Completed
Push — master ( 708613...9f9161 )
by f
01:19
created

GeographicalNamesInflection::getCases()   D

Complexity

Conditions 28
Paths 31

Size

Total Lines 164
Code Lines 122

Duplication

Lines 12
Ratio 7.32 %

Importance

Changes 0
Metric Value
cc 28
eloc 122
nc 31
nop 1
dl 12
loc 164
rs 4.4803
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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
        // // ends with 'ы' or 'и': plural form
24
        // if (in_array(S::slice($name, -1), array('и', 'ы')))
25
        //     return false;
26
        if (in_array($name, self::$abbreviations)) {
27
            return false;
28
        }
29
        // ends with 'е' or 'о', but not with 'ово/ёво/ево/ино/ыно'
30
        if (in_array(S::slice($name, -1), array('е', 'о')) && !in_array(S::slice($name, -3, -1), array('ов', 'ёв', 'ев', 'ин', 'ын'))) {
31
            return false;
32
        }
33
        return true;
34
    }
35
36
    public static function getCases($name)
37
    {
38
        $name = S::lower($name);
39
40
        // check for name of two words
41
        if (strpos($name, ' ') !== false) {
42
            $parts = explode(' ', $name);
43
            $cases = array();
0 ignored issues
show
Unused Code introduced by
$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...
44
            $result = array();
45
            foreach ($parts as $i => $part) {
46
                $result[$i] = static::getCases($part);
47
                if ($i > 0) {
48
                    $result[$i][self::PREDLOJ] = substr(strstr($result[$i][self::PREDLOJ], ' '), 1);
49
                }
50
            }
51
52
            $cases = array();
53
            foreach (array(self::IMENIT, self::RODIT, self::DAT, self::VINIT, self::TVORIT, self::PREDLOJ) as $case) {
54
                foreach ($parts as $i => $part) {
55
                    $cases[$case][] = $result[$i][$case];
56
                }
57
                $cases[$case] = implode(' ', $cases[$case]);
58
            }
59
            return $cases;
60
        }
61
62
        if (!in_array($name, self::$abbreviations)) {
63
            if (S::slice($name, -2) == 'ий') {
64
                // Нижний, Русский
65
                $prefix = S::name(S::slice($name, 0, -2));
66
                return array(
67
                    self::IMENIT => $prefix.'ий',
68
                    self::RODIT => $prefix.(self::isVelarConsonant(S::slice($name, -3, -2)) ? 'ого' : 'его'),
69
                    self::DAT => $prefix.(self::isVelarConsonant(S::slice($name, -3, -2)) ? 'ому' : 'ему'),
70
                    self::VINIT => $prefix.'ий',
71
                    self::TVORIT => $prefix.'им',
72
                    self::PREDLOJ => self::choosePrepositionByFirstLetter($prefix, 'об', 'о').' '.$prefix.'ем',
73
                );
74
            } elseif (S::slice($name, -1) == 'а') {
75
                // Москва, Рига
76
                $prefix = S::name(S::slice($name, 0, -1));
77
                return array(
78
                    self::IMENIT => $prefix.'а',
79
                    self::RODIT => $prefix.(self::isVelarConsonant(S::slice($name, -2, -1)) ? 'и' : 'ы'),
80
                    self::DAT => $prefix.'е',
81
                    self::VINIT => $prefix.'у',
82
                    self::TVORIT => $prefix.'ой',
83
                    self::PREDLOJ => self::choosePrepositionByFirstLetter($prefix, 'об', 'о').' '.$prefix.'е',
84
                );
85
            } elseif (S::slice($name, -1) == 'я') {
86
                // Азия
87
                $prefix = S::name(S::slice($name, 0, -1));
88
                return array(
89
                    self::IMENIT => S::name($name),
90
                    self::RODIT => $prefix.'и',
91
                    self::DAT => $prefix.'и',
92
                    self::VINIT => $prefix.'ю',
93
                    self::TVORIT => $prefix.'ей',
94
                    self::PREDLOJ => self::choosePrepositionByFirstLetter($prefix, 'об', 'о').' '.$prefix.'и',
95
                );
96
            } elseif (S::slice($name, -1) == 'й') {
97
                // Ишимбай
98
                $prefix = S::name(S::slice($name, 0, -1));
99
                return array(
100
                    self::IMENIT => $prefix.'й',
101
                    self::RODIT => $prefix.'я',
102
                    self::DAT => $prefix.'ю',
103
                    self::VINIT => $prefix.'й',
104
                    self::TVORIT => $prefix.'ем',
105
                    self::PREDLOJ => self::choosePrepositionByFirstLetter($prefix, 'об', 'о').' '.$prefix.'е',
106
                );
107 View Code Duplication
            } elseif (self::isConsonant(S::slice($name, -1)) && S::slice($name, -2) != 'ов') {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
108
                // Париж, Валаам, Киев
109
                $prefix = S::name($name);
110
                return array(
111
                    self::IMENIT => $prefix,
112
                    self::RODIT => $prefix.'а',
113
                    self::DAT => $prefix.'у',
114
                    self::VINIT => $prefix,
115
                    self::TVORIT => $prefix.(self::isVelarConsonant(S::slice($name, -2, -1)) ? 'ем' : 'ом'),
116
                    self::PREDLOJ => self::choosePrepositionByFirstLetter($prefix, 'об', 'о').' '.$prefix.'е',
117
                );
118
            } elseif (S::slice($name, -2) == 'ль') {
119
                // Ставрополь, Ярославль
120
                $prefix = S::name(S::slice($name, 0, -1));
121
                return array(
122
                    self::IMENIT => $prefix.'ь',
123
                    self::RODIT => $prefix.'я',
124
                    self::DAT => $prefix.'ю',
125
                    self::VINIT => $prefix.'ь',
126
                    self::TVORIT => $prefix.'ем',
127
                    self::PREDLOJ => self::choosePrepositionByFirstLetter($prefix, 'об', 'о').' '.$prefix.'е',
128
                );
129
            } elseif (S::slice($name, -2) == 'рь') {
130
                // Тверь
131
                $prefix = S::name(S::slice($name, 0, -1));
132
                return array(
133
                    self::IMENIT => $prefix.'ь',
134
                    self::RODIT => $prefix.'и',
135
                    self::DAT => $prefix.'и',
136
                    self::VINIT => $prefix.'ь',
137
                    self::TVORIT => $prefix.'ью',
138
                    self::PREDLOJ => self::choosePrepositionByFirstLetter($prefix, 'об', 'о').' '.$prefix.'и',
139
                );
140
            } elseif (S::slice($name, -2) == 'ки') {
141
                // Березники, Ессентуки
142
                $prefix = S::name(S::slice($name, 0, -1));
143
                return array(
144
                    self::IMENIT => $prefix.'и',
145
                    self::RODIT => $prefix.'ов',
146
                    self::DAT => $prefix.'ам',
147
                    self::VINIT => $prefix.'и',
148
                    self::TVORIT => $prefix.'ами',
149
                    self::PREDLOJ => self::choosePrepositionByFirstLetter($prefix, 'об', 'о').' '.$prefix.'ах',
150
                );
151
            } elseif (S::slice($name, -2) == 'мь') {
152
                // Пермь, Кемь
153
                $prefix = S::name(S::slice($name, 0, -1));
154
                return array(
155
                    self::IMENIT => $prefix.'ь',
156
                    self::RODIT => $prefix.'и',
157
                    self::DAT => $prefix.'и',
158
                    self::VINIT => $prefix.'ь',
159
                    self::TVORIT => $prefix.'ью',
160
                    self::PREDLOJ => self::choosePrepositionByFirstLetter($prefix, 'об', 'о').' '.$prefix.'и',
161
                );
162
            } elseif (S::slice($name, -2) == 'нь') {
163
                // Рязань, Назрань
164
                $prefix = S::name(S::slice($name, 0, -1));
165
                return array(
166
                    self::IMENIT => $prefix.'ь',
167
                    self::RODIT => $prefix.'и',
168
                    self::DAT => $prefix.'и',
169
                    self::VINIT => $prefix.'ь',
170
                    self::TVORIT => $prefix.'ью',
171
                    self::PREDLOJ => self::choosePrepositionByFirstLetter($prefix, 'об', 'о').' '.$prefix.'и',
172
                );
173
            }
174
175
            $suffixes = array('ов', 'ёв', 'ев', 'ин', 'ын');
176
            if ((in_array(S::slice($name, -1), array('е', 'о')) && in_array(S::slice($name, -3, -1), $suffixes)) || in_array(S::slice($name, -2), $suffixes)) {
177
                // ово, ёво, ...
178
                if (in_array(S::slice($name, -3, -1), $suffixes)) {
179
                    $prefix = S::name(S::slice($name, 0, -1));
180
                }
181
                // ов, её, ...
182
                elseif (in_array(S::slice($name, -2), $suffixes)) {
183
                    $prefix = S::name($name);
184
                }
185
                return array(
186
                    self::IMENIT => S::name($name),
187
                    self::RODIT => $prefix.'а',
188
                    self::DAT => $prefix.'у',
189
                    self::VINIT => S::name($name),
190
                    self::TVORIT => $prefix.'ым',
191
                    self::PREDLOJ => self::choosePrepositionByFirstLetter($prefix, 'об', 'о').' '.$prefix.'е',
192
                );
193
            }
194
        }
195
196
        // if no rules matches or name is immutable
197
        $name = in_array($name, self::$abbreviations) ? S::upper($name) : S::name($name);
198
        return array_fill_keys(array(self::IMENIT, self::RODIT, self::DAT, self::VINIT, self::TVORIT), $name) + array(self::PREDLOJ => self::choosePrepositionByFirstLetter($name, 'об', 'о').' '.$name);
199
    }
200
201
    public static function getCase($name, $case)
202
    {
203
        $case = self::canonizeCase($case);
204
        $forms = self::getCases($name);
205
        return $forms[$case];
206
    }
207
}
208