1<?php 2namespace Fisharebest\Webtrees; 3 4/** 5 * webtrees: online genealogy 6 * Copyright (C) 2015 webtrees development team 7 * This program is free software: you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation, either version 3 of the License, or 10 * (at your option) any later version. 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * You should have received a copy of the GNU General Public License 16 * along with this program. If not, see <http://www.gnu.org/licenses/>. 17 */ 18 19/** 20 * Class FamilyNavigatorModule 21 */ 22class FamilyNavigatorModule extends Module implements ModuleSidebarInterface { 23 24 const TTL = "<div class='flyout2'>%s</div>"; 25 const LNK = "<div class='flyout3' data-href='%s'>%s</div>"; 26 const MSG = "<div class='flyout4'>(%s)</div>"; // class flyout4 not used in standard themes 27 28 /** {@inheritdoc} */ 29 public function getTitle() { 30 return /* I18N: Name of a module/sidebar */ I18N::translate('Family navigator'); 31 } 32 33 /** {@inheritdoc} */ 34 public function getDescription() { 35 return /* I18N: Description of the “Family navigator” module */ I18N::translate('A sidebar showing an individual’s close families and relatives.'); 36 } 37 38 /** {@inheritdoc} */ 39 public function defaultSidebarOrder() { 40 return 20; 41 } 42 43 /** {@inheritdoc} */ 44 public function hasSidebarContent() { 45 return !Auth::isSearchEngine(); 46 } 47 48 /** {@inheritdoc} */ 49 public function getSidebarAjaxContent() { 50 return ''; 51 } 52 53 /** {@inheritdoc} */ 54 public function getSidebarContent() { 55 global $controller; 56 57 $controller->addInlineJavascript(' 58 jQuery("#sb_family_nav_content") 59 .on("click", ".flyout a", function() { 60 return false; 61 }) 62 .on("click", ".flyout3", function() { 63 window.location.href = jQuery(this).data("href"); 64 return false; 65 }); 66 '); 67 68 ob_start(); 69 70 ?> 71 <div id="sb_family_nav_content"> 72 <table class="nav_content"> 73 74 <?php 75 //-- parent families ------------------------------------------------------------- 76 foreach ($controller->record->getChildFamilies() as $family) { 77 $this->drawFamily($family, $controller->record->getChildFamilyLabel($family)); 78 } 79 //-- step parents ---------------------------------------------------------------- 80 foreach ($controller->record->getChildStepFamilies() as $family) { 81 $this->drawFamily($family, $controller->record->getStepFamilyLabel($family)); 82 } 83 //-- spouse and children -------------------------------------------------- 84 foreach ($controller->record->getSpouseFamilies() as $family) { 85 $this->drawFamily($family, $controller->record->getSpouseFamilyLabel($family)); 86 } 87 //-- step children ---------------------------------------------------------------- 88 foreach ($controller->record->getSpouseStepFamilies() as $family) { 89 $this->drawFamily($family, $family->getFullName()); 90 } 91 ?> 92 </table> 93 </div> 94 <?php 95 96 return ob_get_clean(); 97 } 98 99 /** 100 * @param Family $family 101 * @param string $title 102 */ 103 private function drawFamily(Family $family, $title) { 104 global $controller, $SHOW_PRIVATE_RELATIONSHIPS; 105 106 ?> 107 <tr> 108 <td class="center" colspan="2"> 109 <a class="famnav_title" href="<?php echo $family->getHtmlUrl(); ?>"> 110 <?php echo $title; ?> 111 </a> 112 </td> 113 </tr> 114 <?php 115 $access_level = $SHOW_PRIVATE_RELATIONSHIPS ? Auth::PRIV_HIDE : Auth::accessLevel($family->getTree()); 116 $facts = array_merge($family->getFacts('HUSB', false, $access_level), $family->getFacts('WIFE', false, $access_level)); 117 foreach ($facts as $fact) { 118 $spouse = $fact->getTarget(); 119 if ($spouse instanceof Individual) { 120 $menu = new Menu(get_close_relationship_name($controller->record, $spouse)); 121 $menu->addClass('', 'submenu flyout'); 122 $menu->addSubmenu(new Menu($this->getParents($spouse))); 123 ?> 124 <tr> 125 <td class="facts_label"> 126 <?php echo $menu->getMenu(); ?> 127 </td> 128 <td class="center <?php echo $controller->getPersonStyle($spouse); ?> nam"> 129 <a class="famnav_link" href="<?php echo $spouse->getHtmlUrl(); ?>"> 130 <?php echo $spouse->getFullName(); ?> 131 </a> 132 <div class="font9"> 133 <?php echo $spouse->getLifeSpan(); ?> 134 </div> 135 </td> 136 </tr> 137 <?php 138 } 139 } 140 141 foreach ($family->getFacts('CHIL', false, $access_level) as $fact) { 142 $child = $fact->getTarget(); 143 if ($child instanceof Individual) { 144 $menu = new Menu(get_close_relationship_name($controller->record, $child)); 145 $menu->addClass('', 'submenu flyout'); 146 $menu->addSubmenu(new Menu($this->getFamily($child))); 147 ?> 148 <tr> 149 <td class="facts_label"> 150 <?php echo $menu->getMenu(); ?> 151 </td> 152 <td class="center <?php echo $controller->getPersonStyle($child); ?> nam"> 153 <a class="famnav_link" href="<?php echo $child->getHtmlUrl(); ?>"> 154 <?php echo $child->getFullName(); ?> 155 </a> 156 <div class="font9"> 157 <?php echo $child->getLifeSpan(); ?> 158 </div> 159 </td> 160 </tr> 161 <?php 162 } 163 } 164 } 165 166 /** 167 * @param $person 168 * @param boolean $showUnknown 169 * 170 * @return string 171 */ 172 private function getHTML($person, $showUnknown = false) { 173 if ($person instanceof Individual) { 174 return sprintf(self::LNK, $person->getHtmlUrl(), $person->getFullName()); 175 } elseif ($showUnknown) { 176 return sprintf(self::MSG, I18N::translate('unknown')); 177 } else { 178 return ''; 179 } 180 } 181 182 /** 183 * @param Individual $person 184 * 185 * @return string 186 */ 187 private function getParents(Individual $person) { 188 $father = null; 189 $mother = null; 190 $html = sprintf(self::TTL, I18N::translate('Parents')); 191 $family = $person->getPrimaryChildFamily(); 192 if (!Auth::isSearchEngine() && $person->canShowName() && $family !== null) { 193 $father = $family->getHusband(); 194 $mother = $family->getWife(); 195 $html .= $this->getHTML($father) . 196 $this->getHTML($mother); 197 198 // Can only have a step parent if one & only one parent found at this point 199 if ($father instanceof Individual xor $mother instanceof Individual) { 200 $stepParents = ''; 201 foreach ($person->getChildStepFamilies() as $family) { 202 if (!$father instanceof Individual) { 203 $stepParents .= $this->getHTML($family->getHusband()); 204 } else { 205 $stepParents .= $this->getHTML($family->getWife()); 206 } 207 } 208 if ($stepParents) { 209 $relationship = $father instanceof Individual ? 210 I18N::translateContext("father’s wife", "step-mother") : I18N::translateContext("mother’s husband", "step-father"); 211 $html .= sprintf(self::TTL, $relationship) . $stepParents; 212 } 213 } 214 } 215 if (!($father instanceof Individual || $mother instanceof Individual)) { 216 $html .= sprintf(self::MSG, I18N::translateContext('unknown family', 'unknown')); 217 } 218 return $html; 219 } 220 221 /** 222 * @param Individual $person 223 * 224 * @return string 225 */ 226 private function getFamily(Individual $person) { 227 $html = ''; 228 if ($person->canShowName() && !Auth::isSearchEngine()) { 229 foreach ($person->getSpouseFamilies() as $family) { 230 $spouse = $family->getSpouse($person); 231 $html .= $this->getHTML($spouse, true); 232 $children = $family->getChildren(); 233 if (count($children) > 0) { 234 $html .= "<ul class='clist'>"; 235 foreach ($children as $child) { 236 $html .= '<li>' . $this->getHTML($child) . '</li>'; 237 } 238 $html .= '</ul>'; 239 } 240 } 241 } 242 if (!$html) { 243 $html = sprintf(self::MSG, I18N::translate('none')); 244 } 245 return sprintf(self::TTL, I18N::translate('Family')) . $html; 246 } 247 248} 249