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