Consolidate import date handling
authoreileen <emcnaughton@wikimedia.org>
Thu, 28 Dec 2023 01:01:56 +0000 (14:01 +1300)
committereileen <emcnaughton@wikimedia.org>
Thu, 28 Dec 2023 02:35:53 +0000 (15:35 +1300)
12 files changed:
CRM/Activity/Import/Form/DataSource.php
CRM/Core/Form/Date.php
CRM/Import/Form/DataSource.php
CRM/Utils/Date.php
ext/civiimport/tests/phpunit/CiviApiImportTest.php
tests/phpunit/CRM/Activity/Import/Parser/ActivityTest.php
tests/phpunit/CRM/Contact/Import/Parser/ContactTest.php
tests/phpunit/CRM/Contribute/Import/Parser/ContributionTest.php
tests/phpunit/CRM/Event/Import/Parser/ParticipantTest.php
tests/phpunit/CRM/Member/Import/Parser/MembershipTest.php
tests/phpunit/CRM/Utils/DateTest.php
tests/phpunit/CRMTraits/Import/ParserTrait.php

index cc27fcd6e96cadc541e1aa477b088fc53608b8cf..b8215234c37bef7e2cd42300a5381829e6375a19 100644 (file)
  */
 class CRM_Activity_Import_Form_DataSource extends CRM_Import_Form_DataSource {
 
+  /**
+   * Should the text describing date formats include the time.
+   *
+   * This is used to alter the displayed text to that perceived to be more useful.
+   * For activities it is likely the user wants to know how to format time.
+   *
+   * @var bool
+   */
+  protected $isDisplayTimeInDateFormats = TRUE;
+
   /**
    * Get the name of the type to be stored in civicrm_user_job.type_id.
    *
index 847f2e4f8e199485a0cb76e2698e0e07b350b294..ada1f2fa152cd9bbad6188fc7a3a335bda824cc3 100644 (file)
@@ -10,6 +10,8 @@
  */
 
 /**
+ *
+ * @deprecated since 5.69 will be removed around 5.79
  *
  * @package CRM
  * @copyright CiviCRM LLC https://civicrm.org/licensing
@@ -18,17 +20,21 @@ class CRM_Core_Form_Date {
 
   /**
    * Various Date Formats.
+   *
+   * @deprecated since 5.69 will be removed around 5.79
    */
   const DATE_yyyy_mm_dd = 1, DATE_mm_dd_yy = 2, DATE_mm_dd_yyyy = 4, DATE_Month_dd_yyyy = 8, DATE_dd_mon_yy = 16, DATE_dd_mm_yyyy = 32;
 
   /**
    * Build the date-format form.
    *
+   * @deprecated since 5.69 will be removed around 5.79
+   *
    * @param CRM_Core_Form $form
    *   The form object that we are operating on.
    */
   public static function buildAllowedDateFormats(&$form) {
-
+    CRM_Core_Error::deprecatedFunctionWarning('function & entire class will be removed');
     $dateOptions = [];
 
     if (CRM_Utils_System::getClassName($form) == 'CRM_Activity_Import_Form_DataSource') {
@@ -52,7 +58,7 @@ class CRM_Core_Form_Date {
   /**
    * Build the date range array that will provide the form option values.
    *
-   * @deprecated
+   * @deprecated since 5.28 will be removed around 5.79
    *
    * It can be - relative or absolute.
    *
@@ -78,7 +84,7 @@ class CRM_Core_Form_Date {
     $required = FALSE, $operators = [],
     $dateFormat = 'searchDate', $displayTime = FALSE
   ) {
-    CRM_Core_Error::deprecatedFunctionWarning('function will be removed');
+    CRM_Core_Error::deprecatedFunctionWarning('function has been deprecated since 5.28 & will be removed around 5.79');
     $selector = [
       '' => ts('- any -'),
       0 => ts('Choose Date Range'),
@@ -103,7 +109,7 @@ class CRM_Core_Form_Date {
   /**
    * Build the date range - relative or absolute.
    *
-   * @deprecated
+   * @deprecated since 5.28 will be removed around 5.79
    *
    * @param CRM_Core_Form $form
    *   The form object that we are operating on.
@@ -131,7 +137,7 @@ class CRM_Core_Form_Date {
     $displayTime,
     $attributes
   ) {
-    CRM_Core_Error::deprecatedFunctionWarning('function will be removed');
+    CRM_Core_Error::deprecatedFunctionWarning('function has been deprecated since 5.28 & will be removed around 5.79');
     $form->add('select',
       "{$fieldName}_relative",
       ts('Relative Date Range'),
index c9ab949279f7e6efebed92996419c86e6405cb7a..30dfc17fdd2f2742f1e4bd1dc1c7e3b43a17067b 100644 (file)
@@ -23,6 +23,17 @@ use Civi\Api4\UserJob;
  */
 abstract class CRM_Import_Form_DataSource extends CRM_Import_Forms {
 
+  /**
+   * Should the text describing date formats include the time.
+   *
+   * This is used to alter the displayed text to that perceived to be more useful.
+   * e.g. for contacts it might be birthdate so including time is confusing
+   * but activities would more likely use them.
+   *
+   * @var bool
+   */
+  protected $isDisplayTimeInDateFormats = FALSE;
+
   /**
    * Values loaded from a saved UserJob template.
    *
@@ -106,7 +117,7 @@ abstract class CRM_Import_Form_DataSource extends CRM_Import_Forms {
     }
 
     //build date formats
-    CRM_Core_Form_Date::buildAllowedDateFormats($this);
+    $this->buildAllowedDateFormats();
     // When we call buildDataSourceFields we add them to the form both for purposes of
     // initial display, but also so they are available during `postProcess`. Hence
     // we need to add them to the form when first displaying it, or when a csv has been
@@ -131,6 +142,15 @@ abstract class CRM_Import_Form_DataSource extends CRM_Import_Forms {
     ]);
   }
 
+  /**
+   * Build the date-format form.
+   */
+  protected function buildAllowedDateFormats(): void {
+    $formats = CRM_Utils_Date::getAvailableInputFormats($this->isDisplayTimeInDateFormats);
+    $this->addRadio('dateFormats', ts('Date Format'), $formats, [], '<br/>');
+    $this->setDefaults(['dateFormats' => array_key_first($formats)]);
+  }
+
   public function setDefaultValues() {
     return array_merge($this->dataSourceDefaults, [
       'dataSource' => $this->getDefaultDataSource(),
index 4501e3d0e171f2ca6ca6cb3f9c35897195305572..e4d89c0d332ce8ae6e6510cdf0752c4ffa5cb6b5 100644 (file)
  */
 class CRM_Utils_Date {
 
+  /**
+   * Date input formats.
+   *
+   * For example a user selecting `DATE_dd_mm_yyyy` in the context of an import is
+   * saying that they want the dates they are importing to be converted from dd_mm_yyy format.
+   */
+  public const DATE_yyyy_mm_dd = 1, DATE_mm_dd_yy = 2, DATE_mm_dd_yyyy = 4, DATE_Month_dd_yyyy = 8, DATE_dd_mon_yy = 16, DATE_dd_mm_yyyy = 32;
+
   /**
    * Format a date by padding it with leading '0'.
    *
@@ -220,6 +228,33 @@ class CRM_Utils_Date {
     return \Civi::$statics[__CLASS__][$key];
   }
 
+  /**
+   * Get the available input formats.
+   *
+   * These are the formats that this class is able to convert into a standard format
+   * provided it knows the input format. These are used when doing an import.
+   *
+   * @param bool $isShowTime
+   *
+   * @return array
+   */
+  public static function getAvailableInputFormats(bool $isShowTime): array {
+    if ($isShowTime) {
+      $dateText = ts('yyyy-mm-dd OR yyyy-mm-dd HH:mm OR yyyymmdd OR yyyymmdd HH:mm (1998-12-25 OR 1998-12-25 15:33 OR 19981225 OR 19981225 10:30 OR ( 2008-9-1 OR 2008-9-1 15:33 OR 20080901 15:33)');
+    }
+    else {
+      $dateText = ts('yyyy-mm-dd OR yyyymmdd (1998-12-25 OR 19981225) OR (2008-9-1 OR 20080901)');
+    }
+    return [
+      CRM_Utils_Date::DATE_yyyy_mm_dd => $dateText,
+      CRM_Utils_Date::DATE_mm_dd_yy => ts('mm/dd/yy OR mm-dd-yy (12/25/98 OR 12-25-98) OR (9/1/08 OR 9-1-08)'),
+      CRM_Utils_Date::DATE_mm_dd_yyyy => ts('mm/dd/yyyy OR mm-dd-yyyy (12/25/1998 OR 12-25-1998) OR (9/1/2008 OR 9-1-2008)'),
+      CRM_Utils_Date::DATE_Month_dd_yyyy => ts('Month dd, yyyy (December 12, 1998)'),
+      CRM_Utils_Date::DATE_dd_mon_yy => ts('dd-mon-yy OR dd/mm/yy (25-Dec-98 OR 25/12/98 OR 1-09-98)'),
+      CRM_Utils_Date::DATE_dd_mm_yyyy => ts('dd/mm/yyyy (25/12/1998 OR 1/9/2008 OR 1-Sep-2008)'),
+    ];
+  }
+
   /**
    * Return abbreviated month names according to the locale.
    *
@@ -2134,7 +2169,7 @@ class CRM_Utils_Date {
    * @param $date
    *   Date string as entered.
    * @param $dateType
-   *   One of the constants like CRM_Core_Form_Date::DATE_yyyy_mm_dd.
+   *   One of the constants like CRM_Utils_Date::DATE_yyyy_mm_dd.
    *
    * @return null|string
    */
index 0273a4e2d2a364e66327b8b7b7000ea21de3a836..b93e5a801024db912ff07f43f12346506c4ebb9b 100644 (file)
@@ -65,7 +65,7 @@ class CiviApiImportTest extends TestCase implements HeadlessInterface, HookInter
           'dataSource' => 'CRM_Import_DataSource_SQL',
           'onDuplicate' => CRM_Import_Parser::DUPLICATE_SKIP,
           'dedupe_rule_id' => NULL,
-          'dateFormats' => CRM_Core_Form_Date::DATE_yyyy_mm_dd,
+          'dateFormats' => CRM_Utils_Date::DATE_yyyy_mm_dd,
         ],
         'import_mappings' => [
           ['name' => 'external_identifier'],
index dc3aec82e76d1a0d614384051f7368c75c54d84e..551537de351a87ec2ce5107d3b75120b2c5e06ba 100644 (file)
@@ -394,7 +394,7 @@ class CRM_Activity_Import_Parser_ActivityTest extends CiviUnitTestCase {
           'sqlQuery' => 'SELECT first_name FROM civicrm_contact',
           'onDuplicate' => CRM_Import_Parser::DUPLICATE_SKIP,
           'dedupe_rule_id' => NULL,
-          'dateFormats' => CRM_Core_Form_Date::DATE_yyyy_mm_dd,
+          'dateFormats' => CRM_Utils_Date::DATE_yyyy_mm_dd,
         ], $submittedValues),
       ],
       'status_id:name' => 'draft',
index deee21ad2b1e25e4b569587d5771448303bbc807..7acc64fc00cdbb032afaedc63d9f1de7511a9dff 100644 (file)
@@ -1564,12 +1564,12 @@ class CRM_Contact_Import_Parser_ContactTest extends CiviUnitTestCase {
    */
   public function dateDataProvider(): array {
     return [
-      'type_1' => ['csv' => 'individual_dates_type1.csv', 'dateType' => CRM_Core_Form_Date::DATE_yyyy_mm_dd],
-      'type_2' => ['csv' => 'individual_dates_type2.csv', 'dateType' => CRM_Core_Form_Date::DATE_mm_dd_yy],
-      'type_4' => ['csv' => 'individual_dates_type4.csv', 'dateType' => CRM_Core_Form_Date::DATE_mm_dd_yyyy],
-      'type_8' => ['csv' => 'individual_dates_type8.csv', 'dateType' => CRM_Core_Form_Date::DATE_Month_dd_yyyy],
-      'type_16' => ['csv' => 'individual_dates_type16.csv', 'dateType' => CRM_Core_Form_Date::DATE_dd_mon_yy],
-      'type_32' => ['csv' => 'individual_dates_type32.csv', 'dateType' => CRM_Core_Form_Date::DATE_dd_mm_yyyy],
+      'type_1' => ['csv' => 'individual_dates_type1.csv', 'dateType' => CRM_Utils_Date::DATE_yyyy_mm_dd],
+      'type_2' => ['csv' => 'individual_dates_type2.csv', 'dateType' => CRM_Utils_Date::DATE_mm_dd_yy],
+      'type_4' => ['csv' => 'individual_dates_type4.csv', 'dateType' => CRM_Utils_Date::DATE_mm_dd_yyyy],
+      'type_8' => ['csv' => 'individual_dates_type8.csv', 'dateType' => CRM_Utils_Date::DATE_Month_dd_yyyy],
+      'type_16' => ['csv' => 'individual_dates_type16.csv', 'dateType' => CRM_Utils_Date::DATE_dd_mon_yy],
+      'type_32' => ['csv' => 'individual_dates_type32.csv', 'dateType' => CRM_Utils_Date::DATE_dd_mm_yyyy],
     ];
   }
 
@@ -2204,7 +2204,7 @@ class CRM_Contact_Import_Parser_ContactTest extends CiviUnitTestCase {
           'sqlQuery' => 'SELECT first_name FROM civicrm_contact',
           'onDuplicate' => CRM_Import_Parser::DUPLICATE_SKIP,
           'dedupe_rule_id' => NULL,
-          'dateFormats' => CRM_Core_Form_Date::DATE_yyyy_mm_dd,
+          'dateFormats' => CRM_Utils_Date::DATE_yyyy_mm_dd,
         ], $submittedValues),
       ],
       'status_id:name' => 'draft',
@@ -2275,7 +2275,7 @@ class CRM_Contact_Import_Parser_ContactTest extends CiviUnitTestCase {
       'mapper' => $mapper,
       'dataSource' => 'CRM_Import_DataSource_CSV',
       'file' => ['name' => $csv],
-      'dateFormats' => CRM_Core_Form_Date::DATE_yyyy_mm_dd,
+      'dateFormats' => CRM_Utils_Date::DATE_yyyy_mm_dd,
       'onDuplicate' => CRM_Import_Parser::DUPLICATE_UPDATE,
       'groups' => [],
     ], $submittedValues);
index a76c9c7e86c085c617b2c0b6dad009be3fa7ef14..3ed941a0d07dd68393b9ae255bd556580605905b 100644 (file)
@@ -284,7 +284,7 @@ class CRM_Contribute_Import_Parser_ContributionTest extends CiviUnitTestCase {
       'contactType' => 'Organization',
       'mapper' => $this->getMapperFromFieldMappings($importMappings),
       'dataSource' => 'CRM_Import_DataSource_CSV',
-      'dateFormats' => CRM_Core_Form_Date::DATE_yyyy_mm_dd,
+      'dateFormats' => CRM_Utils_Date::DATE_yyyy_mm_dd,
       'onDuplicate' => CRM_Import_Parser::DUPLICATE_SKIP,
     ];
     $this->submitDataSourceForm('soft_credit_extended.csv', $submittedValues);
@@ -687,7 +687,7 @@ class CRM_Contribute_Import_Parser_ContributionTest extends CiviUnitTestCase {
       'mapper' => $this->getMapperFromFieldMappings($fieldMappings),
       'dataSource' => 'CRM_Import_DataSource_CSV',
       'file' => ['name' => 'contributions_bad_campaign.csv'],
-      'dateFormats' => CRM_Core_Form_Date::DATE_yyyy_mm_dd,
+      'dateFormats' => CRM_Utils_Date::DATE_yyyy_mm_dd,
       'onDuplicate' => CRM_Import_Parser::DUPLICATE_UPDATE,
       'groups' => [],
     ];
@@ -806,7 +806,7 @@ class CRM_Contribute_Import_Parser_ContributionTest extends CiviUnitTestCase {
           'sqlQuery' => 'SELECT first_name FROM civicrm_contact',
           'onDuplicate' => CRM_Import_Parser::DUPLICATE_SKIP,
           'dedupe_rule_id' => NULL,
-          'dateFormats' => CRM_Core_Form_Date::DATE_yyyy_mm_dd,
+          'dateFormats' => CRM_Utils_Date::DATE_yyyy_mm_dd,
         ], $submittedValues),
       ],
       'status_id:name' => 'draft',
index 3d87192e17af8580053c13c2d8e97317292bc426..216e635820ba234d8d8fb84e6826395b51aecb45 100644 (file)
@@ -58,7 +58,7 @@ class CRM_Event_Import_Parser_ParticipantTest extends CiviUnitTestCase {
       'mapper' => $this->getMapperFromFieldMappings($fieldMappings),
       'dataSource' => 'CRM_Import_DataSource_CSV',
       'file' => ['name' => $csv],
-      'dateFormats' => CRM_Core_Form_Date::DATE_yyyy_mm_dd,
+      'dateFormats' => CRM_Utils_Date::DATE_yyyy_mm_dd,
       'onDuplicate' => CRM_Import_Parser::DUPLICATE_UPDATE,
       'groups' => [],
       'saveMapping' => TRUE,
@@ -197,7 +197,7 @@ class CRM_Event_Import_Parser_ParticipantTest extends CiviUnitTestCase {
           'sqlQuery' => 'SELECT first_name FROM civicrm_contact',
           'onDuplicate' => CRM_Import_Parser::DUPLICATE_SKIP,
           'dedupe_rule_id' => NULL,
-          'dateFormats' => CRM_Core_Form_Date::DATE_yyyy_mm_dd,
+          'dateFormats' => CRM_Utils_Date::DATE_yyyy_mm_dd,
         ], $submittedValues),
       ],
       'status_id:name' => 'draft',
index d724395772971377dfacbb7f946128abf4db5792..53103d2493d8d184339dd7880abc056e9bf89b25 100644 (file)
@@ -352,7 +352,7 @@ class CRM_Member_Import_Parser_MembershipTest extends CiviUnitTestCase {
           'sqlQuery' => 'SELECT first_name FROM civicrm_contact',
           'onDuplicate' => CRM_Import_Parser::DUPLICATE_SKIP,
           'dedupe_rule_id' => NULL,
-          'dateFormats' => CRM_Core_Form_Date::DATE_yyyy_mm_dd,
+          'dateFormats' => CRM_Utils_Date::DATE_yyyy_mm_dd,
         ], $submittedValues),
       ],
       'status_id:name' => 'draft',
