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