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