1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace Huntie\JsonApi\Serializers; |
4
|
|
|
|
5
|
|
|
use Request; |
6
|
|
|
use Illuminate\Contracts\Pagination\LengthAwarePaginator; |
7
|
|
|
|
8
|
|
|
class CollectionSerializer extends JsonApiSerializer |
9
|
|
|
{ |
10
|
|
|
/** |
11
|
|
|
* The collection of records to transform. |
12
|
|
|
* |
13
|
|
|
* @var \Illuminate\Support\Collection |
14
|
|
|
*/ |
15
|
|
|
protected $records; |
16
|
|
|
|
17
|
|
|
/** |
18
|
|
|
* The subset of attributes to return on each record type. |
19
|
|
|
* |
20
|
|
|
* @var array |
21
|
|
|
*/ |
22
|
|
|
protected $fields; |
23
|
|
|
|
24
|
|
|
/** |
25
|
|
|
* The relationships to load and include. |
26
|
|
|
* |
27
|
|
|
* @var array |
28
|
|
|
*/ |
29
|
|
|
protected $include; |
30
|
|
|
|
31
|
|
|
/** |
32
|
|
|
* Create a new JSON API collection serializer. |
33
|
|
|
* |
34
|
|
|
* @param \Illuminate\Support\Collection|LengthAwarePaginator $records The collection of records to serialize |
35
|
|
|
* @param array|null $fields Subset of fields to return by record type |
36
|
|
|
* @param array|null $include Relations to include |
37
|
|
|
*/ |
38
|
|
|
public function __construct($records, array $fields = [], array $include = []) |
39
|
|
|
{ |
40
|
|
|
parent::__construct(); |
41
|
|
|
|
42
|
|
|
if ($records instanceof LengthAwarePaginator) { |
43
|
|
|
$this->addPaginationLinks($records); |
44
|
|
|
|
45
|
|
|
$this->records = $records->getCollection(); |
46
|
|
|
} else { |
47
|
|
|
$this->records = $records; |
48
|
|
|
} |
49
|
|
|
|
50
|
|
|
$this->fields = array_unique($fields); |
51
|
|
|
$this->include = array_unique($include); |
52
|
|
|
} |
53
|
|
|
|
54
|
|
|
/** |
55
|
|
|
* Return a collection of JSON API resource objects for the record set. |
56
|
|
|
* |
57
|
|
|
* @return \Illuminate\Support\Collection |
58
|
|
|
*/ |
59
|
|
|
public function toResourceCollection() |
60
|
|
|
{ |
61
|
|
|
return $this->records->map(function ($record) { |
62
|
|
|
return (new ResourceSerializer($record, $this->fields, $this->include))->toResourceObject(); |
63
|
|
|
}); |
64
|
|
|
} |
65
|
|
|
|
66
|
|
|
/** |
67
|
|
|
* Return primary data for the JSON API document. |
68
|
|
|
* |
69
|
|
|
* @return mixed |
70
|
|
|
*/ |
71
|
|
|
protected function getPrimaryData() |
72
|
|
|
{ |
73
|
|
|
return $this->toResourceCollection()->toArray(); |
74
|
|
|
} |
75
|
|
|
|
76
|
|
|
/** |
77
|
|
|
* Return any secondary included resource objects. |
78
|
|
|
* |
79
|
|
|
* @throws \Huntie\JsonApi\Exceptions\InvalidRelationPathException |
80
|
|
|
* |
81
|
|
|
* @return \Illuminate\Support\Collection |
82
|
|
|
*/ |
83
|
|
|
public function getIncluded() |
84
|
|
|
{ |
85
|
|
|
$included = collect(); |
86
|
|
|
|
87
|
|
|
foreach ($this->records as $record) { |
88
|
|
|
$included = $included->merge( |
89
|
|
|
(new ResourceSerializer($record, $this->fields, $this->include)) |
90
|
|
|
->getIncluded() |
91
|
|
|
); |
92
|
|
|
} |
93
|
|
|
|
94
|
|
|
return $included->unique(); |
95
|
|
|
} |
96
|
|
|
|
97
|
|
|
/** |
98
|
|
|
* Add pagination links and meta information to the main document. |
99
|
|
|
* |
100
|
|
|
* @param LengthAwarePaginator $paginator |
101
|
|
|
*/ |
102
|
|
|
protected function addPaginationLinks($paginator) |
103
|
|
|
{ |
104
|
|
|
$query = array_add(Request::query(), 'page.size', $paginator->perPage()); |
|
|
|
|
105
|
|
|
|
106
|
|
|
$this->addLinks(array_map(function ($page) use ($query) { |
107
|
|
|
return '?' . urldecode(http_build_query(array_add($query, 'page.number', $page))); |
108
|
|
|
}, array_filter([ |
109
|
|
|
'first' => 1, |
110
|
|
|
'last' => $paginator->lastPage(), |
111
|
|
|
'prev' => $paginator->currentPage() > 1 ? $paginator->currentPage() - 1 : null, |
112
|
|
|
'next' => $paginator->currentPage() < $paginator->lastPage() ? $paginator->currentPage() + 1 : null, |
113
|
|
|
]))); |
114
|
|
|
|
115
|
|
|
$this->addMeta('total', $paginator->total()); |
116
|
|
|
} |
117
|
|
|
} |
118
|
|
|
|
This check looks at variables that are passed out again to other methods.
If the outgoing method call has stricter type requirements than the method itself, an issue is raised.
An additional type check may prevent trouble.