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