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