vendor/shopware/core/HttpKernel.php line 184

Open in your IDE?
  1. <?php declare(strict_types=1);
  2. namespace Shopware\Core;
  3. use Composer\Autoload\ClassLoader;
  4. use Composer\InstalledVersions;
  5. use Doctrine\DBAL\Configuration;
  6. use Doctrine\DBAL\Connection;
  7. use Doctrine\DBAL\DBALException;
  8. use Doctrine\DBAL\DriverManager;
  9. use Shopware\Core\DevOps\Environment\EnvironmentHelper;
  10. use Shopware\Core\Framework\Adapter\Cache\CacheIdLoader;
  11. use Shopware\Core\Framework\Event\BeforeSendRedirectResponseEvent;
  12. use Shopware\Core\Framework\Event\BeforeSendResponseEvent;
  13. use Shopware\Core\Framework\Plugin\KernelPluginLoader\DbalKernelPluginLoader;
  14. use Shopware\Core\Framework\Plugin\KernelPluginLoader\KernelPluginLoader;
  15. use Shopware\Core\Framework\Routing\CanonicalRedirectService;
  16. use Shopware\Core\Framework\Routing\RequestTransformerInterface;
  17. use Shopware\Core\Profiling\Doctrine\DebugStack;
  18. use Shopware\Storefront\Framework\Cache\CacheStore;
  19. use Symfony\Component\HttpFoundation\RedirectResponse;
  20. use Symfony\Component\HttpFoundation\Request;
  21. use Symfony\Component\HttpFoundation\Response;
  22. use Symfony\Component\HttpKernel\HttpCache\HttpCache;
  23. use Symfony\Component\HttpKernel\HttpKernelInterface;
  24. use Symfony\Component\HttpKernel\KernelInterface;
  25. use Symfony\Component\HttpKernel\TerminableInterface;
  26. class HttpKernel
  27. {
  28.     /**
  29.      * @var Connection|null
  30.      */
  31.     protected static $connection;
  32.     /**
  33.      * @var class-string<Kernel>
  34.      */
  35.     protected static $kernelClass Kernel::class;
  36.     /**
  37.      * @var ClassLoader|null
  38.      */
  39.     protected $classLoader;
  40.     /**
  41.      * @var string
  42.      */
  43.     protected $environment;
  44.     /**
  45.      * @var bool
  46.      */
  47.     protected $debug;
  48.     /**
  49.      * @var string
  50.      */
  51.     protected $projectDir;
  52.     /**
  53.      * @var KernelPluginLoader|null
  54.      */
  55.     protected $pluginLoader;
  56.     /**
  57.      * @var KernelInterface|null
  58.      */
  59.     protected $kernel;
  60.     public function __construct(string $environmentbool $debug, ?ClassLoader $classLoader null)
  61.     {
  62.         $this->classLoader $classLoader;
  63.         $this->environment $environment;
  64.         $this->debug $debug;
  65.     }
  66.     public function handle(Request $request$type HttpKernelInterface::MASTER_REQUEST$catch true): HttpKernelResult
  67.     {
  68.         try {
  69.             return $this->doHandle($request, (int) $type, (bool) $catch);
  70.         } catch (DBALException $e) {
  71.             $connectionParams self::getConnection()->getParams();
  72.             $message str_replace([$connectionParams['url'], $connectionParams['password'], $connectionParams['user']], '******'$e->getMessage());
  73.             throw new \RuntimeException(sprintf('Could not connect to database. Message from SQL Server: %s'$message));
  74.         }
  75.     }
  76.     public function getKernel(): KernelInterface
  77.     {
  78.         return $this->createKernel();
  79.     }
  80.     /**
  81.      * Allows to switch the plugin loading.
  82.      */
  83.     public function setPluginLoader(KernelPluginLoader $pluginLoader): void
  84.     {
  85.         $this->pluginLoader $pluginLoader;
  86.     }
  87.     public static function getConnection(): Connection
  88.     {
  89.         if (self::$connection) {
  90.             return self::$connection;
  91.         }
  92.         $url EnvironmentHelper::getVariable('DATABASE_URL'getenv('DATABASE_URL'));
  93.         if ($url === false) {
  94.             $url Kernel::PLACEHOLDER_DATABASE_URL;
  95.         }
  96.         $parameters = [
  97.             'url' => $url,
  98.             'charset' => 'utf8mb4',
  99.             'driverOptions' => [
  100.                 \PDO::ATTR_STRINGIFY_FETCHES => true,
  101.             ],
  102.         ];
  103.         if ($sslCa EnvironmentHelper::getVariable('DATABASE_SSL_CA')) {
  104.             $parameters['driverOptions'][\PDO::MYSQL_ATTR_SSL_CA] = $sslCa;
  105.         }
  106.         if ($sslCert EnvironmentHelper::getVariable('DATABASE_SSL_CERT')) {
  107.             $parameters['driverOptions'][\PDO::MYSQL_ATTR_SSL_CERT] = $sslCert;
  108.         }
  109.         if ($sslCertKey EnvironmentHelper::getVariable('DATABASE_SSL_KEY')) {
  110.             $parameters['driverOptions'][\PDO::MYSQL_ATTR_SSL_KEY] = $sslCertKey;
  111.         }
  112.         if (EnvironmentHelper::getVariable('DATABASE_SSL_DONT_VERIFY_SERVER_CERT')) {
  113.             $parameters['driverOptions'][\PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT] = false;
  114.         }
  115.         self::$connection DriverManager::getConnection($parameters, new Configuration());
  116.         return self::$connection;
  117.     }
  118.     public function terminate(Request $requestResponse $response): void
  119.     {
  120.         if (!$this->kernel instanceof TerminableInterface) {
  121.             return;
  122.         }
  123.         $this->kernel->terminate($request$response);
  124.     }
  125.     private function doHandle(Request $requestint $typebool $catch): HttpKernelResult
  126.     {
  127.         // create core kernel which contains bootstrapping for plugins etc.
  128.         $kernel $this->createKernel();
  129.         $kernel->boot();
  130.         $container $kernel->getContainer();
  131.         // transform request to resolve seo urls and detect sales channel
  132.         $transformed $container
  133.             ->get(RequestTransformerInterface::class)
  134.             ->transform($request);
  135.         $redirect $container
  136.             ->get(CanonicalRedirectService::class)
  137.             ->getRedirect($transformed);
  138.         if ($redirect instanceof RedirectResponse) {
  139.             $event = new BeforeSendRedirectResponseEvent($transformed$redirect);
  140.             $container->get('event_dispatcher')->dispatch($event);
  141.             return new HttpKernelResult($transformed$event->getResponse());
  142.         }
  143.         // check for http caching
  144.         $enabled $container->hasParameter('shopware.http.cache.enabled')
  145.             && $container->getParameter('shopware.http.cache.enabled');
  146.         if ($enabled && $container->has(CacheStore::class)) {
  147.             $kernel = new HttpCache($kernel$container->get(CacheStore::class), null, ['debug' => $this->debug]);
  148.         }
  149.         $response $kernel->handle($transformed$type$catch);
  150.         // fire event to trigger runtime events like seo url headers
  151.         $event = new BeforeSendResponseEvent($transformed$response);
  152.         $container->get('event_dispatcher')->dispatch($event);
  153.         return new HttpKernelResult($transformed$event->getResponse());
  154.     }
  155.     private function createKernel(): KernelInterface
  156.     {
  157.         if ($this->kernel !== null) {
  158.             return $this->kernel;
  159.         }
  160.         if (InstalledVersions::isInstalled('shopware/platform')) {
  161.             $shopwareVersion InstalledVersions::getVersion('shopware/platform')
  162.                 . '@' InstalledVersions::getReference('shopware/platform');
  163.         } else {
  164.             $shopwareVersion InstalledVersions::getVersion('shopware/core')
  165.                 . '@' InstalledVersions::getReference('shopware/core');
  166.         }
  167.         $connection self::getConnection();
  168.         if ($this->environment !== 'prod') {
  169.             $connection->getConfiguration()->setSQLLogger(new DebugStack());
  170.         }
  171.         $pluginLoader $this->createPluginLoader($connection);
  172.         $cacheId = (new CacheIdLoader($connection))->load();
  173.         return $this->kernel = new static::$kernelClass(
  174.             $this->environment,
  175.             $this->debug,
  176.             $pluginLoader,
  177.             $cacheId,
  178.             $shopwareVersion,
  179.             $connection,
  180.             $this->getProjectDir()
  181.         );
  182.     }
  183.     private function getProjectDir()
  184.     {
  185.         if ($this->projectDir === null) {
  186.             if ($dir $_ENV['PROJECT_ROOT'] ?? $_SERVER['PROJECT_ROOT'] ?? false) {
  187.                 return $this->projectDir $dir;
  188.             }
  189.             $r = new \ReflectionObject($this);
  190.             if (!file_exists($dir $r->getFileName())) {
  191.                 throw new \LogicException(sprintf('Cannot auto-detect project dir for kernel of class "%s".'$r->name));
  192.             }
  193.             $dir $rootDir \dirname($dir);
  194.             while (!file_exists($dir '/vendor')) {
  195.                 if ($dir === \dirname($dir)) {
  196.                     return $this->projectDir $rootDir;
  197.                 }
  198.                 $dir \dirname($dir);
  199.             }
  200.             $this->projectDir $dir;
  201.         }
  202.         return $this->projectDir;
  203.     }
  204.     private function createPluginLoader(Connection $connection): KernelPluginLoader
  205.     {
  206.         if ($this->pluginLoader) {
  207.             return $this->pluginLoader;
  208.         }
  209.         if (!$this->classLoader) {
  210.             throw new \RuntimeException('No plugin loader and no class loader provided');
  211.         }
  212.         $this->pluginLoader = new DbalKernelPluginLoader($this->classLoadernull$connection);
  213.         return $this->pluginLoader;
  214.     }
  215. }