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\I18N; 19use Fisharebest\Webtrees\Individual; 20use Fisharebest\Webtrees\Menu; 21use Fisharebest\Webtrees\Module\InteractiveTree\TreeView; 22use Fisharebest\Webtrees\Tree; 23use Symfony\Component\HttpFoundation\Request; 24use Symfony\Component\HttpFoundation\Response; 25use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; 26 27/** 28 * Class InteractiveTreeModule 29 * 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 30 */ 31class InteractiveTreeModule extends AbstractModule implements ModuleTabInterface, ModuleChartInterface { 32 /** {@inheritdoc} */ 33 public function getTitle() { 34 return /* I18N: Name of a module */ 35 I18N::translate('Interactive tree'); 36 } 37 38 /** {@inheritdoc} */ 39 public function getDescription() { 40 return /* I18N: Description of the “Interactive tree” module */ 41 I18N::translate('An interactive tree, showing all the ancestors and descendants of an individual.'); 42 } 43 44 /** {@inheritdoc} */ 45 public function defaultTabOrder() { 46 return 68; 47 } 48 49 /** {@inheritdoc} */ 50 public function getTabContent(Individual $individual) { 51 $treeview = new TreeView('tvTab'); 52 list($html, $js) = $treeview->drawViewport($individual, 3); 53 54 return view('modules/tree/tab', [ 55 'html' => $html, 56 'js' => $js, 57 'treeview_css' => $this->css(), 58 'treeview_js' => $this->js(), 59 ]); 60 } 61 62 /** 63 * @return string 64 */ 65 public function css(): string { 66 return WT_MODULES_DIR . $this->getName() . '/css/treeview.css'; 67 } 68 69 /** 70 * @return string 71 */ 72 public function js(): string { 73 return WT_MODULES_DIR . $this->getName() . '/js/treeview.js'; 74 } 75 76 /** {@inheritdoc} */ 77 public function hasTabContent(Individual $individual) { 78 return true; 79 } 80 81 /** {@inheritdoc} */ 82 public function isGrayedOut(Individual $individual) { 83 return false; 84 } 85 86 /** {@inheritdoc} */ 87 public function canLoadAjax() { 88 return true; 89 } 90 91 /** 92 * Return a menu item for this chart. 93 * 94 * @param Individual $individual 95 * 96 * @return Menu|null 97 */ 98 public function getChartMenu(Individual $individual) { 99 return new Menu( 100 $this->getTitle(), 101 e(route('module', ['module' => $this->getName(), 'action' => 'Treeview', 'xref' => $individual->getXref(), 'ged' => $individual->getTree()->getName()])), 102 'menu-chart-tree', 103 ['rel' => 'nofollow'] 104 ); 105 } 106 107 /** 108 * Return a menu item for this chart - for use in individual boxes. 109 * 110 * @param Individual $individual 111 * 112 * @return Menu|null 113 */ 114 public function getBoxChartMenu(Individual $individual) { 115 return $this->getChartMenu($individual); 116 } 117 118 /** 119 * @param Request $request 120 * 121 * @return Response 122 */ 123 public function getTreeviewAction(Request $request): Response { 124 /** @var Tree $tree */ 125 $tree = $request->attributes->get('tree'); 126 127 $xref = $request->get('xref'); 128 129 $individual = Individual::getInstance($xref, $tree); 130 $tv = new TreeView('tv'); 131 132 list($html, $js) = $tv->drawViewport($individual, 4); 133 134 $title = I18N::translate('Interactive tree of %s', $individual->getFullName()); 135 136 return $this->viewResponse('interactive-tree-page', [ 137 'title' => $title, 138 'individual' => $individual, 139 'js' => $js, 140 'html' => $html, 141 'tree' => $tree, 142 ]); 143 } 144 145 /** 146 * @param Request $request 147 * 148 * @return Response 149 */ 150 public function getDetailsAction(Request $request): Response { 151 /** @var Tree $tree */ 152 $tree = $request->attributes->get('tree'); 153 154 $pid = $request->get('pid', WT_REGEX_XREF); 155 $individual = Individual::getInstance($pid, $tree); 156 157 if ($individual && $individual->canShow()) { 158 $instance = $request->get('instance'); 159 $treeview = new TreeView($instance); 160 161 return new Response($treeview->getDetails($individual)); 162 } else { 163 throw new NotFoundHttpException; 164 } 165 } 166 167 /** 168 * @param Request $request 169 * 170 * @return Response 171 */ 172 public function getPersonsAction(Request $request): Response { 173 $q = $request->get('q'); 174 $instance = $request->get('instance'); 175 $treeview = new TreeView($instance); 176 177 return new Response($treeview->getPersons($q)); 178 } 179} 180