Completed
Pull Request — master (#19)
by Viacheslav
03:03
created

Format::dateTimeError()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 6
ccs 4
cts 4
cp 1
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 4
nc 2
nop 1
crap 2
1
<?php
2
3
namespace Swaggest\JsonSchema\Constraint;
4
5
use Swaggest\JsonSchema\Constraint\Format\IdnHostname;
6
use Swaggest\JsonSchema\Constraint\Format\Iri;
7
use Swaggest\JsonSchema\Constraint\Format\Uri;
8
9
class Format
10
{
11
    const DATE_TIME = 'date-time';
12
    const DATE = 'date';
13
    const TIME = 'time';
14
    const URI = 'uri';
15
    const IRI = 'iri';
16
    const EMAIL = 'email';
17
    const IDN_EMAIL = 'idn-email';
18
    const IPV4 = 'ipv4';
19
    const IPV6 = 'ipv6';
20
    const HOSTNAME = 'hostname';
21
    const IDN_HOSTNAME = 'idn-hostname';
22
    const REGEX = 'regex';
23
    const JSON_POINTER = 'json-pointer';
24
    const RELATIVE_JSON_POINTER = 'relative-json-pointer';
25
    const URI_REFERENCE = 'uri-reference';
26
    const IRI_REFERENCE = 'iri-reference';
27
    const URI_TEMPLATE = 'uri-template';
28
29
    private static $dateRegexPart = '(\d{4})-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])';
30
    private static $timeRegexPart = '([01][0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9]|60)(\.[0-9]+)?(Z|(\+|-)([01][0-9]|2[0-3]):([0-5][0-9]))?';
31
    private static $jsonPointerRegex = '_^(?:/|(?:/[^/#]*)*)$_';
32
    private static $jsonPointerRelativeRegex = '~^(0|[1-9][0-9]*)((?:/[^/#]*)*)(#?)$~';
33
    private static $jsonPointerUnescapedTilde = '/~([^01]|$)/';
34
35 401
    public static function validationError($format, $data)
36
    {
37
        switch ($format) {
38 401
            case self::DATE_TIME:
39 17
                return self::dateTimeError($data);
40 384
            case self::DATE:
41 6
                return preg_match('/^' . self::$dateRegexPart . '$/i', $data) ? null : 'Invalid date';
42 378
            case self::TIME:
43 9
                return preg_match('/^' . self::$timeRegexPart . '$/i', $data) ? null : 'Invalid time';
44 369
            case self::URI:
45 149
                return Uri::validationError($data, Uri::IS_SCHEME_REQUIRED);
46 232
            case self::IRI:
47 7
                return Iri::validationError($data);
48 225
            case self::EMAIL:
49 9
                return filter_var($data, FILTER_VALIDATE_EMAIL) ? null : 'Invalid email';
50 217
            case self::IDN_EMAIL:
51 2
                return count(explode('@', $data, 3)) === 2 ? null : 'Invalid email';
52 215
            case self::IPV4:
53 16
                return filter_var($data, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) ? null : 'Invalid ipv4';
54 199
            case self::IPV6:
55 12
                return filter_var($data, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) ? null : 'Invalid ipv6';
56 187
            case self::HOSTNAME:
57 16
                return preg_match(Uri::HOSTNAME_REGEX, $data) ? null : 'Invalid hostname';
58 172
            case self::IDN_HOSTNAME:
59 4
                return IdnHostname::validationError($data);
60 168
            case self::REGEX:
61 52
                return self::regexError($data);
62 116
            case self::JSON_POINTER:
63 70
                return self::jsonPointerError($data);
64 46
            case self::RELATIVE_JSON_POINTER:
65 14
                return self::jsonPointerError($data, true);
66 32
            case self::URI_REFERENCE:
67 14
                return Uri::validationError($data, Uri::IS_URI_REFERENCE);
68 18
            case self::IRI_REFERENCE:
69 7
                return Iri::validationError($data, Uri::IS_URI_REFERENCE);
70 11
            case self::URI_TEMPLATE:
71 10
                return Uri::validationError($data, Uri::IS_URI_TEMPLATE);
72
        }
73 1
        return null;
74
    }
75
76 17
    public static function dateTimeError($data)
77
    {
78 17
        return preg_match('/^' . self::$dateRegexPart . 'T' . self::$timeRegexPart . '$/i', $data)
79 7
            ? null
80 17
            : 'Invalid date-time: ' . $data;
81
    }
82
83 52
    public static function regexError($data)
84
    {
85 52
        if (substr($data, -2) === '\Z') {
86 3
            return 'Invalid regex: \Z is not supported';
87
        }
88 49
        if (substr($data, 0, 2) === '\A') {
89
            return 'Invalid regex: \A is not supported';
90
        }
91
92
93 49
        $d = null;
94 49
        foreach (array('/', '_', '~', '#', '!', '%', '`', '=') as $delimiter) {
95 49
            if (strpos($data, $delimiter) === false) {
96 49
                $d = $delimiter;
97 49
                break;
98
            }
99
        }
100 49
        return @preg_match($d . $data . $d, '') === false ? 'Invalid regex: ' . $data : null;
101
    }
102
103 84
    public static function jsonPointerError($data, $isRelative = false)
104
    {
105 84
        if (preg_match(self::$jsonPointerUnescapedTilde, $data)) {
106 14
            return 'Invalid json-pointer: unescaped ~';
107
        }
108 70
        if ($isRelative) {
109 13
            return preg_match(self::$jsonPointerRelativeRegex, $data) ? null : 'Invalid relative json-pointer';
110
        } else {
111 57
            return preg_match(self::$jsonPointerRegex, $data) ? null : 'Invalid json-pointer';
112
        }
113
    }
114
}