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 */ 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 const UNLIMITED_RECURSION = 99; 37 38 /** By default new trees allow unlimited recursion */ 39 const DEFAULT_RECURSION = '99'; 40 41 /** By default new trees search for all relationships (not via ancestors) */ 42 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->getTree(); 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->getXref(), 96 'ged' => $individual->getTree()->getName(), 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->getXref(), 107 'ged' => $individual->getTree()->getName(), 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 * @param Request $request 142 * 143 * @return Response 144 */ 145 public function getAdminAction(Request $request): Response 146 { 147 $this->layout = 'layouts/administration'; 148 149 return $this->viewResponse('modules/relationships_chart/config', [ 150 'all_trees' => Tree::getAll(), 151 'ancestors_options' => $this->ancestorsOptions(), 152 'default_ancestors' => self::DEFAULT_ANCESTORS, 153 'default_recursion' => self::DEFAULT_RECURSION, 154 'recursion_options' => $this->recursionOptions(), 155 'title' => I18N::translate('Chart preferences') . ' — ' . $this->getTitle(), 156 ]); 157 } 158 159 /** 160 * @param Request $request 161 * 162 * @return RedirectResponse 163 */ 164 public function postAdminAction(Request $request): RedirectResponse 165 { 166 foreach (Tree::getAll() as $tree) { 167 $recursion = $request->get('relationship-recursion-' . $tree->getTreeId(), ''); 168 $ancestors = $request->get('relationship-ancestors-' . $tree->getTreeId(), ''); 169 170 $tree->setPreference('RELATIONSHIP_RECURSION', $recursion); 171 $tree->setPreference('RELATIONSHIP_ANCESTORS', $ancestors); 172 } 173 174 FlashMessages::addMessage(I18N::translate('The preferences for the module “%s” have been updated.', $this->getTitle()), 'success'); 175 176 return new RedirectResponse($this->getConfigLink()); 177 } 178 179 /** 180 * Possible options for the ancestors option 181 * 182 * @return string[] 183 */ 184 private function ancestorsOptions(): array 185 { 186 return [ 187 0 => I18N::translate('Find any relationship'), 188 1 => I18N::translate('Find relationships via ancestors'), 189 ]; 190 } 191 192 /** 193 * Possible options for the recursion option 194 * 195 * @return string[] 196 */ 197 private function recursionOptions(): array 198 { 199 return [ 200 0 => I18N::translate('none'), 201 1 => I18N::number(1), 202 2 => I18N::number(2), 203 3 => I18N::number(3), 204 self::UNLIMITED_RECURSION => I18N::translate('unlimited'), 205 ]; 206 } 207} 208