Merge pull request #900 from nlegoff/replace_demand

[3.9] Migrate registration table to doctrine entity && refactor registration API
This commit is contained in:
Romain Neutron
2014-02-27 16:08:17 +01:00
43 changed files with 1704 additions and 871 deletions

View File

@@ -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,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($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();
@@ -121,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();
@@ -637,4 +646,19 @@ class RegenerateSqliteDb extends Command
$em->persist($entry);
}
private function insertOneRegistration(\Pimple $DI, EntityManager $em, User $user, \collection $collection, $when, $name)
{
$em->getEventManager()->removeEventSubscriber(new TimestampableListener());
$registration = new Registration();
$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;
}
}

View File

@@ -353,58 +353,39 @@ class Users implements ControllerProviderInterface
return $response;
})->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();
$controllers->get('/registrations/', function (Application $app) {
$app['manipulator.registration']->deleteOldRegistrations();
$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' => []];
foreach ($app['EM.native-query']->getUsersRegistrationDemand($basList) as $row) {
$user = $row[0];
if ($user->getId() !== $currentUsr) {
$currentUsr = $user->getId();
$table['users'][$currentUsr] = [
'user' => $user,
'date_demand' => $row['date_demand'],
];
}
if (!isset($table['coll'][$user->getId()])) {
$table['coll'][$user->getId()] = [];
}
if (!in_array($row['base_demand'], $table['coll'][$user->getId()])) {
$table['coll'][$user->getId()][] = $row['base_demand'];
}
$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();
$userRegistrations[$user->getId()]['user'] = $user;
$userRegistrations[$user->getId()]['registrations'][$registration->getBaseid()] = $registration;
}
$stmt->closeCursor();
return $app['twig']->render('admin/user/demand.html.twig', [
'table' => $table,
return $app['twig']->render('admin/user/registrations.html.twig', [
'user_registrations' => $userRegistrations,
'models' => $models,
]);
})->bind('users_display_demands');
$controllers->post('/demands/', function (Application $app, Request $request) {
})->bind('users_display_registrations');
$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];
}
}
@@ -438,127 +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);
if (!isset($done[$usr])) {
$done[$usr] = [];
foreach ($collections as $collection) {
$done[$usr][$collection->get_base_id()] = true;
}
foreach ($base_ids as $base_id) {
$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['manipulator.registration']->deleteUserRegistrations($user, $collections);
}
$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]);
if (!isset($done[$usr])) {
$done[$usr] = [];
}
$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;
}
}
$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);
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();
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');

View File

@@ -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']->getRegistrationSummary($app['authentication']->getUser())
]);
}
@@ -328,17 +326,15 @@ class Account implements ControllerProviderInterface
*/
public function updateAccount(PhraseaApplication $app, Request $request)
{
$demands = (array) $request->request->get('demand', []);
if (0 !== count($demands)) {
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) {
}
$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($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.'));
}
$accountFields = [

View File

@@ -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;
@@ -80,7 +81,7 @@ class Login implements ControllerProviderInterface
'recaptcha_display' => $app->isCaptchaRequired(),
'unlock_usr_id' => $app->getUnlockAccountData(),
'guest_allowed' => $app->isGuestAllowed(),
'register_enable' => $app['registration.enabled'],
'register_enable' => $app['registration.manager']->isRegistrationEnabled(),
'display_layout' => $app['conf']->get(['registry', 'general', 'home-presentation-mode']),
'authentication_providers' => $app['authentication.providers'],
'registration_fields' => $app['registration.fields'],
@@ -266,7 +267,7 @@ class Login implements ControllerProviderInterface
public function doRegistration(PhraseaApplication $app, Request $request)
{
if (!$app['registration.enabled']) {
if (!$app['registration.manager']->isRegistrationEnabled()) {
$app->abort(404, 'Registration is disabled');
}
@@ -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']->getRegistrationSummary();
$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;
}
}
}
@@ -393,34 +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;
}
$collection = \collection::get_from_base_id($app, $base_id);
$app['phraseanet.appbox-register']->add_request($user, $collection);
$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()
];
@@ -705,7 +688,7 @@ class Login implements ControllerProviderInterface
*/
public function displayRegisterForm(PhraseaApplication $app, Request $request)
{
if (!$app['registration.enabled']) {
if (!$app['registration.manager']->isRegistrationEnabled()) {
$app->abort(404, 'Registration is disabled');
}
@@ -750,8 +733,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) {
@@ -973,7 +954,7 @@ class Login implements ControllerProviderInterface
}
return $app->redirect($redirection);
} elseif ($app['registration.enabled']) {
} elseif ($app['registration.manager']->isRegistrationEnabled()) {
return $app->redirectPath('login_register_classic', ['providerId' => $providerId]);
}

View File

@@ -0,0 +1,204 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2014 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Alchemy\Phrasea\Core\Configuration;
use Alchemy\Phrasea\Model\Repositories\RegistrationRepository;
use Alchemy\Phrasea\Model\Entities\User;
use igorw;
class RegistrationManager
{
/** @var \appbox */
private $appbox;
private $repository;
public function __construct(\appbox $appbox, RegistrationRepository $repository, $locale)
{
$this->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)
];
}
}

View File

@@ -68,7 +68,7 @@ class AuthenticationManagerServiceProvider implements ServiceProviderInterface
}
}, $authConf['auto-create']['templates']));
$enabled = $app['conf']->get(['registry', 'registration', 'auto-register-enabled']) && $app['registration.enabled'];
$enabled = $app['conf']->get(['registry', 'registration', 'auto-register-enabled']) && $app['registration.manager']->isRegistrationEnabled();
return new AccountCreator($app['tokens'], $app['phraseanet.appbox'], $enabled, $templates);
});

View File

@@ -12,6 +12,7 @@
namespace Alchemy\Phrasea\Core\Provider;
use Alchemy\Phrasea\Model\Manipulator\ACLManipulator;
use Alchemy\Phrasea\Model\Manipulator\RegistrationManipulator;
use Alchemy\Phrasea\Model\Manipulator\TaskManipulator;
use Alchemy\Phrasea\Model\Manipulator\UserManipulator;
use Alchemy\Phrasea\Model\Manager\UserManager;
@@ -37,6 +38,10 @@ class ManipulatorServiceProvider implements ServiceProviderInterface
$app['model.user-manager'] = $app->share(function ($app) {
return new UserManager($app['EM'], $app['phraseanet.appbox']->get_connection());
});
$app['manipulator.registration'] = $app->share(function ($app) {
return new RegistrationManipulator($app, $app['EM'], $app['acl'], $app['phraseanet.appbox']);
});
}
public function boot(SilexApplication $app)

