xref: /webtrees/app/Module/InteractiveTreeModule.php (revision d32a32162970e6bfef5abe5397602a75311438d3)
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;
24
25/**
26 * Class InteractiveTreeModule
27 * 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
28 */
29class InteractiveTreeModule extends AbstractModule implements ModuleTabInterface, ModuleChartInterface {
30	/** {@inheritdoc} */
31	public function getTitle() {
32		return /* I18N: Name of a module */ I18N::translate('Interactive tree');
33	}
34
35	/** {@inheritdoc} */
36	public function getDescription() {
37		return /* I18N: Description of the “Interactive tree” module */ I18N::translate('An interactive tree, showing all the ancestors and descendants of an individual.');
38	}
39
40	/** {@inheritdoc} */
41	public function defaultTabOrder() {
42		return 68;
43	}
44
45	/** {@inheritdoc} */
46	public function getTabContent(Individual $individual) {
47		$treeview        = new TreeView('tvTab');
48		list($html, $js) = $treeview->drawViewport($individual, 3);
49
50		return view('tabs/treeview', [
51			'html'         => $html,
52			'js'           => $js,
53			'treeview_css' => $this->css(),
54			'treeview_js'  => $this->js(),
55		]);
56	}
57
58	/** {@inheritdoc} */
59	public function hasTabContent(Individual $individual) {
60		return true;
61	}
62
63	/** {@inheritdoc} */
64	public function isGrayedOut(Individual $individual) {
65		return false;
66	}
67
68	/** {@inheritdoc} */
69	public function canLoadAjax() {
70		return true;
71	}
72
73	/**
74	 * Return a menu item for this chart.
75	 *
76	 * @param Individual $individual
77	 *
78	 * @return Menu|null
79	 */
80	public function getChartMenu(Individual $individual) {
81		return new Menu(
82			$this->getTitle(),
83			'module.php?mod=tree&amp;mod_action=treeview&amp;rootid=' . $individual->getXref() . '&amp;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	 * @param Individual $individual
93	 *
94	 * @return Menu|null
95	 */
96	public function getBoxChartMenu(Individual $individual) {
97		return $this->getChartMenu($individual);
98	}
99
100	/**
101	 * This is a general purpose hook, allowing modules to respond to routes
102	 * of the form module.php?mod=FOO&mod_action=BAR
103	 *
104	 * @param string $mod_action
105	 */
106	public function modAction($mod_action) {
107		global $controller, $WT_TREE;
108
109		switch ($mod_action) {
110			case 'treeview':
111				$controller = new ChartController;
112				$tv         = new TreeView('tv');
113
114				$person = $controller->getSignificantIndividual();
115
116				list($html, $js) = $tv->drawViewport($person, 4);
117
118				$controller
119					->setPageTitle(I18N::translate('Interactive tree of %s', $person->getFullName()))
120					->pageHeader()
121					->addExternalJavascript($this->js())
122					->addInlineJavascript($js)
123					->addInlineJavascript('
124					if (document.createStyleSheet) {
125						document.createStyleSheet("' . $this->css() . '"); // For Internet Explorer
126					} else {
127						$("head").append(\'<link rel="stylesheet" type="text/css" href="' . $this->css() . '">\');
128					}
129				');
130
131				echo view('interactive-tree-page', [
132					'title'      => $controller->getPageTitle(),
133					'individual' => $controller->root,
134					'html'       => $html,
135					//'css'        => $this->css(),
136					//'js'         => $this->js(),
137				]);
138
139				break;
140
141			case 'getDetails':
142				header('Content-Type: text/html; charset=UTF-8');
143				$pid        = Filter::get('pid', WT_REGEX_XREF);
144				$i          = Filter::get('instance');
145				$tv         = new TreeView($i);
146				$individual = Individual::getInstance($pid, $WT_TREE);
147				if ($individual) {
148					echo $tv->getDetails($individual);
149				}
150				break;
151
152			case 'getPersons':
153				header('Content-Type: text/html; charset=UTF-8');
154				$q  = Filter::get('q');
155				$i  = Filter::get('instance');
156				$tv = new TreeView($i);
157				echo $tv->getPersons($q);
158				break;
159
160			default:
161				http_response_code(404);
162				break;
163		}
164	}
165
166	/**
167	 * URL for our style sheet.
168	 *
169	 * @return string
170	 */
171	public function css() {
172		return WT_MODULES_DIR . $this->getName() . '/css/treeview.css';
173	}
174
175	/**
176	 * URL for our JavaScript.
177	 *
178	 * @return string
179	 */
180	public function js() {
181		return WT_MODULES_DIR . $this->getName() . '/js/treeview.js';
182	}
183}
184