From: Lisa Marie Maginnis Date: Thu, 1 May 2014 21:29:27 +0000 (-0400) Subject: Additional files for PDF/Latex X-Git-Url: https://vcs.fsf.org/?a=commitdiff_plain;h=cb25a178b52865df48824af9c571d416b31743ca;p=civicrm-core.git Additional files for PDF/Latex --- diff --git a/CRM/Contact/Form/Task/LatexPDF.php b/CRM/Contact/Form/Task/LatexPDF.php new file mode 100644 index 0000000000..3fccdd8d7b --- /dev/null +++ b/CRM/Contact/Form/Task/LatexPDF.php @@ -0,0 +1,125 @@ +skipOnHold = $this->skipDeceased = FALSE; + CRM_Contact_Form_Task_PDFLatexCommon::preProcess($this); + + // store case id if present + $this->_caseId = CRM_Utils_Request::retrieve('caseid', 'Positive', $this, FALSE); + + // retrieve contact ID if this is 'single' mode + $cid = CRM_Utils_Request::retrieve('cid', 'Positive', $this, FALSE); + + if ($cid) { + // this is true in non-search context / single mode + // in search context 'id' is the default profile id for search display + // CRM-11227 + $this->_activityId = CRM_Utils_Request::retrieve('id', 'Positive', $this, FALSE); + } + + if ($cid) { + CRM_Contact_Form_Task_PDFLatexCommon::preProcessSingle($this, $cid); + $this->_single = TRUE; + $this->_cid = $cid; + } + else { + parent::preProcess(); + } + $this->assign('single', $this->_single); + } + + function setDefaultValues() { + $defaults = array(); + if (isset($this->_activityId)) { + $params = array('id' => $this->_activityId); + CRM_Activity_BAO_Activity::retrieve($params, $defaults); + $defaults['html_message'] = CRM_Utils_Array::value('details', $defaults); + } + $defaults = $defaults + CRM_Contact_Form_Task_PDFLatexCommon::setDefaultValues(); + return $defaults; + } + + /** + * Build the form + * + * @access public + * + * @return void + */ + public function buildQuickForm() { + //enable form element + $this->assign('suppressForm', FALSE); + CRM_Contact_Form_Task_PDFLatexCommon::buildQuickForm($this); + } + + /** + * process the form after the input has been submitted and validated + * + * @access public + * + * @return None + */ + public function postProcess() { + CRM_Contact_Form_Task_PDFLatexCommon::postProcess($this); + } +} + diff --git a/CRM/Contact/Form/Task/PDFLatexCommon.php b/CRM/Contact/Form/Task/PDFLatexCommon.php new file mode 100644 index 0000000000..a0ca45339c --- /dev/null +++ b/CRM/Contact/Form/Task/PDFLatexCommon.php @@ -0,0 +1,434 @@ +is_active = 1; + $dao->find(); + while ($dao->fetch()) { + $messageText[$dao->id] = $dao->msg_text; + $messageSubject[$dao->id] = $dao->msg_subject; + } + + $form->assign('message', $messageText); + $form->assign('messageSubject', $messageSubject); + } + + static function preProcessSingle(&$form, $cid) { + $form->_contactIds = array($cid); + // put contact display name in title for single contact mode + CRM_Contact_Page_View::setTitle($cid); + } + + /** + * Build the form + * + * @access public + * + * @return void + */ + static function buildQuickForm(&$form) { + $form->add('static', 'pdf_format_header', NULL, ts('Page Format')); + $form->add( + 'select', + 'format_id', + ts('Select Format'), + array(0 => ts('- default -')) + CRM_Core_BAO_PdfFormat::getList(TRUE), + FALSE, + array('onChange' => "selectFormat( this.value, false );") + );; + $form->add( + 'select', + 'paper_size', + ts('Paper Size'), + array(0 => ts('- default -')) + CRM_Core_BAO_PaperSize::getList(TRUE), + FALSE, + array('onChange' => "selectPaper( this.value ); showUpdateFormatChkBox();") + ); + $form->add('static', 'paper_dimensions', NULL, ts('Width x Height')); + $form->add( + 'select', + 'orientation', + ts('Orientation'), + CRM_Core_BAO_PdfFormat::getPageOrientations(), + FALSE, + array('onChange' => "updatePaperDimensions(); showUpdateFormatChkBox();") + ); + $form->add( + 'select', + 'metric', + ts('Unit of Measure'), + CRM_Core_BAO_PdfFormat::getUnits(), + FALSE, + array('onChange' => "selectMetric( this.value );") + ); + $form->add( + 'text', + 'margin_left', + ts('Left Margin'), + array('size' => 8, 'maxlength' => 8, 'onkeyup' => "showUpdateFormatChkBox();"), + TRUE + ); + $form->add( + 'text', + 'margin_right', + ts('Right Margin'), + array('size' => 8, 'maxlength' => 8, 'onkeyup' => "showUpdateFormatChkBox();"), + TRUE + ); + $form->add( + 'text', + 'margin_top', + ts('Top Margin'), + array('size' => 8, 'maxlength' => 8, 'onkeyup' => "showUpdateFormatChkBox();"), + TRUE + ); + $form->add( + 'text', + 'margin_bottom', + ts('Bottom Margin'), + array('size' => 8, 'maxlength' => 8, 'onkeyup' => "showUpdateFormatChkBox();"), + TRUE + ); + $form->add('checkbox', 'bind_format', ts('Always use this Page Format with the selected Template')); + $form->add('checkbox', 'update_format', ts('Update Page Format (this will affect all templates that use this format)')); + + $form->assign('useThisPageFormat', ts('Always use this Page Format with the new template?')); + $form->assign('useSelectedPageFormat', ts('Should the new template always use the selected Page Format?')); + $form->assign('totalSelectedContacts', count($form->_contactIds)); + + CRM_Mailing_BAO_Mailing::commonLetterCompose($form); + + if ($form->_single) { + $cancelURL = CRM_Utils_System::url( + 'civicrm/contact/view', + "reset=1&cid={$form->_cid}&selectedChild=activity", + FALSE, + NULL, + FALSE + ); + if ($form->get('action') == CRM_Core_Action::VIEW) { + $form->addButtons(array( + array( + 'type' => 'cancel', + 'name' => ts('Done'), + 'js' => array('onclick' => "location.href='{$cancelURL}'; return false;"), + ), + ) + ); + } + else { + $form->addButtons(array( + array( + 'type' => 'submit', + 'name' => ts('Make PDF Letter'), + 'isDefault' => TRUE, + ), + array( + 'type' => 'cancel', + 'name' => ts('Done'), + 'js' => array('onclick' => "location.href='{$cancelURL}'; return false;"), + ), + ) + ); + } + } + else { + $form->addDefaultButtons(ts('Make PDF Letters')); + } + + $form->addFormRule(array('CRM_Contact_Form_Task_PDFLatexCommon', 'formRule'), $form); + } + + /** + * Set default values + */ + static function setDefaultValues() { + $defaultFormat = CRM_Core_BAO_PdfFormat::getDefaultValues(); + $defaultFormat['format_id'] = $defaultFormat['id']; + return $defaultFormat; + } + + /** + * form rule + * + * @param array $fields the input form values + * @param array $dontCare + * @param array $self additional values form 'this' + * + * @return true if no errors, else array of errors + * @access public + * + */ + static function formRule($fields, $dontCare, $self) { + $errors = array(); + $template = CRM_Core_Smarty::singleton(); + + //Added for CRM-1393 + if (CRM_Utils_Array::value('saveTemplate', $fields) && empty($fields['saveTemplateName'])) { + $errors['saveTemplateName'] = ts("Enter name to save message template"); + } + if (!is_numeric($fields['margin_left'])) { + $errors['margin_left'] = 'Margin must be numeric'; + } + if (!is_numeric($fields['margin_right'])) { + $errors['margin_right'] = 'Margin must be numeric'; + } + if (!is_numeric($fields['margin_top'])) { + $errors['margin_top'] = 'Margin must be numeric'; + } + if (!is_numeric($fields['margin_bottom'])) { + $errors['margin_bottom'] = 'Margin must be numeric'; + } + return empty($errors) ? TRUE : $errors; + } + + /** + * part of the post process which prepare and extract information from the template + * + * @access protected + * + * @return array( $categories, $html_message, $messageToken, $returnProperties ) + */ + static protected function processMessageTemplate(&$form) { + $formValues = $form->controller->exportValues($form->getName()); + + // process message template + if (CRM_Utils_Array::value('saveTemplate', $formValues) || CRM_Utils_Array::value('updateTemplate', $formValues)) { + $messageTemplate = array( + 'msg_text' => NULL, + 'msg_html' => $formValues['html_message'], + 'msg_subject' => NULL, + 'is_active' => TRUE, + ); + + $messageTemplate['pdf_format_id'] = 'null'; + if (CRM_Utils_Array::value('bind_format', $formValues) && $formValues['format_id'] > 0) { + $messageTemplate['pdf_format_id'] = $formValues['format_id']; + } + if (CRM_Utils_Array::value('saveTemplate', $formValues) && $formValues['saveTemplate']) { + $messageTemplate['msg_title'] = $formValues['saveTemplateName']; + CRM_Core_BAO_MessageTemplates::add($messageTemplate); + } + + if (CRM_Utils_Array::value('updateTemplate', $formValues) && $formValues['template'] && $formValues['updateTemplate']) { + $messageTemplate['id'] = $formValues['template']; + + unset($messageTemplate['msg_title']); + CRM_Core_BAO_MessageTemplates::add($messageTemplate); + } + } + elseif (CRM_Utils_Array::value('template', $formValues) > 0) { + if (CRM_Utils_Array::value('bind_format', $formValues) && $formValues['format_id'] > 0) { + $query = "UPDATE civicrm_msg_template SET pdf_format_id = {$formValues['format_id']} WHERE id = {$formValues['template']}"; + } + else { + $query = "UPDATE civicrm_msg_template SET pdf_format_id = NULL WHERE id = {$formValues['template']}"; + } + CRM_Core_DAO::executeQuery($query, CRM_Core_DAO::$_nullArray); + } + if (CRM_Utils_Array::value('update_format', $formValues)) { + $bao = new CRM_Core_BAO_PdfFormat(); + $bao->savePdfFormat($formValues, $formValues['format_id']); + } + + $html = array(); + + $tokens = array(); + CRM_Utils_Hook::tokens($tokens); + $categories = array_keys($tokens); + + $html_message = $formValues['html_message']; + + //time being hack to strip ' ' + //from particular letter line, CRM-6798 + self::formatMessage($html_message); + + $messageToken = CRM_Utils_Token::getTokens($html_message); + + $returnProperties = array(); + if (isset($messageToken['contact'])) { + foreach ($messageToken['contact'] as $key => $value) { + $returnProperties[$value] = 1; + } + } + + return array($formValues, $categories, $html_message, $messageToken, $returnProperties); + } + + /** + * process the form after the input has been submitted and validated + * + * @access public + * + * @return None + */ + static function postProcess(&$form) { + list($formValues, $categories, $html_message, $messageToken, $returnProperties) = self::processMessageTemplate($form); + + $skipOnHold = isset($form->skipOnHold) ? $form->skipOnHold : FALSE; + $skipDeceased = isset($form->skipDeceased) ? $form->skipDeceased : TRUE; + + foreach ($form->_contactIds as $item => $contactId) { + $params = array('contact_id' => $contactId); + + list($contact) = CRM_Utils_Token::getTokenDetails($params, + $returnProperties, + $skipOnHold, + $skipDeceased, + NULL, + $messageToken, + 'CRM_Contact_Form_Task_PDFLatexCommon' + ); + if (civicrm_error($contact)) { + $notSent[] = $contactId; + continue; + } + + $tokenHtml = CRM_Utils_Token::replaceContactTokens($html_message, $contact[$contactId], TRUE, $messageToken); + $tokenHtml = CRM_Utils_Token::replaceHookTokens($tokenHtml, $contact[$contactId], $categories, TRUE); + + if (defined('CIVICRM_MAIL_SMARTY') && CIVICRM_MAIL_SMARTY) { + $smarty = CRM_Core_Smarty::singleton(); + // also add the contact tokens to the template + $smarty->assign_by_ref('contact', $contact); + $tokenHtml = $smarty->fetch("string:$tokenHtml"); + } + + $html[] = $tokenHtml; + } + + self::createActivities($form, $html_message, $form->_contactIds); + + CRM_Utils_PDF_Utils::latex2pdf($html, "CiviLatex.pdf", FALSE, $formValues); + + $form->postProcessHook(); + + CRM_Utils_System::civiExit(1); + } + + function createActivities($form, $html_message, $contactIds) { + + $session = CRM_Core_Session::singleton(); + $userID = $session->get('userID'); + $activityTypeID = CRM_Core_OptionGroup::getValue('activity_type', + 'Print PDF LaTeX Letter', + 'name' + ); + $activityParams = array( + 'source_contact_id' => $userID, + 'activity_type_id' => $activityTypeID, + 'activity_date_time' => date('YmdHis'), + 'details' => $html_message, + ); + if (!empty($form->_activityId)) { + $activityParams += array('id' => $form->_activityId); + } + if ($form->_cid) { + $activity = CRM_Activity_BAO_Activity::create($activityParams); + } + else { + // create Print PDF activity for each selected contact. CRM-6886 + $activityIds = array(); + foreach ($contactIds as $contactId) { + $activityID = CRM_Activity_BAO_Activity::create($activityParams); + $activityIds[$contactId] = $activityID->id; + } + } + + foreach ($form->_contactIds as $contactId) { + $activityTargetParams = array( + 'activity_id' => empty($activity->id) ? $activityIds[$contactId] : $activity->id, + 'target_contact_id' => $contactId, + ); + CRM_Activity_BAO_Activity::createActivityTarget($activityTargetParams); + } + } + + function formatMessage(&$message) { + $newLineOperators = array( + 'p' => array( + 'oper' => '

