PluginProbe
Yoast SEO – Advanced SEO with real-time guidance and built-in AI / 28.1
Yoast SEO – Advanced SEO with real-time guidance and built-in AI v28.1
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 / promises / src / Utils.php

Utils.php in Yoast SEO – Advanced SEO with real-time guidance and built-in AI 28.1, at vendor_prefixed/guzzlehttp/promises/src/Utils.php

245 lines 10.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 declare (strict_types=1);
4 namespace YoastSEO_Vendor\GuzzleHttp\Promise;
5
6 final class Utils
7 {
8 /**
9 * Get the global task queue used for promise resolution.
10 *
11 * This task queue MUST be run in an event loop in order for promises to be
12 * settled asynchronously. It will be automatically run when synchronously
13 * waiting on a promise.
14 *
15 * <code>
16 * while ($eventLoop->isRunning()) {
17 * GuzzleHttp\Promise\Utils::queue()->run();
18 * }
19 * </code>
20 *
21 * @param TaskQueueInterface|null $assign Optionally specify a new queue instance.
22 */
23 public static function queue(?\YoastSEO_Vendor\GuzzleHttp\Promise\TaskQueueInterface $assign = null) : \YoastSEO_Vendor\GuzzleHttp\Promise\TaskQueueInterface
24 {
25 static $queue;
26 if ($assign) {
27 $queue = $assign;
28 } elseif (!$queue) {
29 $queue = new \YoastSEO_Vendor\GuzzleHttp\Promise\TaskQueue();
30 }
31 return $queue;
32 }
33 /**
34 * Adds a function to run in the task queue when it is next `run()` and
35 * returns a promise that is fulfilled or rejected with the result.
36 *
37 * @param callable $task Task function to run.
38 */
39 public static function task(callable $task) : \YoastSEO_Vendor\GuzzleHttp\Promise\PromiseInterface
40 {
41 $queue = self::queue();
42 $promise = new \YoastSEO_Vendor\GuzzleHttp\Promise\Promise([$queue, 'run']);
43 $queue->add(function () use($task, $promise) : void {
44 try {
45 if (\YoastSEO_Vendor\GuzzleHttp\Promise\Is::pending($promise)) {
46 $promise->resolve($task());
47 }
48 } catch (\Throwable $e) {
49 $promise->reject($e);
50 }
51 });
52 return $promise;
53 }
54 /**
55 * Synchronously waits on a promise to resolve and returns an inspection
56 * state array.
57 *
58 * Returns a state associative array containing a "state" key mapping to a
59 * valid promise state. If the state of the promise is "fulfilled", the
60 * array will contain a "value" key mapping to the fulfilled value of the
61 * promise. If the promise is rejected, the array will contain a "reason"
62 * key mapping to the rejection reason of the promise.
63 *
64 * @param PromiseInterface $promise Promise or value.
65 */
66 public static function inspect(\YoastSEO_Vendor\GuzzleHttp\Promise\PromiseInterface $promise) : array
67 {
68 try {
69 return ['state' => \YoastSEO_Vendor\GuzzleHttp\Promise\PromiseInterface::FULFILLED, 'value' => $promise->wait()];
70 } catch (\Throwable $e) {
71 if ($e instanceof \YoastSEO_Vendor\GuzzleHttp\Promise\AggregateException) {
72 return ['state' => \YoastSEO_Vendor\GuzzleHttp\Promise\PromiseInterface::REJECTED, 'reason' => $e];
73 }
74 if ($e instanceof \YoastSEO_Vendor\GuzzleHttp\Promise\RejectionException) {
75 return ['state' => \YoastSEO_Vendor\GuzzleHttp\Promise\PromiseInterface::REJECTED, 'reason' => $e->getReason()];
76 }
77 return ['state' => \YoastSEO_Vendor\GuzzleHttp\Promise\PromiseInterface::REJECTED, 'reason' => $e];
78 }
79 }
80 /**
81 * Waits on all of the provided promises, but does not unwrap rejected
82 * promises as thrown exception.
83 *
84 * Returns an array of inspection state arrays.
85 *
86 * @see inspect for the inspection state array format.
87 *
88 * @param PromiseInterface[] $promises Traversable of promises to wait upon.
89 */
90 public static function inspectAll($promises) : array
91 {
92 $promises = self::prepareIterable($promises, __FUNCTION__);
93 $results = [];
94 foreach ($promises as $key => $promise) {
95 $results[$key] = self::inspect($promise);
96 }
97 return $results;
98 }
99 /**
100 * Waits on all of the provided promises and returns the fulfilled values.
101 *
102 * Returns an array that contains the value of each promise (in the same
103 * order the promises were provided). An exception is thrown if any of the
104 * promises are rejected.
105 *
106 * @param iterable<PromiseInterface> $promises Iterable of PromiseInterface objects to wait on.
107 *
108 * @throws \Throwable on error
109 */
110 public static function unwrap($promises) : array
111 {
112 $promises = self::prepareIterable($promises, __FUNCTION__);
113 $results = [];
114 foreach ($promises as $key => $promise) {
115 $results[$key] = $promise->wait();
116 }
117 return $results;
118 }
119 /**
120 * Given an array of promises, return a promise that is fulfilled when all
121 * the items in the array are fulfilled.
122 *
123 * The promise's fulfillment value is an array with fulfillment values at
124 * respective positions to the original array. If any promise in the array
125 * rejects, the returned promise is rejected with the rejection reason.
126 *
127 * @param mixed $promises Promises or values.
128 * @param bool $recursive If true, resolves new promises that might have been added to the stack during its own resolution.
129 */
130 public static function all($promises, bool $recursive = \false) : \YoastSEO_Vendor\GuzzleHttp\Promise\PromiseInterface
131 {
132 $promises = self::prepareIterable($promises, __FUNCTION__);
133 $results = [];
134 $promise = \YoastSEO_Vendor\GuzzleHttp\Promise\Each::of($promises, function ($value, $idx) use(&$results) : void {
135 $results[$idx] = $value;
136 }, function ($reason, $idx, \YoastSEO_Vendor\GuzzleHttp\Promise\Promise $aggregate) : void {
137 if (\YoastSEO_Vendor\GuzzleHttp\Promise\Is::pending($aggregate)) {
138 $aggregate->reject($reason);
139 }
140 })->then(function () use(&$results) {
141 \ksort($results);
142 return $results;
143 });
144 if (\true === $recursive) {
145 $promise = $promise->then(function ($results) use($recursive, &$promises) {
146 foreach ($promises as $promise) {
147 if (\YoastSEO_Vendor\GuzzleHttp\Promise\Is::pending($promise)) {
148 return self::all($promises, $recursive);
149 }
150 }
151 return $results;
152 });
153 }
154 return $promise;
155 }
156 /**
157 * Initiate a competitive race between multiple promises or values (values
158 * will become immediately fulfilled promises).
159 *
160 * When count amount of promises have been fulfilled, the returned promise
161 * is fulfilled with an array that contains the fulfillment values of the
162 * winners in order of resolution.
163 *
164 * This promise is rejected with a {@see AggregateException} if the number
165 * of fulfilled promises is less than the desired $count.
166 *
167 * @param int $count Total number of promises.
168 * @param mixed $promises Promises or values.
169 */
170 public static function some(int $count, $promises) : \YoastSEO_Vendor\GuzzleHttp\Promise\PromiseInterface
171 {
172 $promises = self::prepareIterable($promises, __FUNCTION__);
173 $results = [];
174 $rejections = [];
175 return \YoastSEO_Vendor\GuzzleHttp\Promise\Each::of($promises, function ($value, $idx, \YoastSEO_Vendor\GuzzleHttp\Promise\PromiseInterface $p) use(&$results, $count) : void {
176 if (\YoastSEO_Vendor\GuzzleHttp\Promise\Is::settled($p)) {
177 return;
178 }
179 $results[$idx] = $value;
180 if (\count($results) >= $count) {
181 $p->resolve(null);
182 }
183 }, function ($reason) use(&$rejections) : void {
184 $rejections[] = $reason;
185 })->then(function () use(&$results, &$rejections, $count) {
186 if (\count($results) !== $count) {
187 throw new \YoastSEO_Vendor\GuzzleHttp\Promise\AggregateException('Not enough promises to fulfill count', $rejections);
188 }
189 \ksort($results);
190 return \array_values($results);
191 });
192 }
193 /**
194 * Like some(), with 1 as count. However, if the promise fulfills, the
195 * fulfillment value is not an array of 1 but the value directly.
196 *
197 * @param mixed $promises Promises or values.
198 */
199 public static function any($promises) : \YoastSEO_Vendor\GuzzleHttp\Promise\PromiseInterface
200 {
201 $promises = self::prepareIterable($promises, __FUNCTION__);
202 return self::some(1, $promises)->then(function ($values) {
203 return $values[0];
204 });
205 }
206 /**
207 * Returns a promise that is fulfilled when all of the provided promises have
208 * been fulfilled or rejected.
209 *
210 * The returned promise is fulfilled with an array of inspection state arrays.
211 *
212 * @see inspect for the inspection state array format.
213 *
214 * @param mixed $promises Promises or values.
215 */
216 public static function settle($promises) : \YoastSEO_Vendor\GuzzleHttp\Promise\PromiseInterface
217 {
218 $promises = self::prepareIterable($promises, __FUNCTION__);
219 $results = [];
220 return \YoastSEO_Vendor\GuzzleHttp\Promise\Each::of($promises, function ($value, $idx) use(&$results) : void {
221 $results[$idx] = ['state' => \YoastSEO_Vendor\GuzzleHttp\Promise\PromiseInterface::FULFILLED, 'value' => $value];
222 }, function ($reason, $idx) use(&$results) : void {
223 $results[$idx] = ['state' => \YoastSEO_Vendor\GuzzleHttp\Promise\PromiseInterface::REJECTED, 'reason' => $reason];
224 })->then(function () use(&$results) {
225 \ksort($results);
226 return $results;
227 });
228 }
229 private static function prepareIterable($promises, string $method) : iterable
230 {
231 if (\is_iterable($promises)) {
232 return $promises;
233 }
234 self::triggerNonIterableDeprecation($promises, $method);
235 return [$promises];
236 }
237 private static function triggerNonIterableDeprecation($promises, string $method) : void
238 {
239 if (\is_iterable($promises)) {
240 return;
241 }
242 \YoastSEO_Vendor\trigger_deprecation('guzzlehttp/promises', '2.5', 'Passing a non-iterable to %s::%s() is deprecated; guzzlehttp/promises 3.0 will require an iterable.', self::class, $method);
243 }
244 }
245