Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
22 / 22
100.00% covered (success)
100.00%
6 / 6
CRAP
100.00% covered (success)
100.00%
1 / 1
TwigAssetExtension
100.00% covered (success)
100.00%
21 / 21
100.00% covered (success)
100.00%
6 / 6
10
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getFunctions
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
1
 asset
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 registerBundle
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 renderBundleCss
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
3
 renderBundleJs
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
3
1<?php
2
3declare(strict_types=1);
4
5/** @license For full copyright and license information, please see the LICENSE.md file. */
6
7namespace App\Core\Asset;
8
9defined('AMMONLY_APP') || exit('Direct script access is forbidden.');
10
11use Twig\Extension\AbstractExtension;
12use Twig\TwigFunction;
13use Yiisoft\Assets\AssetManager;
14
15/**
16 * TwigAssetExtension.
17 *
18 * Exposes asset() and bundle functions to Twig templates for automated cache busting
19 * and Yii3 AssetManager bundle registration.
20 *
21 * @package App\Core\Asset
22 */
23final class TwigAssetExtension extends AbstractExtension
24{
25    /**
26     * TwigAssetExtension constructor.
27     *
28     * @param AssetManagerInterface $assetManager Asset manager instance.
29     * @param AssetManager|null     $yiiAssetManager Optional Yii3 asset manager instance.
30     */
31    public function __construct(
32        private readonly AssetManagerInterface $assetManager,
33        private readonly ?AssetManager $yiiAssetManager = null,
34    ) {
35    }
36
37    /**
38     * @return array<int, TwigFunction> List of registered Twig functions.
39     */
40    public function getFunctions(): array
41    {
42        return [
43            new TwigFunction('asset', [$this, 'asset']),
44            new TwigFunction('register_asset_bundle', [$this, 'registerBundle']),
45            new TwigFunction('render_bundle_css', [$this, 'renderBundleCss'], ['is_safe' => ['html']]),
46            new TwigFunction('render_bundle_js', [$this, 'renderBundleJs'], ['is_safe' => ['html']]),
47        ];
48    }
49
50    /**
51     * Generates versioned URL for an asset.
52     *
53     * @param string $path Asset relative path.
54     * @return string Versioned asset URL.
55     */
56    public function asset(string $path): string
57    {
58        return $this->assetManager->getAssetUrl($path);
59    }
60
61    /**
62     * Registers a Yii3 AssetBundle class name.
63     *
64     * @param string $bundleClass Fully qualified AssetBundle class-string.
65     * @return void
66     */
67    public function registerBundle(string $bundleClass): void
68    {
69        $this->yiiAssetManager?->register($bundleClass);
70    }
71
72    /**
73     * Renders HTML link tags for all registered CSS bundles.
74     *
75     * @return string HTML link tags.
76     */
77    public function renderBundleCss(): string
78    {
79        if ($this->yiiAssetManager === null) {
80            return '';
81        }
82
83        $html = '';
84        foreach ($this->yiiAssetManager->getCssFiles() as $url => $options) {
85            $html .= sprintf('<link rel="stylesheet" href="%s">' . "\n", htmlspecialchars((string) $url, ENT_QUOTES));
86        }
87
88        return $html;
89    }
90
91    /**
92     * Renders HTML script tags for all registered JS bundles.
93     *
94     * @return string HTML script tags.
95     */
96    public function renderBundleJs(): string
97    {
98        if ($this->yiiAssetManager === null) {
99            return '';
100        }
101
102        $html = '';
103        foreach ($this->yiiAssetManager->getJsFiles() as $url => $options) {
104            $html .= sprintf('<script src="%s" defer></script>' . "\n", htmlspecialchars((string) $url, ENT_QUOTES));
105        }
106
107        return $html;
108    }
109}