Skip to content

Commit

Permalink
dev/core#2325 import second-handling fix
Browse files Browse the repository at this point in the history
  • Loading branch information
eileenmcnaughton committed Jun 10, 2022
1 parent 4b377f0 commit aa65dcd
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 24 deletions.
2 changes: 1 addition & 1 deletion CRM/Import/Parser.php
Original file line number Diff line number Diff line change
Expand Up @@ -1354,7 +1354,7 @@ protected function getTransformedFieldValue(string $fieldName, $importedValue) {
}
if ($fieldMetadata['type'] === CRM_Utils_Type::T_DATE || $fieldMetadata['type'] === (CRM_Utils_Type::T_DATE + CRM_Utils_Type::T_TIME) || $fieldMetadata['type'] === CRM_Utils_Type::T_TIMESTAMP) {
$value = CRM_Utils_Date::formatDate($importedValue, $this->getSubmittedValue('dateFormats'));
return ($value) ?: 'invalid_import_value';
return $value ?: 'invalid_import_value';
}
$options = $this->getFieldOptions($fieldName);
if ($options !== FALSE) {
Expand Down
49 changes: 27 additions & 22 deletions CRM/Utils/Date.php
Original file line number Diff line number Diff line change
Expand Up @@ -369,6 +369,7 @@ public static function customFormat($dateString, $format = NULL, $dateParts = NU

$hour24 = (int) substr($dateString, 11, 2);
$minute = (int) substr($dateString, 14, 2);
$second = (int) substr($dateString, 16, 2);
}
else {
$year = (int) substr($dateString, 0, 4);
Expand All @@ -377,6 +378,7 @@ public static function customFormat($dateString, $format = NULL, $dateParts = NU

$hour24 = (int) substr($dateString, 8, 2);
$minute = (int) substr($dateString, 10, 2);
$second = (int) substr($dateString, 12, 2);
}

if ($day % 10 == 1 and $day != 11) {
Expand Down Expand Up @@ -430,13 +432,12 @@ public static function customFormat($dateString, $format = NULL, $dateParts = NU
'%P' => $type,
'%A' => $type,
'%Y' => $year,
'%s' => str_pad($second, 2, 0, STR_PAD_LEFT),
];

return strtr($format, $date);
}
else {
return '';
}
return '';
}

/**
Expand Down Expand Up @@ -2101,15 +2102,23 @@ public static function getDateFormat($formatType = NULL) {
}

/**
* Date formatting for imports where date format is specified.
*
* Note this is used for imports (only) because the importer can
* specify the format.
*
* Tests are in CRM_Utils_DateTest::testFormatDate
*
* @param $date
* Date string as entered.
* @param $dateType
* One of the constants like CRM_Core_Form_Date::DATE_yyyy_mm_dd.
*
* @return null|string
* @return false|string
*/
public static function formatDate($date, $dateType) {
$formattedDate = NULL;
if (empty($date)) {
return $formattedDate;
return FALSE;
}

// 1. first convert date to default format.
Expand All @@ -2122,32 +2131,28 @@ public static function formatDate($date, $dateType) {

if (CRM_Utils_Date::convertToDefaultDate($dateParams, $dateType, $dateKey)) {
$dateVal = $dateParams[$dateKey];
$ruleName = 'date';
if ($dateType == 1) {
if ($dateType === 1) {
$matches = [];
if (preg_match("/(\s(([01]\d)|[2][0-3]):([0-5]\d):?[0-5]?\d?)$/", $date, $matches)) {
$ruleName = 'dateTime';
// The seconds part of this regex is not quite right - but it does succeed
// in clarifying whether there is a time component or not - which is all it is meant
// to do.
if (preg_match('/(\s(([01]\d)|[2][0-3]):([0-5]\d):?[0-5]?\d?)$/', $date, $matches)) {
if (strpos($date, '-') !== FALSE) {
$dateVal .= array_shift($matches);
}
if (!CRM_Utils_Rule::dateTime($dateVal)) {
return NULL;
}
$dateVal = CRM_Utils_Date::customFormat(preg_replace("/(:|\s)?/", '', $dateVal), '%Y%m%d%H%i%s');
return $dateVal;
}
}

// validate date.
$valid = CRM_Utils_Rule::$ruleName($dateVal);

if ($valid) {
// format date and time to default.
if ($ruleName == 'dateTime') {
$dateVal = CRM_Utils_Date::customFormat(preg_replace("/(:|\s)?/", "", $dateVal), '%Y%m%d%H%i');
// hack to add seconds
$dateVal .= '00';
}
$formattedDate = $dateVal;
}
return CRM_Utils_Rule::date($dateVal) ? $dateVal : FALSE;
}

return $formattedDate;
return FALSE;
}

/**
Expand Down
27 changes: 26 additions & 1 deletion tests/phpunit/CRM/Utils/DateTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ public function testGetFromTo() {
$cases = $this->fromToData();
foreach ($cases as $caseDescription => $case) {
$obj = new CRM_Utils_Date();
list($calculatedFrom, $calculatedTo) = $obj->getFromTo($case['relative'], $case['from'], $case['to']);
[$calculatedFrom, $calculatedTo] = $obj->getFromTo($case['relative'], $case['from'], $case['to']);
$this->assertEquals($case['expectedFrom'], $calculatedFrom, "Expected From failed for case $caseDescription");
$this->assertEquals($case['expectedTo'], $calculatedTo, "Expected To failed for case $caseDescription");
}
Expand Down Expand Up @@ -324,4 +324,29 @@ public function testLocalizeConsts() {
}
}

/**
* Test formatDate function.
*
* @dataProvider dateDataProvider
*
* Test the format function used in imports. Note most forms
* are able to format pre-submit but the import needs to parse the date.
*/
public function testFormatDate($date, $format, $expected): void {
$this->assertEquals($expected, CRM_Utils_Date::formatDate($date, $format));
}

/**
* Data provider for date formats.
*
* @return array[]
*/
public function dateDataProvider(): array {
return [
['date' => '2022-10-01', 'format' => CRM_Core_Form_Date::DATE_yyyy_mm_dd, 'expected' => '20221001'],
['date' => '2022-10-01 15:54', 'format' => CRM_Core_Form_Date::DATE_yyyy_mm_dd, 'expected' => '20221001155400'],
['date' => '2022-10-01 15:54:56', 'format' => CRM_Core_Form_Date::DATE_yyyy_mm_dd, 'expected' => '20221001155456'],
];
}

}

0 comments on commit aa65dcd

Please sign in to comment.