CRM-19394: Relative date is not processed correctly
[civicrm-core.git] / CRM / Contact / ActionMapping.php
index b448ef2e444e1a694e2f62006a8f366e9179eb09..69a7dd3ca10b275b0a0982366c4e71e8c4d434a3 100644 (file)
@@ -1,9 +1,9 @@
 <?php
 /*
  +--------------------------------------------------------------------+
- | CiviCRM version 4.6                                                |
+ | CiviCRM version 4.7                                                |
  +--------------------------------------------------------------------+
- | Copyright CiviCRM LLC (c) 2004-2015                                |
+ | Copyright CiviCRM LLC (c) 2004-2016                                |
  +--------------------------------------------------------------------+
  | This file is a part of CiviCRM.                                    |
  |                                                                    |
@@ -37,12 +37,62 @@ use Civi\ActionSchedule\RecipientBuilder;
  */
 class CRM_Contact_ActionMapping extends \Civi\ActionSchedule\Mapping {
 
+  /**
+   * The value for civicrm_action_schedule.mapping_id which identifies the
+   * "Contact" mapping.
+   *
+   * Note: This value is chosen to match legacy DB IDs.
+   */
+  const CONTACT_MAPPING_ID = 6;
+
+  /**
+   * Register Contact-related action mappings.
+   *
+   * @param \Civi\ActionSchedule\Event\MappingRegisterEvent $registrations
+   */
+  public static function onRegisterActionMappings(\Civi\ActionSchedule\Event\MappingRegisterEvent $registrations) {
+    $registrations->register(CRM_Contact_ActionMapping::create(array(
+      'id' => CRM_Contact_ActionMapping::CONTACT_MAPPING_ID,
+      'entity' => 'civicrm_contact',
+      'entity_label' => ts('Contact'),
+      'entity_value' => 'civicrm_contact',
+      'entity_value_label' => ts('Date Field'),
+      'entity_status' => 'contact_date_reminder_options',
+      'entity_status_label' => ts('Annual Options'),
+      'entity_date_start' => 'date_field',
+    )));
+  }
+
   private $contactDateFields = array(
     'birth_date',
     'created_date',
     'modified_date',
   );
 
+  /**
+   * Determine whether a schedule based on this mapping is sufficiently
+   * complete.
+   *
+   * @param \CRM_Core_DAO_ActionSchedule $schedule
+   * @return array
+   *   Array (string $code => string $message).
+   *   List of error messages.
+   */
+  public function validateSchedule($schedule) {
+    $errors = array();
+    if (CRM_Utils_System::isNull($schedule->entity_value) || $schedule->entity_value === '0') {
+      $errors['entity'] = ts('Please select a specific date field.');
+    }
+    elseif (count(CRM_Utils_Array::explodePadded($schedule->entity_value)) > 1) {
+      $errors['entity'] = ts('You may only select one contact field per reminder');
+    }
+    elseif (CRM_Utils_System::isNull($schedule->entity_status) || $schedule->entity_status === '0') {
+      $errors['entity'] = ts('Please select whether the reminder is sent each year.');
+    }
+
+    return $errors;
+  }
+
   /**
    * Generate a query to locate recipients who match the given
    * schedule.
@@ -51,11 +101,13 @@ class CRM_Contact_ActionMapping extends \Civi\ActionSchedule\Mapping {
    *   The schedule as configured by the administrator.
    * @param string $phase
    *   See, e.g., RecipientBuilder::PHASE_RELATION_FIRST.
+   * @param array $defaultParams
+   *
    * @return \CRM_Utils_SQL_Select
-   * @see RecipientBuilder
    * @throws \CRM_Core_Exception
+   * @see RecipientBuilder
    */
-  public function createQuery($schedule, $phase) {
+  public function createQuery($schedule, $phase, $defaultParams) {
     $selectedValues = (array) \CRM_Utils_Array::explodePadded($schedule->entity_value);
     $selectedStatuses = (array) \CRM_Utils_Array::explodePadded($schedule->entity_status);
 
@@ -66,7 +118,7 @@ class CRM_Contact_ActionMapping extends \Civi\ActionSchedule\Mapping {
     }
     elseif (in_array($selectedValues[0], $this->contactDateFields)) {
       $dateDBField = $selectedValues[0];
-      $query = \CRM_Utils_SQL_Select::from("{$this->entity} e");
+      $query = \CRM_Utils_SQL_Select::from("{$this->entity} e")->param($defaultParams);
       $query->param(array(
         'casAddlCheckFrom' => 'civicrm_contact e',
         'casContactIdField' => 'e.id',
@@ -83,7 +135,7 @@ class CRM_Contact_ActionMapping extends \Civi\ActionSchedule\Mapping {
       $dateDBField = $customField['column_name'];
       $customGroupParams = array('id' => $customField['custom_group_id'], $customGroup);
       \CRM_Core_BAO_CustomGroup::retrieve($customGroupParams, $customGroup);
-      $query = \CRM_Utils_SQL_Select::from("{$customGroup['table_name']} e");
+      $query = \CRM_Utils_SQL_Select::from("{$customGroup['table_name']} e")->param($defaultParams);
       $query->param(array(
         'casAddlCheckFrom' => "{$customGroup['table_name']} e",
         'casContactIdField' => 'e.entity_id',
@@ -97,7 +149,7 @@ class CRM_Contact_ActionMapping extends \Civi\ActionSchedule\Mapping {
 
     if (in_array(2, $selectedStatuses)) {
       $query['casAnniversaryMode'] = 1;
-      $query['casDateField'] = 'DATE_ADD(' . $query['casDateField'] . ', INTERVAL ROUND(DATEDIFF(DATE(!casNow), ' . $query['casDateField'] . ') / 365) YEAR)';
+      $query['casDateField'] = 'DATE_ADD(' . $query['casDateField'] . ', INTERVAL ROUND(DATEDIFF(DATE(' . $query['casNow'] . '), ' . $query['casDateField'] . ') / 365) YEAR)';
     }
 
     return $query;