Completed
Push — master ( e98ae3...0e888f )
by Matt
02:50
created

Format   A

Complexity

Total Complexity 17

Size/Duplication

Total Lines 122
Duplicated Lines 0 %

Coupling/Cohesion

Components 0
Dependencies 2

Test Coverage

Coverage 97.01%

Importance

Changes 1
Bugs 1 Features 0
Metric Value
dl 0
loc 122
ccs 65
cts 67
cp 0.9701
rs 10
c 1
b 1
f 0
wmc 17
lcom 0
cbo 2

3 Methods

Rating   Name   Duplication   Size   Complexity  
B validate() 0 53 7
A validateRegex() 0 14 3
C validateFilter() 0 22 7
1
<?php
2
3
namespace League\JsonGuard\Constraints;
4
5
use League\JsonGuard;
6
use League\JsonGuard\Assert;
7
use League\JsonGuard\ValidationError;
8
9
class Format implements PropertyConstraint
10
{
11
    const KEYWORD = 'format';
12
13
    // @codingStandardsIgnoreStart
14
    const DATE_TIME_PATTERN = '/^([0-9]{4})-([0-9]{2})-([0-9]{2})([Tt]([0-9]{2}):([0-9]{2}):([0-9]{2})(\\.[0-9]+)?)?(([Zz]|([+-])([0-9]{2}):([0-9]{2})))?/';
15
    // @codingStandardsIgnoreEnd
16
17
    const HOST_NAME_PATTERN = '/^[_a-z]+\.([_a-z]+\.?)+$/i';
18
19
    /**
20
     * {@inheritdoc}
21
     */
22 10
    public static function validate($value, $parameter, $pointer = null)
23
    {
24 10
        Assert::type($parameter, 'string', self::KEYWORD, $pointer);
25
26
        switch ($parameter) {
27 8
            case 'date-time':
28 4
                return self::validateRegex(
29 4
                    $parameter,
30 4
                    $value,
31 4
                    self::DATE_TIME_PATTERN,
32
                    $pointer
33 4
                );
34 6
            case 'uri':
35 4
                return self::validateFilter(
36 4
                    $parameter,
37 4
                    $value,
38 4
                    FILTER_VALIDATE_URL,
39 4
                    null,
40
                    $pointer
41 4
                );
42 4
            case 'email':
43 4
                return self::validateFilter(
44 4
                    $parameter,
45 4
                    $value,
46 4
                    FILTER_VALIDATE_EMAIL,
47 4
                    null,
48
                    $pointer
49 4
                );
50 2
            case 'ipv4':
51 2
                return self::validateFilter(
52 2
                    $parameter,
53 2
                    $value,
54 2
                    FILTER_VALIDATE_IP,
55 2
                    FILTER_FLAG_IPV4,
56
                    $pointer
57 2
                );
58 2
            case 'ipv6':
59 2
                return self::validateFilter(
60 2
                    $parameter,
61 2
                    $value,
62 2
                    FILTER_VALIDATE_IP,
63 2
                    FILTER_FLAG_IPV6,
64
                    $pointer
65 2
                );
66 2
            case 'hostname':
67 2
                return self::validateRegex(
68 2
                    $parameter,
69 2
                    $value,
70 2
                    self::HOST_NAME_PATTERN,
71
                    $pointer
72 2
                );
73
        }
74
    }
75
76
    /**
77
     * @param string $format
78
     * @param mixed $value
79
     * @param string $pattern
80
     * @param string $pointer
81
     *
82
     * @return \League\JsonGuard\ValidationError|null
83
     */
84 4
    private static function validateRegex($format, $value, $pattern, $pointer)
85
    {
86 4
        if (!is_string($value) || preg_match($pattern, $value) === 1) {
87 4
            return null;
88
        }
89
90 2
        return new ValidationError(
91 2
            'Value {value} does not match the format {format}',
92 2
            self::KEYWORD,
93 2
            $value,
94 2
            $pointer,
95 2
            ['value' => $value, 'format' => $format]
96 2
        );
97
    }
98
99
    /**
100
     * @param string $format
101
     * @param mixed  $value
102
     * @param int    $filter
103
     * @param mixed  $options
104
     * @param string $pointer
105
     *
106
     * @return \League\JsonGuard\ValidationError|null
107
     */
108 6
    private static function validateFilter($format, $value, $filter, $options, $pointer)
109
    {
110 6
        if (!is_string($value) || filter_var($value, $filter, $options) !== false) {
111 6
            return null;
112
        }
113
114
        // This workaround allows otherwise valid protocol relative urls to pass.
115
        // @see https://bugs.php.net/bug.php?id=72301
116 2
        if ($filter === FILTER_VALIDATE_URL && is_string($value) && strpos($value, '//') === 0) {
117 2
            if (filter_var('http:' . $value, $filter, $options) !== false) {
118 2
                return null;
119
            }
120
        }
121
122 2
        return new ValidationError(
123 2
            'Value {value} does not match the format {format}',
124 2
            self::KEYWORD,
125 2
            $value,
126 2
            $pointer,
127 2
            ['value' => $value, 'format' => $format]
128 2
        );
129
    }
130
}
131