xref: /webtrees/app/Module/IndividualFactsTabModule.php (revision dc46b57449e335587417319b1bb980729dfe17aa)
13763c3f2SGreg Roach<?php
23763c3f2SGreg Roach/**
33763c3f2SGreg Roach * webtrees: online genealogy
4369c0ce6SGreg Roach * Copyright (C) 2016 webtrees development team
53763c3f2SGreg Roach * This program is free software: you can redistribute it and/or modify
63763c3f2SGreg Roach * it under the terms of the GNU General Public License as published by
73763c3f2SGreg Roach * the Free Software Foundation, either version 3 of the License, or
83763c3f2SGreg Roach * (at your option) any later version.
93763c3f2SGreg Roach * This program is distributed in the hope that it will be useful,
103763c3f2SGreg Roach * but WITHOUT ANY WARRANTY; without even the implied warranty of
113763c3f2SGreg Roach * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
123763c3f2SGreg Roach * GNU General Public License for more details.
133763c3f2SGreg Roach * You should have received a copy of the GNU General Public License
143763c3f2SGreg Roach * along with this program. If not, see <http://www.gnu.org/licenses/>.
153763c3f2SGreg Roach */
1676692c8bSGreg Roachnamespace Fisharebest\Webtrees\Module;
1776692c8bSGreg Roach
180e62c4b8SGreg Roachuse Fisharebest\Webtrees\Auth;
190e62c4b8SGreg Roachuse Fisharebest\Webtrees\Date;
200e62c4b8SGreg Roachuse Fisharebest\Webtrees\Fact;
210e62c4b8SGreg Roachuse Fisharebest\Webtrees\Family;
223d7a8a4cSGreg Roachuse Fisharebest\Webtrees\Functions\Functions;
233d7a8a4cSGreg Roachuse Fisharebest\Webtrees\Functions\FunctionsPrint;
243d7a8a4cSGreg Roachuse Fisharebest\Webtrees\Functions\FunctionsPrintFacts;
250e62c4b8SGreg Roachuse Fisharebest\Webtrees\I18N;
260e62c4b8SGreg Roachuse Fisharebest\Webtrees\Individual;
270e62c4b8SGreg Roachuse Fisharebest\Webtrees\Module;
280e62c4b8SGreg Roachuse Fisharebest\Webtrees\Site;
293763c3f2SGreg Roach
303763c3f2SGreg Roach/**
313763c3f2SGreg Roach * Class IndividualFactsTabModule
323763c3f2SGreg Roach */
33e2a378d3SGreg Roachclass IndividualFactsTabModule extends AbstractModule implements ModuleTabInterface {
343763c3f2SGreg Roach	/** {@inheritdoc} */
353763c3f2SGreg Roach	public function getTitle() {
363763c3f2SGreg Roach		return /* I18N: Name of a module/tab on the individual page. */ I18N::translate('Facts and events');
373763c3f2SGreg Roach	}
383763c3f2SGreg Roach
393763c3f2SGreg Roach	/** {@inheritdoc} */
403763c3f2SGreg Roach	public function getDescription() {
413763c3f2SGreg Roach		return /* I18N: Description of the “Facts and events” module */ I18N::translate('A tab showing the facts and events of an individual.');
423763c3f2SGreg Roach	}
433763c3f2SGreg Roach
443763c3f2SGreg Roach	/** {@inheritdoc} */
453763c3f2SGreg Roach	public function defaultTabOrder() {
463763c3f2SGreg Roach		return 10;
473763c3f2SGreg Roach	}
483763c3f2SGreg Roach
493763c3f2SGreg Roach	/** {@inheritdoc} */
503763c3f2SGreg Roach	public function isGrayedOut() {
513763c3f2SGreg Roach		return false;
523763c3f2SGreg Roach	}
533763c3f2SGreg Roach
543763c3f2SGreg Roach	/** {@inheritdoc} */
553763c3f2SGreg Roach	public function getTabContent() {
563763c3f2SGreg Roach		global $controller;
573763c3f2SGreg Roach		$EXPAND_HISTO_EVENTS = false;
583763c3f2SGreg Roach
593763c3f2SGreg Roach		$indifacts = array();
603763c3f2SGreg Roach		// The individual’s own facts
613763c3f2SGreg Roach		foreach ($controller->record->getFacts() as $fact) {
623763c3f2SGreg Roach			switch ($fact->getTag()) {
633763c3f2SGreg Roach			case 'SEX':
643763c3f2SGreg Roach			case 'NAME':
653763c3f2SGreg Roach			case 'SOUR':
663763c3f2SGreg Roach			case 'OBJE':
673763c3f2SGreg Roach			case 'NOTE':
683763c3f2SGreg Roach			case 'FAMC':
693763c3f2SGreg Roach			case 'FAMS':
703763c3f2SGreg Roach				break;
713763c3f2SGreg Roach			default:
723763c3f2SGreg Roach				if (!array_key_exists('extra_info', Module::getActiveSidebars($controller->record->getTree())) || !ExtraInformationModule::showFact($fact)) {
733763c3f2SGreg Roach					$indifacts[] = $fact;
743763c3f2SGreg Roach				}
753763c3f2SGreg Roach				break;
763763c3f2SGreg Roach			}
773763c3f2SGreg Roach		}
783763c3f2SGreg Roach
793763c3f2SGreg Roach		// Add spouse-family facts
803763c3f2SGreg Roach		foreach ($controller->record->getSpouseFamilies() as $family) {
813763c3f2SGreg Roach			foreach ($family->getFacts() as $fact) {
823763c3f2SGreg Roach				switch ($fact->getTag()) {
833763c3f2SGreg Roach				case 'SOUR':
843763c3f2SGreg Roach				case 'NOTE':
853763c3f2SGreg Roach				case 'OBJE':
863763c3f2SGreg Roach				case 'CHAN':
873763c3f2SGreg Roach				case '_UID':
883763c3f2SGreg Roach				case 'RIN':
893763c3f2SGreg Roach				case 'HUSB':
903763c3f2SGreg Roach				case 'WIFE':
913763c3f2SGreg Roach				case 'CHIL':
923763c3f2SGreg Roach					break;
933763c3f2SGreg Roach				default:
943763c3f2SGreg Roach					$indifacts[] = $fact;
953763c3f2SGreg Roach					break;
963763c3f2SGreg Roach				}
973763c3f2SGreg Roach			}
983763c3f2SGreg Roach			$spouse = $family->getSpouse($controller->record);
993763c3f2SGreg Roach			if ($spouse) {
1003763c3f2SGreg Roach				foreach (self::spouseFacts($controller->record, $spouse) as $fact) {
1013763c3f2SGreg Roach					$indifacts[] = $fact;
1023763c3f2SGreg Roach				}
1033763c3f2SGreg Roach			}
1043763c3f2SGreg Roach			foreach (self::childFacts($controller->record, $family, '_CHIL', '') as $fact) {
1053763c3f2SGreg Roach				$indifacts[] = $fact;
1063763c3f2SGreg Roach			}
1073763c3f2SGreg Roach		}
1083763c3f2SGreg Roach
1093763c3f2SGreg Roach		foreach (self::parentFacts($controller->record, 1) as $fact) {
1103763c3f2SGreg Roach			$indifacts[] = $fact;
1113763c3f2SGreg Roach		}
1123763c3f2SGreg Roach		foreach (self::historicalFacts($controller->record) as $fact) {
1133763c3f2SGreg Roach			$indifacts[] = $fact;
1143763c3f2SGreg Roach		}
1153763c3f2SGreg Roach		foreach (self::associateFacts($controller->record) as $fact) {
1163763c3f2SGreg Roach			$indifacts[] = $fact;
1173763c3f2SGreg Roach		}
1183763c3f2SGreg Roach
1193d7a8a4cSGreg Roach		Functions::sortFacts($indifacts);
1203763c3f2SGreg Roach
1213763c3f2SGreg Roach		ob_start();
1223763c3f2SGreg Roach
123*dc46b574SDavid Drury		echo '<div class="descriptionbox rela"><form action="?"><input id="checkbox_rela_facts" type="checkbox" ';
1243763c3f2SGreg Roach		echo $controller->record->getTree()->getPreference('EXPAND_RELATIVES_EVENTS') ? 'checked' : '';
1253763c3f2SGreg Roach		echo ' onclick="jQuery(\'tr.rela\').toggle();"><label for="checkbox_rela_facts">', I18N::translate('Events of close relatives'), '</label>';
1263763c3f2SGreg Roach		if (file_exists(Site::getPreference('INDEX_DIRECTORY') . 'histo.' . WT_LOCALE . '.php')) {
1273763c3f2SGreg Roach			echo ' <input id="checkbox_histo" type="checkbox" ';
1283763c3f2SGreg Roach			echo $EXPAND_HISTO_EVENTS ? 'checked' : '';
1293763c3f2SGreg Roach			echo ' onclick="jQuery(\'tr.histo\').toggle();"><label for="checkbox_histo">', I18N::translate('Historical facts'), '</label>';
1303763c3f2SGreg Roach		}
131*dc46b574SDavid Drury		echo '</form></div>';
132*dc46b574SDavid Drury		echo '<table class="facts_table">';
133*dc46b574SDavid Drury		echo '<tbody>';
134*dc46b574SDavid Drury		if (!$indifacts) {
135*dc46b574SDavid Drury			echo '<tr><td colspan="2" class="facts_value">', I18N::translate('There are no facts for this individual.'), '</td></tr>';
136*dc46b574SDavid Drury		}
1373763c3f2SGreg Roach
1383763c3f2SGreg Roach		foreach ($indifacts as $fact) {
1393d7a8a4cSGreg Roach			FunctionsPrintFacts::printFact($fact, $controller->record);
1403763c3f2SGreg Roach		}
1413763c3f2SGreg Roach
1423763c3f2SGreg Roach		//-- new fact link
1433763c3f2SGreg Roach		if ($controller->record->canEdit()) {
1443d7a8a4cSGreg Roach			FunctionsPrint::printAddNewFact($controller->record->getXref(), $indifacts, 'INDI');
1453763c3f2SGreg Roach		}
1463763c3f2SGreg Roach		echo '</tbody>';
1473763c3f2SGreg Roach		echo '</table>';
1483763c3f2SGreg Roach
1493763c3f2SGreg Roach		if (!$controller->record->getTree()->getPreference('EXPAND_RELATIVES_EVENTS')) {
1503763c3f2SGreg Roach			echo '<script>jQuery("tr.rela").toggle();</script>';
1513763c3f2SGreg Roach		}
1523763c3f2SGreg Roach		if (!$EXPAND_HISTO_EVENTS) {
1533763c3f2SGreg Roach			echo '<script>jQuery("tr.histo").toggle();</script>';
1543763c3f2SGreg Roach		}
1553763c3f2SGreg Roach
1563763c3f2SGreg Roach		return '<div id="' . $this->getName() . '_content">' . ob_get_clean() . '</div>';
1573763c3f2SGreg Roach	}
1583763c3f2SGreg Roach
1593763c3f2SGreg Roach	/** {@inheritdoc} */
1603763c3f2SGreg Roach	public function hasTabContent() {
1613763c3f2SGreg Roach		return true;
1623763c3f2SGreg Roach	}
1633763c3f2SGreg Roach
1643763c3f2SGreg Roach	/** {@inheritdoc} */
1653763c3f2SGreg Roach	public function canLoadAjax() {
1663763c3f2SGreg Roach		return !Auth::isSearchEngine(); // Search engines cannot use AJAX
1673763c3f2SGreg Roach	}
1683763c3f2SGreg Roach
1693763c3f2SGreg Roach	/** {@inheritdoc} */
1703763c3f2SGreg Roach	public function getPreLoadContent() {
1713763c3f2SGreg Roach		return '';
1723763c3f2SGreg Roach	}
1733763c3f2SGreg Roach
1743763c3f2SGreg Roach	/**
1753763c3f2SGreg Roach	 * Spouse facts that are shown on an individual’s page.
1763763c3f2SGreg Roach	 *
1773763c3f2SGreg Roach	 * @param Individual $individual Show events that occured during the lifetime of this individual
1783763c3f2SGreg Roach	 * @param Individual $spouse     Show events of this individual
1793763c3f2SGreg Roach	 *
1803763c3f2SGreg Roach	 * @return Fact[]
1813763c3f2SGreg Roach	 */
1823763c3f2SGreg Roach	private static function spouseFacts(Individual $individual, Individual $spouse) {
1833763c3f2SGreg Roach		$SHOW_RELATIVES_EVENTS = $individual->getTree()->getPreference('SHOW_RELATIVES_EVENTS');
1843763c3f2SGreg Roach
1853763c3f2SGreg Roach		$facts = array();
1863763c3f2SGreg Roach		if (strstr($SHOW_RELATIVES_EVENTS, '_DEAT_SPOU')) {
1873763c3f2SGreg Roach			// Only include events between birth and death
1883763c3f2SGreg Roach			$birt_date = $individual->getEstimatedBirthDate();
1893763c3f2SGreg Roach			$deat_date = $individual->getEstimatedDeathDate();
1903763c3f2SGreg Roach
1913763c3f2SGreg Roach			foreach ($spouse->getFacts(WT_EVENTS_DEAT) as $fact) {
1923763c3f2SGreg Roach
1933763c3f2SGreg Roach				$fact_date = $fact->getDate();
1943763c3f2SGreg Roach				if ($fact_date->isOK() && Date::compare($birt_date, $fact_date) <= 0 && Date::compare($fact_date, $deat_date) <= 0) {
1953763c3f2SGreg Roach					// Convert the event to a close relatives event.
1963763c3f2SGreg Roach					$rela_fact = clone($fact);
1973763c3f2SGreg Roach					$rela_fact->setTag('_' . $fact->getTag() . '_SPOU');
1983763c3f2SGreg Roach					$facts[] = $rela_fact;
1993763c3f2SGreg Roach				}
2003763c3f2SGreg Roach			}
2013763c3f2SGreg Roach		}
2023763c3f2SGreg Roach
2033763c3f2SGreg Roach		return $facts;
2043763c3f2SGreg Roach	}
2053763c3f2SGreg Roach
2063763c3f2SGreg Roach	/**
2073763c3f2SGreg Roach	 * Get the events of children and grandchildren.
2083763c3f2SGreg Roach	 *
2093763c3f2SGreg Roach	 * @param Individual $person
2103763c3f2SGreg Roach	 * @param Family     $family
2113763c3f2SGreg Roach	 * @param string     $option
2123763c3f2SGreg Roach	 * @param string     $relation
2133763c3f2SGreg Roach	 *
2143763c3f2SGreg Roach	 * @return Fact[]
2153763c3f2SGreg Roach	 */
2163763c3f2SGreg Roach	private static function childFacts(Individual $person, Family $family, $option, $relation) {
2173763c3f2SGreg Roach		global $controller;
2183763c3f2SGreg Roach
2193763c3f2SGreg Roach		$SHOW_RELATIVES_EVENTS = $person->getTree()->getPreference('SHOW_RELATIVES_EVENTS');
2203763c3f2SGreg Roach
2213763c3f2SGreg Roach		$facts = array();
2223763c3f2SGreg Roach
2233763c3f2SGreg Roach		// Only include events between birth and death
2243763c3f2SGreg Roach		$birt_date = $controller->record->getEstimatedBirthDate();
2253763c3f2SGreg Roach		$deat_date = $controller->record->getEstimatedDeathDate();
2263763c3f2SGreg Roach
2273763c3f2SGreg Roach		// Deal with recursion.
2283763c3f2SGreg Roach		switch ($option) {
2293763c3f2SGreg Roach		case '_CHIL':
2303763c3f2SGreg Roach			// Add grandchildren
2313763c3f2SGreg Roach			foreach ($family->getChildren() as $child) {
2323763c3f2SGreg Roach				foreach ($child->getSpouseFamilies() as $cfamily) {
2333763c3f2SGreg Roach					switch ($child->getSex()) {
2343763c3f2SGreg Roach					case 'M':
2353763c3f2SGreg Roach						foreach (self::childFacts($person, $cfamily, '_GCHI', 'son') as $fact) {
2363763c3f2SGreg Roach							$facts[] = $fact;
2373763c3f2SGreg Roach						}
2383763c3f2SGreg Roach						break;
2393763c3f2SGreg Roach					case 'F':
2403763c3f2SGreg Roach						foreach (self::childFacts($person, $cfamily, '_GCHI', 'dau') as $fact) {
2413763c3f2SGreg Roach							$facts[] = $fact;
2423763c3f2SGreg Roach						}
2433763c3f2SGreg Roach						break;
2443763c3f2SGreg Roach					default:
2453763c3f2SGreg Roach						foreach (self::childFacts($person, $cfamily, '_GCHI', 'chi') as $fact) {
2463763c3f2SGreg Roach							$facts[] = $fact;
2473763c3f2SGreg Roach						}
2483763c3f2SGreg Roach						break;
2493763c3f2SGreg Roach					}
2503763c3f2SGreg Roach				}
2513763c3f2SGreg Roach			}
2523763c3f2SGreg Roach			break;
2533763c3f2SGreg Roach		}
2543763c3f2SGreg Roach
2553763c3f2SGreg Roach		// For each child in the family
2563763c3f2SGreg Roach		foreach ($family->getChildren() as $child) {
2573763c3f2SGreg Roach			if ($child->getXref() == $person->getXref()) {
2583763c3f2SGreg Roach				// We are not our own sibling!
2593763c3f2SGreg Roach				continue;
2603763c3f2SGreg Roach			}
2613763c3f2SGreg Roach			// add child’s birth
2623763c3f2SGreg Roach			if (strpos($SHOW_RELATIVES_EVENTS, '_BIRT' . str_replace('_HSIB', '_SIBL', $option)) !== false) {
2633763c3f2SGreg Roach				foreach ($child->getFacts(WT_EVENTS_BIRT) as $fact) {
2643763c3f2SGreg Roach					$sgdate = $fact->getDate();
2653763c3f2SGreg Roach					// Always show _BIRT_CHIL, even if the dates are not known
2663763c3f2SGreg Roach					if ($option == '_CHIL' || $sgdate->isOK() && Date::compare($birt_date, $sgdate) <= 0 && Date::compare($sgdate, $deat_date) <= 0) {
2673763c3f2SGreg Roach						if ($option == '_GCHI' && $relation == 'dau') {
2683763c3f2SGreg Roach							// Convert the event to a close relatives event.
2693763c3f2SGreg Roach							$rela_fact = clone($fact);
2703763c3f2SGreg Roach							$rela_fact->setTag('_' . $fact->getTag() . '_GCH1');
2713763c3f2SGreg Roach							$facts[] = $rela_fact;
2723763c3f2SGreg Roach						} elseif ($option == '_GCHI' && $relation == 'son') {
2733763c3f2SGreg Roach							// Convert the event to a close relatives event.
2743763c3f2SGreg Roach							$rela_fact = clone($fact);
2753763c3f2SGreg Roach							$rela_fact->setTag('_' . $fact->getTag() . '_GCH2');
2763763c3f2SGreg Roach							$facts[] = $rela_fact;
2773763c3f2SGreg Roach						} else {
2783763c3f2SGreg Roach							// Convert the event to a close relatives event.
2793763c3f2SGreg Roach							$rela_fact = clone($fact);
2803763c3f2SGreg Roach							$rela_fact->setTag('_' . $fact->getTag() . $option);
2813763c3f2SGreg Roach							$facts[] = $rela_fact;
2823763c3f2SGreg Roach						}
2833763c3f2SGreg Roach					}
2843763c3f2SGreg Roach				}
2853763c3f2SGreg Roach			}
2863763c3f2SGreg Roach			// add child’s death
2873763c3f2SGreg Roach			if (strpos($SHOW_RELATIVES_EVENTS, '_DEAT' . str_replace('_HSIB', '_SIBL', $option)) !== false) {
2883763c3f2SGreg Roach				foreach ($child->getFacts(WT_EVENTS_DEAT) as $fact) {
2893763c3f2SGreg Roach					$sgdate = $fact->getDate();
2903763c3f2SGreg Roach					if ($sgdate->isOK() && Date::compare($birt_date, $sgdate) <= 0 && Date::compare($sgdate, $deat_date) <= 0) {
2913763c3f2SGreg Roach						if ($option == '_GCHI' && $relation == 'dau') {
2923763c3f2SGreg Roach							// Convert the event to a close relatives event.
2933763c3f2SGreg Roach							$rela_fact = clone($fact);
2943763c3f2SGreg Roach							$rela_fact->setTag('_' . $fact->getTag() . '_GCH1');
2953763c3f2SGreg Roach							$facts[] = $rela_fact;
2963763c3f2SGreg Roach						} elseif ($option == '_GCHI' && $relation == 'son') {
2973763c3f2SGreg Roach							// Convert the event to a close relatives event.
2983763c3f2SGreg Roach							$rela_fact = clone($fact);
2993763c3f2SGreg Roach							$rela_fact->setTag('_' . $fact->getTag() . '_GCH2');
3003763c3f2SGreg Roach							$facts[] = $rela_fact;
3013763c3f2SGreg Roach						} else {
3023763c3f2SGreg Roach							// Convert the event to a close relatives event.
3033763c3f2SGreg Roach							$rela_fact = clone($fact);
3043763c3f2SGreg Roach							$rela_fact->setTag('_' . $fact->getTag() . $option);
3053763c3f2SGreg Roach							$facts[] = $rela_fact;
3063763c3f2SGreg Roach						}
3073763c3f2SGreg Roach					}
3083763c3f2SGreg Roach				}
3093763c3f2SGreg Roach			}
3103763c3f2SGreg Roach			// add child’s marriage
3113763c3f2SGreg Roach			if (strstr($SHOW_RELATIVES_EVENTS, '_MARR' . str_replace('_HSIB', '_SIBL', $option))) {
3123763c3f2SGreg Roach				foreach ($child->getSpouseFamilies() as $sfamily) {
3133763c3f2SGreg Roach					foreach ($sfamily->getFacts(WT_EVENTS_MARR) as $fact) {
3143763c3f2SGreg Roach						$sgdate = $fact->getDate();
3153763c3f2SGreg Roach						if ($sgdate->isOK() && Date::compare($birt_date, $sgdate) <= 0 && Date::compare($sgdate, $deat_date) <= 0) {
3163763c3f2SGreg Roach							if ($option == '_GCHI' && $relation == 'dau') {
3173763c3f2SGreg Roach								// Convert the event to a close relatives event.
3183763c3f2SGreg Roach								$rela_fact = clone($fact);
3193763c3f2SGreg Roach								$rela_fact->setTag('_' . $fact->getTag() . '_GCH1');
3203763c3f2SGreg Roach								$facts[] = $rela_fact;
3213763c3f2SGreg Roach							} elseif ($option == '_GCHI' && $relation == 'son') {
3223763c3f2SGreg Roach								// Convert the event to a close relatives event.
3233763c3f2SGreg Roach								$rela_fact = clone($fact);
3243763c3f2SGreg Roach								$rela_fact->setTag('_' . $fact->getTag() . '_GCH2');
3253763c3f2SGreg Roach								$facts[] = $rela_fact;
3263763c3f2SGreg Roach							} else {
3273763c3f2SGreg Roach								// Convert the event to a close relatives event.
3283763c3f2SGreg Roach								$rela_fact = clone($fact);
3293763c3f2SGreg Roach								$rela_fact->setTag('_' . $fact->getTag() . $option);
3303763c3f2SGreg Roach								$facts[] = $rela_fact;
3313763c3f2SGreg Roach							}
3323763c3f2SGreg Roach						}
3333763c3f2SGreg Roach					}
3343763c3f2SGreg Roach				}
3353763c3f2SGreg Roach			}
3363763c3f2SGreg Roach		}
3373763c3f2SGreg Roach
3383763c3f2SGreg Roach		return $facts;
3393763c3f2SGreg Roach	}
3403763c3f2SGreg Roach
3413763c3f2SGreg Roach	/**
3423763c3f2SGreg Roach	 * Get the events of parents and grandparents.
3433763c3f2SGreg Roach	 *
3443763c3f2SGreg Roach	 * @param Individual $person
345cbc1590aSGreg Roach	 * @param int        $sosa
3463763c3f2SGreg Roach	 *
3473763c3f2SGreg Roach	 * @return Fact[]
3483763c3f2SGreg Roach	 */
3493763c3f2SGreg Roach	private static function parentFacts(Individual $person, $sosa) {
3503763c3f2SGreg Roach		global $controller;
3513763c3f2SGreg Roach
3523763c3f2SGreg Roach		$SHOW_RELATIVES_EVENTS = $person->getTree()->getPreference('SHOW_RELATIVES_EVENTS');
3533763c3f2SGreg Roach
3543763c3f2SGreg Roach		$facts = array();
3553763c3f2SGreg Roach
3563763c3f2SGreg Roach		// Only include events between birth and death
3573763c3f2SGreg Roach		$birt_date = $controller->record->getEstimatedBirthDate();
3583763c3f2SGreg Roach		$deat_date = $controller->record->getEstimatedDeathDate();
3593763c3f2SGreg Roach
3603763c3f2SGreg Roach		if ($sosa == 1) {
3613763c3f2SGreg Roach			foreach ($person->getChildFamilies() as $family) {
3623763c3f2SGreg Roach				// Add siblings
3633763c3f2SGreg Roach				foreach (self::childFacts($person, $family, '_SIBL', '') as $fact) {
3643763c3f2SGreg Roach					$facts[] = $fact;
3653763c3f2SGreg Roach				}
3663763c3f2SGreg Roach				foreach ($family->getSpouses() as $spouse) {
3673763c3f2SGreg Roach					foreach ($spouse->getSpouseFamilies() as $sfamily) {
3683763c3f2SGreg Roach						if ($family !== $sfamily) {
3693763c3f2SGreg Roach							// Add half-siblings
3703763c3f2SGreg Roach							foreach (self::childFacts($person, $sfamily, '_HSIB', '') as $fact) {
3713763c3f2SGreg Roach								$facts[] = $fact;
3723763c3f2SGreg Roach							}
3733763c3f2SGreg Roach						}
3743763c3f2SGreg Roach					}
3753763c3f2SGreg Roach					// Add grandparents
3763763c3f2SGreg Roach					foreach (self::parentFacts($spouse, $spouse->getSex() == 'F' ? 3 : 2) as $fact) {
3773763c3f2SGreg Roach						$facts[] = $fact;
3783763c3f2SGreg Roach					}
3793763c3f2SGreg Roach				}
3803763c3f2SGreg Roach			}
3813763c3f2SGreg Roach
3823763c3f2SGreg Roach			if (strstr($SHOW_RELATIVES_EVENTS, '_MARR_PARE')) {
3833763c3f2SGreg Roach				// add father/mother marriages
3843763c3f2SGreg Roach				foreach ($person->getChildFamilies() as $sfamily) {
3853763c3f2SGreg Roach					foreach ($sfamily->getFacts(WT_EVENTS_MARR) as $fact) {
3863763c3f2SGreg Roach						if ($fact->getDate()->isOK() && Date::compare($birt_date, $fact->getDate()) <= 0 && Date::compare($fact->getDate(), $deat_date) <= 0) {
3873763c3f2SGreg Roach							// marriage of parents (to each other)
3883763c3f2SGreg Roach							$rela_fact = clone($fact);
3893763c3f2SGreg Roach							$rela_fact->setTag('_' . $fact->getTag() . '_FAMC');
3903763c3f2SGreg Roach							$facts[] = $rela_fact;
3913763c3f2SGreg Roach						}
3923763c3f2SGreg Roach					}
3933763c3f2SGreg Roach				}
3943763c3f2SGreg Roach				foreach ($person->getChildStepFamilies() as $sfamily) {
3953763c3f2SGreg Roach					foreach ($sfamily->getFacts(WT_EVENTS_MARR) as $fact) {
3963763c3f2SGreg Roach						if ($fact->getDate()->isOK() && Date::compare($birt_date, $fact->getDate()) <= 0 && Date::compare($fact->getDate(), $deat_date) <= 0) {
3973763c3f2SGreg Roach							// marriage of a parent (to another spouse)
3983763c3f2SGreg Roach							// Convert the event to a close relatives event
3993763c3f2SGreg Roach							$rela_fact = clone($fact);
4003763c3f2SGreg Roach							$rela_fact->setTag('_' . $fact->getTag() . '_PARE');
4013763c3f2SGreg Roach							$facts[] = $rela_fact;
4023763c3f2SGreg Roach						}
4033763c3f2SGreg Roach					}
4043763c3f2SGreg Roach				}
4053763c3f2SGreg Roach			}
4063763c3f2SGreg Roach		}
4073763c3f2SGreg Roach
4083763c3f2SGreg Roach		foreach ($person->getChildFamilies() as $family) {
4093763c3f2SGreg Roach			foreach ($family->getSpouses() as $parent) {
4103763c3f2SGreg Roach				if (strstr($SHOW_RELATIVES_EVENTS, '_DEAT' . ($sosa == 1 ? '_PARE' : '_GPAR'))) {
4113763c3f2SGreg Roach					foreach ($parent->getFacts(WT_EVENTS_DEAT) as $fact) {
4123763c3f2SGreg Roach						if ($fact->getDate()->isOK() && Date::compare($birt_date, $fact->getDate()) <= 0 && Date::compare($fact->getDate(), $deat_date) <= 0) {
4133763c3f2SGreg Roach							switch ($sosa) {
4143763c3f2SGreg Roach							case 1:
4153763c3f2SGreg Roach								// Convert the event to a close relatives event.
4163763c3f2SGreg Roach								$rela_fact = clone($fact);
4173763c3f2SGreg Roach								$rela_fact->setTag('_' . $fact->getTag() . '_PARE');
4183763c3f2SGreg Roach								$facts[] = $rela_fact;
4193763c3f2SGreg Roach								break;
4203763c3f2SGreg Roach							case 2:
4213763c3f2SGreg Roach								// Convert the event to a close relatives event
4223763c3f2SGreg Roach								$rela_fact = clone($fact);
4233763c3f2SGreg Roach								$rela_fact->setTag('_' . $fact->getTag() . '_GPA1');
4243763c3f2SGreg Roach								$facts[] = $rela_fact;
4253763c3f2SGreg Roach								break;
4263763c3f2SGreg Roach							case 3:
4273763c3f2SGreg Roach								// Convert the event to a close relatives event
4283763c3f2SGreg Roach								$rela_fact = clone($fact);
4293763c3f2SGreg Roach								$rela_fact->setTag('_' . $fact->getTag() . '_GPA2');
4303763c3f2SGreg Roach								$facts[] = $rela_fact;
4313763c3f2SGreg Roach								break;
4323763c3f2SGreg Roach							}
4333763c3f2SGreg Roach						}
4343763c3f2SGreg Roach					}
4353763c3f2SGreg Roach				}
4363763c3f2SGreg Roach			}
4373763c3f2SGreg Roach		}
4383763c3f2SGreg Roach
4393763c3f2SGreg Roach		return $facts;
4403763c3f2SGreg Roach	}
4413763c3f2SGreg Roach
4423763c3f2SGreg Roach	/**
4433763c3f2SGreg Roach	 * Get any historical events.
4443763c3f2SGreg Roach	 *
4453763c3f2SGreg Roach	 * @param Individual $person
4463763c3f2SGreg Roach	 *
4473763c3f2SGreg Roach	 * @return Fact[]
4483763c3f2SGreg Roach	 */
4493763c3f2SGreg Roach	private static function historicalFacts(Individual $person) {
4503763c3f2SGreg Roach		$SHOW_RELATIVES_EVENTS = $person->getTree()->getPreference('SHOW_RELATIVES_EVENTS');
4513763c3f2SGreg Roach
4523763c3f2SGreg Roach		$facts = array();
4533763c3f2SGreg Roach
4543763c3f2SGreg Roach		if ($SHOW_RELATIVES_EVENTS) {
4553763c3f2SGreg Roach			// Only include events between birth and death
4563763c3f2SGreg Roach			$birt_date = $person->getEstimatedBirthDate();
4573763c3f2SGreg Roach			$deat_date = $person->getEstimatedDeathDate();
4583763c3f2SGreg Roach
4593763c3f2SGreg Roach			if (file_exists(Site::getPreference('INDEX_DIRECTORY') . 'histo.' . WT_LOCALE . '.php')) {
4603763c3f2SGreg Roach				$histo = array();
4613763c3f2SGreg Roach				require Site::getPreference('INDEX_DIRECTORY') . 'histo.' . WT_LOCALE . '.php';
4623763c3f2SGreg Roach				foreach ($histo as $hist) {
4633763c3f2SGreg Roach					// Earlier versions of the WIKI encouraged people to use HTML entities,
4643763c3f2SGreg Roach					// rather than UTF8 encoding.
4653763c3f2SGreg Roach					$hist = html_entity_decode($hist, ENT_QUOTES, 'UTF-8');
4663763c3f2SGreg Roach
4673763c3f2SGreg Roach					$fact  = new Fact($hist, $person, 'histo');
4683763c3f2SGreg Roach					$sdate = $fact->getDate();
4693763c3f2SGreg Roach					if ($sdate->isOK() && Date::compare($birt_date, $sdate) <= 0 && Date::compare($sdate, $deat_date) <= 0) {
4703763c3f2SGreg Roach						$facts[] = $fact;
4713763c3f2SGreg Roach					}
4723763c3f2SGreg Roach				}
4733763c3f2SGreg Roach			}
4743763c3f2SGreg Roach		}
4753763c3f2SGreg Roach
4763763c3f2SGreg Roach		return $facts;
4773763c3f2SGreg Roach	}
4783763c3f2SGreg Roach
4793763c3f2SGreg Roach	/**
4803763c3f2SGreg Roach	 * Get the events of associates.
4813763c3f2SGreg Roach	 *
4823763c3f2SGreg Roach	 * @param Individual $person
4833763c3f2SGreg Roach	 *
4843763c3f2SGreg Roach	 * @return Fact[]
4853763c3f2SGreg Roach	 */
4863763c3f2SGreg Roach	private static function associateFacts(Individual $person) {
4873763c3f2SGreg Roach		$facts = array();
4883763c3f2SGreg Roach
4893763c3f2SGreg Roach		$associates = array_merge(
4903763c3f2SGreg Roach			$person->linkedIndividuals('ASSO'),
4913763c3f2SGreg Roach			$person->linkedIndividuals('_ASSO'),
4923763c3f2SGreg Roach			$person->linkedFamilies('ASSO'),
4933763c3f2SGreg Roach			$person->linkedFamilies('_ASSO')
4943763c3f2SGreg Roach		);
4953763c3f2SGreg Roach		foreach ($associates as $associate) {
4963763c3f2SGreg Roach			foreach ($associate->getFacts() as $fact) {
4973763c3f2SGreg Roach				$arec = $fact->getAttribute('_ASSO');
4983763c3f2SGreg Roach				if (!$arec) {
4993763c3f2SGreg Roach					$arec = $fact->getAttribute('ASSO');
5003763c3f2SGreg Roach				}
5013763c3f2SGreg Roach				if ($arec && trim($arec, '@') === $person->getXref()) {
5023763c3f2SGreg Roach					// Extract the important details from the fact
5033763c3f2SGreg Roach					$factrec = '1 ' . $fact->getTag();
5043763c3f2SGreg Roach					if (preg_match('/\n2 DATE .*/', $fact->getGedcom(), $match)) {
5053763c3f2SGreg Roach						$factrec .= $match[0];
5063763c3f2SGreg Roach					}
5073763c3f2SGreg Roach					if (preg_match('/\n2 PLAC .*/', $fact->getGedcom(), $match)) {
5083763c3f2SGreg Roach						$factrec .= $match[0];
5093763c3f2SGreg Roach					}
5103763c3f2SGreg Roach					if ($associate instanceof Family) {
5113763c3f2SGreg Roach						foreach ($associate->getSpouses() as $spouse) {
5123763c3f2SGreg Roach							$factrec .= "\n2 _ASSO @" . $spouse->getXref() . '@';
5133763c3f2SGreg Roach						}
5143763c3f2SGreg Roach					} else {
5153763c3f2SGreg Roach						$factrec .= "\n2 _ASSO @" . $associate->getXref() . '@';
5163763c3f2SGreg Roach					}
5173763c3f2SGreg Roach					$facts[] = new Fact($factrec, $associate, 'asso');
5183763c3f2SGreg Roach				}
5193763c3f2SGreg Roach			}
5203763c3f2SGreg Roach		}
5213763c3f2SGreg Roach
5223763c3f2SGreg Roach		return $facts;
5233763c3f2SGreg Roach	}
5243763c3f2SGreg Roach}
525