1<?php 2namespace Fisharebest\Webtrees; 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 */ 18 19/** 20 * Class SlideShowModule 21 */ 22class SlideShowModule extends AbstractModule implements ModuleBlockInterface { 23 /** {@inheritdoc} */ 24 public function getTitle() { 25 return /* I18N: Name of a module */ I18N::translate('Slide show'); 26 } 27 28 /** {@inheritdoc} */ 29 public function getDescription() { 30 return /* I18N: Description of the “Slide show” module */ I18N::translate('Random images from the current family tree.'); 31 } 32 33 /** {@inheritdoc} */ 34 public function getBlock($block_id, $template = true, $cfg = null) { 35 global $ctype, $WT_TREE; 36 37 $filter = $this->getBlockSetting($block_id, 'filter', 'all'); 38 $controls = $this->getBlockSetting($block_id, 'controls', '1'); 39 $start = $this->getBlockSetting($block_id, 'start', '0') || Filter::getBool('start'); 40 41 // We can apply the filters using SQL 42 // Do not use "ORDER BY RAND()" - it is very slow on large tables. Use PHP::array_rand() instead. 43 $all_media = Database::prepare( 44 "SELECT m_id FROM `##media`" . 45 " WHERE m_file = ?" . 46 " AND m_ext IN (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, '')" . 47 " AND m_type IN (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, '')" 48 )->execute(array( 49 $WT_TREE->getTreeId(), 50 $this->getBlockSetting($block_id, 'filter_avi', '0') ? 'avi' : null, 51 $this->getBlockSetting($block_id, 'filter_bmp', '1') ? 'bmp' : null, 52 $this->getBlockSetting($block_id, 'filter_gif', '1') ? 'gif' : null, 53 $this->getBlockSetting($block_id, 'filter_jpeg', '1') ? 'jpg' : null, 54 $this->getBlockSetting($block_id, 'filter_jpeg', '1') ? 'jpeg' : null, 55 $this->getBlockSetting($block_id, 'filter_mp3', '0') ? 'mp3' : null, 56 $this->getBlockSetting($block_id, 'filter_ole', '1') ? 'ole' : null, 57 $this->getBlockSetting($block_id, 'filter_pcx', '1') ? 'pcx' : null, 58 $this->getBlockSetting($block_id, 'filter_pdf', '0') ? 'pdf' : null, 59 $this->getBlockSetting($block_id, 'filter_png', '1') ? 'png' : null, 60 $this->getBlockSetting($block_id, 'filter_tiff', '1') ? 'tiff' : null, 61 $this->getBlockSetting($block_id, 'filter_wav', '0') ? 'wav' : null, 62 $this->getBlockSetting($block_id, 'filter_audio', '0') ? 'audio' : null, 63 $this->getBlockSetting($block_id, 'filter_book', '1') ? 'book' : null, 64 $this->getBlockSetting($block_id, 'filter_card', '1') ? 'card' : null, 65 $this->getBlockSetting($block_id, 'filter_certificate', '1') ? 'certificate' : null, 66 $this->getBlockSetting($block_id, 'filter_coat', '1') ? 'coat' : null, 67 $this->getBlockSetting($block_id, 'filter_document', '1') ? 'document' : null, 68 $this->getBlockSetting($block_id, 'filter_electronic', '1') ? 'electronic' : null, 69 $this->getBlockSetting($block_id, 'filter_fiche', '1') ? 'fiche' : null, 70 $this->getBlockSetting($block_id, 'filter_film', '1') ? 'film' : null, 71 $this->getBlockSetting($block_id, 'filter_magazine', '1') ? 'magazine' : null, 72 $this->getBlockSetting($block_id, 'filter_manuscript', '1') ? 'manuscript' : null, 73 $this->getBlockSetting($block_id, 'filter_map', '1') ? 'map' : null, 74 $this->getBlockSetting($block_id, 'filter_newspaper', '1') ? 'newspaper' : null, 75 $this->getBlockSetting($block_id, 'filter_other', '1') ? 'other' : null, 76 $this->getBlockSetting($block_id, 'filter_painting', '1') ? 'painting' : null, 77 $this->getBlockSetting($block_id, 'filter_photo', '1') ? 'photo' : null, 78 $this->getBlockSetting($block_id, 'filter_tombstone', '1') ? 'tombstone' : null, 79 $this->getBlockSetting($block_id, 'filter_video', '0') ? 'video' : null, 80 ))->fetchOneColumn(); 81 82 // Keep looking through the media until a suitable one is found. 83 $random_media = null; 84 while ($all_media) { 85 $n = array_rand($all_media); 86 $media = Media::getInstance($all_media[$n], $WT_TREE); 87 if ($media->canShow() && !$media->isExternal()) { 88 // Check if it is linked to a suitable individual 89 foreach ($media->linkedIndividuals('OBJE') as $indi) { 90 if ( 91 $filter === 'all' || 92 $filter === 'indi' && strpos($indi->getGedcom(), "\n1 OBJE @" . $media->getXref() . '@') !== false || 93 $filter === 'event' && strpos($indi->getGedcom(), "\n2 OBJE @" . $media->getXref() . '@') !== false 94 ) { 95 // Found one :-) 96 $random_media = $media; 97 break 2; 98 } 99 } 100 } 101 unset($all_media[$n]); 102 }; 103 104 $id = $this->getName() . $block_id; 105 $class = $this->getName() . '_block'; 106 if ($ctype === 'gedcom' && Auth::isManager($WT_TREE) || $ctype === 'user' && Auth::check()) { 107 $title = '<a class="icon-admin" title="' . I18N::translate('Configure') . '" href="block_edit.php?block_id=' . $block_id . '&ged=' . $WT_TREE->getNameHtml() . '&ctype=' . $ctype . '"></a>'; 108 } else { 109 $title = ''; 110 } 111 $title .= $this->getTitle(); 112 113 if ($random_media) { 114 $content = "<div id=\"random_picture_container$block_id\">"; 115 if ($controls) { 116 if ($start) { 117 $icon_class = 'icon-media-stop'; 118 } else { 119 $icon_class = 'icon-media-play'; 120 } 121 $content .= '<div dir="ltr" class="center" id="random_picture_controls' . $block_id . '"><br>'; 122 $content .= "<a href=\"#\" onclick=\"togglePlay(); return false;\" id=\"play_stop\" class=\"" . $icon_class . "\" title=\"" . I18N::translate('Play') . "/" . I18N::translate('Stop') . '"></a>'; 123 $content .= '<a href="#" onclick="jQuery(\'#block_' . $block_id . '\').load(\'index.php?ctype=' . $ctype . '&action=ajax&block_id=' . $block_id . '\');return false;" title="' . I18N::translate('Next image') . '" class="icon-media-next"></a>'; 124 $content .= '</div><script> 125 var play = false; 126 function togglePlay() { 127 if (play) { 128 play = false; 129 jQuery("#play_stop").removeClass("icon-media-stop").addClass("icon-media-play"); 130 } 131 else { 132 play = true; 133 playSlideShow(); 134 jQuery("#play_stop").removeClass("icon-media-play").addClass("icon-media-stop"); 135 } 136 } 137 138 function playSlideShow() { 139 if (play) { 140 window.setTimeout("reload_image()", 6000); 141 } 142 } 143 function reload_image() { 144 if (play) { 145 jQuery("#block_'.$block_id . '").load("index.php?ctype=' . $ctype . '&action=ajax&block_id=' . $block_id . '&start=1"); 146 } 147 } 148 </script>'; 149 } 150 if ($start) { 151 $content .= '<script>togglePlay();</script>'; 152 } 153 $content .= '<div class="center" id="random_picture_content' . $block_id . '">'; 154 $content .= '<table id="random_picture_box"><tr><td class="details1">'; 155 $content .= $random_media->displayImage(); 156 157 $content .= '<br>'; 158 $content .= '<a href="' . $random_media->getHtmlUrl() . '"><b>' . $random_media->getFullName() . '</b></a><br>'; 159 foreach ($random_media->linkedIndividuals('OBJE') as $individual) { 160 $content .= '<a href="' . $individual->getHtmlUrl() . '">' . I18N::translate('View individual') . ' — ' . $individual->getFullname() . '</a><br>'; 161 } 162 foreach ($random_media->linkedFamilies('OBJE') as $family) { 163 $content .= '<a href="' . $family->getHtmlUrl() . '">' . I18N::translate('View family') . ' — ' . $family->getFullname() . '</a><br>'; 164 } 165 foreach ($random_media->linkedSources('OBJE') as $source) { 166 $content .= '<a href="' . $source->getHtmlUrl() . '">' . I18N::translate('View source') . ' — ' . $source->getFullname() . '</a><br>'; 167 } 168 $content .= '<br><div class="indent">'; 169 $content .= print_fact_notes($random_media->getGedcom(), "1", false); 170 $content .= '</div>'; 171 $content .= '</td></tr></table>'; 172 $content .= '</div>'; // random_picture_content 173 $content .= '</div>'; // random_picture_container 174 } else { 175 $content = I18N::translate('This family tree has no images to display.'); 176 } 177 if ($template) { 178 return Theme::theme()->formatBlock($id, $title, $class, $content); 179 } else { 180 return $content; 181 } 182 } 183 184 /** {@inheritdoc} */ 185 public function loadAjax() { 186 return true; 187 } 188 189 /** {@inheritdoc} */ 190 public function isUserBlock() { 191 return true; 192 } 193 194 /** {@inheritdoc} */ 195 public function isGedcomBlock() { 196 return true; 197 } 198 199 /** {@inheritdoc} */ 200 public function configureBlock($block_id) { 201 if (Filter::postBool('save') && Filter::checkCsrf()) { 202 $this->setBlockSetting($block_id, 'filter', Filter::post('filter', 'indi|event|all', 'all')); 203 $this->setBlockSetting($block_id, 'controls', Filter::postBool('controls')); 204 $this->setBlockSetting($block_id, 'start', Filter::postBool('start')); 205 $this->setBlockSetting($block_id, 'filter_avi', Filter::postBool('filter_avi')); 206 $this->setBlockSetting($block_id, 'filter_bmp', Filter::postBool('filter_bmp')); 207 $this->setBlockSetting($block_id, 'filter_gif', Filter::postBool('filter_gif')); 208 $this->setBlockSetting($block_id, 'filter_jpeg', Filter::postBool('filter_jpeg')); 209 $this->setBlockSetting($block_id, 'filter_mp3', Filter::postBool('filter_mp3')); 210 $this->setBlockSetting($block_id, 'filter_ole', Filter::postBool('filter_ole')); 211 $this->setBlockSetting($block_id, 'filter_pcx', Filter::postBool('filter_pcx')); 212 $this->setBlockSetting($block_id, 'filter_pdf', Filter::postBool('filter_pdf')); 213 $this->setBlockSetting($block_id, 'filter_png', Filter::postBool('filter_png')); 214 $this->setBlockSetting($block_id, 'filter_tiff', Filter::postBool('filter_tiff')); 215 $this->setBlockSetting($block_id, 'filter_wav', Filter::postBool('filter_wav')); 216 $this->setBlockSetting($block_id, 'filter_audio', Filter::postBool('filter_audio')); 217 $this->setBlockSetting($block_id, 'filter_book', Filter::postBool('filter_book')); 218 $this->setBlockSetting($block_id, 'filter_card', Filter::postBool('filter_card')); 219 $this->setBlockSetting($block_id, 'filter_certificate', Filter::postBool('filter_certificate')); 220 $this->setBlockSetting($block_id, 'filter_coat', Filter::postBool('filter_coat')); 221 $this->setBlockSetting($block_id, 'filter_document', Filter::postBool('filter_document')); 222 $this->setBlockSetting($block_id, 'filter_electronic', Filter::postBool('filter_electronic')); 223 $this->setBlockSetting($block_id, 'filter_fiche', Filter::postBool('filter_fiche')); 224 $this->setBlockSetting($block_id, 'filter_film', Filter::postBool('filter_film')); 225 $this->setBlockSetting($block_id, 'filter_magazine', Filter::postBool('filter_magazine')); 226 $this->setBlockSetting($block_id, 'filter_manuscript', Filter::postBool('filter_manuscript')); 227 $this->setBlockSetting($block_id, 'filter_map', Filter::postBool('filter_map')); 228 $this->setBlockSetting($block_id, 'filter_newspaper', Filter::postBool('filter_newspaper')); 229 $this->setBlockSetting($block_id, 'filter_other', Filter::postBool('filter_other')); 230 $this->setBlockSetting($block_id, 'filter_painting', Filter::postBool('filter_painting')); 231 $this->setBlockSetting($block_id, 'filter_photo', Filter::postBool('filter_photo')); 232 $this->setBlockSetting($block_id, 'filter_tombstone', Filter::postBool('filter_tombstone')); 233 $this->setBlockSetting($block_id, 'filter_video', Filter::postBool('filter_video')); 234 } 235 236 $filter = $this->getBlockSetting($block_id, 'filter', 'all'); 237 $controls = $this->getBlockSetting($block_id, 'controls', '1'); 238 $start = $this->getBlockSetting($block_id, 'start', '0') || Filter::getBool('start'); 239 240 echo '<tr><td class="descriptionbox wrap width33">'; 241 echo I18N::translate('Show only individuals, events, or all?'); 242 echo '</td><td class="optionbox">'; 243 echo select_edit_control('filter', array('indi'=> I18N::translate('Individuals'), 'event'=> I18N::translate('Facts and events'), 'all'=> I18N::translate('All')), null, $filter, ''); 244 echo '</td></tr>'; 245 246 $filters = array( 247 'avi' =>$this->getBlockSetting($block_id, 'filter_avi', '0'), 248 'bmp' =>$this->getBlockSetting($block_id, 'filter_bmp', '1'), 249 'gif' =>$this->getBlockSetting($block_id, 'filter_gif', '1'), 250 'jpeg' =>$this->getBlockSetting($block_id, 'filter_jpeg', '1'), 251 'mp3' =>$this->getBlockSetting($block_id, 'filter_mp3', '0'), 252 'ole' =>$this->getBlockSetting($block_id, 'filter_ole', '1'), 253 'pcx' =>$this->getBlockSetting($block_id, 'filter_pcx', '1'), 254 'pdf' =>$this->getBlockSetting($block_id, 'filter_pdf', '0'), 255 'png' =>$this->getBlockSetting($block_id, 'filter_png', '1'), 256 'tiff' =>$this->getBlockSetting($block_id, 'filter_tiff', '1'), 257 'wav' =>$this->getBlockSetting($block_id, 'filter_wav', '0'), 258 'audio' =>$this->getBlockSetting($block_id, 'filter_audio', '0'), 259 'book' =>$this->getBlockSetting($block_id, 'filter_book', '1'), 260 'card' =>$this->getBlockSetting($block_id, 'filter_card', '1'), 261 'certificate'=>$this->getBlockSetting($block_id, 'filter_certificate', '1'), 262 'coat' =>$this->getBlockSetting($block_id, 'filter_coat', '1'), 263 'document' =>$this->getBlockSetting($block_id, 'filter_document', '1'), 264 'electronic' =>$this->getBlockSetting($block_id, 'filter_electronic', '1'), 265 'fiche' =>$this->getBlockSetting($block_id, 'filter_fiche', '1'), 266 'film' =>$this->getBlockSetting($block_id, 'filter_film', '1'), 267 'magazine' =>$this->getBlockSetting($block_id, 'filter_magazine', '1'), 268 'manuscript' =>$this->getBlockSetting($block_id, 'filter_manuscript', '1'), 269 'map' =>$this->getBlockSetting($block_id, 'filter_map', '1'), 270 'newspaper' =>$this->getBlockSetting($block_id, 'filter_newspaper', '1'), 271 'other' =>$this->getBlockSetting($block_id, 'filter_other', '1'), 272 'painting' =>$this->getBlockSetting($block_id, 'filter_painting', '1'), 273 'photo' =>$this->getBlockSetting($block_id, 'filter_photo', '1'), 274 'tombstone' =>$this->getBlockSetting($block_id, 'filter_tombstone', '1'), 275 'video' =>$this->getBlockSetting($block_id, 'filter_video', '0'), 276 ); 277 278 echo '<tr><td class="descriptionbox wrap width33">'; 279 echo I18N::translate('Filter'); 280 ?> 281 </td> 282 <td class="optionbox"> 283 <center><b><?php echo GedcomTag::getLabel('FORM'); ?></b></center> 284 <table class="width100"> 285 <tr> 286 <td class="width33"> 287 <label> 288 <input type="checkbox" value="yes" name="filter_avi" <?php echo $filters['avi'] ? 'checked' : ''; ?>> 289 avi 290 </td> 291 <td class="width33"> 292 <label> 293 <input type="checkbox" value="yes" name="filter_bmp" <?php echo $filters['bmp'] ? 'checked' : ''; ?>> 294 bmp 295 </label> 296 </td> 297 <td class="width33"> 298 <label> 299 <input type="checkbox" value="yes" name="filter_gif" <?php echo $filters['gif'] ? 'checked' : ''; ?>> 300 gif 301 </label> 302 </td> 303 </tr> 304 <tr> 305 <td class="width33"> 306 <label> 307 <input type="checkbox" value="yes" name="filter_jpeg" <?php echo $filters['jpeg'] ? 'checked' : ''; ?>> 308 jpeg 309 </label> 310 </td> 311 <td class="width33"> 312 <label> 313 <input type="checkbox" value="yes" name="filter_mp3" <?php echo $filters['mp3'] ? 'checked' : ''; ?>> 314 mp3 315 </label> 316 </td> 317 <td class="width33"> 318 <label> 319 <input type="checkbox" value="yes" name="filter_ole" <?php echo $filters['ole'] ? 'checked' : ''; ?>> 320 ole 321 </label> 322 </td> 323 </tr> 324 <tr> 325 <td class="width33"> 326 <label> 327 <input type="checkbox" value="yes" name="filter_pcx" <?php echo $filters['pcx'] ? 'checked' : ''; ?>> 328 pcx 329 </label> 330 </td> 331 <td class="width33"> 332 <label> 333 <input type="checkbox" value="yes" name="filter_pdf" <?php echo $filters['pdf'] ? 'checked' : ''; ?>> 334 pdf 335 </label> 336 </td> 337 <td class="width33"> 338 <label> 339 <input type="checkbox" value="yes" name="filter_png" <?php echo $filters['png'] ? 'checked' : ''; ?>> 340 png 341 </label> 342 </td> 343 </tr> 344 <tr> 345 <td class="width33"> 346 <label> 347 <input type="checkbox" value="yes" name="filter_tiff" <?php echo $filters['tiff'] ? 'checked' : ''; ?>> 348 tiff 349 </label> 350 </td> 351 <td class="width33"> 352 <label> 353 <input type="checkbox" value="yes" name="filter_wav" <?php echo $filters['wav'] ? 'checked' : ''; ?>> 354 wav 355 </label> 356 </td> 357 <td class="width33"></td> 358 <td class="width33"></td> 359 </tr> 360 </table> 361 <br> 362 <center><b><?php echo GedcomTag::getLabel('TYPE'); ?></b></center> 363 <table class="width100"> 364 <tr> 365 <?php 366 //-- Build the list of checkboxes 367 $i = 0; 368 foreach (GedcomTag::getFileFormTypes() as $typeName => $typeValue) { 369 $i++; 370 if ($i > 3) { 371 $i = 1; 372 echo '</tr><tr>'; 373 } 374 echo '<td class="width33"><label><input type="checkbox" value="yes" name="filter_' . $typeName . '" '; 375 echo $filters[$typeName] ? 'checked' : ''; 376 echo '> ' . $typeValue . '</label></td>'; 377 } 378 ?> 379 </tr> 380 </table> 381 </td> 382 </tr> 383 384 <?php 385 386 echo '<tr><td class="descriptionbox wrap width33">'; 387 echo I18N::translate('Show slide show controls?'); 388 echo '</td><td class="optionbox">'; 389 echo edit_field_yes_no('controls', $controls); 390 echo '</td></tr>'; 391 392 echo '<tr><td class="descriptionbox wrap width33">'; 393 echo I18N::translate('Start slide show on page load?'); 394 echo '</td><td class="optionbox">'; 395 echo edit_field_yes_no('start', $start); 396 echo '</td></tr>'; 397 } 398} 399