+--------------------------------------------------------------------+
*/
+use Civi\Token\TokenProcessor;
+
/**
*
* @package CRM
*/
public function postProcess() {
$formValues = $this->controller->exportValues($this->getName());
- [$formValues, $html_message, $messageToken, $returnProperties] = $this->processMessageTemplate($formValues);
+ [$formValues, $html_message] = $this->processMessageTemplate($formValues);
+
+ $messageToken = CRM_Utils_Token::getTokens($html_message);
+
+ $returnProperties = [];
+ if (isset($messageToken['contact'])) {
+ foreach ($messageToken['contact'] as $key => $value) {
+ $returnProperties[$value] = 1;
+ }
+ }
+
$isPDF = FALSE;
$emailParams = [];
if (!empty($formValues['email_options'])) {
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, $this->resolveTokens($html_message, $contact, $contribution, $messageToken, $grouped, $separator, $groupedContributions));
+ $html = str_replace($separator, $realSeparator, $this->resolveTokens($html_message, $contact, $contribution['id'], $grouped, $separator, $groupedContributions));
}
return $html;
*
* @param string $html_message
* @param array $contact
- * @param array $contribution
- * @param array $messageToken
+ * @param int $contributionID
* @param bool $grouped
* Does this letter represent more than one contribution.
* @param string $separator
*
* @return string
*/
- protected function resolveTokens(string $html_message, $contact, $contribution, $messageToken, $grouped, $separator, $contributions): string {
+ protected function resolveTokens(string $html_message, $contact, $contributionID, $grouped, $separator, $contributions): string {
$tokenContext = [
'smarty' => (defined('CIVICRM_MAIL_SMARTY') && CIVICRM_MAIL_SMARTY),
'contactId' => $contact['contact_id'],
+ 'schema' => ['contributionId'],
];
if ($grouped) {
- $html_message = CRM_Utils_Token::replaceMultipleContributionTokens($separator, $html_message, $contributions, $messageToken);
- }
- else {
- $tokenContext['schema'] = ['contributionId'];
- $tokenContext['contributionId'] = $contribution['id'];
+ // First replace the contribution tokens. These are pretty ... special.
+ // if the text looks like `<td>{contribution.currency} {contribution.total_amount}</td>'
+ // and there are 2 rows with a currency separator of
+ // you wind up with a string like
+ // '<td>USD</td><td>USD></td> <td>$50</td><td>$89</td>
+ // see https://docs.civicrm.org/user/en/latest/contributions/manual-receipts-and-thank-yous/#grouped-contribution-thank-you-letters
+ $tokenProcessor = new TokenProcessor(\Civi::dispatcher(), $tokenContext);
+ $contributionTokens = CRM_Utils_Token::getTokens($html_message)['contribution'] ?? [];
+ foreach ($contributionTokens as $token) {
+ $tokenProcessor->addMessage($token, '{contribution.' . $token . '}', 'text/html');
+ }
+
+ foreach ($contributions as $contribution) {
+ $tokenProcessor->addRow([
+ 'contributionId' => $contribution['id'],
+ 'contribution' => $contribution,
+ ]);
+ }
+ $tokenProcessor->evaluate();
+ $resolvedTokens = [];
+ foreach ($contributionTokens as $token) {
+ foreach ($tokenProcessor->getRows() as $row) {
+ $resolvedTokens[$token][$row->context['contributionId']] = $row->render($token);
+ }
+ // We've resolved the value for each row - resorting to swapping them out
+ // with the old function.
+ $html_message = CRM_Utils_Token::token_replace('contribution', $token, implode($separator, $resolvedTokens[$token]), $html_message);
+ }
}
- $smarty = ['contact' => $contact];
- return CRM_Core_TokenSmarty::render(['html' => $html_message], $tokenContext, $smarty)['html'];
+ $tokenContext['contributionId'] = $contributionID;
+ return CRM_Core_TokenSmarty::render(['html' => $html_message], $tokenContext)['html'];
}
}
}
/**
+ * Do not use - unused in core.
+ *
* Replace Contribution tokens in html.
*
* @param string $str
* @param string $knownTokens
* @param bool|string $escapeSmarty
*
+ * @deprecated
+ *
* @return mixed
*/
public static function replaceContributionTokens($str, &$contribution, $html = FALSE, $knownTokens = NULL, $escapeSmarty = FALSE) {
* @param array $contributions
* @param array $knownTokens
*
+ * @deprecated
+ *
* @return string
*/
public static function replaceMultipleContributionTokens(string $separator, string $str, array $contributions, array $knownTokens): string {
+ CRM_Core_Error::deprecatedFunctionWarning('no alternative');
foreach ($knownTokens['contribution'] ?? [] as $token) {
$resolvedTokens = [];
foreach ($contributions as $contribution) {
}
/**
+ * Do not use - unused in core.
+ *
* @param $token
* @param $contribution
* @param bool $html
* @param bool $escapeSmarty
*
+ * @deprecated
+ *
* @return mixed|string
* @throws \CRM_Core_Exception
*/
* @throws \CRM_Core_Exception
*/
public function tearDown(): void {
- CRM_Utils_Token::$_tokens['contribution'] = NULL;
$this->quickCleanUpFinancialEntities();
$this->quickCleanup(['civicrm_uf_match', 'civicrm_campaign'], TRUE);
CRM_Utils_Hook::singleton()->reset();
'receive_date' => '2021-02-01 2:21',
'currency' => 'USD',
])['id'];
+ /* @var CRM_Contribute_Form_Task_PDFLetter $form */
$form = $this->getFormObject('CRM_Contribute_Form_Task_PDFLetter', [
'campaign_id' => '',
'subject' => '',
'total_amount' => 6,
'campaign_id' => $this->campaignCreate(['title' => $campaignTitle], FALSE),
'financial_type_id' => 'Donation',
- $customFieldKey => 'Text_' . substr(sha1(rand()), 0, 7),
+ $customFieldKey => 'Text_',
];
$contributionIDs = $returnProperties = [];
$result = $this->callAPISuccess('Contribution', 'create', $params);
fee_amount : € 1,111.11
net_amount : € 7,777.78
non_deductible_amount : € 2,222.22
-receive_date : July 20th, 2018 12:00 AM
+receive_date : July 20th, 2018
payment_instrument_id:label : Check
trxn_id : 1234
invoice_id : 568
currency : EUR
-cancel_date : December 30th, 2019 12:00 AM
+cancel_date : December 30th, 2019
cancel_reason : Contribution Cancel Reason
-receipt_date : October 30th, 2019 12:00 AM
-thankyou_date : November 30th, 2019 12:00 AM
+receipt_date : October 30th, 2019
+thankyou_date : November 30th, 2019
source : Contribution Source
amount_level : Amount Level
contribution_status_id : 2