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 } 100 101 return new Menu( 102 I18N::translate('Relationships'), 103 route('relationships', [ 104 'xref1' => $individual->getXref(), 105 'ged' => $individual->getTree()->getName(), 106 ]), 107 'menu-chart-relationship', 108 ['rel' => 'nofollow'] 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 * @return string[] 178 */ 179 private function ancestorsOptions(): array 180 { 181 return [ 182 0 => I18N::translate('Find any relationship'), 183 1 => I18N::translate('Find relationships via ancestors'), 184 ]; 185 } 186 187 /** 188 * Possible options for the recursion option 189 * 190 * @return string[] 191 */ 192 private function recursionOptions(): array 193 { 194 return [ 195 0 => I18N::translate('none'), 196 1 => I18N::number(1), 197 2 => I18N::number(2), 198 3 => I18N::number(3), 199 self::UNLIMITED_RECURSION => I18N::translate('unlimited'), 200 ]; 201 } 202} 203