Completed
Push — master ( 13fe0a...7029b0 )
by f
02:11
created

src/Russian/GeographicalNamesInflection.php (1 issue)

Upgrade to new PHP Analysis Engine

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\S;
5
6
/**
7
 * Rules are from: https://ru.wikipedia.org/wiki/%D0%A1%D0%BA%D0%BB%D0%BE%D0%BD%D0%B5%D0%BD%D0%B8%D0%B5_%D0%B3%D0%B5%D0%BE%D0%B3%D1%80%D0%B0%D1%84%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%B8%D1%85_%D0%BD%D0%B0%D0%B7%D0%B2%D0%B0%D0%BD%D0%B8%D0%B9_%D0%B2_%D1%80%D1%83%D1%81%D1%81%D0%BA%D0%BE%D0%BC_%D1%8F%D0%B7%D1%8B%D0%BA%D0%B5
8
 */
9
class GeographicalNamesInflection extends \morphos\BaseInflection implements Cases
10
{
11
    use RussianLanguage, CasesHelper;
12
13
    protected static $abbreviations = array(
14
        'сша',
15
        'оаэ',
16
        'ссср',
17
        'юар',
18
    );
19
20
    public static function isMutable($name)
21
    {
22
        $name = S::lower($name);
23
24
        // // ends with 'ы' or 'и': plural form
25
        // if (in_array(S::slice($name, -1), array('и', 'ы')))
26
        //     return false;
27
28
        if (in_array($name, self::$abbreviations)) {
29
            return false;
30
        }
31
32
        // N край
33
        if (S::slice($name, -5) == ' край') {
34
            return static::isMutable(S::slice($name, 0, -5));
35
        }
36
37
        // N область
38
        if (S::slice($name, -8) == ' область') {
39
            return true;
40
        }
41
42
        // город N
43
        if (S::slice($name, 0, 6) == 'город ') {
44
            return true;
45
        }
46
47
        // ends with 'е' or 'о', but not with 'ово/ёво/ево/ино/ыно'
48
        if (in_array(S::slice($name, -1), array('е', 'о')) && !in_array(S::slice($name, -3, -1), array('ов', 'ёв', 'ев', 'ин', 'ын'))) {
49
            return false;
50
        }
51
        return true;
52
    }
53
54
    public static function getCases($name)
55
    {
56
        $name = S::lower($name);
57
58
        // N край
59 View Code Duplication
        if (S::slice($name, -5) == ' край') {
60
            return self::composeCasesFromWords([static::getCases(S::slice($name, 0, -5)), NounDeclension::getCases('край')]);
61
        }
62
63
        // N область
64 View Code Duplication
        if (S::slice($name, -8) == ' область') {
65
            return self::composeCasesFromWords([static::getCases(S::slice($name, 0, -8)), NounDeclension::getCases('область')]);
66
        }
67
68
        // город N
69 View Code Duplication
        if (S::slice($name, 0, 6) == 'город ') {
70
            return self::composeCasesFromWords([
71
                NounDeclension::getCases('город'),
72
                array_fill_keys(self::getAllCases(), S::name(S::slice($name, -6)))
73
            ]);
74
        }
75
76
        // check for name of few words
77 View Code Duplication
        if (strpos($name, ' ') !== false) {
78
            $parts = explode(' ', $name);
79
            $cases = array();
0 ignored issues
show
$cases is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

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.

Loading history...
80
            $result = array();
81
            foreach ($parts as $i => $part) {
82
                $result[$i] = static::getCases($part);
83
            }
84
            return self::composeCasesFromWords($result);
85
        }
86
87
        if (!in_array($name, self::$abbreviations)) {
88
            if (S::slice($name, -2) == 'ий') {
89
                // Нижний, Русский
90
                $prefix = S::name(S::slice($name, 0, -2));
91
                return array(
92
                    self::IMENIT => $prefix.'ий',
93
                    self::RODIT => $prefix.(self::isVelarConsonant(S::slice($name, -3, -2)) ? 'ого' : 'его'),
94
                    self::DAT => $prefix.(self::isVelarConsonant(S::slice($name, -3, -2)) ? 'ому' : 'ему'),
95
                    self::VINIT => $prefix.'ий',
96
                    self::TVORIT => $prefix.'им',
97
                    self::PREDLOJ => $prefix.(self::chooseEndingBySonority($prefix, 'ем', 'ом')),
98
                );
99
            } else if (S::slice($name, -2) == 'ая') {
100
                // Ростовская
101
                $prefix = S::name(S::slice($name, 0, -2));
102
                return array(
103
                    self::IMENIT => $prefix.'ая',
104
                    self::RODIT => $prefix.'ой',
105
                    self::DAT => $prefix.'ой',
106
                    self::VINIT => $prefix.'ую',
107
                    self::TVORIT => $prefix.'ой',
108
                    self::PREDLOJ => $prefix.'ой',
109
                );
110
            } else if (S::slice($name, -2) == 'ый') {
111
                // Грозный, Благодарный
112
                $prefix = S::name(S::slice($name, 0, -2));
113
                return array(
114
                    self::IMENIT => $prefix.'ый',
115
                    self::RODIT => $prefix.'ого',
116
                    self::DAT => $prefix.'ому',
117
                    self::VINIT => $prefix.'ый',
118
                    self::TVORIT => $prefix.'ым',
119
                    self::PREDLOJ => $prefix.'ом',
120
                );
121
            } elseif (S::slice($name, -1) == 'а') {
122
                // Москва, Рига
123
                $prefix = S::name(S::slice($name, 0, -1));
124
                return array(
125
                    self::IMENIT => $prefix.'а',
126
                    self::RODIT => $prefix.(self::isVelarConsonant(S::slice($name, -2, -1)) ? 'и' : 'ы'),
127
                    self::DAT => $prefix.'е',
128
                    self::VINIT => $prefix.'у',
129
                    self::TVORIT => $prefix.'ой',
130
                    self::PREDLOJ => $prefix.'е',
131
                );
132
            } elseif (S::slice($name, -1) == 'я') {
133
                // Азия
134
                $prefix = S::name(S::slice($name, 0, -1));
135
                return array(
136
                    self::IMENIT => S::name($name),
137
                    self::RODIT => $prefix.'и',
138
                    self::DAT => $prefix.'и',
139
                    self::VINIT => $prefix.'ю',
140
                    self::TVORIT => $prefix.'ей',
141
                    self::PREDLOJ => $prefix.'и',
142
                );
143
            } elseif (S::slice($name, -1) == 'й') {
144
                // Ишимбай
145
                $prefix = S::name(S::slice($name, 0, -1));
146
                return array(
147
                    self::IMENIT => $prefix.'й',
148
                    self::RODIT => $prefix.'я',
149
                    self::DAT => $prefix.'ю',
150
                    self::VINIT => $prefix.'й',
151
                    self::TVORIT => $prefix.'ем',
152
                    self::PREDLOJ => $prefix.'е',
153
                );
154 View Code Duplication
            } elseif (self::isConsonant(S::slice($name, -1)) && S::slice($name, -2) != 'ов') {
155
                // Париж, Валаам, Киев
156
                $prefix = S::name($name);
157
                return array(
158
                    self::IMENIT => $prefix,
159
                    self::RODIT => $prefix.'а',
160
                    self::DAT => $prefix.'у',
161
                    self::VINIT => $prefix,
162
                    self::TVORIT => $prefix.(self::isVelarConsonant(S::slice($name, -2, -1)) ? 'ем' : 'ом'),
163
                    self::PREDLOJ => $prefix.'е',
164
                );
165
            } elseif (S::slice($name, -2) == 'ль') {
166
                // Ставрополь, Ярославль
167
                $prefix = S::name(S::slice($name, 0, -1));
168
                return array(
169
                    self::IMENIT => $prefix.'ь',
170
                    self::RODIT => $prefix.'я',
171
                    self::DAT => $prefix.'ю',
172
                    self::VINIT => $prefix.'ь',
173
                    self::TVORIT => $prefix.'ем',
174
                    self::PREDLOJ => $prefix.'е',
175
                );
176
            } elseif (S::slice($name, -2) == 'рь') {
177
                // Тверь
178
                $prefix = S::name(S::slice($name, 0, -1));
179
                return array(
180
                    self::IMENIT => $prefix.'ь',
181
                    self::RODIT => $prefix.'и',
182
                    self::DAT => $prefix.'и',
183
                    self::VINIT => $prefix.'ь',
184
                    self::TVORIT => $prefix.'ью',
185
                    self::PREDLOJ => $prefix.'и',
186
                );
187
            } elseif (S::slice($name, -2) == 'ки') {
188
                // Березники, Ессентуки
189
                $prefix = S::name(S::slice($name, 0, -1));
190
                return array(
191
                    self::IMENIT => $prefix.'и',
192
                    self::RODIT => $prefix.'ов',
193
                    self::DAT => $prefix.'ам',
194
                    self::VINIT => $prefix.'и',
195
                    self::TVORIT => $prefix.'ами',
196
                    self::PREDLOJ => $prefix.'ах',
197
                );
198
            } elseif (S::slice($name, -2) == 'мь') {
199
                // Пермь, Кемь
200
                $prefix = S::name(S::slice($name, 0, -1));
201
                return array(
202
                    self::IMENIT => $prefix.'ь',
203
                    self::RODIT => $prefix.'и',
204
                    self::DAT => $prefix.'и',
205
                    self::VINIT => $prefix.'ь',
206
                    self::TVORIT => $prefix.'ью',
207
                    self::PREDLOJ => $prefix.'и',
208
                );
209
            } elseif (S::slice($name, -2) == 'нь') {
210
                // Рязань, Назрань
211
                $prefix = S::name(S::slice($name, 0, -1));
212
                return array(
213
                    self::IMENIT => $prefix.'ь',
214
                    self::RODIT => $prefix.'и',
215
                    self::DAT => $prefix.'и',
216
                    self::VINIT => $prefix.'ь',
217
                    self::TVORIT => $prefix.'ью',
218
                    self::PREDLOJ => $prefix.'и',
219
                );
220 View Code Duplication
            } else if (S::slice($name, -2) == 'ые') {
221
                // Набережные
222
                $prefix = S::name(S::slice($name, 0, -1));
223
                return array(
224
                    self::IMENIT => $prefix.'е',
225
                    self::RODIT => $prefix.'х',
226
                    self::DAT => $prefix.'м',
227
                    self::VINIT => $prefix.'е',
228
                    self::TVORIT => $prefix.'ми',
229
                    self::PREDLOJ => $prefix.'х',
230
                );
231
            } else if (S::slice($name, -2) == 'ны') {
232
                // Челны
233
                $prefix = S::name(S::slice($name, 0, -1));
234
                return array(
235
                    self::IMENIT => $prefix.'ы',
236
                    self::RODIT => $prefix.'ов',
237
                    self::DAT => $prefix.'ам',
238
                    self::VINIT => $prefix.'ы',
239
                    self::TVORIT => $prefix.'ами',
240
                    self::PREDLOJ => $prefix.'ах',
241
                );
242
            }
243
244
            $suffixes = array('ов', 'ёв', 'ев', 'ин', 'ын');
245
            if ((in_array(S::slice($name, -1), array('е', 'о')) && in_array(S::slice($name, -3, -1), $suffixes)) || in_array(S::slice($name, -2), $suffixes)) {
246
                // ово, ёво, ...
247
                if (in_array(S::slice($name, -3, -1), $suffixes)) {
248
                    $prefix = S::name(S::slice($name, 0, -1));
249
                }
250
                // ов, её, ...
251
                elseif (in_array(S::slice($name, -2), $suffixes)) {
252
                    $prefix = S::name($name);
253
                }
254
                return array(
255
                    self::IMENIT => S::name($name),
256
                    self::RODIT => $prefix.'а',
257
                    self::DAT => $prefix.'у',
258
                    self::VINIT => S::name($name),
259
                    self::TVORIT => $prefix.'ым',
260
                    self::PREDLOJ => $prefix.'е',
261
                );
262
            }
263
        }
264
265
        // if no rules matches or name is immutable
266
        $name = in_array($name, self::$abbreviations) ? S::upper($name) : S::name($name);
267
        return array_fill_keys(array(self::IMENIT, self::RODIT, self::DAT, self::VINIT, self::TVORIT, self::PREDLOJ), $name);
268
    }
269
270
    public static function getCase($name, $case)
271
    {
272
        $case = self::canonizeCase($case);
273
        $forms = self::getCases($name);
274
        return $forms[$case];
275
    }
276
}
277