diff --git a/.travis.yml b/.travis.yml index 0285f57d18..697870c488 100644 --- a/.travis.yml +++ b/.travis.yml @@ -49,10 +49,11 @@ script: - bin/developer assets:compile-less - bin/developer system:uninstall - bin/setup system:install --email=test@phraseanet.com --password=test --db-user=root --db-template=fr --db-password= --databox=db_test --appbox=ab_test --server-name=http://127.0.0.1 -y; - - sh -c " if [ '$SETUP_MODE' = 'update' ]; then - bin/developer ini:reset --email=test@phraseanet.com --password=test --run-patches --no-setup-dbs; - php resources/hudson/cleanupSubdefs.php; - fi" + - > + sh -c "if [ '$SETUP_MODE' = 'update' ]; then + bin/developer ini:reset --email=test@phraseanet.com --password=test --run-patches --no-setup-dbs; + php resources/hudson/cleanupSubdefs.php; + fi" - bin/developer ini:setup-tests-dbs - bin/console searchengine:index:create - bin/developer phraseanet:regenerate-sqlite diff --git a/AUTHORS b/AUTHORS index 4ea8516c0e..d749eb8fcf 100644 --- a/AUTHORS +++ b/AUTHORS @@ -1,9 +1,10 @@ ** Phraseanet is written and maintained by the Phraseanet Developer Team ** + Benoît Burnichon Jean-Yves Gaulier Andrey Kalinovsky Nicolas Legoff - Romain Neutron + Romain Neutron ** Proudly Powered by Alchemy ** diff --git a/config/configuration.sample.yml b/config/configuration.sample.yml index 90ee18bbdd..050676bca6 100644 --- a/config/configuration.sample.yml +++ b/config/configuration.sample.yml @@ -71,7 +71,7 @@ main: host: 127.0.0.1 port: 6700 storage: - subdefs:null + subdefs: null cache: null log : null download: null diff --git a/lib/Alchemy/Phrasea/Border/Attribute/Status.php b/lib/Alchemy/Phrasea/Border/Attribute/Status.php index 1a78b7a58e..b1486896b1 100644 --- a/lib/Alchemy/Phrasea/Border/Attribute/Status.php +++ b/lib/Alchemy/Phrasea/Border/Attribute/Status.php @@ -29,11 +29,11 @@ class Status implements AttributeInterface } elseif (ctype_digit($status)) { $status = decbin((int) $status); } elseif (strpos($status, '0x') === 0 && ctype_xdigit(substr($status, 2))) { - $status = \databox_status::hex2bin($app, $status); + $status = \databox_status::hex2bin($status); } elseif (strpos($status, '0b') === 0 && preg_match('/^[01]+$/', substr($status, 2))) { $status = substr($status, 2); } elseif (ctype_xdigit($status)) { - $status = \databox_status::hex2bin($app, $status); + $status = \databox_status::hex2bin($status); } else { throw new \InvalidArgumentException('Invalid status argument'); } diff --git a/lib/Alchemy/Phrasea/Controller/Prod/Edit.php b/lib/Alchemy/Phrasea/Controller/Prod/Edit.php index bdca7d5da0..41706cbcc3 100644 --- a/lib/Alchemy/Phrasea/Controller/Prod/Edit.php +++ b/lib/Alchemy/Phrasea/Controller/Prod/Edit.php @@ -348,13 +348,13 @@ class Edit implements ControllerProviderInterface if (!in_array($statbits, ['', 'null'])) { $mask_and = ltrim(str_replace(['x', '0', '1', 'z'], ['1', 'z', '0', '1'], $statbits), '0'); if ($mask_and != '') { - $newstat = \databox_status::operation_and_not($app, $newstat, $mask_and); + $newstat = \databox_status::operation_and_not($newstat, $mask_and); } $mask_or = ltrim(str_replace('x', '0', $statbits), '0'); if ($mask_or != '') { - $newstat = \databox_status::operation_or($app, $newstat, $mask_or); + $newstat = \databox_status::operation_or($newstat, $mask_or); } $record->set_binary_status($newstat); diff --git a/lib/Alchemy/Phrasea/Controller/Thesaurus/Xmlhttp.php b/lib/Alchemy/Phrasea/Controller/Thesaurus/Xmlhttp.php index 6831d7afda..37937954be 100644 --- a/lib/Alchemy/Phrasea/Controller/Thesaurus/Xmlhttp.php +++ b/lib/Alchemy/Phrasea/Controller/Thesaurus/Xmlhttp.php @@ -1381,7 +1381,7 @@ class Xmlhttp implements ControllerProviderInterface // first, count the number of records to update foreach ($tsbas as $ksbas => $sbas) { - /* @var $databox databox */ + /* @var $databox \databox */ try { $databox = $appbox->get_databox($sbas['sbas_id']); $connbas = $databox->get_connection(); @@ -1394,7 +1394,7 @@ class Xmlhttp implements ControllerProviderInterface continue; } - $lid = ''; + $lids = []; $xpathct = new \DOMXPath($tsbas[$ksbas]['domct']); foreach ($sbas['tids'] as $tid) { @@ -1403,7 +1403,7 @@ class Xmlhttp implements ControllerProviderInterface if ($nodes->length == 1) { $sy = $nodes->item(0); $syid = str_replace('.', 'd', $sy->getAttribute('id')) . 'd'; - $lid .= ( $lid ? ',' : '') . "'" . $syid . "'"; + $lids[] = $syid; $field = $sy->parentNode->parentNode->getAttribute('field'); if (!array_key_exists($field, $tsbas[$ksbas]['tvals'])) { @@ -1413,19 +1413,18 @@ class Xmlhttp implements ControllerProviderInterface } } - if ($lid == '') { + if (empty($lids)) { // no cterm was found continue; } - $tsbas[$ksbas]['lid'] = $lid; + $tsbas[$ksbas]['lid'] = "'" . implode("','", $lids) . "'"; // count records $sql = 'SELECT DISTINCT record_id AS r - FROM thit WHERE value IN (' . $lid . ') + FROM thit WHERE value IN (:lids) ORDER BY record_id'; $stmt = $connbas->prepare($sql); - $stmt->execute(); - + $stmt->execute(['lids' => $lids]); $tsbas[$ksbas]['trids'] = $stmt->fetchAll(\PDO::FETCH_COLUMN, 0); $stmt->closeCursor(); diff --git a/lib/Alchemy/Phrasea/Core/Connection/ConnectionPoolManager.php b/lib/Alchemy/Phrasea/Core/Connection/ConnectionPoolManager.php index a71d803d0f..98f050a41d 100644 --- a/lib/Alchemy/Phrasea/Core/Connection/ConnectionPoolManager.php +++ b/lib/Alchemy/Phrasea/Core/Connection/ConnectionPoolManager.php @@ -11,8 +11,6 @@ namespace Alchemy\Phrasea\Core\Connection; -use Doctrine\Common\EventManager; -use Doctrine\DBAL\Configuration; use Doctrine\DBAL\Driver\Connection; use Doctrine\DBAL\DriverManager; use Psr\Log\LoggerInterface; diff --git a/lib/Alchemy/Phrasea/Helper/User/Edit.php b/lib/Alchemy/Phrasea/Helper/User/Edit.php index 2a174dc8bc..9378a6bf48 100644 --- a/lib/Alchemy/Phrasea/Helper/User/Edit.php +++ b/lib/Alchemy/Phrasea/Helper/User/Edit.php @@ -16,6 +16,7 @@ use Alchemy\Phrasea\Exception\InvalidArgumentException; use Alchemy\Phrasea\Model\Entities\User; use Alchemy\Phrasea\Notification\Mail\MailSuccessEmailUpdate; use Alchemy\Phrasea\Notification\Receiver; +use Doctrine\DBAL\Connection; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; @@ -131,25 +132,39 @@ class Edit extends \Alchemy\Phrasea\Helper\Helper ON (bu.base_id = b.base_id AND u.id = bu.usr_id) LEFT join sbasusr sbu ON (sbu.sbas_id = b.sbas_id AND u.id = sbu.usr_id) - WHERE ( (u.id = " . implode(' OR u.id = ', $this->users) . " ) + WHERE ( (u.id IN (:users) ) AND b.sbas_id = s.sbas_id - AND (b.base_id = '" . implode("' OR b.base_id = '", $list) . "')) + AND (b.base_id IN (:bases))) GROUP BY b.base_id ORDER BY s.ord, s.sbas_id, b.ord, b.base_id "; - $stmt = $this->app['phraseanet.appbox']->get_connection()->prepare($sql); - $stmt->execute(); - $rs = $stmt->fetchAll(\PDO::FETCH_ASSOC); - $stmt->closeCursor(); + $rs = $this->app['phraseanet.appbox']->get_connection()->fetchAll( + $sql, + [ + 'users' => $this->users, + 'bases' => $list, + ], + [ + 'users' => Connection::PARAM_INT_ARRAY, + 'bases' => Connection::PARAM_INT_ARRAY, + ] + ); $sql = 'SELECT base_id, sum(1) as access FROM basusr - WHERE (usr_id = ' . implode(' OR usr_id = ', $this->users) . ') - AND (base_id = ' . implode(' OR base_id = ', $list) . ') + WHERE (usr_id IN (:users)) + AND (base_id IN (:bases)) GROUP BY base_id'; - $stmt = $this->app['phraseanet.appbox']->get_connection()->prepare($sql); - $stmt->execute(); - $access = $stmt->fetchAll(\PDO::FETCH_ASSOC); - $stmt->closeCursor(); + $access = $this->app['phraseanet.appbox']->get_connection()->fetchAll( + $sql, + [ + 'users' => $this->users, + 'bases' => $list, + ], + [ + 'users' => Connection::PARAM_INT_ARRAY, + 'bases' => Connection::PARAM_INT_ARRAY, + ] + ); $base_ids = []; foreach ($access as $acc) { @@ -194,14 +209,20 @@ class Edit extends \Alchemy\Phrasea\Helper\Helper $sql = "SELECT u.id, restrict_dwnld, remain_dwnld, month_dwnld_max FROM (Users u INNER JOIN basusr bu ON u.id = bu.usr_id) - WHERE (u.id = " . implode(' OR u.id = ', $this->users) . ") - AND bu.base_id = :base_id"; + WHERE (u.id IN (:users)) AND bu.base_id = :base_id"; + /** @var Connection $conn */ $conn = $this->app['phraseanet.appbox']->get_connection(); - $stmt = $conn->prepare($sql); - $stmt->execute([':base_id' => $this->base_id]); - $rs = $stmt->fetchAll(\PDO::FETCH_ASSOC); - $stmt->closeCursor(); + $rs = $conn->fetchAll($sql, + [ + 'base_id' => $this->base_id, + 'users' => $this->users, + ], + [ + 'base_id' => \PDO::PARAM_INT, + 'users' => Connection::PARAM_INT_ARRAY, + ] + ); $this->users_datas = $rs; @@ -220,14 +241,21 @@ class Edit extends \Alchemy\Phrasea\Helper\Helper $sql = "SELECT BIN(mask_and) AS mask_and, BIN(mask_xor) AS mask_xor FROM basusr - WHERE usr_id IN (" . implode(',', $this->users) . ") + WHERE usr_id IN (:users) AND base_id = :base_id"; + /** @var Connection $conn */ $conn = $this->app['phraseanet.appbox']->get_connection(); - $stmt = $conn->prepare($sql); - $stmt->execute([':base_id' => $this->base_id]); - $rs = $stmt->fetchAll(\PDO::FETCH_ASSOC); - $stmt->closeCursor(); + $rs = $conn->fetchAll($sql, + [ + 'base_id' => $this->base_id, + 'users' => $this->users, + ], + [ + 'base_id' => \PDO::PARAM_INT, + 'users' => Connection::PARAM_INT_ARRAY, + ] + ); $tbits_and = []; $tbits_xor = []; @@ -317,14 +345,20 @@ class Edit extends \Alchemy\Phrasea\Helper\Helper $sql = "SELECT u.id, time_limited, limited_from, limited_to FROM (Users u INNER JOIN basusr bu ON u.id = bu.usr_id) - WHERE (u.id = " . implode(' OR u.id = ', $this->users) . ") - AND bu.base_id = :base_id"; + WHERE (u.id IN (:users)) AND bu.base_id = :base_id"; + /** @var Connection $conn */ $conn = $this->app['phraseanet.appbox']->get_connection(); - $stmt = $conn->prepare($sql); - $stmt->execute([':base_id' => $this->base_id]); - $rs = $stmt->fetchAll(\PDO::FETCH_ASSOC); - $stmt->closeCursor(); + $rs = $conn->fetchAll($sql, + [ + 'base_id' => $this->base_id, + 'users' => $this->users, + ], + [ + 'base_id' => \PDO::PARAM_INT, + 'users' => Connection::PARAM_INT_ARRAY, + ] + ); $time_limited = -1; $limited_from = $limited_to = false; @@ -373,14 +407,20 @@ class Edit extends \Alchemy\Phrasea\Helper\Helper FROM (Users u INNER JOIN basusr bu ON u.id = bu.usr_id INNER JOIN bas b ON b.base_id = bu.base_id) - WHERE (u.id = " . implode(' OR u.id = ', $this->users) . ") - AND b.sbas_id = :sbas_id"; + WHERE (u.id IN (:users)) AND b.sbas_id = :sbas_id"; + /** @var Connection $conn */ $conn = $this->app['phraseanet.appbox']->get_connection(); - $stmt = $conn->prepare($sql); - $stmt->execute([':sbas_id' => $sbas_id]); - $rs = $stmt->fetchAll(\PDO::FETCH_ASSOC); - $stmt->closeCursor(); + $rs = $conn->fetchAll($sql, + [ + 'sbas_id' => $sbas_id, + 'users' => $this->users, + ], + [ + 'sbas_id' => \PDO::PARAM_INT, + 'users' => Connection::PARAM_INT_ARRAY, + ] + ); $time_limited = $limited_from = $limited_to = []; diff --git a/lib/Alchemy/Phrasea/Model/Repositories/LazaretFileRepository.php b/lib/Alchemy/Phrasea/Model/Repositories/LazaretFileRepository.php index 1359d0e58f..0aad964a0b 100644 --- a/lib/Alchemy/Phrasea/Model/Repositories/LazaretFileRepository.php +++ b/lib/Alchemy/Phrasea/Model/Repositories/LazaretFileRepository.php @@ -24,20 +24,18 @@ class LazaretFileRepository extends EntityRepository { public function findPerPage(array $base_ids, $offset = 0, $perPage = 10) { - $base_ids = implode(', ', array_map(function ($int) { - return (int) $int; - }, $base_ids)); + $builder = $this->createQueryBuilder('f'); - $dql = ' - SELECT f - FROM Phraseanet:LazaretFile f' - . ('' === $base_ids ? '' : ' WHERE f.base_id IN (' . $base_ids . ')') - . ' ORDER BY f.id DESC'; + if (! empty($base_ids)) { + $builder->where($builder->expr()->in('f.base_id', $base_ids)); + } - $query = $this->_em->createQuery($dql); - $query->setFirstResult($offset) - ->setMaxResults($perPage); + $builder + ->orderBy('f.id', 'DESC') + ->setFirstResult($offset) + ->setMaxResults($perPage) + ; - return new Paginator($query, true); + return new Paginator($builder->getQuery(), true); } } diff --git a/lib/Alchemy/Phrasea/Model/Repositories/RegistrationRepository.php b/lib/Alchemy/Phrasea/Model/Repositories/RegistrationRepository.php index 65a25d5004..a91d1e25aa 100644 --- a/lib/Alchemy/Phrasea/Model/Repositories/RegistrationRepository.php +++ b/lib/Alchemy/Phrasea/Model/Repositories/RegistrationRepository.php @@ -38,7 +38,7 @@ class RegistrationRepository extends EntityRepository if (count($collections) > 0) { $qb->andWhere('d.baseId IN (:bases)'); - $qb->setParameter(':bases', array_map(function ($collection) { + $qb->setParameter(':bases', array_map(function (\collection $collection) { return $collection->get_base_id(); }, $collections)); } diff --git a/lib/Alchemy/Phrasea/SearchEngine/Phrasea/PhraseaEngine.php b/lib/Alchemy/Phrasea/SearchEngine/Phrasea/PhraseaEngine.php index d8d6cf117f..229e98ef86 100644 --- a/lib/Alchemy/Phrasea/SearchEngine/Phrasea/PhraseaEngine.php +++ b/lib/Alchemy/Phrasea/SearchEngine/Phrasea/PhraseaEngine.php @@ -293,7 +293,7 @@ class PhraseaEngine implements SearchEngineInterface */ public function updateRecord(\record_adapter $record) { - $record->set_binary_status(\databox_status::dec2bin($this->app, bindec($record->get_status()) & ~7 | 4)); + $record->set_binary_status(\databox_status::dec2bin(bindec($record->get_status()) & ~7 | 4)); return $this; } diff --git a/lib/Alchemy/Phrasea/Setup/Version/MailChecker.php b/lib/Alchemy/Phrasea/Setup/Version/MailChecker.php index 9cea69a9a6..350506be3e 100644 --- a/lib/Alchemy/Phrasea/Setup/Version/MailChecker.php +++ b/lib/Alchemy/Phrasea/Setup/Version/MailChecker.php @@ -12,7 +12,7 @@ namespace Alchemy\Phrasea\Setup\Version; use Alchemy\Phrasea\Application; -use Alchemy\Phrasea\Core\Version; +use Doctrine\DBAL\Driver\Statement; /** * In version 3.9 the user table have been removed. @@ -21,23 +21,42 @@ use Alchemy\Phrasea\Core\Version; */ class MailChecker { + /** @var \appbox */ + private $appbox; + /** @var string */ + private $table; + + /** + * Constructor + * + * @param \appbox $appbox + * @param string $table + */ + public function __construct(\appbox $appbox, $table = 'usr') + { + $this->appbox = $appbox; + $this->table = $table; + } + /** * Returns users with duplicated emails * - * @param \Application $app - * @param string $table The table name where to look - * * @return array An array of User */ - public static function getWrongEmailUsers(Application $app, $table = 'usr') + public function getWrongEmailUsers() { - if (version_compare(Version::getNumber(), '3.9', '>')) { + if (version_compare($this->appbox->get_version(), '3.9', '>=')) { return []; } - $sql = 'SELECT usr_mail, usr_id, last_conn, usr_login FROM '. $table .' WHERE usr_mail IS NOT NULL'; - $stmt = $app['phraseanet.appbox']->get_connection()->prepare($sql); - $stmt->execute(); + $builder = $this->appbox->get_connection()->createQueryBuilder(); + /** @var Statement $stmt */ + $stmt = $builder + ->select('u.usr_mail', 'u.usr_id', 'u.last_conn', 'u.usr_login') + ->from($this->table, 'u') + ->where($builder->expr()->isNotNull('u.usr_mail')) + ->execute() + ; $rs = $stmt->fetchAll(\PDO::FETCH_ASSOC); $stmt->closeCursor(); @@ -66,4 +85,14 @@ class MailChecker return $badUsers; } + + /** + * Whether there is users with same emails + * + * @return bool + */ + public function hasWrongEmailUsers() + { + return count($this->getWrongEmailUsers()) > 0; + } } diff --git a/lib/Alchemy/Phrasea/Setup/Version/PreSchemaUpgrade/Upgrade39Users.php b/lib/Alchemy/Phrasea/Setup/Version/PreSchemaUpgrade/Upgrade39Users.php index aa7cc52d72..8184dac8c2 100644 --- a/lib/Alchemy/Phrasea/Setup/Version/PreSchemaUpgrade/Upgrade39Users.php +++ b/lib/Alchemy/Phrasea/Setup/Version/PreSchemaUpgrade/Upgrade39Users.php @@ -14,6 +14,7 @@ namespace Alchemy\Phrasea\Setup\Version\PreSchemaUpgrade; use Alchemy\Phrasea\Application; use Alchemy\Phrasea\Model\Entities\User; use Alchemy\Phrasea\Model\Entities\FtpCredential; +use Doctrine\DBAL\Connection; use Doctrine\DBAL\Migrations\Configuration\Configuration; use Doctrine\ORM\EntityManager; use Doctrine\ORM\NoResultException; @@ -357,7 +358,11 @@ class Upgrade39Users implements PreSchemaUpgradeInterface ); $em->getConnection()->executeUpdate('UPDATE Users SET geoname_id=NULL WHERE geoname_id=0'); - $em->getConnection()->executeUpdate('UPDATE Users SET locale=NULL WHERE locale NOT IN ("'.implode('", "', array_keys(Application::getAvailableLanguages())).'")'); + $em->getConnection()->executeUpdate( + 'UPDATE Users SET locale=NULL WHERE locale NOT IN (:locales)', + ['locales' => array_keys(Application::getAvailableLanguages())], + ['locales' => Connection::PARAM_STR_ARRAY] + ); $em->getConnection()->executeUpdate('UPDATE Users SET deleted=1, login=SUBSTRING(login, 11) WHERE login LIKE "(#deleted_%"'); } @@ -367,14 +372,28 @@ class Upgrade39Users implements PreSchemaUpgradeInterface $perBatch = 100; do { - $sql = 'SELECT usr_id, activeFTP, addrFTP, loginFTP, - retryFTP, passifFTP, pwdFTP, destFTP, prefixFTPfolder - FROM usr - WHERE - usr_login NOT LIKE "(#deleted_%" - AND model_of = 0 - AND addrFTP != ""' - .sprintf(' LIMIT %d, %d', $offset, $perBatch); + $builder = $em->getConnection()->createQueryBuilder(); + $sql = $builder + ->select( + 'u.usr_id', + 'u.activeFTP', + 'u.addrFTP', + 'u.loginFTP', + 'u.retryFTP', + 'u.passifFTP', + 'u.pwdFTP', + 'u.destFTP', + 'u.prefixFTPfolder' + ) + ->from('usr', 'u') + ->where( + $builder->expr()->notLike('u.usr_login', $builder->expr()->literal('(#deleted_%')), + $builder->expr()->eq('u.model_of', 0), + $builder->expr()->neq('u.addrFTP', $builder->expr()->literal('')) + ) + ->setFirstResult($offset) + ->setMaxResults($perBatch) + ->getSQL(); $rs = $em->getConnection()->fetchAll($sql); diff --git a/lib/Alchemy/Phrasea/TaskManager/Job/ArchiveJob.php b/lib/Alchemy/Phrasea/TaskManager/Job/ArchiveJob.php index 0f43145953..f7a22d0649 100644 --- a/lib/Alchemy/Phrasea/TaskManager/Job/ArchiveJob.php +++ b/lib/Alchemy/Phrasea/TaskManager/Job/ArchiveJob.php @@ -985,7 +985,7 @@ class ArchiveJob extends AbstractJob public function createStory(Application $app, \collection $collection, $pathfile, $captionFile, $stat0, $stat1) { - $status = \databox_status::operation_or($app, $stat0, $stat1); + $status = \databox_status::operation_or($stat0, $stat1); $media = $app['mediavorus']->guess($pathfile); @@ -1000,7 +1000,7 @@ class ArchiveJob extends AbstractJob $captionStatus = $this->parseStatusBit(@simplexml_load_file($captionFile)); if ($captionStatus) { - $status = \databox_status::operation_mask($app, $status, $captionStatus); + $status = \databox_status::operation_mask($status, $captionStatus); } } @@ -1013,7 +1013,7 @@ class ArchiveJob extends AbstractJob $story->set_metadatas($metaFields->toMetadataArray($metadatasStructure), true); } - $story->set_binary_status(\databox_status::operation_or($app, $stat0, $stat1)); + $story->set_binary_status(\databox_status::operation_or($stat0, $stat1)); $story->rebuild_subdefs(); unset($media); @@ -1033,7 +1033,7 @@ class ArchiveJob extends AbstractJob */ public function createRecord(Application $app, \collection $collection, $pathfile, $captionFile, $grp_rid, $force, $stat0, $stat1) { - $status = \databox_status::operation_or($app, $stat0, $stat1); + $status = \databox_status::operation_or($stat0, $stat1); $media = $app['mediavorus']->guess($pathfile); @@ -1048,7 +1048,7 @@ class ArchiveJob extends AbstractJob $captionStatus = $this->parseStatusBit(@simplexml_load_file($captionFile)); if ($captionStatus) { - $status = \databox_status::operation_mask($app, $status, $captionStatus); + $status = \databox_status::operation_mask($status, $captionStatus); } } $file = new File($app, $media, $collection); diff --git a/lib/classes/Setup/Upgrade.php b/lib/classes/Setup/Upgrade.php index 6220eb4884..3fb0c6d299 100644 --- a/lib/classes/Setup/Upgrade.php +++ b/lib/classes/Setup/Upgrade.php @@ -39,8 +39,8 @@ class Setup_Upgrade $this->app = $app; - if (version_compare($this->app['phraseanet.appbox']->get_version(), '3.9', '<') - && count(MailChecker::getWrongEmailUsers($app)) > 0) { + $checker = new MailChecker($app['phraseanet.appbox']); + if ($checker->hasWrongEmailUsers()) { throw new \Exception_Setup_FixBadEmailAddresses('Please fix the database before starting'); } diff --git a/lib/classes/appbox.php b/lib/classes/appbox.php index 027a4890d2..7bb3e77755 100644 --- a/lib/classes/appbox.php +++ b/lib/classes/appbox.php @@ -21,22 +21,14 @@ use vierbergenlars\SemVer\version; class appbox extends base { - /** - * - * @var int - */ + /** @var int */ protected $id; /** - * * constant defining the app type */ const BASE_TYPE = self::APPLICATION_BOX; - /** - * - * @var - */ protected $cache; protected $connection; protected $app; @@ -46,25 +38,16 @@ class appbox extends base const CACHE_LIST_BASES = 'list_bases'; const CACHE_SBAS_IDS = 'sbas_ids'; - /** - * Constructor - * - * @return appbox - */ public function __construct(Application $app) { - $this->app = $app; $connexion = $app['conf']->get(['main', 'database']); - - $this->connection = $app['db.provider']($connexion); + parent::__construct($app, $app['db.provider']($connexion)); $this->host = $connexion['host']; $this->port = $connexion['port']; $this->user = $connexion['user']; $this->passwd = $connexion['password']; $this->dbname = $connexion['dbname']; - - return $this; } public function write_collection_pic(Alchemyst $alchemyst, Filesystem $filesystem, collection $collection, SymfoFile $pathfile = null, $pic_type) @@ -372,8 +355,7 @@ class appbox extends base } /** - * - * @return Array + * @return databox[] */ public function get_databoxes() { diff --git a/lib/classes/base.php b/lib/classes/base.php index 451b3e4502..d51129985c 100644 --- a/lib/classes/base.php +++ b/lib/classes/base.php @@ -12,74 +12,37 @@ use Alchemy\Phrasea\Application; use Alchemy\Phrasea\Core\Version as PhraseaVersion; use vierbergenlars\SemVer\version; -use Alchemy\Phrasea\Model\Entities\User; -use Doctrine\DBAL\Driver\Connection; +use Doctrine\DBAL\Connection; abstract class base implements cache_cacheableInterface { protected $version; - /** - * - * @var int - */ + /** @var int */ protected $id; - - /** - * - * @var string - */ protected $schema; - - /** - * - * @var - */ protected $dbname; - - /** - * - * @var - */ protected $passwd; - - /** - * Database Username - * - * @var - */ protected $user; - - /** - * - * @var - */ protected $port; - - /** - * - * @var - */ protected $host; - /** - * - */ + /** @var Connection */ + protected $connection; + /** @var Application */ + protected $app; + const APPLICATION_BOX = 'APPLICATION_BOX'; - /** - * - */ const DATA_BOX = 'DATA_BOX'; - /** - * - */ + public function __construct(Application $application, Connection $connection) + { + $this->app = $application; + $this->connection = $connection; + } + abstract public function get_base_type(); - /** - * - * @return - */ public function get_schema() { if ($this->schema) { @@ -91,55 +54,32 @@ abstract class base implements cache_cacheableInterface return $this->schema; } - /** - * - * @return - */ public function get_dbname() { return $this->dbname; } - /** - * - * @return - */ public function get_passwd() { return $this->passwd; } - /** - * - * @return - */ public function get_user() { return $this->user; } - /** - * - * @return - */ public function get_port() { return $this->port; } - /** - * - * @return - */ public function get_host() { return $this->host; } - /** - * - * @return Connection - */ + /** @return Connection */ public function get_connection() { return $this->connection; @@ -150,11 +90,6 @@ abstract class base implements cache_cacheableInterface return $this->app['cache']; } - /** - * - * @param $option - * @return - */ public function get_data_from_cache($option = null) { if ($this->get_base_type() == self::DATA_BOX) { @@ -340,7 +275,7 @@ abstract class base implements cache_cacheableInterface try { $sql = ''; if ($this->get_base_type() === self::APPLICATION_BOX) - $sql = 'UPDATE sitepreff SET version = "' . $version->getNumber() . '"'; + $sql = 'UPDATE sitepreff SET version = :version'; if ($this->get_base_type() === self::DATA_BOX) { $sql = 'DELETE FROM pref WHERE prop="version" AND locale IS NULL'; $this->get_connection()->query($sql); @@ -363,7 +298,6 @@ abstract class base implements cache_cacheableInterface } /** - * * @return base */ protected function load_schema() @@ -387,7 +321,6 @@ abstract class base implements cache_cacheableInterface } /** - * * @return base */ public function insert_datas() @@ -404,7 +337,6 @@ abstract class base implements cache_cacheableInterface } /** - * * @param SimpleXMLElement $table * @return base */ diff --git a/lib/classes/caption/field.php b/lib/classes/caption/field.php index 33c2b182d1..771cbe51bf 100644 --- a/lib/classes/caption/field.php +++ b/lib/classes/caption/field.php @@ -10,6 +10,7 @@ */ use Alchemy\Phrasea\Application; +use Doctrine\DBAL\Driver\Statement; class caption_field implements cache_cacheableInterface { @@ -284,35 +285,35 @@ class caption_field implements cache_cacheableInterface public static function rename_all_metadatas(Application $app, databox_field $databox_field) { - $sql = 'SELECT count(id) as count_id FROM metadatas - WHERE meta_struct_id = :meta_struct_id'; - $stmt = $databox_field->get_databox()->get_connection()->prepare($sql); - $params = [ - ':meta_struct_id' => $databox_field->get_id() - ]; + $connection = $databox_field->get_databox()->get_connection(); + $builder = $connection->createQueryBuilder(); + $builder + ->select('COUNT(m.id) AS count_id') + ->from('metadatas', 'm') + ->where($builder->expr()->eq('m.meta_struct_id', ':meta_struct_id')) + ->setParameter('meta_struct_id', $databox_field->get_id()) + ; - $stmt->execute($params); - $rowcount = $stmt->rowCount(); + /** @var Statement $stmt */ + $stmt = $builder->execute(); + $rowcount = $stmt->fetchColumn(); $stmt->closeCursor(); + unset($stmt); $n = 0; $increment = 500; + $builder + ->select('m.record_id', 'm.id') + ->setMaxResults($increment) + ; while ($n < $rowcount) { - $sql = 'SELECT record_id, id FROM metadatas - WHERE meta_struct_id = :meta_struct_id LIMIT ' . $n . ', ' . $increment; - - $params = [ - ':meta_struct_id' => $databox_field->get_id() - ]; - - $stmt = $databox_field->get_databox()->get_connection()->prepare($sql); - $stmt->execute($params); - $rowcount = $stmt->rowCount(); - $rs = $stmt->fetchAll(PDO::FETCH_ASSOC); - $stmt->closeCursor(); - unset($stmt); + /** @var Statement $stmt */ + $stmt = $builder + ->setFirstResult($n) + ->execute(); + $rs = $stmt->fetchAll(\PDO::FETCH_ASSOC); foreach ($rs as $row) { try { $record = $databox_field->get_databox()->get_record($row['record_id']); @@ -326,43 +327,39 @@ class caption_field implements cache_cacheableInterface $n += $increment; } - - return; } public static function delete_all_metadatas(Application $app, databox_field $databox_field) { - $sql = 'SELECT count(id) as count_id FROM metadatas - WHERE meta_struct_id = :meta_struct_id'; + $connection = $databox_field->get_databox()->get_connection(); + $builder = $connection->createQueryBuilder(); + $builder + ->select('COUNT(m.id) AS count_id') + ->from('metadatas', 'm') + ->where($builder->expr()->eq('m.meta_struct_id', ':meta_struct_id')) + ->setParameter('meta_struct_id', $databox_field->get_id()) + ; - $stmt = $databox_field->get_databox()->get_connection()->prepare($sql); - $params = [ - ':meta_struct_id' => $databox_field->get_id() - ]; - - $stmt->execute($params); - $rowcount = $stmt->rowCount(); + /** @var Statement $stmt */ + $stmt = $builder->execute(); + $rowcount = $stmt->fetchColumn(); $stmt->closeCursor(); + unset($stmt); $n = 0; $increment = 500; + $builder + ->select('m.record_id', 'm.id') + ->setMaxResults($increment) + ; while ($n < $rowcount) { - $sql = 'SELECT record_id, id FROM metadatas - WHERE meta_struct_id = :meta_struct_id - LIMIT ' . $n . ', ' . $increment; - - $params = [ - ':meta_struct_id' => $databox_field->get_id() - ]; - - $stmt = $databox_field->get_databox()->get_connection()->prepare($sql); - $stmt->execute($params); - $rowcount = $stmt->rowCount(); - $rs = $stmt->fetchAll(PDO::FETCH_ASSOC); - $stmt->closeCursor(); - unset($stmt); + /** @var Statement $stmt */ + $stmt = $builder + ->setFirstResult($n) + ->execute(); + $rs = $stmt->fetchAll(\PDO::FETCH_ASSOC); foreach ($rs as $row) { try { $record = $databox_field->get_databox()->get_record($row['record_id']); diff --git a/lib/classes/databox.php b/lib/classes/databox.php index 0a366e6d99..3a48021337 100644 --- a/lib/classes/databox.php +++ b/lib/classes/databox.php @@ -12,7 +12,8 @@ use Alchemy\Phrasea\Application; use Alchemy\Phrasea\Model\Entities\User; use Alchemy\Phrasea\Exception\InvalidArgumentException; -use Doctrine\DBAL\Driver\Connection; +use Doctrine\DBAL\Connection; +use Doctrine\DBAL\Driver\Statement; use Symfony\Component\Filesystem\Filesystem; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; use Symfony\Component\Translation\TranslatorInterface; @@ -101,42 +102,42 @@ class databox extends base const PIC_PDF = 'logopdf'; protected $cache; - protected $connection; - protected $app; private $labels = []; private $ord; private $viewname; private $loaded = false; + /** + * @param Application $app + * @param int $sbas_id + */ public function __construct(Application $app, $sbas_id) { assert(is_int($sbas_id)); assert($sbas_id > 0); - $this->app = $app; $this->id = $sbas_id; - $connection_params = phrasea::sbas_params($this->app); + $connection_params = phrasea::sbas_params($app); if (! isset($connection_params[$sbas_id])) { throw new NotFoundHttpException(sprintf('databox %d not found', $sbas_id)); } - $this->connection = $app['db.provider']([ + $params = [ 'host' => $connection_params[$sbas_id]['host'], 'port' => $connection_params[$sbas_id]['port'], 'user' => $connection_params[$sbas_id]['user'], 'password' => $connection_params[$sbas_id]['pwd'], 'dbname' => $connection_params[$sbas_id]['dbname'], - ]); + ]; + parent::__construct($app, $app['db.provider']($params)); - $this->host = $connection_params[$sbas_id]['host']; - $this->port = $connection_params[$sbas_id]['port']; - $this->user = $connection_params[$sbas_id]['user']; - $this->passwd = $connection_params[$sbas_id]['pwd']; - $this->dbname = $connection_params[$sbas_id]['dbname']; - - return $this; + $this->host = $params['host']; + $this->port = $params['port']; + $this->user = $params['user']; + $this->passwd = $params['password']; + $this->dbname = $params['dbname']; } private function load() @@ -796,6 +797,7 @@ class databox extends base */ public function get_mountable_colls() { + /** @var Connection $conn */ $conn = $this->app['phraseanet.appbox']->get_connection(); $colls = []; @@ -804,6 +806,7 @@ class databox extends base $stmt->execute([':sbas_id' => $this->id]); $rs = $stmt->fetchAll(PDO::FETCH_ASSOC); $stmt->closeCursor(); + unset($stmt); foreach ($rs as $row) { $colls[] = (int) $row['server_coll_id']; @@ -811,16 +814,22 @@ class databox extends base $mountable_colls = []; - $sql = 'SELECT coll_id, asciiname FROM coll'; - + $builder = $this->get_connection()->createQueryBuilder(); + $builder + ->select('c.coll_id', 'c.asciiname') + ->from('coll', 'c'); if (count($colls) > 0) { - $sql .= ' WHERE coll_id NOT IN (' . implode(',', $colls) . ')'; + $builder + ->where($builder->expr()->notIn('c.coll_id', [':colls'])) + ->setParameter('colls', $colls, Connection::PARAM_INT_ARRAY) + ; } - $stmt = $this->get_connection()->prepare($sql); - $stmt->execute(); + /** @var Statement $stmt */ + $stmt = $builder->execute(); $rs = $stmt->fetchAll(PDO::FETCH_ASSOC); $stmt->closeCursor(); + unset($stmt); foreach ($rs as $row) { $mountable_colls[$row['coll_id']] = $row['asciiname']; @@ -831,6 +840,7 @@ class databox extends base public function get_activable_colls() { + /** @var Connection $conn */ $conn = $this->app['phraseanet.appbox']->get_connection(); $base_ids = []; @@ -858,8 +868,7 @@ class databox extends base $dom_struct->documentElement ->setAttribute("modification_date", $now = date("YmdHis")); - $sql = "UPDATE pref SET value= :structure, updated_on= :now - WHERE prop='structure'"; + $sql = "UPDATE pref SET value= :structure, updated_on= :now WHERE prop='structure'"; $this->structure = $dom_struct->saveXML(); @@ -1075,10 +1084,7 @@ class databox extends base public function clear_logs() { foreach (['log', 'log_colls', 'log_docs', 'log_search', 'log_view', 'log_thumb'] as $table) { - $sql = 'DELETE FROM ' . $table; - $stmt = $this->get_connection()->prepare($sql); - $stmt->execute(); - $stmt->closeCursor(); + $this->get_connection()->delete($table, []); } return $this; @@ -1086,10 +1092,7 @@ class databox extends base public function reindex() { - $sql = 'UPDATE pref SET updated_on="0000-00-00 00:00:00" WHERE prop="indexes"'; - $stmt = $this->get_connection()->prepare($sql); - $stmt->execute(); - $stmt->closeCursor(); + $this->get_connection()->update('pref', ['updated_on' => '0000-00-00 00:00:00'], ['prop' => 'indexes']); return $this; } diff --git a/lib/classes/databox/status.php b/lib/classes/databox/status.php index f4d00a9728..26bd2674ac 100644 --- a/lib/classes/databox/status.php +++ b/lib/classes/databox/status.php @@ -149,126 +149,68 @@ class databox_status return true; } - public static function operation_and(Application $app, $stat1, $stat2) + public static function operation_and($stat1, $stat2) { - $conn = $app['phraseanet.appbox']->get_connection(); - - $status = '0'; - if (substr($stat1, 0, 2) === '0x') { - $stat1 = self::hex2bin($app, substr($stat1, 2)); + $stat1 = self::hex2bin(substr($stat1, 2)); } if (substr($stat2, 0, 2) === '0x') { - $stat2 = self::hex2bin($app, substr($stat2, 2)); + $stat2 = self::hex2bin(substr($stat2, 2)); } - $sql = 'select bin(0b' . trim($stat1) . ' & 0b' . trim($stat2) . ') as result'; - - $stmt = $conn->prepare($sql); - $stmt->execute(); - $row = $stmt->fetch(PDO::FETCH_ASSOC); - $stmt->closeCursor(); - - if ($row) { - $status = $row['result']; - } - - return $status; + return dechex(hexdec($stat1) & hexdec($stat2)); } /** * compute ((0 M s1) M s2) where M is the "mask" operator * nb : s1,s2 are binary mask strings as "01x0xx1xx0x", no other format (hex) supported * - * @param Application $app * @param $stat1 a binary mask "010x1xx0.." STRING * @param $stat2 a binary mask "x100x1..." STRING * - * @return binary string + * @return string */ - public static function operation_mask(Application $app, $stat1, $stat2) + public static function operation_mask($stat1, $stat2) { - $conn = $app['phraseanet.appbox']->get_connection(); + $stat1 = str_pad($stat1, 32, '0', STR_PAD_LEFT); + $stat2 = str_pad($stat2, 32, '0', STR_PAD_LEFT); + $stat1_or = bindec(trim(str_replace("x", "0", $stat1))); + $stat1_and = bindec(trim(str_replace("x", "1", $stat1))); + $stat2_or = bindec(trim(str_replace("x", "0", $stat2))); + $stat2_and = bindec(trim(str_replace("x", "1", $stat2))); - $status = '0'; - $stat1_or = '0b' . trim(str_replace("x", "0", $stat1)); - $stat1_and = '0b' . trim(str_replace("x", "1", $stat1)); - $stat2_or = '0b' . trim(str_replace("x", "0", $stat2)); - $stat2_and = '0b' . trim(str_replace("x", "1", $stat2)); - - // $sql = "SELECT BIN(((((0 | :o1) & :a1)) | :o2) & :a2) AS result"; - // $stmt = $conn->prepare($sql); - // $stmt->execute(array(':o1'=>$stat1_or, ':a1'=>$stat1_and, ':o2'=>$stat2_or, ':a2'=>$stat2_and)); - - $sql = "SELECT BIN(((((0 | $stat1_or) & $stat1_and)) | $stat2_or) & $stat2_and) AS result"; - $stmt = $conn->prepare($sql); - $stmt->execute(); - - $row = $stmt->fetch(\PDO::FETCH_ASSOC); - $stmt->closeCursor(); - - if ($row) { - $status = $row['result']; - } - - return $status; + return decbin((((0 | $stat1_or) & $stat1_and) | $stat2_or) & $stat2_and); } - public static function operation_and_not(Application $app, $stat1, $stat2) + public static function operation_and_not($stat1, $stat2) { - $conn = $app['phraseanet.appbox']->get_connection(); - - $status = '0'; - if (substr($stat1, 0, 2) === '0x') { - $stat1 = self::hex2bin($app, substr($stat1, 2)); + $stat1 = self::hex2bin(substr($stat1, 2)); } if (substr($stat2, 0, 2) === '0x') { - $stat2 = self::hex2bin($app, substr($stat2, 2)); + $stat2 = self::hex2bin(substr($stat2, 2)); } + $stat1 = str_pad($stat1, 32, '0', STR_PAD_LEFT); + $stat2 = str_pad($stat2, 32, '0', STR_PAD_LEFT); - $sql = 'select bin(0b' . trim($stat1) . ' & ~0b' . trim($stat2) . ') as result'; - - $stmt = $conn->prepare($sql); - $stmt->execute(); - $row = $stmt->fetch(PDO::FETCH_ASSOC); - $stmt->closeCursor(); - - if ($row) { - $status = $row['result']; - } - - return $status; + return decbin(bindec($stat1) & ~bindec($stat2)); } - public static function operation_or(Application $app, $stat1, $stat2) + public static function operation_or($stat1, $stat2) { - $conn = $app['phraseanet.appbox']->get_connection(); - - $status = '0'; - if (substr($stat1, 0, 2) === '0x') { - $stat1 = self::hex2bin($app, substr($stat1, 2)); + $stat1 = self::hex2bin(substr($stat1, 2)); } if (substr($stat2, 0, 2) === '0x') { - $stat2 = self::hex2bin($app, substr($stat2, 2)); + $stat2 = self::hex2bin(substr($stat2, 2)); } + $stat1 = str_pad($stat1, 32, '0', STR_PAD_LEFT); + $stat2 = str_pad($stat2, 32, '0', STR_PAD_LEFT); - $sql = 'select bin(0b' . trim($stat1) . ' | 0b' . trim($stat2) . ') as result'; - - $stmt = $conn->prepare($sql); - $stmt->execute(); - $row = $stmt->fetch(PDO::FETCH_ASSOC); - $stmt->closeCursor(); - - if ($row) { - $status = $row['result']; - } - - return $status; + return decbin(bindec($stat1) | bindec($stat2)); } - public static function dec2bin(Application $app, $status) + public static function dec2bin($status) { $status = (string) $status; @@ -276,25 +218,10 @@ class databox_status throw new \Exception(sprintf('`%s`is non-decimal value', $status)); } - $conn = $app['phraseanet.appbox']->get_connection(); - - $sql = 'select bin(' . $status . ') as result'; - - $stmt = $conn->prepare($sql); - $stmt->execute(); - $row = $stmt->fetch(PDO::FETCH_ASSOC); - $stmt->closeCursor(); - - $status = '0'; - - if ($row) { - $status = $row['result']; - } - - return $status; + return decbin($status); } - public static function hex2bin(Application $app, $status) + public static function hex2bin($status) { $status = (string) $status; if (substr($status, 0, 2) === '0x') { @@ -305,22 +232,7 @@ class databox_status throw new \Exception('Non-hexadecimal value'); } - $conn = $app['phraseanet.appbox']->get_connection(); - - $sql = 'select BIN( CAST( 0x' . trim($status) . ' AS UNSIGNED ) ) as result'; - - $stmt = $conn->prepare($sql); - $stmt->execute(); - $row = $stmt->fetch(PDO::FETCH_ASSOC); - $stmt->closeCursor(); - - $status = '0'; - - if ($row) { - $status = $row['result']; - } - - return $status; + return base_convert($status, 16, 2); } public static function bitIsSet($bitValue, $nthBit) diff --git a/lib/classes/eventsmanager/broker.php b/lib/classes/eventsmanager/broker.php index 24d787d65c..fb9ee347aa 100644 --- a/lib/classes/eventsmanager/broker.php +++ b/lib/classes/eventsmanager/broker.php @@ -11,6 +11,7 @@ use Alchemy\Phrasea\Application; use Alchemy\Phrasea\Model\Entities\User; +use Doctrine\DBAL\Connection; class eventsmanager_broker { @@ -260,13 +261,28 @@ class eventsmanager_broker return false; } - $sql = 'UPDATE notifications SET unread="0" - WHERE usr_id = :usr_id - AND (id="' . implode('" OR id="', $notifications) . '")'; - - $stmt = $this->app['phraseanet.appbox']->get_connection()->prepare($sql); - $stmt->execute([':usr_id' => $usr_id]); - $stmt->closeCursor(); + /** @var Connection $connection */ + $connection = $this->app['phraseanet.appbox']->get_connection(); + $builder = $connection->createQueryBuilder(); + $builder + ->update('notifications') + ->set('unread', '0') + ->where( + $builder->expr()->eq('usr_id', ':usr_id'), + $builder->expr()->in('id', [':notifications']) + ) + ->setParameters( + [ + 'usr_id' => $usr_id, + 'notifications' => $notifications, + ], + [ + 'usr_id' => PDO::PARAM_INT, + 'notifications' => Connection::PARAM_INT_ARRAY, + ] + ) + ->execute() + ; return $this; } diff --git a/lib/classes/module/console/fieldsMerge.php b/lib/classes/module/console/fieldsMerge.php index 6c7e0b540c..438a78f7de 100644 --- a/lib/classes/module/console/fieldsMerge.php +++ b/lib/classes/module/console/fieldsMerge.php @@ -44,6 +44,7 @@ class module_console_fieldsMerge extends Command $output->writeln(""); try { + /** @var databox $databox */ $databox = $this->getService('phraseanet.appbox')->get_databox((int) $input->getArgument('sbas_id')); } catch (\Exception $e) { $output->writeln("Invalid databox id "); @@ -155,11 +156,16 @@ class module_console_fieldsMerge extends Command $start = 0; $quantity = 100; + $builder = $databox->get_connection()->createQueryBuilder(); + $builder + ->select('r.record_id') + ->from('record', 'r') + ->orderBy('r.record_id', 'ASC') + ->setFirstResult($start) + ->setMaxResults($quantity) + ; do { - $sql = 'SELECT record_id FROM record - ORDER BY record_id LIMIT ' . $start . ', ' . $quantity; - $stmt = $databox->get_connection()->prepare($sql); - $stmt->execute(); + $stmt = $builder->execute(); $results = $stmt->fetchAll(PDO::FETCH_ASSOC); $stmt->closeCursor(); diff --git a/lib/classes/module/console/fieldsRename.php b/lib/classes/module/console/fieldsRename.php index 30f8fb76eb..6dbf7f931b 100644 --- a/lib/classes/module/console/fieldsRename.php +++ b/lib/classes/module/console/fieldsRename.php @@ -35,6 +35,7 @@ class module_console_fieldsRename extends Command $new_name = $input->getArgument('name'); try { + /** @var databox $databox */ $databox = $this->getService('phraseanet.appbox')->get_databox((int) $input->getArgument('sbas_id')); } catch (\Exception $e) { $output->writeln("Invalid databox id "); @@ -84,13 +85,18 @@ class module_console_fieldsRename extends Command $start = 0; $quantity = 100; + $builder = $databox->get_connection()->createQueryBuilder(); + $builder + ->select('r.record_id') + ->from('record', 'r') + ->orderBy('r.record_id', 'ASC') + ->setFirstResult($start) + ->setMaxResults($quantity) + ; do { $output->write("\rUpdating records... ".min($start, $total)." / $total"); - $sql = 'SELECT record_id FROM record - ORDER BY record_id LIMIT ' . $start . ', ' . $quantity; - $stmt = $databox->get_connection()->prepare($sql); - $stmt->execute(); + $stmt = $builder->execute(); $results = $stmt->fetchAll(PDO::FETCH_ASSOC); $stmt->closeCursor(); diff --git a/lib/classes/module/console/systemExport.php b/lib/classes/module/console/systemExport.php index 68946ccdde..bc109ebbba 100644 --- a/lib/classes/module/console/systemExport.php +++ b/lib/classes/module/console/systemExport.php @@ -11,6 +11,7 @@ use Alchemy\Phrasea\Command\Command; use Alchemy\Phrasea\Model\Serializer\CaptionSerializer; +use Doctrine\DBAL\Connection; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; @@ -120,6 +121,7 @@ class module_console_systemExport extends Command $total = $errors = 0; + /** @var databox $databox */ foreach ($this->getService('phraseanet.appbox')->get_databoxes() as $databox) { $output->writeln(sprintf("Processing %s", $databox->get_label($this->container['locale']))); @@ -153,20 +155,27 @@ class module_console_systemExport extends Command $this->getService('filesystem')->mkdir($local_export); - $sql = 'SELECT record_id FROM record WHERE parent_record_id = 0 '; + $builder = $databox->get_connection()->createQueryBuilder(); + $builder + ->select('r.record_id') + ->from('record', 'r') + ->where($builder->expr()->eq('r.parent_record_id', $builder->expr()->literal(0))) + ; if (count($coll_ids) > 0) { - $sql .= ' AND coll_id IN (' . implode(', ', $coll_ids) . ') '; + $builder + ->andWhere($builder->expr()->in('r.coll_id', [':collIds'])) + ->setParameter('collIds', $coll_ids, Connection::PARAM_INT_ARRAY) + ; } - $sql .= ' ORDER BY record_id ASC '; + $builder->orderBy('r.record_id', 'ASC'); if ($limit) { - $sql .= ' LIMIT 0, ' . $limit; + $builder->setMaxResults($limit); } - $stmt = $databox->get_connection()->prepare($sql); - $stmt->execute(); + $stmt = $builder->execute(); $rs = $stmt->fetchAll(PDO::FETCH_ASSOC); $stmt->closeCursor(); diff --git a/lib/classes/module/console/systemMailCheck.php b/lib/classes/module/console/systemMailCheck.php index ca93ed0313..17633eb4fd 100644 --- a/lib/classes/module/console/systemMailCheck.php +++ b/lib/classes/module/console/systemMailCheck.php @@ -35,15 +35,15 @@ class module_console_systemMailCheck extends Command { $output->writeln("Processing..."); - $bad_users = []; - if (version_compare($this->getService('phraseanet.appbox')->get_version(), '3.9', '<')) { - $bad_users = MailChecker::getWrongEmailUsers($this->container); - } + /** @var appbox $appBox */ + $appBox = $this->getService('phraseanet.appbox'); + $checker = new MailChecker($appBox); + $bad_users = $checker->getWrongEmailUsers(); foreach ($bad_users as $email => $users) { if ($input->getOption('list')) { - $this->write_infos($email, $users, $output, $this->getService('phraseanet.appbox')); - } elseif ($this->manage_group($email, $users, $output, $this->getService('phraseanet.appbox')) === false) { + $this->write_infos($email, $users, $output, $appBox); + } elseif ($this->manage_group($email, $users, $output, $appBox) === false) { break; } diff --git a/lib/classes/module/report/activity.php b/lib/classes/module/report/activity.php index 022279366f..53aa7aec6f 100644 --- a/lib/classes/module/report/activity.php +++ b/lib/classes/module/report/activity.php @@ -106,8 +106,6 @@ class module_report_activity extends module_report WHERE (" . $filter['sql'] . ") AND !ISNULL(usrid) GROUP BY heures;"; -// no_file_put_contents("/tmp/report.txt", sprintf("%s (%s)\n%s\n\n", __FILE__, __LINE__, $sql), FILE_APPEND); - $stmt = $sqlBuilder->getConnBas()->prepare($sql); $stmt->execute($params); $rs = $stmt->fetchAll(PDO::FETCH_ASSOC); diff --git a/tests/Alchemy/Tests/Phrasea/Controller/SetupTest.php b/tests/Alchemy/Tests/Phrasea/Controller/SetupTest.php index 18c0ecfc1b..7d52ab3bbc 100644 --- a/tests/Alchemy/Tests/Phrasea/Controller/SetupTest.php +++ b/tests/Alchemy/Tests/Phrasea/Controller/SetupTest.php @@ -207,7 +207,7 @@ class SetupTest extends \PhraseanetWebTestCase "port" => $connexion['port'], "user" => $connexion['user'], "password" => $connexion['password'], - "dbname" => $connexion['dbname'], + "db_name" => $connexion['dbname'], ); $client = $this->createClient(); @@ -266,7 +266,7 @@ class SetupTest extends \PhraseanetWebTestCase "port" => $connexion['port'], "user" => $connexion['user'], "password" => $connexion['password'], - "dbname" => "fake-DTABASE-name" + "db_name" => "fake-DTABASE-name" ); $client = $this->createClient(); diff --git a/tests/Alchemy/Tests/Phrasea/Setup/Version/MailCheckerTest.php b/tests/Alchemy/Tests/Phrasea/Setup/Version/MailCheckerTest.php index ac359932b4..ef5a579ed3 100644 --- a/tests/Alchemy/Tests/Phrasea/Setup/Version/MailCheckerTest.php +++ b/tests/Alchemy/Tests/Phrasea/Setup/Version/MailCheckerTest.php @@ -8,8 +8,13 @@ class MailCheckerTest extends \PhraseanetTestCase { public function testMailChecker() { - $users = MailChecker::getWrongEmailUsers(self::$DI['app'], 'usr_tmp'); + $checker = new MailChecker(self::$DI['app']['phraseanet.appbox'], 'usr_tmp'); + $this->assertEmpty($checker->getWrongEmailUsers()); + } - $this->assertEquals(0, count($users)); + public function testItHasNoDuplicateEmailUsers() + { + $checker = new MailChecker(self::$DI['app']['phraseanet.appbox'], 'usr_tmp'); + $this->assertFalse($checker->hasWrongEmailUsers()); } } diff --git a/tests/classes/databox/statusTest.php b/tests/classes/databox/statusTest.php index eec5603695..481d660d22 100644 --- a/tests/classes/databox/statusTest.php +++ b/tests/classes/databox/statusTest.php @@ -1,65 +1,52 @@ databox = self::$DI['record_1']->get_databox(); - $this->object = $this->databox->getStatusStructure(); - } - public function testOperation_and() { - $this->assertEquals('0', databox_status::operation_and(self::$DI['app'], '0x001', '0x010')); - $this->assertEquals('1', databox_status::operation_and(self::$DI['app'], '01', '11')); - $this->assertEquals('0', databox_status::operation_and(self::$DI['app'], '01', '10')); - $this->assertEquals('10', databox_status::operation_and(self::$DI['app'], '11', '10')); + $this->assertEquals('0', databox_status::operation_and('0x001', '0x010')); + $this->assertEquals('1', databox_status::operation_and('01', '11')); + $this->assertEquals('0', databox_status::operation_and('01', '10')); + $this->assertEquals('10', databox_status::operation_and('11', '10')); } public function testOperation_and_not() { - $this->assertEquals('0', databox_status::operation_and_not(self::$DI['app'], '0x001', '0x011')); - $this->assertEquals('0', databox_status::operation_and_not(self::$DI['app'], '01', '11')); - $this->assertEquals('1', databox_status::operation_and_not(self::$DI['app'], '01', '10')); - $this->assertEquals('1', databox_status::operation_and_not(self::$DI['app'], '11', '10')); - $this->assertEquals('10', databox_status::operation_and_not(self::$DI['app'], '10', '01')); + $this->assertEquals('0', databox_status::operation_and_not('0x001', '0x011')); + $this->assertEquals('0', databox_status::operation_and_not('01', '11')); + $this->assertEquals('1', databox_status::operation_and_not('01', '10')); + $this->assertEquals('1', databox_status::operation_and_not('11', '10')); + $this->assertEquals('10', databox_status::operation_and_not('10', '01')); } public function testOperation_mask() { - $this->assertEquals('001101', databox_status::operation_mask(self::$DI['app'], '010101', '0011xx')); - $this->assertEquals('001100', databox_status::operation_mask(self::$DI['app'], '0', '0011xx')); - $this->assertEquals('001101', databox_status::operation_mask(self::$DI['app'], '1', '0011xx')); + $this->assertEquals('001101', databox_status::operation_mask('010101', '0011xx')); + $this->assertEquals('001100', databox_status::operation_mask('0', '0011xx')); + $this->assertEquals('001101', databox_status::operation_mask('1', '0011xx')); } public function testOperation_or() { - $this->assertEquals('10001', databox_status::operation_or(self::$DI['app'], '0x001', '0x011')); - $this->assertEquals('11', databox_status::operation_or(self::$DI['app'], '01', '11')); + $this->assertEquals('10001', databox_status::operation_or('0x001', '0x011')); + $this->assertEquals('11', databox_status::operation_or('01', '11')); } public function testDec2bin() { - $this->assertEquals('1010', databox_status::dec2bin(self::$DI['app'], '10')); + $this->assertEquals('1010', databox_status::dec2bin('10')); } public function testHex2bin() { - $this->assertEquals('10100001', databox_status::hex2bin(self::$DI['app'], '0x0A1')); - $this->assertEquals('10100001', databox_status::hex2bin(self::$DI['app'], '0A1')); + $this->assertEquals('10100001', databox_status::hex2bin('0x0A1')); + $this->assertEquals('10100001', databox_status::hex2bin('0A1')); try { - databox_status::hex2bin(self::$DI['app'], 'G1'); + databox_status::hex2bin('G1'); $this->fail('Should raise an exception'); } catch (Exception $e) { - + $this->assertEquals('Non-hexadecimal value', $e->getMessage()); } } } diff --git a/www/include/jslibs/SWFUpload/swfupload license.txt b/www/include/jslibs/SWFUpload/swfupload license.txt index 80651f436b..9f5170b24b 100644 --- a/www/include/jslibs/SWFUpload/swfupload license.txt +++ b/www/include/jslibs/SWFUpload/swfupload license.txt @@ -3,7 +3,7 @@ * * mmSWFUpload 1.0: Flash upload dialog - http://profandesign.se/swfupload/, http://www.vinterwebb.se/ * - * SWFUpload is (c) 2006-2007 Lars Huring, Olov Nilzén and Mammon Media and is released under the MIT License: + * SWFUpload is (c) 2006-2007 Lars Huring, Olov Nilzén and Mammon Media and is released under the MIT License: * http://www.opensource.org/licenses/mit-license.php * * SWFUpload 2 is (c) 2007-2008 Jake Roberts and is released under the MIT License: