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

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