Completed
Push — master ( 1d9387...a47b74 )
by Garrett
08:57
created

StrObj::asciify()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 11
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
c 1
b 0
f 1
dl 0
loc 11
rs 9.4286
cc 3
eloc 7
nc 4
nop 1
1
<?php
2
3
namespace StringObject;
4
5
class StrObj extends AnyStrObj implements \ArrayAccess, \Countable, \Iterator
6
{
7
    // CONSTANTS
8
9
    const NORMAL = 0;
10
    const START = 0;
11
    const END = 1;
12
    const BOTH_ENDS = 2;
13
    const CASE_INSENSITIVE = 4;
14
    const REVERSE = 8;
15
    const EXACT_POSITION = 16;
16
    const CURRENT_LOCALE = 32;
17
    const NATURAL_ORDER = 64;
18
    const FIRST_N = 128;
19
    const C_STYLE = 256;
20
    const META = 512;
21
    const LAZY = 1024;
22
    const GREEDY = 2048;
23
24
    // PROPERTIES
25
26
    protected $raw;
27
    protected $token = false;
28
    protected $caret = 0;
29
30
    // MAGIC METHODS
31
32
    /**
33
     * @return mixed
34
     */
35
    public function __get($name)
36
    {
37
        return $this->$name;
38
    }
39
40
    /**
41
     * @return string
42
     */
43
    public function __toString()
44
    {
45
        return $this->raw;
46
    }
47
48 View Code Duplication
    public function toArray($delim = '', $limit = null)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
49
    {
50
        if (empty($delim)) {
51
            return \str_split($this->raw);
52
        }
53
        if (is_int($delim)) {
54
            return \str_split($this->raw, $delim);
55
        }
56
        if ($limit === null) {
57
            return \explode($delim, $this->raw);
58
        }
59
        return \explode($delim, $this->raw, $limit);
60
    }
61
62
    // INFORMATIONAL METHODS
63
64
    public function charAt($offset)
65
    {
66
        return new self($this->raw{$offset});
67
    }
68
69
    /**
70
     * @param integer $offset
71
     */
72
    public function charCodeAt($offset)
73
    {
74
        return \ord($this->raw{$offset});
75
    }
76
77
    public function compareTo($str, $flags = self::NORMAL, $length = 1)
78
    {
79
        $flagsmap = [
80
            self::NORMAL => 'strcmp',
81
            self::CASE_INSENSITIVE => 'strcasecmp',
82
            self::CURRENT_LOCALE => 'strcoll',
83
            self::NATURAL_ORDER => 'strnatcmp',
84
            (self::NATURAL_ORDER | self::CASE_INSENSITIVE) => 'strnatcasecmp',
85
            self::FIRST_N => 'strncmp',
86
            (self::FIRST_N | self::CASE_INSENSITIVE) => 'strncasecmp',
87
        ];
88
89
        if ($flags & self::FIRST_N) {
90
            return \call_user_func($flagsmap[$flags], $this->raw, $str, $length);
91
        }
92
        return \call_user_func($flagsmap[$flags], $this->raw, $str);
93
    }
94
95
    public function indexOf($needle, $offset = 0, $flags = self::NORMAL)
96
    {
97
        // strip out bits we don't understand
98
        $flags &= (self::REVERSE | self::CASE_INSENSITIVE);
99
100
        $flagsmap = [
101
            self::NORMAL => 'strpos',
102
            self::CASE_INSENSITIVE => 'stripos',
103
            self::REVERSE => 'strrpos',
104
            (self::REVERSE | self::CASE_INSENSITIVE) => 'strripos',
105
        ];
106
        return \call_user_func($flagsmap[$flags], $this->raw, $needle, $offset);
107
    }
108
109
    public function length()
110
    {
111
        return \strlen($this->raw);
112
    }
113
114
    // MODIFYING METHODS
115
116
    public function append($str)
117
    {
118
        return new self($this->raw . $str);
119
    }
120
121
    public function chunk($length = 76, $ending = "\r\n")
122
    {
123
        return new self(\chunk_split($this->raw, $length, $ending));
124
    }
125
126
    public function concat($str)
127
    {
128
        return $this->append($str);
129
    }
130
131
    public function escape($flags = self::NORMAL, $charlist = '')
132
    {
133
        $flagsmap = [
134
            self::NORMAL => 'addslashes',
135
            self::C_STYLE => 'addcslashes',
136
            self::META => 'quotemeta',
137
        ];
138
        if ($flags === self::C_STYLE) {
139
            return new self(\call_user_func($flagsmap[$flags], $this->raw, $charlist));
140
        }
141
        return new self(\call_user_func($flagsmap[$flags], $this->raw));
142
    }
143
144
    public function insertAt($str, $offset)
145
    {
146
        return $this->replaceSubstr($str, $offset, 0);
147
    }
148
149
    public function nextToken($delim)
150
    {
151
        if ($this->token) {
152
            return new self(\strtok($delim));
153
        }
154
        $this->token = true;
155
        return new self(\strtok($this->raw, $delim));
156
    }
157
158
    public function pad($newlength, $padding = ' ', $flags = self::END)
159
    {
160
        return new self(\str_pad($this->raw, $newlength, $padding, $flags));
161
    }
162
163
    public function prepend($str)
164
    {
165
        return new self($str . $this->raw);
166
    }
167
168
    public function remove($str, $flags = self::NORMAL)
169
    {
170
        return $this->replace($str, '', $flags);
171
    }
172
173
    public function removeSubstr($start, $length = null)
174
    {
175
        return $this->replaceSubstr('', $start, $length);
176
    }
177
178
    public function repeat($times)
179
    {
180
        return new self(\str_repeat($this->raw, $times));
181
    }
182
183
    /**
184
     * @param string $replace
185
     */
186
    public function replace($search, $replace, $flags = self::NORMAL)
187
    {
188
        if ($flags & self::CASE_INSENSITIVE) {
189
            return new self(\str_ireplace($search, $replace, $this->raw));
190
        }
191
        return new self(\str_replace($search, $replace, $this->raw));
192
    }
193
194
    public function replaceSubstr($replacement, $start, $length = null)
195
    {
196
        if ($length === null) {
197
            $length = $this->length();
198
        }
199
        return new self(\substr_replace($this->raw, $replacement, $start, $length));
200
    }
201
202
    public function resetToken()
203
    {
204
        $this->token = false;
205
    }
206
207
    public function reverse()
208
    {
209
        return new self(\strrev($this->raw));
210
    }
211
212
    public function shuffle()
213
    {
214
        return new self(\str_shuffle($this->raw));
215
    }
216
217
    public function substr($start, $length = 'omitted')
218
    {
219
        if ($length === 'omitted') {
220
            return new self(\substr($this->raw, $start));
221
        }
222
        return new self(\substr($this->raw, $start, $length));
223
    }
224
225
    public function times($times)
226
    {
227
        return $this->repeat($times);
228
    }
229
230
    public function translate($search, $replace = '')
231
    {
232
        if (is_array($search)) {
233
            return new self(\strtr($this->raw, $search));
234
        }
235
        return new self(\strtr($this->raw, $search, $replace));
236
    }
237
238 View Code Duplication
    public function trim($mask = " \t\n\r\0\x0B", $flags = self::BOTH_ENDS)
1 ignored issue
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
239
    {
240
        $flagsmap = [
241
            self::START => 'ltrim',
242
            self::END => 'rtrim',
243
            self::BOTH_ENDS => 'trim',
244
        ];
245
        return new self(\call_user_func($flagsmap[$flags], $this->raw, $mask));
246
    }
247
248 View Code Duplication
    public function unescape($flags = self::NORMAL)
1 ignored issue
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
249
    {
250
        $flagsmap = [
251
            self::NORMAL => 'stripslashes',
252
            self::C_STYLE => 'stripcslashes',
253
            self::META => 'stripslashes',
254
        ];
255
        return new self(\call_user_func($flagsmap[$flags], $this->raw));
256
    }
257
258
    public function uuDecode()
259
    {
260
        return new self(\convert_uudecode($this->raw));
261
    }
262
263
    public function uuEncode()
264
    {
265
        return new self(\convert_uuencode($this->raw));
266
    }
267
268
    public function wordwrap($width = 75, $break = "\n")
269
    {
270
        return new self(\wordwrap($this->raw, $width, $break, false));
271
    }
272
273
    public function wordwrapBreaking($width = 75, $break = "\n")
274
    {
275
        return new self(\wordwrap($this->raw, $width, $break, true));
276
    }
277
278
    // TESTING METHODS
279
280
    public function contains($needle, $offset = 0, $flags = self::NORMAL)
281
    {
282
        if ($flags & self::EXACT_POSITION) {
283
            return ($this->indexOf($needle, $offset, $flags) === $offset);
284
        }
285
        return ($this->indexOf($needle, $offset, $flags) !== false);
286
    }
287
288
    public function countSubstr($needle, $offset = 0, $length = null)
289
    {
290
        if ($length === null) {
291
            return \substr_count($this->raw, $needle, $offset);
292
        }
293
        return \substr_count($this->raw, $needle, $offset, $length);
294
    }
295
296
    public function endsWith($str, $flags = self::NORMAL)
297
    {
298
        $flags &= self::CASE_INSENSITIVE;
299
        $offset = $this->length() - \strlen($str);
300
        return $this->contains($str, $offset, $flags | self::EXACT_POSITION | self::REVERSE);
301
    }
302
303
    public function equals($str)
304
    {
305
        self::testStringableObject($str);
306
307
        $str = (string) $str;
308
        return ($str == $this->raw);
309
    }
310
311
    public function isAscii()
312
    {
313
        $len = $this->length();
314
315
        for ($i = 0; $i < $len; $i++) {
316
            if ($this->charCodeAt($i) >= 128) {
317
                return false;
318
            }
319
        }
320
        return true;
321
    }
322
323
    public function isEmpty()
324
    {
325
        return empty($this->raw);
326
    }
327
328
    public function startsWith($str, $flags = self::NORMAL)
329
    {
330
        $flags &= self::CASE_INSENSITIVE;
331
        return $this->contains($str, 0, $flags | self::EXACT_POSITION);
332
    }
333
334
    // INTERFACE IMPLEMENTATION METHODS
335
336
    public function count()
337
    {
338
        return \strlen($this->raw);
339
    }
340
341
    public function current()
342
    {
343
        return $this->raw[$this->caret];
344
    }
345
346
    public function key()
347
    {
348
        return $this->caret;
349
    }
350
351
    public function next()
352
    {
353
        $this->caret++;
354
    }
355
356
    public function rewind()
357
    {
358
        $this->caret = 0;
359
    }
360
361
    public function valid()
362
    {
363
        return ($this->caret < \strlen($this->raw));
364
    }
365
366
    public function offsetExists($offset)
367
    {
368
        $offset = (int) $offset;
369
        return ($offset >= 0 && $offset < \strlen($this->raw));
370
    }
371
372
    public function offsetGet($offset)
373
    {
374
        return $this->raw{$offset};
375
    }
376
377
    public function offsetSet($offset, $value)
378
    {
379
        throw new \LogicException('Cannot assign ' . $value . ' to immutable StrObj instance at index ' . $offset);
380
    }
381
382
    public function offsetUnset($offset)
383
    {
384
        throw new \LogicException('Cannot unset index ' . $offset . ' on immutable StrObj instance');
385
    }
386
387
    // PRIVATE STATIC FUNCTIONS
388
389
    protected static function testStringableObject($thing)
390
    {
391
        if (\is_object($thing) && !\method_exists($thing, '__toString')) {
392
            throw new \InvalidArgumentException(
393
                'Parameter is an object that does not implement __toString() method'
394
            );
395
        }
396
    }
397
}
398