PluginProbe
Yoast SEO – Advanced SEO with real-time guidance and built-in AI / trunk
Yoast SEO – Advanced SEO with real-time guidance and built-in AI vtrunk
28.6 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 All 130 releases
← All changes | vendor_prefixed/guzzlehttp/promises/src/EachPromise.php +33 -29 19.0 → trunk View file →
@@ -1,11 +1,14 @@
1 1 <?php
2 2
3 +declare (strict_types=1);
3 4 namespace YoastSEO_Vendor\GuzzleHttp\Promise;
4 5
5 6 /**
6 7 * Represents a promise that iterates over many promises and invokes
7 8 * side-effect functions in the process.
9 + *
10 + * @final
8 11 */
9 12 class EachPromise implements \YoastSEO_Vendor\GuzzleHttp\Promise\PromisorInterface
10 13 {
11 14 private $pending = [];
@@ -44,8 +47,12 @@
44 47 * @param array $config Configuration options
45 48 */
46 49 public function __construct($iterable, array $config = [])
47 50 {
51 + if (!\is_iterable($iterable)) {
52 + \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.', __CLASS__, __FUNCTION__);
53 + $iterable = [$iterable];
54 + }
48 55 $this->iterable = \YoastSEO_Vendor\GuzzleHttp\Promise\Create::iterFor($iterable);
49 56 if (isset($config['concurrency'])) {
50 57 $this->concurrency = $config['concurrency'];
51 58 }
@@ -56,9 +63,9 @@
56 63 $this->onRejected = $config['rejected'];
57 64 }
58 65 }
59 66 /** @psalm-suppress InvalidNullableReturnType */
60 - public function promise()
67 + public function promise() : \YoastSEO_Vendor\GuzzleHttp\Promise\PromiseInterface
61 68 {
62 69 if ($this->aggregate) {
63 70 return $this->aggregate;
64 71 }
@@ -66,31 +73,32 @@
66 73 $this->createPromise();
67 74 /** @psalm-assert Promise $this->aggregate */
68 75 $this->iterable->rewind();
69 76 $this->refillPending();
77 + if (!$this->pending) {
78 + \YoastSEO_Vendor\GuzzleHttp\Promise\Utils::queue()->add(function () : void {
79 + if (!$this->aggregate || \YoastSEO_Vendor\GuzzleHttp\Promise\Is::settled($this->aggregate)) {
80 + return;
81 + }
82 + try {
83 + $this->checkIfFinished();
84 + } catch (\Throwable $e) {
85 + $this->aggregate->reject($e);
86 + }
87 + });
88 + }
70 89 } catch (\Throwable $e) {
71 - /**
72 - * @psalm-suppress NullReference
73 - * @phpstan-ignore-next-line
74 - */
75 90 $this->aggregate->reject($e);
76 - } catch (\Exception $e) {
77 - /**
78 - * @psalm-suppress NullReference
79 - * @phpstan-ignore-next-line
80 - */
81 - $this->aggregate->reject($e);
82 91 }
83 92 /**
84 93 * @psalm-suppress NullableReturnStatement
85 - * @phpstan-ignore-next-line
86 94 */
87 95 return $this->aggregate;
88 96 }
89 - private function createPromise()
97 + private function createPromise() : void
90 98 {
91 99 $this->mutex = \false;
92 - $this->aggregate = new \YoastSEO_Vendor\GuzzleHttp\Promise\Promise(function () {
100 + $this->aggregate = new \YoastSEO_Vendor\GuzzleHttp\Promise\Promise(function () : void {
93 101 if ($this->checkIfFinished()) {
94 102 return;
95 103 }
96 104 \reset($this->pending);
@@ -104,9 +112,9 @@
104 112 }
105 113 }
106 114 });
107 115 // Clear the references when the promise is resolved.
108 - $clearFn = function () {
116 + $clearFn = function () : void {
109 117 $this->iterable = $this->concurrency = $this->pending = null;
110 118 $this->onFulfilled = $this->onRejected = null;
111 119 $this->nextPendingIndex = 0;
112 120 };
@@ -111,9 +119,9 @@
111 119 $this->nextPendingIndex = 0;
112 120 };
113 121 $this->aggregate->then($clearFn, $clearFn);
114 122 }
115 - private function refillPending()
123 + private function refillPending() : void
116 124 {
117 125 if (!$this->concurrency) {
118 126 // Add all pending promises.
119 127 while ($this->addPending() && $this->advanceIterator()) {
@@ -120,9 +128,9 @@
120 128 }
121 129 return;
122 130 }
123 131 // Add only up to N pending promises.
124 - $concurrency = \is_callable($this->concurrency) ? \call_user_func($this->concurrency, \count($this->pending)) : $this->concurrency;
132 + $concurrency = \is_callable($this->concurrency) ? ($this->concurrency)(\count($this->pending)) : $this->concurrency;
125 133 $concurrency = \max($concurrency - \count($this->pending), 0);
126 134 // Concurrency may be set to 0 to disallow new promises.
127 135 if (!$concurrency) {
128 136 return;
@@ -135,9 +143,9 @@
135 143 // next value to yield until promise callbacks are called.
136 144 while (--$concurrency && $this->advanceIterator() && $this->addPending()) {
137 145 }
138 146 }
139 - private function addPending()
147 + private function addPending() : bool
140 148 {
141 149 if (!$this->iterable || !$this->iterable->valid()) {
142 150 return \false;
143 151 }
@@ -145,22 +153,22 @@
145 153 $key = $this->iterable->key();
146 154 // Iterable keys may not be unique, so we use a counter to
147 155 // guarantee uniqueness
148 156 $idx = $this->nextPendingIndex++;
149 - $this->pending[$idx] = $promise->then(function ($value) use($idx, $key) {
157 + $this->pending[$idx] = $promise->then(function ($value) use($idx, $key) : void {
150 158 if ($this->onFulfilled) {
151 - \call_user_func($this->onFulfilled, $value, $key, $this->aggregate);
159 + ($this->onFulfilled)($value, $key, $this->aggregate);
152 160 }
153 161 $this->step($idx);
154 - }, function ($reason) use($idx, $key) {
162 + }, function ($reason) use($idx, $key) : void {
155 163 if ($this->onRejected) {
156 - \call_user_func($this->onRejected, $reason, $key, $this->aggregate);
164 + ($this->onRejected)($reason, $key, $this->aggregate);
157 165 }
158 166 $this->step($idx);
159 167 });
160 168 return \true;
161 169 }
162 - private function advanceIterator()
170 + private function advanceIterator() : bool
163 171 {
164 172 // Place a lock on the iterator so that we ensure to not recurse,
165 173 // preventing fatal generator errors.
166 174 if ($this->mutex) {
@@ -174,15 +182,11 @@
174 182 } catch (\Throwable $e) {
175 183 $this->aggregate->reject($e);
176 184 $this->mutex = \false;
177 185 return \false;
178 - } catch (\Exception $e) {
179 - $this->aggregate->reject($e);
180 - $this->mutex = \false;
181 - return \false;
182 186 }
183 187 }
184 - private function step($idx)
188 + private function step(int $idx) : void
185 189 {
186 190 // If the promise was already resolved, then ignore this step.
187 191 if (\YoastSEO_Vendor\GuzzleHttp\Promise\Is::settled($this->aggregate)) {
188 192 return;
@@ -195,9 +199,9 @@
195 199 // Add more pending promises if possible.
196 200 $this->refillPending();
197 201 }
198 202 }
199 - private function checkIfFinished()
203 + private function checkIfFinished() : bool
200 204 {
201 205 if (!$this->pending && !$this->iterable->valid()) {
202 206 // Resolve the promise if there's nothing left to do.
203 207 $this->aggregate->resolve(null);