Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[REF] Move more functions back to pdfLetter class #20155

Merged
merged 1 commit into from
Apr 27, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
171 changes: 168 additions & 3 deletions CRM/Contribute/Form/Task/PDFLetter.php
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,12 @@ public function buildQuickForm() {
$this->assign('suppressForm', FALSE);

// Build common form elements
CRM_Contribute_Form_Task_PDFLetterCommon::buildQuickForm($this);
// use contact form as a base
CRM_Contact_Form_Task_PDFLetterCommon::buildQuickForm($this);

// Contribute PDF tasks allow you to email as well, so we need to add email address to those forms
$this->add('select', 'from_email_address', ts('From Email Address'), $this->_fromEmails, TRUE);
CRM_Core_Form_Task_PDFLetterCommon::buildQuickForm($this);

// specific need for contributions
$this->add('static', 'more_options_header', NULL, ts('Thank-you Letter Options'));
Expand Down Expand Up @@ -145,7 +150,143 @@ public function buildQuickForm() {
*/
public function postProcess() {
$formValues = $this->controller->exportValues($this->getName());
CRM_Contribute_Form_Task_PDFLetterCommon::postProcess($this, $formValues);
$form = $this;
[$formValues, $categories, $html_message, $messageToken, $returnProperties] = CRM_Contact_Form_Task_PDFLetterCommon::processMessageTemplate($formValues);
$isPDF = FALSE;
$emailParams = [];
if (!empty($formValues['email_options'])) {
$returnProperties['email'] = $returnProperties['on_hold'] = $returnProperties['is_deceased'] = $returnProperties['do_not_email'] = 1;
$emailParams = [
'subject' => $formValues['subject'] ?? NULL,
'from' => $formValues['from_email_address'] ?? NULL,
];

$emailParams['from'] = CRM_Utils_Mail::formatFromAddress($emailParams['from']);

// We need display_name for emailLetter() so add to returnProperties here
$returnProperties['display_name'] = 1;
if (stristr($formValues['email_options'], 'pdfemail')) {
$isPDF = TRUE;
}
}
// update dates ?
$receipt_update = $formValues['receipt_update'] ?? FALSE;
$thankyou_update = $formValues['thankyou_update'] ?? FALSE;
$nowDate = date('YmdHis');
$receipts = $thanks = $emailed = 0;
$updateStatus = '';
$task = 'CRM_Contribution_Form_Task_PDFLetterCommon';
$realSeparator = ', ';
$tableSeparators = [
'td' => '</td><td>',
'tr' => '</td></tr><tr><td>',
];
//the original thinking was mutliple options - but we are going with only 2 (comma & td) for now in case
// there are security (& UI) issues we need to think through
if (isset($formValues['group_by_separator'])) {
if (in_array($formValues['group_by_separator'], ['td', 'tr'])) {
$realSeparator = $tableSeparators[$formValues['group_by_separator']];
}
elseif ($formValues['group_by_separator'] == 'br') {
$realSeparator = "<br />";
}
}
// a placeholder in case the separator is common in the string - e.g ', '
$separator = '****~~~~';
$groupBy = $formValues['group_by'];

// skip some contacts ?
$skipOnHold = $form->skipOnHold ?? FALSE;
$skipDeceased = $form->skipDeceased ?? TRUE;
$contributionIDs = $form->getVar('_contributionIds');
if ($form->isQueryIncludesSoftCredits()) {
$contributionIDs = [];
$result = $form->getSearchQueryResults();
while ($result->fetch()) {
$form->_contactIds[$result->contact_id] = $result->contact_id;
$contributionIDs["{$result->contact_id}-{$result->contribution_id}"] = $result->contribution_id;
}
}
[$contributions, $contacts] = CRM_Contribute_Form_Task_PDFLetter::buildContributionArray($groupBy, $contributionIDs, $returnProperties, $skipOnHold, $skipDeceased, $messageToken, $task, $separator, $form->isQueryIncludesSoftCredits());
$html = [];
$contactHtml = $emailedHtml = [];
foreach ($contributions as $contributionId => $contribution) {
$contact = &$contacts[$contribution['contact_id']];
$grouped = FALSE;
$groupByID = 0;
if ($groupBy) {
$groupByID = empty($contribution[$groupBy]) ? 0 : $contribution[$groupBy];
$contribution = $contact['combined'][$groupBy][$groupByID];
$grouped = TRUE;
}

if (empty($groupBy) || empty($contact['is_sent'][$groupBy][$groupByID])) {
$html[$contributionId] = CRM_Contribute_Form_Task_PDFLetter::generateHtml($contact, $contribution, $groupBy, $contributions, $realSeparator, $tableSeparators, $messageToken, $html_message, $separator, $grouped, $groupByID);
$contactHtml[$contact['contact_id']][] = $html[$contributionId];
if (!empty($formValues['email_options'])) {
if (CRM_Contribute_Form_Task_PDFLetter::emailLetter($contact, $html[$contributionId], $isPDF, $formValues, $emailParams)) {
$emailed++;
if (!stristr($formValues['email_options'], 'both')) {
$emailedHtml[$contributionId] = TRUE;
}
}
}
$contact['is_sent'][$groupBy][$groupByID] = TRUE;
}
// Update receipt/thankyou dates
$contributionParams = ['id' => $contributionId];
if ($receipt_update) {
$contributionParams['receipt_date'] = $nowDate;
}
if ($thankyou_update) {
$contributionParams['thankyou_date'] = $nowDate;
}
if ($receipt_update || $thankyou_update) {
civicrm_api3('Contribution', 'create', $contributionParams);
$receipts = ($receipt_update ? $receipts + 1 : $receipts);
$thanks = ($thankyou_update ? $thanks + 1 : $thanks);
}
}

$contactIds = array_keys($contacts);
CRM_Contact_Form_Task_PDFLetterCommon::createActivities($form, $html_message, $contactIds, CRM_Utils_Array::value('subject', $formValues, ts('Thank you letter')), CRM_Utils_Array::value('campaign_id', $formValues), $contactHtml);
$html = array_diff_key($html, $emailedHtml);

if (!empty($formValues['is_unit_test'])) {
return $html;
}

//CRM-19761
if (!empty($html)) {
$type = $formValues['document_type'];

if ($type === 'pdf') {
CRM_Utils_PDF_Utils::html2pdf($html, "CiviLetter.pdf", FALSE, $formValues);
}
else {
CRM_Utils_PDF_Document::html2doc($html, "CiviLetter.$type", $formValues);
}
}

$form->postProcessHook();

if ($emailed) {
$updateStatus = ts('Receipts have been emailed to %1 contributions.', [1 => $emailed]);
}
if ($receipts) {
$updateStatus = ts('Receipt date has been updated for %1 contributions.', [1 => $receipts]);
}
if ($thanks) {
$updateStatus .= ' ' . ts('Thank-you date has been updated for %1 contributions.', [1 => $thanks]);
}

if ($updateStatus) {
CRM_Core_Session::setStatus($updateStatus);
}
if (!empty($html)) {
// ie. we have only sent emails - lets no show a white screen
CRM_Utils_System::civiExit();
}
}

/**
Expand Down Expand Up @@ -290,7 +431,7 @@ public static function generateHtml(&$contact, $contribution, $groupBy, $contrib
CRM_Contribute_Form_Task_PDFLetter::assignCombinedContributionValues($contact, $groupedContributions, $groupBy, $groupByID);

if (empty($groupBy) || empty($contact['is_sent'][$groupBy][$groupByID])) {
if (!$validated && in_array($realSeparator, $tableSeparators) && !CRM_Contribute_Form_Task_PDFLetterCommon::isValidHTMLWithTableSeparator($messageToken, $html_message)) {
if (!$validated && in_array($realSeparator, $tableSeparators) && !CRM_Contribute_Form_Task_PDFLetter::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.'));
}
Expand Down Expand Up @@ -375,4 +516,28 @@ public static function isHtmlTokenInTableCell($token, $entity, $textToSearch) {
return ($within == $total);
}

/**
* Check whether any of the tokens exist in the html outside a table cell.
* If they do the table cell separator is not supported (return false)
* At this stage we are only anticipating contributions passed in this way but
* it would be easy to add others
* @param $tokens
* @param $html
*
* @return bool
*/
public static function isValidHTMLWithTableSeparator($tokens, $html) {
$relevantEntities = ['contribution'];
foreach ($relevantEntities as $entity) {
if (isset($tokens[$entity]) && is_array($tokens[$entity])) {
foreach ($tokens[$entity] as $token) {
if (!CRM_Contribute_Form_Task_PDFLetter::isHtmlTokenInTableCell($token, $entity, $html)) {
return FALSE;
}
}
}
}
return TRUE;
}

}
185 changes: 0 additions & 185 deletions CRM/Contribute/Form/Task/PDFLetterCommon.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,191 +6,6 @@
*/
class CRM_Contribute_Form_Task_PDFLetterCommon extends CRM_Contact_Form_Task_PDFLetterCommon {

/**
* Build the form object.
*
* @var CRM_Core_Form $form
*/
public static function buildQuickForm(&$form) {
// use contact form as a base
CRM_Contact_Form_Task_PDFLetterCommon::buildQuickForm($form);

// Contribute PDF tasks allow you to email as well, so we need to add email address to those forms
$form->add('select', 'from_email_address', ts('From Email Address'), $form->_fromEmails, TRUE);
parent::buildQuickForm($form);
}

/**
* Process the form after the input has been submitted and validated.
*
* @param \CRM_Contribute_Form_Task_PDFLetter $form
* @param array $formValues
*
* @throws \CRM_Core_Exception
*/
public static function postProcess(&$form, $formValues = NULL) {
[$formValues, $categories, $html_message, $messageToken, $returnProperties] = CRM_Contact_Form_Task_PDFLetterCommon::processMessageTemplate($formValues);
$isPDF = FALSE;
$emailParams = [];
if (!empty($formValues['email_options'])) {
$returnProperties['email'] = $returnProperties['on_hold'] = $returnProperties['is_deceased'] = $returnProperties['do_not_email'] = 1;
$emailParams = [
'subject' => $formValues['subject'] ?? NULL,
'from' => $formValues['from_email_address'] ?? NULL,
];

$emailParams['from'] = CRM_Utils_Mail::formatFromAddress($emailParams['from']);

// We need display_name for emailLetter() so add to returnProperties here
$returnProperties['display_name'] = 1;
if (stristr($formValues['email_options'], 'pdfemail')) {
$isPDF = TRUE;
}
}
// update dates ?
$receipt_update = $formValues['receipt_update'] ?? FALSE;
$thankyou_update = $formValues['thankyou_update'] ?? FALSE;
$nowDate = date('YmdHis');
$receipts = $thanks = $emailed = 0;
$updateStatus = '';
$task = 'CRM_Contribution_Form_Task_PDFLetterCommon';
$realSeparator = ', ';
$tableSeparators = [
'td' => '</td><td>',
'tr' => '</td></tr><tr><td>',
];
//the original thinking was mutliple options - but we are going with only 2 (comma & td) for now in case
// there are security (& UI) issues we need to think through
if (isset($formValues['group_by_separator'])) {
if (in_array($formValues['group_by_separator'], ['td', 'tr'])) {
$realSeparator = $tableSeparators[$formValues['group_by_separator']];
}
elseif ($formValues['group_by_separator'] == 'br') {
$realSeparator = "<br />";
}
}
// a placeholder in case the separator is common in the string - e.g ', '
$separator = '****~~~~';
$groupBy = $formValues['group_by'];

// skip some contacts ?
$skipOnHold = $form->skipOnHold ?? FALSE;
$skipDeceased = $form->skipDeceased ?? TRUE;
$contributionIDs = $form->getVar('_contributionIds');
if ($form->isQueryIncludesSoftCredits()) {
$contributionIDs = [];
$result = $form->getSearchQueryResults();
while ($result->fetch()) {
$form->_contactIds[$result->contact_id] = $result->contact_id;
$contributionIDs["{$result->contact_id}-{$result->contribution_id}"] = $result->contribution_id;
}
}
[$contributions, $contacts] = CRM_Contribute_Form_Task_PDFLetter::buildContributionArray($groupBy, $contributionIDs, $returnProperties, $skipOnHold, $skipDeceased, $messageToken, $task, $separator, $form->isQueryIncludesSoftCredits());
$html = [];
$contactHtml = $emailedHtml = [];
foreach ($contributions as $contributionId => $contribution) {
$contact = &$contacts[$contribution['contact_id']];
$grouped = FALSE;
$groupByID = 0;
if ($groupBy) {
$groupByID = empty($contribution[$groupBy]) ? 0 : $contribution[$groupBy];
$contribution = $contact['combined'][$groupBy][$groupByID];
$grouped = TRUE;
}

if (empty($groupBy) || empty($contact['is_sent'][$groupBy][$groupByID])) {
$html[$contributionId] = CRM_Contribute_Form_Task_PDFLetter::generateHtml($contact, $contribution, $groupBy, $contributions, $realSeparator, $tableSeparators, $messageToken, $html_message, $separator, $grouped, $groupByID);
$contactHtml[$contact['contact_id']][] = $html[$contributionId];
if (!empty($formValues['email_options'])) {
if (CRM_Contribute_Form_Task_PDFLetter::emailLetter($contact, $html[$contributionId], $isPDF, $formValues, $emailParams)) {
$emailed++;
if (!stristr($formValues['email_options'], 'both')) {
$emailedHtml[$contributionId] = TRUE;
}
}
}
$contact['is_sent'][$groupBy][$groupByID] = TRUE;
}
// Update receipt/thankyou dates
$contributionParams = ['id' => $contributionId];
if ($receipt_update) {
$contributionParams['receipt_date'] = $nowDate;
}
if ($thankyou_update) {
$contributionParams['thankyou_date'] = $nowDate;
}
if ($receipt_update || $thankyou_update) {
civicrm_api3('Contribution', 'create', $contributionParams);
$receipts = ($receipt_update ? $receipts + 1 : $receipts);
$thanks = ($thankyou_update ? $thanks + 1 : $thanks);
}
}

$contactIds = array_keys($contacts);
CRM_Contact_Form_Task_PDFLetterCommon::createActivities($form, $html_message, $contactIds, CRM_Utils_Array::value('subject', $formValues, ts('Thank you letter')), CRM_Utils_Array::value('campaign_id', $formValues), $contactHtml);
$html = array_diff_key($html, $emailedHtml);

if (!empty($formValues['is_unit_test'])) {
return $html;
}

//CRM-19761
if (!empty($html)) {
$type = $formValues['document_type'];

if ($type === 'pdf') {
CRM_Utils_PDF_Utils::html2pdf($html, "CiviLetter.pdf", FALSE, $formValues);
}
else {
CRM_Utils_PDF_Document::html2doc($html, "CiviLetter.$type", $formValues);
}
}

$form->postProcessHook();

if ($emailed) {
$updateStatus = ts('Receipts have been emailed to %1 contributions.', [1 => $emailed]);
}
if ($receipts) {
$updateStatus = ts('Receipt date has been updated for %1 contributions.', [1 => $receipts]);
}
if ($thanks) {
$updateStatus .= ' ' . ts('Thank-you date has been updated for %1 contributions.', [1 => $thanks]);
}

if ($updateStatus) {
CRM_Core_Session::setStatus($updateStatus);
}
if (!empty($html)) {
// ie. we have only sent emails - lets no show a white screen
CRM_Utils_System::civiExit();
}
}

/**
* Check whether any of the tokens exist in the html outside a table cell.
* If they do the table cell separator is not supported (return false)
* At this stage we are only anticipating contributions passed in this way but
* it would be easy to add others
* @param $tokens
* @param $html
*
* @return bool
*/
public static function isValidHTMLWithTableSeparator($tokens, $html) {
$relevantEntities = ['contribution'];
foreach ($relevantEntities as $entity) {
if (isset($tokens[$entity]) && is_array($tokens[$entity])) {
foreach ($tokens[$entity] as $token) {
if (!CRM_Contribute_Form_Task_PDFLetter::isHtmlTokenInTableCell($token, $entity, $html)) {
return FALSE;
}
}
}
}
return TRUE;
}

/**
*
* @param string $html_message
Expand Down
Loading