optimization
[civicrm-core.git] / CRM / Core / BAO / CustomField.php
index 6555a2dcf59d0d243c79f636be269185f6062111..ae9c4023a18b806875c4058d6ceb543267825567 100644 (file)
@@ -362,6 +362,47 @@ class CRM_Core_BAO_CustomField extends CRM_Core_DAO_CustomField {
     return CRM_Core_DAO::getFieldValue('CRM_Core_DAO_CustomField', $id, 'label');
   }
 
+  /**
+   * @param string $context
+   * @return array|bool
+   */
+  public function getOptions($context = NULL) {
+    CRM_Core_DAO::buildOptionsContext($context);
+
+    if (!$this->id) {
+      return FALSE;
+    }
+    if (!$this->data_type || !$this->custom_group_id) {
+      $this->find(TRUE);
+    }
+
+    if (!empty($this->option_group_id)) {
+      $options = CRM_Core_OptionGroup::valuesByID(
+        $this->option_group_id,
+        FALSE,
+        FALSE,
+        FALSE,
+        'label',
+        !($context == 'validate' || $context == 'get')
+      );
+    }
+    elseif ($this->data_type === 'StateProvince') {
+      $options = CRM_Core_Pseudoconstant::stateProvince();
+    }
+    elseif ($this->data_type === 'Country') {
+      $options = $context == 'validate' ? CRM_Core_Pseudoconstant::countryIsoCode() : CRM_Core_Pseudoconstant::country();
+    }
+    elseif ($this->data_type === 'Boolean') {
+      $options = $context == 'validate' ? array(0, 1) : CRM_Core_SelectValues::boolean();
+    }
+    else {
+      return FALSE;
+    }
+    CRM_Utils_Hook::customFieldOptions($this->id, $options, FALSE);
+    CRM_Utils_Hook::fieldOptions($this->getEntity(), "custom_{$this->id}", $options, array('context' => $context));
+    return $options;
+  }
+
   /**
    * Store and return an array of all active custom fields.
    *
@@ -700,11 +741,11 @@ class CRM_Core_BAO_CustomField extends CRM_Core_DAO_CustomField {
    * @param int $fieldID
    *   The custom field ID.
    *
-   * @return CRM_Core_DAO_CustomField
+   * @return CRM_Core_BAO_CustomField
    *   The field object.
    */
   public static function getFieldObject($fieldID) {
-    $field = new CRM_Core_DAO_CustomField();
+    $field = new CRM_Core_BAO_CustomField();
 
     // check if we can get the field values from the system cache
     $cacheKey = "CRM_Core_DAO_CustomField_{$fieldID}";
@@ -729,33 +770,28 @@ class CRM_Core_BAO_CustomField extends CRM_Core_DAO_CustomField {
   }
 
   /**
-   * This function for building custom fields.
+   * Add a custom field to an existing form.
    *
    * @param CRM_Core_Form $qf
    *   Form object (reference).
    * @param string $elementName
    *   Name of the custom field.
    * @param int $fieldId
-   * @param bool $inactiveNeeded
-   *   -deprecated.
    * @param bool $useRequired
    *   True if required else false.
    * @param bool $search
    *   True if used for search else false.
    * @param string $label
    *   Label for custom field.
+   * @return \HTML_QuickForm_Element|null
+   * @throws \CiviCRM_API3_Exception
    */
   public static function addQuickFormElement(
-    &$qf,
-    $elementName,
-    $fieldId,
-    $inactiveNeeded = FALSE,
-    $useRequired = TRUE,
-    $search = FALSE,
-    $label = NULL
+    $qf, $elementName, $fieldId, $useRequired = TRUE, $search = FALSE, $label = NULL
   ) {
     $field = self::getFieldObject($fieldId);
     $widget = $field->html_type;
+    $element = NULL;
 
     // Custom field HTML should indicate group+field name
     $groupName = CRM_Core_DAO::getFieldValue('CRM_Core_DAO_CustomGroup', $field->custom_group_id);
@@ -784,10 +820,7 @@ class CRM_Core_BAO_CustomField extends CRM_Core_DAO_CustomField {
     )));
 
     if ($isSelect) {
-      $options = CRM_Utils_Array::value('values', civicrm_api3('contact', 'getoptions', array(
-        'field' => "custom_$fieldId",
-        'context' => $search ? 'search' : 'create',
-      ), array()));
+      $options = $field->getOptions($search ? 'search' : 'create');
 
       // Consolidate widget types to simplify the below switch statement
       if ($search || ($widget !== 'AdvMulti-Select' && strpos($widget, 'Select') !== FALSE)) {
@@ -806,8 +839,7 @@ class CRM_Core_BAO_CustomField extends CRM_Core_DAO_CustomField {
       // Add data for popup link. Normally this is handled by CRM_Core_Form->addSelect
       if ($field->option_group_id && !$search && $widget == 'Select' && CRM_Core_Permission::check('administer CiviCRM')) {
         $selectAttributes += array(
-          'data-api-entity' => 'contact',
-          // FIXME: This works because the getoptions api isn't picky about custom fields, but it's WRONG
+          'data-api-entity' => $field->getEntity(),
           'data-api-field' => 'custom_' . $field->id,
           'data-option-edit-path' => 'civicrm/admin/options/' . CRM_Core_DAO::getFieldValue('CRM_Core_DAO_OptionGroup', $field->option_group_id),
         );
@@ -828,7 +860,7 @@ class CRM_Core_BAO_CustomField extends CRM_Core_DAO_CustomField {
           $qf->add('text', $elementName . '_to', ts('To'), $field->attributes);
         }
         else {
-          $element = &$qf->add('text', $elementName, $label,
+          $element = $qf->add('text', $elementName, $label,
             $field->attributes,
             $useRequired && !$search
           );
@@ -852,7 +884,7 @@ class CRM_Core_BAO_CustomField extends CRM_Core_DAO_CustomField {
         if ($field->text_length) {
           $attributes .= ' maxlength=' . $field->text_length;
         }
-        $element = &$qf->add('textarea',
+        $element = $qf->add('textarea',
           $elementName,
           $label,
           $attributes,
@@ -861,37 +893,19 @@ class CRM_Core_BAO_CustomField extends CRM_Core_DAO_CustomField {
         break;
 
       case 'Select Date':
+        $attr = array('data-crm-custom' => $dataCrmCustomVal);
+        $params = array(
+          'date' => $field->date_format,
+          'minDate' => isset($field->start_date_years) ? (date('Y') - $field->start_date_years) . '-01-01' : NULL,
+          'maxDate' => isset($field->end_date_years) ? (date('Y') + $field->end_date_years) . '-01-01' : NULL,
+          'time' => $field->time_format ? $field->time_format * 12 : FALSE,
+        );
         if ($field->is_search_range && $search) {
-          $qf->addDate($elementName . '_from', $label . ' - ' . ts('From'), FALSE,
-            array(
-              'format' => $field->date_format,
-              'timeFormat' => $field->time_format,
-              'startOffset' => $field->start_date_years,
-              'endOffset' => $field->end_date_years,
-              'data-crm-custom' => $dataCrmCustomVal,
-            )
-          );
-
-          $qf->addDate($elementName . '_to', ts('To'), FALSE,
-            array(
-              'format' => $field->date_format,
-              'timeFormat' => $field->time_format,
-              'startOffset' => $field->start_date_years,
-              'endOffset' => $field->end_date_years,
-              'data-crm-custom' => $dataCrmCustomVal,
-            )
-          );
+          $qf->add('datepicker', $elementName . '_from', $label, $attr + array('placeholder' => ts('From')), FALSE, $params);
+          $qf->add('datepicker', $elementName . '_to', NULL, $attr + array('placeholder' => ts('To')), FALSE, $params);
         }
         else {
-          $required = $useRequired && !$search;
-
-          $qf->addDate($elementName, $label, $required, array(
-            'format' => $field->date_format,
-            'timeFormat' => $field->time_format,
-            'startOffset' => $field->start_date_years,
-            'endOffset' => $field->end_date_years,
-            'data-crm-custom' => $dataCrmCustomVal,
-          ));
+          $element = $qf->add('datepicker', $elementName, $label, $attr, $useRequired && !$search, $params);
         }
         break;
 
@@ -900,12 +914,12 @@ class CRM_Core_BAO_CustomField extends CRM_Core_DAO_CustomField {
         foreach ($options as $v => $l) {
           $choice[] = $qf->createElement('radio', NULL, '', $l, (string) $v, $field->attributes);
         }
-        $group = $qf->addGroup($choice, $elementName, $label);
+        $element = $qf->addGroup($choice, $elementName, $label);
         if ($useRequired && !$search) {
           $qf->addRule($elementName, ts('%1 is a required field.', array(1 => $label)), 'required');
         }
         else {
-          $group->setAttribute('allowClear', TRUE);
+          $element->setAttribute('allowClear', TRUE);
         }
         break;
 
@@ -914,7 +928,7 @@ class CRM_Core_BAO_CustomField extends CRM_Core_DAO_CustomField {
         if (empty($selectAttributes['multiple'])) {
           $options = array('' => $placeholder) + $options;
         }
-        $qf->add('select', $elementName, $label, $options, $useRequired && !$search, $selectAttributes);
+        $element = $qf->add('select', $elementName, $label, $options, $useRequired && !$search, $selectAttributes);
 
         // Add and/or option for fields that store multiple values
         if ($search && self::isSerialized($field)) {
@@ -929,7 +943,7 @@ class CRM_Core_BAO_CustomField extends CRM_Core_DAO_CustomField {
         break;
 
       case 'AdvMulti-Select':
-        $include =& $qf->addElement(
+        $element = $qf->addElement(
           'advmultiselect',
           $elementName,
           $label, $options,
@@ -941,8 +955,8 @@ class CRM_Core_BAO_CustomField extends CRM_Core_DAO_CustomField {
           )
         );
 
-        $include->setButtonAttributes('add', array('value' => ts('Add >>')));
-        $include->setButtonAttributes('remove', array('value' => ts('<< Remove')));
+        $element->setButtonAttributes('add', array('value' => ts('Add >>')));
+        $element->setButtonAttributes('remove', array('value' => ts('<< Remove')));
 
         if ($useRequired && !$search) {
           $qf->addRule($elementName, ts('%1 is a required field.', array(1 => $label)), 'required');
@@ -954,7 +968,7 @@ class CRM_Core_BAO_CustomField extends CRM_Core_DAO_CustomField {
         foreach ($options as $v => $l) {
           $check[] = &$qf->addElement('advcheckbox', $v, NULL, $l, array('data-crm-custom' => $dataCrmCustomVal));
         }
-        $qf->addGroup($check, $elementName, $label);
+        $element = $qf->addGroup($check, $elementName, $label);
         if ($useRequired && !$search) {
           $qf->addRule($elementName, ts('%1 is a required field.', array(1 => $label)), 'required');
         }
@@ -963,9 +977,9 @@ class CRM_Core_BAO_CustomField extends CRM_Core_DAO_CustomField {
       case 'File':
         // we should not build upload file in search mode
         if ($search) {
-          return;
+          return NULL;
         }
-        $qf->add(
+        $element = $qf->add(
           strtolower($field->html_type),
           $elementName,
           $label,
@@ -984,7 +998,7 @@ class CRM_Core_BAO_CustomField extends CRM_Core_DAO_CustomField {
         if ($field->text_length) {
           $attributes['maxlength'] = $field->text_length;
         }
-        $qf->add('wysiwyg', $elementName, $label, $attributes, $search);
+        $element = $qf->add('wysiwyg', $elementName, $label, $attributes, $search);
         break;
 
       case 'Autocomplete-Select':
@@ -1001,10 +1015,8 @@ class CRM_Core_BAO_CustomField extends CRM_Core_DAO_CustomField {
         }
         if ($field->data_type == 'ContactReference') {
           $attributes['class'] = (isset($attributes['class']) ? $attributes['class'] . ' ' : '') . 'crm-form-contact-reference huge';
-          $attributes['data-api-entity'] = 'contact';
-          $qf->add('text', $elementName, $label, $attributes,
-            $useRequired && !$search
-          );
+          $attributes['data-api-entity'] = 'Contact';
+          $element = $qf->add('text', $elementName, $label, $attributes, $useRequired && !$search);
 
           $urlParams = "context=customfield&id={$field->id}";
 
@@ -1024,7 +1036,7 @@ class CRM_Core_BAO_CustomField extends CRM_Core_DAO_CustomField {
               'params' => array('option_group_id' => $field->option_group_id),
             ),
           );
-          $qf->addEntityRef($elementName, $label, $attributes, $useRequired && !$search);
+          $element = $qf->addEntityRef($elementName, $label, $attributes, $useRequired && !$search);
         }
 
         $qf->assign('customUrls', $customUrls);
@@ -1071,6 +1083,7 @@ class CRM_Core_BAO_CustomField extends CRM_Core_DAO_CustomField {
     if ($field->is_view && !$search) {
       $qf->freeze($elementName);
     }
+    return $element;
   }
 
   /**
@@ -1098,222 +1111,132 @@ class CRM_Core_BAO_CustomField extends CRM_Core_DAO_CustomField {
   }
 
   /**
-   * Find the display value for this field.
-   *
-   * @param mixed $value
-   *   The custom field value.
-   * @param int $id
-   *   The custom field id.
-   * @param array $options
-   *   The assoc array of option name/value pairs.
-   *
-   * @param int $contactID
-   * @param int $fieldID
+   * @param string|int|array|null $value
+   * @param CRM_Core_BAO_CustomField|int|array|string $field
+   * @param $contactId
    *
    * @return string
-   *   the display value
+   * @throws \Exception
    */
-  public static function getDisplayValue($value, $id, &$options, $contactID = NULL, $fieldID = NULL) {
-    $option = &$options[$id];
-    $attributes = &$option['attributes'];
-    $html_type = $attributes['html_type'];
-    $data_type = $attributes['data_type'];
-
-    return self::getDisplayValueCommon($value,
-      $option,
-      $html_type,
-      $data_type,
-      $contactID,
-      $fieldID
-    );
+  public static function displayValue($value, $field, $contactId = NULL) {
+    $field = is_array($field) ? $field['id'] : $field;
+    $fieldId = is_object($field) ? $field->id : (int) str_replace('custom_', '', $field);
+
+    if (!$fieldId) {
+      throw new Exception('CRM_Core_BAO_CustomField::displayValue requires a field id');
+    }
+
+    if (!is_a($field, 'CRM_Core_BAO_CustomField')) {
+      $field = self::getFieldObject($fieldId);
+    }
+
+    $fieldInfo = array('options' => $field->getOptions()) + (array) $field;
+
+    return self::formatDisplayValue($value, $fieldInfo, $contactId);
   }
 
   /**
-   * Get display value.
+   * Lower-level logic for rendering a custom field value
    *
-   * @param string $value
-   * @param array $option
-   * @param string $html_type
-   * @param string $data_type
-   * @param int $contactID
-   * @param int $fieldID
+   * @param string|array $value
+   * @param array $field
+   * @param int|null $entityId
    *
-   * @return array|mixed|null|string
+   * @return string
    */
-  public static function getDisplayValueCommon(
-    $value,
-    &$option,
-    $html_type,
-    $data_type,
-    $contactID = NULL,
-    $fieldID = NULL
-  ) {
-    $display = $value;
-
-    if ($fieldID &&
-      (($html_type == 'Radio' && $data_type != 'Boolean') ||
-        ($html_type == 'Autocomplete-Select' && $data_type != 'ContactReference') ||
-        $html_type == 'Select' ||
-        $html_type == 'CheckBox' ||
-        $html_type == 'AdvMulti-Select' ||
-        $html_type == 'Multi-Select'
-      )
-    ) {
-      CRM_Utils_Hook::customFieldOptions($fieldID, $option);
+  private static function formatDisplayValue($value, $field, $entityId = NULL) {
+
+    if (self::isSerialized($field) && !is_array($value)) {
+      $value = CRM_Utils_Array::explodePadded($value);
+    }
+    // CRM-12989 fix
+    if ($field['html_type'] == 'CheckBox') {
+      CRM_Utils_Array::formatArrayKeys($value);
     }
 
-    switch ($html_type) {
-      case 'Radio':
-        if ($data_type == 'Boolean') {
-          $options = array('No', 'Yes');
-        }
-        else {
-          $options = $option;
-        }
-        if (is_array($value)) {
-          $display = NULL;
-          foreach ($value as $data) {
-            $display .= $display ? ', ' . $options[$data] : $options[$data];
-          }
-        }
-        else {
-          $display = CRM_Utils_Array::value($value, $options);
-        }
-        break;
+    $display = is_array($value) ? implode(', ', $value) : (string) $value;
 
-      case 'Autocomplete-Select':
-        if ($data_type == 'ContactReference' &&
-          $value
-        ) {
-          $display = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Contact', $value, 'display_name');
-        }
-        elseif (is_array($value)) {
-          $display = NULL;
-          foreach ($value as $data) {
-            $display .= $display ? ', ' . $option[$data] : $option[$data];
-          }
-        }
-        else {
-          $display = CRM_Utils_Array::value($value, $option);
-        }
-        break;
+    switch ($field['html_type']) {
 
       case 'Select':
-        if (is_array($value)) {
-          $display = NULL;
-          foreach ($value as $data) {
-            $display .= $display ? ', ' . $option[$data] : $option[$data];
-          }
-        }
-        else {
-          $display = CRM_Utils_Array::value($value, $option);
-        }
-        break;
-
+      case 'Autocomplete-Select':
+      case 'Radio':
+      case 'Select Country':
+      case 'Select State/Province':
       case 'CheckBox':
       case 'AdvMulti-Select':
       case 'Multi-Select':
-        if (is_array($value)) {
-          if ($html_type == 'CheckBox') {
-            // CRM-12989 fix
-            CRM_Utils_Array::formatArrayKeys($value);
-          }
-
-          $checkedData = $value;
-        }
-        else {
-          $checkedData = explode(CRM_Core_DAO::VALUE_SEPARATOR,
-            substr($value, 1, -1)
-          );
-          if ($html_type == 'CheckBox') {
-            $newData = array();
-            foreach ($checkedData as $v) {
-              $v = str_replace(CRM_Core_DAO::VALUE_SEPARATOR, '', $v);
-              $newData[] = $v;
-            }
-            $checkedData = $newData;
-          }
-        }
-
-        $v = array();
-        foreach ($checkedData as $key => $val) {
-          $v[] = CRM_Utils_Array::value($val, $option);
-        }
-        if (!empty($v)) {
-          $display = implode(', ', $v);
+      case 'Multi-Select State/Province':
+      case 'Multi-Select Country':
+        if ($field['data_type'] == 'ContactReference' && $value) {
+          $display = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Contact', $value, 'display_name');
         }
-        break;
-
-      case 'Select Date':
-        if (is_array($value)) {
+        elseif (is_array($value)) {
+          $v = array();
           foreach ($value as $key => $val) {
-            $display[$key] = CRM_Utils_Date::customFormat($val);
+            $v[] = CRM_Utils_Array::value($val, $field['options']);
           }
+          $display = implode(', ', $v);
         }
         else {
-          // remove time element display if time is not set
-          if (empty($option['attributes']['time_format'])) {
-            $value = substr($value, 0, 10);
-          }
-          $display = CRM_Utils_Date::customFormat($value);
+          $display = CRM_Utils_Array::value($value, $field['options'], '');
         }
         break;
 
-      case 'Select State/Province':
-      case 'Multi-Select State/Province':
-      case 'Select Country':
-      case 'Multi-Select Country':
-        if (strstr($html_type, 'State/Province')) {
-          $option = CRM_Core_PseudoConstant::stateProvince(FALSE, FALSE);
-        }
-        else {
-          $option = CRM_Core_PseudoConstant::country(FALSE, FALSE);
-        }
-        // process multi-select state/country field values
-        if (!is_array($value)) {
-          $value = explode(CRM_Core_DAO::VALUE_SEPARATOR, $value);
-        }
-
-        $display = NULL;
-        foreach ($value as $data) {
-          $display .= ($display && !empty($option[$data])) ? ', ' . $option[$data] : $option[$data];
+      case 'Select Date':
+        $customFormat = NULL;
+
+        // FIXME: Are there any legitimate reasons why $value would be an array?
+        // Or should we throw an exception here if it is?
+        $value = is_array($value) ? CRM_Utils_Array::first($value) : $value;
+
+        $actualPHPFormats = CRM_Core_SelectValues::datePluginToPHPFormats();
+        $format = CRM_Utils_Array::value('date_format', $field);
+
+        if ($format) {
+          if (array_key_exists($format, $actualPHPFormats)) {
+            $customTimeFormat = (array) $actualPHPFormats[$format];
+            switch (CRM_Utils_Array::value('time_format', $field)) {
+              case 1:
+                $customTimeFormat[] = 'g:iA';
+                break;
+
+              case 2:
+                $customTimeFormat[] = 'G:i';
+                break;
+
+              default:
+                // if time is not selected remove time from value
+                $value = substr($value, 0, 10);
+            }
+            $customFormat = implode(" ", $customTimeFormat);
+          }
         }
+        $display = CRM_Utils_Date::processDate($value, NULL, FALSE, $customFormat);
         break;
 
       case 'File':
         // In the context of displaying a profile, show file/image
-        if ($contactID && $value) {
-          $url = self::getFileURL($contactID, $fieldID, $value);
-          if ($url) {
-            $display = $url['file_url'];
+        if ($value) {
+          if ($entityId) {
+            $url = self::getFileURL($entityId, $field['id']);
+            if ($url) {
+              $display = $url['file_url'];
+            }
+          }
+          else {
+            // In other contexts show a paperclip icon
+            $icons = CRM_Core_BAO_File::paperIconAttachment('*', $value);
+            $display = $icons[$value];
           }
-        }
-        // In other contexts show a paperclip icon
-        elseif ($value) {
-          $icons = CRM_Core_BAO_File::paperIconAttachment('*', $value);
-          $display = $icons[$value];
         }
         break;
 
       case 'TextArea':
-        if (empty($value)) {
-          $display = '';
-        }
-        else {
-          $display = is_array($value) ? nl2br(implode(', ', $value)) : nl2br($value);
-        }
+        $display = nl2br($display);
         break;
-
-      case 'Link':
-      case 'Text':
-        if (empty($value)) {
-          $display = '';
-        }
-        else {
-          $display = is_array($value) ? implode(', ', $value) : $value;
-        }
     }
-    return $display ? $display : $value;
+    return $display;
   }
 
   /**
@@ -1405,17 +1328,6 @@ class CRM_Core_BAO_CustomField extends CRM_Core_DAO_CustomField {
         }
         break;
 
-      case 'Select Date':
-        if ($value) {
-          list($defaults[$elementName], $defaults[$elementName . '_time']) = CRM_Utils_Date::setDateDefaults(
-            $value,
-            NULL,
-            $customField->date_format,
-            $customField->time_format
-          );
-        }
-        break;
-
       case 'Autocomplete-Select':
         if ($customField->data_type == 'ContactReference') {
           if (is_numeric($value)) {
@@ -1628,13 +1540,7 @@ SELECT id
       $customFields[$customFieldId]['html_type'] == 'AdvMulti-Select'
     ) {
       if ($value) {
-        // Note that only during merge this is not an array,
-        // and you can directly use value, CRM-4385
-        if (is_array($value)) {
-          $value = CRM_Core_DAO::VALUE_SEPARATOR . implode(CRM_Core_DAO::VALUE_SEPARATOR,
-              array_values($value)
-            ) . CRM_Core_DAO::VALUE_SEPARATOR;
-        }
+        $value = CRM_Utils_Array::implodePadded($value);
       }
       else {
         $value = '';
@@ -2196,6 +2102,7 @@ ORDER BY html_type";
    * @param int $entityID
    * @param string $customFieldExtends
    * @param bool $inline
+   * @param bool $checkPermissions
    *
    * @return array
    */
@@ -2203,7 +2110,8 @@ ORDER BY html_type";
     &$params,
     $entityID,
     $customFieldExtends,
-    $inline = FALSE
+    $inline = FALSE,
+    $checkPermissions = TRUE
   ) {
     $customData = array();
 
@@ -2226,7 +2134,8 @@ ORDER BY html_type";
           $customFieldExtends,
           $customFieldInfo[1],
           $entityID,
-          $inline
+          $inline,
+          $checkPermissions
         );
       }
     }
@@ -2234,61 +2143,8 @@ ORDER BY html_type";
   }
 
   /**
-   * Build option.
    *
-   * @param array $field
-   * @param array $options
-   *
-   * @throws Exception
    */
-  public static function buildOption($field, &$options) {
-    // Fixme - adding anything but options to the $options array is a bad idea
-    // What if an option had the key 'attributes'?
-    $options['attributes'] = array(
-      'label' => $field['label'],
-      'data_type' => $field['data_type'],
-      'html_type' => $field['html_type'],
-    );
-
-    $optionGroupID = NULL;
-    if (($field['html_type'] == 'CheckBox' ||
-      $field['html_type'] == 'Radio' ||
-      $field['html_type'] == 'Select' ||
-      $field['html_type'] == 'AdvMulti-Select' ||
-      $field['html_type'] == 'Multi-Select' ||
-      ($field['html_type'] == 'Autocomplete-Select' && $field['data_type'] != 'ContactReference')
-    )
-    ) {
-      if ($field['option_group_id']) {
-        $optionGroupID = $field['option_group_id'];
-      }
-      elseif ($field['data_type'] != 'Boolean') {
-        CRM_Core_Error::fatal();
-      }
-    }
-
-    // build the cache for custom values with options (label => value)
-    if ($optionGroupID != NULL) {
-      $query = "
-SELECT label, value
-  FROM civicrm_option_value
- WHERE option_group_id = $optionGroupID
-";
-
-      $dao = CRM_Core_DAO::executeQuery($query);
-      while ($dao->fetch()) {
-        if ($field['data_type'] == 'Int' || $field['data_type'] == 'Float') {
-          $num = round($dao->value, 2);
-          $options["$num"] = $dao->label;
-        }
-        else {
-          $options[$dao->value] = $dao->label;
-        }
-      }
-
-      CRM_Utils_Hook::customFieldOptions($field['id'], $options);
-    }
-  }
 
   /**
    * Get custom field ID.
@@ -2510,7 +2366,17 @@ WHERE cf.id = %1 AND cg.is_multiple = 1";
   }
 
   /**
-   * Get options for field.
+   * Get api entity for this field
+   *
+   * @return string
+   */
+  public function getEntity() {
+    $entity = CRM_Core_DAO::getFieldValue('CRM_Core_DAO_CustomGroup', $this->custom_group_id, 'extends');
+    return in_array($entity, array('Individual', 'Household', 'Organization')) ? 'Contact' : $entity;
+  }
+
+  /**
+   * Set pseudoconstant properties for field metadata.
    *
    * @param array $field
    * @param string|null $optionGroupName