Completed
Branch master (e25020)
by Richan
03:06
created

I18nService::getLocale()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 15
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 15
c 0
b 0
f 0
rs 9.2
cc 4
eloc 8
nc 4
nop 1
1
<?php
2
3
namespace RichanFongdasen\I18n;
4
5
use Illuminate\Http\Request;
6
use RichanFongdasen\I18n\Exceptions\InvalidFallbackLanguageException;
7
use RichanFongdasen\I18n\Exceptions\InvalidLocaleException;
8
9
class I18nService
10
{
11
    /**
12
     * I18n configuration.
13
     *
14
     * @var array
15
     */
16
    protected $config;
17
18
    /**
19
     * Default locale key.
20
     *
21
     * @var string
22
     */
23
    protected $defaultKey;
24
25
    /**
26
     * Locale collection object.
27
     *
28
     * @var \Illuminate\Support\Collection
29
     */
30
    protected $locale;
31
32
    /**
33
     * All of possible locale keys.
34
     *
35
     * @var array
36
     */
37
    protected $possibleKeys = ['ietfCode', 'language'];
38
39
    /**
40
     * HTTP Request Object.
41
     *
42
     * @var \Illuminate\Http\Request
43
     */
44
    protected $request;
45
46
    /**
47
     * URL Generator object.
48
     *
49
     * @var \RichanFongdasen\I18n\UrlGenerator
50
     */
51
    protected $urlGenerator;
52
53
    /**
54
     * Class constructor.
55
     *
56
     * @param \Illuminate\Http\Request $request
57
     */
58
    public function __construct(Request $request)
0 ignored issues
show
Bug introduced by
You have injected the Request via parameter $request. This is generally not recommended as there might be multiple instances during a request cycle (f.e. when using sub-requests). Instead, it is recommended to inject the RequestStack and retrieve the current request each time you need it via getCurrentRequest().
Loading history...
59
    {
60
        $this->request = $request;
61
        $this->loadConfig();
62
63
        $this->defaultKey = $this->getConfig('language_key');
64
65
        $this->locale = $this->loadLocale();
66
67
        $this->urlGenerator = new UrlGenerator($this->defaultKey);
68
    }
69
70
    /**
71
     * Get default locale.
72
     *
73
     * @return \RichanFongdasen\I18n\Locale
74
     */
75
    public function defaultLocale()
76
    {
77
        $fallback = $this->getConfig('fallback_language');
78
        $locale = $this->getLocale($fallback);
79
80
        if (!$locale instanceof Locale) {
81
            throw new InvalidFallbackLanguageException('Can\'t find the fallback locale object');
82
        }
83
84
        return $locale;
85
    }
86
87
    /**
88
     * Format the IETF locale string.
89
     *
90
     * @param string $string
91
     *
92
     * @return string
93
     */
94
    protected function formatIetf($string)
95
    {
96
        return preg_replace('/\_/', '-', $string);
97
    }
98
99
    /**
100
     * Get configuration value for a specific key.
101
     *
102
     * @param string $key
103
     * @param mixed  $default
104
     *
105
     * @return mixed
106
     */
107
    public function getConfig($key, $default = null)
108
    {
109
        return data_get($this->config, $key, $default);
110
    }
111
112
    /**
113
     * Get any locale matched to the given keyword.
114
     * It will return all available locales when
115
     * there is no keyword.
116
     *
117
     * @param string|null $keyword
118
     *
119
     * @return mixed
120
     */
121
    public function getLocale($keyword = null)
122
    {
123
        if ($keyword === null) {
124
            return $this->locale;
125
        }
126
        $keyword = $this->formatIetf($keyword);
127
128
        foreach ($this->possibleKeys as $key) {
129
            if ($locale = $this->locale->keyBy($key)->get($keyword)) {
130
                return $locale;
131
            }
132
        }
133
134
        return null;
135
    }
136
137
    /**
138
     * Get all of available locale keys.
139
     *
140
     * @param string|null $key
141
     *
142
     * @return null|array
143
     */
144
    public function getLocaleKeys($key = null)
145
    {
146
        if (empty($key)) {
147
            $key = $this->defaultKey;
148
        }
149
        $keys = $this->locale->keyBy($key)->keys()->all();
150
151
        if ((count($keys) == 1) && empty($keys[0])) {
152
            return null;
153
        }
154
155
        return $keys;
156
    }
157
158
    protected function loadConfig()
159
    {
160
        $this->config = \Config::get('i18n');
161
    }
162
163
    /**
164
     * Load locale from repository.
165
     *
166
     * @return \Illuminate\Support\Collection
167
     */
168
    protected function loadLocale()
169
    {
170
        $cacheKey = 'laravel-i18n-locale-'.$this->getConfig('driver');
171
        $cacheDuration = $this->getConfig('cache_duration', 1440);
172
173
        return \Cache::remember($cacheKey, $cacheDuration, function () {
174
            return app(RepositoryManager::class)->collect();
175
        });
176
    }
177
178
    /**
179
     * Get the current routed locale.
180
     *
181
     * @param null|\Illuminate\Http\Request $request
182
     *
183
     * @return \RichanFongdasen\I18n\Locale|null
184
     */
185
    public function routedLocale(Request $request = null)
186
    {
187
        if (!$request) {
188
            $request = $this->request;
189
        }
190
        $language = $request->segment(1);
191
192
        if ($locale = $this->getLocale($language)) {
193
            \App::setLocale($locale->{$this->defaultKey});
194
        }
195
196
        return $locale;
197
    }
198
199
    /**
200
     * Get the route prefix.
201
     *
202
     * @return string
203
     */
204
    public function routePrefix()
205
    {
206
        $locale = $this->routedLocale() ? $this->routedLocale() : $this->defaultLocale();
207
208
        return $locale->{$this->defaultKey};
209
    }
210
211
    /**
212
     * Generate a localized URL for the application.
213
     *
214
     * @param string $url
215
     * @param mixed  $locale
216
     *
217
     * @return string
218
     */
219
    public function url($url, $locale = null)
220
    {
221
        if (is_string($locale) && !($locale = $this->getLocale($locale))) {
222
            throw new InvalidLocaleException('Failed to generate URL with the given locale');
223
        }
224
        if (($locale === null) && !($locale = $this->routedLocale())) {
225
            $locale = $this->defaultLocale();
226
        }
227
228
        return $this->urlGenerator->setUrl($url)->localize($locale);
229
    }
230
}
231