Skip to content

Commit

Permalink
feat(property-access): allow escaping in PropertyPath
Browse files Browse the repository at this point in the history
  • Loading branch information
alanpoulain committed Feb 10, 2023
1 parent b7b2eb8 commit 9b6013a
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 2 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
CHANGELOG
=========

6.3
---

* Allow escaping `.` and `[` with `\` in `PropertyPath`

6.2
---

Expand Down
8 changes: 6 additions & 2 deletions PropertyPath.php
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ public function __construct(self|string $propertyPath)
$remaining = $propertyPath;

// first element is evaluated differently - no leading dot for properties
$pattern = '/^(([^\.\[]++)|\[([^\]]++)\])(.*)/';
$pattern = '/^(((?:[^\\\\.\[]|\\\\.)++)|\[([^\]]++)\])(.*)/';

while (preg_match($pattern, $remaining, $matches)) {
if ('' !== $matches[2]) {
Expand All @@ -114,11 +114,15 @@ public function __construct(self|string $propertyPath)
$this->isNullSafe[] = false;
}

$element = preg_replace('/\\\([.[])/', '$1', $element);
if (str_ends_with($element, '\\\\')) {
$element = substr($element, 0, -1);
}
$this->elements[] = $element;

$position += \strlen($matches[1]);
$remaining = $matches[4];
$pattern = '/^(\.([^\.|\[]++)|\[([^\]]++)\])(.*)/';
$pattern = '/^(\.((?:[^\\\\.\[]|\\\\.)++)|\[([^\]]++)\])(.*)/';
}

if ('' !== $remaining) {
Expand Down
28 changes: 28 additions & 0 deletions Tests/PropertyPathTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,34 @@ public function testGetParentWithDot()
$this->assertEquals(new PropertyPath('grandpa.parent'), $propertyPath->getParent());
}

public function testGetElementsWithEscapedDot()
{
$propertyPath = new PropertyPath('grandpa\.parent.child');

$this->assertEquals(['grandpa.parent', 'child'], $propertyPath->getElements());
}

public function testGetElementsWithEscapedArray()
{
$propertyPath = new PropertyPath('grandpa\[parent][child]');

$this->assertEquals(['grandpa[parent]', 'child'], $propertyPath->getElements());
}

public function testGetElementsWithDoubleEscapedDot()
{
$propertyPath = new PropertyPath('grandpa\\\.par\ent.\\\child');

$this->assertEquals(['grandpa\\', 'par\ent', '\\\child'], $propertyPath->getElements());
}

public function testGetElementsWithDoubleEscapedArray()
{
$propertyPath = new PropertyPath('grandpa\\\[par\ent][\\\child]');

$this->assertEquals(['grandpa\\', 'par\ent', '\\\child'], $propertyPath->getElements());
}

public function testGetParentWithIndex()
{
$propertyPath = new PropertyPath('grandpa.parent[child]');
Expand Down

0 comments on commit 9b6013a

Please sign in to comment.