Passed
Push — v5 ( 6adbf6...c0775f )
by Alexey
06:03
created

View   F

Complexity

Total Complexity 165

Size/Duplication

Total Lines 632
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
dl 0
loc 632
rs 1.4778
c 0
b 0
f 0
wmc 165

24 Methods

Rating   Name   Duplication   Size   Complexity  
A addMetaTag() 0 5 3
C parentContent() 0 25 7
B getHref() 0 10 7
A init() 0 5 2
A getCss() 0 12 4
B resolveTemplate() 0 17 5
C ResolveCssHref() 0 39 13
C widget() 0 31 12
A content() 0 12 3
C genScriptArray() 0 52 16
C checkNeedLibs() 0 21 12
D parseSource() 0 37 9
A setTitle() 0 9 4
A parseRaw() 0 7 2
C paramsParse() 0 22 9
C parseCss() 0 58 11
C getMetaTags() 0 22 8
A page() 0 11 3
A cutTag() 0 4 1
A getScripts() 0 12 4
C bodyEnd() 0 60 12
C head() 0 26 11
A customAsset() 0 6 4
B getWidgetPaths() 0 24 3

How to fix   Complexity   

Complex Class

Complex classes like View 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.

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 View, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
namespace Inji;
4
use Inji\View\Template;
5
6
/**
7
 * View module
8
 *
9
 * Rendering pages, contents and widgets
10
 *
11
 * @author Alexey Krupskiy <[email protected]>
12
 * @link http://inji.ru/
13
 * @copyright 2015 Alexey Krupskiy
14
 * @license https://github.com/injitools/cms-Inji/blob/master/LICENSE
15
 */
