Failed Conditions
Pull Request — experimental/3.1 (#2525)
by Kiyotaka
54:52 queued 29:13
created

EccubePluginServiceProvider::loadPlugin()   D

Complexity

Conditions 15
Paths 24

Size

Total Lines 82
Code Lines 45

Duplication

Lines 6
Ratio 7.32 %

Code Coverage

Tests 16
CRAP Score 68.3647

Importance

Changes 0
Metric Value
cc 15
eloc 45
nc 24
nop 1
dl 6
loc 82
ccs 16
cts 42
cp 0.381
crap 68.3647
rs 4.9485
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
4
namespace Eccube\ServiceProvider;
5
6
use Eccube\Common\Constant;
7
use Eccube\Plugin\ConfigManager as PluginConfigManager;
8
use Eccube\Service\PluginService;
9
use Pimple\Container;
10
use Pimple\ServiceProviderInterface;
11
use Silex\Api\BootableProviderInterface;
12
use Silex\Application;
13
use Symfony\Component\EventDispatcher\EventDispatcher;
14
use Symfony\Component\Finder\Finder;
15
use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
16
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
17
use Symfony\Component\HttpKernel\Event\PostResponseEvent;
18
use Symfony\Component\HttpKernel\KernelEvents;
19
20
21
class EccubePluginServiceProvider implements ServiceProviderInterface, BootableProviderInterface
0 ignored issues
show
introduced by
Missing class doc comment
Loading history...
22
{
23
    /**
24
     * {@inheritDoc}
25
     */
26 1069
    public function register(Container $app)
27
    {
28
        // EventDispatcher
29
        $app['eccube.event.dispatcher'] = function () {
30 345
            return new EventDispatcher();
31
        };
32
33
        // プラグインディレクトリを探索.
34 1069
        $pluginConfigs = PluginConfigManager::getPluginConfigAll($app['debug']);
35
36 1069
        $enabledPlugins = $app['orm.em']->getRepository('Eccube\Entity\Plugin')->findAllEnabled();
37
38
        $app['eccube.routers.plugin'] = function ($app) use ($enabledPlugins) {
39
            $pluginDirs = array_map(function($plugin) use ($app) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space after FUNCTION keyword; 0 found
Loading history...
40
                return $app['config']['root_dir'].'/app/Plugin/'.$plugin->getCode();
41 1069
            }, $enabledPlugins);
42
43 1069
            $routers = [];
44
45 1069
            if ((empty($pluginDirs)) === false) {
46
                $dirs = Finder::create()
47
                    ->in($pluginDirs)
48
                    ->name('Controller')
49
                    ->directories();
50
51
                foreach ($dirs as $dir) {
52
                    $realPath = $dir->getRealPath();
53
                    $pluginCode = basename(dirname($realPath));
54
                    $routers[] = $app['eccube.router']($realPath, 'Plugin'.$pluginCode);
55
                }
56
            }
57
58 1069
            return $routers;
59
        };
60
61 1069
        foreach ($pluginConfigs as $code => $pluginConfig) {
62 1069
            $config = $pluginConfig['config'];
63
64 1069
            if (isset($config['const'])) {
65
                $app->extend('config', function ($eccubeConfig) use ($config) {
66
                    $eccubeConfig[$config['code']] = array(
67
                        'const' => $config['const'],
68
                    );
69
                    return $eccubeConfig;
0 ignored issues
show
introduced by
Missing blank line before return statement
Loading history...
70 1069
                });
71
            }
72
        }
73
    }
74
75
    /**
76
     * {@inheritDoc}
77
     */
78 1069
    public function boot(Application $app)
79
    {
80 1069
        $this->initPluginEventDispatcher($app);
81 1069
        $this->loadPlugin($app);
82
    }
83
84 1069
    public function initPluginEventDispatcher(Application $app)
0 ignored issues
show
introduced by
Missing function doc comment
Loading history...
85
    {
86
        // hook point
87
        $app->on(KernelEvents::REQUEST, function (GetResponseEvent $event) use ($app) {
88 314
            if (!$event->isMasterRequest()) {
89 58
                return;
90
            }
91 314
            $hookpoint = 'eccube.event.app.before';
92 314
            $app['eccube.event.dispatcher']->dispatch($hookpoint, $event);
93 1069
        }, Application::EARLY_EVENT);
94
95 View Code Duplication
        $app->on(KernelEvents::REQUEST, function (GetResponseEvent $event) use ($app) {
96 314
            if (!$event->isMasterRequest()) {
97 58
                return;
98
            }
99 313
            $route = $event->getRequest()->attributes->get('_route');
100 313
            $hookpoint = "eccube.event.controller.$route.before";
101 313
            $app['eccube.event.dispatcher']->dispatch($hookpoint, $event);
102 1069
        });
103
104 View Code Duplication
        $app->on(KernelEvents::RESPONSE, function (FilterResponseEvent $event) use ($app) {
105 295
            if (!$event->isMasterRequest()) {
106 58
                return;
107
            }
108 295
            $route = $event->getRequest()->attributes->get('_route');
109 295
            $hookpoint = "eccube.event.controller.$route.after";
110 295
            $app['eccube.event.dispatcher']->dispatch($hookpoint, $event);
111 1069
        });
112
113
        $app->on(KernelEvents::RESPONSE, function (FilterResponseEvent $event) use ($app) {
114 295
            if (!$event->isMasterRequest()) {
115 58
                return;
116
            }
117 295
            $hookpoint = 'eccube.event.app.after';
118 295
            $app['eccube.event.dispatcher']->dispatch($hookpoint, $event);
119 1069
        }, Application::LATE_EVENT);
120
121
        $app->on(KernelEvents::TERMINATE, function (PostResponseEvent $event) use ($app) {
122 295
            $route = $event->getRequest()->attributes->get('_route');
123 295
            $hookpoint = "eccube.event.controller.$route.finish";
124 295
            $app['eccube.event.dispatcher']->dispatch($hookpoint, $event);
125 1069
        });
126
127
        $app->on(\Symfony\Component\HttpKernel\KernelEvents::RESPONSE, function (\Symfony\Component\HttpKernel\Event\FilterResponseEvent $event) use ($app) {
128 295
            if (!$event->isMasterRequest()) {
129 58
                return;
130
            }
131 295
            $route = $event->getRequest()->attributes->get('_route');
132 295
            $app['eccube.event.dispatcher']->dispatch('eccube.event.render.'.$route.'.before', $event);
133 1069
        });
134
135
        // Request Event
136 View Code Duplication
        $app->on(\Symfony\Component\HttpKernel\KernelEvents::REQUEST, function (\Symfony\Component\HttpKernel\Event\GetResponseEvent $event) use ($app) {
137
138 314
            if (!$event->isMasterRequest()) {
139 58
                return;
140
            }
141
142 314
            $route = $event->getRequest()->attributes->get('_route');
143
144 314
            if (is_null($route)) {
145
                return;
146
            }
147
148 314
            $app['monolog']->debug('KernelEvents::REQUEST '.$route);
149
150
            // 全体
151 314
            $app['eccube.event.dispatcher']->dispatch('eccube.event.app.request', $event);
152
153 314
            if (strpos($route, 'admin') === 0) {
154
                // 管理画面
155 218
                $app['eccube.event.dispatcher']->dispatch('eccube.event.admin.request', $event);
156
            } else {
157
                // フロント画面
158 96
                $app['eccube.event.dispatcher']->dispatch('eccube.event.front.request', $event);
159
            }
160
161
            // ルーティング単位
162 314
            $app['eccube.event.dispatcher']->dispatch("eccube.event.route.{$route}.request", $event);
163
164 1069
        }, 30); // Routing(32)が解決し, 認証判定(8)が実行される前のタイミング.
165
166
        // Controller Event
167 View Code Duplication
        $app->on(\Symfony\Component\HttpKernel\KernelEvents::CONTROLLER, function (\Symfony\Component\HttpKernel\Event\FilterControllerEvent $event) use ($app) {
168
169 304
            if (!$event->isMasterRequest()) {
170 58
                return;
171
            }
172
173 303
            $route = $event->getRequest()->attributes->get('_route');
174
175 303
            if (is_null($route)) {
176
                return;
177
            }
178
179 303
            $app['monolog']->debug('KernelEvents::CONTROLLER '.$route);
180
181
            // 全体
182 303
            $app['eccube.event.dispatcher']->dispatch('eccube.event.app.controller', $event);
183
184 303
            if (strpos($route, 'admin') === 0) {
185
                // 管理画面
186 209
                $app['eccube.event.dispatcher']->dispatch('eccube.event.admin.controller', $event);
187
            } else {
188
                // フロント画面
189 94
                $app['eccube.event.dispatcher']->dispatch('eccube.event.front.controller', $event);
190
            }
191
            // ルーティング単位
192 303
            $app['eccube.event.dispatcher']->dispatch("eccube.event.route.{$route}.controller", $event);
193 1069
        });
194
195
        // Response Event
196 View Code Duplication
        $app->on(\Symfony\Component\HttpKernel\KernelEvents::RESPONSE, function (\Symfony\Component\HttpKernel\Event\FilterResponseEvent $event) use ($app) {
197 295
            if (!$event->isMasterRequest()) {
198 58
                return;
199
            }
200
201 295
            $route = $event->getRequest()->attributes->get('_route');
202
203 295
            if (is_null($route)) {
204
                return;
205
            }
206
207 295
            $app['monolog']->debug('KernelEvents::RESPONSE '.$route);
208
209
            // ルーティング単位
210 295
            $app['eccube.event.dispatcher']->dispatch("eccube.event.route.{$route}.response", $event);
211
212 295
            if (strpos($route, 'admin') === 0) {
213
                // 管理画面
214 208
                $app['eccube.event.dispatcher']->dispatch('eccube.event.admin.response', $event);
215
            } else {
216
                // フロント画面
217 87
                $app['eccube.event.dispatcher']->dispatch('eccube.event.front.response', $event);
218
            }
219
220
            // 全体
221 295
            $app['eccube.event.dispatcher']->dispatch('eccube.event.app.response', $event);
222 1069
        });
223
224
        // Exception Event
225 View Code Duplication
        $app->on(\Symfony\Component\HttpKernel\KernelEvents::EXCEPTION, function (\Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent $event) use ($app) {
226
227 23
            if (!$event->isMasterRequest()) {
228
                return;
229
            }
230
231 23
            $route = $event->getRequest()->attributes->get('_route');
232
233 23
            if (is_null($route)) {
234
                return;
235
            }
236
237 23
            $app['monolog']->debug('KernelEvents::EXCEPTION '.$route);
238
239
            // ルーティング単位
240 23
            $app['eccube.event.dispatcher']->dispatch("eccube.event.route.{$route}.exception", $event);
241
242 23
            if (strpos($route, 'admin') === 0) {
243
                // 管理画面
244 10
                $app['eccube.event.dispatcher']->dispatch('eccube.event.admin.exception', $event);
245
            } else {
246
                // フロント画面
247 13
                $app['eccube.event.dispatcher']->dispatch('eccube.event.front.exception', $event);
248
            }
249
250
            // 全体
251 23
            $app['eccube.event.dispatcher']->dispatch('eccube.event.app.exception', $event);
252 1069
        });
253
254
        // Terminate Event
255 1069 View Code Duplication
        $app->on(\Symfony\Component\HttpKernel\KernelEvents::TERMINATE, function (\Symfony\Component\HttpKernel\Event\PostResponseEvent $event) use ($app) {
256
257 295
            $route = $event->getRequest()->attributes->get('_route');
258
259 295
            if (is_null($route)) {
260
                return;
261
            }
262
263 295
            $app['monolog']->debug('KernelEvents::TERMINATE '.$route);
264
265
            // ルーティング単位
266 295
            $app['eccube.event.dispatcher']->dispatch("eccube.event.route.{$route}.terminate", $event);
267
268 295
            if (strpos($route, 'admin') === 0) {
269
                // 管理画面
270 208
                $app['eccube.event.dispatcher']->dispatch('eccube.event.admin.terminate', $event);
271
            } else {
272
                // フロント画面
273 87
                $app['eccube.event.dispatcher']->dispatch('eccube.event.front.terminate', $event);
274
            }
275
276
            // 全体
277 295
            $app['eccube.event.dispatcher']->dispatch('eccube.event.app.terminate', $event);
278 1069
        });
279
    }
280
281 1069
    public function loadPlugin(Application $app)
0 ignored issues
show
introduced by
Missing function doc comment
Loading history...
282
    {
283
        // ハンドラ優先順位をdbから持ってきてハッシュテーブルを作成
284 1069
        $priorities = array();
285 1069
        $pluginConfigs = PluginConfigManager::getPluginConfigAll($app['debug']);
286
287 1069
        $handlers = $app['orm.em']
288 1069
            ->getRepository('Eccube\Entity\PluginEventHandler')
289 1069
            ->getHandlers();
290
291 1069
        foreach ($handlers as $handler) {
292
            if ($handler->getPlugin()->getEnable()) {
0 ignored issues
show
Coding Style introduced by
Blank line found at start of control structure
Loading history...
293
294
                $priority = $handler->getPriority();
295
            } else {
296
                // Pluginがdisable、削除済みの場合、EventHandlerのPriorityを全て0とみなす
297
                $priority = \Eccube\Entity\PluginEventHandler::EVENT_PRIORITY_DISABLED;
298
            }
299
            $priorities[$handler->getPlugin()->getClassName()][$handler->getEvent()][$handler->getHandler()] = $priority;
300
        }
301
302
        // プラグインをロードする.
303
        // config.yml/event.ymlの定義に沿ってインスタンスの生成を行い, イベント設定を行う.
304 1069
        foreach ($pluginConfigs as $code => $pluginConfig) {
305
            // 正しい形式の pluginConfig のみ読み込む
306 1069
            $path = PluginConfigManager::getPluginRealDir().'/'.$code;
307
            try {
308 1069
                $app[PluginService::class]->checkPluginArchiveContent($path, $pluginConfig['config']);
309
            } catch (\Eccube\Exception\PluginException $e) {
310
                $app['monolog']->warning("Configuration file config.yml for plugin {$code} not found or is invalid. Skipping loading.", array(
0 ignored issues
show
introduced by
Add a comma after each item in a multi-line array
Loading history...
311
                    'path' => $path,
312
                    'original-message' => $e->getMessage()
313
                ));
314
                continue;
315
            }
316 1069
            $config = $pluginConfig['config'];
317
318 1069
            $plugin = $app['orm.em']
319 1069
                ->getRepository('Eccube\Entity\Plugin')
320 1069
                ->findOneBy(array('code' => $config['code']));
321
322
            // const
323 1069
            if (is_null($plugin) || $plugin->getEnable() == Constant::DISABLED) {
324
                // プラグインが無効化されていれば読み込まない
325 1069
                continue;
326
            }
327
328
            // Type: Event
329
            if (isset($config['event'])) {
330
                $class = '\\Plugin\\'.$config['code'].'\\'.$config['event'];
331
                $eventExists = true;
332
333 View Code Duplication
                if (!class_exists($class)) {
334
                    $app['monolog']->warning("Event class for plugin {$code} not exists.", array(
335
                        'class' => $class,
336
                    ));
337
                    $eventExists = false;
338
                }
339
340
                if ($eventExists && isset($config['event'])) {
0 ignored issues
show
Coding Style introduced by
Blank line found at start of control structure
Loading history...
341
342
                    $subscriber = new $class($app);
343
344
                    foreach ($pluginConfig['event'] as $event => $handlers) {
345
                        foreach ($handlers as $handler) {
346
                            if (!isset($priorities[$config['event']][$event][$handler[0]])) { // ハンドラテーブルに登録されていない(ソースにしか記述されていない)ハンドラは一番後ろにする
347
                                $priority = \Eccube\Entity\PluginEventHandler::EVENT_PRIORITY_LATEST;
348
                            } else {
349
                                $priority = $priorities[$config['event']][$event][$handler[0]];
350
                            }
351
                            // 優先度が0のプラグインは登録しない
352
                            if (\Eccube\Entity\PluginEventHandler::EVENT_PRIORITY_DISABLED != $priority) {
353
                                $app['eccube.event.dispatcher']->addListener($event, array($subscriber, $handler[0]), $priority);
354
                            }
355
                        }
356
                    }
357
                }
358
            }
359
360
            $this->registerServiceProviders($app, $config);
361
        }
362
    }
363
364
    private function registerServiceProviders($app, $config)
365
    {
366
        $code = $config['code'];
367
        if (isset($config['service'])) {
368
            // config.ymlの`service`定義から登録する
369
            foreach ($config['service'] as $service) {
370
                $class = '\\Plugin\\'.$code.'\\ServiceProvider\\'.$service;
371 View Code Duplication
                if (!class_exists($class)) {
372
                    $app['monolog']->warning("Service provider class for plugin {$code} not exists.", array(
373
                        'class' => $class,
374
                    ));
375
                    continue;
376
                }
377
                $app->register(new $class($app));
378
            }
379
        } else {
380
            // ServiceProviderディレクトリ以下のServiceProviderクラスを登録する
381
            $serviceProviderDir = $app['config']['root_dir'].'/app/Plugin/'.$code.'/ServiceProvider';
382
            if (file_exists($serviceProviderDir)) {
383
                $serviceProviderFiles = Finder::create()
384
                    ->in($app['config']['root_dir'].'/app/Plugin/'.$code.'/ServiceProvider')
385
                    ->files();
386
                foreach ($serviceProviderFiles as $file) {
387
                    $class = '\\Plugin\\'.$code.'\\ServiceProvider\\'.$file->getBasename('.php');
388
                    if (class_exists($class)) {
389
                        $app->register(new $class($app));
390
                    }
391
                }
392
            }
393
        }
394
    }
395
}
396