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