Skip to content

Commit

Permalink
[REF] Move more functions bask to pdfLetter class
Browse files Browse the repository at this point in the history
As with the previous moves this is
1) covered by unit tests
2) just code moving around

But note that this doesn't move whole functions but moves the
contents of postProcess & buildQuickForm back into the same functions
on the 'actual' class
  • Loading branch information
eileenmcnaughton committed Apr 27, 2021
1 parent 5b90f13 commit 3c73bb6
Show file tree
Hide file tree
Showing 2 changed files with 168 additions and 188 deletions.
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

0 comments on commit 3c73bb6

Please sign in to comment.