1323788f4SGreg Roach<?php 23976b470SGreg Roach 3323788f4SGreg Roach/** 4323788f4SGreg Roach * webtrees: online genealogy 5d11be702SGreg Roach * Copyright (C) 2023 webtrees development team 6323788f4SGreg Roach * This program is free software: you can redistribute it and/or modify 7323788f4SGreg Roach * it under the terms of the GNU General Public License as published by 8323788f4SGreg Roach * the Free Software Foundation, either version 3 of the License, or 9323788f4SGreg Roach * (at your option) any later version. 10323788f4SGreg Roach * This program is distributed in the hope that it will be useful, 11323788f4SGreg Roach * but WITHOUT ANY WARRANTY; without even the implied warranty of 12323788f4SGreg Roach * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13323788f4SGreg Roach * GNU General Public License for more details. 14323788f4SGreg Roach * You should have received a copy of the GNU General Public License 1589f7189bSGreg Roach * along with this program. If not, see <https://www.gnu.org/licenses/>. 16323788f4SGreg Roach */ 17fcfa147eSGreg Roach 18e7f56f2aSGreg Roachdeclare(strict_types=1); 19e7f56f2aSGreg Roach 20323788f4SGreg Roachnamespace Fisharebest\Webtrees\SurnameTradition; 21323788f4SGreg Roach 227c29ac65SGreg Roachuse Fisharebest\Webtrees\Elements\NameType; 23cb7a42eaSGreg Roachuse Fisharebest\Webtrees\Fact; 247e128bbfSGreg Roachuse Fisharebest\Webtrees\I18N; 25cb7a42eaSGreg Roachuse Fisharebest\Webtrees\Individual; 26cb7a42eaSGreg Roach 27cb7a42eaSGreg Roachuse function array_filter; 28cb7a42eaSGreg Roachuse function array_keys; 29cb7a42eaSGreg Roachuse function array_map; 30cb7a42eaSGreg Roachuse function implode; 31cb7a42eaSGreg Roachuse function in_array; 32cb7a42eaSGreg Roach 33323788f4SGreg Roach/** 34323788f4SGreg Roach * All family members keep their original surname 35323788f4SGreg Roach */ 36c1010edaSGreg Roachclass DefaultSurnameTradition implements SurnameTraditionInterface 37c1010edaSGreg Roach{ 38323788f4SGreg Roach /** Extract a GIVN from a NAME */ 3916d6367aSGreg Roach protected const REGEX_GIVN = '~^(?<GIVN>[^/ ]+)~'; 40323788f4SGreg Roach 41323788f4SGreg Roach /** Extract a SPFX and SURN from a NAME */ 4216d6367aSGreg Roach protected const REGEX_SPFX_SURN = '~(?<NAME>/(?<SPFX>[a-z’\']{0,4}(?: [a-z’\']{1,4})*) ?(?<SURN>[^/]*)/)~'; 43323788f4SGreg Roach 44323788f4SGreg Roach /** Extract a simple SURN from a NAME */ 4516d6367aSGreg Roach protected const REGEX_SURN = '~(?<NAME>/(?<SURN>[^/]+)/)~'; 46323788f4SGreg Roach 47323788f4SGreg Roach /** Extract two Spanish/Portuguese SURNs from a NAME */ 4816d6367aSGreg Roach protected const REGEX_SURNS = '~/(?<SURN1>[^ /]+)(?: | y |/ /|/ y /)(?<SURN2>[^ /]+)/~'; 49323788f4SGreg Roach 50323788f4SGreg Roach /** 517e128bbfSGreg Roach * The name of this surname tradition 527e128bbfSGreg Roach * 537e128bbfSGreg Roach * @return string 547e128bbfSGreg Roach */ 557e128bbfSGreg Roach public function name(): string 567e128bbfSGreg Roach { 577e128bbfSGreg Roach return I18N::translateContext('Surname tradition', 'none'); 587e128bbfSGreg Roach } 597e128bbfSGreg Roach 607e128bbfSGreg Roach /** 617e128bbfSGreg Roach * A short description of this surname tradition 627e128bbfSGreg Roach * 637e128bbfSGreg Roach * @return string 647e128bbfSGreg Roach */ 657e128bbfSGreg Roach public function description(): string 667e128bbfSGreg Roach { 677e128bbfSGreg Roach return ''; 687e128bbfSGreg Roach } 697e128bbfSGreg Roach 707e128bbfSGreg Roach /** 71a171b6a5SGreg Roach * A default/empty name 72323788f4SGreg Roach * 73a171b6a5SGreg Roach * @return string 74323788f4SGreg Roach */ 75a171b6a5SGreg Roach public function defaultName(): string 76c1010edaSGreg Roach { 77a171b6a5SGreg Roach return '//'; 78c1ec7145SGreg Roach } 79c1ec7145SGreg Roach 80c1ec7145SGreg Roach /** 81cb7a42eaSGreg Roach * What name is given to a new child 82323788f4SGreg Roach * 83cb7a42eaSGreg Roach * @param Individual|null $father 84cb7a42eaSGreg Roach * @param Individual|null $mother 85cb7a42eaSGreg Roach * @param string $sex 86323788f4SGreg Roach * 8701ffdfd0SGreg Roach * @return array<int,string> 88323788f4SGreg Roach */ 89*1ff45046SGreg Roach public function newChildNames(Individual|null $father, Individual|null $mother, string $sex): array 90c1010edaSGreg Roach { 9113abd6f3SGreg Roach return [ 9288a03560SGreg Roach $this->buildName('//', ['TYPE' => NameType::VALUE_BIRTH]), 9313abd6f3SGreg Roach ]; 94323788f4SGreg Roach } 95323788f4SGreg Roach 96323788f4SGreg Roach /** 97cb7a42eaSGreg Roach * What name is given to a new parent 98323788f4SGreg Roach * 99cb7a42eaSGreg Roach * @param Individual $child 100cb7a42eaSGreg Roach * @param string $sex 101323788f4SGreg Roach * 10201ffdfd0SGreg Roach * @return array<int,string> 103323788f4SGreg Roach */ 104cb7a42eaSGreg Roach public function newParentNames(Individual $child, string $sex): array 105c1010edaSGreg Roach { 10613abd6f3SGreg Roach return [ 10788a03560SGreg Roach $this->buildName('//', ['TYPE' => NameType::VALUE_BIRTH]), 10813abd6f3SGreg Roach ]; 109323788f4SGreg Roach } 110323788f4SGreg Roach 111323788f4SGreg Roach /** 112323788f4SGreg Roach * What names are given to a new spouse 113323788f4SGreg Roach * 114cb7a42eaSGreg Roach * @param Individual $spouse 115cb7a42eaSGreg Roach * @param string $sex 116323788f4SGreg Roach * 11701ffdfd0SGreg Roach * @return array<int,string> 118323788f4SGreg Roach */ 119cb7a42eaSGreg Roach public function newSpouseNames(Individual $spouse, string $sex): array 120c1010edaSGreg Roach { 12113abd6f3SGreg Roach return [ 12288a03560SGreg Roach $this->buildName('//', ['TYPE' => NameType::VALUE_BIRTH]), 12313abd6f3SGreg Roach ]; 124323788f4SGreg Roach } 125cb7a42eaSGreg Roach 126cb7a42eaSGreg Roach /** 127cb7a42eaSGreg Roach * Build a GEDCOM name record 128cb7a42eaSGreg Roach * 129cb7a42eaSGreg Roach * @param string $name 130cb7a42eaSGreg Roach * @param array<string,string> $parts 131cb7a42eaSGreg Roach * 132cb7a42eaSGreg Roach * @return string 133cb7a42eaSGreg Roach */ 134cb7a42eaSGreg Roach protected function buildName(string $name, array $parts): string 135cb7a42eaSGreg Roach { 136cb7a42eaSGreg Roach $parts = array_filter($parts); 137cb7a42eaSGreg Roach 138cb7a42eaSGreg Roach $parts = array_map( 13905babb96SGreg Roach static fn (string $tag, string $value): string => "\n2 " . $tag . ' ' . $value, 140cb7a42eaSGreg Roach array_keys($parts), 141cb7a42eaSGreg Roach $parts 142cb7a42eaSGreg Roach ); 143cb7a42eaSGreg Roach 144cb7a42eaSGreg Roach if ($name === '') { 145cb7a42eaSGreg Roach return '1 NAME' . implode($parts); 146cb7a42eaSGreg Roach } 147cb7a42eaSGreg Roach 148cb7a42eaSGreg Roach return '1 NAME ' . $name . implode($parts); 149cb7a42eaSGreg Roach } 150cb7a42eaSGreg Roach 151cb7a42eaSGreg Roach /** 152cb7a42eaSGreg Roach * Extract an individual's name. 153cb7a42eaSGreg Roach * 154cb7a42eaSGreg Roach * @param Individual|null $individual 155cb7a42eaSGreg Roach * 156cb7a42eaSGreg Roach * @return string 157cb7a42eaSGreg Roach */ 158*1ff45046SGreg Roach protected function extractName(Individual|null $individual): string 159cb7a42eaSGreg Roach { 160cb7a42eaSGreg Roach if ($individual instanceof Individual) { 161cb7a42eaSGreg Roach $fact = $individual 162cb7a42eaSGreg Roach ->facts(['NAME']) 16388a03560SGreg Roach ->first(fn (Fact $fact): bool => in_array($fact->attribute('TYPE'), ['', NameType::VALUE_BIRTH, NameType::VALUE_CHANGE], true)); 164cb7a42eaSGreg Roach 165cb7a42eaSGreg Roach if ($fact instanceof Fact) { 166cb7a42eaSGreg Roach return $fact->value(); 167cb7a42eaSGreg Roach } 168cb7a42eaSGreg Roach } 169cb7a42eaSGreg Roach 170cb7a42eaSGreg Roach return ''; 171cb7a42eaSGreg Roach } 172323788f4SGreg Roach} 173