Add experimental setting `enableBackgroundQueue`
[civicrm-core.git] / CRM / Core / PseudoConstant.php
index 494201eaa68fd2f587ad0448e2ea8c5865ad1554..ca7189dc3179f164d9dc47164e4586f61fd5b931 100644 (file)
@@ -162,8 +162,7 @@ class CRM_Core_PseudoConstant {
    * @param string $fieldName
    * @param array $params
    * - name       string  name of the option group
-   * - flip       boolean results are return in id => label format if false
-   *                            if true, the results are reversed
+   * - flip       DEPRECATED
    * - grouping   boolean if true, return the value in 'grouping' column (currently unsupported for tables other than option_value)
    * - localize   boolean if true, localize the results before returning
    * - condition  string|array add condition(s) to the sql query - will be concatenated using 'AND'
@@ -226,6 +225,7 @@ class CRM_Core_PseudoConstant {
       // if callback is specified..
       if (!empty($pseudoconstant['callback'])) {
         $fieldOptions = call_user_func(Civi\Core\Resolver::singleton()->get($pseudoconstant['callback']), $context, $params);
+        $fieldOptions = self::formatArrayOptions($context, $fieldOptions);
         //CRM-18223: Allow additions to field options via hook.
         CRM_Utils_Hook::fieldOptions($entity, $fieldName, $fieldOptions, $params);
         return $fieldOptions;
@@ -255,10 +255,10 @@ class CRM_Core_PseudoConstant {
           $params['grouping'],
           $params['localize'],
           $params['condition'] ? ' AND ' . implode(' AND ', (array) $params['condition']) : NULL,
-          $params['labelColumn'] ? $params['labelColumn'] : 'label',
+          $params['labelColumn'] ?: 'label',
           $params['onlyActive'],
           $params['fresh'],
-          $params['keyColumn'] ? $params['keyColumn'] : 'value',
+          $params['keyColumn'] ?: 'value',
           !empty($params['orderColumn']) ? $params['orderColumn'] : 'weight'
         );
         CRM_Utils_Hook::fieldOptions($entity, $fieldName, $options, $params);
@@ -1586,4 +1586,36 @@ WHERE  id = %1
     return $output;
   }
 
+  /**
+   * Convert multidimensional option list to flat array, if necessary
+   *
+   * Detect if an array of options is simple key/value pairs or a multidimensional array.
+   * If the latter, convert to a flat array, as determined by $context.
+   *
+   * @param string|null $context
+   *   See https://docs.civicrm.org/dev/en/latest/framework/pseudoconstant/#context
+   * @param array $options
+   *   List of options, each as a record of id+name+label.
+   *   Ex: [['id' => 123, 'name' => 'foo_bar', 'label' => 'Foo Bar']]
+   */
+  public static function formatArrayOptions($context, array &$options) {
+    // Already flat; return keys/values according to context
+    if (!isset($options[0]) || !is_array($options[0])) {
+      // For validate context, machine names are expected in place of labels.
+      // A flat array has no names so use the ids for both key and value.
+      return $context === 'validate' ?
+        array_combine(array_keys($options), array_keys($options)) :
+        $options;
+    }
+    $result = [];
+    $key = ($context === 'match') ? 'name' : 'id';
+    $value = ($context === 'validate') ? 'name' : (($context === 'abbreviate') ? 'abbr' : 'label');
+    foreach ($options as $option) {
+      // Some fallbacks in case the array is missing a 'name' or 'label' or 'abbr'
+      $id = $option[$key] ?? $option['id'] ?? $option['name'];
+      $result[$id] = $option[$value] ?? $option['label'] ?? $option['name'];
+    }
+    return $result;
+  }
+
 }