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 ( db16e9...2b0a92 )
by Freek
01:48
created

Fractal::limitRecursion()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

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