From 786ad6e16cb6c58f5d55aad2f8d42a2574a0852f Mon Sep 17 00:00:00 2001 From: Coleman Watts Date: Tue, 11 Jun 2013 14:50:47 -0700 Subject: [PATCH] Develop 'context' param in BAO and api CRM-12464 ---------------------------------------- * CRM-12464: Add PseudoConstants to Schema Metadata http://issues.civicrm.org/jira/browse/CRM-12464 --- CRM/Contact/BAO/Contact.php | 2 +- CRM/Core/BAO/Address.php | 10 ++-- CRM/Core/DAO.php | 24 ++++++++- CRM/Core/OptionGroup.php | 19 +++++--- CRM/Core/PseudoConstant.php | 57 ++++++++++++++-------- CRM/Financial/BAO/PaymentProcessorType.php | 2 +- api/v3/Generic.php | 17 +++++-- api/v3/utils.php | 2 +- 8 files changed, 91 insertions(+), 42 deletions(-) diff --git a/CRM/Contact/BAO/Contact.php b/CRM/Contact/BAO/Contact.php index 7e4eb08432..ea9238937b 100644 --- a/CRM/Contact/BAO/Contact.php +++ b/CRM/Contact/BAO/Contact.php @@ -3011,7 +3011,7 @@ LEFT JOIN civicrm_address add2 ON ( add1.master_id = add2.id ) } break; } - return CRM_Core_PseudoConstant::get(__CLASS__, $fieldName, $params); + return CRM_Core_PseudoConstant::get(__CLASS__, $fieldName, $params, $context); } /** diff --git a/CRM/Core/BAO/Address.php b/CRM/Core/BAO/Address.php index ac90857042..53131f3ee8 100644 --- a/CRM/Core/BAO/Address.php +++ b/CRM/Core/BAO/Address.php @@ -1182,9 +1182,11 @@ SELECT is_primary, break; // Filter country list based on site defaults case 'country_id': - $config = CRM_Core_Config::singleton(); - if (!empty($config->countryLimit) && is_array($config->countryLimit)) { - $params['condition'] = 'id IN (' . implode(',', $config->countryLimit) . ')'; + if ($context != 'get' && $context != 'validate') { + $config = CRM_Core_Config::singleton(); + if (!empty($config->countryLimit) && is_array($config->countryLimit)) { + $params['condition'] = 'id IN (' . implode(',', $config->countryLimit) . ')'; + } } break; // Filter county list based on chosen state @@ -1194,6 +1196,6 @@ SELECT is_primary, } break; } - return CRM_Core_PseudoConstant::get(__CLASS__, $fieldName, $params); + return CRM_Core_PseudoConstant::get(__CLASS__, $fieldName, $params, $context); } } diff --git a/CRM/Core/DAO.php b/CRM/Core/DAO.php index 697a671fa8..c79489ec1f 100644 --- a/CRM/Core/DAO.php +++ b/CRM/Core/DAO.php @@ -1764,13 +1764,33 @@ EOS; * The overriding function will generally call the lower-level CRM_Core_PseudoConstant::get * * @param String $fieldName - * @param String $context: e.g. "search" "edit" "create" "view" + * @param String $context: e.g. "search" "get" "create" "validate" * @param Array $props: whatever is known about this bao object */ public static function buildOptions($fieldName, $context = NULL, $props = array()) { // If a given bao does not override this function $baoName = get_called_class(); - return CRM_Core_PseudoConstant::get($baoName, $fieldName); + return CRM_Core_PseudoConstant::get($baoName, $fieldName, array(), $context); } + + /** + * Provides documentation and validation for the buildOptions $context param + * + * @param String $context + */ + public static function buildOptionsContext($context = NULL) { + $contexts = array( + 'get' => "All options are returned, even if they are disabled. Labels are translated.", + 'create' => "Options are filtered appropriately for the object being created/updated. Labels are translated.", + 'search' => "Searchable options are returned. Labels are translated.", + 'validate' => "All options are returned, even if they are disabled. Machine names are used in place of labels.", + ); + // Validation: enforce uniformity of this param + if ($context !== NULL && !isset($contexts[$context])) { + throw new exception("'$context' is not a valid context for buildOptions."); + } + return $contexts; + } + } diff --git a/CRM/Core/OptionGroup.php b/CRM/Core/OptionGroup.php index 4008a3ee83..33251b38ac 100644 --- a/CRM/Core/OptionGroup.php +++ b/CRM/Core/OptionGroup.php @@ -193,13 +193,15 @@ WHERE v.option_group_id = g.id * @static * @void */ - static function &valuesByID($id, $flip = FALSE, $grouping = FALSE, $localize = FALSE, $labelColumnName = 'label') { - $cacheKey = "CRM_OG_ID_{$id}_{$flip}_{$grouping}_{$localize}_{$labelColumnName}"; + static function &valuesByID($id, $flip = FALSE, $grouping = FALSE, $localize = FALSE, $labelColumnName = 'label', $onlyActive = TRUE, $fresh = FALSE) { + $cacheKey = self::createCacheKey($id, $flip, $grouping, $localize, $labelColumnName, $onlyActive); $cache = CRM_Utils_Cache::singleton(); - $var = $cache->get($cacheKey); - if ($var) { - return $var; + if (!$fresh) { + $var = $cache->get($cacheKey); + if ($var) { + return $var; + } } $query = " SELECT v.{$labelColumnName} as {$labelColumnName} ,v.value as value, v.grouping as grouping @@ -207,10 +209,13 @@ FROM civicrm_option_value v, civicrm_option_group g WHERE v.option_group_id = g.id AND g.id = %1 - AND v.is_active = 1 AND g.is_active = 1 - ORDER BY v.weight, v.label; "; + if ($onlyActive) { + $query .= " AND v.is_active = 1 "; + } + $query .= " ORDER BY v.weight, v.label"; + $p = array(1 => array($id, 'Integer')); $dao = CRM_Core_DAO::executeQuery($query, $p); diff --git a/CRM/Core/PseudoConstant.php b/CRM/Core/PseudoConstant.php index 3d0366106b..6eb653b0ba 100644 --- a/CRM/Core/PseudoConstant.php +++ b/CRM/Core/PseudoConstant.php @@ -220,26 +220,40 @@ class CRM_Core_PseudoConstant { * - orderColumn string the column to use for sorting, defaults to 'weight' column if one exists, else defaults to labelColumn * - onlyActive boolean return only the action option values * - fresh boolean ignore cache entries and go back to DB + * @param String $context: Context string * * @return Array on success, FALSE on error. * * @static */ - public static function get($daoName, $fieldName, $params = array()) { + public static function get($daoName, $fieldName, $params = array(), $context = NULL) { + CRM_Core_DAO::buildOptionsContext($context); $flip = !empty($params['flip']); + // Merge params with defaults + $params += array( + 'grouping' => FALSE, + 'localize' => FALSE, + 'onlyActive' => ($context == 'validate' || $context == 'create') ? FALSE : TRUE, + 'fresh' => FALSE, + ); // Custom fields are not in the schema - if (strpos($fieldName, 'custom') === 0 && is_numeric($fieldName[7])) { - $dao = new CRM_Core_DAO_CustomField; - $dao->id = (int) substr($fieldName, 7); - $dao->find(TRUE); - $customField = (array) $dao; - $dao->free(); - $output = array(); - CRM_Core_BAO_CustomField::buildOption($customField, $output); - // @see FIXME note in CRM_Core_BAO_CustomField::buildOption() - unset($output['attributes']); - return $flip ? array_flip($output) : $output; + if (strpos($fieldName, 'custom_') === 0 && is_numeric($fieldName[7])) { + $customFieldID = (int) substr($fieldName, 7); + $optionGroupID = CRM_Core_DAO::getFieldValue('CRM_Core_DAO_CustomField', $customFieldID, 'option_group_id'); + + $options = CRM_Core_OptionGroup::valuesByID($optionGroupID, + $flip, + $params['grouping'], + $params['localize'], + // Note: for custom fields the 'name' column is NULL + CRM_Utils_Array::value('labelColumn', $params, 'label'), + $params['onlyActive'], + $params['fresh'] + ); + + CRM_Utils_Hook::customFieldOptions($customFieldID, $options, FALSE); + return $options; } // Core field: load schema @@ -263,19 +277,18 @@ class CRM_Core_PseudoConstant { elseif (!empty($fieldSpec['pseudoconstant'])) { $pseudoconstant = $fieldSpec['pseudoconstant']; - // Merge params with defaults + // Merge params with schema defaults $params += array( - 'grouping' => FALSE, - 'localize' => FALSE, - 'condition' => CRM_Utils_Array::value('condition', $pseudoconstant), + 'condition' => CRM_Utils_Array::value('condition', $pseudoconstant, array()), 'keyColumn' => CRM_Utils_Array::value('keyColumn', $pseudoconstant), 'labelColumn' => CRM_Utils_Array::value('labelColumn', $pseudoconstant), - 'onlyActive' => TRUE, - 'fresh' => FALSE, ); // Fetch option group from option_value table if(!empty($pseudoconstant['optionGroupName'])) { + if ($context == 'validate') { + $params['labelColumn'] = 'name'; + } // Call our generic fn for retrieving from the option_value table return CRM_Core_OptionGroup::values( $pseudoconstant['optionGroupName'], @@ -309,15 +322,17 @@ class CRM_Core_PseudoConstant { // Get list of fields for the option table $dao = new $daoName; $availableFields = array_keys($dao->fieldKeys()); - if (in_array('is_active', $availableFields)) { - $wheres[] = 'is_active = 1'; - } $dao->free(); $select = "SELECT %1 AS id, %2 AS label"; $from = "FROM %3"; $wheres = array(); $order = "ORDER BY %2"; + + // Use name field instead of label in validate context + if ($context == 'validate' && in_array('name', $availableFields)) { + $params['labelColumn'] = 'name'; + } // 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']); diff --git a/CRM/Financial/BAO/PaymentProcessorType.php b/CRM/Financial/BAO/PaymentProcessorType.php index d645b09699..ee789920db 100644 --- a/CRM/Financial/BAO/PaymentProcessorType.php +++ b/CRM/Financial/BAO/PaymentProcessorType.php @@ -234,7 +234,7 @@ WHERE pp.payment_processor_type_id = ppt.id AND ppt.id = %1"; CRM_Core_Payment::BILLING_MODE_NOTIFY => 'notify', ); } - return CRM_Core_PseudoConstant::get(__CLASS__, $fieldName, $params); + return CRM_Core_PseudoConstant::get(__CLASS__, $fieldName, $params, $context); } } diff --git a/api/v3/Generic.php b/api/v3/Generic.php index 77713a3e42..9c62f9d01a 100644 --- a/api/v3/Generic.php +++ b/api/v3/Generic.php @@ -90,9 +90,14 @@ function civicrm_api3_generic_getfields($apiRequest) { case 'getoptions': $metadata = array( - 'field' => array('title' => 'Field to retrieve options for', - 'api.required' => 1, - )); + 'field' => array( + 'title' => 'Field to retrieve options for', + 'api.required' => 1, + ), + 'context' => array( + 'title' => 'Context string', + ), + ); break; default: // oddballs are on their own @@ -207,9 +212,11 @@ function civicrm_api3_generic_getoptions($apiRequest) { if (!$fieldName) { return civicrm_api3_create_error("The field '{$apiRequest['params']['field']}' doesn't exist."); } + $context = CRM_Utils_Array::value('context', $apiRequest['params']); + CRM_Core_DAO::buildOptionsContext($context); - $daoName = _civicrm_api3_get_BAO($apiRequest['entity']); - $options = $daoName::buildOptions($fieldName); + $baoName = _civicrm_api3_get_BAO($apiRequest['entity']); + $options = $baoName::buildOptions($fieldName, $context); if ($options === FALSE) { return civicrm_api3_create_error("The field '{$fieldName}' has no associated option list."); } diff --git a/api/v3/utils.php b/api/v3/utils.php index 9b4d47bf72..a5fd74c35b 100644 --- a/api/v3/utils.php +++ b/api/v3/utils.php @@ -1530,7 +1530,7 @@ function _civicrm_api3_validate_string(&$params, &$fieldName, &$fieldInfo, $enti function _civicrm_api3_api_match_pseudoconstant(&$params, $entity, $fieldName, $fieldInfo) { $options = CRM_Utils_Array::value('options', $fieldInfo); if (!$options) { - $options = civicrm_api($entity, 'getoptions', array('version' => 3, 'field' => $fieldInfo['name'])); + $options = civicrm_api($entity, 'getoptions', array('version' => 3, 'field' => $fieldInfo['name'], 'context' => 'validate')); $options = CRM_Utils_Array::value('values', $options, array()); } -- 2.25.1