Completed
Pull Request — master (#1621)
by Kentaro
35:34
created

Application::isSessionStarted()   B

Complexity

Conditions 5
Paths 5

Size

Total Lines 11
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 30

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 11
ccs 0
cts 0
cp 0
rs 8.8571
cc 5
eloc 7
nc 5
nop 0
crap 30
1
<?php
2
/*
3
 * This file is part of EC-CUBE
4
 *
5
 * Copyright(c) 2000-2015 LOCKON CO.,LTD. All Rights Reserved.
6
 *
7
 * http://www.lockon.co.jp/
8
 *
9
 * This program is free software; you can redistribute it and/or
10
 * modify it under the terms of the GNU General Public License
11
 * as published by the Free Software Foundation; either version 2
12
 * of the License, or (at your option) any later version.
13
 *
14
 * This program is distributed in the hope that it will be useful,
15
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
 * GNU General Public License for more details.
18
 *
19
 * You should have received a copy of the GNU General Public License
20
 * along with this program; if not, write to the Free Software
21
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22
 */
23
24
namespace Eccube;
25
26
use Eccube\Application\ApplicationTrait;
27
use Eccube\Common\Constant;
28
use Monolog\Logger;
29
use Symfony\Component\EventDispatcher\EventDispatcher;
30
use Symfony\Component\Finder\Finder;
31
use Symfony\Component\HttpFoundation\Request;
32
use Symfony\Component\HttpFoundation\Response;
33
use Symfony\Component\Yaml\Yaml;
34
35
class Application extends ApplicationTrait
0 ignored issues
show
introduced by
Missing class doc comment
Loading history...
36
{
37
    protected static $instance;
38
39
    protected $initialized = false;
40
    protected $initializedPlugin = false;
41 423
42
    public static function getInstance(array $values = array())
0 ignored issues
show
introduced by
Missing function doc comment
Loading history...
43
    {
44
        if (!is_object(self::$instance)) {
45
            self::$instance = new Application($values);
46
        }
47 423
48 423
        return self::$instance;
49
    }
50 769
51
    public static function clearInstance()
0 ignored issues
show
introduced by
Missing function doc comment
Loading history...
52 769
    {
53 769
        self::$instance = null;
54
    }
55
56
    final public function __clone()
0 ignored issues
show
introduced by
Missing function doc comment
Loading history...
57
    {
58
        throw new \Exception('Clone is not allowed against '.get_class($this));
59
    }
60 769
61
    public function __construct(array $values = array())
0 ignored issues
show
introduced by
Missing function doc comment
Loading history...
62
    {
63
        parent::__construct($values);
64
65 769
        if (is_null(self::$instance)) {
66
            self::$instance = $this;
67
        }
68
69
        // load config
70
        $this->initConfig();
71
72
        // init monolog
73
        $this->initLogger();
74
    }
75 783
76
    public function initConfig()
0 ignored issues
show
introduced by
Missing function doc comment
Loading history...
77
    {
78
        // load config
79 772
        $this['config'] = $this->share(function() {
0 ignored issues
show
Coding Style introduced by
Expected 1 space after FUNCTION keyword; 0 found
Loading history...
80 772
            $ymlPath = __DIR__.'/../../app/config/eccube';
81
            $distPath = __DIR__.'/../../src/Eccube/Resource/config';
82 772
83 772
            $config = array();
84
            $config_yml = $ymlPath.'/config.yml';
85
            if (file_exists($config_yml)) {
86
                $config = Yaml::parse(file_get_contents($config_yml));
87
            }
88 772
89 772
            $config_dist = array();
90
            $config_yml_dist = $distPath.'/config.yml.dist';
91
            if (file_exists($config_yml_dist)) {
92
                $config_dist = Yaml::parse(file_get_contents($config_yml_dist));
93
            }
94 772
95 772
            $config_path = array();
96
            $path_yml = $ymlPath.'/path.yml';
97
            if (file_exists($path_yml)) {
98
                $config_path = Yaml::parse(file_get_contents($path_yml));
99
            }
100 772
101 772
            $config_constant = array();
102
            $constant_yml = $ymlPath.'/constant.yml';
103
            if (file_exists($constant_yml)) {
104
                $config_constant = Yaml::parse(file_get_contents($constant_yml));
105
                $config_constant = empty($config_constant) ? array() : $config_constant;
106
            }
107 772
108 772
            $config_constant_dist = array();
109
            $constant_yml_dist = $distPath.'/constant.yml.dist';
110
            if (file_exists($constant_yml_dist)) {
111
                $config_constant_dist = Yaml::parse(file_get_contents($constant_yml_dist));
112
            }
113
114
            $configAll = array_replace_recursive($config_constant_dist, $config_dist, $config_constant, $config_path, $config);
115 772
116 772
            $database = array();
117
            $yml = $ymlPath.'/database.yml';
118
            if (file_exists($yml)) {
119
                $database = Yaml::parse(file_get_contents($yml));
120
            }
121 772
122 772
            $mail = array();
123
            $yml = $ymlPath.'/mail.yml';
124
            if (file_exists($yml)) {
125
                $mail = Yaml::parse(file_get_contents($yml));
126
            }
127
            $configAll = array_replace_recursive($configAll, $database, $mail);
128 772
129 772
            $config_log = array();
130
            $yml = $ymlPath.'/log.yml';
131
            if (file_exists($yml)) {
132
                $config_log = Yaml::parse(file_get_contents($yml));
133 772
            }
134 772
            $config_log_dist = array();
135
            $log_yml_dist = $distPath.'/log.yml.dist';
136
            if (file_exists($log_yml_dist)) {
137
                $config_log_dist = Yaml::parse(file_get_contents($log_yml_dist));
138
            }
139
140
            $configAll = array_replace_recursive($configAll, $config_log_dist, $config_log);
141 772
142 772
            $config_nav = array();
143
            $yml = $ymlPath.'/nav.yml';
144
            if (file_exists($yml)) {
145
                $config_nav = array('nav' => Yaml::parse(file_get_contents($yml)));
146 772
            }
147 772
            $config_nav_dist = array();
148
            $nav_yml_dist = $distPath.'/nav.yml.dist';
149
            if (file_exists($nav_yml_dist)) {
150
                $config_nav_dist = array('nav' => Yaml::parse(file_get_contents($nav_yml_dist)));
151
            }
152
153
            $configAll = array_replace_recursive($configAll, $config_nav_dist, $config_nav);
154 772
155
            return $configAll;
156 783
        });
157
    }
158 783
159
    public function initLogger()
0 ignored issues
show
introduced by
Missing function doc comment
Loading history...
160 783
    {
161
        $app = $this;
162
        $this->register(new ServiceProvider\EccubeMonologServiceProvider($app));
0 ignored issues
show
Unused Code introduced by
The call to EccubeMonologServiceProvider::__construct() has too many arguments starting with $app.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
163
        $this['monolog.logfile'] = __DIR__.'/../../app/log/site.log';
164 783
        $this['monolog.name'] = 'eccube';
165
    }
166 769
167
    public function initialize()
0 ignored issues
show
introduced by
Missing function doc comment
Loading history...
168 769
    {
169
        if ($this->initialized) {
170
            return;
171
        }
172
173
        // init locale
174
        $this->initLocale();
175
176
        // init session
177
        if (!$this->isSessionStarted()) {
178
            $this->initSession();
179
        }
180
181
        // init twig
182
        $this->initRendering();
183
184
        // init provider
185
        $this->register(new \Silex\Provider\HttpFragmentServiceProvider());
186
        $this->register(new \Silex\Provider\UrlGeneratorServiceProvider());
187
        $this->register(new \Silex\Provider\FormServiceProvider());
188 769
        $this->register(new \Silex\Provider\SerializerServiceProvider());
189
        $this->register(new \Eccube\ServiceProvider\ValidatorServiceProvider());
190
191 10
        $app = $this;
192
        $this->error(function(\Exception $e, $code) use ($app) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space after FUNCTION keyword; 0 found
Loading history...
193
            if ($app['debug']) {
194
                return;
195
            }
196
197
            switch ($code) {
198
                case 403:
199
                    $title = 'アクセスできません。';
200
                    $message = 'お探しのページはアクセスができない状況にあるか、移動もしくは削除された可能性があります。';
201
                    break;
202
                case 404:
203
                    $title = 'ページがみつかりません。';
204
                    $message = 'URLに間違いがないかご確認ください。';
205
                    break;
206
                default:
207
                    $title = 'システムエラーが発生しました。';
208
                    $message = '大変お手数ですが、サイト管理者までご連絡ください。';
209
                    break;
210
            }
211
212
            return $app->render('error.twig', array(
213
                'error_title' => $title,
214
                'error_message' => $message,
215
            ));
216
        });
217
218
        // init mailer
219
        $this->initMailer();
220
221
        // init doctrine orm
222
        $this->initDoctrine();
223
224
        // Set up the DBAL connection now to check for a proper connection to the database.
225
        $this->checkDatabaseConnection();
226
227
        // init security
228
        $this->initSecurity();
229
230
        // init ec-cube service provider
231
        $this->register(new ServiceProvider\EccubeServiceProvider());
232
233
        // mount controllers
234
        $this->register(new \Silex\Provider\ServiceControllerServiceProvider());
235
        $this->mount('', new ControllerProvider\FrontControllerProvider());
236 769
        $this->mount('/'.trim($this['config']['admin_route'], '/').'/', new ControllerProvider\AdminControllerProvider());
237 769
        Request::enableHttpMethodParameterOverride(); // PUTやDELETEできるようにする
238
239 769
        $this->initialized = true;
240
    }
241
242
    public function initLocale()
0 ignored issues
show
introduced by
Missing function doc comment
Loading history...
243
    {
244
245
        // timezone
246
        if (!empty($this['config']['timezone'])) {
247
            date_default_timezone_set($this['config']['timezone']);
248 769
        }
249
250
        $this->register(new \Silex\Provider\TranslationServiceProvider(), array(
251
            'locale' => $this['config']['locale'],
252
        ));
253
        $this['translator'] = $this->share($this->extend('translator', function($translator, \Silex\Application $app) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space after FUNCTION keyword; 0 found
Loading history...
254
            $translator->addLoader('yaml', new \Symfony\Component\Translation\Loader\YamlFileLoader());
255
256
            $r = new \ReflectionClass('Symfony\Component\Validator\Validator');
257
            $file = dirname($r->getFilename()).'/Resources/translations/validators.'.$app['locale'].'.xlf';
258
            if (file_exists($file)) {
259
                $translator->addResource('xliff', $file, $app['locale'], 'validators');
260
            }
261
262
            $file = __DIR__.'/Resource/locale/validator.'.$app['locale'].'.yml';
263
            if (file_exists($file)) {
264
                $translator->addResource('yaml', $file, $app['locale'], 'validators');
265
            }
266
267
            $file = __DIR__.'/Resource/locale/message.'.$app['locale'].'.yml';
268
            if (file_exists($file)) {
269 444
                $translator->addResource('yaml', $file, $app['locale']);
270
            }
271 769
272
            return $translator;
273 769
        }));
274
    }
