PluginProbe ʕ •ᴥ•ʔ
MailPoet – Newsletters, Email Marketing, and Automation / 5.34.2
MailPoet – Newsletters, Email Marketing, and Automation v5.34.2
5.34.2 5.34.1 5.34.0 5.33.1 5.33.0 5.32.0 5.31.0 5.30.0 5.29.0 5.28.1 5.28.0 5.27.0 5.26.0 5.26.1 5.25.0 5.24.0 4.43.0 4.43.1 4.44.0 4.44.1 4.45.0 4.46.0 4.47.0 4.48.0 4.48.1 4.48.2 4.49.0 4.49.1 4.5.0 4.5.1 4.5.2 4.50.0 4.50.1 4.51.0 4.51.1 4.51.2 4.52.0 4.53.0 4.54.0 4.55.0 4.56.0 4.57.0 4.58.0 4.58.1 4.58.2 4.6.0 4.6.1 4.6.2 4.7.0 4.7.1 4.8.0 4.8.1 4.9.0 5.0.0 5.0.1 5.0.2 5.1.0 5.1.1 5.10.0 5.10.1 5.11.0 5.12.0 5.12.1 5.12.10 5.12.11 5.12.12 5.12.13 5.12.2 5.12.3 5.12.4 5.12.5 5.12.6 5.12.7 5.12.8 5.12.9 5.13.0 5.13.1 5.13.2 5.14.0 5.14.1 5.14.2 5.14.3 5.15.0 5.15.1 5.16.0 5.16.1 5.16.2 5.16.3 5.16.4 5.17.0 5.17.1 5.17.2 5.17.3 5.17.4 5.17.5 5.17.6 5.18.0 5.19.0 5.2.0 5.2.1 5.2.2 5.2.3 5.20.0 5.21.0 5.21.1 5.21.2 5.21.3 5.22.0 5.22.1 5.22.2 5.22.3 5.22.4 5.23.0 5.23.1 5.23.2 5.3.0 5.3.1 5.3.2 5.3.3 5.3.4 5.3.5 5.3.6 5.3.7 5.4.0 5.4.1 5.4.2 5.5.0 5.5.1 5.5.2 5.6.0 5.6.1 5.6.2 5.6.3 5.6.4 5.7.0 5.7.1 5.8.0 5.8.1 5.9.0 3.0.0-beta.15 3.7.1 3.0.0-beta.16 3.7.2 3.0.0-beta.17 3.7.3 3.0.0-beta.18 3.7.4 3.0.0-beta.19 3.7.5 3.0.0-beta.2 3.7.6 3.0.0-beta.20 3.7.8 3.0.0-beta.21 3.70.0 3.0.0-beta.22 3.71.0 3.0.0-beta.23 3.71.1 3.0.0-beta.23.1 3.71.2 3.0.0-beta.23.2 3.71.3 3.0.0-beta.24 3.72.0 3.0.0-beta.25 3.73.0 3.0.0-beta.26 3.73.1 3.0.0-beta.27 3.73.2 3.0.0-beta.28 3.74.0 3.0.0-beta.29 3.74.1 3.0.0-beta.3 3.74.2 3.0.0-beta.30 3.74.3 3.0.0-beta.31 3.75.0 3.0.0-beta.32 3.75.1 3.0.0-beta.33 3.76.0 3.0.0-beta.33.1 3.77.0 3.0.0-beta.34.0.0 3.77.1 3.0.0-beta.36.0.0 3.78.0 3.0.0-beta.36.0.1 3.79.0 3.0.0-beta.36.2.0 3.8 3.0.0-beta.36.3.0 3.8.1 3.0.0-beta.36.3.1 3.8.2 3.0.0-beta.37.0.0 3.8.3 3.0.0-beta.4 3.8.4 3.0.0-beta.5 3.8.5 3.0.0-beta.6 3.8.6 3.0.0-beta.7 3.80.0 3.0.0-beta.7.1 3.81.0 3.0.0-beta.8 3.82.0 3.0.0-beta.9 3.83.0 3.0.0-rc.1.0.0 3.84.0 3.0.0-rc.1.0.1 3.84.1 3.0.0-rc.1.0.2 3.85.0 3.0.0-rc.1.0.3 3.85.1 3.0.0-rc.1.0.4 3.86.0 3.0.0-rc.2.0.0 3.87.0 3.0.0-rc.2.0.1 3.87.1 3.0.0-rc.2.0.2 3.87.2 3.0.0-rc.2.0.3 3.88.0 3.0.1 3.88.1 3.0.2 3.88.2 3.0.3 3.89.0 3.0.4 3.89.1 3.0.5 3.89.2 3.0.6 3.89.3 3.0.7 3.89.4 3.0.8 3.9.0 3.0.9 3.9.1 3.1.0 3.90.0 3.10 3.90.1 3.10.1 3.90.2 3.100.0 3.91.0 3.100.1 3.91.1 3.100.2 3.92.0 3.101.0 3.92.1 3.101.1 3.93.0 3.102.0 3.93.1 3.102.1 3.94.0 3.103.0 3.95.0 3.103.1 3.95.1 3.11.0 3.96.0 3.11.1 3.96.1 3.11.2 3.97.0 3.11.3 3.98.0 3.11.4 3.98.1 3.11.5 3.99.0 3.12.0 3.99.1 3.12.1 4.0.0 3.13.0 4.0.1 3.14.0 4.1.0 3.14.1 4.1.1 3.15.0 4.10.0 3.16.0 4.11.0 3.16.1 4.11.1 3.16.2 4.12.0 3.16.3 4.12.1 3.17.0 4.12.2 3.17.1 4.13.0 3.17.2 4.14.0 3.18.0 4.15.0 3.18.1 4.16.0 3.18.2 4.17.0 3.19.0 4.17.1 3.19.1 4.18.0 3.19.2 4.18.1 3.19.3 4.19.0 3.2.0 4.2.0 3.2.1 4.20.0 3.2.2 4.20.1 3.2.3 4.20.2 3.2.4 4.21.0 3.2.5 4.22.0 3.20.0 4.22.1 3.21.0 4.22.2 3.21.1 4.23.0 3.22.0 4.24.0 3.23.0 4.25.0 3.23.1 4.26.0 3.23.2 4.26.1 3.24.0 4.27.0 3.25.0 4.28.0 3.25.1 4.29.0 3.26.0 4.3.0 3.26.1 4.3.1 3.27.0 4.30.0 3.28.0 4.31.0 3.29.0 4.31.1 3.3.0 4.32.0 3.3.1 4.33.0 3.3.2 4.34.0 3.3.3 4.35.0 3.3.4 4.35.1 3.3.5 4.36.0 3.3.6 4.37.0 3.30.0 4.38.0 3.31.0 4.39.0 3.31.1 4.4.0 3.32.0 4.40.0 3.32.1 4.41.0 3.32.2 4.41.1 3.33.0 4.41.2 3.34.0 4.41.3 3.34.1 4.42.0 3.34.2 4.42.1 3.34.3 3.34.4 3.35.0 3.35.1 3.35.3 3.35.4 3.36.0 3.37.0 3.37.1 3.37.2 3.37.3 3.38.0 3.38.1 3.39.0 3.39.1 3.39.2 3.4.0 3.4.1 3.4.2 3.4.3 3.4.4 3.40.0 3.40.1 3.41.0 3.41.1 3.41.2 3.42.0 3.42.1 3.42.2 3.42.3 3.43.0 3.43.1 3.44.0 3.45.0 3.45.1 3.46.0 3.46.1 3.46.10 3.46.11 3.46.12 3.46.13 3.46.14 3.46.2 3.46.3 3.46.4 3.46.5 3.46.6 3.46.7 3.46.8 3.46.9 3.47.0 3.47.1 3.47.10 3.47.11 3.47.2 3.47.3 3.47.5 3.47.6 3.47.7 3.47.9 3.48.0 3.48.1 3.49.0 3.49.1 3.5.0 3.5.1 3.50.0 3.51.0 3.51.1 3.51.2 3.52.0 3.53.0 3.54.0 3.54.1 3.54.2 3.54.3 3.55.0 3.55.1 3.56.0 3.56.1 3.56.2 3.57.0 3.57.1 3.58.0 3.59.0 3.59.1 3.59.2 3.6.0 3.6.1 3.6.2 3.6.3 3.6.4 3.6.5 3.6.6 3.6.7 3.60.0 3.60.1 3.60.10 3.60.11 3.60.12 3.60.2 3.60.3 3.60.4 3.60.6 3.60.7 3.60.8 3.60.9 3.61.0 3.62.0 3.62.1 3.63.0 3.64.0 3.64.1 3.64.2 3.64.3 3.65.0 trunk 3.65.1 3.0.0 3.66.0 3.0.0-beta.1 3.67.0 3.0.0-beta.10 3.67.1 3.0.0-beta.11 3.68.0 3.0.0-beta.12 3.69.0 3.0.0-beta.13 3.69.1 3.0.0-beta.14 3.7.0
mailpoet / vendor-prefixed / symfony / string / AbstractString.php
mailpoet / vendor-prefixed / symfony / string Last commit date
Exception 2 years ago Inflector 8 months ago Resources 8 months ago Slugger 2 years ago AbstractString.php 2 years ago AbstractUnicodeString.php 8 months ago ByteString.php 2 years ago CodePointString.php 2 years ago LazyString.php 2 years ago UnicodeString.php 2 years ago index.php 2 years ago
AbstractString.php
468 lines
1 <?php
2 namespace MailPoetVendor\Symfony\Component\String;
3 if (!defined('ABSPATH')) exit;
4 use MailPoetVendor\Symfony\Component\String\Exception\ExceptionInterface;
5 use MailPoetVendor\Symfony\Component\String\Exception\InvalidArgumentException;
6 use MailPoetVendor\Symfony\Component\String\Exception\RuntimeException;
7 abstract class AbstractString implements \Stringable, \JsonSerializable
8 {
9 public const PREG_PATTERN_ORDER = \PREG_PATTERN_ORDER;
10 public const PREG_SET_ORDER = \PREG_SET_ORDER;
11 public const PREG_OFFSET_CAPTURE = \PREG_OFFSET_CAPTURE;
12 public const PREG_UNMATCHED_AS_NULL = \PREG_UNMATCHED_AS_NULL;
13 public const PREG_SPLIT = 0;
14 public const PREG_SPLIT_NO_EMPTY = \PREG_SPLIT_NO_EMPTY;
15 public const PREG_SPLIT_DELIM_CAPTURE = \PREG_SPLIT_DELIM_CAPTURE;
16 public const PREG_SPLIT_OFFSET_CAPTURE = \PREG_SPLIT_OFFSET_CAPTURE;
17 protected $string = '';
18 protected $ignoreCase = \false;
19 public abstract function __construct(string $string = '');
20 public static function unwrap(array $values) : array
21 {
22 foreach ($values as $k => $v) {
23 if ($v instanceof self) {
24 $values[$k] = $v->__toString();
25 } elseif (\is_array($v) && $values[$k] !== ($v = static::unwrap($v))) {
26 $values[$k] = $v;
27 }
28 }
29 return $values;
30 }
31 public static function wrap(array $values) : array
32 {
33 $i = 0;
34 $keys = null;
35 foreach ($values as $k => $v) {
36 if (\is_string($k) && '' !== $k && $k !== ($j = (string) new static($k))) {
37 $keys = $keys ?? \array_keys($values);
38 $keys[$i] = $j;
39 }
40 if (\is_string($v)) {
41 $values[$k] = new static($v);
42 } elseif (\is_array($v) && $values[$k] !== ($v = static::wrap($v))) {
43 $values[$k] = $v;
44 }
45 ++$i;
46 }
47 return null !== $keys ? \array_combine($keys, $values) : $values;
48 }
49 public function after($needle, bool $includeNeedle = \false, int $offset = 0) : self
50 {
51 $str = clone $this;
52 $i = \PHP_INT_MAX;
53 foreach ((array) $needle as $n) {
54 $n = (string) $n;
55 $j = $this->indexOf($n, $offset);
56 if (null !== $j && $j < $i) {
57 $i = $j;
58 $str->string = $n;
59 }
60 }
61 if (\PHP_INT_MAX === $i) {
62 return $str;
63 }
64 if (!$includeNeedle) {
65 $i += $str->length();
66 }
67 return $this->slice($i);
68 }
69 public function afterLast($needle, bool $includeNeedle = \false, int $offset = 0) : self
70 {
71 $str = clone $this;
72 $i = null;
73 foreach ((array) $needle as $n) {
74 $n = (string) $n;
75 $j = $this->indexOfLast($n, $offset);
76 if (null !== $j && $j >= $i) {
77 $i = $offset = $j;
78 $str->string = $n;
79 }
80 }
81 if (null === $i) {
82 return $str;
83 }
84 if (!$includeNeedle) {
85 $i += $str->length();
86 }
87 return $this->slice($i);
88 }
89 public abstract function append(string ...$suffix) : self;
90 public function before($needle, bool $includeNeedle = \false, int $offset = 0) : self
91 {
92 $str = clone $this;
93 $i = \PHP_INT_MAX;
94 foreach ((array) $needle as $n) {
95 $n = (string) $n;
96 $j = $this->indexOf($n, $offset);
97 if (null !== $j && $j < $i) {
98 $i = $j;
99 $str->string = $n;
100 }
101 }
102 if (\PHP_INT_MAX === $i) {
103 return $str;
104 }
105 if ($includeNeedle) {
106 $i += $str->length();
107 }
108 return $this->slice(0, $i);
109 }
110 public function beforeLast($needle, bool $includeNeedle = \false, int $offset = 0) : self
111 {
112 $str = clone $this;
113 $i = null;
114 foreach ((array) $needle as $n) {
115 $n = (string) $n;
116 $j = $this->indexOfLast($n, $offset);
117 if (null !== $j && $j >= $i) {
118 $i = $offset = $j;
119 $str->string = $n;
120 }
121 }
122 if (null === $i) {
123 return $str;
124 }
125 if ($includeNeedle) {
126 $i += $str->length();
127 }
128 return $this->slice(0, $i);
129 }
130 public function bytesAt(int $offset) : array
131 {
132 $str = $this->slice($offset, 1);
133 return '' === $str->string ? [] : \array_values(\unpack('C*', $str->string));
134 }
135 public abstract function camel() : self;
136 public abstract function chunk(int $length = 1) : array;
137 public function collapseWhitespace() : self
138 {
139 $str = clone $this;
140 $str->string = \trim(\preg_replace("/(?:[ \n\r\t\f]{2,}+|[\n\r\t\f])/", ' ', $str->string), " \n\r\t\f");
141 return $str;
142 }
143 public function containsAny($needle) : bool
144 {
145 return null !== $this->indexOf($needle);
146 }
147 public function endsWith($suffix) : bool
148 {
149 if (!\is_array($suffix) && !$suffix instanceof \Traversable) {
150 throw new \TypeError(\sprintf('Method "%s()" must be overridden by class "%s" to deal with non-iterable values.', __FUNCTION__, static::class));
151 }
152 foreach ($suffix as $s) {
153 if ($this->endsWith((string) $s)) {
154 return \true;
155 }
156 }
157 return \false;
158 }
159 public function ensureEnd(string $suffix) : self
160 {
161 if (!$this->endsWith($suffix)) {
162 return $this->append($suffix);
163 }
164 $suffix = \preg_quote($suffix);
165 $regex = '{(' . $suffix . ')(?:' . $suffix . ')++$}D';
166 return $this->replaceMatches($regex . ($this->ignoreCase ? 'i' : ''), '$1');
167 }
168 public function ensureStart(string $prefix) : self
169 {
170 $prefix = new static($prefix);
171 if (!$this->startsWith($prefix)) {
172 return $this->prepend($prefix);
173 }
174 $str = clone $this;
175 $i = $prefixLen = $prefix->length();
176 while ($this->indexOf($prefix, $i) === $i) {
177 $str = $str->slice($prefixLen);
178 $i += $prefixLen;
179 }
180 return $str;
181 }
182 public function equalsTo($string) : bool
183 {
184 if (!\is_array($string) && !$string instanceof \Traversable) {
185 throw new \TypeError(\sprintf('Method "%s()" must be overridden by class "%s" to deal with non-iterable values.', __FUNCTION__, static::class));
186 }
187 foreach ($string as $s) {
188 if ($this->equalsTo((string) $s)) {
189 return \true;
190 }
191 }
192 return \false;
193 }
194 public abstract function folded() : self;
195 public function ignoreCase() : self
196 {
197 $str = clone $this;
198 $str->ignoreCase = \true;
199 return $str;
200 }
201 public function indexOf($needle, int $offset = 0) : ?int
202 {
203 if (!\is_array($needle) && !$needle instanceof \Traversable) {
204 throw new \TypeError(\sprintf('Method "%s()" must be overridden by class "%s" to deal with non-iterable values.', __FUNCTION__, static::class));
205 }
206 $i = \PHP_INT_MAX;
207 foreach ($needle as $n) {
208 $j = $this->indexOf((string) $n, $offset);
209 if (null !== $j && $j < $i) {
210 $i = $j;
211 }
212 }
213 return \PHP_INT_MAX === $i ? null : $i;
214 }
215 public function indexOfLast($needle, int $offset = 0) : ?int
216 {
217 if (!\is_array($needle) && !$needle instanceof \Traversable) {
218 throw new \TypeError(\sprintf('Method "%s()" must be overridden by class "%s" to deal with non-iterable values.', __FUNCTION__, static::class));
219 }
220 $i = null;
221 foreach ($needle as $n) {
222 $j = $this->indexOfLast((string) $n, $offset);
223 if (null !== $j && $j >= $i) {
224 $i = $offset = $j;
225 }
226 }
227 return $i;
228 }
229 public function isEmpty() : bool
230 {
231 return '' === $this->string;
232 }
233 public abstract function join(array $strings, ?string $lastGlue = null) : self;
234 public function jsonSerialize() : string
235 {
236 return $this->string;
237 }
238 public abstract function length() : int;
239 public abstract function lower() : self;
240 public abstract function match(string $regexp, int $flags = 0, int $offset = 0) : array;
241 public abstract function padBoth(int $length, string $padStr = ' ') : self;
242 public abstract function padEnd(int $length, string $padStr = ' ') : self;
243 public abstract function padStart(int $length, string $padStr = ' ') : self;
244 public abstract function prepend(string ...$prefix) : self;
245 public function repeat(int $multiplier) : self
246 {
247 if (0 > $multiplier) {
248 throw new InvalidArgumentException(\sprintf('Multiplier must be positive, %d given.', $multiplier));
249 }
250 $str = clone $this;
251 $str->string = \str_repeat($str->string, $multiplier);
252 return $str;
253 }
254 public abstract function replace(string $from, string $to) : self;
255 public abstract function replaceMatches(string $fromRegexp, $to) : self;
256 public abstract function reverse() : self;
257 public abstract function slice(int $start = 0, ?int $length = null) : self;
258 public abstract function snake() : self;
259 public abstract function splice(string $replacement, int $start = 0, ?int $length = null) : self;
260 public function split(string $delimiter, ?int $limit = null, ?int $flags = null) : array
261 {
262 if (null === $flags) {
263 throw new \TypeError('Split behavior when $flags is null must be implemented by child classes.');
264 }
265 if ($this->ignoreCase) {
266 $delimiter .= 'i';
267 }
268 \set_error_handler(static function ($t, $m) {
269 throw new InvalidArgumentException($m);
270 });
271 try {
272 if (\false === ($chunks = \preg_split($delimiter, $this->string, $limit, $flags))) {
273 $lastError = \preg_last_error();
274 foreach (\get_defined_constants(\true)['pcre'] as $k => $v) {
275 if ($lastError === $v && '_ERROR' === \substr($k, -6)) {
276 throw new RuntimeException('Splitting failed with ' . $k . '.');
277 }
278 }
279 throw new RuntimeException('Splitting failed with unknown error code.');
280 }
281 } finally {
282 \restore_error_handler();
283 }
284 $str = clone $this;
285 if (self::PREG_SPLIT_OFFSET_CAPTURE & $flags) {
286 foreach ($chunks as &$chunk) {
287 $str->string = $chunk[0];
288 $chunk[0] = clone $str;
289 }
290 } else {
291 foreach ($chunks as &$chunk) {
292 $str->string = $chunk;
293 $chunk = clone $str;
294 }
295 }
296 return $chunks;
297 }
298 public function startsWith($prefix) : bool
299 {
300 if (!\is_array($prefix) && !$prefix instanceof \Traversable) {
301 throw new \TypeError(\sprintf('Method "%s()" must be overridden by class "%s" to deal with non-iterable values.', __FUNCTION__, static::class));
302 }
303 foreach ($prefix as $prefix) {
304 if ($this->startsWith((string) $prefix)) {
305 return \true;
306 }
307 }
308 return \false;
309 }
310 public abstract function title(bool $allWords = \false) : self;
311 public function toByteString(?string $toEncoding = null) : ByteString
312 {
313 $b = new ByteString();
314 $toEncoding = \in_array($toEncoding, ['utf8', 'utf-8', 'UTF8'], \true) ? 'UTF-8' : $toEncoding;
315 if (null === $toEncoding || $toEncoding === ($fromEncoding = $this instanceof AbstractUnicodeString || \preg_match('//u', $b->string) ? 'UTF-8' : 'Windows-1252')) {
316 $b->string = $this->string;
317 return $b;
318 }
319 \set_error_handler(static function ($t, $m) {
320 throw new InvalidArgumentException($m);
321 });
322 try {
323 try {
324 $b->string = \mb_convert_encoding($this->string, $toEncoding, 'UTF-8');
325 } catch (InvalidArgumentException|\ValueError $e) {
326 if (!\function_exists('iconv')) {
327 if ($e instanceof \ValueError) {
328 throw new InvalidArgumentException($e->getMessage(), $e->getCode(), $e);
329 }
330 throw $e;
331 }
332 $b->string = \iconv('UTF-8', $toEncoding, $this->string);
333 }
334 } finally {
335 \restore_error_handler();
336 }
337 return $b;
338 }
339 public function toCodePointString() : CodePointString
340 {
341 return new CodePointString($this->string);
342 }
343 public function toString() : string
344 {
345 return $this->string;
346 }
347 public function toUnicodeString() : UnicodeString
348 {
349 return new UnicodeString($this->string);
350 }
351 public abstract function trim(string $chars = " \t\n\r\x00\v\f ") : self;
352 public abstract function trimEnd(string $chars = " \t\n\r\x00\v\f ") : self;
353 public function trimPrefix($prefix) : self
354 {
355 if (\is_array($prefix) || $prefix instanceof \Traversable) {
356 foreach ($prefix as $s) {
357 $t = $this->trimPrefix($s);
358 if ($t->string !== $this->string) {
359 return $t;
360 }
361 }
362 return clone $this;
363 }
364 $str = clone $this;
365 if ($prefix instanceof self) {
366 $prefix = $prefix->string;
367 } else {
368 $prefix = (string) $prefix;
369 }
370 if ('' !== $prefix && \strlen($this->string) >= \strlen($prefix) && 0 === \substr_compare($this->string, $prefix, 0, \strlen($prefix), $this->ignoreCase)) {
371 $str->string = \substr($this->string, \strlen($prefix));
372 }
373 return $str;
374 }
375 public abstract function trimStart(string $chars = " \t\n\r\x00\v\f ") : self;
376 public function trimSuffix($suffix) : self
377 {
378 if (\is_array($suffix) || $suffix instanceof \Traversable) {
379 foreach ($suffix as $s) {
380 $t = $this->trimSuffix($s);
381 if ($t->string !== $this->string) {
382 return $t;
383 }
384 }
385 return clone $this;
386 }
387 $str = clone $this;
388 if ($suffix instanceof self) {
389 $suffix = $suffix->string;
390 } else {
391 $suffix = (string) $suffix;
392 }
393 if ('' !== $suffix && \strlen($this->string) >= \strlen($suffix) && 0 === \substr_compare($this->string, $suffix, -\strlen($suffix), null, $this->ignoreCase)) {
394 $str->string = \substr($this->string, 0, -\strlen($suffix));
395 }
396 return $str;
397 }
398 public function truncate(int $length, string $ellipsis = '', bool $cut = \true) : self
399 {
400 $stringLength = $this->length();
401 if ($stringLength <= $length) {
402 return clone $this;
403 }
404 $ellipsisLength = '' !== $ellipsis ? (new static($ellipsis))->length() : 0;
405 if ($length < $ellipsisLength) {
406 $ellipsisLength = 0;
407 }
408 if (!$cut) {
409 if (null === ($length = $this->indexOf([' ', "\r", "\n", "\t"], ($length ?: 1) - 1))) {
410 return clone $this;
411 }
412 $length += $ellipsisLength;
413 }
414 $str = $this->slice(0, $length - $ellipsisLength);
415 return $ellipsisLength ? $str->trimEnd()->append($ellipsis) : $str;
416 }
417 public abstract function upper() : self;
418 public abstract function width(bool $ignoreAnsiDecoration = \true) : int;
419 public function wordwrap(int $width = 75, string $break = "\n", bool $cut = \false) : self
420 {
421 $lines = '' !== $break ? $this->split($break) : [clone $this];
422 $chars = [];
423 $mask = '';
424 if (1 === \count($lines) && '' === $lines[0]->string) {
425 return $lines[0];
426 }
427 foreach ($lines as $i => $line) {
428 if ($i) {
429 $chars[] = $break;
430 $mask .= '#';
431 }
432 foreach ($line->chunk() as $char) {
433 $chars[] = $char->string;
434 $mask .= ' ' === $char->string ? ' ' : '?';
435 }
436 }
437 $string = '';
438 $j = 0;
439 $b = $i = -1;
440 $mask = \wordwrap($mask, $width, '#', $cut);
441 while (\false !== ($b = \strpos($mask, '#', $b + 1))) {
442 for (++$i; $i < $b; ++$i) {
443 $string .= $chars[$j];
444 unset($chars[$j++]);
445 }
446 if ($break === $chars[$j] || ' ' === $chars[$j]) {
447 unset($chars[$j++]);
448 }
449 $string .= $break;
450 }
451 $str = clone $this;
452 $str->string = $string . \implode('', $chars);
453 return $str;
454 }
455 public function __sleep() : array
456 {
457 return ['string'];
458 }
459 public function __clone()
460 {
461 $this->ignoreCase = \false;
462 }
463 public function __toString() : string
464 {
465 return $this->string;
466 }
467 }
468