View File

@@ -13,6 +13,7 @@ namespace Alchemy\Phrasea\Core\Provider;
use Alchemy\Phrasea\Form\Constraint\NewLogin;
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;
@@ -25,20 +26,8 @@ class RegistrationServiceProvider implements ServiceProviderInterface
return $app['conf']->get('registration-fields', []);
});
$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;
$app['registration.manager'] = $app->share(function (Application $app) {
return new RegistrationManager($app['phraseanet.appbox'], $app['manipulator.registration']->getRepository(), $app['locale']);
});
$app['registration.optional-fields'] = $app->share(function (Application $app) {

View File

@@ -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()

View File

@@ -72,39 +72,16 @@ class PhraseaRegisterForm extends AbstractType
$builder->add('provider-id', 'hidden');
require_once $this->app['root.path'] . '/lib/classes/deprecated/inscript.api.php';
$choices = [];
$baseIds = [];
$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;
}
}
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;
}
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] = $collInfo['coll-name'];
$baseIds[] = $baseId;
}
}

View File

@@ -0,0 +1,209 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2014 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
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",uniqueConstraints={
* @ORM\UniqueConstraint(name="unique_registration", columns={"user_id","base_id","pending"})
* })
* @ORM\Entity(repositoryClass="Alchemy\Phrasea\Model\Repositories\RegistrationRepository")
*/
class Registration
{
/**
* @ORM\Column(type="integer")
* @ORM\Id
* @ORM\GeneratedValue
*/
private $id;
/**
* @ORM\ManyToOne(targetEntity="User")
* @ORM\JoinColumn(name="user_id", referencedColumnName="id", nullable=false)
*
* @return User
**/
private $user;
/**
* @ORM\Column(type="integer", name="base_id")
*/
private $baseId;
/**
* @ORM\Column(type="boolean", name="pending")
*/
private $pending = true;
/**
* @ORM\Column(type="boolean", name="rejected")
*/
private $rejected = false;
/**
* @Gedmo\Timestampable(on="create")
* @ORM\Column(type="datetime")
*/
private $created;
/**
* @Gedmo\Timestampable(on="update")
* @ORM\Column(type="datetime")
*/
private $updated;
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* @param mixed $pending
*
* @return Registration
*/
public function setPending($pending)
{
$this->pending = (Boolean) $pending;
return $this;
}
/**
* @return mixed
*/
public function isPending()
{
return $this->pending;
}
/**
* @param mixed $rejected
*
* @return Registration
*/
public function setRejected($rejected)
{
$this->rejected = (Boolean) $rejected;
return $this;
}
/**
* @return mixed
*/
public function isRejected()
{
return $this->rejected;
}
/**
* @return Registration
*/
public function setUser(User $user)
{
$this->user = $user;
return $this;
}
/**
* @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
*
* @return Registration
*/
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;
}
}

View File

@@ -0,0 +1,155 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2014 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
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;
class RegistrationManipulator implements ManipulatorInterface
{
private $em;
private $app;
private $appbox;
private $repository;
private $aclProvider;
public function __construct(Application $app, EntityManager $em, ACLProvider $aclProvider, \appbox $appbox)
{
$this->app = $app;
$this->em = $em;
$this->appbox = $appbox;
$this->aclProvider = $aclProvider;
$this->repository = $this->em->getRepository('Phraseanet:Registration');
}
/**
* Creates a new registration.
*
* @param User $user
* @param \collection $collection
*
* @return Registration
*/
public function createRegistration(User $user, \collection $collection)
{
$registration = new Registration();
$registration->setUser($user);
$registration->setCollection($collection);
$this->em->persist($registration);
$this->em->flush();
return $registration;
}
/**
* Rejects a registration.
*
* @param Registration $registration
*/
public function rejectRegistration(Registration $registration)
{
$registration->setPending(false);
$registration->setRejected(true);
$this->em->persist($registration);
$this->em->flush();
}
/**
* Accepts a registration.
*
* @param Registration $registration
* @param bool $grantHd
* @param bool $grantWatermark
*/
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(), [
'canputinalbum' => '1',
'candwnldhd' => (string) (int) $grantHd,
'nowatermark' => (string) (int) $grantWatermark,
'candwnldpreview' => '1',
'actif' => '1',
]);
$this->em->remove($registration);
$this->em->flush();
}
/**
* Gets Registration Repository.
*
* @return RegistrationRepository
*/
public function getRepository()
{
return $this->repository;
}
/**
* Deletes registration for given user.
*
* @param User $user
* @param \collection[] $collections
*
* @return mixed
*/
public function deleteUserRegistrations(User $user, array $collections)
{
$qb = $this->getRepository()->createQueryBuilder('d');
$qb->delete('Phraseanet:Registration', 'd');
$qb->where($qb->expr()->eq('d.user', ':user'));
$qb->setParameter(':user', $user->getId());
if (count($collections) > 0) {
$qb->andWhere('d.baseId IN (:bases)');
$qb->setParameter(':bases', array_map(function ($collection) {
return $collection->get_base_id();
}, $collections));
}
return $qb->getQuery()->execute();
}
/**
* Deletes old registrations.
*/
public function deleteOldRegistrations()
{
$qb = $this->getRepository()->createQueryBuilder('d');
$qb->delete('Phraseanet:Registration', 'd');
$qb->where($qb->expr()->lt('d.created', ':date'));
$qb->setParameter(':date', new \DateTime('-1 month'));
$qb->getQuery()->execute();
}
/**
* Deletes registrations on given collection.
*
* @param $baseId
*/
public function deleteRegistrationsOnCollection(\collection $collection)
{
$qb = $this->getRepository()->createQueryBuilder('d');
$qb->delete('Phraseanet:Registration', 'd');
$qb->where($qb->expr()->eq('d.baseId', ':base'));
$qb->setParameter(':base', $collection->get_base_id());
$qb->getQuery()->execute();
}
}

View File

@@ -82,6 +82,6 @@ class NativeQueryProvider
AND u.deleted="0"', $rsm
);
return $query->getResults();
return $query->getResult();
}
}

View File

