Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
51 / 51
100.00% covered (success)
100.00%
4 / 4
CRAP
100.00% covered (success)
100.00%
1 / 1
TwigServiceProvider
100.00% covered (success)
100.00%
51 / 51
100.00% covered (success)
100.00%
4 / 4
8
100.00% covered (success)
100.00%
1 / 1
 register
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
2
 boot
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
3
 registerTwigEngine
100.00% covered (success)
100.00%
35 / 35
100.00% covered (success)
100.00%
1 / 1
2
 registerTwigExtensions
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2
3declare(strict_types=1);
4
5namespace Engelsystem\Renderer;
6
7use Engelsystem\Config\Config as EngelsystemConfig;
8use Engelsystem\Container\ServiceProvider;
9use Engelsystem\Renderer\Twig\Extensions\Assets;
10use Engelsystem\Renderer\Twig\Extensions\Authentication;
11use Engelsystem\Renderer\Twig\Extensions\Config;
12use Engelsystem\Renderer\Twig\Extensions\Csrf;
13use Engelsystem\Renderer\Twig\Extensions\Develop;
14use Engelsystem\Renderer\Twig\Extensions\Globals;
15use Engelsystem\Renderer\Twig\Extensions\Legacy;
16use Engelsystem\Renderer\Twig\Extensions\Markdown;
17use Engelsystem\Renderer\Twig\Extensions\Notification;
18use Engelsystem\Renderer\Twig\Extensions\Qr;
19use Engelsystem\Renderer\Twig\Extensions\Session;
20use Engelsystem\Renderer\Twig\Extensions\StringExtension;
21use Engelsystem\Renderer\Twig\Extensions\Translation;
22use Engelsystem\Renderer\Twig\Extensions\Url;
23use Engelsystem\Renderer\Twig\Extensions\Uuid;
24use Symfony\Component\VarDumper\VarDumper;
25use Twig\Environment as Twig;
26use Twig\Extension\CoreExtension as TwigCore;
27use Twig\Loader\LoaderInterface as TwigLoaderInterface;
28use TwigBridge\Extension\Laravel\Model as TwigModel;
29
30class TwigServiceProvider extends ServiceProvider
31{
32    /** @var array<string, class-string> */
33    protected array $extensions = [
34        'assets'         => Assets::class,
35        'authentication' => Authentication::class,
36        'config'         => Config::class,
37        'csrf'           => Csrf::class,
38        'develop'        => Develop::class,
39        'globals'        => Globals::class,
40        'notification'   => Notification::class,
41        'twigmodel'      => TwigModel::class,
42        'session'        => Session::class,
43        'string'         => StringExtension::class,
44        'legacy'         => Legacy::class,
45        'markdown'       => Markdown::class,
46        'qr'             => Qr::class,
47        'translation'    => Translation::class,
48        'url'            => Url::class,
49        'uuid'           => Uuid::class,
50    ];
51
52    public function register(): void
53    {
54        $this->registerTwigEngine();
55
56        foreach ($this->extensions as $alias => $class) {
57            $this->registerTwigExtensions($class, $alias);
58        }
59    }
60
61    public function boot(): void
62    {
63        /** @var Twig $renderer */
64        $renderer = $this->app->get('twig.environment');
65        /** @var Twig $textRenderer */
66        $textRenderer = $this->app->get('twig.textEnvironment');
67
68        foreach ($this->app->tagged('twig.extension') as $extension) {
69            $renderer->addExtension($extension);
70            $textRenderer->addExtension($extension);
71        }
72
73        if (class_exists(VarDumper::class)) {
74            /** @var Develop $dev */
75            $dev = $this->app->get('twig.extension.develop');
76            $dev->setDumper($this->app->make(VarDumper::class));
77        }
78    }
79
80    protected function registerTwigEngine(): void
81    {
82        $viewsPath = $this->app->get('path.views');
83        /** @var EngelsystemConfig $config */
84        $config = $this->app->get('config');
85
86        $twigLoader = $this->app->make(TwigLoader::class, ['paths' => $viewsPath]);
87        $this->app->instance(TwigLoader::class, $twigLoader);
88        $this->app->instance(TwigLoaderInterface::class, $twigLoader);
89        $this->app->instance('twig.loader', $twigLoader);
90
91        $twigTextLoader = $this->app->make(TwigTextLoader::class, ['paths' => $viewsPath]);
92        $this->app->instance('twig.textLoader', $twigTextLoader);
93
94        $cache = $this->app->get('path.cache.views');
95        $twigDebug = false;
96        if ($config->get('environment') == 'development') {
97            $cache = false;
98            $twigDebug = true;
99        }
100
101        $twigOptions =  [
102            'cache'            => $cache,
103            'auto_reload'      => true,
104            'debug'            => $twigDebug,
105            'strict_variables' => $twigDebug,
106        ];
107
108        /** @var Twig $twig */
109        $twig = $this->app->make(Twig::class, ['options' => $twigOptions]);
110        $this->app->instance(Twig::class, $twig);
111        $this->app->instance('twig.environment', $twig);
112
113        /** @var TwigCore $twigCore */
114        $twigCore = $twig->getExtension(TwigCore::class);
115        $twigCore->setTimezone($config->get('timezone'));
116
117        $twigEngine = $this->app->make(TwigEngine::class);
118        $this->app->instance('renderer.twigEngine', $twigEngine);
119
120        /** @var Twig $textTwig */
121        $textTwig = $this->app->make(
122            Twig::class,
123            ['loader' => $twigTextLoader, 'options' => [...$twigOptions, 'autoescape' => false]]
124        );
125        $this->app->instance('twig.textEnvironment', $textTwig);
126        $twigTextEngine = $this->app->make(TwigEngine::class, ['twig' => $textTwig]);
127        $this->app->instance('renderer.twigTextEngine', $twigTextEngine);
128
129        // Text is tagged first to catch .text.twig files
130        $this->app->tag('renderer.twigTextEngine', ['renderer.engine']);
131        $this->app->tag('renderer.twigEngine', ['renderer.engine']);
132    }
133
134    protected function registerTwigExtensions(string $class, string $alias): void
135    {
136        $alias = 'twig.extension.' . $alias;
137
138        $extension = $this->app->make($class);
139
140        $this->app->instance($class, $extension);
141        $this->app->instance($alias, $extension);
142
143        $this->app->tag($alias, ['twig.extension']);
144    }
145}