xref: /webtrees/app/Module/UpcomingAnniversariesModule.php (revision 4459dc9a6d0c27769f8135175f3569e4fa287451)
18c2e8227SGreg Roach<?php
28c2e8227SGreg Roach/**
38c2e8227SGreg Roach * webtrees: online genealogy
48fcd0d32SGreg Roach * Copyright (C) 2019 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 */
16e7f56f2aSGreg Roachdeclare(strict_types=1);
17e7f56f2aSGreg Roach
1876692c8bSGreg Roachnamespace Fisharebest\Webtrees\Module;
1976692c8bSGreg Roach
200e62c4b8SGreg Roachuse Fisharebest\Webtrees\Auth;
21*4459dc9aSGreg Roachuse Fisharebest\Webtrees\Carbon;
228d0ebef0SGreg Roachuse Fisharebest\Webtrees\Gedcom;
2312664b30SGreg Roachuse Fisharebest\Webtrees\GedcomTag;
240e62c4b8SGreg Roachuse Fisharebest\Webtrees\I18N;
25f0a11419SGreg Roachuse Fisharebest\Webtrees\Services\CalendarService;
26e490cd80SGreg Roachuse Fisharebest\Webtrees\Tree;
27a45f9889SGreg Roachuse Symfony\Component\HttpFoundation\Request;
288c2e8227SGreg Roach
298c2e8227SGreg Roach/**
308c2e8227SGreg Roach * Class UpcomingAnniversariesModule
318c2e8227SGreg Roach */
3237eb8894SGreg Roachclass UpcomingAnniversariesModule extends AbstractModule implements ModuleBlockInterface
33c1010edaSGreg Roach{
3449a243cbSGreg Roach    use ModuleBlockTrait;
3549a243cbSGreg Roach
36c385536dSGreg Roach    // Default values for new blocks.
3716d6367aSGreg Roach    private const DEFAULT_DAYS   = '7';
3816d6367aSGreg Roach    private const DEFAULT_FILTER = '1';
3916d6367aSGreg Roach    private const DEFAULT_SORT   = 'alpha';
4016d6367aSGreg Roach    private const DEFAULT_STYLE  = 'table';
41c385536dSGreg Roach
42c385536dSGreg Roach    // Can show this number of days into the future.
4316d6367aSGreg Roach    private const MIN_DAYS = 1;
4416d6367aSGreg Roach    private const MAX_DAYS = 30;
45c385536dSGreg Roach
4612664b30SGreg Roach    // All standard GEDCOM 5.5.1 events except CENS, RESI and EVEN
4716d6367aSGreg Roach    private const ALL_EVENTS = [
4812664b30SGreg Roach        'ADOP',
4912664b30SGreg Roach        'ANUL',
5012664b30SGreg Roach        'BAPM',
5112664b30SGreg Roach        'BARM',
5212664b30SGreg Roach        'BASM',
5312664b30SGreg Roach        'BIRT',
5412664b30SGreg Roach        'BLES',
5512664b30SGreg Roach        'BURI',
5612664b30SGreg Roach        'CHR',
5712664b30SGreg Roach        'CHRA',
5812664b30SGreg Roach        'CONF',
5912664b30SGreg Roach        'CREM',
6012664b30SGreg Roach        'DEAT',
6112664b30SGreg Roach        'DIV',
6212664b30SGreg Roach        'DIVF',
6312664b30SGreg Roach        'EMIG',
6412664b30SGreg Roach        'ENGA',
6512664b30SGreg Roach        'FCOM',
6612664b30SGreg Roach        'GRAD',
6712664b30SGreg Roach        'IMMI',
6812664b30SGreg Roach        'MARB',
6912664b30SGreg Roach        'MARC',
7012664b30SGreg Roach        'MARL',
7112664b30SGreg Roach        'MARR',
7212664b30SGreg Roach        'MARS',
7312664b30SGreg Roach        'NATU',
7412664b30SGreg Roach        'ORDN',
7512664b30SGreg Roach        'PROB',
7612664b30SGreg Roach        'RETI',
7712664b30SGreg Roach        'WILL',
7812664b30SGreg Roach    ];
7912664b30SGreg Roach
8016d6367aSGreg Roach    private const DEFAULT_EVENTS = [
8112664b30SGreg Roach        'BIRT',
8212664b30SGreg Roach        'MARR',
8312664b30SGreg Roach        'DEAT',
8412664b30SGreg Roach    ];
8512664b30SGreg Roach
8676692c8bSGreg Roach    /**
8776692c8bSGreg Roach     * How should this module be labelled on tabs, menus, etc.?
8876692c8bSGreg Roach     *
8976692c8bSGreg Roach     * @return string
9076692c8bSGreg Roach     */
9149a243cbSGreg Roach    public function title(): string
92c1010edaSGreg Roach    {
93bbb76c12SGreg Roach        /* I18N: Name of a module */
94bbb76c12SGreg Roach        return I18N::translate('Upcoming events');
958c2e8227SGreg Roach    }
968c2e8227SGreg Roach
9776692c8bSGreg Roach    /**
9876692c8bSGreg Roach     * A sentence describing what this module does.
9976692c8bSGreg Roach     *
10076692c8bSGreg Roach     * @return string
10176692c8bSGreg Roach     */
10249a243cbSGreg Roach    public function description(): string
103c1010edaSGreg Roach    {
104bbb76c12SGreg Roach        /* I18N: Description of the “Upcoming events” module */
105bbb76c12SGreg Roach        return I18N::translate('A list of the anniversaries that will occur in the near future.');
1068c2e8227SGreg Roach    }
1078c2e8227SGreg Roach
10876692c8bSGreg Roach    /**
10976692c8bSGreg Roach     * Generate the HTML content of this block.
11076692c8bSGreg Roach     *
111e490cd80SGreg Roach     * @param Tree     $tree
11276692c8bSGreg Roach     * @param int      $block_id
1135f2ae573SGreg Roach     * @param string   $ctype
114727f238cSGreg Roach     * @param string[] $cfg
11576692c8bSGreg Roach     *
11676692c8bSGreg Roach     * @return string
11776692c8bSGreg Roach     */
1185f2ae573SGreg Roach    public function getBlock(Tree $tree, int $block_id, string $ctype = '', array $cfg = []): string
119c1010edaSGreg Roach    {
120f0a11419SGreg Roach        $calendar_service = new CalendarService();
121f0a11419SGreg Roach
12212664b30SGreg Roach        $default_events = implode(',', self::DEFAULT_EVENTS);
12312664b30SGreg Roach
12476f666f4SGreg Roach        $days      = (int) $this->getBlockSetting($block_id, 'days', self::DEFAULT_DAYS);
125c385536dSGreg Roach        $filter    = (bool) $this->getBlockSetting($block_id, 'filter', self::DEFAULT_FILTER);
126c385536dSGreg Roach        $infoStyle = $this->getBlockSetting($block_id, 'infoStyle', self::DEFAULT_STYLE);
127c385536dSGreg Roach        $sortStyle = $this->getBlockSetting($block_id, 'sortStyle', self::DEFAULT_SORT);
12812664b30SGreg Roach        $events    = $this->getBlockSetting($block_id, 'events', $default_events);
1298c2e8227SGreg Roach
130c385536dSGreg Roach        extract($cfg, EXTR_OVERWRITE);
1318c2e8227SGreg Roach
13212664b30SGreg Roach        $event_array = explode(',', $events);
13312664b30SGreg Roach
13412664b30SGreg Roach        // If we are only showing living individuals, then we don't need to search for DEAT events.
13512664b30SGreg Roach        if ($filter) {
1368d0ebef0SGreg Roach            $event_array  = array_diff($event_array, Gedcom::DEATH_EVENTS);
13712664b30SGreg Roach        }
13812664b30SGreg Roach
13912664b30SGreg Roach        $events_filter = implode('|', $event_array);
14012664b30SGreg Roach
141*4459dc9aSGreg Roach        $startjd = Carbon::now()->julianDay() + 1;
142*4459dc9aSGreg Roach        $endjd   = Carbon::now()->julianDay() + $days;
14312664b30SGreg Roach
144f0a11419SGreg Roach        $facts = $calendar_service->getEventsList($startjd, $endjd, $events_filter, $filter, $sortStyle, $tree);
14512664b30SGreg Roach
14612664b30SGreg Roach        if (empty($facts)) {
147d8189b6aSDavid Drury            if ($endjd == $startjd) {
148147e99aaSGreg Roach                $content = view('modules/upcoming_events/empty', [
149c1010edaSGreg Roach                    'message' => I18N::translate('No events exist for tomorrow.'),
1500280f44aSGreg Roach                ]);
151d8189b6aSDavid Drury            } else {
152bbb76c12SGreg Roach                /* I18N: translation for %s==1 is unused; it is translated separately as “tomorrow” */                $content = view('modules/upcoming_events/empty', [
153bbb76c12SGreg 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)),
1540280f44aSGreg Roach                ]);
1558c2e8227SGreg Roach            }
156147e99aaSGreg Roach        } elseif ($infoStyle === 'list') {
157147e99aaSGreg Roach            $content = view('modules/upcoming_events/list', [
158d8189b6aSDavid Drury                'facts' => $facts,
159147e99aaSGreg Roach            ]);
160147e99aaSGreg Roach        } else {
161147e99aaSGreg Roach            $content = view('modules/upcoming_events/table', [
162147e99aaSGreg Roach                'facts' => $facts,
163147e99aaSGreg Roach            ]);
1640280f44aSGreg Roach        }
1658c2e8227SGreg Roach
1666a8879feSGreg Roach        if ($ctype !== '') {
167e490cd80SGreg Roach            if ($ctype === 'gedcom' && Auth::isManager($tree)) {
168c1010edaSGreg Roach                $config_url = route('tree-page-block-edit', [
169c1010edaSGreg Roach                    'block_id' => $block_id,
170aa6f03bbSGreg Roach                    'ged'      => $tree->name(),
171c1010edaSGreg Roach                ]);
172397e599aSGreg Roach            } elseif ($ctype === 'user' && Auth::check()) {
173c1010edaSGreg Roach                $config_url = route('user-page-block-edit', [
174c1010edaSGreg Roach                    'block_id' => $block_id,
175aa6f03bbSGreg Roach                    'ged'      => $tree->name(),
176c1010edaSGreg Roach                ]);
1778cbbfdceSGreg Roach            } else {
1788cbbfdceSGreg Roach                $config_url = '';
1798cbbfdceSGreg Roach            }
1808cbbfdceSGreg Roach
181147e99aaSGreg Roach            return view('modules/block-template', [
18226684e68SGreg Roach                'block'      => str_replace('_', '-', $this->name()),
1839c6524dcSGreg Roach                'id'         => $block_id,
1848cbbfdceSGreg Roach                'config_url' => $config_url,
18549a243cbSGreg Roach                'title'      => $this->title(),
1869c6524dcSGreg Roach                'content'    => $content,
1879c6524dcSGreg Roach            ]);
1888c2e8227SGreg Roach        }
189b2ce94c6SRico Sonntag
190b2ce94c6SRico Sonntag        return $content;
1918c2e8227SGreg Roach    }
1928c2e8227SGreg Roach
1938c2e8227SGreg Roach    /** {@inheritdoc} */
194c1010edaSGreg Roach    public function loadAjax(): bool
195c1010edaSGreg Roach    {
1968c2e8227SGreg Roach        return true;
1978c2e8227SGreg Roach    }
1988c2e8227SGreg Roach
1998c2e8227SGreg Roach    /** {@inheritdoc} */
200c1010edaSGreg Roach    public function isUserBlock(): bool
201c1010edaSGreg Roach    {
2028c2e8227SGreg Roach        return true;
2038c2e8227SGreg Roach    }
2048c2e8227SGreg Roach
2058c2e8227SGreg Roach    /** {@inheritdoc} */
20663276d8fSGreg Roach    public function isTreeBlock(): bool
207c1010edaSGreg Roach    {
2088c2e8227SGreg Roach        return true;
2098c2e8227SGreg Roach    }
2108c2e8227SGreg Roach
21176692c8bSGreg Roach    /**
212a45f9889SGreg Roach     * Update the configuration for a block.
213a45f9889SGreg Roach     *
214a45f9889SGreg Roach     * @param Request $request
215a45f9889SGreg Roach     * @param int     $block_id
216a45f9889SGreg Roach     *
217a45f9889SGreg Roach     * @return void
218a45f9889SGreg Roach     */
219a45f9889SGreg Roach    public function saveBlockConfiguration(Request $request, int $block_id)
220a45f9889SGreg Roach    {
221a45f9889SGreg Roach        $this->setBlockSetting($block_id, 'days', $request->get('days', self::DEFAULT_DAYS));
222a45f9889SGreg Roach        $this->setBlockSetting($block_id, 'filter', $request->get('filter', ''));
223a45f9889SGreg Roach        $this->setBlockSetting($block_id, 'infoStyle', $request->get('infoStyle', self::DEFAULT_STYLE));
224a45f9889SGreg Roach        $this->setBlockSetting($block_id, 'sortStyle', $request->get('sortStyle', self::DEFAULT_SORT));
225a45f9889SGreg Roach        $this->setBlockSetting($block_id, 'events', implode(',', (array) $request->get('events')));
226a45f9889SGreg Roach    }
227a45f9889SGreg Roach
228a45f9889SGreg Roach    /**
22976692c8bSGreg Roach     * An HTML form to edit block settings
23076692c8bSGreg Roach     *
231e490cd80SGreg Roach     * @param Tree $tree
23276692c8bSGreg Roach     * @param int  $block_id
233a9430be8SGreg Roach     *
234a9430be8SGreg Roach     * @return void
23576692c8bSGreg Roach     */
236a45f9889SGreg Roach    public function editBlockConfiguration(Tree $tree, int $block_id)
237c1010edaSGreg Roach    {
23812664b30SGreg Roach        $default_events = implode(',', self::DEFAULT_EVENTS);
23912664b30SGreg Roach
24076f666f4SGreg Roach        $days      = (int) $this->getBlockSetting($block_id, 'days', self::DEFAULT_DAYS);
241c385536dSGreg Roach        $filter    = $this->getBlockSetting($block_id, 'filter', self::DEFAULT_FILTER);
242c385536dSGreg Roach        $infoStyle = $this->getBlockSetting($block_id, 'infoStyle', self::DEFAULT_STYLE);
243c385536dSGreg Roach        $sortStyle = $this->getBlockSetting($block_id, 'sortStyle', self::DEFAULT_SORT);
24412664b30SGreg Roach        $events    = $this->getBlockSetting($block_id, 'events', $default_events);
2458c2e8227SGreg Roach
24612664b30SGreg Roach        $event_array = explode(',', $events);
24712664b30SGreg Roach
24812664b30SGreg Roach        $all_events = [];
24912664b30SGreg Roach        foreach (self::ALL_EVENTS as $event) {
25012664b30SGreg Roach            $all_events[$event] = GedcomTag::getLabel($event);
25112664b30SGreg Roach        }
25212664b30SGreg Roach
253c385536dSGreg Roach        $info_styles = [
254bbb76c12SGreg Roach            /* I18N: An option in a list-box */
255bbb76c12SGreg Roach            'list'  => I18N::translate('list'),
256bbb76c12SGreg Roach            /* I18N: An option in a list-box */
257bbb76c12SGreg Roach            'table' => I18N::translate('table'),
258c385536dSGreg Roach        ];
2598c2e8227SGreg Roach
260c385536dSGreg Roach        $sort_styles = [
261bbb76c12SGreg Roach            /* I18N: An option in a list-box */
262bbb76c12SGreg Roach            'alpha' => I18N::translate('sort by name'),
263bbb76c12SGreg Roach            /* I18N: An option in a list-box */
264bbb76c12SGreg Roach            'anniv' => I18N::translate('sort by date'),
265c385536dSGreg Roach        ];
2668c2e8227SGreg Roach
267147e99aaSGreg Roach        echo view('modules/upcoming_events/config', [
268c385536dSGreg Roach            'all_events'  => $all_events,
269c385536dSGreg Roach            'days'        => $days,
270c385536dSGreg Roach            'event_array' => $event_array,
271c385536dSGreg Roach            'filter'      => $filter,
272c385536dSGreg Roach            'infoStyle'   => $infoStyle,
273c385536dSGreg Roach            'info_styles' => $info_styles,
274c385536dSGreg Roach            'max_days'    => self::MAX_DAYS,
275c385536dSGreg Roach            'sortStyle'   => $sortStyle,
276c385536dSGreg Roach            'sort_styles' => $sort_styles,
277c385536dSGreg Roach        ]);
2788c2e8227SGreg Roach    }
2798c2e8227SGreg Roach}
280