aboutsummaryrefslogtreecommitdiff
path: root/app/Utils/dotNotationUtil.php
diff options
context:
space:
mode:
authorGravatar Alexandre Alapetite <alexandre@alapetite.fr> 2025-03-13 22:40:41 +0100
committerGravatar GitHub <noreply@github.com> 2025-03-13 22:40:41 +0100
commita7361a3e7cd335c8932deba88fe60e8f673c2d40 (patch)
treebb4c007188d54897210f2a0539c2df0f438fb069 /app/Utils/dotNotationUtil.php
parentdf545b513b1c43e54da5b023bf3fe01bf36ad013 (diff)
Implement JSON string concatenation with & operator (#7414)
Inspired by [JSONata syntax](https://docs.jsonata.org/expressions). fix https://github.com/FreshRSS/FreshRSS/issues/6565
Diffstat (limited to 'app/Utils/dotNotationUtil.php')
-rw-r--r--app/Utils/dotNotationUtil.php32
1 files changed, 31 insertions, 1 deletions
diff --git a/app/Utils/dotNotationUtil.php b/app/Utils/dotNotationUtil.php
index 77ae96c30..89b91bc5b 100644
--- a/app/Utils/dotNotationUtil.php
+++ b/app/Utils/dotNotationUtil.php
@@ -18,9 +18,39 @@ final class FreshRSS_dotNotation_Util
return static::value($default);
}
/** @var \ArrayAccess<string,mixed>|array<string,mixed> $array */
- if (in_array($key, [null, '', '.', '$'], true)) {
+ if ($key === null) {
return $array;
}
+ $key = trim($key);
+
+ if (in_array($key, ['', '.', '$'], true)) {
+ return $array;
+ }
+
+ // If the key is a simple string, return the text
+ if (preg_match('/^(?P<delim>[\'"])(?P<text>[^&]*)(?P=delim)$/', $key, $matches)) {
+ $text = $matches['text'];
+ $text = str_replace('&', '&', $text); // Unescape `&`
+ return $text;
+ }
+
+ // Escape `&` operator
+ $key = preg_replace_callback('/(?P<delim>[\'"])(?P<text>.*?)(?P=delim)/',
+ fn(array $matches): string => str_replace('&', '&', $matches[0]),
+ $key) ?? $key;
+
+ // If the key contains string concatenations with `&`, process them
+ $concats = explode('&', $key);
+ if (count($concats) > 1) {
+ $text = '';
+ foreach ($concats as $concat) {
+ $result = static::get($array, $concat, $default);
+ if (is_scalar($result)) {
+ $text .= (string)$result;
+ }
+ }
+ return $text;
+ }
// Compatibility with brackets path such as `items[0].value`
$key = preg_replace('/\[(\d+)\]/', '.$1', $key);