Passed
Pull Request — master (#8)
by Dominik
02:42
created

EmbedManyFieldDenormalizer::createCollection()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 10
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 10
ccs 5
cts 5
cp 1
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 5
nc 2
nop 0
crap 2
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
     * @var callable|null
28
     */
29
    private $collectionFactory;
30
31
    /**
32
     * @param string            $class
33
     * @param AccessorInterface $accessor
34
     * @param callable|null     $collectionFactory
35
     */
36 8
    public function __construct(string $class, AccessorInterface $accessor, callable $collectionFactory = null)
37
    {
38 8
        $this->class = $class;
39 8
        $this->accessor = $accessor;
40 8
        $this->collectionFactory = $collectionFactory;
41 8
    }
42
43
    /**
44
     * @param string                       $path
45
     * @param object                       $object
46
     * @param mixed                        $value
47
     * @param DenormalizerContextInterface $context
48
     * @param DenormalizerInterface|null   $denormalizer
49
     *
50
     * @throws DeserializerLogicException
51
     * @throws DeserializerRuntimeException
52
     */
53 8
    public function denormalizeField(
54
        string $path,
55
        $object,
56
        $value,
57
        DenormalizerContextInterface $context,
58
        DenormalizerInterface $denormalizer = null
59
    ) {
60 8
        if (null === $value) {
61 1
            $this->accessor->setValue($object, $value);
62
63 1
            return;
64
        }
65
66 7
        if (null === $denormalizer) {
67 1
            throw DeserializerLogicException::createMissingDenormalizer($path);
68
        }
69
70 6
        if (!is_array($value)) {
71 1
            throw DeserializerRuntimeException::createInvalidDataType($path, gettype($value), 'array');
72
        }
73
74 5
        $existEmbObjects = $this->accessor->getValue($object);
75
76 5
        $relatedObjects = $this->createCollection();
77 5
        foreach ($value as $i => $subValue) {
78 5
            $subPath = $path.'['.$i.']';
79
80 5
            if (!is_array($subValue)) {
81 1
                throw DeserializerRuntimeException::createInvalidDataType($subPath, gettype($subValue), 'array');
82
            }
83
84 4
            $relatedObject = $existEmbObjects[$i] ?? $this->class;
85
86 4
            $relatedObjects[$i] = $denormalizer->denormalize($relatedObject, $subValue, $context, $subPath);
87
        }
88
89 4
        $this->accessor->setValue($object, $relatedObjects);
90 4
    }
91
92
    /**
93
     * @return array|\Traversable|\ArrayAccess
94
     */
95 5
    private function createCollection()
96
    {
97 5
        if (null === $this->collectionFactory) {
98 3
            return [];
99
        }
100
101 2
        $collectionFactory = $this->collectionFactory;
102
103 2
        return $collectionFactory();
104
    }
105
}
106