mirror of
https://github.com/alchemy-fr/Phraseanet.git
synced 2025-10-22 17:33:12 +00:00
Merge pull request #3425 from alchemy-fr/PHRAS-3006_Port41_Front_delete_3_by_3
PHRAS-3006 #comment merge Port to 41 : front delete 3 by 3
This commit is contained in:
@@ -7,6 +7,7 @@
|
|||||||
* For the full copyright and license information, please view the LICENSE
|
* For the full copyright and license information, please view the LICENSE
|
||||||
* file that was distributed with this source code.
|
* file that was distributed with this source code.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace Alchemy\Phrasea\Controller\Prod;
|
namespace Alchemy\Phrasea\Controller\Prod;
|
||||||
|
|
||||||
use Alchemy\Phrasea\Application;
|
use Alchemy\Phrasea\Application;
|
||||||
@@ -24,6 +25,7 @@ use Alchemy\Phrasea\Model\Repositories\StoryWZRepository;
|
|||||||
use Alchemy\Phrasea\SearchEngine\SearchEngineOptions;
|
use Alchemy\Phrasea\SearchEngine\SearchEngineOptions;
|
||||||
use Alchemy\Phrasea\Twig\Fit;
|
use Alchemy\Phrasea\Twig\Fit;
|
||||||
use Alchemy\Phrasea\Twig\PhraseanetExtension;
|
use Alchemy\Phrasea\Twig\PhraseanetExtension;
|
||||||
|
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
use Symfony\Component\HttpFoundation\Response;
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
|
|
||||||
@@ -36,7 +38,7 @@ class RecordController extends Controller
|
|||||||
*
|
*
|
||||||
* @param Request $request
|
* @param Request $request
|
||||||
*
|
*
|
||||||
* @return Response
|
* @return \Symfony\Component\HttpFoundation\JsonResponse
|
||||||
*/
|
*/
|
||||||
public function getRecord(Request $request)
|
public function getRecord(Request $request)
|
||||||
{
|
{
|
||||||
@@ -194,7 +196,8 @@ class RecordController extends Controller
|
|||||||
$flatten = (bool)($request->request->get('del_children')) ? RecordsRequest::FLATTEN_YES_PRESERVE_STORIES : RecordsRequest::FLATTEN_NO;
|
$flatten = (bool)($request->request->get('del_children')) ? RecordsRequest::FLATTEN_YES_PRESERVE_STORIES : RecordsRequest::FLATTEN_NO;
|
||||||
$records = RecordsRequest::fromRequest(
|
$records = RecordsRequest::fromRequest(
|
||||||
$this->app,
|
$this->app,
|
||||||
$request,$flatten,
|
$request,
|
||||||
|
$flatten,
|
||||||
[\ACL::CANDELETERECORD]
|
[\ACL::CANDELETERECORD]
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -224,16 +227,16 @@ class RecordController extends Controller
|
|||||||
$manager->remove($attachedStory);
|
$manager->remove($attachedStory);
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach($record->get_grouping_parents() as $story) {
|
foreach ($record->get_grouping_parents() as $story) {
|
||||||
$this->getEventDispatcher()->dispatch(PhraseaEvents::RECORD_EDIT, new RecordEdit($story));
|
$this->getEventDispatcher()->dispatch(PhraseaEvents::RECORD_EDIT, new RecordEdit($story));
|
||||||
}
|
}
|
||||||
|
|
||||||
$sbasId = $record->getDatabox()->get_sbas_id();
|
$sbasId = $record->getDatabox()->get_sbas_id();
|
||||||
if(!array_key_exists($sbasId, $trashCollectionsBySbasId)) {
|
if (!array_key_exists($sbasId, $trashCollectionsBySbasId)) {
|
||||||
$trashCollectionsBySbasId[$sbasId] = $record->getDatabox()->getTrashCollection();
|
$trashCollectionsBySbasId[$sbasId] = $record->getDatabox()->getTrashCollection();
|
||||||
}
|
}
|
||||||
$deleted[] = $record->getId();
|
$deleted[] = $record->getId();
|
||||||
if($trashCollectionsBySbasId[$sbasId] !== null) {
|
if ($trashCollectionsBySbasId[$sbasId] !== null) {
|
||||||
if($record->getCollection()->get_coll_id() == $trashCollectionsBySbasId[$sbasId]->get_coll_id()) {
|
if($record->getCollection()->get_coll_id() == $trashCollectionsBySbasId[$sbasId]->get_coll_id()) {
|
||||||
// record is already in trash so delete it
|
// record is already in trash so delete it
|
||||||
$this->getEventDispatcher()->dispatch(RecordEvents::DELETE, new DeleteEvent($record));
|
$this->getEventDispatcher()->dispatch(RecordEvents::DELETE, new DeleteEvent($record));
|
||||||
@@ -280,35 +283,69 @@ class RecordController extends Controller
|
|||||||
* Delete a record or a list of records
|
* Delete a record or a list of records
|
||||||
*
|
*
|
||||||
* @param Request $request
|
* @param Request $request
|
||||||
* @return Response
|
* @return string html
|
||||||
*/
|
*/
|
||||||
public function whatCanIDelete(Request $request)
|
public function whatCanIDelete(Request $request)
|
||||||
{
|
{
|
||||||
|
$viewParms = [];
|
||||||
|
|
||||||
|
// pre-count records that would be trashed/deleted when the "deleted children" will be un-checked
|
||||||
|
|
||||||
$records = RecordsRequest::fromRequest(
|
$records = RecordsRequest::fromRequest(
|
||||||
$this->app,
|
$this->app,
|
||||||
$request,
|
$request,
|
||||||
!!$request->request->get('del_children'),
|
RecordsRequest::FLATTEN_NO,
|
||||||
[\ACL::CANDELETERECORD]
|
[\ACL::CANDELETERECORD]
|
||||||
);
|
);
|
||||||
|
|
||||||
$filteredRecord = $this->filterRecordToDelete($records);
|
$filteredRecords = $this->filterRecordToDelete($records);
|
||||||
|
|
||||||
return $this->app->json([
|
$viewParms['parents_only'] = [
|
||||||
'renderView' => $this->render('prod/actions/delete_records_confirm.html.twig', [
|
'records' => $records,
|
||||||
'records' => $records,
|
'trashableCount' => count($filteredRecords['trash']),
|
||||||
'filteredRecord' => $filteredRecord
|
'deletableCount' => count($filteredRecords['delete'])
|
||||||
]),
|
];
|
||||||
'filteredRecord' => $filteredRecord
|
|
||||||
]);
|
// pre-count records that would be trashed/deleted when the "deleted children" will be checked
|
||||||
|
//
|
||||||
|
$records = RecordsRequest::fromRequest(
|
||||||
|
$this->app,
|
||||||
|
$request,
|
||||||
|
RecordsRequest::FLATTEN_YES_PRESERVE_STORIES,
|
||||||
|
[\ACL::CANDELETERECORD]
|
||||||
|
);
|
||||||
|
$filteredRecords = $this->filterRecordToDelete($records);
|
||||||
|
$viewParms['with_children'] = [
|
||||||
|
'records' => $records,
|
||||||
|
'trashableCount' => count($filteredRecords['trash']),
|
||||||
|
'deletableCount' => count($filteredRecords['delete'])
|
||||||
|
];
|
||||||
|
|
||||||
|
return $this->render(
|
||||||
|
'prod/actions/delete_records_confirm.html.twig',
|
||||||
|
$viewParms
|
||||||
|
);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* classifies records in two groups (does NOT delete anything)
|
||||||
|
* - 'trash' : the record can go to trash because the db has a "_TRASH_" coll, and the record is not already into it
|
||||||
|
* - 'delete' : the record would be deleted because the db has no trash, or the record is already trashed
|
||||||
|
*
|
||||||
|
* @param RecordsRequest $records
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
private function filterRecordToDelete(RecordsRequest $records)
|
private function filterRecordToDelete(RecordsRequest $records)
|
||||||
{
|
{
|
||||||
|
$ret = [
|
||||||
|
'trash' => [],
|
||||||
|
'delete' => []
|
||||||
|
];
|
||||||
|
|
||||||
$trashCollectionsBySbasId = [];
|
$trashCollectionsBySbasId = [];
|
||||||
$goingToTrash = [];
|
|
||||||
$delete = [];
|
|
||||||
foreach ($records as $record) {
|
foreach ($records as $record) {
|
||||||
|
/** @var \record_adapter $record */
|
||||||
$sbasId = $record->getDatabox()->get_sbas_id();
|
$sbasId = $record->getDatabox()->get_sbas_id();
|
||||||
if (!array_key_exists($sbasId, $trashCollectionsBySbasId)) {
|
if (!array_key_exists($sbasId, $trashCollectionsBySbasId)) {
|
||||||
$trashCollectionsBySbasId[$sbasId] = $record->getDatabox()->getTrashCollection();
|
$trashCollectionsBySbasId[$sbasId] = $record->getDatabox()->getTrashCollection();
|
||||||
@@ -316,21 +353,20 @@ class RecordController extends Controller
|
|||||||
if ($trashCollectionsBySbasId[$sbasId] !== null) {
|
if ($trashCollectionsBySbasId[$sbasId] !== null) {
|
||||||
if ($record->getCollection()->get_coll_id() == $trashCollectionsBySbasId[$sbasId]->get_coll_id()) {
|
if ($record->getCollection()->get_coll_id() == $trashCollectionsBySbasId[$sbasId]->get_coll_id()) {
|
||||||
// record is already in trash
|
// record is already in trash
|
||||||
$delete[] = $record;
|
$ret['delete'][] = $record;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// will be moved to trash
|
// will be moved to trash
|
||||||
$goingToTrash[] = $record;
|
$ret['trash'][] = $record;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// trash does not exist
|
// trash does not exist
|
||||||
$delete[] = $record;
|
$ret['delete'][] = $record;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//check if all values in array are true
|
|
||||||
//return (!in_array(false, $goingToTrash, true));
|
return $ret;
|
||||||
return ['trash' => $goingToTrash, 'delete' => $delete];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -338,7 +374,8 @@ class RecordController extends Controller
|
|||||||
*
|
*
|
||||||
* @param Request $request
|
* @param Request $request
|
||||||
*
|
*
|
||||||
* @return Response
|
* @return \Symfony\Component\HttpFoundation\JsonResponse
|
||||||
|
* @throws \Alchemy\Phrasea\Cache\Exception
|
||||||
*/
|
*/
|
||||||
public function renewUrl(Request $request)
|
public function renewUrl(Request $request)
|
||||||
{
|
{
|
||||||
|
@@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
namespace Alchemy\Phrasea\Controller;
|
namespace Alchemy\Phrasea\Controller;
|
||||||
|
|
||||||
|
use Alchemy\Phrasea\Model\Converter\BasketConverter;
|
||||||
use Alchemy\Phrasea\Model\Entities\Basket;
|
use Alchemy\Phrasea\Model\Entities\Basket;
|
||||||
use Doctrine\Common\Collections\ArrayCollection;
|
use Doctrine\Common\Collections\ArrayCollection;
|
||||||
use Alchemy\Phrasea\Application;
|
use Alchemy\Phrasea\Application;
|
||||||
@@ -21,6 +22,7 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
|||||||
class RecordsRequest extends ArrayCollection
|
class RecordsRequest extends ArrayCollection
|
||||||
{
|
{
|
||||||
protected $isSingleStory = false;
|
protected $isSingleStory = false;
|
||||||
|
protected $rejected;
|
||||||
protected $received;
|
protected $received;
|
||||||
protected $basket;
|
protected $basket;
|
||||||
protected $databoxes;
|
protected $databoxes;
|
||||||
@@ -31,30 +33,38 @@ class RecordsRequest extends ArrayCollection
|
|||||||
const FLATTEN_YES_PRESERVE_STORIES = 'preserve';
|
const FLATTEN_YES_PRESERVE_STORIES = 'preserve';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* RecordsRequest Constructor
|
||||||
*
|
*
|
||||||
* @param array $elements
|
* @param array $elements
|
||||||
|
* @param ArrayCollection $rejected
|
||||||
* @param ArrayCollection $received
|
* @param ArrayCollection $received
|
||||||
* @param Basket $basket
|
* @param Basket|null $basket
|
||||||
* @param Boolean $flatten
|
* @param Boolean $flatten
|
||||||
*/
|
*/
|
||||||
public function __construct(array $elements, ArrayCollection $received, Basket $basket = null, $flatten = self::FLATTEN_NO)
|
public function __construct(array $elements, ArrayCollection $rejected, ArrayCollection $received, Basket $basket = null, $flatten = self::FLATTEN_NO)
|
||||||
{
|
{
|
||||||
parent::__construct($elements);
|
parent::__construct($elements);
|
||||||
$this->received = $received;
|
$this->received = $received;
|
||||||
|
$this->rejected = $rejected;
|
||||||
$this->basket = $basket;
|
$this->basket = $basket;
|
||||||
$this->isSingleStory = ($flatten !== self::FLATTEN_YES && 1 === count($this) && $this->first()->isStory());
|
$this->isSingleStory = ($flatten !== self::FLATTEN_YES && count($this) === 1 && $this->first()->isStory());
|
||||||
|
|
||||||
if (self::FLATTEN_NO !== $flatten) {
|
if ($flatten !== self::FLATTEN_NO) {
|
||||||
$to_remove = [];
|
$to_remove = [];
|
||||||
/** @var record_adapter $record */
|
/** @var record_adapter $record */
|
||||||
foreach ($this as $key => $record) {
|
foreach ($this as $key => $record) {
|
||||||
if ($record->isStory()) {
|
if ($record->isStory()) {
|
||||||
if (self::FLATTEN_YES === $flatten) {
|
if ($flatten === self::FLATTEN_YES) {
|
||||||
|
// simple flatten : remove the story
|
||||||
$to_remove[] = $key;
|
$to_remove[] = $key;
|
||||||
}
|
}
|
||||||
foreach ($record->getChildren() as $child) {
|
|
||||||
$this->set($child->getId(), $child);
|
try {
|
||||||
|
foreach ($record->getChildren() as $child) {
|
||||||
|
$this->set($child->getId(), $child);
|
||||||
|
}
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
// getChildren will no fail since record IS a story
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -106,7 +116,7 @@ class RecordsRequest extends ArrayCollection
|
|||||||
/** @var \record_adapter $record */
|
/** @var \record_adapter $record */
|
||||||
foreach ($this as $record) {
|
foreach ($this as $record) {
|
||||||
if (! isset($this->collections[$record->getBaseId()])) {
|
if (! isset($this->collections[$record->getBaseId()])) {
|
||||||
$this->collections[$record->getBaseId()] = $record->get_collection();
|
$this->collections[$record->getBaseId()] = $record->getCollection();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -126,6 +136,16 @@ class RecordsRequest extends ArrayCollection
|
|||||||
return $this->received;
|
return $this->received;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return all rejected records
|
||||||
|
*
|
||||||
|
* @return \record_adapter[]|ArrayCollection
|
||||||
|
*/
|
||||||
|
public function rejected()
|
||||||
|
{
|
||||||
|
return $this->rejected;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return basket entity if provided, null otherwise
|
* Return basket entity if provided, null otherwise
|
||||||
*
|
*
|
||||||
@@ -201,15 +221,18 @@ class RecordsRequest extends ArrayCollection
|
|||||||
* @param boolean $flattenStories
|
* @param boolean $flattenStories
|
||||||
* @param array $rightsColl
|
* @param array $rightsColl
|
||||||
* @param array $rightsDatabox
|
* @param array $rightsDatabox
|
||||||
* @return RecordsRequest|\record_adapter[]
|
* @return RecordsRequest
|
||||||
|
* @throws \Alchemy\Phrasea\Cache\Exception
|
||||||
*/
|
*/
|
||||||
public static function fromRequest(Application $app, Request $request, $flattenStories = self::FLATTEN_NO, array $rightsColl = [], array $rightsDatabox = [])
|
public static function fromRequest(Application $app, Request $request, $flattenStories = self::FLATTEN_NO, array $rightsColl = [], array $rightsDatabox = [])
|
||||||
{
|
{
|
||||||
$elements = $received = [];
|
$received = [];
|
||||||
$basket = null;
|
$basket = null;
|
||||||
|
|
||||||
if ($request->get('ssel')) {
|
if ($request->get('ssel')) {
|
||||||
$basket = $app['converter.basket']->convert($request->get('ssel'));
|
/** @var BasketConverter $basketConverter */
|
||||||
|
$basketConverter = $app['converter.basket'];
|
||||||
|
$basket = $basketConverter->convert($request->get('ssel'));
|
||||||
$app['acl.basket']->hasAccess($basket, $app->getAuthenticatedUser());
|
$app['acl.basket']->hasAccess($basket, $app->getAuthenticatedUser());
|
||||||
|
|
||||||
foreach ($basket->getElements() as $basket_element) {
|
foreach ($basket->getElements() as $basket_element) {
|
||||||
@@ -240,35 +263,56 @@ class RecordsRequest extends ArrayCollection
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// fill an array with records from flattened stories
|
||||||
$elements = $received;
|
$elements = $received;
|
||||||
|
|
||||||
$to_remove = [];
|
if ($flattenStories !== self::FLATTEN_NO) {
|
||||||
|
/** @var record_adapter $record */
|
||||||
foreach ($elements as $id => $record) {
|
foreach ($received as $key => $record) {
|
||||||
if (!$app->getAclForUser($app->getAuthenticatedUser())->has_access_to_record($record)) {
|
if ($record->isStory()) {
|
||||||
$to_remove[] = $id;
|
if ($flattenStories === self::FLATTEN_YES) {
|
||||||
continue;
|
// simple flatten : remove the story from elements
|
||||||
}
|
unset($elements[$key]);
|
||||||
|
}
|
||||||
foreach ($rightsColl as $right) {
|
foreach ($record->getChildren() as $child) {
|
||||||
if (!$app->getAclForUser($app->getAuthenticatedUser())->has_right_on_base($record->get_base_id(), $right)) {
|
$elements[$child->getId()] = $child;
|
||||||
$to_remove[] = $id;
|
}
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach ($rightsDatabox as $right) {
|
|
||||||
if (!$app->getAclForUser($app->getAuthenticatedUser())->has_right_on_sbas($record->get_sbas_id(), $right)) {
|
|
||||||
$to_remove[] = $id;
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($to_remove as $id) {
|
// apply rights filter, remove from elements if no rights
|
||||||
unset($elements[$id]);
|
$rejected = [];
|
||||||
|
$acl = $app->getAclForUser($app->getAuthenticatedUser());
|
||||||
|
foreach ($elements as $key => $record) {
|
||||||
|
// any false or unknown right will throw exception and the record will be rejected
|
||||||
|
try {
|
||||||
|
if (!$acl->has_access_to_record($record)) {
|
||||||
|
throw new \Exception();
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($rightsColl as $right) {
|
||||||
|
if (!$acl->has_right_on_base($record->getBaseId(), $right)) {
|
||||||
|
throw new \Exception();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($rightsDatabox as $right) {
|
||||||
|
if (!$acl->has_right_on_sbas($record->getDataboxId(), $right)) {
|
||||||
|
throw new \Exception();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (\Exception $e) {
|
||||||
|
$rejected[$key] = $record;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// remove rejected from elements
|
||||||
|
foreach ($rejected as $key => $record) {
|
||||||
|
unset($elements[$key]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new static($elements, new ArrayCollection($received), $basket, $flattenStories);
|
// flattening is already done
|
||||||
|
return new static($elements, new ArrayCollection($rejected), new ArrayCollection($received), $basket, self::FLATTEN_NO);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -31,7 +31,8 @@ class BasketConverter implements ConverterInterface
|
|||||||
*/
|
*/
|
||||||
public function convert($id)
|
public function convert($id)
|
||||||
{
|
{
|
||||||
if (null === $basket = $this->repository->find((int) $id)) {
|
/** @var Basket $basket */
|
||||||
|
if ( ($basket = $this->repository->find((int) $id)) === null) {
|
||||||
throw new NotFoundHttpException(sprintf('Basket %s not found.', $id));
|
throw new NotFoundHttpException(sprintf('Basket %s not found.', $id));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -47,6 +47,10 @@ class ApiOrderController extends BaseOrderController
|
|||||||
use FilesystemAware;
|
use FilesystemAware;
|
||||||
use JsonBodyAware;
|
use JsonBodyAware;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Request $request
|
||||||
|
* @return Response
|
||||||
|
*/
|
||||||
public function createAction(Request $request)
|
public function createAction(Request $request)
|
||||||
{
|
{
|
||||||
$data = $this->decodeJsonBody($request, 'orders.json#/definitions/order_request');
|
$data = $this->decodeJsonBody($request, 'orders.json#/definitions/order_request');
|
||||||
@@ -54,7 +58,13 @@ class ApiOrderController extends BaseOrderController
|
|||||||
$availableRecords = $this->toRequestedRecords($data->data->records);
|
$availableRecords = $this->toRequestedRecords($data->data->records);
|
||||||
$records = $this->filterOrderableRecords($availableRecords);
|
$records = $this->filterOrderableRecords($availableRecords);
|
||||||
|
|
||||||
$recordRequest = new RecordsRequest($records, new ArrayCollection($availableRecords), null, RecordsRequest::FLATTEN_YES);
|
$recordRequest = new RecordsRequest(
|
||||||
|
$records, // orderable records
|
||||||
|
new ArrayCollection([]), // rejected (rights)
|
||||||
|
new ArrayCollection($availableRecords), // all records from request
|
||||||
|
null, // basket
|
||||||
|
RecordsRequest::FLATTEN_YES // orderable records is stories + children
|
||||||
|
);
|
||||||
|
|
||||||
$filler = new OrderFiller($this->app['repo.collection-references'], $this->app['orm.em']);
|
$filler = new OrderFiller($this->app['repo.collection-references'], $this->app['orm.em']);
|
||||||
|
|
||||||
@@ -62,7 +72,13 @@ class ApiOrderController extends BaseOrderController
|
|||||||
|
|
||||||
$order = new Order();
|
$order = new Order();
|
||||||
$order->setUser($this->getAuthenticatedUser());
|
$order->setUser($this->getAuthenticatedUser());
|
||||||
$order->setDeadline(new \DateTime($data->data->deadline, new \DateTimeZone('UTC')));
|
try {
|
||||||
|
$order->setDeadline(new \DateTime()); // safe value in case of data->deadline is invalid
|
||||||
|
$order->setDeadline(new \DateTime($data->data->deadline, new \DateTimeZone('UTC')));
|
||||||
|
}
|
||||||
|
catch (\Exception $e) {
|
||||||
|
// no-op, will end-up with safe value
|
||||||
|
}
|
||||||
$order->setOrderUsage($data->data->usage);
|
$order->setOrderUsage($data->data->usage);
|
||||||
$order->setNotificationMethod(Order::NOTIFY_WEBHOOK);
|
$order->setNotificationMethod(Order::NOTIFY_WEBHOOK);
|
||||||
|
|
||||||
@@ -139,8 +155,9 @@ class ApiOrderController extends BaseOrderController
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param int $orderId
|
* @param $orderId
|
||||||
* @return Response
|
* @return Response
|
||||||
|
* @throws \Exception
|
||||||
*/
|
*/
|
||||||
public function getArchiveAction($orderId)
|
public function getArchiveAction($orderId)
|
||||||
{
|
{
|
||||||
@@ -162,7 +179,12 @@ class ApiOrderController extends BaseOrderController
|
|||||||
$user = $this->getAuthenticatedUser();
|
$user = $this->getAuthenticatedUser();
|
||||||
$subdefs = $this->findDataboxSubdefNames();
|
$subdefs = $this->findDataboxSubdefNames();
|
||||||
|
|
||||||
$exportData = $export->prepare_export($user, $this->getFilesystem(), $subdefs, true, true);
|
try {
|
||||||
|
$exportData = $export->prepare_export($user, $this->getFilesystem(), $subdefs, true, true);
|
||||||
|
}
|
||||||
|
catch (\Exception $e) {
|
||||||
|
throw new NotFoundHttpException(sprintf('No archive could be downloaded for Order "%d"', $order->getId()));
|
||||||
|
}
|
||||||
|
|
||||||
/** @var Token $token */
|
/** @var Token $token */
|
||||||
$token = $this->app['manipulator.token']->createDownloadToken($user, serialize($exportData));
|
$token = $this->app['manipulator.token']->createDownloadToken($user, serialize($exportData));
|
||||||
@@ -248,8 +270,13 @@ class ApiOrderController extends BaseOrderController
|
|||||||
$filtered = [];
|
$filtered = [];
|
||||||
|
|
||||||
foreach ($records as $index => $record) {
|
foreach ($records as $index => $record) {
|
||||||
if (!$record->isStory() && $acl->has_right_on_base($record->getBaseId(), \ACL::CANCMD)) {
|
try {
|
||||||
$filtered[$index] = $record;
|
if ($acl->has_right_on_base($record->getBaseId(), \ACL::CANCMD)) {
|
||||||
|
$filtered[$index] = $record;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (\Exception $e) {
|
||||||
|
// will NOT happen since \ACL::CANCMD IS a known right
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -65,7 +65,7 @@
|
|||||||
"normalize-css": "^2.1.0",
|
"normalize-css": "^2.1.0",
|
||||||
"npm": "^6.0.0",
|
"npm": "^6.0.0",
|
||||||
"npm-modernizr": "^2.8.3",
|
"npm-modernizr": "^2.8.3",
|
||||||
"phraseanet-production-client": "0.34.160-d",
|
"phraseanet-production-client": "0.34.162-d",
|
||||||
"requirejs": "^2.3.5",
|
"requirejs": "^2.3.5",
|
||||||
"tinymce": "^4.0.28",
|
"tinymce": "^4.0.28",
|
||||||
"underscore": "^1.8.3",
|
"underscore": "^1.8.3",
|
||||||
|
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:jms="urn:jms:translation" version="1.2">
|
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:jms="urn:jms:translation" version="1.2">
|
||||||
<file date="2020-03-17T12:44:42Z" source-language="en" target-language="de" datatype="plaintext" original="not.available">
|
<file date="2020-04-03T07:42:51Z" source-language="en" target-language="de" datatype="plaintext" original="not.available">
|
||||||
<header>
|
<header>
|
||||||
<tool tool-id="JMSTranslationBundle" tool-name="JMSTranslationBundle" tool-version="1.1.0-DEV"/>
|
<tool tool-id="JMSTranslationBundle" tool-name="JMSTranslationBundle" tool-version="1.1.0-DEV"/>
|
||||||
<note>The source node in most cases contains the sample message as written by the developer. If it looks like a dot-delimitted string such as "form.label.firstname", then the developer has not provided a default message.</note>
|
<note>The source node in most cases contains the sample message as written by the developer. If it looks like a dot-delimitted string such as "form.label.firstname", then the developer has not provided a default message.</note>
|
||||||
@@ -9,9 +9,9 @@
|
|||||||
<trans-unit id="96f0767cb7ea65a7f86c8c9432e80d16cf9d8680" resname="Please provide the same passwords." approved="yes">
|
<trans-unit id="96f0767cb7ea65a7f86c8c9432e80d16cf9d8680" resname="Please provide the same passwords." approved="yes">
|
||||||
<source>Please provide the same passwords.</source>
|
<source>Please provide the same passwords.</source>
|
||||||
<target state="translated">Bitte geben Sie diesselbe Passwörter ein.</target>
|
<target state="translated">Bitte geben Sie diesselbe Passwörter ein.</target>
|
||||||
<jms:reference-file line="36">Form/Login/PhraseaRenewPasswordForm.php</jms:reference-file>
|
|
||||||
<jms:reference-file line="44">Form/Login/PhraseaRecoverPasswordForm.php</jms:reference-file>
|
<jms:reference-file line="44">Form/Login/PhraseaRecoverPasswordForm.php</jms:reference-file>
|
||||||
<jms:reference-file line="49">Form/Login/PhraseaRegisterForm.php</jms:reference-file>
|
<jms:reference-file line="49">Form/Login/PhraseaRegisterForm.php</jms:reference-file>
|
||||||
|
<jms:reference-file line="36">Form/Login/PhraseaRenewPasswordForm.php</jms:reference-file>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="90b8c9717bb7ed061dbf20fe1986c8b8593d43d4" resname="The token provided is not valid anymore" approved="yes">
|
<trans-unit id="90b8c9717bb7ed061dbf20fe1986c8b8593d43d4" resname="The token provided is not valid anymore" approved="yes">
|
||||||
<source>The token provided is not valid anymore</source>
|
<source>The token provided is not valid anymore</source>
|
||||||
|
@@ -1,67 +1,14 @@
|
|||||||
{% set nbReceived = records.received().count() %}
|
{% if with_children.records.stories().count() > 0 %}
|
||||||
{% set nbEligibleDocuments = records.count() %}
|
<label class="checkbox">
|
||||||
|
<input type="checkbox" id="del_children" name="del_children"
|
||||||
|
value="1"> {{ "Also delete records that rely on groupings." | trans }}
|
||||||
|
</label>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
{% set nbTrash = filteredRecord.trash|length %}
|
<div id="delete_records_parent_only">
|
||||||
{% set nbDelete = filteredRecord.delete|length %}
|
{{ include('prod/actions/delete_records_confirm_form.html.twig', parents_only) }}
|
||||||
|
</div>
|
||||||
|
|
||||||
{% if nbEligibleDocuments > 0 %}
|
<div id="delete_records_with_children">
|
||||||
{% if nbReceived != records.count() %}
|
{{ include('prod/actions/delete_records_confirm_form.html.twig', with_children) }}
|
||||||
<div class="well-small" style="text-align:center;">
|
</div>
|
||||||
<span class="label label-info">{{ "You do not have rights to remove all selected documents. Are you sure ?" | trans }}</span>
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
<form id="delete-record-form" style="margin: 0;" method="POST" action="{{ path('record_delete') }}">
|
|
||||||
<input type="hidden" value="{{ records.serializedList() }}" name="lst" />
|
|
||||||
{% if nbTrash > 0 %}
|
|
||||||
<div class="well-small label-important"
|
|
||||||
style="background-color: #ffef22;">
|
|
||||||
<div class="dialog-left-section">
|
|
||||||
<img src="/assets/common/images/icons/icon_collection_bin.png"/>
|
|
||||||
</div>
|
|
||||||
<div class="dialog-right-section" style="margin-top: 8px;">
|
|
||||||
<span>{{ nbTrash }} {{ "prod:app trash: record-move-to-trash" | trans }}</span>
|
|
||||||
</div>
|
|
||||||
{% if records.stories().count() %}
|
|
||||||
<label class="checkbox story">
|
|
||||||
<input type="checkbox" id="del_children" name="del_children"
|
|
||||||
value="1"> {{ "prod:app trash: also-move-record" | trans }}
|
|
||||||
</label>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
{% if nbDelete > 0 %}
|
|
||||||
<div class="well-small label-important"
|
|
||||||
style="background-color: #ed1c24;">
|
|
||||||
<div class="dialog-left-section">
|
|
||||||
<img src="/assets/common/images/icons/icon_empty_bin.png"/>
|
|
||||||
</div>
|
|
||||||
<div class="dialog-right-section">
|
|
||||||
<span>{{ nbDelete }} {{ "prod:app trash: record-delete" | trans }}</span>
|
|
||||||
</div>
|
|
||||||
{% if records.stories().count() %}
|
|
||||||
<label class="checkbox story">
|
|
||||||
<input type="checkbox" id="del_children" name="del_children"
|
|
||||||
value="1"> {{ "Also delete records that rely on groupings." | trans }}
|
|
||||||
</label>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
<div class="form-actions" style="background-color:transparent;">
|
|
||||||
<button type="button" class="btn btn-danger submiter">{{ "Ok" | trans }}</button>
|
|
||||||
<button type="button" class="btn cancel">{{ "Cancel" | trans }}</button>
|
|
||||||
<span class="form-action-loader" style="display:none;">
|
|
||||||
<img src="/assets/common/images/icons/loader000.gif"/>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
|
|
||||||
{% elseif nbReceived == 0 %}
|
|
||||||
<div class="well-small" style="text-align:center;">
|
|
||||||
<span class="label label-important">{{ "No document selected" | trans }}</span>
|
|
||||||
</div>
|
|
||||||
{% else %}
|
|
||||||
<div class="well-small" style="text-align:center;">
|
|
||||||
<span class="label label-info">{{ "You do not have rights to remove selected documents" | trans }}</span>
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
@@ -0,0 +1,48 @@
|
|||||||
|
{% if records.count() > 0 %}
|
||||||
|
{% if records.rejected().count() > 0 %}
|
||||||
|
<div class="well-small" style="text-align:center;">
|
||||||
|
{{ "You do not have rights to remove all selected documents. Are you sure ?" | trans }}
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
<form id="delete-record-form" style="margin: 0;" method="POST" action="{{ path('record_delete') }}">
|
||||||
|
<input type="hidden" value="{{ records.serializedList() }}" name="lst"/>
|
||||||
|
{% if trashableCount > 0 %}
|
||||||
|
<div class="well-small label-important"
|
||||||
|
style="background-color: #ffef22;">
|
||||||
|
<div class="dialog-left-section">
|
||||||
|
<img src="/assets/common/images/icons/icon_collection_bin.png"/>
|
||||||
|
</div>
|
||||||
|
<div class="dialog-right-section" style="margin-top: 8px;">
|
||||||
|
<span class="to_trash_count">{{ trashableCount }}</span> {{ "prod:app trash: record-move-to-trash" | trans }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
{% if deletableCount > 0 %}
|
||||||
|
<div class="well-small label-important"
|
||||||
|
style="background-color: #ed1c24;">
|
||||||
|
<div class="dialog-left-section">
|
||||||
|
<img src="/assets/common/images/icons/icon_empty_bin.png"/>
|
||||||
|
</div>
|
||||||
|
<div class="dialog-right-section">
|
||||||
|
<span class="to_delete_count">{{ deletableCount }}</span> {{ "prod:app trash: record-to-delete" | trans }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
<div class="form-actions" style="background-color:transparent;">
|
||||||
|
<button type="button" class="btn btn-danger submiter">{{ "Ok" | trans }}</button>
|
||||||
|
<button type="button" class="btn cancel">{{ "Cancel" | trans }}</button>
|
||||||
|
<span class="form-action-loader" style="display:none;">
|
||||||
|
<img src="/assets/common/images/icons/loader000.gif"/>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
{% elseif records.received().count() == 0 %}
|
||||||
|
<div class="well-small" style="text-align:center;">
|
||||||
|
<span class="label label-important">{{ "No document selected" | trans }}</span>
|
||||||
|
</div>
|
||||||
|
{% else %}
|
||||||
|
<div class="well-small" style="text-align:center;">
|
||||||
|
<span class="label label-info">{{ "You do not have rights to remove selected documents" | trans }}</span>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
@@ -7577,10 +7577,10 @@ phraseanet-common@^0.4.5-d:
|
|||||||
js-cookie "^2.1.0"
|
js-cookie "^2.1.0"
|
||||||
pym.js "^1.3.1"
|
pym.js "^1.3.1"
|
||||||
|
|
||||||
phraseanet-production-client@0.34.160-d:
|
phraseanet-production-client@0.34.162-d:
|
||||||
version "0.34.160-d"
|
version "0.34.162-d"
|
||||||
resolved "https://registry.yarnpkg.com/phraseanet-production-client/-/phraseanet-production-client-0.34.160-d.tgz#3deb3387b54e56aec73b073cae8cc013cc316999"
|
resolved "https://registry.yarnpkg.com/phraseanet-production-client/-/phraseanet-production-client-0.34.162-d.tgz#4bfbb6998bae864f5be2eefba87b07ef06f7e4e6"
|
||||||
integrity sha512-00jnCOCDrLowL8TE+h8mH+Lg4P0+EQPSDOXN2Lq6KF577GGu0OWQRh2YmUeXkacHTUT4N0u39IsBkkBYqorVnQ==
|
integrity sha512-FVXzj0Qi6DQSJnv3LrCiIaEUZ0A1DoOn3kUGPBpgws+EzXS13tFC6W0eLz/gDgw/L9Y82S60gI9s778fadwoew==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@mapbox/mapbox-gl-language" "^0.9.2"
|
"@mapbox/mapbox-gl-language" "^0.9.2"
|
||||||
"@turf/turf" "^5.1.6"
|
"@turf/turf" "^5.1.6"
|
||||||
|
Reference in New Issue
Block a user