1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace Illuminate\Translation; |
4
|
|
|
|
5
|
|
|
use Illuminate\Support\Str; |
6
|
|
|
|
7
|
|
|
class MessageSelector |
8
|
|
|
{ |
9
|
|
|
/** |
10
|
|
|
* Select a proper translation string based on the given number. |
11
|
|
|
* |
12
|
|
|
* @param string $line |
13
|
|
|
* @param int $number |
14
|
|
|
* @param string $locale |
15
|
|
|
* @return mixed |
16
|
|
|
*/ |
17
|
|
|
public function choose($line, $number, $locale) |
18
|
|
|
{ |
19
|
|
|
$segments = explode('|', $line); |
20
|
|
|
|
21
|
|
|
if (($value = $this->extract($segments, $number)) !== null) { |
22
|
|
|
return trim($value); |
23
|
|
|
} |
24
|
|
|
|
25
|
|
|
$segments = $this->stripConditions($segments); |
26
|
|
|
|
27
|
|
|
$pluralIndex = $this->getPluralIndex($locale, $number); |
28
|
|
|
|
29
|
|
|
if (count($segments) == 1 || ! isset($segments[$pluralIndex])) { |
30
|
|
|
return $segments[0]; |
31
|
|
|
} |
32
|
|
|
|
33
|
|
|
return $segments[$pluralIndex]; |
34
|
|
|
} |
35
|
|
|
|
36
|
|
|
/** |
37
|
|
|
* Extract a translation string using inline conditions. |
38
|
|
|
* |
39
|
|
|
* @param array $segments |
40
|
|
|
* @param int $number |
41
|
|
|
* @return mixed |
|
|
|
|
42
|
|
|
*/ |
43
|
|
|
private function extract($segments, $number) |
44
|
|
|
{ |
45
|
|
|
foreach ($segments as $part) { |
46
|
|
|
if (! is_null($line = $this->extractFromString($part, $number))) { |
47
|
|
|
return $line; |
48
|
|
|
} |
49
|
|
|
} |
50
|
|
|
} |
51
|
|
|
|
52
|
|
|
/** |
53
|
|
|
* Get the translation string if the condition matches. |
54
|
|
|
* |
55
|
|
|
* @param string $part |
56
|
|
|
* @param int $number |
57
|
|
|
* @return mixed |
|
|
|
|
58
|
|
|
*/ |
59
|
|
|
private function extractFromString($part, $number) |
60
|
|
|
{ |
61
|
|
|
preg_match('/^[\{\[]([^\[\]\{\}]*)[\}\]](.*)/s', $part, $matches); |
62
|
|
|
|
63
|
|
|
if (count($matches) !== 3) { |
64
|
|
|
return; |
65
|
|
|
} |
66
|
|
|
|
67
|
|
|
$condition = $matches[1]; |
68
|
|
|
|
69
|
|
|
$value = $matches[2]; |
70
|
|
|
|
71
|
|
|
if (Str::contains($condition, ',')) { |
72
|
|
|
list($from, $to) = explode(',', $condition, 2); |
73
|
|
|
|
74
|
|
|
if ($to == '*' && $number >= $from) { |
75
|
|
|
return $value; |
76
|
|
|
} elseif ($from == '*' && $number <= $to) { |
77
|
|
|
return $value; |
78
|
|
|
} elseif ($number >= $from && $number <= $to) { |
79
|
|
|
return $value; |
80
|
|
|
} |
81
|
|
|
} |
82
|
|
|
|
83
|
|
|
return $condition == $number ? $value : null; |
84
|
|
|
} |
85
|
|
|
|
86
|
|
|
/** |
87
|
|
|
* Strip the inline conditions from each segment, just leaving the text. |
88
|
|
|
* |
89
|
|
|
* @param array $segments |
90
|
|
|
* @return array |
91
|
|
|
*/ |
92
|
|
|
private function stripConditions($segments) |
93
|
|
|
{ |
94
|
|
|
return collect($segments)->map(function ($part) { |
95
|
|
|
return preg_replace('/^[\{\[]([^\[\]\{\}]*)[\}\]]/', '', $part); |
96
|
|
|
})->all(); |
97
|
|
|
} |
98
|
|
|
|
99
|
|
|
/** |
100
|
|
|
* Get the index to use for pluralization. |
101
|
|
|
* |
102
|
|
|
* The plural rules are derived from code of the Zend Framework (2010-09-25), which |
103
|
|
|
* is subject to the new BSD license (http://framework.zend.com/license/new-bsd) |
104
|
|
|
* Copyright (c) 2005-2010 - Zend Technologies USA Inc. (http://www.zend.com) |
105
|
|
|
* |
106
|
|
|
* @param string $locale |
107
|
|
|
* @param int $number |
108
|
|
|
* @return int |
109
|
|
|
*/ |
110
|
|
|
public function getPluralIndex($locale, $number) |
111
|
|
|
{ |
112
|
|
|
switch ($locale) { |
113
|
|
|
case 'az': |
114
|
|
|
case 'az_AZ': |
115
|
|
|
case 'bo': |
116
|
|
|
case 'bo_CN': |
117
|
|
|
case 'bo_IN': |
118
|
|
|
case 'dz': |
119
|
|
|
case 'dz_BT': |
120
|
|
|
case 'id': |
121
|
|
|
case 'id_ID': |
122
|
|
|
case 'ja': |
123
|
|
|
case 'ja_JP': |
124
|
|
|
case 'jv': |
125
|
|
|
case 'ka': |
126
|
|
|
case 'ka_GE': |
127
|
|
|
case 'km': |
128
|
|
|
case 'km_KH': |
129
|
|
|
case 'kn': |
130
|
|
|
case 'kn_IN': |
131
|
|
|
case 'ko': |
132
|
|
|
case 'ko_KR': |
133
|
|
|
case 'ms': |
134
|
|
|
case 'ms_MY': |
135
|
|
|
case 'th': |
136
|
|
|
case 'th_TH': |
137
|
|
|
case 'tr': |
138
|
|
|
case 'tr_CY': |
139
|
|
|
case 'tr_TR': |
140
|
|
|
case 'vi': |
141
|
|
|
case 'vi_VN': |
142
|
|
|
case 'zh': |
143
|
|
|
case 'zh_CN': |
144
|
|
|
case 'zh_HK': |
145
|
|
|
case 'zh_SG': |
146
|
|
|
case 'zh_TW': |
147
|
|
|
return 0; |
148
|
|
|
case 'af': |
149
|
|
|
case 'af_ZA': |
150
|
|
|
case 'bn': |
151
|
|
|
case 'bn_BD': |
152
|
|
|
case 'bn_IN': |
153
|
|
|
case 'bg': |
154
|
|
|
case 'bg_BG': |
155
|
|
|
case 'ca': |
156
|
|
|
case 'ca_AD': |
157
|
|
|
case 'ca_ES': |
158
|
|
|
case 'ca_FR': |
159
|
|
|
case 'ca_IT': |
160
|
|
|
case 'da': |
161
|
|
|
case 'da_DK': |
162
|
|
|
case 'de': |
163
|
|
|
case 'de_AT': |
164
|
|
|
case 'de_BE': |
165
|
|
|
case 'de_CH': |
166
|
|
|
case 'de_DE': |
167
|
|
|
case 'de_LI': |
168
|
|
|
case 'de_LU': |
169
|
|
|
case 'el': |
170
|
|
|
case 'el_CY': |
171
|
|
|
case 'el_GR': |
172
|
|
|
case 'en': |
173
|
|
|
case 'en_AG': |
174
|
|
|
case 'en_AU': |
175
|
|
|
case 'en_BW': |
176
|
|
|
case 'en_CA': |
177
|
|
|
case 'en_DK': |
178
|
|
|
case 'en_GB': |
179
|
|
|
case 'en_HK': |
180
|
|
|
case 'en_IE': |
181
|
|
|
case 'en_IN': |
182
|
|
|
case 'en_NG': |
183
|
|
|
case 'en_NZ': |
184
|
|
|
case 'en_PH': |
185
|
|
|
case 'en_SG': |
186
|
|
|
case 'en_US': |
187
|
|
|
case 'en_ZA': |
188
|
|
|
case 'en_ZM': |
189
|
|
|
case 'en_ZW': |
190
|
|
|
case 'eo': |
191
|
|
|
case 'eo_US': |
192
|
|
|
case 'es': |
193
|
|
|
case 'es_AR': |
194
|
|
|
case 'es_BO': |
195
|
|
|
case 'es_CL': |
196
|
|
|
case 'es_CO': |
197
|
|
|
case 'es_CR': |
198
|
|
|
case 'es_CU': |
199
|
|
|
case 'es_DO': |
200
|
|
|
case 'es_EC': |
201
|
|
|
case 'es_ES': |
202
|
|
|
case 'es_GT': |
203
|
|
|
case 'es_HN': |
204
|
|
|
case 'es_MX': |
205
|
|
|
case 'es_NI': |
206
|
|
|
case 'es_PA': |
207
|
|
|
case 'es_PE': |
208
|
|
|
case 'es_PR': |
209
|
|
|
case 'es_PY': |
210
|
|
|
case 'es_SV': |
211
|
|
|
case 'es_US': |
212
|
|
|
case 'es_UY': |
213
|
|
|
case 'es_VE': |
214
|
|
|
case 'et': |
215
|
|
|
case 'et_EE': |
216
|
|
|
case 'eu': |
217
|
|
|
case 'eu_ES': |
218
|
|
|
case 'eu_FR': |
219
|
|
|
case 'fa': |
220
|
|
|
case 'fa_IR': |
221
|
|
|
case 'fi': |
222
|
|
|
case 'fi_FI': |
223
|
|
|
case 'fo': |
224
|
|
|
case 'fo_FO': |
225
|
|
|
case 'fur': |
226
|
|
|
case 'fur_IT': |
227
|
|
|
case 'fy': |
228
|
|
|
case 'fy_DE': |
229
|
|
|
case 'fy_NL': |
230
|
|
|
case 'gl': |
231
|
|
|
case 'gl_ES': |
232
|
|
|
case 'gu': |
233
|
|
|
case 'gu_IN': |
234
|
|
|
case 'ha': |
235
|
|
|
case 'ha_NG': |
236
|
|
|
case 'he': |
237
|
|
|
case 'he_IL': |
238
|
|
|
case 'hu': |
239
|
|
|
case 'hu_HU': |
240
|
|
|
case 'is': |
241
|
|
|
case 'is_IS': |
242
|
|
|
case 'it': |
243
|
|
|
case 'it_CH': |
244
|
|
|
case 'it_IT': |
245
|
|
|
case 'ku': |
246
|
|
|
case 'ku_TR': |
247
|
|
|
case 'lb': |
248
|
|
|
case 'lb_LU': |
249
|
|
|
case 'ml': |
250
|
|
|
case 'ml_IN': |
251
|
|
|
case 'mn': |
252
|
|
|
case 'mn_MN': |
253
|
|
|
case 'mr': |
254
|
|
|
case 'mr_IN': |
255
|
|
|
case 'nah': |
256
|
|
|
case 'nb': |
257
|
|
|
case 'nb_NO': |
258
|
|
|
case 'ne': |
259
|
|
|
case 'ne_NP': |
260
|
|
|
case 'nl': |
261
|
|
|
case 'nl_AW': |
262
|
|
|
case 'nl_BE': |
263
|
|
|
case 'nl_NL': |
264
|
|
|
case 'nn': |
265
|
|
|
case 'nn_NO': |
266
|
|
|
case 'no': |
267
|
|
|
case 'om': |
268
|
|
|
case 'om_ET': |
269
|
|
|
case 'om_KE': |
270
|
|
|
case 'or': |
271
|
|
|
case 'or_IN': |
272
|
|
|
case 'pa': |
273
|
|
|
case 'pa_IN': |
274
|
|
|
case 'pa_PK': |
275
|
|
|
case 'pap': |
276
|
|
|
case 'pap_AN': |
277
|
|
|
case 'pap_AW': |
278
|
|
|
case 'pap_CW': |
279
|
|
|
case 'ps': |
280
|
|
|
case 'ps_AF': |
281
|
|
|
case 'pt': |
282
|
|
|
case 'pt_BR': |
283
|
|
|
case 'pt_PT': |
284
|
|
|
case 'so': |
285
|
|
|
case 'so_DJ': |
286
|
|
|
case 'so_ET': |
287
|
|
|
case 'so_KE': |
288
|
|
|
case 'so_SO': |
289
|
|
|
case 'sq': |
290
|
|
|
case 'sq_AL': |
291
|
|
|
case 'sq_MK': |
292
|
|
|
case 'sv': |
293
|
|
|
case 'sv_FI': |
294
|
|
|
case 'sv_SE': |
295
|
|
|
case 'sw': |
296
|
|
|
case 'sw_KE': |
297
|
|
|
case 'sw_TZ': |
298
|
|
|
case 'ta': |
299
|
|
|
case 'ta_IN': |
300
|
|
|
case 'ta_LK': |
301
|
|
|
case 'te': |
302
|
|
|
case 'te_IN': |
303
|
|
|
case 'tk': |
304
|
|
|
case 'tk_TM': |
305
|
|
|
case 'ur': |
306
|
|
|
case 'ur_IN': |
307
|
|
|
case 'ur_PK': |
308
|
|
|
case 'zu': |
309
|
|
|
case 'zu_ZA': |
310
|
|
|
return ($number == 1) ? 0 : 1; |
311
|
|
|
case 'am': |
312
|
|
|
case 'am_ET': |
313
|
|
|
case 'bh': |
314
|
|
|
case 'fil': |
315
|
|
|
case 'fil_PH': |
316
|
|
|
case 'fr': |
317
|
|
|
case 'fr_BE': |
318
|
|
|
case 'fr_CA': |
319
|
|
|
case 'fr_CH': |
320
|
|
|
case 'fr_FR': |
321
|
|
|
case 'fr_LU': |
322
|
|
|
case 'gun': |
323
|
|
|
case 'hi': |
324
|
|
|
case 'hi_IN': |
325
|
|
|
case 'hy': |
326
|
|
|
case 'hy_AM': |
327
|
|
|
case 'ln': |
328
|
|
|
case 'ln_CD': |
329
|
|
|
case 'mg': |
330
|
|
|
case 'mg_MG': |
331
|
|
|
case 'nso': |
332
|
|
|
case 'nso_ZA': |
333
|
|
|
case 'ti': |
334
|
|
|
case 'ti_ER': |
335
|
|
|
case 'ti_ET': |
336
|
|
|
case 'wa': |
337
|
|
|
case 'wa_BE': |
338
|
|
|
case 'xbr': |
339
|
|
|
return (($number == 0) || ($number == 1)) ? 0 : 1; |
340
|
|
|
case 'be': |
341
|
|
|
case 'be_BY': |
342
|
|
|
case 'bs': |
343
|
|
|
case 'bs_BA': |
344
|
|
|
case 'hr': |
345
|
|
|
case 'hr_HR': |
346
|
|
|
case 'ru': |
347
|
|
|
case 'ru_RU': |
348
|
|
|
case 'ru_UA': |
349
|
|
|
case 'sr': |
350
|
|
|
case 'sr_ME': |
351
|
|
|
case 'sr_RS': |
352
|
|
|
case 'uk': |
353
|
|
|
case 'uk_UA': |
354
|
|
|
return (($number % 10 == 1) && ($number % 100 != 11)) ? 0 : ((($number % 10 >= 2) && ($number % 10 <= 4) && (($number % 100 < 10) || ($number % 100 >= 20))) ? 1 : 2); |
355
|
|
|
case 'cs': |
356
|
|
|
case 'cs_CZ': |
357
|
|
|
case 'sk': |
358
|
|
|
case 'sk_SK': |
359
|
|
|
return ($number == 1) ? 0 : ((($number >= 2) && ($number <= 4)) ? 1 : 2); |
360
|
|
|
case 'ga': |
361
|
|
|
case 'ga_IE': |
362
|
|
|
return ($number == 1) ? 0 : (($number == 2) ? 1 : 2); |
363
|
|
|
case 'lt': |
364
|
|
View Code Duplication |
case 'lt_LT': |
365
|
|
|
return (($number % 10 == 1) && ($number % 100 != 11)) ? 0 : ((($number % 10 >= 2) && (($number % 100 < 10) || ($number % 100 >= 20))) ? 1 : 2); |
366
|
|
|
case 'sl': |
367
|
|
View Code Duplication |
case 'sl_SI': |
368
|
|
|
return ($number % 100 == 1) ? 0 : (($number % 100 == 2) ? 1 : ((($number % 100 == 3) || ($number % 100 == 4)) ? 2 : 3)); |
369
|
|
|
case 'mk': |
370
|
|
|
case 'mk_MK': |
371
|
|
|
return ($number % 10 == 1) ? 0 : 1; |
372
|
|
|
case 'mt': |
373
|
|
View Code Duplication |
case 'mt_MT': |
374
|
|
|
return ($number == 1) ? 0 : ((($number == 0) || (($number % 100 > 1) && ($number % 100 < 11))) ? 1 : ((($number % 100 > 10) && ($number % 100 < 20)) ? 2 : 3)); |
375
|
|
|
case 'lv': |
376
|
|
|
case 'lv_LV': |
377
|
|
|
return ($number == 0) ? 0 : ((($number % 10 == 1) && ($number % 100 != 11)) ? 1 : 2); |
378
|
|
|
case 'pl': |
379
|
|
View Code Duplication |
case 'pl_PL': |
380
|
|
|
return ($number == 1) ? 0 : ((($number % 10 >= 2) && ($number % 10 <= 4) && (($number % 100 < 12) || ($number % 100 > 14))) ? 1 : 2); |
381
|
|
|
case 'cy': |
382
|
|
|
case 'cy_GB': |
383
|
|
|
return ($number == 1) ? 0 : (($number == 2) ? 1 : ((($number == 8) || ($number == 11)) ? 2 : 3)); |
384
|
|
|
case 'ro': |
385
|
|
|
case 'ro_RO': |
386
|
|
|
return ($number == 1) ? 0 : ((($number == 0) || (($number % 100 > 0) && ($number % 100 < 20))) ? 1 : 2); |
387
|
|
|
case 'ar': |
388
|
|
|
case 'ar_AE': |
389
|
|
|
case 'ar_BH': |
390
|
|
|
case 'ar_DZ': |
391
|
|
|
case 'ar_EG': |
392
|
|
|
case 'ar_IN': |
393
|
|
|
case 'ar_IQ': |
394
|
|
|
case 'ar_JO': |
395
|
|
|
case 'ar_KW': |
396
|
|
|
case 'ar_LB': |
397
|
|
|
case 'ar_LY': |
398
|
|
|
case 'ar_MA': |
399
|
|
|
case 'ar_OM': |
400
|
|
|
case 'ar_QA': |
401
|
|
|
case 'ar_SA': |
402
|
|
|
case 'ar_SD': |
403
|
|
|
case 'ar_SS': |
404
|
|
|
case 'ar_SY': |
405
|
|
|
case 'ar_TN': |
406
|
|
View Code Duplication |
case 'ar_YE': |
407
|
|
|
return ($number == 0) ? 0 : (($number == 1) ? 1 : (($number == 2) ? 2 : ((($number % 100 >= 3) && ($number % 100 <= 10)) ? 3 : ((($number % 100 >= 11) && ($number % 100 <= 99)) ? 4 : 5)))); |
408
|
|
|
default: |
409
|
|
|
return 0; |
410
|
|
|
} |
411
|
|
|
} |
412
|
|
|
} |
413
|
|
|
|
This check looks for the generic type
array
as a return type and suggests a more specific type. This type is inferred from the actual code.