@@ -0,0 +1,101 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2014 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Alchemy\Phrasea\Model\Repositories;
use Doctrine\ORM\EntityRepository;
use Alchemy\Phrasea\Model\Entities\User;
/**
* RegistrationRepository
*
* This class was generated by the Doctrine ORM. Add your own custom
* repository methods below.
*/
class RegistrationRepository extends EntityRepository
{
/**
* Displays registrations for user on provided collection.
*
* @param User $user
* @param \collection[] $collections
*
* @return array
*/
public function getUserRegistrations(User $user, array $collections)
{
$qb = $this->createQueryBuilder('d');
$qb->where($qb->expr()->eq('d.user', ':user'));
$qb->setParameter(':user', $user->getId());
if (count($collections) > 0) {
$qb->andWhere('d.baseId IN (:bases)');
$qb->setParameter(':bases', array_map(function ($collection) {
return $collection->get_base_id();
}, $collections));
}
$qb->orderBy('d.created', 'DESC');
return $qb->getQuery()->getResult();
}
/**
* Gets registration registrations for a user.
*
* @param User $user
*
* @return array
*/
public function getRegistrationsSummaryForUser(User $user)
{
$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, $user->getId());
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;
}
}

View File

@@ -0,0 +1,27 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2014 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Alchemy\Phrasea\Setup\DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
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, 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)
{
$this->addSql("DROP TABLE Registration");
}
}

View File

@@ -1,95 +0,0 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2014 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
use Alchemy\Phrasea\Application;
use Alchemy\Phrasea\Model\Entities\User;
class appbox_register
{
/**
*
* @var appbox
*/
protected $appbox;
/**
* Construct an Appbox_Register object which will give use infos
* about the current registrations on the provided appbox
*
* @param appbox $appbox
* @return appbox_register
*/
public function __construct(appbox $appbox)
{
$this->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;
}
}

View File

@@ -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['manipulator.registration']->deleteRegistrationsOnCollection($this);
$this->get_databox()->delete_data_from_cache(databox::CACHE_COLLECTIONS);
@@ -543,10 +540,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['manipulator.registration']->deleteRegistrationsOnCollection($this);
phrasea::reset_baseDatas($app['phraseanet.appbox']);
@@ -752,4 +746,48 @@ class collection implements cache_cacheableInterface
{
self::$_collections = [];
}
/**
* Tells whether registration is activated for provided collection or not.
*
* @return boolean
*/
public function isRegistrationEnabled()
{
if (false === $xml = simplexml_load_string($this->get_prefs())) {
return false;
}
$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 (false === $xml = simplexml_load_string($this->get_prefs())) {
return;
}
foreach ($xml->xpath('/baseprefs/cgu') as $sbpcgu) {
return $sbpcgu->saveXML();
}
}
}

View File

@@ -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 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;
}
}

View File

@@ -29,7 +29,7 @@ class databox_cgu
if (trim($term['terms']) == '') {
continue;
}
$out .= '<div style="display:none;" class="cgu-dialog" title="' . str_replace('"', '&quot;', $app->trans('cgus:: CGUs de la base %s', $name)) . '">';
$out .= '<div style="display:none;" class="cgu-dialog" title="' . str_replace('"', '&quot;', $app->trans('cgus:: CGUs de la base %name%', ['%name%', $name])) . '">';
$out .= '<blockquote>' . $term['terms'] . '</blockquote>';
$out .= '<div>' . $app->trans('cgus:: Pour continuer a utiliser lapplication, vous devez accepter les conditions precedentes') . '

View File

