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] dev/core#2790 towards pdf task trait #21276

Merged
merged 1 commit into from
Aug 31, 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
104 changes: 99 additions & 5 deletions CRM/Activity/Form/Task/PDF.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
+--------------------------------------------------------------------+
*/

use Civi\Token\TokenProcessor;

/**
* This class provides the functionality to create PDF/Word letters for activities.
*/
Expand All @@ -19,9 +21,9 @@ class CRM_Activity_Form_Task_PDF extends CRM_Activity_Form_Task {
/**
* Build all the data structures needed to build the form.
*/
public function preProcess() {
public function preProcess(): void {
parent::preProcess();
CRM_Activity_Form_Task_PDFLetterCommon::preProcess($this);
$this->setTitle('Print/Merge Document');
}

/**
Expand All @@ -35,14 +37,23 @@ public function buildQuickForm() {
// for them to block pdf.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So far so good just this seems like a useful comment? Otherwise it's not clear why this override is here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@demeritcowboy good catch - I had wondered why that line was there, not realising I had removed the explanation - back now

// @todo debug & fix....
$this->add('select', 'document_type', ts('Document Type'), ['pdf' => ts('Portable Document Format (.pdf)')]);

}

/**
* Process the form after the input has been submitted and validated.
*/
public function postProcess() {
CRM_Activity_Form_Task_PDFLetterCommon::postProcess($this);
$form = $this;
$activityIds = $form->_activityHolderIds;
$formValues = $form->controller->exportValues($form->getName());
$html_message = CRM_Core_Form_Task_PDFLetterCommon::processTemplate($formValues);

// Do the rest in another function to make testing easier
$form->createDocument($activityIds, $html_message, $formValues);

$form->postProcessHook();

CRM_Utils_System::civiExit(1);
}

/**
Expand All @@ -51,7 +62,90 @@ public function postProcess() {
* @return array
*/
public function listTokens() {
return CRM_Activity_Form_Task_PDFLetterCommon::listTokens();
return $this->createTokenProcessor()->listTokens();
}

/**
* Create a token processor
*
* @return \Civi\Token\TokenProcessor
*/
public function createTokenProcessor() {
return new TokenProcessor(\Civi::dispatcher(), [
'controller' => get_class(),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

get_class() here is a different class than before the patch, but it doesn't seem to make a difference on the activity print/merge. When I look around the token classes for "controller", I only really see it in hook_tokenValues. I don't see any hook implementations in universe that depend specifically on CRM_Activity_Form_Task_PDFLetterCommon.

'smarty' => FALSE,
'schema' => ['activityId'],
]);
}

/**
* Produce the document from the activities
* This uses the new token processor
*
* @param array $activityIds array of activity ids
* @param string $html_message message text with tokens
* @param array $formValues formValues from the form
*
* @return array
*/
public function createDocument($activityIds, $html_message, $formValues) {
$tp = $this->createTokenProcessor();
$tp->addMessage('body_html', $html_message, 'text/html');

foreach ($activityIds as $activityId) {
$tp->addRow()->context('activityId', $activityId);
}
$tp->evaluate();

return $this->renderFromRows($tp->getRows(), 'body_html', $formValues);
}

/**
* Render html from rows
*
* @param $rows
* @param string $msgPart
* The name registered with the TokenProcessor
* @param array $formValues
* The values submitted through the form
*
* @return string
* If formValues['is_unit_test'] is true, otherwise outputs document to browser
*/
public function renderFromRows($rows, $msgPart, $formValues) {
$html = [];
foreach ($rows as $row) {
$html[] = $row->render($msgPart);
}

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

if (!empty($html)) {
$this->outputFromHtml($formValues, $html);
}
}

/**
* Output the pdf or word document from the generated html.
*
* @param array $formValues
* @param array $html
*/
protected function outputFromHtml($formValues, array $html) {
if (!empty($formValues['subject'])) {
$fileName = CRM_Utils_File::makeFilenameWithUnicode($formValues['subject'], '_', 200);
}
else {
$fileName = 'CiviLetter';
}
if ($formValues['document_type'] === 'pdf') {
CRM_Utils_PDF_Utils::html2pdf($html, $fileName . '.pdf', FALSE, $formValues);
}
else {
CRM_Utils_PDF_Document::html2doc($html, $fileName . '.' . $formValues['document_type'], $formValues);
}
}

}
12 changes: 10 additions & 2 deletions CRM/Activity/Form/Task/PDFLetterCommon.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
* This class provides the common functionality for creating PDF letter for
* activities.
*
* @deprecated
*/
class CRM_Activity_Form_Task_PDFLetterCommon extends CRM_Core_Form_Task_PDFLetterCommon {

Expand All @@ -26,12 +27,13 @@ class CRM_Activity_Form_Task_PDFLetterCommon extends CRM_Core_Form_Task_PDFLette
* @return void
*/
public static function postProcess(&$form) {
CRM_Core_Error::deprecatedFunctionWarning('no alternative');
$activityIds = $form->_activityHolderIds;
$formValues = $form->controller->exportValues($form->getName());
$html_message = self::processTemplate($formValues);
$html_message = CRM_Core_Form_Task_PDFLetterCommon::processTemplate($formValues);

// Do the rest in another function to make testing easier
self::createDocument($activityIds, $html_message, $formValues);
$form->createDocument($activityIds, $html_message, $formValues);

$form->postProcessHook();

Expand All @@ -46,9 +48,12 @@ public static function postProcess(&$form) {
* @param string $html_message message text with tokens
* @param array $formValues formValues from the form
*
* @deprecated
*
* @return string
*/
public static function createDocument($activityIds, $html_message, $formValues) {
CRM_Core_Error::deprecatedFunctionWarning('no alternative');
$tp = self::createTokenProcessor();
$tp->addMessage('body_html', $html_message, 'text/html');

Expand All @@ -63,9 +68,12 @@ public static function createDocument($activityIds, $html_message, $formValues)
/**
* Create a token processor
*
* @deprecated
*
* @return \Civi\Token\TokenProcessor
*/
public static function createTokenProcessor() {
CRM_Core_Error::deprecatedFunctionWarning('no alternative');
return new TokenProcessor(\Civi::dispatcher(), [
'controller' => get_class(),
'smarty' => FALSE,
Expand Down
11 changes: 9 additions & 2 deletions CRM/Core/Form/Task/PDFLetterCommon.php
Original file line number Diff line number Diff line change
Expand Up @@ -346,10 +346,13 @@ public static function formatMessage(&$message) {
* @param array $formValues
* The values submitted through the form
*
* @deprecated
*
* @return array
* If formValues['is_unit_test'] is true, otherwise outputs document to browser
*/
public static function renderFromRows($rows, $msgPart, $formValues) {
CRM_Core_Error::deprecatedFunctionWarning('no alternative');
$html = [];
foreach ($rows as $row) {
$html[] = $row->render($msgPart);
Expand All @@ -367,8 +370,11 @@ public static function renderFromRows($rows, $msgPart, $formValues) {
/**
* List the available tokens
* @return array of token name => label
*
* @deprecated
*/
public static function listTokens() {
CRM_Core_Error::deprecatedFunctionWarning('no alternative');
$class = get_called_class();
if (method_exists($class, 'createTokenProcessor')) {
return $class::createTokenProcessor()->listTokens();
Expand All @@ -378,19 +384,20 @@ public static function listTokens() {
/**
* Output the pdf or word document from the generated html.
*
* @deprecated
*
* @param array $formValues
* @param array $html
*/
protected static function outputFromHtml($formValues, array $html) {

CRM_Core_Error::deprecatedFunctionWarning('no alternative');
// Set the filename for the PDF using the Activity Subject, if defined. Remove unwanted characters and limit the length to 200 characters.
if (!empty($formValues['subject'])) {
$fileName = CRM_Utils_File::makeFilenameWithUnicode($formValues['subject'], '_', 200);
}
else {
$fileName = 'CiviLetter';
}

if ($formValues['document_type'] === 'pdf') {
CRM_Utils_PDF_Utils::html2pdf($html, $fileName . '.pdf', FALSE, $formValues);
}
Expand Down
12 changes: 8 additions & 4 deletions tests/phpunit/CRM/Activity/Form/Task/PDFLetterCommonTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ public function testCreateDocumentBasicTokens(): void {
['Activity ID: {activity.activity_id}', 'Activity ID: ' . $activity['id']],
];
$html_message = "\n" . implode("\n", CRM_Utils_Array::collect('0', $data)) . "\n";
$output = CRM_Activity_Form_Task_PDFLetterCommon::createDocument([$activity['id']], $html_message, ['is_unit_test' => TRUE]);
$form = $this->getFormObject('CRM_Activity_Form_Task_PDF');
$output = $form->createDocument([$activity['id']], $html_message, ['is_unit_test' => TRUE]);

// Check some basic fields
foreach ($data as $line) {
Expand All @@ -58,7 +59,8 @@ public function testCreateDocumentCustomFieldTokens() {

$html_message = "Custom: {activity.$cf}";
$activityIds = CRM_Utils_Array::collect('id', $activities);
$output = CRM_Activity_Form_Task_PDFLetterCommon::createDocument($activityIds, $html_message, ['is_unit_test' => TRUE]);
$form = $this->getFormObject('CRM_Activity_Form_Task_PDF');
$output = $form->createDocument($activityIds, $html_message, ['is_unit_test' => TRUE]);
// Should have one row of output per activity
$this->assertCount(count($activities), $output);

Expand Down Expand Up @@ -89,7 +91,8 @@ public function testCreateDocumentSpecialTokens(): void {
['Target Count: {activity.targets_count}', "Target Count: 1"],
];
$html_message = "\n" . implode("\n", CRM_Utils_Array::collect('0', $data)) . "\n";
$output = CRM_Activity_Form_Task_PDFLetterCommon::createDocument([$activity['id']], $html_message, ['is_unit_test' => TRUE]);
$form = $this->getFormObject('CRM_Activity_Form_Task_PDF');
$output = $form->createDocument([$activity['id']], $html_message, ['is_unit_test' => TRUE]);

foreach ($data as $line) {
$this->assertContains("\n" . $line[1] . "\n", $output[0]);
Expand All @@ -103,7 +106,8 @@ public function testCreateDocumentSpecialTokens(): void {
public function testCreateDocumentUnknownTokens(): void {
$activity = $this->activityCreate();
$html_message = 'Unknown token: {activity.something_unknown}';
$output = CRM_Activity_Form_Task_PDFLetterCommon::createDocument([$activity['id']], $html_message, ['is_unit_test' => TRUE]);
$form = $this->getFormObject('CRM_Activity_Form_Task_PDF');
$output = $form->createDocument([$activity['id']], $html_message, ['is_unit_test' => TRUE]);
// Unknown tokens should be left alone
$this->assertEquals($html_message, $output[0]);
}
Expand Down