Passed
Push — master ( 635760...191350 )
by Divine Niiquaye
11:17
created

TwigRender::addExtension()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
c 1
b 0
f 0
nc 1
nop 1
dl 0
loc 3
ccs 0
cts 2
cp 0
crap 2
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of Biurad opensource projects.
7
 *
8
 * PHP version 7.2 and above required
9
 *
10
 * @author    Divine Niiquaye Ibok <[email protected]>
11
 * @copyright 2019 Biurad Group (https://biurad.com/)
12
 * @license   https://opensource.org/licenses/BSD-3-Clause License
13
 *
14
 * For the full copyright and license information, please view the LICENSE
15
 * file that was distributed with this source code.
16
 */
17
18
namespace Biurad\UI\Renders;
19
20
use Biurad\UI\Exceptions\LoaderException;
21
use Biurad\UI\Interfaces\CacheInterface as RenderCacheInterface;
22
use Biurad\UI\Interfaces\RenderInterface;
23
use Biurad\UI\Template;
24
use Twig;
25
use Twig\Cache\FilesystemCache;
26
use Twig\Extension\ExtensionInterface;
27
use Twig\Loader\ArrayLoader;
28
use Twig\Loader\ChainLoader;
29
use Twig\Loader\FilesystemLoader;
30
use Twig\Loader\LoaderInterface;
31
use Twig\NodeVisitor\NodeVisitorInterface;
32
use Twig\RuntimeLoader\RuntimeLoaderInterface;
33
34
/**
35
 * Render for Twig templating.
36
 *
37
 * @author Divine Niiquaye Ibok <[email protected]>
38
 */
39
final class TwigRender extends AbstractRender implements RenderCacheInterface
40
{
41
    protected const EXTENSIONS = ['twig'];
42
43
    /** @var Twig\Environment */
44
    protected $environment;
45
46
    /**
47
     * TwigEngine constructor.
48
     *
49
     * @param string[] $extensions
50
     */
51 4
    public function __construct(Twig\Environment $environment = null, array $extensions = self::EXTENSIONS)
52
    {
53 4
        $this->environment = $environment ?? new Twig\Environment(new ArrayLoader([], true));
0 ignored issues
show
Unused Code introduced by
The call to Twig\Loader\ArrayLoader::__construct() has too many arguments starting with true. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

53
        $this->environment = $environment ?? new Twig\Environment(/** @scrutinizer ignore-call */ new ArrayLoader([], true));

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
54 4
        $this->extensions = $extensions;
55
    }
56
57
    /**
58
     * {@inheritdoc}
59
     */
60 4
    public function withCache(?string $cacheDir): void
61
    {
62 4
        if (null !== $cacheDir) {
63 3
            if (false !== $this->environment->getCache()) {
64
                throw new LoaderException('The Twig render has an existing cache implementation which must be removed.');
65
            }
66
67 3
            $this->environment->setCache(new FilesystemCache($cacheDir));
68
        }
69
    }
70
71
    /**
72
     * {@inheritdoc}
73
     */
74 4
    public function withLoader(Template $loader): RenderInterface
75
    {
76 4
        $this->environment->addFunction(
77 4
            new Twig\TwigFunction(
78
                'template',
79 4
                static function (string $template, array $parameters = []) use ($loader): string {
80 4
                    return $loader->render($template, $parameters);
81
                },
82 4
                ['is_safe' => ['all']]
83
            )
84
        );
85
86 4
        return parent::withLoader($loader);
87
    }
88
89
    /**
90
     * {@inheritdoc}
91
     */
92 4
    public function render(string $template, array $parameters): string
93
    {
94 4
        $source = self::loadHtml($template) ?? $template;
95
96 4
        if ($source !== $template || !\file_exists($template)) {
97
            $loader = new ArrayLoader([$template => $source]);
98
        } else {
99 4
            $loader = new FilesystemLoader([\dirname($template)]);
100 4
            $template = \substr($template, strripos($template, '/'));
101
        }
102
103 4
        $this->addLoader($loader);
104
105 4
        return $this->environment->load($template)->render($parameters);
106
    }
107
108
    public function setCharset(string $charset): void
109
    {
110
        $this->environment->setCharset($charset);
111
    }
112
113 4
    public function addLoader(LoaderInterface $loader): void
114
    {
115 4
        $templateLoader = $this->environment->getLoader();
116
117 4
        if ($templateLoader instanceof ChainLoader) {
118
            $templateLoader->addLoader($loader);
119
120
            return;
121
        }
122
123 4
        if ($loader instanceof ChainLoader) {
124
            $loader->addLoader($templateLoader);
125 4
        } elseif (!$templateLoader instanceof ArrayLoader) {
126 3
            $loader = new ChainLoader([$loader, $templateLoader]);
127
        }
128
129 4
        $this->environment->setLoader($loader);
130
    }
131
132
    public function addRuntimeLoader(RuntimeLoaderInterface $loader): void
133
    {
134
        $this->environment->addRuntimeLoader($loader);
135
    }
136
137
    public function addExtension(ExtensionInterface $extension): void
138
    {
139
        $this->environment->addExtension($extension);
140
    }
141
142
    /**
143
     * @param ExtensionInterface[] $extensions An array of extensions
144
     */
145
    public function setExtensions(array $extensions): void
146
    {
147
        $this->environment->setExtensions($extensions);
148
    }
149
150
    public function addNodeVisitor(NodeVisitorInterface $visitor): void
151
    {
152
        $this->environment->addNodeVisitor($visitor);
153
    }
154
155
    public function addFilter(Twig\TwigFilter $filter): void
156
    {
157
        $this->environment->addFilter($filter);
158
    }
159
160
    public function registerUndefinedFilterCallback(callable $callable): void
161
    {
162
        $this->environment->registerUndefinedFilterCallback($callable);
163
    }
164
165
    public function addFunction(Twig\TwigFunction $function): void
166
    {
167
        $this->environment->addFunction($function);
168
    }
169
}
170