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 ( 453307...4c295e )
by Freek
8s
created

Fractal::create()   B

Complexity

Conditions 5
Paths 16

Size

Total Lines 11
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

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