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\Individual; 21use Fisharebest\Webtrees\Media; 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(Individual $individual) { 64 return $individual->canEdit() || $this->getMedia($individual); 65 } 66 67 /** 68 * A greyed out tab has no actual content, but may perhaps have 69 * options to create content. 70 * 71 * @return bool 72 */ 73 public function isGrayedOut(Individual $individual) { 74 return !$this->getMedia($individual); 75 } 76 77 /** 78 * Generate the HTML content of this tab. 79 * 80 * @param Individual $individual 81 * 82 * @return string 83 */ 84 public function getTabContent(Individual $individual) { 85 return view('tabs/album', [ 86 'media_list' => $this->getMedia($individual) 87 ]); 88 } 89 90 /** 91 * Get all facts containing media links for this person and their spouse-family records 92 * 93 * @param Individual $individual 94 * 95 * @return Media[] 96 */ 97 private function getMedia(Individual $individual) { 98 if ($this->media_list === null) { 99 // Use facts from this individual and all their spouses 100 $facts = $individual->getFacts(); 101 foreach ($individual->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, $individual->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 ($individual->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