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