Merge pull request #2264 from dlobo/CRM-13606
[civicrm-core.git] / CRM / Core / BAO / ActionSchedule.php
index eb36170e2d788c73471b4beda8d462c8514cab51..decb24753ccc6b39de118bee79d6c4270db2dd4b 100755 (executable)
@@ -1,7 +1,7 @@
 <?php
 /*
   +--------------------------------------------------------------------+
-  | CiviCRM version 4.3                                                |
+  | CiviCRM version 4.4                                                |
   +--------------------------------------------------------------------+
   | Copyright (C) 2011 Marty Wright                                    |
   | Licensed to CiviCRM under the Academic Free License version 3.0.   |
@@ -214,7 +214,6 @@ class CRM_Core_BAO_ActionSchedule extends CRM_Core_DAO_ActionSchedule {
 
       }
     }
-
     return array(
       'sel1' => $sel1,
       'sel2' => $sel2,
@@ -464,6 +463,8 @@ WHERE   cas.entity_value = $id AND
         'toName' => $contact['display_name'],
         'toEmail' => $email,
         'subject' => $messageSubject,
+        'entity' => 'action_schedule',
+        'entity_id' => $scheduleID,
       );
 
       if (!$html || $contact['preferred_mail_format'] == 'Text' ||
@@ -496,7 +497,7 @@ WHERE   cas.entity_value = $id AND
    * @static
    *
    */
