Subversion Repositories cheapmusic

Rev

Details | Last modification | View Log | RSS feed

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