Subversion-Projekte lars-tiefland.laravel_shop

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
148 lars 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
 
12
namespace Symfony\Component\String;
13
 
14
use Symfony\Component\String\Exception\ExceptionInterface;
15
use Symfony\Component\String\Exception\InvalidArgumentException;
16
 
17
/**
18
 * Represents a string of Unicode code points encoded as UTF-8.
19
 *
20
 * @author Nicolas Grekas <p@tchwork.com>
21
 * @author Hugo Hamon <hugohamon@neuf.fr>
22
 *
23
 * @throws ExceptionInterface
24
 */
25
class CodePointString extends AbstractUnicodeString
26
{
27
    public function __construct(string $string = '')
28
    {
29
        if ('' !== $string && !preg_match('//u', $string)) {
30
            throw new InvalidArgumentException('Invalid UTF-8 string.');
31
        }
32
 
33
        $this->string = $string;
34
    }
35
 
36
    public function append(string ...$suffix): static
37
    {
38
        $str = clone $this;
39
        $str->string .= 1 >= \count($suffix) ? ($suffix[0] ?? '') : implode('', $suffix);
40
 
41
        if (!preg_match('//u', $str->string)) {
42
            throw new InvalidArgumentException('Invalid UTF-8 string.');
43
        }
44
 
45
        return $str;
46
    }
47
 
48
    public function chunk(int $length = 1): array
49
    {
50
        if (1 > $length) {
51
            throw new InvalidArgumentException('The chunk length must be greater than zero.');
52
        }
53
 
54
        if ('' === $this->string) {
55
            return [];
56
        }
57
 
58
        $rx = '/(';
59
        while (65535 < $length) {
60
            $rx .= '.{65535}';
61
            $length -= 65535;
62
        }
63
        $rx .= '.{'.$length.'})/us';
64
 
65
        $str = clone $this;
66
        $chunks = [];
67
 
68
        foreach (preg_split($rx, $this->string, -1, \PREG_SPLIT_DELIM_CAPTURE | \PREG_SPLIT_NO_EMPTY) as $chunk) {
69
            $str->string = $chunk;
70
            $chunks[] = clone $str;
71
        }
72
 
73
        return $chunks;
74
    }
75
 
76
    public function codePointsAt(int $offset): array
77
    {
78
        $str = $offset ? $this->slice($offset, 1) : $this;
79
 
80
        return '' === $str->string ? [] : [mb_ord($str->string, 'UTF-8')];
81
    }
82
 
83
    public function endsWith(string|iterable|AbstractString $suffix): bool
84
    {
85
        if ($suffix instanceof AbstractString) {
86
            $suffix = $suffix->string;
87
        } elseif (!\is_string($suffix)) {
88
            return parent::endsWith($suffix);
89
        }
90
 
91
        if ('' === $suffix || !preg_match('//u', $suffix)) {
92
            return false;
93
        }
94
 
95
        if ($this->ignoreCase) {
96
            return preg_match('{'.preg_quote($suffix).'$}iuD', $this->string);
97
        }
98
 
99
        return \strlen($this->string) >= \strlen($suffix) && 0 === substr_compare($this->string, $suffix, -\strlen($suffix));
100
    }
101
 
102
    public function equalsTo(string|iterable|AbstractString $string): bool
103
    {
104
        if ($string instanceof AbstractString) {
105
            $string = $string->string;
106
        } elseif (!\is_string($string)) {
107
            return parent::equalsTo($string);
108
        }
109
 
110
        if ('' !== $string && $this->ignoreCase) {
111
            return \strlen($string) === \strlen($this->string) && 0 === mb_stripos($this->string, $string, 0, 'UTF-8');
112
        }
113
 
114
        return $string === $this->string;
115
    }
116
 
117
    public function indexOf(string|iterable|AbstractString $needle, int $offset = 0): ?int
118
    {
119
        if ($needle instanceof AbstractString) {
120
            $needle = $needle->string;
121
        } elseif (!\is_string($needle)) {
122
            return parent::indexOf($needle, $offset);
123
        }
124
 
125
        if ('' === $needle) {
126
            return null;
127
        }
128
 
129
        $i = $this->ignoreCase ? mb_stripos($this->string, $needle, $offset, 'UTF-8') : mb_strpos($this->string, $needle, $offset, 'UTF-8');
130
 
131
        return false === $i ? null : $i;
132
    }
133
 
134
    public function indexOfLast(string|iterable|AbstractString $needle, int $offset = 0): ?int
135
    {
136
        if ($needle instanceof AbstractString) {
137
            $needle = $needle->string;
138
        } elseif (!\is_string($needle)) {
139
            return parent::indexOfLast($needle, $offset);
140
        }
141
 
142
        if ('' === $needle) {
143
            return null;
144
        }
145
 
146
        $i = $this->ignoreCase ? mb_strripos($this->string, $needle, $offset, 'UTF-8') : mb_strrpos($this->string, $needle, $offset, 'UTF-8');
147
 
148
        return false === $i ? null : $i;
149
    }
150
 
151
    public function length(): int
152
    {
153
        return mb_strlen($this->string, 'UTF-8');
154
    }
155
 
156
    public function prepend(string ...$prefix): static
157
    {
158
        $str = clone $this;
159
        $str->string = (1 >= \count($prefix) ? ($prefix[0] ?? '') : implode('', $prefix)).$this->string;
160
 
161
        if (!preg_match('//u', $str->string)) {
162
            throw new InvalidArgumentException('Invalid UTF-8 string.');
163
        }
164
 
165
        return $str;
166
    }
167
 
168
    public function replace(string $from, string $to): static
169
    {
170
        $str = clone $this;
171
 
172
        if ('' === $from || !preg_match('//u', $from)) {
173
            return $str;
174
        }
175
 
176
        if ('' !== $to && !preg_match('//u', $to)) {
177
            throw new InvalidArgumentException('Invalid UTF-8 string.');
178
        }
179
 
180
        if ($this->ignoreCase) {
181
            $str->string = implode($to, preg_split('{'.preg_quote($from).'}iuD', $this->string));
182
        } else {
183
            $str->string = str_replace($from, $to, $this->string);
184
        }
185
 
186
        return $str;
187
    }
188
 
189
    public function slice(int $start = 0, int $length = null): static
190
    {
191
        $str = clone $this;
192
        $str->string = mb_substr($this->string, $start, $length, 'UTF-8');
193
 
194
        return $str;
195
    }
196
 
197
    public function splice(string $replacement, int $start = 0, int $length = null): static
198
    {
199
        if (!preg_match('//u', $replacement)) {
200
            throw new InvalidArgumentException('Invalid UTF-8 string.');
201
        }
202
 
203
        $str = clone $this;
204
        $start = $start ? \strlen(mb_substr($this->string, 0, $start, 'UTF-8')) : 0;
205
        $length = $length ? \strlen(mb_substr($this->string, $start, $length, 'UTF-8')) : $length;
206
        $str->string = substr_replace($this->string, $replacement, $start, $length ?? \PHP_INT_MAX);
207
 
208
        return $str;
209
    }
210
 
211
    public function split(string $delimiter, int $limit = null, int $flags = null): array
212
    {
213
        if (1 > $limit ??= \PHP_INT_MAX) {
214
            throw new InvalidArgumentException('Split limit must be a positive integer.');
215
        }
216
 
217
        if ('' === $delimiter) {
218
            throw new InvalidArgumentException('Split delimiter is empty.');
219
        }
220
 
221
        if (null !== $flags) {
222
            return parent::split($delimiter.'u', $limit, $flags);
223
        }
224
 
225
        if (!preg_match('//u', $delimiter)) {
226
            throw new InvalidArgumentException('Split delimiter is not a valid UTF-8 string.');
227
        }
228
 
229
        $str = clone $this;
230
        $chunks = $this->ignoreCase
231
            ? preg_split('{'.preg_quote($delimiter).'}iuD', $this->string, $limit)
232
            : explode($delimiter, $this->string, $limit);
233
 
234
        foreach ($chunks as &$chunk) {
235
            $str->string = $chunk;
236
            $chunk = clone $str;
237
        }
238
 
239
        return $chunks;
240
    }
241
 
242
    public function startsWith(string|iterable|AbstractString $prefix): bool
243
    {
244
        if ($prefix instanceof AbstractString) {
245
            $prefix = $prefix->string;
246
        } elseif (!\is_string($prefix)) {
247
            return parent::startsWith($prefix);
248
        }
249
 
250
        if ('' === $prefix || !preg_match('//u', $prefix)) {
251
            return false;
252
        }
253
 
254
        if ($this->ignoreCase) {
255
            return 0 === mb_stripos($this->string, $prefix, 0, 'UTF-8');
256
        }
257
 
258
        return 0 === strncmp($this->string, $prefix, \strlen($prefix));
259
    }
260
}