Passed
Pull Request — master (#1676)
by Arnaud
05:15 queued 14s
created

Twig::__construct()   C

Complexity

Conditions 15
Paths 96

Size

Total Lines 93
Code Lines 54

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 51
CRAP Score 15.3956

Importance

Changes 0
Metric Value
cc 15
eloc 54
c 0
b 0
f 0
nc 96
nop 2
dl 0
loc 93
ccs 51
cts 58
cp 0.8793
crap 15.3956
rs 5.9166

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

118
                        return date($this->builder->getConfig()->get('date.format') ?? 'F j, Y', $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...
119 1
                    });
120
            }
121
122
            return false;
123 1
        });
124
        // debug
125 1
        if ($this->builder->isDebug()) {
126
            // dump()
127 1
            $this->twig->addExtension(new \Twig\Extension\DebugExtension());
128
            // profiler
129 1
            $this->profile = new \Twig\Profiler\Profile();
130 1
            $this->twig->addExtension(new \Twig\Extension\ProfilerExtension($this->profile));
131
        }
132
        // loads custom extensions
133 1
        if ($this->builder->getConfig()->has('layouts.extensions')) {
134 1
            Util::autoload($builder, 'extensions');
135 1
            foreach ((array) $this->builder->getConfig()->get('layouts.extensions') as $name => $class) {
136 1
                $this->twig->addExtension(new $class($this->builder));
137 1
                $this->builder->getLogger()->debug(sprintf('Extension "%s" (%s) added.', $name, $class));
138
            }
139
        }
140
    }
141
142
    /**
143
     * {@inheritdoc}
144
     */
145 1
    public function addGlobal(string $name, $value): void
146
    {
147 1
        $this->twig->addGlobal($name, $value);
148
    }
149
150
    /**
151
     * {@inheritdoc}
152
     */
153 1
    public function render(string $template, array $variables): string
154
    {
155 1
        return $this->twig->render($template, $variables);
156
    }
157
158
    /**
159
     * {@inheritdoc}
160
     */
161 1
    public function setLocale(string $locale): void
162
    {
163 1
        if (\extension_loaded('intl')) {
164 1
            \Locale::setDefault($locale);
165
        }
166 1
        $this->translator === null ?: $this->translator->setLocale($locale);
167
    }
168
169
    /**
170
     * {@inheritdoc}
171
     */
172 1
    public function addTransResource(string $translationsDir, string $locale): void
173
    {
174 1
        $locales = [$locale];
175
        // if locale is 'fr_FR', trying to load ['fr', 'fr_FR']
176 1
        if (\strlen($locale) > 2) {
177 1
            array_unshift($locales, substr($locale, 0, 2));
178
        }
179 1
        foreach ($locales as $locale) {
180 1
            foreach ((array) $this->builder->getConfig()->get('translations.formats') as $format) {
181
                $translationFile = Util::joinPath($translationsDir, sprintf('messages.%s.%s', $locale, $format));
182
                if (Util\File::getFS()->exists($translationFile)) {
183
                    $this->translator->addResource($format, $translationFile, $locale);
184
                    $this->builder->getLogger()->debug(sprintf('Translation file "%s" added', $translationFile));
185
                }
186
            }
187
        }
188
    }
189
190
    /**
191
     * {@inheritdoc}
192
     */
193 1
    public function getDebugProfile(): ?\Twig\Profiler\Profile
194
    {
195 1
        return $this->profile;
196
    }
197
}
198