xref: /webtrees/app/Module/RelationshipsChartModule.php (revision e9e853987811e8bd423dccf26f6ef57571f393eb)
1<?php
2/**
3 * webtrees: online genealogy
4 * Copyright (C) 2019 webtrees development team
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16declare(strict_types=1);
17
18namespace Fisharebest\Webtrees\Module;
19
20use Fisharebest\Webtrees\Auth;
21use Fisharebest\Webtrees\FlashMessages;
22use Fisharebest\Webtrees\I18N;
23use Fisharebest\Webtrees\Individual;
24use Fisharebest\Webtrees\Menu;
25use Fisharebest\Webtrees\Tree;
26use Symfony\Component\HttpFoundation\RedirectResponse;
27use Symfony\Component\HttpFoundation\Request;
28use Symfony\Component\HttpFoundation\Response;
29
30/**
31 * Class RelationshipsChartModule
32 */
33class RelationshipsChartModule extends AbstractModule implements ModuleConfigInterface, ModuleChartInterface
34{
35    /** It would be more correct to use PHP_INT_MAX, but this isn't friendly in URLs */
36    public const UNLIMITED_RECURSION = 99;
37
38    /** By default new trees allow unlimited recursion */
39    public const DEFAULT_RECURSION = '99';
40
41    /** By default new trees search for all relationships (not via ancestors) */
42    public const DEFAULT_ANCESTORS = '0';
43
44    /**
45     * How should this module be labelled on tabs, menus, etc.?
46     *
47     * @return string
48     */
49    public function getTitle(): string
50    {
51        /* I18N: Name of a module/chart */
52        return I18N::translate('Relationships');
53    }
54
55    /**
56     * A sentence describing what this module does.
57     *
58     * @return string
59     */
60    public function getDescription(): string
61    {
62        /* I18N: Description of the “RelationshipsChart” module */
63        return I18N::translate('A chart displaying relationships between two individuals.');
64    }
65
66    /**
67     * What is the default access level for this module?
68     *
69     * Some modules are aimed at admins or managers, and are not generally shown to users.
70     *
71     * @return int
72     */
73    public function defaultAccessLevel(): int
74    {
75        return Auth::PRIV_PRIVATE;
76    }
77
78    /**
79     * Return a menu item for this chart.
80     *
81     * @param Individual $individual
82     *
83     * @return Menu|null
84     */
85    public function getChartMenu(Individual $individual)
86    {
87        $tree     = $individual->tree();
88        $gedcomid = $tree->getUserPreference(Auth::user(), 'gedcomid');
89
90        if ($gedcomid !== '') {
91            return new Menu(
92                I18N::translate('Relationship to me'),
93                route('relationships', [
94                    'xref1' => $gedcomid,
95                    'xref2' => $individual->xref(),
96                    'ged'   => $individual->tree()->name(),
97                ]),
98                'menu-chart-relationship',
99                ['rel' => 'nofollow']
100            );
101        }
102
103        return new Menu(
104            I18N::translate('Relationships'),
105            route('relationships', [
106                'xref1' => $individual->xref(),
107                'ged'   => $individual->tree()->name(),
108            ]),
109            'menu-chart-relationship',
110            ['rel' => 'nofollow']
111        );
112    }
113
114    /**
115     * Return a menu item for this chart - for use in individual boxes.
116     *
117     * @param Individual $individual
118     *
119     * @return Menu|null
120     */
121    public function getBoxChartMenu(Individual $individual)
122    {
123        return $this->getChartMenu($individual);
124    }
125
126
127    /**
128     * The URL to a page where the user can modify the configuration of this module.
129     *
130     * @return string
131     */
132    public function getConfigLink(): string
133    {
134        return route('module', [
135            'module' => $this->getName(),
136            'action' => 'Admin',
137        ]);
138    }
139
140    /**
141     * @return Response
142     */
143    public function getAdminAction(): Response
144    {
145        $this->layout = 'layouts/administration';
146
147        return $this->viewResponse('modules/relationships_chart/config', [
148            'all_trees'         => Tree::getAll(),
149            'ancestors_options' => $this->ancestorsOptions(),
150            'default_ancestors' => self::DEFAULT_ANCESTORS,
151            'default_recursion' => self::DEFAULT_RECURSION,
152            'recursion_options' => $this->recursionOptions(),
153            'title'             => I18N::translate('Chart preferences') . ' — ' . $this->getTitle(),
154        ]);
155    }
156
157    /**
158     * @param Request $request
159     *
160     * @return RedirectResponse
161     */
162    public function postAdminAction(Request $request): RedirectResponse
163    {
164        foreach (Tree::getAll() as $tree) {
165            $recursion = $request->get('relationship-recursion-' . $tree->id(), '');
166            $ancestors = $request->get('relationship-ancestors-' . $tree->id(), '');
167
168            $tree->setPreference('RELATIONSHIP_RECURSION', $recursion);
169            $tree->setPreference('RELATIONSHIP_ANCESTORS', $ancestors);
170        }
171
172        FlashMessages::addMessage(I18N::translate('The preferences for the module “%s” have been updated.', $this->getTitle()), 'success');
173
174        return new RedirectResponse($this->getConfigLink());
175    }
176
177    /**
178     * Possible options for the ancestors option
179     *
180     * @return string[]
181     */
182    private function ancestorsOptions(): array
183    {
184        return [
185            0 => I18N::translate('Find any relationship'),
186            1 => I18N::translate('Find relationships via ancestors'),
187        ];
188    }
189
190    /**
191     * Possible options for the recursion option
192     *
193     * @return string[]
194     */
195    private function recursionOptions(): array
196    {
197        return [
198            0                         => I18N::translate('none'),
199            1                         => I18N::number(1),
200            2                         => I18N::number(2),
201            3                         => I18N::number(3),
202            self::UNLIMITED_RECURSION => I18N::translate('unlimited'),
203        ];
204    }
205}
206