Completed
Push — master ( 23c3de...bd527c )
by Cheren
12:34
created

Plugin   B

Complexity

Total Complexity 40

Size/Duplication

Total Lines 295
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 7

Importance

Changes 4
Bugs 0 Features 3
Metric Value
wmc 40
c 4
b 0
f 3
lcom 1
cbo 7
dl 0
loc 295
rs 8.2608

13 Methods

Rating   Name   Duplication   Size   Complexity  
B getData() 0 17 5
A getLocalePath() 0 4 1
A getManifestPath() 0 8 2
A load() 0 12 3
A loadList() 0 12 4
A manifestEvent() 0 12 3
A unload() 0 15 4
A _checkData() 0 4 2
A _findPlugin() 0 20 4
A _getConfigForLoad() 0 18 3
A _getPluginData() 0 8 2
A _addManifestCallback() 0 9 3
A _isCallablePluginData() 0 11 4

How to fix   Complexity   

Complex Class

Complex classes like Plugin 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 Plugin, and based on these observations, apply Extract Interface, too.

1
<?php
2
/**
3
 * CakeCMS Core
4
 *
5
 * This file is part of the of the simple cms based on CakePHP 3.
6
 * For the full copyright and license information, please view the LICENSE
7
 * file that was distributed with this source code.
8
 *
9
 * @package   Core
10
 * @license   MIT
11
 * @copyright MIT License http://www.opensource.org/licenses/mit-license.php
12
 * @link      https://github.com/CakeCMS/Core".
13
 * @author    Sergey Kalistratov <[email protected]>
14
 */
15
16
namespace Core;
17
18
use Cake\Core\App;
19
use JBZoo\Utils\FS;
20
use JBZoo\Data\Data;
21
use JBZoo\Utils\Arr;
22
use Cake\Core\Configure;
23
use Cake\Core\Plugin as CakePlugin;
24
25
/**
26
 * Class Plugin
27
 *
28
 * @package Core
29
 */