@@ -1,294 +0,0 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2014 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
use Alchemy\Phrasea\Application;
function giveMeBases(Application $app, $usr = null)
{
$conn = $app['phraseanet.appbox']->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 = '<table border="0" style="table-layout:fixed;font-size:11px;" cellspacing=0 width="100%">' .
'<tr>' .
'<td style="width:180px; text-align:right">&nbsp;</td>' .
'<td width="15px" style="width:15px">&nbsp;</td>' .
'<td style="width:180px;">&nbsp;</td>' .
'</tr>';
$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 .= '<tr><td colspan="3" style="text-align:center;"><h3>' . phrasea::sbas_labels($sbasId, $app) . '</h3></td></tr>';
if ($baseInsc['CollsRegistered']) {
foreach ($baseInsc['CollsRegistered'] as $collId => $isTrue) {
$base_id = phrasea::baseFromColl($sbasId, $collId, $app);
$out .= '<tr><td colspan="3" style="text-align:center;">' . $app->trans('login::register: acces authorise sur la collection') . phrasea::bas_labels($base_id, $app);
if (trim($isTrue) != '')
$out .= ' <a class="inscriptlink" href="/include/cguUtils.php?action=PRINT&bas=' . $sbasId . '&col=' . $collId . '">' . $app->trans('login::register::CGU: lire les CGU') . '</a>';
$out .= '</td></tr>';
}
$out .= '<tr style="height:5px;"><td></td></tr>';
}
if ($baseInsc['CollsRefuse']) {
foreach ($baseInsc['CollsRefuse'] as $collId => $isTrue) {
$base_id = phrasea::baseFromColl($sbasId, $collId, $app);
$out .= '<tr><td colspan="3" style="text-align:center;"><span style="color:red;">' . $app->trans('login::register: acces refuse sur la collection') . phrasea::bas_labels($base_id, $app) . '</span>';
if (trim($isTrue) != '')
$out .= ' <a class="inscriptlink" href="/include/cguUtils.php?action=PRINT&bas=' . $sbasId . '&col=' . $collId . '">' . $app->trans('login::register::CGU: lire les CGU') . '</a>';
$out .= '</td></tr>';
}
$out .= '<tr style="height:5px;"><td></td></tr>';
}
if ($baseInsc['CollsWait']) {
foreach ($baseInsc['CollsWait'] as $collId => $isTrue) {
$base_id = phrasea::baseFromColl($sbasId, $collId, $app);
$out .= '<tr><td colspan="3" style="text-align:center;"><span style="color:orange;">' . $app->trans('login::register: en attente d\'acces sur') . ' ' . phrasea::bas_labels($base_id, $app) . '</span>';
if (trim($isTrue) != '')
$out .= ' <a class="inscriptlink" href="/include/cguUtils.php?action=PRINT&bas=' . $sbasId . '&col=' . $collId . '">' . $app->trans('login::register::CGU: lire les CGU') . '</a>';
$out .= '</td></tr>';
}
$out .= '<tr style="height:5px;"><td></td></tr>';
}
if ($baseInsc['CollsIntime']) {
foreach ($baseInsc['CollsIntime'] as $collId => $isTrue) {
$base_id = phrasea::baseFromColl($sbasId, $collId, $app);
$out .= '<tr><td colspan="3" style="text-align:center;">' . $app->trans('login::register: acces temporaire sur') . phrasea::bas_labels($base_id, $app) . '</span>';
if (trim($isTrue) != '')
$out .= ' <a class="inscriptlink" href="/include/cguUtils.php?action=PRINT&bas=' . $sbasId . '&col=' . $collId . '">' . $app->trans('login::register::CGU: lire les CGU') . '</a>';
$out .= '</td></tr>';
}
$out .= '<tr style="height:5px;"><td></td></tr>';
}
if ($baseInsc['CollsOuttime']) {
foreach ($baseInsc['CollsOuttime'] as $collId => $isTrue) {
$base_id = phrasea::baseFromColl($sbasId, $collId, $app);
$out .= '<tr><td colspan="3" style="text-align:center;"><span style="color:red;">' . $app->trans('login::register: acces temporaire termine sur') . phrasea::bas_labels($base_id, $app) . '</span>';
if (trim($isTrue) != '')
$out .= ' <a class="inscriptlink" href="/include/cguUtils.php?action=PRINT&bas=' . $sbasId . '&col=' . $collId . '">' . $app->trans('login::register::CGU: lire les CGU') . '</a>';
$out .= '</td></tr>';
}
$out .= '<tr style="height:5px;"><td></td></tr>';
}
if ($baseInsc['CollsNonactif']) {
foreach ($baseInsc['CollsNonactif'] as $collId => $isTrue) {
$base_id = phrasea::baseFromColl($sbasId, $collId, $app);
$out .= '<tr><td colspan="3" style="text-align:center;"><span style="color:red;">' . $app->trans('login::register: acces supendu sur') . phrasea::bas_labels($base_id, $app) . '</span>';
if (trim($isTrue) != '')
$out .= ' <a class="inscriptlink" href="/include/cguUtils.php?action=PRINT&bas=' . $sbasId . '&col=' . $collId . '">' . $app->trans('login::register::CGU: lire les CGU') . '</a>';
$out .= '</td></tr>';
}
$out .= '<tr style="height:5px;"><td></td></tr>';
}
$out .= '<tr style="height:5px;"><td></td></tr>';
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 .= '<tr><td colspan="3" style="text-align:center;">' . $app->trans('login::register: L\'acces aux bases ci-dessous implique l\'acceptation des Conditions Generales d\'Utilisation (CGU) suivantes') . '</td></tr>';
$out .= '<tr><td colspan="3" style="text-align:center;"><div style="width:90%;height:120px;text-align:left;overflow:auto;">' . $baseInsc['CGU'] . '</div></td></tr>';
}
foreach ($baseInsc['Colls'] as $collId => $collName) {
$base_id = phrasea::baseFromColl($sbasId, $collId, $app);
$out .= '<tr>' .
'<td style="text-align:right;">' . $collName . '</td>' .
'<td></td>' .
'<td class="TD_R" style="width:200px;">' .
'<input style="width:15px;" class="checkbox" type="checkbox" name="demand[]" value="' . $base_id . '" >' .
'<span>' . $app->trans('login::register: Faire une demande d\'acces') . '</span>' .
'</td>' .
'</tr>';
}
}
if ($baseInsc['CollsCGU']) {
foreach ($baseInsc['CollsCGU'] as $collId => $collDesc) {
$base_id = phrasea::baseFromColl($sbasId, $collId, $app);
$out .= '<tr><td colspan="3" style="text-align:center;"><hr style="width:80%"/></td></tr>' .
'<tr><td colspan="3" style="text-align:center;">' . $app->trans('login::register: L\'acces aux bases ci-dessous implique l\'acceptation des Conditions Generales d\'Utilisation (CGU) suivantes') . '</td></tr>' .
'<tr>' .
'<td colspan="3" style="text-align:center;">' .
'<div style="width:90%;height:120px;text-align:left;overflow:auto;">' . $collDesc['CGU'] . '</div>' .
'</td>' .
'</tr>' .
'<tr >' .
'<td style="text-align:right;">' . $collDesc['name'] . '</td>' .
'<td></td>' .
'<td class="TD_R" style="width:200px;">' .
'<input style="width:15px;" class="checkbox" type="checkbox" name="demand[]" value="' . $base_id . '" >' .
'<span>' . $app->trans('login::register: Faire une demande d\'acces') . '</span>' .
'</td>' .
'</tr>';
}
}
}
}
$out .= '</table>';
return ['tab' => $out, 'demandes' => $noDemand];
}

View File

