Failed Conditions
Push — master ( 336183...daf744 )
by Kentaro
39:43
created

Application::clearInstance()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 1
CRAP Score 1.2963

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 4
ccs 1
cts 3
cp 0.3333
rs 10
cc 1
eloc 2
nc 1
nop 0
crap 1.2963
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\Yaml\Yaml;
33
34
class Application extends ApplicationTrait
0 ignored issues
show
introduced by
Missing class doc comment
Loading history...
35
{
36
    protected static $instance;
37
38
    protected $initialized = false;
39
    protected $initializedPlugin = false;
40
41
    public static function getInstance(array $values = array())
0 ignored issues
show
introduced by
Missing function doc comment
Loading history...
42
    {
43
        if (!is_object(self::$instance)) {
44
            self::$instance = new Application($values);
45
        }
46
47
        return self::$instance;
48
    }
49
50
    public static function clearInstance()
0 ignored issues
show
introduced by
Missing function doc comment
Loading history...
51
    {
52
        self::$instance = null;
53 712
    }
54
55
    final public function __clone()
0 ignored issues
show
introduced by
Missing function doc comment
Loading history...
56
    {
57 700
        throw new \Exception('Clone is not allowed against '.get_class($this));
58 700
    }
59
60 700
    public function __construct(array $values = array())
0 ignored issues
show
introduced by
Missing function doc comment
Loading history...
61 700
    {
62
        parent::__construct($values);
63
64
        if (is_null(self::$instance)) {
65
            self::$instance = $this;
66 700
        }
67 700
68
        // load config
69
        $this->initConfig();
70
71
        // init monolog
72 700
        $this->initLogger();
73 700
    }
74
75
    public function initConfig()
0 ignored issues
show
introduced by
Missing function doc comment
Loading history...
76
    {
77
        // load config
78 700
        $this['config'] = $this->share(function() {
79 700
            $ymlPath = __DIR__.'/../../app/config/eccube';
80
            $distPath = __DIR__.'/../../src/Eccube/Resource/config';
81
82
            $config = array();
83
            $config_yml = $ymlPath.'/config.yml';
84
            if (file_exists($config_yml)) {
85 700
                $config = Yaml::parse(file_get_contents($config_yml));
86 700
            }
87
88
            $config_dist = array();
89
            $config_yml_dist = $distPath.'/config.yml.dist';
90
            if (file_exists($config_yml_dist)) {
91
                $config_dist = Yaml::parse(file_get_contents($config_yml_dist));
92
            }
93 700
94 700
            $config_path = array();
95
            $path_yml = $ymlPath.'/path.yml';
96
            if (file_exists($path_yml)) {
97
                $config_path = Yaml::parse(file_get_contents($path_yml));
98
            }
99 700
100 700
            $config_constant = array();
101
            $constant_yml = $ymlPath.'/constant.yml';
102
            if (file_exists($constant_yml)) {
103
                $config_constant = Yaml::parse(file_get_contents($constant_yml));
104
                $config_constant = empty($config_constant) ? array() : $config_constant;
105
            }
106 700
107 700
            $config_constant_dist = array();
108
            $constant_yml_dist = $distPath.'/constant.yml.dist';
109
            if (file_exists($constant_yml_dist)) {
110
                $config_constant_dist = Yaml::parse(file_get_contents($constant_yml_dist));
111 700
            }
112 700
113
            $configAll = array_replace_recursive($config_constant_dist, $config_dist, $config_constant, $config_path, $config);
114
115
            $database = array();
116
            $yml = $ymlPath.'/database.yml';
117
            if (file_exists($yml)) {
118
                $database = Yaml::parse(file_get_contents($yml));
119 700
            }
120 700
121
            $mail = array();
122
            $yml = $ymlPath.'/mail.yml';
123
            if (file_exists($yml)) {
124 700
                $mail = Yaml::parse(file_get_contents($yml));
125 700
            }
126
            $configAll = array_replace_recursive($configAll, $database, $mail);
127
128
            $config_log = array();
129
            $yml = $ymlPath.'/log.yml';
130
            if (file_exists($yml)) {
131
                $config_log = Yaml::parse(file_get_contents($yml));
132 700
            }
133
            $config_log_dist = array();
134 712
            $log_yml_dist = $distPath.'/log.yml.dist';
135
            if (file_exists($log_yml_dist)) {
136 712
                $config_log_dist = Yaml::parse(file_get_contents($log_yml_dist));
137
            }
138 712
139
            $configAll = array_replace_recursive($configAll, $config_log_dist, $config_log);
140
141
            $config_nav = array();
142 712
            $yml = $ymlPath.'/nav.yml';
143
            if (file_exists($yml)) {
144 697
                $config_nav = array('nav' => Yaml::parse(file_get_contents($yml)));
145
            }
146
            $config_nav_dist = array();
147
            $nav_yml_dist = $distPath.'/nav.yml.dist';
148
            if (file_exists($nav_yml_dist)) {
149
                $config_nav_dist = array('nav' => Yaml::parse(file_get_contents($nav_yml_dist)));
150
            }
151
152
            $configAll = array_replace_recursive($configAll, $config_nav_dist, $config_nav);
153
154
            return $configAll;
155
        });
156
    }
157
158
    public function initLogger()
0 ignored issues
show
introduced by
Missing function doc comment
Loading history...
159
    {
160
        $app = $this;
161
        $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...
162 697
        $this['monolog.logfile'] = __DIR__.'/../../app/log/site.log';
163
        $this['monolog.name'] = 'eccube';
164
    }
165 5
166
    public function initialize()
0 ignored issues
show
introduced by
Missing function doc comment
Loading history...
167
    {
168
        if ($this->initialized) {
169
            return;
170
        }
171
172
        // init locale
173
        $this->initLocale();
174
175
        // init session
176
        $this->initSession();
177
178
        // init twig
179
        $this->initRendering();
180
181
        // init provider
182
        $this->register(new \Silex\Provider\HttpFragmentServiceProvider());
183
        $this->register(new \Silex\Provider\UrlGeneratorServiceProvider());
184
        $this->register(new \Silex\Provider\FormServiceProvider());
185
        $this->register(new \Silex\Provider\SerializerServiceProvider());
186
        $this->register(new \Eccube\ServiceProvider\ValidatorServiceProvider());
187
188
        $app = $this;
189
        $this->error(function(\Exception $e, $code) use ($app) {
190
            if ($app['debug']) {
191
                return;
192
            }
193
194
            switch ($code) {
195
                case 403:
196
                    $title = 'アクセスできません。';
197
                    $message = 'お探しのページはアクセスができない状況にあるか、移動もしくは削除された可能性があります。';
198
                    break;
199
                case 404:
200
                    $title = 'ページがみつかりません。';
201
                    $message = 'URLに間違いがないかご確認ください。';
202
                    break;
203
                default:
204
                    $title = 'システムエラーが発生しました。';
205
                    $message = '大変お手数ですが、サイト管理者までご連絡ください。';
206 697
                    break;
207
            }
208 697
209
            return $app['twig']->render('error.twig', array(
210
                'error_title' => $title,
211
                'error_message' => $message,
212
            ));
213
        });
214
215
        // init mailer
216
        $this->initMailer();
217 697
218
        // init doctrine orm
219
        $this->initDoctrine();
220
221
        // init security
222
        $this->initSecurity();
223
224
        // init ec-cube service provider
225
        $this->register(new ServiceProvider\EccubeServiceProvider());
226
227
        // mount controllers
228
        $this->register(new \Silex\Provider\ServiceControllerServiceProvider());
229
        $this->mount('', new ControllerProvider\FrontControllerProvider());
230
        $this->mount('/'.trim($this['config']['admin_route'], '/').'/', new ControllerProvider\AdminControllerProvider());
231
        Request::enableHttpMethodParameterOverride(); // PUTやDELETEできるようにする
232
233
        $this->initialized = true;
234
    }
235
236
    public function initLocale()
0 ignored issues
show
introduced by
Missing function doc comment
Loading history...
237
    {
238 372
239
        // timezone
240 697
        if (!empty($this['config']['timezone'])) {
241
            date_default_timezone_set($this['config']['timezone']);
242 697
        }
243
244
        $this->register(new \Silex\Provider\TranslationServiceProvider(), array(
245
            'locale' => $this['config']['locale'],
246 697
        ));
247
        $this['translator'] = $this->share($this->extend('translator', function($translator, \Silex\Application $app) {
248 697
            $translator->addLoader('yaml', new \Symfony\Component\Translation\Loader\YamlFileLoader());
249 697
250 697
            $r = new \ReflectionClass('Symfony\Component\Validator\Validator');
251
            $file = dirname($r->getFilename()).'/Resources/translations/validators.'.$app['locale'].'.xlf';
252
            if (file_exists($file)) {
253 697
                $translator->addResource('xliff', $file, $app['locale'], 'validators');
254
            }
255 697
256
            $file = __DIR__.'/Resource/locale/validator.'.$app['locale'].'.yml';
257
            if (file_exists($file)) {
258
                $translator->addResource('yaml', $file, $app['locale'], 'validators');
259 697
            }
260
261
            $file = __DIR__.'/Resource/locale/message.'.$app['locale'].'.yml';
262
            if (file_exists($file)) {
263
                $translator->addResource('yaml', $file, $app['locale']);
264
            }
265
266 697
            return $translator;
267
        }));
268 697
    }
269
270
    public function initSession()
0 ignored issues
show
introduced by
Missing function doc comment
Loading history...
271
    {
272
        $this->register(new \Silex\Provider\SessionServiceProvider(), array(
273
            'session.storage.save_path' => $this['config']['root_dir'].'/app/cache/eccube/session',
274
            'session.storage.options' => array(
275
                'name' => 'eccube',
276
                'cookie_path' => $this['config']['root_urlpath'] ?: '/',
277 132
                'cookie_secure' => $this['config']['force_ssl'],
278
                'cookie_lifetime' => $this['config']['cookie_lifetime'],
279
                'cookie_httponly' => true,
280
                // cookie_domainは指定しない
281
                // http://blog.tokumaru.org/2011/10/cookiedomain.html
282
            ),
283 101
        ));
284
    }
285
286
    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 101
        ));
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 55
295
            return $twig;
