xref: /webtrees/app/Module/CompactTreeChartModule.php (revision 1e65345293efca3993945bfd7b2e1fdb9103d8bc)
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 */
17
18declare(strict_types=1);
19
20namespace Fisharebest\Webtrees\Module;
21
22use Aura\Router\RouterContainer;
23use Fig\Http\Message\RequestMethodInterface;
24use Fisharebest\Webtrees\Auth;
25use Fisharebest\Webtrees\I18N;
26use Fisharebest\Webtrees\Individual;
27use Fisharebest\Webtrees\Menu;
28use Fisharebest\Webtrees\Services\ChartService;
29use Psr\Http\Message\ResponseInterface;
30use Psr\Http\Message\ServerRequestInterface;
31use Psr\Http\Server\RequestHandlerInterface;
32
33use function route;
34
35/**
36 * Class CompactTreeChartModule
37 */
38class CompactTreeChartModule extends AbstractModule implements ModuleChartInterface, RequestHandlerInterface
39{
40    use ModuleChartTrait;
41
42    private const ROUTE_NAME = 'compact-chart';
43    private const ROUTE_URL  = '/tree/{tree}/compact/{xref}';
44
45    /** @var ChartService */
46    private $chart_service;
47
48    /**
49     * CompactTreeChartModule constructor.
50     *
51     * @param ChartService $chart_service
52     */
53    public function __construct(ChartService $chart_service)
54    {
55        $this->chart_service = $chart_service;
56    }
57
58    /**
59     * Initialization.
60     *
61     * @param RouterContainer $router_container
62     */
63    public function boot(RouterContainer $router_container): void
64    {
65        $router_container->getMap()
66            ->get(self::ROUTE_NAME, self::ROUTE_URL, self::class)
67            ->allows(RequestMethodInterface::METHOD_POST);
68    }
69
70    /**
71     * How should this module be identified in the control panel, etc.?
72     *
73     * @return string
74     */
75    public function title(): string
76    {
77        /* I18N: Name of a module/chart */
78        return I18N::translate('Compact tree');
79    }
80
81    /**
82     * A sentence describing what this module does.
83     *
84     * @return string
85     */
86    public function description(): string
87    {
88        /* I18N: Description of the “CompactTreeChart” module */
89        return I18N::translate('A chart of an individual’s ancestors, as a compact tree.');
90    }
91
92    /**
93     * CSS class for the URL.
94     *
95     * @return string
96     */
97    public function chartMenuClass(): string
98    {
99        return 'menu-chart-compact';
100    }
101
102    /**
103     * Return a menu item for this chart - for use in individual boxes.
104     *
105     * @param Individual $individual
106     *
107     * @return Menu|null
108     */
109    public function chartBoxMenu(Individual $individual): ?Menu
110    {
111        return $this->chartMenu($individual);
112    }
113
114    /**
115     * The title for a specific instance of this chart.
116     *
117     * @param Individual $individual
118     *
119     * @return string
120     */
121    public function chartTitle(Individual $individual): string
122    {
123        /* I18N: %s is an individual’s name */
124        return I18N::translate('Compact tree of %s', $individual->fullName());
125    }
126
127    /**
128     * The URL for a page showing chart options.
129     *
130     * @param Individual $individual
131     * @param mixed[]    $parameters
132     *
133     * @return string
134     */
135    public function chartUrl(Individual $individual, array $parameters = []): string
136    {
137        return route(self::ROUTE_NAME, [
138                'xref' => $individual->xref(),
139                'tree' => $individual->tree()->name(),
140            ] + $parameters);
141    }
142
143    /**
144     * @param ServerRequestInterface $request
145     *
146     * @return ResponseInterface
147     */
148    public function handle(ServerRequestInterface $request): ResponseInterface
149    {
150        $tree       = $request->getAttribute('tree');
151        $user       = $request->getAttribute('user');
152        $xref       = $request->getAttribute('xref');
153        $ajax       = $request->getQueryParams()['ajax'] ?? '';
154        $individual = Individual::getInstance($xref, $tree);
155
156        // Convert POST requests into GET requests for pretty URLs.
157        if ($request->getMethod() === RequestMethodInterface::METHOD_POST) {
158            return redirect(route(self::ROUTE_NAME, [
159                'tree' => $request->getAttribute('tree')->name(),
160                'xref' => $request->getParsedBody()['xref'],
161            ]));
162        }
163
164        Auth::checkIndividualAccess($individual);
165        Auth::checkComponentAccess($this, 'chart', $tree, $user);
166
167        if ($ajax === '1') {
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        ]);
186    }
187}
188