Completed
Pull Request — master (#3)
by Andre
06:23
created

LastnameMapper::isPrefix()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 1
1
<?php
2
3
namespace TheIconic\NameParser\Mapper;
4
5
use TheIconic\NameParser\LanguageInterface;
6
use TheIconic\NameParser\Part\AbstractPart;
7
use TheIconic\NameParser\Part\Lastname;
8
use TheIconic\NameParser\Part\LastnamePrefix;
9
use TheIconic\NameParser\Part\Suffix;
10
11
class LastnameMapper extends AbstractMapper
12
{
13
    protected $prefixes = [];
14
15
    protected $matchSinglePart = false;
16
17
    public function __construct(array $prefixes, bool $matchSinglePart = false)
18
    {
19
        $this->prefixes = $prefixes;
20
        $this->matchSinglePart = $matchSinglePart;
21
    }
22
23
    /**
24
     * map lastnames in the parts array
25
     *
26
     * @param array $parts the name parts
27
     * @return array the mapped parts
28
     */
29
    public function map(array $parts): array
30
    {
31
        if (!$this->matchSinglePart && count($parts) < 2) {
32
            return $parts;
33
        }
34
35
        $parts = array_reverse($parts);
36
37
        $parts = $this->mapReversedParts($parts);
38
39
        return array_reverse($parts);
40
    }
41
42
    /**
43
     * @param array $parts
44
     * @return array
45
     */
46
    protected function mapReversedParts(array $parts): array
47
    {
48
        $length = count($parts);
49
50
        foreach ($parts as $k => $part) {
51
            if ($part instanceof Suffix) {
52
                continue;
53
            }
54
55
            if ($part instanceof AbstractPart) {
56
                break;
57
            }
58
59
            $originalIndex = $length - $k - 1;
60
            $originalParts = array_reverse($parts);
61
62
            if ($this->isFollowedByLastnamePart($originalParts, $originalIndex)) {
63
                if ($this->isApplicablePrefix($originalParts, $originalIndex)) {
64
                    $parts[$k] = new LastnamePrefix($part, $this->prefixes[$this->getKey($part)]);
65
                    continue;
66
                }
67
                break;
68
            }
69
70
            $parts[$k] = new Lastname($part);
71
        }
72
73
        return $parts;
74
    }
75
76
    /**
77
     * @param array $parts
78
     * @param int $index
79
     * @return bool
80
     */
81
    protected function isFollowedByLastnamePart(array $parts, int $index): bool
82
    {
83
        $next = $index + 1;
84
85
        return (isset($parts[$next]) && $parts[$next] instanceof Lastname);
86
    }
87
88
    /**
89
     * Assuming that the part at the given index is matched as a prefix,
90
     * determines if the prefix should be applied to the lastname.
91
     *
92
     * We only apply it to the lastname if we already have at least one
93
     * lastname part and there are other parts left in
94
     * the name (this effectively prioritises firstname over prefix matching).
95
     *
96
     * This expects the parts array and index to be in the original order.
97
     *
98
     * @param array $parts
99
     * @param int $index
100
     * @return bool
101
     */
102
    protected function isApplicablePrefix(array $parts, int $index): bool
103
    {
104
        if (!$this->isPrefix($parts[$index])) {
105
            return false;
106
        }
107
108
        return $this->hasUnmappedPartsBefore($parts, $index);
109
    }
110
111
    /**
112
     * check if the given word is a lastname prefix
113
     *
114
     * @param string $word the word to check
115
     * @return bool
116
     */
117
    protected function isPrefix($word): bool
118
    {
119
        return (array_key_exists($this->getKey($word), $this->prefixes));
120
    }
121
}
122