PluginProbe ʕ •ᴥ•ʔ
Independent Analytics – WordPress Analytics Plugin / 1.30.0
Independent Analytics – WordPress Analytics Plugin v1.30.0
2.15.5 2.15.4 2.15.3 2.15.2 2.15.1 2.15.0 2.14.10 trunk 1.1 1.10 1.10.1 1.11 1.12 1.13 1.14 1.15 1.16 1.17 1.17.1 1.17.2 1.17.3 1.17.4 1.18 1.18.1 1.19.0 1.19.1 1.2 1.20.0 1.21.0 1.22.0 1.22.1 1.23.0 1.23.1 1.24.0 1.24.1 1.25.0 1.25.1 1.26.0 1.27.0 1.28.0 1.28.1 1.28.2 1.28.3 1.29.0 1.3 1.30.0 1.30.1 1.4 1.5 1.6 1.7 1.8 1.9 2.0.0 2.0.1 2.1.4 2.1.5 2.1.6 2.10.0 2.10.1 2.10.2 2.10.3 2.10.4 2.11.0 2.11.1 2.11.10 2.11.2 2.11.3 2.11.4 2.11.5 2.11.6 2.11.7 2.11.8 2.11.9 2.12.0 2.12.1 2.12.2 2.13.1 2.13.2 2.13.5 2.13.6 2.14.0 2.14.1 2.14.2 2.14.4 2.14.6 2.14.7 2.14.8 2.14.9 2.2.0 2.2.1 2.3.1 2.3.2 2.4.2 2.4.3 2.5.0 2.5.1 2.6.0 2.6.1 2.6.2 2.6.3 2.6.4 2.7.0 2.7.1 2.7.2 2.7.3 2.8.2 2.8.3 2.8.4 2.8.5 2.8.6 2.8.7 2.8.8 2.8.9 2.9.2 2.9.3 2.9.4 2.9.5 2.9.6 2.9.7
independent-analytics / vendor / symfony / string / UnicodeString.php
independent-analytics / vendor / symfony / string Last commit date
Exception 3 years ago Inflector 3 years ago Resources 3 years ago Slugger 3 years ago AbstractString.php 3 years ago AbstractUnicodeString.php 3 years ago ByteString.php 3 years ago CodePointString.php 3 years ago LazyString.php 3 years ago UnicodeString.php 3 years ago
UnicodeString.php
303 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 IAWP_SCOPED\Symfony\Component\String;
12
13 use IAWP_SCOPED\Symfony\Component\String\Exception\ExceptionInterface;
14 use IAWP_SCOPED\Symfony\Component\String\Exception\InvalidArgumentException;
15 /**
16 * Represents a string of Unicode grapheme clusters encoded as UTF-8.
17 *
18 * A letter followed by combining characters (accents typically) form what Unicode defines
19 * as a grapheme cluster: a character as humans mean it in written texts. This class knows
20 * about the concept and won't split a letter apart from its combining accents. It also
21 * ensures all string comparisons happen on their canonically-composed representation,
22 * ignoring e.g. the order in which accents are listed when a letter has many of them.
23 *
24 * @see https://unicode.org/reports/tr15/
25 *
26 * @author Nicolas Grekas <p@tchwork.com>
27 * @author Hugo Hamon <hugohamon@neuf.fr>
28 *
29 * @throws ExceptionInterface
30 */
31 class UnicodeString extends AbstractUnicodeString
32 {
33 public function __construct(string $string = '')
34 {
35 $this->string = \normalizer_is_normalized($string) ? $string : \normalizer_normalize($string);
36 if (\false === $this->string) {
37 throw new InvalidArgumentException('Invalid UTF-8 string.');
38 }
39 }
40 public function append(string ...$suffix) : AbstractString
41 {
42 $str = clone $this;
43 $str->string = $this->string . (1 >= \count($suffix) ? $suffix[0] ?? '' : \implode('', $suffix));
44 \normalizer_is_normalized($str->string) ?: ($str->string = \normalizer_normalize($str->string));
45 if (\false === $str->string) {
46 throw new InvalidArgumentException('Invalid UTF-8 string.');
47 }
48 return $str;
49 }
50 public function chunk(int $length = 1) : array
51 {
52 if (1 > $length) {
53 throw new InvalidArgumentException('The chunk length must be greater than zero.');
54 }
55 if ('' === $this->string) {
56 return [];
57 }
58 $rx = '/(';
59 while (65535 < $length) {
60 $rx .= '\\X{65535}';
61 $length -= 65535;
62 }
63 $rx .= '\\X{' . $length . '})/u';
64 $str = clone $this;
65 $chunks = [];
66 foreach (\preg_split($rx, $this->string, -1, \PREG_SPLIT_DELIM_CAPTURE | \PREG_SPLIT_NO_EMPTY) as $chunk) {
67 $str->string = $chunk;
68 $chunks[] = clone $str;
69 }
70 return $chunks;
71 }
72 public function endsWith($suffix) : bool
73 {
74 if ($suffix instanceof AbstractString) {
75 $suffix = $suffix->string;
76 } elseif (\is_array($suffix) || $suffix instanceof \Traversable) {
77 return parent::endsWith($suffix);
78 } else {
79 $suffix = (string) $suffix;
80 }
81 $form = null === $this->ignoreCase ? \Normalizer::NFD : \Normalizer::NFC;
82 \normalizer_is_normalized($suffix, $form) ?: ($suffix = \normalizer_normalize($suffix, $form));
83 if ('' === $suffix || \false === $suffix) {
84 return \false;
85 }
86 if ($this->ignoreCase) {
87 return 0 === \mb_stripos(\grapheme_extract($this->string, \strlen($suffix), \GRAPHEME_EXTR_MAXBYTES, \strlen($this->string) - \strlen($suffix)), $suffix, 0, 'UTF-8');
88 }
89 return $suffix === \grapheme_extract($this->string, \strlen($suffix), \GRAPHEME_EXTR_MAXBYTES, \strlen($this->string) - \strlen($suffix));
90 }
91 public function equalsTo($string) : bool
92 {
93 if ($string instanceof AbstractString) {
94 $string = $string->string;
95 } elseif (\is_array($string) || $string instanceof \Traversable) {
96 return parent::equalsTo($string);
97 } else {
98 $string = (string) $string;
99 }
100 $form = null === $this->ignoreCase ? \Normalizer::NFD : \Normalizer::NFC;
101 \normalizer_is_normalized($string, $form) ?: ($string = \normalizer_normalize($string, $form));
102 if ('' !== $string && \false !== $string && $this->ignoreCase) {
103 return \strlen($string) === \strlen($this->string) && 0 === \mb_stripos($this->string, $string, 0, 'UTF-8');
104 }
105 return $string === $this->string;
106 }
107 public function indexOf($needle, int $offset = 0) : ?int
108 {
109 if ($needle instanceof AbstractString) {
110 $needle = $needle->string;
111 } elseif (\is_array($needle) || $needle instanceof \Traversable) {
112 return parent::indexOf($needle, $offset);
113 } else {
114 $needle = (string) $needle;
115 }
116 $form = null === $this->ignoreCase ? \Normalizer::NFD : \Normalizer::NFC;
117 \normalizer_is_normalized($needle, $form) ?: ($needle = \normalizer_normalize($needle, $form));
118 if ('' === $needle || \false === $needle) {
119 return null;
120 }
121 try {
122 $i = $this->ignoreCase ? \grapheme_stripos($this->string, $needle, $offset) : \grapheme_strpos($this->string, $needle, $offset);
123 } catch (\ValueError $e) {
124 return null;
125 }
126 return \false === $i ? null : $i;
127 }
128 public function indexOfLast($needle, int $offset = 0) : ?int
129 {
130 if ($needle instanceof AbstractString) {
131 $needle = $needle->string;
132 } elseif (\is_array($needle) || $needle instanceof \Traversable) {
133 return parent::indexOfLast($needle, $offset);
134 } else {
135 $needle = (string) $needle;
136 }
137 $form = null === $this->ignoreCase ? \Normalizer::NFD : \Normalizer::NFC;
138 \normalizer_is_normalized($needle, $form) ?: ($needle = \normalizer_normalize($needle, $form));
139 if ('' === $needle || \false === $needle) {
140 return null;
141 }
142 $string = $this->string;
143 if (0 > $offset) {
144 // workaround https://bugs.php.net/74264
145 if (0 > ($offset += \grapheme_strlen($needle))) {
146 $string = \grapheme_substr($string, 0, $offset);
147 }
148 $offset = 0;
149 }
150 $i = $this->ignoreCase ? \grapheme_strripos($string, $needle, $offset) : \grapheme_strrpos($string, $needle, $offset);
151 return \false === $i ? null : $i;
152 }
153 public function join(array $strings, string $lastGlue = null) : AbstractString
154 {
155 $str = parent::join($strings, $lastGlue);
156 \normalizer_is_normalized($str->string) ?: ($str->string = \normalizer_normalize($str->string));
157 return $str;
158 }
159 public function length() : int
160 {
161 return \grapheme_strlen($this->string);
162 }
163 /**
164 * @return static
165 */
166 public function normalize(int $form = self::NFC) : parent
167 {
168 $str = clone $this;
169 if (\in_array($form, [self::NFC, self::NFKC], \true)) {
170 \normalizer_is_normalized($str->string, $form) ?: ($str->string = \normalizer_normalize($str->string, $form));
171 } elseif (!\in_array($form, [self::NFD, self::NFKD], \true)) {
172 throw new InvalidArgumentException('Unsupported normalization form.');
173 } elseif (!\normalizer_is_normalized($str->string, $form)) {
174 $str->string = \normalizer_normalize($str->string, $form);
175 $str->ignoreCase = null;
176 }
177 return $str;
178 }
179 public function prepend(string ...$prefix) : AbstractString
180 {
181 $str = clone $this;
182 $str->string = (1 >= \count($prefix) ? $prefix[0] ?? '' : \implode('', $prefix)) . $this->string;
183 \normalizer_is_normalized($str->string) ?: ($str->string = \normalizer_normalize($str->string));
184 if (\false === $str->string) {
185 throw new InvalidArgumentException('Invalid UTF-8 string.');
186 }
187 return $str;
188 }
189 public function replace(string $from, string $to) : AbstractString
190 {
191 $str = clone $this;
192 \normalizer_is_normalized($from) ?: ($from = \normalizer_normalize($from));
193 if ('' !== $from && \false !== $from) {
194 $tail = $str->string;
195 $result = '';
196 $indexOf = $this->ignoreCase ? 'grapheme_stripos' : 'grapheme_strpos';
197 while ('' !== $tail && \false !== ($i = $indexOf($tail, $from))) {
198 $slice = \grapheme_substr($tail, 0, $i);
199 $result .= $slice . $to;
200 $tail = \substr($tail, \strlen($slice) + \strlen($from));
201 }
202 $str->string = $result . $tail;
203 \normalizer_is_normalized($str->string) ?: ($str->string = \normalizer_normalize($str->string));
204 if (\false === $str->string) {
205 throw new InvalidArgumentException('Invalid UTF-8 string.');
206 }
207 }
208 return $str;
209 }
210 public function replaceMatches(string $fromRegexp, $to) : AbstractString
211 {
212 $str = parent::replaceMatches($fromRegexp, $to);
213 \normalizer_is_normalized($str->string) ?: ($str->string = \normalizer_normalize($str->string));
214 return $str;
215 }
216 public function slice(int $start = 0, int $length = null) : AbstractString
217 {
218 $str = clone $this;
219 if (\PHP_VERSION_ID < 80000 && 0 > $start && \grapheme_strlen($this->string) < -$start) {
220 $start = 0;
221 }
222 $str->string = (string) \grapheme_substr($this->string, $start, $length ?? 2147483647);
223 return $str;
224 }
225 public function splice(string $replacement, int $start = 0, int $length = null) : AbstractString
226 {
227 $str = clone $this;
228 if (\PHP_VERSION_ID < 80000 && 0 > $start && \grapheme_strlen($this->string) < -$start) {
229 $start = 0;
230 }
231 $start = $start ? \strlen(\grapheme_substr($this->string, 0, $start)) : 0;
232 $length = $length ? \strlen(\grapheme_substr($this->string, $start, $length ?? 2147483647)) : $length;
233 $str->string = \substr_replace($this->string, $replacement, $start, $length ?? 2147483647);
234 \normalizer_is_normalized($str->string) ?: ($str->string = \normalizer_normalize($str->string));
235 if (\false === $str->string) {
236 throw new InvalidArgumentException('Invalid UTF-8 string.');
237 }
238 return $str;
239 }
240 public function split(string $delimiter, int $limit = null, int $flags = null) : array
241 {
242 if (1 > ($limit = $limit ?? 2147483647)) {
243 throw new InvalidArgumentException('Split limit must be a positive integer.');
244 }
245 if ('' === $delimiter) {
246 throw new InvalidArgumentException('Split delimiter is empty.');
247 }
248 if (null !== $flags) {
249 return parent::split($delimiter . 'u', $limit, $flags);
250 }
251 \normalizer_is_normalized($delimiter) ?: ($delimiter = \normalizer_normalize($delimiter));
252 if (\false === $delimiter) {
253 throw new InvalidArgumentException('Split delimiter is not a valid UTF-8 string.');
254 }
255 $str = clone $this;
256 $tail = $this->string;
257 $chunks = [];
258 $indexOf = $this->ignoreCase ? 'grapheme_stripos' : 'grapheme_strpos';
259 while (1 < $limit && \false !== ($i = $indexOf($tail, $delimiter))) {
260 $str->string = \grapheme_substr($tail, 0, $i);
261 $chunks[] = clone $str;
262 $tail = \substr($tail, \strlen($str->string) + \strlen($delimiter));
263 --$limit;
264 }
265 $str->string = $tail;
266 $chunks[] = clone $str;
267 return $chunks;
268 }
269 public function startsWith($prefix) : bool
270 {
271 if ($prefix instanceof AbstractString) {
272 $prefix = $prefix->string;
273 } elseif (\is_array($prefix) || $prefix instanceof \Traversable) {
274 return parent::startsWith($prefix);
275 } else {
276 $prefix = (string) $prefix;
277 }
278 $form = null === $this->ignoreCase ? \Normalizer::NFD : \Normalizer::NFC;
279 \normalizer_is_normalized($prefix, $form) ?: ($prefix = \normalizer_normalize($prefix, $form));
280 if ('' === $prefix || \false === $prefix) {
281 return \false;
282 }
283 if ($this->ignoreCase) {
284 return 0 === \mb_stripos(\grapheme_extract($this->string, \strlen($prefix), \GRAPHEME_EXTR_MAXBYTES), $prefix, 0, 'UTF-8');
285 }
286 return $prefix === \grapheme_extract($this->string, \strlen($prefix), \GRAPHEME_EXTR_MAXBYTES);
287 }
288 public function __wakeup()
289 {
290 if (!\is_string($this->string)) {
291 throw new \BadMethodCallException('Cannot unserialize ' . __CLASS__);
292 }
293 \normalizer_is_normalized($this->string) ?: ($this->string = \normalizer_normalize($this->string));
294 }
295 public function __clone()
296 {
297 if (null === $this->ignoreCase) {
298 \normalizer_is_normalized($this->string) ?: ($this->string = \normalizer_normalize($this->string));
299 }
300 $this->ignoreCase = \false;
301 }
302 }
303