Completed
Push — 1.0.0-alpha ( c04b09...2436c2 )
by Alex
11s
created

src/Serializers/CollectionSerializer.php (1 issue)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

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 resource type.
19
     *
20
     * @var array
21
     */
22
    protected $fields;
23
24
    /**
25
     * The relationship paths to match for included resources.
26
     *
27
     * @var array
28
     */
29
    protected $include;
30
31
    /**
32
     * The additional named relationships to list against each resource.
33
     *
34
     * @var array
35
     */
36
    protected $relationships;
37
38
    /**
39
     * Create a new JSON API collection serializer.
40
     *
41
     * @param \Illuminate\Support\Collection|LengthAwarePaginator $records       The collection of records to serialise
42
     * @param array|null                                          $fields        The subset of fields to return on each resource type
0 ignored issues
show
This line exceeds maximum limit of 120 characters; contains 133 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
43
     * @param array|null                                          $include       The paths of relationships to include
44
     * @param array|null                                          $relationships Additional named relationships to list
45
     */
46
    public function __construct($records, array $fields = [], array $include = [], array $relationships = [])
47
    {
48
        parent::__construct();
49
50
        if ($records instanceof LengthAwarePaginator) {
51
            $this->addPaginationLinks($records);
52
53
            $this->records = $records->getCollection();
54
        } else {
55
            $this->records = $records;
56
        }
57
58
        $this->fields = array_unique($fields);
59
        $this->include = array_unique($include);
60
        $this->relationships = array_unique($relationships);
61
    }
62
63
    /**
64
     * Return a collection of JSON API resource objects for the record set.
65
     *
66
     * @return \Illuminate\Support\Collection
67
     */
68
    public function toResourceCollection()
69
    {
70
        return $this->records->map(function ($record) {
71
            return (new ResourceSerializer($record, $this->fields, $this->include, $this->relationships))
72
                ->toResourceObject();
73
        });
74
    }
75
76
    /**
77
     * Return primary data for the JSON API document.
78
     *
79
     * @return mixed
80
     */
81
    protected function getPrimaryData()
82
    {
83
        return $this->toResourceCollection()->toArray();
84
    }
85
86
    /**
87
     * Return any secondary included resource objects.
88
     *
89
     * @throws \Huntie\JsonApi\Exceptions\InvalidRelationPathException
90
     *
91
     * @return \Illuminate\Support\Collection
92
     */
93
    public function getIncluded()
94
    {
95
        $included = collect();
96
97
        foreach ($this->records as $record) {
98
            $included = $included->merge(
99
                (new ResourceSerializer($record, $this->fields, $this->include, $this->relationships))
100
                    ->getIncluded()
101
            );
102
        }
103
104
        return $this->filterUnique($included);
105
    }
106
107
    /**
108
     * Add pagination links and meta information to the main document.
109
     *
110
     * @param LengthAwarePaginator $paginator
111
     */
112
    protected function addPaginationLinks($paginator)
113
    {
114
        $this->addLinks(array_map(function ($page) use ($paginator) {
115
            return $this->formatPaginationQueryString(Request::query(), $page, $paginator->perPage());
116
        }, array_filter([
117
            'first' => 1,
118
            'last' => $paginator->lastPage(),
119
            'prev' => $paginator->currentPage() > 1 ? $paginator->currentPage() - 1 : null,
120
            'next' => $paginator->currentPage() < $paginator->lastPage() ? $paginator->currentPage() + 1 : null,
121
        ])));
122
123
        if (config('jsonapi.include_total_meta')) {
124
            $this->addMeta('total', $paginator->total());
125
        }
126
    }
127
128
    /**
129
     * Add JSON API pagination parameters to request query set based on
130
     * selected pagination strategy, and return the built URL query string.
131
     *
132
     * @param array $query
133
     * @param int   $number
134
     * @param int   $size
135
     */
136
    protected function formatPaginationQueryString(array $query = [], int $number, int $size): string
137
    {
138
        if (config('jsonapi.pagination_method') === 'offset-based') {
139
            $query['page'] = [
140
                'offset' => ($number - 1) * $size,
141
                'limit' => $size,
142
            ];
143
        }
144
145
        $query['page'] = compact('number', 'size');
146
147
        return '?' . urldecode(http_build_query($query));
148
    }
149
}
150