mirror of
https://github.com/alchemy-fr/Phraseanet.git
synced 2025-10-14 21:43:18 +00:00
Refactor record property (status, type)
update property route Fixed status Conflicts: lib/Alchemy/Phrasea/Controller/Prod/Record/Property.php
This commit is contained in:
@@ -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;
|
||||
|
@@ -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());
|
||||
|
205
lib/Alchemy/Phrasea/Controller/Prod/Record/Property.php
Normal file
205
lib/Alchemy/Phrasea/Controller/Prod/Record/Property.php
Normal file
@@ -0,0 +1,205 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Phraseanet
|
||||
*
|
||||
* (c) 2005-2012 Alchemy
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Alchemy\Phrasea\Controller\Prod\Record;
|
||||
|
||||
use Alchemy\Phrasea\Controller\RecordsRequest;
|
||||
use Silex\Application;
|
||||
use Silex\ControllerProviderInterface;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
/**
|
||||
*
|
||||
* @license http://opensource.org/licenses/gpl-3.0 GPLv3
|
||||
* @link www.phraseanet.com
|
||||
*/
|
||||
class Property implements ControllerProviderInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function connect(Application $app)
|
||||
{
|
||||
$controllers = $app['controllers_factory'];
|
||||
|
||||
$controllers->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);
|
||||
}
|
||||
}
|
@@ -1,4 +1,4 @@
|
||||
<?php
|
||||
<?php //
|
||||
|
||||
use Alchemy\Phrasea\Application;
|
||||
|
||||
|
@@ -1298,7 +1298,7 @@ class record_adapter implements record_Interface, cache_cacheableInterface
|
||||
$stmt->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();
|
||||
|
148
templates/web/prod/actions/Property/index.html.twig
Normal file
148
templates/web/prod/actions/Property/index.html.twig
Normal file
@@ -0,0 +1,148 @@
|
||||
{% set nbReceivedDocuments = records.received().count() %}
|
||||
{% set nbEditableDocuments = records.count() %}
|
||||
|
||||
<div id='tabs-records-property'>
|
||||
<ul>
|
||||
<li><a href="#property-statut">{% trans 'Records Statut' %}</a></li>
|
||||
<li><a href="#property-type">{% trans 'Records type' %}</a></li>
|
||||
</ul>
|
||||
|
||||
<div id='property-statut'>
|
||||
<p class="header" style='text-align:center;'>
|
||||
<h4>
|
||||
{% 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 %}
|
||||
</h4>
|
||||
</p>
|
||||
|
||||
<form style='padding:15px;' name="change-records-status" action="/prod/records/property/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>
|
||||
<th colspan="6">
|
||||
{{ databox.get_viewname()|title }}
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td colspan="6" style='font-size:11px;'>
|
||||
{% if nbRecords == 0 and nbStories > 0 %}
|
||||
<i>({% trans %}Status edition of stories{% endtrans %})</i>
|
||||
{% elseif nbRecords > 0 and nbStories == 0 %}
|
||||
<i>({% trans %}Status edition of documents{% endtrans %})</i>
|
||||
{% endif %}
|
||||
</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 %}
|
||||
<tr>
|
||||
<td colspan="6">
|
||||
<h6>{{ values['name']|title }}</h6>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style='text-align:right'>
|
||||
{% if values['img_off'] is not empty %}
|
||||
<label for="status-radio-{{ sbasId ~ "-" ~ bit ~ '-off'}}">
|
||||
<img src="{{ values['img_off'] }}" width="16" height="16" />
|
||||
</label>
|
||||
{% endif %}
|
||||
</td>
|
||||
<td style='text-align:right'>
|
||||
<label for="status-radio-{{ sbasId ~ "-" ~ bit ~ '-off'}}">
|
||||
{{ values['labeloff']|default('off') }}
|
||||
</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 %}/>
|
||||
</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 %}/>
|
||||
</td>
|
||||
<td style='text-align:left'>
|
||||
<label for="status-radio-{{ sbasId ~ "-" ~ bit ~ '-on'}}">
|
||||
{{ values['labelon']|default('on') }}
|
||||
</label>
|
||||
</td>
|
||||
<td style='text-align:left'>
|
||||
{% if values['img_on'] is not empty %}
|
||||
<label for="status-radio-{{ sbasId ~ "-" ~ bit ~ '-on'}}">
|
||||
<img src="{{ values['img_on'] }}" width="16" height="16" />
|
||||
</label>
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
<tfoot>
|
||||
{% if nbStories > 0 %}
|
||||
<tr>
|
||||
<td colspan="6"><input type="checkbox" name="apply_to_children[{{ sbasId }}]"/></td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
</tfoot>
|
||||
</table>
|
||||
{% endfor %}
|
||||
<div class="form-actions">
|
||||
<button type="button" class="btn btn-primary submiter">{% trans "Apply changes" %}</button>
|
||||
<button type="button" class="btn">{% trans "Cancel" %}</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div id='property-type'>TODO</div>
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function(){
|
||||
$("#tabs-records-property").tabs();
|
||||
var $dialog = p4.Dialog.get(1);
|
||||
var $dialogBox = $dialog.getDomElement();
|
||||
|
||||
var form = $("form[name=change-records-status]", $dialogBox);
|
||||
var button = $(".submiter", form);
|
||||
|
||||
button.bind("click", function(){
|
||||
$.ajax({
|
||||
type: form.attr("method"),
|
||||
url: form.attr("action"),
|
||||
data: form.serializeArray(),
|
||||
dataType: 'json',
|
||||
beforeSend:function(){
|
||||
button.attr("disabled", true);
|
||||
//@todo add loader
|
||||
},
|
||||
success: function(data){
|
||||
$dialog.Close(1);
|
||||
},
|
||||
complete: function(){
|
||||
button.attr("disabled", false);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
@@ -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]
|
||||
|
@@ -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();
|
||||
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_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_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'))
|
||||
{
|
||||
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();
|
||||
} 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);
|
||||
}
|
||||
});
|
||||
|
Reference in New Issue
Block a user