Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[NFC] Date metadata fixes towards CRM-19490, CRM-18387, CRM-20012, CRM-20011, CRM-15948, CRM-19911 #9845

Merged
merged 3 commits into from
Feb 16, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 45 additions & 10 deletions CRM/Core/BAO/UFGroup.php
Original file line number Diff line number Diff line change
Expand Up @@ -348,9 +348,7 @@ public static function getFields(
$query = self::createUFFieldQuery($group->id, $searchable, $showAll, $visibility, $orderBy);
$field = CRM_Core_DAO::executeQuery($query);

$profileType = CRM_Core_BAO_UFField::getProfileType($group->id);
$contactActivityProfile = CRM_Core_BAO_UFField::checkContactActivityProfileType($group->id);
$importableFields = self::getImportableFields($showAll, $profileType, $contactActivityProfile);
$importableFields = self::getProfileFieldMetadata($showAll);
list($customFields, $addressCustomFields) = self::getCustomFields($ctype);

while ($field->fetch()) {
Expand Down Expand Up @@ -478,6 +476,7 @@ protected static function formatUFField(
if (isset($field->phone_type_id)) {
$name .= "-{$field->phone_type_id}";
}
$fieldMetaData = CRM_Utils_Array::value($name, $importableFields, (isset($importableFields[$field->field_name]) ? $importableFields[$field->field_name] : array()));

// No lie: this is bizarre; why do we need to mix so many UFGroup properties into UFFields?
// I guess to make field self sufficient with all the required data and avoid additional calls
Expand Down Expand Up @@ -515,8 +514,11 @@ protected static function formatUFField(
CRM_Utils_Array::value($field->field_name, $importableFields)
),
'skipDisplay' => 0,
'data_type' => CRM_Utils_Type::getDataTypeFromFieldMetadata($fieldMetaData),
);

$formattedField = CRM_Utils_Date::addDateMetadataToField($fieldMetaData, $formattedField);

//adding custom field property
if (substr($field->field_name, 0, 6) == 'custom' ||
substr($field->field_name, 0, 14) === 'address_custom'
Expand All @@ -527,12 +529,16 @@ protected static function formatUFField(
$formattedField['is_search_range'] = $customFields[$field->field_name]['is_search_range'];
// fix for CRM-1994
$formattedField['options_per_line'] = $customFields[$field->field_name]['options_per_line'];
$formattedField['data_type'] = $customFields[$field->field_name]['data_type'];
$formattedField['html_type'] = $customFields[$field->field_name]['html_type'];

if (CRM_Utils_Array::value('html_type', $formattedField) == 'Select Date') {
$formattedField['date_format'] = $customFields[$field->field_name]['date_format'];
$formattedField['time_format'] = $customFields[$field->field_name]['time_format'];
$formattedField['php_datetime_format'] = CRM_Utils_Date::getPhpDateFormatFromInputStyleDateFormat($customFields[$field->field_name]['date_format']);
if ($formattedField['time_format']) {
$formattedField['php_datetime_format'] .= ' H-i-s';
}
$formattedField['is_datetime_field'] = TRUE;
}

$formattedField['is_multi_summary'] = $field->is_multi_summary;
Expand Down Expand Up @@ -636,36 +642,65 @@ protected static function filterUFField($field, $searchable, $showAll, $visibili
}

/**
* Get a list of filtered field metadata.
*
* @deprecated use getProfileFieldMetadata
*
* @param $showAll
* @param $profileType
* @param $contactActivityProfile
* @param bool $filterMode
* Filter mode means you are using importable fields for filtering rather than just getting metadata.
* With filter mode = FALSE BOTH activity fields and component fields are returned.
* I can't see why you would ever want to use this function in filter mode as the component fields are
* still unfiltered. However, I feel scared enough to leave it as it is. I have marked this function as
* deprecated and am recommending the wrapper 'getProfileFieldMetadata' in order to try to
* send this confusion to history.
*
* @return array
*/
protected static function getImportableFields($showAll, $profileType, $contactActivityProfile) {
protected static function getImportableFields($showAll, $profileType, $contactActivityProfile, $filterMode = TRUE) {
if (!$showAll) {
$importableFields = CRM_Contact_BAO_Contact::importableFields('All', FALSE, FALSE, FALSE, TRUE, TRUE);
}
else {
$importableFields = CRM_Contact_BAO_Contact::importableFields('All', FALSE, TRUE, FALSE, TRUE, TRUE);
}

if ($profileType == 'Activity' || $contactActivityProfile) {
$componentFields = CRM_Activity_BAO_Activity::getProfileFields();
$activityFields = CRM_Activity_BAO_Activity::getProfileFields();
$componentFields = CRM_Core_Component::getQueryFields();
if ($filterMode == TRUE) {
if ($profileType == 'Activity' || $contactActivityProfile) {
$importableFields = array_merge($importableFields, $activityFields);
}
else {
$importableFields = array_merge($importableFields, $componentFields);
}
}
else {
$componentFields = CRM_Core_Component::getQueryFields();
$importableFields = array_merge($importableFields, $activityFields, $componentFields);
}

$importableFields = array_merge($importableFields, $componentFields);

$importableFields['group']['title'] = ts('Group(s)');
$importableFields['group']['where'] = NULL;
$importableFields['tag']['title'] = ts('Tag(s)');
$importableFields['tag']['where'] = NULL;
return $importableFields;
}

/**
* Get the metadata for all potential profile fields.
*
* @param bool $isIncludeInactive
* Should disabled fields be included.
*
* @return array
* Field metadata for all fields that might potentially be in a profile.
*/
protected static function getProfileFieldMetadata($isIncludeInactive) {
return self::getImportableFields($isIncludeInactive, NULL, NULL, NULL, TRUE);
}

/**
* Get the fields relating to locations.
*
Expand Down
2 changes: 2 additions & 0 deletions CRM/Core/Form.php
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,8 @@ public function registerRules() {
* @param bool $required
* @param array $extra
* (attributes for select elements).
* For datepicker elements this is consistent with the data
* from CRM_Utils_Date::getDatePickerExtra
*
* @return HTML_QuickForm_Element
* Could be an error object
Expand Down
32 changes: 21 additions & 11 deletions CRM/Core/SelectValues.php
Original file line number Diff line number Diff line change
Expand Up @@ -311,7 +311,8 @@ public static function groupType() {
* @return array
* the date array
*/
public static function date($type = NULL, $format = NULL, $minOffset = NULL, $maxOffset = NULL) {
public static function date($type = NULL, $format = NULL, $minOffset = NULL, $maxOffset = NULL, $context = 'display') {
// These options are deprecated. Definitely not used in datepicker. Possibly not even in jcalendar+addDateTime.
$date = array(
'addEmptyOption' => TRUE,
'emptyOptionText' => ts('- select -'),
Expand All @@ -328,25 +329,34 @@ public static function date($type = NULL, $format = NULL, $minOffset = NULL, $ma
if (!$dao->find(TRUE)) {
CRM_Core_Error::fatal();
}
}
if (!$maxOffset) {
$maxOffset = $dao->end;
}
if (!$minOffset) {
$minOffset = $dao->start;
}

if ($type == 'creditCard') {
$minOffset = $dao->start;
$maxOffset = $dao->end;
$date['format'] = $dao->date_format;
$date['addEmptyOption'] = TRUE;
$date['emptyOptionText'] = ts('- select -');
$date['emptyOptionValue'] = '';
$date['time'] = (bool) $dao->time_format;
}

if (empty($date['format'])) {
$date['format'] = 'M d';
if ($context == 'Input') {
$date['format'] = Civi::settings()->get('dateInputFormat');
$date['php_datetime_format'] = self::datePluginToPHPFormats(Civi::settings()->get('dateInputFormat'));
}
else {
$date['format'] = 'M d';
}
}
}
if (!isset($date['time'])) {
$date['time'] = FALSE;
}

$year = date('Y');
$date['minYear'] = $year - $minOffset;
$date['maxYear'] = $year + $maxOffset;
$date['minYear'] = $year - (int) $minOffset;
$date['maxYear'] = $year + (int) $maxOffset;
return $date;
}

Expand Down
7 changes: 0 additions & 7 deletions CRM/Price/Form/Field.php
Original file line number Diff line number Diff line change
Expand Up @@ -327,13 +327,6 @@ public function buildQuickForm() {
CRM_Core_DAO::getAttribute('CRM_Price_DAO_PriceField', 'help_post')
);

// active_on
$date_options = array(
'format' => 'dmY His',
'minYear' => date('Y') - 1,
'maxYear' => date('Y') + 5,
'addEmptyOption' => TRUE,
);
$this->addDateTime('active_on', ts('Active On'), FALSE, array('formatType' => 'activityDateTime'));

// expire_on
Expand Down
100 changes: 100 additions & 0 deletions CRM/Utils/Date.php
Original file line number Diff line number Diff line change
Expand Up @@ -1741,6 +1741,106 @@ public static function processDate($date, $time = NULL, $returnNullString = FALS
return $mysqlDate;
}

/**
* Convert a Civi-special date string to a standard php date string.
*
* For historical reasons CiviCRM has it's own (possibly Smarty derived)
* format for defined date strings. This renders something php can use.
*
* @param string $dateFormatString
* e.g mm/dd/yy
* These map to the values used in the date_format field in civicrm_custom_field.date_format.
*
* @return string
* A proper php strotime formatted equivalent of the string.
* eg m/d/y for the above.
*
* http://php.net/manual/en/function.strtotime.php
*/
public static function getPhpDateFormatFromInputStyleDateFormat($dateFormatString) {
$formats = CRM_Core_SelectValues::datePluginToPHPFormats();
return $formats[$dateFormatString];
}

/**
* Add the metadata about a date field to the field.
*
* This metadata will work with the call $form->add('datepicker', ...
*
* @param array $fieldMetaData
* @param array $field
*
* @return array
*/
public static function addDateMetadataToField($fieldMetaData, $field) {
if (isset($fieldMetaData['html'])) {
$field['html_type'] = $fieldMetaData['html']['type'];
if ($field['html_type'] === 'Select Date' && !isset($field['date_format'])) {
$dateAttributes = CRM_Core_SelectValues::date($fieldMetaData['html']['formatType'], NULL, NULL, NULL, 'Input');
$field['start_date_years'] = $dateAttributes['minYear'];
$field['end_date_years'] = $dateAttributes['maxYear'];
$field['date_format'] = $dateAttributes['format'];
$field['is_datetime_field'] = TRUE;
$field['time_format'] = $dateAttributes['time'];
$field['php_datetime_format'] = CRM_Utils_Date::getPhpDateFormatFromInputStyleDateFormat($field['date_format']);
if ($field['time_format']) {
$field['php_datetime_format'] .= ' H-i-s';
}
}
$field['datepicker']['extra'] = self::getDatePickerExtra($field);
$field['datepicker']['attributes'] = self::getDatePickerAttributes($field);
}
return $field;
}


/**
* Get the fields required for the 'extra' parameter when adding a datepicker.
*
* @param array $field
*
* @return array
*/
public static function getDatePickerExtra($field) {
$extra = array();
if (isset($field['date_format'])) {
$extra['date'] = $field['date_format'];
$extra['time'] = $field['time_format'];
}
$thisYear = date('Y');
if (isset($field['start_date_years'])) {
$extra['minDate'] = date('Y-m-d', strtotime('-' . ($thisYear - $field['start_date_years']) . ' years'));
}
if (isset($field['end_date_years'])) {
$extra['maxDate'] = date('Y-m-d', strtotime('-' . ($thisYear - $field['end_date_years']) . ' years'));
}
return $extra;
}

/**
* Get the attributes parameters required for datepicker.
*
* @param array $field
* Field metadata
*
* @return array
* Array ready to pass to $this->addForm('datepicker' as attributes.
*/
public static function getDatePickerAttributes(&$field) {
$attributes = array();
$dateAttributes = array(
'start_date_years' => 'minYear',
'end_date_years' => 'maxYear',
'date_format' => 'format',
);
foreach ($dateAttributes as $dateAttribute => $mapTo) {
if (isset($field[$dateAttribute])) {
$attributes[$mapTo] = $field[$dateAttribute];
}
}
return $attributes;
}

/**
* Function to convert mysql to date plugin format.
*
Expand Down
22 changes: 22 additions & 0 deletions CRM/Utils/Type.php
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,28 @@ public static function typeToString($type) {
return (isset($string)) ? $string : "";
}

/**
* Get the data_type for the field.
*
* @param array $fieldMetadata
* Metadata about the field.
*
* @return string
*/
public static function getDataTypeFromFieldMetadata($fieldMetadata) {
if (isset($fieldMetadata['data_type'])) {
return $fieldMetadata['data_type'];
}
if (empty($fieldMetadata['type'])) {
// I would prefer to throw an e-notice but there is some,
// probably unnecessary logic, that only retrieves activity fields
// if they are 'in the profile' and probably they are not 'in'
// until they are added - which might lead to ? who knows!
return '';
}
return self::typeToString($fieldMetadata['type']);
}

/**
* Helper function to call escape on arrays.
*
Expand Down