xref: /webtrees/resources/views/fact-date.phtml (revision ac71572d8462e396ed5a307f05b29381e49f9e6e)
1<?php
2
3declare(strict_types=1);
4
5use Fisharebest\Webtrees\Age;
6use Fisharebest\Webtrees\Date;
7use Fisharebest\Webtrees\Fact;
8use Fisharebest\Webtrees\Family;
9use Fisharebest\Webtrees\Gedcom;
10use Fisharebest\Webtrees\GedcomRecord;
11use Fisharebest\Webtrees\I18N;
12use Fisharebest\Webtrees\Individual;
13use Fisharebest\Webtrees\Registry;
14
15/**
16 * @var bool         $cal_link
17 * @var Fact         $fact
18 * @var GedcomRecord $record
19 * @var bool         $time
20 */
21
22$element_factory = Registry::elementFactory();
23
24$factrec = $fact->gedcom();
25$html    = '';
26
27// Recorded age
28if (preg_match('/\n2 AGE (.+)/', $factrec, $match) === 1) {
29    $fact_age = $element_factory->make($fact->tag() . ':AGE')->value($match[1], $record->tree());
30} else {
31    $fact_age = '';
32}
33
34if (preg_match('/\n2 HUSB\n3 AGE (.+)/', $factrec, $match) === 1) {
35    $husb_age = $element_factory->make($fact->tag() . ':HUSB:AGE')->value($match[1], $record->tree());
36} else {
37    $husb_age = '';
38}
39
40if (preg_match('/\n2 WIFE\n3 AGE (.+)/', $factrec, $match) === 1) {
41    $wife_age = $element_factory->make($fact->tag() . ':WIFE:AGE')->value($match[1], $record->tree());
42} else {
43    $wife_age = '';
44}
45
46// Calculated age
47[, $tag] = explode(':', $fact->tag());
48
49if (preg_match('/\n2 DATE (.+)/', $factrec, $match) === 1) {
50    $date = new Date($match[1]);
51    $html .= ' ' . $date->display($cal_link ? $record->tree() : null, null, true);
52    // Time isn't valid GEDCOM, but it is widely used.
53    if ($time && preg_match('/\n3 TIME (.+)/', $factrec, $match) === 1) {
54        $html .= ' – <span class="date">' . $match[1] . '</span>';
55    }
56
57    if ($record instanceof Individual) {
58        if (
59            in_array($tag, Gedcom::BIRTH_EVENTS, true) &&
60            $record === $fact->record() &&
61            $record->tree()->getPreference('SHOW_PARENTS_AGE') === '1'
62        ) {
63            // age of parents at child birth
64            $html .= view('fact-parents-age', ['individual' => $record, 'birth_date' => $date]);
65        }
66
67        if ($tag !== 'BIRT' && $tag !== 'CHAN' && $tag !== '_TODO') {
68            // age at event
69            $birth_date = $record->getBirthDate();
70            // Can't use getDeathDate(), as this also gives BURI/CREM events, which
71            // wouldn't give the correct "days after death" result for people with
72            // no DEAT.
73            $death_event = $record->facts(['DEAT'])->first();
74            if ($death_event instanceof Fact) {
75                $death_date = $death_event->date();
76            } else {
77                $death_date = new Date('');
78            }
79            $ageText = '';
80
81            if ($tag === 'DEAT' || Date::compare($date, $death_date) <= 0 || !$record->isDead()) {
82                // Before death, print age
83                $age = (string) new Age($birth_date, $date);
84
85                // Only show calculated age if it differs from recorded age
86                if ($age !== '') {
87                    if (
88                        $fact_age !== '' && !str_starts_with($fact_age, $age) ||
89                        $fact_age === '' && $husb_age === '' && $wife_age === '' ||
90                        $husb_age !== '' && !str_starts_with($husb_age, $age) && $record->sex() === 'M' ||
91                        $wife_age !== '' && !str_starts_with($wife_age, $age) && $record->sex() === 'F'
92                    ) {
93                        switch ($record->sex()) {
94                            case 'M':
95                                /* I18N: The age of an individual at a given date */
96                                $ageText = I18N::translateContext('Male', '(aged %s)', $age);
97                                break;
98                            case 'F':
99                                /* I18N: The age of an individual at a given date */
100                                $ageText = I18N::translateContext('Female', '(aged %s)', $age);
101                                break;
102                            default:
103                                /* I18N: The age of an individual at a given date */
104                                $ageText = I18N::translate('(aged %s)', $age);
105                                break;
106                        }
107                    }
108                }
109            }
110
111            if ($tag !== 'DEAT' && $death_date->isOK() && Date::compare($death_date, $date) <= 0) {
112                $death_day = $death_date->minimumDate()->day();
113                $event_day = $date->minimumDate()->day();
114                if ($death_day !== 0 && $event_day !== 0 && Date::compare($death_date, $date) === 0) {
115                    // On the exact date of death?
116                    // NOTE: this path is never reached.  Keep the code (translation) in case
117                    // we decide to re-introduce it.
118                    $ageText = I18N::translate('(on the date of death)');
119                } else {
120                    // After death
121                    $age     = (string) new Age($death_date, $date);
122                    $ageText = I18N::translate('(%s after death)', $age);
123                }
124
125                // Family events which occur after death are probably errors
126                if ($fact->record() instanceof Family) {
127                    $ageText .= view('icons/warning');
128                }
129            }
130
131            if ($ageText !== '') {
132                $html .= ' <span class="age">' . $ageText . '</span>';
133            }
134        }
135    }
136}
137// print gedcom ages
138$age_labels = [
139    I18N::translate('Age')     => $fact_age,
140    I18N::translate('Husband') => $husb_age,
141    I18N::translate('Wife')    => $wife_age,
142];
143
144foreach (array_filter($age_labels) as $label => $age) {
145    $html .= ' <span class="label">' . $label . ':</span> <span class="age">' . $age . '</span>';
146}
147
148?>
149<span class="wt-fact-date-age">
150    <?= $html ?>
151</span>
152