PHP Classes

File: application/modules/extensions/aws/Aws/ResultPaginator.php

Recommend this page to a friend!
  Classes of Tran Tuan   Pretty PHP S3 Files Manager   application/modules/extensions/aws/Aws/ResultPaginator.php   Download  
File: application/modules/extensions/aws/Aws/ResultPaginator.php
Role: Application script
Content type: text/plain
Description: Initial
Class: Pretty PHP S3 Files Manager
Web based interface to manage files in Amazon S3
Author: By
Last change:
Date: 8 years ago
Size: 5,198 bytes
 

Contents

Class file image Download
<?php
namespace Aws;

use
GuzzleHttp\Promise;

/**
 * Iterator that yields each page of results of a pageable operation.
 */
class ResultPaginator implements \Iterator
{
   
/** @var AwsClientInterface Client performing operations. */
   
private $client;

   
/** @var string Name of the operation being paginated. */
   
private $operation;

   
/** @var array Args for the operation. */
   
private $args;

   
/** @var array Configuration for the paginator. */
   
private $config;

   
/** @var Result Most recent result from the client. */
   
private $result;

   
/** @var string|array Next token to use for pagination. */
   
private $nextToken;

   
/** @var int Number of operations/requests performed. */
   
private $requestCount = 0;

   
/**
     * @param AwsClientInterface $client
     * @param string $operation
     * @param array $args
     * @param array $config
     */
   
public function __construct(
       
AwsClientInterface $client,
       
$operation,
        array
$args,
        array
$config
   
) {
       
$this->client = $client;
       
$this->operation = $operation;
       
$this->args = $args;
       
$this->config = $config;
    }

   
/**
     * Runs a paginator asynchronously and uses a callback to handle results.
     *
     * The callback should have the signature: function (Aws\Result $result).
     * A non-null return value from the callback will be yielded by the
     * promise. This means that you can return promises from the callback that
     * will need to be resolved before continuing iteration over the remaining
     * items, essentially merging in other promises to the iteration. The last
     * non-null value returned by the callback will be the result that fulfills
     * the promise to any downstream promises.
     *
     * @param callable $handleResult Callback for handling each page of results.
     * The callback accepts the result that was
     * yielded as a single argument. If the
     * callback returns a promise, the promise
     * will be merged into the coroutine.
     *
     * @return Promise\Promise
     */
   
public function each(callable $handleResult)
    {
        return
Promise\coroutine(function () use ($handleResult) {
           
$nextToken = null;
            do {
               
$command = $this->createNextCommand($this->args, $nextToken);
               
$result = (yield $this->client->executeAsync($command));
               
$nextToken = $this->determineNextToken($result);
               
$retVal = $handleResult($result);
                if (
$retVal !== null) {
                    yield
Promise\promise_for($retVal);
                }
            } while (
$nextToken);
        });
    }

   
/**
     * Returns an iterator that iterates over the values of applying a JMESPath
     * search to each result yielded by the iterator as a flat sequence.
     *
     * @param string $expression JMESPath expression to apply to each result.
     *
     * @return \Iterator
     */
   
public function search($expression)
    {
       
// Apply JMESPath expression on each result, but as a flat sequence.
       
return flatmap($this, function (Result $result) use ($expression) {
            return (array)
$result->search($expression);
        });
    }

   
/**
     * @return Result
     */
   
public function current()
    {
        return
$this->valid() ? $this->result : false;
    }

    public function
key()
    {
        return
$this->valid() ? $this->requestCount - 1 : null;
    }

    public function
next()
    {
       
$this->result = null;
    }

    public function
valid()
    {
        if (
$this->result) {
            return
true;
        }

        if (
$this->nextToken || !$this->requestCount) {
           
$this->result = $this->client->execute(
               
$this->createNextCommand($this->args, $this->nextToken)
            );
           
$this->nextToken = $this->determineNextToken($this->result);
           
$this->requestCount++;
            return
true;
        }

        return
false;
    }

    public function
rewind()
    {
       
$this->requestCount = 0;
       
$this->nextToken = null;
       
$this->result = null;
    }

    private function
createNextCommand(array $args, array $nextToken = null)
    {
        return
$this->client->getCommand($this->operation, $args + ($nextToken ?: []));
    }

    private function
determineNextToken(Result $result)
    {
        if (!
$this->config['output_token']) {
            return
null;
        }

        if (
$this->config['more_results']
            && !
$result->search($this->config['more_results'])
        ) {
            return
null;
        }

       
$nextToken = is_scalar($this->config['output_token'])
            ? [
$this->config['input_token'] => $this->config['output_token']]
            :
array_combine($this->config['input_token'], $this->config['output_token']);

        return
array_filter(array_map(function ($outputToken) use ($result) {
            return
$result->search($outputToken);
        },
$nextToken));
    }
}