Completed
Push — master ( ee4e95...909957 )
by Mads
10s
created

ApiTransformer::transformPaginatedOutput()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 3
nc 1
nop 1
dl 0
loc 7
ccs 4
cts 4
cp 1
crap 1
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
namespace Napp\Core\Api\Transformers;
4
5
use Illuminate\Contracts\Support\Arrayable;
6
use Illuminate\Database\Eloquent\Model;
7
use Illuminate\Pagination\LengthAwarePaginator;
8
use Illuminate\Pagination\Paginator;
9
use Illuminate\Support\Collection;
10
11
class ApiTransformer implements TransformerInterface
12
{
13
    /**
14
     * @var array
15
     */
16
    protected $apiMapping = [];
17
18
    /**
19
     * Strict mode removes keys that are
20
     * not specified in api mapping array.
21
     *
22
     * @var bool
23
     */
24
    protected $strict = false;
25
26
    /**
27
     * @param array|Model $apiMapping
28
     * @return void
29
     */
30 14
    public function setApiMapping($apiMapping)
31
    {
32 14
        $this->apiMapping = [];
33
34 14
        if (true === $apiMapping instanceof Model && true === property_exists($apiMapping, 'apiMapping')) {
35
            $this->apiMapping = $apiMapping->apiMapping;
36 14
        } elseif (true === \is_array($apiMapping)) {
37 14
            $this->apiMapping = $apiMapping;
38
        }
39 14
    }
40
41
    /**
42
     * @param array|Arrayable $data
43
     * @return array
44
     */
45 8
    public function transformInput($data): array
46
    {
47 8
        $input = [];
48
49 8
        $data = (true === \is_array($data)) ? $data : $data->toArray();
50 8
        foreach ($data as $key => $value) {
51 4
            $input[$this->findOriginalKey($key)] = $value;
52
        }
53
54 8
        return $input;
55
    }
56
57
    /**
58
     * @param array|Arrayable $data
59
     * @return array
60
     */
61 12
    public function transformOutput($data): array
62
    {
63 12
        $output = [];
64
65 12
        if (true === $data instanceof LengthAwarePaginator || true === $data instanceof Paginator) {
66 4
            return $this->transformPaginatedOutput($data);
67
        }
68
69 12
        if (true === $data instanceof Collection) {
70 8
            foreach ($data as $item) {
71 8
                $output[] = $this->transformOutput($item);
72
            }
73
        } else {
74 12
            $data = (true === \is_array($data)) ? $data : $data->toArray();
75 12
            foreach ($data as $key => $value) {
76 12
                if (true === $this->strict && false === array_key_exists($key, $this->apiMapping)) {
77 4
                    continue;
78
                }
79 12
                $output[$this->findNewKey($key)] = $this->convertValueType($key, $value);
80
            }
81
        }
82
83 12
        return $output;
84
    }
85
86 4
    protected function transformPaginatedOutput($data): array
87
    {
88 4
        $result = $data->toArray();
89
90 4
        $result['data'] = $this->transformOutput($data->getCollection());
91
92 4
        return $result;
93
    }
94
95
    /**
96
     * @param string $newKey
97
     * @return string
98
     */
99 4
    protected function findOriginalKey(string $newKey)
100
    {
101 4
        foreach ($this->apiMapping as $key => $value) {
102 2
            if (true === \in_array($newKey, $value)) {
103 2
                return $key;
104
            }
105
        }
106
107 4
        return $newKey;
108
    }
109
110
    /**
111
     * @param string $originalKey
112
     * @return string
113
     */
114 12
    protected function findNewKey(string $originalKey): string
115
    {
116 12
        if (true === array_key_exists($originalKey, $this->apiMapping)) {
117 12
            return $this->apiMapping[$originalKey]['newName'];
118
        }
119
120 4
        return $originalKey;
121
    }
122
123
    /**
124
     * @param string $key
125
     * @param mixed $value
126
     * @return mixed
127
     */
128 12
    protected function convertValueType(string $key, $value)
129
    {
130 12
        $type = (true === array_key_exists($key, $this->apiMapping))
131 12
            ? $this->apiMapping[$key]['dataType']
132 12
            : 'string';
133
134
        switch ($type) {
135 12
            case 'datetime':
136
                return strtotime($value) > 0 ? date("c", strtotime($value)) : '';
137 12
            case 'int':
138 12
                return (int) $value;
139 12
            case 'bool':
140 8
                return (bool) $value;
141 12
            case 'array':
142
                return (array) $value;
143 12
            case 'json':
144
                return json_decode($value);
145
            default:
146 12
                return $value;
147
        }
148
    }
149
}
150