Completed
Push — master ( e7e02a...99d79e )
by f
09:19 queued 04:36
created

src/Russian/RussianLanguage.php (2 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

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 337
    public static function isVowel($char)
77
    {
78 337
        return in_array($char, self::$vowels);
79
    }
80
81
    /**
82
     * Проверка согласной
83
     */
84 187
    public static function isConsonant($char)
85
    {
86 187
        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 429
    public static function isHissingConsonant($consonant)
109
    {
110 429
        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 37
    public static function checkLastConsonantSoftness($word)
142
    {
143 37
        if (($substring = S::findLastPositionForOneOfChars(S::lower($word), self::$consonants)) !== false) {
144 37
            if (in_array(S::slice($substring, 0, 1), ['й', 'ч', 'щ'], true)) { // always soft consonants
145 14
                return true;
146 23
            } 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 20
        return false;
151
    }
152
153
    /**
154
     * Выбор предлога по первой букве
155
     */
156
    public static function choosePrepositionByFirstLetter($word, $prepositionWithVowel, $preposition)
157
    {
158 View Code Duplication
        if (in_array(S::lower(S::slice($word, 0, 1)), ['а', 'о', 'и', 'у', 'э'], true)) {
0 ignored issues
show
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...
159
            return $prepositionWithVowel;
160
        } else {
161
            return $preposition;
162
        }
163
    }
164
165
    /**
166
     * Выбор окончания в зависимости от мягкости
167
     */
168 102
    public static function chooseVowelAfterConsonant($last, $soft_last, $after_soft, $after_hard)
169
    {
170 102
        if ((RussianLanguage::isHissingConsonant($last) && !in_array($last, ['ж', 'ч'], true)) || /*self::isVelarConsonant($last) ||*/ $soft_last) {
171 37
            return $after_soft;
172
        } else {
173 79
            return $after_hard;
174
        }
175
    }
176
177
    /**
178
     * @param string $verb Verb to modify if gender is female
179
     * @param string $gender If not `m`, verb will be modified
180
     * @return string Correct verb
181
     */
182 8
    public static function verb($verb, $gender)
183
    {
184 8
        $verb = S::lower($verb);
185
        // возвратный глагол
186 8
        if (S::slice($verb, -2) == 'ся') {
187 4
            return ($gender == Gender::MALE ? $verb : mb_substr($verb, 0, -2).'ась');
188
        }
189
190
        // обычный глагол
191 4
        return ($gender == Gender::MALE ? $verb : $verb.'а');
192
    }
193
194
    /**
195
     * Add 'в' or 'во' prepositional before the word
196
     * @param string $word
197
     * @return string
198
     */
199 1
    public static function in($word)
200
    {
201 1
        $normalized = trim(S::lower($word));
202 1 View Code Duplication
        if (in_array(S::slice($normalized, 0, 1), ['в', 'ф'], true))
0 ignored issues
show
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...
203 1
            return 'во '.$word;
204 1
        return 'в '.$word;
205
    }
206
207
    /**
208
     * Add 'с' or 'со' prepositional before the word
209
     * @param string $word
210
     * @return string
211
     */
212 1
    public static function with($word)
213
    {
214 1
        $normalized = trim(S::lower($word));
215 1
        if (in_array(S::slice($normalized, 0, 1), ['c', 'з', 'ш', 'ж'], true) && static::isConsonant(S::slice($normalized, 1, 2)) || S::slice($normalized, 0, 1) == 'щ')
216 1
            return 'со '.$word;
217 1
        return 'с '.$word;
218
    }
219
220
    /**
221
     * Add 'о' or 'об' or 'обо' prepositional before the word
222
     * @param string $word
223
     * @return string
224
     */
225 1
    public static function about($word)
226
    {
227 1
        $normalized = trim(S::lower($word));
228 1
        if (static::isVowel(S::slice($normalized, 0, 1)) && !in_array(S::slice($normalized, 0, 1), ['е', 'ё', 'ю', 'я'], true))
229 1
            return 'об '.$word;
230
231 1 View Code Duplication
        if (in_array(S::slice($normalized, 0, 3), ['все', 'всё', 'всю', 'что', 'мне'], true))
232 1
            return 'обо '.$word;
233
234 1
        return 'о '.$word;
235
    }
236
237
    /**
238
     * Выбирает первое или второе окончание в зависимости от звонкости/глухости в конце слова.
239
     * @param string $word Слово (или префикс), на основе звонкости которого нужно выбрать окончание
240
     * @param string $ifSonorous Окончание, если слово оканчивается на звонкую согласную
241
     * @param string $ifDeaf Окончание, если слово оканчивается на глухую согласную
242
     * @return string Первое или второе окончание
243
     * @throws \Exception
244
     */
245 2
    public static function chooseEndingBySonority($word, $ifSonorous, $ifDeaf)
246
    {
247 2
        $last = S::slice($word, -1);
248 2
        if (self::isSonorousConsonant($last))
249 1
            return $ifSonorous;
250 1
        if (self::isDeafConsonant($last))
251 1
            return $ifDeaf;
252
253
        throw new \Exception('Not implemented');
254
    }
255
256
    /**
257
     * Проверяет, является ли существительно адъективным существительным
258
     * @param string $noun Существительное
259
     * @return bool
260
     */
261 127
    public static function isAdjectiveNoun($noun)
262
    {
263 127
        return in_array(S::slice($noun, -2), ['ой', 'ий', 'ый', 'ая', 'ое', 'ее'])
264 127
            && $noun != 'гений';
265
    }
266
}
267