1<?php 2/** 3 * webtrees: online genealogy 4 * Copyright (C) 2017 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\Auth; 19use Fisharebest\Webtrees\Controller\ChartController; 20use Fisharebest\Webtrees\Filter; 21use Fisharebest\Webtrees\I18N; 22use Fisharebest\Webtrees\Individual; 23use Fisharebest\Webtrees\Menu; 24use Fisharebest\Webtrees\Module\InteractiveTree\TreeView; 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 src="' . WT_JQUERYUI_TOUCH_PUNCH_URL . '"></script>' . 56 '<script>' . $js . '</script>' . 57 $html; 58 } 59 60 /** {@inheritdoc} */ 61 public function hasTabContent() { 62 return !Auth::isSearchEngine(); 63 } 64 65 /** {@inheritdoc} */ 66 public function isGrayedOut() { 67 return false; 68 } 69 70 /** {@inheritdoc} */ 71 public function canLoadAjax() { 72 return true; 73 } 74 75 /** 76 * Return a menu item for this chart. 77 * 78 * @return Menu|null 79 */ 80 public function getChartMenu(Individual $individual) { 81 return new Menu( 82 $this->getTitle(), 83 'module.php?mod=tree&mod_action=treeview&rootid=' . $individual->getXref() . '&ged=' . $individual->getTree()->getNameUrl(), 84 'menu-chart-tree', 85 ['rel' => 'nofollow'] 86 ); 87 } 88 89 /** 90 * Return a menu item for this chart - for use in individual boxes. 91 * 92 * @return Menu|null 93 */ 94 public function getBoxChartMenu(Individual $individual) { 95 return $this->getChartMenu($individual); 96 } 97 98 /** {@inheritdoc} */ 99 public function getPreLoadContent() { 100 // We cannot use jQuery("head").append(<link rel="stylesheet" ...as jQuery is not loaded at this time 101 return 102 '<script> 103 if (document.createStyleSheet) { 104 document.createStyleSheet("' . $this->css() . '"); // For Internet Explorer 105 } else { 106 var newSheet=document.createElement("link"); 107 newSheet.setAttribute("rel","stylesheet"); 108 newSheet.setAttribute("type","text/css"); 109 newSheet.setAttribute("href","' . $this->css() . '"); 110 document.getElementsByTagName("head")[0].appendChild(newSheet); 111 } 112 </script>'; 113 } 114 115 /** 116 * This is a general purpose hook, allowing modules to respond to routes 117 * of the form module.php?mod=FOO&mod_action=BAR 118 * 119 * @param string $mod_action 120 */ 121 public function modAction($mod_action) { 122 global $controller, $WT_TREE; 123 124 switch ($mod_action) { 125 case 'treeview': 126 $controller = new ChartController; 127 $tv = new TreeView('tv'); 128 ob_start(); 129 130 $person = $controller->getSignificantIndividual(); 131 132 list($html, $js) = $tv->drawViewport($person, 4); 133 134 $controller 135 ->setPageTitle(I18N::translate('Interactive tree of %s', $person->getFullName())) 136 ->pageHeader() 137 ->addExternalJavascript($this->js()) 138 ->addExternalJavascript(WT_JQUERYUI_TOUCH_PUNCH_URL) 139 ->addInlineJavascript($js) 140 ->addInlineJavascript(' 141 if (document.createStyleSheet) { 142 document.createStyleSheet("' . $this->css() . '"); // For Internet Explorer 143 } else { 144 jQuery("head").append(\'<link rel="stylesheet" type="text/css" href="' . $this->css() . '">\'); 145 } 146 '); 147 echo $html; 148 break; 149 150 case 'getDetails': 151 header('Content-Type: text/html; charset=UTF-8'); 152 $pid = Filter::get('pid', WT_REGEX_XREF); 153 $i = Filter::get('instance'); 154 $tv = new TreeView($i); 155 $individual = Individual::getInstance($pid, $WT_TREE); 156 if ($individual) { 157 echo $tv->getDetails($individual); 158 } 159 break; 160 161 case 'getPersons': 162 header('Content-Type: text/html; charset=UTF-8'); 163 $q = Filter::get('q'); 164 $i = Filter::get('instance'); 165 $tv = new TreeView($i); 166 echo $tv->getPersons($q); 167 break; 168 169 default: 170 http_response_code(404); 171 break; 172 } 173 } 174 175 /** 176 * URL for our style sheet. 177 * 178 * @return string 179 */ 180 public function css() { 181 return WT_STATIC_URL . WT_MODULES_DIR . $this->getName() . '/css/treeview.css'; 182 } 183 184 /** 185 * URL for our JavaScript. 186 * 187 * @return string 188 */ 189 public function js() { 190 return WT_STATIC_URL . WT_MODULES_DIR . $this->getName() . '/js/treeview.js'; 191 } 192} 193