|
34 | 34 | use ReflectionClass;
|
35 | 35 | use ReflectionException;
|
36 | 36 |
|
| 37 | +use function array_key_first; |
37 | 38 | use function assert;
|
38 | 39 | use function end;
|
39 | 40 | use function get_object_vars;
|
@@ -207,22 +208,26 @@ function get_encrypted_fields_from_server(string $databaseName, string $collecti
|
207 | 208 | /**
|
208 | 209 | * Return whether the first key in the document starts with a "$" character.
|
209 | 210 | *
|
210 |
| - * This is used for differentiating update and replacement documents. Since true |
211 |
| - * and false return values may be expected in different contexts, this function |
212 |
| - * intentionally throws if $document has an unexpected type. |
| 211 | + * This is used for validating aggregation pipeline stages and differentiating |
| 212 | + * update and replacement documents. Since true and false return values may be |
| 213 | + * expected in different contexts, this function intentionally throws if |
| 214 | + * $document has an unexpected type instead of returning false. |
213 | 215 | *
|
214 | 216 | * @internal
|
215 |
| - * @param array|object $document Update or replacement document |
| 217 | + * @param array|object $document |
216 | 218 | * @throws InvalidArgumentException if $document is not an array or object
|
217 | 219 | */
|
218 | 220 | function is_first_key_operator($document): bool
|
219 | 221 | {
|
220 | 222 | $document = document_to_array($document);
|
221 | 223 |
|
222 |
| - reset($document); |
223 |
| - $firstKey = (string) key($document); |
| 224 | + $firstKey = array_key_first($document); |
| 225 | + |
| 226 | + if (! is_string($firstKey)) { |
| 227 | + return false; |
| 228 | + } |
224 | 229 |
|
225 |
| - return isset($firstKey[0]) && $firstKey[0] === '$'; |
| 230 | + return '$' === $firstKey[0] ?? null; |
226 | 231 | }
|
227 | 232 |
|
228 | 233 | /**
|
@@ -266,11 +271,8 @@ function is_pipeline($pipeline): bool
|
266 | 271 | }
|
267 | 272 |
|
268 | 273 | $expectedKey++;
|
269 |
| - $stage = document_to_array($stage); |
270 |
| - reset($stage); |
271 |
| - $key = key($stage); |
272 | 274 |
|
273 |
| - if (! is_string($key) || substr($key, 0, 1) !== '$') { |
| 275 | + if (! is_first_key_operator($stage)) { |
274 | 276 | return false;
|
275 | 277 | }
|
276 | 278 | }
|
|
0 commit comments