ILIAS  release_8 Revision v8.24
ilCharSelectorConfig.php
Go to the documentation of this file.
1<?php
2
20{
25 public const INACTIVE = 0; // default for admin: deactivates the whole tool
26 public const INHERIT = 0; // default for user and test: take the plattform default
27 public const ENABLED = 1; // enable the selector
28 public const DISABLED = 2; // disable the selector
29
33 public const CONTEXT_NONE = ''; // no context => no initialisation
34 public const CONTEXT_ADMIN = 'admin'; // administrative settings
35 public const CONTEXT_USER = 'user'; // user specific settings
36 public const CONTEXT_TEST = 'test'; // test specific settings
37
42 public static array $unicode_blocks = array(
43 'basic_latin' => array('Basic Latin', '0020', '007F'), // only printing characters
44 'latin_1_supplement' => array('Latin-1 Supplement', '00A0', '00FF'), // only printing characters
45 'latin_extended_a' => array('Latin Extended-A', '0100', '017F'),
46 'latin_extended_b' => array('Latin Extended-B', '0180', '024F'),
47 'ipa_extensions' => array('IPA Extensions', '0250', '02AF'),
48 'spacing_modifier_letters' => array('Spacing Modifier Letters', '02B0', '02FF'),
49 'combining_diacritical_marks' => array('Combining Diacritical Marks', '0300', '036F'),
50 'greek_and_coptic' => array('Greek and Coptic', '0370', '03FF'),
51 'cyrillic' => array('Cyrillic', '0400', '04FF'),
52 'cyrillic_supplement' => array('Cyrillic Supplement', '0500', '052F'),
53 'armenian' => array('Armenian', '0530', '058F'),
54 'hebrew' => array('Hebrew', '0590', '05FF'),
55 'arabic' => array('Arabic', '0600', '06FF'),
56 'syriac' => array('Syriac', '0700', '074F'),
57 'arabic_supplement' => array('Arabic Supplement', '0750', '077F'),
58 'thaana' => array('Thaana', '0780', '07BF'),
59 'nko' => array('NKo', '07C0', '07FF'),
60 'samaritan' => array('Samaritan', '0800', '083F'),
61 'mandaic' => array('Mandaic', '0840', '085F'),
62 'arabic_extended_a' => array('Arabic Extended-A', '08A0', '08FF'),
63 'devanagari' => array('Devanagari', '0900', '097F'),
64 'bengali' => array('Bengali', '0980', '09FF'),
65 'gurmukhi' => array('Gurmukhi', '0A00', '0A7F'),
66 'gujarati' => array('Gujarati', '0A80', '0AFF'),
67 'oriya' => array('Oriya', '0B00', '0B7F'),
68 'tamil' => array('Tamil', '0B80', '0BFF'),
69 'telugu' => array('Telugu', '0C00', '0C7F'),
70 'kannada' => array('Kannada', '0C80', '0CFF'),
71 'malayalam' => array('Malayalam', '0D00', '0D7F'),
72 'sinhala' => array('Sinhala', '0D80', '0DFF'),
73 'thai' => array('Thai', '0E00', '0E7F'),
74 'lao' => array('Lao', '0E80', '0EFF'),
75 'tibetan' => array('Tibetan', '0F00', '0FFF'),
76 'myanmar' => array('Myanmar', '1000', '109F'),
77 'georgian' => array('Georgian', '10A0', '10FF'),
78 'hangul_jamo' => array('Hangul Jamo', '1100', '11FF'),
79 'ethiopic' => array('Ethiopic', '1200', '137F'),
80 'ethiopic_supplement' => array('Ethiopic Supplement', '1380', '139F'),
81 'cherokee' => array('Cherokee', '13A0', '13FF'),
82 'unified_canadian_aboriginal_syllabics' => array('Unified Canadian Aboriginal Syllabics', '1400', '167F'),
83 'ogham' => array('Ogham', '1680', '169F'),
84 'runic' => array('Runic', '16A0', '16FF'),
85 'tagalog' => array('Tagalog', '1700', '171F'),
86 'hanunoo' => array('Hanunoo', '1720', '173F'),
87 'buhid' => array('Buhid', '1740', '175F'),
88 'tagbanwa' => array('Tagbanwa', '1760', '177F'),
89 'khmer' => array('Khmer', '1780', '17FF'),
90 'mongolian' => array('Mongolian', '1800', '18AF'),
91 'unified_canadian_aboriginal_syllabics_extended' => array('Unified Canadian Aboriginal Syllabics Extended',
92 '18B0',
93 '18FF'
94 ),
95 'limbu' => array('Limbu', '1900', '194F'),
96 'tai_le' => array('Tai Le', '1950', '197F'),
97 'new_tai_lue' => array('New Tai Lue', '1980', '19DF'),
98 'khmer_symbols' => array('Khmer Symbols', '19E0', '19FF'),
99 'buginese' => array('Buginese', '1A00', '1A1F'),
100 'tai_tham' => array('Tai Tham', '1A20', '1AAF'),
101 'balinese' => array('Balinese', '1B00', '1B7F'),
102 'sundanese' => array('Sundanese', '1B80', '1BBF'),
103 'batak' => array('Batak', '1BC0', '1BFF'),
104 'lepcha' => array('Lepcha', '1C00', '1C4F'),
105 'ol_chiki' => array('Ol Chiki', '1C50', '1C7F'),
106 'sundanese_supplement' => array('Sundanese Supplement', '1CC0', '1CCF'),
107 'vedic_extensions' => array('Vedic Extensions', '1CD0', '1CFF'),
108 'phonetic_extensions' => array('Phonetic Extensions', '1D00', '1D7F'),
109 'phonetic_extensions_supplement' => array('Phonetic Extensions Supplement', '1D80', '1DBF'),
110 'combining_diacritical_marks_supplement' => array('Combining Diacritical Marks Supplement', '1DC0', '1DFF'),
111 'latin_extended_additional' => array('Latin Extended Additional', '1E00', '1EFF'),
112 'greek_extended' => array('Greek Extended', '1F00', '1FFF'),
113 'general_punctuation' => array('General Punctuation', '2000', '206F'),
114 'superscripts_and_subscripts' => array('Superscripts and Subscripts', '2070', '209F'),
115 'currency_symbols' => array('Currency Symbols', '20A0', '20CF'),
116 'combining_diacritical_marks_for_symbols' => array('Combining Diacritical Marks for Symbols', '20D0', '20FF'),
117 'letterlike_symbols' => array('Letterlike Symbols', '2100', '214F'),
118 'number_forms' => array('Number Forms', '2150', '218F'),
119 'arrows' => array('Arrows', '2190', '21FF'),
120 'mathematical_operators' => array('Mathematical Operators', '2200', '22FF'),
121 'miscellaneous_technical' => array('Miscellaneous Technical', '2300', '23FF'),
122 'control_pictures' => array('Control Pictures', '2400', '243F'),
123 'optical_character_recognition' => array('Optical Character Recognition', '2440', '245F'),
124 'enclosed_alphanumerics' => array('Enclosed Alphanumerics', '2460', '24FF'),
125 'box_drawing' => array('Box Drawing', '2500', '257F'),
126 'block_elements' => array('Block Elements', '2580', '259F'),
127 'geometric_shapes' => array('Geometric Shapes', '25A0', '25FF'),
128 'miscellaneous_symbols' => array('Miscellaneous Symbols', '2600', '26FF'),
129 'dingbats' => array('Dingbats', '2700', '27BF'),
130 'miscellaneous_mathematical_symbols_a' => array('Miscellaneous Mathematical Symbols-A', '27C0', '27EF'),
131 'supplemental_arrows_a' => array('Supplemental Arrows-A', '27F0', '27FF'),
132 'braille_patterns' => array('Braille Patterns', '2800', '28FF'),
133 'supplemental_arrows_b' => array('Supplemental Arrows-B', '2900', '297F'),
134 'miscellaneous_mathematical_symbols_b' => array('Miscellaneous Mathematical Symbols-B', '2980', '29FF'),
135 'supplemental_mathematical_operators' => array('Supplemental Mathematical Operators', '2A00', '2AFF'),
136 'miscellaneous_symbols_and_arrows' => array('Miscellaneous Symbols and Arrows', '2B00', '2BFF'),
137 'glagolitic' => array('Glagolitic', '2C00', '2C5F'),
138 'latin_extended_c' => array('Latin Extended-C', '2C60', '2C7F'),
139 'coptic' => array('Coptic', '2C80', '2CFF'),
140 'georgian_supplement' => array('Georgian Supplement', '2D00', '2D2F'),
141 'tifinagh' => array('Tifinagh', '2D30', '2D7F'),
142 'ethiopic_extended' => array('Ethiopic Extended', '2D80', '2DDF'),
143 'cyrillic_extended_a' => array('Cyrillic Extended-A', '2DE0', '2DFF'),
144 'supplemental_punctuation' => array('Supplemental Punctuation', '2E00', '2E7F'),
145 'cjk_radicals_supplement' => array('CJK Radicals Supplement', '2E80', '2EFF'),
146 'kangxi_radicals' => array('Kangxi Radicals', '2F00', '2FDF'),
147 'ideographic_description_characters' => array('Ideographic Description Characters', '2FF0', '2FFF'),
148 'cjk_symbols_and_punctuation' => array('CJK Symbols and Punctuation', '3000', '303F'),
149 'hiragana' => array('Hiragana', '3040', '309F'),
150 'katakana' => array('Katakana', '30A0', '30FF'),
151 'bopomofo' => array('Bopomofo', '3100', '312F'),
152 'hangul_compatibility_jamo' => array('Hangul Compatibility Jamo', '3130', '318F'),
153 'kanbun' => array('Kanbun', '3190', '319F'),
154 'bopomofo_extended' => array('Bopomofo Extended', '31A0', '31BF'),
155 'cjk_strokes' => array('CJK Strokes', '31C0', '31EF'),
156 'katakana_phonetic_extensions' => array('Katakana Phonetic Extensions', '31F0', '31FF'),
157 'enclosed_cjk_letters_and_months' => array('Enclosed CJK Letters and Months', '3200', '32FF'),
158 'cjk_compatibility' => array('CJK Compatibility', '3300', '33FF'),
159 'cjk_unified_ideographs_extension_a' => array('CJK Unified Ideographs Extension A', '3400', '4DBF'),
160 'yijing_hexagram_symbols' => array('Yijing Hexagram Symbols', '4DC0', '4DFF'),
161 'cjk_unified_ideographs' => array('CJK Unified Ideographs', '4E00', '9FFF'),
162 'yi_syllables' => array('Yi Syllables', 'A000', 'A48F'),
163 'yi_radicals' => array('Yi Radicals', 'A490', 'A4CF'),
164 'lisu' => array('Lisu', 'A4D0', 'A4FF'),
165 'vai' => array('Vai', 'A500', 'A63F'),
166 'cyrillic_extended_b' => array('Cyrillic Extended-B', 'A640', 'A69F'),
167 'bamum' => array('Bamum', 'A6A0', 'A6FF'),
168 'modifier_tone_letters' => array('Modifier Tone Letters', 'A700', 'A71F'),
169 'latin_extended_d' => array('Latin Extended-D', 'A720', 'A7FF'),
170 'syloti_nagri' => array('Syloti Nagri', 'A800', 'A82F'),
171 'common_indic_number_forms' => array('Common Indic Number Forms', 'A830', 'A83F'),
172 'phags_pa' => array('Phags-pa', 'A840', 'A87F'),
173 'saurashtra' => array('Saurashtra', 'A880', 'A8DF'),
174 'devanagari_extended' => array('Devanagari Extended', 'A8E0', 'A8FF'),
175 'kayah_li' => array('Kayah Li', 'A900', 'A92F'),
176 'rejang' => array('Rejang', 'A930', 'A95F'),
177 'hangul_jamo_extended_a' => array('Hangul Jamo Extended-A', 'A960', 'A97F'),
178 'javanese' => array('Javanese', 'A980', 'A9DF'),
179 'cham' => array('Cham', 'AA00', 'AA5F'),
180 'myanmar_extended_a' => array('Myanmar Extended-A', 'AA60', 'AA7F'),
181 'tai_viet' => array('Tai Viet', 'AA80', 'AADF'),
182 'meetei_mayek_extensions' => array('Meetei Mayek Extensions', 'AAE0', 'AAFF'),
183 'ethiopic_extended_a' => array('Ethiopic Extended-A', 'AB00', 'AB2F'),
184 'meetei_mayek' => array('Meetei Mayek', 'ABC0', 'ABFF'),
185 'hangul_syllables' => array('Hangul Syllables', 'AC00', 'D7AF'),
186 'hangul_jamo_extended_b' => array('Hangul Jamo Extended-B', 'D7B0', 'D7FF'),
187 'high_surrogates' => array('High Surrogates', 'D800', 'DB7F'),
188 'high_private_use_surrogates' => array('High Private Use Surrogates', 'DB80', 'DBFF'),
189 'low_surrogates' => array('Low Surrogates', 'DC00', 'DFFF'),
190 'private_use_area' => array('Private Use Area', 'E000', 'F8FF'),
191 'cjk_compatibility_ideographs' => array('CJK Compatibility Ideographs', 'F900', 'FAFF'),
192 'alphabetic_presentation_forms' => array('Alphabetic Presentation Forms', 'FB00', 'FB4F'),
193 'arabic_presentation_forms_a' => array('Arabic Presentation Forms-A', 'FB50', 'FDFF'),
194 'variation_selectors' => array('Variation Selectors', 'FE00', 'FE0F'),
195 'vertical_forms' => array('Vertical Forms', 'FE10', 'FE1F'),
196 'combining_half_marks' => array('Combining Half Marks', 'FE20', 'FE2F'),
197 'cjk_compatibility_forms' => array('CJK Compatibility Forms', 'FE30', 'FE4F'),
198 'small_form_variants' => array('Small Form Variants', 'FE50', 'FE6F'),
199 'arabic_presentation_forms_b' => array('Arabic Presentation Forms-B', 'FE70', 'FEFF'),
200 'halfwidth_and_fullwidth_forms' => array('Halfwidth and Fullwidth Forms', 'FF00', 'FFEF'),
201 'specials' => array('Specials', 'FFF0', 'FFFF'),
202 /* here ends the Basic Multilinguage Plane (BMP) */
203
204 /*
205 * The following blocks are not yet supported well.
206 * It seems that the chars are taken from the BMP instead
207 *
208 'linear_b_syllabary' => array('Linear B Syllabary', '10000', '1007F'),
209 'linear_b_ideograms' => array('Linear B Ideograms', '10080', '100FF'),
210 'aegean_numbers' => array('Aegean Numbers', '10100', '1013F'),
211 'ancient_greek_numbers' => array('Ancient Greek Numbers', '10140', '1018F'),
212 'ancient_symbols' => array('Ancient Symbols', '10190', '101CF'),
213 'phaistos_disc' => array('Phaistos Disc', '101D0', '101FF'),
214 'lycian' => array('Lycian', '10280', '1029F'),
215 'carian' => array('Carian', '102A0', '102DF'),
216 'old_italic' => array('Old Italic', '10300', '1032F'),
217 'gothic' => array('Gothic', '10330', '1034F'),
218 'ugaritic' => array('Ugaritic', '10380', '1039F'),
219 'old_persian' => array('Old Persian', '103A0', '103DF'),
220 'deseret' => array('Deseret', '10400', '1044F'),
221 'shavian' => array('Shavian', '10450', '1047F'),
222 'osmanya' => array('Osmanya', '10480', '104AF'),
223 'cypriot_syllabary' => array('Cypriot Syllabary', '10800', '1083F'),
224 'imperial_aramaic' => array('Imperial Aramaic', '10840', '1085F'),
225 'phoenician' => array('Phoenician', '10900', '1091F'),
226 'lydian' => array('Lydian', '10920', '1093F'),
227 'meroitic_hieroglyphs' => array('Meroitic Hieroglyphs', '10980', '1099F'),
228 'meroitic_cursive' => array('Meroitic Cursive', '109A0', '109FF'),
229 'kharoshthi' => array('Kharoshthi', '10A00', '10A5F'),
230 'old_south_arabian' => array('Old South Arabian', '10A60', '10A7F'),
231 'avestan' => array('Avestan', '10B00', '10B3F'),
232 'inscriptional_parthian' => array('Inscriptional Parthian', '10B40', '10B5F'),
233 'inscriptional_pahlavi' => array('Inscriptional Pahlavi', '10B60', '10B7F'),
234 'old_turkic' => array('Old Turkic', '10C00', '10C4F'),
235 'rumi_numeral_symbols' => array('Rumi Numeral Symbols', '10E60', '10E7F'),
236 'brahmi' => array('Brahmi', '11000', '1107F'),
237 'kaithi' => array('Kaithi', '11080', '110CF'),
238 'sora_sompeng' => array('Sora Sompeng', '110D0', '110FF'),
239 'chakma' => array('Chakma', '11100', '1114F'),
240 'sharada' => array('Sharada', '11180', '111DF'),
241 'takri' => array('Takri', '11680', '116CF'),
242 'cuneiform' => array('Cuneiform', '12000', '123FF'),
243 'cuneiform_numbers_and_punctuation' => array('Cuneiform Numbers and Punctuation', '12400', '1247F'),
244 'egyptian_hieroglyphs' => array('Egyptian Hieroglyphs', '13000', '1342F'),
245 'bamum_supplement' => array('Bamum Supplement', '16800', '16A3F'),
246 'miao' => array('Miao', '16F00', '16F9F'),
247 'kana_supplement' => array('Kana Supplement', '1B000', '1B0FF'),
248 'byzantine_musical_symbols' => array('Byzantine Musical Symbols', '1D000', '1D0FF'),
249 'musical_symbols' => array('Musical Symbols', '1D100', '1D1FF'),
250 'ancient_greek_musical_notation' => array('Ancient Greek Musical Notation', '1D200', '1D24F'),
251 'tai_xuan_jing_symbols' => array('Tai Xuan Jing Symbols', '1D300', '1D35F'),
252 'counting_rod_numerals' => array('Counting Rod Numerals', '1D360', '1D37F'),
253 'mathematical_alphanumeric_symbols' => array('Mathematical Alphanumeric Symbols', '1D400', '1D7FF'),
254 'arabic_mathematical_alphabetic_symbols' => array('Arabic Mathematical Alphabetic Symbols', '1EE00', '1EEFF'),
255 'mahjong_tiles' => array('Mahjong Tiles', '1F000', '1F02F'),
256 'domino_tiles' => array('Domino Tiles', '1F030', '1F09F'),
257 'playing_cards' => array('Playing Cards', '1F0A0', '1F0FF'),
258 'enclosed_alphanumeric_supplement' => array('Enclosed Alphanumeric Supplement', '1F100', '1F1FF'),
259 'enclosed_ideographic_supplement' => array('Enclosed Ideographic Supplement', '1F200', '1F2FF'),
260 'miscellaneous_symbols_and_pictographs' => array('Miscellaneous Symbols And Pictographs', '1F300', '1F5FF'),
261 'emoticons' => array('Emoticons', '1F600', '1F64F'),
262 'transport_and_map_symbols' => array('Transport And Map Symbols', '1F680', '1F6FF'),
263 'alchemical_symbols' => array('Alchemical Symbols', '1F700', '1F77F'),
264 'cjk_unified_ideographs_extension_b' => array('CJK Unified Ideographs Extension B', '20000', '2A6DF'),
265 'cjk_unified_ideographs_extension_c' => array('CJK Unified Ideographs Extension C', '2A700', '2B73F'),
266 'cjk_unified_ideographs_extension_d' => array('CJK Unified Ideographs Extension D', '2B740', '2B81F'),
267 'cjk_compatibility_ideographs_supplement' => array('CJK Compatibility Ideographs Supplement', '2F800', '2FA1F'),
268 'tags' => array('Tags', 'E0000', 'E007F'),
269 'variation_selectors_supplement' => array('Variation Selectors Supplement', 'E0100', 'E01EF'),
270 'supplementary_private_use_area_a' => array('Supplementary Private Use Area-A', 'F0000', 'FFFFF'),
271 'supplementary_private_use_area_b' => array('Supplementary Private Use Area-B', '100000', '10FFFF')
272 */
273 );
274
275 // settings context
276 private string $context = self::CONTEXT_NONE;
277
278 // availability of the character selector
280
281 // list of added unicode block names
282 private array $added_blocks = array();
283
284 // list of custom selector items (splitted custom block)
285 private array $custom_items = array();
286
287 public function __construct(string $a_context = self::CONTEXT_NONE)
288 {
289 switch ($a_context) {
293 $this->context = $a_context;
294 break;
295 default:
296 $this->context = self::CONTEXT_NONE;
297 }
298 }
299
303 public static function _getCurrentConfig(ilObjTest $a_test_obj = null): self
304 {
305 global $ilSetting, $ilUser;
306
307 // check configuration from administration settings
308 $admin_config = new self(self::CONTEXT_ADMIN);
309 $admin_config->setAvailability((int) $ilSetting->get('char_selector_availability'));
310 $admin_config->setDefinition((string) $ilSetting->get('char_selector_definition'));
311 if ($admin_config->getAvailability() === self::INACTIVE) {
312 // a globally inactive selector can't be overwritten by users or tests
313 return $admin_config;
314 }
315
316 // a test configuration is relevant for test runs
317 if (isset($a_test_obj)) {
318 $test_config = new self(self::CONTEXT_TEST);
319 $test_config->setAvailability((int) $a_test_obj->getCharSelectorAvailability());
320 $test_config->setDefinition((string) $a_test_obj->getCharSelectorDefinition());
321 if ($test_config->getAvailability() !== self::INHERIT) {
322 // a specific test configuration has precedence over user configuration
323 return $test_config;
324 }
325 }
326
327 // check configuration from user settings
328 $user_config = new self(self::CONTEXT_USER);
329 $user_config->setAvailability((int) $ilUser->getPref('char_selector_availability'));
330 $user_config->setDefinition((string) $ilUser->getPref('char_selector_definition'));
331 if ($user_config->getAvailability() !== self::INHERIT) {
332 // take user specific config
333 return $user_config;
334 } else {
335 // take admin config as default
336 return $admin_config;
337 }
338 }
339
344 public function getContext(): string
345 {
346 return $this->context;
347 }
348
349 public function setAvailability(int $a_availability): void
350 {
351 switch ($a_availability) {
352 case self::INACTIVE:
353 case self::INHERIT:
354 case self::ENABLED:
355 case self::DISABLED:
356 $this->availability = $a_availability;
357 break;
358 default:
359 $this->availability = self::INHERIT;
360 }
361 }
362
363 public function getAvailability(): int
364 {
365 return $this->availability;
366 }
367
371 public function setAddedBlocks(array $a_blocks = array()): void
372 {
373 $this->added_blocks = array();
374 foreach ($a_blocks as $block_name) {
375 if ($block_name === "all" || array_key_exists($block_name, self::$unicode_blocks)) {
376 $this->added_blocks[] = $block_name;
377 }
378 }
379 }
380
381 public function getAddedBlocks(): array
382 {
383 return $this->added_blocks;
384 }
385
390 public function setCustomItems(string $a_items = ''): void
391 {
392 $this->custom_items = explode(' ', $a_items);
393 }
394
399 public function getCustomItems(): string
400 {
401 return implode(' ', $this->custom_items);
402 }
403
420 public function setDefinition(string $a_definition = ''): void
421 {
422 // first reset all previous settings
423 $this->added_blocks = array();
424 $this->custom_items = array();
425
426 // set the default definition to all unicode blocks
427 if (trim($a_definition) === '') {
428 $a_definition = "[all]";
429 }
430
431 // analyze definition items
432 $items = explode(' ', $a_definition);
433 foreach ($items as $item) {
434 if (($block_name = $this->extractUnicodeBlock($item)) !== '') {
435 $this->added_blocks[] = $block_name;
436 } elseif ($item !== '') {
437 $this->custom_items[] = trim($item);
438 }
439 }
440 }
441
446 public function getDefinition(): string
447 {
448 $definition = implode(' ', $this->custom_items);
449 foreach ($this->added_blocks as $block_name) {
450 $definition .= ' [' . $block_name . ']';
451 }
452 return trim($definition);
453 }
454
458 public function getBlockOptions(): array
459 {
460 global $lng;
461
462 $options = array(
463 '' => $lng->txt('please_select'),
464 'all' => $lng->txt('char_selector_unicode_all')
465 );
466 foreach (array_keys(self::$unicode_blocks) as $block_name) {
467 $options[$block_name] = $this->getBlockTitle($block_name);
468 }
469 return $options;
470 }
471
476 public function getBlockTitle(string $a_block_name): string
477 {
478 global $lng;
479
480 $langvar = 'char_selector_unicode_' . $a_block_name;
481 if ($lng->txt($langvar) !== '-' . $langvar . '-') {
482 return $lng->txt($langvar);
483 } else {
484 return self::$unicode_blocks[$a_block_name][0];
485 }
486 }
487
493 private function extractUnicodeBlock(string $a_item = ''): string
494 {
495 $a_item = trim($a_item);
496 $matches = array();
497 if (preg_match('/^\[(.+)\]$/', $a_item, $matches)) {
498 $block_name = $matches[1];
499 if ($block_name === 'all' || array_key_exists($block_name, self::$unicode_blocks)) {
500 return $block_name;
501 }
502 }
503 return '';
504 }
505
511 public function getCharPages(): array
512 {
513 global $lng;
514
515 $pages = array();
516
517 // add custom block
518 //
519 $page = array($lng->txt('char_selector_custom_items'));
520 foreach ($this->custom_items as $item) {
521 if (strpos($item, '-') > 0) {
522 // handle range
523 $subitems = explode('-', $item);
524 $start = $this->getItemCodepoint($subitems[0]);
525 $end = $this->getItemCodepoint($subitems[1]);
526 $page[] = array($start, $end);
527 } else {
528 // handle normal item
529 $page[] = $this->getItemParsed($item);
530 }
531 }
532 if (count($page) > 1) {
533 $pages[] = $page;
534 }
535
536 // add unicode blocks
537 //
538 $blocks = in_array('all', $this->added_blocks) ?
539 array_keys(self::$unicode_blocks) :
541
542 foreach ($blocks as $block_name) {
543 $start = hexdec(self::$unicode_blocks[$block_name][1]);
544 $end = hexdec(self::$unicode_blocks[$block_name][2]);
545 $page = array($this->getBlockTitle($block_name), array($start, $end));
546 $pages[] = $page;
547 }
548
549 return $pages;
550 }
551
555 private function getItemCodepoint(string $a_item): string
556 {
557 if (preg_match('/^[uU]\+[0-9a-fA-F]+$/', $a_item)) {
558 return (int) hexdec(substr($a_item, 2));
559 } else {
560 //take the codepoint of the first character
561 return $this->utf8ToCodepoint($a_item);
562 }
563 }
564
568 private function getItemParsed(string $a_item): string
569 {
570 return preg_replace_callback(
571 '/[uU]\+[0-9a-fA-F]+/',
572 array($this, 'getItemParsedCallback'),
573 $a_item
574 );
575 }
576
582 private function getItemParsedCallback(array $matches): string
583 {
584 return $this->codepointToUtf8((int) hexdec(substr($matches[0], 2)));
585 }
586
596 private function codepointToUtf8(int $codepoint): string
597 {
598 if ($codepoint < 0x80) {
599 return chr($codepoint);
600 }
601 if ($codepoint < 0x800) {
602 return chr($codepoint >> 6&0x3f|0xc0) .
603 chr($codepoint&0x3f|0x80);
604 }
605 if ($codepoint < 0x10000) {
606 return chr($codepoint >> 12&0x0f|0xe0) .
607 chr($codepoint >> 6&0x3f|0x80) .
608 chr($codepoint&0x3f|0x80);
609 }
610 if ($codepoint < 0x110000) {
611 return chr($codepoint >> 18&0x07|0xf0) .
612 chr($codepoint >> 12&0x3f|0x80) .
613 chr($codepoint >> 6&0x3f|0x80) .
614 chr($codepoint&0x3f|0x80);
615 }
616
617 return '';
618 }
619
629 private function utf8ToCodepoint(string $char): int
630 {
631 # Find the length
632 $z = ord($char[0]);
633 if ($z&0x80) {
634 $length = 0;
635 while ($z&0x80) {
636 $length++;
637 $z <<= 1;
638 }
639 } else {
640 $length = 1;
641 }
642
643 if ($length != strlen($char)) {
644 return false;
645 }
646 if ($length == 1) {
647 return ord($char);
648 }
649
650 # Mask off the length-determining bits and shift back to the original location
651 $z &= 0xff;
652 $z >>= $length;
653
654 # Add in the free bits from subsequent bytes
655 for ($i = 1; $i < $length; $i++) {
656 $z <<= 6;
657 $z |= ord($char[$i])&0x3f;
658 }
659
660 return $z;
661 }
662}
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
const INACTIVE
Availabilities INACTIVE/INHERIT corresponds to an unconfigured selector (no database entries)
utf8ToCodepoint(string $char)
Determine the Unicode codepoint of a single-character UTF-8 sequence.
setCustomItems(string $a_items='')
set the custom items
getBlockTitle(string $a_block_name)
Get the title of a unicode block for display or selection A translation is used if it exists.
getItemCodepoint(string $a_item)
get the unicode index of an item
getCustomItems()
set the custom items
getItemParsedCallback(array $matches)
callback for replacement of unicode notations
getBlockOptions()
get the options for a block selection
static _getCurrentConfig(ilObjTest $a_test_obj=null)
Get the configuration that should be used for the current selector.
extractUnicodeBlock(string $a_item='')
Extract the unicode block name from a definition item.
setAddedBlocks(array $a_blocks=array())
getContext()
get the context of the configuration (the context is set at initialisation and can't be changed)
__construct(string $a_context=self::CONTEXT_NONE)
getCharPages()
Get the character pages.
getDefinition()
Set the definition of the available characters.
setAvailability(int $a_availability)
setDefinition(string $a_definition='')
const CONTEXT_NONE
Configuration contexts.
codepointToUtf8(int $codepoint)
Return the UTF-8 sequence for a given Unicode code point.
getItemParsed(string $a_item)
replace unicode notations with their utf8 chars in a string
$ilUser
Definition: imgupload.php:34
$i
Definition: metadata.php:41
global $ilSetting
Definition: privfeed.php:17
$lng