Completed
Pull Request — master (#1662)
by Kentaro
73:39 queued 40:38
created

Application::isTestMode()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

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