@@ -80,26 +80,31 @@ private function evaluate(JsonPath $query): array
8080 throw new InvalidJsonStringInputException ($ e ->getMessage (), $ e );
8181 }
8282
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 );
9684 } catch (InvalidArgumentException $ e ) {
9785 throw $ e ;
9886 } catch (\Throwable $ e ) {
9987 throw new JsonCrawlerException ($ query , $ e ->getMessage (), previous: $ e );
10088 }
10189 }
10290
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+
103108 private function evaluateToken (JsonPathToken $ token , mixed $ value ): array
104109 {
105110 return match ($ token ->type ) {
@@ -246,10 +251,6 @@ private function evaluateFilter(string $expr, mixed $value): array
246251
247252 $ result = [];
248253 foreach ($ value as $ item ) {
249- if (!\is_array ($ item )) {
250- continue ;
251- }
252-
253254 if ($ this ->evaluateFilterExpression ($ expr , $ item )) {
254255 $ result [] = $ item ;
255256 }
@@ -258,7 +259,7 @@ private function evaluateFilter(string $expr, mixed $value): array
258259 return $ result ;
259260 }
260261
261- private function evaluateFilterExpression (string $ expr , array $ context ): bool
262+ private function evaluateFilterExpression (string $ expr , mixed $ context ): bool
262263 {
263264 $ expr = trim ($ expr );
264265
@@ -294,10 +295,12 @@ private function evaluateFilterExpression(string $expr, array $context): bool
294295 }
295296 }
296297
297- if (str_starts_with ($ expr , '@. ' )) {
298- $ path = substr ($ expr , 2 );
298+ if ('@ ' === $ expr ) {
299+ return true ;
300+ }
299301
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 );
301304 }
302305
303306 // function calls
@@ -315,12 +318,16 @@ private function evaluateFilterExpression(string $expr, array $context): bool
315318 return false ;
316319 }
317320
318- private function evaluateScalar (string $ expr , array $ context ): mixed
321+ private function evaluateScalar (string $ expr , mixed $ context ): mixed
319322 {
320323 if (is_numeric ($ expr )) {
321324 return str_contains ($ expr , '. ' ) ? (float ) $ expr : (int ) $ expr ;
322325 }
323326
327+ if ('@ ' === $ expr ) {
328+ return $ context ;
329+ }
330+
324331 if ('true ' === $ expr ) {
325332 return true ;
326333 }
@@ -339,10 +346,12 @@ private function evaluateScalar(string $expr, array $context): mixed
339346 }
340347
341348 // 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+ }
344353
345- return $ context[ $ path ] ?? null ;
354+ return $ this -> evaluateTokensOnDecodedData (JsonPathTokenizer:: tokenize ( new JsonPath ( ' $ ' . substr ( $ expr , 1 ))), $ context)[ 0 ] ?? null ;
346355 }
347356
348357 // function calls
0 commit comments