1<?php 2namespace Fisharebest\Webtrees\Module; 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 */ 18use Fisharebest\Webtrees\Auth; 19use Fisharebest\Webtrees\Family; 20use Fisharebest\Webtrees\I18N; 21use Fisharebest\Webtrees\Individual; 22use Fisharebest\Webtrees\Menu; 23 24/** 25 * Class FamilyNavigatorModule 26 */ 27class FamilyNavigatorModule extends AbstractModule implements ModuleSidebarInterface { 28 const TTL = "<div class='flyout2'>%s</div>"; 29 const LNK = "<div class='flyout3' data-href='%s'>%s</div>"; 30 const MSG = "<div class='flyout4'>(%s)</div>"; // class flyout4 not used in standard themes 31 32 /** {@inheritdoc} */ 33 public function getTitle() { 34 return /* I18N: Name of a module/sidebar */ I18N::translate('Family navigator'); 35 } 36 37 /** {@inheritdoc} */ 38 public function getDescription() { 39 return /* I18N: Description of the “Family navigator” module */ I18N::translate('A sidebar showing an individual’s close families and relatives.'); 40 } 41 42 /** {@inheritdoc} */ 43 public function defaultSidebarOrder() { 44 return 20; 45 } 46 47 /** {@inheritdoc} */ 48 public function hasSidebarContent() { 49 return !Auth::isSearchEngine(); 50 } 51 52 /** {@inheritdoc} */ 53 public function getSidebarAjaxContent() { 54 return ''; 55 } 56 57 /** {@inheritdoc} */ 58 public function getSidebarContent() { 59 global $controller; 60 61 $controller->addInlineJavascript(' 62 jQuery("#sb_family_nav_content") 63 .on("click", ".flyout a", function() { 64 return false; 65 }) 66 .on("click", ".flyout3", function() { 67 window.location.href = jQuery(this).data("href"); 68 return false; 69 }); 70 '); 71 72 ob_start(); 73 74 ?> 75 <div id="sb_family_nav_content"> 76 <table class="nav_content"> 77 78 <?php 79 //-- parent families ------------------------------------------------------------- 80 foreach ($controller->record->getChildFamilies() as $family) { 81 $this->drawFamily($family, $controller->record->getChildFamilyLabel($family)); 82 } 83 //-- step parents ---------------------------------------------------------------- 84 foreach ($controller->record->getChildStepFamilies() as $family) { 85 $this->drawFamily($family, $controller->record->getStepFamilyLabel($family)); 86 } 87 //-- spouse and children -------------------------------------------------- 88 foreach ($controller->record->getSpouseFamilies() as $family) { 89 $this->drawFamily($family, $controller->getSpouseFamilyLabel($family, $controller->record)); 90 } 91 //-- step children ---------------------------------------------------------------- 92 foreach ($controller->record->getSpouseStepFamilies() as $family) { 93 $this->drawFamily($family, $family->getFullName()); 94 } 95 ?> 96 </table> 97 </div> 98 <?php 99 100 return ob_get_clean(); 101 } 102 103 /** 104 * @param Family $family 105 * @param string $title 106 */ 107 private function drawFamily(Family $family, $title) { 108 global $controller; 109 110 ?> 111 <tr> 112 <td class="center" colspan="2"> 113 <a class="famnav_title" href="<?php echo $family->getHtmlUrl(); ?>"> 114 <?php echo $title; ?> 115 </a> 116 </td> 117 </tr> 118 <?php 119 foreach ($family->getSpouses() as $spouse) { 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 foreach ($family->getChildren() as $child) { 141 $menu = new Menu(get_close_relationship_name($controller->record, $child)); 142 $menu->addClass('', 'submenu flyout'); 143 $menu->addSubmenu(new Menu($this->getFamily($child))); 144 ?> 145 <tr> 146 <td class="facts_label"> 147 <?php echo $menu->getMenu(); ?> 148 </td> 149 <td class="center <?php echo $controller->getPersonStyle($child); ?> nam"> 150 <a class="famnav_link" href="<?php echo $child->getHtmlUrl(); ?>"> 151 <?php echo $child->getFullName(); ?> 152 </a> 153 <div class="font9"> 154 <?php echo $child->getLifeSpan(); ?> 155 </div> 156 </td> 157 </tr> 158 <?php 159 } 160 } 161 162 /** 163 * @param $person 164 * @param bool $showUnknown 165 * 166 * @return string 167 */ 168 private function getHTML($person, $showUnknown = false) { 169 if ($person instanceof Individual) { 170 return sprintf(self::LNK, $person->getHtmlUrl(), $person->getFullName()); 171 } elseif ($showUnknown) { 172 return sprintf(self::MSG, I18N::translate('unknown')); 173 } else { 174 return ''; 175 } 176 } 177 178 /** 179 * @param Individual $person 180 * 181 * @return string 182 */ 183 private function getParents(Individual $person) { 184 $father = null; 185 $mother = null; 186 $html = sprintf(self::TTL, I18N::translate('Parents')); 187 $family = $person->getPrimaryChildFamily(); 188 if (!Auth::isSearchEngine() && $person->canShowName() && $family !== null) { 189 $father = $family->getHusband(); 190 $mother = $family->getWife(); 191 $html .= $this->getHTML($father) . 192 $this->getHTML($mother); 193 194 // Can only have a step parent if one & only one parent found at this point 195 if ($father instanceof Individual xor $mother instanceof Individual) { 196 $stepParents = ''; 197 foreach ($person->getChildStepFamilies() as $family) { 198 if (!$father instanceof Individual) { 199 $stepParents .= $this->getHTML($family->getHusband()); 200 } else { 201 $stepParents .= $this->getHTML($family->getWife()); 202 } 203 } 204 if ($stepParents) { 205 $relationship = $father instanceof Individual ? 206 I18N::translateContext("father’s wife", "step-mother") : I18N::translateContext("mother’s husband", "step-father"); 207 $html .= sprintf(self::TTL, $relationship) . $stepParents; 208 } 209 } 210 } 211 if (!($father instanceof Individual || $mother instanceof Individual)) { 212 $html .= sprintf(self::MSG, I18N::translateContext('unknown family', 'unknown')); 213 } 214 215 return $html; 216 } 217 218 /** 219 * @param Individual $person 220 * 221 * @return string 222 */ 223 private function getFamily(Individual $person) { 224 $html = ''; 225 if ($person->canShowName() && !Auth::isSearchEngine()) { 226 foreach ($person->getSpouseFamilies() as $family) { 227 $spouse = $family->getSpouse($person); 228 $html .= $this->getHTML($spouse, true); 229 $children = $family->getChildren(); 230 if (count($children) > 0) { 231 $html .= "<ul class='clist'>"; 232 foreach ($children as $child) { 233 $html .= '<li>' . $this->getHTML($child) . '</li>'; 234 } 235 $html .= '</ul>'; 236 } 237 } 238 } 239 if (!$html) { 240 $html = sprintf(self::MSG, I18N::translate('none')); 241 } 242 243 return sprintf(self::TTL, I18N::translate('Family')) . $html; 244 } 245 246} 247