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

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