Completed
Push — master ( a8c5db...77b530 )
by Jonathan
02:15
created

Builder::getRule()   B

Complexity

Conditions 6
Paths 4

Size

Total Lines 16
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 11
CRAP Score 6

Importance

Changes 0
Metric Value
dl 0
loc 16
ccs 11
cts 11
cp 1
rs 8.8571
c 0
b 0
f 0
cc 6
eloc 11
nc 4
nop 2
crap 6
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-2018 LibreWorks contributors
19
 * @license   Apache-2.0
20
 */
21
namespace Caridea\Validate;
22
23
/**
24
 * Builds validators.
25
 *
26
 * @copyright 2015-2018 LibreWorks contributors
27
 * @license   Apache-2.0
28
 */
29
class Builder
30
{
31
    /**
32
     * @var \Caridea\Validate\Registry
33
     */
34
    private $registry;
35
    /**
36
     * @var array<string,array<Rule>>
37
     */
38
    private $validators = [];
39
40
    /**
41
     * Creates a new Validation Builder.
42
     *
43
     * @param \Caridea\Validate\Registry $registry The registry.
44
     */
45 1
    public function __construct(Registry $registry)
46
    {
47 1
        $this->registry = $registry;
48 1
    }
49
50
    /**
51
     * Adds one or more rules to this builder.
52
     *
53
     * @param string $field The field to validate
54
     * @param string|object|array $rules Either a string name, an associative
55
     *        array, or an object with name → arguments
56
     * @return $this provides a fluent interface
57
     */
58 1
    public function field(string $field, ...$rules): self
59
    {
60 1
        $vrules = [];
61 1
        foreach ($rules as $rule) {
62 1
            $vrules = array_merge($vrules, $this->getRule($rule));
63
        }
64 1
        $this->validators[$field] = $vrules;
65 1
        return $this;
66
    }
67
68
    /**
69
     * Builds a validator for the provided ruleset.
70
     *
71
     * ```javascript
72
     * // rules.json
73
     * {
74
     *     name: 'required',
75
     *     email: ['required', 'email'],
76
     *     drinks: { one_of: [['coffee', 'tea']] },
77
     *     phone: {max_length: 10}
78
     * }
79
     * ```
80
     * ```php
81
     * $ruleset = json_decode(file_get_contents('rules.json'));
82
     * $builder = new \Caridea\Validate\Builder();
83
     * $validator = $builder->build($ruleset);
84
     * ```
85
     *
86
     * @param object|array $ruleset Object or associative array (as returned
87
     *        from `json_decode`) with ruleset, or `null` to use defined rules.
88
     * @return \Caridea\Validate\Validator the built validator
89
     */
90 1
    public function build($ruleset = null): Validator
91
    {
92 1
        $validators = array_merge([], $this->validators);
93 1
        if (is_object($ruleset) || (is_array($ruleset) && count(array_filter(array_keys($ruleset), 'is_string')) > 0)) {
94
            foreach ($ruleset as $field => $rules) {
95
                $isArray = is_array($rules);
96
                $isAssoc = $isArray &&
97
                    count(array_filter(array_keys($rules), 'is_string')) > 0;
98
                if (is_string($rules) || is_object($rules) || $isAssoc) {
99
                    $validators[$field] = $this->getRule($rules);
100
                } elseif ($isArray) {
101
                    $setup = [];
102
                    foreach ($rules as $v) {
103
                        $setup = array_merge($setup, $this->getRule($v));
104
                    }
105
                    $validators[$field] = $setup;
106
                }
107
            }
108
        }
109 1
        return new Validator($validators);
110
    }
111
112
    /**
113
     * Parses rule definitions.
114
     *
115
     * @param string|object|array $rule Either a string name, an associative
116
     *        array, or an object with name → arguments
117
     * @param mixed $arg Optional constructor argument, or an array of arguments
118
     * @return array<Rule> An array of instantiated rules
119
     */
120 3
    protected function getRule($rule, $arg = null): array
121
    {
122 3
        $rules = [];
123 3
        if (is_string($rule)) {
124 3
            $vrule = $this->registry->factory($rule, $arg);
125 2
            if ($vrule instanceof Draft) {
126 1
                $vrule = $vrule->finish($this);
127
            }
128 2
            $rules[] = $vrule;
129 1
        } elseif (is_object($rule) || is_array($rule)) {
130 1
            foreach ($rule as $name => $args) {
131 1
                $rules = array_merge($rules, $this->getRule($name, $args));
132
            }
133
        }
134 2
        return $rules;
135
    }
136
}
137