CRM-14423 - Extract class CRM_Utils_Check from CRM_Utils_Check_Security
[civicrm-core.git] / CRM / Utils / Array.php
index 296f470a0024e07105bd12c6a882cd0b6f39f746..575c0e66b880594f254cbab8145633d0c5ebe319 100644 (file)
@@ -519,7 +519,7 @@ class CRM_Utils_Array {
         } else {
           $keyvalue = $record->{$key};
         }
-        if (!is_array($node[$keyvalue])) {
+        if (isset($node[$keyvalue]) && !is_array($node[$keyvalue])) {
           $node[$keyvalue] = array();
         }
         $node = &$node[$keyvalue];
@@ -635,5 +635,48 @@ class CRM_Utils_Array {
     }
     return $default;
   }
+
+  /**
+   * Generate the Cartesian product of zero or more vectors
+   *
+   * @param array $dimensions list of dimensions to multiply; each key is a dimension name; each value is a vector
+   * @param array $template a base set of values included in every output
+   * @return array each item is a distinct combination of values from $dimensions
+   *
+   * For example, the product of
+   * {
+   *   fg => {red, blue},
+   *   bg => {white, black}
+   * }
+   * would be
+   * {
+   *   {fg => red, bg => white},
+   *   {fg => red, bg => black},
+   *   {fg => blue, bg => white},
+   *   {fg => blue, bg => black}
+   * }
+   */
+  static function product($dimensions, $template = array()) {
+    if (empty($dimensions)) {
+      return array($template);
+    }
+
+    foreach ($dimensions as $key => $value) {
+      $firstKey = $key;
+      $firstValues = $value;
+      break;
+    }
+    unset($dimensions[$key]);
+
+    $results = array();
+    foreach ($firstValues as $firstValue) {
+      foreach (self::product($dimensions, $template) as $result) {
+        $result[$firstKey] = $firstValue;
+        $results[] = $result;
+      }
+    }
+
+    return $results;
+  }
 }