vendor/pimcore/pimcore/bundles/AdminBundle/Controller/Admin/ElementController.php line 39

Open in your IDE?
  1. <?php
  2. /**
  3.  * Pimcore
  4.  *
  5.  * This source file is available under two different licenses:
  6.  * - GNU General Public License version 3 (GPLv3)
  7.  * - Pimcore Commercial License (PCL)
  8.  * Full copyright and license information is available in
  9.  * LICENSE.md which is distributed with this source code.
  10.  *
  11.  *  @copyright  Copyright (c) Pimcore GmbH (http://www.pimcore.org)
  12.  *  @license    http://www.pimcore.org/license     GPLv3 and PCL
  13.  */
  14. namespace Pimcore\Bundle\AdminBundle\Controller\Admin;
  15. use Pimcore\Bundle\AdminBundle\Controller\AdminController;
  16. use Pimcore\Bundle\AdminBundle\DependencyInjection\PimcoreAdminExtension;
  17. use Pimcore\Db;
  18. use Pimcore\Event\AdminEvents;
  19. use Pimcore\Event\Model\ResolveElementEvent;
  20. use Pimcore\Logger;
  21. use Pimcore\Model;
  22. use Pimcore\Model\Asset;
  23. use Pimcore\Model\DataObject;
  24. use Pimcore\Model\Document;
  25. use Pimcore\Model\Element;
  26. use Pimcore\Model\Version;
  27. use Symfony\Component\HttpFoundation\JsonResponse;
  28. use Symfony\Component\HttpFoundation\Request;
  29. use Symfony\Component\HttpFoundation\Response;
  30. use Symfony\Component\Routing\Annotation\Route;
  31. /**
  32.  *
  33.  * @internal
  34.  */
  35. class ElementController extends AdminController
  36. {
  37.     /**
  38.      * @Route("/element/lock-element", name="pimcore_admin_element_lockelement", methods={"PUT"})
  39.      *
  40.      * @param Request $request
  41.      *
  42.      * @return Response
  43.      */
  44.     public function lockElementAction(Request $request)
  45.     {
  46.         Element\Editlock::lock($request->get('id'), $request->get('type'));
  47.         return $this->adminJson(['success' => true]);
  48.     }
  49.     /**
  50.      * @Route("/element/unlock-element", name="pimcore_admin_element_unlockelement", methods={"PUT"})
  51.      *
  52.      * @param Request $request
  53.      *
  54.      * @return Response
  55.      */
  56.     public function unlockElementAction(Request $request)
  57.     {
  58.         Element\Editlock::unlock($request->get('id'), $request->get('type'));
  59.         return $this->adminJson(['success' => true]);
  60.     }
  61.     /**
  62.      * @Route("/element/unlock-elements", name="pimcore_admin_element_unlockelements", methods={"POST"})
  63.      *
  64.      * @param Request $request
  65.      *
  66.      * @return Response
  67.      */
  68.     public function unlockElementsAction(Request $request)
  69.     {
  70.         $request json_decode($request->getContent(), true) ?? [];
  71.         foreach ($request['elements'] as $elementIdentifierData) {
  72.             Element\Editlock::unlock($elementIdentifierData['id'], $elementIdentifierData['type']);
  73.         }
  74.         return $this->adminJson(['success' => true]);
  75.     }
  76.     /**
  77.      * Returns the element data denoted by the given type and ID or path.
  78.      *
  79.      * @Route("/element/get-subtype", name="pimcore_admin_element_getsubtype", methods={"GET"})
  80.      *
  81.      * @param Request $request
  82.      *
  83.      * @return JsonResponse
  84.      */
  85.     public function getSubtypeAction(Request $request)
  86.     {
  87.         $idOrPath trim($request->get('id'));
  88.         $type $request->get('type');
  89.         $event = new ResolveElementEvent($type$idOrPath);
  90.         \Pimcore::getEventDispatcher()->dispatch($eventAdminEvents::RESOLVE_ELEMENT);
  91.         $idOrPath $event->getId();
  92.         $type $event->getType();
  93.         if (is_numeric($idOrPath)) {
  94.             $el Element\Service::getElementById($type, (int) $idOrPath);
  95.         } else {
  96.             if ($type == 'document') {
  97.                 $el Document\Service::getByUrl($idOrPath);
  98.             } else {
  99.                 $el Element\Service::getElementByPath($type$idOrPath);
  100.             }
  101.         }
  102.         if ($el) {
  103.             $subtype null;
  104.             if ($el instanceof Asset || $el instanceof Document) {
  105.                 $subtype $el->getType();
  106.             } elseif ($el instanceof DataObject\Concrete) {
  107.                 $subtype $el->getClassName();
  108.             } elseif ($el instanceof DataObject\Folder) {
  109.                 $subtype 'folder';
  110.             }
  111.             return $this->adminJson([
  112.                 'subtype' => $subtype,
  113.                 'id' => $el->getId(),
  114.                 'type' => $type,
  115.                 'success' => true,
  116.             ]);
  117.         } else {
  118.             return $this->adminJson([
  119.                 'success' => false,
  120.             ]);
  121.         }
  122.     }
  123.     /**
  124.      * @param string $parameterName
  125.      *
  126.      * @return \Pimcore\Bundle\AdminBundle\HttpFoundation\JsonResponse
  127.      */
  128.     protected function processNoteTypesFromParameters(string $parameterName)
  129.     {
  130.         $config $this->getParameter($parameterName);
  131.         $result = [];
  132.         foreach ($config as $configEntry) {
  133.             $result[] = [
  134.                 'name' => $configEntry,
  135.             ];
  136.         }
  137.         return $this->adminJson(['noteTypes' => $result]);
  138.     }
  139.     /**
  140.      * @Route("/element/note-types", name="pimcore_admin_element_notetypes", methods={"GET"})
  141.      *
  142.      * @param Request $request
  143.      *
  144.      * @return JsonResponse
  145.      */
  146.     public function noteTypes(Request $request)
  147.     {
  148.         switch ($request->get('ctype')) {
  149.             case 'document':
  150.                 return $this->processNoteTypesFromParameters(PimcoreAdminExtension::PARAM_DOCUMENTS_NOTES_EVENTS_TYPES);
  151.             case 'asset':
  152.                 return $this->processNoteTypesFromParameters(PimcoreAdminExtension::PARAM_ASSETS_NOTES_EVENTS_TYPES);
  153.             case 'object':
  154.                 return $this->processNoteTypesFromParameters(PimcoreAdminExtension::PARAM_DATAOBJECTS_NOTES_EVENTS_TYPES);
  155.             default:
  156.                 return $this->adminJson(['noteTypes' => []]);
  157.         }
  158.     }
  159.     /**
  160.      * @Route("/element/note-list", name="pimcore_admin_element_notelist", methods={"POST"})
  161.      *
  162.      * @param Request $request
  163.      *
  164.      * @return JsonResponse
  165.      */
  166.     public function noteListAction(Request $request)
  167.     {
  168.         $this->checkPermission('notes_events');
  169.         $list = new Element\Note\Listing();
  170.         $list->setLimit($request->get('limit'));
  171.         $list->setOffset($request->get('start'));
  172.         $sortingSettings \Pimcore\Bundle\AdminBundle\Helper\QueryParams::extractSortingSettings(array_merge($request->request->all(), $request->query->all()));
  173.         if ($sortingSettings['orderKey'] && $sortingSettings['order']) {
  174.             $list->setOrderKey($sortingSettings['orderKey']);
  175.             $list->setOrder($sortingSettings['order']);
  176.         } else {
  177.             $list->setOrderKey(['date''id']);
  178.             $list->setOrder(['DESC''DESC']);
  179.         }
  180.         $conditions = [];
  181.         $filterText $request->get('filterText');
  182.         if ($filterText) {
  183.             $conditions[] = '('
  184.                 '`title` LIKE ' $list->quote('%'$filterText .'%')
  185.                 . ' OR `description` LIKE ' $list->quote('%'.$filterText.'%')
  186.                 . ' OR `type` LIKE ' $list->quote('%'.$filterText.'%')
  187.                 . ' OR `user` IN (SELECT `id` FROM `users` WHERE `name` LIKE ' $list->quote('%'.$filterText.'%') . ')'
  188.                 " OR DATE_FORMAT(FROM_UNIXTIME(`date`), '%Y-%m-%d') LIKE " $list->quote('%'.$filterText.'%')
  189.                 . ')';
  190.         }
  191.         $filterJson $request->get('filter');
  192.         if ($filterJson) {
  193.             $db Db::get();
  194.             $filters $this->decodeJson($filterJson);
  195.             $propertyKey 'property';
  196.             $comparisonKey 'operator';
  197.             foreach ($filters as $filter) {
  198.                 $operator '=';
  199.                 if ($filter['type'] == 'string') {
  200.                     $operator 'LIKE';
  201.                 } elseif ($filter['type'] == 'numeric') {
  202.                     if ($filter[$comparisonKey] == 'lt') {
  203.                         $operator '<';
  204.                     } elseif ($filter[$comparisonKey] == 'gt') {
  205.                         $operator '>';
  206.                     } elseif ($filter[$comparisonKey] == 'eq') {
  207.                         $operator '=';
  208.                     }
  209.                 } elseif ($filter['type'] == 'date') {
  210.                     if ($filter[$comparisonKey] == 'lt') {
  211.                         $operator '<';
  212.                     } elseif ($filter[$comparisonKey] == 'gt') {
  213.                         $operator '>';
  214.                     } elseif ($filter[$comparisonKey] == 'eq') {
  215.                         $operator '=';
  216.                     }
  217.                     $filter['value'] = strtotime($filter['value']);
  218.                 } elseif ($filter[$comparisonKey] == 'list') {
  219.                     $operator '=';
  220.                 } elseif ($filter[$comparisonKey] == 'boolean') {
  221.                     $operator '=';
  222.                     $filter['value'] = (int) $filter['value'];
  223.                 }
  224.                 // system field
  225.                 $value = ($filter['value']??'');
  226.                 if ($operator == 'LIKE') {
  227.                     $value '%' $value '%';
  228.                 }
  229.                 if ($filter[$propertyKey] == 'user') {
  230.                     $conditions[] = '`user` IN (SELECT `id` FROM `users` WHERE `name` LIKE ' $list->quote($value) . ')';
  231.                 } else {
  232.                     if ($filter['type'] == 'date' && $filter[$comparisonKey] == 'eq') {
  233.                         $maxTime $value + (86400 1); //specifies the top point of the range used in the condition
  234.                         $dateCondition '`' $filter[$propertyKey] . '` ' ' BETWEEN ' $db->quote($value) . ' AND ' $db->quote($maxTime);
  235.                         $conditions[] = $dateCondition;
  236.                     } else {
  237.                         $conditions[] = $db->quoteIdentifier($filter[$propertyKey]).' '.$operator.' '.$db->quote($value);
  238.                     }
  239.                 }
  240.             }
  241.         }
  242.         if ($request->get('cid') && $request->get('ctype')) {
  243.             $conditions[] = '(cid = ' $list->quote($request->get('cid')) . ' AND ctype = ' $list->quote($request->get('ctype')) . ')';
  244.         }
  245.         if (!empty($conditions)) {
  246.             $condition implode(' AND '$conditions);
  247.             $list->setCondition($condition);
  248.         }
  249.         $list->load();
  250.         $notes = [];
  251.         foreach ($list->getNotes() as $note) {
  252.             $e Element\Service::getNoteData($note);
  253.             $notes[] = $e;
  254.         }
  255.         return $this->adminJson([
  256.             'data' => $notes,
  257.             'success' => true,
  258.             'total' => $list->getTotalCount(),
  259.         ]);
  260.     }
  261.     /**
  262.      * @Route("/element/note-add", name="pimcore_admin_element_noteadd", methods={"POST"})
  263.      *
  264.      * @param Request $request
  265.      *
  266.      * @return JsonResponse
  267.      */
  268.     public function noteAddAction(Request $request)
  269.     {
  270.         $this->checkPermission('notes_events');
  271.         $note = new Element\Note();
  272.         $note->setCid((int) $request->get('cid'));
  273.         $note->setCtype($request->get('ctype'));
  274.         $note->setDate(time());
  275.         $note->setTitle($request->get('title'));
  276.         $note->setDescription($request->get('description'));
  277.         $note->setType($request->get('type'));
  278.         $note->save();
  279.         return $this->adminJson([
  280.             'success' => true,
  281.         ]);
  282.     }
  283.     /**
  284.      * @Route("/element/find-usages", name="pimcore_admin_element_findusages", methods={"GET"})
  285.      *
  286.      * @param Request $request
  287.      *
  288.      * @return JsonResponse
  289.      */
  290.     public function findUsagesAction(Request $request)
  291.     {
  292.         $element null;
  293.         if ($request->get('id')) {
  294.             $element Element\Service::getElementById($request->get('type'), $request->get('id'));
  295.         } elseif ($request->get('path')) {
  296.             $element Element\Service::getElementByPath($request->get('type'), $request->get('path'));
  297.         }
  298.         $results = [];
  299.         $success false;
  300.         $hasHidden false;
  301.         $total 0;
  302.         $limit = (int)$request->get('limit'50);
  303.         $offset = (int)$request->get('start'0);
  304.         if ($element instanceof Element\ElementInterface) {
  305.             $total $element->getDependencies()->getRequiredByTotalCount();
  306.             if ($request->get('sort')) {
  307.                 $sort json_decode($request->get('sort'))[0];
  308.                 $orderBy $sort->property;
  309.                 $orderDirection $sort->direction;
  310.             } else {
  311.                 $orderBy null;
  312.                 $orderDirection null;
  313.             }
  314.             $queryOffset $offset;
  315.             $queryLimit $limit;
  316.             while (count($results) < min($limit$total) && $queryOffset $total) {
  317.                 $elements $element->getDependencies()
  318.                     ->getRequiredByWithPath($queryOffset$queryLimit$orderBy$orderDirection);
  319.                 foreach ($elements as $el) {
  320.                     $item Element\Service::getElementById($el['type'], $el['id']);
  321.                     if ($item instanceof Element\ElementInterface) {
  322.                         if ($item->isAllowed('list')) {
  323.                             $results[] = $el;
  324.                         } else {
  325.                             $hasHidden true;
  326.                         }
  327.                     }
  328.                 }
  329.                 $queryOffset += count($elements);
  330.                 $queryLimit $limit count($results);
  331.             }
  332.             $success true;
  333.         }
  334.         return $this->adminJson([
  335.             'data' => $results,
  336.             'total' => $total,
  337.             'hasHidden' => $hasHidden,
  338.             'success' => $success,
  339.         ]);
  340.     }
  341.     /**
  342.      * @Route("/element/get-replace-assignments-batch-jobs", name="pimcore_admin_element_getreplaceassignmentsbatchjobs", methods={"GET"})
  343.      *
  344.      * @param Request $request
  345.      *
  346.      * @return \Pimcore\Bundle\AdminBundle\HttpFoundation\JsonResponse
  347.      */
  348.     public function getReplaceAssignmentsBatchJobsAction(Request $request)
  349.     {
  350.         $element null;
  351.         if ($request->get('id')) {
  352.             $element Element\Service::getElementById($request->get('type'), $request->get('id'));
  353.         } elseif ($request->get('path')) {
  354.             $element Element\Service::getElementByPath($request->get('type'), $request->get('path'));
  355.         }
  356.         if ($element instanceof Element\ElementInterface) {
  357.             return $this->adminJson([
  358.                 'success' => true,
  359.                 'jobs' => $element->getDependencies()->getRequiredBy(),
  360.             ]);
  361.         } else {
  362.             return $this->adminJson(['success' => false], Response::HTTP_NOT_FOUND);
  363.         }
  364.     }
  365.     /**
  366.      * @Route("/element/replace-assignments", name="pimcore_admin_element_replaceassignments", methods={"POST"})
  367.      *
  368.      * @param Request $request
  369.      *
  370.      * @return JsonResponse
  371.      */
  372.     public function replaceAssignmentsAction(Request $request)
  373.     {
  374.         $success false;
  375.         $message '';
  376.         $element Element\Service::getElementById($request->get('type'), $request->get('id'));
  377.         $sourceEl Element\Service::getElementById($request->get('sourceType'), $request->get('sourceId'));
  378.         $targetEl Element\Service::getElementById($request->get('targetType'), $request->get('targetId'));
  379.         if ($element && $sourceEl && $targetEl
  380.             && $request->get('sourceType') == $request->get('targetType')
  381.             && $sourceEl->getType() == $targetEl->getType()
  382.             && $element->isAllowed('save')
  383.         ) {
  384.             $rewriteConfig = [
  385.                 $request->get('sourceType') => [
  386.                     $sourceEl->getId() => $targetEl->getId(),
  387.                 ],
  388.             ];
  389.             if ($element instanceof Document) {
  390.                 $element Document\Service::rewriteIds($element$rewriteConfig);
  391.             } elseif ($element instanceof DataObject\AbstractObject) {
  392.                 $element DataObject\Service::rewriteIds($element$rewriteConfig);
  393.             } elseif ($element instanceof Asset) {
  394.                 $element Asset\Service::rewriteIds($element$rewriteConfig);
  395.             }
  396.             $element->setUserModification($this->getAdminUser()->getId());
  397.             $element->save();
  398.             $success true;
  399.         } else {
  400.             $message 'source-type and target-type do not match';
  401.         }
  402.         return $this->adminJson([
  403.             'success' => $success,
  404.             'message' => $message,
  405.         ]);
  406.     }
  407.     /**
  408.      * @Route("/element/unlock-propagate", name="pimcore_admin_element_unlockpropagate", methods={"PUT"})
  409.      *
  410.      * @param Request $request
  411.      *
  412.      * @return JsonResponse
  413.      */
  414.     public function unlockPropagateAction(Request $request)
  415.     {
  416.         $success false;
  417.         $element Element\Service::getElementById($request->get('type'), $request->get('id'));
  418.         if ($element) {
  419.             $element->unlockPropagate();
  420.             $success true;
  421.         }
  422.         return $this->adminJson([
  423.             'success' => $success,
  424.         ]);
  425.     }
  426.     /**
  427.      * @Route("/element/type-path", name="pimcore_admin_element_typepath", methods={"GET"})
  428.      *
  429.      * @param Request $request
  430.      *
  431.      * @return JsonResponse
  432.      */
  433.     public function typePathAction(Request $request)
  434.     {
  435.         $id $request->get('id');
  436.         $type $request->get('type');
  437.         $data = [];
  438.         if ($type === 'asset') {
  439.             $element Asset::getById($id);
  440.         } elseif ($type === 'document') {
  441.             $element Document::getById($id);
  442.         } else {
  443.             $element DataObject::getById($id);
  444.         }
  445.         if (!$element) {
  446.             $data['success'] = false;
  447.             return $this->adminJson($data);
  448.         }
  449.         $typePath Element\Service::getTypePath($element);
  450.         $data['success'] = true;
  451.         $data['index'] = method_exists($element'getIndex') ? (int) $element->getIndex() : 0;
  452.         $data['idPath'] = Element\Service::getIdPath($element);
  453.         $data['typePath'] = $typePath;
  454.         $data['fullpath'] = $element->getRealFullPath();
  455.         if ($type !== 'asset') {
  456.             $sortIndexPath Element\Service::getSortIndexPath($element);
  457.             $data['sortIndexPath'] = $sortIndexPath;
  458.         }
  459.         return $this->adminJson($data);
  460.     }
  461.     /**
  462.      * @Route("/element/version-update", name="pimcore_admin_element_versionupdate", methods={"PUT"})
  463.      *
  464.      * @param Request $request
  465.      *
  466.      * @return JsonResponse
  467.      */
  468.     public function versionUpdateAction(Request $request)
  469.     {
  470.         $data $this->decodeJson($request->get('data'));
  471.         $version Version::getById($data['id']);
  472.         if ($data['public'] != $version->getPublic() || $data['note'] != $version->getNote()) {
  473.             $version->setPublic($data['public']);
  474.             $version->setNote($data['note']);
  475.             $version->save();
  476.         }
  477.         return $this->adminJson(['success' => true]);
  478.     }
  479.     /**
  480.      * @Route("/element/get-nice-path", name="pimcore_admin_element_getnicepath", methods={"POST"})
  481.      *
  482.      * @param Request $request
  483.      *
  484.      * @return JsonResponse
  485.      *
  486.      * @throws \Exception
  487.      */
  488.     public function getNicePathAction(Request $request)
  489.     {
  490.         $source $this->decodeJson($request->get('source'));
  491.         if ($source['type'] != 'object') {
  492.             throw new \Exception('currently only objects as source elements are supported');
  493.         }
  494.         $result = [];
  495.         $id $source['id'];
  496.         $source DataObject\Concrete::getById($id);
  497.         if ($request->get('context')) {
  498.             $context $this->decodeJson($request->get('context'));
  499.         } else {
  500.             $context = [];
  501.         }
  502.         $ownerType $context['containerType'];
  503.         $fieldname $context['fieldname'];
  504.         $fd $this->getNicePathFormatterFieldDefinition($source$context);
  505.         $targets $this->decodeJson($request->get('targets'));
  506.         $result $this->convertResultWithPathFormatter($source$context$result$targets);
  507.         if ($request->get('loadEditModeData') == 'true') {
  508.             $idProperty $request->get('idProperty''id');
  509.             $methodName 'get' ucfirst($fieldname);
  510.             if ($ownerType == 'object' && method_exists($source$methodName)) {
  511.                 $data $source->$methodName();
  512.                 $editModeData $fd->getDataForEditmode($data$source);
  513.                 // Inherited values show as an empty array
  514.                 if (is_array($editModeData) && !empty($editModeData)) {
  515.                     foreach ($editModeData as $relationObjectAttribute) {
  516.                         $relationObjectAttribute['$$nicepath'] =
  517.                             isset($relationObjectAttribute[$idProperty]) && isset($result[$relationObjectAttribute[$idProperty]]) ? $result[$relationObjectAttribute[$idProperty]] : null;
  518.                         $result[$relationObjectAttribute[$idProperty]] = $relationObjectAttribute;
  519.                     }
  520.                 } else {
  521.                     foreach ($result as $resultItemId => $resultItem) {
  522.                         $result[$resultItemId] = ['$$nicepath' => $resultItem];
  523.                     }
  524.                 }
  525.             } else {
  526.                 Logger::error('Loading edit mode data is not supported for ownertype: ' $ownerType);
  527.             }
  528.         }
  529.         return $this->adminJson(['success' => true'data' => $result]);
  530.     }
  531.     /**
  532.      * @Route("/element/get-versions", name="pimcore_admin_element_getversions", methods={"GET"})
  533.      *
  534.      * @param Request $request
  535.      *
  536.      * @return JsonResponse
  537.      *
  538.      * @throws \Exception
  539.      */
  540.     public function getVersionsAction(Request $request)
  541.     {
  542.         $id = (int)$request->get('id');
  543.         $type $request->get('elementType');
  544.         $allowedTypes = ['asset''document''object'];
  545.         if ($id && in_array($type$allowedTypes)) {
  546.             $element Model\Element\Service::getElementById($type$id);
  547.             if ($element) {
  548.                 if ($element->isAllowed('versions')) {
  549.                     $schedule $element->getScheduledTasks();
  550.                     $schedules = [];
  551.                     foreach ($schedule as $task) {
  552.                         if ($task->getActive()) {
  553.                             $schedules[$task->getVersion()] = $task->getDate();
  554.                         }
  555.                     }
  556.                     //only load auto-save versions from current user
  557.                     $list = new Version\Listing();
  558.                     $list->setLoadAutoSave(true);
  559.                     $list->setCondition('cid = ? AND ctype = ? AND (autoSave=0 OR (autoSave=1 AND userId = ?)) ', [
  560.                         $element->getId(),
  561.                         Element\Service::getElementType($element),
  562.                         $this->getAdminUser()->getId(),
  563.                     ])
  564.                         ->setOrderKey('date')
  565.                         ->setOrder('ASC');
  566.                     $versions $list->load();
  567.                     $versions Model\Element\Service::getSafeVersionInfo($versions);
  568.                     $versions array_reverse($versions); //reverse array to sort by ID DESC
  569.                     foreach ($versions as &$version) {
  570.                         $version['scheduled'] = null;
  571.                         if (array_key_exists($version['id'], $schedules)) {
  572.                             $version['scheduled'] = $schedules[$version['id']];
  573.                         }
  574.                     }
  575.                     return $this->adminJson(['versions' => $versions]);
  576.                 } else {
  577.                     throw $this->createAccessDeniedException('Permission denied, ' $type ' id [' $id ']');
  578.                 }
  579.             } else {
  580.                 throw $this->createNotFoundException($type ' with id [' $id "] doesn't exist");
  581.             }
  582.         }
  583.         throw $this->createNotFoundException('Element type not found');
  584.     }
  585.     /**
  586.      * @Route("/element/delete-draft", name="pimcore_admin_element_deletedraft", methods={"DELETE"})
  587.      *
  588.      * @param Request $request
  589.      *
  590.      * @return JsonResponse
  591.      */
  592.     public function deleteDraftAction(Request $request)
  593.     {
  594.         $version Version::getById((int) $request->get('id'));
  595.         if ($version) {
  596.             $version->delete();
  597.         }
  598.         return $this->adminJson(['success' => true]);
  599.     }
  600.     /**
  601.      * @Route("/element/delete-version", name="pimcore_admin_element_deleteversion", methods={"DELETE"})
  602.      *
  603.      * @param Request $request
  604.      *
  605.      * @return JsonResponse
  606.      */
  607.     public function deleteVersionAction(Request $request)
  608.     {
  609.         $version Model\Version::getById((int) $request->get('id'));
  610.         $version->delete();
  611.         return $this->adminJson(['success' => true]);
  612.     }
  613.     /**
  614.      * @Route("/element/delete-all-versions", name="pimcore_admin_element_deleteallversion", methods={"DELETE"})
  615.      *
  616.      * @param Request $request
  617.      *
  618.      * @return JsonResponse
  619.      */
  620.     public function deleteAllVersionAction(Request $request)
  621.     {
  622.         $elementId $request->get('id');
  623.         $elementModificationdate $request->get('date');
  624.         $versions = new Model\Version\Listing();
  625.         $versions->setCondition('cid = ' $versions->quote($elementId) . ' AND date <> ' $versions->quote($elementModificationdate));
  626.         foreach ($versions->load() as $vkey => $version) {
  627.             $version->delete();
  628.         }
  629.         return $this->adminJson(['success' => true]);
  630.     }
  631.     /**
  632.      * @Route("/element/get-requires-dependencies", name="pimcore_admin_element_getrequiresdependencies", methods={"GET"})
  633.      *
  634.      * @param Request $request
  635.      *
  636.      * @return JsonResponse
  637.      */
  638.     public function getRequiresDependenciesAction(Request $request)
  639.     {
  640.         $id $request->get('id');
  641.         $type $request->get('elementType');
  642.         $allowedTypes = ['asset''document''object'];
  643.         $offset $request->get('start');
  644.         $limit $request->get('limit');
  645.         if ($id && in_array($type$allowedTypes)) {
  646.             $element Model\Element\Service::getElementById($type$id);
  647.             $dependencies $element->getDependencies();
  648.             if ($element instanceof Model\Element\ElementInterface) {
  649.                 $dependenciesResult Model\Element\Service::getRequiresDependenciesForFrontend($dependencies$offset$limit);
  650.                 $dependenciesResult['start'] = $offset;
  651.                 $dependenciesResult['limit'] = $limit;
  652.                 $dependenciesResult['total'] = $dependencies->getRequiresTotalCount();
  653.                 return $this->adminJson($dependenciesResult);
  654.             }
  655.         }
  656.         return $this->adminJson(false);
  657.     }
  658.     /**
  659.      * @Route("/element/get-required-by-dependencies", name="pimcore_admin_element_getrequiredbydependencies", methods={"GET"})
  660.      *
  661.      * @param Request $request
  662.      *
  663.      * @return JsonResponse
  664.      */
  665.     public function getRequiredByDependenciesAction(Request $request)
  666.     {
  667.         $id $request->get('id');
  668.         $type $request->get('elementType');
  669.         $allowedTypes = ['asset''document''object'];
  670.         $offset $request->get('start');
  671.         $limit $request->get('limit');
  672.         if ($id && in_array($type$allowedTypes)) {
  673.             $element Model\Element\Service::getElementById($type$id);
  674.             $dependencies $element->getDependencies();
  675.             if ($element instanceof Model\Element\ElementInterface) {
  676.                 $dependenciesResult Model\Element\Service::getRequiredByDependenciesForFrontend($dependencies$offset$limit);
  677.                 $dependenciesResult['start'] = $offset;
  678.                 $dependenciesResult['limit'] = $limit;
  679.                 $dependenciesResult['total'] = $dependencies->getRequiredByTotalCount();
  680.                 return $this->adminJson($dependenciesResult);
  681.             }
  682.         }
  683.         return $this->adminJson(false);
  684.     }
  685.     /**
  686.      * @Route("/element/get-predefined-properties", name="pimcore_admin_element_getpredefinedproperties", methods={"GET"})
  687.      *
  688.      * @param Request $request
  689.      *
  690.      * @return JsonResponse
  691.      */
  692.     public function getPredefinedPropertiesAction(Request $request)
  693.     {
  694.         $properties = [];
  695.         $type $request->get('elementType');
  696.         $query $request->get('query');
  697.         $allowedTypes = ['asset''document''object'];
  698.         if (in_array($type$allowedTypestrue)) {
  699.             $list = new Model\Property\Predefined\Listing();
  700.             $list->setFilter(function (Model\Property\Predefined $predefined) use ($type$query) {
  701.                 if (!str_contains($predefined->getCtype(), $type)) {
  702.                     return false;
  703.                 }
  704.                 if ($query && stripos($this->trans($predefined->getName()), $query) === false) {
  705.                     return false;
  706.                 }
  707.                 return true;
  708.             });
  709.             foreach ($list->getProperties() as $type) {
  710.                 $properties[] = $type->getObjectVars();
  711.             }
  712.         }
  713.         return $this->adminJson(['properties' => $properties]);
  714.     }
  715.     /**
  716.      * @Route("/element/analyze-permissions", name="pimcore_admin_element_analyzepermissions", methods={"POST"})
  717.      *
  718.      * @param Request $request
  719.      *
  720.      * @return Response
  721.      */
  722.     public function analyzePermissionsAction(Request $request)
  723.     {
  724.         $userId $request->get('userId');
  725.         if ($userId) {
  726.             $user Model\User::getById($userId);
  727.             $userList = [$user];
  728.         } else {
  729.             $userList = new Model\User\Listing();
  730.             $userList->setCondition('type = ?', ['user']);
  731.             $userList $userList->load();
  732.         }
  733.         $elementType $request->get('elementType');
  734.         $elementId $request->get('elementId');
  735.         $element Element\Service::getElementById($elementType$elementId);
  736.         $result Element\PermissionChecker::check($element$userList);
  737.         return $this->adminJson(
  738.             [
  739.                 'data' => $result,
  740.                 'success' => true,
  741.             ]
  742.         );
  743.     }
  744.     /**
  745.      * @param DataObject\Concrete $source
  746.      * @param array $context
  747.      *
  748.      * @return bool|DataObject\ClassDefinition\Data|null
  749.      *
  750.      * @throws \Exception
  751.      */
  752.     protected function getNicePathFormatterFieldDefinition($source$context)
  753.     {
  754.         $ownerType $context['containerType'];
  755.         $fieldname $context['fieldname'];
  756.         $fd null;
  757.         if ($ownerType == 'object') {
  758.             $subContainerType = isset($context['subContainerType']) ? $context['subContainerType'] : null;
  759.             if ($subContainerType) {
  760.                 $subContainerKey $context['subContainerKey'];
  761.                 $subContainer $source->getClass()->getFieldDefinition($subContainerKey);
  762.                 if (method_exists($subContainer'getFieldDefinition')) {
  763.                     $fd $subContainer->getFieldDefinition($fieldname);
  764.                 }
  765.             } else {
  766.                 $fd $source->getClass()->getFieldDefinition($fieldname);
  767.             }
  768.         } elseif ($ownerType == 'localizedfield') {
  769.             $localizedfields $source->getClass()->getFieldDefinition('localizedfields');
  770.             if ($localizedfields instanceof DataObject\ClassDefinition\Data\Localizedfields) {
  771.                 $fd $localizedfields->getFieldDefinition($fieldname);
  772.             }
  773.         } elseif ($ownerType == 'objectbrick') {
  774.             $fdBrick DataObject\Objectbrick\Definition::getByKey($context['containerKey']);
  775.             $fd $fdBrick->getFieldDefinition($fieldname);
  776.         } elseif ($ownerType == 'fieldcollection') {
  777.             $containerKey $context['containerKey'];
  778.             $fdCollection DataObject\Fieldcollection\Definition::getByKey($containerKey);
  779.             if (($context['subContainerType'] ?? null) === 'localizedfield') {
  780.                 /** @var DataObject\ClassDefinition\Data\Localizedfields $fdLocalizedFields */
  781.                 $fdLocalizedFields $fdCollection->getFieldDefinition('localizedfields');
  782.                 $fd $fdLocalizedFields->getFieldDefinition($fieldname);
  783.             } else {
  784.                 $fd $fdCollection->getFieldDefinition($fieldname);
  785.             }
  786.         }
  787.         return $fd;
  788.     }
  789.     /**
  790.      * @param DataObject\Concrete $source
  791.      * @param array $context
  792.      * @param array $result
  793.      * @param array $targets
  794.      *
  795.      * @return array
  796.      *
  797.      * @throws \Exception
  798.      */
  799.     protected function convertResultWithPathFormatter(DataObject\Concrete $source$context$result$targets): array
  800.     {
  801.         $fd $this->getNicePathFormatterFieldDefinition($source$context);
  802.         if ($fd instanceof DataObject\ClassDefinition\PathFormatterAwareInterface) {
  803.             $formatter $fd->getPathFormatterClass();
  804.             if (null !== $formatter) {
  805.                 $pathFormatter DataObject\ClassDefinition\Helper\PathFormatterResolver::resolvePathFormatter(
  806.                     $fd->getPathFormatterClass()
  807.                 );
  808.                 if ($pathFormatter instanceof DataObject\ClassDefinition\PathFormatterInterface) {
  809.                     $result $pathFormatter->formatPath($result$source$targets, [
  810.                         'fd' => $fd,
  811.                         'context' => $context,
  812.                     ]);
  813.                 }
  814.             }
  815.         }
  816.         return $result;
  817.     }
  818. }