1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
|
<?php
declare(strict_types=1);
use Fisharebest\Webtrees\Age;
use Fisharebest\Webtrees\Auth;
use Fisharebest\Webtrees\Fact;
use Fisharebest\Webtrees\Family;
use Fisharebest\Webtrees\Gedcom;
use Fisharebest\Webtrees\I18N;
use Fisharebest\Webtrees\Individual;
use Fisharebest\Webtrees\Module\ModuleChartInterface;
use Fisharebest\Webtrees\Module\ModuleInterface;
use Fisharebest\Webtrees\Module\RelationshipsChartModule;
use Fisharebest\Webtrees\Registry;
use Fisharebest\Webtrees\Services\ModuleService;
use Fisharebest\Webtrees\Services\RelationshipService;
/**
* @var Fact $fact
*/
$parent = $fact->record();
// To whom is this record an associate?
if ($parent instanceof Individual) {
// On an individual page, we just show links to the person
$associates = [$parent];
} elseif ($parent instanceof Family) {
// On a family page, we show links to both spouses
$associates = $parent->spouses();
} else {
// On other pages, it does not make sense to show associates
return '';
}
preg_match_all('/\n2 (_?ASSO) @(' . Gedcom::REGEX_XREF . ')@((\n[3-9].*)*)/', $fact->gedcom(), $amatches, PREG_SET_ORDER);
$html = '';
// For each ASSO record
foreach ($amatches as $amatch) {
$person = Registry::individualFactory()->make($amatch[2], $fact->record()->tree());
if ($person instanceof Individual && $person->canShowName()) {
// Is there a "RELA" tag
if (preg_match('/\n([23]) RELA (.+)/', $amatch[3], $rmatch) === 1) {
if ($rmatch[1] === '2') {
$rela_tag = $fact->record()->tag() . ':' . $amatch[1] . ':RELA';
} else {
$rela_tag = $fact->tag() . ':' . $amatch[1] . ':RELA';
}
// Use the supplied relationship as a label
$label = Registry::elementFactory()->make($rela_tag)->value($rmatch[2], $parent->tree());
} elseif (preg_match('/^1 _?ASSO/', $fact->gedcom()) === 1) {
// Use a default label
$label = Registry::elementFactory()->make($fact->tag())->label();
} else {
// Use a default label
$label = Registry::elementFactory()->make($fact->tag() . ':_ASSO')->label();
}
if ($person !== $parent && $person->getBirthDate()->isOK() && $fact->date()->isOK()) {
$age = new Age($person->getBirthDate(), $fact->date());
switch ($person->sex()) {
case 'M':
$age_text = ' ' . I18N::translateContext('Male', '(aged %s)', (string) $age);
break;
case 'F':
$age_text = ' ' . I18N::translateContext('Female', '(aged %s)', (string) $age);
break;
default:
$age_text = ' ' . I18N::translate('(aged %s)', (string) $age);
break;
}
} else {
$age_text = '';
}
$values = ['<a href="' . e($person->url()) . '">' . $person->fullName() . '</a>' . $age_text];
$module = Registry::container()->get(ModuleService::class)
->findByComponent(ModuleChartInterface::class, $person->tree(), Auth::user())
->first(static function (ModuleInterface $module) {
return $module instanceof RelationshipsChartModule;
});
if ($module instanceof RelationshipsChartModule) {
foreach ($associates as $associate) {
$relationship_name = Registry::container()->get(RelationshipService::class)->getCloseRelationshipName($associate, $person);
if ($relationship_name === '') {
$relationship_name = I18N::translate('Relationship');
}
if ($parent instanceof Family) {
// For family ASSO records (e.g. MARR), identify the spouse with a sex icon
$relationship_name .= '<small>' . view('icons/sex', ['sex' => $associate->sex()]) . '</small>';
}
$values[] = '<a href="' . $module->chartUrl($associate, ['xref2' => $person->xref()]) . '" rel="nofollow">' . $relationship_name . '</a>';
}
}
$label = '<span class="label">' . $label . '</span>';
$value = '<span class="field" dir="auto">' . implode(' — ', $values) . '</span>';
$asso = I18N::translate('%1$s: %2$s', $label, $value);
} elseif ($amatch[2] === 'VOID') {
$label = '<span class="label">' . I18N::translate('Associate') . '</span>';
$value = I18N::translate('Not recorded');
$asso = I18N::translate('%1$s: %2$s', $label, $value);
} elseif (Auth::isEditor($fact->record()->tree())) {
$label = '<span class="label">' . I18N::translate('Associate') . '</span>';
$value = '<span class="error">@' . e($amatch[2]) . '@</span>';
$asso = I18N::translate('%1$s: %2$s', $label, $value);
} else {
$asso = '';
}
$html .= '<div class="fact_ASSO">' . $asso . '</div>';
}
echo $html;
|