Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
21 / 21
100.00% covered (success)
100.00%
8 / 8
CRAP
100.00% covered (success)
100.00%
1 / 1
AssetService
100.00% covered (success)
100.00%
21 / 21
100.00% covered (success)
100.00%
8 / 8
11
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 version
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 cdnLink
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 mediaLink
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 hasMediaFile
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 injectTailwindConfig
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
3
 constructCdnPath
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
1
 getCacheBustKey
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
2
1<?php
2
3declare(strict_types=1);
4
5namespace Hyde\Framework\Services;
6
7use Hyde\Hyde;
8use Hyde\Facades\Config;
9use Illuminate\Support\Str;
10
11use function rtrim;
12use function explode;
13use function implode;
14use function md5_file;
15use function file_exists;
16use function str_replace;
17use function preg_replace;
18use function str_contains;
19use function file_get_contents;
20
21/**
22 * Handles the retrieval of core asset files. Commonly used through the Asset facade.
23 *
24 * This class is loaded into the service container, making it easy to access and modify.
25 *
26 * The class also provides helper methods for interacting with versioned files,
27 * as well as the HydeFront CDN service and the media directories.
28 *
29 * @see \Hyde\Facades\Asset
30 */
31class AssetService
32{
33    /** @var string The default HydeFront SemVer tag to load. This constant is set to match the styles used for the installed framework version. */
34    final public const HYDEFRONT_VERSION = 'v3.4';
35
36    /** @var string The default HydeFront CDN path pattern. The Blade-style placeholders are replaced with the proper values. */
37    final public const HYDEFRONT_CDN_URL = 'https://cdn.jsdelivr.net/npm/hydefront@{{ $version }}/dist/{{ $file }}';
38
39    protected string $version = self::HYDEFRONT_VERSION;
40    protected string $cdnUrl = self::HYDEFRONT_CDN_URL;
41
42    public function __construct()
43    {
44        $this->version = Config::getString('hyde.hydefront_version', self::HYDEFRONT_VERSION);
45        $this->cdnUrl = Config::getString('hyde.hydefront_url', self::HYDEFRONT_CDN_URL);
46    }
47
48    public function version(): string
49    {
50        return $this->version;
51    }
52
53    public function cdnLink(string $file): string
54    {
55        return $this->constructCdnPath($file);
56    }
57
58    public function mediaLink(string $file): string
59    {
60        return Hyde::mediaLink($file).$this->getCacheBustKey($file);
61    }
62
63    public function hasMediaFile(string $file): bool
64    {
65        return file_exists(Hyde::mediaPath($file));
66    }
67
68    public function injectTailwindConfig(): string
69    {
70        if (! file_exists(Hyde::path('tailwind.config.js'))) {
71            return '';
72        }
73
74        $config = Str::between(file_get_contents(Hyde::path('tailwind.config.js')), '{', '}');
75
76        // Remove the plugins array, as it is not used in the frontend.
77        if (str_contains($config, 'plugins: [')) {
78            $tokens = explode('plugins: [', $config, 2);
79            $tokens[1] = Str::after($tokens[1], ']');
80            $config = implode('', $tokens);
81        }
82
83        return preg_replace('/\s+/', ' ', "/* tailwind.config.js */ \n".rtrim($config, ",\n\r"));
84    }
85
86    protected function constructCdnPath(string $file): string
87    {
88        return str_replace(
89            ['{{ $version }}', '{{ $file }}'], [$this->version(), $file],
90            $this->cdnUrl
91        );
92    }
93
94    protected function getCacheBustKey(string $file): string
95    {
96        return Config::getBool('hyde.enable_cache_busting', true)
97            ? '?v='.md5_file(Hyde::mediaPath("$file"))
98            : '';
99    }
100}