16
class View extends Module {
17
    public $name = 'View';
18
    public $title = 'No title';
19
20
    /**
21
     * @var View\Template
22
     */
23
    public $template = null;
24
    public $libAssets = ['css' => [], 'js' => []];
25
    public $dynAssets = ['css' => [], 'js' => []];
26
    public $dynMetas = [];
27
    public $viewedContent = '';
28
    public $contentData = [];
29
    public $templatesPath = '';
30
    public $loadedCss = [];
31
    public $loadedJs = [];
32
33
    public function init() {
34
        if (!empty($this->app->config['site']['name'])) {
35
            $this->title = $this->app->config['site']['name'];
36
        }
37
        $this->resolveTemplate();
38
    }
39
40
    public function resolveTemplate() {
41
        $templateName = 'default';
42
        if (!empty($this->config[$this->app->type]['current'])) {
43
            $templateName = $this->config[$this->app->type]['current'];
44
            if (!empty($this->config[$this->app->type]['installed'][$templateName]['location'])) {
45
                $this->templatesPath = App::$primary->path . "/templates";
46
            }
47
        }
48
        if (!$this->templatesPath) {
49
            $this->templatesPath = $this->app->path . "/templates";
50
        }
51
        $this->template = View\Template::get($templateName, $this->app, $this->templatesPath);
52
        if (!$this->template) {
53
            $this->template = new View\Template([
54
                'name' => 'default',
55
                'path' => $this->templatesPath . '/default',
56
                'app' => $this->app
57
            ]);
58
        }
59
    }
60
61
    public function page($params = []) {
62
        $this->paramsParse($params);
63
        App::$cur->log->template_parsed = true;
0 ignored issues
show
Bug Best Practice introduced by
The property log does not exist on Inji\App. Since you implemented __get, consider adding a @property annotation.
Loading history...
64
        if (file_exists($this->template->pagePath)) {
65
            $source = file_get_contents($this->template->pagePath);
66
            if (strpos($source, 'BODYEND') === false) {
67
                $source = str_replace('</body>', '{BODYEND}</body>', $source);
68
            }
69
            $this->parseSource($source);
70
        } else {
71
            $this->content();
72
        }
73
    }
74
75
    public function paramsParse($params) {
76
        // set template
77
        if (!empty($params['template']) && $params['template'] != 'current') {
78
            $this->template = Template::get($params['template']);
79
        }
80
        //set page
81
        if (!empty($params['page']) && $params['page'] != 'current') {
82
            $this->template->setPage($params['page']);
83
        }
84
        //set module
85
        if (!empty($params['module'])) {
86
            $this->template->setModule($params['module']);
87
        }
88
        //set content
89
        if (!empty($params['content'])) {
90
            $this->template->setContent($params['content']);
91
        } elseif (!$this->template->contentPath) {
92
            $this->template->setContent();
93
        }
94
        //set data
95
        if (!empty($params['data'])) {
96
            $this->contentData = array_merge($this->contentData, $params['data']);
97
        }
98
    }
99
100
    public function content($params = []) {
101
102
        $this->paramsParse($params);
103
104
        if (empty($this->template->config['noSysMsgAutoShow'])) {
105
            Msg::show();
106
        }
107
        if (!file_exists($this->template->contentPath)) {
108
            echo 'Content not found';
109
        } else {
110
            extract($this->contentData);
111
            include $this->template->contentPath;
112
        }
113
    }
114
115
    public function parentContent($contentName = '') {
116
        if (!$contentName) {
117
            $contentName = $this->template->content;
118
        }
119
120
        $paths = $this->template->getContentPaths($contentName);
121
122
        $data = [];
123
        $exist = false;
124
        foreach ($paths as $type => $path) {
0 ignored issues
show
Bug introduced by
The expression $paths of type string is not traversable.
Loading history...
125
            if (substr($path, 0, strrpos($path, '/')) == substr($this->template->contentPath, 0, strrpos($this->template->contentPath, '/'))) {
126
                $exist = true;
127
                continue;
128
            }
129
            if (file_exists($path) && $exist) {
130
                $data['contentPath'] = $path;
131
                $data['content'] = $contentName;
132
                break;
133
            }
134
        }
135
        if (!$data) {
136
            echo 'Content not found';
137
        } else {
138
            extract($this->contentData);
139
            include $data['contentPath'];
140
        }
141
    }
142
143
    private function parseRaw($source) {
144
        if (!$source) {
145
            return [];
146
        }
147
148
        preg_match_all("|{([^}]+)}|", $source, $result);
149
        return $result[1];
150
    }
151
152
    public function parseSource($source) {
153
        $tags = $this->parseRaw($source);
154
        foreach ($tags as $rawTag) {
155
            $tag = explode(':', $rawTag);
156
            switch ($tag[0]) {
157
                case 'CONTENT':
158
                    $source = $this->cutTag($source, $rawTag);
159
                    $this->content();
160
                    break;
161
                case 'TITLE':
162
                    $source = $this->cutTag($source, $rawTag);
163
                    echo $this->title;
164
                    break;
165
                case 'WIDGET':
166
                    $source = $this->cutTag($source, $rawTag);
167
                    $params = array_slice($tag, 2);
168
                    $this->widget($tag[1], ['params' => $params], ':' . implode(':', $params));
169
                    break;
170
                case 'HEAD':
171
                    $source = $this->cutTag($source, $rawTag);
172
                    $this->head();
173
                    break;
174
                case 'PAGE':
175
                    $source = $this->cutTag($source, $rawTag);
176
                    $this->page(['page' => $tag[1]]);
177
                    break;
178
                case 'BODYEND':
179
                    $source = $this->cutTag($source, $rawTag);
180
                    $this->bodyEnd();
181
                    break;
182
                case 'TEMPLATE_PATH':
183
                    $source = $this->cutTag($source, $rawTag);
184
                    echo "/static/templates/{$this->template->name}";
185
                    break;
186
            }
187
        }
188
        echo $source;
189
    }
190
191
    public function cutTag($source, $rawTag) {
192
        $pos = strpos($source, $rawTag) - 1;
193
        echo substr($source, 0, $pos);
194
        return substr($source, ($pos + strlen($rawTag) + 2));
195
    }
196
197
    public function getHref($type, $params) {
198
        $href = '';
199
        if (is_string($params)) {
200
            $href = $params;
201
        } elseif (empty($params['template']) && !empty($params['file'])) {
202
            $href = ($this->app->type != 'app' ? '/' . $this->app->name : '') . $params['file'];
203
        } elseif (!empty($params['template']) && !empty($params['file'])) {
204
            $href = $this->app->templatesPath . "/{$this->template->name}/{$type}/{$params['file']}";
205
        }
206
        return $href;
207
    }
208
209
    public function checkNeedLibs() {
210
        if (!empty($this->template->config['libs'])) {
211
            foreach ($this->template->config['libs'] as $libName => $libOptions) {
212
                if (!is_array($libOptions)) {
213
                    $libName = $libOptions;
214
                    $libOptions = [];
215
                }
216
                $this->app->libs->loadLib($libName, $libOptions);
0 ignored issues
show
Bug introduced by
The method loadLib() does not exist on Inji\Module. It seems like you code against a sub-type of Inji\Module such as Inji\Libs or Inji\Db. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

216
                $this->app->libs->/** @scrutinizer ignore-call */ 
217
                                  loadLib($libName, $libOptions);
Loading history...
Bug Best Practice introduced by
The property libs does not exist on Inji\App. Since you implemented __get, consider adding a @property annotation.
Loading history...
217
            }
218
        }
219
        foreach ($this->dynAssets['js'] as $asset) {
220
            if (is_array($asset) && !empty($asset['libs'])) {
221
                foreach ($asset['libs'] as $libName) {
222
                    $this->app->libs->loadLib($libName);
223
                }
224
            }
225
        }
226
        foreach ($this->libAssets['js'] as $asset) {
227
            if (is_array($asset) && !empty($asset['libs'])) {
228
                foreach ($asset['libs'] as $libName) {
229
                    $this->app->libs->loadLib($libName);
230
                }
231
            }
232
        }
233
    }
234
235
    public function head() {
236
237
        echo "<title>{$this->title}</title>\n";
238
        if (!empty(App::$primary->config['site']['favicon']) && file_exists(App::$primary->path . '/' . App::$primary->config['site']['favicon'])) {
239
            echo "        <link rel='shortcut icon' href='" . App::$primary->config['site']['favicon'] . "' />";
240
        } elseif (!empty($this->template->config['favicon']) && file_exists($this->template->path . "/{$this->template->config['favicon']}")) {
241
            echo "        <link rel='shortcut icon' href='/templates/{$this->template->name}/{$this->template->config['favicon']}' />";
242
        } elseif (!empty($this->template->config['favicon']) && file_exists($this->app->path . "/static/images/{$this->template->config['favicon']}")) {
243
            echo "        <link rel='shortcut icon' href='/static/images/{$this->template->config['favicon']}' />";
244
        } elseif (file_exists($this->app->path . '/static/images/favicon.ico')) {
245
            echo "        <link rel='shortcut icon' href='/static/images/favicon.ico' />";
246
        }
247
248
        foreach ($this->getMetaTags() as $meta) {
249
            echo "\n        " . Html::el('meta', $meta, '', null);
250
        }
251
252
        if (!empty(\Inji::$config['assets']['js'])) {
253
            foreach (\Inji::$config['assets']['js'] as $js) {
254
                $this->customAsset('js', $js);
255
            }
256
        }
257
258
        $this->checkNeedLibs();
259
        $this->parseCss();
260
        echo "\n        <script src='" . Statics::file("/static/system/js/Inji.js") . "'></script>";
261
    }
262
263
    public function parseCss() {
264
        $css = $this->getCss();
265
        $urls = [];
266
        $timeStr = '';
267
        $cssAll = '';
268
        $exclude = ['^http:', '^https:', '^//'];
269
        foreach ($css as $href) {
270
            if (!empty($this->loadedCss[$href])) {
271
                continue;
272
            }
273
            foreach ($exclude as $item) {
274
                if (preg_match("!{$item}!", $href)) {
275
                    echo "\n        <link href='{$href}' rel='stylesheet' type='text/css' />";
276
                    continue;
277
                }
278
            }
279
            $path = $this->app->staticLoader->parsePath($href);
0 ignored issues
show
Bug Best Practice introduced by
The property staticLoader does not exist on Inji\App. Since you implemented __get, consider adding a @property annotation.
Loading history...
Bug introduced by
The method parsePath() does not exist on Inji\Module. It seems like you code against a sub-type of Inji\Module such as Inji\StaticLoader or Inji\Db. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

279
            /** @scrutinizer ignore-call */ 
280
            $path = $this->app->staticLoader->parsePath($href);
Loading history...
280
            if (file_exists($path)) {
281
                $this->loadedCss[$href] = $href;
282
                $urls[$href] = $path;
283
                $timeStr .= filemtime($path);
284
            } else {
285
                echo "\n        <link href='{$href}' rel='stylesheet' type='text/css' />";
286
            }
287
        }
288
        if (!$urls) {
289
            return;
290
        }
291
        $timeMd5 = md5($timeStr);
292
        $cacheDir = Cache::getDir('static');
293
        if (!file_exists($cacheDir . 'all' . $timeMd5 . '.css')) {
294
            foreach ($urls as $primaryUrl => $url) {
295
                $source = file_get_contents($url);
296
                $rootPath = substr($primaryUrl, 0, strrpos($primaryUrl, '/'));
297
                $levelUpPath = substr($rootPath, 0, strrpos($rootPath, '/'));
298
                $source = preg_replace('!url\((\'?"?)[\.]{2}!isU', 'url($1' . $levelUpPath, $source);
299
                $source = preg_replace('!url\((\'?"?)[\.]{1}!isU', 'url($1' . $rootPath, $source);
300
                $source = preg_replace('#url\(([\'"]){1}(?!http|https|/|data\:)([^/])#isU', 'url($1' . $rootPath . '/$2', $source);
301
                $source = preg_replace('#url\((?!http|https|/|data\:|\'|")([^/])#isU', 'url(' . $rootPath . '/$1$2', $source);
302
                $cssAll .= $source . "\n";
303
            }
304
            file_put_contents($cacheDir . 'all' . $timeMd5 . '.css', $cssAll);
305
        }
306
        $id = 'css' . Tools::randomString();
307
        echo "\n        <link id='{$id}' href='/{$cacheDir}all{$timeMd5}.css' rel='stylesheet' type='text/css' />";
308
        if (!empty($this->template->config['staticUpdater'])) {
309
            $hash = json_encode(array_keys($urls));
310
            if (!empty($this->template->config['staticUpdaterSalt'])) {
311
                $hash .= $this->template->config['staticUpdaterSalt'];
312
            }
313
            $hash = md5($hash);
314
            ?>
315
            <script>
316
                setInterval(function () {
317
                    var hash = '<?=$hash;?>';
318
                    var files = '<?=http_build_query(['files' => array_keys($urls)]);?>';
319
                    var timeHash = '<?=$timeMd5?>';
320
                    var id = '<?=$id;?>';
321
                    // 1. Создаём новый объект XMLHttpRequest
322
                    var xhr = new XMLHttpRequest();
323
324
                    // 2. Конфигурируем его: GET-запрос на URL 'phones.json'
325
                    xhr.open('GET', '/view/checkStaticUpdates/' + hash + '/' + timeHash + '?' + files, false);
326
327
                    // 3. Отсылаем запрос
328
                    xhr.send();
329
330
                    // 4. Если код ответа сервера не 200, то это ошибка
331
                    if (xhr.status != 200) {
332
                        // обработать ошибку
333
                        //alert(xhr.status + ': ' + xhr.statusText); // пример вывода: 404: Not Found
334
                    } else {
335
                        if (xhr.responseText.length > 0) {
336
                            var result = JSON.parse(xhr.responseText);
337
                            document.getElementById(id).href = result.path;
338
                            timeHash = result.timeHash;
339
                        }
340
                        // вывести результат
341
                        //alert(xhr.responseText); // responseText -- текст ответа.
342
                    }
343
                }, 2000);
344
            </script>
345
            <?php
346
        }
347
348
    }
349
350
    public function getCss() {
351
        $css = [];
352
        if (!empty($this->libAssets['css'])) {
353
            $this->ResolveCssHref($this->libAssets['css'], 'libs', $css);
354
        }
355
        if (!empty($this->template->config['css'])) {
356
            $this->ResolveCssHref($this->template->config['css'], 'template', $css);
357
        }
358
        if (!empty($this->dynAssets['css'])) {
359
            $this->ResolveCssHref($this->dynAssets['css'], 'custom', $css);
360
        }
361
        return $css;
362
    }
363
364
    public function ResolveCssHref($cssArray, $type = 'custom', &$hrefs) {
365
        switch ($type) {
366
            case 'libs':
367
                foreach ($cssArray as $css) {
368
                    if (is_array($css)) {
369
                        $this->ResolveCssHref($css, $type, $hrefs);
370
                        continue;
371
                    }
372
                    $hrefs[$css] = $css;
373
                }
374
                break;
375
            case 'template':
376
                foreach ($cssArray as $css) {
377
                    if (is_array($css)) {
378
                        $this->ResolveCssHref($css, $type, $hrefs);
379
                        continue;
380
                    }
381
                    if (strpos($css, '://') !== false) {
382
                        $href = $css;
383
                    } else {
384
                        $href = $this->app->templatesPath . "/{$this->template->name}/css/{$css}";
385
                    }
386
                    $hrefs[$href] = $href;
387
                }
388
                break;
389
            case 'custom':
390
                foreach ($cssArray as $css) {
391
                    if (is_array($css)) {
392
                        $this->ResolveCssHref($css, $type, $hrefs);
393
                        continue;
394
                    }
395
                    if (strpos($css, '//') !== false) {
396
                        $href = $css;
397
                    } else {
398
                        $href = ($this->app->type != 'app' ? '/' . $this->app->name : '') . $css;
399
                    }
400
                    $hrefs[$href] = $href;
401
                }
402
                break;
403
        }
404
    }
405
406
    public function getMetaTags() {
407
        $metas = [];
408
409
        if (!empty($this->app->config['site']['keywords'])) {
410
            $metas['metaName:keywords'] = ['name' => 'keywords', 'content' => $this->app->config['site']['keywords']];
411
        }
412
        if (!empty($this->app->config['site']['description'])) {
413
            $metas['metaName:description'] = ['name' => 'description', 'content' => $this->app->config['site']['description']];
414
        }
415
        if (!empty($this->app->config['site']['metatags'])) {
416
            foreach ($this->app->config['site']['metatags'] as $meta) {
417
                if (!empty($meta['name'])) {
418
                    $metas['metaName:' . $meta['name']] = $meta;
419
                } elseif (!empty($meta['property'])) {
420
                    $metas['metaProperty:' . $meta['property']] = $meta;
421
                }
422
            }
423
        }
424
        if ($this->dynMetas) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->dynMetas of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
425
            $metas = array_merge($metas, $this->dynMetas);
426
        }
427
        return $metas;
428
    }
