GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Completed
Push — master ( 2be073...609234 )
by Freek
11s
created

Fractal::parseFieldsets()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 12
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 12
rs 9.4285
c 0
b 0
f 0
cc 3
eloc 6
nc 3
nop 1
1
<?php
2
3
namespace Spatie\Fractalistic;
4
5
use Traversable;
6
use JsonSerializable;
7
use League\Fractal\Manager;
8
use League\Fractal\Pagination\CursorInterface;
9
use League\Fractal\Pagination\PaginatorInterface;
10
use League\Fractal\Serializer\SerializerAbstract;
11
use Spatie\Fractalistic\Exceptions\InvalidTransformation;
12
use Spatie\Fractalistic\Exceptions\NoTransformerSpecified;
13
14
class Fractal implements JsonSerializable
15
{
16
    /** @var \League\Fractal\Manager */
17
    protected $manager;
18
19
    /** @var int */
20
    protected $recursionLimit = 10;
21
22
    /** @var \League\Fractal\Serializer\SerializerAbstract */
23
    protected $serializer;
24
25
    /** @var \League\Fractal\TransformerAbstract|callable */
26
    protected $transformer;
27
28
    /** @var \League\Fractal\Pagination\PaginatorInterface */
29
    protected $paginator;
30
31
    /** @var \League\Fractal\Pagination\CursorInterface */
32
    protected $cursor;
33
34
    /** @var array */
35
    protected $includes = [];
36
37
    /** @var array */
38
    protected $excludes = [];
39
40
    /** @var array */
41
    protected $fieldsets = [];
42
43
    /** @var string */
44
    protected $dataType;
45
46
    /** @var mixed */
47
    protected $data;
48
49
    /** @var string */
50
    protected $resourceName;
51
52
    /** @var array */
53
    protected $meta = [];
54
55
    /**
56
     * @param null|mixed $data
57
     * @param null|callable|\League\Fractal\TransformerAbstract $transformer
58
     * @param null|\League\Fractal\Serializer\SerializerAbstract $serializer
59
     *
60
     * @return \Spatie\Fractalistic\Fractal
61
     */
62
    public static function create($data = null, $transformer = null, $serializer = null)
63
    {
64
        $instance = new static(new Manager());
65
66
        $instance->data = $data ?: null;
67
        $instance->dataType = $data ? $instance->determineDataType($data) : null;
68
        $instance->transformer = $transformer ?: null;
69
        $instance->serializer = $serializer ?: null;
70
71
        return $instance;
72
    }
73
74
    /** @param \League\Fractal\Manager $manager */
75
    public function __construct(Manager $manager)
76
    {
77
        $this->manager = $manager;
78
    }
79
80
    /**
81
     * Set the collection data that must be transformed.
82
     *
83
     * @param mixed                                             $data
84
     * @param \League\Fractal\TransformerAbstract|callable|null $transformer
85
     * @param string|null                                       $resourceName
86
     *
87
     * @return $this
88
     */
89
    public function collection($data, $transformer = null, $resourceName = null)
90
    {
91
        $this->resourceName = $resourceName;
92
93
        return $this->data('collection', $data, $transformer);
94
    }
95
96
    /**
97
     * Set the item data that must be transformed.
98
     *
99
     * @param mixed                                             $data
100
     * @param \League\Fractal\TransformerAbstract|callable|null $transformer
101
     * @param string|null                                       $resourceName
102
     *
103
     * @return $this
104
     */
105
    public function item($data, $transformer = null, $resourceName = null)
106
    {
107
        $this->resourceName = $resourceName;
108
109
        return $this->data('item', $data, $transformer);
110
    }
111
112
    /**
113
     * Set the data that must be transformed.
114
     *
115
     * @param string                                            $dataType
116
     * @param mixed                                             $data
117
     * @param \League\Fractal\TransformerAbstract|callable|null $transformer
118
     *
119
     * @return $this
120
     */
121
    public function data($dataType, $data, $transformer = null)
122
    {
123
        $this->dataType = $dataType;
124
125
        $this->data = $data;
126
127
        if (! is_null($transformer)) {
128
            $this->transformer = $transformer;
129
        }
130
131
        return $this;
132
    }
133
134
    /**
135
     * @param mixed $data
136
     *
137
     * @return string
138
     */
139
    protected function determineDataType($data)
140
    {
141
        if (is_array($data)) {
142
            return 'collection';
143
        }
144
145
        if ($data instanceof Traversable) {
146
            return 'collection';
147
        }
148
149
        return 'item';
150
    }
151
152
    /**
153
     * Set the class or function that will perform the transform.
154
     *
155
     * @param \League\Fractal\TransformerAbstract|callable $transformer
156
     *
157
     * @return $this
158
     */
159
    public function transformWith($transformer)
160
    {
161
        if (is_string($transformer) && class_exists($transformer)) {
162
            $transformer = new $transformer;
163
        }
164
165
        $this->transformer = $transformer;
166
167
        return $this;
168
    }
169
170
    /**
171
     * Set the serializer to be used.
172
     *
173
     * @param \League\Fractal\Serializer\SerializerAbstract $serializer
174
     *
175
     * @return $this
176
     */
177
    public function serializeWith(SerializerAbstract $serializer)
178
    {
179
        $this->serializer = $serializer;
180
181
        return $this;
182
    }
183
184
    /**
185
     * Set a Fractal paginator for the data.
186
     *
187
     * @param \League\Fractal\Pagination\PaginatorInterface $paginator
188
     *
189
     * @return $this
190
     */
191
    public function paginateWith(PaginatorInterface $paginator)
192
    {
193
        $this->paginator = $paginator;
194
195
        return $this;
196
    }
197
198
    /**
199
     * Set a Fractal cursor for the data.
200
     *
201
     * @param \League\Fractal\Pagination\CursorInterface $cursor
202
     *
203
     * @return $this
204
     */
205
    public function withCursor(CursorInterface $cursor)
206
    {
207
        $this->cursor = $cursor;
208
209
        return $this;
210
    }
211
212
    /**
213
     * Specify the includes.
214
     *
215
     * @param array|string $includes Array or string of resources to include.
216
     *
217
     * @return $this
218
     */
219
    public function parseIncludes($includes)
220
    {
221
        $includes = $this->normalizeIncludesOrExcludes($includes);
222
223
        $this->includes = array_merge($this->includes, (array) $includes);
224
225
        return $this;
226
    }
227
228
    /**
229
     * Specify the excludes.
230
     *
231
     * @param array|string $excludes Array or string of resources to exclude.
232
     * @return $this
233
     */
234
    public function parseExcludes($excludes)
235
    {
236
        $excludes = $this->normalizeIncludesOrExcludes($excludes);
237
238
        $this->excludes = array_merge($this->excludes, (array) $excludes);
239
240
        return $this;
241
    }
242
243
    /**
244
     * Specify the fieldsets to include in the response.
245
     *
246
     * @param array $fieldsets array with key = resourceName and value = fields to include
247
     *                                (array or comma separated string with field names)
248
     *
249
     * @return $this
250
     */
251
    public function parseFieldsets(array $fieldsets)
252
    {
253
        foreach ($fieldsets as $key => $fields) {
254
            if (is_array($fields)) {
255
                $fieldsets[$key] = implode(',', $fields);
256
            }
257
        }
258
259
        $this->fieldsets = array_merge($this->fieldsets, $fieldsets);
260
261
        return $this;
262
    }
263
264
    /**
265
     * Normalize the includes an excludes.
266
     *
267
     * @param array|string $includesOrExcludes
268
     *
269
     * @return array|string
270
     */
271
    protected function normalizeIncludesOrExcludes($includesOrExcludes = '')
272
    {
273
        if (! is_string($includesOrExcludes)) {
274
            return $includesOrExcludes;
275
        }
276
277
        return array_map(function ($value) {
278
            return trim($value);
279
        }, explode(',', $includesOrExcludes));
280
    }
281
282
    /**
283
     * Set the meta data.
284
     *
285
     * @param $array,...
286
     *
287
     * @return $this
288
     */
289
    public function addMeta()
290
    {
291
        foreach (func_get_args() as $meta) {
292
            if (is_array($meta)) {
293
                $this->meta += $meta;
294
            }
295
        }
296
297
        return $this;
298
    }
299
300
    /**
301
     * Set the resource name, to replace 'data' as the root of the collection or item.
302
     *
303
     * @param string $resourceName
304
     *
305
     * @return $this
306
     */
307
    public function withResourceName($resourceName)
308
    {
309
        $this->resourceName = $resourceName;
310
311
        return $this;
312
    }
313
314
    /**
315
     * Upper limit to how many levels of included data are allowed.
316
     *
317
     * @param int $recursionLimit
318
     *
319
     * @return $this
320
     */
321
    public function limitRecursion(int $recursionLimit)
322
    {
323
        $this->recursionLimit = $recursionLimit;
324
325
        return $this;
326
    }
327
328
    /**
329
     * Perform the transformation to json.
330
     *
331
     * @return string
332
     */
333
    public function toJson()
334
    {
335
        return $this->createData()->toJson();
336
    }
337
338
    /**
339
     * Perform the transformation to array.
340
     *
341
     * @return array
342
     */
343
    public function toArray()
344
    {
345
        return $this->createData()->toArray();
346
    }
347
348
    /**
349
     * Create fractal data.
350
     *
351
     * @return \League\Fractal\Scope
352
     *
353
     * @throws \Spatie\Fractalistic\Exceptions\InvalidTransformation
354
     * @throws \Spatie\Fractalistic\Exceptions\NoTransformerSpecified
355
     */
356
    public function createData()
357
    {
358
        if (is_null($this->transformer)) {
359
            throw new NoTransformerSpecified();
360
        }
361
362
        if (! is_null($this->serializer)) {
363
            $this->manager->setSerializer($this->serializer);
364
        }
365
366
        $this->manager->setRecursionLimit($this->recursionLimit);
367
368
        if (! empty($this->includes)) {
369
            $this->manager->parseIncludes($this->includes);
370
        }
371
372
        if (! empty($this->excludes)) {
373
            $this->manager->parseExcludes($this->excludes);
374
        }
375
376
        if (! empty($this->fieldsets)) {
377
            $this->manager->parseFieldsets($this->fieldsets);
378
        }
379
380
        return $this->manager->createData($this->getResource());
381
    }
382
383
    /**
384
     * Get the resource.
385
     *
386
     * @return \League\Fractal\Resource\ResourceInterface
387
     *
388
     * @throws \Spatie\Fractalistic\Exceptions\InvalidTransformation
389
     */
390
    public function getResource()
391
    {
392
        $resourceClass = 'League\\Fractal\\Resource\\'.ucfirst($this->dataType);
393
394
        if (! class_exists($resourceClass)) {
395
            throw new InvalidTransformation();
396
        }
397
398
        $resource = new $resourceClass($this->data, $this->transformer, $this->resourceName);
399
400
        $resource->setMeta($this->meta);
401
402
        if (! is_null($this->paginator)) {
403
            $resource->setPaginator($this->paginator);
404
        }
405
406
        if (! is_null($this->cursor)) {
407
            $resource->setCursor($this->cursor);
408
        }
409
410
        return $resource;
411
    }
412
413
    /**
414
     * Convert the object into something JSON serializable.
415
     */
416
    public function jsonSerialize()
417
    {
418
        return $this->toArray();
419
    }
420
421
    /**
422
     * Support for magic methods to included data.
423
     *
424
     * @param string $name
425
     * @param array  $arguments
426
     *
427
     * @return $this
428
     */
429
    public function __call($name, array $arguments)
430
    {
431 View Code Duplication
        if ($this->startsWith($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...
432
            $includeName = lcfirst(substr($name, strlen('include')));
433
434
            return $this->parseIncludes($includeName);
435
        }
436
437 View Code Duplication
        if ($this->startsWith($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...
438
            $excludeName = lcfirst(substr($name, strlen('exclude')));
439
440
            return $this->parseExcludes($excludeName);
441
        }
442
443
        trigger_error('Call to undefined method '.__CLASS__.'::'.$name.'()', E_USER_ERROR);
444
    }
445
446
    /**
447
     * Determine if a given string starts with a given substring.
448
     *
449
     * @param  string  $haystack
450
     * @param  string|array  $needles
451
     * @return bool
452
     */
453
    protected function startsWith($haystack, $needles)
454
    {
455
        foreach ((array) $needles as $needle) {
456
            if ($needle != '' && substr($haystack, 0, strlen($needle)) === (string) $needle) {
457
                return true;
458
            }
459
        }
460
461
        return false;
462
    }
463
}
464