PluginProbe
FluentCart A New Era of eCommerce – Faster, Lighter, and Simpler / 1.6.4
FluentCart A New Era of eCommerce – Faster, Lighter, and Simpler v1.6.4
1.6.4 1.6.3 1.6.2 1.6.1 1.6.0 1.5.4 1.5.5 1.5.3 1.5.2 1.5.1 1.5.0 1.4.2 1.4.1 1.4.0 1.3.28 1.3.27 1.3.26 1.3.25 1.3.23 1.3.22 1.3.21 1.3.20 1.3.19 trunk 1.2.0 All 47 releases
fluent-cart / app / Vite.php

Vite.php in FluentCart A New Era of eCommerce – Faster, Lighter, and Simpler 1.6.4, at app/Vite.php

575 lines 17.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace FluentCart\App;
4
5 use Exception;
6 use FluentCart\Framework\Support\Arr;
7
8 class Vite
9 {
10
11 private array $moduleScripts = [];
12 private bool $isScriptFilterAdded = false;
13 private string $viteHostProtocol = 'http://';
14 private string $viteHost = 'localhost';
15 private string $vitePort = '8880';
16 private string $resourceDirectory = 'resources/';
17
18 protected static ?Vite $instance = null;
19 public ?string $lastJsHandel = null;
20 private ?array $manifestData = null;
21
22 public function __construct()
23 {
24 $serverConfigPath = FLUENTCART_PLUGIN_PATH . 'config' . DIRECTORY_SEPARATOR . 'vite.json';
25 if (file_exists($serverConfigPath)) {
26 $serverConfig = json_decode(file_get_contents($serverConfigPath));
27 $this->viteHost = $serverConfig->host ?: $this->viteHost;
28 $this->viteHostProtocol = $serverConfig->protocol ?: $this->viteHostProtocol;
29 $this->vitePort = $serverConfig->port ?: $this->vitePort;
30 }
31 }
32
33 private static function getInstance(): Vite
34 {
35 if (static::$instance === null) {
36 static::$instance = new static();
37 if (!static::$instance->usingDevMode()) {
38 (static::$instance)->loadViteManifest();
39 }
40 }
41
42 return static::$instance;
43 }
44
45 /**
46 * @throws Exception
47 */
48 private function loadViteManifest()
49 {
50 if (!empty($this->manifestData)) {
51 return;
52 }
53 $this->manifestData = App::config()->get('vite_config');
54
55 if (empty($this->manifestData)) {
56 $this->manifestData = [];
57 //throw new Exception('Vite Manifest Not Found. Run : npm run dev or npm run prod');
58 }
59 }
60
61
62 public static function enqueueScript($handle, $src, $dependency = [], $version = null, $inFooter = false): Vite
63 {
64 return static::getInstance()->enqueue_script(
65 $handle,
66 $src,
67 $dependency,
68 $version,
69 $inFooter
70 );
71 }
72
73 private function enqueue_script($handle, $src, $dependency = [], $version = null, $inFooter = false): Vite
74 {
75
76 // if (in_array($handle, $this->moduleScripts)) {
77 // if ($this->usingDevMode()) {
78 // $callerReference = (debug_backtrace(2)[1]);
79 // $fileName = explode('plugins', $callerReference['file']);
80 // $line = $callerReference['line'];
81 // throw new \Exception("This handel Has been used'. 'Filename: $fileName Line: $line");
82 // }
83 // }
84
85 $this->moduleScripts[] = $handle;
86
87 $this->lastJsHandel = $handle;
88
89 if (!$this->isScriptFilterAdded) {
90 add_filter('script_loader_tag', function ($tag, $handle, $src) {
91 return $this->addModuleToScript($tag, $handle, $src);
92 }, 10, 3);
93 $this->isScriptFilterAdded = true;
94 }
95
96
97 if (!$this->usingDevMode()) {
98 $assetFile = $this->getFileFromManifest($src);
99 $srcPath = $this->getProductionFilePath($assetFile);
100 } else {
101 $srcPath = $this->getVitePath() . $src;
102 }
103
104 if (empty($srcPath)) {
105 return $this;
106 }
107
108 $version = empty($version) ? FLUENTCART_VERSION : $version;
109
110 wp_enqueue_script(
111 $handle,
112 $srcPath,
113 $dependency,
114 $version,
115 $inFooter
116 );
117 return $this;
118 }
119
120 private function getFileFromManifest($src)
121 {
122
123 if (isset($this->manifestData[$this->resourceDirectory . $src])) {
124 return $this->manifestData[$this->resourceDirectory . $src];
125 }
126
127 if ($this->usingDevMode()) {
128 throw new \Exception(esc_html($src) . " file not found in vite manifest, Make sure it is in rollupOptions input and build again");
129 }
130
131 return '';
132 }
133
134 private function getProductionFilePath($file): string
135 {
136
137 if (!isset($file['file'])) {
138 return '';
139 }
140 $assetPath = static::getAssetPath();
141
142 $this->ensureChunkCssIsLoaded($file);
143
144 return ($assetPath . $file['file']);
145 }
146
147 private function ensureChunkCssIsLoaded($file)
148 {
149 $assetPath = static::getAssetPath();
150 if (isset($file['css']) && is_array($file['css'])) {
151 foreach ($file['css'] as $key => $path) {
152 wp_enqueue_style(
153 $file['file'] . '_' . $key . '_css',
154 $assetPath . $path,
155 [],
156 FLUENTCART_VERSION
157 );
158 }
159 }
160 }
161
162 public function with($params)
163 {
164
165
166 if (!is_array($params) || !Arr::isAssoc($params) || empty($this->lastJsHandel)) {
167 $this->lastJsHandel = null;
168 return;
169 }
170
171 foreach ($params as $key => $val) {
172 wp_localize_script($this->lastJsHandel, $key, $val);
173 }
174 $this->lastJsHandel = null;
175 }
176
177
178 public static function enqueueStyle($handle, $src, $dependency = [], $version = null, $media = 'all')
179 {
180 static::getInstance()->enqueue_style(
181 $handle,
182 $src,
183 $dependency,
184 $version,
185 $media
186 );
187 }
188
189
190 private function enqueue_style($handle, $src, $dependency = [], $version = null, $media = 'all')
191 {
192 if (!$this->usingDevMode()) {
193 $assetFile = (static::$instance)->getFileFromManifest($src);
194 $srcPath = $this->getProductionFilePath($assetFile);
195 } else {
196 $srcPath = $this->getVitePath() . $src;
197 }
198
199 if (empty($srcPath)) {
200 return;
201 }
202
203 $version = empty($version) ? FLUENTCART_VERSION : $version;
204
205 wp_enqueue_style(
206 $handle,
207 $srcPath,
208 $dependency,
209 $version,
210 $media
211 );
212 }
213
214 public static function enqueueStaticScript($handle, $src, $dependency = [], $version = null, $inFooter = false): Vite
215 {
216 $version = empty($version) ? FLUENTCART_VERSION : $version;
217
218 return static::getInstance()->enqueue_static_script(
219 $handle,
220 $src,
221 $dependency,
222 $version,
223 $inFooter
224 );
225 }
226
227 private function enqueue_static_script($handle, $src, $dependency = [], $version = null, $inFooter = false): Vite
228 {
229 $version = empty($version) ? FLUENTCART_VERSION : $version;
230 wp_enqueue_script(
231 $handle,
232 $this->getStaticEnqueuePath($src),
233 $dependency,
234 $version,
235 $inFooter
236 );
237
238 return $this;
239 }
240
241 private function getStaticEnqueuePath($path): string
242 {
243 if (!$this->usingDevMode()) {
244 $srcPath = $this->get_asset_url($path);
245 } else {
246 $srcPath = $this->getVitePath() . $path;
247 }
248
249 return $srcPath;
250 }
251
252 public static function enqueueStaticStyle($handle, $src, $dependency = [], $version = null, $media = 'all')
253 {
254 $version = empty($version) ? FLUENTCART_VERSION : $version;
255
256 static::getInstance()->enqueue_static_style(
257 $handle, $src, $dependency, $version, $media
258 );
259 }
260
261 private function enqueue_static_style($handle, $src, $dependency = [], $version = null, $media = 'all')
262 {
263
264 $version = empty($version) ? FLUENTCART_VERSION : $version;
265
266 wp_enqueue_style(
267 $handle,
268 $this->getStaticEnqueuePath($src),
269 $dependency,
270 $version,
271 $media
272 );
273 }
274
275
276 public static function underDevelopment(): bool
277 {
278 return static::getInstance()->usingDevMode();
279 }
280
281 public function usingDevMode(): bool
282 {
283 return App::config()->get('app.env') === 'dev';
284 }
285
286 public function getVitePath(): string
287 {
288 $protocol = rtrim($this->viteHostProtocol, ':/');
289 $host = rtrim($this->viteHost, '/');
290 $port = $this->vitePort;
291 $resource = ltrim($this->resourceDirectory, '/');
292
293 return sprintf('%s://%s:%s/%s', $protocol, $host, $port, $resource);
294 }
295
296 public static function getEnqueuePath($path = ''): string
297 {
298 $vite = static::getInstance();
299
300 if (!$vite->usingDevMode()) {
301 $assetFile = $vite->getFileFromManifest($path);
302 $srcPath = $vite->getProductionFilePath($assetFile);
303 } else {
304 $srcPath = $vite->getVitePath() . $path;
305 }
306
307 return $srcPath;
308
309 }
310
311 public static function getAssetUrl($path = ''): string
312 {
313 return esc_url(static::getInstance()->get_asset_url($path) ?? '');
314 }
315
316 private function get_asset_url($path = ''): string
317 {
318 if (!$this->usingDevMode()) {
319 return FLUENTCART_URL . 'assets' . '/' . $path;
320 } else {
321 return $this->getVitePath() . $path;
322 }
323 }
324
325 static function getAssetPath(): string
326 {
327 return App::getInstance()['url.assets'];
328 }
329
330
331 private function addModuleToScript($tag, $handle, $src)
332 {
333
334 if (in_array($handle, (static::$instance)->moduleScripts)) {
335 return wp_get_script_tag(
336 [
337 'src' => esc_url($src),
338 'type' => 'module',
339 'id' => $handle . '-js'
340 ]
341 );
342 }
343 return $tag;
344 }
345
346
347 public static function enqueueAllScripts(array $scripts, string $handlePrefix, $localizeableData = [])
348 {
349 $loopCount = 0;
350 $isLocalized = false;
351 foreach ($scripts as $index => $script) {
352
353 $dependency = [];
354 $version = null;
355 $inFooter = false;
356 $isStatic = false;
357 $handle = false;
358 if (is_array($script)) {
359 $source = Arr::get($script, 'source');
360 $dependency = Arr::get($script, 'dependencies', []);
361 $version = Arr::get($script, 'version');
362 $inFooter = Arr::get($script, 'inFooter', false);
363 $isStatic = Arr::get($script, 'isStatic', false) === true;
364 $handle = Arr::get($script, 'handle', null);
365 } else {
366 $source = $script;
367 }
368
369 if (!$version) {
370 $version = FLUENTCART_VERSION;
371 }
372
373 if (!$handle) {
374 if ($loopCount < 1) {
375 $handle = $handlePrefix;
376 } else {
377 $handle = $handlePrefix . '_' . $index;
378 }
379 }
380
381 if ($isStatic) {
382 $vite = Vite::enqueueStaticScript(
383 $handle,
384 $source,
385 $dependency,
386 $version,
387 $inFooter
388 );
389 } else {
390
391 $vite = Vite::enqueueScript(
392 $handle,
393 $source,
394 $dependency,
395 $version,
396 $inFooter
397 );
398 }
399
400 // Localize the script only once during the first loop iteration,
401 // and only if it's not already localized and the script is not static.
402 if (($loopCount === 0 || !$isLocalized) && !$isStatic) {
403 $vite->with($localizeableData);
404 $isLocalized = true;
405 }
406 $loopCount++;
407 }
408 }
409
410 public static function enqueueAllStyles(array $styles, string $handlePrefix)
411 {
412 $loopCount = 0;
413
414 foreach ($styles as $index => $style) {
415
416 $dependency = [];
417 $version = null;
418 $media = 'all';
419 $isStatic = false;
420 $handle = false;
421 if (is_array($style)) {
422 $source = Arr::get($style, 'source');
423 $dependency = Arr::get($style, 'dependencies', []);
424 $version = Arr::get($style, 'version');
425 $media = Arr::get($style, 'media', false);
426 $isStatic = Arr::get($style, 'isStatic', false) === true;
427 $handle = Arr::get($style, 'handle', false);
428 } else {
429 $source = $style;
430 }
431
432 if (!$handle) {
433 if ($loopCount === 0) {
434 $handle = $handlePrefix;
435 } else {
436 $handle = $handlePrefix . '_' . $index;
437 }
438 }
439
440 $loopCount++;
441
442 if ($isStatic) {
443 Vite::enqueueStaticStyle(
444 $handle,
445 $source,
446 $dependency,
447 $version,
448 $media
449 );
450 } else {
451 Vite::enqueueStyle(
452 $handle,
453 $source,
454 $dependency,
455 $version,
456 $media
457 );
458 }
459 }
460 }
461
462 public static function printAllScripts(array $scripts, string $handlePrefix, $localizeableData = [])
463 {
464 $loopCount = 0;
465 $isLocalized = false;
466 foreach ($scripts as $index => $script) {
467
468 $dependency = [];
469 $version = null;
470 $inFooter = false;
471 $isStatic = false;
472
473 if (is_array($script)) {
474 $source = Arr::get($script, 'source');
475 $dependency = Arr::get($script, 'dependencies', []);
476 $version = Arr::get($script, 'version');
477 $inFooter = Arr::get($script, 'inFooter', false);
478 $isStatic = Arr::get($script, 'isStatic', false) === true;
479 } else {
480 $source = $script;
481 }
482
483 if ($loopCount < 1) {
484 $handle = $handlePrefix;
485 } else {
486 $handle = $handlePrefix . '_' . $index;
487 }
488
489 if (!$version) {
490 $version = FLUENTCART_VERSION;
491 }
492
493 $vite = static::getInstance();
494
495 if ($isStatic) {
496 $srcPath = $vite->getStaticEnqueuePath($source);
497 } else {
498 if (!$vite->usingDevMode()) {
499 $assetFile = $vite->getFileFromManifest($source);
500 $srcPath = $vite->getProductionFilePath($assetFile);
501 } else {
502 $srcPath = $vite->getVitePath() . $source;
503 }
504 }
505
506 if (!empty($srcPath)) {
507 $version = empty($version) ? FLUENTCART_VERSION : $version;
508 $type = !$isStatic && in_array($handle, $vite->moduleScripts) ? 'module' : 'text/javascript';
509
510 echo '<script type="' . esc_attr($type) . '" src="' . esc_url($srcPath) . '?ver=' . esc_attr($version) . '" id="' . esc_attr($handle) . '-js"></script>' . "\n";
511
512 // Localize the script only once during the first loop iteration
513 if (($loopCount === 0 || !$isLocalized) && !$isStatic && !empty($localizeableData)) {
514 foreach ($localizeableData as $key => $val) {
515 echo '<script type="text/javascript" id="' . esc_attr($handle) . '-' . esc_attr($key) . '-js-extra">' . "\n";
516 echo 'var ' . esc_js($key) . ' = ' . wp_json_encode($val) . ';' . "\n";
517 echo '</script>' . "\n";
518 }
519 $isLocalized = true;
520 }
521 }
522 $loopCount++;
523 }
524 }
525
526 public static function printAllStyles(array $styles, string $handlePrefix)
527 {
528 $loopCount = 0;
529
530 foreach ($styles as $index => $style) {
531
532 $dependency = [];
533 $version = null;
534 $media = 'all';
535 $isStatic = false;
536
537 if (is_array($style)) {
538 $source = Arr::get($style, 'source');
539 $dependency = Arr::get($style, 'dependencies', []);
540 $version = Arr::get($style, 'version');
541 $media = Arr::get($style, 'media', 'all');
542 $isStatic = Arr::get($style, 'isStatic', false) === true;
543 } else {
544 $source = $style;
545 }
546
547 if ($loopCount === 0) {
548 $handle = $handlePrefix;
549 } else {
550 $handle = $handlePrefix . '_' . $index;
551 }
552 $loopCount++;
553
554 $vite = static::getInstance();
555
556 if ($isStatic) {
557 $srcPath = $vite->getStaticEnqueuePath($source);
558 } else {
559 if (!$vite->usingDevMode()) {
560 $assetFile = $vite->getFileFromManifest($source);
561 $srcPath = $vite->getProductionFilePath($assetFile);
562 } else {
563 $srcPath = $vite->getVitePath() . $source;
564 }
565 }
566
567 if (!empty($srcPath)) {
568 $version = empty($version) ? FLUENTCART_VERSION : $version;
569 //phpcs:ignore WordPress.WP.EnqueuedResources.NonEnqueuedStylesheet
570 echo '<link rel="stylesheet" id="' . esc_attr($handle) . '-css" href="' . esc_url($srcPath) . '?ver=' . esc_attr($version) . '" type="text/css" media="' . esc_attr($media) . '" />' . "\n";
571 }
572 }
573 }
574 }
575