vendor/shopware/core/HttpKernel.php line 149

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