xref: /webtrees/app/Module/IndividualFactsTabModule.php (revision 7413816e6dd2d50e569034fb804f3dce7471bb94)
13763c3f2SGreg Roach<?php
23976b470SGreg Roach
33763c3f2SGreg Roach/**
43763c3f2SGreg Roach * webtrees: online genealogy
5*d11be702SGreg Roach * Copyright (C) 2023 webtrees development team
63763c3f2SGreg Roach * This program is free software: you can redistribute it and/or modify
73763c3f2SGreg Roach * it under the terms of the GNU General Public License as published by
83763c3f2SGreg Roach * the Free Software Foundation, either version 3 of the License, or
93763c3f2SGreg Roach * (at your option) any later version.
103763c3f2SGreg Roach * This program is distributed in the hope that it will be useful,
113763c3f2SGreg Roach * but WITHOUT ANY WARRANTY; without even the implied warranty of
123763c3f2SGreg Roach * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
133763c3f2SGreg Roach * GNU General Public License for more details.
143763c3f2SGreg Roach * You should have received a copy of the GNU General Public License
1589f7189bSGreg Roach * along with this program. If not, see <https://www.gnu.org/licenses/>.
163763c3f2SGreg Roach */
17fcfa147eSGreg Roach
18e7f56f2aSGreg Roachdeclare(strict_types=1);
19e7f56f2aSGreg Roach
2076692c8bSGreg Roachnamespace Fisharebest\Webtrees\Module;
2176692c8bSGreg Roach
2263276d8fSGreg Roachuse Fisharebest\Webtrees\Auth;
23d07f58d4SGreg Roachuse Fisharebest\Webtrees\Elements\AdoptedByWhichParent;
24e820a2a4SGreg Roachuse Fisharebest\Webtrees\Elements\CustomElement;
25d07f58d4SGreg Roachuse Fisharebest\Webtrees\Elements\XrefFamily;
260e62c4b8SGreg Roachuse Fisharebest\Webtrees\Fact;
270e62c4b8SGreg Roachuse Fisharebest\Webtrees\I18N;
280e62c4b8SGreg Roachuse Fisharebest\Webtrees\Individual;
29e820a2a4SGreg Roachuse Fisharebest\Webtrees\Registry;
302adcbd9aSGreg Roachuse Fisharebest\Webtrees\Services\ClipboardService;
312c066a59SGreg Roachuse Fisharebest\Webtrees\Services\IndividualFactsService;
324ca7e03cSGreg Roachuse Fisharebest\Webtrees\Services\ModuleService;
3317c50b57SGreg Roachuse Illuminate\Support\Collection;
343763c3f2SGreg Roach
35d0889c63SGreg Roachuse function view;
36dec352c1SGreg Roach
373763c3f2SGreg Roach/**
383763c3f2SGreg Roach * Class IndividualFactsTabModule
393763c3f2SGreg Roach */
4037eb8894SGreg Roachclass IndividualFactsTabModule extends AbstractModule implements ModuleTabInterface
41c1010edaSGreg Roach{
4249a243cbSGreg Roach    use ModuleTabTrait;
4349a243cbSGreg Roach
4491a257a4SGreg Roach    private ClipboardService $clipboard_service;
452adcbd9aSGreg Roach
46154df5cfSGreg Roach    private IndividualFactsService $individual_facts_service;
474991f205SGreg Roach
484991f205SGreg Roach    private ModuleService $module_service;
494991f205SGreg Roach
504ca7e03cSGreg Roach    /**
512adcbd9aSGreg Roach     * @param ClipboardService       $clipboard_service
522c066a59SGreg Roach     * @param IndividualFactsService $individual_facts_service
532c066a59SGreg Roach     * @param ModuleService          $module_service
544ca7e03cSGreg Roach     */
552c066a59SGreg Roach    public function __construct(
562c066a59SGreg Roach        ClipboardService $clipboard_service,
572c066a59SGreg Roach        IndividualFactsService $individual_facts_service,
582c066a59SGreg Roach        ModuleService $module_service
592c066a59SGreg Roach    ) {
602adcbd9aSGreg Roach        $this->clipboard_service        = $clipboard_service;
612c066a59SGreg Roach        $this->individual_facts_service = $individual_facts_service;
624991f205SGreg Roach        $this->module_service           = $module_service;
634ca7e03cSGreg Roach    }
644ca7e03cSGreg Roach
654ca7e03cSGreg Roach    /**
660cfd6963SGreg Roach     * How should this module be identified in the control panel, etc.?
67961ec755SGreg Roach     *
68961ec755SGreg Roach     * @return string
69961ec755SGreg Roach     */
7049a243cbSGreg Roach    public function title(): string
71c1010edaSGreg Roach    {
72bbb76c12SGreg Roach        /* I18N: Name of a module/tab on the individual page. */
73bbb76c12SGreg Roach        return I18N::translate('Facts and events');
743763c3f2SGreg Roach    }
753763c3f2SGreg Roach
7649a243cbSGreg Roach    public function description(): string
77c1010edaSGreg Roach    {
78bbb76c12SGreg Roach        /* I18N: Description of the “Facts and events” module */
79bbb76c12SGreg Roach        return I18N::translate('A tab showing the facts and events of an individual.');
803763c3f2SGreg Roach    }
813763c3f2SGreg Roach
8249a243cbSGreg Roach    /**
8349a243cbSGreg Roach     * The default position for this tab.  It can be changed in the control panel.
8449a243cbSGreg Roach     *
8549a243cbSGreg Roach     * @return int
8649a243cbSGreg Roach     */
87cbf4b7faSGreg Roach    public function defaultTabOrder(): int
88cbf4b7faSGreg Roach    {
89fb7a0427SGreg Roach        return 1;
903763c3f2SGreg Roach    }
913763c3f2SGreg Roach
923caaa4d2SGreg Roach    /**
933caaa4d2SGreg Roach     * A greyed out tab has no actual content, but may perhaps have
943caaa4d2SGreg Roach     * options to create content.
953caaa4d2SGreg Roach     *
963caaa4d2SGreg Roach     * @param Individual $individual
973caaa4d2SGreg Roach     *
983caaa4d2SGreg Roach     * @return bool
993caaa4d2SGreg Roach     */
1008f53f488SRico Sonntag    public function isGrayedOut(Individual $individual): bool
101c1010edaSGreg Roach    {
1023763c3f2SGreg Roach        return false;
1033763c3f2SGreg Roach    }
1043763c3f2SGreg Roach
1053caaa4d2SGreg Roach    /**
1063caaa4d2SGreg Roach     * Generate the HTML content of this tab.
1073caaa4d2SGreg Roach     *
1083caaa4d2SGreg Roach     * @param Individual $individual
1093caaa4d2SGreg Roach     *
1103caaa4d2SGreg Roach     * @return string
1113caaa4d2SGreg Roach     */
1129b34404bSGreg Roach    public function getTabContent(Individual $individual): string
113c1010edaSGreg Roach    {
1148eaf8709SGreg Roach        // Which facts and events are handled by other modules?
1158eaf8709SGreg Roach        $sidebar_facts = $this->module_service
11687cca37cSGreg Roach            ->findByComponent(ModuleSidebarInterface::class, $individual->tree(), Auth::user())
1172c066a59SGreg Roach            ->map(fn (ModuleSidebarInterface $sidebar): Collection => $sidebar->supportedFacts())
1182c066a59SGreg Roach            ->flatten();
1198eaf8709SGreg Roach
1208eaf8709SGreg Roach        $tab_facts = $this->module_service
12187cca37cSGreg Roach            ->findByComponent(ModuleTabInterface::class, $individual->tree(), Auth::user())
1222c066a59SGreg Roach            ->map(fn (ModuleTabInterface $tab): Collection => $tab->supportedFacts())
1232c066a59SGreg Roach            ->flatten();
1248eaf8709SGreg Roach
1254b720571SGreg Roach        // Don't show family meta-data tags
1264b720571SGreg Roach        $exclude_facts  = new Collection(['FAM:CHAN', 'FAM:_UID']);
1274b720571SGreg Roach        // Don't show tags that are shown in tabs or sidebars
1284b720571SGreg Roach        $exclude_facts = $exclude_facts->merge($sidebar_facts)->merge($tab_facts);
1298eaf8709SGreg Roach
130c67afd10SGreg Roach        $individual_facts = $this->individual_facts_service->individualFacts($individual, $exclude_facts);
131c67afd10SGreg Roach        $family_facts     = $this->individual_facts_service->familyFacts($individual, $exclude_facts);
1322c066a59SGreg Roach        $relative_facts   = $this->individual_facts_service->relativeFacts($individual);
1332c066a59SGreg Roach        $associate_facts  = $this->individual_facts_service->associateFacts($individual);
1342c066a59SGreg Roach        $historic_facts   = $this->individual_facts_service->historicFacts($individual);
135225e381fSGreg Roach
13691a257a4SGreg Roach        $individual_facts = $individual_facts
1372c066a59SGreg Roach            ->merge($family_facts)
1382c066a59SGreg Roach            ->merge($relative_facts)
13939ca88baSGreg Roach            ->merge($associate_facts)
1402c066a59SGreg Roach            ->merge($historic_facts);
1413763c3f2SGreg Roach
14291a257a4SGreg Roach        $individual_facts = Fact::sortFacts($individual_facts);
1433763c3f2SGreg Roach
144e820a2a4SGreg Roach        // Facts of relatives take the form 1 EVEN / 2 TYPE Event of Individual
145e820a2a4SGreg Roach        // Ensure custom tags from there are recognised
146df016312SGreg Roach        Registry::elementFactory()->registerTags([
147df016312SGreg Roach            'INDI:EVEN:CEME'      => new CustomElement('Cemetery'),
148df016312SGreg Roach            'INDI:EVEN:_GODP'     => new CustomElement('Godparent'),
149d07f58d4SGreg Roach            'INDI:EVEN:FAMC'      => new XrefFamily(I18N::translate('Adoptive parents')),
150d07f58d4SGreg Roach            'INDI:EVEN:FAMC:ADOP' => new AdoptedByWhichParent(I18N::translate('Adoption')),
151df016312SGreg Roach        ]);
152e820a2a4SGreg Roach
153a8cd57e1SGreg Roach        return view('modules/personal_facts/tab', [
154225e381fSGreg Roach            'can_edit'            => $individual->canEdit(),
15569cdf014SGreg Roach            'clipboard_facts'     => $this->clipboard_service->pastableFacts($individual),
15691a257a4SGreg Roach            'has_associate_facts' => $associate_facts->isNotEmpty(),
15791a257a4SGreg Roach            'has_historic_facts'  => $historic_facts->isNotEmpty(),
15891a257a4SGreg Roach            'has_relative_facts'  => $relative_facts->isNotEmpty(),
159225e381fSGreg Roach            'individual'          => $individual,
16091a257a4SGreg Roach            'facts'               => $individual_facts,
161225e381fSGreg Roach        ]);
1623763c3f2SGreg Roach    }
1633763c3f2SGreg Roach
164ee727175SGreg Roach    /**
16591a257a4SGreg Roach     * Is this tab empty? If so, we don't always need to display it.
16691a257a4SGreg Roach     *
16791a257a4SGreg Roach     * @param Individual $individual
16891a257a4SGreg Roach     *
16991a257a4SGreg Roach     * @return bool
17091a257a4SGreg Roach     */
17191a257a4SGreg Roach    public function hasTabContent(Individual $individual): bool
17291a257a4SGreg Roach    {
17391a257a4SGreg Roach        return true;
17491a257a4SGreg Roach    }
17591a257a4SGreg Roach
17691a257a4SGreg Roach    /**
17791a257a4SGreg Roach     * Can this tab load asynchronously?
17891a257a4SGreg Roach     *
17991a257a4SGreg Roach     * @return bool
18091a257a4SGreg Roach     */
18191a257a4SGreg Roach    public function canLoadAjax(): bool
18291a257a4SGreg Roach    {
18391a257a4SGreg Roach        return false;
1843763c3f2SGreg Roach    }
1858eaf8709SGreg Roach
1868eaf8709SGreg Roach    /**
1878eaf8709SGreg Roach     * This module handles the following facts - so don't show them on the "Facts and events" tab.
1888eaf8709SGreg Roach     *
18936779af1SGreg Roach     * @return Collection<int,string>
1908eaf8709SGreg Roach     */
1918eaf8709SGreg Roach    public function supportedFacts(): Collection
1928eaf8709SGreg Roach    {
1938eaf8709SGreg Roach        // We don't actually displaye these facts, but they are displayed
1948eaf8709SGreg Roach        // outside the tabs/sidebar systems. This just forces them to be excluded here.
195d0889c63SGreg Roach        return new Collection(['INDI:NAME', 'INDI:SEX', 'INDI:OBJE']);
1968eaf8709SGreg Roach    }
1973763c3f2SGreg Roach}
198