Failed Conditions
Push — improve/performance ( a6615f...85882a )
by Ryo
422:59 queued 414:38
created

src/Eccube/Application.php (2 issues)

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

Syntax error, unexpected T_SL, expecting T_FUNCTION
Loading history...
1049
    /**
1050
     * セッションが開始されているかどうか.
1051
     *
1052
     * @return boolean セッションが開始済みの場合 true
1053
     * @link http://php.net/manual/ja/function.session-status.php#113468
1054
     */
1055
    protected function isSessionStarted()
1056
    {
1057
        if (php_sapi_name() !== 'cli') {
1058
            if (version_compare(phpversion(), '5.4.0', '>=')) {
1059
                return session_status() === PHP_SESSION_ACTIVE ? true : false;
1060
            } else {
1061
                return session_id() === '' ? false : true;
1062
            }
1063
        }
1064
        return false;
1065
=======
1066
1067
    /**
1068
     * Http Cache対応
1069
     */
1070
    protected function cacheRequest()
1071
    {
1072
        $app = $this;
1073
1074
        // Response Event(http cache対応、event実行は一番遅く設定)
1075
        $this->on(\Symfony\Component\HttpKernel\KernelEvents::RESPONSE, function (\Symfony\Component\HttpKernel\Event\FilterResponseEvent $event) use ($app) {
1076
1077
            if ($app['config']['http_cache']['enabled']) {
1078
                // httpキャッシュが有効の場合
1079
1080
                $request = $event->getRequest();
1081
                $response = $event->getResponse();
1082
1083
                $route = $request->attributes->get('_route');
1084
1085
                $etag = md5($response->getContent());
1086
1087
                if (strpos($route, 'admin') === 0) {
1088
                    // 管理画面
1089
1090
                    // 管理画面ではコンテンツの中身が変更された時点でキャッシュを更新し、キャッシュの適用範囲はprivateに設定
1091
                    $response->setCache(array(
1092
                        'etag' => $etag,
1093
                        'private' => true,
1094
                    ));
1095
1096
                    if ($response->isNotModified($request)) {
1097
                        return $response;
1098
                    }
1099
1100
                } else {
1101
                    // フロント画面
1102
                    $cacheRoute = $app['config']['http_cache']['route'];
1103
1104
                    if (in_array($route, $cacheRoute) === true) {
1105
                        // キャッシュ対象となる画面lが含まれていた場合、キャッシュ化
1106
                        // max-ageを設定しているためExpiresは不要
1107
                        // Last-Modifiedだと比較する項目がないためETagで対応
1108
                        // max-ageを設定していた場合、contentの中身が変更されても変更されない
1109
1110
                        $age = $app['config']['http_cache']['age'];
1111
1112
                        $response->setCache(array(
1113
                            'etag' => $etag,
1114
                            'max_age' => $age,
1115
                            's_maxage' => $age,
1116
                            'public' => true,
1117
                        ));
1118
1119
                        if ($response->isNotModified($request)) {
1120
                            return $response;
1121
                        }
1122
                    }
1123
                }
1124
            }
1125
1126
        }, -1024);
1127
1128
>>>>>>> k-yamamura/feature-httpcache
1129
    }
1130
}
1131