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

Builder::field()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 9
ccs 6
cts 6
cp 1
rs 9.6666
c 0
b 0
f 0
cc 2
eloc 6
nc 2
nop 2
crap 2
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;
22
23
/**
24
 * Builds validators.
25
 *
26
 * @copyright 2015-2016 LibreWorks contributors
27
 * @license   http://opensource.org/licenses/Apache-2.0 Apache 2.0 License
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. This argument will be required in 3.0.
44
     */
45 2
    public function __construct(Registry $registry = null)
46
    {
47 2
        $this->registry = $registry ?? new Registry();
48 2
    }
49
50
    /**
51
     * Registers rule definitions into the registry.
52
     *
53
     * @param array $definitions Associative array of definition name to function callback
54
     * @return $this provides a fluent interface
55
     * @see \Caridea\Validate\Registry::register
56
     * @deprecated 2.1.0:3.0.0 Use \Caridea\Validate\Registry::register instead
57
     */
58 1
    public function register(array $definitions): self
59
    {
60 1
        $this->registry->register($definitions);
61 1
        return $this;
62
    }
63
64
    /**
65
     * Adds one or more rules to this builder.
66
     *
67
     * @param string $field The field to validate
68
     * @param string|object|array $rules Either a string name, an associative
69
     *        array, or an object with name → arguments
70
     * @return $this provides a fluent interface
71
     */
72 1
    public function field(string $field, ...$rules): self
73
    {
74 1
        $vrules = [];
75 1
        foreach ($rules as $rule) {
76 1
            $vrules = array_merge($vrules, $this->getRule($rule));
77
        }
78 1
        $this->validators[$field] = $vrules;
79 1
        return $this;
80
    }
81
82
    /**
83
     * Builds a validator for the provided ruleset.
84
     *
85
     * ```javascript
86
     * // rules.json
87
     * {
88
     *     name: 'required',
89
     *     email: ['required', 'email'],
90
     *     drinks: { one_of: [['coffee', 'tea']] },
91
     *     phone: {max_length: 10}
92
     * }
93
     * ```
94
     * ```php
95
     * $ruleset = json_decode(file_get_contents('rules.json'));
96
     * $builder = new \Caridea\Validate\Builder();
97
     * $validator = $builder->build($ruleset);
98
     * ```
99
     *
100
     * @param object|array $ruleset Object or associative array (as returned
101
     *        from `json_decode`) with ruleset, or `null` to use defined rules.
102
     * @return \Caridea\Validate\Validator the built validator
103
     */
104 2
    public function build($ruleset = null): Validator
105
    {
106 2
        $validators = array_merge([], $this->validators);
107 2
        if (is_object($ruleset) || (is_array($ruleset) && count(array_filter(array_keys($ruleset), 'is_string')) > 0)) {
108 1
            foreach ($ruleset as $field => $rules) {
109 1
                $isArray = is_array($rules);
110 1
                $isAssoc = $isArray &&
111 1
                    count(array_filter(array_keys($rules), 'is_string')) > 0;
112 1
                if (is_string($rules) || is_object($rules) || $isAssoc) {
113 1
                    $validators[$field] = $this->getRule($rules);
114 1
                } elseif ($isArray) {
115 1
                    $setup = [];
116 1
                    foreach ($rules as $v) {
117 1
                        $setup = array_merge($setup, $this->getRule($v));
118
                    }
119 1
                    $validators[$field] = $setup;
120
                }
121
            }
122
        }
123 2
        return new Validator($validators);
124
    }
125
126
    /**
127
     * Parses rule definitions.
128
     *
129
     * @param string|object|array $rule Either a string name, an associative
130
     *        array, or an object with name → arguments
131
     * @param mixed $arg Optional constructor argument, or an array of arguments
132
     * @return array<Rule> An array of instantiated rules
133
     */
134 4
    protected function getRule($rule, $arg = null): array
135
    {
136 4
        $rules = [];
137 4
        if (is_string($rule)) {
138 4
            $vrule = $this->registry->factory($rule, $arg);
139 3
            if ($vrule instanceof Draft) {
140 1
                $vrule = $vrule->finish($this);
141
            }
142 3
            $rules[] = $vrule;
143 2
        } elseif (is_object($rule) || is_array($rule)) {
144 2
            foreach ($rule as $name => $args) {
145 2
                $rules = array_merge($rules, $this->getRule($name, $args));
146
            }
147
        }
148 3
        return $rules;
149
    }
150
}
151