275
276
    public function initSession()
0 ignored issues
show
introduced by
Missing function doc comment
Loading history...
277
    {
278 769
        $this->register(new \Silex\Provider\SessionServiceProvider(), array(
279
            'session.storage.save_path' => $this['config']['root_dir'].'/app/cache/eccube/session',
280 769
            'session.storage.options' => array(
281 769
                'name' => 'eccube',
282 769
                'cookie_path' => $this['config']['root_urlpath'] ?: '/',
283
                'cookie_secure' => $this['config']['force_ssl'],
284
                'cookie_lifetime' => $this['config']['cookie_lifetime'],
285 769
                'cookie_httponly' => true,
286
                // cookie_domainは指定しない
287 769
                // http://blog.tokumaru.org/2011/10/cookiedomain.html
288
            ),
289 769
        ));
290
    }
291
292
    public function initRendering()
0 ignored issues
show
introduced by
Missing function doc comment
Loading history...
293
    {
294
        $this->register(new \Silex\Provider\TwigServiceProvider(), array(
295
            'twig.form.templates' => array('Form/form_layout.twig'),
296
        ));
297
        $this['twig'] = $this->share($this->extend('twig', function(\Twig_Environment $twig, \Silex\Application $app) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space after FUNCTION keyword; 0 found
Loading history...
298 203
            $twig->addExtension(new \Eccube\Twig\Extension\EccubeExtension($app));
299
            $twig->addExtension(new \Twig_Extension_StringLoader());
300
301
            return $twig;
302
        }));
