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; 17 18use Fisharebest\Webtrees\Functions\FunctionsPrintFacts; 19 20/** 21 * A GEDCOM media (OBJE) object. 22 */ 23class Media extends GedcomRecord { 24 const RECORD_TYPE = 'OBJE'; 25 const URL_PREFIX = 'mediaviewer.php?mid='; 26 27 /** 28 * Each object type may have its own special rules, and re-implement this function. 29 * 30 * @param int $access_level 31 * 32 * @return bool 33 */ 34 protected function canShowByType($access_level) { 35 // Hide media objects if they are attached to private records 36 $linked_ids = Database::prepare( 37 "SELECT l_from FROM `##link` WHERE l_to = ? AND l_file = ?" 38 )->execute([ 39 $this->xref, $this->tree->getTreeId(), 40 ])->fetchOneColumn(); 41 foreach ($linked_ids as $linked_id) { 42 $linked_record = GedcomRecord::getInstance($linked_id, $this->tree); 43 if ($linked_record && !$linked_record->canShow($access_level)) { 44 return false; 45 } 46 } 47 48 // ... otherwise apply default behaviour 49 return parent::canShowByType($access_level); 50 } 51 52 /** 53 * Fetch data from the database 54 * 55 * @param string $xref 56 * @param int $tree_id 57 * 58 * @return null|string 59 */ 60 protected static function fetchGedcomRecord($xref, $tree_id) { 61 return Database::prepare( 62 "SELECT m_gedcom FROM `##media` WHERE m_id = :xref AND m_file = :tree_id" 63 )->execute([ 64 'xref' => $xref, 65 'tree_id' => $tree_id, 66 ])->fetchOne(); 67 } 68 69 /** 70 * Get the media files for this media object 71 * 72 * @return MediaFile[] 73 */ 74 public function mediaFiles(): array { 75 $media_files = []; 76 77 foreach ($this->getFacts('FILE') as $fact) { 78 $media_files[] = new MediaFile($fact->getGedcom(), $this); 79 } 80 81 return $media_files; 82 } 83 84 /** 85 * Get the first media file that contains an image. 86 * 87 * @return MediaFile|null 88 */ 89 public function firstImageFile() { 90 foreach ($this->mediaFiles() as $media_file) { 91 if ($media_file->isImage()) { 92 return $media_file; 93 } 94 } 95 96 return null; 97 } 98 99 /** 100 * Get the first note attached to this media object 101 * 102 * @return null|string 103 */ 104 public function getNote() { 105 $note = $this->getFirstFact('NOTE'); 106 if ($note) { 107 $text = $note->getValue(); 108 if (preg_match('/^@' . WT_REGEX_XREF . '@$/', $text)) { 109 $text = $note->getTarget()->getNote(); 110 } 111 112 return $text; 113 } else { 114 return ''; 115 } 116 } 117 118 /** 119 * Extract names from the GEDCOM record. 120 */ 121 public function extractNames() { 122 $names = []; 123 foreach ($this->mediaFiles() as $media_file) { 124 $names[] = $media_file->title(); 125 } 126 foreach ($this->mediaFiles() as $media_file) { 127 $names[] = $media_file->filename(); 128 } 129 $names = array_filter(array_unique($names)); 130 131 if (empty($names)) { 132 $names[] = $this->getFallBackName(); 133 } 134 135 foreach ($names as $name) { 136 $this->addName(static::RECORD_TYPE, $name, null); 137 } 138 } 139 140 /** 141 * This function should be redefined in derived classes to show any major 142 * identifying characteristics of this record. 143 * 144 * @return string 145 */ 146 public function formatListDetails() { 147 ob_start(); 148 FunctionsPrintFacts::printMediaLinks('1 OBJE @' . $this->getXref() . '@', 1); 149 150 return ob_get_clean(); 151 } 152 153 /** 154 * Display an image-thumbnail or a media-icon, and add markup for image viewers such as colorbox. 155 * 156 * @param int $width Pixels 157 * @param int $height Pixels 158 * @param string $fit "crop" or "contain" 159 * @param string[] $attributes Additional HTML attributes 160 * 161 * @return string 162 */ 163 public function displayImage($width, $height, $fit, $attributes = []) { 164 // Display the first image 165 foreach ($this->mediaFiles() as $media_file) { 166 if ($media_file->isImage()) { 167 return $media_file->displayImage($width, $height, $fit, $attributes); 168 } 169 } 170 171 // Display the first file of any type 172 foreach ($this->mediaFiles() as $media_file) { 173 return $media_file->displayImage($width, $height, $fit, $attributes); 174 } 175 176 // No image? 177 return ''; 178 } 179} 180