Completed
Pull Request — master (#45)
by
unknown
01:16
created

Parser::addCustomSalutations()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 8
rs 10
c 0
b 0
f 0
cc 2
nc 2
nop 1
1
<?php
2
3
namespace TheIconic\NameParser;
4
5
use TheIconic\NameParser\Language\English;
6
use TheIconic\NameParser\Mapper\NicknameMapper;
7
use TheIconic\NameParser\Mapper\SalutationMapper;
8
use TheIconic\NameParser\Mapper\SuffixMapper;
9
use TheIconic\NameParser\Mapper\InitialMapper;
10
use TheIconic\NameParser\Mapper\LastnameMapper;
11
use TheIconic\NameParser\Mapper\FirstnameMapper;
12
use TheIconic\NameParser\Mapper\MiddlenameMapper;
13
14
class Parser
15
{
16
    /**
17
     * @var string
18
     */
19
    protected $whitespace = " \r\n\t";
20
21
    /**
22
     * @var array
23
     */
24
    protected $mappers = [];
25
26
    /**
27
     * @var array
28
     */
29
    protected $languages = [];
30
31
    /**
32
     * @var array
33
     */
34
    protected $nicknameDelimiters = [];
35
36
    /**
37
     * @var array
38
     */
39
    protected $customSalutations = [];
40
41
    /**
42
     * @var int
43
     */
44
    protected $maxSalutationIndex = 0;
45
46
    /**
47
     * @var int
48
     */
49
    protected $maxCombinedInitials = 2;
50
51
    public function __construct(array $languages = [])
52
    {
53
        if (empty($languages)) {
54
            $languages = [new English()];
55
        }
56
57
        $this->languages = $languages;
58
    }
59
60
    /**
61
     * split full names into the following parts:
62
     * - prefix / salutation  (Mr., Mrs., etc)
63
     * - given name / first name
64
     * - middle initials
65
     * - surname / last name
66
     * - suffix (II, Phd, Jr, etc)
67
     *
68
     * @param string $name
69
     * @return Name
70
     */
71
    public function parse($name): Name
72
    {
73
        $name = $this->normalize($name);
74
75
        $segments = explode(',', $name);
76
77
        if (1 < count($segments)) {
78
            return $this->parseSplitName($segments[0], $segments[1], $segments[2] ?? '');
79
        }
80
81
        $parts = explode(' ', $name);
82
83
        foreach ($this->getMappers() as $mapper) {
84
            $parts = $mapper->map($parts);
85
        }
86
87
        return new Name($parts);
88
    }
89
90
    /**
91
     * handles split-parsing of comma-separated name parts
92
     *
93
     * @param $left - the name part left of the comma
94
     * @param $right - the name part right of the comma
95
     *
96
     * @return Name
97
     */
98
    protected function parseSplitName($first, $second, $third): Name
99
    {
100
        $parts = array_merge(
101
            $this->getFirstSegmentParser()->parse($first)->getParts(),
102
            $this->getSecondSegmentParser()->parse($second)->getParts(),
103
            $this->getThirdSegmentParser()->parse($third)->getParts()
104
        );
105
106
        return new Name($parts);
107
    }
108
109
    /**
110
     * @return Parser
111
     */
112 View Code Duplication
    protected function getFirstSegmentParser(): Parser
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
113
    {
114
        $parser = new Parser();
115
116
        $parser->setMappers([
117
            new SalutationMapper($this->getSalutations(), $this->getMaxSalutationIndex()),
118
            new SuffixMapper($this->getSuffixes(), false, 2),
119
            new LastnameMapper($this->getPrefixes(), true),
120
            new FirstnameMapper(),
121
            new MiddlenameMapper(),
122
        ]);
123
124
        return $parser;
125
    }
126
127
    /**
128
     * @return Parser
129
     */
130 View Code Duplication
    protected function getSecondSegmentParser(): Parser
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
131
    {
132
        $parser = new Parser();
133
134
        $parser->setMappers([
135
            new SalutationMapper($this->getSalutations(), $this->getMaxSalutationIndex()),
136
            new SuffixMapper($this->getSuffixes(), true, 1),
137
            new NicknameMapper($this->getNicknameDelimiters()),
138
            new InitialMapper($this->getMaxCombinedInitials(), true),
139
            new FirstnameMapper(),
140
            new MiddlenameMapper(true),
141
        ]);
142
143
        return $parser;
144
    }
145
146
    protected function getThirdSegmentParser(): Parser
147
    {
148
        $parser = new Parser();
149
150
        $parser->setMappers([
151
            new SuffixMapper($this->getSuffixes(), true, 0),
152
        ]);
153
154
        return $parser;
155
    }
156
157
    /**
158
     * get the mappers for this parser
159
     *
160
     * @return array
161
     */
162
    public function getMappers(): array
163
    {
164
        if (empty($this->mappers)) {
165
            $this->setMappers([
166
                new NicknameMapper($this->getNicknameDelimiters()),
167
                new SalutationMapper($this->getSalutations(), $this->getMaxSalutationIndex()),
168
                new SuffixMapper($this->getSuffixes()),
169
                new InitialMapper($this->getMaxCombinedInitials()),
170
                new LastnameMapper($this->getPrefixes()),
171
                new FirstnameMapper(),
172
                new MiddlenameMapper(),
173
            ]);
174
        }
175
176
        return $this->mappers;
177
    }
178
179
    /**
180
     * set the mappers for this parser
181
     *
182
     * @param array $mappers
183
     * @return Parser
184
     */
185
    public function setMappers(array $mappers): Parser
186
    {
187
        $this->mappers = $mappers;
188
189
        return $this;
190
    }
191
192
    /**
193
     * normalize the name
194
     *
195
     * @param string $name
196
     * @return string
197
     */
198
    protected function normalize(string $name): string
199
    {
200
        $whitespace = $this->getWhitespace();
201
202
        $name = trim($name);
203
204
        return preg_replace('/[' . preg_quote($whitespace) . ']+/', ' ', $name);
205
    }
206
207
    /**
208
     * get a string of characters that are supposed to be treated as whitespace
209
     *
210
     * @return string
211
     */
212
    public function getWhitespace(): string
213
    {
214
        return $this->whitespace;
215
    }
216
217
    /**
218
     * set the string of characters that are supposed to be treated as whitespace
219
     *
220
     * @param $whitespace
221
     * @return Parser
222
     */
223
    public function setWhitespace($whitespace): Parser
224
    {
225
        $this->whitespace = $whitespace;
226
227
        return $this;
228
    }
229
230
    /**
231
     * @return array
232
     */
233
    protected function getPrefixes()
234
    {
235
        $prefixes = [];
236
237
        /** @var LanguageInterface $language */
238
        foreach ($this->languages as $language) {
239
            $prefixes += $language->getLastnamePrefixes();
240
        }
241
242
        return $prefixes;
243
    }
244
245
    /**
246
     * @return array
247
     */
248
    protected function getSuffixes()
249
    {
250
        $suffixes = [];
251
252
        /** @var LanguageInterface $language */
253
        foreach ($this->languages as $language) {
254
            $suffixes += $language->getSuffixes();
255
        }
256
257
        return $suffixes;
258
    }
259
260
    /**
261
     * @return array
262
     */
263
    protected function getSalutations()
264
    {
265
        $salutations = [];
266
267
        /** @var LanguageInterface $language */
268
        foreach ($this->languages as $language) {
269
            $salutations += $language->getSalutations();
270
        }
271
        
272
        $salutations += $this->customSalutations;
273
274
        return $salutations;
275
    }
276
277
    /**
278
     * @param array $customSalutations
0 ignored issues
show
Documentation introduced by
There is no parameter named $customSalutations. Did you maybe mean $salutation?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function. It has, however, found a similar but not annotated parameter which might be a good fit.

Consider the following example. The parameter $ireland is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $ireland
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was changed, but the annotation was not.

Loading history...
279
     * @return Parser
280
     */
281
    public function addCustomSalutation(string $key, string $salutation): Parser
282
    {
283
        $this->customSalutations += [$key => $salutation];
284
285
        return $this;
286
    }
287
288
    /**
289
     * @param array $customSalutations
290
     * @return Parser
291
     */
292
    public function addCustomSalutations(array $customSalutations): Parser
293
    {
294
        foreach ($customSalutations as $key => $salutation) {
295
            $this->addCustomSalutation($key, $salutation);
296
        }
297
        
298
        return $this;
299
    }
300
301
    /**
302
     * @return array
303
     */
304
    public function getNicknameDelimiters(): array
305
    {
306
        return $this->nicknameDelimiters;
307
    }
308
309
    /**
310
     * @param array $nicknameDelimiters
311
     * @return Parser
312
     */
313
    public function setNicknameDelimiters(array $nicknameDelimiters): Parser
314
    {
315
        $this->nicknameDelimiters = $nicknameDelimiters;
316
317
        return $this;
318
    }
319
320
    /**
321
     * @return int
322
     */
323
    public function getMaxSalutationIndex(): int
324
    {
325
        return $this->maxSalutationIndex;
326
    }
327
328
    /**
329
     * @param int $maxSalutationIndex
330
     * @return Parser
331
     */
332
    public function setMaxSalutationIndex(int $maxSalutationIndex): Parser
333
    {
334
        $this->maxSalutationIndex = $maxSalutationIndex;
335
336
        return $this;
337
    }
338
339
    /**
340
     * @return int
341
     */
342
    public function getMaxCombinedInitials(): int
343
    {
344
        return $this->maxCombinedInitials;
345
    }
346
347
    /**
348
     * @param int $maxCombinedInitials
349
     * @return Parser
350
     */
351
    public function setMaxCombinedInitials(int $maxCombinedInitials): Parser
352
    {
353
        $this->maxCombinedInitials = $maxCombinedInitials;
354
355
        return $this;
356
    }
357
}
358