vendor/pimcore/pimcore/bundles/AdminBundle/Controller/Admin/IndexController.php line 76

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 Linfo;
  16. use Pimcore\Analytics\Google\Config\SiteConfigProvider;
  17. use Pimcore\Bundle\AdminBundle\Controller\AdminController;
  18. use Pimcore\Bundle\AdminBundle\EventListener\CsrfProtectionListener;
  19. use Pimcore\Bundle\AdminBundle\HttpFoundation\JsonResponse;
  20. use Pimcore\Config;
  21. use Pimcore\Controller\Configuration\TemplatePhp;
  22. use Pimcore\Controller\EventedControllerInterface;
  23. use Pimcore\Db\ConnectionInterface;
  24. use Pimcore\Event\Admin\IndexSettingsEvent;
  25. use Pimcore\Event\AdminEvents;
  26. use Pimcore\Google;
  27. use Pimcore\Maintenance\Executor;
  28. use Pimcore\Maintenance\ExecutorInterface;
  29. use Pimcore\Model\Element\Service;
  30. use Pimcore\Model\User;
  31. use Pimcore\Templating\Model\ViewModel;
  32. use Pimcore\Tool;
  33. use Pimcore\Tool\Admin;
  34. use Pimcore\Tool\Session;
  35. use Pimcore\Version;
  36. use Symfony\Component\EventDispatcher\EventDispatcherInterface;
  37. use Symfony\Component\HttpFoundation\Request;
  38. use Symfony\Component\HttpFoundation\Session\Attribute\AttributeBagInterface;
  39. use Symfony\Component\HttpKernel\Event\FilterControllerEvent;
  40. use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
  41. use Symfony\Component\HttpKernel\KernelInterface;
  42. use Symfony\Component\Routing\Annotation\Route;
  43. class IndexController extends AdminController implements EventedControllerInterface
  44. {
  45.     /**
  46.      * @var EventDispatcherInterface
  47.      */
  48.     private $eventDispatcher;
  49.     /**
  50.      * @param EventDispatcherInterface $eventDispatcher
  51.      */
  52.     public function __construct(EventDispatcherInterface $eventDispatcher)
  53.     {
  54.         $this->eventDispatcher $eventDispatcher;
  55.     }
  56.     /**
  57.      * @Route("/", name="pimcore_admin_index", methods={"GET"})
  58.      * @TemplatePhp()
  59.      *
  60.      * @param Request $request
  61.      * @param SiteConfigProvider $siteConfigProvider
  62.      * @param KernelInterface $kernel
  63.      * @param Executor $maintenanceExecutor
  64.      * @param CsrfProtectionListener $csrfProtectionListener
  65.      * @param Config $config
  66.      *
  67.      * @return ViewModel
  68.      *
  69.      * @throws \Exception
  70.      */
  71.     public function indexAction(
  72.         Request $request,
  73.         SiteConfigProvider $siteConfigProvider,
  74.         KernelInterface $kernel,
  75.         Executor $maintenanceExecutor,
  76.         CsrfProtectionListener $csrfProtectionListener,
  77.         Config $config
  78.     ) {
  79.         $user $this->getAdminUser();
  80.         $view = new ViewModel([
  81.             'config' => $config,
  82.         ]);
  83.         $this
  84.             ->addRuntimePerspective($view$user)
  85.             ->addReportConfig($view)
  86.             ->addPluginAssets($view);
  87.         $settings $this->buildPimcoreSettings($request$view$user$kernel$maintenanceExecutor$csrfProtectionListener);
  88.         $this->buildGoogleAnalyticsSettings($view$settings$siteConfigProvider);
  89.         if ($user->getTwoFactorAuthentication('required') && !$user->getTwoFactorAuthentication('enabled')) {
  90.             // only one login is allowed to setup 2FA by the user himself
  91.             $user->setTwoFactorAuthentication('enabled'true);
  92.             // disable the 2FA prompt for the current session
  93.             Tool\Session::useSession(function (AttributeBagInterface $adminSession) {
  94.                 $adminSession->set('2fa_required'false);
  95.             });
  96.             $user->save();
  97.             $settings->getParameters()->add([
  98.                 'twoFactorSetupRequired' => true,
  99.             ]);
  100.         }
  101.         // allow to alter settings via an event
  102.         $this->eventDispatcher->dispatch(AdminEvents::INDEX_SETTINGS, new IndexSettingsEvent($settings));
  103.         $view->settings $settings;
  104.         return $view;
  105.     }
  106.     /**
  107.      * @Route("/index/statistics", name="pimcore_admin_index_statistics", methods={"GET"})
  108.      *
  109.      * @param Request $request
  110.      * @param ConnectionInterface $db
  111.      * @param KernelInterface $kernel
  112.      *
  113.      * @return JsonResponse
  114.      *
  115.      * @throws \Exception
  116.      */
  117.     public function statisticsAction(Request $requestConnectionInterface $dbKernelInterface $kernel)
  118.     {
  119.         // DB
  120.         $mysqlVersion null;
  121.         try {
  122.             $tables $db->fetchAll('SELECT TABLE_NAME as name,TABLE_ROWS as rows from information_schema.TABLES
  123.                 WHERE TABLE_ROWS IS NOT NULL AND TABLE_SCHEMA = ?', [$db->getDatabase()]);
  124.             $mysqlVersion $db->fetchOne('SELECT VERSION()');
  125.         } catch (\Exception $e) {
  126.             $tables = [];
  127.         }
  128.         // System
  129.         try {
  130.             $linfo = new Linfo\Linfo([
  131.                 'show' => [
  132.                     'os' => true,
  133.                     'ram' => true,
  134.                     'cpu' => true,
  135.                     'virtualization' => true,
  136.                     'distro' => true,
  137.                 ],
  138.             ]);
  139.             $linfo->scan();
  140.             $systemData $linfo->getInfo();
  141.             $system = [
  142.                 'OS' => $systemData['OS'],
  143.                 'Distro' => $systemData['Distro'],
  144.                 'RAMTotal' => $systemData['RAM']['total'],
  145.                 'CPUCount' => count($systemData['CPU']),
  146.                 'CPUModel' => $systemData['CPU'][0]['Model'],
  147.                 'CPUClock' => $systemData['CPU'][0]['MHz'],
  148.                 'virtualization' => $systemData['virtualization'],
  149.             ];
  150.         } catch (\Exception $e) {
  151.             $system = [];
  152.         }
  153.         try {
  154.             $data = [
  155.                 'instanceId' => $this->getInstanceId(),
  156.                 'pimcore_version' => Version::getVersion(),
  157.                 'pimcore_hash' => Version::getRevision(),
  158.                 'php_version' => PHP_VERSION,
  159.                 'mysql_version' => $mysqlVersion,
  160.                 'bundles' => array_keys($kernel->getBundles()),
  161.                 'system' => $system,
  162.                 'tables' => $tables,
  163.             ];
  164.         } catch (\Exception $e) {
  165.             $data = [];
  166.         }
  167.         return $this->adminJson($data);
  168.     }
  169.     /**
  170.      * @param ViewModel $view
  171.      * @param User $user
  172.      *
  173.      * @return $this
  174.      */
  175.     protected function addRuntimePerspective(ViewModel $viewUser $user)
  176.     {
  177.         $runtimePerspective Config::getRuntimePerspective($user);
  178.         $view->runtimePerspective $runtimePerspective;
  179.         return $this;
  180.     }
  181.     /**
  182.      * @param ViewModel $view
  183.      *
  184.      * @return $this
  185.      */
  186.     protected function addReportConfig(ViewModel $view)
  187.     {
  188.         // TODO where is this used?
  189.         $view->report_config Config::getReportConfig();
  190.         return $this;
  191.     }
  192.     /**
  193.      * @param ViewModel $view
  194.      *
  195.      * @return $this
  196.      */
  197.     protected function addPluginAssets(ViewModel $view)
  198.     {
  199.         $bundleManager $this->get('pimcore.extension.bundle_manager');
  200.         $view->pluginJsPaths $bundleManager->getJsPaths();
  201.         $view->pluginCssPaths $bundleManager->getCssPaths();
  202.         return $this;
  203.     }
  204.     /**
  205.      * @param Request $request
  206.      * @param ViewModel $view
  207.      * @param User $user
  208.      * @param KernelInterface $kernel
  209.      * @param ExecutorInterface $maintenanceExecutor
  210.      * @param CsrfProtectionListener $csrfProtectionListener
  211.      *
  212.      * @return ViewModel
  213.      */
  214.     protected function buildPimcoreSettings(Request $requestViewModel $viewUser $userKernelInterface $kernelExecutorInterface $maintenanceExecutorCsrfProtectionListener $csrfProtectionListener)
  215.     {
  216.         $config $view->config;
  217.         $settings = new ViewModel([
  218.             'instanceId' => $this->getInstanceId(),
  219.             'version' => Version::getVersion(),
  220.             'build' => Version::getRevision(),
  221.             'debug' => \Pimcore::inDebugMode(),
  222.             'devmode' => \Pimcore::inDevMode(),
  223.             'disableMinifyJs' => \Pimcore::disableMinifyJs(),
  224.             'environment' => $kernel->getEnvironment(),
  225.             'cached_environments' => Tool::getCachedSymfonyEnvironments(),
  226.             'sessionId' => htmlentities(Session::getSessionId(), ENT_QUOTES'UTF-8'),
  227.         ]);
  228.         // languages
  229.         $settings->getParameters()->add([
  230.             'language' => $request->getLocale(),
  231.             'websiteLanguages' => Admin::reorderWebsiteLanguages(
  232.                 $this->getAdminUser(),
  233.                 $config['general']['valid_languages'],
  234.                 true
  235.             ),
  236.         ]);
  237.         // flags
  238.         $namingStrategy $this->get('pimcore.document.tag.naming.strategy');
  239.         $settings->getParameters()->add([
  240.             'showCloseConfirmation' => true,
  241.             'debug_admin_translations' => (bool)$config['general']['debug_admin_translations'],
  242.             'document_generatepreviews' => (bool)$config['documents']['generate_preview'],
  243.             'document_naming_strategy' => $namingStrategy->getName(),
  244.             'asset_disable_tree_preview' => (bool)$config['assets']['disable_tree_preview'],
  245.             'htmltoimage' => \Pimcore\Image\HtmlToImage::isSupported(),
  246.             'videoconverter' => \Pimcore\Video::isAvailable(),
  247.             'asset_hide_edit' => (bool)$config['assets']['hide_edit_image'],
  248.             'main_domain' => $config['general']['domain'],
  249.             'timezone' => $config['general']['timezone'],
  250.             'tile_layer_url_template' => $config['maps']['tile_layer_url_template'],
  251.             'geocoding_url_template' => $config['maps']['geocoding_url_template'],
  252.             'reverse_geocoding_url_template' => $config['maps']['reverse_geocoding_url_template'],
  253.             'asset_tree_paging_limit' => $config['assets']['tree_paging_limit'],
  254.             'document_tree_paging_limit' => $config['documents']['tree_paging_limit'],
  255.             'object_tree_paging_limit' => $config['objects']['tree_paging_limit'],
  256.             'maxmind_geoip_installed' => (bool) $this->getParameter('pimcore.geoip.db_file'),
  257.         ]);
  258.         $dashboardHelper = new \Pimcore\Helper\Dashboard($user);
  259.         // perspective and portlets
  260.         $settings->getParameters()->add([
  261.             'perspective' => $view->runtimePerspective,
  262.             'availablePerspectives' => Config::getAvailablePerspectives($user),
  263.             'disabledPortlets' => $dashboardHelper->getDisabledPortlets(),
  264.         ]);
  265.         $this
  266.             ->addSystemVarSettings($settings)
  267.             ->addMaintenanceSettings($settings$maintenanceExecutor)
  268.             ->addMailSettings($settings$config)
  269.             ->addCustomViewSettings($settings);
  270.         $settings->csrfToken $csrfProtectionListener->getCsrfToken();
  271.         return $settings;
  272.     }
  273.     /**
  274.      * @return string
  275.      */
  276.     private function getInstanceId()
  277.     {
  278.         $instanceId 'not-set';
  279.         try {
  280.             $instanceId $this->getParameter('secret');
  281.             $instanceId sha1(substr($instanceId3, -3));
  282.         } catch (\Exception $e) {
  283.             // nothing to do
  284.         }
  285.         return $instanceId;
  286.     }
  287.     private function buildGoogleAnalyticsSettings(
  288.         ViewModel $view,
  289.         ViewModel $settings,
  290.         SiteConfigProvider $siteConfigProvider
  291.     ) {
  292.         $config $view->config;
  293.         $settings->getParameters()->add([
  294.             'google_analytics_enabled' => (bool)$siteConfigProvider->isSiteReportingConfigured(),
  295.             'google_webmastertools_enabled' => (bool)Google\Webmastertools::isConfigured(),
  296.         ]);
  297.     }
  298.     /**
  299.      * @param ViewModel $settings
  300.      *
  301.      * @return $this
  302.      */
  303.     protected function addSystemVarSettings(ViewModel $settings)
  304.     {
  305.         // upload limit
  306.         $max_upload filesize2bytes(ini_get('upload_max_filesize') . 'B');
  307.         $max_post filesize2bytes(ini_get('post_max_size') . 'B');
  308.         $upload_mb min($max_upload$max_post);
  309.         $settings->upload_max_filesize = (int)$upload_mb;
  310.         // session lifetime (gc)
  311.         $session_gc_maxlifetime ini_get('session.gc_maxlifetime');
  312.         if (empty($session_gc_maxlifetime)) {
  313.             $session_gc_maxlifetime 120;
  314.         }
  315.         $settings->session_gc_maxlifetime = (int)$session_gc_maxlifetime;
  316.         return $this;
  317.     }
  318.     /**
  319.      * @param ViewModel $settings
  320.      * @param ExecutorInterface $maintenanceExecutor
  321.      *
  322.      * @return $this
  323.      */
  324.     protected function addMaintenanceSettings(ViewModel $settingsExecutorInterface $maintenanceExecutor)
  325.     {
  326.         // check maintenance
  327.         $maintenance_active false;
  328.         if ($lastExecution $maintenanceExecutor->getLastExecution()) {
  329.             if ((time() - $lastExecution) < 3660) { // maintenance script should run at least every hour + a little tolerance
  330.                 $maintenance_active true;
  331.             }
  332.         }
  333.         $settings->maintenance_active $maintenance_active;
  334.         $settings->maintenance_mode Admin::isInMaintenanceMode();
  335.         return $this;
  336.     }
  337.     /**
  338.      * @param ViewModel $settings
  339.      * @param Config $config
  340.      *
  341.      * @return $this
  342.      */
  343.     protected function addMailSettings(ViewModel $settings$config)
  344.     {
  345.         //mail settings
  346.         $mailIncomplete false;
  347.         if (isset($config['email'])) {
  348.             if (empty($config['email']['debug']['email_addresses'])) {
  349.                 $mailIncomplete true;
  350.             }
  351.             if (empty($config['email']['sender']['email'])) {
  352.                 $mailIncomplete true;
  353.             }
  354.             if (($config['email']['method'] ?? '') == 'smtp' && empty($config['email']['smtp']['host'])) {
  355.                 $mailIncomplete true;
  356.             }
  357.         }
  358.         $settings->mail = !$mailIncomplete;
  359.         $settings->mailDefaultAddress $config['email']['sender']['email'] ?? null;
  360.         return $this;
  361.     }
  362.     /**
  363.      * @param ViewModel $settings
  364.      *
  365.      * @return $this
  366.      */
  367.     protected function addCustomViewSettings(ViewModel $settings)
  368.     {
  369.         $cvData = [];
  370.         // still needed when publishing objects
  371.         $cvConfig Tool::getCustomViewConfig();
  372.         if ($cvConfig) {
  373.             foreach ($cvConfig as $node) {
  374.                 $tmpData $node;
  375.                 // backwards compatibility
  376.                 $treeType $tmpData['treetype'] ? $tmpData['treetype'] : 'object';
  377.                 $rootNode Service::getElementByPath($treeType$tmpData['rootfolder']);
  378.                 if ($rootNode) {
  379.                     $tmpData['rootId'] = $rootNode->getId();
  380.                     $tmpData['allowedClasses'] = isset($tmpData['classes']) && $tmpData['classes'] ? explode(','$tmpData['classes']) : null;
  381.                     $tmpData['showroot'] = (bool)$tmpData['showroot'];
  382.                     // Check if a user has privileges to that node
  383.                     if ($rootNode->isAllowed('list')) {
  384.                         $cvData[] = $tmpData;
  385.                     }
  386.                 }
  387.             }
  388.         }
  389.         $settings->customviews $cvData;
  390.         return $this;
  391.     }
  392.     public function onKernelController(FilterControllerEvent $event)
  393.     {
  394.     }
  395.     public function onKernelResponse(FilterResponseEvent $event)
  396.     {
  397.         $event->getResponse()->headers->set('X-Frame-Options''deny'true);
  398.     }
  399. }