', + 'pattern' => '/<(\s+)?p(\s+)?>/m', + ), + 'br' => array( + 'oper' => '
', + 'pattern' => '/<(\s+)?br(\s+)?\/>/m', + ), + ); + + $htmlMsg = preg_split($newLineOperators['p']['pattern'], $message); + foreach ($htmlMsg as $k => & $m) { + $messages = preg_split($newLineOperators['br']['pattern'], $m); + foreach ($messages as $key => & $msg) { + $msg = trim($msg); + $matches = array(); + if (preg_match('/^( )+/', $msg, $matches)) { + $spaceLen = strlen($matches[0]) / 6; + $trimMsg = ltrim($msg, '  '); + $charLen = strlen($trimMsg); + $totalLen = $charLen + $spaceLen; + if ($totalLen > 100) { + $spacesCount = 10; + if ($spaceLen > 50) { + $spacesCount = 20; + } + if ($charLen > 100) { + $spacesCount = 1; + } + $msg = str_repeat(' ', $spacesCount) . $trimMsg; + } + } + } + $m = implode($newLineOperators['br']['oper'], $messages); + } + $message = implode($newLineOperators['p']['oper'], $htmlMsg); + } +} + diff --git a/CRM/Contribute/Form/Task/PDFLatex.php b/CRM/Contribute/Form/Task/PDFLatex.php new file mode 100644 index 0000000000..f353e00c4e --- /dev/null +++ b/CRM/Contribute/Form/Task/PDFLatex.php @@ -0,0 +1,147 @@ +skipOnHold = $this->skipDeceased = FALSE; + CRM_Contact_Form_Task_PDFLetterCommon::preProcess($this); + + // store case id if present + $this->_caseId = CRM_Utils_Request::retrieve('caseid', 'Positive', $this, FALSE); + + // retrieve contact ID if this is 'single' mode + $cid = CRM_Utils_Request::retrieve('cid', 'Positive', $this, FALSE); + + $this->_activityId = CRM_Utils_Request::retrieve('id', 'Positive', $this, FALSE); + + if ($cid) { + CRM_Contact_Form_Task_PDFLetterCommon::preProcessSingle($this, $cid); + $this->_single = TRUE; + $this->_cid = $cid; + } + else { + parent::preProcess(); + } + $this->assign('single', $this->_single); + } + + function setDefaultValues() { + $defaults = array(); + if (isset($this->_activityId)) { + $params = array('id' => $this->_activityId); + CRM_Activity_BAO_Activity::retrieve($params, $defaults); + $defaults['html_message'] = $defaults['details']; + } + $defaults = $defaults + CRM_Contact_Form_Task_PDFLetterCommon::setDefaultValues(); + return $defaults; + } + + /** + * Build the form + * + * @access public + * + * @return void + */ + public function buildQuickForm() { + //enable form element + $this->assign('suppressForm', FALSE); + + // use contact form as a base + CRM_Contact_Form_Task_PDFLetterCommon::buildQuickForm($this); + + // specific need for contributions + $this->add('static', 'more_options_header', NULL, ts('Record Update Options')); + $this->add('checkbox', 'receipt_update', ts('Update receipt dates for these contributions'), FALSE); + $this->add('checkbox', 'thankyou_update', ts('Update thank-you dates for these contributions'), FALSE); + + // Group options for tokens are not yet implemented. dgg + $options = array(ts('Contact'), ts('Recurring')); + $this->addRadio('is_group_by', ts('Grouping contributions in one letter based on'), $options, array(), "
", FALSE); + + $this->addButtons(array( + array( + 'type' => 'submit', + 'name' => ts('Make Thank-you Letters'), + 'isDefault' => TRUE, + ), + array( + 'type' => 'cancel', + 'name' => ts('Done'), + ), + ) + ); + + } + + /** + * process the form after the input has been submitted and validated + * + * @access public + * + * @return None + */ + public function postProcess() { + // TODO: rewrite using contribution token and one letter by contribution + $this->setContactIDs(); + + CRM_Contribute_Form_Task_PDFLatexCommon::postProcess($this); + } + + +} + diff --git a/CRM/Contribute/Form/Task/PDFLatexCommon.php b/CRM/Contribute/Form/Task/PDFLatexCommon.php new file mode 100644 index 0000000000..862b03f279 --- /dev/null +++ b/CRM/Contribute/Form/Task/PDFLatexCommon.php @@ -0,0 +1,116 @@ +skipOnHold) ? $form->skipOnHold : FALSE; + $skipDeceased = isset($form->skipDeceased) ? $form->skipDeceased : TRUE; + + foreach ($form->getVar('_contributionIds') as $item => $contributionId) { + + // get contact information + $contactId = civicrm_api("Contribution", "getvalue", array('version' => '3', 'id' => $contributionId, 'return' => 'contact_id')); + $params = array('contact_id' => $contactId); + + list($contact) = CRM_Utils_Token::getTokenDetails($params, + $returnProperties, + $skipOnHold, + $skipDeceased, + NULL, + $messageToken, + 'CRM_Contribution_Form_Task_PDFLetterCommon' + ); + if (civicrm_error($contact)) { + $notSent[] = $contributionId; + continue; + } + + // get contribution information + $params = array('contribution_id' => $contributionId); + $contribution = CRM_Utils_Token::getContributionTokenDetails($params, + $returnProperties, + NULL, + $messageToken, + 'CRM_Contribution_Form_Task_PDFLetterCommon' + ); + if (civicrm_error($contribution)) { + $notSent[] = $contributionId; + continue; + } + + $tokenHtml = CRM_Utils_Token::replaceContactTokens($html_message, $contact[$contactId], FALSE, $messageToken); + $tokenHtml = CRM_Utils_Token::replaceContributionTokens($tokenHtml, $contribution[$contributionId], TRUE, $messageToken); + $tokenHtml = CRM_Utils_Token::replaceHookTokens($tokenHtml, $contact[$contactId], $categories, TRUE); + + if (defined('CIVICRM_MAIL_SMARTY') && CIVICRM_MAIL_SMARTY) { + $smarty = CRM_Core_Smarty::singleton(); + // also add the tokens to the template + $smarty->assign_by_ref('contact', $contact); + $tokenHtml = $smarty->fetch("string:$tokenHtml"); + } + + $html[] = $tokenHtml; + + // update dates (do it for each contribution including grouped recurring contribution) + if ($receipt_update) { + $result = CRM_Core_DAO::setFieldValue('CRM_Contribute_DAO_Contribution', $contributionId, 'receipt_date', $nowDate); + // We can't use CRM_Core_Error::fatal here because the api error elevates the exception level. FIXME. dgg + if ($result) { + $receipts++; + } + } + if ($thankyou_update) { + $result = CRM_Core_DAO::setFieldValue('CRM_Contribute_DAO_Contribution', $contributionId, 'thankyou_date', $nowDate); + // We can't use CRM_Core_Error::fatal here because the api error elevates the exception level. FIXME. dgg + if ($result) { + $thanks++; + } + } + } + + self::createActivities($form, $html_message, $form->_contactIds); + + CRM_Utils_PDF_Utils::latex2pdf($html, "CiviLatex.pdf", FALSE, $formValues); + + $form->postProcessHook(); + + if ($receipts) { + $updateStatus = ts('Receipt date has been updated for %1 contributions.', array(1 => $receipts)); + } + if ($thanks) { + $updateStatus .= ' ' . ts('Thank-you date has been updated for %1 contributions.', array(1 => $thanks)); + } + + if ($updateStatus) { + CRM_Core_Session::setStatus($updateStatus); + } + + CRM_Utils_System::civiExit(1); + } + //end of function +} + diff --git a/CRM/Core/Payment/TrustCommerce.php b/CRM/Core/Payment/TrustCommerce.php new file mode 100644 index 0000000000..534bc8fde6 --- /dev/null +++ b/CRM/Core/Payment/TrustCommerce.php @@ -0,0 +1,467 @@ + (http://www.fsf.org) + * + */ + +require_once 'CRM/Core/Payment.php'; +class CRM_Core_Payment_TrustCommerce extends CRM_Core_Payment { + CONST CHARSET = 'iso-8859-1'; + CONST AUTH_APPROVED = 'approve'; + CONST AUTH_DECLINED = 'decline'; + CONST AUTH_BADDATA = 'baddata'; + CONST AUTH_ERROR = 'error'; + + static protected $_mode = NULL; + + static protected $_params = array(); + + /** + * We only need one instance of this object. So we use the singleton + * pattern and cache the instance in this variable + * + * @var object + * @static + */ + static private $_singleton = NULL; + + /** + * Constructor + * + * @param string $mode the mode of operation: live or test + * + * @return void + */ function __construct($mode, &$paymentProcessor) { + $this->_mode = $mode; + + $this->_paymentProcessor = $paymentProcessor; + + $this->_processorName = ts('TrustCommerce'); + + $config = CRM_Core_Config::singleton(); + $this->_setParam('user_name', $paymentProcessor['user_name']); + $this->_setParam('password', $paymentProcessor['password']); + + $this->_setParam('timestamp', time()); + srand(time()); + $this->_setParam('sequence', rand(1, 1000)); + } + + /** + * singleton function used to manage this object + * + * @param string $mode the mode of operation: live or test + * + * @return object + * @static + * + */ + static + function &singleton($mode, &$paymentProcessor) { + $processorName = $paymentProcessor['name']; + if (self::$_singleton[$processorName] === NULL) { + self::$_singleton[$processorName] = new CRM_Core_Payment_TrustCommerce($mode, $paymentProcessor); + } + return self::$_singleton[$processorName]; + } + + /** + * Submit a payment using Advanced Integration Method + * + * @param array $params assoc array of input parameters for this transaction + * + * @return array the result in a nice formatted array (or an error object) + * @public + */ + function doDirectPayment(&$params) { + if (!extension_loaded("tclink")) { + return self::error(9001, 'TrustCommerce requires that the tclink module is loaded'); + } + + /* + * recurpayment function does not compile an array & then proces it - + * - the tpl does the transformation so adding call to hook here + * & giving it a change to act on the params array + */ + + $newParams = $params; + if (CRM_Utils_Array::value('is_recur', $params) && + $params['contributionRecurID'] + ) { + CRM_Utils_Hook::alterPaymentProcessorParams($this, + $params, + $newParams + ); + } + foreach ($newParams as $field => $value) { + $this->_setParam($field, $value); + } + + if (CRM_Utils_Array::value('is_recur', $params) && + $params['contributionRecurID'] + ) { + return $this->doRecurPayment($params); + } + + $postFields = array(); + $tclink = $this->_getTrustCommerceFields(); + + // Set up our call for hook_civicrm_paymentProcessor, + // since we now have our parameters as assigned for the AIM back end. + CRM_Utils_Hook::alterPaymentProcessorParams($this, + $params, + $tclink + ); + + // TrustCommerce will not refuse duplicates, so we should check if the user already submitted this transaction + if ($this->_checkDupe($tclink['ticket'])) { + return self::error(9004, 'It appears that this transaction is a duplicate. Have you already submitted the form once? If so there may have been a connection problem. You can try your transaction again. If you continue to have problems please contact the site administrator.'); + } + + $result = tclink_send($tclink); + + if (!$result) { + return self::error(9002, 'Could not initiate connection to payment gateway'); + } + + foreach ($result as $field => $value) { + error_log("result: $field => $value"); + } + + switch($result['status']) { + case self::AUTH_APPROVED: + // It's all good + break; + case self::AUTH_DECLINED: + // TODO FIXME be more or less specific? + // declinetype can be: decline, avs, cvv, call, expiredcard, carderror, authexpired, fraud, blacklist, velocity + // See TC documentation for more info + return self::error(9009, "Your transaction was declined: {$result['declinetype']}"); + break; + case self::AUTH_BADDATA: + // TODO FIXME do something with $result['error'] and $result['offender'] + return self::error(9011, "Invalid credit card information. Please re-enter."); + break; + case self::AUTH_ERROR: + return self::error(9002, 'Could not initiate connection to payment gateway'); + break; + } + + // Success + + $params['trxn_id'] = $result['transid']; + $params['gross_amount'] = $tclink['amount'] / 100; + + return $params; + } + + /** + * Submit an Automated Recurring Billing subscription + * + * @param array $params assoc array of input parameters for this transaction + * + * @return array the result in a nice formatted array (or an error object) + * @public + */ + function doRecurPayment(&$params) { + $template = CRM_Core_Smarty::singleton(); + + $intervalLength = $this->_getParam('frequency_interval'); + $intervalUnit = $this->_getParam('frequency_unit'); + if ($intervalUnit == 'week') { + $intervalLength *= 7; + $intervalUnit = 'days'; + } + elseif ($intervalUnit == 'year') { + $intervalLength *= 12; + $intervalUnit = 'months'; + } + elseif ($intervalUnit == 'day') { + $intervalUnit = 'days'; + } + elseif ($intervalUnit == 'month') { + $intervalUnit = 'months'; + } + + // interval cannot be less than 7 days or more than 1 year + if ($intervalUnit == 'days') { + if ($intervalLength < 7) { + return self::error(9001, 'Payment interval must be at least one week'); + } + elseif ($intervalLength > 365) { + return self::error(9001, 'Payment interval may not be longer than one year'); + } + } + elseif ($intervalUnit == 'months') { + if ($intervalLength < 1) { + return self::error(9001, 'Payment interval must be at least one week'); + } + elseif ($intervalLength > 12) { + return self::error(9001, 'Payment interval may not be longer than one year'); + } + } + + $template->assign('intervalLength', $intervalLength); + $template->assign('intervalUnit', $intervalUnit); + + $template->assign('apiLogin', $this->_getParam('apiLogin')); + $template->assign('paymentKey', $this->_getParam('paymentKey')); + $template->assign('refId', substr($this->_getParam('invoiceID'), 0, 20)); + + //for recurring, carry first contribution id + $template->assign('invoiceNumber', $this->_getParam('contributionID')); + $firstPaymentDate = $this->_getParam('receive_date'); + if (!empty($firstPaymentDate)) { + //allow for post dated payment if set in form + $template->assign('startDate', date('Y-m-d', strtotime($firstPaymentDate))); + } + else { + $template->assign('startDate', date('Y-m-d')); + } + // for open ended subscription totalOccurrences has to be 9999 + $installments = $this->_getParam('installments'); + $template->assign('totalOccurrences', $installments ? $installments : 9999); + + $template->assign('amount', $this->_getParam('amount')); + + $template->assign('cardNumber', $this->_getParam('credit_card_number')); + $exp_month = str_pad($this->_getParam('month'), 2, '0', STR_PAD_LEFT); + $exp_year = $this->_getParam('year'); + $template->assign('expirationDate', $exp_year . '-' . $exp_month); + // name rather than description is used in the tpl - see http://www.authorize.net/support/ARB_guide.pdf + $template->assign('name', $this->_getParam('description')); + + $template->assign('email', $this->_getParam('email')); + $template->assign('contactID', $this->_getParam('contactID')); + $template->assign('billingFirstName', $this->_getParam('billing_first_name')); + $template->assign('billingLastName', $this->_getParam('billing_last_name')); + $template->assign('billingAddress', $this->_getParam('street_address')); + $template->assign('billingCity', $this->_getParam('city')); + $template->assign('billingState', $this->_getParam('state_province')); + $template->assign('billingZip', $this->_getParam('postal_code')); + $template->assign('billingCountry', $this->_getParam('country')); + + $arbXML = $template->fetch('CRM/Contribute/Form/Contribution/AuthorizeNetARB.tpl'); + // submit to authorize.net + + $submit = curl_init($this->_paymentProcessor['url_recur']); + if (!$submit) { + return self::error(9002, 'Could not initiate connection to payment gateway'); + } + curl_setopt($submit, CURLOPT_RETURNTRANSFER, 1); + curl_setopt($submit, CURLOPT_HTTPHEADER, array("Content-Type: text/xml")); + curl_setopt($submit, CURLOPT_HEADER, 1); + curl_setopt($submit, CURLOPT_POSTFIELDS, $arbXML); + curl_setopt($submit, CURLOPT_POST, 1); + curl_setopt($submit, CURLOPT_SSL_VERIFYPEER, 0); + + $response = curl_exec($submit); + + if (!$response) { + return self::error(curl_errno($submit), curl_error($submit)); + } + + curl_close($submit); + $responseFields = $this->_ParseArbReturn($response); + + if ($responseFields['resultCode'] == 'Error') { + return self::error($responseFields['code'], $responseFields['text']); + } + + // update recur processor_id with subscriptionId + CRM_Core_DAO::setFieldValue('CRM_Contribute_DAO_ContributionRecur', $params['contributionRecurID'], + 'processor_id', $responseFields['subscriptionId'] + ); + //only impact of assigning this here is is can be used to cancel the subscription in an automated test + // if it isn't cancelled a duplicate transaction error occurs + if (CRM_Utils_Array::value('subscriptionId', $responseFields)) { + $this->_setParam('subscriptionId', $responseFields['subscriptionId']); + } + return $params; + } + + function _getTrustCommerceFields() { + // Total amount is from the form contribution field + $amount = $this->_getParam('total_amount'); + // CRM-9894 would this ever be the case?? + if (empty($amount)) { + $amount = $this->_getParam('amount'); + } + $fields = array(); + $fields['custid'] = $this->_getParam('user_name'); + $fields['password'] = $this->_getParam('password'); + $fields['action'] = 'sale'; + + // Enable address verification + $fields['avs'] = 'y'; + + $fields['address1'] = $this->_getParam('street_address'); + $fields['zip'] = $this->_getParam('postal_code'); + + $fields['name'] = $this->_getParam('billing_first_name') . ' ' . $this->_getParam('billing_last_name'); + + // We need to pass the amount to TrustCommerce in dollar cents + $fields['amount'] = $amount * 100; + + // Unique identifier + $fields['ticket'] = substr($this->_getParam('invoiceID'), 0, 20); + + // cc info + $fields['cc'] = $this->_getParam('credit_card_number'); + $fields['cvv'] = $this->_getParam('cvv2'); + $exp_month = str_pad($this->_getParam('month'), 2, '0', STR_PAD_LEFT); + $exp_year = substr($this->_getParam('year'),-2); + $fields['exp'] = "$exp_month$exp_year"; + + if ($this->_mode != 'live') { + $fields['demo'] = 'y'; + } + // TODO FIXME remove + foreach ($fields as $field => $value) { + if ($field == 'custid') $value = '********'; + if ($field == 'password') $value = '********'; + error_log("fields: $field => $value"); + } + + return $fields; + } + + /** + * Checks to see if invoice_id already exists in db + * + * @param int $invoiceId The ID to check + * + * @return bool True if ID exists, else false + */ + function _checkDupe($invoiceId) { + require_once 'CRM/Contribute/DAO/Contribution.php'; + $contribution = new CRM_Contribute_DAO_Contribution(); + $contribution->invoice_id = $invoiceId; + return $contribution->find(); + } + + /** + * Get the value of a field if set + * + * @param string $field the field + * + * @return mixed value of the field, or empty string if the field is + * not set + */ + function _getParam($field) { + return CRM_Utils_Array::value($field, $this->_params, ''); + } + + function &error($errorCode = NULL, $errorMessage = NULL) { + $e = CRM_Core_Error::singleton(); + if ($errorCode) { + $e->push($errorCode, 0, NULL, $errorMessage); + } + else { + $e->push(9001, 0, NULL, 'Unknown System Error.'); + } + return $e; + } + + /** + * Set a field to the specified value. Value must be a scalar (int, + * float, string, or boolean) + * + * @param string $field + * @param mixed $value + * + * @return bool false if value is not a scalar, true if successful + */ + function _setParam($field, $value) { + if (!is_scalar($value)) { + return FALSE; + } + else { + $this->_params[$field] = $value; + } + } + + /** + * This function checks to see if we have the right config values + * + * @return string the error message if any + * @public + */ + function checkConfig() { + $error = array(); + if (empty($this->_paymentProcessor['user_name'])) { + $error[] = ts('Customer ID is not set for this payment processor'); + } + + if (empty($this->_paymentProcessor['password'])) { + $error[] = ts('Password is not set for this payment processor'); + } + + if (!empty($error)) { + return implode('

