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); |
|
0 ignored issues
–
show
|
|||
135 | |||
136 | // г, к, х, ударное ш - признак смешанного прилагательно |
||
137 | 25 | if (in_array($last_consonant, ['г', 'к', 'х'], true) || |
|
138 | ( |
||
139 | 25 | $last_consonant === 'ш' && in_array(S::slice($substring, 1, 2), ['о', 'а'], true) |
|
0 ignored issues
–
show
It seems like
$substring defined by \morphos\S::findLastPosi...adjective, $consonants) on line 133 can also be of type false ; however, morphos\S::slice() does only seem to accept string , did you maybe forget to handle an error condition?
This check looks for type mismatches where the missing type is Consider the follow example <?php
function getDate($date)
{
if ($date !== null) {
return new DateTime($date);
}
return false;
}
This function either returns a new
Loading history...
|
|||
140 | )) { |
||
141 | 12 | return static::MIXED_BASE; |
|
142 | } |
||
143 | |||
144 | 13 | return static::checkBaseLastConsonantSoftness($substring) |
|
0 ignored issues
–
show
It seems like
$substring defined by \morphos\S::findLastPosi...adjective, $consonants) on line 133 can also be of type false ; however, morphos\Russian\RussianL...LastConsonantSoftness() does only seem to accept string , did you maybe forget to handle an error condition?
This check looks for type mismatches where the missing type is Consider the follow example <?php
function getDate($date)
{
if ($date !== null) {
return new DateTime($date);
}
return false;
}
This function either returns a new
Loading history...
|
|||
145 | 13 | || (S::slice($substring, 0, 2) === 'шн') |
|
0 ignored issues
–
show
It seems like
$substring defined by \morphos\S::findLastPosi...adjective, $consonants) on line 133 can also be of type false ; however, morphos\S::slice() does only seem to accept string , did you maybe forget to handle an error condition?
This check looks for type mismatches where the missing type is Consider the follow example <?php
function getDate($date)
{
if ($date !== null) {
return new DateTime($date);
}
return false;
}
This function either returns a new
Loading history...
|
|||
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
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...
|
|||
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 | } |
This check looks for type mismatches where the missing type is
false
. This is usually indicative of an error condtion.Consider the follow example
This function either returns a new
DateTime
object or false, if there was an error. This is a typical pattern in PHP programming to show that an error has occurred without raising an exception. The calling code should check for this returnedfalse
before passing on the value to another function or method that may not be able to handle afalse
.