ReferenceManyFieldDenormalizer::__construct()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 1
Metric Value
cc 1
eloc 2
c 1
b 0
f 1
nc 1
nop 2
dl 0
loc 4
ccs 0
cts 0
cp 0
crap 2
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Chubbyphp\Deserialization\Denormalizer\Relation;
6
7
use Chubbyphp\Deserialization\Accessor\AccessorInterface;
8
use Chubbyphp\Deserialization\Denormalizer\DenormalizerContextInterface;
9
use Chubbyphp\Deserialization\Denormalizer\DenormalizerInterface;
10
use Chubbyphp\Deserialization\Denormalizer\FieldDenormalizerInterface;
11
use Chubbyphp\Deserialization\DeserializerLogicException;
12
use Chubbyphp\Deserialization\DeserializerRuntimeException;
13
14
final class ReferenceManyFieldDenormalizer implements FieldDenormalizerInterface
15
{
16
    /**
17
     * @var callable
18
     */
19
    private $repository;
20
21
    /**
22
     * @var AccessorInterface
23
     */
24
    private $accessor;
25
26
    public function __construct(callable $repository, AccessorInterface $accessor)
27
    {
28
        $this->repository = $repository;
29
        $this->accessor = $accessor;
30 8
    }
31
32 8
    /**
33 8
     * @param object $object
34 8
     * @param mixed  $value
35
     *
36
     * @throws DeserializerLogicException
37
     * @throws DeserializerRuntimeException
38
     */
39
    public function denormalizeField(
40
        string $path,
41
        $object,
42
        $value,
43
        DenormalizerContextInterface $context,
44
        DenormalizerInterface $denormalizer = null
45
    ): void {
46 8
        if (null === $value) {
47
            $value = [];
48
        }
49
50
        if (!is_array($value)) {
51
            throw DeserializerRuntimeException::createInvalidDataType($path, gettype($value), 'array');
52
        }
53 8
54 1
        $relatedObjects = $this->accessor->getValue($object) ?? [];
55
56
        $this->cleanRelatedObjects($relatedObjects);
57 8
        $this->assignRelatedObjects($path, $value, $relatedObjects);
58 1
59
        $this->accessor->setValue($object, $relatedObjects);
60
    }
61 7
62
    /**
63 7
     * @param iterable $relatedObjects
64 7
     */
65
    private function cleanRelatedObjects(&$relatedObjects): void
66 6
    {
67 6
        foreach ($relatedObjects as $key => $existEmbObject) {
68
            unset($relatedObjects[$key]);
69
        }
70
    }
71
72 7
    /**
73
     * @param iterable $relatedObjects
74 7
     */
75 2
    private function assignRelatedObjects(string $path, array $value, &$relatedObjects): void
76
    {
77 7
        $repository = $this->repository;
78
79
        foreach ($value as $key => $subValue) {
80
            $subPath = $path.'['.$key.']';
81
82
            if (!is_string($subValue)) {
83
                throw DeserializerRuntimeException::createInvalidDataType($subPath, gettype($subValue), 'string');
84 7
            }
85
86 7
            $relatedObjects[$key] = $repository($subValue) ?? $subValue;
87
        }
88 7
    }
89
}
90