Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
17 / 17
100.00% covered (success)
100.00%
5 / 5
CRAP
100.00% covered (success)
100.00%
1 / 1
TwigRenderer
100.00% covered (success)
100.00%
17 / 17
100.00% covered (success)
100.00%
5 / 5
6
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
1
 getAssetContents
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getAssetUrl
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 render
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
2
 getFallbackFixturesPath
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2namespace Apie\TwigTemplateLayoutRenderer;
3
4use Apie\Core\Context\ApieContext;
5use Apie\Core\Exceptions\InvalidTypeException;
6use Apie\HtmlBuilders\Assets\AssetManager;
7use Apie\HtmlBuilders\Interfaces\ComponentInterface;
8use Apie\HtmlBuilders\Interfaces\ComponentRendererInterface;
9use Apie\TwigTemplateLayoutRenderer\Extension\ComponentHelperExtension;
10use Symfony\UX\Icons\Twig\UXIconRuntime;
11use Twig\Environment;
12use Twig\Loader\FilesystemLoader;
13use WeakMap;
14
15final class TwigRenderer implements ComponentRendererInterface
16{
17    private Environment $twigEnvironment;
18
19    /** @var WeakMap<UXIconRuntime, ComponentHelperExtension> */
20    private static WeakMap $extensions;
21
22    public function __construct(
23        string $path,
24        private AssetManager $assetManager,
25        private string $namespacePrefix,
26        private UXIconRuntime $uxIconRuntime,
27    ) {
28        $loader = new FilesystemLoader([$path, self::getFallbackFixturesPath()]);
29        $this->twigEnvironment = new Environment($loader, []);
30        self::$extensions ??= new WeakMap();
31        $this->twigEnvironment->addExtension(
32            self::$extensions[$uxIconRuntime] ??= new ComponentHelperExtension($uxIconRuntime)
33        );
34    }
35
36    public function getAssetContents(string $filename): string
37    {
38        return $this->assetManager->getAsset($filename)->getContents();
39    }
40
41    public function getAssetUrl(string $filename): string
42    {
43        return $this->assetManager->getAsset($filename)->getBase64Url();
44    }
45
46    public function render(ComponentInterface $component, ApieContext $apieContext): string
47    {
48        $className = get_class($component);
49        if (!str_starts_with($className, $this->namespacePrefix)) {
50            throw new InvalidTypeException($component, 'class in ' . $this->namespacePrefix . ' namespace');
51        }
52        $extension = self::$extensions[$this->uxIconRuntime];
53        $extension->selectComponent($this, $component, $apieContext);
54        try {
55            $templatePath = str_replace('\\', '/', strtolower(substr($className, strlen($this->namespacePrefix)))) . '.html.twig';
56            return $this->twigEnvironment->render($templatePath);
57        } finally {
58            $extension->deselectComponent($component);
59        }
60    }
61
62    final public static function getFallbackFixturesPath(): string
63    {
64        return __DIR__ . '/../resources';
65    }
66}