Failed Conditions
Pull Request — 4.0 (#4409)
by Kentaro
05:58
created

Kernel::boot()   B

Complexity

Conditions 8
Paths 16

Size

Total Lines 39

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 23
CRAP Score 8

Importance

Changes 0
Metric Value
cc 8
nc 16
nop 0
dl 0
loc 39
rs 8.0515
c 0
b 0
f 0
ccs 23
cts 23
cp 1
crap 8
1
<?php
2
3
/*
4
 * This file is part of EC-CUBE
5
 *
6
 * Copyright(c) EC-CUBE CO.,LTD. All Rights Reserved.
7
 *
8
 * http://www.ec-cube.co.jp/
9
 *
10
 * For the full copyright and license information, please view the LICENSE
11
 * file that was distributed with this source code.
12
 */
13
14
namespace Eccube;
15
16
use Doctrine\Bundle\DoctrineBundle\DependencyInjection\Compiler\DoctrineOrmMappingsPass;
17
use Eccube\Common\EccubeNav;
18
use Eccube\Common\EccubeTwigBlock;
19
use Eccube\DependencyInjection\Compiler\AutoConfigurationTagPass;
20
use Eccube\DependencyInjection\Compiler\NavCompilerPass;
21
use Eccube\DependencyInjection\Compiler\PaymentMethodPass;
22
use Eccube\DependencyInjection\Compiler\PluginPass;
23
use Eccube\DependencyInjection\Compiler\PurchaseFlowPass;
24
use Eccube\DependencyInjection\Compiler\QueryCustomizerPass;
25
use Eccube\DependencyInjection\Compiler\TwigBlockPass;
26
use Eccube\DependencyInjection\Compiler\TwigExtensionPass;
27
use Eccube\DependencyInjection\Compiler\WebServerDocumentRootPass;
28
use Eccube\DependencyInjection\EccubeExtension;
29
use Eccube\DependencyInjection\Facade\AnnotationReaderFacade;
30
use Eccube\DependencyInjection\Facade\LoggerFacade;
31
use Eccube\DependencyInjection\Facade\TranslatorFacade;
32
use Eccube\Doctrine\DBAL\Types\UTCDateTimeType;
33
use Eccube\Doctrine\DBAL\Types\UTCDateTimeTzType;
34
use Eccube\Doctrine\ORM\Mapping\Driver\AnnotationDriver;
35
use Eccube\Doctrine\Query\QueryCustomizer;
36
use Eccube\Service\Payment\PaymentMethodInterface;
37
use Eccube\Service\PurchaseFlow\DiscountProcessor;
38
use Eccube\Service\PurchaseFlow\ItemHolderPostValidator;
39
use Eccube\Service\PurchaseFlow\ItemHolderPreprocessor;
40
use Eccube\Service\PurchaseFlow\ItemHolderValidator;
41
use Eccube\Service\PurchaseFlow\ItemPreprocessor;
42
use Eccube\Service\PurchaseFlow\ItemValidator;
43
use Eccube\Service\PurchaseFlow\PurchaseProcessor;
44
use Eccube\Validator\EmailValidator\NoRFCEmailValidator;
45
use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait;
46
use Symfony\Component\Config\Loader\LoaderInterface;
47
use Symfony\Component\DependencyInjection\Compiler\PassConfig;
48
use Symfony\Component\DependencyInjection\ContainerBuilder;
49
use Symfony\Component\DependencyInjection\Definition;
50
use Symfony\Component\DependencyInjection\Reference;
51
use Symfony\Component\Finder\Finder;
52
use Symfony\Component\HttpKernel\Kernel as BaseKernel;
53
use Symfony\Component\Routing\RouteCollectionBuilder;
54
55
class Kernel extends BaseKernel
56 1332
{
57
    use MicroKernelTrait;
58 1332
59
    const CONFIG_EXTS = '.{php,xml,yaml,yml}';
60
61 13
    public function getCacheDir()
62
    {
63 13
        return $this->getProjectDir().'/var/cache/'.$this->environment;
64
    }
65
66 1332
    public function getLogDir()
67
    {
68 1332
        return $this->getProjectDir().'/var/log';
69 1332
    }
70 1332
71 1332
    public function registerBundles()
72
    {
73
        $contents = require $this->getProjectDir().'/app/config/eccube/bundles.php';
74
        foreach ($contents as $class => $envs) {
75
            if (isset($envs['all']) || isset($envs[$this->environment])) {
76
                yield new $class();
77
            }
78
        }
79
    }
80
81 1332
    /**
82
     * {@inheritdoc}
83
     *
84 1332
     * @see \Symfony\Component\HttpKernel\Kernel::boot()
85
     */
86 1332
    public function boot()
87
    {
88
        // Symfonyがsrc/Eccube/Entity以下を読み込む前にapp/proxy/entity以下をロードする
89 1332
        $this->loadEntityProxies();
90 1332
91 1332
        parent::boot();
92
93
        $container = $this->getContainer();
94 1332
95 1332
        // DateTime/DateTimeTzのタイムゾーンを設定.
96 1332
        $timezone = $container->getParameter('timezone');
97 1332
        UTCDateTimeType::setTimeZone($timezone);
98
        UTCDateTimeTzType::setTimeZone($timezone);
99 1332
        date_default_timezone_set($timezone);
100
101
        // RFC違反のメールを送信できるよう独自のValidationを設定
102 1
        if (!$container->getParameter('eccube_rfc_email_check')) {
103
            // RFC違反のメールを許容する
104 1
            \Swift_DependencyContainer::getInstance()
105 1
                ->register('email.validator')
106 1
                ->asSharedInstanceOf(NoRFCEmailValidator::class);
107 1
        }
108
109 1
        $Logger = $container->get('eccube.logger');
110 1
        if ($Logger !== null && $Logger instanceof \Eccube\Log\Logger) {
111
            LoggerFacade::init($container, $Logger);
0 ignored issues
show
Bug introduced by
It seems like $container defined by $this->getContainer() on line 93 can be null; however, Eccube\DependencyInjecti...de\LoggerFacade::init() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
112
        }
113 1
        $Translator = $container->get('translator');
114 1
        if ($Translator !== null && $Translator instanceof \Symfony\Component\Translation\TranslatorInterface) {
115
            TranslatorFacade::init($container, $Translator);
0 ignored issues
show
Bug introduced by
It seems like $container defined by $this->getContainer() on line 93 can be null; however, Eccube\DependencyInjecti...ranslatorFacade::init() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
116
        }
117 57
118
        /** @var AnnotationReaderFacade $AnnotationReaderFacade */
119 57
        $AnnotationReaderFacade = $container->get(AnnotationReaderFacade::class);
120
        $AnnotationReader = $AnnotationReaderFacade->getAnnotationReader();
121 57
        if ($AnnotationReader !== null && $AnnotationReader instanceof \Doctrine\Common\Annotations\Reader) {
122 57
            AnnotationReaderFacade::init($container, $AnnotationReader);
0 ignored issues
show
Bug introduced by
It seems like $container defined by $this->getContainer() on line 93 can be null; however, Eccube\DependencyInjecti...ionReaderFacade::init() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
123 57
        }
124
    }
125 57
126 57
    protected function configureContainer(ContainerBuilder $container, LoaderInterface $loader)
0 ignored issues
show
Unused Code introduced by
The parameter $container is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
127 57
    {
128 57
        $confDir = $this->getProjectDir().'/app/config/eccube';
129
        $loader->load($confDir.'/services'.self::CONFIG_EXTS, 'glob');
130 57
        $loader->load($confDir.'/packages/*'.self::CONFIG_EXTS, 'glob');
131
        if (is_dir($confDir.'/packages/'.$this->environment)) {
132
            $loader->load($confDir.'/packages/'.$this->environment.'/**/*'.self::CONFIG_EXTS, 'glob');
133
        }
134 57
        $loader->load($confDir.'/services_'.$this->environment.self::CONFIG_EXTS, 'glob');
135 57
136 57
        // プラグインのservices.phpをロードする.
137 57
        $dir = dirname(__DIR__).'/../app/Plugin/*/Resource/config';
138
        $loader->load($dir.'/services'.self::CONFIG_EXTS, 'glob');
139
        $loader->load($dir.'/services_'.$this->environment.self::CONFIG_EXTS, 'glob');
140 57
141 57
        // カスタマイズディレクトリのservices.phpをロードする.
142 57
        $dir = dirname(__DIR__).'/../app/Customize/Resource/config';
143
        $loader->load($dir.'/services'.self::CONFIG_EXTS, 'glob');
144
        $loader->load($dir.'/services_'.$this->environment.self::CONFIG_EXTS, 'glob');
145
    }
146
147
    protected function configureRoutes(RouteCollectionBuilder $routes)
148
    {
149
        $container = $this->getContainer();
150
151 1
        $scheme = ['https', 'http'];
152
        $forceSSL = $container->getParameter('eccube_force_ssl');
153 1
        if ($forceSSL) {
154
            $scheme = 'https';
155 1
        }
156
        $routes->setSchemes($scheme);
157
158 1
        $confDir = $this->getProjectDir().'/app/config/eccube';
159
        if (is_dir($confDir.'/routes/')) {
160
            $builder = $routes->import($confDir.'/routes/*'.self::CONFIG_EXTS, '/', 'glob');
161
            $builder->setSchemes($scheme);
162
        }
163 1
        if (is_dir($confDir.'/routes/'.$this->environment)) {
164
            $builder = $routes->import($confDir.'/routes/'.$this->environment.'/**/*'.self::CONFIG_EXTS, '/', 'glob');
165
            $builder->setSchemes($scheme);
166 1
        }
167
        $builder = $routes->import($confDir.'/routes'.self::CONFIG_EXTS, '/', 'glob');
168 1
        $builder->setSchemes($scheme);
169
        $builder = $routes->import($confDir.'/routes_'.$this->environment.self::CONFIG_EXTS, '/', 'glob');
170 1
        $builder->setSchemes($scheme);
171
172
        // 有効なプラグインのルーティングをインポートする.
173
        $plugins = $container->getParameter('eccube.plugins.enabled');
174 1
        $pluginDir = $this->getProjectDir().'/app/Plugin';
175
        foreach ($plugins as $plugin) {
176 1
            $dir = $pluginDir.'/'.$plugin.'/Controller';
177 1
            if (file_exists($dir)) {
178 1
                $builder = $routes->import($dir, '/', 'annotation');
179
                $builder->setSchemes($scheme);
180
            }
181 1
        }
182 1
    }
183 1
184
    protected function build(ContainerBuilder $container)
185
    {
186 1
        $this->addEntityExtensionPass($container);
187 1
188 1
        $container->registerExtension(new EccubeExtension());
189
190
        // サービスタグの自動設定を行う
191 1
        $container->addCompilerPass(new AutoConfigurationTagPass(), PassConfig::TYPE_BEFORE_OPTIMIZATION, 11);
192 1
193 1
        // サービスタグの収集より先に実行し, 付与されているタグをクリアする.
194
        // FormPassは優先度0で実行されているので, それより速いタイミングで実行させる.
195
        // 自動登録されるタグやコンパイラパスの登録タイミングは, FrameworkExtension::load(), FrameworkBundle::build()を参考に.
196 1
        $container->addCompilerPass(new PluginPass(), PassConfig::TYPE_BEFORE_OPTIMIZATION, 10);
197 1
198 1
        // DocumentRootをルーティディレクトリに設定する.
199
        $container->addCompilerPass(new WebServerDocumentRootPass('%kernel.project_dir%/'));
200
201 1
202 1
        // twigのurl,path関数を差し替え
203 1
        $container->addCompilerPass(new TwigExtensionPass());
204 1
205 1
        $container->register('app', Application::class)
206 1
            ->setSynthetic(true)
207 1
            ->setPublic(true);
208 1
209 1
        // クエリカスタマイズの拡張.
210 1
        $container->registerForAutoconfiguration(QueryCustomizer::class)
211 1
            ->addTag(QueryCustomizerPass::QUERY_CUSTOMIZER_TAG);
212
        $container->addCompilerPass(new QueryCustomizerPass());
213
214 1
        // 管理画面ナビの拡張
215
        $container->registerForAutoconfiguration(EccubeNav::class)
216 1
            ->addTag(NavCompilerPass::NAV_TAG);
217
        $container->addCompilerPass(new NavCompilerPass());
218
219 1
        // TwigBlockの拡張
220 1
        $container->registerForAutoconfiguration(EccubeTwigBlock::class)
221 1
            ->addTag(TwigBlockPass::TWIG_BLOCK_TAG);
222 1
        $container->addCompilerPass(new TwigBlockPass());
223 1
224 1
        // PaymentMethod の拡張
225
        $container->registerForAutoconfiguration(PaymentMethodInterface::class)
226
            ->addTag(PaymentMethodPass::PAYMENT_METHOD_TAG);
227 1
        $container->addCompilerPass(new PaymentMethodPass());
228 1
229 1
        // PurchaseFlow の拡張
230
        $container->registerForAutoconfiguration(ItemPreprocessor::class)
231
            ->addTag(PurchaseFlowPass::ITEM_PREPROCESSOR_TAG);
232
        $container->registerForAutoconfiguration(ItemValidator::class)
233 1
            ->addTag(PurchaseFlowPass::ITEM_VALIDATOR_TAG);
234 1
        $container->registerForAutoconfiguration(ItemHolderPreprocessor::class)
235 1
            ->addTag(PurchaseFlowPass::ITEM_HOLDER_PREPROCESSOR_TAG);
236 1
        $container->registerForAutoconfiguration(ItemHolderValidator::class)
237 1
            ->addTag(PurchaseFlowPass::ITEM_HOLDER_VALIDATOR_TAG);
238 1
        $container->registerForAutoconfiguration(ItemHolderPostValidator::class)
239 1
            ->addTag(PurchaseFlowPass::ITEM_HOLDER_POST_VALIDATOR_TAG);
240 1
        $container->registerForAutoconfiguration(DiscountProcessor::class)
241 1
            ->addTag(PurchaseFlowPass::DISCOUNT_PROCESSOR_TAG);
242
        $container->registerForAutoconfiguration(PurchaseProcessor::class)
243 1
            ->addTag(PurchaseFlowPass::PURCHASE_PROCESSOR_TAG);
244 1
        $container->addCompilerPass(new PurchaseFlowPass());
245 1
    }
246 1
247 1
    protected function addEntityExtensionPass(ContainerBuilder $container)
248
    {
249
        $projectDir = $container->getParameter('kernel.project_dir');
250
251
        // Eccube
252
        $paths = ['%kernel.project_dir%/src/Eccube/Entity'];
253 1332
        $namespaces = ['Eccube\\Entity'];
254
        $reader = new Reference('annotation_reader');
255 1332
        $driver = new Definition(AnnotationDriver::class, [$reader, $paths]);
256
        $driver->addMethodCall('setTraitProxiesDirectory', [$projectDir.'/app/proxy/entity']);
257
        $container->addCompilerPass(new DoctrineOrmMappingsPass($driver, $namespaces, []));
258
259
        // Customize
260
        $container->addCompilerPass(DoctrineOrmMappingsPass::createAnnotationMappingDriver(
261
            ['Customize\\Entity'],
262
            ['%kernel.project_dir%/app/Customize/Entity']
263
        ));
264
265
        // Plugin
266
        $pluginDir = $projectDir.'/app/Plugin';
267
        $finder = (new Finder())
268
            ->in($pluginDir)
269
            ->sortByName()
270
            ->depth(0)
271
            ->directories();
272
        $plugins = array_map(function ($dir) {
273
            return $dir->getBaseName();
274
        }, iterator_to_array($finder));
275
276
        foreach ($plugins as $code) {
277
            if (file_exists($pluginDir.'/'.$code.'/Entity')) {
278
                $container->addCompilerPass(DoctrineOrmMappingsPass::createAnnotationMappingDriver(
279
                    ['Plugin\\'.$code.'\\Entity'],
280
                    ['%kernel.project_dir%/app/Plugin/'.$code.'/Entity']
281
                ));
282
            }
283
        }
284
    }
285
286
    protected function loadEntityProxies()
287
    {
288
        $files = Finder::create()
289
            ->in(__DIR__.'/../../app/proxy/entity/')
290
            ->name('*.php')
291
            ->files();
292
        foreach ($files as $file) {
293
            require_once $file->getRealPath();
294
        }
295
    }
296
}
297