AbstractTransformer::collection()   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
dl 0
loc 3
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 1
eloc 1
nc 1
nop 3
crap 1
1
<?php
2
3
namespace Rexlabs\Smokescreen\Transformer;
4
5
use Rexlabs\Smokescreen\Exception\ParseDefinitionException;
6
use Rexlabs\Smokescreen\Helpers\StrHelper;
7
use Rexlabs\Smokescreen\Resource\Collection;
8
use Rexlabs\Smokescreen\Resource\Item;
9
use Rexlabs\Smokescreen\Transformer\Props\DeclarativeProps;
10
11
class AbstractTransformer implements TransformerInterface
12
{
13
    use DeclarativeProps;
14
15
//    protected $autoIncludes = true;
16
17
    /** @var array The list of available includes */
18
    protected $includes = [];
19
20
    /** @var array The default properties to return (if blank, all props from transform() are returned) */
21
    protected $defaultProps = [];
22
23
    /** @var null|array The $includes property is processed and turned into a map */
24
    protected $cachedIncludeMap;
25
26
//    protected $scope;
27
28
    /**
29
     * {@inheritdoc}
30
     *
31
     * @throws ParseDefinitionException
32
     */
33 10
    public function getAvailableIncludes(): array
34
    {
35 10
        return array_keys($this->getIncludeMap());
36
    }
37
38
    /**
39
     * Return a cached version of the include map.
40
     *
41
     * @see AbstractTransformer::getIncludeMap()
42
     *
43
     * @throws ParseDefinitionException
44
     *
45
     * @return array
46
     */
47 13
    public function getIncludeMap(): array
48
    {
49 13
        if ($this->cachedIncludeMap === null) {
50 13
            $this->cachedIncludeMap = $this->getRawIncludeMap();
51
        }
52
53 12
        return $this->cachedIncludeMap;
54
    }
55
56
    /**
57
     * Process the $includes property and convert the directives into a map
58
     * indexed by the include key, and specifying: default, relation, method.
59
     *
60
     * @throws ParseDefinitionException
61
     *
62
     * @return array
63
     */
64 13
    protected function getRawIncludeMap(): array
65
    {
66 13
        $map = [];
67
68 13
        foreach ($this->includes as $includeKey => $definition) {
69 12
            if (\is_int($includeKey)) {
70 8
                $includeKey = $definition;
71 8
                $definition = null;
72
            }
73
74 12
            $settings = [];
75 12
            if (!empty($definition)) {
76 9
                $parts = preg_split('/\s*\|\s*/', $definition);
77 9
                foreach ($parts as $part) {
78 9
                    if (!preg_match('/^([^:]+)(:(.+))?$/', $part, $match)) {
79 1
                        throw new ParseDefinitionException("Unable to parse field definition for '{$includeKey}''");
80
                    }
81
                    // If only list() was viable ...
82 8
                    $directive = $match[1];
83 8
                    $val = $match[3] ?? null;
84
                    switch ($directive) {
85 8
                        case 'default':
86 2
                            $settings['default'] = true;
87 2
                            break;
88 7
                        case 'relation':
89 3
                            $settings['relation'] = !empty($val) ?
90 3
                                explode(',', $val) : [$includeKey];
91 3
                            break;
92 4
                        case 'method':
93 2
                            if (!empty($val)) {
94 2
                                $settings['method'] = $val;
95
                            }
96 2
                            break;
97 3
                        case 'item':
98 1
                            $settings['resource_type'] = 'item';
99 1
                            break;
100 3
                        case 'collection':
101 3
                            $settings['resource_type'] = 'collection';
102 3
                            break;
103
                        default:
104
                            throw new ParseDefinitionException("Invalid key '{$directive}' for {$includeKey}");
105
                    }
106
                }
107
            }
108
109 12
            if (!isset($settings['relation'])) {
110 10
                $settings['relation'] = [];
111
            }
112 12
            if (!isset($settings['method'])) {
113 11
                $settings['method'] = 'include'.StrHelper::studlyCase($includeKey);
114
            }
115 12
            if (!isset($settings['default'])) {
116 12
                $settings['default'] = false;
117
            }
118 12
            if (!isset($settings['resource_type'])) {
119 12
                $settings['resource_type'] = null;
120
            }
121
122 12
            $map[$includeKey] = $settings;
123
        }
124
125 12
        return $map;
126
    }
127
128
    /**
129
     * {@inheritdoc}
130
     *
131
     * @throws ParseDefinitionException
132
     */
133 3
    public function getDefaultIncludes(): array
134
    {
135 3
        return array_values(array_filter(array_keys($this->getIncludeMap()), function ($includeKey) {
136 1
            return $this->getIncludeMap()[$includeKey]['default'];
137 3
        }));
138
    }
139
140
    /**
141
     * {@inheritdoc}
142
     *
143
     * @throws ParseDefinitionException
144
     */
145 1
    public function getRelationships(): array
146
    {
147 1
        return array_column(
148 1
            array_filter(array_map(function ($includeKey, $settings) {
149 1
                return $settings['relation'] ? [$includeKey, $settings['relation']] : null;
150 1
            }, array_keys($this->getIncludeMap()), array_values($this->getIncludeMap()))),
151 1
            1, 0
152 1
        );
153
    }
154
155
    /**
156
     * {@inheritdoc}
157
     */
158 7
    public function getDefaultProps(): array
159
    {
160 7
        return $this->defaultProps;
161
    }
162
163
//    /**
164
//     * @inheritdoc
165
//     */
166
//    public function getScope(): Scope
167
//    {
168
//        return $this->scope;
169
//    }
170
171
    /**
172
     * Create a new Item resource.
173
     *
174
     * @param mixed       $data
175
     * @param mixed|null  $transformer
176
     * @param string|null $resourceKey
177
     *
178
     * @return Item
179
     */
180 1
    public function item($data, $transformer = null, $resourceKey = null): Item
181
    {
182 1
        return new Item($data, $transformer, $resourceKey);
183
    }
184
185
    /**
186
     * Create new Collection resource.
187
     *
188
     * @param mixed       $data
189
     * @param mixed|null  $transformer
190
     * @param string|null $resourceKey
191
     *
192
     * @return Collection
193
     */
194 1
    public function collection($data, $transformer = null, $resourceKey = null): Collection
195
    {
196 1
        return new Collection($data, $transformer, $resourceKey);
197
    }
198
199
    /**
200
     * @param $data
201
     *
202
     * @throws \InvalidArgumentException
203
     *
204
     * @return array
205
     */
206 7
    public function getTransformedData($data): array
207
    {
208 7
        if (method_exists($this, 'transform')) {
209
            // Transformer provides a 'transform' method
210 7
            return (array) $this->transform($data);
211
        }
212
213
        // Otherwise, use the withProps method which calls getProps()
214
        return $this->withProps($data, $this->getProps());
215
    }
216
}
217