18c2e8227SGreg Roach<?php 28c2e8227SGreg Roach/** 38c2e8227SGreg Roach * webtrees: online genealogy 41062a142SGreg Roach * Copyright (C) 2018 webtrees development team 58c2e8227SGreg Roach * This program is free software: you can redistribute it and/or modify 68c2e8227SGreg Roach * it under the terms of the GNU General Public License as published by 78c2e8227SGreg Roach * the Free Software Foundation, either version 3 of the License, or 88c2e8227SGreg Roach * (at your option) any later version. 98c2e8227SGreg Roach * This program is distributed in the hope that it will be useful, 108c2e8227SGreg Roach * but WITHOUT ANY WARRANTY; without even the implied warranty of 118c2e8227SGreg Roach * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 128c2e8227SGreg Roach * GNU General Public License for more details. 138c2e8227SGreg Roach * You should have received a copy of the GNU General Public License 148c2e8227SGreg Roach * along with this program. If not, see <http://www.gnu.org/licenses/>. 158c2e8227SGreg Roach */ 1676692c8bSGreg Roachnamespace Fisharebest\Webtrees\Module; 1776692c8bSGreg Roach 180e62c4b8SGreg Roachuse Fisharebest\Webtrees\Auth; 190e62c4b8SGreg Roachuse Fisharebest\Webtrees\Filter; 2012664b30SGreg Roachuse Fisharebest\Webtrees\GedcomTag; 210e62c4b8SGreg Roachuse Fisharebest\Webtrees\I18N; 22*f0a11419SGreg Roachuse Fisharebest\Webtrees\Services\CalendarService; 23e490cd80SGreg Roachuse Fisharebest\Webtrees\Tree; 248c2e8227SGreg Roach 258c2e8227SGreg Roach/** 268c2e8227SGreg Roach * Class UpcomingAnniversariesModule 278c2e8227SGreg Roach */ 28c1010edaSGreg Roachclass UpcomingAnniversariesModule extends AbstractModule implements ModuleBlockInterface 29c1010edaSGreg Roach{ 30c385536dSGreg Roach // Default values for new blocks. 31c385536dSGreg Roach const DEFAULT_DAYS = 7; 32c385536dSGreg Roach const DEFAULT_FILTER = '1'; 33c385536dSGreg Roach const DEFAULT_SORT = 'alpha'; 34c385536dSGreg Roach const DEFAULT_STYLE = 'table'; 35c385536dSGreg Roach 36c385536dSGreg Roach // Can show this number of days into the future. 37c385536dSGreg Roach const MIN_DAYS = 1; 38c385536dSGreg Roach const MAX_DAYS = 30; 39c385536dSGreg Roach 4012664b30SGreg Roach // All standard GEDCOM 5.5.1 events except CENS, RESI and EVEN 4112664b30SGreg Roach const ALL_EVENTS = [ 4212664b30SGreg Roach 'ADOP', 4312664b30SGreg Roach 'ANUL', 4412664b30SGreg Roach 'BAPM', 4512664b30SGreg Roach 'BARM', 4612664b30SGreg Roach 'BASM', 4712664b30SGreg Roach 'BIRT', 4812664b30SGreg Roach 'BLES', 4912664b30SGreg Roach 'BURI', 5012664b30SGreg Roach 'CHR', 5112664b30SGreg Roach 'CHRA', 5212664b30SGreg Roach 'CONF', 5312664b30SGreg Roach 'CREM', 5412664b30SGreg Roach 'DEAT', 5512664b30SGreg Roach 'DIV', 5612664b30SGreg Roach 'DIVF', 5712664b30SGreg Roach 'EMIG', 5812664b30SGreg Roach 'ENGA', 5912664b30SGreg Roach 'FCOM', 6012664b30SGreg Roach 'GRAD', 6112664b30SGreg Roach 'IMMI', 6212664b30SGreg Roach 'MARB', 6312664b30SGreg Roach 'MARC', 6412664b30SGreg Roach 'MARL', 6512664b30SGreg Roach 'MARR', 6612664b30SGreg Roach 'MARS', 6712664b30SGreg Roach 'NATU', 6812664b30SGreg Roach 'ORDN', 6912664b30SGreg Roach 'PROB', 7012664b30SGreg Roach 'RETI', 7112664b30SGreg Roach 'WILL', 7212664b30SGreg Roach ]; 7312664b30SGreg Roach 7412664b30SGreg Roach const DEFAULT_EVENTS = [ 7512664b30SGreg Roach 'BIRT', 7612664b30SGreg Roach 'MARR', 7712664b30SGreg Roach 'DEAT', 7812664b30SGreg Roach ]; 7912664b30SGreg Roach 8076692c8bSGreg Roach /** 8176692c8bSGreg Roach * How should this module be labelled on tabs, menus, etc.? 8276692c8bSGreg Roach * 8376692c8bSGreg Roach * @return string 8476692c8bSGreg Roach */ 85c1010edaSGreg Roach public function getTitle() 86c1010edaSGreg Roach { 87bbb76c12SGreg Roach /* I18N: Name of a module */ 88bbb76c12SGreg Roach return I18N::translate('Upcoming events'); 898c2e8227SGreg Roach } 908c2e8227SGreg Roach 9176692c8bSGreg Roach /** 9276692c8bSGreg Roach * A sentence describing what this module does. 9376692c8bSGreg Roach * 9476692c8bSGreg Roach * @return string 9576692c8bSGreg Roach */ 96c1010edaSGreg Roach public function getDescription() 97c1010edaSGreg Roach { 98bbb76c12SGreg Roach /* I18N: Description of the “Upcoming events” module */ 99bbb76c12SGreg Roach return I18N::translate('A list of the anniversaries that will occur in the near future.'); 1008c2e8227SGreg Roach } 1018c2e8227SGreg Roach 10276692c8bSGreg Roach /** 10376692c8bSGreg Roach * Generate the HTML content of this block. 10476692c8bSGreg Roach * 105e490cd80SGreg Roach * @param Tree $tree 10676692c8bSGreg Roach * @param int $block_id 10776692c8bSGreg Roach * @param bool $template 108727f238cSGreg Roach * @param string[] $cfg 10976692c8bSGreg Roach * 11076692c8bSGreg Roach * @return string 11176692c8bSGreg Roach */ 112c1010edaSGreg Roach public function getBlock(Tree $tree, int $block_id, bool $template = true, array $cfg = []): string 113c1010edaSGreg Roach { 114e490cd80SGreg Roach global $ctype; 1158c2e8227SGreg Roach 116*f0a11419SGreg Roach $calendar_service = new CalendarService(); 117*f0a11419SGreg Roach 11812664b30SGreg Roach $default_events = implode(',', self::DEFAULT_EVENTS); 11912664b30SGreg Roach 120c385536dSGreg Roach $days = $this->getBlockSetting($block_id, 'days', self::DEFAULT_DAYS); 121c385536dSGreg Roach $filter = (bool)$this->getBlockSetting($block_id, 'filter', self::DEFAULT_FILTER); 122c385536dSGreg Roach $infoStyle = $this->getBlockSetting($block_id, 'infoStyle', self::DEFAULT_STYLE); 123c385536dSGreg Roach $sortStyle = $this->getBlockSetting($block_id, 'sortStyle', self::DEFAULT_SORT); 12412664b30SGreg Roach $events = $this->getBlockSetting($block_id, 'events', $default_events); 1258c2e8227SGreg Roach 126c385536dSGreg Roach extract($cfg, EXTR_OVERWRITE); 1278c2e8227SGreg Roach 12812664b30SGreg Roach $event_array = explode(',', $events); 12912664b30SGreg Roach 13012664b30SGreg Roach // If we are only showing living individuals, then we don't need to search for DEAT events. 13112664b30SGreg Roach if ($filter) { 13212664b30SGreg Roach $death_events = explode('|', WT_EVENTS_DEAT); 13312664b30SGreg Roach $event_array = array_diff($event_array, $death_events); 13412664b30SGreg Roach } 13512664b30SGreg Roach 13612664b30SGreg Roach $events_filter = implode('|', $event_array); 13712664b30SGreg Roach 1388c2e8227SGreg Roach $startjd = WT_CLIENT_JD + 1; 139e490cd80SGreg Roach $endjd = WT_CLIENT_JD + (int)$days; 14012664b30SGreg Roach 141*f0a11419SGreg Roach $facts = $calendar_service->getEventsList($startjd, $endjd, $events_filter, $filter, $sortStyle, $tree); 14212664b30SGreg Roach 14312664b30SGreg Roach if (empty($facts)) { 144d8189b6aSDavid Drury if ($endjd == $startjd) { 145147e99aaSGreg Roach $content = view('modules/upcoming_events/empty', [ 146c1010edaSGreg Roach 'message' => I18N::translate('No events exist for tomorrow.'), 1470280f44aSGreg Roach ]); 148d8189b6aSDavid Drury } else { 149bbb76c12SGreg Roach /* I18N: translation for %s==1 is unused; it is translated separately as “tomorrow” */ $content = view('modules/upcoming_events/empty', [ 150bbb76c12SGreg Roach 'message' => I18N::plural('No events exist for the next %s day.', 'No events exist for the next %s days.', $endjd - $startjd + 1, I18N::number($endjd - $startjd + 1)), 1510280f44aSGreg Roach ]); 1528c2e8227SGreg Roach } 153147e99aaSGreg Roach } elseif ($infoStyle === 'list') { 154147e99aaSGreg Roach $content = view('modules/upcoming_events/list', [ 155d8189b6aSDavid Drury 'facts' => $facts, 156147e99aaSGreg Roach ]); 157147e99aaSGreg Roach } else { 158147e99aaSGreg Roach $content = view('modules/upcoming_events/table', [ 159147e99aaSGreg Roach 'facts' => $facts, 160147e99aaSGreg Roach ]); 1610280f44aSGreg Roach } 1628c2e8227SGreg Roach 1638c2e8227SGreg Roach if ($template) { 164e490cd80SGreg Roach if ($ctype === 'gedcom' && Auth::isManager($tree)) { 165c1010edaSGreg Roach $config_url = route('tree-page-block-edit', [ 166c1010edaSGreg Roach 'block_id' => $block_id, 167c1010edaSGreg Roach 'ged' => $tree->getName(), 168c1010edaSGreg Roach ]); 169397e599aSGreg Roach } elseif ($ctype === 'user' && Auth::check()) { 170c1010edaSGreg Roach $config_url = route('user-page-block-edit', [ 171c1010edaSGreg Roach 'block_id' => $block_id, 172c1010edaSGreg Roach 'ged' => $tree->getName(), 173c1010edaSGreg Roach ]); 1748cbbfdceSGreg Roach } else { 1758cbbfdceSGreg Roach $config_url = ''; 1768cbbfdceSGreg Roach } 1778cbbfdceSGreg Roach 178147e99aaSGreg Roach return view('modules/block-template', [ 1799c6524dcSGreg Roach 'block' => str_replace('_', '-', $this->getName()), 1809c6524dcSGreg Roach 'id' => $block_id, 1818cbbfdceSGreg Roach 'config_url' => $config_url, 1829c6524dcSGreg Roach 'title' => $this->getTitle(), 1839c6524dcSGreg Roach 'content' => $content, 1849c6524dcSGreg Roach ]); 1858c2e8227SGreg Roach } else { 1868c2e8227SGreg Roach return $content; 1878c2e8227SGreg Roach } 1888c2e8227SGreg Roach } 1898c2e8227SGreg Roach 1908c2e8227SGreg Roach /** {@inheritdoc} */ 191c1010edaSGreg Roach public function loadAjax(): bool 192c1010edaSGreg Roach { 1938c2e8227SGreg Roach return true; 1948c2e8227SGreg Roach } 1958c2e8227SGreg Roach 1968c2e8227SGreg Roach /** {@inheritdoc} */ 197c1010edaSGreg Roach public function isUserBlock(): bool 198c1010edaSGreg Roach { 1998c2e8227SGreg Roach return true; 2008c2e8227SGreg Roach } 2018c2e8227SGreg Roach 2028c2e8227SGreg Roach /** {@inheritdoc} */ 203c1010edaSGreg Roach public function isGedcomBlock(): bool 204c1010edaSGreg Roach { 2058c2e8227SGreg Roach return true; 2068c2e8227SGreg Roach } 2078c2e8227SGreg Roach 20876692c8bSGreg Roach /** 20976692c8bSGreg Roach * An HTML form to edit block settings 21076692c8bSGreg Roach * 211e490cd80SGreg Roach * @param Tree $tree 21276692c8bSGreg Roach * @param int $block_id 213a9430be8SGreg Roach * 214a9430be8SGreg Roach * @return void 21576692c8bSGreg Roach */ 216c1010edaSGreg Roach public function configureBlock(Tree $tree, int $block_id) 217c1010edaSGreg Roach { 218c385536dSGreg Roach if ($_SERVER['REQUEST_METHOD'] === 'POST') { 219c385536dSGreg Roach $this->setBlockSetting($block_id, 'days', Filter::postInteger('days', self::MIN_DAYS, self::MAX_DAYS, self::DEFAULT_DAYS)); 220e2a378d3SGreg Roach $this->setBlockSetting($block_id, 'filter', Filter::postBool('filter')); 221c385536dSGreg Roach $this->setBlockSetting($block_id, 'infoStyle', Filter::post('infoStyle', 'list|table', self::DEFAULT_STYLE)); 222c385536dSGreg Roach $this->setBlockSetting($block_id, 'sortStyle', Filter::post('sortStyle', 'alpha|anniv', self::DEFAULT_SORT)); 22312664b30SGreg Roach $this->setBlockSetting($block_id, 'events', implode(',', Filter::postArray('events'))); 224c385536dSGreg Roach 225c385536dSGreg Roach return; 2268c2e8227SGreg Roach } 2278c2e8227SGreg Roach 22812664b30SGreg Roach $default_events = implode(',', self::DEFAULT_EVENTS); 22912664b30SGreg Roach 230c385536dSGreg Roach $days = $this->getBlockSetting($block_id, 'days', self::DEFAULT_DAYS); 231c385536dSGreg Roach $filter = $this->getBlockSetting($block_id, 'filter', self::DEFAULT_FILTER); 232c385536dSGreg Roach $infoStyle = $this->getBlockSetting($block_id, 'infoStyle', self::DEFAULT_STYLE); 233c385536dSGreg Roach $sortStyle = $this->getBlockSetting($block_id, 'sortStyle', self::DEFAULT_SORT); 23412664b30SGreg Roach $events = $this->getBlockSetting($block_id, 'events', $default_events); 2358c2e8227SGreg Roach 23612664b30SGreg Roach $event_array = explode(',', $events); 23712664b30SGreg Roach 23812664b30SGreg Roach $all_events = []; 23912664b30SGreg Roach foreach (self::ALL_EVENTS as $event) { 24012664b30SGreg Roach $all_events[$event] = GedcomTag::getLabel($event); 24112664b30SGreg Roach } 24212664b30SGreg Roach 243c385536dSGreg Roach $info_styles = [ 244bbb76c12SGreg Roach /* I18N: An option in a list-box */ 245bbb76c12SGreg Roach 'list' => I18N::translate('list'), 246bbb76c12SGreg Roach /* I18N: An option in a list-box */ 247bbb76c12SGreg Roach 'table' => I18N::translate('table'), 248c385536dSGreg Roach ]; 2498c2e8227SGreg Roach 250c385536dSGreg Roach $sort_styles = [ 251bbb76c12SGreg Roach /* I18N: An option in a list-box */ 252bbb76c12SGreg Roach 'alpha' => I18N::translate('sort by name'), 253bbb76c12SGreg Roach /* I18N: An option in a list-box */ 254bbb76c12SGreg Roach 'anniv' => I18N::translate('sort by date'), 255c385536dSGreg Roach ]; 2568c2e8227SGreg Roach 257147e99aaSGreg Roach echo view('modules/upcoming_events/config', [ 258c385536dSGreg Roach 'all_events' => $all_events, 259c385536dSGreg Roach 'days' => $days, 260c385536dSGreg Roach 'event_array' => $event_array, 261c385536dSGreg Roach 'filter' => $filter, 262c385536dSGreg Roach 'infoStyle' => $infoStyle, 263c385536dSGreg Roach 'info_styles' => $info_styles, 264c385536dSGreg Roach 'max_days' => self::MAX_DAYS, 265c385536dSGreg Roach 'sortStyle' => $sortStyle, 266c385536dSGreg Roach 'sort_styles' => $sort_styles, 267c385536dSGreg Roach ]); 2688c2e8227SGreg Roach } 2698c2e8227SGreg Roach} 270