Failed Conditions
Pull Request — 3.0.9-dev (#1451)
by chihiro
138:07 queued 132:13
created

src/Eccube/Application.php (1 issue)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
/*
3
 * This file is part of EC-CUBE
4
 *
5
 * Copyright(c) 2000-2015 LOCKON CO.,LTD. All Rights Reserved.
6
 *
7
 * http://www.lockon.co.jp/
8
 *
9
 * This program is free software; you can redistribute it and/or
10
 * modify it under the terms of the GNU General Public License
11
 * as published by the Free Software Foundation; either version 2
12
 * of the License, or (at your option) any later version.
13
 *
14
 * This program is distributed in the hope that it will be useful,
15
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
 * GNU General Public License for more details.
18
 *
19
 * You should have received a copy of the GNU General Public License
20
 * along with this program; if not, write to the Free Software
21
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22
 */
23
24
namespace Eccube;
25
26
use Eccube\Application\ApplicationTrait;
27
use Eccube\Common\Constant;
28
use Monolog\Logger;
29
use Symfony\Component\EventDispatcher\EventDispatcher;
30
use Symfony\Component\Finder\Finder;
31
use Symfony\Component\HttpFoundation\Request;
32
use Symfony\Component\HttpFoundation\Response;
33
use Symfony\Component\Yaml\Yaml;
34
35
class Application extends ApplicationTrait
36
{
37
    protected static $instance;
38
39
    protected $initialized = false;
40
    protected $initializedPlugin = false;
41
42 419
    public static function getInstance(array $values = array())
43
    {
44
        if (!is_object(self::$instance)) {
45
            self::$instance = new Application($values);
46
        }
47
48 419
        return self::$instance;
49 419
    }
50
51 759
    public static function clearInstance()
52
    {
53 759
        self::$instance = null;
54 759
    }
55
56
    final public function __clone()
57
    {
58
        throw new \Exception('Clone is not allowed against '.get_class($this));
59
    }
60
61 759
    public function __construct(array $values = array())
62
    {
63
        parent::__construct($values);
64
65
        if (is_null(self::$instance)) {
66 759
            self::$instance = $this;
67
        }
68
69
        // load config
70
        $this->initConfig();
71
72
        // init monolog
73
        $this->initLogger();
74
    }
75
76 773
    public function initConfig()
77
    {
78
        // load config
79
        $this['config'] = $this->share(function() {
80 766
            $ymlPath = __DIR__.'/../../app/config/eccube';
81 766
            $distPath = __DIR__.'/../../src/Eccube/Resource/config';
82
83 766
            $config = array();
84 766
            $config_yml = $ymlPath.'/config.yml';
85
            if (file_exists($config_yml)) {
86
                $config = Yaml::parse(file_get_contents($config_yml));
87
            }
88
89 766
            $config_dist = array();
90 766
            $config_yml_dist = $distPath.'/config.yml.dist';
91
            if (file_exists($config_yml_dist)) {
92
                $config_dist = Yaml::parse(file_get_contents($config_yml_dist));
93
            }
94
95 766
            $config_path = array();
96 766
            $path_yml = $ymlPath.'/path.yml';
97
            if (file_exists($path_yml)) {
98
                $config_path = Yaml::parse(file_get_contents($path_yml));
99
            }
100
101 766
            $config_constant = array();
102 766
            $constant_yml = $ymlPath.'/constant.yml';
103
            if (file_exists($constant_yml)) {
104
                $config_constant = Yaml::parse(file_get_contents($constant_yml));
105
                $config_constant = empty($config_constant) ? array() : $config_constant;
106
            }
107
108 766
            $config_constant_dist = array();
109 766
            $constant_yml_dist = $distPath.'/constant.yml.dist';
110
            if (file_exists($constant_yml_dist)) {
111
                $config_constant_dist = Yaml::parse(file_get_contents($constant_yml_dist));
112
            }
113
114
            $configAll = array_replace_recursive($config_constant_dist, $config_dist, $config_constant, $config_path, $config);
115
116 766
            $database = array();
117 766
            $yml = $ymlPath.'/database.yml';
118
            if (file_exists($yml)) {
119
                $database = Yaml::parse(file_get_contents($yml));
120
            }
121
122 766
            $mail = array();
123 766
            $yml = $ymlPath.'/mail.yml';
124
            if (file_exists($yml)) {
125
                $mail = Yaml::parse(file_get_contents($yml));
126
            }
127
            $configAll = array_replace_recursive($configAll, $database, $mail);
128
129 766
            $config_log = array();
130 766
            $yml = $ymlPath.'/log.yml';
131
            if (file_exists($yml)) {
132
                $config_log = Yaml::parse(file_get_contents($yml));
133
            }
134 766
            $config_log_dist = array();
135 766
            $log_yml_dist = $distPath.'/log.yml.dist';
136
            if (file_exists($log_yml_dist)) {
137
                $config_log_dist = Yaml::parse(file_get_contents($log_yml_dist));
138
            }
139
140
            $configAll = array_replace_recursive($configAll, $config_log_dist, $config_log);
141
142 766
            $config_nav = array();
143 766
            $yml = $ymlPath.'/nav.yml';
144
            if (file_exists($yml)) {
145
                $config_nav = array('nav' => Yaml::parse(file_get_contents($yml)));
146
            }
147 766
            $config_nav_dist = array();
148 766
            $nav_yml_dist = $distPath.'/nav.yml.dist';
149
            if (file_exists($nav_yml_dist)) {
150
                $config_nav_dist = array('nav' => Yaml::parse(file_get_contents($nav_yml_dist)));
151
            }
152
153
            $configAll = array_replace_recursive($configAll, $config_nav_dist, $config_nav);
154
155 766
            return $configAll;
156
        });
157 773
    }
158
159 773
    public function initLogger()
160
    {
161 773
        $app = $this;
162
        $this->register(new ServiceProvider\EccubeMonologServiceProvider($app));
163
        $this['monolog.logfile'] = __DIR__.'/../../app/log/site.log';
164
        $this['monolog.name'] = 'eccube';
165 773
    }
166
167 763
    public function initialize()
168
    {
169 763
        if ($this->initialized) {
170
            return;
171
        }
172
173
        // init locale
174
        $this->initLocale();
175
176
        // init session
177
        $this->initSession();
178
179
        // init twig
180
        $this->initRendering();
181
182
        // init provider
183
        $this->register(new \Silex\Provider\HttpFragmentServiceProvider());
184
        $this->register(new \Silex\Provider\UrlGeneratorServiceProvider());
185
        $this->register(new \Silex\Provider\FormServiceProvider());
186
        $this->register(new \Silex\Provider\SerializerServiceProvider());
187
        $this->register(new \Eccube\ServiceProvider\ValidatorServiceProvider());
188
189 763
        $app = $this;
190
        $this->error(function(\Exception $e, $code) use ($app) {
191
            if ($app['debug']) {
192 6
                return;
193
            }
194
195
            switch ($code) {
196
                case 403:
197
                    $title = 'アクセスできません。';
198
                    $message = 'お探しのページはアクセスができない状況にあるか、移動もしくは削除された可能性があります。';
199
                    break;
200
                case 404:
201
                    $title = 'ページがみつかりません。';
202
                    $message = 'URLに間違いがないかご確認ください。';
203
                    break;
204
                default:
205
                    $title = 'システムエラーが発生しました。';
206
                    $message = '大変お手数ですが、サイト管理者までご連絡ください。';
207
                    break;
208
            }
209
210
            return $app->render('error.twig', array(
211
                'error_title' => $title,
212
                'error_message' => $message,
213
            ));
214
        });
215
216
        // init mailer
217
        $this->initMailer();
218
219
        // init doctrine orm
220
        $this->initDoctrine();
221
222
        // Set up the DBAL connection now to check for a proper connection to the database.
223
        $this->checkDatabaseConnection();
224
225
        // init security
226
        $this->initSecurity();
227
228
        // init ec-cube service provider
229
        $this->register(new ServiceProvider\EccubeServiceProvider());
230
231
        // mount controllers
232
        $this->register(new \Silex\Provider\ServiceControllerServiceProvider());
233
        $this->mount('', new ControllerProvider\FrontControllerProvider());
234
        $this->mount('/'.trim($this['config']['admin_route'], '/').'/', new ControllerProvider\AdminControllerProvider());
235
        Request::enableHttpMethodParameterOverride(); // PUTやDELETEできるようにする
236
237 763
        $this->initialized = true;
238 763
    }
239
240 763
    public function initLocale()
241
    {
242
243
        // timezone
244
        if (!empty($this['config']['timezone'])) {
245
            date_default_timezone_set($this['config']['timezone']);
246
        }
247
248
        $this->register(new \Silex\Provider\TranslationServiceProvider(), array(
249 763
            'locale' => $this['config']['locale'],
250
        ));
251
        $this['translator'] = $this->share($this->extend('translator', function($translator, \Silex\Application $app) {
252
            $translator->addLoader('yaml', new \Symfony\Component\Translation\Loader\YamlFileLoader());
253
254
            $r = new \ReflectionClass('Symfony\Component\Validator\Validator');
255
            $file = dirname($r->getFilename()).'/Resources/translations/validators.'.$app['locale'].'.xlf';
256
            if (file_exists($file)) {
257
                $translator->addResource('xliff', $file, $app['locale'], 'validators');
258
            }
259
260
            $file = __DIR__.'/Resource/locale/validator.'.$app['locale'].'.yml';
261
            if (file_exists($file)) {
262
                $translator->addResource('yaml', $file, $app['locale'], 'validators');
263
            }
264
265
            $file = __DIR__.'/Resource/locale/message.'.$app['locale'].'.yml';
266
            if (file_exists($file)) {
267
                $translator->addResource('yaml', $file, $app['locale']);
268
            }
269
270 438
            return $translator;
271
        }));
272 763
    }
273
274 763
    public function initSession()
275
    {
276
        $this->register(new \Silex\Provider\SessionServiceProvider(), array(
277
            'session.storage.save_path' => $this['config']['root_dir'].'/app/cache/eccube/session',
278
            'session.storage.options' => array(
279 763
                'name' => 'eccube',
280
                'cookie_path' => $this['config']['root_urlpath'] ?: '/',
281 763
                'cookie_secure' => $this['config']['force_ssl'],
282 763
                'cookie_lifetime' => $this['config']['cookie_lifetime'],
283 763
                'cookie_httponly' => true,
284
                // cookie_domainは指定しない
285
                // http://blog.tokumaru.org/2011/10/cookiedomain.html
286 763
            ),
287
        ));
288 763
    }
289
290 763
    public function initRendering()
291
    {
292
        $this->register(new \Silex\Provider\TwigServiceProvider(), array(
293
            'twig.form.templates' => array('Form/form_layout.twig'),
294
        ));
295
        $this['twig'] = $this->share($this->extend('twig', function(\Twig_Environment $twig, \Silex\Application $app) {
296
            $twig->addExtension(new \Eccube\Twig\Extension\EccubeExtension($app));
297
            $twig->addExtension(new \Twig_Extension_StringLoader());
298
299 197
            return $twig;
300
        }));
301
302
        $this->before(function(Request $request, \Silex\Application $app) {
303
            // フロント or 管理画面ごとにtwigの探索パスを切り替える.
304
            $app['twig'] = $app->share($app->extend('twig', function(\Twig_Environment $twig, \Silex\Application $app) {
305 159
                $paths = array();
306
307
                // 互換性がないのでprofiler とproduction 時のcacheを分離する
308
309
                $app['admin'] = false;
310
                $app['front'] = false;
311
312
                if (isset($app['profiler'])) {
313
                    $cacheBaseDir = __DIR__.'/../../app/cache/twig/profiler/';
314
                } else {
315 159
                    $cacheBaseDir = __DIR__.'/../../app/cache/twig/production/';
316
                }
317
                if (strpos($app['request']->getPathInfo(), '/'.trim($app['config']['admin_route'], '/')) === 0) {
318
                    if (file_exists(__DIR__.'/../../app/template/admin')) {
319 91
                        $paths[] = __DIR__.'/../../app/template/admin';
320
                    }
321
                    $paths[] = $app['config']['template_admin_realdir'];
322 91
                    $paths[] = __DIR__.'/../../app/Plugin';
323 91
                    $cache = $cacheBaseDir.'admin';
324
                    $app['admin'] = true;
325
                } else {
326
                    if (file_exists($app['config']['template_realdir'])) {
327
                        $paths[] = $app['config']['template_realdir'];
328
                    }
329
                    $paths[] = $app['config']['template_default_realdir'];
330 68
                    $paths[] = __DIR__.'/../../app/Plugin';
331
                    $cache = $cacheBaseDir.$app['config']['template_code'];
332
                    $app['front'] = true;
333 91
                }
334
                $twig->setCache($cache);
335
                $app['twig.loader']->addLoader(new \Twig_Loader_Filesystem($paths));
336
337 159
                return $twig;
338
            }));
339
340
            // 管理画面のIP制限チェック.
341
            if (strpos($app['request']->getPathInfo(), '/'.trim($app['config']['admin_route'], '/')) === 0) {
342
                // IP制限チェック
343
                $allowHost = $app['config']['admin_allow_host'];
344
                if (count($allowHost) > 0) {
345
                    if (array_search($app['request']->getClientIp(), $allowHost) === false) {
346
                        throw new \Exception();
347
                    }
348
                }
349
            }
350
        }, self::EARLY_EVENT);
351
352
        // twigのグローバル変数を定義.
353 763
        $app = $this;
354
        $this->on(\Symfony\Component\HttpKernel\KernelEvents::CONTROLLER, function(\Symfony\Component\HttpKernel\Event\FilterControllerEvent $event) use ($app) {
355
            // ショップ基本情報
356
            $BaseInfo = $app['eccube.repository.base_info']->get();
357
            $app['twig']->addGlobal('BaseInfo', $BaseInfo);
358
359
            if (strpos($app['request']->getPathInfo(), '/'.trim($app['config']['admin_route'], '/')) === 0) {
360
                // 管理画面
361
                // 管理画面メニュー
362 91
                $menus = array('', '', '');
363
                $app['twig']->addGlobal('menus', $menus);
364
365
                $Member = $app->user();
366
                if (is_object($Member)) {
367
                    // ログインしていれば管理者のロールを取得
368
                    $AuthorityRoles = $app['eccube.repository.authority_role']->findBy(array('Authority' => $Member->getAuthority()));
369
370 88
                    $roles = array();
371
                    foreach ($AuthorityRoles as $AuthorityRole) {
372
                        // 管理画面でメニュー制御するため相対パス全てをセット
373
                        $roles[] = $app['request']->getBaseUrl().'/'.$app['config']['admin_route'].$AuthorityRole->getDenyUrl();
374 88
                    }
375
376
                    $app['twig']->addGlobal('AuthorityRoles', $roles);
377
                }
378
379
            } else {
380
                // フロント画面
381
                $request = $event->getRequest();
382
                $route = $request->attributes->get('_route');
383
384
                // ユーザ作成画面
385
                if ($route === trim($app['config']['user_data_route'])) {
386
                    $params = $request->attributes->get('_route_params');
387 2
                    $route = $params['route'];
388
                    // プレビュー画面
389
                } elseif ($request->get('preview')) {
390
                    $route = 'preview';
391 2
                }
392
393
                try {
394
                    $DeviceType = $app['eccube.repository.master.device_type']
395
                        ->find(\Eccube\Entity\Master\DeviceType::DEVICE_TYPE_PC);
396
                    $PageLayout = $app['eccube.repository.page_layout']->getByUrl($DeviceType, $route);
397
                } catch (\Doctrine\ORM\NoResultException $e) {
398
                    $PageLayout = $app['eccube.repository.page_layout']->newPageLayout($DeviceType);
399 34
                }
400
401
                $app['twig']->addGlobal('PageLayout', $PageLayout);
402
                $app['twig']->addGlobal('title', $PageLayout->getName());
403 91
            }
404
        });
405 763
    }
406
407 763
    public function initMailer()
408
    {
409
410
        // メール送信時の文字エンコード指定(デフォルトはUTF-8)
411
        if (isset($this['config']['mail']['charset_iso_2022_jp']) && is_bool($this['config']['mail']['charset_iso_2022_jp'])) {
412
            if ($this['config']['mail']['charset_iso_2022_jp'] === true) {
413
                \Swift::init(function() {
414
                    \Swift_DependencyContainer::getInstance()
415
                        ->register('mime.qpheaderencoder')
416
                        ->asAliasOf('mime.base64headerencoder');
417
                    \Swift_Preferences::getInstance()->setCharset('iso-2022-jp');
418
                });
419
            }
420
        }
421
422
        $this->register(new \Silex\Provider\SwiftmailerServiceProvider());
423
        $this['swiftmailer.options'] = $this['config']['mail'];
424
425
        if (isset($this['config']['mail']['spool']) && is_bool($this['config']['mail']['spool'])) {
426
            $this['swiftmailer.use_spool'] = $this['config']['mail']['spool'];
427
        }
428
        // デフォルトはsmtpを使用
429
        $transport = $this['config']['mail']['transport'];
430 763
        if ($transport == 'sendmail') {
431
            $this['swiftmailer.transport'] = \Swift_SendmailTransport::newInstance();
432 763
        } elseif ($transport == 'mail') {
433
            $this['swiftmailer.transport'] = \Swift_MailTransport::newInstance();
434
        }
435 763
    }
436
437 763
    public function initDoctrine()
438
    {
439
        $this->register(new \Silex\Provider\DoctrineServiceProvider(), array(
440
            'dbs.options' => array(
441 763
                'default' => $this['config']['database']
442
        )));
443
        $this->register(new \Saxulum\DoctrineOrmManagerRegistry\Silex\Provider\DoctrineOrmManagerRegistryProvider());
444
445
        // プラグインのmetadata定義を合わせて行う.
446 763
        $pluginBasePath = __DIR__.'/../../app/Plugin';
447 762
        $finder = Finder::create()
448 763
            ->in($pluginBasePath)
449 763
            ->directories()
450
            ->depth(0);
451
452 763
        $ormMappings = array();
453
        $ormMappings[] = array(
454 763
            'type' => 'yml',
455 763
            'namespace' => 'Eccube\Entity',
456
            'path' => array(
457 763
                __DIR__.'/Resource/doctrine',
458 763
                __DIR__.'/Resource/doctrine/master',
459 763
            ),
460 763
        );
461
462
        foreach ($finder as $dir) {
463
            if (file_exists($dir->getRealPath().'/config.yml')) {
464
                $config = Yaml::parse(file_get_contents($dir->getRealPath().'/config.yml'));
465
            }else{
466
                $error = 'Application::initDoctrine : config.yamlがみつかりません'.$dir->getRealPath();
467
                $this->log($error, array(), Logger::WARNING);
468
                continue;
469
            }
470
471
            // Doctrine Extend
472
            if (isset($config['orm.path']) && is_array($config['orm.path'])) {
473
                $paths = array();
474
                foreach ($config['orm.path'] as $path) {
475
                    $paths[] = $pluginBasePath.'/'.$config['code'].$path;
476
                }
477
                $ormMappings[] = array(
478
                    'type' => 'yml',
479
                    'namespace' => 'Plugin\\'.$config['code'].'\\Entity',
480
                    'path' => $paths,
481
                );
482
            }
483 763
        }
484
485
        $this->register(new \Dflydev\Silex\Provider\DoctrineOrm\DoctrineOrmServiceProvider(), array(
486 763
            'orm.proxies_dir' => __DIR__.'/../../app/cache/doctrine',
487
            'orm.em.options' => array(
488
                'mappings' => $ormMappings,
489 763
            ),
490
        ));
491 763
    }
492
493 763
    public function initSecurity()
494
    {
495
        $this->register(new \Silex\Provider\SecurityServiceProvider());
496
        $this->register(new \Silex\Provider\RememberMeServiceProvider());
497
498 763
        $this['security.firewalls'] = array(
499
            'admin' => array(
500
                'pattern' => "^/{$this['config']['admin_route']}",
501
                'form' => array(
502
                    'login_path' => "/{$this['config']['admin_route']}/login",
503
                    'check_path' => "/{$this['config']['admin_route']}/login_check",
504 763
                    'username_parameter' => 'login_id',
505 763
                    'password_parameter' => 'password',
506 763
                    'with_csrf' => true,
507 763
                    'use_forward' => true,
508 763
                ),
509
                'logout' => array(
510
                    'logout_path' => "/{$this['config']['admin_route']}/logout",
511
                    'target_url' => "/{$this['config']['admin_route']}/",
512 763
                ),
513
                'users' => $this['orm.em']->getRepository('Eccube\Entity\Member'),
514 763
                'anonymous' => true,
515
            ),
516
            'customer' => array(
517 763
                'pattern' => '^/',
518
                'form' => array(
519
                    'login_path' => '/mypage/login',
520
                    'check_path' => '/login_check',
521
                    'username_parameter' => 'login_email',
522
                    'password_parameter' => 'login_pass',
523
                    'with_csrf' => true,
524
                    'use_forward' => true,
525 763
                ),
526
                'logout' => array(
527
                    'logout_path' => '/logout',
528
                    'target_url' => '/',
529 763
                ),
530
                'remember_me' => array(
531
                    'key' => sha1($this['config']['auth_magic']),
532 763
                    'name' => 'eccube_rememberme',
533
                    // lifetimeはデフォルトの1年間にする
534
                    // 'lifetime' => $this['config']['cookie_lifetime'],
535
                    'path' => $this['config']['root_urlpath'] ?: '/',
536 763
                    'secure' => $this['config']['force_ssl'],
537 763
                    'httponly' => true,
538 763
                    'always_remember_me' => false,
539 763
                    'remember_me_parameter' => 'login_memory',
540
                ),
541
                'users' => $this['orm.em']->getRepository('Eccube\Entity\Customer'),
542 763
                'anonymous' => true,
543
            ),
544
        );
545
546 763
        $this['security.access_rules'] = array(
547
            array("^/{$this['config']['admin_route']}/login", 'IS_AUTHENTICATED_ANONYMOUSLY'),
548
            array("^/{$this['config']['admin_route']}", 'ROLE_ADMIN'),
549 763
            array('^/mypage/login', 'IS_AUTHENTICATED_ANONYMOUSLY'),
550 763
            array('^/mypage/withdraw_complete', 'IS_AUTHENTICATED_ANONYMOUSLY'),
551 763
            array('^/mypage/change', 'IS_AUTHENTICATED_FULLY'),
552 763
            array('^/mypage', 'ROLE_USER'),
553
        );
554
555
        $this['eccube.password_encoder'] = $this->share(function($app) {
556
            return new \Eccube\Security\Core\Encoder\PasswordEncoder($app['config']);
557
        });
558
        $this['security.encoder_factory'] = $this->share(function($app) {
559
            return new \Symfony\Component\Security\Core\Encoder\EncoderFactory(array(
560 763
                'Eccube\Entity\Customer' => $app['eccube.password_encoder'],
561 763
                'Eccube\Entity\Member' => $app['eccube.password_encoder'],
562
            ));
563
        });
564
        $this['eccube.event_listner.security'] = $this->share(function($app) {
565
            return new \Eccube\EventListener\SecurityEventListener($app['orm.em']);
566
        });
567
        $this['user'] = function($app) {
568
            $token = $app['security']->getToken();
569
570
            return ($token !== null) ? $token->getUser() : null;
571
        };
572
573
        // ログイン時のイベントを設定.
574
        $this['dispatcher']->addListener(\Symfony\Component\Security\Http\SecurityEvents::INTERACTIVE_LOGIN, array($this['eccube.event_listner.security'], 'onInteractiveLogin'));
575
576
        // Voterの設定
577 763
        $app = $this;
578
        $this['authority_voter'] = $this->share(function($app) {
579
            return new \Eccube\Security\Voter\AuthorityVoter($app);
580
        });
581
582
        $app['security.voters'] = $app->extend('security.voters', function($voters) use ($app) {
583
            $voters[] = $app['authority_voter'];
584
585 763
            return $voters;
586
        });
587
588
        $this['security.access_manager'] = $this->share(function($app) {
589
            return new \Symfony\Component\Security\Core\Authorization\AccessDecisionManager($app['security.voters'], 'unanimous');
590
        });
591
592 763
    }
593
594 4
    public function initializePlugin()
595
    {
596 4
        if ($this->initializedPlugin) {
597
            return;
598
        }
599
600
        // setup event dispatcher
601
        $this->initPluginEventDispatcher();
602
603
        // load plugin
604
        $this->loadPlugin();
605
606 4
        $this->initializedPlugin = true;
607 4
    }
608
609 763
    public function initPluginEventDispatcher()
610
    {
611
        // EventDispatcher
612
        $this['eccube.event.dispatcher'] = $this->share(function() {
613
            return new EventDispatcher();
614
        });
615
616
        // hook point
617
        $this->before(function(Request $request, \Silex\Application $app) {
618
            $app['eccube.event.dispatcher']->dispatch('eccube.event.app.before');
619
        }, self::EARLY_EVENT);
620
621
        $this->before(function(Request $request, \Silex\Application $app) {
622
            $event = 'eccube.event.controller.'.$request->attributes->get('_route').'.before';
623
            $app['eccube.event.dispatcher']->dispatch($event);
624
        });
625
626 View Code Duplication
        $this->after(function(Request $request, Response $response, \Silex\Application $app) {
627
            $event = 'eccube.event.controller.'.$request->attributes->get('_route').'.after';
628
            $app['eccube.event.dispatcher']->dispatch($event);
629
        });
630
631
        $this->after(function(Request $request, Response $response, \Silex\Application $app) {
632
            $app['eccube.event.dispatcher']->dispatch('eccube.event.app.after');
633
        }, self::LATE_EVENT);
634
635 View Code Duplication
        $this->finish(function(Request $request, Response $response, \Silex\Application $app) {
636
            $event = 'eccube.event.controller.'.$request->attributes->get('_route').'.finish';
637
            $app['eccube.event.dispatcher']->dispatch($event);
638
        });
639
640 763
        $app = $this;
641
        $this->on(\Symfony\Component\HttpKernel\KernelEvents::RESPONSE, function(\Symfony\Component\HttpKernel\Event\FilterResponseEvent $event) use ($app) {
642
            $route = $event->getRequest()->attributes->get('_route');
643
            $app['eccube.event.dispatcher']->dispatch('eccube.event.render.'.$route.'.before', $event);
644
        });
645
646
        // Request Event
647 View Code Duplication
        $this->on(\Symfony\Component\HttpKernel\KernelEvents::REQUEST, function(\Symfony\Component\HttpKernel\Event\GetResponseEvent $event) use ($app) {
648
649
            if (\Symfony\Component\HttpKernel\HttpKernelInterface::MASTER_REQUEST !== $event->getRequestType()) {
650 1
                return;
651
            }
652
653
            $route = $event->getRequest()->attributes->get('_route');
654
655
            if (is_null($route)) {
656
                return;
657
            }
658
659
            $app['monolog']->debug('KernelEvents::REQUEST '.$route);
660
661
            // 全体
662
            $app['eccube.event.dispatcher']->dispatch('eccube.event.app.request', $event);
663
664
            if (strpos('admin', $route) === 0) {
665
                // 管理画面
666
                $app['eccube.event.dispatcher']->dispatch('eccube.event.admin.request', $event);
667
            } else {
668
                // フロント画面
669
                $app['eccube.event.dispatcher']->dispatch('eccube.event.front.request', $event);
670
            }
671
672
            // ルーティング単位
673
            $app['eccube.event.dispatcher']->dispatch("eccube.event.route.{$route}.request", $event);
674
675
        }, 30); // Routing(32)が解決しし, 認証判定(8)が実行される前のタイミング.
676
677
        // Controller Event
678 View Code Duplication
        $this->on(\Symfony\Component\HttpKernel\KernelEvents::CONTROLLER, function(\Symfony\Component\HttpKernel\Event\FilterControllerEvent $event) use ($app) {
679
680
            if (\Symfony\Component\HttpKernel\HttpKernelInterface::MASTER_REQUEST !== $event->getRequestType()) {
681 1
                return;
682
            }
683
684
685
            $route = $event->getRequest()->attributes->get('_route');
686
687
            if (is_null($route)) {
688
                return;
689
            }
690
691
            $app['monolog']->debug('KernelEvents::CONTROLLER '.$route);
692
693
            // 全体
694
            $app['eccube.event.dispatcher']->dispatch('eccube.event.app.controller', $event);
695
696
            if (strpos('admin', $route) === 0) {
697
                // 管理画面
698
                $app['eccube.event.dispatcher']->dispatch('eccube.event.admin.controller', $event);
699
            } else {
700
                // フロント画面
701
                $app['eccube.event.dispatcher']->dispatch('eccube.event.front.controller', $event);
702
            }
703
704
            // ルーティング単位
705
            $app['eccube.event.dispatcher']->dispatch("eccube.event.route.{$route}.controller", $event);
706
        });
707
708
        // Response Event
709 View Code Duplication
        $this->on(\Symfony\Component\HttpKernel\KernelEvents::RESPONSE, function(\Symfony\Component\HttpKernel\Event\FilterResponseEvent $event) use ($app) {
710
711
            if (\Symfony\Component\HttpKernel\HttpKernelInterface::MASTER_REQUEST !== $event->getRequestType()) {
712 1
                return;
713
            }
714
715
            $route = $event->getRequest()->attributes->get('_route');
716
717
            if (is_null($route)) {
718
                return;
719
            }
720
721
            $app['monolog']->debug('KernelEvents::RESPONSE '.$route);
722
723
            // ルーティング単位
724
            $app['eccube.event.dispatcher']->dispatch("eccube.event.route.{$route}.response", $event);
725
726
            if (strpos('admin', $route) === 0) {
727
                // 管理画面
728
                $app['eccube.event.dispatcher']->dispatch('eccube.event.admin.response', $event);
729
            } else {
730
                // フロント画面
731
                $app['eccube.event.dispatcher']->dispatch('eccube.event.front.response', $event);
732
            }
733
734
            // 全体
735
            $app['eccube.event.dispatcher']->dispatch('eccube.event.app.response', $event);
736
        });
737
738
        // Exception Event
739 View Code Duplication
        $this->on(\Symfony\Component\HttpKernel\KernelEvents::EXCEPTION, function(\Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent $event) use ($app) {
740
741
            if (\Symfony\Component\HttpKernel\HttpKernelInterface::MASTER_REQUEST !== $event->getRequestType()) {
742
                return;
743
            }
744
745
            $route = $event->getRequest()->attributes->get('_route');
746
747
            if (is_null($route)) {
748
                return;
749
            }
750
751
            $app['monolog']->debug('KernelEvents::EXCEPTION '.$route);
752
753
            // ルーティング単位
754
            $app['eccube.event.dispatcher']->dispatch("eccube.event.route.{$route}.exception", $event);
755
756
            if (strpos('admin', $route) === 0) {
757
                // 管理画面
758
                $app['eccube.event.dispatcher']->dispatch('eccube.event.admin.exception', $event);
759
            } else {
760
                // フロント画面
761
                $app['eccube.event.dispatcher']->dispatch('eccube.event.front.exception', $event);
762
            }
763
764
            // 全体
765
            $app['eccube.event.dispatcher']->dispatch('eccube.event.app.exception', $event);
766
        });
767
768
        // Terminate Event
769 View Code Duplication
        $this->on(\Symfony\Component\HttpKernel\KernelEvents::TERMINATE, function(\Symfony\Component\HttpKernel\Event\PostResponseEvent $event) use ($app) {
770
771
            $route = $event->getRequest()->attributes->get('_route');
772
773
            if (is_null($route)) {
774
                return;
775
            }
776
777
            $app['monolog']->debug('KernelEvents::TERMINATE '.$route);
778
779
            // ルーティング単位
780
            $app['eccube.event.dispatcher']->dispatch("eccube.event.route.{$route}.terminate", $event);
781
782
            if (strpos('admin', $route) === 0) {
783
                // 管理画面
784
                $app['eccube.event.dispatcher']->dispatch('eccube.event.admin.terminate', $event);
785
            } else {
786
                // フロント画面
787
                $app['eccube.event.dispatcher']->dispatch('eccube.event.front.terminate', $event);
788
            }
789
790
            // 全体
791
            $app['eccube.event.dispatcher']->dispatch('eccube.event.app.terminate', $event);
792
        });
793 763
    }
794
795 4
    public function loadPlugin()
796
    {
797
        // プラグインディレクトリを探索.
798 4
        $basePath = __DIR__.'/../../app/Plugin';
799 4
        $finder = Finder::create()
800 4
            ->in($basePath)
801 4
            ->directories()
802
            ->depth(0);
803
804
        $finder->sortByName();
805
806
        // ハンドラ優先順位をdbから持ってきてハッシュテーブルを作成
807 4
        $priorities = array();
808
        $handlers = $this['orm.em']
809
            ->getRepository('Eccube\Entity\PluginEventHandler')
810
            ->getHandlers();
811
        foreach ($handlers as $handler) {
812
            if ($handler->getPlugin()->getEnable() && !$handler->getPlugin()->getDelFlg()) {
813
814
                $priority = $handler->getPriority();
815
            } else {
816
                // Pluginがdisable、削除済みの場合、EventHandlerのPriorityを全て0とみなす
817
                $priority = \Eccube\Entity\PluginEventHandler::EVENT_PRIORITY_DISABLED;
818
            }
819
            $priorities[$handler->getPlugin()->getClassName()][$handler->getEvent()][$handler->getHandler()] = $priority;
820 4
        }
821
822
        // プラグインをロードする.
823
        // config.yml/event.ymlの定義に沿ってインスタンスの生成を行い, イベント設定を行う.
824
        foreach ($finder as $dir) {
825
            //config.ymlのないディレクトリは無視する
826
            try {
827
                $this['eccube.service.plugin']->checkPluginArchiveContent($dir->getRealPath());
828
            } catch(\Eccube\Exception\PluginException $e) {
829
                $this['monolog']->warning($e->getMessage());
830
                continue;
831
            }
832
            $config = $this['eccube.service.plugin']->readYml($dir->getRealPath().'/config.yml');
833
834
            $plugin = $this['orm.em']
835
                ->getRepository('Eccube\Entity\Plugin')
836
                ->findOneBy(array('code' => $config['code']));
837
838
            // const
839
            if (isset($config['const'])) {
840
                $this['config'] = $this->share($this->extend('config', function($eccubeConfig) use ($config) {
841
                    $eccubeConfig[$config['code']] = array(
842
                        'const' => $config['const'],
843
                    );
844
845
                    return $eccubeConfig;
846
                }));
847
            }
848
849
            if ($plugin && $plugin->getEnable() == Constant::DISABLED) {
850
                // プラグインが無効化されていれば読み込まない
851
                continue;
852
            }
853
854
            // Type: Event
855
            if (isset($config['event'])) {
856
                $class = '\\Plugin\\'.$config['code'].'\\'.$config['event'];
857
                $subscriber = new $class($this);
858
859
                if (file_exists($dir->getRealPath().'/event.yml')) {
860
                    foreach (Yaml::parse(file_get_contents($dir->getRealPath().'/event.yml')) as $event => $handlers) {
861
                        foreach ($handlers as $handler) {
862
                            if (!isset($priorities[$config['event']][$event][$handler[0]])) { // ハンドラテーブルに登録されていない(ソースにしか記述されていない)ハンドラは一番後ろにする
863
                                $priority = \Eccube\Entity\PluginEventHandler::EVENT_PRIORITY_LATEST;
864
                            } else {
865
                                $priority = $priorities[$config['event']][$event][$handler[0]];
866
                            }
867
                            // 優先度が0のプラグインは登録しない
868
                            if (\Eccube\Entity\PluginEventHandler::EVENT_PRIORITY_DISABLED != $priority) {
869
                                $this['eccube.event.dispatcher']->addListener($event, array($subscriber, $handler[0]), $priority);
870
                            }
871
                        }
872
                    }
873
                }
874
            }
875
            // Type: ServiceProvider
876
            if (isset($config['service'])) {
877
                foreach ($config['service'] as $service) {
878
                    $class = '\\Plugin\\'.$config['code'].'\\ServiceProvider\\'.$service;
879
                    if (!class_exists($class)) {
880
                        $this['monolog']->warning('該当クラスが見つかりません:' . $class);
881
                        continue;
882
                    }
883
                    $this->register(new $class($this));
884
                }
885
            }
886 4
        }
887
    }
888
889
    /**
890
     *
891
     * データベースの接続を確認
892
     * 成功 : trueを返却
893
     * 失敗 : \Doctrine\DBAL\DBALExceptionエラーが発生( 接続に失敗した場合 )、エラー画面を表示しdie()
894
     * 備考 : app['debug']がtrueの際は処理を行わない
895
     * @return boolean true
896
     *
897
     */
898 759
    protected function checkDatabaseConnection()
899
    {
900
        if ($this['debug']) {
901 759
            return;
902
        }
903
        try {
904
            $this['db']->connect();
905
        } catch (\Doctrine\DBAL\DBALException $e) {
906
            $this['monolog']->error($e->getMessage());
907
            $this['twig.path'] = array(__DIR__.'/Resource/template/exception');
908
            $html = $this['twig']->render('error.twig', array(
909
                'error_title' => 'データーベース接続エラー',
910
                'error_message' => 'データーベースを確認してください',
911
            ));
912
            $response = new Response();
913
            $response->setContent($html);
914
            $response->setStatusCode('500');
915
            $response->headers->set('Content-Type', 'text/html');
916
            $response->send();
917
            die();
0 ignored issues
show
Coding Style Compatibility introduced by
The method checkDatabaseConnection() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
918 4
        }
919 4
        return true;
920
    }
921
}
922