Passed
Pull Request — master (#2133)
by Arnaud
09:42 queued 04:08
created

Twig::__construct()   C

Complexity

Conditions 16
Paths 160

Size

Total Lines 104
Code Lines 63

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 63
CRAP Score 16.0241

Importance

Changes 3
Bugs 1 Features 0
Metric Value
cc 16
eloc 63
c 3
b 1
f 0
nc 160
nop 2
dl 0
loc 104
ccs 63
cts 66
cp 0.9545
crap 16.0241
rs 5.0666

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of Cecil.
7
 *
8
 * Copyright (c) Arnaud Ligny <[email protected]>
9
 *
10
 * For the full copyright and license information, please view the LICENSE
11
 * file that was distributed with this source code.
12
 */
13
14
namespace Cecil\Renderer;
15
16
use Cecil\Builder;
17
use Cecil\Exception\RuntimeException;
18
use Cecil\Renderer\Extension\Core as CoreExtension;
19
use Cecil\Util;
20
use Performing\TwigComponents\Configuration;
21
use Symfony\Bridge\Twig\Extension\TranslationExtension;
22
use Symfony\Component\Translation\Formatter\MessageFormatter;
23
use Symfony\Component\Translation\IdentityTranslator;
24
use Symfony\Component\Translation\Translator;
25
use Twig\Extra\Intl\IntlExtension;
26
use Twig\Extra\Cache\CacheExtension;
27
28
/**
29
 * Class Twig.
30
 */
31
class Twig implements RendererInterface
32
{
33
    /** @var Builder */
34
    private $builder;
35
36
    /** @var \Twig\Environment */
37
    private $twig;
38
39
    /** @var Translator */
40
    private $translator = null;
41
42
    /** @var \Twig\Profiler\Profile */
43
    private $profile = null;
44
45
    /**
46
     * {@inheritdoc}
47
     */
48 1
    public function __construct(Builder $builder, $templatesPath)
49
    {
50 1
        $this->builder = $builder;
51
        // load layouts
52 1
        $loader = new \Twig\Loader\FilesystemLoader($templatesPath);
53
        // default options
54 1
        $loaderOptions = [
55 1
            'debug'            => $this->builder->isDebug(),
56 1
            'strict_variables' => true,
57 1
            'autoescape'       => false,
58 1
            'auto_reload'      => true,
59 1
            'cache'            => false,
60 1
        ];
61
        // use Twig cache?
62 1
        if ((bool) $this->builder->getConfig()->get('cache.templates.enabled')) {
63 1
            $loaderOptions = array_replace($loaderOptions, ['cache' => $this->builder->getConfig()->getCacheTemplatesPath()]);
64
        }
65
        // create the Twig instance
66 1
        $this->twig = new \Twig\Environment($loader, $loaderOptions);
67
        // set date format
68 1
        $this->twig->getExtension(\Twig\Extension\CoreExtension::class)
69 1
            ->setDateFormat((string) $this->builder->getConfig()->get('date.format'));
70
        // set timezone
71 1
        if ($this->builder->getConfig()->has('date.timezone')) {
72
            $this->twig->getExtension(\Twig\Extension\CoreExtension::class)
73
                ->setTimezone((string) $this->builder->getConfig()->get('date.timezone') ?? date_default_timezone_get());
74
        }
75
        /*
76
         * adds extensions
77
         */
78
        // Cecil core extension
79 1
        $this->twig->addExtension(new CoreExtension($this->builder));
80
        // required by `template_from_string()`
81 1
        $this->twig->addExtension(new \Twig\Extension\StringLoaderExtension());
82
        // l10n
83 1
        $this->translator = new Translator(
84 1
            $this->builder->getConfig()->getLanguageProperty('locale'),
85 1
            new MessageFormatter(new IdentityTranslator()),
86 1
            (bool) $this->builder->getConfig()->get('cache.templates.enabled') ? $this->builder->getConfig()->getCacheTranslationsPath() : null,
87 1
            $this->builder->isDebug()
88 1
        );
89 1
        if (\count($this->builder->getConfig()->getLanguages()) > 0) {
90 1
            foreach ((array) $this->builder->getConfig()->get('layouts.translations.formats') as $format) {
91 1
                $loader = \sprintf('Symfony\Component\Translation\Loader\%sFileLoader', ucfirst($format));
92 1
                if (class_exists($loader)) {
93 1
                    $this->translator->addLoader($format, new $loader());
94 1
                    $this->builder->getLogger()->debug(\sprintf('Translation loader for format "%s" found', $format));
95
                }
96
            }
97 1
            foreach ($this->builder->getConfig()->getLanguages() as $lang) {
98
                // internal
99 1
                $this->addTransResource($this->builder->getConfig()->getTranslationsInternalPath(), $lang['locale']);
100
                // themes
101 1
                if ($themes = $this->builder->getConfig()->getTheme()) {
102 1
                    foreach ($themes as $theme) {
103 1
                        $this->addTransResource($this->builder->getConfig()->getThemeDirPath($theme, 'translations'), $lang['locale']);
104
                    }
105
                }
106
                // site
107 1
                $this->addTransResource($this->builder->getConfig()->getTranslationsPath(), $lang['locale']);
108
            }
109
        }
110 1
        $this->twig->addExtension(new TranslationExtension($this->translator));
111
        // intl
112 1
        $this->twig->addExtension(new IntlExtension());
113 1
        if (\extension_loaded('intl')) {
114 1
            $this->builder->getLogger()->debug('PHP Intl extension is loaded');
115
        }
116
        // filters fallback
117 1
        $this->twig->registerUndefinedFilterCallback(function ($name) {
118
            switch ($name) {
119 1
                case 'localizeddate':
120 1
                    return new \Twig\TwigFilter($name, function (?\DateTime $value = null) {
121 1
                        return date($this->builder->getConfig()->get('date.format'), $value->getTimestamp());
0 ignored issues
show
Bug introduced by
The method getTimestamp() does not exist on null. ( Ignorable by Annotation )

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

121
                        return date($this->builder->getConfig()->get('date.format'), $value->/** @scrutinizer ignore-call */ getTimestamp());

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
Bug introduced by
It seems like $this->builder->getConfig()->get('date.format') can also be of type null; however, parameter $format of date() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

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

121
                        return date(/** @scrutinizer ignore-type */ $this->builder->getConfig()->get('date.format'), $value->getTimestamp());
Loading history...
122 1
                    });
123
            }
124
125
            return false;
126 1
        });
127
        // components
128 1
        Configuration::make($this->twig)
129 1
            ->setTemplatesPath($this->builder->getConfig()->get('layouts.components.dir') ?? 'components')
130 1
            ->setTemplatesExtension($this->builder->getConfig()->get('layouts.components.ext') ?? 'twig')
131 1
            ->useCustomTags()
132 1
            ->setup();
133
        // cache
134 1
        $this->twig->addExtension(new CacheExtension());
135 1
        $this->twig->addRuntimeLoader(new TwigCacheRuntimeLoader($this->builder->getConfig()->getCacheTemplatesPath()));
136
        // debug
137 1
        if ($this->builder->isDebug()) {
138
            // dump()
139 1
            $this->twig->addExtension(new \Twig\Extension\DebugExtension());
140
            // profiler
141 1
            $this->profile = new \Twig\Profiler\Profile();
142 1
            $this->twig->addExtension(new \Twig\Extension\ProfilerExtension($this->profile));
143
        }
144
        // loads custom extensions
145 1
        if ($this->builder->getConfig()->has('layouts.extensions')) {
146 1
            foreach ((array) $this->builder->getConfig()->get('layouts.extensions') as $name => $class) {
147
                try {
148 1
                    $this->twig->addExtension(new $class($this->builder));
149 1
                    $this->builder->getLogger()->debug(\sprintf('Twig extension "%s" added', $name));
150 1
                } catch (RuntimeException | \Error $e) {
151 1
                    $this->builder->getLogger()->error(\sprintf('Unable to add Twig extension "%s": %s', $name, $e->getMessage()));
152
                }
153
            }
154
        }
155
    }
156
157
    /**
158
     * {@inheritdoc}
159
     */
160 1
    public function addGlobal(string $name, $value): void
161
    {
162 1
        $this->twig->addGlobal($name, $value);
163
    }
164
165
    /**
166
     * {@inheritdoc}
167
     */
168 1
    public function render(string $template, array $variables): string
169
    {
170 1
        return $this->twig->render($template, $variables);
171
    }
172
173
    /**
174
     * {@inheritdoc}
175
     */
176 1
    public function setLocale(string $locale): void
177
    {
178 1
        if (\extension_loaded('intl')) {
179 1
            \Locale::setDefault($locale);
180
        }
181 1
        $this->translator === null ?: $this->translator->setLocale($locale);
182
    }
183
184
    /**
185
     * {@inheritdoc}
186
     */
187 1
    public function addTransResource(string $translationsDir, string $locale): void
188
    {
189 1
        $locales = [$locale];
190
        // if locale is 'fr_FR', trying to load ['fr', 'fr_FR']
191 1
        if (\strlen($locale) > 2) {
192 1
            array_unshift($locales, substr($locale, 0, 2));
193
        }
194 1
        foreach ($locales as $locale) {
195 1
            foreach ((array) $this->builder->getConfig()->get('layouts.translations.formats') as $format) {
196 1
                $translationFile = Util::joinPath($translationsDir, \sprintf('messages.%s.%s', $locale, $format));
197 1
                if (Util\File::getFS()->exists($translationFile)) {
198 1
                    $this->translator->addResource($format, $translationFile, $locale);
199 1
                    $this->builder->getLogger()->debug(\sprintf('Translation file "%s" added', $translationFile));
200
                }
201
            }
202
        }
203
    }
204
205
    /**
206
     * {@inheritdoc}
207
     */
208 1
    public function getDebugProfile(): ?\Twig\Profiler\Profile
209
    {
210 1
        return $this->profile;
211
    }
212
213
    /**
214
     * Returns the Twig instance.
215
     */
216
    public function getTwig(): \Twig\Environment
217
    {
218
        return $this->twig;
219
    }
220
}
221