Passed
Push — feat_i18n ( c4f2d5...2092c2 )
by Arnaud
03:41
created

Twig::__construct()   B

Complexity

Conditions 9
Paths 16

Size

Total Lines 74
Code Lines 44

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 35
CRAP Score 9.0397

Importance

Changes 6
Bugs 2 Features 1
Metric Value
cc 9
eloc 44
c 6
b 2
f 1
nc 16
nop 2
dl 0
loc 74
ccs 35
cts 38
cp 0.9211
crap 9.0397
rs 7.6604

How to fix   Long Method   

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\Twig\Extension as TwigExtension;
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\Loader\MoFileLoader;
23
use Symfony\Component\Translation\Translator;
24
use Twig\Extra\Intl\IntlExtension;
25
26
/**
27
 * Class Twig.
28
 */
29
class Twig implements RendererInterface
30
{
31
    /** @var \Twig\Profiler\Profile */
32
    public $profile;
33
34
    /** @var \Twig\Environment */
35
    private $twig;
36
37
    /** @var Translator */
38
    private $translator;
39
40
    /**
41
     * {@inheritdoc}
42
     */
43 1
    public function __construct(Builder $builder, $templatesPath)
44
    {
45
        // load layouts
46 1
        $loader = new \Twig\Loader\FilesystemLoader($templatesPath);
47
        // default options
48
        $loaderOptions = [
49 1
            'debug'            => $builder->isDebug(),
50
            'strict_variables' => true,
51
            'autoescape'       => false,
52
            'auto_reload'      => true,
53
            'cache'            => false,
54
        ];
55
        // use Twig cache?
56 1
        if ($builder->getConfig()->get('cache.templates.enabled')) {
57 1
            $templatesCachePath = \Cecil\Util::joinFile(
58 1
                $builder->getConfig()->getCachePath(),
59 1
                (string) $builder->getConfig()->get('cache.templates.dir')
60
            );
61 1
            $loaderOptions = array_replace($loaderOptions, ['cache' => $templatesCachePath]);
62
        }
63
        // create the Twig instance
64 1
        $this->twig = new \Twig\Environment($loader, $loaderOptions);
65
        // set date format
66 1
        $this->twig->getExtension(\Twig\Extension\CoreExtension::class)
67 1
            ->setDateFormat($builder->getConfig()->get('date.format'));
68
        // set timezone
69 1
        if ($builder->getConfig()->has('date.timezone')) {
70
            $this->twig->getExtension(\Twig\Extension\CoreExtension::class)
71
                ->setTimezone($builder->getConfig()->get('date.timezone'));
72
        }
73
        // adds extensions
74 1
        $this->twig->addExtension(new TwigExtension($builder));
75 1
        $this->twig->addExtension(new \Twig\Extension\StringLoaderExtension());
76
        // i18n
77 1
        $this->twig->addExtension(new IntlExtension());
78
        // filters fallback
79 1
        $this->twig->registerUndefinedFilterCallback(function ($name) use ($builder) {
80
            switch ($name) {
81 1
                case 'localizeddate':
82 1
                    return new \Twig\TwigFilter($name, function (\DateTime $value = null) use ($builder) {
83 1
                        return date((string) $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

83
                        return date((string) $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...
84
                    });
85
            }
86
87
            return false;
88
        });
89
        // l10n
90 1
        if (count($builder->getConfig()->getLanguages()) > 1) {
91 1
            $this->translator = new Translator(
92 1
                $builder->getConfig()->getLanguageProperty('locale'),
93 1
                new MessageFormatter(new IdentityTranslator()),
94 1
                Util::joinFile($builder->getConfig()->getCachePath(), 'translations'),
95 1
                $builder->isDebug()
96
            );
97 1
            $this->translator->addLoader('mo', new MoFileLoader());
98 1
            foreach ($builder->getConfig()->getLanguages() as $lang) {
99 1
                // themes
100 1
                if ($themes = $builder->getConfig()->getTheme()) {
101 1
                    foreach ($themes as $theme) {
102
                        $this->addTransResource($builder->getConfig()->getThemeDirPath($theme, 'translations'), $lang['locale']);
103
                    }
104 1
                }
105
                // site
106
                $this->addTransResource($builder->getConfig()->getTranslationsPath(), $lang['locale']);
107 1
            }
108
            $this->twig->addExtension(new TranslationExtension($this->translator));
109 1
        }
110
        // debug
111 1
        if ($builder->isDebug()) {
112 1
            // dump()
113
            $this->twig->addExtension(new \Twig\Extension\DebugExtension());
114
            // profiler
115
            $this->profile = new \Twig\Profiler\Profile();
116
            $this->twig->addExtension(new \Twig\Extension\ProfilerExtension($this->profile));
117
        }
118
    }
119 1
120
    /**
121 1
     * {@inheritdoc}
122 1
     */
123
    public function addGlobal(string $name, $value): void
124
    {
125
        $this->twig->addGlobal($name, $value);
126
    }
127
128 1
    /**
129
     * {@inheritdoc}
130 1
     */
131
    public function render(string $template, array $variables): string
132
    {
133
        return $this->twig->render($template, $variables);
134
    }
135
136 1
    /**
137
     * {@inheritdoc}
138 1
     */
139
    public function setLocale(string $locale): void
140
    {
141
        !class_exists(\Locale::class) ?: \Locale::setDefault($locale);
142
        !$this->translator instanceof Translator ?: $this->translator->setLocale($locale);
0 ignored issues
show
introduced by
$this->translator is always a sub-type of Symfony\Component\Translation\Translator.
Loading history...
143
    }
144
145
    /**
146
     * {@inheritdoc}
147
     */
148
    public function addTransResource(string $translationsDir, string $locale): void
149
    {
150
        $translationFile = realpath(Util::joinFile($translationsDir, \sprintf('messages.%s.mo', $locale)));
151
        if (Util\File::getFS()->exists($translationFile)) {
152
            $this->translator->addResource('mo', $translationFile, $locale);
153
        }
154
    }
155
}
156