/** * Lower-level logic for rendering a custom field value * * @param string|array $value * @param array $field * @param int|null $entityId * * @return string */ 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); } $display = is_array($value) ? implode(', ', $value) : (string) $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': 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'); } elseif (is_array($value)) { $v = array(); foreach ($value as $key => $val) { $v[] = CRM_Utils_Array::value($val, $field['options']); } $display = implode(', ', $v); } else { $display = CRM_Utils_Array::value($value, $field['options'], ''); } break; 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 ($value) { if ($entityId) { $url = self::getFileURL($entityId, $field['id']); if ($url) { $display = $url['file_url']; } } else { // In other contexts show a paperclip icon if (CRM_Utils_Rule::integer($value)) { $icons = CRM_Core_BAO_File::paperIconAttachment('*', $value); $display = $icons[$value]; } else { //CRM-18396, if filename is passed instead $display = $value; } } } break; case 'TextArea': $display = nl2br($display); break; case 'Text': if ($field['data_type'] == 'Money' && isset($value)) { //$value can also be an array(while using IN operator from search builder or api). foreach ((array) $value as $val) { $disp[] = CRM_Utils_Money::format($val); } $display = implode(', ', $disp); } break; } return $display; }
/** * Browse the listing. * * @return void */ public function browse() { $dateFields = NULL; $cgcount = 0; $attributes = array(); $dateFieldsVals = NULL; if ($this->_pageViewType == 'profileDataView' && $this->_profileId) { $fields = CRM_Core_BAO_UFGroup::getFields($this->_profileId, FALSE, NULL, NULL, NULL, FALSE, NULL, FALSE, NULL, CRM_Core_Permission::EDIT); $multiRecordFields = array(); $fieldIDs = NULL; $result = NULL; $multiRecordFieldsWithSummaryListing = CRM_Core_BAO_UFGroup::shiftMultiRecordFields($fields, $multiRecordFields, TRUE); $multiFieldId = CRM_Core_BAO_CustomField::getKeyID(key($multiRecordFields)); $customGroupId = CRM_Core_DAO::getFieldValue('CRM_Core_DAO_CustomField', $multiFieldId, 'custom_group_id'); $reached = CRM_Core_BAO_CustomGroup::hasReachedMaxLimit($customGroupId, $this->_contactId); if (!$reached) { $this->assign('contactId', $this->_contactId); $this->assign('gid', $this->_profileId); } $this->assign('reachedMax', $reached); if ($multiRecordFieldsWithSummaryListing && !empty($multiRecordFieldsWithSummaryListing)) { $fieldIDs = array_keys($multiRecordFieldsWithSummaryListing); } } elseif ($this->_pageViewType == 'customDataView') { // require custom group id for _pageViewType of customDataView $customGroupId = $this->_customGroupId; $reached = CRM_Core_BAO_CustomGroup::hasReachedMaxLimit($customGroupId, $this->_contactId); if (!$reached) { $this->assign('contactId', $this->_contactId); $this->assign('customGroupId', $customGroupId); $this->assign('ctype', $this->_contactType); } $this->assign('reachedMax', $reached); // custom group info : this consists of the field title of group fields $groupDetail = CRM_Core_BAO_CustomGroup::getGroupDetail($customGroupId, NULL, CRM_Core_DAO::$_nullObject, TRUE); // field ids of fields in_selector for the custom group id provided $fieldIDs = array_keys($groupDetail[$customGroupId]['fields']); // field labels for headers $fieldLabels = $groupDetail[$customGroupId]['fields']; // from the above customGroupInfo we can get $this->_customGroupTitle $this->_customGroupTitle = $groupDetail[$customGroupId]['title']; } if ($fieldIDs && !empty($fieldIDs) && $this->_contactId) { $options = array(); $returnProperities = array('html_type', 'data_type', 'date_format', 'time_format', 'default_value', 'is_required'); foreach ($fieldIDs as $key => $fieldID) { $fieldIDs[$key] = !is_numeric($fieldID) ? CRM_Core_BAO_CustomField::getKeyID($fieldID) : $fieldID; $param = array('id' => $fieldIDs[$key]); $returnValues = array(); CRM_Core_DAO::commonRetrieve('CRM_Core_DAO_CustomField', $param, $returnValues, $returnProperities); if ($returnValues['data_type'] == 'Date') { $dateFields[$fieldIDs[$key]] = 1; $actualPHPFormats = CRM_Core_SelectValues::datePluginToPHPFormats(); $dateFormat = (array) CRM_Utils_Array::value($returnValues['date_format'], $actualPHPFormats); $timeFormat = CRM_Utils_Array::value('time_format', $returnValues); } $optionValuePairs = CRM_Core_BAO_CustomOption::getCustomOption($fieldIDs[$key]); if (!empty($optionValuePairs)) { foreach ($optionValuePairs as $optionPairs) { $options[$fieldIDs[$key]][$optionPairs['value']] = $optionPairs['label']; } } $options[$fieldIDs[$key]]['attributes']['html_type'] = $returnValues['html_type']; $options[$fieldIDs[$key]]['attributes']['data_type'] = $returnValues['data_type']; $options[$fieldIDs[$key]]['attributes']['is_required'] = !empty($returnValues['is_required']); $options[$fieldIDs[$key]]['attributes']['default_value'] = CRM_Utils_Array::value('default_value', $returnValues); $options[$fieldIDs[$key]]['attributes']['format'] = $options[$fieldIDs[$key]]['attributes']['date_format'] = CRM_Utils_Array::value('date_format', $returnValues); $options[$fieldIDs[$key]]['attributes']['time_format'] = CRM_Utils_Array::value('time_format', $returnValues); } // commonly used for both views i.e profile listing view (profileDataView) and custom data listing view (customDataView) $result = CRM_Core_BAO_CustomValueTable::getEntityValues($this->_contactId, NULL, $fieldIDs, TRUE); if ($this->_pageViewType == 'profileDataView') { if (!empty($fieldIDs)) { //get the group info of multi rec fields in listing view $fieldInput = $fieldIDs; $fieldIdInput = $fieldIDs[0]; } else { //if no listing fields exist, take the group title for display $nonListingFieldIds = array_keys($multiRecordFields); $singleField = CRM_Core_BAO_CustomField::getKeyID($nonListingFieldIds[0]); $fieldIdInput = $singleField; $singleField = array($singleField); $fieldInput = $singleField; } $customGroupInfo = CRM_Core_BAO_CustomGroup::getGroupTitles($fieldInput); $this->_customGroupTitle = $customGroupInfo[$fieldIdInput]['groupTitle']; } // $cgcount is defined before 'if' condition as enitiy may have no record // and $cgcount is used to build new record url $cgcount = 1; if ($result && !empty($result)) { $links = self::links(); if ($this->_pageViewType == 'profileDataView') { $pageCheckSum = $this->get('pageCheckSum'); if ($pageCheckSum) { foreach ($links as $key => $link) { $links[$key] = $link['qs'] . "&cs=%%cs%%"; } } } $linkAction = array_sum(array_keys($this->links())); if ($reached) { unset($links[CRM_Core_Action::COPY]); } $newCgCount = !$reached ? count($result) + 1 : NULL; foreach ($result as $recId => &$value) { foreach ($value as $fieldId => &$val) { if (is_numeric($fieldId)) { $customValue =& $val; if (!empty($dateFields) && array_key_exists($fieldId, $dateFields)) { // formated date capture value capture $dateFieldsVals[$fieldId][$recId] = CRM_Core_BAO_CustomField::getDisplayValue($customValue, $fieldId, $options); //set date and time format switch ($timeFormat) { case 1: $dateFormat[1] = 'g:iA'; break; case 2: $dateFormat[1] = 'G:i'; break; default: // if time is not selected remove time from value $result[$recId][$fieldId] = substr($result[$recId][$fieldId], 0, 10); } $result[$recId][$fieldId] = CRM_Utils_Date::processDate($result[$recId][$fieldId], NULL, FALSE, implode(" ", $dateFormat)); } else { // assign to $result $customValue = CRM_Core_BAO_CustomField::getDisplayValue($customValue, $fieldId, $options); } // FIXME: getDisplayValue should always return a string so why is this necessary? if (!$customValue && $customValue !== '0') { $customValue = ""; } // Set field attributes to support crmEditable // Note that $fieldAttributes[data-type] actually refers to the html type not the sql data type // TODO: Not all widget types and validation rules are supported by crmEditable so some fields will not be in-place editable $fieldAttributes = array('class' => "crmf-custom_{$fieldId}_{$recId}"); $editable = FALSE; if ($linkAction & CRM_Core_Action::UPDATE) { $spec = $options[$fieldId]['attributes']; switch ($spec['html_type']) { case 'Text': // Other data types like money would require some extra validation // FIXME: crmEditable currently does not support any validation rules :( $supportedDataTypes = array('Float', 'String', 'Int'); $editable = in_array($spec['data_type'], $supportedDataTypes); break; case 'TextArea': $editable = TRUE; $fieldAttributes['data-type'] = 'textarea'; break; case 'Radio': case 'Select': case 'Select Country': case 'Select State/Province': $editable = TRUE; $fieldAttributes['data-type'] = $spec['data_type'] == 'Boolean' ? 'boolean' : 'select'; if (!$spec['is_required']) { $fieldAttributes['data-empty-option'] = ts('- none -'); } break; } } if ($editable) { $fieldAttributes['class'] .= ' crm-editable'; } $attributes[$fieldId][$recId] = $fieldAttributes; $op = NULL; if ($this->_pageViewType == 'profileDataView') { $actionParams = array('recordId' => $recId, 'gid' => $this->_profileId, 'id' => $this->_contactId); $op = 'profile.multiValue.row'; } else { // different set of url params $actionParams['gid'] = $actionParams['groupID'] = $this->_customGroupId; $actionParams['cid'] = $actionParams['entityID'] = $this->_contactId; $actionParams['recId'] = $recId; $actionParams['type'] = $this->_contactType; $actionParams['cgcount'] = $cgcount; $actionParams['newCgCount'] = $newCgCount; // DELETE action links $deleteData = array('valueID' => $recId, 'groupID' => $this->_customGroupId, 'contactId' => $this->_contactId, 'key' => CRM_Core_Key::get('civicrm/ajax/customvalue')); $links[CRM_Core_Action::DELETE]['url'] = '#'; $links[CRM_Core_Action::DELETE]['extra'] = ' data-delete_params="' . htmlspecialchars(json_encode($deleteData)) . '"'; $links[CRM_Core_Action::DELETE]['class'] = 'delete-custom-row'; } if (!empty($pageCheckSum)) { $actionParams['cs'] = $pageCheckSum; } $value['action'] = CRM_Core_Action::formLink($links, $linkAction, $actionParams, ts('more'), FALSE, $op, 'customValue', $fieldId); } } $cgcount++; } } } $headers = array(); if (!empty($fieldIDs)) { foreach ($fieldIDs as $fieldID) { $headers[$fieldID] = $this->_pageViewType == 'profileDataView' ? $customGroupInfo[$fieldID]['fieldLabel'] : $fieldLabels[$fieldID]['label']; } } $this->assign('dateFields', $dateFields); $this->assign('dateFieldsVals', $dateFieldsVals); $this->assign('cgcount', $cgcount); $this->assign('customGroupTitle', $this->_customGroupTitle); $this->assign('headers', $headers); $this->assign('records', $result); $this->assign('attributes', $attributes); }
/** * Function to convert mysql to date plugin format * * @param string $mysqlDate date string * * @return array $date and time */ static function setDateDefaults($mysqlDate = null, $formatType = null, $format = null, $timeFormat = null) { // if date is not passed assume it as today if (!$mysqlDate) { $mysqlDate = date('Y-m-d G:i:s'); } $config = CRM_Core_Config::singleton(); if ($formatType) { // get actual format $params = array('name' => $formatType); $values = array(); CRM_Core_DAO::commonRetrieve('CRM_Core_DAO_PreferencesDate', $params, $values); if ($values['date_format']) { $format = $values['date_format']; } if ($values['time_format']) { $timeFormat = $values['time_format']; } } if (!$format) { $format = $config->dateInputFormat; } require_once 'CRM/Core/SelectValues.php'; // get actual format $actualPHPFormats = CRM_Core_SelectValues::datePluginToPHPFormats(); $dateFormat = $actualPHPFormats[$format]; $date = date($dateFormat, strtotime($mysqlDate)); if (!$timeFormat) { $timeFormat = $config->timeInputFormat; } $actualTimeFormat = "g:iA"; $appendZeroLength = 7; if ($timeFormat > 1) { $actualTimeFormat = "G:i"; $appendZeroLength = 5; } $time = date($actualTimeFormat, strtotime($mysqlDate)); // need to append zero for hours < 10 if (strlen($time) < $appendZeroLength) { $time = '0' . $time; } return array($date, $time); }
/** * Format custom value according to data, view mode * * @param array $values * Associated array of custom values. * @param array $field * @param bool $dncOptionPerLine * True if optionPerLine should not be consider. * * @return array|null|string */ public static function formatCustomValues(&$values, &$field, $dncOptionPerLine = FALSE) { $value = $values['data']; //changed isset CRM-4601 if (CRM_Utils_System::isNull($value)) { return NULL; } $htmlType = CRM_Utils_Array::value('html_type', $field); $dataType = CRM_Utils_Array::value('data_type', $field); $option_group_id = CRM_Utils_Array::value('option_group_id', $field); $timeFormat = CRM_Utils_Array::value('time_format', $field); $optionPerLine = CRM_Utils_Array::value('options_per_line', $field); $freezeString = ""; $freezeStringChecked = ""; switch ($dataType) { case 'Date': $customFormat = NULL; $actualPHPFormats = CRM_Core_SelectValues::datePluginToPHPFormats(); if ($format = CRM_Utils_Array::value('date_format', $field)) { if (array_key_exists($format, $actualPHPFormats)) { $customTimeFormat = (array) CRM_Utils_Array::value($format, $actualPHPFormats); switch ($timeFormat) { 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); } } $retValue = CRM_Utils_Date::processDate($value, NULL, FALSE, $customFormat); break; case 'Boolean': if ($value == '1') { $retValue = $freezeStringChecked . ts('Yes') . "\n"; } else { $retValue = $freezeStringChecked . ts('No') . "\n"; } break; case 'Link': if ($value) { $retValue = CRM_Utils_System::formatWikiURL($value); } break; case 'File': $retValue = $values; break; case 'ContactReference': if (!empty($values['data'])) { $retValue = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Contact', $values['data'], 'display_name'); } break; case 'Memo': $retValue = $value; break; case 'Float': if ($htmlType == 'Text') { $retValue = (double) $value; break; } case 'Money': if ($htmlType == 'Text') { $retValue = CRM_Utils_Money::format($value, NULL, '%a'); break; } case 'String': case 'Int': if (in_array($htmlType, array('Text', 'TextArea'))) { $retValue = $value; break; } // note that if its not text / textarea, the code falls thru and executes // the below case also // note that if its not text / textarea, the code falls thru and executes // the below case also case 'StateProvince': case 'Country': $options = array(); $coDAO = NULL; //added check for Multi-Select in the below if-statement $customData[] = $value; //form custom data for multiple-valued custom data switch ($htmlType) { case 'Multi-Select Country': case 'Select Country': $customData = $value; if (!is_array($value)) { $customData = explode(CRM_Core_DAO::VALUE_SEPARATOR, $value); } $query = "\n SELECT id as value, name as label\n FROM civicrm_country"; $coDAO = CRM_Core_DAO::executeQuery($query); break; case 'Select State/Province': case 'Multi-Select State/Province': $customData = $value; if (!is_array($value)) { $customData = explode(CRM_Core_DAO::VALUE_SEPARATOR, $value); } $query = "\n SELECT id as value, name as label\n FROM civicrm_state_province"; $coDAO = CRM_Core_DAO::executeQuery($query); break; case 'Select': $customData = explode(CRM_Core_DAO::VALUE_SEPARATOR, $value); if ($option_group_id) { $options = CRM_Core_BAO_OptionValue::getOptionValuesAssocArray($option_group_id); } break; case 'CheckBox': case 'AdvMulti-Select': case 'Multi-Select': $customData = explode(CRM_Core_DAO::VALUE_SEPARATOR, $value); default: if ($option_group_id) { $options = CRM_Core_BAO_OptionValue::getOptionValuesAssocArray($option_group_id); } } if (is_object($coDAO)) { while ($coDAO->fetch()) { if ($dataType == 'Country') { // NB: using ts() on a variable here is OK, since the value is pre-determined, not variable // and already extracted to .pot files. $options[$coDAO->value] = ts($coDAO->label, array('context' => 'country')); } elseif ($dataType == 'StateProvince') { $options[$coDAO->value] = ts($coDAO->label, array('context' => 'province')); } else { $options[$coDAO->value] = $coDAO->label; } } } CRM_Utils_Hook::customFieldOptions($field['id'], $options, FALSE); $retValue = NULL; foreach ($options as $optionValue => $optionLabel) { if ($dataType == 'Money') { foreach ($customData as $k => $v) { $customData[] = CRM_Utils_Money::format($v, NULL, '%a'); } } //to show only values that are checked if (in_array((string) $optionValue, $customData)) { $checked = in_array($optionValue, $customData) ? $freezeStringChecked : $freezeString; if (!$optionPerLine || $dncOptionPerLine) { if ($retValue) { $retValue .= ", "; } $retValue .= $checked . $optionLabel; } else { $retValue[] = $checked . $optionLabel; } } } break; } //special case for option per line formatting if ($optionPerLine > 1 && is_array($retValue)) { $rowCounter = 0; $fieldCounter = 0; $displayValues = array(); $displayString = ''; foreach ($retValue as $val) { if ($displayString) { $displayString .= ", "; } $displayString .= $val; $rowCounter++; $fieldCounter++; if ($rowCounter == $optionPerLine || $fieldCounter == count($retValue)) { $displayValues[] = $displayString; $displayString = ''; $rowCounter = 0; } } $retValue = $displayValues; } $retValue = isset($retValue) ? $retValue : NULL; return $retValue; }
/** * Given an id, extract the formValues of the saved search. * * @param int $id * The id of the saved search. * * @return array * the values of the posted saved search used as default values in various Search Form */ public static function getFormValues($id) { $fv = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_SavedSearch', $id, 'form_values'); $result = NULL; if ($fv) { // make sure u unserialize - since it's stored in serialized form $result = unserialize($fv); } //CRM-19250: fetch the default date format to format mysql value as per CRM_Core_Error::addDate() $dateFormat = CRM_Core_DAO::getFieldValue('CRM_Core_DAO_PreferencesDate', 'searchDate', 'date_format', 'name'); $dateFormat = empty($dateFormat) ? CRM_Core_Config::singleton()->dateInputFormat : $dateFormat; $dateFormat = CRM_Utils_Array::value($dateFormat, CRM_Core_SelectValues::datePluginToPHPFormats()); $specialFields = array('contact_type', 'group', 'contact_tags', 'member_membership_type_id', 'member_status_id'); foreach ($result as $element => $value) { if (CRM_Contact_BAO_Query::isAlreadyProcessedForQueryFormat($value)) { $id = CRM_Utils_Array::value(0, $value); $value = CRM_Utils_Array::value(2, $value); if (is_array($value) && in_array(key($value), CRM_Core_DAO::acceptedSQLOperators(), TRUE)) { $value = CRM_Utils_Array::value(key($value), $value); } if (strpos($id, '_date_low') !== FALSE || strpos($id, '_date_high') !== FALSE) { $result[$id] = date($dateFormat, strtotime($value)); $entityName = strstr($id, '_date', TRUE); $result["{$entityName}_date_relative"] = 0; } else { $result[$id] = $value; } unset($result[$element]); continue; } if (!empty($value) && is_array($value)) { if (in_array($element, $specialFields)) { // Remove the element to minimise support for legacy formats. It is stored in $value // so will be re-set with the right name. unset($result[$element]); $element = str_replace('member_membership_type_id', 'membership_type_id', $element); $element = str_replace('member_status_id', 'membership_status_id', $element); CRM_Contact_BAO_Query::legacyConvertFormValues($element, $value); $result[$element] = $value; } elseif (in_array(key($value), CRM_Core_DAO::acceptedSQLOperators(), TRUE)) { $result[$element] = CRM_Utils_Array::value(key($value), $value); if (is_string($result[$element])) { $result[$element] = str_replace("%", '', $result[$element]); } } } if (substr($element, 0, 7) == 'custom_' && (substr($element, -5, 5) == '_from' || substr($element, -3, 3) == '_to')) { // Ensure the _relative field is set if from or to are set to ensure custom date // fields with 'from' or 'to' values are displayed when the are set in the smart group // being loaded. (CRM-17116) if (!isset($result[CRM_Contact_BAO_Query::getCustomFieldName($element) . '_relative'])) { $result[CRM_Contact_BAO_Query::getCustomFieldName($element) . '_relative'] = 0; } } // check to see if we need to convert the old privacy array // CRM-9180 if (!empty($result['privacy'])) { if (is_array($result['privacy'])) { $result['privacy_operator'] = 'AND'; $result['privacy_toggle'] = 1; if (isset($result['privacy']['do_not_toggle'])) { if ($result['privacy']['do_not_toggle']) { $result['privacy_toggle'] = 2; } unset($result['privacy']['do_not_toggle']); } $result['privacy_options'] = array(); foreach ($result['privacy'] as $name => $val) { if ($val) { $result['privacy_options'][] = $name; } } } unset($result['privacy']); } } return $result; }
/** * Function to convert mysql to date plugin format * * @param string $mysqlDate date string * * @return array $date and time */ static function setDateDefaults($mysqlDate = null, $formatType = null, $format = null, $timeFormat = null) { // if date is not passed assume it as today if (!$mysqlDate) { $mysqlDate = date('Y-m-d G:i:s'); } $config =& CRM_Core_Config::singleton(); if ($formatType) { $format = CRM_Core_Dao::getFieldValue('CRM_Core_DAO_PreferencesDate', $formatType, 'format', 'name'); } if (!$format) { $format = $config->dateInputFormat; } // get actual format $actualPHPFormats = CRM_Core_SelectValues::datePluginToPHPFormats(); $dateFormat = $actualPHPFormats[$format]; $date = date($dateFormat, strtotime($mysqlDate)); if (!$timeFormat) { $timeFormat = $config->timeInputFormat; } $actualTimeFormat = "g:iA"; $appendZeroLength = 7; if ($timeFormat > 1) { $actualTimeFormat = "G:i"; $appendZeroLength = 5; } $time = date($actualTimeFormat, strtotime($mysqlDate)); // need to append zero for hours < 10 if (strlen($time) < $appendZeroLength) { $time = '0' . $time; } return array($date, $time); }