PluginProbe
AutomatorWP – No-Code Workflow Automation, Integration & Webhooks Plugin, now with AI / 6.0.4
AutomatorWP – No-Code Workflow Automation, Integration & Webhooks Plugin, now with AI v6.0.4
6.0.4 6.0.3 6.0.2 6.0.1 6.0.0 5.8.6 5.8.5 5.8.4 5.8.3 5.8.2 5.8.1 5.8.0 5.7.9.2 5.7.9.1 5.7.8 5.7.9 5.7.6 5.7.7 5.7.5 5.7.4 5.7.3 5.7.2 5.7.1 trunk 5.6.0 All 35 releases
← All changes | integrations/mailchimp/vendor/guzzlehttp/guzzle/src/HandlerStack.php +275 -0 5.8.2 → 6.0.4 View file →
@@ -1,0 +1,275 @@
1 +<?php
2 +
3 +namespace GuzzleHttp;
4 +
5 +use GuzzleHttp\Promise\PromiseInterface;
6 +use Psr\Http\Message\RequestInterface;
7 +use Psr\Http\Message\ResponseInterface;
8 +
9 +/**
10 + * Creates a composed Guzzle handler function by stacking middlewares on top of
11 + * an HTTP handler function.
12 + *
13 + * @final
14 + */
15 +class HandlerStack
16 +{
17 + /**
18 + * @var (callable(RequestInterface, array): PromiseInterface)|null
19 + */
20 + private $handler;
21 +
22 + /**
23 + * @var array{(callable(callable(RequestInterface, array): PromiseInterface): callable), (string|null)}[]
24 + */
25 + private $stack = [];
26 +
27 + /**
28 + * @var (callable(RequestInterface, array): PromiseInterface)|null
29 + */
30 + private $cached;
31 +
32 + /**
33 + * Creates a default handler stack that can be used by clients.
34 + *
35 + * The returned handler will wrap the provided handler or use the most
36 + * appropriate default handler for your system. The returned HandlerStack has
37 + * support for cookies, redirects, HTTP error exceptions, and preparing a body
38 + * before sending.
39 + *
40 + * The returned handler stack can be passed to a client in the "handler"
41 + * option.
42 + *
43 + * @param (callable(RequestInterface, array): PromiseInterface)|null $handler HTTP handler function to use with the stack. If no
44 + * handler is provided, the best handler for your
45 + * system will be utilized.
46 + */
47 + public static function create(?callable $handler = null): self
48 + {
49 + $stack = new self($handler ?: Utils::chooseHandler());
50 + $stack->push(Middleware::httpErrors(), 'http_errors');
51 + $stack->push(Middleware::redirect(), 'allow_redirects');
52 + $stack->push(Middleware::cookies(), 'cookies');
53 + $stack->push(Middleware::prepareBody(), 'prepare_body');
54 +
55 + return $stack;
56 + }
57 +
58 + /**
59 + * @param (callable(RequestInterface, array): PromiseInterface)|null $handler Underlying HTTP handler.
60 + */
61 + public function __construct(?callable $handler = null)
62 + {
63 + $this->handler = $handler;
64 + }
65 +
66 + /**
67 + * Invokes the handler stack as a composed handler
68 + *
69 + * @return ResponseInterface|PromiseInterface
70 + */
71 + public function __invoke(RequestInterface $request, array $options)
72 + {
73 + $handler = $this->resolve();
74 +
75 + return $handler($request, $options);
76 + }
77 +
78 + /**
79 + * Dumps a string representation of the stack.
80 + *
81 + * @return string
82 + */
83 + public function __toString()
84 + {
85 + $depth = 0;
86 + $stack = [];
87 +
88 + if ($this->handler !== null) {
89 + $stack[] = '0) Handler: '.$this->debugCallable($this->handler);
90 + }
91 +
92 + $result = '';
93 + foreach (\array_reverse($this->stack) as $tuple) {
94 + ++$depth;
95 + $str = "{$depth}) Name: '{$tuple[1]}', ";
96 + $str .= 'Function: '.$this->debugCallable($tuple[0]);
97 + $result = "> {$str}\n{$result}";
98 + $stack[] = $str;
99 + }
100 +
101 + foreach (\array_keys($stack) as $k) {
102 + $result .= "< {$stack[$k]}\n";
103 + }
104 +
105 + return $result;
106 + }
107 +
108 + /**
109 + * Set the HTTP handler that actually returns a promise.
110 + *
111 + * @param callable(RequestInterface, array): PromiseInterface $handler Accepts a request and array of options and
112 + * returns a Promise.
113 + */
114 + public function setHandler(callable $handler): void
115 + {
116 + $this->handler = $handler;
117 + $this->cached = null;
118 + }
119 +
120 + /**
121 + * Returns true if the builder has a handler.
122 + */
123 + public function hasHandler(): bool
124 + {
125 + return $this->handler !== null;
126 + }
127 +
128 + /**
129 + * Unshift a middleware to the bottom of the stack.
130 + *
131 + * @param callable(callable): callable $middleware Middleware function
132 + * @param string $name Name to register for this middleware.
133 + */
134 + public function unshift(callable $middleware, ?string $name = null): void
135 + {
136 + \array_unshift($this->stack, [$middleware, $name]);
137 + $this->cached = null;
138 + }
139 +
140 + /**
141 + * Push a middleware to the top of the stack.
142 + *
143 + * @param callable(callable): callable $middleware Middleware function
144 + * @param string $name Name to register for this middleware.
145 + */
146 + public function push(callable $middleware, string $name = ''): void
147 + {
148 + $this->stack[] = [$middleware, $name];
149 + $this->cached = null;
150 + }
151 +
152 + /**
153 + * Add a middleware before another middleware by name.
154 + *
155 + * @param string $findName Middleware to find
156 + * @param callable(callable): callable $middleware Middleware function
157 + * @param string $withName Name to register for this middleware.
158 + */
159 + public function before(string $findName, callable $middleware, string $withName = ''): void
160 + {
161 + $this->splice($findName, $withName, $middleware, true);
162 + }
163 +
164 + /**
165 + * Add a middleware after another middleware by name.
166 + *
167 + * @param string $findName Middleware to find
168 + * @param callable(callable): callable $middleware Middleware function
169 + * @param string $withName Name to register for this middleware.
170 + */
171 + public function after(string $findName, callable $middleware, string $withName = ''): void
172 + {
173 + $this->splice($findName, $withName, $middleware, false);
174 + }
175 +
176 + /**
177 + * Remove a middleware by instance or name from the stack.
178 + *
179 + * @param callable|string $remove Middleware to remove by instance or name.
180 + */
181 + public function remove($remove): void
182 + {
183 + if (!is_string($remove) && !is_callable($remove)) {
184 + trigger_deprecation('guzzlehttp/guzzle', '7.4', 'Not passing a callable or string to %s::%s() is deprecated and will cause an error in 8.0.', __CLASS__, __FUNCTION__);
185 + }
186 +
187 + $this->cached = null;
188 + $idx = \is_callable($remove) ? 0 : 1;
189 + $this->stack = \array_values(\array_filter(
190 + $this->stack,
191 + static function ($tuple) use ($idx, $remove) {
192 + return $tuple[$idx] !== $remove;
193 + }
194 + ));
195 + }
196 +
197 + /**
198 + * Compose the middleware and handler into a single callable function.
199 + *
200 + * @return callable(RequestInterface, array): PromiseInterface
201 + */
202 + public function resolve(): callable
203 + {
204 + if ($this->cached === null) {
205 + if (($prev = $this->handler) === null) {
206 + throw new \LogicException('No handler has been specified');
207 + }
208 +
209 + foreach (\array_reverse($this->stack) as $fn) {
210 + /** @var callable(RequestInterface, array): PromiseInterface $prev */
211 + $prev = $fn[0]($prev);
212 + }
213 +
214 + $this->cached = $prev;
215 + }
216 +
217 + return $this->cached;
218 + }
219 +
220 + private function findByName(string $name): int
221 + {
222 + foreach ($this->stack as $k => $v) {
223 + if ($v[1] === $name) {
224 + return $k;
225 + }
226 + }
227 +
228 + throw new \InvalidArgumentException("Middleware not found: $name");
229 + }
230 +
231 + /**
232 + * Splices a function into the middleware list at a specific position.
233 + */
234 + private function splice(string $findName, string $withName, callable $middleware, bool $before): void
235 + {
236 + $this->cached = null;
237 + $idx = $this->findByName($findName);
238 + $tuple = [$middleware, $withName];
239 +
240 + if ($before) {
241 + if ($idx === 0) {
242 + \array_unshift($this->stack, $tuple);
243 + } else {
244 + $replacement = [$tuple, $this->stack[$idx]];
245 + \array_splice($this->stack, $idx, 1, $replacement);
246 + }
247 + } elseif ($idx === \count($this->stack) - 1) {
248 + $this->stack[] = $tuple;
249 + } else {
250 + $replacement = [$this->stack[$idx], $tuple];
251 + \array_splice($this->stack, $idx, 1, $replacement);
252 + }
253 + }
254 +
255 + /**
256 + * Provides a debug string for a given callable.
257 + *
258 + * @param callable|string $fn Function to write as a string.
259 + */
260 + private function debugCallable($fn): string
261 + {
262 + if (\is_string($fn)) {
263 + return "callable({$fn})";
264 + }
265 +
266 + if (\is_array($fn)) {
267 + return \is_string($fn[0])
268 + ? "callable({$fn[0]}::{$fn[1]})"
269 + : "callable(['".\get_class($fn[0])."', '{$fn[1]}'])";
270 + }
271 +
272 + /** @var object $fn */
273 + return 'callable('.\spl_object_hash($fn).')';
274 + }
275 +}