', $error); + } + else { + return NULL; + } + } + + function cancelSubscriptionURL($entityID = NULL, $entity = NULL) { + if ($entityID && $entity == 'membership') { + require_once 'CRM/Contact/BAO/Contact/Utils.php'; + $contactID = CRM_Core_DAO::getFieldValue("CRM_Member_DAO_Membership", $entityID, "contact_id"); + $checksumValue = CRM_Contact_BAO_Contact_Utils::generateChecksum($contactID, NULL, 'inf'); + + return CRM_Utils_System::url('civicrm/contribute/unsubscribe', + "reset=1&mid={$entityID}&cs={$checksumValue}", TRUE, NULL, FALSE, FALSE + ); + } + + return ($this->_mode == 'test') ? 'https://test.authorize.net' : 'https://authorize.net'; + } + + function cancelSubscription() { + $template = CRM_Core_Smarty::singleton(); + + $template->assign('subscriptionType', 'cancel'); + + $template->assign('apiLogin', $this->_getParam('apiLogin')); + $template->assign('paymentKey', $this->_getParam('paymentKey')); + $template->assign('subscriptionId', $this->_getParam('subscriptionId')); + + $arbXML = $template->fetch('CRM/Contribute/Form/Contribution/AuthorizeNetARB.tpl'); + + // submit to authorize.net + $submit = curl_init($this->_paymentProcessor['url_recur']); + if (!$submit) { + return self::error(9002, 'Could not initiate connection to payment gateway'); + } + + curl_setopt($submit, CURLOPT_RETURNTRANSFER, 1); + curl_setopt($submit, CURLOPT_HTTPHEADER, array("Content-Type: text/xml")); + curl_setopt($submit, CURLOPT_HEADER, 1); + curl_setopt($submit, CURLOPT_POSTFIELDS, $arbXML); + curl_setopt($submit, CURLOPT_POST, 1); + curl_setopt($submit, CURLOPT_SSL_VERIFYPEER, 0); + + $response = curl_exec($submit); + + if (!$response) { + return self::error(curl_errno($submit), curl_error($submit)); + } + + curl_close($submit); + + $responseFields = $this->_ParseArbReturn($response); + + if ($responseFields['resultCode'] == 'Error') { + return self::error($responseFields['code'], $responseFields['text']); + } + + // carry on cancelation procedure + return TRUE; + } +} + diff --git a/CRM/Core/Payment/insert_tc.sql b/CRM/Core/Payment/insert_tc.sql new file mode 100644 index 0000000000..3bbd1e55b8 --- /dev/null +++ b/CRM/Core/Payment/insert_tc.sql @@ -0,0 +1,7 @@ + INSERT INTO civicrm_payment_processor_type + (name, title, description, is_active, is_default, user_name_label, password_label, signature_label, subject_label, class_name, url_site_default, url_recur_default, url_button_default, url_site_test_default, url_recur_test_default, url_button_test_default, billing_mode, is_recur ) + VALUES + ('TrustCommerce','TrustCommerce',NULL,1,0,'Customer ID','Password',NULL,NULL,'Payment_TrustCommerce',NULL,NULL,NULL,NULL,NULL,NULL,1,NULL); + + + diff --git a/i/mini_cvv2.gif b/i/mini_cvv2.gif new file mode 100644 index 0000000000..c3d6a8dd99 Binary files /dev/null and b/i/mini_cvv2.gif differ diff --git a/latex.patch b/latex.patch new file mode 100644 index 0000000000..4a59aa2461 --- /dev/null +++ b/latex.patch @@ -0,0 +1,764 @@ +diff --git a/CRM/Contribute/Form/Task/PDFLatex.php b/CRM/Contribute/Form/Task/PDFLatex.php +new file mode 100644 +index 0000000..f353e00 +--- /dev/null ++++ b/CRM/Contribute/Form/Task/PDFLatex.php +@@ -0,0 +1,147 @@ ++skipOnHold = $this->skipDeceased = FALSE; ++ CRM_Contact_Form_Task_PDFLetterCommon::preProcess($this); ++ ++ // store case id if present ++ $this->_caseId = CRM_Utils_Request::retrieve('caseid', 'Positive', $this, FALSE); ++ ++ // retrieve contact ID if this is 'single' mode ++ $cid = CRM_Utils_Request::retrieve('cid', 'Positive', $this, FALSE); ++ ++ $this->_activityId = CRM_Utils_Request::retrieve('id', 'Positive', $this, FALSE); ++ ++ if ($cid) { ++ CRM_Contact_Form_Task_PDFLetterCommon::preProcessSingle($this, $cid); ++ $this->_single = TRUE; ++ $this->_cid = $cid; ++ } ++ else { ++ parent::preProcess(); ++ } ++ $this->assign('single', $this->_single); ++ } ++ ++ function setDefaultValues() { ++ $defaults = array(); ++ if (isset($this->_activityId)) { ++ $params = array('id' => $this->_activityId); ++ CRM_Activity_BAO_Activity::retrieve($params, $defaults); ++ $defaults['html_message'] = $defaults['details']; ++ } ++ $defaults = $defaults + CRM_Contact_Form_Task_PDFLetterCommon::setDefaultValues(); ++ return $defaults; ++ } ++ ++ /** ++ * Build the form ++ * ++ * @access public ++ * ++ * @return void ++ */ ++ public function buildQuickForm() { ++ //enable form element ++ $this->assign('suppressForm', FALSE); ++ ++ // use contact form as a base ++ CRM_Contact_Form_Task_PDFLetterCommon::buildQuickForm($this); ++ ++ // specific need for contributions ++ $this->add('static', 'more_options_header', NULL, ts('Record Update Options')); ++ $this->add('checkbox', 'receipt_update', ts('Update receipt dates for these contributions'), FALSE); ++ $this->add('checkbox', 'thankyou_update', ts('Update thank-you dates for these contributions'), FALSE); ++ ++ // Group options for tokens are not yet implemented. dgg ++ $options = array(ts('Contact'), ts('Recurring')); ++ $this->addRadio('is_group_by', ts('Grouping contributions in one letter based on'), $options, array(), "
", FALSE); ++ ++ $this->addButtons(array( ++ array( ++ 'type' => 'submit', ++ 'name' => ts('Make Thank-you Letters'), ++ 'isDefault' => TRUE, ++ ), ++ array( ++ 'type' => 'cancel', ++ 'name' => ts('Done'), ++ ), ++ ) ++ ); ++ ++ } ++ ++ /** ++ * process the form after the input has been submitted and validated ++ * ++ * @access public ++ * ++ * @return None ++ */ ++ public function postProcess() { ++ // TODO: rewrite using contribution token and one letter by contribution ++ $this->setContactIDs(); ++ ++ CRM_Contribute_Form_Task_PDFLatexCommon::postProcess($this); ++ } ++ ++ ++} ++ +diff --git a/CRM/Contribute/Form/Task/PDFLatexCommon.php b/CRM/Contribute/Form/Task/PDFLatexCommon.php +new file mode 100644 +index 0000000..862b03f +--- /dev/null ++++ b/CRM/Contribute/Form/Task/PDFLatexCommon.php +@@ -0,0 +1,116 @@ ++skipOnHold) ? $form->skipOnHold : FALSE; ++ $skipDeceased = isset($form->skipDeceased) ? $form->skipDeceased : TRUE; ++ ++ foreach ($form->getVar('_contributionIds') as $item => $contributionId) { ++ ++ // get contact information ++ $contactId = civicrm_api("Contribution", "getvalue", array('version' => '3', 'id' => $contributionId, 'return' => 'contact_id')); ++ $params = array('contact_id' => $contactId); ++ ++ list($contact) = CRM_Utils_Token::getTokenDetails($params, ++ $returnProperties, ++ $skipOnHold, ++ $skipDeceased, ++ NULL, ++ $messageToken, ++ 'CRM_Contribution_Form_Task_PDFLetterCommon' ++ ); ++ if (civicrm_error($contact)) { ++ $notSent[] = $contributionId; ++ continue; ++ } ++ ++ // get contribution information ++ $params = array('contribution_id' => $contributionId); ++ $contribution = CRM_Utils_Token::getContributionTokenDetails($params, ++ $returnProperties, ++ NULL, ++ $messageToken, ++ 'CRM_Contribution_Form_Task_PDFLetterCommon' ++ ); ++ if (civicrm_error($contribution)) { ++ $notSent[] = $contributionId; ++ continue; ++ } ++ ++ $tokenHtml = CRM_Utils_Token::replaceContactTokens($html_message, $contact[$contactId], FALSE, $messageToken); ++ $tokenHtml = CRM_Utils_Token::replaceContributionTokens($tokenHtml, $contribution[$contributionId], TRUE, $messageToken); ++ $tokenHtml = CRM_Utils_Token::replaceHookTokens($tokenHtml, $contact[$contactId], $categories, TRUE); ++ ++ if (defined('CIVICRM_MAIL_SMARTY') && CIVICRM_MAIL_SMARTY) { ++ $smarty = CRM_Core_Smarty::singleton(); ++ // also add the tokens to the template ++ $smarty->assign_by_ref('contact', $contact); ++ $tokenHtml = $smarty->fetch("string:$tokenHtml"); ++ } ++ ++ $html[] = $tokenHtml; ++ ++ // update dates (do it for each contribution including grouped recurring contribution) ++ if ($receipt_update) { ++ $result = CRM_Core_DAO::setFieldValue('CRM_Contribute_DAO_Contribution', $contributionId, 'receipt_date', $nowDate); ++ // We can't use CRM_Core_Error::fatal here because the api error elevates the exception level. FIXME. dgg ++ if ($result) { ++ $receipts++; ++ } ++ } ++ if ($thankyou_update) { ++ $result = CRM_Core_DAO::setFieldValue('CRM_Contribute_DAO_Contribution', $contributionId, 'thankyou_date', $nowDate); ++ // We can't use CRM_Core_Error::fatal here because the api error elevates the exception level. FIXME. dgg ++ if ($result) { ++ $thanks++; ++ } ++ } ++ } ++ ++ self::createActivities($form, $html_message, $form->_contactIds); ++ ++ CRM_Utils_PDF_Utils::latex2pdf($html, "CiviLatex.pdf", FALSE, $formValues); ++ ++ $form->postProcessHook(); ++ ++ if ($receipts) { ++ $updateStatus = ts('Receipt date has been updated for %1 contributions.', array(1 => $receipts)); ++ } ++ if ($thanks) { ++ $updateStatus .= ' ' . ts('Thank-you date has been updated for %1 contributions.', array(1 => $thanks)); ++ } ++ ++ if ($updateStatus) { ++ CRM_Core_Session::setStatus($updateStatus); ++ } ++ ++ CRM_Utils_System::civiExit(1); ++ } ++ //end of function ++} ++ +diff --git a/CRM/Contribute/Task.php b/CRM/Contribute/Task.php +index 987b280..129cb45 100644 +--- a/CRM/Contribute/Task.php ++++ b/CRM/Contribute/Task.php +@@ -39,7 +39,7 @@ + * + */ + class CRM_Contribute_Task { +- CONST DELETE_CONTRIBUTIONS = 1, PRINT_CONTRIBUTIONS = 2, EXPORT_CONTRIBUTIONS = 3, BATCH_CONTRIBUTIONS = 4, EMAIL_CONTACTS = 5, UPDATE_STATUS = 6, PDF_RECEIPT = 7; ++ CONST DELETE_CONTRIBUTIONS = 1, PRINT_CONTRIBUTIONS = 2, EXPORT_CONTRIBUTIONS = 3, BATCH_CONTRIBUTIONS = 4, EMAIL_CONTACTS = 5, UPDATE_STATUS = 6, PDF_RECEIPT = 7, LATEX_TEST = 9; + + /** + * the task array +@@ -106,6 +106,10 @@ static function &tasks() { + 'class' => 'CRM_Contribute_Form_Task_PDFLetter', + 'result' => FALSE, + ), ++ 9 => array('title' => ts('Latex Letters for Contributions'), ++ 'class' => 'CRM_Contribute_Form_Task_PDFLatex', ++ 'result' => FALSE, ++ ), + ); + + //CRM-4418, check for delete +diff --git a/CRM/Utils/PDF/Utils.php b/CRM/Utils/PDF/Utils.php +index 72d4880..e9d59b9 100644 +--- a/CRM/Utils/PDF/Utils.php ++++ b/CRM/Utils/PDF/Utils.php +@@ -34,6 +34,69 @@ + */ + class CRM_Utils_PDF_Utils { + ++ static function latex2pdf(&$text, $fileName = 'civicrm.pdf', $output = FALSE, $pdfFormat = NULL) { ++ /* FIXME: get $paper_size, $orientation, $margins */ ++ ++ if (is_array($text)) { ++ $pages = &$text; ++ } ++ else { ++ $pages = array($text); ++ } ++ ++ ++ $head='\documentclass[12pt]{letter} ++\oddsidemargin 0in ++\evensidemargin 0in ++\textwidth 6.5in ++ ++\topmargin -.25in ++\textheight 8.15in ++ ++\address{\vspace{0.354in}} ++ ++\begin{document} ++ ++'; ++ $footer=' ++\end{document}'; ++ ++ $latex = $head; ++ foreach ($pages as $page) { ++ $latex.=$page; ++ } ++ $latex.=$footer; ++ ++ $descriptorspec = array( ++ 0 => array("pipe", "r"), ++ 1 => array("pipe", "w") ++ ); ++ ++ ++ ++ $process = proc_open("/usr/local/bin/pdflatex_wrapper.sh", $descriptorspec, $pipes); ++ ++ ++ if (is_resource($process)) { ++ fwrite($pipes[0], $latex); ++ fclose($pipes[0]); ++ ++ $pdf = stream_get_contents($pipes[1]); ++ fclose($pipes[1]); ++ } else { ++ CRM_Core_Error::debug_log_message("ERROR creating PDF. Check /tmp/pdflatex_*"); ++ } ++ ++ if ($output) { ++ return $pdf; ++ } ++ else { ++ header('Content-Type: application/pdf'); ++ header('Content-Disposition: attachment; filename="' . $fileName . '"'); ++ echo $pdf; ++ } ++ } ++ + static function html2pdf(&$text, $fileName = 'civicrm.pdf', $output = FALSE, $pdfFormat = NULL) { + if (is_array($text)) { + $pages = &$text; +diff --git a/CRM/Utils/Token.php b/CRM/Utils/Token.php +index 28ca941..e8df124 100644 +--- a/CRM/Utils/Token.php ++++ b/CRM/Utils/Token.php +@@ -619,7 +619,10 @@ function ($matches) use(&$contact, $html, $returnBlankToken, $escapeSmarty) { + $str + ); + +- $str = preg_replace('/\\\\|\{(\s*)?\}/', ' ', $str); ++ // 2013-08-31 nico@fsf.org this replacement is stripping all the '{' and '}' from the LaTeX files ++ // maybe it got solved at some point. maybe it has undesired collateral effects. I'm bugging the ++ // CiviCRM community to take a look at this pull request. ++ //$str = preg_replace('/\\\\|\{(\s*)?\}/', ' ', $str); + return $str; + } + +diff --git a/templates/CRM/Contact/Form/Task/PDFLatexCommon.tpl b/templates/CRM/Contact/Form/Task/PDFLatexCommon.tpl +new file mode 100644 +index 0000000..1f75f97 +--- /dev/null ++++ b/templates/CRM/Contact/Form/Task/PDFLatexCommon.tpl +@@ -0,0 +1,312 @@ ++{* ++ +--------------------------------------------------------------------+ ++ | CiviCRM version 4.4 | ++ +--------------------------------------------------------------------+ ++ | Copyright CiviCRM LLC (c) 2004-2013 | ++ +--------------------------------------------------------------------+ ++ | This file is a part of CiviCRM. | ++ | | ++ | CiviCRM is free software; you can copy, modify, and distribute it | ++ | under the terms of the GNU Affero General Public License | ++ | Version 3, 19 November 2007 and the CiviCRM Licensing Exception. | ++ | | ++ | CiviCRM is distributed in the hope that it will be useful, but | ++ | WITHOUT ANY WARRANTY; without even the implied warranty of | ++ | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | ++ | See the GNU Affero General Public License for more details. | ++ | | ++ | You should have received a copy of the GNU Affero General Public | ++ | License and the CiviCRM Licensing Exception along | ++ | with this program; if not, contact CiviCRM LLC | ++ | at info[AT]civicrm[DOT]org. If you have questions about the | ++ | GNU Affero General Public License or the licensing of CiviCRM, | ++ | see the CiviCRM license FAQ at http://civicrm.org/licensing | ++ +--------------------------------------------------------------------+ ++*} ++{*common template for compose PDF letters*} ++{if $form.template.html} ++ ++ ++ ++ ++ ++
{$form.template.label}{$form.template.html}
++{/if} ++ ++

