vendor/shopware/core/HttpKernel.php line 68

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