Completed
Push — master ( 9beb61...fcf0cf )
by Jodie
03:20
created

Smokescreen::transformItem()   C

Complexity

Conditions 12
Paths 29

Size

Total Lines 76
Code Lines 35

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 35
CRAP Score 12.0228

Importance

Changes 0
Metric Value
dl 0
loc 76
ccs 35
cts 37
cp 0.9459
rs 5.2846
c 0
b 0
f 0
cc 12
eloc 35
nc 29
nop 3
crap 12.0228

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace Rexlabs\Smokescreen;
4
5
use Rexlabs\Smokescreen\Exception\MissingResourceException;
6
use Rexlabs\Smokescreen\Helpers\JsonHelper;
7
use Rexlabs\Smokescreen\Includes\IncludeParser;
8
use Rexlabs\Smokescreen\Includes\IncludeParserInterface;
9
use Rexlabs\Smokescreen\Includes\Includes;
10
use Rexlabs\Smokescreen\Relations\RelationLoaderInterface;
11
use Rexlabs\Smokescreen\Resource\Collection;
12
use Rexlabs\Smokescreen\Resource\Item;
13
use Rexlabs\Smokescreen\Resource\ResourceInterface;
14
use Rexlabs\Smokescreen\Serializer\DefaultSerializer;
15
use Rexlabs\Smokescreen\Serializer\SerializerInterface;
16
use Rexlabs\Smokescreen\Transformer\Pipeline;
17
use Rexlabs\Smokescreen\Transformer\Scope;
18
use Rexlabs\Smokescreen\Transformer\TransformerInterface;
19
use Rexlabs\Smokescreen\Transformer\TransformerResolverInterface;
20
21
/**
22
 * Smokescreen is a library for transforming and serializing data - typically RESTful API output.
23
 */