303
304 168
        $this->before(function(Request $request, \Silex\Application $app) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space after FUNCTION keyword; 0 found
Loading history...
305
            // フロント or 管理画面ごとにtwigの探索パスを切り替える.
306
            $app['twig'] = $app->share($app->extend('twig', function(\Twig_Environment $twig, \Silex\Application $app) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space after FUNCTION keyword; 0 found
Loading history...
307
                $paths = array();
308
309
                // 互換性がないのでprofiler とproduction 時のcacheを分離する
310
311 168
                $app['admin'] = false;
312
                $app['front'] = false;
313
314
                if (isset($app['profiler'])) {
315 101
                    $cacheBaseDir = __DIR__.'/../../app/cache/twig/profiler/';
316
                } else {
317
                    $cacheBaseDir = __DIR__.'/../../app/cache/twig/production/';
318 101
                }
319 101
                $pathinfo = rawurldecode($app['request']->getPathInfo());
320
                if (strpos($pathinfo, '/'.trim($app['config']['admin_route'], '/').'/') === 0) {
321
                    if (file_exists(__DIR__.'/../../app/template/admin')) {
322
                        $paths[] = __DIR__.'/../../app/template/admin';
323
                    }
324
                    $paths[] = $app['config']['template_admin_realdir'];
325 68
                    $paths[] = __DIR__.'/../../app/Plugin';
326
                    $cache = $cacheBaseDir.'admin';
327 101
                    $app['admin'] = true;
328
                } else {
329
                    if (file_exists($app['config']['template_realdir'])) {
330
                        $paths[] = $app['config']['template_realdir'];
331 168
                    }
332
                    $paths[] = $app['config']['template_default_realdir'];
333
                    $paths[] = __DIR__.'/../../app/Plugin';
334
                    $cache = $cacheBaseDir.$app['config']['template_code'];
335
                    $app['front'] = true;
336
                }
337
                $twig->setCache($cache);
338
                $app['twig.loader']->addLoader(new \Twig_Loader_Filesystem($paths));
339
340
                return $twig;
341
            }));
342
343
            // 管理画面のIP制限チェック.
344
            $pathinfo = rawurldecode($app['request']->getPathInfo());
345
            if (strpos($pathinfo, '/'.trim($app['config']['admin_route'], '/').'/') === 0) {
346
                // IP制限チェック
347 769
                $allowHost = $app['config']['admin_allow_host'];
348
                if (count($allowHost) > 0) {
349
                    if (array_search($app['request']->getClientIp(), $allowHost) === false) {
350
                        throw new \Exception();
351
                    }
352
                }
353
            }
354
        }, self::EARLY_EVENT);
355
356 101
        // twigのグローバル変数を定義.
357
        $app = $this;
