IncludeTrait   A
last analyzed

Complexity

Total Complexity 28

Size/Duplication

Total Lines 230
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 2

Importance

Changes 0
Metric Value
wmc 28
lcom 1
cbo 2
dl 0
loc 230
rs 10
c 0
b 0
f 0

11 Methods

Rating   Name   Duplication   Size   Complexity  
A _arrayInclude() 0 18 4
A _getAssetType() 0 4 2
A _getCssOutput() 0 15 2
A _getCurrentPath() 0 4 2
A _getCurrentUrlAndOptions() 0 13 2
A _getScriptOutput() 0 7 1
A _getTypeOutput() 0 9 2
A _hasAsset() 0 4 2
B _include() 0 47 7
A _isOnceIncluded() 0 4 2
A _setFetchBlock() 0 8 2
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\View\Helper\Traits;
17
18
use JBZoo\Utils\Str;
19
20
/**
21
 * Class IncludeTrait
22
 *
23
 * @package Core\View\Helper\Traits
24
 * @property \Core\View\Helper\DocumentHelper $Document
25
 * @property \Core\View\Helper\UrlHelper $Url
26
 * @property \Core\View\AppView _View
27
 * @property array _includedAssets
28
 * @property array _assets
29
 * @method \Cake\View\StringTemplate templater()
30
 * @method string formatTemplate($name, $data)
31
 */
