]>
Commit | Line | Data |
---|---|---|
4f5b44bd NL |
1 | <?php |
2 | ||
3 | /* | |
4 | * This file is part of the Symfony package. | |
5 | * | |
6 | * (c) Fabien Potencier <fabien@symfony.com> | |
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 Symfony\Component\Translation; | |
13 | ||
14 | /** | |
15 | * Returns the plural rules for a given locale. | |
16 | * | |
17 | * @author Fabien Potencier <fabien@symfony.com> | |
18 | */ | |
19 | class PluralizationRules | |
20 | { | |
21 | // @codeCoverageIgnoreStart | |
22 | private static $rules = array(); | |
23 | ||
24 | /** | |
25 | * Returns the plural position to use for the given locale and number. | |
26 | * | |
27 | * @param integer $number The number | |
28 | * @param string $locale The locale | |
29 | * | |
30 | * @return integer The plural position | |
31 | */ | |
32 | public static function get($number, $locale) | |
33 | { | |
34 | if ("pt_BR" == $locale) { | |
35 | // temporary set a locale for brazilian | |
36 | $locale = "xbr"; | |
37 | } | |
38 | ||
39 | if (strlen($locale) > 3) { | |
40 | $locale = substr($locale, 0, -strlen(strrchr($locale, '_'))); | |
41 | } | |
42 | ||
43 | if (isset(self::$rules[$locale])) { | |
44 | $return = call_user_func(self::$rules[$locale], $number); | |
45 | ||
46 | if (!is_int($return) || $return < 0) { | |
47 | return 0; | |
48 | } | |
49 | ||
50 | return $return; | |
51 | } | |
52 | ||
53 | /* | |
54 | * The plural rules are derived from code of the Zend Framework (2010-09-25), | |
55 | * which is subject to the new BSD license (http://framework.zend.com/license/new-bsd). | |
56 | * Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com) | |
57 | */ | |
58 | switch ($locale) { | |
59 | case 'bo': | |
60 | case 'dz': | |
61 | case 'id': | |
62 | case 'ja': | |
63 | case 'jv': | |
64 | case 'ka': | |
65 | case 'km': | |
66 | case 'kn': | |
67 | case 'ko': | |
68 | case 'ms': | |
69 | case 'th': | |
70 | case 'tr': | |
71 | case 'vi': | |
72 | case 'zh': | |
73 | return 0; | |
74 | break; | |
75 | ||
76 | case 'af': | |
77 | case 'az': | |
78 | case 'bn': | |
79 | case 'bg': | |
80 | case 'ca': | |
81 | case 'da': | |
82 | case 'de': | |
83 | case 'el': | |
84 | case 'en': | |
85 | case 'eo': | |
86 | case 'es': | |
87 | case 'et': | |
88 | case 'eu': | |
89 | case 'fa': | |
90 | case 'fi': | |
91 | case 'fo': | |
92 | case 'fur': | |
93 | case 'fy': | |
94 | case 'gl': | |
95 | case 'gu': | |
96 | case 'ha': | |
97 | case 'he': | |
98 | case 'hu': | |
99 | case 'is': | |
100 | case 'it': | |
101 | case 'ku': | |
102 | case 'lb': | |
103 | case 'ml': | |
104 | case 'mn': | |
105 | case 'mr': | |
106 | case 'nah': | |
107 | case 'nb': | |
108 | case 'ne': | |
109 | case 'nl': | |
110 | case 'nn': | |
111 | case 'no': | |
112 | case 'om': | |
113 | case 'or': | |
114 | case 'pa': | |
115 | case 'pap': | |
116 | case 'ps': | |
117 | case 'pt': | |
118 | case 'so': | |
119 | case 'sq': | |
120 | case 'sv': | |
121 | case 'sw': | |
122 | case 'ta': | |
123 | case 'te': | |
124 | case 'tk': | |
125 | case 'ur': | |
126 | case 'zu': | |
127 | return ($number == 1) ? 0 : 1; | |
128 | ||
129 | case 'am': | |
130 | case 'bh': | |
131 | case 'fil': | |
132 | case 'fr': | |
133 | case 'gun': | |
134 | case 'hi': | |
135 | case 'ln': | |
136 | case 'mg': | |
137 | case 'nso': | |
138 | case 'xbr': | |
139 | case 'ti': | |
140 | case 'wa': | |
141 | return (($number == 0) || ($number == 1)) ? 0 : 1; | |
142 | ||
143 | case 'be': | |
144 | case 'bs': | |
145 | case 'hr': | |
146 | case 'ru': | |
147 | case 'sr': | |
148 | case 'uk': | |
149 | return (($number % 10 == 1) && ($number % 100 != 11)) ? 0 : ((($number % 10 >= 2) && ($number % 10 <= 4) && (($number % 100 < 10) || ($number % 100 >= 20))) ? 1 : 2); | |
150 | ||
151 | case 'cs': | |
152 | case 'sk': | |
153 | return ($number == 1) ? 0 : ((($number >= 2) && ($number <= 4)) ? 1 : 2); | |
154 | ||
155 | case 'ga': | |
156 | return ($number == 1) ? 0 : (($number == 2) ? 1 : 2); | |
157 | ||
158 | case 'lt': | |
159 | return (($number % 10 == 1) && ($number % 100 != 11)) ? 0 : ((($number % 10 >= 2) && (($number % 100 < 10) || ($number % 100 >= 20))) ? 1 : 2); | |
160 | ||
161 | case 'sl': | |
162 | return ($number % 100 == 1) ? 0 : (($number % 100 == 2) ? 1 : ((($number % 100 == 3) || ($number % 100 == 4)) ? 2 : 3)); | |
163 | ||
164 | case 'mk': | |
165 | return ($number % 10 == 1) ? 0 : 1; | |
166 | ||
167 | case 'mt': | |
168 | return ($number == 1) ? 0 : ((($number == 0) || (($number % 100 > 1) && ($number % 100 < 11))) ? 1 : ((($number % 100 > 10) && ($number % 100 < 20)) ? 2 : 3)); | |
169 | ||
170 | case 'lv': | |
171 | return ($number == 0) ? 0 : ((($number % 10 == 1) && ($number % 100 != 11)) ? 1 : 2); | |
172 | ||
173 | case 'pl': | |
174 | return ($number == 1) ? 0 : ((($number % 10 >= 2) && ($number % 10 <= 4) && (($number % 100 < 12) || ($number % 100 > 14))) ? 1 : 2); | |
175 | ||
176 | case 'cy': | |
177 | return ($number == 1) ? 0 : (($number == 2) ? 1 : ((($number == 8) || ($number == 11)) ? 2 : 3)); | |
178 | ||
179 | case 'ro': | |
180 | return ($number == 1) ? 0 : ((($number == 0) || (($number % 100 > 0) && ($number % 100 < 20))) ? 1 : 2); | |
181 | ||
182 | case 'ar': | |
183 | return ($number == 0) ? 0 : (($number == 1) ? 1 : (($number == 2) ? 2 : ((($number >= 3) && ($number <= 10)) ? 3 : ((($number >= 11) && ($number <= 99)) ? 4 : 5)))); | |
184 | ||
185 | default: | |
186 | return 0; | |
187 | } | |
188 | } | |
189 | ||
190 | /** | |
191 | * Overrides the default plural rule for a given locale. | |
192 | * | |
193 | * @param string $rule A PHP callable | |
194 | * @param string $locale The locale | |
195 | * | |
196 | * @return null | |
197 | * | |
198 | * @throws \LogicException | |
199 | */ | |
200 | public static function set($rule, $locale) | |
201 | { | |
202 | if ("pt_BR" == $locale) { | |
203 | // temporary set a locale for brazilian | |
204 | $locale = "xbr"; | |
205 | } | |
206 | ||
207 | if (strlen($locale) > 3) { | |
208 | $locale = substr($locale, 0, -strlen(strrchr($locale, '_'))); | |
209 | } | |
210 | ||
211 | if (!is_callable($rule)) { | |
212 | throw new \LogicException('The given rule can not be called'); | |
213 | } | |
214 | ||
215 | self::$rules[$locale] = $rule; | |
216 | } | |
217 | ||
218 | // @codeCoverageIgnoreEnd | |
219 | } |