1<?php 2/** 3 * webtrees: online genealogy 4 * Copyright (C) 2018 webtrees development team 5 * This program is free software: you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation, either version 3 of the License, or 8 * (at your option) any later version. 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * You should have received a copy of the GNU General Public License 14 * along with this program. If not, see <http://www.gnu.org/licenses/>. 15 */ 16namespace Fisharebest\Webtrees\Module; 17 18use Fisharebest\Webtrees\Controller\ChartController; 19use Fisharebest\Webtrees\Filter; 20use Fisharebest\Webtrees\I18N; 21use Fisharebest\Webtrees\Individual; 22use Fisharebest\Webtrees\Menu; 23use Fisharebest\Webtrees\Module\InteractiveTree\TreeView; 24use Fisharebest\Webtrees\View; 25 26/** 27 * Class InteractiveTreeModule 28 * Tip : you could change the number of generations loaded before ajax calls both in individual page and in treeview page to optimize speed and server load 29 */ 30class InteractiveTreeModule extends AbstractModule implements ModuleTabInterface, ModuleChartInterface { 31 /** {@inheritdoc} */ 32 public function getTitle() { 33 return /* I18N: Name of a module */ I18N::translate('Interactive tree'); 34 } 35 36 /** {@inheritdoc} */ 37 public function getDescription() { 38 return /* I18N: Description of the “Interactive tree” module */ I18N::translate('An interactive tree, showing all the ancestors and descendants of an individual.'); 39 } 40 41 /** {@inheritdoc} */ 42 public function defaultTabOrder() { 43 return 68; 44 } 45 46 /** {@inheritdoc} */ 47 public function getTabContent() { 48 global $controller; 49 50 $tv = new TreeView('tvTab'); 51 list($html, $js) = $tv->drawViewport($controller->record, 3); 52 53 return 54 '<script src="' . $this->js() . '"></script>' . 55 '<script>' . $js . '</script>' . 56 $html; 57 } 58 59 /** {@inheritdoc} */ 60 public function hasTabContent() { 61 return true; 62 } 63 64 /** {@inheritdoc} */ 65 public function isGrayedOut() { 66 return false; 67 } 68 69 /** {@inheritdoc} */ 70 public function canLoadAjax() { 71 return true; 72 } 73 74 /** 75 * Return a menu item for this chart. 76 * 77 * @param Individual $individual 78 * 79 * @return Menu|null 80 */ 81 public function getChartMenu(Individual $individual) { 82 return new Menu( 83 $this->getTitle(), 84 'module.php?mod=tree&mod_action=treeview&rootid=' . $individual->getXref() . '&ged=' . $individual->getTree()->getNameUrl(), 85 'menu-chart-tree', 86 ['rel' => 'nofollow'] 87 ); 88 } 89 90 /** 91 * Return a menu item for this chart - for use in individual boxes. 92 * 93 * @param Individual $individual 94 * 95 * @return Menu|null 96 */ 97 public function getBoxChartMenu(Individual $individual) { 98 return $this->getChartMenu($individual); 99 } 100 101 /** {@inheritdoc} */ 102 public function getPreLoadContent() { 103 // We cannot use $("head").append(<link rel="stylesheet" ...as jQuery is not loaded at this time 104 return 105 '<script> 106 if (document.createStyleSheet) { 107 document.createStyleSheet("' . $this->css() . '"); // For Internet Explorer 108 } else { 109 var newSheet=document.createElement("link"); 110 newSheet.setAttribute("rel","stylesheet"); 111 newSheet.setAttribute("type","text/css"); 112 newSheet.setAttribute("href","' . $this->css() . '"); 113 document.getElementsByTagName("head")[0].appendChild(newSheet); 114 } 115 </script>'; 116 } 117 118 /** 119 * This is a general purpose hook, allowing modules to respond to routes 120 * of the form module.php?mod=FOO&mod_action=BAR 121 * 122 * @param string $mod_action 123 */ 124 public function modAction($mod_action) { 125 global $controller, $WT_TREE; 126 127 switch ($mod_action) { 128 case 'treeview': 129 $controller = new ChartController; 130 $tv = new TreeView('tv'); 131 132 $person = $controller->getSignificantIndividual(); 133 134 list($html, $js) = $tv->drawViewport($person, 4); 135 136 $controller 137 ->setPageTitle(I18N::translate('Interactive tree of %s', $person->getFullName())) 138 ->pageHeader() 139 ->addExternalJavascript($this->js()) 140 ->addInlineJavascript($js) 141 ->addInlineJavascript(' 142 if (document.createStyleSheet) { 143 document.createStyleSheet("' . $this->css() . '"); // For Internet Explorer 144 } else { 145 $("head").append(\'<link rel="stylesheet" type="text/css" href="' . $this->css() . '">\'); 146 } 147 '); 148 149 echo View::make('interactive-tree-page', [ 150 'title' => $controller->getPageTitle(), 151 'individual' => $controller->root, 152 'html' => $html, 153 //'css' => $this->css(), 154 //'js' => $this->js(), 155 ]); 156 157 break; 158 159 case 'getDetails': 160 header('Content-Type: text/html; charset=UTF-8'); 161 $pid = Filter::get('pid', WT_REGEX_XREF); 162 $i = Filter::get('instance'); 163 $tv = new TreeView($i); 164 $individual = Individual::getInstance($pid, $WT_TREE); 165 if ($individual) { 166 echo $tv->getDetails($individual); 167 } 168 break; 169 170 case 'getPersons': 171 header('Content-Type: text/html; charset=UTF-8'); 172 $q = Filter::get('q'); 173 $i = Filter::get('instance'); 174 $tv = new TreeView($i); 175 echo $tv->getPersons($q); 176 break; 177 178 default: 179 http_response_code(404); 180 break; 181 } 182 } 183 184 /** 185 * URL for our style sheet. 186 * 187 * @return string 188 */ 189 public function css() { 190 return WT_MODULES_DIR . $this->getName() . '/css/treeview.css'; 191 } 192 193 /** 194 * URL for our JavaScript. 195 * 196 * @return string 197 */ 198 public function js() { 199 return WT_MODULES_DIR . $this->getName() . '/js/treeview.js'; 200 } 201} 202