Completed
Pull Request — master (#4)
by Chauncey
19:59 queued 12:58
created

LocalesManager::__construct()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 10
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 10
rs 9.4285
c 0
b 0
f 0
cc 3
eloc 6
nc 4
nop 1
1
<?php
2
3
namespace Charcoal\Translator;
4
5
use InvalidArgumentException;
6
7
/**
8
 * Locales Manager
9
 *
10
 * The manager handles the collection of available languages, their definitions,
11
 * the default language, and tracks the current language.
12
 */
13
class LocalesManager
14
{
15
    /**
16
     * Dictionary of language definitions.
17
     *
18
     * @var array
19
     */
20
    private $locales;
21
22
    /**
23
     * List of language codes.
24
     *
25
     * @var string[]
26
     */
27
    private $languages;
28
29
    /**
30
     * Language code for the default locale.
31
     *
32
     * @var string
33
     */
34
    private $defaultLanguage;
35
36
    /**
37
     * Language code for the current locale.
38
     *
39
     * @var string|null
40
     */
41
    private $currentLanguage;
42
43
    /**
44
     * Create the Locales Manager with locales and optional options.
45
     *
46
     * Required parameters:
47
     * - **locales** (`array`)
48
     *
49
     * Optional parameters:
50
     * - **default_language** (`string`)
51
     *   - If none is set, the first language (from _locales_) will be used.
52
     * - **current_language** (`string`)
53
     *   - If none is set, then the default language will be used.
54
     *
55
     * @param  array $data Constructor dependencies.
56
     * @throws InvalidArgumentException If the default language is not a valid language.
57
     */
58
    public function __construct(array $data)
59
    {
60
        $this->setLocales($data['locales']);
61
62
        $default = isset($data['default_language']) ? $data['default_language'] : null;
63
        $this->setDefaultLocale($default);
64
65
        $current = isset($data['current_language']) ? $data['current_language'] : null;
66
        $this->setCurrentLocale($current);
67
    }
68
69
    /**
70
     * Retrieve the available locales information.
71
     *
72
     * @return array
73
     */
74
    public function locales()
75
    {
76
        return $this->locales;
77
    }
78
79
    /**
80
     * Retrieve the available locales (language codes).
81
     *
82
     * @return string[]
83
     */
84
    public function availableLocales()
85
    {
86
        return $this->languages;
87
    }
88
89
    /**
90
     * Set the default language.
91
     *
92
     * @param  string|null $lang The default language code.
93
     *    If NULL, the first language is assigned.
94
     * @throws InvalidArgumentException If the language is invalid.
95
     * @return void
96
     */
97 View Code Duplication
    private function setDefaultLocale($lang)
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...
98
    {
99
        if ($lang === null) {
100
            $this->defaultLanguage = $this->languages[0];
101
            return;
102
        }
103
104
        if (!$this->hasLocale($lang)) {
105
            if (!is_string($lang)) {
106
                $lang = is_object($lang) ? get_class($lang) : gettype($lang);
107
            }
108
109
            throw new InvalidArgumentException(sprintf(
110
                'Unsupported default language; must be one of "%s", received "%s"',
111
                implode(', ', $this->availableLocales()),
112
                $lang
113
            ));
114
        }
115
116
        $this->defaultLanguage = $lang;
117
    }
118
119
    /**
120
     * Retrieve the default language.
121
     *
122
     * @return string
123
     */
124
    public function defaultLocale()
125
    {
126
        return $this->defaultLanguage;
127
    }
128
129
    /**
130
     * Set the current language.
131
     *
132
     * @param  string|null $lang The current language code.
133
     *    If NULL, the current language is unset.
134
     * @throws InvalidArgumentException If the language is invalid.
135
     * @return void
136
     */
137 View Code Duplication
    public function setCurrentLocale($lang)
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...
138
    {
139
        if ($lang === null) {
140
            $this->currentLanguage = null;
141
            return;
142
        }
143
144
        if (!$this->hasLocale($lang)) {
145
            if (!is_string($lang)) {
146
                $lang = is_object($lang) ? get_class($lang) : gettype($lang);
147
            }
148
149
            throw new InvalidArgumentException(sprintf(
150
                'Unsupported language; must be one of "%s", received "%s"',
151
                implode(', ', $this->availableLocales()),
152
                $lang
153
            ));
154
        }
155
156
        $this->currentLanguage = $lang;
157
    }
158
159
    /**
160
     * Retrieve the current language.
161
     *
162
     * @return string
163
     */
164
    public function currentLocale()
165
    {
166
        if ($this->currentLanguage === null) {
167
            return $this->defaultLanguage;
168
        }
169
        return $this->currentLanguage;
170
    }
171
172
    /**
173
     * Determine if a locale is available.
174
     *
175
     * @param  string $lang The language code to check.
176
     * @return boolean
177
     */
178
    public function hasLocale($lang)
179
    {
180
        return isset($this->locales[$lang]);
181
    }
182
183
    /**
184
     * Set the available languages.
185
     *
186
     * Ensure that explicitely inactive locales are excluded and that the required
187
     * values are set on the locales configuration structure.
188
     *
189
     * This method is only called from the constructor.
190
     *
191
     * @param  array $locales The locales configuration structure.
192
     * @throws InvalidArgumentException If there are no active locales.
193
     * @return void
194
     */
195
    private function setLocales(array $locales)
196
    {
197
        $this->locales = [];
198
        $this->languages = [];
199
        foreach ($locales as $langCode => $locale) {
200
            if (isset($locale['active']) && !$locale['active']) {
201
                continue;
202
            }
203
            if (!isset($locale['locale'])) {
204
                $locale['locale'] = $langCode;
205
            }
206
            $this->locales[$langCode] = $locale;
207
            $this->languages[] = $langCode;
208
        }
209
        if (empty($this->locales)) {
210
            throw new InvalidArgumentException(
211
                'Locales can not be empty.'
212
            );
213
        }
214
    }
215
}
216