Passed
Push — master ( fdfe1f...78b513 )
by Théo
05:22 queued 03:08
created

RegexChecker   A

Complexity

Total Complexity 11

Size/Duplication

Total Lines 70
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 36
c 1
b 0
f 0
dl 0
loc 70
rs 10
wmc 11

3 Methods

Rating   Name   Duplication   Size   Complexity  
A validateRegex() 0 10 2
A isRegexLike() 0 23 5
A isValidRegexFlags() 0 15 4
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Humbug\PhpScoper;
6
7
use function array_pop;
8
use function count;
9
use function current;
10
use function end;
11
use function explode;
12
use function in_array;
13
use function preg_last_error;
14
use function preg_last_error_msg;
15
use function preg_match as native_preg_match;
16
use function Safe\sprintf;
17
use function str_contains;
18
use function str_split;
19
use function strlen;
20
use function trim;
21
22
// TODO: move this under a Configuration namespace
23
final class RegexChecker
24
{
25
    // https://www.php.net/manual/en/reference.pcre.pattern.modifiers.php
26
    private const PATTERN_MODIFIERS = [
27
        'i',
28
        'm',
29
        's',
30
        'x',
31
        'A',
32
        'D',
33
        'S',
34
        'U',
35
        'X',
36
        'J',
37
        'u',
38
    ];
39
40
    public function isRegexLike(string $value): bool
41
    {
42
        $valueLength = strlen($value);
43
44
        if ($valueLength < 2) {
45
            return false;
46
        }
47
48
        $firstCharacter = $value[0];
49
50
        $parts = explode($firstCharacter, $value);
51
52
        if (false === $parts || count($parts) !== 3) {
53
            return false;
54
        }
55
56
        $lastPart = array_pop($parts);
57
58
        if (!self::isValidRegexFlags($lastPart)) {
59
            return false;
60
        }
61
62
        return true;
63
    }
64
65
    public function validateRegex(string $regex): ?string
66
    {
67
        if (@native_preg_match($regex, '') !== false) {
68
            return null;
69
        }
70
71
        return sprintf(
72
            'Invalid regex: %s (code %s)',
73
            preg_last_error_msg(),
74
            preg_last_error(),
75
        );
76
    }
77
78
    private static function isValidRegexFlags(string $value): bool
79
    {
80
        if ('' === $value) {
81
            return true;
82
        }
83
84
        $characters = str_split($value);
85
86
        foreach ($characters as $character) {
87
            if (!in_array($character, self::PATTERN_MODIFIERS, true)) {
88
                return false;
89
            }
90
        }
91
92
        return true;
93
    }
94
}
95