358
        $this->on(\Symfony\Component\HttpKernel\KernelEvents::CONTROLLER, function(\Symfony\Component\HttpKernel\Event\FilterControllerEvent $event) use ($app) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space after FUNCTION keyword; 0 found
Loading history...
359
            // ショップ基本情報
360
            $BaseInfo = $app['eccube.repository.base_info']->get();
361
            $app['twig']->addGlobal('BaseInfo', $BaseInfo);
362
363
            $pathinfo = rawurldecode($app['request']->getPathInfo());
364 98
            if (strpos($pathinfo, '/'.trim($app['config']['admin_route'], '/').'/') === 0) {
365
                // 管理画面
366
                // 管理画面メニュー
367
                $menus = array('', '', '');
368 98
                $app['twig']->addGlobal('menus', $menus);
369
370
                $Member = $app->user();
371
                if (is_object($Member)) {
372
                    // ログインしていれば管理者のロールを取得
373
                    $AuthorityRoles = $app['eccube.repository.authority_role']->findBy(array('Authority' => $Member->getAuthority()));
374
375
                    $roles = array();
376
                    foreach ($AuthorityRoles as $AuthorityRole) {
377
                        // 管理画面でメニュー制御するため相対パス全てをセット
378
                        $roles[] = $app['request']->getBaseUrl().'/'.$app['config']['admin_route'].$AuthorityRole->getDenyUrl();
379
                    }
380
381 2
                    $app['twig']->addGlobal('AuthorityRoles', $roles);
382
                }
383
0 ignored issues
show
Coding Style introduced by
Blank line found at end of control structure
Loading history...
384
            } else {
385 2
                // フロント画面
386
                $request = $event->getRequest();
387
                $route = $request->attributes->get('_route');
388
389
                // ユーザ作成画面
390
                if ($route === trim($app['config']['user_data_route'])) {
391
                    $params = $request->attributes->get('_route_params');
392
                    $route = $params['route'];
393 34
                    // プレビュー画面
394
                } elseif ($request->get('preview')) {
395
                    $route = 'preview';
396
                }
397 101
398
                try {
399 769
                    $DeviceType = $app['eccube.repository.master.device_type']
400
                        ->find(\Eccube\Entity\Master\DeviceType::DEVICE_TYPE_PC);
401 769
                    $PageLayout = $app['eccube.repository.page_layout']->getByUrl($DeviceType, $route);
402
                } catch (\Doctrine\ORM\NoResultException $e) {
403
                    $PageLayout = $app['eccube.repository.page_layout']->newPageLayout($DeviceType);
404
                }
405
406
                $app['twig']->addGlobal('PageLayout', $PageLayout);
407
                $app['twig']->addGlobal('title', $PageLayout->getName());
408
            }
409
        });
410
    }
411
412
    public function initMailer()
0 ignored issues
show
introduced by
Missing function doc comment
Loading history...
413
    {
414
415
        // メール送信時の文字エンコード指定(デフォルトはUTF-8)
0 ignored issues
show
Unused Code Comprehensibility introduced by
43% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
416
        if (isset($this['config']['mail']['charset_iso_2022_jp']) && is_bool($this['config']['mail']['charset_iso_2022_jp'])) {
417
            if ($this['config']['mail']['charset_iso_2022_jp'] === true) {
418
                \Swift::init(function() {
0 ignored issues
show
Coding Style introduced by
Expected 1 space after FUNCTION keyword; 0 found
Loading history...
419
                    \Swift_DependencyContainer::getInstance()
420
                        ->register('mime.qpheaderencoder')
421
                        ->asAliasOf('mime.base64headerencoder');
422
                    \Swift_Preferences::getInstance()->setCharset('iso-2022-jp');
423
                });
424 769
            }
425
        }
426 769
427
        $this->register(new \Silex\Provider\SwiftmailerServiceProvider());
428
        $this['swiftmailer.options'] = $this['config']['mail'];
429 769
430
        if (isset($this['config']['mail']['spool']) && is_bool($this['config']['mail']['spool'])) {
431 769
            $this['swiftmailer.use_spool'] = $this['config']['mail']['spool'];
432
        }
433
        // デフォルトはsmtpを使用
434
        $transport = $this['config']['mail']['transport'];
435 769
        if ($transport == 'sendmail') {
436
            $this['swiftmailer.transport'] = \Swift_SendmailTransport::newInstance();
437
        } elseif ($transport == 'mail') {
438
            $this['swiftmailer.transport'] = \Swift_MailTransport::newInstance();
439
        }
440 769
    }
441 768
442 769
    public function initDoctrine()
0 ignored issues
show
introduced by
Missing function doc comment
Loading history...
443 769
    {
444
        $this->register(new \Silex\Provider\DoctrineServiceProvider(), array(
0 ignored issues
show
introduced by
Add a comma after each item in a multi-line array
Loading history...
445
            'dbs.options' => array(
0 ignored issues
show
introduced by
Add a comma after each item in a multi-line array
Loading history...
446 769
                'default' => $this['config']['database']
447
        )));
448 769
        $this->register(new \Saxulum\DoctrineOrmManagerRegistry\Silex\Provider\DoctrineOrmManagerRegistryProvider());
449 769
450
        // プラグインのmetadata定義を合わせて行う.
451 769
        $pluginBasePath = __DIR__.'/../../app/Plugin';
452 769
        $finder = Finder::create()
453 769
            ->in($pluginBasePath)
454 769
            ->directories()
455
            ->depth(0);
456
457
        $ormMappings = array();
458
        $ormMappings[] = array(
459
            'type' => 'yml',
460
            'namespace' => 'Eccube\Entity',
461
            'path' => array(
462
                __DIR__.'/Resource/doctrine',
463
                __DIR__.'/Resource/doctrine/master',
464
            ),
465
        );
466
467
        foreach ($finder as $dir) {
0 ignored issues
show
Coding Style introduced by
Blank line found at start of control structure
Loading history...
468
469
            $file = $dir->getRealPath().'/config.yml';
470
471
            if (file_exists($file)) {
472
                $config = Yaml::parse(file_get_contents($file));
473
            } else {
474
                $code = $dir->getBaseName();
475
                $this['monolog']->warning("skip {$code} orm.path loading. config.yml not found.", array('path' => $file));
476
                continue;
477
            }
478
479
            // Doctrine Extend
480 769
            if (isset($config['orm.path']) && is_array($config['orm.path'])) {
481
                $paths = array();
482
                foreach ($config['orm.path'] as $path) {
483 769
                    $paths[] = $pluginBasePath.'/'.$config['code'].$path;
484
                }
485
                $ormMappings[] = array(
486 769
                    'type' => 'yml',
487
                    'namespace' => 'Plugin\\'.$config['code'].'\\Entity',
488 769
                    'path' => $paths,
489
                );
490 769
            }
491
        }
492
493
        $this->register(new \Dflydev\Silex\Provider\DoctrineOrm\DoctrineOrmServiceProvider(), array(
494
            'orm.proxies_dir' => __DIR__.'/../../app/cache/doctrine',
495 769
            'orm.em.options' => array(
496
                'mappings' => $ormMappings,
497
            ),
498
        ));
499
    }
