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