@@ -80,26 +80,31 @@ private function evaluate(JsonPath $query): array
80
80
throw new InvalidJsonStringInputException ($ e ->getMessage (), $ e );
81
81
}
82
82
83
- $ current = [$ data ];
84
-
85
- foreach ($ tokens as $ token ) {
86
- $ next = [];
87
- foreach ($ current as $ value ) {
88
- $ result = $ this ->evaluateToken ($ token , $ value );
89
- $ next = array_merge ($ next , $ result );
90
- }
91
-
92
- $ current = $ next ;
93
- }
94
-
95
- return $ current ;
83
+ return $ this ->evaluateTokensOnDecodedData ($ tokens , $ data );
96
84
} catch (InvalidArgumentException $ e ) {
97
85
throw $ e ;
98
86
} catch (\Throwable $ e ) {
99
87
throw new JsonCrawlerException ($ query , $ e ->getMessage (), previous: $ e );
100
88
}
101
89
}
102
90
91
+ private function evaluateTokensOnDecodedData (array $ tokens , array $ data ): array
92
+ {
93
+ $ current = [$ data ];
94
+
95
+ foreach ($ tokens as $ token ) {
96
+ $ next = [];
97
+ foreach ($ current as $ value ) {
98
+ $ result = $ this ->evaluateToken ($ token , $ value );
99
+ $ next = array_merge ($ next , $ result );
100
+ }
101
+
102
+ $ current = $ next ;
103
+ }
104
+
105
+ return $ current ;
106
+ }
107
+
103
108
private function evaluateToken (JsonPathToken $ token , mixed $ value ): array
104
109
{
105
110
return match ($ token ->type ) {
@@ -246,10 +251,6 @@ private function evaluateFilter(string $expr, mixed $value): array
246
251
247
252
$ result = [];
248
253
foreach ($ value as $ item ) {
249
- if (!\is_array ($ item )) {
250
- continue ;
251
- }
252
-
253
254
if ($ this ->evaluateFilterExpression ($ expr , $ item )) {
254
255
$ result [] = $ item ;
255
256
}
@@ -258,7 +259,7 @@ private function evaluateFilter(string $expr, mixed $value): array
258
259
return $ result ;
259
260
}
260
261
261
- private function evaluateFilterExpression (string $ expr , array $ context ): bool
262
+ private function evaluateFilterExpression (string $ expr , mixed $ context ): bool
262
263
{
263
264
$ expr = trim ($ expr );
264
265
@@ -294,10 +295,12 @@ private function evaluateFilterExpression(string $expr, array $context): bool
294
295
}
295
296
}
296
297
297
- if (str_starts_with ($ expr , '@. ' )) {
298
- $ path = substr ($ expr , 2 );
298
+ if ('@ ' === $ expr ) {
299
+ return true ;
300
+ }
299
301
300
- return \array_key_exists ($ path , $ context );
302
+ if (str_starts_with ($ expr , '@. ' )) {
303
+ return (bool ) ($ this ->evaluateTokensOnDecodedData (JsonPathTokenizer::tokenize (new JsonPath ('$ ' . substr ($ expr , 1 ))), $ context )[0 ] ?? false );
301
304
}
302
305
303
306
// function calls
@@ -315,12 +318,16 @@ private function evaluateFilterExpression(string $expr, array $context): bool
315
318
return false ;
316
319
}
317
320
318
- private function evaluateScalar (string $ expr , array $ context ): mixed
321
+ private function evaluateScalar (string $ expr , mixed $ context ): mixed
319
322
{
320
323
if (is_numeric ($ expr )) {
321
324
return str_contains ($ expr , '. ' ) ? (float ) $ expr : (int ) $ expr ;
322
325
}
323
326
327
+ if ('@ ' === $ expr ) {
328
+ return $ context ;
329
+ }
330
+
324
331
if ('true ' === $ expr ) {
325
332
return true ;
326
333
}
@@ -339,10 +346,12 @@ private function evaluateScalar(string $expr, array $context): mixed
339
346
}
340
347
341
348
// current node references
342
- if (str_starts_with ($ expr , '@. ' )) {
343
- $ path = substr ($ expr , 2 );
349
+ if (str_starts_with ($ expr , '@ ' )) {
350
+ if (!\is_array ($ context )) {
351
+ return null ;
352
+ }
344
353
345
- return $ context[ $ path ] ?? null ;
354
+ return $ this -> evaluateTokensOnDecodedData (JsonPathTokenizer:: tokenize ( new JsonPath ( ' $ ' . substr ( $ expr , 1 ))), $ context)[ 0 ] ?? null ;
346
355
}
347
356
348
357
// function calls
0 commit comments