30
class Plugin extends CakePlugin
31
{
32
33
    /**
34
     * Plugin bootstrap file.
35
     */
36
    const FILE_BOOTSTRAP = 'bootstrap.php';
37
38
    /**
39
     * Plugin routes file.
40
     */
41
    const FILE_ROUTES = 'routes.php';
42
43
    /**
44
     * The plugin manifest file name.
45
     */
46
    const PLUGIN_MANIFEST = 'plugin.manifest.php';
47
48
    /**
49
     * Hold plugin data.
50
     *
51
     * @var array
52
     */
53
    protected static $_data = [];
54
55
    /**
56
     * Holds a list of all plugin events from manifest file.
57
     *
58
     * @var array
59
     */
60
    protected static $_eventList = [];
61
62
    /**
63
     * Manifest callback list.
64
     *
65
     * @var array
66
     */
67
    protected static $_manifestEvents = [
68
        'Controller.initialize',
69
        'Controller.beforeRender',
70
        'Controller.beforeFilter',
71
        'Controller.beforeRedirect',
72
        'Controller.afterFilter',
73
        'View.initialize',
74
        'View.beforeRenderFile',
75
        'View.afterRenderFile',
76
        'View.beforeRender',
77
        'View.afterRender',
78
        'View.beforeLayout',
79
    ];
80
81
    /**
82
     * Get plugin manifest data.
83
     *
84
     * @param string $plugin
85
     * @param null|string $key
86
     * @return Data
87
     */
88
    public static function getData($plugin, $key = null)
89
    {
90
        $data = self::_checkData($plugin);
91
        if (empty($data) && $path = self::getManifestPath($plugin)) {
92
            if (FS::isFile($path)) {
93
                /** @noinspection PhpIncludeInspection */
94
                $plgData = include $path;
95
                $plgData = (array) $plgData;
96
                if (!empty($plgData)) {
97
                    self::$_data[$plugin] = $plgData;
98
                    $data = $plgData;
99
                }
100
            }
101
        }
102
103
        return self::_getPluginData($data, $key);
104
    }
105
106
    /**
107
     * Get plugin locale path.
108
     *
109
     * @param string $plugin
110
     * @return string
111
     */
112
    public static function getLocalePath($plugin)
113
    {
114
        return self::path($plugin) . 'src' . DS . 'Locale' . DS;
115
    }
116
117
    /**
118
     * Get absolute plugin manifest file path.
119
     *
120
     * @param string $plugin
121
     * @return null|string
122
     */
123
    public static function getManifestPath($plugin)
124
    {
125
        if (self::loaded($plugin)) {
126
            return FS::clean(self::path($plugin) . DS . self::PLUGIN_MANIFEST);
127
        }
128
129
        return null;
130
    }
131
132
    /**
133
     * Load the plugin.
134
     *
135
     * @param array|string $plugin
136
     * @param array $config
137
     */
138
    public static function load($plugin, array $config = [])
139
    {
140
        parent::load($plugin, $config);
141
142
        $plugin = (array) $plugin;
143
        foreach ($plugin as $name) {
144
            if ((bool) self::loaded($name)) {
145
                self::_addManifestCallback($name);
146
                Cms::mergeConfig('App.paths.locales', self::getLocalePath($name));
147
            }
148
        }
149
    }
150
151
    /**
152
     * Load list plugin.
153
     *
154
     * @param array $plugins
155
     * @return void
156
     */
157
    public static function loadList(array $plugins)
158
    {
159
        foreach ($plugins as $name) {
160
            if (self::loaded($name)) {
161
                continue;
162
            }
163
164
            if ($path = self::_findPlugin($name)) {
165
                self::load($name, self::_getConfigForLoad($path));
166
            }
167
        }
168
    }
169
170
    /**
171
     * Call plugin manifest callbacks.
172
     *
173
     * @return void
174
     */
175
    public static function manifestEvent()
176
    {
177
        $args     = func_get_args();
178
        $callback = array_shift($args);
179
180
        if (Arr::key($callback, self::$_eventList)) {
181
            $callbacks = self::$_eventList[$callback];
182
            foreach ($callbacks as $method) {
183
                call_user_func_array($method, $args);
184
            }
185
        }
186
    }
187
188
    /**
189
     * Unload the plugin.
190
     *
191
     * @param null|string $plugin
192
     * @return void
193
     */
194
    public static function unload($plugin = null)
195
    {
196
        if (self::loaded($plugin)) {
197
            $locales = Configure::read('App.paths.locales');
198
            foreach ($locales as $key => $path) {
199
                if ($path == self::getLocalePath($plugin)) {
200
                    unset($locales[$key]);
201
                }
202
            }
203
204
            Configure::write('App.paths.locales', $locales);
205
        }
206
207
        parent::unload($plugin);
208
    }
209
210
    /**
211
     * Registration plugin manifest callbacks.
212
     *
213
     * @param string $plugin
214
     * @return void
215
     */
216
    protected static function _addManifestCallback($plugin)
217
    {
218
        $data = Plugin::getData($plugin);
219
        foreach ($data as $name => $callback) {
220
            if (self::_isCallablePluginData($name, $plugin, $callback)) {
221
                self::$_eventList[$name][$plugin] = $callback;
222
            }
223
        }
224
    }
225
226
    /**
227
     * Check plugin data.
228
     *
229
     * @param string $plugin
230
     * @return array
231
     */
232
    protected static function _checkData($plugin)
233
    {
234
        return (Arr::in($plugin, self::$_data)) ? self::$_data[$plugin] : [];
235
    }
236
237
    /**
238
     * Find plugin dir in registered paths.
239
     *
240
     * @param string $name
241
     * @return null|string
242
     */
243
    protected static function _findPlugin($name)
244
    {
245
        $output = null;
246
        $paths  = App::path('Plugin');
247
        $plugin = Configure::read('plugins.' . $name);
248
249
        if ($plugin !== null) {
250
            return $plugin;
251
        }
252
253
        foreach ($paths as $path) {
254
            $plgPath = $path . $name . DS;
255
            if (FS::isDir($plgPath)) {
256
                $output = $plgPath;
257
                break;
258
            }
259
        }
260
261
        return $output;
262
    }
263
264
    /**
265
     * Get plugin configuration for load plugin.
266
     *
267
     * @param string $path
268
     * @return array
269
     */
270
    protected static function _getConfigForLoad($path)
271
    {
272
        $config    = ['autoload' => true];
273
        $routes    = $path . 'config' . DS . Plugin::FILE_ROUTES;
274
        $bootstrap = $path . 'config' . DS . Plugin::FILE_BOOTSTRAP;
275
276
        if (FS::isFile($bootstrap)) {
277
            $config['bootstrap'] = true;
278
        }
279
280
        if (FS::isFile($routes)) {
281
            $config['routes'] = true;
282
        }
283
284
        $config['path'] = $path;
285
286
        return $config;
287
    }
288
289
    /**
290
     * Get current plugin data.
291
     *
292
     * @param array $data
293
     * @param null|string $key
294
     * @return Data
295
     */
296
    protected static function _getPluginData(array $data, $key = null)
297
    {
298
        if (isset($data[$key])) {
299
            $data = $data[$key];
300
        }
301
302
        return new Data($data);
303
    }
304
305
    /**
306
     * Check manifest param on callable.
307
     *
308
     * @param string $name
309
     * @param string $plugin
310
     * @param mixed $callback
311
     * @return bool
312
     */
313
    protected static function _isCallablePluginData($name, $plugin, $callback)
314
    {
315
        if (Arr::in($name, self::$_manifestEvents) &&
316
            !isset(self::$_eventList[$name][$plugin]) &&
317
            is_callable($callback)
318
        ) {
319
            return true;
320
        }
321
322
        return false;
323
    }
324
}
325