From 7d812442b1cc5efdd4bba5a5f3d40c3e12545886 Mon Sep 17 00:00:00 2001 From: Coleman Watts Date: Wed, 23 May 2018 13:42:59 -0600 Subject: [PATCH] Add utils for finding nested array items --- CRM/Utils/Array.php | 45 ++++++++++++++++++ tests/phpunit/CRM/Utils/ArrayTest.php | 68 +++++++++++++++++++++++++++ 2 files changed, 113 insertions(+) diff --git a/CRM/Utils/Array.php b/CRM/Utils/Array.php index 089ab66205..4829078fc0 100644 --- a/CRM/Utils/Array.php +++ b/CRM/Utils/Array.php @@ -1152,4 +1152,49 @@ class CRM_Utils_Array { return NULL; } + /** + * Check if a key isset which may be several layers deep. + * + * This is a helper for when the calling function does not know how many layers deep the + * path array is so cannot easily check. + * + * @param array $array + * @param array $path + * @return bool + * @throws \CRM_Core_Exception + */ + public static function recursiveIsset($array, $path) { + foreach ($path as $key) { + if (!is_array($array) || !isset($array[$key])) { + return FALSE; + } + $array = $array[$key]; + } + return TRUE; + } + + /** + * Check if a key isset which may be several layers deep. + * + * This is a helper for when the calling function does not know how many layers deep the + * path array is so cannot easily check. + * + * @param array $array + * @param array $path + * An array of keys - e.g [0, 'bob', 8] where we want to check if $array[0]['bob'][8] + * @param mixed $default + * Value to return if not found. + * @return bool + * @throws \CRM_Core_Exception + */ + public static function recursiveValue($array, $path, $default = NULL) { + foreach ($path as $key) { + if (!is_array($array) || !isset($array[$key])) { + return $default; + } + $array = $array[$key]; + } + return $array; + } + } diff --git a/tests/phpunit/CRM/Utils/ArrayTest.php b/tests/phpunit/CRM/Utils/ArrayTest.php index 852a99a844..1c32c0c681 100644 --- a/tests/phpunit/CRM/Utils/ArrayTest.php +++ b/tests/phpunit/CRM/Utils/ArrayTest.php @@ -230,4 +230,72 @@ class CRM_Utils_ArrayTest extends CiviUnitTestCase { } } + public function getRecursiveIssetExamples() { + return [ + [ + [[[], [0, 1, 2], []]], [0, 1, 2], TRUE, + ], + [ + [[[], [0, 1, 2], []]], [0, 1, 3], FALSE, + ], + [ + [], ['foo'], FALSE, + ], + [ + [NULL, ['wrong' => NULL, 'right' => ['foo' => 1, 'bar' => 2]]], [1, 'wrong'], FALSE, + ], + [ + [NULL, ['wrong' => NULL, 'right' => ['foo' => 1, 'bar' => 2]]], [1, 'right'], TRUE, + ], + [ + [NULL, ['wrong' => NULL, 'right' => ['foo' => 1, 'bar' => 2]]], [1, 'right', 'foo'], TRUE, + ], + ]; + } + + /** + * @param $array + * @param $path + * @param $expected + * @dataProvider getRecursiveIssetExamples + */ + public function testRecursiveIsset($array, $path, $expected) { + $result = CRM_Utils_Array::recursiveIsset($array, $path); + $this->assertEquals($expected, $result); + } + + public function getRecursiveValueExamples() { + return [ + [ + [[[], [0, 1, 2], []]], [0, 1, 2], NULL, 2, + ], + [ + [[[], [0, 1, 2], []]], [0, 1, 3], NULL, NULL, + ], + [ + [], ['foo'], FALSE, FALSE, + ], + [ + [NULL, ['wrong' => NULL, 'right' => ['foo' => 1, 'bar' => 2]]], [1, 'wrong'], 'nada', 'nada', + ], + [ + [NULL, ['wrong' => NULL, 'right' => ['foo' => 1, 'bar' => 2]]], [1, 'right'], NULL, ['foo' => 1, 'bar' => 2] + ], + [ + [NULL, ['wrong' => NULL, 'right' => ['foo' => 1, 'bar' => 2]]], [1, 'right', 'foo'], NULL, 1, + ], + ]; + } + + /** + * @param $array + * @param $path + * @param $expected + * @dataProvider getRecursiveValueExamples + */ + public function testRecursiveValue($array, $path, $default, $expected) { + $result = CRM_Utils_Array::recursiveValue($array, $path, $default); + $this->assertEquals($expected, $result); + } + } -- 2.25.1