Completed
Pull Request — master (#1241)
by Kentaro
16:45
created

Application   F

Complexity

Total Complexity 72

Size/Duplication

Total Lines 616
Duplicated Lines 1.3 %

Coupling/Cohesion

Components 1
Dependencies 34

Test Coverage

Coverage 93.39%

Importance

Changes 3
Bugs 0 Features 0
Metric Value
wmc 72
c 3
b 0
f 0
lcom 1
cbo 34
dl 8
loc 616
ccs 113
cts 121
cp 0.9339
rs 1.2626

13 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 10 1
D initConfig() 0 82 13
A initLogger() 0 6 1
B initLocale() 0 33 5
B initSession() 0 25 2
C initRendering() 0 96 12
C initMailer() 0 29 8
B initDoctrine() 0 50 5
B initSecurity() 0 81 3
A initializePlugin() 0 8 1
B initPluginEventDispatcher() 8 37 1
D loadPlugin() 0 85 17
A initialize() 0 59 3

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like Application often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Application, and based on these observations, apply Extract Interface, too.

1
<?php
2
/*
3
 * This file is part of EC-CUBE
4
 *
5
 * Copyright(c) 2000-2015 LOCKON CO.,LTD. All Rights Reserved.
6
 *
7
 * http://www.lockon.co.jp/
8
 *
9
 * This program is free software; you can redistribute it and/or
10
 * modify it under the terms of the GNU General Public License
11
 * as published by the Free Software Foundation; either version 2
12
 * of the License, or (at your option) any later version.
13
 *
14
 * This program is distributed in the hope that it will be useful,
15
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
 * GNU General Public License for more details.
18
 *
19
 * You should have received a copy of the GNU General Public License
20
 * along with this program; if not, write to the Free Software
21
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22
 */
23
24
namespace Eccube;
25
26
use Eccube\Application\ApplicationTrait;
27
use Eccube\Common\Constant;
28
use Monolog\Formatter\LineFormatter;
29
use Monolog\Handler\FingersCrossed\ErrorLevelActivationStrategy;
30
use Monolog\Handler\FingersCrossedHandler;
31
use Monolog\Handler\RotatingFileHandler;
32
use Monolog\Logger;
33
use Symfony\Component\EventDispatcher\EventDispatcher;
34
use Symfony\Component\Finder\Finder;
35
use Symfony\Component\HttpFoundation\Request;
36
use Symfony\Component\HttpFoundation\Response;
37
use Symfony\Component\HttpFoundation\Session\Storage\Handler\PdoSessionHandler;
38
use Symfony\Component\Yaml\Yaml;
39
40
class Application extends ApplicationTrait
0 ignored issues
show
introduced by
Missing class doc comment
Loading history...
41
{
42
    public function __construct(array $values = array())
0 ignored issues
show
introduced by
Missing function doc comment
Loading history...
43
    {
44
        parent::__construct($values);
45
46
        // load config
47
        $this->initConfig();
48
49
        // init monolog
50
        $this->initLogger();
51
    }
52
53 665
    public function initConfig()
0 ignored issues
show
introduced by
Missing function doc comment
Loading history...
54
    {
55
        // load config
56
        $this['config'] = $this->share(function() {
57 653
            $ymlPath = __DIR__.'/../../app/config/eccube';
58 653
            $distPath = __DIR__.'/../../src/Eccube/Resource/config';
59
60 653
            $config = array();
61 653
            $config_yml = $ymlPath.'/config.yml';
62
            if (file_exists($config_yml)) {
63
                $config = Yaml::parse($config_yml);
64
            }
65
66 653
            $config_dist = array();
67 653
            $config_yml_dist = $distPath.'/config.yml.dist';
68
            if (file_exists($config_yml_dist)) {
69
                $config_dist = Yaml::parse($config_yml_dist);
70
            }
71
72 653
            $config_path = array();
73 653
            $path_yml = $ymlPath.'/path.yml';
74
            if (file_exists($path_yml)) {
75
                $config_path = Yaml::parse($path_yml);
76
            }
77
78 653
            $config_constant = array();
79 653
            $constant_yml = $ymlPath.'/constant.yml';
80
            if (file_exists($constant_yml)) {
81
                $config_constant = Yaml::parse($constant_yml);
82
                $config_constant = empty($config_constant) ? array() : $config_constant;
83
            }
84
85 653
            $config_constant_dist = array();
86 653
            $constant_yml_dist = $distPath.'/constant.yml.dist';
87
            if (file_exists($constant_yml_dist)) {
88
                $config_constant_dist = Yaml::parse($constant_yml_dist);
89
            }
90
91
            $configAll = array_replace_recursive($config_constant_dist, $config_dist, $config_constant, $config_path, $config);
92
93 653
            $database = array();
94 653
            $yml = $ymlPath.'/database.yml';
95
            if (file_exists($yml)) {
96
                $database = Yaml::parse($yml);
97
            }
98
99 653
            $mail = array();
100 653
            $yml = $ymlPath.'/mail.yml';
101
            if (file_exists($yml)) {
102
                $mail = Yaml::parse($yml);
103
            }
104
            $configAll = array_replace_recursive($configAll, $database, $mail);
105
106 653
            $config_log = array();
107 653
            $yml = $ymlPath.'/log.yml';
108
            if (file_exists($yml)) {
109
                $config_log = Yaml::parse($yml);
110
            }
111 653
            $config_log_dist = array();
112 653
            $log_yml_dist = $distPath.'/log.yml.dist';
113
            if (file_exists($log_yml_dist)) {
114
                $config_log_dist = Yaml::parse($log_yml_dist);
115
            }
116
117
            $configAll = array_replace_recursive($configAll, $config_log_dist, $config_log);
118
119 653
            $config_nav = array();
120 653
            $yml = $ymlPath.'/nav.yml';
121
            if (file_exists($yml)) {
122
                $config_nav = array('nav' => Yaml::parse($yml));
123
            }
124 653
            $config_nav_dist = array();
125 653
            $nav_yml_dist = $distPath.'/nav.yml.dist';
126
            if (file_exists($nav_yml_dist)) {
127
                $config_nav_dist = array('nav' => Yaml::parse($nav_yml_dist));
128
            }
129
130
            $configAll = array_replace_recursive($configAll, $config_nav_dist, $config_nav);
131
132 653
            return $configAll;
133
        });
134 665
    }
135
136 665
    public function initLogger()
0 ignored issues
show
introduced by
Missing function doc comment
Loading history...
137
    {
138 665
        $app = $this;
139
        $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...
140
        $this['monolog.logfile'] = __DIR__.'/../../app/log/site.log';
141 665
    }
142
143 650
    public function initialize()
0 ignored issues
show
introduced by
Missing function doc comment
Loading history...
144
    {
145
        // init locale
146
        $this->initLocale();
147
148
        // init session
149
        $this->initSession();
150
151
        // init twig
152
        $this->initRendering();
153
154
        // init provider
155
        $this->register(new \Silex\Provider\HttpFragmentServiceProvider());
156
        $this->register(new \Silex\Provider\UrlGeneratorServiceProvider());
157
        $this->register(new \Silex\Provider\FormServiceProvider());
158
        $this->register(new \Silex\Provider\SerializerServiceProvider());
159
        $this->register(new \Eccube\ServiceProvider\ValidatorServiceProvider());
160
161 650
        $app = $this;
162
        $this->error(function(\Exception $e, $code) use ($app) {
163
            if ($app['debug']) {
164 2
                return;
165
            }
166
167
            switch ($code) {
168
                case 404:
169
                    $title = 'ページがみつかりません。';
170
                    $message = 'URLに間違いがないかご確認ください。';
171
                    break;
172
                default:
173
                    $title = 'システムエラーが発生しました。';
174
                    $message = '大変お手数ですが、サイト管理者までご連絡ください。';
175
                    break;
176
            }
177
178
            return $app['twig']->render('error.twig', array(
179
                'error_title' => $title,
180
                'error_message' => $message,
181
            ));
182
        });
183
184
        // init mailer
185
        $this->initMailer();
186
187
        // init doctrine orm
188
        $this->initDoctrine();
189
190
        // init security
191
        $this->initSecurity();
192
193
        // init ec-cube service provider
194
        $this->register(new ServiceProvider\EccubeServiceProvider());
195
196
        // mount controllers
197
        $this->register(new \Silex\Provider\ServiceControllerServiceProvider());
198
        $this->mount('', new ControllerProvider\FrontControllerProvider());
199
        $this->mount('/'.trim($this['config']['admin_route'], '/').'/', new ControllerProvider\AdminControllerProvider());
200
        Request::enableHttpMethodParameterOverride(); // PUTやDELETEできるようにする
201 650
    }
202
203 650
    public function initLocale()
0 ignored issues
show
introduced by
Missing function doc comment
Loading history...
204
    {
205
206
        // timezone
207
        if (!empty($this['config']['timezone'])) {
208
            date_default_timezone_set($this['config']['timezone']);
209
        }
210
211
        $this->register(new \Silex\Provider\TranslationServiceProvider(), array(
212 650
            'locale' => $this['config']['locale'],
213
        ));
214
        $this['translator'] = $this->share($this->extend('translator', function($translator, \Silex\Application $app) {
215
            $translator->addLoader('yaml', new \Symfony\Component\Translation\Loader\YamlFileLoader());
216
217
            $r = new \ReflectionClass('Symfony\Component\Validator\Validator');
218
            $file = dirname($r->getFilename()).'/Resources/translations/validators.'.$app['locale'].'.xlf';
219
            if (file_exists($file)) {
220
                $translator->addResource('xliff', $file, $app['locale'], 'validators');
221
            }
222
223
            $file = __DIR__.'/Resource/locale/validator.'.$app['locale'].'.yml';
224
            if (file_exists($file)) {
225
                $translator->addResource('yaml', $file, $app['locale'], 'validators');
226
            }
227
228
            $file = __DIR__.'/Resource/locale/message.'.$app['locale'].'.yml';
229
            if (file_exists($file)) {
230
                $translator->addResource('yaml', $file, $app['locale']);
231
            }
232
233 328
            return $translator;
234
        }));
235 650
    }
236
237 650
    public function initSession()
0 ignored issues
show
introduced by
Missing function doc comment
Loading history...
238
    {
239
        $this->register(new \Silex\Provider\SessionServiceProvider(), array(
240
            'session.storage.options' => array(
241 650
                'name' => 'eccube',
242
                'cookie_path' => $this['config']['root_urlpath'] ?: '/',
243 650
                'cookie_secure' => $this['config']['force_ssl'],
244 650
                'cookie_lifetime' => $this['config']['cookie_lifetime'],
245 650
                'cookie_httponly' => true,
246
                // cookie_domainは指定しない
247
                // http://blog.tokumaru.org/2011/10/cookiedomain.html
248 650
            ),
249
        ));
250 650
        $this['session.db_options'] = array(
251
            'db_table'      => 'dtb_session',
252
        );
253
254 650
        $app = $this;
255
        $this['session.storage.handler'] = function() use ($app) {
256
            return new PdoSessionHandler(
257
                $app['dbs']['session']->getWrappedConnection(),
258
                $app['session.db_options']
259
            );
260
        };
261 650
    }
262
263 650
    public function initRendering()
0 ignored issues
show
introduced by
Missing function doc comment
Loading history...
264
    {
265
        $this->register(new \Silex\Provider\TwigServiceProvider(), array(
266
            'twig.form.templates' => array('Form/form_layout.twig'),
267
        ));
268
        $this['twig'] = $this->share($this->extend('twig', function(\Twig_Environment $twig, \Silex\Application $app) {
269
            $twig->addExtension(new \Eccube\Twig\Extension\EccubeExtension($app));
270
            $twig->addExtension(new \Twig_Extension_StringLoader());
271
272 89
            return $twig;
273
        }));
274
275
        $this->before(function(Request $request, \Silex\Application $app) {
276
            // フロント or 管理画面ごとにtwigの探索パスを切り替える.
277
            $app['twig'] = $app->share($app->extend('twig', function(\Twig_Environment $twig, \Silex\Application $app) {
278 80
                $paths = array();
279
280
                // 互換性がないのでprofiler とproduction 時のcacheを分離する
281
282
                if (isset($app['profiler'])) {
283
                    $cacheBaseDir = __DIR__.'/../../app/cache/twig/profiler/';
284
                } else {
285 80
                    $cacheBaseDir = __DIR__.'/../../app/cache/twig/production/';
286
                }
287
                if (strpos($app['request']->getPathInfo(), '/'.trim($app['config']['admin_route'], '/')) === 0) {
288
                    if (file_exists(__DIR__.'/../../app/template/admin')) {
289 51
                        $paths[] = __DIR__.'/../../app/template/admin';
290
                    }
291
                    $paths[] = $app['config']['template_admin_realdir'];
292 51
                    $paths[] = __DIR__.'/../../app/Plugin';
293 51
                    $cache = $cacheBaseDir.'admin';
294
                } else {
295
                    if (file_exists($app['config']['template_realdir'])) {
296
                        $paths[] = $app['config']['template_realdir'];
297
                    }
298
                    $paths[] = $app['config']['template_default_realdir'];
299 29
                    $paths[] = __DIR__.'/../../app/Plugin';
300
                    $cache = $cacheBaseDir.$app['config']['template_code'];
301 51
                }
302
                $twig->setCache($cache);
303
                $app['twig.loader']->addLoader(new \Twig_Loader_Filesystem($paths));
304
305 80
                return $twig;
306
            }));
307
308
            // 管理画面のIP制限チェック.
309
            if (strpos($app['request']->getPathInfo(), '/'.trim($app['config']['admin_route'], '/')) === 0) {
310
                // IP制限チェック
311
                $allowHost = $app['config']['admin_allow_host'];
312
                if (count($allowHost) > 0) {
313
                    if (array_search($app['request']->getClientIp(), $allowHost) === false) {
314
                        throw new \Exception();
315
                    }
316
                }
317
            }
318
        }, self::EARLY_EVENT);
319
320
        // twigのグローバル変数を定義.
321 650
        $app = $this;
322
        $this->on(\Symfony\Component\HttpKernel\KernelEvents::CONTROLLER, function(\Symfony\Component\HttpKernel\Event\FilterControllerEvent $event) use ($app) {
323
            // ショップ基本情報
324
            $BaseInfo = $app['eccube.repository.base_info']->get();
325
            $app['twig']->addGlobal('BaseInfo', $BaseInfo);
326
327
            // 管理画面
328
            if (strpos($app['request']->getPathInfo(), '/'.trim($app['config']['admin_route'], '/')) === 0) {
329
                // 管理画面メニュー
330 51
                $menus = array('', '', '');
331
                $app['twig']->addGlobal('menus', $menus);
332
                // フロント画面
333
            } else {
334
                $request = $event->getRequest();
335
                $route = $request->attributes->get('_route');
336
337
                // ユーザ作成画面
338
                if ($route === trim($app['config']['user_data_route'])) {
339
                    $params = $request->attributes->get('_route_params');
340
                    $route = $params['route'];
341
                    // プレビュー画面
342
                } elseif ($request->get('preview')) {
343
                    $route = 'preview';
344
                }
345
346
                try {
347
                    $DeviceType = $app['eccube.repository.master.device_type']
348
                        ->find(\Eccube\Entity\Master\DeviceType::DEVICE_TYPE_PC);
349
                    $PageLayout = $app['eccube.repository.page_layout']->getByUrl($DeviceType, $route);
350
                } catch (\Doctrine\ORM\NoResultException $e) {
351
                    $PageLayout = $app['eccube.repository.page_layout']->newPageLayout($DeviceType);
352 11
                }
353
354
                $app['twig']->addGlobal('PageLayout', $PageLayout);
355
                $app['twig']->addGlobal('title', $PageLayout->getName());
356 51
            }
357
        });
358 650
    }
359
360 650
    public function initMailer()
0 ignored issues
show
introduced by
Missing function doc comment
Loading history...
361
    {
362
363
        // メール送信時の文字エンコード指定(デフォルトは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...
364
        if (isset($this['config']['mail']['charset_iso_2022_jp']) && is_bool($this['config']['mail']['charset_iso_2022_jp'])) {
365
            if ($this['config']['mail']['charset_iso_2022_jp'] === true) {
366
                \Swift::init(function() {
367
                    \Swift_DependencyContainer::getInstance()
368
                        ->register('mime.qpheaderencoder')
369
                        ->asAliasOf('mime.base64headerencoder');
370
                    \Swift_Preferences::getInstance()->setCharset('iso-2022-jp');
371
                });
372
            }
373
        }
374
375
        $this->register(new \Silex\Provider\SwiftmailerServiceProvider());
376
        $this['swiftmailer.options'] = $this['config']['mail'];
377
378
        if (isset($this['config']['mail']['spool']) && is_bool($this['config']['mail']['spool'])) {
379
            $this['swiftmailer.use_spool'] = $this['config']['mail']['spool'];
380
        }
381
        // デフォルトはsmtpを使用
382
        $transport = $this['config']['mail']['transport'];
383 650
        if ($transport == 'sendmail') {
384
            $this['swiftmailer.transport'] = \Swift_SendmailTransport::newInstance();
385 650
        } elseif ($transport == 'mail') {
386
            $this['swiftmailer.transport'] = \Swift_MailTransport::newInstance();
387
        }
388 650
    }
389
390 650
    public function initDoctrine()
0 ignored issues
show
introduced by
Missing function doc comment
Loading history...
391
    {
392
        $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...
393
            'dbs.options' => array(
394 650
                'default' => $this['config']['database'],
395 650
                'session' => $this['config']['database'],
396
        )));
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...
397
        $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...
398
399
        // プラグインのmetadata定義を合わせて行う.
400 650
        $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...
401 649
        $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...
402 650
            ->in($pluginBasePath)
403 650
            ->directories()
404
            ->depth(0);
405
406 650
        $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...
407
        $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...
408 650
            'type' => 'yml',
409 650
            'namespace' => 'Eccube\Entity',
410
            'path' => array(
411 650
                __DIR__.'/Resource/doctrine',
412 650
                __DIR__.'/Resource/doctrine/master',
413 650
            ),
414 650
        );