++ ++
++
++ {$form.html_message.label} ++
++
++ {if $action neq 4} ++ ++ {$form.token1.label} ++ {help id="id-token-html" file="CRM/Contact/Form/Task/Email.hlp" tplFile=$tplFile isAdmin=$isAdmin editor=$editor} ++ ++ ++ {/if} ++
++
++ {if $editor EQ 'textarea'} ++
{ts}The content of this page should be LaTeX.{/ts}
++ {/if} ++ {$form.html_message.html}
++
++ ++
++
++ {$form.updateTemplate.html} {$form.updateTemplate.label} ++
++
++ {$form.saveTemplate.html} {$form.saveTemplate.label} ++
++
++ ++
++
{$form.saveTemplateName.label}
++
{$form.saveTemplateName.html|crmAddClass:huge}
++
++ ++
++
++ ++{include file="CRM/Mailing/Form/InsertTokens.tpl"} ++ ++{literal} ++ ++{/literal} ++ +diff --git a/templates/CRM/Contribute/Form/Task/PDFLatex.tpl b/templates/CRM/Contribute/Form/Task/PDFLatex.tpl +new file mode 100644 +index 0000000..a7fb259 +--- /dev/null ++++ b/templates/CRM/Contribute/Form/Task/PDFLatex.tpl +@@ -0,0 +1,48 @@ ++{* ++ +--------------------------------------------------------------------+ ++ | CiviCRM version 4.4 | ++ +--------------------------------------------------------------------+ ++ | Copyright CiviCRM LLC (c) 2004-2013 | ++ +--------------------------------------------------------------------+ ++ | This file is a part of CiviCRM. | ++ | | ++ | CiviCRM is free software; you can copy, modify, and distribute it | ++ | under the terms of the GNU Affero General Public License | ++ | Version 3, 19 November 2007 and the CiviCRM Licensing Exception. | ++ | | ++ | CiviCRM is distributed in the hope that it will be useful, but | ++ | WITHOUT ANY WARRANTY; without even the implied warranty of | ++ | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | ++ | See the GNU Affero General Public License for more details. | ++ | | ++ | You should have received a copy of the GNU Affero General Public | ++ | License and the CiviCRM Licensing Exception along | ++ | with this program; if not, contact CiviCRM LLC | ++ | at info[AT]civicrm[DOT]org. If you have questions about the | ++ | GNU Affero General Public License or the licensing of CiviCRM, | ++ | see the CiviCRM license FAQ at http://civicrm.org/licensing | ++ +--------------------------------------------------------------------+ ++*} ++
++

{ts}Thank-you Letter In Latex for Contributions (PDF){/ts}

++{if $single eq false} ++
{include file="CRM/Contribute/Form/Task.tpl"}
++{/if} ++ ++
++
++ {$form.more_options_header.html} ++
++
++ ++ ++ ++ ++
{$form.thankyou_update.html} {$form.thankyou_update.label}
{$form.receipt_update.html} {$form.receipt_update.label}
++
++
++ ++{include file="CRM/Contact/Form/Task/PDFLatexCommon.tpl"} ++ ++
{include file="CRM/common/formButtons.tpl" location="bottom"}
++
+-- +1.8.4 + diff --git a/sigjohns.pdf b/sigjohns.pdf new file mode 100644 index 0000000000..1965aa8c94 Binary files /dev/null and b/sigjohns.pdf differ diff --git a/sigjohns.png b/sigjohns.png new file mode 100644 index 0000000000..733c18c87a Binary files /dev/null and b/sigjohns.png differ diff --git a/templates/CRM/Contact/Form/Task/LatexPDF.tpl b/templates/CRM/Contact/Form/Task/LatexPDF.tpl new file mode 100644 index 0000000000..d260d564d4 --- /dev/null +++ b/templates/CRM/Contact/Form/Task/LatexPDF.tpl @@ -0,0 +1,33 @@ +{* + +--------------------------------------------------------------------+ + | CiviCRM version 4.3 | + +--------------------------------------------------------------------+ + | Copyright CiviCRM LLC (c) 2004-2013 | + +--------------------------------------------------------------------+ + | This file is a part of CiviCRM. | + | | + | CiviCRM is free software; you can copy, modify, and distribute it | + | under the terms of the GNU Affero General Public License | + | Version 3, 19 November 2007 and the CiviCRM Licensing Exception. | + | | + | CiviCRM is distributed in the hope that it will be useful, but | + | WITHOUT ANY WARRANTY; without even the implied warranty of | + | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | + | See the GNU Affero General Public License for more details. | + | | + | You should have received a copy of the GNU Affero General Public | + | License and the CiviCRM Licensing Exception along | + | with this program; if not, contact CiviCRM LLC | + | at info[AT]civicrm[DOT]org. If you have questions about the | + | GNU Affero General Public License or the licensing of CiviCRM, | + | see the CiviCRM license FAQ at http://civicrm.org/licensing | + +--------------------------------------------------------------------+ +*} +
+

{ts}Create Printable Latex Letters (PDF){/ts}

+{if $single eq false} +
{include file="CRM/Contact/Form/Task.tpl"}
+{/if} +{include file="CRM/Contact/Form/Task/LatexPDFLatexCommon.tpl"} +
{include file="CRM/common/formButtons.tpl" location="bottom"}
+
diff --git a/templates/CRM/Contact/Form/Task/LatexPDFLatexCommon.tpl b/templates/CRM/Contact/Form/Task/LatexPDFLatexCommon.tpl new file mode 100644 index 0000000000..1f75f97f7a --- /dev/null +++ b/templates/CRM/Contact/Form/Task/LatexPDFLatexCommon.tpl @@ -0,0 +1,312 @@ +{* + +--------------------------------------------------------------------+ + | CiviCRM version 4.4 | + +--------------------------------------------------------------------+ + | Copyright CiviCRM LLC (c) 2004-2013 | + +--------------------------------------------------------------------+ + | This file is a part of CiviCRM. | + | | + | CiviCRM is free software; you can copy, modify, and distribute it | + | under the terms of the GNU Affero General Public License | + | Version 3, 19 November 2007 and the CiviCRM Licensing Exception. | + | | + | CiviCRM is distributed in the hope that it will be useful, but | + | WITHOUT ANY WARRANTY; without even the implied warranty of | + | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | + | See the GNU Affero General Public License for more details. | + | | + | You should have received a copy of the GNU Affero General Public | + | License and the CiviCRM Licensing Exception along | + | with this program; if not, contact CiviCRM LLC | + | at info[AT]civicrm[DOT]org. If you have questions about the | + | GNU Affero General Public License or the licensing of CiviCRM, | + | see the CiviCRM license FAQ at http://civicrm.org/licensing | + +--------------------------------------------------------------------+ +*} +{*common template for compose PDF letters*} +{if $form.template.html} + + + + + +
{$form.template.label}{$form.template.html}
+{/if} + + + +
+
+ {$form.html_message.label} +
+
+ {if $action neq 4} + + {$form.token1.label} + {help id="id-token-html" file="CRM/Contact/Form/Task/Email.hlp" tplFile=$tplFile isAdmin=$isAdmin editor=$editor} + + + {/if} +
+
+ {if $editor EQ 'textarea'} +
{ts}The content of this page should be LaTeX.{/ts}
+ {/if} + {$form.html_message.html}
+
+ +
+
+ {$form.updateTemplate.html} {$form.updateTemplate.label} +
+
+ {$form.saveTemplate.html} {$form.saveTemplate.label} +
+
+ +
+
{$form.saveTemplateName.label}
+
{$form.saveTemplateName.html|crmAddClass:huge}
+
+ +
+
+ +{include file="CRM/Mailing/Form/InsertTokens.tpl"} + +{literal} + +{/literal} + diff --git a/templates/CRM/Contribute/Form/Task/PDFLatex.tpl b/templates/CRM/Contribute/Form/Task/PDFLatex.tpl new file mode 100644 index 0000000000..a7fb2599ce --- /dev/null +++ b/templates/CRM/Contribute/Form/Task/PDFLatex.tpl @@ -0,0 +1,48 @@ +{* + +--------------------------------------------------------------------+ + | CiviCRM version 4.4 | + +--------------------------------------------------------------------+ + | Copyright CiviCRM LLC (c) 2004-2013 | + +--------------------------------------------------------------------+ + | This file is a part of CiviCRM. | + | | + | CiviCRM is free software; you can copy, modify, and distribute it | + | under the terms of the GNU Affero General Public License | + | Version 3, 19 November 2007 and the CiviCRM Licensing Exception. | + | | + | CiviCRM is distributed in the hope that it will be useful, but | + | WITHOUT ANY WARRANTY; without even the implied warranty of | + | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | + | See the GNU Affero General Public License for more details. | + | | + | You should have received a copy of the GNU Affero General Public | + | License and the CiviCRM Licensing Exception along | + | with this program; if not, contact CiviCRM LLC | + | at info[AT]civicrm[DOT]org. If you have questions about the | + | GNU Affero General Public License or the licensing of CiviCRM, | + | see the CiviCRM license FAQ at http://civicrm.org/licensing | + +--------------------------------------------------------------------+ +*} +
+

{ts}Thank-you Letter In Latex for Contributions (PDF){/ts}

+{if $single eq false} +
{include file="CRM/Contribute/Form/Task.tpl"}
+{/if} + +
+
+ {$form.more_options_header.html} +
+
+ + + + +
{$form.thankyou_update.html} {$form.thankyou_update.label}
{$form.receipt_update.html} {$form.receipt_update.label}
+
+
+ +{include file="CRM/Contact/Form/Task/PDFLatexCommon.tpl"} + +
{include file="CRM/common/formButtons.tpl" location="bottom"}
+
diff --git a/tmp_table_myisam.patch b/tmp_table_myisam.patch new file mode 100644 index 0000000000..a531b5f2a1 --- /dev/null +++ b/tmp_table_myisam.patch @@ -0,0 +1,51 @@ +diff --git a/CRM/Contact/Form/Search/Custom/Group.php b/CRM/Contact/Form/Search/Custom/Group.php +index 999a733..b40d55f 100644 +--- a/CRM/Contact/Form/Search/Custom/Group.php ++++ b/CRM/Contact/Form/Search/Custom/Group.php +@@ -32,7 +32,9 @@ + * $Id$ + * + */ +-class CRM_Contact_Form_Search_Custom_Group extends CRM_Contact_Form_Search_Custom_Base implements CRM_Contact_Form_Search_Interface { ++class CRM_Contact_Form_Search_Custom_Group ++ extends CRM_Contact_Form_Search_Custom_Base ++ implements CRM_Contact_Form_Search_Interface { + + protected $_formValues; + +@@ -283,7 +285,7 @@ function from() { + $xGroups = 0; + } + +- $sql = "CREATE TEMPORARY TABLE Xg_{$this->_tableName} ( contact_id int primary key) ENGINE=HEAP"; ++ $sql = "CREATE TEMPORARY TABLE Xg_{$this->_tableName} ( contact_id int primary key) ENGINE=MyISAM"; + CRM_Core_DAO::executeQuery($sql); + + //used only when exclude group is selected +@@ -318,7 +320,7 @@ function from() { + + $sql = "CREATE TEMPORARY TABLE Ig_{$this->_tableName} ( id int PRIMARY KEY AUTO_INCREMENT, + contact_id int, +- group_names varchar(64)) ENGINE=HEAP"; ++ group_names varchar(64)) ENGINE=MyISAM"; + + CRM_Core_DAO::executeQuery($sql); + +@@ -418,7 +420,7 @@ function from() { + $xTags = 0; + } + +- $sql = "CREATE TEMPORARY TABLE Xt_{$this->_tableName} ( contact_id int primary key) ENGINE=HEAP"; ++ $sql = "CREATE TEMPORARY TABLE Xt_{$this->_tableName} ( contact_id int primary key) ENGINE=MyISAM"; + CRM_Core_DAO::executeQuery($sql); + + //used only when exclude tag is selected +@@ -436,7 +438,7 @@ function from() { + + $sql = "CREATE TEMPORARY TABLE It_{$this->_tableName} ( id int PRIMARY KEY AUTO_INCREMENT, + contact_id int, +- tag_names varchar(64)) ENGINE=HEAP"; ++ tag_names varchar(64)) ENGINE=MyISAM"; + + CRM_Core_DAO::executeQuery($sql); +