xref: /webtrees/app/Module/InteractiveTreeModule.php (revision 1f3fb95c905e623518962b025974a0e6c19d068b)
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\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&amp;mod_action=treeview&amp;rootid=' . $individual->getXref() . '&amp;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