415
416
        foreach ($finder as $dir) {
417
            $config = Yaml::parse($dir->getRealPath().'/config.yml');
418
419
            // Doctrine Extend
420
            if (isset($config['orm.path']) && is_array($config['orm.path'])) {
421
                $paths = array();
422
                foreach ($config['orm.path'] as $path) {
423
                    $paths[] = $pluginBasePath.'/'.$config['code'].$path;
424
                }
425
                $ormMappings[] = array(
426
                    'type' => 'yml',
427
                    'namespace' => 'Plugin\\'.$config['code'].'\\Entity',
428
                    'path' => $paths,
429
                );
430
            }
431 650
        }
432
433
        $this->register(new \Dflydev\Silex\Provider\DoctrineOrm\DoctrineOrmServiceProvider(), array(
434 650
            'orm.proxies_dir' => __DIR__.'/../../app/cache/doctrine',
435
            'orm.em.options' => array(
436
                'mappings' => $ormMappings,
437 650
            ),
438
        ));
439 650
    }
440
441 650
    public function initSecurity()
0 ignored issues
show
introduced by
Missing function doc comment
Loading history...
442
    {
443
        $this->register(new \Silex\Provider\SecurityServiceProvider());
444
        $this->register(new \Silex\Provider\RememberMeServiceProvider());
445
446 650
        $this['security.firewalls'] = array(
447
            'admin' => array(
448
                'pattern' => "^/{$this['config']['admin_route']}",
449
                'form' => array(
450
                    'login_path' => "/{$this['config']['admin_route']}/login",
451
                    'check_path' => "/{$this['config']['admin_route']}/login_check",
452 650
                    'username_parameter' => 'login_id',
453 650
                    'password_parameter' => 'password',
454 650
                    'with_csrf' => true,
455 650
                    'use_forward' => true,
456 650
                ),
457
                'logout' => array(
458
                    'logout_path' => "/{$this['config']['admin_route']}/logout",
459
                    'target_url' => "/{$this['config']['admin_route']}/",
460 650
                ),
461
                'users' => $this['orm.em']->getRepository('Eccube\Entity\Member'),
462 650
                'anonymous' => true,
463
            ),
464
            'customer' => array(
465 650
                'pattern' => '^/',
466
                'form' => array(
467
                    'login_path' => '/mypage/login',
468
                    'check_path' => '/login_check',
469
                    'username_parameter' => 'login_email',
470
                    'password_parameter' => 'login_pass',
471
                    'with_csrf' => true,
472
                    'use_forward' => true,
473 650
                ),
474
                'logout' => array(
475
                    'logout_path' => '/logout',
476
                    'target_url' => '/',
477 650
                ),
478
                'remember_me' => array(
479
                    'key' => sha1($this['config']['auth_magic']),
480 650
                    'name' => 'eccube_rememberme',
481
                    // lifetimeはデフォルトの1年間にする
482
                    // '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...
483
                    'path' => $this['config']['root_urlpath'] ?: '/',
484 650
                    'secure' => $this['config']['force_ssl'],
485 650
                    'httponly' => true,
486 650
                    'always_remember_me' => false,
487 650
                    'remember_me_parameter' => 'login_memory',
488
                ),
489
                'users' => $this['orm.em']->getRepository('Eccube\Entity\Customer'),
490 650
                'anonymous' => true,
491
            ),
492
        );
493 650
        $this['security.access_rules'] = array(
494
            array("^/{$this['config']['admin_route']}/login", 'IS_AUTHENTICATED_ANONYMOUSLY'),
495
            array("^/{$this['config']['admin_route']}", 'ROLE_ADMIN'),
496 650
            array('^/mypage/login', 'IS_AUTHENTICATED_ANONYMOUSLY'),
497 650
            array('^/mypage/withdraw_complete', 'IS_AUTHENTICATED_ANONYMOUSLY'),
498 650
            array('^/mypage/change', 'IS_AUTHENTICATED_FULLY'),
499 650
            array('^/mypage', 'ROLE_USER'),
500
        );
501
        $this['eccube.password_encoder'] = $this->share(function($app) {
502
            return new \Eccube\Security\Core\Encoder\PasswordEncoder($app['config']);
503
        });
504
        $this['security.encoder_factory'] = $this->share(function($app) {
505
            return new \Symfony\Component\Security\Core\Encoder\EncoderFactory(array(
506 650
                'Eccube\Entity\Customer' => $app['eccube.password_encoder'],
507 650
                'Eccube\Entity\Member' => $app['eccube.password_encoder'],
508
            ));
509
        });
510
        $this['eccube.event_listner.security'] = $this->share(function($app) {
511
            return new \Eccube\EventListener\SecurityEventListener($app['orm.em']);
512
        });
513
        $this['user'] = $this->share(function($app) {
514
            $token = $app['security']->getToken();
515
516
            return ($token !== null) ? $token->getUser() : null;
517
        });
518
519
        // ログイン時のイベントを設定.
520
        $this['dispatcher']->addListener(\Symfony\Component\Security\Http\SecurityEvents::INTERACTIVE_LOGIN, array($this['eccube.event_listner.security'], 'onInteractiveLogin'));
521 650
    }
