CursorBasedPagination::getNextPageInfo()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 2
nc 2
nop 0
1
<?php
2
3
namespace Slince\Shopify\Common;
4
5
use GuzzleHttp\Psr7\Request;
6
use Psr\Http\Message\ResponseInterface;
7
use Slince\Shopify\Client;
8
use Slince\Shopify\Common\Manager\ManagerInterface;
9
use Slince\Shopify\Common\Model\ModelInterface;
10
use Slince\Shopify\Exception\RuntimeException;
11
12
class CursorBasedPagination
13
{
14
    const LINK_REGEX = '/<(.*page_info=([a-z0-9\-_]+).*)>; rel="?{type}"?/i';
15
16
    /**
17
     * @var string
18
     */
19
    protected $resource;
20
21
    /**
22
     * @var array
23
     */
24
    protected $query;
25
26
    /**
27
     * @var ManagerInterface
28
     */
29
    protected $manager;
30
31
    /**
32
     * @var array
33
     */
34
    protected $links = [];
35
36
    public function __construct(ManagerInterface $manager, $resource, $query = [])
37
    {
38
        $this->manager = $manager;
39
        $this->resource = $resource;
40
        $this->query = $query;
41
    }
42
43
    /**
44
     * Gets the current page data.
45
     *
46
     * @param string $pageInfo
47
     * @return ModelInterface[]
48
     */
49
    public function current($pageInfo = null)
50
    {
51
        $client = $this->manager->getClient();
52
        $query = $this->query;
53
        if (null !== $pageInfo) {
54
            $query = array_intersect_key($query, ['limit' => true, 'fields' => true]);
55
            $query['page_info'] = $pageInfo;
56
        }
57
        $data = $client->get($this->resource, $query);
58
59
        $this->links = $this->extractHeaderLink($client->getLastResponse());
60
        return $this->manager->createMany(reset($data));
61
    }
62
63
    protected function extractHeaderLink(ResponseInterface $response)
64
    {
65
        if (!$response->hasHeader('Link')) {
66
            return [];
67
        }
68
        $links = [
69
            'next' => null,
70
            'previous' => null,
71
        ];
72
        foreach (array_keys($links) as $type) {
73
            $matched = preg_match(
74
                str_replace('{type}', $type, static::LINK_REGEX),
75
                $response->getHeader('Link')[0],
76
                $matches
77
            );
78
            if ($matched) {
79
                $links[$type] = $matches[2];
80
            }
81
        }
82
83
        return $links;
84
    }
85
86
    /**
87
     * Get the next page of data.
88
     *
89
     * @return ModelInterface[]
90
     */
91
    public function next()
92
    {
93
        if (!$this->hasNext()) {
94
            throw new RuntimeException("There's no next page");
95
        }
96
97
        return $this->current($this->links['next']);
98
    }
99
100
    /**
101
     * Checks whether has next page.
102
     *
103
     * @return bool
104
     */
105
    public function hasNext()
106
    {
107
        return !empty($this->links['next']);
108
    }
109
110
    /**
111
     * Gets the next page info.
112
     *
113
     * @return string|null
114
     */
115
    public function getNextPageInfo()
116
    {
117
        return isset($this->links['next']) ? $this->links['next'] : null;
118
    }
119
120
    /**
121
     * Get the previous page of data.
122
     *
123
     * @return ModelInterface[]
124
     */
125
    public function prev()
126
    {
127
        if (!$this->hasPrev()) {
128
            throw new RuntimeException("There's no previous page");
129
        }
130
131
        return $this->current($this->links['previous']);
132
    }
133
134
    /**
135
     * Checks whether has previous page.
136
     *
137
     * @return bool
138
     */
139
    public function hasPrev()
140
    {
141
        return !empty($this->links['previous']);
142
    }
143
144
    /**
145
     * Gets the previous page info.
146
     *
147
     * @return string|null
148
     */
149
    public function getPrevPageInfo()
150
    {
151
        return isset($this->links['previous']) ? $this->links['previous'] : null;
152
    }
153
}