xref: /webtrees/app/Module/HtmlBlockModule.php (revision 3d7a8a4ca809135634f38216b734b15acff479f7)
1<?php
2namespace Fisharebest\Webtrees\Module;
3
4/**
5 * webtrees: online genealogy
6 * Copyright (C) 2015 webtrees development team
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18use Fisharebest\Webtrees\Auth;
19use Fisharebest\Webtrees\Filter;
20use Fisharebest\Webtrees\Functions\FunctionsDate;
21use Fisharebest\Webtrees\Functions\FunctionsEdit;
22use Fisharebest\Webtrees\GedcomTag;
23use Fisharebest\Webtrees\I18N;
24use Fisharebest\Webtrees\Module;
25use Fisharebest\Webtrees\Site;
26use Fisharebest\Webtrees\Stats;
27use Fisharebest\Webtrees\Theme;
28use Fisharebest\Webtrees\Tree;
29
30/**
31 * Class HtmlBlockModule
32 */
33class HtmlBlockModule extends AbstractModule implements ModuleBlockInterface {
34	/** {@inheritdoc} */
35	public function getTitle() {
36		return /* I18N: Name of a module */ I18N::translate('HTML');
37	}
38
39	/** {@inheritdoc} */
40	public function getDescription() {
41		return /* I18N: Description of the “HTML” module */ I18N::translate('Add your own text and graphics.');
42	}
43
44	/** {@inheritdoc} */
45	public function getBlock($block_id, $template = true, $cfg = null) {
46		global $ctype, $WT_TREE;
47
48		$title          = $this->getBlockSetting($block_id, 'title');
49		$html           = $this->getBlockSetting($block_id, 'html');
50		$gedcom         = $this->getBlockSetting($block_id, 'gedcom');
51		$show_timestamp = $this->getBlockSetting($block_id, 'show_timestamp', '0');
52		$languages      = $this->getBlockSetting($block_id, 'languages');
53
54		// Only show this block for certain languages
55		if ($languages && !in_array(WT_LOCALE, explode(',', $languages))) {
56			return '';
57		}
58
59		/*
60		 * Select GEDCOM
61		 */
62		switch ($gedcom) {
63		case '__current__':
64			$stats = new Stats($WT_TREE);
65			break;
66		case '__default__':
67			$tree = Tree::findByName(Site::getPreference('DEFAULT_GEDCOM'));
68			if ($tree) {
69				$stats = new Stats($tree);
70			} else {
71				$stats = new Stats($WT_TREE);
72			}
73			break;
74		default:
75			$tree = Tree::findByName($gedcom);
76			if ($tree) {
77				$stats = new Stats($tree);
78			} else {
79				$stats = new Stats($WT_TREE);
80			}
81			break;
82		}
83
84		/*
85		* Retrieve text, process embedded variables
86		*/
87		if (strpos($title, '#') !== false || strpos($html, '#') !== false) {
88			$title = $stats->embedTags($title);
89			$html  = $stats->embedTags($html);
90		}
91
92		/*
93		* Start Of Output
94		*/
95		$id    = $this->getName() . $block_id;
96		$class = $this->getName() . '_block';
97		if ($ctype === 'gedcom' && Auth::isManager($WT_TREE) || $ctype === 'user' && Auth::check()) {
98			$title = '<a class="icon-admin" title="' . I18N::translate('Configure') . '" href="block_edit.php?block_id=' . $block_id . '&amp;ged=' . $WT_TREE->getNameHtml() . '&amp;ctype=' . $ctype . '"></a>';
99		}
100
101		$content = $html;
102
103		if ($show_timestamp) {
104			$content .= '<br>' . FunctionsDate::formatTimestamp($this->getBlockSetting($block_id, 'timestamp', WT_TIMESTAMP) + WT_TIMESTAMP_OFFSET);
105		}
106
107		if ($template) {
108			return Theme::theme()->formatBlock($id, $title, $class, $content);
109		} else {
110			return $content;
111		}
112	}
113
114	/** {@inheritdoc} */
115	public function loadAjax() {
116		return false;
117	}
118
119	/** {@inheritdoc} */
120	public function isUserBlock() {
121		return true;
122	}
123
124	/** {@inheritdoc} */
125	public function isGedcomBlock() {
126		return true;
127	}
128
129	/** {@inheritdoc} */
130	public function configureBlock($block_id) {
131		global $WT_TREE;
132
133		if (Filter::postBool('save') && Filter::checkCsrf()) {
134			$languages = Filter::postArray('lang');
135			$this->setBlockSetting($block_id, 'gedcom', Filter::post('gedcom'));
136			$this->setBlockSetting($block_id, 'title', Filter::post('title'));
137			$this->setBlockSetting($block_id, 'html', Filter::post('html'));
138			$this->setBlockSetting($block_id, 'show_timestamp', Filter::postBool('show_timestamp'));
139			$this->setBlockSetting($block_id, 'timestamp', Filter::post('timestamp'));
140			$this->setBlockSetting($block_id, 'languages', implode(',', $languages));
141		}
142
143		$templates = array(
144			I18N::translate('Keyword examples') =>
145			'#getAllTagsTable#',
146
147			I18N::translate('Narrative description') =>
148			/* I18N: do not translate the #keywords# */ I18N::translate('This family tree was last updated on #gedcomUpdated#.  There are #totalSurnames# surnames in this family tree.  The earliest recorded event is the #firstEventType# of #firstEventName# in #firstEventYear#.  The most recent event is the #lastEventType# of #lastEventName# in #lastEventYear#.<br><br>If you have any comments or feedback please contact #contactWebmaster#.'),
149
150			I18N::translate('Statistics') =>
151			'<div class="gedcom_stats">
152				<span style="font-weight: bold;"><a href="index.php?command=gedcom">#gedcomTitle#</a></span><br>
153				' . I18N::translate('This family tree was last updated on %s.', '#gedcomUpdated#') . '
154				<table id="keywords">
155					<tr>
156						<td valign="top" class="width20">
157							<table cellspacing="1" cellpadding="0">
158								<tr>
159									<td class="facts_label">' . I18N::translate('Individuals') . '</td>
160									<td class="facts_value" align="right"><a href="indilist.php?surname_sublist=no">#totalIndividuals#</a></td>
161								</tr>
162								<tr>
163									<td class="facts_label">' . I18N::translate('Males') . '</td>
164									<td class="facts_value" align="right">#totalSexMales#<br>#totalSexMalesPercentage#</td>
165								</tr>
166								<tr>
167									<td class="facts_label">' . I18N::translate('Females') . '</td>
168									<td class="facts_value" align="right">#totalSexFemales#<br>#totalSexFemalesPercentage#</td>
169								</tr>
170								<tr>
171									<td class="facts_label">' . I18N::translate('Total surnames') . '</td>
172									<td class="facts_value" align="right"><a href="indilist.php?show_all=yes&amp;surname_sublist=yes&amp;ged=' . $WT_TREE->getNameUrl() . '">#totalSurnames#</a></td>
173								</tr>
174								<tr>
175									<td class="facts_label">' . I18N::translate('Families') . '</td>
176									<td class="facts_value" align="right"><a href="famlist.php?ged=' . $WT_TREE->getNameUrl() . '">#totalFamilies#</a></td>
177								</tr>
178								<tr>
179									<td class="facts_label">' . I18N::translate('Sources') . '</td>
180									<td class="facts_value" align="right"><a href="sourcelist.php?ged=' . $WT_TREE->getNameUrl() . '">#totalSources#</a></td>
181								</tr>
182								<tr>
183									<td class="facts_label">' . I18N::translate('Media objects') . '</td>
184									<td class="facts_value" align="right"><a href="medialist.php?ged=' . $WT_TREE->getNameUrl() . '">#totalMedia#</a></td>
185								</tr>
186								<tr>
187									<td class="facts_label">' . I18N::translate('Repositories') . '</td>
188									<td class="facts_value" align="right"><a href="repolist.php?ged=' . $WT_TREE->getNameUrl() . '">#totalRepositories#</a></td>
189								</tr>
190								<tr>
191									<td class="facts_label">' . I18N::translate('Total events') . '</td>
192									<td class="facts_value" align="right">#totalEvents#</td>
193								</tr>
194								<tr>
195									<td class="facts_label">' . I18N::translate('Total users') . '</td>
196									<td class="facts_value" align="right">#totalUsers#</td>
197								</tr>
198							</table>
199						</td>
200						<td><br></td>
201						<td valign="top">
202							<table cellspacing="1" cellpadding="0" border="0">
203								<tr>
204									<td class="facts_label">' . I18N::translate('Earliest birth year') . '</td>
205									<td class="facts_value" align="right">#firstBirthYear#</td>
206									<td class="facts_value">#firstBirth#</td>
207								</tr>
208								<tr>
209									<td class="facts_label">' . I18N::translate('Latest birth year') . '</td>
210									<td class="facts_value" align="right">#lastBirthYear#</td>
211									<td class="facts_value">#lastBirth#</td>
212								</tr>
213								<tr>
214									<td class="facts_label">' . I18N::translate('Earliest death year') . '</td>
215									<td class="facts_value" align="right">#firstDeathYear#</td>
216									<td class="facts_value">#firstDeath#</td>
217								</tr>
218								<tr>
219									<td class="facts_label">' . I18N::translate('Latest death year') . '</td>
220									<td class="facts_value" align="right">#lastDeathYear#</td>
221									<td class="facts_value">#lastDeath#</td>
222								</tr>
223								<tr>
224									<td class="facts_label">' . I18N::translate('Individual who lived the longest') . '</td>
225									<td class="facts_value" align="right">#longestLifeAge#</td>
226									<td class="facts_value">#longestLife#</td>
227								</tr>
228								<tr>
229									<td class="facts_label">' . I18N::translate('Average age at death') . '</td>
230									<td class="facts_value" align="right">#averageLifespan#</td>
231									<td class="facts_value"></td>
232								</tr>
233								<tr>
234									<td class="facts_label">' . I18N::translate('Family with the most children') . '</td>
235									<td class="facts_value" align="right">#largestFamilySize#</td>
236									<td class="facts_value">#largestFamily#</td>
237								</tr>
238								<tr>
239									<td class="facts_label">' . I18N::translate('Average number of children per family') . '</td>
240									<td class="facts_value" align="right">#averageChildren#</td>
241									<td class="facts_value"></td>
242								</tr>
243							</table>
244						</td>
245					</tr>
246				</table><br>
247				<span style="font-weight: bold;">' . I18N::translate('Most common surnames') . '</span><br>
248				#commonSurnames#
249			</div>',
250		);
251
252		$title          = $this->getBlockSetting($block_id, 'title');
253		$html           = $this->getBlockSetting($block_id, 'html');
254		$gedcom         = $this->getBlockSetting($block_id, 'gedcom');
255		$show_timestamp = $this->getBlockSetting($block_id, 'show_timestamp', '0');
256		$languages      = explode(',', $this->getBlockSetting($block_id, 'languages'));
257
258		echo '<tr><td class="descriptionbox wrap">',
259			GedcomTag::getLabel('TITL'),
260			'</td><td class="optionbox"><input type="text" name="title" size="30" value="', Filter::escapeHtml($title), '"></td></tr>';
261
262		// templates
263		echo '<tr><td class="descriptionbox wrap">',
264			I18N::translate('Templates'),
265			'</td><td class="optionbox wrap">';
266		// The CK editor needs lots of help to load/save data :-(
267		if (Module::getModuleByName('ckeditor')) {
268			$ckeditor_onchange = 'CKEDITOR.instances.html.setData(document.block.html.value);';
269		} else {
270			$ckeditor_onchange = '';
271		}
272		echo '<select name="template" onchange="document.block.html.value=document.block.template.options[document.block.template.selectedIndex].value;', $ckeditor_onchange, '">';
273		echo '<option value="', Filter::escapeHtml($html), '">', I18N::translate('Custom'), '</option>';
274		foreach ($templates as $title => $template) {
275			echo '<option value="', Filter::escapeHtml($template), '">', $title, '</option>';
276		}
277		echo '</select>';
278		if (!$html) {
279			echo '<p>', I18N::translate('To assist you in getting started with this block, we have created several standard templates.  When you select one of these templates, the text area will contain a copy that you can then alter to suit your site’s requirements.'), '</p>';
280		}
281		echo '</td></tr>';
282
283		if (count(Tree::getAll()) > 1) {
284			if ($gedcom == '__current__') {$sel_current = 'selected'; } else {$sel_current = ''; }
285			if ($gedcom == '__default__') {$sel_default = 'selected'; } else {$sel_default = ''; }
286			echo '<tr><td class="descriptionbox wrap">',
287				I18N::translate('Family tree'),
288				'</td><td class="optionbox">',
289				'<select name="gedcom">',
290				'<option value="__current__" ', $sel_current, '>', I18N::translate('Current'), '</option>',
291				'<option value="__default__" ', $sel_default, '>', I18N::translate('Default'), '</option>';
292			foreach (Tree::getAll() as $tree) {
293				if ($tree->getName() === $gedcom) {$sel = 'selected'; } else {$sel = ''; }
294				echo '<option value="', $tree->getNameHtml(), '" ', $sel, '>', $tree->getTitleHtml(), '</option>';
295			}
296			echo '</select>';
297			echo '</td></tr>';
298		}
299
300		// html
301		echo '<tr><td colspan="2" class="descriptionbox">',
302			I18N::translate('Content');
303		if (!$html) {
304			echo '<p>', I18N::translate('As well as using the toolbar to apply HTML formatting, you can insert database fields which are updated automatically.  These special fields are marked with <b>#</b> characters.  For example <b>#totalFamilies#</b> will be replaced with the actual number of families in the database.  Advanced users may wish to apply CSS classes to their text, so that the formatting matches the currently selected theme.'), '</p>';
305		}
306		echo
307			'</td></tr><tr>',
308			'<td colspan="2" class="optionbox">';
309		echo '<textarea name="html" class="html-edit" rows="10" style="width:98%;">', Filter::escapeHtml($html), '</textarea>';
310		echo '</td></tr>';
311
312		echo '<tr><td class="descriptionbox wrap">';
313		echo I18N::translate('Show the date and time of update');
314		echo '</td><td class="optionbox">';
315		echo FunctionsEdit::editFieldYesNo('show_timestamp', $show_timestamp);
316		echo '<input type="hidden" name="timestamp" value="', WT_TIMESTAMP, '">';
317		echo '</td></tr>';
318
319		echo '<tr><td class="descriptionbox wrap">';
320		echo I18N::translate('Show this block for which languages?');
321		echo '</td><td class="optionbox">';
322		echo FunctionsEdit::editLanguageCheckboxes('lang', $languages);
323		echo '</td></tr>';
324	}
325}
326