Passed
Push — master ( c388dd...1e2651 )
by Stephen
02:27
created

StringHelpers::fill()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

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