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 | /** |
||
5 | * Rules are from: http://www.imena.org/decl_mn.html |
||
6 | * and http://www.imena.org/decl_fn.html |
||
7 | */ |
||
8 | class FirstNamesDeclension extends \morphos\NamesDeclension implements Cases { |
||
9 | use RussianLanguage; |
||
10 | |||
11 | protected $exceptions = array( |
||
12 | 'лев' => array( |
||
13 | self::IMENIT_1 => 'Лев', |
||
14 | self::RODIT_2 => 'Льва', |
||
15 | self::DAT_3 => 'Льву', |
||
16 | self::VINIT_4 => 'Льва', |
||
17 | self::TVORIT_5 => 'Львом', |
||
18 | self::PREDLOJ_6 => 'о Льве', |
||
19 | ), |
||
20 | 'павел' => array( |
||
21 | self::IMENIT_1 => 'Павел', |
||
22 | self::RODIT_2 => 'Павла', |
||
23 | self::DAT_3 => 'Павлу', |
||
24 | self::VINIT_4 => 'Павла', |
||
25 | self::TVORIT_5 => 'Павлом', |
||
26 | self::PREDLOJ_6 => 'о Павле', |
||
27 | ) |
||
28 | ); |
||
29 | |||
30 | static protected $menNames = array( |
||
31 | 'абрам', |
||
32 | 'аверьян', |
||
33 | 'авраам', |
||
34 | 'агафон', |
||
35 | 'адам', |
||
36 | 'азар', |
||
37 | 'акакий', |
||
38 | 'аким', |
||
39 | 'аксён', |
||
40 | 'александр', |
||
41 | 'алексей', |
||
42 | 'альберт', |
||
43 | 'анатолий', |
||
44 | 'андрей', |
||
45 | 'андрон', |
||
46 | 'антип', |
||
47 | 'антон', |
||
48 | 'аполлон', |
||
49 | 'аристарх', |
||
50 | 'аркадий', |
||
51 | 'арнольд', |
||
52 | 'арсений', |
||
53 | 'арсентий', |
||
54 | 'артем', |
||
55 | 'артём', |
||
56 | 'артемий', |
||
57 | 'артур', |
||
58 | 'аскольд', |
||
59 | 'афанасий', |
||
60 | 'богдан', |
||
61 | 'борис', |
||
62 | 'борислав', |
||
63 | 'бронислав', |
||
64 | 'вадим', |
||
65 | 'валентин', |
||
66 | 'валерий', |
||
67 | 'варлам', |
||
68 | 'василий', |
||
69 | 'венедикт', |
||
70 | 'вениамин', |
||
71 | 'веньямин', |
||
72 | 'венцеслав', |
||
73 | 'виктор', |
||
74 | 'вилен', |
||
75 | 'виталий', |
||
76 | 'владилен', |
||
77 | 'владимир', |
||
78 | 'владислав', |
||
79 | 'владлен', |
||
80 | 'всеволод', |
||
81 | 'всеслав', |
||
82 | 'вячеслав', |
||
83 | 'гавриил', |
||
84 | 'геннадий', |
||
85 | 'георгий', |
||
86 | 'герман', |
||
87 | 'глеб', |
||
88 | 'григорий', |
||
89 | 'давид', |
||
90 | 'даниил', |
||
91 | 'данил', |
||
92 | 'данила', |
||
93 | 'демьян', |
||
94 | 'денис', |
||
95 | 'димитрий', |
||
96 | 'дмитрий', |
||
97 | 'добрыня', |
||
98 | 'евгений', |
||
99 | 'евдоким', |
||
100 | 'евсей', |
||
101 | 'егор', |
||
102 | 'емельян', |
||
103 | 'еремей', |
||
104 | 'ермолай', |
||
105 | 'ерофей', |
||
106 | 'ефим', |
||
107 | 'захар', |
||
108 | 'иван', |
||
109 | 'игнат', |
||
110 | 'игорь', |
||
111 | 'илларион', |
||
112 | 'иларион', |
||
113 | 'илья', |
||
114 | 'иосиф', |
||
115 | 'казимир', |
||
116 | 'касьян', |
||
117 | 'кирилл', |
||
118 | 'кондрат', |
||
119 | 'константин', |
||
120 | 'кузьма', |
||
121 | 'лавр', |
||
122 | 'лаврентий', |
||
123 | 'лазарь', |
||
124 | 'ларион', |
||
125 | 'лев', |
||
126 | 'леонард', |
||
127 | 'леонид', |
||
128 | 'лука', |
||
129 | 'максим', |
||
130 | 'марат', |
||
131 | 'мартын', |
||
132 | 'матвей', |
||
133 | 'мефодий', |
||
134 | 'мирон', |
||
135 | 'михаил', |
||
136 | 'моисей', |
||
137 | 'назар', |
||
138 | 'никита', |
||
139 | 'николай', |
||
140 | 'олег', |
||
141 | 'осип', |
||
142 | 'остап', |
||
143 | 'павел', |
||
144 | 'панкрат', |
||
145 | 'пантелей', |
||
146 | 'парамон', |
||
147 | 'пётр', |
||
148 | 'петр', |
||
149 | 'платон', |
||
150 | 'потап', |
||
151 | 'прохор', |
||
152 | 'роберт', |
||
153 | 'ростислав', |
||
154 | 'савва', |
||
155 | 'савелий', |
||
156 | 'семён', |
||
157 | 'семен', |
||
158 | 'сергей', |
||
159 | 'сидор', |
||
160 | 'спартак', |
||
161 | 'тарас', |
||
162 | 'терентий', |
||
163 | 'тимофей', |
||
164 | 'тимур', |
||
165 | 'тихон', |
||
166 | 'ульян', |
||
167 | 'фёдор', |
||
168 | 'федор', |
||
169 | 'федот', |
||
170 | 'феликс', |
||
171 | 'фирс', |
||
172 | 'фома', |
||
173 | 'харитон', |
||
174 | 'харлам', |
||
175 | 'эдуард', |
||
176 | 'эммануил', |
||
177 | 'эраст', |
||
178 | 'юлиан', |
||
179 | 'юлий', |
||
180 | 'юрий', |
||
181 | 'яков', |
||
182 | 'ян', |
||
183 | 'ярослав', |
||
184 | ); |
||
185 | |||
186 | static protected $womenNames = array( |
||
187 | 'авдотья', |
||
188 | 'аврора', |
||
189 | 'агата', |
||
190 | 'агния', |
||
191 | 'агриппина', |
||
192 | 'ада', |
||
193 | 'аксинья', |
||
194 | 'алевтина', |
||
195 | 'александра', |
||
196 | 'алёна', |
||
197 | 'алена', |
||
198 | 'алина', |
||
199 | 'алиса', |
||
200 | 'алла', |
||
201 | 'альбина', |
||
202 | 'амалия', |
||
203 | 'анастасия', |
||
204 | 'ангелина', |
||
205 | 'анжела', |
||
206 | 'анжелика', |
||
207 | 'анна', |
||
208 | 'антонина', |
||
209 | 'анфиса', |
||
210 | 'арина', |
||
211 | 'белла', |
||
212 | 'божена', |
||
213 | 'валентина', |
||
214 | 'валерия', |
||
215 | 'ванда', |
||
216 | 'варвара', |
||
217 | 'василина', |
||
218 | 'василиса', |
||
219 | 'вера', |
||
220 | 'вероника', |
||
221 | 'виктория', |
||
222 | 'виола', |
||
223 | 'виолетта', |
||
224 | 'вита', |
||
225 | 'виталия', |
||
226 | 'владислава', |
||
227 | 'власта', |
||
228 | 'галина', |
||
229 | 'глафира', |
||
230 | 'дарья', |
||
231 | 'диана', |
||
232 | 'дина', |
||
233 | 'ева', |
||
234 | 'евгения', |
||
235 | 'евдокия', |
||
236 | 'евлампия', |
||
237 | 'екатерина', |
||
238 | 'елена', |
||
239 | 'елизавета', |
||
240 | 'ефросиния', |
||
241 | 'ефросинья', |
||
242 | 'жанна', |
||
243 | 'зиновия', |
||
244 | 'злата', |
||
245 | 'зоя', |
||
246 | 'ивонна', |
||
247 | 'изольда', |
||
248 | 'илона', |
||
249 | 'инга', |
||
250 | 'инесса', |
||
251 | 'инна', |
||
252 | 'ирина', |
||
253 | 'ия', |
||
254 | 'капитолина', |
||
255 | 'карина', |
||
256 | 'каролина', |
||
257 | 'кира', |
||
258 | 'клавдия', |
||
259 | 'клара', |
||
260 | 'клеопатра', |
||
261 | 'кристина', |
||
262 | 'ксения', |
||
263 | 'лада', |
||
264 | 'лариса', |
||
265 | 'лиана', |
||
266 | 'лидия', |
||
267 | 'лилия', |
||
268 | 'лина', |
||
269 | 'лия', |
||
270 | 'лора', |
||
271 | 'любава', |
||
272 | 'любовь', |
||
273 | 'людмила', |
||
274 | 'майя', |
||
275 | 'маргарита', |
||
276 | 'марианна', |
||
277 | 'мариетта', |
||
278 | 'марина', |
||
279 | 'мария', |
||
280 | 'марья', |
||
281 | 'марта', |
||
282 | 'марфа', |
||
283 | 'марьяна', |
||
284 | 'матрёна', |
||
285 | 'матрена', |
||
286 | 'матрона', |
||
287 | 'милена', |
||
288 | 'милослава', |
||
289 | 'мирослава', |
||
290 | 'муза', |
||
291 | 'надежда', |
||
292 | 'настасия', |
||
293 | 'настасья', |
||
294 | 'наталия', |
||
295 | 'наталья', |
||
296 | 'нелли', |
||
297 | 'ника', |
||
298 | 'нина', |
||
299 | 'нинель', |
||
300 | 'нонна', |
||
301 | 'оксана', |
||
302 | 'олимпиада', |
||
303 | 'ольга', |
||
304 | 'пелагея', |
||
305 | 'полина', |
||
306 | 'прасковья', |
||
307 | 'раиса', |
||
308 | 'рената', |
||
309 | 'римма', |
||
310 | 'роза', |
||
311 | 'роксана', |
||
312 | 'руфь', |
||
313 | 'сарра', |
||
314 | 'светлана', |
||
315 | 'серафима', |
||
316 | 'снежана', |
||
317 | 'софья', |
||
318 | 'софия', |
||
319 | 'стелла', |
||
320 | 'степанида', |
||
321 | 'стефания', |
||
322 | 'таисия', |
||
323 | 'таисья', |
||
324 | 'тамара', |
||
325 | 'татьяна', |
||
326 | 'ульяна', |
||
327 | 'устиния', |
||
328 | 'устинья', |
||
329 | 'фаина', |
||
330 | 'фёкла', |
||
331 | 'фекла', |
||
332 | 'феодора', |
||
333 | 'хаврония', |
||
334 | 'христина', |
||
335 | 'эвелина', |
||
336 | 'эдита', |
||
337 | 'элеонора', |
||
338 | 'элла', |
||
339 | 'эльвира', |
||
340 | 'эмилия', |
||
341 | 'эмма', |
||
342 | 'юдифь', |
||
343 | 'юлиана', |
||
344 | 'юлия', |
||
345 | 'ядвига', |
||
346 | 'яна', |
||
347 | 'ярослава', |
||
348 | ); |
||
349 | |||
350 | public function hasForms($name, $gender) { |
||
351 | //var_dump(upper(slice($name, -1))); |
||
352 | $name = lower($name); |
||
353 | // man rules |
||
354 | if ($gender === self::MAN) { |
||
355 | // soft consonant |
||
356 | if (lower(slice($name, -1)) == 'ь' && in_array(upper(slice($name, -2, -1)), self::$consonants)) { |
||
357 | return true; |
||
358 | } else if (in_array(upper(slice($name, -1)), array_diff(self::$consonants, array('Й', /*'Ч', 'Щ'*/)))) { // hard consonant |
||
359 | return true; |
||
360 | } else if (slice($name, -1) == 'й') { |
||
361 | return true; |
||
362 | } |
||
363 | } |
||
364 | |||
365 | // common rules |
||
366 | if ((in_array(slice($name, -1), array('а', 'я')) && !in_array(upper(slice($name, -2, -1)), self::$vowels)) || in_array(slice($name, -2), array('ия', 'ья', 'ея'))) { |
||
367 | return true; |
||
368 | } |
||
369 | |||
370 | return false; |
||
371 | } |
||
372 | |||
373 | |||
374 | |||
375 | public function detectGender($name) { |
||
376 | $name = lower($name); |
||
377 | if (in_array($name, self::$menNames)) |
||
378 | return self::MAN; |
||
379 | else if (in_array($name, self::$womenNames)) |
||
380 | return self::WOMAN; |
||
381 | |||
382 | return null; |
||
383 | } |
||
384 | |||
385 | public function getForms($name, $gender) { |
||
386 | $name = lower($name); |
||
387 | if ($gender == self::MAN) { |
||
388 | if (in_array(upper(slice($name, -1)), array_diff(self::$consonants, array('Й', /*'Ч', 'Щ'*/)))) { // hard consonant |
||
389 | $prefix = name($name); |
||
390 | // special cases for Лев, Павел |
||
391 | if (isset($this->exceptions[$name])) |
||
392 | return $this->exceptions[$name]; |
||
393 | else { |
||
394 | return array( |
||
395 | self::IMENIT_1 => $prefix, |
||
396 | self::RODIT_2 => $prefix.'а', |
||
397 | self::DAT_3 => $prefix.'у', |
||
398 | self::VINIT_4 => $prefix.'а', |
||
399 | self::TVORIT_5 => RussianLanguage::isHissingConsonant(slice($name, -1)) || slice($name, -1) == 'ц' ? $prefix.'ем' : $prefix.'ом', |
||
400 | self::PREDLOJ_6 => $this->choosePrepositionByFirstLetter($prefix, 'об', 'о').' '.$prefix.'е', |
||
401 | ); |
||
402 | } |
||
403 | } else if (slice($name, -1) == 'ь' && in_array(upper(slice($name, -2, -1)), self::$consonants)) { // soft consonant |
||
404 | $prefix = name(slice($name, 0, -1)); |
||
405 | return array( |
||
406 | self::IMENIT_1 => $prefix.'ь', |
||
407 | self::RODIT_2 => $prefix.'я', |
||
408 | self::DAT_3 => $prefix.'ю', |
||
409 | self::VINIT_4 => $prefix.'я', |
||
410 | self::TVORIT_5 => $prefix.'ем', |
||
411 | self::PREDLOJ_6 => $this->choosePrepositionByFirstLetter($prefix, 'об', 'о').' '.$prefix.'е', |
||
412 | ); |
||
413 | } else if (in_array(slice($name, -2), array('ай', 'ей', 'ой', 'уй', 'яй', 'юй', 'ий'))) { |
||
414 | $prefix = name(slice($name, 0, -1)); |
||
415 | $postfix = slice($name, -2) == 'ий' ? 'и' : 'е'; |
||
416 | return array( |
||
417 | self::IMENIT_1 => $prefix.'й', |
||
418 | self::RODIT_2 => $prefix.'я', |
||
419 | self::DAT_3 => $prefix.'ю', |
||
420 | self::VINIT_4 => $prefix.'я', |
||
421 | self::TVORIT_5 => $prefix.'ем', |
||
422 | self::PREDLOJ_6 => $this->choosePrepositionByFirstLetter($prefix, 'об', 'о').' '.$prefix.$postfix, |
||
423 | ); |
||
424 | } else if (slice($name, -1) == 'а' && ($before = slice($name, -2, -1)) && self::isConsonant($before) && !in_array($before, array(/*'г', 'к', 'х', */'ц'))) { |
||
425 | $prefix = name(slice($name, 0, -1)); |
||
426 | $postfix = (RussianLanguage::isHissingConsonant($before) || in_array($before, array('г', 'к', 'х'))) ? 'и' : 'ы'; |
||
427 | return array( |
||
428 | self::IMENIT_1 => $prefix.'а', |
||
429 | self::RODIT_2 => $prefix.$postfix, |
||
430 | self::DAT_3 => $prefix.'е', |
||
431 | self::VINIT_4 => $prefix.'у', |
||
432 | self::TVORIT_5 => $prefix.'ой', |
||
433 | self::PREDLOJ_6 => $this->choosePrepositionByFirstLetter($prefix, 'об', 'о').' '.$prefix.'е', |
||
434 | ); |
||
435 | } else if (slice($name, -2) == 'ия') { |
||
436 | $prefix = name(slice($name, 0, -1)); |
||
437 | return array( |
||
438 | self::IMENIT_1 => $prefix.'я', |
||
439 | self::RODIT_2 => $prefix.'и', |
||
440 | self::DAT_3 => $prefix.'и', |
||
441 | self::VINIT_4 => $prefix.'ю', |
||
442 | self::TVORIT_5 => $prefix.'ей', |
||
443 | self::PREDLOJ_6 => $this->choosePrepositionByFirstLetter($prefix, 'об', 'о').' '.$prefix.'и', |
||
444 | ); |
||
445 | } else if (slice($name, -2) == 'ло' || slice($name, -2) == 'ко') { |
||
446 | $prefix = name(slice($name, 0, -1)); |
||
447 | $postfix = slice($name, -2, -1) == 'к' ? 'и' : 'ы'; |
||
448 | return array( |
||
449 | self::IMENIT_1 => $prefix.'о', |
||
450 | self::RODIT_2 => $prefix.$postfix, |
||
451 | self::DAT_3 => $prefix.'е', |
||
452 | self::VINIT_4 => $prefix.'у', |
||
453 | self::TVORIT_5 => $prefix.'ой', |
||
454 | self::PREDLOJ_6 => $this->choosePrepositionByFirstLetter($prefix, 'об', 'о').' '.$prefix.'е', |
||
455 | ); |
||
456 | } |
||
457 | } else if ($gender == self::WOMAN) { |
||
458 | if (slice($name, -1) == 'а' && !in_array(upper($before = (slice($name, -2, -1))), self::$vowels)) { |
||
459 | $prefix = name(slice($name, 0, -1)); |
||
460 | if ($before != 'ц') { |
||
461 | $postfix = (RussianLanguage::isHissingConsonant($before) || in_array($before, array('г', 'к', 'х'))) ? 'и' : 'ы'; |
||
462 | return array( |
||
463 | self::IMENIT_1 => $prefix.'а', |
||
464 | self::RODIT_2 => $prefix.$postfix, |
||
465 | self::DAT_3 => $prefix.'е', |
||
466 | self::VINIT_4 => $prefix.'у', |
||
467 | self::TVORIT_5 => $prefix.'ой', |
||
468 | self::PREDLOJ_6 => $this->choosePrepositionByFirstLetter($prefix, 'об', 'о').' '.$prefix.'е', |
||
469 | ); |
||
470 | } else { |
||
471 | return array( |
||
472 | self::IMENIT_1 => $prefix.'а', |
||
473 | self::RODIT_2 => $prefix.'ы', |
||
474 | self::DAT_3 => $prefix.'е', |
||
475 | self::VINIT_4 => $prefix.'у', |
||
476 | self::TVORIT_5 => $prefix.'ей', |
||
477 | self::PREDLOJ_6 => $this->choosePrepositionByFirstLetter($prefix, 'об', 'о').' '.$prefix.'е', |
||
478 | ); |
||
479 | } |
||
480 | } else if (slice($name, -1) == 'ь' && self::isConsonant(slice($name, -2, -1))) { |
||
481 | $prefix = name(slice($name, 0, -1)); |
||
482 | return array( |
||
483 | self::IMENIT_1 => $prefix.'ь', |
||
484 | self::RODIT_2 => $prefix.'и', |
||
485 | self::DAT_3 => $prefix.'и', |
||
486 | self::VINIT_4 => $prefix.'ь', |
||
487 | self::TVORIT_5 => $prefix.'ью', |
||
488 | self::PREDLOJ_6 => $this->choosePrepositionByFirstLetter($prefix, 'об', 'о').' '.$prefix.'и', |
||
489 | ); |
||
490 | } else if (RussianLanguage::isHissingConsonant(slice($name, -1))) { |
||
491 | $prefix = name($name); |
||
492 | return array( |
||
493 | self::IMENIT_1 => $prefix, |
||
494 | self::RODIT_2 => $prefix.'и', |
||
495 | self::DAT_3 => $prefix.'и', |
||
496 | self::VINIT_4 => $prefix, |
||
497 | self::TVORIT_5 => $prefix.'ью', |
||
498 | self::PREDLOJ_6 => $this->choosePrepositionByFirstLetter($prefix, 'об', 'о').' '.$prefix.'и', |
||
499 | ); |
||
500 | } |
||
501 | } |
||
502 | |||
503 | // common rules for ия and я |
||
504 | if (slice($name, -1) == 'я' and slice($name, -2, -1) != 'и') { |
||
505 | $prefix = name(slice($name, 0, -1)); |
||
506 | return array( |
||
507 | self::IMENIT_1 => $prefix.'я', |
||
508 | self::RODIT_2 => $prefix.'и', |
||
509 | self::DAT_3 => $prefix.'е', |
||
510 | self::VINIT_4 => $prefix.'ю', |
||
511 | self::TVORIT_5 => $prefix.'ей', |
||
512 | self::PREDLOJ_6 => $this->choosePrepositionByFirstLetter($prefix, 'об', 'о').' '.$prefix.'е', |
||
513 | ); |
||
514 | View Code Duplication | } else if (slice($name, -2) == 'ия') { |
|
0 ignored issues
–
show
|
|||
515 | $prefix = name(slice($name, 0, -1)); |
||
516 | return array( |
||
517 | self::IMENIT_1 => $prefix.'я', |
||
518 | self::RODIT_2 => $prefix.'и', |
||
519 | self::DAT_3 => $prefix.'и', |
||
520 | self::VINIT_4 => $prefix.'ю', |
||
521 | self::TVORIT_5 => $prefix.'ей', |
||
522 | self::PREDLOJ_6 => $this->choosePrepositionByFirstLetter($prefix, 'об', 'о').' '.$prefix.'и', |
||
523 | ); |
||
524 | } |
||
525 | |||
526 | $name = name($name); |
||
527 | return array_fill_keys(array(self::IMENIT_1, self::RODIT_2, self::DAT_3, self::VINIT_4, self::TVORIT_5), $name) + array(self::PREDLOJ_6 => $this->choosePrepositionByFirstLetter($name, 'об', 'о').' '.$name); |
||
528 | } |
||
529 | |||
530 | View Code Duplication | public function getForm($name, $form, $gender) { |
|
0 ignored issues
–
show
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...
|
|||
531 | $forms = $this->getForms($name, $gender); |
||
532 | if ($forms !== false) |
||
533 | if (isset($forms[$form])) |
||
534 | return $forms[$form]; |
||
535 | else |
||
536 | return $name; |
||
537 | else |
||
538 | return $name; |
||
539 | } |
||
540 | } |
||
541 |
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.