1168ff6f3Sric2016<?php 2168ff6f3Sric2016/** 3168ff6f3Sric2016 * webtrees: online genealogy 4*1062a142SGreg Roach * Copyright (C) 2018 webtrees development team 5168ff6f3Sric2016 * This program is free software: you can redistribute it and/or modify 6168ff6f3Sric2016 * it under the terms of the GNU General Public License as published by 7168ff6f3Sric2016 * the Free Software Foundation, either version 3 of the License, or 8168ff6f3Sric2016 * (at your option) any later version. 9168ff6f3Sric2016 * This program is distributed in the hope that it will be useful, 10168ff6f3Sric2016 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11168ff6f3Sric2016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12168ff6f3Sric2016 * GNU General Public License for more details. 13168ff6f3Sric2016 * You should have received a copy of the GNU General Public License 14168ff6f3Sric2016 * along with this program. If not, see <http://www.gnu.org/licenses/>. 15168ff6f3Sric2016 */ 16168ff6f3Sric2016namespace Fisharebest\Webtrees\Module; 17168ff6f3Sric2016 18168ff6f3Sric2016use Fisharebest\Webtrees\Auth; 1915d603e7SGreg Roachuse Fisharebest\Webtrees\Bootstrap4; 2045ac604bSGreg Roachuse Fisharebest\Webtrees\Controller\PageController; 2145ac604bSGreg Roachuse Fisharebest\Webtrees\Filter; 2245ac604bSGreg Roachuse Fisharebest\Webtrees\FlashMessages; 23b1b85189SGreg Roachuse Fisharebest\Webtrees\Html; 24168ff6f3Sric2016use Fisharebest\Webtrees\I18N; 25168ff6f3Sric2016use Fisharebest\Webtrees\Individual; 261e3273c9SGreg Roachuse Fisharebest\Webtrees\Menu; 2745ac604bSGreg Roachuse Fisharebest\Webtrees\Tree; 28168ff6f3Sric2016 29168ff6f3Sric2016/** 30168ff6f3Sric2016 * Class RelationshipsChartModule 31168ff6f3Sric2016 */ 3245ac604bSGreg Roachclass RelationshipsChartModule extends AbstractModule implements ModuleConfigInterface, ModuleChartInterface { 331e3273c9SGreg Roach /** It would be more correct to use PHP_INT_MAX, but this isn't friendly in URLs */ 341e3273c9SGreg Roach const UNLIMITED_RECURSION = 99; 351e3273c9SGreg Roach 361e3273c9SGreg Roach /** By default new trees allow unlimited recursion */ 371e3273c9SGreg Roach const DEFAULT_RECURSION = self::UNLIMITED_RECURSION; 3845ac604bSGreg Roach 39e0bd7dc9SGreg Roach /** By default new trees search for all relationships (not via ancestors) */ 40e0bd7dc9SGreg Roach const DEFAULT_ANCESTORS = 0; 41e0bd7dc9SGreg Roach 42168ff6f3Sric2016 /** 43168ff6f3Sric2016 * How should this module be labelled on tabs, menus, etc.? 44168ff6f3Sric2016 * 45168ff6f3Sric2016 * @return string 46168ff6f3Sric2016 */ 47168ff6f3Sric2016 public function getTitle() { 48168ff6f3Sric2016 return /* I18N: Name of a module/chart */ I18N::translate('Relationships'); 49168ff6f3Sric2016 } 50168ff6f3Sric2016 51168ff6f3Sric2016 /** 52168ff6f3Sric2016 * A sentence describing what this module does. 53168ff6f3Sric2016 * 54168ff6f3Sric2016 * @return string 55168ff6f3Sric2016 */ 56168ff6f3Sric2016 public function getDescription() { 57168ff6f3Sric2016 return /* I18N: Description of the “RelationshipsChart” module */ I18N::translate('A chart displaying relationships between two individuals.'); 58168ff6f3Sric2016 } 59168ff6f3Sric2016 60168ff6f3Sric2016 /** 61168ff6f3Sric2016 * What is the default access level for this module? 62168ff6f3Sric2016 * 63168ff6f3Sric2016 * Some modules are aimed at admins or managers, and are not generally shown to users. 64168ff6f3Sric2016 * 65168ff6f3Sric2016 * @return int 66168ff6f3Sric2016 */ 67168ff6f3Sric2016 public function defaultAccessLevel() { 68168ff6f3Sric2016 return Auth::PRIV_PRIVATE; 69168ff6f3Sric2016 } 70168ff6f3Sric2016 71168ff6f3Sric2016 /** 72168ff6f3Sric2016 * Return a menu item for this chart. 73168ff6f3Sric2016 * 748e69695bSGreg Roach * @param Individual $individual 758e69695bSGreg Roach * 764eb71cfaSGreg Roach * @return Menu|null 77168ff6f3Sric2016 */ 78168ff6f3Sric2016 public function getChartMenu(Individual $individual) { 794eb71cfaSGreg Roach $tree = $individual->getTree(); 804eb71cfaSGreg Roach $gedcomid = $tree->getUserPreference(Auth::user(), 'gedcomid'); 81168ff6f3Sric2016 824eb71cfaSGreg Roach if ($gedcomid) { 83168ff6f3Sric2016 return new Menu( 84168ff6f3Sric2016 I18N::translate('Relationship to me'), 854eb71cfaSGreg Roach 'relationship.php?pid1=' . $gedcomid . '&pid2=' . $individual->getXref() . '&ged=' . $tree->getNameUrl(), 86168ff6f3Sric2016 'menu-chart-relationship', 8713abd6f3SGreg Roach ['rel' => 'nofollow'] 88168ff6f3Sric2016 ); 89168ff6f3Sric2016 } else { 90168ff6f3Sric2016 return new Menu( 91168ff6f3Sric2016 I18N::translate('Relationships'), 924eb71cfaSGreg Roach 'relationship.php?pid1=' . $individual->getXref() . '&ged=' . $tree->getNameUrl(), 93168ff6f3Sric2016 'menu-chart-relationship', 9413abd6f3SGreg Roach ['rel' => 'nofollow'] 95168ff6f3Sric2016 ); 96168ff6f3Sric2016 } 97168ff6f3Sric2016 } 98168ff6f3Sric2016 994eb71cfaSGreg Roach /** 1004eb71cfaSGreg Roach * Return a menu item for this chart - for use in individual boxes. 1014eb71cfaSGreg Roach * 1028e69695bSGreg Roach * @param Individual $individual 1038e69695bSGreg Roach * 1044eb71cfaSGreg Roach * @return Menu|null 1054eb71cfaSGreg Roach */ 106168ff6f3Sric2016 public function getBoxChartMenu(Individual $individual) { 107168ff6f3Sric2016 return $this->getChartMenu($individual); 108168ff6f3Sric2016 } 10945ac604bSGreg Roach 11045ac604bSGreg Roach /** 11145ac604bSGreg Roach * This is a general purpose hook, allowing modules to respond to routes 11245ac604bSGreg Roach * of the form module.php?mod=FOO&mod_action=BAR 11345ac604bSGreg Roach * 11445ac604bSGreg Roach * @param string $mod_action 11545ac604bSGreg Roach */ 11645ac604bSGreg Roach public function modAction($mod_action) { 11745ac604bSGreg Roach switch ($mod_action) { 11845ac604bSGreg Roach case 'admin': 11945ac604bSGreg Roach if ($_SERVER['REQUEST_METHOD'] === 'POST') { 12045ac604bSGreg Roach $this->saveConfig(); 12145ac604bSGreg Roach } else { 12245ac604bSGreg Roach $this->editConfig(); 12345ac604bSGreg Roach } 12445ac604bSGreg Roach break; 12545ac604bSGreg Roach default: 12645ac604bSGreg Roach http_response_code(404); 12745ac604bSGreg Roach } 12845ac604bSGreg Roach } 12945ac604bSGreg Roach 13045ac604bSGreg Roach /** 131e0bd7dc9SGreg Roach * Possible options for the ancestors option 132e0bd7dc9SGreg Roach */ 133e0bd7dc9SGreg Roach private function ancestorsOptions() { 13413abd6f3SGreg Roach return [ 135e0bd7dc9SGreg Roach 0 => I18N::translate('Find any relationship'), 136e0bd7dc9SGreg Roach 1 => I18N::translate('Find relationships via ancestors'), 13713abd6f3SGreg Roach ]; 138e0bd7dc9SGreg Roach } 139e0bd7dc9SGreg Roach 140e0bd7dc9SGreg Roach /** 1411e3273c9SGreg Roach * Possible options for the recursion option 1421e3273c9SGreg Roach */ 1431e3273c9SGreg Roach private function recursionOptions() { 14413abd6f3SGreg Roach return [ 1451e3273c9SGreg Roach 0 => I18N::translate('none'), 1461e3273c9SGreg Roach 1 => I18N::number(1), 1471e3273c9SGreg Roach 2 => I18N::number(2), 1481e3273c9SGreg Roach 3 => I18N::number(3), 149e0bd7dc9SGreg Roach self::UNLIMITED_RECURSION => I18N::translate('unlimited'), 15013abd6f3SGreg Roach ]; 1511e3273c9SGreg Roach } 1521e3273c9SGreg Roach 1531e3273c9SGreg Roach /** 15445ac604bSGreg Roach * Display a form to edit configuration settings. 15545ac604bSGreg Roach */ 15645ac604bSGreg Roach private function editConfig() { 15745ac604bSGreg Roach $controller = new PageController; 15845ac604bSGreg Roach $controller 15945ac604bSGreg Roach ->restrictAccess(Auth::isAdmin()) 16045ac604bSGreg Roach ->setPageTitle(I18N::translate('Chart preferences') . ' — ' . $this->getTitle()) 16145ac604bSGreg Roach ->pageHeader(); 16245ac604bSGreg Roach 16315d603e7SGreg Roach echo Bootstrap4::breadcrumbs([ 1641f3fb95cSGreg Roach route('admin-control-panel') => I18N::translate('Control panel'), 1651f3fb95cSGreg Roach route('admin-modules') => I18N::translate('Module administration'), 16615d603e7SGreg Roach ], $controller->getPageTitle()); 16745ac604bSGreg Roach ?> 16815d603e7SGreg Roach 16915d603e7SGreg Roach <h1><?= $controller->getPageTitle() ?></h1> 17045ac604bSGreg Roach 171e0bd7dc9SGreg Roach <p> 17215d603e7SGreg Roach <?= I18N::translate('Searching for all possible relationships can take a lot of time in complex trees.') ?> 173e0bd7dc9SGreg Roach </p> 174e0bd7dc9SGreg Roach 17545ac604bSGreg Roach <form method="post"> 17645ac604bSGreg Roach <?php foreach (Tree::getAll() as $tree): ?> 17715d603e7SGreg Roach <h2><?= $tree->getTitleHtml() ?></h2> 17815d603e7SGreg Roach <div class="row form-group"> 17915d603e7SGreg Roach <label class="col-sm-3 col-form-label" for="relationship-ancestors-<?= $tree->getTreeId() ?>"> 18015d603e7SGreg Roach <?= /* I18N: Configuration option */I18N::translate('Relationships') ?> 181e0bd7dc9SGreg Roach </label> 182e0bd7dc9SGreg Roach <div class="col-sm-9"> 18315d603e7SGreg Roach <?= Bootstrap4::select($this->ancestorsOptions(), $tree->getPreference('RELATIONSHIP_ANCESTORS', self::DEFAULT_ANCESTORS), ['id' => 'relationship-ancestors-' . $tree->getTreeId(), 'name' => 'relationship-ancestors-' . $tree->getTreeId()]) ?> 184e0bd7dc9SGreg Roach </div> 185e0bd7dc9SGreg Roach </div> 186e0bd7dc9SGreg Roach 18745ac604bSGreg Roach <fieldset class="form-group"> 18815d603e7SGreg Roach <div class="row"> 189fff20713SGreg Roach <legend class="col-form-label col-sm-3"> 19015d603e7SGreg Roach <?= /* I18N: Configuration option */I18N::translate('How much recursion to use when searching for relationships') ?> 19145ac604bSGreg Roach </legend> 19245ac604bSGreg Roach <div class="col-sm-9"> 19315d603e7SGreg Roach <?= Bootstrap4::radioButtons('relationship-recursion-' . $tree->getTreeId(), $this->recursionOptions(), $tree->getPreference('RELATIONSHIP_RECURSION', self::DEFAULT_RECURSION), true) ?> 19415d603e7SGreg Roach </div> 19545ac604bSGreg Roach </div> 19645ac604bSGreg Roach </fieldset> 19715d603e7SGreg Roach <?php endforeach ?> 19845ac604bSGreg Roach 19915d603e7SGreg Roach <div class="row form-group"> 20015d603e7SGreg Roach <div class="offset-sm-3 col-sm-9"> 20145ac604bSGreg Roach <button type="submit" class="btn btn-primary"> 2028108dc50SGreg Roach <i class="fas fa-check"></i> 20315d603e7SGreg Roach <?= I18N::translate('save') ?> 20445ac604bSGreg Roach </button> 20545ac604bSGreg Roach </div> 20645ac604bSGreg Roach </div> 20745ac604bSGreg Roach </form> 20845ac604bSGreg Roach <?php 20945ac604bSGreg Roach } 21045ac604bSGreg Roach 21145ac604bSGreg Roach /** 21245ac604bSGreg Roach * Save updated configuration settings. 21345ac604bSGreg Roach */ 21445ac604bSGreg Roach private function saveConfig() { 21545ac604bSGreg Roach if (Auth::isAdmin()) { 21645ac604bSGreg Roach foreach (Tree::getAll() as $tree) { 2171e3273c9SGreg Roach $tree->setPreference('RELATIONSHIP_RECURSION', Filter::post('relationship-recursion-' . $tree->getTreeId())); 218e0bd7dc9SGreg Roach $tree->setPreference('RELATIONSHIP_ANCESTORS', Filter::post('relationship-ancestors-' . $tree->getTreeId())); 21945ac604bSGreg Roach } 22045ac604bSGreg Roach 22145ac604bSGreg Roach FlashMessages::addMessage(I18N::translate('The preferences for the chart “%s” have been updated.', $this->getTitle()), 'success'); 22245ac604bSGreg Roach } 22345ac604bSGreg Roach 224bff8dc60SGreg Roach header('Location: module.php?mod=' . $this->getName() . '&mod_action=admin'); 22545ac604bSGreg Roach } 22645ac604bSGreg Roach 22745ac604bSGreg Roach /** 22845ac604bSGreg Roach * The URL to a page where the user can modify the configuration of this module. 22945ac604bSGreg Roach * 23045ac604bSGreg Roach * @return string 23145ac604bSGreg Roach */ 23245ac604bSGreg Roach public function getConfigLink() { 233b1b85189SGreg Roach return Html::url('module.php', [ 234b1b85189SGreg Roach 'mod' => $this->getName(), 235b1b85189SGreg Roach 'mod_action' => 'admin', 236b1b85189SGreg Roach ]); 23745ac604bSGreg Roach } 238168ff6f3Sric2016} 239