Page.php 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. <?php
  2. namespace Twilio;
  3. use Twilio\Exceptions\DeserializeException;
  4. use Twilio\Exceptions\RestException;
  5. use Twilio\Http\Response;
  6. abstract class Page implements \Iterator {
  7. protected static $metaKeys = array(
  8. 'end',
  9. 'first_page_uri',
  10. 'next_page_uri',
  11. 'last_page_uri',
  12. 'page',
  13. 'page_size',
  14. 'previous_page_uri',
  15. 'total',
  16. 'num_pages',
  17. 'start',
  18. 'uri',
  19. );
  20. protected $version;
  21. protected $payload;
  22. protected $solution;
  23. protected $records;
  24. abstract public function buildInstance(array $payload);
  25. public function __construct(Version $version, Response $response) {
  26. $payload = $this->processResponse($response);
  27. $this->version = $version;
  28. $this->payload = $payload;
  29. $this->solution = array();
  30. $this->records = new \ArrayIterator($this->loadPage());
  31. }
  32. protected function processResponse(Response $response) {
  33. if ($response->getStatusCode() != 200 && !$this->isPagingEol($response->getContent())) {
  34. $message = '[HTTP ' . $response->getStatusCode() . '] Unable to fetch page';
  35. $code = $response->getStatusCode();
  36. $content = $response->getContent();
  37. if (is_array($content)) {
  38. $message .= isset($content['message']) ? ': ' . $content['message'] : '';
  39. $code = isset($content['code']) ? $content['code'] : $code;
  40. }
  41. throw new RestException($message, $code, $response->getStatusCode());
  42. }
  43. return $response->getContent();
  44. }
  45. protected function isPagingEol($content) {
  46. return !is_null($content) && array_key_exists('code', $content) && $content['code'] == 20006;
  47. }
  48. protected function hasMeta($key) {
  49. return array_key_exists('meta', $this->payload) && array_key_exists($key, $this->payload['meta']);
  50. }
  51. protected function getMeta($key, $default=null) {
  52. return $this->hasMeta($key) ? $this->payload['meta'][$key] : $default;
  53. }
  54. protected function loadPage() {
  55. $key = $this->getMeta('key');
  56. if ($key) {
  57. return $this->payload[$key];
  58. } else {
  59. $keys = array_keys($this->payload);
  60. $key = array_diff($keys, self::$metaKeys);
  61. $key = array_values($key);
  62. if (count($key) == 1) {
  63. return $this->payload[$key[0]];
  64. }
  65. }
  66. // handle end of results error code
  67. if ($this->isPagingEol($this->payload)) {
  68. return array();
  69. }
  70. throw new DeserializeException('Page Records can not be deserialized');
  71. }
  72. public function getPreviousPageUrl() {
  73. if ($this->hasMeta('previous_page_url')) {
  74. return $this->getMeta('previous_page_url');
  75. } else if (array_key_exists('previous_page_uri', $this->payload) && $this->payload['previous_page_uri']) {
  76. return $this->getVersion()->getDomain()->absoluteUrl($this->payload['previous_page_uri']);
  77. }
  78. return null;
  79. }
  80. public function getNextPageUrl() {
  81. if ($this->hasMeta('next_page_url')) {
  82. return $this->getMeta('next_page_url');
  83. } else if (array_key_exists('next_page_uri', $this->payload) && $this->payload['next_page_uri']) {
  84. return $this->getVersion()->getDomain()->absoluteUrl($this->payload['next_page_uri']);
  85. }
  86. return null;
  87. }
  88. public function nextPage() {
  89. if (!$this->getNextPageUrl()) {
  90. return null;
  91. }
  92. $response = $this->getVersion()->getDomain()->getClient()->request('GET', $this->getNextPageUrl());
  93. return new static($this->getVersion(), $response, $this->solution);
  94. }
  95. public function previousPage() {
  96. if (!$this->getPreviousPageUrl()) {
  97. return null;
  98. }
  99. $response = $this->getVersion()->getDomain()->getClient()->request('GET', $this->getPreviousPageUrl());
  100. return new static($this->getVersion(), $response, $this->solution);
  101. }
  102. /**
  103. * (PHP 5 &gt;= 5.0.0)<br/>
  104. * Return the current element
  105. * @link http://php.net/manual/en/iterator.current.php
  106. * @return mixed Can return any type.
  107. */
  108. public function current() {
  109. return $this->buildInstance($this->records->current());
  110. }
  111. /**
  112. * (PHP 5 &gt;= 5.0.0)<br/>
  113. * Move forward to next element
  114. * @link http://php.net/manual/en/iterator.next.php
  115. * @return void Any returned value is ignored.
  116. */
  117. public function next() {
  118. $this->records->next();
  119. }
  120. /**
  121. * (PHP 5 &gt;= 5.0.0)<br/>
  122. * Return the key of the current element
  123. * @link http://php.net/manual/en/iterator.key.php
  124. * @return mixed scalar on success, or null on failure.
  125. */
  126. public function key() {
  127. return $this->records->key();
  128. }
  129. /**
  130. * (PHP 5 &gt;= 5.0.0)<br/>
  131. * Checks if current position is valid
  132. * @link http://php.net/manual/en/iterator.valid.php
  133. * @return boolean The return value will be casted to boolean and then evaluated.
  134. * Returns true on success or false on failure.
  135. */
  136. public function valid() {
  137. return $this->records->valid();
  138. }
  139. /**
  140. * (PHP 5 &gt;= 5.0.0)<br/>
  141. * Rewind the Iterator to the first element
  142. * @link http://php.net/manual/en/iterator.rewind.php
  143. * @return void Any returned value is ignored.
  144. */
  145. public function rewind() {
  146. $this->records->rewind();
  147. }
  148. /**
  149. * @return Version
  150. */
  151. public function getVersion() {
  152. return $this->version;
  153. }
  154. public function __toString() {
  155. return '[Page]';
  156. }
  157. }