summaryrefslogtreecommitdiff
path: root/vendor/guzzle/guzzle/src/Guzzle/Service/Resource/ResourceIterator.php
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/guzzle/guzzle/src/Guzzle/Service/Resource/ResourceIterator.php')
-rw-r--r--vendor/guzzle/guzzle/src/Guzzle/Service/Resource/ResourceIterator.php254
1 files changed, 254 insertions, 0 deletions
diff --git a/vendor/guzzle/guzzle/src/Guzzle/Service/Resource/ResourceIterator.php b/vendor/guzzle/guzzle/src/Guzzle/Service/Resource/ResourceIterator.php
new file mode 100644
index 0000000..e141524
--- /dev/null
+++ b/vendor/guzzle/guzzle/src/Guzzle/Service/Resource/ResourceIterator.php
@@ -0,0 +1,254 @@
+<?php
+
+namespace Guzzle\Service\Resource;
+
+use Guzzle\Common\AbstractHasDispatcher;
+use Guzzle\Service\Command\CommandInterface;
+
+abstract class ResourceIterator extends AbstractHasDispatcher implements ResourceIteratorInterface
+{
+ /** @var CommandInterface Command used to send requests */
+ protected $command;
+
+ /** @var CommandInterface First sent command */
+ protected $originalCommand;
+
+ /** @var array Currently loaded resources */
+ protected $resources;
+
+ /** @var int Total number of resources that have been retrieved */
+ protected $retrievedCount = 0;
+
+ /** @var int Total number of resources that have been iterated */
+ protected $iteratedCount = 0;
+
+ /** @var string NextToken/Marker for a subsequent request */
+ protected $nextToken = false;
+
+ /** @var int Maximum number of resources to fetch per request */
+ protected $pageSize;
+
+ /** @var int Maximum number of resources to retrieve in total */
+ protected $limit;
+
+ /** @var int Number of requests sent */
+ protected $requestCount = 0;
+
+ /** @var array Initial data passed to the constructor */
+ protected $data = array();
+
+ /** @var bool Whether or not the current value is known to be invalid */
+ protected $invalid;
+
+ public static function getAllEvents()
+ {
+ return array(
+ // About to issue another command to get more results
+ 'resource_iterator.before_send',
+ // Issued another command to get more results
+ 'resource_iterator.after_send'
+ );
+ }
+
+ /**
+ * @param CommandInterface $command Initial command used for iteration
+ * @param array $data Associative array of additional parameters. You may specify any number of custom
+ * options for an iterator. Among these options, you may also specify the following values:
+ * - limit: Attempt to limit the maximum number of resources to this amount
+ * - page_size: Attempt to retrieve this number of resources per request
+ */
+ public function __construct(CommandInterface $command, array $data = array())
+ {
+ // Clone the command to keep track of the originating command for rewind
+ $this->originalCommand = $command;
+
+ // Parse options from the array of options
+ $this->data = $data;
+ $this->limit = array_key_exists('limit', $data) ? $data['limit'] : 0;
+ $this->pageSize = array_key_exists('page_size', $data) ? $data['page_size'] : false;
+ }
+
+ /**
+ * Get all of the resources as an array (Warning: this could issue a large number of requests)
+ *
+ * @return array
+ */
+ public function toArray()
+ {
+ return iterator_to_array($this, false);
+ }
+
+ public function setLimit($limit)
+ {
+ $this->limit = $limit;
+ $this->resetState();
+
+ return $this;
+ }
+
+ public function setPageSize($pageSize)
+ {
+ $this->pageSize = $pageSize;
+ $this->resetState();
+
+ return $this;
+ }
+
+ /**
+ * Get an option from the iterator
+ *
+ * @param string $key Key of the option to retrieve
+ *
+ * @return mixed|null Returns NULL if not set or the value if set
+ */
+ public function get($key)
+ {
+ return array_key_exists($key, $this->data) ? $this->data[$key] : null;
+ }
+
+ /**
+ * Set an option on the iterator
+ *
+ * @param string $key Key of the option to set
+ * @param mixed $value Value to set for the option
+ *
+ * @return ResourceIterator
+ */
+ public function set($key, $value)
+ {
+ $this->data[$key] = $value;
+
+ return $this;
+ }
+
+ public function current()
+ {
+ return $this->resources ? current($this->resources) : false;
+ }
+
+ public function key()
+ {
+ return max(0, $this->iteratedCount - 1);
+ }
+
+ public function count()
+ {
+ return $this->retrievedCount;
+ }
+
+ /**
+ * Get the total number of requests sent
+ *
+ * @return int
+ */
+ public function getRequestCount()
+ {
+ return $this->requestCount;
+ }
+
+ /**
+ * Rewind the Iterator to the first element and send the original command
+ */
+ public function rewind()
+ {
+ // Use the original command
+ $this->command = clone $this->originalCommand;
+ $this->resetState();
+ $this->next();
+ }
+
+ public function valid()
+ {
+ return !$this->invalid && (!$this->resources || $this->current() || $this->nextToken)
+ && (!$this->limit || $this->iteratedCount < $this->limit + 1);
+ }
+
+ public function next()
+ {
+ $this->iteratedCount++;
+
+ // Check if a new set of resources needs to be retrieved
+ $sendRequest = false;
+ if (!$this->resources) {
+ $sendRequest = true;
+ } else {
+ // iterate over the internal array
+ $current = next($this->resources);
+ $sendRequest = $current === false && $this->nextToken && (!$this->limit || $this->iteratedCount < $this->limit + 1);
+ }
+
+ if ($sendRequest) {
+
+ $this->dispatch('resource_iterator.before_send', array(
+ 'iterator' => $this,
+ 'resources' => $this->resources
+ ));
+
+ // Get a new command object from the original command
+ $this->command = clone $this->originalCommand;
+ // Send a request and retrieve the newly loaded resources
+ $this->resources = $this->sendRequest();
+ $this->requestCount++;
+
+ // If no resources were found, then the last request was not needed
+ // and iteration must stop
+ if (empty($this->resources)) {
+ $this->invalid = true;
+ } else {
+ // Add to the number of retrieved resources
+ $this->retrievedCount += count($this->resources);
+ // Ensure that we rewind to the beginning of the array
+ reset($this->resources);
+ }
+
+ $this->dispatch('resource_iterator.after_send', array(
+ 'iterator' => $this,
+ 'resources' => $this->resources
+ ));
+ }
+ }
+
+ /**
+ * Retrieve the NextToken that can be used in other iterators.
+ *
+ * @return string Returns a NextToken
+ */
+ public function getNextToken()
+ {
+ return $this->nextToken;
+ }
+
+ /**
+ * Returns the value that should be specified for the page size for a request that will maintain any hard limits,
+ * but still honor the specified pageSize if the number of items retrieved + pageSize < hard limit
+ *
+ * @return int Returns the page size of the next request.
+ */
+ protected function calculatePageSize()
+ {
+ if ($this->limit && $this->iteratedCount + $this->pageSize > $this->limit) {
+ return 1 + ($this->limit - $this->iteratedCount);
+ }
+
+ return (int) $this->pageSize;
+ }
+
+ /**
+ * Reset the internal state of the iterator without triggering a rewind()
+ */
+ protected function resetState()
+ {
+ $this->iteratedCount = 0;
+ $this->retrievedCount = 0;
+ $this->nextToken = false;
+ $this->resources = null;
+ $this->invalid = false;
+ }
+
+ /**
+ * Send a request to retrieve the next page of results. Hook for subclasses to implement.
+ *
+ * @return array Returns the newly loaded resources
+ */
+ abstract protected function sendRequest();
+}