Passed
Push — master ( f9d022...66a5c5 )
by Sergei
02:37
created

RulesDumper   A

Complexity

Total Complexity 8

Size/Duplication

Total Lines 67
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 21
c 0
b 0
f 0
dl 0
loc 67
rs 10
wmc 8

2 Methods

Rating   Name   Duplication   Size   Complexity  
A asArray() 0 3 1
B fetchOptions() 0 33 7
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Validator\Helper;
6
7
use InvalidArgumentException;
8
use Yiisoft\Validator\RuleInterface;
9
use Yiisoft\Validator\RuleWithOptionsInterface;
10
11
use function is_int;
12
use function is_string;
13
14
/**
15
 * RulesDumper allows to get an array of rule names and corresponding settings from a set of rules.
16
 * The array is usually passed to the client to use it in client-side validation.
17
 *
18
 * @see RuleInterface
19
 * @see RuleWithOptionsInterface
20
 */
21
final class RulesDumper
22
{
23
    /**
24
     * Return all attribute rules as array.
25
     *
26
     * For example:
27
     *
28
     * ```php
29
     * [
30
     *    'amount' => [
31
     *        [
32
     *            'number',
33
     *            'integer' => true,
34
     *            'max' => 100,
35
     *            'notNumberMessage' => ['template' => 'Value must be an integer.', 'parameters' => []],
36
     *            'tooBigMessage' => ['template' => 'Value must be no greater than 100.', 'parameters' => []],
37
     *        ],
38
     *        ['callback'],
39
     *    ],
40
     *    'name' => [
41
     *        [
42
     *            'hasLength',
43
     *            'max' => 20,
44
     *            'message' => ['template' => 'Value must contain at most 20 characters.', 'parameters' => []],
45
     *        ],
46
     *    ],
47
     * ]
48
     * ```
49
     */
50
    public function asArray(iterable $rules): array
51
    {
52
        return $this->fetchOptions($rules);
53
    }
54
55
    private function fetchOptions(iterable $rules): array
56
    {
57
        $result = [];
58
        /** @var mixed $attribute */
59
        /** @var mixed $rule */
60
        foreach ($rules as $attribute => $rule) {
61
            if (!is_int($attribute) && !is_string($attribute)) {
62
                $message = sprintf(
63
                    'An attribute can only have an integer or a string type. %s given.',
64
                    get_debug_type($attribute),
65
                );
66
67
                throw new InvalidArgumentException($message);
68
            }
69
70
            if (is_iterable($rule)) {
71
                $options = $this->fetchOptions($rule);
72
            } elseif ($rule instanceof RuleWithOptionsInterface) {
73
                $options = array_merge([$rule->getName()], $rule->getOptions());
74
            } elseif ($rule instanceof RuleInterface) {
75
                $options = [$rule->getName()];
76
            } else {
77
                throw new InvalidArgumentException(sprintf(
78
                    'Every rule must implement "%s". Type "%s" given.',
79
                    RuleInterface::class,
80
                    get_debug_type($rule),
81
                ));
82
            }
83
84
            $result[$attribute] = $options;
85
        }
86
87
        return $result;
88
    }
89
}
90