Test Failed
Push — master ( 87423a...80cf47 )
by Alexey
08:24 queued 03:00
created

Module::getModels()   C

Complexity

Conditions 8
Paths 2

Size

Total Lines 27
Code Lines 19

Duplication

Lines 27
Ratio 100 %

Code Coverage

Tests 0
CRAP Score 72

Importance

Changes 0
Metric Value
cc 8
eloc 19
nc 2
nop 2
dl 27
loc 27
ccs 0
cts 0
cp 0
crap 72
rs 5.3846
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * Module
5
 *
6
 * @author Alexey Krupskiy <[email protected]>
7
 * @link http://inji.ru/
8
 * @copyright 2015 Alexey Krupskiy
9
 * @license https://github.com/injitools/cms-Inji/blob/master/LICENSE
10
 */
11
class Module {
12
13
    /**
14
     * Storage of cur requested module
15
     *
16
     * @var \Module
17
     */
18
    public static $cur = null;
19
20
    /**
21
     * Module name
22
     *
23
     * @var string
24
     */
25
    public $moduleName = '';
26
27
    /**
28
     * Module config
29
     *
30
     * @var array
31
     */
32
    public $config = [];
33
34
    /**
35
     * Module info
36
     *
37
     * @var array
38
     */
39
    public $info = [];
40
41
    /**
42
     * Requested module params
43
     *
44
     * @var array
45
     */
46
    public $params = [];
47
48
    /**
49
     * Module directory path
50
     *
51
     * @var string
52
     */
53
    public $path = '';
54
55
    /**
56
     * Module app
57
     *
58
     * @var \App
59
     */
60
    public $app = null;
61
62
    /**
63
     * Parse cur module
64
     *
65
     * @param \App $app
66
     */
67
    public function __construct($app) {
68
        $this->app = $app;
69
        $this->moduleName = get_class($this);
70
        $this->path = Router::getLoadedClassPath($this->moduleName);
71
        $this->info = $this->getInfo();
72
        $this->config = Config::module($this->moduleName, !empty($this->info['systemConfig']));
73
        $that = $this;
74
        Inji::$inst->listen('Config-change-module-' . $this->app->name . '-' . $this->moduleName, $this->app->name . '-' . $this->moduleName . 'config', function ($event) use ($that) {
75
            $that->config = $event['eventObject'];
76
            return $event['eventObject'];
77
        });
78
    }
79
80
    /**
81
     * Get all posible directorys for module files
82
     *
83
     * @param string $moduleName
84
     * @return array
85
     */
86
    public static function getModulePaths($moduleName) {
87
        $moduleName = ucfirst($moduleName);
88
        $paths = [];
89
        if (App::$cur !== App::$primary) {
90
            $paths['primaryAppPath'] = App::$primary->path . '/modules/' . $moduleName;
91
        }
92
        $paths['curAppPath'] = App::$cur->path . '/modules/' . $moduleName;
93
        $paths['systemPath'] = INJI_SYSTEM_DIR . '/modules/' . $moduleName;
94
        return $paths;
95
    }
96
97
    /**
98
     * Return directory where places module file
99
     *
100
     * @param string $moduleName
101
     * @return string
102
     */
103
    public static function getModulePath($moduleName) {
104
        $moduleName = ucfirst($moduleName);
105
        $paths = Module::getModulePaths($moduleName);
106
        foreach ($paths as $path) {
107
            if (file_exists($path . '/' . $moduleName . '.php')) {
108
                return $path;
109
            }
110
        }
111
    }
112
113
    /**
114
     * Check module for installed
115
     *
116
     * @param string $moduleName
117
     * @param \App $app
118
     * @return boolean
119
     */
120
    public static function installed($moduleName, $app) {
121
        if (in_array($moduleName, self::getInstalled($app))) {
122
            return true;
123
        }
124
        return false;
125
    }
126
127
    /**
128
     * Get installed modules for app
129
     *
130
     * @param \App $app
131
     * @param App $primary
132
     * @return array
133
     */
134
    public static function getInstalled($app, $primary = false) {
135
        if (!$primary) {
136
            $primary = \App::$primary;
137
        }
138
        $system = !empty(Inji::$config['modules']) ? Inji::$config['modules'] : [];
139
        $primary = !empty($primary->config['modules']) ? $primary->config['modules'] : [];
140
        $actual = $app !== $primary && !empty($app->config['modules']) ? $app->config['modules'] : [];
141
        $modules = array_unique(array_merge($system, $primary, $actual));
142
        return $modules;
143
    }
144
145
    /**
146
     * Find module controllers
147
     *
148
     * @param string $moduleName
149
     * @return array
150
     */
151
    public static function getModuleControllers($moduleName) {
152
        $controllers = [];
153
        $moduleDirs = static::getModulePaths($moduleName);
154
        foreach ($moduleDirs as $moduleDir) {
155
            if (is_dir($moduleDir)) {
156
                foreach (scandir($moduleDir) as $dir) {
157
                    if (preg_match('!Controllers$!', $dir) && is_dir($moduleDir . '/' . $dir)) {
158
                        $path = $moduleDir . '/' . $dir;
159
                        foreach (scandir($path) as $file) {
160
                            if (preg_match('!Controller\.php$!', $file) && is_file($path . '/' . $file)) {
161
                                $controllerName = preg_replace('!Controller\.php$!', '', $file);
162
                                $controllers[preg_replace('!Controllers$!', '', $dir)][$controllerName] = $path . '/' . $file;
163
                            }
164
                        }
165
                    }
166
                }
167
            }
168
        }
169
        return $controllers;
170
    }
171
172
    /**
173
     * Find module by request
174
     *
175
     * @param \App $app
176
     * @param array|null $params
177
     * @return \Module
178
     */
179
    public static function resolveModule($app, $params = null) {
180
        $search = is_array($params) ? $params : $app->params;
181
182
        if (!empty($search[0]) && $app->{$search[0]}) {
183
            $module = $app->{$search[0]};
184
            $module->params = array_slice($search, 1);
185
            return $module;
186
        }
187
        if (!empty($app->config['defaultModule']) && $app->{$app->config['defaultModule']}) {
188
            $module = $app->{$app->config['defaultModule']};
189
            $module->params = $app->params;
190
            return $module;
191
        }
192
193
        if ($app->Main) {
194
            $module = $app->Main;
195
            $module->params = $app->params;
196
            return $module;
197
        }
198
        return null;
199
    }
200
201
    /**
202
     * Get posible path for controller
203
     *
204
     * @return array
205
     */
206
    public function getControllerPaths() {
207
        $paths = [];
208
        if (App::$cur != App::$primary) {
209
            if (!empty($this->params[0]) && strtolower($this->params[0]) != strtolower($this->moduleName)) {
210
                $paths['primaryAppAppTypePath_slice'] = App::$primary->path . '/modules/' . $this->moduleName . '/' . $this->app->type . 'Controllers/' . ucfirst($this->params[0]) . 'Controller.php';
211
                if (App::$primary->{$this->moduleName}) {
212
                    $paths['primaryAppAppTypePath_slice'] = App::$primary->{$this->moduleName}->path . '/' . $this->app->type . 'Controllers/' . ucfirst($this->params[0]) . 'Controller.php';
213
                }
214
            }
215
            $paths['primaryAppAppAppTypePath'] = App::$primary->path . '/modules/' . $this->moduleName . '/' . $this->app->type . 'Controllers/' . $this->moduleName . 'Controller.php';
216
            if (App::$primary->{$this->moduleName}) {
217
                $paths['primaryAppAppTypePath'] = App::$primary->{$this->moduleName}->path . '/' . $this->app->type . 'Controllers/' . $this->moduleName . 'Controller.php';
218
            }
219
            $paths['curAppAppTypePath'] = $this->app->{$this->moduleName}->path . '/' . $this->app->type . 'Controllers/' . $this->moduleName . 'Controller.php';
220
        }
221
222
        if (!empty($this->params[0]) && strtolower($this->params[0]) != strtolower($this->moduleName)) {
223
            $paths['appAppTypePath_slice'] = $this->app->path . '/modules/' . $this->moduleName . '/' . $this->app->type . 'Controllers/' . ucfirst($this->params[0]) . 'Controller.php';
224
            $paths['appTypePath_slice'] = $this->path . '/' . $this->app->type . 'Controllers/' . ucfirst($this->params[0]) . 'Controller.php';
225
        }
226
        $paths['appAppTypePath'] = $this->app->path . '/modules/' . $this->moduleName . '/' . $this->app->type . 'Controllers/' . $this->moduleName . 'Controller.php';
227
        $paths['appTypePath'] = $this->path . '/' . $this->app->type . 'Controllers/' . $this->moduleName . 'Controller.php';
228
229
        if (!empty($this->params[0]) && strtolower($this->params[0]) != strtolower($this->moduleName)) {
230
            $paths['appUniversalPath_slice'] = $this->app->path . '/modules/' . $this->moduleName . '/Controllers/' . ucfirst($this->params[0]) . 'Controller.php';
231
            $paths['universalPath_slice'] = $this->path . '/Controllers/' . ucfirst($this->params[0]) . 'Controller.php';
232
        }
233
        $paths['appUniversalPath'] = $this->app->path . '/modules/' . $this->moduleName . '/Controllers/' . $this->moduleName . 'Controller.php';
234
        $paths['universalPath'] = $this->path . '/Controllers/' . $this->moduleName . 'Controller.php';
235
236
        return $paths;
237
    }
238
239
    /**
240
     * Find controller by request
241
     *
242
     * @return \Controller
243
     */
244
    public function findController() {
245
        $paths = $this->getControllerPaths();
246
        foreach ($paths as $pathName => $path) {
247
            if (file_exists($path)) {
248
                include_once $path;
249
                if (strpos($pathName, 'slice')) {
250
                    $controllerName = ucfirst($this->params[0]);
251
                    $params = array_slice($this->params, 1);
252
                } else {
253
                    $controllerName = $this->moduleName;
254
                    $params = $this->params;
255
                }
256
                $fullControllerName = $controllerName . 'Controller';
257
                $controller = new $fullControllerName();
258
                $controller->params = $params;
259
                $controller->module = $this;
260
                $controller->path = pathinfo($path, PATHINFO_DIRNAME);
261
                $controller->name = $controllerName;
262
                return $controller;
263
            }
264
        }
265
    }
266
267
    /**
268
     * Return module info
269
     *
270
     * @param string $moduleName
271
     * @return array
272
     */
273
    public static function getInfo($moduleName = '') {
274
        if (!$moduleName && get_called_class()) {
275
            $moduleName = get_called_class();
276
        } elseif (!$moduleName) {
277
            return [];
278
        }
279
        $paths = Module::getModulePaths($moduleName);
280
        foreach ($paths as $path) {
281
            if (file_exists($path . '/info.php')) {
282
                return include $path . '/info.php';
283
            }
284
        }
285
        return [];
286
    }
287
288
    /**
289
     * Return snippets by name
290
     *
291
     * @param string $snippetsPath
292
     * @param boolean $extensions
293
     * @param string $dir
294
     * @param string $moduleName
295
     * @return array
296
     */
297
    public function getSnippets($snippetsPath, $extensions = true, $dir = '/snippets', $moduleName = '') {
298
        $moduleName = $moduleName ? $moduleName : $this->moduleName;
299
        $modulePaths = Module::getModulePaths($moduleName);
300
        $modulePaths = array_reverse($modulePaths);
301
        $modulePaths['templatePath'] = App::$cur->view->template->path . '/modules/' . ucfirst($moduleName);
302
        $snippets = [];
303
        foreach ($modulePaths as $path) {
304
            if (file_exists($path . $dir . '/' . $snippetsPath)) {
305
                $snippetsPaths = array_slice(scandir($path . $dir . '/' . $snippetsPath), 2);
306
                foreach ($snippetsPaths as $snippetPath) {
307
                    if (is_dir($path . $dir . '/' . $snippetsPath . '/' . $snippetPath)) {
308
                        $snippets[$snippetPath] = include $path . $dir . '/' . $snippetsPath . '/' . $snippetPath . '/info.php';
309
                    } else {
310
                        $snippets[pathinfo($snippetPath, PATHINFO_FILENAME)] = include $path . $dir . '/' . $snippetsPath . '/' . $snippetPath;
311
                    }
312
                }
313
            }
314
        }
315
        if ($extensions) {
316
            $snippets = array_merge($snippets, $this->getExtensions('snippets', $snippetsPath));
317
        }
318
        return $snippets;
319
    }
320
321
    /**
322
     * Return module objects
323
     *
324
     * @return array
325
     */
326 View Code Duplication
    public function getObjects($filterNamespace = '') {
327
        $moduleName = $this->moduleName;
328
        $modulePaths = Module::getModulePaths($moduleName);
329
        $modulePaths = array_reverse($modulePaths);
330
        $scanFn = function ($path, $namespace, &$files = []) use (&$scanFn, $filterNamespace) {
331
            if (file_exists($path)) {
332
                foreach (scandir($path) as $item) {
333
                    if (in_array($item, ['..', '.'])) {
334
                        continue;
335
                    }
336
                    $filename = pathinfo($item)['filename'];
337
                    if (is_dir($path . '/' . $item)) {
338
                        $scanFn($path . '/' . $item, $namespace . '\\' . $filename, $files);
339
                    } else {
340
                        if (!$filterNamespace || strpos($namespace, $filterNamespace) === 0) {
341
                            $files[$path . '/' . $item] = $namespace . '\\' . $filename;
342
                        }
343
                    }
344
                }
345
            }
346
            return $files;
347
        };
348
        $files = [];
349
        foreach ($modulePaths as $path) {
350
            $scanFn($path . '/objects', $moduleName, $files);
351
        }
352
        return $files;
353
    }
354
355
    /**
356
     * Return module models
357
     *
358
     * @return array
359
     */
360 View Code Duplication
    public static function getModels($moduleName, $filterNamespace = '') {
361
        $modulePaths = Module::getModulePaths($moduleName);
362
        $modulePaths = array_reverse($modulePaths);
363
        $scanFn = function ($path, $namespace, &$files = []) use (&$scanFn, $filterNamespace) {
364
            if (file_exists($path)) {
365
                foreach (scandir($path) as $item) {
366
                    if (in_array($item, ['..', '.'])) {
367
                        continue;
368
                    }
369
                    $filename = pathinfo($item)['filename'];
370
                    if (is_dir($path . '/' . $item)) {
371
                        $scanFn($path . '/' . $item, $namespace . '\\' . $filename, $files);
372
                    } else {
373
                        if (!$filterNamespace || strpos($namespace, $filterNamespace) === 0) {
374
                            $files[$path . '/' . $item] = $namespace . '\\' . $filename;
375
                        }
376
                    }
377
                }
378
            }
379
            return $files;
380
        };
381
        $files = [];
382
        foreach ($modulePaths as $path) {
383
            $scanFn($path . '/models', $moduleName, $files);
384
        }
385
        return $files;
386
    }
387
388
    /**
389
     * Return extensions for type
390
     *
391
     * @param string $extensionType
392
     * @param string $request
393
     * @return array
394
     */
395
    public function getExtensions($extensionType, $request) {
396
        $extensions = [];
397
        $modules = Module::getInstalled(App::$cur);
398
        $method = 'get' . ucfirst($extensionType);
399
        foreach ($modules as $module) {
400
            $extensions = array_merge($extensions, $this->{$method}($request, false, "/extensions/{$this->moduleName}/" . $extensionType, $module));
401
        }
402
        return $extensions;
403
    }
404
405
    public function checkDbMigration() {
406
        if (empty($this->info['migrations'])) {
407
            return true;
408
        }
409
        $code = 'module:' . get_called_class();
410
        $newMigrations = App::$cur->db->compareMigrations($code, $this->info['migrations']);
411
        foreach ($newMigrations as $version => $migrationOption) {
412
            $migration = include $this->path . '/migrations/' . $migrationOption . '.php';
413
            App::$cur->db->makeMigration($code, $version, $migration);
414
        }
415
    }
416
417
    public function sitemap() {
418
        return [];
419
    }
420
}