Overview

Namespaces

  • Contrib
    • Bundle
      • CoverallsBundle
        • Console
        • Entity
      • CoverallsV1Bundle
        • Api
        • Collector
        • Command
        • Config
        • Entity
          • Git
    • Component
      • File
      • Log
      • System
        • Git
  • Guzzle
    • Batch
      • Exception
    • Cache
    • Common
      • Exception
    • Http
      • Curl
      • Exception
      • Message
      • QueryAggregator
    • Inflection
    • Iterator
    • Log
    • Parser
      • Cookie
      • Message
      • UriTemplate
      • Url
    • Plugin
      • Async
      • Backoff
      • Cache
      • Cookie
        • CookieJar
        • Exception
      • CurlAuth
      • ErrorResponse
        • Exception
      • History
      • Log
      • Md5
      • Mock
      • Oauth
    • Service
      • Builder
      • Command
        • Factory
        • LocationVisitor
          • Request
          • Response
      • Description
      • Exception
      • Resource
    • Stream
  • PHP
  • Psr
    • Log
  • Symfony
    • Component
      • Config
        • Definition
          • Builder
          • Exception
        • Exception
        • Loader
        • Resource
        • Util
      • Console
        • Command
        • Formatter
        • Helper
        • Input
        • Output
        • Tester
      • EventDispatcher
        • Debug
      • Finder
        • Adapter
        • Comparator
        • Exception
        • Expression
        • Iterator
        • Shell
      • Stopwatch
      • Yaml
        • Exception

Classes

  • AbstractResourceIteratorFactory
  • CompositeResourceIteratorFactory
  • MapResourceIteratorFactory
  • Model
  • ResourceIterator
  • ResourceIteratorApplyBatched
  • ResourceIteratorClassFactory

