Completed
Pull Request — master (#9)
by Jodie
02:26
created

AbstractTransformer::getDefaultIncludes()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 0
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 8
    public function getAvailableIncludes(): array
34
    {
35 8
        return array_keys($this->getCachedIncludeMap());
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 9
    protected function getCachedIncludeMap(): array
48
    {
49 9
        if ($this->cachedIncludeMap === null) {
50 9
            $this->cachedIncludeMap = $this->getIncludeMap();
51
        }
52
53 9
        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 10
    public function getIncludeMap(): array
65
    {
66 10
        $map = [];
67
68 10
        foreach ($this->includes as $includeKey => $definition) {
69 9
            if (\is_int($includeKey)) {
70 5
                $includeKey = $definition;
71 5
                $definition = null;
72
            }
73
74 9
            $settings = [];
75 9
            if (!empty($definition)) {
76 6
                $parts = preg_split('/\s*\|\s*/', $definition);
77 6
                foreach ($parts as $part) {
78 6
                    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 5
                    $directive = $match[1];
83 5
                    $val = $match[3] ?? null;
84
                    switch ($directive) {
85 5
                        case 'default':
86 1
                            $settings['default'] = true;
87 1
                            break;
88 4
                        case 'relation':
89 2
                            $settings['relation'] = !empty($val) ?
90 2
                                preg_split('/s*,\s*/', $val) : [$includeKey];
91 2
                            break;
92 2
                        case 'method':
93 2
                            if (!empty($val)) {
94 2
                                $settings['method'] = $val;
95
                            }
96 2
                            break;
97
                        default:
98 5
                            throw new ParseDefinitionException("Invalid key '{$directive}' for {$includeKey}");
99
                    }
100
                }
101
            }
102
103 9
            if (!isset($settings['relation'])) {
104 7
                $settings['relation'] = [];
105
            }
106 9
            if (!isset($settings['method'])) {
107 7
                $settings['method'] = 'include'.StrHelper::studlyCase($includeKey);
108
            }
109 9
            if (!isset($settings['default'])) {
110 9
                $settings['default'] = false;
111
            }
112
113 9
            $map[$includeKey] = $settings;
114
        }
115
116 9
        return $map;
117
    }
118
119
    /**
120
     * {@inheritdoc}
121
     *
122
     * @throws ParseDefinitionException
123
     */
124
    public function getDefaultIncludes(): array
125
    {
126 4
        return array_values(array_filter(array_keys($this->getCachedIncludeMap()), function ($includeKey) {
127 2
            return $this->getCachedIncludeMap()[$includeKey]['default'];
128 4
        }));
129
    }
130
131
    /**
132
     * {@inheritdoc}
133
     *
134
     * @throws ParseDefinitionException
135
     */
136 1
    public function getRelationships(): array
137
    {
138 1
        return array_column(
139 1
            array_filter(array_map(function ($includeKey, $settings) {
140 1
                return $settings['relation'] ? [$includeKey, $settings['relation']] : null;
141 1
            }, array_keys($this->getCachedIncludeMap()), array_values($this->getCachedIncludeMap()))),
142 1
            1, 0
143
        );
144
    }
145
146
    /**
147
     * {@inheritdoc}
148
     */
149 5
    public function getDefaultProps(): array
150
    {
151 5
        return $this->defaultProps;
152
    }
153
154
//    /**
155
//     * @inheritdoc
156
//     */
157
//    public function getScope(): Scope
158
//    {
159
//        return $this->scope;
160
//    }
161
162
    /**
163
     * Create a new Item resource.
164
     *
165
     * @param mixed       $data
166
     * @param mixed|null  $transformer
167
     * @param string|null $resourceKey
168
     *
169
     * @return Item
170
     */
171 1
    public function item($data, $transformer = null, $resourceKey = null): Item
172
    {
173 1
        return new Item($data, $transformer, $resourceKey);
174
    }
175
176
    /**
177
     * Create new Collection resource.
178
     *
179
     * @param mixed       $data
180
     * @param mixed|null  $transformer
181
     * @param string|null $resourceKey
182
     *
183
     * @return Collection
184
     */
185 1
    public function collection($data, $transformer = null, $resourceKey = null): Collection
186
    {
187 1
        return new Collection($data, $transformer, $resourceKey);
188
    }
189
190
    /**
191
     * @param $data
192
     *
193
     * @return array
194
     * @throws \InvalidArgumentException
195
     */
196 5
    public function getTransformedData($data): array
197
    {
198 5
        if (method_exists($this, 'transform')) {
199
            // Transformer provides a 'transform' method
200 5
            return (array) $this->transform($data);
201
        }
202
203
        // Otherwise, use the withProps method which calls getProps()
204
        return $this->withProps($data, $this->getProps());
205
    }
206
}
207