Completed
Push — master ( efaf6c...67e396 )
by
unknown
02:40
created

Translator::isValidTranslation()   D

Complexity

Conditions 10
Paths 5

Size

Total Lines 31
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 31
rs 4.8196
c 0
b 0
f 0
cc 10
eloc 17
nc 5
nop 1

How to fix   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
namespace Charcoal\Translator;
4
5
// From 'symfony/translation'
6
use Symfony\Component\Translation\Translator as SymfonyTranslator;
7
8
// From 'charcoal-translator'
9
use Charcoal\Translator\LocalesManager;
10
use Charcoal\Translator\Translation;
11
12
/**
13
 * Charcoal Translator.
14
 *
15
 * Extends the Symfony translator to allow returned values in a "Translation" oject,
16
 * containing localizations for all locales.
17
 */
18
class Translator extends SymfonyTranslator
19
{
20
    /**
21
     * The locales manager.
22
     *
23
     * @var LocalesManager
24
     */
25
    private $manager;
26
27
    /**
28
     * The loaded domains.
29
     *
30
     * @var string[]
31
     */
32
    private $domains = [ 'messages' ];
33
34
    /**
35
     * @param array $data Constructor data.
36
     */
37
    public function __construct(array $data)
38
    {
39
        $this->setManager($data['manager']);
40
41
        $defaults = [
42
            'locale'            => $this->manager->currentLocale(),
43
            'message_selector'  => null,
44
            'cache_dir'         => null,
45
            'debug'             => false
46
        ];
47
        $data = array_merge($defaults, $data);
48
49
        // If symfony-config is not installed, DON'T use cache.
50
        if (!class_exists('\Symfony\Component\Config\ConfigCacheFactory')) {
51
            $data['cache_dir'] = null;
52
        }
53
54
        parent::__construct(
55
            $data['locale'],
56
            $data['message_selector'],
57
            $data['cache_dir'],
58
            $data['debug']
59
        );
60
    }
61
62
    /**
63
     * Adds a resource.
64
     *
65
     * @see    SymfonyTranslator::addResource() Keep track of the translation domains.
66
     * @param  string      $format   The name of the loader (@see addLoader()).
67
     * @param  mixed       $resource The resource name.
68
     * @param  string      $locale   The locale.
69
     * @param  string|null $domain   The domain.
70
     * @return void
71
     */
72
    public function addResource($format, $resource, $locale, $domain = null)
73
    {
74
        if (null !== $domain) {
75
            $this->domains[] = $domain;
76
        }
77
78
        parent::addResource($format, $resource, $locale, $domain);
79
    }
80
81
    /**
82
     * Retrieve the loaded domains.
83
     *
84
     * @return string[]
85
     */
86
    public function availableDomains()
87
    {
88
        return $this->domains;
89
    }
90
91
    /**
92
     * Retrieve a translation object from a (mixed) message.
93
     *
94
     * @uses   SymfonyTranslator::trans()
95
     * @param  mixed       $val        The string or translation-object to retrieve.
96
     * @param  array       $parameters An array of parameters for the message.
97
     * @param  string|null $domain     The domain for the message or NULL to use the default.
98
     * @return Translation|null The translation object or NULL if the value is not translatable.
99
     */
100 View Code Duplication
    public function translation($val, array $parameters = [], $domain = null)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
101
    {
102
        if ($this->isValidTranslation($val) === false) {
103
            return null;
104
        }
105
106
        $translation = new Translation($val, $this->manager);
107
        foreach ($this->availableLocales() as $lang) {
108
            if (!isset($translation[$lang]) || $translation[$lang] == $val) {
109
                $translation[$lang] = $this->trans((string)$translation, $parameters, $domain, $lang);
110
            }
111
        }
112
113
        return $translation;
114
    }
115
116
    /**
117
     * Translates the given (mixed) message.
118
     *
119
     * @uses   SymfonyTranslator::trans()
120
     * @uses   Translator::translation()
121
     * @param  mixed       $val        The string or translation-object to retrieve.
122
     * @param  array       $parameters An array of parameters for the message.
123
     * @param  string|null $domain     The domain for the message or NULL to use the default.
124
     * @param  string|null $locale     The locale or NULL to use the default.
125
     * @return string The translated string
126
     */
127 View Code Duplication
    public function translate($val, array $parameters = [], $domain = null, $locale = null)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
128
    {
129
        if ($val instanceof Translation) {
130
            return strtr($val[$locale], $parameters);
131
        }
132
133
        if (is_object($val) && method_exists($val, '__toString')) {
134
            $val = (string)$val;
135
        }
136
137
        if (is_string($val)) {
138
            return $this->trans($val, $parameters, $domain, $locale);
139
        } else {
140
            $translation = $this->translation($val, $parameters, $domain);
141
            return $translation[$locale];
142
        }
143
    }
144
145
    /**
146
     * Retrieve a translation object from a (mixed) message by choosing a translation according to a number.
147
     *
148
     * @uses   SymfonyTranslator::transChoice()
149
     * @param  mixed       $val        The string or translation-object to retrieve.
150
     * @param  integer     $number     The number to use to find the indice of the message.
151
     * @param  array       $parameters An array of parameters for the message.
152
     * @param  string|null $domain     The domain for the message or NULL to use the default.
153
     * @return Translation|null The translation object or NULL if the value is not translatable.
154
     */
155 View Code Duplication
    public function translationChoice($val, $number, array $parameters = [], $domain = null)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
156
    {
157
        if ($this->isValidTranslation($val) === false) {
158
            return null;
159
        }
160
161
        $translation = new Translation($val, $this->manager);
162
        foreach ($this->availableLocales() as $lang) {
163
            if (!isset($translation[$lang]) || $translation[$lang] == $val) {
164
                $translation[$lang] = $this->transChoice((string)$translation, $number, $parameters, $domain, $lang);
165
            }
166
        }
167
168
        return $translation;
169
    }
170
171
    /**
172
     * Translates the given (mixed) choice message by choosing a translation according to a number.
173
     *
174
     * @uses   SymfonyTranslator::transChoice()
175
     * @uses   Translator::translationChoice()
176
     * @param  mixed       $val        The string or translation-object to retrieve.
177
     * @param  integer     $number     The number to use to find the indice of the message.
178
     * @param  array       $parameters An array of parameters for the message.
179
     * @param  string|null $domain     The domain for the message or NULL to use the default.
180
     * @param  string|null $locale     The locale or NULL to use the default.
181
     * @return string The translated string
182
     */
183 View Code Duplication
    public function translateChoice($val, $number, array $parameters = [], $domain = null, $locale = null)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
184
    {
185
        if ($val instanceof Translation) {
186
            return strtr($val[$locale], $parameters);
187
        }
188
189
        if (is_object($val) && method_exists($val, '__toString')) {
190
            $val = (string)$val;
191
        }
192
193
        if (is_string($val)) {
194
            return $this->transChoice($val, $number, $parameters, $domain, $locale);
195
        } else {
196
            $translation = $this->translationChoice($val, $number, $parameters, $domain);
197
            return $translation[$locale];
198
        }
199
    }
200
201
    /**
202
     * Retrieve the available locales information.
203
     *
204
     * @return array
205
     */
206
    public function locales()
207
    {
208
        return $this->manager->locales();
209
    }
210
211
    /**
212
     * Retrieve the available locales (language codes).
213
     *
214
     * @return string[]
215
     */
216
    public function availableLocales()
217
    {
218
        return $this->manager->availableLocales();
219
    }
220
221
    /**
222
     * Sets the current locale.
223
     *
224
     * @see    SymfonyTranslator::setLocale() Ensure that the method also changes the locales manager's language.
225
     * @param  string $locale The locale.
226
     * @return void
227
     */
228
    public function setLocale($locale)
229
    {
230
        parent::setLocale($locale);
231
232
        $this->manager->setCurrentLocale($locale);
233
    }
234
235
    /**
236
     * Set the locales manager.
237
     *
238
     * @param  LocalesManager $manager The locales manager.
239
     * @return void
240
     */
241
    private function setManager(LocalesManager $manager)
242
    {
243
        $this->manager = $manager;
244
    }
245
246
    /**
247
     * Determine if the value is translatable.
248
     *
249
     * @param  mixed $val The value to be checked.
250
     * @return boolean
251
     */
252
    private function isValidTranslation($val)
253
    {
254
        if (empty($val) && !is_numeric($val)) {
255
            return false;
256
        }
257
258
        if (is_string($val)) {
259
            return !empty(trim($val));
260
        }
261
262
        if ($val instanceof Translation) {
263
            return true;
264
        }
265
266
        if (is_array($val)) {
267
            return !!array_filter(
268
                $val,
269
                function ($v, $k) {
270
                    if (is_string($k) && strlen($k) > 0) {
271
                        if (is_string($v) && strlen($v) > 0) {
272
                            return true;
273
                        }
274
                    }
275
276
                    return false;
277
                },
278
                ARRAY_FILTER_USE_BOTH
279
            );
280
        }
281
        return false;
282
    }
283
}
284