1
|
|
|
<?php |
2
|
|
|
namespace morphos\Russian; |
3
|
|
|
|
4
|
|
|
class FirstNamesDeclension extends \morphos\NamesDeclension implements Cases { |
5
|
|
|
use RussianLanguage; |
6
|
|
|
|
7
|
|
|
public function hasForms($name, $gender) { |
8
|
|
|
//var_dump(upper(slice($name, -1))); |
9
|
|
|
$name = lower($name); |
10
|
|
|
// man rules |
11
|
|
|
if ($gender === self::MAN) { |
12
|
|
|
// soft consonant |
13
|
|
|
if (lower(slice($name, -1)) == 'ь' && in_array(upper(slice($name, -2, -1)), self::$consonants)) { |
14
|
|
|
return true; |
15
|
|
|
} else if (in_array(upper(slice($name, -1)), array_diff(self::$consonants, array('Й', /*'Ч', 'Щ'*/)))) { // hard consonant |
16
|
|
|
return true; |
17
|
|
|
} else if (slice($name, -1) == 'й') { |
18
|
|
|
return true; |
19
|
|
|
} |
20
|
|
|
} |
21
|
|
|
|
22
|
|
|
// common rules |
23
|
|
|
if ((in_array(slice($name, -1), array('а', 'я')) && !in_array(upper(slice($name, -2, -1)), self::$vowels)) || in_array(slice($name, -2), array('ия', 'ья', 'ея'))) { |
24
|
|
|
return true; |
25
|
|
|
} |
26
|
|
|
|
27
|
|
|
return false; |
28
|
|
|
} |
29
|
|
|
|
30
|
|
|
public function getForms($name, $gender) { |
31
|
|
|
$name = lower($name); |
32
|
|
|
if ($gender == self::MAN) { |
33
|
|
|
if (in_array(upper(slice($name, -1)), array_diff(self::$consonants, array('Й', /*'Ч', 'Щ'*/)))) { // hard consonant |
34
|
|
|
$prefix = name($name); |
35
|
|
|
// special cases for Лев, Павел |
36
|
|
|
if ($name == 'лев') |
37
|
|
|
return $this->getFormsForLev(); |
38
|
|
|
else if ($name == 'павел') |
39
|
|
|
return $this->getFormsForPavel(); |
40
|
|
|
else { |
41
|
|
|
return array( |
42
|
|
|
self::IMENIT_1 => $prefix, |
43
|
|
|
self::RODIT_2 => $prefix.'а', |
44
|
|
|
self::DAT_3 => $prefix.'у', |
45
|
|
|
self::VINIT_4 => $prefix.'а', |
46
|
|
|
self::TVORIT_5 => $this->isHissingConsonant(slice($name, -1)) || slice($name, -1) == 'ц' ? $prefix.'ем' : $prefix.'ом', |
47
|
|
|
self::PREDLOJ_6 => in_array(upper(slice($name, 0, 1)), self::$vowels) ? 'об '.$prefix.'е' : 'о '.$prefix.'е', |
48
|
|
|
); |
49
|
|
|
} |
50
|
|
|
} else if (slice($name, -1) == 'ь' && in_array(upper(slice($name, -2, -1)), self::$consonants)) { // soft consonant |
51
|
|
|
$prefix = name(slice($name, 0, -1)); |
52
|
|
|
return array( |
53
|
|
|
self::IMENIT_1 => $prefix.'ь', |
54
|
|
|
self::RODIT_2 => $prefix.'я', |
55
|
|
|
self::DAT_3 => $prefix.'ю', |
56
|
|
|
self::VINIT_4 => $prefix.'я', |
57
|
|
|
self::TVORIT_5 => $prefix.'ем', |
58
|
|
|
self::PREDLOJ_6 => in_array(upper(slice($name, 0, 1)), self::$vowels) ? 'об '.$prefix.'е' : 'о '.$prefix.'е', |
59
|
|
|
); |
60
|
|
|
} else if (in_array(slice($name, -2), array('ай', 'ей', 'ой', 'уй', 'яй', 'юй', 'ий'))) { |
61
|
|
|
$prefix = name(slice($name, 0, -1)); |
62
|
|
|
$postfix = slice($name, -2) == 'ий' ? 'и' : 'е'; |
63
|
|
|
return array( |
64
|
|
|
self::IMENIT_1 => $prefix.'й', |
65
|
|
|
self::RODIT_2 => $prefix.'я', |
66
|
|
|
self::DAT_3 => $prefix.'ю', |
67
|
|
|
self::VINIT_4 => $prefix.'я', |
68
|
|
|
self::TVORIT_5 => $prefix.'ем', |
69
|
|
|
self::PREDLOJ_6 => in_array(upper(slice($name, 0, 1)), self::$vowels) ? 'об '.$prefix.$postfix : 'о '.$prefix.$postfix, |
70
|
|
|
); |
71
|
|
|
} else if (slice($name, -1) == 'а' && ($before = slice($name, -2, -1)) && $this->isConsonant($before) && !in_array($before, array(/*'г', 'к', 'х', */'ц'))) { |
72
|
|
|
$prefix = name(slice($name, 0, -1)); |
73
|
|
|
$postfix = ($this->isHissingConsonant($before) || in_array($before, array('г', 'к', 'х'))) ? 'и' : 'ы'; |
74
|
|
|
return array( |
75
|
|
|
self::IMENIT_1 => $prefix.'а', |
76
|
|
|
self::RODIT_2 => $prefix.$postfix, |
77
|
|
|
self::DAT_3 => $prefix.'е', |
78
|
|
|
self::VINIT_4 => $prefix.'у', |
79
|
|
|
self::TVORIT_5 => $prefix.'ой', |
80
|
|
|
self::PREDLOJ_6 => in_array(upper(slice($name, 0, 1)), self::$vowels) ? 'об '.$prefix.'е' : 'о '.$prefix.'е', |
81
|
|
|
); |
82
|
|
|
} else if (slice($name, -2) == 'ия') { |
83
|
|
|
$prefix = name(slice($name, 0, -1)); |
84
|
|
|
return array( |
85
|
|
|
self::IMENIT_1 => $prefix.'я', |
86
|
|
|
self::RODIT_2 => $prefix.'и', |
87
|
|
|
self::DAT_3 => $prefix.'и', |
88
|
|
|
self::VINIT_4 => $prefix.'ю', |
89
|
|
|
self::TVORIT_5 => $prefix.'ей', |
90
|
|
|
self::PREDLOJ_6 => in_array(upper(slice($name, 0, 1)), self::$vowels) ? 'об '.$prefix.'и' : 'о '.$prefix.'и', |
91
|
|
|
); |
92
|
|
|
} else if (slice($name, -2) == 'ло' || slice($name, -2) == 'ко') { |
93
|
|
|
$prefix = name(slice($name, 0, -1)); |
94
|
|
|
$postfix = slice($name, -2, -1) == 'к' ? 'и' : 'ы'; |
95
|
|
|
return array( |
96
|
|
|
self::IMENIT_1 => $prefix.'о', |
97
|
|
|
self::RODIT_2 => $prefix.$postfix, |
98
|
|
|
self::DAT_3 => $prefix.'е', |
99
|
|
|
self::VINIT_4 => $prefix.'у', |
100
|
|
|
self::TVORIT_5 => $prefix.'ой', |
101
|
|
|
self::PREDLOJ_6 => in_array(upper(slice($name, 0, 1)), self::$vowels) ? 'об '.$prefix.'е' : 'о '.$prefix.'е', |
102
|
|
|
); |
103
|
|
|
} else { |
104
|
|
|
return false; |
105
|
|
|
} |
106
|
|
|
} else { |
107
|
|
|
if (slice($name, -1) == 'а' && ($before = (slice($name, -2, -1)))) { |
108
|
|
|
$prefix = name(slice($name, 0, -1)); |
109
|
|
|
if ($before != 'ц') { |
110
|
|
|
$postfix = ($this->isHissingConsonant($before) || in_array($before, array('г', 'к', 'х'))) ? 'и' : 'ы'; |
111
|
|
|
return array( |
112
|
|
|
self::IMENIT_1 => $prefix.'а', |
113
|
|
|
self::RODIT_2 => $prefix.$postfix, |
114
|
|
|
self::DAT_3 => $prefix.'е', |
115
|
|
|
self::VINIT_4 => $prefix.'у', |
116
|
|
|
self::TVORIT_5 => $prefix.'ой', |
117
|
|
|
self::PREDLOJ_6 => in_array(upper(slice($name, 0, 1)), self::$vowels) ? 'об '.$prefix.'е' : 'о '.$prefix.'е', |
118
|
|
|
); |
119
|
|
|
} else { |
120
|
|
|
return array( |
121
|
|
|
self::IMENIT_1 => $prefix.'а', |
122
|
|
|
self::RODIT_2 => $prefix.'ы', |
123
|
|
|
self::DAT_3 => $prefix.'е', |
124
|
|
|
self::VINIT_4 => $prefix.'у', |
125
|
|
|
self::TVORIT_5 => $prefix.'ей', |
126
|
|
|
self::PREDLOJ_6 => in_array(upper(slice($name, 0, 1)), self::$vowels) ? 'об '.$prefix.'е' : 'о '.$prefix.'е', |
127
|
|
|
); |
128
|
|
|
} |
129
|
|
|
} else if (slice($name, -1) == 'я' and slice($name, -2, -1) != 'и') { |
130
|
|
|
$prefix = name(slice($name, 0, -1)); |
131
|
|
|
return array( |
132
|
|
|
self::IMENIT_1 => $prefix.'я', |
133
|
|
|
self::RODIT_2 => $prefix.'и', |
134
|
|
|
self::DAT_3 => $prefix.'е', |
135
|
|
|
self::VINIT_4 => $prefix.'ю', |
136
|
|
|
self::TVORIT_5 => $prefix.'ей', |
137
|
|
|
self::PREDLOJ_6 => in_array(upper(slice($name, 0, 1)), self::$vowels) ? 'об '.$prefix.'е' : 'о '.$prefix.'е', |
138
|
|
|
); |
139
|
|
|
} else if (slice($name, -2) == 'ия') { |
140
|
|
|
$prefix = name(slice($name, 0, -1)); |
141
|
|
|
return array( |
142
|
|
|
self::IMENIT_1 => $prefix.'я', |
143
|
|
|
self::RODIT_2 => $prefix.'и', |
144
|
|
|
self::DAT_3 => $prefix.'и', |
145
|
|
|
self::VINIT_4 => $prefix.'ю', |
146
|
|
|
self::TVORIT_5 => $prefix.'ей', |
147
|
|
|
self::PREDLOJ_6 => in_array(upper(slice($name, 0, 1)), self::$vowels) ? 'об '.$prefix.'и' : 'о '.$prefix.'и', |
148
|
|
|
); |
149
|
|
|
} else if (slice($name, -1) == 'ь' && $this->isConsonant(slice($name, -2, -1))) { |
150
|
|
|
$prefix = name(slice($name, 0, -1)); |
151
|
|
|
return array( |
152
|
|
|
self::IMENIT_1 => $prefix.'ь', |
153
|
|
|
self::RODIT_2 => $prefix.'и', |
154
|
|
|
self::DAT_3 => $prefix.'и', |
155
|
|
|
self::VINIT_4 => $prefix.'ь', |
156
|
|
|
self::TVORIT_5 => $prefix.'ью', |
157
|
|
|
self::PREDLOJ_6 => in_array(upper(slice($name, 0, 1)), self::$vowels) ? 'об '.$prefix.'и' : 'о '.$prefix.'и', |
158
|
|
|
); |
159
|
|
|
} else if ($this->isHissingConsonant(slice($name, -1))) { |
160
|
|
|
$prefix = name($name); |
161
|
|
|
return array( |
162
|
|
|
self::IMENIT_1 => $prefix, |
163
|
|
|
self::RODIT_2 => $prefix.'и', |
164
|
|
|
self::DAT_3 => $prefix.'и', |
165
|
|
|
self::VINIT_4 => $prefix, |
166
|
|
|
self::TVORIT_5 => $prefix.'ью', |
167
|
|
|
self::PREDLOJ_6 => in_array(upper(slice($name, 0, 1)), self::$vowels) ? 'об '.$prefix.'и' : 'о '.$prefix.'и', |
168
|
|
|
); |
169
|
|
|
} else { |
170
|
|
|
return false; |
171
|
|
|
} |
172
|
|
|
} |
173
|
|
|
} |
174
|
|
|
|
175
|
|
View Code Duplication |
private function getFormsForLev() { |
|
|
|
|
176
|
|
|
return array( |
177
|
|
|
self::IMENIT_1 => 'Лев', |
178
|
|
|
self::RODIT_2 => 'Льва', |
179
|
|
|
self::DAT_3 => 'Льву', |
180
|
|
|
self::VINIT_4 => 'Льва', |
181
|
|
|
self::TVORIT_5 => 'Львом', |
182
|
|
|
self::PREDLOJ_6 => 'о Льве', |
183
|
|
|
); |
184
|
|
|
} |
185
|
|
|
|
186
|
|
View Code Duplication |
private function getFormsForPavel() { |
|
|
|
|
187
|
|
|
return array( |
188
|
|
|
self::IMENIT_1 => 'Павел', |
189
|
|
|
self::RODIT_2 => 'Павла', |
190
|
|
|
self::DAT_3 => 'Павлу', |
191
|
|
|
self::VINIT_4 => 'Павла', |
192
|
|
|
self::TVORIT_5 => 'Павлом', |
193
|
|
|
self::PREDLOJ_6 => 'о Павле', |
194
|
|
|
); |
195
|
|
|
} |
196
|
|
|
|
197
|
|
View Code Duplication |
public function getForm($name, $form, $gender) { |
|
|
|
|
198
|
|
|
$forms = $this->getForms($name, $gender); |
199
|
|
|
if ($forms !== false) |
200
|
|
|
if (isset($forms[$form])) |
201
|
|
|
return $forms[$form]; |
202
|
|
|
else |
203
|
|
|
return false; |
204
|
|
|
else |
205
|
|
|
return false; |
206
|
|
|
} |
207
|
|
|
} |
208
|
|
|
|
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.