@@ -193,7 +193,7 @@ class eventsmanager_notify_autoregister extends eventsmanager_notifyAbstract
*/
public function is_available($usr_id)
{
if (!$this->app['registration.enabled']) {
if (! $this->app['registration.manager']->isRegistrationEnabled()) {
return false;
}

View File

@@ -38,13 +38,10 @@ class eventsmanager_notify_register extends eventsmanager_notifyAbstract
*/
public function fire($event, $params, &$object)
{
$default = [
'usr_id' => ''
, 'demand' => []
];
$default = ['usr_id' => '', 'registrations' => []];
$params = array_merge($default, $params);
$base_ids = $params['demand'];
$base_ids = $params['registrations'];
if (count($base_ids) == 0) {
return;
@@ -79,7 +76,7 @@ class eventsmanager_notify_register extends eventsmanager_notifyAbstract
$usr_id->appendChild($dom_xml->createTextNode($params['usr_id']));
foreach ($params['demand'] as $base_id => $is_ok) {
foreach ($params['registrations'] as $base_id => $is_ok) {
$base_id_node = $dom_xml->createElement('base_id');
$base_id_node->appendChild($dom_xml->createTextNode($base_id));
$base_ids->appendChild($base_id_node);
@@ -176,7 +173,7 @@ class eventsmanager_notify_register extends eventsmanager_notifyAbstract
*/
public function is_available($usr_id)
{
if (!$this->app['registration.enabled']) {
if (!$this->app['registration.manager']->isRegistrationEnabled()) {
return false;
}

View File

@@ -0,0 +1,122 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2014 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
use Alchemy\Phrasea\Application;
use Alchemy\Phrasea\Model\Entities\Registration;
use Doctrine\ORM\NoResultException;
use Doctrine\ORM\Query;
use Doctrine\ORM\Query\ResultSetMapping;
class patch_390alpha13a implements patchInterface
{
/** @var string */
private $release = '3.9.0-alpha.13';
/** @var array */
private $concern = [base::APPLICATION_BOX];
/**
* {@inheritdoc}
*/
public function get_release()
{
return $this->release;
}
/**
* {@inheritdoc}
*/
public function require_all_upgrades()
{
return false;
}
/**
* {@inheritdoc}
*/
public function concern()
{
return $this->concern;
}
/**
* {@inheritdoc}
*/
public function getDoctrineMigrations()
{
return ['registration'];
}
/**
* {@inheritdoc}
*/
public function apply(base $appbox, Application $app)
{
$em = $app['EM'];
$sql = "SELECT date_modif, usr_id, base_id, en_cours, refuser
FROM demand";
$rsm = new ResultSetMapping();
$rsm->addScalarResult('base_id','base_id');
$rsm->addScalarResult('en_cours','en_cours');
$rsm->addScalarResult('refuser','refuser');
$rsm->addScalarResult('usr_id', 'usr_id');
$rsm->addScalarResult('date_modif', 'date_modif');
$rs = $em->createNativeQuery($sql, $rsm)->getResult();
$n = 0;
foreach ($rs as $row) {
try {
$user = $em->createQuery('SELECT PARTIAL u.{id} FROM Phraseanet:User s WHERE u.id = :id')
->setParameters(['id' => $row['usr_id']])
->setHint(Query::HINT_FORCE_PARTIAL_LOAD, true)
->getSingleResult();
} catch (NoResultException $e) {
$app['monolog']->addInfo(sprintf(
'Patch %s : Registration for user (%s) could not be turn into doctrine entity as user could not be found.',
$this->get_release(),
$row['usr_id']
));
continue;
}
try {
$collection = \collection::get_from_base_id($app, $row['base_id']);
} catch (\Exception $e) {
$app['monolog']->addInfo(sprintf(
'Patch %s : Registration for user (%s) could not be turn into doctrine entity as base with id (%s) could not be found.',
$this->get_release(),
$row['usr_id'],
$row['base_id']
));
continue;
}
$registration = new Registration();
$registration->setCollection($collection);
$registration->setUser($user);
$registration->setPending($row['en_cours']);
$registration->setCreated(new \DateTime($row['date_modif']));
$registration->setRejected($row['refuser']);
if ($n % 100 === 0) {
$em->flush();
$em->clear();
}
$n++;
}
$em->flush();
$em->clear();
}
}

View File

@@ -371,7 +371,7 @@ class record_preview extends record_adapter
[
'final' => []
, 'comment' => []
, 'user' => $this->app['manipulator.user']->getRepository()->find($row['usr_id'])
, 'user' => $row['usr_id'] ? $this->app['manipulator.user']->getRepository()->find($row['usr_id']) : null
];
}

View File

@@ -54,3 +54,6 @@ migrations:
migration17:
version: user-auth-provider
class: Alchemy\Phrasea\Setup\DoctrineMigrations\UserAuthProviderMigration
migration18:
version: registration
class: Alchemy\Phrasea\Setup\DoctrineMigrations\RegistrationMigration

View File

@@ -14,42 +14,19 @@
<td width="15px" style="width: 15px">&nbsp;</td>
<td style="width: 180px;">&nbsp;</td>
</tr>
{% 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"] %}
<tr>
<td colspan="3" style="text-align: center;"><h3>{{ sbasId | sbas_labels(app) }}</h3></td>
</tr>
{% 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) %}
<tr>
<td colspan="3" style="text-align:center;">
{{ "login::register: acces authorise sur la collection" | trans }}{{ sbasId |sbas_labels(app) }}
{% if isTrue | trim != "" %}
<a class="inscriptlink" href="{{ path('get_tou', {'to_display[]' : sbasId}) }}">{{ "login::register::CGU: lire les CGU" | trans }}</a>
{% endif %}
</td>
</tr>
{% endfor %}
{% endfor %}
<tr style="height: 5px;">
<td>
</td>
</tr>
{% 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) %}
<tr>
<td colspan="3" style="text-align: center;"><h3>{{ sbasName }}</h3></td>
</tr>
{% if baseInfo["registrations"]["by-type"]["accepted"]|length > 0 %}
{% for baseId in baseInfo["registrations"]["by-type"]["accepted"] %}
<tr>
<td colspan="3" style="text-align: center;">
<span style="color: red;">{{ "login::register: acces refuse sur la collection" | trans }}{{ sbasId |sbas_labels(app) }}</span>
{% if isTrue | trim != "" %}
<a class="inscriptlink" href="{{ path('get_tou', {'to_display[]' : sbasId}) }}">{{ "login::register::CGU: lire les CGU" | trans }}</a>
{% endif %}
<td colspan="3" style="text-align:center;">
{{ "login::register: acces authorise sur la collection" | trans }}{{ sbasName }}
<a class="inscriptlink" href="{{ path('get_tou', {'to_display[]' : sbasId}) }}">
{{ "login::register::CGU: lire les CGU" | trans }}
</a>
</td>
</tr>
{% endfor %}
@@ -58,114 +35,116 @@
</td>
</tr>
{% endif %}
{% if baseInsc["CollsWait"] %}
{% for collId, isTrue in baseInsc["CollsWait"] %}
{% set base_id = sbasId |base_from_coll(collId, app) %}
{% if baseInfo["registrations"]["by-type"]["rejected"]|length > 0 %}
{% for baseId in baseInfo["registrations"]["by-type"]["rejected"] %}
<tr>
<td colspan="3" style="text-align: center;">
<td colspan="3" style="text-align:center;">
<span style="color: red;">{{ "login::register: acces refuse sur la collection" | trans }}{{ sbasName }}
<a class="inscriptlink" href="{{ path('get_tou', {'to_display[]' : sbasId}) }}">
{{ "login::register::CGU: lire les CGU" | trans }}
</a>
</td>
</tr>
{% endfor %}
<tr style="height: 5px;">
<td>
</td>
</tr>
{% endif %}
{% if baseInfo["registrations"]["by-type"]["pending"]|length > 0 %}
{% for baseId in baseInfo["registrations"]["by-type"]["pending"] %}
<tr>
<td colspan="3" style="text-align:center;">
<span style="color: orange;">{{ "login::register: en attente d\'acces sur" | trans }} {{ sbasId |sbas_labels(app) }}</span>
{% if isTrue | trim != "" %}
<a class="inscriptlink" href="{{ path('get_tou', {'to_display[]' : sbasId}) }}">{{ "login::register::CGU: lire les CGU" | trans }}</a>
{% endif %}
<a class="inscriptlink" href="{{ path('get_tou', {'to_display[]' : sbasId}) }}">
{{ "login::register::CGU: lire les CGU" | trans }}
</a>
</td>
</tr>
{% endfor %}
<tr style="height: 5px;"><td></td></tr>
<tr style="height: 5px;">
<td>
</td>
</tr>
{% endif %}
{% if baseInsc["CollsIntime"] %}
{% for collId, isTrue in baseInsc["CollsIntime"] %}
{% set base_id = sbasId |base_from_coll(collId, app) %}
{% if baseInfo["registrations"]["by-type"]["in-time"]|length > 0 %}
{% for baseId in baseInfo["registrations"]["by-type"]["in-time"] %}
<tr>
<td colspan="3" style="text-align: center;">
<td colspan="3" style="text-align:center;">
<span>{{ "login::register: acces temporaire sur" | trans }} {{ sbasId |sbas_labels(app) }}</span>
{% if isTrue |trim != "" %}
<a class="inscriptlink" href="{{ path('get_tou', {'to_display[]' : sbasId}) }}">{{ "login::register::CGU: lire les CGU" | trans }}</a>
{% endif %}
<a class="inscriptlink" href="{{ path('get_tou', {'to_display[]' : sbasId}) }}">
{{ "login::register::CGU: lire les CGU" | trans }}
</a>
</td>
</tr>
{% endfor %}
<tr style="height: 5px;"><td></td></tr>
<tr style="height: 5px;">
<td>
</td>
</tr>
{% endif %}
{% if baseInsc["CollsOuttime"] %}
{% for collId, isTrue in baseInsc["CollsOuttime"] %}
{% set base_id = sbasId |base_from_coll(collId, app) %}
{% if baseInfo["registrations"]["by-type"]["out-dated"]|length > 0 %}
{% for baseId in baseInfo["registrations"]["by-type"]["out-dated"] %}
<tr>
<td colspan="3" style="text-align: center;">
<td colspan="3" style="text-align:center;">
<span style="color:red;">{{ "login::register: acces temporaire termine sur" | trans }}{{ sbasId |sbas_labels(app) }}</span>
{% if isTrue |trim != "" %}
<a class="inscriptlink" href="{{ path('get_tou', {'to_display[]' : sbasId}) }}">{{ "login::register::CGU: lire les CGU" | trans }}</a>
{% endif %}
<a class="inscriptlink" href="{{ path('get_tou', {'to_display[]' : sbasId}) }}">
{{ "login::register::CGU: lire les CGU" | trans }}
</a>
</td>
</tr>
{% endfor %}
<tr style="height: 5px;"><td></td></tr>
<tr style="height: 5px;">
<td>
</td>
</tr>
{% endif %}
{% if baseInsc["CollsNonactif"] %}
{% for collId, isTrue in baseInsc["CollsNonactif"] %}
{% set base_id = sbasId |base_from_coll(collId, app) %}
{% if baseInfo["registrations"]["by-type"]["inactive"]|length > 0 %}
{% for baseId in baseInfo["registrations"]["by-type"]["inactive"] %}
<tr>
<td colspan="3" style="text-align: center;">
<td colspan="3" style="text-align:center;">
<span style="color:red;">{{ "login::register: acces supendu sur" | trans }} {{ sbasId |sbas_labels(app) }}</span>
{% if isTrue |trim != "" %}
<a class="inscriptlink" href="{{ path('get_tou', {'to_display[]' : sbasId}) }}">{{ "login::register::CGU: lire les CGU" | trans }}</a>
{% endif %}
<a class="inscriptlink" href="{{ path('get_tou', {'to_display[]' : sbasId}) }}">
{{ "login::register::CGU: lire les CGU" | trans }}
</a>
</td>
</tr>
{% endfor %}
<tr style="height: 5px;"><td></td></tr>
<tr style="height: 5px;">
<td>
</td>
</tr>
{% endif %}
{% endfor %}
{% if (baseInsc["CollsCGU"] or baseInsc["Colls"]) and baseInsc["inscript"] %}
{% if baseInsc["Colls"] %}
{% if baseInsc["CGU"] %}
<tr>
<td colspan="3" style="text-align: center;">{{ "login::register: L\'acces aux bases ci-dessous implique l\'acceptation des Conditions Generales d\'Utilisation (CGU) suivantes" | trans }}</td>
</tr>
<tr>
<td colspan="3" style="text-align: center;"><div style="width: 90%; height: 120px; text-align: left; overflow: auto;">{{ baseInsc["CGU"] }}</div></td>
</tr>
{% endif %}
{% for collId, collName in baseInsc["Colls"] %}
{% set base_id = sbasId |base_from_coll(collId, app) %}
<tr>
<td style="text-align: right;">{{ collName }}</td>
<td></td>
<td class="TD_R" style="width: 200px;">
<input style="width: 15px;" class="checkbox" type="checkbox" name="demand[]" value="{{ base_id }}" />
<span>{{ "login::register: Faire une demande d\'acces" | trans }}</span>
</td>
</tr>
{% endfor %}
{% endif %}
{% if baseInsc["CollsCGU"] %}
{% for collId, collDesc in baseInsc["CollsCGU"] %}
{% set base_id = sbasId |base_from_coll(collId, app) %}
<tr>
<td colspan="3" style="text-align: center;"><hr style="width: 80%"/></td>
</tr>
<tr>
<td colspan="3" style="text-align: center;">{{ "login::register: L\'acces aux bases ci-dessous implique l\'acceptation des Conditions Generales d\'Utilisation (CGU) suivantes" | trans }}</td>
</tr>
<tr>
<td colspan="3" style="text-align: center;">
<div style="width: 90%; height: 120px; text-align: left; overflow: auto;">{{ collDesc["CGU"] }}</div>
</td>
</tr>
<tr>
<td style="text-align: right;">{{ collDesc["name"] }}</td>
<td></td>
<td class="TD_R" style="width: 200px;">
<input style="width: 15px;" class="checkbox" type="checkbox" name="demand[]" value="{{ base_id }}" />
<span>{{ "login::register: Faire une demande d\'acces" | trans }}</span>
</td>
</tr>
{% endfor %}
{% endif %}
{% for sbasId, baseInfo in inscriptions %}
{% if baseInfo["config"]["cgu"] is not none %}
<tr>
<td colspan="3" style="text-align: center;">{{ "login::register: L\'acces aux bases ci-dessous implique l\'acceptation des Conditions Generales d\'Utilisation (CGU) suivantes" | trans }}</td>
</tr>
<tr>
<td colspan="3" style="text-align: center;"><div style="width: 90%; height: 120px; text-align: left; overflow: auto;">{{ baseInfo["config"]["cgu"] }}</div></td>
</tr>
{% endif %}
{% for baseId, collInfo in baseInfo["config"]["collections"] if (collInfo['registration'] is none and collInfo['can-register']) %}
{% if collInfo["cgu"] is not none %}
<tr>
<td colspan="3" style="text-align: center;">{{ "login::register: L\'acces aux bases ci-dessous implique l\'acceptation des Conditions Generales d\'Utilisation (CGU) suivantes" | trans }}</td>
</tr>
<tr>
<td colspan="3" style="text-align: center;"><div style="width: 90%; height: 120px; text-align: left; overflow: auto;">{{ baseInsc["CGU"] }}</div></td>
</tr>
{% endif %}
<tr>
<td style="text-align: right;">{{ collInfo["coll-name"] }}</td>
<td></td>
<td class="TD_R" style="width: 200px;">
<input style="width: 15px;" class="checkbox" type="checkbox" name="registrations[]" value="{{ baseId }}" />
<span>{{ "login::register: Faire une demande d\'acces" | trans }}</span>
</td>
</tr>
{% endfor %}
{% endfor %}
</table>
<div class="form-actions">

View File

@@ -44,7 +44,7 @@
</a>
</li>
<li class="{% if feature == 'registrations' %}selected{% endif %}">
<a target="right" href="{{ path('users_display_demands') }}" class="ajax">
<a target="right" href="{{ path('users_display_registrations') }}" class="ajax">
<img src="/skins/admin/Demandes.png" />
<span>{{ 'admin::utilisateurs: demandes en cours' | trans }}</span>
</a>

View File

@@ -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 @@
</div>
{% endif %}
{% if table['users'] | length > 0 %}
<form id="accept-demand" action="{{ path('users_submit_demands') }}" method="post">
{% if user_registrations | length > 0 %}
<form id="accept-registration" action="{{ path('users_submit_registrations') }}" method="post">
<div class="btn-group btn-all-action">
<button data-event="deny" class="btn deny-checker" type="button">
<img title="{{ 'admin:: refuser l\'acces' | trans }}" src="/skins/icons/delete.gif"/>
@@ -200,20 +200,13 @@
</table>
<div class="registration-wrapper PNB" style="top:160px;bottom: 50px;overflow: auto">
<div id="tab_demandes">
{% set tableColls = table['coll'] %}
{% for row in table['users'] %}
{% set user = row['user'] %}
<div id="registrations">
{% for user_registration in user_registrations %}
{% set user = user_registration['user'] %}
<div class="well well-small">
<table class="table" style="table-layout: fixed;">
<tr>
<span>
{{ app['date-formatter'].getPrettyString(row["date_demand"]) }}
</span>
</tr>
<tr>
<td>
{% set colls = tableColls[user.getId()] %}
<dl class="dl-horizontal">
<dt>{{ 'admin::compte-utilisateur identifiant' | trans }}</dt>
<dd>{{ user.getLogin() }}</dd>
@@ -237,7 +230,10 @@
</dl>
</td>
<td>
{% for basId in colls %}
{% for basId, registration in user_registration['registrations'] %}
<div>
{{ app['date-formatter'].getPrettyString(registration.getUpdated()) }}
</div>
<span style="font-weight:bold;font-size:14px;word-wrap: break-word;">
{{ basId| bas_labels(app) }}
</span>

View File

@@ -366,32 +366,18 @@ class UsersTest extends \PhraseanetAuthenticatedWebTestCase
self::$DI['app']['manipulator.user']->delete($user);
}
public function testRenderDemands()
public function testRenderRegistrations()
{
$nativeQueryMock = $this->getMockBuilder('Alchemy\Phrasea\Model\NativeQueryProvider')
->disableOriginalConstructor()
->getMock();
$nativeQueryMock->expects($this->once())->method('getUsersRegistrationDemand')->will($this->returnValue([[
self::$DI['user'],
'date_demand' => new \DateTime(),
'base_demand' => 1
]]));
self::$DI['app']['EM.native-query'] = $nativeQueryMock;
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())
@@ -420,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],
@@ -428,7 +414,6 @@ class UsersTest extends \PhraseanetAuthenticatedWebTestCase
]);
self::$DI['app']['phraseanet.appbox'] = $appbox;
$this->assertTrue(self::$DI['client']->getResponse()->isRedirect());
}

View File

@@ -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');

View File

@@ -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 . '/';

View File

@@ -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;
@@ -47,10 +48,53 @@ class AccountTest extends \PhraseanetAuthenticatedWebTestCase
*/
public function testGetAccountAccess()
{
$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,
'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
]
],
]
]
];
$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['client']->request('GET', '/account/access/');
$response = self::$DI['client']->getResponse();
$this->assertTrue($response->isOk());
}
@@ -276,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',
@@ -303,11 +347,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('Phraseanet:Registration')->findBy([
'user' => self::$DI['app']['authentication']->getUser()->getId(),
'pending' => true
]);
$this->assertCount(count($bases), $rs);
}

