UuidFilter   A
last analyzed

Complexity

Total Complexity 16

Size/Duplication

Total Lines 110
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 32
c 1
b 0
f 0
dl 0
loc 110
rs 10
wmc 16

4 Methods

Rating   Name   Duplication   Size   Complexity  
A valueIsNilAndValid() 0 7 4
A filter() 0 27 5
A valueIsNullAndValid() 0 7 4
A validateVersions() 0 5 3
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 string
27
     */
28
    const NIL_NOT_ALLOWED_ERROR_FORMAT = "Value '%s' is nil uuid, but nil values are not allowed.";
29
30
    /**
31
     * @var string
32
     */
33
    const NULL_NOT_ALLOWED_ERROR = "Value is null, but null values are not allowed.";
34
35
    /**
36
     * @var string
37
     */
38
    const UNSUPPORTED_VERSION_ERROR_FORMAT = 'Filter does not support UUID v%d';
39
40
    /**
41
     * @var string
42
     */
43
    const NIL_UUID = '00000000-0000-0000-0000-000000000000';
44
45
    /**
46
     * @var array
47
     * @internal
48
     */
49
    const VALID_UUID_VERSIONS = [1,2,3,4,5,6,7];
50
51
52
    /**
53
     * Filters a given string values to a valid UUID
54
     *
55
     * @param string|null $value     The value to be filtered.
56
     * @param bool        $allowNull Flag to allow value to be null.
57
     * @param bool        $allowNil  Flag to allow value to be a NIL UUID.
58
     * @param array       $versions  List of specific UUID version to validate against.
59
     *
60
     * @return string|null
61
     *
62
     * @throws FilterException Thrown if value cannot be filtered as an UUID.
63
     */
64
    public static function filter(
65
        string $value = null,
66
        bool $allowNull = false,
67
        bool $allowNil = false,
68
        array $versions = self::VALID_UUID_VERSIONS
69
    ) {
70
        if (self::valueIsNullAndValid($allowNull, $value)) {
71
            return null;
72
        }
73
74
        if (self::valueIsNilAndValid($allowNil, $value)) {
75
            return self::NIL_UUID;
76
        }
77
78
        self::validateVersions($versions);
79
        foreach ($versions as $version) {
80
            $pattern = sprintf(self::UUID_PATTERN_FORMAT, $version);
81
            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

81
            if (preg_match("/{$pattern}/i", /** @scrutinizer ignore-type */ $value)) {
Loading history...
82
                return $value;
83
            }
84
        }
85
86
        throw new FilterException(
87
            sprintf(
88
                self::FILTER_ERROR_FORMAT,
89
                $value,
90
                implode(', ', $versions)
91
            )
92
        );
93
    }
94
95
    private static function valueIsNullAndValid(bool $allowNull, string $value = null): bool
96
    {
97
        if ($allowNull === false && $value === null) {
98
            throw new FilterException(self::NULL_NOT_ALLOWED_ERROR);
99
        }
100
101
        return $allowNull === true && $value === null;
102
    }
103
104
    private static function valueIsNilAndValid(bool $allowNil, string $value = null): bool
105
    {
106
        if ($allowNil === false && $value === self::NIL_UUID) {
107
            throw new FilterException(sprintf(self::NIL_NOT_ALLOWED_ERROR_FORMAT, $value));
108
        }
109
110
        return $allowNil === true && $value === self::NIL_UUID;
111
    }
112
113
    private static function validateVersions(array $versions)
114
    {
115
        foreach ($versions as $version) {
116
            if (!in_array($version, self::VALID_UUID_VERSIONS)) {
117
                throw new InvalidArgumentException(sprintf(self::UNSUPPORTED_VERSION_ERROR_FORMAT, $version));
118
            }
119
        }
120
    }
121
}
122