Develop 'context' param in BAO and api CRM-12464
authorColeman Watts <coleman@civicrm.org>
Tue, 11 Jun 2013 21:50:47 +0000 (14:50 -0700)
committerColeman Watts <coleman@civicrm.org>
Tue, 11 Jun 2013 21:50:47 +0000 (14:50 -0700)
----------------------------------------
* CRM-12464: Add PseudoConstants to Schema Metadata
  http://issues.civicrm.org/jira/browse/CRM-12464

CRM/Contact/BAO/Contact.php
CRM/Core/BAO/Address.php
CRM/Core/DAO.php
CRM/Core/OptionGroup.php
CRM/Core/PseudoConstant.php
CRM/Financial/BAO/PaymentProcessorType.php
api/v3/Generic.php
api/v3/utils.php

index 7e4eb08432488383e9446b0cd678dc07b4376fc2..ea9238937bff9f9ab7bcde08fcb9d2db1b03e6ac 100644 (file)
@@ -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);
   }
 
   /**
index ac90857042fed5dd7ffdb19a584dcd5778f0e439..53131f3ee8484cee433601666c5540d57fc3fd81 100644 (file)
@@ -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);
   }
 }
index 697a671fa857d0c3bdbec4ea4e3e55c27f34555f..c79489ec1fb55458dc9df87b4ab2fae27a0f1993 100644 (file)
@@ -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;
+  }
+
 }
 
index 4008a3ee830091e4ba532654c7c480bbaede5808..33251b38aca23ef2cbde174980c6563995571dfb 100644 (file)
@@ -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);
 
index 3d0366106b12e40bf02e5fe5ee23d37afb9cc3b4..6eb653b0babe418fa6cbb54150e040a2cdcef5e3 100644 (file)
@@ -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']);
index d645b0969954273b244883e5cf5bed03722dd5a8..ee789920dbaa72ef9ade2be4c0d3d877594836c3 100644 (file)
@@ -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);
   }
 }
 
index 77713a3e420bd8aeed391816b77d1b7451c5a4c2..9c62f9d01a2a8b8af9301df0aa85e524ddf8c012 100644 (file)
@@ -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.");
   }
index 9b4d47bf72a1852cc7e783feada1a79cfc186955..a5fd74c35b7063c330654604c2e9b1223579243d 100644 (file)
@@ -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());
   }