xref: /webtrees/app/Module/UpcomingAnniversariesModule.php (revision 397e599a3131684b8a335ebfddcfe63828b9f51b)
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;
1915d603e7SGreg Roachuse Fisharebest\Webtrees\Bootstrap4;
200e62c4b8SGreg Roachuse Fisharebest\Webtrees\Filter;
21d8189b6aSDavid Druryuse Fisharebest\Webtrees\Functions\FunctionsDB;
223d7a8a4cSGreg Roachuse Fisharebest\Webtrees\Functions\FunctionsEdit;
2312664b30SGreg Roachuse Fisharebest\Webtrees\GedcomTag;
248cbbfdceSGreg Roachuse Fisharebest\Webtrees\Html;
250e62c4b8SGreg Roachuse Fisharebest\Webtrees\I18N;
268c2e8227SGreg Roach
278c2e8227SGreg Roach/**
288c2e8227SGreg Roach * Class UpcomingAnniversariesModule
298c2e8227SGreg Roach */
30e2a378d3SGreg Roachclass UpcomingAnniversariesModule extends AbstractModule implements ModuleBlockInterface {
3112664b30SGreg Roach	// All standard GEDCOM 5.5.1 events except CENS, RESI and EVEN
3212664b30SGreg Roach	const ALL_EVENTS = [
3312664b30SGreg Roach		'ADOP',
3412664b30SGreg Roach		'ANUL',
3512664b30SGreg Roach		'BAPM',
3612664b30SGreg Roach		'BARM',
3712664b30SGreg Roach		'BASM',
3812664b30SGreg Roach		'BIRT',
3912664b30SGreg Roach		'BLES',
4012664b30SGreg Roach		'BURI',
4112664b30SGreg Roach		'CHR',
4212664b30SGreg Roach		'CHRA',
4312664b30SGreg Roach		'CONF',
4412664b30SGreg Roach		'CREM',
4512664b30SGreg Roach		'DEAT',
4612664b30SGreg Roach		'DIV',
4712664b30SGreg Roach		'DIVF',
4812664b30SGreg Roach		'EMIG',
4912664b30SGreg Roach		'ENGA',
5012664b30SGreg Roach		'FCOM',
5112664b30SGreg Roach		'GRAD',
5212664b30SGreg Roach		'IMMI',
5312664b30SGreg Roach		'MARB',
5412664b30SGreg Roach		'MARC',
5512664b30SGreg Roach		'MARL',
5612664b30SGreg Roach		'MARR',
5712664b30SGreg Roach		'MARS',
5812664b30SGreg Roach		'NATU',
5912664b30SGreg Roach		'ORDN',
6012664b30SGreg Roach		'PROB',
6112664b30SGreg Roach		'RETI',
6212664b30SGreg Roach		'WILL',
6312664b30SGreg Roach	];
6412664b30SGreg Roach
6512664b30SGreg Roach	const DEFAULT_EVENTS = [
6612664b30SGreg Roach		'BIRT',
6712664b30SGreg Roach		'MARR',
6812664b30SGreg Roach		'DEAT',
6912664b30SGreg Roach	];
7012664b30SGreg Roach
7176692c8bSGreg Roach	/**
7276692c8bSGreg Roach	 * How should this module be labelled on tabs, menus, etc.?
7376692c8bSGreg Roach	 *
7476692c8bSGreg Roach	 * @return string
7576692c8bSGreg Roach	 */
768c2e8227SGreg Roach	public function getTitle() {
778c2e8227SGreg Roach		return /* I18N: Name of a module */ I18N::translate('Upcoming events');
788c2e8227SGreg Roach	}
798c2e8227SGreg Roach
8076692c8bSGreg Roach	/**
8176692c8bSGreg Roach	 * A sentence describing what this module does.
8276692c8bSGreg Roach	 *
8376692c8bSGreg Roach	 * @return string
8476692c8bSGreg Roach	 */
858c2e8227SGreg Roach	public function getDescription() {
868c2e8227SGreg Roach		return /* I18N: Description of the “Upcoming events” module */ I18N::translate('A list of the anniversaries that will occur in the near future.');
878c2e8227SGreg Roach	}
888c2e8227SGreg Roach
8976692c8bSGreg Roach	/**
9076692c8bSGreg Roach	 * Generate the HTML content of this block.
9176692c8bSGreg Roach	 *
9276692c8bSGreg Roach	 * @param int      $block_id
9376692c8bSGreg Roach	 * @param bool     $template
94727f238cSGreg Roach	 * @param string[] $cfg
9576692c8bSGreg Roach	 *
9676692c8bSGreg Roach	 * @return string
9776692c8bSGreg Roach	 */
98a9430be8SGreg Roach	public function getBlock($block_id, $template = true, $cfg = []): string {
994b9ff166SGreg Roach		global $ctype, $WT_TREE;
1008c2e8227SGreg Roach
10112664b30SGreg Roach		$default_events = implode(',', self::DEFAULT_EVENTS);
10212664b30SGreg Roach
103e2a378d3SGreg Roach		$days      = $this->getBlockSetting($block_id, 'days', '7');
104d8189b6aSDavid Drury		$filter    = (bool) $this->getBlockSetting($block_id, 'filter', '1');
105e2a378d3SGreg Roach		$infoStyle = $this->getBlockSetting($block_id, 'infoStyle', 'table');
106e2a378d3SGreg Roach		$sortStyle = $this->getBlockSetting($block_id, 'sortStyle', 'alpha');
10712664b30SGreg Roach		$events    = $this->getBlockSetting($block_id, 'events', $default_events);
1088c2e8227SGreg Roach
10912664b30SGreg Roach		foreach (['days', 'events', 'filter', 'infoStyle', 'sortStyle'] as $name) {
1108c2e8227SGreg Roach			if (array_key_exists($name, $cfg)) {
1118c2e8227SGreg Roach				$$name = $cfg[$name];
1128c2e8227SGreg Roach			}
1138c2e8227SGreg Roach		}
1148c2e8227SGreg Roach
11512664b30SGreg Roach		$event_array = explode(',', $events);
11612664b30SGreg Roach
11712664b30SGreg Roach		// If we are only showing living individuals, then we don't need to search for DEAT events.
11812664b30SGreg Roach		if ($filter) {
11912664b30SGreg Roach			$death_events = explode('|', WT_EVENTS_DEAT);
12012664b30SGreg Roach			$event_array = array_diff($event_array, $death_events);
12112664b30SGreg Roach		}
12212664b30SGreg Roach
12312664b30SGreg Roach		$events_filter = implode('|', $event_array);
12412664b30SGreg Roach
1258c2e8227SGreg Roach		$startjd = WT_CLIENT_JD + 1;
1268c2e8227SGreg Roach		$endjd   = WT_CLIENT_JD + $days;
12712664b30SGreg Roach
12812664b30SGreg Roach		$facts = FunctionsDB::getEventsList($startjd, $endjd, $events_filter, $filter, $sortStyle, $WT_TREE);
12912664b30SGreg Roach
130d8189b6aSDavid Drury		$summary = '';
1318c2e8227SGreg Roach
13212664b30SGreg Roach		if (empty($facts)) {
133d8189b6aSDavid Drury			if ($filter) {
134d8189b6aSDavid Drury				if ($endjd == $startjd) {
135d8189b6aSDavid Drury					$summary = I18N::translate('No events for living individuals exist for tomorrow.');
136d8189b6aSDavid Drury				} else {
137d8189b6aSDavid Drury					// I18N: translation for %s==1 is unused; it is translated separately as “tomorrow”
138d8189b6aSDavid Drury					$summary = I18N::plural('No events for living people exist for the next %s day.', 'No events for living people exist for the next %s days.', $endjd - $startjd + 1, I18N::number($endjd - $startjd + 1));
1398c2e8227SGreg Roach				}
140d8189b6aSDavid Drury			} else {
141d8189b6aSDavid Drury				if ($endjd == $startjd) {
142d8189b6aSDavid Drury					$summary = I18N::translate('No events exist for tomorrow.');
143d8189b6aSDavid Drury				} else {
144d8189b6aSDavid Drury					// I18N: translation for %s==1 is unused; it is translated separately as “tomorrow”
145d8189b6aSDavid Drury					$summary = 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));
146d8189b6aSDavid Drury				}
147d8189b6aSDavid Drury			}
148d8189b6aSDavid Drury		}
149d8189b6aSDavid Drury
150d8189b6aSDavid Drury		$content = view('blocks/events-' . $infoStyle, [
151d8189b6aSDavid Drury				'facts'   => $facts,
152d8189b6aSDavid Drury				'summary' => $summary,
153d8189b6aSDavid Drury			]
154d8189b6aSDavid Drury		);
1558c2e8227SGreg Roach
1568c2e8227SGreg Roach		if ($template) {
157*397e599aSGreg Roach			if ($ctype === 'gedcom' && Auth::isManager($WT_TREE)) {
158*397e599aSGreg Roach				$config_url = route('tree-page-block-edit', ['block_id' => $block_id, 'ged' => $WT_TREE->getName()]);
159*397e599aSGreg Roach			} elseif ($ctype === 'user' && Auth::check()) {
160*397e599aSGreg Roach				$config_url = route('user-page-block-edit', ['block_id' => $block_id, 'ged' => $WT_TREE->getName()]);
1618cbbfdceSGreg Roach			} else {
1628cbbfdceSGreg Roach				$config_url = '';
1638cbbfdceSGreg Roach			}
1648cbbfdceSGreg Roach
165225e381fSGreg Roach			return view('blocks/template', [
1669c6524dcSGreg Roach				'block'      => str_replace('_', '-', $this->getName()),
1679c6524dcSGreg Roach				'id'         => $block_id,
1688cbbfdceSGreg Roach				'config_url' => $config_url,
1699c6524dcSGreg Roach				'title'      => $this->getTitle(),
1709c6524dcSGreg Roach				'content'    => $content,
1719c6524dcSGreg Roach			]);
1728c2e8227SGreg Roach		} else {
1738c2e8227SGreg Roach			return $content;
1748c2e8227SGreg Roach		}
1758c2e8227SGreg Roach	}
1768c2e8227SGreg Roach
1778c2e8227SGreg Roach	/** {@inheritdoc} */
178a9430be8SGreg Roach	public function loadAjax(): bool {
1798c2e8227SGreg Roach		return true;
1808c2e8227SGreg Roach	}
1818c2e8227SGreg Roach
1828c2e8227SGreg Roach	/** {@inheritdoc} */
183a9430be8SGreg Roach	public function isUserBlock(): bool {
1848c2e8227SGreg Roach		return true;
1858c2e8227SGreg Roach	}
1868c2e8227SGreg Roach
1878c2e8227SGreg Roach	/** {@inheritdoc} */
188a9430be8SGreg Roach	public function isGedcomBlock(): bool {
1898c2e8227SGreg Roach		return true;
1908c2e8227SGreg Roach	}
1918c2e8227SGreg Roach
19276692c8bSGreg Roach	/**
19376692c8bSGreg Roach	 * An HTML form to edit block settings
19476692c8bSGreg Roach	 *
19576692c8bSGreg Roach	 * @param int $block_id
196a9430be8SGreg Roach	 *
197a9430be8SGreg Roach	 * @return void
19876692c8bSGreg Roach	 */
199be9a728cSGreg Roach	public function configureBlock($block_id) {
2008c2e8227SGreg Roach		if (Filter::postBool('save') && Filter::checkCsrf()) {
201e2a378d3SGreg Roach			$this->setBlockSetting($block_id, 'days', Filter::postInteger('days', 1, 30, 7));
202e2a378d3SGreg Roach			$this->setBlockSetting($block_id, 'filter', Filter::postBool('filter'));
203e2a378d3SGreg Roach			$this->setBlockSetting($block_id, 'infoStyle', Filter::post('infoStyle', 'list|table', 'table'));
204e2a378d3SGreg Roach			$this->setBlockSetting($block_id, 'sortStyle', Filter::post('sortStyle', 'alpha|anniv', 'alpha'));
20512664b30SGreg Roach			$this->setBlockSetting($block_id, 'events', implode(',', Filter::postArray('events')));
2068c2e8227SGreg Roach		}
2078c2e8227SGreg Roach
20812664b30SGreg Roach		$default_events = implode(',', self::DEFAULT_EVENTS);
20912664b30SGreg Roach
210e2a378d3SGreg Roach		$days      = $this->getBlockSetting($block_id, 'days', '7');
211e2a378d3SGreg Roach		$filter    = $this->getBlockSetting($block_id, 'filter', '1');
212e2a378d3SGreg Roach		$infoStyle = $this->getBlockSetting($block_id, 'infoStyle', 'table');
213e2a378d3SGreg Roach		$sortStyle = $this->getBlockSetting($block_id, 'sortStyle', 'alpha');
21412664b30SGreg Roach		$events    = $this->getBlockSetting($block_id, 'events', $default_events);
2158c2e8227SGreg Roach
21612664b30SGreg Roach		$event_array = explode(',', $events);
21712664b30SGreg Roach
21812664b30SGreg Roach		$all_events = [];
21912664b30SGreg Roach		foreach (self::ALL_EVENTS as $event) {
22012664b30SGreg Roach			$all_events[$event] = GedcomTag::getLabel($event);
22112664b30SGreg Roach		}
22215d603e7SGreg Roach		?>
22312664b30SGreg Roach
22415d603e7SGreg Roach		<div class="form-group row">
22515d603e7SGreg Roach			<label class="col-sm-3 col-form-label" for="days">
22615d603e7SGreg Roach				<?= I18N::translate('Number of days to show') ?>
22715d603e7SGreg Roach			</label>
22815d603e7SGreg Roach			<div class="col-sm-9">
22915d603e7SGreg Roach				<input type="text" name="days" id="days" size="2" value="<?= $days ?>">
23015d603e7SGreg Roach				<?= I18N::plural('maximum %s day', 'maximum %s days', 30, I18N::number(30)) ?>
23115d603e7SGreg Roach			</div>
23215d603e7SGreg Roach		</div>
2338c2e8227SGreg Roach
23415d603e7SGreg Roach		<div class="form-group row">
23515d603e7SGreg Roach			<label class="col-sm-3 col-form-label" for="filter">
23615d603e7SGreg Roach				<?= I18N::translate('Show only events of living individuals') ?>
23715d603e7SGreg Roach			</label>
23815d603e7SGreg Roach			<div class="col-sm-9">
23915d603e7SGreg Roach				<?= Bootstrap4::radioButtons('filter', FunctionsEdit::optionsNoYes(), $filter, true) ?>
24015d603e7SGreg Roach			</div>
24115d603e7SGreg Roach		</div>
2428c2e8227SGreg Roach
24315d603e7SGreg Roach		<div class="form-group row">
24412664b30SGreg Roach			<label class="col-sm-3 col-form-label" for="events">
24512664b30SGreg Roach				<?= I18N::translate('Events') ?>
24615d603e7SGreg Roach			</label>
24715d603e7SGreg Roach			<div class="col-sm-9">
24812664b30SGreg Roach				<?= Bootstrap4::multiSelect($all_events, $event_array, ['id' => 'events', 'name' => 'events[]', 'class' => 'select2']) ?>
24915d603e7SGreg Roach			</div>
25015d603e7SGreg Roach		</div>
2518c2e8227SGreg Roach
25215d603e7SGreg Roach		<div class="form-group row">
25315d603e7SGreg Roach			<label class="col-sm-3 col-form-label" for="infoStyle">
25412664b30SGreg Roach				<?= /* I18N: Label for a configuration option */ I18N::translate('Presentation style') ?>
25515d603e7SGreg Roach			</label>
25615d603e7SGreg Roach			<div class="col-sm-9">
25715d603e7SGreg Roach				<?= Bootstrap4::select(['list' => I18N::translate('list'), 'table' => I18N::translate('table')], $infoStyle, ['id' => 'infoStyle', 'name' => 'infoStyle']) ?>
25815d603e7SGreg Roach			</div>
25915d603e7SGreg Roach		</div>
2608c2e8227SGreg Roach
26115d603e7SGreg Roach		<div class="form-group row">
26215d603e7SGreg Roach			<label class="col-sm-3 col-form-label" for="sortStyle">
26312664b30SGreg Roach				<?= /* I18N: Label for a configuration option */ I18N::translate('Sort order') ?>
26415d603e7SGreg Roach			</label>
26515d603e7SGreg Roach			<div class="col-sm-9">
26612664b30SGreg Roach				<?= Bootstrap4::select(['alpha' => /* I18N: An option in a list-box */ I18N::translate('sort by name'), 'anniv' => /* I18N: An option in a list-box */ I18N::translate('sort by date')], $sortStyle, ['id' => 'sortStyle', 'name' => 'sortStyle']) ?>
26715d603e7SGreg Roach			</div>
26815d603e7SGreg Roach		</div>
26915d603e7SGreg Roach		<?php
2708c2e8227SGreg Roach	}
2718c2e8227SGreg Roach}
272