From 75fac19e73f1a6b9299e0c8d034e41c0b3d586ed Mon Sep 17 00:00:00 2001 From: Nicolas Le Goff Date: Fri, 24 Jan 2014 18:45:41 +0100 Subject: [PATCH 1/6] Migrate demand table to doctrine entity && refactor registration API --- .../Phrasea/Controller/Admin/Users.php | 76 +-- .../Phrasea/Controller/Root/Account.php | 16 +- lib/Alchemy/Phrasea/Controller/Root/Login.php | 21 +- .../Provider/RegistrationServiceProvider.php | 19 +- .../Form/Login/PhraseaRegisterForm.php | 37 +- .../Model/Entities/RegistrationDemand.php | 183 +++++++ .../RegistrationDemandRepository.php | 98 ++++ .../Registration/RegistrationManager.php | 454 ++++++++++++++++++ .../RegistrationDemandMigration.php | 28 ++ lib/classes/appbox/register.php | 95 ---- lib/classes/collection.php | 10 +- lib/classes/deprecated/inscript.api.php | 294 ------------ lib/conf.d/migrations.yml | 3 + templates/web/account/access.html.twig | 213 ++++---- templates/web/admin/user/demand.html.twig | 17 +- .../Phrasea/Controller/Admin/UsersTest.php | 1 - .../Phrasea/Controller/Root/AccountTest.php | 45 +- .../Phrasea/Controller/Root/LoginTest.php | 38 +- .../Registration/RegistrationManagerTest.php | 349 ++++++++++++++ 19 files changed, 1331 insertions(+), 666 deletions(-) create mode 100644 lib/Alchemy/Phrasea/Model/Entities/RegistrationDemand.php create mode 100644 lib/Alchemy/Phrasea/Model/Repositories/RegistrationDemandRepository.php create mode 100644 lib/Alchemy/Phrasea/Registration/RegistrationManager.php create mode 100644 lib/Alchemy/Phrasea/Setup/DoctrineMigrations/RegistrationDemandMigration.php delete mode 100644 lib/classes/appbox/register.php delete mode 100644 lib/classes/deprecated/inscript.api.php create mode 100644 tests/Alchemy/Tests/Phrasea/Registration/RegistrationManagerTest.php diff --git a/lib/Alchemy/Phrasea/Controller/Admin/Users.php b/lib/Alchemy/Phrasea/Controller/Admin/Users.php index 51f6359efa..934794b6aa 100644 --- a/lib/Alchemy/Phrasea/Controller/Admin/Users.php +++ b/lib/Alchemy/Phrasea/Controller/Admin/Users.php @@ -354,40 +354,35 @@ class Users implements ControllerProviderInterface })->bind('admin_users_export_csv'); $controllers->get('/demands/', function (Application $app) { - $lastMonth = time() - (3 * 4 * 7 * 24 * 60 * 60); - $sql = "DELETE FROM demand WHERE date_modif < :date"; - $stmt = $app['phraseanet.appbox']->get_connection()->prepare($sql); - $stmt->execute([':date' => date('Y-m-d', $lastMonth)]); - $stmt->closeCursor(); + $app['registration-manager']->deleteOldDemand(); - $basList = array_keys($app['acl']->get($app['authentication']->getUser())->get_granted_base(['canadmin'])); $models = $app['manipulator.user']->getRepository()->findModelOf($app['authentication']->getUser()); - $currentUsr = null; - $table = ['users' => [], 'coll' => []]; + $demands = $app['registration-manager']->getRepository()->getDemandsForUser( + $app['authentication']->getUser(), + array_keys($app['acl']->get($app['authentication']->getUser())->get_granted_base(['canadmin'])) + ); - foreach ($app['EM.native-query']->getUsersRegistrationDemand($basList) as $row) { - $user = $row[0]; + $currentUsr = null; + $table = ['user' => [], 'demand' => []]; + + foreach ($demands as $demand) { + $user = $demand->getUser(); if ($user->getId() !== $currentUsr) { $currentUsr = $user->getId(); - $table['users'][$currentUsr] = [ - 'user' => $user, - 'date_demand' => $row['date_demand'], - ]; + $table['user'][$user->getId()] = $user; } - if (!isset($table['coll'][$user->getId()])) { - $table['coll'][$user->getId()] = []; + if (!isset($table['demand'][$user->getId()])) { + $table['demand'][$user->getId()] = []; } - if (!in_array($row['base_demand'], $table['coll'][$user->getId()])) { - $table['coll'][$user->getId()][] = $row['base_demand']; + if (!array_key_exists($demand->getBaseId(), $table['demand'][$user->getId()][$demand->getBaseId()])) { + $table['demand'][$user->getId()][$demand->getBaseId()] = $demand; } } - $stmt->closeCursor(); - return $app['twig']->render('admin/user/demand.html.twig', [ 'table' => $table, 'models' => $models, @@ -395,7 +390,6 @@ class Users implements ControllerProviderInterface })->bind('users_display_demands'); $controllers->post('/demands/', function (Application $app, Request $request) { - $templates = $deny = $accept = $options = []; foreach ($request->request->get('template', []) as $tmp) { @@ -458,27 +452,13 @@ class Users implements ControllerProviderInterface $done[$usr][$base_id] = true; } - $sql = " - DELETE FROM demand - WHERE usr_id = :usr_id - AND (base_id = " . implode(' OR base_id = ', $base_ids) . ")"; - - $stmt = $app['phraseanet.appbox']->get_connection()->prepare($sql); - $stmt->execute([':usr_id' => $usr]); - $stmt->closeCursor(); + $app['registration-manager']->getRepository()->deleteUserDemands($user, $base_ids); } - $sql = " - UPDATE demand SET en_cours=0, refuser=1, date_modif=now() - WHERE usr_id = :usr_id - AND base_id = :base_id"; - - $stmt = $app['phraseanet.appbox']->get_connection()->prepare($sql); - foreach ($deny as $usr => $bases) { $cache_to_update[$usr] = true; foreach ($bases as $bas) { - $stmt->execute([':usr_id' => $usr, ':base_id' => $bas]); + $app['registration-manager']->rejectDemand($usr, $bas); if (!isset($done[$usr])) { $done[$usr] = []; @@ -488,36 +468,18 @@ class Users implements ControllerProviderInterface } } - $stmt->closeCursor(); - foreach ($accept as $usr => $bases) { $user = $app['manipulator.user']->getRepository()->find($usr); $cache_to_update[$usr] = true; foreach ($bases as $bas) { - $app['acl']->get($user)->give_access_to_sbas([\phrasea::sbasFromBas($app, $bas)]); - - $rights = [ - 'canputinalbum' => '1', - 'candwnldhd' => ($options[$usr][$bas]['HD'] ? '1' : '0'), - 'nowatermark' => ($options[$usr][$bas]['WM'] ? '0' : '1'), - 'candwnldpreview' => '1', - 'actif' => '1', - ]; - - $app['acl']->get($user)->give_access_to_base([$bas]); - $app['acl']->get($user)->update_rights_to_base($bas, $rights); - + $collection = \collection::get_from_base_id($app, $bas); if (!isset($done[$usr])) { $done[$usr] = []; } - $done[$usr][$bas] = true; - $sql = "DELETE FROM demand WHERE usr_id = :usr_id AND base_id = :base_id"; - $stmt = $app['phraseanet.appbox']->get_connection()->prepare($sql); - $stmt->execute([':usr_id' => $usr, ':base_id' => $bas]); - $stmt->closeCursor(); + $app['registration-manager']->acceptDemand($user, $collection, $options[$usr][$bas]['HD'], $options[$usr][$bas]['WM']); } } diff --git a/lib/Alchemy/Phrasea/Controller/Root/Account.php b/lib/Alchemy/Phrasea/Controller/Root/Account.php index 6be7b357c8..cf831f73e8 100644 --- a/lib/Alchemy/Phrasea/Controller/Root/Account.php +++ b/lib/Alchemy/Phrasea/Controller/Root/Account.php @@ -231,10 +231,8 @@ class Account implements ControllerProviderInterface */ public function accountAccess(Application $app, Request $request) { - require_once $app['root.path'] . '/lib/classes/deprecated/inscript.api.php'; - return $app['twig']->render('account/access.html.twig', [ - 'inscriptions' => giveMeBases($app, $app['authentication']->getUser()->getId()) + 'inscriptions' => $app['registration-manager']->getRegistrationInformations($app['authentication']->getUser()->getId()) ]); } @@ -328,17 +326,11 @@ class Account implements ControllerProviderInterface */ public function updateAccount(PhraseaApplication $app, Request $request) { - $demands = (array) $request->request->get('demand', []); - - if (0 !== count($demands)) { + if (0 !== count($demands = (array) $request->request->get('demand', []))) { foreach ($demands as $baseId) { - try { - $app['phraseanet.appbox-register']->add_request($app['authentication']->getUser(), \collection::get_from_base_id($app, $baseId)); - $app->addFlash('success', $app->trans('login::notification: Vos demandes ont ete prises en compte')); - } catch (\Exception $e) { - - } + $app['registration-manager']->newDemand($app['authentication']->getUser()->getId(), $baseId); } + $app->addFlash('success', $app->trans('login::notification: Vos demandes ont ete prises en compte')); } $accountFields = [ diff --git a/lib/Alchemy/Phrasea/Controller/Root/Login.php b/lib/Alchemy/Phrasea/Controller/Root/Login.php index d5c3feb814..cbf8af0df9 100644 --- a/lib/Alchemy/Phrasea/Controller/Root/Login.php +++ b/lib/Alchemy/Phrasea/Controller/Root/Login.php @@ -38,6 +38,7 @@ use Alchemy\Phrasea\Form\Login\PhraseaForgotPasswordForm; use Alchemy\Phrasea\Form\Login\PhraseaRecoverPasswordForm; use Alchemy\Phrasea\Form\Login\PhraseaRegisterForm; use Doctrine\ORM\EntityManager; +use igorw; use Silex\Application; use Silex\ControllerProviderInterface; use Symfony\Component\HttpFoundation\Cookie; @@ -329,14 +330,12 @@ class Login implements ControllerProviderInterface throw new FormProcessingException($app->trans('Invalid captcha answer.')); } - require_once $app['root.path'] . '/lib/classes/deprecated/inscript.api.php'; - if ($app['conf']->get(['registry', 'registration', 'auto-select-collections'])) { $selected = null; } else { $selected = isset($data['collections']) ? $data['collections'] : null; } - $inscriptions = giveMeBases($app); + $inscriptions = $app['registration-manager']->getRegistrationInformations(); $inscOK = []; foreach ($app['phraseanet.appbox']->get_databoxes() as $databox) { @@ -345,15 +344,8 @@ class Login implements ControllerProviderInterface continue; } - $sbas_id = $databox->get_sbas_id(); - - if (isset($inscriptions[$sbas_id]) - && $inscriptions[$sbas_id]['inscript'] === true - && (isset($inscriptions[$sbas_id]['Colls'][$collection->get_coll_id()]) - || isset($inscriptions[$sbas_id]['CollsCGU'][$collection->get_coll_id()]))) { - $inscOK[$collection->get_base_id()] = true; - } else { - $inscOK[$collection->get_base_id()] = false; + if ($canRegister = igorw\get_in($inscriptions, [$databox->get_sbas_id(), 'config', 'collections', $collection->get_base_id(), 'can-register'])) { + $inscOK[$collection->get_base_id()] = $canRegister; } } } @@ -414,8 +406,7 @@ class Login implements ControllerProviderInterface continue; } - $collection = \collection::get_from_base_id($app, $base_id); - $app['phraseanet.appbox-register']->add_request($user, $collection); + $app['registration-manager']->newDemand($user->getId(), $base_id); $demandOK[$base_id] = true; } @@ -750,8 +741,6 @@ class Login implements ControllerProviderInterface */ public function login(PhraseaApplication $app, Request $request) { - require_once $app['root.path'] . '/lib/classes/deprecated/inscript.api.php'; - try { $app['phraseanet.appbox']->get_connection(); } catch (\Exception $e) { diff --git a/lib/Alchemy/Phrasea/Core/Provider/RegistrationServiceProvider.php b/lib/Alchemy/Phrasea/Core/Provider/RegistrationServiceProvider.php index 62c1cf2fa2..8f1110c82c 100644 --- a/lib/Alchemy/Phrasea/Core/Provider/RegistrationServiceProvider.php +++ b/lib/Alchemy/Phrasea/Core/Provider/RegistrationServiceProvider.php @@ -12,6 +12,7 @@ namespace Alchemy\Phrasea\Core\Provider; use Alchemy\Phrasea\Form\Constraint\NewLogin; +use Alchemy\Phrasea\Registration\RegistrationManager; use Alchemy\Phrasea\Model\Entities\User; use Silex\Application; use Silex\ServiceProviderInterface; @@ -26,19 +27,7 @@ class RegistrationServiceProvider implements ServiceProviderInterface }); $app['registration.enabled'] = $app->share(function (Application $app) { - require_once __DIR__ . '/../../../../classes/deprecated/inscript.api.php'; - - $bases = giveMeBases($app); - - if ($bases) { - foreach ($bases as $base) { - if ($base['inscript']) { - return true; - } - } - } - - return false; + return $app['registration-manager']->isRegistrationEnabled(); }); $app['registration.optional-fields'] = $app->share(function (Application $app) { @@ -134,6 +123,10 @@ class RegistrationServiceProvider implements ServiceProviderInterface ], ]; }); + + $app['registration-manager'] = $app->share(function (Application $app) { + return new RegistrationManager($app['EM'], $app['phraseanet.appbox'], $app['acl']); + }); } public function boot(Application $app) diff --git a/lib/Alchemy/Phrasea/Form/Login/PhraseaRegisterForm.php b/lib/Alchemy/Phrasea/Form/Login/PhraseaRegisterForm.php index 0792dce296..0654856c3b 100644 --- a/lib/Alchemy/Phrasea/Form/Login/PhraseaRegisterForm.php +++ b/lib/Alchemy/Phrasea/Form/Login/PhraseaRegisterForm.php @@ -72,39 +72,22 @@ class PhraseaRegisterForm extends AbstractType $builder->add('provider-id', 'hidden'); - require_once $this->app['root.path'] . '/lib/classes/deprecated/inscript.api.php'; $choices = []; $baseIds = []; - foreach (\giveMeBases($this->app) as $sbas_id => $baseInsc) { - if (($baseInsc['CollsCGU'] || $baseInsc['Colls']) && $baseInsc['inscript']) { - if ($baseInsc['Colls']) { - foreach ($baseInsc['Colls'] as $collId => $collName) { - $baseId = \phrasea::baseFromColl($sbas_id, $collId, $this->app); - $sbasName= \phrasea::sbas_names($sbas_id, $this->app); - - if (!isset($choices[$sbasName])) { - $choices[$sbasName] = []; - } - - $choices[$sbasName][$baseId] = \phrasea::bas_labels($baseId, $this->app); - $baseIds[] = $baseId; - } + foreach ($this->app['registration-manager']->getRegistrationInformations() as $baseInfo) { + $dbName = $baseInfo['config']['db-name']; + foreach ($baseInfo['config']['collections'] as $baseId => $collInfo) { + if (false === $collInfo['can-register']) { + continue; } - if ($baseInsc['CollsCGU']) { - foreach ($baseInsc['CollsCGU'] as $collId => $collName) { - $baseId = \phrasea::baseFromColl($sbas_id, $collId, $this->app); - $sbasName= \phrasea::sbas_names($sbas_id, $this->app); - - if (!isset($choices[$sbasName])) { - $choices[$sbasName] = []; - } - - $choices[$sbasName][$baseId] = \phrasea::bas_labels($baseId, $this->app); - $baseIds[] = $baseId; - } + if (!isset($choices[$dbName])) { + $choices[$dbName] = []; } + + $choices[$dbName][$baseId] = \phrasea::bas_labels($baseId, $this->app); + $baseIds[] = $baseId; } } diff --git a/lib/Alchemy/Phrasea/Model/Entities/RegistrationDemand.php b/lib/Alchemy/Phrasea/Model/Entities/RegistrationDemand.php new file mode 100644 index 0000000000..f4a45a9e4a --- /dev/null +++ b/lib/Alchemy/Phrasea/Model/Entities/RegistrationDemand.php @@ -0,0 +1,183 @@ +id; + } + + /** + * @param mixed $pending + * + * @return RegistrationDemand + */ + public function setPending($pending) + { + $this->pending = (Boolean) $pending; + + return $this; + } + + /** + * @return mixed + */ + public function isPending() + { + return $this->pending; + } + + /** + * @param mixed $rejected + * + * @return RegistrationDemand + */ + public function setRejected($rejected) + { + $this->rejected = (Boolean) $rejected; + + return $this; + } + + /** + * @return mixed + */ + public function isRejected() + { + return $this->rejected; + } + + /** + * @param mixed $user + * + * @return RegistrationDemand + */ + public function setUser($user) + { + $this->user = $user; + + return $this; + } + + /** + * @return mixed + */ + public function getUser() + { + return $this->user; + } + + /** + * @param mixed $baseId + * + * @return RegistrationDemand + */ + public function setBaseId($baseId) + { + $this->baseId = $baseId; + + return $this; + } + + /** + * @return mixed + */ + public function getBaseId() + { + return $this->baseId; + } + + /** + * @return \DateTime + */ + public function getCreated() + { + return $this->created; + } + + /** + * @return \DateTime + */ + public function getUpdated() + { + return $this->updated; + } + + /** + * @param \Datetime $created + */ + public function setCreated(\Datetime $created) + { + $this->created = $created; + } + + /** + * @param \Datetime $updated + */ + public function setUpdated(\Datetime $updated) + { + $this->updated = $updated; + } +} diff --git a/lib/Alchemy/Phrasea/Model/Repositories/RegistrationDemandRepository.php b/lib/Alchemy/Phrasea/Model/Repositories/RegistrationDemandRepository.php new file mode 100644 index 0000000000..84a9ae9774 --- /dev/null +++ b/lib/Alchemy/Phrasea/Model/Repositories/RegistrationDemandRepository.php @@ -0,0 +1,98 @@ +createQueryBuilder('d'); + $qb->where($qb->expr()->eq('d.user', ':user')); + $qb->setParameter(':user', $user->get_id()); + + if (count($baseList) > 0) { + $qb->andWhere('d.baseId IN (:bases)'); + $qb->setParameter(':bases', $baseList); + } + + $qb->orderBy('d.created', 'DESC'); + + return $qb->getQuery()->getResult(); + } + + /** + * Deletes demands for user on collection. + * + * @param \User_Adapter $user + * @param array $baseList + * + * @return mixed + */ + public function deleteUserDemands(\User_Adapter $user, $baseList = []) + { + $qb = $this->createQueryBuilder('d'); + $qb->delete('Alchemy\Phrasea\Model\Entities\RegistrationDemand', 'd'); + $qb->where($qb->expr()->eq('d.user', ':user')); + $qb->setParameter(':user', $user->get_id()); + + if (count($baseList) > 0) { + $qb->andWhere('d.baseId IN (:bases)'); + $qb->setParameter(':bases', $baseList); + } + + return $qb->getQuery()->execute(); + } + + /** + * Deletes outdated demands. + * + * @param string $limit + */ + public function deleteDemandsOldestThan($limit = '-1 month') + { + $qb = $this->createQueryBuilder('d'); + $qb->delete('Alchemy\Phrasea\Model\Entities\RegistrationDemand', 'd'); + $qb->where($qb->expr()->lt('d.created', ':date')); + $qb->setParameter(':date', new \DateTime($limit)); + $qb->getQuery()->execute(); + } + + /** + * Deletes demands on collection. + * + * @param $baseId + */ + public function deleteDemandsOnCollection($baseId) + { + $qb = $this->createQueryBuilder('d'); + $qb->delete('Alchemy\Phrasea\Model\Entities\RegistrationDemand', 'd'); + $qb->where($qb->expr()->eq('d.baseId', ':base')); + $qb->setParameter(':base', $baseId); + $qb->getQuery()->execute(); + } +} diff --git a/lib/Alchemy/Phrasea/Registration/RegistrationManager.php b/lib/Alchemy/Phrasea/Registration/RegistrationManager.php new file mode 100644 index 0000000000..542ba32d23 --- /dev/null +++ b/lib/Alchemy/Phrasea/Registration/RegistrationManager.php @@ -0,0 +1,454 @@ +em = $em; + $this->appbox = $appbox; + $this->repository = $this->em->getRepository('Alchemy\Phrasea\Model\Entities\RegistrationDemand'); + $this->aclProvider = $aclProvider; + } + + /** + * Creates a new demand. + * + * @param $userId + * @param $baseId + * + * @return RegistrationDemand + */ + public function newDemand($userId, $baseId) + { + $demand = new RegistrationDemand(); + $demand->setUser($userId); + $demand->setBaseId($baseId); + $this->em->persist($demand); + $this->em->flush(); + + return $demand; + } + + /** + * Rejects a demand. + * + * @param $usrId + * @param $baseId + */ + public function rejectDemand($usrId, $baseId) + { + if ($demand = $this->getRepository()->findOneBy([ + 'user' => $usrId, + 'baseId' => $baseId + ])) { + $demand->setPending(false); + $demand->setRejected(true); + $this->em->persist($demand); + } + $this->em->flush(); + } + + /** + * Accepts a demand. + * + * @param $userId + * @param $basId + */ + public function acceptDemand(\User_Adapter $user, \Collection $collection, $grantHd = false, $grantWatermark = false) + { + if ($demand = $this->getRepository()->findOneBy([ + 'user' => $user->get_id(), + 'baseId' => $collection->get_base_id() + ])) { + $this->aclProvider->get($user)->give_access_to_sbas([$collection->get_sbas_id()]); + $this->aclProvider->get($user)->give_access_to_base([$collection->get_base_id()]); + $this->aclProvider->get($user)->update_rights_to_base($collection->get_base_id(), [ + 'canputinalbum' => '1', + 'candwnldhd' => (string) (int) $grantHd, + 'nowatermark' => (string) (int) $grantWatermark, + 'candwnldpreview' => '1', + 'actif' => '1', + ]); + $this->em->remove($demand); + $this->em->flush(); + } + } + + /** + * Tells whether registration is enabled or not. + * + * @return boolean + */ + public function isRegistrationEnabled() + { + $enabled = false; + foreach ($this->getRegistrationInformations() as $baseInfo) { + foreach ($baseInfo['config']['collections'] as $collInfo) { + if ($collInfo['can-register']) { + $enabled = true; + break 2; + } + } + } + + return $enabled; + } + + /** + * Gets information about registration configuration and demand status if a user id is provided. + * + * @param null|integer $userId + * + * @return array + */ + public function getRegistrationInformations($userId = null) + { + $data = $userData = []; + + if (null !== $userId) { + $userData = $this->getRegistrationDemandsForUser($userId); + } + + foreach ($this->appbox->get_databoxes() as $databox) { + $ddata = [ + 'demands' => [ + 'by-type' => [ + 'inactive' => [], + 'accepted' => [], + 'in-time' => [], + 'out-dated' => [], + 'pending' => [], + 'rejected' => [], + ], + 'by-collection' => [] + ], + 'config' => [ + 'db-name' => $databox->get_dbname(), + 'cgu' => $this->getCguPreferencesForDatabox($databox), + 'cgu-release' => $this->getCguReleasedPreferencesForDatabox($databox), + 'can-register' => $this->isRegistrationEnabledForDatabox($databox), + 'collections' => [], + ] + ]; + + foreach ($databox->get_collections() as $collection) { + // sets collection info + $ddata['config']['collections'][$collection->get_base_id()] = [ + 'coll-name' => $collection->get_name(), + // gets collection registration or fallback to databox configuration + 'can-register' => $this->isRegistrationDefinedForCollection($collection) ? + $this->isRegistrationEnabledForCollection($collection) : $ddata['config']['can-register'], + 'cgu' => $this->getCguPreferencesForCollection($collection), + 'cgu-release' => $this->getCguReleasedPreferencesForCollection($collection), + 'demand' => null + ]; + + if (null === $userDemand = igorw\get_in($userData, [$databox->get_sbas_id(), $collection->get_base_id()])) { + continue; + } + + // sets collection name + $userDemand['coll-name'] = $collection->get_name(); + // gets demand entity + $demand = $userDemand['demand']; + + $noDemandMade = is_null($userDemand['active']); + $demandMade = !$noDemandMade; + $demandStillExists = !is_null($demand); + $demandNoMoreExists = !$demandStillExists; + $isPending = $demandStillExists && $demand->isPending() && !$demand->isRejected(); + $isRejected = $demandStillExists && $demand->isRejected(); + $isDone = ($demandNoMoreExists && $demandMade) || (!$isPending && !$isRejected); + $isActive = (Boolean) $userDemand['active']; + $isTimeLimited = (Boolean) $userDemand['time-limited']; + $isNotTimeLimited = !$isTimeLimited; + $isOnTime = (Boolean) $userDemand['in-time']; + $isOutDated = !$isOnTime; + + if ($noDemandMade) { + continue; + } + // sets demands + $ddata['config']['collections'][$collection->get_base_id()]['demand'] = $userDemand; + $ddata['demands']['by-collection'][$collection->get_base_id()] = $userDemand; + + if (!$isActive) { + $ddata['demands']['by-type']['inactive'][] = $userDemand; + continue; + } + + if ($isDone) { + $ddata['demands']['by-type']['accepted'][] = $userDemand; + continue; + } + + if ($isRejected) { + $ddata['demands']['by-type']['rejected'][] = $userDemand; + continue; + } + + if ($isTimeLimited && $isOnTime && $isPending) { + $ddata['demands']['by-type']['in-time'][] = $userDemand; + continue; + } + + if ($isTimeLimited && $isOutDated && $isPending) { + $ddata['demands']['by-type']['out-time'][] = $userDemand; + continue; + } + + if ($isNotTimeLimited && $isPending) { + $ddata['demands']['by-type']['pending'][] = $userDemand; + } + } + } + + $data[$databox->get_sbas_id()] = $ddata; + + return $data; + } + + /** + * Gets registration demands for a user. + * + * @param $usrId + * + * @return array + */ + public function getRegistrationDemandsForUser($usrId) + { + $data = []; + $rsm = new ResultSetMappingBuilder($this->em); + $rsm->addRootEntityFromClassMetadata('Alchemy\Phrasea\Model\Entities\RegistrationDemand', 'd'); + $rsm->addScalarResult('sbas_id','sbas_id'); + $rsm->addScalarResult('bas_id','bas_id'); + $rsm->addScalarResult('dbname','dbname'); + $rsm->addScalarResult('time_limited', 'time_limited'); + $rsm->addScalarResult('limited_from', 'limited_from'); + $rsm->addScalarResult('limited_to', 'limited_to'); + $rsm->addScalarResult('actif', 'actif'); + + $sql = " + SELECT dbname, sbas.sbas_id, time_limited, + UNIX_TIMESTAMP( limited_from ) AS limited_from, + UNIX_TIMESTAMP( limited_to ) AS limited_to, + bas.server_coll_id, usr.usr_id, basusr.actif, + bas.base_id AS bas_id , " . $rsm->generateSelectClause(['d' => 'd',]) . " + FROM (usr, bas, sbas) + LEFT JOIN basusr ON ( usr.usr_id = basusr.usr_id AND bas.base_id = basusr.base_id ) + LEFT JOIN RegistrationDemand d ON ( d.user_id = usr.usr_id AND bas.base_id = d.base_id ) + WHERE bas.active = 1 AND bas.sbas_id = sbas.sbas_id + AND usr.usr_id = ? + AND model_of = 0"; + + $query = $this->em->createNativeQuery($sql, $rsm); + $query->setParameter(1, $usrId); + + foreach ($query->getResult() as $row) { + $demandEntity = $row[0]; + + $data[$row['sbas_id']][$row['bas_id']] = [ + 'base-id' => $row['bas_id'], + 'db-name' => $row['dbname'], + 'active' => (Boolean) $row['actif'], + 'time-limited' => (Boolean) $row['time_limited'], + 'in-time' => $row['time_limited'] && ! ($row['limited_from'] >= time() && $row['limited_to'] <= time()), + 'demand' => $demandEntity + ]; + } + + return $data; + } + + /** + * Gets RegistrationDemands Repository. + * + * @return \Doctrine\ORM\EntityRepository + */ + public function getRepository() + { + return $this->repository; + } + + /** + * Deletes old demands. + */ + public function deleteOldDemand() + { + $this->repository->deleteDemandsOldestThan('-1 month'); + } + + /** + * Tells whether the registration is enable for provided databox or not. + * + * @param \databox $databox + * + * @return boolean + */ + public function isRegistrationEnabledForDatabox(\databox $databox) + { + $enabled = false; + + if ($xml = $databox->get_sxml_structure()) { + foreach ($xml->xpath('/record/caninscript') as $caninscript) { + $enabled = (Boolean) (string) $caninscript; + break; + } + } + + return $enabled; + } + + /** + * Gets CGU released preference for provided databox. + * + * @param \databox $databox + * + * @return null|string + */ + public function getCguReleasedPreferencesForDatabox(\databox $databox) + { + $cguRelease = null; + + if ($xml = $databox->get_sxml_structure()) { + foreach ($xml->xpath('/record/cgu') as $sbpcgu) { + foreach ($sbpcgu->attributes() as $a => $b) { + if ($a == "release") { + $cguRelease = (string) $b; + break 2; + } + } + } + } + + return $cguRelease; + } + + /** + * Gets Cgu preference for provided databox. + * + * @param \databox $databox + * + * @return null|string + */ + public function getCguPreferencesForDatabox(\databox $databox) + { + $cgu = null; + + if ($xml = $databox->get_sxml_structure()) { + foreach ($xml->xpath('/record/cgu') as $sbpcgu) { + $cgu = (string) $sbpcgu->saveXML(); + break; + } + } + + return $cgu; + } + + /** + * Tells whether registration is activated for provided collection or not. + * + * @param \collection $collection + * + * @return boolean + */ + public function isRegistrationEnabledForCollection(\collection $collection) + { + $enabled = false; + if ($xml = simplexml_load_string($collection->get_prefs())) { + foreach ($xml->xpath('/baseprefs/caninscript') as $caninscript) { + $enabled = (Boolean) (string) $caninscript; + break; + } + } + + return $enabled; + } + + /** + * Gets CGU released preferences for provided collection. + * + * @param \collection $collection + * + * @return null|string + */ + public function getCguReleasedPreferencesForCollection(\collection $collection) + { + $cguRelease = null; + + if ($xml = simplexml_load_string($collection->get_prefs())) { + foreach ($xml->xpath('/baseprefs/cgu') as $sbpcgu) { + foreach ($sbpcgu->attributes() as $a => $b) { + if ($a == "release") { + $cguRelease = (string) $b; + break 2; + } + } + } + } + + return $cguRelease; + } + + /** + * Gets CGU preferences for provided collection. + * + * @param \collection $collection + * + * @return null|string + */ + public function getCguPreferencesForCollection(\collection $collection) + { + $cgu = null; + + if ($xml = simplexml_load_string($collection->get_prefs())) { + foreach ($xml->xpath('/baseprefs/cgu') as $sbpcgu) { + $cgu = (string) $sbpcgu->saveXML(); + break; + } + } + + return $cgu; + } + + /** + * Tells whether registration preference is defined for provided collection. + * + * @param \collection $collection + * + * @return bool + */ + private function isRegistrationDefinedForCollection(\collection $collection) + { + $defined = false; + if ($xml = simplexml_load_string($collection->get_prefs())) { + if (count($xml->xpath('/baseprefs/caninscript')) > 0) { + $defined = true; + } + } + + return $defined; + } +} diff --git a/lib/Alchemy/Phrasea/Setup/DoctrineMigrations/RegistrationDemandMigration.php b/lib/Alchemy/Phrasea/Setup/DoctrineMigrations/RegistrationDemandMigration.php new file mode 100644 index 0000000000..1da763cc79 --- /dev/null +++ b/lib/Alchemy/Phrasea/Setup/DoctrineMigrations/RegistrationDemandMigration.php @@ -0,0 +1,28 @@ +addSql("CREATE TABLE RegistrationDemand (id INT AUTO_INCREMENT NOT NULL, user_id INT NOT NULL, base_id INT NOT NULL, pending TINYINT(1) NOT NULL, rejected TINYINT(1) NOT NULL, created DATETIME NOT NULL, updated DATETIME NOT NULL, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB"); + } + + public function doDownSql(Schema $schema) + { + $this->addSql("DROP TABLE RegistrationDemand"); + } +} diff --git a/lib/classes/appbox/register.php b/lib/classes/appbox/register.php deleted file mode 100644 index 89442dc565..0000000000 --- a/lib/classes/appbox/register.php +++ /dev/null @@ -1,95 +0,0 @@ -appbox = $appbox; - - return $this; - } - - /** - * Add a registration request for a user on a collection - * - * @param User $user - * @param collection $collection - * @return appbox_register - */ - public function add_request(User $user, collection $collection) - { - $sql = "INSERT INTO demand (date_modif, usr_id, base_id, en_cours, refuser) - VALUES (now(), :usr_id , :base_id, 1, 0)"; - $stmt = $this->appbox->get_connection()->prepare($sql); - $stmt->execute([':usr_id' => $user->getId(), ':base_id' => $collection->get_base_id()]); - $stmt->closeCursor(); - - return $this; - } - - /** - * Return an array of collection objects where provided - * user is waiting for approbation - * - * @param Application $app - * @param User $user - * - * @return array - */ - public function get_collection_awaiting_for_user(Application $app, User $user) - { - $sql = 'SELECT base_id FROM demand WHERE usr_id = :usr_id AND en_cours="1" '; - $stmt = $this->appbox->get_connection()->prepare($sql); - $stmt->execute([':usr_id' => $user->getId()]); - $rs = $stmt->fetchAll(PDO::FETCH_ASSOC); - $stmt->closeCursor(); - $ret = []; - foreach ($rs as $row) { - $ret[] = collection::get_from_base_id($app, $row['base_id']); - } - - return $ret; - } - - /** - * Remove all registration older than a month - * - * @param appbox $appbox - * @return appbox_register - */ - public static function clean_old_requests(appbox $appbox) - { - $lastMonth = new DateTime('-1 month'); - $sql = "delete from demand where date_modif < :lastMonth"; - $stmt = $appbox->get_connection()->prepare($sql); - $stmt->execute([':lastMonth' => $lastMonth->format(DATE_ISO8601)]); - $stmt->closeCursor(); - - return; - } -} diff --git a/lib/classes/collection.php b/lib/classes/collection.php index 2e39306bb4..70056d1db7 100644 --- a/lib/classes/collection.php +++ b/lib/classes/collection.php @@ -406,10 +406,7 @@ class collection implements cache_cacheableInterface $stmt->execute([':base_id' => $this->get_base_id()]); $stmt->closeCursor(); - $sql = "DELETE FROM demand WHERE base_id = :base_id"; - $stmt = $appbox->get_connection()->prepare($sql); - $stmt->execute([':base_id' => $this->get_base_id()]); - $stmt->closeCursor(); + $this->app['registration-manager']->getRepository()->deleteDemandsOnCollection($this->get_base_id()); $this->get_databox()->delete_data_from_cache(databox::CACHE_COLLECTIONS); @@ -537,10 +534,7 @@ class collection implements cache_cacheableInterface $stmt->execute($params); $stmt->closeCursor(); - $sql = "DELETE FROM demand WHERE base_id = :base_id"; - $stmt = $app['phraseanet.appbox']->get_connection()->prepare($sql); - $stmt->execute($params); - $stmt->closeCursor(); + $this->app['registration-manager']->getRepository()->deleteDemandsOnCollection($this->get_base_id()); phrasea::reset_baseDatas($app['phraseanet.appbox']); diff --git a/lib/classes/deprecated/inscript.api.php b/lib/classes/deprecated/inscript.api.php deleted file mode 100644 index f0c266dcc1..0000000000 --- a/lib/classes/deprecated/inscript.api.php +++ /dev/null @@ -1,294 +0,0 @@ -get_connection(); - - $inscriptions = null; - - $usrerRegis = null; - - if ($usr != null) { - - $sqlU = ' - SELECT sbas.dbname, time_limited, UNIX_TIMESTAMP( limited_from ) AS limited_from, - UNIX_TIMESTAMP( limited_to ) AS limited_to, bas.server_coll_id, - u.id, basusr.actif, demand.en_cours, demand.refuser - FROM (Users u, bas, sbas) - LEFT JOIN basusr ON ( u.id = basusr.usr_id - AND bas.base_id = basusr.base_id ) - LEFT JOIN demand ON ( demand.usr_id = u.id - AND bas.base_id = demand.base_id ) - WHERE bas.active > 0 - AND bas.sbas_id = sbas.sbas_id - AND u.id = :usr_id - AND u.model_of IS NULL - '; - - $stmt = $conn->prepare($sqlU); - $stmt->execute([':usr_id' => $usr]); - $rsU = $stmt->fetchAll(PDO::FETCH_ASSOC); - $stmt->closeCursor(); - - if (count($rsU) == 0) { - return null; - } - - foreach ($rsU as $rowU) { - if ( ! isset($usrerRegis[$rowU['dbname']])) - $usrerRegis[$rowU['dbname']] = null; - - if ( ! is_null($rowU['actif']) || ! is_null($rowU['en_cours'])) { - - $usrerRegis[$rowU['dbname']][$rowU['server_coll_id']] = true; - if ($rowU['actif'] == '0') - $usrerRegis[$rowU['dbname']][$rowU['server_coll_id']] = 'NONACTIF'; - elseif ($rowU['time_limited'] == '1' && ! ($rowU['limited_from'] >= time() && $rowU['limited_to'] <= time())) - $usrerRegis[$rowU['dbname']][$rowU['server_coll_id']] = 'OUTTIME'; - elseif ($rowU['time_limited'] == '1' && ($rowU['limited_from'] > time() && $rowU['limited_to'] < time())) - $usrerRegis[$rowU['dbname']][$rowU['server_coll_id']] = 'INTIME'; - elseif ($rowU['en_cours'] == '1') - $usrerRegis[$rowU['dbname']][$rowU['server_coll_id']] = 'WAIT'; - elseif ($rowU['refuser'] == '1') - $usrerRegis[$rowU['dbname']][$rowU['server_coll_id']] = 'REFUSE'; - } - } - } - - foreach ($app['phraseanet.appbox']->get_databoxes() as $databox) { - $collname = $basname = null; - $sbas_id = $databox->get_sbas_id(); - $inscriptions[$sbas_id] = []; - $inscriptions[$sbas_id]['CGU'] = false; - $inscriptions[$sbas_id]['CGUrelease'] = false; - $inscriptions[$sbas_id]['inscript'] = false; - $inscriptions[$sbas_id]['CollsCGU'] = null; - $inscriptions[$sbas_id]['Colls'] = null; - $inscriptions[$sbas_id]['CollsRegistered'] = null; - $inscriptions[$sbas_id]['CollsWait'] = null; - $inscriptions[$sbas_id]['CollsRefuse'] = null; - $inscriptions[$sbas_id]['CollsIntime'] = null; - $inscriptions[$sbas_id]['CollsOuttime'] = null; - $inscriptions[$sbas_id]['CollsNonactif'] = null; - - foreach ($databox->get_collections() as $key => $coll) { - $collname[$key] = $coll->get_label($app['locale']); - $basname[$key] = $coll->get_coll_id(); - } - $sbpcgu = ''; - - $xml = $databox->get_sxml_structure(); - if ($xml) { - foreach ($xml->xpath('/record/caninscript') as $caninscript) { - if ($inscriptions[$sbas_id]['inscript'] === false) - $inscriptions[$sbas_id]['inscript'] = ((string) $caninscript == "1"); - } - foreach ($xml->xpath('/record/cgu') as $sbpcgu) { - foreach ($sbpcgu->attributes() as $a => $b) { - if ($a == "release") - $inscriptions[$sbas_id]['CGUrelease'] = (string) $b; - } - $inscriptions[$sbas_id]['CGU'] = (string) $sbpcgu->saveXML(); - } - } - $baseInscript = $inscriptions[$sbas_id]['inscript']; - foreach ($databox->get_collections() as $collection) { - $cguColl = false; - - $collInscript = $baseInscript; - $cguSpec = false; - if (false !== $xml = simplexml_load_string($collection->get_prefs())) { - foreach ($xml->xpath('/baseprefs/caninscript') as $caninscript) { - $tmp = (string) $caninscript; - if ($tmp === "1") - $collInscript = true; - elseif ($tmp === "0") - $collInscript = false; - } - if ($collInscript) { - $cguCollRelease = false; - - if ($inscriptions[$sbas_id]['inscript'] === false) - $inscriptions[$sbas_id]['inscript'] = ! ! $collInscript; - - foreach ($xml->xpath('/baseprefs/cgu') as $bpcgu) { - foreach ($bpcgu->attributes() as $a => $b) { - if ($a == "release") - $cguCollRelease = (string) $b; - } - $cguColl = (string) $bpcgu->saveXML(); - } - if ($cguColl) { - $cguSpec = true; - } else { - if ( ! isset($usrerRegis[$databox->get_dbname()][$collection->get_coll_id()])) - $inscriptions[$sbas_id]['Colls'][$collection->get_coll_id()] = $collection->get_label($app['locale']); - } - } - } - $lacgu = $cguColl ? $cguColl : (string) $sbpcgu; - - if (isset($usrerRegis[$databox->get_dbname()]) && isset($usrerRegis[$databox->get_dbname()][$collection->get_coll_id()])) { - if ($usrerRegis[$databox->get_dbname()][$collection->get_coll_id()] === "WAIT") - $inscriptions[$sbas_id]['CollsWait'][$collection->get_coll_id()] = $lacgu; - elseif ($usrerRegis[$databox->get_dbname()][$collection->get_coll_id()] === "REFUSE") - $inscriptions[$sbas_id]['CollsRefuse'][$collection->get_coll_id()] = $lacgu; - elseif ($usrerRegis[$databox->get_dbname()][$collection->get_coll_id()] === "INTIME") - $inscriptions[$sbas_id]['CollsIntime'][$collection->get_coll_id()] = $lacgu; - elseif ($usrerRegis[$databox->get_dbname()][$collection->get_coll_id()] === "OUTTIME") - $inscriptions[$sbas_id]['CollsOuttime'][$collection->get_coll_id()] = $lacgu; - elseif ($usrerRegis[$databox->get_dbname()][$collection->get_coll_id()] === "NONACTIF") - $inscriptions[$sbas_id]['CollsNonactif'][$collection->get_coll_id()] = $lacgu; - elseif ($usrerRegis[$databox->get_dbname()][$collection->get_coll_id()] === true) - $inscriptions[$sbas_id]['CollsRegistered'][$collection->get_coll_id()] = $lacgu; - } elseif (! $cguSpec && $collInscript) {//ne va pas.. si l'inscriptio na la coll est explicitement non autorise, je refuse' - $inscriptions[$sbas_id]['Colls'][$collection->get_coll_id()] = $collection->get_label($app['locale']); - } elseif ($cguSpec) { - $inscriptions[$sbas_id]['CollsCGU'][$collection->get_coll_id()]['name'] = $collection->get_label($app['locale']); - $inscriptions[$sbas_id]['CollsCGU'][$collection->get_coll_id()]['CGU'] = $cguColl; - $inscriptions[$sbas_id]['CollsCGU'][$collection->get_coll_id()]['CGUrelease'] = $cguCollRelease; - } - } - } - - return $inscriptions; -} - -function giveMeBaseUsr(Application $app, $usr) -{ - $noDemand = true; - - $out = '' . - '' . - '' . - '' . - '' . - ''; - - $inscriptions = giveMeBases($app, $usr); - foreach ($inscriptions as $sbasId => $baseInsc) { - //je presente la base - if (($baseInsc['CollsRegistered'] || $baseInsc['CollsRefuse'] || $baseInsc['CollsWait'] || $baseInsc['CollsIntime'] || $baseInsc['CollsOuttime'] || $baseInsc['CollsNonactif'] || $baseInsc['CollsCGU'] || $baseInsc['Colls']))//&& $baseInsc['inscript']) - $out .= ''; - - if ($baseInsc['CollsRegistered']) { - foreach ($baseInsc['CollsRegistered'] as $collId => $isTrue) { - $base_id = phrasea::baseFromColl($sbasId, $collId, $app); - $out .= ''; - } - $out .= ''; - } - if ($baseInsc['CollsRefuse']) { - foreach ($baseInsc['CollsRefuse'] as $collId => $isTrue) { - $base_id = phrasea::baseFromColl($sbasId, $collId, $app); - $out .= ''; - } - $out .= ''; - } - if ($baseInsc['CollsWait']) { - foreach ($baseInsc['CollsWait'] as $collId => $isTrue) { - $base_id = phrasea::baseFromColl($sbasId, $collId, $app); - $out .= ''; - } - $out .= ''; - } - if ($baseInsc['CollsIntime']) { - foreach ($baseInsc['CollsIntime'] as $collId => $isTrue) { - $base_id = phrasea::baseFromColl($sbasId, $collId, $app); - $out .= ''; - } - $out .= ''; - } - if ($baseInsc['CollsOuttime']) { - foreach ($baseInsc['CollsOuttime'] as $collId => $isTrue) { - $base_id = phrasea::baseFromColl($sbasId, $collId, $app); - $out .= ''; - } - $out .= ''; - } - if ($baseInsc['CollsNonactif']) { - foreach ($baseInsc['CollsNonactif'] as $collId => $isTrue) { - $base_id = phrasea::baseFromColl($sbasId, $collId, $app); - $out .= ''; - } - $out .= ''; - } - - $out .= ''; - if (($baseInsc['CollsCGU'] || $baseInsc['Colls']) && $baseInsc['inscript']) {// il y a des coll ou s'inscrire ! - $noDemand = false; - - if ($baseInsc['Colls']) {//des coll ou on peut s'inscrire sans cgu specifiques - //je check si ya des cgu pour la base - if ($baseInsc['CGU']) { - $out .= ''; - $out .= ''; - } - foreach ($baseInsc['Colls'] as $collId => $collName) { - $base_id = phrasea::baseFromColl($sbasId, $collId, $app); - $out .= '' . - '' . - '' . - '' . - ''; - } - } - if ($baseInsc['CollsCGU']) { - foreach ($baseInsc['CollsCGU'] as $collId => $collDesc) { - $base_id = phrasea::baseFromColl($sbasId, $collId, $app); - $out .= '' . - '' . - '' . - '' . - '' . - '' . - '' . - '' . - '' . - ''; - } - } - } - } - - $out .= '
   

' . phrasea::sbas_labels($sbasId, $app) . '

' . $app->trans('login::register: acces authorise sur la collection') . phrasea::bas_labels($base_id, $app); - if (trim($isTrue) != '') - $out .= ' ' . $app->trans('login::register::CGU: lire les CGU') . ''; - $out .= '
' . $app->trans('login::register: acces refuse sur la collection') . phrasea::bas_labels($base_id, $app) . ''; - if (trim($isTrue) != '') - $out .= ' ' . $app->trans('login::register::CGU: lire les CGU') . ''; - $out .= '
' . $app->trans('login::register: en attente d\'acces sur') . ' ' . phrasea::bas_labels($base_id, $app) . ''; - if (trim($isTrue) != '') - $out .= ' ' . $app->trans('login::register::CGU: lire les CGU') . ''; - $out .= '
' . $app->trans('login::register: acces temporaire sur') . phrasea::bas_labels($base_id, $app) . ''; - if (trim($isTrue) != '') - $out .= ' ' . $app->trans('login::register::CGU: lire les CGU') . ''; - $out .= '
' . $app->trans('login::register: acces temporaire termine sur') . phrasea::bas_labels($base_id, $app) . ''; - if (trim($isTrue) != '') - $out .= ' ' . $app->trans('login::register::CGU: lire les CGU') . ''; - $out .= '
' . $app->trans('login::register: acces supendu sur') . phrasea::bas_labels($base_id, $app) . ''; - if (trim($isTrue) != '') - $out .= ' ' . $app->trans('login::register::CGU: lire les CGU') . ''; - $out .= '
' . $app->trans('login::register: L\'acces aux bases ci-dessous implique l\'acceptation des Conditions Generales d\'Utilisation (CGU) suivantes') . '
' . $baseInsc['CGU'] . '
' . $collName . '' . - '' . - '' . $app->trans('login::register: Faire une demande d\'acces') . '' . - '

' . $app->trans('login::register: L\'acces aux bases ci-dessous implique l\'acceptation des Conditions Generales d\'Utilisation (CGU) suivantes') . '
' . - '
' . $collDesc['CGU'] . '
' . - '
' . $collDesc['name'] . '' . - '' . - '' . $app->trans('login::register: Faire une demande d\'acces') . '' . - '
'; - - return ['tab' => $out, 'demandes' => $noDemand]; -} diff --git a/lib/conf.d/migrations.yml b/lib/conf.d/migrations.yml index 341bd40e73..8dd2b848fa 100644 --- a/lib/conf.d/migrations.yml +++ b/lib/conf.d/migrations.yml @@ -54,3 +54,6 @@ migrations: migration17: version: user-auth-provider class: Alchemy\Phrasea\Setup\DoctrineMigrations\UserAuthProviderMigration + migration18: + version: registration-demand + class: Alchemy\Phrasea\Setup\DoctrineMigrations\RegistrationDemandMigration diff --git a/templates/web/account/access.html.twig b/templates/web/account/access.html.twig index b2a761c0be..1732decbef 100644 --- a/templates/web/account/access.html.twig +++ b/templates/web/account/access.html.twig @@ -14,42 +14,19 @@     - {% for sbasId, baseInsc in inscriptions %} - {% if baseInsc["CollsRegistered"] or baseInsc["CollsRefuse"] or baseInsc["CollsWait"] or baseInsc["CollsIntime"] or baseInsc["CollsOuttime"] or baseInsc["CollsNonactif"] or baseInsc["CollsCGU"] or baseInsc["Colls"] %} - -