View File

@@ -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\Registration;
use Alchemy\Phrasea\Model\Entities\User;
use Symfony\Component\HttpKernel\Client;
use Symfony\Component\HttpFoundation\ResponseHeaderBag;
@@ -16,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;
@@ -26,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()];
@@ -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,8 @@ class LoginTest extends \PhraseanetAuthenticatedWebTestCase
if (null === self::$email) {
self::$email = self::$DI['user']->getEmail();
}
$this->enableRegistration();
}
public function tearDown()
@@ -55,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();
}
@@ -208,7 +210,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']);
$registration = new Registration();
$registration->setUser(self::$DI['user']);
$registration->setBaseId(self::$DI['collection']->get_base_id());
self::$DI['app']['EM']->persist($registration);
self::$DI['app']['EM']->flush();
self::$DI['client']->request('GET', '/login/register-confirm/', ['code' => $token]);
$response = self::$DI['client']->getResponse();
@@ -470,7 +478,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 +490,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');
@@ -529,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());
@@ -538,8 +544,9 @@ 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;
self::$DI['app']['registration.fields'] = $extraParameters;
@@ -548,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;
@@ -571,7 +578,9 @@ 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());
$this->assertFormOrFlashError($crawler, self::$DI['app']['conf']->get(['registry', 'registration', 'auto-select-collections']) ? 6 : 7);
}
@@ -585,6 +594,7 @@ class LoginTest extends \PhraseanetAuthenticatedWebTestCase
'confirm' => 'password'
],
"collections" => null,
"accept-tou" => '1'
], [], 1],
[[//required extra-field missing
"password" => [
@@ -592,7 +602,8 @@ class LoginTest extends \PhraseanetAuthenticatedWebTestCase
'confirm' => 'password'
],
"email" => $this->generateEmail(),
"collections" => null
"collections" => null,
"accept-tou" => '1'
], [
[
'name' => 'login',
@@ -605,7 +616,8 @@ class LoginTest extends \PhraseanetAuthenticatedWebTestCase
'confirm' => 'passwordMismatch'
],
"email" => $this->generateEmail(),
"collections" => null
"collections" => null,
"accept-tou" => '1'
], [], 1],
[[//password tooshort
"password" => [
@@ -613,7 +625,8 @@ class LoginTest extends \PhraseanetAuthenticatedWebTestCase
'confirm' => 'min'
],
"email" => $this->generateEmail(),
"collections" => null
"collections" => null,
"accept-tou" => '1'
], [], 1],
[[//email invalid
"password" => [
@@ -621,7 +634,8 @@ class LoginTest extends \PhraseanetAuthenticatedWebTestCase
'confirm' => 'password'
],
"email" => 'invalid.email',
"collections" => null
"collections" => null,
"accept-tou" => '1'
], [], 1],
[[//login exists
"login" => null,
@@ -630,7 +644,8 @@ class LoginTest extends \PhraseanetAuthenticatedWebTestCase
'confirm' => 'password'
],
"email" => $this->generateEmail(),
"collections" => null
"collections" => null,
"accept-tou" => '1'
], [
[
'name' => 'login',
@@ -643,7 +658,8 @@ class LoginTest extends \PhraseanetAuthenticatedWebTestCase
'confirm' => 'password'
],
"email" => null,
"collections" => null
"collections" => null,
"accept-tou" => '1'
], [], 1],
[[//tou declined
"password" => [
@@ -651,8 +667,7 @@ class LoginTest extends \PhraseanetAuthenticatedWebTestCase
'confirm' => 'password'
],
"email" => $this->generateEmail(),
"collections" => null,
"accept-tou" => '1'
"collections" => null
], [], 1]
];
}
@@ -842,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;
@@ -875,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;
@@ -917,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;
@@ -938,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,
@@ -993,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;
@@ -1045,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,
@@ -1058,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;
@@ -1599,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);
@@ -1626,8 +1642,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/');
@@ -1641,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())
@@ -1669,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()
@@ -1773,15 +1783,14 @@ 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()
{
$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 Phraseanet:Registration d WHERE d.user=?1');
$query->setParameter(1, self::$DI['user']->getId());
$query->execute();
}
/**
@@ -1809,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);
}
}
}
@@ -1838,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));
}
}

View File

@@ -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);
}
/**

View File

@@ -0,0 +1,179 @@
<?php
namespace Alchemy\Tests\Phrasea\Core\Configuration;
use Alchemy\Phrasea\Application;
use Alchemy\Phrasea\Model\Entities\Registration;
use Alchemy\Phrasea\Model\Entities\User;
use Alchemy\Phrasea\Core\Configuration\RegistrationManager;
class RegistrationManagerTest extends \PhraseanetTestCase
{
/**
* @dataProvider getRegistrationProvider
*/
public function testRegistrationIsEnabled($enabledOnColl, $expected)
{
$mockColl = $this->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
];
}
}

