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 . '&ged=' . $WT_TREE->getNameHtml() . '&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&surname_sublist=yes&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