PluginProbe ʕ •ᴥ•ʔ
Matomo Analytics – Powerful, Privacy-First Insights for WordPress / 5.12.1
Matomo Analytics – Powerful, Privacy-First Insights for WordPress v5.12.1
5.12.1 5.12.0 5.11.1 5.11.0 5.10.2 5.10.1 trunk 1.0.2 1.0.3 1.0.4 1.0.5 1.0.6 1.1.0 1.1.1 1.1.2 1.1.3 1.2.0 1.3.0 1.3.1 1.3.2 4.0.0 4.0.1 4.0.2 4.0.3 4.0.4 4.1.0 4.1.1 4.1.2 4.1.3 4.10.0 4.11.0 4.12.0 4.13.0 4.13.2 4.13.3 4.13.4 4.13.5 4.14.0 4.14.1 4.14.2 4.15.0 4.15.1 4.15.2 4.15.3 4.2.0 4.3.0 4.3.1 4.4.1 4.4.2 4.5.0 4.6.0 5.0.1 5.0.2 5.0.3 5.0.4 5.0.5 5.0.6 5.0.7 5.0.8 5.1.0 5.1.1 5.1.2 5.1.3 5.1.4 5.1.5 5.1.6 5.1.7 5.10.0 5.2.0 5.2.1 5.2.2 5.3.0 5.3.1 5.3.2 5.3.3 5.6.0 5.6.1 5.7.0 5.7.1 5.8.0 5.8.1 5.8.2
matomo / app / vendor / symfony / polyfill-intl-normalizer / Normalizer.php
matomo / app / vendor / symfony / polyfill-intl-normalizer Last commit date
Resources 2 months ago LICENSE 2 years ago Normalizer.php 2 months ago README.md 2 years ago bootstrap.php 2 months ago bootstrap80.php 2 months ago
Normalizer.php
301 lines
1 <?php
2
3 /*
4 * This file is part of the Symfony package.
5 *
6 * (c) Fabien Potencier <fabien@symfony.com>
7 *
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
10 */
11 namespace Symfony\Polyfill\Intl\Normalizer;
12
13 /**
14 * Normalizer is a PHP fallback implementation of the Normalizer class provided by the intl extension.
15 *
16 * It has been validated with Unicode 6.3 Normalization Conformance Test.
17 * See http://www.unicode.org/reports/tr15/ for detailed info about Unicode normalizations.
18 *
19 * @author Nicolas Grekas <p@tchwork.com>
20 *
21 * @internal
22 */
23 class Normalizer
24 {
25 public const FORM_D = \Normalizer::FORM_D;
26 public const FORM_KD = \Normalizer::FORM_KD;
27 public const FORM_C = \Normalizer::FORM_C;
28 public const FORM_KC = \Normalizer::FORM_KC;
29 public const NFD = \Normalizer::NFD;
30 public const NFKD = \Normalizer::NFKD;
31 public const NFC = \Normalizer::NFC;
32 public const NFKC = \Normalizer::NFKC;
33 private static $C;
34 private static $D;
35 private static $KD;
36 private static $cC;
37 private static $rawD;
38 private static $rawKD;
39 private static $ulenMask = ["\xc0" => 2, "\xd0" => 2, "\xe0" => 3, "\xf0" => 4];
40 private static $ASCII = " eiasntrolud][cmp'\ng|hv.fb,:=-q10C2*yx)(L9AS/P\"EjMIk3>5T<D4}B{8FwR67UGN;JzV#HOW_&!K?XQ%Y\\\tZ+~^\$@`\x00\x01\x02\x03\x04\x05\x06\x07\x08\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f";
41 public static function isNormalized(string $s, int $form = self::FORM_C)
42 {
43 if (!\in_array($form, [self::NFD, self::NFKD, self::NFC, self::NFKC])) {
44 return \false;
45 }
46 if (!isset($s[strspn($s, self::$ASCII)])) {
47 return \true;
48 }
49 if (self::NFC == $form && preg_match('//u', $s) && !preg_match('/[^\\x00-\\x{2FF}]/u', $s)) {
50 return \true;
51 }
52 return self::normalize($s, $form) === $s;
53 }
54 public static function getRawDecomposition(string $s, int $form = self::FORM_C)
55 {
56 if ('' === $s || !preg_match('//u', $s)) {
57 return null;
58 }
59 $ulen = $s[0] < "\x80" ? 1 : self::$ulenMask[$s[0] & "\xf0"] ?? 0;
60 if (!$ulen || \strlen($s) !== $ulen) {
61 return null;
62 }
63 if (self::NFC !== $form && self::NFD !== $form && self::NFKC !== $form && self::NFKD !== $form) {
64 return '';
65 }
66 if ($s >= "" && $s <= "") {
67 $u = unpack('C*', $s);
68 $j = ($u[1] - 224 << 12) + ($u[2] - 128 << 6) + $u[3] - 0xac80;
69 if ($t = $j % 28) {
70 $j -= $t;
71 $lv = 0xac00 + $j;
72 $r = \chr(0xe0 | $lv >> 12) . \chr(0x80 | $lv >> 6 & 0x3f) . \chr(0x80 | $lv & 0x3f);
73 $r .= $t < 25 ? "\xe1\x86" . \chr(0xa7 + $t) : "\xe1\x87" . \chr(0x67 + $t);
74 return $r;
75 }
76 return "\xe1\x84" . \chr(0x80 + (int) ($j / 588)) . "\xe1\x85" . \chr(0xa1 + (int) ($j % 588 / 28));
77 }
78 if (null === self::$rawD) {
79 self::$rawD = self::getData('rawCanonicalDecomposition');
80 }
81 if (isset(self::$rawD[$s])) {
82 return self::$rawD[$s];
83 }
84 if (self::NFKC === $form || self::NFKD === $form) {
85 if (null === self::$rawKD) {
86 self::$rawKD = self::getData('rawCompatibilityDecomposition');
87 }
88 return self::$rawKD[$s] ?? null;
89 }
90 return null;
91 }
92 public static function normalize(string $s, int $form = self::FORM_C)
93 {
94 if (!preg_match('//u', $s)) {
95 return \false;
96 }
97 switch ($form) {
98 case self::NFC:
99 $C = \true;
100 $K = \false;
101 break;
102 case self::NFD:
103 $C = \false;
104 $K = \false;
105 break;
106 case self::NFKC:
107 $C = \true;
108 $K = \true;
109 break;
110 case self::NFKD:
111 $C = \false;
112 $K = \true;
113 break;
114 default:
115 if (\defined('Normalizer::NONE') && \Normalizer::NONE == $form) {
116 return $s;
117 }
118 if (80000 > \PHP_VERSION_ID) {
119 return \false;
120 }
121 throw new \ValueError('normalizer_normalize(): Argument #2 ($form) must be a a valid normalization form');
122 }
123 if ('' === $s) {
124 return '';
125 }
126 if ($K && null === self::$KD) {
127 self::$KD = self::getData('compatibilityDecomposition');
128 }
129 if (null === self::$D) {
130 self::$D = self::getData('canonicalDecomposition');
131 self::$cC = self::getData('combiningClass');
132 }
133 if (null !== ($mbEncoding = 2 & (int) \ini_get('mbstring.func_overload') ? mb_internal_encoding() : null)) {
134 mb_internal_encoding('8bit');
135 }
136 $r = self::decompose($s, $K);
137 if ($C) {
138 if (null === self::$C) {
139 self::$C = self::getData('canonicalComposition');
140 }
141 $r = self::recompose($r);
142 }
143 if (null !== $mbEncoding) {
144 mb_internal_encoding($mbEncoding);
145 }
146 return $r;
147 }
148 private static function recompose($s)
149 {
150 $ASCII = self::$ASCII;
151 $compMap = self::$C;
152 $combClass = self::$cC;
153 $ulenMask = self::$ulenMask;
154 $result = $tail = '';
155 $i = $s[0] < "\x80" ? 1 : $ulenMask[$s[0] & "\xf0"];
156 $len = \strlen($s);
157 $lastUchr = substr($s, 0, $i);
158 $lastUcls = isset($combClass[$lastUchr]) ? 256 : 0;
159 while ($i < $len) {
160 if ($s[$i] < "\x80") {
161 // ASCII chars
162 if ($tail) {
163 $lastUchr .= $tail;
164 $tail = '';
165 }
166 if ($j = strspn($s, $ASCII, $i + 1)) {
167 $lastUchr .= substr($s, $i, $j);
168 $i += $j;
169 }
170 $result .= $lastUchr;
171 $lastUchr = $s[$i];
172 $lastUcls = 0;
173 ++$i;
174 continue;
175 }
176 $ulen = $ulenMask[$s[$i] & "\xf0"];
177 $uchr = substr($s, $i, $ulen);
178 if ($lastUchr < "ᄀ" || "ᄒ" < $lastUchr || $uchr < "�
179 �" || "�
180 �" < $uchr || $lastUcls) {
181 // Table lookup and combining chars composition
182 $ucls = $combClass[$uchr] ?? 0;
183 if (isset($compMap[$lastUchr . $uchr]) && (!$lastUcls || $lastUcls < $ucls)) {
184 $lastUchr = $compMap[$lastUchr . $uchr];
185 } elseif ($lastUcls = $ucls) {
186 $tail .= $uchr;
187 } else {
188 if ($tail) {
189 $lastUchr .= $tail;
190 $tail = '';
191 }
192 $result .= $lastUchr;
193 $lastUchr = $uchr;
194 }
195 } else {
196 // Hangul chars
197 $L = \ord($lastUchr[2]) - 0x80;
198 $V = \ord($uchr[2]) - 0xa1;
199 $T = 0;
200 $uchr = substr($s, $i + $ulen, 3);
201 if ("" <= $uchr && $uchr <= "") {
202 $T = \ord($uchr[2]) - 0xa7;
203 0 > $T && ($T += 0x40);
204 $ulen += 3;
205 }
206 $L = 0xac00 + ($L * 21 + $V) * 28 + $T;
207 $lastUchr = \chr(0xe0 | $L >> 12) . \chr(0x80 | $L >> 6 & 0x3f) . \chr(0x80 | $L & 0x3f);
208 }
209 $i += $ulen;
210 }
211 return $result . $lastUchr . $tail;
212 }
213 private static function decompose($s, $c)
214 {
215 $result = '';
216 $ASCII = self::$ASCII;
217 $decompMap = self::$D;
218 $combClass = self::$cC;
219 $ulenMask = self::$ulenMask;
220 if ($c) {
221 $compatMap = self::$KD;
222 }
223 $c = [];
224 $i = 0;
225 $len = \strlen($s);
226 while ($i < $len) {
227 if ($s[$i] < "\x80") {
228 // ASCII chars
229 if ($c) {
230 ksort($c);
231 $result .= implode('', $c);
232 $c = [];
233 }
234 $j = 1 + strspn($s, $ASCII, $i + 1);
235 $result .= substr($s, $i, $j);
236 $i += $j;
237 continue;
238 }
239 $ulen = $ulenMask[$s[$i] & "\xf0"];
240 $uchr = substr($s, $i, $ulen);
241 $i += $ulen;
242 if ($uchr < "" || "" < $uchr) {
243 // Table lookup
244 if ($uchr !== ($j = $compatMap[$uchr] ?? $decompMap[$uchr] ?? $uchr)) {
245 $uchr = $j;
246 $j = \strlen($uchr);
247 $ulen = $uchr[0] < "\x80" ? 1 : $ulenMask[$uchr[0] & "\xf0"];
248 if ($ulen != $j) {
249 // Put trailing chars in $s
250 $j -= $ulen;
251 $i -= $j;
252 if (0 > $i) {
253 $s = str_repeat(' ', -$i) . $s;
254 $len -= $i;
255 $i = 0;
256 }
257 while ($j--) {
258 $s[$i + $j] = $uchr[$ulen + $j];
259 }
260 $uchr = substr($uchr, 0, $ulen);
261 }
262 }
263 if (isset($combClass[$uchr])) {
264 // Combining chars, for sorting
265 if (!isset($c[$combClass[$uchr]])) {
266 $c[$combClass[$uchr]] = '';
267 }
268 $c[$combClass[$uchr]] .= $uchr;
269 continue;
270 }
271 } else {
272 // Hangul chars
273 $uchr = unpack('C*', $uchr);
274 $j = ($uchr[1] - 224 << 12) + ($uchr[2] - 128 << 6) + $uchr[3] - 0xac80;
275 $uchr = "\xe1\x84" . \chr(0x80 + (int) ($j / 588)) . "\xe1\x85" . \chr(0xa1 + (int) ($j % 588 / 28));
276 if ($j %= 28) {
277 $uchr .= $j < 25 ? "\xe1\x86" . \chr(0xa7 + $j) : "\xe1\x87" . \chr(0x67 + $j);
278 }
279 }
280 if ($c) {
281 ksort($c);
282 $result .= implode('', $c);
283 $c = [];
284 }
285 $result .= $uchr;
286 }
287 if ($c) {
288 ksort($c);
289 $result .= implode('', $c);
290 }
291 return $result;
292 }
293 private static function getData($file)
294 {
295 if (file_exists($file = __DIR__ . '/Resources/unidata/' . $file . '.php')) {
296 return require $file;
297 }
298 return \false;
299 }
300 }
301