195 lines
6.1 KiB
PHP
Executable file
195 lines
6.1 KiB
PHP
Executable file
<?php
|
|
|
|
|
|
namespace Twilio;
|
|
|
|
|
|
use Twilio\Exceptions\DeserializeException;
|
|
use Twilio\Exceptions\RestException;
|
|
use Twilio\Http\Response;
|
|
|
|
abstract class Page implements \Iterator {
|
|
protected static $metaKeys = [
|
|
'end',
|
|
'first_page_uri',
|
|
'next_page_uri',
|
|
'last_page_uri',
|
|
'page',
|
|
'page_size',
|
|
'previous_page_uri',
|
|
'total',
|
|
'num_pages',
|
|
'start',
|
|
'uri',
|
|
];
|
|
|
|
protected $version;
|
|
protected $payload;
|
|
protected $solution;
|
|
protected $records;
|
|
|
|
abstract public function buildInstance(array $payload);
|
|
|
|
public function __construct(Version $version, Response $response) {
|
|
$payload = $this->processResponse($response);
|
|
|
|
$this->version = $version;
|
|
$this->payload = $payload;
|
|
$this->solution = [];
|
|
$this->records = new \ArrayIterator($this->loadPage());
|
|
}
|
|
|
|
protected function processResponse(Response $response) {
|
|
if ($response->getStatusCode() !== 200 && !$this->isPagingEol($response->getContent())) {
|
|
$message = '[HTTP ' . $response->getStatusCode() . '] Unable to fetch page';
|
|
$code = $response->getStatusCode();
|
|
|
|
$content = $response->getContent();
|
|
$details = [];
|
|
$moreInfo = '';
|
|
|
|
if (\is_array($content)) {
|
|
$message .= isset($content['message']) ? ': ' . $content['message'] : '';
|
|
$code = $content['code'] ?? $code;
|
|
$moreInfo = $content['more_info'] ?? '';
|
|
$details = $content['details'] ?? [] ;
|
|
}
|
|
|
|
throw new RestException($message, $code, $response->getStatusCode(), $moreInfo, $details);
|
|
}
|
|
return $response->getContent();
|
|
}
|
|
|
|
protected function isPagingEol(?array $content): bool {
|
|
return $content !== null && \array_key_exists('code', $content) && $content['code'] === 20006;
|
|
}
|
|
|
|
protected function hasMeta(string $key): bool {
|
|
return \array_key_exists('meta', $this->payload) && \array_key_exists($key, $this->payload['meta']);
|
|
}
|
|
|
|
protected function getMeta(string $key, string $default = null): ?string {
|
|
return $this->hasMeta($key) ? $this->payload['meta'][$key] : $default;
|
|
}
|
|
|
|
protected function loadPage(): array {
|
|
$key = $this->getMeta('key');
|
|
if ($key) {
|
|
return $this->payload[$key];
|
|
}
|
|
|
|
$keys = \array_keys($this->payload);
|
|
$key = \array_diff($keys, self::$metaKeys);
|
|
$key = \array_values($key);
|
|
|
|
if (\count($key) === 1) {
|
|
return $this->payload[$key[0]];
|
|
}
|
|
|
|
// handle end of results error code
|
|
if ($this->isPagingEol($this->payload)) {
|
|
return [];
|
|
}
|
|
|
|
throw new DeserializeException('Page Records can not be deserialized');
|
|
}
|
|
|
|
public function getPreviousPageUrl(): ?string {
|
|
if ($this->hasMeta('previous_page_url')) {
|
|
return $this->getMeta('previous_page_url');
|
|
} else if (\array_key_exists('previous_page_uri', $this->payload) && $this->payload['previous_page_uri']) {
|
|
return $this->getVersion()->getDomain()->absoluteUrl($this->payload['previous_page_uri']);
|
|
}
|
|
return null;
|
|
}
|
|
|
|
public function getNextPageUrl(): ?string {
|
|
if ($this->hasMeta('next_page_url')) {
|
|
return $this->getMeta('next_page_url');
|
|
} else if (\array_key_exists('next_page_uri', $this->payload) && $this->payload['next_page_uri']) {
|
|
return $this->getVersion()->getDomain()->absoluteUrl($this->payload['next_page_uri']);
|
|
}
|
|
return null;
|
|
}
|
|
|
|
public function nextPage(): ?Page {
|
|
if (!$this->getNextPageUrl()) {
|
|
return null;
|
|
}
|
|
|
|
$response = $this->getVersion()->getDomain()->getClient()->request('GET', $this->getNextPageUrl());
|
|
return new static($this->getVersion(), $response, $this->solution);
|
|
}
|
|
|
|
public function previousPage(): ?Page {
|
|
if (!$this->getPreviousPageUrl()) {
|
|
return null;
|
|
}
|
|
|
|
$response = $this->getVersion()->getDomain()->getClient()->request('GET', $this->getPreviousPageUrl());
|
|
return new static($this->getVersion(), $response, $this->solution);
|
|
}
|
|
|
|
/**
|
|
* (PHP 5 >= 5.0.0)<br/>
|
|
* Return the current element
|
|
* @link http://php.net/manual/en/iterator.current.php
|
|
* @return mixed Can return any type.
|
|
*/
|
|
#[\ReturnTypeWillChange]
|
|
public function current() {
|
|
return $this->buildInstance($this->records->current());
|
|
}
|
|
|
|
/**
|
|
* (PHP 5 >= 5.0.0)<br/>
|
|
* Move forward to next element
|
|
* @link http://php.net/manual/en/iterator.next.php
|
|
* @return void Any returned value is ignored.
|
|
*/
|
|
public function next(): void {
|
|
$this->records->next();
|
|
}
|
|
|
|
/**
|
|
* (PHP 5 >= 5.0.0)<br/>
|
|
* Return the key of the current element
|
|
* @link http://php.net/manual/en/iterator.key.php
|
|
* @return mixed scalar on success, or null on failure.
|
|
*/
|
|
#[\ReturnTypeWillChange]
|
|
public function key() {
|
|
return $this->records->key();
|
|
}
|
|
|
|
/**
|
|
* (PHP 5 >= 5.0.0)<br/>
|
|
* Checks if current position is valid
|
|
* @link http://php.net/manual/en/iterator.valid.php
|
|
* @return bool The return value will be casted to boolean and then evaluated.
|
|
* Returns true on success or false on failure.
|
|
*/
|
|
public function valid(): bool {
|
|
return $this->records->valid();
|
|
}
|
|
|
|
/**
|
|
* (PHP 5 >= 5.0.0)<br/>
|
|
* Rewind the Iterator to the first element
|
|
* @link http://php.net/manual/en/iterator.rewind.php
|
|
* @return void Any returned value is ignored.
|
|
*/
|
|
public function rewind(): void {
|
|
$this->records->rewind();
|
|
}
|
|
|
|
|
|
public function getVersion(): Version {
|
|
return $this->version;
|
|
}
|
|
|
|
public function __toString(): string {
|
|
return '[Page]';
|
|
}
|
|
|
|
}
|