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 /** 236 * A sentence describing what this module does. 237 * 238 * @return string 239 */ 240 public function description(): string 241 { 242 return I18N::translate('Language') . ' — ' . $this->title() . ' — ' . $this->locale()->languageTag(); 243 } 244 245 /** 246 * @return LocaleInterface 247 */ 248 public function locale(): LocaleInterface 249 { 250 return new LocaleEnUs(); 251 } 252 253 /** 254 * @return array<Relationship> 255 */ 256 public function relationships(): array 257 { 258 return []; 259 } 260} 261