xref: /webtrees/app/Module/CompactTreeChartModule.php (revision 71378461661e7642e52abe7d41c9cfffb3e5369b)
1<?php
2
3/**
4 * webtrees: online genealogy
5 * Copyright (C) 2019 webtrees development team
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17declare(strict_types=1);
18
19namespace Fisharebest\Webtrees\Module;
20
21use Aura\Router\RouterContainer;
22use Fig\Http\Message\RequestMethodInterface;
23use Fisharebest\Webtrees\Auth;
24use Fisharebest\Webtrees\I18N;
25use Fisharebest\Webtrees\Individual;
26use Fisharebest\Webtrees\Menu;
27use Fisharebest\Webtrees\Services\ChartService;
28use Psr\Http\Message\ResponseInterface;
29use Psr\Http\Message\ServerRequestInterface;
30use Psr\Http\Server\RequestHandlerInterface;
31
32use function route;
33
34/**
35 * Class CompactTreeChartModule
36 */
37class CompactTreeChartModule extends AbstractModule implements ModuleChartInterface, RequestHandlerInterface
38{
39    use ModuleChartTrait;
40
41    private const ROUTE_NAME = 'compact-chart';
42    private const ROUTE_URL  = '/tree/{tree}/compact/{xref}';
43
44    /** @var ChartService */
45    private $chart_service;
46
47    /**
48     * CompactTreeChartModule constructor.
49     *
50     * @param ChartService $chart_service
51     */
52    public function __construct(ChartService $chart_service)
53    {
54        $this->chart_service = $chart_service;
55    }
56
57    /**
58     * Initialization.
59     *
60     * @param RouterContainer $router_container
61     */
62    public function boot(RouterContainer $router_container)
63    {
64        $router_container->getMap()
65            ->get(self::ROUTE_NAME, self::ROUTE_URL, self::class)
66            ->allows(RequestMethodInterface::METHOD_POST);
67    }
68
69    /**
70     * How should this module be identified in the control panel, etc.?
71     *
72     * @return string
73     */
74    public function title(): string
75    {
76        /* I18N: Name of a module/chart */
77        return I18N::translate('Compact tree');
78    }
79
80    /**
81     * A sentence describing what this module does.
82     *
83     * @return string
84     */
85    public function description(): string
86    {
87        /* I18N: Description of the “CompactTreeChart” module */
88        return I18N::translate('A chart of an individual’s ancestors, as a compact tree.');
89    }
90
91    /**
92     * CSS class for the URL.
93     *
94     * @return string
95     */
96    public function chartMenuClass(): string
97    {
98        return 'menu-chart-compact';
99    }
100
101    /**
102     * Return a menu item for this chart - for use in individual boxes.
103     *
104     * @param Individual $individual
105     *
106     * @return Menu|null
107     */
108    public function chartBoxMenu(Individual $individual): ?Menu
109    {
110        return $this->chartMenu($individual);
111    }
112
113    /**
114     * The title for a specific instance of this chart.
115     *
116     * @param Individual $individual
117     *
118     * @return string
119     */
120    public function chartTitle(Individual $individual): string
121    {
122        /* I18N: %s is an individual’s name */
123        return I18N::translate('Compact tree of %s', $individual->fullName());
124    }
125
126    /**
127     * The URL for a page showing chart options.
128     *
129     * @param Individual $individual
130     * @param string[]   $parameters
131     *
132     * @return string
133     */
134    public function chartUrl(Individual $individual, array $parameters = []): string
135    {
136        return route(self::ROUTE_NAME, [
137                'xref' => $individual->xref(),
138                'tree' => $individual->tree()->name(),
139            ] + $parameters);
140    }
141
142    /**
143     * @param ServerRequestInterface $request
144     *
145     * @return ResponseInterface
146     */
147    public function handle(ServerRequestInterface $request): ResponseInterface
148    {
149        $tree       = $request->getAttribute('tree');
150        $user       = $request->getAttribute('user');
151        $xref       = $request->getAttribute('xref');
152        $ajax       = $request->getQueryParams()['ajax'] ?? '';
153        $individual = Individual::getInstance($xref, $tree);
154
155        // Convert POST requests into GET requests for pretty URLs.
156        if ($request->getMethod() === RequestMethodInterface::METHOD_POST) {
157            return redirect(route(self::ROUTE_NAME, [
158                'tree' => $request->getAttribute('tree')->name(),
159                'xref' => $request->getParsedBody()['xref'],
160            ]));
161        }
162
163        Auth::checkIndividualAccess($individual);
164        Auth::checkComponentAccess($this, 'chart', $tree, $user);
165
166        if ($ajax === '1') {
167            $this->layout = 'layouts/ajax';
168
169            return $this->viewResponse('modules/compact-chart/chart', [
170                'ancestors' => $this->chart_service->sosaStradonitzAncestors($individual, 5),
171                'module'    => $this,
172            ]);
173        }
174
175        $ajax_url = $this->chartUrl($individual, [
176            'ajax' => true,
177        ]);
178
179        return $this->viewResponse('modules/compact-chart/page', [
180            'ajax_url'   => $ajax_url,
181            'individual' => $individual,
182            'module'     => $this->name(),
183            'title'      => $this->chartTitle($individual),
184        ]);
185    }
186}
187