From 2ec4ffdbcc6e9f7708082f80133db05695de8938 Mon Sep 17 00:00:00 2001 From: Nicolas Le Goff Date: Thu, 6 Feb 2014 12:42:47 +0100 Subject: [PATCH] Refactor && Typo && Use plain objects as function parameters instead of ids --- .../Command/Developer/RegenerateSqliteDb.php | 19 +- .../Phrasea/Controller/Admin/Users.php | 164 ++++++------- .../Phrasea/Controller/Prod/Lazaret.php | 4 +- .../Phrasea/Controller/Root/Account.php | 14 +- lib/Alchemy/Phrasea/Controller/Root/Login.php | 26 +-- .../Configuration/RegistrationManager.php | 204 ++++++++++++++++ .../Provider/ManipulatorServiceProvider.php | 2 +- .../Provider/RegistrationServiceProvider.php | 4 +- lib/Alchemy/Phrasea/Core/Version.php | 2 +- .../Form/Login/PhraseaRegisterForm.php | 7 +- .../Phrasea/Model/Entities/Registration.php | 42 +++- .../Manipulator/RegistrationManipulator.php | 167 +++---------- .../Phrasea/Model/NativeQueryProvider.php | 2 +- .../Repositories/RegistrationRepository.php | 21 +- .../Registration/RegistrationManager.php | 40 ---- ...igration.php => RegistrationMigration.php} | 3 +- lib/classes/API/V1/adapter.php | 2 +- lib/classes/collection.php | 34 +-- lib/classes/databox/cgu.php | 2 +- lib/classes/eventsmanager/notify/register.php | 9 +- lib/classes/patch/390alpha13a.php | 122 ++++++++++ lib/classes/record/preview.php | 2 +- lib/conf.d/migrations.yml | 4 +- templates/web/account/access.html.twig | 2 +- templates/web/admin/tree.html.twig | 2 +- ...mand.html.twig => registrations.html.twig} | 16 +- .../Phrasea/Controller/Admin/UsersTest.php | 10 +- .../Phrasea/Controller/Prod/UploadTest.php | 2 +- .../Phrasea/Controller/Prod/UsrListsTest.php | 2 +- .../Phrasea/Controller/Root/AccountTest.php | 10 +- .../Phrasea/Controller/Root/LoginTest.php | 167 ++++++++----- .../Controller/User/PreferencesTest.php | 27 +-- .../Configuration/RegistrationManagerTest.php | 179 ++++++++++++++ .../RegistrationServiceProviderTest.php | 4 +- .../RegistrationManipulatorTest.php | 220 +++--------------- .../Repositories/FeedItemRepositoryTest.php | 6 +- .../Registration/RegistrationManagerTest.php | 44 ---- tests/classes/PhraseanetTestCase.php | 10 + www/skins/admin/css/Main.css | 4 +- 39 files changed, 909 insertions(+), 692 deletions(-) create mode 100644 lib/Alchemy/Phrasea/Core/Configuration/RegistrationManager.php delete mode 100644 lib/Alchemy/Phrasea/Registration/RegistrationManager.php rename lib/Alchemy/Phrasea/Setup/DoctrineMigrations/{RegistrationDemandMigration.php => RegistrationMigration.php} (75%) create mode 100644 lib/classes/patch/390alpha13a.php rename templates/web/admin/user/{demand.html.twig => registrations.html.twig} (96%) create mode 100644 tests/Alchemy/Tests/Phrasea/Core/Configuration/RegistrationManagerTest.php delete mode 100644 tests/Alchemy/Tests/Phrasea/Registration/RegistrationManagerTest.php diff --git a/lib/Alchemy/Phrasea/Command/Developer/RegenerateSqliteDb.php b/lib/Alchemy/Phrasea/Command/Developer/RegenerateSqliteDb.php index 3e53c2aa7a..ef581d48d1 100644 --- a/lib/Alchemy/Phrasea/Command/Developer/RegenerateSqliteDb.php +++ b/lib/Alchemy/Phrasea/Command/Developer/RegenerateSqliteDb.php @@ -96,10 +96,9 @@ 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']); - + $this->insertOneRegistration($DI, $this->container['EM'], $DI['user_alt1'], $DI['coll'], 'now', 'registration_1'); + $this->insertOneRegistration($DI, $this->container['EM'], $DI['user_alt2'], $DI['coll'], '-3 months', 'registration_2'); + $this->insertOneRegistration($DI, $this->container['EM'], $DI['user_notAdmin'], $DI['coll'], 'now', 'registration_3'); $fixtures['user']['test_phpunit'] = $DI['user']->getId(); $fixtures['user']['test_phpunit_not_admin'] = $DI['user_notAdmin']->getId(); @@ -127,6 +126,10 @@ class RegenerateSqliteDb extends Command $fixtures['record']['record_6'] = $DI['record_6']->get_record_id(); $fixtures['record']['record_7'] = $DI['record_7']->get_record_id(); + $fixtures['registrations']['registration_1'] = $DI['registration_1']->getId(); + $fixtures['registrations']['registration_2'] = $DI['registration_2']->getId(); + $fixtures['registrations']['registration_3'] = $DI['registration_3']->getId(); + $fixtures['lazaret']['lazaret_1'] = $DI['lazaret_1']->getId(); $fixtures['user']['user_1'] = $DI['user_1']->getId(); @@ -644,16 +647,18 @@ class RegenerateSqliteDb extends Command $em->persist($entry); } - private function insertOneRegistration(EntityManager $em, \User_Adapter $user, \collection $collection, $when = 'now') + private function insertOneRegistration(\Pimple $DI, EntityManager $em, User $user, \collection $collection, $when, $name) { $em->getEventManager()->removeEventSubscriber(new TimestampableListener()); $registration = new Registration(); - $registration->setBaseId($collection->get_base_id()); - $registration->setUser($user->get_id()); + $registration->setCollection($collection); + $registration->setUser($user); $registration->setUpdated(new \DateTime($when)); $registration->setCreated(new \DateTime($when)); $em->persist($registration); $em->flush(); $em->getEventManager()->addEventSubscriber(new TimestampableListener()); + + $DI[$name] = $registration; } } diff --git a/lib/Alchemy/Phrasea/Controller/Admin/Users.php b/lib/Alchemy/Phrasea/Controller/Admin/Users.php index 3a80425eac..73be535de7 100644 --- a/lib/Alchemy/Phrasea/Controller/Admin/Users.php +++ b/lib/Alchemy/Phrasea/Controller/Admin/Users.php @@ -14,7 +14,6 @@ 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,42 +353,39 @@ class Users implements ControllerProviderInterface return $response; })->bind('admin_users_export_csv'); - $controllers->get('/demands/', function (Application $app) { + $controllers->get('/registrations/', function (Application $app) { $app['manipulator.registration']->deleteOldRegistrations(); $models = $app['manipulator.user']->getRepository()->findModelOf($app['authentication']->getUser()); - $users = $registrations = []; - foreach ($app['manipulator.registration']->getRepository()->getDemandsForUser( - $app['authentication']->getUser(), - array_keys($app['acl']->get($app['authentication']->getUser())->get_granted_base(['canadmin'])) + $userRegistrations = []; + foreach ($app['manipulator.registration']->getRepository()->getUserRegistrations( + $app['authentication']->getUser(), + $app['acl']->get($app['authentication']->getUser())->get_granted_base(['canadmin']) ) as $registration) { $user = $registration->getUser(); - $users[$user->getId()] = $user; - - - if (null !== igorw::get_in($registrations, [$user->getId(), $registration->getBaseId()])) { - $registrations[$user->getId()][$registration->getBaseId()] = $registration; - } + $userRegistrations[$user->getId()]['user'] = $user; + $userRegistrations[$user->getId()]['registrations'][$registration->getBaseid()] = $registration; } - return $app['twig']->render('admin/user/demand.html.twig', [ - 'users' => $users, - 'registrations' => $registrations, + return $app['twig']->render('admin/user/registrations.html.twig', [ + 'user_registrations' => $userRegistrations, 'models' => $models, ]); - })->bind('users_display_demands'); + })->bind('users_display_registrations'); - $controllers->post('/demands/', function (Application $app, Request $request) { + $controllers->post('/registrations/', function (Application $app, Request $request) { $templates = $deny = $accept = $options = []; foreach ($request->request->get('template', []) as $tmp) { - if (trim($tmp) != '') { - $tmp = explode('_', $tmp); + if ('' === trim($tmp)) { + continue; + } - if (count($tmp) == 2) { - $templates[$tmp[0]] = $tmp[1]; - } + $tmp = explode('_', $tmp); + + if (count($tmp) == 2) { + $templates[$tmp[0]] = $tmp[1]; } } @@ -423,92 +419,102 @@ class Users implements ControllerProviderInterface } if (count($templates) > 0 || count($deny) > 0 || count($accept) > 0) { - $done = []; - $cache_to_update = []; + $cacheToUpdate = $done = []; foreach ($templates as $usr => $template_id) { - $user = $app['manipulator.user']->getRepository()->find($usr); - $cache_to_update[$usr] = true; + if (null === $user = $app['manipulator.user']->getRepository()->find($usr)) { + $app->abort(400, srpintf("User with id % in provided in 'template' request variable could not be found", $usr)); + } + $cacheToUpdate[$usr] = $user; $user_template = $app['manipulator.user']->getRepository()->find($template_id); - $base_ids = array_keys($app['acl']->get($user_template)->get_granted_base()); + $collections = $app['acl']->get($user_template)->get_granted_base(); + $baseIds = array_keys($collections); - $app['acl']->get($user)->apply_model($user_template, $base_ids); + $app['acl']->get($user)->apply_model($user_template, $baseIds); - foreach ($base_ids as $base_id) { - $done[$usr][$base_id] = true; + foreach ($collections as $collection) { + $done[$usr][$collection->get_base_id()] = true; } - $app['manipulator.registration']->deleteRegistrationsForUser($user->get_id(), $base_ids); + $app['manipulator.registration']->deleteUserRegistrations($user, $collections); } foreach ($deny as $usr => $bases) { - $cache_to_update[$usr] = true; - foreach ($bases as $bas) { - if (null !== $registration = $app['manipulator.registration']->getRepository()->findOneBy([ - 'user' => $usr, - 'baseId' => $bas - ])) { - $app['manipulator.registration']->rejectDemand($registration); - $done[$usr][$bas] = false; - } + if (null === $user = $app['manipulator.user']->getRepository()->find($usr)) { + $app->abort(400, srpintf("User with id % in provided in 'deny' request variable could not be found", $usr)); + } + $cacheToUpdate[$usr] = $user; + foreach ($app['manipulator.registration']->getRepository()->getUserRegistrations( + $user, + array_map(function ($baseId) use ($app) { + return \collection::get_from_base_id($app, $baseId); + }, $bases) + ) as $registration) { + $app['manipulator.registration']->rejectRegistration($registration); + $done[$usr][$registration->getBaseId()] = false; } } foreach ($accept as $usr => $bases) { - $user = $app['manipulator.user']->getRepository()->find($usr); - $cache_to_update[$usr] = true; - - foreach ($bases as $bas) { - $collection = \collection::get_from_base_id($app, $bas); - if (null !== $registration = $app['manipulator.registration']->getRepository()->findOneBy([ - 'user' => $user->get_id(), - 'baseId' => $collection->get_base_id() - ])) { - $done[$usr][$bas] = true; - $app['manipulator.registration']->acceptRegistration($registration, $user, $collection, $options[$usr][$bas]['HD'], $options[$usr][$bas]['WM']); - } + if (null === $user = $app['manipulator.user']->getRepository()->find($usr)) { + $app->abort(400, srpintf("User with id % in provided in 'accept' request variable could not be found", $usr)); + } + $cacheToUpdate[$usr] = $user; + foreach ($app['manipulator.registration']->getRepository()->getUserRegistrations( + $user, + array_map(function ($baseId) use ($app) { + return \collection::get_from_base_id($app, $baseId); + }, $bases) + ) as $registration) { + $done[$usr][$registration->getBaseId()] = true; + $app['manipulator.registration']->acceptRegistration( + $registration, + $options[$usr][$registration->getBaseId()]['HD'], + $options[$usr][$registration->getBaseId()]['WM'] + ); } } - foreach (array_keys($cache_to_update) as $usr_id) { - $user = $app['manipulator.user']->getRepository()->find($usr_id); + array_walk($cacheToUpdate, function (User $user) use ($app) { $app['acl']->get($user)->delete_data_from_cache(); - unset($user); - } + }); + unset ($cacheToUpdate); foreach ($done as $usr => $bases) { + $user = $app['manipulator.user']->getRepository()->find($usr); $acceptColl = $denyColl = []; - if (null !== $user = $app['manipulator.user']->getRepository()->find($usr)) { - if (\Swift_Validate::email($user->getEmail())) { - foreach ($bases as $bas => $isok) { - if ($isok) { - $acceptColl[] = \phrasea::bas_labels($bas, $app); - } else { - $denyColl[] = \phrasea::bas_labels($bas, $app); - } - } - if (0 !== count($acceptColl) || 0 !== count($denyColl)) { - $message = ''; - if (0 !== count($acceptColl)) { - $message .= "\n" . $app->trans('login::register:email: Vous avez ete accepte sur les collections suivantes : ') . implode(', ', $acceptColl). "\n"; - } - if (0 !== count($denyColl)) { - $message .= "\n" . $app->trans('login::register:email: Vous avez ete refuse sur les collections suivantes : ') . implode(', ', $denyColl) . "\n"; - } - $receiver = new Receiver(null, $user->getEmail()); - $mail = MailSuccessEmailUpdate::create($app, $receiver, null, $message); + foreach ($bases as $bas => $isok) { + $collection = \collection::get_from_base_id($app, $bas); - $app['notification.deliverer']->deliver($mail); - } + if ($isok) { + $acceptColl[] = $collection->get_label($app['locale']); + continue; } + + $denyColl[] = $collection->get_label($app['locale']); + } + + if (0 !== count($acceptColl) || 0 !== count($denyColl)) { + $message = ''; + if (0 !== count($acceptColl)) { + $message .= "\n" . $app->trans('login::register:email: Vous avez ete accepte sur les collections suivantes : ') . implode(', ', $acceptColl). "\n"; + } + if (0 !== count($denyColl)) { + $message .= "\n" . $app->trans('login::register:email: Vous avez ete refuse sur les collections suivantes : ') . implode(', ', $denyColl) . "\n"; + } + + $receiver = new Receiver(null, $user->getEmail()); + $mail = MailSuccessEmailUpdate::create($app, $receiver, null, $message); + + $app['notification.deliverer']->deliver($mail); } } } - return $app->redirectPath('users_display_demands', ['success' => 1]); - })->bind('users_submit_demands'); + return $app->redirectPath('users_display_registrations', ['success' => 1]); + })->bind('users_submit_registrations'); $controllers->get('/import/file/', function (Application $app, Request $request) { return $app['twig']->render('admin/user/import/file.html.twig'); diff --git a/lib/Alchemy/Phrasea/Controller/Prod/Lazaret.php b/lib/Alchemy/Phrasea/Controller/Prod/Lazaret.php index 59cacb7e90..915ed0e40c 100644 --- a/lib/Alchemy/Phrasea/Controller/Prod/Lazaret.php +++ b/lib/Alchemy/Phrasea/Controller/Prod/Lazaret.php @@ -92,11 +92,11 @@ class Lazaret implements ControllerProviderInterface $lazaretFiles = $lazaretRepository->findPerPage($baseIds, $offset, $perPage); } - return $app['twig']->render('prod/upload/lazaret.html.twig', array( + return $app['twig']->render('prod/upload/lazaret.html.twig', [ 'lazaretFiles' => $lazaretFiles, 'currentPage' => $page, 'perPage' => $perPage, - )); + ]); } /** diff --git a/lib/Alchemy/Phrasea/Controller/Root/Account.php b/lib/Alchemy/Phrasea/Controller/Root/Account.php index 48bfd491a0..9135575be3 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['manipulator.registration']->getRegistrationSummary($app['authentication']->getUser()->getId()) + 'inscriptions' => $app['registration.manager']->getRegistrationSummary($app['authentication']->getUser()) ]); } @@ -326,13 +326,13 @@ class Account implements ControllerProviderInterface */ public function updateAccount(PhraseaApplication $app, Request $request) { - $demands = $request->request->get('demand'); - if (false === is_array($demands)) { - $app->abort(400, '"demand" parameter must be an array of base id '); + $registrations = $request->request->get('registrations'); + if (false === is_array($registrations)) { + $app->abort(400, '"registrations" parameter must be an array of base ids.'); } - if (0 !== count($demands)) { - foreach ($demands as $baseId) { - $app['registration-manager']->createRegistration($app['authentication']->getUser()->get_id(), $baseId); + if (0 !== count($registrations)) { + foreach ($registrations as $baseId) { + $app['manipulator.registration']->createRegistration($app['authentication']->getUser(), \collection::get_from_base_id($app, $baseId)); } $app->addFlash('success', $app->trans('Your registration requests have been taken into account.')); } diff --git a/lib/Alchemy/Phrasea/Controller/Root/Login.php b/lib/Alchemy/Phrasea/Controller/Root/Login.php index 85a00ce92a..9969c2ffc8 100644 --- a/lib/Alchemy/Phrasea/Controller/Root/Login.php +++ b/lib/Alchemy/Phrasea/Controller/Root/Login.php @@ -267,7 +267,7 @@ class Login implements ControllerProviderInterface public function doRegistration(PhraseaApplication $app, Request $request) { - if (! $app['registration.manager']->isRegistrationEnabled()) { + if (!$app['registration.manager']->isRegistrationEnabled()) { $app->abort(404, 'Registration is disabled'); } @@ -335,7 +335,7 @@ class Login implements ControllerProviderInterface } else { $selected = isset($data['collections']) ? $data['collections'] : null; } - $inscriptions = $app['manipulator.registration']->getRegistrationSummary(); + $inscriptions = $app['registration.manager']->getRegistrationSummary(); $inscOK = []; foreach ($app['phraseanet.appbox']->get_databoxes() as $databox) { @@ -385,33 +385,25 @@ class Login implements ControllerProviderInterface $app['EM']->flush(); } - $demandOK = []; - + $registrationsOK = []; if ($app['conf']->get(['registry', 'registration', 'auto-register-enabled'])) { $template_user = $app['manipulator.user']->getRepository()->findByLogin(User::USER_AUTOREGISTER); - - $base_ids = []; - - foreach (array_keys($inscOK) as $base_id) { - $base_ids[] = $base_id; - } - - $app['acl']->get($user)->apply_model($template_user, $base_ids); + $app['acl']->get($user)->apply_model($template_user, array_keys($inscOK)); } $autoReg = $app['acl']->get($user)->get_granted_base(); - foreach ($inscOK as $base_id => $autorisation) { - if (false === $autorisation || $app['acl']->get($user)->has_access_to_base($base_id)) { + foreach ($inscOK as $baseId => $authorization) { + if (false === $authorization || $app['acl']->get($user)->has_access_to_base($baseId)) { continue; } - $app['manipulator.registration']->createRegistration($user->getId(), $base_id); - $demandOK[$base_id] = true; + $app['manipulator.registration']->createRegistration($user, \collection::get_from_base_id($app, $baseId)); + $registrationsOK[$baseId] = true; } $params = [ - 'demand' => $demandOK, + 'registrations'=> $registrationsOK, 'autoregister' => $autoReg, 'usr_id' => $user->getId() ]; diff --git a/lib/Alchemy/Phrasea/Core/Configuration/RegistrationManager.php b/lib/Alchemy/Phrasea/Core/Configuration/RegistrationManager.php new file mode 100644 index 0000000000..992b090644 --- /dev/null +++ b/lib/Alchemy/Phrasea/Core/Configuration/RegistrationManager.php @@ -0,0 +1,204 @@ +appbox = $appbox; + $this->repository = $repository; + $this->locale = $locale; + } + + /** + * Tells whether registration is enabled or not. + * + * @return boolean + */ + public function isRegistrationEnabled() + { + foreach ($this->appbox->get_databoxes() as $databox) { + foreach ($databox->get_collections() as $collection) { + if ($collection->isRegistrationEnabled()) { + return true; + } + } + } + + return false; + } + + /** + * Gets information about registration configuration and registration status if a user id is provided. + * + * @param null|user $user + * + * @return array + */ + public function getRegistrationSummary(User $user = null) + { + $data = $userData = []; + + // Gets user data + if (null !== $user) { + $userData = $this->repository->getRegistrationsSummaryForUser($user); + } + + foreach ($this->appbox->get_databoxes() as $databox) { + $data[$databox->get_sbas_id()] = [ + // Registrations on databox by type + 'registrations' => [ + 'by-type' => [ + 'inactive' => [], + 'accepted' => [], + 'in-time' => [], + 'out-dated' => [], + 'pending' => [], + 'rejected' => [], + ] + ], + // Registration configuration on databox and collections that belong to the databox + 'config' => [ + 'db-name' => $databox->get_dbname(), + 'cgu' => $databox->get_cgus(), + 'can-register' => $databox->isRegistrationEnabled(), + // Configuration on collection + 'collections' => [], + ] + ]; + + foreach ($databox->get_collections() as $collection) { + // Sets collection info + $data[$databox->get_sbas_id()]['config']['collections'][$collection->get_base_id()] = $this->getCollectionSummary($collection, $userData); + // Sets registration by type + if (null !== $registration = $this->getUserCollectionRegistration($collection, $userData)) { + $data[$databox->get_sbas_id()]['registrations']['by-type'][$registration['type']][] = $registration; + } + } + } + + return $data; + } + + /** + * Tells whether user has ever requested a registration on collection or not. + * + * @param \collection $collection + * @param $userData + * + * @return boolean + */ + private function userHasRequestedARegistrationOnCollection(\collection $collection, $userData) + { + if (null === $userRegistration = igorw\get_in($userData, [$collection->get_sbas_id(), $collection->get_base_id()])) { + return false; + } + + return !is_null($userRegistration['active']); + } + + /** + * Returns a user registration for given collection or null if no registration were requested. + * + * @param \collection $collection + * @param $userData + * + * @return null|array + */ + private function getUserCollectionRegistration(\collection $collection, $userData) + { + if (false === $this->userHasRequestedARegistrationOnCollection($collection, $userData)) { + return null; + } + + $userRegistration = igorw\get_in($userData, [$collection->get_sbas_id(), $collection->get_base_id()]); + + // sets collection name + $userRegistration['coll-name'] = $collection->get_label($this->locale); + // sets default type + $userRegistration['type'] = 'active'; + + // gets registration entity + $registration = $userRegistration['registration']; + + // set registration type & return user registration + $registrationStillExists = !is_null($registration); + $registrationNoMoreExists = !$registrationStillExists; + $isPending = $registrationStillExists && $registration->isPending() && !$registration->isRejected(); + $isRejected = $registrationStillExists && $registration->isRejected(); + $isDone = ($registrationNoMoreExists) || (!$isPending && !$isRejected); + $isActive = (Boolean) $userRegistration['active']; + $isTimeLimited = (Boolean) $userRegistration['time-limited']; + $isNotTimeLimited = !$isTimeLimited; + $isOnTime = (Boolean) $userRegistration['in-time']; + $isOutDated = !$isOnTime; + + if (!$isActive) { + $userRegistration['type'] = 'inactive'; + + return $userRegistration; + } + + if ($isDone) { + $userRegistration['type'] = 'accepted'; + + return $userRegistration; + } + + if ($isRejected) { + $userRegistration['type'] = 'rejected'; + + return $userRegistration; + } + + if ($isTimeLimited && $isOnTime && $isPending) { + $userRegistration['type'] = 'in-time'; + + return $userRegistration; + } + + if ($isTimeLimited && $isOutDated && $isPending) { + $userRegistration['type'] = 'out-time'; + + return $userRegistration; + } + + if ($isNotTimeLimited && $isPending) { + $userRegistration['type'] = 'pending'; + + return $userRegistration; + } + + return $userRegistration; + } + + private function getCollectionSummary(\collection $collection, $userData) + { + return [ + 'coll-name' => $collection->get_label($this->locale), + // gets collection registration or fallback to databox configuration + 'can-register' => $collection->isRegistrationEnabled(), + 'cgu' => $collection->getTermsOfUse(), + // boolean to tell whether user has already requested an access to the collection + 'registration' => $this->userHasRequestedARegistrationOnCollection($collection, $userData) + ]; + } +} diff --git a/lib/Alchemy/Phrasea/Core/Provider/ManipulatorServiceProvider.php b/lib/Alchemy/Phrasea/Core/Provider/ManipulatorServiceProvider.php index ccd502261c..a2bb2c8996 100644 --- a/lib/Alchemy/Phrasea/Core/Provider/ManipulatorServiceProvider.php +++ b/lib/Alchemy/Phrasea/Core/Provider/ManipulatorServiceProvider.php @@ -40,7 +40,7 @@ class ManipulatorServiceProvider implements ServiceProviderInterface }); $app['manipulator.registration'] = $app->share(function ($app) { - return new RegistrationManipulator($app['EM'], $app['phraseanet.appbox'], $app['acl']); + return new RegistrationManipulator($app, $app['EM'], $app['acl'], $app['phraseanet.appbox']); }); } diff --git a/lib/Alchemy/Phrasea/Core/Provider/RegistrationServiceProvider.php b/lib/Alchemy/Phrasea/Core/Provider/RegistrationServiceProvider.php index 7ee2428e5d..f3c9b173a3 100644 --- a/lib/Alchemy/Phrasea/Core/Provider/RegistrationServiceProvider.php +++ b/lib/Alchemy/Phrasea/Core/Provider/RegistrationServiceProvider.php @@ -12,8 +12,8 @@ namespace Alchemy\Phrasea\Core\Provider; use Alchemy\Phrasea\Form\Constraint\NewLogin; -use Alchemy\Phrasea\Model\Manipulator\RegistrationManipulator; use Alchemy\Phrasea\Model\Entities\User; +use Alchemy\Phrasea\Core\Configuration\RegistrationManager; use Silex\Application; use Silex\ServiceProviderInterface; use Symfony\Component\Validator\Constraints as Assert; @@ -27,7 +27,7 @@ class RegistrationServiceProvider implements ServiceProviderInterface }); $app['registration.manager'] = $app->share(function (Application $app) { - return new RegistrationManager($app['phraseanet.appbox']); + return new RegistrationManager($app['phraseanet.appbox'], $app['manipulator.registration']->getRepository(), $app['locale']); }); $app['registration.optional-fields'] = $app->share(function (Application $app) { diff --git a/lib/Alchemy/Phrasea/Core/Version.php b/lib/Alchemy/Phrasea/Core/Version.php index 0116a51337..790a226bc0 100644 --- a/lib/Alchemy/Phrasea/Core/Version.php +++ b/lib/Alchemy/Phrasea/Core/Version.php @@ -13,7 +13,7 @@ namespace Alchemy\Phrasea\Core; class Version { - protected static $number = '3.9.0-alpha.12'; + protected static $number = '3.9.0-alpha.13'; protected static $name = 'Epanterias'; public static function getNumber() diff --git a/lib/Alchemy/Phrasea/Form/Login/PhraseaRegisterForm.php b/lib/Alchemy/Phrasea/Form/Login/PhraseaRegisterForm.php index 2718cbcef9..837ad767a8 100644 --- a/lib/Alchemy/Phrasea/Form/Login/PhraseaRegisterForm.php +++ b/lib/Alchemy/Phrasea/Form/Login/PhraseaRegisterForm.php @@ -72,16 +72,15 @@ class PhraseaRegisterForm extends AbstractType $builder->add('provider-id', 'hidden'); - $choices = []; - $baseIds = []; + $choices = $baseIds = []; - foreach ($this->app['manipulator.registration']->getRegistrationSummary() 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']) { continue; } - $choices[$dbName][$baseId] = \phrasea::bas_labels($baseId, $this->app); + $choices[$dbName][$baseId] = $collInfo['coll-name']; $baseIds[] = $baseId; } } diff --git a/lib/Alchemy/Phrasea/Model/Entities/Registration.php b/lib/Alchemy/Phrasea/Model/Entities/Registration.php index c6b6e26d10..4223753642 100644 --- a/lib/Alchemy/Phrasea/Model/Entities/Registration.php +++ b/lib/Alchemy/Phrasea/Model/Entities/Registration.php @@ -11,11 +11,14 @@ namespace Alchemy\Phrasea\Model\Entities; +use Alchemy\Phrasea\Application; use Doctrine\ORM\Mapping as ORM; use Gedmo\Mapping\Annotation as Gedmo; /** - * @ORM\Table(name="Registration") + * @ORM\Table(name="Registration",uniqueConstraints={ + * @ORM\UniqueConstraint(name="unique_registration", columns={"user_id","base_id","pending"}) + * }) * @ORM\Entity(repositoryClass="Alchemy\Phrasea\Model\Repositories\RegistrationRepository") */ class Registration @@ -28,8 +31,11 @@ class Registration private $id; /** - * @ORM\Column(type="integer", name="user_id") - */ + * @ORM\ManyToOne(targetEntity="User") + * @ORM\JoinColumn(name="user_id", referencedColumnName="id", nullable=false) + * + * @return User + **/ private $user; /** @@ -110,25 +116,45 @@ class Registration } /** - * @param mixed $user - * * @return Registration */ - public function setUser($user) + public function setUser(User $user) { - $this->user = $user; + $this->user = $user; return $this; } /** - * @return mixed + * @return integer */ public function getUser() { return $this->user; } + /** + * @param Application $app + * + * @return \collection + */ + public function getCollection(Application $app) + { + return \collection::get_from_base_id($app, $this->baseId); + } + + /** + * @param \collection $collection + * + * @return $this + */ + public function setCollection(\collection $collection) + { + $this->baseId = $collection->get_base_id(); + + return $this; + } + /** * @param mixed $baseId * diff --git a/lib/Alchemy/Phrasea/Model/Manipulator/RegistrationManipulator.php b/lib/Alchemy/Phrasea/Model/Manipulator/RegistrationManipulator.php index 62527152e9..58e6fa4f8c 100644 --- a/lib/Alchemy/Phrasea/Model/Manipulator/RegistrationManipulator.php +++ b/lib/Alchemy/Phrasea/Model/Manipulator/RegistrationManipulator.php @@ -11,40 +11,43 @@ namespace Alchemy\Phrasea\Model\Manipulator; +use Alchemy\Phrasea\Application; use Alchemy\Phrasea\Authentication\ACLProvider; use Alchemy\Phrasea\Model\Entities\Registration; +use Alchemy\Phrasea\Model\Entities\User; use Alchemy\Phrasea\Model\Repositories\RegistrationRepository; use Doctrine\ORM\EntityManager; -use igorw; class RegistrationManipulator implements ManipulatorInterface { private $em; + private $app; private $appbox; private $repository; private $aclProvider; - public function __construct(EntityManager $em, \appbox $appbox, ACLProvider $aclProvider) + public function __construct(Application $app, EntityManager $em, ACLProvider $aclProvider, \appbox $appbox) { + $this->app = $app; $this->em = $em; $this->appbox = $appbox; - $this->repository = $this->em->getRepository('Alchemy\Phrasea\Model\Entities\Registration'); $this->aclProvider = $aclProvider; + $this->repository = $this->em->getRepository('Phraseanet:Registration'); } /** * Creates a new registration. * - * @param $userId - * @param $baseId + * @param User $user + * @param \collection $collection * * @return Registration */ - public function createRegistration($userId, $baseId) + public function createRegistration(User $user, \collection $collection) { $registration = new Registration(); - $registration->setUser($userId); - $registration->setBaseId($baseId); + $registration->setUser($user); + $registration->setCollection($collection); $this->em->persist($registration); $this->em->flush(); @@ -67,14 +70,15 @@ class RegistrationManipulator implements ManipulatorInterface /** * Accepts a registration. * - * @param Registration $registration - * @param \User_Adapter $user - * @param \Collection $collection - * @param bool $grantHd - * @param bool $grantWatermark + * @param Registration $registration + * @param bool $grantHd + * @param bool $grantWatermark */ - public function acceptRegistration(Registration $registration, \User_Adapter $user, \Collection $collection, $grantHd = false, $grantWatermark = false) + public function acceptRegistration(Registration $registration, $grantHd = false, $grantWatermark = false) { + $user = $registration->getUser(); + $collection = $registration->getCollection($this->app); + $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(), [ @@ -88,117 +92,6 @@ class RegistrationManipulator implements ManipulatorInterface $this->em->flush(); } - /** - * Gets information about registration configuration and registration status if a user id is provided. - * - * @param null|integer $userId - * - * @return array - */ - public function getRegistrationSummary($userId = null) - { - $data = $userData = []; - - if (null !== $userId) { - $userData = $this->getRepository()->getRegistrationsSummaryForUser($userId); - } - - foreach ($this->appbox->get_databoxes() as $databox) { - $ddata = [ - 'registrations' => [ - 'by-type' => [ - 'inactive' => [], - 'accepted' => [], - 'in-time' => [], - 'out-dated' => [], - 'pending' => [], - 'rejected' => [], - ], - 'by-collection' => [] - ], - 'config' => [ - 'db-name' => $databox->get_dbname(), - 'cgu' => $databox->get_cgus(), - 'can-register' => $databox->isRegistrationEnabled(), - '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' => $collection->isRegistrationEnabled(), - 'cgu' => $collection->getTermsOfUse(), - 'registration' => null - ]; - - if (null === $userRegistration = igorw\get_in($userData, [$databox->get_sbas_id(), $collection->get_base_id()])) { - continue; - } - - // sets collection name - $userRegistration['coll-name'] = $collection->get_name(); - // gets registration entity - $registration = $userRegistration['registration']; - - $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) $userRegistration['in-time']; - $isOutDated = !$isOnTime; - - if ($noRegistrationMade) { - continue; - } - // sets registrations - $ddata['config']['collections'][$collection->get_base_id()]['registration'] = $userRegistration; - $ddata['registrations']['by-collection'][$collection->get_base_id()] = $userRegistration; - - if (!$isActive) { - $ddata['registrations']['by-type']['inactive'][] = $userRegistration; - continue; - } - - if ($isDone) { - $ddata['registrations']['by-type']['accepted'][] = $userRegistration; - continue; - } - - if ($isRejected) { - $ddata['registrations']['by-type']['rejected'][] = $userRegistration; - continue; - } - - if ($isTimeLimited && $isOnTime && $isPending) { - $ddata['registrations']['by-type']['in-time'][] = $userRegistration; - continue; - } - - if ($isTimeLimited && $isOutDated && $isPending) { - $ddata['registrations']['by-type']['out-time'][] = $userRegistration; - continue; - } - - if ($isNotTimeLimited && $isPending) { - $ddata['registrations']['by-type']['pending'][] = $userRegistration; - } - } - } - - $data[$databox->get_sbas_id()] = $ddata; - - return $data; - } - /** * Gets Registration Repository. * @@ -212,21 +105,23 @@ class RegistrationManipulator implements ManipulatorInterface /** * Deletes registration for given user. * - * @param $userId - * @param array $baseList + * @param User $user + * @param \collection[] $collections * * @return mixed */ - public function deleteRegistrationsForUser($userId, array $baseList) + public function deleteUserRegistrations(User $user, array $collections) { $qb = $this->getRepository()->createQueryBuilder('d'); - $qb->delete('Alchemy\Phrasea\Model\Entities\Registration', 'd'); + $qb->delete('Phraseanet:Registration', 'd'); $qb->where($qb->expr()->eq('d.user', ':user')); - $qb->setParameter(':user', $userId); + $qb->setParameter(':user', $user->getId()); - if (count($baseList) > 0) { + if (count($collections) > 0) { $qb->andWhere('d.baseId IN (:bases)'); - $qb->setParameter(':bases', $baseList); + $qb->setParameter(':bases', array_map(function ($collection) { + return $collection->get_base_id(); + }, $collections)); } return $qb->getQuery()->execute(); @@ -238,7 +133,7 @@ class RegistrationManipulator implements ManipulatorInterface public function deleteOldRegistrations() { $qb = $this->getRepository()->createQueryBuilder('d'); - $qb->delete('Alchemy\Phrasea\Model\Entities\Registration', 'd'); + $qb->delete('Phraseanet:Registration', 'd'); $qb->where($qb->expr()->lt('d.created', ':date')); $qb->setParameter(':date', new \DateTime('-1 month')); $qb->getQuery()->execute(); @@ -249,12 +144,12 @@ class RegistrationManipulator implements ManipulatorInterface * * @param $baseId */ - public function deleteRegistrationsOnCollection($baseId) + public function deleteRegistrationsOnCollection(\collection $collection) { $qb = $this->getRepository()->createQueryBuilder('d'); - $qb->delete('Alchemy\Phrasea\Model\Entities\Registration', 'd'); + $qb->delete('Phraseanet:Registration', 'd'); $qb->where($qb->expr()->eq('d.baseId', ':base')); - $qb->setParameter(':base', $baseId); + $qb->setParameter(':base', $collection->get_base_id()); $qb->getQuery()->execute(); } } diff --git a/lib/Alchemy/Phrasea/Model/NativeQueryProvider.php b/lib/Alchemy/Phrasea/Model/NativeQueryProvider.php index 8ea422c27d..83adb29da3 100644 --- a/lib/Alchemy/Phrasea/Model/NativeQueryProvider.php +++ b/lib/Alchemy/Phrasea/Model/NativeQueryProvider.php @@ -82,6 +82,6 @@ class NativeQueryProvider AND u.deleted="0"', $rsm ); - return $query->getResults(); + return $query->getResult(); } } diff --git a/lib/Alchemy/Phrasea/Model/Repositories/RegistrationRepository.php b/lib/Alchemy/Phrasea/Model/Repositories/RegistrationRepository.php index a75aeee1c4..4573c623ab 100644 --- a/lib/Alchemy/Phrasea/Model/Repositories/RegistrationRepository.php +++ b/lib/Alchemy/Phrasea/Model/Repositories/RegistrationRepository.php @@ -12,6 +12,7 @@ namespace Alchemy\Phrasea\Model\Repositories; use Doctrine\ORM\EntityRepository; +use Alchemy\Phrasea\Model\Entities\User; /** * RegistrationRepository @@ -24,20 +25,22 @@ class RegistrationRepository extends EntityRepository /** * Displays registrations for user on provided collection. * - * @param \User_Adapter $user - * @param array $baseList + * @param User $user + * @param \collection[] $collections * * @return array */ - public function getRegistrationsForUser(\User_Adapter $user, array $baseList) + public function getUserRegistrations(User $user, array $collections) { $qb = $this->createQueryBuilder('d'); $qb->where($qb->expr()->eq('d.user', ':user')); - $qb->setParameter(':user', $user->get_id()); + $qb->setParameter(':user', $user->getId()); - if (count($baseList) > 0) { + if (count($collections) > 0) { $qb->andWhere('d.baseId IN (:bases)'); - $qb->setParameter(':bases', $baseList); + $qb->setParameter(':bases', array_map(function ($collection) { + return $collection->get_base_id(); + }, $collections)); } $qb->orderBy('d.created', 'DESC'); @@ -48,11 +51,11 @@ class RegistrationRepository extends EntityRepository /** * Gets registration registrations for a user. * - * @param $usrId + * @param User $user * * @return array */ - public function getRegistrationsSummaryForUser($usrId) + public function getRegistrationsSummaryForUser(User $user) { $data = []; $rsm = $this->createResultSetMappingBuilder('d'); @@ -78,7 +81,7 @@ class RegistrationRepository extends EntityRepository AND model_of = 0"; $query = $this->_em->createNativeQuery($sql, $rsm); - $query->setParameter(1, $usrId); + $query->setParameter(1, $user->getId()); foreach ($query->getResult() as $row) { $registrationEntity = $row[0]; diff --git a/lib/Alchemy/Phrasea/Registration/RegistrationManager.php b/lib/Alchemy/Phrasea/Registration/RegistrationManager.php deleted file mode 100644 index 46fcf9235f..0000000000 --- a/lib/Alchemy/Phrasea/Registration/RegistrationManager.php +++ /dev/null @@ -1,40 +0,0 @@ -appbox = $appbox; - } - - /** - * Tells whether registration is enabled or not. - * - * @return boolean - */ - public function isRegistrationEnabled() - { - foreach ($this->appbox->get_databoxes() as $databox) { - foreach($databox->get_collections() as $collection) { - if ($collection->isRegistrationEnabled()) { - return true; - } - } - } - return false; - } -} diff --git a/lib/Alchemy/Phrasea/Setup/DoctrineMigrations/RegistrationDemandMigration.php b/lib/Alchemy/Phrasea/Setup/DoctrineMigrations/RegistrationMigration.php similarity index 75% rename from lib/Alchemy/Phrasea/Setup/DoctrineMigrations/RegistrationDemandMigration.php rename to lib/Alchemy/Phrasea/Setup/DoctrineMigrations/RegistrationMigration.php index ef06201fdb..b1564c84e6 100644 --- a/lib/Alchemy/Phrasea/Setup/DoctrineMigrations/RegistrationDemandMigration.php +++ b/lib/Alchemy/Phrasea/Setup/DoctrineMigrations/RegistrationMigration.php @@ -12,13 +12,12 @@ namespace Alchemy\Phrasea\Setup\DoctrineMigrations; use Doctrine\DBAL\Schema\Schema; -use Doctrine\ORM\Query\ResultSetMapping; class RegistrationMigration extends AbstractMigration { public function doUpSql(Schema $schema) { - $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"); + $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, INDEX IDX_7A997C5FA76ED395 (user_id), UNIQUE INDEX unique_registration (user_id, base_id, pending), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB"); } public function doDownSql(Schema $schema) diff --git a/lib/classes/API/V1/adapter.php b/lib/classes/API/V1/adapter.php index ac0d12f9a4..f6d7f8560c 100644 --- a/lib/classes/API/V1/adapter.php +++ b/lib/classes/API/V1/adapter.php @@ -1089,7 +1089,7 @@ class API_V1_adapter extends API_V1_Abstract } $record->set_metadatas($metadatas); - $result->set_datas(array("record_metadatas" => $this->list_record_caption($record->get_caption()))); + $result->set_datas(["record_metadatas" => $this->list_record_caption($record->get_caption())]); } catch (\Exception $e) { $result->set_error_message(API_V1_result::ERROR_BAD_REQUEST, _('An error occured')); } diff --git a/lib/classes/collection.php b/lib/classes/collection.php index 4acc6f2838..f6d9c48f26 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['manipulator.registration']->deleteRegistrationsOnCollection($this->get_base_id()); + $this->app['manipulator.registration']->deleteRegistrationsOnCollection($this); $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['manipulator.registration']->deleteRegistrationsOnCollection($this->get_base_id()); + $this->app['manipulator.registration']->deleteRegistrationsOnCollection($this); phrasea::reset_baseDatas($app['phraseanet.appbox']); @@ -748,17 +748,19 @@ class collection implements cache_cacheableInterface */ public function isRegistrationEnabled() { - if ($xml = simplexml_load_string($this->get_prefs())) { - $element = $xml->xpath('/baseprefs/caninscript'); + if (false === $xml = simplexml_load_string($this->get_prefs())) { + return false; + } - if (count($element) === 0) { - return $this->databox->isRegistrationEnabled(); - } + $element = $xml->xpath('/baseprefs/caninscript'); - foreach ($element as $caninscript) { - if (false !== (Boolean) (string) $caninscript) { - return true; - } + if (count($element) === 0) { + return $this->databox->isRegistrationEnabled(); + } + + foreach ($element as $caninscript) { + if (false !== (Boolean) (string) $caninscript) { + return true; } } @@ -774,12 +776,12 @@ class collection implements cache_cacheableInterface */ public function getTermsOfUse() { - if ($xml = simplexml_load_string($this->get_prefs())) { - foreach ($xml->xpath('/baseprefs/cgu') as $sbpcgu) { - return $sbpcgu->saveXML(); - } + if (false === $xml = simplexml_load_string($this->get_prefs())) { + return; } - return null; + foreach ($xml->xpath('/baseprefs/cgu') as $sbpcgu) { + return $sbpcgu->saveXML(); + } } } diff --git a/lib/classes/databox/cgu.php b/lib/classes/databox/cgu.php index 4a54b836af..6bf4234c5d 100644 --- a/lib/classes/databox/cgu.php +++ b/lib/classes/databox/cgu.php @@ -29,7 +29,7 @@ class databox_cgu if (trim($term['terms']) == '') { continue; } - $out .= '