ILIAS  trunk Revision v11.0_alpha-1723-g8e69f309bab
All Data Structures Namespaces Files Functions Variables Enumerations Enumerator Modules Pages
LanguageTag.php
Go to the documentation of this file.
1 <?php
2 
19 declare(strict_types=1);
20 
21 namespace ILIAS\Data;
22 
31 use Closure;
32 
39 abstract class LanguageTag
40 {
41  abstract public function value(): string;
42 
43  public function __toString(): string
44  {
45  return $this->value();
46  }
47 
48  public static function fromString(string $string): static
49  {
50  $brick = new Brick();
51  return $brick->apply(self::definition($brick), $string)->except(static fn (): Result => (
52  new Error('Given string is no valid language tag.')
53  ))->value();
54  }
55 
59  private static function definition(Brick $brick): Closure
60  {
61  $extlang = $brick->sequence([
62  $brick->repeat(3, 3, $brick->alpha()),
63  $brick->repeat(0, 2, $brick->sequence(['-', $brick->repeat(3, 3, $brick->alpha())])),
64  ]);
65 
66  $language = $brick->either([
67  $brick->sequence([
68  'lang' => $brick->repeat(2, 3, $brick->alpha()),
69  $brick->repeat(0, 1, $brick->sequence(['-', 'extlang' => $extlang])),
70  ]),
71  $brick->sequence(['lang' => $brick->repeat(4, 4, $brick->alpha())]),
72  $brick->sequence(['lang' => $brick->repeat(5, 8, $brick->alpha())]),
73  ]);
74 
75  $script = $brick->repeat(4, 4, $brick->alpha());
76 
77  $region = $brick->either([
78  $brick->repeat(2, 2, $brick->alpha()),
79  $brick->repeat(3, 3, $brick->digit()),
80  ]);
81 
82  $alphanum = $brick->either([$brick->alpha(), $brick->digit()]);
83 
84  $variant = $brick->either([
85  $brick->repeat(5, 8, $alphanum),
86  $brick->sequence([$brick->digit(), $brick->repeat(3, 3, $alphanum)])
87  ]);
88 
89  $singleton = $brick->either([
90  $brick->digit(),
91  $brick->range(0x41, 0x57),
92  $brick->range(0x59, 0x5A),
93  $brick->range(0x61, 0x77),
94  $brick->range(0x79, 0x7A),
95  ]);
96 
97  $extension = $brick->sequence([
98  $singleton,
99  $brick->repeat(1, null, $brick->sequence(['-', $brick->repeat(2, 8, $alphanum)])),
100  ]);
101 
102  $privateuse = $brick->sequence([
103  'x',
104  $brick->repeat(1, null, $brick->sequence(['-', $brick->repeat(1, 8, $alphanum)]))
105  ]);
106 
107  $new = static fn (string $class) => new Custom(static fn (string $arg) => new $class($arg));
108 
109  $privateuse = $brick->transformation($new(PrivateUse::class), $privateuse);
110 
111  $irregular = $brick->either([
112  'en-GB-oed',
113  'i-ami',
114  'i-bnn',
115  'i-default',
116  'i-enochian',
117  'i-hak',
118  'i-klingon',
119  'i-lux',
120  'i-mingo',
121  'i-navajo',
122  'i-pwn',
123  'i-tao',
124  'i-tay',
125  'i-tsu',
126  'sgn-BE-FR',
127  'sgn-BE-NL',
128  'sgn-CH-DE',
129  ]);
130 
131  $regular = $brick->either([
132  'art-lojban',
133  'cel-gaulish',
134  'no-bok',
135  'no-nyn',
136  'zh-guoyu',
137  'zh-hakka',
138  'zh-min',
139  'zh-min-nan',
140  'zh-xiang',
141  ]);
142 
143  $grandfathered = $brick->either([
144  $brick->transformation($new(Irregular::class), $irregular),
145  $brick->transformation($new(Regular::class), $regular)
146  ]);
147 
148  $langtag = $brick->transformation(
149  new Custom(static fn (array $from): Standard => new Standard(
150  $from['language']['lang'],
151  $from['language']['extlang'] ?? null,
152  $from['script'] ?? null,
153  $from['region'] ?? null,
154  $from['variant'] ?? null,
155  $from['extension'] ?? null,
156  $from['privateuse'] ?? null,
157  )),
158  $brick->sequence([
159  'language' => $language,
160  $brick->repeat(0, 1, $brick->sequence(['-', 'script' => $script])),
161  $brick->repeat(0, 1, $brick->sequence(['-', 'region' => $region])),
162  $brick->repeat(0, null, $brick->sequence(['-', 'variant' => $variant])),
163  $brick->repeat(0, null, $brick->sequence(['-', 'extension' => $extension])),
164  $brick->repeat(0, 1, $brick->sequence(['-', 'privateuse' => $privateuse])),
165  ])
166  );
167 
168  return $brick->either([$langtag, $privateuse, $grandfathered]);
169  }
170 }
static fromString(string $string)
Definition: LanguageTag.php:48
transformation(Transformation $transformation, Closure $parse)
Definition: Brick.php:130
This class represents a valid language tag that should be used instead of plain strings.
Definition: LanguageTag.php:39
repeat(int $min, ?int $max, $parse)
Definition: Brick.php:114
while($session_entry=$r->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) return null
either(array $parsers)
Definition: Brick.php:94
static definition(Brick $brick)
This definition is directly translated from the ABNF definition on https://www.ietf.org/rfc/bcp/bcp47.txt.
Definition: LanguageTag.php:59
sequence(array $parsers)
Definition: Brick.php:103
range(int $start, int $end)
Definition: Brick.php:68
-type Continuation Closure(Result<Intermediate>): Result<Intermediate> -type Parser Closure(Intermedi...
Definition: Brick.php:34