Passed
Push — master ( 0deb8f...f54565 )
by Goffy
04:13
created

Paginator   A

Complexity

Total Complexity 17

Size/Duplication

Total Lines 143
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 40
dl 0
loc 143
rs 10
c 0
b 0
f 0
wmc 17

10 Methods

Rating   Name   Duplication   Size   Complexity  
A limit() 0 7 2
A load() 0 4 2
A current() 0 4 1
A __construct() 0 4 1
A rewind() 0 5 1
A key() 0 3 1
A parsePage() 0 8 2
A parseLink() 0 7 2
A next() 0 17 2
A valid() 0 3 3
1
<?php
2
3
namespace XoopsModules\Wggithub\Github;
4
5
6
/**
7
 * Iterates through the Github API responses by Link: header.
8
 *
9
 * @see https://developer.github.com/guides/traversing-with-pagination/
10
 *
11
 * @author  Miloslav Hůla (https://github.com/milo)
12
 */
13
class Paginator extends Sanity implements \Iterator
14
{
15
	/** @var Api */
16
	private $api;
17
18
	/** @var Http\Request */
19
	private $firstRequest;
20
21
	/** @var Http\Request|NULL */
22
	private $request;
23
24
	/** @var Http\Response|NULL */
25
	private $response;
26
27
	/** @var int */
28
	private $limit;
29
30
	/** @var int */
31
	private $counter = 0;
32
33
34
	public function __construct(Api $api, Http\Request $request)
35
	{
36
		$this->api = $api;
37
		$this->firstRequest = clone $request;
38
	}
39
40
41
	/**
42
	 * Limits maximum steps of iteration.
43
	 *
44
	 * @param  int|NULL
45
	 * @return self
46
	 */
47
	public function limit($limit)
48
	{
49
		$this->limit = $limit === NULL
50
			? NULL
51
			: (int) $limit;
52
53
		return $this;
54
	}
55
56
57
	/**
58
	 * @return void
59
	 */
60
	public function rewind()
61
	{
62
		$this->request = $this->firstRequest;
63
		$this->response = NULL;
64
		$this->counter = 0;
65
	}
66
67
68
	/**
69
	 * @return bool
70
	 */
71
	public function valid()
72
	{
73
		return $this->request !== NULL && ($this->limit === NULL || $this->counter < $this->limit);
74
	}
75
76
77
	/**
78
	 * @return Http\Response
79
	 */
80
	public function current()
81
	{
82
		$this->load();
83
		return $this->response;
84
	}
85
86
87
	/**
88
	 * @return int
89
	 */
90
	public function key()
91
	{
92
		return static::parsePage($this->request->getUrl());
0 ignored issues
show
Bug introduced by
The method getUrl() does not exist on null. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

92
		return static::parsePage($this->request->/** @scrutinizer ignore-call */ getUrl());

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
93
	}
94
95
96
	/**
97
	 * @return void
98
	 */
99
	public function next()
100
	{
101
		$this->load();
102
103
		if ($url = static::parseLink($this->response->getHeader('Link'), 'next')) {
104
			$this->request = new Http\Request(
105
				$this->request->getMethod(),
106
				$url,
107
				$this->request->getHeaders(),
108
				$this->request->getContent()
109
			);
110
		} else {
111
			$this->request = NULL;
112
		}
113
114
		$this->response = NULL;
115
		$this->counter++;
116
	}
117
118
119
	private function load()
120
	{
121
		if ($this->response === NULL) {
122
			$this->response = $this->api->request($this->request);
0 ignored issues
show
Bug introduced by
It seems like $this->request can also be of type null; however, parameter $request of XoopsModules\Wggithub\Github\Api::request() does only seem to accept XoopsModules\Wggithub\Github\Http\Request, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

122
			$this->response = $this->api->request(/** @scrutinizer ignore-type */ $this->request);
Loading history...
123
		}
124
	}
125
126
127
	/**
128
	 * @param  string
129
	 * @return int
130
	 */
131
	public static function parsePage($url)
132
	{
133
		list (, $parametersStr) = explode('?', $url, 2) + ['', ''];
134
		parse_str($parametersStr, $parameters);
135
136
		return isset($parameters['page'])
137
			? max(1, (int) $parameters['page'])
138
			: 1;
139
	}
140
141
142
	/**
143
	 * @see  https://developer.github.com/guides/traversing-with-pagination/#navigating-through-the-pages
144
	 *
145
	 * @param  string
146
	 * @param  string
147
	 * @return string|NULL
148
	 */
149
	public static function parseLink($link, $rel)
150
	{
151
		if (!preg_match('(<([^>]+)>;\s*rel="' . preg_quote($rel) . '")', $link, $match)) {
152
			return NULL;
153
		}
154
155
		return $match[1];
156
	}
157
158
}
159