-
Notifications
You must be signed in to change notification settings - Fork 260
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Iterator final touches #521
Changes from all commits
bbf3bd4
0a32a76
25187e2
f801208
5f07e05
339610d
1eeb4bd
7bc3f8f
7b61553
2ce8083
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,24 +4,33 @@ | |
|
||
/** | ||
* Cursor Based Pagination | ||
* Used in paginationStrategyClass | ||
* Used in PaginationIterator | ||
*/ | ||
class CbpStrategy extends AbstractStrategy | ||
{ | ||
private $afterCursor = null; | ||
private $afterCursor; | ||
private $hasMore; | ||
private $started = false; | ||
|
||
public function page($getPageFn) | ||
{ | ||
$this->started = true; | ||
$response = $getPageFn(); | ||
$this->afterCursor = $response->meta->has_more ? $response->meta->after_cursor : null; | ||
$this->latestResponse = $getPageFn(); | ||
if (!isset($this->latestResponse->meta->has_more)) { | ||
throw new PaginationError( | ||
"Response not conforming to the CBP format, if you think your request is correct, please open an issue at https://github.com/zendesk/zendesk_api_client_php/issues" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. did you come across a case like this? can you try CBP requests on resources that do not implement them? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I haven't found any. But the iterator can be used in a customized way by the final users, so it can either be a problem with an endpoint that we missed (php also defines chat, talk, HC, voice). This is a friendly error so that the final user won't have to debug our code. |
||
); | ||
} | ||
$this->hasMore = $this->latestResponse->meta->has_more; | ||
if (isset($this->latestResponse->meta->after_cursor)) { | ||
$this->afterCursor = $this->latestResponse->meta->after_cursor; | ||
} | ||
|
||
return $response->{$this->resourcesKey}; | ||
return $this->latestResponse->{$this->resourcesKey}; | ||
} | ||
|
||
public function shouldGetPage($position) { | ||
return !$this->started || $this->afterCursor; | ||
return !$this->started || $this->hasMore; | ||
} | ||
|
||
public function params() | ||
|
@@ -31,14 +40,15 @@ public function params() | |
|
||
return $result; | ||
} | ||
|
||
/** | ||
* The params that are needed to ordering in CBP (eg: ["sort" => "-age"]) | ||
* If OBP params are passed, they are converted to CBP | ||
* | ||
* OBP: https://{subdomain}.zendesk.com/api/v2/tickets?sort_order=desc&sort_by=updated_at&per_page=2 | ||
* CBP: https://{subdomain}.zendesk.com/api/v2/tickets?sort=-updated_at&page[size]=2 | ||
* | ||
* @return array all params with CBP sorting order | ||
* @return array Params with proper CBP sorting order | ||
*/ | ||
private function sortParams() | ||
{ | ||
|
@@ -53,7 +63,7 @@ private function sortParams() | |
* The params that are needed to for pagination (eg: ["page[size]" => "100"]) | ||
* If OBP params are passed, they are converted to CBP | ||
* | ||
* @return array all params with CBP sorting order | ||
* @return array Params for pagination | ||
*/ | ||
private function paginationParams() | ||
{ | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,69 +2,86 @@ | |
|
||
namespace Zendesk\API\Traits\Utility\Pagination; | ||
|
||
class PaginationError extends \Exception {} | ||
|
||
const DEFAULT_PAGE_SIZE = 100; | ||
|
||
use Iterator; | ||
|
||
class PaginationIterator implements Iterator | ||
{ | ||
/** | ||
* @var mixed using trait FindAll. The object handling the list, Ie: `$client->{clientList}()` | ||
* Eg: `$client->tickets()` which uses FindAll | ||
*/ | ||
private $clientList; | ||
private $strategy; | ||
private $method; | ||
private $position = 0; | ||
private $page = []; | ||
private $items = []; | ||
|
||
public function __construct($clientList, AbstractStrategy $strategy, $method = 'findAll') | ||
/** | ||
* @param mixed using trait FindAll. The resources collection, Eg: `$client->tickets()` which uses FindAll | ||
* @param AbstractStrategy $strategy For pagination Logic (OBP, CBP, SinglePage) | ||
* @param string $method used to make the API call | ||
*/ | ||
public function __construct($clientList, AbstractStrategy $strategy, $method) | ||
{ | ||
$this->clientList = $clientList; | ||
$this->strategy = $strategy; | ||
$this->method = $method; | ||
} | ||
|
||
#[\ReturnTypeWillChange] | ||
public function key() | ||
{ | ||
return $this->position; | ||
} | ||
|
||
#[\ReturnTypeWillChange] | ||
public function next() | ||
{ | ||
++$this->position; | ||
} | ||
|
||
#[\ReturnTypeWillChange] | ||
public function rewind() | ||
{ | ||
$this->position = 0; | ||
} | ||
|
||
#[\ReturnTypeWillChange] | ||
public function valid() | ||
{ | ||
$this->getPageIfNeeded(); | ||
return !!$this->current(); | ||
} | ||
|
||
#[\ReturnTypeWillChange] | ||
public function current() | ||
{ | ||
if (isset($this->page[$this->position])) { | ||
return $this->page[$this->position]; | ||
if (isset($this->items[$this->position])) { | ||
return $this->items[$this->position]; | ||
} else { | ||
return null; | ||
} | ||
} | ||
|
||
/** | ||
* Returns the latest HTTP response, unless an error occurred, which causes an exception | ||
* | ||
* @return \GuzzleHttp\Psr7\Response | ||
*/ | ||
public function latestResponse() | ||
{ | ||
return $this->strategy->latestResponse(); | ||
} | ||
private function getPageIfNeeded() | ||
{ | ||
if (!$this->strategy->shouldGetPage($this->position)) { | ||
if (isset($this->items[$this->position]) || !$this->strategy->shouldGetPage($this->position)) { | ||
return; | ||
} | ||
|
||
$getPageFn = function () { | ||
return $this->clientList->{$this->method}($this->strategy->params()); | ||
}; | ||
|
||
$this->page = array_merge($this->page, $this->strategy->page($getPageFn)); | ||
$this->items = array_merge($this->items, $this->strategy->page($getPageFn)); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I can't store one single page, |
||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am guessing this to do is meant to be there and will be filled out later?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes, thanks, this is the upcoming work. To be addressed in a separate PR.