24
class Smokescreen implements \JsonSerializable
25
{
26
    /** @var ResourceInterface Item or Collection to be transformed */
27
    protected $resource;
28
29
    /** @var SerializerInterface */
30
    protected $serializer;
31
32
    /** @var IncludeParserInterface */
33
    protected $includeParser;
34
35
    /** @var RelationLoaderInterface */
36
    protected $relationLoader;
37
38
    /** @var Includes */
39
    protected $includes;
40
41
    /** @var TransformerResolverInterface */
42
    protected $transformerResolver;
43
44
    /**
45
     * Return the current resource.
46
     *
47
     * @return ResourceInterface|mixed|null
48
     */
49 6
    public function getResource()
50
    {
51 6
        return $this->resource;
52
    }
53
54
    /**
55
     * Set the resource to be transformed.
56
     *
57
     * @param ResourceInterface|mixed|null $resource
58
     *
59
     * @return $this
60
     */
61 21
    public function setResource($resource)
62
    {
63 21
        $this->resource = $resource;
64
65 21
        return $this;
66
    }
67
68
    /**
69
     * Set the resource item to be transformed.
70
     *
71
     * @param mixed                           $data
72
     * @param TransformerInterface|mixed|null $transformer
73
     * @param string|null                     $key
74
     *
75
     * @throws \Rexlabs\Smokescreen\Exception\InvalidTransformerException
76
     *
77
     * @return $this
78
     */
79 14
    public function item($data, $transformer = null, $key = null)
80
    {
81 14
        $this->setResource(new Item($data, $transformer, $key));
82
83 13
        return $this;
84
    }
85
86
    /**
87
     * Set the resource collection to be transformed.
88
     *
89
     * @param mixed                           $data
90
     * @param TransformerInterface|mixed|null $transformer
91
     * @param string|null                     $key
92
     * @param callable|null                   $callback
93
     *
94
     * @throws \Rexlabs\Smokescreen\Exception\InvalidTransformerException
95
     *
96
     * @return $this
97
     */
98 8
    public function collection($data, TransformerInterface $transformer = null, $key = null, callable $callback = null)
99
    {
100 8
        $this->setResource(new Collection($data, $transformer, $key));
101 8
        if ($callback !== null) {
102 1
            $callback($this->resource);
103
        }
104
105 8
        return $this;
106
    }
107
108
    /**
109
     * Sets the transformer to be used to transform the resource ... later.
110
     *
111
     * @throws MissingResourceException
112
     *
113
     * @return TransformerInterface|mixed|null
114
     */
115 5
    public function getTransformer()
116
    {
117 5
        if (!$this->resource) {
118 1
            throw new MissingResourceException('Resource must be specified before setting a transformer');
119
        }
120
121 4
        return $this->resource->getTransformer();
122
    }
123
124
    /**
125
     * Sets the transformer to be used to transform the resource ... later.
126
     *
127
     * @param TransformerInterface|mixed|null $transformer
128
     *
129
     * @throws MissingResourceException
130
     *
131
     * @return $this
132
     */
133 2
    public function setTransformer($transformer = null)
134
    {
135 2
        if (!$this->resource) {
136 1
            throw new MissingResourceException('Resource must be specified before setting a transformer');
137
        }
138 1
        $this->resource->setTransformer($transformer);
139
140 1
        return $this;
141
    }
142
143
    /**
144
     * Returns an object (stdClass) representation of the transformed/serialized data.
145
     *
146
     * @throws \Rexlabs\Smokescreen\Exception\InvalidSerializerException
147
     * @throws \Rexlabs\Smokescreen\Exception\UnhandledResourceType
148
     * @throws \Rexlabs\Smokescreen\Exception\MissingResourceException
149
     * @throws \Rexlabs\Smokescreen\Exception\InvalidTransformerException
150
     * @throws \Rexlabs\Smokescreen\Exception\JsonEncodeException
151
     * @throws \Rexlabs\Smokescreen\Exception\IncludeException
152
     *
153
     * @return \stdClass
154
     */
155 1
    public function toObject(): \stdClass
156
    {
157 1
        return (object) json_decode($this->toJson());
158
    }
159
160
    /**
161
     * Outputs a JSON string of the resulting transformed and serialized data.
162
     *
163
     * @param int $options
164
     *
165
     * @throws \Rexlabs\Smokescreen\Exception\InvalidSerializerException
166
     * @throws \Rexlabs\Smokescreen\Exception\UnhandledResourceType
167
     * @throws \Rexlabs\Smokescreen\Exception\MissingResourceException
168
     * @throws \Rexlabs\Smokescreen\Exception\InvalidTransformerException
169
     * @throws \Rexlabs\Smokescreen\Exception\JsonEncodeException
170
     * @throws \Rexlabs\Smokescreen\Exception\IncludeException
171
     *
172
     * @return string
173
     */
174 2
    public function toJson($options = 0): string
175
    {
176 2
        return JsonHelper::encode($this->jsonSerialize(), $options);
177
    }
178
179
    /**
180
     * Output the transformed and serialized data as an array.
181
     * Implements PHP's JsonSerializable interface.
182
     *
183
     * @throws \Rexlabs\Smokescreen\Exception\InvalidSerializerException
184
     * @throws \Rexlabs\Smokescreen\Exception\UnhandledResourceType
185
     * @throws \Rexlabs\Smokescreen\Exception\InvalidTransformerException
186
     * @throws \Rexlabs\Smokescreen\Exception\MissingResourceException
187
     * @throws \Rexlabs\Smokescreen\Exception\IncludeException
188
     *
189
     * @return array
190
     *
191
     * @see Smokescreen::toArray()
192
     */
193 2
    public function jsonSerialize(): array
194
    {
195 2
        return $this->toArray();
196
    }
197
198
    /**
199
     * Return the transformed data as an array.
200
     *
201
     * @throws \Rexlabs\Smokescreen\Exception\InvalidSerializerException
202
     * @throws \Rexlabs\Smokescreen\Exception\UnhandledResourceType
203
     * @throws \Rexlabs\Smokescreen\Exception\InvalidTransformerException
204
     * @throws \Rexlabs\Smokescreen\Exception\MissingResourceException
205
     * @throws \Rexlabs\Smokescreen\Exception\IncludeException
206
     *
207
     * @return array
208
     */
209 17
    public function toArray(): array
210
    {
211 17
        if (!$this->resource) {
212 1
            throw new MissingResourceException('No resource has been defined to transform');
213
        }
214 16
        return $this->transform();
215
    }
216
217
    /**
218
     * @return array
219
     * @throws Exception\IncludeException
220
     */
221 16
    protected function transform()
222
    {
223 16
        $scope = new Scope($this->resource, $this->getIncludes());
224 16
        $pipeline = new Pipeline();
225 16
        $pipeline->setSerializer($this->getSerializer());
226
227 16
        if (($transformerResolver = $this->getTransformerResolver()) !== null) {
228 2
            $pipeline->setTransformerResolver($transformerResolver);
229
        }
230
231 16
        if (($relationLoader = $this->getRelationLoader()) !== null) {
232 1
            $pipeline->setRelationLoader($relationLoader);
233
        }
234
        
235 16
        return $pipeline->transform($scope);
236
    }
237
238
    /**
239
     * @return SerializerInterface
240
     */
241 17
    public function getSerializer(): SerializerInterface
242
    {
243 17
        return $this->serializer ?? new DefaultSerializer();
244
    }
245
246
    /**
247
     * Set the serializer which will be used to output the transformed resource.
248
     *
249
     * @param SerializerInterface|null $serializer
250
     *
251
     * @return $this
252
     */
253 1
    public function setSerializer(SerializerInterface $serializer = null)
254
    {
255 1
        $this->serializer = $serializer;
256
257 1
        return $this;
258
    }
259
260
    /**
261
     * Get the current includes object.
262
     *
263
     * @return Includes
264
     */
265 18
    public function getIncludes(): Includes
266
    {
267 18
        return $this->includes ?? new Includes();
268
    }
269
270
    /**
271
     * Set the Includes object used for determining included resources.
272
     *
273
     * @param Includes $includes
274
     *
275
     * @return $this
276
     */
277 1
    public function setIncludes(Includes $includes)
278
    {
279 1
        $this->includes = $includes;
280
281 1
        return $this;
282
    }
283
284
    /**
285
     * Parse the given string to generate a new Includes object.
286
     *
287
     * @param string $str
288
     *
289
     * @return $this
290
     */
291 8
    public function parseIncludes($str)
292
    {
293 8
        $this->includes = $this->getIncludeParser()->parse(!empty($str) ? $str : '');
294
295 8
        return $this;
296
    }
297
298
    /**
299
     * Return the include parser object.
300
     * If not set explicitly via setIncludeParser(), it will return the default IncludeParser object.
301
     *
302
     * @return IncludeParserInterface
303
     *
304
     * @see Smokescreen::setIncludeParser()
305
     */
306 8
    public function getIncludeParser(): IncludeParserInterface
307
    {
308 8
        return $this->includeParser ?? new IncludeParser();
309
    }
310
311
    /**
312
     * Set the include parser to handle converting a string to an Includes object.
313
     *
314
     * @param IncludeParserInterface $includeParser
315
     *
316
     * @return $this
317
     */
318 1
    public function setIncludeParser(IncludeParserInterface $includeParser)
319
    {
320 1
        $this->includeParser = $includeParser;
321
322 1
        return $this;
323
    }
324
325
    /**
326
     * Get the current relation loader.
327
     *
328
     * @return RelationLoaderInterface|null
329
     */
330 16
    public function getRelationLoader()
331
    {
332 16
        return $this->relationLoader;
333
    }
334
335
    /**
336
     * Set the relationship loader.
337
     *
338
     * @param RelationLoaderInterface $relationLoader
339
     *
340
     * @return $this
341
     */
342 1
    public function setRelationLoader(RelationLoaderInterface $relationLoader)
343
    {
344 1
        $this->relationLoader = $relationLoader;
345
346 1
        return $this;
347
    }
348
349
    /**
350
     * Returns true if a RelationLoaderInterface object has been defined.
351
     *
352
     * @return bool
353
     */
354 1
    public function hasRelationLoader(): bool
355
    {
356 1
        return $this->relationLoader !== null;
357
    }
358
359
    /**
360
     * @return TransformerResolverInterface|null
361
     */
362 17
    public function getTransformerResolver()
363
    {
364 17
        return $this->transformerResolver;
365
    }
366
367
    /**
368
     * Set the transformer resolve to user.
369
     *
370
     * @param TransformerResolverInterface|null $transformerResolver
371
     *
372
     * @return $this
373
     */
374 3
    public function setTransformerResolver(TransformerResolverInterface $transformerResolver = null)
375
    {
376 3
        $this->transformerResolver = $transformerResolver;
377
378 3
        return $this;
379
    }
380
}
381