Completed
Pull Request — master (#72)
by Matt
02:46
created

Format   A

Complexity

Total Complexity 17

Size/Duplication

Total Lines 120
Duplicated Lines 0 %

Coupling/Cohesion

Components 0
Dependencies 1

Test Coverage

Coverage 96.67%

Importance

Changes 1
Bugs 1 Features 0
Metric Value
dl 0
loc 120
ccs 58
cts 60
cp 0.9667
rs 10
c 1
b 1
f 0
wmc 17
lcom 0
cbo 1

3 Methods

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