This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
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\BaseInflection; |
||
5 | use morphos\Gender; |
||
6 | use morphos\S; |
||
7 | use RuntimeException; |
||
8 | |||
9 | /** |
||
10 | * Class AdjectiveDeclension. |
||
11 | * |
||
12 | * Склонение прилагательных. |
||
13 | * |
||
14 | * Правила склонения: |
||
15 | * - http://www.fio.ru/pravila/grammatika/sklonenie-prilagatelnykh-v-russkom-yazyke/ |
||
16 | * |
||
17 | * @package morphos\Russian |
||
18 | */ |
||
19 | class AdjectiveDeclension extends BaseInflection implements Cases, Gender |
||
20 | { |
||
21 | use RussianLanguage, CasesHelper; |
||
22 | |||
23 | const HARD_BASE = 1; |
||
24 | const SOFT_BASE = 2; |
||
25 | const MIXED_BASE = 3; |
||
26 | |||
27 | /** |
||
28 | * @param string $adjective |
||
29 | * @return bool|void |
||
30 | */ |
||
31 | public static function isMutable($adjective) |
||
32 | { |
||
33 | return false; |
||
34 | } |
||
35 | |||
36 | /** |
||
37 | * @param string $adjective |
||
38 | * @param string $case |
||
39 | * @param bool $animateness |
||
40 | * @param null $gender |
||
41 | * |
||
42 | * @return string |
||
43 | * @throws \Exception |
||
44 | */ |
||
45 | public static function getCase($adjective, $case, $animateness = false, $gender = null) |
||
46 | { |
||
47 | $case = static::canonizeCase($case); |
||
48 | |||
49 | if ($gender === null) |
||
50 | $gender = static::detectGender($adjective); |
||
51 | |||
52 | $forms = static::getCases($adjective, $animateness, $gender); |
||
53 | return $forms[$case]; |
||
54 | } |
||
55 | |||
56 | /** |
||
57 | * @param string $adjective |
||
58 | * |
||
59 | * @param bool $isEmphasized |
||
60 | * |
||
61 | * @return string |
||
62 | */ |
||
63 | 24 | public static function detectGender($adjective, &$isEmphasized = false) |
|
64 | { |
||
65 | 24 | switch (S::lower(S::slice($adjective, -2))) |
|
66 | { |
||
67 | 24 | case 'ой': |
|
68 | 4 | $isEmphasized = true; |
|
69 | 20 | case 'ый': |
|
70 | 19 | case 'ий': |
|
71 | 8 | return static::MALE; |
|
72 | |||
73 | 16 | case 'ая': |
|
74 | 10 | case 'яя': |
|
75 | 8 | return static::FEMALE; |
|
76 | |||
77 | 8 | case 'ое': |
|
78 | 2 | case 'ее': |
|
79 | 8 | return static::NEUTER; |
|
80 | } |
||
81 | |||
82 | throw new RuntimeException('Unreachable'); |
||
83 | } |
||
84 | |||
85 | /** |
||
86 | * @param string $adjective |
||
87 | * @param bool $animateness |
||
88 | * @param null|string $gender |
||
89 | * |
||
90 | * @return string[] |
||
91 | * @phpstan-return array<string, string> |
||
92 | */ |
||
93 | 18 | public static function getCases($adjective, $animateness = false, $gender = null) |
|
94 | { |
||
95 | 18 | if ($gender === null) |
|
96 | 18 | $gender = static::detectGender($adjective, $isEmphasized); |
|
97 | |||
98 | 18 | $last_consonant_vowel = S::slice($adjective, -2, -1); |
|
99 | 18 | $type = static::getAdjectiveBaseType($adjective); |
|
100 | 18 | $adjective = S::slice($adjective, 0, -2); |
|
101 | |||
102 | switch ($type) |
||
103 | { |
||
104 | 18 | case static::HARD_BASE: |
|
105 | 6 | return static::declinateHardAdjective($adjective, $animateness, $gender, |
|
106 | 6 | $last_consonant_vowel); |
|
107 | |||
108 | 12 | case static::SOFT_BASE: |
|
109 | 3 | return static::declinateSoftAdjective($adjective, $animateness, $gender, |
|
110 | 3 | $last_consonant_vowel); |
|
111 | |||
112 | 9 | case static::MIXED_BASE: |
|
113 | 9 | return static::declinateMixedAdjective($adjective, $animateness, $gender, |
|
114 | 9 | $last_consonant_vowel); |
|
115 | } |
||
116 | |||
117 | throw new RuntimeException('Unreachable'); |
||
118 | } |
||
119 | |||
120 | /** |
||
121 | * @param string $adjective |
||
122 | * |
||
123 | * @return int |
||
124 | */ |
||
125 | 25 | public static function getAdjectiveBaseType($adjective) |
|
126 | { |
||
127 | 25 | $adjective = S::lower($adjective); |
|
128 | 25 | $consonants = static::$consonants; |
|
129 | |||
130 | 25 | unset($consonants[array_search('н', $consonants)]); |
|
131 | 25 | unset($consonants[array_search('й', $consonants)]); |
|
132 | |||
133 | 25 | $substring = S::findLastPositionForOneOfChars($adjective, $consonants); |
|
134 | 25 | $last_consonant = S::slice($substring, 0, 1); |
|
135 | |||
136 | // г, к, х, ударное ш - признак смешанного прилагательно |
||
137 | 25 | if (in_array($last_consonant, ['г', 'к', 'х'], true) || |
|
138 | ( |
||
139 | 25 | $last_consonant === 'ш' && in_array(S::slice($substring, 1, 2), ['о', 'а'], true) |
|
140 | )) { |
||
141 | 12 | return static::MIXED_BASE; |
|
142 | } |
||
143 | |||
144 | 13 | return static::checkBaseLastConsonantSoftness($substring) |
|
145 | 13 | || (S::slice($substring, 0, 2) === 'шн') |
|
146 | 4 | ? static::SOFT_BASE |
|
147 | 13 | : static::HARD_BASE; |
|
148 | } |
||
149 | |||
150 | /** |
||
151 | * @param string $adjective |
||
152 | * @param bool $animateness |
||
153 | * @param string $gender |
||
154 | * @param string $afterConsonantVowel |
||
155 | * |
||
156 | * @return string[] |
||
157 | * @phpstan-return array<string, string> |
||
158 | */ |
||
159 | 6 | View Code Duplication | protected static function declinateHardAdjective($adjective, $animateness, $gender, |
0 ignored issues
–
show
|
|||
160 | $afterConsonantVowel) |
||
161 | { |
||
162 | switch ($gender) |
||
163 | { |
||
164 | 6 | case static::MALE: |
|
165 | 2 | $postfix = $afterConsonantVowel.'й'; |
|
166 | 2 | break; |
|
167 | |||
168 | 4 | case static::FEMALE: |
|
169 | 2 | $postfix = $afterConsonantVowel.'я'; |
|
170 | 2 | break; |
|
171 | |||
172 | 2 | case static::NEUTER: |
|
173 | 2 | $postfix = $afterConsonantVowel.'е'; |
|
174 | 2 | break; |
|
175 | |||
176 | default: throw new RuntimeException('Unreachable'); |
||
177 | } |
||
178 | |||
179 | $cases = [ |
||
180 | 6 | static::IMENIT => $adjective.$postfix, |
|
181 | 6 | static::RODIT => $adjective.'о'.($gender !== static::FEMALE ? 'го' : 'й'), |
|
182 | 6 | static::DAT => $adjective.'о'.($gender !== static::FEMALE ? 'му' : 'й'), |
|
183 | ]; |
||
184 | |||
185 | 6 | if ($gender !== static::FEMALE) |
|
186 | 4 | $cases[static::VINIT] = static::getVinitCaseByAnimateness($cases, $animateness); |
|
187 | else |
||
188 | 2 | $cases[static::VINIT] = $adjective.'ую'; |
|
189 | |||
190 | 6 | $cases[static::TVORIT] = $adjective.($gender !== static::FEMALE ? 'ым' : 'ой'); |
|
191 | 6 | $cases[static::PREDLOJ] = $adjective.($gender !== static::FEMALE ? 'ом' : 'ой'); |
|
192 | |||
193 | 6 | return $cases; |
|
194 | } |
||
195 | |||
196 | /** |
||
197 | * @param string $adjective |
||
198 | * @param bool $animateness |
||
199 | * @param string $gender |
||
200 | * @param string $afterConsonantVowel |
||
201 | * |
||
202 | * @return string[] |
||
203 | * @phpstan-return array<string, string> |
||
204 | */ |
||
205 | 3 | View Code Duplication | protected static function declinateSoftAdjective($adjective, $animateness, $gender, $afterConsonantVowel) |
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...
|
|||
206 | { |
||
207 | switch ($gender) |
||
208 | { |
||
209 | 3 | case static::MALE: |
|
210 | 1 | $postfix = $afterConsonantVowel.'й'; |
|
211 | 1 | break; |
|
212 | |||
213 | 2 | case static::FEMALE: |
|
214 | 1 | $postfix = $afterConsonantVowel.'я'; |
|
215 | 1 | break; |
|
216 | |||
217 | 1 | case static::NEUTER: |
|
218 | 1 | $postfix = $afterConsonantVowel.'е'; |
|
219 | 1 | break; |
|
220 | |||
221 | default: throw new RuntimeException('Unreachable'); |
||
222 | } |
||
223 | |||
224 | $cases = [ |
||
225 | 3 | static::IMENIT => $adjective.$postfix, |
|
226 | 3 | static::RODIT => $adjective.'е'.($gender !== static::FEMALE ? 'го' : 'й'), |
|
227 | 3 | static::DAT => $adjective.'е'.($gender !== static::FEMALE ? 'му' : 'й'), |
|
228 | ]; |
||
229 | |||
230 | 3 | if ($gender !== static::FEMALE) |
|
231 | 2 | $cases[static::VINIT] = static::getVinitCaseByAnimateness($cases, $animateness); |
|
232 | else |
||
233 | 1 | $cases[static::VINIT] = $adjective.'юю'; |
|
234 | |||
235 | 3 | $cases[static::TVORIT] = $adjective.($gender !== static::FEMALE ? 'им' : 'ей'); |
|
236 | 3 | $cases[static::PREDLOJ] = $adjective.($gender !== static::FEMALE ? 'ем' : 'ей'); |
|
237 | |||
238 | 3 | return $cases; |
|
239 | } |
||
240 | |||
241 | /** |
||
242 | * @param string $adjective |
||
243 | * @param bool $animateness |
||
244 | * @param string $gender |
||
245 | * @param string $afterConsonantVowel |
||
246 | * |
||
247 | * @return string[] |
||
248 | * @phpstan-return array<string, string> |
||
249 | */ |
||
250 | 9 | protected static function declinateMixedAdjective($adjective, $animateness, $gender, $afterConsonantVowel) |
|
251 | { |
||
252 | switch ($gender) |
||
253 | { |
||
254 | 9 | case static::MALE: |
|
255 | 3 | $postfix = $afterConsonantVowel.'й'; |
|
256 | 3 | break; |
|
257 | |||
258 | 6 | case static::FEMALE: |
|
259 | 3 | $postfix = $afterConsonantVowel.'я'; |
|
260 | 3 | break; |
|
261 | |||
262 | 3 | case static::NEUTER: |
|
263 | 3 | $postfix = $afterConsonantVowel.'е'; |
|
264 | 3 | break; |
|
265 | |||
266 | default: throw new RuntimeException('Unreachable'); |
||
267 | } |
||
268 | |||
269 | $cases = [ |
||
270 | 9 | static::IMENIT => $adjective.$postfix, |
|
271 | 9 | static::RODIT => $adjective.'о'.($gender !== static::FEMALE ? 'го' : 'й'), |
|
272 | 9 | static::DAT => $adjective.'о'.($gender !== static::FEMALE ? 'му' : 'й'), |
|
273 | ]; |
||
274 | |||
275 | 9 | if ($gender === static::MALE) |
|
276 | 3 | $cases[static::VINIT] = static::getVinitCaseByAnimateness($cases, $animateness); |
|
277 | 6 | else if ($gender === static::NEUTER) |
|
278 | 3 | $cases[static::VINIT] = $adjective.'ое'; |
|
279 | else |
||
280 | 3 | $cases[static::VINIT] = $adjective.'ую'; |
|
281 | |||
282 | 9 | $cases[static::TVORIT] = $adjective.($gender !== static::FEMALE ? 'им' : 'ой'); |
|
283 | 9 | $cases[static::PREDLOJ] = $adjective.($gender !== static::FEMALE ? 'ом' : 'ой'); |
|
284 | |||
285 | 9 | return $cases; |
|
286 | } |
||
287 | } |
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.