<?php
/*
+--------------------------------------------------------------------+
- | CiviCRM version 4.6 |
+ | CiviCRM version 4.7 |
+--------------------------------------------------------------------+
| Copyright CiviCRM LLC (c) 2004-2015 |
+--------------------------------------------------------------------+
*
* @package CRM
* @copyright CiviCRM LLC (c) 2004-2015
- * $Id$
- *
*/
/**
* Business objects for managing custom data fields.
- *
*/
class CRM_Core_BAO_CustomField extends CRM_Core_DAO_CustomField {
/**
- * Array for valid combinations of data_type & descriptions
+ * Array for valid combinations of data_type & descriptions.
*
* @var array
*/
public static $_dataType = NULL;
/**
- * Array for valid combinations of data_type & html_type
+ * Array for valid combinations of data_type & html_type.
*
* @var array
*/
*/
public static $_importFields = NULL;
+ /**
+ * @var array
+ */
+ public static $displayInfoCache = array();
+
/**
* Build and retrieve the list of data types and descriptions.
*
}
/**
+ * Get data to html array.
+ *
+ * (Does this caching achieve anything?)
+ *
* @return array
*/
public static function dataToHtml() {
* Value we want to set the is_active field.
*
* @return Object
- * DAO object on sucess, null otherwise
- *
+ * DAO object on success, null otherwise
*/
public static function setIsActive($id, $is_active) {
*
* @return string
* name
- *
*/
public static function getTitle($id) {
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);
+ $entity = CRM_Core_DAO::getFieldValue('CRM_Core_DAO_CustomGroup', $this->custom_group_id, 'extends');
+ $entity = in_array($entity, array('Individual', 'Household', 'Organization')) ? 'Contact' : $entity;
+ CRM_Utils_Hook::fieldOptions($entity, "custom_{$this->id}", $options, array('context' => $context));
+ return $options;
+ }
+
/**
* Store and return an array of all active custom fields.
*
*
* @return array
* an array of active custom fields.
- *
*/
public static function &getFields(
$customDataType = 'Individual',
* @param bool $withMultiple
*
* @return array
- *
- *
*/
- public static function &getFieldsForImport(
+ public static function getFieldsForImport(
$contactType = 'Individual',
$showAll = FALSE,
$onlyParent = FALSE,
* The key to parse.
*
* @param bool $all
+ *
* @return int|null
* The id (if exists)
*/
* True if used for search else false.
* @param string $label
* Label for custom field.
- *
*/
public static function addQuickFormElement(
&$qf,
$label = $field->label;
}
- /**
- * at some point in time we might want to split the below into small functions
- **/
+ // at some point in time we might want to split the below into small functions
switch ($widget) {
case 'Text':
if ($field->text_length) {
$attributes['maxlength'] = $field->text_length;
}
- $qf->addWysiwyg($elementName, $label, $attributes, $search);
+ $qf->add('wysiwyg', $elementName, $label, $attributes, $search);
break;
case 'Autocomplete-Select':
break;
case 'Link':
- $element->setAttribute('onfocus', "if (!this.value) {this.value='http://';}");
- $element->setAttribute('onblur', "if (this.value == 'http://') {this.value='';}");
$element->setAttribute('class', "url");
- $qf->addRule($elementName, ts('Enter a valid Website.'), 'wikiURL');
+ $qf->addRule($elementName, ts('Enter a valid web address beginning with \'http://\' or \'https://\'.'), 'wikiURL');
break;
}
if ($field->is_view && !$search) {
}
/**
- * Given a custom field value, its id and the set of options
- * 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
- *
- * @return string
- * the display value
+ * @param string|int|array|null $value
+ * @param CRM_Core_BAO_CustomField|int $field
+ * @param $contactId
*
+ * @return array|int|null|string
*/
- 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'];
- $format = CRM_Utils_Array::value('format', $attributes);
-
- return self::getDisplayValueCommon($value,
- $option,
- $html_type,
- $data_type,
- $format,
- $contactID,
- $fieldID
- );
+ public static function displayValue($value, $field, $contactId = NULL) {
+ $fieldId = is_object($field) ? $field->id : $field;
+
+ if (!isset(self::$displayInfoCache[$fieldId])) {
+ if (!is_a($field, 'CRM_Core_BAO_CustomField')) {
+ $field = new CRM_Core_BAO_CustomField();
+ $field->id = $fieldId;
+ }
+ $options = $field->getOptions();
+ self::$displayInfoCache[$fieldId] = array(
+ 'id' => $fieldId,
+ 'html_type' => $field->html_type,
+ 'data_type' => $field->data_type,
+ 'options' => $options,
+ );
+ }
+ return self::formatDisplayValue($value, self::$displayInfoCache[$fieldId], $contactId);
}
/**
- * @param $value
- * @param $option
- * @param $html_type
- * @param $data_type
- * @param null $format
+ * Legacy display value formatter.
+ *
+ * @deprecated
+ *
+ * @param string $value
+ * @param array $option
+ * @param string $html_type
+ * @param string $data_type
* @param int $contactID
* @param int $fieldID
*
*/
public static function getDisplayValueCommon(
$value,
- &$option,
+ $option,
$html_type,
$data_type,
- $format = NULL,
$contactID = NULL,
$fieldID = NULL
) {
- $display = $value;
if ($fieldID &&
(($html_type == 'Radio' && $data_type != 'Boolean') ||
CRM_Utils_Hook::customFieldOptions($fieldID, $option);
}
- 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;
+ if ($data_type == 'Boolean') {
+ $option = CRM_Core_SelectValues::boolean();
+ }
- 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;
+ if ($data_type == 'Country') {
+ $option = CRM_Core_PseudoConstant::country(FALSE, FALSE);
+ }
- 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;
+ if ($data_type == 'StateProvince') {
+ $option = CRM_Core_PseudoConstant::stateProvince(FALSE, FALSE);
+ }
+
+ $field = array(
+ 'id' => $fieldID,
+ 'html_type' => $html_type,
+ 'data_type' => $data_type,
+ 'options' => $option,
+ );
+
+ return self::formatDisplayValue($value, $field, $contactID);
+ }
+
+
+ /**
+ * Lower-level logic for rendering a custom field value
+ *
+ * @param string|array $value
+ * @param array $field
+ * @param int|null $contactID
+ *
+ * @return string|array|int|null
+ */
+ private static function formatDisplayValue($value, $field, $contactID = NULL) {
+ $display = $value;
+
+ if (self::isSerialized($field) && !is_array($value)) {
+ $value = (array) CRM_Utils_Array::explodePadded($value);
+ }
+ // CRM-12989 fix
+ if ($field['html_type'] == 'CheckBox') {
+ CRM_Utils_Array::formatArrayKeys($value);
+ }
+
+ switch ($field['html_type']) {
+ case 'Select':
+ case 'Autocomplete-Select':
+ case 'Radio':
+ case 'Select Country':
+ case 'Select State/Province':
case 'CheckBox':
case 'AdvMulti-Select':
case 'Multi-Select':
- if (is_array($value)) {
- $checkedData = $value;
+ 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');
}
- 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;
+ elseif (is_array($value)) {
+ $v = array();
+ foreach ($value as $key => $val) {
+ $v[] = CRM_Utils_Array::value($val, $field['options']);
}
- }
-
- $v = array();
- foreach ($checkedData as $key => $val) {
- $v[] = CRM_Utils_Array::value($val, $option);
- }
- if (!empty($v)) {
$display = implode(', ', $v);
}
+ else {
+ $display = CRM_Utils_Array::value($value, $field['options']);
+ }
break;
case 'Select Date':
}
else {
// remove time element display if time is not set
- if (empty($option['attributes']['time_format'])) {
+ if (empty($field['options']['attributes']['time_format'])) {
$value = substr($value, 0, 10);
}
$display = CRM_Utils_Date::customFormat($value);
}
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];
- }
- break;
-
case 'File':
// In the context of displaying a profile, show file/image
if ($contactID && $value) {
- $url = self::getFileURL($contactID, $fieldID, $value);
+ $url = self::getFileURL($contactID, $field['id'], $value);
if ($url) {
$display = $url['file_url'];
}
case 'Link':
case 'Text':
- if (empty($value)) {
- $display = '';
- }
- else {
- $display = is_array($value) ? implode(', ', $value) : $value;
- }
+ $display = is_array($value) ? implode(', ', $value) : $value;
}
return $display ? $display : $value;
}
* @param mixed $value
* If passed - dont fetch value from db,.
* just format the given value
- *
*/
public static function setProfileDefaults(
$customFieldId,
}
/**
- * @param int $contactID
- * @param int $cfID
- * @param int $fileID
- * @param bool $absolute
+ * Get file url.
*
- * @return array
- */
- /**
* @param int $contactID
* @param int $cfID
* @param int $fileID
* @param bool $absolute
*
+ * @param string $multiRecordWhereClause
+ *
* @return array
*/
public static function getFileURL($contactID, $cfID, $fileID = NULL, $absolute = FALSE, $multiRecordWhereClause = NULL) {
* Custom field id.
* @param array $customFormatted
* Formatted array.
- * @param mix $value
+ * @param mixed $value
* Value of custom field.
* @param string $customFieldExtend
* Custom field extends.
$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 = '';
}
/**
+ * Get default custom table schema.
+ *
* @param array $params
*
* @return array
*/
- public static function &defaultCustomTableSchema(&$params) {
+ public static function defaultCustomTableSchema($params) {
// add the id and extends_id
$table = array(
'name' => $params['name'],
}
/**
- * @param $field
- * @param $operation
+ * Create custom field.
+ *
+ * @param CRM_Core_DAO_CustomField $field
+ * @param string $operation
* @param bool $indexExist
* @param bool $triggerRebuild
*/
}
/**
- * Move a custom data field from one group (table) to another
+ * Move a custom data field from one group (table) to another.
*
* @param int $fieldID
* FK to civicrm_custom_field.
* @param int $newGroupID
* FK to civicrm_custom_group.
- *
- * @return void
*/
public static function moveField($fieldID, $newGroupID) {
$validation = self::_moveFieldValidate($fieldID, $newGroupID);
* Get custom option groups.
*
* @param array $includeFieldIds
- * Ids of custom fields for which.
- * option groups must be included.
+ * Ids of custom fields for which option groups must be included.
*
* Currently this is required in the cases where option groups are to be included
* for inactive fields : CRM-5369
*
- *
* @return mixed
*/
- public static function &customOptionGroup($includeFieldIds = NULL) {
+ public static function customOptionGroup($includeFieldIds = NULL) {
static $customOptionGroup = NULL;
$cacheKey = (empty($includeFieldIds)) ? 'onlyActive' : 'force';
* Custom field id.
* @param int $optionGroupId
* Option group id.
- *
- * @return void
*/
public static function fixOptionGroups($customFieldId, $optionGroupId) {
// check if option group belongs to any custom Field else delete
}
/**
- * Check if option group is related to more than one
- * custom field
+ * Check if option group is related to more than one custom field.
*
* @param int $optionGroupId
* Option group id.
- *
- * @return void
*/
public static function checkOptionGroup($optionGroupId) {
$query = "
}
/**
+ * Get option group default.
+ *
* @param int $optionGroupId
- * @param $htmlType
+ * @param string $htmlType
*
* @return null|string
*/
}
/**
+ * Post process function.
+ *
* @param array $params
- * @param $customFields
* @param int $entityID
- * @param $customFieldExtends
+ * @param string $customFieldExtends
* @param bool $inline
+ * @param bool $checkPermissions
*
* @return array
*/
public static function postProcess(
&$params,
- &$customFields,
$entityID,
$customFieldExtends,
- $inline = FALSE
+ $inline = FALSE,
+ $checkPermissions = TRUE
) {
$customData = array();
$customFieldExtends,
$customFieldInfo[1],
$entityID,
- $inline
+ $inline,
+ $checkPermissions
);
}
}
}
/**
- * @param $field
- * @param $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);
- }
- }
/**
- * @param $fieldLabel
+ * Get custom field ID.
+ *
+ * @param string $fieldLabel
* @param null $groupTitle
*
- * @return null
+ * @return int|null
*/
public static function getCustomFieldID($fieldLabel, $groupTitle = NULL) {
$params = array(1 => array($fieldLabel, 'String'));
}
/**
+ * Is this field a multi record field.
+ *
* @param int $customId
*
* @return bool
/**
* Does this field store a serialized string?
- * @param CRM_Core_DAO_CustomField|array $field
+ *
+ * @param array $field
+ *
* @return bool
*/
public static function isSerialized($field) {
}
/**
+ * Set pseudoconstant properties for field metadata.
+ *
* @param array $field
* @param string|null $optionGroupName
*/