• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

JBZoo / Utils / 29770052588

20 Jul 2026 06:55PM UTC coverage: 92.619% (-0.1%) from 92.722%
29770052588

push

github

web-flow
Merge pull request #57 from JBZoo/release/8.0

8.0.0 — PHP 8.3+ floor & lock-step major

15 of 16 new or added lines in 7 files covered. (93.75%)

106 existing lines in 13 files now uncovered.

1669 of 1802 relevant lines covered (92.62%)

41.2 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

98.68
/src/Filter.php
1
<?php
2

3
/**
4
 * JBZoo Toolbox - Utils.
5
 *
6
 * This file is part of the JBZoo Toolbox project.
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 *
10
 * @license    MIT
11
 * @copyright  Copyright (C) JBZoo.com, All rights reserved.
12
 * @see        https://github.com/JBZoo/Utils
13
 */
14

15
declare(strict_types=1);
16

17
namespace JBZoo\Utils;
18

19
use JBZoo\Data\Data;
20
use JBZoo\Data\JSON;
21

22
/**
23
 * @SuppressWarnings(PHPMD.TooManyMethods)
24
 * @SuppressWarnings(PHPMD.TooManyPublicMethods)
25
 * @psalm-suppress UnusedClass
26
 */
27
final class Filter
28
{
29
    /**
30
     * Apply custom filter to variable.
31
     * @SuppressWarnings(PHPMD.CamelCaseMethodName)
32
     * @SuppressWarnings(PHPMD.ShortMethodName)
33
     */
34
    public static function _(mixed $value, \Closure|string $filters = 'raw'): mixed
35
    {
36
        if (\is_string($filters)) {
660✔
37
            $filters = Str::trim($filters);
654✔
38
            $filters = \explode(',', $filters);
654✔
39

40
            foreach ($filters as $filter) {
654✔
41
                $filterName = self::cmd($filter);
654✔
42

43
                if (!isStrEmpty($filterName)) {
654✔
44
                    if (\method_exists(self::class, $filterName)) {
654✔
45
                        /** @phpstan-ignore-next-line */
46
                        $value = self::$filterName($value);
648✔
47
                    } else {
48
                        throw new Exception('Undefined filter method: ' . $filter);
6✔
49
                    }
50
                }
51
            }
52
        } else {
53
            $value = $filters($value);
6✔
54
        }
55

56
        return $value;
654✔
57
    }
58

59
    /**
60
     * Converts many english words that equate to true or false to boolean.
61
     *
62
     * @param mixed $variable The string to convert to boolean
63
     */
64
    public static function bool(mixed $variable): bool
65
    {
66
        if ($variable === null) {
378✔
67
            return false;
6✔
68
        }
69

70
        if (\is_bool($variable)) {
372✔
71
            return $variable;
12✔
72
        }
73

74
        if (\is_array($variable)) {
360✔
UNCOV
75
            return \count($variable) > 0;
×
76
        }
77

78
        if (
79
            !\is_float($variable)
360✔
80
            && !\is_int($variable)
360✔
81
            && !\is_numeric($variable)
360✔
82
            && !\is_string($variable)
360✔
83
        ) {
84
            // @phpstan-ignore-next-line
UNCOV
85
            return empty($variable);
×
86
        }
87

88
        $yesList = [
360✔
89
            '*',
360✔
90
            '+',
360✔
91
            '++',
360✔
92
            '+++',
360✔
93
            '++++',
360✔
94
            '+++++',
360✔
95
            '1',
360✔
96
            'affirmative',
360✔
97
            'all right',
360✔
98
            'aye',
360✔
99
            'indubitably',
360✔
100
            'most assuredly',
360✔
101
            'of course',
360✔
102
            'ok',
360✔
103
            'okay',
360✔
104
            'on',
360✔
105
            'oui',
360✔
106
            'sure thing',
360✔
107
            'sure',
360✔
108
            't',
360✔
109
            'true',
360✔
110
            'vrai',
360✔
111
            'y',
360✔
112
            'yea',
360✔
113
            'yeah',
360✔
114
            'yep',
360✔
115
            'yes',
360✔
116
            'д',
360✔
117
            'да',
360✔
118
        ];
360✔
119

120
        $noList = [
360✔
121
            '0',
360✔
122
            '-',
360✔
123
            'absolutely not',
360✔
124
            'by no means',
360✔
125
            'f',
360✔
126
            'false',
360✔
127
            'faux',
360✔
128
            'na',
360✔
129
            'nah',
360✔
130
            'negative',
360✔
131
            'never ever',
360✔
132
            'never',
360✔
133
            'nil',
360✔
134
            'nill',
360✔
135
            'no way',
360✔
136
            'no*',
360✔
137
            'non',
360✔
138
            'nope',
360✔
139
            'null',
360✔
140
            'off',
360✔
141
            'undefined',
360✔
142
            'н',
360✔
143
            'немає',
360✔
144
            'нет',
360✔
145
        ];
360✔
146

147
        $variable = Str::low((string)$variable);
360✔
148

149
        if (\in_array($variable, $yesList, true) || self::float($variable) !== 0.0) {
360✔
150
            return true;
246✔
151
        }
152

153
        if (\in_array($variable, $noList, true)) {
114✔
154
            return false;
60✔
155
        }
156

157
        return \filter_var($variable, \FILTER_VALIDATE_BOOLEAN);
54✔
158
    }
159

160
    /**
161
     * Smart converter string to float.
162
     */
163
    public static function float(mixed $value, int $round = 10): float
164
    {
165
        $cleaned = (string)\preg_replace('#[^\deE\-\.\,]#iu', '', (string)$value);
444✔
166
        $cleaned = \str_replace(',', '.', $cleaned);
444✔
167

168
        \preg_match('#[-+]?[\d]+(\.[\d]+)?([eE][-+]?[\d]+)?#', $cleaned, $matches);
444✔
169
        $result = (float)($matches[0] ?? 0.0);
444✔
170

171
        return \round($result, $round);
444✔
172
    }
173

174
    /**
175
     * Smart convert any string to int.
176
     */
177
    public static function int(bool|float|int|string|null $value): int
178
    {
179
        $cleaned = (string)\preg_replace('#[^0-9-+.,]#', '', (string)$value);
270✔
180
        \preg_match('#[-+]?[\d]+#', $cleaned, $matches);
270✔
181
        $result = $matches[0] ?? 0;
270✔
182

183
        return (int)$result;
270✔
184
    }
185

186
    /**
187
     * Returns only digits chars.
188
     */
189
    public static function digits(?string $value): string
190
    {
191
        // we need to remove - and + because they're allowed in the filter
192
        $cleaned = \str_replace(['-', '+'], '', (string)$value);
12✔
193

194
        /**
195
         * @psalm-suppress RedundantCast
196
         */
197
        return (string)\filter_var($cleaned, \FILTER_SANITIZE_NUMBER_INT);
12✔
198
    }
199

200
    /**
201
     * Returns only alpha chars.
202
     */
203
    public static function alpha(?string $value): string
204
    {
205
        return (string)\preg_replace('#[^[:alpha:]]#', '', (string)$value);
12✔
206
    }
207

208
    /**
209
     * Returns only alpha and digits chars.
210
     */
211
    public static function alphanum(?string $value): string
212
    {
213
        return (string)\preg_replace('#[^[:alnum:]]#', '', (string)$value);
12✔
214
    }
215

216
    /**
217
     * Returns only chars for base64.
218
     */
219
    public static function base64(string $value): string
220
    {
221
        return (string)\preg_replace('#[^A-Z0-9\/+=]#i', '', $value);
6✔
222
    }
223

224
    /**
225
     * Returns only chars for base64url.
226
     */
227
    public static function path(string $value): string
228
    {
229
        $pattern = '#^[A-Za-z0-9_\/-]+[A-Za-z0-9_\.-]*([\\\\\/][A-Za-z0-9_-]+[A-Za-z0-9_\.-]*)*$#';
12✔
230
        \preg_match($pattern, $value, $matches);
12✔
231

232
        return $matches[0] ?? '';
12✔
233
    }
234

235
    /**
236
     * Alias for build-in function \trim().
237
     */
238
    public static function trim(string $value): string
239
    {
240
        return Str::trim($value);
6✔
241
    }
242

243
    /**
244
     * Extended trim function for remove all spaces, tabs, new lines and really special chars.
245
     */
246
    public static function trimExtend(string $value): string
247
    {
248
        return Str::trim($value, true);
6✔
249
    }
250

251
    /**
252
     * Cleanup array. No empty values.
253
     */
254
    public static function arr(mixed $value, \Closure|string|null $filter = null): array
255
    {
256
        $array = (array)$value;
6✔
257

258
        if ($filter === 'noempty') {
6✔
259
            $array = Arr::clean($array);
6✔
260
        } elseif ($filter instanceof \Closure) {
6✔
261
            $array = \array_filter($array, $filter); // TODO add support both - key + value
6✔
262
        }
263

264
        return $array;
6✔
265
    }
266

267
    /**
268
     * Cleanup system command.
269
     */
270
    public static function cmd(string $value): string
271
    {
272
        $value = Str::low($value);
660✔
273
        $value = (string)\preg_replace('#[^a-z0-9\_\-\.]#', '', $value);
660✔
274

275
        return Str::trim($value);
660✔
276
    }
277

278
    /**
279
     * Get safe string without html tags and trimmed.
280
     */
281
    public static function strip(string $string): string
282
    {
283
        $cleaned = \strip_tags($string);
30✔
284

285
        return Str::trim($cleaned);
30✔
286
    }
287

288
    /**
289
     * Get safe string for sensitive external dependencies.
290
     */
291
    public static function alias(string $string): string
292
    {
293
        $cleaned = self::strip($string);
18✔
294

295
        return Str::slug($cleaned);
18✔
296
    }
297

298
    /**
299
     * String to lower and trim.
300
     */
301
    public static function low(string $string): string
302
    {
303
        $cleaned = Str::low($string);
6✔
304

305
        return Str::trim($cleaned);
6✔
306
    }
307

308
    /**
309
     * String to upper and trim.
310
     * @SuppressWarnings(PHPMD.ShortMethodName)
311
     */
312
    public static function up(string $string): string
313
    {
314
        $cleaned = Str::up($string);
6✔
315

316
        return Str::trim($cleaned);
6✔
317
    }
318

319
    /**
320
     * Alias of "Str::stripSpace($string)".
321
     */
322
    public static function stripSpace(string $string): string
323
    {
324
        return Str::stripSpace($string);
6✔
325
    }
326

327
    /**
328
     * Alias of "Str::clean($string, true, true)".
329
     */
330
    public static function clean(string $string): string
331
    {
332
        return Str::clean($string, true, true);
6✔
333
    }
334

335
    /**
336
     * Alias of "Str::htmlEnt($string)".
337
     */
338
    public static function html(string $string): string
339
    {
340
        return Str::htmlEnt($string);
6✔
341
    }
342

343
    /**
344
     * Alias of "Xml::escape($string)".
345
     */
346
    public static function xml(string $string): string
347
    {
348
        return Xml::escape($string);
6✔
349
    }
350

351
    /**
352
     * Alias of "Str::esc($string)".
353
     */
354
    public static function esc(string $string): string
355
    {
356
        return Str::esc($string);
6✔
357
    }
358

359
    /**
360
     * Returns Data object from array.
361
     */
362
    public static function data(array|Data $data): Data
363
    {
364
        if ($data instanceof Data) {
6✔
365
            return $data;
6✔
366
        }
367

368
        return new Data($data);
6✔
369
    }
370

371
    /**
372
     * Returns JSON object from array.
373
     */
374
    public static function json(array|JSON $data): JSON
375
    {
376
        if ($data instanceof JSON) {
6✔
377
            return $data;
6✔
378
        }
379

380
        return new JSON($data);
6✔
381
    }
382

383
    /**
384
     * RAW placeholder for internal API of the library.
385
     */
386
    public static function raw(mixed $variable): mixed
387
    {
388
        return $variable;
6✔
389
    }
390

391
    /**
392
     * First char to upper, other to lower.
393
     */
394
    public static function ucFirst(string $input): string
395
    {
396
        $string = Str::low($input);
12✔
397

398
        return \ucfirst($string);
12✔
399
    }
400

401
    /**
402
     * Parse lines to assoc list.
403
     */
404
    public static function parseLines(array|string $input): array
405
    {
406
        if (\is_array($input)) {
6✔
407
            $input = \implode(\PHP_EOL, $input);
6✔
408
        }
409

410
        return Str::parseLines($input);
6✔
411
    }
412

413
    /**
414
     * Convert words to PHP Class name.
415
     */
416
    public static function className(string $input): string
417
    {
418
        $output = (string)\preg_replace(['#(?<=[^A-Z\s])([A-Z\s])#i'], ' $0', $input);
6✔
419
        $output = \explode(' ', $output);
6✔
420

421
        $output = \array_map(static function ($item) {
6✔
422
            $item = (string)\preg_replace('#[^a-z0-9]#i', '', $item);
6✔
423

424
            return self::ucFirst($item);
6✔
425
        }, $output);
6✔
426

427
        $output = \array_filter($output);
6✔
428

429
        return \implode('', $output);
6✔
430
    }
431

432
    /**
433
     * Smart striping quotes, double and single.
434
     */
435
    public static function stripQuotes(string $value): string
436
    {
437
        if (\str_starts_with($value, '"') && \str_ends_with($value, '"')) {
138✔
438
            $value = \trim($value, '"');
18✔
439
        }
440

441
        if (\str_starts_with($value, "'") && \str_ends_with($value, "'")) {
138✔
442
            $value = \trim($value, "'");
12✔
443
        }
444

445
        return $value;
138✔
446
    }
447
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc