Completed
Push — master ( 89c874...acb1c9 )
by Cheren
15:37
created

IncludeTrait::_hasAsset()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 2
eloc 2
nc 2
nop 3
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
 * @method \Cake\View\StringTemplate templater()
29
 * @method string formatTemplate($name, $data)
30
 */
31
trait IncludeTrait
32
{
33
34
    /**
35
     * Include array paths.
36
     *
37
     * @param array|string $path
38
     * @param array $options
39
     * @param string $type
40
     * @return bool|null|string
41
     */
42
    protected function _arrayInclude($path, array $options = [], $type = 'css')
43
    {
44
        $doc = $this->Document;
45
        if (is_array($path)) {
46
            $out = '';
47
            foreach ($path as $i) {
48
                $out .= $this->{$type}($i, $options);
49
            }
50
51
            if (empty($options['block'])) {
52
                return $out . $doc->eol;
53
            }
54
55
            return null;
56
        }
57
58
        return false;
59
    }
60
61
    /**
62
     * Get current asset type.
63
     *
64
     * @param string $type
65
     * @return string
66
     */
67
    protected function _getAssetType($type = 'css')
68
    {
69
        return ($type == 'script') ? 'js' : $type;
70
    }
71
72
    /**
73
     * Get current css output.
74
     *
75
     * @param array $options
76
     * @param string $url
77
     * @return string
78
     */
79
    protected function _getCssOutput(array $options, $url)
80
    {
81
        if ($options['rel'] === 'import') {
82
            return $this->formatTemplate('style', [
83
                'attrs'   => $this->templater()->formatAttributes($options, ['rel', 'block']),
84
                'content' => '@import url(' . $url . ');',
85
            ]);
86
        }
87
88
        return $this->formatTemplate('css', [
89
            'rel'   => $options['rel'],
90
            'url'   => $url,
91
            'attrs' => $this->templater()->formatAttributes($options, ['rel', 'block']),
92
        ]);
93
    }
94
95
    /**
96
     * Get current asset path.
97
     *
98
     * @param string|array $path
99
     * @param string|array $assetArray
100
     * @return string
101
     */
102
    protected function _getCurrentPath($path, $assetArray)
103
    {
104
        return (is_array($path)) ? (string) $assetArray : (string) $path;
105
    }
106
107
    /**
108
     * Get current options and url asset.
109
     *
110
     * @param string $path
111
     * @param array $options
112
     * @param string $type
113
     * @param bool $external
114
     * @return array
115
     */
116
    protected function _getCurrentUrlAndOptions($path, array $options, $type, $external)
117
    {
118
        if (strpos($path, '//') !== false) {
119
            $url      = $path;
120
            $external = true;
121
            unset($options['fullBase']);
122
        } else {
123
            $url = $this->Url->{$type}($path, $options);
124
            $options = array_diff_key($options, ['fullBase' => null, 'pathPrefix' => null]);
125
        }
126
127
        return [$url, $options, $external];
128
    }
129
130
    /**
131
     * Get current script output.
132
     *
133
     * @param array $options
134
     * @param string $url
135
     * @return string
136
     */
137
    protected function _getScriptOutput(array $options, $url)
138
    {
139
        return $this->formatTemplate('javascriptlink', [
140
            'url'   => $url,
141
            'attrs' => $this->templater()->formatAttributes($options, ['block', 'once']),
142
        ]);
143
    }
144
145
    /**
146
     * Get current output by type.
147
     *
148
     * @param array $options
149
     * @param string $url
150
     * @param string $type
151
     * @return string
152
     */
153
    protected function _getTypeOutput(array $options, $url, $type)
154
    {
155
        $type = Str::low($type);
156
        if ($type == 'css') {
157
            return $this->_getCssOutput($options, $url);
158
        }
159
160
        return $this->_getScriptOutput($options, $url);
161
    }
162
163
    /**
164
     * Check has asset.
165
     *
166
     * @param string $path
167
     * @param string $type
168
     * @param bool $external
169
     * @return bool
170
     */
171
    protected function _hasAsset($path, $type, $external)
172
    {
173
        return !$this->Url->assetPath($path, $this->_getAssetType($type)) && $external === false;
174
    }
175
176
    /**
177
     * Include asset.
178
     *
179
     * @param string|array $path
180
     * @param array $options
181
     * @param string $type
182
     * @return bool|null|string
183
     */
184
    protected function _include($path, array $options = [], $type = 'css')
185
    {
186
        $doc = $this->Document;
187
        $options += ['once' => true, 'block' => null, 'fullBase' => true];
188
        $external = false;
189
190
        $assetArray = $this->_arrayInclude($path, $options, $type);
191
        if ($assetArray) {
192
            return $assetArray;
193
        }
194
195
        $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 190 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...
196
197
        if (empty($path)) {
198
            return null;
199
        }
200
201
        list($url, $options, $external) = $this->_getCurrentUrlAndOptions($path, $options, $type, $external);
202
203
        if (($this->_isOnceIncluded($path, $type, $options)) || $this->_hasAsset($path, $type, $external)) {
204
            return null;
205
        }
206
207
        unset($options['once']);
208
        $this->_includedAssets[$type][$path] = true;
209
210
        $out = $this->_getTypeOutput($options, $url, $type);
211
212
        if (empty($options['block'])) {
213
            return $out;
214
        }
215
216
        $options = $this->_setFetchBlock($options, $type);
217
        $this->_View->append($options['block'], $out . $doc->eol);
218
    }
219
220
    /**
221
     * Check asset on once include.
222
     *
223
     * @param string $path
224
     * @param string $type
225
     * @param array $options
226
     * @return bool
227
     */
228
    protected function _isOnceIncluded($path, $type, array $options = [])
229
    {
230
        return $options['once'] && isset($this->_includedAssets[$type][$path]);
231
    }
232
233
    /**
234
     * Setup default fetch block if option block is true.
235
     *
236
     * @param array $options
237
     * @param string $block
238
     * @return array
239
     */
240
    protected function _setFetchBlock(array $options, $block)
241
    {
242
        if ($options['block'] === true) {
243
            $options['block'] = $block;
244
        }
245
246
        return $options;
247
    }
248
}
249