@@ -473,7 +473,7 @@ class CRM_Member_Import_Parser_MembershipTest extends CiviUnitTestCase {
       'mapper' => $this->getMapperFromFieldMappings($fieldMappings),
       'dataSource' => 'CRM_Import_DataSource_CSV',
       'file' => ['name' => $csv],
-      'dateFormats' => CRM_Core_Form_Date::DATE_yyyy_mm_dd,
+      'dateFormats' => CRM_Utils_Date::DATE_yyyy_mm_dd,
       'onDuplicate' => CRM_Import_Parser::DUPLICATE_UPDATE,
       'groups' => [],
     ], $submittedValues);
index 65a21079785f2b6fc7c7523dc13773a415f1060a..a645f1c612a5a4801a7c7e5990647e6b661a4322 100644 (file)
@@ -2672,9 +2672,9 @@ class CRM_Utils_DateTest extends CiviUnitTestCase {
    */
   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'],
+      ['date' => '2022-10-01', 'format' => CRM_Utils_Date::DATE_yyyy_mm_dd, 'expected' => '20221001'],
+      ['date' => '2022-10-01 15:54', 'format' => CRM_Utils_Date::DATE_yyyy_mm_dd, 'expected' => '20221001155400'],
+      ['date' => '2022-10-01 15:54:56', 'format' => CRM_Utils_Date::DATE_yyyy_mm_dd, 'expected' => '20221001155456'],
     ];
   }
 
