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
|
|
|
|
18
|
|
|
declare(strict_types=1); |
19
|
|
|
|
20
|
|
|
namespace Fisharebest\Webtrees\Module; |
21
|
|
|
|
22
|
|
|
use Fisharebest\Webtrees\Auth; |
23
|
|
|
use Fisharebest\Webtrees\Date; |
24
|
|
|
use Fisharebest\Webtrees\Fact; |
25
|
|
|
use Fisharebest\Webtrees\Family; |
26
|
|
|
use Fisharebest\Webtrees\I18N; |
27
|
|
|
use Fisharebest\Webtrees\Individual; |
28
|
|
|
use Fisharebest\Webtrees\Services\ClipboardService; |
29
|
|
|
use Fisharebest\Webtrees\Services\ModuleService; |
30
|
|
|
use Illuminate\Support\Collection; |
31
|
|
|
|
32
|
|
|
use function str_contains; |
33
|
|
|
|
34
|
|
|
/** |
35
|
|
|
* Class IndividualFactsTabModule |
36
|
|
|
*/ |
37
|
|
|
class IndividualFactsTabModule extends AbstractModule implements ModuleTabInterface |
38
|
|
|
{ |
39
|
|
|
use ModuleTabTrait; |
40
|
|
|
|
41
|
|
|
/** @var ModuleService */ |
42
|
|
|
private $module_service; |
43
|
|
|
|
44
|
|
|
/** @var ClipboardService */ |
45
|
|
|
private $clipboard_service; |
46
|
|
|
|
47
|
|
|
/** |
48
|
|
|
* IndividualFactsTabModule constructor. |
49
|
|
|
* |
50
|
|
|
* @param ModuleService $module_service |
51
|
|
|
* @param ClipboardService $clipboard_service |
52
|
|
|
*/ |
53
|
|
|
public function __construct(ModuleService $module_service, ClipboardService $clipboard_service) |
54
|
|
|
{ |
55
|
|
|
$this->module_service = $module_service; |
56
|
|
|
$this->clipboard_service = $clipboard_service; |
57
|
|
|
} |
58
|
|
|
|
59
|
|
|
/** |
60
|
|
|
* How should this module be identified in the control panel, etc.? |
61
|
|
|
* |
62
|
|
|
* @return string |
63
|
|
|
*/ |
64
|
|
|
public function title(): string |
65
|
|
|
{ |
66
|
|
|
/* I18N: Name of a module/tab on the individual page. */ |
67
|
|
|
return I18N::translate('Facts and events'); |
68
|
|
|
} |
69
|
|
|
|
70
|
|
|
/** |
71
|
|
|
* A sentence describing what this module does. |
72
|
|
|
* |
73
|
|
|
* @return string |
74
|
|
|
*/ |
75
|
|
|
public function description(): string |
76
|
|
|
{ |
77
|
|
|
/* I18N: Description of the “Facts and events” module */ |
78
|
|
|
return I18N::translate('A tab showing the facts and events of an individual.'); |
79
|
|
|
} |
80
|
|
|
|
81
|
|
|
/** |
82
|
|
|
* The default position for this tab. It can be changed in the control panel. |
83
|
|
|
* |
84
|
|
|
* @return int |
85
|
|
|
*/ |
86
|
|
|
public function defaultTabOrder(): int |
87
|
|
|
{ |
88
|
|
|
return 1; |
89
|
|
|
} |
90
|
|
|
|
91
|
|
|
/** |
92
|
|
|
* A greyed out tab has no actual content, but may perhaps have |
93
|
|
|
* options to create content. |
94
|
|
|
* |
95
|
|
|
* @param Individual $individual |
96
|
|
|
* |
97
|
|
|
* @return bool |
98
|
|
|
*/ |
99
|
|
|
public function isGrayedOut(Individual $individual): bool |
100
|
|
|
{ |
101
|
|
|
return false; |
102
|
|
|
} |
103
|
|
|
|
104
|
|
|
/** |
105
|
|
|
* Generate the HTML content of this tab. |
106
|
|
|
* |
107
|
|
|
* @param Individual $individual |
108
|
|
|
* |
109
|
|
|
* @return string |
110
|
|
|
*/ |
111
|
|
|
public function getTabContent(Individual $individual): string |
112
|
|
|
{ |
113
|
|
|
// Only include events of close relatives that are between birth and death |
114
|
|
|
$min_date = $individual->getEstimatedBirthDate(); |
115
|
|
|
$max_date = $individual->getEstimatedDeathDate(); |
116
|
|
|
|
117
|
|
|
// Which facts and events are handled by other modules? |
118
|
|
|
$sidebar_facts = $this->module_service |
119
|
|
|
->findByComponent(ModuleSidebarInterface::class, $individual->tree(), Auth::user()) |
120
|
|
|
->map(static function (ModuleSidebarInterface $sidebar): Collection { |
121
|
|
|
return $sidebar->supportedFacts(); |
122
|
|
|
}); |
123
|
|
|
|
124
|
|
|
$tab_facts = $this->module_service |
125
|
|
|
->findByComponent(ModuleTabInterface::class, $individual->tree(), Auth::user()) |
126
|
|
|
->map(static function (ModuleTabInterface $sidebar): Collection { |
127
|
|
|
return $sidebar->supportedFacts(); |
128
|
|
|
}); |
129
|
|
|
|
130
|
|
|
$exclude_facts = $sidebar_facts->merge($tab_facts)->flatten(); |
131
|
|
|
|
132
|
|
|
// The individual’s own facts |
133
|
|
|
$indifacts = $individual->facts() |
134
|
|
|
->filter(static function (Fact $fact) use ($exclude_facts): bool { |
135
|
|
|
return !$exclude_facts->contains($fact->getTag()); |
|
|
|
|
136
|
|
|
}); |
137
|
|
|
|
138
|
|
|
// Add spouse-family facts |
139
|
|
|
foreach ($individual->spouseFamilies() as $family) { |
140
|
|
|
foreach ($family->facts() as $fact) { |
141
|
|
|
if (!$exclude_facts->contains($fact->getTag()) && $fact->getTag() !== 'CHAN') { |
142
|
|
|
$indifacts->push($fact); |
143
|
|
|
} |
144
|
|
|
} |
145
|
|
|
|
146
|
|
|
$spouse = $family->spouse($individual); |
147
|
|
|
|
148
|
|
|
if ($spouse instanceof Individual) { |
149
|
|
|
$spouse_facts = $this->spouseFacts($individual, $spouse, $min_date, $max_date); |
150
|
|
|
$indifacts = $indifacts->merge($spouse_facts); |
151
|
|
|
} |
152
|
|
|
|
153
|
|
|
$child_facts = $this->childFacts($individual, $family, '_CHIL', '', $min_date, $max_date); |
154
|
|
|
$indifacts = $indifacts->merge($child_facts); |
155
|
|
|
} |
156
|
|
|
|
157
|
|
|
$parent_facts = $this->parentFacts($individual, 1, $min_date, $max_date); |
158
|
|
|
$associate_facts = $this->associateFacts($individual); |
159
|
|
|
$historical_facts = $this->historicalFacts($individual); |
160
|
|
|
|
161
|
|
|
$indifacts = $indifacts |
162
|
|
|
->merge($parent_facts) |
163
|
|
|
->merge($associate_facts) |
164
|
|
|
->merge($historical_facts); |
165
|
|
|
|
166
|
|
|
$indifacts = Fact::sortFacts($indifacts); |
167
|
|
|
|
168
|
|
|
return view('modules/personal_facts/tab', [ |
169
|
|
|
'can_edit' => $individual->canEdit(), |
170
|
|
|
'clipboard_facts' => $this->clipboard_service->pastableFacts($individual, new Collection()), |
171
|
|
|
'has_historical_facts' => $historical_facts !== [], |
172
|
|
|
'individual' => $individual, |
173
|
|
|
'facts' => $indifacts, |
174
|
|
|
]); |
175
|
|
|
} |
176
|
|
|
|
177
|
|
|
/** |
178
|
|
|
* Does a relative event occur within a date range (i.e. the individual's lifetime)? |
179
|
|
|
* |
180
|
|
|
* @param Fact $fact |
181
|
|
|
* @param Date $min_date |
182
|
|
|
* @param Date $max_date |
183
|
|
|
* |
184
|
|
|
* @return bool |
185
|
|
|
*/ |
186
|
|
|
private function includeFact(Fact $fact, Date $min_date, Date $max_date): bool |
187
|
|
|
{ |
188
|
|
|
$fact_date = $fact->date(); |
189
|
|
|
|
190
|
|
|
return $fact_date->isOK() && Date::compare($min_date, $fact_date) <= 0 && Date::compare($fact_date, $max_date) <= 0; |
191
|
|
|
} |
192
|
|
|
|
193
|
|
|
/** |
194
|
|
|
* Is this tab empty? If so, we don't always need to display it. |
195
|
|
|
* |
196
|
|
|
* @param Individual $individual |
197
|
|
|
* |
198
|
|
|
* @return bool |
199
|
|
|
*/ |
200
|
|
|
public function hasTabContent(Individual $individual): bool |
201
|
|
|
{ |
202
|
|
|
return true; |
203
|
|
|
} |
204
|
|
|
|
205
|
|
|
/** |
206
|
|
|
* Can this tab load asynchronously? |
207
|
|
|
* |
208
|
|
|
* @return bool |
209
|
|
|
*/ |
210
|
|
|
public function canLoadAjax(): bool |
211
|
|
|
{ |
212
|
|
|
return false; |
213
|
|
|
} |
214
|
|
|
|
215
|
|
|
/** |
216
|
|
|
* Convert an event into a special "event of a close relative". |
217
|
|
|
* |
218
|
|
|
* @param Fact $fact |
219
|
|
|
* @param string $type |
220
|
|
|
* |
221
|
|
|
* @return Fact |
222
|
|
|
*/ |
223
|
|
|
private function convertEvent(Fact $fact, string $type): Fact |
224
|
|
|
{ |
225
|
|
|
$gedcom = $fact->gedcom(); |
226
|
|
|
$gedcom = preg_replace('/\n2 TYPE .*/', '', $gedcom); |
227
|
|
|
$gedcom = preg_replace('/^1 .*/', "1 EVEN CLOSE_RELATIVE\n2 TYPE " . $type, $gedcom); |
228
|
|
|
|
229
|
|
|
$converted = new Fact($gedcom, $fact->record(), $fact->id()); |
230
|
|
|
|
231
|
|
|
if ($fact->isPendingAddition()) { |
232
|
|
|
$converted->setPendingAddition(); |
233
|
|
|
} |
234
|
|
|
|
235
|
|
|
if ($fact->isPendingDeletion()) { |
236
|
|
|
$converted->setPendingDeletion(); |
237
|
|
|
} |
238
|
|
|
|
239
|
|
|
return $converted; |
240
|
|
|
} |
241
|
|
|
|
242
|
|
|
/** |
243
|
|
|
* Spouse facts that are shown on an individual’s page. |
244
|
|
|
* |
245
|
|
|
* @param Individual $individual Show events that occured during the lifetime of this individual |
246
|
|
|
* @param Individual $spouse Show events of this individual |
247
|
|
|
* @param Date $min_date |
248
|
|
|
* @param Date $max_date |
249
|
|
|
* |
250
|
|
|
* @return Fact[] |
251
|
|
|
*/ |
252
|
|
|
private function spouseFacts(Individual $individual, Individual $spouse, Date $min_date, Date $max_date): array |
253
|
|
|
{ |
254
|
|
|
$SHOW_RELATIVES_EVENTS = $individual->tree()->getPreference('SHOW_RELATIVES_EVENTS'); |
255
|
|
|
|
256
|
|
|
$death_of_a_spouse = [ |
257
|
|
|
'DEAT' => [ |
258
|
|
|
'M' => I18N::translate('Death of a husband'), |
259
|
|
|
'F' => I18N::translate('Death of a wife'), |
260
|
|
|
'U' => I18N::translate('Death of a spouse'), |
261
|
|
|
], |
262
|
|
|
'BURI' => [ |
263
|
|
|
'M' => I18N::translate('Burial of a husband'), |
264
|
|
|
'F' => I18N::translate('Burial of a wife'), |
265
|
|
|
'U' => I18N::translate('Burial of a spouse'), |
266
|
|
|
], |
267
|
|
|
'CREM' => [ |
268
|
|
|
'M' => I18N::translate('Cremation of a husband'), |
269
|
|
|
'F' => I18N::translate('Cremation of a wife'), |
270
|
|
|
'U' => I18N::translate('Cremation of a spouse'), |
271
|
|
|
], |
272
|
|
|
]; |
273
|
|
|
|
274
|
|
|
$facts = []; |
275
|
|
|
|
276
|
|
|
if (str_contains($SHOW_RELATIVES_EVENTS, '_DEAT_SPOU')) { |
277
|
|
|
foreach ($spouse->facts(['DEAT', 'BURI', 'CREM']) as $fact) { |
278
|
|
|
if ($this->includeFact($fact, $min_date, $max_date)) { |
279
|
|
|
$facts[] = $this->convertEvent($fact, $death_of_a_spouse[$fact->getTag()][$fact->record()->sex()]); |
280
|
|
|
} |
281
|
|
|
} |
282
|
|
|
} |
283
|
|
|
|
284
|
|
|
return $facts; |
285
|
|
|
} |
286
|
|
|
|
287
|
|
|
/** |
288
|
|
|
* Get the events of children and grandchildren. |
289
|
|
|
* |
290
|
|
|
* @param Individual $person |
291
|
|
|
* @param Family $family |
292
|
|
|
* @param string $option |
293
|
|
|
* @param string $relation |
294
|
|
|
* @param Date $min_date |
295
|
|
|
* @param Date $max_date |
296
|
|
|
* |
297
|
|
|
* @return Fact[] |
298
|
|
|
*/ |
299
|
|
|
private function childFacts(Individual $person, Family $family, string $option, string $relation, Date $min_date, Date $max_date): array |
300
|
|
|
{ |
301
|
|
|
$SHOW_RELATIVES_EVENTS = $person->tree()->getPreference('SHOW_RELATIVES_EVENTS'); |
302
|
|
|
|
303
|
|
|
$birth_of_a_child = [ |
304
|
|
|
'BIRT' => [ |
305
|
|
|
'M' => I18N::translate('Birth of a son'), |
306
|
|
|
'F' => I18N::translate('Birth of a daughter'), |
307
|
|
|
'U' => I18N::translate('Birth of a child'), |
308
|
|
|
], |
309
|
|
|
'CHR' => [ |
310
|
|
|
'M' => I18N::translate('Christening of a son'), |
311
|
|
|
'F' => I18N::translate('Christening of a daughter'), |
312
|
|
|
'U' => I18N::translate('Christening of a child'), |
313
|
|
|
], |
314
|
|
|
'BAPM' => [ |
315
|
|
|
'M' => I18N::translate('Baptism of a son'), |
316
|
|
|
'F' => I18N::translate('Baptism of a daughter'), |
317
|
|
|
'U' => I18N::translate('Baptism of a child'), |
318
|
|
|
], |
319
|
|
|
'ADOP' => [ |
320
|
|
|
'M' => I18N::translate('Adoption of a son'), |
321
|
|
|
'F' => I18N::translate('Adoption of a daughter'), |
322
|
|
|
'U' => I18N::translate('Adoption of a child'), |
323
|
|
|
], |
324
|
|
|
]; |
325
|
|
|
|
326
|
|
|
$birth_of_a_sibling = [ |
327
|
|
|
'BIRT' => [ |
328
|
|
|
'M' => I18N::translate('Birth of a brother'), |
329
|
|
|
'F' => I18N::translate('Birth of a sister'), |
330
|
|
|
'U' => I18N::translate('Birth of a sibling'), |
331
|
|
|
], |
332
|
|
|
'CHR' => [ |
333
|
|
|
'M' => I18N::translate('Christening of a brother'), |
334
|
|
|
'F' => I18N::translate('Christening of a sister'), |
335
|
|
|
'U' => I18N::translate('Christening of a sibling'), |
336
|
|
|
], |
337
|
|
|
'BAPM' => [ |
338
|
|
|
'M' => I18N::translate('Baptism of a brother'), |
339
|
|
|
'F' => I18N::translate('Baptism of a sister'), |
340
|
|
|
'U' => I18N::translate('Baptism of a sibling'), |
341
|
|
|
], |
342
|
|
|
'ADOP' => [ |
343
|
|
|
'M' => I18N::translate('Adoption of a brother'), |
344
|
|
|
'F' => I18N::translate('Adoption of a sister'), |
345
|
|
|
'U' => I18N::translate('Adoption of a sibling'), |
346
|
|
|
], |
347
|
|
|
]; |
348
|
|
|
|
349
|
|
|
$birth_of_a_half_sibling = [ |
350
|
|
|
'BIRT' => [ |
351
|
|
|
'M' => I18N::translate('Birth of a half-brother'), |
352
|
|
|
'F' => I18N::translate('Birth of a half-sister'), |
353
|
|
|
'U' => I18N::translate('Birth of a half-sibling'), |
354
|
|
|
], |
355
|
|
|
'CHR' => [ |
356
|
|
|
'M' => I18N::translate('Christening of a half-brother'), |
357
|
|
|
'F' => I18N::translate('Christening of a half-sister'), |
358
|
|
|
'U' => I18N::translate('Christening of a half-sibling'), |
359
|
|
|
], |
360
|
|
|
'BAPM' => [ |
361
|
|
|
'M' => I18N::translate('Baptism of a half-brother'), |
362
|
|
|
'F' => I18N::translate('Baptism of a half-sister'), |
363
|
|
|
'U' => I18N::translate('Baptism of a half-sibling'), |
364
|
|
|
], |
365
|
|
|
'ADOP' => [ |
366
|
|
|
'M' => I18N::translate('Adoption of a half-brother'), |
367
|
|
|
'F' => I18N::translate('Adoption of a half-sister'), |
368
|
|
|
'U' => I18N::translate('Adoption of a half-sibling'), |
369
|
|
|
], |
370
|
|
|
]; |
371
|
|
|
|
372
|
|
|
$birth_of_a_grandchild = [ |
373
|
|
|
'BIRT' => [ |
374
|
|
|
'M' => I18N::translate('Birth of a grandson'), |
375
|
|
|
'F' => I18N::translate('Birth of a granddaughter'), |
376
|
|
|
'U' => I18N::translate('Birth of a grandchild'), |
377
|
|
|
], |
378
|
|
|
'CHR' => [ |
379
|
|
|
'M' => I18N::translate('Christening of a grandson'), |
380
|
|
|
'F' => I18N::translate('Christening of a granddaughter'), |
381
|
|
|
'U' => I18N::translate('Christening of a grandchild'), |
382
|
|
|
], |
383
|
|
|
'BAPM' => [ |
384
|
|
|
'M' => I18N::translate('Baptism of a grandson'), |
385
|
|
|
'F' => I18N::translate('Baptism of a granddaughter'), |
386
|
|
|
'U' => I18N::translate('Baptism of a grandchild'), |
387
|
|
|
], |
388
|
|
|
'ADOP' => [ |
389
|
|
|
'M' => I18N::translate('Adoption of a grandson'), |
390
|
|
|
'F' => I18N::translate('Adoption of a granddaughter'), |
391
|
|
|
'U' => I18N::translate('Adoption of a grandchild'), |
392
|
|
|
], |
393
|
|
|
]; |
394
|
|
|
|
395
|
|
|
$birth_of_a_grandchild1 = [ |
396
|
|
|
'BIRT' => [ |
397
|
|
|
'M' => I18N::translateContext('daughter’s son', 'Birth of a grandson'), |
398
|
|
|
'F' => I18N::translateContext('daughter’s daughter', 'Birth of a granddaughter'), |
399
|
|
|
'U' => I18N::translate('Birth of a grandchild'), |
400
|
|
|
], |
401
|
|
|
'CHR' => [ |
402
|
|
|
'M' => I18N::translateContext('daughter’s son', 'Christening of a grandson'), |
403
|
|
|
'F' => I18N::translateContext('daughter’s daughter', 'Christening of a granddaughter'), |
404
|
|
|
'U' => I18N::translate('Christening of a grandchild'), |
405
|
|
|
], |
406
|
|
|
'BAPM' => [ |
407
|
|
|
'M' => I18N::translateContext('daughter’s son', 'Baptism of a grandson'), |
408
|
|
|
'F' => I18N::translateContext('daughter’s daughter', 'Baptism of a granddaughter'), |
409
|
|
|
'U' => I18N::translate('Baptism of a grandchild'), |
410
|
|
|
], |
411
|
|
|
'ADOP' => [ |
412
|
|
|
'M' => I18N::translateContext('daughter’s son', 'Adoption of a grandson'), |
413
|
|
|
'F' => I18N::translateContext('daughter’s daughter', 'Adoption of a granddaughter'), |
414
|
|
|
'U' => I18N::translate('Adoption of a grandchild'), |
415
|
|
|
], |
416
|
|
|
]; |
417
|
|
|
|
418
|
|
|
$birth_of_a_grandchild2 = [ |
419
|
|
|
'BIRT' => [ |
420
|
|
|
'M' => I18N::translateContext('son’s son', 'Birth of a grandson'), |
421
|
|
|
'F' => I18N::translateContext('son’s daughter', 'Birth of a granddaughter'), |
422
|
|
|
'U' => I18N::translate('Birth of a grandchild'), |
423
|
|
|
], |
424
|
|
|
'CHR' => [ |
425
|
|
|
'M' => I18N::translateContext('son’s son', 'Christening of a grandson'), |
426
|
|
|
'F' => I18N::translateContext('son’s daughter', 'Christening of a granddaughter'), |
427
|
|
|
'U' => I18N::translate('Christening of a grandchild'), |
428
|
|
|
], |
429
|
|
|
'BAPM' => [ |
430
|
|
|
'M' => I18N::translateContext('son’s son', 'Baptism of a grandson'), |
431
|
|
|
'F' => I18N::translateContext('son’s daughter', 'Baptism of a granddaughter'), |
432
|
|
|
'U' => I18N::translate('Baptism of a grandchild'), |
433
|
|
|
], |
434
|
|
|
'ADOP' => [ |
435
|
|
|
'M' => I18N::translateContext('son’s son', 'Adoption of a grandson'), |
436
|
|
|
'F' => I18N::translateContext('son’s daughter', 'Adoption of a granddaughter'), |
437
|
|
|
'U' => I18N::translate('Adoption of a grandchild'), |
438
|
|
|
], |
439
|
|
|
]; |
440
|
|
|
|
441
|
|
|
$death_of_a_child = [ |
442
|
|
|
'DEAT' => [ |
443
|
|
|
'M' => I18N::translate('Death of a son'), |
444
|
|
|
'F' => I18N::translate('Death of a daughter'), |
445
|
|
|
'U' => I18N::translate('Death of a child'), |
446
|
|
|
], |
447
|
|
|
'BURI' => [ |
448
|
|
|
'M' => I18N::translate('Burial of a son'), |
449
|
|
|
'F' => I18N::translate('Burial of a daughter'), |
450
|
|
|
'U' => I18N::translate('Burial of a child'), |
451
|
|
|
], |
452
|
|
|
'CREM' => [ |
453
|
|
|
'M' => I18N::translate('Cremation of a son'), |
454
|
|
|
'F' => I18N::translate('Cremation of a daughter'), |
455
|
|
|
'U' => I18N::translate('Cremation of a child'), |
456
|
|
|
], |
457
|
|
|
]; |
458
|
|
|
|
459
|
|
|
$death_of_a_sibling = [ |
460
|
|
|
'DEAT' => [ |
461
|
|
|
'M' => I18N::translate('Death of a brother'), |
462
|
|
|
'F' => I18N::translate('Death of a sister'), |
463
|
|
|
'U' => I18N::translate('Death of a sibling'), |
464
|
|
|
], |
465
|
|
|
'BURI' => [ |
466
|
|
|
'M' => I18N::translate('Burial of a brother'), |
467
|
|
|
'F' => I18N::translate('Burial of a sister'), |
468
|
|
|
'U' => I18N::translate('Burial of a sibling'), |
469
|
|
|
], |
470
|
|
|
'CREM' => [ |
471
|
|
|
'M' => I18N::translate('Cremation of a brother'), |
472
|
|
|
'F' => I18N::translate('Cremation of a sister'), |
473
|
|
|
'U' => I18N::translate('Cremation of a sibling'), |
474
|
|
|
], |
475
|
|
|
]; |
476
|
|
|
|
477
|
|
|
$death_of_a_half_sibling = [ |
478
|
|
|
'DEAT' => [ |
479
|
|
|
'M' => I18N::translate('Death of a half-brother'), |
480
|
|
|
'F' => I18N::translate('Death of a half-sister'), |
481
|
|
|
'U' => I18N::translate('Death of a half-sibling'), |
482
|
|
|
], |
483
|
|
|
'BURI' => [ |
484
|
|
|
'M' => I18N::translate('Burial of a half-brother'), |
485
|
|
|
'F' => I18N::translate('Burial of a half-sister'), |
486
|
|
|
'U' => I18N::translate('Burial of a half-sibling'), |
487
|
|
|
], |
488
|
|
|
'CREM' => [ |
489
|
|
|
'M' => I18N::translate('Cremation of a half-brother'), |
490
|
|
|
'F' => I18N::translate('Cremation of a half-sister'), |
491
|
|
|
'U' => I18N::translate('Cremation of a half-sibling'), |
492
|
|
|
], |
493
|
|
|
]; |
494
|
|
|
|
495
|
|
|
$death_of_a_grandchild = [ |
496
|
|
|
'DEAT' => [ |
497
|
|
|
'M' => I18N::translate('Death of a grandson'), |
498
|
|
|
'F' => I18N::translate('Death of a granddaughter'), |
499
|
|
|
'U' => I18N::translate('Death of a grandchild'), |
500
|
|
|
], |
501
|
|
|
'BURI' => [ |
502
|
|
|
'M' => I18N::translate('Burial of a grandson'), |
503
|
|
|
'F' => I18N::translate('Burial of a granddaughter'), |
504
|
|
|
'U' => I18N::translate('Burial of a grandchild'), |
505
|
|
|
], |
506
|
|
|
'CREM' => [ |
507
|
|
|
'M' => I18N::translate('Cremation of a grandson'), |
508
|
|
|
'F' => I18N::translate('Cremation of a granddaughter'), |
509
|
|
|
'U' => I18N::translate('Baptism of a grandchild'), |
510
|
|
|
], |
511
|
|
|
]; |
512
|
|
|
|
513
|
|
|
$death_of_a_grandchild1 = [ |
514
|
|
|
'DEAT' => [ |
515
|
|
|
'M' => I18N::translateContext('daughter’s son', 'Death of a grandson'), |
516
|
|
|
'F' => I18N::translateContext('daughter’s daughter', 'Death of a granddaughter'), |
517
|
|
|
'U' => I18N::translate('Death of a grandchild'), |
518
|
|
|
], |
519
|
|
|
'BURI' => [ |
520
|
|
|
'M' => I18N::translateContext('daughter’s son', 'Burial of a grandson'), |
521
|
|
|
'F' => I18N::translateContext('daughter’s daughter', 'Burial of a granddaughter'), |
522
|
|
|
'U' => I18N::translate('Burial of a grandchild'), |
523
|
|
|
], |
524
|
|
|
'CREM' => [ |
525
|
|
|
'M' => I18N::translateContext('daughter’s son', 'Cremation of a grandson'), |
526
|
|
|
'F' => I18N::translateContext('daughter’s daughter', 'Cremation of a granddaughter'), |
527
|
|
|
'U' => I18N::translate('Baptism of a grandchild'), |
528
|
|
|
], |
529
|
|
|
]; |
530
|
|
|
|
531
|
|
|
$death_of_a_grandchild2 = [ |
532
|
|
|
'DEAT' => [ |
533
|
|
|
'M' => I18N::translateContext('son’s son', 'Death of a grandson'), |
534
|
|
|
'F' => I18N::translateContext('son’s daughter', 'Death of a granddaughter'), |
535
|
|
|
'U' => I18N::translate('Death of a grandchild'), |
536
|
|
|
], |
537
|
|
|
'BURI' => [ |
538
|
|
|
'M' => I18N::translateContext('son’s son', 'Burial of a grandson'), |
539
|
|
|
'F' => I18N::translateContext('son’s daughter', 'Burial of a granddaughter'), |
540
|
|
|
'U' => I18N::translate('Burial of a grandchild'), |
541
|
|
|
], |
542
|
|
|
'CREM' => [ |
543
|
|
|
'M' => I18N::translateContext('son’s son', 'Cremation of a grandson'), |
544
|
|
|
'F' => I18N::translateContext('son’s daughter', 'Cremation of a granddaughter'), |
545
|
|
|
'U' => I18N::translate('Cremation of a grandchild'), |
546
|
|
|
], |
547
|
|
|
]; |
548
|
|
|
|
549
|
|
|
$marriage_of_a_child = [ |
550
|
|
|
'M' => I18N::translate('Marriage of a son'), |
551
|
|
|
'F' => I18N::translate('Marriage of a daughter'), |
552
|
|
|
'U' => I18N::translate('Marriage of a child'), |
553
|
|
|
]; |
554
|
|
|
|
555
|
|
|
$marriage_of_a_grandchild = [ |
556
|
|
|
'M' => I18N::translate('Marriage of a grandson'), |
557
|
|
|
'F' => I18N::translate('Marriage of a granddaughter'), |
558
|
|
|
'U' => I18N::translate('Marriage of a grandchild'), |
559
|
|
|
]; |
560
|
|
|
|
561
|
|
|
$marriage_of_a_grandchild1 = [ |
562
|
|
|
'M' => I18N::translateContext('daughter’s son', 'Marriage of a grandson'), |
563
|
|
|
'F' => I18N::translateContext('daughter’s daughter', 'Marriage of a granddaughter'), |
564
|
|
|
'U' => I18N::translate('Marriage of a grandchild'), |
565
|
|
|
]; |
566
|
|
|
|
567
|
|
|
$marriage_of_a_grandchild2 = [ |
568
|
|
|
'M' => I18N::translateContext('son’s son', 'Marriage of a grandson'), |
569
|
|
|
'F' => I18N::translateContext('son’s daughter', 'Marriage of a granddaughter'), |
570
|
|
|
'U' => I18N::translate('Marriage of a grandchild'), |
571
|
|
|
]; |
572
|
|
|
|
573
|
|
|
$marriage_of_a_sibling = [ |
574
|
|
|
'M' => I18N::translate('Marriage of a brother'), |
575
|
|
|
'F' => I18N::translate('Marriage of a sister'), |
576
|
|
|
'U' => I18N::translate('Marriage of a sibling'), |
577
|
|
|
]; |
578
|
|
|
|
579
|
|
|
$marriage_of_a_half_sibling = [ |
580
|
|
|
'M' => I18N::translate('Marriage of a half-brother'), |
581
|
|
|
'F' => I18N::translate('Marriage of a half-sister'), |
582
|
|
|
'U' => I18N::translate('Marriage of a half-sibling'), |
583
|
|
|
]; |
584
|
|
|
|
585
|
|
|
$facts = []; |
586
|
|
|
|
587
|
|
|
// Deal with recursion. |
588
|
|
|
switch ($option) { |
589
|
|
|
case '_CHIL': |
590
|
|
|
// Add grandchildren |
591
|
|
|
foreach ($family->children() as $child) { |
592
|
|
|
foreach ($child->spouseFamilies() as $cfamily) { |
593
|
|
|
switch ($child->sex()) { |
594
|
|
|
case 'M': |
595
|
|
|
foreach ($this->childFacts($person, $cfamily, '_GCHI', 'son', $min_date, $max_date) as $fact) { |
596
|
|
|
$facts[] = $fact; |
597
|
|
|
} |
598
|
|
|
break; |
599
|
|
|
case 'F': |
600
|
|
|
foreach ($this->childFacts($person, $cfamily, '_GCHI', 'dau', $min_date, $max_date) as $fact) { |
601
|
|
|
$facts[] = $fact; |
602
|
|
|
} |
603
|
|
|
break; |
604
|
|
|
default: |
605
|
|
|
foreach ($this->childFacts($person, $cfamily, '_GCHI', 'chi', $min_date, $max_date) as $fact) { |
606
|
|
|
$facts[] = $fact; |
607
|
|
|
} |
608
|
|
|
break; |
609
|
|
|
} |
610
|
|
|
} |
611
|
|
|
} |
612
|
|
|
break; |
613
|
|
|
} |
614
|
|
|
|
615
|
|
|
// For each child in the family |
616
|
|
|
foreach ($family->children() as $child) { |
617
|
|
|
if ($child->xref() === $person->xref()) { |
618
|
|
|
// We are not our own sibling! |
619
|
|
|
continue; |
620
|
|
|
} |
621
|
|
|
// add child’s birth |
622
|
|
|
if (str_contains($SHOW_RELATIVES_EVENTS, '_BIRT' . str_replace('_HSIB', '_SIBL', $option))) { |
623
|
|
|
foreach ($child->facts(['BIRT', 'CHR', 'BAPM', 'ADOP']) as $fact) { |
624
|
|
|
// Always show _BIRT_CHIL, even if the dates are not known |
625
|
|
|
if ($option === '_CHIL' || $this->includeFact($fact, $min_date, $max_date)) { |
626
|
|
|
switch ($option) { |
627
|
|
|
case '_GCHI': |
628
|
|
|
switch ($relation) { |
629
|
|
|
case 'dau': |
630
|
|
|
$facts[] = $this->convertEvent($fact, $birth_of_a_grandchild1[$fact->getTag()][$fact->record()->sex()]); |
631
|
|
|
break; |
632
|
|
|
case 'son': |
633
|
|
|
$facts[] = $this->convertEvent($fact, $birth_of_a_grandchild2[$fact->getTag()][$fact->record()->sex()]); |
634
|
|
|
break; |
635
|
|
|
case 'chil': |
636
|
|
|
$facts[] = $this->convertEvent($fact, $birth_of_a_grandchild[$fact->getTag()][$fact->record()->sex()]); |
637
|
|
|
break; |
638
|
|
|
} |
639
|
|
|
break; |
640
|
|
|
case '_SIBL': |
641
|
|
|
$facts[] = $this->convertEvent($fact, $birth_of_a_sibling[$fact->getTag()][$fact->record()->sex()]); |
642
|
|
|
break; |
643
|
|
|
case '_HSIB': |
644
|
|
|
$facts[] = $this->convertEvent($fact, $birth_of_a_half_sibling[$fact->getTag()][$fact->record()->sex()]); |
645
|
|
|
break; |
646
|
|
|
case '_CHIL': |
647
|
|
|
$facts[] = $this->convertEvent($fact, $birth_of_a_child[$fact->getTag()][$fact->record()->sex()]); |
648
|
|
|
break; |
649
|
|
|
} |
650
|
|
|
} |
651
|
|
|
} |
652
|
|
|
} |
653
|
|
|
// add child’s death |
654
|
|
|
if (str_contains($SHOW_RELATIVES_EVENTS, '_DEAT' . str_replace('_HSIB', '_SIBL', $option))) { |
655
|
|
|
foreach ($child->facts(['DEAT', 'BURI', 'CREM']) as $fact) { |
656
|
|
|
if ($this->includeFact($fact, $min_date, $max_date)) { |
657
|
|
|
switch ($option) { |
658
|
|
|
case '_GCHI': |
659
|
|
|
switch ($relation) { |
660
|
|
|
case 'dau': |
661
|
|
|
$facts[] = $this->convertEvent($fact, $death_of_a_grandchild1[$fact->getTag()][$fact->record()->sex()]); |
662
|
|
|
break; |
663
|
|
|
case 'son': |
664
|
|
|
$facts[] = $this->convertEvent($fact, $death_of_a_grandchild2[$fact->getTag()][$fact->record()->sex()]); |
665
|
|
|
break; |
666
|
|
|
case 'chi': |
667
|
|
|
$facts[] = $this->convertEvent($fact, $death_of_a_grandchild[$fact->getTag()][$fact->record()->sex()]); |
668
|
|
|
break; |
669
|
|
|
} |
670
|
|
|
break; |
671
|
|
|
case '_SIBL': |
672
|
|
|
$facts[] = $this->convertEvent($fact, $death_of_a_sibling[$fact->getTag()][$fact->record()->sex()]); |
673
|
|
|
break; |
674
|
|
|
case '_HSIB': |
675
|
|
|
$facts[] = $this->convertEvent($fact, $death_of_a_half_sibling[$fact->getTag()][$fact->record()->sex()]); |
676
|
|
|
break; |
677
|
|
|
case '_CHIL': |
678
|
|
|
$facts[] = $this->convertEvent($fact, $death_of_a_child[$fact->getTag()][$fact->record()->sex()]); |
679
|
|
|
break; |
680
|
|
|
} |
681
|
|
|
} |
682
|
|
|
} |
683
|
|
|
} |
684
|
|
|
|
685
|
|
|
// add child’s marriage |
686
|
|
|
if (str_contains($SHOW_RELATIVES_EVENTS, '_MARR' . str_replace('_HSIB', '_SIBL', $option))) { |
687
|
|
|
foreach ($child->spouseFamilies() as $sfamily) { |
688
|
|
|
foreach ($sfamily->facts(['MARR']) as $fact) { |
689
|
|
|
if ($this->includeFact($fact, $min_date, $max_date)) { |
690
|
|
|
switch ($option) { |
691
|
|
|
case '_GCHI': |
692
|
|
|
switch ($relation) { |
693
|
|
|
case 'dau': |
694
|
|
|
$facts[] = $this->convertEvent($fact, $marriage_of_a_grandchild1['F']); |
695
|
|
|
break; |
696
|
|
|
case 'son': |
697
|
|
|
$facts[] = $this->convertEvent($fact, $marriage_of_a_grandchild2['M']); |
698
|
|
|
break; |
699
|
|
|
case 'chi': |
700
|
|
|
$facts[] = $this->convertEvent($fact, $marriage_of_a_grandchild['U']); |
701
|
|
|
break; |
702
|
|
|
} |
703
|
|
|
break; |
704
|
|
|
case '_SIBL': |
705
|
|
|
$facts[] = $this->convertEvent($fact, $marriage_of_a_sibling['U']); |
706
|
|
|
break; |
707
|
|
|
case '_HSIB': |
708
|
|
|
$facts[] = $this->convertEvent($fact, $marriage_of_a_half_sibling['U']); |
709
|
|
|
break; |
710
|
|
|
case '_CHIL': |
711
|
|
|
$facts[] = $this->convertEvent($fact, $marriage_of_a_child['U']); |
712
|
|
|
break; |
713
|
|
|
} |
714
|
|
|
} |
715
|
|
|
} |
716
|
|
|
} |
717
|
|
|
} |
718
|
|
|
} |
719
|
|
|
|
720
|
|
|
return $facts; |
721
|
|
|
} |
722
|
|
|
|
723
|
|
|
/** |
724
|
|
|
* Get the events of parents and grandparents. |
725
|
|
|
* |
726
|
|
|
* @param Individual $person |
727
|
|
|
* @param int $sosa |
728
|
|
|
* @param Date $min_date |
729
|
|
|
* @param Date $max_date |
730
|
|
|
* |
731
|
|
|
* @return Fact[] |
732
|
|
|
*/ |
733
|
|
|
private function parentFacts(Individual $person, int $sosa, Date $min_date, Date $max_date): array |
734
|
|
|
{ |
735
|
|
|
$SHOW_RELATIVES_EVENTS = $person->tree()->getPreference('SHOW_RELATIVES_EVENTS'); |
736
|
|
|
|
737
|
|
|
$death_of_a_parent = [ |
738
|
|
|
'DEAT' => [ |
739
|
|
|
'M' => I18N::translate('Death of a father'), |
740
|
|
|
'F' => I18N::translate('Death of a mother'), |
741
|
|
|
'U' => I18N::translate('Death of a parent'), |
742
|
|
|
], |
743
|
|
|
'BURI' => [ |
744
|
|
|
'M' => I18N::translate('Burial of a father'), |
745
|
|
|
'F' => I18N::translate('Burial of a mother'), |
746
|
|
|
'U' => I18N::translate('Burial of a parent'), |
747
|
|
|
], |
748
|
|
|
'CREM' => [ |
749
|
|
|
'M' => I18N::translate('Cremation of a father'), |
750
|
|
|
'F' => I18N::translate('Cremation of a mother'), |
751
|
|
|
'U' => I18N::translate('Cremation of a parent'), |
752
|
|
|
], |
753
|
|
|
]; |
754
|
|
|
|
755
|
|
|
$death_of_a_grandparent = [ |
756
|
|
|
'DEAT' => [ |
757
|
|
|
'M' => I18N::translate('Death of a grandfather'), |
758
|
|
|
'F' => I18N::translate('Death of a grandmother'), |
759
|
|
|
'U' => I18N::translate('Death of a grandparent'), |
760
|
|
|
], |
761
|
|
|
'BURI' => [ |
762
|
|
|
'M' => I18N::translate('Burial of a grandfather'), |
763
|
|
|
'F' => I18N::translate('Burial of a grandmother'), |
764
|
|
|
'U' => I18N::translate('Burial of a grandparent'), |
765
|
|
|
], |
766
|
|
|
'CREM' => [ |
767
|
|
|
'M' => I18N::translate('Cremation of a grandfather'), |
768
|
|
|
'F' => I18N::translate('Cremation of a grandmother'), |
769
|
|
|
'U' => I18N::translate('Cremation of a grandparent'), |
770
|
|
|
], |
771
|
|
|
]; |
772
|
|
|
|
773
|
|
|
$death_of_a_maternal_grandparent = [ |
774
|
|
|
'DEAT' => [ |
775
|
|
|
'M' => I18N::translate('Death of a maternal grandfather'), |
776
|
|
|
'F' => I18N::translate('Death of a maternal grandmother'), |
777
|
|
|
'U' => I18N::translate('Death of a grandparent'), |
778
|
|
|
], |
779
|
|
|
'BURI' => [ |
780
|
|
|
'M' => I18N::translate('Burial of a maternal grandfather'), |
781
|
|
|
'F' => I18N::translate('Burial of a maternal grandmother'), |
782
|
|
|
'U' => I18N::translate('Burial of a grandparent'), |
783
|
|
|
], |
784
|
|
|
'CREM' => [ |
785
|
|
|
'M' => I18N::translate('Cremation of a maternal grandfather'), |
786
|
|
|
'F' => I18N::translate('Cremation of a maternal grandmother'), |
787
|
|
|
'U' => I18N::translate('Cremation of a grandparent'), |
788
|
|
|
], |
789
|
|
|
]; |
790
|
|
|
|
791
|
|
|
$death_of_a_paternal_grandparent = [ |
792
|
|
|
'DEAT' => [ |
793
|
|
|
'M' => I18N::translate('Death of a paternal grandfather'), |
794
|
|
|
'F' => I18N::translate('Death of a paternal grandmother'), |
795
|
|
|
'U' => I18N::translate('Death of a grandparent'), |
796
|
|
|
], |
797
|
|
|
'BURI' => [ |
798
|
|
|
'M' => I18N::translate('Burial of a paternal grandfather'), |
799
|
|
|
'F' => I18N::translate('Burial of a paternal grandmother'), |
800
|
|
|
'U' => I18N::translate('Burial of a grandparent'), |
801
|
|
|
], |
802
|
|
|
'CREM' => [ |
803
|
|
|
'M' => I18N::translate('Cremation of a paternal grandfather'), |
804
|
|
|
'F' => I18N::translate('Cremation of a paternal grandmother'), |
805
|
|
|
'U' => I18N::translate('Cremation of a grandparent'), |
806
|
|
|
], |
807
|
|
|
]; |
808
|
|
|
|
809
|
|
|
$marriage_of_a_parent = [ |
810
|
|
|
'M' => I18N::translate('Marriage of a father'), |
811
|
|
|
'F' => I18N::translate('Marriage of a mother'), |
812
|
|
|
'U' => I18N::translate('Marriage of a parent'), |
813
|
|
|
]; |
814
|
|
|
|
815
|
|
|
$facts = []; |
816
|
|
|
|
817
|
|
|
if ($sosa === 1) { |
818
|
|
|
foreach ($person->childFamilies() as $family) { |
819
|
|
|
// Add siblings |
820
|
|
|
foreach ($this->childFacts($person, $family, '_SIBL', '', $min_date, $max_date) as $fact) { |
821
|
|
|
$facts[] = $fact; |
822
|
|
|
} |
823
|
|
|
foreach ($family->spouses() as $spouse) { |
824
|
|
|
foreach ($spouse->spouseFamilies() as $sfamily) { |
825
|
|
|
if ($family !== $sfamily) { |
826
|
|
|
// Add half-siblings |
827
|
|
|
foreach ($this->childFacts($person, $sfamily, '_HSIB', '', $min_date, $max_date) as $fact) { |
828
|
|
|
$facts[] = $fact; |
829
|
|
|
} |
830
|
|
|
} |
831
|
|
|
} |
832
|
|
|
// Add grandparents |
833
|
|
|
foreach ($this->parentFacts($spouse, $spouse->sex() === 'F' ? 3 : 2, $min_date, $max_date) as $fact) { |
834
|
|
|
$facts[] = $fact; |
835
|
|
|
} |
836
|
|
|
} |
837
|
|
|
} |
838
|
|
|
|
839
|
|
|
if (str_contains($SHOW_RELATIVES_EVENTS, '_MARR_PARE')) { |
840
|
|
|
// add father/mother marriages |
841
|
|
|
foreach ($person->childFamilies() as $sfamily) { |
842
|
|
|
foreach ($sfamily->facts(['MARR']) as $fact) { |
843
|
|
|
if ($this->includeFact($fact, $min_date, $max_date)) { |
844
|
|
|
// marriage of parents (to each other) |
845
|
|
|
$facts[] = $this->convertEvent($fact, I18N::translate('Marriage of parents')); |
846
|
|
|
} |
847
|
|
|
} |
848
|
|
|
} |
849
|
|
|
foreach ($person->childStepFamilies() as $sfamily) { |
850
|
|
|
foreach ($sfamily->facts(['MARR']) as $fact) { |
851
|
|
|
if ($this->includeFact($fact, $min_date, $max_date)) { |
852
|
|
|
// marriage of a parent (to another spouse) |
853
|
|
|
$facts[] = $this->convertEvent($fact, $marriage_of_a_parent['U']); |
854
|
|
|
} |
855
|
|
|
} |
856
|
|
|
} |
857
|
|
|
} |
858
|
|
|
} |
859
|
|
|
|
860
|
|
|
foreach ($person->childFamilies() as $family) { |
861
|
|
|
foreach ($family->spouses() as $parent) { |
862
|
|
|
if (str_contains($SHOW_RELATIVES_EVENTS, '_DEAT' . ($sosa === 1 ? '_PARE' : '_GPAR'))) { |
863
|
|
|
foreach ($parent->facts(['DEAT', 'BURI', 'CREM']) as $fact) { |
864
|
|
|
// Show death of parent when it happened prior to birth |
865
|
|
|
if ($sosa === 1 && Date::compare($fact->date(), $min_date) < 0 || $this->includeFact($fact, $min_date, $max_date)) { |
866
|
|
|
switch ($sosa) { |
867
|
|
|
case 1: |
868
|
|
|
$facts[] = $this->convertEvent($fact, $death_of_a_parent[$fact->getTag()][$fact->record()->sex()]); |
869
|
|
|
break; |
870
|
|
|
case 2: |
871
|
|
|
case 3: |
872
|
|
|
switch ($person->sex()) { |
873
|
|
|
case 'M': |
874
|
|
|
$facts[] = $this->convertEvent($fact, $death_of_a_paternal_grandparent[$fact->getTag()][$fact->record()->sex()]); |
875
|
|
|
break; |
876
|
|
|
case 'F': |
877
|
|
|
$facts[] = $this->convertEvent($fact, $death_of_a_maternal_grandparent[$fact->getTag()][$fact->record()->sex()]); |
878
|
|
|
break; |
879
|
|
|
default: |
880
|
|
|
$facts[] = $this->convertEvent($fact, $death_of_a_grandparent[$fact->getTag()][$fact->record()->sex()]); |
881
|
|
|
break; |
882
|
|
|
} |
883
|
|
|
} |
884
|
|
|
} |
885
|
|
|
} |
886
|
|
|
} |
887
|
|
|
} |
888
|
|
|
} |
889
|
|
|
|
890
|
|
|
return $facts; |
891
|
|
|
} |
892
|
|
|
|
893
|
|
|
/** |
894
|
|
|
* Get any historical events. |
895
|
|
|
* |
896
|
|
|
* @param Individual $individual |
897
|
|
|
* |
898
|
|
|
* @return Fact[] |
899
|
|
|
*/ |
900
|
|
|
private function historicalFacts(Individual $individual): array |
901
|
|
|
{ |
902
|
|
|
return $this->module_service->findByInterface(ModuleHistoricEventsInterface::class) |
903
|
|
|
->map(static function (ModuleHistoricEventsInterface $module) use ($individual): Collection { |
904
|
|
|
return $module->historicEventsForIndividual($individual); |
905
|
|
|
}) |
906
|
|
|
->flatten() |
907
|
|
|
->all(); |
908
|
|
|
} |
909
|
|
|
|
910
|
|
|
/** |
911
|
|
|
* Get the events of associates. |
912
|
|
|
* |
913
|
|
|
* @param Individual $person |
914
|
|
|
* |
915
|
|
|
* @return Fact[] |
916
|
|
|
*/ |
917
|
|
|
private function associateFacts(Individual $person): array |
918
|
|
|
{ |
919
|
|
|
$facts = []; |
920
|
|
|
|
921
|
|
|
/** @var Individual[] $associates */ |
922
|
|
|
$asso1 = $person->linkedIndividuals('ASSO'); |
923
|
|
|
$asso2 = $person->linkedIndividuals('_ASSO'); |
924
|
|
|
$asso3 = $person->linkedFamilies('ASSO'); |
925
|
|
|
$asso4 = $person->linkedFamilies('_ASSO'); |
926
|
|
|
|
927
|
|
|
$associates = $asso1->merge($asso2)->merge($asso3)->merge($asso4); |
928
|
|
|
|
929
|
|
|
foreach ($associates as $associate) { |
930
|
|
|
foreach ($associate->facts() as $fact) { |
931
|
|
|
if (preg_match('/\n\d _?ASSO @' . $person->xref() . '@/', $fact->gedcom())) { |
932
|
|
|
// Extract the important details from the fact |
933
|
|
|
$factrec = '1 ' . $fact->getTag(); |
934
|
|
|
if (preg_match('/\n2 DATE .*/', $fact->gedcom(), $match)) { |
935
|
|
|
$factrec .= $match[0]; |
936
|
|
|
} |
937
|
|
|
if (preg_match('/\n2 PLAC .*/', $fact->gedcom(), $match)) { |
938
|
|
|
$factrec .= $match[0]; |
939
|
|
|
} |
940
|
|
|
if ($associate instanceof Family) { |
941
|
|
|
foreach ($associate->spouses() as $spouse) { |
942
|
|
|
$factrec .= "\n2 _ASSO @" . $spouse->xref() . '@'; |
943
|
|
|
} |
944
|
|
|
} else { |
945
|
|
|
$factrec .= "\n2 _ASSO @" . $associate->xref() . '@'; |
946
|
|
|
} |
947
|
|
|
$facts[] = new Fact($factrec, $associate, 'asso'); |
948
|
|
|
} |
949
|
|
|
} |
950
|
|
|
} |
951
|
|
|
|
952
|
|
|
return $facts; |
953
|
|
|
} |
954
|
|
|
|
955
|
|
|
/** |
956
|
|
|
* This module handles the following facts - so don't show them on the "Facts and events" tab. |
957
|
|
|
* |
958
|
|
|
* @return Collection<string> |
959
|
|
|
*/ |
960
|
|
|
public function supportedFacts(): Collection |
961
|
|
|
{ |
962
|
|
|
// We don't actually displaye these facts, but they are displayed |
963
|
|
|
// outside the tabs/sidebar systems. This just forces them to be excluded here. |
964
|
|
|
return new Collection(['NAME', 'SEX', 'OBJE']); |
965
|
|
|
} |
966
|
|
|
} |
967
|
|
|
|
This function has been deprecated. The supplier of the function has supplied an explanatory message.
The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.