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