AbstractTransformer::from()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
eloc 1
dl 0
loc 3
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
crap 1
1
<?php
2
3
namespace Cerbero\Transformer;
4
5
use Illuminate\Support\Arr;
6
use InvalidArgumentException;
7
8
/**
9
 * The abstract transformer.
10
 *
11
 */
12
abstract class AbstractTransformer
13
{
14
    use CallsTransformation;
15
16
    /**
17
     * The array or object to transform.
18
     *
19
     * @param array|object
20
     */
21
    protected $data;
22
23
    /**
24
     * The object to map data into.
25
     *
26
     * @var object|null
27
     */
28
    protected $object;
29
30
    /**
31
     * The current item.
32
     *
33
     * @var array|object
34
     */
35
    protected $item;
36
37
    /**
38
     * The item being processed.
39
     *
40
     * @var array|object
41
     */
42
    protected $processingItem;
43
44
    /**
45
     * The current value.
46
     *
47
     * @var mixed
48
     */
49
    protected $value;
50
51
    /**
52
     * Retrieve the expected structure of the transformed data
53
     *
54
     * @return array
55
     */
56
    abstract protected function getStructure(): array;
57
58
    /**
59
     * Set the dependencies.
60
     *
61
     * @param array|object $data
62
     */
63 54
    public function __construct($data)
64
    {
65 54
        $this->setData($data);
66 48
    }
67
68
    /**
69
     * Set the given data and check whether it is a matrix
70
     *
71
     * @param array|object $data
72
     * @return void
73
     */
74 54
    protected function setData($data)
75
    {
76 54
        if (!is_array($data) && !is_object($data)) {
77 6
            throw new InvalidArgumentException('Only objects or arrays can be transformed.');
78
        }
79
80 48
        $this->data = $data;
81 48
    }
82
83
    /**
84
     * Create a new instance while easing method chaining
85
     *
86
     * @param array|object $data
87
     * @return self
88
     */
89 48
    public static function from($data): self
90
    {
91 48
        return new static($data);
92
    }
93
94
    /**
95
     * Transform the data into the given object
96
     *
97
     * @param object $object
98
     * @return array|object
99
     */
100 18
    public function transformInto($object)
101
    {
102 18
        if (!is_object($object)) {
103 3
            throw new InvalidArgumentException('Unable to transform data into the given value.');
104
        }
105
106 15
        $this->object = $object;
107
108 15
        return $this->transform();
109
    }
110
111
    /**
112
     * Transform the data
113
     *
114
     * @return array|object
115
     */
116 39
    public function transform()
117
    {
118 39
        $isCollection = !Arr::isAssoc((array)$this->data);
119 39
        $data = $isCollection ? $this->data : [$this->data];
120 39
        $transformedData = array_map([$this, 'transformItem'], $data);
121
122 24
        return $isCollection ? $transformedData : $transformedData[0];
123
    }
124
125
    /**
126
     * Transform the given item
127
     *
128
     * @param array|object $item
129
     * @return array|object
130
     */
131 39
    protected function transformItem($item)
132
    {
133 39
        if (!Arr::isAssoc((array)$item)) {
134 6
            throw new InvalidArgumentException('Only objects or associative arrays can be transformed.');
135
        }
136
137 33
        $this->item = $item;
138 33
        $this->processingItem = $this->object ? clone $this->object : [];
139 33
        $structure = Arr::dot($this->getStructure());
140
141 33
        foreach ($structure as $key => $rawRules) {
142 33
            $this->processItemKey($item, $key, $rawRules);
143
        }
144
145 24
        return $this->processingItem;
146
    }
147
148
    /**
149
     * Process the given key of the provided item
150
     *
151
     * @param array|object $item
152
     * @param string $key
153
     * @param string|null $rawRules
154
     * @return void
155
     */
156 33
    protected function processItemKey($item, string $key, string $rawRules = null)
157
    {
158 33
        $customKey = Arr::get($this->getKeysMap(), $key);
159 33
        $parser = new Parser($rawRules, $customKey);
160 33
        $this->value = data_get($item, $parser->parseKey());
161
162 33
        foreach ($parser->parseTransformations() as $transformation => $parameters) {
163 33
            $this->value = $this->callTransformation($transformation, $parameters);
164
        }
165
166 24
        data_set($this->processingItem, $key, $this->value);
167 24
    }
168
169
    /**
170
     * Retrieve the keys map in the format expected_key => original_key
171
     *
172
     * @return array
173
     */
174
    protected function getKeysMap(): array
175
    {
176
        return [];
177
    }
178
}
179