Passed
Pull Request — master (#1676)
by Arnaud
09:10 queued 03:10
created

Twig::__construct()   C

Complexity

Conditions 16
Paths 96

Size

Total Lines 93
Code Lines 54

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 51
CRAP Score 16.4501

Importance

Changes 3
Bugs 1 Features 0
Metric Value
cc 16
eloc 54
c 3
b 1
f 0
nc 96
nop 2
dl 0
loc 93
ccs 51
cts 58
cp 0.8793
crap 16.4501
rs 5.5666

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 $value === null ?: date((string) $this->builder->getConfig()->get('date.format'), $value->getTimestamp());
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