pimcore/lib/Pimcore/Bundle/AdminBundle/Controller/Admin/MiscController.php line 231

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