*/
use Civi\Api4\Email;
-use Civi\Api4\Contribution;
/**
* This class provides the common functionality for tasks that send emails.
$bcc = $this->getEmailString($bccArray);
$additionalDetails .= empty($bccArray) ? '' : "\nbcc : " . $this->getEmailUrlString($bccArray);
- // format contact details array to handle multiple emails from same contact
- $formattedContactDetails = [];
- foreach ($this->getEmails() as $details) {
- $formattedContactDetails[$details['contact_id'] . '::' . $details['email']] = $details;
- }
-
// send the mail
[$sent, $activityIds] = $this->sendEmail(
- $formattedContactDetails,
$formValues['text_message'],
$formValues['html_message'],
$from,
$cc,
$bcc,
$additionalDetails,
- $this->getContributionIDs(),
CRM_Utils_Array::value('campaign_id', $formValues),
$this->getCaseID()
);
}
}
- /**
- * List available tokens for this form.
- *
- * @return array
- */
- public function listTokens(): array {
- return CRM_Core_SelectValues::contactTokens();
- }
-
/**
* Get the emails from the added element.
*
*
* Also insert a contact activity in each contacts record.
*
- * @param array $contactDetails
- * The array of contact details to send the email.
* @param $text
* @param $html
* @param string $from
* Bcc recipient.
* @param string|null $additionalDetails
* The additional information of CC and BCC appended to the activity Details.
- * @param array|null $contributionIds
* @param int|null $campaignId
* @param int|null $caseId
*
*
* @throws \API_Exception
* @throws \CRM_Core_Exception
- * @throws \Civi\API\Exception\UnauthorizedException
+ * @throws \PEAR_Exception
* @internal
*
* Also insert a contact activity in each contacts record.
*
+ * @internal
+ *
+ * Also insert a contact activity in each contacts record.
*/
public function sendEmail(
- $contactDetails,
$text,
$html,
$from,
$cc = NULL,
$bcc = NULL,
$additionalDetails = NULL,
- $contributionIds = NULL,
$campaignId = NULL,
$caseId = NULL
) {
$userID = CRM_Core_Session::getLoggedInContactID();
- $contributionDetails = [];
- if (!empty($contributionIds)) {
- $contributionDetails = Contribution::get(FALSE)
- ->setSelect(['contact_id'])
- ->addWhere('id', 'IN', $contributionIds)
- ->execute()
- // Note that this indexing means that only the last
- // contribution per contact is resolved to tokens.
- // this is long-standing functionality, albeit possibly
- // not thought through.
- ->indexBy('contact_id');
- }
-
$sent = $notSent = [];
$attachmentFileIds = [];
$activityIds = [];
$firstActivityCreated = FALSE;
- foreach ($contactDetails as $values) {
- $tokenContext = $caseId ? ['caseId' => $caseId] : [];
+ foreach ($this->getRowsForEmails() as $values) {
$contactId = $values['contact_id'];
$emailAddress = $values['email'];
-
- if (!empty($contributionDetails)) {
- $tokenContext['contributionId'] = $contributionDetails[$contactId]['id'];
- }
-
$renderedTemplate = CRM_Core_BAO_MessageTemplate::renderTemplate([
'messageTemplate' => [
'msg_text' => $text,
'msg_html' => $html,
'msg_subject' => $this->getSubject(),
],
- 'tokenContext' => $tokenContext,
+ 'tokenContext' => array_merge(['schema' => $this->getTokenSchema()], ($values['schema'] ?? [])),
'contactId' => $contactId,
'disableSmarty' => !CRM_Utils_Constant::value('CIVICRM_MAIL_SMARTY'),
]);
return $url;
}
+ /**
+ * Get the result rows to email.
+ *
+ * @return array
+ *
+ * @throws \API_Exception
+ * @throws \CRM_Core_Exception
+ */
+ protected function getRowsForEmails(): array {
+ $rows = [];
+ foreach ($this->getRows() as $row) {
+ $rows[$row['contact_id']][] = $row;
+ }
+ // format contact details array to handle multiple emails from same contact
+ $formattedContactDetails = [];
+ foreach ($this->getEmails() as $details) {
+ $contactID = $details['contact_id'];
+ $index = $contactID . '::' . $details['email'];
+ if (!isset($rows[$contactID])) {
+ $formattedContactDetails[$index] = $details;
+ continue;
+ }
+ if ($this->isGroupByContact()) {
+ foreach ($rows[$contactID] as $rowDetail) {
+ $details['schema'] = $rowDetail['schema'] ?? [];
+ }
+ $formattedContactDetails[$index] = $details;
+ }
+ else {
+ foreach ($rows[$contactID] as $key => $rowDetail) {
+ $index .= '_' . $key;
+ $formattedContactDetails[$index] = $details;
+ $formattedContactDetails[$index]['schema'] = $rowDetail['schema'] ?? [];
+ }
+ }
+
+ }
+ return $formattedContactDetails;
+ }
+
+ /**
+ * Only send one email per contact.
+ *
+ * This has historically been done for contributions & makes sense if
+ * no entity specific tokens are in use.
+ *
+ * @return bool
+ */
+ protected function isGroupByContact(): bool {
+ return TRUE;
+ }
+
+ /**
+ * Get the tokens in the submitted message.
+ *
+ * @return array
+ * @throws \CRM_Core_Exception
+ */
+ protected function getMessageTokens(): array {
+ return CRM_Utils_Token::getTokens($this->getSubject() . $this->getSubmittedValue('html_message') . $this->getSubmittedValue('text_message'));
+ }
+
}
* @copyright CiviCRM LLC https://civicrm.org/licensing
*/
+use Civi\Api4\Contribution;
+
/**
* This class provides the functionality to email a group of contacts.
*/
return $this->getIDs();
}
+ /**
+ * Get the result rows to email.
+ *
+ * @return array
+ *
+ * @throws \API_Exception
+ * @throws \CRM_Core_Exception
+ */
+ protected function getRows(): array {
+ $contributionDetails = Contribution::get(FALSE)
+ ->setSelect(['contact_id', 'id'])
+ ->addWhere('id', 'IN', $this->getContributionIDs())
+ ->execute()
+ // Note that this indexing means that only the last
+ // contribution per contact is resolved to tokens.
+ // this is long-standing functionality, albeit possibly
+ // not thought through.
+ ->indexBy('contact_id');
+
+ // format contact details array to handle multiple emails from same contact
+ $formattedContactDetails = [];
+ foreach ($this->getEmails() as $details) {
+ $formattedContactDetails[$details['contact_id'] . '::' . $details['email']] = $details;
+ if (!empty($contributionDetails[$details['contact_id']])) {
+ $formattedContactDetails[$details['contact_id'] . '::' . $details['email']]['schema'] = ['contributionId' => $contributionDetails[$details['contact_id']]['id']];
+ }
+
+ }
+ return $formattedContactDetails;
+ }
+
}
* @copyright CiviCRM LLC https://civicrm.org/licensing
*/
+use Civi\Api4\Membership;
+
/**
* Class for member form task actions.
* FIXME: This needs refactoring to properly inherit from CRM_Core_Form_Task and share more functions.
);
}
+ /**
+ * @return array
+ */
+ protected function getIDS() {
+ return $this->_memberIds;
+ }
+
+ /**
+ * Get the rows form the search, keyed to make the token processor happy.
+ *
+ * @throws \API_Exception
+ */
+ protected function getRows(): array {
+ if (empty($this->rows)) {
+ // checkPermissions set to false - in case form is bypassing in some way.
+ $memberships = Membership::get(FALSE)
+ ->addWhere('id', 'IN', $this->getIDs())
+ ->setSelect(['id', 'contact_id'])->execute();
+ foreach ($memberships as $membership) {
+ $this->rows[] = [
+ 'contact_id' => $membership['contact_id'],
+ 'membership_id' => $membership['id'],
+ 'schema' => [
+ 'contactId' => $membership['contact_id'],
+ 'membershipId' => $membership['id'],
+ ],
+ ];
+ }
+ }
+ return $this->rows;
+ }
+
/**
* Get the token processor schema required to list any tokens for this task.
*