1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace Botble\Assets; |
4
|
|
|
|
5
|
|
|
use Illuminate\Config\Repository; |
6
|
|
|
|
7
|
|
|
/** |
8
|
|
|
* Class Assets. |
9
|
|
|
* |
10
|
|
|
* @since 22/07/2015 11:23 PM |
11
|
|
|
*/ |
12
|
|
|
class Assets |
13
|
|
|
{ |
14
|
|
|
/** |
15
|
|
|
* @var Repository |
16
|
|
|
*/ |
17
|
|
|
protected $config; |
18
|
|
|
|
19
|
|
|
/** |
20
|
|
|
* @var HtmlBuilder |
21
|
|
|
*/ |
22
|
|
|
protected $htmlBuilder; |
23
|
|
|
|
24
|
|
|
/** |
25
|
|
|
* @var array |
26
|
|
|
*/ |
27
|
|
|
protected $scripts = []; |
28
|
|
|
|
29
|
|
|
/** |
30
|
|
|
* @var array |
31
|
|
|
*/ |
32
|
|
|
protected $styles = []; |
33
|
|
|
|
34
|
|
|
/** |
35
|
|
|
* @var array |
36
|
|
|
*/ |
37
|
|
|
protected $appendedScripts = [ |
38
|
|
|
'header' => [], |
39
|
|
|
'footer' => [], |
40
|
|
|
]; |
41
|
|
|
|
42
|
|
|
/** |
43
|
|
|
* @var array |
44
|
|
|
*/ |
45
|
|
|
protected $appendedStyles = []; |
46
|
|
|
|
47
|
|
|
/** |
48
|
|
|
* @var string |
49
|
|
|
*/ |
50
|
|
|
protected $build = ''; |
51
|
|
|
|
52
|
|
|
const ASSETS_SCRIPT_POSITION_HEADER = 'header'; |
53
|
|
|
|
54
|
|
|
const ASSETS_SCRIPT_POSITION_FOOTER = 'footer'; |
55
|
|
|
|
56
|
|
|
/** |
57
|
|
|
* Assets constructor. |
58
|
|
|
* |
59
|
|
|
* @param Repository $config |
60
|
|
|
* @param HtmlBuilder $htmlBuilder |
61
|
|
|
*/ |
62
|
|
|
public function __construct(Repository $config, HtmlBuilder $htmlBuilder) |
63
|
|
|
{ |
64
|
|
|
$this->config = $config->get('assets'); |
65
|
|
|
|
66
|
|
|
$this->scripts = $this->config['scripts']; |
67
|
|
|
|
68
|
|
|
$this->styles = $this->config['styles']; |
69
|
|
|
|
70
|
|
|
$this->htmlBuilder = $htmlBuilder; |
71
|
|
|
} |
72
|
|
|
|
73
|
|
|
/** |
74
|
|
|
* Add scripts to current module. |
75
|
|
|
* |
76
|
|
|
* @param array $assets |
77
|
|
|
* @return $this |
78
|
|
|
*/ |
79
|
|
|
public function addScripts($assets) |
80
|
|
|
{ |
81
|
|
|
if (!is_array($assets)) { |
82
|
|
|
$assets = [$assets]; |
83
|
|
|
} |
84
|
|
|
|
85
|
|
|
$this->scripts = array_merge($this->scripts, $assets); |
86
|
|
|
|
87
|
|
|
return $this; |
88
|
|
|
} |
89
|
|
|
|
90
|
|
|
/** |
91
|
|
|
* Add Css to current module. |
92
|
|
|
* |
93
|
|
|
* @param array $assets |
94
|
|
|
* @return $this |
95
|
|
|
*/ |
96
|
|
|
public function addStyles($assets) |
97
|
|
|
{ |
98
|
|
|
if (!is_array($assets)) { |
99
|
|
|
$assets = [$assets]; |
100
|
|
|
} |
101
|
|
|
|
102
|
|
|
$this->styles = array_merge($this->styles, $assets); |
103
|
|
|
|
104
|
|
|
return $this; |
105
|
|
|
} |
106
|
|
|
|
107
|
|
|
/** |
108
|
|
|
* Add styles directly. |
109
|
|
|
* |
110
|
|
|
* @param array|string $assets |
111
|
|
|
* @return $this |
112
|
|
|
*/ |
113
|
|
|
public function addStylesDirectly($assets) |
114
|
|
|
{ |
115
|
|
|
if (!is_array($assets)) { |
116
|
|
|
$assets = [$assets]; |
117
|
|
|
} |
118
|
|
|
|
119
|
|
View Code Duplication |
foreach ($assets as &$item) { |
|
|
|
|
120
|
|
|
if (!in_array($item, $this->appendedStyles)) { |
121
|
|
|
$this->appendedStyles[] = [ |
122
|
|
|
'src' => $item, |
123
|
|
|
'attributes' => [], |
124
|
|
|
]; |
125
|
|
|
} |
126
|
|
|
} |
127
|
|
|
|
128
|
|
|
return $this; |
129
|
|
|
} |
130
|
|
|
|
131
|
|
|
/** |
132
|
|
|
* Add scripts directly. |
133
|
|
|
* |
134
|
|
|
* @param string|array $assets |
135
|
|
|
* @param string $location |
136
|
|
|
* @return $this |
137
|
|
|
*/ |
138
|
|
|
public function addScriptsDirectly($assets, $location = self::ASSETS_SCRIPT_POSITION_FOOTER) |
139
|
|
|
{ |
140
|
|
|
if (!is_array($assets)) { |
141
|
|
|
$assets = [$assets]; |
142
|
|
|
} |
143
|
|
|
|
144
|
|
View Code Duplication |
foreach ($assets as &$item) { |
|
|
|
|
145
|
|
|
if (!in_array($item, $this->appendedScripts[$location])) { |
146
|
|
|
$this->appendedScripts[$location][] = [ |
147
|
|
|
'src' => $item, |
148
|
|
|
'attributes' => [], |
149
|
|
|
]; |
150
|
|
|
} |
151
|
|
|
} |
152
|
|
|
|
153
|
|
|
return $this; |
154
|
|
|
} |
155
|
|
|
|
156
|
|
|
/** |
157
|
|
|
* Remove Css to current module. |
158
|
|
|
* |
159
|
|
|
* @param array $assets |
160
|
|
|
* @return $this |
161
|
|
|
*/ |
162
|
|
View Code Duplication |
public function removeStyles($assets) |
|
|
|
|
163
|
|
|
{ |
164
|
|
|
if (!is_array($assets)) { |
165
|
|
|
$assets = [$assets]; |
166
|
|
|
} |
167
|
|
|
|
168
|
|
|
foreach ($assets as $rem) { |
169
|
|
|
array_forget($this->styles, array_search($rem, $this->styles)); |
170
|
|
|
} |
171
|
|
|
|
172
|
|
|
return $this; |
173
|
|
|
} |
174
|
|
|
|
175
|
|
|
/** |
176
|
|
|
* Add scripts. |
177
|
|
|
* |
178
|
|
|
* @param array $assets |
179
|
|
|
* @return $this |
180
|
|
|
*/ |
181
|
|
View Code Duplication |
public function removeScripts($assets) |
|
|
|
|
182
|
|
|
{ |
183
|
|
|
if (!is_array($assets)) { |
184
|
|
|
$assets = [$assets]; |
185
|
|
|
} |
186
|
|
|
|
187
|
|
|
foreach ($assets as $rem) { |
188
|
|
|
array_forget($this->scripts, array_search($rem, $this->scripts)); |
189
|
|
|
} |
190
|
|
|
|
191
|
|
|
return $this; |
192
|
|
|
} |
193
|
|
|
|
194
|
|
|
/** |
195
|
|
|
* Get All scripts in current module. |
196
|
|
|
* |
197
|
|
|
* @param string $location `header` or `footer` |
198
|
|
|
* @return array |
199
|
|
|
*/ |
200
|
|
|
public function getScripts($location = null) |
201
|
|
|
{ |
202
|
|
|
$scripts = []; |
203
|
|
|
|
204
|
|
|
$this->scripts = array_unique($this->scripts); |
205
|
|
|
|
206
|
|
|
foreach ($this->scripts as $script) { |
207
|
|
|
$configName = 'resources.scripts.' . $script; |
208
|
|
|
|
209
|
|
|
if (array_has($this->config, $configName)) { |
210
|
|
|
if (!empty($location) && $location !== array_get($this->config, $configName . '.location')) { |
211
|
|
|
continue; // Skip assets that don't match this location |
212
|
|
|
} |
213
|
|
|
|
214
|
|
|
$scripts = array_merge($scripts, $this->getScriptItem($location, $configName, $script)); |
215
|
|
|
} |
216
|
|
|
} |
217
|
|
|
|
218
|
|
|
if (isset($this->appendedScripts[$location])) { |
219
|
|
|
$scripts = array_merge($scripts, $this->appendedScripts[$location]); |
220
|
|
|
} |
221
|
|
|
|
222
|
|
|
return $scripts; |
223
|
|
|
} |
224
|
|
|
|
225
|
|
|
/** |
226
|
|
|
* Get All CSS in current module. |
227
|
|
|
* |
228
|
|
|
* @param array $lastStyles Append last CSS to current module |
229
|
|
|
* @return array |
230
|
|
|
*/ |
231
|
|
|
public function getStyles($lastStyles = []) |
232
|
|
|
{ |
233
|
|
|
$styles = []; |
234
|
|
|
if (!empty($lastStyles)) { |
235
|
|
|
$this->styles = array_merge($this->styles, $lastStyles); |
236
|
|
|
} |
237
|
|
|
|
238
|
|
|
$this->styles = array_unique($this->styles); |
239
|
|
|
|
240
|
|
|
foreach ($this->styles as $style) { |
241
|
|
|
$configName = 'resources.styles.' . $style; |
242
|
|
|
|
243
|
|
|
if (array_has($this->config, $configName)) { |
244
|
|
|
$src = array_get($this->config, $configName . '.src.local'); |
245
|
|
|
|
246
|
|
|
$attributes = array_get($this->config, $configName . '.attributes', []); |
247
|
|
|
|
248
|
|
View Code Duplication |
if (array_get($this->config, $configName . '.use_cdn') && !$this->config['offline']) { |
|
|
|
|
249
|
|
|
$src = array_get($this->config, $configName . '.src.cdn'); |
250
|
|
|
|
251
|
|
|
$attributes = []; |
252
|
|
|
} |
253
|
|
|
|
254
|
|
|
foreach ((array)$src as $s) { |
255
|
|
|
$styles[] = [ |
256
|
|
|
'src' => $s, |
257
|
|
|
'attributes' => $attributes, |
258
|
|
|
]; |
259
|
|
|
} |
260
|
|
|
} |
261
|
|
|
} |
262
|
|
|
|
263
|
|
|
return array_merge($styles, $this->appendedStyles); |
264
|
|
|
} |
265
|
|
|
|
266
|
|
|
/** |
267
|
|
|
* Convert script to html. |
268
|
|
|
* |
269
|
|
|
* @param string $name |
270
|
|
|
* @return string|null |
271
|
|
|
*/ |
272
|
|
|
public function scriptToHtml($name) |
273
|
|
|
{ |
274
|
|
|
return $this->itemToHtml($name, 'script'); |
275
|
|
|
} |
276
|
|
|
|
277
|
|
|
/** |
278
|
|
|
* Convert style to html. |
279
|
|
|
* |
280
|
|
|
* @param string $name |
281
|
|
|
*/ |
282
|
|
|
public function styleToHtml($name) |
283
|
|
|
{ |
284
|
|
|
return $this->itemToHtml($name, 'style'); |
285
|
|
|
} |
286
|
|
|
|
287
|
|
|
/** |
288
|
|
|
* Render assets to header. |
289
|
|
|
* |
290
|
|
|
* @param array $lastStyles |
291
|
|
|
* @return string |
292
|
|
|
* @throws \Throwable |
293
|
|
|
*/ |
294
|
|
|
public function renderHeader($lastStyles = []) |
295
|
|
|
{ |
296
|
|
|
$styles = $this->getStyles($lastStyles); |
297
|
|
|
|
298
|
|
|
$headScripts = $this->getScripts(self::ASSETS_SCRIPT_POSITION_HEADER); |
299
|
|
|
|
300
|
|
|
return view('assets::header', compact('styles', 'headScripts'))->render(); |
|
|
|
|
301
|
|
|
} |
302
|
|
|
|
303
|
|
|
/** |
304
|
|
|
* Render assets to footer. |
305
|
|
|
* |
306
|
|
|
* @return string |
307
|
|
|
* @throws \Throwable |
308
|
|
|
*/ |
309
|
|
|
public function renderFooter() |
310
|
|
|
{ |
311
|
|
|
$bodyScripts = $this->getScripts(self::ASSETS_SCRIPT_POSITION_FOOTER); |
312
|
|
|
|
313
|
|
|
return view('assets::footer', compact('bodyScripts'))->render(); |
|
|
|
|
314
|
|
|
} |
315
|
|
|
|
316
|
|
|
/** |
317
|
|
|
* Get script item. |
318
|
|
|
* |
319
|
|
|
* @param string $location |
320
|
|
|
* @param string $configName |
321
|
|
|
* @param string $script |
322
|
|
|
* @return array |
323
|
|
|
*/ |
324
|
|
|
protected function getScriptItem($location, $configName, $script) |
325
|
|
|
{ |
326
|
|
|
$scripts = []; |
327
|
|
|
|
328
|
|
|
$src = array_get($this->config, $configName . '.src.local'); |
329
|
|
|
|
330
|
|
|
$cdn = false; |
331
|
|
|
|
332
|
|
|
$attributes = array_get($this->config, $configName . '.attributes', []); |
333
|
|
|
|
334
|
|
View Code Duplication |
if (array_get($this->config, $configName . '.use_cdn') && !$this->config['offline']) { |
|
|
|
|
335
|
|
|
$src = array_get($this->config, $configName . '.src.cdn'); |
336
|
|
|
|
337
|
|
|
$cdn = true; |
338
|
|
|
|
339
|
|
|
$attributes = []; |
340
|
|
|
} |
341
|
|
|
|
342
|
|
|
if (!is_array($src)) { |
343
|
|
|
$scripts[] = [ |
344
|
|
|
'src' => $src, |
345
|
|
|
'attributes' => $attributes, |
346
|
|
|
]; |
347
|
|
|
} else { |
348
|
|
|
foreach ($src as $s) { |
349
|
|
|
$scripts[] = [ |
350
|
|
|
'src' => $s, |
351
|
|
|
'attributes' => $attributes, |
352
|
|
|
]; |
353
|
|
|
} |
354
|
|
|
} |
355
|
|
|
|
356
|
|
|
if (empty($src) && |
357
|
|
|
$cdn && |
358
|
|
|
$location === self::ASSETS_SCRIPT_POSITION_HEADER && |
359
|
|
|
array_has($this->config, $configName . '.fallback')) { |
360
|
|
|
$scripts[] = $this->getFallbackScript($src, $configName); |
361
|
|
|
} |
362
|
|
|
|
363
|
|
|
if (array_get($this->config, $configName . '.include_style')) { |
364
|
|
|
$this->addStyles([$script]); |
365
|
|
|
} |
366
|
|
|
|
367
|
|
|
return $scripts; |
368
|
|
|
} |
369
|
|
|
|
370
|
|
|
/** |
371
|
|
|
* Fallback to local script if CDN fails. |
372
|
|
|
* |
373
|
|
|
* @param string $src |
374
|
|
|
* @param string $configName |
375
|
|
|
* @return array |
376
|
|
|
*/ |
377
|
|
|
protected function getFallbackScript($src, $configName) |
378
|
|
|
{ |
379
|
|
|
return [ |
380
|
|
|
'src' => $src, |
381
|
|
|
'fallback' => array_get($this->config, $configName . '.fallback'), |
382
|
|
|
'fallbackURL' => array_get($this->config, $configName . '.src.local'), |
383
|
|
|
]; |
384
|
|
|
} |
385
|
|
|
|
386
|
|
|
/** |
387
|
|
|
* Convert item to html. |
388
|
|
|
* |
389
|
|
|
* @param string $name |
390
|
|
|
* @param string $type |
391
|
|
|
* @return null|string |
392
|
|
|
*/ |
393
|
|
|
protected function itemToHtml($name, $type = 'style') |
394
|
|
|
{ |
395
|
|
|
$html = ''; |
396
|
|
|
|
397
|
|
|
if (!in_array($type, ['style', 'script'])) { |
398
|
|
|
return $html; |
399
|
|
|
} |
400
|
|
|
|
401
|
|
|
$config = 'resources.styles.' . $name; |
402
|
|
|
|
403
|
|
|
if ($type === 'script') { |
404
|
|
|
$config = 'resources.scripts.' . $name; |
405
|
|
|
} |
406
|
|
|
|
407
|
|
|
if (array_has($this->config, $config)) { |
408
|
|
|
$src = array_get($this->config, $config . '.src.local'); |
409
|
|
|
|
410
|
|
View Code Duplication |
if (array_get($this->config, $config . '.use_cdn') && !$this->config['offline']) { |
|
|
|
|
411
|
|
|
$src = array_get($this->config, $config . '.src.cdn'); |
412
|
|
|
} |
413
|
|
|
|
414
|
|
|
if (!is_array($src)) { |
415
|
|
|
$src = [$src]; |
416
|
|
|
} |
417
|
|
|
|
418
|
|
|
foreach ($src as $item) { |
419
|
|
|
$html .= $this->{$type}($item, ['class' => 'hidden'])->toHtml(); |
420
|
|
|
} |
421
|
|
|
} |
422
|
|
|
|
423
|
|
|
return $html; |
424
|
|
|
} |
425
|
|
|
|
426
|
|
|
/** |
427
|
|
|
* @return string |
428
|
|
|
*/ |
429
|
|
|
public function getBuildVersion() |
430
|
|
|
{ |
431
|
|
|
return $this->build = $this->config['enable_version'] ? '?v=' . $this->config['version'] : ''; |
432
|
|
|
} |
433
|
|
|
|
434
|
|
|
/** |
435
|
|
|
* @return HtmlBuilder |
436
|
|
|
*/ |
437
|
|
|
public function getHtmlBuilder() |
438
|
|
|
{ |
439
|
|
|
return $this->htmlBuilder; |
440
|
|
|
} |
441
|
|
|
} |
442
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.