500
501 769
    public function initSecurity()
0 ignored issues
show
introduced by
Missing function doc comment
Loading history...
502 769
    {
503 769
        $this->register(new \Silex\Provider\SecurityServiceProvider());
504 769
        $this->register(new \Silex\Provider\RememberMeServiceProvider());
505 769
506
        $this['security.firewalls'] = array(
507
            'admin' => array(
508
                'pattern' => "^/{$this['config']['admin_route']}/",
509 769
                'form' => array(
510
                    'login_path' => "/{$this['config']['admin_route']}/login",
511 769
                    'check_path' => "/{$this['config']['admin_route']}/login_check",
512
                    'username_parameter' => 'login_id',
513
                    'password_parameter' => 'password',
514 769
                    'with_csrf' => true,
515
                    'use_forward' => true,
516
                ),
517
                'logout' => array(
518
                    'logout_path' => "/{$this['config']['admin_route']}/logout",
519
                    'target_url' => "/{$this['config']['admin_route']}/",
520
                ),
521
                'users' => $this['orm.em']->getRepository('Eccube\Entity\Member'),
522 769
                'anonymous' => true,
523
            ),
524
            'customer' => array(
525
                'pattern' => '^/',
526 769
                'form' => array(
527
                    'login_path' => '/mypage/login',
528
                    'check_path' => '/login_check',
529 769
                    'username_parameter' => 'login_email',
530
                    'password_parameter' => 'login_pass',
531
                    'with_csrf' => true,
532
                    'use_forward' => true,
533 769
                ),
534 769
                'logout' => array(
535 769
                    'logout_path' => '/logout',
536 769
                    'target_url' => '/',
537
                ),
538
                'remember_me' => array(
539 769
                    'key' => sha1($this['config']['auth_magic']),
540
                    'name' => 'eccube_rememberme',
541
                    // lifetimeはデフォルトの1年間にする
542
                    // 'lifetime' => $this['config']['cookie_lifetime'],
0 ignored issues
show
Unused Code Comprehensibility introduced by
77% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
543 769
                    'path' => $this['config']['root_urlpath'] ?: '/',
544
                    'secure' => $this['config']['force_ssl'],
545
                    'httponly' => true,
546 769
                    'always_remember_me' => false,
547 769
                    'remember_me_parameter' => 'login_memory',
548 769
                ),
549 769
                'users' => $this['orm.em']->getRepository('Eccube\Entity\Customer'),
550
                'anonymous' => true,
551
            ),
552
        );
553
554
        $this['security.access_rules'] = array(
555
            array("^/{$this['config']['admin_route']}/login", 'IS_AUTHENTICATED_ANONYMOUSLY'),
556
            array("^/{$this['config']['admin_route']}/", 'ROLE_ADMIN'),
557 769
            array('^/mypage/login', 'IS_AUTHENTICATED_ANONYMOUSLY'),
558 769
            array('^/mypage/withdraw_complete', 'IS_AUTHENTICATED_ANONYMOUSLY'),
559
            array('^/mypage/change', 'IS_AUTHENTICATED_FULLY'),
560
            array('^/mypage', 'ROLE_USER'),
561
        );
562
563
        $this['eccube.password_encoder'] = $this->share(function($app) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space after FUNCTION keyword; 0 found
Loading history...
564
            return new \Eccube\Security\Core\Encoder\PasswordEncoder($app['config']);
565
        });
566
        $this['security.encoder_factory'] = $this->share(function($app) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space after FUNCTION keyword; 0 found
Loading history...
567
            return new \Symfony\Component\Security\Core\Encoder\EncoderFactory(array(
568
                'Eccube\Entity\Customer' => $app['eccube.password_encoder'],
569
                'Eccube\Entity\Member' => $app['eccube.password_encoder'],
570
            ));
571
        });
572
        $this['eccube.event_listner.security'] = $this->share(function($app) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space after FUNCTION keyword; 0 found
Loading history...
573
            return new \Eccube\EventListener\SecurityEventListener($app['orm.em']);
574 769
        });
575
        $this['user'] = function($app) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space after FUNCTION keyword; 0 found
Loading history...
576
            $token = $app['security']->getToken();
577
578
            return ($token !== null) ? $token->getUser() : null;
579
        };
580
581
        // ログイン時のイベントを設定.
582 769
        $this['dispatcher']->addListener(\Symfony\Component\Security\Http\SecurityEvents::INTERACTIVE_LOGIN, array($this['eccube.event_listner.security'], 'onInteractiveLogin'));
583
584
        // Voterの設定
585
        $app = $this;
586
        $this['authority_voter'] = $this->share(function($app) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space after FUNCTION keyword; 0 found
Loading history...
587
            return new \Eccube\Security\Voter\AuthorityVoter($app);
588
        });
589 769
590
        $app['security.voters'] = $app->extend('security.voters', function($voters) use ($app) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space after FUNCTION keyword; 0 found
Loading history...
591
            $voters[] = $app['authority_voter'];
592
593
            return $voters;
594
        });
595
596
        $this['security.access_manager'] = $this->share(function($app) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space after FUNCTION keyword; 0 found
Loading history...
597
            return new \Symfony\Component\Security\Core\Authorization\AccessDecisionManager($app['security.voters'], 'unanimous');
598
        });
