Completed
Pull Request — master (#36)
by Michael
04:53
created

Fractal::collection()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

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