296
        }));
297 55
298 55
        $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
                $paths = array();
302
303
                // 互換性がないのでprofiler とproduction 時のcacheを分離する
304 46
305
                if (isset($app['profiler'])) {
306 55
                    $cacheBaseDir = __DIR__.'/../../app/cache/twig/profiler/';
307
                } else {
308
                    $cacheBaseDir = __DIR__.'/../../app/cache/twig/production/';
309
                }
310 101
                if (strpos($app['request']->getPathInfo(), '/'.trim($app['config']['admin_route'], '/')) === 0) {
311
                    if (file_exists(__DIR__.'/../../app/template/admin')) {
312
                        $paths[] = __DIR__.'/../../app/template/admin';
313
                    }
314
                    $paths[] = $app['config']['template_admin_realdir'];
315
                    $paths[] = __DIR__.'/../../app/Plugin';
316
                    $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
                    $paths[] = __DIR__.'/../../app/Plugin';
323
                    $cache = $cacheBaseDir.$app['config']['template_code'];
324
                }
325
                $twig->setCache($cache);
326 697
                $app['twig.loader']->addLoader(new \Twig_Loader_Filesystem($paths));
327
328
                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 55
                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 52
        // twigのグローバル変数を定義.
344
        $app = $this;
345
        $this->on(\Symfony\Component\HttpKernel\KernelEvents::CONTROLLER, function(\Symfony\Component\HttpKernel\Event\FilterControllerEvent $event) use ($app) {
346
            // ショップ基本情報
347 52
            $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
                $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 2
361
                    $roles = array();
362
                    foreach ($AuthorityRoles as $AuthorityRole) {
363
                        // 管理画面でメニュー制御するため相対パス全てをセット
364 2
                        $roles[] = $app['request']->getBaseUrl().'/'.$app['config']['admin_route'].$AuthorityRole->getDenyUrl();
365
                    }
366
367
                    $app['twig']->addGlobal('AuthorityRoles', $roles);
368
                }
369
370
            } else {
371
                // フロント画面
372 23
                $request = $event->getRequest();
373
                $route = $request->attributes->get('_route');
374
375
                // ユーザ作成画面
376 55
                if ($route === trim($app['config']['user_data_route'])) {
377
                    $params = $request->attributes->get('_route_params');
378 697
                    $route = $params['route'];
379
                    // プレビュー画面
380 697
                } elseif ($request->get('preview')) {
381
                    $route = 'preview';
382
                }
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
                }