522
523
    public function initializePlugin()
0 ignored issues
show
introduced by
Missing function doc comment
Loading history...
524
    {
525
        // setup event dispatcher
526
        $this->initPluginEventDispatcher();
527
528
        // load plugin
529
        $this->loadPlugin();
530
    }
531
532 411
    public function initPluginEventDispatcher()
0 ignored issues
show
introduced by
Missing function doc comment
Loading history...
533
    {
534
        // EventDispatcher
535
        $this['eccube.event.dispatcher'] = $this->share(function() {
536
            return new EventDispatcher();
537
        });
538
539
        // hook point
540
        $this->before(function(Request $request, \Silex\Application $app) {
541
            $app['eccube.event.dispatcher']->dispatch('eccube.event.app.before');
542
        }, self::EARLY_EVENT);
543
544
        $this->before(function(Request $request, \Silex\Application $app) {
545
            $event = 'eccube.event.controller.'.$request->attributes->get('_route').'.before';
546
            $app['eccube.event.dispatcher']->dispatch($event);
547
        });
548
549 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...
550
            $event = 'eccube.event.controller.'.$request->attributes->get('_route').'.after';
551
            $app['eccube.event.dispatcher']->dispatch($event);
552
        });
553
554
        $this->after(function(Request $request, Response $response, \Silex\Application $app) {
555
            $app['eccube.event.dispatcher']->dispatch('eccube.event.app.after');
556
        }, self::LATE_EVENT);
