Merge pull request #17033 from seamuslee001/5.25
[civicrm-core.git] / CRM / Core / PseudoConstant.php
index 2655544aafae072ded92aa4f3830b60dafe04c70..afbb0b5fbb4120b2515db85bd44c6f5d191809dd 100644 (file)
@@ -185,12 +185,12 @@ class CRM_Core_PseudoConstant {
     // Historically this was 'false' but according to the notes in
     // CRM_Core_DAO::buildOptionsContext it should be context dependent.
     // timidly changing for 'search' only to fix world_region in search options.
-    $localizeDefault = in_array($context, ['search']) ? TRUE : FALSE;
+    $localizeDefault = in_array($context, ['search']);
     // Merge params with defaults
     $params += [
       'grouping' => FALSE,
       'localize' => $localizeDefault,
-      'onlyActive' => ($context == 'validate' || $context == 'get') ? FALSE : TRUE,
+      'onlyActive' => !($context == 'validate' || $context == 'get'),
       'fresh' => FALSE,
       'context' => $context,
     ];
@@ -211,15 +211,15 @@ class CRM_Core_PseudoConstant {
     $dao = new $daoName();
     $fieldSpec = $dao->getFieldSpec($fieldName);
 
-    // Ensure we have the canonical name for this field
-    $fieldName = CRM_Utils_Array::value('name', $fieldSpec, $fieldName);
-
     // Return false if field doesn't exist.
     if (empty($fieldSpec)) {
       return FALSE;
     }
 
-    elseif (!empty($fieldSpec['pseudoconstant'])) {
+    // Ensure we have the canonical name for this field
+    $fieldName = $fieldSpec['name'] ?? $fieldName;
+
+    if (!empty($fieldSpec['pseudoconstant'])) {
       $pseudoconstant = $fieldSpec['pseudoconstant'];
 
       // if callback is specified..
@@ -232,9 +232,9 @@ class CRM_Core_PseudoConstant {
 
       // Merge params with schema defaults
       $params += [
-        'condition' => CRM_Utils_Array::value('condition', $pseudoconstant, []),
-        'keyColumn' => CRM_Utils_Array::value('keyColumn', $pseudoconstant),
-        'labelColumn' => CRM_Utils_Array::value('labelColumn', $pseudoconstant),
+        'condition' => $pseudoconstant['condition'] ?? [],
+        'keyColumn' => $pseudoconstant['keyColumn'] ?? NULL,
+        'labelColumn' => $pseudoconstant['labelColumn'] ?? NULL,
       ];
 
       // Fetch option group from option_value table
@@ -264,103 +264,16 @@ class CRM_Core_PseudoConstant {
 
       // Fetch options from other tables
       if (!empty($pseudoconstant['table'])) {
-        // Normalize params so the serialized cache string will be consistent.
         CRM_Utils_Array::remove($params, 'flip', 'fresh');
+        // Normalize params so the serialized cache string will be consistent.
         ksort($params);
         $cacheKey = $daoName . $fieldName . serialize($params);
-
         // Retrieve cached options
         if (isset(\Civi::$statics[__CLASS__][$cacheKey]) && empty($params['fresh'])) {
           $output = \Civi::$statics[__CLASS__][$cacheKey];
         }
         else {
-          $daoName = CRM_Core_DAO_AllCoreTables::getClassForTable($pseudoconstant['table']);
-          if (!class_exists($daoName)) {
-            return FALSE;
-          }
-          // Get list of fields for the option table
-          $dao = new $daoName();
-          $availableFields = array_keys($dao->fieldKeys());
-
-          $select = "SELECT %1 AS id, %2 AS label";
-          $from = "FROM %3";
-          $wheres = [];
-          $order = "ORDER BY %2";
-
-          // Use machine name in certain contexts
-          if ($context == 'validate' || $context == 'match') {
-            $nameField = $context == 'validate' ? 'labelColumn' : 'keyColumn';
-            if (!empty($pseudoconstant['nameColumn'])) {
-              $params[$nameField] = $pseudoconstant['nameColumn'];
-            }
-            elseif (in_array('name', $availableFields)) {
-              $params[$nameField] = 'name';
-            }
-          }
-
-          // Use abbrColum if context is abbreviate
-          if ($context == 'abbreviate' && (in_array('abbreviation', $availableFields) || !empty($pseudoconstant['abbrColumn']))) {
-            $params['labelColumn'] = $pseudoconstant['abbrColumn'] ?? 'abbreviation';
-          }
-
-          // Condition param can be passed as an sql clause string or an array of clauses
-          if (!empty($params['condition'])) {
-            $wheres[] = implode(' AND ', (array) $params['condition']);
-          }
-          // onlyActive param will automatically filter on common flags
-          if (!empty($params['onlyActive'])) {
-            foreach (['is_active' => 1, 'is_deleted' => 0, 'is_test' => 0, 'is_hidden' => 0] as $flag => $val) {
-              if (in_array($flag, $availableFields)) {
-                $wheres[] = "$flag = $val";
-              }
-            }
-          }
-          // Filter domain specific options
-          if (in_array('domain_id', $availableFields)) {
-            $wheres[] = 'domain_id = ' . CRM_Core_Config::domainID();
-          }
-          $queryParams = [
-            1 => [$params['keyColumn'], 'String', CRM_Core_DAO::QUERY_FORMAT_NO_QUOTES],
-            2 => [$params['labelColumn'], 'String', CRM_Core_DAO::QUERY_FORMAT_NO_QUOTES],
-            3 => [$pseudoconstant['table'], 'String', CRM_Core_DAO::QUERY_FORMAT_NO_QUOTES],
-          ];
-          // Add orderColumn param
-          if (!empty($params['orderColumn'])) {
-            $queryParams[4] = [$params['orderColumn'], 'String', CRM_Core_DAO::QUERY_FORMAT_NO_QUOTES];
-            $order = "ORDER BY %4";
-          }
-          // Support no sorting if $params[orderColumn] is FALSE
-          elseif (isset($params['orderColumn']) && $params['orderColumn'] === FALSE) {
-            $order = '';
-          }
-          // Default to 'weight' if that column exists
-          elseif (in_array('weight', $availableFields)) {
-            $order = "ORDER BY weight";
-          }
-
-          $output = [];
-          $query = "$select $from";
-          if ($wheres) {
-            $query .= " WHERE " . implode($wheres, ' AND ');
-          }
-          $query .= ' ' . $order;
-          $dao = CRM_Core_DAO::executeQuery($query, $queryParams);
-          while ($dao->fetch()) {
-            $output[$dao->id] = $dao->label;
-          }
-          // Localize results
-          if (!empty($params['localize']) || $pseudoconstant['table'] == 'civicrm_country' || $pseudoconstant['table'] == 'civicrm_state_province') {
-            $I18nParams = [];
-            if (isset($fieldSpec['localize_context'])) {
-              $I18nParams['context'] = $fieldSpec['localize_context'];
-            }
-            $i18n = CRM_Core_I18n::singleton();
-            $i18n->localizeArray($output, $I18nParams);
-            // Maintain sort by label
-            if ($order == "ORDER BY %2") {
-              $output = CRM_Utils_Array::asort($output);
-            }
-          }
+          $output = self::renderOptionsFromTablePseudoconstant($pseudoconstant, $params, ($fieldSpec['localize_context'] ?? NULL), $context);
           CRM_Utils_Hook::fieldOptions($entity, $fieldName, $output, $params);
           \Civi::$statics[__CLASS__][$cacheKey] = $output;
         }
@@ -397,7 +310,7 @@ class CRM_Core_PseudoConstant {
     if ($values === FALSE) {
       return FALSE;
     }
-    return CRM_Utils_Array::value($key, $values);
+    return $values[$key] ?? NULL;
   }
 
   /**
@@ -417,7 +330,7 @@ class CRM_Core_PseudoConstant {
     if ($values === FALSE) {
       return FALSE;
     }
-    return CRM_Utils_Array::value($key, $values);
+    return $values[$key] ?? NULL;
   }
 
   /**
@@ -824,7 +737,7 @@ WHERE  id = %1";
         $countryIsoCodes = self::countryIsoCode();
         $defaultID = array_search(CRM_Core_BAO_Country::defaultContactCountry(), $countryIsoCodes);
         if ($defaultID !== FALSE) {
-          $default[$defaultID] = CRM_Utils_Array::value($defaultID, self::$country);
+          $default[$defaultID] = self::$country[$defaultID] ?? NULL;
           self::$country = $default + self::$country;
         }
       }
@@ -1393,7 +1306,7 @@ WHERE  id = %1
     $index = $filter['greeting_type'] . '_' . $columnName;
 
     // also add contactType to the array
-    $contactType = CRM_Utils_Array::value('contact_type', $filter);
+    $contactType = $filter['contact_type'] ?? NULL;
     if ($contactType) {
       $index .= '_' . $contactType;
     }
@@ -1478,7 +1391,7 @@ WHERE  id = %1
       self::$accountOptionValues[$cacheKey] = CRM_Core_OptionGroup::values($optionGroupName, FALSE, FALSE, FALSE, $condition);
     }
     if ($id) {
-      return CRM_Utils_Array::value($id, self::$accountOptionValues[$cacheKey]);
+      return self::$accountOptionValues[$cacheKey][$id] ?? NULL;
     }
 
     return self::$accountOptionValues[$cacheKey];
@@ -1557,4 +1470,109 @@ WHERE  id = %1
     ];
   }
 
+  /**
+   * Render the field options from the available pseudoconstant.
+   *
+   * Do not call this function directly or from untested code. Further cleanup is likely.
+   *
+   * @param array $pseudoconstant
+   * @param array $params
+   * @param string|null $localizeContext
+   * @param string $context
+   *
+   * @return array|bool|mixed
+   */
+  public static function renderOptionsFromTablePseudoconstant($pseudoconstant, &$params = [], $localizeContext = NULL, $context = '') {
+    $daoName = CRM_Core_DAO_AllCoreTables::getClassForTable($pseudoconstant['table']);
+    if (!class_exists($daoName)) {
+      return FALSE;
+    }
+    // Get list of fields for the option table
+    /* @var CRM_Core_DAO $dao * */
+    $dao = new $daoName();
+    $availableFields = array_keys($dao->fieldKeys());
+
+    $select = 'SELECT %1 AS id, %2 AS label';
+    $from = 'FROM %3';
+    $wheres = [];
+    $order = 'ORDER BY %2';
+
+    // Use machine name in certain contexts
+    if ($context === 'validate' || $context === 'match') {
+      $nameField = $context === 'validate' ? 'labelColumn' : 'keyColumn';
+      if (!empty($pseudoconstant['nameColumn'])) {
+        $params[$nameField] = $pseudoconstant['nameColumn'];
+      }
+      elseif (in_array('name', $availableFields)) {
+        $params[$nameField] = 'name';
+      }
+    }
+
+    // Use abbrColum if context is abbreviate
+    if ($context === 'abbreviate' && (in_array('abbreviation', $availableFields) || !empty($pseudoconstant['abbrColumn']))) {
+      $params['labelColumn'] = $pseudoconstant['abbrColumn'] ?? 'abbreviation';
+    }
+
+    // Condition param can be passed as an sql clause string or an array of clauses
+    if (!empty($params['condition'])) {
+      $wheres[] = implode(' AND ', (array) $params['condition']);
+    }
+    // onlyActive param will automatically filter on common flags
+    if (!empty($params['onlyActive'])) {
+      foreach (['is_active' => 1, 'is_deleted' => 0, 'is_test' => 0, 'is_hidden' => 0] as $flag => $val) {
+        if (in_array($flag, $availableFields)) {
+          $wheres[] = "$flag = $val";
+        }
+      }
+    }
+    // Filter domain specific options
+    if (in_array('domain_id', $availableFields)) {
+      $wheres[] = 'domain_id = ' . CRM_Core_Config::domainID();
+    }
+    $queryParams = [
+      1 => [$params['keyColumn'], 'String', CRM_Core_DAO::QUERY_FORMAT_NO_QUOTES],
+      2 => [$params['labelColumn'], 'String', CRM_Core_DAO::QUERY_FORMAT_NO_QUOTES],
+      3 => [$pseudoconstant['table'], 'String', CRM_Core_DAO::QUERY_FORMAT_NO_QUOTES],
+    ];
+    // Add orderColumn param
+    if (!empty($params['orderColumn'])) {
+      $queryParams[4] = [$params['orderColumn'], 'String', CRM_Core_DAO::QUERY_FORMAT_NO_QUOTES];
+      $order = 'ORDER BY %4';
+    }
+    // Support no sorting if $params[orderColumn] is FALSE
+    elseif (isset($params['orderColumn']) && $params['orderColumn'] === FALSE) {
+      $order = '';
+    }
+    // Default to 'weight' if that column exists
+    elseif (in_array('weight', $availableFields)) {
+      $order = "ORDER BY weight";
+    }
+
+    $output = [];
+    $query = "$select $from";
+    if ($wheres) {
+      $query .= " WHERE " . implode($wheres, ' AND ');
+    }
+    $query .= ' ' . $order;
+    $dao = CRM_Core_DAO::executeQuery($query, $queryParams);
+    while ($dao->fetch()) {
+      $output[$dao->id] = $dao->label;
+    }
+    // Localize results
+    if (!empty($params['localize']) || $pseudoconstant['table'] === 'civicrm_country' || $pseudoconstant['table'] === 'civicrm_state_province') {
+      $I18nParams = [];
+      if ($localizeContext) {
+        $I18nParams['context'] = $localizeContext;
+      }
+      $i18n = CRM_Core_I18n::singleton();
+      $i18n->localizeArray($output, $I18nParams);
+      // Maintain sort by label
+      if ($order === 'ORDER BY %2') {
+        $output = CRM_Utils_Array::asort($output);
+      }
+    }
+
+    return $output;
+  }
+
 }