391
392
                $app['twig']->addGlobal('PageLayout', $PageLayout);
393
                $app['twig']->addGlobal('title', $PageLayout->getName());
394
            }
395
        });
396
    }
397
398
    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 697
            if ($this['config']['mail']['charset_iso_2022_jp'] === true) {
404
                \Swift::init(function() {
405 697
                    \Swift_DependencyContainer::getInstance()
406
                        ->register('mime.qpheaderencoder')
407
                        ->asAliasOf('mime.base64headerencoder');
408 697
                    \Swift_Preferences::getInstance()->setCharset('iso-2022-jp');
409
                });
410 697
            }
411
        }
412
413
        $this->register(new \Silex\Provider\SwiftmailerServiceProvider());
414 697
        $this['swiftmailer.options'] = $this['config']['mail'];
415 697
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 697
        $transport = $this['config']['mail']['transport'];
421 696
        if ($transport == 'sendmail') {
422 697
            $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 697
    {
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 697
            'dbs.options' => array(
0 ignored issues
show
introduced by
Add a comma after each item in a multi-line array
Loading history...
432 697
                'default' => $this['config']['database']
433 697
        )));
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...
434 697
        $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...
435
436
        // プラグインのmetadata定義を合わせて行う.
437
        $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...
438
        $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...