{{ sbasId | sbas_labels(app) }}

- - {% endif %} - - {% if baseInsc["CollsRegistered"] is not none %} - {% for base in baseInsc["CollsRegistered"]%} - {% for collId, isTrue in base %} - {% set base_id = sbasId |base_from_coll(collId, app) %} - - - {{ "login::register: acces authorise sur la collection" | trans }}{{ sbasId |sbas_labels(app) }} - {% if isTrue | trim != "" %} - {{ "login::register::CGU: lire les CGU" | trans }} - {% endif %} - - - {% endfor %} - {% endfor %} - - - - - {% endif %} - - {% if baseInsc["CollsRefuse"] %} - {% for collId, isTrue in baseInsc["CollsRefuse"] %} - {% set base_id = sbasId |base_from_coll(collId, app) %} + {% for sbasId, baseInfo in inscriptions %} + {% set sbasName = sbasId | sbas_labels(app) %} + +

{{ sbasName }}

+ + {% if baseInfo["demands"]["by-type"]["accepted"]|length > 0 %} + {% for baseId in baseInfo["demands"]["by-type"]["accepted"] %} - - {{ "login::register: acces refuse sur la collection" | trans }}{{ sbasId |sbas_labels(app) }} - {% if isTrue | trim != "" %} - {{ "login::register::CGU: lire les CGU" | trans }} - {% endif %} + + {{ "login::register: acces authorise sur la collection" | trans }}{{ sbasName }} + + {{ "login::register::CGU: lire les CGU" | trans }} + {% endfor %} @@ -58,114 +35,116 @@ {% endif %} - - {% if baseInsc["CollsWait"] %} - {% for collId, isTrue in baseInsc["CollsWait"] %} - {% set base_id = sbasId |base_from_coll(collId, app) %} + {% if baseInfo["demands"]["by-type"]["rejected"]|length > 0 %} + {% for baseId in baseInfo["demands"]["by-type"]["rejected"] %} - + + {{ "login::register: acces refuse sur la collection" | trans }}{{ sbasName }} + + {{ "login::register::CGU: lire les CGU" | trans }} + + + + {% endfor %} + + + + + {% endif %} + {% if baseInfo["demands"]["by-type"]["pending"]|length > 0 %} + {% for baseId in baseInfo["demands"]["by-type"]["pending"] %} + + {{ "login::register: en attente d\'acces sur" | trans }} {{ sbasId |sbas_labels(app) }} - {% if isTrue | trim != "" %} - {{ "login::register::CGU: lire les CGU" | trans }} - {% endif %} + + {{ "login::register::CGU: lire les CGU" | trans }} + {% endfor %} - + + + + {% endif %} - - {% if baseInsc["CollsIntime"] %} - {% for collId, isTrue in baseInsc["CollsIntime"] %} - {% set base_id = sbasId |base_from_coll(collId, app) %} + {% if baseInfo["demands"]["by-type"]["in-time"]|length > 0 %} + {% for baseId in baseInfo["demands"]["by-type"]["in-time"] %} - + {{ "login::register: acces temporaire sur" | trans }} {{ sbasId |sbas_labels(app) }} - {% if isTrue |trim != "" %} - {{ "login::register::CGU: lire les CGU" | trans }} - {% endif %} + + {{ "login::register::CGU: lire les CGU" | trans }} + {% endfor %} - + + + + {% endif %} - - {% if baseInsc["CollsOuttime"] %} - {% for collId, isTrue in baseInsc["CollsOuttime"] %} - {% set base_id = sbasId |base_from_coll(collId, app) %} + {% if baseInfo["demands"]["by-type"]["out-dated"]|length > 0 %} + {% for baseId in baseInfo["demands"]["by-type"]["out-dated"] %} - + {{ "login::register: acces temporaire termine sur" | trans }}{{ sbasId |sbas_labels(app) }} - {% if isTrue |trim != "" %} - {{ "login::register::CGU: lire les CGU" | trans }} - {% endif %} + + {{ "login::register::CGU: lire les CGU" | trans }} + {% endfor %} - + + + + {% endif %} - - {% if baseInsc["CollsNonactif"] %} - {% for collId, isTrue in baseInsc["CollsNonactif"] %} - {% set base_id = sbasId |base_from_coll(collId, app) %} + {% if baseInfo["demands"]["by-type"]["inactive"]|length > 0 %} + {% for baseId in baseInfo["demands"]["by-type"]["inactive"] %} - + {{ "login::register: acces supendu sur" | trans }} {{ sbasId |sbas_labels(app) }} - {% if isTrue |trim != "" %} - {{ "login::register::CGU: lire les CGU" | trans }} - {% endif %} + + {{ "login::register::CGU: lire les CGU" | trans }} + {% endfor %} - + + + + {% endif %} + {% endfor %} - {% if (baseInsc["CollsCGU"] or baseInsc["Colls"]) and baseInsc["inscript"] %} - {% if baseInsc["Colls"] %} - {% if baseInsc["CGU"] %} - - {{ "login::register: L\'acces aux bases ci-dessous implique l\'acceptation des Conditions Generales d\'Utilisation (CGU) suivantes" | trans }} - - -
{{ baseInsc["CGU"] }}
- - {% endif %} - {% for collId, collName in baseInsc["Colls"] %} - {% set base_id = sbasId |base_from_coll(collId, app) %} - - {{ collName }} - - - - {{ "login::register: Faire une demande d\'acces" | trans }} - - - {% endfor %} - {% endif %} - {% if baseInsc["CollsCGU"] %} - {% for collId, collDesc in baseInsc["CollsCGU"] %} - {% set base_id = sbasId |base_from_coll(collId, app) %} - -
- - - {{ "login::register: L\'acces aux bases ci-dessous implique l\'acceptation des Conditions Generales d\'Utilisation (CGU) suivantes" | trans }} - - - -
{{ collDesc["CGU"] }}
- - - - {{ collDesc["name"] }} - - - - {{ "login::register: Faire une demande d\'acces" | trans }} - - - {% endfor %} - {% endif %} + + {% for sbasId, baseInfo in inscriptions %} + {% if baseInfo["config"]["cgu"] is not none %} + + {{ "login::register: L\'acces aux bases ci-dessous implique l\'acceptation des Conditions Generales d\'Utilisation (CGU) suivantes" | trans }} + + +
{{ baseInfo["config"]["cgu"] }}
+ {% endif %} + {% for baseId, collInfo in baseInfo["config"]["collections"] if (collInfo['demand'] is none and collInfo['can-register']) %} + {% if collInfo["cgu"] is not none %} + + {{ "login::register: L\'acces aux bases ci-dessous implique l\'acceptation des Conditions Generales d\'Utilisation (CGU) suivantes" | trans }} + + +
{{ baseInsc["CGU"] }}
+ + {% endif %} + + {{ collInfo["coll-name"] }} + + + + {{ "login::register: Faire une demande d\'acces" | trans }} + + + {% endfor %} {% endfor %}
diff --git a/templates/web/admin/user/demand.html.twig b/templates/web/admin/user/demand.html.twig index 28ad9d8787..b72b6c6e15 100644 --- a/templates/web/admin/user/demand.html.twig +++ b/templates/web/admin/user/demand.html.twig @@ -201,19 +201,13 @@
- {% set tableColls = table['coll'] %} - {% for row in table['users'] %} - {% set user = row['user'] %} + {% set demands = table['demand'] %} + {% for user in table['user'] %} + {% set userDemands = demands[user.getId()] %}
- - - {{ app['date-formatter'].getPrettyString(row["date_demand"]) }} - - - {% if baseInfo["demands"]["by-type"]["accepted"]|length > 0 %} - {% for baseId in baseInfo["demands"]["by-type"]["accepted"] %} + {% if baseInfo["registrations"]["by-type"]["accepted"]|length > 0 %} + {% for baseId in baseInfo["registrations"]["by-type"]["accepted"] %} {% endif %} - {% if baseInfo["demands"]["by-type"]["rejected"]|length > 0 %} - {% for baseId in baseInfo["demands"]["by-type"]["rejected"] %} + {% if baseInfo["registrations"]["by-type"]["rejected"]|length > 0 %} + {% for baseId in baseInfo["registrations"]["by-type"]["rejected"] %} {% endif %} - {% if baseInfo["demands"]["by-type"]["pending"]|length > 0 %} - {% for baseId in baseInfo["demands"]["by-type"]["pending"] %} + {% if baseInfo["registrations"]["by-type"]["pending"]|length > 0 %} + {% for baseId in baseInfo["registrations"]["by-type"]["pending"] %} {% endif %} - {% if baseInfo["demands"]["by-type"]["in-time"]|length > 0 %} - {% for baseId in baseInfo["demands"]["by-type"]["in-time"] %} + {% if baseInfo["registrations"]["by-type"]["in-time"]|length > 0 %} + {% for baseId in baseInfo["registrations"]["by-type"]["in-time"] %} {% endif %} - {% if baseInfo["demands"]["by-type"]["out-dated"]|length > 0 %} - {% for baseId in baseInfo["demands"]["by-type"]["out-dated"] %} + {% if baseInfo["registrations"]["by-type"]["out-dated"]|length > 0 %} + {% for baseId in baseInfo["registrations"]["by-type"]["out-dated"] %} {% endif %} - {% if baseInfo["demands"]["by-type"]["inactive"]|length > 0 %} - {% for baseId in baseInfo["demands"]["by-type"]["inactive"] %} + {% if baseInfo["registrations"]["by-type"]["inactive"]|length > 0 %} + {% for baseId in baseInfo["registrations"]["by-type"]["inactive"] %} {% endif %} - {% for baseId, collInfo in baseInfo["config"]["collections"] if (collInfo['demand'] is none and collInfo['can-register']) %} + {% for baseId, collInfo in baseInfo["config"]["collections"] if (collInfo['registration'] is none and collInfo['can-register']) %} {% if collInfo["cgu"] is not none %} diff --git a/templates/web/admin/user/demand.html.twig b/templates/web/admin/user/demand.html.twig index b72b6c6e15..e0bb3735f0 100644 --- a/templates/web/admin/user/demand.html.twig +++ b/templates/web/admin/user/demand.html.twig @@ -201,9 +201,8 @@
- {% set demands = table['demand'] %} - {% for user in table['user'] %} - {% set userDemands = demands[user.getId()] %} + {% for user in users %} + {% set userRegistrations = registrations[user.getId()] %}
- {% set colls = tableColls[user.getId()] %}
{{ 'admin::compte-utilisateur identifiant' | trans }}
{{ user.getLogin() }}
@@ -237,7 +231,10 @@
- {% for basId in colls %} + {% for baseId, demand in userDemands %} +
+ {{ app['date-formatter'].getPrettyString(demand.getUpdated()) }} +
{{ basId| bas_labels(app) }} diff --git a/tests/Alchemy/Tests/Phrasea/Controller/Admin/UsersTest.php b/tests/Alchemy/Tests/Phrasea/Controller/Admin/UsersTest.php index 4062970a50..90198bb359 100644 --- a/tests/Alchemy/Tests/Phrasea/Controller/Admin/UsersTest.php +++ b/tests/Alchemy/Tests/Phrasea/Controller/Admin/UsersTest.php @@ -428,7 +428,6 @@ class UsersTest extends \PhraseanetAuthenticatedWebTestCase ]); self::$DI['app']['phraseanet.appbox'] = $appbox; - $this->assertTrue(self::$DI['client']->getResponse()->isRedirect()); } diff --git a/tests/Alchemy/Tests/Phrasea/Controller/Root/AccountTest.php b/tests/Alchemy/Tests/Phrasea/Controller/Root/AccountTest.php index 05292a5d54..dfb43e2737 100644 --- a/tests/Alchemy/Tests/Phrasea/Controller/Root/AccountTest.php +++ b/tests/Alchemy/Tests/Phrasea/Controller/Root/AccountTest.php @@ -47,10 +47,44 @@ class AccountTest extends \PhraseanetAuthenticatedWebTestCase */ public function testGetAccountAccess() { + $data = [ + [ + 'config' => [ + 'db-name' => 'a_db_name', + 'cgu' => null, + 'cgu-release' => null, + 'can-register' => false, + 'collections' => [ + [ + 'coll-name' => 'a_coll_name', + 'can-register' => false, + 'cgu' => null, + 'cgu-release' => null, + 'demand' => null + ], + [ + 'coll-name' => 'an_other_coll_name', + 'can-register' => false, + 'cgu' => null, + 'cgu-release' => null, + 'demand' => null + ] + ], + ] + ] + ]; + + $service = $this->getMockBuilder('Alchemy\Phrasea\Registration\RegistrationManager') + ->setConstructorArgs([self::$DI['app']['EM'], self::$DI['app']['phraseanet.appbox'], self::$DI['app']['acl']]) + ->setMethods(['getRegistrationDemandsForUser']) + ->getMock(); + + $service->expects($this->once())->method('getRegistrationDemandsForUser')->will($this->returnValue($data)); + + self::$DI['app']['registration-manager'] = $service; self::$DI['client']->request('GET', '/account/access/'); $response = self::$DI['client']->getResponse(); - $this->assertTrue($response->isOk()); } @@ -303,11 +337,10 @@ class AccountTest extends \PhraseanetAuthenticatedWebTestCase $this->assertTrue($response->isRedirect()); $this->assertEquals('minet', self::$DI['app']['authentication']->getUser()->getLastName()); - $sql = 'SELECT base_id FROM demand WHERE usr_id = :usr_id AND en_cours="1" '; - $stmt = self::$DI['app']['phraseanet.appbox']->get_connection()->prepare($sql); - $stmt->execute([':usr_id' => self::$DI['app']['authentication']->getUser()->getId()]); - $rs = $stmt->fetchAll(\PDO::FETCH_ASSOC); - $stmt->closeCursor(); + $rs = self::$DI['app']['EM']->getRepository('Alchemy\Phrasea\Model\Entities\RegistrationDemand')->findBy([ + 'user' => self::$DI['app']['authentication']->getUser(), + 'pending' => true + ]); $this->assertCount(count($bases), $rs); } diff --git a/tests/Alchemy/Tests/Phrasea/Controller/Root/LoginTest.php b/tests/Alchemy/Tests/Phrasea/Controller/Root/LoginTest.php index aa9dcda634..a0f2adbcca 100644 --- a/tests/Alchemy/Tests/Phrasea/Controller/Root/LoginTest.php +++ b/tests/Alchemy/Tests/Phrasea/Controller/Root/LoginTest.php @@ -9,6 +9,7 @@ use Alchemy\Phrasea\Authentication\Provider\Token\Identity; use Alchemy\Phrasea\Authentication\Exception\NotAuthenticatedException; use Alchemy\Phrasea\Exception\InvalidArgumentException; use Alchemy\Phrasea\Authentication\ProvidersCollection; +use Alchemy\Phrasea\Model\Entities\RegistrationDemand; use Alchemy\Phrasea\Model\Entities\User; use Symfony\Component\HttpKernel\Client; use Symfony\Component\HttpFoundation\ResponseHeaderBag; @@ -36,7 +37,6 @@ class LoginTest extends \PhraseanetAuthenticatedWebTestCase $sxml->caninscript = 1; $dom = new \DOMDocument(); $dom->loadXML($sxml->asXML()); - self::$DI['collection']->set_prefs($dom); } if (null === self::$login) { @@ -45,6 +45,7 @@ class LoginTest extends \PhraseanetAuthenticatedWebTestCase if (null === self::$email) { self::$email = self::$DI['user']->getEmail(); } + self::$DI['app']['registration.enabled'] = true; } public function tearDown() @@ -208,7 +209,13 @@ class LoginTest extends \PhraseanetAuthenticatedWebTestCase self::$DI['user']->setMailLocked(true); $this->deleteRequest(); - self::$DI['app']['phraseanet.appbox-register']->add_request(self::$DI['user'], self::$DI['collection']); + $demand = new RegistrationDemand(); + $demand->setUser(self::$DI['user']); + $demand->setBaseId(self::$DI['collection']->get_base_id()); + + self::$DI['app']['EM']->persist($demand); + self::$DI['app']['EM']->flush(); + self::$DI['client']->request('GET', '/login/register-confirm/', ['code' => $token]); $response = self::$DI['client']->getResponse(); @@ -470,7 +477,6 @@ class LoginTest extends \PhraseanetAuthenticatedWebTestCase */ public function testGetRegister($type, $message) { - self::$DI['app']['registration.enabled'] = true; $this->logout(self::$DI['app']); self::$DI['app']->addFlash($type, $message); $crawler = self::$DI['client']->request('GET', '/login/register-classic/'); @@ -483,7 +489,6 @@ class LoginTest extends \PhraseanetAuthenticatedWebTestCase public function testGetRegisterWithRegisterIdBindDataToForm() { - self::$DI['app']['registration.enabled'] = true; $this->logout(self::$DI['app']); $provider = $this->getMock('Alchemy\Phrasea\Authentication\Provider\ProviderInterface'); @@ -540,6 +545,7 @@ class LoginTest extends \PhraseanetAuthenticatedWebTestCase */ public function testPostRegisterbadArguments($parameters, $extraParameters, $errors) { + $this->enableTOU(); self::$DI['app']['registration.enabled'] = true; self::$DI['app']['registration.fields'] = $extraParameters; @@ -572,6 +578,7 @@ class LoginTest extends \PhraseanetAuthenticatedWebTestCase { $this->logout(self::$DI['app']); $crawler = self::$DI['client']->request('POST', '/login/register-classic/'); + $this->assertFalse(self::$DI['client']->getResponse()->isRedirect()); $this->assertFormOrFlashError($crawler, self::$DI['app']['conf']->get(['registry', 'registration', 'auto-select-collections']) ? 6 : 7); } @@ -815,6 +822,13 @@ class LoginTest extends \PhraseanetAuthenticatedWebTestCase self::$DI['app']['registration.fields'] = []; $this->logout(self::$DI['app']); + $managerMock = $this->getMockBuilder('Alchemy\Phrasea\Registration\RegistrationManager') + ->setConstructorArgs([self::$DI['app']['EM'], self::$DI['app']['phraseanet.appbox'], self::$DI['app']['acl']]) + ->setMethods(['getRepository']) + ->getMock(); + $managerMock->expects($this->any())->method('getRepository')->will($this->returnValue(self::$DI['app']['registration-manager']->getRepository())); + self::$DI['app']['registration-manager'] = $managerMock; + $provider = $this->getMock('Alchemy\Phrasea\Authentication\Provider\ProviderInterface'); $this->addProvider('provider-test', $provider); @@ -1454,6 +1468,13 @@ class LoginTest extends \PhraseanetAuthenticatedWebTestCase public function testAuthenticateProviderCallbackAlreadyBound() { + $managerMock = $this->getMockBuilder('Alchemy\Phrasea\Registration\RegistrationManager') + ->setConstructorArgs([self::$DI['app']['EM'], self::$DI['app']['phraseanet.appbox'], self::$DI['app']['acl']]) + ->setMethods(['getRepository']) + ->getMock(); + $managerMock->expects($this->any())->method('getRepository')->will($this->returnValue(self::$DI['app']['registration-manager']->getRepository())); + self::$DI['app']['registration-manager'] = $managerMock; + $provider = $this->getMock('Alchemy\Phrasea\Authentication\Provider\ProviderInterface'); $this->addProvider('provider-test', $provider); @@ -1626,8 +1647,6 @@ class LoginTest extends \PhraseanetAuthenticatedWebTestCase ->method('isEnabled') ->will($this->returnValue(false)); - self::$DI['app']['registration.enabled'] = true; - $this->logout(self::$DI['app']); self::$DI['client']->request('GET', '/login/provider/provider-test/callback/'); @@ -1778,10 +1797,9 @@ class LoginTest extends \PhraseanetAuthenticatedWebTestCase */ private function deleteRequest() { - $sql = "DELETE FROM demand WHERE usr_id = :usr_id"; - $stmt = self::$DI['app']['phraseanet.appbox']->get_connection()->prepare($sql); - $stmt->execute([':usr_id' => self::$DI['user']->getId()]); - $stmt->closeCursor(); + $query = self::$DI['app']['EM']->createQuery('DELETE FROM Alchemy\Phrasea\Model\Entities\RegistrationDemand d WHERE d.user=?1'); + $query->setParameter(1, self::$DI['user']->getId()); + $query->execute(); } /** diff --git a/tests/Alchemy/Tests/Phrasea/Registration/RegistrationManagerTest.php b/tests/Alchemy/Tests/Phrasea/Registration/RegistrationManagerTest.php new file mode 100644 index 0000000000..c88241ea67 --- /dev/null +++ b/tests/Alchemy/Tests/Phrasea/Registration/RegistrationManagerTest.php @@ -0,0 +1,349 @@ +getMockBuilder('Alchemy\Phrasea\Registration\RegistrationManager') + ->setConstructorArgs([self::$DI['app']['EM'], self::$DI['app']['phraseanet.appbox'], self::$DI['app']['acl']]) + ->setMethods(['getRegistrationInformations']) + ->getMock(); + + $service->expects($this->once())->method('getRegistrationInformations')->will($this->returnValue($data)); + $this->assertEquals($value, $service->isRegistrationEnabled()); + } + + /** + * @dataProvider databoxXmlConfiguration + */ + public function testIsRegistrationEnabledForDatabox($data, $value) + { + $service = new RegistrationManager(self::$DI['app']['EM'], self::$DI['app']['phraseanet.appbox'], self::$DI['app']['acl']); + + $mock = $this->getMockBuilder('\databox') + ->disableOriginalConstructor() + ->setMethods(['get_sxml_structure']) + ->getMock(); + + $mock->expects($this->once())->method('get_sxml_structure')->will($this->returnValue($data)); + $this->assertEquals($value, $service->isRegistrationEnabledForDatabox($mock)); + } + + /** + * @dataProvider collectionXmlConfiguration + */ + public function testIsRegistrationEnabledForCollection($data, $value) + { + $service = new RegistrationManager(self::$DI['app']['EM'], self::$DI['app']['phraseanet.appbox'], self::$DI['app']['acl']); + + $mock = $this->getMockBuilder('\collection') + ->disableOriginalConstructor() + ->setMethods(['get_prefs']) + ->getMock(); + + $mock->expects($this->once())->method('get_prefs')->will($this->returnValue($data)); + $this->assertEquals($value, $service->isRegistrationEnabledForCollection($mock)); + } + + /** + * @dataProvider userDataProvider + */ + public function testGetRegistrationInformationsWithUserData($data, $type, $value) + { + $service = $this->getMockBuilder('Alchemy\Phrasea\Registration\RegistrationManager') + ->setConstructorArgs([self::$DI['app']['EM'], self::$DI['app']['phraseanet.appbox'], self::$DI['app']['acl']]) + ->setMethods(['getRegistrationDemandsForUser']) + ->getMock(); + + $service->expects($this->once())->method('getRegistrationDemandsForUser')->will($this->returnValue($data)); + + $rs = $service->getRegistrationInformations(4); + + $databox = current(self::$DI['app']['phraseanet.appbox']->get_databoxes()); + $collection = current($databox->get_collections()); + + $this->assertEquals($value, count($rs[$databox->get_sbas_id()]['demands']['by-type'][$type])); + $this->assertNotNull($rs[$databox->get_sbas_id()]['demands']['by-collection'][$collection->get_base_id()]); + } + + public function databoxXmlConfiguration() + { + $xmlInscript = +<< +11 +XML; + $xmlNoInscript = + << +01 +XML; + $xmlNoInscriptEmpty = + << + +XML; + + return [ + [simplexml_load_string($xmlInscript), true], + [simplexml_load_string($xmlNoInscript), false], + [simplexml_load_string($xmlNoInscriptEmpty), false], + ]; + } + + public function collectionXmlConfiguration() + { + $xmlInscript = +<< +11 +XML; + $xmlNoInscript = +<< +01 +XML; + $xmlNoInscriptEmpty = +<< + +XML; + + return [ + [$xmlInscript, true], + [$xmlNoInscript, false], + [$xmlNoInscriptEmpty, false], + ]; + } + + public function registrationConfigProvider() + { + $enableDataboxConfig = [ + [ + [ + 'config' => [ + 'db-name' => 'a_db_name', + 'cgu' => null, + 'cgu-release' => null, + 'can-register' => true, + 'collections' => [], + ] + ] + ], + false + ]; + + $enableCollectionConfig = [ + [ + [ + 'config' => [ + 'db-name' => 'a_db_name', + 'cgu' => null, + 'cgu-release' => null, + 'can-register' => false, + 'collections' => [ + [ + 'coll-name' => 'a_coll_name', + 'can-register' => true, + 'cgu' => null, + 'cgu-release' => null, + 'demand' => null + ] + ], + ] + ] + ], + true + ]; + + $nothingEnabledConfig = [ + [ + [ + 'config' => [ + 'db-name' => 'a_db_name', + 'cgu' => null, + 'cgu-release' => null, + 'can-register' => false, + 'collections' => [ + [ + 'coll-name' => 'a_coll_name', + 'can-register' => false, + 'cgu' => null, + 'cgu-release' => null, + 'demand' => null + ], + [ + 'coll-name' => 'an_other_coll_name', + 'can-register' => false, + 'cgu' => null, + 'cgu-release' => null, + 'demand' => null + ] + ], + ] + ] + ], + false + ]; + + $noCollectionEnabledButBaseEnabledConfig = [ + [ + [ + 'config' => [ + 'db-name' => 'a_db_name', + 'cgu' => null, + 'cgu-release' => null, + 'can-register' => true, + 'collections' => [ + [ + 'coll-name' => 'a_coll_name', + 'can-register' => false, + 'cgu' => null, + 'cgu-release' => null, + 'demand' => null + ], + [ + 'coll-name' => 'an_other_coll_name', + 'can-register' => false, + 'cgu' => null, + 'cgu-release' => null, + 'demand' => null + ] + ], + ] + ] + ], + false + ]; + + return [ + $enableDataboxConfig, + $enableCollectionConfig, + $nothingEnabledConfig, + $noCollectionEnabledButBaseEnabledConfig + ]; + } + + public function userDataProvider() + { + $pendingDemand = new RegistrationDemand(); + $pendingDemand->setBaseId(1); + $pendingDemand->setUser(3); + $pendingDemand->setPending(true); + $pendingDemand->setRejected(false); + + $rejectedDemand = new RegistrationDemand(); + $rejectedDemand->setBaseId(1); + $rejectedDemand->setUser(3); + $rejectedDemand->setPending(true); + $rejectedDemand->setRejected(true); + + $databox = current((new \appbox(new Application()))->get_databoxes()); + $collection = current($databox->get_collections()); + + $noLimitedPendingDemand = [ + [ + $databox->get_sbas_id() => [ + $collection->get_base_id() => [ + 'base-id' => $collection->get_base_id(), + 'db-name' => 'toto', + 'active' => true, + 'time-limited' => false, + 'in-time' => null, + 'demand' => $pendingDemand + ] + ] + ], + 'pending', + 1 + ]; + + + $rejectedDemand = [ + [ + $databox->get_sbas_id() => [ + $collection->get_base_id() => [ + 'base-id' => $collection->get_base_id(), + 'db-name' => 'titi', + 'active' => true, + 'time-limited' => false, + 'in-time' => null, + 'demand' => $rejectedDemand + ] + ] + ], + 'rejected', + 1 + ]; + + $noActiveDemand = [ + [ + $databox->get_sbas_id() => [ + $collection->get_base_id() => [ + 'base-id' => 1, + 'db-name' => 'tutu', + 'active' => false, + 'time-limited' => false, + 'in-time' => null, + 'demand' => $pendingDemand + ] + ] + ], + 'inactive', + 1 + ]; + + $limitedActiveIntimePendingDemand = [ + [ + $databox->get_sbas_id() => [ + $collection->get_base_id() => [ + 'base-id' => $collection->get_base_id(), + 'db-name' => 'tata', + 'active' => true, + 'time-limited' => true, + 'in-time' => true, + 'demand' => $pendingDemand + ] + ] + ], + 'in-time', + 1 + ]; + + $limitedActiveOutdatedPendingDemand = [ + [ + $databox->get_sbas_id() => [ + $collection->get_base_id() => [ + 'base-id' => $collection->get_base_id(), + 'db-name' => 'toutou', + 'active' => true, + 'time-limited' => true, + 'in-time' => false, + 'demand' => $pendingDemand + ] + ] + ], + 'out-time', + 1 + ]; + + return [ + $noLimitedPendingDemand, + $noActiveDemand, + $limitedActiveIntimePendingDemand, + $limitedActiveOutdatedPendingDemand, + $rejectedDemand + ]; + } +} From 52f3baac056fd03661657f45b357bda1f754a4bb Mon Sep 17 00:00:00 2001 From: Nicolas Le Goff Date: Mon, 3 Feb 2014 18:10:49 +0100 Subject: [PATCH 2/6] Fix neutron's comment --- .../Command/Developer/RegenerateSqliteDb.php | 19 + .../Phrasea/Controller/Admin/Users.php | 60 ++- .../Phrasea/Controller/Root/Account.php | 12 +- lib/Alchemy/Phrasea/Controller/Root/Login.php | 4 +- .../Provider/RegistrationServiceProvider.php | 9 +- .../Form/Login/PhraseaRegisterForm.php | 2 +- ...egistrationDemand.php => Registration.php} | 14 +- .../RegistrationDemandRepository.php | 98 ----- .../Repositories/RegistrationRepository.php | 98 +++++ .../Registration/RegistrationManager.php | 388 +++++------------- .../RegistrationDemandMigration.php | 6 +- lib/classes/collection.php | 46 ++- lib/classes/databox.php | 18 + lib/conf.d/migrations.yml | 4 +- templates/web/account/access.html.twig | 26 +- templates/web/admin/user/demand.html.twig | 7 +- .../Phrasea/Controller/Root/AccountTest.php | 28 +- .../Phrasea/Controller/Root/LoginTest.php | 6 +- .../Registration/RegistrationManagerTest.php | 345 ++++++---------- tests/classes/collectionTest.php | 39 ++ tests/classes/databoxTest.php | 39 ++ 21 files changed, 571 insertions(+), 697 deletions(-) rename lib/Alchemy/Phrasea/Model/Entities/{RegistrationDemand.php => Registration.php} (92%) delete mode 100644 lib/Alchemy/Phrasea/Model/Repositories/RegistrationDemandRepository.php create mode 100644 lib/Alchemy/Phrasea/Model/Repositories/RegistrationRepository.php diff --git a/lib/Alchemy/Phrasea/Command/Developer/RegenerateSqliteDb.php b/lib/Alchemy/Phrasea/Command/Developer/RegenerateSqliteDb.php index fe39bd6a51..3e53c2aa7a 100644 --- a/lib/Alchemy/Phrasea/Command/Developer/RegenerateSqliteDb.php +++ b/lib/Alchemy/Phrasea/Command/Developer/RegenerateSqliteDb.php @@ -23,6 +23,7 @@ use Alchemy\Phrasea\Model\Entities\FeedItem; use Alchemy\Phrasea\Model\Entities\FeedPublisher; use Alchemy\Phrasea\Model\Entities\FeedToken; use Alchemy\Phrasea\Model\Entities\LazaretSession; +use Alchemy\Phrasea\Model\Entities\Registration; use Alchemy\Phrasea\Model\Entities\Session; use Alchemy\Phrasea\Model\Entities\Task; use Alchemy\Phrasea\Model\Entities\User; @@ -36,6 +37,7 @@ use Alchemy\Phrasea\Model\Entities\StoryWZ; use Alchemy\Phrasea\Core\Provider\ORMServiceProvider; use Doctrine\ORM\EntityManager; use Doctrine\ORM\Tools\SchemaTool; +use Gedmo\Timestampable\TimestampableListener; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Filesystem\Filesystem; @@ -94,6 +96,10 @@ class RegenerateSqliteDb extends Command $this->insertOneAggregateToken($this->container['EM'], $DI); $this->insertLazaretFiles($this->container['EM'], $DI); $this->insertAuthFailures($this->container['EM'], $DI); + $this->insertOneRegistration($this->container['EM'],$DI['user_alt1'], $DI['coll']); + $this->insertOneRegistration($this->container['EM'],$DI['user_alt2'], $DI['coll'], '-3 months'); + $this->insertOneRegistration($this->container['EM'],$DI['user_alt2'], $DI['coll']); + $fixtures['user']['test_phpunit'] = $DI['user']->getId(); $fixtures['user']['test_phpunit_not_admin'] = $DI['user_notAdmin']->getId(); @@ -637,4 +643,17 @@ class RegenerateSqliteDb extends Command $em->persist($entry); } + + private function insertOneRegistration(EntityManager $em, \User_Adapter $user, \collection $collection, $when = 'now') + { + $em->getEventManager()->removeEventSubscriber(new TimestampableListener()); + $registration = new Registration(); + $registration->setBaseId($collection->get_base_id()); + $registration->setUser($user->get_id()); + $registration->setUpdated(new \DateTime($when)); + $registration->setCreated(new \DateTime($when)); + $em->persist($registration); + $em->flush(); + $em->getEventManager()->addEventSubscriber(new TimestampableListener()); + } } diff --git a/lib/Alchemy/Phrasea/Controller/Admin/Users.php b/lib/Alchemy/Phrasea/Controller/Admin/Users.php index 934794b6aa..b0b1a3a900 100644 --- a/lib/Alchemy/Phrasea/Controller/Admin/Users.php +++ b/lib/Alchemy/Phrasea/Controller/Admin/Users.php @@ -14,6 +14,7 @@ namespace Alchemy\Phrasea\Controller\Admin; use Alchemy\Phrasea\Helper\User as UserHelper; use Alchemy\Phrasea\Model\Entities\FtpCredential; use Alchemy\Phrasea\Model\Entities\User; +use igorw; use Silex\Application; use Silex\ControllerProviderInterface; use Symfony\Component\HttpFoundation\Request; @@ -354,37 +355,27 @@ class Users implements ControllerProviderInterface })->bind('admin_users_export_csv'); $controllers->get('/demands/', function (Application $app) { - $app['registration-manager']->deleteOldDemand(); + $app['registration-manager']->deleteOldRegistrations(); $models = $app['manipulator.user']->getRepository()->findModelOf($app['authentication']->getUser()); - $demands = $app['registration-manager']->getRepository()->getDemandsForUser( + $users = $registrations = []; + foreach ($app['registration-manager']->getRepository()->getDemandsForUser( $app['authentication']->getUser(), array_keys($app['acl']->get($app['authentication']->getUser())->get_granted_base(['canadmin'])) - ); + ) as $registration) { + $user = $registration->getUser(); + $users[$user->getId()] = $user; - $currentUsr = null; - $table = ['user' => [], 'demand' => []]; - foreach ($demands as $demand) { - $user = $demand->getUser(); - - if ($user->getId() !== $currentUsr) { - $currentUsr = $user->getId(); - $table['user'][$user->getId()] = $user; - } - - if (!isset($table['demand'][$user->getId()])) { - $table['demand'][$user->getId()] = []; - } - - if (!array_key_exists($demand->getBaseId(), $table['demand'][$user->getId()][$demand->getBaseId()])) { - $table['demand'][$user->getId()][$demand->getBaseId()] = $demand; + if (null !== igorw::get_in($registrations, [$user->getId(), $registration->getBaseId()])) { + $registrations[$user->getId()][$registration->getBaseId()] = $registration; } } return $app['twig']->render('admin/user/demand.html.twig', [ - 'table' => $table, + 'users' => $users, + 'registrations' => $registrations, 'models' => $models, ]); })->bind('users_display_demands'); @@ -444,27 +435,23 @@ class Users implements ControllerProviderInterface $app['acl']->get($user)->apply_model($user_template, $base_ids); - if (!isset($done[$usr])) { - $done[$usr] = []; - } - foreach ($base_ids as $base_id) { $done[$usr][$base_id] = true; } - $app['registration-manager']->getRepository()->deleteUserDemands($user, $base_ids); + $app['registration-manager']->deleteRegistrationsForUser($user->get_id(), $base_ids); } foreach ($deny as $usr => $bases) { $cache_to_update[$usr] = true; foreach ($bases as $bas) { - $app['registration-manager']->rejectDemand($usr, $bas); - - if (!isset($done[$usr])) { - $done[$usr] = []; + if (null !== $registration = $this->getRepository()->findOneBy([ + 'user' => $usr, + 'baseId' => $bas + ])) { + $app['registration-manager']->rejectDemand($registration); + $done[$usr][$bas] = false; } - - $done[$usr][$bas] = false; } } @@ -474,12 +461,13 @@ class Users implements ControllerProviderInterface foreach ($bases as $bas) { $collection = \collection::get_from_base_id($app, $bas); - if (!isset($done[$usr])) { - $done[$usr] = []; + if (null !== $registration = $this->getRepository()->findOneBy([ + 'user' => $user->get_id(), + 'baseId' => $collection->get_base_id() + ])) { + $done[$usr][$bas] = true; + $app['registration-manager']->acceptDemand($registration, $user, $collection, $options[$usr][$bas]['HD'], $options[$usr][$bas]['WM']); } - $done[$usr][$bas] = true; - - $app['registration-manager']->acceptDemand($user, $collection, $options[$usr][$bas]['HD'], $options[$usr][$bas]['WM']); } } diff --git a/lib/Alchemy/Phrasea/Controller/Root/Account.php b/lib/Alchemy/Phrasea/Controller/Root/Account.php index cf831f73e8..5b6fd60f35 100644 --- a/lib/Alchemy/Phrasea/Controller/Root/Account.php +++ b/lib/Alchemy/Phrasea/Controller/Root/Account.php @@ -232,7 +232,7 @@ class Account implements ControllerProviderInterface public function accountAccess(Application $app, Request $request) { return $app['twig']->render('account/access.html.twig', [ - 'inscriptions' => $app['registration-manager']->getRegistrationInformations($app['authentication']->getUser()->getId()) + 'inscriptions' => $app['registration-manager']->getRegistrationSummary($app['authentication']->getUser()->getId()) ]); } @@ -326,11 +326,15 @@ class Account implements ControllerProviderInterface */ public function updateAccount(PhraseaApplication $app, Request $request) { - if (0 !== count($demands = (array) $request->request->get('demand', []))) { + $demands = $request->request->get('demand'); + if (false === is_array($demands)) { + $app->abort(400, '"demand" parameter must be an array of base id '); + } + if (0 !== count($demands)) { foreach ($demands as $baseId) { - $app['registration-manager']->newDemand($app['authentication']->getUser()->getId(), $baseId); + $app['registration-manager']->createRegistration($app['authentication']->getUser()->getId(), $baseId); } - $app->addFlash('success', $app->trans('login::notification: Vos demandes ont ete prises en compte')); + $app->addFlash('success', $app->trans('Your registration requests have been taken into account.')); } $accountFields = [ diff --git a/lib/Alchemy/Phrasea/Controller/Root/Login.php b/lib/Alchemy/Phrasea/Controller/Root/Login.php index cbf8af0df9..103a260725 100644 --- a/lib/Alchemy/Phrasea/Controller/Root/Login.php +++ b/lib/Alchemy/Phrasea/Controller/Root/Login.php @@ -335,7 +335,7 @@ class Login implements ControllerProviderInterface } else { $selected = isset($data['collections']) ? $data['collections'] : null; } - $inscriptions = $app['registration-manager']->getRegistrationInformations(); + $inscriptions = $app['registration-manager']->getRegistrationSummary(); $inscOK = []; foreach ($app['phraseanet.appbox']->get_databoxes() as $databox) { @@ -406,7 +406,7 @@ class Login implements ControllerProviderInterface continue; } - $app['registration-manager']->newDemand($user->getId(), $base_id); + $app['registration-manager']->createRegistration($user->getId(), $base_id); $demandOK[$base_id] = true; } diff --git a/lib/Alchemy/Phrasea/Core/Provider/RegistrationServiceProvider.php b/lib/Alchemy/Phrasea/Core/Provider/RegistrationServiceProvider.php index 8f1110c82c..9c36512c7a 100644 --- a/lib/Alchemy/Phrasea/Core/Provider/RegistrationServiceProvider.php +++ b/lib/Alchemy/Phrasea/Core/Provider/RegistrationServiceProvider.php @@ -27,7 +27,14 @@ class RegistrationServiceProvider implements ServiceProviderInterface }); $app['registration.enabled'] = $app->share(function (Application $app) { - return $app['registration-manager']->isRegistrationEnabled(); + foreach ($app['phraseanet.appbox']->get_databoxes() as $databox) { + foreach($databox->get_collections() as $collection) { + if ($collection->isRegistrationEnabled()) { + return true; + } + } + } + return false; }); $app['registration.optional-fields'] = $app->share(function (Application $app) { diff --git a/lib/Alchemy/Phrasea/Form/Login/PhraseaRegisterForm.php b/lib/Alchemy/Phrasea/Form/Login/PhraseaRegisterForm.php index 0654856c3b..2389dea842 100644 --- a/lib/Alchemy/Phrasea/Form/Login/PhraseaRegisterForm.php +++ b/lib/Alchemy/Phrasea/Form/Login/PhraseaRegisterForm.php @@ -75,7 +75,7 @@ class PhraseaRegisterForm extends AbstractType $choices = []; $baseIds = []; - foreach ($this->app['registration-manager']->getRegistrationInformations() as $baseInfo) { + foreach ($this->app['registration-manager']->getRegistrationSummary() as $baseInfo) { $dbName = $baseInfo['config']['db-name']; foreach ($baseInfo['config']['collections'] as $baseId => $collInfo) { if (false === $collInfo['can-register']) { diff --git a/lib/Alchemy/Phrasea/Model/Entities/RegistrationDemand.php b/lib/Alchemy/Phrasea/Model/Entities/Registration.php similarity index 92% rename from lib/Alchemy/Phrasea/Model/Entities/RegistrationDemand.php rename to lib/Alchemy/Phrasea/Model/Entities/Registration.php index f4a45a9e4a..c6b6e26d10 100644 --- a/lib/Alchemy/Phrasea/Model/Entities/RegistrationDemand.php +++ b/lib/Alchemy/Phrasea/Model/Entities/Registration.php @@ -15,10 +15,10 @@ use Doctrine\ORM\Mapping as ORM; use Gedmo\Mapping\Annotation as Gedmo; /** - * @ORM\Table(name="RegistrationDemand") - * @ORM\Entity(repositoryClass="Alchemy\Phrasea\Model\Repositories\RegistrationDemandRepository") + * @ORM\Table(name="Registration") + * @ORM\Entity(repositoryClass="Alchemy\Phrasea\Model\Repositories\RegistrationRepository") */ -class RegistrationDemand +class Registration { /** * @ORM\Column(type="integer") @@ -72,7 +72,7 @@ class RegistrationDemand /** * @param mixed $pending * - * @return RegistrationDemand + * @return Registration */ public function setPending($pending) { @@ -92,7 +92,7 @@ class RegistrationDemand /** * @param mixed $rejected * - * @return RegistrationDemand + * @return Registration */ public function setRejected($rejected) { @@ -112,7 +112,7 @@ class RegistrationDemand /** * @param mixed $user * - * @return RegistrationDemand + * @return Registration */ public function setUser($user) { @@ -132,7 +132,7 @@ class RegistrationDemand /** * @param mixed $baseId * - * @return RegistrationDemand + * @return Registration */ public function setBaseId($baseId) { diff --git a/lib/Alchemy/Phrasea/Model/Repositories/RegistrationDemandRepository.php b/lib/Alchemy/Phrasea/Model/Repositories/RegistrationDemandRepository.php deleted file mode 100644 index 84a9ae9774..0000000000 --- a/lib/Alchemy/Phrasea/Model/Repositories/RegistrationDemandRepository.php +++ /dev/null @@ -1,98 +0,0 @@ -createQueryBuilder('d'); - $qb->where($qb->expr()->eq('d.user', ':user')); - $qb->setParameter(':user', $user->get_id()); - - if (count($baseList) > 0) { - $qb->andWhere('d.baseId IN (:bases)'); - $qb->setParameter(':bases', $baseList); - } - - $qb->orderBy('d.created', 'DESC'); - - return $qb->getQuery()->getResult(); - } - - /** - * Deletes demands for user on collection. - * - * @param \User_Adapter $user - * @param array $baseList - * - * @return mixed - */ - public function deleteUserDemands(\User_Adapter $user, $baseList = []) - { - $qb = $this->createQueryBuilder('d'); - $qb->delete('Alchemy\Phrasea\Model\Entities\RegistrationDemand', 'd'); - $qb->where($qb->expr()->eq('d.user', ':user')); - $qb->setParameter(':user', $user->get_id()); - - if (count($baseList) > 0) { - $qb->andWhere('d.baseId IN (:bases)'); - $qb->setParameter(':bases', $baseList); - } - - return $qb->getQuery()->execute(); - } - - /** - * Deletes outdated demands. - * - * @param string $limit - */ - public function deleteDemandsOldestThan($limit = '-1 month') - { - $qb = $this->createQueryBuilder('d'); - $qb->delete('Alchemy\Phrasea\Model\Entities\RegistrationDemand', 'd'); - $qb->where($qb->expr()->lt('d.created', ':date')); - $qb->setParameter(':date', new \DateTime($limit)); - $qb->getQuery()->execute(); - } - - /** - * Deletes demands on collection. - * - * @param $baseId - */ - public function deleteDemandsOnCollection($baseId) - { - $qb = $this->createQueryBuilder('d'); - $qb->delete('Alchemy\Phrasea\Model\Entities\RegistrationDemand', 'd'); - $qb->where($qb->expr()->eq('d.baseId', ':base')); - $qb->setParameter(':base', $baseId); - $qb->getQuery()->execute(); - } -} diff --git a/lib/Alchemy/Phrasea/Model/Repositories/RegistrationRepository.php b/lib/Alchemy/Phrasea/Model/Repositories/RegistrationRepository.php new file mode 100644 index 0000000000..a75aeee1c4 --- /dev/null +++ b/lib/Alchemy/Phrasea/Model/Repositories/RegistrationRepository.php @@ -0,0 +1,98 @@ +createQueryBuilder('d'); + $qb->where($qb->expr()->eq('d.user', ':user')); + $qb->setParameter(':user', $user->get_id()); + + if (count($baseList) > 0) { + $qb->andWhere('d.baseId IN (:bases)'); + $qb->setParameter(':bases', $baseList); + } + + $qb->orderBy('d.created', 'DESC'); + + return $qb->getQuery()->getResult(); + } + + /** + * Gets registration registrations for a user. + * + * @param $usrId + * + * @return array + */ + public function getRegistrationsSummaryForUser($usrId) + { + $data = []; + $rsm = $this->createResultSetMappingBuilder('d'); + $rsm->addScalarResult('sbas_id','sbas_id'); + $rsm->addScalarResult('bas_id','bas_id'); + $rsm->addScalarResult('dbname','dbname'); + $rsm->addScalarResult('time_limited', 'time_limited'); + $rsm->addScalarResult('limited_from', 'limited_from'); + $rsm->addScalarResult('limited_to', 'limited_to'); + $rsm->addScalarResult('actif', 'actif'); + + $sql = " + SELECT dbname, sbas.sbas_id, time_limited, + UNIX_TIMESTAMP( limited_from ) AS limited_from, + UNIX_TIMESTAMP( limited_to ) AS limited_to, + bas.server_coll_id, usr.usr_id, basusr.actif, + bas.base_id AS bas_id , " . $rsm->generateSelectClause(['d' => 'd',]) . " + FROM (usr, bas, sbas) + LEFT JOIN basusr ON ( usr.usr_id = basusr.usr_id AND bas.base_id = basusr.base_id ) + LEFT JOIN Registration d ON ( d.user_id = usr.usr_id AND bas.base_id = d.base_id ) + WHERE bas.active = 1 AND bas.sbas_id = sbas.sbas_id + AND usr.usr_id = ? + AND model_of = 0"; + + $query = $this->_em->createNativeQuery($sql, $rsm); + $query->setParameter(1, $usrId); + + foreach ($query->getResult() as $row) { + $registrationEntity = $row[0]; + + $data[$row['sbas_id']][$row['bas_id']] = [ + 'base-id' => $row['bas_id'], + 'db-name' => $row['dbname'], + 'active' => (Boolean) $row['actif'], + 'time-limited' => (Boolean) $row['time_limited'], + 'in-time' => $row['time_limited'] && ! ($row['limited_from'] >= time() && $row['limited_to'] <= time()), + 'registration' => $registrationEntity + ]; + } + + return $data; + } +} diff --git a/lib/Alchemy/Phrasea/Registration/RegistrationManager.php b/lib/Alchemy/Phrasea/Registration/RegistrationManager.php index 542ba32d23..9aac344646 100644 --- a/lib/Alchemy/Phrasea/Registration/RegistrationManager.php +++ b/lib/Alchemy/Phrasea/Registration/RegistrationManager.php @@ -12,9 +12,9 @@ namespace Alchemy\Phrasea\Registration; use Alchemy\Phrasea\Authentication\ACLProvider; -use Alchemy\Phrasea\Model\Entities\RegistrationDemand; +use Alchemy\Phrasea\Model\Entities\Registration; +use Alchemy\Phrasea\Model\Repositories\RegistrationRepository; use Doctrine\ORM\EntityManager; -use Doctrine\ORM\Query\ResultSetMappingBuilder; use igorw; class RegistrationManager @@ -28,112 +28,82 @@ class RegistrationManager { $this->em = $em; $this->appbox = $appbox; - $this->repository = $this->em->getRepository('Alchemy\Phrasea\Model\Entities\RegistrationDemand'); + $this->repository = $this->em->getRepository('Alchemy\Phrasea\Model\Entities\Registration'); $this->aclProvider = $aclProvider; } /** - * Creates a new demand. + * Creates a new registration. * * @param $userId * @param $baseId * - * @return RegistrationDemand + * @return Registration */ - public function newDemand($userId, $baseId) + public function createRegistration($userId, $baseId) { - $demand = new RegistrationDemand(); - $demand->setUser($userId); - $demand->setBaseId($baseId); - $this->em->persist($demand); + $registration = new Registration(); + $registration->setUser($userId); + $registration->setBaseId($baseId); + $this->em->persist($registration); $this->em->flush(); - return $demand; + return $registration; } /** - * Rejects a demand. + * Rejects a registration. * * @param $usrId * @param $baseId */ - public function rejectDemand($usrId, $baseId) + public function rejectRegistration(Registration $registration) { - if ($demand = $this->getRepository()->findOneBy([ - 'user' => $usrId, - 'baseId' => $baseId - ])) { - $demand->setPending(false); - $demand->setRejected(true); - $this->em->persist($demand); - } + $registration->setPending(false); + $registration->setRejected(true); + $this->em->persist($registration); $this->em->flush(); } /** - * Accepts a demand. + * Accepts a registration. * * @param $userId * @param $basId */ - public function acceptDemand(\User_Adapter $user, \Collection $collection, $grantHd = false, $grantWatermark = false) + public function acceptRegistration(Registration $registration, \User_Adapter $user, \Collection $collection, $grantHd = false, $grantWatermark = false) { - if ($demand = $this->getRepository()->findOneBy([ - 'user' => $user->get_id(), - 'baseId' => $collection->get_base_id() - ])) { - $this->aclProvider->get($user)->give_access_to_sbas([$collection->get_sbas_id()]); - $this->aclProvider->get($user)->give_access_to_base([$collection->get_base_id()]); - $this->aclProvider->get($user)->update_rights_to_base($collection->get_base_id(), [ - 'canputinalbum' => '1', - 'candwnldhd' => (string) (int) $grantHd, - 'nowatermark' => (string) (int) $grantWatermark, - 'candwnldpreview' => '1', - 'actif' => '1', - ]); - $this->em->remove($demand); - $this->em->flush(); - } + $this->aclProvider->get($user)->give_access_to_sbas([$collection->get_sbas_id()]); + $this->aclProvider->get($user)->give_access_to_base([$collection->get_base_id()]); + $this->aclProvider->get($user)->update_rights_to_base($collection->get_base_id(), [ + 'canputinalbum' => '1', + 'candwnldhd' => (string) (int) $grantHd, + 'nowatermark' => (string) (int) $grantWatermark, + 'candwnldpreview' => '1', + 'actif' => '1', + ]); + $this->em->remove($registration); + $this->em->flush(); } /** - * Tells whether registration is enabled or not. - * - * @return boolean - */ - public function isRegistrationEnabled() - { - $enabled = false; - foreach ($this->getRegistrationInformations() as $baseInfo) { - foreach ($baseInfo['config']['collections'] as $collInfo) { - if ($collInfo['can-register']) { - $enabled = true; - break 2; - } - } - } - - return $enabled; - } - - /** - * Gets information about registration configuration and demand status if a user id is provided. + * Gets information about registration configuration and registration status if a user id is provided. * * @param null|integer $userId * * @return array */ - public function getRegistrationInformations($userId = null) + public function getRegistrationSummary($userId = null) { $data = $userData = []; if (null !== $userId) { - $userData = $this->getRegistrationDemandsForUser($userId); + $userData = $this->getRepository()->getRegistrationsSummaryForUser($userId); } foreach ($this->appbox->get_databoxes() as $databox) { $ddata = [ - 'demands' => [ + 'registrations' => [ 'by-type' => [ 'inactive' => [], 'accepted' => [], @@ -146,9 +116,8 @@ class RegistrationManager ], 'config' => [ 'db-name' => $databox->get_dbname(), - 'cgu' => $this->getCguPreferencesForDatabox($databox), - 'cgu-release' => $this->getCguReleasedPreferencesForDatabox($databox), - 'can-register' => $this->isRegistrationEnabledForDatabox($databox), + 'cgu' => $databox->get_cgus(), + 'can-register' => $databox->isRegistrationEnabled(), 'collections' => [], ] ]; @@ -158,69 +127,67 @@ class RegistrationManager $ddata['config']['collections'][$collection->get_base_id()] = [ 'coll-name' => $collection->get_name(), // gets collection registration or fallback to databox configuration - 'can-register' => $this->isRegistrationDefinedForCollection($collection) ? - $this->isRegistrationEnabledForCollection($collection) : $ddata['config']['can-register'], - 'cgu' => $this->getCguPreferencesForCollection($collection), - 'cgu-release' => $this->getCguReleasedPreferencesForCollection($collection), - 'demand' => null + 'can-register' => $collection->isRegistrationEnabled(), + 'cgu' => $collection->getTermsOfUse(), + 'registration' => null ]; - if (null === $userDemand = igorw\get_in($userData, [$databox->get_sbas_id(), $collection->get_base_id()])) { + if (null === $userRegistration = igorw\get_in($userData, [$databox->get_sbas_id(), $collection->get_base_id()])) { continue; } // sets collection name - $userDemand['coll-name'] = $collection->get_name(); - // gets demand entity - $demand = $userDemand['demand']; + $userRegistration['coll-name'] = $collection->get_name(); + // gets registration entity + $registration = $userRegistration['registration']; - $noDemandMade = is_null($userDemand['active']); - $demandMade = !$noDemandMade; - $demandStillExists = !is_null($demand); - $demandNoMoreExists = !$demandStillExists; - $isPending = $demandStillExists && $demand->isPending() && !$demand->isRejected(); - $isRejected = $demandStillExists && $demand->isRejected(); - $isDone = ($demandNoMoreExists && $demandMade) || (!$isPending && !$isRejected); - $isActive = (Boolean) $userDemand['active']; - $isTimeLimited = (Boolean) $userDemand['time-limited']; + $noRegistrationMade = is_null($userRegistration['active']); + $registrationMade = !$noRegistrationMade; + $registrationStillExists = !is_null($registration); + $registrationNoMoreExists = !$registrationStillExists; + $isPending = $registrationStillExists && $registration->isPending() && !$registration->isRejected(); + $isRejected = $registrationStillExists && $registration->isRejected(); + $isDone = ($registrationNoMoreExists && $registrationMade) || (!$isPending && !$isRejected); + $isActive = (Boolean) $userRegistration['active']; + $isTimeLimited = (Boolean) $userRegistration['time-limited']; $isNotTimeLimited = !$isTimeLimited; - $isOnTime = (Boolean) $userDemand['in-time']; + $isOnTime = (Boolean) $userRegistration['in-time']; $isOutDated = !$isOnTime; - if ($noDemandMade) { + if ($noRegistrationMade) { continue; } - // sets demands - $ddata['config']['collections'][$collection->get_base_id()]['demand'] = $userDemand; - $ddata['demands']['by-collection'][$collection->get_base_id()] = $userDemand; + // sets registrations + $ddata['config']['collections'][$collection->get_base_id()]['registration'] = $userRegistration; + $ddata['registrations']['by-collection'][$collection->get_base_id()] = $userRegistration; if (!$isActive) { - $ddata['demands']['by-type']['inactive'][] = $userDemand; + $ddata['registrations']['by-type']['inactive'][] = $userRegistration; continue; } if ($isDone) { - $ddata['demands']['by-type']['accepted'][] = $userDemand; + $ddata['registrations']['by-type']['accepted'][] = $userRegistration; continue; } if ($isRejected) { - $ddata['demands']['by-type']['rejected'][] = $userDemand; + $ddata['registrations']['by-type']['rejected'][] = $userRegistration; continue; } if ($isTimeLimited && $isOnTime && $isPending) { - $ddata['demands']['by-type']['in-time'][] = $userDemand; + $ddata['registrations']['by-type']['in-time'][] = $userRegistration; continue; } if ($isTimeLimited && $isOutDated && $isPending) { - $ddata['demands']['by-type']['out-time'][] = $userDemand; + $ddata['registrations']['by-type']['out-time'][] = $userRegistration; continue; } if ($isNotTimeLimited && $isPending) { - $ddata['demands']['by-type']['pending'][] = $userDemand; + $ddata['registrations']['by-type']['pending'][] = $userRegistration; } } } @@ -231,61 +198,9 @@ class RegistrationManager } /** - * Gets registration demands for a user. + * Gets Registration Repository. * - * @param $usrId - * - * @return array - */ - public function getRegistrationDemandsForUser($usrId) - { - $data = []; - $rsm = new ResultSetMappingBuilder($this->em); - $rsm->addRootEntityFromClassMetadata('Alchemy\Phrasea\Model\Entities\RegistrationDemand', 'd'); - $rsm->addScalarResult('sbas_id','sbas_id'); - $rsm->addScalarResult('bas_id','bas_id'); - $rsm->addScalarResult('dbname','dbname'); - $rsm->addScalarResult('time_limited', 'time_limited'); - $rsm->addScalarResult('limited_from', 'limited_from'); - $rsm->addScalarResult('limited_to', 'limited_to'); - $rsm->addScalarResult('actif', 'actif'); - - $sql = " - SELECT dbname, sbas.sbas_id, time_limited, - UNIX_TIMESTAMP( limited_from ) AS limited_from, - UNIX_TIMESTAMP( limited_to ) AS limited_to, - bas.server_coll_id, usr.usr_id, basusr.actif, - bas.base_id AS bas_id , " . $rsm->generateSelectClause(['d' => 'd',]) . " - FROM (usr, bas, sbas) - LEFT JOIN basusr ON ( usr.usr_id = basusr.usr_id AND bas.base_id = basusr.base_id ) - LEFT JOIN RegistrationDemand d ON ( d.user_id = usr.usr_id AND bas.base_id = d.base_id ) - WHERE bas.active = 1 AND bas.sbas_id = sbas.sbas_id - AND usr.usr_id = ? - AND model_of = 0"; - - $query = $this->em->createNativeQuery($sql, $rsm); - $query->setParameter(1, $usrId); - - foreach ($query->getResult() as $row) { - $demandEntity = $row[0]; - - $data[$row['sbas_id']][$row['bas_id']] = [ - 'base-id' => $row['bas_id'], - 'db-name' => $row['dbname'], - 'active' => (Boolean) $row['actif'], - 'time-limited' => (Boolean) $row['time_limited'], - 'in-time' => $row['time_limited'] && ! ($row['limited_from'] >= time() && $row['limited_to'] <= time()), - 'demand' => $demandEntity - ]; - } - - return $data; - } - - /** - * Gets RegistrationDemands Repository. - * - * @return \Doctrine\ORM\EntityRepository + * @return RegistrationRepository */ public function getRepository() { @@ -293,162 +208,49 @@ class RegistrationManager } /** - * Deletes old demands. + * @param $userId + * @param array $baseList + * + * @return mixed */ - public function deleteOldDemand() + public function deleteRegistrationsForUser($userId, array $baseList) { - $this->repository->deleteDemandsOldestThan('-1 month'); + $qb = $this->getRepository()->createQueryBuilder('d'); + $qb->delete('Alchemy\Phrasea\Model\Entities\Registration', 'd'); + $qb->where($qb->expr()->eq('d.user', ':user')); + $qb->setParameter(':user', $userId); + + if (count($baseList) > 0) { + $qb->andWhere('d.baseId IN (:bases)'); + $qb->setParameter(':bases', $baseList); + } + + return $qb->getQuery()->execute(); } /** - * Tells whether the registration is enable for provided databox or not. - * - * @param \databox $databox - * - * @return boolean + * Deletes old registrations. */ - public function isRegistrationEnabledForDatabox(\databox $databox) + public function deleteOldRegistrations() { - $enabled = false; - - if ($xml = $databox->get_sxml_structure()) { - foreach ($xml->xpath('/record/caninscript') as $caninscript) { - $enabled = (Boolean) (string) $caninscript; - break; - } - } - - return $enabled; + $qb = $this->getRepository()->createQueryBuilder('d'); + $qb->delete('Alchemy\Phrasea\Model\Entities\Registration', 'd'); + $qb->where($qb->expr()->lt('d.created', ':date')); + $qb->setParameter(':date', new \DateTime('-1 month')); + $qb->getQuery()->execute(); } /** - * Gets CGU released preference for provided databox. + * Deletes registrations on given collection. * - * @param \databox $databox - * - * @return null|string + * @param $baseId */ - public function getCguReleasedPreferencesForDatabox(\databox $databox) + public function deleteRegistrationsOnCollection($baseId) { - $cguRelease = null; - - if ($xml = $databox->get_sxml_structure()) { - foreach ($xml->xpath('/record/cgu') as $sbpcgu) { - foreach ($sbpcgu->attributes() as $a => $b) { - if ($a == "release") { - $cguRelease = (string) $b; - break 2; - } - } - } - } - - return $cguRelease; - } - - /** - * Gets Cgu preference for provided databox. - * - * @param \databox $databox - * - * @return null|string - */ - public function getCguPreferencesForDatabox(\databox $databox) - { - $cgu = null; - - if ($xml = $databox->get_sxml_structure()) { - foreach ($xml->xpath('/record/cgu') as $sbpcgu) { - $cgu = (string) $sbpcgu->saveXML(); - break; - } - } - - return $cgu; - } - - /** - * Tells whether registration is activated for provided collection or not. - * - * @param \collection $collection - * - * @return boolean - */ - public function isRegistrationEnabledForCollection(\collection $collection) - { - $enabled = false; - if ($xml = simplexml_load_string($collection->get_prefs())) { - foreach ($xml->xpath('/baseprefs/caninscript') as $caninscript) { - $enabled = (Boolean) (string) $caninscript; - break; - } - } - - return $enabled; - } - - /** - * Gets CGU released preferences for provided collection. - * - * @param \collection $collection - * - * @return null|string - */ - public function getCguReleasedPreferencesForCollection(\collection $collection) - { - $cguRelease = null; - - if ($xml = simplexml_load_string($collection->get_prefs())) { - foreach ($xml->xpath('/baseprefs/cgu') as $sbpcgu) { - foreach ($sbpcgu->attributes() as $a => $b) { - if ($a == "release") { - $cguRelease = (string) $b; - break 2; - } - } - } - } - - return $cguRelease; - } - - /** - * Gets CGU preferences for provided collection. - * - * @param \collection $collection - * - * @return null|string - */ - public function getCguPreferencesForCollection(\collection $collection) - { - $cgu = null; - - if ($xml = simplexml_load_string($collection->get_prefs())) { - foreach ($xml->xpath('/baseprefs/cgu') as $sbpcgu) { - $cgu = (string) $sbpcgu->saveXML(); - break; - } - } - - return $cgu; - } - - /** - * Tells whether registration preference is defined for provided collection. - * - * @param \collection $collection - * - * @return bool - */ - private function isRegistrationDefinedForCollection(\collection $collection) - { - $defined = false; - if ($xml = simplexml_load_string($collection->get_prefs())) { - if (count($xml->xpath('/baseprefs/caninscript')) > 0) { - $defined = true; - } - } - - return $defined; + $qb = $this->getRepository()->createQueryBuilder('d'); + $qb->delete('Alchemy\Phrasea\Model\Entities\Registration', 'd'); + $qb->where($qb->expr()->eq('d.baseId', ':base')); + $qb->setParameter(':base', $baseId); + $qb->getQuery()->execute(); } } diff --git a/lib/Alchemy/Phrasea/Setup/DoctrineMigrations/RegistrationDemandMigration.php b/lib/Alchemy/Phrasea/Setup/DoctrineMigrations/RegistrationDemandMigration.php index 1da763cc79..ef06201fdb 100644 --- a/lib/Alchemy/Phrasea/Setup/DoctrineMigrations/RegistrationDemandMigration.php +++ b/lib/Alchemy/Phrasea/Setup/DoctrineMigrations/RegistrationDemandMigration.php @@ -14,15 +14,15 @@ namespace Alchemy\Phrasea\Setup\DoctrineMigrations; use Doctrine\DBAL\Schema\Schema; use Doctrine\ORM\Query\ResultSetMapping; -class RegistrationDemandMigration extends AbstractMigration +class RegistrationMigration extends AbstractMigration { public function doUpSql(Schema $schema) { - $this->addSql("CREATE TABLE RegistrationDemand (id INT AUTO_INCREMENT NOT NULL, user_id INT NOT NULL, base_id INT NOT NULL, pending TINYINT(1) NOT NULL, rejected TINYINT(1) NOT NULL, created DATETIME NOT NULL, updated DATETIME NOT NULL, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB"); + $this->addSql("CREATE TABLE Registration (id INT AUTO_INCREMENT NOT NULL, user_id INT NOT NULL, base_id INT NOT NULL, pending TINYINT(1) NOT NULL, rejected TINYINT(1) NOT NULL, created DATETIME NOT NULL, updated DATETIME NOT NULL, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB"); } public function doDownSql(Schema $schema) { - $this->addSql("DROP TABLE RegistrationDemand"); + $this->addSql("DROP TABLE Registration"); } } diff --git a/lib/classes/collection.php b/lib/classes/collection.php index 70056d1db7..fa51210cfc 100644 --- a/lib/classes/collection.php +++ b/lib/classes/collection.php @@ -406,7 +406,7 @@ class collection implements cache_cacheableInterface $stmt->execute([':base_id' => $this->get_base_id()]); $stmt->closeCursor(); - $this->app['registration-manager']->getRepository()->deleteDemandsOnCollection($this->get_base_id()); + $this->app['registration-manager']->deleteRegistrationsOnCollection($this->get_base_id()); $this->get_databox()->delete_data_from_cache(databox::CACHE_COLLECTIONS); @@ -534,7 +534,7 @@ class collection implements cache_cacheableInterface $stmt->execute($params); $stmt->closeCursor(); - $this->app['registration-manager']->getRepository()->deleteDemandsOnCollection($this->get_base_id()); + $this->app['registration-manager']->deleteRegistrationsOnCollection($this->get_base_id()); phrasea::reset_baseDatas($app['phraseanet.appbox']); @@ -740,4 +740,46 @@ class collection implements cache_cacheableInterface { self::$_collections = []; } + + /** + * Tells whether registration is activated for provided collection or not. + * + * @return boolean + */ + public function isRegistrationEnabled() + { + if ($xml = simplexml_load_string($this->get_prefs())) { + $element = $xml->xpath('/baseprefs/caninscript'); + + if (count($element) === 0) { + return $this->databox->isRegistrationEnabled(); + } + + foreach ($element as $caninscript) { + if (false !== (Boolean) (string) $caninscript) { + return true; + } + } + } + + return false; + } + + /** + * Gets terms of use. + * + * @param \collection $collection + * + * @return null|string + */ + public function getTermsOfUse() + { + if ($xml = simplexml_load_string($this->get_prefs())) { + foreach ($xml->xpath('/baseprefs/cgu') as $sbpcgu) { + return $sbpcgu->saveXML(); + } + } + + return null; + } } diff --git a/lib/classes/databox.php b/lib/classes/databox.php index 0ac8b268d9..d9d689f436 100644 --- a/lib/classes/databox.php +++ b/lib/classes/databox.php @@ -1482,4 +1482,22 @@ class databox extends base { self::$_xpath_thesaurus = self::$_dom_thesaurus = self::$_thesaurus = self::$_sxml_thesaurus = []; } + + /** + * Tells whether the registration is enable for provided databox or not. + * + * @return boolean + */ + public function isRegistrationEnabled() + { + if (false !== $xml = $this->get_sxml_structure()) { + foreach ($xml->xpath('/record/caninscript') as $canRegister) { + if (false !== (Boolean) (string) $canRegister) { + return true; + } + } + } + + return false; + } } diff --git a/lib/conf.d/migrations.yml b/lib/conf.d/migrations.yml index 8dd2b848fa..904f62ace8 100644 --- a/lib/conf.d/migrations.yml +++ b/lib/conf.d/migrations.yml @@ -55,5 +55,5 @@ migrations: version: user-auth-provider class: Alchemy\Phrasea\Setup\DoctrineMigrations\UserAuthProviderMigration migration18: - version: registration-demand - class: Alchemy\Phrasea\Setup\DoctrineMigrations\RegistrationDemandMigration + version: registration-request + class: Alchemy\Phrasea\Setup\DoctrineMigrations\RegistrationMigration \ No newline at end of file diff --git a/templates/web/account/access.html.twig b/templates/web/account/access.html.twig index 1732decbef..6f632fbeac 100644 --- a/templates/web/account/access.html.twig +++ b/templates/web/account/access.html.twig @@ -19,8 +19,8 @@

{{ sbasName }}

{{ "login::register: acces authorise sur la collection" | trans }}{{ sbasName }} @@ -35,8 +35,8 @@
{{ "login::register: acces refuse sur la collection" | trans }}{{ sbasName }} @@ -51,8 +51,8 @@
{{ "login::register: en attente d\'acces sur" | trans }} {{ sbasId |sbas_labels(app) }} @@ -67,8 +67,8 @@
{{ "login::register: acces temporaire sur" | trans }} {{ sbasId |sbas_labels(app) }} @@ -83,8 +83,8 @@
{{ "login::register: acces temporaire termine sur" | trans }}{{ sbasId |sbas_labels(app) }} @@ -99,8 +99,8 @@
{{ "login::register: acces supendu sur" | trans }} {{ sbasId |sbas_labels(app) }} @@ -127,7 +127,7 @@
{{ baseInfo["config"]["cgu"] }}
{{ "login::register: L\'acces aux bases ci-dessous implique l\'acceptation des Conditions Generales d\'Utilisation (CGU) suivantes" | trans }}
@@ -231,7 +230,7 @@ diff --git a/templates/web/admin/tree.html.twig b/templates/web/admin/tree.html.twig index ab65d59a6b..9559e0fb7d 100644 --- a/templates/web/admin/tree.html.twig +++ b/templates/web/admin/tree.html.twig @@ -44,7 +44,7 @@
  • - + {{ 'admin::utilisateurs: demandes en cours' | trans }} diff --git a/templates/web/admin/user/demand.html.twig b/templates/web/admin/user/registrations.html.twig similarity index 96% rename from templates/web/admin/user/demand.html.twig rename to templates/web/admin/user/registrations.html.twig index ac3fd2f5f3..7e83081ae9 100644 --- a/templates/web/admin/user/demand.html.twig +++ b/templates/web/admin/user/registrations.html.twig @@ -7,7 +7,7 @@ resize(); }); - var $form = $("form#accept-demand"); + var $form = $("form#accept-registration"); var $mainBtnAction = $(".btn-all-action", $form); var $basesBtnAction = $(".btn-single-action", $form); @@ -172,8 +172,8 @@ {% endif %} -{% if users | length > 0 %} - +{% if user_registrations | length > 0 %} +
  • - {% for baseId, demand in userDemands %} + {% for baseId, demand in userRegistrations %}
    {{ app['date-formatter'].getPrettyString(demand.getUpdated()) }}
    diff --git a/tests/Alchemy/Tests/Phrasea/Controller/Root/AccountTest.php b/tests/Alchemy/Tests/Phrasea/Controller/Root/AccountTest.php index dfb43e2737..fc9d0012ea 100644 --- a/tests/Alchemy/Tests/Phrasea/Controller/Root/AccountTest.php +++ b/tests/Alchemy/Tests/Phrasea/Controller/Root/AccountTest.php @@ -3,6 +3,7 @@ namespace Alchemy\Tests\Phrasea\Controller\Root; use Alchemy\Phrasea\Application; +use Alchemy\Phrasea\Model\Entities\Registration; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; use Alchemy\Phrasea\Model\Entities\User; @@ -49,6 +50,17 @@ class AccountTest extends \PhraseanetAuthenticatedWebTestCase { $data = [ [ + 'registrations' => [ + 'by-type' => [ + 'inactive' => [new Registration()], + 'accepted' => [new Registration()], + 'in-time' => [new Registration()], + 'out-dated' => [new Registration()], + 'pending' => [new Registration()], + 'rejected' => [new Registration()], + ], + 'by-collection' => [] + ], 'config' => [ 'db-name' => 'a_db_name', 'cgu' => null, @@ -58,16 +70,14 @@ class AccountTest extends \PhraseanetAuthenticatedWebTestCase [ 'coll-name' => 'a_coll_name', 'can-register' => false, - 'cgu' => null, - 'cgu-release' => null, - 'demand' => null + 'cgu' => 'Some terms of use.', + 'registration' => null ], [ 'coll-name' => 'an_other_coll_name', 'can-register' => false, 'cgu' => null, - 'cgu-release' => null, - 'demand' => null + 'registration' => null ] ], ] @@ -76,10 +86,10 @@ class AccountTest extends \PhraseanetAuthenticatedWebTestCase $service = $this->getMockBuilder('Alchemy\Phrasea\Registration\RegistrationManager') ->setConstructorArgs([self::$DI['app']['EM'], self::$DI['app']['phraseanet.appbox'], self::$DI['app']['acl']]) - ->setMethods(['getRegistrationDemandsForUser']) + ->setMethods(['getRegistrationSummary']) ->getMock(); - $service->expects($this->once())->method('getRegistrationDemandsForUser')->will($this->returnValue($data)); + $service->expects($this->once())->method('getRegistrationSummary')->will($this->returnValue($data)); self::$DI['app']['registration-manager'] = $service; self::$DI['client']->request('GET', '/account/access/'); @@ -337,8 +347,8 @@ class AccountTest extends \PhraseanetAuthenticatedWebTestCase $this->assertTrue($response->isRedirect()); $this->assertEquals('minet', self::$DI['app']['authentication']->getUser()->getLastName()); - $rs = self::$DI['app']['EM']->getRepository('Alchemy\Phrasea\Model\Entities\RegistrationDemand')->findBy([ - 'user' => self::$DI['app']['authentication']->getUser(), + $rs = self::$DI['app']['EM']->getRepository('Alchemy\Phrasea\Model\Entities\Registration')->findBy([ + 'user' => self::$DI['app']['authentication']->getUser()->getId(), 'pending' => true ]); diff --git a/tests/Alchemy/Tests/Phrasea/Controller/Root/LoginTest.php b/tests/Alchemy/Tests/Phrasea/Controller/Root/LoginTest.php index a0f2adbcca..1b73487e55 100644 --- a/tests/Alchemy/Tests/Phrasea/Controller/Root/LoginTest.php +++ b/tests/Alchemy/Tests/Phrasea/Controller/Root/LoginTest.php @@ -9,7 +9,7 @@ use Alchemy\Phrasea\Authentication\Provider\Token\Identity; use Alchemy\Phrasea\Authentication\Exception\NotAuthenticatedException; use Alchemy\Phrasea\Exception\InvalidArgumentException; use Alchemy\Phrasea\Authentication\ProvidersCollection; -use Alchemy\Phrasea\Model\Entities\RegistrationDemand; +use Alchemy\Phrasea\Model\Entities\Registration; use Alchemy\Phrasea\Model\Entities\User; use Symfony\Component\HttpKernel\Client; use Symfony\Component\HttpFoundation\ResponseHeaderBag; @@ -209,7 +209,7 @@ class LoginTest extends \PhraseanetAuthenticatedWebTestCase self::$DI['user']->setMailLocked(true); $this->deleteRequest(); - $demand = new RegistrationDemand(); + $demand = new Registration(); $demand->setUser(self::$DI['user']); $demand->setBaseId(self::$DI['collection']->get_base_id()); @@ -1797,7 +1797,7 @@ class LoginTest extends \PhraseanetAuthenticatedWebTestCase */ private function deleteRequest() { - $query = self::$DI['app']['EM']->createQuery('DELETE FROM Alchemy\Phrasea\Model\Entities\RegistrationDemand d WHERE d.user=?1'); + $query = self::$DI['app']['EM']->createQuery('DELETE FROM Alchemy\Phrasea\Model\Entities\Registration d WHERE d.user=?1'); $query->setParameter(1, self::$DI['user']->getId()); $query->execute(); } diff --git a/tests/Alchemy/Tests/Phrasea/Registration/RegistrationManagerTest.php b/tests/Alchemy/Tests/Phrasea/Registration/RegistrationManagerTest.php index c88241ea67..8350dcbf43 100644 --- a/tests/Alchemy/Tests/Phrasea/Registration/RegistrationManagerTest.php +++ b/tests/Alchemy/Tests/Phrasea/Registration/RegistrationManagerTest.php @@ -3,256 +3,163 @@ namespace Alchemy\Tests\Phrasea\Registration; use Alchemy\Phrasea\Application; -use Alchemy\Phrasea\Authentication\ProvidersCollection; -use Alchemy\Phrasea\Exception\InvalidArgumentException; -use Alchemy\Phrasea\Model\Entities\RegistrationDemand; +use Alchemy\Phrasea\Model\Entities\Registration; use Alchemy\Phrasea\Registration\RegistrationManager; class RegistrationManagerTest extends \PhraseanetTestCase { - /** - * @dataProvider registrationConfigProvider - */ - public function testRegistrationIsEnable($data, $value) + public function testCreateRegistration() { - $service = $this->getMockBuilder('Alchemy\Phrasea\Registration\RegistrationManager') - ->setConstructorArgs([self::$DI['app']['EM'], self::$DI['app']['phraseanet.appbox'], self::$DI['app']['acl']]) - ->setMethods(['getRegistrationInformations']) + $em = $this->getMockBuilder('Doctrine\ORM\EntityManager') + ->disableOriginalConstructor() ->getMock(); + $em->expects($this->once())->method('persist')->with($this->isInstanceOf('Alchemy\Phrasea\Model\Entities\Registration')); + $em->expects($this->once())->method('flush'); - $service->expects($this->once())->method('getRegistrationInformations')->will($this->returnValue($data)); - $this->assertEquals($value, $service->isRegistrationEnabled()); + $service = new RegistrationManager($em, self::$DI['app']['phraseanet.appbox'], self::$DI['app']['acl']); + + $registration = $service->createRegistration(self::$DI['user']->get_id(), self::$DI['collection']->get_base_id()); + + $this->assertInstanceOf('Alchemy\Phrasea\Model\Entities\Registration', $registration); + $this->assertEquals(self::$DI['collection']->get_base_id(), $registration->getBaseId()); + $this->assertEquals(self::$DI['user']->get_id(), $registration->getUser()); + + return $registration; } /** - * @dataProvider databoxXmlConfiguration + * @depends testCreateRegistration */ - public function testIsRegistrationEnabledForDatabox($data, $value) + public function testRejectRegistration($registration) { - $service = new RegistrationManager(self::$DI['app']['EM'], self::$DI['app']['phraseanet.appbox'], self::$DI['app']['acl']); - - $mock = $this->getMockBuilder('\databox') + $em = $this->getMockBuilder('Doctrine\ORM\EntityManager') ->disableOriginalConstructor() - ->setMethods(['get_sxml_structure']) ->getMock(); + $em->expects($this->once())->method('persist')->with($this->isInstanceOf('Alchemy\Phrasea\Model\Entities\Registration')); + $em->expects($this->once())->method('flush'); - $mock->expects($this->once())->method('get_sxml_structure')->will($this->returnValue($data)); - $this->assertEquals($value, $service->isRegistrationEnabledForDatabox($mock)); + $service = new RegistrationManager($em, self::$DI['app']['phraseanet.appbox'], self::$DI['app']['acl']); + + $service->rejectRegistration($registration); + $this->assertFalse($registration->isPending()); + $this->assertTrue($registration->isRejected()); + + return $registration; } /** - * @dataProvider collectionXmlConfiguration + * @depends testCreateRegistration */ - public function testIsRegistrationEnabledForCollection($data, $value) + public function testAcceptRegistration($registration) + { + $aclMock = $this->getMockBuilder('ACL') + ->disableOriginalConstructor() + ->getMock(); + $aclMock->expects($this->once())->method('give_access_to_sbas')->with($this->equalTo([self::$DI['collection']->get_sbas_id()])); + $aclMock->expects($this->once())->method('give_access_to_base')->with($this->equalTo([self::$DI['collection']->get_base_id()])); + $aclMock->expects($this->once())->method('update_rights_to_base')->with($this->equalTo(self::$DI['collection']->get_base_id()), $this->equalTo([ + 'canputinalbum' => '1', + 'candwnldhd' => '1', + 'nowatermark' => '0', + 'candwnldpreview' => '1', + 'actif' => '1', + ])); + $aclProviderMock = $this->getMockBuilder('Alchemy\Phrasea\Authentication\ACLProvider') + ->disableOriginalConstructor() + ->getMock(); + $aclProviderMock->expects($this->any())->method('get')->with($this->equalTo(self::$DI['user']))->will($this->returnvalue($aclMock)); + $em = $this->getMockBuilder('Doctrine\ORM\EntityManager') + ->disableOriginalConstructor() + ->getMock(); + $em->expects($this->once())->method('remove')->with($this->isInstanceOf('Alchemy\Phrasea\Model\Entities\Registration')); + $em->expects($this->once())->method('flush'); + + $service = new RegistrationManager($em, self::$DI['app']['phraseanet.appbox'], $aclProviderMock); + $service->acceptRegistration($registration, self::$DI['user'], self::$DI['collection'], true, false); + } + + public function testDeleteRegistrationForUser() { $service = new RegistrationManager(self::$DI['app']['EM'], self::$DI['app']['phraseanet.appbox'], self::$DI['app']['acl']); + $qb = $service->getRepository()->createQueryBuilder('r'); + $nbRegistrationBefore = $qb->select('COUNT(r)') + ->where($qb->expr()->eq('r.user', ':user')) + ->setParameter(':user', self::$DI['user_alt1']->get_id()) + ->getQuery() + ->getSingleScalarResult(); + $service->deleteRegistrationsForUser(self::$DI['user_alt1']->get_id(), [self::$DI['collection']->get_base_id()]); + $nbRegistrationAfter = $qb->getQuery()->getSingleScalarResult(); + $this->assertGreaterThan($nbRegistrationAfter, $nbRegistrationBefore); + } - $mock = $this->getMockBuilder('\collection') - ->disableOriginalConstructor() - ->setMethods(['get_prefs']) - ->getMock(); + public function testDeleteOldRegistrations() + { + $service = new RegistrationManager(self::$DI['app']['EM'], self::$DI['app']['phraseanet.appbox'], self::$DI['app']['acl']); + $qb = $service->getRepository()->createQueryBuilder('r'); + $nbRegistrationBefore = $qb->select('COUNT(r)') + ->getQuery() + ->getSingleScalarResult(); + $service->deleteOldRegistrations(); + $nbRegistrationAfter = $qb->getQuery()->getSingleScalarResult(); + $this->assertGreaterThan($nbRegistrationAfter, $nbRegistrationBefore); + } - $mock->expects($this->once())->method('get_prefs')->will($this->returnValue($data)); - $this->assertEquals($value, $service->isRegistrationEnabledForCollection($mock)); + public function testDeleteRegistrationOnCollection() + { + $service = new RegistrationManager(self::$DI['app']['EM'], self::$DI['app']['phraseanet.appbox'], self::$DI['app']['acl']); + $qb = $service->getRepository()->createQueryBuilder('r'); + $nbRegistrationBefore = $qb->select('COUNT(r)') + ->getQuery() + ->getSingleScalarResult(); + $service->deleteRegistrationsOnCollection(self::$DI['collection']->get_base_id()); + $nbRegistrationAfter = $qb->getQuery()->getSingleScalarResult(); + $this->assertGreaterThan($nbRegistrationAfter, $nbRegistrationBefore); } /** * @dataProvider userDataProvider */ - public function testGetRegistrationInformationsWithUserData($data, $type, $value) + public function testGetRegistrationSummaryWithUserData($data, $type, $value) { - $service = $this->getMockBuilder('Alchemy\Phrasea\Registration\RegistrationManager') - ->setConstructorArgs([self::$DI['app']['EM'], self::$DI['app']['phraseanet.appbox'], self::$DI['app']['acl']]) - ->setMethods(['getRegistrationDemandsForUser']) + $repoMock = $this->getMockBuilder('Alchemy\Phrasea\Model\Repositories\RegistrationRepository') + ->disableOriginalConstructor() + ->setMethods(['getRegistrationsSummaryForUser']) ->getMock(); + $repoMock->expects($this->once())->method('getRegistrationsSummaryForUser')->will($this->returnValue($data)); + $em = $this->getMockBuilder('Doctrine\ORM\EntityManager') + ->disableOriginalConstructor() + ->getMock(); + $em->expects($this->once())->method('getRepository')->will($this->returnValue($repoMock)); - $service->expects($this->once())->method('getRegistrationDemandsForUser')->will($this->returnValue($data)); + $service = new RegistrationManager($em, self::$DI['app']['phraseanet.appbox'], self::$DI['app']['acl']); - $rs = $service->getRegistrationInformations(4); + $rs = $service->getRegistrationSummary(4); $databox = current(self::$DI['app']['phraseanet.appbox']->get_databoxes()); $collection = current($databox->get_collections()); - $this->assertEquals($value, count($rs[$databox->get_sbas_id()]['demands']['by-type'][$type])); - $this->assertNotNull($rs[$databox->get_sbas_id()]['demands']['by-collection'][$collection->get_base_id()]); - } - - public function databoxXmlConfiguration() - { - $xmlInscript = -<< -11 -XML; - $xmlNoInscript = - << -01 -XML; - $xmlNoInscriptEmpty = - << - -XML; - - return [ - [simplexml_load_string($xmlInscript), true], - [simplexml_load_string($xmlNoInscript), false], - [simplexml_load_string($xmlNoInscriptEmpty), false], - ]; - } - - public function collectionXmlConfiguration() - { - $xmlInscript = -<< -11 -XML; - $xmlNoInscript = -<< -01 -XML; - $xmlNoInscriptEmpty = -<< - -XML; - - return [ - [$xmlInscript, true], - [$xmlNoInscript, false], - [$xmlNoInscriptEmpty, false], - ]; - } - - public function registrationConfigProvider() - { - $enableDataboxConfig = [ - [ - [ - 'config' => [ - 'db-name' => 'a_db_name', - 'cgu' => null, - 'cgu-release' => null, - 'can-register' => true, - 'collections' => [], - ] - ] - ], - false - ]; - - $enableCollectionConfig = [ - [ - [ - 'config' => [ - 'db-name' => 'a_db_name', - 'cgu' => null, - 'cgu-release' => null, - 'can-register' => false, - 'collections' => [ - [ - 'coll-name' => 'a_coll_name', - 'can-register' => true, - 'cgu' => null, - 'cgu-release' => null, - 'demand' => null - ] - ], - ] - ] - ], - true - ]; - - $nothingEnabledConfig = [ - [ - [ - 'config' => [ - 'db-name' => 'a_db_name', - 'cgu' => null, - 'cgu-release' => null, - 'can-register' => false, - 'collections' => [ - [ - 'coll-name' => 'a_coll_name', - 'can-register' => false, - 'cgu' => null, - 'cgu-release' => null, - 'demand' => null - ], - [ - 'coll-name' => 'an_other_coll_name', - 'can-register' => false, - 'cgu' => null, - 'cgu-release' => null, - 'demand' => null - ] - ], - ] - ] - ], - false - ]; - - $noCollectionEnabledButBaseEnabledConfig = [ - [ - [ - 'config' => [ - 'db-name' => 'a_db_name', - 'cgu' => null, - 'cgu-release' => null, - 'can-register' => true, - 'collections' => [ - [ - 'coll-name' => 'a_coll_name', - 'can-register' => false, - 'cgu' => null, - 'cgu-release' => null, - 'demand' => null - ], - [ - 'coll-name' => 'an_other_coll_name', - 'can-register' => false, - 'cgu' => null, - 'cgu-release' => null, - 'demand' => null - ] - ], - ] - ] - ], - false - ]; - - return [ - $enableDataboxConfig, - $enableCollectionConfig, - $nothingEnabledConfig, - $noCollectionEnabledButBaseEnabledConfig - ]; + $this->assertEquals($value, count($rs[$databox->get_sbas_id()]['registrations']['by-type'][$type])); + $this->assertNotNull($rs[$databox->get_sbas_id()]['registrations']['by-collection'][$collection->get_base_id()]); } public function userDataProvider() { - $pendingDemand = new RegistrationDemand(); - $pendingDemand->setBaseId(1); - $pendingDemand->setUser(3); - $pendingDemand->setPending(true); - $pendingDemand->setRejected(false); + $pendingRegistration = new Registration(); + $pendingRegistration->setBaseId(1); + $pendingRegistration->setUser(3); + $pendingRegistration->setPending(true); + $pendingRegistration->setRejected(false); - $rejectedDemand = new RegistrationDemand(); - $rejectedDemand->setBaseId(1); - $rejectedDemand->setUser(3); - $rejectedDemand->setPending(true); - $rejectedDemand->setRejected(true); + $rejectedRegistration = new Registration(); + $rejectedRegistration->setBaseId(1); + $rejectedRegistration->setUser(3); + $rejectedRegistration->setPending(true); + $rejectedRegistration->setRejected(true); $databox = current((new \appbox(new Application()))->get_databoxes()); $collection = current($databox->get_collections()); - $noLimitedPendingDemand = [ + $noLimitedPendingRegistration = [ [ $databox->get_sbas_id() => [ $collection->get_base_id() => [ @@ -261,7 +168,7 @@ XML; 'active' => true, 'time-limited' => false, 'in-time' => null, - 'demand' => $pendingDemand + 'registration' => $pendingRegistration ] ] ], @@ -270,7 +177,7 @@ XML; ]; - $rejectedDemand = [ + $rejectedRegistration = [ [ $databox->get_sbas_id() => [ $collection->get_base_id() => [ @@ -279,7 +186,7 @@ XML; 'active' => true, 'time-limited' => false, 'in-time' => null, - 'demand' => $rejectedDemand + 'registration' => $rejectedRegistration ] ] ], @@ -287,7 +194,7 @@ XML; 1 ]; - $noActiveDemand = [ + $noActiveRegistration = [ [ $databox->get_sbas_id() => [ $collection->get_base_id() => [ @@ -296,7 +203,7 @@ XML; 'active' => false, 'time-limited' => false, 'in-time' => null, - 'demand' => $pendingDemand + 'registration' => $pendingRegistration ] ] ], @@ -304,7 +211,7 @@ XML; 1 ]; - $limitedActiveIntimePendingDemand = [ + $limitedActiveIntimePendingRegistration = [ [ $databox->get_sbas_id() => [ $collection->get_base_id() => [ @@ -313,7 +220,7 @@ XML; 'active' => true, 'time-limited' => true, 'in-time' => true, - 'demand' => $pendingDemand + 'registration' => $pendingRegistration ] ] ], @@ -321,7 +228,7 @@ XML; 1 ]; - $limitedActiveOutdatedPendingDemand = [ + $limitedActiveOutdatedPendingRegistration = [ [ $databox->get_sbas_id() => [ $collection->get_base_id() => [ @@ -330,7 +237,7 @@ XML; 'active' => true, 'time-limited' => true, 'in-time' => false, - 'demand' => $pendingDemand + 'registration' => $pendingRegistration ] ] ], @@ -339,11 +246,11 @@ XML; ]; return [ - $noLimitedPendingDemand, - $noActiveDemand, - $limitedActiveIntimePendingDemand, - $limitedActiveOutdatedPendingDemand, - $rejectedDemand + $noLimitedPendingRegistration, + $noActiveRegistration, + $limitedActiveIntimePendingRegistration, + $limitedActiveOutdatedPendingRegistration, + $rejectedRegistration ]; } } diff --git a/tests/classes/collectionTest.php b/tests/classes/collectionTest.php index 0949bbd416..6f7c084618 100644 --- a/tests/classes/collectionTest.php +++ b/tests/classes/collectionTest.php @@ -363,4 +363,43 @@ class collectionTest extends \PhraseanetAuthenticatedTestCase 'This test has not been implemented yet.' ); } + + /** + * @dataProvider collectionXmlConfiguration + */ + public function testIsRegistrationEnabled($data, $value) + { + $mock = $this->getMockBuilder('\collection') + ->disableOriginalConstructor() + ->setMethods(['get_prefs']) + ->getMock(); + + $mock->expects($this->once())->method('get_prefs')->will($this->returnValue($data)); + $this->assertEquals($value, $mock->isRegistrationEnabled()); + } + + public function collectionXmlConfiguration() + { + $xmlInscript = +<< +11 +XML; + $xmlNoInscript = +<< +01 +XML; + $xmlNoInscriptEmpty = +<< + +XML; + + return [ + [$xmlInscript, true], + [$xmlNoInscript, false], + [$xmlNoInscriptEmpty, false], + ]; + } } diff --git a/tests/classes/databoxTest.php b/tests/classes/databoxTest.php index c53911ead7..8da601ee8b 100644 --- a/tests/classes/databoxTest.php +++ b/tests/classes/databoxTest.php @@ -112,4 +112,43 @@ class databoxTest extends \PhraseanetAuthenticatedWebTestCase $this->assertNull($databox->get_label('fr', false)); $this->assertNull($databox->get_label('en', false)); } + + /** + * @dataProvider databoxXmlConfiguration + */ + public function testIsRegistrationEnabled($data, $value) + { + $mock = $this->getMockBuilder('\databox') + ->disableOriginalConstructor() + ->setMethods(['get_sxml_structure']) + ->getMock(); + + $mock->expects($this->once())->method('get_sxml_structure')->will($this->returnValue($data)); + $this->assertEquals($value, $mock->isRegistrationEnabled()); + } + + public function databoxXmlConfiguration() + { + $xmlInscript = +<< +11 +XML; + $xmlNoInscript = +<< +01 +XML; + $xmlNoInscriptEmpty = +<< + +XML; + + return [ + [simplexml_load_string($xmlInscript), true], + [simplexml_load_string($xmlNoInscript), false], + [simplexml_load_string($xmlNoInscriptEmpty), false], + ]; + } } From 4946e35516187f674ebe69c56bf738ae14e7e76a Mon Sep 17 00:00:00 2001 From: Nicolas Le Goff Date: Tue, 4 Feb 2014 12:01:54 +0100 Subject: [PATCH 3/6] Fix tests, CS && typo --- lib/Alchemy/Phrasea/Controller/Admin/Users.php | 6 +++--- .../Phrasea/Form/Login/PhraseaRegisterForm.php | 5 ----- .../Phrasea/Registration/RegistrationManager.php | 12 ++++++++---- lib/classes/databox.php | 2 +- templates/web/admin/user/demand.html.twig | 2 +- .../Tests/Phrasea/Controller/Admin/UsersTest.php | 12 ------------ 6 files changed, 13 insertions(+), 26 deletions(-) diff --git a/lib/Alchemy/Phrasea/Controller/Admin/Users.php b/lib/Alchemy/Phrasea/Controller/Admin/Users.php index b0b1a3a900..0d293a44bf 100644 --- a/lib/Alchemy/Phrasea/Controller/Admin/Users.php +++ b/lib/Alchemy/Phrasea/Controller/Admin/Users.php @@ -445,7 +445,7 @@ class Users implements ControllerProviderInterface foreach ($deny as $usr => $bases) { $cache_to_update[$usr] = true; foreach ($bases as $bas) { - if (null !== $registration = $this->getRepository()->findOneBy([ + if (null !== $registration = $app['registration-manager']->getRepository()->findOneBy([ 'user' => $usr, 'baseId' => $bas ])) { @@ -461,12 +461,12 @@ class Users implements ControllerProviderInterface foreach ($bases as $bas) { $collection = \collection::get_from_base_id($app, $bas); - if (null !== $registration = $this->getRepository()->findOneBy([ + if (null !== $registration = $app['registration-manager']->getRepository()->findOneBy([ 'user' => $user->get_id(), 'baseId' => $collection->get_base_id() ])) { $done[$usr][$bas] = true; - $app['registration-manager']->acceptDemand($registration, $user, $collection, $options[$usr][$bas]['HD'], $options[$usr][$bas]['WM']); + $app['registration-manager']->acceptRegistration($registration, $user, $collection, $options[$usr][$bas]['HD'], $options[$usr][$bas]['WM']); } } } diff --git a/lib/Alchemy/Phrasea/Form/Login/PhraseaRegisterForm.php b/lib/Alchemy/Phrasea/Form/Login/PhraseaRegisterForm.php index 2389dea842..80449b1bf2 100644 --- a/lib/Alchemy/Phrasea/Form/Login/PhraseaRegisterForm.php +++ b/lib/Alchemy/Phrasea/Form/Login/PhraseaRegisterForm.php @@ -81,11 +81,6 @@ class PhraseaRegisterForm extends AbstractType if (false === $collInfo['can-register']) { continue; } - - if (!isset($choices[$dbName])) { - $choices[$dbName] = []; - } - $choices[$dbName][$baseId] = \phrasea::bas_labels($baseId, $this->app); $baseIds[] = $baseId; } diff --git a/lib/Alchemy/Phrasea/Registration/RegistrationManager.php b/lib/Alchemy/Phrasea/Registration/RegistrationManager.php index 9aac344646..3d4f93b1b6 100644 --- a/lib/Alchemy/Phrasea/Registration/RegistrationManager.php +++ b/lib/Alchemy/Phrasea/Registration/RegistrationManager.php @@ -54,8 +54,7 @@ class RegistrationManager /** * Rejects a registration. * - * @param $usrId - * @param $baseId + * @param Registration $registration */ public function rejectRegistration(Registration $registration) { @@ -68,8 +67,11 @@ class RegistrationManager /** * Accepts a registration. * - * @param $userId - * @param $basId + * @param Registration $registration + * @param \User_Adapter $user + * @param \Collection $collection + * @param bool $grantHd + * @param bool $grantWatermark */ public function acceptRegistration(Registration $registration, \User_Adapter $user, \Collection $collection, $grantHd = false, $grantWatermark = false) { @@ -208,6 +210,8 @@ class RegistrationManager } /** + * Deletes registration for given user. + * * @param $userId * @param array $baseList * diff --git a/lib/classes/databox.php b/lib/classes/databox.php index d9d689f436..9df97cbab8 100644 --- a/lib/classes/databox.php +++ b/lib/classes/databox.php @@ -1484,7 +1484,7 @@ class databox extends base } /** - * Tells whether the registration is enable for provided databox or not. + * Tells whether the registration is enable or not. * * @return boolean */ diff --git a/templates/web/admin/user/demand.html.twig b/templates/web/admin/user/demand.html.twig index e0bb3735f0..ac3fd2f5f3 100644 --- a/templates/web/admin/user/demand.html.twig +++ b/templates/web/admin/user/demand.html.twig @@ -172,7 +172,7 @@ {% endif %} -{% if table['users'] | length > 0 %} +{% if users | length > 0 %}
    {{ collInfo["coll-name"] }} - + {{ "login::register: Faire une demande d\'acces" | trans }}
    -
    - {% for user in users %} - {% set userRegistrations = registrations[user.getId()] %} +
    + {% for user_registration in user_registrations %} + {% set user = user_registration['user'] %}
    @@ -230,9 +230,9 @@
    - {% for baseId, demand in userRegistrations %} + {% for basId, registration in user_registration['registrations'] %}
    - {{ app['date-formatter'].getPrettyString(demand.getUpdated()) }} + {{ app['date-formatter'].getPrettyString(registration.getUpdated()) }}
    {{ basId| bas_labels(app) }} diff --git a/tests/Alchemy/Tests/Phrasea/Controller/Admin/UsersTest.php b/tests/Alchemy/Tests/Phrasea/Controller/Admin/UsersTest.php index 2943bdc54b..cbe7e296fc 100644 --- a/tests/Alchemy/Tests/Phrasea/Controller/Admin/UsersTest.php +++ b/tests/Alchemy/Tests/Phrasea/Controller/Admin/UsersTest.php @@ -366,20 +366,18 @@ class UsersTest extends \PhraseanetAuthenticatedWebTestCase self::$DI['app']['manipulator.user']->delete($user); } - public function testRenderDemands() + public function testRenderRegistrations() { - self::$DI['client']->request('GET', '/admin/users/demands/'); + self::$DI['client']->request('GET', '/admin/users/registrations/'); $this->assertTrue(self::$DI['client']->getResponse()->isOk()); } - public function testPostDemands() + public function testPostRegistrations() { $id = self::$DI['user_alt1']->getId(); $baseId = self::$DI['collection']->get_base_id(); $param = sprintf('%s_%s', $id, $baseId); - $appbox = self::$DI['app']['phraseanet.appbox']; - $stmt = $this->getMock('PDOStatement'); $stmt->expects($this->any()) @@ -408,7 +406,7 @@ class UsersTest extends \PhraseanetAuthenticatedWebTestCase $this->mockNotificationDeliverer('Alchemy\Phrasea\Notification\Mail\MailSuccessEmailUpdate'); - self::$DI['client']->request('POST', '/admin/users/demands/', [ + self::$DI['client']->request('POST', '/admin/users/registrations/', [ 'template' => [], 'accept' => [$param], 'accept_hd' => [$param], diff --git a/tests/Alchemy/Tests/Phrasea/Controller/Prod/UploadTest.php b/tests/Alchemy/Tests/Phrasea/Controller/Prod/UploadTest.php index 3be33c9180..27c741762e 100644 --- a/tests/Alchemy/Tests/Phrasea/Controller/Prod/UploadTest.php +++ b/tests/Alchemy/Tests/Phrasea/Controller/Prod/UploadTest.php @@ -140,7 +140,7 @@ class UploadTest extends \PhraseanetAuthenticatedWebTestCase * @covers Alchemy\Phrasea\Controller\Prod\Upload::upload * @covers Alchemy\Phrasea\Controller\Prod\Upload::getJsonResponse */ - public function testUploadingTwiceTheSameRecordShouldSendToQuantantine() + public function testUploadingTwiceTheSameRecordShouldSendToQuarantine() { $this->mockNotificationDeliverer('Alchemy\Phrasea\Notification\Mail\MailInfoRecordQuarantined'); $this->mockUserNotificationSettings('eventsmanager_notify_uploadquarantine'); diff --git a/tests/Alchemy/Tests/Phrasea/Controller/Prod/UsrListsTest.php b/tests/Alchemy/Tests/Phrasea/Controller/Prod/UsrListsTest.php index c0391c95ef..d6e87d512a 100644 --- a/tests/Alchemy/Tests/Phrasea/Controller/Prod/UsrListsTest.php +++ b/tests/Alchemy/Tests/Phrasea/Controller/Prod/UsrListsTest.php @@ -168,7 +168,7 @@ class UsrListsTest extends \PhraseanetAuthenticatedWebTestCase { $entry = self::$DI['app']['EM']->find('Phraseanet:UsrListEntry', 2); $list_id = $entry->getList()->getId(); - $usr_id = $entry->getUser(self::$DI['app'])->getId(); + $usr_id = $entry->getUser()->getId(); $entry_id = $entry->getId(); $route = '/prod/lists/list/' . $list_id . '/remove/' . $usr_id . '/'; diff --git a/tests/Alchemy/Tests/Phrasea/Controller/Root/AccountTest.php b/tests/Alchemy/Tests/Phrasea/Controller/Root/AccountTest.php index 7c53244c0b..43cfa97c23 100644 --- a/tests/Alchemy/Tests/Phrasea/Controller/Root/AccountTest.php +++ b/tests/Alchemy/Tests/Phrasea/Controller/Root/AccountTest.php @@ -84,14 +84,14 @@ class AccountTest extends \PhraseanetAuthenticatedWebTestCase ] ]; - $service = $this->getMockBuilder('Alchemy\Phrasea\Model\Manipulator\RegistrationManipulator') - ->setConstructorArgs([self::$DI['app']['EM'], self::$DI['app']['phraseanet.appbox'], self::$DI['app']['acl']]) + $service = $this->getMockBuilder('Alchemy\Phrasea\Core\Configuration\RegistrationManager') + ->setConstructorArgs([self::$DI['app']['phraseanet.appbox'], self::$DI['app']['manipulator.registration']->getRepository(), self::$DI['app']['locale']]) ->setMethods(['getRegistrationSummary']) ->getMock(); $service->expects($this->once())->method('getRegistrationSummary')->will($this->returnValue($data)); - self::$DI['app']['registration-manager'] = $service; + self::$DI['app']['registration.manager'] = $service; self::$DI['client']->request('GET', '/account/access/'); $response = self::$DI['client']->getResponse(); @@ -320,7 +320,7 @@ class AccountTest extends \PhraseanetAuthenticatedWebTestCase array_shift($notifs); self::$DI['client']->request('POST', '/account/', [ - 'demand' => $bases, + 'registrations' => $bases, 'form_gender' => User::GENDER_MR, 'form_firstname' => 'gros', 'form_lastname' => 'minet', @@ -347,7 +347,7 @@ class AccountTest extends \PhraseanetAuthenticatedWebTestCase $this->assertTrue($response->isRedirect()); $this->assertEquals('minet', self::$DI['app']['authentication']->getUser()->getLastName()); - $rs = self::$DI['app']['EM']->getRepository('Alchemy\Phrasea\Model\Entities\Registration')->findBy([ + $rs = self::$DI['app']['EM']->getRepository('Phraseanet:Registration')->findBy([ 'user' => self::$DI['app']['authentication']->getUser()->getId(), 'pending' => true ]); diff --git a/tests/Alchemy/Tests/Phrasea/Controller/Root/LoginTest.php b/tests/Alchemy/Tests/Phrasea/Controller/Root/LoginTest.php index 7e1df47b29..def95dc701 100644 --- a/tests/Alchemy/Tests/Phrasea/Controller/Root/LoginTest.php +++ b/tests/Alchemy/Tests/Phrasea/Controller/Root/LoginTest.php @@ -17,7 +17,7 @@ use Symfony\Component\HttpFoundation\Response; class LoginTest extends \PhraseanetAuthenticatedWebTestCase { - public static $demands; + public static $registrationCollections; public static $collections; public static $login; public static $email; @@ -27,8 +27,8 @@ class LoginTest extends \PhraseanetAuthenticatedWebTestCase { parent::setUp(); - if (null === self::$demands) { - self::$demands = [self::$DI['collection']->get_coll_id()]; + if (null === self::$registrationCollections) { + self::$registrationCollections = [self::$DI['collection']->get_coll_id()]; } if (null === self::$collections) { self::$collections = [self::$DI['collection']->get_base_id()]; @@ -45,7 +45,8 @@ class LoginTest extends \PhraseanetAuthenticatedWebTestCase if (null === self::$email) { self::$email = self::$DI['user']->getEmail(); } - self::$DI['app']['registration.enabled'] = true; + + $this->enableRegistration(); } public function tearDown() @@ -56,7 +57,7 @@ class LoginTest extends \PhraseanetAuthenticatedWebTestCase public static function tearDownAfterClass() { - self::$demands = self::$collections = self::$login = self::$email = self::$termsOfUse = null; + self::$registrationCollections = self::$collections = self::$login = self::$email = self::$termsOfUse = null; parent::tearDownAfterClass(); } @@ -209,11 +210,11 @@ class LoginTest extends \PhraseanetAuthenticatedWebTestCase self::$DI['user']->setMailLocked(true); $this->deleteRequest(); - $demand = new Registration(); - $demand->setUser(self::$DI['user']); - $demand->setBaseId(self::$DI['collection']->get_base_id()); + $registration = new Registration(); + $registration->setUser(self::$DI['user']); + $registration->setBaseId(self::$DI['collection']->get_base_id()); - self::$DI['app']['EM']->persist($demand); + self::$DI['app']['EM']->persist($registration); self::$DI['app']['EM']->flush(); self::$DI['client']->request('GET', '/login/register-confirm/', ['code' => $token]); @@ -534,7 +535,7 @@ class LoginTest extends \PhraseanetAuthenticatedWebTestCase */ public function testGetPostRegisterWhenRegistrationDisabled($method, $route) { - self::$DI['app']['registration.enabled'] = false; + $this->disableRegistration(); $this->logout(self::$DI['app']); self::$DI['client']->request($method, $route); $this->assertEquals(404, self::$DI['client']->getResponse()->getStatusCode()); @@ -543,7 +544,7 @@ class LoginTest extends \PhraseanetAuthenticatedWebTestCase /** * @dataProvider provideInvalidRegistrationData */ - public function testPostRegisterbadArguments($parameters, $extraParameters, $errors) + public function testPostRegisterBadArguments($parameters, $extraParameters, $errors) { $this->enableTOU(); self::$DI['app']['registration.enabled'] = true; @@ -554,7 +555,7 @@ class LoginTest extends \PhraseanetAuthenticatedWebTestCase $parameters = array_merge(['_token' => 'token'], $parameters); foreach ($parameters as $key => $parameter) { if ('collections' === $key && null === $parameter) { - $parameters[$key] = self::$demands; + $parameters[$key] = self::$registrationCollections; } if ('login' === $key && null === $parameter) { $parameters[$key] = self::$login; @@ -577,6 +578,7 @@ class LoginTest extends \PhraseanetAuthenticatedWebTestCase public function testPostRegisterWithoutParams() { $this->logout(self::$DI['app']); + $this->disableTOU(); $crawler = self::$DI['client']->request('POST', '/login/register-classic/'); $this->assertFalse(self::$DI['client']->getResponse()->isRedirect()); @@ -592,6 +594,7 @@ class LoginTest extends \PhraseanetAuthenticatedWebTestCase 'confirm' => 'password' ], "collections" => null, + "accept-tou" => '1' ], [], 1], [[//required extra-field missing "password" => [ @@ -599,7 +602,8 @@ class LoginTest extends \PhraseanetAuthenticatedWebTestCase 'confirm' => 'password' ], "email" => $this->generateEmail(), - "collections" => null + "collections" => null, + "accept-tou" => '1' ], [ [ 'name' => 'login', @@ -612,7 +616,8 @@ class LoginTest extends \PhraseanetAuthenticatedWebTestCase 'confirm' => 'passwordMismatch' ], "email" => $this->generateEmail(), - "collections" => null + "collections" => null, + "accept-tou" => '1' ], [], 1], [[//password tooshort "password" => [ @@ -620,7 +625,8 @@ class LoginTest extends \PhraseanetAuthenticatedWebTestCase 'confirm' => 'min' ], "email" => $this->generateEmail(), - "collections" => null + "collections" => null, + "accept-tou" => '1' ], [], 1], [[//email invalid "password" => [ @@ -628,7 +634,8 @@ class LoginTest extends \PhraseanetAuthenticatedWebTestCase 'confirm' => 'password' ], "email" => 'invalid.email', - "collections" => null + "collections" => null, + "accept-tou" => '1' ], [], 1], [[//login exists "login" => null, @@ -637,7 +644,8 @@ class LoginTest extends \PhraseanetAuthenticatedWebTestCase 'confirm' => 'password' ], "email" => $this->generateEmail(), - "collections" => null + "collections" => null, + "accept-tou" => '1' ], [ [ 'name' => 'login', @@ -650,7 +658,8 @@ class LoginTest extends \PhraseanetAuthenticatedWebTestCase 'confirm' => 'password' ], "email" => null, - "collections" => null + "collections" => null, + "accept-tou" => '1' ], [], 1], [[//tou declined "password" => [ @@ -658,8 +667,7 @@ class LoginTest extends \PhraseanetAuthenticatedWebTestCase 'confirm' => 'password' ], "email" => $this->generateEmail(), - "collections" => null, - "accept-tou" => '1' + "collections" => null ], [], 1] ]; } @@ -822,13 +830,6 @@ class LoginTest extends \PhraseanetAuthenticatedWebTestCase self::$DI['app']['registration.fields'] = []; $this->logout(self::$DI['app']); - $managerMock = $this->getMockBuilder('Alchemy\Phrasea\Model\Manipulator\RegistrationManipulator') - ->setConstructorArgs([self::$DI['app']['EM'], self::$DI['app']['phraseanet.appbox'], self::$DI['app']['acl']]) - ->setMethods(['getRepository']) - ->getMock(); - $managerMock->expects($this->any())->method('getRepository')->will($this->returnValue(self::$DI['app']['registration-manager']->getRepository())); - self::$DI['app']['registration-manager'] = $managerMock; - $provider = $this->getMock('Alchemy\Phrasea\Authentication\Provider\ProviderInterface'); $this->addProvider('provider-test', $provider); @@ -856,7 +857,7 @@ class LoginTest extends \PhraseanetAuthenticatedWebTestCase foreach ($parameters as $key => $parameter) { if ('collections' === $key && null === $parameter) { - $parameters[$key] = self::$demands; + $parameters[$key] = self::$registrationCollections; } if ('login' === $key && null === $parameter) { $parameters[$key] = self::$login; @@ -889,7 +890,7 @@ class LoginTest extends \PhraseanetAuthenticatedWebTestCase foreach ($parameters as $key => $parameter) { if ('collections' === $key && null === $parameter) { - $parameters[$key] = self::$demands; + $parameters[$key] = self::$registrationCollections; } if ('login' === $key && null === $parameter) { $parameters[$key] = self::$login; @@ -931,7 +932,7 @@ class LoginTest extends \PhraseanetAuthenticatedWebTestCase foreach ($parameters as $key => $parameter) { if ('collections' === $key && null === $parameter) { - $parameters[$key] = self::$demands; + $parameters[$key] = self::$registrationCollections; } if ('login' === $key && null === $parameter) { $parameters[$key] = self::$login; @@ -952,6 +953,7 @@ class LoginTest extends \PhraseanetAuthenticatedWebTestCase { self::$DI['app']['registration.fields'] = []; $this->logout(self::$DI['app']); + $this->disableTOU(); $emails = [ 'Alchemy\Phrasea\Notification\Mail\MailRequestEmailConfirmation'=>0, @@ -1007,7 +1009,7 @@ class LoginTest extends \PhraseanetAuthenticatedWebTestCase foreach ($parameters as $key => $parameter) { if ('collections' === $key && null === $parameter) { - $parameters[$key] = self::$demands; + $parameters[$key] = self::$registrationCollections; } if ('login' === $key && null === $parameter) { $parameters[$key] = self::$login; @@ -1059,6 +1061,7 @@ class LoginTest extends \PhraseanetAuthenticatedWebTestCase self::$DI['app']['registration.fields'] = $extraParameters; $this->logout(self::$DI['app']); + $this->disableTOU(); $emails = [ 'Alchemy\Phrasea\Notification\Mail\MailRequestEmailConfirmation'=>0, @@ -1072,7 +1075,7 @@ class LoginTest extends \PhraseanetAuthenticatedWebTestCase $parameters = array_merge(['_token' => 'token'], $parameters); foreach ($parameters as $key => $parameter) { if ('collections' === $key && null === $parameter) { - $parameters[$key] = self::$demands; + $parameters[$key] = self::$registrationCollections; } if ('login' === $key && null === $parameter) { $parameters[$key] = self::$login; @@ -1468,13 +1471,6 @@ class LoginTest extends \PhraseanetAuthenticatedWebTestCase public function testAuthenticateProviderCallbackAlreadyBound() { - $managerMock = $this->getMockBuilder('Alchemy\Phrasea\Model\Manipulator\RegistrationManipulator') - ->setConstructorArgs([self::$DI['app']['EM'], self::$DI['app']['phraseanet.appbox'], self::$DI['app']['acl']]) - ->setMethods(['getRepository']) - ->getMock(); - $managerMock->expects($this->any())->method('getRepository')->will($this->returnValue(self::$DI['app']['registration-manager']->getRepository())); - self::$DI['app']['registration-manager'] = $managerMock; - $provider = $this->getMock('Alchemy\Phrasea\Authentication\Provider\ProviderInterface'); $this->addProvider('provider-test', $provider); @@ -1620,8 +1616,7 @@ class LoginTest extends \PhraseanetAuthenticatedWebTestCase $provider = $this->getMock('Alchemy\Phrasea\Authentication\Provider\ProviderInterface'); $this->addProvider('provider-test', $provider); - $provider->expects($this->once()) - ->method('onCallback'); + $provider->expects($this->once())->method('onCallback'); $token = new Token($provider, 42); @@ -1660,10 +1655,7 @@ class LoginTest extends \PhraseanetAuthenticatedWebTestCase { $provider = $this->getMock('Alchemy\Phrasea\Authentication\Provider\ProviderInterface'); $this->addProvider('provider-test', $provider); - - $provider->expects($this->once()) - ->method('onCallback'); - + $provider->expects($this->once())->method('onCallback'); $token = new Token($provider, 42); $provider->expects($this->any()) @@ -1688,16 +1680,15 @@ class LoginTest extends \PhraseanetAuthenticatedWebTestCase ->method('isEnabled') ->will($this->returnValue(false)); - self::$DI['app']['registration.enabled'] = false; - + $this->disableRegistration(); $this->logout(self::$DI['app']); self::$DI['client']->request('GET', '/login/provider/provider-test/callback/'); $this->assertSame(302, self::$DI['client']->getResponse()->getStatusCode()); - $this->assertSame('/login/', self::$DI['client']->getResponse()->headers->get('location')); $this->assertFalse(self::$DI['app']['authentication']->isAuthenticated()); $this->assertFlashMessagePopulated(self::$DI['app'], 'error', 1); + $this->assertSame('/login/', self::$DI['client']->getResponse()->headers->get('location')); } public function testGetRegistrationFields() @@ -1792,12 +1783,12 @@ class LoginTest extends \PhraseanetAuthenticatedWebTestCase } /** - * Delete inscription demand made by the current authenticathed user + * Delete inscription request made by the current authenticathed user * @return void */ private function deleteRequest() { - $query = self::$DI['app']['EM']->createQuery('DELETE FROM Alchemy\Phrasea\Model\Entities\Registration d WHERE d.user=?1'); + $query = self::$DI['app']['EM']->createQuery('DELETE FROM Phraseanet:Registration d WHERE d.user=?1'); $query->setParameter(1, self::$DI['user']->getId()); $query->execute(); } @@ -1827,14 +1818,15 @@ class LoginTest extends \PhraseanetAuthenticatedWebTestCase private function enableTOU() { - if (null === self::$termsOfUse) { - self::$termsOfUse = []; - foreach (self::$DI['app']['phraseanet.appbox']->get_databoxes() as $databox) { - self::$termsOfUse[$databox->get_sbas_id()] = $databox->get_cgus(); + if (null !== self::$termsOfUse) { + return; + } + self::$termsOfUse = []; + foreach (self::$DI['app']['phraseanet.appbox']->get_databoxes() as $databox) { + self::$termsOfUse[$databox->get_sbas_id()] = $databox->get_cgus(); - foreach ( self::$termsOfUse[$databox->get_sbas_id()]as $lng => $tou) { - $databox->update_cgus($lng, 'something', false); - } + foreach ( self::$termsOfUse[$databox->get_sbas_id()]as $lng => $tou) { + $databox->update_cgus($lng, 'something', false); } } } @@ -1856,4 +1848,65 @@ class LoginTest extends \PhraseanetAuthenticatedWebTestCase self::$termsOfUse = null; } + + private function getRegistrationSummary() + { + return [ + [ + 'registrations' => [ + 'by-type' => [ + 'inactive' => [new Registration()], + 'accepted' => [new Registration()], + 'in-time' => [new Registration()], + 'out-dated' => [new Registration()], + 'pending' => [new Registration()], + 'rejected' => [new Registration()], + ], + 'by-collection' => [] + ], + 'config' => [ + 'db-name' => 'a_db_name', + 'cgu' => null, + 'cgu-release' => null, + 'can-register' => false, + 'collections' => [ + [ + 'coll-name' => 'a_coll_name', + 'can-register' => false, + 'cgu' => 'Some terms of use.', + 'registration' => null + ], + [ + 'coll-name' => 'an_other_coll_name', + 'can-register' => false, + 'cgu' => null, + 'registration' => null + ] + ], + ] + ] + ]; + } + + private function enableRegistration() + { + $managerMock = $this->getMockBuilder('Alchemy\Phrasea\Core\Configuration\RegistrationManager') + ->setConstructorArgs([self::$DI['app']['phraseanet.appbox'], self::$DI['app']['manipulator.registration']->getRepository(), self::$DI['app']['locale']]) + ->setMethods(['isRegistrationEnabled']) + ->getMock(); + + self::$DI['app']['registration.manager'] = $managerMock; + self::$DI['app']['registration.manager']->expects($this->any())->method('isRegistrationEnabled')->will($this->returnValue(true)); + } + + private function disableRegistration() + { + $managerMock = $this->getMockBuilder('Alchemy\Phrasea\Core\Configuration\RegistrationManager') + ->setConstructorArgs([self::$DI['app']['phraseanet.appbox'], self::$DI['app']['manipulator.registration']->getRepository(), self::$DI['app']['locale']]) + ->setMethods(['isRegistrationEnabled']) + ->getMock(); + + self::$DI['app']['registration.manager'] = $managerMock; + self::$DI['app']['registration.manager']->expects($this->any())->method('isRegistrationEnabled')->will($this->returnValue(false)); + } } diff --git a/tests/Alchemy/Tests/Phrasea/Controller/User/PreferencesTest.php b/tests/Alchemy/Tests/Phrasea/Controller/User/PreferencesTest.php index c597a98953..2ddf77a001 100644 --- a/tests/Alchemy/Tests/Phrasea/Controller/User/PreferencesTest.php +++ b/tests/Alchemy/Tests/Phrasea/Controller/User/PreferencesTest.php @@ -11,29 +11,11 @@ class PreferencesTest extends \PhraseanetAuthenticatedWebTestCase */ public function testSaveUserPref() { - self::$DI['app']['authentication']->setUser($this->getMockBuilder('Alchemy\Phrasea\Model\Entities\User') - ->setMethods(['addSetting']) - ->disableOriginalConstructor() - ->getMock()); - - self::$DI['app']['manipulator.user'] = $this->getMockBuilder('Alchemy\Phrasea\Model\Manipulator\User') - ->setMethods(['setUserSetting']) - ->disableOriginalConstructor() - ->getMock(); - - self::$DI['app']['manipulator.user']->expects($this->once()) - ->method('setUserSetting') - ->with($this->isInstanceOf('Alchemy\Phrasea\Model\Entities\User'), $this->equalTo('prop_test'), $this->equalTo('val_test')) - ->will($this->returnValue(null)); - $this->XMLHTTPRequest('POST', '/user/preferences/', ['prop' => 'prop_test', 'value' => 'val_test']); $response = self::$DI['client']->getResponse(); $this->assertTrue($response->isOk()); - $datas = (array) json_decode($response->getContent()); - $this->assertArrayHasKey('success', $datas); - $this->assertTrue($datas['success']); - $this->assertArrayHasKey('message', $datas); - unset($response, $datas); + $this->assertTrue(json_decode($response->getContent())->success); + $this->assertEquals('val_test', self::$DI['app']['settings']->getUserSetting(self::$DI['user'], 'prop_test')); } /** @@ -64,11 +46,8 @@ class PreferencesTest extends \PhraseanetAuthenticatedWebTestCase $this->XMLHTTPRequest('POST', "/user/preferences/temporary/", ['prop' => 'prop_test', 'value' => 'val_test']); $response = self::$DI['client']->getResponse(); $this->assertTrue($response->isOk()); - $datas = (array) json_decode($response->getContent()); - $this->assertArrayHasKey('success', $datas); - $this->assertTrue($datas['success']); + $this->assertTrue(json_decode($response->getContent())->success); $this->assertEquals('val_test', self::$DI['app']['session']->get('phraseanet.prop_test')); - unset($response, $datas); } /** diff --git a/tests/Alchemy/Tests/Phrasea/Core/Configuration/RegistrationManagerTest.php b/tests/Alchemy/Tests/Phrasea/Core/Configuration/RegistrationManagerTest.php new file mode 100644 index 0000000000..6c283cc9dc --- /dev/null +++ b/tests/Alchemy/Tests/Phrasea/Core/Configuration/RegistrationManagerTest.php @@ -0,0 +1,179 @@ +getMockBuilder('\collection') + ->disableOriginalConstructor() + ->getMock(); + + $mockColl->expects($this->once())->method('isRegistrationEnabled')->will($this->returnValue($enabledOnColl)); + + $mockDatabox = $this->getMockBuilder('\databox') + ->disableOriginalConstructor() + ->getMock(); + + $mockAppbox = $this->getMockBuilder('\appbox') + ->disableOriginalConstructor() + ->getMock(); + + $mockColl->expects($this->once())->method('isRegistrationEnabled')->will($this->returnValue(false)); + + $mockDatabox->expects($this->once())->method('get_collections')->will($this->returnValue([$mockColl])); + $mockAppbox->expects($this->once())->method('get_databoxes')->will($this->returnValue([$mockDatabox])); + + $service = new RegistrationManager($mockAppbox, self::$DI['app']['manipulator.registration']->getRepository(), self::$DI['app']['locale']); + $this->assertEquals($expected, $service->isRegistrationEnabled()); + } + + public function getRegistrationProvider() + { + return [ + [false, false], + [true, true], + ]; + } + + /** + * @dataProvider userDataProvider + */ + public function testGetRegistrationSummaryWithUserData($data, $type, $value) + { + $repoMock = $this->getMockBuilder('Alchemy\Phrasea\Model\Repositories\RegistrationRepository') + ->disableOriginalConstructor() + ->setMethods(['getRegistrationsSummaryForUser']) + ->getMock(); + $repoMock->expects($this->once())->method('getRegistrationsSummaryForUser')->will($this->returnValue($data)); + + $service = new RegistrationManager(self::$DI['app']['phraseanet.appbox'], $repoMock, self::$DI['app']['locale']); + + $rs = $service->getRegistrationSummary(self::$DI['user']); + + $databox = current(self::$DI['app']['phraseanet.appbox']->get_databoxes()); + $collection = current($databox->get_collections()); + + $this->assertEquals($value, count($rs[$databox->get_sbas_id()]['registrations']['by-type'][$type])); + } + + public function userDataProvider() + { + $pendingRegistration = new Registration(); + $pendingRegistration->setBaseId(1); + $pendingRegistration->setUser(new User()); + $pendingRegistration->setPending(true); + $pendingRegistration->setRejected(false); + + $rejectedRegistration = new Registration(); + $rejectedRegistration->setBaseId(1); + $rejectedRegistration->setUser(new User()); + $rejectedRegistration->setPending(true); + $rejectedRegistration->setRejected(true); + + $databox = current((new \appbox(new Application()))->get_databoxes()); + $collection = current($databox->get_collections()); + + $noLimitedPendingRegistration = [ + [ + $databox->get_sbas_id() => [ + $collection->get_base_id() => [ + 'base-id' => $collection->get_base_id(), + 'db-name' => 'toto', + 'active' => true, + 'time-limited' => false, + 'in-time' => null, + 'registration' => $pendingRegistration + ] + ] + ], + 'pending', + 1 + ]; + + $rejectedRegistration = [ + [ + $databox->get_sbas_id() => [ + $collection->get_base_id() => [ + 'base-id' => $collection->get_base_id(), + 'db-name' => 'titi', + 'active' => true, + 'time-limited' => false, + 'in-time' => null, + 'registration' => $rejectedRegistration + ] + ] + ], + 'rejected', + 1 + ]; + + $noActiveRegistration = [ + [ + $databox->get_sbas_id() => [ + $collection->get_base_id() => [ + 'base-id' => 1, + 'db-name' => 'tutu', + 'active' => false, + 'time-limited' => false, + 'in-time' => null, + 'registration' => $pendingRegistration + ] + ] + ], + 'inactive', + 1 + ]; + + $limitedActiveIntimePendingRegistration = [ + [ + $databox->get_sbas_id() => [ + $collection->get_base_id() => [ + 'base-id' => $collection->get_base_id(), + 'db-name' => 'tata', + 'active' => true, + 'time-limited' => true, + 'in-time' => true, + 'registration' => $pendingRegistration + ] + ] + ], + 'in-time', + 1 + ]; + + $limitedActiveOutdatedPendingRegistration = [ + [ + $databox->get_sbas_id() => [ + $collection->get_base_id() => [ + 'base-id' => $collection->get_base_id(), + 'db-name' => 'toutou', + 'active' => true, + 'time-limited' => true, + 'in-time' => false, + 'registration' => $pendingRegistration + ] + ] + ], + 'out-time', + 1 + ]; + + return [ + $noLimitedPendingRegistration, + $noActiveRegistration, + $limitedActiveIntimePendingRegistration, + $limitedActiveOutdatedPendingRegistration, + $rejectedRegistration + ]; + } +} diff --git a/tests/Alchemy/Tests/Phrasea/Core/Provider/RegistrationServiceProviderTest.php b/tests/Alchemy/Tests/Phrasea/Core/Provider/RegistrationServiceProviderTest.php index 210dcfae4b..e4af59a54a 100644 --- a/tests/Alchemy/Tests/Phrasea/Core/Provider/RegistrationServiceProviderTest.php +++ b/tests/Alchemy/Tests/Phrasea/Core/Provider/RegistrationServiceProviderTest.php @@ -7,7 +7,7 @@ use Alchemy\Phrasea\Core\Provider\RegistrationServiceProvider; /** * @covers Alchemy\Phrasea\Core\Provider\RegistrationServiceProvider */ -class RegistrationServiceProviderTest extends ServiceProviderTestCase +class RegistrationServiceProviderTest extends ServiceProviderTestCase { private $fields; @@ -37,7 +37,7 @@ class RegistrationServiceProviderTest extends ServiceProviderTestCase public function provideServiceDescription() { return [ - ['Alchemy\Phrasea\Core\Provider\RegistrationServiceProvider', 'registration.manager', 'Alchemy\Phrasea\Registration\RegistrationManager'], + ['Alchemy\Phrasea\Core\Provider\RegistrationServiceProvider', 'registration.manager', 'Alchemy\Phrasea\Core\Configuration\RegistrationManager'], ]; } } diff --git a/tests/Alchemy/Tests/Phrasea/Model/Manipulator/RegistrationManipulatorTest.php b/tests/Alchemy/Tests/Phrasea/Model/Manipulator/RegistrationManipulatorTest.php index b763b297df..f1f58d57f4 100644 --- a/tests/Alchemy/Tests/Phrasea/Model/Manipulator/RegistrationManipulatorTest.php +++ b/tests/Alchemy/Tests/Phrasea/Model/Manipulator/RegistrationManipulatorTest.php @@ -2,7 +2,6 @@ namespace Alchemy\Tests\Phrasea\Registration; -use Alchemy\Phrasea\Application; use Alchemy\Phrasea\Model\Entities\Registration; use Alchemy\Phrasea\Model\Manipulator\RegistrationManipulator; @@ -10,51 +9,30 @@ class RegistrationManipulatorTest extends \PhraseanetTestCase { public function testCreateRegistration() { - $em = $this->getMockBuilder('Doctrine\ORM\EntityManager') - ->disableOriginalConstructor() - ->getMock(); - $em->expects($this->once())->method('persist')->with($this->isInstanceOf('Alchemy\Phrasea\Model\Entities\Registration')); - $em->expects($this->once())->method('flush'); - - $service = new RegistrationManipulator($em, self::$DI['app']['phraseanet.appbox'], self::$DI['app']['acl']); - - $registration = $service->createRegistration(self::$DI['user']->get_id(), self::$DI['collection']->get_base_id()); + $service = new RegistrationManipulator(self::$DI['app'], self::$DI['app']['EM'], self::$DI['app']['acl'], self::$DI['app']['phraseanet.appbox']); + $registration = $service->createRegistration(self::$DI['user'], self::$DI['collection']); $this->assertInstanceOf('Alchemy\Phrasea\Model\Entities\Registration', $registration); $this->assertEquals(self::$DI['collection']->get_base_id(), $registration->getBaseId()); - $this->assertEquals(self::$DI['user']->get_id(), $registration->getUser()); - - return $registration; + $this->assertEquals(self::$DI['user']->getId(), $registration->getUser()->getId()); } - /** - * @depends testCreateRegistration - */ - public function testRejectRegistration($registration) + public function testRejectRegistration() { - $em = $this->getMockBuilder('Doctrine\ORM\EntityManager') - ->disableOriginalConstructor() - ->getMock(); - $em->expects($this->once())->method('persist')->with($this->isInstanceOf('Alchemy\Phrasea\Model\Entities\Registration')); - $em->expects($this->once())->method('flush'); - - $service = new RegistrationManipulator($em, self::$DI['app']['phraseanet.appbox'], self::$DI['app']['acl']); + $registration = self::$DI['registration_1']; + $service = new RegistrationManipulator(self::$DI['app'], self::$DI['app']['EM'], self::$DI['app']['acl'], self::$DI['app']['phraseanet.appbox']); $service->rejectRegistration($registration); + $this->assertFalse($registration->isPending()); $this->assertTrue($registration->isRejected()); - - return $registration; } - /** - * @depends testCreateRegistration - */ - public function testAcceptRegistration($registration) + public function testAcceptRegistration() { - $aclMock = $this->getMockBuilder('ACL') - ->disableOriginalConstructor() - ->getMock(); + $registration = self::$DI['registration_1']; + + $aclMock = $this->getMockBuilder('ACL')->disableOriginalConstructor()->getMock(); $aclMock->expects($this->once())->method('give_access_to_sbas')->with($this->equalTo([self::$DI['collection']->get_sbas_id()])); $aclMock->expects($this->once())->method('give_access_to_base')->with($this->equalTo([self::$DI['collection']->get_base_id()])); $aclMock->expects($this->once())->method('update_rights_to_base')->with($this->equalTo(self::$DI['collection']->get_base_id()), $this->equalTo([ @@ -64,41 +42,35 @@ class RegistrationManipulatorTest extends \PhraseanetTestCase 'candwnldpreview' => '1', 'actif' => '1', ])); - $aclProviderMock = $this->getMockBuilder('Alchemy\Phrasea\Authentication\ACLProvider') - ->disableOriginalConstructor() - ->getMock(); - $aclProviderMock->expects($this->any())->method('get')->with($this->equalTo(self::$DI['user']))->will($this->returnvalue($aclMock)); - $em = $this->getMockBuilder('Doctrine\ORM\EntityManager') - ->disableOriginalConstructor() - ->getMock(); - $em->expects($this->once())->method('remove')->with($this->isInstanceOf('Alchemy\Phrasea\Model\Entities\Registration')); - $em->expects($this->once())->method('flush'); - $service = new RegistrationManipulator($em, self::$DI['app']['phraseanet.appbox'], $aclProviderMock); - $service->acceptRegistration($registration, self::$DI['user'], self::$DI['collection'], true, false); + $aclProviderMock = $this->getMockBuilder('Alchemy\Phrasea\Authentication\ACLProvider')->disableOriginalConstructor()->getMock(); + $aclProviderMock->expects($this->any())->method('get')->with($this->isInstanceOf('Alchemy\Phrasea\Model\Entities\User'))->will($this->returnvalue($aclMock)); + + self::$DI['app']['acl'] = $aclProviderMock; + + $service = new RegistrationManipulator(self::$DI['app'], self::$DI['app']['EM'], self::$DI['app']['acl'], self::$DI['app']['phraseanet.appbox']); + $service->acceptRegistration($registration, true, false); } public function testDeleteRegistrationForUser() { - $service = new RegistrationManipulator(self::$DI['app']['EM'], self::$DI['app']['phraseanet.appbox'], self::$DI['app']['acl']); + $service = new RegistrationManipulator(self::$DI['app'], self::$DI['app']['EM'], self::$DI['app']['acl'], self::$DI['app']['phraseanet.appbox']); $qb = $service->getRepository()->createQueryBuilder('r'); $nbRegistrationBefore = $qb->select('COUNT(r)') ->where($qb->expr()->eq('r.user', ':user')) - ->setParameter(':user', self::$DI['user_alt1']->get_id()) + ->setParameter(':user', self::$DI['user_alt1']->getId()) ->getQuery() ->getSingleScalarResult(); - $service->deleteRegistrationsForUser(self::$DI['user_alt1']->get_id(), [self::$DI['collection']->get_base_id()]); + $service->deleteUserRegistrations(self::$DI['user_alt1'], [self::$DI['collection']]); $nbRegistrationAfter = $qb->getQuery()->getSingleScalarResult(); $this->assertGreaterThan($nbRegistrationAfter, $nbRegistrationBefore); } public function testDeleteOldRegistrations() { - $service = new RegistrationManipulator(self::$DI['app']['EM'], self::$DI['app']['phraseanet.appbox'], self::$DI['app']['acl']); + $service = new RegistrationManipulator(self::$DI['app'], self::$DI['app']['EM'], self::$DI['app']['acl'], self::$DI['app']['phraseanet.appbox']); $qb = $service->getRepository()->createQueryBuilder('r'); - $nbRegistrationBefore = $qb->select('COUNT(r)') - ->getQuery() - ->getSingleScalarResult(); + $nbRegistrationBefore = $qb->select('COUNT(r)')->getQuery()->getSingleScalarResult(); $service->deleteOldRegistrations(); $nbRegistrationAfter = $qb->getQuery()->getSingleScalarResult(); $this->assertGreaterThan($nbRegistrationAfter, $nbRegistrationBefore); @@ -106,151 +78,11 @@ class RegistrationManipulatorTest extends \PhraseanetTestCase public function testDeleteRegistrationOnCollection() { - $service = new RegistrationManipulator(self::$DI['app']['EM'], self::$DI['app']['phraseanet.appbox'], self::$DI['app']['acl']); + $service = new RegistrationManipulator(self::$DI['app'], self::$DI['app']['EM'], self::$DI['app']['acl'], self::$DI['app']['phraseanet.appbox']); $qb = $service->getRepository()->createQueryBuilder('r'); - $nbRegistrationBefore = $qb->select('COUNT(r)') - ->getQuery() - ->getSingleScalarResult(); - $service->deleteRegistrationsOnCollection(self::$DI['collection']->get_base_id()); + $nbRegistrationBefore = $qb->select('COUNT(r)')->getQuery()->getSingleScalarResult(); + $service->deleteRegistrationsOnCollection(self::$DI['collection']); $nbRegistrationAfter = $qb->getQuery()->getSingleScalarResult(); $this->assertGreaterThan($nbRegistrationAfter, $nbRegistrationBefore); } - - /** - * @dataProvider userDataProvider - */ - public function testGetRegistrationSummaryWithUserData($data, $type, $value) - { - $repoMock = $this->getMockBuilder('Alchemy\Phrasea\Model\Repositories\RegistrationRepository') - ->disableOriginalConstructor() - ->setMethods(['getRegistrationsSummaryForUser']) - ->getMock(); - $repoMock->expects($this->once())->method('getRegistrationsSummaryForUser')->will($this->returnValue($data)); - $em = $this->getMockBuilder('Doctrine\ORM\EntityManager') - ->disableOriginalConstructor() - ->getMock(); - $em->expects($this->once())->method('getRepository')->will($this->returnValue($repoMock)); - - $service = new RegistrationManipulator($em, self::$DI['app']['phraseanet.appbox'], self::$DI['app']['acl']); - - $rs = $service->getRegistrationSummary(4); - - $databox = current(self::$DI['app']['phraseanet.appbox']->get_databoxes()); - $collection = current($databox->get_collections()); - - $this->assertEquals($value, count($rs[$databox->get_sbas_id()]['registrations']['by-type'][$type])); - $this->assertNotNull($rs[$databox->get_sbas_id()]['registrations']['by-collection'][$collection->get_base_id()]); - } - - public function userDataProvider() - { - $pendingRegistration = new Registration(); - $pendingRegistration->setBaseId(1); - $pendingRegistration->setUser(3); - $pendingRegistration->setPending(true); - $pendingRegistration->setRejected(false); - - $rejectedRegistration = new Registration(); - $rejectedRegistration->setBaseId(1); - $rejectedRegistration->setUser(3); - $rejectedRegistration->setPending(true); - $rejectedRegistration->setRejected(true); - - $databox = current((new \appbox(new Application()))->get_databoxes()); - $collection = current($databox->get_collections()); - - $noLimitedPendingRegistration = [ - [ - $databox->get_sbas_id() => [ - $collection->get_base_id() => [ - 'base-id' => $collection->get_base_id(), - 'db-name' => 'toto', - 'active' => true, - 'time-limited' => false, - 'in-time' => null, - 'registration' => $pendingRegistration - ] - ] - ], - 'pending', - 1 - ]; - - - $rejectedRegistration = [ - [ - $databox->get_sbas_id() => [ - $collection->get_base_id() => [ - 'base-id' => $collection->get_base_id(), - 'db-name' => 'titi', - 'active' => true, - 'time-limited' => false, - 'in-time' => null, - 'registration' => $rejectedRegistration - ] - ] - ], - 'rejected', - 1 - ]; - - $noActiveRegistration = [ - [ - $databox->get_sbas_id() => [ - $collection->get_base_id() => [ - 'base-id' => 1, - 'db-name' => 'tutu', - 'active' => false, - 'time-limited' => false, - 'in-time' => null, - 'registration' => $pendingRegistration - ] - ] - ], - 'inactive', - 1 - ]; - - $limitedActiveIntimePendingRegistration = [ - [ - $databox->get_sbas_id() => [ - $collection->get_base_id() => [ - 'base-id' => $collection->get_base_id(), - 'db-name' => 'tata', - 'active' => true, - 'time-limited' => true, - 'in-time' => true, - 'registration' => $pendingRegistration - ] - ] - ], - 'in-time', - 1 - ]; - - $limitedActiveOutdatedPendingRegistration = [ - [ - $databox->get_sbas_id() => [ - $collection->get_base_id() => [ - 'base-id' => $collection->get_base_id(), - 'db-name' => 'toutou', - 'active' => true, - 'time-limited' => true, - 'in-time' => false, - 'registration' => $pendingRegistration - ] - ] - ], - 'out-time', - 1 - ]; - - return [ - $noLimitedPendingRegistration, - $noActiveRegistration, - $limitedActiveIntimePendingRegistration, - $limitedActiveOutdatedPendingRegistration, - $rejectedRegistration - ]; - } } diff --git a/tests/Alchemy/Tests/Phrasea/Model/Repositories/FeedItemRepositoryTest.php b/tests/Alchemy/Tests/Phrasea/Model/Repositories/FeedItemRepositoryTest.php index 536bd67053..d44850ede8 100644 --- a/tests/Alchemy/Tests/Phrasea/Model/Repositories/FeedItemRepositoryTest.php +++ b/tests/Alchemy/Tests/Phrasea/Model/Repositories/FeedItemRepositoryTest.php @@ -53,14 +53,14 @@ class FeedItemRepositoryTest extends \PhraseanetTestCase $item = new FeedItem(); $item->setEntry($entry) ->setOrd(4) - ->setRecordId(self::$DI['record_1']->get_record_id()) - ->setSbasId(self::$DI['record_1']->get_record_id()); + ->setRecordId(123456789) + ->setSbasId(123456789); $entry->addItem($item); self::$DI['app']['EM']->persist($item); self::$DI['app']['EM']->persist($entry); self::$DI['app']['EM']->flush(); - $this->assertCount(4, self::$DI['app']['EM']->getRepository('Phraseanet:FeedItem')->loadLatest(self::$DI['app'], 20)); + $this->assertCount(3, self::$DI['app']['EM']->getRepository('Phraseanet:FeedItem')->loadLatest(self::$DI['app'], 20)); } } diff --git a/tests/Alchemy/Tests/Phrasea/Registration/RegistrationManagerTest.php b/tests/Alchemy/Tests/Phrasea/Registration/RegistrationManagerTest.php deleted file mode 100644 index 5f384edb33..0000000000 --- a/tests/Alchemy/Tests/Phrasea/Registration/RegistrationManagerTest.php +++ /dev/null @@ -1,44 +0,0 @@ -getMockBuilder('\collection') - ->disableOriginalConstructor() - ->getMock(); - - $mockColl->expects($this->once())->method('isRegistrationEnabled')->will($this->returnValue($enabledOnColl)); - - $mockDatabox = $this->getMockBuilder('\databox') - ->disableOriginalConstructor() - ->getMock(); - - $mockAppbox = $this->getMockBuilder('\appbox') - ->disableOriginalConstructor() - ->getMock(); - - $mockColl->expects($this->once())->method('isRegistrationEnabled')->will($this->returnValue(false)); - - $mockDatabox->expects($this->once())->method('get_collections')->will($this->returnValue([$mockColl])); - $mockAppbox->expects($this->once())->method('get_databoxes')->will($this->returnValue([$mockDatabox])); - - $service = new RegistrationManager($mockAppbox); - $this->assertEquals($expected, $service->isRegistrationEnabled()); - } - - public function getRegistrationProvider() - { - return [ - [false, false], - [true, true], - ]; - } -} \ No newline at end of file diff --git a/tests/classes/PhraseanetTestCase.php b/tests/classes/PhraseanetTestCase.php index 96e1b33866..a1118b3a2f 100644 --- a/tests/classes/PhraseanetTestCase.php +++ b/tests/classes/PhraseanetTestCase.php @@ -133,6 +133,16 @@ abstract class PhraseanetTestCase extends WebTestCase return $DI['app']['manipulator.user']->getRepository()->find(self::$fixtureIds['user']['user_template']); }); + self::$DI['registration_1'] = self::$DI->share(function ($DI) { + return $DI['app']['manipulator.registration']->getRepository()->find(self::$fixtureIds['registrations']['registration_1']); + }); + self::$DI['registration_2'] = self::$DI->share(function ($DI) { + return $DI['app']['manipulator.registration']->getRepository()->find(self::$fixtureIds['registrations']['registration_2']); + }); + self::$DI['registration_3'] = self::$DI->share(function ($DI) { + return $DI['app']['manipulator.registration']->getRepository()->find(self::$fixtureIds['registrations']['registration_3']); + }); + self::$DI['oauth2-app-user'] = self::$DI->share(function ($DI) { return new \API_OAuth2_Application($DI['app'], self::$fixtureIds['oauth']['user']); }); diff --git a/www/skins/admin/css/Main.css b/www/skins/admin/css/Main.css index e9ebbb5070..06db995351 100644 --- a/www/skins/admin/css/Main.css +++ b/www/skins/admin/css/Main.css @@ -284,12 +284,12 @@ div.switch_right.unchecked { line-height: 22px; } -#tab_demandes .dl-horizontal dd { +#tab-registrations .dl-horizontal dd { word-break: break-all; margin-left: 140px; } -#tab_demandes .dl-horizontal dt { +#tab-registrations .dl-horizontal dt { width: 130px; }