xref: /webtrees/app/SurnameTradition/DefaultSurnameTradition.php (revision c5b48766684db09f7f8372612300a247ec6929e4)
1<?php
2
3/**
4 * webtrees: online genealogy
5 * Copyright (C) 2022 webtrees development team
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <https://www.gnu.org/licenses/>.
16 */
17
18declare(strict_types=1);
19
20namespace Fisharebest\Webtrees\SurnameTradition;
21
22use Fisharebest\Webtrees\Fact;
23use Fisharebest\Webtrees\Individual;
24
25use function array_filter;
26use function array_keys;
27use function array_map;
28use function implode;
29use function in_array;
30
31/**
32 * All family members keep their original surname
33 */
34class DefaultSurnameTradition implements SurnameTraditionInterface
35{
36    /** Extract a GIVN from a NAME */
37    protected const REGEX_GIVN = '~^(?<GIVN>[^/ ]+)~';
38
39    /** Extract a SPFX and SURN from a NAME */
40    protected const REGEX_SPFX_SURN = '~(?<NAME>/(?<SPFX>[a-z’\']{0,4}(?: [a-z’\']{1,4})*) ?(?<SURN>[^/]*)/)~';
41
42    /** Extract a simple SURN from a NAME */
43    protected const REGEX_SURN = '~(?<NAME>/(?<SURN>[^/]+)/)~';
44
45    /** Extract two Spanish/Portuguese SURNs from a NAME */
46    protected const REGEX_SURNS = '~/(?<SURN1>[^ /]+)(?: | y |/ /|/ y /)(?<SURN2>[^ /]+)/~';
47
48    /**
49     * A default/empty name
50     *
51     * @return string
52     */
53    public function defaultName(): string
54    {
55        return '//';
56    }
57
58    /**
59     * What name is given to a new child
60     *
61     * @param Individual|null $father
62     * @param Individual|null $mother
63     * @param string          $sex
64     *
65     * @return array<int,string>
66     */
67    public function newChildNames(?Individual $father, ?Individual $mother, string $sex): array
68    {
69        return [
70            $this->buildName('//', ['TYPE' => 'birth']),
71        ];
72    }
73
74    /**
75     * What name is given to a new parent
76     *
77     * @param Individual $child
78     * @param string     $sex
79     *
80     * @return array<int,string>
81     */
82    public function newParentNames(Individual $child, string $sex): array
83    {
84        return [
85            $this->buildName('//', ['TYPE' => 'birth']),
86        ];
87    }
88
89    /**
90     * What names are given to a new spouse
91     *
92     * @param Individual $spouse
93     * @param string     $sex
94     *
95     * @return array<int,string>
96     */
97    public function newSpouseNames(Individual $spouse, string $sex): array
98    {
99        return [
100            $this->buildName('//', ['TYPE' => 'birth']),
101        ];
102    }
103
104    /**
105     * Build a GEDCOM name record
106     *
107     * @param string               $name
108     * @param array<string,string> $parts
109     *
110     * @return string
111     */
112    protected function buildName(string $name, array $parts): string
113    {
114        $parts = array_filter($parts);
115
116        $parts = array_map(
117            static fn (string $tag, string $value): string => "\n2 " . $tag . ' ' . $value,
118            array_keys($parts),
119            $parts
120        );
121
122        if ($name === '') {
123            return '1 NAME' . implode($parts);
124        }
125
126        return '1 NAME ' . $name . implode($parts);
127    }
128
129    /**
130     * Extract an individual's name.
131     *
132     * @param Individual|null $individual
133     *
134     * @return string
135     */
136    protected function extractName(?Individual $individual): string
137    {
138        if ($individual instanceof Individual) {
139            $fact = $individual
140                ->facts(['NAME'])
141                ->first(fn (Fact $fact): bool => in_array($fact->attribute('TYPE'), ['', 'birth', 'change'], true));
142
143            if ($fact instanceof Fact) {
144                return $fact->value();
145            }
146        }
147
148        return '';
149    }
150}
151