Completed
Pull Request — master (#20)
by Hosmel
02:35
created

Fractal::jsonSerialize()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

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