xref: /webtrees/app/Module/ModuleLanguageTrait.php (revision e873f434551745f888937263ff89e80db3b0f785)
1<?php
2
3/**
4 * webtrees: online genealogy
5 * Copyright (C) 2023 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\Module;
21
22use Fisharebest\ExtCalendar\CalendarInterface;
23use Fisharebest\ExtCalendar\GregorianCalendar;
24use Fisharebest\Localization\Locale\LocaleEnUs;
25use Fisharebest\Localization\Locale\LocaleInterface;
26use Fisharebest\Webtrees\I18N;
27use Fisharebest\Webtrees\Relationship;
28use Normalizer;
29
30use function mb_substr;
31use function normalizer_normalize;
32
33/**
34 * Trait ModuleLanguageEventsTrait - default implementation of ModuleLanguageInterface.
35 */
36trait ModuleLanguageTrait
37{
38    /** @var array<string,string> */
39    private array $combining_diacritics = [
40        "\u{0300}" => '',
41        "\u{0301}" => '',
42        "\u{0302}" => '',
43        "\u{0303}" => '',
44        "\u{0304}" => '',
45        "\u{0305}" => '',
46        "\u{0306}" => '',
47        "\u{0307}" => '',
48        "\u{0308}" => '',
49        "\u{0309}" => '',
50        "\u{030A}" => '',
51        "\u{030B}" => '',
52        "\u{030C}" => '',
53        "\u{030D}" => '',
54        "\u{030E}" => '',
55        "\u{030F}" => '',
56        "\u{0310}" => '',
57        "\u{0311}" => '',
58        "\u{0312}" => '',
59        "\u{0313}" => '',
60        "\u{0314}" => '',
61        "\u{0315}" => '',
62        "\u{0316}" => '',
63        "\u{0317}" => '',
64        "\u{0318}" => '',
65        "\u{0319}" => '',
66        "\u{031A}" => '',
67        "\u{031B}" => '',
68        "\u{031C}" => '',
69        "\u{031D}" => '',
70        "\u{031E}" => '',
71        "\u{031F}" => '',
72        "\u{0320}" => '',
73        "\u{0321}" => '',
74        "\u{0322}" => '',
75        "\u{0323}" => '',
76        "\u{0324}" => '',
77        "\u{0325}" => '',
78        "\u{0326}" => '',
79        "\u{0327}" => '',
80        "\u{0328}" => '',
81        "\u{0329}" => '',
82        "\u{032A}" => '',
83        "\u{032B}" => '',
84        "\u{032C}" => '',
85        "\u{032D}" => '',
86        "\u{032E}" => '',
87        "\u{032F}" => '',
88        "\u{0330}" => '',
89        "\u{0331}" => '',
90        "\u{0332}" => '',
91        "\u{0333}" => '',
92        "\u{0334}" => '',
93        "\u{0335}" => '',
94        "\u{0336}" => '',
95        "\u{0337}" => '',
96        "\u{0338}" => '',
97        "\u{0339}" => '',
98        "\u{033A}" => '',
99        "\u{033B}" => '',
100        "\u{033C}" => '',
101        "\u{033D}" => '',
102        "\u{033E}" => '',
103        "\u{033F}" => '',
104        "\u{0340}" => '',
105        "\u{0341}" => '',
106        "\u{0342}" => '',
107        "\u{0343}" => '',
108        "\u{0344}" => '',
109        "\u{0345}" => '',
110        "\u{0346}" => '',
111        "\u{0347}" => '',
112        "\u{0348}" => '',
113        "\u{0349}" => '',
114        "\u{034A}" => '',
115        "\u{034B}" => '',
116        "\u{034C}" => '',
117        "\u{034D}" => '',
118        "\u{034E}" => '',
119        "\u{034F}" => '',
120        "\u{0350}" => '',
121        "\u{0351}" => '',
122        "\u{0352}" => '',
123        "\u{0353}" => '',
124        "\u{0354}" => '',
125        "\u{0355}" => '',
126        "\u{0356}" => '',
127        "\u{0357}" => '',
128        "\u{0358}" => '',
129        "\u{0359}" => '',
130        "\u{035A}" => '',
131        "\u{035B}" => '',
132        "\u{035C}" => '',
133        "\u{035D}" => '',
134        "\u{035E}" => '',
135        "\u{035F}" => '',
136        "\u{0360}" => '',
137        "\u{0361}" => '',
138        "\u{0362}" => '',
139        "\u{0363}" => '',
140        "\u{0364}" => '',
141        "\u{0365}" => '',
142        "\u{0366}" => '',
143        "\u{0367}" => '',
144        "\u{0368}" => '',
145        "\u{0369}" => '',
146        "\u{036A}" => '',
147        "\u{036B}" => '',
148        "\u{036C}" => '',
149        "\u{036D}" => '',
150        "\u{036E}" => '',
151        "\u{036F}" => '',
152    ];
153
154    /**
155     * Phone-book ordering of letters.
156     *
157     * @return array<int,string>
158     */
159    public function alphabet(): array
160    {
161        return ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'];
162    }
163
164    /**
165     * Default calendar used by this language.
166     *
167     * @return CalendarInterface
168     */
169    public function calendar(): CalendarInterface
170    {
171        return new GregorianCalendar();
172    }
173
174    /**
175     * One of: 'DMY', 'MDY', 'YMD'.
176     *
177     * @return string
178     */
179    public function dateOrder(): string
180    {
181        return 'DMY';
182    }
183
184    /**
185     * Some languages use digraphs and trigraphs.
186     *
187     * @param string $string
188     *
189     * @return string
190     */
191    public function initialLetter(string $string): string
192    {
193        return mb_substr($string, 0, 1);
194    }
195
196    /**
197     * Ignore diacritics on letters - unless the language considers them a different letter.
198     *
199     * @param string $text
200     *
201     * @return string
202     */
203    public function normalize(string $text): string
204    {
205        // Decompose any combined characters.
206        $text = normalizer_normalize($text, Normalizer::FORM_KD);
207
208        // Keep any significant diacritics.
209        $text = strtr($text, $this->normalizeExceptions());
210
211        // Remove other diacritics.
212        return strtr($text, $this->combining_diacritics);
213    }
214
215    /**
216     * Letters with diacritics that are considered distinct letters in this language.
217     *
218     * @return array<string,string>
219     */
220    protected function normalizeExceptions(): array
221    {
222        return [];
223    }
224
225    /**
226     * How should this module be identified in the control panel, etc.?
227     *
228     * @return string
229     */
230    public function title(): string
231    {
232        return  $this->locale()->endonym();
233    }
234
235    public function description(): string
236    {
237        return I18N::translate('Language') . ' — ' . $this->title() . ' — ' . $this->locale()->languageTag();
238    }
239
240    /**
241     * @return LocaleInterface
242     */
243    public function locale(): LocaleInterface
244    {
245        return new LocaleEnUs();
246    }
247
248    /**
249     * @return array<Relationship>
250     */
251    public function relationships(): array
252    {
253        return [];
254    }
255}
256