Completed
Push — master ( 4b1809...5e3fcd )
by f
01:31
created

RussianLanguage::getVowels()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 0
dl 0
loc 4
ccs 0
cts 2
cp 0
crap 2
rs 10
c 0
b 0
f 0
1
<?php
2
namespace morphos\Russian;
3
4
use morphos\Gender;
5
use morphos\S;
6
7
trait RussianLanguage
8
{
9
    /**
10
     * @var array Все гласные
11
     */
12
    public static $vowels = [
13
        'а',
14
        'е',
15
        'ё',
16
        'и',
17
        'о',
18
        'у',
19
        'ы',
20
        'э',
21
        'ю',
22
        'я',
23
    ];
24
25
    /**
26
     * @var array Все согласные
27
     */
28
    public static $consonants = [
29
        'б',
30
        'в',
31
        'г',
32
        'д',
33
        'ж',
34
        'з',
35
        'й',
36
        'к',
37
        'л',
38
        'м',
39
        'н',
40
        'п',
41
        'р',
42
        'с',
43
        'т',
44
        'ф',
45
        'х',
46
        'ц',
47
        'ч',
48
        'ш',
49
        'щ',
50
    ];
51
52
    /**
53
     * @var array Пары согласных
54
     */
55
    public static $pairs = [
56
        'б' => 'п',
57
        'в' => 'ф',
58
        'г' => 'к',
59
        'д' => 'т',
60
        'ж' => 'ш',
61
        'з' => 'с',
62
    ];
63
64
    /**
65
     * @var array Звонкие согласные
66
     */
67
    public static $sonorousConsonants = ['б', 'в', 'г', 'д', 'з', 'ж', 'л', 'м', 'н', 'р'];
68
    /**
69
     * @var array Глухие согласные
70
     */
71
    public static $deafConsonants = ['п', 'ф', 'к', 'т', 'с', 'ш', 'х', 'ч', 'щ'];
72
73
    /**
74
     * @var array Союзы
75
     */
76
    public static $unions = ['и', 'или'];
77
78
    /**
79
     * @return array
80
     */
81
    public static function getVowels()
82
    {
83
        return self::$vowels;
84
    }
85
86
    /**
87
     * Проверка гласной
88
     * @param $char
89
     * @return bool
90
     */
91 348
    public static function isVowel($char)
92
    {
93 348
        return in_array($char, static::$vowels, true);
94
    }
95
96
    /**
97
     * Проверка согласной
98
     * @param $char
99
     * @return bool
100
     */
101 208
    public static function isConsonant($char)
102
    {
103 208
        return in_array($char, static::$consonants, true);
104
    }
105
106
    /**
107
     * Проверка звонкости согласной
108
     */
109 3
    public static function isSonorousConsonant($char)
110
    {
111 3
        return in_array($char, static::$sonorousConsonants, true);
112
    }
113
114
    /**
115
     * Проверка глухости согласной
116
     * @param $char
117
     * @return bool
118
     */
119 6
    public static function isDeafConsonant($char)
120
    {
121 6
        return in_array($char, static::$deafConsonants, true);
122
    }
123
124
    /**
125
     * Щипящая ли согласная
126
     * @param $consonant
127
     * @return bool
128
     */
129 461
    public static function isHissingConsonant($consonant)
130
    {
131 461
        return in_array(S::lower($consonant), ['ж', 'ш', 'ч', 'щ'], true);
132
    }
133
134
    /**
135
     * Проверка на велярность согласной
136
     * @param string[1] $consonant
0 ignored issues
show
Documentation introduced by
The doc-type string[1] could not be parsed: Expected "]" at position 2, but found "1". (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
137
     * @return bool
138
     */
139 15
    protected static function isVelarConsonant($consonant)
140
    {
141 15
        return in_array(S::lower($consonant), ['г', 'к', 'х'], true);
142
    }
143
144
    /**
145
     * Подсчет слогов
146
     * @param $string
147
     * @return bool|int
148
     */
149
    public static function countSyllables($string)
150
    {
151
        return S::countChars($string, static::$vowels);
152
    }
153
154
    /**
155
     * Проверка парности согласной
156
     *
157
     * @param $consonant
158
     * @return bool
159
     */
160
    public static function isPairedConsonant($consonant)
161
    {
162
        $consonant = S::lower($consonant);
163
        return array_key_exists($consonant, static::$pairs) || (array_search($consonant, static::$pairs) !== false);
164
    }
165
166
    /**
167
     * Проверка мягкости последней согласной
168
     * @param $word
169
     * @return bool
170
     */
171 46
    public static function checkLastConsonantSoftness($word)
172
    {
173 46 View Code Duplication
        if (($substring = S::findLastPositionForOneOfChars(S::lower($word), static::$consonants)) !== 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...
174 46
            if (in_array(S::slice($substring, 0, 1), ['й', 'ч', 'щ', 'ш'], true)) { // always soft consonants
175 14
                return true;
176 32
            } elseif (S::length($substring) > 1 && in_array(S::slice($substring, 1, 2), ['е', 'ё', 'и', 'ю', 'я', 'ь'], true)) { // consonants are soft if they are trailed with these vowels
177 3
                return true;
178
            }
179
        }
180 29
        return false;
181
    }
182
183
    /**
184
     * Проверка мягкости последней согласной, за исключением Н
185
     * @param $word
186
     * @return bool
187
     */
188 10
    public static function checkBaseLastConsonantSoftness($word)
189
    {
190 10
        $consonants = static::$consonants;
191 10
        unset($consonants[array_search('н', $consonants)]);
192 10
        unset($consonants[array_search('й', $consonants)]);
193
194 10 View Code Duplication
        if (($substring = S::findLastPositionForOneOfChars(S::lower($word), $consonants)) !== 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...
195
            if (in_array(S::slice($substring, 0, 1), ['й', 'ч', 'щ', 'ш'], true)) { // always soft consonants
196
                return true;
197
            } elseif (S::length($substring) > 1 && in_array(S::slice($substring, 1, 2), ['е', 'ё', 'и', 'ю', 'я', 'ь'], true)) { // consonants are soft if they are trailed with these vowels
198
                return true;
199
            }
200
        }
201 10
        return false;
202
    }
203
204
    /**
205
     * Проверяет, что гласная образует два звука в словах
206
     * @param $vowel
207
     * @return bool
208
     */
209 2
    public static function isBinaryVowel($vowel)
210
    {
211 2
        return in_array(S::lower($vowel), ['е', 'ё', 'ю', 'я'], true);
212
    }
213
214
    /**
215
     * Выбор предлога по первой букве
216
     *
217
     * @param string $word Слово
218
     * @param string $prepositionWithVowel Предлог, если слово начинается с гласной
219
     * @param string $preposition Предлог, если слово не начинается с гласной
220
     *
221
     * @return string
222
     */
223
    public static function choosePrepositionByFirstLetter($word, $prepositionWithVowel, $preposition)
224
    {
225 View Code Duplication
        if (in_array(S::lower(S::slice($word, 0, 1)), ['а', 'о', 'и', 'у', 'э'], true)) {
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...
226
            return $prepositionWithVowel;
227
        } else {
228
            return $preposition;
229
        }
230
    }
231
232
    /**
233
     * Выбор окончания в зависимости от мягкости
234
     *
235
     * @param $last
236
     * @param $softLast
237
     * @param $afterSoft
238
     * @param $afterHard
239
     *
240
     * @return mixed
241
     */
242 130
    public static function chooseVowelAfterConsonant($last, $softLast, $afterSoft, $afterHard)
243
    {
244 130
        if ((RussianLanguage::isHissingConsonant($last) && !in_array($last, ['ж', 'ч'], true)) || /*static::isVelarConsonant($last) ||*/ $softLast) {
245 46
            return $afterSoft;
246
        } else {
247 100
            return $afterHard;
248
        }
249
    }
250
251
    /**
252
     * @param string $verb Verb to modify if gender is female
253
     * @param string $gender If not `m`, verb will be modified
254
     * @return string Correct verb
255
     */
256 10
    public static function verb($verb, $gender)
257
    {
258 10
        $verb = S::lower($verb);
259
        // возвратный глагол
260 10
        if (S::slice($verb, -2) == 'ся') {
0 ignored issues
show
Bug introduced by
It seems like $verb defined by \morphos\S::lower($verb) on line 258 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...
261
262 5
            return ($gender == Gender::MALE
263 2
                ? $verb
264 5
                : S::slice($verb, 0, -2).(S::slice($verb, -3, -2) === 'л' ? null : 'л').'ась');
0 ignored issues
show
Bug introduced by
It seems like $verb defined by \morphos\S::lower($verb) on line 258 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...
265
        }
266
267
        // обычный глагол
268 5
        return ($gender == Gender::MALE
269 2
            ? $verb
270 5
            : $verb.(S::slice($verb, -1) === 'л' ? null : 'л').'а');
0 ignored issues
show
Bug introduced by
It seems like $verb defined by \morphos\S::lower($verb) on line 258 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...
271
    }
272
273
    /**
274
     * Add 'в' or 'во' prepositional before the word
275
     * @param string $word
276
     * @return string
277
     */
278 1
    public static function in($word)
279
    {
280 1
        $normalized = trim(S::lower($word));
281 1 View Code Duplication
        if (in_array(S::slice($normalized, 0, 1), ['в', 'ф'], true))
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...
282 1
            return 'во '.$word;
283 1
        return 'в '.$word;
284
    }
285
286
    /**
287
     * Add 'с' or 'со' prepositional before the word
288
     * @param string $word
289
     * @return string
290
     */
291 1
    public static function with($word)
292
    {
293 1
        $normalized = trim(S::lower($word));
294 1
        if (in_array(S::slice($normalized, 0, 1), ['c', 'з', 'ш', 'ж'], true) && static::isConsonant(S::slice($normalized, 1, 2)) || S::slice($normalized, 0, 1) == 'щ')
295 1
            return 'со '.$word;
296 1
        return 'с '.$word;
297
    }
298
299
    /**
300
     * Add 'о' or 'об' or 'обо' prepositional before the word
301
     * @param string $word
302
     * @return string
303
     */
304 1
    public static function about($word)
305
    {
306 1
        $normalized = trim(S::lower($word));
307 1
        if (static::isVowel(S::slice($normalized, 0, 1)) && !in_array(S::slice($normalized, 0, 1), ['е', 'ё', 'ю', 'я'], true))
308 1
            return 'об '.$word;
309
310 1 View Code Duplication
        if (in_array(S::slice($normalized, 0, 3), ['все', 'всё', 'всю', 'что', 'мне'], true))
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...
311 1
            return 'обо '.$word;
312
313 1
        return 'о '.$word;
314
    }
315
316
    /**
317
     * Выбирает первое или второе окончание в зависимости от звонкости/глухости в конце слова.
318
     * @param string $word Слово (или префикс), на основе звонкости которого нужно выбрать окончание
319
     * @param string $ifSonorous Окончание, если слово оканчивается на звонкую согласную
320
     * @param string $ifDeaf Окончание, если слово оканчивается на глухую согласную
321
     * @return string Первое или второе окончание
322
     * @throws \Exception
323
     */
324 3
    public static function chooseEndingBySonority($word, $ifSonorous, $ifDeaf)
325
    {
326 3
        $last = S::slice($word, -1);
327 3
        if (static::isSonorousConsonant($last))
328 2
            return $ifSonorous;
329 1
        if (static::isDeafConsonant($last))
330 1
            return $ifDeaf;
331
332
        throw new \Exception('Not implemented');
333
    }
334
335
    /**
336
     * Проверяет, является ли существительно адъективным существительным
337
     * @param string $noun Существительное
338
     * @return bool
339
     */
340 157
    public static function isAdjectiveNoun($noun)
341
    {
342 157
        return in_array(S::slice($noun, -2), ['ой', 'ий', 'ый', 'ая', 'ое', 'ее'])
343 157
            && !in_array($noun, ['гений', 'комментарий']);
344
    }
345
346
    /**
347
     * @param array $forms
348
     * @param $animate
349
     * @return mixed
350
     */
351 117
    public static function getVinitCaseByAnimateness(array $forms, $animate)
352
    {
353 117
        if ($animate) {
354 9
            return $forms[Cases::RODIT];
355
        } else {
356 108
            return $forms[Cases::IMENIT];
357
        }
358
    }
359
}
360