View File

@@ -17,6 +17,11 @@ class ManipulatorServiceProviderTest extends ServiceProviderTestCase
'manipulator.acl',
'Alchemy\Phrasea\Model\Manipulator\ACLManipulator'
],
[
'Alchemy\Phrasea\Core\Provider\ManipulatorServiceProvider',
'manipulator.registration',
'Alchemy\Phrasea\Model\Manipulator\RegistrationManipulator'
],
];
}
}

View File

@@ -7,7 +7,7 @@ use Alchemy\Phrasea\Core\Provider\RegistrationServiceProvider;
/**
* @covers Alchemy\Phrasea\Core\Provider\RegistrationServiceProvider
*/
class RegistrationServiceProviderTest extends \PhraseanetTestCase
class RegistrationServiceProviderTest extends ServiceProviderTestCase
{
private $fields;
@@ -33,4 +33,11 @@ class RegistrationServiceProviderTest extends \PhraseanetTestCase
$this->assertInternalType('array', self::$DI['app']['registration.optional-fields']);
}
public function provideServiceDescription()
{
return [
['Alchemy\Phrasea\Core\Provider\RegistrationServiceProvider', 'registration.manager', 'Alchemy\Phrasea\Core\Configuration\RegistrationManager'],
];
}
}

View File

@@ -0,0 +1,88 @@
<?php
namespace Alchemy\Tests\Phrasea\Registration;
use Alchemy\Phrasea\Model\Entities\Registration;
use Alchemy\Phrasea\Model\Manipulator\RegistrationManipulator;
class RegistrationManipulatorTest extends \PhraseanetTestCase
{
public function testCreateRegistration()
{
$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']->getId(), $registration->getUser()->getId());
}
public function testRejectRegistration()
{
$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());
}
public function testAcceptRegistration()
{
$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([
'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->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'], 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']->getId())
->getQuery()
->getSingleScalarResult();
$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'], 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->deleteOldRegistrations();
$nbRegistrationAfter = $qb->getQuery()->getSingleScalarResult();
$this->assertGreaterThan($nbRegistrationAfter, $nbRegistrationBefore);
}
public function testDeleteRegistrationOnCollection()
{
$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']);
$nbRegistrationAfter = $qb->getQuery()->getSingleScalarResult();
$this->assertGreaterThan($nbRegistrationAfter, $nbRegistrationBefore);
}
}