439
            ->in($pluginBasePath)
440
            ->directories()
441
            ->depth(0);
442
443
        $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...
444
        $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
            'type' => 'yml',
446
            'namespace' => 'Eccube\Entity',
447
            'path' => array(
448
                __DIR__.'/Resource/doctrine',
449
                __DIR__.'/Resource/doctrine/master',
450
            ),
451 697
        );
452
453
        foreach ($finder as $dir) {
454 697
            $config = Yaml::parse(file_get_contents($dir->getRealPath().'/config.yml'));
455
456
            // Doctrine Extend
457 697
            if (isset($config['orm.path']) && is_array($config['orm.path'])) {
458
                $paths = array();
459 697
                foreach ($config['orm.path'] as $path) {
460
                    $paths[] = $pluginBasePath.'/'.$config['code'].$path;
461 697
                }
462
                $ormMappings[] = array(
463
                    'type' => 'yml',
464
                    'namespace' => 'Plugin\\'.$config['code'].'\\Entity',
465
                    'path' => $paths,
466 697
                );
467
            }
468
        }
469
470
        $this->register(new \Dflydev\Silex\Provider\DoctrineOrm\DoctrineOrmServiceProvider(), array(
471
            'orm.proxies_dir' => __DIR__.'/../../app/cache/doctrine',
472 697
            'orm.em.options' => array(
473 697
                'mappings' => $ormMappings,
474 697
            ),
475 697
        ));
476 697
    }
477
478
    public function initSecurity()
