Passed
Push — master ( 973a5a...376082 )
by Paul
05:11
created

transformArrayPartial()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 14
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 2

Importance

Changes 0
Metric Value
cc 2
eloc 8
nc 2
nop 2
dl 0
loc 14
ccs 9
cts 9
cp 1
crap 2
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
namespace CCT\Component\Rest\Transformer\Response;
4
5
use CCT\Component\Rest\Http\ResponseInterface;
6
use CCT\Component\Rest\Serializer\ContextInterface;
7
use Symfony\Component\HttpFoundation\Response;
8
9
class ObjectCollectionTransformer extends AbstractSerializerResponseTransformer
10
{
11
    protected $mappingKeys = null;
12
13
    /**
14
     * @param ResponseInterface|Response $response
15
     *
16
     * {@inheritdoc}
17
     */
18 3
    public function transform(ResponseInterface $response, ContextInterface $context = null)
19
    {
20 3
        $data = $response->getData();
21
22 3
        if (count($this->mappingKeys) === 0) {
23 1
            $response->setData(
24 1
                $this->transformArrayPartial($data, $context)
25
            );
26 1
            return;
27
        }
28
29 2
        $mappedData = $this->map($response->getData());
30 2
        $transformedData = [];
31
32 2
        foreach ($mappedData as $key => $transformingData) {
33 2
            $transformedData[$key] = $this->transformArrayPartial($transformingData, $context);
34
        }
35
36 2
        $response->setData(array_merge($data, $transformedData));
37 2
    }
38
39
    /**
40
     * @param ResponseInterface|Response $response
41
     *
42
     * {@inheritdoc}
43
     */
44 8
    public function supports(ResponseInterface $response): bool
45
    {
46 8
        $data = $response->getData();
47
48
        return (
49 8
            $response->isSuccessful()
50 8
            && $this->isArrayAndNotEmpty($data)
51 8
            && $this->mappingKeysExist($data)
52 8
            && $this->isDataSequential($this->map($data))
53
        );
54
    }
55
56
    /**
57
     * @param array $transformingData
58
     * @param ContextInterface $context
59
     *
60
     * @return array
61
     */
62 3
    protected function transformArrayPartial(array $transformingData, ContextInterface $context = null): array
63
    {
64 3
        $transformedData = [];
65
66 3
        foreach ($transformingData as $key => $object) {
67 3
            $transformedData[$key] = $this->serializer->deserialize(
68 3
                json_encode($object),
69 3
                $this->class,
70 3
                'json',
71 3
                $context ?? $this->context
72
            );
73
        }
74
75 3
        return $transformedData;
76
    }
77
78
    /**
79
     * Check if $data is an array and not empty
80
     *
81
     * @param mixed $data
82
     *
83
     * @return bool
84
     */
85 7
    protected function isArrayAndNotEmpty($data)
86
    {
87 7
        return is_array($data) && !empty($data);
88
    }
89
90
    /**
91
     * Extract collection from response array based on mapping key.
92
     * Supports single level only
93
     * If no mapping key returns full data
94
     *
95
     * @param $data
96
     *
97
     * @return array
98
     */
99 5
    protected function map(array $data): array
100
    {
101 5
        if (null === $this->mappingKeys) {
102 2
            return $data;
103
        }
104
105 3
        $mappingKeys = $this->mappingKeys;
106
107
        return
108 3
            array_filter(
109 3
                $data,
110 3
                function ($key) use ($mappingKeys) {
111 3
                    return in_array($key, $mappingKeys);
112 3
                },
113 3
                ARRAY_FILTER_USE_KEY
114
            );
115
    }
116
117
    /**
118
     * @param array $data
119
     *
120
     * @return bool
121
     */
122 4
    protected function mappingKeysExist(array $data): bool
123
    {
124 4
        if (null === $this->mappingKeys) {
125 2
            return true;
126
        }
127
128 2
        return (bool)count(array_intersect($this->mappingKeys, array_keys($data))) > 0;
129
    }
130
131
    /**
132
     * @return array|null
133
     */
134
    public function getMappingKeys(): ?array
135
    {
136
        return $this->mappingKeys;
137
    }
138
139
    /**
140
     * @param null|array $mappingKeys
141
     */
142 4
    public function setMappingKeys(array $mappingKeys = null)
143
    {
144 4
        $this->mappingKeys = $mappingKeys;
145 4
    }
146
147
    /**
148
     * @param array $data
149
     *
150
     * @return bool
151
     */
152 3
    protected function isDataSequential(array $data): bool
153
    {
154 3
        if (null === $this->mappingKeys) {
155 2
            return $this->isSequential($data);
156
        }
157
158 1
        foreach ($data as $sequentialArray) {
159 1
            if (false === $this->isSequential($sequentialArray)) {
160 1
                return false;
161
            }
162
        }
163
164 1
        return true;
165
    }
166
167
    /**
168
     * @param array $data
169
     *
170
     * @return bool
171
     */
172 3
    protected function isSequential(array $data): bool
173
    {
174 3
        return array_keys($data) === range(0, count($data) - 1);
175
    }
176
}
177