View File

@@ -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));
}
}

View File

@@ -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']);
});

View File

@@ -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 =
<<<XML
<?xml version="1.0" encoding="UTF-8"?>
<baseprefs><caninscript>1</caninscript>1</baseprefs>
XML;
$xmlNoInscript =
<<<XML
<?xml version="1.0" encoding="UTF-8"?>
<baseprefs><caninscript>0</caninscript>1</baseprefs>
XML;
$xmlNoInscriptEmpty =
<<<XML
<?xml version="1.0" encoding="UTF-8"?>
<baseprefs><caninscript></caninscript></baseprefs>
XML;
return [
[$xmlInscript, true],
[$xmlNoInscript, false],
[$xmlNoInscriptEmpty, false],
];
}
}

View File

@@ -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 =
<<<XML
<?xml version="1.0" encoding="UTF-8"?>
<record><caninscript>1</caninscript>1</record>
XML;
$xmlNoInscript =
<<<XML
<?xml version="1.0" encoding="UTF-8"?>
<record><caninscript>0</caninscript>1</record>
XML;
$xmlNoInscriptEmpty =
<<<XML
<?xml version="1.0" encoding="UTF-8"?>
<record><caninscript></caninscript></record>
XML;
return [
[simplexml_load_string($xmlInscript), true],
[simplexml_load_string($xmlNoInscript), false],
[simplexml_load_string($xmlNoInscriptEmpty), false],
];
}
}

View File

@@ -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;
}