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