429
430
    public function addMetaTag($meta) {
431
        if (!empty($meta['name'])) {
432
            $this->dynMetas['metaName:' . $meta['name']] = $meta;
433
        } elseif (!empty($meta['property'])) {
434
            $this->dynMetas['metaProperty:' . $meta['property']] = $meta;
435
        }
436
    }
437
438
    public function bodyEnd() {
439
        $this->checkNeedLibs();
440
        $this->parseCss();
441
        $scripts = $this->getScripts();
442
        $onLoadModules = [];
443
        $scriptAll = '';
444
        $urls = [];
445
        $nativeUrl = [];
446
        $timeStr = '';
447
        $noParsedScripts = [];
448
        foreach ($scripts as $script) {
449
            if (is_string($script)) {
450
                if (!empty($urls[$script])) {
451
                    continue;
452
                }
453
454
                $path = $this->app->staticLoader->parsePath($script);
0 ignored issues
show
Bug Best Practice introduced by
The property staticLoader does not exist on Inji\App. Since you implemented __get, consider adding a @property annotation.
Loading history...
455
                if (file_exists($path)) {
456
                    $nativeUrl[$script] = $script;
457
                    $urls[$script] = $path;
458
                    $timeStr .= filemtime($path);
459
                } else {
460
                    $noParsedScripts[$script] = $script;
461
                }
462
            } elseif (!empty($script['file'])) {
463
                if (!empty($urls[$script['file']])) {
464
                    continue;
465
                }
466
467
                $path = $this->app->staticLoader->parsePath($script['file']);
468
                if (file_exists($path)) {
469
                    $nativeUrl[$script['file']] = $script['file'];
470
                    $urls[$script['file']] = $path;
471
                    if (!empty($script['name'])) {
472
                        $onLoadModules[$script['name']] = $script['name'];
473
                    }
474
                    $timeStr .= filemtime($path);
475
                } else {
476
                    $noParsedScripts[$script['file']] = $script['file'];
477
                }
478
            }
479
        }
480
481
        $timeMd5 = md5($timeStr);
482
        $cacheDir = Cache::getDir('static');
483
        if (!file_exists($cacheDir . 'all' . $timeMd5 . '.js')) {
484
            foreach ($urls as $url) {
485
                $scriptAll .= ";\n" . file_get_contents($url);
486
            }
487
            file_put_contents($cacheDir . 'all' . $timeMd5 . '.js', $scriptAll);
488
        }
489
        $options = [
490
            'scripts' => array_values($noParsedScripts),
491
            'compresedScripts' => $nativeUrl,
492
            'styles' => [],
493
            'appRoot' => $this->app->type == 'app' ? '/' : '/' . $this->app->name . '/',
494
            'onLoadModules' => $onLoadModules
495
        ];
496
        $options['scripts'][] = '/' . $cacheDir . 'all' . $timeMd5 . '.js';
497
        $this->widget('View\bodyEnd', compact('options'));
498
    }
