diff --git a/config/nginx.rewrite.rules b/config/nginx.rewrite.rules index 2be618bda7..2421d150c4 100644 --- a/config/nginx.rewrite.rules +++ b/config/nginx.rewrite.rules @@ -14,6 +14,7 @@ rewrite ^/developers/.*$ /index.php last; rewrite ^/permalink/.*$ /index.php last; rewrite ^/datafiles/.*$ /index.php last; rewrite ^/prod/records/edit/.*$ /index.php last; +rewrite ^/prod/records/property/.*$ /index.php last; rewrite ^/prod/records/movecollection/.*$ /index.php last; rewrite ^/prod/records/delete/.*$ /index.php last; rewrite ^/prod/order/.*$ /index.php last; diff --git a/lib/Alchemy/Phrasea/Application/Root.php b/lib/Alchemy/Phrasea/Application/Root.php index 3c93edf042..88e3e5bad4 100644 --- a/lib/Alchemy/Phrasea/Application/Root.php +++ b/lib/Alchemy/Phrasea/Application/Root.php @@ -44,6 +44,7 @@ use Alchemy\Phrasea\Controller\Prod\Order; use Alchemy\Phrasea\Controller\Prod\Printer; use Alchemy\Phrasea\Controller\Prod\Push; use Alchemy\Phrasea\Controller\Prod\Query; +use Alchemy\Phrasea\Controller\Prod\Record\Property; use Alchemy\Phrasea\Controller\Prod\Root as Prod; use Alchemy\Phrasea\Controller\Prod\Story; use Alchemy\Phrasea\Controller\Prod\Tools; @@ -135,6 +136,7 @@ return call_user_func(function($environment = null) { $app->mount('/prod/lists', new UsrLists()); $app->mount('/prod/MustacheLoader', new MustacheLoader()); $app->mount('/prod/records/edit', new Edit()); + $app->mount('/prod/records/property', new Property()); $app->mount('/prod/records/movecollection', new MoveCollection()); $app->mount('/prod/bridge/', new Bridge()); $app->mount('/prod/push/', new Push()); diff --git a/lib/Alchemy/Phrasea/Controller/Prod/Record/Property.php b/lib/Alchemy/Phrasea/Controller/Prod/Record/Property.php new file mode 100644 index 0000000000..0e82a42461 --- /dev/null +++ b/lib/Alchemy/Phrasea/Controller/Prod/Record/Property.php @@ -0,0 +1,205 @@ +before(function(Request $request) use ($app) { + $response = $app['firewall']->requireNotGuest(); + if ($response instanceof Response) { + return $response; + } + }); + + $controllers->get('/', $this->call('displayProperty')) + ->bind('display_property'); + + $controllers->post('/status/', $this->call('changeStatus')) + ->bind('change_status'); + + return $controllers; + } + + /** + * Display property + * + * @param Application $app + * @param Request $request + * @return Response + */ + public function displayProperty(Application $app, Request $request) + { + if (!$request->isXmlHttpRequest()) { + $app->abort(400); + } + + $records = RecordsRequest::fromRequest($app, $request, false, array('chgstatus')); + $databoxStatus = \databox_status::getDisplayStatus($app); + $statusBit = $recordsType = $nRec = $toRemove = array(); + + foreach ($records as $key => $record) { + if (!$app['phraseanet.user']->ACL()->has_hd_grant($record) || + !$app['phraseanet.user']->ACL()->has_preview_grant($record)) { + try { + $conn = $record->get_databox()->get_connection(); + + $sql = sprintf('SELECT record_id FROM record WHERE ((status ^ %s) & %s) = 0 AND record_id = :record_id', $app['phraseanet.user']->ACL()->get_mask_xor($record->get_base_id()), $app['phraseanet.user']->ACL()->get_mask_and($record->get_base_id())); + + $stmt = $conn->prepare($sql); + $stmt->execute(array(':record_id' => $record->get_record_id())); + + if (0 === $stmt->rowCount()) { + $toRemove[] = $key; + } + + $stmt->closeCursor(); + unset($stmt); + } catch (Exception $e) { + $toRemove[] = $key; + } + } + } + + foreach ($toRemove as $key) { + $records->remove($key); + } + + foreach ($records as $record) { + $sbasId = $record->get_databox()->get_sbas_id(); + + if (!isset($nRec[$sbasId])) { + $nRec[$sbasId] = array('stories' => 0, 'records' => 0); + } + + $nRec[$sbasId]['records']++; + + if ($record->is_grouping()) { + $nRec[$sbasId]['stories']++; + } + + if (!isset($recordsType[$sbasId])) { + $recordsType[$sbasId] = array(); + } + + if (!isset($recordsType[$sbasId][$record->get_type()])) { + $recordsType[$sbasId][$record->get_type()] = array(); + } + + $recordsType[$sbasId][$record->get_type()] = $record; + + if (!isset($statusBit[$sbasId])) { + + $statusBit[$sbasId] = isset($databoxStatus[$sbasId]) ? $databoxStatus[$sbasId] : array(); + + foreach (array_keys($statusBit[$sbasId]) as $bit) { + $statusBit[$sbasId][$bit]['nset'] = 0; + } + } + + $status = strrev($record->get_status()); + + foreach (array_keys($statusBit[$sbasId]) as $bit) { + $statusBit[$sbasId][$bit]["nset"] += substr($status, $bit, 1) !== "0" ? 1 : 0; + } + } + + 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 $app['twig']->render('prod/actions/Property/index.html.twig', array( + 'records' => $records, + 'statusBit' => $statusBit, + 'recordsType' => $recordsType, + 'nRec' => $nRec + )); + } + + public function changeStatus(Application $app, Request $request) + { + $applyStatusToChildren = $request->request->get('apply_to_children', array()); + $records = RecordsRequest::fromRequest($app, $request, false, array('chgstatus')); + $updated = array(); + $postStatus = $request->request->get('status'); + + foreach ($records as $record) { + $sbasId = $record->get_databox()->get_sbas_id(); + + //update record + $updated[$record->get_serialize_key()] = $this->updateRecordStatus($record, $postStatus); + + //update children if current record is a story + if (isset($applyStatusToChildren[$sbasId]) && $record->is_grouping()) { + foreach ($record->get_children() as $child) { + $updated[$record->get_serialize_key()] = $this->updateRecordStatus($child, $postStatus); + } + } + } + + return $app->json(array('success' => true, 'updated' => $updated), 201); + } + + private function updateRecordStatus(\record_adapter $record, Array $postStatus) + { + $sbasId = $record->get_databox()->get_sbas_id(); + + if (isset($postStatus[$sbasId]) && is_array($postStatus[$sbasId])) { + $postStatus = $postStatus[$sbasId]; + $currentStatus = strrev($record->get_status()); + + $newStatus = ''; + foreach (range(0, 63) as $i) { + $newStatus .= isset($postStatus[$i]) ? ($postStatus[$i] ? '1' : '0') : $currentStatus[$i]; + } + + $record->set_binary_status(strrev($newStatus)); + + return array( + 'current_status' => $currentStatus, + 'new_status' => $newStatus + ); + } + } + + /** + * Prefix the method to call with the controller class name + * + * @param string $method The method to call + * @return string + */ + private function call($method) + { + return sprintf('%s::%s', __CLASS__, $method); + } +} diff --git a/lib/classes/liste.class.php b/lib/classes/liste.class.php index fd6c41008b..e3e190dbe1 100644 --- a/lib/classes/liste.class.php +++ b/lib/classes/liste.class.php @@ -1,4 +1,4 @@ -closeCursor(); try { - $sphinx = sphinxrt::get_instance(); + $sphinx = sphinxrt::get_instance($this->app['phraseanet.registry']); $sbas_params = phrasea::sbas_params($this->app); $sbas_id = $this->get_sbas_id(); diff --git a/templates/web/prod/actions/Property/index.html.twig b/templates/web/prod/actions/Property/index.html.twig new file mode 100644 index 0000000000..fe697a053a --- /dev/null +++ b/templates/web/prod/actions/Property/index.html.twig @@ -0,0 +1,148 @@ +{% set nbReceivedDocuments = records.received().count() %} +{% set nbEditableDocuments = records.count() %} + +
+ + +
+

+

+ {% trans %} + You have selected one document. + {% plural nbReceivedDocuments %} + You have selected {{ nbReceivedDocuments }} documents. + {% endtrans %} + + {% if nbEditableDocuments < nbReceivedDocuments %} + {% trans %} + Only one document is editable. + {% plural nbEditableDocuments %} + Only {{ nbEditableDocuments }} documents are editable. + {% endtrans %} + {% endif %} +

+

+ +
+ + {% for databox in records.databoxes() %} + {% set sbasId = databox.get_sbas_id() %} + {% set nbItems = attribute(nRec, sbasId) %} + {% set nbRecords = nbItems['records'] %} + {% set nbStories = nbItems['stories'] %} + + + + + + + + + + + {% 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 %} + + + + + + + + + + + + {% endfor %} + + + {% if nbStories > 0 %} + + + + {% endif %} + +
+ {{ databox.get_viewname()|title }} +
+ {% if nbRecords == 0 and nbStories > 0 %} + ({% trans %}Status edition of stories{% endtrans %}) + {% elseif nbRecords > 0 and nbStories == 0 %} + ({% trans %}Status edition of documents{% endtrans %}) + {% endif %} +
+
{{ values['name']|title }}
+
+ {% if values['img_off'] is not empty %} + + {% endif %} + + + + + + + + + + {% if values['img_on'] is not empty %} + + {% endif %} +
+ {% endfor %} +
+ + +
+
+
+
TODO
+
+ + \ No newline at end of file diff --git a/www/.htaccess b/www/.htaccess index 0d36074e32..f781bbb579 100644 --- a/www/.htaccess +++ b/www/.htaccess @@ -16,6 +16,7 @@ RewriteRule ^developers/.*$ /index.php [L] RewriteRule ^login/.*$ /index.php [L] RewriteRule ^prod/records/edit/.*$ /index.php [L] + RewriteRule ^prod/records/property/.*$ /index.php [L] RewriteRule ^prod/records/movecollection/.*$ /index.php [L] RewriteRule ^prod/records/delete/.*$ /index.php [L] RewriteRule ^prod/order/.*$ /index.php [L] diff --git a/www/prod/page0.js b/www/prod/page0.js index ffe9cb3e02..978c4193b4 100644 --- a/www/prod/page0.js +++ b/www/prod/page0.js @@ -1703,29 +1703,29 @@ function chgCollThis(datas) }); } -function chgStatusThis(url) -{ - url = "docfunction.php?"+url; - $('#MODALDL').attr('src','about:blank'); - $('#MODALDL').attr('src',url); - - - var t = (bodySize.y - 400) / 2; - var l = (bodySize.x - 550) / 2; - - $('#MODALDL').css({ - 'display': 'block', - 'opacity': 0, - 'width': '550px', - 'position': 'absolute', - 'top': t, - 'left': l, - 'height': '400px' - }).fadeTo(500, 1); - - showOverlay(2); - $('#tooltip').hide(); -} +//function chgStatusThis(url) +//{ +// url = "docfunction.php?"+url; +// $('#MODALDL').attr('src','about:blank'); +// $('#MODALDL').attr('src',url); +// +// +// var t = (bodySize.y - 400) / 2; +// var l = (bodySize.x - 550) / 2; +// +// $('#MODALDL').css({ +// 'display': 'block', +// 'opacity': 0, +// 'width': '550px', +// 'position': 'absolute', +// 'top': t, +// 'left': l, +// 'height': '400px' +// }).fadeTo(500, 1); +// +// showOverlay(2); +// $('#tooltip').hide(); +//} function pushThis(sstt_id, lst, story) @@ -2152,52 +2152,39 @@ function activeIcons() }); $('.TOOL_chgstatus_btn').live('click', 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 = "SSTTID=" + $('.SSTT.active').attr('id').split('_').slice(1,2).pop(); + var params = {}; + var $this = $(this); + console.log(p4.Results.Selection.length()); + if ($this.hasClass('results_window')) { + if (p4.Results.Selection.length() > 0) { + params.lst = p4.Results.Selection.serialize(); } - else - { - if($(this).hasClass('basket_element')) - { - value = "SSTTID=" + $('.SSTT.active').attr('id').split('_').slice(1,2).pop(); + } 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('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(); + } 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(value !== '') - { - chgStatusThis(value); - } - else - { + if (false === $.isEmptyObject(params)) { + var dialog = p4.Dialog.Create(); + dialog.load('/prod/records/property/', 'GET', params); + } else { alert(language.nodocselected); } });