Passed
Pull Request — master (#23)
by Chad
02:00
created

UuidFilter::validateVersions()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
eloc 3
c 1
b 0
f 0
nc 3
nop 1
dl 0
loc 5
rs 10
1
<?php
2
3
namespace TraderInteractive\Filter;
4
5
use InvalidArgumentException;
6
use TraderInteractive\Exceptions\FilterException;
7
8
final class UuidFilter
9
{
10
    /**
11
     * @var string
12
     */
13
    const FILTER_ALIAS = 'uuid';
14
15
    /**
16
     * @var string
17
     */
18
    const UUID_PATTERN_FORMAT = '^[0-9A-F]{8}-[0-9A-F]{4}-[%d][0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$';
19
20
    /**
21
     * @var string
22
     */
23
    const FILTER_ERROR_FORMAT = "Value '%s' is not a valid UUID. Versions checked (%s)";
24
25
    /**
26
     * @var array
27
     * @internal
28
     */
29
    const VALID_UUID_VERSIONS = [1,4,7];
30
31
32
    /**
33
     * Filters a given string values to a valid UUID
34
     *
35
     * @param string|null $value     The value to be filtered.
36
     * @param bool        $allowNull Flag to allow value to be null.
37
     * @param array       $versions  List of specific UUID version to validate against.
38
     *
39
     * @return string|null
40
     *
41
     * @throws FilterException Thrown if value cannot be filtered as an UUID.
42
     */
43
    public static function filter(
44
        string $value = null,
45
        bool $allowNull = false,
46
        array $versions = self::VALID_UUID_VERSIONS
47
    ) {
48
        if (self::valueIsNullAndValid($allowNull, $value)) {
49
            return null;
50
        }
51
52
        self::validateVersions($versions);
53
        foreach ($versions as $version) {
54
            $pattern = sprintf(self::UUID_PATTERN_FORMAT, $version);
55
            if (preg_match("/{$pattern}/i", $value)) {
0 ignored issues
show
Bug introduced by
It seems like $value can also be of type null; however, parameter $subject of preg_match() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

55
            if (preg_match("/{$pattern}/i", /** @scrutinizer ignore-type */ $value)) {
Loading history...
56
                return $value;
57
            }
58
        }
59
60
        throw new FilterException(
61
            sprintf(
62
                self::FILTER_ERROR_FORMAT,
63
                $value,
64
                implode(', ', $versions)
65
            )
66
        );
67
    }
68
69
    private static function valueIsNullAndValid(bool $allowNull, string $value = null): bool
70
    {
71
        if ($allowNull === false && $value === null) {
72
            throw new FilterException('Value failed filtering, $allowNull is set to false');
73
        }
74
75
        return $allowNull === true && $value === null;
76
    }
77
78
    private static function validateVersions(array $versions)
79
    {
80
        foreach ($versions as $version) {
81
            if (!in_array($version, self::VALID_UUID_VERSIONS)) {
82
                throw new InvalidArgumentException("Filter does not support UUID v{$version}");
83
            }
84
        }
85
    }
86
}
87