Completed
Pull Request — master (#1392)
by Kentaro
16:05
created

Application::initSession()   A

Complexity

Conditions 2
Paths 1

Size

Total Lines 14
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 2

Importance

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

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
695
                        foreach ($handlers as $handler) {
696
                            if (!isset($priorities[$config['event']][$event][$handler[0]])) { // ハンドラテーブルに登録されていない(ソースにしか記述されていない)ハンドラは一番後ろにする
697
                                $priority = \Eccube\Entity\PluginEventHandler::EVENT_PRIORITY_LATEST;
698
                            } else {
699
                                $priority = $priorities[$config['event']][$event][$handler[0]];
700
                            }
701
                            // 優先度が0のプラグインは登録しない
702
                            if (\Eccube\Entity\PluginEventHandler::EVENT_PRIORITY_DISABLED != $priority) {
703
                                $this['eccube.event.dispatcher']->addListener($event, array($subscriber, $handler[0]), $priority);
704
                            }
705
                        }
706
                    }
707
                }
708
            }
709
            // Type: ServiceProvider
710
            if (isset($config['service'])) {
711
                foreach ($config['service'] as $service) {
712
                    $class = '\\Plugin\\'.$config['code'].'\\ServiceProvider\\'.$service;
713
                    $this->register(new $class($this));
714
                }
715
            }
716
        }
717
    }
718
}
719