xref: /webtrees/app/Module/RelationshipsChartModule.php (revision cfe766af61e4d860f17afd91dc1b2e538caffa79)
1<?php
2/**
3 * webtrees: online genealogy
4 * Copyright (C) 2018 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 */
16namespace Fisharebest\Webtrees\Module;
17
18use Fisharebest\Webtrees\Auth;
19use Fisharebest\Webtrees\FlashMessages;
20use Fisharebest\Webtrees\I18N;
21use Fisharebest\Webtrees\Individual;
22use Fisharebest\Webtrees\Menu;
23use Fisharebest\Webtrees\Tree;
24use Symfony\Component\HttpFoundation\RedirectResponse;
25use Symfony\Component\HttpFoundation\Request;
26use Symfony\Component\HttpFoundation\Response;
27
28/**
29 * Class RelationshipsChartModule
30 */
31class RelationshipsChartModule extends AbstractModule implements ModuleConfigInterface, ModuleChartInterface
32{
33    /** It would be more correct to use PHP_INT_MAX, but this isn't friendly in URLs */
34    const UNLIMITED_RECURSION = '99';
35
36    /** By default new trees allow unlimited recursion */
37    const DEFAULT_RECURSION = self::UNLIMITED_RECURSION;
38
39    /** By default new trees search for all relationships (not via ancestors) */
40    const DEFAULT_ANCESTORS = '0';
41
42    /**
43     * How should this module be labelled on tabs, menus, etc.?
44     *
45     * @return string
46     */
47    public function getTitle(): string
48    {
49        /* I18N: Name of a module/chart */
50        return I18N::translate('Relationships');
51    }
52
53    /**
54     * A sentence describing what this module does.
55     *
56     * @return string
57     */
58    public function getDescription(): string
59    {
60        /* I18N: Description of the “RelationshipsChart” module */
61        return I18N::translate('A chart displaying relationships between two individuals.');
62    }
63
64    /**
65     * What is the default access level for this module?
66     *
67     * Some modules are aimed at admins or managers, and are not generally shown to users.
68     *
69     * @return int
70     */
71    public function defaultAccessLevel(): int
72    {
73        return Auth::PRIV_PRIVATE;
74    }
75
76    /**
77     * Return a menu item for this chart.
78     *
79     * @param Individual $individual
80     *
81     * @return Menu|null
82     */
83    public function getChartMenu(Individual $individual)
84    {
85        $tree     = $individual->getTree();
86        $gedcomid = $tree->getUserPreference(Auth::user(), 'gedcomid');
87
88        if ($gedcomid !== '') {
89            return new Menu(
90                I18N::translate('Relationship to me'),
91                route('relationships', [
92                    'xref1' => $gedcomid,
93                    'xref2' => $individual->getXref(),
94                    'ged'   => $individual->getTree()->getName(),
95                ]),
96                'menu-chart-relationship',
97                ['rel' => 'nofollow']
98            );
99        } else {
100            return new Menu(
101                I18N::translate('Relationships'),
102                route('relationships', [
103                    'xref1' => $individual->getXref(),
104                    'ged'   => $individual->getTree()->getName(),
105                ]),
106                'menu-chart-relationship',
107                ['rel' => 'nofollow']
108            );
109        }
110    }
111
112    /**
113     * Return a menu item for this chart - for use in individual boxes.
114     *
115     * @param Individual $individual
116     *
117     * @return Menu|null
118     */
119    public function getBoxChartMenu(Individual $individual)
120    {
121        return $this->getChartMenu($individual);
122    }
123
124
125    /**
126     * The URL to a page where the user can modify the configuration of this module.
127     *
128     * @return string
129     */
130    public function getConfigLink(): string
131    {
132        return route('module', [
133            'module' => $this->getName(),
134            'action' => 'Admin',
135        ]);
136    }
137
138    /**
139     * @param Request $request
140     *
141     * @return Response
142     */
143    public function getAdminAction(Request $request): 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            $tree->setPreference('RELATIONSHIP_RECURSION', $request->get('relationship-recursion-' . $tree->getTreeId()));
166            $tree->setPreference('RELATIONSHIP_ANCESTORS', $request->get('relationship-ancestors-' . $tree->getTreeId()));
167        }
168
169        FlashMessages::addMessage(I18N::translate('The preferences for the module “%s” have been updated.', $this->getTitle()), 'success');
170
171        return new RedirectResponse($this->getConfigLink());
172    }
173
174    /**
175     * Possible options for the ancestors option
176     */
177    private function ancestorsOptions()
178    {
179        return [
180            0 => I18N::translate('Find any relationship'),
181            1 => I18N::translate('Find relationships via ancestors'),
182        ];
183    }
184
185    /**
186     * Possible options for the recursion option
187     */
188    private function recursionOptions()
189    {
190        return [
191            0                         => I18N::translate('none'),
192            1                         => I18N::number(1),
193            2                         => I18N::number(2),
194            3                         => I18N::number(3),
195            self::UNLIMITED_RECURSION => I18N::translate('unlimited'),
196        ];
197    }
198}
199