Completed
Push — master ( e51e61...7776ec )
by Kamil
17s
created

Translator::getLocaleWithoutModifier()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 2
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);
117
118
        $computedFallbackLocales = parent::computeFallbackLocales($locale);
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