Esempio n. 1
0
 /**
  * This method iterates over a collection of resources. It sends the operation's request to the API,
  * parses the response, converts each element into {@see self} and - if pagination is supported - continues
  * to send requests until an empty collection is received back.
  *
  * For paginated collections, it sends subsequent requests according to a marker URL query. The value
  * of the marker will depend on the last element returned in the previous response. If a limit is
  * provided, the loop will continue up until that point.
  *
  * @param Operation $operation The operation responsible for retrieving a new collection
  * @param callable  $mapFn     An optional callback that will be executed on every resource iteration.
  */
 public function enumerate(Operation $operation, callable $mapFn = null)
 {
     $limit = $operation->getValue('limit') ?: false;
     $supportsPagination = $operation->hasParam('marker');
     $markerKey = $this->markerKey ?: self::DEFAULT_MARKER_KEY;
     $count = 0;
     $moreRequestsRequired = true;
     $totalReached = function ($count) use($limit) {
         return $limit && $count >= $limit;
     };
     while ($moreRequestsRequired && $count < 20) {
         $response = $operation->send();
         $body = $response->json();
         $json = $this->flatten($body, $this->resourcesKey);
         foreach ($json as $resourceData) {
             if ($totalReached($count)) {
                 break;
             }
             $count++;
             $resource = $this->newInstance();
             $resource->populateFromArray($resourceData);
             if ($mapFn) {
                 call_user_func_array($mapFn, [$resource]);
             }
             if ($supportsPagination) {
                 $operation->setValue('marker', $resource->{$markerKey});
             }
             (yield $resource);
         }
         if ($totalReached($count) || !$supportsPagination || empty($json)) {
             $moreRequestsRequired = false;
         }
     }
 }