-  static function add(&$params, &$ids) {
+  static function add(&$params, $ids = array()) {
     $actionSchedule = new CRM_Core_DAO_ActionSchedule();
     $actionSchedule->copyValues($params);
 
@@ -606,7 +607,7 @@ WHERE   cas.entity_value = $id AND
         $extraJoin   = "
 INNER JOIN civicrm_option_group og ON og.name = 'activity_type'
 INNER JOIN civicrm_option_value ov ON e.activity_type_id = ov.value AND ov.option_group_id = og.id";
-        $extraOn = 'AND e.is_current_revision = 1 AND e.is_deleted = 0';
+        $extraOn = ' AND e.is_current_revision = 1 AND e.is_deleted = 0 ';
         if ($actionSchedule->limit_to == 0) {
           $extraJoin   = "
 LEFT JOIN civicrm_option_group og ON og.name = 'activity_type'
@@ -683,7 +684,7 @@ WHERE reminder.action_schedule_id = %1 AND reminder.action_date_time IS NULL
             $stateProvince = CRM_Core_PseudoConstant::stateProvince();
             $loc['street_address'] = $dao->street_address;
             $loc['city'] = $dao->city;
-            $loc['state_province'] = CRM_Utils_array::value($dao->state_province_id, $stateProvince);
+            $loc['state_province'] = CRM_Utils_Array::value($dao->state_province_id, $stateProvince);
             $loc['postal_code'] = $dao->postal_code;
             $entityTokenParams["{$tokenEntity}." . $field] = CRM_Utils_Address::format($loc);
           }
@@ -782,7 +783,7 @@ WHERE reminder.action_schedule_id = %1 AND reminder.action_date_time IS NULL
       $status = implode(',', $status);
 
       if (!CRM_Utils_System::isNull($mapping->entity_recipient)) {
-        $recipientOptions = CRM_Core_OptionGroup::values($mapping->entity_recipient);
+        $recipientOptions = CRM_Core_OptionGroup::values($mapping->entity_recipient, FALSE, FALSE, FALSE, NULL, 'name');
       }
       $from = "{$mapping->entity} e";
 
@@ -841,7 +842,7 @@ WHERE reminder.action_schedule_id = %1 AND reminder.action_date_time IS NULL
           $rList = implode(',', $rList);
 
           switch ($recipientOptions[$actionSchedule->recipient]) {
-            case 'Participant Role':
+            case 'participant_role':
               $where[] = "e.role_id IN ({$rList})";
               break;
 
@@ -899,10 +900,44 @@ WHERE reminder.action_schedule_id = %1 AND reminder.action_date_time IS NULL
         $where[] = "e.status_id IN ({$mStatus})";
       }
 
+      // CRM-13577 Introduce Smart Groups Handling
+      if ($actionSchedule->group_id) {
+
+        // Need to check if its a smart group or not
+        // Then decide which table to join onto the query
+        $group = CRM_Contact_DAO_Group::getTableName();
+
+        // Get the group information
+        $sql = "
+SELECT     $group.id, $group.cache_date, $group.saved_search_id, $group.children
+FROM       $group
+WHERE      $group.id = {$actionSchedule->group_id}
+";
+
+        $groupDAO = CRM_Core_DAO::executeQuery($sql);
+        $isSmartGroup = FALSE;
+        if (
+          $groupDAO->fetch() &&
+          !empty($groupDAO->saved_search_id)
+        ) {
+          // Check that the group is in place in the cache and up to date
+          CRM_Contact_BAO_GroupContactCache::check($actionSchedule->group_id);
+          // Set smart group flag
+          $isSmartGroup = TRUE;
+        }
+      }
+      // CRM-13577 End Introduce Smart Groups Handling
+
       if ($limitTo) {
         if ($actionSchedule->group_id) {
-          $join[] = "INNER JOIN civicrm_group_contact grp ON {$contactField} = grp.contact_id AND grp.status = 'Added'";
-          $where[] = "grp.group_id IN ({$actionSchedule->group_id})";
+          // CRM-13577 If smart group then use Cache table
+          if ($isSmartGroup) {
+            $join[] = "INNER JOIN civicrm_group_contact_cache grp ON {$contactField} = grp.contact_id";
+            $where[] = "grp.group_id IN ({$actionSchedule->group_id})";
+          } else {
+            $join[] = "INNER JOIN civicrm_group_contact grp ON {$contactField} = grp.contact_id AND grp.status = 'Added'";
+            $where[] = "grp.group_id IN ({$actionSchedule->group_id})";
+          }
         }
         elseif (!empty($actionSchedule->recipient_manual)) {
           $rList = CRM_Utils_Type::escape($actionSchedule->recipient_manual, 'String');
@@ -912,8 +947,14 @@ WHERE reminder.action_schedule_id = %1 AND reminder.action_date_time IS NULL
       else {
         $addGroup = $addWhere = '';
         if ($actionSchedule->group_id) {
-          $addGroup = " INNER JOIN civicrm_group_contact grp ON c.id = grp.contact_id AND grp.status = 'Added'";
-          $addWhere = " grp.group_id IN ({$actionSchedule->group_id})";
+          // CRM-13577 If smart group then use Cache table
+          if ($isSmartGroup) {
+            $addGroup = " INNER JOIN civicrm_group_contact_cache grp ON c.id = grp.contact_id";
+            $addWhere = " grp.group_id IN ({$actionSchedule->group_id})";
+          } else {
+            $addGroup = " INNER JOIN civicrm_group_contact grp ON c.id = grp.contact_id AND grp.status = 'Added'";
+            $addWhere = " grp.group_id IN ({$actionSchedule->group_id})";
+          }
         }
         if (!empty($actionSchedule->recipient_manual)) {
           $rList = CRM_Utils_Type::escape($actionSchedule->recipient_manual, 'String');
@@ -959,7 +1000,10 @@ reminder.action_schedule_id = %1";
       $fromClause = "FROM $from";
       $joinClause = !empty($join) ? implode(' ', $join) : '';
       $whereClause = 'WHERE ' . implode(' AND ', $where);
-      $limitWhere .= implode(' AND ', $limitWhere);
+      $limitWhereClause = '';
+      if (!empty($limitWhere)) {
+        $limitWhereClause = ' AND ' . implode(' AND ', $limitWhere);
+      }
 
       $query = "
 INSERT INTO civicrm_action_log (contact_id, entity_id, entity_table, action_schedule_id)
@@ -967,27 +1011,29 @@ INSERT INTO civicrm_action_log (contact_id, entity_id, entity_table, action_sche
 {$fromClause}
 {$joinClause}
 LEFT JOIN {$reminderJoinClause}
-{$whereClause} {$limitWhere} AND {$dateClause} {$notINClause}
+{$whereClause} {$limitWhereClause} AND {$dateClause} {$notINClause}
 ";
-
       CRM_Core_DAO::executeQuery($query, array(1 => array($actionSchedule->id, 'Integer')));
 
       if ($limitTo == 0) {
         $additionWhere = ' WHERE ';
         if ($actionSchedule->start_action_date) {
-          $additionWhere = $whereClause;
+          $additionWhere = $whereClause . ' AND ';
         }
+        $contactTable = "civicrm_contact c";
+        $addSelect  = "SELECT c.id as contact_id, c.id as entity_id, 'civicrm_contact' as entity_table, {$actionSchedule->id} as action_schedule_id";
+        $additionReminderClause = "civicrm_action_log reminder ON reminder.contact_id = c.id AND
+          reminder.entity_id          = c.id AND
+          reminder.entity_table       = 'civicrm_contact' AND
+          reminder.action_schedule_id = {$actionSchedule->id}";
 
         $insertAdditionalSql ="
 INSERT INTO civicrm_action_log (contact_id, entity_id, entity_table, action_schedule_id)
-     SELECT c.id as contact_id, c.id as entity_id, 'civicrm_contact' as entity_table, {$actionSchedule->id} as action_schedule_id
-FROM (civicrm_contact c, {$table})
-LEFT JOIN civicrm_action_log reminder ON reminder.contact_id = c.id AND
-        reminder.entity_id          = c.id AND
-        reminder.entity_table       = 'civicrm_contact' AND
-        reminder.action_schedule_id = {$actionSchedule->id}
+{$addSelect}
+FROM ({$contactTable}, {$table})
+LEFT JOIN {$additionReminderClause}
 {$addGroup}
-{$additionWhere} (reminder.id IS NULL AND c.is_deleted = 0 AND c.is_deceased = 0 AND {$addWhere})
+{$additionWhere} c.is_deleted = 0 AND c.is_deceased = 0 AND {$addWhere}
 AND {$dateClause}
 AND c.id NOT IN (
      SELECT rem.contact_id
@@ -995,6 +1041,7 @@ AND c.id NOT IN (
      WHERE rem.action_schedule_id = {$actionSchedule->id}
       AND rem.entity_table = '{$mapping->entity}'
     )
+GROUP BY c.id
 ";
         CRM_Core_DAO::executeQuery($insertAdditionalSql);
       }
@@ -1018,12 +1065,11 @@ AND c.id NOT IN (
         $havingClause = "HAVING TIMEDIFF({$now}, latest_log_time) >= TIME('{$hrs}:00:00')";
         $groupByClause = 'GROUP BY reminder.contact_id, reminder.entity_id, reminder.entity_table';
         $selectClause .= ', MAX(reminder.action_date_time) as latest_log_time';
-
         $sqlInsertValues = "{$selectClause}
 {$fromClause}
 {$joinClause}
 INNER JOIN {$reminderJoinClause}
-{$whereClause} AND {$repeatEventClause}
+{$whereClause} {$limitWhereClause} AND {$repeatEventClause}
 {$groupByClause}
 {$havingClause}";
 
@@ -1041,6 +1087,38 @@ INNER JOIN {$reminderJoinClause}
               INSERT INTO civicrm_action_log (contact_id, entity_id, entity_table, action_schedule_id) VALUES ' . $valString;
           CRM_Core_DAO::executeQuery($query, array(1 => array($actionSchedule->id, 'Integer')));
         }
+
+        if ($limitTo == 0) {
+          $addSelect .= ', MAX(reminder.action_date_time) as latest_log_time';
+          $sqlEndEventCheck = "
+SELECT * FROM {$table}
+{$whereClause} AND {$repeatEventClause} LIMIT 1";
+
+          $daoCheck = CRM_Core_DAO::executeQuery($sqlEndEventCheck);
+          if ($daoCheck->fetch()) {
+            $valSqlAdditionInsert = "
+{$addSelect}
+FROM  {$contactTable}
+{$addGroup}
+INNER JOIN {$additionReminderClause}
+WHERE {$addWhere} AND c.is_deleted = 0 AND c.is_deceased = 0
+GROUP BY reminder.contact_id
+{$havingClause}
+";
+            $daoForVals = CRM_Core_DAO::executeQuery($valSqlAdditionInsert);
+            $addValues = array();
+            while ($daoForVals->fetch()) {
+              $addValues[] = "( {$daoForVals->contact_id}, {$daoForVals->entity_id}, '{$daoForVals->entity_table}',{$daoForVals->action_schedule_id} )";
+            }
+            $valString = implode(',', $addValues);
+
+            if ($valString) {
+              $query = '
+                INSERT INTO civicrm_action_log (contact_id, entity_id, entity_table, action_schedule_id) VALUES ' . $valString;
+              CRM_Core_DAO::executeQuery($query);
+            }
+          }
+        }
       }
     }
   }
@@ -1117,7 +1195,7 @@ WHERE     m.owner_membership_id IS NOT NULL AND
         if (!CRM_Utils_Array::value($recipientType, $eventContacts)) {
           return $options;
         }
-        if ($eventContacts[$recipientType] == 'Participant Role') {
+        if ($eventContacts[$recipientType] == 'participant_role') {
           $options = CRM_Event_PseudoConstant::participantRole();
         }
         break;