src/Eccube/Kernel.php line 120

Open in your IDE?
  1. <?php
  2. /*
  3.  * This file is part of EC-CUBE
  4.  *
  5.  * Copyright(c) EC-CUBE CO.,LTD. All Rights Reserved.
  6.  *
  7.  * http://www.ec-cube.co.jp/
  8.  *
  9.  * For the full copyright and license information, please view the LICENSE
  10.  * file that was distributed with this source code.
  11.  */
  12. namespace Eccube;
  13. use Doctrine\Bundle\DoctrineBundle\DependencyInjection\Compiler\DoctrineOrmMappingsPass;
  14. use Eccube\Common\EccubeNav;
  15. use Eccube\Common\EccubeTwigBlock;
  16. use Eccube\DependencyInjection\Compiler\AutoConfigurationTagPass;
  17. use Eccube\DependencyInjection\Compiler\NavCompilerPass;
  18. use Eccube\DependencyInjection\Compiler\PaymentMethodPass;
  19. use Eccube\DependencyInjection\Compiler\PluginPass;
  20. use Eccube\DependencyInjection\Compiler\PurchaseFlowPass;
  21. use Eccube\DependencyInjection\Compiler\QueryCustomizerPass;
  22. use Eccube\DependencyInjection\Compiler\TwigBlockPass;
  23. use Eccube\DependencyInjection\Compiler\TwigExtensionPass;
  24. use Eccube\DependencyInjection\Compiler\WebServerDocumentRootPass;
  25. use Eccube\DependencyInjection\EccubeExtension;
  26. use Eccube\DependencyInjection\Facade\AnnotationReaderFacade;
  27. use Eccube\DependencyInjection\Facade\LoggerFacade;
  28. use Eccube\DependencyInjection\Facade\TranslatorFacade;
  29. use Eccube\Doctrine\DBAL\Types\UTCDateTimeType;
  30. use Eccube\Doctrine\DBAL\Types\UTCDateTimeTzType;
  31. use Eccube\Doctrine\ORM\Mapping\Driver\AnnotationDriver;
  32. use Eccube\Doctrine\Query\QueryCustomizer;
  33. use Eccube\Service\Payment\PaymentMethodInterface;
  34. use Eccube\Service\PurchaseFlow\DiscountProcessor;
  35. use Eccube\Service\PurchaseFlow\ItemHolderPostValidator;
  36. use Eccube\Service\PurchaseFlow\ItemHolderPreprocessor;
  37. use Eccube\Service\PurchaseFlow\ItemHolderValidator;
  38. use Eccube\Service\PurchaseFlow\ItemPreprocessor;
  39. use Eccube\Service\PurchaseFlow\ItemValidator;
  40. use Eccube\Service\PurchaseFlow\PurchaseProcessor;
  41. use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait;
  42. use Symfony\Component\Config\Loader\LoaderInterface;
  43. use Symfony\Component\DependencyInjection\Compiler\PassConfig;
  44. use Symfony\Component\DependencyInjection\ContainerBuilder;
  45. use Symfony\Component\DependencyInjection\Definition;
  46. use Symfony\Component\DependencyInjection\Reference;
  47. use Symfony\Component\Finder\Finder;
  48. use Symfony\Component\HttpKernel\Kernel as BaseKernel;
  49. use Symfony\Component\Routing\Loader\Configurator\RoutingConfigurator;
  50. use Symfony\Component\Routing\RouteCollectionBuilder;
  51. class Kernel extends BaseKernel
  52. {
  53.     use MicroKernelTrait;
  54.     public const CONFIG_EXTS '.{php,xml,yaml,yml}';
  55.     public function __construct(string $environmentbool $debug)
  56.     {
  57.         parent::__construct($environment$debug);
  58.         $this->loadEntityProxies();
  59.     }
  60.     public function getCacheDir()
  61.     {
  62.         return $this->getProjectDir().'/var/cache/'.$this->environment;
  63.         // return $this->getParameter('project_root').'/var/cache/'.$this->environment;
  64.     }
  65.     public function getLogDir()
  66.     {
  67.         return $this->getProjectDir().'/var/log';
  68.         // return $this->getParameter('project_root').'/var/log';
  69.     }
  70.     public function registerBundles()
  71.     {
  72.         $contents = require $this->getProjectDir().'/app/config/eccube/bundles.php';
  73.         // $contents = require dirname(__DIR__, 2).'/app/config/eccube/bundles.php';
  74.         // $contents = require getParameter('project_root').'/app/config/eccube/bundles.php';
  75.         foreach ($contents as $class => $envs) {
  76.             if (isset($envs['all']) || isset($envs[$this->environment])) {
  77.                 yield new $class();
  78.             }
  79.         }
  80.         $pluginDir $this->getProjectDir().'/app/Plugin';
  81.         // $pluginDir = dirname(__DIR__, 2).'/app/Plugin';
  82.         $finder = (new Finder())
  83.             ->in($pluginDir)
  84.             ->sortByName()
  85.             ->depth(0)
  86.             ->directories();
  87.         $plugins array_map(function ($dir) {
  88.             return $dir->getBaseName();
  89.         }, iterator_to_array($finder));
  90.         foreach ($plugins as $code) {
  91.             $pluginBundles $pluginDir.'/'.$code.'/Resource/config/bundles.php';
  92.             if (file_exists($pluginBundles)) {
  93.                 $contents = require $pluginBundles;
  94.                 foreach ($contents as $class => $envs) {
  95.                     if (isset($envs['all']) || isset($envs[$this->environment])) {
  96.                         yield new $class();
  97.                     }
  98.                 }
  99.             }
  100.         }
  101.     }
  102.     /**
  103.      * {@inheritdoc}
  104.      *
  105.      * @see \Symfony\Component\HttpKernel\Kernel::boot()
  106.      */
  107.     public function boot()
  108.     {
  109.         // Symfonyがsrc/Eccube/Entity以下を読み込む前にapp/proxy/entity以下をロードする
  110.         // $this->loadEntityProxies();
  111.         parent::boot();
  112.         $container $this->getContainer();
  113.         // DateTime/DateTimeTzのタイムゾーンを設定.
  114.         $timezone $container->getParameter('timezone');
  115.         UTCDateTimeType::setTimeZone($timezone);
  116.         UTCDateTimeTzType::setTimeZone($timezone);
  117.         date_default_timezone_set($timezone);
  118.         $Logger $container->get('eccube.logger');
  119.         if ($Logger !== null && $Logger instanceof \Eccube\Log\Logger) {
  120.             LoggerFacade::init($container$Logger);
  121.         }
  122.         $Translator $container->get('translator');
  123.         if ($Translator !== null && $Translator instanceof \Symfony\Contracts\Translation\TranslatorInterface) {
  124.             TranslatorFacade::init($Translator);
  125.         }
  126.         /** @var AnnotationReaderFacade $AnnotationReaderFacade */
  127.         $AnnotationReaderFacade $container->get(AnnotationReaderFacade::class);
  128.         $AnnotationReader $AnnotationReaderFacade->getAnnotationReader();
  129.         if ($AnnotationReader !== null && $AnnotationReader instanceof \Doctrine\Common\Annotations\Reader) {
  130.             AnnotationReaderFacade::init($AnnotationReader);
  131.         }
  132.     }
  133.     protected function configureContainer(ContainerBuilder $containerLoaderInterface $loader)
  134.     {
  135.         $confDir $this->getProjectDir().'/app/config/eccube';
  136.         // $confDir = dirname(__DIR__, 2).'/app/config/eccube';
  137.         $loader->load($confDir.'/services'.self::CONFIG_EXTS'glob');
  138.         $loader->load($confDir.'/packages/*'.self::CONFIG_EXTS'glob');
  139.         if (is_dir($confDir.'/packages/'.$this->environment)) {
  140.             $loader->load($confDir.'/packages/'.$this->environment.'/**/*'.self::CONFIG_EXTS'glob');
  141.         }
  142.         $loader->load($confDir.'/services_'.$this->environment.self::CONFIG_EXTS'glob');
  143.         // プラグインのservices.phpをロードする.
  144.         $dir dirname(__DIR__).'/../app/Plugin/*/Resource/config';
  145.         $loader->load($dir.'/services'.self::CONFIG_EXTS'glob');
  146.         $loader->load($dir.'/services_'.$this->environment.self::CONFIG_EXTS'glob');
  147.         // カスタマイズディレクトリのservices.phpをロードする.
  148.         $dir dirname(__DIR__).'/../app/Customize/Resource/config';
  149.         $loader->load($dir.'/services'.self::CONFIG_EXTS'glob');
  150.         $loader->load($dir.'/services_'.$this->environment.self::CONFIG_EXTS'glob');
  151.     }
  152.     protected function configureRoutes(RouteCollectionBuilder $routes)
  153.     {
  154.         $container $this->getContainer();
  155.         $scheme = ['https''http'];
  156.         $forceSSL $container->getParameter('eccube_force_ssl');
  157.         if ($forceSSL) {
  158.             $scheme 'https';
  159.         }
  160.         $routes->setSchemes($scheme);
  161.         $confDir $this->getProjectDir().'/app/config/eccube';
  162.         // $confDir = dirname(__DIR__, 2).'/app/config/eccube';
  163.         if (is_dir($confDir.'/routes/')) {
  164.             $builder $routes->import($confDir.'/routes/*'.self::CONFIG_EXTS'/''glob');
  165.             $builder->setSchemes($scheme);
  166.         }
  167.         if (is_dir($confDir.'/routes/'.$this->environment)) {
  168.             $builder $routes->import($confDir.'/routes/'.$this->environment.'/**/*'.self::CONFIG_EXTS'/''glob');
  169.             $builder->setSchemes($scheme);
  170.         }
  171.         //20240220 https://techmemo.biz/ec-cube/user_data-url-delete-change/
  172.         //プラグイン側を優先とする
  173.         
  174.         $builder $routes->import($confDir.'/routes'.self::CONFIG_EXTS'/''glob');
  175.         $builder->setSchemes($scheme);
  176.         $builder $routes->import($confDir.'/routes_'.$this->environment.self::CONFIG_EXTS'/''glob');
  177.         $builder->setSchemes($scheme);
  178.         // 有効なプラグインのルーティングをインポートする.
  179.         $plugins $container->getParameter('eccube.plugins.enabled');
  180.         $pluginDir $this->getProjectDir().'/app/Plugin';
  181.         // $pluginDir = dirname(__DIR__, 2).'/app/Plugin';
  182.         foreach ($plugins as $plugin) {
  183.             $dir $pluginDir.'/'.$plugin.'/Controller';
  184.             if (file_exists($dir)) {
  185.                 $builder $routes->import($dir'/''annotation');
  186.                 $builder->setSchemes($scheme);
  187.             }
  188.             if (file_exists($pluginDir.'/'.$plugin.'/Resource/config')) {
  189.                 $builder $routes->import($pluginDir.'/'.$plugin.'/Resource/config/routes'.self::CONFIG_EXTS'/''glob');
  190.                 $builder->setSchemes($scheme);
  191.             }
  192.         }
  193.         // $builder = $routes->import($confDir.'/routes'.self::CONFIG_EXTS, '/', 'glob');
  194.         // $builder->setSchemes($scheme);
  195.         // $builder = $routes->import($confDir.'/routes_'.$this->environment.self::CONFIG_EXTS, '/', 'glob');
  196.         // $builder->setSchemes($scheme);
  197.     }
  198.     protected function build(ContainerBuilder $container)
  199.     {
  200.         $this->addEntityExtensionPass($container);
  201.         $container->registerExtension(new EccubeExtension());
  202.         // サービスタグの自動設定を行う
  203.         $container->addCompilerPass(new AutoConfigurationTagPass(), PassConfig::TYPE_BEFORE_OPTIMIZATION11);
  204.         // サービスタグの収集より先に実行し, 付与されているタグをクリアする.
  205.         // FormPassは優先度0で実行されているので, それより速いタイミングで実行させる.
  206.         // 自動登録されるタグやコンパイラパスの登録タイミングは, FrameworkExtension::load(), FrameworkBundle::build()を参考に.
  207.         $container->addCompilerPass(new PluginPass(), PassConfig::TYPE_BEFORE_OPTIMIZATION10);
  208.         // DocumentRootをルーティディレクトリに設定する.
  209.         $container->addCompilerPass(new WebServerDocumentRootPass('%kernel.project_dir%/'));
  210.         // twigのurl,path関数を差し替え
  211.         $container->addCompilerPass(new TwigExtensionPass());
  212.         // クエリカスタマイズの拡張.
  213.         $container->registerForAutoconfiguration(QueryCustomizer::class)
  214.             ->addTag(QueryCustomizerPass::QUERY_CUSTOMIZER_TAG);
  215.         $container->addCompilerPass(new QueryCustomizerPass());
  216.         // 管理画面ナビの拡張
  217.         $container->registerForAutoconfiguration(EccubeNav::class)
  218.             ->addTag(NavCompilerPass::NAV_TAG);
  219.         $container->addCompilerPass(new NavCompilerPass());
  220.         // TwigBlockの拡張
  221.         $container->registerForAutoconfiguration(EccubeTwigBlock::class)
  222.             ->addTag(TwigBlockPass::TWIG_BLOCK_TAG);
  223.         $container->addCompilerPass(new TwigBlockPass());
  224.         // PaymentMethod の拡張
  225.         $container->registerForAutoconfiguration(PaymentMethodInterface::class)
  226.             ->addTag(PaymentMethodPass::PAYMENT_METHOD_TAG);
  227.         $container->addCompilerPass(new PaymentMethodPass());
  228.         // PurchaseFlow の拡張
  229.         $container->registerForAutoconfiguration(ItemPreprocessor::class)
  230.             ->addTag(PurchaseFlowPass::ITEM_PREPROCESSOR_TAG);
  231.         $container->registerForAutoconfiguration(ItemValidator::class)
  232.             ->addTag(PurchaseFlowPass::ITEM_VALIDATOR_TAG);
  233.         $container->registerForAutoconfiguration(ItemHolderPreprocessor::class)
  234.             ->addTag(PurchaseFlowPass::ITEM_HOLDER_PREPROCESSOR_TAG);
  235.         $container->registerForAutoconfiguration(ItemHolderValidator::class)
  236.             ->addTag(PurchaseFlowPass::ITEM_HOLDER_VALIDATOR_TAG);
  237.         $container->registerForAutoconfiguration(ItemHolderPostValidator::class)
  238.             ->addTag(PurchaseFlowPass::ITEM_HOLDER_POST_VALIDATOR_TAG);
  239.         $container->registerForAutoconfiguration(DiscountProcessor::class)
  240.             ->addTag(PurchaseFlowPass::DISCOUNT_PROCESSOR_TAG);
  241.         $container->registerForAutoconfiguration(PurchaseProcessor::class)
  242.             ->addTag(PurchaseFlowPass::PURCHASE_PROCESSOR_TAG);
  243.         $container->addCompilerPass(new PurchaseFlowPass());
  244.     }
  245.     protected function addEntityExtensionPass(ContainerBuilder $container)
  246.     {
  247.         $projectDir $container->getParameter('kernel.project_dir');
  248.         // Eccube
  249.         $paths = ['%kernel.project_dir%/src/Eccube/Entity'];
  250.         $namespaces = ['Eccube\\Entity'];
  251.         $reader = new Reference('annotation_reader');
  252.         $driver = new Definition(AnnotationDriver::class, [$reader$paths]);
  253.         $driver->addMethodCall('setTraitProxiesDirectory', [$projectDir.'/app/proxy/entity']);
  254.         $container->addCompilerPass(new DoctrineOrmMappingsPass($driver$namespaces, []));
  255.         // Customize
  256.         $container->addCompilerPass(DoctrineOrmMappingsPass::createAnnotationMappingDriver(
  257.             ['Customize\\Entity'],
  258.             ['%kernel.project_dir%/app/Customize/Entity']
  259.         ));
  260.         // Plugin
  261.         $pluginDir $projectDir.'/app/Plugin';
  262.         // $pluginDir = dirname(__DIR__, 2).'/app/Plugin';
  263.         $finder = (new Finder())
  264.             ->in($pluginDir)
  265.             ->sortByName()
  266.             ->depth(0)
  267.             ->directories();
  268.         $plugins array_map(function ($dir) {
  269.             return $dir->getBaseName();
  270.         }, iterator_to_array($finder));
  271.         foreach ($plugins as $code) {
  272.             if (file_exists($pluginDir.'/'.$code.'/Entity')) {
  273.                 $paths = ['%kernel.project_dir%/app/Plugin/'.$code.'/Entity'];
  274.                 $namespaces = ['Plugin\\'.$code.'\\Entity'];
  275.                 $reader = new Reference('annotation_reader');
  276.                 $driver = new Definition(AnnotationDriver::class, [$reader$paths]);
  277.                 $driver->addMethodCall('setTraitProxiesDirectory', [$projectDir.'/app/proxy/entity']);
  278.                 $container->addCompilerPass(new DoctrineOrmMappingsPass($driver$namespaces, []));
  279.             }
  280.         }
  281.     }
  282.     protected function loadEntityProxies()
  283.     {
  284.         // see https://github.com/EC-CUBE/ec-cube/issues/4727
  285.         // キャッシュクリアなど、コード内でコマンドを利用している場合に2回実行されてしまう
  286.         if (true === $this->booted) {
  287.             return;
  288.         }
  289.         $files Finder::create()
  290.             ->in(__DIR__.'/../../app/proxy/entity/')
  291.             ->name('*.php')
  292.             ->files();
  293.         foreach ($files as $file) {
  294.             require_once $file->getRealPath();
  295.         }
  296.     }
  297. }