Passed
Pull Request — master (#5)
by Alex
02:16
created

AbstractEntityValidator::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
cc 1
eloc 1
c 1
b 0
f 1
nc 1
nop 3
dl 0
loc 6
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Arp\LaminasDoctrine\Validator;
6
7
use Arp\Entity\EntityInterface;
8
use Arp\LaminasDoctrine\Repository\EntityRepositoryInterface;
9
use Laminas\Validator\AbstractValidator;
10
use Laminas\Validator\Exception\RuntimeException;
11
12
abstract class AbstractEntityValidator extends AbstractValidator
13
{
14
    public const CRITERIA_EMPTY = 'criteria_empty';
15
16
    /**
17
     * @param EntityRepositoryInterface<EntityInterface> $repository
18
     * @param array<int, string> $fieldNames
19
     * @param array<mixed>|null $options
20
     */
21
    public function __construct(
22
        protected EntityRepositoryInterface $repository,
23
        protected array $fieldNames,
24
        ?array $options = null
25
    ) {
26
        parent::__construct($options);
27
    }
28
29
    /**
30
     * @param array<mixed> $criteria
31
     *
32
     * @throws RuntimeException
33
     */
34
    protected function getMatchedEntity(array $criteria): ?EntityInterface
35
    {
36
        try {
37
            return $this->repository->findOneBy($criteria);
38
        } catch (\Exception $e) {
39
            throw new RuntimeException(
40
                sprintf(
41
                    'Failed to validate for entity \'%s\': %s',
42
                    $this->repository->getClassName(),
43
                    $e->getMessage()
44
                ),
45
                $e->getCode(),
46
                $e
47
            );
48
        }
49
    }
50
51
    /**
52
     * @param mixed $value
53
     * @param array<mixed> $additionalData
54
     *
55
     * @return array<mixed>
56
     */
57
    protected function getMatchCriteria(mixed $value, array $additionalData): array
58
    {
59
        $criteria = [];
60
        foreach ($this->fieldNames as $fieldName) {
61
            if (empty($criteria[$fieldName]) && !empty($additionalData[$fieldName])) {
62
                $criteria[$fieldName] = $additionalData[$fieldName];
63
            }
64
        }
65
66
        // Let's add in the existing value if not already set
67
        if (!empty($this->fieldNames[0]) && !array_key_exists($this->fieldNames[0], $criteria)) {
68
            $criteria[$this->fieldNames[0]] = $value;
69
        }
70
71
        return $criteria;
72
    }
73
74
    /**
75
     * @param string $messageKey
76
     * @param mixed|null $value
77
     *
78
     * @return void
79
     */
80
    protected function error($messageKey, mixed $value = null): void
81
    {
82
        if (empty($this->abstractOptions['messageVariables'])) {
83
            $this->abstractOptions['messageVariables'] = array_combine($this->fieldNames, $this->fieldNames);
84
        }
85
86
        if (is_array($value)) {
87
            foreach ($value as $errorFieldName => $errorFieldValue) {
88
                $this->{$errorFieldName} = $errorFieldValue;
89
            }
90
        }
91
92
        parent::error($messageKey, $value);
93
    }
94
}
95