diff --git a/composer.json b/composer.json index 6a0d9d964d..f874661edc 100644 --- a/composer.json +++ b/composer.json @@ -10,26 +10,28 @@ "type": "vcs", "url": "https://github.com/alchemy-fr/tcpdf-clone" }, - { "type": "git", "url": "https://github.com/romainneutron/ProcessManager.git" - }, - { - "type": "vcs", - "url": "https://github.com/alchemy-fr/imagine" - }, - { - "type": "vcs", - "url": "https://github.com/alchemy-fr/JMSTranslationBundle" - }, - { - "type": "git", - "url": "https://github.com/bburnichon/fractal.git" - } - ], - "require": { - "php": ">=5.5.9", - "ext-intl": "*", + { + "type": "vcs", + "url": "https://github.com/alchemy-fr/imagine" + }, + { + "type": "vcs", + "url": "https://github.com/alchemy-fr/JMSTranslationBundle" + }, + { + "type": "vcs", + "url": "https://github.com/alchemy-fr/embed-bundle.git" + }, + { + "type": "git", + "url": "https://github.com/alchemy-fr/fractal.git" + } + ], + "require": { + "php": ">=5.5.9", + "ext-intl": "*", "alchemy-fr/tcpdf-clone": "~6.0", "alchemy/embed-bundle": "^0.4.1", "alchemy/geonames-api-consumer": "~0.1.0", diff --git a/lib/Alchemy/Phrasea/Application.php b/lib/Alchemy/Phrasea/Application.php index e680a0bd79..bba5aae23e 100644 --- a/lib/Alchemy/Phrasea/Application.php +++ b/lib/Alchemy/Phrasea/Application.php @@ -544,6 +544,7 @@ class Application extends SilexApplication $this['root.path'] = realpath(__DIR__ . '/../../..'); // temporary resources default path such as download zip, quarantined documents etc .. $this['tmp.path'] = getenv('PHRASEANET_TMP') ?: $this['root.path'].'/tmp'; + // plugin path $this['plugin.path'] = $this['root.path'].'/plugins'; // thumbnails path diff --git a/lib/Alchemy/Phrasea/Collection/CollectionService.php b/lib/Alchemy/Phrasea/Collection/CollectionService.php index 238aad9b47..acc1db6772 100644 --- a/lib/Alchemy/Phrasea/Collection/CollectionService.php +++ b/lib/Alchemy/Phrasea/Collection/CollectionService.php @@ -267,27 +267,28 @@ class CollectionService */ public function grantAdminRights(CollectionReference $reference, User $user) { - $rights = [ - "canputinalbum" => "1", - "candwnldhd" => "1", - "nowatermark" => "1", - "candwnldpreview" => "1", - "cancmd" => "1", - "canadmin" => "1", - "actif" => "1", - "canreport" => "1", - "canpush" => "1", - "basusr_infousr" => "", - "canaddrecord" => "1", - "canmodifrecord" => "1", - "candeleterecord" => "1", - "chgstatus" => "1", - "imgtools" => "1", - "manage" => "1", - "modify_struct" => "1" - ]; - - $this->app->getAclForUser($user)->update_rights_to_base($reference->getBaseId(), $rights); + $this->app->getAclForUser($user)->update_rights_to_base( + $reference->getBaseId(), + [ + "basusr_infousr" => "", // todo : wtf + \ACL::CANPUTINALBUM => true, + \ACL::CANDWNLDHD => true, + \ACL::NOWATERMARK => true, + \ACL::CANDWNLDPREVIEW => true, + \ACL::CANCMD => true, + \ACL::CANADMIN => true, + \ACL::ACTIF => true, + \ACL::CANREPORT => true, + \ACL::CANPUSH => true, + \ACL::CANADDRECORD => true, + \ACL::CANMODIFRECORD => true, + \ACL::CANDELETERECORD => true, + \ACL::CHGSTATUS => true, + \ACL::IMGTOOLS => true, + \ACL::COLL_MANAGE => true, + \ACL::COLL_MODIFY_STRUCT => true + ] + ); } public function setOrderMasters(CollectionReference $reference, array $userIds) @@ -317,18 +318,28 @@ class CollectionService $userQuery = $factory(); $result = $userQuery->on_base_ids([ $reference->getBaseId()] ) - ->who_have_right(['order_master']) + ->who_have_right([\ACL::ORDER_MASTER]) ->execute()->get_results(); /** @var ACLProvider $acl */ $acl = $this->app['acl']; foreach ($result as $user) { - $acl->get($user)->update_rights_to_base($reference->getBaseId(), ['order_master' => false]); + $acl->get($user)->update_rights_to_base( + $reference->getBaseId(), + [ + \ACL::ORDER_MASTER => false + ] + ); } foreach ($admins as $admin) { - $acl->get($admin)->update_rights_to_base($reference->getBaseId(), ['order_master' => true]); + $acl->get($admin)->update_rights_to_base( + $reference->getBaseId(), + [ + \ACL::ORDER_MASTER => true + ] + ); } $conn->commit(); diff --git a/lib/Alchemy/Phrasea/Command/BuildSubdefs.php b/lib/Alchemy/Phrasea/Command/BuildSubdefs.php index d3cd61bac1..530ad3aded 100644 --- a/lib/Alchemy/Phrasea/Command/BuildSubdefs.php +++ b/lib/Alchemy/Phrasea/Command/BuildSubdefs.php @@ -345,7 +345,9 @@ class BuildSubdefs extends Command while( ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) ) { $type = $row['type']; - $msg = sprintf(' record %s (%s) : ', $row['record_id'], $type); + $msg = []; + + $msg[] = sprintf(' record %s (%s) :', $row['record_id'], $type); try { $record = $this->databox->get_record($row['record_id']); @@ -366,7 +368,7 @@ class BuildSubdefs extends Command $subdef->delete(); } $subdefsDeleted[] = $name; - $msg .= sprintf(" \"%s\" deleted,", $name); + $msg[] = sprintf(" \"%s\" pruned", $name); } continue; } @@ -386,10 +388,14 @@ class BuildSubdefs extends Command continue; } } + // here an existing subdef must be (re)done - if(!$this->dry) { - $subdef->remove_file(); - $subdef->set_substituted(false); + if(isset($subdefNamesToDo[$name])) { + if (!$this->dry) { + $subdef->remove_file(); + $subdef->set_substituted(false); + } + $msg[] = sprintf(" [\"%s\"] deleted", $name); } } @@ -401,7 +407,7 @@ class BuildSubdefs extends Command $subdefGenerator->generateSubdefs($record, $subdefNamesToDo); } - $msg .= sprintf(" [\"%s\"] built", implode('","', $subdefNamesToDo)); + $msg[] = sprintf(" [\"%s\"] built", implode('","', $subdefNamesToDo)); } else { // $msg .= " nothing to build"; @@ -416,10 +422,10 @@ class BuildSubdefs extends Command . ' WHERE record_id=:record_id'; if($this->reset_subdef_flag) { - $msg .= ", jeton[\"make_subdef\"]=0"; + $msg[] = "jeton[\"make_subdef\"]=0"; } if($this->set_writemeta_flag) { - $msg .= ", jeton[\"write_met_subdef\"]=1"; + $msg[] = "jeton[\"write_met_subdef\"]=1"; } if(!$this->dry) { $this->connection->executeUpdate($sql, [ @@ -436,10 +442,10 @@ class BuildSubdefs extends Command if($progress) { $progress->advance(); - $this->output->write($msg); + $this->output->write(implode(' ', $msg)); } else { - $this->output->writeln($msg); + $this->output->writeln(implode("\n", $msg)); } } diff --git a/lib/Alchemy/Phrasea/Controller/Admin/CollectionController.php b/lib/Alchemy/Phrasea/Controller/Admin/CollectionController.php index 2ebe77a408..3304a19de8 100644 --- a/lib/Alchemy/Phrasea/Controller/Admin/CollectionController.php +++ b/lib/Alchemy/Phrasea/Controller/Admin/CollectionController.php @@ -46,10 +46,10 @@ class CollectionController extends Controller $admins = []; - if ($this->getAclForUser()->has_right_on_base($bas_id, 'manage')) { + if ($this->getAclForUser()->has_right_on_base($bas_id, \ACL::COLL_MANAGE)) { $query = $this->createUserQuery(); $admins = $query->on_base_ids([$bas_id]) - ->who_have_right(['order_master']) + ->who_have_right([\ACL::ORDER_MASTER]) ->execute() ->get_results(); } diff --git a/lib/Alchemy/Phrasea/Controller/Admin/DataboxesController.php b/lib/Alchemy/Phrasea/Controller/Admin/DataboxesController.php index 63e9a05cec..fee5eef475 100644 --- a/lib/Alchemy/Phrasea/Controller/Admin/DataboxesController.php +++ b/lib/Alchemy/Phrasea/Controller/Admin/DataboxesController.php @@ -31,8 +31,8 @@ class DataboxesController extends Controller { $acl = $this->getAclForUser(); $sbasIds = array_merge( - array_keys($acl->get_granted_sbas(['bas_manage'])), - array_keys($acl->get_granted_sbas(['bas_modify_struct'])) + array_keys($acl->get_granted_sbas([\ACL::BAS_MANAGE])), + array_keys($acl->get_granted_sbas([\ACL::BAS_MODIFY_STRUCT])) ); $sbas = []; diff --git a/lib/Alchemy/Phrasea/Controller/Admin/RootController.php b/lib/Alchemy/Phrasea/Controller/Admin/RootController.php index 901d2efc95..7683573b89 100644 --- a/lib/Alchemy/Phrasea/Controller/Admin/RootController.php +++ b/lib/Alchemy/Phrasea/Controller/Admin/RootController.php @@ -88,7 +88,7 @@ class RootController extends Controller */ public function displayStatusBitAction($databox_id) { - if (!$this->getAclForUser()->has_right_on_sbas($databox_id, 'bas_modify_struct')) { + if (!$this->getAclForUser()->has_right_on_sbas($databox_id, \ACL::BAS_MODIFY_STRUCT)) { $this->app->abort(403); } @@ -105,7 +105,7 @@ class RootController extends Controller */ public function displayDataboxStructureAction(Request $request, $databox_id) { - if (!$this->getAclForUser()->has_right_on_sbas($databox_id, 'bas_modify_struct')) { + if (!$this->getAclForUser()->has_right_on_sbas($databox_id, \ACL::BAS_MODIFY_STRUCT)) { $this->app->abort(403); } @@ -132,7 +132,7 @@ class RootController extends Controller public function submitDatabaseStructureAction(Request $request, $databox_id) { - if (!$this->getAclForUser()->has_right_on_sbas($databox_id, 'bas_modify_struct')) { + if (!$this->getAclForUser()->has_right_on_sbas($databox_id, \ACL::BAS_MODIFY_STRUCT)) { $this->app->abort(403); } @@ -162,7 +162,7 @@ class RootController extends Controller public function displayDatabaseStatusBitFormAction(Request $request, $databox_id, $bit) { - if (!$this->getAclForUser()->has_right_on_sbas($databox_id, 'bas_modify_struct')) { + if (!$this->getAclForUser()->has_right_on_sbas($databox_id, \ACL::BAS_MODIFY_STRUCT)) { $this->app->abort(403); } @@ -220,7 +220,7 @@ class RootController extends Controller $this->app->abort(400, $this->app->trans('Bad request format, only JSON is allowed')); } - if (!$this->getAclForUser()->has_right_on_sbas($databox_id, 'bas_modify_struct')) { + if (!$this->getAclForUser()->has_right_on_sbas($databox_id, \ACL::BAS_MODIFY_STRUCT)) { $this->app->abort(403); } @@ -238,7 +238,7 @@ class RootController extends Controller } public function submitStatusBitAction(Request $request, $databox_id, $bit) { - if (!$this->getAclForUser()->has_right_on_sbas($databox_id, 'bas_modify_struct')) { + if (!$this->getAclForUser()->has_right_on_sbas($databox_id, \ACL::BAS_MODIFY_STRUCT)) { $this->app->abort(403); } diff --git a/lib/Alchemy/Phrasea/Controller/Admin/SetupController.php b/lib/Alchemy/Phrasea/Controller/Admin/SetupController.php index a3738d8e91..0ca5c9f262 100644 --- a/lib/Alchemy/Phrasea/Controller/Admin/SetupController.php +++ b/lib/Alchemy/Phrasea/Controller/Admin/SetupController.php @@ -10,29 +10,43 @@ namespace Alchemy\Phrasea\Controller\Admin; +use Alchemy\Phrasea\Application; use Alchemy\Phrasea\Controller\Controller; -use Alchemy\Phrasea\Core\Configuration\Configuration; use Alchemy\Phrasea\Core\Configuration\PropertyAccess; -use Alchemy\Phrasea\Core\Configuration\RegistryManipulator; +use Alchemy\Phrasea\Core\Configuration\RegistryFormManipulator; use Symfony\Component\HttpFoundation\Request; class SetupController extends Controller { + /** + * @var RegistryFormManipulator + */ + private $registryFormManipulator; + + /** + * @var PropertyAccess + */ + private $configuration; + + public function __construct(Application $app, RegistryFormManipulator $registryFormManipulator, PropertyAccess $configuration) + { + parent::__construct($app); + + $this->registryFormManipulator = $registryFormManipulator; + $this->configuration = $configuration; + } + public function submitGlobalsAction(Request $request) { - /** @var RegistryManipulator $manipulator */ - $manipulator = $this->app['registry.manipulator']; - /** @var PropertyAccess $config */ - $config = $this->app['conf']; - - $form = $manipulator->createForm($this->app['conf']); + $form = $this->registryFormManipulator->createForm(); if ('POST' === $request->getMethod()) { $form->submit($request->request->all()); - if ($form->isValid()) { - $config->set('registry', $manipulator->getRegistryData($form)); - return $this->app->redirectPath('setup_display_globals'); + if ($form->isValid()) { + $registryData = $this->registryFormManipulator->getRegistryData($form, $this->configuration); + + $this->configuration->set('registry', $registryData); } // Do not return a 400 status code as not very well handled in calling JS. diff --git a/lib/Alchemy/Phrasea/Controller/Admin/TaskManagerController.php b/lib/Alchemy/Phrasea/Controller/Admin/TaskManagerController.php index 0fd26968da..086119ec0b 100644 --- a/lib/Alchemy/Phrasea/Controller/Admin/TaskManagerController.php +++ b/lib/Alchemy/Phrasea/Controller/Admin/TaskManagerController.php @@ -46,8 +46,10 @@ class TaskManagerController extends Controller $this->getDispatcher()->addListener(KernelEvents::TERMINATE, function () use ($cmdLine) { $process = new Process($cmdLine); + $process->setTimeout(0); $process->disableOutput(); + set_time_limit(0); ignore_user_abort(true); @@ -65,6 +67,7 @@ class TaskManagerController extends Controller $info = $this->getLiveInformationRequest(); $data = $info->getManager(); + if (null !== $pid = $data['process-id']) { if (substr(php_uname(), 0, 7) == "Windows"){ exec(sprintf('TaskKill /PID %d', $pid)); diff --git a/lib/Alchemy/Phrasea/Controller/Admin/UserController.php b/lib/Alchemy/Phrasea/Controller/Admin/UserController.php index 606f72abaf..65da919edd 100644 --- a/lib/Alchemy/Phrasea/Controller/Admin/UserController.php +++ b/lib/Alchemy/Phrasea/Controller/Admin/UserController.php @@ -285,7 +285,7 @@ class UserController extends Controller $on_base = $request->request->get('base_id') ? : null; $on_sbas = $request->request->get('sbas_id') ? : null; - $eligible_users = $user_query->on_bases_where_i_am($this->getAclForConnectedUser(), ['canadmin']) + $eligible_users = $user_query->on_bases_where_i_am($this->getAclForConnectedUser(), [\ACL::CANADMIN]) ->like($like_field, $like_value) ->on_base_ids($on_base) ->on_sbas_ids($on_sbas); @@ -357,7 +357,7 @@ class UserController extends Controller $userRegistrations = []; /** @var RegistrationRepository $registrationRepository */ $registrationRepository = $this->app['repo.registrations']; - $collections = $this->getAclForConnectedUser()->get_granted_base(['canadmin']); + $collections = $this->getAclForConnectedUser()->get_granted_base([\ACL::CANADMIN]); $authenticatedUserId = $authenticatedUser->getId(); foreach ($registrationRepository->getPendingRegistrations($collections) as $registration) { $user = $registration->getUser(); @@ -689,7 +689,7 @@ class UserController extends Controller ]); } - $basList = array_keys($this->getAclForConnectedUser()->get_granted_base(['manage'])); + $basList = array_keys($this->getAclForConnectedUser()->get_granted_base([\ACL::COLL_MANAGE])); /** @var NativeQueryProvider $query */ $query = $this->app['orm.em.native-query']; $models = $query->getModelForUser($this->getAuthenticatedUser(), $basList); @@ -832,7 +832,7 @@ class UserController extends Controller $this->getAclForUser($newUser)->apply_model( $userRepository->find($model), - array_keys($this->getAclForConnectedUser()->get_granted_base(['manage'])) + array_keys($this->getAclForConnectedUser()->get_granted_base([\ACL::COLL_MANAGE])) ); $nbCreation++; diff --git a/lib/Alchemy/Phrasea/Controller/Api/V1Controller.php b/lib/Alchemy/Phrasea/Controller/Api/V1Controller.php index 770bf18a54..5cbbc25dd4 100644 --- a/lib/Alchemy/Phrasea/Controller/Api/V1Controller.php +++ b/lib/Alchemy/Phrasea/Controller/Api/V1Controller.php @@ -486,7 +486,7 @@ class V1Controller extends Controller { $userQuery = new \User_Query($this->app); $orderMasters = $userQuery->on_base_ids([ $collection->get_base_id() ] ) - ->who_have_right(['order_master']) + ->who_have_right([\ACL::ORDER_MASTER]) ->execute() ->get_results() ->map(function (User $user) { @@ -632,7 +632,7 @@ class V1Controller extends Controller $offset_start = max($request->get('offset_start', 0), 0); $per_page = min(max($request->get('per_page', 10), 1), 1000); - $baseIds = array_keys($this->getAclForUser()->get_granted_base(['canaddrecord'])); + $baseIds = array_keys($this->getAclForUser()->get_granted_base([\ACL::CANADDRECORD])); $lazaretFiles = []; @@ -667,7 +667,7 @@ class V1Controller extends Controller return Result::createError($request, 404, sprintf('Lazaret file id %d not found', $lazaret_id))->createResponse(); } - if (!$this->getAclForUser()->has_right_on_base($lazaretFile->getBaseId(), 'canaddrecord')) { + if (!$this->getAclForUser()->has_right_on_base($lazaretFile->getBaseId(), \ACL::CANADDRECORD)) { return Result::createError($request, 403, 'You do not have access to this quarantine item')->createResponse(); } @@ -906,7 +906,7 @@ class V1Controller extends Controller $collection = \collection::getByBaseId($this->app, $request->get('base_id')); - if (!$this->getAclForUser()->has_right_on_base($request->get('base_id'), 'canaddrecord')) { + if (!$this->getAclForUser()->has_right_on_base($request->get('base_id'), \ACL::CANADDRECORD)) { return Result::createError($request, 403, sprintf( 'You do not have access to collection %s', $collection->get_label($this->app['locale']) ))->createResponse(); @@ -1003,7 +1003,7 @@ class V1Controller extends Controller $record = $this->findDataboxById($request->get('databox_id'))->get_record($request->get('record_id')); $base_id = $record->getBaseId(); $collection = \collection::getByBaseId($this->app, $base_id); - if (!$this->getAclForUser()->has_right_on_base($base_id, 'canaddrecord')) { + if (!$this->getAclForUser()->has_right_on_base($base_id, \ACL::CANADDRECORD)) { return Result::createError($request, 403, sprintf( 'You do not have access to collection %s', $collection->get_label($this->app['locale.I18n']) )); @@ -1035,7 +1035,7 @@ class V1Controller extends Controller return null; } if ($media->get_name() === 'document' - && !$acl->has_right_on_base($record->getBaseId(), 'candwnldhd') + && !$acl->has_right_on_base($record->getBaseId(), \ACL::CANDWNLDHD) && !$acl->has_hd_grant($record) ) { return null; @@ -2448,7 +2448,7 @@ class V1Controller extends Controller { $collection = \collection::getByBaseId($this->app, $data->{'base_id'}); - if (!$this->getAclForUser()->has_right_on_base($collection->get_base_id(), 'canaddrecord')) { + if (!$this->getAclForUser()->has_right_on_base($collection->get_base_id(), \ACL::CANADDRECORD)) { $this->app->abort(403, sprintf('You can not create a story on this collection %s', $collection->get_base_id())); } @@ -2770,9 +2770,11 @@ class V1Controller extends Controller $user = $this->getApiAuthenticatedUser(); $acl = $this->getAclForUser($user); - if (! $acl->has_access_to_module('admin') || ! $acl->has_right('manageusers')) { + if (! $acl->has_access_to_module('admin') || ! $acl->has_right(\ACL::CANADMIN)) { return Result::createError($request, 401, 'You are not authorized')->createResponse(); } + + return null; } public function ensureAccessToDatabox(Request $request) @@ -2814,7 +2816,7 @@ class V1Controller extends Controller public function ensureCanModifyRecord(Request $request) { $user = $this->getApiAuthenticatedUser(); - if (!$this->getAclForUser($user)->has_right('modifyrecord')) { + if (!$this->getAclForUser($user)->has_right(\ACL::CANMODIFRECORD)) { return Result::createError($request, 401, 'You are not authorized')->createResponse(); } @@ -2826,7 +2828,7 @@ class V1Controller extends Controller $user = $this->getApiAuthenticatedUser(); $record = $this->findDataboxById($request->attributes->get('databox_id')) ->get_record($request->attributes->get('record_id')); - if (!$this->getAclForUser($user)->has_right_on_base($record->getBaseId(), 'chgstatus')) { + if (!$this->getAclForUser($user)->has_right_on_base($record->getBaseId(), \ACL::CHGSTATUS)) { return Result::createError($request, 401, 'You are not authorized')->createResponse(); } @@ -2837,7 +2839,7 @@ class V1Controller extends Controller { $user = $this->getApiAuthenticatedUser(); $databox = $this->findDataboxById($request->attributes->get('databox_id')); - if (!$this->getAclForUser($user)->has_right_on_sbas($databox->get_sbas_id(), 'bas_modify_struct')) { + if (!$this->getAclForUser($user)->has_right_on_sbas($databox->get_sbas_id(), \ACL::BAS_MODIFY_STRUCT)) { return Result::createError($request, 401, 'You are not authorized')->createResponse(); } @@ -2850,9 +2852,9 @@ class V1Controller extends Controller $record = $this->findDataboxById($request->attributes->get('databox_id')) ->get_record($request->attributes->get('record_id')); // TODO: Check comparison. seems to be a mismatch - if ((!$this->getAclForUser($user)->has_right('addrecord') - && !$this->getAclForUser($user)->has_right('deleterecord')) - || !$this->getAclForUser($user)->has_right_on_base($record->getBaseId(), 'candeleterecord') + if ((!$this->getAclForUser($user)->has_right(\ACL::CANADDRECORD) + && !$this->getAclForUser($user)->has_right(\ACL::CANDELETERECORD)) + || !$this->getAclForUser($user)->has_right_on_base($record->getBaseId(), \ACL::CANDELETERECORD) ) { return Result::createError($request, 401, 'You are not authorized')->createResponse(); } @@ -2866,7 +2868,7 @@ class V1Controller extends Controller $record = $this->findDataboxById($request->attributes->get('databox_id')) ->get_record($request->attributes->get('record_id')); - if (!$this->getAclForUser($user)->has_right_on_base($record->getBaseId(), 'candeleterecord')) { + if (!$this->getAclForUser($user)->has_right_on_base($record->getBaseId(), \ACL::CANDELETERECORD)) { return Result::createError($request, 401, 'You are not authorized')->createResponse(); } diff --git a/lib/Alchemy/Phrasea/Controller/DatafileController.php b/lib/Alchemy/Phrasea/Controller/DatafileController.php index 15fb91a3ae..5f68956c8b 100644 --- a/lib/Alchemy/Phrasea/Controller/DatafileController.php +++ b/lib/Alchemy/Phrasea/Controller/DatafileController.php @@ -66,7 +66,7 @@ class DatafileController extends AbstractDelivery $stamp = false; $watermark = !$this->acl->get($this->authentication->getUser()) - ->has_right_on_base($record->getBaseId(), 'nowatermark'); + ->has_right_on_base($record->getBaseId(), \ACL::NOWATERMARK); if ($watermark && !$all_access) { $subdef_class = null; diff --git a/lib/Alchemy/Phrasea/Controller/PermalinkController.php b/lib/Alchemy/Phrasea/Controller/PermalinkController.php index d6d7279c7e..9baf7931bc 100644 --- a/lib/Alchemy/Phrasea/Controller/PermalinkController.php +++ b/lib/Alchemy/Phrasea/Controller/PermalinkController.php @@ -126,9 +126,7 @@ class PermalinkController extends AbstractDelivery $isDownload = $request->query->getBoolean('download', false); - if ($isDownload) { - $user = $this->app->getAuthenticatedUser(); - + if ($isDownload && $user = $this->app->getAuthenticatedUser()) { $this->getEventDispatcher()->dispatch( PhraseaEvents::EXPORT_CREATE, new ExportEvent($user, 0, $sbas_id . '_' . $record_id, [ $subdef ], '') @@ -136,7 +134,7 @@ class PermalinkController extends AbstractDelivery } if ($this->authentication->isAuthenticated()) { - $watermark = !$this->acl->get($this->authentication->getUser())->has_right_on_base($record->getBaseId(), 'nowatermark'); + $watermark = !$this->acl->get($this->authentication->getUser())->has_right_on_base($record->getBaseId(), \ACL::NOWATERMARK); if ($watermark) { /** @var BasketElementRepository $repository */ diff --git a/lib/Alchemy/Phrasea/Controller/Prod/EditController.php b/lib/Alchemy/Phrasea/Controller/Prod/EditController.php index 4d2ce9a6fd..a050c6cd3a 100644 --- a/lib/Alchemy/Phrasea/Controller/Prod/EditController.php +++ b/lib/Alchemy/Phrasea/Controller/Prod/EditController.php @@ -39,7 +39,7 @@ class EditController extends Controller $this->app, $request, RecordsRequest::FLATTEN_YES_PRESERVE_STORIES, - ['canmodifrecord'] + [\ACL::CANMODIFRECORD] ); $thesaurus = false; @@ -121,7 +121,7 @@ class EditController extends Controller } // generate javascript status - if ($this->getAclForUser()->has_right('changestatus')) { + if ($this->getAclForUser()->has_right(\ACL::CHGSTATUS)) { $statusStructure = $databox->getStatusStructure(); foreach ($statusStructure as $statbit) { $bit = $statbit['bit']; @@ -158,7 +158,7 @@ class EditController extends Controller $elements[$indice]['statbits'] = []; $elements[$indice]['editableStatus'] = false; - if ($this->getAclForUser()->has_right_on_base($record->getBaseId(), 'chgstatus')) { + if ($this->getAclForUser()->has_right_on_base($record->getBaseId(), \ACL::CHGSTATUS)) { $elements[$indice]['editableStatus'] = true; foreach ($status as $n => $s) { $tmp_val = substr(strrev($record->getStatus()), $n, 1); @@ -279,7 +279,7 @@ class EditController extends Controller public function applyAction(Request $request) { - $records = RecordsRequest::fromRequest($this->app, $request, RecordsRequest::FLATTEN_YES_PRESERVE_STORIES, ['canmodifrecord']); + $records = RecordsRequest::fromRequest($this->app, $request, RecordsRequest::FLATTEN_YES_PRESERVE_STORIES, [\ACL::CANMODIFRECORD]); $databoxes = $records->databoxes(); if (count($databoxes) !== 1) { diff --git a/lib/Alchemy/Phrasea/Controller/Prod/FeedController.php b/lib/Alchemy/Phrasea/Controller/Prod/FeedController.php index 055af2b1d5..2bc333f45c 100644 --- a/lib/Alchemy/Phrasea/Controller/Prod/FeedController.php +++ b/lib/Alchemy/Phrasea/Controller/Prod/FeedController.php @@ -37,7 +37,7 @@ class FeedController extends Controller public function publishRecordsAction(Request $request) { $feeds = $this->getFeedRepository()->getAllForUser($this->getAclForUser()); - $publishing = RecordsRequest::fromRequest($this->app, $request, true, [], ['bas_chupub']); + $publishing = RecordsRequest::fromRequest($this->app, $request, true, [], [\ACL::BAS_CHUPUB]); return $this->render( 'prod/actions/publish/publish.html.twig', @@ -76,7 +76,7 @@ class FeedController extends Controller $feed->addEntry($entry); - $publishing = RecordsRequest::fromRequest($this->app, $request, true, [], ['bas_chupub']); + $publishing = RecordsRequest::fromRequest($this->app, $request, true, [], [\ACL::BAS_CHUPUB]); $manager = $this->getEntityManager(); foreach ($publishing as $record) { $item = new FeedItem(); @@ -270,7 +270,7 @@ class FeedController extends Controller public function ensureUserHasPublishRight() { - $this->requireRight('bas_chupub'); + $this->requireRight(\ACL::BAS_CHUPUB); } /** diff --git a/lib/Alchemy/Phrasea/Controller/Prod/LazaretController.php b/lib/Alchemy/Phrasea/Controller/Prod/LazaretController.php index 626df230c7..b9c1d1567b 100644 --- a/lib/Alchemy/Phrasea/Controller/Prod/LazaretController.php +++ b/lib/Alchemy/Phrasea/Controller/Prod/LazaretController.php @@ -42,7 +42,7 @@ class LazaretController extends Controller */ public function listElement(Request $request) { - $baseIds = array_keys($this->getAclForUser()->get_granted_base(['canaddrecord'])); + $baseIds = array_keys($this->getAclForUser()->get_granted_base([\ACL::CANADDRECORD])); $lazaretFiles = null; $perPage = 10; diff --git a/lib/Alchemy/Phrasea/Controller/Prod/MoveCollectionController.php b/lib/Alchemy/Phrasea/Controller/Prod/MoveCollectionController.php index 3ec8de1d08..a76b431272 100644 --- a/lib/Alchemy/Phrasea/Controller/Prod/MoveCollectionController.php +++ b/lib/Alchemy/Phrasea/Controller/Prod/MoveCollectionController.php @@ -17,7 +17,7 @@ class MoveCollectionController extends Controller { public function displayForm(Request $request) { - $records = RecordsRequest::fromRequest($this->app, $request, false, ['candeleterecord']); + $records = RecordsRequest::fromRequest($this->app, $request, false, [\ACL::CANDELETERECORD]); $sbas_ids = array_map(function (\databox $databox) { return $databox->get_sbas_id(); @@ -26,6 +26,7 @@ class MoveCollectionController extends Controller $message = ''; $template = ''; $collections = $this->getAclForUser()->get_granted_base(['canaddrecord'], $sbas_ids); + $collections = $this->getAclForUser()->get_granted_base([\ACL::CANADDRECORD], $sbas_ids); if (count($records->databoxes()) > 1) { $success = false; @@ -56,7 +57,7 @@ class MoveCollectionController extends Controller public function apply(Request $request) { /** @var \record_adapter[] $records */ - $records = RecordsRequest::fromRequest($this->app, $request, false, ['candeleterecord']); + $records = RecordsRequest::fromRequest($this->app, $request, false, [\ACL::CANDELETERECORD]); $datas = [ 'success' => false, @@ -70,7 +71,7 @@ class MoveCollectionController extends Controller return $this->app->json($datas); } - if (!$this->getAclForUser()->has_right_on_base($request->request->get('base_id'), 'canaddrecord')) { + if (!$this->getAclForUser()->has_right_on_base($request->request->get('base_id'), \ACL::CANADDRECORD)) { $datas['message'] = $this->app->trans("You do not have the permission to move records to %collection%", ['%collection%', \phrasea::bas_labels($request->request->get('base_id'), $this->app)]); return $this->app->json($datas); @@ -90,7 +91,7 @@ class MoveCollectionController extends Controller if ($request->request->get("chg_coll_son") == "1") { /** @var \record_adapter $child */ foreach ($record->getChildren() as $child) { - if ($this->getAclForUser()->has_right_on_base($child->getBaseId(), 'candeleterecord')) { + if ($this->getAclForUser()->has_right_on_base($child->getBaseId(), \ACL::CANDELETERECORD)) { $child->move_to_collection($collection, $this->getApplicationBox()); } } diff --git a/lib/Alchemy/Phrasea/Controller/Prod/PropertyController.php b/lib/Alchemy/Phrasea/Controller/Prod/PropertyController.php index 317aeb7cb7..ff834ab119 100644 --- a/lib/Alchemy/Phrasea/Controller/Prod/PropertyController.php +++ b/lib/Alchemy/Phrasea/Controller/Prod/PropertyController.php @@ -28,7 +28,7 @@ class PropertyController extends Controller $this->app->abort(400); } - $records = RecordsRequest::fromRequest($this->app, $request, false, ['chgstatus']); + $records = RecordsRequest::fromRequest($this->app, $request, false, [\ACL::CHGSTATUS]); $databoxes = $records->databoxes(); if (count($databoxes) > 1) { @@ -81,7 +81,7 @@ class PropertyController extends Controller $this->app->abort(400); } - $records = RecordsRequest::fromRequest($this->app, $request, false, ['canmodifrecord']); + $records = RecordsRequest::fromRequest($this->app, $request, false, [\ACL::CANMODIFRECORD]); $recordsType = []; @@ -115,7 +115,7 @@ class PropertyController extends Controller public function changeStatus(Request $request) { $applyStatusToChildren = $request->request->get('apply_to_children', []); - $records = RecordsRequest::fromRequest($this->app, $request, false, ['chgstatus']); + $records = RecordsRequest::fromRequest($this->app, $request, false, [\ACL::CHGSTATUS]); $updated = []; $postStatus = (array) $request->request->get('status'); @@ -149,7 +149,7 @@ class PropertyController extends Controller public function changeType(Request $request) { $typeLst = $request->request->get('types', []); - $records = RecordsRequest::fromRequest($this->app, $request, false, ['canmodifrecord']); + $records = RecordsRequest::fromRequest($this->app, $request, false, [\ACL::CANMODIFRECORD]); $mimeLst = $request->request->get('mimes', []); $forceType = $request->request->get('force_types', ''); $updated = []; diff --git a/lib/Alchemy/Phrasea/Controller/Prod/PushController.php b/lib/Alchemy/Phrasea/Controller/Prod/PushController.php index 60feb34658..569537fed3 100644 --- a/lib/Alchemy/Phrasea/Controller/Prod/PushController.php +++ b/lib/Alchemy/Phrasea/Controller/Prod/PushController.php @@ -395,7 +395,7 @@ class PushController extends Controller $data = null; $query = $this->createUserQuery(); - $query->on_bases_where_i_am($this->getAclForUser($this->getAuthenticatedUser()), ['canpush']); + $query->on_bases_where_i_am($this->getAclForUser($this->getAuthenticatedUser()), [\ACL::CANPUSH]); $query->in([$usr_id]); @@ -431,7 +431,7 @@ class PushController extends Controller $result = ['success' => false, 'message' => '', 'user' => null]; try { - if (!$this->getAclForUser($this->getAuthenticatedUser())->has_right('manageusers')) + if (!$this->getAclForUser($this->getAuthenticatedUser())->has_right(\ACL::CANADMIN)) throw new ControllerException($this->app->trans('You are not allowed to add users')); if (!$request->request->get('firstname')) @@ -502,7 +502,7 @@ class PushController extends Controller public function searchUserAction(Request $request) { $query = $this->createUserQuery(); - $query->on_bases_where_i_am($this->getAclForUser($this->getAuthenticatedUser()), ['canpush']); + $query->on_bases_where_i_am($this->getAclForUser($this->getAuthenticatedUser()), [\ACL::CANPUSH]); $query ->like(\User_Query::LIKE_FIRSTNAME, $request->query->get('query')) ->like(\User_Query::LIKE_LASTNAME, $request->query->get('query')) @@ -540,7 +540,7 @@ class PushController extends Controller $list = $repository->findUserListByUserAndId($this->getAuthenticatedUser(), $list_id); $query = $this->createUserQuery(); - $query->on_bases_where_i_am($this->getAclForUser($this->getAuthenticatedUser()), ['canpush']); + $query->on_bases_where_i_am($this->getAclForUser($this->getAuthenticatedUser()), [\ACL::CANPUSH]); if ($request->get('query')) { $query diff --git a/lib/Alchemy/Phrasea/Controller/Prod/RecordController.php b/lib/Alchemy/Phrasea/Controller/Prod/RecordController.php index 4d18de4bfd..5567ff8bc9 100644 --- a/lib/Alchemy/Phrasea/Controller/Prod/RecordController.php +++ b/lib/Alchemy/Phrasea/Controller/Prod/RecordController.php @@ -130,9 +130,11 @@ class RecordController extends Controller public function doDeleteRecords(Request $request) { $flatten = (bool)($request->request->get('del_children')) ? RecordsRequest::FLATTEN_YES_PRESERVE_STORIES : RecordsRequest::FLATTEN_NO; - $records = RecordsRequest::fromRequest($this->app, $request, $flatten, [ - 'candeleterecord' - ]); + $records = RecordsRequest::fromRequest( + $this->app, + $request,$flatten, + [\ACL::CANDELETERECORD] + ); $basketElementsRepository = $this->getBasketElementRepository(); $StoryWZRepository = $this->getStoryWorkZoneRepository(); @@ -175,9 +177,12 @@ class RecordController extends Controller */ public function whatCanIDelete(Request $request) { - $records = RecordsRequest::fromRequest($this->app, $request, !!$request->request->get('del_children'), [ - 'candeleterecord', - ]); + $records = RecordsRequest::fromRequest( + $this->app, + $request, + !!$request->request->get('del_children'), + [\ACL::CANDELETERECORD] + ); return $this->render('prod/actions/delete_records_confirm.html.twig', [ 'records' => $records, diff --git a/lib/Alchemy/Phrasea/Controller/Prod/StoryController.php b/lib/Alchemy/Phrasea/Controller/Prod/StoryController.php index 39ffb95bf9..9a65ed61fa 100644 --- a/lib/Alchemy/Phrasea/Controller/Prod/StoryController.php +++ b/lib/Alchemy/Phrasea/Controller/Prod/StoryController.php @@ -35,7 +35,7 @@ class StoryController extends Controller { $collection = \collection::getByBaseId($this->app, $request->request->get('base_id')); - if (!$this->getAclForUser()->has_right_on_base($collection->get_base_id(), 'canaddrecord')) { + if (!$this->getAclForUser()->has_right_on_base($collection->get_base_id(), \ACL::CANADDRECORD)) { throw new AccessDeniedHttpException('You can not create a story on this collection'); } @@ -109,7 +109,7 @@ class StoryController extends Controller { $Story = new \record_adapter($this->app, $sbas_id, $record_id); - if (!$this->getAclForUser()->has_right_on_base($Story->getBaseId(), 'canmodifrecord')) { + if (!$this->getAclForUser()->has_right_on_base($Story->getBaseId(), \ACL::CANMODIFRECORD)) { throw new AccessDeniedHttpException('You can not add document to this Story'); } @@ -145,7 +145,7 @@ class StoryController extends Controller $story = new \record_adapter($this->app, $sbas_id, $record_id); $record = new \record_adapter($this->app, $child_sbas_id, $child_record_id); - if (!$this->getAclForUser()->has_right_on_base($story->getBaseId(), 'canmodifrecord')) { + if (!$this->getAclForUser()->has_right_on_base($story->getBaseId(), \ACL::CANMODIFRECORD)) { throw new AccessDeniedHttpException('You can not add document to this Story'); } @@ -188,7 +188,7 @@ class StoryController extends Controller throw new \Exception('This is not a story'); } - if (!$this->getAclForUser()->has_right_on_base($story->getBaseId(), 'canmodifrecord')) { + if (!$this->getAclForUser()->has_right_on_base($story->getBaseId(), \ACL::CANMODIFRECORD)) { throw new ControllerException($this->app->trans('You can not edit this story')); } diff --git a/lib/Alchemy/Phrasea/Controller/Prod/ToolsController.php b/lib/Alchemy/Phrasea/Controller/Prod/ToolsController.php index e91485e0ec..497e4fa86a 100644 --- a/lib/Alchemy/Phrasea/Controller/Prod/ToolsController.php +++ b/lib/Alchemy/Phrasea/Controller/Prod/ToolsController.php @@ -51,9 +51,9 @@ class ToolsController extends Controller $acl = $this->getAclForUser(); - if ($acl->has_right('bas_chupub') - && $acl->has_right_on_base($record->getBaseId(), 'canmodifrecord') - && $acl->has_right_on_base($record->getBaseId(), 'imgtools') + if ($acl->has_right(\ACL::BAS_CHUPUB) + && $acl->has_right_on_base($record->getBaseId(), \ACL::CANMODIFRECORD) + && $acl->has_right_on_base($record->getBaseId(), \ACL::IMGTOOLS) ) { $databoxSubdefs = $record->getDatabox()->get_subdef_structure()->getSubdefGroup($record->getType()); @@ -64,7 +64,7 @@ class ToolsController extends Controller } if ('document' == $subdefName) { - if (!$acl->has_right_on_base($record->getBaseId(), 'candwnldhd')) { + if (!$acl->has_right_on_base($record->getBaseId(), \ACL::CANDWNLDHD)) { continue; } $label = $this->app->trans('prod::tools: document'); @@ -149,7 +149,7 @@ class ToolsController extends Controller $force = $request->request->get('force_substitution') == '1'; - $selection = RecordsRequest::fromRequest($this->app, $request, false, array('canmodifrecord')); + $selection = RecordsRequest::fromRequest($this->app, $request, false, [\ACL::CANMODIFRECORD]); foreach ($selection as $record) { $substituted = false; @@ -188,8 +188,10 @@ class ToolsController extends Controller try { $tempoDir = tempnam(sys_get_temp_dir(), 'substit'); + unlink($tempoDir); mkdir($tempoDir); + $tempoFile = $tempoDir . DIRECTORY_SEPARATOR . $fileName; if (false === rename($file->getPathname(), $tempoFile)) { @@ -342,10 +344,10 @@ class ToolsController extends Controller $state = $request->request->get('state') == 'true' ? true : false; $acl = $this->getAclForUser(); - if (!$acl->has_right('bas_chupub') - || !$acl->has_right_on_base($record->getBaseId(), 'canmodifrecord') - || !$acl->has_right_on_base($record->getBaseId(), 'imgtools') - || ('document' == $subdefName && !$acl->has_right_on_base($record->getBaseId(), 'candwnldhd')) + if (!$acl->has_right(\ACL::BAS_CHUPUB) + || !$acl->has_right_on_base($record->getBaseId(), \ACL::CANMODIFRECORD) + || !$acl->has_right_on_base($record->getBaseId(), \ACL::IMGTOOLS) + || ('document' == $subdefName && !$acl->has_right_on_base($record->getBaseId(), \ACL::CANDWNLDHD)) || ('document' != $subdefName && !$acl->has_access_to_subdef($record, $subdefName)) ) { $this->app->abort(403); diff --git a/lib/Alchemy/Phrasea/Controller/Prod/UploadController.php b/lib/Alchemy/Phrasea/Controller/Prod/UploadController.php index d800aacdb9..846b934fd7 100644 --- a/lib/Alchemy/Phrasea/Controller/Prod/UploadController.php +++ b/lib/Alchemy/Phrasea/Controller/Prod/UploadController.php @@ -115,7 +115,7 @@ class UploadController extends Controller throw new BadRequestHttpException('Missing base_id parameter'); } - if (!$this->getAclForUser()->has_right_on_base($base_id, 'canaddrecord')) { + if (!$this->getAclForUser()->has_right_on_base($base_id, \ACL::CANADDRECORD)) { throw new AccessDeniedHttpException('User is not allowed to add record on this collection'); } @@ -243,7 +243,7 @@ class UploadController extends Controller { $collections = []; - foreach ($acl->get_granted_base(['canaddrecord']) as $collection) { + foreach ($acl->get_granted_base([\ACL::CANADDRECORD]) as $collection) { $databox = $collection->get_databox(); if ( ! isset($collections[$databox->get_sbas_id()])) { diff --git a/lib/Alchemy/Phrasea/Controller/RecordsRequest.php b/lib/Alchemy/Phrasea/Controller/RecordsRequest.php index 7768a30b15..bb911d15b9 100644 --- a/lib/Alchemy/Phrasea/Controller/RecordsRequest.php +++ b/lib/Alchemy/Phrasea/Controller/RecordsRequest.php @@ -219,8 +219,8 @@ class RecordsRequest extends ArrayCollection $repository = $app['repo.story-wz']; $storyWZ = $repository->findByUserAndId( - $app, $app->getAuthenticatedUser() - , $request->get('story') + $app, $app->getAuthenticatedUser(), + $request->get('story') ); $received[$storyWZ->getRecord($app)->get_serialize_key()] = $storyWZ->getRecord($app); diff --git a/lib/Alchemy/Phrasea/Controller/Report/RootController.php b/lib/Alchemy/Phrasea/Controller/Report/RootController.php index 552de7a5ed..8bb9006402 100644 --- a/lib/Alchemy/Phrasea/Controller/Report/RootController.php +++ b/lib/Alchemy/Phrasea/Controller/Report/RootController.php @@ -53,7 +53,7 @@ class RootController extends Controller $granted = []; - foreach ($this->getAclForUser()->get_granted_base(['canreport']) as $collection) { + foreach ($this->getAclForUser()->get_granted_base([\ACL::CANREPORT]) as $collection) { if (!isset($granted[$collection->get_sbas_id()])) { $granted[$collection->get_sbas_id()] = [ 'id' => $collection->get_sbas_id(), diff --git a/lib/Alchemy/Phrasea/Controller/Thesaurus/ThesaurusXmlHttpController.php b/lib/Alchemy/Phrasea/Controller/Thesaurus/ThesaurusXmlHttpController.php index 2500a7dc23..2e970e51d8 100644 --- a/lib/Alchemy/Phrasea/Controller/Thesaurus/ThesaurusXmlHttpController.php +++ b/lib/Alchemy/Phrasea/Controller/Thesaurus/ThesaurusXmlHttpController.php @@ -700,43 +700,14 @@ class ThesaurusXmlHttpController extends Controller foreach ($collections as $collection) { $lcoll .= ($lcoll?",":"") . $collection->get_coll_id(); } - $site = $this->app['phraseanet.configuration']['main']['key']; - $usr_id = $this->getAuthenticatedUser()->getId(); $tids = explode('.', $request->get('id')); $thid = implode('.', $tids); try { $databox = $this->findDataboxById($sbid); - $connbas = $databox->get_connection(); $dbname = \phrasea::sbas_labels($sbid, $this->app); - $t_nrec = []; - $lthid = strlen($thid); - - // count occurrences - if ($lthid > 1) { - $dthid = str_replace('.', 'd', $thid); - $sql = "SELECT" - . " 0+SUBSTR(t.value, " . ($lthid + 2) . ") AS k, COUNT(DISTINCT(`record_id`)) AS n" - . " FROM (thit AS t INNER JOIN record AS r USING(record_id))" - . " INNER JOIN collusr AS c ON c.site=:site AND c.usr_id=:usr_id AND r.coll_id=c.coll_id" - . " WHERE t.value LIKE :like AND r.coll_id IN(".$lcoll.") AND (r.status^c.mask_xor)&c.mask_and=0" - . " GROUP BY k ORDER BY NULL"; - $sqlparm = array(':like' => $dthid . 'd%', ':site'=>$site, ':usr_id'=>$usr_id); - - $stmt = $connbas->prepare($sql); - $stmt->execute($sqlparm); - - $rs = $stmt->fetchAll(\PDO::FETCH_ASSOC); - $stmt->closeCursor(); - - foreach ($rs as $rowbas) { - $t_nrec[$thid . '.' . $rowbas['k']] = $rowbas; - } - } - - $databox = $this->findDataboxById($sbid); if ($request->get('type') == 'T') { $xqroot = 'thesaurus'; $dom = $databox->get_dom_thesaurus(); @@ -758,17 +729,7 @@ class ThesaurusXmlHttpController extends Controller $node0 = $nodes->item(0); $key0 = null; // key of the sy in the current language (or key of the first sy if we can't find good lng) - $nts0 = 0; // count of ts under this term - $label = $this->buildBranchLabel($dbname, $lng, $node0, $key0, $nts0); - - $class = ''; - if ($nts0 > 0) { - $class .= ( $class == '' ? '' : ' ') . 'expandable'; - } - if ($request->get('last')) { - $class .= ( $class == '' ? '' : ' ') . 'last'; - } // on dresse la liste des termes specifiques avec comme cle le synonyme dans la langue pivot $nts = 0; $tts = []; @@ -795,14 +756,14 @@ class ThesaurusXmlHttpController extends Controller } } + $field0 = $node0->getAttribute('field'); + if ($field0) { + $field0 = 'field="' . $field0 . '"'; + } + + $html .= '' . "\n"; } } } catch (\Exception $e) { diff --git a/lib/Alchemy/Phrasea/ControllerProvider/Admin/Collection.php b/lib/Alchemy/Phrasea/ControllerProvider/Admin/Collection.php index 915f1cd0d3..c92a16c4e8 100644 --- a/lib/Alchemy/Phrasea/ControllerProvider/Admin/Collection.php +++ b/lib/Alchemy/Phrasea/ControllerProvider/Admin/Collection.php @@ -45,7 +45,7 @@ class Collection implements ControllerProviderInterface, ServiceProviderInterfac $controllers->before(function (Request $request) use ($firewall) { $firewall ->requireAccessToModule('admin') - ->requireRightOnBase($request->attributes->get('bas_id'), 'canadmin'); + ->requireRightOnBase($request->attributes->get('bas_id'), \ACL::CANADMIN); }); $controllers->get('/{bas_id}/', 'controller.admin.collection:getCollection') diff --git a/lib/Alchemy/Phrasea/ControllerProvider/Admin/Databox.php b/lib/Alchemy/Phrasea/ControllerProvider/Admin/Databox.php index b739965329..6f7c716422 100644 --- a/lib/Alchemy/Phrasea/ControllerProvider/Admin/Databox.php +++ b/lib/Alchemy/Phrasea/ControllerProvider/Admin/Databox.php @@ -135,11 +135,11 @@ class Databox implements ControllerProviderInterface, ServiceProviderInterface public function requireManageRightOnSbas(Request $request, Application $app) { - $this->getFirewall($app)->requireRightOnSbas($request->attributes->get('databox_id'), 'bas_manage'); + $this->getFirewall($app)->requireRightOnSbas($request->attributes->get('databox_id'), \ACL::BAS_MANAGE); } public function requireChangeSbasStructureRight(Request $request, Application $app) { - $this->getFirewall($app)->requireRightOnSbas($request->attributes->get('databox_id'), 'bas_modify_struct'); + $this->getFirewall($app)->requireRightOnSbas($request->attributes->get('databox_id'), \ACL::BAS_MODIFY_STRUCT); } } diff --git a/lib/Alchemy/Phrasea/ControllerProvider/Admin/Feeds.php b/lib/Alchemy/Phrasea/ControllerProvider/Admin/Feeds.php index f9b73e7f87..5e7c147f82 100644 --- a/lib/Alchemy/Phrasea/ControllerProvider/Admin/Feeds.php +++ b/lib/Alchemy/Phrasea/ControllerProvider/Admin/Feeds.php @@ -41,7 +41,7 @@ class Feeds implements ControllerProviderInterface, ServiceProviderInterface $controllers->before(function () use ($firewall) { $firewall ->requireAccessToModule('admin') - ->requireRight('bas_chupub'); + ->requireRight(\ACL::BAS_CHUPUB); }); $controllers->get('/list/', 'controller.admin.feeds:listFeedsAction') diff --git a/lib/Alchemy/Phrasea/ControllerProvider/Admin/Fields.php b/lib/Alchemy/Phrasea/ControllerProvider/Admin/Fields.php index b6f111a37a..205939fd62 100644 --- a/lib/Alchemy/Phrasea/ControllerProvider/Admin/Fields.php +++ b/lib/Alchemy/Phrasea/ControllerProvider/Admin/Fields.php @@ -51,7 +51,7 @@ class Fields implements ControllerProviderInterface, ServiceProviderInterface $controllers->before(function () use ($firewall) { $firewall ->requireAccessToModule('admin') - ->requireRight('bas_modify_struct'); + ->requireRight(\ACL::BAS_MODIFY_STRUCT); }); $controllers->get('/language.json', 'controller.admin.fields:getLanguage') diff --git a/lib/Alchemy/Phrasea/ControllerProvider/Admin/Setup.php b/lib/Alchemy/Phrasea/ControllerProvider/Admin/Setup.php index 0575dc8a4c..9734c038fd 100644 --- a/lib/Alchemy/Phrasea/ControllerProvider/Admin/Setup.php +++ b/lib/Alchemy/Phrasea/ControllerProvider/Admin/Setup.php @@ -24,7 +24,7 @@ class Setup implements ControllerProviderInterface, ServiceProviderInterface public function register(Application $app) { $app['controller.admin.setup'] = $app->share(function (PhraseaApplication $app) { - return new SetupController($app); + return new SetupController($app, $app['registry.manipulator'], $app['conf']); }); } diff --git a/lib/Alchemy/Phrasea/ControllerProvider/Admin/Subdefs.php b/lib/Alchemy/Phrasea/ControllerProvider/Admin/Subdefs.php index 0e5c8d06f4..91d8eb07c2 100644 --- a/lib/Alchemy/Phrasea/ControllerProvider/Admin/Subdefs.php +++ b/lib/Alchemy/Phrasea/ControllerProvider/Admin/Subdefs.php @@ -41,7 +41,7 @@ class Subdefs implements ControllerProviderInterface, ServiceProviderInterface $controllers->before(function (Request $request) use ($firewall) { $firewall->requireAccessToModule('admin') - ->requireRightOnSbas($request->attributes->get('sbas_id'), 'bas_modify_struct'); + ->requireRightOnSbas($request->attributes->get('sbas_id'), \ACL::BAS_MODIFY_STRUCT); }); $controllers->get('/{sbas_id}/', 'controller.admin.subdefs:indexAction') diff --git a/lib/Alchemy/Phrasea/ControllerProvider/Admin/TaskManager.php b/lib/Alchemy/Phrasea/ControllerProvider/Admin/TaskManager.php index f6ecd5f1fe..bd802f1558 100644 --- a/lib/Alchemy/Phrasea/ControllerProvider/Admin/TaskManager.php +++ b/lib/Alchemy/Phrasea/ControllerProvider/Admin/TaskManager.php @@ -46,7 +46,7 @@ class TaskManager implements ControllerProviderInterface, ServiceProviderInterfa }; $controllers->before(function () use ($firewall) { - $firewall->requireRight('taskmanager'); + $firewall->requireRight(\ACL::TASKMANAGER); }); $controllers diff --git a/lib/Alchemy/Phrasea/ControllerProvider/Admin/Users.php b/lib/Alchemy/Phrasea/ControllerProvider/Admin/Users.php index 23ffe894ba..39a5afa0aa 100644 --- a/lib/Alchemy/Phrasea/ControllerProvider/Admin/Users.php +++ b/lib/Alchemy/Phrasea/ControllerProvider/Admin/Users.php @@ -43,7 +43,7 @@ class Users implements ControllerProviderInterface, ServiceProviderInterface $controllers->before(function () use ($firewall) { $firewall->requireAccessToModule('admin') - ->requireRight('manageusers'); + ->requireRight(\ACL::CANADMIN); }); $controllers->match('/rights/', 'controller.admin.users:editRightsAction') diff --git a/lib/Alchemy/Phrasea/ControllerProvider/Api/V2.php b/lib/Alchemy/Phrasea/ControllerProvider/Api/V2.php index c1b0651b3d..5e2c07022e 100644 --- a/lib/Alchemy/Phrasea/ControllerProvider/Api/V2.php +++ b/lib/Alchemy/Phrasea/ControllerProvider/Api/V2.php @@ -53,12 +53,21 @@ class V2 extends Api implements ControllerProviderInterface, ServiceProviderInte $app['controller.api.v2.orders'] = $app->share( function (PhraseaApplication $app) { - return (new ApiOrderController($app)) + $controller = new ApiOrderController( + $app, + $app['repo.orders'], + $app['repo.order-elements'], + $app['provider.order_basket'] + ); + + $controller ->setDispatcher($app['dispatcher']) ->setEntityManagerLocator(new LazyLocator($app, 'orm.em')) ->setDelivererLocator(new LazyLocator($app, 'phraseanet.file-serve')) ->setFileSystemLocator(new LazyLocator($app, 'filesystem')) ->setJsonBodyHelper($app['json.body_helper']); + + return $controller; } ); } diff --git a/lib/Alchemy/Phrasea/ControllerProvider/Prod/Bridge.php b/lib/Alchemy/Phrasea/ControllerProvider/Prod/Bridge.php index c3885150f4..e54d2044a5 100644 --- a/lib/Alchemy/Phrasea/ControllerProvider/Prod/Bridge.php +++ b/lib/Alchemy/Phrasea/ControllerProvider/Prod/Bridge.php @@ -40,7 +40,7 @@ class Bridge implements ControllerProviderInterface, ServiceProviderInterface $firewall = $this->getFirewall($app); $controllers->before(function () use ($firewall) { - $firewall->requireRight('bas_chupub'); + $firewall->requireRight(\ACL::BAS_CHUPUB); }); $controllers diff --git a/lib/Alchemy/Phrasea/ControllerProvider/Prod/Edit.php b/lib/Alchemy/Phrasea/ControllerProvider/Prod/Edit.php index a9ed65e354..8fb6861088 100644 --- a/lib/Alchemy/Phrasea/ControllerProvider/Prod/Edit.php +++ b/lib/Alchemy/Phrasea/ControllerProvider/Prod/Edit.php @@ -47,7 +47,7 @@ class Edit implements ControllerProviderInterface, ServiceProviderInterface $controllers->before(function () use ($firewall) { $firewall ->requireNotGuest() - ->requireRight('modifyrecord'); + ->requireRight(\ACL::CANMODIFRECORD); }); $controllers->post('/', 'controller.prod.edit:submitAction'); diff --git a/lib/Alchemy/Phrasea/ControllerProvider/Prod/Lazaret.php b/lib/Alchemy/Phrasea/ControllerProvider/Prod/Lazaret.php index 011dbd8ab3..96d454439b 100644 --- a/lib/Alchemy/Phrasea/ControllerProvider/Prod/Lazaret.php +++ b/lib/Alchemy/Phrasea/ControllerProvider/Prod/Lazaret.php @@ -53,7 +53,7 @@ class Lazaret implements ControllerProviderInterface, ServiceProviderInterface $firewall = $this->getFirewall($app); $controllers->before(function () use ($firewall) { - $firewall->requireRight('addrecord'); + $firewall->requireRight(\ACL::CANADDRECORD); }); $controllers->get('/', 'controller.prod.lazaret:listElement') diff --git a/lib/Alchemy/Phrasea/ControllerProvider/Prod/MoveCollection.php b/lib/Alchemy/Phrasea/ControllerProvider/Prod/MoveCollection.php index a8c80e49bd..e6a835afaf 100644 --- a/lib/Alchemy/Phrasea/ControllerProvider/Prod/MoveCollection.php +++ b/lib/Alchemy/Phrasea/ControllerProvider/Prod/MoveCollection.php @@ -41,8 +41,8 @@ class MoveCollection implements ControllerProviderInterface, ServiceProviderInte $controllers->before(function () use ($firewall) { $firewall - ->requireRight('addrecord') - ->requireRight('deleterecord'); + ->requireRight(\ACL::CANADDRECORD) + ->requireRight(\ACL::CANDELETERECORD); }); $controllers->post('/', 'controller.prod.move-collection:displayForm') diff --git a/lib/Alchemy/Phrasea/ControllerProvider/Prod/Order.php b/lib/Alchemy/Phrasea/ControllerProvider/Prod/Order.php index 983bacdbad..1db0fdfda9 100644 --- a/lib/Alchemy/Phrasea/ControllerProvider/Prod/Order.php +++ b/lib/Alchemy/Phrasea/ControllerProvider/Prod/Order.php @@ -12,8 +12,8 @@ namespace Alchemy\Phrasea\ControllerProvider\Prod; use Alchemy\Phrasea\Application as PhraseaApplication; -use Alchemy\Phrasea\Controller\LazyLocator; use Alchemy\Phrasea\ControllerProvider\ControllerProviderTrait; +use Alchemy\Phrasea\Core\LazyLocator; use Alchemy\Phrasea\Order\Controller\ProdOrderController; use Alchemy\Phrasea\Order\OrderBasketProvider; use Alchemy\Phrasea\Order\OrderValidator; @@ -39,11 +39,19 @@ class Order implements ControllerProviderInterface, ServiceProviderInterface }); $app['controller.prod.order'] = $app->share(function (PhraseaApplication $app) { - return (new ProdOrderController($app)) + $controller = new ProdOrderController( + $app, + $app['repo.orders'], + $app['repo.order-elements'], + $app['provider.order_basket'] + ); + + $controller ->setDispatcher($app['dispatcher']) ->setEntityManagerLocator(new LazyLocator($app, 'orm.em')) - ->setUserQueryFactory(new LazyLocator($app, 'phraseanet.user-query')) - ; + ->setUserQueryFactory(new LazyLocator($app, 'phraseanet.user-query')); + + return $controller; }); } @@ -64,7 +72,7 @@ class Order implements ControllerProviderInterface, ServiceProviderInterface }; $controllers->before(function () use ($firewall) { - $firewall->requireRight('order'); + $firewall->requireRight(\ACL::CANCMD); }); $controllers->get('/', 'controller.prod.order:displayOrders') diff --git a/lib/Alchemy/Phrasea/ControllerProvider/Prod/Push.php b/lib/Alchemy/Phrasea/ControllerProvider/Prod/Push.php index e787946c17..a3a99718bd 100644 --- a/lib/Alchemy/Phrasea/ControllerProvider/Prod/Push.php +++ b/lib/Alchemy/Phrasea/ControllerProvider/Prod/Push.php @@ -46,7 +46,7 @@ class Push implements ControllerProviderInterface, ServiceProviderInterface $firewall = $this->getFirewall($app); $controllers->before(function () use ($firewall) { - $firewall->requireRight('push'); + $firewall->requireRight(\ACL::CANPUSH); }); $controllers->post('/sendform/', 'controller.prod.push:postFormAction'); diff --git a/lib/Alchemy/Phrasea/ControllerProvider/Prod/Share.php b/lib/Alchemy/Phrasea/ControllerProvider/Prod/Share.php index 1fb7d1de43..e4e58e53b2 100644 --- a/lib/Alchemy/Phrasea/ControllerProvider/Prod/Share.php +++ b/lib/Alchemy/Phrasea/ControllerProvider/Prod/Share.php @@ -49,7 +49,7 @@ class Share implements ControllerProviderInterface, ServiceProviderInterface ->before(function (Request $request) use ($app, $firewall) { $firewall->requireRightOnSbas( \phrasea::sbasFromBas($app, $request->attributes->get('base_id')), - 'bas_chupub' + \ACL::BAS_CHUPUB ); }) ->bind('share_record'); diff --git a/lib/Alchemy/Phrasea/ControllerProvider/Prod/Tools.php b/lib/Alchemy/Phrasea/ControllerProvider/Prod/Tools.php index 103e9aad51..de63ae1375 100644 --- a/lib/Alchemy/Phrasea/ControllerProvider/Prod/Tools.php +++ b/lib/Alchemy/Phrasea/ControllerProvider/Prod/Tools.php @@ -46,7 +46,7 @@ class Tools implements ControllerProviderInterface, ServiceProviderInterface $firewall = $this->getFirewall($app); $controllers->before(function () use ($firewall) { - $firewall->requireRight('doctools'); + $firewall->requireRight(\ACL::IMGTOOLS); }); $controllers->get('/', 'controller.prod.tools:indexAction'); diff --git a/lib/Alchemy/Phrasea/ControllerProvider/Prod/Upload.php b/lib/Alchemy/Phrasea/ControllerProvider/Prod/Upload.php index 1982ac8b73..985944957d 100644 --- a/lib/Alchemy/Phrasea/ControllerProvider/Prod/Upload.php +++ b/lib/Alchemy/Phrasea/ControllerProvider/Prod/Upload.php @@ -55,7 +55,7 @@ class Upload implements ControllerProviderInterface, ServiceProviderInterface $firewall = $this->getFirewall($app); $controllers->before(function () use ($firewall) { - $firewall->requireRight('addrecord'); + $firewall->requireRight(\ACL::CANADDRECORD); }); $controllers->get('/', 'controller.prod.upload:getUploadForm') diff --git a/lib/Alchemy/Phrasea/Core/Configuration/RegistryFormManipulator.php b/lib/Alchemy/Phrasea/Core/Configuration/RegistryFormManipulator.php new file mode 100644 index 0000000000..9543cbbc6d --- /dev/null +++ b/lib/Alchemy/Phrasea/Core/Configuration/RegistryFormManipulator.php @@ -0,0 +1,178 @@ +factory = $factory; + $this->languages = $languages; + $this->translator = $translator; + } + + /** + * Creates a setup form. Set data if a configuration is given. + * + * @param PropertyAccess $conf + * + * @return FormInterface + */ + public function createForm(PropertyAccess $conf = null) + { + $form = $this->factory->create(new MainConfigurationFormType($this->translator, $this->languages)); + $currentConf = $conf ? ($conf->get('registry') ?: []) : []; + $data = array_replace_recursive($this->getDefaultData($currentConf), $currentConf); + $form->setData($data); + + return $form; + } + + /** + * Gets the registry data given a submitted form. + * Default configuration is returned if no form provided. + * + * @param FormInterface $form + * + * @param PropertyAccess $conf + * @return array + */ + public function getRegistryData(FormInterface $form = null, PropertyAccess $conf = null) + { + $data = []; + + if (null !== $form) { + if (!$form->isSubmitted()) { + throw new RuntimeException('Form must have been submitted'); + } + $newData = $form->getData(); + $data = $this->filterNullValues($newData); + } + + $currentConf = $conf ? ($conf->get('registry') ?: []) : []; + + return array_replace_recursive($this->getDefaultData($currentConf), $data); + } + + private function filterNullValues(array &$array) + { + return array_filter($array, function (&$value) { + if (is_array($value)) { + $value = $this->filterNullValues($value); + } + + return null !== $value; + }); + } + + private function getDefaultData(array $config) + { + return [ + 'general' => [ + 'title' => 'Phraseanet', + 'keywords' => null, + 'description' => null, + 'analytics' => null, + 'allow-indexation' => true, + 'home-presentation-mode' => 'GALLERIA', + 'default-subdef-url-ttl' => 7200, + ], + 'modules' => [ + 'thesaurus' => true, + 'stories' => true, + 'doc-substitution' => true, + 'thumb-substitution' => true, + 'anonymous-report' => false, + ], + 'actions' => [ + 'download-max-size' => 120, + 'validation-reminder-days' => 2, + 'validation-expiration-days' => 10, + 'auth-required-for-export' => true, + 'tou-validation-required-for-export' => false, + 'export-title-choice' => false, + 'default-export-title' => 'title', + 'social-tools' => 'none', + 'enable-push-authentication' => false, + 'force-push-authentication' => false, + 'enable-feed-notification' => true, + ], + 'ftp' => [ + 'ftp-enabled' => false, + 'ftp-user-access' => false, + ], + 'registration' => [ + 'auto-select-collections' => true, + 'auto-register-enabled' => false, + ], + 'maintenance' => [ + 'message' => 'The application is down for maintenance', + 'enabled' => false, + ], + 'api-clients' => [ + 'api-enabled' => true, + 'navigator-enabled' => true, + 'office-enabled' => true, + ], + 'webservices' => [ + 'google-charts-enabled' => true, + 'geonames-server' => 'http://geonames.alchemyasp.com/', + 'captchas-enabled' => false, + 'recaptcha-public-key' => '', + 'recaptcha-private-key' => '', + ], + 'executables' => [ + 'h264-streaming-enabled' => false, + 'auth-token-directory' => null, + 'auth-token-directory-path' => null, + 'auth-token-passphrase' => null, + 'php-conf-path' => null, + 'imagine-driver' => '', + 'ffmpeg-threads' => 2, + 'pdf-max-pages' => 5, + ], + 'searchengine' => [ + 'min-letters-truncation' => 1, + 'default-query' => '', + 'default-query-type' => 0, + ], + 'email' => [ + 'emitter-email' => 'phraseanet@example.com', + 'prefix' => null, + 'smtp-enabled' => false, + 'smtp-auth-enabled' => false, + 'smtp-host' => null, + 'smtp-port' => null, + 'smtp-secure-mode' => 'tls', + 'smtp-user' => null, + 'smtp-password' => isset($config['email']['smtp-password']) ? $config['email']['smtp-password'] : null, + ], + ]; + } +} diff --git a/lib/Alchemy/Phrasea/Core/Configuration/RegistryManipulator.php b/lib/Alchemy/Phrasea/Core/Configuration/RegistryManipulator.php index a8a73423c9..1fba436dbe 100644 --- a/lib/Alchemy/Phrasea/Core/Configuration/RegistryManipulator.php +++ b/lib/Alchemy/Phrasea/Core/Configuration/RegistryManipulator.php @@ -17,170 +17,12 @@ use Symfony\Component\Form\FormFactoryInterface; use Symfony\Component\Form\FormInterface; use Symfony\Component\Translation\TranslatorInterface; -class RegistryManipulator +/** + * Class RegistryManipulator + * @package Alchemy\Phrasea\Core\Configuration + * @deprecated Use RegistryFormManipulator instead + */ +class RegistryManipulator extends RegistryFormManipulator { - /** - * @var FormFactoryInterface - */ - private $factory; - /** - * @var array - */ - private $languages; - - /** - * @var TranslatorInterface - */ - private $translator; - - /** - * @param FormFactoryInterface $factory - * @param TranslatorInterface $translator - * @param array $languages - */ - public function __construct(FormFactoryInterface $factory, TranslatorInterface $translator, array $languages) - { - $this->factory = $factory; - $this->languages = $languages; - $this->translator = $translator; - } - - /** - * Creates a setup form. Set data if a configuration is given. - * - * @param PropertyAccess $conf - * - * @return FormInterface - */ - public function createForm(PropertyAccess $conf = null) - { - $form = $this->factory->create(new MainConfigurationFormType($this->translator, $this->languages)); - $currentConf = $conf ? ($conf->get('registry') ?: []) : []; - $data = array_replace_recursive($this->getDefaultData(), $currentConf); - $form->setData($data); - - return $form; - } - - /** - * Gets the registry data given a submitted form. - * Default configuration is returned if no form provided. - * - * @param FormInterface $form - * - * @return array - * - * @throws RuntimeException - */ - public function getRegistryData(FormInterface $form = null) - { - $data = []; - - if (null !== $form) { - if (!$form->isSubmitted()) { - throw new RuntimeException('Form must have been submitted'); - } - $newData = $form->getData(); - $data = $this->filterNullValues($newData); - } - - return array_replace_recursive($this->getDefaultData(), $data); - } - - private function filterNullValues(array &$array) - { - return array_filter($array, function (&$value) { - if (is_array($value)) { - $value = $this->filterNullValues($value); - } - - return null !== $value; - }); - } - - private function getDefaultData() - { - return [ - 'general' => [ - 'title' => 'Phraseanet', - 'keywords' => null, - 'description' => null, - 'analytics' => null, - 'allow-indexation' => true, - 'home-presentation-mode' => 'GALLERIA', - 'default-subdef-url-ttl' => 7200, - ], - 'modules' => [ - 'thesaurus' => true, - 'stories' => true, - 'doc-substitution' => true, - 'thumb-substitution' => true, - 'anonymous-report' => false, - ], - 'actions' => [ - 'download-max-size' => 120, - 'validation-reminder-days' => 2, - 'validation-expiration-days' => 10, - 'auth-required-for-export' => true, - 'tou-validation-required-for-export' => false, - 'export-title-choice' => false, - 'default-export-title' => 'title', - 'social-tools' => 'none', - 'enable-push-authentication' => false, - 'force-push-authentication' => false, - 'enable-feed-notification' => true, - ], - 'ftp' => [ - 'ftp-enabled' => false, - 'ftp-user-access' => false, - ], - 'registration' => [ - 'auto-select-collections' => true, - 'auto-register-enabled' => false, - ], - 'maintenance' => [ - 'message' => 'The application is down for maintenance', - 'enabled' => false, - ], - 'api-clients' => [ - 'api-enabled' => true, - 'navigator-enabled' => true, - 'office-enabled' => true, - ], - 'webservices' => [ - 'google-charts-enabled' => true, - 'geonames-server' => 'http://geonames.alchemyasp.com/', - 'captchas-enabled' => false, - 'recaptcha-public-key' => '', - 'recaptcha-private-key' => '', - ], - 'executables' => [ - 'h264-streaming-enabled' => false, - 'auth-token-directory' => null, - 'auth-token-directory-path' => null, - 'auth-token-passphrase' => null, - 'php-conf-path' => null, - 'imagine-driver' => '', - 'ffmpeg-threads' => 2, - 'pdf-max-pages' => 5, - ], - 'searchengine' => [ - 'min-letters-truncation' => 1, - 'default-query' => '', - 'default-query-type' => 0, - ], - 'email' => [ - 'emitter-email' => 'phraseanet@example.com', - 'prefix' => null, - 'smtp-enabled' => false, - 'smtp-auth-enabled' => false, - 'smtp-host' => null, - 'smtp-port' => null, - 'smtp-secure-mode' => 'tls', - 'smtp-user' => null, - 'smtp-password' => null, - ], - ]; - } } diff --git a/lib/Alchemy/Phrasea/Core/Event/Subscriber/LazaretSubscriber.php b/lib/Alchemy/Phrasea/Core/Event/Subscriber/LazaretSubscriber.php index f4c0b95dde..0db6fa8794 100644 --- a/lib/Alchemy/Phrasea/Core/Event/Subscriber/LazaretSubscriber.php +++ b/lib/Alchemy/Phrasea/Core/Event/Subscriber/LazaretSubscriber.php @@ -38,7 +38,7 @@ class LazaretSubscriber extends AbstractNotificationSubscriber $query = $this->app['phraseanet.user-query']; $users = $query ->on_base_ids([$lazaretFile->getBaseId()]) - ->who_have_right(['canaddrecord']) + ->who_have_right([\ACL::CANADDRECORD]) ->execute() ->get_results(); diff --git a/lib/Alchemy/Phrasea/Core/Event/Subscriber/OrderSubscriber.php b/lib/Alchemy/Phrasea/Core/Event/Subscriber/OrderSubscriber.php index d17c725cd1..142537f418 100644 --- a/lib/Alchemy/Phrasea/Core/Event/Subscriber/OrderSubscriber.php +++ b/lib/Alchemy/Phrasea/Core/Event/Subscriber/OrderSubscriber.php @@ -48,7 +48,7 @@ class OrderSubscriber extends AbstractNotificationSubscriber $query = $this->app['phraseanet.user-query']; /** @var User[] $users */ $users = $query->on_base_ids($base_ids) - ->who_have_right(['order_master']) + ->who_have_right([\ACL::ORDER_MASTER]) ->execute()->get_results(); if (count($users) == 0) { diff --git a/lib/Alchemy/Phrasea/Filesystem/FilesystemService.php b/lib/Alchemy/Phrasea/Filesystem/FilesystemService.php index bbe1c32ab9..9d5e75822d 100644 --- a/lib/Alchemy/Phrasea/Filesystem/FilesystemService.php +++ b/lib/Alchemy/Phrasea/Filesystem/FilesystemService.php @@ -115,6 +115,7 @@ class FilesystemService * @param \databox $databox * @param string $source * @param string $filename + * @return string */ public function writeMediaSourceFile(\databox $databox, $source, $filename) { @@ -122,6 +123,8 @@ class FilesystemService $this->filesystem->copy($source, $realPath, true); $this->filesystem->chmod($realPath, 0760); + + return $realPath; } /** diff --git a/lib/Alchemy/Phrasea/Helper/Prod.php b/lib/Alchemy/Phrasea/Helper/Prod.php index 9aab76ad72..3537b367c0 100644 --- a/lib/Alchemy/Phrasea/Helper/Prod.php +++ b/lib/Alchemy/Phrasea/Helper/Prod.php @@ -93,7 +93,7 @@ class Prod extends Helper if (!$bases[$sbasId]['thesaurus']) { continue; } - if (!$this->app->getAclForUser($this->app->getAuthenticatedUser())->has_right_on_sbas($sbasId, 'bas_modif_th')) { + if (!$this->app->getAclForUser($this->app->getAuthenticatedUser())->has_right_on_sbas($sbasId, \ACL::BAS_MODIF_TH)) { continue; } diff --git a/lib/Alchemy/Phrasea/Helper/User/Edit.php b/lib/Alchemy/Phrasea/Helper/User/Edit.php index e8d0381dd2..2fab6b47f4 100644 --- a/lib/Alchemy/Phrasea/Helper/User/Edit.php +++ b/lib/Alchemy/Phrasea/Helper/User/Edit.php @@ -71,7 +71,7 @@ class Edit extends \Alchemy\Phrasea\Helper\Helper protected function delete_user(User $user) { - $list = array_keys($this->app->getAclForUser($this->app->getAuthenticatedUser())->get_granted_base(['canadmin'])); + $list = array_keys($this->app->getAclForUser($this->app->getAuthenticatedUser())->get_granted_base([\ACL::CANADMIN])); $this->app->getAclForUser($user)->revoke_access_from_bases($list); @@ -84,55 +84,54 @@ class Edit extends \Alchemy\Phrasea\Helper\Helper public function get_users_rights() { - $list = array_keys($this->app->getAclForUser($this->app->getAuthenticatedUser())->get_granted_base(['canadmin'])); + $list = array_keys($this->app->getAclForUser($this->app->getAuthenticatedUser())->get_granted_base([\ACL::CANADMIN])); - $sql = "SELECT - b.sbas_id, - b.base_id, - sum(actif) as actif, - sum(canputinalbum) as canputinalbum, - sum(candwnldpreview) as candwnldpreview, - sum(candwnldhd) as candwnldhd, - sum(cancmd) as cancmd, - sum(nowatermark) as nowatermark, + $sql = "SELECT b.sbas_id, b.base_id,\n" - sum(canaddrecord) as canaddrecord, - sum(canmodifrecord) as canmodifrecord, - sum(chgstatus) as chgstatus, - sum(candeleterecord) as candeleterecord, - sum(imgtools) as imgtools, + . " SUM(actif) AS actif,\n" + . " SUM(canputinalbum) AS canputinalbum,\n" + . " SUM(candwnldpreview) AS candwnldpreview,\n" + . " SUM(candwnldhd) AS candwnldhd,\n" + . " SUM(cancmd) AS cancmd,\n" + . " SUM(nowatermark) AS nowatermark,\n" - sum(canadmin) as canadmin, - sum(canreport) as canreport, - sum(canpush) as canpush, - sum(manage) as manage, - sum(modify_struct) as modify_struct, + . " SUM(canaddrecord) AS canaddrecord,\n" + . " SUM(canmodifrecord) AS canmodifrecord,\n" + . " SUM(chgstatus) AS chgstatus,\n" + . " SUM(candeleterecord) AS candeleterecord,\n" + . " SUM(imgtools) AS imgtools,\n" - sum(sbu.bas_modif_th) as bas_modif_th, - sum(sbu.bas_manage) as bas_manage, - sum(sbu.bas_modify_struct) as bas_modify_struct, - sum(sbu.bas_chupub) as bas_chupub, + . " SUM(canadmin) AS canadmin,\n" + . " SUM(canreport) AS canreport,\n" + . " SUM(canpush) AS canpush,\n" + . " SUM(manage) AS manage,\n" + . " SUM(modify_struct) AS modify_struct,\n" - sum(time_limited) as time_limited, - DATE_FORMAT(limited_from,'%Y%m%d') as limited_from, - DATE_FORMAT(limited_to,'%Y%m%d') as limited_to, + . " SUM(sbu.bas_modif_th) AS bas_modif_th,\n" + . " SUM(sbu.bas_manage) AS bas_manage,\n" + . " SUM(sbu.bas_modify_struct) AS bas_modify_struct,\n" + . " SUM(sbu.bas_chupub) AS bas_chupub,\n" - sum(restrict_dwnld) as restrict_dwnld, - sum(remain_dwnld) as remain_dwnld, - sum(month_dwnld_max) as month_dwnld_max, + . " SUM(time_limited) AS time_limited,\n" + . " SUM(restrict_dwnld) AS restrict_dwnld,\n" - sum(mask_and + mask_xor) as masks + // --- todo : wtf doing sum on non booleans ? + . " SUM(remain_dwnld) AS remain_dwnld,\n" + . " SUM(month_dwnld_max) AS month_dwnld_max,\n" + . " SUM(mask_and + mask_xor) AS masks,\n" + // --- - FROM (Users u, bas b, sbas s) - LEFT JOIN (basusr bu) - ON (bu.base_id = b.base_id AND u.id = bu.usr_id) - LEFT join sbasusr sbu - ON (sbu.sbas_id = b.sbas_id AND u.id = sbu.usr_id) - WHERE ( (u.id IN (:users) ) - AND b.sbas_id = s.sbas_id - AND (b.base_id IN (:bases))) - GROUP BY b.base_id - ORDER BY s.ord, s.sbas_id, b.ord, b.base_id "; + // -- todo : wtf no aggregate fct ? + . " DATE_FORMAT(limited_from,'%Y%m%d') AS limited_from,\n" + . " DATE_FORMAT(limited_to,'%Y%m%d') AS limited_to\n" + // --- + + . " FROM (Users u, bas b, sbas s)\n" + . " LEFT JOIN (basusr bu) ON (bu.base_id = b.base_id AND u.id = bu.usr_id)\n" + . " LEFT join sbasusr sbu ON (sbu.sbas_id = b.sbas_id AND u.id = sbu.usr_id)\n" + . " WHERE ( (u.id IN (:users) ) AND b.sbas_id = s.sbas_id AND (b.base_id IN (:bases)))\n" + . " GROUP BY b.base_id\n" + . " ORDER BY s.ord, s.sbas_id, b.ord, b.base_id "; $rs = $this->app->getApplicationBox()->get_connection()->fetchAll( $sql, @@ -146,10 +145,10 @@ class Edit extends \Alchemy\Phrasea\Helper\Helper ] ); - $sql = 'SELECT base_id, sum(1) as access FROM basusr - WHERE (usr_id IN (:users)) - AND (base_id IN (:bases)) - GROUP BY base_id'; + $sql = "SELECT base_id, SUM(1) AS access FROM basusr\n" + . " WHERE (usr_id IN (:users)) AND (base_id IN (:bases))\n" + . " GROUP BY base_id"; + $access = $this->app->getApplicationBox()->get_connection()->fetchAll( $sql, [ @@ -164,12 +163,13 @@ class Edit extends \Alchemy\Phrasea\Helper\Helper $base_ids = []; foreach ($access as $acc) { - $base_ids[$acc['base_id']] = $acc; + $base_ids[$acc['base_id']] = $acc['access']; } unset($access); + // add a 'access' column foreach ($rs as $k => $row) { - $rs[$k]['access'] = array_key_exists($row['base_id'], $base_ids) ? $base_ids[$row['base_id']]['access'] : '0'; + $rs[$k]['access'] = array_key_exists($row['base_id'], $base_ids) ? $base_ids[$row['base_id']] : '0'; foreach ($row as $dk => $data) { if (is_null($data)) $rs[$k][$dk] = '0'; @@ -477,41 +477,45 @@ class Edit extends \Alchemy\Phrasea\Helper\Helper public function apply_rights() { $ACL = $this->app->getAclForUser($this->app->getAuthenticatedUser()); - $base_ids = array_keys($ACL->get_granted_base(['canadmin'])); + $base_ids = array_keys($ACL->get_granted_base([\ACL::CANADMIN])); $update = $create = $delete = $create_sbas = $update_sbas = []; foreach ($base_ids as $base_id) { $rights = [ - 'access', - 'actif', - 'canputinalbum', - 'nowatermark', - 'candwnldpreview', - 'candwnldhd', - 'cancmd', - 'canaddrecord', - 'canmodifrecord', - 'chgstatus', - 'candeleterecord', - 'imgtools', - 'canadmin', - 'canreport', - 'canpush', - 'manage', - 'modify_struct' + \ACL::ACCESS, + \ACL::ACTIF, + \ACL::CANPUTINALBUM, + \ACL::NOWATERMARK, + \ACL::CANDWNLDPREVIEW, + \ACL::CANDWNLDHD, + \ACL::CANCMD, + \ACL::CANADDRECORD, + \ACL::CANMODIFRECORD, + \ACL::CHGSTATUS, + \ACL::CANDELETERECORD, + \ACL::IMGTOOLS, + \ACL::CANADMIN, + \ACL::CANREPORT, + \ACL::CANPUSH, + \ACL::COLL_MANAGE, + \ACL::COLL_MODIFY_STRUCT ]; foreach ($rights as $k => $right) { - if (($right == 'access' && !$ACL->has_access_to_base($base_id)) - || ($right != 'access' && !$ACL->has_right_on_base($base_id, $right))) { + if (($right == \ACL::ACCESS && !$ACL->has_access_to_base($base_id)) + || ($right != \ACL::ACCESS && !$ACL->has_right_on_base($base_id, $right))) { unset($rights[$k]); continue; } $rights[$k] = $right . '_' . $base_id; } + + // todo : wtf check if parm contains good types (a checkbox should be a bool, not a "0" or "1" + // as required by ACL::update_rights_to_bas(...) $parm = $this->unserializedRequestData($this->app['request'], $rights, 'values'); foreach ($parm as $p => $v) { + // p is like {bid}_{right} => right-value if (trim($v) == '') continue; @@ -520,14 +524,18 @@ class Edit extends \Alchemy\Phrasea\Helper\Helper $p = implode('_', $serial); - if ($p == 'access') { + if ($p == \ACL::ACCESS) { if ($v === '1') { $create_sbas[\phrasea::sbasFromBas($this->app, $base_id)] = \phrasea::sbasFromBas($this->app, $base_id); $create[] = $base_id; - } else + } + else { $delete[] = $base_id; - } else { + } + } + else { $create_sbas[\phrasea::sbasFromBas($this->app, $base_id)] = \phrasea::sbasFromBas($this->app, $base_id); + // todo : wtf $update is arg. for ACL::update_rights_to_base(...) but $v is always a string. how to convert to bool ? $update[$base_id][$p] = $v; } } @@ -537,10 +545,10 @@ class Edit extends \Alchemy\Phrasea\Helper\Helper foreach ($sbas_ids as $databox) { $rights = [ - 'bas_modif_th', - 'bas_manage', - 'bas_modify_struct', - 'bas_chupub' + \ACL::BAS_MODIF_TH, + \ACL::BAS_MANAGE, + \ACL::BAS_MODIFY_STRUCT, + \ACL::BAS_CHUPUB ]; foreach ($rights as $k => $right) { if (!$ACL->has_right_on_sbas($databox->get_sbas_id(), $right)) { @@ -550,6 +558,8 @@ class Edit extends \Alchemy\Phrasea\Helper\Helper $rights[$k] = $right . '_' . $databox->get_sbas_id(); } + // todo : wtf check if parm contains good types (a checkbox should be a bool, not a "0" or "1" + // as required by ACL::update_rights_to_sbas(...) $parm = $this->unserializedRequestData($this->app['request'], $rights, 'values'); foreach ($parm as $p => $v) { @@ -569,6 +579,7 @@ class Edit extends \Alchemy\Phrasea\Helper\Helper try { $this->app->getApplicationBox()->get_connection()->beginTransaction(); + /** @var User $user */ $user = $this->app['repo.users']->find($usr_id); $this->app->getAclForUser($user)->revoke_access_from_bases($delete) @@ -576,11 +587,18 @@ class Edit extends \Alchemy\Phrasea\Helper\Helper ->give_access_to_sbas($create_sbas); foreach ($update as $base_id => $rights) { - $this->app->getAclForUser($user)->update_rights_to_base($base_id, $rights); + $this->app->getAclForUser($user) + ->update_rights_to_base( + $base_id, + $rights + ); } foreach ($update_sbas as $sbas_id => $rights) { - $this->app->getAclForUser($user)->update_rights_to_sbas($sbas_id, $rights); + $this->app->getAclForUser($user)->update_rights_to_sbas( + $sbas_id, + $rights + ); } $this->app->getApplicationBox()->get_connection()->commit(); @@ -611,18 +629,18 @@ class Edit extends \Alchemy\Phrasea\Helper\Helper } $infos = [ - 'gender' - , 'first_name' - , 'last_name' - , 'email' - , 'address' - , 'zip' - , 'geonameid' - , 'function' - , 'company' - , 'activite' - , 'telephone' - , 'fax' + 'gender', + 'first_name', + 'last_name', + 'email', + 'address', + 'zip', + 'geonameid', + 'function', + 'company', + 'activite', + 'telephone', + 'fax' ]; $parm = $this->unserializedRequestData($this->request, $infos, 'user_infos'); @@ -688,7 +706,7 @@ class Edit extends \Alchemy\Phrasea\Helper\Helper throw new AccessDeniedHttpException('You are not the owner of the template'); } - $base_ids = array_keys($this->app->getAclForUser($this->app->getAuthenticatedUser())->get_granted_base(['canadmin'])); + $base_ids = array_keys($this->app->getAclForUser($this->app->getAuthenticatedUser())->get_granted_base([\ACL::CANADMIN])); foreach ($this->users as $usr_id) { $user = $this->app['repo.users']->find($usr_id); @@ -744,7 +762,7 @@ class Edit extends \Alchemy\Phrasea\Helper\Helper $activate = !!$this->request->get('limit'); - $base_ids = array_keys($this->app->getAclForUser($this->app->getAuthenticatedUser())->get_granted_base(['canadmin'])); + $base_ids = array_keys($this->app->getAclForUser($this->app->getAuthenticatedUser())->get_granted_base([\ACL::CANADMIN])); foreach ($this->users as $usr_id) { $user = $this->app['repo.users']->find($usr_id); @@ -763,7 +781,7 @@ class Edit extends \Alchemy\Phrasea\Helper\Helper public function resetRights() { - $base_ids = array_keys($this->app->getAclForUser($this->app->getAuthenticatedUser())->get_granted_base(['canadmin'])); + $base_ids = array_keys($this->app->getAclForUser($this->app->getAuthenticatedUser())->get_granted_base([\ACL::CANADMIN])); foreach ($this->users as $usr_id) { $user = $this->app['repo.users']->find($usr_id); diff --git a/lib/Alchemy/Phrasea/Helper/User/Manage.php b/lib/Alchemy/Phrasea/Helper/User/Manage.php index 979195fb10..bea053f56c 100644 --- a/lib/Alchemy/Phrasea/Helper/User/Manage.php +++ b/lib/Alchemy/Phrasea/Helper/User/Manage.php @@ -71,7 +71,7 @@ class Manage extends Helper ->last_model_is($this->query_parms['last_model']) ->get_inactives($this->query_parms['inactives']) ->include_templates(false) - ->on_bases_where_i_am($this->app->getAclForUser($this->app->getAuthenticatedUser()), ['canadmin']) + ->on_bases_where_i_am($this->app->getAclForUser($this->app->getAuthenticatedUser()), [\ACL::CANADMIN]) ->execute(); return $results->get_results(); @@ -109,7 +109,7 @@ class Manage extends Helper ->last_model_is($this->query_parms['last_model']) ->get_inactives($this->query_parms['inactives']) ->include_templates(true) - ->on_bases_where_i_am($this->app->getAclForUser($this->app->getAuthenticatedUser()), ['canadmin']) + ->on_bases_where_i_am($this->app->getAclForUser($this->app->getAuthenticatedUser()), [\ACL::CANADMIN]) ->limit($offset_start, $results_quantity) ->execute(); diff --git a/lib/Alchemy/Phrasea/Media/MediaTypeFactory.php b/lib/Alchemy/Phrasea/Media/MediaTypeFactory.php index 33a351ce5f..2bc93f907f 100644 --- a/lib/Alchemy/Phrasea/Media/MediaTypeFactory.php +++ b/lib/Alchemy/Phrasea/Media/MediaTypeFactory.php @@ -30,6 +30,8 @@ class MediaTypeFactory return new Type\Document(); case Type\Type::TYPE_FLASH: return new Type\Flash(); + case Type\Type::TYPE_UNKNOWN: + return new Type\Unknown(); } throw new \RuntimeException('Could not create requested media type'); diff --git a/lib/Alchemy/Phrasea/Media/Subdef/Subdef.php b/lib/Alchemy/Phrasea/Media/Subdef/Subdef.php index db42b01c84..339d50002f 100644 --- a/lib/Alchemy/Phrasea/Media/Subdef/Subdef.php +++ b/lib/Alchemy/Phrasea/Media/Subdef/Subdef.php @@ -20,6 +20,7 @@ interface Subdef const TYPE_VIDEO = 'video'; const TYPE_AUDIO = 'audio'; const TYPE_FLEXPAPER = 'flexpaper'; + const TYPE_UNKNOWN = 'unknown'; /** * One of Subdef Type const diff --git a/lib/Alchemy/Phrasea/Media/Subdef/Unknown.php b/lib/Alchemy/Phrasea/Media/Subdef/Unknown.php new file mode 100644 index 0000000000..4a19f4b3d0 --- /dev/null +++ b/lib/Alchemy/Phrasea/Media/Subdef/Unknown.php @@ -0,0 +1,69 @@ +translator = $translator; + + $this->registerOption(new OptionType\Range($this->translator->trans('Dimension'), self::OPTION_SIZE, 20, 3000, 800)); + $this->registerOption(new OptionType\Range($this->translator->trans('Resolution'), self::OPTION_RESOLUTION, 50, 300, 72)); + $this->registerOption(new OptionType\Boolean($this->translator->trans('Remove ICC Profile'), self::OPTION_STRIP, false)); + $this->registerOption(new OptionType\Boolean($this->translator->trans('Flatten layers'), self::OPTION_FLATTEN, false)); + $this->registerOption(new OptionType\Range($this->translator->trans('Quality'), self::OPTION_QUALITY, 0, 100, 75)); + $this->registerOption(new OptionType\Enum('Image Codec', self::OPTION_ICODEC, array('jpeg', 'png', 'tiff'), 'jpeg')); + } + + public function getType() + { + return self::TYPE_IMAGE; + } + + public function getDescription() + { + return $this->translator->trans('Generates an image'); + } + + public function getMediaAlchemystSpec() + { + if (! $this->spec) { + $this->spec = new ImageSpecification(); + } + + $size = $this->getOption(self::OPTION_SIZE)->getValue(); + $resolution = $this->getOption(self::OPTION_RESOLUTION)->getValue(); + + $this->spec->setImageCodec($this->getOption(self::OPTION_ICODEC)->getValue()); + $this->spec->setResizeMode(ImageSpecification::RESIZE_MODE_INBOUND_FIXEDRATIO); + $this->spec->setDimensions($size, $size); + $this->spec->setQuality($this->getOption(self::OPTION_QUALITY)->getValue()); + $this->spec->setStrip($this->getOption(self::OPTION_STRIP)->getValue()); + $this->spec->setFlatten($this->getOption(self::OPTION_FLATTEN)->getValue()); + $this->spec->setResolution($resolution, $resolution); + + return $this->spec; + } +} diff --git a/lib/Alchemy/Phrasea/Media/SubdefSubstituer.php b/lib/Alchemy/Phrasea/Media/SubdefSubstituer.php index 6333ba4fd1..3bbdc2666d 100644 --- a/lib/Alchemy/Phrasea/Media/SubdefSubstituer.php +++ b/lib/Alchemy/Phrasea/Media/SubdefSubstituer.php @@ -67,9 +67,9 @@ class SubdefSubstituer $source = $file->getRealPath(); $target = $this->fs->generateDocumentFilename($record, $file); - $this->fs->writeMediaSourceFile($record->getDatabox(), $source, $target); + $target = $this->fs->writeMediaSourceFile($record->getDatabox(), $source, $target); - $media = $this->mediavorus->guess($source); + $media = $this->mediavorus->guess($target); $this->createMediaSubdef($record, 'document', $media); diff --git a/lib/Alchemy/Phrasea/Media/Type/Type.php b/lib/Alchemy/Phrasea/Media/Type/Type.php index 6febd03a9c..731ced8149 100644 --- a/lib/Alchemy/Phrasea/Media/Type/Type.php +++ b/lib/Alchemy/Phrasea/Media/Type/Type.php @@ -18,6 +18,7 @@ interface Type const TYPE_DOCUMENT = 'document'; const TYPE_FLASH = 'flash'; const TYPE_IMAGE = 'image'; + const TYPE_UNKNOWN = 'unknown'; public function getType(); } diff --git a/lib/Alchemy/Phrasea/Media/Type/Unknown.php b/lib/Alchemy/Phrasea/Media/Type/Unknown.php new file mode 100644 index 0000000000..1b22583be9 --- /dev/null +++ b/lib/Alchemy/Phrasea/Media/Type/Unknown.php @@ -0,0 +1,21 @@ +sha256 = $sha256; } + /** {@inheritdoc} */ + public function getWidth() + { + return $this->width; + } + + /** {@inheritdoc} */ + public function setWidth($width) + { + $this->width = $width; + } + + /** {@inheritdoc} */ + public function getHeight() + { + return $this->height; + } + + /** {@inheritdoc} */ + public function setHeight($height) + { + $this->height = $height; + } + + /** {@inheritdoc} */ + public function getSize() + { + return $this->size; + } + + /** {@inheritdoc} */ + public function setSize($size) + { + $this->size = $size; + } + /** * @param string|null $locale * diff --git a/lib/Alchemy/Phrasea/Model/Manipulator/ACLManipulator.php b/lib/Alchemy/Phrasea/Model/Manipulator/ACLManipulator.php index 4a07f69524..748bf9c1fc 100644 --- a/lib/Alchemy/Phrasea/Model/Manipulator/ACLManipulator.php +++ b/lib/Alchemy/Phrasea/Model/Manipulator/ACLManipulator.php @@ -71,12 +71,15 @@ class ACLManipulator implements ManipulatorInterface { $collections = $databox->get_collections(); - $acl->update_rights_to_sbas($databox->get_sbas_id(), [ - 'bas_manage' => '1', - 'bas_modify_struct' => '1', - 'bas_modif_th' => '1', - 'bas_chupub' => '1' - ]); + $acl->update_rights_to_sbas( + $databox->get_sbas_id(), + [ + \ACL::BAS_MANAGE => true, + \ACL::BAS_MODIFY_STRUCT => true, + \ACL::BAS_MODIF_TH => true, + \ACL::BAS_CHUPUB => true + ] + ); $acl->give_access_to_base(array_map(function (\collection $collection) { return $collection->get_base_id(); @@ -100,26 +103,28 @@ class ACLManipulator implements ManipulatorInterface $acl->set_limits($baseId, false); $acl->remove_quotas_on_base($baseId); $acl->set_masks_on_base($baseId, '0', '0', '0', '0'); - $acl->update_rights_to_base($baseId, [ - 'canputinalbum' => '1', - 'candwnldhd' => '1', - 'candwnldsubdef' => '1', - 'nowatermark' => '1', - 'candwnldpreview' => '1', - 'cancmd' => '1', - 'canadmin' => '1', - 'canreport' => '1', - 'canpush' => '1', - 'creationdate' => '1', - 'canaddrecord' => '1', - 'canmodifrecord' => '1', - 'candeleterecord' => '1', - 'chgstatus' => '1', - 'imgtools' => '1', - 'manage' => '1', - 'modify_struct' => '1', - 'bas_modify_struct' => '1' - ]); + $acl->update_rights_to_base( + $baseId, + [ + 'creationdate' => '1', // todo : wtf + \ACL::CANPUTINALBUM => true, + \ACL::CANDWNLDHD => true, + \ACL::NOWATERMARK => true, + \ACL::CANDWNLDPREVIEW => true, + \ACL::CANCMD => true, + \ACL::CANADMIN => true, + \ACL::CANREPORT => true, + \ACL::CANPUSH => true, + \ACL::CANADDRECORD => true, + \ACL::CANMODIFRECORD => true, + \ACL::CANDELETERECORD => true, + \ACL::CHGSTATUS => true, + \ACL::IMGTOOLS => true, + \ACL::COLL_MANAGE => true, + \ACL::COLL_MODIFY_STRUCT => true, + \ACL::BAS_MODIFY_STRUCT => true + ] + ); } /** diff --git a/lib/Alchemy/Phrasea/Model/Manipulator/RegistrationManipulator.php b/lib/Alchemy/Phrasea/Model/Manipulator/RegistrationManipulator.php index ad85eef361..34ceb18874 100644 --- a/lib/Alchemy/Phrasea/Model/Manipulator/RegistrationManipulator.php +++ b/lib/Alchemy/Phrasea/Model/Manipulator/RegistrationManipulator.php @@ -81,13 +81,16 @@ class RegistrationManipulator implements ManipulatorInterface $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->aclProvider->get($user)->update_rights_to_base( + $collection->get_base_id(), + [ + \ACL::CANPUTINALBUM => true, + \ACL::CANDWNLDHD => (bool)$grantHd, + \ACL::NOWATERMARK => (bool)$grantWatermark, + \ACL::CANDWNLDPREVIEW => true, + \ACL::ACTIF => true + ] + ); $this->em->remove($registration); $this->em->flush(); } diff --git a/lib/Alchemy/Phrasea/Model/NativeQueryProvider.php b/lib/Alchemy/Phrasea/Model/NativeQueryProvider.php index 83adb29da3..4226cc0395 100644 --- a/lib/Alchemy/Phrasea/Model/NativeQueryProvider.php +++ b/lib/Alchemy/Phrasea/Model/NativeQueryProvider.php @@ -32,16 +32,13 @@ class NativeQueryProvider $selectClause = $rsm->generateSelectClause(); - return $this->em->createNativeQuery(" - SELECT d.date_modif AS date_demand, d.base_id AS base_demand, " . $selectClause . " - FROM (demand d INNER JOIN Users u ON d.usr_id=u.id - AND d.en_cours=1 - AND u.deleted=0 - ) - WHERE (base_id='" . implode("' OR base_id='", $basList) . "') - ORDER BY d.usr_id DESC, d.base_id ASC - ", $rsm) - ->getResult(); + return $this->em->createNativeQuery( + "SELECT d.date_modif AS date_demand, d.base_id AS base_demand, " . $selectClause . "\n" + . " FROM (demand d INNER JOIN Users u ON d.usr_id=u.id AND d.en_cours=1 AND u.deleted=0)\n" + . " WHERE (base_id='" . implode("' OR base_id='", $basList) . "')\n" + . " ORDER BY d.usr_id DESC, d.base_id ASC", + $rsm + )->getResult(); } public function getModelForUser(User $user, array $basList) @@ -51,14 +48,14 @@ class NativeQueryProvider $selectClause = $rsm->generateSelectClause(); - $query = $this->em->createNativeQuery(" - SELECT " . $selectClause . " - FROM Users u - INNER JOIN basusr b ON (b.usr_id=u.id) - WHERE u.model_of = :user_id - AND b.base_id IN (" . implode(', ', $basList) . ") - AND u.deleted='0' - GROUP BY u.id", $rsm); + $query = $this->em->createNativeQuery( + "SELECT " . $selectClause . " FROM Users u INNER JOIN basusr b ON (b.usr_id=u.id)\n" + . " WHERE u.model_of = :user_id\n" + . " AND b.base_id IN (" . implode(', ', $basList) . ")\n" + . " AND u.deleted='0'\n" + . " GROUP BY u.id", + $rsm + ); $query->setParameter(':user_id', $user->getId()); @@ -72,14 +69,15 @@ class NativeQueryProvider $rsm->addScalarResult('base_id', 'base_id'); $selectClause = $rsm->generateSelectClause(); - $query = $this->em->createNativeQuery(' - SELECT b.base_id, '.$selectClause.' FROM Users u, basusr b - WHERE u.id = b.usr_id - AND b.base_id IN (' . implode(', ', $basList) . ') - AND u.model_of IS NULL - AND b.actif="1" - AND b.canadmin="1" - AND u.deleted="0"', $rsm + $query = $this->em->createNativeQuery( + "SELECT b.base_id, ".$selectClause." FROM Users u, basusr b\n" + . " WHERE u.id = b.usr_id\n" + . " AND b.base_id IN (" . implode(', ', $basList) . ")\n" + . " AND u.model_of IS NULL\n" + . " AND b.actif=1\n" + . " AND b.canadmin=1\n" + . " AND u.deleted=0", + $rsm ); return $query->getResult(); diff --git a/lib/Alchemy/Phrasea/Model/RecordInterface.php b/lib/Alchemy/Phrasea/Model/RecordInterface.php index fb2e47fe0b..d839a38dac 100644 --- a/lib/Alchemy/Phrasea/Model/RecordInterface.php +++ b/lib/Alchemy/Phrasea/Model/RecordInterface.php @@ -48,6 +48,27 @@ interface RecordInterface extends RecordReferenceInterface /** @return array */ public function getExif(); + /** + * The width of the 'document' subdef + * + * @return integer|null + */ + public function getWidth(); + + /** + * The height of the 'document' subdef + * + * @return integer|null + */ + public function getHeight(); + + /** + * The size (filesize) of the 'document' subdef + * + * @return integer|null + */ + public function getSize(); + /** * Get Caption with requested fields if exists. * @param array $fields Returns only public fields when null diff --git a/lib/Alchemy/Phrasea/Order/Controller/ApiOrderController.php b/lib/Alchemy/Phrasea/Order/Controller/ApiOrderController.php index 5c81b9fb0e..6b8d6f64bc 100644 --- a/lib/Alchemy/Phrasea/Order/Controller/ApiOrderController.php +++ b/lib/Alchemy/Phrasea/Order/Controller/ApiOrderController.php @@ -22,6 +22,7 @@ use Alchemy\Phrasea\Http\DeliverDataInterface; use Alchemy\Phrasea\Model\Entities\Basket; use Alchemy\Phrasea\Model\Entities\BasketElement; use Alchemy\Phrasea\Model\Entities\Order; +use Alchemy\Phrasea\Model\Entities\Token; use Alchemy\Phrasea\Order\OrderElementTransformer; use Alchemy\Phrasea\Order\OrderFiller; use Alchemy\Phrasea\Order\OrderTransformer; @@ -88,7 +89,7 @@ class ApiOrderController extends BaseOrderController ]); }; - $builder = $this->app['repo.orders']->createQueryBuilder('o'); + $builder = $this->getOrderRepository()->createQueryBuilder('o'); $builder ->where($builder->expr()->eq('o.user', $this->getAuthenticatedUser()->getId())) ; @@ -138,11 +139,10 @@ class ApiOrderController extends BaseOrderController } /** - * @param Request $request * @param int $orderId * @return Response */ - public function getArchiveAction(Request $request, $orderId) + public function getArchiveAction($orderId) { $order = $this->findOr404($orderId); @@ -160,12 +160,11 @@ class ApiOrderController extends BaseOrderController $exportName = sprintf('%s/%s.zip', $this->app['tmp.download.path'], $export->getExportName()); $user = $this->getAuthenticatedUser(); - $subdefs = $this->findDataboxSubdefNames(); $exportData = $export->prepare_export($user, $this->getFilesystem(), $subdefs, true, true); - $exportData['export_name'] = $exportName; + /** @var Token $token */ $token = $this->app['manipulator.token']->createDownloadToken($user, serialize($exportData)); $lst = []; @@ -180,7 +179,7 @@ class ApiOrderController extends BaseOrderController set_time_limit(0); ignore_user_abort(true); - $file = \set_export::build_zip($this->app, $token, $exportData, $exportName); + $file = \set_export::build_zip($this->app, $token, $exportData, $token->getValue() . '.zip'); return $this->deliverFile($file, $exportName, DeliverDataInterface::DISPOSITION_INLINE, 'application/zip'); } @@ -188,7 +187,6 @@ class ApiOrderController extends BaseOrderController public function acceptElementsAction(Request $request, $orderId) { $elementIds = $this->fetchElementIdsFromRequest($request); - $elements = $this->doAcceptElements($orderId, $elementIds, $this->getAuthenticatedUser()); $resource = new Collection($elements, function (BasketElement $element) { @@ -242,7 +240,7 @@ class ApiOrderController extends BaseOrderController $filtered = []; foreach ($records as $index => $record) { - if (!$record->isStory() && $acl->has_right_on_base($record->getBaseId(), 'cancmd')) { + if (!$record->isStory() && $acl->has_right_on_base($record->getBaseId(), \ACL::CANCMD)) { $filtered[$index] = $record; } } diff --git a/lib/Alchemy/Phrasea/Order/Controller/BaseOrderController.php b/lib/Alchemy/Phrasea/Order/Controller/BaseOrderController.php index f297006ab9..5b2e90d4cb 100644 --- a/lib/Alchemy/Phrasea/Order/Controller/BaseOrderController.php +++ b/lib/Alchemy/Phrasea/Order/Controller/BaseOrderController.php @@ -10,6 +10,7 @@ namespace Alchemy\Phrasea\Order\Controller; +use Alchemy\Phrasea\Application; use Alchemy\Phrasea\Application\Helper\DispatcherAware; use Alchemy\Phrasea\Application\Helper\EntityManagerAware; use Alchemy\Phrasea\Controller\Controller; @@ -22,10 +23,10 @@ use Alchemy\Phrasea\Model\Entities\OrderElement; use Alchemy\Phrasea\Model\Entities\User; use Alchemy\Phrasea\Model\Repositories\OrderElementRepository; use Alchemy\Phrasea\Model\Repositories\OrderRepository; +use Alchemy\Phrasea\Order\OrderBasketProvider; use Alchemy\Phrasea\Order\OrderDelivery; use Alchemy\Phrasea\Order\OrderValidator; use Alchemy\Phrasea\Order\PartialOrder; -use Alchemy\Phrasea\Record\RecordReference; use Alchemy\Phrasea\Record\RecordReferenceCollection; use Assert\Assertion; use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException; @@ -38,12 +39,46 @@ class BaseOrderController extends Controller use DispatcherAware; use EntityManagerAware; + /** + * @var OrderRepository + */ + private $orderRepository; + + /** + * @var OrderElementRepository + */ + private $orderElementRepository; + + /** + * @var OrderBasketProvider + */ + private $orderBasketProvider; + + /** + * @param Application $app + * @param OrderRepository $orderRepository + * @param OrderElementRepository $orderElementRepository + * @param OrderBasketProvider $orderBasketProvider + */ + public function __construct( + Application $app, + OrderRepository $orderRepository, + OrderElementRepository $orderElementRepository, + OrderBasketProvider $orderBasketProvider + ) { + parent::__construct($app); + + $this->orderRepository = $orderRepository; + $this->orderElementRepository = $orderElementRepository; + $this->orderBasketProvider = $orderBasketProvider; + } + /** * @return OrderRepository */ protected function getOrderRepository() { - return $this->app['repo.orders']; + return $this->orderRepository; } /** @@ -51,7 +86,7 @@ class BaseOrderController extends Controller */ protected function getOrderElementRepository() { - return $this->app['repo.order-elements']; + return $this->orderElementRepository; } /** @@ -116,7 +151,7 @@ class BaseOrderController extends Controller $elements = $this->findRequestedElements($order_id, $elementIds, $acceptor); $order = $this->findOr404($order_id); - $basket = $this->app['provider.order_basket']->provideBasketForOrderAndUser($order, $acceptor); + $basket = $this->orderBasketProvider->provideBasketForOrderAndUser($order, $acceptor); $partialOrder = new PartialOrder($order, $elements); diff --git a/lib/Alchemy/Phrasea/Order/Controller/ProdOrderController.php b/lib/Alchemy/Phrasea/Order/Controller/ProdOrderController.php index 50830d3e07..d4372c18b8 100644 --- a/lib/Alchemy/Phrasea/Order/Controller/ProdOrderController.php +++ b/lib/Alchemy/Phrasea/Order/Controller/ProdOrderController.php @@ -37,7 +37,7 @@ class ProdOrderController extends BaseOrderController */ public function createOrder(Request $request) { - $records = RecordsRequest::fromRequest($this->app, $request, true, ['cancmd']); + $records = RecordsRequest::fromRequest($this->app, $request, true, [\ACL::CANCMD]); try { if ($records->isEmpty()) { @@ -109,7 +109,7 @@ class ProdOrderController extends BaseOrderController $sort = $request->query->get('sort'); - $baseIds = array_keys($this->getAclForUser()->get_granted_base(['order_master'])); + $baseIds = array_keys($this->getAclForUser()->get_granted_base([\ACL::ORDER_MASTER])); $ordersList = $this->getOrderRepository()->listOrders($baseIds, $offsetStart, $perPage, $sort); $total = $this->getOrderRepository()->countTotalOrders($baseIds); diff --git a/lib/Alchemy/Phrasea/Order/OrderValidator.php b/lib/Alchemy/Phrasea/Order/OrderValidator.php index 55339c2697..551958dc62 100644 --- a/lib/Alchemy/Phrasea/Order/OrderValidator.php +++ b/lib/Alchemy/Phrasea/Order/OrderValidator.php @@ -114,7 +114,7 @@ class OrderValidator $element->getRecordId() ); - $acl->grant_hd_on($recordReference, $user, 'order'); + $acl->grant_hd_on($recordReference, $user, \ACL::GRANT_ACTION_ORDER); } } diff --git a/lib/Alchemy/Phrasea/Out/Module/PDF.php b/lib/Alchemy/Phrasea/Out/Module/PDF.php index ab62ce1aa4..6b59262dbc 100644 --- a/lib/Alchemy/Phrasea/Out/Module/PDF.php +++ b/lib/Alchemy/Phrasea/Out/Module/PDF.php @@ -166,7 +166,7 @@ class PDF $fimg = $subdef->getRealPath(); - if (!$this->app->getAclForUser($this->app->getAuthenticatedUser())->has_right_on_base($rec->getBaseId(), "nowatermark") + if (!$this->app->getAclForUser($this->app->getAuthenticatedUser())->has_right_on_base($rec->getBaseId(), \ACL::NOWATERMARK) && $subdef->get_type() == \media_subdef::TYPE_IMAGE) { $fimg = \recordutils_image::watermark($this->app, $subdef); } @@ -438,7 +438,7 @@ class PDF $f = $subdef->getRealPath(); - if (!$this->app->getAclForUser($this->app->getAuthenticatedUser())->has_right_on_base($rec->getBaseId(), "nowatermark") + if (!$this->app->getAclForUser($this->app->getAuthenticatedUser())->has_right_on_base($rec->getBaseId(), \ACL::NOWATERMARK) && $subdef->get_type() == \media_subdef::TYPE_IMAGE) $f = \recordutils_image::watermark($this->app, $subdef); diff --git a/lib/Alchemy/Phrasea/Search/SubdefTransformer.php b/lib/Alchemy/Phrasea/Search/SubdefTransformer.php index ecd43ff032..a2d23cb34f 100644 --- a/lib/Alchemy/Phrasea/Search/SubdefTransformer.php +++ b/lib/Alchemy/Phrasea/Search/SubdefTransformer.php @@ -53,7 +53,7 @@ class SubdefTransformer extends TransformerAbstract return null; } if ($media->get_name() === 'document' - && !$acl->has_right_on_base($record->getBaseId(), 'candwnldhd') + && !$acl->has_right_on_base($record->getBaseId(), \ACL::CANDWNLDHD) && !$acl->has_hd_grant($record) ) { return null; diff --git a/lib/Alchemy/Phrasea/SearchEngine/Elastic/ElasticSearchEngine.php b/lib/Alchemy/Phrasea/SearchEngine/Elastic/ElasticSearchEngine.php index a90e433a1f..8445c86fb5 100644 --- a/lib/Alchemy/Phrasea/SearchEngine/Elastic/ElasticSearchEngine.php +++ b/lib/Alchemy/Phrasea/SearchEngine/Elastic/ElasticSearchEngine.php @@ -460,7 +460,7 @@ class ElasticSearchEngine implements SearchEngineInterface $acl = $this->app->getAclForUser($this->app->getAuthenticatedUser()); - $grantedCollections = array_keys($acl->get_granted_base(['actif'])); + $grantedCollections = array_keys($acl->get_granted_base([\ACL::ACTIF])); if (count($grantedCollections) === 0) { return ['bool' => ['must_not' => ['match_all' => new \stdClass()]]]; @@ -540,10 +540,16 @@ class ElasticSearchEngine implements SearchEngineInterface $sort['_score'] = $options->getSortOrder(); } elseif ($options->getSortBy() === SearchEngineOptions::SORT_CREATED_ON) { $sort['created_on'] = $options->getSortOrder(); + } elseif ($options->getSortBy() === 'recordid') { + $sort['record_id'] = $options->getSortOrder(); } else { $sort[sprintf('caption.%s', $options->getSortBy())] = $options->getSortOrder(); } + if (! array_key_exists('record_id', $sort)) { + $sort['record_id'] = $options->getSortOrder(); + } + return $sort; } diff --git a/lib/Alchemy/Phrasea/SearchEngine/Elastic/ElasticsearchRecordHydrator.php b/lib/Alchemy/Phrasea/SearchEngine/Elastic/ElasticsearchRecordHydrator.php index 5d5d57631e..3c6003b6fe 100644 --- a/lib/Alchemy/Phrasea/SearchEngine/Elastic/ElasticsearchRecordHydrator.php +++ b/lib/Alchemy/Phrasea/SearchEngine/Elastic/ElasticsearchRecordHydrator.php @@ -51,6 +51,9 @@ class ElasticsearchRecordHydrator $record->setOriginalName(igorw\get_in($data, ['original_name'], '')); $record->setRecordId(igorw\get_in($data, ['record_id'], 0)); $record->setSha256(igorw\get_in($data, ['sha256'], '')); + $record->setWidth(igorw\get_in($data, ['width'], 0)); + $record->setHeight(igorw\get_in($data, ['height'], 0)); + $record->setSize(igorw\get_in($data, ['size'], 0)); $record->setType(igorw\get_in($data, ['type'], 'unknown')); $updatedOn = igorw\get_in($data, ['updated_on']); $record->setUpdated($updatedOn ? new \DateTime($updatedOn) : $updatedOn); diff --git a/lib/Alchemy/Phrasea/SearchEngine/Elastic/Indexer.php b/lib/Alchemy/Phrasea/SearchEngine/Elastic/Indexer.php index 2b28ca5d82..b4dc6ec4a4 100644 --- a/lib/Alchemy/Phrasea/SearchEngine/Elastic/Indexer.php +++ b/lib/Alchemy/Phrasea/SearchEngine/Elastic/Indexer.php @@ -144,6 +144,7 @@ class Indexer } if ($what & self::RECORDS) { + $databox->clearCandidates(); $this->recordIndexer->populateIndex($bulk, $databox); // Final flush diff --git a/lib/Alchemy/Phrasea/SearchEngine/Elastic/Indexer/Record/Fetcher.php b/lib/Alchemy/Phrasea/SearchEngine/Elastic/Indexer/Record/Fetcher.php index 187809c573..ab90cb4a73 100644 --- a/lib/Alchemy/Phrasea/SearchEngine/Elastic/Indexer/Record/Fetcher.php +++ b/lib/Alchemy/Phrasea/SearchEngine/Elastic/Indexer/Record/Fetcher.php @@ -132,7 +132,9 @@ class Fetcher . ", r.sha256" // -- TODO rename in "hash" . ", r.originalname AS original_name" . ", r.mime, r.type, r.parent_record_id, r.credate AS created_on, r.moddate AS updated_on" - . " FROM record r INNER JOIN coll c ON (c.coll_id = r.coll_id)" + . ", subdef.width, subdef.height, subdef.size" + . " FROM (record r INNER JOIN coll c ON (c.coll_id = r.coll_id))" + . " LEFT JOIN subdef ON subdef.record_id=r.record_id AND subdef.name='document'" . " -- WHERE" . " ORDER BY r.record_id DESC" . " LIMIT :offset, :limit"; diff --git a/lib/Alchemy/Phrasea/SearchEngine/Elastic/Indexer/Record/Hydrator/CoreHydrator.php b/lib/Alchemy/Phrasea/SearchEngine/Elastic/Indexer/Record/Hydrator/CoreHydrator.php index 135cf854e8..7dd92b567e 100644 --- a/lib/Alchemy/Phrasea/SearchEngine/Elastic/Indexer/Record/Hydrator/CoreHydrator.php +++ b/lib/Alchemy/Phrasea/SearchEngine/Elastic/Indexer/Record/Hydrator/CoreHydrator.php @@ -45,6 +45,9 @@ class CoreHydrator implements HydratorInterface $record['base_id'] = $this->helper->getUniqueCollectionId($this->databox_id, $record['collection_id']); $record['databox_id'] = $this->databox_id; $record['databox_name'] = $this->databox_name; + $record['width'] = (int) $record['width']; + $record['height'] = (int) $record['height']; + $record['size'] = (int) $record['size']; $record['record_type'] = ((int) $record['parent_record_id'] === 1) ? SearchEngineInterface::GEM_TYPE_STORY diff --git a/lib/Alchemy/Phrasea/SearchEngine/Elastic/Indexer/RecordIndex.php b/lib/Alchemy/Phrasea/SearchEngine/Elastic/Indexer/RecordIndex.php index 321b19f951..8f3ca67283 100644 --- a/lib/Alchemy/Phrasea/SearchEngine/Elastic/Indexer/RecordIndex.php +++ b/lib/Alchemy/Phrasea/SearchEngine/Elastic/Indexer/RecordIndex.php @@ -47,8 +47,8 @@ class RecordIndex implements MappingProvider $mapping = new MappingBuilder(); // Compound primary key - $mapping->addField('record_id', FieldMapping::TYPE_INTEGER); - $mapping->addField('databox_id', FieldMapping::TYPE_INTEGER); + $mapping->addIntegerField('record_id'); + $mapping->addIntegerField('databox_id'); // Database name (still indexed for facets) $mapping->addStringField('databox_name')->disableAnalysis(); @@ -66,6 +66,10 @@ class RecordIndex implements MappingProvider $mapping->addStringField('type')->disableAnalysis(); $mapping->addStringField('record_type')->disableAnalysis(); + $mapping->addIntegerField('width')->disableIndexing(); + $mapping->addIntegerField('height')->disableIndexing(); + $mapping->addIntegerField('size')->disableIndexing(); + $mapping->addDateField('created_on', FieldMapping::DATE_FORMAT_MYSQL_OR_CAPTION); $mapping->addDateField('updated_on', FieldMapping::DATE_FORMAT_MYSQL_OR_CAPTION); @@ -87,9 +91,7 @@ class RecordIndex implements MappingProvider private function buildCaptionMapping(MappingBuilder $parent, $name, array $fields) { $fieldConverter = new Mapping\FieldToFieldMappingConverter(); - $captionMapping = new Mapping\ComplexFieldMapping($name, FieldMapping::TYPE_OBJECT); - - $captionMapping->useAsPropertyContainer(); + $captionMapping = new Mapping\ComplexPropertiesMapping($name); foreach ($fields as $field) { $captionMapping->addChild($fieldConverter->convertField($field, $this->locales)); @@ -109,7 +111,7 @@ class RecordIndex implements MappingProvider private function buildThesaurusPathMapping($name) { - $thesaurusMapping = new Mapping\ComplexFieldMapping($name, FieldMapping::TYPE_OBJECT); + $thesaurusMapping = new Mapping\ComplexPropertiesMapping($name); foreach (array_keys($this->structure->getThesaurusEnabledFields()) as $name) { $child = new Mapping\StringFieldMapping($name); @@ -118,7 +120,7 @@ class RecordIndex implements MappingProvider $child->setAnalyzer('keyword', 'searching'); $child->addChild((new Mapping\StringFieldMapping('raw'))->enableRawIndexing()); - $thesaurusMapping->addChild($thesaurusMapping); + $thesaurusMapping->addChild($child); } return $thesaurusMapping; @@ -127,9 +129,7 @@ class RecordIndex implements MappingProvider private function buildMetadataTagMapping($name) { $tagConverter = new Mapping\MetadataTagToFieldMappingConverter(); - $metadataMapping = new Mapping\ComplexFieldMapping($name, FieldMapping::TYPE_OBJECT); - - $metadataMapping->useAsPropertyContainer(); + $metadataMapping = new Mapping\ComplexPropertiesMapping($name); foreach ($this->structure->getMetadataTags() as $tag) { $metadataMapping->addChild($tagConverter->convertTag($tag)); @@ -141,9 +141,7 @@ class RecordIndex implements MappingProvider private function buildFlagMapping($name) { $index = 0; - $flagMapping = new Mapping\ComplexFieldMapping($name, FieldMapping::TYPE_OBJECT); - - $flagMapping->useAsPropertyContainer(); + $flagMapping = new Mapping\ComplexPropertiesMapping($name); foreach ($this->structure->getAllFlags() as $childName => $_) { if (trim($childName) == '') { diff --git a/lib/Alchemy/Phrasea/SearchEngine/Elastic/Mapping/ComplexFieldMapping.php b/lib/Alchemy/Phrasea/SearchEngine/Elastic/Mapping/ComplexFieldMapping.php index 1159144650..97d757e414 100644 --- a/lib/Alchemy/Phrasea/SearchEngine/Elastic/Mapping/ComplexFieldMapping.php +++ b/lib/Alchemy/Phrasea/SearchEngine/Elastic/Mapping/ComplexFieldMapping.php @@ -13,64 +13,12 @@ namespace Alchemy\Phrasea\SearchEngine\Elastic\Mapping; use Alchemy\Phrasea\SearchEngine\Elastic\FieldMapping; -class ComplexFieldMapping extends FieldMapping +class ComplexFieldMapping extends ComplexMapping { - /** - * @var FieldMapping[] - */ - private $children = []; - private $childKey = 'fields'; - - public function useAsPropertyContainer() + public function __construct($name, $type = null) { - $this->childKey = 'properties'; - } - - public function useAsFieldContainer() - { - $this->childKey = 'fields'; - } - - /** - * @param FieldMapping $child - * @return FieldMapping - */ - public function addChild(FieldMapping $child) - { - if (isset($this->children[$child->getName()])) { - throw new \LogicException(sprintf('There is already a "%s" multi field.', $child->getName())); - } - - if ($child->getType() !== $this->getType() && $this->getType() !== self::TYPE_OBJECT) { - throw new \LogicException('Child field type must match parent type.'); - } - - return $this->children[$child->getName()] = $child; - } - - /** - * @return RawFieldMapping - */ - public function addRawChild() - { - return $this->addChild(new RawFieldMapping($this->getType())); - } - - /** - * @return bool - */ - public function hasChildren() - { - return ! empty($this->children); - } - - /** - * @return FieldMapping[] - */ - public function getChildren() - { - return $this->children; + parent::__construct($name, $type ?: FieldMapping::TYPE_OBJECT); } /** @@ -78,16 +26,12 @@ class ComplexFieldMapping extends FieldMapping */ protected function getProperties() { - if (! $this->hasChildren()) { - return []; + $properties = parent::getProperties(); + + if (! empty($properties)) { + return ['fields' => parent::getProperties()]; } - $properties = [ ]; - - foreach ($this->children as $name => $child) { - $properties[$name] = $child->toArray(); - } - - return [ $this->childKey => $properties ]; + return $properties; } } diff --git a/lib/Alchemy/Phrasea/SearchEngine/Elastic/Mapping/ComplexMapping.php b/lib/Alchemy/Phrasea/SearchEngine/Elastic/Mapping/ComplexMapping.php new file mode 100644 index 0000000000..0e154f832f --- /dev/null +++ b/lib/Alchemy/Phrasea/SearchEngine/Elastic/Mapping/ComplexMapping.php @@ -0,0 +1,81 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Alchemy\Phrasea\SearchEngine\Elastic\Mapping; + +use Alchemy\Phrasea\SearchEngine\Elastic\FieldMapping; + +class ComplexMapping extends FieldMapping +{ + /** + * @var FieldMapping[] + */ + private $children = []; + + /** + * @param FieldMapping $child + * @return FieldMapping + */ + public function addChild(FieldMapping $child) + { + if (isset($this->children[$child->getName()])) { + throw new \LogicException(sprintf('There is already a "%s" multi field.', $child->getName())); + } + + if ($child->getType() !== $this->getType() && $this->getType() !== self::TYPE_OBJECT) { + throw new \LogicException('Child field type must match parent type.'); + } + + return $this->children[$child->getName()] = $child; + } + + /** + * @return RawFieldMapping + */ + public function addRawChild() + { + return $this->addChild(new RawFieldMapping($this->getType())); + } + + /** + * @return bool + */ + public function hasChildren() + { + return ! empty($this->children); + } + + /** + * @return FieldMapping[] + */ + public function getChildren() + { + return $this->children; + } + + /** + * @return array + */ + protected function getProperties() + { + if (! $this->hasChildren()) { + return []; + } + + $properties = [ ]; + + foreach ($this->children as $name => $child) { + $properties[$name] = $child->toArray(); + } + + return $properties; + } +} diff --git a/lib/Alchemy/Phrasea/SearchEngine/Elastic/Mapping/ComplexPropertiesMapping.php b/lib/Alchemy/Phrasea/SearchEngine/Elastic/Mapping/ComplexPropertiesMapping.php new file mode 100644 index 0000000000..af1487da15 --- /dev/null +++ b/lib/Alchemy/Phrasea/SearchEngine/Elastic/Mapping/ComplexPropertiesMapping.php @@ -0,0 +1,31 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Alchemy\Phrasea\SearchEngine\Elastic\Mapping; + +use Alchemy\Phrasea\SearchEngine\Elastic\FieldMapping; + +class ComplexPropertiesMapping extends ComplexMapping +{ + + public function __construct($name) + { + parent::__construct($name, FieldMapping::TYPE_OBJECT); + } + + /** + * @return array + */ + public function getProperties() + { + return [ 'properties' => parent::getProperties() ]; + } +} diff --git a/lib/Alchemy/Phrasea/SearchEngine/SearchEngineOptions.php b/lib/Alchemy/Phrasea/SearchEngine/SearchEngineOptions.php index eae2a6b225..530b668363 100644 --- a/lib/Alchemy/Phrasea/SearchEngine/SearchEngineOptions.php +++ b/lib/Alchemy/Phrasea/SearchEngine/SearchEngineOptions.php @@ -639,9 +639,9 @@ class SearchEngineOptions $options->onCollections($bas); - if ($isAuthenticated && $acl->has_right('modifyrecord')) { + if ($isAuthenticated && $acl->has_right(\ACL::CANMODIFRECORD)) { $bf = array_filter($bas, function (\collection $collection) use ($acl) { - return $acl->has_right_on_base($collection->get_base_id(), 'canmodifrecord'); + return $acl->has_right_on_base($collection->get_base_id(), \ACL::CANMODIFRECORD); }); $options->allowBusinessFieldsOn($bf); diff --git a/lib/Alchemy/Phrasea/Security/Firewall.php b/lib/Alchemy/Phrasea/Security/Firewall.php index 836edd1ed8..2343a50b3e 100644 --- a/lib/Alchemy/Phrasea/Security/Firewall.php +++ b/lib/Alchemy/Phrasea/Security/Firewall.php @@ -146,7 +146,7 @@ class Firewall public function requireOrdersAdmin() { - if (empty($this->app->getAclForUser($this->app->getAuthenticatedUser())->get_granted_base(['order_master']))) { + if (empty($this->app->getAclForUser($this->app->getAuthenticatedUser())->get_granted_base([\ACL::ORDER_MASTER]))) { $this->app->abort(403, 'You are not an order admin'); } diff --git a/lib/Alchemy/Phrasea/Setup/DoctrineMigrations/OrderMigration.php b/lib/Alchemy/Phrasea/Setup/DoctrineMigrations/OrderMigration.php index 6d4b2e57e8..7ca214f03e 100644 --- a/lib/Alchemy/Phrasea/Setup/DoctrineMigrations/OrderMigration.php +++ b/lib/Alchemy/Phrasea/Setup/DoctrineMigrations/OrderMigration.php @@ -11,6 +11,7 @@ namespace Alchemy\Phrasea\Setup\DoctrineMigrations; +use Alchemy\Phrasea\Model\Entities\Order; use Doctrine\DBAL\Schema\Schema; class OrderMigration extends AbstractMigration @@ -23,6 +24,8 @@ class OrderMigration extends AbstractMigration public function doUpSql(Schema $schema) { $this->addSql("CREATE TABLE Orders (id INT AUTO_INCREMENT NOT NULL, user_id INT NOT NULL, basket_id INT DEFAULT NULL, order_usage VARCHAR(2048) NOT NULL, todo INT DEFAULT NULL, deadline DATETIME NOT NULL, created_on DATETIME NOT NULL, INDEX IDX_E283F8D8A76ED395 (user_id), UNIQUE INDEX UNIQ_E283F8D81BE1FB52 (basket_id), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB"); + $this->addSql(sprintf("ALTER TABLE Orders ADD COLUMN notification_method VARCHAR(32) NOT NULL DEFAULT '%s'", Order::NOTIFY_MAIL)); + $this->addSql("ALTER TABLE Orders ALTER COLUMN notification_method DROP DEFAULT"); $this->addSql("CREATE TABLE OrderElements (id INT AUTO_INCREMENT NOT NULL, order_master INT DEFAULT NULL, order_id INT DEFAULT NULL, base_id INT NOT NULL, record_id INT NOT NULL, deny TINYINT(1) DEFAULT NULL, INDEX IDX_8C7066C8EE86B303 (order_master), INDEX IDX_8C7066C88D9F6D38 (order_id), UNIQUE INDEX unique_ordercle (base_id, record_id, order_id), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB"); $this->addSql("ALTER TABLE Orders ADD CONSTRAINT FK_E283F8D8A76ED395 FOREIGN KEY (user_id) REFERENCES Users (id)"); $this->addSql("ALTER TABLE Orders ADD CONSTRAINT FK_E283F8D81BE1FB52 FOREIGN KEY (basket_id) REFERENCES Baskets (id)"); diff --git a/lib/Alchemy/Phrasea/Setup/DoctrineMigrations/Version20160511160640.php b/lib/Alchemy/Phrasea/Setup/DoctrineMigrations/Version20160511160640.php index 51c9ea55b0..3c9f7a16f0 100644 --- a/lib/Alchemy/Phrasea/Setup/DoctrineMigrations/Version20160511160640.php +++ b/lib/Alchemy/Phrasea/Setup/DoctrineMigrations/Version20160511160640.php @@ -18,9 +18,7 @@ class Version20160511160640 extends BaseMigration { // this up() migration is auto-generated, please modify it to your needs $this->abortIf($this->connection->getDatabasePlatform()->getName() != 'mysql', 'Migration can only be executed safely on \'mysql\'.'); - - $this->addSql(sprintf("ALTER TABLE Orders ADD COLUMN notification_method VARCHAR(32) NOT NULL DEFAULT '%s'", Order::NOTIFY_MAIL)); - $this->addSql("ALTER TABLE Orders ALTER COLUMN notification_method DROP DEFAULT"); + // no-op } /** @@ -30,7 +28,6 @@ class Version20160511160640 extends BaseMigration { // this down() migration is auto-generated, please modify it to your needs $this->abortIf($this->connection->getDatabasePlatform()->getName() != 'mysql', 'Migration can only be executed safely on \'mysql\'.'); - - $this->addSql("ALTER TABLE Orders DROP COLUMN notification_method"); + // no-op } } diff --git a/lib/Alchemy/Phrasea/Setup/Installer.php b/lib/Alchemy/Phrasea/Setup/Installer.php index 4c18e5eb5a..2868f79835 100644 --- a/lib/Alchemy/Phrasea/Setup/Installer.php +++ b/lib/Alchemy/Phrasea/Setup/Installer.php @@ -59,23 +59,42 @@ class Installer $this->app->getAclForUser($admin) ->give_access_to_sbas([$databox->get_sbas_id()]) ->update_rights_to_sbas( - $databox->get_sbas_id(), [ - 'bas_manage' => 1, 'bas_modify_struct' => 1, - 'bas_modif_th' => 1, 'bas_chupub' => 1 + $databox->get_sbas_id(), + [ + \ACL::BAS_MANAGE => true, + \ACL::BAS_MODIFY_STRUCT => true, + \ACL::BAS_MODIF_TH => true, + \ACL::BAS_CHUPUB => true ] ); $collection = \collection::create($this->app, $databox, $this->app['phraseanet.appbox'], 'test', $admin); - $this->app->getAclForUser($admin)->give_access_to_base([$collection->get_base_id()]); - $this->app->getAclForUser($admin)->update_rights_to_base($collection->get_base_id(), [ - 'canpush' => 1, 'cancmd' => 1 - , 'canputinalbum' => 1, 'candwnldhd' => 1, 'candwnldpreview' => 1, 'canadmin' => 1 - , 'actif' => 1, 'canreport' => 1, 'canaddrecord' => 1, 'canmodifrecord' => 1 - , 'candeleterecord' => 1, 'chgstatus' => 1, 'imgtools' => 1, 'manage' => 1 - , 'modify_struct' => 1, 'nowatermark' => 1 - ] - ); + $this->app->getAclForUser($admin) + ->give_access_to_base([$collection->get_base_id()]); + + $this->app->getAclForUser($admin) + ->update_rights_to_base( + $collection->get_base_id(), + [ + \ACL::CANPUSH => true, + \ACL::CANCMD => true, + \ACL::CANPUTINALBUM => true, + \ACL::CANDWNLDHD => true, + \ACL::CANDWNLDPREVIEW => true, + \ACL::CANADMIN => true, + \ACL::ACTIF => true, + \ACL::CANREPORT => true, + \ACL::CANADDRECORD => true, + \ACL::CANMODIFRECORD => true, + \ACL::CANDELETERECORD => true, + \ACL::CHGSTATUS => true, + \ACL::IMGTOOLS => true, + \ACL::COLL_MANAGE => true, + \ACL::COLL_MODIFY_STRUCT => true, + \ACL::NOWATERMARK => true + ] + ); foreach (['Subdefs', 'WriteMetadata'] as $jobName) { /** @var JobInterface $job */ diff --git a/lib/Alchemy/Phrasea/TaskManager/Editor/SubdefsEditor.php b/lib/Alchemy/Phrasea/TaskManager/Editor/SubdefsEditor.php index 0929975ed5..69d9aff8eb 100644 --- a/lib/Alchemy/Phrasea/TaskManager/Editor/SubdefsEditor.php +++ b/lib/Alchemy/Phrasea/TaskManager/Editor/SubdefsEditor.php @@ -53,6 +53,7 @@ class SubdefsEditor extends AbstractEditor 5 20 256 + 3600 EOF; } diff --git a/lib/Alchemy/Phrasea/TaskManager/TaskList.php b/lib/Alchemy/Phrasea/TaskManager/TaskList.php index 19c5f564a8..c108a10537 100644 --- a/lib/Alchemy/Phrasea/TaskManager/TaskList.php +++ b/lib/Alchemy/Phrasea/TaskManager/TaskList.php @@ -49,6 +49,17 @@ class TaskList implements TaskListInterface $arguments[] = $this->phpConf; } + $maxmegs = 128; // default (Mo) if not set in xml + $maxduration = 1800; // default (seconds) if not set in xml + if( ($sxSettings = @simplexml_load_string($task->getSettings())) ) { + if( ($v = (int)($sxSettings->maxmegs)) && $v > 0) { + $maxmegs = $v; + } + if( ($v = (int)($sxSettings->maxduration)) && $v > 0) { + $maxduration = $v; + } + } + $arguments[] = '-f'; $arguments[] = $this->root . '/bin/console'; $arguments[] = '--'; @@ -57,9 +68,9 @@ class TaskList implements TaskListInterface $arguments[] = $task->getId(); $arguments[] = '--listen-signal'; $arguments[] = '--max-duration'; - $arguments[] = '1800'; + $arguments[] = $maxduration; $arguments[] = '--max-memory'; - $arguments[] = 128 << 20; + $arguments[] = $maxmegs << 20; $builder = ProcessBuilder::create($arguments); $builder->setTimeout(0); diff --git a/lib/Alchemy/Phrasea/Twig/PhraseanetExtension.php b/lib/Alchemy/Phrasea/Twig/PhraseanetExtension.php index a11b9d6ee6..0fef3ee23e 100644 --- a/lib/Alchemy/Phrasea/Twig/PhraseanetExtension.php +++ b/lib/Alchemy/Phrasea/Twig/PhraseanetExtension.php @@ -133,7 +133,7 @@ class PhraseanetExtension extends \Twig_Extension $structure = $databox->getStatusStructure()->toArray(); - if (!$this->isGrantedOnCollection($record->getBaseId(), 'chgstatus')) { + if (!$this->isGrantedOnCollection($record->getBaseId(), [\ACL::CHGSTATUS])) { $structure = array_filter($structure, function($status) { return (bool) $status['printable']; }); @@ -175,16 +175,25 @@ class PhraseanetExtension extends \Twig_Extension return true; } - public function isGrantedOnCollection($baseId, $rights) + /** + * returns true if user is authenticated and has all the passed rights on the base + * todo : wtf $rights is an array since it's never called with more than 1 right in it ? + * + * @param $baseId + * @param array $rights + * @return bool + * @throws \Exception + */ + public function isGrantedOnCollection($baseId, Array $rights) { if (false === ($this->app->getAuthenticatedUser() instanceof User)) { return false; } - $rights = (array) $rights; + $acl = $this->app->getAclForUser($this->app->getAuthenticatedUser()); foreach ($rights as $right) { - if (false === $this->app->getAclForUser($this->app->getAuthenticatedUser())->has_right_on_base($baseId, $right)) { + if (! $acl->has_right_on_base($baseId, $right)) { return false; } @@ -196,6 +205,7 @@ class PhraseanetExtension extends \Twig_Extension public function getCollectionLogo($baseId) { if (false === $this->app['filesystem']->exists(sprintf('%s/config/minilogos/%s', $this->app['root.path'], $baseId))) { + return ''; } diff --git a/lib/Alchemy/Phrasea/Vocabulary/ControlProvider/UserProvider.php b/lib/Alchemy/Phrasea/Vocabulary/ControlProvider/UserProvider.php index 2c9af43bd3..a8a7224b1d 100644 --- a/lib/Alchemy/Phrasea/Vocabulary/ControlProvider/UserProvider.php +++ b/lib/Alchemy/Phrasea/Vocabulary/ControlProvider/UserProvider.php @@ -56,7 +56,7 @@ class UserProvider implements ControlProviderInterface ->like(\User_Query::LIKE_LOGIN, $query) ->like_match(\User_Query::LIKE_MATCH_OR) ->include_phantoms(true) - ->on_bases_where_i_am($this->app->getAclForUser($for_user), ['canadmin']) + ->on_bases_where_i_am($this->app->getAclForUser($for_user), [\ACL::CANADMIN]) ->limit(0, 50) ->execute()->get_results(); diff --git a/lib/classes/ACL.php b/lib/classes/ACL.php index 5a851a7dc4..86817a3f5f 100644 --- a/lib/classes/ACL.php +++ b/lib/classes/ACL.php @@ -28,29 +28,65 @@ use Alchemy\Phrasea\Model\RecordInterface; use Alchemy\Phrasea\Model\RecordReferenceInterface; use Alchemy\Phrasea\Utilities\NullableDateTime; use Doctrine\DBAL\DBALException; +use Doctrine\DBAL\Statement; class ACL implements cache_cacheableInterface { + // those constants MUST match the related sql columns (so sql can be built from anonymous constants... ugly) + const BAS_MODIF_TH = 'bas_modif_th'; + const BAS_MODIFY_STRUCT = 'bas_modify_struct'; + const BAS_MANAGE = 'bas_manage'; + const BAS_CHUPUB = 'bas_chupub'; + + const ACCESS = 'access'; // not a real sql column + const ACTIF = 'actif'; + const CANADDRECORD = 'canaddrecord'; + const CANADMIN = 'canadmin'; + const CANCMD = 'cancmd'; + const CANDELETERECORD = 'candeleterecord'; + const CANDWNLDHD = 'candwnldhd'; + const CANDWNLDPREVIEW = 'candwnldpreview'; + const CANMODIFRECORD = 'canmodifrecord'; + const CANPUSH = 'canpush'; + const CANPUTINALBUM = 'canputinalbum'; + const CANREPORT = 'canreport'; + const CHGSTATUS = 'chgstatus'; + const IMGTOOLS = 'imgtools'; + const COLL_MANAGE = 'manage'; + const COLL_MODIFY_STRUCT = 'modify_struct'; + const NOWATERMARK = 'nowatermark'; + const ORDER_MASTER = 'order_master'; + const RESTRICT_DWNLD = 'restrict_dwnld'; + + const TASKMANAGER = 'taskmanager'; protected static $bas_rights = [ - 'actif', - 'canaddrecord', - 'canadmin', - 'cancmd', - 'candeleterecord', - 'candwnldhd', - 'candwnldpreview', - 'canmodifrecord', - 'canpush', - 'canputinalbum', - 'canreport', - 'chgstatus', - 'imgtools', - 'manage', - 'modify_struct', - 'nowatermark', - 'order_master', + self::ACTIF, + self::CANADDRECORD, + self::CANADMIN, + self::CANCMD, + self::CANDELETERECORD, + self::CANDWNLDHD, + self::CANDWNLDPREVIEW, + self::CANMODIFRECORD, + self::CANPUSH, + self::CANPUTINALBUM, + self::CANREPORT, + self::CHGSTATUS, + self::IMGTOOLS, + self::COLL_MANAGE, + self::COLL_MODIFY_STRUCT, + self::NOWATERMARK, + self::ORDER_MASTER, + self::RESTRICT_DWNLD + ]; + + protected static $sbas_rights = [ + self::BAS_CHUPUB, + self::BAS_MANAGE, + self::BAS_MODIF_TH, + self::BAS_MODIFY_STRUCT ]; /** @@ -89,26 +125,31 @@ class ACL implements cache_cacheableInterface protected $is_admin; protected $_global_rights = [ - 'addrecord' => false, - 'addtoalbum' => false, - 'bas_chupub' => false, - 'bas_manage' => false, - 'bas_modif_th' => false, - 'bas_modify_struct' => false, - 'candwnldhd' => true, - 'candwnldpreview' => true, - 'changestatus' => false, - 'coll_manage' => false, - 'coll_modify_struct' => false, - 'deleterecord' => false, - 'doctools' => false, - 'manageusers' => false, - 'modifyrecord' => false, - 'order' => false, - 'order_master' => false, - 'push' => false, - 'report' => false, - 'taskmanager' => false, + self::ACTIF => false, + self::CANADDRECORD => false, + self::CANPUTINALBUM => false, + self::CANDWNLDHD => true, + self::CANDWNLDPREVIEW => true, + self::CHGSTATUS => false, + self::COLL_MANAGE => false, + self::COLL_MODIFY_STRUCT => false, + self::CANDELETERECORD => false, + self::IMGTOOLS => false, + self::CANADMIN => false, + self::CANMODIFRECORD => false, + self::CANCMD => false, + self::ORDER_MASTER => false, + self::CANPUSH => false, + self::CANREPORT => false, + self::NOWATERMARK => false, + self::RESTRICT_DWNLD => false, + + self::BAS_CHUPUB => false, + self::BAS_MANAGE => false, + self::BAS_MODIF_TH => false, + self::BAS_MODIFY_STRUCT => false, + + self::TASKMANAGER => false, ]; /** @@ -116,14 +157,15 @@ class ACL implements cache_cacheableInterface */ protected $app; - const CACHE_IS_ADMIN = 'is_admin'; - const CACHE_RIGHTS_BAS = 'rights_bas'; - const CACHE_LIMITS_BAS = 'limits_bas'; - const CACHE_RIGHTS_SBAS = 'rights_sbas'; - const CACHE_RIGHTS_RECORDS = 'rights_records'; - const CACHE_GLOBAL_RIGHTS = 'global_rights'; - const GRANT_ACTION_PUSH = 'push'; + const CACHE_IS_ADMIN = 'is_admin'; + const CACHE_RIGHTS_BAS = 'rights_bas'; + const CACHE_LIMITS_BAS = 'limits_bas'; + const CACHE_RIGHTS_SBAS = 'rights_sbas'; + const CACHE_RIGHTS_RECORDS = 'rights_records'; + const CACHE_GLOBAL_RIGHTS = 'global_rights'; + const GRANT_ACTION_PUSH = 'push'; const GRANT_ACTION_VALIDATE = 'validate'; + const GRANT_ACTION_ORDER = 'order'; /** * Constructor @@ -179,17 +221,16 @@ class ACL implements cache_cacheableInterface public function grant_hd_on(RecordReferenceInterface $record, User $pusher, $action) { - $sql = 'REPLACE INTO records_rights - (id, usr_id, sbas_id, record_id, document, `case`, pusher_usr_id) - VALUES - (null, :usr_id, :sbas_id, :record_id, 1, :case, :pusher)'; + $sql = "REPLACE INTO records_rights\n" + . " (id, usr_id, sbas_id, record_id, document, `case`, pusher_usr_id)\n" + . " VALUES (null, :usr_id, :sbas_id, :record_id, 1, :case, :pusher)"; $params = [ - ':usr_id' => $this->user->getId() - , ':sbas_id' => $record->getDataboxId() - , ':record_id' => $record->getRecordId() - , ':case' => $action - , ':pusher' => $pusher->getId() + ':usr_id' => $this->user->getId(), + ':sbas_id' => $record->getDataboxId(), + ':record_id' => $record->getRecordId(), + ':case' => $action, + ':pusher' => $pusher->getId() ]; $stmt = $this->app->getApplicationBox()->get_connection()->prepare($sql); @@ -203,17 +244,17 @@ class ACL implements cache_cacheableInterface public function grant_preview_on(RecordReferenceInterface $record, User $pusher, $action) { - $sql = 'REPLACE INTO records_rights - (id, usr_id, sbas_id, record_id, preview, `case`, pusher_usr_id) - VALUES - (null, :usr_id, :sbas_id, :record_id, 1, :case, :pusher)'; + $sql = "REPLACE INTO records_rights\n" + . " (id, usr_id, sbas_id, record_id, preview, `case`, pusher_usr_id)\n" + . " VALUES\n" + . " (null, :usr_id, :sbas_id, :record_id, 1, :case, :pusher)"; $params = [ - ':usr_id' => $this->user->getId() - , ':sbas_id' => $record->getDataboxId() - , ':record_id' => $record->getRecordId() - , ':case' => $action - , ':pusher' => $pusher->getId() + ':usr_id' => $this->user->getId(), + ':sbas_id' => $record->getDataboxId(), + ':record_id' => $record->getRecordId(), + ':case' => $action, + ':pusher' => $pusher->getId() ]; $stmt = $this->app->getApplicationBox()->get_connection()->prepare($sql); @@ -279,11 +320,11 @@ class ACL implements cache_cacheableInterface if ($subdef_class == databox_subdef::CLASS_THUMBNAIL) { $granted = true; - } elseif ($subdef_class == databox_subdef::CLASS_PREVIEW && $this->has_right_on_base($record->getBaseId(), 'candwnldpreview')) { + } elseif ($subdef_class == databox_subdef::CLASS_PREVIEW && $this->has_right_on_base($record->getBaseId(), self::CANDWNLDPREVIEW)) { $granted = true; } elseif ($subdef_class == databox_subdef::CLASS_PREVIEW && $this->has_preview_grant($record)) { $granted = true; - } elseif ($subdef_class == databox_subdef::CLASS_DOCUMENT && $this->has_right_on_base($record->getBaseId(), 'candwnldhd')) { + } elseif ($subdef_class == databox_subdef::CLASS_DOCUMENT && $this->has_right_on_base($record->getBaseId(), self::CANDWNLDHD)) { $granted = true; } elseif ($subdef_class == databox_subdef::CLASS_DOCUMENT && $this->has_hd_grant($record)) { $granted = true; @@ -317,8 +358,6 @@ class ACL implements cache_cacheableInterface $sbas_ids = array_unique($sbas_ids); - $sbas_rights = ['bas_manage', 'bas_modify_struct', 'bas_modif_th', 'bas_chupub']; - $sbas_to_acces = []; $rights_to_give = []; @@ -332,9 +371,9 @@ class ACL implements cache_cacheableInterface $sbas_to_acces[] = $sbas_id; } - foreach ($sbas_rights as $right) { + foreach (self::$sbas_rights as $right) { if ($this->app->getAclForUser($template_user)->has_right_on_sbas($sbas_id, $right)) { - $rights_to_give[$sbas_id][$right] = '1'; + $rights_to_give[$sbas_id][$right] = true; } } } @@ -349,6 +388,8 @@ class ACL implements cache_cacheableInterface $bas_to_acces = $masks_to_give = $rights_to_give = []; + // todo ? wtf simplify this sb manipulation, now it is 32 bits + /** * map masks (and+xor) of template to masks to apply to user on base * (and_and, and_or, xor_and, xor_or) @@ -363,8 +404,9 @@ class ACL implements cache_cacheableInterface foreach ($this->app->getAclForUser($template_user)->get_granted_base() as $collection) { $base_id = $collection->get_base_id(); - if (!in_array($base_id, $base_ids)) + if (!in_array($base_id, $base_ids)) { continue; + } if (!$this->has_access_to_base($base_id)) { $bas_to_acces[] = $base_id; @@ -402,10 +444,10 @@ class ACL implements cache_cacheableInterface } $masks_to_give[$base_id] = [ - 'aa' => $m['aa'] - , 'ao' => $m['ao'] - , 'xa' => $m['xa'] - , 'xo' => $m['xo'] + 'aa' => $m['aa'], + 'ao' => $m['ao'], + 'xa' => $m['xa'], + 'xo' => $m['xo'] ]; } @@ -448,10 +490,10 @@ class ACL implements cache_cacheableInterface } /** - * - * @param int $base_id - * @param string $right - * @return boolean + * @param $base_id + * @param $right + * @return bool + * @throws Exception */ public function has_right_on_base($base_id, $right) { @@ -465,16 +507,16 @@ class ACL implements cache_cacheableInterface return false; } - if (!isset($this->_rights_bas[$base_id][$right])) + if (!isset($this->_rights_bas[$base_id][$right])) { throw new Exception('right ' . $right . ' does not exists'); + } return ($this->_rights_bas[$base_id][$right] === true); } /** - * - * @param $option - * @return + * @param string|null $option + * @return string */ public function get_cache_key($option = null) { @@ -482,9 +524,7 @@ class ACL implements cache_cacheableInterface } /** - * - * @param $option - * @return + * @param string|null $option */ public function delete_data_from_cache($option = null) { @@ -508,13 +548,12 @@ class ACL implements cache_cacheableInterface break; } - return $this->app->getApplicationBox()->delete_data_from_cache($this->get_cache_key($option)); + $this->app->getApplicationBox()->delete_data_from_cache($this->get_cache_key($option)); } /** - * - * @param $option - * @return + * @param string|null $option + * @return array */ public function get_data_from_cache($option = null) { @@ -522,11 +561,10 @@ class ACL implements cache_cacheableInterface } /** - * - * @param $value - * @param $option - * @param $duration - * @return + * @param $value + * @param string|null $option + * @param int $duration + * @return bool */ public function set_data_to_cache($value, $option = null, $duration = 0) { @@ -547,7 +585,7 @@ class ACL implements cache_cacheableInterface return false; } - return $this->_rights_bas[$base_id]['restrict_dwnld']; + return $this->_rights_bas[$base_id][self::RESTRICT_DWNLD]; } /** @@ -573,6 +611,8 @@ class ACL implements cache_cacheableInterface * @param int $base_id * @param int $n * @return ACL + * + * todo : wtf direct cache modification, where is sql ? */ public function remove_remaining($base_id, $n = 1) { @@ -582,11 +622,7 @@ class ACL implements cache_cacheableInterface return false; } - $this->_rights_bas[$base_id]['remain_dwnld'] = - $this->_rights_bas[$base_id]['remain_dwnld'] - (int) $n; - $v = $this->_rights_bas[$base_id]['remain_dwnld']; - $this->_rights_bas[$base_id]['remain_dwnld'] = - $this->_rights_bas[$base_id]['remain_dwnld'] < 0 ? 0 : $v; + $this->_rights_bas[$base_id]['remain_dwnld'] = max(0, $this->_rights_bas[$base_id]['remain_dwnld'] - (int) $n); return $this; } @@ -602,8 +638,9 @@ class ACL implements cache_cacheableInterface { $this->load_global_rights(); - if (!isset($this->_global_rights[$right])) + if (!isset($this->_global_rights[$right])) { throw new Exception('This right does not exists'); + } return $this->_global_rights[$right]; } @@ -624,8 +661,9 @@ class ACL implements cache_cacheableInterface return false; } - if (!isset($this->_rights_sbas[$sbas_id][$right])) + if (!isset($this->_rights_sbas[$sbas_id][$right])) { throw new Exception('This right does not exists'); + } if ($this->_rights_sbas[$sbas_id][$right] === true) { return true; @@ -677,7 +715,7 @@ class ACL implements cache_cacheableInterface $this->load_rights_bas(); return (isset($this->_rights_bas[$base_id]) && - $this->_rights_bas[$base_id]['actif'] === true); + $this->_rights_bas[$base_id][self::ACTIF] === true); } /** @@ -746,8 +784,9 @@ class ACL implements cache_cacheableInterface */ public function get_granted_sbas($rights = []) { - if (is_string($rights)) + if (is_string($rights)) { $rights = [$rights]; + } assert(is_array($rights)); @@ -764,13 +803,14 @@ class ACL implements cache_cacheableInterface break; } } - if ($continue) + if ($continue) { continue; + } try { $ret[$sbas_id] = $this->app->findDataboxById((int) $sbas_id); } catch (\Exception $e) { - + // no-op } } @@ -824,8 +864,7 @@ class ACL implements cache_cacheableInterface } catch (\Exception $e) { } - $sql = 'SELECT sbas_id, record_id, preview, document - FROM records_rights WHERE usr_id = :usr_id'; + $sql = "SELECT sbas_id, record_id, preview, document FROM records_rights WHERE usr_id = :usr_id"; $stmt = $this->app->getApplicationBox()->get_connection()->prepare($sql); $stmt->execute([':usr_id' => $this->user->getId()]); @@ -844,8 +883,8 @@ class ACL implements cache_cacheableInterface } $datas = [ - 'preview' => $this->_rights_records_preview - , 'document' => $this->_rights_records_document + 'preview' => $this->_rights_records_preview, + 'document' => $this->_rights_records_document ]; $this->set_data_to_cache($datas, self::CACHE_RIGHTS_RECORDS); @@ -880,12 +919,10 @@ class ACL implements cache_cacheableInterface return $this; } catch (\Exception $e) { - + // no-op } - $sql = 'SELECT sbasusr.* FROM sbasusr, sbas - WHERE usr_id= :usr_id - AND sbas.sbas_id = sbasusr.sbas_id'; + $sql = "SELECT sbasusr.* FROM sbasusr INNER JOIN sbas USING(sbas_id) WHERE usr_id= :usr_id"; $stmt = $this->app->getApplicationBox()->get_connection()->prepare($sql); $stmt->execute([':usr_id' => $this->user->getId()]); @@ -894,26 +931,16 @@ class ACL implements cache_cacheableInterface $this->_rights_sbas = []; - $this->_global_rights['bas_modif_th'] = false; - $this->_global_rights['bas_modify_struct'] = false; - $this->_global_rights['bas_manage'] = false; - $this->_global_rights['bas_chupub'] = false; + foreach(self::$sbas_rights as $b) { + $this->_global_rights[$b] = false; + } foreach ($rs as $row) { - - if ($row['bas_modif_th'] == '1') - $this->_global_rights['bas_modif_th'] = true; - if ($row['bas_modify_struct'] == '1') - $this->_global_rights['bas_modify_struct'] = true; - if ($row['bas_manage'] == '1') - $this->_global_rights['bas_manage'] = true; - if ($row['bas_chupub'] == '1') - $this->_global_rights['bas_chupub'] = true; - - $this->_rights_sbas[$row['sbas_id']]['bas_modify_struct'] = ($row['bas_modify_struct'] == '1'); - $this->_rights_sbas[$row['sbas_id']]['bas_manage'] = ($row['bas_manage'] == '1'); - $this->_rights_sbas[$row['sbas_id']]['bas_chupub'] = ($row['bas_chupub'] == '1'); - $this->_rights_sbas[$row['sbas_id']]['bas_modif_th'] = ($row['bas_modif_th'] == '1'); + $sbid = $row['sbas_id']; + $this->_rights_sbas[$sbid] = []; + foreach (self::$sbas_rights as $b) { + $this->_global_rights[$b] = ($this->_rights_sbas[$sbid][$b] = ($row[$b] == '1')) || $this->_global_rights[$b]; + } } $this->set_data_to_cache($this->_rights_sbas, self::CACHE_RIGHTS_SBAS); $this->set_data_to_cache($this->_global_rights, self::CACHE_GLOBAL_RIGHTS); @@ -956,9 +983,9 @@ class ACL implements cache_cacheableInterface } $sql = "SELECT u.* FROM basusr u, bas b, sbas s\n" - . "WHERE usr_id= :usr_id\n" - . "AND b.base_id = u.base_id\n" - . "AND s.sbas_id = b.sbas_id"; + . " WHERE usr_id= :usr_id\n" + . " AND b.base_id = u.base_id\n" + . " AND s.sbas_id = b.sbas_id"; $stmt = $this->app->getApplicationBox()->get_connection()->prepare($sql); $stmt->execute([':usr_id' => $this->user->getId()]); @@ -967,110 +994,30 @@ class ACL implements cache_cacheableInterface $this->_rights_bas = $this->_limited = []; - $this->_global_rights['manageusers'] = false; - $this->_global_rights['coll_manage'] = false; - $this->_global_rights['coll_modify_struct'] = false; - $this->_global_rights['order'] = false; - $this->_global_rights['push'] = false; - $this->_global_rights['addrecord'] = false; - $this->_global_rights['modifyrecord'] = false; - $this->_global_rights['changestatus'] = false; - $this->_global_rights['doctools'] = false; - $this->_global_rights['deleterecord'] = false; - $this->_global_rights['addtoalbum'] = false; - $this->_global_rights['report'] = false; - $this->_global_rights['candwnldpreview'] = false; - $this->_global_rights['candwnldhd'] = false; - $this->_global_rights['order_master'] = false; + foreach(self::$bas_rights as $b) { + $this->_global_rights[$b] = false; + } foreach ($rs as $row) { - $this->_rights_bas[$row['base_id']]['actif'] = ($row['actif'] == '1'); + $bid = $row['base_id']; - if ($row['canadmin'] == '1') - $this->_global_rights['manageusers'] = true; - if ($row['manage'] == '1') - $this->_global_rights['coll_manage'] = true; - if ($row['modify_struct'] == '1') - $this->_global_rights['coll_modify_struct'] = true; - if ($row['cancmd'] == '1') - $this->_global_rights['order'] = true; - if ($row['canpush'] == '1') - $this->_global_rights['push'] = true; - if ($row['canaddrecord'] == '1') - $this->_global_rights['addrecord'] = true; - if ($row['canmodifrecord'] == '1') - $this->_global_rights['modifyrecord'] = true; - if ($row['chgstatus'] == '1') - $this->_global_rights['changestatus'] = true; - if ($row['imgtools'] == '1') - $this->_global_rights['doctools'] = true; - if ($row['candeleterecord'] == '1') - $this->_global_rights['deleterecord'] = true; - if ($row['canputinalbum'] == '1') - $this->_global_rights['addtoalbum'] = true; - if ($row['canreport'] == '1') - $this->_global_rights['report'] = true; - if ($row['candwnldpreview'] == '1') - $this->_global_rights['candwnldpreview'] = true; - if ($row['candwnldhd'] == '1') - $this->_global_rights['candwnldhd'] = true; - if ($row['order_master'] == '1') - $this->_global_rights['order_master'] = true; - - $row['limited_from'] = $row['limited_from'] == '0000-00-00 00:00:00' ? '' : trim($row['limited_from']); - $row['limited_to'] = $row['limited_to'] == '0000-00-00 00:00:00' ? '' : trim($row['limited_to']); - - if ($row['time_limited'] == '1' - && ($row['limited_from'] !== '' || $row['limited_to'] !== '')) { - $this->_limited[$row['base_id']] = [ - 'dmin' => $row['limited_from'] ? new DateTime($row['limited_from']) : null - , 'dmax' => $row['limited_to'] ? new DateTime($row['limited_to']) : null - ]; + foreach(self::$bas_rights as $b) { + $this->_global_rights[$b] = ($this->_rights_bas[$bid][$b] = ($row[$b] == '1')) || $this->_global_rights[$b]; } - $this->_rights_bas[$row['base_id']]['imgtools'] - = $row['imgtools'] == '1'; + $this->_rights_bas[$bid]['remain_dwnld'] = (int) $row['remain_dwnld']; + $this->_rights_bas[$bid]['mask_and'] = (int) $row['mask_and']; + $this->_rights_bas[$bid]['mask_xor'] = (int) $row['mask_xor']; - $this->_rights_bas[$row['base_id']]['chgstatus'] - = $row['chgstatus'] == '1'; - $this->_rights_bas[$row['base_id']]['cancmd'] - = $row['cancmd'] == '1'; - $this->_rights_bas[$row['base_id']]['canaddrecord'] - = $row['canaddrecord'] == '1'; - $this->_rights_bas[$row['base_id']]['canpush'] - = $row['canpush'] == '1'; - $this->_rights_bas[$row['base_id']]['candeleterecord'] - = $row['candeleterecord'] == '1'; - $this->_rights_bas[$row['base_id']]['canadmin'] - = $row['canadmin'] == '1'; - $this->_rights_bas[$row['base_id']]['chgstatus'] - = $row['chgstatus'] == '1'; - $this->_rights_bas[$row['base_id']]['candwnldpreview'] - = $row['candwnldpreview'] == '1'; - $this->_rights_bas[$row['base_id']]['candwnldhd'] - = $row['candwnldhd'] == '1'; - $this->_rights_bas[$row['base_id']]['nowatermark'] - = $row['nowatermark'] == '1'; - $this->_rights_bas[$row['base_id']]['restrict_dwnld'] - = $row['restrict_dwnld'] == '1'; - $this->_rights_bas[$row['base_id']]['remain_dwnld'] - = (int) $row['remain_dwnld']; - $this->_rights_bas[$row['base_id']]['canmodifrecord'] - = $row['canmodifrecord'] == '1'; - $this->_rights_bas[$row['base_id']]['canputinalbum'] - = $row['canputinalbum'] == '1'; - $this->_rights_bas[$row['base_id']]['canreport'] - = $row['canreport'] == '1'; - $this->_rights_bas[$row['base_id']]['mask_and'] - = (int) $row['mask_and']; - $this->_rights_bas[$row['base_id']]['mask_xor'] - = (int) $row['mask_xor']; - $this->_rights_bas[$row['base_id']]['modify_struct'] - = $row['modify_struct'] == '1'; - $this->_rights_bas[$row['base_id']]['manage'] - = $row['manage'] == '1'; - $this->_rights_bas[$row['base_id']]['order_master'] - = $row['order_master'] == '1'; + $row['limited_from'] = $row['limited_from'] == '0000-00-00 00:00:00' ? '' : trim($row['limited_from']); + $row['limited_to'] = $row['limited_to'] == '0000-00-00 00:00:00' ? '' : trim($row['limited_to']); + + if ($row['time_limited'] == '1' && ($row['limited_from'] !== '' || $row['limited_to'] !== '')) { + $this->_limited[$bid] = [ + 'dmin' => $row['limited_from'] ? new DateTime($row['limited_from']) : null, + 'dmax' => $row['limited_to'] ? new DateTime($row['limited_to']) : null + ]; + } } $this->set_data_to_cache($this->_global_rights, self::CACHE_GLOBAL_RIGHTS); @@ -1089,7 +1036,7 @@ class ACL implements cache_cacheableInterface { $this->load_rights_bas(); $this->load_rights_sbas(); - $this->_global_rights['taskmanager'] = $this->is_admin(); + $this->_global_rights[self::TASKMANAGER] = $this->is_admin(); return $this; } @@ -1105,21 +1052,21 @@ class ACL implements cache_cacheableInterface switch ($module_name) { case 'admin': return ( - ($this->has_right('bas_modify_struct') || - $this->has_right('coll_modify_struct') || - $this->has_right('bas_manage') || - $this->has_right('coll_manage') || - $this->has_right('manageusers') || + ($this->has_right(self::BAS_MODIFY_STRUCT) || + $this->has_right(self::COLL_MODIFY_STRUCT) || + $this->has_right(self::BAS_MANAGE) || + $this->has_right(self::COLL_MANAGE) || + $this->has_right(self::CANADMIN) || $this->is_admin()) ); break; case 'thesaurus': - return ($this->has_right('bas_modif_th') === true ); + return ($this->has_right(self::BAS_MODIF_TH) === true ); break; case 'upload': - return ($this->has_right('addrecord') === true); + return ($this->has_right(self::CANADDRECORD) === true); break; case 'report': - return ($this->has_right('report') === true); + return ($this->has_right(self::CANREPORT) === true); break; default: break; @@ -1129,9 +1076,10 @@ class ACL implements cache_cacheableInterface } /** - * - * @param array $base_ids - * @return ACL + * @param array $base_ids + * @return $this + * @throws DBALException + * @throws Exception */ public function revoke_access_from_bases(Array $base_ids) { @@ -1168,48 +1116,36 @@ class ACL implements cache_cacheableInterface */ public function give_access_to_base(Array $base_ids) { - $sql_ins = 'INSERT INTO basusr (id, base_id, usr_id, actif) - VALUES (null, :base_id, :usr_id, "1")'; - $stmt_ins = $this->app->getApplicationBox()->get_connection()->prepare($sql_ins); - $usr_id = $this->user->getId(); - $to_update = []; $this->load_rights_bas(); + $usr_id = $this->user->getId(); + + $sql_i = "INSERT INTO basusr (base_id, usr_id, actif) VALUES (:base_id, :usr_id, '1')"; + $stmt_i = $this->app->getApplicationBox()->get_connection()->prepare($sql_i); + + $sql_u = "UPDATE basusr SET actif='1' WHERE base_id = :base_id AND usr_id = :usr_id"; + $stmt_u = $this->app->getApplicationBox()->get_connection()->prepare($sql_u); + foreach ($base_ids as $base_id) { - if (!isset($this->_rights_bas[$base_id])) { - try { - $stmt_ins->execute([':base_id' => $base_id, ':usr_id' => $usr_id]); - } catch (DBALException $e) { -// if (null !== $e) { -// var_dump(get_class($e->getPrevious())); -// } - if (($e->getCode() == 23000)) { - $to_update[] = $base_id; - } - } - } elseif ($this->_rights_bas[$base_id]['actif'] === false) { - $to_update[] = $base_id; + if (isset($this->_rights_bas[$base_id]) && $this->_rights_bas[$base_id][self::ACTIF] == true) { + continue; + } + + if($this->try_give_access_to_base_insert($stmt_i, $base_id, $usr_id) == true) { + $this->app['dispatcher']->dispatch( + AclEvents::ACCESS_TO_BASE_GRANTED, + new AccessToBaseGrantedEvent( + $this, + array( + 'base_id'=>$base_id + ) + ) + ); + } + else { + $this->try_give_access_to_base_update($stmt_u, $base_id, $usr_id); } } - $stmt_ins->closeCursor(); - - $sql_upd = 'UPDATE basusr SET actif="1" - WHERE usr_id = :usr_id AND base_id = :base_id'; - $stmt_upd = $this->app->getApplicationBox()->get_connection()->prepare($sql_upd); - foreach ($to_update as $base_id) { - $stmt_upd->execute([':usr_id' => $usr_id, ':base_id' => $base_id]); - - $this->app['dispatcher']->dispatch( - AclEvents::ACCESS_TO_BASE_GRANTED, - new AccessToBaseGrantedEvent( - $this, - array( - 'base_id'=>$base_id - ) - ) - ); - } - $stmt_upd->closeCursor(); $this->delete_data_from_cache(self::CACHE_RIGHTS_BAS); $this->inject_rights(); @@ -1217,6 +1153,29 @@ class ACL implements cache_cacheableInterface return $this; } + private function try_give_access_to_base_insert(Statement $stmt, $base_id, $usr_id) + { + $inserted = false; + try { + $stmt->execute([':base_id' => $base_id, ':usr_id' => $usr_id]); + if ($stmt->rowCount() > 0) { + $inserted = true; + } + $stmt->closeCursor(); + } + catch(DBALException $e) { + // no-op, mostly the row did exist + } + + return $inserted; + } + + private function try_give_access_to_base_update(Statement $stmt, $base_id, $usr_id) + { + $stmt->execute([':base_id' => $base_id, ':usr_id' => $usr_id]); + $stmt->closeCursor(); + } + /** * * @param array $sbas_ids @@ -1264,44 +1223,31 @@ class ACL implements cache_cacheableInterface */ public function update_rights_to_base($base_id, $rights) { - - if (!$this->has_access_to_base($base_id) && (!isset($rights['actif']) || $rights['actif'] == '1')) { + if (!$this->has_access_to_base($base_id) && (!isset($rights[self::ACTIF]) || $rights[self::ACTIF] == true)) { $this->give_access_to_base([$base_id]); } - $sql_up = "UPDATE basusr SET "; + $conn = $this->app->getApplicationBox()->get_connection(); - $sql_args = $params = []; + $sql_args = []; foreach ($rights as $right => $v) { - $sql_args[] = " " . $right . " = :" . $right; - switch ($right) { - default: - $params[':' . $right] = $v ? '1' : '0'; - break; - case 'mask_and': - case 'mask_xor': - $params[':' . $right] = $v; - break; + if(is_bool($v)) { + $v = $v ? 1 : 0; } + $sql_args[] = " " . $conn->quoteIdentifier($right) . "=" . $conn->quote($v) . "\n"; } if (count($sql_args) == 0) { return $this; } - $usr_id = $this->user->getId(); + $sql = "UPDATE basusr SET\n" + . implode(',', $sql_args) + . " WHERE base_id = :base_id AND usr_id = :usr_id"; - $sql_up .= implode(', ', $sql_args) . ' WHERE base_id = :base_id - AND usr_id = :usr_id'; - - $params = array_merge( - $params - , [':base_id' => $base_id, ':usr_id' => $usr_id] - ); - - $stmt_up = $this->app->getApplicationBox()->get_connection()->prepare($sql_up); - $stmt_up->execute($params); - $stmt_up->closeCursor(); + $stmt = $conn->prepare($sql); + $stmt->execute([':base_id' => $base_id, ':usr_id' => $this->user->getId()]); + $stmt->closeCursor(); $this->delete_data_from_cache(self::CACHE_RIGHTS_BAS); @@ -1309,10 +1255,10 @@ class ACL implements cache_cacheableInterface AclEvents::RIGHTS_TO_BASE_CHANGED, new RightsToBaseChangedEvent( $this, - array( - 'base_id'=>$base_id, - 'rights'=>$rights - ) + [ + 'base_id' => $base_id, + 'rights' => $rights + ] ) ); @@ -1325,11 +1271,10 @@ class ACL implements cache_cacheableInterface */ public function revoke_unused_sbas_rights() { - $sql = 'DELETE FROM sbasusr - WHERE usr_id = :usr_id_1 - AND sbas_id NOT IN - (SELECT distinct sbas_id FROM basusr bu, bas b - WHERE usr_id = :usr_id_2 AND b.base_id = bu.base_id)'; + $sql = "DELETE FROM sbasusr\n" + . " WHERE usr_id = :usr_id_1\n" + . " AND sbas_id NOT IN\n" + . "(SELECT distinct sbas_id FROM basusr bu, bas b WHERE usr_id = :usr_id_2 AND b.base_id = bu.base_id)"; $usr_id = $this->user->getId(); $params = [':usr_id_1' => $usr_id, ':usr_id_2' => $usr_id]; @@ -1344,50 +1289,50 @@ class ACL implements cache_cacheableInterface } /** - * - * @param $sbas_id - * @param $rights - * @return ACL + * @param $sbas_id + * @param $rights + * @return $this + * @throws DBALException + * @throws Exception */ public function update_rights_to_sbas($sbas_id, $rights) { - if (!$this->has_access_to_sbas($sbas_id)) + if (!$this->has_access_to_sbas($sbas_id)) { $this->give_access_to_sbas([$sbas_id]); - - $sql_up = "UPDATE sbasusr SET "; + } $sql_args = []; - $usr_id = $this->user->getId(); - $params = [':sbas_id' => $sbas_id, ':usr_id' => $usr_id]; + $conn = $this->app->getApplicationBox()->get_connection(); foreach ($rights as $right => $v) { - $sql_args[] = " " . $right . " = :" . $right; - $params[':' . $right] = $v ? '1' : '0'; + if(is_bool($v)) { + $v = $v ? 1 : 0; + } + $sql_args[] = " " . $conn->quoteIdentifier($right) . "=" . $conn->quote($v) . "\n"; } if (count($sql_args) == 0) { return $this; } - $sql_up .= implode(', ', $sql_args) . ' - WHERE sbas_id = :sbas_id AND usr_id = :usr_id'; + $sql = "UPDATE sbasusr SET\n" + . implode(',', $sql_args) + . " WHERE sbas_id = :sbas_id AND usr_id = :usr_id"; - $stmt_up = $this->app->getApplicationBox()->get_connection()->prepare($sql_up); + $stmt = $conn->prepare($sql); + $stmt->execute([':sbas_id' => $sbas_id, ':usr_id' => $this->user->getId()]); + $stmt->closeCursor(); - if (!$stmt_up->execute($params)) { - throw new Exception('Error while updating some rights'); - } - $stmt_up->closeCursor(); $this->delete_data_from_cache(self::CACHE_RIGHTS_SBAS); $this->app['dispatcher']->dispatch( AclEvents::RIGHTS_TO_SBAS_CHANGED, new RightsToSbasChangedEvent( $this, - array( - 'sbas_id'=>$sbas_id, - 'rights'=>$rights - ) + [ + 'sbas_id' => $sbas_id, + 'rights' => $rights + ] ) ); @@ -1401,9 +1346,8 @@ class ACL implements cache_cacheableInterface */ public function remove_quotas_on_base($base_id) { - $sql = 'UPDATE basusr - SET remain_dwnld = 0, restrict_dwnld = 0, month_dwnld_max = 0 - WHERE usr_id = :usr_id AND base_id = :base_id '; + $sql = "UPDATE basusr SET remain_dwnld = 0, restrict_dwnld = 0, month_dwnld_max = 0\n" + . " WHERE usr_id = :usr_id AND base_id = :base_id"; $stmt = $this->app->getApplicationBox()->get_connection()->prepare($sql); $stmt->execute([':usr_id' => $this->user->getId(), ':base_id' => $base_id]); @@ -1427,16 +1371,15 @@ class ACL implements cache_cacheableInterface public function update_download_restrictions() { - $sql = 'UPDATE basusr SET remain_dwnld = month_dwnld_max - WHERE actif = 1 - AND usr_id = :usr_id - AND MONTH(lastconn) != MONTH(NOW()) AND restrict_dwnld = 1'; + $sql = "UPDATE basusr SET remain_dwnld = month_dwnld_max\n" + . " WHERE actif = 1" + . " AND usr_id = :usr_id" + . " AND MONTH(lastconn) != MONTH(NOW()) AND restrict_dwnld = 1"; $stmt = $this->app->getApplicationBox()->get_connection()->prepare($sql); $stmt->execute([':usr_id' => $this->user->getId()]); $stmt->closeCursor(); - $sql = "UPDATE basusr SET lastconn=now() - WHERE usr_id = :usr_id AND actif = 1"; + $sql = "UPDATE basusr SET lastconn=NOW() WHERE usr_id = :usr_id AND actif = 1"; $stmt = $this->app->getApplicationBox()->get_connection()->prepare($sql); $stmt->execute([':usr_id' => $this->user->getId()]); $stmt->closeCursor(); @@ -1463,9 +1406,8 @@ class ACL implements cache_cacheableInterface */ public function set_quotas_on_base($base_id, $droits, $restes) { - $sql = 'UPDATE basusr - SET remain_dwnld = :restes, restrict_dwnld = 1, month_dwnld_max = :droits - WHERE usr_id = :usr_id AND base_id = :base_id '; + $sql = "UPDATE basusr SET remain_dwnld = :restes, restrict_dwnld = 1, month_dwnld_max = :droits\n" + . " WHERE usr_id = :usr_id AND base_id = :base_id"; $params = [ ':usr_id' => $this->user->getId(), @@ -1498,8 +1440,7 @@ class ACL implements cache_cacheableInterface public function duplicate_right_from_bas($base_id_from, $base_id_dest) { - $sql = 'SELECT * FROM basusr - WHERE base_id = :base_from AND usr_id = :usr_id'; + $sql = "SELECT * FROM basusr WHERE base_id = :base_from AND usr_id = :usr_id"; $params = [ ':base_from' => $base_id_from, @@ -1517,43 +1458,28 @@ class ACL implements cache_cacheableInterface $this->give_access_to_base([$base_id_dest]); - $rights = [ - 'mask_and' => $row['mask_and'], - 'mask_xor' => $row['mask_xor'], - ]; - - if ($row['canputinalbum']) - $rights['canputinalbum'] = true; - if ($row['candwnldhd']) - $rights['candwnldhd'] = true; - if ($row['candwnldpreview']) - $rights['candwnldpreview'] = true; - if ($row['cancmd']) - $rights['cancmd'] = true; - if ($row['canadmin']) - $rights['canadmin'] = true; - if ($row['canreport']) - $rights['canreport'] = true; - if ($row['canpush']) - $rights['canpush'] = true; - if ($row['nowatermark']) - $rights['nowatermark'] = true; - if ($row['canaddrecord']) - $rights['canaddrecord'] = true; - if ($row['canmodifrecord']) - $rights['canmodifrecord'] = true; - if ($row['candeleterecord']) - $rights['candeleterecord'] = true; - if ($row['chgstatus']) - $rights['chgstatus'] = true; - if ($row['imgtools']) - $rights['imgtools'] = true; - if ($row['manage']) - $rights['manage'] = true; - if ($row['modify_struct']) - $rights['modify_struct'] = true; - - $this->update_rights_to_base($base_id_dest, $rights); + $this->update_rights_to_base( + $base_id_dest, + [ + 'mask_and' => $row['mask_and'], + 'mask_xor' => $row['mask_xor'], + self::CANPUTINALBUM => ($row[self::CANPUTINALBUM] == '1'), + self::CANDWNLDHD => ($row[self::CANDWNLDHD] == '1'), + self::CANDWNLDPREVIEW => ($row[self::CANDWNLDPREVIEW] == '1'), + self::CANCMD => ($row[self::CANCMD] == '1'), + self::CANADMIN => ($row[self::CANADMIN] == '1'), + self::CANREPORT => ($row[self::CANREPORT] == '1'), + self::CANPUSH => ($row[self::CANPUSH] == '1'), + self::NOWATERMARK => ($row[self::NOWATERMARK] == '1'), + self::CANADDRECORD => ($row[self::CANADDRECORD] == '1'), + self::CANMODIFRECORD => ($row[self::CANMODIFRECORD] == '1'), + self::CANDELETERECORD => ($row[self::CANDELETERECORD] == '1'), + self::CHGSTATUS => ($row[self::CHGSTATUS] == '1'), + self::IMGTOOLS => ($row[self::IMGTOOLS] == '1'), + self::COLL_MANAGE => ($row[self::COLL_MANAGE] == '1'), + self::COLL_MODIFY_STRUCT => ($row[self::COLL_MODIFY_STRUCT] == '1') + ] + ); if ($row['time_limited']) { $this->set_limits($base_id_dest, $row['time_limited'], new \DateTime($row['limited_from']), new \DateTime($row['limited_to'])); @@ -1652,10 +1578,10 @@ class ACL implements cache_cacheableInterface } } - $sql = "UPDATE basusr - SET mask_and=((mask_and & " . $vhex['and_and'] . ") | " . $vhex['and_or'] . ") - ,mask_xor=((mask_xor & " . $vhex['xor_and'] . ") | " . $vhex['xor_or'] . ") - WHERE usr_id = :usr_id and base_id = :base_id"; + $sql = "UPDATE basusr\n" + . " SET mask_and=((mask_and & " . $vhex['and_and'] . ") | " . $vhex['and_or'] . "),\n" + . " mask_xor=((mask_xor & " . $vhex['xor_and'] . ") | " . $vhex['xor_or'] . ")\n" + . " WHERE usr_id = :usr_id and base_id = :base_id"; $stmt = $this->app->getApplicationBox()->get_connection()->prepare($sql); $stmt->execute([':base_id' => $base_id, ':usr_id' => $this->user->getId()]); @@ -1695,6 +1621,13 @@ class ACL implements cache_cacheableInterface return $lim_max || $lim_min; } + /** + * returns date limits ['dmin'=>x, 'dmax'=>y] with x,y : NullableDateTime + * + * + * @param $base_id + * @return array|null + */ public function get_limits($base_id) { $this->load_rights_bas(); @@ -1707,31 +1640,18 @@ class ACL implements cache_cacheableInterface public function set_limits($base_id, $limit, DateTime $limit_from = null, DateTime $limit_to = null) { - if ($limit) { - $sql = 'UPDATE basusr - SET time_limited = 1 - , limited_from = :limited_from - , limited_to = :limited_to - WHERE base_id = :base_id AND usr_id = :usr_id'; - } else { - $sql = 'UPDATE basusr - SET time_limited = 0 - , limited_from = :limited_from - , limited_to = :limited_to - WHERE base_id = :base_id AND usr_id = :usr_id'; - } - - $params = [ - ':usr_id' => $this->user->getId(), - ':base_id' => $base_id, - 'limited_from' => NullableDateTime::format($limit_from, DATE_ISO8601), - 'limited_to' => NullableDateTime::format($limit_to, DATE_ISO8601), - ]; + $sql = "UPDATE basusr\n" + . " SET time_limited = :time_limited, limited_from = :limited_from, limited_to = :limited_to\n" + . " WHERE base_id = :base_id AND usr_id = :usr_id"; $stmt = $this->app->getApplicationBox()->get_connection()->prepare($sql); - - $stmt->execute($params); - + $stmt->execute([ + ':time_limited' => $limit ? 1 : 0, + ':usr_id' => $this->user->getId(), + ':base_id' => $base_id, + ':limited_from' => NullableDateTime::format($limit_from, DATE_ISO8601), + ':limited_to' => NullableDateTime::format($limit_to, DATE_ISO8601), + ]); $stmt->closeCursor(); $this->delete_data_from_cache(self::CACHE_LIMITS_BAS); @@ -1753,7 +1673,7 @@ class ACL implements cache_cacheableInterface { // a user can see the business fields if he has at least the right on one collection to edit a record foreach($databox->get_collections() as $collection) { - if ($this->has_access_to_base($collection->get_base_id()) && $this->has_right_on_base($collection->get_base_id(), 'canmodifrecord')) { + if ($this->has_access_to_base($collection->get_base_id()) && $this->has_right_on_base($collection->get_base_id(), self::CANMODIFRECORD)) { return true; } } @@ -1768,7 +1688,7 @@ class ACL implements cache_cacheableInterface */ public function getOrderMasterCollectionsBaseIds() { - $sql = 'SELECT base_id FROM basusr WHERE order_master="1" AND usr_id= :usr_id'; + $sql = "SELECT base_id FROM basusr WHERE order_master='1' AND usr_id= :usr_id"; $result = $this->app->getApplicationBox() ->get_connection() ->executeQuery($sql, [':usr_id' => $this->user->getId()]) @@ -1819,8 +1739,7 @@ class ACL implements cache_cacheableInterface */ public function set_order_master(\collection $collection, $bool) { - $sql = 'UPDATE basusr SET order_master = :master - WHERE usr_id = :usr_id AND base_id = :base_id'; + $sql = "UPDATE basusr SET order_master = :master WHERE usr_id = :usr_id AND base_id = :base_id"; $stmt = $this->app->getApplicationBox()->get_connection()->prepare($sql); $stmt->execute([ diff --git a/lib/classes/User/Query.php b/lib/classes/User/Query.php index 11543ccc0b..4c1c1a8152 100644 --- a/lib/classes/User/Query.php +++ b/lib/classes/User/Query.php @@ -14,7 +14,7 @@ use Alchemy\Phrasea\Model\Entities\User; use Doctrine\Common\Collections\ArrayCollection; use Alchemy\Phrasea\Utilities\Countries; -class User_Query implements User_QueryInterface +class User_Query { const ORD_ASC = 'ASC'; const ORD_DESC = 'DESC'; diff --git a/lib/classes/User/QueryInterface.php b/lib/classes/User/QueryInterface.php deleted file mode 100644 index 837c80c9cf..0000000000 --- a/lib/classes/User/QueryInterface.php +++ /dev/null @@ -1,47 +0,0 @@ -app->getAclForUser($user) ->give_access_to_sbas([$this->id]) ->update_rights_to_sbas( - $this->id, [ - 'bas_manage' => 1, 'bas_modify_struct' => 1, - 'bas_modif_th' => 1, 'bas_chupub' => 1 + $this->id, + [ + \ACL::BAS_MANAGE => true, + \ACL::BAS_MODIFY_STRUCT => true, + \ACL::BAS_MODIF_TH => true, + \ACL::BAS_CHUPUB => true ] ); @@ -1133,9 +1136,7 @@ class databox extends base implements ThumbnailedElement $rs = $stmt->fetchAll(PDO::FETCH_ASSOC); $stmt->closeCursor(); - $sql = "INSERT INTO bas - (base_id, active, server_coll_id, sbas_id) VALUES - (null,'1', :coll_id, :sbas_id)"; + $sql = "INSERT INTO bas (active, server_coll_id, sbas_id) VALUES ('1', :coll_id, :sbas_id)"; $stmt = $conn->prepare($sql); $base_ids = []; @@ -1156,24 +1157,28 @@ class databox extends base implements ThumbnailedElement $this->app->getAclForUser($user)->give_access_to_base($base_ids); foreach ($base_ids as $base_id) { - $this->app->getAclForUser($user)->update_rights_to_base($base_id, [ - 'canpush' => 1, - 'cancmd' => 1, - 'canputinalbum' => 1, - 'candwnldhd' => 1, - 'candwnldpreview' => 1, - 'canadmin' => 1, - 'actif' => 1, - 'canreport' => 1, - 'canaddrecord' => 1, - 'canmodifrecord' => 1, - 'candeleterecord' => 1, - 'chgstatus' => 1, - 'imgtools' => 1, - 'manage' => 1, - 'modify_struct' => 1, - 'nowatermark' => 1 - ]); + $this->app->getAclForUser($user) + ->update_rights_to_base( + $base_id, + [ + \ACL::CANPUSH => true, + \ACL::CANCMD => true, + \ACL::CANPUTINALBUM => true, + \ACL::CANDWNLDHD => true, + \ACL::CANDWNLDPREVIEW => true, + \ACL::CANADMIN => true, + \ACL::ACTIF => true, + \ACL::CANREPORT => true, + \ACL::CANADDRECORD => true, + \ACL::CANMODIFRECORD => true, + \ACL::CANDELETERECORD => true, + \ACL::CHGSTATUS => true, + \ACL::IMGTOOLS => true, + \ACL::COLL_MANAGE => true, + \ACL::COLL_MODIFY_STRUCT => true, + \ACL::NOWATERMARK => true + ] + ); } $this->app->getAclForUser($user)->delete_data_from_cache(); @@ -1190,14 +1195,40 @@ class databox extends base implements ThumbnailedElement return $this; } + public function clearCandidates() + { + try { + $domct = $this->get_dom_cterms(); + + if ($domct !== false) { + $nodesToDel = []; + for($n = $domct->documentElement->firstChild; $n; $n = $n->nextSibling) { + if(!($n->getAttribute('delbranch'))){ + $nodesToDel[] = $n; + } + } + foreach($nodesToDel as $n) { + $n->parentNode->removeChild($n); + } + if(!empty($nodesToDel)) { + $this->saveCterms($domct); + } + } + } catch (\Exception $e) { + + } + } + public function reindex() { + $this->clearCandidates(); $this->get_connection()->update('pref', ['updated_on' => '0000-00-00 00:00:00'], ['prop' => 'indexes']); // Set TO_INDEX flag on all records - $sql = "UPDATE record SET jeton = (jeton | :token)"; + $sql = "UPDATE record SET jeton = ((jeton & ~ :token_and) | :token_or)"; $stmt = $this->connection->prepare($sql); - $stmt->bindValue(':token', PhraseaTokens::TO_INDEX, PDO::PARAM_INT); + $stmt->bindValue(':token_and', PhraseaTokens::INDEXING, PDO::PARAM_INT); + $stmt->bindValue(':token_or', PhraseaTokens::TO_INDEX, PDO::PARAM_INT); $stmt->execute(); $this->app['dispatcher']->dispatch( diff --git a/lib/classes/databox/status.php b/lib/classes/databox/status.php index cf3a817ded..744041e034 100644 --- a/lib/classes/databox/status.php +++ b/lib/classes/databox/status.php @@ -24,7 +24,7 @@ class databox_status foreach ($app->getAclForUser($app->getAuthenticatedUser())->get_granted_sbas() as $databox) { $see_all = false; foreach ($databox->get_collections() as $collection) { - if ($app->getAclForUser($app->getAuthenticatedUser())->has_right_on_base($collection->get_base_id(), 'chgstatus')) { + if ($app->getAclForUser($app->getAuthenticatedUser())->has_right_on_base($collection->get_base_id(), \ACL::CHGSTATUS)) { $see_all = true; break; } diff --git a/lib/classes/databox/subdef.php b/lib/classes/databox/subdef.php index 78dda05862..1cac20b970 100644 --- a/lib/classes/databox/subdef.php +++ b/lib/classes/databox/subdef.php @@ -12,6 +12,7 @@ use Alchemy\Phrasea\Media\Subdef\Audio; use Alchemy\Phrasea\Media\Subdef\FlexPaper; use Alchemy\Phrasea\Media\Subdef\Gif; use Alchemy\Phrasea\Media\Subdef\Image; +use Alchemy\Phrasea\Media\Subdef\Unknown; use Alchemy\Phrasea\Media\Subdef\Subdef as SubdefSpecs; use Alchemy\Phrasea\Media\Subdef\Video; use Alchemy\Phrasea\Media\Type\Type as SubdefType; @@ -37,6 +38,7 @@ class databox_subdef SubdefType::TYPE_FLASH => [SubdefSpecs::TYPE_IMAGE], SubdefType::TYPE_IMAGE => [SubdefSpecs::TYPE_IMAGE], SubdefType::TYPE_VIDEO => [SubdefSpecs::TYPE_IMAGE, SubdefSpecs::TYPE_VIDEO, SubdefSpecs::TYPE_ANIMATION], + SubdefType::TYPE_UNKNOWN => [SubdefSpecs::TYPE_IMAGE] ]; /** @@ -111,6 +113,9 @@ class databox_subdef case SubdefSpecs::TYPE_FLEXPAPER: $this->subdef_type = $this->buildFlexPaperSubdef($sd); break; + case SubdefSpecs::TYPE_UNKNOWN: + $this->subdef_type = $this->buildImageSubdef($sd); + break; } } @@ -372,6 +377,9 @@ class databox_subdef case SubdefSpecs::TYPE_VIDEO: $mediatype_obj = new Video($this->translator); break; + case SubdefSpecs::TYPE_UNKNOWN: + $mediatype_obj = new Unknown($this->translator); + break; default: continue; break; diff --git a/lib/classes/eventsmanager/broker.php b/lib/classes/eventsmanager/broker.php index 55d974d6b1..62244756ce 100644 --- a/lib/classes/eventsmanager/broker.php +++ b/lib/classes/eventsmanager/broker.php @@ -129,13 +129,13 @@ class eventsmanager_broker foreach ($rs as $row) { $type = 'eventsmanager_' . $row['type']; - $data = @json_decode($row['datas'], true); + $json = @json_decode($row['datas'], true); if (json_last_error() !== JSON_ERROR_NONE) { continue; } - $content = $this->pool_classes[$type]->datas($data, $row['unread']); + $content = $this->pool_classes[$type]->datas($json, $row['unread']); if ( ! isset($this->pool_classes[$type]) || count($content) === 0) { $sql = 'DELETE FROM notifications WHERE id = :id'; diff --git a/lib/classes/eventsmanager/notify/autoregister.php b/lib/classes/eventsmanager/notify/autoregister.php index a4a609087b..d9749f8835 100644 --- a/lib/classes/eventsmanager/notify/autoregister.php +++ b/lib/classes/eventsmanager/notify/autoregister.php @@ -73,6 +73,6 @@ class eventsmanager_notify_autoregister extends eventsmanager_notifyAbstract return false; } - return $this->app->getAclForUser($user)->has_right('manageusers'); + return $this->app->getAclForUser($user)->has_right(\ACL::CANADMIN); } } diff --git a/lib/classes/eventsmanager/notify/order.php b/lib/classes/eventsmanager/notify/order.php index 734530fe6e..d5aca30998 100644 --- a/lib/classes/eventsmanager/notify/order.php +++ b/lib/classes/eventsmanager/notify/order.php @@ -75,6 +75,6 @@ class eventsmanager_notify_order extends eventsmanager_notifyAbstract */ public function is_available(User $user) { - return $this->app->getAclForUser($user)->has_right('order_master'); + return $this->app->getAclForUser($user)->has_right(\ACL::ORDER_MASTER); } } diff --git a/lib/classes/eventsmanager/notify/register.php b/lib/classes/eventsmanager/notify/register.php index 8d58b6f001..c0d7222251 100644 --- a/lib/classes/eventsmanager/notify/register.php +++ b/lib/classes/eventsmanager/notify/register.php @@ -75,6 +75,6 @@ class eventsmanager_notify_register extends eventsmanager_notifyAbstract return false; } - return $this->app->getAclForUser($user)->has_right('manageusers'); + return $this->app->getAclForUser($user)->has_right(\ACL::CANADMIN); } } diff --git a/lib/classes/eventsmanager/notify/uploadquarantine.php b/lib/classes/eventsmanager/notify/uploadquarantine.php index 4f1a82b57f..e44f2d66e3 100644 --- a/lib/classes/eventsmanager/notify/uploadquarantine.php +++ b/lib/classes/eventsmanager/notify/uploadquarantine.php @@ -75,6 +75,6 @@ class eventsmanager_notify_uploadquarantine extends eventsmanager_notifyAbstract */ public function is_available(User $user) { - return $this->app->getAclForUser($user)->has_right('addrecord'); + return $this->app->getAclForUser($user)->has_right(\ACL::CANADDRECORD); } } diff --git a/lib/classes/eventsmanager/notify/validationdone.php b/lib/classes/eventsmanager/notify/validationdone.php index 99502ad6d5..6f231f90aa 100644 --- a/lib/classes/eventsmanager/notify/validationdone.php +++ b/lib/classes/eventsmanager/notify/validationdone.php @@ -90,6 +90,6 @@ class eventsmanager_notify_validationdone extends eventsmanager_notifyAbstract */ public function is_available(User $user) { - return $this->app->getAclForUser($user)->has_right('push'); + return $this->app->getAclForUser($user)->has_right(\ACL::CANPUSH); } } diff --git a/lib/classes/media/subdef.php b/lib/classes/media/subdef.php index ed9cf0ffe6..339efac9d1 100644 --- a/lib/classes/media/subdef.php +++ b/lib/classes/media/subdef.php @@ -656,10 +656,12 @@ class media_subdef extends media_abstract implements cache_cacheableInterface $params['height'] = $media->getHeight(); } + /** @var callable $factoryProvider */ $factoryProvider = $app['provider.factory.media_subdef']; $factory = $factoryProvider($record->getDataboxId()); $subdef = $factory($params); + Assertion::isInstanceOf($subdef, \media_subdef::class); $repository = self::getMediaSubdefRepository($app, $record->getDataboxId()); diff --git a/lib/classes/module/report/dashboard.php b/lib/classes/module/report/dashboard.php index 3e7b6b552a..ef9109c6bd 100644 --- a/lib/classes/module/report/dashboard.php +++ b/lib/classes/module/report/dashboard.php @@ -241,7 +241,7 @@ class module_report_dashboard implements module_report_dashboard_componentInterf { $all_coll = []; - $base_ids = $this->app->getAclForUser($this->usr)->get_granted_base(['canreport']); + $base_ids = $this->app->getAclForUser($this->usr)->get_granted_base([\ACL::CANREPORT]); foreach ($base_ids as $base_id => $collection) { $databox = $collection->get_databox(); diff --git a/lib/classes/patch/390alpha1a.php b/lib/classes/patch/390alpha1a.php index 2707f7885a..59628f6b97 100644 --- a/lib/classes/patch/390alpha1a.php +++ b/lib/classes/patch/390alpha1a.php @@ -83,10 +83,7 @@ class patch_390alpha1a extends patchAbstract $em->getEventManager()->removeEventSubscriber(new TimestampableListener()); foreach ($rs as $row) { - $sql = 'SELECT count(id) as todo - FROM order_elements - WHERE deny = NULL - AND order_id = :id'; + $sql = "SELECT count(id) as todo FROM order_elements WHERE deny = NULL AND order_id = :id"; $stmt = $conn->prepare($sql); $stmt->execute([':id' => $row['id']]); @@ -116,9 +113,7 @@ class patch_390alpha1a extends patchAbstract $em->persist($order); - $sql = 'SELECT base_id, record_id, order_master_id, deny - FROM order_elements - WHERE order_id = :id'; + $sql = "SELECT base_id, record_id, order_master_id, deny FROM order_elements WHERE order_id = :id"; $stmt = $conn->prepare($sql); $stmt->execute([':id' => $row['id']]); diff --git a/lib/classes/record/adapter.php b/lib/classes/record/adapter.php index 8a6cb60df0..f924f75a17 100644 --- a/lib/classes/record/adapter.php +++ b/lib/classes/record/adapter.php @@ -98,6 +98,13 @@ class record_adapter implements RecordInterface, cache_cacheableInterface /** @var DateTime */ private $updated; + /** @var bool|null|integer */ + private $width; + /** @var bool|null|integer */ + private $height; + /** @var bool|null|integer */ + private $size; + /** * @param Application $app * @param integer $sbas_id @@ -111,6 +118,8 @@ class record_adapter implements RecordInterface, cache_cacheableInterface $this->reference = RecordReference::createFromDataboxIdAndRecordId($sbas_id, $record_id); $this->number = (int)$number; + $this->width = $this->height = $this->size = false; // means unknown for now + if ($load) { $this->load(); } @@ -171,6 +180,42 @@ class record_adapter implements RecordInterface, cache_cacheableInterface return $this->uuid; } + public function getWidth() + { + $this->getDocInfos(); + + return $this->width; + } + + public function getHeight() + { + $this->getDocInfos(); + + return $this->height; + } + + public function getSize() + { + $this->getDocInfos(); + + return $this->size; + } + + private function getDocInfos() + { + if($this->width === false) { // strict false means unknown + try { + $doc = $this->get_subdef('document'); + $this->width = $doc->get_width(); + $this->height = $doc->get_height(); + $this->size = $doc->get_size(); + } catch (\Exception $e) { + // failing once is failing ever + $this->width = $this->height = $this->size = null; + } + } + } + /** * @return DateTime * @deprecated use {@link self::getUpdated} instead diff --git a/lib/classes/record/exportElement.php b/lib/classes/record/exportElement.php index 1e3f21dc6d..e95558c7e5 100644 --- a/lib/classes/record/exportElement.php +++ b/lib/classes/record/exportElement.php @@ -99,10 +99,10 @@ class record_exportElement extends record_adapter 'thumbnail' => true ]; - if ($this->app->getAclForUser($this->app->getAuthenticatedUser())->has_right_on_base($this->getBaseId(), 'candwnldhd')) { + if ($this->app->getAclForUser($this->app->getAuthenticatedUser())->has_right_on_base($this->getBaseId(), \ACL::CANDWNLDHD)) { $go_dl['document'] = true; } - if ($this->app->getAclForUser($this->app->getAuthenticatedUser())->has_right_on_base($this->getBaseId(), 'candwnldpreview')) { + if ($this->app->getAclForUser($this->app->getAuthenticatedUser())->has_right_on_base($this->getBaseId(), \ACL::CANDWNLDPREVIEW)) { $go_dl['preview'] = true; } if ($this->app->getAclForUser($this->app->getAuthenticatedUser())->has_hd_grant($this)) { @@ -116,10 +116,10 @@ class record_exportElement extends record_adapter $query = $this->app['phraseanet.user-query']; $masters = $query->on_base_ids([$this->getBaseId()]) - ->who_have_right(['order_master']) + ->who_have_right([\ACL::ORDER_MASTER]) ->execute()->get_results(); - $go_cmd = (count($masters) > 0 && $this->app->getAclForUser($this->app->getAuthenticatedUser())->has_right_on_base($this->getBaseId(), 'cancmd')); + $go_cmd = (count($masters) > 0 && $this->app->getAclForUser($this->app->getAuthenticatedUser())->has_right_on_base($this->getBaseId(), \ACL::CANCMD)); $orderable['document'] = false; $downloadable['document'] = false; diff --git a/lib/classes/record/preview.php b/lib/classes/record/preview.php index 92e2b1bbed..210c4f1c5f 100644 --- a/lib/classes/record/preview.php +++ b/lib/classes/record/preview.php @@ -307,9 +307,10 @@ class record_preview extends record_adapter $tab = []; - $report = $this->app->getAclForUser($this->app->getAuthenticatedUser())->has_right_on_base($this->getBaseId(), 'canreport'); + $report = $this->app->getAclForUser($this->app->getAuthenticatedUser()) + ->has_right_on_base($this->getBaseId(), \ACL::CANREPORT); - $sql = 'SELECT d . * , l.user, l.usrid as usr_id, l.site + $sql = 'SELECT d.* , l.user, l.usrid as usr_id, l.site FROM log_docs d, log l WHERE d.log_id = l.id AND d.record_id = :record_id '; @@ -374,8 +375,8 @@ class record_preview extends record_adapter return $this->view_popularity; } - $report = $this->app->getAclForUser($this->app->getAuthenticatedUser())->has_right_on_base( - $this->getBaseId(), 'canreport'); + $report = $this->app->getAclForUser($this->app->getAuthenticatedUser()) + ->has_right_on_base($this->getBaseId(), \ACL::CANREPORT); if ( ! $report && ! $this->app['conf']->get(['registry', 'webservices', 'google-charts-enabled'])) { $this->view_popularity = false; @@ -458,8 +459,8 @@ class record_preview extends record_adapter return $this->refferer_popularity; } - $report = $this->app->getAclForUser($this->app->getAuthenticatedUser())->has_right_on_base( - $this->getBaseId(), 'canreport'); + $report = $this->app->getAclForUser($this->app->getAuthenticatedUser()) + ->has_right_on_base($this->getBaseId(), \ACL::CANREPORT); if ( ! $report && ! $this->app['conf']->get(['registry', 'webservices', 'google-charts-enabled'])) { $this->refferer_popularity = false; @@ -526,7 +527,8 @@ class record_preview extends record_adapter return $this->download_popularity; } - $report = $this->app->getAclForUser($this->app->getAuthenticatedUser())->has_right_on_base($this->getBaseId(), 'canreport'); + $report = $this->app->getAclForUser($this->app->getAuthenticatedUser()) + ->has_right_on_base($this->getBaseId(), \ACL::CANREPORT); $ret = false; if ( ! $report && ! $this->app['conf']->get(['registry', 'webservices', 'google-charts-enabled'])) { diff --git a/lib/classes/set/export.php b/lib/classes/set/export.php index 4eb955a930..50d3799510 100644 --- a/lib/classes/set/export.php +++ b/lib/classes/set/export.php @@ -175,7 +175,7 @@ class set_export extends set_abstract /** @var record_exportElement $download_element */ foreach ($this->get_elements() as $download_element) { - if ($app->getAclForUser($app->getAuthenticatedUser())->has_right_on_base($download_element->getBaseId(), 'canmodifrecord')) { + if ($app->getAclForUser($app->getAuthenticatedUser())->has_right_on_base($download_element->getBaseId(), \ACL::CANMODIFRECORD)) { $this->businessFieldsAccess = true; } @@ -227,11 +227,11 @@ class set_export extends set_abstract $display_ftp = []; - $hasadminright = $app->getAclForUser($app->getAuthenticatedUser())->has_right('addrecord') - || $app->getAclForUser($app->getAuthenticatedUser())->has_right('deleterecord') - || $app->getAclForUser($app->getAuthenticatedUser())->has_right('modifyrecord') - || $app->getAclForUser($app->getAuthenticatedUser())->has_right('coll_manage') - || $app->getAclForUser($app->getAuthenticatedUser())->has_right('coll_modify_struct'); + $hasadminright = $app->getAclForUser($app->getAuthenticatedUser())->has_right(\ACL::CANADDRECORD) + || $app->getAclForUser($app->getAuthenticatedUser())->has_right(\ACL::CANDELETERECORD) + || $app->getAclForUser($app->getAuthenticatedUser())->has_right(\ACL::CANMODIFRECORD) + || $app->getAclForUser($app->getAuthenticatedUser())->has_right(\ACL::COLL_MANAGE) + || $app->getAclForUser($app->getAuthenticatedUser())->has_right(\ACL::COLL_MODIFY_STRUCT); $this->ftp_datas = []; @@ -419,7 +419,7 @@ class set_export extends set_abstract $BF = false; - if ($includeBusinessFields && $this->app->getAclForUser($user)->has_right_on_base($download_element->getBaseId(), 'canmodifrecord')) { + if ($includeBusinessFields && $this->app->getAclForUser($user)->has_right_on_base($download_element->getBaseId(), \ACL::CANMODIFRECORD)) { $BF = true; } @@ -512,7 +512,7 @@ class set_export extends set_abstract 'path' => $subdef->get_path(), 'file' => $subdef->get_file(), ]; - if (!$this->app->getAclForUser($user)->has_right_on_base($download_element->getBaseId(), "nowatermark") + if (!$this->app->getAclForUser($user)->has_right_on_base($download_element->getBaseId(), \ACL::NOWATERMARK) && !$this->app->getAclForUser($user)->has_preview_grant($download_element) && $subdef->get_type() == media_subdef::TYPE_IMAGE ) { diff --git a/resources/ansible/roles/elasticsearch/tasks/main.yml b/resources/ansible/roles/elasticsearch/tasks/main.yml index 5608d8f9f9..c869f754d2 100644 --- a/resources/ansible/roles/elasticsearch/tasks/main.yml +++ b/resources/ansible/roles/elasticsearch/tasks/main.yml @@ -31,6 +31,10 @@ apt: deb=/tmp/elasticsearch-{{ elasticsearch.version }}.deb when: not is_installed +- name: Remove old plugin directory + shell: rm -rf /usr/share/elasticsearch/plugins/analysis-icu + sudo: yes + - name: Install plugins shell: /usr/share/elasticsearch/bin/plugin install {{ item.name }}/{{ item.version }} when: not is_installed diff --git a/resources/www/admin/styles/main.scss b/resources/www/admin/styles/main.scss index 254a8c409c..f04f92f2b7 100644 --- a/resources/www/admin/styles/main.scss +++ b/resources/www/admin/styles/main.scss @@ -253,6 +253,7 @@ div.switch_right.unchecked { } .board_section div[class="section"] ul.setup li.blocker { background-image: url('#{$iconsPath}delete.png'); + background-size: 16px; } .board_section div[class="section"] ul.setup li:hover { background-color: #fffbcd; @@ -322,7 +323,9 @@ div.switch_right.unchecked { #admin_setup_registry .form-horizontal .controls, #admin_setup_registry .form-horizontal .help-message { margin-left: 300px; } - +.alert .close{ + text-decoration: none; +} @import './databases'; @import './fields'; diff --git a/resources/www/prod/js/jquery.main-prod.js b/resources/www/prod/js/jquery.main-prod.js new file mode 100644 index 0000000000..2107c4e4f0 --- /dev/null +++ b/resources/www/prod/js/jquery.main-prod.js @@ -0,0 +1,2845 @@ +document.getElementById('loader_bar').style.width = '30%'; + +var p4 = p4 || {}; + +var baskAjax, baskAjaxrunning; +baskAjaxrunning = false; +var answAjax, answAjaxrunning; +answAjaxrunning = false; +var searchAjax, searchAjaxRunning; +searchAjaxRunning = false; + +var language = {}; +var bodySize = { + x: 0, + y: 0 +}; + +function resizePreview() { + p4.preview.height = $('#PREVIEWIMGCONT').height(); + p4.preview.width = $('#PREVIEWIMGCONT').width(); + setPreview(); +} + +function getHome(cas, page) { + + if (typeof(page) === 'undefined') + page = 0; + + switch (cas) { + case 'QUERY': + selectedFacetValues = []; + newSearch($("#EDIT_query").val()); + break; + case 'PUBLI': + publicationModule.fetchPublications(page, answAjax, answAjaxrunning); + break; + case 'HELP': + $.ajax({ + type: "POST", + url: "/client/home/", + dataType: 'html', + data: { + type: cas + }, + beforeSend: function () { + if (answAjaxrunning && answAjax.abort) + answAjax.abort(); + clearAnswers(); + answAjaxrunning = true; + $('#answers').addClass('loading'); + }, + error: function () { + answAjaxrunning = false; + $('#answers').removeClass('loading'); + }, + timeout: function () { + answAjaxrunning = false; + $('#answers').removeClass('loading'); + }, + success: function (data) { + answAjaxrunning = false; + $('#answers').append(data); + afterSearch(); + return; + } + + }); + break; + + + default: + break; + } +} + +function getLanguage() { + $.ajax({ + type: "GET", + url: "../prod/language/", + dataType: 'json', + success: function (data) { + language = data; + return; + } + }); +} + +function is_ctrl_key(event) { + if (event.altKey) + return true; + if (event.ctrlKey) + return true; + if (event.metaKey) // apple key opera + return true; + if (event.keyCode === 17) // apple key opera + return true; + if (event.keyCode === 224) // apple key mozilla + return true; + if (event.keyCode === 91) // apple key safari + return true; + + return false; +} + +function is_shift_key(event) { + if (event.shiftKey) + return true; + return false; +} + +/** + * adv search : check/uncheck all the collections (called by the buttons "all"/"none") + * + * @param bool + */ +function checkBases(bool) { + $('form.phrasea_query .sbas_list').each(function () { + + var sbas_id = $(this).find('input[name=reference]:first').val(); + if (bool) + $(this).find(':checkbox').prop('checked', true); + else + $(this).find(':checkbox').prop('checked', false); + }); + + checkFilters(true); +} + +function checkFilters(save) { + var danger = false; + var search = { + bases: {}, + fields: [], + dates: {}, + status: [], + elasticSort: {} + + }; + + var adv_box = $('form.phrasea_query .adv_options'); + var container = $("#ADVSRCH_OPTIONS_ZONE"); + var fieldsSort = $('#ADVSRCH_SORT_ZONE select[name=sort]', container); + var fieldsSortOrd = $('#ADVSRCH_SORT_ZONE select[name=ord]', container); + var fieldsSelect = $('#ADVSRCH_FIELDS_ZONE select', container); + var statusFilters = $('#ADVSRCH_SB_ZONE .status-section-title', container); + var dateFilterSelect = $('#ADVSRCH_DATE_ZONE select', container); + var scroll = fieldsSelect.scrollTop(); + + // hide all the fields in the "sort by" select, so only the relevant ones will be shown again + $("option.dbx", fieldsSort).hide().prop("disabled", true); // dbx is for "field of databases" + + // hide all the fields in the "fields" select, so only the relevant ones will be shown again + $("option.dbx", fieldsSelect).hide().prop("disabled", true); // option[0] is "all fields" + + // hide all the fields in the "date field" select, so only the relevant ones will be shown again + $("option.dbx", dateFilterSelect).hide().prop("disabled", true); // dbx = all "field" entries in the select = all except the firstt + + statusFilters.removeClass('danger_indicator danger'); + $.each($('#ADVSRCH_SB_ZONE .field_switch'), function(index,el){ + if( $(el).prop('checked') === true ) { + danger = true; + statusFilters.addClass('danger_indicator danger'); + } + }); + + var nbTotalSelectedColls = 0; + $.each($('.sbascont', adv_box), function () { + var $this = $(this); + + var sbas_id = $this.parent().find('input[name="reference"]').val(); + search.bases[sbas_id] = []; + + var nbCols = 0; + var nbSelectedColls = 0; + $this.find('.checkbas').each(function (idx, el) { + nbCols++; + if($(this).prop('checked')) { + nbSelectedColls++; + nbTotalSelectedColls++; + search.bases[sbas_id].push($(this).val()); + } + }); + + // display the number of selected colls for the databox + $('.infos_sbas_' + sbas_id).empty().append(nbSelectedColls + '/' + nbCols); + + // if one coll is not checked, show danger + if(nbSelectedColls != nbCols) { + $("#ADVSRCH_SBAS_LABEL_" + sbas_id).addClass("danger"); + danger = true; + } + else { + $("#ADVSRCH_SBAS_LABEL_" + sbas_id).removeClass("danger"); + } + + if(nbSelectedColls == 0) { + // no collections checked for this databox + // hide the status bits + $("#ADVSRCH_SB_ZONE_"+sbas_id, container).hide(); + // uncheck + $("#ADVSRCH_SB_ZONE_"+sbas_id+" input:checkbox", container).prop("checked", false); + } + else { + // at least one coll checked for this databox + // show again the relevant fields in "sort by" select + $(".db_"+sbas_id, fieldsSort).show().prop("disabled", false); + // show again the relevant fields in "from fields" select + $(".db_"+sbas_id, fieldsSelect).show().prop("disabled", false); + // show the sb + $("#ADVSRCH_SB_ZONE_"+sbas_id, container).show(); + // show again the relevant fields in "date field" select + $(".db_"+sbas_id, dateFilterSelect).show().prop("disabled", false); + } + }); + + if (nbTotalSelectedColls == 0) { + // no collections checked at all + // hide irrelevant filters + $("#ADVSRCH_OPTIONS_ZONE").hide(); + } + else { + // at least one collection checked + // show relevant filters + $("#ADVSRCH_OPTIONS_ZONE").show(); + } + + // --------- sort -------- + + // if no field is selected for sort, select the default option + if($("option:selected:enabled", fieldsSort).length == 0) { + $("option.default-selection", fieldsSort).prop("selected", true); + $("option.default-selection", fieldsSortOrd).prop("selected", true); + } + + search.elasticSort.by = $("option:selected:enabled", fieldsSort).val(); + search.elasticSort.order = $("option:selected:enabled", fieldsSortOrd).val(); + + //--------- from fields filter --------- + + // unselect the unavailable fields (or all fields if "all" is selected) + var optAllSelected = false; + $("option", fieldsSelect).each( + function(idx, opt) { + if(idx == 0) { + // nb: unselect the "all" field, so it acts as a button + optAllSelected = $(opt).is(":selected"); + } + if(idx == 0 || optAllSelected || $(opt).is(":disabled") || !$(opt).is(":visible") ) { + $(opt).prop("selected", false); + } + } + ); + + // here only the relevant fields are selected + search.fields = fieldsSelect.val(); + if(search.fields == null || search.fields.length == 0) { + $('#ADVSRCH_FIELDS_ZONE', container).removeClass('danger'); + search.fields = []; + } + else { + $('#ADVSRCH_FIELDS_ZONE', container).addClass('danger'); + danger = true; + } + + //--------- status bits filter --------- + + // here only the relevant sb are checked + for(sbas_id in search.bases) { + var nchecked = 0; + $("#ADVSRCH_SB_ZONE_"+sbas_id+" :checkbox[checked]", container).each(function () { + var n = $(this).attr('n'); + search.status[n] = $(this).val().split('_'); + nchecked++; + }); + if(nchecked == 0) { + $("#ADVSRCH_SB_ZONE_"+sbas_id, container).removeClass('danger'); + } + else { + $("#ADVSRCH_SB_ZONE_"+sbas_id, container).addClass('danger'); + danger = true; + } + } + + //--------- dates filter --------- + + // if no date field is selected for filter, select the first option + $('#ADVSRCH_DATE_ZONE', adv_box).removeClass('danger'); + if($("option.dbx:selected:enabled", dateFilterSelect).length == 0) { + $("option:eq(0)", dateFilterSelect).prop("selected", true); + $("#ADVSRCH_DATE_SELECTORS", container).hide(); + } + else { + $("#ADVSRCH_DATE_SELECTORS", container).show(); + search.dates.minbound = $('#ADVSRCH_DATE_ZONE input[name=date_min]', adv_box).val(); + search.dates.maxbound = $('#ADVSRCH_DATE_ZONE input[name=date_max]', adv_box).val(); + search.dates.field = $('#ADVSRCH_DATE_ZONE select[name=date_field]', adv_box).val(); + console.log(search.dates.minbound, search.dates.maxbound, search.dates.field) + if ($.trim(search.dates.minbound) || $.trim(search.dates.maxbound)) { + danger = true; + $('#ADVSRCH_DATE_ZONE', adv_box).addClass('danger'); + } + } + + fieldsSelect.scrollTop(scroll); + + // if one filter shows danger, show it on the query + if (danger) { + $('#EDIT_query').addClass('danger'); + } + else { + $('#EDIT_query').removeClass('danger'); + } + + if (save === true) { + setPref('search', JSON.stringify(search)); + } +} + +function toggleFilter(filter, ele) { + var el = $('#' + filter); + if (el.is(':hidden')) + $(ele).parent().addClass('open'); + else + $(ele).parent().removeClass('open'); + el.slideToggle('fast'); +} + + +function setVisible(el) { + el.style.visibility = 'visible'; +} + +function resize() { + var body = $('#mainContainer'); + bodySize.y = body.height(); + bodySize.x = body.width(); + + $('.overlay').height(bodySize.y).width(bodySize.x); + + var headBlockH = $('#headBlock').outerHeight(); + var bodyY = bodySize.y - headBlockH - 2; + var bodyW = bodySize.x - 2; + //$('#desktop').height(bodyY).width(bodyW); + + if (p4.preview.open) + resizePreview(); + + if ($('#idFrameC').data('ui-resizable')) { + $('#idFrameC').resizable('option', 'maxWidth', (480)); + $('#idFrameC').resizable('option', 'minWidth', 360); + } + + answerSizer(); + linearize(); + + +} + + +function clearAnswers() { + $('#formAnswerPage').val(''); + $('#searchForm input[name="nba"]').val(''); + $('#answers, #dyn_tool').empty(); +} + +function reset_adv_search() { + var container = $("#ADVSRCH_OPTIONS_ZONE"); + var fieldsSort = $('#ADVSRCH_SORT_ZONE select[name=sort]', container); + var fieldsSortOrd = $('#ADVSRCH_SORT_ZONE select[name=ord]', container); + var dateFilterSelect = $('#ADVSRCH_DATE_ZONE select', container); + + $("option.default-selection", fieldsSort).prop("selected", true); + $("option.default-selection", fieldsSortOrd).prop("selected", true); + + $('#ADVSRCH_FIELDS_ZONE option').prop("selected", false); + $('#ADVSRCH_OPTIONS_ZONE input:checkbox.field_switch').prop("checked", false); + + $("option:eq(0)", dateFilterSelect).prop("selected", true); + $('#ADVSRCH_OPTIONS_ZONE .datepicker').val(''); + $('form.adv_search_bind input:text').val(''); + checkBases(true); +} + +function search_doubles() { + selectedFacetValues = []; + $('#EDIT_query').val('sha256=sha256'); + newSearch('sha256=sha256'); +} + +function newSearch(query) { + p4.Results.Selection.empty(); + + clearAnswers(); + $('#SENT_query').val(query); + var histo = $('#history-queries ul'); + + histo.prepend('
  • ' + query + '
  • '); + + var lis = $('li', histo); + if (lis.length > 25) { + $('li:last', histo).remove(); + } + + $('#idFrameC li.proposals_WZ').removeClass('active'); + + $('#searchForm').submit(); + return false; +} + +function beforeSearch() { + if (answAjaxrunning) + return; + answAjaxrunning = true; + + clearAnswers(); + $('#tooltip').css({ + 'display': 'none' + }); + $('#answers').addClass('loading').empty(); + $('#answercontextwrap').remove(); +} + +function afterSearch() { + if ($('#answercontextwrap').length === 0) + $('body').append('
    '); + + $.each($('#answers .contextMenuTrigger'), function () { + + var id = $(this).closest('.IMGT').attr('id').split('_').slice(1, 3).join('_'); + + $(this).contextMenu('#IMGT_' + id + ' .answercontextmenu', { + appendTo: '#answercontextwrap', + openEvt: 'click', + dropDown: true, + theme: 'vista', + showTransition: 'slideDown', + hideTransition: 'hide', + shadow: false + }); + }); + + answAjaxrunning = false; + $('#answers').removeClass('loading'); + $('.captionTips, .captionRolloverTips').tooltip({ + delay: 0, + isBrowsable: false, + extraClass: 'caption-tooltip-container' + }); + $('.infoTips').tooltip({ + delay: 0 + }); + $('.previewTips').tooltip({ + fixable: true + }); + $('.thumb .rollovable').hover( + function () { + $('.rollover-gif-hover', this).show(); + $('.rollover-gif-out', this).hide(); + }, + function () { + $('.rollover-gif-hover', this).hide(); + $('.rollover-gif-out', this).show(); + } + ); + viewNbSelect(); + $('#answers div.IMGT').draggable({ + helper: function () { + $('body').append('
    ' + p4.Results.Selection.length() + '
    '); + return $('#dragDropCursor'); + }, + scope: "objects", + distance: 20, + scroll: false, + cursorAt: { + top: -10, + left: -20 + }, + start: function (event, ui) { + if (!$(this).hasClass('selected')) + return false; + } + }); + linearize(); +} + +function initAnswerForm() { + + var searchForm = $('#searchForm'); + $('button[type="submit"]', searchForm).bind('click', function () { + selectedFacetValues = []; + newSearch($("#EDIT_query").val()); + return false; + }); + + searchForm.unbind('submit').bind('submit', function () { + + var $this = $(this), + method = $this.attr('method') ? $this.attr('method') : 'POST'; + + var data = $this.serializeArray(); + + answAjax = $.ajax({ + type: method, + url: $this.attr('action'), + data: data, + dataType: 'json', + beforeSend: function (formData) { + if (answAjaxrunning && answAjax.abort) + answAjax.abort(); + beforeSearch(); + }, + error: function () { + answAjaxrunning = false; + $('#answers').removeClass('loading'); + }, + timeout: function () { + answAjaxrunning = false; + $('#answers').removeClass('loading'); + }, + success: function (datas) { + + // DEBUG QUERY PARSER + try { + console.info(JSON.parse(datas.parsed_query)); + } + catch(e) {} + + $('#answers').empty().append(datas.results).removeClass('loading'); + + $("#answers img.lazyload").lazyload({ + container: $('#answers') + }); + + loadFacets(datas.facets); + + $('#answers').append('
    '); + + $('#tool_results').empty().append(datas.infos); + $('#tool_navigate').empty().append(datas.navigationTpl); + + $.each(p4.Results.Selection.get(), function (i, el) { + $('#IMGT_' + el).addClass('selected'); + }); + + p4.tot = datas.total_answers; + p4.tot_options = datas.form; + p4.tot_query = datas.query; + p4.navigation = datas.navigation; + + if (datas.next_page) { + $("#NEXT_PAGE, #answersNext").bind('click', function () { + gotopage(datas.next_page); + }); + } + else { + $("#NEXT_PAGE").unbind('click'); + } + + if (datas.prev_page) { + $("#PREV_PAGE").bind('click', function () { + gotopage(datas.prev_page); + }); + } + else { + $("#PREV_PAGE").unbind('click'); + } + + afterSearch(); + } + }); + return false; + }); + if (searchForm.hasClass('triggerAfterInit')) { + searchForm.removeClass('triggerAfterInit').trigger('submit'); + } +} + +var selectedFacetValues = []; + +function loadFacets(facets) { + // Convert facets data to fancytree source format + var treeSource = _.map(facets, function(facet) { + // Values + var values = _.map(facet.values, function(value) { + return { + title: value.value + ' (' + value.count + ')', + query: value.query, + label: value.value, + tooltip: value.value + ' (' + value.count + ')' + } + }); + // Facet + return { + name: facet.name, + title: facet.label, + folder: true, + children: values, + expanded: _.isUndefined(selectedFacetValues[facet.name]) + }; + }); + + treeSource.sort(sortFacets('title', true, function(a){return a.toUpperCase()})); + + treeSource = sortByPredefinedFacets(treeSource, 'name', ['Base_Name', 'Collection_Name', 'Type_Name']); + + return getFacetsTree().reload(treeSource); +} + +function sortByPredefinedFacets(source, field, predefinedFieldOrder) { + var filteredSource = source, + ordered = []; + + _.forEach(predefinedFieldOrder, function (fieldValue, index) { + _.forEach(source, function (facet, facetIndex) { + if (facet[field] !== undefined) { + if (facet[field] === fieldValue) { + ordered.push(facet); + // remove from filtered + filteredSource.splice(facetIndex, 1); + } + } + }); + }); + + var olen = filteredSource.length; + // fill predefined facets with non predefined facets + for (var i = 0; i < olen; i++) { + ordered.push(filteredSource[i]); + } + return ordered; +} + +// from stackoverflow +// http://stackoverflow.com/questions/979256/sorting-an-array-of-javascript-objects/979325#979325 +function sortFacets(field, reverse, primer) { + var key = function (x) {return primer ? primer(x[field]) : x[field]}; + + return function (a,b) { + var A = key(a), B = key(b); + return ( (A < B) ? -1 : ((A > B) ? 1 : 0) ) * [-1,1][+!!reverse]; + } +} + +function getFacetsTree() { + var $facetsTree = $('#proposals'); + if (!$facetsTree.data('ui-fancytree')) { + $facetsTree.fancytree({ + clickFolderMode: 3, // activate and expand + icons:false, + source: [], + activate: function(event, data){ + var query = data.node.data.query; + if (query) { + var facet = data.node.parent; + selectedFacetValues[facet.title] = data.node.data; + facetCombinedSearch(); + } + }, + renderNode: function(event, data){ + var facetFilter = ""; + if(data.node.folder && !_.isUndefined(selectedFacetValues[data.node.title])) { + facetFilter = selectedFacetValues[data.node.title].label; + + var s_label = document.createElement("SPAN"); + s_label.setAttribute("class", "facetFilter-label"); + s_label.setAttribute("title", facetFilter); + + var length = 15; + var facetFilterString = facetFilter; + if( facetFilterString.length > length) { + facetFilterString = facetFilterString.substring(0,length) + '…'; + } + s_label.appendChild(document.createTextNode(facetFilterString)); + + var s_closer = document.createElement("A"); + s_closer.setAttribute("class", "facetFilter-closer"); + + var s_gradient = document.createElement("SPAN"); + s_gradient.setAttribute("class", "facetFilter-gradient"); + s_gradient.appendChild(document.createTextNode("\u00A0")); + + s_label.appendChild(s_gradient); + + var s_facet = document.createElement("SPAN"); + s_facet.setAttribute("class", "facetFilter"); + s_facet.appendChild(s_label); + s_closer = $(s_facet.appendChild(s_closer)); + s_closer.data("facetTitle", data.node.title); + + s_closer.click( + function(event) { + event.stopPropagation(); + var facetTitle = $(this).data("facetTitle"); + delete selectedFacetValues[facetTitle]; + facetCombinedSearch(); + return false; + } + ); + + $(".fancytree-folder", data.node.li).append( + $(s_facet) + ); + } + } + }); + + } + return $facetsTree.fancytree('getTree'); +} + +function facetCombinedSearch() { + var q = $("#EDIT_query").val(); + var q_facet = ""; + _.each(_.values(selectedFacetValues), function(facetValue) { + q_facet += (q_facet ? " AND " : "") + '(' + facetValue.query + ')'; + }); + if(q_facet) { + if(q) { + q = '(' + q + ') AND ' + } + q += q_facet; + } + + checkFilters(); + newSearch(q); +} + + + + + +$(document).ready(function() { +}); + + + +function answerSizer() { + var el = $('#idFrameC').outerWidth(); + if (!$.support.cssFloat) { + // $('#idFrameC .insidebloc').width(el - 56); + } + var widthA = Math.round(bodySize.x - el - 10); + $('#rightFrame').width(widthA); + $('#rightFrame').css('left', $('#idFrameC').width()); + +} + +function linearize() { + var list = $('#answers .list'); + if (list.length > 0) { + var fllWidth = $('#answers').innerWidth(); + fllWidth -= 16; + + var stdWidth = 460; + var diff = 28; + var n = Math.round(fllWidth / (stdWidth)); + var w = Math.floor(fllWidth / n) - diff; + if (w < 360 && n > 1) + w = Math.floor(fllWidth / (n - 1)) - diff; + $('#answers .list').width(w); + } + else { + var minMargin = 5; + var margin = 0; + var el = $('#answers .diapo:first'); + var diapoWidth = el.outerWidth() + (minMargin * 2); + var fllWidth = $('#answers').innerWidth(); + fllWidth -= 26; + + var n = Math.floor(fllWidth / (diapoWidth)); + + margin = Math.floor((fllWidth % diapoWidth) / (2 * n)); + margin = margin + minMargin; + + $('#answers .diapo').css('margin', '5px ' + (margin) + 'px'); + } + +} + + +function initLook() { + $('#nperpage_slider').slider({ + value: parseInt($('#nperpage_value').val()), + min: 10, + max: 100, + step: 10, + slide: function (event, ui) { + $('#nperpage_value').val(ui.value); + }, + stop: function (event, ui) { + setPref('images_per_page', $('#nperpage_value').val()); + } + }); + $('#sizeAns_slider').slider({ + value: parseInt($('#sizeAns_value').val()), + min: 90, + max: 270, + step: 10, + slide: function (event, ui) { + $('#sizeAns_value').val(ui.value); + }, + stop: function (event, ui) { + setPref('images_size', $('#sizeAns_value').val()); + } + }); +} + +function acceptCgus(name, value) { + setPref(name, value); +} + +function cancelCgus(id) { + + $.ajax({ + type: "POST", + url: "../prod/TOU/deny/" + id + "/", + dataType: 'json', + success: function (data) { + if (data.success) { + alert(language.cgusRelog); + self.location.replace(self.location.href); + } + else { + humane.error(data.message); + } + } + }); + +} + +function activateCgus() { + var $this = $('.cgu-dialog:first'); + $this.dialog({ + autoOpen: true, + closeOnEscape: false, + draggable: false, + modal: true, + resizable: false, + width: 800, + height: 500, + open: function () { + $this.parents(".ui-dialog:first").find(".ui-dialog-titlebar-close").remove(); + $('.cgus-accept', $(this)).bind('click', function () { + acceptCgus($('.cgus-accept', $this).attr('id'), $('.cgus-accept', $this).attr('date')); + $this.dialog('close').remove(); + activateCgus(); + }); + $('.cgus-cancel', $(this)).bind('click', function () { + if (confirm(language.warningDenyCgus)) { + cancelCgus($('.cgus-cancel', $this).attr('id').split('_').pop()); + } + }); + } + }); +} + +$(document).ready(function () { + humane.forceNew = true; + activateCgus(); +}); + + +function triggerShortcuts() { + + $('#keyboard-stop').bind('click', function () { + var display = $(this).get(0).checked ? '0' : '1'; + + setPref('keyboard_infos', display); + + }); + + var buttons = {}; + + buttons[language.fermer] = function () { + $("#keyboard-dialog").dialog('close'); + }; + + $('#keyboard-dialog').dialog({ + closeOnEscape: false, + resizable: false, + draggable: false, + modal: true, + width: 600, + height: 400, + overlay: { + backgroundColor: '#000', + opacity: 0.7 + }, + open: function (event, ui) { + $(this).dialog("widget").css("z-index", "1400"); + }, + close: function () { + $(this).dialog("widget").css("z-index", "auto"); + if ($('#keyboard-stop').get(0).checked) { + var dialog = $('#keyboard-dialog'); + if (dialog.data("ui-dialog")) { + dialog.dialog('destroy'); + } + dialog.remove(); + } + } + }).dialog('option', 'buttons', buttons).dialog('open'); + + $('#keyboard-dialog').scrollTop(0); + + return false; +} + +function activeZoning() { + $('#idFrameC, #rightFrame').bind('mousedown', function (event) { + var old_zone = p4.active_zone; + p4.active_zone = $(this).attr('id'); + if (p4.active_zone !== old_zone && p4.active_zone !== 'headBlock') { + $('.effectiveZone.activeZone').removeClass('activeZone'); + $('.effectiveZone', this).addClass('activeZone');//.flash('#555555'); + } + $('#EDIT_query').blur(); + }); + $('#rightFrame').trigger('mousedown'); +} + +function RGBtoHex(R, G, B) { + return toHex(R) + toHex(G) + toHex(B); +} +function toHex(N) { + if (N === null) return "00"; + N = parseInt(N); + if (N === 0 || isNaN(N)) return "00"; + N = Math.max(0, N); + N = Math.min(N, 255); + N = Math.round(N); + return "0123456789ABCDEF".charAt((N - N % 16) / 16) + + "0123456789ABCDEF".charAt(N % 16); +} +function hsl2rgb(h, s, l) { + var m1, m2, hue; + var r, g, b; + s /= 100; + l /= 100; + if (s === 0) + r = g = b = (l * 255); + else { + if (l <= 0.5) + m2 = l * (s + 1); + else + m2 = l + s - l * s; + m1 = l * 2 - m2; + hue = h / 360; + r = HueToRgb(m1, m2, hue + 1 / 3); + g = HueToRgb(m1, m2, hue); + b = HueToRgb(m1, m2, hue - 1 / 3); + } + return { + r: r, + g: g, + b: b + }; +} + +function HueToRgb(m1, m2, hue) { + var v; + if (hue < 0) + hue += 1; + else if (hue > 1) + hue -= 1; + + if (6 * hue < 1) + v = m1 + (m2 - m1) * hue * 6; + else if (2 * hue < 1) + v = m2; + else if (3 * hue < 2) + v = m1 + (m2 - m1) * (2 / 3 - hue) * 6; + else + v = m1; + + return 255 * v; +} + +$(document).ready(function () { + + $('input[name=search_type]').bind('click', function () { + console.log('search bind') + var $this = $(this); + var $record_types = $('#recordtype_sel'); + + console.log($this.hasClass('mode_type_reg'), $record_types) + if ($this.hasClass('mode_type_reg')) { + $record_types.css("visibility", "hidden"); // better than hide because does not change layout + $record_types.prop("selectedIndex", 0); + } else { + $record_types.css("visibility", "visible"); + } + }); + + $('.adv_search_button').on('click', function () { + var searchForm = $('#searchForm'); + var parent = searchForm.parent(); + + var options = { + size: (bodySize.x - 120)+'x'+(bodySize.y - 120), + loading: false, + closeCallback: function (dialog) { + + var datas = dialog.find('form.phrasea_query').appendTo(parent);//.clone(); + + $('.adv_trigger', searchForm).show(); + $('.adv_options', searchForm).hide(); + } + }; + + $dialog = p4.Dialog.Create(options); + + searchForm.appendTo($dialog.getDomElement()); + + $dialog.getDomElement().find('.adv_options').show(); + $dialog.getDomElement().find('.adv_trigger').hide(); + + $dialog.getDomElement().find('form').bind('submit.conbo', function () { + $(this).unbind('submit.conbo'); + $dialog.Close(); + return false; + }); + + + return false; + }); + + $(document).bind('contextmenu', function (event) { + var targ; + if (event.target) + targ = event.target; + else if (event.srcElement) + targ = event.srcElement; + if (targ.nodeType === 3)// safari bug + targ = targ.parentNode; + + var gogo = true; + var targ_name = targ.nodeName ? targ.nodeName.toLowerCase() : false; + + if (targ_name !== 'input' && targ_name.toLowerCase() !== 'textarea') { + gogo = false; + } + if (targ_name === 'input') { + if ($(targ).is(':checkbox')) + gogo = false; + } + + return gogo; + }); + + $('.basket_refresher').on('click', function () { + return p4.WorkZone.refresh('current'); + return false; + }); + + $('#loader_bar').stop().animate({ + width: '70%' + }, 450); + p4.preview = { + open: false, + current: false + }; + p4.currentViewMode = 'classic'; + p4.nbNoview = 0; + p4.reg_delete = true; + p4.sel = []; + p4.baskSel = []; + p4.edit = {}; + p4.thesau = { + tabs: null + }; + p4.active_zone = false; + p4.next_bask_scroll = false; + + + $('#backcolorpickerHolder').ColorPicker({ + flat: true, + color: '404040', + livePreview: false, + eventName: 'mouseover', + onSubmit: function (hsb, hex, rgb, el) { + var back_hex = ''; + var unactive = ''; + + + if (hsb.b >= 50) { + back_hex = '000000'; + + var sim_b = 0.1 * hsb.b; + } + else { + back_hex = 'FFFFFF'; + + var sim_b = 100 - 0.1 * (100 - hsb.b); + } + + var sim_b = 0.1 * hsb.b; + + var sim_rgb = hsl2rgb(hsb.h, hsb.s, sim_b); + var sim_hex = RGBtoHex(sim_rgb.r, sim_rgb.g, sim_rgb.b); + + setPref('background-selection', hex); + setPref('background-selection-disabled', sim_hex); + setPref('fontcolor-selection', back_hex); + + $('style[title=color_selection]').empty(); + + var datas = '.diapo.selected,#reorder_box .diapo.selected, #EDIT_ALL .diapo.selected, .list.selected, .list.selected .diapo' + + '{' + + ' COLOR: #' + back_hex + ';' + + ' BACKGROUND-COLOR: #' + hex + ';' + + '}'; + $('style[title=color_selection]').empty().text(datas); + } + }); + $('#backcolorpickerHolder').find('.colorpicker_submit').append($('#backcolorpickerHolder .submiter')).bind('click', function () { + $(this).highlight('#CCCCCC'); + }); + + $('#search_submit').on('mousedown', function (event) { + return false; + }); + + $('#history-queries ul li').on('mouseover',function () { + $(this).addClass('hover'); + }).on('mouseout', function () { + $(this).removeClass('hover'); + }); + + startThesaurus(); + checkFilters(); + + activeZoning(); + + $('.shortcuts-trigger').bind('click', function () { + triggerShortcuts(); + }); + + $('#idFrameC').resizable({ + handles: 'e', + resize: function () { + answerSizer(); + linearize(); + }, + stop: function () { + + var el = $('.SSTT.active').next().find('div:first'); + var w = el.find('div.chim-wrapper:first').outerWidth(); + var iw = el.innerWidth(); + var diff = $('#idFrameC').width() - el.outerWidth(); + var n = Math.floor(iw / w); + + $('#idFrameC').height('auto'); + + var nwidth = (n) * w + diff + n; + if (isNaN(nwidth)) { + saveWindows(); + return; + } + if (nwidth < 265) + nwidth = 265; + if (el.find('div.chim-wrapper:first').hasClass('valid') && nwidth < 410) + nwidth = 410; + + + $('#idFrameC').stop().animate({ + width: nwidth + }, + 360, + 'linear', + function () { + answerSizer(); + linearize(); + saveWindows(); + }); + } + }); + + $('#idFrameC .ui-tabs-nav li').on('click', function (event) { + if($('#idFrameC').attr('data-status') == 'closed'){ + $('#idFrameC').width(360); + $('#rightFrame').css('left', 360); + $('#rightFrame').width($(window).width()-360); + $('#baskets, #proposals, #thesaurus_tab').hide(); + $('.ui-resizable-handle, #basket_menu_trigger').show(); + var IDname = $(this).attr('aria-controls'); + $('#'+IDname).show(); + } + + $('#idFrameC').attr('data-status', 'open'); + $('.WZbasketTab').css('background-position', '9px 25px'); + $('#idFrameC').removeClass('closed'); + }); + + var previousTab = ""; + + $('#idFrameC #retractableButton').bind('click', function (event) { + + if($('#idFrameC').attr('data-status') != 'closed'){ + $(this).find('i').removeClass('icon-double-angle-left').addClass('icon-double-angle-right') + $('#idFrameC').width(80); + $('#rightFrame').css('left', 80); + $('#rightFrame').width($(window).width()-80); + $('#idFrameC').attr('data-status', 'closed'); + $('#baskets, #proposals, #thesaurus_tab, .ui-resizable-handle, #basket_menu_trigger').hide(); + $('#idFrameC .ui-tabs-nav li').removeClass('ui-state-active'); + $('.WZbasketTab').css('background-position', '15px 25px'); + $('#idFrameC').addClass('closed'); + previousTab = $('#idFrameC .icon-menu').find('li.ui-tabs-active'); + }else{ + $(this).find('i').removeClass('icon-double-angle-right').addClass('icon-double-angle-left') + $('#idFrameC').width(360); + $('#rightFrame').css('left', 360); + $('#rightFrame').width($(window).width()-360); + $('#idFrameC').attr('data-status', 'open'); + $('.ui-resizable-handle, #basket_menu_trigger').show(); + $('.WZbasketTab').css('background-position', '9px 25px'); + $('#idFrameC').removeClass('closed'); + $('#idFrameC .icon-menu li').last().find('a').trigger('click'); + $('#idFrameC .icon-menu li').first().find('a').trigger('click'); + $(previousTab).find('a').trigger('click'); + } + + event.stopImmediatePropagation(); + //p4.WorkZone.close(); + return false; + }); + + $('#look_box .tabs').tabs(); + + resize(); + + $(window).bind('resize', function () { + resize(); + }); + $('body').append(''); + + $('body').append(''); + + $('#basket_menu_trigger').contextMenu('#basket_menu', { + openEvt: 'click', + dropDown: true, + theme: 'vista', + showTransition: 'slideDown', + hideTransition: 'hide', + shadow: false + }); + + $('#basket_menu_trigger').trigger("click"); + $('#basket_menu_trigger').trigger("click"); + + $('.datepicker').datepicker({ + changeYear: true, + changeMonth: true, + dateFormat: 'yy/mm/dd' + }); + + $.ajaxSetup({ + + error: function (jqXHR, textStatus, errorThrown) { + //Request is aborted + if (errorThrown === 'abort') { + return false; + } else { + showModal('error', { + title: language.errorAjaxRequest + ' ' + jqXHR.responseText + }); + } + }, + timeout: function () { + showModal('timeout', { + title: 'Server not responding' + }); + } + }); + + $('.tools .answer_selector').bind('click',function () { + selector($(this)); + }).bind('mouseover',function (event) { + if (is_ctrl_key(event)) { + $(this).addClass('add_selector'); + } + else { + $(this).removeClass('add_selector'); + } + }).bind('mouseout', function () { + $(this).removeClass('add_selector'); + }); + + getLanguage(); + + activeIcons(); + + initAnswerForm(); + + initLook(); + + setTimeout("pollNotifications();", 10000); + + $(this).bind('keydown', function (event) { + var cancelKey = false; + var shortCut = false; + + if ($('#MODALDL').is(':visible')) { + switch (event.keyCode) { + case 27: + hideDwnl(); + break; + } + } + else { + if ($('#EDITWINDOW').is(':visible')) { + + switch (event.keyCode) { + case 9: // tab ou shift-tab + edit_chgFld(event, is_shift_key(event) ? -1 : 1); + cancelKey = shortCut = true; + break; + case 27: + edit_cancelMultiDesc(event); + shortCut = true; + break; + + case 33: // pg up + if (!p4.edit.textareaIsDirty || edit_validField(event, "ask_ok")) + skipImage(event, 1); + cancelKey = true; + break; + case 34: // pg dn + if (!p4.edit.textareaIsDirty || edit_validField(event, "ask_ok")) + skipImage(event, -1); + cancelKey = true; + break; + } + + } + else { + if (p4.preview.open) { + if (($('#dialog_dwnl:visible').length === 0 && $('#DIALOG1').length === 0 && $('#DIALOG2').length === 0)) { + switch (event.keyCode) { + case 39: + getNext(); + cancelKey = shortCut = true; + break; + case 37: + getPrevious(); + cancelKey = shortCut = true; + break; + case 27://escape + closePreview(); + break; + case 32: + if (p4.slideShow) + stopSlide(); + else + startSlide(); + cancelKey = shortCut = true; + break; + } + } + } + else { + if ($('#EDIT_query').hasClass('focused')) + return true; + + if ($('.overlay').is(':visible')) + return true; + + if ($('.ui-widget-overlay').is(':visible')) + return true; + + switch (p4.active_zone) { + case 'rightFrame': + switch (event.keyCode) { + case 65: // a + if (is_ctrl_key(event)) { + $('.tools .answer_selector.all_selector').trigger('click'); + cancelKey = shortCut = true; + } + break; + case 80://P + if (is_ctrl_key(event)) { + printThis("lst=" + p4.Results.Selection.serialize()); + cancelKey = shortCut = true; + } + break; + case 69://e + if (is_ctrl_key(event)) { + editThis('IMGT', p4.Results.Selection.serialize()); + cancelKey = shortCut = true; + } + break; + case 40: // down arrow + $('#answers').scrollTop($('#answers').scrollTop() + 30); + cancelKey = shortCut = true; + break; + case 38: // down arrow + $('#answers').scrollTop($('#answers').scrollTop() - 30); + cancelKey = shortCut = true; + break; + case 37://previous page + $('#PREV_PAGE').trigger('click'); + shortCut = true; + break; + case 39://previous page + $('#NEXT_PAGE').trigger('click'); + shortCut = true; + break; + case 9://tab + if (!is_ctrl_key(event) && !$('.ui-widget-overlay').is(':visible') && !$('.overlay_box').is(':visible')) { + document.getElementById('EDIT_query').focus(); + cancelKey = shortCut = true; + } + break; + } + break; + + + case 'idFrameC': + switch (event.keyCode) { + case 65: // a + if (is_ctrl_key(event)) { + p4.WorkZone.Selection.selectAll(); + cancelKey = shortCut = true; + } + break; + case 80://P + if (is_ctrl_key(event)) { + printThis("lst=" + p4.WorkZone.Selection.serialize()); + cancelKey = shortCut = true; + } + break; + case 69://e + if (is_ctrl_key(event)) { + editThis('IMGT', p4.WorkZone.Selection.serialize()); + cancelKey = shortCut = true; + } + break; + // case 46://del + // deleteThis(p4.Results.Selection.serialize()); + // cancelKey = true; + // break; + case 40: // down arrow + $('#baskets div.bloc').scrollTop($('#baskets div.bloc').scrollTop() + 30); + cancelKey = shortCut = true; + break; + case 38: // down arrow + $('#baskets div.bloc').scrollTop($('#baskets div.bloc').scrollTop() - 30); + cancelKey = shortCut = true; + break; + // case 37://previous page + // $('#PREV_PAGE').trigger('click'); + // break; + // case 39://previous page + // $('#NEXT_PAGE').trigger('click'); + // break; + case 9://tab + if (!is_ctrl_key(event) && !$('.ui-widget-overlay').is(':visible') && !$('.overlay_box').is(':visible')) { + document.getElementById('EDIT_query').focus(); + cancelKey = shortCut = true; + } + break; + } + break; + + + case 'mainMenu': + break; + + + case 'headBlock': + break; + + default: + break; + + } + } + } + } + + if (!$('#EDIT_query').hasClass('focused') && event.keyCode !== 17) { + + if ($('#keyboard-dialog.auto').length > 0 && shortCut) { + triggerShortcuts(); + } + } + if (cancelKey) { + event.cancelBubble = true; + if (event.stopPropagation) + event.stopPropagation(); + return(false); + } + return(true); + }); + + + $('#EDIT_query').bind('focus',function () { + $(this).addClass('focused'); + }).bind('blur', function () { + $(this).removeClass('focused'); + }); + + $('.basketTips').tooltip({ + delay: 200 + }); + + $('#idFrameC .tabs').tabs({ + activate: function (event, ui) { + if (ui.newTab.context.hash == "#thesaurus_tab") { + thesau_show(); + } + p4.WorkZone.open(); + } + }); + + $('#PREVIEWBOX .gui_vsplitter', p4.edit.editBox).draggable({ + axis: 'x', + containment: 'parent', + drag: function (event, ui) { + var x = $(ui.position.left)[0]; + if (x < 330 || x > (bodySize.x - 400)) { + return false; + } + var v = $(ui.position.left)[0]; + $("#PREVIEWLEFT").width(v); + $("#PREVIEWRIGHT").css("left", $(ui.position.left)[0]); + resizePreview(); + } + }); + + $('input.input_select_copy').on('focus', function () { + $(this).select(); + }); + $('input.input_select_copy').on('blur', function () { + $(this).deselect(); + }); + $('input.input_select_copy').on('click', function () { + $(this).select(); + }); + + $('#loader_bar').stop().animate({ + width: '100%' + }, 450, function () { + $('#loader').parent().fadeOut('slow', function () { + $(this).remove(); + }); + }); + +}); + + +function editThis(type, value) { + + $('#idFrameE').empty().addClass('loading'); + showOverlay(2); + + $('#EDITWINDOW').show(); + + var options = { + lst: '', + ssel: '', + act: '' + }; + + switch (type) { + case "IMGT": + options.lst = value; + break; + + case "SSTT": + options.ssel = value; + break; + + case "STORY": + options.story = value; + break; + } + + $.ajax({ + url: "../prod/records/edit/", + type: "POST", + dataType: "html", + data: options, + success: function (data) { + initializeEdit(); + $('#idFrameE').removeClass('loading').empty().html(data); + $('#tooltip').hide(); + return; + }, + error: function (XHR, textStatus, errorThrown) { + if (XHR.status === 0) { + return false; + } + } + }); + + return; +} + +(function ($) { + $.fn.extend({ + highlight: function (color) { + if ($(this).hasClass('animating')) { + return; + } + color = typeof color !== 'undefined' ? color : 'red'; + var oldColor = $(this).css('backgroundColor'); + return $(this).addClass('animating').stop().animate({ + backgroundColor: color + }, 50, 'linear', function () { + $(this).stop().animate({ + backgroundColor: oldColor + }, 450, 'linear', function () { + $(this).removeClass('animating'); + }); + }); + } + }); +})(jQuery); + +(function ($) { + $.fn.extend({ + flash: function (color) { + if ($(this).hasClass('animating')) { + return true; + } + color = typeof color !== 'undefined' ? color : 'red'; + + var pos = $(this).offset(); + + if (!pos) { + pos = { + top: 0, + left: 0 + }; + } + + var h = $(this).height(); + var w = $(this).width(); + $('body').append('
    '); + $(this).addClass('animating'); + var el = $(this); + + $('#flashing').stop().animate({ + top: (pos.top + (h / 4)), + left: (pos.left + (w / 4)), + opacity: 0, + width: ($(this).width() / 2), + height: ($(this).height() / 2) + }, 700, function () { + $('#flashing').remove(); + $(el).removeClass('animating'); + }); + } + }); +})(jQuery); + + +function toggleRemoveReg(el) { + var state = !el.checked; + setPref('reg_delete', (state ? '1' : '0')); + p4.reg_delete = state; +} + + +function deleteThis(lst) { + if (lst.split(';').length === 0) { + alert(language.nodocselected); + return false; + } + + var $dialog = p4.Dialog.Create({ + size: 'Small', + title: language.deleteRecords + }); + + $.ajax({ + type: "POST", + url: "../prod/records/delete/what/", + dataType: 'html', + data: {lst: lst}, + success: function (data) { + $dialog.setContent(data); + } + }); + + return false; +} + +function chgCollThis(datas) { + $dialog = p4.Dialog.Create({ + size: 'Small', + title: language.move, + closeButton: true + }); + $.ajax({ + type: "POST", + url: "../prod/records/movecollection/", + data: datas, + success: function (data) { + $dialog.setContent(data); + } + }); +} + +function pushThis(sstt_id, lst, story) { + $dialog = p4.Dialog.Create({ + size: 'Full', + title: language.push + }); + + $.post("../prod/push/sendform/", { + lst: lst, + ssel: sstt_id, + story: story + }, function (data) { + $dialog.setContent(data); + return; + }); +} + +function feedbackThis(sstt_id, lst, story) { + /* disable push closeonescape as an over dialog may exist (add user) */ + $dialog = p4.Dialog.Create({ + size: 'Full', + title: language.feedback + }); + + $.post("../prod/push/validateform/", { + lst: lst, + ssel: sstt_id, + story: story + }, function (data) { + $dialog.setContent(data); + return; + }); +} + +function toolREFACTOR(datas, activeTab) { + + var dialog = p4.Dialog.Create({ + size: 'Medium', + title: language.toolbox, + loading: true + }); + + $.get("../prod/tools/" + , datas + , function (data) { + dialog.setContent(data); + dialog.setOption('contextArgs', datas); + var tabs = $('.tabs', dialog.getDomElement()).tabs(); + + // activate tab if exists: + if( activeTab !== undefined ) { + tabs.tabs('option', 'active', activeTab); + } + return; + } + ); +} + +function activeIcons() { + var $container = $('body'); + $container.on('click', '.TOOL_print_btn', function (e) { + e.preventDefault(); + var value = ""; + + if ($(this).hasClass('results_window')) { + if (p4.Results.Selection.length() > 0) + value = "lst=" + p4.Results.Selection.serialize(); + } + else { + if ($(this).hasClass('basket_window')) { + if (p4.WorkZone.Selection.length() > 0) + value = "lst=" + p4.WorkZone.Selection.serialize(); + else + value = "SSTTID=" + $('.SSTT.active').attr('id').split('_').slice(1, 2).pop(); + } + else { + if ($(this).hasClass('basket_element')) { + value = "SSTTID=" + $('.SSTT.active').attr('id').split('_').slice(1, 2).pop(); + } + else { + if ($(this).hasClass('story_window')) { + if (p4.WorkZone.Selection.length() > 0) { + value = "lst=" + p4.WorkZone.Selection.serialize(); + } + else { + value = "story=" + $('.SSTT.active').attr('id').split('_').slice(1, 2).pop(); + } + } + } + } + } + + if (value !== '') { + printThis(value); + } + else { + alert(language.nodocselected); + } + }); + $container.on('click', '.TOOL_bridge_btn', function (e) { + e.preventDefault(); + var $button = $(this); + var datas = {}; + var bridgeHref = $button.attr("href"); + + if ($button.hasClass('results_window')) { + if (p4.Results.Selection.length() > 0) + datas.lst = p4.Results.Selection.serialize(); + } + else { + if ($button.hasClass('basket_window')) { + bridgeHref = $button.attr("data-href"); + if (p4.WorkZone.Selection.length() > 0) + datas.lst = p4.WorkZone.Selection.serialize(); + else + datas.ssel = $('.SSTT.active').attr('id').split('_').slice(1, 2).pop(); + } + else { + if ($button.hasClass('basket_element')) { + datas.ssel = $('.SSTT.active').attr('id').split('_').slice(1, 2).pop(); + } + else { + if ($button.hasClass('story_window')) { + bridgeHref = $button.attr("data-href"); + if (p4.WorkZone.Selection.length() > 0) { + datas.lst = p4.WorkZone.Selection.serialize(); + } + else { + datas.story = $('.SSTT.active').attr('id').split('_').slice(1, 2).pop(); + } + } + } + } + } + + if (datas.ssel || datas.lst || datas.story) { + init_publicator(bridgeHref, datas); + } + else { + alert(language.nodocselected); + } + }); + + $container.on('click', '.TOOL_trash_btn', function () { + + var type = ""; + var el = false; + + if ($(this).hasClass('results_window')) { + if (p4.Results.Selection.length() > 0) + type = 'IMGT'; + } + else { + if ($(this).hasClass('basket_window')) { + if (p4.WorkZone.Selection.length() > 0) + type = 'CHIM'; + else { + type = 'SSTT'; + el = $('.SSTT.active'); + } + } + else { + if ($(this).hasClass('story_window')) { + if (p4.WorkZone.Selection.length() > 0) { + type = 'CHIM'; + } + else { + type = 'STORY'; + el = $(this).find('input[name=story_key]'); + } + } + } + } + if (type !== '') { + checkDeleteThis(type, el); + } + else { + alert(language.nodocselected); + } + }); + $container.on('click', '.TOOL_ppen_btn', function () { + + var value = ""; + var type = ""; + + if ($(this).hasClass('results_window')) { + if (p4.Results.Selection.length() > 0) { + type = 'IMGT'; + value = p4.Results.Selection.serialize(); + } + } + else { + if ($(this).hasClass('basket_window')) { + if (p4.WorkZone.Selection.length() > 0) { + type = 'IMGT'; + value = p4.WorkZone.Selection.serialize(); + } + else { + type = 'SSTT'; + value = $('.SSTT.active').attr('id').split('_').slice(1, 2).pop(); + } + } + else { + if ($(this).hasClass('basket_element')) { + type = 'SSTT'; + value = $('.SSTT.active').attr('id').split('_').slice(1, 2).pop(); + } + else { + if ($(this).hasClass('story_window')) { + if (p4.WorkZone.Selection.length() > 0) { + type = 'IMGT'; + value = p4.WorkZone.Selection.serialize(); + } + else { + type = 'STORY'; + value = $('.SSTT.active').attr('id').split('_').slice(1, 2).pop(); + } + } + } + } + } + + if (value !== '') { + editThis(type, value); + } + else { + alert(language.nodocselected); + } + }); + $container.on('click', '.TOOL_publish_btn', function () { + var value = ""; + var type = ""; + + if ($(this).hasClass('results_window')) { + if (p4.Results.Selection.length() > 0) { + type = 'IMGT'; + value = p4.Results.Selection.serialize(); + } + } + else { + if ($(this).hasClass('basket_window')) { + if (p4.WorkZone.Selection.length() > 0) { + type = 'IMGT'; + value = p4.WorkZone.Selection.serialize(); + } + else { + type = 'SSTT'; + value = $('.SSTT.active').attr('id').split('_').slice(1, 2).pop(); + } + } + else { + if ($(this).hasClass('basket_element')) { + type = 'SSTT'; + value = $('.SSTT.active').attr('id').split('_').slice(1, 2).pop(); + } + else { + if ($(this).hasClass('story_window')) { + if (p4.WorkZone.Selection.length() > 0) { + type = 'IMGT'; + value = p4.WorkZone.Selection.serialize(); + } + else { + type = 'STORY'; + value = $('.SSTT.active').attr('id').split('_').slice(1, 2).pop(); + } + } + } + } + } + + if (value !== '') { + publicationModule.publishRecords(type, value); + } + else { + alert(language.nodocselected); + } + }); + + + $container.on('click', '.TOOL_chgcoll_btn', function () { + var value = {}; + + if ($(this).hasClass('results_window')) { + if (p4.Results.Selection.length() > 0) + value.lst = p4.Results.Selection.serialize(); + } + else { + if ($(this).hasClass('basket_window')) { + if (p4.WorkZone.Selection.length() > 0) + value.lst = p4.WorkZone.Selection.serialize(); + else + value.ssel = $('.SSTT.active').attr('id').split('_').slice(1, 2).pop(); + } + else { + if ($(this).hasClass('basket_element')) { + value.ssel = $('.SSTT.active').attr('id').split('_').slice(1, 2).pop(); + } + else { + if ($(this).hasClass('story_window')) { + if (p4.WorkZone.Selection.length() > 0) { + value.lst = p4.WorkZone.Selection.serialize(); + } + else { + value.story = $('.SSTT.active').attr('id').split('_').slice(1, 2).pop(); + } + } + } + } + } + + /** + * if works, then the object is not empty + */ + for (i in value) { + return chgCollThis(value); + } + + alert(language.nodocselected); + }); + + $container.on('click', '.TOOL_chgstatus_btn', function () { + var params = {}; + var $this = $(this); + + if ($this.hasClass('results_window')) { + if (p4.Results.Selection.length() > 0) { + params.lst = p4.Results.Selection.serialize(); + } + } else { + if ($this.hasClass('basket_window')) { + if (p4.WorkZone.Selection.length() > 0) { + params.lst = p4.WorkZone.Selection.serialize(); + } else { + params.ssel = $('.SSTT.active').attr('id').split('_').slice(1, 2).pop(); + } + } else { + if ($this.hasClass('basket_element')) { + params.ssel = $('.SSTT.active').attr('id').split('_').slice(1, 2).pop(); + } else { + if ($this.hasClass('story_window')) { + if (p4.WorkZone.Selection.length() > 0) { + params.lst = p4.WorkZone.Selection.serialize(); + } else { + params.story = $('.SSTT.active').attr('id').split('_').slice(1, 2).pop(); + } + } + } + } + } + + if (false === $.isEmptyObject(params)) { + var dialog = p4.Dialog.Create(); + dialog.load('../prod/records/property/', 'GET', params); + } else { + alert(language.nodocselected); + } + }); + + $container.on('click', '.TOOL_pushdoc_btn', function () { + var value = "", type = "", sstt_id = "", story = ""; + if ($(this).hasClass('results_window')) { + if (p4.Results.Selection.length() > 0) + value = p4.Results.Selection.serialize(); + } + else { + if ($(this).hasClass('basket_window')) { + if (p4.WorkZone.Selection.length() > 0) + value = p4.WorkZone.Selection.serialize(); + else + sstt_id = $('.SSTT.active').attr('id').split('_').slice(1, 2).pop(); + } + else { + if ($(this).hasClass('basket_element')) { + sstt_id = $('.SSTT.active').attr('id').split('_').slice(1, 2).pop(); + } + else { + if ($(this).hasClass('story_window')) { + if (p4.WorkZone.Selection.length() > 0) { + value = p4.WorkZone.Selection.serialize(); + } + else { + story = $('.SSTT.active').attr('id').split('_').slice(1, 2).pop(); + } + } + } + } + } + if (value !== '' || sstt_id !== '' || story !== '') { + pushThis(sstt_id, value, story); + } + else { + alert(language.nodocselected); + } + }); + + $container.on('click', '.TOOL_feedback_btn', function () { + var value = "", type = "", sstt_id = "", story = ''; + if ($(this).hasClass('results_window')) { + if (p4.Results.Selection.length() > 0) + value = p4.Results.Selection.serialize(); + } + else { + if ($(this).hasClass('basket_window')) { + if (p4.WorkZone.Selection.length() > 0) + value = p4.WorkZone.Selection.serialize(); + else + sstt_id = $('.SSTT.active').attr('id').split('_').slice(1, 2).pop(); + } + else { + if ($(this).hasClass('basket_element')) { + sstt_id = $('.SSTT.active').attr('id').split('_').slice(1, 2).pop(); + } + else { + if ($(this).hasClass('story_window')) { + if (p4.WorkZone.Selection.length() > 0) { + value = p4.WorkZone.Selection.serialize(); + } + else { + story = $('.SSTT.active').attr('id').split('_').slice(1, 2).pop(); + } + } + } + } + } + if (value !== '' || sstt_id !== '' || story !== '') { + feedbackThis(sstt_id, value, story); + } + else { + alert(language.nodocselected); + } + }); + + $container.on('click', '.TOOL_imgtools_btn', function () { + var datas = {}; + + if ($(this).hasClass('results_window')) { + if (p4.Results.Selection.length() > 0) + datas.lst = p4.Results.Selection.serialize(); + } + else { + if ($(this).hasClass('basket_window')) { + if (p4.WorkZone.Selection.length() > 0) + datas.lst = p4.WorkZone.Selection.serialize(); + else + datas.ssel = $('.SSTT.active').attr('id').split('_').slice(1, 2).pop(); + } + else { + if ($(this).hasClass('basket_element')) { + datas.ssel = $('.SSTT.active').attr('id').split('_').slice(1, 2).pop(); + } + else { + if ($(this).hasClass('story_window')) { + if (p4.WorkZone.Selection.length() > 0) { + datas.lst = p4.WorkZone.Selection.serialize(); + } + else { + datas.story = $('.SSTT.active').attr('id').split('_').slice(1, 2).pop(); + } + } + } + } + } + + if (!$.isEmptyObject(datas)) { + toolREFACTOR(datas); + } + else { + alert(language.nodocselected); + } + }); + + $container.on('click', '.TOOL_disktt_btn', function () { + var datas = {}; + + if ($(this).hasClass('results_window')) { + if (p4.Results.Selection.length() > 0) { + datas.lst = p4.Results.Selection.serialize(); + } + } + else { + if ($(this).hasClass('basket_window')) { + if (p4.WorkZone.Selection.length() > 0) { + datas.lst = p4.WorkZone.Selection.serialize(); + } + else { + datas.ssel = $('.SSTT.active').attr('id').split('_').slice(1, 2).pop(); + } + } + else { + if ($(this).hasClass('basket_element')) { + datas.ssel = $('.SSTT.active').attr('id').split('_').slice(1, 2).pop(); + } + else { + if ($(this).hasClass('story_window')) { + if (p4.WorkZone.Selection.length() > 0) { + datas.lst = p4.WorkZone.Selection.serialize(); + } + else { + datas.story = $('.SSTT.active').attr('id').split('_').slice(1, 2).pop(); + } + } + } + } + } + + for (var i in datas) { + return downloadThis(datas); + } + + alert(language.nodocselected); + }); + + +} + +function checkDeleteThis(type, el) { + el = $(el); + switch (type) { + + + case "IMGT": + case "CHIM": + + var lst = ''; + + if (type === 'IMGT') + lst = p4.Results.Selection.serialize(); + if (type === 'CHIM') + lst = p4.WorkZone.Selection.serialize(); + + deleteThis(lst); + + return; + break; + + + case "SSTT": + + var buttons = {}; + buttons[language.valider] = function (e) { + deleteBasket(el); + }; + + $('#DIALOG').empty().append(language.confirmDel).attr('title', language.attention).dialog({ + autoOpen: false, + resizable: false, + modal: true, + draggable: false + }).dialog('open').dialog('option', 'buttons', buttons); + $('#tooltip').hide(); + return; + break; + case "STORY": + lst = el.val(); + deleteThis(lst); + break; + + } +} + +function shareThis(bas, rec) { + var dialog = p4.Dialog.Create({ + title: language['share'] + }); + + dialog.load("../prod/share/record/" + bas + "/" + rec + "/", "GET"); +} + +function printThis(value) { + if ($("#DIALOG").data("ui-dialog")) { + $("#DIALOG").dialog('destroy'); + } + $('#DIALOG').attr('title', language.print) + .empty().addClass('loading') + .dialog({ + resizable: false, + closeOnEscape: true, + modal: true, + width: '800', + height: '500', + open: function (event, ui) { + $(this).dialog("widget").css("z-index", "1999"); + }, + close: function (event, ui) { + $(this).dialog("widget").css("z-index", "auto"); + } + }) + .dialog('open'); + + $.ajax({ + type: "POST", + url: '../prod/printer/?' + value, + dataType: 'html', + beforeSend: function () { + + }, + success: function (data) { + $('#DIALOG').removeClass('loading').empty() + .append(data); + return; + } + }); +} + + +function downloadThis(datas) { + var dialog = p4.Dialog.Create({title: language['export']}); + + $.post("../prod/export/multi-export/", datas, function (data) { + + dialog.setContent(data); + + $('.tabs', dialog.getDomElement()).tabs(); + + $('.close_button', dialog.getDomElement()).bind('click', function () { + dialog.Close(); + }); + + return false; + }); +} + + +function viewNbSelect() { + $("#nbrecsel").empty().append(p4.Results.Selection.length()); +} + +function selector(el) { + if (el.hasClass('all_selector')) { + p4.Results.Selection.selectAll(); + } + else { + if (el.hasClass('none_selector')) { + p4.Results.Selection.empty(); + } + else { + if (el.hasClass('starred_selector')) { + + } + else { + if (el.hasClass('video_selector')) { + p4.Results.Selection.empty(); + p4.Results.Selection.select('.type-video'); + } + else { + if (el.hasClass('image_selector')) { + p4.Results.Selection.empty(); + p4.Results.Selection.select('.type-image'); + } + else { + if (el.hasClass('document_selector')) { + p4.Results.Selection.empty(); + p4.Results.Selection.select('.type-document'); + } + else { + if (el.hasClass('audio_selector')) { + p4.Results.Selection.empty(); + p4.Results.Selection.select('.type-audio'); + } + } + } + } + } + } + } +} + +function evt_dwnl(value) { + downloadThis("lst=" + value); +} + +function evt_print(value) { + printThis("lst=" + value); +} + +function evt_add_in_chutier(sbas_id, record_id, event, singleSelection) { + var singleSelection = singleSelection || false; + p4.WorkZone.addElementToBasket(sbas_id, record_id, event, singleSelection); +} + +function remove_from_basket(el, confirm) { + var confirm = confirm || false; + p4.WorkZone.removeElementFromBasket(el, confirm); +} + + +function doSpecialSearch(qry, allbase) { + if (allbase) { + checkBases(true); + } + selectedFacetValues = []; + $('#EDIT_query').val(decodeURIComponent(qry).replace(/\+/g, " ")); + newSearch(qry); +} + +function clktri(id) { + var o = $('#TOPIC_UL' + id); + if ($('#TOPIC_UL' + id).hasClass('closed')) + $('#TOPIC_TRI' + id + ' ,#TOPIC_UL' + id).removeClass('closed').addClass('opened'); + else + $('#TOPIC_TRI' + id + ' ,#TOPIC_UL' + id).removeClass('opened').addClass('closed'); +} + + +// ---------------------- fcts du thesaurus +function chgProp(path, v, k) { + var q2; + if (!k) + k = "*"; + //if(k!=null) + v = v + " [" + k + "]"; + $("#thprop_a_" + path).html('"' + v + '"'); + // q = document.getElementById("thprop_q").innerText; + // if(!q ) + // if(document.getElementById("thprop_q") && document.getElementById("thprop_q").textContent) + // q = document.getElementById("thprop_q").textContent; + q = $("#thprop_q").text(); + + q2 = ""; + for (i = 0; i < q.length; i++) + q2 += q.charCodeAt(i) == 160 ? " " : q.charAt(i); + + selectedFacetValues = []; + $('#EDIT_query').val(q); + newSearch(q); + + return(false); +} + +function doDelete(lst) { + var children = '0'; + if (document.getElementById('del_children') && document.getElementById('del_children').checked) + children = '1'; + $.ajax({ + type: "POST", + url: "../prod/delete/", + dataType: 'json', + data: { + lst: lst.join(';'), + del_children: children + }, + success: function (data) { + + $.each(data, function (i, n) { + var imgt = $('#IMGT_' + n), + chim = $('.CHIM_' + n), + stories = $('.STORY_' + n); + $('.doc_infos', imgt).remove(); + imgt.unbind("click").removeAttr("ondblclick").removeClass("selected").removeClass("IMGT").find("img").unbind(); + + if (imgt.data("ui-draggable")) { + imgt.draggable("destroy"); + } + + imgt.find(".thumb img").attr("src", "/assets/common/images/icons/deleted.png").css({ + width: '100%', + height: 'auto', + margin: '0 10px', + top: '0' + }); + chim.parent().slideUp().remove(); + imgt.find(".status,.title,.bottom").empty(); + + p4.Results.Selection.remove(n); + if (stories.length > 0) { + p4.WorkZone.refresh(); + } + else { + p4.WorkZone.Selection.remove(n); + } + }); + viewNbSelect(); + } + }); +} + +function archiveBasket(basket_id) { + $.ajax({ + type: "POST", + url: "../prod/baskets/" + basket_id + "/archive/?archive=1", + dataType: 'json', + beforeSend: function () { + + }, + success: function (data) { + if (data.success) { + var basket = $('#SSTT_' + basket_id); + var next = basket.next(); + + if (next.data("ui-droppable")) { + next.droppable('destroy'); + } + + next.slideUp().remove(); + + if (basket.data("ui-droppable")) { + basket.droppable('destroy'); + } + + basket.slideUp().remove(); + + if ($('#baskets .SSTT').length === 0) { + return p4.WorkZone.refresh(false); + } + } + else { + alert(data.message); + } + return; + } + }); +} + + +function deleteBasket(item) { + if ($("#DIALOG").data("ui-dialog")) { + $("#DIALOG").dialog('destroy'); + } + + var k = $(item).attr('id').split('_').slice(1, 2).pop(); // id de chutier + $.ajax({ + type: "POST", + url: "../prod/baskets/" + k + '/delete/', + dataType: 'json', + beforeSend: function () { + + }, + success: function (data) { + if (data.success) { + var basket = $('#SSTT_' + k); + var next = basket.next(); + + if (next.data("ui-droppable")) { + next.droppable('destroy'); + } + + next.slideUp().remove(); + + if (basket.data("ui-droppable")) { + basket.droppable('destroy'); + } + + basket.slideUp().remove(); + + if ($('#baskets .SSTT').length === 0) { + return p4.WorkZone.refresh(false); + } + } + else { + alert(data.message); + } + return; + } + }); +} + +function deploy(deployer, todeploy_selector) +{ + if($(deployer).hasClass("deployer_opened")) { + $(deployer).removeClass("deployer_opened").addClass("deployer_closed"); + $(todeploy_selector).hide(); + } + else { + $(deployer).removeClass("deployer_closed").addClass("deployer_opened"); + $(todeploy_selector).show(); + } +} + +function clksbas(el, sbas_id) { + var bool = $(el).prop('checked'); + $.each($('.sbascont_' + sbas_id + ' :checkbox'), function () { + this.checked = bool; + }); + + checkFilters(true); +} + + +function advSearch(event) { + event.cancelBubble = true; + // alternateSearch(false); + $('#idFrameC .tabs a.adv_search').trigger('click'); +} + +function start_page_selector() { + var el = $('#look_box_settings select[name=start_page]'); + + switch (el.val()) { + case "LAST_QUERY": + case "PUBLI": + case "HELP": + $('#look_box_settings input[name=start_page_value]').hide(); + break; + case "QUERY": + $('#look_box_settings input[name=start_page_value]').show(); + break; + } +} + +function set_start_page() { + var el = $('#look_box_settings select[name=start_page]'); + var val = el.val(); + + + var start_page_query = $('#look_box_settings input[name=start_page_value]').val(); + + if (val === 'QUERY') { + setPref('start_page_query', start_page_query); + } + + setPref('start_page', val); + +} + +function basketPrefs() { + $('#basket_preferences').dialog({ + closeOnEscape: true, + resizable: false, + width: 450, + height: 500, + modal: true, + draggable: false, + overlay: { + backgroundColor: '#000', + opacity: 0.7 + } + }).dialog('open'); +} + +function lookBox(el, event) { + $("#look_box").dialog({ + closeOnEscape: true, + resizable: false, + width: 450, + height: 500, + modal: true, + draggable: false, + overlay: { + backgroundColor: '#000', + opacity: 0.7 + } + }).dialog('open'); +} + +function showAnswer(p) { + var o; + if (p === 'Results') { + // on montre les results + if (o = document.getElementById("AnswerExplain")) + o.style.visibility = "hidden"; + if (o = document.getElementById("AnswerResults")) { + o.style.visibility = ""; + o.style.display = "block"; + } + // on montre explain + if (document.getElementById("divpage")) + document.getElementById("divpage").style.visibility = visibilityDivPage; + + if (document.getElementById("explainResults")) + document.getElementById("explainResults").style.display = "none"; + } + else { + // on montre explain + if (document.getElementById("divpage")) { + visibilityDivPage = "visible"; + document.getElementById("divpage").style.visibility = "hidden"; + } + if (document.getElementById("explainResults")) + document.getElementById("explainResults").style.display = "block"; + + if (o = document.getElementById("AnswerResults")) { + o.style.visibility = "hidden"; + o.style.display = "none"; + + } + if (o = document.getElementById("AnswerExplain")) + o.style.visibility = ""; + if (o = document.getElementById("AnswerExplain")) { + o.style.display = "none"; + setTimeout('document.getElementById("AnswerExplain").style.display = "block";', 200); + } + } +} + + +/** FROM INDEX.php **/ +function saveeditPbar(idesc, ndesc) { + document.getElementById("saveeditPbarI").innerHTML = idesc; + document.getElementById("saveeditPbarN").innerHTML = ndesc; +} + +function getSelText() { + var txt = ''; + if (window.getSelection) { + txt = window.getSelection(); + } + else if (document.getSelection) { + txt = document.getSelection(); + } + else if (document.selection) { + txt = document.selection.createRange().text; + } + else + return; + return txt; +} + +function getWinPosAsXML() { + var ret = ''; + + if ($('#idFrameE').is(':visible') && $('#EDITWINDOW').is(':visible')) + ret += ''; + + + return ret; +} + +function saveWindows() { + var key = ''; + var value = ''; + + + if ($('#idFrameE').is(':visible') && $('#EDITWINDOW').is(':visible')) { + key = 'edit_window'; + value = $('#idFrameE').outerWidth() / $('#EDITWINDOW').innerWidth(); + } + else { + key = 'search_window'; + value = $('#idFrameC').outerWidth() / bodySize.x; + } + setPref(key, value); +} + +function gotopage(pag) { + $('#searchForm input[name="sel"]').val(p4.Results.Selection.serialize()); + $('#formAnswerPage').val(pag); + $('#searchForm').submit(); +} + +function addFilterMulti(filter, link, sbasid) { + var clone = $('#filter_multi_' + sbasid + '_' + filter); + var orig = clone; + if (!$('#filter_multi_' + sbasid + '_' + filter).is(':visible')) { + clone = orig.clone(true); + var par = orig.parent(); + orig.remove(); + par.append(clone); + clone.slideDown('fast', function () { + $(this); + }); + $(link).addClass('filterActive'); + } + else { + clone.slideUp(); + $(link).removeClass('filterActive'); + } + return false; +} + +function autoorder() { + var val = $.trim($('#auto_order').val()); + + if (val === '') + return; + + var sorter = new Array(); + + $('#reorder_box .diapo form').each(function (i, n) { + + var id = $('input[name=id]', n).val(); + + switch (val) { + case 'title': + default: + var data = $('input[name=title]', n).val(); + break; + case 'default': + var data = $('input[name=default]', n).val(); + break; + } + + sorter[id] = data; + }); + + var data_type = 'string'; + + switch (val) { + case 'default': + var data_type = 'integer'; + break; + } + + sorter = arraySortByValue(sorter, data_type); + + var last_moved = false; + + for (i in sorter) { + var elem = $('#ORDER_' + i); + if (last_moved) { + elem.insertAfter(last_moved); + } + else { + $('#reorder_box').prepend(elem); + } + last_moved = elem; + } + +} + + + + +//clear search +$(document).ready(function () { + + $('#thesaurus_tab .input-medium').on('keyup', function(){ + if($('#thesaurus_tab .input-medium').val() != ''){ + $('#thesaurus_tab .th_clear').show(); + }else{ + $('#thesaurus_tab .th_clear').hide(); + } + }); + + $('.th_clear').on('click', function(){ + $('#thesaurus_tab .input-medium').val(''); + $('#thesaurus_tab .gform').submit(); + $('#thesaurus_tab .th_clear').hide(); + }); + + $('.treeview>li.expandable>.hitarea').on('click', function(){ + if($(this).css('background-position') == '99% 22px'){ + $(this).css('background-position', '99% -28px'); + $(this).addClass('active'); + }else{ + $(this).css('background-position', '99% 22px'); + $(this).removeClass('active'); + } + }); + +}); diff --git a/resources/www/prod/skins/ui-components/_workzone.scss b/resources/www/prod/skins/ui-components/_workzone.scss new file mode 100644 index 0000000000..36c0f8e750 --- /dev/null +++ b/resources/www/prod/skins/ui-components/_workzone.scss @@ -0,0 +1,196 @@ +$workzoneBackgroundColor: $darkBackgroundColor !default; //$mediumBackgroundColor !default; +$workzoneTopBorder: none !default; +$workzoneTabTopBorder: 1px solid $darkBorderColor !default; +$workzoneBorderTopColor: $mediumBorderColor !default; +$tabHeight: 86px !default; +$subTabHeight: 46px !default; + + +$workzoneTabContentBackgroundColor: $workzoneBackgroundColor !default; + +$workzoneTabBackgroundColor: $workzoneBackgroundColor !default; +$workzoneTabTextColor: $mediumTextColor !default; + +$workzoneTabActiveBackgroundColor: $tabContentBackgroundColor !default; +$workzoneTabActiveTextColor: $lightTextColor !default; + +$workzoneTabDisabledBackgroundColor: $tabBackgroundColor !default; +$workzoneTabDisabledTextColor: $mediumTextActiveColor !default; + + +/** + * Workzone + */ +#idFrameC { + top: 0 !important; + min-width: 360px; + bottom: 0 !important; + &.closed { + min-width: 0; + } + #retractableButton { + cursor: pointer; + width: 70px; + height: 85px; + float: right; + text-align: center; + line-height: 85px; + margin-bottom: -20px; + i { + font-size: 23px; + color: $mediumTextColor; + } + } + .wrapper { + background-color: $workzoneBackgroundColor; + right: 10px; + border-top: $workzoneTopBorder; //$workzoneBorderTop; + } + + .ui-tabs { + position: absolute; + top: 0px; + left: 0px; + bottom: 0px; + right: 0; + margin: 0; + padding: 0; + .ui-tabs-nav { + background-color: $workzoneTabContentBackgroundColor; + top: 0; + left: 10px; + right: 10px; + //margin-top: 21px; + // border-top: 1px solid $workzoneTabTopBorder; + border-radius: 0; + height: $subTabHeight; + border-bottom: 1px solid $workzoneTabBorderBottom; + box-sizing: border-box; + li { + width: auto; + height: $tabHeight; + display: inline-block; + background-color: $workzoneTabBackgroundColor; + z-index: 10; + border-radius: 0; + margin: 0; + box-sizing: border-box; + &.proposals_WZ { + &.ui-state-active { + a { + border-bottom: 3px solid $proposalColor; + } + } + &.active { + img.proposals_off { + display: none; + } + } + img.proposals_on { + display: none; + } + } + + /*&.proposals_WZ.ui-state-active a { + border-bottom: 3px solid #4c5d84; + }*/ + &.thesaurus.ui-state-active a { + border-bottom: 3px solid $thesaurusColor; + } + &.baskets.ui-state-active a { + border-bottom: 3px solid $basketsColor; + } + &.plugins.ui-state-active a { + border-bottom: 3px solid $pluginsColor; + } + + + a { + padding: 0; + margin: 0; + border-radius: 0; + &.escamote { + margin: 25px 25px 0 0; + } + } + &:hover { + a { + background-color: $workzoneTabBgHover; + border-bottom: 3px solid $workzoneTabBgHover; + } + } + &.ui-state-active { + a { + background-color: $workzoneTabBgActive; + border-bottom: 1px solid $thesaurusColor; + // height: 82px; + } + } + } + } + .ui-tabs-panel { + position: absolute; + top: 56px; + left: 0; + bottom: 0; + right: 0; + } + + } + ul.icon-menu { + width: 100%; + } + .icon-menu { + .WZtabs, .WZplugins { + display: block; + width: 70px; + height: 82px; + line-height: 82px; + vertical-align: middle; + text-align: center; + } + .WZbasketTab { + display: block; + background-image: url('#{$iconsPath}workzone32.png'); + background-repeat: no-repeat; + background-position: 9px 25px; + width: 70px; + height: 82px; + } + } + .closed { + .icon-menu li { + clear: left; + } + } + .ui-tabs-panel, + .ui-resizable-handle { + display: none; + } + .tools { + padding: 7px 0 7px 0; + text-align: left !important; + button { + background-color: transparent; + border: none; + width: 16px; + height: 22px; + cursor: pointer; + padding: 0; + } + label { + display: inline; + margin: 0 15px 0 0; + float: left; + font-size: $smallFontSize; + color: $workzoneToolsLabelColor; + line-height: 22px; + vertical-align: middle; + } + } +} + +.alert_datas_changed a { + color: #404040; + text-decoration: underline; +} diff --git a/templates/web/admin/collection/collection.html.twig b/templates/web/admin/collection/collection.html.twig index a7b2f747a3..72d5eff89e 100644 --- a/templates/web/admin/collection/collection.html.twig +++ b/templates/web/admin/collection/collection.html.twig @@ -35,7 +35,7 @@
  • {{ collection.get_record_amount() }} records {{ 'phraseanet:: details' | trans }}
  • -{% if app.getAclForUser(app.getAuthenticatedUser()).has_right_on_base(bas_id, 'manage') %} +{% if app.getAclForUser(app.getAuthenticatedUser()).has_right_on_base(bas_id, constant('\\ACL::COLL_MANAGE')) %}
    {{ 'admin::collection:: Gestionnaires des commandes' | trans }}
    @@ -144,7 +144,7 @@
    {{ 'admin::base:collection: minilogo actuel' | trans }}
    {% if collection.getLogo(bas_id, app) is not empty %}
    {{ collection.getLogo(bas_id, app) | raw }}
    - {% if app.getAclForUser(app.getAuthenticatedUser()).has_right_on_base(bas_id, 'manage') %} + {% if app.getAclForUser(app.getAuthenticatedUser()).has_right_on_base(bas_id, constant('\\ACL::COLL_MANAGE')) %}
    {% endif%} - {% elseif app.getAclForUser(app.getAuthenticatedUser()).has_right_on_base(bas_id, 'manage') %} + {% elseif app.getAclForUser(app.getAuthenticatedUser()).has_right_on_base(bas_id, constant('\\ACL::COLL_MANAGE')) %} {{ 'admin::base:collection: aucun fichier (minilogo, watermark ...)' | trans }}
    @@ -169,7 +169,7 @@
    {{ "Watermark" | trans }}
    {% if collection.getWatermark(bas_id) is not empty %}
    {{ collection.getWatermark(bas_id)| raw }}
    - {% if app.getAclForUser(app.getAuthenticatedUser()).has_right_on_base(bas_id, 'manage') %} + {% if app.getAclForUser(app.getAuthenticatedUser()).has_right_on_base(bas_id, constant('\\ACL::COLL_MANAGE')) %} {% endif%} - {% elseif app.getAclForUser(app.getAuthenticatedUser()).has_right_on_base(bas_id, 'manage') %} + {% elseif app.getAclForUser(app.getAuthenticatedUser()).has_right_on_base(bas_id, constant('\\ACL::COLL_MANAGE')) %} {{ 'admin::base:collection: aucun fichier (minilogo, watermark ...)' | trans }}
    @@ -194,7 +194,7 @@
    {{ "Stamp logo" | trans }}
    {% if collection.getStamp(bas_id) is not empty %}
    {{ collection.getStamp(bas_id)| raw }}
    - {% if app.getAclForUser(app.getAuthenticatedUser()).has_right_on_base(bas_id, 'manage') %} + {% if app.getAclForUser(app.getAuthenticatedUser()).has_right_on_base(bas_id, constant('\\ACL::COLL_MANAGE')) %} {% endif%} - {% elseif app.getAclForUser(app.getAuthenticatedUser()).has_right_on_base(bas_id, 'manage') %} + {% elseif app.getAclForUser(app.getAuthenticatedUser()).has_right_on_base(bas_id, constant('\\ACL::COLL_MANAGE')) %} {{ 'admin::base:collection: aucun fichier (minilogo, watermark ...)' | trans }}
    diff --git a/templates/web/admin/collection/create.html.twig b/templates/web/admin/collection/create.html.twig index 36cdca68b0..26c0039feb 100644 --- a/templates/web/admin/collection/create.html.twig +++ b/templates/web/admin/collection/create.html.twig @@ -32,10 +32,10 @@
    - {% if app.getAclForUser(app.getAuthenticatedUser()).get_granted_base(["canadmin"]) | length > 0 %} + {% if app.getAclForUser(app.getAuthenticatedUser()).get_granted_base([constant('\\ACL::CANADMIN')]) | length > 0 %} diff --git a/templates/web/admin/dashboard.html.twig b/templates/web/admin/dashboard.html.twig index 2242d18c17..2018626663 100644 --- a/templates/web/admin/dashboard.html.twig +++ b/templates/web/admin/dashboard.html.twig @@ -7,11 +7,11 @@
  • {{ requirement.getTestMessage }} -

    {% if not requirement.isFulfilled() %} +

    {{ requirement.getHelpHtml() | raw }} - {% endif %}

    + {% endif %}
  • {% endfor %} {% endif %} diff --git a/templates/web/admin/databox/databox.html.twig b/templates/web/admin/databox/databox.html.twig index 9182ac6787..04273a27c3 100644 --- a/templates/web/admin/databox/databox.html.twig +++ b/templates/web/admin/databox/databox.html.twig @@ -30,7 +30,7 @@
  • {{ 'admin::base: Alias' | trans }} : {{ databox.get_label(app['locale']) }} - {% if app.getAclForUser(app.getAuthenticatedUser()).has_right_on_sbas(databox.get_sbas_id(), "bas_manage") %} + {% if app.getAclForUser(app.getAuthenticatedUser()).has_right_on_sbas(databox.get_sbas_id(), constant('\\ACL::BAS_MANAGE')) %}
  • -{% if app.getAclForUser(app.getAuthenticatedUser()).has_right_on_sbas(databox.get_sbas_id(), "bas_manage") %} +{% if app.getAclForUser(app.getAuthenticatedUser()).has_right_on_sbas(databox.get_sbas_id(), constant('\\ACL::BAS_MANAGE')) %}
    - {{_self.format_checkbox(app.getAuthenticatedUser(), rights, 'bas_chupub', users, 'sbas')}} + {{_self.format_checkbox(app.getAuthenticatedUser(), rights, constant('\\ACL::BAS_CHUPUB'), users, 'sbas')}} - {{_self.format_checkbox(app.getAuthenticatedUser(), rights, 'bas_modif_th', users, 'sbas')}} + {{_self.format_checkbox(app.getAuthenticatedUser(), rights, constant('\\ACL::BAS_MODIF_TH'), users, 'sbas')}} - {{_self.format_checkbox(app.getAuthenticatedUser(), rights, 'bas_manage', users, 'sbas')}} + {{_self.format_checkbox(app.getAuthenticatedUser(), rights, constant('\\ACL::BAS_MANAGE'), users, 'sbas')}} - {{_self.format_checkbox(app.getAuthenticatedUser(), rights, 'bas_modify_struct', users, 'sbas')}} + {{_self.format_checkbox(app.getAuthenticatedUser(), rights, constant('\\ACL::BAS_MODIFY_STRUCT'), users, 'sbas')}} @@ -341,29 +340,29 @@ {{rights['base_id']|bas_labels(app)}} - {{_self.format_checkbox(app.getAuthenticatedUser(), rights, 'access', users, 'base')}} + {{_self.format_checkbox(app.getAuthenticatedUser(), rights, constant('\\ACL::ACCESS'), users, 'base')}} - {{_self.format_checkbox(app.getAuthenticatedUser(), rights, 'actif', users, 'base')}} + {{_self.format_checkbox(app.getAuthenticatedUser(), rights, constant('\\ACL::ACTIF'), users, 'base')}} - {{_self.format_checkbox(app.getAuthenticatedUser(), rights, 'canputinalbum', users, 'base')}} + {{_self.format_checkbox(app.getAuthenticatedUser(), rights, constant('\\ACL::CANPUTINALBUM'), users, 'base')}} - {{_self.format_checkbox(app.getAuthenticatedUser(), rights, 'candwnldpreview', users, 'base')}} + {{_self.format_checkbox(app.getAuthenticatedUser(), rights, constant('\\ACL::CANDWNLDPREVIEW'), users, 'base')}} - {{_self.format_checkbox(app.getAuthenticatedUser(), rights, 'nowatermark', users, 'base')}} + {{_self.format_checkbox(app.getAuthenticatedUser(), rights, constant('\\ACL::NOWATERMARK'), users, 'base')}} - {{_self.format_checkbox(app.getAuthenticatedUser(), rights, 'candwnldhd', users, 'base')}} + {{_self.format_checkbox(app.getAuthenticatedUser(), rights, constant('\\ACL::CANDWNLDHD'), users, 'base')}} - {{_self.format_checkbox(app.getAuthenticatedUser(), rights, 'cancmd', users, 'base')}} + {{_self.format_checkbox(app.getAuthenticatedUser(), rights, constant('\\ACL::CANCMD'), users, 'base')}}
    - {% if rights['restrict_dwnld'] > 0 %} + {% if rights[constant('\\ACL::RESTRICT_DWNLD')] > 0 %} {% else %} @@ -395,34 +394,34 @@ - {{_self.format_checkbox(app.getAuthenticatedUser(), rights, 'canaddrecord', users, 'base')}} + {{_self.format_checkbox(app.getAuthenticatedUser(), rights, constant('\\ACL::CANADDRECORD'), users, 'base')}} - {{_self.format_checkbox(app.getAuthenticatedUser(), rights, 'canmodifrecord', users, 'base')}} + {{_self.format_checkbox(app.getAuthenticatedUser(), rights, constant('\\ACL::CANMODIFRECORD'), users, 'base')}} - {{_self.format_checkbox(app.getAuthenticatedUser(), rights, 'chgstatus', users, 'base')}} + {{_self.format_checkbox(app.getAuthenticatedUser(), rights, constant('\\ACL::CHGSTATUS'), users, 'base')}} - {{_self.format_checkbox(app.getAuthenticatedUser(), rights, 'candeleterecord', users, 'base')}} + {{_self.format_checkbox(app.getAuthenticatedUser(), rights, constant('\\ACL::CANDELETERECORD'), users, 'base')}} - {{_self.format_checkbox(app.getAuthenticatedUser(), rights, 'imgtools', users, 'base')}} + {{_self.format_checkbox(app.getAuthenticatedUser(), rights, constant('\\ACL::IMGTOOLS'), users, 'base')}} - {{_self.format_checkbox(app.getAuthenticatedUser(), rights, 'canadmin', users, 'base')}} + {{_self.format_checkbox(app.getAuthenticatedUser(), rights, constant('\\ACL::CANADMIN'), users, 'base')}} - {{_self.format_checkbox(app.getAuthenticatedUser(), rights, 'canreport', users, 'base')}} + {{_self.format_checkbox(app.getAuthenticatedUser(), rights, constant('\\ACL::CANREPORT'), users, 'base')}} - {{_self.format_checkbox(app.getAuthenticatedUser(), rights, 'canpush', users, 'base')}} + {{_self.format_checkbox(app.getAuthenticatedUser(), rights, constant('\\ACL::CANPUSH'), users, 'base')}} - {{_self.format_checkbox(app.getAuthenticatedUser(), rights, 'manage', users, 'base')}} + {{_self.format_checkbox(app.getAuthenticatedUser(), rights, constant('\\ACL::COLL_MANAGE'), users, 'base')}} - {{_self.format_checkbox(app.getAuthenticatedUser(), rights, 'modify_struct', users, 'base')}} + {{_self.format_checkbox(app.getAuthenticatedUser(), rights, constant('\\ACL::COLL_MODIFY_STRUCT'), users, 'base')}} diff --git a/templates/web/admin/editusers_quotas.html.twig b/templates/web/admin/editusers_quotas.html.twig index 537e7baaae..75fcea933a 100644 --- a/templates/web/admin/editusers_quotas.html.twig +++ b/templates/web/admin/editusers_quotas.html.twig @@ -5,8 +5,8 @@ {% for usr_id, data in datas %} {% if restrict == -1 %} - {% set restrict = data['restrict_dwnld'] %} - {% elseif restrict != data['restrict_dwnld'] %} + {% set restrict = data[constant('\\ACL::RESTRICT_DWNLD')] %} + {% elseif restrict != data[constant('\\ACL::RESTRICT_DWNLD')] %} {% set restrict = 2 %} {% endif %} diff --git a/templates/web/admin/fields/index.html.twig b/templates/web/admin/fields/index.html.twig index f9c71746ad..e8198a324f 100644 --- a/templates/web/admin/fields/index.html.twig +++ b/templates/web/admin/fields/index.html.twig @@ -1,5 +1,10 @@
    {# sbas_id is saved in the dom and used to fetch right models and collections #} +
    + × + {% trans %}Danger zone !{% endtrans %}
    + {% trans %}See documentation about structure manipulation.{% endtrans %} +
    diff --git a/templates/web/admin/publications/fiche.html.twig b/templates/web/admin/publications/fiche.html.twig index d53d912280..a211daaef1 100644 --- a/templates/web/admin/publications/fiche.html.twig +++ b/templates/web/admin/publications/fiche.html.twig @@ -106,7 +106,7 @@
    - {% for databox in app.getAclForUser(app.getAuthenticatedUser()).get_granted_sbas('bas_chupub') %} + {% for databox in app.getAclForUser(app.getAuthenticatedUser()).get_granted_sbas([constant('\\ACL::BAS_CHUPUB')]) %} {% for collection in databox.get_collections() %} diff --git a/templates/web/admin/tree.html.twig b/templates/web/admin/tree.html.twig index 259ec05c4c..ecad1411c4 100644 --- a/templates/web/admin/tree.html.twig +++ b/templates/web/admin/tree.html.twig @@ -36,7 +36,7 @@ - {% if app.getAclForUser(app.getAuthenticatedUser()).has_right('manageusers') %} + {% if app.getAclForUser(app.getAuthenticatedUser()).has_right(constant('\\ACL::CANADMIN')) %}
  • @@ -51,7 +51,7 @@
  • {% endif %} - {% if app.getAclForUser(app.getAuthenticatedUser()).has_right('bas_chupub') %} + {% if app.getAclForUser(app.getAuthenticatedUser()).has_right(constant('\\ACL::BAS_CHUPUB')) %}
  • @@ -60,7 +60,7 @@
  • {% endif %} - {% if app.getAclForUser(app.getAuthenticatedUser()).has_right('taskmanager') %} + {% if app.getAclForUser(app.getAuthenticatedUser()).has_right(constant('\\ACL::TASKMANAGER')) %}
  • @@ -110,7 +110,7 @@
  • - {% elseif acl.has_right('push') %} + {% elseif acl.has_right(constant('\\ACL::CANPUSH')) %}
    - {% elseif acl.has_right('bas_chupub') %} + {% elseif acl.has_right(constant('\\ACL::BAS_CHUPUB')) %}
    {% endif %} - {% if acl.has_right('deleterecord') %} + {% if acl.has_right(constant('\\ACL::CANDELETERECORD')) %}