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\I18N; 20use Fisharebest\Webtrees\Media; 21use Fisharebest\Webtrees\View; 22 23/** 24 * Class AlbumModule 25 */ 26class AlbumModule extends AbstractModule implements ModuleTabInterface { 27 /** @var Media[] List of media objects. */ 28 private $media_list; 29 30 /** 31 * How should this module be labelled on tabs, menus, etc.? 32 * 33 * @return string 34 */ 35 public function getTitle() { 36 return /* I18N: Name of a module */ I18N::translate('Album'); 37 } 38 39 /** 40 * A sentence describing what this module does. 41 * 42 * @return string 43 */ 44 public function getDescription() { 45 return /* I18N: Description of the “Album” module */ I18N::translate('An alternative to the “media” tab, and an enhanced image viewer.'); 46 } 47 48 /** 49 * The user can re-arrange the tab order, but until they do, this 50 * is the order in which tabs are shown. 51 * 52 * @return int 53 */ 54 public function defaultTabOrder() { 55 return 60; 56 } 57 58 /** 59 * Is this tab empty? If so, we don't always need to display it. 60 * 61 * @return bool 62 */ 63 public function hasTabContent() { 64 global $WT_TREE; 65 66 return Auth::isEditor($WT_TREE) || $this->getMedia(); 67 } 68 69 /** 70 * A greyed out tab has no actual content, but may perhaps have 71 * options to create content. 72 * 73 * @return bool 74 */ 75 public function isGrayedOut() { 76 return !$this->getMedia(); 77 } 78 79 /** 80 * Generate the HTML content of this tab. 81 * 82 * @return string 83 */ 84 public function getTabContent() { 85 return View::make('tabs/album', [ 86 'media_list' => $this->getMedia() 87 ]); 88 } 89 90 /** 91 * Get all facts containing media links for this person and their spouse-family records 92 * 93 * @return Media[] 94 */ 95 private function getMedia() { 96 global $controller; 97 98 if ($this->media_list === null) { 99 // Use facts from this individual and all their spouses 100 $facts = $controller->record->getFacts(); 101 foreach ($controller->record->getSpouseFamilies() as $family) { 102 foreach ($family->getFacts() as $fact) { 103 $facts[] = $fact; 104 } 105 } 106 // Use all media from each fact 107 $this->media_list = []; 108 foreach ($facts as $fact) { 109 // Don't show pending edits, as the user just sees duplicates 110 if (!$fact->isPendingDeletion()) { 111 preg_match_all('/(?:^1|\n\d) OBJE @(' . WT_REGEX_XREF . ')@/', $fact->getGedcom(), $matches); 112 foreach ($matches[1] as $match) { 113 $media = Media::getInstance($match, $controller->record->getTree()); 114 if ($media && $media->canShow()) { 115 $this->media_list[] = $media; 116 } 117 } 118 } 119 } 120 // If a media object is linked twice, only show it once 121 $this->media_list = array_unique($this->media_list); 122 // Sort these using _WT_OBJE_SORT 123 $wt_obje_sort = []; 124 foreach ($controller->record->getFacts('_WT_OBJE_SORT') as $fact) { 125 $wt_obje_sort[] = trim($fact->getValue(), '@'); 126 } 127 usort($this->media_list, function (Media $x, Media $y) use ($wt_obje_sort) { 128 return array_search($x->getXref(), $wt_obje_sort) - array_search($y->getXref(), $wt_obje_sort); 129 }); 130 } 131 132 return $this->media_list; 133 } 134 135 /** 136 * Can this tab load asynchronously? 137 * 138 * @return bool 139 */ 140 public function canLoadAjax() { 141 return false; 142 } 143 144 /** 145 * Any content (e.g. Javascript) that needs to be rendered before the tabs. 146 * 147 * This function is probably not needed, as there are better ways to achieve this. 148 * 149 * @return string 150 */ 151 public function getPreLoadContent() { 152 return ''; 153 } 154} 155