Completed
Push — master ( a85940...3d0bce )
by f
01:53
created

RussianLanguage::isBinaryVowel()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 1
dl 0
loc 4
ccs 2
cts 2
cp 1
crap 1
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
     * Проверка гласной
75
     */
76 342
    public static function isVowel($char)
77
    {
78 342
        return in_array($char, self::$vowels);
79
    }
80
81
    /**
82
     * Проверка согласной
83
     */
84 188
    public static function isConsonant($char)
85
    {
86 188
        return in_array($char, self::$consonants);
87
    }
88
89
    /**
90
     * Проверка звонкости согласной
91
     */
92 2
    public static function isSonorousConsonant($char)
93
    {
94 2
        return in_array($char, self::$sonorousConsonants);
95
    }
96
97
    /**
98
     * Проверка глухости согласной
99
     */
100 6
    public static function isDeafConsonant($char)
101
    {
102 6
        return in_array($char, self::$deafConsonants);
103
    }
104
105
    /**
106
     * Щипящая ли согласная
107
     */
108 445
    public static function isHissingConsonant($consonant)
109
    {
110 445
        return in_array(S::lower($consonant), ['ж', 'ш', 'ч', 'щ'], true);
111
    }
112
113
    /**
114
     *
115
     */
116 12
    protected static function isVelarConsonant($consonant)
117
    {
118 12
        return in_array(S::lower($consonant), ['г', 'к', 'х'], true);
119
    }
120
121
    /**
122
     * Подсчет слогов
123
     */
124
    public static function countSyllables($string)
125
    {
126
        return S::countChars($string, self::$vowels);
127
    }
128
129
    /**
130
     * Проверка парности согласной
131
     */
132
    public static function isPaired($consonant)
133
    {
134
        $consonant = S::lower($consonant);
135
        return array_key_exists($consonant, self::$pairs) || (array_search($consonant, self::$pairs) !== false);
136
    }
137
138
    /**
139
     * Проверка мягкости последней согласной
140
     */
141 43
    public static function checkLastConsonantSoftness($word)
142
    {
143 43
        if (($substring = S::findLastPositionForOneOfChars(S::lower($word), self::$consonants)) !== false) {
144 43
            if (in_array(S::slice($substring, 0, 1), ['й', 'ч', 'щ'], true)) { // always soft consonants
145 14
                return true;
146 29
            } elseif (S::length($substring) > 1 && in_array(S::slice($substring, 1, 2), ['е', 'ё', 'и', 'ю', 'я', 'ь'], true)) { // consonants are soft if they are trailed with these vowels
147 3
                return true;
148
            }
149
        }
150 26
        return false;
151
    }
152
153
    /**
154
     * Проверяет, что гласная образует два звука в словах
155
     * @param $vowel
156
     * @return bool
157
     */
158 2
    public static function isBinaryVowel($vowel)
159
    {
160 2
        return in_array(S::lower($vowel), ['е', 'ё', 'ю', 'я'], true);
161
    }
162
163
    /**
164
     * Выбор предлога по первой букве
165
     */
166
    public static function choosePrepositionByFirstLetter($word, $prepositionWithVowel, $preposition)
167
    {
168 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...
169
            return $prepositionWithVowel;
170
        } else {
171
            return $preposition;
172
        }
173
    }
174
175
    /**
176
     * Выбор окончания в зависимости от мягкости
177
     */
178 116
    public static function chooseVowelAfterConsonant($last, $soft_last, $after_soft, $after_hard)
179
    {
180 116
        if ((RussianLanguage::isHissingConsonant($last) && !in_array($last, ['ж', 'ч'], true)) || /*self::isVelarConsonant($last) ||*/ $soft_last) {
181 40
            return $after_soft;
182
        } else {
183 90
            return $after_hard;
184
        }
185
    }
186
187
    /**
188
     * @param string $verb Verb to modify if gender is female
189
     * @param string $gender If not `m`, verb will be modified
190
     * @return string Correct verb
191
     */
192 8
    public static function verb($verb, $gender)
193
    {
194 8
        $verb = S::lower($verb);
195
        // возвратный глагол
196 8
        if (S::slice($verb, -2) == 'ся') {
0 ignored issues
show
Security Bug introduced by
It seems like $verb defined by \morphos\S::lower($verb) on line 194 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...
197 4
            return ($gender == Gender::MALE ? $verb : mb_substr($verb, 0, -2).'ась');
198
        }
199
200
        // обычный глагол
201 4
        return ($gender == Gender::MALE ? $verb : $verb.'а');
202
    }
203
204
    /**
205
     * Add 'в' or 'во' prepositional before the word
206
     * @param string $word
207
     * @return string
208
     */
209 1
    public static function in($word)
210
    {
211 1
        $normalized = trim(S::lower($word));
212 1
        if (in_array(S::slice($normalized, 0, 1), ['в', 'ф'], true))
213 1
            return 'во '.$word;
214 1
        return 'в '.$word;
215
    }
216
217
    /**
218
     * Add 'с' or 'со' prepositional before the word
219
     * @param string $word
220
     * @return string
221
     */
222 1
    public static function with($word)
223
    {
224 1
        $normalized = trim(S::lower($word));
225 1
        if (in_array(S::slice($normalized, 0, 1), ['c', 'з', 'ш', 'ж'], true) && static::isConsonant(S::slice($normalized, 1, 2)) || S::slice($normalized, 0, 1) == 'щ')
226 1
            return 'со '.$word;
227 1
        return 'с '.$word;
228
    }
229
230
    /**
231
     * Add 'о' or 'об' or 'обо' prepositional before the word
232
     * @param string $word
233
     * @return string
234
     */
235 1
    public static function about($word)
236
    {
237 1
        $normalized = trim(S::lower($word));
238 1
        if (static::isVowel(S::slice($normalized, 0, 1)) && !in_array(S::slice($normalized, 0, 1), ['е', 'ё', 'ю', 'я'], true))
239 1
            return 'об '.$word;
240
241 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...
242 1
            return 'обо '.$word;
243
244 1
        return 'о '.$word;
245
    }
246
247
    /**
248
     * Выбирает первое или второе окончание в зависимости от звонкости/глухости в конце слова.
249
     * @param string $word Слово (или префикс), на основе звонкости которого нужно выбрать окончание
250
     * @param string $ifSonorous Окончание, если слово оканчивается на звонкую согласную
251
     * @param string $ifDeaf Окончание, если слово оканчивается на глухую согласную
252
     * @return string Первое или второе окончание
253
     * @throws \Exception
254
     */
255 2
    public static function chooseEndingBySonority($word, $ifSonorous, $ifDeaf)
256
    {
257 2
        $last = S::slice($word, -1);
258 2
        if (self::isSonorousConsonant($last))
259 1
            return $ifSonorous;
260 1
        if (self::isDeafConsonant($last))
261 1
            return $ifDeaf;
262
263
        throw new \Exception('Not implemented');
264
    }
265
266
    /**
267
     * Проверяет, является ли существительно адъективным существительным
268
     * @param string $noun Существительное
269
     * @return bool
270
     */
271 142
    public static function isAdjectiveNoun($noun)
272
    {
273 142
        return in_array(S::slice($noun, -2), ['ой', 'ий', 'ый', 'ая', 'ое', 'ее'])
274 142
            && $noun != 'гений';
275
    }
276
}
277