Passed
Pull Request — master (#2045)
by Arnaud
06:45
created

Twig::__construct()   C

Complexity

Conditions 16
Paths 160

Size

Total Lines 101
Code Lines 61

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 61
CRAP Score 16.0264

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 16
eloc 61
c 1
b 0
f 0
nc 160
nop 2
dl 0
loc 101
ccs 61
cts 64
cp 0.9531
crap 16.0264
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
27
/**
28
 * Class Twig.
29
 */
30
class Twig implements RendererInterface
31
{
32
    /** @var Builder */
33
    private $builder;
34
35
    /** @var \Twig\Environment */
36
    private $twig;
37
38
    /** @var Translator */
39
    private $translator = null;
40
41
    /** @var \Twig\Profiler\Profile */
42
    private $profile = null;
43
44
    /**
45
     * {@inheritdoc}
46
     */
47 1
    public function __construct(Builder $builder, $templatesPath)
48
    {
49 1
        $this->builder = $builder;
50
        // load layouts
51 1
        $loader = new \Twig\Loader\FilesystemLoader($templatesPath);
52
        // default options
53 1
        $loaderOptions = [
54 1
            'debug'            => $this->builder->isDebug(),
55 1
            'strict_variables' => true,
56 1
            'autoescape'       => false,
57 1
            'auto_reload'      => true,
58 1
            'cache'            => false,
59 1
        ];
60
        // use Twig cache?
61 1
        if ((bool) $this->builder->getConfig()->get('cache.templates.enabled')) {
62 1
            $loaderOptions = array_replace($loaderOptions, ['cache' => $this->builder->getConfig()->getCacheTemplatesPath()]);
63
        }
64
        // create the Twig instance
65 1
        $this->twig = new \Twig\Environment($loader, $loaderOptions);
66
        // set date format
67 1
        $this->twig->getExtension(\Twig\Extension\CoreExtension::class)
68 1
            ->setDateFormat((string) $this->builder->getConfig()->get('date.format'));
69
        // set timezone
70 1
        if ($this->builder->getConfig()->has('date.timezone')) {
71
            $this->twig->getExtension(\Twig\Extension\CoreExtension::class)
72
                ->setTimezone((string) $this->builder->getConfig()->get('date.timezone') ?? date_default_timezone_get());
73
        }
74
        /*
75
         * adds extensions
76
         */
77
        // Cecil core extension
78 1
        $this->twig->addExtension(new CoreExtension($this->builder));
79
        // required by `template_from_string()`
80 1
        $this->twig->addExtension(new \Twig\Extension\StringLoaderExtension());
81
        // l10n
82 1
        $this->translator = new Translator(
83 1
            $this->builder->getConfig()->getLanguageProperty('locale'),
84 1
            new MessageFormatter(new IdentityTranslator()),
85 1
            (bool) $this->builder->getConfig()->get('cache.templates.enabled') ? $this->builder->getConfig()->getCacheTranslationsPath() : null,
86 1
            $this->builder->isDebug()
87 1
        );
88 1
        if (\count($this->builder->getConfig()->getLanguages()) > 0) {
89 1
            foreach ((array) $this->builder->getConfig()->get('layouts.translations.formats') as $format) {
90 1
                $loader = \sprintf('Symfony\Component\Translation\Loader\%sFileLoader', ucfirst($format));
91 1
                if (class_exists($loader)) {
92 1
                    $this->translator->addLoader($format, new $loader());
93 1
                    $this->builder->getLogger()->debug(\sprintf('Translation loader for format "%s" found', $format));
94
                }
95
            }
96 1
            foreach ($this->builder->getConfig()->getLanguages() as $lang) {
97
                // internal
98 1
                $this->addTransResource($this->builder->getConfig()->getTranslationsInternalPath(), $lang['locale']);
99
                // themes
100 1
                if ($themes = $this->builder->getConfig()->getTheme()) {
101 1
                    foreach ($themes as $theme) {
102 1
                        $this->addTransResource($this->builder->getConfig()->getThemeDirPath($theme, 'translations'), $lang['locale']);
103
                    }
104
                }
105
                // site
106 1
                $this->addTransResource($this->builder->getConfig()->getTranslationsPath(), $lang['locale']);
107
            }
108
        }
109 1
        $this->twig->addExtension(new TranslationExtension($this->translator));
110
        // intl
111 1
        $this->twig->addExtension(new IntlExtension());
112 1
        if (\extension_loaded('intl')) {
113 1
            $this->builder->getLogger()->debug('PHP Intl extension is loaded');
114
        }
115
        // filters fallback
116 1
        $this->twig->registerUndefinedFilterCallback(function ($name) {
117
            switch ($name) {
118 1
                case 'localizeddate':
119 1
                    return new \Twig\TwigFilter($name, function (?\DateTime $value = null) {
120 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

120
                        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

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