1
|
|
|
<?php |
2
|
|
|
namespace morphos\Russian; |
3
|
|
|
|
4
|
|
|
use morphos\Gender; |
5
|
|
|
use morphos\S; |
6
|
|
|
|
7
|
|
|
/** |
8
|
|
|
* Inflects the name in one case. |
9
|
|
|
* @param string $fullName Name in "F", "L F" or "L M F" format, where L - last name, M - middle name, F - first name |
10
|
|
|
* @param string $case Case to inflect to. |
11
|
|
|
* Should be one of [[morphos\Cases]] or [[morphos\Russian\Cases]] constants. |
12
|
|
|
* @param null|string $gender Gender of name owner. If null, auto detection will be used. |
13
|
|
|
* Should be one of [[morphos\Gender]] constants. |
14
|
|
|
* @return string Returns string containing the inflection of name to a case. |
15
|
|
|
*/ |
16
|
|
|
function inflectName($fullName, $case, $gender = null) |
17
|
|
|
{ |
18
|
|
|
if (in_array($case, [Gender::MALE, Gender::FEMALE], true)) { |
19
|
|
|
return getNameCases($fullName, $gender); |
20
|
|
|
} |
21
|
|
|
|
22
|
|
|
$fullName = normalizeFullName($fullName); |
23
|
|
|
if ($gender === null) $gender = detectGender($fullName); |
24
|
|
|
|
25
|
|
|
$name = explode(' ', $fullName); |
26
|
|
|
$case = CasesHelper::canonizeCase($case); |
27
|
|
|
|
28
|
|
|
switch (count($name)) { |
29
|
|
|
case 1: |
30
|
|
|
$name[0] = FirstNamesInflection::getCase($name[0], $case, $gender); |
31
|
|
|
break; |
32
|
|
|
|
33
|
|
View Code Duplication |
case 2: |
|
|
|
|
34
|
|
|
$name[0] = LastNamesInflection::getCase($name[0], $case, $gender); |
35
|
|
|
$name[1] = FirstNamesInflection::getCase($name[1], $case, $gender); |
36
|
|
|
break; |
37
|
|
|
|
38
|
|
View Code Duplication |
case 3: |
|
|
|
|
39
|
|
|
$name[0] = LastNamesInflection::getCase($name[0], $case, $gender); |
40
|
|
|
$name[1] = FirstNamesInflection::getCase($name[1], $case, $gender); |
41
|
|
|
$name[2] = MiddleNamesInflection::getCase($name[2], $case, $gender); |
42
|
|
|
break; |
43
|
|
|
|
44
|
|
|
default: |
45
|
|
|
return false; |
46
|
|
|
} |
47
|
|
|
|
48
|
|
|
return implode(' ', $name); |
49
|
|
|
} |
50
|
|
|
|
51
|
|
|
/** |
52
|
|
|
* Inflects the name to all cases. |
53
|
|
|
* @param string $fullName Name in "F", "L F" or "L M F" format, where L - last name, M - middle name, F - first name |
54
|
|
|
* @param null|string $gender Gender of name owner. If null, auto detection will be used. |
55
|
|
|
* Should be one of [[morphos\Gender]] constants. |
56
|
|
|
* @return array Returns an array with name inflected to all cases. |
57
|
|
|
*/ |
58
|
|
|
function getNameCases($fullName, $gender = null) |
59
|
|
|
{ |
60
|
|
|
$fullName = normalizeFullName($fullName); |
61
|
|
|
if ($gender === null) $gender = detectGender($fullName); |
62
|
|
|
|
63
|
|
|
$name = explode(' ', $fullName); |
64
|
|
|
|
65
|
|
|
switch (count($name)) { |
66
|
|
|
case 1: |
67
|
|
|
$name[0] = FirstNamesInflection::getCases($name[0], $gender); |
68
|
|
|
break; |
69
|
|
|
|
70
|
|
View Code Duplication |
case 2: |
|
|
|
|
71
|
|
|
$name[0] = LastNamesInflection::getCases($name[0], $gender); |
72
|
|
|
$name[1] = FirstNamesInflection::getCases($name[1], $gender); |
73
|
|
|
break; |
74
|
|
|
|
75
|
|
View Code Duplication |
case 3: |
|
|
|
|
76
|
|
|
$name[0] = LastNamesInflection::getCases($name[0], $gender); |
77
|
|
|
$name[1] = FirstNamesInflection::getCases($name[1], $gender); |
78
|
|
|
$name[2] = MiddleNamesInflection::getCases($name[2], $gender); |
79
|
|
|
break; |
80
|
|
|
|
81
|
|
|
default: |
82
|
|
|
return false; |
83
|
|
|
} |
84
|
|
|
|
85
|
|
|
return CasesHelper::composeCasesFromWords($name); |
86
|
|
|
} |
87
|
|
|
|
88
|
|
|
/** |
89
|
|
|
* Guesses the gender of name owner. |
90
|
|
|
* @param string $fullName |
91
|
|
|
* @return null|string Null if not detected. One of [[morphos\Gender]] constants. |
92
|
|
|
*/ |
93
|
|
|
function detectGender($fullName) |
94
|
|
|
{ |
95
|
|
|
$gender = null; |
96
|
|
|
$name = explode(' ', S::lower($fullName)); |
97
|
|
|
$nameCount = count($name); |
98
|
|
|
if (!in_array($nameCount, [2, 3], true)) { |
99
|
|
|
return false; |
100
|
|
|
} |
101
|
|
|
if ($nameCount === 3) { |
102
|
|
|
$gender = detectGender(implode(' ', [$name[1], $name[2]])); |
103
|
|
|
} |
104
|
|
|
|
105
|
|
|
if (!$gender) { |
106
|
|
|
$gender = (isset($name[2]) ? MiddleNamesInflection::detectGender($name[2]) : null) ?: |
107
|
|
|
LastNamesInflection::detectGender($name[0]) ?: |
108
|
|
|
FirstNamesInflection::detectGender($name[1]); |
109
|
|
|
} |
110
|
|
|
|
111
|
|
|
return $gender; |
112
|
|
|
} |
113
|
|
|
|
114
|
|
|
/** |
115
|
|
|
* Normalizes a full name. Swaps name parts to make "L F" or "L M F" scheme. |
116
|
|
|
* @param string $name Input name |
117
|
|
|
* @return string Normalized name |
118
|
|
|
*/ |
119
|
|
|
function normalizeFullName($name) |
120
|
|
|
{ |
121
|
|
|
$name = preg_replace('~[ ]{2,}~', null, trim($name)); |
122
|
|
|
return $name; |
123
|
|
|
} |
124
|
|
|
|
125
|
|
|
/** |
126
|
|
|
* Генерация строки с числом и существительным, в правильной форме для сочетания с числом (кол-вом предметов). |
127
|
|
|
* @param int $count Количество предметов |
128
|
|
|
* @param string $word Название предмета |
129
|
|
|
* @param bool $animateness Признак одушевленности |
130
|
|
|
* @return string Строка в формате "ЧИСЛО [СУЩ в правильно форме]" |
131
|
|
|
*/ |
132
|
|
|
function pluralize($count, $word, $animateness = false) |
133
|
|
|
{ |
134
|
|
|
// меняем местами аргументы, если они переданы в старом формате |
135
|
|
View Code Duplication |
if (is_string($count) && is_numeric($word)) { |
|
|
|
|
136
|
|
|
list($count, $word) = [$word, $count]; |
137
|
|
|
} |
138
|
|
|
return $count.' '.NounPluralization::pluralize($count, $word, $animateness); |
139
|
|
|
} |
140
|
|
|
|
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.