599
600
    }
601
602
    public function initializePlugin()
0 ignored issues
show
introduced by
Missing function doc comment
Loading history...
603
    {
604
        if ($this->initializedPlugin) {
605
            return;
606 769
        }
607
608
        // setup event dispatcher
609
        $this->initPluginEventDispatcher();
610
611
        // load plugin
612
        $this->loadPlugin();
613
614
        $this->initializedPlugin = true;
615
    }
616
617
    public function initPluginEventDispatcher()
0 ignored issues
show
introduced by
Missing function doc comment
Loading history...
618
    {
619
        // EventDispatcher
620
        $this['eccube.event.dispatcher'] = $this->share(function() {
0 ignored issues
show
Coding Style introduced by
Expected 1 space after FUNCTION keyword; 0 found
Loading history...
621
            return new EventDispatcher();
622
        });
623
624
        // hook point
625
        $this->before(function(Request $request, \Silex\Application $app) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space after FUNCTION keyword; 0 found
Loading history...
626
            $app['eccube.event.dispatcher']->dispatch('eccube.event.app.before');
627
        }, self::EARLY_EVENT);
628
629
        $this->before(function(Request $request, \Silex\Application $app) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space after FUNCTION keyword; 0 found
Loading history...
630
            $event = 'eccube.event.controller.'.$request->attributes->get('_route').'.before';
631
            $app['eccube.event.dispatcher']->dispatch($event);
632
        });
633
634 View Code Duplication
        $this->after(function(Request $request, Response $response, \Silex\Application $app) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space after FUNCTION keyword; 0 found
Loading history...
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
635
            $event = 'eccube.event.controller.'.$request->attributes->get('_route').'.after';
636
            $app['eccube.event.dispatcher']->dispatch($event);
637 769
        });
638
639
        $this->after(function(Request $request, Response $response, \Silex\Application $app) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space after FUNCTION keyword; 0 found
Loading history...
640
            $app['eccube.event.dispatcher']->dispatch('eccube.event.app.after');
641
        }, self::LATE_EVENT);
642 769
643 View Code Duplication
        $this->finish(function(Request $request, Response $response, \Silex\Application $app) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
Coding Style introduced by
Expected 1 space after FUNCTION keyword; 0 found
Loading history...
644
            $event = 'eccube.event.controller.'.$request->attributes->get('_route').'.finish';
645
            $app['eccube.event.dispatcher']->dispatch($event);
646
        });
647
648
        $app = $this;
649
        $this->on(\Symfony\Component\HttpKernel\KernelEvents::RESPONSE, function(\Symfony\Component\HttpKernel\Event\FilterResponseEvent $event) use ($app) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space after FUNCTION keyword; 0 found
Loading history...
650
            $route = $event->getRequest()->attributes->get('_route');
651
            $app['eccube.event.dispatcher']->dispatch('eccube.event.render.'.$route.'.before', $event);
652
        });
653
654
        // Request Event
655 View Code Duplication
        $this->on(\Symfony\Component\HttpKernel\KernelEvents::REQUEST, function(\Symfony\Component\HttpKernel\Event\GetResponseEvent $event) use ($app) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
Coding Style introduced by
Expected 1 space after FUNCTION keyword; 0 found
Loading history...
656
657
            if (\Symfony\Component\HttpKernel\HttpKernelInterface::MASTER_REQUEST !== $event->getRequestType()) {
658
                return;
659
            }
660
661
            $route = $event->getRequest()->attributes->get('_route');
662
663
            if (is_null($route)) {
664
                return;
665
            }
666
667
            $app['monolog']->debug('KernelEvents::REQUEST '.$route);
668
669
            // 全体
670
            $app['eccube.event.dispatcher']->dispatch('eccube.event.app.request', $event);
671
672
            if (strpos($route, 'admin') === 0) {
673
                // 管理画面
674
                $app['eccube.event.dispatcher']->dispatch('eccube.event.admin.request', $event);
675
            } else {
676
                // フロント画面
677
                $app['eccube.event.dispatcher']->dispatch('eccube.event.front.request', $event);
678
            }
679
680
            // ルーティング単位
681
            $app['eccube.event.dispatcher']->dispatch("eccube.event.route.{$route}.request", $event);
682
683
        }, 30); // Routing(32)が解決しし, 認証判定(8)が実行される前のタイミング.
0 ignored issues
show
Unused Code Comprehensibility introduced by
50% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
684
685
        // Controller Event
686 View Code Duplication
        $this->on(\Symfony\Component\HttpKernel\KernelEvents::CONTROLLER, function(\Symfony\Component\HttpKernel\Event\FilterControllerEvent $event) use ($app) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
Coding Style introduced by
Expected 1 space after FUNCTION keyword; 0 found
Loading history...
687
688
            if (\Symfony\Component\HttpKernel\HttpKernelInterface::MASTER_REQUEST !== $event->getRequestType()) {
689
                return;
690
            }
691
692
693
            $route = $event->getRequest()->attributes->get('_route');
694
695
            if (is_null($route)) {
696
                return;
697
            }
698
699
            $app['monolog']->debug('KernelEvents::CONTROLLER '.$route);
700
701
            // 全体
702
            $app['eccube.event.dispatcher']->dispatch('eccube.event.app.controller', $event);
703
704
            if (strpos($route, 'admin') === 0) {
705
                // 管理画面
706
                $app['eccube.event.dispatcher']->dispatch('eccube.event.admin.controller', $event);
707
            } else {
708
                // フロント画面
709
                $app['eccube.event.dispatcher']->dispatch('eccube.event.front.controller', $event);
710
            }
711
712
            // ルーティング単位
713
            $app['eccube.event.dispatcher']->dispatch("eccube.event.route.{$route}.controller", $event);
714
        });
