xref: /webtrees/app/Module/AlbumModule.php (revision d2681c37325a35ab01be82034f4afd3b58010fb8)
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	 * @return bool
61	 */
62	public function hasTabContent(Individual $individual) {
63		return $individual->canEdit() || $this->getMedia($individual);
64	}
65
66	/**
67	 * A greyed out tab has no actual content, but may perhaps have
68	 * options to create content.
69	 *
70	 * @return bool
71	 */
72	public function isGrayedOut(Individual $individual) {
73		return !$this->getMedia($individual);
74	}
75
76	/**
77	 * Generate the HTML content of this tab.
78	 *
79	 * @param Individual $individual
80	 *
81	 * @return string
82	 */
83	public function getTabContent(Individual $individual) {
84		return view('tabs/album', [
85			'media_list' => $this->getMedia($individual)
86		]);
87	}
88
89	/**
90	 * Get all facts containing media links for this person and their spouse-family records
91	 *
92	 * @param Individual $individual
93	 *
94	 * @return Media[]
95	 */
96	private function getMedia(Individual $individual) {
97		if ($this->media_list === null) {
98			// Use facts from this individual and all their spouses
99			$facts = $individual->getFacts();
100			foreach ($individual->getSpouseFamilies() as $family) {
101				foreach ($family->getFacts() as $fact) {
102					$facts[] = $fact;
103				}
104			}
105			// Use all media from each fact
106			$this->media_list = [];
107			foreach ($facts as $fact) {
108				// Don't show pending edits, as the user just sees duplicates
109				if (!$fact->isPendingDeletion()) {
110					preg_match_all('/(?:^1|\n\d) OBJE @(' . WT_REGEX_XREF . ')@/', $fact->getGedcom(), $matches);
111					foreach ($matches[1] as $match) {
112						$media = Media::getInstance($match, $individual->getTree());
113						if ($media && $media->canShow()) {
114							$this->media_list[] = $media;
115						}
116					}
117				}
118			}
119			// If a media object is linked twice, only show it once
120			$this->media_list = array_unique($this->media_list);
121			// Sort these using _WT_OBJE_SORT
122			$wt_obje_sort = [];
123			foreach ($individual->getFacts('_WT_OBJE_SORT') as $fact) {
124				$wt_obje_sort[] = trim($fact->getValue(), '@');
125			}
126			usort($this->media_list, function (Media $x, Media $y) use ($wt_obje_sort) {
127				return array_search($x->getXref(), $wt_obje_sort) - array_search($y->getXref(), $wt_obje_sort);
128			});
129		}
130
131		return $this->media_list;
132	}
133
134	/**
135	 * Can this tab load asynchronously?
136	 *
137	 * @return bool
138	 */
139	public function canLoadAjax() {
140		return false;
141	}
142}
143