Issues (3)

src/Pipe/LazyPropertiesPipe.php (1 issue)

Severity
1
<?php
2
3
namespace Lneicelis\Transformer\Pipe;
4
5
use Lneicelis\Transformer\Contract\CanPipe;
6
use Lneicelis\Transformer\Contract\HasLazyProperties;
7
use Lneicelis\Transformer\Contract\HasSchema;
8
use Lneicelis\Transformer\Exception\TransformerNotFoundException;
9
use Lneicelis\Transformer\TransformerRegistry;
10
use Lneicelis\Transformer\ValueObject\Context;
11
use Lneicelis\Transformer\ValueObject\Path;
12
13
class LazyPropertiesPipe implements CanPipe
14
{
15
    /** @var TransformerRegistry */
16
    protected $transformerRepository;
17
18
    /**
19
     * @param TransformerRegistry $transformerRepository
20
     */
21 12
    public function __construct(TransformerRegistry $transformerRepository)
22
    {
23 12
        $this->transformerRepository = $transformerRepository;
24 12
    }
25
26
    /**
27
     * @param object $resource
28
     * @param Context $context
29
     * @param Path $path
30
     * @param $data
31
     * @return array
32
     * @throws TransformerNotFoundException
33
     */
34 7
    public function pipe($resource, Context $context, Path $path, $data)
35
    {
36 7
        if (! $context instanceof HasSchema) {
0 ignored issues
show
$context is always a sub-type of Lneicelis\Transformer\Contract\HasSchema.
Loading history...
37
            return $data;
38
        }
39
40 7
        $transformer = $this->transformerRepository->getTransformer($resource);
41
42 7
        if (! $transformer instanceof HasLazyProperties) {
43 5
            return $data;
44
        }
45
46
47 2
        $schema = $this->getPathSchema($path, $context->getSchema());
48 2
        $properties = $this->getProperties($schema);
49
50 2
        return array_reduce(
51 2
            $properties,
52 2
            function (array $data, string $key) use ($resource, $transformer) {
53 2
                if (! array_key_exists($key, $data)) {
54 2
                    $data[$key] = $transformer->{$key}($resource);
55
                }
56
57 2
                return $data;
58 2
            },
59 2
            $data
60
        );
61
    }
62
63
    private function getProperties(array $schema): array
64
    {
65 2
        return array_map(function ($value, $key) {
66 2
            return is_string($value) ? $value : $key;
67 2
        }, $schema, array_keys($schema));
68
    }
69
70
    private function getPathSchema(Path $path, array $schema): array
71
    {
72 2
        $segments = array_filter($path->getSegments(), function ($segment) {
73 1
            return ! is_numeric($segment);
74 2
        });
75
76 2
        return $this->arrayGet($schema, $segments, []);
77
    }
78
79 2
    private function arrayGet(array $array, array $path, $default): array
80
    {
81 2
        foreach ($path as $key) {
82 1
            if (! array_key_exists($key, $array)) {
83 1
                return $default;
84
            }
85
86 1
            $array = $array[$key];
87
        }
88
89 2
        return $array;
90
    }
91
}
92