DependenciesConstraint::normalize()   D
last analyzed

Complexity

Conditions 9
Paths 8

Size

Total Lines 38
Code Lines 21

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 24
CRAP Score 9

Importance

Changes 0
Metric Value
dl 0
loc 38
c 0
b 0
f 0
ccs 24
cts 24
cp 1
rs 4.909
cc 9
eloc 21
nc 8
nop 3
crap 9
1
<?php
2
3
/*
4
 * This file is part of the JVal package.
5
 *
6
 * For the full copyright and license information, please view the LICENSE
7
 * file that was distributed with this source code.
8
 */
9
10
namespace JVal\Constraint;
11
12
use JVal\Constraint;
13
use JVal\Context;
14
use JVal\Exception\Constraint\EmptyArrayException;
15
use JVal\Exception\Constraint\InvalidTypeException;
16
use JVal\Exception\Constraint\NotUniqueException;
17
use JVal\Types;
18
use JVal\Walker;
19
use stdClass;
20
21
/**
22
 * Constraint for the "dependencies" keyword.
23
 */
24
class DependenciesConstraint implements Constraint
25
{
26
    /**
27
     * {@inheritdoc}
28
     */
29 373
    public function keywords()
30
    {
31 373
        return ['dependencies'];
32
    }
33
34
    /**
35
     * {@inheritdoc}
36
     */
37 357
    public function supports($type)
38
    {
39 357
        return $type === Types::TYPE_OBJECT;
40
    }
41
42
    /**
43
     * {@inheritdoc}
44
     */
45 37
    public function normalize(stdClass $schema, Context $context, Walker $walker)
46
    {
47 37
        $context->enterNode('dependencies');
48
49 37
        if (!is_object($schema->dependencies)) {
50 1
            throw new InvalidTypeException($context, Types::TYPE_OBJECT);
51
        }
52
53 36
        foreach ($schema->dependencies as $property => $value) {
54 36
            $context->enterNode($property);
55
56 36
            if (is_object($value)) {
57 12
                $walker->parseSchema($value, $context);
58 36
            } elseif (is_array($value)) {
59 24
                if (0 === $propertyCount = count($value)) {
60 1
                    throw new EmptyArrayException($context);
61
                }
62
63 24
                foreach ($value as $index => $subProperty) {
64 24
                    if (!is_string($subProperty)) {
65 1
                        $context->enterNode($index);
66
67 1
                        throw new InvalidTypeException($context, Types::TYPE_STRING);
68
                    }
69 24
                }
70
71 24
                if (count(array_unique($value)) !== $propertyCount) {
72 1
                    throw new NotUniqueException($context);
73
                }
74 24
            } else {
75 1
                throw new InvalidTypeException($context, [Types::TYPE_OBJECT, Types::TYPE_ARRAY]);
76
            }
77
78 36
            $context->leaveNode();
79 36
        }
80
81 32
        $context->leaveNode();
82 32
    }
83
84
    /**
85
     * {@inheritdoc}
86
     */
87 30
    public function apply($instance, stdClass $schema, Context $context, Walker $walker)
88
    {
89 30
        foreach ($schema->dependencies as $property => $value) {
90 30
            if (property_exists($instance, $property)) {
91 20
                if (is_object($value)) {
92
                    // Schema dependencies (see §5.4.5.2.1)
93 9
                    $walker->applyConstraints($instance, $value, $context);
94 9
                } else {
95
                    // Property dependencies (see §5.4.5.2.2)
96 11
                    foreach ($value as $propertyDependency) {
97 11
                        if (!property_exists($instance, $propertyDependency)) {
98 6
                            $context->addViolation(
99 6
                                'dependency property "%s" is missing',
100 6
                                [$propertyDependency]
101 6
                            );
102 6
                        }
103 11
                    }
104
                }
105 20
            }
106 30
        }
107 30
    }
108
}
109