Completed
Pull Request — master (#116)
by
unknown
02:15
created

Type::getDefaultBigintMode()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 0
dl 0
loc 4
ccs 2
cts 2
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace League\JsonGuard\Constraint\DraftFour;
4
5
use League\JsonGuard\Assert;
6
use League\JsonGuard\ConstraintInterface;
7
use League\JsonGuard\ValidationError;
8
use League\JsonGuard\Validator;
9
use function League\JsonGuard\error;
10
11
final class Type implements ConstraintInterface
12
{
13
    const KEYWORD = 'type';
14
15
    /**
16
     * Whether examples like 98249283749234923498293171823948729348710298301928331
17
     * and "98249283749234923498293171823948729348710298301928331" are valid strings.
18
     */
19
    const BIGINT_MODE_STRING_VALID = 1;
20
    const BIGINT_MODE_STRING_INVALID = 2;
21
22
    /**
23
     * @var int
24
     */
25
    private static $defaultBigintMode = self::BIGINT_MODE_STRING_INVALID;
26
27
    /**
28
     * @var int
29
     */
30
    private $bigintMode = 0;
31
32
    /**
33
     * @param int $bigintMode
34
     */
35 58
    public function __construct($bigintMode = null)
36
    {
37 58
        $this->bigintMode = $bigintMode ? $bigintMode : self::$defaultBigintMode;
38 58
    }
39
40
    /**
41
     * {@inheritdoc}
42
     */
43 58
    public function validate($value, $type, Validator $validator)
44
    {
45 58
        Assert::type($type, ['array', 'string'], self::KEYWORD, $validator->getSchemaPath());
46
47 56
        if (is_array($type)) {
48 4
            return $this->anyType($value, $type, $validator);
49
        }
50
51
        switch ($type) {
52 56
            case 'object':
53 16
                return $this->validateType($value, 'is_object', $validator);
54 54
            case 'array':
55 8
                return $this->validateType($value, 'is_array', $validator);
56 52
            case 'boolean':
57 8
                return $this->validateType($value, 'is_bool', $validator);
58 50
            case 'null':
59 4
                return $this->validateType($value, 'is_null', $validator);
60 50
            case 'number':
61 10
                return $this->validateType(
62 5
                    $value,
63 10
                    'League\JsonGuard\is_json_number',
64
                    $validator
65 5
                );
66 46
            case 'integer':
67 32
                return $this->validateType(
68 16
                    $value,
69 32
                    'League\JsonGuard\is_json_integer',
70
                    $validator
71 16
                );
72 36
            case 'string':
73 36
                return $this->validateType(
74 18
                    $value,
75 36
                    function ($value) {
76 36
                        if (is_string($value)) {
77
                            // Make sure the string isn't actually a number that was too large
78
                            // to be cast to an int on this platform.  This will only happen if
79
                            // you decode JSON with the JSON_BIGINT_AS_STRING option.
80 34
                            if (self::BIGINT_MODE_STRING_VALID === $this->bigintMode
81 34
                                || !(ctype_digit($value) && bccomp($value, PHP_INT_MAX) === 1)) {
82 28
                                return true;
83
                            }
84 3
                        }
85
86 22
                        return false;
87 36
                    },
88
                    $validator
89 18
                );
90
        }
91
    }
92
93
    /**
94
     * @param int|null $bigintMode
95
     *
96
     * @throws \InvalidArgumentException
97
     */
98
    public function setBigintMode($bigintMode = null)
99
    {
100
        if (!in_array($bigintMode, [null, self::BIGINT_MODE_STRING_VALID, self::BIGINT_MODE_STRING_INVALID])) {
101
            throw new \InvalidArgumentException('Please use one of the bigint mode constants.');
102
        }
103
104
        $this->bigintMode = $bigintMode ? $bigintMode : self::$defaultBigintMode;
105
    }
106
107
    /**
108
     * @return int
109
     */
110
    public function getBigintMode()
111
    {
112
        return $this->bigintMode;
113
    }
114
115
    /**
116
     * @param int $defaultBigintMode
117
     *
118
     * @throws \InvalidArgumentException
119
     */
120 4
    public static function setDefaultBigintMode($defaultBigintMode)
121
    {
122 4
        if (!in_array($defaultBigintMode, [self::BIGINT_MODE_STRING_VALID, self::BIGINT_MODE_STRING_INVALID])) {
123
            throw new \InvalidArgumentException('Please use one of the bigint mode constants.');
124
        }
125
126 4
        self::$defaultBigintMode = $defaultBigintMode;
127 4
    }
128
129
    /**
130
     * @return int
131
     */
132 4
    public static function getDefaultBigintMode()
133
    {
134 4
        return self::$defaultBigintMode;
135
    }
136
137
    /**
138
     * @param mixed                       $value
139
     * @param callable                    $callable
140
     * @param \League\JsonGuard\Validator $validator
141
     *
142
     * @return \League\JsonGuard\ValidationError|null
143
     *
144
     */
145 56
    private function validateType($value, callable $callable, Validator $validator)
146
    {
147 56
        if (call_user_func($callable, $value) === true) {
148 48
            return null;
149
        }
150
151 42
        return error('The data must be a(n) {parameter}.', $validator);
152
    }
153
154
    /**
155
     * @param mixed $value
156
     * @param array $choices
157
     *
158
     * @param Validator $validator
159
     *
160
     * @return ValidationError|null
161
     */
162 4
    private function anyType($value, array $choices, Validator $validator)
163
    {
164 4
        foreach ($choices as $type) {
165 4
            $error = $this->validate($value, $type, $validator);
166 4
            if (is_null($error)) {
167 4
                return null;
168
            }
169 2
        }
170
171 4
        return error('The data must be one of {parameter}.', $validator);
172
    }
173
}
174