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