Skip to content

Commit

Permalink
TASK: Enable escaping of string path in Arrays::getValueByPath
Browse files Browse the repository at this point in the history
It is now possible to escape the dot in the path of Arrays::getValueByPath.
With this you get array keys, which have a dot.

Example:
```
$foo = ['bar.baz' => 'value'];
$path = 'bar\.baz';
```
  • Loading branch information
gerdemann committed Jan 31, 2020
1 parent 1ee9122 commit ca00646
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 1 deletion.
26 changes: 25 additions & 1 deletion Neos.Utility.Arrays/Classes/Arrays.php
Expand Up @@ -194,7 +194,31 @@ public static function array_reduce(array $array, string $function, $initial = n
public static function getValueByPath(array &$array, $path)
{
if (is_string($path)) {
$path = explode('.', $path);
if (strpos($path, '\\.') === -1) {
$path = explode('.', $path);
} else {
$pattern = '#(?<!\\\\)((?:\\\\\\\\)*)\\.#';
$split = preg_split($pattern, $path, -1, PREG_SPLIT_NO_EMPTY|PREG_SPLIT_DELIM_CAPTURE);
$split = array_reduce(
$split,
static function ($result, $value) {
$lastIndex = count($result) - 1;
if ($lastIndex >= 0 && preg_match('#^\\\\*$#', $value)) {
$result[$lastIndex] = $result[$lastIndex] . $value;
} else {
$result[] = $value;
}
return $result;
},
[]
);
$path = array_map(
static function ($value) {
return str_replace(['\\\\','\\.'], ['\\','.'], $value);
},
$split
);
}
} elseif (!is_array($path)) {
throw new \InvalidArgumentException('getValueByPath() expects $path to be string or array, "' . gettype($path) . '" given.', 1304950007);
}
Expand Down
24 changes: 24 additions & 0 deletions Neos.Utility.Arrays/Tests/Unit/ArraysTest.php
Expand Up @@ -80,6 +80,30 @@ public function getValueByPathReturnsTheValueOfANestedArrayByFollowingTheGivenPa
$this->assertSame($expectedResult, $actualResult);
}

/**
* @test
*/
public function getValueByPathReturnsTheValueOfANestedArrayByFollowingTheGivenPathIfPathIsStringWithEscapedDots()
{
$path = 'Foo.Bar\.Baz.2';
$array = ['Foo' => ['Bar.Baz' => [2 => 'the value']]];
$expectedResult = 'the value';
$actualResult = Arrays::getValueByPath($array, $path);
self::assertSame($expectedResult, $actualResult);
}

/**
* @test
*/
public function getValueByPathReturnsTheValueOfANestedArrayByFollowingTheGivenPathIfPathIsStringWithBackslashes()
{
$path = 'Foo.Bar\\\\.Baz.2';
$array = ['Foo' => ['Bar\\' => ['Baz' => [2 => 'the value']]]];
$expectedResult = 'the value';
$actualResult = Arrays::getValueByPath($array, $path);
self::assertSame($expectedResult, $actualResult);
}

/**
* @test
* @expectedException \InvalidArgumentException
Expand Down

0 comments on commit ca00646

Please sign in to comment.