* @param int $caseId
*
* @return array
- * ( sent, activityId) if any email is sent and activityId
+ * bool $sent FIXME: this only indicates the status of the last email sent.
+ * array $activityIds The activity ids created, one per "To" recipient.
+ *
* @throws \CRM_Core_Exception
* @throws \CiviCRM_API3_Exception
*/
$sent = $notSent = [];
$attachmentFileIds = [];
+ $activityIds = [];
$firstActivityCreated = FALSE;
foreach ($contactDetails as $values) {
$contactId = $values['contact_id'];
// Create email activity.
$activityID = self::createEmailActivity($userID, $tokenSubject, $tokenHtml, $tokenText, $additionalDetails, $campaignId, $attachments, $caseId);
+ $activityIds[] = $activityID;
if ($firstActivityCreated == FALSE && !empty($attachments)) {
$attachmentFileIds = self::getAttachmentFileIds($activityID, $attachments);
}
}
- return [$sent, $activityID];
+ return [$sent, $activityIds];
}
/**
}
// send the mail
- list($sent, $activityId) = CRM_Activity_BAO_Activity::sendEmail(
+ list($sent, $activityIds) = CRM_Activity_BAO_Activity::sendEmail(
$formattedContactDetails,
$this->getSubject($formValues['subject']),
$formValues['text_message'],
);
if ($sent) {
- $followupStatus = $this->createFollowUpActivities($formValues, $activityId);
+ // Only use the first activity id if there's multiple.
+ // If there's multiple recipients the idea behind multiple activities
+ // is to record the token value replacements separately, but that
+ // has no meaning for followup activities, and this doesn't prevent
+ // creating more manually if desired.
+ $followupStatus = $this->createFollowUpActivities($formValues, $activityIds[0]);
$count_success = count($this->_toContactDetails);
CRM_Core_Session::setStatus(ts('One message was sent successfully. ', [
'plural' => '%count messages were sent successfully. ',
$text = __FUNCTION__ . ' text';
$userID = $loggedInUser;
- list($sent, $activity_id) = $email_result = CRM_Activity_BAO_Activity::sendEmail(
+ list($sent, $activity_ids) = $email_result = CRM_Activity_BAO_Activity::sendEmail(
$contactDetails,
$subject,
$text,
$from = __FUNCTION__ . '@example.com'
);
- $activity = $this->civicrm_api('activity', 'getsingle', ['id' => $activity_id, 'version' => $this->_apiversion]);
+ $activity = $this->civicrm_api('activity', 'getsingle', ['id' => $activity_ids[0], 'version' => $this->_apiversion]);
$details = "-ALTERNATIVE ITEM 0-
$html
-ALTERNATIVE ITEM 1-
$text = __FUNCTION__ . ' text';
$userID = $loggedInUser;
- list($sent, $activity_id) = $email_result = CRM_Activity_BAO_Activity::sendEmail(
+ list($sent, $activity_ids) = $email_result = CRM_Activity_BAO_Activity::sendEmail(
$contactDetails,
$subject,
$text,
NULL,
$campaign_id
);
- $activity = $this->civicrm_api('activity', 'getsingle', ['id' => $activity_id, 'version' => $this->_apiversion]);
+ $activity = $this->civicrm_api('activity', 'getsingle', ['id' => $activity_ids[0], 'version' => $this->_apiversion]);
$this->assertEquals($activity['campaign_id'], $campaign_id, 'Activity campaign_id does not match.');
}
$text = __FUNCTION__ . ' text';
$mut = new CiviMailUtils($this, TRUE);
- list($sent, $activity_id) = $email_result = CRM_Activity_BAO_Activity::sendEmail(
+ list($sent, $activity_ids) = $email_result = CRM_Activity_BAO_Activity::sendEmail(
$contact['values'],
$subject,
$text,
NULL,
$caseId
);
- $activity = $this->callAPISuccess('Activity', 'getsingle', ['id' => $activity_id, 'return' => ['case_id']]);
+ $activity = $this->callAPISuccess('Activity', 'getsingle', ['id' => $activity_ids[0], 'return' => ['case_id']]);
$this->assertEquals($caseId, $activity['case_id'][0], 'Activity case_id does not match.');
$mut->checkMailLog(['subject my case']);
$mut->stop();
];
}
+ /**
+ * Test the returned activity ids when there are multiple "To" recipients.
+ * Similar to testSendEmailWillReplaceTokensUniquelyForEachContact but we're
+ * checking the activity ids returned from sendEmail.
+ */
+ public function testSendEmailWithMultipleToRecipients() {
+ $contactId1 = $this->individualCreate(['first_name' => 'Aaaa', 'last_name' => 'Bbbb']);
+ $contactId2 = $this->individualCreate(['first_name' => 'Cccc', 'last_name' => 'Dddd']);
+
+ // create a logged in USER since the code references it for sendEmail user.
+ $loggedInUser = $this->createLoggedInUser();
+ $contacts = $this->callAPISuccess('Contact', 'get', [
+ 'sequential' => 1,
+ 'id' => ['IN' => [$contactId1, $contactId2]],
+ ]);
+
+ list($sent, $activityIds) = CRM_Activity_BAO_Activity::sendEmail(
+ $contacts['values'],
+ 'a subject',
+ 'here is some text',
+ '<p>here is some html</p>',
+ $contacts['values'][0]['email'],
+ $loggedInUser,
+ $from = __FUNCTION__ . '@example.com',
+ $attachments = NULL,
+ $cc = NULL,
+ $bcc = NULL,
+ $contactIds = array_column($contacts['values'], 'id'),
+ $additionalDetails = NULL,
+ NULL,
+ $campaign_id = NULL
+ );
+
+ // Get all activities for these contacts
+ $result = $this->callAPISuccess('activity', 'get', [
+ 'sequential' => 1,
+ 'return' => ['target_contact_id'],
+ 'target_contact_id' => ['IN' => [$contactId1, $contactId2]],
+ ]);
+
+ // There should be one activity created for each of the two contacts
+ $this->assertEquals(2, $result['count']);
+
+ // Activity ids returned from sendEmail should match the ones returned from api call.
+ $this->assertEquals($activityIds, array_column($result['values'], 'id'));
+
+ // Is it the right contacts?
+ $this->assertEquals(
+ [0 => [0 => $contactId1], 1 => [0 => $contactId2]],
+ array_column($result['values'], 'target_contact_id')
+ );
+ $this->assertEquals(
+ [0 => [$contactId1 => 'Bbbb, Aaaa'], 1 => [$contactId2 => 'Dddd, Cccc']],
+ array_column($result['values'], 'target_contact_sort_name')
+ );
+ }
+
}