vendor/pimcore/pimcore/bundles/AdminBundle/Controller/Admin/DataObject/ClassController.php line 964

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 Enterprise License (PEL)
  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 PEL
  13.  */
  14. namespace Pimcore\Bundle\AdminBundle\Controller\Admin\DataObject;
  15. use Pimcore\Bundle\AdminBundle\Controller\AdminController;
  16. use Pimcore\Bundle\AdminBundle\HttpFoundation\JsonResponse;
  17. use Pimcore\Controller\EventedControllerInterface;
  18. use Pimcore\Db;
  19. use Pimcore\Event\AdminEvents;
  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\Tool\Session;
  26. use Symfony\Component\EventDispatcher\GenericEvent;
  27. use Symfony\Component\HttpFoundation\Request;
  28. use Symfony\Component\HttpFoundation\Response;
  29. use Symfony\Component\HttpFoundation\Session\Attribute\AttributeBagInterface;
  30. use Symfony\Component\HttpKernel\Event\FilterControllerEvent;
  31. use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
  32. use Symfony\Component\Routing\Annotation\Route;
  33. /**
  34.  * @Route("/class")
  35.  */
  36. class ClassController extends AdminController implements EventedControllerInterface
  37. {
  38.     /**
  39.      * @Route("/get-document-types", name="pimcore_admin_dataobject_class_getdocumenttypes", methods={"GET"})
  40.      *
  41.      * @param Request $request
  42.      *
  43.      * @return JsonResponse
  44.      */
  45.     public function getDocumentTypesAction(Request $request)
  46.     {
  47.         $documentTypes Document::getTypes();
  48.         $typeItems = [];
  49.         foreach ($documentTypes as $documentType) {
  50.             $typeItems[] = [
  51.                 'text' => $documentType
  52.             ];
  53.         }
  54.         return $this->adminJson($typeItems);
  55.     }
  56.     /**
  57.      * @Route("/get-asset-types", name="pimcore_admin_dataobject_class_getassettypes", methods={"GET"})
  58.      *
  59.      * @param Request $request
  60.      *
  61.      * @return JsonResponse
  62.      */
  63.     public function getAssetTypesAction(Request $request)
  64.     {
  65.         $assetTypes Asset::getTypes();
  66.         $typeItems = [];
  67.         foreach ($assetTypes as $assetType) {
  68.             $typeItems[] = [
  69.                 'text' => $assetType
  70.             ];
  71.         }
  72.         return $this->adminJson($typeItems);
  73.     }
  74.     /**
  75.      * @Route("/get-tree", name="pimcore_admin_dataobject_class_gettree", methods={"GET", "POST"})
  76.      *
  77.      * @param Request $request
  78.      *
  79.      * @return JsonResponse
  80.      */
  81.     public function getTreeAction(Request $request)
  82.     {
  83.         $defaultIcon '/bundles/pimcoreadmin/img/flat-color-icons/class.svg';
  84.         $classesList = new DataObject\ClassDefinition\Listing();
  85.         $classesList->setOrderKey('name');
  86.         $classesList->setOrder('asc');
  87.         $classes $classesList->load();
  88.         // filter classes
  89.         if ($request->get('createAllowed')) {
  90.             $tmpClasses = [];
  91.             foreach ($classes as $class) {
  92.                 if ($this->getAdminUser()->isAllowed($class->getId(), 'class')) {
  93.                     $tmpClasses[] = $class;
  94.                 }
  95.             }
  96.             $classes $tmpClasses;
  97.         }
  98.         $withId $request->get('withId');
  99.         $getClassConfig = function ($class) use ($defaultIcon$withId) {
  100.             $text $class->getname();
  101.             if ($withId) {
  102.                 $text .= ' (' $class->getId() . ')';
  103.             }
  104.             return [
  105.                 'id' => $class->getId(),
  106.                 'text' => $text,
  107.                 'leaf' => true,
  108.                 'icon' => $class->getIcon() ? $class->getIcon() : $defaultIcon,
  109.                 'cls' => 'pimcore_class_icon',
  110.                 'propertyVisibility' => $class->getPropertyVisibility(),
  111.                 'enableGridLocking' => $class->isEnableGridLocking()
  112.             ];
  113.         };
  114.         // build groups
  115.         $groups = [];
  116.         foreach ($classes as $class) {
  117.             if (!$class) {
  118.                 continue;
  119.             }
  120.             $groupName null;
  121.             if ($class->getGroup()) {
  122.                 $type 'manual';
  123.                 $groupName $class->getGroup();
  124.             } else {
  125.                 $type 'auto';
  126.                 if (preg_match('@^([A-Za-z])([^A-Z]+)@'$class->getName(), $matches)) {
  127.                     $groupName $matches[0];
  128.                 }
  129.                 if (!$groupName) {
  130.                     // this is eg. the case when class name uses only capital letters
  131.                     $groupName $class->getName();
  132.                 }
  133.             }
  134.             $groupName = \Pimcore\Model\Translation\Admin::getByKeyLocalized($groupNametruetrue);
  135.             if (!isset($groups[$groupName])) {
  136.                 $groups[$groupName] = [
  137.                     'classes' => [],
  138.                     'type' => $type
  139.                 ];
  140.             }
  141.             $groups[$groupName]['classes'][] = $class;
  142.         }
  143.         $treeNodes = [];
  144.         if (!$request->get('grouped')) {
  145.             // list output
  146.             foreach ($groups as $groupName => $groupData) {
  147.                 foreach ($groupData['classes'] as $class) {
  148.                     $node $getClassConfig($class);
  149.                     if (count($groupData['classes']) > || $groupData['type'] == 'manual') {
  150.                         $node['group'] = $groupName;
  151.                     }
  152.                     $treeNodes[] = $node;
  153.                 }
  154.             }
  155.         } else {
  156.             // create json output
  157.             foreach ($groups as $groupName => $groupData) {
  158.                 if (count($groupData['classes']) === && $groupData['type'] == 'auto') {
  159.                     // no group, only one child
  160.                     $node $getClassConfig($groupData['classes'][0]);
  161.                 } else {
  162.                     // group classes
  163.                     $node = [
  164.                         'id' => 'folder_' $groupName,
  165.                         'text' => $groupName,
  166.                         'leaf' => false,
  167.                         'expandable' => true,
  168.                         'allowChildren' => true,
  169.                         'iconCls' => 'pimcore_icon_folder',
  170.                         'children' => []
  171.                     ];
  172.                     foreach ($groupData['classes'] as $class) {
  173.                         $node['children'][] = $getClassConfig($class);
  174.                     }
  175.                 }
  176.                 $treeNodes[] = $node;
  177.             }
  178.         }
  179.         return $this->adminJson($treeNodes);
  180.     }
  181.     /**
  182.      * @Route("/get", name="pimcore_admin_dataobject_class_get", methods={"GET"})
  183.      *
  184.      * @param Request $request
  185.      *
  186.      * @return JsonResponse
  187.      */
  188.     public function getAction(Request $request)
  189.     {
  190.         $class DataObject\ClassDefinition::getById($request->get('id'));
  191.         $class->setFieldDefinitions([]);
  192.         return $this->adminJson($class);
  193.     }
  194.     /**
  195.      * @Route("/get-custom-layout", name="pimcore_admin_dataobject_class_getcustomlayout", methods={"GET"})
  196.      *
  197.      * @param Request $request
  198.      *
  199.      * @return JsonResponse
  200.      */
  201.     public function getCustomLayoutAction(Request $request)
  202.     {
  203.         $customLayout DataObject\ClassDefinition\CustomLayout::getById($request->get('id'));
  204.         return $this->adminJson(['success' => true'data' => $customLayout]);
  205.     }
  206.     /**
  207.      * @Route("/add", name="pimcore_admin_dataobject_class_add", methods={"POST"})
  208.      *
  209.      * @param Request $request
  210.      *
  211.      * @return JsonResponse
  212.      */
  213.     public function addAction(Request $request)
  214.     {
  215.         $className $request->get('className');
  216.         $className $this->correctClassname($className);
  217.         $classId $request->get('classIdentifier');
  218.         $existingClass DataObject\ClassDefinition::getById($classId);
  219.         if ($existingClass) {
  220.             throw new \Exception('Class identifier already exists');
  221.         }
  222.         $class DataObject\ClassDefinition::create(
  223.             ['name' => $className,
  224.                 'userOwner' => $this->getAdminUser()->getId()]
  225.         );
  226.         $class->setId($classId);
  227.         $class->save(true);
  228.         return $this->adminJson(['success' => true'id' => $class->getId()]);
  229.     }
  230.     /**
  231.      * @Route("/add-custom-layout", name="pimcore_admin_dataobject_class_addcustomlayout", methods={"POST"})
  232.      *
  233.      * @param Request $request
  234.      *
  235.      * @return JsonResponse
  236.      */
  237.     public function addCustomLayoutAction(Request $request)
  238.     {
  239.         $layoutId $request->get('layoutIdentifier');
  240.         $existingLayout DataObject\ClassDefinition\CustomLayout::getById($layoutId);
  241.         if ($existingLayout) {
  242.             throw new \Exception('Custom Layout identifier already exists');
  243.         }
  244.         $customLayout DataObject\ClassDefinition\CustomLayout::create(
  245.             [
  246.                 'name' => $request->get('layoutName'),
  247.                 'userOwner' => $this->getAdminUser()->getId(),
  248.                 'classId' => $request->get('classId')
  249.             ]
  250.         );
  251.         $customLayout->setId($layoutId);
  252.         $customLayout->save();
  253.         return $this->adminJson(['success' => true'id' => $customLayout->getId(), 'name' => $customLayout->getName(),
  254.                                  'data' => $customLayout]);
  255.     }
  256.     /**
  257.      * @Route("/delete", name="pimcore_admin_dataobject_class_delete", methods={"DELETE"})
  258.      *
  259.      * @param Request $request
  260.      *
  261.      * @return Response
  262.      */
  263.     public function deleteAction(Request $request)
  264.     {
  265.         $class DataObject\ClassDefinition::getById($request->get('id'));
  266.         $class->delete();
  267.         return new Response();
  268.     }
  269.     /**
  270.      * @Route("/delete-custom-layout", name="pimcore_admin_dataobject_class_deletecustomlayout", methods={"DELETE"})
  271.      *
  272.      * @param Request $request
  273.      *
  274.      * @return JsonResponse
  275.      */
  276.     public function deleteCustomLayoutAction(Request $request)
  277.     {
  278.         $customLayout DataObject\ClassDefinition\CustomLayout::getById($request->get('id'));
  279.         if ($customLayout) {
  280.             $customLayout->delete();
  281.         }
  282.         return $this->adminJson(['success' => true]);
  283.     }
  284.     /**
  285.      * @Route("/save-custom-layout", name="pimcore_admin_dataobject_class_savecustomlayout", methods={"PUT"})
  286.      *
  287.      * @param Request $request
  288.      *
  289.      * @return JsonResponse
  290.      */
  291.     public function saveCustomLayoutAction(Request $request)
  292.     {
  293.         $customLayout DataObject\ClassDefinition\CustomLayout::getById($request->get('id'));
  294.         $class DataObject\ClassDefinition::getById($customLayout->getClassId());
  295.         $configuration $this->decodeJson($request->get('configuration'));
  296.         $values $this->decodeJson($request->get('values'));
  297.         $modificationDate intval($values['modificationDate']);
  298.         if ($modificationDate $customLayout->getModificationDate()) {
  299.             return $this->adminJson(['success' => false'msg' => 'custom_layout_changed']);
  300.         }
  301.         $configuration['datatype'] = 'layout';
  302.         $configuration['fieldtype'] = 'panel';
  303.         $configuration['name'] = 'pimcore_root';
  304.         try {
  305.             $layout DataObject\ClassDefinition\Service::generateLayoutTreeFromArray($configurationtrue);
  306.             $customLayout->setLayoutDefinitions($layout);
  307.             $customLayout->setName($values['name']);
  308.             $customLayout->setDescription($values['description']);
  309.             $customLayout->setDefault($values['default']);
  310.             $customLayout->save();
  311.             return $this->adminJson(['success' => true'id' => $customLayout->getId(), 'data' => $customLayout]);
  312.         } catch (\Exception $e) {
  313.             Logger::error($e->getMessage());
  314.             return $this->adminJson(['success' => false'message' => $e->getMessage()]);
  315.         }
  316.     }
  317.     /**
  318.      * @Route("/save", name="pimcore_admin_dataobject_class_save", methods={"PUT"})
  319.      *
  320.      * @param Request $request
  321.      *
  322.      * @return JsonResponse
  323.      *
  324.      * @throws \Exception
  325.      */
  326.     public function saveAction(Request $request)
  327.     {
  328.         $class DataObject\ClassDefinition::getById($request->get('id'));
  329.         $configuration $this->decodeJson($request->get('configuration'));
  330.         $values $this->decodeJson($request->get('values'));
  331.         // check if the class was changed during editing in the frontend
  332.         if ($class->getModificationDate() != $values['modificationDate']) {
  333.             throw new \Exception('The class was modified during editing, please reload the class and make your changes again');
  334.         }
  335.         if ($values['name'] != $class->getName()) {
  336.             $classByName DataObject\ClassDefinition::getByName($values['name']);
  337.             if ($classByName && $classByName->getId() != $class->getId()) {
  338.                 throw new \Exception('Class name already exists');
  339.             }
  340.             $values['name'] = $this->correctClassname($values['name']);
  341.             $class->rename($values['name']);
  342.         }
  343.         unset($values['creationDate']);
  344.         unset($values['userOwner']);
  345.         unset($values['layoutDefinitions']);
  346.         unset($values['fieldDefinitions']);
  347.         $configuration['datatype'] = 'layout';
  348.         $configuration['fieldtype'] = 'panel';
  349.         $configuration['name'] = 'pimcore_root';
  350.         $class->setValues($values);
  351.         try {
  352.             $layout DataObject\ClassDefinition\Service::generateLayoutTreeFromArray($configurationtrue);
  353.             $class->setLayoutDefinitions($layout);
  354.             $class->setUserModification($this->getAdminUser()->getId());
  355.             $class->setModificationDate(time());
  356.             $propertyVisibility = [];
  357.             foreach ($values as $key => $value) {
  358.                 if (preg_match('/propertyVisibility/i'$key)) {
  359.                     if (preg_match("/\.grid\./i"$key)) {
  360.                         $propertyVisibility['grid'][preg_replace("/propertyVisibility\.grid\./i"''$key)] = (bool) $value;
  361.                     } elseif (preg_match("/\.search\./i"$key)) {
  362.                         $propertyVisibility['search'][preg_replace("/propertyVisibility\.search\./i"''$key)] = (bool) $value;
  363.                     }
  364.                 }
  365.             }
  366.             if (!empty($propertyVisibility)) {
  367.                 $class->setPropertyVisibility($propertyVisibility);
  368.             }
  369.             $class->save();
  370.             // set the fielddefinitions to [] because we don't need them in the response
  371.             $class->setFieldDefinitions([]);
  372.             return $this->adminJson(['success' => true'class' => $class]);
  373.         } catch (\Exception $e) {
  374.             Logger::error($e->getMessage());
  375.             return $this->adminJson(['success' => false'message' => $e->getMessage()]);
  376.         }
  377.     }
  378.     /**
  379.      * @param string $name
  380.      *
  381.      * @return string
  382.      */
  383.     protected function correctClassname($name)
  384.     {
  385.         $name preg_replace('/[^a-zA-Z0-9_]+/'''$name);
  386.         $name preg_replace('/^[0-9]+/'''$name);
  387.         return $name;
  388.     }
  389.     /**
  390.      * @Route("/import-class", name="pimcore_admin_dataobject_class_importclass", methods={"POST", "PUT"})
  391.      *
  392.      * @param Request $request
  393.      *
  394.      * @return Response
  395.      */
  396.     public function importClassAction(Request $request)
  397.     {
  398.         $class DataObject\ClassDefinition::getById($request->get('id'));
  399.         $json file_get_contents($_FILES['Filedata']['tmp_name']);
  400.         $success DataObject\ClassDefinition\Service::importClassDefinitionFromJson($class$jsonfalsetrue);
  401.         $response $this->adminJson([
  402.             'success' => $success
  403.         ]);
  404.         // set content-type to text/html, otherwise (when application/json is sent) chrome will complain in
  405.         // Ext.form.Action.Submit and mark the submission as failed
  406.         $response->headers->set('Content-Type''text/html');
  407.         return $response;
  408.     }
  409.     /**
  410.      * @Route("/import-custom-layout-definition", name="pimcore_admin_dataobject_class_importcustomlayoutdefinition", methods={"POST", "PUT"})
  411.      *
  412.      * @param Request $request
  413.      *
  414.      * @return Response
  415.      */
  416.     public function importCustomLayoutDefinitionAction(Request $request)
  417.     {
  418.         $success false;
  419.         $json file_get_contents($_FILES['Filedata']['tmp_name']);
  420.         $importData $this->decodeJson($json);
  421.         $customLayoutId $request->get('id');
  422.         $customLayout DataObject\ClassDefinition\CustomLayout::getById($customLayoutId);
  423.         if ($customLayout) {
  424.             try {
  425.                 $layout DataObject\ClassDefinition\Service::generateLayoutTreeFromArray($importData['layoutDefinitions'], true);
  426.                 $customLayout->setLayoutDefinitions($layout);
  427.                 $customLayout->setDescription($importData['description']);
  428.                 $customLayout->save();
  429.                 $success true;
  430.             } catch (\Exception $e) {
  431.                 Logger::error($e->getMessage());
  432.             }
  433.         }
  434.         $response $this->adminJson([
  435.             'success' => $success
  436.         ]);
  437.         // set content-type to text/html, otherwise (when application/json is sent) chrome will complain in
  438.         // Ext.form.Action.Submit and mark the submission as failed
  439.         $response->headers->set('Content-Type''text/html');
  440.         return $response;
  441.     }
  442.     /**
  443.      * @Route("/get-custom-layout-definitions", name="pimcore_admin_dataobject_class_getcustomlayoutdefinitions", methods={"GET"})
  444.      *
  445.      * @param Request $request
  446.      *
  447.      * @return JsonResponse
  448.      */
  449.     public function getCustomLayoutDefinitionsAction(Request $request)
  450.     {
  451.         $classId $request->get('classId');
  452.         $list = new DataObject\ClassDefinition\CustomLayout\Listing();
  453.         $list->setCondition('classId = ' $list->quote($classId));
  454.         $list $list->load();
  455.         $result = [];
  456.         /** @var DataObject\ClassDefinition\CustomLayout $item */
  457.         foreach ($list as $item) {
  458.             $result[] = [
  459.                 'id' => $item->getId(),
  460.                 'name' => $item->getName() . ' (ID: ' $item->getId() . ')',
  461.                 'default' => $item->getDefault() ?: 0,
  462.             ];
  463.         }
  464.         return $this->adminJson(['success' => true'data' => $result]);
  465.     }
  466.     /**
  467.      * @Route("/get-all-layouts", name="pimcore_admin_dataobject_class_getalllayouts", methods={"GET"})
  468.      *
  469.      * @param Request $request
  470.      *
  471.      * @return JsonResponse
  472.      */
  473.     public function getAllLayoutsAction(Request $request)
  474.     {
  475.         // get all classes
  476.         $resultList = [];
  477.         $mapping = [];
  478.         $customLayouts = new DataObject\ClassDefinition\CustomLayout\Listing();
  479.         $customLayouts->setOrder('ASC');
  480.         $customLayouts->setOrderKey('name');
  481.         $customLayouts $customLayouts->load();
  482.         foreach ($customLayouts as $layout) {
  483.             $mapping[$layout->getClassId()][] = $layout;
  484.         }
  485.         $classList = new DataObject\ClassDefinition\Listing();
  486.         $classList->setOrder('ASC');
  487.         $classList->setOrderKey('name');
  488.         $classList $classList->load();
  489.         foreach ($classList as $class) {
  490.             if (isset($mapping[$class->getId()])) {
  491.                 $classMapping $mapping[$class->getId()];
  492.                 $resultList[] = [
  493.                     'type' => 'master',
  494.                     'id' => $class->getId() . '_' 0,
  495.                     'name' => $class->getName()
  496.                 ];
  497.                 foreach ($classMapping as $layout) {
  498.                     $resultList[] = [
  499.                         'type' => 'custom',
  500.                         'id' => $class->getId() . '_' $layout->getId(),
  501.                         'name' => $class->getName() . ' - ' $layout->getName()
  502.                     ];
  503.                 }
  504.             }
  505.         }
  506.         return $this->adminJson(['data' => $resultList]);
  507.     }
  508.     /**
  509.      * @Route("/export-class", name="pimcore_admin_dataobject_class_exportclass", methods={"GET"})
  510.      *
  511.      * @param Request $request
  512.      *
  513.      * @return Response
  514.      */
  515.     public function exportClassAction(Request $request)
  516.     {
  517.         $id $request->get('id');
  518.         $class DataObject\ClassDefinition::getById($id);
  519.         if (!$class instanceof DataObject\ClassDefinition) {
  520.             $errorMessage ': Class with id [ ' $id ' not found. ]';
  521.             Logger::error($errorMessage);
  522.             throw $this->createNotFoundException($errorMessage);
  523.         }
  524.         $json DataObject\ClassDefinition\Service::generateClassDefinitionJson($class);
  525.         $response = new Response($json);
  526.         $response->headers->set('Content-type''application/json');
  527.         $response->headers->set('Content-Disposition''attachment; filename="class_' $class->getName() . '_export.json"');
  528.         return $response;
  529.     }
  530.     /**
  531.      * @Route("/export-custom-layout-definition", name="pimcore_admin_dataobject_class_exportcustomlayoutdefinition", methods={"GET"})
  532.      *
  533.      * @param Request $request
  534.      *
  535.      * @return Response
  536.      */
  537.     public function exportCustomLayoutDefinitionAction(Request $request)
  538.     {
  539.         $id $request->get('id');
  540.         if ($id) {
  541.             $customLayout DataObject\ClassDefinition\CustomLayout::getById($id);
  542.             if ($customLayout) {
  543.                 $name $customLayout->getName();
  544.                 unset($customLayout->id);
  545.                 unset($customLayout->classId);
  546.                 unset($customLayout->name);
  547.                 unset($customLayout->creationDate);
  548.                 unset($customLayout->modificationDate);
  549.                 unset($customLayout->userOwner);
  550.                 unset($customLayout->userModification);
  551.                 unset($customLayout->fieldDefinitions);
  552.                 $json json_encode($customLayoutJSON_PRETTY_PRINT);
  553.                 $response = new Response($json);
  554.                 $response->headers->set('Content-type''application/json');
  555.                 $response->headers->set('Content-Disposition''attachment; filename="custom_definition_' $name '_export.json"');
  556.                 return $response;
  557.             }
  558.         }
  559.         $errorMessage ': Custom Layout with id [ ' $id ' not found. ]';
  560.         Logger::error($errorMessage);
  561.         throw $this->createNotFoundException($errorMessage);
  562.     }
  563.     /**
  564.      * FIELDCOLLECTIONS
  565.      */
  566.     /**
  567.      * @Route("/fieldcollection-get", name="pimcore_admin_dataobject_class_fieldcollectionget", methods={"GET"})
  568.      *
  569.      * @param Request $request
  570.      *
  571.      * @return JsonResponse
  572.      */
  573.     public function fieldcollectionGetAction(Request $request)
  574.     {
  575.         $fc DataObject\Fieldcollection\Definition::getByKey($request->get('id'));
  576.         return $this->adminJson($fc);
  577.     }
  578.     /**
  579.      * @Route("/fieldcollection-update", name="pimcore_admin_dataobject_class_fieldcollectionupdate", methods={"PUT", "POST"})
  580.      *
  581.      * @param Request $request
  582.      *
  583.      * @return JsonResponse
  584.      */
  585.     public function fieldcollectionUpdateAction(Request $request)
  586.     {
  587.         try {
  588.             $key $request->get('key');
  589.             $title $request->get('title');
  590.             $group $request->get('group');
  591.             if ($request->get('task') == 'add') {
  592.                 // check for existing fieldcollection with same name with different lower/upper cases
  593.                 $list = new DataObject\Fieldcollection\Definition\Listing();
  594.                 $list $list->load();
  595.                 foreach ($list as $item) {
  596.                     if (strtolower($key) === strtolower($item->getKey())) {
  597.                         throw new \Exception('FieldCollection with the same name already exists (lower/upper cases may be different)');
  598.                     }
  599.                 }
  600.             }
  601.             $fcDef = new DataObject\Fieldcollection\Definition();
  602.             $fcDef->setKey($key);
  603.             $fcDef->setTitle($title);
  604.             $fcDef->setGroup($group);
  605.             if ($request->get('values')) {
  606.                 $values $this->decodeJson($request->get('values'));
  607.                 $fcDef->setParentClass($values['parentClass']);
  608.                 $fcDef->setImplementsInterfaces($values['implementsInterfaces']);
  609.             }
  610.             if ($request->get('configuration')) {
  611.                 $configuration $this->decodeJson($request->get('configuration'));
  612.                 $configuration['datatype'] = 'layout';
  613.                 $configuration['fieldtype'] = 'panel';
  614.                 $layout DataObject\ClassDefinition\Service::generateLayoutTreeFromArray($configurationtrue);
  615.                 $fcDef->setLayoutDefinitions($layout);
  616.             }
  617.             $fcDef->save();
  618.             return $this->adminJson(['success' => true'id' => $fcDef->getKey()]);
  619.         } catch (\Exception $e) {
  620.             Logger::error($e->getMessage());
  621.             return $this->adminJson(['success' => false'message' => $e->getMessage()]);
  622.         }
  623.     }
  624.     /**
  625.      * @Route("/import-fieldcollection", name="pimcore_admin_dataobject_class_importfieldcollection", methods={"POST"})
  626.      *
  627.      * @param Request $request
  628.      *
  629.      * @return Response
  630.      */
  631.     public function importFieldcollectionAction(Request $request)
  632.     {
  633.         $fieldCollection DataObject\Fieldcollection\Definition::getByKey($request->get('id'));
  634.         $data file_get_contents($_FILES['Filedata']['tmp_name']);
  635.         $success DataObject\ClassDefinition\Service::importFieldCollectionFromJson($fieldCollection$data);
  636.         $response $this->adminJson([
  637.             'success' => $success
  638.         ]);
  639.         // set content-type to text/html, otherwise (when application/json is sent) chrome will complain in
  640.         // Ext.form.Action.Submit and mark the submission as failed
  641.         $response->headers->set('Content-Type''text/html');
  642.         return $response;
  643.     }
  644.     /**
  645.      * @Route("/export-fieldcollection", name="pimcore_admin_dataobject_class_exportfieldcollection", methods={"GET"})
  646.      *
  647.      * @param Request $request
  648.      *
  649.      * @return Response
  650.      */
  651.     public function exportFieldcollectionAction(Request $request)
  652.     {
  653.         $fieldCollection DataObject\Fieldcollection\Definition::getByKey($request->get('id'));
  654.         if (!$fieldCollection instanceof DataObject\Fieldcollection\Definition) {
  655.             $errorMessage ': Field-Collection with id [ ' $request->get('id') . ' not found. ]';
  656.             Logger::error($errorMessage);
  657.             throw $this->createNotFoundException($errorMessage);
  658.         }
  659.         $json DataObject\ClassDefinition\Service::generateFieldCollectionJson($fieldCollection);
  660.         $response = new Response($json);
  661.         $response->headers->set('Content-type''application/json');
  662.         $response->headers->set('Content-Disposition''attachment; filename="fieldcollection_' $fieldCollection->getKey() . '_export.json"');
  663.         return $response;
  664.     }
  665.     /**
  666.      * @Route("/fieldcollection-delete", name="pimcore_admin_dataobject_class_fieldcollectiondelete", methods={"DELETE"})
  667.      *
  668.      * @param Request $request
  669.      *
  670.      * @return JsonResponse
  671.      */
  672.     public function fieldcollectionDeleteAction(Request $request)
  673.     {
  674.         $fc DataObject\Fieldcollection\Definition::getByKey($request->get('id'));
  675.         $fc->delete();
  676.         return $this->adminJson(['success' => true]);
  677.     }
  678.     /**
  679.      * @Route("/fieldcollection-tree", name="pimcore_admin_dataobject_class_fieldcollectiontree", methods={"GET", "POST"})
  680.      *
  681.      * @param Request $request
  682.      *
  683.      * @return JsonResponse
  684.      */
  685.     public function fieldcollectionTreeAction(Request $request)
  686.     {
  687.         $list = new DataObject\Fieldcollection\Definition\Listing();
  688.         $list $list->load();
  689.         $forObjectEditor $request->get('forObjectEditor');
  690.         $layoutDefinitions = [];
  691.         $definitions = [];
  692.         $allowedTypes null;
  693.         if ($request->query->has('allowedTypes')) {
  694.             $allowedTypes explode(','$request->get('allowedTypes'));
  695.         }
  696.         $object DataObject\AbstractObject::getById($request->get('object_id'));
  697.         $currentLayoutId $request->get('layoutId'null);
  698.         $user = \Pimcore\Tool\Admin::getCurrentUser();
  699.         $groups = [];
  700.         /** @var DataObject\Fieldcollection\Definition $item */
  701.         foreach ($list as $item) {
  702.             if ($allowedTypes && !in_array($item->getKey(), $allowedTypes)) {
  703.                 continue;
  704.             }
  705.             if ($item->getGroup()) {
  706.                 if (!isset($groups[$item->getGroup()])) {
  707.                     $groups[$item->getGroup()] = [
  708.                         'id' => 'group_' $item->getKey(),
  709.                         'text' => $item->getGroup(),
  710.                         'expandable' => true,
  711.                         'leaf' => false,
  712.                         'allowChildren' => true,
  713.                         'iconCls' => 'pimcore_icon_folder',
  714.                         'group' => $item->getGroup(),
  715.                         'children' => []
  716.                     ];
  717.                 }
  718.                 if ($forObjectEditor) {
  719.                     $itemLayoutDefinitions $item->getLayoutDefinitions();
  720.                     DataObject\Service::enrichLayoutDefinition($itemLayoutDefinitions$object);
  721.                     if ($currentLayoutId == -&& $user->isAdmin()) {
  722.                         DataObject\Service::createSuperLayout($itemLayoutDefinitions);
  723.                     }
  724.                     $layoutDefinitions[$item->getKey()] = $itemLayoutDefinitions;
  725.                 }
  726.                 $groups[$item->getGroup()]['children'][] =
  727.                     [
  728.                         'id' => $item->getKey(),
  729.                         'text' => $item->getKey(),
  730.                         'title' => $item->getTitle(),
  731.                         'key' => $item->getKey(),
  732.                         'leaf' => true,
  733.                         'iconCls' => 'pimcore_icon_fieldcollection'
  734.                     ];
  735.             } else {
  736.                 if ($forObjectEditor) {
  737.                     $itemLayoutDefinitions $item->getLayoutDefinitions();
  738.                     DataObject\Service::enrichLayoutDefinition($itemLayoutDefinitions$object);
  739.                     if ($currentLayoutId == -&& $user->isAdmin()) {
  740.                         DataObject\Service::createSuperLayout($itemLayoutDefinitions);
  741.                     }
  742.                     $layoutDefinitions[$item->getKey()] = $itemLayoutDefinitions;
  743.                 }
  744.                 $definitions[] = [
  745.                     'id' => $item->getKey(),
  746.                     'text' => $item->getKey(),
  747.                     'title' => $item->getTitle(),
  748.                     'key' => $item->getKey(),
  749.                     'leaf' => true,
  750.                     'iconCls' => 'pimcore_icon_fieldcollection'
  751.                 ];
  752.             }
  753.         }
  754.         foreach ($groups as $group) {
  755.             $definitions[] = $group;
  756.         }
  757.         $event = new GenericEvent($this, [
  758.             'list' => $definitions,
  759.             'objectId' => $request->get('object_id')
  760.         ]);
  761.         \Pimcore::getEventDispatcher()->dispatch(AdminEvents::CLASS_FIELDCOLLECTION_LIST_PRE_SEND_DATA$event);
  762.         $definitions $event->getArgument('list');
  763.         if ($forObjectEditor) {
  764.             return $this->adminJson(['fieldcollections' => $definitions'layoutDefinitions' => $layoutDefinitions]);
  765.         } else {
  766.             return $this->adminJson($definitions);
  767.         }
  768.     }
  769.     /**
  770.      * @Route("/fieldcollection-list", name="pimcore_admin_dataobject_class_fieldcollectionlist", methods={"GET"})
  771.      *
  772.      * @param Request $request
  773.      *
  774.      * @return JsonResponse
  775.      */
  776.     public function fieldcollectionListAction(Request $request)
  777.     {
  778.         $user = \Pimcore\Tool\Admin::getCurrentUser();
  779.         $currentLayoutId $request->get('layoutId');
  780.         $list = new DataObject\Fieldcollection\Definition\Listing();
  781.         $list $list->load();
  782.         if ($request->query->has('allowedTypes')) {
  783.             $filteredList = [];
  784.             $allowedTypes explode(','$request->get('allowedTypes'));
  785.             /** @var DataObject\Fieldcollection\Definition $type */
  786.             foreach ($list as $type) {
  787.                 if (in_array($type->getKey(), $allowedTypes)) {
  788.                     $filteredList[] = $type;
  789.                     // mainly for objects-meta data-type
  790.                     $layoutDefinitions $type->getLayoutDefinitions();
  791.                     $context = [
  792.                         'containerType' => 'fieldcollection',
  793.                         'containerKey' => $type->getKey(),
  794.                         'outerFieldname' => $request->get('field_name')
  795.                     ];
  796.                     $object DataObject\AbstractObject::getById($request->get('object_id'));
  797.                     DataObject\Service::enrichLayoutDefinition($layoutDefinitions$object$context);
  798.                     if ($currentLayoutId == -&& $user->isAdmin()) {
  799.                         DataObject\Service::createSuperLayout($layoutDefinitions);
  800.                     }
  801.                 }
  802.             }
  803.             $list $filteredList;
  804.         }
  805.         $event = new GenericEvent($this, [
  806.             'list' => $list,
  807.             'objectId' => $request->get('object_id')
  808.         ]);
  809.         \Pimcore::getEventDispatcher()->dispatch(AdminEvents::CLASS_FIELDCOLLECTION_LIST_PRE_SEND_DATA$event);
  810.         $list $event->getArgument('list');
  811.         return $this->adminJson(['fieldcollections' => $list]);
  812.     }
  813.     /**
  814.      * @Route("/get-class-definition-for-column-config", name="pimcore_admin_dataobject_class_getclassdefinitionforcolumnconfig", methods={"GET"})
  815.      *
  816.      * @param Request $request
  817.      *
  818.      * @return JsonResponse
  819.      */
  820.     public function getClassDefinitionForColumnConfigAction(Request $request)
  821.     {
  822.         $class DataObject\ClassDefinition::getById($request->get('id'));
  823.         $objectId intval($request->get('oid'));
  824.         $filteredDefinitions DataObject\Service::getCustomLayoutDefinitionForGridColumnConfig($class$objectId);
  825.         $layoutDefinitions = isset($filteredDefinitions['layoutDefinition']) ? $filteredDefinitions['layoutDefinition'] : false;
  826.         $filteredFieldDefinition = isset($filteredDefinitions['fieldDefinition']) ? $filteredDefinitions['fieldDefinition'] : false;
  827.         $class->setFieldDefinitions([]);
  828.         $result = [];
  829.         $result['objectColumns']['childs'] = $layoutDefinitions->getChilds();
  830.         $result['objectColumns']['nodeLabel'] = 'object_columns';
  831.         $result['objectColumns']['nodeType'] = 'object';
  832.         // array("id", "fullpath", "published", "creationDate", "modificationDate", "filename", "classname");
  833.         $systemColumnNames DataObject\Concrete::$systemColumnNames;
  834.         $systemColumns = [];
  835.         foreach ($systemColumnNames as $systemColumn) {
  836.             $systemColumns[] = ['title' => $systemColumn'name' => $systemColumn'datatype' => 'data''fieldtype' => 'system'];
  837.         }
  838.         $result['systemColumns']['nodeLabel'] = 'system_columns';
  839.         $result['systemColumns']['nodeType'] = 'system';
  840.         $result['systemColumns']['childs'] = $systemColumns;
  841.         $list = new DataObject\Objectbrick\Definition\Listing();
  842.         $list $list->load();
  843.         foreach ($list as $brickDefinition) {
  844.             $classDefs $brickDefinition->getClassDefinitions();
  845.             if (!empty($classDefs)) {
  846.                 foreach ($classDefs as $classDef) {
  847.                     if ($classDef['classname'] == $class->getName()) {
  848.                         $fieldName $classDef['fieldname'];
  849.                         if ($filteredFieldDefinition && !$filteredFieldDefinition[$fieldName]) {
  850.                             continue;
  851.                         }
  852.                         $key $brickDefinition->getKey();
  853.                         $result[$key]['nodeLabel'] = $key;
  854.                         $result[$key]['brickField'] = $fieldName;
  855.                         $result[$key]['nodeType'] = 'objectbricks';
  856.                         $result[$key]['childs'] = $brickDefinition->getLayoutDefinitions()->getChildren();
  857.                         break;
  858.                     }
  859.                 }
  860.             }
  861.         }
  862.         return $this->adminJson($result);
  863.     }
  864.     /**
  865.      * OBJECT BRICKS
  866.      */
  867.     /**
  868.      * @Route("/objectbrick-get", name="pimcore_admin_dataobject_class_objectbrickget", methods={"GET"})
  869.      *
  870.      * @param Request $request
  871.      *
  872.      * @return JsonResponse
  873.      */
  874.     public function objectbrickGetAction(Request $request)
  875.     {
  876.         $fc DataObject\Objectbrick\Definition::getByKey($request->get('id'));
  877.         return $this->adminJson($fc);
  878.     }
  879.     /**
  880.      * @Route("/objectbrick-update", name="pimcore_admin_dataobject_class_objectbrickupdate", methods={"PUT", "POST"})
  881.      *
  882.      * @param Request $request
  883.      *
  884.      * @return JsonResponse
  885.      */
  886.     public function objectbrickUpdateAction(Request $request)
  887.     {
  888.         try {
  889.             $key $request->get('key');
  890.             $title $request->get('title');
  891.             $group $request->get('group');
  892.             if ($request->get('task') == 'add') {
  893.                 // check for existing brick with same name with different lower/upper cases
  894.                 $list = new DataObject\Objectbrick\Definition\Listing();
  895.                 $list $list->load();
  896.                 foreach ($list as $item) {
  897.                     if (strtolower($key) === strtolower($item->getKey())) {
  898.                         throw new \Exception('Brick with the same name already exists (lower/upper cases may be different)');
  899.                     }
  900.                 }
  901.             }
  902.             // now we create a new definition
  903.             $brickDef = new DataObject\Objectbrick\Definition();
  904.             $brickDef->setKey($key);
  905.             $brickDef->setTitle($title);
  906.             $brickDef->setGroup($group);
  907.             if ($request->get('values')) {
  908.                 $values $this->decodeJson($request->get('values'));
  909.                 $brickDef->setParentClass($values['parentClass']);
  910.                 $brickDef->setImplementsInterfaces($values['implementsInterfaces']);
  911.                 $brickDef->setClassDefinitions($values['classDefinitions']);
  912.             }
  913.             if ($request->get('configuration')) {
  914.                 $configuration $this->decodeJson($request->get('configuration'));
  915.                 $configuration['datatype'] = 'layout';
  916.                 $configuration['fieldtype'] = 'panel';
  917.                 $layout DataObject\ClassDefinition\Service::generateLayoutTreeFromArray($configurationtrue);
  918.                 $brickDef->setLayoutDefinitions($layout);
  919.             }
  920.             $event = new GenericEvent($this, [
  921.                 'brickDefinition' => $brickDef
  922.             ]);
  923.             \Pimcore::getEventDispatcher()->dispatch(AdminEvents::CLASS_OBJECTBRICK_UPDATE_DEFINITION$event);
  924.             $brickDef $event->getArgument('brickDefinition');
  925.             $brickDef->save();
  926.             return $this->adminJson(['success' => true'id' => $brickDef->getKey()]);
  927.         } catch (\Exception $e) {
  928.             Logger::error($e->getMessage());
  929.             return $this->adminJson(['success' => false'message' => $e->getMessage()]);
  930.         }
  931.     }
  932.     /**
  933.      * @Route("/import-objectbrick", name="pimcore_admin_dataobject_class_importobjectbrick", methods={"POST"})
  934.      *
  935.      * @param Request $request
  936.      *
  937.      * @return JsonResponse
  938.      */
  939.     public function importObjectbrickAction(Request $request)
  940.     {
  941.         $objectBrick DataObject\Objectbrick\Definition::getByKey($request->get('id'));
  942.         $data file_get_contents($_FILES['Filedata']['tmp_name']);
  943.         $success DataObject\ClassDefinition\Service::importObjectBrickFromJson($objectBrick$data);
  944.         $response $this->adminJson([
  945.             'success' => $success
  946.         ]);
  947.         // set content-type to text/html, otherwise (when application/json is sent) chrome will complain in
  948.         // Ext.form.Action.Submit and mark the submission as failed
  949.         $response->headers->set('Content-Type''text/html');
  950.         return $response;
  951.     }
  952.     /**
  953.      * @Route("/export-objectbrick", name="pimcore_admin_dataobject_class_exportobjectbrick", methods={"GET"})
  954.      *
  955.      * @param Request $request
  956.      *
  957.      * @return Response
  958.      */
  959.     public function exportObjectbrickAction(Request $request)
  960.     {
  961.         $objectBrick DataObject\Objectbrick\Definition::getByKey($request->get('id'));
  962.         if (!$objectBrick instanceof DataObject\Objectbrick\Definition) {
  963.             $errorMessage ': Object-Brick with id [ ' $request->get('id') . ' not found. ]';
  964.             Logger::error($errorMessage);
  965.             throw $this->createNotFoundException($errorMessage);
  966.         }
  967.         $xml DataObject\ClassDefinition\Service::generateObjectBrickJson($objectBrick);
  968.         $response = new Response($xml);
  969.         $response->headers->set('Content-type''application/json');
  970.         $response->headers->set('Content-Disposition''attachment; filename="objectbrick_' $objectBrick->getKey() . '_export.json"');
  971.         return $response;
  972.     }
  973.     /**
  974.      * @Route("/objectbrick-delete", name="pimcore_admin_dataobject_class_objectbrickdelete", methods={"DELETE"})
  975.      *
  976.      * @param Request $request
  977.      *
  978.      * @return JsonResponse
  979.      */
  980.     public function objectbrickDeleteAction(Request $request)
  981.     {
  982.         $fc DataObject\Objectbrick\Definition::getByKey($request->get('id'));
  983.         $fc->delete();
  984.         return $this->adminJson(['success' => true]);
  985.     }
  986.     /**
  987.      * @Route("/objectbrick-tree", name="pimcore_admin_dataobject_class_objectbricktree", methods={"GET", "POST"})
  988.      *
  989.      * @param Request $request
  990.      *
  991.      * @return JsonResponse
  992.      */
  993.     public function objectbrickTreeAction(Request $request)
  994.     {
  995.         $list = new DataObject\Objectbrick\Definition\Listing();
  996.         $list $list->load();
  997.         $forObjectEditor $request->get('forObjectEditor');
  998.         $layoutDefinitions = [];
  999.         $groups = [];
  1000.         $definitions = [];
  1001.         $fieldname null;
  1002.         $className null;
  1003.         $object DataObject\AbstractObject::getById($request->get('object_id'));
  1004.         if ($request->query->has('class_id') && $request->query->has('field_name')) {
  1005.             $classId $request->get('class_id');
  1006.             $fieldname $request->get('field_name');
  1007.             $classDefinition DataObject\ClassDefinition::getById($classId);
  1008.             $className $classDefinition->getName();
  1009.         }
  1010.         /** @var DataObject\Objectbrick\Definition $item */
  1011.         foreach ($list as $item) {
  1012.             if ($request->query->has('class_id') && $request->query->has('field_name')) {
  1013.                 $keep false;
  1014.                 $clsDefs $item->getClassDefinitions();
  1015.                 if (!empty($clsDefs)) {
  1016.                     foreach ($clsDefs as $cd) {
  1017.                         if ($cd['classname'] == $className && $cd['fieldname'] == $fieldname) {
  1018.                             $keep true;
  1019.                             continue;
  1020.                         }
  1021.                     }
  1022.                 }
  1023.                 if (!$keep) {
  1024.                     continue;
  1025.                 }
  1026.             }
  1027.             if ($item->getGroup()) {
  1028.                 if (!isset($groups[$item->getGroup()])) {
  1029.                     $groups[$item->getGroup()] = [
  1030.                         'id' => 'group_' $item->getKey(),
  1031.                         'text' => $item->getGroup(),
  1032.                         'expandable' => true,
  1033.                         'leaf' => false,
  1034.                         'allowChildren' => true,
  1035.                         'iconCls' => 'pimcore_icon_folder',
  1036.                         'group' => $item->getGroup(),
  1037.                         'children' => []
  1038.                     ];
  1039.                 }
  1040.                 if ($forObjectEditor) {
  1041.                     $itemLayoutDefinitions $item->getLayoutDefinitions();
  1042.                     DataObject\Service::enrichLayoutDefinition($itemLayoutDefinitions$object);
  1043.                     $layoutDefinitions[$item->getKey()] = $itemLayoutDefinitions;
  1044.                 }
  1045.                 $groups[$item->getGroup()]['children'][] =
  1046.                     [
  1047.                         'id' => $item->getKey(),
  1048.                         'text' => $item->getKey(),
  1049.                         'title' => $item->getTitle(),
  1050.                         'key' => $item->getKey(),
  1051.                         'leaf' => true,
  1052.                         'iconCls' => 'pimcore_icon_objectbricks'
  1053.                     ];
  1054.             } else {
  1055.                 if ($forObjectEditor) {
  1056.                     $layout $item->getLayoutDefinitions();
  1057.                     $currentLayoutId $request->get('layoutId'null);
  1058.                     $user $this->getAdminUser();
  1059.                     if ($currentLayoutId == -&& $user->isAdmin()) {
  1060.                         DataObject\Service::createSuperLayout($layout);
  1061.                         $objectData['layout'] = $layout;
  1062.                     }
  1063.                     $context = [
  1064.                         'containerType' => 'objectbrick',
  1065.                         'containerKey' => $item->getKey(),
  1066.                         'outerFieldname' => $request->get('field_name')
  1067.                     ];
  1068.                     DataObject\Service::enrichLayoutDefinition($layout$object$context);
  1069.                     $layoutDefinitions[$item->getKey()] = $layout;
  1070.                 }
  1071.                 $definitions[] = [
  1072.                     'id' => $item->getKey(),
  1073.                     'text' => $item->getKey(),
  1074.                     'title' => $item->getTitle(),
  1075.                     'key' => $item->getKey(),
  1076.                     'leaf' => true,
  1077.                     'iconCls' => 'pimcore_icon_objectbricks'
  1078.                 ];
  1079.             }
  1080.         }
  1081.         foreach ($groups as $group) {
  1082.             $definitions[] = $group;
  1083.         }
  1084.         $event = new GenericEvent($this, [
  1085.             'list' => $definitions,
  1086.             'objectId' => $request->get('object_id')
  1087.         ]);
  1088.         \Pimcore::getEventDispatcher()->dispatch(AdminEvents::CLASS_OBJECTBRICK_LIST_PRE_SEND_DATA$event);
  1089.         $definitions $event->getArgument('list');
  1090.         if ($forObjectEditor) {
  1091.             return $this->adminJson(['objectbricks' => $definitions'layoutDefinitions' => $layoutDefinitions]);
  1092.         } else {
  1093.             return $this->adminJson($definitions);
  1094.         }
  1095.     }
  1096.     /**
  1097.      * @Route("/objectbrick-list", name="pimcore_admin_dataobject_class_objectbricklist", methods={"GET"})
  1098.      *
  1099.      * @param Request $request
  1100.      *
  1101.      * @return JsonResponse
  1102.      */
  1103.     public function objectbrickListAction(Request $request)
  1104.     {
  1105.         $list = new DataObject\Objectbrick\Definition\Listing();
  1106.         $list $list->load();
  1107.         if ($request->query->has('class_id') && $request->query->has('field_name')) {
  1108.             $filteredList = [];
  1109.             $classId $request->get('class_id');
  1110.             $fieldname $request->get('field_name');
  1111.             $classDefinition DataObject\ClassDefinition::getById($classId);
  1112.             $className $classDefinition->getName();
  1113.             foreach ($list as $type) {
  1114.                 $clsDefs $type->getClassDefinitions();
  1115.                 if (!empty($clsDefs)) {
  1116.                     foreach ($clsDefs as $cd) {
  1117.                         if ($cd['classname'] == $className && $cd['fieldname'] == $fieldname) {
  1118.                             $filteredList[] = $type;
  1119.                             continue;
  1120.                         }
  1121.                     }
  1122.                 }
  1123.                 $layout $type->getLayoutDefinitions();
  1124.                 $currentLayoutId $request->get('layoutId'null);
  1125.                 $user $this->getAdminUser();
  1126.                 if ($currentLayoutId == -&& $user->isAdmin()) {
  1127.                     DataObject\Service::createSuperLayout($layout);
  1128.                     $objectData['layout'] = $layout;
  1129.                 }
  1130.                 $context = [
  1131.                     'containerType' => 'objectbrick',
  1132.                     'containerKey' => $type->getKey(),
  1133.                     'outerFieldname' => $request->get('field_name')
  1134.                 ];
  1135.                 $object DataObject\AbstractObject::getById($request->get('object_id'));
  1136.                 DataObject\Service::enrichLayoutDefinition($layout$object$context);
  1137.                 $type->setLayoutDefinitions($layout);
  1138.             }
  1139.             $list $filteredList;
  1140.         }
  1141.         $event = new GenericEvent($this, [
  1142.             'list' => $list,
  1143.             'objectId' => $request->get('object_id')
  1144.         ]);
  1145.         \Pimcore::getEventDispatcher()->dispatch(AdminEvents::CLASS_OBJECTBRICK_LIST_PRE_SEND_DATA$event);
  1146.         $list $event->getArgument('list');
  1147.         return $this->adminJson(['objectbricks' => $list]);
  1148.     }
  1149.     /**
  1150.      * See http://www.pimcore.org/issues/browse/PIMCORE-2358
  1151.      * Add option to export/import all class definitions/brick definitions etc. at once
  1152.      */
  1153.     /**
  1154.      * @Route("/bulk-import", name="pimcore_admin_dataobject_class_bulkimport", methods={"POST"})
  1155.      *
  1156.      * @param Request $request
  1157.      *
  1158.      * @return JsonResponse
  1159.      */
  1160.     public function bulkImportAction(Request $request)
  1161.     {
  1162.         $result = [];
  1163.         $tmpName $_FILES['Filedata']['tmp_name'];
  1164.         $json file_get_contents($tmpName);
  1165.         $tmpName PIMCORE_SYSTEM_TEMP_DIRECTORY '/bulk-import-' uniqid() . '.tmp';
  1166.         file_put_contents($tmpName$json);
  1167.         Session::useSession(function (AttributeBagInterface $session) use ($tmpName) {
  1168.             $session->set('class_bulk_import_file'$tmpName);
  1169.         }, 'pimcore_objects');
  1170.         $json json_decode($jsontrue);
  1171.         foreach ($json as $groupName => $group) {
  1172.             foreach ($group as $groupItem) {
  1173.                 $displayName null;
  1174.                 $icon null;
  1175.                 if ($groupName == 'class') {
  1176.                     $name $groupItem['name'];
  1177.                     $icon 'class';
  1178.                 } elseif ($groupName == 'customlayout') {
  1179.                     $className $groupItem['className'];
  1180.                     $layoutData = ['className' => $className'name' => $groupItem['name']];
  1181.                     $name base64_encode(json_encode($layoutData));
  1182.                     $displayName $className ' / ' $groupItem['name'];
  1183.                     $icon 'custom_views';
  1184.                 } else {
  1185.                     if ($groupName == 'objectbrick') {
  1186.                         $icon 'objectbricks';
  1187.                     } elseif ($groupName == 'fieldcollection') {
  1188.                         $icon 'fieldcollection';
  1189.                     }
  1190.                     $name $groupItem['key'];
  1191.                 }
  1192.                 if (!$displayName) {
  1193.                     $displayName $name;
  1194.                 }
  1195.                 $result[] = ['icon' => $icon'checked' => true'type' => $groupName'name' => $name'displayName' => $displayName];
  1196.             }
  1197.         }
  1198.         $response $this->adminJson(['success' => true'data' => $result]);
  1199.         $response->headers->set('Content-Type''text/html');
  1200.         return $response;
  1201.     }
  1202.     /**
  1203.      * See http://www.pimcore.org/issues/browse/PIMCORE-2358
  1204.      * Add option to export/import all class definitions/brick definitions etc. at once
  1205.      */
  1206.     /**
  1207.      * @Route("/bulk-commit", name="pimcore_admin_dataobject_class_bulkcommit", methods={"POST"})
  1208.      *
  1209.      * @param Request $request
  1210.      *
  1211.      * @return JsonResponse
  1212.      *
  1213.      * @throws \Exception
  1214.      */
  1215.     public function bulkCommitAction(Request $request)
  1216.     {
  1217.         $data json_decode($request->get('data'), true);
  1218.         $session Session::get('pimcore_objects');
  1219.         $filename $session->get('class_bulk_import_file');
  1220.         $json = @file_get_contents($filename);
  1221.         $json json_decode($jsontrue);
  1222.         $type $data['type'];
  1223.         $name $data['name'];
  1224.         $list $json[$type];
  1225.         foreach ($list as $item) {
  1226.             unset($item['creationDate']);
  1227.             unset($item['modificationDate']);
  1228.             unset($item['userOwner']);
  1229.             unset($item['userModification']);
  1230.             if ($type == 'class' && $item['name'] == $name) {
  1231.                 $class DataObject\ClassDefinition::getByName($name);
  1232.                 if (!$class) {
  1233.                     $class = new DataObject\ClassDefinition();
  1234.                     $class->setName($name);
  1235.                 }
  1236.                 $success DataObject\ClassDefinition\Service::importClassDefinitionFromJson($classjson_encode($item), true);
  1237.                 return $this->adminJson(['success' => $success !== false]);
  1238.             } elseif ($type == 'objectbrick' && $item['key'] == $name) {
  1239.                 if (!$brick DataObject\Objectbrick\Definition::getByKey($name)) {
  1240.                     $brick = new DataObject\Objectbrick\Definition();
  1241.                     $brick->setKey($name);
  1242.                 }
  1243.                 $success DataObject\ClassDefinition\Service::importObjectBrickFromJson($brickjson_encode($item), true);
  1244.                 return $this->adminJson(['success' => $success !== false]);
  1245.             } elseif ($type == 'fieldcollection' && $item['key'] == $name) {
  1246.                 if (!$fieldCollection DataObject\Fieldcollection\Definition::getByKey($name)) {
  1247.                     $fieldCollection = new DataObject\Fieldcollection\Definition();
  1248.                     $fieldCollection->setKey($name);
  1249.                 }
  1250.                 $success DataObject\ClassDefinition\Service::importFieldCollectionFromJson($fieldCollectionjson_encode($item), true);
  1251.                 return $this->adminJson(['success' => $success !== false]);
  1252.             } elseif ($type == 'customlayout') {
  1253.                 $layoutData json_decode(base64_decode($data['name']), true);
  1254.                 $className $layoutData['className'];
  1255.                 $layoutName $layoutData['name'];
  1256.                 if ($item['name'] == $layoutName && $item['className'] == $className) {
  1257.                     $class DataObject\ClassDefinition::getByName($className);
  1258.                     if (!$class) {
  1259.                         throw new \Exception('Class does not exist');
  1260.                     }
  1261.                     $classId $class->getId();
  1262.                     $layoutList = new DataObject\ClassDefinition\CustomLayout\Listing();
  1263.                     $db = \Pimcore\Db::get();
  1264.                     $layoutList->setCondition('name = ' $db->quote($layoutName) . ' AND classId = ' $classId);
  1265.                     $layoutList $layoutList->load();
  1266.                     $layoutDefinition null;
  1267.                     if ($layoutList) {
  1268.                         $layoutDefinition $layoutList[0];
  1269.                     }
  1270.                     if (!$layoutDefinition) {
  1271.                         $layoutDefinition = new DataObject\ClassDefinition\CustomLayout();
  1272.                         $layoutDefinition->setName($layoutName);
  1273.                         $layoutDefinition->setClassId($classId);
  1274.                     }
  1275.                     try {
  1276.                         $layoutDefinition->setDescription($item['description']);
  1277.                         $layoutDef DataObject\ClassDefinition\Service::generateLayoutTreeFromArray($item['layoutDefinitions'], true);
  1278.                         $layoutDefinition->setLayoutDefinitions($layoutDef);
  1279.                         $layoutDefinition->save();
  1280.                     } catch (\Exception $e) {
  1281.                         Logger::error($e->getMessage());
  1282.                         return $this->adminJson(['success' => false'message' => $e->getMessage()]);
  1283.                     }
  1284.                 }
  1285.             }
  1286.         }
  1287.         return $this->adminJson(['success' => true]);
  1288.     }
  1289.     /**
  1290.      * See http://www.pimcore.org/issues/browse/PIMCORE-2358
  1291.      * Add option to export/import all class definitions/brick definitions etc. at once
  1292.      */
  1293.     /**
  1294.      * @Route("/bulk-export-prepare", name="pimcore_admin_dataobject_class_bulkexportprepare", methods={"POST"})
  1295.      *
  1296.      * @param Request $request
  1297.      *
  1298.      * @return Response
  1299.      */
  1300.     public function bulkExportPrepareAction(Request $request)
  1301.     {
  1302.         $data $request->get('data');
  1303.         Session::useSession(function (AttributeBagInterface $session) use ($data) {
  1304.             $session->set('class_bulk_export_settings'$data);
  1305.         }, 'pimcore_objects');
  1306.         return $this->adminJson(['success' => true]);
  1307.     }
  1308.     /**
  1309.      * @Route("/bulk-export", name="pimcore_admin_dataobject_class_bulkexport", methods={"GET"})
  1310.      *
  1311.      * @param Request $request
  1312.      *
  1313.      * @return Response
  1314.      */
  1315.     public function bulkExportAction(Request $request)
  1316.     {
  1317.         $result = [];
  1318.         $fieldCollections = new DataObject\Fieldcollection\Definition\Listing();
  1319.         $fieldCollections $fieldCollections->load();
  1320.         foreach ($fieldCollections as $fieldCollection) {
  1321.             $result[] = [
  1322.                 'icon' => 'fieldcollection',
  1323.                 'checked' => true,
  1324.                 'type' => 'fieldcollection',
  1325.                 'name' => $fieldCollection->getKey(),
  1326.                 'displayName' => $fieldCollection->getKey()
  1327.             ];
  1328.         }
  1329.         $classes = new DataObject\ClassDefinition\Listing();
  1330.         $classes->setOrder('ASC');
  1331.         $classes->setOrderKey('id');
  1332.         $classes $classes->load();
  1333.         foreach ($classes as $class) {
  1334.             $result[] = [
  1335.                 'icon' => 'class',
  1336.                 'checked' => true,
  1337.                 'type' => 'class',
  1338.                 'name' => $class->getName(),
  1339.                 'displayName' => $class->getName()
  1340.             ];
  1341.         }
  1342.         $objectBricks = new DataObject\Objectbrick\Definition\Listing();
  1343.         $objectBricks $objectBricks->load();
  1344.         foreach ($objectBricks as $objectBrick) {
  1345.             $result[] = [
  1346.                 'icon' => 'objectbricks',
  1347.                 'checked' => true,
  1348.                 'type' => 'objectbrick',
  1349.                 'name' => $objectBrick->getKey(),
  1350.                 'displayName' => $objectBrick->getKey()
  1351.             ];
  1352.         }
  1353.         $customLayouts = new DataObject\ClassDefinition\CustomLayout\Listing();
  1354.         $customLayouts $customLayouts->load();
  1355.         foreach ($customLayouts as $customLayout) {
  1356.             $class DataObject\ClassDefinition::getById($customLayout->getClassId());
  1357.             $displayName $class->getName() . ' / ' .  $customLayout->getName();
  1358.             $result[] = [
  1359.                 'icon' => 'custom_views',
  1360.                 'checked' => true,
  1361.                 'type' => 'customlayout',
  1362.                 'name' => $customLayout->getId(),
  1363.                 'displayName' => $displayName
  1364.             ];
  1365.         }
  1366.         return new JsonResponse(['success' => true'data' => $result]);
  1367.     }
  1368.     /**
  1369.      * @Route("/do-bulk-export", name="pimcore_admin_dataobject_class_dobulkexport", methods={"GET"})
  1370.      *
  1371.      * @param Request $request
  1372.      *
  1373.      * @return Response
  1374.      */
  1375.     public function doBulkExportAction(Request $request)
  1376.     {
  1377.         $session Session::get('pimcore_objects');
  1378.         $list $session->get('class_bulk_export_settings');
  1379.         $list json_decode($listtrue);
  1380.         $result = [];
  1381.         foreach ($list as $item) {
  1382.             if ($item['type'] == 'fieldcollection') {
  1383.                 $fieldCollection DataObject\Fieldcollection\Definition::getByKey($item['name']);
  1384.                 $key $fieldCollection->getKey();
  1385.                 $fieldCollectionJson json_decode(DataObject\ClassDefinition\Service::generateFieldCollectionJson($fieldCollection));
  1386.                 $fieldCollectionJson->key $key;
  1387.                 $result['fieldcollection'][] = $fieldCollectionJson;
  1388.             } elseif ($item['type'] == 'class') {
  1389.                 $class DataObject\ClassDefinition::getByName($item['name']);
  1390.                 $data Model\Webservice\Data\Mapper::map($class'\\Pimcore\\Model\\Webservice\\Data\\ClassDefinition\\Out''out');
  1391.                 unset($data->fieldDefinitions);
  1392.                 $result['class'][] = $data;
  1393.             } elseif ($item['type'] == 'objectbrick') {
  1394.                 $objectBrick DataObject\Objectbrick\Definition::getByKey($item['name']);
  1395.                 $key $objectBrick->getKey();
  1396.                 $objectBrickJson json_decode(DataObject\ClassDefinition\Service::generateObjectBrickJson($objectBrick));
  1397.                 $objectBrickJson->key $key;
  1398.                 $result['objectbrick'][] = $objectBrickJson;
  1399.             } elseif ($item['type'] == 'customlayout') {
  1400.                 /** @var DataObject\ClassDefinition\CustomLayout $customLayout */
  1401.                 $customLayout DataObject\ClassDefinition\CustomLayout::getById($item['name']);
  1402.                 $classId $customLayout->getClassId();
  1403.                 $class DataObject\ClassDefinition::getById($classId);
  1404.                 $customLayout $customLayout->getObjectVars();
  1405.                 $customLayout['className'] = $class->getName();
  1406.                 $result['customlayout'][] = $customLayout;
  1407.             }
  1408.         }
  1409.         $result json_encode($resultJSON_PRETTY_PRINT);
  1410.         $response = new Response($result);
  1411.         $response->headers->set('Content-type''application/json');
  1412.         $response->headers->set('Content-Disposition''attachment; filename="bulk_export.json"');
  1413.         return $response;
  1414.     }
  1415.     /**
  1416.      * @param FilterControllerEvent $event
  1417.      */
  1418.     public function onKernelController(FilterControllerEvent $event)
  1419.     {
  1420.         $isMasterRequest $event->isMasterRequest();
  1421.         if (!$isMasterRequest) {
  1422.             return;
  1423.         }
  1424.         // check permissions
  1425.         $unrestrictedActions = [
  1426.             'getTreeAction''fieldcollectionListAction''fieldcollectionTreeAction''fieldcollectionGetAction',
  1427.             'getClassDefinitionForColumnConfigAction''objectbrickListAction''objectbrickTreeAction''objectbrickGetAction'
  1428.         ];
  1429.         $this->checkActionPermission($event'classes'$unrestrictedActions);
  1430.     }
  1431.     /**
  1432.      * @param FilterResponseEvent $event
  1433.      */
  1434.     public function onKernelResponse(FilterResponseEvent $event)
  1435.     {
  1436.         // nothing to do
  1437.     }
  1438.     /**
  1439.      * @Route("/get-fieldcollection-usages", name="pimcore_admin_dataobject_class_getfieldcollectionusages", methods={"GET"})
  1440.      *
  1441.      * @param Request $request
  1442.      *
  1443.      * @return Response
  1444.      */
  1445.     public function getFieldcollectionUsagesAction(Request $request)
  1446.     {
  1447.         $key $request->get('key');
  1448.         $result = [];
  1449.         $classes = new DataObject\ClassDefinition\Listing();
  1450.         $classes $classes->load();
  1451.         foreach ($classes as $class) {
  1452.             $fieldDefs $class->getFieldDefinitions();
  1453.             foreach ($fieldDefs as $fieldDef) {
  1454.                 if ($fieldDef instanceof DataObject\ClassDefinition\Data\Fieldcollections) {
  1455.                     $allowedKeys $fieldDef->getAllowedTypes();
  1456.                     if (is_array($allowedKeys) && in_array($key$allowedKeys)) {
  1457.                         $result[] = [
  1458.                             'class' => $class->getName(),
  1459.                             'field' => $fieldDef->getName()
  1460.                         ];
  1461.                     }
  1462.                 }
  1463.             }
  1464.         }
  1465.         return $this->adminJson($result);
  1466.     }
  1467.     /**
  1468.      * @Route("/get-bricks-usages", name="pimcore_admin_dataobject_class_getbrickusages", methods={"GET"})
  1469.      *
  1470.      * @param Request $request
  1471.      *
  1472.      * @return Response
  1473.      */
  1474.     public function getBrickUsagesAction(Request $request)
  1475.     {
  1476.         $classId $request->get('classId');
  1477.         $myclass DataObject\ClassDefinition::getById($classId);
  1478.         $result = [];
  1479.         $brickDefinitions = new DataObject\Objectbrick\Definition\Listing();
  1480.         $brickDefinitions $brickDefinitions->load();
  1481.         foreach ($brickDefinitions as $brickDefinition) {
  1482.             $classes $brickDefinition->getClassDefinitions();
  1483.             foreach ($classes as $class) {
  1484.                 if ($myclass->getName() == $class['classname']) {
  1485.                     $result[] = [
  1486.                         'objectbrick' => $brickDefinition->getKey(),
  1487.                         'field' => $class['fieldname']
  1488.                     ];
  1489.                 }
  1490.             }
  1491.         }
  1492.         return $this->adminJson($result);
  1493.     }
  1494.     /**
  1495.      * @Route("/get-icons", name="pimcore_admin_dataobject_class_geticons", methods={"GET"})
  1496.      *
  1497.      * @param Request $request
  1498.      *
  1499.      * @return Response
  1500.      */
  1501.     public function getIconsAction(Request $request)
  1502.     {
  1503.         $classId $request->get('classId');
  1504.         $iconDir PIMCORE_WEB_ROOT '/bundles/pimcoreadmin/img';
  1505.         $classIcons rscandir($iconDir '/object-icons/');
  1506.         $colorIcons rscandir($iconDir '/flat-color-icons/');
  1507.         $twemoji rscandir($iconDir '/twemoji/');
  1508.         $icons array_merge($classIcons$colorIcons$twemoji);
  1509.         foreach ($icons as &$icon) {
  1510.             $icon str_replace(PIMCORE_WEB_ROOT''$icon);
  1511.         }
  1512.         $event = new GenericEvent($this, [
  1513.             'icons' => $icons,
  1514.             'classId' => $classId
  1515.         ]);
  1516.         \Pimcore::getEventDispatcher()->dispatch(AdminEvents::CLASS_OBJECT_ICONS_PRE_SEND_DATA$event);
  1517.         $icons $event->getArgument('icons');
  1518.         $result = [];
  1519.         foreach ($icons as $icon) {
  1520.             $result[] = [
  1521.                 'text' => "<img src='{$icon}'>",
  1522.                 'value' => $icon
  1523.             ];
  1524.         }
  1525.         return $this->adminJson($result);
  1526.     }
  1527.     /**
  1528.      * @Route("/suggest-class-identifier", name="pimcore_admin_dataobject_class_suggestclassidentifier")
  1529.      *
  1530.      * @return Response
  1531.      */
  1532.     public function suggestClassIdentifierAction()
  1533.     {
  1534.         $db Db::get();
  1535.         $maxId $db->fetchOne('SELECT MAX(CAST(id AS SIGNED)) FROM classes;');
  1536.         $existingIds $db->fetchCol('select LOWER(id) from classes');
  1537.         $result = [
  1538.             'suggestedIdentifier' => $maxId $maxId 1,
  1539.             'existingIds' => $existingIds
  1540.             ];
  1541.         return $this->adminJson($result);
  1542.     }
  1543.     /**
  1544.      * @Route("/suggest-custom-layout-identifier", name="pimcore_admin_dataobject_class_suggestcustomlayoutidentifier")
  1545.      *
  1546.      * @param Request $request
  1547.      *
  1548.      * @return Response
  1549.      */
  1550.     public function suggestCustomLayoutIdentifierAction(Request $request)
  1551.     {
  1552.         $classId $request->get('classId');
  1553.         $identifier DataObject\ClassDefinition\CustomLayout::getIdentifier($classId);
  1554.         $list = new DataObject\ClassDefinition\CustomLayout\Listing();
  1555.         $list $list->load();
  1556.         $existingIds = [];
  1557.         $existingNames = [];
  1558.         /** @var DataObject\ClassDefinition\CustomLayout $item */
  1559.         foreach ($list as $item) {
  1560.             $existingIds[] = $item->getId();
  1561.             if ($item->getClassId() == $classId) {
  1562.                 $existingNames[] = $item->getName();
  1563.             }
  1564.         }
  1565.         $result = [
  1566.             'suggestedIdentifier' => $identifier,
  1567.             'existingIds' => $existingIds,
  1568.             'existingNames' => $existingNames
  1569.             ];
  1570.         return $this->adminJson($result);
  1571.     }
  1572. }