18c2e8227SGreg Roach<?php 28c2e8227SGreg Roach/** 38c2e8227SGreg Roach * webtrees: online genealogy 46bdf7674SGreg Roach * Copyright (C) 2017 webtrees development team 58c2e8227SGreg Roach * This program is free software: you can redistribute it and/or modify 68c2e8227SGreg Roach * it under the terms of the GNU General Public License as published by 78c2e8227SGreg Roach * the Free Software Foundation, either version 3 of the License, or 88c2e8227SGreg Roach * (at your option) any later version. 98c2e8227SGreg Roach * This program is distributed in the hope that it will be useful, 108c2e8227SGreg Roach * but WITHOUT ANY WARRANTY; without even the implied warranty of 118c2e8227SGreg Roach * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 128c2e8227SGreg Roach * GNU General Public License for more details. 138c2e8227SGreg Roach * You should have received a copy of the GNU General Public License 148c2e8227SGreg Roach * along with this program. If not, see <http://www.gnu.org/licenses/>. 158c2e8227SGreg Roach */ 1676692c8bSGreg Roachnamespace Fisharebest\Webtrees\Module; 1776692c8bSGreg Roach 180e62c4b8SGreg Roachuse Fisharebest\Webtrees\Auth; 1915d603e7SGreg Roachuse Fisharebest\Webtrees\Bootstrap4; 200e62c4b8SGreg Roachuse Fisharebest\Webtrees\Filter; 213d7a8a4cSGreg Roachuse Fisharebest\Webtrees\Functions\FunctionsDate; 223d7a8a4cSGreg Roachuse Fisharebest\Webtrees\Functions\FunctionsEdit; 23cc5ab399SGreg Roachuse Fisharebest\Webtrees\Html; 240e62c4b8SGreg Roachuse Fisharebest\Webtrees\I18N; 250e62c4b8SGreg Roachuse Fisharebest\Webtrees\Site; 260e62c4b8SGreg Roachuse Fisharebest\Webtrees\Stats; 270e62c4b8SGreg Roachuse Fisharebest\Webtrees\Tree; 289c6524dcSGreg Roachuse Fisharebest\Webtrees\View; 298c2e8227SGreg Roach 308c2e8227SGreg Roach/** 318c2e8227SGreg Roach * Class HtmlBlockModule 328c2e8227SGreg Roach */ 33e2a378d3SGreg Roachclass HtmlBlockModule extends AbstractModule implements ModuleBlockInterface { 348c2e8227SGreg Roach /** {@inheritdoc} */ 358c2e8227SGreg Roach public function getTitle() { 369c6524dcSGreg Roach return /* I18N: Name of a module */ 379c6524dcSGreg Roach I18N::translate('HTML'); 388c2e8227SGreg Roach } 398c2e8227SGreg Roach 408c2e8227SGreg Roach /** {@inheritdoc} */ 418c2e8227SGreg Roach public function getDescription() { 429c6524dcSGreg Roach return /* I18N: Description of the “HTML” module */ 439c6524dcSGreg Roach I18N::translate('Add your own text and graphics.'); 448c2e8227SGreg Roach } 458c2e8227SGreg Roach 4676692c8bSGreg Roach /** 4776692c8bSGreg Roach * Generate the HTML content of this block. 4876692c8bSGreg Roach * 4976692c8bSGreg Roach * @param int $block_id 5076692c8bSGreg Roach * @param bool $template 51727f238cSGreg Roach * @param string[] $cfg 5276692c8bSGreg Roach * 5376692c8bSGreg Roach * @return string 5476692c8bSGreg Roach */ 55a9430be8SGreg Roach public function getBlock($block_id, $template = true, $cfg = []): string { 568c2e8227SGreg Roach global $ctype, $WT_TREE; 578c2e8227SGreg Roach 58c02d9576SGreg Roach $title = $this->getBlockSetting($block_id, 'title', ''); 59c02d9576SGreg Roach $content = $this->getBlockSetting($block_id, 'html', ''); 60e2a378d3SGreg Roach $gedcom = $this->getBlockSetting($block_id, 'gedcom'); 61e2a378d3SGreg Roach $show_timestamp = $this->getBlockSetting($block_id, 'show_timestamp', '0'); 62e2a378d3SGreg Roach $languages = $this->getBlockSetting($block_id, 'languages'); 638c2e8227SGreg Roach 648c2e8227SGreg Roach // Only show this block for certain languages 658c2e8227SGreg Roach if ($languages && !in_array(WT_LOCALE, explode(',', $languages))) { 668c2e8227SGreg Roach return ''; 678c2e8227SGreg Roach } 688c2e8227SGreg Roach 698c2e8227SGreg Roach /* 708c2e8227SGreg Roach * Select GEDCOM 718c2e8227SGreg Roach */ 728c2e8227SGreg Roach switch ($gedcom) { 738c2e8227SGreg Roach case '__current__': 748c2e8227SGreg Roach $stats = new Stats($WT_TREE); 758c2e8227SGreg Roach break; 768c2e8227SGreg Roach case '__default__': 77ef2fd529SGreg Roach $tree = Tree::findByName(Site::getPreference('DEFAULT_GEDCOM')); 78ef2fd529SGreg Roach if ($tree) { 79ef2fd529SGreg Roach $stats = new Stats($tree); 808c2e8227SGreg Roach } else { 818c2e8227SGreg Roach $stats = new Stats($WT_TREE); 828c2e8227SGreg Roach } 838c2e8227SGreg Roach break; 848c2e8227SGreg Roach default: 85ef2fd529SGreg Roach $tree = Tree::findByName($gedcom); 86ef2fd529SGreg Roach if ($tree) { 87ef2fd529SGreg Roach $stats = new Stats($tree); 888c2e8227SGreg Roach } else { 898c2e8227SGreg Roach $stats = new Stats($WT_TREE); 908c2e8227SGreg Roach } 918c2e8227SGreg Roach break; 928c2e8227SGreg Roach } 938c2e8227SGreg Roach 948c2e8227SGreg Roach /* 958c2e8227SGreg Roach * Retrieve text, process embedded variables 968c2e8227SGreg Roach */ 978c2e8227SGreg Roach $title = $stats->embedTags($title); 989c6524dcSGreg Roach $content = $stats->embedTags($content); 998c2e8227SGreg Roach 100c02d9576SGreg Roach if ($show_timestamp === '1') { 1013d7a8a4cSGreg Roach $content .= '<br>' . FunctionsDate::formatTimestamp($this->getBlockSetting($block_id, 'timestamp', WT_TIMESTAMP) + WT_TIMESTAMP_OFFSET); 1028c2e8227SGreg Roach } 1038c2e8227SGreg Roach 1048c2e8227SGreg Roach if ($template) { 1059c6524dcSGreg Roach if ($ctype === 'gedcom' && Auth::isManager($WT_TREE) || $ctype === 'user' && Auth::check()) { 1069c6524dcSGreg Roach $config_url = Html::url('block_edit.php', ['block_id' => $block_id, 'ged' => $WT_TREE->getName()]); 1079c6524dcSGreg Roach } else { 1089c6524dcSGreg Roach $config_url = ''; 1099c6524dcSGreg Roach } 1109c6524dcSGreg Roach 1119c6524dcSGreg Roach return View::make('blocks/template', [ 1129c6524dcSGreg Roach 'block' => str_replace('_', '-', $this->getName()), 1139c6524dcSGreg Roach 'id' => $block_id, 1149c6524dcSGreg Roach 'config_url' => $config_url, 1159c6524dcSGreg Roach 'title' => $title, 1169c6524dcSGreg Roach 'content' => $content, 1179c6524dcSGreg Roach ]); 1188c2e8227SGreg Roach } else { 1198c2e8227SGreg Roach return $content; 1208c2e8227SGreg Roach } 1218c2e8227SGreg Roach } 1228c2e8227SGreg Roach 1238c2e8227SGreg Roach /** {@inheritdoc} */ 124a9430be8SGreg Roach public function loadAjax(): bool { 1258c2e8227SGreg Roach return false; 1268c2e8227SGreg Roach } 1278c2e8227SGreg Roach 1288c2e8227SGreg Roach /** {@inheritdoc} */ 129a9430be8SGreg Roach public function isUserBlock(): bool { 1308c2e8227SGreg Roach return true; 1318c2e8227SGreg Roach } 1328c2e8227SGreg Roach 1338c2e8227SGreg Roach /** {@inheritdoc} */ 134a9430be8SGreg Roach public function isGedcomBlock(): bool { 1358c2e8227SGreg Roach return true; 1368c2e8227SGreg Roach } 1378c2e8227SGreg Roach 13876692c8bSGreg Roach /** 13976692c8bSGreg Roach * An HTML form to edit block settings 14076692c8bSGreg Roach * 14176692c8bSGreg Roach * @param int $block_id 142a9430be8SGreg Roach * 143a9430be8SGreg Roach * @return void 14476692c8bSGreg Roach */ 145*be9a728cSGreg Roach public function configureBlock($block_id) { 1464b9ff166SGreg Roach global $WT_TREE; 1474b9ff166SGreg Roach 1488c2e8227SGreg Roach if (Filter::postBool('save') && Filter::checkCsrf()) { 149c999a340SGreg Roach $languages = Filter::postArray('lang'); 150e2a378d3SGreg Roach $this->setBlockSetting($block_id, 'gedcom', Filter::post('gedcom')); 151e2a378d3SGreg Roach $this->setBlockSetting($block_id, 'title', Filter::post('title')); 152e2a378d3SGreg Roach $this->setBlockSetting($block_id, 'html', Filter::post('html')); 153e2a378d3SGreg Roach $this->setBlockSetting($block_id, 'show_timestamp', Filter::postBool('show_timestamp')); 154e2a378d3SGreg Roach $this->setBlockSetting($block_id, 'timestamp', Filter::post('timestamp')); 155e2a378d3SGreg Roach $this->setBlockSetting($block_id, 'languages', implode(',', $languages)); 1568c2e8227SGreg Roach } 1578c2e8227SGreg Roach 15813abd6f3SGreg Roach $templates = [ 1590fd39724SGreg Roach I18N::translate('Keyword examples') => '#getAllTagsTable#', 1608c2e8227SGreg Roach 1610fd39724SGreg Roach I18N::translate('Narrative description') => /* 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#.'), 1628c2e8227SGreg Roach 1630fd39724SGreg Roach I18N::translate('Statistics') => '<div class="gedcom_stats"> 1648c2e8227SGreg Roach <span style="font-weight: bold;"><a href="index.php?command=gedcom">#gedcomTitle#</a></span><br> 1658c2e8227SGreg Roach ' . I18N::translate('This family tree was last updated on %s.', '#gedcomUpdated#') . ' 166e0486a06SGreg Roach <div class="row"> 167e0486a06SGreg Roach <div class="col col-sm-4"> 168e0486a06SGreg Roach <table class="table wt-facts-table"> 1698c2e8227SGreg Roach <tr> 170e0486a06SGreg Roach <th scope="row">' . I18N::translate('Individuals') . '</th> 171e0486a06SGreg Roach <td>#totalIndividuals#</td> 1728c2e8227SGreg Roach </tr> 1738c2e8227SGreg Roach <tr> 174e0486a06SGreg Roach <th scope="row">' . I18N::translate('Males') . '</th> 175e0486a06SGreg Roach <td>#totalSexMales#<br>#totalSexMalesPercentage#</td> 1768c2e8227SGreg Roach </tr> 1778c2e8227SGreg Roach <tr> 178e0486a06SGreg Roach <th scope="row">' . I18N::translate('Females') . '</th> 179e0486a06SGreg Roach <td>#totalSexFemales#<br>#totalSexFemalesPercentage#</td> 1808c2e8227SGreg Roach </tr> 1818c2e8227SGreg Roach <tr> 182e0486a06SGreg Roach <th scope="row">' . I18N::translate('Total surnames') . '</th> 1835bcf6074SGreg Roach <td>#totalSurnames#</td> 1848c2e8227SGreg Roach </tr> 1858c2e8227SGreg Roach <tr> 186e0486a06SGreg Roach <th scope="row">' . I18N::translate('Families') . '</th> 187e0486a06SGreg Roach <td>#totalFamilies#</td> 1888c2e8227SGreg Roach </tr> 1898c2e8227SGreg Roach <tr> 190e0486a06SGreg Roach <th scope="row">' . I18N::translate('Sources') . '</th> 191e0486a06SGreg Roach <td>#totalSources#</td> 1928c2e8227SGreg Roach </tr> 1938c2e8227SGreg Roach <tr> 194e0486a06SGreg Roach <th scope="row">' . I18N::translate('Media objects') . '</th> 195e0486a06SGreg Roach <td>#totalMedia#</td> 1968c2e8227SGreg Roach </tr> 1978c2e8227SGreg Roach <tr> 198e0486a06SGreg Roach <th scope="row">' . I18N::translate('Repositories') . '</th> 199e0486a06SGreg Roach <td>#totalRepositories#</td> 2008c2e8227SGreg Roach </tr> 2018c2e8227SGreg Roach <tr> 202e0486a06SGreg Roach <th scope="row">' . I18N::translate('Events') . '</th> 203e0486a06SGreg Roach <td>#totalEvents#</td> 2048c2e8227SGreg Roach </tr> 2058c2e8227SGreg Roach <tr> 206e0486a06SGreg Roach <th scope="row">' . I18N::translate('Users') . '</th> 207e0486a06SGreg Roach <td>#totalUsers#</td> 2088c2e8227SGreg Roach </tr> 2098c2e8227SGreg Roach </table> 210e0486a06SGreg Roach </div> 211e0486a06SGreg Roach 212e0486a06SGreg Roach <div class="col col-sm-8"> 213e0486a06SGreg Roach <table class="table wt-facts-table"> 2148c2e8227SGreg Roach <tr> 215e0486a06SGreg Roach <th scope="row">' . I18N::translate('Earliest birth') . '</th> 216e0486a06SGreg Roach <td>#firstBirth#</td> 2178c2e8227SGreg Roach </tr> 2188c2e8227SGreg Roach <tr> 219e0486a06SGreg Roach <th scope="row">' . I18N::translate('Latest birth') . '</th> 220e0486a06SGreg Roach <td>#lastBirth#</td> 2218c2e8227SGreg Roach </tr> 2228c2e8227SGreg Roach <tr> 223e0486a06SGreg Roach <th scope="row">' . I18N::translate('Earliest death') . '</th> 224e0486a06SGreg Roach <td>#firstDeath#</td> 2258c2e8227SGreg Roach </tr> 2268c2e8227SGreg Roach <tr> 227e0486a06SGreg Roach <th scope="row">' . I18N::translate('Latest death') . '</th> 228e0486a06SGreg Roach <td>#lastDeath#</td> 2298c2e8227SGreg Roach </tr> 2308c2e8227SGreg Roach <tr> 231e0486a06SGreg Roach <th scope="row">' . I18N::translate('Individual who lived the longest') . '</th> 232e0486a06SGreg Roach <td>#longestLife#</td> 2338c2e8227SGreg Roach </tr> 2348c2e8227SGreg Roach <tr> 235e0486a06SGreg Roach <th scope="row">' . I18N::translate('Average age at death') . '</th> 236e0486a06SGreg Roach <td>#averageLifespan#</td> 2378c2e8227SGreg Roach </tr> 2388c2e8227SGreg Roach <tr> 239e0486a06SGreg Roach <th scope="row">' . I18N::translate('Family with the most children') . '</th> 240e0486a06SGreg Roach <td>#largestFamilySize#<br>#largestFamily#</td> 2418c2e8227SGreg Roach </tr> 2428c2e8227SGreg Roach <tr> 243e0486a06SGreg Roach <th scope="row">' . I18N::translate('Average number of children per family') . '</th> 244e0486a06SGreg Roach <td>#averageChildren#</td> 2458c2e8227SGreg Roach </tr> 2468c2e8227SGreg Roach </table> 247e0486a06SGreg Roach </div> 248e0486a06SGreg Roach </div> 249e0486a06SGreg Roach <br> 250e0486a06SGreg Roach <span style="font-weight: bold;">' . I18N::translate('Most common surnames') . '</span> 251e0486a06SGreg Roach <br> 2528c2e8227SGreg Roach #commonSurnames# 253cbc1590aSGreg Roach </div>', 25413abd6f3SGreg Roach ]; 2558c2e8227SGreg Roach 256e2a378d3SGreg Roach $title = $this->getBlockSetting($block_id, 'title'); 257e2a378d3SGreg Roach $html = $this->getBlockSetting($block_id, 'html'); 25815d603e7SGreg Roach $gedcom = $this->getBlockSetting($block_id, 'gedcom', '__current__'); 259e2a378d3SGreg Roach $show_timestamp = $this->getBlockSetting($block_id, 'show_timestamp', '0'); 260e2a378d3SGreg Roach $languages = explode(',', $this->getBlockSetting($block_id, 'languages')); 2618c2e8227SGreg Roach 26215d603e7SGreg Roach ?> 26315d603e7SGreg Roach <div class="row form-group"> 26415d603e7SGreg Roach <label class="col-sm-3 col-form-label" for="title"> 26515d603e7SGreg Roach <?= I18N::translate('Title') ?> 26615d603e7SGreg Roach </label> 26715d603e7SGreg Roach <div class="col-sm-9"> 268cc5ab399SGreg Roach <input class="form-control" type="text" id="title" name="title" value="<?= Html::escape($title) ?>"> 26915d603e7SGreg Roach </div> 27015d603e7SGreg Roach </div> 2718c2e8227SGreg Roach 27215d603e7SGreg Roach <div class="row form-group"> 27315d603e7SGreg Roach <label class="col-sm-3 col-form-label" for="template"> 27415d603e7SGreg Roach <?= I18N::translate('Templates') ?> 27515d603e7SGreg Roach </label> 27615d603e7SGreg Roach <div class="col-sm-9"> 277c87f84e3SGreg Roach <?= Bootstrap4::select([$html => I18N::translate('Custom')] + array_flip($templates), '', ['onchange' => 'this.form.html.value=this.options[this.selectedIndex].value; CKEDITOR.instances.html.setData(document.block.html.value);', 'id' => 'template']) ?> 27815d603e7SGreg Roach <p class="small text-muted"> 27915d603e7SGreg Roach <?= 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.') ?> 28015d603e7SGreg Roach </p> 28115d603e7SGreg Roach </div> 28215d603e7SGreg Roach </div> 2838c2e8227SGreg Roach 28415d603e7SGreg Roach <div class="row form-group"> 28515d603e7SGreg Roach <label class="col-sm-3 col-form-label" for="gedcom"> 28615d603e7SGreg Roach <?= I18N::translate('Family tree') ?> 28715d603e7SGreg Roach </label> 28815d603e7SGreg Roach <div class="col-sm-9"> 28915d603e7SGreg Roach <?= Bootstrap4::select(['__current__' => I18N::translate('Current'), '__default__' => I18N::translate('Default')] + Tree::getNameList(), $gedcom, ['id' => 'gedcom', 'name' => 'gedcom']) ?> 29015d603e7SGreg Roach </div> 29115d603e7SGreg Roach </div> 2928c2e8227SGreg Roach 29315d603e7SGreg Roach <div class="row form-group"> 29415d603e7SGreg Roach <label class="col-sm-3 col-form-label" for="html"> 29515d603e7SGreg Roach <?= I18N::translate('Content') ?> 29615d603e7SGreg Roach </label> 29715d603e7SGreg Roach <div class="col-sm-9"> 29815d603e7SGreg Roach <p> 29915d603e7SGreg Roach <?= 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.') ?> 30015d603e7SGreg Roach </p> 30115d603e7SGreg Roach </div> 30215d603e7SGreg Roach </div> 3038c2e8227SGreg Roach 30415d603e7SGreg Roach <div class="row form-group"> 305cc5ab399SGreg Roach <textarea name="html" id="html" class="html-edit" rows="10"><?= Html::escape($html) ?></textarea> 30615d603e7SGreg Roach </div> 3078c2e8227SGreg Roach 30815d603e7SGreg Roach <fieldset class="form-group"> 30915d603e7SGreg Roach <div class="row"> 31015d603e7SGreg Roach <legend class="form-control-legend col-sm-3"> 31115d603e7SGreg Roach <?= I18N::translate('Show the date and time of update') ?> 31215d603e7SGreg Roach </legend> 31315d603e7SGreg Roach <div class="col-sm-9"> 3149c6524dcSGreg Roach <?= Bootstrap4::radioButtons('show_timestamp', FunctionsEdit::optionsNoYes(), $show_timestamp, true) ?> 31515d603e7SGreg Roach </div> 31615d603e7SGreg Roach </div> 31715d603e7SGreg Roach </fieldset> 31815d603e7SGreg Roach 31915d603e7SGreg Roach <fieldset class="form-group"> 32015d603e7SGreg Roach <div class="row"> 32115d603e7SGreg Roach <legend class="form-control-legend col-sm-3"> 32215d603e7SGreg Roach <?= I18N::translate('Show this block for which languages') ?> 32315d603e7SGreg Roach </legend> 32415d603e7SGreg Roach <div class="col-sm-9"> 32515d603e7SGreg Roach <?= FunctionsEdit::editLanguageCheckboxes('lang', $languages) ?> 32615d603e7SGreg Roach </div> 32715d603e7SGreg Roach </div> 32815d603e7SGreg Roach </fieldset> 32915d603e7SGreg Roach 33015d603e7SGreg Roach <?php 3318c2e8227SGreg Roach } 3328c2e8227SGreg Roach} 333