715
716
        // Response Event
717 View Code Duplication
        $this->on(\Symfony\Component\HttpKernel\KernelEvents::RESPONSE, function(\Symfony\Component\HttpKernel\Event\FilterResponseEvent $event) use ($app) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
Coding Style introduced by
Expected 1 space after FUNCTION keyword; 0 found
Loading history...
718
719
            if (\Symfony\Component\HttpKernel\HttpKernelInterface::MASTER_REQUEST !== $event->getRequestType()) {
720
                return;
721
            }
722
723
            $route = $event->getRequest()->attributes->get('_route');
724
725
            if (is_null($route)) {
726
                return;
727
            }
728
729
            $app['monolog']->debug('KernelEvents::RESPONSE '.$route);
730
731
            // ルーティング単位
732
            $app['eccube.event.dispatcher']->dispatch("eccube.event.route.{$route}.response", $event);
733
734
            if (strpos($route, 'admin') === 0) {
735
                // 管理画面
736
                $app['eccube.event.dispatcher']->dispatch('eccube.event.admin.response', $event);
737
            } else {
738
                // フロント画面
739
                $app['eccube.event.dispatcher']->dispatch('eccube.event.front.response', $event);
740
            }
741
742
            // 全体
743
            $app['eccube.event.dispatcher']->dispatch('eccube.event.app.response', $event);
744
        });
745
746
        // Exception Event
747 View Code Duplication
        $this->on(\Symfony\Component\HttpKernel\KernelEvents::EXCEPTION, function(\Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent $event) use ($app) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
Coding Style introduced by
Expected 1 space after FUNCTION keyword; 0 found
Loading history...
748
749
            if (\Symfony\Component\HttpKernel\HttpKernelInterface::MASTER_REQUEST !== $event->getRequestType()) {
750
                return;
751
            }
752
753
            $route = $event->getRequest()->attributes->get('_route');
754
755
            if (is_null($route)) {
756
                return;
757
            }
758
759
            $app['monolog']->debug('KernelEvents::EXCEPTION '.$route);
760
761
            // ルーティング単位
762
            $app['eccube.event.dispatcher']->dispatch("eccube.event.route.{$route}.exception", $event);
763
764 769
            if (strpos($route, 'admin') === 0) {
765
                // 管理画面
766
                $app['eccube.event.dispatcher']->dispatch('eccube.event.admin.exception', $event);
767 769
            } else {
768
                // フロント画面
769
                $app['eccube.event.dispatcher']->dispatch('eccube.event.front.exception', $event);
770
            }
771
772
            // 全体
773
            $app['eccube.event.dispatcher']->dispatch('eccube.event.app.exception', $event);
774
        });
775
776
        // Terminate Event
777 View Code Duplication
        $this->on(\Symfony\Component\HttpKernel\KernelEvents::TERMINATE, function(\Symfony\Component\HttpKernel\Event\PostResponseEvent $event) use ($app) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
Coding Style introduced by
Expected 1 space after FUNCTION keyword; 0 found
Loading history...
778
779
            $route = $event->getRequest()->attributes->get('_route');
780
781
            if (is_null($route)) {
782
                return;
783
            }
784
785
            $app['monolog']->debug('KernelEvents::TERMINATE '.$route);
786
787
            // ルーティング単位
788
            $app['eccube.event.dispatcher']->dispatch("eccube.event.route.{$route}.terminate", $event);
789
790
            if (strpos($route, 'admin') === 0) {
791
                // 管理画面
792
                $app['eccube.event.dispatcher']->dispatch('eccube.event.admin.terminate', $event);
793
            } else {
794
                // フロント画面
795
                $app['eccube.event.dispatcher']->dispatch('eccube.event.front.terminate', $event);
796
            }
797
798
            // 全体
799
            $app['eccube.event.dispatcher']->dispatch('eccube.event.app.terminate', $event);
800
        });
801
    }
802
803
    public function loadPlugin()