0 ignored issues
show
introduced by
Missing function doc comment
Loading history...
479
    {
480 697
        $this->register(new \Silex\Provider\SecurityServiceProvider());
481
        $this->register(new \Silex\Provider\RememberMeServiceProvider());
482 697
483
        $this['security.firewalls'] = array(
484
            'admin' => array(
485 697
                'pattern' => "^/{$this['config']['admin_route']}",
486
                'form' => array(
487
                    'login_path' => "/{$this['config']['admin_route']}/login",
488
                    'check_path' => "/{$this['config']['admin_route']}/login_check",
489
                    'username_parameter' => 'login_id',
490
                    'password_parameter' => 'password',
491
                    'with_csrf' => true,
492
                    'use_forward' => true,
493 697
                ),
494
                'logout' => array(
495
                    'logout_path' => "/{$this['config']['admin_route']}/logout",
496
                    'target_url' => "/{$this['config']['admin_route']}/",
497 697
                ),
498
                'users' => $this['orm.em']->getRepository('Eccube\Entity\Member'),
499
                'anonymous' => true,
500 697
            ),
501
            'customer' => array(
502
                'pattern' => '^/',
503
                'form' => array(
504 697
                    'login_path' => '/mypage/login',
505 697
                    'check_path' => '/login_check',
506 697
                    'username_parameter' => 'login_email',
507 697
                    'password_parameter' => 'login_pass',
508
                    'with_csrf' => true,
509
                    'use_forward' => true,
510 697
                ),
511
                'logout' => array(
512
                    'logout_path' => '/logout',
513
                    'target_url' => '/',
514 697
                ),
515
                'remember_me' => array(
516
                    'key' => sha1($this['config']['auth_magic']),
517 697
                    'name' => 'eccube_rememberme',
518 697
                    // lifetimeはデフォルトの1年間にする
519 697
                    // '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...
520 697
                    'path' => $this['config']['root_urlpath'] ?: '/',
521
                    'secure' => $this['config']['force_ssl'],
522
                    'httponly' => true,
523
                    'always_remember_me' => false,
524
                    'remember_me_parameter' => 'login_memory',
525
                ),
526
                'users' => $this['orm.em']->getRepository('Eccube\Entity\Customer'),
527
                'anonymous' => true,
528 697
            ),
529 697
        );
530
531
        $this['security.access_rules'] = array(
532
            array("^/{$this['config']['admin_route']}/login", 'IS_AUTHENTICATED_ANONYMOUSLY'),
533
            array("^/{$this['config']['admin_route']}", 'ROLE_ADMIN'),
534
            array('^/mypage/login', 'IS_AUTHENTICATED_ANONYMOUSLY'),
535
            array('^/mypage/withdraw_complete', 'IS_AUTHENTICATED_ANONYMOUSLY'),
536
            array('^/mypage/change', 'IS_AUTHENTICATED_FULLY'),
537
            array('^/mypage', 'ROLE_USER'),
538
        );
539
540
        $this['eccube.password_encoder'] = $this->share(function($app) {
541
            return new \Eccube\Security\Core\Encoder\PasswordEncoder($app['config']);
542
        });
543
        $this['security.encoder_factory'] = $this->share(function($app) {
544
            return new \Symfony\Component\Security\Core\Encoder\EncoderFactory(array(
545 697
                'Eccube\Entity\Customer' => $app['eccube.password_encoder'],
546
                'Eccube\Entity\Member' => $app['eccube.password_encoder'],
547
            ));
548
        });
549
        $this['eccube.event_listner.security'] = $this->share(function($app) {
550
            return new \Eccube\EventListener\SecurityEventListener($app['orm.em']);
551
        });
552
        $this['user'] = $this->share(function($app) {
553 697
            $token = $app['security']->getToken();
554
555
            return ($token !== null) ? $token->getUser() : null;
556
        });
557
558
        // ログイン時のイベントを設定.
559
        $this['dispatcher']->addListener(\Symfony\Component\Security\Http\SecurityEvents::INTERACTIVE_LOGIN, array($this['eccube.event_listner.security'], 'onInteractiveLogin'));
560 697
561
        // Voterの設定
562
        $app = $this;
563
        $this['authority_voter'] = $this->share(function($app) {
564
            return new \Eccube\Security\Voter\AuthorityVoter($app);
565
        });
566
567
        $app['security.voters'] = $app->extend('security.voters', function($voters) use ($app) {
568
            $voters[] = $app['authority_voter'];
569
570
            return $voters;
571 457
        });
572
573
        $this['security.access_manager'] = $this->share(function($app) {
574
            return new \Symfony\Component\Security\Core\Authorization\AccessDecisionManager($app['security.voters'], 'unanimous');
575
        });
576
577
    }
578
579
    public function initializePlugin()
0 ignored issues
show
introduced by
Missing function doc comment
Loading history...
580
    {
581
        if ($this->initializedPlugin) {
582
            return;
583
        }
584
585
        // setup event dispatcher
586
        $this->initPluginEventDispatcher();
587
588
        // load plugin
589
        $this->loadPlugin();
590
591
        $this->initializedPlugin = true;
592
    }
593
594
    public function initPluginEventDispatcher()
0 ignored issues
show
introduced by
Missing function doc comment
Loading history...
595
    {
596
        // EventDispatcher
597
        $this['eccube.event.dispatcher'] = $this->share(function() {
598
            return new EventDispatcher();
599
        });
600
601
        // hook point
602 457
        $this->before(function(Request $request, \Silex\Application $app) {
603
            $app['eccube.event.dispatcher']->dispatch('eccube.event.app.before');
604
        }, self::EARLY_EVENT);
605
606
        $this->before(function(Request $request, \Silex\Application $app) {
607 457
            $event = 'eccube.event.controller.'.$request->attributes->get('_route').'.before';
608
            $app['eccube.event.dispatcher']->dispatch($event);
609
        });
610
611 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...
612
            $event = 'eccube.event.controller.'.$request->attributes->get('_route').'.after';
613
            $app['eccube.event.dispatcher']->dispatch($event);
614
        });
615
616
        $this->after(function(Request $request, Response $response, \Silex\Application $app) {
617
            $app['eccube.event.dispatcher']->dispatch('eccube.event.app.after');
618
        }, self::LATE_EVENT);
