Completed
Push — master ( dd6397...5d0bef )
by f
01:45
created

LastNamesInflection   A

Complexity

Total Complexity 34

Size/Duplication

Total Lines 209
Duplicated Lines 27.75 %

Coupling/Cohesion

Components 1
Dependencies 4

Importance

Changes 0
Metric Value
dl 58
loc 209
rs 9.2
c 0
b 0
f 0
wmc 34
lcom 1
cbo 4

4 Methods

Rating   Name   Duplication   Size   Complexity  
A getCase() 0 6 1
A detectGender() 0 12 3
C isMutable() 11 53 13
D getCases() 47 127 17

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
<?php
2
namespace morphos\Russian;
3
4
use morphos\S;
5
6
/**
7
 * Rules are from http://gramma.ru/SPR/?id=2.8
8
 */
9
class LastNamesInflection extends \morphos\NamesInflection implements Cases
10
{
11
    use RussianLanguage, CasesHelper;
12
13
    protected static $menPostfixes = array('ов', 'ев' ,'ин' ,'ын', 'ой', 'ий');
14
    protected static $womenPostfixes = array('ва', 'на', 'ая', 'яя');
15
16
    public static function isMutable($name, $gender = null)
17
    {
18
        $name = S::lower($name);
19
        if ($gender === null) {
20
            $gender = self::detectGender($name);
21
        }
22
        // составная фамилия - разбить на части и проверить по отдельности
23
        if (strpos($name, '-') !== false) {
24
            foreach (explode('-', $name) as $part) {
25
                if (static::isMutable($part, $gender))
26
                    return true;
27
            }
28
            return false;
29
        }
30
31 View Code Duplication
        if (in_array(S::slice($name, -1), array('а', 'я'))) {
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...
32
            return true;
33
        }
34
35
        if ($gender == self::MALE) {
36
            // Несклоняемые фамилии (Фоминых, Седых / Стецко, Писаренко)
37
            if (in_array(S::slice($name, -2), ['ых', 'ко']))
38
                return false;
39
40
            // Несклоняемые, образованные из родительного падежа личного или прозвищного имени главы семьи
41
            // суффиксы: ово, аго
42
            if (in_array(S::slice($name, -3), ['ово', 'аго']))
43
                return false;
44
45
            // Типичные суффикс мужских фамилий
46 View Code Duplication
            if (in_array(S::slice($name, -2), array('ов', 'ев', 'ин', 'ын', 'ий', 'ой'))) {
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...
47
                return true;
48
            }
49
50
            // Согласная на конце
51
            if (self::isConsonant(S::slice($name, -1))) {
52
                return true;
53
            }
54
55
            // Мягкий знак на конце
56
            if (S::slice($name, -1) == 'ь') {
57
                return true;
58
            }
59
60 View Code Duplication
        } else {
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...
61
            // Типичные суффиксы женских фамилий
62
            if (in_array(S::slice($name, -2), ['ва', 'на', 'ая'])) {
63
                return true;
64
            }
65
        }
66
67
        return false;
68
    }
69
70
    public static function detectGender($name)
71
    {
72
        $name = S::lower($name);
73
        if (in_array(S::slice($name, -2), self::$menPostfixes)) {
74
            return self::MALE;
75
        }
76
        if (in_array(S::slice($name, -2), self::$womenPostfixes)) {
77
            return self::FEMALE;
78
        }
79
80
        return null;
81
    }
82
83
    public static function getCases($name, $gender = null)
84
    {
85
        $name = S::lower($name);
86
        if ($gender === null) {
87
            $gender = self::detectGender($name);
88
        }
89
90
        // составная фамилия - разбить на части и склонять по отдельности
91 View Code Duplication
        if (strpos($name, '-') !== false) {
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...
92
            $parts = explode('-', $name);
93
            $cases = [];
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...
94
            foreach ($parts as $i => $part) {
95
                $parts[$i] = static::getCases($part, $gender);
96
            }
97
98
            return self::composeCasesFromWords($parts, '-');
99
        }
100
101
        if ($gender == self::MALE) {
102
            if (in_array(S::slice($name, -2), array('ов', 'ев', 'ин', 'ын'))) {
103
                $prefix = S::name($name);
104
                return array(
105
                    self::IMENIT => $prefix,
106
                    self::RODIT => $prefix.'а',
107
                    self::DAT => $prefix.'у',
108
                    self::VINIT => $prefix.'а',
109
                    self::TVORIT => $prefix.'ым',
110
                    self::PREDLOJ => $prefix.'е'
111
                );
112 View Code Duplication
            } elseif (in_array(S::slice($name, -4), array('ский', 'ской', 'цкий', 'цкой'))) {
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...
113
                $prefix = S::name(S::slice($name, 0, -2));
114
                return array(
115
                    self::IMENIT => S::name($name),
116
                    self::RODIT => $prefix.'ого',
117
                    self::DAT => $prefix.'ому',
118
                    self::VINIT => $prefix.'ого',
119
                    self::TVORIT => $prefix.'им',
120
                    self::PREDLOJ => $prefix.'ом'
121
                );
122
            // Верхний / Убогий / Толстой
123
            // Верхнего / Убогого / Толстого
124
            // Верхнему / Убогому / Толстому
125
            // Верхним / Убогим / Толстым
126
            // О Верхнем / Об Убогом / О Толстом
127
            } else if (in_array(S::slice($name, -2), ['ой', 'ый', 'ий'])) {
128
                $prefix = S::name(S::slice($name, 0, -2));
129
                return array(
130
                    self::IMENIT => S::name($name),
131
                    self::RODIT => $prefix.'ого',
132
                    self::DAT => $prefix.'ому',
133
                    self::VINIT => $prefix.'ого',
134
                    self::TVORIT => $prefix.'ым',
135
                    self::PREDLOJ => $prefix.'ом'
136
                );
137
            }
138
139
        } else {
140 View Code Duplication
            if (in_array(S::slice($name, -3), array('ова', 'ева', 'ина', 'ына'))) {
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...
141
                $prefix = S::name(S::slice($name, 0, -1));
142
                return array(
143
                    self::IMENIT => S::name($name),
144
                    self::RODIT => $prefix.'ой',
145
                    self::DAT => $prefix.'ой',
146
                    self::VINIT => $prefix.'у',
147
                    self::TVORIT => $prefix.'ой',
148
                    self::PREDLOJ => $prefix.'ой'
149
                );
150
            }
151
152
            if (in_array(S::slice($name, -2), array('ая'))) {
153
                $prefix = S::name(S::slice($name, 0, -2));
154
                return array(
155
                    self::IMENIT => S::name($name),
156
                    self::RODIT => $prefix.'ой',
157
                    self::DAT => $prefix.'ой',
158
                    self::VINIT => $prefix.'ую',
159
                    self::TVORIT => $prefix.'ой',
160
                    self::PREDLOJ => $prefix.'ой'
161
                );
162
            }
163
        }
164
165
        if (S::slice($name, -1) == 'я') {
166
            $prefix = S::name(S::slice($name, 0, -1));
167
            return array(
168
                self::IMENIT => S::name($name),
169
                self::RODIT => $prefix.'и',
170
                self::DAT => $prefix.'е',
171
                self::VINIT => $prefix.'ю',
172
                self::TVORIT => $prefix.'ей',
173
                self::PREDLOJ => $prefix.'е'
174
            );
175 View Code Duplication
        } elseif (S::slice($name, -1) == 'а') {
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...
176
            $prefix = S::name(S::slice($name, 0, -1));
177
            return array(
178
                self::IMENIT => S::name($name),
179
                self::RODIT => $prefix.(self::isDeafConsonant(S::slice($name, -2, -1)) ? 'и' : 'ы'),
180
                self::DAT => $prefix.'е',
181
                self::VINIT => $prefix.'у',
182
                self::TVORIT => $prefix.'ой',
183
                self::PREDLOJ => $prefix.'е'
184
            );
185
        } elseif (self::isConsonant(S::slice($name, -1)) && S::slice($name, -2) != 'ых') {
186
            $prefix = S::name($name);
187
            return array(
188
                self::IMENIT => S::name($name),
189
                self::RODIT => $prefix.'а',
190
                self::DAT => $prefix.'у',
191
                self::VINIT => $prefix.'а',
192
                self::TVORIT => $prefix.'ом',
193
                self::PREDLOJ => $prefix.'е'
194
            );
195
        } elseif (S::slice($name, -1) == 'ь' && $gender == self::MALE) {
196
            $prefix = S::name(S::slice($name, 0, -1));
197
            return array(
198
                self::IMENIT => S::name($name),
199
                self::RODIT => $prefix.'я',
200
                self::DAT => $prefix.'ю',
201
                self::VINIT => $prefix.'я',
202
                self::TVORIT => $prefix.'ем',
203
                self::PREDLOJ => $prefix.'е'
204
            );
205
        }
206
207
        $name = S::name($name);
208
        return array_fill_keys(array(self::IMENIT, self::RODIT, self::DAT, self::VINIT, self::TVORIT, self::PREDLOJ), $name);
209
    }
210
211
    public static function getCase($name, $case, $gender = null)
212
    {
213
        $case = self::canonizeCase($case);
214
        $forms = self::getCases($name, $gender);
215
        return $forms[$case];
216
    }
217
}
218