Add utils for finding nested array items
authorColeman Watts <coleman@civicrm.org>
Wed, 23 May 2018 19:42:59 +0000 (13:42 -0600)
committerColeman Watts <coleman@civicrm.org>
Wed, 23 May 2018 19:42:59 +0000 (13:42 -0600)
CRM/Utils/Array.php
tests/phpunit/CRM/Utils/ArrayTest.php

index 089ab662052e60dc9ffdc2ddb499a3abb061fafb..4829078fc043dabbe7eceacc001bc6c5abf894e4 100644 (file)
@@ -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;
+  }
+
 }
index 852a99a844a8d9e1b1eb16540e574aa013f30c6c..1c32c0c681328ead1978be7d32863becbc11bd01 100644 (file)
@@ -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);
+  }
+
 }