From 543046f91dd7b4866945715132ecb009175d6a85 Mon Sep 17 00:00:00 2001 From: Sergei Predvoditelev Date: Sat, 24 Jan 2026 14:48:39 +0300 Subject: [PATCH 1/3] Enhance `Message::parse()` to support nested placeholders --- CHANGELOG.md | 3 ++- src/Message.php | 2 +- tests/MessageTest.php | 40 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 43 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6439b25a..254d23b4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,8 @@ ## 2.2.1 under development - Bug #130: Updated `Message::parse()` to correctly support multiple placeholders (@technicated) -- Chg #130: Changed `Message::parse()` to conform to PSR-3, removing support for placeholders with arbitrary names and nested placeholders (@technicated) +- Chg #130, #131: Changed `Message::parse()` to conform to PSR-3, removing support for placeholders with arbitrary names + and nested placeholders (@technicated, @vjik) ## 2.2.0 December 13, 2025 diff --git a/src/Message.php b/src/Message.php index bc0df4b2..0985e702 100644 --- a/src/Message.php +++ b/src/Message.php @@ -208,7 +208,7 @@ private function parse(string|Stringable $message, array $context): string /** @var string */ return preg_replace_callback( - '/\{([\w\._]+)\}/', + '/\{([\w\.\\\\_]+)\}/', static function (array $matches) use ($context) { [$exist, $value] = ContextValueExtractor::extract($context, $matches[1]); if ($exist) { diff --git a/tests/MessageTest.php b/tests/MessageTest.php index 42ef888e..88634847 100644 --- a/tests/MessageTest.php +++ b/tests/MessageTest.php @@ -122,6 +122,46 @@ public function dataParseMessage(): array ['p1' => 'hello', 'p2' => 'world'], 'Placeholder 1: hello - Placeholder 2: world', ], + 'nested-quoted' => [ + 'has "{foo\.ba\\\\r}" placeholder', + ['foo.ba\\r' => 'test'], + 'has "test" placeholder', + ], + 'nested-extended-1' => [ + 'has "{foo\\\.bar}" placeholder', + ['foo\\' => ['bar' => 'test']], + 'has "test" placeholder', + ], + 'nested-extended-2' => [ + 'has "{foo\\\\\\\\.bar}" placeholder', + ['foo\\\\' => ['bar' => 'test']], + 'has "test" placeholder', + ], + 'nested-extended-3' => [ + 'has "{foo\\\.}" placeholder', + ['foo\\' => ['' => 'test']], + 'has "test" placeholder', + ], + 'nested-extended-4' => [ + 'has "{foo\\\\}" placeholder', + ['foo\\' => 'test'], + 'has "test" placeholder', + ], + 'nested-extended-5' => [ + 'has "{foo\.bar.a}" placeholder', + ['foo.bar' => ['a' => 'test']], + 'has "test" placeholder', + ], + 'nested-extended-6' => [ + 'has "{key1\..\.key2\..\.key3}" placeholder', + ['key1.' => ['.key2.' => ['.key3' => 'test']]], + 'has "test" placeholder', + ], + 'nested-extended-7' => [ + 'has "{key1\..\.key2\..\.key3}" placeholder', + ['key1.' => ['.key2.' => ['.key3' => 'test']]], + 'has "test" placeholder', + ], ]; } From fedfb56fd00d726972af8205c26ab885635f9065 Mon Sep 17 00:00:00 2001 From: Sergei Predvoditelev Date: Sat, 24 Jan 2026 14:49:23 +0300 Subject: [PATCH 2/3] fix --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 254d23b4..03e20a34 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,7 @@ ## 2.2.1 under development - Bug #130: Updated `Message::parse()` to correctly support multiple placeholders (@technicated) -- Chg #130, #131: Changed `Message::parse()` to conform to PSR-3, removing support for placeholders with arbitrary names +- Chg #130, #133: Changed `Message::parse()` to conform to PSR-3, removing support for placeholders with arbitrary names and nested placeholders (@technicated, @vjik) ## 2.2.0 December 13, 2025 From c5e220dd57dff4714ac3d33822fa29abf4320440 Mon Sep 17 00:00:00 2001 From: Alexander Makarov Date: Sun, 25 Jan 2026 15:10:11 +0300 Subject: [PATCH 3/3] Update CHANGELOG.md --- CHANGELOG.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 03e20a34..f472158d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,8 +3,7 @@ ## 2.2.1 under development - Bug #130: Updated `Message::parse()` to correctly support multiple placeholders (@technicated) -- Chg #130, #133: Changed `Message::parse()` to conform to PSR-3, removing support for placeholders with arbitrary names - and nested placeholders (@technicated, @vjik) +- Chg #130, #133: Changed `Message::parse()` to conform to PSR-3 (@technicated, @vjik) ## 2.2.0 December 13, 2025