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