Issues (3)

src/DeferredAwareTransformer.php (1 issue)

Labels
Severity
1
<?php
2
3
namespace Lneicelis\Transformer;
4
5
use Lneicelis\Transformer\Exception\TransformerNotFoundException;
6
use Lneicelis\Transformer\Helper\Arr;
7
use Lneicelis\Transformer\ValueObject\Context;
8
use Lneicelis\Transformer\ValueObject\Deferred;
9
use Lneicelis\Transformer\ValueObject\Path;
10
11
class DeferredAwareTransformer extends Transformer
12
{
13
    /** @var array[] */
14
    private $deferredTree = [];
15
16
    /** @var LoaderRegistry */
17
    private $loaderRegistry;
18
19 2
    public function __construct(array $pipes, LoaderRegistry $loaderRegistry)
20
    {
21 2
        parent::__construct($pipes);
22
23 2
        $this->loaderRegistry = $loaderRegistry;
24 2
    }
25
26
    /**
27
     * @param mixed $resource
28
     * @param Context|null $context
29
     * @return string|int|float|array
30
     * @throws TransformerNotFoundException
31
     */
32 2
    public function transform($resource, Context $context = null)
33
    {
34 2
        $context = $context ?: new Context();
35
36 2
        $result = parent::transform($resource, $context);
37 2
        $result = $this->loadDeferred($result, $context);
0 ignored issues
show
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, $context);
Loading history...
38
39 2
        return $result;
40
    }
41
42
    /**
43
     * @param $deferred
44
     * @param Context $context
45
     * @param Path $path
46
     * @return array|float|int|string
47
     * @throws TransformerNotFoundException
48
     */
49 2
    protected function transformAny($deferred, Context $context, Path $path)
50
    {
51 2
        if (! $deferred instanceof Deferred) {
52 2
            return parent::transformAny($deferred, $context, $path);
53
        }
54
55 2
        $resource = $deferred->getResource();
56 2
        $property = $deferred->getProperty();
57 2
        $resourceClass = get_class($resource);
58
59 2
        $this->deferredTree = Arr::setValue($this->deferredTree, [$resourceClass, $property, (string)$path], $deferred);
60
61 2
        return null;
62
    }
63
64
    /**
65
     * @param array $result
66
     * @param Context $context
67
     * @return array
68
     * @throws TransformerNotFoundException
69
     */
70 2
    protected function loadDeferred(array $result, Context $context): array
71
    {
72 2
        foreach ($this->deferredTree as $resourceClass => $properties) {
73 2
            unset($this->deferredTree[$resourceClass]);
74
75 2
            foreach ($properties as $property => $deferredByPath) {
76 2
                $loader = $this->loaderRegistry->getLoader($resourceClass, $property);
77 2
                $paths = array_keys($deferredByPath);
78 2
                $deferreds = array_values($deferredByPath);
79
80 2
                $loadedValues = $loader->load($deferreds);
81
82 2
                foreach ($paths as $index => $path) {
83 2
                    $segments = explode('.', $path);
84 2
                    $path = new Path($segments);
85 2
                    $value = $this->transformAny($loadedValues[$index], $context, $path);
86
87 2
                    $result = Arr::setValue($result, $segments, $value);
88
                }
89
            }
90
        }
91
92 2
        if (! empty($this->deferredTree)) {
93 1
            return $this->loadDeferred($result, $context);
94
        }
95
96 2
        return $result;
97
    }
98
}
99