xref: /webtrees/app/Module/RelationshipsChartModule.php (revision bff8dc608bbc4d35f7c720d8a008a0ca3c766e2d)
1168ff6f3Sric2016<?php
2168ff6f3Sric2016/**
3168ff6f3Sric2016 * webtrees: online genealogy
46bdf7674SGreg Roach * Copyright (C) 2017 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;
23168ff6f3Sric2016use Fisharebest\Webtrees\I18N;
24168ff6f3Sric2016use Fisharebest\Webtrees\Individual;
251e3273c9SGreg Roachuse Fisharebest\Webtrees\Menu;
2645ac604bSGreg Roachuse Fisharebest\Webtrees\Tree;
27168ff6f3Sric2016
28168ff6f3Sric2016/**
29168ff6f3Sric2016 * Class RelationshipsChartModule
30168ff6f3Sric2016 */
3145ac604bSGreg Roachclass RelationshipsChartModule extends AbstractModule implements ModuleConfigInterface, ModuleChartInterface {
321e3273c9SGreg Roach	/** It would be more correct to use PHP_INT_MAX, but this isn't friendly in URLs */
331e3273c9SGreg Roach	const UNLIMITED_RECURSION = 99;
341e3273c9SGreg Roach
351e3273c9SGreg Roach	/** By default new trees allow unlimited recursion */
361e3273c9SGreg Roach	const DEFAULT_RECURSION = self::UNLIMITED_RECURSION;
3745ac604bSGreg Roach
38e0bd7dc9SGreg Roach	/** By default new trees search for all relationships (not via ancestors) */
39e0bd7dc9SGreg Roach	const DEFAULT_ANCESTORS = 0;
40e0bd7dc9SGreg Roach
41168ff6f3Sric2016	/**
42168ff6f3Sric2016	 * How should this module be labelled on tabs, menus, etc.?
43168ff6f3Sric2016	 *
44168ff6f3Sric2016	 * @return string
45168ff6f3Sric2016	 */
46168ff6f3Sric2016	public function getTitle() {
47168ff6f3Sric2016		return /* I18N: Name of a module/chart */ I18N::translate('Relationships');
48168ff6f3Sric2016	}
49168ff6f3Sric2016
50168ff6f3Sric2016	/**
51168ff6f3Sric2016	 * A sentence describing what this module does.
52168ff6f3Sric2016	 *
53168ff6f3Sric2016	 * @return string
54168ff6f3Sric2016	 */
55168ff6f3Sric2016	public function getDescription() {
56168ff6f3Sric2016		return /* I18N: Description of the “RelationshipsChart” module */ I18N::translate('A chart displaying relationships between two individuals.');
57168ff6f3Sric2016	}
58168ff6f3Sric2016
59168ff6f3Sric2016	/**
60168ff6f3Sric2016	 * What is the default access level for this module?
61168ff6f3Sric2016	 *
62168ff6f3Sric2016	 * Some modules are aimed at admins or managers, and are not generally shown to users.
63168ff6f3Sric2016	 *
64168ff6f3Sric2016	 * @return int
65168ff6f3Sric2016	 */
66168ff6f3Sric2016	public function defaultAccessLevel() {
67168ff6f3Sric2016		return Auth::PRIV_PRIVATE;
68168ff6f3Sric2016	}
69168ff6f3Sric2016
70168ff6f3Sric2016	/**
71168ff6f3Sric2016	 * Return a menu item for this chart.
72168ff6f3Sric2016	 *
738e69695bSGreg Roach	 * @param Individual $individual
748e69695bSGreg Roach	 *
754eb71cfaSGreg Roach	 * @return Menu|null
76168ff6f3Sric2016	 */
77168ff6f3Sric2016	public function getChartMenu(Individual $individual) {
784eb71cfaSGreg Roach		$tree     = $individual->getTree();
794eb71cfaSGreg Roach		$gedcomid = $tree->getUserPreference(Auth::user(), 'gedcomid');
80168ff6f3Sric2016
814eb71cfaSGreg Roach		if ($gedcomid) {
82168ff6f3Sric2016			return new Menu(
83168ff6f3Sric2016				I18N::translate('Relationship to me'),
844eb71cfaSGreg Roach				'relationship.php?pid1=' . $gedcomid . '&amp;pid2=' . $individual->getXref() . '&amp;ged=' . $tree->getNameUrl(),
85168ff6f3Sric2016				'menu-chart-relationship',
8613abd6f3SGreg Roach				['rel' => 'nofollow']
87168ff6f3Sric2016			);
88168ff6f3Sric2016		} else {
89168ff6f3Sric2016			return new Menu(
90168ff6f3Sric2016				I18N::translate('Relationships'),
914eb71cfaSGreg Roach				'relationship.php?pid1=' . $individual->getXref() . '&amp;ged=' . $tree->getNameUrl(),
92168ff6f3Sric2016				'menu-chart-relationship',
9313abd6f3SGreg Roach				['rel' => 'nofollow']
94168ff6f3Sric2016			);
95168ff6f3Sric2016		}
96168ff6f3Sric2016	}
97168ff6f3Sric2016
984eb71cfaSGreg Roach	/**
994eb71cfaSGreg Roach	 * Return a menu item for this chart - for use in individual boxes.
1004eb71cfaSGreg Roach	 *
1018e69695bSGreg Roach	 * @param Individual $individual
1028e69695bSGreg Roach	 *
1034eb71cfaSGreg Roach	 * @return Menu|null
1044eb71cfaSGreg Roach	 */
105168ff6f3Sric2016	public function getBoxChartMenu(Individual $individual) {
106168ff6f3Sric2016		return $this->getChartMenu($individual);
107168ff6f3Sric2016	}
10845ac604bSGreg Roach
10945ac604bSGreg Roach	/**
11045ac604bSGreg Roach	 * This is a general purpose hook, allowing modules to respond to routes
11145ac604bSGreg Roach	 * of the form module.php?mod=FOO&mod_action=BAR
11245ac604bSGreg Roach	 *
11345ac604bSGreg Roach	 * @param string $mod_action
11445ac604bSGreg Roach	 */
11545ac604bSGreg Roach	public function modAction($mod_action) {
11645ac604bSGreg Roach		switch ($mod_action) {
11745ac604bSGreg Roach		case 'admin':
11845ac604bSGreg Roach			if ($_SERVER['REQUEST_METHOD'] === 'POST') {
11945ac604bSGreg Roach				$this->saveConfig();
12045ac604bSGreg Roach			} else {
12145ac604bSGreg Roach				$this->editConfig();
12245ac604bSGreg Roach			}
12345ac604bSGreg Roach			break;
12445ac604bSGreg Roach		default:
12545ac604bSGreg Roach			http_response_code(404);
12645ac604bSGreg Roach		}
12745ac604bSGreg Roach	}
12845ac604bSGreg Roach
12945ac604bSGreg Roach	/**
130e0bd7dc9SGreg Roach	 * Possible options for the ancestors option
131e0bd7dc9SGreg Roach	 */
132e0bd7dc9SGreg Roach	private function ancestorsOptions() {
13313abd6f3SGreg Roach		return [
134e0bd7dc9SGreg Roach			0 => I18N::translate('Find any relationship'),
135e0bd7dc9SGreg Roach			1 => I18N::translate('Find relationships via ancestors'),
13613abd6f3SGreg Roach		];
137e0bd7dc9SGreg Roach	}
138e0bd7dc9SGreg Roach
139e0bd7dc9SGreg Roach	/**
1401e3273c9SGreg Roach	 * Possible options for the recursion option
1411e3273c9SGreg Roach	 */
1421e3273c9SGreg Roach	private function recursionOptions() {
14313abd6f3SGreg Roach		return [
1441e3273c9SGreg Roach			0                         => I18N::translate('none'),
1451e3273c9SGreg Roach			1                         => I18N::number(1),
1461e3273c9SGreg Roach			2                         => I18N::number(2),
1471e3273c9SGreg Roach			3                         => I18N::number(3),
148e0bd7dc9SGreg Roach			self::UNLIMITED_RECURSION => I18N::translate('unlimited'),
14913abd6f3SGreg Roach		];
1501e3273c9SGreg Roach	}
1511e3273c9SGreg Roach
1521e3273c9SGreg Roach	/**
15345ac604bSGreg Roach	 * Display a form to edit configuration settings.
15445ac604bSGreg Roach	 */
15545ac604bSGreg Roach	private function editConfig() {
15645ac604bSGreg Roach		$controller = new PageController;
15745ac604bSGreg Roach		$controller
15845ac604bSGreg Roach			->restrictAccess(Auth::isAdmin())
15945ac604bSGreg Roach			->setPageTitle(I18N::translate('Chart preferences') . ' — ' . $this->getTitle())
16045ac604bSGreg Roach			->pageHeader();
16145ac604bSGreg Roach
16215d603e7SGreg Roach		echo Bootstrap4::breadcrumbs([
16315d603e7SGreg Roach			'admin.php'         => I18N::translate('Control panel'),
16415d603e7SGreg Roach			'admin_modules.php' => I18N::translate('Module administration'),
16515d603e7SGreg Roach		], $controller->getPageTitle());
16645ac604bSGreg Roach		?>
16715d603e7SGreg Roach
16815d603e7SGreg Roach		<h1><?= $controller->getPageTitle() ?></h1>
16945ac604bSGreg Roach
170e0bd7dc9SGreg Roach		<p>
17115d603e7SGreg Roach			<?= I18N::translate('Searching for all possible relationships can take a lot of time in complex trees.') ?>
172e0bd7dc9SGreg Roach		</p>
173e0bd7dc9SGreg Roach
17445ac604bSGreg Roach		<form method="post">
17545ac604bSGreg Roach			<?php foreach (Tree::getAll() as $tree): ?>
17615d603e7SGreg Roach				<h2><?= $tree->getTitleHtml() ?></h2>
17715d603e7SGreg Roach				<div class="row form-group">
17815d603e7SGreg Roach					<label class="col-sm-3 col-form-label" for="relationship-ancestors-<?= $tree->getTreeId() ?>">
17915d603e7SGreg Roach						<?= /* I18N: Configuration option */I18N::translate('Relationships') ?>
180e0bd7dc9SGreg Roach					</label>
181e0bd7dc9SGreg Roach					<div class="col-sm-9">
18215d603e7SGreg Roach						<?= Bootstrap4::select($this->ancestorsOptions(), $tree->getPreference('RELATIONSHIP_ANCESTORS', self::DEFAULT_ANCESTORS), ['id' => 'relationship-ancestors-' . $tree->getTreeId(), 'name' => 'relationship-ancestors-' . $tree->getTreeId()]) ?>
183e0bd7dc9SGreg Roach					</div>
184e0bd7dc9SGreg Roach				</div>
185e0bd7dc9SGreg Roach
18645ac604bSGreg Roach				<fieldset class="form-group">
18715d603e7SGreg Roach					<div class="row">
18815d603e7SGreg Roach						<legend class="col-form-legend col-sm-3">
18915d603e7SGreg Roach							<?= /* I18N: Configuration option */I18N::translate('How much recursion to use when searching for relationships') ?>
19045ac604bSGreg Roach						</legend>
19145ac604bSGreg Roach						<div class="col-sm-9">
19215d603e7SGreg Roach							<?= Bootstrap4::radioButtons('relationship-recursion-' . $tree->getTreeId(), $this->recursionOptions(), $tree->getPreference('RELATIONSHIP_RECURSION', self::DEFAULT_RECURSION), true) ?>
19315d603e7SGreg Roach						</div>
19445ac604bSGreg Roach					</div>
19545ac604bSGreg Roach				</fieldset>
19615d603e7SGreg Roach			<?php endforeach ?>
19745ac604bSGreg Roach
19815d603e7SGreg Roach			<div class="row form-group">
19915d603e7SGreg Roach				<div class="offset-sm-3 col-sm-9">
20045ac604bSGreg Roach					<button type="submit" class="btn btn-primary">
20145ac604bSGreg Roach						<i class="fa fa-check"></i>
20215d603e7SGreg Roach						<?= I18N::translate('save') ?>
20345ac604bSGreg Roach					</button>
20445ac604bSGreg Roach				</div>
20545ac604bSGreg Roach			</div>
20645ac604bSGreg Roach		</form>
20745ac604bSGreg Roach		<?php
20845ac604bSGreg Roach	}
20945ac604bSGreg Roach
21045ac604bSGreg Roach	/**
21145ac604bSGreg Roach	 * Save updated configuration settings.
21245ac604bSGreg Roach	 */
21345ac604bSGreg Roach	private function saveConfig() {
21445ac604bSGreg Roach		if (Auth::isAdmin()) {
21545ac604bSGreg Roach			foreach (Tree::getAll() as $tree) {
2161e3273c9SGreg Roach				$tree->setPreference('RELATIONSHIP_RECURSION', Filter::post('relationship-recursion-' . $tree->getTreeId()));
217e0bd7dc9SGreg Roach				$tree->setPreference('RELATIONSHIP_ANCESTORS', Filter::post('relationship-ancestors-' . $tree->getTreeId()));
21845ac604bSGreg Roach			}
21945ac604bSGreg Roach
22045ac604bSGreg Roach			FlashMessages::addMessage(I18N::translate('The preferences for the chart “%s” have been updated.', $this->getTitle()), 'success');
22145ac604bSGreg Roach		}
22245ac604bSGreg Roach
223*bff8dc60SGreg Roach		header('Location: module.php?mod=' . $this->getName() . '&mod_action=admin');
22445ac604bSGreg Roach	}
22545ac604bSGreg Roach
22645ac604bSGreg Roach	/**
22745ac604bSGreg Roach	 * The URL to a page where the user can modify the configuration of this module.
22845ac604bSGreg Roach	 *
22945ac604bSGreg Roach	 * @return string
23045ac604bSGreg Roach	 */
23145ac604bSGreg Roach	public function getConfigLink() {
23245ac604bSGreg Roach		return 'module.php?mod=' . $this->getName() . '&amp;mod_action=admin';
23345ac604bSGreg Roach	}
234168ff6f3Sric2016}
235