Passed
Push — master ( d9423e...3d42cd )
by Lukas
04:29
created

DeferredAwareTransformer::transformAny()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 11
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 2

Importance

Changes 0
Metric Value
eloc 6
dl 0
loc 11
ccs 7
cts 7
cp 1
rs 10
c 0
b 0
f 0
cc 2
nc 2
nop 3
crap 2
1
<?php
2
3
namespace Lneicelis\Transformer;
4
5
use Lneicelis\Transformer\Contract\CanLoad;
6
use Lneicelis\Transformer\Exception\TransformerNotFoundException;
7
use Lneicelis\Transformer\Helper\Arr;
8
use Lneicelis\Transformer\ValueObject\Context;
9
use Lneicelis\Transformer\ValueObject\Deferred;
10
use Lneicelis\Transformer\ValueObject\Path;
11
12
class DeferredAwareTransformer extends Transformer
13
{
14
    /** @var array[] */
15
    private $deferredTree = [];
16
17
    /** @var CanLoad */
18
    private $loaderByResourceClass;
19
20 2
    public function addLoader(CanLoad $loader): void
21
    {
22 2
        $this->loaderByResourceClass[$loader->getResourceName()] = $loader;
23 2
    }
24
25
    /**
26
     * @param mixed $resource
27
     * @param Context|null $context
28
     * @return string|int|float|array
29
     * @throws TransformerNotFoundException
30
     */
31 2
    public function transform($resource, Context $context = null)
32
    {
33 2
        $context = $context ?: new Context();
34
35 2
        $result = parent::transform($resource, $context);
36 2
        if (! empty($this->deferredTree)) {
37 2
            $result = $this->loadDeferred($result);
0 ignored issues
show
Bug introduced by
It seems like $result can also be of type double and integer and string; however, parameter $result of Lneicelis\Transformer\De...sformer::loadDeferred() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

37
            $result = $this->loadDeferred(/** @scrutinizer ignore-type */ $result);
Loading history...
38
39 2
            return $this->transform($result, $context);
40
        }
41
42 2
        return $result;
43
    }
44
45
    /**
46
     * @param $resource
47
     * @param Context $context
48
     * @param Path $path
49
     * @return array|float|int|string
50
     * @throws TransformerNotFoundException
51
     * @throws Exception\TransformerNotFoundException
52
     */
53 2
    protected function transformAny($resource, Context $context, Path $path)
54
    {
55 2
        if (! $resource instanceof Deferred) {
56 2
            return parent::transformAny($resource, $context, $path);
57
        }
58
59 2
        $resourceClass = $resource->getResourceClass();
60 2
        $resourceId = $resource->getId();
61 2
        $this->deferredTree[$resourceClass][$resourceId] = $path;
62
63 2
        return null;
64
    }
65
66
    /**
67
     * @param array $result
68
     * @return array
69
     */
70 2
    protected function loadDeferred(array $result): array
71
    {
72 2
        foreach ($this->deferredTree as $resourceClass => $pathByResourceId) {
73 2
            $loader = $this->getLoader($resourceClass);
74 2
            $ids = array_keys($pathByResourceId);
75
76 2
            $loadedValues = $loader->load($ids);
77
78 2
            foreach (array_values($pathByResourceId) as $index => $path) {
79
                /** @var Path $path */
80 2
                $result = Arr::setValue(
81 2
                    $result,
82 2
                    $path->getSegments(),
83 2
                    $loadedValues[$index]
84
                );
85
            }
86
87 2
            unset($this->deferredTree[$resourceClass]);
88
        }
89
90 2
        return $result;
91
    }
92
93 2
    protected function getLoader(string $resourceClass): CanLoad
94
    {
95 2
        return $this->loaderByResourceClass[$resourceClass];
96
    }
97
}
98