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