Passed
Push — master ( 1db31e...232505 )
by Stephen
11:31
created

StringHelpers::strip()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 16
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 9
c 1
b 0
f 0
nc 1
nop 0
dl 0
loc 16
rs 9.9666
1
<?php
2
3
namespace Sfneal\Helpers\Strings;
4
5
use Sfneal\Helpers\Arrays\ArrayHelpers;
6
use Sfneal\Helpers\Strings\Traits\StaticMethods;
7
use Sfneal\Helpers\Strings\Utils\Regex;
8
9
class StringHelpers
10
{
11
    use StaticMethods;
12
13
    /**
14
     * @var string
15
     */
16
    private $string;
17
18
    /**
19
     * StringHelpers constructor.
20
     *
21
     * @param string $string
22
     */
23
    public function __construct(string $string)
24
    {
25
        $this->string = $string;
26
    }
27
28
    /**
29
     * Sanitize a file name to remove illegal chars.
30
     *
31
     * @return string
32
     */
33
    public function sanitizeFileName(): string
34
    {
35
        return preg_replace('/[^A-Za-z0-9_\-]/', '_', $this->string);
36
    }
37
38
    /**
39
     * Truncate a string to be no longer than $chars.
40
     *
41
     * @param int $chars
42
     * @param string $suffix
43
     * @return string
44
     */
45
    public function truncate(int $chars = 100, string $suffix = '...'): string
46
    {
47
        return (strlen($this->string) <= $chars) ? $this->string : substr($this->string, 0, $chars).$suffix;
48
    }
49
50
    /**
51
     * Covert a camel cased string into a $char separated string.
52
     *
53
     * @param string $char
54
     * @return string
55
     */
56
    public function camelCaseConvert(string $char = '-'): string
57
    {
58
        return strtolower(preg_replace('/(?<!^)[A-Z]/', $char.'$0', $this->string));
59
    }
60
61
    /**
62
     * Explode a string using upper case chars as the separator.
63
     *
64
     * @return array
65
     */
66
    public function camelCaseSplit(): array
67
    {
68
        return preg_split('/(?=[A-Z])/', $this->string, -1, PREG_SPLIT_NO_EMPTY);
69
    }
70
71
    /**
72
     * Remove illegal characters from a string to create an ID.
73
     *
74
     *  - legal chars: '&', ' '
75
     *
76
     * @return string
77
     */
78
    public function id(): string
79
    {
80
        // todo: improve this by removing repeated '-'
81
        return (new self(
82
            strtolower(str_replace(' ', '-', str_replace('&', '-', $this->string)))
83
        ))->removeDuplicateChars();
84
    }
85
86
    /**
87
     * Remove ' ', '-', '&' characters.
88
     *
89
     * @return string
90
     */
91
    public function strip(): string
92
    {
93
        // todo: maybe replace with id & make depreciated?
94
        return (new self(
95
            strtolower(
96
                str_replace(
97
                    ',', '', str_replace(
98
                        ' ', '-', str_replace(
99
                            '&',
100
                            '',
101
                            $this->string
102
                        )
103
                    )
104
                )
105
            )
106
        ))->removeDuplicateChars();
107
    }
108
109
    /**
110
     * Remove duplicate characters from a string
111
     *
112
     * @param string $pattern
113
     * @return string
114
     */
115
    public function removeDuplicateChars(string $pattern = Regex::NOT_NUMBERS_OR_LETTERS_OR_UNDERSCORE): string
116
    {
117
        return preg_replace("/({$pattern})\\1+/", "$1", $this->string);
118
    }
119
120
    /**
121
     * Check if a needle string is in a haystack string.
122
     *
123
     *  $boolean param determines weather ALL or ANY of $needles
124
     *  need to be found to return true (only when $needle is an array).
125
     *
126
     *  todo: rename given $needle can be an array
127
     *
128
     * @param string|array $needle
129
     * @param string $boolean
130
     * @return bool
131
     */
132
    public function inString($needle, string $boolean = 'and'): bool
133
    {
134
        // Determine if an array of $needle's was passed
135
        if (is_array($needle)) {
136
137
            // Check if each of the needles is found in the haystack
138
            $results = [];
139
            foreach ($needle as $need) {
140
                $results[] = $this->isNeedleInString($need);
141
            }
142
143
            // Determine if any of the needles can exist to return true
144
            if ($boolean == 'or') {
145
                return in_array(true, $results);
146
            }
147
148
            // All needles must be found
149
            else {
150
                return (new ArrayHelpers($results))->arrayValuesEqual(true);
151
            }
152
        }
153
154
        return $this->isNeedleInString($needle);
155
    }
156
157
    /**
158
     * Check if a needle exists inside a haystack.
159
     *
160
     * @param $needle
161
     * @return bool
162
     */
163
    private function isNeedleInString($needle): bool
164
    {
165
        return strpos($this->string, $needle) !== false;
166
    }
167
168
    /**
169
     * Determine if the $string is a plain text list of values.
170
     *
171
     *  - if $string is a list, an array of values is returned
172
     *  - if $sting is a string, false is returned
173
     *
174
     *  todo: refactor to listString?
175
     *
176
     * @param array|string[] $separators
177
     * @return bool|false|string[]
178
     */
179
    public function isListString(array $separators = [', ', ' '])
180
    {
181
        foreach ($separators as $needle) {
182
            // If the $needle is found in the $string
183
            // we know the string is a plain text list
184
            // so an array of values is returned
185
            if ($this->inString($needle)) {
186
                // todo: use explode many?
187
                return explode($needle, $this->string);
188
            }
189
        }
190
191
        // If none of the separators are found
192
        // we know the string is not a list
193
        return false;
194
    }
195
196
    /**
197
     * Explode a string using an array of delimiters instead of a single string.
198
     *
199
     * @param array|string[] $delimiters
200
     * @param string $replacer
201
     * @return array
202
     */
203
    public function explodeMany(array $delimiters = [',', '&', '/', '-'], string $replacer = '***'): array
204
    {
205
        // Replace all of $delimiters chars with the
206
        // $replacer so that a single delimiter can
207
        // be used to explode the string
208
        $cleaned = str_replace($delimiters, $replacer, $this->string);
209
210
        // Use the replacer as the $delimiter
211
        // since it has replaced each of the
212
        // passed $delimiters
213
        $split = explode($replacer, $cleaned);
214
215
        // Utilize collection's if laravel/framework is installed
216
        if (function_exists('collect')) {
217
            // Collect the array of strings
218
            return collect($split)
219
220
                // Remove empty strings from the collection
221
                ->filter(function (string $item) {
222
                    return strlen($item) > 0;
223
                })
224
225
                // Trim the remaining strings in the collection
226
                ->map(function (string $item) {
227
                    return trim($item);
228
                })
229
230
                // Encode as array
231
                ->toArray();
232
        }
233
234
        // Use built in array functions
235
        else {
236
            // Remove empty strings from the collection
237
            $filtered = array_filter($split, function (string $item) {
238
                return strlen($item) > 0;
239
            });
240
241
            // Trim the remaining strings in the collection
242
            return  array_map(function (string $item) {
243
                return trim($item);
244
            }, $filtered);
245
        }
246
    }
247
248
    /**
249
     * Add whitespace padding to a string.
250
     *
251
     * @param int $amount
252
     * @param string $pad
253
     * @param bool $front add whitespace to 'front' of the string
254
     * @param bool $back add whitespace to the 'back' of the string
255
     * @return string
256
     */
257
    public function whitespacePad(int $amount = 1,
258
                                  string $pad = ' ',
259
                                  bool $front = true,
260
                                  bool $back = true): string
261
    {
262
        // Multiple $pad chars by $amount
263
        $whitespace = str_repeat($pad, $amount);
264
265
        // Return string with padding
266
        return ($front ? $whitespace : '').$this->string.($back ? $whitespace : '');
267
    }
268
269
    /**
270
     * Add whitespace padding to only the 'back' of the string.
271
     *
272
     * @param int $amount
273
     * @param string $pad
274
     * @return string
275
     */
276
    public function whitespacePadBack(int $amount = 1, string $pad = ' '): string
277
    {
278
        return $this->whitespacePad($amount, $pad, false, true);
279
    }
280
281
    /**
282
     * Add whitespace padding to only the 'back' of the string.
283
     *
284
     * @param int $amount
285
     * @param string $pad
286
     * @return string
287
     */
288
    public function whitespacePadFront(int $amount = 1, string $pad = ' '): string
289
    {
290
        return $this->whitespacePad($amount, $pad, true, false);
291
    }
292
293
    /**
294
     * Remove all whitespace (spaces) from a string.
295
     *
296
     * @return string
297
     */
298
    public function whitespaceRemove(): string
299
    {
300
        return $this->whitespaceReplace();
301
    }
302
303
    /**
304
     * Remove all whitespace (spaces) from a string & replace with another string.
305
     *
306
     * @param string $replacement defaults to ''
307
     * @return string
308
     */
309
    public function whitespaceReplace(string $replacement = ''): string
310
    {
311
        return str_replace(' ', $replacement, $this->string);
312
    }
313
314
    /**
315
     * Fill a string with whitespace in order to make it a certain length in chars.
316
     *
317
     * @param int $length length of the string in characters
318
     * @param string $filler string to use to fill the needed whitespace
319
     * @return string
320
     */
321
    public function fill(int $length, string $filler = ' '): string
322
    {
323
        return $this->string.str_repeat($filler, $length - strlen($this->string));
324
    }
325
}
326