Issues (8)

src/Rules/AttributeSet.php (1 issue)

Severity
1
<?php
2
/**
3
 * This file is part of graze/config-validation.
4
 *
5
 * Copyright (c) 2017 Nature Delivered Ltd. <https://www.graze.com>
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 *
10
 * @license https://github.com/graze/config-validation/blob/master/LICENSE.md
11
 * @link    https://github.com/graze/config-validation
12
 */
13
14
namespace Graze\ConfigValidation\Rules;
15
16
use Graze\ConfigValidation\Exceptions\AttributeSetException;
17
use Respect\Validation\Exceptions\ComponentException;
18
use Respect\Validation\Rules\AllOf;
19
use Respect\Validation\Rules\Attribute;
20
use Respect\Validation\Validatable;
21
22
/**
23
 * Validates attributes in a defined structure.
24
 */
25
class AttributeSet extends AllOf
26
{
27
    /**
28
     * @param AllOf $rule
29
     *
30
     * @return Validatable
31
     * @throws ComponentException
32
     */
33 3
    private function filterAllOf(AllOf $rule)
34
    {
35 3
        $rules = $rule->getRules();
36 3
        if (count($rules) != 1) {
37 1
            throw new ComponentException('AllOf rule must have only one Attribute rule');
38
        }
39
40 2
        return current($rules);
41
    }
42
43
    /**
44
     * {@inheritdoc}
45
     *
46
     * @param mixed $rule
47
     * @param array $arguments
48
     *
49
     * @return $this
50
     * @throws ComponentException
51
     */
52
    // @codingStandardsIgnoreLine
53 17
    public function addRule($rule, $arguments = [])
54
    {
55 17
        if ($rule instanceof AllOf) {
56 3
            $rule = $this->filterAllOf($rule);
57
        }
58
59 16
        if (!$rule instanceof Attribute) {
60 2
            throw new ComponentException('AttributeSet rule accepts only Attribute rules');
61
        }
62
63 14
        $this->appendRule($rule);
64
65 14
        return $this;
66
    }
67
68
    /**
69
     * {@inheritdoc}
70
     *
71
     * @param array $rules
72
     *
73
     * @return $this
74
     * @throws ComponentException
75
     */
76 17
    public function addRules(array $rules)
77
    {
78 17
        foreach ($rules as $rule) {
79 17
            if (is_array($rule)) {
80 1
                $this->addRules($rule);
81
            } else {
82 17
                $this->addRule($rule);
83
            }
84
        }
85
86 14
        return $this;
87
    }
88
89
    /**
90
     * @return array
91
     */
92 1
    public function getAttributes()
93
    {
94 1
        $keys = [];
95 1
        foreach ($this->getRules() as $attributeRule) {
96 1
            $keys[] = $attributeRule->reference;
97
        }
98
99 1
        return $keys;
100
    }
101
102
    /**
103
     * @param object $input
104
     *
105
     * @return array unknown
106
     */
107 11
    private function checkValidStructure($input)
108
    {
109 11
        $mirror = ($input) ? (array)$input : [];
0 ignored issues
show
$input is of type object, thus it always evaluated to true.
Loading history...
110
111 11
        foreach ($this->getRules() as $attributeRule) {
112 11
            if (array_key_exists($attributeRule->reference, $mirror)) {
113 11
                unset($mirror[$attributeRule->reference]);
114
            }
115
        }
116
117 11
        return array_keys($mirror);
118
    }
119
120
    /**
121
     * @param object $input
122
     *
123
     * @return bool
124
     */
125 11
    private function hasValidStructure($input)
126
    {
127 11
        $unknown = $this->checkValidStructure($input);
128
129 11
        return count($unknown) === 0;
130
    }
131
132
    /**
133
     * @param object $input
134
     *
135
     * @throws AttributeSetException
136
     */
137 6
    private function checkAttributes($input)
138
    {
139 6
        if (!$this->hasValidStructure($input)) {
140 3
            $unknown = $this->checkValidStructure($input);
141
142 3
            $params = [];
143 3
            if (count($unknown) !== 0) {
144 3
                $params['attributes'] = $unknown;
145
            }
146 3
            $exception = $this->reportError($input, $params);
147
148 3
            throw $exception;
149
        }
150 3
    }
151
152
    /**
153
     * {@inheritdoc}
154
     *
155
     * @param mixed $input
156
     *
157
     * @return bool
158
     */
159 5
    public function assert($input)
160
    {
161 5
        $this->checkAttributes($input);
162
163 2
        return parent::assert($input);
164
    }
165
166
    /**
167
     * {@inheritdoc}
168
     * @param mixed $input
169
     *
170
     * @return bool
171
     */
172 1
    public function check($input)
173
    {
174 1
        $this->checkAttributes($input);
175
176 1
        return parent::check($input);
177
    }
178
179
    /**
180
     * {@inheritdoc}
181
     *
182
     * @param mixed $input
183
     *
184
     * @return bool
185
     */
186 5
    public function validate($input)
187
    {
188 5
        if (!$this->hasValidStructure($input)) {
189 1
            return false;
190
        }
191
192 4
        return parent::validate($input);
193
    }
194
}
195