13763c3f2SGreg Roach<?php 20e62c4b8SGreg Roachnamespace Fisharebest\Webtrees\Module; 33763c3f2SGreg Roach 43763c3f2SGreg Roach/** 53763c3f2SGreg Roach * webtrees: online genealogy 63763c3f2SGreg Roach * Copyright (C) 2015 webtrees development team 73763c3f2SGreg Roach * This program is free software: you can redistribute it and/or modify 83763c3f2SGreg Roach * it under the terms of the GNU General Public License as published by 93763c3f2SGreg Roach * the Free Software Foundation, either version 3 of the License, or 103763c3f2SGreg Roach * (at your option) any later version. 113763c3f2SGreg Roach * This program is distributed in the hope that it will be useful, 123763c3f2SGreg Roach * but WITHOUT ANY WARRANTY; without even the implied warranty of 133763c3f2SGreg Roach * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 143763c3f2SGreg Roach * GNU General Public License for more details. 153763c3f2SGreg Roach * You should have received a copy of the GNU General Public License 163763c3f2SGreg Roach * along with this program. If not, see <http://www.gnu.org/licenses/>. 173763c3f2SGreg Roach */ 180e62c4b8SGreg Roachuse Fisharebest\Webtrees\Auth; 190e62c4b8SGreg Roachuse Fisharebest\Webtrees\Date; 200e62c4b8SGreg Roachuse Fisharebest\Webtrees\Fact; 210e62c4b8SGreg Roachuse Fisharebest\Webtrees\Family; 22*3d7a8a4cSGreg Roachuse Fisharebest\Webtrees\Functions\Functions; 23*3d7a8a4cSGreg Roachuse Fisharebest\Webtrees\Functions\FunctionsPrint; 24*3d7a8a4cSGreg 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 119*3d7a8a4cSGreg Roach Functions::sortFacts($indifacts); 1203763c3f2SGreg Roach 1213763c3f2SGreg Roach ob_start(); 1223763c3f2SGreg Roach 1233763c3f2SGreg Roach echo '<table class="facts_table">'; 1243763c3f2SGreg Roach echo '<tbody>'; 1253763c3f2SGreg Roach if (!$indifacts) { 1263763c3f2SGreg Roach echo '<tr><td colspan="2" class="facts_value">', I18N::translate('There are no facts for this individual.'), '</td></tr>'; 1273763c3f2SGreg Roach } 1283763c3f2SGreg Roach 1293763c3f2SGreg Roach echo '<tr><td colspan="2" class="descriptionbox rela"><form action="?"><input id="checkbox_rela_facts" type="checkbox" '; 1303763c3f2SGreg Roach echo $controller->record->getTree()->getPreference('EXPAND_RELATIVES_EVENTS') ? 'checked' : ''; 1313763c3f2SGreg Roach echo ' onclick="jQuery(\'tr.rela\').toggle();"><label for="checkbox_rela_facts">', I18N::translate('Events of close relatives'), '</label>'; 1323763c3f2SGreg Roach if (file_exists(Site::getPreference('INDEX_DIRECTORY') . 'histo.' . WT_LOCALE . '.php')) { 1333763c3f2SGreg Roach echo ' <input id="checkbox_histo" type="checkbox" '; 1343763c3f2SGreg Roach echo $EXPAND_HISTO_EVENTS ? 'checked' : ''; 1353763c3f2SGreg Roach echo ' onclick="jQuery(\'tr.histo\').toggle();"><label for="checkbox_histo">', I18N::translate('Historical facts'), '</label>'; 1363763c3f2SGreg Roach } 1373763c3f2SGreg Roach echo '</form></td></tr>'; 1383763c3f2SGreg Roach 1393763c3f2SGreg Roach foreach ($indifacts as $fact) { 140*3d7a8a4cSGreg Roach FunctionsPrintFacts::printFact($fact, $controller->record); 1413763c3f2SGreg Roach } 1423763c3f2SGreg Roach 1433763c3f2SGreg Roach //-- new fact link 1443763c3f2SGreg Roach if ($controller->record->canEdit()) { 145*3d7a8a4cSGreg Roach FunctionsPrint::printAddNewFact($controller->record->getXref(), $indifacts, 'INDI'); 1463763c3f2SGreg Roach } 1473763c3f2SGreg Roach echo '</tbody>'; 1483763c3f2SGreg Roach echo '</table>'; 1493763c3f2SGreg Roach 1503763c3f2SGreg Roach if (!$controller->record->getTree()->getPreference('EXPAND_RELATIVES_EVENTS')) { 1513763c3f2SGreg Roach echo '<script>jQuery("tr.rela").toggle();</script>'; 1523763c3f2SGreg Roach } 1533763c3f2SGreg Roach if (!$EXPAND_HISTO_EVENTS) { 1543763c3f2SGreg Roach echo '<script>jQuery("tr.histo").toggle();</script>'; 1553763c3f2SGreg Roach } 1563763c3f2SGreg Roach 1573763c3f2SGreg Roach return '<div id="' . $this->getName() . '_content">' . ob_get_clean() . '</div>'; 1583763c3f2SGreg Roach } 1593763c3f2SGreg Roach 1603763c3f2SGreg Roach /** {@inheritdoc} */ 1613763c3f2SGreg Roach public function hasTabContent() { 1623763c3f2SGreg Roach return true; 1633763c3f2SGreg Roach } 1643763c3f2SGreg Roach 1653763c3f2SGreg Roach /** {@inheritdoc} */ 1663763c3f2SGreg Roach public function canLoadAjax() { 1673763c3f2SGreg Roach return !Auth::isSearchEngine(); // Search engines cannot use AJAX 1683763c3f2SGreg Roach } 1693763c3f2SGreg Roach 1703763c3f2SGreg Roach /** {@inheritdoc} */ 1713763c3f2SGreg Roach public function getPreLoadContent() { 1723763c3f2SGreg Roach return ''; 1733763c3f2SGreg Roach } 1743763c3f2SGreg Roach 1753763c3f2SGreg Roach /** 1763763c3f2SGreg Roach * Spouse facts that are shown on an individual’s page. 1773763c3f2SGreg Roach * 1783763c3f2SGreg Roach * @param Individual $individual Show events that occured during the lifetime of this individual 1793763c3f2SGreg Roach * @param Individual $spouse Show events of this individual 1803763c3f2SGreg Roach * 1813763c3f2SGreg Roach * @return Fact[] 1823763c3f2SGreg Roach */ 1833763c3f2SGreg Roach private static function spouseFacts(Individual $individual, Individual $spouse) { 1843763c3f2SGreg Roach $SHOW_RELATIVES_EVENTS = $individual->getTree()->getPreference('SHOW_RELATIVES_EVENTS'); 1853763c3f2SGreg Roach 1863763c3f2SGreg Roach $facts = array(); 1873763c3f2SGreg Roach if (strstr($SHOW_RELATIVES_EVENTS, '_DEAT_SPOU')) { 1883763c3f2SGreg Roach // Only include events between birth and death 1893763c3f2SGreg Roach $birt_date = $individual->getEstimatedBirthDate(); 1903763c3f2SGreg Roach $deat_date = $individual->getEstimatedDeathDate(); 1913763c3f2SGreg Roach 1923763c3f2SGreg Roach foreach ($spouse->getFacts(WT_EVENTS_DEAT) as $fact) { 1933763c3f2SGreg Roach 1943763c3f2SGreg Roach $fact_date = $fact->getDate(); 1953763c3f2SGreg Roach if ($fact_date->isOK() && Date::compare($birt_date, $fact_date) <= 0 && Date::compare($fact_date, $deat_date) <= 0) { 1963763c3f2SGreg Roach // Convert the event to a close relatives event. 1973763c3f2SGreg Roach $rela_fact = clone($fact); 1983763c3f2SGreg Roach $rela_fact->setTag('_' . $fact->getTag() . '_SPOU'); 1993763c3f2SGreg Roach $facts[] = $rela_fact; 2003763c3f2SGreg Roach } 2013763c3f2SGreg Roach } 2023763c3f2SGreg Roach } 2033763c3f2SGreg Roach 2043763c3f2SGreg Roach return $facts; 2053763c3f2SGreg Roach } 2063763c3f2SGreg Roach 2073763c3f2SGreg Roach /** 2083763c3f2SGreg Roach * Get the events of children and grandchildren. 2093763c3f2SGreg Roach * 2103763c3f2SGreg Roach * @param Individual $person 2113763c3f2SGreg Roach * @param Family $family 2123763c3f2SGreg Roach * @param string $option 2133763c3f2SGreg Roach * @param string $relation 2143763c3f2SGreg Roach * 2153763c3f2SGreg Roach * @return Fact[] 2163763c3f2SGreg Roach */ 2173763c3f2SGreg Roach private static function childFacts(Individual $person, Family $family, $option, $relation) { 2183763c3f2SGreg Roach global $controller; 2193763c3f2SGreg Roach 2203763c3f2SGreg Roach $SHOW_RELATIVES_EVENTS = $person->getTree()->getPreference('SHOW_RELATIVES_EVENTS'); 2213763c3f2SGreg Roach 2223763c3f2SGreg Roach $facts = array(); 2233763c3f2SGreg Roach 2243763c3f2SGreg Roach // Only include events between birth and death 2253763c3f2SGreg Roach $birt_date = $controller->record->getEstimatedBirthDate(); 2263763c3f2SGreg Roach $deat_date = $controller->record->getEstimatedDeathDate(); 2273763c3f2SGreg Roach 2283763c3f2SGreg Roach // Deal with recursion. 2293763c3f2SGreg Roach switch ($option) { 2303763c3f2SGreg Roach case '_CHIL': 2313763c3f2SGreg Roach // Add grandchildren 2323763c3f2SGreg Roach foreach ($family->getChildren() as $child) { 2333763c3f2SGreg Roach foreach ($child->getSpouseFamilies() as $cfamily) { 2343763c3f2SGreg Roach switch ($child->getSex()) { 2353763c3f2SGreg Roach case 'M': 2363763c3f2SGreg Roach foreach (self::childFacts($person, $cfamily, '_GCHI', 'son') as $fact) { 2373763c3f2SGreg Roach $facts[] = $fact; 2383763c3f2SGreg Roach } 2393763c3f2SGreg Roach break; 2403763c3f2SGreg Roach case 'F': 2413763c3f2SGreg Roach foreach (self::childFacts($person, $cfamily, '_GCHI', 'dau') as $fact) { 2423763c3f2SGreg Roach $facts[] = $fact; 2433763c3f2SGreg Roach } 2443763c3f2SGreg Roach break; 2453763c3f2SGreg Roach default: 2463763c3f2SGreg Roach foreach (self::childFacts($person, $cfamily, '_GCHI', 'chi') as $fact) { 2473763c3f2SGreg Roach $facts[] = $fact; 2483763c3f2SGreg Roach } 2493763c3f2SGreg Roach break; 2503763c3f2SGreg Roach } 2513763c3f2SGreg Roach } 2523763c3f2SGreg Roach } 2533763c3f2SGreg Roach break; 2543763c3f2SGreg Roach } 2553763c3f2SGreg Roach 2563763c3f2SGreg Roach // For each child in the family 2573763c3f2SGreg Roach foreach ($family->getChildren() as $child) { 2583763c3f2SGreg Roach if ($child->getXref() == $person->getXref()) { 2593763c3f2SGreg Roach // We are not our own sibling! 2603763c3f2SGreg Roach continue; 2613763c3f2SGreg Roach } 2623763c3f2SGreg Roach // add child’s birth 2633763c3f2SGreg Roach if (strpos($SHOW_RELATIVES_EVENTS, '_BIRT' . str_replace('_HSIB', '_SIBL', $option)) !== false) { 2643763c3f2SGreg Roach foreach ($child->getFacts(WT_EVENTS_BIRT) as $fact) { 2653763c3f2SGreg Roach $sgdate = $fact->getDate(); 2663763c3f2SGreg Roach // Always show _BIRT_CHIL, even if the dates are not known 2673763c3f2SGreg Roach if ($option == '_CHIL' || $sgdate->isOK() && Date::compare($birt_date, $sgdate) <= 0 && Date::compare($sgdate, $deat_date) <= 0) { 2683763c3f2SGreg Roach if ($option == '_GCHI' && $relation == 'dau') { 2693763c3f2SGreg Roach // Convert the event to a close relatives event. 2703763c3f2SGreg Roach $rela_fact = clone($fact); 2713763c3f2SGreg Roach $rela_fact->setTag('_' . $fact->getTag() . '_GCH1'); 2723763c3f2SGreg Roach $facts[] = $rela_fact; 2733763c3f2SGreg Roach } elseif ($option == '_GCHI' && $relation == 'son') { 2743763c3f2SGreg Roach // Convert the event to a close relatives event. 2753763c3f2SGreg Roach $rela_fact = clone($fact); 2763763c3f2SGreg Roach $rela_fact->setTag('_' . $fact->getTag() . '_GCH2'); 2773763c3f2SGreg Roach $facts[] = $rela_fact; 2783763c3f2SGreg Roach } else { 2793763c3f2SGreg Roach // Convert the event to a close relatives event. 2803763c3f2SGreg Roach $rela_fact = clone($fact); 2813763c3f2SGreg Roach $rela_fact->setTag('_' . $fact->getTag() . $option); 2823763c3f2SGreg Roach $facts[] = $rela_fact; 2833763c3f2SGreg Roach } 2843763c3f2SGreg Roach } 2853763c3f2SGreg Roach } 2863763c3f2SGreg Roach } 2873763c3f2SGreg Roach // add child’s death 2883763c3f2SGreg Roach if (strpos($SHOW_RELATIVES_EVENTS, '_DEAT' . str_replace('_HSIB', '_SIBL', $option)) !== false) { 2893763c3f2SGreg Roach foreach ($child->getFacts(WT_EVENTS_DEAT) as $fact) { 2903763c3f2SGreg Roach $sgdate = $fact->getDate(); 2913763c3f2SGreg Roach if ($sgdate->isOK() && Date::compare($birt_date, $sgdate) <= 0 && Date::compare($sgdate, $deat_date) <= 0) { 2923763c3f2SGreg Roach if ($option == '_GCHI' && $relation == 'dau') { 2933763c3f2SGreg Roach // Convert the event to a close relatives event. 2943763c3f2SGreg Roach $rela_fact = clone($fact); 2953763c3f2SGreg Roach $rela_fact->setTag('_' . $fact->getTag() . '_GCH1'); 2963763c3f2SGreg Roach $facts[] = $rela_fact; 2973763c3f2SGreg Roach } elseif ($option == '_GCHI' && $relation == 'son') { 2983763c3f2SGreg Roach // Convert the event to a close relatives event. 2993763c3f2SGreg Roach $rela_fact = clone($fact); 3003763c3f2SGreg Roach $rela_fact->setTag('_' . $fact->getTag() . '_GCH2'); 3013763c3f2SGreg Roach $facts[] = $rela_fact; 3023763c3f2SGreg Roach } else { 3033763c3f2SGreg Roach // Convert the event to a close relatives event. 3043763c3f2SGreg Roach $rela_fact = clone($fact); 3053763c3f2SGreg Roach $rela_fact->setTag('_' . $fact->getTag() . $option); 3063763c3f2SGreg Roach $facts[] = $rela_fact; 3073763c3f2SGreg Roach } 3083763c3f2SGreg Roach } 3093763c3f2SGreg Roach } 3103763c3f2SGreg Roach } 3113763c3f2SGreg Roach // add child’s marriage 3123763c3f2SGreg Roach if (strstr($SHOW_RELATIVES_EVENTS, '_MARR' . str_replace('_HSIB', '_SIBL', $option))) { 3133763c3f2SGreg Roach foreach ($child->getSpouseFamilies() as $sfamily) { 3143763c3f2SGreg Roach foreach ($sfamily->getFacts(WT_EVENTS_MARR) as $fact) { 3153763c3f2SGreg Roach $sgdate = $fact->getDate(); 3163763c3f2SGreg Roach if ($sgdate->isOK() && Date::compare($birt_date, $sgdate) <= 0 && Date::compare($sgdate, $deat_date) <= 0) { 3173763c3f2SGreg Roach if ($option == '_GCHI' && $relation == 'dau') { 3183763c3f2SGreg Roach // Convert the event to a close relatives event. 3193763c3f2SGreg Roach $rela_fact = clone($fact); 3203763c3f2SGreg Roach $rela_fact->setTag('_' . $fact->getTag() . '_GCH1'); 3213763c3f2SGreg Roach $facts[] = $rela_fact; 3223763c3f2SGreg Roach } elseif ($option == '_GCHI' && $relation == 'son') { 3233763c3f2SGreg Roach // Convert the event to a close relatives event. 3243763c3f2SGreg Roach $rela_fact = clone($fact); 3253763c3f2SGreg Roach $rela_fact->setTag('_' . $fact->getTag() . '_GCH2'); 3263763c3f2SGreg Roach $facts[] = $rela_fact; 3273763c3f2SGreg Roach } else { 3283763c3f2SGreg Roach // Convert the event to a close relatives event. 3293763c3f2SGreg Roach $rela_fact = clone($fact); 3303763c3f2SGreg Roach $rela_fact->setTag('_' . $fact->getTag() . $option); 3313763c3f2SGreg Roach $facts[] = $rela_fact; 3323763c3f2SGreg Roach } 3333763c3f2SGreg Roach } 3343763c3f2SGreg Roach } 3353763c3f2SGreg Roach } 3363763c3f2SGreg Roach } 3373763c3f2SGreg Roach } 3383763c3f2SGreg Roach 3393763c3f2SGreg Roach return $facts; 3403763c3f2SGreg Roach } 3413763c3f2SGreg Roach 3423763c3f2SGreg Roach /** 3433763c3f2SGreg Roach * Get the events of parents and grandparents. 3443763c3f2SGreg Roach * 3453763c3f2SGreg Roach * @param Individual $person 346cbc1590aSGreg Roach * @param int $sosa 3473763c3f2SGreg Roach * 3483763c3f2SGreg Roach * @return Fact[] 3493763c3f2SGreg Roach */ 3503763c3f2SGreg Roach private static function parentFacts(Individual $person, $sosa) { 3513763c3f2SGreg Roach global $controller; 3523763c3f2SGreg Roach 3533763c3f2SGreg Roach $SHOW_RELATIVES_EVENTS = $person->getTree()->getPreference('SHOW_RELATIVES_EVENTS'); 3543763c3f2SGreg Roach 3553763c3f2SGreg Roach $facts = array(); 3563763c3f2SGreg Roach 3573763c3f2SGreg Roach // Only include events between birth and death 3583763c3f2SGreg Roach $birt_date = $controller->record->getEstimatedBirthDate(); 3593763c3f2SGreg Roach $deat_date = $controller->record->getEstimatedDeathDate(); 3603763c3f2SGreg Roach 3613763c3f2SGreg Roach if ($sosa == 1) { 3623763c3f2SGreg Roach foreach ($person->getChildFamilies() as $family) { 3633763c3f2SGreg Roach // Add siblings 3643763c3f2SGreg Roach foreach (self::childFacts($person, $family, '_SIBL', '') as $fact) { 3653763c3f2SGreg Roach $facts[] = $fact; 3663763c3f2SGreg Roach } 3673763c3f2SGreg Roach foreach ($family->getSpouses() as $spouse) { 3683763c3f2SGreg Roach foreach ($spouse->getSpouseFamilies() as $sfamily) { 3693763c3f2SGreg Roach if ($family !== $sfamily) { 3703763c3f2SGreg Roach // Add half-siblings 3713763c3f2SGreg Roach foreach (self::childFacts($person, $sfamily, '_HSIB', '') as $fact) { 3723763c3f2SGreg Roach $facts[] = $fact; 3733763c3f2SGreg Roach } 3743763c3f2SGreg Roach } 3753763c3f2SGreg Roach } 3763763c3f2SGreg Roach // Add grandparents 3773763c3f2SGreg Roach foreach (self::parentFacts($spouse, $spouse->getSex() == 'F' ? 3 : 2) as $fact) { 3783763c3f2SGreg Roach $facts[] = $fact; 3793763c3f2SGreg Roach } 3803763c3f2SGreg Roach } 3813763c3f2SGreg Roach } 3823763c3f2SGreg Roach 3833763c3f2SGreg Roach if (strstr($SHOW_RELATIVES_EVENTS, '_MARR_PARE')) { 3843763c3f2SGreg Roach // add father/mother marriages 3853763c3f2SGreg Roach foreach ($person->getChildFamilies() as $sfamily) { 3863763c3f2SGreg Roach foreach ($sfamily->getFacts(WT_EVENTS_MARR) as $fact) { 3873763c3f2SGreg Roach if ($fact->getDate()->isOK() && Date::compare($birt_date, $fact->getDate()) <= 0 && Date::compare($fact->getDate(), $deat_date) <= 0) { 3883763c3f2SGreg Roach // marriage of parents (to each other) 3893763c3f2SGreg Roach $rela_fact = clone($fact); 3903763c3f2SGreg Roach $rela_fact->setTag('_' . $fact->getTag() . '_FAMC'); 3913763c3f2SGreg Roach $facts[] = $rela_fact; 3923763c3f2SGreg Roach } 3933763c3f2SGreg Roach } 3943763c3f2SGreg Roach } 3953763c3f2SGreg Roach foreach ($person->getChildStepFamilies() as $sfamily) { 3963763c3f2SGreg Roach foreach ($sfamily->getFacts(WT_EVENTS_MARR) as $fact) { 3973763c3f2SGreg Roach if ($fact->getDate()->isOK() && Date::compare($birt_date, $fact->getDate()) <= 0 && Date::compare($fact->getDate(), $deat_date) <= 0) { 3983763c3f2SGreg Roach // marriage of a parent (to another spouse) 3993763c3f2SGreg Roach // Convert the event to a close relatives event 4003763c3f2SGreg Roach $rela_fact = clone($fact); 4013763c3f2SGreg Roach $rela_fact->setTag('_' . $fact->getTag() . '_PARE'); 4023763c3f2SGreg Roach $facts[] = $rela_fact; 4033763c3f2SGreg Roach } 4043763c3f2SGreg Roach } 4053763c3f2SGreg Roach } 4063763c3f2SGreg Roach } 4073763c3f2SGreg Roach } 4083763c3f2SGreg Roach 4093763c3f2SGreg Roach foreach ($person->getChildFamilies() as $family) { 4103763c3f2SGreg Roach foreach ($family->getSpouses() as $parent) { 4113763c3f2SGreg Roach if (strstr($SHOW_RELATIVES_EVENTS, '_DEAT' . ($sosa == 1 ? '_PARE' : '_GPAR'))) { 4123763c3f2SGreg Roach foreach ($parent->getFacts(WT_EVENTS_DEAT) as $fact) { 4133763c3f2SGreg Roach if ($fact->getDate()->isOK() && Date::compare($birt_date, $fact->getDate()) <= 0 && Date::compare($fact->getDate(), $deat_date) <= 0) { 4143763c3f2SGreg Roach switch ($sosa) { 4153763c3f2SGreg Roach case 1: 4163763c3f2SGreg Roach // Convert the event to a close relatives event. 4173763c3f2SGreg Roach $rela_fact = clone($fact); 4183763c3f2SGreg Roach $rela_fact->setTag('_' . $fact->getTag() . '_PARE'); 4193763c3f2SGreg Roach $facts[] = $rela_fact; 4203763c3f2SGreg Roach break; 4213763c3f2SGreg Roach case 2: 4223763c3f2SGreg Roach // Convert the event to a close relatives event 4233763c3f2SGreg Roach $rela_fact = clone($fact); 4243763c3f2SGreg Roach $rela_fact->setTag('_' . $fact->getTag() . '_GPA1'); 4253763c3f2SGreg Roach $facts[] = $rela_fact; 4263763c3f2SGreg Roach break; 4273763c3f2SGreg Roach case 3: 4283763c3f2SGreg Roach // Convert the event to a close relatives event 4293763c3f2SGreg Roach $rela_fact = clone($fact); 4303763c3f2SGreg Roach $rela_fact->setTag('_' . $fact->getTag() . '_GPA2'); 4313763c3f2SGreg Roach $facts[] = $rela_fact; 4323763c3f2SGreg Roach break; 4333763c3f2SGreg Roach } 4343763c3f2SGreg Roach } 4353763c3f2SGreg Roach } 4363763c3f2SGreg Roach } 4373763c3f2SGreg Roach } 4383763c3f2SGreg Roach } 4393763c3f2SGreg Roach 4403763c3f2SGreg Roach return $facts; 4413763c3f2SGreg Roach } 4423763c3f2SGreg Roach 4433763c3f2SGreg Roach /** 4443763c3f2SGreg Roach * Get any historical events. 4453763c3f2SGreg Roach * 4463763c3f2SGreg Roach * @param Individual $person 4473763c3f2SGreg Roach * 4483763c3f2SGreg Roach * @return Fact[] 4493763c3f2SGreg Roach */ 4503763c3f2SGreg Roach private static function historicalFacts(Individual $person) { 4513763c3f2SGreg Roach $SHOW_RELATIVES_EVENTS = $person->getTree()->getPreference('SHOW_RELATIVES_EVENTS'); 4523763c3f2SGreg Roach 4533763c3f2SGreg Roach $facts = array(); 4543763c3f2SGreg Roach 4553763c3f2SGreg Roach if ($SHOW_RELATIVES_EVENTS) { 4563763c3f2SGreg Roach // Only include events between birth and death 4573763c3f2SGreg Roach $birt_date = $person->getEstimatedBirthDate(); 4583763c3f2SGreg Roach $deat_date = $person->getEstimatedDeathDate(); 4593763c3f2SGreg Roach 4603763c3f2SGreg Roach if (file_exists(Site::getPreference('INDEX_DIRECTORY') . 'histo.' . WT_LOCALE . '.php')) { 4613763c3f2SGreg Roach $histo = array(); 4623763c3f2SGreg Roach require Site::getPreference('INDEX_DIRECTORY') . 'histo.' . WT_LOCALE . '.php'; 4633763c3f2SGreg Roach foreach ($histo as $hist) { 4643763c3f2SGreg Roach // Earlier versions of the WIKI encouraged people to use HTML entities, 4653763c3f2SGreg Roach // rather than UTF8 encoding. 4663763c3f2SGreg Roach $hist = html_entity_decode($hist, ENT_QUOTES, 'UTF-8'); 4673763c3f2SGreg Roach 4683763c3f2SGreg Roach $fact = new Fact($hist, $person, 'histo'); 4693763c3f2SGreg Roach $sdate = $fact->getDate(); 4703763c3f2SGreg Roach if ($sdate->isOK() && Date::compare($birt_date, $sdate) <= 0 && Date::compare($sdate, $deat_date) <= 0) { 4713763c3f2SGreg Roach $facts[] = $fact; 4723763c3f2SGreg Roach } 4733763c3f2SGreg Roach } 4743763c3f2SGreg Roach } 4753763c3f2SGreg Roach } 4763763c3f2SGreg Roach 4773763c3f2SGreg Roach return $facts; 4783763c3f2SGreg Roach } 4793763c3f2SGreg Roach 4803763c3f2SGreg Roach /** 4813763c3f2SGreg Roach * Get the events of associates. 4823763c3f2SGreg Roach * 4833763c3f2SGreg Roach * @param Individual $person 4843763c3f2SGreg Roach * 4853763c3f2SGreg Roach * @return Fact[] 4863763c3f2SGreg Roach */ 4873763c3f2SGreg Roach private static function associateFacts(Individual $person) { 4883763c3f2SGreg Roach $facts = array(); 4893763c3f2SGreg Roach 4903763c3f2SGreg Roach $associates = array_merge( 4913763c3f2SGreg Roach $person->linkedIndividuals('ASSO'), 4923763c3f2SGreg Roach $person->linkedIndividuals('_ASSO'), 4933763c3f2SGreg Roach $person->linkedFamilies('ASSO'), 4943763c3f2SGreg Roach $person->linkedFamilies('_ASSO') 4953763c3f2SGreg Roach ); 4963763c3f2SGreg Roach foreach ($associates as $associate) { 4973763c3f2SGreg Roach foreach ($associate->getFacts() as $fact) { 4983763c3f2SGreg Roach $arec = $fact->getAttribute('_ASSO'); 4993763c3f2SGreg Roach if (!$arec) { 5003763c3f2SGreg Roach $arec = $fact->getAttribute('ASSO'); 5013763c3f2SGreg Roach } 5023763c3f2SGreg Roach if ($arec && trim($arec, '@') === $person->getXref()) { 5033763c3f2SGreg Roach // Extract the important details from the fact 5043763c3f2SGreg Roach $factrec = '1 ' . $fact->getTag(); 5053763c3f2SGreg Roach if (preg_match('/\n2 DATE .*/', $fact->getGedcom(), $match)) { 5063763c3f2SGreg Roach $factrec .= $match[0]; 5073763c3f2SGreg Roach } 5083763c3f2SGreg Roach if (preg_match('/\n2 PLAC .*/', $fact->getGedcom(), $match)) { 5093763c3f2SGreg Roach $factrec .= $match[0]; 5103763c3f2SGreg Roach } 5113763c3f2SGreg Roach if ($associate instanceof Family) { 5123763c3f2SGreg Roach foreach ($associate->getSpouses() as $spouse) { 5133763c3f2SGreg Roach $factrec .= "\n2 _ASSO @" . $spouse->getXref() . '@'; 5143763c3f2SGreg Roach } 5153763c3f2SGreg Roach } else { 5163763c3f2SGreg Roach $factrec .= "\n2 _ASSO @" . $associate->getXref() . '@'; 5173763c3f2SGreg Roach // CHR/BAPM events are commonly used. Generate the reverse relationship 5183763c3f2SGreg Roach if (preg_match('/^(?:BAPM|CHR)$/', $fact->getTag()) && preg_match('/2 _?ASSO @(' . $person->getXref() . ')@\n3 RELA god(?:parent|mother|father)/', $fact->getGedcom())) { 5193763c3f2SGreg Roach switch ($associate->getSex()) { 5203763c3f2SGreg Roach case 'M': 5213763c3f2SGreg Roach $factrec .= "\n3 RELA godson"; 5223763c3f2SGreg Roach break; 5233763c3f2SGreg Roach case 'F': 5243763c3f2SGreg Roach $factrec .= "\n3 RELA goddaughter"; 5253763c3f2SGreg Roach break; 5263763c3f2SGreg Roach default: 5273763c3f2SGreg Roach $factrec .= "\n3 RELA godchild"; 5283763c3f2SGreg Roach break; 5293763c3f2SGreg Roach } 5303763c3f2SGreg Roach } 5313763c3f2SGreg Roach } 5323763c3f2SGreg Roach $facts[] = new Fact($factrec, $associate, 'asso'); 5333763c3f2SGreg Roach } 5343763c3f2SGreg Roach } 5353763c3f2SGreg Roach } 5363763c3f2SGreg Roach 5373763c3f2SGreg Roach return $facts; 5383763c3f2SGreg Roach } 5393763c3f2SGreg Roach} 540