app/Kernel.php line 53

Open in your IDE?
  1. <?php
  2. namespace ForkCMS\App;
  3. use PDOException;
  4. use Spoon;
  5. use SpoonDatabaseException;
  6. use Symfony\Component\DependencyInjection\ContainerBuilder;
  7. use Symfony\Component\Filesystem\Filesystem;
  8. use Symfony\Component\Finder\Finder;
  9. use Symfony\Component\HttpFoundation\Response;
  10. use Symfony\Component\HttpKernel\DependencyInjection\MergeExtensionConfigurationPass;
  11. use Symfony\Component\HttpKernel\Kernel as BaseKernel;
  12. use Symfony\Component\HttpFoundation\Request;
  13. use Symfony\Component\HttpKernel\HttpKernelInterface;
  14. use Backend\DependencyInjection\BackendExtension;
  15. /**
  16.  * The Kernel provides a proper way to load an environment and DI container.
  17.  * It also handles requests and responses.
  18.  */
  19. abstract class Kernel extends BaseKernel
  20. {
  21.     /** @var Request We need this to check if a module is being installed */
  22.     private $request;
  23.     /**
  24.      * Constructor.
  25.      *
  26.      * @param string $environment The environment
  27.      * @param bool $enableDebug Whether to enable debugging or not
  28.      *
  29.      * @api
  30.      */
  31.     public function __construct(string $environmentbool $enableDebug)
  32.     {
  33.         $this->request Request::createFromGlobals();
  34.         parent::__construct($environment$enableDebug);
  35.         $this->boot();
  36.     }
  37.     /**
  38.      * {@inheritdoc}
  39.      *
  40.      * @api
  41.      */
  42.     public function handle(Request $request$type HttpKernelInterface::MASTER_REQUEST$catch true): Response
  43.     {
  44.         // boot if it hasn't booted yet
  45.         $this->boot();
  46.         return $this->getHttpKernel()->handle($request$type$catch);
  47.     }
  48.     /**
  49.      * Boot and define the Fork Constants.
  50.      */
  51.     public function boot(): void
  52.     {
  53.         if ($this->booted) {
  54.             return;
  55.         }
  56.         parent::boot();
  57.         // define Fork constants
  58.         $this->defineForkConstants();
  59.     }
  60.     /**
  61.      * This will disappear in time in favour of container-driven parameters.
  62.      *
  63.      * @deprecated
  64.      */
  65.     public function defineForkConstants(): void
  66.     {
  67.         $container $this->getContainer();
  68.         Spoon::setDebug($container->getParameter('kernel.debug'));
  69.         Spoon::setDebugEmail($container->getParameter('fork.debug_email'));
  70.         Spoon::setDebugMessage($container->getParameter('fork.debug_message'));
  71.         Spoon::setCharset($container->getParameter('kernel.charset'));
  72.         /**
  73.          * @deprecated SPOON_* constants are deprecated in favour of Spoon::set*().
  74.          * Will be removed in the next major release.
  75.          */
  76.         defined('PATH_WWW') || define('PATH_WWW'realpath($container->getParameter('site.path_www')));
  77.         defined('SITE_DEFAULT_LANGUAGE') || define('SITE_DEFAULT_LANGUAGE'$container->getParameter('site.default_language'));
  78.         defined('SITE_DEFAULT_TITLE') || define('SITE_DEFAULT_TITLE'$container->getParameter('site.default_title'));
  79.         defined('SITE_MULTILANGUAGE') || define('SITE_MULTILANGUAGE'$container->getParameter('site.multilanguage'));
  80.         defined('SITE_DOMAIN') || define('SITE_DOMAIN'$container->getParameter('site.domain'));
  81.         defined('SITE_PROTOCOL') || define('SITE_PROTOCOL'$container->getParameter('site.protocol'));
  82.         defined('SITE_URL') || define('SITE_URL'SITE_PROTOCOL '://' SITE_DOMAIN);
  83.         defined('FORK_VERSION') || define('FORK_VERSION'$container->getParameter('fork.version'));
  84.         defined('ACTION_GROUP_TAG') || define('ACTION_GROUP_TAG'$container->getParameter('action.group_tag'));
  85.         defined('ACTION_RIGHTS_LEVEL') || define('ACTION_RIGHTS_LEVEL'$container->getParameter('action.rights_level'));
  86.         defined('BACKEND_PATH') || define('BACKEND_PATH'PATH_WWW '/src/Backend');
  87.         defined('BACKEND_CACHE_PATH') || define('BACKEND_CACHE_PATH'BACKEND_PATH '/Cache');
  88.         defined('BACKEND_CORE_PATH') || define('BACKEND_CORE_PATH'BACKEND_PATH '/Core');
  89.         defined('BACKEND_MODULES_PATH') || define('BACKEND_MODULES_PATH'BACKEND_PATH '/Modules');
  90.         defined('BACKEND_CORE_URL') || define('BACKEND_CORE_URL''/src/Backend/Core');
  91.         defined('BACKEND_CACHE_URL') || define('BACKEND_CACHE_URL''/src/Backend/Cache');
  92.         defined('FRONTEND_PATH') || define('FRONTEND_PATH'PATH_WWW '/src/Frontend');
  93.         defined('FRONTEND_CACHE_PATH') || define('FRONTEND_CACHE_PATH'FRONTEND_PATH '/Cache');
  94.         defined('FRONTEND_THEMES_PATH') || define('FRONTEND_THEMES_PATH'FRONTEND_PATH '/Themes');
  95.         defined('FRONTEND_CORE_PATH') || define('FRONTEND_CORE_PATH'FRONTEND_PATH '/Core');
  96.         defined('FRONTEND_MODULES_PATH') || define('FRONTEND_MODULES_PATH'FRONTEND_PATH '/Modules');
  97.         defined('FRONTEND_FILES_PATH') || define('FRONTEND_FILES_PATH'FRONTEND_PATH '/Files');
  98.         defined('FRONTEND_FILES_URL') || define('FRONTEND_FILES_URL''/src/Frontend/Files');
  99.         defined('FRONTEND_CORE_URL') || define('FRONTEND_CORE_URL''/src/Frontend/Core');
  100.         defined('FRONTEND_CACHE_URL') || define('FRONTEND_CACHE_URL''/src/Frontend/Cache');
  101.     }
  102.     /**
  103.      * Builds the service container.
  104.      *
  105.      * @throws \RuntimeException
  106.      *
  107.      * @return ContainerBuilder The compiled service container
  108.      */
  109.     protected function buildContainer()
  110.     {
  111.         $container parent::buildContainer();
  112.         $installedModules $this->getInstalledModules($container);
  113.         $container->setParameter('installed_modules'$installedModules);
  114.         foreach ($installedModules as $module) {
  115.             $class 'Backend\\Modules\\' $module '\\DependencyInjection\\' $module 'Extension';
  116.             if (class_exists($class)) {
  117.                 $container->registerExtension(new $class());
  118.             }
  119.         }
  120.         $container->registerExtension(new BackendExtension());
  121.         // ensure these extensions are implicitly loaded
  122.         $container->getCompilerPassConfig()->setMergePass(
  123.             new MergeExtensionConfigurationPass(array_keys($container->getExtensions()))
  124.         );
  125.         return $container;
  126.     }
  127.     private function getInstalledModules(ContainerBuilder $containerBuilder): array
  128.     {
  129.         // on installation all modules should be loaded
  130.         if ($this->environment === 'install' || $this->environment === 'test') {
  131.             return $this->getAllPossibleModuleNames();
  132.         }
  133.         $moduleNames = [];
  134.         if ($this->isInstallingModule()) {
  135.             $moduleNames[] = $this->request->query->get('module');
  136.         }
  137.         try {
  138.             $moduleNames array_merge(
  139.                 $moduleNames,
  140.                 (array) $containerBuilder->get('database')->getColumn(
  141.                     'SELECT name FROM modules'
  142.                 )
  143.             );
  144.         } catch (SpoonDatabaseException $e) {
  145.             $moduleNames = [];
  146.         } catch (PDOException $e) {
  147.             // fork is probably not installed yet
  148.             $moduleNames = [];
  149.         }
  150.         if (empty($moduleNames)) {
  151.             return $this->getAllPossibleModuleNames();
  152.         }
  153.         return $moduleNames;
  154.     }
  155.     public function isInstallingModule(): bool
  156.     {
  157.         return preg_match('/\/private(\/\w\w)?\/extensions\/install_module\?/'$this->request->getRequestUri())
  158.                && $this->request->query->has('module')
  159.                && in_array($this->request->query->get('module'), $this->getAllPossibleModuleNames());
  160.     }
  161.     private function getAllPossibleModuleNames(): array
  162.     {
  163.         $moduleNames = [];
  164.         $finder = new Finder();
  165.         $directories $finder->directories()->in(__DIR__ '/../src/Backend/Modules')->depth(0);
  166.         foreach ($directories->getIterator() as $directory) {
  167.             $moduleNames[] = $directory->getFilename();
  168.         }
  169.         return $moduleNames;
  170.     }
  171.     protected function initializeContainer(): void
  172.     {
  173.         // remove the cache dir when installing a module to trigger rebuilding the kernel
  174.         if ($this->isInstallingModule()) {
  175.             $fileSystem = new Filesystem();
  176.             $fileSystem->remove($this->getCacheDir().'/'.$this->getContainerClass().'.php');
  177.         }
  178.         parent::initializeContainer();
  179.     }
  180.     public function getLogDir(): string
  181.     {
  182.         return dirname(__DIR__).'/var/logs/' $this->environment;
  183.     }
  184.     public function getCacheDir(): string
  185.     {
  186.         return dirname(__DIR__) . '/var/cache/' $this->environment;
  187.     }
  188. }