Passed
Pull Request — master (#10)
by Dominik
02:09
created

EmbedManyFieldDenormalizer   A

Complexity

Total Complexity 10

Size/Duplication

Total Lines 106
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 2

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 10
lcom 1
cbo 2
dl 0
loc 106
ccs 31
cts 31
cp 1
rs 10
c 0
b 0
f 0

4 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 1
B denormalizeField() 0 28 4
A cleanRelatedObjects() 0 10 2
A assignRelatedObjects() 0 20 3
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 EmbedManyFieldDenormalizer implements FieldDenormalizerInterface
15
{
16
    /**
17
     * @var string
18
     */
19
    private $class;
20
21
    /**
22
     * @var AccessorInterface
23
     */
24
    private $accessor;
25
26
    /**
27
     * @param string            $class
28
     * @param AccessorInterface $accessor
29
     */
30 8
    public function __construct(string $class, AccessorInterface $accessor)
31
    {
32 8
        $this->class = $class;
33 8
        $this->accessor = $accessor;
34 8
    }
35
36
    /**
37
     * @param string                       $path
38
     * @param object                       $object
39
     * @param mixed                        $value
40
     * @param DenormalizerContextInterface $context
41
     * @param DenormalizerInterface|null   $denormalizer
42
     *
43
     * @throws DeserializerLogicException
44
     * @throws DeserializerRuntimeException
45
     */
46 8
    public function denormalizeField(
47
        string $path,
48
        $object,
49
        $value,
50
        DenormalizerContextInterface $context,
51
        DenormalizerInterface $denormalizer = null
52
    ) {
53 8
        if (null === $value) {
54 1
            $this->accessor->setValue($object, $value);
55
56 1
            return;
57
        }
58
59 7
        if (null === $denormalizer) {
60 1
            throw DeserializerLogicException::createMissingDenormalizer($path);
61
        }
62
63 6
        if (!is_array($value)) {
64 1
            throw DeserializerRuntimeException::createInvalidDataType($path, gettype($value), 'array');
65
        }
66
67 5
        $relatedObjects = $this->accessor->getValue($object) ?? [];
68
69 5
        $existEmbObjects = $this->cleanRelatedObjects($relatedObjects);
70 5
        $this->assignRelatedObjects($path, $value, $relatedObjects, $existEmbObjects, $context, $denormalizer);
71
72 4
        $this->accessor->setValue($object, $relatedObjects);
73 4
    }
74
75
    /**
76
     * @param array|\Traversable|\ArrayAccess $relatedObjects
77
     *
78
     * @return array
79
     */
80 5
    private function cleanRelatedObjects(&$relatedObjects)
81
    {
82 5
        $existEmbObjects = [];
83 5
        foreach ($relatedObjects as $i => $existEmbObject) {
84 2
            $existEmbObjects[$i] = $existEmbObject;
85 2
            unset($relatedObjects[$i]);
86
        }
87
88 5
        return $existEmbObjects;
89
    }
90
91
    /**
92
     * @param string                          $path
93
     * @param array                           $value
94
     * @param array|\Traversable|\ArrayAccess $relatedObjects
95
     * @param array                           $existEmbObjects
96
     * @param DenormalizerContextInterface    $context
97
     * @param DenormalizerInterface           $denormalizer
98
     */
99 5
    private function assignRelatedObjects(
100
        string $path,
101
        array $value,
102
        &$relatedObjects,
103
        array $existEmbObjects,
104
        DenormalizerContextInterface $context,
105
        DenormalizerInterface $denormalizer
106
    ) {
107 5
        foreach ($value as $i => $subValue) {
108 5
            $subPath = $path.'['.$i.']';
109
110 5
            if (!is_array($subValue)) {
111 1
                throw DeserializerRuntimeException::createInvalidDataType($subPath, gettype($subValue), 'array');
112
            }
113
114 4
            $relatedObject = $existEmbObjects[$i] ?? $this->class;
115
116 4
            $relatedObjects[$i] = $denormalizer->denormalize($relatedObject, $subValue, $context, $subPath);
117
        }
118 4
    }
119
}
120