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; 178c2e8227SGreg Roach 188c2e8227SGreg Roachuse Fisharebest\ExtCalendar\JewishCalendar; 190e62c4b8SGreg Roachuse Fisharebest\Webtrees\Auth; 2015d603e7SGreg Roachuse Fisharebest\Webtrees\Bootstrap4; 210e62c4b8SGreg Roachuse Fisharebest\Webtrees\Date; 220e62c4b8SGreg Roachuse Fisharebest\Webtrees\Date\GregorianDate; 230e62c4b8SGreg Roachuse Fisharebest\Webtrees\Date\JewishDate; 240e62c4b8SGreg Roachuse Fisharebest\Webtrees\Filter; 253d7a8a4cSGreg Roachuse Fisharebest\Webtrees\Functions\FunctionsDb; 268cbbfdceSGreg Roachuse Fisharebest\Webtrees\Html; 270e62c4b8SGreg Roachuse Fisharebest\Webtrees\I18N; 288c2e8227SGreg Roach 298c2e8227SGreg Roach/** 308c2e8227SGreg Roach * Class YahrzeitModule 318c2e8227SGreg Roach */ 32e2a378d3SGreg Roachclass YahrzeitModule extends AbstractModule implements ModuleBlockInterface { 338c2e8227SGreg Roach /** {@inheritdoc} */ 348c2e8227SGreg Roach public function getTitle() { 358c2e8227SGreg Roach return /* I18N: Name of a module. Yahrzeiten (the plural of Yahrzeit) are special anniversaries of deaths in the Hebrew faith/calendar. */ I18N::translate('Yahrzeiten'); 368c2e8227SGreg Roach } 378c2e8227SGreg Roach 388c2e8227SGreg Roach /** {@inheritdoc} */ 398c2e8227SGreg Roach public function getDescription() { 408c2e8227SGreg Roach return /* I18N: Description of the “Yahrzeiten” module. A “Hebrew death” is a death where the date is recorded in the Hebrew calendar. */ I18N::translate('A list of the Hebrew death anniversaries that will occur in the near future.'); 418c2e8227SGreg Roach } 428c2e8227SGreg Roach 4376692c8bSGreg Roach /** 4476692c8bSGreg Roach * Generate the HTML content of this block. 4576692c8bSGreg Roach * 4676692c8bSGreg Roach * @param int $block_id 4776692c8bSGreg Roach * @param bool $template 48727f238cSGreg Roach * @param string[] $cfg 4976692c8bSGreg Roach * 5076692c8bSGreg Roach * @return string 5176692c8bSGreg Roach */ 52a9430be8SGreg Roach public function getBlock($block_id, $template = true, $cfg = []): string { 5360084bb2SGreg Roach global $ctype, $WT_TREE; 548c2e8227SGreg Roach 55e2a378d3SGreg Roach $days = $this->getBlockSetting($block_id, 'days', '7'); 56e2a378d3SGreg Roach $infoStyle = $this->getBlockSetting($block_id, 'infoStyle', 'table'); 57e2a378d3SGreg Roach $calendar = $this->getBlockSetting($block_id, 'calendar', 'jewish'); 588c2e8227SGreg Roach 5915d603e7SGreg Roach foreach (['days', 'infoStyle', 'calendar'] as $name) { 608c2e8227SGreg Roach if (array_key_exists($name, $cfg)) { 618c2e8227SGreg Roach $$name = $cfg[$name]; 628c2e8227SGreg Roach } 638c2e8227SGreg Roach } 648c2e8227SGreg Roach 6589f721acSGreg Roach $jewish_calendar = new JewishCalendar; 668c2e8227SGreg Roach $startjd = WT_CLIENT_JD; 678c2e8227SGreg Roach $endjd = WT_CLIENT_JD + $days - 1; 688c2e8227SGreg Roach 698c2e8227SGreg Roach // The standard anniversary rules cover most of the Yahrzeit rules, we just 708c2e8227SGreg Roach // need to handle a few special cases. 7189f721acSGreg Roach // Fetch normal anniversaries, with an extra day before/after 7213abd6f3SGreg Roach $yahrzeits = []; 738c2e8227SGreg Roach for ($jd = $startjd - 1; $jd <= $endjd + $days; ++$jd) { 743d7a8a4cSGreg Roach foreach (FunctionsDb::getAnniversaryEvents($jd, 'DEAT _YART', $WT_TREE) as $fact) { 758c2e8227SGreg Roach // Exact hebrew dates only 768c2e8227SGreg Roach $date = $fact->getDate(); 778c2e8227SGreg Roach if ($date->minimumDate() instanceof JewishDate && $date->minimumJulianDay() === $date->maximumJulianDay()) { 788c2e8227SGreg Roach 7989f721acSGreg Roach // ...then adjust DEAT dates (but not _YART) 8089f721acSGreg Roach if ($fact->getTag() === 'DEAT') { 8189f721acSGreg Roach $today = new JewishDate($jd); 8289f721acSGreg Roach $hd = $fact->getDate()->minimumDate(); 838c2e8227SGreg Roach $hd1 = new JewishDate($hd); 848c2e8227SGreg Roach $hd1->y += 1; 858c2e8227SGreg Roach $hd1->setJdFromYmd(); 868c2e8227SGreg Roach // Special rules. See http://www.hebcal.com/help/anniv.html 878c2e8227SGreg Roach // Everything else is taken care of by our standard anniversary rules. 888c2e8227SGreg Roach if ($hd->d == 30 && $hd->m == 2 && $hd->y != 0 && $hd1->daysInMonth() < 30) { 898c2e8227SGreg Roach // 30 CSH - Last day in CSH 9089f721acSGreg Roach $jd = $jewish_calendar->ymdToJd($today->y, 3, 1) - 1; 918c2e8227SGreg Roach } elseif ($hd->d == 30 && $hd->m == 3 && $hd->y != 0 && $hd1->daysInMonth() < 30) { 928c2e8227SGreg Roach // 30 KSL - Last day in KSL 9389f721acSGreg Roach $jd = $jewish_calendar->ymdToJd($today->y, 4, 1) - 1; 948c2e8227SGreg Roach } elseif ($hd->d == 30 && $hd->m == 6 && $hd->y != 0 && $today->daysInMonth() < 30 && !$today->isLeapYear()) { 958c2e8227SGreg Roach // 30 ADR - Last day in SHV 9689f721acSGreg Roach $jd = $jewish_calendar->ymdToJd($today->y, 6, 1) - 1; 9789f721acSGreg Roach } 9889f721acSGreg Roach } 9989f721acSGreg Roach 10089f721acSGreg Roach // Filter adjusted dates to our date range 10189f721acSGreg Roach if ($jd >= $startjd && $jd < $startjd + $days) { 10289f721acSGreg Roach // upcomming yahrzeit dates 10389f721acSGreg Roach switch ($calendar) { 10489f721acSGreg Roach case 'gregorian': 10589f721acSGreg Roach $yahrzeit_date = new GregorianDate($jd); 10689f721acSGreg Roach break; 10789f721acSGreg Roach case 'jewish': 10889f721acSGreg Roach default: 10989f721acSGreg Roach $yahrzeit_date = new JewishDate($jd); 11089f721acSGreg Roach break; 11189f721acSGreg Roach } 11289f721acSGreg Roach $yahrzeit_date = new Date($yahrzeit_date->format('%@ %A %O %E')); 11389f721acSGreg Roach 11489f721acSGreg Roach $yahrzeits[] = (object) [ 11589f721acSGreg Roach 'individual' => $fact->getParent(), 11689f721acSGreg Roach 'fact_date' => $fact->getDate(), 11789f721acSGreg Roach 'fact' => $fact, 11889f721acSGreg Roach 'jd' => $jd, 11989f721acSGreg Roach 'yahrzeit_date' => $yahrzeit_date, 12089f721acSGreg Roach ]; 12189f721acSGreg Roach } 1228c2e8227SGreg Roach } 1238c2e8227SGreg Roach } 1248c2e8227SGreg Roach } 1258c2e8227SGreg Roach 1268c2e8227SGreg Roach switch ($infoStyle) { 1278c2e8227SGreg Roach case 'list': 12889f721acSGreg Roach $content = view('blocks/yahrzeit-list', [ 12989f721acSGreg Roach 'yahrzeits' => $yahrzeits, 13089f721acSGreg Roach ]); 1318c2e8227SGreg Roach break; 1328c2e8227SGreg Roach case 'table': 1338c2e8227SGreg Roach default: 13489f721acSGreg Roach $content = view('blocks/yahrzeit-table', [ 13589f721acSGreg Roach 'yahrzeits' => $yahrzeits, 13689f721acSGreg Roach ]); 1378c2e8227SGreg Roach break; 1388c2e8227SGreg Roach } 1398c2e8227SGreg Roach 1408c2e8227SGreg Roach if ($template) { 141*397e599aSGreg Roach if ($ctype === 'gedcom' && Auth::isManager($WT_TREE)) { 142*397e599aSGreg Roach $config_url = route('tree-page-block-edit', ['block_id' => $block_id, 'ged' => $WT_TREE->getName()]); 143*397e599aSGreg Roach } elseif ($ctype === 'user' && Auth::check()) { 144*397e599aSGreg Roach $config_url = route('user-page-block-edit', ['block_id' => $block_id, 'ged' => $WT_TREE->getName()]); 1458cbbfdceSGreg Roach } else { 1468cbbfdceSGreg Roach $config_url = ''; 1478cbbfdceSGreg Roach } 1488cbbfdceSGreg Roach 14989f721acSGreg Roach return view('blocks/template', [ 1509c6524dcSGreg Roach 'block' => str_replace('_', '-', $this->getName()), 1519c6524dcSGreg Roach 'id' => $block_id, 152f7f4b984SGreg Roach 'config_url' => $config_url, 1539c6524dcSGreg Roach 'title' => $this->getTitle(), 1549c6524dcSGreg Roach 'content' => $content, 1559c6524dcSGreg Roach ]); 1568c2e8227SGreg Roach } else { 1578c2e8227SGreg Roach return $content; 1588c2e8227SGreg Roach } 1598c2e8227SGreg Roach } 1608c2e8227SGreg Roach 1618c2e8227SGreg Roach /** {@inheritdoc} */ 162a9430be8SGreg Roach public function loadAjax(): bool { 1638c2e8227SGreg Roach return true; 1648c2e8227SGreg Roach } 1658c2e8227SGreg Roach 1668c2e8227SGreg Roach /** {@inheritdoc} */ 167a9430be8SGreg Roach public function isUserBlock(): bool { 1688c2e8227SGreg Roach return true; 1698c2e8227SGreg Roach } 1708c2e8227SGreg Roach 1718c2e8227SGreg Roach /** {@inheritdoc} */ 172a9430be8SGreg Roach public function isGedcomBlock(): bool { 1738c2e8227SGreg Roach return true; 1748c2e8227SGreg Roach } 1758c2e8227SGreg Roach 17676692c8bSGreg Roach /** 17776692c8bSGreg Roach * An HTML form to edit block settings 17876692c8bSGreg Roach * 17976692c8bSGreg Roach * @param int $block_id 180a9430be8SGreg Roach * 181a9430be8SGreg Roach * @return void 18276692c8bSGreg Roach */ 183be9a728cSGreg Roach public function configureBlock($block_id) { 1848c2e8227SGreg Roach if (Filter::postBool('save') && Filter::checkCsrf()) { 185e2a378d3SGreg Roach $this->setBlockSetting($block_id, 'days', Filter::postInteger('days', 1, 30, 7)); 186e2a378d3SGreg Roach $this->setBlockSetting($block_id, 'infoStyle', Filter::post('infoStyle', 'list|table', 'table')); 187e2a378d3SGreg Roach $this->setBlockSetting($block_id, 'calendar', Filter::post('calendar', 'jewish|gregorian', 'jewish')); 1888c2e8227SGreg Roach } 1898c2e8227SGreg Roach 190e2a378d3SGreg Roach $days = $this->getBlockSetting($block_id, 'days', '7'); 191e2a378d3SGreg Roach $infoStyle = $this->getBlockSetting($block_id, 'infoStyle', 'table'); 192e2a378d3SGreg Roach $calendar = $this->getBlockSetting($block_id, 'calendar', 'jewish'); 1938c2e8227SGreg Roach 19415d603e7SGreg Roach echo '<div class="form-group row"><label class="col-sm-3 col-form-label" for="days">'; 1958c2e8227SGreg Roach echo I18N::translate('Number of days to show'); 19615d603e7SGreg Roach echo '</label><div class="col-sm-9">'; 1978c2e8227SGreg Roach echo '<input type="text" name="days" size="2" value="' . $days . '">'; 198def7396fSGreg Roach echo ' <em>', I18N::plural('maximum %s day', 'maximum %s days', 30, I18N::number(30)), '</em>'; 19915d603e7SGreg Roach echo '</div></div>'; 2008c2e8227SGreg Roach 20115d603e7SGreg Roach echo '<div class="form-group row"><label class="col-sm-3 col-form-label" for="infoStyle">'; 2028c2e8227SGreg Roach echo I18N::translate('Presentation style'); 20315d603e7SGreg Roach echo '</label><div class="col-sm-9">'; 20415d603e7SGreg Roach echo Bootstrap4::select(['list' => I18N::translate('list'), 'table' => I18N::translate('table')], $infoStyle, ['id' => 'infoStyle', 'name' => 'infoStyle']); 20515d603e7SGreg Roach echo '</div></div>'; 2068c2e8227SGreg Roach 20715d603e7SGreg Roach echo '<div class="form-group row"><label class="col-sm-3 col-form-label" for="calendar">'; 2088c2e8227SGreg Roach echo I18N::translate('Calendar'); 20915d603e7SGreg Roach echo '</label><div class="col-sm-9">'; 21015d603e7SGreg Roach echo Bootstrap4::select(['jewish' => I18N::translate('Jewish'), 'gregorian' => I18N::translate('Gregorian')], $calendar, ['id' => 'calendar', 'name' => 'calendar']); 21115d603e7SGreg Roach echo '</div></div>'; 2128c2e8227SGreg Roach } 2138c2e8227SGreg Roach} 214