PluginProbe
Yoast SEO – Advanced SEO with real-time guidance and built-in AI / 18.4
Yoast SEO – Advanced SEO with real-time guidance and built-in AI v18.4
28.5 28.4 28.3 28.2 28.1 28.0 27.9 27.8 27.7 27.6 27.5 trunk 18.0 18.1 18.2 18.3 18.4 18.4.1 18.5 18.5.1 18.6 18.7 18.8 18.9 19.0 All 129 releases
wordpress-seo / vendor_prefixed / guzzlehttp / guzzle / src / HandlerStack.php

HandlerStack.php in Yoast SEO – Advanced SEO with real-time guidance and built-in AI 18.4, at vendor_prefixed/guzzlehttp/guzzle/src/HandlerStack.php

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