Completed
Push — master ( 18bbe5...4b1809 )
by f
01:51
created

NounDeclension::getVinitCaseByAnimateness()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 2

Importance

Changes 0
Metric Value
cc 2
nc 2
nop 2
dl 0
loc 8
ccs 4
cts 4
cp 1
crap 2
rs 10
c 0
b 0
f 0
1
<?php
2
namespace morphos\Russian;
3
4
use morphos\BaseInflection;
5
use morphos\Gender;
6
use morphos\S;
7
8
/**
9
 * Rules are from http://morpher.ru/Russian/Noun.aspx
10
 */
11
class NounDeclension extends BaseInflection implements Cases, Gender
12
{
13
    use RussianLanguage, CasesHelper;
14
15
    const FIRST_DECLENSION = 1;
16
    const SECOND_DECLENSION = 2;
17
    const THIRD_DECLENSION = 3;
18
19
    /**
20
     * These words has 2 declension type.
21
     */
22
    protected static $abnormalExceptions = [
23
        'бремя',
24
        'вымя',
25
        'темя',
26
        'пламя',
27
        'стремя',
28
        'пламя',
29
        'время',
30
        'знамя',
31
        'имя',
32
        'племя',
33
        'семя',
34
        'путь' => ['путь', 'пути', 'пути', 'путь', 'путем', 'пути'],
35
        'дитя' => ['дитя', 'дитяти', 'дитяти', 'дитя', 'дитятей', 'дитяти'],
36
    ];
37
38
    protected static $masculineWithSoft = [
39
        'ячмень',
40
        'путь',
41
        'шкворень',
42
        'пельмень',
43
        'табель',
44
        'рояль',
45
        'шампунь',
46
        'гвоздь',
47
        'рубль',
48
        'дождь',
49
        'зверь',
50
        'юань',
51
        'олень',
52
        'конь',
53
        'конь',
54
        'лось',
55
        'тюлень',
56
        'выхухоль',
57
        'медведь',
58
        'председатель',
59
        'руководитель',
60
        'заместитель',
61
    ];
62
63
    protected static $masculineWithSoftAndRunAwayVowels = [
64
        'день',
65
        'пень',
66
        'парень',
67
        'камень',
68
        'корень',
69
        'трутень',
70
    ];
71
72
    protected static $immutableWords = [
73
        // валюты
74
        'евро', 'пенни', 'песо', 'сентаво',
75
76
        // на а
77
        'боа', 'бра', 'фейхоа', 'амплуа', 'буржуа',
78
        // на о
79
        'манго', 'какао', 'кино', 'трюмо', 'пальто', 'бюро', 'танго', 'вето', 'бунгало', 'сабо', 'авокадо', 'депо',
80
        // на у
81
        'зебу', 'кенгуру', 'рагу', 'какаду', 'шоу',
82
        // на е
83
        'шимпанзе', 'конферансье', 'атташе', 'колье', 'резюме', 'пенсне', 'кашне', 'протеже', 'коммюнике', 'драже', 'суфле', 'пюре', 'купе', 'фойе', 'шоссе',
84
        // на и
85
        'такси', 'жалюзи', 'шасси', 'алиби', 'киви', 'иваси', 'регби', 'конфетти', 'колибри', 'жюри', 'пенальти', 'рефери', 'кольраби',
86
        // на э
87
        'каноэ', 'алоэ',
88
        // на ю
89
        'меню', 'парвеню', 'авеню', 'дежавю', 'инженю', 'барбекю', 'интервью',
90
    ];
91
92
    /**
93
     * Проверка, изменяемое ли слово.
94
     * @param string $word Слово для проверки
95
     * @param bool $animateness Признак одушевленности
96
     * @return bool
97
     */
98 86
    public static function isMutable($word, $animateness = false)
0 ignored issues
show
Unused Code introduced by
The parameter $animateness is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
99
    {
100 86
        $word = S::lower($word);
101 86
        if (in_array(S::slice($word, -1), ['у', 'и', 'е', 'о', 'ю'], true) || in_array($word, static::$immutableWords, true)) {
0 ignored issues
show
Bug introduced by
It seems like $word defined by \morphos\S::lower($word) on line 100 can also be of type boolean; however, morphos\S::slice() does only seem to accept string, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
102 86
            return false;
103
        }
104
        return true;
105
    }
106
107
    /**
108
     * Определение рода существительного.
109
     * @param string $word
110
     * @return string
111
     */
112 8
    public static function detectGender($word)
113
    {
114 8
    	$word = S::lower($word);
115 8
    	$last = S::slice($word, -1);
0 ignored issues
show
Bug introduced by
It seems like $word defined by \morphos\S::lower($word) on line 114 can also be of type boolean; however, morphos\S::slice() does only seem to accept string, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
116
		// пытаемся угадать род объекта, хотя бы примерно, чтобы правильно склонять
117 8
		if (S::slice($word, -2) == 'мя' || in_array($last, ['о', 'е', 'и', 'у'], true))
0 ignored issues
show
Bug introduced by
It seems like $word defined by \morphos\S::lower($word) on line 114 can also be of type boolean; however, morphos\S::slice() does only seem to accept string, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
118 2
			return static::NEUTER;
119
120 6
		if (in_array($last, ['а', 'я'], true) ||
121 6
			($last == 'ь' && !in_array($word, static::$masculineWithSoft, true) && !in_array($word, static::$masculineWithSoftAndRunAwayVowels, true)))
122 3
			return static::FEMALE;
123
124 3
		return static::MALE;
125
    }
126
127
    /**
128
     * Определение склонения (по школьной программе) существительного.
129
     * @param $word
130
     * @param bool $animateness
131
     * @return int
132
     */
133 178
    public static function getDeclension($word, $animateness = false)
0 ignored issues
show
Unused Code introduced by
The parameter $animateness is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
134
    {
135 178
        $word = S::lower($word);
136 178
        $last = S::slice($word, -1);
0 ignored issues
show
Bug introduced by
It seems like $word defined by \morphos\S::lower($word) on line 135 can also be of type boolean; however, morphos\S::slice() does only seem to accept string, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
137 178
        if (isset(static::$abnormalExceptions[$word]) || in_array($word, static::$abnormalExceptions, true)) {
138 3
            return 2;
139
        }
140
141 175
        if (in_array($last, ['а', 'я'], true) && S::slice($word, -2) != 'мя') {
0 ignored issues
show
Bug introduced by
It seems like $word defined by \morphos\S::lower($word) on line 135 can also be of type boolean; however, morphos\S::slice() does only seem to accept string, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
142 56
            return 1;
143 128
        } elseif (static::isConsonant($last) || in_array($last, ['о', 'е', 'ё'], true)
144 32
            || ($last == 'ь' && static::isConsonant(S::slice($word, -2, -1)) && !static::isHissingConsonant(S::slice($word, -2, -1))
0 ignored issues
show
Bug introduced by
It seems like $word defined by \morphos\S::lower($word) on line 135 can also be of type boolean; however, morphos\S::slice() does only seem to accept string, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
145 128
                && (in_array($word, static::$masculineWithSoft, true)) || in_array($word, static::$masculineWithSoftAndRunAwayVowels, true))) {
146 119
            return 2;
147
        } else {
148 9
            return 3;
149
        }
150
    }
151
152
    /**
153
     * Получение слова во всех 6 падежах.
154
     * @param string $word
155
     * @param bool $animateness Признак одушевлённости
156
     * @return array
157
     */
158 101
    public static function getCases($word, $animateness = false)
159
    {
160 101
        $word = S::lower($word);
161
162
        // Адъективное склонение (Сущ, образованные от прилагательных и причастий) - прохожий, существительное
163 101
        if (static::isAdjectiveNoun($word)) {
0 ignored issues
show
Bug introduced by
It seems like $word defined by \morphos\S::lower($word) on line 160 can also be of type boolean; however, morphos\Russian\RussianLanguage::isAdjectiveNoun() does only seem to accept string, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
164 8
            return static::declinateAdjective($word, $animateness);
165
        }
166
167
        // Субстантивное склонение (существительные)
168 93
        if (in_array($word, static::$immutableWords, true)) {
169
            return [
170 3
                static::IMENIT => $word,
171 3
                static::RODIT => $word,
172 3
                static::DAT => $word,
173 3
                static::VINIT => $word,
174 3
                static::TVORIT => $word,
175 3
                static::PREDLOJ => $word,
176
            ];
177 90
        } elseif (isset(static::$abnormalExceptions[$word])) {
178 2
            return array_combine([static::IMENIT, static::RODIT, static::DAT, static::VINIT, static::TVORIT, static::PREDLOJ], static::$abnormalExceptions[$word]);
179 88
        } elseif (in_array($word, static::$abnormalExceptions, true)) {
180 1
            $prefix = S::slice($word, 0, -1);
0 ignored issues
show
Bug introduced by
It seems like $word defined by \morphos\S::lower($word) on line 160 can also be of type boolean; however, morphos\S::slice() does only seem to accept string, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
181
            return [
182 1
                static::IMENIT => $word,
183 1
                static::RODIT => $prefix.'ени',
184 1
                static::DAT => $prefix.'ени',
185 1
                static::VINIT => $word,
186 1
                static::TVORIT => $prefix.'енем',
187 1
                static::PREDLOJ => $prefix.'ени',
188
            ];
189
        }
190
191 87
        switch (static::getDeclension($word)) {
192 87
            case static::FIRST_DECLENSION:
193 25
                return static::declinateFirstDeclension($word);
194 64
            case static::SECOND_DECLENSION:
195 60
                return static::declinateSecondDeclension($word, $animateness);
196 4
            case static::THIRD_DECLENSION:
197 4
                return static::declinateThirdDeclension($word);
198
        }
199
    }
200
201
    /**
202
     * Получение всех форм слова первого склонения.
203
     * @param $word
204
     * @return array
205
     */
206 25
    public static function declinateFirstDeclension($word)
207
    {
208 25
        $word = S::lower($word);
209 25
        $prefix = S::slice($word, 0, -1);
0 ignored issues
show
Bug introduced by
It seems like $word defined by \morphos\S::lower($word) on line 208 can also be of type boolean; however, morphos\S::slice() does only seem to accept string, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
210 25
        $last = S::slice($word, -1);
0 ignored issues
show
Bug introduced by
It seems like $word defined by \morphos\S::lower($word) on line 208 can also be of type boolean; however, morphos\S::slice() does only seem to accept string, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
211 25
        $soft_last = static::checkLastConsonantSoftness($word);
212
        $forms =  [
213 25
            Cases::IMENIT => $word,
214
        ];
215
216
        // RODIT
217 25
        $forms[Cases::RODIT] = static::chooseVowelAfterConsonant($last, $soft_last || (in_array(S::slice($word, -2, -1), ['г', 'к', 'х'], true)), $prefix.'и', $prefix.'ы');
0 ignored issues
show
Bug introduced by
It seems like $word defined by \morphos\S::lower($word) on line 208 can also be of type boolean; however, morphos\S::slice() does only seem to accept string, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
218
219
        // DAT
220 25
        $forms[Cases::DAT] = static::getPredCaseOf12Declensions($word, $last, $prefix);
221
222
        // VINIT
223 25
        $forms[Cases::VINIT] = static::chooseVowelAfterConsonant($last, $soft_last && S::slice($word, -2, -1) != 'ч', $prefix.'ю', $prefix.'у');
0 ignored issues
show
Bug introduced by
It seems like $word defined by \morphos\S::lower($word) on line 208 can also be of type boolean; however, morphos\S::slice() does only seem to accept string, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
224
225
        // TVORIT
226 25
        if ($last == 'ь') {
227
            $forms[Cases::TVORIT] = $prefix.'ой';
228 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...
229 25
            $forms[Cases::TVORIT] = static::chooseVowelAfterConsonant($last, $soft_last, $prefix.'ей', $prefix.'ой');
230
        }
231
232
        // 	if ($last == 'й' || (static::isConsonant($last) && !static::isHissingConsonant($last)) || static::checkLastConsonantSoftness($word))
233
        // 	$forms[Cases::TVORIT] = $prefix.'ей';
234
        // else
235
        // 	$forms[Cases::TVORIT] = $prefix.'ой'; # http://morpher.ru/Russian/Spelling.aspx#sibilant
236
237
        // PREDLOJ the same as DAT
238 25
        $forms[Cases::PREDLOJ] = $forms[Cases::DAT];
239 25
        return $forms;
240
    }
241
242
    /**
243
     * Получение всех форм слова второго склонения.
244
     * @param $word
245
     * @param bool $animateness
246
     * @return array
247
     */
248 60
    public static function declinateSecondDeclension($word, $animateness = false)
249
    {
250 60
        $word = S::lower($word);
251 60
        $last = S::slice($word, -1);
0 ignored issues
show
Bug introduced by
It seems like $word defined by \morphos\S::lower($word) on line 250 can also be of type boolean; however, morphos\S::slice() does only seem to accept string, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
252 60
        $soft_last = $last == 'й' || (in_array($last, ['ь', 'е', 'ё', 'ю', 'я'], true)
253
            && ((
254 22
                static::isConsonant(S::slice($word, -2, -1)) && !static::isHissingConsonant(S::slice($word, -2, -1)))
0 ignored issues
show
Bug introduced by
It seems like $word defined by \morphos\S::lower($word) on line 250 can also be of type boolean; however, morphos\S::slice() does only seem to accept string, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
255 60
                    || S::slice($word, -2, -1) == 'и'));
0 ignored issues
show
Bug introduced by
It seems like $word defined by \morphos\S::lower($word) on line 250 can also be of type boolean; however, morphos\S::slice() does only seem to accept string, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
256 60
        $prefix = static::getPrefixOfSecondDeclension($word, $last);
257
        $forms =  [
258 60
            Cases::IMENIT => $word,
259
        ];
260
261
        // RODIT
262 60
        $forms[Cases::RODIT] = static::chooseVowelAfterConsonant($last, $soft_last, $prefix.'я', $prefix.'а');
263
264
        // DAT
265 60
        $forms[Cases::DAT] = static::chooseVowelAfterConsonant($last, $soft_last, $prefix.'ю', $prefix.'у');
266
267
        // VINIT
268 60
        if (in_array($last, ['о', 'е', 'ё'], true)) {
269 13
            $forms[Cases::VINIT] = $word;
270
        } else {
271 47
            $forms[Cases::VINIT] = static::getVinitCaseByAnimateness($forms, $animateness);
272
        }
273
274
        // TVORIT
275
        // if ($last == 'ь')
276
        // 	$forms[Cases::TVORIT] = $prefix.'ом';
277
        // else if ($last == 'й' || (static::isConsonant($last) && !static::isHissingConsonant($last)))
278
        // 	$forms[Cases::TVORIT] = $prefix.'ем';
279
        // else
280
        // 	$forms[Cases::TVORIT] = $prefix.'ом'; # http://morpher.ru/Russian/Spelling.aspx#sibilant
281 60
        if (static::isHissingConsonant($last) || (in_array($last, ['ь', 'е', 'ё', 'ю', 'я'], true) && static::isHissingConsonant(S::slice($word, -2, -1))) || $last == 'ц') {
0 ignored issues
show
Bug introduced by
It seems like $word defined by \morphos\S::lower($word) on line 250 can also be of type boolean; however, morphos\S::slice() does only seem to accept string, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
282 5
            $forms[Cases::TVORIT] = $prefix.'ем';
283 55 View Code Duplication
        } elseif (in_array($last, ['й'/*, 'ч', 'щ'*/], true) || $soft_last) {
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...
284 23
            $forms[Cases::TVORIT] = $prefix.'ем';
285
        } else {
286 32
            $forms[Cases::TVORIT] = $prefix.'ом';
287
        }
288
289
        // PREDLOJ
290 60
        $forms[Cases::PREDLOJ] = static::getPredCaseOf12Declensions($word, $last, $prefix);
291
292 60
        return $forms;
293
    }
294
295
    /**
296
     * Получение всех форм слова третьего склонения.
297
     * @param $word
298
     * @return array
299
     */
300 4
    public static function declinateThirdDeclension($word)
301
    {
302 4
        $word = S::lower($word);
303 4
        $prefix = S::slice($word, 0, -1);
0 ignored issues
show
Bug introduced by
It seems like $word defined by \morphos\S::lower($word) on line 302 can also be of type boolean; however, morphos\S::slice() does only seem to accept string, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
304
        return [
305 4
            Cases::IMENIT => $word,
306 4
            Cases::RODIT => $prefix.'и',
307 4
            Cases::DAT => $prefix.'и',
308 4
            Cases::VINIT => $word,
309 4
            Cases::TVORIT => $prefix.'ью',
310 4
            Cases::PREDLOJ => $prefix.'и',
311
        ];
312
    }
313
314
    /**
315
     * Склонение существительных, образованных от прилагательных и причастий.
316
     * Rules are from http://rusgram.narod.ru/1216-1231.html
317
     * @param $word
318
     * @param $animateness
319
     * @return array
320
     */
321 8
    public static function declinateAdjective($word, $animateness)
0 ignored issues
show
Unused Code introduced by
The parameter $animateness is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
322
    {
323 8
        $prefix = S::slice($word, 0, -2);
324
325 8
        switch (S::slice($word, -2)) {
326
            // Male adjectives
327 8
            case 'ой':
328 7 View Code Duplication
            case 'ый':
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...
329
                return [
330 2
                    Cases::IMENIT => $word,
331 2
                    Cases::RODIT => $prefix.'ого',
332 2
                    Cases::DAT => $prefix.'ому',
333 2
                    Cases::VINIT => $word,
334 2
                    Cases::TVORIT => $prefix.'ым',
335 2
                    Cases::PREDLOJ => $prefix.'ом',
336
                ];
337
338 6 View Code Duplication
            case 'ий':
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...
339
                return [
340 1
                    Cases::IMENIT => $word,
341 1
                    Cases::RODIT => $prefix.'его',
342 1
                    Cases::DAT => $prefix.'ему',
343 1
                    Cases::VINIT => $prefix.'его',
344 1
                    Cases::TVORIT => $prefix.'им',
345 1
                    Cases::PREDLOJ => $prefix.'ем',
346
                ];
347
348
            // Neuter adjectives
349 5
            case 'ое':
350 4 View Code Duplication
            case 'ее':
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...
351 2
                $prefix = S::slice($word, 0, -1);
352
                return [
353 2
                    Cases::IMENIT => $word,
354 2
                    Cases::RODIT => $prefix.'го',
355 2
                    Cases::DAT => $prefix.'му',
356 2
                    Cases::VINIT => $word,
357 2
                    Cases::TVORIT => S::slice($word, 0, -2).(S::slice($word, -2, -1) == 'о' ? 'ы' : 'и').'м',
358 2
                    Cases::PREDLOJ => $prefix.'м',
359
                ];
360
361
            // Female adjectives
362 3
            case 'ая':
363 3
                $ending = static::isHissingConsonant(S::slice($prefix, -1)) ? 'ей' : 'ой';
0 ignored issues
show
Security Bug introduced by
It seems like $prefix defined by \morphos\S::slice($word, 0, -2) on line 323 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 false. This is usually indicative of an error condtion.

Consider the follow example

<?php

function getDate($date)
{
    if ($date !== null) {
        return new DateTime($date);
    }

    return false;
}

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 returned false before passing on the value to another function or method that may not be able to handle a false.

Loading history...
364
                return [
365 3
                    Cases::IMENIT => $word,
366 3
                    Cases::RODIT => $prefix.$ending,
367 3
                    Cases::DAT => $prefix.$ending,
368 3
                    Cases::VINIT => $prefix.'ую',
369 3
                    Cases::TVORIT => $prefix.$ending,
370 3
                    Cases::PREDLOJ => $prefix.$ending,
371
                ];
372
        }
373
    }
374
375
    /**
376
     * Получение одной формы слова (падежа).
377
     * @param string $word Слово
378
     * @param integer $case Падеж
379
     * @param bool $animateness Признак одушевленности
380
     * @return string
381
     * @throws \Exception
382
     */
383 40
    public static function getCase($word, $case, $animateness = false)
384
    {
385 40
        $case = static::canonizeCase($case);
386 40
        $forms = static::getCases($word, $animateness);
387 40
        return $forms[$case];
388
    }
389
390
    /**
391
     * @param $word
392
     * @param $last
393
     * @return bool
394
     */
395 89
    public static function getPrefixOfSecondDeclension($word, $last)
396
    {
397
        // слова с бегающей гласной в корне
398 89
        if (in_array($word, static::$masculineWithSoftAndRunAwayVowels, true)) {
399 7
            $prefix = S::slice($word, 0, -3).S::slice($word, -2, -1);
400 84
        } elseif (in_array($last, ['о', 'е', 'ё', 'ь', 'й'], true)) {
401 32
            $prefix = S::slice($word, 0, -1);
402
        }
403
        // уменьшительные формы слов (котенок) и слова с суффиксом ок
404 52
        elseif (S::slice($word, -2) == 'ок' && S::length($word) > 3) {
405 4
            $prefix = S::slice($word, 0, -2).'к';
406
        } else {
407 48
            $prefix = $word;
408
        }
409 89
        return $prefix;
410
    }
411
412
    /**
413
     * @param $word
414
     * @param $last
415
     * @param $prefix
416
     * @return string
417
     */
418 83
    public static function getPredCaseOf12Declensions($word, $last, $prefix)
419
    {
420 83
        if (in_array(S::slice($word, -2), ['ий', 'ие'], true)) {
421 6
            if ($last == 'ё') {
422
                return $prefix.'е';
423
            } else {
424 6
                return $prefix.'и';
425
            }
426
        } else {
427 77
            return $prefix.'е';
428
        }
429
    }
430
}
431