Completed
Pull Request — master (#28)
by Matt
10:53 queued 08:33
created

Format   A

Complexity

Total Complexity 16

Size/Duplication

Total Lines 125
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 1

Test Coverage

Coverage 96.77%

Importance

Changes 2
Bugs 1 Features 0
Metric Value
c 2
b 1
f 0
dl 0
loc 125
ccs 60
cts 62
cp 0.9677
rs 10
wmc 16
lcom 1
cbo 1

4 Methods

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