1 | <?php |
||
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) |
|
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) |
|
133 | } |
||
134 |