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