13763c3f2SGreg Roach<?php 23976b470SGreg Roach 33763c3f2SGreg Roach/** 43763c3f2SGreg Roach * webtrees: online genealogy 55bfc6897SGreg Roach * Copyright (C) 2022 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; 23e820a2a4SGreg Roachuse Fisharebest\Webtrees\Elements\CustomElement; 240e62c4b8SGreg Roachuse Fisharebest\Webtrees\Fact; 250e62c4b8SGreg Roachuse Fisharebest\Webtrees\I18N; 260e62c4b8SGreg Roachuse Fisharebest\Webtrees\Individual; 27e820a2a4SGreg Roachuse Fisharebest\Webtrees\Registry; 282adcbd9aSGreg Roachuse Fisharebest\Webtrees\Services\ClipboardService; 292c066a59SGreg Roachuse Fisharebest\Webtrees\Services\IndividualFactsService; 304ca7e03cSGreg Roachuse Fisharebest\Webtrees\Services\ModuleService; 3117c50b57SGreg Roachuse Illuminate\Support\Collection; 323763c3f2SGreg Roach 33d0889c63SGreg Roachuse function view; 34dec352c1SGreg Roach 353763c3f2SGreg Roach/** 363763c3f2SGreg Roach * Class IndividualFactsTabModule 373763c3f2SGreg Roach */ 3837eb8894SGreg Roachclass IndividualFactsTabModule extends AbstractModule implements ModuleTabInterface 39c1010edaSGreg Roach{ 4049a243cbSGreg Roach use ModuleTabTrait; 4149a243cbSGreg Roach 4291a257a4SGreg Roach private ClipboardService $clipboard_service; 432adcbd9aSGreg Roach 44154df5cfSGreg Roach private IndividualFactsService $individual_facts_service; 454991f205SGreg Roach 464991f205SGreg Roach private ModuleService $module_service; 474991f205SGreg Roach 484ca7e03cSGreg Roach /** 492adcbd9aSGreg Roach * @param ClipboardService $clipboard_service 502c066a59SGreg Roach * @param IndividualFactsService $individual_facts_service 512c066a59SGreg Roach * @param ModuleService $module_service 524ca7e03cSGreg Roach */ 532c066a59SGreg Roach public function __construct( 542c066a59SGreg Roach ClipboardService $clipboard_service, 552c066a59SGreg Roach IndividualFactsService $individual_facts_service, 562c066a59SGreg Roach ModuleService $module_service 572c066a59SGreg Roach ) { 582adcbd9aSGreg Roach $this->clipboard_service = $clipboard_service; 592c066a59SGreg Roach $this->individual_facts_service = $individual_facts_service; 604991f205SGreg Roach $this->module_service = $module_service; 614ca7e03cSGreg Roach } 624ca7e03cSGreg Roach 634ca7e03cSGreg Roach /** 640cfd6963SGreg Roach * How should this module be identified in the control panel, etc.? 65961ec755SGreg Roach * 66961ec755SGreg Roach * @return string 67961ec755SGreg Roach */ 6849a243cbSGreg Roach public function title(): string 69c1010edaSGreg Roach { 70bbb76c12SGreg Roach /* I18N: Name of a module/tab on the individual page. */ 71bbb76c12SGreg Roach return I18N::translate('Facts and events'); 723763c3f2SGreg Roach } 733763c3f2SGreg Roach 74961ec755SGreg Roach /** 75961ec755SGreg Roach * A sentence describing what this module does. 76961ec755SGreg Roach * 77961ec755SGreg Roach * @return string 78961ec755SGreg Roach */ 7949a243cbSGreg Roach public function description(): string 80c1010edaSGreg Roach { 81bbb76c12SGreg Roach /* I18N: Description of the “Facts and events” module */ 82bbb76c12SGreg Roach return I18N::translate('A tab showing the facts and events of an individual.'); 833763c3f2SGreg Roach } 843763c3f2SGreg Roach 8549a243cbSGreg Roach /** 8649a243cbSGreg Roach * The default position for this tab. It can be changed in the control panel. 8749a243cbSGreg Roach * 8849a243cbSGreg Roach * @return int 8949a243cbSGreg Roach */ 90cbf4b7faSGreg Roach public function defaultTabOrder(): int 91cbf4b7faSGreg Roach { 92fb7a0427SGreg Roach return 1; 933763c3f2SGreg Roach } 943763c3f2SGreg Roach 953caaa4d2SGreg Roach /** 963caaa4d2SGreg Roach * A greyed out tab has no actual content, but may perhaps have 973caaa4d2SGreg Roach * options to create content. 983caaa4d2SGreg Roach * 993caaa4d2SGreg Roach * @param Individual $individual 1003caaa4d2SGreg Roach * 1013caaa4d2SGreg Roach * @return bool 1023caaa4d2SGreg Roach */ 1038f53f488SRico Sonntag public function isGrayedOut(Individual $individual): bool 104c1010edaSGreg Roach { 1053763c3f2SGreg Roach return false; 1063763c3f2SGreg Roach } 1073763c3f2SGreg Roach 1083caaa4d2SGreg Roach /** 1093caaa4d2SGreg Roach * Generate the HTML content of this tab. 1103caaa4d2SGreg Roach * 1113caaa4d2SGreg Roach * @param Individual $individual 1123caaa4d2SGreg Roach * 1133caaa4d2SGreg Roach * @return string 1143caaa4d2SGreg Roach */ 1159b34404bSGreg Roach public function getTabContent(Individual $individual): string 116c1010edaSGreg Roach { 1178eaf8709SGreg Roach // Which facts and events are handled by other modules? 1188eaf8709SGreg Roach $sidebar_facts = $this->module_service 11987cca37cSGreg Roach ->findByComponent(ModuleSidebarInterface::class, $individual->tree(), Auth::user()) 1202c066a59SGreg Roach ->map(fn (ModuleSidebarInterface $sidebar): Collection => $sidebar->supportedFacts()) 1212c066a59SGreg Roach ->flatten(); 1228eaf8709SGreg Roach 1238eaf8709SGreg Roach $tab_facts = $this->module_service 12487cca37cSGreg Roach ->findByComponent(ModuleTabInterface::class, $individual->tree(), Auth::user()) 1252c066a59SGreg Roach ->map(fn (ModuleTabInterface $tab): Collection => $tab->supportedFacts()) 1262c066a59SGreg Roach ->flatten(); 1278eaf8709SGreg Roach 1284b720571SGreg Roach // Don't show family meta-data tags 1294b720571SGreg Roach $exclude_facts = new Collection(['FAM:CHAN', 'FAM:_UID']); 1304b720571SGreg Roach // Don't show tags that are shown in tabs or sidebars 1314b720571SGreg Roach $exclude_facts = $exclude_facts->merge($sidebar_facts)->merge($tab_facts); 1328eaf8709SGreg Roach 133c67afd10SGreg Roach $individual_facts = $this->individual_facts_service->individualFacts($individual, $exclude_facts); 134c67afd10SGreg Roach $family_facts = $this->individual_facts_service->familyFacts($individual, $exclude_facts); 1352c066a59SGreg Roach $relative_facts = $this->individual_facts_service->relativeFacts($individual); 1362c066a59SGreg Roach $associate_facts = $this->individual_facts_service->associateFacts($individual); 1372c066a59SGreg Roach $historic_facts = $this->individual_facts_service->historicFacts($individual); 138225e381fSGreg Roach 13991a257a4SGreg Roach $individual_facts = $individual_facts 1402c066a59SGreg Roach ->merge($family_facts) 1412c066a59SGreg Roach ->merge($relative_facts) 14239ca88baSGreg Roach ->merge($associate_facts) 1432c066a59SGreg Roach ->merge($historic_facts); 1443763c3f2SGreg Roach 14591a257a4SGreg Roach $individual_facts = Fact::sortFacts($individual_facts); 1463763c3f2SGreg Roach 147e820a2a4SGreg Roach // Facts of relatives take the form 1 EVEN / 2 TYPE Event of Individual 148e820a2a4SGreg Roach // Ensure custom tags from there are recognised 149*df016312SGreg Roach Registry::elementFactory()->registerTags([ 150*df016312SGreg Roach 'INDI:EVEN:CEME' => new CustomElement('Cemetery'), 151*df016312SGreg Roach 'INDI:EVEN:_GODP' => new CustomElement('Godparent'), 152*df016312SGreg Roach ]); 153e820a2a4SGreg Roach 154a8cd57e1SGreg Roach return view('modules/personal_facts/tab', [ 155225e381fSGreg Roach 'can_edit' => $individual->canEdit(), 15669cdf014SGreg Roach 'clipboard_facts' => $this->clipboard_service->pastableFacts($individual), 15791a257a4SGreg Roach 'has_associate_facts' => $associate_facts->isNotEmpty(), 15891a257a4SGreg Roach 'has_historic_facts' => $historic_facts->isNotEmpty(), 15991a257a4SGreg Roach 'has_relative_facts' => $relative_facts->isNotEmpty(), 160225e381fSGreg Roach 'individual' => $individual, 16191a257a4SGreg Roach 'facts' => $individual_facts, 162225e381fSGreg Roach ]); 1633763c3f2SGreg Roach } 1643763c3f2SGreg Roach 165ee727175SGreg Roach /** 16691a257a4SGreg Roach * Is this tab empty? If so, we don't always need to display it. 16791a257a4SGreg Roach * 16891a257a4SGreg Roach * @param Individual $individual 16991a257a4SGreg Roach * 17091a257a4SGreg Roach * @return bool 17191a257a4SGreg Roach */ 17291a257a4SGreg Roach public function hasTabContent(Individual $individual): bool 17391a257a4SGreg Roach { 17491a257a4SGreg Roach return true; 17591a257a4SGreg Roach } 17691a257a4SGreg Roach 17791a257a4SGreg Roach /** 17891a257a4SGreg Roach * Can this tab load asynchronously? 17991a257a4SGreg Roach * 18091a257a4SGreg Roach * @return bool 18191a257a4SGreg Roach */ 18291a257a4SGreg Roach public function canLoadAjax(): bool 18391a257a4SGreg Roach { 18491a257a4SGreg Roach return false; 1853763c3f2SGreg Roach } 1868eaf8709SGreg Roach 1878eaf8709SGreg Roach /** 1888eaf8709SGreg Roach * This module handles the following facts - so don't show them on the "Facts and events" tab. 1898eaf8709SGreg Roach * 19036779af1SGreg Roach * @return Collection<int,string> 1918eaf8709SGreg Roach */ 1928eaf8709SGreg Roach public function supportedFacts(): Collection 1938eaf8709SGreg Roach { 1948eaf8709SGreg Roach // We don't actually displaye these facts, but they are displayed 1958eaf8709SGreg Roach // outside the tabs/sidebar systems. This just forces them to be excluded here. 196d0889c63SGreg Roach return new Collection(['INDI:NAME', 'INDI:SEX', 'INDI:OBJE']); 1978eaf8709SGreg Roach } 1983763c3f2SGreg Roach} 199