<?php
namespace IcebirdCMS\App;
use PDOException;
use Spoon;
use SpoonDatabaseException;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\Finder\Finder;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\DependencyInjection\MergeExtensionConfigurationPass;
use Symfony\Component\HttpKernel\Kernel as BaseKernel;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\HttpKernelInterface;
use Application\DependencyInjection\ApplicationExtension;
abstract class Kernel extends BaseKernel
{
private $request;
public function __construct(string $environment, bool $enableDebug)
{
$this->request = Request::createFromGlobals();
parent::__construct($environment, $enableDebug);
$this->boot();
}
public function handle(Request $request, $type = HttpKernelInterface::MASTER_REQUEST, $catch = true): Response
{
$this->boot();
return $this->getHttpKernel()->handle($request, $type, $catch);
}
public function boot(): void
{
if ($this->booted) {
return;
}
parent::boot();
$this->defineIcebirdConstants();
}
public function defineIcebirdConstants(): void
{
$container = $this->getContainer();
Spoon::setDebug($container->getParameter('kernel.debug'));
Spoon::setDebugEmail($container->getParameter('icebird.debug_email'));
Spoon::setDebugMessage($container->getParameter('icebird.debug_message'));
Spoon::setCharset($container->getParameter('kernel.charset'));
defined('PATH_WWW') || define('PATH_WWW', realpath($container->getParameter('site.path_www')));
defined('SITE_DEFAULT_LANGUAGE') || define('SITE_DEFAULT_LANGUAGE', $container->getParameter('site.default_language'));
defined('SITE_DEFAULT_TITLE') || define('SITE_DEFAULT_TITLE', $container->getParameter('site.default_title'));
defined('SITE_MULTILANGUAGE') || define('SITE_MULTILANGUAGE', $container->getParameter('site.multilanguage'));
defined('SITE_DOMAIN') || define('SITE_DOMAIN', $container->getParameter('site.domain'));
defined('SITE_PROTOCOL') || define('SITE_PROTOCOL', $container->getParameter('site.protocol'));
defined('SITE_URL') || define('SITE_URL', SITE_PROTOCOL . '://' . SITE_DOMAIN);
defined('ICEBIRD_VERSION') || define('ICEBIRD_VERSION', $container->getParameter('icebird.version'));
defined('ACTION_GROUP_TAG') || define('ACTION_GROUP_TAG', $container->getParameter('action.group_tag'));
defined('ACTION_RIGHTS_LEVEL') || define('ACTION_RIGHTS_LEVEL', $container->getParameter('action.rights_level'));
defined('APPLICATION_PATH') || define('APPLICATION_PATH', PATH_WWW . '/src/Application');
defined('APPLICATION_CACHE_PATH') || define('APPLICATION_CACHE_PATH', APPLICATION_PATH . '/Cache');
defined('APPLICATION_CORE_PATH') || define('APPLICATION_CORE_PATH', APPLICATION_PATH . '/Core');
defined('APPLICATION_MODULES_PATH') || define('APPLICATION_MODULES_PATH', APPLICATION_PATH . '/Modules');
defined('APPLICATION_CORE_URL') || define('APPLICATION_CORE_URL', '/src/Application/Core');
defined('APPLICATION_CACHE_URL') || define('APPLICATION_CACHE_URL', '/src/Application/Cache');
defined('WEB_PATH') || define('WEB_PATH', PATH_WWW . '/src/Web');
defined('WEB_CACHE_PATH') || define('WEB_CACHE_PATH', WEB_PATH . '/Cache');
defined('WEB_THEMES_PATH') || define('WEB_THEMES_PATH', WEB_PATH . '/Themes');
defined('WEB_CORE_PATH') || define('WEB_CORE_PATH', WEB_PATH . '/Core');
defined('WEB_MODULES_PATH') || define('WEB_MODULES_PATH', WEB_PATH . '/Modules');
defined('WEB_FILES_PATH') || define('WEB_FILES_PATH', WEB_PATH . '/Files');
defined('WEB_FILES_URL') || define('WEB_FILES_URL', '/src/Web/Files');
defined('WEB_CORE_URL') || define('WEB_CORE_URL', '/src/Web/Core');
defined('WEB_CACHE_URL') || define('WEB_CACHE_URL', '/src/Web/Cache');
}
protected function buildContainer()
{
$container = parent::buildContainer();
$installedModules = $this->getInstalledModules($container);
$container->setParameter('installed_modules', $installedModules);
foreach ($installedModules as $module) {
$class = 'Application\\Modules\\' . $module . '\\DependencyInjection\\' . $module . 'Extension';
if (class_exists($class)) {
$container->registerExtension(new $class());
}
}
$container->registerExtension(new ApplicationExtension());
$container->getCompilerPassConfig()->setMergePass(
new MergeExtensionConfigurationPass(array_keys($container->getExtensions()))
);
return $container;
}
private function getInstalledModules(ContainerBuilder $containerBuilder): array
{
if ($this->environment === 'install' || $this->environment === 'test') {
return $this->getAllPossibleModuleNames();
}
$moduleNames = [];
if ($this->isInstallingModule()) {
$moduleNames[] = $this->request->query->get('module');
}
try {
$moduleNames = array_merge(
$moduleNames,
(array) $containerBuilder->get('database')->getColumn(
'SELECT name FROM modules'
)
);
} catch (SpoonDatabaseException $e) {
$moduleNames = [];
} catch (PDOException $e) {
$moduleNames = [];
}
if (empty($moduleNames)) {
return $this->getAllPossibleModuleNames();
}
return $moduleNames;
}
private function isInstallingModule(): bool
{
return preg_match('/\/private(\/\w\w)?\/extensions\/install_module\?/', $this->request->getRequestUri())
&& $this->request->query->has('module')
&& in_array($this->request->query->get('module'), $this->getAllPossibleModuleNames());
}
private function getAllPossibleModuleNames(): array
{
$moduleNames = [];
$finder = new Finder();
$directories = $finder->directories()->in(__DIR__ . '/../src/Application/Modules')->depth(0);
foreach ($directories->getIterator() as $directory) {
$moduleNames[] = $directory->getFilename();
}
return $moduleNames;
}
protected function initializeContainer(): void
{
if ($this->isInstallingModule()) {
$fileSystem = new Filesystem();
$fileSystem->remove($this->getCacheDir().'/'.$this->getContainerClass().'.php');
}
parent::initializeContainer();
}
public function getLogDir(): string
{
return dirname(__DIR__).'/var/logs/' . $this->environment;
}
public function getCacheDir(): string
{
return dirname(__DIR__) . '/var/cache/' . $this->environment;
}
}