32
trait IncludeTrait
33
{
34
35
    /**
36
     * Include array paths.
37
     *
38
     * @param array|string $path
39
     * @param array $options
40
     * @param string $type
41
     * @return bool|null|string
42
     */
43
    protected function _arrayInclude($path, array $options = [], $type = 'css')
44
    {
45
        $doc = $this->Document;
46
        if (is_array($path)) {
47
            $out = '';
48
            foreach ($path as $i) {
49
                $out .= $this->{$type}($i, $options);
50
            }
51
52
            if (empty($options['block'])) {
53
                return $out . $doc->eol;
54
            }
55
56
            return null;
57
        }
58
59
        return false;
60
    }
61
62
    /**
63
     * Get current asset type.
64
     *
65
     * @param string $type
66
     * @return string
67
     */
68
    protected function _getAssetType($type = 'css')
69
    {
70
        return ($type === 'script') ? 'js' : $type;
71
    }
72
73
    /**
74
     * Get current css output.
75
     *
76
     * @param array $options
77
     * @param string $url
78
     * @return string
79
     */
80
    protected function _getCssOutput(array $options, $url)
81
    {
82
        if ($options['rel'] === 'import') {
83
            return $this->formatTemplate('style', [
84
                'attrs'   => $this->templater()->formatAttributes($options, ['rel', 'block', 'weight', 'alias']),
85
                'content' => '@import url(' . $url . ');',
86
            ]);
87
        }
88
89
        return $this->formatTemplate('css', [
90
            'rel'   => $options['rel'],
91
            'url'   => $url,
92
            'attrs' => $this->templater()->formatAttributes($options, ['rel', 'block', 'weight', 'alias']),
93
        ]);
94
    }
95
96
    /**
97
     * Get current asset path.
98
     *
99
     * @param string|array $path
100
     * @param string|array $assetArray
101
     * @return string
102
     */
103
    protected function _getCurrentPath($path, $assetArray)
104
    {
105
        return (is_array($path)) ? (string) $assetArray : (string) $path;
106
    }
107
108
    /**
109
     * Get current options and url asset.
110
     *
111
     * @param string $path
112
     * @param array $options
113
     * @param string $type
114
     * @param bool $external
115
     * @return array
116
     */
117
    protected function _getCurrentUrlAndOptions($path, array $options, $type, $external)
118
    {
119
        if (strpos($path, '//') !== false) {
120
            $url      = $path;
121
            $external = true;
122
            unset($options['fullBase']);
123
        } else {
124
            $url = $this->Url->{$type}($path, $options);
125
            $options = array_diff_key($options, ['fullBase' => null, 'pathPrefix' => null]);
126
        }
127
128
        return [$url, $options, $external];
129
    }
130
131
    /**
132
     * Get current script output.
133
     *
134
     * @param array $options
135
     * @param string $url
136
     * @return string
137
     */
138
    protected function _getScriptOutput(array $options, $url)
139
    {
140
        return $this->formatTemplate('javascriptlink', [
141
            'url'   => $url,
142
            'attrs' => $this->templater()->formatAttributes($options, ['block', 'once', 'weight', 'alias']),
143
        ]);
144
    }
145
146
    /**
147
     * Get current output by type.
148
     *
149
     * @param array $options
150
     * @param string $url
151
     * @param string $type
152
     * @return string
153
     */
154
    protected function _getTypeOutput(array $options, $url, $type)
155
    {
156
        $type = Str::low($type);
157
        if ($type === 'css') {
158
            return $this->_getCssOutput($options, $url);
159
        }
160
161
        return $this->_getScriptOutput($options, $url);
162
    }
163
164
    /**
165
     * Check has asset.
166
     *
167
     * @param string $path
168
     * @param string $type
169
     * @param bool $external
170
     * @return bool
171
     */
172
    protected function _hasAsset($path, $type, $external)
173
    {
174
        return !$this->Url->assetPath($path, $this->_getAssetType($type)) && $external === false;
175
    }
176
177
    /**
178
     * Include asset.
179
     *
180
     * @param string|array $path
181
     * @param array $options
182
     * @param string $type
183
     * @return bool|null|string
184
     */
185
    protected function _include($path, array $options = [], $type = 'css')
186
    {
187
        $doc = $this->Document;
188
        $options += ['once' => true, 'block' => null, 'fullBase' => true, 'weight' => 10];
189
        $external = false;
190
191
        $assetArray = $this->_arrayInclude($path, $options, $type);
192
        if ($assetArray) {
193
            return $assetArray;
194
        }
195
196
        $path = $this->_getCurrentPath($path, $assetArray);
0 ignored issues
show
Bug introduced by
It seems like $assetArray defined by $this->_arrayInclude($path, $options, $type) on line 191 can also be of type false or null; however, Core\View\Helper\Traits\...rait::_getCurrentPath() does only seem to accept string|array, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
197
        if (empty($path)) {
198
            return null;
199
        }
200
201
        $options += ['alias' => Str::slug($path)];
202
        list($url, $options, $external) = $this->_getCurrentUrlAndOptions($path, $options, $type, $external);
203
204
        if (($this->_isOnceIncluded($path, $type, $options)) || $this->_hasAsset($path, $type, $external)) {
205
            return null;
206
        }
207
208
        unset($options['once']);
209
        $this->_includedAssets[$type][$path] = true;
210
211
        $out = $this->_getTypeOutput($options, $url, $type);
212
213
        $options['alias'] = Str::low($options['alias']);
214
        if ($options['block'] === 'assets') {
215
            $this->_assets[$type][$options['alias']] = [
216
                'url'    => $url,
217
                'output' => $out,
218
                'path'   => $path,
219
                'weight' => $options['weight'],
220
            ];
221
222
            return null;
223
        }
224
225
        if (empty($options['block'])) {
226
            return $out;
227
        }
228
229
        $options = $this->_setFetchBlock($options, $type);
230
        $this->_View->append($options['block'], $out . $doc->eol);
231
    }
232
233
    /**
234
     * Check asset on once include.
235
     *
236
     * @param string $path
237
     * @param string $type
238
     * @param array $options
239
     * @return bool
240
     */
241
    protected function _isOnceIncluded($path, $type, array $options = [])
242
    {
243
        return $options['once'] && isset($this->_includedAssets[$type][$path]);
244
    }
245
246
    /**
247
     * Setup default fetch block if option block is true.
248
     *
249
     * @param array $options
250
     * @param string $block
251
     * @return array
252
     */
253
    protected function _setFetchBlock(array $options, $block)
254
    {
255
        if ($options['block'] === true) {
256
            $options['block'] = $block;
257
        }
258
259
        return $options;
260
    }
261
}
262