RegistryChecker::anyValue()   A
last analyzed

Complexity

Conditions 3
Paths 3

Size

Total Lines 14
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 14
rs 9.4285
c 0
b 0
f 0
cc 3
eloc 7
nc 3
nop 3
1
<?php
2
3
namespace Vvval\Spiral\Validation\Checkers;
4
5
use Spiral\ORM\Entities\RecordSource;
6
use Spiral\Validation\Prototypes\AbstractChecker;
7
use Vvval\Spiral\Validation\Checkers\Traits\CustomMessagesTrait;
8
9
class RegistryChecker extends AbstractChecker
10
{
11
    use CustomMessagesTrait;
12
13
    /**
14
     * Default error messages associated with checker method by name.
15
     * {@inheritdoc}
16
     */
17
    const MESSAGES = [
18
        'anyValue'      => '[[This value is required.]]',
19
        'allowedValues' => '[[This value is not allowed.]]'
20
    ];
21
22
    /**
23
     * Check if any of multiple values is selected (radio buttons or check boxes).
24
     * This rule will not pass empty condition check, so it has to be added to "emptyConditions" section in the validation config.
25
     *
26
     * @param mixed       $value
27
     * @param string|null $field
28
     * @param string|null $message
29
     *
30
     * @return bool
31
     */
32
    public function anyValue($value, string $field = null, string $message = null): bool
33
    {
34
        if (!is_null($value)) {
35
            return true;
36
        }
37
38
        if (!empty($field)) {
39
            $this->getValidator()->registerError($field, $this->makeMessage($message, __METHOD__));
40
41
            return true;
42
        }
43
44
        return false;
45
    }
46
47
    /**
48
     * Check if array of given values contain only allowed values.
49
     * Allowed values are taken from database. You can overwrite populate method to get allowed values from another place, for example from config.
50
     *
51
     * @param array       $values
52
     * @param string      $sourceClass
53
     * @param string      $column
54
     * @param string|null $field
55
     * @param string|null $message
56
     *
57
     * @return bool
58
     * @throws \Psr\Container\ContainerExceptionInterface
59
     * @throws \Psr\Container\NotFoundExceptionInterface
60
     */
61
    public function allowedValues(array $values, string $sourceClass, string $column, string $field = null, string $message = null): bool
62
    {
63
        $data = $this->populate($sourceClass, $column);
64
65
        $diff = array_diff($values, $data);
66
        if (!empty($diff) && !empty($field)) {
67
            foreach ($diff as $item) {
68
                $this->getValidator()->registerError($this->makeField($field, $item), $this->makeMessage($message, __METHOD__));
69
            }
70
        }
71
72
        return empty($diff);
73
    }
74
75
    /**
76
     * Populate registry records and fetch given column to match valid values.
77
     *
78
     * @param string $sourceClass
79
     * @param string $column
80
     *
81
     * @return array
82
     * @throws \Psr\Container\ContainerExceptionInterface
83
     * @throws \Psr\Container\NotFoundExceptionInterface
84
     */
85
    protected function populate(string $sourceClass, string $column): array
86
    {
87
        $source = $this->getSource($sourceClass);
88
        $input = $source->find()->fetchAll();
89
90
        return array_column($input, $column);
91
    }
92
93
    /**
94
     * Cast record source by its class name.
95
     *
96
     * @param string $sourceClass
97
     *
98
     * @return \Spiral\ORM\Entities\RecordSource
99
     * @throws \Psr\Container\ContainerExceptionInterface
100
     * @throws \Psr\Container\NotFoundExceptionInterface
101
     */
102
    protected function getSource(string $sourceClass): RecordSource
103
    {
104
        return $this->container->get($sourceClass);
105
    }
106
107
    /**
108
     * Given error field name can be formatted using sprintf function.
109
     * Don't forget to add placeholders to render errors
110
     *
111
     * Example:
112
     *      errorField = "registry-error-for-value-%s" (in the request filter)
113
     *      data-message-placeholder = "registry-error-for-value-test"
114
     *
115
     *      If "test" is invalid value, you will receive error in the field "registry-error-for-value-test"
116
     *
117
     * @param string $format
118
     * @param mixed  $value
119
     *
120
     * @return string
121
     */
122
    private function makeField(string $format, $value): string
123
    {
124
        return sprintf($format, $value);
125
    }
126
}