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