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\NumeralGenerator; |
||
5 | use morphos\S; |
||
6 | |||
7 | /** |
||
8 | * Rules are from http://www.fio.ru/pravila/grammatika/sklonenie-imen-chislitelnykh/ |
||
9 | * and http://school-collection.edu.ru/dlrstore-wrapper/ebbc76cf-46b6-4d51-ad92-d9a84db35cfa/[I-RUS_06-05]_[TE_16-SU]/[I-RUS_06-05]_[TE_16-SU].html |
||
10 | */ |
||
11 | class OrdinalNumeralGenerator extends NumeralGenerator implements Cases |
||
12 | { |
||
13 | use RussianLanguage, CasesHelper; |
||
14 | |||
15 | protected static $words = array( |
||
16 | 1 => 'первый', |
||
17 | 2 => 'второй', |
||
18 | 3 => 'третий', |
||
19 | 4 => 'четвертый', |
||
20 | 5 => 'пятый', |
||
21 | 6 => 'шестой', |
||
22 | 7 => 'седьмой', |
||
23 | 8 => 'восьмой', |
||
24 | 9 => 'девятый', |
||
25 | 10 => 'десятый', |
||
26 | 11 => 'одиннадцатый', |
||
27 | 12 => 'двенадцатый', |
||
28 | 13 => 'тринадцатый', |
||
29 | 14 => 'четырнадцатый', |
||
30 | 15 => 'пятнадцатый', |
||
31 | 16 => 'шестнадцатый', |
||
32 | 17 => 'семнадцатый', |
||
33 | 18 => 'восемнадцатый', |
||
34 | 19 => 'девятнадцатый', |
||
35 | 20 => 'двадцатый', |
||
36 | 30 => 'тридцатый', |
||
37 | 40 => 'сороковой', |
||
38 | 50 => 'пятьдесятый', |
||
39 | 60 => 'шестьдесятый', |
||
40 | 70 => 'семьдесятый', |
||
41 | 80 => 'восемьдесятый', |
||
42 | 90 => 'девяностый', |
||
43 | 100 => 'сотый', |
||
44 | 200 => 'двухсотый', |
||
45 | 300 => 'трехсотый', |
||
46 | 400 => 'четырехсотый', |
||
47 | 500 => 'пятисотый', |
||
48 | 600 => 'шестисотый', |
||
49 | 700 => 'семисотый', |
||
50 | 800 => 'восемисотый', |
||
51 | 900 => 'девятисотый', |
||
52 | ); |
||
53 | |||
54 | protected static $exponents = array( |
||
55 | 1000 => 'тысячный', |
||
56 | 1000000 => 'миллионный', |
||
57 | 1000000000 => 'миллиардный', |
||
58 | 1000000000000 => 'триллионный', |
||
59 | ); |
||
60 | |||
61 | protected static $multipliers = array( |
||
62 | 2 => 'двух', |
||
63 | 3 => 'трех', |
||
64 | 4 => 'четырех', |
||
65 | 5 => 'пяти', |
||
66 | 6 => 'шести', |
||
67 | 7 => 'седьми', |
||
68 | 8 => 'восьми', |
||
69 | 9 => 'девяти', |
||
70 | 10 => 'десяти', |
||
71 | 11 => 'одиннадцати', |
||
72 | 12 => 'двенадцати', |
||
73 | 13 => 'тринадцати', |
||
74 | 14 => 'четырнадцати', |
||
75 | 15 => 'пятнадцати', |
||
76 | 16 => 'шестнадцати', |
||
77 | 17 => 'семнадцати', |
||
78 | 18 => 'восемнадцати', |
||
79 | 19 => 'девятнадцати', |
||
80 | 20 => 'двадцати', |
||
81 | 30 => 'тридцати', |
||
82 | 40 => 'сорока', |
||
83 | 50 => 'пятьдесяти', |
||
84 | 60 => 'шестьдесяти', |
||
85 | 70 => 'семьдесяти', |
||
86 | 80 => 'восемьдесяти', |
||
87 | 90 => 'девяности', |
||
88 | 100 => 'сто', |
||
89 | 200 => 'двухста', |
||
90 | 300 => 'трехста', |
||
91 | 400 => 'четырехста', |
||
92 | 500 => 'пятиста', |
||
93 | 600 => 'шестиста', |
||
94 | 700 => 'семиста', |
||
95 | 800 => 'восемиста', |
||
96 | 900 => 'девятиста', |
||
97 | ); |
||
98 | |||
99 | public static function getCases($number, $gender = self::MALE) |
||
100 | { |
||
101 | // simple numeral |
||
102 | if (isset(self::$words[$number]) || isset(self::$exponents[$number])) { |
||
103 | $word = isset(self::$words[$number]) ? self::$words[$number] : self::$exponents[$number]; |
||
104 | // special rules for 3 |
||
105 | if ($number == 3) { |
||
106 | $prefix = S::slice($word, 0, -2); |
||
107 | return array( |
||
108 | self::IMENIT => $prefix.($gender == self::MALE ? 'ий' : ($gender == self::FEMALE ? 'ья' : 'ье')), |
||
109 | self::RODIT => $prefix.($gender == self::FEMALE ? 'ьей' : 'ьего'), |
||
110 | self::DAT => $prefix.($gender == self::FEMALE ? 'ьей' : 'ьему'), |
||
111 | self::VINIT => $prefix.($gender == self::FEMALE ? 'ью' : 'ьего'), |
||
112 | self::TVORIT => $prefix.($gender == self::FEMALE ? 'ьей' : 'ьим'), |
||
113 | self::PREDLOJ => self::choosePrepositionByFirstLetter($prefix, 'об', 'о').' '.$prefix.($gender == self::FEMALE ? 'ьей' : 'ьем'), |
||
114 | ); |
||
115 | } else { |
||
116 | switch ($gender) { |
||
117 | View Code Duplication | case self::MALE: |
|
118 | $prefix = S::slice($word, 0, $number == 40 ? -1 : -2); |
||
119 | return array( |
||
120 | self::IMENIT => $word, |
||
121 | self::RODIT => $prefix.'ого', |
||
122 | self::DAT => $prefix.'ому', |
||
123 | self::VINIT => $word, |
||
124 | self::TVORIT => $prefix.'ым', |
||
125 | self::PREDLOJ => self::choosePrepositionByFirstLetter($prefix, 'об', 'о').' '.$prefix.'ом', |
||
126 | ); |
||
127 | |||
128 | View Code Duplication | case self::FEMALE: |
|
129 | $prefix = S::slice($word, 0, $number == 40 ? -1 : -2); |
||
130 | return array( |
||
131 | self::IMENIT => $prefix.'ая', |
||
132 | self::RODIT => $prefix.'ой', |
||
133 | self::DAT => $prefix.'ой', |
||
134 | self::VINIT => $prefix.'ую', |
||
135 | self::TVORIT => $prefix.'ой', |
||
136 | self::PREDLOJ => self::choosePrepositionByFirstLetter($prefix, 'об', 'о').' '.$prefix.'ой', |
||
137 | ); |
||
138 | |||
139 | View Code Duplication | case self::NEUTER: |
|
140 | $prefix = S::slice($word, 0, $number == 40 ? -1 : -2); |
||
141 | return array( |
||
142 | self::IMENIT => $prefix.'ое', |
||
143 | self::RODIT => $prefix.'ого', |
||
144 | self::DAT => $prefix.'ому', |
||
145 | self::VINIT => $prefix.'ое', |
||
146 | self::TVORIT => $prefix.'ым', |
||
147 | self::PREDLOJ => self::choosePrepositionByFirstLetter($prefix, 'об', 'о').' '.$prefix.'ом', |
||
148 | ); |
||
149 | } |
||
150 | } |
||
151 | } |
||
152 | // compound numeral |
||
153 | else { |
||
154 | $ordinal_part = null; |
||
155 | $ordinal_prefix = null; |
||
156 | $cardinal_part = array(); |
||
0 ignored issues
–
show
|
|||
157 | $result = array(); |
||
158 | |||
159 | // test for exponents. If smaller summand of number is an exponent, declinate it |
||
160 | foreach (array_reverse(self::$exponents, true) as $word_number => $word) { |
||
161 | if ($number >= $word_number && ($number % $word_number) == 0) { |
||
162 | $count = floor($number / $word_number) % 1000; |
||
163 | $number -= ($count * $word_number); |
||
164 | foreach (array_reverse(self::$multipliers, true) as $multiplier => $multipliers_word) { |
||
165 | if ($count >= $multiplier) { |
||
166 | $ordinal_prefix .= $multipliers_word; |
||
167 | $count -= $multiplier; |
||
168 | } |
||
169 | } |
||
170 | $ordinal_part = self::getCases($word_number, $gender); |
||
171 | foreach ($ordinal_part as $case => $ordinal_word) { |
||
172 | View Code Duplication | if ($case == self::PREDLOJ) { |
|
173 | list(, $ordinal_part[$case]) = explode(' ', $ordinal_part[$case]); |
||
174 | $ordinal_part[$case] = self::choosePrepositionByFirstLetter($ordinal_prefix, 'об', 'о').' '.$ordinal_prefix.$ordinal_part[$case]; |
||
175 | } else { |
||
176 | $ordinal_part[$case] = $ordinal_prefix.$ordinal_part[$case]; |
||
177 | } |
||
178 | } |
||
179 | |||
180 | break; |
||
181 | } |
||
182 | } |
||
183 | |||
184 | // otherwise, test if smaller summand is just a number with it's own name |
||
185 | if (empty($ordinal_part)) { |
||
186 | // get the smallest number with it's own name |
||
187 | foreach (self::$words as $word_number => $word) { |
||
188 | if ($number >= $word_number) { |
||
189 | if ($word_number <= 9) { |
||
190 | if ($number % 10 == 0) { |
||
191 | continue; |
||
192 | } |
||
193 | // check for case when word_number smaller than should be used (e.g. 1,2,3 when it can be 4 (number: 344)) |
||
194 | if (($number % 10) > $word_number) { |
||
195 | continue; |
||
196 | } |
||
197 | // check that there is no two-digits number with it's own name (e.g. 13 for 113) |
||
198 | if (isset(self::$words[$number % 100]) && $number % 100 > $word_number) { |
||
199 | continue; |
||
200 | } |
||
201 | } elseif ($word_number <= 90) { |
||
202 | // check for case when word_number smaller than should be used (e.g. 10, 11, 12 when it can be 13) |
||
203 | if (($number % 100) > $word_number) { |
||
204 | continue; |
||
205 | } |
||
206 | } |
||
207 | $ordinal_part = self::getCases($word_number, $gender); |
||
208 | $number -= $word_number; |
||
209 | break; |
||
210 | } |
||
211 | } |
||
212 | } |
||
213 | |||
214 | // if number has second summand, get cardinal form of it |
||
215 | if ($number > 0) { |
||
216 | $cardinal_part = CardinalNumeralGenerator::getCase($number, self::IMENIT, $gender); |
||
217 | |||
218 | // make one array with cases and delete 'o/об' prepositional from all parts except the last one |
||
219 | foreach (array(self::IMENIT, self::RODIT, self::DAT, self::VINIT, self::TVORIT, self::PREDLOJ) as $case) { |
||
220 | View Code Duplication | if ($case == self::PREDLOJ) { |
|
221 | list(, $ordinal_part[$case]) = explode(' ', $ordinal_part[$case]); |
||
222 | $result[$case] = self::choosePrepositionByFirstLetter($cardinal_part, 'об', 'о').' '.$cardinal_part.' '.$ordinal_part[$case]; |
||
223 | } else { |
||
224 | $result[$case] = $cardinal_part.' '.$ordinal_part[$case]; |
||
225 | } |
||
226 | } |
||
227 | } else { |
||
228 | $result = $ordinal_part; |
||
229 | } |
||
230 | |||
231 | return $result; |
||
232 | } |
||
233 | } |
||
234 | |||
235 | public static function getCase($number, $case, $gender = self::MALE) |
||
236 | { |
||
237 | $case = self::canonizeCase($case); |
||
238 | $forms = self::getCases($number, $gender); |
||
239 | return $forms[$case]; |
||
240 | } |
||
241 | } |
||
242 |
This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.
Both the
$myVar
assignment in line 1 and the$higher
assignment in line 2 are dead. The first because$myVar
is never used and the second because$higher
is always overwritten for every possible time line.