Completed
Pull Request — 1.x (#8)
by Dorian
46:47
created

SubHydratingHandler::addValidator()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 1
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 1
rs 10
c 0
b 0
f 0
cc 1
eloc 1
nc 1
nop 1
1
<?php
2
namespace MetaHydrator\Handler;
3
4
use MetaHydrator\Exception\HydratingException;
5
use MetaHydrator\Exception\ValidationException;
6
use MetaHydrator\MetaHydrator;
7
use MetaHydrator\Reflection\Getter;
8
use MetaHydrator\Reflection\GetterInterface;
9
use MetaHydrator\Validator\ValidatorInterface;
10
use Mouf\Hydrator\Hydrator;
11
12
/**
13
 * An implementation of HydratingHandlerInterface aiming to manage partial edition of sub-objects
14
 *
15
 * Class SubHydratingHandler
16
 * @package MetaHydrator\Handler
17
 */
18
class SubHydratingHandler implements HydratingHandlerInterface
19
{
20
    /** @var string */
21
    protected $key;
22
    public function getKey() { return $this->key; }
23
    public function setKey(string $key) { $this->key = $key; }
24
25
    /** @var string */
26
    protected $className;
27
    public function getClassName() { return $this->className; }
28
    public function setClassName(string $className) { $this->className = $className; }
29
30
    /** @var Hydrator */
31
    protected $hydrator;
32
    public function getHydrator() { return $this->hydrator; }
33
    public function setHydrator(Hydrator $hydrator) { $this->hydrator = $hydrator; }
34
35
    /** @var ValidatorInterface[] */
36
    protected $validators;
37
    public function getValidators() { return $this->validators; }
38
    public function setValidators(array $validators) { $this->validators = $validators; }
39
    public function addValidator(ValidatorInterface $validator) { $this->validators[] = $validator; }
40
41
    /** @var mixed */
42
    protected $defaultValue;
43
    public function getDefaultValue() { return $this->defaultValue; }
44
    public function setDefaultValue($defaultValue) { $this->defaultValue = $defaultValue; }
45
46
    /** @var string */
47
    protected $errorMessage;
48
    public function getErrorMessage() { return $this->errorMessage; }
49
    public function setErrorMessage(string $errorMessage) { $this->errorMessage = $errorMessage; }
50
51
    /** @var GetterInterface */
52
    protected $getter;
53
    public function getGetter() { return $this->getter; }
54
    public function setGetter(GetterInterface $getter) { $this->getter = $getter; }
55
56
    /**
57
     * SubHydratingHandler constructor.
58
     * @param string $key
59
     * @param string $className
60
     * @param Hydrator $hydrator
61
     * @param ValidatorInterface[] $validators
62
     * @param mixed $defaultValue
63
     * @param string $errorMessage
64
     * @param GetterInterface $getter
65
     */
66
    public function __construct(string $key, string $className, Hydrator $hydrator, array $validators = [], $defaultValue = null, string $errorMessage = "", GetterInterface $getter = null)
67
    {
68
        $this->key = $key;
69
        $this->className = $className;
70
        $this->hydrator = $hydrator;
71
        $this->validators = $validators;
72
        $this->defaultValue = $defaultValue;
73
        $this->errorMessage = $errorMessage;
74
        $this->getter = $getter ?? new Getter(false);
75
    }
76
77
    /**
78
     * @param array $data
79
     * @param array $targetData
80
     * @param $object
81
     *
82
     * @throws HydratingException
83
     */
84
    public function handle(array $data, array &$targetData, $object = null)
85
    {
86
        if (!array_key_exists($this->key, $data)) {
87
            if ($object !== null) {
88
                return;
89
            } else {
90
                $subObject = $this->defaultValue;
91
                $targetData[$this->key] = $subObject;
92
            }
93
        } elseif ($data[$this->key] === null) {
94
            $subObject = null;
95
            $targetData[$this->key] = null;
96
        } elseif (!is_array($data[$this->key])) {
97
            throw new HydratingException([$this->key => $this->errorMessage]);
98
        } else {
99
            $subData = $data[$this->key];
100
101
            try {
102
                $subObject = $this->getSubObject($object);
103
                if ($subObject !== null) {
104
                    $this->hydrator->hydrateObject($subData, $subObject);
105
                } else {
106
                    $subObject = $this->hydrator->hydrateNewObject($subData, $this->className);
107
                    $targetData[$this->key] = $subObject;
108
                }
109
            } catch (HydratingException $exception) {
110
                throw new HydratingException([$this->key => $exception->getErrorsMap()]);
111
            }
112
        }
113
114
        $this->validate($subObject, $object);
115
    }
116
117
    /**
118
     * @param mixed $parsedValue
119
     * @param mixed $contextObject
120
     *
121
     * @throws HydratingException
122
     */
123 View Code Duplication
    private function validate($parsedValue, $contextObject = null)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
124
    {
125
        try {
126
            foreach ($this->validators as $validator) {
127
                $validator->validate($parsedValue, $contextObject);
128
            }
129
        } catch (ValidationException $exception) {
130
            throw new HydratingException([ $this->key => $exception->getInnerError() ]);
131
        }
132
    }
133
134
    /**
135
     * @param $object
136
     * @return mixed
137
     */
138
    protected function getSubObject($object)
139
    {
140
        if ($object === null) {
141
            return null;
142
        }
143
        return $this->getter->get($object, $this->key);
144
    }
145
}
146