Completed
Push — master ( 5927eb...1e13db )
by
unknown
04:04
created

Type::validate()   C

Complexity

Conditions 15
Paths 9

Size

Total Lines 53
Code Lines 34

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 36
CRAP Score 15.0044
Metric Value
cc 15
eloc 34
nc 9
nop 3
dl 0
loc 53
ccs 36
cts 37
cp 0.973
crap 15.0044
rs 6.2939

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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 Type implements PropertyConstraint
10
{
11
    /**
12
     * {@inheritdoc}
13
     */
14 34
    public static function validate($value, $type, $pointer = null)
15
    {
16 34
        if (is_array($type)) {
17 4
            return self::anyType($value, $type, $pointer);
18
        }
19
20
        switch ($type) {
21 34
            case 'object':
22 10
                return self::validateType($value, $type, 'is_object', ErrorCode::INVALID_OBJECT, $pointer);
23 34
            case 'array':
24 8
                return self::validateType($value, $type, 'is_array', ErrorCode::INVALID_ARRAY, $pointer);
25 32
            case 'boolean':
26 8
                return self::validateType($value, $type, 'is_bool', ErrorCode::INVALID_BOOLEAN, $pointer);
27 30
            case 'null':
28 4
                return self::validateType($value, $type, 'is_null', ErrorCode::INVALID_NULL, $pointer);
29 30
            case 'number':
30 6
                return self::validateType($value, $type, 'is_numeric', ErrorCode::INVALID_NUMERIC, $pointer);
31 30
            case 'integer':
32 30
                return self::validateType(
33 30
                    $value,
34 30
                    $type,
35
                    function ($value) {
36
                        // when json decoding numbers larger than PHP_INT_MAX,
37
                        // it's possible to receive a valid int as a string.
38 30
                        return is_int($value) || is_string($value) && ctype_digit($value);
39 30
                    },
40 30
                    ErrorCode::INVALID_INTEGER,
41
                    $pointer
42 30
                );
43 20
            case 'string':
44 20
                return self::validateType(
45 20
                    $value,
46 20
                    $type,
47 20
                    function ($value) {
48 20
                        if (is_string($value)) {
49
                            // Make sure the string isn't actually a number that was too large
50
                            // to be cast to an int on this platform.  This is only possible
51
                            // if the bcmath extension is loaded, and will only happen if
52
                            // you decode JSON with the JSON_BIGINT_AS_STRING option.
53 18
                            if (function_exists('bccomp')) {
54 18
                                if (!(ctype_digit($value) && bccomp($value, PHP_INT_MAX, 0) === 1)) {
55 16
                                    return true;
56
                                }
57 2
                            }
58 2
                        }
59
60 18
                        return false;
61 20
                    },
62 20
                    ErrorCode::INVALID_STRING,
63
                    $pointer
64 20
                );
65
        }
66
    }
67
68
    /**
69
     * @param mixed    $value
70
     * @param string   $type
71
     * @param callable $callable
72
     * @param int      $errorCode
73
     * @param string   $pointer
74
     *
75
     * @return \League\JsonGuard\ValidationError|null
76
     */
77 34
    private static function validateType($value, $type, callable $callable, $errorCode, $pointer)
78
    {
79 34
        if (call_user_func($callable, $value) === true) {
80 32
            return null;
81
        }
82
83 34
        $message = sprintf('Value "%s" is not %s.', JsonGuard\asString($value), $type);
84
85 34
        return new ValidationError($message, $errorCode, $value, $pointer);
86
    }
87
88
    /**
89
     * @param mixed  $value
90
     * @param array  $choices
91
     * @param string $pointer
92
     *
93
     * @return \League\JsonGuard\ValidationError|null
94
     */
95 4
    private static function anyType($value, array $choices, $pointer)
96
    {
97 4
        foreach ($choices as $type) {
98 4
            $error = static::validate($value, $type, $pointer);
99 4
            if (is_null($error)) {
100 4
                return null;
101
            }
102 4
        }
103
104 4
        $message = sprintf(
105 4
            'Value "%s" is not one of: %s',
106 4
            JsonGuard\asString($value),
107 4
            implode(', ', array_map('League\JsonGuard\asString', $choices))
108 4
        );
109
110 4
        return new ValidationError($message, ErrorCode::INVALID_TYPE, $value, $pointer, ['types' => $choices]);
111
    }
112
}
113