0 ignored issues
show
introduced by
Missing function doc comment
Loading history...
804
    {
805
        // プラグインディレクトリを探索.
806
        $basePath = __DIR__.'/../../app/Plugin';
807
        $finder = Finder::create()
808
            ->in($basePath)
809
            ->directories()
810
            ->depth(0);
811
812
        $finder->sortByName();
813
814
        // ハンドラ優先順位をdbから持ってきてハッシュテーブルを作成
815
        $priorities = array();
816
        $handlers = $this['orm.em']
817
            ->getRepository('Eccube\Entity\PluginEventHandler')
818
            ->getHandlers();
819
        foreach ($handlers as $handler) {
820
            if ($handler->getPlugin()->getEnable() && !$handler->getPlugin()->getDelFlg()) {
0 ignored issues
show
Coding Style introduced by
Blank line found at start of control structure
Loading history...
821
822
                $priority = $handler->getPriority();
823
            } else {
824
                // Pluginがdisable、削除済みの場合、EventHandlerのPriorityを全て0とみなす
825
                $priority = \Eccube\Entity\PluginEventHandler::EVENT_PRIORITY_DISABLED;
826
            }
827
            $priorities[$handler->getPlugin()->getClassName()][$handler->getEvent()][$handler->getHandler()] = $priority;
828
        }
829
830
        // プラグインをロードする.
831
        // config.yml/event.ymlの定義に沿ってインスタンスの生成を行い, イベント設定を行う.
832
        foreach ($finder as $dir) {
833
            //config.ymlのないディレクトリは無視する
834
            $path = $dir->getRealPath();
835
            $code = $dir->getBaseName();
836
            try {
837
                $this['eccube.service.plugin']->checkPluginArchiveContent($path);
838
            } catch (\Eccube\Exception\PluginException $e) {
839
                $this['monolog']->warning("skip {$code} config loading. config.yml not foud or invalid.", array(
0 ignored issues
show
introduced by
Add a comma after each item in a multi-line array
Loading history...
840
                    'path' =>  $path,
841
                    'original-message' => $e->getMessage()
842
                ));
843
                continue;
844
            }
845
            $config = $this['eccube.service.plugin']->readYml($dir->getRealPath().'/config.yml');
846
847
            $plugin = $this['orm.em']
848
                ->getRepository('Eccube\Entity\Plugin')
849
                ->findOneBy(array('code' => $config['code']));
850
851
            // const
852
            if (isset($config['const'])) {
853
                $this['config'] = $this->share($this->extend('config', function($eccubeConfig) use ($config) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space after FUNCTION keyword; 0 found
Loading history...
854
                    $eccubeConfig[$config['code']] = array(
855
                        'const' => $config['const'],
856
                    );
857
858
                    return $eccubeConfig;
859
                }));
860
            }
861
862
            if ($plugin && $plugin->getEnable() == Constant::DISABLED) {
863
                // プラグインが無効化されていれば読み込まない
864
                continue;
865
            }
866
867
            // Type: Event
868
            if (isset($config['event'])) {
869
                $class = '\\Plugin\\'.$config['code'].'\\'.$config['event'];
870
                $eventExists = true;
871
872 View Code Duplication
                if (!class_exists($class)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
873
                    $this['monolog']->warning("skip {$code} loading. event class not foud.", array(
874
                        'class' =>  $class,
875
                    ));
876
                    $eventExists = false;
877
                }
878
879
                if ($eventExists && file_exists($dir->getRealPath().'/event.yml')) {
0 ignored issues
show
Coding Style introduced by
Blank line found at start of control structure
Loading history...
880
881
                    $subscriber = new $class($this);
882
883
                    foreach (Yaml::parse(file_get_contents($dir->getRealPath().'/event.yml')) as $event => $handlers) {
884
                        foreach ($handlers as $handler) {
885
                            if (!isset($priorities[$config['event']][$event][$handler[0]])) { // ハンドラテーブルに登録されていない(ソースにしか記述されていない)ハンドラは一番後ろにする
886
                                $priority = \Eccube\Entity\PluginEventHandler::EVENT_PRIORITY_LATEST;
887
                            } else {
888
                                $priority = $priorities[$config['event']][$event][$handler[0]];
889
                            }
890
                            // 優先度が0のプラグインは登録しない
891
                            if (\Eccube\Entity\PluginEventHandler::EVENT_PRIORITY_DISABLED != $priority) {
892
                                $this['eccube.event.dispatcher']->addListener($event, array($subscriber, $handler[0]), $priority);
893
                            }
894
                        }
895
                    }
896
                }
897
            }
898
            // Type: ServiceProvider
899
            if (isset($config['service'])) {
900
                foreach ($config['service'] as $service) {
901
                    $class = '\\Plugin\\'.$config['code'].'\\ServiceProvider\\'.$service;
902 View Code Duplication
                    if (!class_exists($class)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
903
                        $this['monolog']->warning("skip {$code} loading. service provider class not foud.", array(
904
                            'class' =>  $class,
905
                        ));
906
                        continue;
907
                    }
908
                    $this->register(new $class($this));
909
                }
910
            }
911
        }
912
    }
913
914
    /**
915
     *
916
     * データベースの接続を確認
917
     * 成功 : trueを返却
918
     * 失敗 : \Doctrine\DBAL\DBALExceptionエラーが発生( 接続に失敗した場合 )、エラー画面を表示しdie()
919
     * 備考 : app['debug']がtrueの際は処理を行わない
920
     * @return boolean true
921
     *
922
     */
923
    protected function checkDatabaseConnection()
924
    {
925
        if ($this['debug']) {
926
            return;
927
        }
928
        try {
929
            $this['db']->connect();
930
        } catch (\Doctrine\DBAL\DBALException $e) {
931
            $this['monolog']->error($e->getMessage());
932
            $this['twig.path'] = array(__DIR__.'/Resource/template/exception');
933
            $html = $this['twig']->render('error.twig', array(
934
                'error_title' => 'データーベース接続エラー',
935
                'error_message' => 'データーベースを確認してください',
936
            ));
937
            $response = new Response();
938
            $response->setContent($html);
939
            $response->setStatusCode('500');
940
            $response->headers->set('Content-Type', 'text/html');
941
            $response->send();
942
            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...
943
        }
944
        return true;
0 ignored issues
show
introduced by
Missing blank line before return statement
Loading history...
945
    }
946
947
    /**
948
     * セッションが開始されているかどうか.
949
     *
950
     * @return boolean セッションが開始済みの場合 true
951
     * @link http://php.net/manual/ja/function.session-status.php#113468
952
     */
953
    protected function isSessionStarted()
954
    {
955
        if (php_sapi_name() !== 'cli') {
956
            if (version_compare(phpversion(), '5.4.0', '>=')) {
957
                return session_status() === PHP_SESSION_ACTIVE ? true : false;
958
            } else {
959
                return session_id() === '' ? false : true;
960
            }
961
        }
962
        return false;
0 ignored issues
show
introduced by
Missing blank line before return statement
Loading history...
963
    }
964
}
965