These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | namespace morphos\Russian; |
||
3 | |||
4 | use morphos\S; |
||
5 | |||
6 | /** |
||
7 | * Rules are from: https://ru.wikipedia.org/wiki/%D0%A1%D0%BA%D0%BB%D0%BE%D0%BD%D0%B5%D0%BD%D0%B8%D0%B5_%D0%B3%D0%B5%D0%BE%D0%B3%D1%80%D0%B0%D1%84%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%B8%D1%85_%D0%BD%D0%B0%D0%B7%D0%B2%D0%B0%D0%BD%D0%B8%D0%B9_%D0%B2_%D1%80%D1%83%D1%81%D1%81%D0%BA%D0%BE%D0%BC_%D1%8F%D0%B7%D1%8B%D0%BA%D0%B5 |
||
8 | */ |
||
9 | class GeographicalNamesInflection extends \morphos\BaseInflection implements Cases |
||
10 | { |
||
11 | use RussianLanguage, CasesHelper; |
||
12 | |||
13 | protected static $abbreviations = array( |
||
14 | 'сша', |
||
15 | 'оаэ', |
||
16 | 'ссср', |
||
17 | 'юар', |
||
18 | ); |
||
19 | |||
20 | public static function isMutable($name) |
||
21 | { |
||
22 | $name = S::lower($name); |
||
23 | |||
24 | // // ends with 'ы' or 'и': plural form |
||
25 | // if (in_array(S::slice($name, -1), array('и', 'ы'))) |
||
26 | // return false; |
||
27 | |||
28 | if (in_array($name, self::$abbreviations)) { |
||
29 | return false; |
||
30 | } |
||
31 | |||
32 | // N край |
||
33 | if (S::slice($name, -5) == ' край') { |
||
34 | return static::isMutable(S::slice($name, 0, -5)); |
||
35 | } |
||
36 | |||
37 | // N область |
||
38 | if (S::slice($name, -8) == ' область') { |
||
39 | return true; |
||
40 | } |
||
41 | |||
42 | // город N |
||
43 | if (S::slice($name, 0, 6) == 'город ') { |
||
44 | return true; |
||
45 | } |
||
46 | |||
47 | // ends with 'е' or 'о', but not with 'ово/ёво/ево/ино/ыно' |
||
48 | if (in_array(S::slice($name, -1), array('е', 'о')) && !in_array(S::slice($name, -3, -1), array('ов', 'ёв', 'ев', 'ин', 'ын'))) { |
||
49 | return false; |
||
50 | } |
||
51 | return true; |
||
52 | } |
||
53 | |||
54 | public static function getCases($name) |
||
55 | { |
||
56 | $name = S::lower($name); |
||
57 | |||
58 | // N край |
||
59 | View Code Duplication | if (S::slice($name, -5) == ' край') { |
|
60 | return self::composeCasesFromWords([static::getCases(S::slice($name, 0, -5)), NounDeclension::getCases('край')]); |
||
61 | } |
||
62 | |||
63 | // N область |
||
64 | View Code Duplication | if (S::slice($name, -8) == ' область') { |
|
65 | return self::composeCasesFromWords([static::getCases(S::slice($name, 0, -8)), NounDeclension::getCases('область')]); |
||
66 | } |
||
67 | |||
68 | // город N |
||
69 | View Code Duplication | if (S::slice($name, 0, 6) == 'город ') { |
|
70 | return self::composeCasesFromWords([ |
||
71 | NounDeclension::getCases('город'), |
||
72 | array_fill_keys(self::getAllCases(), S::name(S::slice($name, -6))) |
||
73 | ]); |
||
74 | } |
||
75 | |||
76 | // check for name of few words |
||
77 | View Code Duplication | if (strpos($name, ' ') !== false) { |
|
0 ignored issues
–
show
|
|||
78 | $parts = explode(' ', $name); |
||
79 | $cases = array(); |
||
80 | $result = array(); |
||
81 | foreach ($parts as $i => $part) { |
||
82 | $result[$i] = static::getCases($part); |
||
83 | } |
||
84 | return self::composeCasesFromWords($result); |
||
85 | } |
||
86 | |||
87 | if (!in_array($name, self::$abbreviations)) { |
||
88 | if (S::slice($name, -2) == 'ий') { |
||
89 | // Нижний, Русский |
||
90 | $prefix = S::name(S::slice($name, 0, -2)); |
||
91 | return array( |
||
92 | self::IMENIT => $prefix.'ий', |
||
93 | self::RODIT => $prefix.(self::isVelarConsonant(S::slice($name, -3, -2)) ? 'ого' : 'его'), |
||
94 | self::DAT => $prefix.(self::isVelarConsonant(S::slice($name, -3, -2)) ? 'ому' : 'ему'), |
||
95 | self::VINIT => $prefix.'ий', |
||
96 | self::TVORIT => $prefix.'им', |
||
97 | self::PREDLOJ => $prefix.(self::chooseEndingBySonority($prefix, 'ем', 'ом')), |
||
98 | ); |
||
99 | } else if (S::slice($name, -2) == 'ая') { |
||
100 | // Ростовская |
||
101 | $prefix = S::name(S::slice($name, 0, -2)); |
||
102 | return array( |
||
103 | self::IMENIT => $prefix.'ая', |
||
104 | self::RODIT => $prefix.'ой', |
||
105 | self::DAT => $prefix.'ой', |
||
106 | self::VINIT => $prefix.'ую', |
||
107 | self::TVORIT => $prefix.'ой', |
||
108 | self::PREDLOJ => $prefix.'ой', |
||
109 | ); |
||
110 | } else if (S::slice($name, -2) == 'ый') { |
||
111 | // Грозный, Благодарный |
||
112 | $prefix = S::name(S::slice($name, 0, -2)); |
||
113 | return array( |
||
114 | self::IMENIT => $prefix.'ый', |
||
115 | self::RODIT => $prefix.'ого', |
||
116 | self::DAT => $prefix.'ому', |
||
117 | self::VINIT => $prefix.'ый', |
||
118 | self::TVORIT => $prefix.'ым', |
||
119 | self::PREDLOJ => $prefix.'ом', |
||
120 | ); |
||
121 | } elseif (S::slice($name, -1) == 'а') { |
||
122 | // Москва, Рига |
||
123 | $prefix = S::name(S::slice($name, 0, -1)); |
||
124 | return array( |
||
125 | self::IMENIT => $prefix.'а', |
||
126 | self::RODIT => $prefix.(self::isVelarConsonant(S::slice($name, -2, -1)) ? 'и' : 'ы'), |
||
127 | self::DAT => $prefix.'е', |
||
128 | self::VINIT => $prefix.'у', |
||
129 | self::TVORIT => $prefix.'ой', |
||
130 | self::PREDLOJ => $prefix.'е', |
||
131 | ); |
||
132 | } elseif (S::slice($name, -1) == 'я') { |
||
133 | // Азия |
||
134 | $prefix = S::name(S::slice($name, 0, -1)); |
||
135 | return array( |
||
136 | self::IMENIT => S::name($name), |
||
137 | self::RODIT => $prefix.'и', |
||
138 | self::DAT => $prefix.'и', |
||
139 | self::VINIT => $prefix.'ю', |
||
140 | self::TVORIT => $prefix.'ей', |
||
141 | self::PREDLOJ => $prefix.'и', |
||
142 | ); |
||
143 | } elseif (S::slice($name, -1) == 'й') { |
||
144 | // Ишимбай |
||
145 | $prefix = S::name(S::slice($name, 0, -1)); |
||
146 | return array( |
||
147 | self::IMENIT => $prefix.'й', |
||
148 | self::RODIT => $prefix.'я', |
||
149 | self::DAT => $prefix.'ю', |
||
150 | self::VINIT => $prefix.'й', |
||
151 | self::TVORIT => $prefix.'ем', |
||
152 | self::PREDLOJ => $prefix.'е', |
||
153 | ); |
||
154 | View Code Duplication | } elseif (self::isConsonant(S::slice($name, -1)) && S::slice($name, -2) != 'ов') { |
|
155 | // Париж, Валаам, Киев |
||
156 | $prefix = S::name($name); |
||
157 | return array( |
||
158 | self::IMENIT => $prefix, |
||
159 | self::RODIT => $prefix.'а', |
||
160 | self::DAT => $prefix.'у', |
||
161 | self::VINIT => $prefix, |
||
162 | self::TVORIT => $prefix.(self::isVelarConsonant(S::slice($name, -2, -1)) ? 'ем' : 'ом'), |
||
163 | self::PREDLOJ => $prefix.'е', |
||
164 | ); |
||
165 | } elseif (S::slice($name, -2) == 'ль') { |
||
166 | // Ставрополь, Ярославль |
||
167 | $prefix = S::name(S::slice($name, 0, -1)); |
||
168 | return array( |
||
169 | self::IMENIT => $prefix.'ь', |
||
170 | self::RODIT => $prefix.'я', |
||
171 | self::DAT => $prefix.'ю', |
||
172 | self::VINIT => $prefix.'ь', |
||
173 | self::TVORIT => $prefix.'ем', |
||
174 | self::PREDLOJ => $prefix.'е', |
||
175 | ); |
||
176 | } elseif (S::slice($name, -2) == 'рь') { |
||
177 | // Тверь |
||
178 | $prefix = S::name(S::slice($name, 0, -1)); |
||
179 | return array( |
||
180 | self::IMENIT => $prefix.'ь', |
||
181 | self::RODIT => $prefix.'и', |
||
182 | self::DAT => $prefix.'и', |
||
183 | self::VINIT => $prefix.'ь', |
||
184 | self::TVORIT => $prefix.'ью', |
||
185 | self::PREDLOJ => $prefix.'и', |
||
186 | ); |
||
187 | } elseif (S::slice($name, -2) == 'ки') { |
||
188 | // Березники, Ессентуки |
||
189 | $prefix = S::name(S::slice($name, 0, -1)); |
||
190 | return array( |
||
191 | self::IMENIT => $prefix.'и', |
||
192 | self::RODIT => $prefix.'ов', |
||
193 | self::DAT => $prefix.'ам', |
||
194 | self::VINIT => $prefix.'и', |
||
195 | self::TVORIT => $prefix.'ами', |
||
196 | self::PREDLOJ => $prefix.'ах', |
||
197 | ); |
||
198 | } elseif (S::slice($name, -2) == 'мь') { |
||
199 | // Пермь, Кемь |
||
200 | $prefix = S::name(S::slice($name, 0, -1)); |
||
201 | return array( |
||
202 | self::IMENIT => $prefix.'ь', |
||
203 | self::RODIT => $prefix.'и', |
||
204 | self::DAT => $prefix.'и', |
||
205 | self::VINIT => $prefix.'ь', |
||
206 | self::TVORIT => $prefix.'ью', |
||
207 | self::PREDLOJ => $prefix.'и', |
||
208 | ); |
||
209 | } elseif (S::slice($name, -2) == 'нь') { |
||
210 | // Рязань, Назрань |
||
211 | $prefix = S::name(S::slice($name, 0, -1)); |
||
212 | return array( |
||
213 | self::IMENIT => $prefix.'ь', |
||
214 | self::RODIT => $prefix.'и', |
||
215 | self::DAT => $prefix.'и', |
||
216 | self::VINIT => $prefix.'ь', |
||
217 | self::TVORIT => $prefix.'ью', |
||
218 | self::PREDLOJ => $prefix.'и', |
||
219 | ); |
||
220 | View Code Duplication | } else if (S::slice($name, -2) == 'ые') { |
|
221 | // Набережные |
||
222 | $prefix = S::name(S::slice($name, 0, -1)); |
||
223 | return array( |
||
224 | self::IMENIT => $prefix.'е', |
||
225 | self::RODIT => $prefix.'х', |
||
226 | self::DAT => $prefix.'м', |
||
227 | self::VINIT => $prefix.'е', |
||
228 | self::TVORIT => $prefix.'ми', |
||
229 | self::PREDLOJ => $prefix.'х', |
||
230 | ); |
||
231 | } else if (S::slice($name, -2) == 'ны') { |
||
232 | // Челны |
||
233 | $prefix = S::name(S::slice($name, 0, -1)); |
||
234 | return array( |
||
235 | self::IMENIT => $prefix.'ы', |
||
236 | self::RODIT => $prefix.'ов', |
||
237 | self::DAT => $prefix.'ам', |
||
238 | self::VINIT => $prefix.'ы', |
||
239 | self::TVORIT => $prefix.'ами', |
||
240 | self::PREDLOJ => $prefix.'ах', |
||
241 | ); |
||
242 | } |
||
243 | |||
244 | $suffixes = array('ов', 'ёв', 'ев', 'ин', 'ын'); |
||
245 | if ((in_array(S::slice($name, -1), array('е', 'о')) && in_array(S::slice($name, -3, -1), $suffixes)) || in_array(S::slice($name, -2), $suffixes)) { |
||
246 | // ово, ёво, ... |
||
247 | if (in_array(S::slice($name, -3, -1), $suffixes)) { |
||
248 | $prefix = S::name(S::slice($name, 0, -1)); |
||
249 | } |
||
250 | // ов, её, ... |
||
251 | elseif (in_array(S::slice($name, -2), $suffixes)) { |
||
252 | $prefix = S::name($name); |
||
253 | } |
||
254 | return array( |
||
255 | self::IMENIT => S::name($name), |
||
256 | self::RODIT => $prefix.'а', |
||
257 | self::DAT => $prefix.'у', |
||
258 | self::VINIT => S::name($name), |
||
259 | self::TVORIT => $prefix.'ым', |
||
260 | self::PREDLOJ => $prefix.'е', |
||
261 | ); |
||
262 | } |
||
263 | } |
||
264 | |||
265 | // if no rules matches or name is immutable |
||
266 | $name = in_array($name, self::$abbreviations) ? S::upper($name) : S::name($name); |
||
267 | return array_fill_keys(array(self::IMENIT, self::RODIT, self::DAT, self::VINIT, self::TVORIT, self::PREDLOJ), $name); |
||
268 | } |
||
269 | |||
270 | public static function getCase($name, $case) |
||
271 | { |
||
272 | $case = self::canonizeCase($case); |
||
273 | $forms = self::getCases($name); |
||
274 | return $forms[$case]; |
||
275 | } |
||
276 | } |
||
277 |
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.