vendor/pimcore/pimcore/bundles/AdminBundle/Controller/Admin/MiscController.php line 40

Open in your IDE?
  1. <?php
  2. /**
  3.  * Pimcore
  4.  *
  5.  * This source file is available under two different licenses:
  6.  * - GNU General Public License version 3 (GPLv3)
  7.  * - Pimcore Commercial License (PCL)
  8.  * Full copyright and license information is available in
  9.  * LICENSE.md which is distributed with this source code.
  10.  *
  11.  *  @copyright  Copyright (c) Pimcore GmbH (http://www.pimcore.org)
  12.  *  @license    http://www.pimcore.org/license     GPLv3 and PCL
  13.  */
  14. namespace Pimcore\Bundle\AdminBundle\Controller\Admin;
  15. use Pimcore\Bundle\AdminBundle\Controller\AdminAbstractController;
  16. use Pimcore\Config;
  17. use Pimcore\Controller\Config\ControllerDataProvider;
  18. use Pimcore\Db;
  19. use Pimcore\File;
  20. use Pimcore\Localization\LocaleServiceInterface;
  21. use Pimcore\Tool;
  22. use Pimcore\Tool\Storage;
  23. use Pimcore\Translation\Translator;
  24. use Symfony\Component\HttpFoundation\BinaryFileResponse;
  25. use Symfony\Component\HttpFoundation\JsonResponse;
  26. use Symfony\Component\HttpFoundation\Request;
  27. use Symfony\Component\HttpFoundation\Response;
  28. use Symfony\Component\HttpKernel\Profiler\Profiler;
  29. use Symfony\Component\Routing\Annotation\Route;
  30. use Symfony\Contracts\Translation\TranslatorInterface;
  31. /**
  32.  * @Route("/misc")
  33.  *
  34.  * @internal
  35.  */
  36. class MiscController extends AdminAbstractController
  37. {
  38.     /**
  39.      * @Route("/get-available-controller-references", name="pimcore_admin_misc_getavailablecontroller_references", methods={"GET"})
  40.      *
  41.      * @param Request $request
  42.      * @param ControllerDataProvider $provider
  43.      *
  44.      * @return JsonResponse
  45.      */
  46.     public function getAvailableControllerReferencesAction(Request $requestControllerDataProvider $provider)
  47.     {
  48.         $controllerReferences $provider->getControllerReferences();
  49.         $result array_map(function ($controller) {
  50.             return [
  51.                 'name' => $controller,
  52.             ];
  53.         }, $controllerReferences);
  54.         return $this->adminJson([
  55.             'success' => true,
  56.             'data' => $result,
  57.             'total' => count($result),
  58.         ]);
  59.     }
  60.     /**
  61.      * @Route("/get-available-templates", name="pimcore_admin_misc_getavailabletemplates", methods={"GET"})
  62.      *
  63.      * @param ControllerDataProvider $provider
  64.      *
  65.      * @return JsonResponse
  66.      */
  67.     public function getAvailableTemplatesAction(ControllerDataProvider $provider)
  68.     {
  69.         $templates $provider->getTemplates();
  70.         sort($templatesSORT_NATURAL SORT_FLAG_CASE);
  71.         $result array_map(static function ($template) {
  72.             return [
  73.                 'path' => $template,
  74.             ];
  75.         }, $templates);
  76.         return $this->adminJson([
  77.             'data' => $result,
  78.         ]);
  79.     }
  80.     /**
  81.      * @Route("/json-translations-system", name="pimcore_admin_misc_jsontranslationssystem", methods={"GET"})
  82.      *
  83.      * @param Request $request
  84.      *
  85.      * @return Response
  86.      */
  87.     public function jsonTranslationsSystemAction(Request $requestTranslatorInterface $translator)
  88.     {
  89.         $language $request->get('language');
  90.         /** @var Translator $translator */
  91.         $translator->lazyInitialize('admin'$language);
  92.         $translations $translator->getCatalogue($language)->all('admin');
  93.         if ($language != 'en') {
  94.             // add en as a fallback
  95.             $translator->lazyInitialize('admin''en');
  96.             foreach ($translator->getCatalogue('en')->all('admin') as $key => $value) {
  97.                 if (!isset($translations[$key]) || empty($translations[$key])) {
  98.                     $translations[$key] = $value;
  99.                 }
  100.             }
  101.         }
  102.         $response = new Response('pimcore.system_i18n = ' $this->encodeJson($translations) . ';');
  103.         $response->headers->set('Content-Type''text/javascript');
  104.         return $response;
  105.     }
  106.     /**
  107.      * @Route("/script-proxy", name="pimcore_admin_misc_scriptproxy", methods={"GET"})
  108.      *
  109.      * @param Request $request
  110.      *
  111.      * @return Response
  112.      */
  113.     public function scriptProxyAction(Request $request)
  114.     {
  115.         if ($storageFile $request->get('storageFile')) {
  116.             $fileExtension \Pimcore\File::getFileExtension($storageFile);
  117.             $storage Storage::get('admin');
  118.             $scriptsContent $storage->read($storageFile);
  119.         } else {
  120.             trigger_deprecation('pimcore/pimcore''10.1''Calling /admin/misc/script-proxy without the parameter storageFile is deprecated and will not work in Pimcore 11.');
  121.             $allowedFileTypes = ['js''css'];
  122.             $scripts explode(','$request->get('scripts'));
  123.             $scriptPath $request->get('scriptPath');
  124.             if ($scriptPath) {
  125.                 $scriptPath realpath(PIMCORE_WEB_ROOT $scriptPath);
  126.                 if(!$scriptPath) {
  127.                     throw $this->createNotFoundException('Directory not found!');
  128.                 }
  129.                 if(!str_starts_with($scriptPathrtrim(str_replace('../'''PIMCORE_WEB_ROOT), './'))) {
  130.                     throw $this->createAccessDeniedException('Scripts not found! Please do not navigate out of the web root directory!');
  131.                 }
  132.                 $scriptPath .= '/';
  133.             } else {
  134.                 $scriptPath PIMCORE_SYSTEM_TEMP_DIRECTORY '/';
  135.             }
  136.             $scriptsContent '';
  137.             foreach ($scripts as $script) {
  138.                 $filePath $scriptPath $script;
  139.                 if (is_file($filePath) && is_readable($filePath) && in_array(\Pimcore\File::getFileExtension($script), $allowedFileTypes)) {
  140.                     $scriptsContent .= file_get_contents($filePath);
  141.                 }
  142.             }
  143.             $fileExtension \Pimcore\File::getFileExtension($scripts[0]);
  144.         }
  145.         if (!empty($scriptsContent)) {
  146.             $contentType 'text/javascript';
  147.             if ($fileExtension == 'css') {
  148.                 $contentType 'text/css';
  149.             }
  150.             $lifetime 86400;
  151.             $response = new Response($scriptsContent);
  152.             $response->headers->set('Cache-Control''max-age=' $lifetime);
  153.             $response->headers->set('Pragma''');
  154.             $response->headers->set('Content-Type'$contentType);
  155.             $response->headers->set('Expires'gmdate('D, d M Y H:i:s'time() + $lifetime) . ' GMT');
  156.             return $response;
  157.         } else {
  158.             throw $this->createNotFoundException('Scripts not found');
  159.         }
  160.     }
  161.     /**
  162.      * @Route("/admin-css", name="pimcore_admin_misc_admincss", methods={"GET"})
  163.      *
  164.      * @param Request $request
  165.      * @param Config $config
  166.      *
  167.      * @return Response
  168.      */
  169.     public function adminCssAction(Request $requestConfig $config)
  170.     {
  171.         // customviews config
  172.         $cvData \Pimcore\CustomView\Config::get();
  173.         // languages
  174.         $languages \Pimcore\Tool::getValidLanguages();
  175.         $adminLanguages \Pimcore\Tool\Admin::getLanguages();
  176.         $languages array_unique(array_merge($languages$adminLanguages));
  177.         $response $this->render('@PimcoreAdmin/Admin/Misc/admin-css.html.twig', [
  178.             'customviews' => $cvData,
  179.             'config' => $config,
  180.             'languages' => $languages,
  181.         ]);
  182.         $response->headers->set('Content-Type''text/css; charset=UTF-8');
  183.         return $response;
  184.     }
  185.     /**
  186.      * @Route("/ping", name="pimcore_admin_misc_ping", methods={"GET"})
  187.      *
  188.      * @param Request $request
  189.      *
  190.      * @return JsonResponse
  191.      */
  192.     public function pingAction(Request $request)
  193.     {
  194.         $response = [
  195.             'success' => true,
  196.         ];
  197.         return $this->adminJson($response);
  198.     }
  199.     /**
  200.      * @Route("/available-languages", name="pimcore_admin_misc_availablelanguages", methods={"GET"})
  201.      *
  202.      * @param Request $request
  203.      *
  204.      * @return Response
  205.      */
  206.     public function availableLanguagesAction(Request $request)
  207.     {
  208.         $locales Tool::getSupportedLocales();
  209.         $response = new Response('pimcore.available_languages = ' $this->encodeJson($locales) . ';');
  210.         $response->headers->set('Content-Type''text/javascript');
  211.         return $response;
  212.     }
  213.     /**
  214.      * @Route("/get-valid-filename", name="pimcore_admin_misc_getvalidfilename", methods={"GET"})
  215.      *
  216.      * @param Request $request
  217.      *
  218.      * @return JsonResponse
  219.      */
  220.     public function getValidFilenameAction(Request $request)
  221.     {
  222.         return $this->adminJson([
  223.             'filename' => \Pimcore\Model\Element\Service::getValidKey($request->get('value'), $request->get('type')),
  224.         ]);
  225.     }
  226.     // FILEEXPLORER
  227.     /**
  228.      * @Route("/fileexplorer-tree", name="pimcore_admin_misc_fileexplorertree", methods={"GET"})
  229.      *
  230.      * @param Request $request
  231.      *
  232.      * @return JsonResponse
  233.      */
  234.     public function fileexplorerTreeAction(Request $request)
  235.     {
  236.         $this->checkPermission('fileexplorer');
  237.         $referencePath $this->getFileexplorerPath($request'node');
  238.         $items scandir($referencePath);
  239.         $contents = [];
  240.         foreach ($items as $item) {
  241.             if ($item == '.' || $item == '..') {
  242.                 continue;
  243.             }
  244.             $file $referencePath '/' $item;
  245.             $file str_replace('//''/'$file);
  246.             if (is_dir($file) || is_file($file)) {
  247.                 $itemConfig = [
  248.                     'id' => '/fileexplorer' str_replace(PIMCORE_PROJECT_ROOT''$file),
  249.                     'text' => $item,
  250.                     'leaf' => true,
  251.                     'writeable' => is_writable($file),
  252.                 ];
  253.                 if (is_dir($file)) {
  254.                     $itemConfig['leaf'] = false;
  255.                     $itemConfig['type'] = 'folder';
  256.                     if (is_dir_empty($file)) {
  257.                         $itemConfig['loaded'] = true;
  258.                     }
  259.                     $itemConfig['expandable'] = true;
  260.                 } elseif (is_file($file)) {
  261.                     $itemConfig['type'] = 'file';
  262.                 }
  263.                 $contents[] = $itemConfig;
  264.             }
  265.         }
  266.         return $this->adminJson($contents);
  267.     }
  268.     /**
  269.      * @Route("/fileexplorer-content", name="pimcore_admin_misc_fileexplorercontent", methods={"GET"})
  270.      *
  271.      * @param Request $request
  272.      *
  273.      * @return JsonResponse
  274.      */
  275.     public function fileexplorerContentAction(Request $request)
  276.     {
  277.         $this->checkPermission('fileexplorer');
  278.         $success false;
  279.         $writeable false;
  280.         $file $this->getFileexplorerPath($request'path');
  281.         $content null;
  282.         if (is_file($file)) {
  283.             if (is_readable($file)) {
  284.                 $content file_get_contents($file);
  285.                 $success true;
  286.                 $writeable is_writable($file);
  287.             }
  288.         }
  289.         return $this->adminJson([
  290.             'success' => $success,
  291.             'content' => $content,
  292.             'writeable' => $writeable,
  293.             'filename' => basename($file),
  294.             'path' => preg_replace('@^' preg_quote(PIMCORE_PROJECT_ROOT'@') . '@'''$file),
  295.         ]);
  296.     }
  297.     /**
  298.      * @Route("/fileexplorer-content-save", name="pimcore_admin_misc_fileexplorercontentsave", methods={"PUT"})
  299.      *
  300.      * @param Request $request
  301.      *
  302.      * @return JsonResponse
  303.      */
  304.     public function fileexplorerContentSaveAction(Request $request)
  305.     {
  306.         $this->checkPermission('fileexplorer');
  307.         $success false;
  308.         if ($request->get('content') && $request->get('path')) {
  309.             $file $this->getFileexplorerPath($request'path');
  310.             if (is_file($file) && is_writable($file)) {
  311.                 File::put($file$request->get('content'));
  312.                 $success true;
  313.             }
  314.         }
  315.         return $this->adminJson([
  316.             'success' => $success,
  317.         ]);
  318.     }
  319.     /**
  320.      * @Route("/fileexplorer-add", name="pimcore_admin_misc_fileexploreradd", methods={"POST"})
  321.      *
  322.      * @param Request $request
  323.      *
  324.      * @return JsonResponse
  325.      *
  326.      * @throws \Exception
  327.      */
  328.     public function fileexplorerAddAction(Request $request)
  329.     {
  330.         $this->checkPermission('fileexplorer');
  331.         $success false;
  332.         if ($request->get('filename') && $request->get('path')) {
  333.             $path $this->getFileexplorerPath($request'path');
  334.             $file $path '/' $request->get('filename');
  335.             $file resolvePath($file);
  336.             if (strpos($filePIMCORE_PROJECT_ROOT) !== 0) {
  337.                 throw new \Exception('not allowed');
  338.             }
  339.             if (is_writable(dirname($file))) {
  340.                 File::put($file'');
  341.                 $success true;
  342.             }
  343.         }
  344.         return $this->adminJson([
  345.             'success' => $success,
  346.         ]);
  347.     }
  348.     /**
  349.      * @Route("/fileexplorer-add-folder", name="pimcore_admin_misc_fileexploreraddfolder", methods={"POST"})
  350.      *
  351.      * @param Request $request
  352.      *
  353.      * @return JsonResponse
  354.      *
  355.      * @throws \Exception
  356.      */
  357.     public function fileexplorerAddFolderAction(Request $request)
  358.     {
  359.         $this->checkPermission('fileexplorer');
  360.         $success false;
  361.         if ($request->get('filename') && $request->get('path')) {
  362.             $path $this->getFileexplorerPath($request'path');
  363.             $file $path '/' $request->get('filename');
  364.             $file resolvePath($file);
  365.             if (strpos($filePIMCORE_PROJECT_ROOT) !== 0) {
  366.                 throw new \Exception('not allowed');
  367.             }
  368.             if (is_writable(dirname($file))) {
  369.                 File::mkdir($file);
  370.                 $success true;
  371.             }
  372.         }
  373.         return $this->adminJson([
  374.             'success' => $success,
  375.         ]);
  376.     }
  377.     /**
  378.      * @Route("/fileexplorer-delete", name="pimcore_admin_misc_fileexplorerdelete", methods={"DELETE"})
  379.      *
  380.      * @param Request $request
  381.      *
  382.      * @return JsonResponse
  383.      */
  384.     public function fileexplorerDeleteAction(Request $request)
  385.     {
  386.         $this->checkPermission('fileexplorer');
  387.         $success false;
  388.         if ($request->get('path')) {
  389.             $file $this->getFileexplorerPath($request'path');
  390.             if (is_writable($file)) {
  391.                 unlink($file);
  392.                 $success true;
  393.             }
  394.         }
  395.         return $this->adminJson([
  396.             'success' => $success,
  397.         ]);
  398.     }
  399.     /**
  400.      * @Route("/fileexplorer-rename", name="pimcore_admin_misc_fileexplorerrename", methods={"PUT"})
  401.      *
  402.      * @param Request $request
  403.      *
  404.      * @return JsonResponse
  405.      */
  406.     public function fileexplorerRenameAction(Request $request)
  407.     {
  408.         $this->checkPermission('fileexplorer');
  409.         $success false;
  410.         if ($request->get('path') && $request->get('newPath')) {
  411.             $file $this->getFileexplorerPath($request'path');
  412.             $newFile $this->getFileexplorerPath($request'newPath');
  413.             $success rename($file$newFile);
  414.         }
  415.         return $this->adminJson([
  416.             'success' => $success,
  417.         ]);
  418.     }
  419.     /**
  420.      * @param Request $request
  421.      * @param string $paramName
  422.      *
  423.      * @return string
  424.      *
  425.      * @throws \Exception
  426.      */
  427.     private function getFileexplorerPath(Request $request$paramName 'node')
  428.     {
  429.         $path preg_replace("/^\/fileexplorer/"''$request->get($paramName));
  430.         $path resolvePath(PIMCORE_PROJECT_ROOT $path);
  431.         if (strpos($pathPIMCORE_PROJECT_ROOT) !== 0) {
  432.             throw new \Exception('operation permitted, permission denied');
  433.         }
  434.         return $path;
  435.     }
  436.     /**
  437.      * @Route("/maintenance", name="pimcore_admin_misc_maintenance", methods={"POST"})
  438.      *
  439.      * @param Request $request
  440.      *
  441.      * @return JsonResponse
  442.      */
  443.     public function maintenanceAction(Request $request)
  444.     {
  445.         $this->checkPermission('maintenance_mode');
  446.         if ($request->get('activate')) {
  447.             Tool\Admin::activateMaintenanceMode(Tool\Session::getSessionId());
  448.         }
  449.         if ($request->get('deactivate')) {
  450.             Tool\Admin::deactivateMaintenanceMode();
  451.         }
  452.         return $this->adminJson([
  453.             'success' => true,
  454.         ]);
  455.     }
  456.     /**
  457.      * @Route("/http-error-log", name="pimcore_admin_misc_httperrorlog", methods={"POST"})
  458.      *
  459.      * @param Request $request
  460.      *
  461.      * @return JsonResponse
  462.      */
  463.     public function httpErrorLogAction(Request $request)
  464.     {
  465.         $this->checkPermission('http_errors');
  466.         $db Db::get();
  467.         $limit = (int)$request->get('limit');
  468.         $offset = (int)$request->get('start');
  469.         $sortInfo = ($request->get('sort') ? json_decode($request->get('sort'), true)[0] : []);
  470.         $sort $sortInfo['property'] ?? null;
  471.         $dir $sortInfo['direction'] ?? null;
  472.         $filter $request->get('filter');
  473.         if (!$limit) {
  474.             $limit 20;
  475.         }
  476.         if (!$offset) {
  477.             $offset 0;
  478.         }
  479.         if (!$sort || !in_array($sort, ['code''uri''date''count'])) {
  480.             $sort 'count';
  481.         }
  482.         if (!$dir || !in_array($dir, ['DESC''ASC'])) {
  483.             $dir 'DESC';
  484.         }
  485.         $condition '';
  486.         if ($filter) {
  487.             $filter $db->quote('%' $filter '%');
  488.             $conditionParts = [];
  489.             foreach (['uri''code''parametersGet''parametersPost''serverVars''cookies'] as $field) {
  490.                 $conditionParts[] = $field ' LIKE ' $filter;
  491.             }
  492.             $condition ' WHERE ' implode(' OR '$conditionParts);
  493.         }
  494.         $logs $db->fetchAllAssociative('SELECT code,uri,`count`,date FROM http_error_log ' $condition ' ORDER BY ' $sort ' ' $dir ' LIMIT ' $offset ',' $limit);
  495.         $total $db->fetchOne('SELECT count(*) FROM http_error_log ' $condition);
  496.         return $this->adminJson([
  497.             'items' => $logs,
  498.             'total' => $total,
  499.             'success' => true,
  500.         ]);
  501.     }
  502.     /**
  503.      * @Route("/http-error-log-flush", name="pimcore_admin_misc_httperrorlogflush", methods={"DELETE"})
  504.      *
  505.      * @param Request $request
  506.      *
  507.      * @return JsonResponse
  508.      */
  509.     public function httpErrorLogFlushAction(Request $request)
  510.     {
  511.         $this->checkPermission('http_errors');
  512.         $db Db::get();
  513.         $db->executeQuery('TRUNCATE TABLE http_error_log');
  514.         return $this->adminJson([
  515.             'success' => true,
  516.         ]);
  517.     }
  518.     /**
  519.      * @Route("/http-error-log-detail", name="pimcore_admin_misc_httperrorlogdetail", methods={"GET"})
  520.      *
  521.      * @param Request $request
  522.      * @param Profiler|null $profiler
  523.      *
  524.      * @return Response
  525.      */
  526.     public function httpErrorLogDetailAction(Request $request, ?Profiler $profiler)
  527.     {
  528.         $this->checkPermission('http_errors');
  529.         if ($profiler) {
  530.             $profiler->disable();
  531.         }
  532.         $db Db::get();
  533.         $data $db->fetchAssociative('SELECT * FROM http_error_log WHERE uri = ?', [$request->get('uri')]);
  534.         foreach ($data as $key => &$value) {
  535.             if (in_array($key, ['parametersGet''parametersPost''serverVars''cookies'])) {
  536.                 $value unserialize($value);
  537.             }
  538.         }
  539.         $response $this->render('@PimcoreAdmin/Admin/Misc/http-error-log-detail.html.twig', ['data' => $data]);
  540.         return $response;
  541.     }
  542.     /**
  543.      * @Route("/country-list", name="pimcore_admin_misc_countrylist", methods={"GET"})
  544.      *
  545.      * @param LocaleServiceInterface $localeService
  546.      *
  547.      * @return JsonResponse
  548.      */
  549.     public function countryListAction(LocaleServiceInterface $localeService)
  550.     {
  551.         $countries $localeService->getDisplayRegions();
  552.         asort($countries);
  553.         $options = [];
  554.         foreach ($countries as $short => $translation) {
  555.             if (strlen($short) == 2) {
  556.                 $options[] = [
  557.                     'name' => $translation,
  558.                     'code' => $short,
  559.                 ];
  560.             }
  561.         }
  562.         return $this->adminJson(['data' => $options]);
  563.     }
  564.     /**
  565.      * @Route("/language-list", name="pimcore_admin_misc_languagelist", methods={"GET"})
  566.      *
  567.      * @param Request $request
  568.      *
  569.      * @return JsonResponse
  570.      */
  571.     public function languageListAction(Request $request)
  572.     {
  573.         $locales Tool::getSupportedLocales();
  574.         $options = [];
  575.         foreach ($locales as $short => $translation) {
  576.             $options[] = [
  577.                 'name' => $translation,
  578.                 'code' => $short,
  579.             ];
  580.         }
  581.         return $this->adminJson(['data' => $options]);
  582.     }
  583.     /**
  584.      * @Route("/phpinfo", name="pimcore_admin_misc_phpinfo", methods={"GET"})
  585.      *
  586.      * @param Request $request
  587.      * @param Profiler|null $profiler
  588.      *
  589.      * @throws \Exception
  590.      *
  591.      * @return Response
  592.      */
  593.     public function phpinfoAction(Request $request, ?Profiler $profiler)
  594.     {
  595.         if ($profiler) {
  596.             $profiler->disable();
  597.         }
  598.         if (!$this->getAdminUser()->isAdmin()) {
  599.             throw new \Exception('Permission denied');
  600.         }
  601.         ob_start();
  602.         phpinfo();
  603.         $content ob_get_clean();
  604.         return new Response($content);
  605.     }
  606.     /**
  607.      * @Route("/get-language-flag", name="pimcore_admin_misc_getlanguageflag", methods={"GET"})
  608.      *
  609.      * @param Request $request
  610.      *
  611.      * @return BinaryFileResponse
  612.      */
  613.     public function getLanguageFlagAction(Request $request)
  614.     {
  615.         $iconPath Tool::getLanguageFlagFile($request->get('language'));
  616.         $response = new BinaryFileResponse($iconPath);
  617.         $response->headers->set('Content-Type''image/svg+xml');
  618.         return $response;
  619.     }
  620.     /**
  621.      * @Route("/icon-list", name="pimcore_admin_misc_iconlist", methods={"GET"})
  622.      *
  623.      * @param Request $request
  624.      * @param Profiler|null $profiler
  625.      *
  626.      * @return Response
  627.      */
  628.     public function iconListAction(Request $request, ?Profiler $profiler)
  629.     {
  630.         if ($profiler) {
  631.             $profiler->disable();
  632.         }
  633.         $publicDir PIMCORE_WEB_ROOT '/bundles/pimcoreadmin';
  634.         $iconDir $publicDir '/img';
  635.         $colorIcons rscandir($iconDir '/flat-color-icons/');
  636.         $whiteIcons rscandir($iconDir '/flat-white-icons/');
  637.         $twemoji rscandir($iconDir '/twemoji/');
  638.         //flag icons for locales
  639.         $locales Tool::getSupportedLocales();
  640.         $languageOptions = [];
  641.         foreach ($locales as $short => $translation) {
  642.             if (!empty($short)) {
  643.                 $languageOptions[] = [
  644.                     'language' => $short,
  645.                     'display' => $translation " ($short)",
  646.                     'flag' => \Pimcore\Tool::getLanguageFlagFile($shorttrue),
  647.                 ];
  648.             }
  649.         }
  650.         $iconsCss file_get_contents($publicDir '/css/icons.css');
  651.         return $this->render('@PimcoreAdmin/Admin/Misc/iconList.html.twig', [
  652.             'colorIcons' => $colorIcons,
  653.             'whiteIcons' => $whiteIcons,
  654.             'twemoji' => $twemoji,
  655.             'languageOptions' => $languageOptions,
  656.             'iconsCss' => $iconsCss,
  657.         ]);
  658.     }
  659.     /**
  660.      * @Route("/test", name="pimcore_admin_misc_test")
  661.      *
  662.      * @param Request $request
  663.      *
  664.      * @return Response
  665.      */
  666.     public function testAction(Request $request)
  667.     {
  668.         return new Response('done');
  669.     }
  670. }