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

AdditionalProperties::getDiff()   B

Complexity

Conditions 4
Paths 6

Size

Total Lines 23
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 14
CRAP Score 4
Metric Value
cc 4
eloc 13
nc 6
nop 2
dl 0
loc 23
ccs 14
cts 14
cp 1
crap 4
rs 8.7972
1
<?php
2
3
namespace League\JsonGuard\Constraints;
4
5
use League\JsonGuard;
6
use League\JsonGuard\ErrorCode;
7
use League\JsonGuard\SubSchemaValidatorFactory;
8
use League\JsonGuard\ValidationError;
9
10
class AdditionalProperties implements ParentSchemaAwareContainerInstanceConstraint
11
{
12
    /**
13
     * {@inheritdoc}
14
     */
15 14
    public static function validate(
16
        $data,
17
        $schema,
18
        $parameter,
19
        SubSchemaValidatorFactory $validatorFactory,
20
        $pointer = null
21
    ) {
22 14
        if (!is_object($data)) {
23 4
            return null;
24
        }
25
26 14
        $diff = self::getDiff($data, $schema);
27
28 14
        if (count($diff) === 0) {
29 12
            return null;
30
        }
31
32 10
        if ($parameter === false) {
33 6
            return new ValidationError(
34 6
                'Additional properties are not allowed.',
35 6
                ErrorCode::NOT_ALLOWED_PROPERTY,
36 6
                $data,
37
                $pointer
38 6
            );
39 6
        } elseif (is_object($parameter)) {
40
            // If additionalProperties is an object it's a schema,
41
            // so validate all additional properties against it.
42 6
            $additionalSchema = array_fill_keys($diff, $parameter);
43
44 6
            return Properties::validate($data, $additionalSchema, $validatorFactory, $pointer);
45
        }
46
47
        return null;
48
    }
49
50
    /**
51
     * Get the properties in $data which are not in $schema 'properties' or matching 'patternProperties'.
52
     *
53
     * @param object $data
54
     * @param object $schema
55
     *
56
     * @return array
57
     */
58 14
    protected static function getDiff($data, $schema)
59
    {
60 14
        if (property_exists($schema, 'properties')) {
61 12
            $definedProperties = array_keys(get_object_vars($schema->properties));
62 12
        } else {
63 2
            $definedProperties = [];
64
        }
65
66 14
        $actualProperties = array_keys(get_object_vars($data));
67 14
        $diff             = array_diff($actualProperties, $definedProperties);
68
69
        // The diff doesn't account for patternProperties, so lets filter those out too.
70 14
        if (property_exists($schema, 'patternProperties')) {
71 2
            foreach ($schema->patternProperties as $property => $schema) {
72 2
                $matches = JsonGuard\propertiesMatchingPattern($property, $diff);
73 2
                $diff    = array_diff($diff, $matches);
74 2
            }
75
76 2
            return $diff;
77
        }
78
79 12
        return $diff;
80
    }
81
}
82