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

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