xref: /webtrees/app/Http/RequestHandlers/HelpText.php (revision 99125a335d0be11b975e213c69fc4ede0c5303f1)
1<?php
2
3/**
4 * webtrees: online genealogy
5 * Copyright (C) 2021 webtrees development team
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <https://www.gnu.org/licenses/>.
16 */
17
18declare(strict_types=1);
19
20namespace Fisharebest\Webtrees\Http\RequestHandlers;
21
22use Fisharebest\Webtrees\Auth;
23use Fisharebest\Webtrees\Date;
24use Fisharebest\Webtrees\I18N;
25use Fisharebest\Webtrees\Services\LocalizationService;
26use Psr\Http\Message\ResponseInterface;
27use Psr\Http\Message\ServerRequestInterface;
28use Psr\Http\Server\RequestHandlerInterface;
29
30use function array_keys;
31use function response;
32use function strip_tags;
33use function view;
34
35/**
36 * Show help text.
37 */
38class HelpText implements RequestHandlerInterface
39{
40    private const FRENCH_DATES = [
41        '@#DFRENCH R@ 12',
42        '@#DFRENCH R@ VEND 12',
43        'ABT @#DFRENCH R@ BRUM 12',
44        'BET @#DFRENCH R@ FRIM 12 AND @#DFRENCH R@ NIVO 12',
45        'FROM @#DFRENCH R@ PLUV 12 TO @#DFRENCH R@ VENT 12',
46        'AFT @#DFRENCH R@ GERM 12',
47        'BEF @#DFRENCH R@ FLOR 12',
48        'ABT @#DFRENCH R@ PRAI 12',
49        'FROM @#DFRENCH R@ MESS 12',
50        'TO @#DFRENCH R@ THER 12',
51        'EST @#DFRENCH R@ FRUC 12',
52        '@#DFRENCH R@ 03 COMP 12',
53    ];
54
55    private const HIJRI_DATES = [
56        '@#DHIJRI@ 1497',
57        '@#DHIJRI@ MUHAR 1497',
58        'ABT @#DHIJRI@ SAFAR 1497',
59        'BET @#DHIJRI@ RABIA 1497 AND @#DHIJRI@ RABIT 1497',
60        'FROM @#DHIJRI@ JUMAA 1497 TO @#DHIJRI@ JUMAT 1497',
61        'AFT @#DHIJRI@ RAJAB 1497',
62        'BEF @#DHIJRI@ SHAAB 1497',
63        'ABT @#DHIJRI@ RAMAD 1497',
64        'FROM @#DHIJRI@ SHAWW 1497',
65        'TO @#DHIJRI@ DHUAQ 1497',
66        '@#DHIJRI@ 03 DHUAH 1497',
67    ];
68
69    private const JEWISH_DATES = [
70        '@#DHEBREW@ 5481',
71        '@#DHEBREW@ TSH 5481',
72        'ABT @#DHEBREW@ CSH 5481',
73        'BET @#DHEBREW@ KSL 5481 AND @#DHEBREW@ TVT 5481',
74        'FROM @#DHEBREW@ SHV 5481 TO @#DHEBREW@ ADR 5481',
75        'AFT @#DHEBREW@ ADR 5481',
76        'AFT @#DHEBREW@ ADS 5480',
77        'BEF @#DHEBREW@ NSN 5481',
78        'ABT @#DHEBREW@ IYR 5481',
79        'FROM @#DHEBREW@ SVN 5481',
80        'TO @#DHEBREW@ TMZ 5481',
81        'EST @#DHEBREW@ AAV 5481',
82        '@#DHEBREW@ 03 ELL 5481',
83    ];
84
85    private const JULIAN_DATES = [
86        '@#DJULIAN@ 14 JAN 1700',
87        '@#DJULIAN@ 44 B.C.',
88        '@#DJULIAN@ 20 FEB 1742/43',
89        'BET @#DJULIAN@ 01 SEP 1752 AND @#DGREGORIAN@ 30 SEP 1752',
90    ];
91
92    private const DATE_SHORTCUTS = [
93        '1900'           => [],
94        'JAN 1900'       => [],
95        'FEB 1900'       => [],
96        'MAR 1900'       => [],
97        'APR 1900'       => [],
98        'MAY 1900'       => [],
99        'JUN 1900'       => [],
100        'JUL 1900'       => [],
101        'AUG 1900'       => [],
102        'SEP 1900'       => [],
103        'OCT 1900'       => [],
104        'NOV 1900'       => [],
105        'DEC 1900'       => [],
106        'ABT 1900'       => ['~1900'],
107        'EST 1900'       => ['*1900'],
108        'CAL 1900'       => ['#1900'],
109        'INT 1900 (...)' => [],
110    ];
111
112    private const DATE_RANGE_SHORTCUTS = [
113        'BET 1900 AND 1910'         => ['1900-1910'],
114        'AFT 1900'                  => ['>1900'],
115        'BEF 1910'                  => ['<1910'],
116        'BET JAN 1900 AND MAR 1900' => ['Q1 1900'],
117        'BET APR 1900 AND JUN 1900' => ['Q2 1900'],
118        'BET JUL 1900 AND SEP 1900' => ['Q3 1900'],
119        'BET OCT 1900 AND DEC 1900' => ['Q4 1900'],
120    ];
121
122    private const DATE_PERIOD_SHORTCUTS = [
123        'FROM 1900 TO 1910' => ['1900~1910'],
124        'FROM 1900'         => ['1900-'],
125        'TO 1910'           => ['-1900'],
126    ];
127
128    private const DMY_SHORTCUTS = [
129        '11 DEC 1913' => [
130            '11/12/1913',
131            '11-12-1913',
132            '11.12.1913',
133        ],
134        '01 FEB 2003' => [
135            '01/02/03',
136            '01-02-03',
137            '01.02.03',
138        ],
139    ];
140
141    private const MDY_SHORTCUTS = [
142        '11 DEC 1913' => [
143            '12/11/1913',
144            '12-11-1913',
145            '12.11.1913',
146        ],
147        '01 FEB 2003' => [
148            '02/01/03',
149            '02-01-03',
150            '02.01.03',
151        ],
152    ];
153
154    private const YMD_SHORTCUTS = [
155        '11 DEC 1913' => [
156            '11/12/1913',
157            '11-12-1913',
158            '11.12.1913',
159        ],
160        '01 FEB 2003' => [
161            '03/02/01',
162            '03-02-01',
163            '03.02.01',
164        ],
165    ];
166
167    private LocalizationService $localisation_service;
168
169    /**
170     * HelpText constructor.
171     *
172     * @param LocalizationService $localization_service
173     */
174    public function __construct(LocalizationService $localization_service)
175    {
176        $this->localisation_service = $localization_service;
177    }
178
179    /**
180     * @param ServerRequestInterface $request
181     *
182     * @return ResponseInterface
183     */
184    public function handle(ServerRequestInterface $request): ResponseInterface
185    {
186        $topic = $request->getAttribute('topic');
187
188        $dmy = $this->localisation_service->dateFormatToOrder(I18N::dateFormat());
189
190        switch ($topic) {
191            case 'DATE':
192                switch ($dmy) {
193                    case 'YMD':
194                        $date_shortcuts = self::DATE_SHORTCUTS + self::YMD_SHORTCUTS;
195                        break;
196                    case 'MDY':
197                        $date_shortcuts = self::DATE_SHORTCUTS + self::MDY_SHORTCUTS;
198                        break;
199                    case 'DMY':
200                    default:
201                        $date_shortcuts = self::DATE_SHORTCUTS + self::DMY_SHORTCUTS;
202                        break;
203                }
204
205                $title = I18N::translate('Date');
206                $text  = view('help/date', [
207                    'date_dates'            => $this->formatDates(array_keys($date_shortcuts)),
208                    'date_shortcuts'        => $date_shortcuts,
209                    'date_period_dates'     => $this->formatDates(array_keys(self::DATE_PERIOD_SHORTCUTS)),
210                    'date_period_shortcuts' => self::DATE_PERIOD_SHORTCUTS,
211                    'date_range_dates'      => $this->formatDates(array_keys(self::DATE_RANGE_SHORTCUTS)),
212                    'date_range_shortcuts'  => self::DATE_RANGE_SHORTCUTS,
213                    'french_dates'          => $this->formatDates(self::FRENCH_DATES),
214                    'hijri_dates'           => $this->formatDates(self::HIJRI_DATES),
215                    'jewish_dates'          => $this->formatDates(self::JEWISH_DATES),
216                    'julian_dates'          => $this->formatDates(self::JULIAN_DATES),
217                ]);
218                break;
219
220            case 'NAME':
221                $title = I18N::translate('Name');
222                $text  = view('help/name');
223                break;
224
225            case 'SURN':
226                $title = I18N::translate('Surname');
227                $text  = view('help/surname');
228                break;
229
230            case 'OBJE':
231                $title = I18N::translate('Media object');
232                $text  = view('help/media-object');
233                break;
234
235            case 'PLAC':
236                $title = I18N::translate('Place');
237                $text  = view('help/place');
238                break;
239
240            case 'RESN':
241                $title = I18N::translate('Restriction');
242                $text  = view('help/restriction');
243                break;
244
245            case 'ROMN':
246                $title = I18N::translate('Romanized');
247                $text  = view('help/romanized');
248                break;
249
250            case '_HEB':
251                $title = I18N::translate('Hebrew');
252                $text  = view('help/hebrew');
253                break;
254
255            case 'data-fixes':
256                $title = I18N::translate('Data fixes');
257                $text  = view('help/data-fixes');
258                break;
259
260            case 'edit_SOUR_EVEN':
261                $title = I18N::translate('Associate events with this source');
262                $text  = view('help/source-events');
263                break;
264
265            case 'pending_changes':
266                $title = I18N::translate('Pending changes');
267                $text  = view('help/pending-changes', [
268                    'is_admin' => Auth::isAdmin(),
269                ]);
270                break;
271
272            case 'relationship-privacy':
273                $title = I18N::translate('Restrict to immediate family');
274                $text  = view('help/relationship-privacy');
275                break;
276
277            case 'iso-8859-1':
278                $title = I18N::translate('Convert from UTF-8 to ISO-8859-1');
279                $text  = view('help/iso-8859-1');
280                break;
281
282            case 'zip-gedcom':
283                $title = I18N::translate('Compress the GEDCOM file');
284                $text  = view('help/zip-gedcom');
285                break;
286
287            default:
288                $title = I18N::translate('Help');
289                $text  = I18N::translate('The help text has not been written for this item.');
290                break;
291        }
292
293        $html = view('modals/help', [
294            'title' => $title,
295            'text'  => $text,
296        ]);
297
298        return response($html);
299    }
300
301    /**
302     * Format GEDCOM dates in the local language.
303     *
304     * @param string[]|int[] $gedcom_dates
305     *
306     * @return array<string>
307     */
308    private function formatDates(array $gedcom_dates): array
309    {
310        $dates = [];
311
312        foreach ($gedcom_dates as $gedcom_date) {
313            // PHP converts numeric array keys ('1900') to integers (1900), so reverse this.
314            $gedcom_date = (string) $gedcom_date;
315
316            $date                = new Date($gedcom_date);
317            $dates[$gedcom_date] = strip_tags($date->display(false, null, false));
318        }
319
320        return $dates;
321    }
322}
323