Completed
Pull Request — master (#40)
by
unknown
01:17
created

Name::getGivenName()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
1
<?php
2
3
namespace TheIconic\NameParser;
4
5
use TheIconic\NameParser\Part\AbstractPart;
6
use TheIconic\NameParser\Part\GivenNamePart;
7
8
class Name
9
{
10
    private const PARTS_NAMESPACE = 'TheIconic\NameParser\Part';
11
12
    /**
13
     * @var array the parts that make up this name
14
     */
15
    protected $parts = [];
16
17
    /**
18
     * constructor takes the array of parts this name consists of
19
     *
20
     * @param array|null $parts
21
     */
22
    public function __construct(array $parts = null)
23
    {
24
        if (null !== $parts) {
25
            $this->setParts($parts);
26
        }
27
    }
28
29
    /**
30
     * @return string
31
     */
32
    public function __toString(): string
33
    {
34
        return implode(' ', $this->getAll(true));
35
    }
36
37
    /**
38
     * set the parts this name consists of
39
     *
40
     * @param array $parts
41
     * @return $this
42
     */
43
    public function setParts(array $parts): Name
44
    {
45
        $this->parts = $parts;
46
47
        return $this;
48
    }
49
50
    /**
51
     * get the parts this name consists of
52
     *
53
     * @return array
54
     */
55
    public function getParts(): array
56
    {
57
        return $this->parts;
58
    }
59
60
    /**
61
     * @param bool $format
62
     * @return array
63
     */
64
    public function getAll(bool $format = false): array
65
    {
66
        $results = [];
67
        $keys = [
68
            'salutation' => [],
69
            'title' => [],
70
            'firstname' => [],
71
            'nickname' => [$format],
72
            'middlename' => [],
73
            'initials' => [],
74
            'extension' => [],
75
            'lastname' => [],
76
            'suffix' => [],
77
            'company' => [],
78
        ];
79
80
        foreach ($keys as $key => $args) {
81
            $method = sprintf('get%s', ucfirst($key));
82
            if ($value = call_user_func_array(array($this, $method), $args)) {
83
                $results[$key] = $value;
84
            };
85
        }
86
87
        return $results;
88
    }
89
90
    /**
91
     * get the given name (first name, middle names and initials)
92
     * in the order they were entered while still applying normalisation
93
     *
94
     * @return string
95
     */
96
    public function getGivenName(): string
97
    {
98
        return $this->export('GivenNamePart');
99
    }
100
101
    /**
102
     * get the given name followed by the last name (including any prefixes)
103
     *
104
     * @return string
105
     */
106
    public function getFullName(): string
107
    {
108
        return sprintf('%s %s', $this->getGivenName(), $this->getLastname());
109
    }
110
111
    /**
112
     * get the first name
113
     *
114
     * @return string
115
     */
116
    public function getFirstname(): string
117
    {
118
        return $this->export('Firstname');
119
    }
120
121
    /**
122
     * get the last name
123
     *
124
     * @param bool $pure
125
     * @return string
126
     */
127
    public function getLastname(bool $pure = false): string
128
    {
129
        return $this->export('Lastname', $pure);
130
    }
131
132
    /**
133
     * get the last name prefix
134
     *
135
     * @return string
136
     */
137
    public function getLastnamePrefix(): string
138
    {
139
        return $this->export('LastnamePrefix');
140
    }
141
142
    /**
143
     * get the initials
144
     *
145
     * @return string
146
     */
147
    public function getInitials(): string
148
    {
149
        return $this->export('Initial');
150
    }
151
152
    /**
153
     * get the suffix(es)
154
     *
155
     * @return string
156
     */
157
    public function getSuffix(): string
158
    {
159
        return $this->export('Suffix');
160
    }
161
162
    /**
163
     * get the salutation(s)
164
     *
165
     * @return string
166
     */
167
    public function getSalutation(): string
168
    {
169
        return $this->export('Salutation');
170
    }
171
172
    /**
173
     * get the nick name(s)
174
     *
175
     * @param bool $wrap
176
     * @return string
177
     */
178
    public function getNickname(bool $wrap = false): string
179
    {
180
        if ($wrap) {
181
            return sprintf('(%s)', $this->export('Nickname'));
182
        }
183
184
        return $this->export('Nickname');
185
    }
186
187
    /**
188
     * get the middle name(s)
189
     *
190
     * @return string
191
     */
192
    public function getMiddlename(): string
193
    {
194
        return $this->export('Middlename');
195
    }
196
197
    /**
198
     * get the company
199
     *
200
     * @return string
201
     */
202
    public function getCompany(): string
203
    {
204
        return $this->export('Company');
205
    }
206
207
    /**
208
     * get the extension
209
     *
210
     * @return string
211
     */
212
    public function getExtension(): string
213
    {
214
        return $this->export('Extension');
215
    }
216
217
    /**
218
     * get the titles(s)
219
     *
220
     * @return string
221
     */
222
    public function getTitle(): string
223
    {
224
        return $this->export('Title');
225
    }
226
227
    /**
228
     * get an array with well formated names and their separators,
229
     * where the keys are representing vCard properties
230
     * see: https://tools.ietf.org/html/rfc6350#section-6.2.2
231
     *
232
     * @return array
233
     */
234
    public function getVCardArray(): array
235
    {
236
        return [
237
            'FN' => implode(' ', array_diff_key($this->getAll(), [
238
                'nickname' => $this->getNickname(),     // fullname with stripped off nickname
239
                ])),
240
            'N' => implode(';', array_filter([          // RFC6350: five segments in sequence:
241
                $this->getLastname(true),               // 1. Family Names (also known as surnames)
242
                $this->getFirstname(),                  // 2. Given Names
243
                implode(',', array_filter([             // 3. Additional Names
244
                    str_replace(' ', ',', $this->getMiddlename()),
245
                    $this->getInitials(),
246
                ])),
247
                implode(',', array_filter([             // 4. Honorific Prefixes
248
                    $this->getSalutation(),
249
                    $this->getTitle(),
250
                ])),
251
                implode(',', array_filter([             // 5. Honorific Suffixes
252
                    $this->getExtension(),
253
                    $this->getLastnamePrefix(),
254
                    $this->getSuffix(),
255
                ])),
256
            ])),
257
            'NICKNAME' => $this->getNickname(),
258
            'ORG'      => $this->getCompany(),
259
        ];
260
    }
261
262
    /**
263
     * helper method used by getters to extract and format relevant name parts
264
     *
265
     * @param string $type
266
     * @param bool $strict
267
     * @return string
268
     */
269
    protected function export(string $type, bool $strict = false): string
270
    {
271
        $matched = [];
272
273
        foreach ($this->parts as $part) {
274
            if ($part instanceof AbstractPart && $this->isType($part, $type, $strict)) {
275
                $matched[] = $part->normalize();
276
            }
277
        }
278
279
        return implode(' ',  $matched);
280
    }
281
282
    /**
283
     * helper method to check if a part is of the given type
284
     *
285
     * @param AbstractPart $part
286
     * @param string $type
287
     * @param bool $strict
288
     * @return bool
289
     */
290
    protected function isType(AbstractPart $part, string $type, bool $strict = false): bool
291
    {
292
        $className = sprintf('%s\\%s', self::PARTS_NAMESPACE, $type);
293
294
        if ($strict) {
295
            return get_class($part) === $className;
296
        }
297
298
        return is_a($part, $className);
299
    }
300
}
301