vendor/pimcore/pimcore/bundles/AdminBundle/Controller/Admin/SettingsController.php line 65

Open in your IDE?
  1. <?php
  2. /**
  3.  * Pimcore
  4.  *
  5.  * This source file is available under two different licenses:
  6.  * - GNU General Public License version 3 (GPLv3)
  7.  * - Pimcore Commercial License (PCL)
  8.  * Full copyright and license information is available in
  9.  * LICENSE.md which is distributed with this source code.
  10.  *
  11.  *  @copyright  Copyright (c) Pimcore GmbH (http://www.pimcore.org)
  12.  *  @license    http://www.pimcore.org/license     GPLv3 and PCL
  13.  */
  14. namespace Pimcore\Bundle\AdminBundle\Controller\Admin;
  15. use Pimcore\Bundle\AdminBundle\Controller\AdminController;
  16. use Pimcore\Cache;
  17. use Pimcore\Cache\Core\CoreCacheHandler;
  18. use Pimcore\Cache\Symfony\CacheClearer;
  19. use Pimcore\Config;
  20. use Pimcore\Event\SystemEvents;
  21. use Pimcore\File;
  22. use Pimcore\Localization\LocaleServiceInterface;
  23. use Pimcore\Model;
  24. use Pimcore\Model\Asset;
  25. use Pimcore\Model\Document;
  26. use Pimcore\Model\Element;
  27. use Pimcore\Model\Glossary;
  28. use Pimcore\Model\Metadata;
  29. use Pimcore\Model\Property;
  30. use Pimcore\Model\Staticroute;
  31. use Pimcore\Model\Tool\SettingsStore;
  32. use Pimcore\Model\WebsiteSetting;
  33. use Pimcore\Tool;
  34. use Symfony\Component\EventDispatcher\EventDispatcherInterface;
  35. use Symfony\Component\EventDispatcher\GenericEvent;
  36. use Symfony\Component\Filesystem\Filesystem;
  37. use Symfony\Component\HttpFoundation\JsonResponse;
  38. use Symfony\Component\HttpFoundation\Request;
  39. use Symfony\Component\HttpFoundation\Response;
  40. use Symfony\Component\HttpFoundation\StreamedResponse;
  41. use Symfony\Component\HttpKernel\KernelEvents;
  42. use Symfony\Component\HttpKernel\KernelInterface;
  43. use Symfony\Component\Routing\Annotation\Route;
  44. use Symfony\Component\Yaml\Yaml;
  45. /**
  46.  * @Route("/settings")
  47.  *
  48.  * @internal
  49.  */
  50. class SettingsController extends AdminController
  51. {
  52.     private const CUSTOM_LOGO_PATH 'custom-logo.image';
  53.     /**
  54.      * @Route("/display-custom-logo", name="pimcore_settings_display_custom_logo", methods={"GET"})
  55.      *
  56.      * @param Request $request
  57.      *
  58.      * @return StreamedResponse
  59.      */
  60.     public function displayCustomLogoAction(Request $request)
  61.     {
  62.         $mime 'image/svg+xml';
  63.         if ($request->get('white')) {
  64.             $logo PIMCORE_WEB_ROOT '/bundles/pimcoreadmin/img/logo-claim-white.svg';
  65.         } else {
  66.             $logo PIMCORE_WEB_ROOT '/bundles/pimcoreadmin/img/logo-claim-gray.svg';
  67.         }
  68.         $stream fopen($logo'rb');
  69.         $storage Tool\Storage::get('admin');
  70.         if ($storage->fileExists(self::CUSTOM_LOGO_PATH)) {
  71.             try {
  72.                 $mime $storage->mimeType(self::CUSTOM_LOGO_PATH);
  73.                 $stream $storage->readStream(self::CUSTOM_LOGO_PATH);
  74.             } catch (\Exception $e) {
  75.                 // do nothing
  76.             }
  77.         }
  78.         return new StreamedResponse(function () use ($stream) {
  79.             fpassthru($stream);
  80.         }, 200, ['Content-Type' => $mime]);
  81.     }
  82.     /**
  83.      * @Route("/upload-custom-logo", name="pimcore_admin_settings_uploadcustomlogo", methods={"POST"})
  84.      *
  85.      * @param Request $request
  86.      *
  87.      * @return JsonResponse
  88.      *
  89.      * @throws \Exception
  90.      */
  91.     public function uploadCustomLogoAction(Request $request)
  92.     {
  93.         $fileExt File::getFileExtension($_FILES['Filedata']['name']);
  94.         if (!in_array($fileExt, ['svg''png''jpg'])) {
  95.             throw new \Exception('Unsupported file format');
  96.         }
  97.         $storage Tool\Storage::get('admin');
  98.         $storage->writeStream(self::CUSTOM_LOGO_PATHfopen($_FILES['Filedata']['tmp_name'], 'rb'));
  99.         // set content-type to text/html, otherwise (when application/json is sent) chrome will complain in
  100.         // Ext.form.Action.Submit and mark the submission as failed
  101.         $response $this->adminJson(['success' => true]);
  102.         $response->headers->set('Content-Type''text/html');
  103.         return $response;
  104.     }
  105.     /**
  106.      * @Route("/delete-custom-logo", name="pimcore_admin_settings_deletecustomlogo", methods={"DELETE"})
  107.      *
  108.      * @param Request $request
  109.      *
  110.      * @return JsonResponse
  111.      */
  112.     public function deleteCustomLogoAction(Request $request)
  113.     {
  114.         if (Tool\Storage::get('admin')->fileExists(self::CUSTOM_LOGO_PATH)) {
  115.             Tool\Storage::get('admin')->delete(self::CUSTOM_LOGO_PATH);
  116.         }
  117.         return $this->adminJson(['success' => true]);
  118.     }
  119.     /**
  120.      * Used by the predefined metadata grid
  121.      *
  122.      * @Route("/predefined-metadata", name="pimcore_admin_settings_metadata", methods={"POST"})
  123.      *
  124.      * @param Request $request
  125.      *
  126.      * @return JsonResponse
  127.      */
  128.     public function metadataAction(Request $request)
  129.     {
  130.         $this->checkPermission('asset_metadata');
  131.         if ($request->get('data')) {
  132.             if ($request->get('xaction') == 'destroy') {
  133.                 $data $this->decodeJson($request->get('data'));
  134.                 $id $data['id'];
  135.                 $metadata Metadata\Predefined::getById($id);
  136.                 $metadata->delete();
  137.                 return $this->adminJson(['success' => true'data' => []]);
  138.             } elseif ($request->get('xaction') == 'update') {
  139.                 $data $this->decodeJson($request->get('data'));
  140.                 // save type
  141.                 $metadata Metadata\Predefined::getById($data['id']);
  142.                 $metadata->setValues($data);
  143.                 $existingItem Metadata\Predefined\Listing::getByKeyAndLanguage($metadata->getName(), $metadata->getLanguage(), $metadata->getTargetSubtype());
  144.                 if ($existingItem && $existingItem->getId() != $metadata->getId()) {
  145.                     return $this->adminJson(['message' => 'rule_violation''success' => false]);
  146.                 }
  147.                 $metadata->minimize();
  148.                 $metadata->save();
  149.                 $metadata->expand();
  150.                 return $this->adminJson(['data' => $metadata->getObjectVars(), 'success' => true]);
  151.             } elseif ($request->get('xaction') == 'create') {
  152.                 $data $this->decodeJson($request->get('data'));
  153.                 unset($data['id']);
  154.                 // save type
  155.                 $metadata Metadata\Predefined::create();
  156.                 $metadata->setValues($data);
  157.                 $existingItem Metadata\Predefined\Listing::getByKeyAndLanguage($metadata->getName(), $metadata->getLanguage(), $metadata->getTargetSubtype());
  158.                 if ($existingItem) {
  159.                     return $this->adminJson(['message' => 'rule_violation''success' => false]);
  160.                 }
  161.                 $metadata->save();
  162.                 return $this->adminJson(['data' => $metadata->getObjectVars(), 'success' => true]);
  163.             }
  164.         } else {
  165.             // get list of types
  166.             $list = new Metadata\Predefined\Listing();
  167.             if ($request->get('filter')) {
  168.                 $filter $request->get('filter');
  169.                 $list->setFilter(function ($row) use ($filter) {
  170.                     foreach ($row as $value) {
  171.                         if (strpos($value$filter) !== false) {
  172.                             return true;
  173.                         }
  174.                     }
  175.                     return false;
  176.                 });
  177.             }
  178.             $list->load();
  179.             $properties = [];
  180.             if (is_array($list->getDefinitions())) {
  181.                 foreach ($list->getDefinitions() as $metadata) {
  182.                     $metadata->expand();
  183.                     $properties[] = $metadata->getObjectVars();
  184.                 }
  185.             }
  186.             return $this->adminJson(['data' => $properties'success' => true'total' => $list->getTotalCount()]);
  187.         }
  188.         return $this->adminJson(['success' => false]);
  189.     }
  190.     /**
  191.      * @Route("/get-predefined-metadata", name="pimcore_admin_settings_getpredefinedmetadata", methods={"GET"})
  192.      *
  193.      * @param Request $request
  194.      *
  195.      * @return JsonResponse
  196.      */
  197.     public function getPredefinedMetadataAction(Request $request)
  198.     {
  199.         $type $request->get('type');
  200.         $subType $request->get('subType');
  201.         $group $request->get('group');
  202.         $list Metadata\Predefined\Listing::getByTargetType($type, [$subType]);
  203.         $result = [];
  204.         foreach ($list as $item) {
  205.             $itemGroup $item->getGroup() ?? '';
  206.             if ($group === 'default' || $group === $itemGroup) {
  207.                 $item->expand();
  208.                 $result[] = $item->getObjectVars();
  209.             }
  210.         }
  211.         return $this->adminJson(['data' => $result'success' => true]);
  212.     }
  213.     /**
  214.      * @Route("/properties", name="pimcore_admin_settings_properties", methods={"POST"})
  215.      *
  216.      * @param Request $request
  217.      *
  218.      * @return JsonResponse
  219.      */
  220.     public function propertiesAction(Request $request)
  221.     {
  222.         if ($request->get('data')) {
  223.             $this->checkPermission('predefined_properties');
  224.             if ($request->get('xaction') == 'destroy') {
  225.                 $data $this->decodeJson($request->get('data'));
  226.                 $id $data['id'];
  227.                 $property Property\Predefined::getById($id);
  228.                 $property->delete();
  229.                 return $this->adminJson(['success' => true'data' => []]);
  230.             } elseif ($request->get('xaction') == 'update') {
  231.                 $data $this->decodeJson($request->get('data'));
  232.                 // save type
  233.                 $property Property\Predefined::getById($data['id']);
  234.                 if (is_array($data['ctype'])) {
  235.                     $data['ctype'] = implode(','$data['ctype']);
  236.                 }
  237.                 $property->setValues($data);
  238.                 $property->save();
  239.                 return $this->adminJson(['data' => $property->getObjectVars(), 'success' => true]);
  240.             } elseif ($request->get('xaction') == 'create') {
  241.                 $data $this->decodeJson($request->get('data'));
  242.                 unset($data['id']);
  243.                 // save type
  244.                 $property Property\Predefined::create();
  245.                 $property->setValues($data);
  246.                 $property->save();
  247.                 return $this->adminJson(['data' => $property->getObjectVars(), 'success' => true]);
  248.             }
  249.         } else {
  250.             // get list of types
  251.             $list = new Property\Predefined\Listing();
  252.             if ($request->get('filter')) {
  253.                 $filter $request->get('filter');
  254.                 $list->setFilter(function ($row) use ($filter) {
  255.                     foreach ($row as $value) {
  256.                         if ($value) {
  257.                             $cellValues is_array($value) ? $value : [$value];
  258.                             foreach ($cellValues as $cellValue) {
  259.                                 if (strpos($cellValue$filter) !== false) {
  260.                                     return true;
  261.                                 }
  262.                             }
  263.                         }
  264.                     }
  265.                     return false;
  266.                 });
  267.             }
  268.             $list->load();
  269.             $properties = [];
  270.             if (is_array($list->getProperties())) {
  271.                 foreach ($list->getProperties() as $property) {
  272.                     $properties[] = $property->getObjectVars();
  273.                 }
  274.             }
  275.             return $this->adminJson(['data' => $properties'success' => true'total' => $list->getTotalCount()]);
  276.         }
  277.         return $this->adminJson(['success' => false]);
  278.     }
  279.     /**
  280.      * @Route("/get-system", name="pimcore_admin_settings_getsystem", methods={"GET"})
  281.      *
  282.      * @param Request $request
  283.      * @param Config $config
  284.      *
  285.      * @return JsonResponse
  286.      */
  287.     public function getSystemAction(Request $requestConfig $config)
  288.     {
  289.         $this->checkPermission('system_settings');
  290.         $valueArray = [
  291.             'general' => $config['general'],
  292.             'documents' => $config['documents'],
  293.             'assets' => $config['assets'],
  294.             'objects' => $config['objects'],
  295.             'branding' => $config['branding'],
  296.             'email' => $config['email'],
  297.         ];
  298.         $locales Tool::getSupportedLocales();
  299.         $languageOptions = [];
  300.         $validLanguages = [];
  301.         foreach ($locales as $short => $translation) {
  302.             if (!empty($short)) {
  303.                 $languageOptions[] = [
  304.                     'language' => $short,
  305.                     'display' => $translation " ($short)",
  306.                 ];
  307.                 $validLanguages[] = $short;
  308.             }
  309.         }
  310.         $valueArray['general']['valid_language'] = explode(','$valueArray['general']['valid_languages']);
  311.         //for "wrong" legacy values
  312.         if (is_array($valueArray['general']['valid_language'])) {
  313.             foreach ($valueArray['general']['valid_language'] as $existingValue) {
  314.                 if (!in_array($existingValue$validLanguages)) {
  315.                     $languageOptions[] = [
  316.                         'language' => $existingValue,
  317.                         'display' => $existingValue,
  318.                     ];
  319.                 }
  320.             }
  321.         }
  322.         $response = [
  323.             'values' => $valueArray,
  324.             'config' => [
  325.                 'languages' => $languageOptions,
  326.             ],
  327.         ];
  328.         return $this->adminJson($response);
  329.     }
  330.     /**
  331.      * @Route("/set-system", name="pimcore_admin_settings_setsystem", methods={"PUT"})
  332.      *
  333.      * @param Request $request
  334.      * @param LocaleServiceInterface $localeService
  335.      *
  336.      * @return JsonResponse
  337.      */
  338.     public function setSystemAction(Request $requestLocaleServiceInterface $localeService)
  339.     {
  340.         $this->checkPermission('system_settings');
  341.         $values $this->decodeJson($request->get('data'));
  342.         $existingValues = [];
  343.         try {
  344.             $file Config::locateConfigFile('system.yml');
  345.             $existingValues Config::getConfigInstance($filetrue);
  346.         } catch (\Exception $e) {
  347.             // nothing to do
  348.         }
  349.         // localized error pages
  350.         $localizedErrorPages = [];
  351.         // fallback languages
  352.         $fallbackLanguages = [];
  353.         $existingValues['pimcore']['general']['fallback_languages'] = [];
  354.         $languages explode(','$values['general.validLanguages']);
  355.         $filteredLanguages = [];
  356.         foreach ($languages as $language) {
  357.             if (isset($values['general.fallbackLanguages.' $language])) {
  358.                 $fallbackLanguages[$language] = str_replace(' '''$values['general.fallbackLanguages.' $language]);
  359.             }
  360.             // localized error pages
  361.             if (isset($values['documents.error_pages.localized.' $language])) {
  362.                 $localizedErrorPages[$language] = $values['documents.error_pages.localized.' $language];
  363.             }
  364.             if ($localeService->isLocale($language)) {
  365.                 $filteredLanguages[] = $language;
  366.             }
  367.         }
  368.         // check if there's a fallback language endless loop
  369.         foreach ($fallbackLanguages as $sourceLang => $targetLang) {
  370.             $this->checkFallbackLanguageLoop($sourceLang$fallbackLanguages);
  371.         }
  372.         $settings['pimcore'] = [
  373.             'general' => [
  374.                 'domain' => $values['general.domain'],
  375.                 'redirect_to_maindomain' => $values['general.redirect_to_maindomain'],
  376.                 'language' => $values['general.language'],
  377.                 'valid_languages' => implode(','$filteredLanguages),
  378.                 'fallback_languages' => $fallbackLanguages,
  379.                 'default_language' => $values['general.defaultLanguage'],
  380.                 'debug_admin_translations' => $values['general.debug_admin_translations'],
  381.             ],
  382.             'documents' => [
  383.                 'versions' => [
  384.                     'days' => $values['documents.versions.days'] ?? null,
  385.                     'steps' => $values['documents.versions.steps'] ?? null,
  386.                 ],
  387.                 'error_pages' => [
  388.                     'default' => $values['documents.error_pages.default'],
  389.                     'localized' => $localizedErrorPages,
  390.                 ],
  391.             ],
  392.             'objects' => [
  393.                 'versions' => [
  394.                     'days' => $values['objects.versions.days'] ?? null,
  395.                     'steps' => $values['objects.versions.steps'] ?? null,
  396.                 ],
  397.             ],
  398.             'assets' => [
  399.                 'versions' => [
  400.                     'days' => $values['assets.versions.days'] ?? null,
  401.                     'steps' => $values['assets.versions.steps'] ?? null,
  402.                 ],
  403.                 'hide_edit_image' => $values['assets.hide_edit_image'],
  404.                 'disable_tree_preview' => $values['assets.disable_tree_preview'],
  405.             ],
  406.         ];
  407.         //branding
  408.         $settings['pimcore_admin'] = [
  409.             'branding' =>
  410.                 [
  411.                     'login_screen_invert_colors' => $values['branding.login_screen_invert_colors'],
  412.                     'color_login_screen' => $values['branding.color_login_screen'],
  413.                     'color_admin_interface' => $values['branding.color_admin_interface'],
  414.                     'login_screen_custom_image' => $values['branding.login_screen_custom_image'],
  415.                 ],
  416.         ];
  417.         if (array_key_exists('email.debug.emailAddresses'$values) && $values['email.debug.emailAddresses']) {
  418.             $settings['pimcore']['email']['debug']['email_addresses'] = $values['email.debug.emailAddresses'];
  419.         }
  420.         $settingsYml Yaml::dump($settings5);
  421.         $configFile Config::locateConfigFile('system.yml');
  422.         File::put($configFile$settingsYml);
  423.         // clear all caches
  424.         $this->forward(self::class . '::clearCacheAction', [
  425.             'only_symfony_cache' => false,
  426.             'only_pimcore_cache' => false,
  427.             'env' => [\Pimcore::getKernel()->getEnvironment()],
  428.         ]);
  429.         return $this->adminJson(['success' => true]);
  430.     }
  431.     /**
  432.      * @param string $source
  433.      * @param array $definitions
  434.      * @param array $fallbacks
  435.      *
  436.      * @throws \Exception
  437.      */
  438.     protected function checkFallbackLanguageLoop($source$definitions$fallbacks = [])
  439.     {
  440.         if (isset($definitions[$source])) {
  441.             $targets explode(','$definitions[$source]);
  442.             foreach ($targets as $l) {
  443.                 $target trim($l);
  444.                 if ($target) {
  445.                     if (in_array($target$fallbacks)) {
  446.                         throw new \Exception("Language `$source` | `$target` causes an infinte loop.");
  447.                     }
  448.                     $fallbacks[] = $target;
  449.                     $this->checkFallbackLanguageLoop($target$definitions$fallbacks);
  450.                 }
  451.             }
  452.         } else {
  453.             throw new \Exception("Language `$source` doesn't exist");
  454.         }
  455.     }
  456.     /**
  457.      * @Route("/get-web2print", name="pimcore_admin_settings_getweb2print", methods={"GET"})
  458.      *
  459.      * @param Request $request
  460.      *
  461.      * @return JsonResponse
  462.      */
  463.     public function getWeb2printAction(Request $request)
  464.     {
  465.         $this->checkPermission('web2print_settings');
  466.         $values Config::getWeb2PrintConfig();
  467.         $valueArray $values->toArray();
  468.         $optionsString = [];
  469.         if ($valueArray['wkhtml2pdfOptions']) {
  470.             foreach ($valueArray['wkhtml2pdfOptions'] as $key => $value) {
  471.                 $tmpStr '--'.$key;
  472.                 if ($value !== null && $value !== '') {
  473.                     $tmpStr .= ' '.$value;
  474.                 }
  475.                 $optionsString[] = $tmpStr;
  476.             }
  477.         }
  478.         $valueArray['wkhtml2pdfOptions'] = implode("\n"$optionsString);
  479.         $response = [
  480.             'values' => $valueArray,
  481.         ];
  482.         return $this->adminJson($response);
  483.     }
  484.     /**
  485.      * @Route("/set-web2print", name="pimcore_admin_settings_setweb2print", methods={"PUT"})
  486.      *
  487.      * @param Request $request
  488.      *
  489.      * @return JsonResponse
  490.      */
  491.     public function setWeb2printAction(Request $request)
  492.     {
  493.         $this->checkPermission('web2print_settings');
  494.         $values $this->decodeJson($request->get('data'));
  495.         if ($values['wkhtml2pdfOptions']) {
  496.             $optionArray = [];
  497.             $lines explode("\n"$values['wkhtml2pdfOptions']);
  498.             foreach ($lines as $line) {
  499.                 $parts explode(' 'substr($line2));
  500.                 $key trim($parts[0]);
  501.                 if ($key) {
  502.                     $value trim($parts[1] ?? '');
  503.                     $optionArray[$key] = $value;
  504.                 }
  505.             }
  506.             $values['wkhtml2pdfOptions'] = $optionArray;
  507.         }
  508.         $configFile \Pimcore\Config::locateConfigFile('web2print.php');
  509.         File::putPhpFile($configFileto_php_data_file_format($values));
  510.         return $this->adminJson(['success' => true]);
  511.     }
  512.     /**
  513.      * @Route("/clear-cache", name="pimcore_admin_settings_clearcache", methods={"DELETE"})
  514.      *
  515.      * @param Request $request
  516.      * @param KernelInterface $kernel
  517.      * @param EventDispatcherInterface $eventDispatcher
  518.      * @param CoreCacheHandler $cache
  519.      * @param Filesystem $filesystem
  520.      * @param CacheClearer $symfonyCacheClearer
  521.      *
  522.      * @return JsonResponse
  523.      */
  524.     public function clearCacheAction(
  525.         Request $request,
  526.         KernelInterface $kernel,
  527.         EventDispatcherInterface $eventDispatcher,
  528.         CoreCacheHandler $cache,
  529.         Filesystem $filesystem,
  530.         CacheClearer $symfonyCacheClearer
  531.     ) {
  532.         $this->checkPermissionsHasOneOf(['clear_cache''system_settings']);
  533.         $result = [
  534.             'success' => true,
  535.         ];
  536.         $clearPimcoreCache = !(bool)$request->get('only_symfony_cache');
  537.         $clearSymfonyCache = !(bool)$request->get('only_pimcore_cache');
  538.         if ($clearPimcoreCache) {
  539.             // empty document cache
  540.             $cache->clearAll();
  541.             if ($filesystem->exists(PIMCORE_CACHE_DIRECTORY)) {
  542.                 $filesystem->remove(PIMCORE_CACHE_DIRECTORY);
  543.             }
  544.             // PIMCORE-1854 - recreate .dummy file => should remain
  545.             File::put(PIMCORE_CACHE_DIRECTORY '/.gitkeep''');
  546.             $eventDispatcher->dispatch(new GenericEvent(), SystemEvents::CACHE_CLEAR);
  547.         }
  548.         if ($clearSymfonyCache) {
  549.             // pass one or move env parameters to clear multiple envs
  550.             // if no env is passed it will use the current one
  551.             $environments $request->get('env'$kernel->getEnvironment());
  552.             if (!is_array($environments)) {
  553.                 $environments trim((string)$environments);
  554.                 if (empty($environments)) {
  555.                     $environments = [];
  556.                 } else {
  557.                     $environments = [$environments];
  558.                 }
  559.             }
  560.             if (empty($environments)) {
  561.                 $environments = [$kernel->getEnvironment()];
  562.             }
  563.             $result['environments'] = $environments;
  564.             if (in_array($kernel->getEnvironment(), $environments)) {
  565.                 // remove terminate and exception event listeners for the current env as they break with a
  566.                 // cleared container - see #2434
  567.                 foreach ($eventDispatcher->getListeners(KernelEvents::TERMINATE) as $listener) {
  568.                     $eventDispatcher->removeListener(KernelEvents::TERMINATE$listener);
  569.                 }
  570.                 foreach ($eventDispatcher->getListeners(KernelEvents::EXCEPTION) as $listener) {
  571.                     $eventDispatcher->removeListener(KernelEvents::EXCEPTION$listener);
  572.                 }
  573.             }
  574.             foreach ($environments as $environment) {
  575.                 try {
  576.                     $symfonyCacheClearer->clear($environment);
  577.                 } catch (\Throwable $e) {
  578.                     $errors $result['errors'] ?? [];
  579.                     $errors[] = $e->getMessage();
  580.                     $result array_merge($result, [
  581.                         'success' => false,
  582.                         'errors' => $errors,
  583.                     ]);
  584.                 }
  585.             }
  586.         }
  587.         $response = new JsonResponse($result);
  588.         if ($clearSymfonyCache) {
  589.             // we send the response directly here and exit to make sure no code depending on the stale container
  590.             // is running after this
  591.             $response->sendHeaders();
  592.             $response->sendContent();
  593.             exit;
  594.         }
  595.         return $response;
  596.     }
  597.     /**
  598.      * @Route("/clear-output-cache", name="pimcore_admin_settings_clearoutputcache", methods={"DELETE"})
  599.      *
  600.      * @param EventDispatcherInterface $eventDispatcher
  601.      *
  602.      * @return JsonResponse
  603.      */
  604.     public function clearOutputCacheAction(EventDispatcherInterface $eventDispatcher)
  605.     {
  606.         $this->checkPermission('clear_fullpage_cache');
  607.         // remove "output" out of the ignored tags, if a cache lifetime is specified
  608.         Cache::removeIgnoredTagOnClear('output');
  609.         // empty document cache
  610.         Cache::clearTags(['output''output_lifetime']);
  611.         $eventDispatcher->dispatch(new GenericEvent(), SystemEvents::CACHE_CLEAR_FULLPAGE_CACHE);
  612.         return $this->adminJson(['success' => true]);
  613.     }
  614.     /**
  615.      * @Route("/clear-temporary-files", name="pimcore_admin_settings_cleartemporaryfiles", methods={"DELETE"})
  616.      *
  617.      * @param EventDispatcherInterface $eventDispatcher
  618.      *
  619.      * @return JsonResponse
  620.      */
  621.     public function clearTemporaryFilesAction(EventDispatcherInterface $eventDispatcher)
  622.     {
  623.         $this->checkPermission('clear_temp_files');
  624.         // public files
  625.         Tool\Storage::get('thumbnail')->deleteDirectory('/');
  626.         Tool\Storage::get('asset_cache')->deleteDirectory('/');
  627.         // system files
  628.         recursiveDelete(PIMCORE_SYSTEM_TEMP_DIRECTORYfalse);
  629.         $eventDispatcher->dispatch(new GenericEvent(), SystemEvents::CACHE_CLEAR_TEMPORARY_FILES);
  630.         return $this->adminJson(['success' => true]);
  631.     }
  632.     /**
  633.      * @Route("/staticroutes", name="pimcore_admin_settings_staticroutes", methods={"POST"})
  634.      *
  635.      * @param Request $request
  636.      *
  637.      * @return JsonResponse
  638.      */
  639.     public function staticroutesAction(Request $request)
  640.     {
  641.         if ($request->get('data')) {
  642.             $this->checkPermission('routes');
  643.             $data $this->decodeJson($request->get('data'));
  644.             if (is_array($data)) {
  645.                 foreach ($data as &$value) {
  646.                     if (is_string($value)) {
  647.                         $value trim($value);
  648.                     }
  649.                 }
  650.             }
  651.             if ($request->get('xaction') == 'destroy') {
  652.                 $data $this->decodeJson($request->get('data'));
  653.                 $id $data['id'];
  654.                 $route Staticroute::getById($id);
  655.                 $route->delete();
  656.                 return $this->adminJson(['success' => true'data' => []]);
  657.             } elseif ($request->get('xaction') == 'update') {
  658.                 // save routes
  659.                 $route Staticroute::getById($data['id']);
  660.                 $route->setValues($data);
  661.                 $route->save();
  662.                 return $this->adminJson(['data' => $route->getObjectVars(), 'success' => true]);
  663.             } elseif ($request->get('xaction') == 'create') {
  664.                 unset($data['id']);
  665.                 // save route
  666.                 $route = new Staticroute();
  667.                 $route->setValues($data);
  668.                 $route->save();
  669.                 return $this->adminJson(['data' => $route->getObjectVars(), 'success' => true]);
  670.             }
  671.         } else {
  672.             // get list of routes
  673.             $list = new Staticroute\Listing();
  674.             if ($request->get('filter')) {
  675.                 $filter $request->get('filter');
  676.                 $list->setFilter(function ($row) use ($filter) {
  677.                     foreach ($row as $value) {
  678.                         if (! is_scalar($value)) {
  679.                             continue;
  680.                         }
  681.                         if (strpos((string)$value$filter) !== false) {
  682.                             return true;
  683.                         }
  684.                     }
  685.                     return false;
  686.                 });
  687.             }
  688.             $list->load();
  689.             $routes = [];
  690.             /** @var Staticroute $route */
  691.             foreach ($list->getRoutes() as $route) {
  692.                 if (is_array($route->getSiteId())) {
  693.                     $route $route->getObjectVars();
  694.                     $route['siteId'] = implode(','$route['siteId']);
  695.                 }
  696.                 $routes[] = $route;
  697.             }
  698.             return $this->adminJson(['data' => $routes'success' => true'total' => $list->getTotalCount()]);
  699.         }
  700.         return $this->adminJson(['success' => false]);
  701.     }
  702.     /**
  703.      * @Route("/get-available-admin-languages", name="pimcore_admin_settings_getavailableadminlanguages", methods={"GET"})
  704.      *
  705.      * @param Request $request
  706.      *
  707.      * @return JsonResponse
  708.      */
  709.     public function getAvailableAdminLanguagesAction(Request $request)
  710.     {
  711.         $langs = [];
  712.         $availableLanguages Tool\Admin::getLanguages();
  713.         $locales Tool::getSupportedLocales();
  714.         foreach ($availableLanguages as $lang) {
  715.             if (array_key_exists($lang$locales)) {
  716.                 $langs[] = [
  717.                     'language' => $lang,
  718.                     'display' => $locales[$lang],
  719.                 ];
  720.             }
  721.         }
  722.         usort($langs, function ($a$b) {
  723.             return strcmp($a['display'], $b['display']);
  724.         });
  725.         return $this->adminJson($langs);
  726.     }
  727.     /**
  728.      * @Route("/glossary", name="pimcore_admin_settings_glossary", methods={"POST"})
  729.      *
  730.      * @param Request $request
  731.      *
  732.      * @return JsonResponse
  733.      */
  734.     public function glossaryAction(Request $request)
  735.     {
  736.         if ($request->get('data')) {
  737.             $this->checkPermission('glossary');
  738.             Cache::clearTag('glossary');
  739.             if ($request->get('xaction') == 'destroy') {
  740.                 $data $this->decodeJson($request->get('data'));
  741.                 $id $data['id'];
  742.                 $glossary Glossary::getById($id);
  743.                 $glossary->delete();
  744.                 return $this->adminJson(['success' => true'data' => []]);
  745.             } elseif ($request->get('xaction') == 'update') {
  746.                 $data $this->decodeJson($request->get('data'));
  747.                 // save glossary
  748.                 $glossary Glossary::getById($data['id']);
  749.                 if (!empty($data['link'])) {
  750.                     if ($doc Document::getByPath($data['link'])) {
  751.                         $data['link'] = $doc->getId();
  752.                     }
  753.                 }
  754.                 $glossary->setValues($data);
  755.                 $glossary->save();
  756.                 if ($link $glossary->getLink()) {
  757.                     if ((int)$link 0) {
  758.                         if ($doc Document::getById((int)$link)) {
  759.                             $glossary->setLink($doc->getRealFullPath());
  760.                         }
  761.                     }
  762.                 }
  763.                 return $this->adminJson(['data' => $glossary'success' => true]);
  764.             } elseif ($request->get('xaction') == 'create') {
  765.                 $data $this->decodeJson($request->get('data'));
  766.                 unset($data['id']);
  767.                 // save glossary
  768.                 $glossary = new Glossary();
  769.                 if (!empty($data['link'])) {
  770.                     if ($doc Document::getByPath($data['link'])) {
  771.                         $data['link'] = $doc->getId();
  772.                     }
  773.                 }
  774.                 $glossary->setValues($data);
  775.                 $glossary->save();
  776.                 if ($link $glossary->getLink()) {
  777.                     if ((int)$link 0) {
  778.                         if ($doc Document::getById((int)$link)) {
  779.                             $glossary->setLink($doc->getRealFullPath());
  780.                         }
  781.                     }
  782.                 }
  783.                 return $this->adminJson(['data' => $glossary->getObjectVars(), 'success' => true]);
  784.             }
  785.         } else {
  786.             // get list of glossaries
  787.             $list = new Glossary\Listing();
  788.             $list->setLimit($request->get('limit'));
  789.             $list->setOffset($request->get('start'));
  790.             $sortingSettings \Pimcore\Bundle\AdminBundle\Helper\QueryParams::extractSortingSettings(array_merge($request->request->all(), $request->query->all()));
  791.             if ($sortingSettings['orderKey']) {
  792.                 $list->setOrderKey($sortingSettings['orderKey']);
  793.                 $list->setOrder($sortingSettings['order']);
  794.             }
  795.             if ($request->get('filter')) {
  796.                 $list->setCondition('`text` LIKE ' $list->quote('%'.$request->get('filter').'%'));
  797.             }
  798.             $list->load();
  799.             $glossaries = [];
  800.             foreach ($list->getGlossary() as $glossary) {
  801.                 if ($link $glossary->getLink()) {
  802.                     if ((int)$link 0) {
  803.                         if ($doc Document::getById((int)$link)) {
  804.                             $glossary->setLink($doc->getRealFullPath());
  805.                         }
  806.                     }
  807.                 }
  808.                 $glossaries[] = $glossary->getObjectVars();
  809.             }
  810.             return $this->adminJson(['data' => $glossaries'success' => true'total' => $list->getTotalCount()]);
  811.         }
  812.         return $this->adminJson(['success' => false]);
  813.     }
  814.     /**
  815.      * @Route("/get-available-sites", name="pimcore_admin_settings_getavailablesites", methods={"GET"})
  816.      *
  817.      * @param Request $request
  818.      *
  819.      * @return JsonResponse
  820.      */
  821.     public function getAvailableSitesAction(Request $request)
  822.     {
  823.         $excludeMainSite $request->get('excludeMainSite');
  824.         $sitesList = new Model\Site\Listing();
  825.         $sitesObjects $sitesList->load();
  826.         $sites = [];
  827.         if (!$excludeMainSite) {
  828.             $sites[] = [
  829.                 'id' => 'default',
  830.                 'rootId' => 1,
  831.                 'domains' => '',
  832.                 'rootPath' => '/',
  833.                 'domain' => $this->trans('main_site'),
  834.             ];
  835.         }
  836.         foreach ($sitesObjects as $site) {
  837.             if ($site->getRootDocument()) {
  838.                 if ($site->getMainDomain()) {
  839.                     $sites[] = [
  840.                         'id' => $site->getId(),
  841.                         'rootId' => $site->getRootId(),
  842.                         'domains' => implode(','$site->getDomains()),
  843.                         'rootPath' => $site->getRootPath(),
  844.                         'domain' => $site->getMainDomain(),
  845.                     ];
  846.                 }
  847.             } else {
  848.                 // site is useless, parent doesn't exist anymore
  849.                 $site->delete();
  850.             }
  851.         }
  852.         return $this->adminJson($sites);
  853.     }
  854.     /**
  855.      * @Route("/get-available-countries", name="pimcore_admin_settings_getavailablecountries", methods={"GET"})
  856.      *
  857.      * @param LocaleServiceInterface $localeService
  858.      *
  859.      * @return JsonResponse
  860.      */
  861.     public function getAvailableCountriesAction(LocaleServiceInterface $localeService)
  862.     {
  863.         $countries $localeService->getDisplayRegions();
  864.         asort($countries);
  865.         $options = [];
  866.         foreach ($countries as $short => $translation) {
  867.             if (strlen($short) == 2) {
  868.                 $options[] = [
  869.                     'key' => $translation ' (' $short ')',
  870.                     'value' => $short,
  871.                 ];
  872.             }
  873.         }
  874.         $result = ['data' => $options'success' => true'total' => count($options)];
  875.         return $this->adminJson($result);
  876.     }
  877.     /**
  878.      * @Route("/thumbnail-adapter-check", name="pimcore_admin_settings_thumbnailadaptercheck", methods={"GET"})
  879.      *
  880.      * @param Request $request
  881.      *
  882.      * @return Response
  883.      */
  884.     public function thumbnailAdapterCheckAction(Request $request)
  885.     {
  886.         $content '';
  887.         $instance \Pimcore\Image::getInstance();
  888.         if ($instance instanceof \Pimcore\Image\Adapter\GD) {
  889.             $content '<span style="color: red; font-weight: bold;padding: 10px;margin:0 0 20px 0;border:1px solid red;display:block;">' .
  890.                 $this->trans('important_use_imagick_pecl_extensions_for_best_results_gd_is_just_a_fallback_with_less_quality') .
  891.                 '</span>';
  892.         }
  893.         return new Response($content);
  894.     }
  895.     /**
  896.      * @Route("/thumbnail-tree", name="pimcore_admin_settings_thumbnailtree", methods={"GET", "POST"})
  897.      *
  898.      * @param Request $request
  899.      *
  900.      * @return JsonResponse
  901.      */
  902.     public function thumbnailTreeAction(Request $request)
  903.     {
  904.         $this->checkPermission('thumbnails');
  905.         $thumbnails = [];
  906.         $list = new Asset\Image\Thumbnail\Config\Listing();
  907.         $items $list->getThumbnails();
  908.         $groups = [];
  909.         /** @var Asset\Image\Thumbnail\Config $item */
  910.         foreach ($items as $item) {
  911.             if ($item->getGroup()) {
  912.                 if (empty($groups[$item->getGroup()])) {
  913.                     $groups[$item->getGroup()] = [
  914.                         'id' => 'group_' $item->getName(),
  915.                         'text' => $item->getGroup(),
  916.                         'expandable' => true,
  917.                         'leaf' => false,
  918.                         'allowChildren' => true,
  919.                         'iconCls' => 'pimcore_icon_folder',
  920.                         'group' => $item->getGroup(),
  921.                         'children' => [],
  922.                     ];
  923.                 }
  924.                 $groups[$item->getGroup()]['children'][] =
  925.                     [
  926.                         'id' => $item->getName(),
  927.                         'text' => $item->getName(),
  928.                         'leaf' => true,
  929.                         'iconCls' => 'pimcore_icon_thumbnails',
  930.                     ];
  931.             } else {
  932.                 $thumbnails[] = [
  933.                     'id' => $item->getName(),
  934.                     'text' => $item->getName(),
  935.                     'leaf' => true,
  936.                     'iconCls' => 'pimcore_icon_thumbnails',
  937.                 ];
  938.             }
  939.         }
  940.         foreach ($groups as $group) {
  941.             $thumbnails[] = $group;
  942.         }
  943.         return $this->adminJson($thumbnails);
  944.     }
  945.     /**
  946.      * @Route("/thumbnail-downloadable", name="pimcore_admin_settings_thumbnaildownloadable", methods={"GET"})
  947.      *
  948.      * @param Request $request
  949.      *
  950.      * @return JsonResponse
  951.      */
  952.     public function thumbnailDownloadableAction(Request $request)
  953.     {
  954.         $thumbnails = [];
  955.         $list = new Asset\Image\Thumbnail\Config\Listing();
  956.         $list->setFilter(function (array $config) {
  957.             return array_key_exists('downloadable'$config) ? $config['downloadable'] : false;
  958.         });
  959.         $items $list->getThumbnails();
  960.         /** @var Asset\Image\Thumbnail\Config $item */
  961.         foreach ($items as $item) {
  962.             $thumbnails[] = [
  963.                 'id' => $item->getName(),
  964.                 'text' => $item->getName(),
  965.             ];
  966.         }
  967.         return $this->adminJson($thumbnails);
  968.     }
  969.     /**
  970.      * @Route("/thumbnail-add", name="pimcore_admin_settings_thumbnailadd", methods={"POST"})
  971.      *
  972.      * @param Request $request
  973.      *
  974.      * @return JsonResponse
  975.      */
  976.     public function thumbnailAddAction(Request $request)
  977.     {
  978.         $this->checkPermission('thumbnails');
  979.         $success false;
  980.         $pipe Asset\Image\Thumbnail\Config::getByName($request->get('name'));
  981.         if (!$pipe) {
  982.             $pipe = new Asset\Image\Thumbnail\Config();
  983.             $pipe->setName($request->get('name'));
  984.             $pipe->save();
  985.             $success true;
  986.         }
  987.         return $this->adminJson(['success' => $success'id' => $pipe->getName()]);
  988.     }
  989.     /**
  990.      * @Route("/thumbnail-delete", name="pimcore_admin_settings_thumbnaildelete", methods={"DELETE"})
  991.      *
  992.      * @param Request $request
  993.      *
  994.      * @return JsonResponse
  995.      */
  996.     public function thumbnailDeleteAction(Request $request)
  997.     {
  998.         $this->checkPermission('thumbnails');
  999.         $pipe Asset\Image\Thumbnail\Config::getByName($request->get('name'));
  1000.         $pipe->delete();
  1001.         return $this->adminJson(['success' => true]);
  1002.     }
  1003.     /**
  1004.      * @Route("/thumbnail-get", name="pimcore_admin_settings_thumbnailget", methods={"GET"})
  1005.      *
  1006.      * @param Request $request
  1007.      *
  1008.      * @return JsonResponse
  1009.      */
  1010.     public function thumbnailGetAction(Request $request)
  1011.     {
  1012.         $this->checkPermission('thumbnails');
  1013.         $pipe Asset\Image\Thumbnail\Config::getByName($request->get('name'));
  1014.         return $this->adminJson($pipe->getObjectVars());
  1015.     }
  1016.     /**
  1017.      * @Route("/thumbnail-update", name="pimcore_admin_settings_thumbnailupdate", methods={"PUT"})
  1018.      *
  1019.      * @param Request $request
  1020.      *
  1021.      * @return JsonResponse
  1022.      */
  1023.     public function thumbnailUpdateAction(Request $request)
  1024.     {
  1025.         $this->checkPermission('thumbnails');
  1026.         $pipe Asset\Image\Thumbnail\Config::getByName($request->get('name'));
  1027.         $settingsData $this->decodeJson($request->get('settings'));
  1028.         $mediaData $this->decodeJson($request->get('medias'));
  1029.         $mediaOrder $this->decodeJson($request->get('mediaOrder'));
  1030.         foreach ($settingsData as $key => $value) {
  1031.             $setter 'set' ucfirst($key);
  1032.             if (method_exists($pipe$setter)) {
  1033.                 $pipe->$setter($value);
  1034.             }
  1035.         }
  1036.         $pipe->resetItems();
  1037.         uksort($mediaData, function ($a$b) use ($mediaOrder) {
  1038.             if ($a === 'default') {
  1039.                 return -1;
  1040.             }
  1041.             return ($mediaOrder[$a] < $mediaOrder[$b]) ? -1;
  1042.         });
  1043.         foreach ($mediaData as $mediaName => $items) {
  1044.             foreach ($items as $item) {
  1045.                 $type $item['type'];
  1046.                 unset($item['type']);
  1047.                 $pipe->addItem($type$item$mediaName);
  1048.             }
  1049.         }
  1050.         $pipe->save();
  1051.         return $this->adminJson(['success' => true]);
  1052.     }
  1053.     /**
  1054.      * @Route("/video-thumbnail-adapter-check", name="pimcore_admin_settings_videothumbnailadaptercheck", methods={"GET"})
  1055.      *
  1056.      * @param Request $request
  1057.      *
  1058.      * @return Response
  1059.      */
  1060.     public function videoThumbnailAdapterCheckAction(Request $request)
  1061.     {
  1062.         $content '';
  1063.         if (!\Pimcore\Video::isAvailable()) {
  1064.             $content '<span style="color: red; font-weight: bold;padding: 10px;margin:0 0 20px 0;border:1px solid red;display:block;">' .
  1065.                 $this->trans('php_cli_binary_and_or_ffmpeg_binary_setting_is_missing') .
  1066.                 '</span>';
  1067.         }
  1068.         return new Response($content);
  1069.     }
  1070.     /**
  1071.      * @Route("/video-thumbnail-tree", name="pimcore_admin_settings_videothumbnailtree", methods={"GET", "POST"})
  1072.      *
  1073.      * @param Request $request
  1074.      *
  1075.      * @return JsonResponse
  1076.      */
  1077.     public function videoThumbnailTreeAction(Request $request)
  1078.     {
  1079.         $this->checkPermission('thumbnails');
  1080.         $thumbnails = [];
  1081.         $list = new Asset\Video\Thumbnail\Config\Listing();
  1082.         $items $list->getThumbnails();
  1083.         $groups = [];
  1084.         /** @var Asset\Image\Thumbnail\Config $item */
  1085.         foreach ($items as $item) {
  1086.             if ($item->getGroup()) {
  1087.                 if (!$groups[$item->getGroup()]) {
  1088.                     $groups[$item->getGroup()] = [
  1089.                         'id' => 'group_' $item->getName(),
  1090.                         'text' => $item->getGroup(),
  1091.                         'expandable' => true,
  1092.                         'leaf' => false,
  1093.                         'allowChildren' => true,
  1094.                         'iconCls' => 'pimcore_icon_folder',
  1095.                         'group' => $item->getGroup(),
  1096.                         'children' => [],
  1097.                     ];
  1098.                 }
  1099.                 $groups[$item->getGroup()]['children'][] =
  1100.                     [
  1101.                         'id' => $item->getName(),
  1102.                         'text' => $item->getName(),
  1103.                         'leaf' => true,
  1104.                         'iconCls' => 'pimcore_icon_videothumbnails',
  1105.                     ];
  1106.             } else {
  1107.                 $thumbnails[] = [
  1108.                     'id' => $item->getName(),
  1109.                     'text' => $item->getName(),
  1110.                     'leaf' => true,
  1111.                     'iconCls' => 'pimcore_icon_videothumbnails',
  1112.                 ];
  1113.             }
  1114.         }
  1115.         foreach ($groups as $group) {
  1116.             $thumbnails[] = $group;
  1117.         }
  1118.         return $this->adminJson($thumbnails);
  1119.     }
  1120.     /**
  1121.      * @Route("/video-thumbnail-add", name="pimcore_admin_settings_videothumbnailadd", methods={"POST"})
  1122.      *
  1123.      * @param Request $request
  1124.      *
  1125.      * @return JsonResponse
  1126.      */
  1127.     public function videoThumbnailAddAction(Request $request)
  1128.     {
  1129.         $this->checkPermission('thumbnails');
  1130.         $success false;
  1131.         $pipe Asset\Video\Thumbnail\Config::getByName($request->get('name'));
  1132.         if (!$pipe) {
  1133.             $pipe = new Asset\Video\Thumbnail\Config();
  1134.             $pipe->setName($request->get('name'));
  1135.             $pipe->save();
  1136.             $success true;
  1137.         }
  1138.         return $this->adminJson(['success' => $success'id' => $pipe->getName()]);
  1139.     }
  1140.     /**
  1141.      * @Route("/video-thumbnail-delete", name="pimcore_admin_settings_videothumbnaildelete", methods={"DELETE"})
  1142.      *
  1143.      * @param Request $request
  1144.      *
  1145.      * @return JsonResponse
  1146.      */
  1147.     public function videoThumbnailDeleteAction(Request $request)
  1148.     {
  1149.         $this->checkPermission('thumbnails');
  1150.         $pipe Asset\Video\Thumbnail\Config::getByName($request->get('name'));
  1151.         $pipe->delete();
  1152.         return $this->adminJson(['success' => true]);
  1153.     }
  1154.     /**
  1155.      * @Route("/video-thumbnail-get", name="pimcore_admin_settings_videothumbnailget", methods={"GET"})
  1156.      *
  1157.      * @param Request $request
  1158.      *
  1159.      * @return JsonResponse
  1160.      */
  1161.     public function videoThumbnailGetAction(Request $request)
  1162.     {
  1163.         $this->checkPermission('thumbnails');
  1164.         $pipe Asset\Video\Thumbnail\Config::getByName($request->get('name'));
  1165.         return $this->adminJson($pipe->getObjectVars());
  1166.     }
  1167.     /**
  1168.      * @Route("/video-thumbnail-update", name="pimcore_admin_settings_videothumbnailupdate", methods={"PUT"})
  1169.      *
  1170.      * @param Request $request
  1171.      *
  1172.      * @return JsonResponse
  1173.      */
  1174.     public function videoThumbnailUpdateAction(Request $request)
  1175.     {
  1176.         $this->checkPermission('thumbnails');
  1177.         $pipe Asset\Video\Thumbnail\Config::getByName($request->get('name'));
  1178.         $settingsData $this->decodeJson($request->get('settings'));
  1179.         $mediaData $this->decodeJson($request->get('medias'));
  1180.         $mediaOrder $this->decodeJson($request->get('mediaOrder'));
  1181.         foreach ($settingsData as $key => $value) {
  1182.             $setter 'set' ucfirst($key);
  1183.             if (method_exists($pipe$setter)) {
  1184.                 $pipe->$setter($value);
  1185.             }
  1186.         }
  1187.         $pipe->resetItems();
  1188.         uksort($mediaData, function ($a$b) use ($mediaOrder) {
  1189.             if ($a === 'default') {
  1190.                 return -1;
  1191.             }
  1192.             return ($mediaOrder[$a] < $mediaOrder[$b]) ? -1;
  1193.         });
  1194.         foreach ($mediaData as $mediaName => $items) {
  1195.             foreach ($items as $item) {
  1196.                 $type $item['type'];
  1197.                 unset($item['type']);
  1198.                 $pipe->addItem($type$item$mediaName);
  1199.             }
  1200.         }
  1201.         $pipe->save();
  1202.         return $this->adminJson(['success' => true]);
  1203.     }
  1204.     /**
  1205.      * @Route("/robots-txt", name="pimcore_admin_settings_robotstxtget", methods={"GET"})
  1206.      *
  1207.      * @return JsonResponse
  1208.      */
  1209.     public function robotsTxtGetAction()
  1210.     {
  1211.         $this->checkPermission('robots.txt');
  1212.         $config Config::getRobotsConfig();
  1213.         $config $config->toArray();
  1214.         return $this->adminJson([
  1215.             'success' => true,
  1216.             'data' => $config,
  1217.             'onFileSystem' => file_exists(PIMCORE_WEB_ROOT '/robots.txt'),
  1218.         ]);
  1219.     }
  1220.     /**
  1221.      * @Route("/robots-txt", name="pimcore_admin_settings_robotstxtput", methods={"PUT"})
  1222.      *
  1223.      * @param Request $request
  1224.      *
  1225.      * @return JsonResponse
  1226.      */
  1227.     public function robotsTxtPutAction(Request $request)
  1228.     {
  1229.         $this->checkPermission('robots.txt');
  1230.         $values $request->get('data');
  1231.         if (!is_array($values)) {
  1232.             $values = [];
  1233.         }
  1234.         foreach ($values as $siteId => $robotsContent) {
  1235.             SettingsStore::set('robots.txt-' $siteId$robotsContent'string''robots.txt');
  1236.         }
  1237.         return $this->adminJson([
  1238.             'success' => true,
  1239.         ]);
  1240.     }
  1241.     /**
  1242.      * @Route("/website-settings", name="pimcore_admin_settings_websitesettings", methods={"POST"})
  1243.      *
  1244.      * @param Request $request
  1245.      *
  1246.      * @return JsonResponse
  1247.      *
  1248.      * @throws \Exception
  1249.      */
  1250.     public function websiteSettingsAction(Request $request)
  1251.     {
  1252.         $this->checkPermission('website_settings');
  1253.         if ($request->get('data')) {
  1254.             $data $this->decodeJson($request->get('data'));
  1255.             if (is_array($data)) {
  1256.                 foreach ($data as &$value) {
  1257.                     $value trim($value);
  1258.                 }
  1259.             }
  1260.             if ($request->get('xaction') == 'destroy') {
  1261.                 $id $data['id'];
  1262.                 $setting WebsiteSetting::getById($id);
  1263.                 if ($setting instanceof WebsiteSetting) {
  1264.                     $setting->delete();
  1265.                     return $this->adminJson(['success' => true'data' => []]);
  1266.                 }
  1267.             } elseif ($request->get('xaction') == 'update') {
  1268.                 // save routes
  1269.                 $setting WebsiteSetting::getById($data['id']);
  1270.                 if ($setting instanceof WebsiteSetting) {
  1271.                     switch ($setting->getType()) {
  1272.                         case 'document':
  1273.                         case 'asset':
  1274.                         case 'object':
  1275.                             if (isset($data['data'])) {
  1276.                                 $element Element\Service::getElementByPath($setting->getType(), $data['data']);
  1277.                                 $data['data'] = $element;
  1278.                             }
  1279.                             break;
  1280.                     }
  1281.                     $setting->setValues($data);
  1282.                     $setting->save();
  1283.                     $data $this->getWebsiteSettingForEditMode($setting);
  1284.                     return $this->adminJson(['data' => $data'success' => true]);
  1285.                 }
  1286.             } elseif ($request->get('xaction') == 'create') {
  1287.                 unset($data['id']);
  1288.                 // save route
  1289.                 $setting = new WebsiteSetting();
  1290.                 $setting->setValues($data);
  1291.                 $setting->save();
  1292.                 return $this->adminJson(['data' => $setting->getObjectVars(), 'success' => true]);
  1293.             }
  1294.         } else {
  1295.             $list = new WebsiteSetting\Listing();
  1296.             $list->setLimit($request->get('limit'));
  1297.             $list->setOffset($request->get('start'));
  1298.             $sortingSettings \Pimcore\Bundle\AdminBundle\Helper\QueryParams::extractSortingSettings(array_merge($request->request->all(), $request->query->all()));
  1299.             if ($sortingSettings['orderKey']) {
  1300.                 $list->setOrderKey($sortingSettings['orderKey']);
  1301.                 $list->setOrder($sortingSettings['order']);
  1302.             } else {
  1303.                 $list->setOrderKey('name');
  1304.                 $list->setOrder('asc');
  1305.             }
  1306.             if ($request->get('filter')) {
  1307.                 $list->setCondition('`name` LIKE ' $list->quote('%'.$request->get('filter').'%'));
  1308.             }
  1309.             $totalCount $list->getTotalCount();
  1310.             $list $list->load();
  1311.             $settings = [];
  1312.             foreach ($list as $item) {
  1313.                 $resultItem $this->getWebsiteSettingForEditMode($item);
  1314.                 $settings[] = $resultItem;
  1315.             }
  1316.             return $this->adminJson(['data' => $settings'success' => true'total' => $totalCount]);
  1317.         }
  1318.         return $this->adminJson(['success' => false]);
  1319.     }
  1320.     /**
  1321.      * @param WebsiteSetting $item
  1322.      *
  1323.      * @return array
  1324.      */
  1325.     private function getWebsiteSettingForEditMode($item)
  1326.     {
  1327.         $resultItem = [
  1328.             'id' => $item->getId(),
  1329.             'name' => $item->getName(),
  1330.             'language' => $item->getLanguage(),
  1331.             'type' => $item->getType(),
  1332.             'data' => null,
  1333.             'siteId' => $item->getSiteId(),
  1334.             'creationDate' => $item->getCreationDate(),
  1335.             'modificationDate' => $item->getModificationDate(),
  1336.         ];
  1337.         switch ($item->getType()) {
  1338.             case 'document':
  1339.             case 'asset':
  1340.             case 'object':
  1341.                 $element $item->getData();
  1342.                 if ($element) {
  1343.                     $resultItem['data'] = $element->getRealFullPath();
  1344.                 }
  1345.                 break;
  1346.             default:
  1347.                 $resultItem['data'] = $item->getData();
  1348.                 break;
  1349.         }
  1350.         return $resultItem;
  1351.     }
  1352.     /**
  1353.      * @Route("/get-available-algorithms", name="pimcore_admin_settings_getavailablealgorithms", methods={"GET"})
  1354.      *
  1355.      * @param Request $request
  1356.      *
  1357.      * @return JsonResponse
  1358.      */
  1359.     public function getAvailableAlgorithmsAction(Request $request)
  1360.     {
  1361.         $options = [
  1362.             [
  1363.                 'key' => 'password_hash',
  1364.                 'value' => 'password_hash',
  1365.             ],
  1366.         ];
  1367.         $algorithms hash_algos();
  1368.         foreach ($algorithms as $algorithm) {
  1369.             $options[] = [
  1370.                 'key' => $algorithm,
  1371.                 'value' => $algorithm,
  1372.             ];
  1373.         }
  1374.         $result = ['data' => $options'success' => true'total' => count($options)];
  1375.         return $this->adminJson($result);
  1376.     }
  1377.     /**
  1378.      * deleteViews
  1379.      * delete views for localized fields when languages are removed to
  1380.      * prevent mysql errors
  1381.      *
  1382.      * @param string $language
  1383.      * @param string $dbName
  1384.      */
  1385.     protected function deleteViews($language$dbName)
  1386.     {
  1387.         $db \Pimcore\Db::get();
  1388.         $views $db->fetchAll('SHOW FULL TABLES IN ' $db->quoteIdentifier($dbName) . " WHERE TABLE_TYPE LIKE 'VIEW'");
  1389.         foreach ($views as $view) {
  1390.             if (preg_match('/^object_localized_[0-9]+_' $language '$/'$view['Tables_in_' $dbName])) {
  1391.                 $sql 'DROP VIEW ' $db->quoteIdentifier($view['Tables_in_' $dbName]);
  1392.                 $db->query($sql);
  1393.             }
  1394.         }
  1395.     }
  1396.     /**
  1397.      * @Route("/test-web2print", name="pimcore_admin_settings_testweb2print", methods={"GET"})
  1398.      *
  1399.      * @param Request $request
  1400.      *
  1401.      * @return Response
  1402.      */
  1403.     public function testWeb2printAction(Request $request)
  1404.     {
  1405.         $this->checkPermission('web2print_settings');
  1406.         $response $this->render('@PimcoreAdmin/Admin/Settings/testWeb2print.html.twig');
  1407.         $html $response->getContent();
  1408.         $adapter \Pimcore\Web2Print\Processor::getInstance();
  1409.         $params = [];
  1410.         if ($adapter instanceof \Pimcore\Web2Print\Processor\WkHtmlToPdf) {
  1411.             $params['adapterConfig'] = '-O landscape';
  1412.         } elseif ($adapter instanceof \Pimcore\Web2Print\Processor\PdfReactor) {
  1413.             $params['adapterConfig'] = [
  1414.                 'javaScriptMode' => 0,
  1415.                 'addLinks' => true,
  1416.                 'appendLog' => true,
  1417.                 'enableDebugMode' => true,
  1418.             ];
  1419.         }
  1420.         $responseOptions = [
  1421.             'Content-Type' => 'application/pdf',
  1422.         ];
  1423.         $pdfData $adapter->getPdfFromString($html$params);
  1424.         return new \Symfony\Component\HttpFoundation\Response(
  1425.             $pdfData,
  1426.             200,
  1427.             $responseOptions
  1428.         );
  1429.     }
  1430. }