xref: /webtrees/app/Module/HourglassChartModule.php (revision 57ab22314b2599feb432b1a1ed71643cfc2f0452)
1168ff6f3Sric2016<?php
2168ff6f3Sric2016/**
3168ff6f3Sric2016 * webtrees: online genealogy
48fcd0d32SGreg Roach * Copyright (C) 2019 webtrees development team
5168ff6f3Sric2016 * This program is free software: you can redistribute it and/or modify
6168ff6f3Sric2016 * it under the terms of the GNU General Public License as published by
7168ff6f3Sric2016 * the Free Software Foundation, either version 3 of the License, or
8168ff6f3Sric2016 * (at your option) any later version.
9168ff6f3Sric2016 * This program is distributed in the hope that it will be useful,
10168ff6f3Sric2016 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11168ff6f3Sric2016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12168ff6f3Sric2016 * GNU General Public License for more details.
13168ff6f3Sric2016 * You should have received a copy of the GNU General Public License
14168ff6f3Sric2016 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15168ff6f3Sric2016 */
16e7f56f2aSGreg Roachdeclare(strict_types=1);
17e7f56f2aSGreg Roach
18168ff6f3Sric2016namespace Fisharebest\Webtrees\Module;
19168ff6f3Sric2016
2026684e68SGreg Roachuse Fisharebest\Webtrees\Auth;
21cb0eb4a9SGreg Roachuse Fisharebest\Webtrees\Family;
22168ff6f3Sric2016use Fisharebest\Webtrees\I18N;
23168ff6f3Sric2016use Fisharebest\Webtrees\Individual;
24e46b0479SScrutinizer Auto-Fixeruse Fisharebest\Webtrees\Menu;
2526684e68SGreg Roachuse Fisharebest\Webtrees\Tree;
26cb0eb4a9SGreg Roachuse Illuminate\Support\Collection;
276ccdf4f0SGreg Roachuse Psr\Http\Message\ResponseInterface;
286ccdf4f0SGreg Roachuse Psr\Http\Message\ServerRequestInterface;
29cb0eb4a9SGreg Roachuse function app;
30cb0eb4a9SGreg Roachuse function response;
31f4ba05e3SGreg Roachuse function view;
32168ff6f3Sric2016
33168ff6f3Sric2016/**
34168ff6f3Sric2016 * Class HourglassChartModule
35168ff6f3Sric2016 */
3637eb8894SGreg Roachclass HourglassChartModule extends AbstractModule implements ModuleChartInterface
37c1010edaSGreg Roach{
3849a243cbSGreg Roach    use ModuleChartTrait;
3949a243cbSGreg Roach
4026684e68SGreg Roach    // Defaults
4126684e68SGreg Roach    private const DEFAULT_GENERATIONS         = '3';
4226684e68SGreg Roach    private const DEFAULT_MAXIMUM_GENERATIONS = '9';
4326684e68SGreg Roach
4426684e68SGreg Roach    // Limits
45e759aebbSGreg Roach    private const MAXIMUM_GENERATIONS = 10;
4626684e68SGreg Roach    private const MINIMUM_GENERATIONS = 2;
4726684e68SGreg Roach
48168ff6f3Sric2016    /**
490cfd6963SGreg Roach     * How should this module be identified in the control panel, etc.?
50168ff6f3Sric2016     *
51168ff6f3Sric2016     * @return string
52168ff6f3Sric2016     */
5349a243cbSGreg Roach    public function title(): string
54c1010edaSGreg Roach    {
55bbb76c12SGreg Roach        /* I18N: Name of a module/chart */
56bbb76c12SGreg Roach        return I18N::translate('Hourglass chart');
57168ff6f3Sric2016    }
58168ff6f3Sric2016
59168ff6f3Sric2016    /**
60168ff6f3Sric2016     * A sentence describing what this module does.
61168ff6f3Sric2016     *
62168ff6f3Sric2016     * @return string
63168ff6f3Sric2016     */
6449a243cbSGreg Roach    public function description(): string
65c1010edaSGreg Roach    {
66bbb76c12SGreg Roach        /* I18N: Description of the “HourglassChart” module */
67bbb76c12SGreg Roach        return I18N::translate('An hourglass chart of an individual’s ancestors and descendants.');
68168ff6f3Sric2016    }
69168ff6f3Sric2016
70168ff6f3Sric2016    /**
71377a2979SGreg Roach     * CSS class for the URL.
72377a2979SGreg Roach     *
73377a2979SGreg Roach     * @return string
74377a2979SGreg Roach     */
75377a2979SGreg Roach    public function chartMenuClass(): string
76377a2979SGreg Roach    {
77377a2979SGreg Roach        return 'menu-chart-hourglass';
78377a2979SGreg Roach    }
79377a2979SGreg Roach
80377a2979SGreg Roach    /**
814eb71cfaSGreg Roach     * Return a menu item for this chart - for use in individual boxes.
824eb71cfaSGreg Roach     *
8360bc3e3fSGreg Roach     * @param Individual $individual
8460bc3e3fSGreg Roach     *
854eb71cfaSGreg Roach     * @return Menu|null
864eb71cfaSGreg Roach     */
87377a2979SGreg Roach    public function chartBoxMenu(Individual $individual): ?Menu
88c1010edaSGreg Roach    {
89e6562982SGreg Roach        return $this->chartMenu($individual);
90e6562982SGreg Roach    }
91e6562982SGreg Roach
92e6562982SGreg Roach    /**
9326684e68SGreg Roach     * A form to request the chart parameters.
94e6562982SGreg Roach     *
956ccdf4f0SGreg Roach     * @param ServerRequestInterface $request
96e6562982SGreg Roach     *
976ccdf4f0SGreg Roach     * @return ResponseInterface
98e6562982SGreg Roach     */
99*57ab2231SGreg Roach    public function getChartAction(ServerRequestInterface $request): ResponseInterface
100e6562982SGreg Roach    {
101*57ab2231SGreg Roach        $tree       = $request->getAttribute('tree');
102*57ab2231SGreg Roach        $user       = $request->getAttribute('user');
1030b93976aSGreg Roach        $ajax       = $request->getQueryParams()['ajax'] ?? '';
1040b93976aSGreg Roach        $xref       = $request->getQueryParams()['xref'] ?? '';
10526684e68SGreg Roach        $individual = Individual::getInstance($xref, $tree);
10626684e68SGreg Roach
10726684e68SGreg Roach        Auth::checkIndividualAccess($individual);
1089867b2f0SGreg Roach        Auth::checkComponentAccess($this, 'chart', $tree, $user);
10926684e68SGreg Roach
1100b93976aSGreg Roach        $generations = (int) ($request->getQueryParams()['generations'] ?? self::DEFAULT_GENERATIONS);
11126684e68SGreg Roach
112e759aebbSGreg Roach        $generations = min($generations, self::MAXIMUM_GENERATIONS);
11326684e68SGreg Roach        $generations = max($generations, self::MINIMUM_GENERATIONS);
11426684e68SGreg Roach
1150b93976aSGreg Roach        $show_spouse = (bool) ($request->getQueryParams()['show_spouse'] ?? false);
11626684e68SGreg Roach
1170b93976aSGreg Roach        if ($ajax === '1') {
11826684e68SGreg Roach            return $this->chart($individual, $generations, $show_spouse);
11926684e68SGreg Roach        }
12026684e68SGreg Roach
12126684e68SGreg Roach        $ajax_url = $this->chartUrl($individual, [
1229b5537c3SGreg Roach            'ajax'        => true,
1232b29a33eSmakitso            'generations' => $generations,
1242f0ffe95SGreg Roach            'show_spouse' => $show_spouse,
12526684e68SGreg Roach        ]);
12626684e68SGreg Roach
1279b5537c3SGreg Roach        return $this->viewResponse('modules/hourglass-chart/page', [
12826684e68SGreg Roach            'ajax_url'            => $ajax_url,
12926684e68SGreg Roach            'generations'         => $generations,
13026684e68SGreg Roach            'individual'          => $individual,
131e759aebbSGreg Roach            'maximum_generations' => self::MAXIMUM_GENERATIONS,
13226684e68SGreg Roach            'minimum_generations' => self::MINIMUM_GENERATIONS,
13326684e68SGreg Roach            'module_name'         => $this->name(),
13426684e68SGreg Roach            'show_spouse'         => $show_spouse,
13526684e68SGreg Roach            'title'               => $this->chartTitle($individual),
13626684e68SGreg Roach        ]);
13726684e68SGreg Roach    }
13826684e68SGreg Roach
13926684e68SGreg Roach    /**
14026684e68SGreg Roach     * Generate the initial generations of the chart
14126684e68SGreg Roach     *
142e5a6b4d4SGreg Roach     * @param Individual $individual
143e5a6b4d4SGreg Roach     * @param int        $generations
144e5a6b4d4SGreg Roach     * @param bool       $show_spouse
14526684e68SGreg Roach     *
1466ccdf4f0SGreg Roach     * @return ResponseInterface
14726684e68SGreg Roach     */
1486ccdf4f0SGreg Roach    protected function chart(Individual $individual, int $generations, bool $show_spouse): ResponseInterface
14926684e68SGreg Roach    {
150cb0eb4a9SGreg Roach        $this->layout = 'layouts/ajax';
15126684e68SGreg Roach
152cb0eb4a9SGreg Roach        return $this->viewResponse('modules/hourglass-chart/chart', [
153cb0eb4a9SGreg Roach            'generations' => $generations,
154cb0eb4a9SGreg Roach            'individual'  => $individual,
155cb0eb4a9SGreg Roach            'show_spouse' => $show_spouse,
156cb0eb4a9SGreg Roach        ]);
157cb0eb4a9SGreg Roach    }
15826684e68SGreg Roach
159cb0eb4a9SGreg Roach    /**
160cb0eb4a9SGreg Roach     * Generate an extension to the chart
161cb0eb4a9SGreg Roach     *
162cb0eb4a9SGreg Roach     * @param ServerRequestInterface $request
163cb0eb4a9SGreg Roach     *
164cb0eb4a9SGreg Roach     * @return ResponseInterface
165cb0eb4a9SGreg Roach     */
166cb0eb4a9SGreg Roach    public function getAncestorsAction(ServerRequestInterface $request): ResponseInterface
167cb0eb4a9SGreg Roach    {
168cb0eb4a9SGreg Roach        $tree = app(Tree::class);
169cb0eb4a9SGreg Roach        $xref = $request->getQueryParams()['xref'] ?? '';
170cb0eb4a9SGreg Roach
171cb0eb4a9SGreg Roach        $family = Family::getInstance($xref, $tree);
172cb0eb4a9SGreg Roach        Auth::checkFamilyAccess($family);
173cb0eb4a9SGreg Roach
174cb0eb4a9SGreg Roach        return response(view('modules/hourglass-chart/parents', [
175cb0eb4a9SGreg Roach            'family'      => $family,
176cb0eb4a9SGreg Roach            'generations' => 1,
17726684e68SGreg Roach        ]));
17826684e68SGreg Roach    }
17926684e68SGreg Roach
18026684e68SGreg Roach    /**
181cb0eb4a9SGreg Roach     * Generate an extension to the chart
182cb0eb4a9SGreg Roach     *
1836ccdf4f0SGreg Roach     * @param ServerRequestInterface $request
18426684e68SGreg Roach     *
1856ccdf4f0SGreg Roach     * @return ResponseInterface
18626684e68SGreg Roach     */
187cb0eb4a9SGreg Roach    public function getDescendantsAction(ServerRequestInterface $request): ResponseInterface
18826684e68SGreg Roach    {
189cb0eb4a9SGreg Roach        $tree = app(Tree::class);
190cb0eb4a9SGreg Roach        $xref = $request->getQueryParams()['xref'] ?? '';
19126684e68SGreg Roach
192cb0eb4a9SGreg Roach        $show_spouse = (bool) ($request->getQueryParams()['show_spouse'] ?? false);
193cb0eb4a9SGreg Roach        $individual  = Individual::getInstance($xref, $tree);
194a21e5374SGreg Roach
19526684e68SGreg Roach        Auth::checkIndividualAccess($individual);
196a21e5374SGreg Roach
197a21e5374SGreg Roach        $children = $individual->spouseFamilies()->map(static function (Family $family): Collection {
198a21e5374SGreg Roach            return $family->children();
199a21e5374SGreg Roach        })->flatten();
20026684e68SGreg Roach
201cb0eb4a9SGreg Roach        return response(view('modules/hourglass-chart/children', [
202cb0eb4a9SGreg Roach            'children'    => $children,
203cb0eb4a9SGreg Roach            'generations' => 1,
204cb0eb4a9SGreg Roach            'show_spouse' => $show_spouse,
205cb0eb4a9SGreg Roach        ]));
206e6562982SGreg Roach    }
207168ff6f3Sric2016}
208