619
620 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...
621
            $event = 'eccube.event.controller.'.$request->attributes->get('_route').'.finish';
622
            $app['eccube.event.dispatcher']->dispatch($event);
623
        });
624
625
        $app = $this;
626
        $this->on(\Symfony\Component\HttpKernel\KernelEvents::RESPONSE, function(\Symfony\Component\HttpKernel\Event\FilterResponseEvent $event) use ($app) {
627
            $route = $event->getRequest()->attributes->get('_route');
628
            $app['eccube.event.dispatcher']->dispatch('eccube.event.render.'.$route.'.before', $event);
629
        });
630
    }
631
632
    public function loadPlugin()
0 ignored issues
show
introduced by
Missing function doc comment
Loading history...
633
    {
634
        // プラグインディレクトリを探索.
635
        $basePath = __DIR__.'/../../app/Plugin';
636
        $finder = Finder::create()
637
            ->in($basePath)
638
            ->directories()
639
            ->depth(0);
640
641
        $finder->sortByName();
642
643
        // ハンドラ優先順位をdbから持ってきてハッシュテーブルを作成
644
        $priorities = array();
645
        $handlers = $this['orm.em']
646
            ->getRepository('Eccube\Entity\PluginEventHandler')
647
            ->getHandlers();
648
        foreach ($handlers as $handler) {
649
            if ($handler->getPlugin()->getEnable() && !$handler->getPlugin()->getDelFlg()) {
650
                $priority = $handler->getPriority();
651
            } else {
652
                // Pluginがdisable、削除済みの場合、EventHandlerのPriorityを全て0とみなす
653
                $priority = \Eccube\Entity\PluginEventHandler::EVENT_PRIORITY_DISABLED;
654
            }
655
            $priorities[$handler->getPlugin()->getClassName()][$handler->getEvent()][$handler->getHandler()] = $priority;
656
        }
657
658
        // プラグインをロードする.
659
        // config.yml/event.ymlの定義に沿ってインスタンスの生成を行い, イベント設定を行う.
660
        foreach ($finder as $dir) {
661
            //config.ymlのないディレクトリは無視する
662
            if (!file_exists($dir->getRealPath().'/config.yml')) {
663
                continue;
664
            }
665
            $config = Yaml::parse(file_get_contents($dir->getRealPath().'/config.yml'));
666
667
            $plugin = $this['orm.em']
668
                ->getRepository('Eccube\Entity\Plugin')
669
                ->findOneBy(array('code' => $config['code']));
670
671
            // const
672
            if (isset($config['const'])) {
673
                $this['config'] = $this->share($this->extend('config', function($eccubeConfig) use ($config) {
674
                    $eccubeConfig[$config['code']] = array(
675
                        'const' => $config['const'],
676
                    );
677
678
                    return $eccubeConfig;
679
                }));
680
            }
681
682
            if ($plugin && $plugin->getEnable() == Constant::DISABLED) {
683
                // プラグインが無効化されていれば読み込まない
684
                continue;
685
            }
686
687
            // Type: Event
688
            if (isset($config['event'])) {
689
                $class = '\\Plugin\\'.$config['code'].'\\'.$config['event'];
690
                $subscriber = new $class($this);
691
692
                if (file_exists($dir->getRealPath().'/event.yml')) {
693
                    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...
694
                        foreach ($handlers as $handler) {
695
                            if (!isset($priorities[$config['event']][$event][$handler[0]])) { // ハンドラテーブルに登録されていない(ソースにしか記述されていない)ハンドラは一番後ろにする
696
                                $priority = \Eccube\Entity\PluginEventHandler::EVENT_PRIORITY_LATEST;
697
                            } else {
698
                                $priority = $priorities[$config['event']][$event][$handler[0]];
699
                            }
700
                            // 優先度が0のプラグインは登録しない
701
                            if (\Eccube\Entity\PluginEventHandler::EVENT_PRIORITY_DISABLED != $priority) {
702
                                $this['eccube.event.dispatcher']->addListener($event, array($subscriber, $handler[0]), $priority);
703
                            }
704
                        }
705
                    }
706
                }
707
            }
708
            // Type: ServiceProvider
709
            if (isset($config['service'])) {
710
                foreach ($config['service'] as $service) {
711
                    $class = '\\Plugin\\'.$config['code'].'\\ServiceProvider\\'.$service;
712
                    $this->register(new $class($this));
713
                }
714
            }
715
        }
716
    }
717
}
718