mirror of
https://github.com/alchemy-fr/Phraseanet.git
synced 2025-10-18 15:33:15 +00:00
Refactor status display
This commit is contained in:
@@ -114,6 +114,7 @@ use Alchemy\Phrasea\Core\Provider\RepositoriesServiceProvider;
|
||||
use Alchemy\Phrasea\Core\Provider\SearchEngineServiceProvider;
|
||||
use Alchemy\Phrasea\Core\Provider\SerializerServiceProvider;
|
||||
use Alchemy\Phrasea\Core\Provider\SessionHandlerServiceProvider;
|
||||
use Alchemy\Phrasea\Core\Provider\StatusServiceProvider;
|
||||
use Alchemy\Phrasea\Core\Provider\SubdefServiceProvider;
|
||||
use Alchemy\Phrasea\Core\Provider\TasksServiceProvider;
|
||||
use Alchemy\Phrasea\Core\Provider\TemporaryFilesystemServiceProvider;
|
||||
@@ -237,7 +238,7 @@ class Application extends SilexApplication
|
||||
$this->register(new FeedServiceProvider());
|
||||
$this->register(new FtpServiceProvider());
|
||||
$this->register(new GeonamesServiceProvider());
|
||||
|
||||
$this->register(new StatusServiceProvider());
|
||||
$this['geonames.server-uri'] = $this->share(function (Application $app) {
|
||||
return $app['conf']->get(['registry', 'webservices', 'geonames-server'], 'http://geonames.alchemyasp.com/');
|
||||
});
|
||||
|
@@ -263,7 +263,7 @@ class Root implements ControllerProviderInterface
|
||||
|
||||
$databox = $app['phraseanet.appbox']->get_databox($databox_id);
|
||||
|
||||
$status = $databox->get_statusbits();
|
||||
$statusStructure = $databox->getStatusStructure();
|
||||
|
||||
switch ($errorMsg = $request->query->get('error')) {
|
||||
case 'rights':
|
||||
@@ -283,8 +283,8 @@ class Root implements ControllerProviderInterface
|
||||
break;
|
||||
}
|
||||
|
||||
if (isset($status[$bit])) {
|
||||
$status = $status[$bit];
|
||||
if ($statusStructure->hasStatus($bit)) {
|
||||
$status = $statusStructure->getStatus($bit);
|
||||
} else {
|
||||
$status = [
|
||||
"labeloff" => '',
|
||||
@@ -320,10 +320,12 @@ class Root implements ControllerProviderInterface
|
||||
$app->abort(403);
|
||||
}
|
||||
|
||||
$databox = $app['phraseanet.appbox']->get_databox($databox_id);
|
||||
|
||||
$error = false;
|
||||
|
||||
try {
|
||||
\databox_status::deleteStatus($app, $app['phraseanet.appbox']->get_databox($databox_id), $bit);
|
||||
$app['status.provider']->deleteStatus($databox->getStatusStructure(), $bit);
|
||||
} catch (\Exception $e) {
|
||||
$error = true;
|
||||
}
|
||||
@@ -349,7 +351,9 @@ class Root implements ControllerProviderInterface
|
||||
'labels_off' => $request->request->get('labels_off', []),
|
||||
];
|
||||
|
||||
\databox_status::updateStatus($app, $databox_id, $bit, $properties);
|
||||
$databox = $app['phraseanet.appbox']->get_databox($databox_id);
|
||||
|
||||
$app['status.provider']->updateStatus($databox->getStatusStructure(), $bit, $properties);
|
||||
|
||||
if (null !== $request->request->get('delete_icon_off')) {
|
||||
\databox_status::deleteIcon($app, $databox_id, $bit, 'off');
|
||||
|
@@ -11,6 +11,7 @@
|
||||
|
||||
namespace Alchemy\Phrasea\Controller\Api;
|
||||
|
||||
use Alchemy\Phrasea\Status\StatusStructure;
|
||||
use Silex\ControllerProviderInterface;
|
||||
use Alchemy\Phrasea\Cache\Cache as CacheInterface;
|
||||
use Alchemy\Phrasea\Core\PhraseaEvents;
|
||||
@@ -437,7 +438,7 @@ class V1 implements ControllerProviderInterface
|
||||
*/
|
||||
public function get_databox_status(Application $app, Request $request, $databox_id)
|
||||
{
|
||||
$ret = ["status" => $this->list_databox_status($app['phraseanet.appbox']->get_databox($databox_id)->get_statusbits())];
|
||||
$ret = ["status" => $this->list_databox_status($app['phraseanet.appbox']->get_databox($databox_id)->getStatusStructure())];
|
||||
|
||||
return Result::create($request, $ret)->createResponse();
|
||||
}
|
||||
@@ -757,7 +758,7 @@ class V1 implements ControllerProviderInterface
|
||||
{
|
||||
$record = $app['phraseanet.appbox']->get_databox($databox_id)->get_record($record_id);
|
||||
|
||||
$ret = ["status" => $this->list_record_status($app['phraseanet.appbox']->get_databox($databox_id), $record->get_status())];
|
||||
$ret = ["status" => $this->list_record_status($record)];
|
||||
|
||||
return Result::create($request, $ret)->createResponse();
|
||||
}
|
||||
@@ -836,7 +837,7 @@ class V1 implements ControllerProviderInterface
|
||||
{
|
||||
$databox = $app['phraseanet.appbox']->get_databox($databox_id);
|
||||
$record = $databox->get_record($record_id);
|
||||
$status_bits = $databox->get_statusbits();
|
||||
$statusStructure = $databox->getStatusStructure();
|
||||
|
||||
$status = $request->get('status');
|
||||
|
||||
@@ -852,7 +853,7 @@ class V1 implements ControllerProviderInterface
|
||||
if (!in_array($value, ['0', '1'])) {
|
||||
return $this->getBadRequest($app, $request);
|
||||
}
|
||||
if (!isset($status_bits[$n])) {
|
||||
if (!$statusStructure->hasStatus($n)) {
|
||||
return $this->getBadRequest($app, $request);
|
||||
}
|
||||
|
||||
@@ -861,7 +862,7 @@ class V1 implements ControllerProviderInterface
|
||||
|
||||
$record->set_binary_status(strrev($datas));
|
||||
|
||||
$ret = ["status" => $this->list_record_status($databox, $record->get_status())];
|
||||
$ret = ["status" => $this->list_record_status($record)];
|
||||
|
||||
return Result::create($request, $ret)->createResponse();
|
||||
}
|
||||
@@ -1304,13 +1305,11 @@ class V1 implements ControllerProviderInterface
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function list_record_status(\databox $databox, $status)
|
||||
private function list_record_status(\record_adapter $record)
|
||||
{
|
||||
$status = strrev($status);
|
||||
|
||||
$ret = [];
|
||||
foreach ($databox->get_statusbits() as $bit => $status_datas) {
|
||||
$ret[] = ['bit' => $bit, 'state' => !!substr($status, ($bit - 1), 1)];
|
||||
foreach ($record->getStatusStructure() as $bit => $status) {
|
||||
$ret[] = ['bit' => $bit, 'state' => \databox_status::bitIsSet($record->getStatusBitField(), $bit)];
|
||||
}
|
||||
|
||||
return $ret;
|
||||
@@ -1502,11 +1501,25 @@ class V1 implements ControllerProviderInterface
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function list_databox_status(array $status)
|
||||
private function list_databox_status(StatusStructure $statusStructure)
|
||||
{
|
||||
$ret = [];
|
||||
foreach ($status as $n => $datas) {
|
||||
$ret[] = ['bit' => $n, 'label_on' => $datas['labelon'], 'label_off' => $datas['labeloff'], 'labels' => ['en' => $datas['labels_on_i18n']['en'], 'fr' => $datas['labels_on_i18n']['fr'], 'de' => $datas['labels_on_i18n']['de'], 'nl' => $datas['labels_on_i18n']['nl'],], 'img_on' => $datas['img_on'], 'img_off' => $datas['img_off'], 'searchable' => !!$datas['searchable'], 'printable' => !!$datas['printable'],];
|
||||
foreach ($statusStructure as $bit => $status) {
|
||||
$ret[] = [
|
||||
'bit' => $bit,
|
||||
'label_on' => $status['labelon'],
|
||||
'label_off' => $status['labeloff'],
|
||||
'labels' => [
|
||||
'en' => $status['labels_on_i18n']['en'],
|
||||
'fr' => $status['labels_on_i18n']['fr'],
|
||||
'de' => $status['labels_on_i18n']['de'],
|
||||
'nl' => $status['labels_on_i18n']['nl'],
|
||||
],
|
||||
'img_on' => $status['img_on'],
|
||||
'img_off' => $status['img_off'],
|
||||
'searchable' => (bool) $status['searchable'],
|
||||
'printable' => (bool) $status['printable'],
|
||||
];
|
||||
}
|
||||
|
||||
return $ret;
|
||||
|
@@ -39,8 +39,7 @@ class Edit implements ControllerProviderInterface
|
||||
$records = RecordsRequest::fromRequest($app, $request, RecordsRequest::FLATTEN_YES_PRESERVE_STORIES, ['canmodifrecord']);
|
||||
|
||||
$thesaurus = false;
|
||||
$status = $ids = $elements = $suggValues =
|
||||
$fields = $JSFields = [];
|
||||
$status = $ids = $elements = $suggValues = $fields = $JSFields = [];
|
||||
$databox = null;
|
||||
|
||||
$multipleDataboxes = count($records->databoxes()) > 1;
|
||||
@@ -120,16 +119,16 @@ class Edit implements ControllerProviderInterface
|
||||
* generate javascript status
|
||||
*/
|
||||
if ($app['acl']->get($app['authentication']->getUser())->has_right('changestatus')) {
|
||||
$dbstatus = \databox_status::getDisplayStatus($app);
|
||||
if (isset($dbstatus[$databox->get_sbas_id()])) {
|
||||
foreach ($dbstatus[$databox->get_sbas_id()] as $n => $statbit) {
|
||||
$status[$n] = [];
|
||||
$status[$n]['label0'] = $statbit['labels_off_i18n'][$app['locale']];
|
||||
$status[$n]['label1'] = $statbit['labels_on_i18n'][$app['locale']];
|
||||
$status[$n]['img_off'] = $statbit['img_off'];
|
||||
$status[$n]['img_on'] = $statbit['img_on'];
|
||||
$status[$n]['_value'] = 0;
|
||||
}
|
||||
$statusStructure = $databox->getStatusStructure();
|
||||
foreach ($statusStructure as $statbit) {
|
||||
$bit = $statbit['bit'];
|
||||
|
||||
$status[$bit] = [];
|
||||
$status[$bit]['label0'] = $statbit['labels_off_i18n'][$app['locale']];
|
||||
$status[$bit]['label1'] = $statbit['labels_on_i18n'][$app['locale']];
|
||||
$status[$bit]['img_off'] = $statbit['img_off'];
|
||||
$status[$bit]['img_on'] = $statbit['img_on'];
|
||||
$status[$bit]['_value'] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -64,49 +64,42 @@ class Property implements ControllerProviderInterface
|
||||
}
|
||||
|
||||
$records = RecordsRequest::fromRequest($app, $request, false, ['chgstatus']);
|
||||
$databoxStatus = \databox_status::getDisplayStatus($app);
|
||||
$statusBit = $nRec = [];
|
||||
|
||||
foreach ($records as $record) {
|
||||
//perform logic
|
||||
$sbasId = $record->get_databox()->get_sbas_id();
|
||||
|
||||
if (!isset($nRec[$sbasId])) {
|
||||
$nRec[$sbasId] = ['stories' => 0, 'records' => 0];
|
||||
if (count($records->databoxes()) > 1) {
|
||||
return new Response($app['twig']->render('prod/actions/Property/index.html.twig', [
|
||||
'records' => $records
|
||||
]));
|
||||
}
|
||||
|
||||
$nRec[$sbasId]['records']++;
|
||||
$databox = current($records->databoxes());
|
||||
$statusStructure = $databox->getStatusStructure();
|
||||
$recordsStatuses = [];
|
||||
|
||||
if ($record->is_grouping()) {
|
||||
$nRec[$sbasId]['stories']++;
|
||||
foreach ($records->received() as $record) {
|
||||
foreach ($statusStructure as $status) {
|
||||
$bit = $status['bit'];
|
||||
|
||||
if (!isset($recordsStatuses[$bit])) {
|
||||
$recordsStatuses[$bit] = $status;
|
||||
}
|
||||
|
||||
if (!isset($statusBit[$sbasId])) {
|
||||
$statusBit[$sbasId] = isset($databoxStatus[$sbasId]) ? $databoxStatus[$sbasId] : [];
|
||||
$statusSet = \databox_status::bitIsSet($record->getStatusBitField(), $bit);
|
||||
|
||||
foreach (array_keys($statusBit[$sbasId]) as $bit) {
|
||||
$statusBit[$sbasId][$bit]['nset'] = 0;
|
||||
}
|
||||
if (!isset($recordsStatuses[$bit]['flag'])) {
|
||||
$recordsStatuses[$bit]['flag'] = (int) $statusSet;
|
||||
}
|
||||
|
||||
$status = strrev($record->get_status());
|
||||
|
||||
foreach (array_keys($statusBit[$sbasId]) as $bit) {
|
||||
$statusBit[$sbasId][$bit]["nset"] += substr($status, $bit, 1) !== "0" ? 1 : 0;
|
||||
// if flag property was already set and the value is different from the previous one
|
||||
// it means that records share different value for the same flag
|
||||
if ($recordsStatuses[$bit]['flag'] !== (int) $statusSet) {
|
||||
$recordsStatuses[$bit]['flag'] = 2;
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($records->databoxes() as $databox) {
|
||||
$sbasId = $databox->get_sbas_id();
|
||||
foreach ($statusBit[$sbasId] as $bit => $values) {
|
||||
$statusBit[$sbasId][$bit]["status"] = $values["nset"] == 0 ? 0 : ($values["nset"] == $nRec[$sbasId]['records'] ? 1 : 2);
|
||||
}
|
||||
}
|
||||
|
||||
return new Response($app['twig']->render('prod/actions/Property/index.html.twig', [
|
||||
'records' => $records,
|
||||
'statusBit' => $statusBit,
|
||||
'nRec' => $nRec
|
||||
'status' => $recordsStatuses
|
||||
]));
|
||||
}
|
||||
|
||||
|
39
lib/Alchemy/Phrasea/Core/Provider/StatusServiceProvider.php
Normal file
39
lib/Alchemy/Phrasea/Core/Provider/StatusServiceProvider.php
Normal file
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Phraseanet
|
||||
*
|
||||
* (c) 2005-2014 Alchemy
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Alchemy\Phrasea\Core\Provider;
|
||||
|
||||
use Alchemy\Phrasea\Status\CacheStatusStructureProvider;
|
||||
use Alchemy\Phrasea\Status\StatusStructureFactory;
|
||||
use Alchemy\Phrasea\Status\XmlStatusStructureProvider;
|
||||
use Silex\Application;
|
||||
use Silex\ServiceProviderInterface;
|
||||
|
||||
class StatusServiceProvider implements ServiceProviderInterface
|
||||
{
|
||||
public function register(Application $app)
|
||||
{
|
||||
$app['status.provider'] = $app->share(function() use ($app) {
|
||||
return new CacheStatusStructureProvider(
|
||||
$app['cache'],
|
||||
new XmlStatusStructureProvider($app['root.path'], $app['locales.available'])
|
||||
);
|
||||
});
|
||||
|
||||
$app['factory.status-structure'] = $app->share(function() use ($app) {
|
||||
return new StatusStructureFactory($app['status.provider']);
|
||||
});
|
||||
}
|
||||
|
||||
public function boot(Application $app)
|
||||
{
|
||||
}
|
||||
}
|
@@ -256,16 +256,16 @@ class Edit extends \Alchemy\Phrasea\Helper\Helper
|
||||
|
||||
$sbas_id = \phrasea::sbasFromBas($this->app, $this->base_id);
|
||||
$databox = $this->app['phraseanet.appbox']->get_databox($sbas_id);
|
||||
$status = $databox->get_statusbits();
|
||||
$statusStructure = $databox->getStatusStructure();
|
||||
|
||||
foreach ($status as $bit => $datas) {
|
||||
foreach ($statusStructure as $bit => $status) {
|
||||
$tbits_left[$bit]["nset"] = 0;
|
||||
$tbits_left[$bit]["name"] = $datas['labels_off_i18n'][$this->app['locale']];
|
||||
$tbits_left[$bit]["icon"] = $datas["img_off"];
|
||||
$tbits_left[$bit]["name"] = $status['labels_off_i18n'][$this->app['locale']];
|
||||
$tbits_left[$bit]["icon"] = $status["img_off"];
|
||||
|
||||
$tbits_right[$bit]["nset"] = 0;
|
||||
$tbits_right[$bit]["name"] = $datas['labels_on_i18n'][$this->app['locale']];
|
||||
$tbits_right[$bit]["icon"] = $datas["img_on"];
|
||||
$tbits_right[$bit]["name"] = $status['labels_on_i18n'][$this->app['locale']];
|
||||
$tbits_right[$bit]["icon"] = $status["img_on"];
|
||||
}
|
||||
|
||||
$vand_and = $vand_or = $vxor_and = $vxor_or = "0000";
|
||||
|
@@ -293,17 +293,16 @@ class ElasticsearchRecord implements RecordInterface, MutableRecordInterface
|
||||
$this->flags = $flags;
|
||||
}
|
||||
|
||||
public function setStatus($status)
|
||||
public function setStatusBitField($status)
|
||||
{
|
||||
$this->status = $status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get status of current current as 32 bits binary string
|
||||
*
|
||||
* Eg: 00000000001011100000000000011111
|
||||
* @return integer
|
||||
*/
|
||||
public function getStatus()
|
||||
public function getStatusBitField()
|
||||
{
|
||||
return $this->status;
|
||||
}
|
||||
|
@@ -426,7 +426,7 @@ class User
|
||||
self::GENDER_MISS,
|
||||
self::GENDER_MR,
|
||||
self::GENDER_MRS
|
||||
], true)) {
|
||||
])) {
|
||||
throw new InvalidArgumentException(sprintf("Invalid gender %s.", $gender));
|
||||
}
|
||||
|
||||
|
@@ -34,8 +34,8 @@ interface MutableRecordInterface
|
||||
/** @param string $uuid */
|
||||
public function setUuid($uuid);
|
||||
|
||||
/** @param string $status */
|
||||
public function setStatus($status);
|
||||
/** @param integer $status */
|
||||
public function setStatusBitField($status);
|
||||
|
||||
/** @param \DateTime $updated */
|
||||
public function setUpdated(\DateTime $updated = null);
|
||||
|
@@ -55,8 +55,8 @@ interface RecordInterface
|
||||
/** @return string */
|
||||
public function getUuid();
|
||||
|
||||
/** @return string */
|
||||
public function getStatus();
|
||||
/** @return integer */
|
||||
public function getStatusBitField();
|
||||
|
||||
/** @return ArrayCollection */
|
||||
public function getExif();
|
||||
|
@@ -435,9 +435,11 @@ class ElasticSearchEngine implements SearchEngineInterface
|
||||
return ['bool' => ['must_not' => ['match_all' => new \stdClass()]]];
|
||||
}
|
||||
|
||||
$flagNamesMap = $this->getFlagsKey($this->app['phraseanet.appbox']);
|
||||
$appbox = $this->app['phraseanet.appbox'];
|
||||
|
||||
$flagNamesMap = $this->getFlagsKey($appbox);
|
||||
// Get flags rules
|
||||
$flagRules = $this->getFlagsRules($acl, $grantedCollections);
|
||||
$flagRules = $this->getFlagsRules($appbox, $acl, $grantedCollections);
|
||||
// Get intersection between collection ACLs and collection chosen by end user
|
||||
$aclRules = $this->getACLsByCollection($flagRules, $flagNamesMap);
|
||||
|
||||
@@ -531,23 +533,25 @@ class ElasticSearchEngine implements SearchEngineInterface
|
||||
$flags = [];
|
||||
foreach ($appbox->get_databoxes() as $databox) {
|
||||
$databoxId = $databox->get_sbas_id();
|
||||
$status = $databox->get_statusbits();
|
||||
foreach($status as $bit => $stat) {
|
||||
$flags[$databoxId][$bit] = RecordHelper::normalizeFlagKey($stat['labelon']);
|
||||
$statusStructure = $databox->getStatusStructure();
|
||||
foreach($statusStructure as $bit => $status) {
|
||||
$flags[$databoxId][$bit] = RecordHelper::normalizeFlagKey($status['labelon']);
|
||||
}
|
||||
}
|
||||
|
||||
return $flags;
|
||||
}
|
||||
|
||||
private function getFlagsRules(\ACL $acl, array $collections)
|
||||
private function getFlagsRules(\appbox $appbox, \ACL $acl, array $collections)
|
||||
{
|
||||
$rules = [];
|
||||
foreach ($collections as $collectionId) {
|
||||
$databoxId = \phrasea::sbasFromBas($this->app, $collectionId);
|
||||
$databox = $appbox->get_databox($databoxId);
|
||||
|
||||
$mask_xor = $acl->get_mask_xor($collectionId);
|
||||
$mask_and = $acl->get_mask_and($collectionId);
|
||||
foreach (range(0, 31) as $bit) {
|
||||
foreach ($databox->getStatusStructure()->getBits() as $bit) {
|
||||
$rules[$databoxId][$collectionId][$bit] = $this->computeAccess(
|
||||
$mask_xor,
|
||||
$mask_and,
|
||||
|
@@ -37,7 +37,7 @@ class ElasticsearchRecordHydrator
|
||||
$updatedOn = igorw\get_in($data, ['updated_on']);
|
||||
$record->setUpdated($updatedOn ? new \DateTime($updatedOn) : $updatedOn);
|
||||
$record->setUuid(igorw\get_in($data, ['uuid'], ''));
|
||||
$record->setStatus(igorw\get_in($data, ['flags_bitmask'], 0));
|
||||
$record->setStatusBitField(igorw\get_in($data, ['flags_bit_value'], 0));
|
||||
$record->setTitles(new ArrayCollection((array) igorw\get_in($data, ['title'], [])));
|
||||
$record->setCaption(new ArrayCollection((array) igorw\get_in($data, ['caption'], [])));
|
||||
$record->setExif(new ArrayCollection((array) igorw\get_in($data, ['exif'], [])));
|
||||
|
@@ -250,6 +250,7 @@ class RecordIndexer
|
||||
$mapping->add('caption', $captionMapping);
|
||||
$privateCaptionMapping = new Mapping();
|
||||
$mapping->add('private_caption', $privateCaptionMapping);
|
||||
|
||||
foreach ($this->getFieldsStructure() as $name => $params) {
|
||||
$m = $params['private'] ? $privateCaptionMapping : $captionMapping;
|
||||
$m->add($name, $params['type']);
|
||||
@@ -319,7 +320,7 @@ class RecordIndexer
|
||||
$mapping = new Mapping();
|
||||
|
||||
foreach ($this->appbox->get_databoxes() as $databox) {
|
||||
foreach ($databox->get_statusbits() as $bit => $status) {
|
||||
foreach ($databox->getStatusStructure() as $bit => $status) {
|
||||
$key = RecordHelper::normalizeFlagKey($status['labelon']);
|
||||
// We only add to mapping new statuses
|
||||
if (!$mapping->has($key)) {
|
||||
@@ -345,10 +346,10 @@ class RecordIndexer
|
||||
$structure = $this->getFieldsStructure();
|
||||
$databox = $this->appbox->get_databox($record['databox_id']);
|
||||
|
||||
foreach ($databox->get_statusbits() as $bit => $status) {
|
||||
foreach ($databox->getStatusStructure() as $bit => $status) {
|
||||
$key = RecordHelper::normalizeFlagKey($status['labelon']);
|
||||
|
||||
$record['flags'][$key] = \databox_status::bitIsSet($record['flags_bitmask'], $bit);
|
||||
$record['flags'][$key] = \databox_status::bitIsSet($record['flags_bit_value'], $bit);
|
||||
}
|
||||
|
||||
foreach ($dateFields as $field) {
|
||||
|
@@ -647,7 +647,7 @@ class SphinxSearchEngine implements SearchEngineInterface
|
||||
*/
|
||||
$status_opts = $options->getStatus();
|
||||
foreach ($options->getDataboxes() as $databox) {
|
||||
foreach ($databox->get_statusbits() as $n => $status) {
|
||||
foreach ($databox->getStatusStructure() as $n => $status) {
|
||||
if (!array_key_exists($n, $status_opts))
|
||||
continue;
|
||||
if (!array_key_exists($databox->get_sbas_id(), $status_opts[$n]))
|
||||
|
72
lib/Alchemy/Phrasea/Status/CacheStatusStructureProvider.php
Normal file
72
lib/Alchemy/Phrasea/Status/CacheStatusStructureProvider.php
Normal file
@@ -0,0 +1,72 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Phraseanet
|
||||
*
|
||||
* (c) 2005-2015 Alchemy
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Alchemy\Phrasea\Status;
|
||||
|
||||
use Alchemy\Phrasea\Application;
|
||||
use Doctrine\Common\Cache\Cache;
|
||||
use Doctrine\Common\Collections\ArrayCollection;
|
||||
|
||||
/**
|
||||
* Provides status structure definition using cache if possible
|
||||
*/
|
||||
class CacheStatusStructureProvider implements StatusStructureProviderInterface
|
||||
{
|
||||
private $cache;
|
||||
private $provider;
|
||||
|
||||
public function __construct(Cache $cache, StatusStructureProviderInterface $provider)
|
||||
{
|
||||
$this->cache = $cache;
|
||||
$this->provider = $provider;
|
||||
}
|
||||
|
||||
public function getStructure(\databox $databox)
|
||||
{
|
||||
if (false !== ($status = $this->cache->fetch($this->get_cache_key($databox->get_sbas_id())))) {
|
||||
|
||||
return new StatusStructure($databox, new ArrayCollection(json_decode($status, true)));
|
||||
}
|
||||
|
||||
$structure = $this->provider->getStructure($databox);
|
||||
|
||||
$this->cache->save($this->get_cache_key($databox->get_sbas_id()), json_encode($structure->toArray()));
|
||||
|
||||
return $structure;
|
||||
}
|
||||
|
||||
public function deleteStatus(StatusStructure $structure, $bit)
|
||||
{
|
||||
$databox = $structure->getDatabox();
|
||||
|
||||
$this->provider->deleteStatus($structure, $bit);
|
||||
|
||||
$this->cache->save($this->get_cache_key($databox->get_sbas_id()), json_encode($structure->toArray()));
|
||||
|
||||
return $structure;
|
||||
}
|
||||
|
||||
public function updateStatus(StatusStructure $structure, $bit, array $properties)
|
||||
{
|
||||
$databox = $structure->getDatabox();
|
||||
|
||||
$this->provider->updateStatus($structure, $bit, $properties);
|
||||
|
||||
$this->cache->save($this->get_cache_key($databox->get_sbas_id()), json_encode($structure->toArray()));
|
||||
|
||||
return $structure;
|
||||
}
|
||||
|
||||
private function get_cache_key($databox_id)
|
||||
{
|
||||
return sprintf('status_%s', $databox_id);
|
||||
}
|
||||
}
|
145
lib/Alchemy/Phrasea/Status/StatusStructure.php
Normal file
145
lib/Alchemy/Phrasea/Status/StatusStructure.php
Normal file
@@ -0,0 +1,145 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Phraseanet
|
||||
*
|
||||
* (c) 2005-2015 Alchemy
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Alchemy\Phrasea\Status;
|
||||
use Doctrine\Common\Collections\ArrayCollection;
|
||||
|
||||
/**
|
||||
* Aim to represent status structure of a databox
|
||||
* which is the combination of a databox and a collection of status
|
||||
*/
|
||||
class StatusStructure implements \IteratorAggregate
|
||||
{
|
||||
private $databox;
|
||||
private $status;
|
||||
private $url;
|
||||
private $path;
|
||||
|
||||
public function __construct(\databox $databox, ArrayCollection $status = null)
|
||||
{
|
||||
$this->databox = $databox;
|
||||
$this->status = $status ?: new ArrayCollection();
|
||||
|
||||
$unique_id = md5(implode('-', array(
|
||||
$this->databox->get_host(),
|
||||
$this->databox->get_port(),
|
||||
$this->databox->get_dbname()
|
||||
)));
|
||||
|
||||
// path to status icon
|
||||
$this->path = __DIR__ . "/../../../../config/status/" . $unique_id;
|
||||
// url to status icon
|
||||
$this->url = "/custom/status/" . $unique_id;
|
||||
}
|
||||
|
||||
public function getIterator()
|
||||
{
|
||||
return $this->status->getIterator();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get url to status icons
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getUrl()
|
||||
{
|
||||
return $this->url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get path to status icons
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getPath()
|
||||
{
|
||||
return $this->path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get databox where belong status
|
||||
*
|
||||
* @return \databox
|
||||
*/
|
||||
public function getDatabox()
|
||||
{
|
||||
return $this->databox;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the bits used in structure
|
||||
* $
|
||||
* @return array[] int
|
||||
*/
|
||||
public function getBits()
|
||||
{
|
||||
return $this->status->getKeys();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set new status at nth position
|
||||
*
|
||||
* @param int $nthBit
|
||||
* @param array $status
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setStatus($nthBit, array $status)
|
||||
{
|
||||
$this->status->set($nthBit, $status);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether structure has nth status set
|
||||
*
|
||||
* @param int $nthBit
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function hasStatus($nthBit)
|
||||
{
|
||||
return $this->status->containsKey($nthBit);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get status at nth position
|
||||
*
|
||||
* @param int $nthBit
|
||||
*
|
||||
* @return array|null
|
||||
*/
|
||||
public function getStatus($nthBit)
|
||||
{
|
||||
return $this->status->get($nthBit);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove status at nth position
|
||||
*
|
||||
* @param int $nthBit
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function removeStatus($nthBit)
|
||||
{
|
||||
$this->status->remove($nthBit);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function toArray()
|
||||
{
|
||||
return $this->status->toArray();
|
||||
}
|
||||
}
|
57
lib/Alchemy/Phrasea/Status/StatusStructureFactory.php
Normal file
57
lib/Alchemy/Phrasea/Status/StatusStructureFactory.php
Normal file
@@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Phraseanet
|
||||
*
|
||||
* (c) 2005-2015 Alchemy
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Alchemy\Phrasea\Status;
|
||||
|
||||
/**
|
||||
* This class is used to get databox status structure
|
||||
*/
|
||||
class StatusStructureFactory
|
||||
{
|
||||
/**
|
||||
* Keep trace of already instantiated databox status structure
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $statusStructure = [];
|
||||
|
||||
/**
|
||||
* A provider that gives the definition of a structure
|
||||
*
|
||||
* @var StatusStructureProviderInterface
|
||||
*/
|
||||
protected $provider;
|
||||
|
||||
public function __construct(StatusStructureProviderInterface $provider)
|
||||
{
|
||||
$this->provider = $provider;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the status structure according to the given databox
|
||||
*
|
||||
* @param \databox $databox
|
||||
*
|
||||
* @return StatusStructure
|
||||
*/
|
||||
public function getStructure(\databox $databox)
|
||||
{
|
||||
$databox_id = $databox->get_sbas_id();
|
||||
|
||||
if (isset($this->statusStructure[$databox_id])) {
|
||||
return $this->statusStructure[$databox_id];
|
||||
}
|
||||
|
||||
$this->statusStructure[$databox_id] = $this->provider->getStructure($databox);
|
||||
|
||||
return $this->statusStructure[$databox_id];
|
||||
}
|
||||
}
|
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Phraseanet
|
||||
*
|
||||
* (c) 2005-2015 Alchemy
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Alchemy\Phrasea\Status;
|
||||
|
||||
/**
|
||||
* Interface defined for status definition providers
|
||||
*/
|
||||
interface StatusStructureProviderInterface
|
||||
{
|
||||
/**
|
||||
* Returns a status structure for a given databox
|
||||
*
|
||||
* @param \databox $databox
|
||||
*
|
||||
* @return StatusStructure
|
||||
*/
|
||||
public function getStructure(\databox $databox);
|
||||
|
||||
/**
|
||||
* Deletes status at nth bit from given status structure
|
||||
*
|
||||
* @param StatusStructure $structure
|
||||
* @param int $bit
|
||||
*
|
||||
* @return StatusStructure
|
||||
*/
|
||||
public function deleteStatus(StatusStructure $structure, $bit);
|
||||
|
||||
/**
|
||||
* Updates status at nth bit from given status structure
|
||||
*
|
||||
* @param StatusStructure $structure
|
||||
* @param int $bit
|
||||
*
|
||||
* @return StatusStructure
|
||||
*/
|
||||
public function updateStatus(StatusStructure $structure, $bit, array $properties);
|
||||
}
|
235
lib/Alchemy/Phrasea/Status/XmlStatusStructureProvider.php
Normal file
235
lib/Alchemy/Phrasea/Status/XmlStatusStructureProvider.php
Normal file
@@ -0,0 +1,235 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Phraseanet
|
||||
*
|
||||
* (c) 2005-2015 Alchemy
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Alchemy\Phrasea\Status;
|
||||
|
||||
use Symfony\Component\Filesystem\Filesystem;
|
||||
|
||||
/**
|
||||
* Provides status structure definition from XML
|
||||
*/
|
||||
class XmlStatusStructureProvider implements StatusStructureProviderInterface
|
||||
{
|
||||
protected $rootPath;
|
||||
protected $locales;
|
||||
|
||||
public function __construct($rootPath, $locales, $fs = null)
|
||||
{
|
||||
$this->rootPath = $rootPath;
|
||||
$this->locales = $locales;
|
||||
$this->fs = $fs ?: new Filesystem();
|
||||
}
|
||||
|
||||
public function getStructure(\databox $databox)
|
||||
{
|
||||
$statusStructure = new StatusStructure($databox);
|
||||
|
||||
$xmlPref = $databox->get_structure();
|
||||
$sxe = simplexml_load_string($xmlPref);
|
||||
|
||||
if ($sxe === false) {
|
||||
throw new \Exception('Failed to load database XML structure');
|
||||
}
|
||||
|
||||
foreach ($sxe->statbits->bit as $sb) {
|
||||
$bit = (int) ($sb['n']);
|
||||
if ($bit < 4 && $bit > 31) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$status = [];
|
||||
|
||||
$status['bit'] = $bit;
|
||||
|
||||
$status['labeloff'] = (string) $sb['labelOff'];
|
||||
$status['labelon'] = (string) $sb['labelOn'];
|
||||
|
||||
foreach ($this->locales as $code => $language) {
|
||||
$status['labels_on'][$code] = null;
|
||||
$status['labels_off'][$code] = null;
|
||||
}
|
||||
|
||||
foreach ($sb->label as $label) {
|
||||
$status['labels_'.$label['switch']][(string) $label['code']] = (string) $label;
|
||||
}
|
||||
|
||||
foreach ($this->locales as $code => $language) {
|
||||
$status['labels_on_i18n'][$code] = '' !== trim($status['labels_on'][$code]) ? $status['labels_on'][$code] : $status['labelon'];
|
||||
$status['labels_off_i18n'][$code] = '' !== trim($status['labels_off'][$code]) ? $status['labels_off'][$code] : $status['labeloff'];
|
||||
}
|
||||
|
||||
$status['img_off'] = null;
|
||||
$status['img_on'] = null;
|
||||
|
||||
if (is_file($statusStructure->getPath() . '-stat_' . $bit . '_0.gif')) {
|
||||
$status['img_off'] = $statusStructure->getUrl() . '-stat_' . $bit . '_0.gif?etag='.md5_file($statusStructure->getPath() . '-stat_' . $bit . '_0.gif');
|
||||
$status['path_off'] = $statusStructure->getPath() . '-stat_' . $bit . '_0.gif';
|
||||
}
|
||||
if (is_file($statusStructure->getPath() . '-stat_' . $bit . '_1.gif')) {
|
||||
$status['img_on'] = $statusStructure->getUrl() . '-stat_' . $bit . '_1.gif?etag='.md5_file($statusStructure->getPath() . '-stat_' . $bit . '_1.gif');
|
||||
$status['path_on'] = $statusStructure->getPath() . '-stat_' . $bit . '_1.gif';
|
||||
}
|
||||
|
||||
$status['searchable'] = isset($sb['searchable']) ? (int) $sb['searchable'] : 0;
|
||||
$status['printable'] = isset($sb['printable']) ? (int) $sb['printable'] : 0;
|
||||
|
||||
$statusStructure->setStatus($bit, $status);
|
||||
}
|
||||
|
||||
return $statusStructure;
|
||||
}
|
||||
|
||||
public function deleteStatus(StatusStructure $statusStructure, $bit)
|
||||
{
|
||||
$databox = $statusStructure->getDatabox();
|
||||
|
||||
if (false === $statusStructure->hasStatus($bit)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$doc = $databox->get_dom_structure();
|
||||
|
||||
if (!$doc) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$xpath = $databox->get_xpath_structure();
|
||||
$entries = $xpath->query('/record/statbits/bit[@n=' . $bit . ']');
|
||||
|
||||
foreach ($entries as $sbit) {
|
||||
if ($p = $sbit->previousSibling) {
|
||||
if ($p->nodeType == XML_TEXT_NODE && $p->nodeValue == '\n\t\t')
|
||||
$p->parentNode->removeChild($p);
|
||||
}
|
||||
if ($sbit->parentNode->removeChild($sbit)) {
|
||||
$sql = 'UPDATE record SET status = status&(~(1<<' . $bit . '))';
|
||||
$stmt = $databox->get_connection()->prepare($sql);
|
||||
$stmt->execute();
|
||||
$stmt->closeCursor();
|
||||
}
|
||||
}
|
||||
|
||||
$databox->saveStructure($doc);
|
||||
|
||||
$status = $statusStructure->getStatus($bit);
|
||||
|
||||
if (null !== $status['img_off']) {
|
||||
$this->fs->remove($status['path_off']);
|
||||
}
|
||||
|
||||
if (null !== $status['img_on']) {
|
||||
$this->fs->remove($status['path_on']);
|
||||
}
|
||||
|
||||
$statusStructure->removeStatus($bit);
|
||||
|
||||
return $statusStructure;
|
||||
}
|
||||
|
||||
public function updateStatus(StatusStructure $statusStructure, $bit, array $properties)
|
||||
{
|
||||
$databox = $statusStructure->getDatabox();
|
||||
|
||||
if (false === $statusStructure->hasStatus($bit)) {
|
||||
$statusStructure->setStatus($bit, []);
|
||||
}
|
||||
|
||||
$doc = $databox->get_dom_structure();
|
||||
|
||||
if (!$doc) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$xpath = $databox->get_xpath_structure();
|
||||
$entries = $xpath->query('/record/statbits');
|
||||
|
||||
if ($entries->length == 0) {
|
||||
$statbits = $doc->documentElement->appendChild($doc->createElement('statbits'));
|
||||
} else {
|
||||
$statbits = $entries->item(0);
|
||||
}
|
||||
|
||||
if ($statbits) {
|
||||
$entries = $xpath->query('/record/statbits/bit[@n=' . $bit . ']');
|
||||
|
||||
if ($entries->length >= 1) {
|
||||
foreach ($entries as $k => $sbit) {
|
||||
if ($p = $sbit->previousSibling) {
|
||||
if ($p->nodeType == XML_TEXT_NODE && $p->nodeValue == '\n\t\t')
|
||||
$p->parentNode->removeChild($p);
|
||||
}
|
||||
$sbit->parentNode->removeChild($sbit);
|
||||
}
|
||||
}
|
||||
|
||||
$sbit = $statbits->appendChild($doc->createElement('bit'));
|
||||
|
||||
if ($n = $sbit->appendChild($doc->createAttribute('n'))) {
|
||||
$n->value = $bit;
|
||||
}
|
||||
|
||||
if ($labOn = $sbit->appendChild($doc->createAttribute('labelOn'))) {
|
||||
$labOn->value = $properties['labelon'];
|
||||
}
|
||||
|
||||
if ($searchable = $sbit->appendChild($doc->createAttribute('searchable'))) {
|
||||
$searchable->value = $properties['searchable'];
|
||||
}
|
||||
|
||||
if ($printable = $sbit->appendChild($doc->createAttribute('printable'))) {
|
||||
$printable->value = $properties['printable'];
|
||||
}
|
||||
|
||||
if ($labOff = $sbit->appendChild($doc->createAttribute('labelOff'))) {
|
||||
$labOff->value = $properties['labeloff'];
|
||||
}
|
||||
|
||||
foreach ($properties['labels_off'] as $code => $label) {
|
||||
$labelTag = $sbit->appendChild($doc->createElement('label'));
|
||||
$switch = $labelTag->appendChild($doc->createAttribute('switch'));
|
||||
$switch->value = 'off';
|
||||
$codeTag = $labelTag->appendChild($doc->createAttribute('code'));
|
||||
$codeTag->value = $code;
|
||||
$labelTag->appendChild($doc->createTextNode($label));
|
||||
}
|
||||
|
||||
foreach ($properties['labels_on'] as $code => $label) {
|
||||
$labelTag = $sbit->appendChild($doc->createElement('label'));
|
||||
$switch = $labelTag->appendChild($doc->createAttribute('switch'));
|
||||
$switch->value = 'on';
|
||||
$codeTag = $labelTag->appendChild($doc->createAttribute('code'));
|
||||
$codeTag->value = $code;
|
||||
$labelTag->appendChild($doc->createTextNode($label));
|
||||
}
|
||||
}
|
||||
|
||||
$databox->saveStructure($doc);
|
||||
|
||||
$status = $statusStructure->getStatus($bit);
|
||||
|
||||
$status['labelon'] = $properties['labelon'];
|
||||
$status['labeloff'] = $properties['labeloff'];
|
||||
$status['searchable'] = (Boolean) $properties['searchable'];
|
||||
$status['printable'] = (Boolean) $properties['printable'];
|
||||
|
||||
if (!isset($properties['img_on'])) {
|
||||
$status['img_on'] = null;
|
||||
}
|
||||
|
||||
if (!isset($properties['img_off'])) {
|
||||
$status['img_off'] = null;
|
||||
}
|
||||
|
||||
$statusStructure->setStatus($bit, $status);
|
||||
|
||||
return $statusStructure;
|
||||
}
|
||||
}
|
@@ -37,9 +37,41 @@ class PhraseanetExtension extends \Twig_Extension
|
||||
new \Twig_SimpleFunction('collection_logo', array($this, 'getCollectionLogo'), array(
|
||||
'is_safe' => array('html')
|
||||
)),
|
||||
new \Twig_SimpleFunction('record_flags', array($this, 'getRecordFlags'))
|
||||
);
|
||||
}
|
||||
|
||||
public function getRecordFlags(RecordInterface $record)
|
||||
{
|
||||
$recordStatuses = [];
|
||||
$databox = $this->app['phraseanet.appbox']->get_databox($record->getDataboxId());
|
||||
|
||||
$structure = $databox->getStatusStructure()->toArray();
|
||||
|
||||
if (!$this->isGrantedOnCollection($record->getBaseId(), 'chgstatus')) {
|
||||
$structure = array_filter($structure, function($status) {
|
||||
return (bool) $status['printable'];
|
||||
});
|
||||
}
|
||||
|
||||
$bitValue = $record->getStatusBitField();
|
||||
|
||||
foreach ($structure as $status) {
|
||||
$on = \databox_status::bitIsSet($bitValue, $status['bit']);
|
||||
|
||||
if (null === ($on ? $status['img_on'] : $status['img_off'])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$recordStatuses[] = [
|
||||
'path' => ($on ? $status['img_on'] : $status['img_off']),
|
||||
'labels' => ($on ? $status['labels_on_i18n'] : $status['labels_off_i18n'])
|
||||
];
|
||||
}
|
||||
|
||||
return $recordStatuses;
|
||||
}
|
||||
|
||||
public function isGrantedOnDatabox($databoxId, $rights)
|
||||
{
|
||||
if (false === ($this->app['authentication']->getUser() instanceof User)) {
|
||||
|
@@ -210,7 +210,7 @@ class ACL implements cache_cacheableInterface
|
||||
|
||||
public function has_status_access_to_record(RecordInterface $record)
|
||||
{
|
||||
return 0 === ((bindec($record->getStatus()) ^ $this->get_mask_xor($record->getBaseId())) & $this->get_mask_and($record->getBaseId()));
|
||||
return 0 === ((bindec($record->getStatusBitField()) ^ $this->get_mask_xor($record->getBaseId())) & $this->get_mask_and($record->getBaseId()));
|
||||
}
|
||||
|
||||
public function has_access_to_subdef(RecordInterface $record, $subdef_name)
|
||||
|
@@ -307,9 +307,9 @@ class databox extends base
|
||||
*
|
||||
* @return databox_status
|
||||
*/
|
||||
public function get_statusbits()
|
||||
public function getStatusStructure()
|
||||
{
|
||||
return databox_status::getStatus($this->app, $this->id);
|
||||
return $this->app['factory.status-structure']->getStructure($this);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -11,385 +11,101 @@
|
||||
|
||||
use Alchemy\Phrasea\Application;
|
||||
use Alchemy\Phrasea\SearchEngine\Elastic\RecordHelper;
|
||||
use MediaAlchemyst\Specification\Image as ImageSpecification;
|
||||
use Symfony\Component\HttpFoundation\File\UploadedFile;
|
||||
use Alchemy\Phrasea\Exception\InvalidArgumentException;
|
||||
use MediaAlchemyst\Specification\Image as ImageSpecification;
|
||||
use Symfony\Component\HttpFoundation\File\Exception\FileException;
|
||||
use Alchemy\Phrasea\Model\RecordInterface;
|
||||
|
||||
class databox_status
|
||||
{
|
||||
/**
|
||||
*
|
||||
* @var Array
|
||||
*/
|
||||
private static $_status = [];
|
||||
|
||||
/**
|
||||
*
|
||||
* @var Array
|
||||
*/
|
||||
protected static $_statuses;
|
||||
|
||||
/**
|
||||
*
|
||||
* @var Array
|
||||
*/
|
||||
private $status = [];
|
||||
|
||||
/**
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $path = '';
|
||||
|
||||
/**
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $url = '';
|
||||
|
||||
/**
|
||||
*
|
||||
* @param int $sbas_id
|
||||
* @return status
|
||||
*/
|
||||
private function __construct(Application $app, $sbas_id)
|
||||
{
|
||||
$this->status = [];
|
||||
|
||||
$path = $url = false;
|
||||
|
||||
$sbas_params = phrasea::sbas_params($app);
|
||||
|
||||
if ( ! isset($sbas_params[$sbas_id])) {
|
||||
return;
|
||||
}
|
||||
|
||||
$uniqid = md5(implode('-', [
|
||||
$sbas_params[$sbas_id]["host"],
|
||||
$sbas_params[$sbas_id]["port"],
|
||||
$sbas_params[$sbas_id]["dbname"]
|
||||
]));
|
||||
|
||||
$path = $this->path = $app['root.path'] . "/config/status/" . $uniqid;
|
||||
$url = $this->url = "/custom/status/" . $uniqid;
|
||||
|
||||
$databox = $app['phraseanet.appbox']->get_databox((int) $sbas_id);
|
||||
$xmlpref = $databox->get_structure();
|
||||
$sxe = simplexml_load_string($xmlpref);
|
||||
|
||||
if ($sxe !== false) {
|
||||
|
||||
foreach ($sxe->statbits->bit as $sb) {
|
||||
$bit = (int) ($sb["n"]);
|
||||
if ($bit < 4 && $bit > 31)
|
||||
continue;
|
||||
|
||||
$this->status[$bit]["labeloff"] = (string) $sb['labelOff'];
|
||||
$this->status[$bit]["labelon"] = (string) $sb['labelOn'];
|
||||
|
||||
foreach ($app['locales.available'] as $code => $language) {
|
||||
$this->status[$bit]['labels_on'][$code] = null;
|
||||
$this->status[$bit]['labels_off'][$code] = null;
|
||||
}
|
||||
|
||||
foreach ($sb->label as $label) {
|
||||
$this->status[$bit]['labels_'.$label['switch']][(string) $label['code']] = (string) $label;
|
||||
}
|
||||
|
||||
foreach ($app['locales.available'] as $code => $language) {
|
||||
$this->status[$bit]['labels_on_i18n'][$code] = '' !== trim($this->status[$bit]['labels_on'][$code]) ? $this->status[$bit]['labels_on'][$code] : $this->status[$bit]["labelon"];
|
||||
$this->status[$bit]['labels_off_i18n'][$code] = '' !== trim($this->status[$bit]['labels_off'][$code]) ? $this->status[$bit]['labels_off'][$code] : $this->status[$bit]["labeloff"];
|
||||
}
|
||||
|
||||
$this->status[$bit]["img_off"] = null;
|
||||
$this->status[$bit]["img_on"] = null;
|
||||
|
||||
if (is_file($path . "-stat_" . $bit . "_0.gif")) {
|
||||
$this->status[$bit]["img_off"] = $url . "-stat_" . $bit . "_0.gif?etag=".md5_file($path . "-stat_" . $bit . "_0.gif");
|
||||
$this->status[$bit]["path_off"] = $path . "-stat_" . $bit . "_0.gif";
|
||||
}
|
||||
if (is_file($path . "-stat_" . $bit . "_1.gif")) {
|
||||
$this->status[$bit]["img_on"] = $url . "-stat_" . $bit . "_1.gif?etag=".md5_file($path . "-stat_" . $bit . "_1.gif");
|
||||
$this->status[$bit]["path_on"] = $path . "-stat_" . $bit . "_1.gif";
|
||||
}
|
||||
|
||||
$this->status[$bit]["searchable"] = isset($sb['searchable']) ? (int) $sb['searchable'] : 0;
|
||||
$this->status[$bit]["printable"] = isset($sb['printable']) ? (int) $sb['printable'] : 0;
|
||||
}
|
||||
}
|
||||
ksort($this->status);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public static function getStatus(Application $app, $sbas_id)
|
||||
{
|
||||
|
||||
if ( ! isset(self::$_status[$sbas_id]))
|
||||
self::$_status[$sbas_id] = new databox_status($app, $sbas_id);
|
||||
|
||||
|
||||
return self::$_status[$sbas_id]->status;
|
||||
}
|
||||
|
||||
public static function getDisplayStatus(Application $app)
|
||||
{
|
||||
if (self::$_statuses) {
|
||||
return self::$_statuses;
|
||||
}
|
||||
|
||||
$sbas_ids = $app['acl']->get($app['authentication']->getUser())->get_granted_sbas();
|
||||
|
||||
$statuses = [];
|
||||
|
||||
foreach ($sbas_ids as $databox) {
|
||||
try {
|
||||
$statuses[$databox->get_sbas_id()] = $databox->get_statusbits();
|
||||
} catch (\Exception $e) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
self::$_statuses = $statuses;
|
||||
|
||||
return self::$_statuses;
|
||||
}
|
||||
|
||||
public static function getSearchStatus(Application $app)
|
||||
{
|
||||
$statuses = $see_all = [];
|
||||
$databoxes = $app['acl']->get($app['authentication']->getUser())->get_granted_sbas();
|
||||
|
||||
foreach ($databoxes as $databox) {
|
||||
$see_all = $structures = $stats = [];
|
||||
foreach ($app['acl']->get($app['authentication']->getUser())->get_granted_sbas() as $databox) {
|
||||
$see_all[$databox->get_sbas_id()] = false;
|
||||
|
||||
foreach ($databox->get_collections() as $collection) {
|
||||
if ($app['acl']->get($app['authentication']->getUser())->has_right_on_base($collection->get_base_id(), 'chgstatus')) {
|
||||
$see_all[$databox->get_sbas_id()] = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
$statuses[$databox->get_sbas_id()] = $databox->get_statusbits();
|
||||
} catch (\Exception $e) {
|
||||
|
||||
}
|
||||
$structures[$databox->get_sbas_id()] = $databox->getStatusStructure();
|
||||
}
|
||||
|
||||
$stats = [];
|
||||
|
||||
foreach ($statuses as $databox_id => $status) {
|
||||
$canSeeAll = isset($see_all[$databox_id]) ? $see_all[$databox_id] : false;
|
||||
$canSeeThis = $app['acl']->get($app['authentication']->getUser())->has_right_on_sbas($databox_id, 'bas_modify_struct');
|
||||
|
||||
$canAccess = $canSeeAll || $canSeeThis;
|
||||
|
||||
foreach ($status as $bit => $props) {
|
||||
if (!$props['searchable'] && !$canAccess) {
|
||||
continue;
|
||||
}
|
||||
$stats[$databox_id][$bit] = array(
|
||||
'name' => RecordHelper::normalizeFlagKey($props['labelon']),
|
||||
'labeloff' => $props['labeloff'],
|
||||
'labelon' => $props['labelon'],
|
||||
'labels_on_i18n' => $props['labels_on_i18n'],
|
||||
'labels_off_i18n' => $props['labels_off_i18n'],
|
||||
'imgoff' => $props['img_off'],
|
||||
'imgon' => $props['img_on']
|
||||
);
|
||||
}
|
||||
foreach ($structures as $databox_id => $structure) {
|
||||
if (false === $see_all[$databox_id]) {
|
||||
$structure = array_filter(function($status) {
|
||||
return (bool) $status['searchable'];
|
||||
}, $structure->toArray());
|
||||
}
|
||||
|
||||
foreach($structure as $bit => $status) {
|
||||
$key = RecordHelper::normalizeFlagKey($status['labelon']);
|
||||
|
||||
if (isset($stats[$key])) {
|
||||
$status = $stats[$key];
|
||||
}
|
||||
|
||||
$status['sbas'][] = $databox_id;
|
||||
$status['bit'] = $bit;
|
||||
|
||||
$stats[$key] = $status;
|
||||
}
|
||||
}
|
||||
return $stats;
|
||||
}
|
||||
|
||||
public static function getPath(Application $app, $sbas_id)
|
||||
public static function deleteIcon(Application $app, $databox_id, $bit, $switch)
|
||||
{
|
||||
if ( ! isset(self::$_status[$sbas_id])) {
|
||||
self::$_status[$sbas_id] = new databox_status($app, $sbas_id);
|
||||
$databox = $app['phraseanet.appbox']->get_databox($databox_id);
|
||||
|
||||
$statusStructure = $app['factory.status-structure']->getStructure($databox);
|
||||
|
||||
if (!$statusStructure->hasStatus($bit)) {
|
||||
throw new InvalidArgumentException(sprintf('bit %s does not exists on database %s', $bit, $statusStructure->getDatabox()->get_dbname()));
|
||||
}
|
||||
|
||||
return self::$_status[$sbas_id]->path;
|
||||
}
|
||||
|
||||
public static function getUrl(Application $app, $sbas_id)
|
||||
{
|
||||
if ( ! isset(self::$_status[$sbas_id])) {
|
||||
self::$_status[$sbas_id] = new databox_status($app, $sbas_id);
|
||||
}
|
||||
|
||||
return self::$_status[$sbas_id]->url;
|
||||
}
|
||||
|
||||
public static function deleteStatus(Application $app, \databox $databox, $bit)
|
||||
{
|
||||
$status = self::getStatus($app, $databox->get_sbas_id());
|
||||
|
||||
if (isset($status[$bit])) {
|
||||
$doc = $databox->get_dom_structure();
|
||||
if ($doc) {
|
||||
$xpath = $databox->get_xpath_structure();
|
||||
$entries = $xpath->query("/record/statbits/bit[@n=" . $bit . "]");
|
||||
|
||||
foreach ($entries as $sbit) {
|
||||
if ($p = $sbit->previousSibling) {
|
||||
if ($p->nodeType == XML_TEXT_NODE && $p->nodeValue == "\n\t\t")
|
||||
$p->parentNode->removeChild($p);
|
||||
}
|
||||
if ($sbit->parentNode->removeChild($sbit)) {
|
||||
$sql = 'UPDATE record SET status = status&(~(1<<' . $bit . '))';
|
||||
$stmt = $databox->get_connection()->prepare($sql);
|
||||
$stmt->execute();
|
||||
$stmt->closeCursor();
|
||||
}
|
||||
}
|
||||
|
||||
$databox->saveStructure($doc);
|
||||
|
||||
if (null !== $status[$bit]['img_off']) {
|
||||
$app['filesystem']->remove($status[$bit]['path_off']);
|
||||
}
|
||||
|
||||
if (null !== $status[$bit]['img_on']) {
|
||||
$app['filesystem']->remove($status[$bit]['path_on']);
|
||||
}
|
||||
|
||||
unset(self::$_status[$databox->get_sbas_id()]->status[$bit]);
|
||||
|
||||
$app['dispatcher']->dispatch(RecordStructureEvents::STATUS_BIT_DELETED, new StatusBitDeletedEvent($databox, $bit));
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function updateStatus(Application $app, $sbas_id, $bit, $properties)
|
||||
{
|
||||
self::getStatus($app, $sbas_id);
|
||||
|
||||
$databox = $app['phraseanet.appbox']->get_databox((int) $sbas_id);
|
||||
|
||||
$doc = $databox->get_dom_structure($sbas_id);
|
||||
if ($doc) {
|
||||
$xpath = $databox->get_xpath_structure($sbas_id);
|
||||
$entries = $xpath->query("/record/statbits");
|
||||
if ($entries->length == 0) {
|
||||
$statbits = $doc->documentElement->appendChild($doc->createElement("statbits"));
|
||||
} else {
|
||||
$statbits = $entries->item(0);
|
||||
}
|
||||
|
||||
if ($statbits) {
|
||||
$entries = $xpath->query("/record/statbits/bit[@n=" . $bit . "]");
|
||||
|
||||
if ($entries->length >= 1) {
|
||||
foreach ($entries as $k => $sbit) {
|
||||
if ($p = $sbit->previousSibling) {
|
||||
if ($p->nodeType == XML_TEXT_NODE && $p->nodeValue == "\n\t\t")
|
||||
$p->parentNode->removeChild($p);
|
||||
}
|
||||
$sbit->parentNode->removeChild($sbit);
|
||||
}
|
||||
}
|
||||
|
||||
$sbit = $statbits->appendChild($doc->createElement("bit"));
|
||||
|
||||
if ($n = $sbit->appendChild($doc->createAttribute("n"))) {
|
||||
$n->value = $bit;
|
||||
}
|
||||
|
||||
if ($labOn = $sbit->appendChild($doc->createAttribute("labelOn"))) {
|
||||
$labOn->value = $properties['labelon'];
|
||||
}
|
||||
|
||||
if ($searchable = $sbit->appendChild($doc->createAttribute("searchable"))) {
|
||||
$searchable->value = $properties['searchable'];
|
||||
}
|
||||
|
||||
if ($printable = $sbit->appendChild($doc->createAttribute("printable"))) {
|
||||
$printable->value = $properties['printable'];
|
||||
}
|
||||
|
||||
if ($labOff = $sbit->appendChild($doc->createAttribute("labelOff"))) {
|
||||
$labOff->value = $properties['labeloff'];
|
||||
}
|
||||
|
||||
foreach ($properties['labels_off'] as $code => $label) {
|
||||
$labelTag = $sbit->appendChild($doc->createElement("label"));
|
||||
$switch = $labelTag->appendChild($doc->createAttribute("switch"));
|
||||
$switch->value = 'off';
|
||||
$codeTag = $labelTag->appendChild($doc->createAttribute("code"));
|
||||
$codeTag->value = $code;
|
||||
$labelTag->appendChild($doc->createTextNode($label));
|
||||
}
|
||||
|
||||
foreach ($properties['labels_on'] as $code => $label) {
|
||||
$labelTag = $sbit->appendChild($doc->createElement("label"));
|
||||
$switch = $labelTag->appendChild($doc->createAttribute("switch"));
|
||||
$switch->value = 'on';
|
||||
$codeTag = $labelTag->appendChild($doc->createAttribute("code"));
|
||||
$codeTag->value = $code;
|
||||
$labelTag->appendChild($doc->createTextNode($label));
|
||||
}
|
||||
}
|
||||
|
||||
$databox->saveStructure($doc);
|
||||
|
||||
self::$_status[$sbas_id]->status[$bit]["labelon"] = $properties['labelon'];
|
||||
self::$_status[$sbas_id]->status[$bit]["labeloff"] = $properties['labeloff'];
|
||||
self::$_status[$sbas_id]->status[$bit]["searchable"] = (Boolean) $properties['searchable'];
|
||||
self::$_status[$sbas_id]->status[$bit]["printable"] = (Boolean) $properties['printable'];
|
||||
|
||||
if ( ! isset(self::$_status[$sbas_id]->status[$bit]['img_on'])) {
|
||||
self::$_status[$sbas_id]->status[$bit]['img_on'] = null;
|
||||
}
|
||||
|
||||
if ( ! isset(self::$_status[$sbas_id]->status[$bit]['img_off'])) {
|
||||
self::$_status[$sbas_id]->status[$bit]['img_off'] = null;
|
||||
}
|
||||
|
||||
$properties = self::$_status[$sbas_id]->status[$bit];
|
||||
$app['dispatcher']->dispatch(RecordStructureEvents::STATUS_BIT_UPDATED, new StatusBitUpdatedEvent($databox, $bit, $properties));
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function deleteIcon(Application $app, $sbas_id, $bit, $switch)
|
||||
{
|
||||
$status = self::getStatus($app, $sbas_id);
|
||||
$status = $statusStructure->getStatus($bit);
|
||||
|
||||
$switch = in_array($switch, ['on', 'off']) ? $switch : false;
|
||||
|
||||
if (! $switch) {
|
||||
if (!$switch) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($status[$bit]['img_' . $switch]) {
|
||||
if (isset($status[$bit]['path_' . $switch])) {
|
||||
$app['filesystem']->remove($status[$bit]['path_' . $switch]);
|
||||
if ($status['img_' . $switch]) {
|
||||
if (isset($status['path_' . $switch])) {
|
||||
$app['filesystem']->remove($status['path_' . $switch]);
|
||||
}
|
||||
|
||||
$status[$bit]['img_' . $switch] = false;
|
||||
unset($status[$bit]['path_' . $switch]);
|
||||
$status['img_' . $switch] = false;
|
||||
unset($status['path_' . $switch]);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static function updateIcon(Application $app, $sbas_id, $bit, $switch, UploadedFile $file)
|
||||
public static function updateIcon(Application $app, $databox_id, $bit, $switch, UploadedFile $file)
|
||||
{
|
||||
$databox = $app['phraseanet.appbox']->get_databox($databox_id);
|
||||
|
||||
$statusStructure = $app['factory.status-structure']->getStructure($databox);
|
||||
|
||||
if (!$statusStructure->hasStatus($bit)) {
|
||||
throw new InvalidArgumentException(sprintf('bit %s does not exists', $bit));
|
||||
}
|
||||
|
||||
$status = $statusStructure->getStatus($bit);
|
||||
|
||||
$switch = in_array($switch, ['on', 'off']) ? $switch : false;
|
||||
|
||||
if (! $switch) {
|
||||
if (!$switch) {
|
||||
throw new Exception_InvalidArgument();
|
||||
}
|
||||
|
||||
$url = self::getUrl($app, $sbas_id);
|
||||
$path = self::getPath($app, $sbas_id);
|
||||
$url = $statusStructure->getUrl();
|
||||
$path = $statusStructure->getPath();
|
||||
|
||||
if ($file->getSize() >= 65535) {
|
||||
throw new Exception_Upload_FileTooBig();
|
||||
@@ -399,7 +115,7 @@ class databox_status
|
||||
throw new Exception_Upload_Error();
|
||||
}
|
||||
|
||||
self::deleteIcon($app, $sbas_id, $bit, $switch);
|
||||
self::deleteIcon($app, $databox_id, $bit, $switch);
|
||||
|
||||
$name = "-stat_" . $bit . "_" . ($switch == 'on' ? '1' : '0') . ".gif";
|
||||
|
||||
@@ -427,8 +143,8 @@ class databox_status
|
||||
|
||||
}
|
||||
|
||||
self::$_status[$sbas_id]->status[$bit]['img_' . $switch] = $url . $name;
|
||||
self::$_status[$sbas_id]->status[$bit]['path_' . $switch] = $filePath;
|
||||
$status['img_' . $switch] = $url . $name;
|
||||
$status['path_' . $switch] = $filePath;
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -607,13 +323,8 @@ class databox_status
|
||||
return $status;
|
||||
}
|
||||
|
||||
public static function purge()
|
||||
public static function bitIsSet($bitValue, $nthBit)
|
||||
{
|
||||
self::$_status = self::$_statuses = [];
|
||||
}
|
||||
|
||||
public static function bitIsSet($bitMask, $nthBit)
|
||||
{
|
||||
return (bool) ($bitMask & (1 << $nthBit));
|
||||
return (bool) ($bitValue & (1 << $nthBit));
|
||||
}
|
||||
}
|
||||
|
@@ -29,6 +29,7 @@ use Doctrine\ORM\EntityManager;
|
||||
use Doctrine\Common\Collections\ArrayCollection;
|
||||
use MediaVorus\MediaVorus;
|
||||
use Rhumsaa\Uuid\Uuid;
|
||||
use Alchemy\Phrasea\Status\StatusStructure;
|
||||
use Alchemy\Phrasea\Model\RecordInterface;
|
||||
use Symfony\Component\HttpFoundation\File\File as SymfoFile;
|
||||
use Alchemy\Phrasea\Core\PhraseaTokens;
|
||||
@@ -381,61 +382,6 @@ class record_adapter implements RecordInterface, cache_cacheableInterface
|
||||
return $this->getSubdfefByDeviceAndMime($devices, $mimes);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_status_icons()
|
||||
{
|
||||
$dstatus = databox_status::getDisplayStatus($this->app);
|
||||
$sbas_id = $this->get_sbas_id();
|
||||
|
||||
$status = '';
|
||||
|
||||
if (isset($dstatus[$sbas_id])) {
|
||||
foreach ($dstatus[$sbas_id] as $n => $statbit) {
|
||||
if ($statbit['printable'] == '0' &&
|
||||
!$this->app['acl']->get($this->app['authentication']->getUser())->has_right_on_base($this->base_id, 'chgstatus')) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$x = (substr((strrev($this->get_status())), $n, 1));
|
||||
|
||||
$source0 = "/skins/icons/spacer.gif";
|
||||
$style0 = "visibility:hidden;display:none;";
|
||||
$source1 = "/skins/icons/spacer.gif";
|
||||
$style1 = "visibility:hidden;display:none;";
|
||||
if ($statbit["img_on"]) {
|
||||
$source1 = $statbit["img_on"];
|
||||
$style1 = "visibility:auto;display:none;";
|
||||
}
|
||||
if ($statbit["img_off"]) {
|
||||
$source0 = $statbit["img_off"];
|
||||
$style0 = "visibility:auto;display:none;";
|
||||
}
|
||||
if ($x == '1') {
|
||||
if ($statbit["img_on"]) {
|
||||
$style1 = "visibility:auto;display:inline;";
|
||||
}
|
||||
} else {
|
||||
if ($statbit["img_off"]) {
|
||||
$style0 = "visibility:auto;display:inline;";
|
||||
}
|
||||
}
|
||||
$status .= '<img style="margin:1px;' . $style1 . '" ' .
|
||||
'class="STAT_' . $this->base_id . '_'
|
||||
. $this->record_id . '_' . $n . '_1" ' .
|
||||
'src="' . $source1 . '" title="' . $statbit['labels_on_i18n'][$this->app['locale']] . '"/>';
|
||||
$status .= '<img style="margin:1px;' . $style0 . '" ' .
|
||||
'class="STAT_' . $this->base_id . '_'
|
||||
. $this->record_id . '_' . $n . '_0" ' .
|
||||
'src="' . $source0 . '" title="' . $statbit['labels_off_i18n'][$this->app['locale']] . '"/>';
|
||||
}
|
||||
}
|
||||
|
||||
return $status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the type of the document
|
||||
*
|
||||
@@ -1601,8 +1547,6 @@ class record_adapter implements RecordInterface, cache_cacheableInterface
|
||||
}
|
||||
$databox = $this->get_databox();
|
||||
|
||||
\cache_databox::update($this->app, $this->get_sbas_id(), 'record', $this->get_record_id());
|
||||
|
||||
return $databox->delete_data_from_cache($this->get_cache_key($option));
|
||||
}
|
||||
|
||||
@@ -1947,9 +1891,9 @@ class record_adapter implements RecordInterface, cache_cacheableInterface
|
||||
}
|
||||
|
||||
/** {@inheritdoc} */
|
||||
public function getStatus()
|
||||
public function getStatusBitField()
|
||||
{
|
||||
return $this->get_status();
|
||||
return bindec($this->get_status());
|
||||
}
|
||||
|
||||
/** {@inheritdoc} */
|
||||
|
@@ -1,4 +1,4 @@
|
||||
{% set status = databox.get_statusbits() %}
|
||||
{% set statusStructure = databox.getStatusStructure() %}
|
||||
{% set databox_id = databox.get_sbas_id() %}
|
||||
|
||||
<h1>
|
||||
@@ -19,7 +19,7 @@
|
||||
<td>
|
||||
{{ bit }}
|
||||
</td>
|
||||
{% if attribute(status, bit) is defined %}
|
||||
{% if statusStructure.hasStatus(bit) %}
|
||||
<td>
|
||||
<a target="right" href="{{ path('database_display_statusbit_form', { 'databox_id' : databox_id, 'bit' : bit }) }}" class="ajax">
|
||||
<img class="editer" src="/skins/icons/edit_0.gif" />
|
||||
@@ -38,8 +38,8 @@
|
||||
</td>
|
||||
{% endif %}
|
||||
|
||||
{% if attribute(status, bit) is defined %}
|
||||
{% set statusbit = attribute(status, bit) %}
|
||||
{% if statusStructure.hasStatus(bit) %}
|
||||
{% set statusbit = statusStructure.getStatus(bit) %}
|
||||
<td>
|
||||
{% if statusbit['img_off'] %}
|
||||
<img title='{{ statusbit['labels_off_i18n'][app['locale']] }}' src='{{ statusbit['img_off'] }}' />
|
||||
|
@@ -195,7 +195,7 @@
|
||||
<img onclick="removeFilters({{ sbasId }});" id="filter_danger{{ sbasId }}" class="filter_danger" src="/skins/icons/alert.png" title="{{ "client::recherche: cliquez ici pour desactiver tous les filtres de cette base" | trans }}" style="vertical-align:bottom;width:12px;height:12px;display:none;"/>
|
||||
</div>
|
||||
{% set status_bit_filters = '' %}
|
||||
{% for bit, data in databox.get_statusbits() if data['searchable'] %}
|
||||
{% for bit, data in databox.getStatusStructure.getStatuses if data['searchable'] %}
|
||||
{% set html_status_bit %}
|
||||
<div style="text-align:center;overflow:hidden;">
|
||||
<table style="table-layout:fixed;width:90%;text-align:left;" cellspacing="0" cellpadding="0">
|
||||
|
@@ -4,6 +4,14 @@
|
||||
|
||||
<div id='tabs-records-property'>
|
||||
|
||||
{# if multi databox edit abort #}
|
||||
{% if records.databoxes() | length > 1 %}
|
||||
<div class="well-small">
|
||||
{{ 'prod::Les enregistrements ne provienent pas tous de la meme base et ne peuvent donc etre traites ensemble' | trans }}
|
||||
</div>
|
||||
{% else %}
|
||||
|
||||
{% set databox = records.databoxes|first %}
|
||||
{# This value is fetched when click on 2nd tab #}
|
||||
<input type="hidden" name='original_selection' value="{{ app.request.query.get('lst') }}">
|
||||
|
||||
@@ -38,11 +46,8 @@
|
||||
|
||||
<form style='padding:15px;' name="change-records-status" action="{{ path('change_status') }}" method="POST">
|
||||
<input name="lst" type="hidden" value="{{ records.serializedList() }}"/>
|
||||
{% for databox in records.databoxes() %}
|
||||
{% set sbasId = databox.get_sbas_id() %}
|
||||
{% set nbItems = attribute(nRec, sbasId) %}
|
||||
{% set nbRecords = nbItems['records'] %}
|
||||
{% set nbStories = nbItems['stories'] %}
|
||||
|
||||
<table style='width:auto;margin:0 auto'>
|
||||
<thead>
|
||||
<tr>
|
||||
@@ -54,22 +59,10 @@
|
||||
<tbody>
|
||||
<tr style='border-bottom:1px solid #FFF;'>
|
||||
<td colspan="6" style='font-size:11px;text-align:center'>
|
||||
{% if nbRecords == 0 and nbStories > 0 %}
|
||||
<i>({% trans %}Stories status edition{% endtrans %})</i>
|
||||
{% elseif nbRecords > 0 and nbStories == 0 %}
|
||||
<i>({% trans %}Records status edition{% endtrans %})</i>
|
||||
{% endif %}
|
||||
{% trans %}Status edition{% endtrans %}</i>
|
||||
</td>
|
||||
</tr>
|
||||
{% set databoxStatus = attribute(statusBit, sbasId) %}
|
||||
{% for bit,values in databoxStatus %}
|
||||
{% set inverse = 0 %}
|
||||
|
||||
{% if values["status"] == "2" %}
|
||||
{% set inverse = 2 %}
|
||||
{% elseif values["status"] == "0" %}
|
||||
{% set inverse = 1 %}
|
||||
{% endif %}
|
||||
{% for bit,values in status %}
|
||||
<tr>
|
||||
<td style='text-align:right'>
|
||||
{% if values['img_off'] is not empty %}
|
||||
@@ -79,18 +72,18 @@
|
||||
{% endif %}
|
||||
</td>
|
||||
<td style='text-align:right'>
|
||||
<label for="status-radio-{{ sbasId ~ "-" ~ bit ~ '-off'}}" {% if inverse == 2 %}style='color:#FF3333'{% endif%}>
|
||||
<label for="status-radio-{{ sbasId ~ "-" ~ bit ~ '-off'}}" {% if values['flag'] == 2 %}style='color:#FF3333'{% endif%}>
|
||||
{{ values['labels_off_i18n'][app['locale']] }}
|
||||
</label>
|
||||
</td>
|
||||
<td style='text-align:right'>
|
||||
<input id="status-radio-{{ sbasId ~ "-" ~ bit ~ '-off'}}" type="radio" name="status[{{ sbasId }}][{{ bit }}]" value="0" {% if inverse == 1 %}checked="checked"{% endif %}/>
|
||||
<input id="status-radio-{{ sbasId ~ "-" ~ bit ~ '-off'}}" type="radio" name="status[{{ sbasId }}][{{ bit }}]" {% if values['flag'] == 0 %}checked="checked"{% endif%} value="0"/>
|
||||
</td>
|
||||
<td style='text-align:left'>
|
||||
<input id="status-radio-{{ sbasId ~ "-" ~ bit ~ '-on'}}" type="radio" name="status[{{ sbasId }}][{{ bit }}]" value="1" {% if inverse == 0 %}checked="checked"{% endif %}/>
|
||||
<input id="status-radio-{{ sbasId ~ "-" ~ bit ~ '-on'}}" type="radio" name="status[{{ sbasId }}][{{ bit }}]" {% if values['flag'] == 1 %}checked="checked"{% endif%} value="1"/>
|
||||
</td>
|
||||
<td style='text-align:left'>
|
||||
<label for="status-radio-{{ sbasId ~ "-" ~ bit ~ '-on'}}" {% if inverse == 2 %}style='color:#FF3333'{% endif%}>
|
||||
<label for="status-radio-{{ sbasId ~ "-" ~ bit ~ '-on'}}" {% if values['flag'] == 2 %}style='color:#FF3333'{% endif%}>
|
||||
{{ values['labels_on_i18n'][app['locale']] }}
|
||||
</label>
|
||||
</td>
|
||||
@@ -105,21 +98,16 @@
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
<tfoot>
|
||||
{% if nbStories > 0 %}
|
||||
{% if records.stories.count > 0 %}
|
||||
<tr>
|
||||
<td colspan="6">
|
||||
<input type="checkbox" name="apply_to_children[{{ sbasId }}]"/>
|
||||
{% if nbStories == 1 %}
|
||||
{% trans %}Apply status on stories children.{% endtrans %}
|
||||
{% elseif nbStories > 0 %}
|
||||
{% trans %}Apply status on story children.{% endtrans %}
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
</tfoot>
|
||||
</table>
|
||||
{% endfor %}
|
||||
<div class="form-actions" style="background:transparent">
|
||||
{% if nbEditableDocuments > 0 %}
|
||||
<button type="button" class="btn btn-primary submiter">{{ "Apply changes" | trans }}</button>
|
||||
@@ -131,9 +119,9 @@
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function(){
|
||||
$("#tabs-records-property").tabs({
|
||||
beforeLoad: function( event, ui ) {
|
||||
@@ -190,4 +178,5 @@
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</script>
|
||||
{% endif %}
|
||||
|
@@ -379,34 +379,32 @@
|
||||
<div class="status_filter">
|
||||
<span>{{ 'Status des documents a rechercher' | trans }}</span>
|
||||
<table style="width: 100%;">
|
||||
{% for sbas_id, bits in search_status %}
|
||||
{% for n, bit in bits %}
|
||||
{% for databox_id, flag in search_status %}
|
||||
<tr>
|
||||
<td>
|
||||
{% if bit['imgoff'] %}
|
||||
<img src="{{bit['imgoff']}}" title="{{bit['labels_off_i18n'][app['locale']]}}" />
|
||||
{% endif %}
|
||||
<label class="checkbox inline">
|
||||
<input onchange="checkFilters(true);" class="field_switch field_{{sbas_id}}"
|
||||
{% if flag['img_off'] %}
|
||||
<img src="{{flag['img_off']}}" title="{{flag['labels_off_i18n'][app['locale']]}}" />
|
||||
{% endif %}
|
||||
<input onchange="checkFilters(true);" class="field_switch field_{{databox_id}}"
|
||||
type="checkbox" value="0"
|
||||
n="{{n}}" name="status[{{sbas_id}}][{{n}}]" />
|
||||
{{bit['labels_off_i18n'][app['locale']]}}
|
||||
n="{{flag['bit']}}" name="status[{{databox_id}}][{{flag['bit']}}]" />
|
||||
{{flag['labels_off_i18n'][app['locale']]}}
|
||||
</label>
|
||||
</td>
|
||||
<td>
|
||||
{% if bit['imgon'] %}
|
||||
<img src="{{bit['imgon']}}" title="{{bit['labels_on_i18n'][app['locale']]}}" />
|
||||
{% endif %}
|
||||
<label class="checkbox inline">
|
||||
<input onchange="checkFilters(true);" class="field_switch field_{{sbas_id}}"
|
||||
{% if flag['img_on'] %}
|
||||
<img src="{{flag['img_on']}}" title="{{flag['labels_on_i18n'][app['locale']]}}" />
|
||||
{% endif %}
|
||||
<input onchange="checkFilters(true);" class="field_switch field_{{databox_id}}"
|
||||
type="checkbox" value="1"
|
||||
n="{{n}}" name="status[{{sbas_id}}][{{n}}]"/>
|
||||
{{bit['labels_on_i18n'][app['locale']]}}
|
||||
n="{{flag['bit']}}" name="status[{{databox_id}}][{{flag['bit']}}]"/>
|
||||
{{flag['labels_on_i18n'][app['locale']]}}
|
||||
</label>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
</table>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
@@ -12,8 +12,9 @@
|
||||
{{ record.title }}
|
||||
</div>
|
||||
<div class="status">
|
||||
{# @todo find a proper way to map lifted flag to status icon img path #}
|
||||
{#{{record.get_status_icons|raw}}#}
|
||||
{% for flag in record_flags(record) %}
|
||||
<img src="{{ flag.path }}" title="{{ attribute(flag.labels, app.locale) }}" />
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@@ -66,7 +66,7 @@
|
||||
<h5>{{ 'upload:: Status :' | trans }} :</h5>
|
||||
<table class="status-tab">
|
||||
<tbody>
|
||||
{% for bit, status in availableCollections['databox'].get_statusbits() %}
|
||||
{% for bit, status in availableCollections['databox'].getStatusStructure() %}
|
||||
<tr>
|
||||
<td class="status-tab-left">
|
||||
{% if status['img_off'] is not empty %}
|
||||
|
@@ -71,7 +71,7 @@
|
||||
<h5>{{ 'upload:: Status :' | trans }} :</h5>
|
||||
<table class="status-tab">
|
||||
<tbody>
|
||||
{% for bit, status in availableCollections['databox'].get_statusbits() %}
|
||||
{% for bit, status in availableCollections['databox'].getStatusStructure() %}
|
||||
<tr>
|
||||
<td class="status-tab-left">
|
||||
{% if status['img_off'] is not empty %}
|
||||
|
@@ -197,8 +197,6 @@ function checkFilters(save) {
|
||||
|
||||
$('input.field_switch:checked', container).removeAttr('checked');
|
||||
|
||||
$('input.field_switch:checkbox', container).parent().hide();
|
||||
|
||||
filters.removeClass('danger');
|
||||
|
||||
var nbSelectedColls = 0;
|
||||
|
Reference in New Issue
Block a user