xref: /webtrees/app/Module/InteractiveTreeModule.php (revision 353b36ab5fd4f6ba09f89e2865edee7108bdf7c0)
18c2e8227SGreg Roach<?php
28c2e8227SGreg Roach/**
38c2e8227SGreg Roach * webtrees: online genealogy
48fcd0d32SGreg Roach * Copyright (C) 2019 webtrees development team
58c2e8227SGreg Roach * This program is free software: you can redistribute it and/or modify
68c2e8227SGreg Roach * it under the terms of the GNU General Public License as published by
78c2e8227SGreg Roach * the Free Software Foundation, either version 3 of the License, or
88c2e8227SGreg Roach * (at your option) any later version.
98c2e8227SGreg Roach * This program is distributed in the hope that it will be useful,
108c2e8227SGreg Roach * but WITHOUT ANY WARRANTY; without even the implied warranty of
118c2e8227SGreg Roach * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
128c2e8227SGreg Roach * GNU General Public License for more details.
138c2e8227SGreg Roach * You should have received a copy of the GNU General Public License
148c2e8227SGreg Roach * along with this program. If not, see <http://www.gnu.org/licenses/>.
158c2e8227SGreg Roach */
16e7f56f2aSGreg Roachdeclare(strict_types=1);
17e7f56f2aSGreg Roach
1876692c8bSGreg Roachnamespace Fisharebest\Webtrees\Module;
1976692c8bSGreg Roach
200bc54ba3SGreg Roachuse Fisharebest\Webtrees\Exceptions\IndividualAccessDeniedException;
210bc54ba3SGreg Roachuse Fisharebest\Webtrees\Exceptions\IndividualNotFoundException;
228d0ebef0SGreg Roachuse Fisharebest\Webtrees\Gedcom;
230e62c4b8SGreg Roachuse Fisharebest\Webtrees\I18N;
240e62c4b8SGreg Roachuse Fisharebest\Webtrees\Individual;
25168ff6f3Sric2016use Fisharebest\Webtrees\Menu;
26e46b0479SScrutinizer Auto-Fixeruse Fisharebest\Webtrees\Module\InteractiveTree\TreeView;
27e2ae4578SGreg Roachuse Fisharebest\Webtrees\Tree;
288d0ebef0SGreg Roachuse Fisharebest\Webtrees\Webtrees;
29e2ae4578SGreg Roachuse Symfony\Component\HttpFoundation\Request;
30e2ae4578SGreg Roachuse Symfony\Component\HttpFoundation\Response;
318c2e8227SGreg Roach
328c2e8227SGreg Roach/**
338c2e8227SGreg Roach * Class InteractiveTreeModule
348c2e8227SGreg Roach * 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
358c2e8227SGreg Roach */
3649a243cbSGreg Roachclass InteractiveTreeModule extends AbstractModule implements ModuleInterface, ModuleChartInterface, ModuleTabInterface
37c1010edaSGreg Roach{
3849a243cbSGreg Roach    use ModuleChartTrait;
3949a243cbSGreg Roach    use ModuleTabTrait;
4049a243cbSGreg Roach
41961ec755SGreg Roach    /**
42961ec755SGreg Roach     * How should this module be labelled on tabs, menus, etc.?
43961ec755SGreg Roach     *
44961ec755SGreg Roach     * @return string
45961ec755SGreg Roach     */
4649a243cbSGreg Roach    public function title(): string
47c1010edaSGreg Roach    {
48bbb76c12SGreg Roach        /* I18N: Name of a module */
49bbb76c12SGreg Roach        return I18N::translate('Interactive tree');
508c2e8227SGreg Roach    }
518c2e8227SGreg Roach
52961ec755SGreg Roach    /**
53961ec755SGreg Roach     * A sentence describing what this module does.
54961ec755SGreg Roach     *
55961ec755SGreg Roach     * @return string
56961ec755SGreg Roach     */
5749a243cbSGreg Roach    public function description(): string
58c1010edaSGreg Roach    {
59bbb76c12SGreg Roach        /* I18N: Description of the “Interactive tree” module */
60bbb76c12SGreg Roach        return I18N::translate('An interactive tree, showing all the ancestors and descendants of an individual.');
618c2e8227SGreg Roach    }
628c2e8227SGreg Roach
6349a243cbSGreg Roach    /**
6449a243cbSGreg Roach     * The default position for this tab.  It can be changed in the control panel.
6549a243cbSGreg Roach     *
6649a243cbSGreg Roach     * @return int
6749a243cbSGreg Roach     */
68cbf4b7faSGreg Roach    public function defaultTabOrder(): int
69cbf4b7faSGreg Roach    {
70*353b36abSGreg Roach        return 9;
718c2e8227SGreg Roach    }
728c2e8227SGreg Roach
738c2e8227SGreg Roach    /** {@inheritdoc} */
749b34404bSGreg Roach    public function getTabContent(Individual $individual): string
75c1010edaSGreg Roach    {
76225e381fSGreg Roach        $treeview = new TreeView('tvTab');
7765e02381SGreg Roach        [$html, $js] = $treeview->drawViewport($individual, 3);
788c2e8227SGreg Roach
79a8cd57e1SGreg Roach        return view('modules/tree/tab', [
80225e381fSGreg Roach            'html'         => $html,
81225e381fSGreg Roach            'js'           => $js,
82d5691647SGreg Roach            'treeview_css' => $this->css(),
83d5691647SGreg Roach            'treeview_js'  => $this->js(),
84225e381fSGreg Roach        ]);
858c2e8227SGreg Roach    }
868c2e8227SGreg Roach
87d5691647SGreg Roach    /**
88d5691647SGreg Roach     * @return string
89d5691647SGreg Roach     */
90c1010edaSGreg Roach    public function css(): string
91c1010edaSGreg Roach    {
928d0ebef0SGreg Roach        return Webtrees::MODULES_PATH . $this->getName() . '/css/treeview.css';
93d5691647SGreg Roach    }
94d5691647SGreg Roach
95d5691647SGreg Roach    /**
96d5691647SGreg Roach     * @return string
97d5691647SGreg Roach     */
98c1010edaSGreg Roach    public function js(): string
99c1010edaSGreg Roach    {
1008d0ebef0SGreg Roach        return Webtrees::MODULES_PATH . $this->getName() . '/js/treeview.js';
101d5691647SGreg Roach    }
102d5691647SGreg Roach
1038c2e8227SGreg Roach    /** {@inheritdoc} */
1049b34404bSGreg Roach    public function hasTabContent(Individual $individual): bool
105c1010edaSGreg Roach    {
10615d603e7SGreg Roach        return true;
1078c2e8227SGreg Roach    }
1088c2e8227SGreg Roach
1098c2e8227SGreg Roach    /** {@inheritdoc} */
1109b34404bSGreg Roach    public function isGrayedOut(Individual $individual): bool
111c1010edaSGreg Roach    {
1128c2e8227SGreg Roach        return false;
1138c2e8227SGreg Roach    }
1148c2e8227SGreg Roach
1158c2e8227SGreg Roach    /** {@inheritdoc} */
1169b34404bSGreg Roach    public function canLoadAjax():  bool
117c1010edaSGreg Roach    {
1188c2e8227SGreg Roach        return true;
1198c2e8227SGreg Roach    }
1208c2e8227SGreg Roach
121168ff6f3Sric2016    /**
122377a2979SGreg Roach     * CSS class for the URL.
123377a2979SGreg Roach     *
124377a2979SGreg Roach     * @return string
125377a2979SGreg Roach     */
126377a2979SGreg Roach    public function chartMenuClass(): string
127377a2979SGreg Roach    {
128377a2979SGreg Roach        return 'menu-chart-tree';
129377a2979SGreg Roach    }
130377a2979SGreg Roach
131377a2979SGreg Roach    /**
1324eb71cfaSGreg Roach     * Return a menu item for this chart - for use in individual boxes.
1334eb71cfaSGreg Roach     *
13460bc3e3fSGreg Roach     * @param Individual $individual
13560bc3e3fSGreg Roach     *
1364eb71cfaSGreg Roach     * @return Menu|null
1374eb71cfaSGreg Roach     */
138377a2979SGreg Roach    public function chartBoxMenu(Individual $individual): ?Menu
139c1010edaSGreg Roach    {
140e6562982SGreg Roach        return $this->chartMenu($individual);
141e6562982SGreg Roach    }
142e6562982SGreg Roach
143e6562982SGreg Roach    /**
144e6562982SGreg Roach     * The title for a specific instance of this chart.
145e6562982SGreg Roach     *
146e6562982SGreg Roach     * @param Individual $individual
147e6562982SGreg Roach     *
148e6562982SGreg Roach     * @return string
149e6562982SGreg Roach     */
150e6562982SGreg Roach    public function chartTitle(Individual $individual): string
151e6562982SGreg Roach    {
152e6562982SGreg Roach        /* I18N: %s is an individual’s name */
153e6562982SGreg Roach        return I18N::translate('Interactive tree of %s', $individual->getFullName());
154e6562982SGreg Roach    }
155e6562982SGreg Roach
156e6562982SGreg Roach    /**
157e6562982SGreg Roach     * The URL for this chart.
158e6562982SGreg Roach     *
159e6562982SGreg Roach     * @param Individual $individual
160e6562982SGreg Roach     * @param string[]   $parameters
161e6562982SGreg Roach     *
162e6562982SGreg Roach     * @return string
163e6562982SGreg Roach     */
164e6562982SGreg Roach    public function chartUrl(Individual $individual, array $parameters = []): string
165e6562982SGreg Roach    {
166e6562982SGreg Roach        return route('module', [
167e6562982SGreg Roach            'module' => $this->getName(),
168e6562982SGreg Roach            'action' => 'Treeview',
169e6562982SGreg Roach            'xref'   => $individual->xref(),
170e6562982SGreg Roach            'ged'    => $individual->tree()->name(),
171e6562982SGreg Roach        ] + $parameters);
172e6562982SGreg Roach    }
173e6562982SGreg Roach
174e6562982SGreg Roach    /**
175e2ae4578SGreg Roach     * @param Request $request
176b6db7c1fSGreg Roach     * @param Tree    $tree
17776692c8bSGreg Roach     *
178e2ae4578SGreg Roach     * @return Response
17976692c8bSGreg Roach     */
180b6db7c1fSGreg Roach    public function getTreeviewAction(Request $request, Tree $tree): Response
181c1010edaSGreg Roach    {
1829e648e55SGreg Roach        $xref = $request->get('xref', '');
183e2ae4578SGreg Roach
184e2ae4578SGreg Roach        $individual = Individual::getInstance($xref, $tree);
185bfaf8159SGreg Roach
186bfaf8159SGreg Roach        if ($individual === null) {
18759f2f229SGreg Roach            throw new IndividualNotFoundException();
188bfaf8159SGreg Roach        }
189bfaf8159SGreg Roach
190bfaf8159SGreg Roach        if (!$individual->canShow()) {
19159f2f229SGreg Roach            throw new IndividualAccessDeniedException();
192bfaf8159SGreg Roach        }
193bfaf8159SGreg Roach
1948c2e8227SGreg Roach        $tv = new TreeView('tv');
1958c2e8227SGreg Roach
19665e02381SGreg Roach        [$html, $js] = $tv->drawViewport($individual, 4);
1978c2e8227SGreg Roach
198e2ae4578SGreg Roach        $title = I18N::translate('Interactive tree of %s', $individual->getFullName());
1998c2e8227SGreg Roach
200e2ae4578SGreg Roach        return $this->viewResponse('interactive-tree-page', [
201e2ae4578SGreg Roach            'title'      => $title,
2028840c547SGreg Roach            'individual' => $individual,
203e2ae4578SGreg Roach            'js'         => $js,
204f8a18b14SGreg Roach            'html'       => $html,
205e2ae4578SGreg Roach            'tree'       => $tree,
206f8a18b14SGreg Roach        ]);
2078c2e8227SGreg Roach    }
2088c2e8227SGreg Roach
209e2ae4578SGreg Roach    /**
210e2ae4578SGreg Roach     * @param Request $request
211b6db7c1fSGreg Roach     * @param Tree    $tree
212e2ae4578SGreg Roach     *
213e2ae4578SGreg Roach     * @return Response
214e2ae4578SGreg Roach     */
215b6db7c1fSGreg Roach    public function getDetailsAction(Request $request, Tree $tree): Response
216c1010edaSGreg Roach    {
2178d0ebef0SGreg Roach        $pid        = $request->get('pid', Gedcom::REGEX_XREF);
218e2ae4578SGreg Roach        $individual = Individual::getInstance($pid, $tree);
219e2ae4578SGreg Roach
2200bc54ba3SGreg Roach        if ($individual === null) {
22159f2f229SGreg Roach            throw new IndividualNotFoundException();
2220bc54ba3SGreg Roach        }
2230bc54ba3SGreg Roach
2240bc54ba3SGreg Roach        if (!$individual->canShow()) {
22559f2f229SGreg Roach            throw new IndividualAccessDeniedException();
2260bc54ba3SGreg Roach        }
2270bc54ba3SGreg Roach
2289e648e55SGreg Roach        $instance = $request->get('instance', '');
229e2ae4578SGreg Roach        $treeview = new TreeView($instance);
230e2ae4578SGreg Roach
231e2ae4578SGreg Roach        return new Response($treeview->getDetails($individual));
2328c2e8227SGreg Roach    }
2338c2e8227SGreg Roach
2348c2e8227SGreg Roach    /**
235e2ae4578SGreg Roach     * @param Request $request
236b6db7c1fSGreg Roach     * @param Tree    $tree
2373cf92ae2SGreg Roach     *
238e2ae4578SGreg Roach     * @return Response
2398c2e8227SGreg Roach     */
240b6db7c1fSGreg Roach    public function getPersonsAction(Request $request, Tree $tree): Response
241c1010edaSGreg Roach    {
2429e648e55SGreg Roach        $q        = $request->get('q', '');
2439e648e55SGreg Roach        $instance = $request->get('instance', '');
244e2ae4578SGreg Roach        $treeview = new TreeView($instance);
2458c2e8227SGreg Roach
246bc8b8f24SGreg Roach        return new Response($treeview->getPersons($tree, $q));
2478c2e8227SGreg Roach    }
2488c2e8227SGreg Roach}
249