Skip to content

Commit

Permalink
dev/core#2344 fix regression affecting sending thank you letters when…
Browse files Browse the repository at this point in the history
… grouped
  • Loading branch information
eileenmcnaughton committed Feb 1, 2021
1 parent 679b301 commit ec6e4b4
Show file tree
Hide file tree
Showing 4 changed files with 95 additions and 27 deletions.
15 changes: 10 additions & 5 deletions CRM/Contribute/Form/Task/PDFLetterCommon.php
Original file line number Diff line number Diff line change
Expand Up @@ -216,15 +216,18 @@ public static function isHtmlTokenInTableCell($token, $entity, $textToSearch) {
* Does this letter represent more than one contribution.
* @param string $separator
* What is the preferred letter separator.
* @param array $contributions
*
* @return string
* @throws \CRM_Core_Exception
*/
private static function resolveTokens($html_message, $contact, $contribution, $messageToken, $grouped, $separator) {
private static function resolveTokens(string $html_message, $contact, $contribution, $messageToken, $grouped, $separator, $contributions): string {
$categories = self::getTokenCategories();
$domain = CRM_Core_BAO_Domain::getDomain();
$tokenHtml = CRM_Utils_Token::replaceDomainTokens($html_message, $domain, TRUE, $messageToken);
$tokenHtml = CRM_Utils_Token::replaceContactTokens($tokenHtml, $contact, TRUE, $messageToken);
if ($grouped) {
$tokenHtml = CRM_Utils_Token::replaceMultipleContributionTokens($separator, $tokenHtml, $contribution, TRUE, $messageToken);
$tokenHtml = CRM_Utils_Token::replaceMultipleContributionTokens($separator, $tokenHtml, $contributions, $messageToken);
}
else {
// no change to normal behaviour to avoid risk of breakage
Expand Down Expand Up @@ -340,7 +343,7 @@ public static function combineContributions($existing, $contribution, $separator
public static function assignCombinedContributionValues($contact, $contributions, $groupBy, $groupByID) {
CRM_Core_Smarty::singleton()->assign('contact_aggregate', $contact['contact_aggregate']);
CRM_Core_Smarty::singleton()
->assign('contributions', array_intersect_key($contributions, $contact['contribution_ids'][$groupBy][$groupByID]));
->assign('contributions', $contributions);
CRM_Core_Smarty::singleton()->assign('contribution_aggregate', $contact['aggregates'][$groupBy][$groupByID]);

}
Expand Down Expand Up @@ -417,20 +420,22 @@ public static function emailLetter($contact, $html, $is_pdf, $format = [], $para
* @param int $groupByID
*
* @return string
* @throws \CRM_Core_Exception
*/
protected static function generateHtml(&$contact, $contribution, $groupBy, $contributions, $realSeparator, $tableSeparators, $messageToken, $html_message, $separator, $grouped, $groupByID) {
static $validated = FALSE;
$html = NULL;

self::assignCombinedContributionValues($contact, $contributions, $groupBy, $groupByID);
$groupedContributions = array_intersect_key($contributions, $contact['contribution_ids'][$groupBy][$groupByID]);
self::assignCombinedContributionValues($contact, $groupedContributions, $groupBy, $groupByID);

if (empty($groupBy) || empty($contact['is_sent'][$groupBy][$groupByID])) {
if (!$validated && in_array($realSeparator, $tableSeparators) && !self::isValidHTMLWithTableSeparator($messageToken, $html_message)) {
$realSeparator = ', ';
CRM_Core_Session::setStatus(ts('You have selected the table cell separator, but one or more token fields are not placed inside a table cell. This would result in invalid HTML, so comma separators have been used instead.'));
}
$validated = TRUE;
$html = str_replace($separator, $realSeparator, self::resolveTokens($html_message, $contact, $contribution, $messageToken, $grouped, $separator));
$html = str_replace($separator, $realSeparator, self::resolveTokens($html_message, $contact, $contribution, $messageToken, $grouped, $separator, $groupedContributions));
}

return $html;
Expand Down
12 changes: 8 additions & 4 deletions CRM/Utils/PDF/Utils.php
Original file line number Diff line number Diff line change
Expand Up @@ -191,11 +191,15 @@ public static function _html2pdf_dompdf($paper_size, $orientation, $html, $outpu
if ($output) {
return $dompdf->output();
}
else {
// CRM-19183 remove .pdf extension from filename
$fileName = basename($fileName, ".pdf");
$dompdf->stream($fileName);
// CRM-19183 remove .pdf extension from filename
$fileName = basename($fileName, ".pdf");
if (CIVICRM_UF === 'UnitTests') {
throw new CRM_Core_Exception_PrematureExitException('_html2pdf_dompdf called', [
'html' => $html,
'fileName' => $fileName,
]);
}
$dompdf->stream($fileName);
}

/**
Expand Down
28 changes: 10 additions & 18 deletions CRM/Utils/Token.php
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ public static function token_match($type, $var, &$str) {
* @return string
* The processed string
*/
public static function &token_replace($type, $var, $value, &$str, $escapeSmarty = FALSE) {
public static function token_replace($type, $var, $value, &$str, $escapeSmarty = FALSE) {
$token = preg_quote('{' . "$type.$var") . '(\|([^\}]+?))?' . preg_quote('}');
if (!$value) {
$value = '$3';
Expand Down Expand Up @@ -1706,28 +1706,20 @@ function ($matches) use (&$contribution, $html, $escapeSmarty) {
*
* @param string $separator
* @param string $str
* @param array $contribution
* @param bool|string $html
* @param string $knownTokens
* @param bool|string $escapeSmarty
* @param array $contributions
* @param array $knownTokens
*
* @return string
*/
public static function replaceMultipleContributionTokens($separator, $str, &$contribution, $html = FALSE, $knownTokens = NULL, $escapeSmarty = FALSE) {
if (empty($knownTokens['contribution'])) {
return $str;
}

if (in_array('receive_date', $knownTokens['contribution'])) {
$formattedDates = [];
$dates = explode($separator, $contribution['receive_date']);
foreach ($dates as $date) {
$formattedDates[] = CRM_Utils_Date::customFormat($date, NULL, ['j', 'm', 'Y']);
public static function replaceMultipleContributionTokens(string $separator, string $str, array $contributions, array $knownTokens): string {
foreach ($knownTokens['contribution'] ?? [] as $token) {
$resolvedTokens = [];
foreach ($contributions as $contribution) {
$resolvedTokens[] = self::replaceContributionTokens('{contribution.' . $token . '}', $contribution, FALSE, $knownTokens);
}
$str = str_replace("{contribution.receive_date}", implode($separator, $formattedDates), $str);
unset($knownTokens['contribution']['receive_date']);
$str = self::token_replace('contribution', $token, implode($separator, $resolvedTokens), $str);
}
return self::replaceContributionTokens($str, $contribution, $html, $knownTokens, $escapeSmarty);
return $str;
}

/**
Expand Down
67 changes: 67 additions & 0 deletions tests/phpunit/CRM/Contribute/Form/Task/PDFLetterCommonTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,60 @@ public function tearDown() {
CRM_Utils_Hook::singleton()->reset();
}

/**
* Test thank you send with grouping.
*
* @throws \CRM_Core_Exception
* @throws \CiviCRM_API3_Exception
*/
public function testGroupedThankYous(): void {
$this->ids['Contact'][0] = $this->individualCreate();
$this->createLoggedInUser();
$contribution1ID = $this->callAPISuccess('Contribution', 'create', [
'contact_id' => $this->ids['Contact'][0],
'total_amount' => '60',
'financial_type_id' => 'Donation',
'currency' => 'USD',
'receive_date' => '2021-01-01 13:21',
])['id'];
$contribution2ID = $this->callAPISuccess('Contribution', 'create', [
'contact_id' => $this->ids['Contact'][0],
'total_amount' => '70',
'financial_type_id' => 'Donation',
'receive_date' => '2021-02-01 2:21',
'currency' => 'USD',
])['id'];
$form = $this->getFormObject('CRM_Contribute_Form_Task_PDFLetter', [
'campaign_id' => '',
'subject' => '',
'format_id' => '',
'paper_size' => 'letter',
'orientation' => 'portrait',
'metric' => 'in',
'margin_left' => '0.75',
'margin_right' => '0.75',
'margin_top' => '0.75',
'margin_bottom' => '0.75',
'document_type' => 'pdf',
'html_message' => '{contribution.currency} * {contribution.total_amount} * {contribution.receive_date}',
'template' => '',
'saveTemplateName' => '',
'from_email_address' => '185',
'thankyou_update' => '1',
'group_by' => 'contact_id',
'group_by_separator' => 'comma',
'email_options' => '',
]);
$this->setSearchSelection([$contribution1ID, $contribution2ID], $form);
$form->preProcess();
try {
$form->postProcess();
}
catch (CRM_Core_Exception_PrematureExitException $e) {
$this->assertContains('USD, USD * $ 60.00, $ 70.00 * January 1st, 2021 1:21 PM, February 1st, 2021 2:21 AM', $e->errorData['html']);
}
}

/**
* Test the buildContributionArray function.
*
Expand Down Expand Up @@ -443,4 +497,17 @@ public function isHtmlTokenInTableCellProvider() {
];
}

/**
* @param array $entities
* @param \CRM_Core_Form $form
*/
protected function setSearchSelection(array $entities, CRM_Core_Form $form): void {
$_SESSION['_' . $form->controller->_name . '_container']['values']['Search'] = [
'radio_ts' => 'ts_sel',
];
foreach ($entities as $entityID) {
$_SESSION['_' . $form->controller->_name . '_container']['values']['Search']['mark_x_' . $entityID] = TRUE;
}
}

}

0 comments on commit ec6e4b4

Please sign in to comment.