xref: /webtrees/app/Module/InteractiveTreeModule.php (revision 1001c3a8c3f3447dd95f8a9481ce18ff581bd6da)
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		/** @var Tree $tree */
174		$tree = $request->attributes->get('tree');
175
176		$q  = $request->get('q');
177		$instance = $request->get('instance');
178		$treeview = new TreeView($instance);
179
180		return new Response($treeview->getPersons($tree, $q));
181	}
182}
183