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