xref: /webtrees/app/Module/RelationshipsChartModule.php (revision 895230eed7521b5cd885b90d4f5310405ff0b69a)
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 ModuleInterface, ModuleChartInterface, ModuleConfigInterface
34{
35    use ModuleChartTrait;
36    use ModuleConfigTrait;
37
38    /** It would be more correct to use PHP_INT_MAX, but this isn't friendly in URLs */
39    public const UNLIMITED_RECURSION = 99;
40
41    /** By default new trees allow unlimited recursion */
42    public const DEFAULT_RECURSION = '99';
43
44    /** By default new trees search for all relationships (not via ancestors) */
45    public const DEFAULT_ANCESTORS = '0';
46
47    /**
48     * How should this module be labelled on tabs, menus, etc.?
49     *
50     * @return string
51     */
52    public function title(): string
53    {
54        /* I18N: Name of a module/chart */
55        return I18N::translate('Relationships');
56    }
57
58    /**
59     * A sentence describing what this module does.
60     *
61     * @return string
62     */
63    public function description(): string
64    {
65        /* I18N: Description of the “RelationshipsChart” module */
66        return I18N::translate('A chart displaying relationships between two individuals.');
67    }
68
69    /**
70     * Return a menu item for this chart.
71     *
72     * @param Individual $individual
73     *
74     * @return Menu|null
75     */
76    public function getChartMenu(Individual $individual): ?Menu
77    {
78        $tree     = $individual->tree();
79        $gedcomid = $tree->getUserPreference(Auth::user(), 'gedcomid');
80
81        if ($gedcomid !== '') {
82            return new Menu(
83                I18N::translate('Relationship to me'),
84                route('relationships', [
85                    'xref1' => $gedcomid,
86                    'xref2' => $individual->xref(),
87                    'ged'   => $individual->tree()->name(),
88                ]),
89                'menu-chart-relationship',
90                ['rel' => 'nofollow']
91            );
92        }
93
94        return new Menu(
95            I18N::translate('Relationships'),
96            route('relationships', [
97                'xref1' => $individual->xref(),
98                'ged'   => $individual->tree()->name(),
99            ]),
100            'menu-chart-relationship',
101            ['rel' => 'nofollow']
102        );
103    }
104
105    /**
106     * Return a menu item for this chart - for use in individual boxes.
107     *
108     * @param Individual $individual
109     *
110     * @return Menu|null
111     */
112    public function getBoxChartMenu(Individual $individual): ?Menu
113    {
114        return $this->getChartMenu($individual);
115    }
116
117    /**
118     * @return Response
119     */
120    public function getAdminAction(): Response
121    {
122        $this->layout = 'layouts/administration';
123
124        return $this->viewResponse('modules/relationships_chart/config', [
125            'all_trees'         => Tree::getAll(),
126            'ancestors_options' => $this->ancestorsOptions(),
127            'default_ancestors' => self::DEFAULT_ANCESTORS,
128            'default_recursion' => self::DEFAULT_RECURSION,
129            'recursion_options' => $this->recursionOptions(),
130            'title'             => I18N::translate('Chart preferences') . ' — ' . $this->title(),
131        ]);
132    }
133
134    /**
135     * @param Request $request
136     *
137     * @return RedirectResponse
138     */
139    public function postAdminAction(Request $request): RedirectResponse
140    {
141        foreach (Tree::getAll() as $tree) {
142            $recursion = $request->get('relationship-recursion-' . $tree->id(), '');
143            $ancestors = $request->get('relationship-ancestors-' . $tree->id(), '');
144
145            $tree->setPreference('RELATIONSHIP_RECURSION', $recursion);
146            $tree->setPreference('RELATIONSHIP_ANCESTORS', $ancestors);
147        }
148
149        FlashMessages::addMessage(I18N::translate('The preferences for the module “%s” have been updated.', $this->title()), 'success');
150
151        return new RedirectResponse($this->getConfigLink());
152    }
153
154    /**
155     * Possible options for the ancestors option
156     *
157     * @return string[]
158     */
159    private function ancestorsOptions(): array
160    {
161        return [
162            0 => I18N::translate('Find any relationship'),
163            1 => I18N::translate('Find relationships via ancestors'),
164        ];
165    }
166
167    /**
168     * Possible options for the recursion option
169     *
170     * @return string[]
171     */
172    private function recursionOptions(): array
173    {
174        return [
175            0                         => I18N::translate('none'),
176            1                         => I18N::number(1),
177            2                         => I18N::number(2),
178            3                         => I18N::number(3),
179            self::UNLIMITED_RECURSION => I18N::translate('unlimited'),
180        ];
181    }
182}
183