499
500
    public function getScripts() {
501
        $scripts = [];
502
        if (!empty($this->libAssets['js'])) {
503
            $this->genScriptArray($this->libAssets['js'], 'libs', $scripts);
504
        }
505
        if (!empty($this->dynAssets['js'])) {
506
            $this->genScriptArray($this->dynAssets['js'], 'custom', $scripts);
507
        }
508
        if (!empty($this->template->config['js'])) {
509
            $this->genScriptArray($this->template->config['js'], 'template', $scripts);
510
        }
511
        return $scripts;
512
    }
513
514
    public function genScriptArray($jsArray, $type = 'custom', &$resultArray) {
515
        switch ($type) {
516
            case 'libs':
517
                foreach ($jsArray as $js) {
518
                    if (is_array($js)) {
519
                        $this->genScriptArray($js, $type, $resultArray);
520
                        continue;
521
                    }
522
                    if (strpos($js, '//') !== false) {
523
                        $href = $js;
524
                    } else {
525
                        $href = $this->getHref('js', $js);
526
                    }
527
                    if (!$href) {
528
                        continue;
529
                    }
530
531
                    $resultArray[] = $href;
532
                }
533
                break;
534
            case 'template':
535
                foreach ($jsArray as $js) {
536
                    if (is_array($js)) {
537
                        $this->genScriptArray($js, $type, $resultArray);
538
                        continue;
539
                    }
540
                    if (strpos($js, '//') !== false) {
541
                        $href = $js;
542
                    } else {
543
                        $href = $this->app->templatesPath . "/{$this->template->name}/js/{$js}";
544
                    }
545
                    $resultArray[] = $href;
546
                }
547
                break;
548
            case 'custom':
549
                foreach ($jsArray as $js) {
550
                    if (is_array($js)) {
551
                        if (!empty($js[0]) && is_array($js[0])) {
552
                            $this->genScriptArray($js, $type, $resultArray);
553
                            continue;
554
                        }
555
                        $asset = $js;
556
                    } else {
557
                        $asset = [];
558
                    }
559
                    $asset['file'] = $this->getHref('js', $js);
560
                    if (!$asset['file']) {
561
                        continue;
562
                    }
563
                    $resultArray[] = $asset;
564
                }
565
                break;
566
        }
567
    }