Interfaces

  • ResourceIteratorFactoryInterface
  • ResourceIteratorInterface
  • Overview
  • Namespace
  • Class
  • Tree
  • Todo
  1: <?php
  2: 
  3: namespace Guzzle\Service\Resource;
  4: 
  5: use Guzzle\Common\AbstractHasDispatcher;
  6: use Guzzle\Service\Command\CommandInterface;
  7: 
  8: /**
  9:  * {@inheritdoc}
 10:  */
 11: abstract class ResourceIterator extends AbstractHasDispatcher implements ResourceIteratorInterface
 12: {
 13:     /**
 14:      * @var CommandInterface Command used to send requests
 15:      */
 16:     protected $command;
 17: 
 18:     /**
 19:      * @var CommandInterface First sent command
 20:      */
 21:     protected $originalCommand;
 22: 
 23:     /**
 24:      * @var array Currently loaded resources
 25:      */
 26:     protected $resources;
 27: 
 28:     /**
 29:      * @var int Total number of resources that have been retrieved
 30:      */
 31:     protected $retrievedCount = 0;
 32: 
 33:     /**
 34:      * @var int Total number of resources that have been iterated
 35:      */
 36:     protected $iteratedCount = 0;
 37: 
 38:     /**
 39:      * @var string NextToken/Marker for a subsequent request
 40:      */
 41:     protected $nextToken = false;
 42: 
 43:     /**
 44:      * @var int Maximum number of resources to fetch per request
 45:      */
 46:     protected $pageSize;
 47: 
 48:     /**
 49:      * @var int Maximum number of resources to retrieve in total
 50:      */
 51:     protected $limit;
 52: 
 53:     /**
 54:      * @var int Number of requests sent
 55:      */
 56:     protected $requestCount = 0;
 57: 
 58:     /**
 59:      * @var array Initial data passed to the constructor
 60:      */
 61:     protected $data = array();
 62: 
 63:     /**
 64:      * @var bool Whether or not the current value is known to be invalid (e.g. when sendRequest() returns 0 resources)
 65:      */
 66:     protected $invalid;
 67: 
 68:     /**
 69:      * {@inheritdoc}
 70:      */
 71:     public static function getAllEvents()
 72:     {
 73:         return array(
 74:             // About to issue another command to get more results
 75:             'resource_iterator.before_send',
 76:             // Issued another command to get more results
 77:             'resource_iterator.after_send'
 78:         );
 79:     }
 80: 
 81:     /**
 82:      * This should only be invoked by a {@see ClientInterface} object.
 83:      *
 84:      * @param CommandInterface $command Initial command used for iteration
 85:      *
 86:      * @param array $data Associative array of additional parameters. You may specify any number of custom options for
 87:      *                    an iterator. Among these options, you may also specify the following values:
 88:      *                    - limit: Attempt to limit the maximum number of resources to this amount
 89:      *                    - page_size: Attempt to retrieve this number of resources per request
 90:      */
 91:     public function __construct(CommandInterface $command, array $data = array())
 92:     {
 93:         // Clone the command to keep track of the originating command for rewind
 94:         $this->originalCommand = $command;
 95: 
 96:         // Parse options from the array of options
 97:         $this->data = $data;
 98:         $this->limit = array_key_exists('limit', $data) ? $data['limit'] : 0;
 99:         $this->pageSize = array_key_exists('page_size', $data) ? $data['page_size'] : false;
100:     }
101: 
102:     /**
103:      * Get all of the resources as an array (Warning: this could issue a large number of requests)
104:      *
105:      * @return array
106:      */
107:     public function toArray()
108:     {
109:         return iterator_to_array($this, false);
110:     }
111: 
112:     /**
113:      * {@inheritdoc}
114:      */
115:     public function setLimit($limit)
116:     {
117:         $this->limit = $limit;
118:         $this->resetState();
119: 
120:         return $this;
121:     }
122: 
123:     /**
124:      * {@inheritdoc}
125:      */
126:     public function setPageSize($pageSize)
127:     {
128:         $this->pageSize = $pageSize;
129:         $this->resetState();
130: 
131:         return $this;
132:     }
133: 
134:     /**
135:      * Get an option from the iterator
136:      *
137:      * @param string $key Key of the option to retrieve
138:      *
139:      * @return mixed|null Returns NULL if not set or the value if set
140:      */
141:     public function get($key)
142:     {
143:         return array_key_exists($key, $this->data) ? $this->data[$key] : null;
144:     }
145: 
146:     /**
147:      * Set an option on the iterator
148:      *
149:      * @param string $key   Key of the option to set
150:      * @param mixed  $value Value to set for the option
151:      *
152:      * @return ResourceIterator
153:      */
154:     public function set($key, $value)
155:     {
156:         $this->data[$key] = $value;
157: 
158:         return $this;
159:     }
160: 
161:     /**
162:      * Return the current element.
163:      *
164:      * @return mixed Returns the current element.
165:      */
166:     public function current()
167:     {
168:         return $this->resources ? current($this->resources) : false;
169:     }
170: 
171:     /**
172:      * Return the key of the current element.
173:      *
174:      * @return mixed
175:      */
176:     public function key()
177:     {
178:         return max(0, $this->iteratedCount - 1);
179:     }
180: 
181:     /**
182:      * Return the total number of items that have been retrieved thus far.
183:      *
184:      * @return int
185:      */
186:     public function count()
187:     {
188:         return $this->retrievedCount;
189:     }
190: 
191:     /**
192:      * Get the total number of requests sent
193:      *
194:      * @return int
195:      */
196:     public function getRequestCount()
197:     {
198:         return $this->requestCount;
199:     }
200: 
201:     /**
202:      * Rewind the Iterator to the first element and send the original command
203:      */
204:     public function rewind()
205:     {
206:         // Use the original command
207:         $this->command = clone $this->originalCommand;
208:         $this->resetState();
209:         $this->next();
210:     }
211: 
212:     /**
213:      * Check if there is a current element after calls to rewind() or next().
214:      *
215:      * @return bool Returns TRUE if the current element is valid or FALSE
216:      */
217:     public function valid()
218:     {
219:         return !$this->invalid && (!$this->resources || $this->current() || $this->nextToken)
220:             && (!$this->limit || $this->iteratedCount < $this->limit + 1);
221:     }
222: 
223:     /**
224:      * Move forward to next element and may trigger subsequent requests
225:      */
226:     public function next()
227:     {
228:         $this->iteratedCount++;
229: 
230:         // Check if a new set of resources needs to be retrieved
231:         $sendRequest = false;
232:         if (!$this->resources) {
233:             $sendRequest = true;
234:         } else {
235:             // iterate over the internal array
236:             $current = next($this->resources);
237:             $sendRequest = $current === false && $this->nextToken && (!$this->limit || $this->iteratedCount < $this->limit + 1);
238:         }
239: 
240:         if ($sendRequest) {
241: 
242:             $this->dispatch('resource_iterator.before_send', array(
243:                 'iterator'  => $this,
244:                 'resources' => $this->resources
245:             ));
246: 
247:             // Get a new command object from the original command
248:             $this->command = clone $this->originalCommand;
249:             // Send a request and retrieve the newly loaded resources
250:             $this->resources = $this->sendRequest();
251:             $this->requestCount++;
252: 
253:             // If no resources were found, then the last request was not needed
254:             // and iteration must stop
255:             if (empty($this->resources)) {
256:                 $this->invalid = true;
257:             } else {
258:                 // Add to the number of retrieved resources
259:                 $this->retrievedCount += count($this->resources);
260:                 // Ensure that we rewind to the beginning of the array
261:                 reset($this->resources);
262:             }
263: 
264:             $this->dispatch('resource_iterator.after_send', array(
265:                 'iterator'  => $this,
266:                 'resources' => $this->resources
267:             ));
268:         }
269:     }
270: 
271:     /**
272:      * Retrieve the NextToken that can be used in other iterators.
273:      *
274:      * @return string Returns a NextToken
275:      */
276:     public function getNextToken()
277:     {
278:         return $this->nextToken;
279:     }
280: 
281:     /**
282:      * Returns the value that should be specified for the page size for a request that will maintain any hard limits,
283:      * but still honor the specified pageSize if the number of items retrieved + pageSize < hard limit
284:      *
285:      * @return int Returns the page size of the next request.
286:      */
287:     protected function calculatePageSize()
288:     {
289:         if ($this->limit && $this->iteratedCount + $this->pageSize > $this->limit) {
290:             return 1 + ($this->limit - $this->iteratedCount);
291:         }
292: 
293:         return (int) $this->pageSize;
294:     }
295: 
296:     /**
297:      * Reset the internal state of the iterator without triggering a rewind()
298:      */
299:     protected function resetState()
300:     {
301:         $this->iteratedCount = 0;
302:         $this->retrievedCount = 0;
303:         $this->nextToken = false;
304:         $this->resources = null;
305:         $this->invalid = false;
306:     }
307: 
308:     /**
309:      * Send a request to retrieve the next page of results. Hook for subclasses to implement.
310:      *
311:      * @return array Returns the newly loaded resources
312:      */
313:     abstract protected function sendRequest();
314: }
315: 
php-coveralls API documentation generated by ApiGen 2.8.0