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