Completed
Push — master ( 9588f6...a8c5db )
by Jonathan
03:49
created

Nested   A

Complexity

Total Complexity 28

Size/Duplication

Total Lines 148
Duplicated Lines 0 %

Coupling/Cohesion

Components 2
Dependencies 4

Test Coverage

Coverage 96.61%

Importance

Changes 0
Metric Value
wmc 28
lcom 2
cbo 4
dl 0
loc 148
ccs 57
cts 59
cp 0.9661
rs 10
c 0
b 0
f 0

7 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 6 1
C finish() 0 24 7
C apply() 0 35 16
A nestedObject() 0 4 1
A listOf() 0 4 1
A listOfObjects() 0 4 1
A listOfDifferentObjects() 0 4 1
1
<?php
2
declare(strict_types=1);
3
/**
4
 * Caridea
5
 *
6
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
7
 * use this file except in compliance with the License. You may obtain a copy of
8
 * the License at
9
 *
10
 * http://www.apache.org/licenses/LICENSE-2.0
11
 *
12
 * Unless required by applicable law or agreed to in writing, software
13
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
14
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
15
 * License for the specific language governing permissions and limitations under
16
 * the License.
17
 *
18
 * @copyright 2015-2016 LibreWorks contributors
19
 * @license   http://opensource.org/licenses/Apache-2.0 Apache 2.0 License
20
 */
21
namespace Caridea\Validate\Rule;
22
23
/**
24
 * Rules for nested list and object validation.
25
 *
26
 * @copyright 2015-2016 LibreWorks contributors
27
 * @license   http://opensource.org/licenses/Apache-2.0 Apache 2.0 License
28
 */
29
class Nested implements \Caridea\Validate\Draft
30
{
31
    /**
32
     * @var string The operator type
33
     */
34
    private $operator;
35
    /**
36
     * @var \Caridea\Validate\Validator Optional. A validator for nested objects.
37
     */
38
    private $validator;
39
    /**
40
     * @var string Optional field on object that chooses rules.
41
     */
42
    private $field;
43
44
    /**
45
     * Creates a new NestedRule.
46
     *
47
     * @param string $operator The operator type
48
     * @param mixed|\Caridea\Validate\Validator The validator to use, or definitions to create one
49
     * @param string $field Optional field on object that chooses rules
50
     */
51 4
    protected function __construct(string $operator, $validator, string $field = null)
52
    {
53 4
        $this->operator = $operator;
54 4
        $this->validator = $validator;
55 4
        $this->field = $field;
56 4
    }
57
58
    /**
59
     * Finishes creating a rule using the parent builder.
60
     *
61
     * @param \Caridea\Validate\Builder $builder
62
     * @return \Caridea\Validate\Rule The fully created rule
63
     */
64 4
    public function finish(\Caridea\Validate\Builder $builder): \Caridea\Validate\Rule
65
    {
66 4
        if ($this->validator instanceof \Caridea\Validate\Validator) {
67 4
            return $this;
68
        } else {
69 4
            $rule = clone $this;
70 4
            switch ($this->operator) {
71 4
                case "nested_object":
72 3
                case "list_objects":
73 2
                    $rule->validator = $builder->build($this->validator);
74 2
                    return $rule;
75 2
                case "list":
76 1
                    $rule->validator = $builder->build((object)['entry' => $this->validator]);
77 1
                    return $rule;
78 1
                case "list_different_objects":
79 1
                    $validators = [];
80 1
                    foreach ($this->validator as $value => $ruleset) {
81 1
                        $validators[$value] = $builder->build($ruleset);
82
                    }
83 1
                    $rule->validator = new \Caridea\Validate\SwitchValidator($this->field, $validators);
84 1
                    return $rule;
85
            }
86
        }
87
    }
88
89
    /**
90
     * Validates the provided value.
91
     *
92
     * @param mixed $value A value to validate against the rule
93
     * @param array|object $data The dataset which contains this field
94
     * @return array An array of error codes or null if validation succeeded
95
     */
96 6
    public function apply($value, $data = [])
97
    {
98 6
        if (!($this->validator instanceof \Caridea\Validate\Validator)) {
99 1
            throw new \BadMethodCallException("This rule is a Draft. Try calling the 'finish' method to get the full Rule.");
100
        }
101 5
        if (!is_array($value) && !($value instanceof \Traversable)) {
102 1
            return ['FORMAT_ERROR'];
103
        }
104 4
        switch ($this->operator) {
105 4
            case "nested_object":
106 1
                $result = $this->validator->validate($value);
107 1
                return $result->hasErrors() ? $result->getErrors() : null;
108 3
            case "list":
109 1
                $errors = [];
110 1
                foreach ($value as $entry) {
111 1
                    $result = $this->validator->validate(['entry' => $entry]);
112 1
                    $errors[] = $result->hasErrors() ?
113 1
                        $result->getErrors()['entry'] : null;
114
                }
115 1
                return array_filter($errors) ? $errors : null;
116 2
            case "list_objects":
117 1
            case "list_different_objects":
118 2
                $errors = [];
119 2
                foreach ($value as $entry) {
120
                    try {
121 2
                        $result = $this->validator->validate($entry);
122 2
                        $errors[] = $result->hasErrors() ?
123 2
                            $result->getErrors() : null;
124 1
                    } catch (\InvalidArgumentException $e) {
125 2
                        $errors[] = 'FORMAT_ERROR';
126
                    }
127
                }
128 2
                return array_filter($errors) ? $errors : null;
129
        }
130
    }
131
132
    /**
133
     * Verifies an object value against separate validator rules.
134
     *
135
     * @param object $ruleset The validation ruleset
136
     * @return \Caridea\Validate\Rule\Nested the created rule
137
     */
138 1
    public static function nestedObject(\stdClass $ruleset): Nested
139
    {
140 1
        return new Nested("nested_object", $ruleset);
141
    }
142
143
    /**
144
     * Verifies each entry in a list using one or more rules.
145
     *
146
     * @param mixed $rules The rule or rules to enforce
147
     * @return \Caridea\Validate\Rule\Nested the created rule
148
     */
149 1
    public static function listOf($rules): Nested
150
    {
151 1
        return new Nested("list", $rules);
152
    }
153
154
    /**
155
     * Verifies each entry in a list against separate validator rules.
156
     *
157
     * @param object $ruleset The validation ruleset
158
     * @return \Caridea\Validate\Rule\Nested the created rule
159
     */
160 1
    public static function listOfObjects(\stdClass $ruleset): Nested
161
    {
162 1
        return new Nested("list_objects", $ruleset);
163
    }
164
165
    /**
166
     * Verifies each entry in a list using one of several validators based on a field value.
167
     *
168
     * @param string $field The deciding field name
169
     * @param object $rulesets The rulesets
170
     * @return \Caridea\Validate\Rule\Nested the created rule
171
     */
172 1
    public static function listOfDifferentObjects(string $field, \stdClass $rulesets): Nested
173
    {
174 1
        return new Nested('list_different_objects', $rulesets, $field);
175
    }
176
}
177