Completed
Pull Request — master (#119)
by Toby
65:37 queued 63:37
created

PaginationLinksTrait::setPaginationLink()   D

Complexity

Conditions 9
Paths 24

Size

Total Lines 32
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 23
CRAP Score 9

Importance

Changes 0
Metric Value
dl 0
loc 32
ccs 23
cts 23
cp 1
rs 4.909
c 0
b 0
f 0
cc 9
eloc 18
nc 24
nop 5
crap 9
1
<?php
2
3
/*
4
 * This file is part of JSON-API.
5
 *
6
 * (c) Toby Zerner <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Tobscure\JsonApi;
13
14
trait PaginationLinksTrait
15
{
16
    abstract public function setLink($key, $value);
0 ignored issues
show
Documentation introduced by
For interfaces and abstract methods it is generally a good practice to add a @return annotation even if it is just @return void or @return null, so that implementors know what to do in the overridden method.

For interface and abstract methods, it is impossible to infer the return type from the immediate code. In these cases, it is generally advisible to explicitly annotate these methods with a @return doc comment to communicate to implementors of these methods what they are expected to return.

Loading history...
17
18
    abstract public function removeLink($key);
0 ignored issues
show
Documentation introduced by
For interfaces and abstract methods it is generally a good practice to add a @return annotation even if it is just @return void or @return null, so that implementors know what to do in the overridden method.

For interface and abstract methods, it is impossible to infer the return type from the immediate code. In these cases, it is generally advisible to explicitly annotate these methods with a @return doc comment to communicate to implementors of these methods what they are expected to return.

Loading history...
19
20
    /**
21
     * Set pagination links (first, prev, next, and last).
22
     *
23
     * @param string $url The base URL for pagination links.
24
     * @param array $queryParams The query params provided in the request.
25
     * @param int $offset The current offset.
26
     * @param int $limit The current limit.
27
     * @param int|null $total The total number of results, or null if unknown.
28
     */
29 3
    public function setPaginationLinks($url, array $queryParams, $offset, $limit, $total = null)
30
    {
31 3
        if (isset($queryParams['page']['number'])) {
32 3
            $offset = floor($offset / $limit) * $limit;
33 3
        }
34
35 3
        $this->setPaginationLink('first', $url, $queryParams, 0, $limit);
36
37 3
        $this->removeLink('prev');
38 3
        $this->removeLink('next');
39 3
        $this->removeLink('last');
40
41 3
        if ($offset > 0) {
42 3
            $this->setPaginationLink('prev', $url, $queryParams, max(0, $offset - $limit), $limit);
43 3
        }
44
45 3
        if ($total === null || $offset + $limit < $total) {
46 3
            $this->setPaginationLink('next', $url, $queryParams, $offset + $limit, $limit);
47 3
        }
48
49 3
        if ($total) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $total of type null|integer is loosely compared to true; this is ambiguous if the integer can be zero. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
50 3
            $this->setPaginationLink('last', $url, $queryParams, floor(($total - 1) / $limit) * $limit, $limit);
51 3
        }
52 3
    }
53
54
    /**
55
     * Set a pagination link.
56
     *
57
     * @param string $name The name of the link.
58
     * @param string $url The base URL for pagination links.
59
     * @param array $queryParams The query params provided in the request.
60
     * @param int $offset The offset to link to.
61
     * @param int $limit The current limit.
62
     */
63 3
    private function setPaginationLink($name, $url, array $queryParams, $offset, $limit)
64
    {
65 3
        if (! isset($queryParams['page']) || ! is_array($queryParams['page'])) {
66 3
            $queryParams['page'] = [];
67 3
        }
68
69 3
        $page = &$queryParams['page'];
70
71 3
        if (isset($page['number'])) {
72 3
            $page['number'] = floor($offset / $limit) + 1;
73
74 3
            if ($page['number'] <= 1) {
75 3
                unset($page['number']);
76 3
            }
77 3
        } else {
78 3
            $page['offset'] = $offset;
79
80 3
            if ($page['offset'] <= 0) {
81 3
                unset($page['offset']);
82 3
            }
83
        }
84
85 3
        if (isset($page['limit'])) {
86 3
            $page['limit'] = $limit;
87 3
        } elseif (isset($page['size'])) {
88 3
            $page['size'] = $limit;
89 3
        }
90
91 3
        $queryString = http_build_query($queryParams);
92
93 3
        $this->setLink($name, $url.($queryString ? '?'.$queryString : ''));
94 3
    }
95
}
96