xref: /webtrees/app/Module/CompactTreeChartModule.php (revision 81b514b4672980e5db010e9d89b55eaf131e798f)
1<?php
2
3/**
4 * webtrees: online genealogy
5 * Copyright (C) 2023 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 <https://www.gnu.org/licenses/>.
16 */
17
18declare(strict_types=1);
19
20namespace Fisharebest\Webtrees\Module;
21
22use Fig\Http\Message\RequestMethodInterface;
23use Fisharebest\Webtrees\Auth;
24use Fisharebest\Webtrees\I18N;
25use Fisharebest\Webtrees\Individual;
26use Fisharebest\Webtrees\Menu;
27use Fisharebest\Webtrees\Registry;
28use Fisharebest\Webtrees\Services\ChartService;
29use Fisharebest\Webtrees\Validator;
30use Psr\Http\Message\ResponseInterface;
31use Psr\Http\Message\ServerRequestInterface;
32use Psr\Http\Server\RequestHandlerInterface;
33
34use function route;
35
36/**
37 * Class CompactTreeChartModule
38 */
39class CompactTreeChartModule extends AbstractModule implements ModuleChartInterface, RequestHandlerInterface
40{
41    use ModuleChartTrait;
42
43    protected const ROUTE_URL = '/tree/{tree}/compact/{xref}';
44
45    private ChartService $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     * @return void
61     */
62    public function boot(): void
63    {
64        Registry::routeFactory()->routeMap()
65            ->get(static::class, static::ROUTE_URL, $this)
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 array<bool|int|string|array<string>|null> $parameters
131     *
132     * @return string
133     */
134    public function chartUrl(Individual $individual, array $parameters = []): string
135    {
136        return route(static::class, [
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 = Validator::attributes($request)->tree();
150        $user = Validator::attributes($request)->user();
151        $xref = Validator::attributes($request)->isXref()->string('xref');
152        $ajax = Validator::queryParams($request)->boolean('ajax', false);
153
154        // Convert POST requests into GET requests for pretty URLs.
155        if ($request->getMethod() === RequestMethodInterface::METHOD_POST) {
156            return redirect(route(static::class, [
157                'tree' => $tree->name(),
158                'xref' => Validator::parsedBody($request)->string('xref', ''),
159            ]));
160        }
161
162        Auth::checkComponentAccess($this, ModuleChartInterface::class, $tree, $user);
163
164        $individual = Registry::individualFactory()->make($xref, $tree);
165        $individual = Auth::checkIndividualAccess($individual, false, true);
166
167        if ($ajax) {
168            $this->layout = 'layouts/ajax';
169
170            return $this->viewResponse('modules/compact-chart/chart', [
171                'ancestors' => $this->chart_service->sosaStradonitzAncestors($individual, 5),
172                'module'    => $this,
173            ]);
174        }
175
176        $ajax_url = $this->chartUrl($individual, [
177            'ajax' => true,
178        ]);
179
180        return $this->viewResponse('modules/compact-chart/page', [
181            'ajax_url'   => $ajax_url,
182            'individual' => $individual,
183            'module'     => $this->name(),
184            'title'      => $this->chartTitle($individual),
185            'tree'       => $tree,
186        ]);
187    }
188}
189