xref: /webtrees/app/Module/LanguageEnglishUnitedStates.php (revision 5bfc689774bb9a6401271c4ed15a6d50652c991b)
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\Module;
21
22use Fisharebest\Localization\Locale\LocaleEnUs;
23use Fisharebest\Localization\Locale\LocaleInterface;
24use Fisharebest\Webtrees\Relationship;
25
26use function abs;
27use function min;
28use function str_repeat;
29
30/**
31 * Class LanguageEnglishUnitedStates.
32 */
33class LanguageEnglishUnitedStates extends AbstractModule implements ModuleLanguageInterface
34{
35    use ModuleLanguageTrait;
36
37    protected const COUSIN = [
38        'sibling',
39        'first cousin',
40        'second cousin',
41        'third cousin',
42        'fourth cousin',
43        'fifth cousin',
44        'sixth cousin',
45        'seventh cousin',
46        'eighth cousin',
47        'ninth cousin',
48        'tenth cousin',
49        'eleventh cousin',
50        'twelfth cousin',
51        'thirteenth cousin',
52        'fourteenth cousin',
53        'fifteenth cousin',
54        'sixteenth cousin',
55        'seventeenth cousin',
56        'eighteenth cousin',
57        'nineteenth cousin',
58        'twentieth cousin',
59        'twenty-first cousin',
60        'twenty-second cousin',
61        'twenty-third cousin',
62        'twenty-fourth cousin',
63        'twenty-fifth cousin',
64        'twenty-sixth cousin',
65        'twenty-seventh cousin',
66        'twenty-eighth cousin',
67        'twenty-ninth cousin',
68        'thirtieth cousin',
69    ];
70
71    protected const REMOVED = [
72        '',
73        ' once removed',
74        ' twice removed',
75        ' three times removed',
76        ' four times removed',
77        ' five times removed',
78        ' six times removed',
79        ' seven times removed',
80        ' eight times removed',
81        ' nine times removed',
82        ' ten times removed',
83        ' eleven removed',
84        ' twelve removed',
85        ' thirteen removed',
86        ' fourteen times removed',
87        ' fifteen times removed',
88        ' sixteen times removed',
89        ' seventeen times removed',
90        ' eighteen times removed',
91        ' nineteen times removed',
92        ' twenty times removed',
93        ' twenty-one times removed',
94        ' twenty-two times removed',
95        ' twenty-three times removed',
96        ' twenty-four times removed',
97        ' twenty-five times removed',
98        ' twenty-six times removed',
99        ' twenty-seven times removed',
100        ' twenty-eight times removed',
101        ' twenty-nine times removed',
102    ];
103
104    protected const DIRECTION = [
105        -1 => ' descending',
106        0  => '',
107        1  => ' ascending',
108    ];
109
110    public function locale(): LocaleInterface
111    {
112        return new LocaleEnUs();
113    }
114
115    /**
116     * @return array<Relationship>
117     */
118    public function relationships(): array
119    {
120        // Genitive forms in English are simple/regular, as no relationship name ends in "s".
121        $genitive = static fn (string $s): array => [$s, $s . '’s %s'];
122
123        $cousin = fn (int $up, int $down): array => $genitive(
124            (static::COUSIN[min($up, $down)] ?? 'distant cousin') .
125            (static::REMOVED[abs($up - $down)] ?? ' many times removed') .
126            static::DIRECTION[$up <=> $down]
127        );
128
129        $great = static fn (int $n, string $prefix, string $suffix): array => $genitive(
130            $prefix . ($n > 3 ? 'great ×' . $n . ' ' : str_repeat('great-', $n)) . $suffix
131        );
132
133        return [
134            // Adopted
135            Relationship::fixed('adoptive-mother', 'adoptive-mother’s %s')->adoptive()->mother(),
136            Relationship::fixed('adoptive-father', 'adoptive-father’s %s')->adoptive()->father(),
137            Relationship::fixed('adoptive-parent', 'adoptive-parent’s %s')->adoptive()->parent(),
138            Relationship::fixed('adopted-daughter', 'adopted-daughter’s %s')->adopted()->daughter(),
139            Relationship::fixed('adopted-son', 'adopted-son’s %s')->adopted()->son(),
140            Relationship::fixed('adopted-child', 'adopted-child’s %s')->adopted()->child(),
141            // Fostered
142            Relationship::fixed('foster-mother', 'foster-mother’s %s')->fostering()->mother(),
143            Relationship::fixed('foster-father', 'foster-father’s %s')->fostering()->father(),
144            Relationship::fixed('foster-parent', 'foster-parent’s %s')->fostering()->parent(),
145            Relationship::fixed('foster-daughter', 'foster-daughter’s %s')->fostered()->daughter(),
146            Relationship::fixed('foster-son', 'foster-son’s %s')->fostered()->son(),
147            Relationship::fixed('foster-child', 'foster-child’s %s')->fostered()->child(),
148            // Parents
149            Relationship::fixed('mother', 'mother’s %s')->mother(),
150            Relationship::fixed('father', 'father’s %s')->father(),
151            Relationship::fixed('parent', 'parent’s %s')->parent(),
152            // Children
153            Relationship::fixed('daughter', 'daughter’s %s')->daughter(),
154            Relationship::fixed('son', 'son’s %s')->son(),
155            Relationship::fixed('child', 'child’s %s')->child(),
156            // Siblings
157            Relationship::fixed('twin sister', 'twin sister’s %s')->twin()->sister(),
158            Relationship::fixed('twin brother', 'twin brother’s %s')->twin()->brother(),
159            Relationship::fixed('twin sibling', 'twin sibling’s %s')->twin()->sibling(),
160            Relationship::fixed('elder sister', 'elder sister’s %s')->older()->sister(),
161            Relationship::fixed('elder brother', 'elder brother’s %s')->older()->brother(),
162            Relationship::fixed('elder sibling', 'elder sibling’s %s')->older()->sibling(),
163            Relationship::fixed('younger sister', 'younger sister’s %s')->younger()->sister(),
164            Relationship::fixed('younger brother', 'younger brother’s %s')->younger()->brother(),
165            Relationship::fixed('younger sibling', 'younger sibling’s %s')->younger()->sibling(),
166            Relationship::fixed('sister', 'sister’s %s')->sister(),
167            Relationship::fixed('brother', 'brother’s %s')->brother(),
168            Relationship::fixed('sibling', 'sibling’s %s')->sibling(),
169            // Half-siblings
170            Relationship::fixed('half-sister', 'half-sister’s %s')->parent()->daughter(),
171            Relationship::fixed('half-brother', 'half-brother’s %s')->parent()->son(),
172            Relationship::fixed('half-sibling', 'half-sibling’s %s')->parent()->child(),
173            // Stepfamily
174            Relationship::fixed('stepmother', 'stepmother’s %s')->parent()->wife(),
175            Relationship::fixed('stepfather', 'stepfather’s %s')->parent()->husband(),
176            Relationship::fixed('stepparent', 'stepparent’s %s')->parent()->married()->spouse(),
177            Relationship::fixed('stepdaughter', 'stepdaughter’s %s')->married()->spouse()->daughter(),
178            Relationship::fixed('stepson', 'stepson’s %s')->married()->spouse()->son(),
179            Relationship::fixed('stepchild', 'stepchild’s %s')->married()->spouse()->child(),
180            Relationship::fixed('stepsister', 'stepsister’s %s')->parent()->spouse()->daughter(),
181            Relationship::fixed('stepbrother', 'stepbrother’s %s')->parent()->spouse()->son(),
182            Relationship::fixed('stepsibling', 'stepsibling’s %s')->parent()->spouse()->child(),
183            // Partners
184            Relationship::fixed('ex-wife', 'ex-wife’s %s')->divorced()->partner()->female(),
185            Relationship::fixed('ex-husband', 'ex-husband’s %s')->divorced()->partner()->male(),
186            Relationship::fixed('ex-spouse', 'ex-spouse’s %s')->divorced()->partner(),
187            Relationship::fixed('fiancée', 'fiancée’s %s')->engaged()->partner()->female(),
188            Relationship::fixed('fiancé', 'fiancé’s %s')->engaged()->partner()->male(),
189            Relationship::fixed('wife', 'wife’s %s')->wife(),
190            Relationship::fixed('husband', 'husband’s %s')->husband(),
191            Relationship::fixed('spouse', 'spouse’s %s')->spouse(),
192            Relationship::fixed('partner', 'partner’s %s')->partner(),
193            // In-laws
194            Relationship::fixed('mother-in-law', 'mother-in-law’s %s')->married()->spouse()->mother(),
195            Relationship::fixed('father-in-law', 'father-in-law’s %s')->married()->spouse()->father(),
196            Relationship::fixed('parent-in-law', 'parent-in-law’s %s')->married()->spouse()->parent(),
197            Relationship::fixed('daughter-in-law', 'daughter-in-law’s %s')->child()->wife(),
198            Relationship::fixed('son-in-law', 'son-in-law’s %s')->child()->husband(),
199            Relationship::fixed('child-in-law', 'child-in-law’s %s')->child()->married()->spouse(),
200            Relationship::fixed('sister-in-law', 'sister-in-law’s %s')->sibling()->spouse()->sister(),
201            Relationship::fixed('brother-in-law', 'brother-in-law’s %s')->sibling()->spouse()->brother(),
202            Relationship::fixed('sibling-in-law', 'sibling-in-law’s %s')->sibling()->spouse()->sibling(),
203            Relationship::fixed('sister-in-law', 'sister-in-law’s %s')->spouse()->sister(),
204            Relationship::fixed('brother-in-law', 'brother-in-law’s %s')->spouse()->brother(),
205            Relationship::fixed('sibling-in-law', 'sibling-in-law’s %s')->spouse()->sibling(),
206            Relationship::fixed('sister-in-law', 'sister-in-law’s %s')->sibling()->wife(),
207            Relationship::fixed('brother-in-law', 'brother-in-law’s %s')->sibling()->husband(),
208            Relationship::fixed('sibling-in-law', 'sibling-in-law’s %s')->sibling()->spouse(),
209            // Grandparents
210            Relationship::fixed('maternal-grandmother', 'maternal-grandmother’s %s')->mother()->mother(),
211            Relationship::fixed('maternal-grandfather', 'maternal-grandfather’s %s')->mother()->father(),
212            Relationship::fixed('maternal-grandparent', 'maternal-grandfather’s %s')->mother()->parent(),
213            Relationship::fixed('paternal-grandmother', 'paternal-grandmother’s %s')->father()->mother(),
214            Relationship::fixed('paternal-grandfather', 'paternal-grandfather’s %s')->father()->father(),
215            Relationship::fixed('paternal-grandparent', 'paternal-grandfather’s %s')->father()->parent(),
216            Relationship::fixed('grandmother', 'grandmother’s %s')->parent()->mother(),
217            Relationship::fixed('grandfather', 'grandfather’s %s')->parent()->father(),
218            Relationship::fixed('grandparent', 'grandparent’s %s')->parent()->parent(),
219            // Grandchildren
220            Relationship::fixed('granddaughter', 'granddaughter’s %s')->child()->daughter(),
221            Relationship::fixed('grandson', 'grandson’s %s')->child()->son(),
222            Relationship::fixed('grandchild', 'grandchild’s %s')->child()->child(),
223            // Relationships with dynamically generated names
224            Relationship::dynamic(fn (int $n) => $great($n - 1, '', 'aunt'))->ancestor()->sister(),
225            Relationship::dynamic(fn (int $n) => $great($n - 1, '', 'aunt'))->ancestor()->sibling()->wife(),
226            Relationship::dynamic(fn (int $n) => $great($n - 1, '', 'uncle'))->ancestor()->brother(),
227            Relationship::dynamic(fn (int $n) => $great($n - 1, '', 'uncle'))->ancestor()->sibling()->husband(),
228            Relationship::dynamic(fn (int $n) => $great($n - 1, '', 'niece'))->sibling()->descendant()->female(),
229            Relationship::dynamic(fn (int $n) => $great($n - 1, '', 'niece'))->married()->spouse()->sibling()->descendant()->female(),
230            Relationship::dynamic(fn (int $n) => $great($n - 1, '', 'nephew'))->sibling()->descendant()->male(),
231            Relationship::dynamic(fn (int $n) => $great($n - 1, '', 'nephew'))->married()->spouse()->sibling()->descendant()->male(),
232            Relationship::dynamic(fn (int $n) => $great($n - 2, 'maternal ', 'grandmother'))->mother()->ancestor()->female(),
233            Relationship::dynamic(fn (int $n) => $great($n - 1, 'maternal ', 'grandfather'))->mother()->ancestor()->male(),
234            Relationship::dynamic(fn (int $n) => $great($n - 1, 'paternal ', 'grandmother'))->father()->ancestor()->female(),
235            Relationship::dynamic(fn (int $n) => $great($n - 1, 'paternal ', 'grandfather'))->father()->ancestor()->male(),
236            Relationship::dynamic(fn (int $n) => $great($n - 1, '', 'grandparent'))->ancestor(),
237            Relationship::dynamic(fn (int $n) => $great($n - 2, '', 'granddaughter'))->descendant()->female(),
238            Relationship::dynamic(fn (int $n) => $great($n - 2, '', 'grandson'))->descendant()->male(),
239            Relationship::dynamic(fn (int $n) => $great($n - 2, '', 'grandchild'))->descendant(),
240            Relationship::dynamic($cousin)->ancestor()->sibling()->descendant(),
241        ];
242    }
243}
244