xref: /webtrees/app/Module/AlbumModule.php (revision a091ac74647eab281b25090b737835eeea14ae10)
18c2e8227SGreg Roach<?php
23976b470SGreg Roach
38c2e8227SGreg Roach/**
48c2e8227SGreg Roach * webtrees: online genealogy
5*a091ac74SGreg Roach * Copyright (C) 2020 webtrees development team
68c2e8227SGreg Roach * This program is free software: you can redistribute it and/or modify
78c2e8227SGreg Roach * it under the terms of the GNU General Public License as published by
88c2e8227SGreg Roach * the Free Software Foundation, either version 3 of the License, or
98c2e8227SGreg Roach * (at your option) any later version.
108c2e8227SGreg Roach * This program is distributed in the hope that it will be useful,
118c2e8227SGreg Roach * but WITHOUT ANY WARRANTY; without even the implied warranty of
128c2e8227SGreg Roach * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
138c2e8227SGreg Roach * GNU General Public License for more details.
148c2e8227SGreg Roach * You should have received a copy of the GNU General Public License
158c2e8227SGreg Roach * along with this program. If not, see <http://www.gnu.org/licenses/>.
168c2e8227SGreg Roach */
17fcfa147eSGreg Roach
18e7f56f2aSGreg Roachdeclare(strict_types=1);
19e7f56f2aSGreg Roach
2076692c8bSGreg Roachnamespace Fisharebest\Webtrees\Module;
2176692c8bSGreg Roach
22*a091ac74SGreg Roachuse Fisharebest\Webtrees\Factory;
238d0ebef0SGreg Roachuse Fisharebest\Webtrees\Gedcom;
240e62c4b8SGreg Roachuse Fisharebest\Webtrees\I18N;
25225e381fSGreg Roachuse Fisharebest\Webtrees\Individual;
260e62c4b8SGreg Roachuse Fisharebest\Webtrees\Media;
278c2e8227SGreg Roach
288c2e8227SGreg Roach/**
298c2e8227SGreg Roach * Class AlbumModule
308c2e8227SGreg Roach */
3137eb8894SGreg Roachclass AlbumModule extends AbstractModule implements ModuleTabInterface
32c1010edaSGreg Roach{
3349a243cbSGreg Roach    use ModuleTabTrait;
3449a243cbSGreg Roach
3576692c8bSGreg Roach    /** @var Media[] List of media objects. */
368c2e8227SGreg Roach    private $media_list;
378c2e8227SGreg Roach
3876692c8bSGreg Roach    /**
390cfd6963SGreg Roach     * How should this module be identified in the control panel, etc.?
4076692c8bSGreg Roach     *
4176692c8bSGreg Roach     * @return string
4276692c8bSGreg Roach     */
4349a243cbSGreg Roach    public function title(): string
44c1010edaSGreg Roach    {
45bbb76c12SGreg Roach        /* I18N: Name of a module */
46bbb76c12SGreg Roach        return I18N::translate('Album');
478c2e8227SGreg Roach    }
488c2e8227SGreg Roach
4976692c8bSGreg Roach    /**
5076692c8bSGreg Roach     * A sentence describing what this module does.
5176692c8bSGreg Roach     *
5276692c8bSGreg Roach     * @return string
5376692c8bSGreg Roach     */
5449a243cbSGreg Roach    public function description(): string
55c1010edaSGreg Roach    {
56bbb76c12SGreg Roach        /* I18N: Description of the “Album” module */
57bbb76c12SGreg Roach        return I18N::translate('An alternative to the “media” tab, and an enhanced image viewer.');
588c2e8227SGreg Roach    }
598c2e8227SGreg Roach
6076692c8bSGreg Roach    /**
6149a243cbSGreg Roach     * The default position for this tab.  It can be changed in the control panel.
6276692c8bSGreg Roach     *
6376692c8bSGreg Roach     * @return int
6476692c8bSGreg Roach     */
65cbf4b7faSGreg Roach    public function defaultTabOrder(): int
66cbf4b7faSGreg Roach    {
67fb7a0427SGreg Roach        return 6;
688c2e8227SGreg Roach    }
698c2e8227SGreg Roach
7076692c8bSGreg Roach    /**
7176692c8bSGreg Roach     * Is this tab empty? If so, we don't always need to display it.
7276692c8bSGreg Roach     *
73f9f36b89SGreg Roach     * @param Individual $individual
74f9f36b89SGreg Roach     *
7576692c8bSGreg Roach     * @return bool
7676692c8bSGreg Roach     */
778f53f488SRico Sonntag    public function hasTabContent(Individual $individual): bool
78c1010edaSGreg Roach    {
79225e381fSGreg Roach        return $individual->canEdit() || $this->getMedia($individual);
808c2e8227SGreg Roach    }
818c2e8227SGreg Roach
8276692c8bSGreg Roach    /**
8376692c8bSGreg Roach     * A greyed out tab has no actual content, but may perhaps have
8476692c8bSGreg Roach     * options to create content.
8576692c8bSGreg Roach     *
86f9f36b89SGreg Roach     * @param Individual $individual
87f9f36b89SGreg Roach     *
8876692c8bSGreg Roach     * @return bool
8976692c8bSGreg Roach     */
908f53f488SRico Sonntag    public function isGrayedOut(Individual $individual): bool
91c1010edaSGreg Roach    {
92225e381fSGreg Roach        return !$this->getMedia($individual);
938c2e8227SGreg Roach    }
948c2e8227SGreg Roach
9576692c8bSGreg Roach    /**
9676692c8bSGreg Roach     * Generate the HTML content of this tab.
9776692c8bSGreg Roach     *
98225e381fSGreg Roach     * @param Individual $individual
99225e381fSGreg Roach     *
10076692c8bSGreg Roach     * @return string
10176692c8bSGreg Roach     */
1028f53f488SRico Sonntag    public function getTabContent(Individual $individual): string
103c1010edaSGreg Roach    {
104a8cd57e1SGreg Roach        return view('modules/lightbox/tab', [
105c1010edaSGreg Roach            'media_list' => $this->getMedia($individual),
106d14df12bSGreg Roach        ]);
1078c2e8227SGreg Roach    }
1088c2e8227SGreg Roach
1098c2e8227SGreg Roach    /**
1108c2e8227SGreg Roach     * Get all facts containing media links for this person and their spouse-family records
1118c2e8227SGreg Roach     *
112225e381fSGreg Roach     * @param Individual $individual
113225e381fSGreg Roach     *
1148c2e8227SGreg Roach     * @return Media[]
1158c2e8227SGreg Roach     */
1168f53f488SRico Sonntag    private function getMedia(Individual $individual): array
117c1010edaSGreg Roach    {
1188c2e8227SGreg Roach        if ($this->media_list === null) {
1198c2e8227SGreg Roach            // Use facts from this individual and all their spouses
12030158ae7SGreg Roach            $facts = $individual->facts();
12139ca88baSGreg Roach            foreach ($individual->spouseFamilies() as $family) {
12230158ae7SGreg Roach                foreach ($family->facts() as $fact) {
12339ca88baSGreg Roach                    $facts->push($fact);
1248c2e8227SGreg Roach                }
1258c2e8227SGreg Roach            }
1268c2e8227SGreg Roach            // Use all media from each fact
12713abd6f3SGreg Roach            $this->media_list = [];
1288c2e8227SGreg Roach            foreach ($facts as $fact) {
1298c2e8227SGreg Roach                // Don't show pending edits, as the user just sees duplicates
1308c2e8227SGreg Roach                if (!$fact->isPendingDeletion()) {
1318d0ebef0SGreg Roach                    preg_match_all('/(?:^1|\n\d) OBJE @(' . Gedcom::REGEX_XREF . ')@/', $fact->gedcom(), $matches);
1328c2e8227SGreg Roach                    foreach ($matches[1] as $match) {
133*a091ac74SGreg Roach                        $media = Factory::media()->make($match, $individual->tree());
1348c2e8227SGreg Roach                        if ($media && $media->canShow()) {
1358c2e8227SGreg Roach                            $this->media_list[] = $media;
1368c2e8227SGreg Roach                        }
1378c2e8227SGreg Roach                    }
1388c2e8227SGreg Roach                }
1398c2e8227SGreg Roach            }
1408c2e8227SGreg Roach            // If a media object is linked twice, only show it once
1418c2e8227SGreg Roach            $this->media_list = array_unique($this->media_list);
1428c2e8227SGreg Roach            // Sort these using _WT_OBJE_SORT
14313abd6f3SGreg Roach            $wt_obje_sort = [];
1448d0ebef0SGreg Roach            foreach ($individual->facts(['_WT_OBJE_SORT']) as $fact) {
14584586c02SGreg Roach                $wt_obje_sort[] = trim($fact->value(), '@');
1468c2e8227SGreg Roach            }
1470b5fd0a6SGreg Roach            usort($this->media_list, static function (Media $x, Media $y) use ($wt_obje_sort): int {
14822d65e5aSGreg Roach                return array_search($x->xref(), $wt_obje_sort, true) - array_search($y->xref(), $wt_obje_sort, true);
1498c2e8227SGreg Roach            });
1508c2e8227SGreg Roach        }
151cbc1590aSGreg Roach
1528c2e8227SGreg Roach        return $this->media_list;
1538c2e8227SGreg Roach    }
1548c2e8227SGreg Roach
15576692c8bSGreg Roach    /**
15676692c8bSGreg Roach     * Can this tab load asynchronously?
15776692c8bSGreg Roach     *
15876692c8bSGreg Roach     * @return bool
15976692c8bSGreg Roach     */
1608f53f488SRico Sonntag    public function canLoadAjax(): bool
161c1010edaSGreg Roach    {
16215d603e7SGreg Roach        return false;
1638c2e8227SGreg Roach    }
1648c2e8227SGreg Roach}
165