3 +--------------------------------------------------------------------+
4 | CiviCRM version 4.5 |
5 +--------------------------------------------------------------------+
6 | Copyright CiviCRM LLC (c) 2004-2014 |
7 +--------------------------------------------------------------------+
8 | This file is a part of CiviCRM. |
10 | CiviCRM is free software; you can copy, modify, and distribute it |
11 | under the terms of the GNU Affero General Public License |
12 | Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
14 | CiviCRM is distributed in the hope that it will be useful, but |
15 | WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
17 | See the GNU Affero General Public License for more details. |
19 | You should have received a copy of the GNU Affero General Public |
20 | License and the CiviCRM Licensing Exception along |
21 | with this program; if not, contact CiviCRM LLC |
22 | at info[AT]civicrm[DOT]org. If you have questions about the |
23 | GNU Affero General Public License or the licensing of CiviCRM, |
24 | see the CiviCRM license FAQ at http://civicrm.org/licensing |
25 +--------------------------------------------------------------------+
31 * @copyright CiviCRM LLC (c) 2004-2014
37 * This class provides the common functionality for creating PDF letter for
38 * one or a group of contact ids.
40 class CRM_Contact_Form_Task_PDFLetterCommon
{
43 * build all the data structures needed to build the form
50 static function preProcess(&$form) {
51 $messageText = array();
52 $messageSubject = array();
53 $dao = new CRM_Core_BAO_MessageTemplate();
56 while ($dao->fetch()) {
57 $messageText[$dao->id
] = $dao->msg_text
;
58 $messageSubject[$dao->id
] = $dao->msg_subject
;
61 $form->assign('message', $messageText);
62 $form->assign('messageSubject', $messageSubject);
63 CRM_Utils_System
::setTitle('Create Printable Letters (PDF)');
70 static function preProcessSingle(&$form, $cid) {
71 $form->_contactIds
= array($cid);
72 // put contact display name in title for single contact mode
73 CRM_Utils_System
::setTitle(ts('Create Printable Letter (PDF) for %1', array(1 => CRM_Core_DAO
::getFieldValue('CRM_Contact_DAO_Contact', $cid, 'display_name'))));
79 * @var CRM_Core_Form $form
83 static function buildQuickForm(&$form) {
84 // This form outputs a file so should never be submitted via ajax
85 $form->preventAjaxSubmit();
87 //Added for CRM-12682: Add activity subject and campaign fields
88 CRM_Campaign_BAO_Campaign
::addCampaign($form);
92 ts('Activity Subject'),
93 array('size' => 45, 'maxlength' => 255),
97 $form->add('static', 'pdf_format_header', NULL, ts('Page Format: %1', array(1 => '<span class="pdf-format-header-label"></span>')));
98 $form->addSelect('format_id', array(
99 'label' => ts('Select Format'),
100 'placeholder' => ts('Default'),
101 'entity' => 'message_template',
102 'field' => 'pdf_format_id',
103 'option_url' => 'civicrm/admin/pdfFormats',
109 array(0 => ts('- default -')) + CRM_Core_BAO_PaperSize
::getList(TRUE),
111 array('onChange' => "selectPaper( this.value ); showUpdateFormatChkBox();")
113 $form->add('static', 'paper_dimensions', NULL, ts('Width x Height'));
118 CRM_Core_BAO_PdfFormat
::getPageOrientations(),
120 array('onChange' => "updatePaperDimensions(); showUpdateFormatChkBox();")
125 ts('Unit of Measure'),
126 CRM_Core_BAO_PdfFormat
::getUnits(),
128 array('onChange' => "selectMetric( this.value );")
134 array('size' => 8, 'maxlength' => 8, 'onkeyup' => "showUpdateFormatChkBox();"),
141 array('size' => 8, 'maxlength' => 8, 'onkeyup' => "showUpdateFormatChkBox();"),
148 array('size' => 8, 'maxlength' => 8, 'onkeyup' => "showUpdateFormatChkBox();"),
155 array('size' => 8, 'maxlength' => 8, 'onkeyup' => "showUpdateFormatChkBox();"),
159 $config = CRM_Core_Config
::singleton();
160 if ($config->wkhtmltopdfPath
== false) {
164 ts('Stationery (relative path to PDF you wish to use as the background)'),
165 array('size' => 25, 'maxlength' => 900, 'onkeyup' => "showUpdateFormatChkBox();"),
169 $form->add('checkbox', 'bind_format', ts('Always use this Page Format with the selected Template'));
170 $form->add('checkbox', 'update_format', ts('Update Page Format (this will affect all templates that use this format)'));
172 $form->assign('useThisPageFormat', ts('Always use this Page Format with the new template?'));
173 $form->assign('useSelectedPageFormat', ts('Should the new template always use the selected Page Format?'));
174 $form->assign('totalSelectedContacts', count($form->_contactIds
));
176 CRM_Mailing_BAO_Mailing
::commonLetterCompose($form);
178 if ($form->_single
) {
179 $cancelURL = CRM_Utils_System
::url(
180 'civicrm/contact/view',
181 "reset=1&cid={$form->_cid}&selectedChild=activity",
187 if ($form->get('action') == CRM_Core_Action
::VIEW
) {
188 $form->addButtons(array(
191 'name' => ts('Done'),
192 'js' => array('onclick' => "location.href='{$cancelURL}'; return false;"),
198 $form->addButtons(array(
201 'name' => ts('Make PDF Letter'),
206 'name' => ts('Done'),
207 'js' => array('onclick' => "location.href='{$cancelURL}'; return false;"),
214 $form->addButtons(array(
217 'name' => ts('Make PDF Letters'),
222 'name' => ts('Done'),
227 $form->addFormRule(array('CRM_Contact_Form_Task_PDFLetterCommon', 'formRule'), $form);
233 static function setDefaultValues() {
234 $defaultFormat = CRM_Core_BAO_PdfFormat
::getDefaultValues();
235 $defaultFormat['format_id'] = $defaultFormat['id'];
236 return $defaultFormat;
242 * @param array $fields the input form values
243 * @param array $dontCare
244 * @param array $self additional values form 'this'
246 * @return true if no errors, else array of errors
250 static function formRule($fields, $dontCare, $self) {
252 $template = CRM_Core_Smarty
::singleton();
255 if (!empty($fields['saveTemplate']) && empty($fields['saveTemplateName'])) {
256 $errors['saveTemplateName'] = ts("Enter name to save message template");
258 if (!is_numeric($fields['margin_left'])) {
259 $errors['margin_left'] = 'Margin must be numeric';
261 if (!is_numeric($fields['margin_right'])) {
262 $errors['margin_right'] = 'Margin must be numeric';
264 if (!is_numeric($fields['margin_top'])) {
265 $errors['margin_top'] = 'Margin must be numeric';
267 if (!is_numeric($fields['margin_bottom'])) {
268 $errors['margin_bottom'] = 'Margin must be numeric';
270 return empty($errors) ?
TRUE : $errors;
274 * part of the post process which prepare and extract information from the template
280 * @return array( $categories, $html_message, $messageToken, $returnProperties )
282 static protected function processMessageTemplate(&$form) {
283 $formValues = $form->controller
->exportValues($form->getName());
285 // process message template
286 if (!empty($formValues['saveTemplate']) ||
!empty($formValues['updateTemplate'])) {
287 $messageTemplate = array(
289 'msg_html' => $formValues['html_message'],
290 'msg_subject' => NULL,
294 $messageTemplate['pdf_format_id'] = 'null';
295 if (!empty($formValues['bind_format']) && $formValues['format_id']) {
296 $messageTemplate['pdf_format_id'] = $formValues['format_id'];
298 if (!empty($formValues['saveTemplate']) && $formValues['saveTemplate']) {
299 $messageTemplate['msg_title'] = $formValues['saveTemplateName'];
300 CRM_Core_BAO_MessageTemplate
::add($messageTemplate);
303 if (!empty($formValues['updateTemplate']) && $formValues['template'] && $formValues['updateTemplate']) {
304 $messageTemplate['id'] = $formValues['template'];
306 unset($messageTemplate['msg_title']);
307 CRM_Core_BAO_MessageTemplate
::add($messageTemplate);
310 elseif (CRM_Utils_Array
::value('template', $formValues) > 0) {
311 if (!empty($formValues['bind_format']) && $formValues['format_id']) {
312 $query = "UPDATE civicrm_msg_template SET pdf_format_id = {$formValues['format_id']} WHERE id = {$formValues['template']}";
315 $query = "UPDATE civicrm_msg_template SET pdf_format_id = NULL WHERE id = {$formValues['template']}";
317 CRM_Core_DAO
::executeQuery($query, CRM_Core_DAO
::$_nullArray);
319 if (!empty($formValues['update_format'])) {
320 $bao = new CRM_Core_BAO_PdfFormat();
321 $bao->savePdfFormat($formValues, $formValues['format_id']);
327 CRM_Utils_Hook
::tokens($tokens);
328 $categories = array_keys($tokens);
330 $html_message = $formValues['html_message'];
332 //time being hack to strip ' '
333 //from particular letter line, CRM-6798
334 self
::formatMessage($html_message);
336 $messageToken = CRM_Utils_Token
::getTokens($html_message);
338 $returnProperties = array();
339 if (isset($messageToken['contact'])) {
340 foreach ($messageToken['contact'] as $key => $value) {
341 $returnProperties[$value] = 1;
345 return array($formValues, $categories, $html_message, $messageToken, $returnProperties);
349 * process the form after the input has been submitted and validated
357 static function postProcess(&$form) {
358 list($formValues, $categories, $html_message, $messageToken, $returnProperties) = self
::processMessageTemplate($form);
360 $skipOnHold = isset($form->skipOnHold
) ?
$form->skipOnHold
: FALSE;
361 $skipDeceased = isset($form->skipDeceased
) ?
$form->skipDeceased
: TRUE;
363 foreach ($form->_contactIds
as $item => $contactId) {
364 $params = array('contact_id' => $contactId);
366 list($contact) = CRM_Utils_Token
::getTokenDetails($params,
372 'CRM_Contact_Form_Task_PDFLetterCommon'
374 if (civicrm_error($contact)) {
375 $notSent[] = $contactId;
379 $tokenHtml = CRM_Utils_Token
::replaceContactTokens($html_message, $contact[$contactId], TRUE, $messageToken);
380 $tokenHtml = CRM_Utils_Token
::replaceHookTokens($tokenHtml, $contact[$contactId], $categories, TRUE);
382 if (defined('CIVICRM_MAIL_SMARTY') && CIVICRM_MAIL_SMARTY
) {
383 $smarty = CRM_Core_Smarty
::singleton();
384 // also add the contact tokens to the template
385 $smarty->assign_by_ref('contact', $contact);
386 $tokenHtml = $smarty->fetch("string:$tokenHtml");
389 $html[] = $tokenHtml;
392 self
::createActivities($form, $html_message, $form->_contactIds
);
394 CRM_Utils_PDF_Utils
::html2pdf($html, "CiviLetter.pdf", FALSE, $formValues);
396 $form->postProcessHook();
398 CRM_Utils_System
::civiExit(1);
403 * @param $html_message
406 * @throws CRM_Core_Exception
408 static function createActivities($form, $html_message, $contactIds) {
409 //Added for CRM-12682: Add activity subject and campaign fields
410 $formValues = $form->controller
->exportValues($form->getName());
412 $session = CRM_Core_Session
::singleton();
413 $userID = $session->get('userID');
414 $activityTypeID = CRM_Core_OptionGroup
::getValue(
419 $activityParams = array(
420 'subject' => $formValues['subject'],
421 'campaign_id' => CRM_Utils_Array
::value('campaign_id', $formValues),
422 'source_contact_id' => $userID,
423 'activity_type_id' => $activityTypeID,
424 'activity_date_time' => date('YmdHis'),
425 'details' => $html_message,
427 if (!empty($form->_activityId
)) {
428 $activityParams +
= array('id' => $form->_activityId
);
431 $activity = CRM_Activity_BAO_Activity
::create($activityParams);
434 // create Print PDF activity for each selected contact. CRM-6886
435 $activityIds = array();
436 foreach ($contactIds as $contactId) {
437 $activityID = CRM_Activity_BAO_Activity
::create($activityParams);
438 $activityIds[$contactId] = $activityID->id
;
442 $activityContacts = CRM_Core_OptionGroup
::values('activity_contacts', FALSE, FALSE, FALSE, NULL, 'name');
443 $targetID = CRM_Utils_Array
::key('Activity Targets', $activityContacts);
445 //@todo why are we using $form->_contactIds here & contactIds above - need comment
446 foreach ($form->_contactIds
as $contactId) {
447 $activityTargetParams = array(
448 'activity_id' => empty($activity->id
) ?
$activityIds[$contactId] : $activity->id
,
449 'contact_id' => $contactId,
450 'record_type_id' => $targetID
452 CRM_Activity_BAO_ActivityContact
::create($activityTargetParams);
459 static function formatMessage(&$message) {
460 $newLineOperators = array(
463 'pattern' => '/<(\s+)?p(\s+)?>/m',
467 'pattern' => '/<(\s+)?br(\s+)?\/>/m',
471 $htmlMsg = preg_split($newLineOperators['p']['pattern'], $message);
472 foreach ($htmlMsg as $k => & $m) {
473 $messages = preg_split($newLineOperators['br']['pattern'], $m);
474 foreach ($messages as $key => & $msg) {
477 if (preg_match('/^( )+/', $msg, $matches)) {
478 $spaceLen = strlen($matches[0]) / 6;
479 $trimMsg = ltrim($msg, ' ');
480 $charLen = strlen($trimMsg);
481 $totalLen = $charLen +
$spaceLen;
482 if ($totalLen > 100) {
484 if ($spaceLen > 50) {
487 if ($charLen > 100) {
490 $msg = str_repeat(' ', $spacesCount) . $trimMsg;
494 $m = implode($newLineOperators['br']['oper'], $messages);
496 $message = implode($newLineOperators['p']['oper'], $htmlMsg);