568
569
    public function customAsset($type, $asset, $lib = false) {
570
        if (!$lib) {
571
            $this->dynAssets[$type][] = $asset;
572
        } else {
573
            if (empty($this->libAssets[$type][$lib]) || !in_array($asset, $this->libAssets[$type][$lib])) {
574
                $this->libAssets[$type][$lib][] = $asset;
575
            }
576
        }
577
    }
578
579
    public function setTitle($title, $add = true) {
580
        if ($add && !empty($this->app->config['site']['name'])) {
581
            if ($title) {
582
                $this->title = $title . ' - ' . $this->app->config['site']['name'];
583
            } else {
584
                $this->title = $this->app->config['site']['name'];
585
            }
586
        } else {
587
            $this->title = $title;
588
        }
589
    }
590
591
    public function widget($_widgetName, $_params = [], $lineParams = null) {
592
        $_paths = $this->getWidgetPaths($_widgetName);
593
        $find = false;
594
        foreach ($_paths as $_path) {
595
            if (file_exists($_path)) {
596
                $find = true;
597
                break;
598
            }
599
        }
600
        if ($lineParams === null) {
601
            $lineParams = '';
602
            if ($_params) {
603
                $paramArray = false;
604
                foreach ($_params as $param) {
605
                    if (is_array($param) || is_object($param)) {
606
                        $paramArray = true;
607
                    }
608
                }
609
                if (!$paramArray) {
610
                    $lineParams = ':' . implode(':', $_params);
611
                }
612
            }
613
        }
614
        echo "<!--start:{WIDGET:{$_widgetName}{$lineParams}}-->\n";
615
        if ($find) {
616
            if ($_params && is_array($_params)) {
617
                extract($_params);
618
            }
619
            include $_path;
620
        }
621
        echo "<!--end:{WIDGET:{$_widgetName}{$lineParams}}-->\n";
622
    }
