Petrovich::detectGender()   A
last analyzed

Complexity

Conditions 6
Paths 6

Size

Total Lines 20
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 14
dl 0
loc 20
c 0
b 0
f 0
rs 9.2222
cc 6
nc 6
nop 1
1
<?php
2
namespace Staticall\Petrovich;
3
4
use Staticall\Petrovich\Petrovich\Ruleset;
5
6
class Petrovich
7
{
8
    /**
9
     * @var Ruleset
10
     */
11
    private $ruleset;
12
13
    /**
14
     * @param Ruleset $ruleset
15
     */
16
    public function __construct(Ruleset $ruleset)
17
    {
18
        $this->setRuleset($ruleset);
19
    }
20
21
    /**
22
     * @param Ruleset $ruleset
23
     *
24
     * @return Petrovich
25
     */
26
    public function setRuleset(Ruleset $ruleset) : Petrovich
27
    {
28
        $this->ruleset = $ruleset;
29
30
        return $this;
31
    }
32
33
    /**
34
     * @return Ruleset
35
     */
36
    public function getRuleset() : Ruleset
37
    {
38
        return $this->ruleset;
39
    }
40
41
    /**
42
     * Inflects full name, format must be:
43
     * LastName FirstName MiddleName
44
     *
45
     * @param string      $fullName Full name, separated by a single space, format: LastName FirstName MiddleName
46
     * @param int         $case     Case constant
47
     * @param string|null $gender   Gender constant
48
     *
49
     * @return string
50
     *
51
     * @throws Exception
52
     */
53
    public function inflectFullName(string $fullName, int $case, string $gender = null) : string
54
    {
55
        $parsed = static::parseFullName($fullName);
56
57
        if ($gender === null) {
58
            $gender = Ruleset::GENDER_ANDROGYNOUS;
59
60
            if ($parsed['middleName'] !== null) {
61
                $gender = static::detectGender($parsed['middleName']);
62
            }
63
        }
64
65
        if ($parsed['middleName'] === null) {
66
            return \implode(
67
                ' ',
68
69
                [
70
                    $this->inflectLastName($parsed['lastName'], $case, $gender),
71
                    $this->inflectFirstName($parsed['firstName'], $case, $gender),
72
                ]
73
            );
74
        }
75
76
        return \implode(
77
            ' ',
78
79
            [
80
                $this->inflectLastName($parsed['lastName'], $case, $gender),
81
                $this->inflectFirstName($parsed['firstName'], $case, $gender),
82
                $this->inflectMiddleName($parsed['middleName'], $case, $gender),
83
            ]
84
        );
85
    }
86
87
    /**
88
     * Inflects first name only
89
     *
90
     * @param string $firstName
91
     * @param int    $case
92
     * @param string $gender
93
     *
94
     * @return string
95
     *
96
     * @throws Petrovich\RuntimeException
97
     */
98
    public function inflectFirstName(string $firstName, int $case, string $gender) : string
99
    {
100
        return $this->ruleset->inflectFirstName($firstName, $case, $gender);
101
    }
102
103
    /**
104
     * Inflects middle name only
105
     *
106
     * @param string      $middleName
107
     * @param int         $case
108
     * @param string|null $gender
109
     *
110
     * @return string
111
     *
112
     * @throws Exception
113
     */
114
    public function inflectMiddleName(string $middleName, int $case, string $gender = null) : string
115
    {
116
        return $this->ruleset->inflectMiddleName($middleName, $case, $gender ?? static::detectGender($middleName));
117
    }
118
119
    /**
120
     * Inflects last name only
121
     *
122
     * @param string $lastName
123
     * @param int    $case
124
     * @param string $gender
125
     *
126
     * @return string
127
     *
128
     * @throws Petrovich\RuntimeException
129
     */
130
    public function inflectLastName(string $lastName, int $case, string $gender) : string
131
    {
132
        return $this->ruleset->inflectLastName($lastName, $case, $gender);
133
    }
134
135
    public static function parseFullName(string $fullName) : array
136
    {
137
        $nameParts = \explode(' ', $fullName);
138
139
        $lastName   = \array_shift($nameParts);
140
        $middleName = \array_pop($nameParts);
141
        $firstName  = \implode(' ', $nameParts);
142
143
        if (empty($firstName)) {
144
            $firstName = $middleName;
145
146
            $middleName = null;
147
        }
148
149
        return [
150
            'lastName'   => $lastName,
151
            'firstName'  => $firstName,
152
            'middleName' => $middleName,
153
        ];
154
    }
155
156
    /**
157
     * Определяет пол по отчеству
158
     *
159
     * @param string $middleName
160
     *
161
     * @return string
162
     *
163
     * @throws Exception
164
     */
165
    public static function detectGender(string $middleName)
166
    {
167
        if (empty($middleName)) {
168
            throw new Exception('Middle name cannot be empty');
169
        }
170
171
        switch (\mb_substr(\mb_strtolower($middleName), -4)) {
172
            case 'оглы':
173
                return Ruleset::GENDER_MALE;
174
            case 'кызы':
175
                return Ruleset::GENDER_FEMALE;
176
        }
177
178
        switch (\mb_substr(\mb_strtolower($middleName), -2)) {
179
            case 'ич':
180
                return Ruleset::GENDER_MALE;
181
            case 'на':
182
                return Ruleset::GENDER_FEMALE;
183
            default:
184
                return Ruleset::GENDER_ANDROGYNOUS;
185
        }
186
    }
187
}
188