Completed
Pull Request — master (#36)
by Michael
06:02
created

Fractal   A

Complexity

Total Complexity 33

Size/Duplication

Total Lines 386
Duplicated Lines 2.07 %

Coupling/Cohesion

Components 1
Dependencies 3

Importance

Changes 2
Bugs 0 Features 0
Metric Value
dl 8
loc 386
rs 9.3999
c 2
b 0
f 0
wmc 33
lcom 1
cbo 3

20 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
A collection() 0 6 1
A item() 0 6 1
A data() 0 12 2
A transformWith() 0 6 1
A paginateWith() 0 6 1
A withCursor() 0 6 1
A parseIncludes() 0 8 1
A parseExcludes() 0 8 1
A normalizeExcludesOrIncludes() 0 10 2
A __call() 8 14 3
A serializeWith() 0 6 1
A addMeta() 0 10 3
A resourceName() 0 6 1
A toJson() 0 4 1
A toArray() 0 4 1
A transform() 0 6 1
B createData() 0 22 5
B getResource() 0 22 4
A jsonSerialize() 0 4 1

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
<?php
2
3
namespace Spatie\Fractal;
4
5
use JsonSerializable;
6
use League\Fractal\Manager;
7
use League\Fractal\Pagination\CursorInterface;
8
use League\Fractal\Pagination\PaginatorInterface;
9
use League\Fractal\Serializer\SerializerAbstract;
10
use Spatie\Fractal\Exceptions\InvalidTransformation;
11
use Spatie\Fractal\Exceptions\NoTransformerSpecified;
12
13
class Fractal implements JsonSerializable
14
{
15
    /**
16
     * @var \League\Fractal\Manager
17
     */
18
    protected $manager;
19
20
    /**
21
     * @var \League\Fractal\Serializer\SerializerAbstract
22
     */
23
    protected $serializer;
24
25
    /**
26
     * @var \League\Fractal\TransformerAbstract|callable
27
     */
28
    protected $transformer;
29
30
    /**
31
     * @var \League\Fractal\Pagination\PaginatorInterface
32
     */
33
    protected $paginator;
34
35
    /**
36
     * @var \League\Fractal\Pagination\CursorInterface
37
     */
38
    protected $cursor;
39
40
    /**
41
     * @var array
42
     */
43
    protected $includes = [];
44
45
	/**
46
	 * @var array
47
	 */
48
	protected $excludes = [];
49
50
    /**
51
     * @var string
52
     */
53
    protected $dataType;
54
55
    /**
56
     * @var mixed
57
     */
58
    protected $data;
59
60
    /**
61
     * @var string
62
     */
63
    protected $resourceName;
64
65
    /**
66
     * @var array
67
     */
68
    protected $meta = [];
69
70
    /**
71
     * @param \League\Fractal\Manager $manager
72
     */
73
    public function __construct(Manager $manager)
74
    {
75
        $this->manager = $manager;
76
    }
77
78
    /**
79
     * Set the collection data that must be transformed.
80
     *
81
     * @param mixed                                             $data
82
     * @param \League\Fractal\TransformerAbstract|callable|null $transformer
83
     * @param string|null                                       $resourceName
84
     *
85
     * @return $this
86
     */
87
    public function collection($data, $transformer = null, $resourceName = null)
88
    {
89
        $this->resourceName = $resourceName;
90
91
        return $this->data('collection', $data, $transformer);
92
    }
93
94
    /**
95
     * Set the item data that must be transformed.
96
     *
97
     * @param mixed                                             $data
98
     * @param \League\Fractal\TransformerAbstract|callable|null $transformer
99
     * @param string|null                                       $resourceName
100
     *
101
     * @return $this
102
     */
103
    public function item($data, $transformer = null, $resourceName = null)
104
    {
105
        $this->resourceName = $resourceName;
106
107
        return $this->data('item', $data, $transformer);
108
    }
109
110
    /**
111
     * Set the data that must be transformed.
112
     *
113
     * @param string                                            $dataType
114
     * @param mixed                                             $data
115
     * @param \League\Fractal\TransformerAbstract|callable|null $transformer
116
     *
117
     * @return $this
118
     */
119
    protected function data($dataType, $data, $transformer = null)
120
    {
121
        $this->dataType = $dataType;
122
123
        $this->data = $data;
124
125
        if (! is_null($transformer)) {
126
            $this->transformer = $transformer;
127
        }
128
129
        return $this;
130
    }
131
132
    /**
133
     * Set the class or function that will perform the transform.
134
     *
135
     * @param \League\Fractal\TransformerAbstract|callable $transformer
136
     *
137
     * @return $this
138
     */
139
    public function transformWith($transformer)
140
    {
141
        $this->transformer = $transformer;
142
143
        return $this;
144
    }
145
146
    /**
147
     * Set a Fractal paginator for the data.
148
     *
149
     * @param \League\Fractal\Pagination\PaginatorInterface $paginator
150
     *
151
     * @return $this
152
     */
153
    public function paginateWith(PaginatorInterface $paginator)
154
    {
155
        $this->paginator = $paginator;
156
157
        return $this;
158
    }
159
160
    /**
161
     * Set a Fractal cursor for the data.
162
     *
163
     * @param \League\Fractal\Pagination\CursorInterface $cursor
164
     *
165
     * @return $this
166
     */
167
    public function withCursor(CursorInterface $cursor)
168
    {
169
        $this->cursor = $cursor;
170
171
        return $this;
172
    }
173
174
    /**
175
     * Specify the includes.
176
     *
177
     * @param array|string $includes Array or csv string of resources to include
178
     *
179
     * @return $this
180
     */
181
    public function parseIncludes($includes)
182
    {
183
        $includes = $this->normalizeExcludesOrIncludes($includes);
184
185
        $this->includes = array_merge($this->includes, (array) $includes);
186
187
        return $this;
188
    }
189
190
	/**
191
	 * Specify the excludes
192
	 *
193
	 * @param $excludes
194
	 * @return $this
195
	 */
196
	public function parseExcludes($excludes)
197
    {
198
        $excludes = $this->normalizeExcludesOrIncludes($excludes);
199
200
        $this->excludes = array_merge($this->excludes, (array) $excludes);
201
202
        return $this;
203
    }
204
205
	/**
206
	 * Normalize the includes an excludes
207
	 *
208
	 * @param $includesOrExcludes
209
	 * @return array
210
	 */
211
	protected function normalizeExcludesOrIncludes($includesOrExcludes)
212
    {
213
        if (! is_string($includesOrExcludes)) {
214
            return $includesOrExcludes;
215
        }
216
217
        return array_map(function ($value) {
218
            return trim($value);
219
        }, explode(',', $includesOrExcludes));
220
    }
221
222
    /**
223
     * Support for magic methods to included data.
224
     *
225
     * @param string $name
226
     * @param array  $arguments
227
     *
228
     * @return $this
229
     */
230
    public function __call($name, array $arguments)
231
    {
232 View Code Duplication
        if (starts_with($name, ['include'])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
233
            $includeName = lcfirst(substr($name, strlen('include')));
234
            return $this->parseIncludes($includeName);
235
        }
236
237 View Code Duplication
        if (starts_with($name, ['exclude'])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
238
            $excludeName = lcfirst(substr($name, strlen('exclude')));
239
            return $this->parseExcludes($excludeName);
240
        }
241
242
        trigger_error('Call to undefined method '.__CLASS__.'::'.$name.'()', E_USER_ERROR);
243
    }
244
245
    /**
246
     * Set the serializer to be used.
247
     *
248
     * @param \League\Fractal\Serializer\SerializerAbstract $serializer
249
     *
250
     * @return $this
251
     */
252
    public function serializeWith(SerializerAbstract $serializer)
253
    {
254
        $this->serializer = $serializer;
255
256
        return $this;
257
    }
258
259
    /**
260
     * Set the meta data.
261
     *
262
     * @param $array,...
263
     *
264
     * @return $this
265
     */
266
    public function addMeta()
267
    {
268
        foreach (func_get_args() as $meta) {
269
            if (is_array($meta)) {
270
                $this->meta += $meta;
271
            }
272
        }
273
274
        return $this;
275
    }
276
277
    /**
278
     * Set the resource name, to replace 'data' as the root of the collection or item.
279
     *
280
     * @param string $resourceName
281
     *
282
     * @return $this
283
     */
284
    public function resourceName($resourceName)
285
    {
286
        $this->resourceName = $resourceName;
287
288
        return $this;
289
    }
290
291
    /**
292
     * Perform the transformation to json.
293
     *
294
     * @return string
295
     */
296
    public function toJson()
297
    {
298
        return $this->transform('toJson');
299
    }
300
301
    /**
302
     * Perform the transformation to array.
303
     *
304
     * @return array
305
     */
306
    public function toArray()
307
    {
308
        return $this->transform('toArray');
309
    }
310
311
    /**
312
     *  Perform the transformation.
313
     *
314
     * @param string $conversionMethod
315
     *
316
     * @return string|array
317
     *
318
     * @throws \Spatie\Fractal\Exceptions\InvalidTransformation
319
     * @throws \Spatie\Fractal\Exceptions\NoTransformerSpecified
320
     */
321
    protected function transform($conversionMethod)
322
    {
323
        $fractalData = $this->createData();
324
325
        return $fractalData->$conversionMethod();
326
    }
327
328
    /**
329
     * Create fractal data.
330
     *
331
     * @return \League\Fractal\Scope
332
     *
333
     * @throws \Spatie\Fractal\Exceptions\InvalidTransformation
334
     * @throws \Spatie\Fractal\Exceptions\NoTransformerSpecified
335
     */
336
    public function createData()
337
    {
338
        if (is_null($this->transformer)) {
339
            throw new NoTransformerSpecified();
340
        }
341
342
        if (! is_null($this->serializer)) {
343
            $this->manager->setSerializer($this->serializer);
344
        }
345
346
        if (! is_null($this->includes)) {
347
            $this->manager->parseIncludes($this->includes);
348
        }
349
350
        if (! is_null($this->excludes)) {
351
            $this->manager->parseExcludes($this->excludes);
352
        }
353
354
355
356
        return $this->manager->createData($this->getResource());
357
    }
358
359
    /**
360
     * Get the resource.
361
     *
362
     * @return \League\Fractal\Resource\ResourceInterface
363
     *
364
     * @throws \Spatie\Fractal\Exceptions\InvalidTransformation
365
     */
366
    public function getResource()
367
    {
368
        $resourceClass = 'League\\Fractal\\Resource\\'.ucfirst($this->dataType);
369
370
        if (! class_exists($resourceClass)) {
371
            throw new InvalidTransformation();
372
        }
373
374
        $resource = new $resourceClass($this->data, $this->transformer, $this->resourceName);
375
376
        $resource->setMeta($this->meta);
377
378
        if (! is_null($this->paginator)) {
379
            $resource->setPaginator($this->paginator);
380
        }
381
382
        if (! is_null($this->cursor)) {
383
            $resource->setCursor($this->cursor);
384
        }
385
386
        return $resource;
387
    }
388
389
    /**
390
     * Convert the object into something JSON serializable.
391
     *
392
     * @return array
393
     */
394
    public function jsonSerialize()
395
    {
396
        return $this->toArray();
397
    }
398
}
399