1<?php 2/** 3 * webtrees: online genealogy 4 * Copyright (C) 2019 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 */ 16declare(strict_types=1); 17 18namespace Fisharebest\Webtrees\Module; 19 20use Carbon\Carbon; 21use Fisharebest\Webtrees\Auth; 22use Fisharebest\Webtrees\Gedcom; 23use Fisharebest\Webtrees\GedcomTag; 24use Fisharebest\Webtrees\I18N; 25use Fisharebest\Webtrees\Services\CalendarService; 26use Fisharebest\Webtrees\Tree; 27use Symfony\Component\HttpFoundation\Request; 28 29/** 30 * Class OnThisDayModule 31 */ 32class OnThisDayModule extends AbstractModule implements ModuleBlockInterface 33{ 34 use ModuleBlockTrait; 35 36 // All standard GEDCOM 5.5.1 events except CENS, RESI and EVEN 37 private const ALL_EVENTS = [ 38 'ADOP', 39 'ANUL', 40 'BAPM', 41 'BARM', 42 'BASM', 43 'BIRT', 44 'BLES', 45 'BURI', 46 'CHR', 47 'CHRA', 48 'CONF', 49 'CREM', 50 'DEAT', 51 'DIV', 52 'DIVF', 53 'EMIG', 54 'ENGA', 55 'FCOM', 56 'GRAD', 57 'IMMI', 58 'MARB', 59 'MARC', 60 'MARL', 61 'MARR', 62 'MARS', 63 'NATU', 64 'ORDN', 65 'PROB', 66 'RETI', 67 'WILL', 68 ]; 69 70 private const DEFAULT_EVENTS = [ 71 'BIRT', 72 'MARR', 73 'DEAT', 74 ]; 75 76 /** 77 * How should this module be labelled on tabs, menus, etc.? 78 * 79 * @return string 80 */ 81 public function title(): string 82 { 83 /* I18N: Name of a module */ 84 return I18N::translate('On this day'); 85 } 86 87 /** 88 * A sentence describing what this module does. 89 * 90 * @return string 91 */ 92 public function description(): string 93 { 94 /* I18N: Description of the “On this day” module */ 95 return I18N::translate('A list of the anniversaries that occur today.'); 96 } 97 98 /** 99 * Generate the HTML content of this block. 100 * 101 * @param Tree $tree 102 * @param int $block_id 103 * @param string $ctype 104 * @param string[] $cfg 105 * 106 * @return string 107 */ 108 public function getBlock(Tree $tree, int $block_id, string $ctype = '', array $cfg = []): string 109 { 110 $calendar_service = new CalendarService(); 111 112 $default_events = implode(',', self::DEFAULT_EVENTS); 113 114 $filter = (bool) $this->getBlockSetting($block_id, 'filter', '1'); 115 $infoStyle = $this->getBlockSetting($block_id, 'infoStyle', 'table'); 116 $sortStyle = $this->getBlockSetting($block_id, 'sortStyle', 'alpha'); 117 $events = $this->getBlockSetting($block_id, 'events', $default_events); 118 119 extract($cfg, EXTR_OVERWRITE); 120 121 $event_array = explode(',', $events); 122 123 // If we are only showing living individuals, then we don't need to search for DEAT events. 124 if ($filter) { 125 $event_array = array_diff($event_array, Gedcom::DEATH_EVENTS); 126 } 127 128 $events_filter = implode('|', $event_array); 129 130 $startjd = unixtojd(Carbon::now()->timestamp); 131 $endjd = $startjd; 132 133 $facts = $calendar_service->getEventsList($startjd, $endjd, $events_filter, $filter, $sortStyle, $tree); 134 135 if (empty($facts)) { 136 $content = view('modules/todays_events/empty'); 137 } elseif ($infoStyle === 'list') { 138 $content = view('modules/todays_events/list', [ 139 'facts' => $facts, 140 ]); 141 } else { 142 $content = view('modules/todays_events/table', [ 143 'facts' => $facts, 144 ]); 145 } 146 147 if ($ctype !== '') { 148 if ($ctype === 'gedcom' && Auth::isManager($tree)) { 149 $config_url = route('tree-page-block-edit', [ 150 'block_id' => $block_id, 151 'ged' => $tree->name(), 152 ]); 153 } elseif ($ctype === 'user' && Auth::check()) { 154 $config_url = route('user-page-block-edit', [ 155 'block_id' => $block_id, 156 'ged' => $tree->name(), 157 ]); 158 } else { 159 $config_url = ''; 160 } 161 162 return view('modules/block-template', [ 163 'block' => str_replace('_', '-', $this->name()), 164 'id' => $block_id, 165 'config_url' => $config_url, 166 'title' => $this->title(), 167 'content' => $content, 168 ]); 169 } 170 171 return $content; 172 } 173 174 /** {@inheritdoc} */ 175 public function loadAjax(): bool 176 { 177 return true; 178 } 179 180 /** {@inheritdoc} */ 181 public function isUserBlock(): bool 182 { 183 return true; 184 } 185 186 /** {@inheritdoc} */ 187 public function isTreeBlock(): bool 188 { 189 return true; 190 } 191 192 /** 193 * Update the configuration for a block. 194 * 195 * @param Request $request 196 * @param int $block_id 197 * 198 * @return void 199 */ 200 public function saveBlockConfiguration(Request $request, int $block_id) 201 { 202 $this->setBlockSetting($block_id, 'filter', $request->get('filter', '1')); 203 $this->setBlockSetting($block_id, 'infoStyle', $request->get('infoStyle', 'table')); 204 $this->setBlockSetting($block_id, 'sortStyle', $request->get('sortStyle', 'alpha')); 205 $this->setBlockSetting($block_id, 'events', implode(',', (array) $request->get('events'))); 206 } 207 208 /** 209 * An HTML form to edit block settings 210 * 211 * @param Tree $tree 212 * @param int $block_id 213 * 214 * @return void 215 */ 216 public function editBlockConfiguration(Tree $tree, int $block_id) 217 { 218 $default_events = implode(',', self::DEFAULT_EVENTS); 219 220 $filter = $this->getBlockSetting($block_id, 'filter', '1'); 221 $infoStyle = $this->getBlockSetting($block_id, 'infoStyle', 'table'); 222 $sortStyle = $this->getBlockSetting($block_id, 'sortStyle', 'alpha'); 223 $events = $this->getBlockSetting($block_id, 'events', $default_events); 224 225 $event_array = explode(',', $events); 226 227 $all_events = []; 228 foreach (self::ALL_EVENTS as $event) { 229 $all_events[$event] = GedcomTag::getLabel($event); 230 } 231 232 $info_styles = [ 233 /* I18N: An option in a list-box */ 234 'list' => I18N::translate('list'), 235 /* I18N: An option in a list-box */ 236 'table' => I18N::translate('table'), 237 ]; 238 239 $sort_styles = [ 240 /* I18N: An option in a list-box */ 241 'alpha' => I18N::translate('sort by name'), 242 /* I18N: An option in a list-box */ 243 'anniv' => I18N::translate('sort by date'), 244 ]; 245 246 echo view('modules/todays_events/config', [ 247 'all_events' => $all_events, 248 'event_array' => $event_array, 249 'filter' => $filter, 250 'infoStyle' => $infoStyle, 251 'info_styles' => $info_styles, 252 'sortStyle' => $sortStyle, 253 'sort_styles' => $sort_styles, 254 ]); 255 } 256} 257