index c28d26b49fc6c97477e44ba26b6461b242784968..6cf9c04dae7c17339b0c8b1671881b51b4c2ea47 100644 (file)
@@ -38,7 +38,7 @@ trait CRMTraits_Import_ParserTrait {
       'mapper' => $this->getMapperFromFieldMappings($fieldMappings),
       'dataSource' => 'CRM_Import_DataSource_CSV',
       'file' => ['name' => $csv],
-      'dateFormats' => CRM_Core_Form_Date::DATE_yyyy_mm_dd,
+      'dateFormats' => CRM_Utils_Date::DATE_yyyy_mm_dd,
       'onDuplicate' => CRM_Import_Parser::DUPLICATE_SKIP,
       'groups' => [],
     ], $submittedValues);
@@ -122,7 +122,7 @@ trait CRMTraits_Import_ParserTrait {
       'contactType' => 'Individual',
       'dataSource' => 'CRM_Import_DataSource_CSV',
       'file' => ['name' => $csv],
-      'dateFormats' => CRM_Core_Form_Date::DATE_yyyy_mm_dd,
+      'dateFormats' => CRM_Utils_Date::DATE_yyyy_mm_dd,
       'onDuplicate' => CRM_Import_Parser::DUPLICATE_SKIP,
       'groups' => [],
     ], $submittedValues);