krz/vox-populi

A Tumblr web client.

clone: git clone https://gitbay.org/krz/vox-populi.git

main: vendor/guzzlehttp/guzzle/src/Handler/MockHandler.php · raw

  1<?php
  2namespace GuzzleHttp\Handler;
  3
  4use GuzzleHttp\Exception\RequestException;
  5use GuzzleHttp\HandlerStack;
  6use GuzzleHttp\Promise\PromiseInterface;
  7use GuzzleHttp\Promise\RejectedPromise;
  8use GuzzleHttp\TransferStats;
  9use Psr\Http\Message\RequestInterface;
 10use Psr\Http\Message\ResponseInterface;
 11
 12/**
 13 * Handler that returns responses or throw exceptions from a queue.
 14 */
 15class MockHandler implements \Countable
 16{
 17    private $queue = [];
 18    private $lastRequest;
 19    private $lastOptions;
 20    private $onFulfilled;
 21    private $onRejected;
 22
 23    /**
 24     * Creates a new MockHandler that uses the default handler stack list of
 25     * middlewares.
 26     *
 27     * @param array $queue Array of responses, callables, or exceptions.
 28     * @param callable $onFulfilled Callback to invoke when the return value is fulfilled.
 29     * @param callable $onRejected  Callback to invoke when the return value is rejected.
 30     *
 31     * @return HandlerStack
 32     */
 33    public static function createWithMiddleware(
 34        array $queue = null,
 35        callable $onFulfilled = null,
 36        callable $onRejected = null
 37    ) {
 38        return HandlerStack::create(new self($queue, $onFulfilled, $onRejected));
 39    }
 40
 41    /**
 42     * The passed in value must be an array of
 43     * {@see Psr7\Http\Message\ResponseInterface} objects, Exceptions,
 44     * callables, or Promises.
 45     *
 46     * @param array $queue
 47     * @param callable $onFulfilled Callback to invoke when the return value is fulfilled.
 48     * @param callable $onRejected  Callback to invoke when the return value is rejected.
 49     */
 50    public function __construct(
 51        array $queue = null,
 52        callable $onFulfilled = null,
 53        callable $onRejected = null
 54    ) {
 55        $this->onFulfilled = $onFulfilled;
 56        $this->onRejected = $onRejected;
 57
 58        if ($queue) {
 59            call_user_func_array([$this, 'append'], $queue);
 60        }
 61    }
 62
 63    public function __invoke(RequestInterface $request, array $options)
 64    {
 65        if (!$this->queue) {
 66            throw new \OutOfBoundsException('Mock queue is empty');
 67        }
 68
 69        if (isset($options['delay']) && is_numeric($options['delay'])) {
 70            usleep($options['delay'] * 1000);
 71        }
 72
 73        $this->lastRequest = $request;
 74        $this->lastOptions = $options;
 75        $response = array_shift($this->queue);
 76
 77        if (isset($options['on_headers'])) {
 78            if (!is_callable($options['on_headers'])) {
 79                throw new \InvalidArgumentException('on_headers must be callable');
 80            }
 81            try {
 82                $options['on_headers']($response);
 83            } catch (\Exception $e) {
 84                $msg = 'An error was encountered during the on_headers event';
 85                $response = new RequestException($msg, $request, $response, $e);
 86            }
 87        }
 88
 89        if (is_callable($response)) {
 90            $response = call_user_func($response, $request, $options);
 91        }
 92
 93        $response = $response instanceof \Exception
 94            ? \GuzzleHttp\Promise\rejection_for($response)
 95            : \GuzzleHttp\Promise\promise_for($response);
 96
 97        return $response->then(
 98            function ($value) use ($request, $options) {
 99                $this->invokeStats($request, $options, $value);
100                if ($this->onFulfilled) {
101                    call_user_func($this->onFulfilled, $value);
102                }
103                if (isset($options['sink'])) {
104                    $contents = (string) $value->getBody();
105                    $sink = $options['sink'];
106
107                    if (is_resource($sink)) {
108                        fwrite($sink, $contents);
109                    } elseif (is_string($sink)) {
110                        file_put_contents($sink, $contents);
111                    } elseif ($sink instanceof \Psr\Http\Message\StreamInterface) {
112                        $sink->write($contents);
113                    }
114                }
115
116                return $value;
117            },
118            function ($reason) use ($request, $options) {
119                $this->invokeStats($request, $options, null, $reason);
120                if ($this->onRejected) {
121                    call_user_func($this->onRejected, $reason);
122                }
123                return \GuzzleHttp\Promise\rejection_for($reason);
124            }
125        );
126    }
127
128    /**
129     * Adds one or more variadic requests, exceptions, callables, or promises
130     * to the queue.
131     */
132    public function append()
133    {
134        foreach (func_get_args() as $value) {
135            if ($value instanceof ResponseInterface
136                || $value instanceof \Exception
137                || $value instanceof PromiseInterface
138                || is_callable($value)
139            ) {
140                $this->queue[] = $value;
141            } else {
142                throw new \InvalidArgumentException('Expected a response or '
143                    . 'exception. Found ' . \GuzzleHttp\describe_type($value));
144            }
145        }
146    }
147
148    /**
149     * Get the last received request.
150     *
151     * @return RequestInterface
152     */
153    public function getLastRequest()
154    {
155        return $this->lastRequest;
156    }
157
158    /**
159     * Get the last received request options.
160     *
161     * @return array
162     */
163    public function getLastOptions()
164    {
165        return $this->lastOptions;
166    }
167
168    /**
169     * Returns the number of remaining items in the queue.
170     *
171     * @return int
172     */
173    public function count()
174    {
175        return count($this->queue);
176    }
177
178    public function reset()
179    {
180        $this->queue = [];
181    }
182
183    private function invokeStats(
184        RequestInterface $request,
185        array $options,
186        ResponseInterface $response = null,
187        $reason = null
188    ) {
189        if (isset($options['on_stats'])) {
190            $transferTime = isset($options['transfer_time']) ? $options['transfer_time'] : 0;
191            $stats = new TransferStats($request, $response, $transferTime, $reason);
192            call_user_func($options['on_stats'], $stats);
193        }
194    }
195}