xref: /webtrees/app/Module/ChartsBlockModule.php (revision c385536d61a9b9bed37314ecc08afa8429a269ef)
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\Bootstrap4;
20use Fisharebest\Webtrees\Controller\HourglassController;
21use Fisharebest\Webtrees\Filter;
22use Fisharebest\Webtrees\Functions\FunctionsEdit;
23use Fisharebest\Webtrees\Functions\FunctionsPrint;
24use Fisharebest\Webtrees\I18N;
25use Fisharebest\Webtrees\Individual;
26use Fisharebest\Webtrees\Module\InteractiveTree\TreeView;
27
28/**
29 * Class ChartsBlockModule
30 */
31class ChartsBlockModule extends AbstractModule implements ModuleBlockInterface {
32	/** {@inheritdoc} */
33	public function getTitle() {
34		return /* I18N: Name of a module/block */ I18N::translate('Charts');
35	}
36
37	/** {@inheritdoc} */
38	public function getDescription() {
39		return /* I18N: Description of the “Charts” module */ I18N::translate('An alternative way to display charts.');
40	}
41
42	/**
43	 * Generate the HTML content of this block.
44	 *
45	 * @param int      $block_id
46	 * @param bool     $template
47	 * @param string[] $cfg
48	 *
49	 * @return string
50	 */
51	public function getBlock($block_id, $template = true, $cfg = []): string {
52		global $WT_TREE, $ctype, $controller;
53
54		$PEDIGREE_ROOT_ID = $WT_TREE->getPreference('PEDIGREE_ROOT_ID');
55		$gedcomid         = $WT_TREE->getUserPreference(Auth::user(), 'gedcomid');
56
57		$type = $this->getBlockSetting($block_id, 'type', 'pedigree');
58		$pid  = $this->getBlockSetting($block_id, 'pid', Auth::check() ? ($gedcomid ? $gedcomid : $PEDIGREE_ROOT_ID) : $PEDIGREE_ROOT_ID);
59
60		extract($cfg, EXTR_OVERWRITE);
61
62		$person = Individual::getInstance($pid, $WT_TREE);
63		if (!$person) {
64			$pid = $PEDIGREE_ROOT_ID;
65			$this->setBlockSetting($block_id, 'pid', $pid);
66			$person = Individual::getInstance($pid, $WT_TREE);
67		}
68
69		$title = $this->getTitle();
70
71		if ($person) {
72			$content = '';
73			switch ($type) {
74				case 'pedigree':
75					$title           = I18N::translate('Pedigree of %s', $person->getFullName());
76					$chartController = new HourglassController($person->getXref());
77					$content .= '<table cellspacing="0" cellpadding="0" border="0"><tr>';
78					$content .= '<td class="myCharts">';
79					ob_start();
80					FunctionsPrint::printPedigreePerson($person);
81					$content .= ob_get_clean();
82					$content .= '</td>';
83					$content .= '<td>';
84					ob_start();
85					$chartController->printPersonPedigree($person, 1);
86					$content .= ob_get_clean();
87					$content .= '</td>';
88					$content .= '</tr></table>';
89					$content .= '<script>' . $chartController->setupJavascript() . '</script>';
90					break;
91				case 'descendants':
92					$title           = I18N::translate('Descendants of %s', $person->getFullName());
93					$chartController = new HourglassController($person->getXref());
94					ob_start();
95					$chartController->printDescendency($person, 1, false);
96					$content .= ob_get_clean();
97					$content .= '<script>' . $chartController->setupJavascript() . '</script>';
98					break;
99				case 'hourglass':
100					$title           = I18N::translate('Hourglass chart of %s', $person->getFullName());
101					$chartController = new HourglassController($person->getXref());
102					$content .= '<table cellspacing="0" cellpadding="0" border="0"><tr>';
103					$content .= '<td>';
104					ob_start();
105					$chartController->printDescendency($person, 1, false);
106					$content .= ob_get_clean();
107					$content .= '</td>';
108					$content .= '<td>';
109					ob_start();
110					$chartController->printPersonPedigree($person, 1);
111					$content .= ob_get_clean();
112					$content .= '</td>';
113					$content .= '</tr></table>';
114					$content .= '<script>' . $chartController->setupJavascript() . '</script>';
115					break;
116				case 'treenav':
117					$title = I18N::translate('Interactive tree of %s', $person->getFullName());
118					$mod   = new InteractiveTreeModule(WT_MODULES_DIR . 'tree');
119					$tv    = new TreeView;
120					$content .= '<script>$("head").append(\'<link rel="stylesheet" href="' . $mod->css() . '" type="text/css" />\');</script>';
121					$content .= '<script src="' . $mod->js() . '"></script>';
122					list($html, $js) = $tv->drawViewport($person, 2);
123					$content .= $html . '<script>' . $js . '</script>';
124					break;
125			}
126		} else {
127			$content = I18N::translate('You must select an individual and a chart type in the block preferences');
128		}
129
130		if ($template) {
131			if ($ctype === 'gedcom' && Auth::isManager($WT_TREE)) {
132				$config_url = route('tree-page-block-edit', ['block_id' => $block_id, 'ged' => $WT_TREE->getName()]);
133			} elseif ($ctype === 'user' && Auth::check()) {
134				$config_url = route('user-page-block-edit', ['block_id' => $block_id, 'ged' => $WT_TREE->getName()]);
135			} else {
136				$config_url = '';
137			}
138
139			return view('blocks/template', [
140				'block'      => str_replace('_', '-', $this->getName()),
141				'id'         => $block_id,
142				'config_url' => $config_url,
143				'title'      => strip_tags($title),
144				'content'    => $content,
145			]);
146		} else {
147			return $content;
148		}
149	}
150
151	/** {@inheritdoc} */
152	public function loadAjax(): bool {
153		return true;
154	}
155
156	/** {@inheritdoc} */
157	public function isUserBlock(): bool {
158		return true;
159	}
160
161	/** {@inheritdoc} */
162	public function isGedcomBlock(): bool {
163		return true;
164	}
165
166	/**
167	 * An HTML form to edit block settings
168	 *
169	 * @param int $block_id
170	 *
171	 * @return void
172	 */
173	public function configureBlock($block_id) {
174		global $WT_TREE;
175
176		$PEDIGREE_ROOT_ID = $WT_TREE->getPreference('PEDIGREE_ROOT_ID');
177		$gedcomid         = $WT_TREE->getUserPreference(Auth::user(), 'gedcomid');
178
179		if ($_SERVER['REQUEST_METHOD'] === 'POST') {
180			$this->setBlockSetting($block_id, 'type', Filter::post('type', 'pedigree|descendants|hourglass|treenav', 'pedigree'));
181			$this->setBlockSetting($block_id, 'pid', Filter::post('pid', WT_REGEX_XREF));
182
183			return;
184		}
185
186		$type = $this->getBlockSetting($block_id, 'type', 'pedigree');
187		$pid  = $this->getBlockSetting($block_id, 'pid', Auth::check() ? ($gedcomid ? $gedcomid : $PEDIGREE_ROOT_ID) : $PEDIGREE_ROOT_ID);
188
189		$charts = [
190			'pedigree'    => I18N::translate('Pedigree'),
191			'descendants' => I18N::translate('Descendants'),
192			'hourglass'   => I18N::translate('Hourglass chart'),
193			'treenav'     => I18N::translate('Interactive tree'),
194		];
195		uasort($charts, 'Fisharebest\Webtrees\I18N::strcasecmp');
196
197		$individual = Individual::getInstance($pid, $WT_TREE);
198
199		echo view('blocks/charts-config', [
200			'charts'     => $charts,
201			'individual' => $individual,
202			'type'       => $type,
203		]);
204	}
205}
206