623
624
    public function getWidgetPaths($widgetName) {
625
        $paths = [];
626
        if (strpos($widgetName, '\\')) {
627
            $widgetName = explode('\\', $widgetName);
628
629
            $paths['templatePath_widgetDir'] = $this->templatesPath . '/' . $this->template->name . '/widgets/' . $widgetName[0] . '/' . $widgetName[1] . '/' . $widgetName[1] . '.php';
630
            $paths['templatePath'] = $this->templatesPath . '/' . $this->template->name . '/widgets/' . $widgetName[0] . '/' . $widgetName[1] . '.php';
631
            $modulePaths = Module::getModulePaths(ucfirst($widgetName[0]));
632
            foreach ($modulePaths as $pathName => $path) {
633
                $paths[$pathName . '_widgetDir'] = $path . '/widgets/' . $widgetName[1] . '/' . $widgetName[1] . '.php';
634
                $paths[$pathName] = $path . '/widgets/' . $widgetName[1] . '.php';
635
            }
636
            return $paths;
637
        } else {
638
            $paths['templatePath_widgetDir'] = $this->templatesPath . '/' . $this->template->name . '/widgets/' . $widgetName . '/' . $widgetName . '.php';
639
            $paths['templatePath'] = $this->templatesPath . '/' . $this->template->name . '/widgets/' . $widgetName . '.php';
640
641
            $paths['curAppPath_widgetDir'] = $this->app->path . '/widgets/' . $widgetName . '/' . $widgetName . '.php';
642
            $paths['curAppPath'] = $this->app->path . '/widgets/' . $widgetName . '.php';
643
644
            $paths['systemPath_widgetDir'] = INJI_SYSTEM_DIR . '/widgets/' . $widgetName . '/' . $widgetName . '.php';
645
            $paths['systemPath'] = INJI_SYSTEM_DIR . '/widgets/' . $widgetName . '.php';
646
        }
647
        return $paths;
648
    }
649
}