Completed
Push — master ( 3a0813...c59800 )
by Taosikai
13:19
created

CursorBasedPagination::getPrevPageInfo()   A

Complexity

Conditions 1
Paths 1

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 1
nc 1
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['page_info'] = $pageInfo;
55
        }
56
        $data = $client->get($this->resource, $query);
57
58
        $this->links = $this->extractHeaderLink($client->getLastResponse());
59
        return $this->manager->createMany(reset($data));
60
    }
61
62
    protected function extractHeaderLink(ResponseInterface $response)
63
    {
64
        if (!$response->hasHeader('Link')) {
65
            return [];
66
        }
67
        $links = [
68
            'next' => null,
69
            'previous' => null,
70
        ];
71
        foreach (array_keys($links) as $type) {
72
            $matched = preg_match(
73
                str_replace('{type}', $type, static::LINK_REGEX),
74
                $response->getHeader('Link')[0],
75
                $matches
76
            );
77
            if ($matched) {
78
                $links[$type] = $matches[2];
79
            }
80
        }
81
82
        return $links;
83
    }
84
85
    /**
86
     * Get the next page of data.
87
     *
88
     * @return ModelInterface[]
89
     */
90
    public function next()
91
    {
92
        if (!$this->hasNext()) {
93
            throw new RuntimeException("There's no next page");
94
        }
95
96
        return $this->current($this->links['next']);
97
    }
98
99
    /**
100
     * Checks whether has next page.
101
     *
102
     * @return bool
103
     */
104
    public function hasNext()
105
    {
106
        return !empty($this->links['next']);
107
    }
108
109
    /**
110
     * Gets the next page info.
111
     *
112
     * @return string|null
113
     */
114
    public function getNextPageInfo()
115
    {
116
        return $this->links['next'];
117
    }
118
119
    /**
120
     * Get the previous page of data.
121
     *
122
     * @return ModelInterface[]
123
     */
124
    public function prev()
125
    {
126
        if (!$this->hasPrev()) {
127
            throw new RuntimeException("There's no previous page");
128
        }
129
130
        return $this->current($this->links['previous']);
131
    }
132
133
    /**
134
     * Checks whether has previous page.
135
     *
136
     * @return bool
137
     */
138
    public function hasPrev()
139
    {
140
        return !empty($this->links['previous']);
141
    }
142
143
    /**
144
     * Gets the previous page info.
145
     *
146
     * @return string|null
147
     */
148
    public function getPrevPageInfo()
149
    {
150
        return $this->links['previous'];
151
    }
152
}