xref: /webtrees/app/Media.php (revision ecf66805cdf435857ce4ed0eb577cfd1296f8989)
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