AbstractValidator::__construct()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 3
c 1
b 0
f 0
nc 1
nop 3
dl 0
loc 6
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Arp\LaminasEntity\Validator;
6
7
use Arp\DoctrineEntityRepository\EntityRepositoryInterface;
8
use Arp\Entity\EntityInterface;
9
use Laminas\Validator\Exception\RuntimeException;
0 ignored issues
show
Bug introduced by
The type Laminas\Validator\Exception\RuntimeException was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
10
11
/**
12
 * @author  Alex Patterson <[email protected]>
13
 * @package Arp\LaminasEntity\Validator
14
 */
15
abstract class AbstractValidator extends \Laminas\Validator\AbstractValidator
0 ignored issues
show
Bug introduced by
The type Laminas\Validator\AbstractValidator was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
16
{
17
    /**
18
     * @var EntityRepositoryInterface
19
     */
20
    protected $repository;
21
22
    /**
23
     * @var string[]
24
     */
25
    private $fieldNames;
26
27
    /**
28
     * @param EntityRepositoryInterface $repository
29
     * @param array                     $fieldNames
30
     * @param null|array                $options
31
     */
32
    public function __construct(EntityRepositoryInterface $repository, array $fieldNames, $options = null)
33
    {
34
        $this->repository = $repository;
35
        $this->fieldNames = $fieldNames;
36
37
        parent::__construct($options);
38
    }
39
40
    /**
41
     * @param mixed  $values   The values that should be validated.
42
     * @param array  $context  Additional information that can be used to validate.
43
     *
44
     * @return array
45
     *
46
     * @throws RuntimeException  If the match cannot be performed or the provided data is invalid.
47
     */
48
    protected function getFilterCriteria($values, array $context = []): array
49
    {
50
        $data = $this->getValidationValues($values, $context);
51
52
        // String index array, map index to a field name.
53
        $isHashMap = (array_values($data) !== $data);
54
        $criteria = [];
55
56
        $entityName = $this->repository->getClassName();
57
58
        if ($isHashMap) {
59
            foreach ($this->fieldNames as $fieldName) {
60
                if (!array_key_exists($fieldName, $data)) {
61
                    throw new RuntimeException(
62
                        sprintf(
63
                            'The expected validation value for field \'%s::%s\' could not not found in \'%s\'.',
64
                            $entityName,
65
                            $fieldName,
66
                            __METHOD__
67
                        )
68
                    );
69
                }
70
71
                $criteria[$fieldName] = $data[$fieldName];
72
            }
73
        } else {
74
            $criteria = @array_combine($this->fieldNames, $data);
75
76
            if (!is_array($criteria)) {
77
                throw new RuntimeException(
78
                    sprintf(
79
                        'The expected validation for \'%s\' field values could not be found for ' .
80
                        'numerically index array in \'%s\'.',
81
                        $entityName,
82
                        __METHOD__
83
                    )
84
                );
85
            }
86
        }
87
88
        return $criteria;
89
    }
90
91
    /**
92
     * Create an array of field name to field values based on the provided value.
93
     *
94
     * @param mixed  $values   The values that should be validated.
95
     * @param array  $context  Additional information that can be used to validate.
96
     *
97
     * @return array
98
     *
99
     * @throws RuntimeException  If the criteria cannot be created.
100
     */
101
    private function getValidationValues($values, array $context = []): array
102
    {
103
        if (null === $values || empty($values)) {
104
            /**
105
             * @NOTE If you have NULL/empty here you probably have a config issue. This validator would normally
106
             * require a UNIQUE value to be compared, empty string obviously will not work.
107
             *
108
             * SUGGESTION - Perhaps you need to have a not empty validator registered before this one
109
             * with break_chain_on_failure = true? This will prevent the NULL from being passed here.
110
             */
111
            $values = '';
112
        } elseif ($values instanceof EntityInterface) {
113
            $values = $values->getId();
114
        }
115
116
        if (is_scalar($values) && isset($this->fieldNames[0]) && 1 === count($this->fieldNames)) {
117
            /**
118
             * Here we are mapping the single scalar value to the single match field, casting the value to an array.
119
             */
120
            $values = [
121
                $this->fieldNames[0] => $values,
122
            ];
123
        } elseif (
124
            is_scalar($values)
125
            && (count($this->fieldNames) > 1
126
            || (bool)$this->getOption('useContext') ?: true)
127
        ) {
128
            /**
129
             * @note if we have a scalar value and more than one field in the match criteria then we have to use
130
             *       the context as the replacement.
131
             */
132
            $values = $context;
133
        }
134
135
        if (! is_array($values)) {
136
            throw new RuntimeException(
137
                sprintf(
138
                    'The \'values\' argument of type \'%s\' could not be resolved \'array\' in \'%s\'.',
139
                    gettype($values),
140
                    __METHOD__
141
                )
142
            );
143
        }
144
145
        return $values;
146
    }
147
}
148