Plugin::getConfigForLoad()   A
last analyzed

Complexity

Conditions 3
Paths 4

Size

Total Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 18
rs 9.6666
c 0
b 0
f 0
cc 3
nc 4
nop 1
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\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::isLoaded($plugin)) {
126
            return FS::clean(self::path($plugin) . DS . self::PLUGIN_MANIFEST);
127
        }
128
129
        return null;
130
    }
131
132
    /**
133
     * Check manifest event.
134
     *
135
     * @param   string $name Plugin name.
136
     * @return  bool
137
     */
138
    public static function hasManifestEvent($name)
139
    {
140
        return Arr::in($name, self::$_manifestEvents);
141
    }
142
143
    /**
144
     * Call plugin manifest callbacks.
145
     *
146
     * @return void
147
     */
148
    public static function manifestEvent()
149
    {
150
        $args     = func_get_args();
151
        $callback = array_shift($args);
152
153
        if (Arr::key($callback, self::$_eventList)) {
154
            $callbacks = self::$_eventList[$callback];
155
            foreach ($callbacks as $method) {
156
                call_user_func_array($method, $args);
157
            }
158
        }
159
    }
160
161
    /**
162
     * Unload the plugin.
163
     *
164
     * @param null|string $plugin
165
     * @return void
166
     */
167
    public static function unload($plugin = null)
168
    {
169
        if ($plugin === null) {
170
            static::getCollection()->clear();
171
        } else {
172
            static::getCollection()->remove($plugin);
173
            $locales = Configure::read('App.paths.locales');
174
            foreach ($locales as $key => $path) {
175
                if ($path == self::getLocalePath($plugin)) {
176
                    unset($locales[$key]);
177
                }
178
            }
179
180
            Configure::write('App.paths.locales', $locales);
181
        }
182
    }
183
184
    /**
185
     * Registration plugin manifest callbacks.
186
     *
187
     * @param string $plugin
188
     * @return void
189
     */
190
    public static function addManifestCallback($plugin)
191
    {
192
        $data = Plugin::getData($plugin);
193
        foreach ($data as $name => $callback) {
194
            if (self::_isCallablePluginData($name, $plugin, $callback) && $plugin !== 'Core') {
195
                self::$_eventList[$name][$plugin] = $callback;
196
            }
197
        }
198
    }
199
200
    /**
201
     * Check plugin data.
202
     *
203
     * @param string $plugin
204
     * @return array
205
     */
206
    protected static function _checkData($plugin)
207
    {
208
        return (Arr::in($plugin, self::$_data)) ? self::$_data[$plugin] : [];
209
    }
210
211
    /**
212
     * Find plugin dir in registered paths.
213
     *
214
     * @param string $name
215
     * @return null|string
216
     */
217
    public static function findPlugin($name)
218
    {
219
        $output = null;
220
        $paths  = App::path('Plugin');
221
        $plugin = Configure::read('plugins.' . $name);
222
223
        if ($plugin !== null) {
224
            return $plugin;
225
        }
226
227
        foreach ($paths as $path) {
228
            $plgPath = $path . $name . DS;
229
            if (FS::isDir($plgPath)) {
230
                $output = $plgPath;
231
                break;
232
            }
233
        }
234
235
        return $output;
236
    }
237
238
    /**
239
     * Get plugin configuration for load plugin.
240
     *
241
     * @param string $path
242
     * @return array
243
     */
244
    public static function getConfigForLoad($path)
245
    {
246
        $config    = ['autoload' => true];
247
        $routes    = $path . 'config' . DS . Plugin::FILE_ROUTES;
248
        $bootstrap = $path . 'config' . DS . Plugin::FILE_BOOTSTRAP;
249
250
        if (FS::isFile($bootstrap)) {
251
            $config['bootstrap'] = true;
252
        }
253
254
        if (FS::isFile($routes)) {
255
            $config['routes'] = true;
256
        }
257
258
        $config['path'] = $path;
259
260
        return $config;
261
    }
262
263
    /**
264
     * Get current plugin data.
265
     *
266
     * @param array $data
267
     * @param null|string $key
268
     * @return Data
269
     */
270
    protected static function _getPluginData(array $data, $key = null)
271
    {
272
        if (isset($data[$key])) {
273
            $data = $data[$key];
274
        }
275
276
        return new Data($data);
277
    }
278
279
    /**
280
     * Check manifest param on callable.
281
     *
282
     * @param string $name
283
     * @param string $plugin
284
     * @param mixed $callback
285
     * @return bool
286
     */
287
    protected static function _isCallablePluginData($name, $plugin, $callback)
288
    {
289
        if (Arr::in($name, self::$_manifestEvents) &&
290
            !isset(self::$_eventList[$name][$plugin]) &&
291
            is_callable($callback)
292
        ) {
293
            return true;
294
        }
295
296
        return false;
297
    }
298
}
299