Passed
Push — 1.0.0-alpha ( 4639cc...268be3 )
by Alex
22:49 queued 12:54
created

formatPaginationQueryString()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 13
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 13
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 7
nc 2
nop 3
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
        $this->addLinks(array_map(function ($page) use ($paginator) {
105
            return $this->formatPaginationQueryString(Request::query(), $page, $paginator->perPage());
106
        }, array_filter([
107
            'first' => 1,
108
            'last' => $paginator->lastPage(),
109
            'prev' => $paginator->currentPage() > 1 ? $paginator->currentPage() - 1 : null,
110
            'next' => $paginator->currentPage() < $paginator->lastPage() ? $paginator->currentPage() + 1 : null,
111
        ])));
112
    }
113
114
    /**
115
     * Add JSON API pagination parameters to request query set based on
116
     * selected pagination strategy, and return the built URL query string.
117
     *
118
     * @param array $query
119
     * @param int   $number
120
     * @param int   $size
121
     */
122
    protected function formatPaginationQueryString(array $query = [], int $number, int $size): string
123
    {
124
        if (config('jsonapi.pagination_method') === 'offset-based') {
125
            $query['page'] = [
126
                'offset' => ($number - 1) * $size,
127
                'limit' => $size,
128
            ];
129
        }
130
131
        $query['page'] = compact('number', 'size');
132
133
        return '?' . urldecode(http_build_query($query));
134
    }
135
}
136