From 884466e66de7dd479f5968f93ff8051d183358bc Mon Sep 17 00:00:00 2001 From: Tim Otten Date: Thu, 15 Jul 2021 13:37:07 -0700 Subject: [PATCH] CRM_Utils_Array::pathMove - Add helper to move an item within array tree --- CRM/Utils/Array.php | 25 +++++++++++++++++++++++++ tests/phpunit/CRM/Utils/ArrayTest.php | 19 ++++++++++++++++++- 2 files changed, 43 insertions(+), 1 deletion(-) diff --git a/CRM/Utils/Array.php b/CRM/Utils/Array.php index 99cd769b5ddd..bbc931c38f91 100644 --- a/CRM/Utils/Array.php +++ b/CRM/Utils/Array.php @@ -1142,6 +1142,31 @@ public static function pathSet(&$values, $pathParts, $value) { $r[$last] = $value; } + /** + * Move an item in an array-tree (if it exists). + * + * @param array $values + * Data-tree + * @param string[] $src + * Old path for the existing item + * @param string[] $dest + * New path + * @param bool $cleanup + * @return int + * Number of items moved (0 or 1). + */ + public static function pathMove(&$values, $src, $dest, $cleanup = FALSE) { + if (!static::pathIsset($values, $src)) { + return 0; + } + else { + $value = static::pathGet($values, $src); + static::pathSet($values, $dest, $value); + static::pathUnset($values, $src, $cleanup); + return 1; + } + } + /** * Convert a simple dictionary into separate key+value records. * diff --git a/tests/phpunit/CRM/Utils/ArrayTest.php b/tests/phpunit/CRM/Utils/ArrayTest.php index f8b01905f086..17cc44dfbd32 100644 --- a/tests/phpunit/CRM/Utils/ArrayTest.php +++ b/tests/phpunit/CRM/Utils/ArrayTest.php @@ -159,7 +159,7 @@ public function testRemove() { } public function testGetSetPathParts() { - $arr = [ + $arr = $arrOrig = [ 'one' => '1', 'two' => [ 'half' => 2, @@ -188,6 +188,23 @@ public function testGetSetPathParts() { $this->assertEquals(['second-third' => '2/3'], $arr['three']); CRM_Utils_Array::pathUnset($arr, ['three', 'second-third'], TRUE); $this->assertFalse(array_key_exists('three', $arr)); + + // pathMove(): Change location of an item + $arr = $arrOrig; + $this->assertEquals(2, $arr['two']['half']); + $this->assertTrue(!isset($arr['verb']['double']['half'])); + $this->assertEquals(1, CRM_Utils_Array::pathMove($arr, ['two'], ['verb', 'double'])); + $this->assertEquals(2, $arr['verb']['double']['half']); + $this->assertTrue(!isset($arr['two']['half'])); + + // pathMove(): If item doesn't exist, return 0. + $arr = $arrOrig; + $this->assertTrue(!isset($arr['not-a-src'])); + $this->assertTrue(!isset($arr['not-a-dest'])); + $this->assertEquals(0, CRM_Utils_Array::pathMove($arr, ['not-a-src'], ['not-a-dest'])); + $this->assertTrue(!isset($arr['not-a-src'])); + $this->assertTrue(!isset($arr['not-a-dest'])); + } public function getSortExamples() {