557
558 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...
559
            $event = 'eccube.event.controller.'.$request->attributes->get('_route').'.finish';
560
            $app['eccube.event.dispatcher']->dispatch($event);
561
        });
562
563 411
        $app = $this;
564
        $this->on(\Symfony\Component\HttpKernel\KernelEvents::RESPONSE, function(\Symfony\Component\HttpKernel\Event\FilterResponseEvent $event) use ($app) {
565
            $route = $event->getRequest()->attributes->get('_route');
566
            $app['eccube.event.dispatcher']->dispatch('eccube.event.render.'.$route.'.before', $event);
567
        });
568 411
    }
569
570
    public function loadPlugin()
0 ignored issues
show
introduced by
Missing function doc comment
Loading history...
571
    {
572
        // プラグインディレクトリを探索.
573
        $basePath = __DIR__.'/../../app/Plugin';
574
        $finder = Finder::create()
575
            ->in($basePath)
576
            ->directories()
577
            ->depth(0);
578
579
        $finder->sortByName();
580
581
        // ハンドラ優先順位をdbから持ってきてハッシュテーブルを作成
582
        $priorities = array();
583
        $handlers = $this['orm.em']
584
            ->getRepository('Eccube\Entity\PluginEventHandler')
585
            ->getHandlers();
586
        foreach ($handlers as $handler) {
587
            if ($handler->getPlugin()->getEnable() && !$handler->getPlugin()->getDelFlg()) {
588
                $priority = $handler->getPriority();
589
            } else {
590
                // Pluginがdisable、削除済みの場合、EventHandlerのPriorityを全て0とみなす
591
                $priority = \Eccube\Entity\PluginEventHandler::EVENT_PRIORITY_DISABLED;
592
            }
593
            $priorities[$handler->getPlugin()->getClassName()][$handler->getEvent()][$handler->getHandler()] = $priority;
594
        }
595
596
        // プラグインをロードする.
597
        // config.yml/event.ymlの定義に沿ってインスタンスの生成を行い, イベント設定を行う.
598
        foreach ($finder as $dir) {
599
            //config.ymlのないディレクトリは無視する
600
            if (!file_exists($dir->getRealPath().'/config.yml')) {
601
                continue;
602
            }
603
            $config = Yaml::parse($dir->getRealPath().'/config.yml');
604
605
            $plugin = $this['orm.em']
606
                ->getRepository('Eccube\Entity\Plugin')
607
                ->findOneBy(array('code' => $config['code']));
608
609
            // const
610
            if (isset($config['const'])) {
611
                $this['config'] = $this->share($this->extend('config', function($eccubeConfig) use ($config) {
612
                    $eccubeConfig[$config['code']] = array(
613
                        'const' => $config['const'],
614
                    );
615
616
                    return $eccubeConfig;
617
                }));
618
            }
619
620
            if ($plugin && $plugin->getEnable() == Constant::DISABLED) {
621
                // プラグインが無効化されていれば読み込まない
622
                continue;
623
            }
624
625
            // Type: Event
626
            if (isset($config['event'])) {
627
                $class = '\\Plugin\\'.$config['code'].'\\'.$config['event'];
628
                $subscriber = new $class($this);
629
630
                if (file_exists($dir->getRealPath().'/event.yml')) {
631
                    foreach (Yaml::Parse($dir->getRealPath().'/event.yml') as $event => $handlers) {
0 ignored issues
show
Bug introduced by
The expression \Symfony\Component\Yaml\...lPath() . '/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...
632
                        foreach ($handlers as $handler) {
633
                            if (!isset($priorities[$config['event']][$event][$handler[0]])) { // ハンドラテーブルに登録されていない(ソースにしか記述されていない)ハンドラは一番後ろにする
634
                                $priority = \Eccube\Entity\PluginEventHandler::EVENT_PRIORITY_LATEST;
635
                            } else {
636
                                $priority = $priorities[$config['event']][$event][$handler[0]];
637
                            }
638
                            // 優先度が0のプラグインは登録しない
639
                            if (\Eccube\Entity\PluginEventHandler::EVENT_PRIORITY_DISABLED != $priority) {
640
                                $this['eccube.event.dispatcher']->addListener($event, array($subscriber, $handler[0]), $priority);
641
                            }
642
                        }
643
                    }
644
                }
645
            }
646
            // Type: ServiceProvider
647
            if (isset($config['service'])) {
648
                foreach ($config['service'] as $service) {
649
                    $class = '\\Plugin\\'.$config['code'].'\\ServiceProvider\\'.$service;
650
                    $this->register(new $class($this));
651
                }
652
            }
653
        }
654
    }
655
}
656