Completed
Push — translatable-trait ( 71d736 )
by Kamil
40:10
created

Translator::getLocaleModifier()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 6
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 3
nc 2
nop 1
1
<?php
2
3
/*
4
 * This file is part of the Sylius package.
5
 *
6
 * (c) Paweł Jędrzejewski
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Sylius\Bundle\ThemeBundle\Translation;
13
14
use Sylius\Bundle\ThemeBundle\Translation\Provider\Loader\TranslatorLoaderProviderInterface;
15
use Sylius\Bundle\ThemeBundle\Translation\Provider\Resource\TranslatorResourceProviderInterface;
16
use Symfony\Component\HttpKernel\CacheWarmer\WarmableInterface;
17
use Symfony\Component\Translation\MessageSelector;
18
use Symfony\Component\Translation\Translator as BaseTranslator;
19
20
/**
21
 * @author Kamil Kokot <[email protected]>
22
 */
23
final class Translator extends BaseTranslator implements WarmableInterface
24
{
25
    /**
26
     * @var array
27
     */
28
    protected $options = [
29
        'cache_dir' => null,
30
        'debug' => false,
31
    ];
32
33
    /**
34
     * @var TranslatorLoaderProviderInterface
35
     */
36
    private $loaderProvider;
37
38
    /**
39
     * @var TranslatorResourceProviderInterface
40
     */
41
    private $resourceProvider;
42
43
    /**
44
     * @var bool
45
     */
46
    private $resourcesLoaded = false;
47
48
    /**
49
     * @param TranslatorLoaderProviderInterface $loaderProvider
50
     * @param TranslatorResourceProviderInterface $resourceProvider
51
     * @param MessageSelector $messageSelector
52
     * @param string $locale
53
     * @param array $options
54
     */
55
    public function __construct(
56
        TranslatorLoaderProviderInterface $loaderProvider,
57
        TranslatorResourceProviderInterface $resourceProvider,
58
        MessageSelector $messageSelector,
59
        $locale,
60
        array $options = []
61
    ) {
62
        $this->assertOptionsAreKnown($options);
63
64
        $this->loaderProvider = $loaderProvider;
65
        $this->resourceProvider = $resourceProvider;
66
67
        $this->options = array_merge($this->options, $options);
68
        if (null !== $this->options['cache_dir'] && $this->options['debug']) {
69
            $this->addResources();
70
        }
71
72
        parent::__construct($locale, $messageSelector, $this->options['cache_dir'], $this->options['debug']);
73
    }
74
75
    /**
76
     * {@inheritdoc}
77
     */
78
    public function warmUp($cacheDir)
79
    {
80
        // skip warmUp when translator doesn't use cache
81
        if (null === $this->options['cache_dir']) {
82
            return;
83
        }
84
85
        $locales = array_merge(
86
            $this->getFallbackLocales(),
87
            [$this->getLocale()],
88
            $this->resourceProvider->getResourcesLocales()
89
        );
90
        foreach (array_unique($locales) as $locale) {
91
            // reset catalogue in case it's already loaded during the dump of the other locales.
92
            if (isset($this->catalogues[$locale])) {
93
                unset($this->catalogues[$locale]);
94
            }
95
96
            $this->loadCatalogue($locale);
97
        }
98
    }
99
100
    /**
101
     * {@inheritdoc}
102
     */
103
    protected function initializeCatalogue($locale)
104
    {
105
        $this->initialize();
106
107
        parent::initializeCatalogue($locale);
108
    }
109
110
    /**
111
     * {@inheritdoc}
112
     */
113
    protected function computeFallbackLocales($locale)
114
    {
115
        $themeModifier = $this->getLocaleModifier($locale);
116
        $localeWithoutModifier = $this->getLocaleWithoutModifier($locale, $themeModifier);
0 ignored issues
show
Comprehensibility Naming introduced by
The variable name $localeWithoutModifier exceeds the maximum configured length of 20.

Very long variable names usually make code harder to read. It is therefore recommended not to make variable names too verbose.

Loading history...
117
118
        $computedFallbackLocales = parent::computeFallbackLocales($locale);
0 ignored issues
show
Comprehensibility Naming introduced by
The variable name $computedFallbackLocales exceeds the maximum configured length of 20.

Very long variable names usually make code harder to read. It is therefore recommended not to make variable names too verbose.

Loading history...
119
        array_unshift($computedFallbackLocales, $localeWithoutModifier);
120
121
        $fallbackLocales = [];
122
        foreach(array_diff($computedFallbackLocales, [$locale]) as $computedFallback) {
123
            $fallback = $computedFallback . $themeModifier;
124
            if (null !== $themeModifier && $locale !== $fallback) {
125
                $fallbackLocales[] = $fallback;
126
            }
127
128
            $fallbackLocales[] = $computedFallback;
129
        }
130
131
        return array_unique($fallbackLocales);
132
    }
133
134
    /**
135
     * @param string $locale
136
     *
137
     * @return string
138
     */
139
    private function getLocaleModifier($locale)
140
    {
141
        $modifier = strrchr($locale, '@');
142
143
        return $modifier ?: '';
144
    }
145
146
    /**
147
     * @param string $locale
148
     * @param string $modifier
149
     *
150
     * @return string
151
     */
152
    private function getLocaleWithoutModifier($locale, $modifier)
153
    {
154
        return str_replace($modifier, '', $locale);
155
    }
156
157
    private function initialize()
158
    {
159
        $this->addResources();
160
        $this->addLoaders();
161
    }
162
163
    private function addResources()
164
    {
165
        if ($this->resourcesLoaded) {
166
            return;
167
        }
168
169
        $resources = $this->resourceProvider->getResources();
170
        foreach ($resources as $resource) {
171
            $this->addResource(
172
                $resource->getFormat(),
173
                $resource->getName(),
174
                $resource->getLocale(),
175
                $resource->getDomain()
176
            );
177
        }
178
179
        $this->resourcesLoaded = true;
180
    }
181
182
    private function addLoaders()
183
    {
184
        $loaders = $this->loaderProvider->getLoaders();
185
        foreach ($loaders as $alias => $loader) {
186
            $this->addLoader($alias, $loader);
187
        }
188
    }
189
190
    /**
191
     * @param array $options
192
     */
193
    private function assertOptionsAreKnown(array $options)
194
    {
195
        if ($diff = array_diff(array_keys($options), array_keys($this->options))) {
196
            throw new \InvalidArgumentException(sprintf('The Translator does not support the following options: \'%s\'.', implode('\', \'', $diff)));
197
        }
198
    }
199
}
200