First commit

This commit is contained in:
Theodotos Andreou 2018-01-14 13:10:16 +00:00
commit c6e2478c40
13918 changed files with 2303184 additions and 0 deletions

View file

@ -0,0 +1,690 @@
<?php
/*
+--------------------------------------------------------------------+
| CiviCRM version 4.7 |
+--------------------------------------------------------------------+
| Copyright CiviCRM LLC (c) 2004-2017 |
+--------------------------------------------------------------------+
| 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 usefusul, 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 |
+--------------------------------------------------------------------+
*/
/**
*
* @package CRM
* @copyright CiviCRM LLC (c) 2004-2017
*/
/**
* This class generates form components for processing a contribution
* CRM-16229 - During the event registration bulk action via search we
* need to inherit CRM_Contact_Form_Task so that we can inherit functions
* like getContactIds and make use of controller state. But this is not possible
* because CRM_Event_Form_Participant inherits this class.
* Ideal situation would be something like
* CRM_Event_Form_Participant extends CRM_Contact_Form_Task,
* CRM_Contribute_Form_AbstractEditPayment
* However this is not possible. Currently PHP does not support multiple
* inheritance. So work around solution is to extend this class with
* CRM_Contact_Form_Task which further extends CRM_Core_Form.
*
*/
class CRM_Contribute_Form_AbstractEditPayment extends CRM_Contact_Form_Task {
public $_mode;
public $_action;
public $_bltID;
public $_fields = array();
/**
* @var array current payment processor including a copy of the object in 'object' key
*/
public $_paymentProcessor;
/**
* Available recurring processors.
*
* @var array
*/
public $_recurPaymentProcessors = array();
/**
* Array of processor options in the format id => array($id => $label)
* WARNING it appears that the format used to differ to this and there are places in the code that
* expect the old format. $this->_paymentProcessors provides the additional data which this
* array seems to have provided in the past
* @var array
*/
public $_processors;
/**
* Available payment processors with full details including the key 'object' indexed by their id
* @var array
*/
protected $_paymentProcessors = array();
/**
* Instance of the payment processor object.
*
* @var CRM_Core_Payment
*/
protected $_paymentObject;
/**
* The id of the contribution that we are processing.
*
* @var int
*/
public $_id;
/**
* The id of the premium that we are proceessing.
*
* @var int
*/
public $_premiumID = NULL;
/**
* @var CRM_Contribute_DAO_ContributionProduct
*/
public $_productDAO = NULL;
/**
* The id of the note
*
* @var int
*/
public $_noteID;
/**
* The id of the contact associated with this contribution
*
* @var int
*/
public $_contactID;
/**
* The id of the pledge payment that we are processing
*
* @var int
*/
public $_ppID;
/**
* The id of the pledge that we are processing
*
* @var int
*/
public $_pledgeID;
/**
* Is this contribution associated with an online
* financial transaction
*
* @var boolean
*/
public $_online = FALSE;
/**
* Stores all product option
*
* @var array
*/
public $_options;
/**
* Stores the honor id
*
* @var int
*/
public $_honorID = NULL;
/**
* Store the financial Type ID
*
* @var array
*/
public $_contributionType;
/**
* The contribution values if an existing contribution
*/
public $_values;
/**
* The pledge values if this contribution is associated with pledge
*/
public $_pledgeValues;
public $_contributeMode = 'direct';
public $_context;
public $_compId;
/**
* Store the line items if price set used.
*/
public $_lineItems;
/**
* Is this a backoffice form
*
* @var bool
*/
public $isBackOffice = TRUE;
protected $_formType;
/**
* Payment instrument id for the transaction.
*
* @var int
*/
public $paymentInstrumentID;
/**
* Array of fields to display on billingBlock.tpl - this is not fully implemented but basically intent is the panes/fieldsets on this page should
* be all in this array in order like
* 'credit_card' => array('credit_card_number' ...
* 'billing_details' => array('first_name' ...
*
* such that both the fields and the order can be more easily altered by payment processors & other extensions
* @var array
*/
public $billingFieldSets = array();
/**
* Pre process function with common actions.
*/
public function preProcess() {
$this->_contactID = CRM_Utils_Request::retrieve('cid', 'Positive', $this);
$this->assign('contactID', $this->_contactID);
CRM_Core_Resources::singleton()->addVars('coreForm', array('contact_id' => (int) $this->_contactID));
$this->_action = CRM_Utils_Request::retrieve('action', 'String', $this, FALSE, 'add');
$this->_mode = empty($this->_mode) ? CRM_Utils_Request::retrieve('mode', 'String', $this) : $this->_mode;
$this->assign('isBackOffice', $this->isBackOffice);
$this->assignPaymentRelatedVariables();
}
/**
* @param int $id
*/
public function showRecordLinkMesssage($id) {
$statusId = CRM_Core_DAO::getFieldValue('CRM_Contribute_BAO_Contribution', $id, 'contribution_status_id');
if (CRM_Contribute_PseudoConstant::contributionStatus($statusId, 'name') == 'Partially paid') {
if ($pid = CRM_Core_DAO::getFieldValue('CRM_Event_BAO_ParticipantPayment', $id, 'participant_id', 'contribution_id')) {
$recordPaymentLink = CRM_Utils_System::url('civicrm/payment',
"reset=1&id={$pid}&cid={$this->_contactID}&action=add&component=event"
);
CRM_Core_Session::setStatus(ts('Please use the <a href="%1">Record Payment</a> form if you have received an additional payment for this Partially paid contribution record.', array(1 => $recordPaymentLink)), ts('Notice'), 'alert');
}
}
}
/**
* @param int $id
* @param $values
*/
public function buildValuesAndAssignOnline_Note_Type($id, &$values) {
$ids = array();
$params = array('id' => $id);
CRM_Contribute_BAO_Contribution::getValues($params, $values, $ids);
//Check if this is an online transaction (financial_trxn.payment_processor_id NOT NULL)
$this->_online = FALSE;
$fids = CRM_Core_BAO_FinancialTrxn::getFinancialTrxnId($id);
if (!empty($fids['financialTrxnId'])) {
$this->_online = CRM_Core_DAO::getFieldValue('CRM_Financial_DAO_FinancialTrxn', $fids['financialTrxnId'], 'payment_processor_id');
}
// Also don't allow user to update some fields for recurring contributions.
if (!$this->_online) {
$this->_online = CRM_Utils_Array::value('contribution_recur_id', $values);
}
$this->assign('isOnline', $this->_online ? TRUE : FALSE);
//to get note id
$daoNote = new CRM_Core_BAO_Note();
$daoNote->entity_table = 'civicrm_contribution';
$daoNote->entity_id = $id;
if ($daoNote->find(TRUE)) {
$this->_noteID = $daoNote->id;
$values['note'] = $daoNote->note;
}
$this->_contributionType = $values['financial_type_id'];
}
/**
* @param string $type
* Eg 'Contribution'.
* @param string $subType
* @param int $entityId
*/
public function applyCustomData($type, $subType, $entityId) {
$this->set('type', $type);
$this->set('subType', $subType);
$this->set('entityId', $entityId);
CRM_Custom_Form_CustomData::preProcess($this, NULL, $subType, 1, $type, $entityId);
CRM_Custom_Form_CustomData::buildQuickForm($this);
CRM_Custom_Form_CustomData::setDefaultValues($this);
}
/**
* @param int $id
* @todo - this function is a long way, non standard of saying $dao = new CRM_Contribute_DAO_ContributionProduct(); $dao->id = $id; $dao->find();
*/
public function assignPremiumProduct($id) {
$sql = "
SELECT *
FROM civicrm_contribution_product
WHERE contribution_id = {$id}
";
$dao = CRM_Core_DAO::executeQuery($sql,
CRM_Core_DAO::$_nullArray
);
if ($dao->fetch()) {
$this->_premiumID = $dao->id;
$this->_productDAO = $dao;
}
$dao->free();
}
/**
* @return array
* Array of valid processors. The array resembles the DB table but also has 'object' as a key
* @throws Exception
*/
public function getValidProcessors() {
$capabilities = array('BackOffice');
if ($this->_mode) {
$capabilities[] = (ucfirst($this->_mode) . 'Mode');
}
$processors = CRM_Financial_BAO_PaymentProcessor::getPaymentProcessors($capabilities);
return $processors;
}
/**
* Assign $this->processors, $this->recurPaymentProcessors, and related Smarty variables
*/
public function assignProcessors() {
//ensure that processor has a valid config
//only valid processors get display to user
$this->assign('processorSupportsFutureStartDate', CRM_Financial_BAO_PaymentProcessor::hasPaymentProcessorSupporting(array('FutureRecurStartDate')));
$this->_paymentProcessors = $this->getValidProcessors();
if (!isset($this->_paymentProcessor['id'])) {
// if the payment processor isn't set yet (as indicated by the presence of an id,) we'll grab the first one which should be the default
$this->_paymentProcessor = reset($this->_paymentProcessors);
}
if (!$this->_mode) {
$this->_paymentProcessor = $this->_paymentProcessors[0];
}
elseif (empty($this->_paymentProcessors) || array_keys($this->_paymentProcessors) === array(0)) {
throw new CRM_Core_Exception(ts('You will need to configure the %1 settings for your Payment Processor before you can submit a credit card transactions.', array(1 => $this->_mode)));
}
$this->_processors = array();
foreach ($this->_paymentProcessors as $id => $processor) {
// @todo review this. The inclusion of this IF was to address test processors being incorrectly loaded.
// However the function $this->getValidProcessors() is expected to only return the processors relevant
// to the mode (using the actual id - ie. the id of the test processor for the test processor).
// for some reason there was a need to filter here per commit history - but this indicates a problem
// somewhere else.
if ($processor['is_test'] == ($this->_mode == 'test')) {
$this->_processors[$id] = ts($processor['name']);
if (!empty($processor['description'])) {
$this->_processors[$id] .= ' : ' . ts($processor['description']);
}
if ($processor['is_recur']) {
$this->_recurPaymentProcessors[$id] = $this->_processors[$id];
}
}
}
// CRM-21002: pass the default payment processor ID whose credit card type icons should be populated first
CRM_Financial_Form_Payment::addCreditCardJs($this->_paymentProcessor['id']);
$this->assign('recurringPaymentProcessorIds',
empty($this->_recurPaymentProcessors) ? '' : implode(',', array_keys($this->_recurPaymentProcessors))
);
// this required to show billing block
// @todo remove this assignment the billing block is now designed to be always included but will not show fieldsets unless those sets of fields are assigned
$this->assign_by_ref('paymentProcessor', $this->_paymentProcessor);
}
/**
* Get current currency from DB or use default currency.
*
* @param $submittedValues
*
* @return mixed
*/
public function getCurrency($submittedValues) {
$config = CRM_Core_Config::singleton();
$currentCurrency = CRM_Utils_Array::value('currency',
$this->_values,
$config->defaultCurrency
);
// use submitted currency if present else use current currency
$result = CRM_Utils_Array::value('currency',
$submittedValues,
$currentCurrency
);
return $result;
}
public function preProcessPledge() {
//get the payment values associated with given pledge payment id OR check for payments due.
$this->_pledgeValues = array();
if ($this->_ppID) {
$payParams = array('id' => $this->_ppID);
CRM_Pledge_BAO_PledgePayment::retrieve($payParams, $this->_pledgeValues['pledgePayment']);
$this->_pledgeID = CRM_Utils_Array::value('pledge_id', $this->_pledgeValues['pledgePayment']);
$paymentStatusID = CRM_Utils_Array::value('status_id', $this->_pledgeValues['pledgePayment']);
$this->_id = CRM_Utils_Array::value('contribution_id', $this->_pledgeValues['pledgePayment']);
//get all status
$allStatus = CRM_Contribute_PseudoConstant::contributionStatus(NULL, 'name');
if (!($paymentStatusID == array_search('Pending', $allStatus) || $paymentStatusID == array_search('Overdue', $allStatus))) {
CRM_Core_Error::fatal(ts("Pledge payment status should be 'Pending' or 'Overdue'."));
}
//get the pledge values associated with given pledge payment.
$ids = array();
$pledgeParams = array('id' => $this->_pledgeID);
CRM_Pledge_BAO_Pledge::getValues($pledgeParams, $this->_pledgeValues, $ids);
$this->assign('ppID', $this->_ppID);
}
else {
// Not making a pledge payment, so if adding a new contribution we should check if pledge payment(s) are due for this contact so we can alert the user. CRM-5206
if (isset($this->_contactID)) {
$contactPledges = CRM_Pledge_BAO_Pledge::getContactPledges($this->_contactID);
if (!empty($contactPledges)) {
$payments = $paymentsDue = NULL;
$multipleDue = FALSE;
foreach ($contactPledges as $key => $pledgeId) {
$payments = CRM_Pledge_BAO_PledgePayment::getOldestPledgePayment($pledgeId);
if ($payments) {
if ($paymentsDue) {
$multipleDue = TRUE;
break;
}
else {
$paymentsDue = $payments;
}
}
}
if ($multipleDue) {
// Show link to pledge tab since more than one pledge has a payment due
$pledgeTab = CRM_Utils_System::url('civicrm/contact/view',
"reset=1&force=1&cid={$this->_contactID}&selectedChild=pledge"
);
CRM_Core_Session::setStatus(ts('This contact has pending or overdue pledge payments. <a href="%1">Click here to view their Pledges tab</a> and verify whether this contribution should be applied as a pledge payment.', array(1 => $pledgeTab)), ts('Notice'), 'alert');
}
elseif ($paymentsDue) {
// Show user link to oldest Pending or Overdue pledge payment
$ppAmountDue = CRM_Utils_Money::format($payments['amount'], $payments['currency']);
$ppSchedDate = CRM_Utils_Date::customFormat(CRM_Core_DAO::getFieldValue('CRM_Pledge_DAO_PledgePayment', $payments['id'], 'scheduled_date'));
if ($this->_mode) {
$ppUrl = CRM_Utils_System::url('civicrm/contact/view/contribution',
"reset=1&action=add&cid={$this->_contactID}&ppid={$payments['id']}&context=pledge&mode=live"
);
}
else {
$ppUrl = CRM_Utils_System::url('civicrm/contact/view/contribution',
"reset=1&action=add&cid={$this->_contactID}&ppid={$payments['id']}&context=pledge"
);
}
CRM_Core_Session::setStatus(ts('This contact has a pending or overdue pledge payment of %2 which is scheduled for %3. <a href="%1">Click here to enter a pledge payment</a>.', array(
1 => $ppUrl,
2 => $ppAmountDue,
3 => $ppSchedDate,
)), ts('Notice'), 'alert');
}
}
}
}
}
/**
* @param array $submittedValues
*
* @return mixed
*/
public function unsetCreditCardFields($submittedValues) {
//Offline Contribution.
$unsetParams = array(
'payment_processor_id',
"email-{$this->_bltID}",
'hidden_buildCreditCard',
'hidden_buildDirectDebit',
'billing_first_name',
'billing_middle_name',
'billing_last_name',
'street_address-5',
"city-{$this->_bltID}",
"state_province_id-{$this->_bltID}",
"postal_code-{$this->_bltID}",
"country_id-{$this->_bltID}",
'credit_card_number',
'cvv2',
'credit_card_exp_date',
'credit_card_type',
);
foreach ($unsetParams as $key) {
if (isset($submittedValues[$key])) {
unset($submittedValues[$key]);
}
}
return $submittedValues;
}
/**
* Common block for setting up the parts of a form that relate to credit / debit card
* @throws Exception
*/
protected function assignPaymentRelatedVariables() {
try {
if ($this->_contactID) {
list($this->userDisplayName, $this->userEmail) = CRM_Contact_BAO_Contact_Location::getEmailDetails($this->_contactID);
$this->assign('displayName', $this->userDisplayName);
}
$this->assignProcessors();
$this->assignBillingType();
CRM_Core_Payment_Form::setPaymentFieldsByProcessor($this, $this->_paymentProcessor, FALSE, TRUE, CRM_Utils_Request::retrieve('payment_instrument_id', 'Integer', $this));
}
catch (CRM_Core_Exception $e) {
CRM_Core_Error::statusBounce($e->getMessage());
}
}
/**
* Begin post processing.
*
* This function aims to start to bring together common postProcessing functions.
*
* Eventually these are also shared with the front end forms & may need to be moved to where they can also
* access this function.
*/
protected function beginPostProcess() {
if ($this->_mode) {
$this->_paymentProcessor = CRM_Financial_BAO_PaymentProcessor::getPayment(
$this->_params['payment_processor_id'],
($this->_mode == 'test')
);
if (in_array('credit_card_exp_date', array_keys($this->_params))) {
$this->_params['year'] = CRM_Core_Payment_Form::getCreditCardExpirationYear($this->_params);
$this->_params['month'] = CRM_Core_Payment_Form::getCreditCardExpirationMonth($this->_params);
}
$this->assign('credit_card_exp_date', CRM_Utils_Date::mysqlToIso(CRM_Utils_Date::format($this->_params['credit_card_exp_date'])));
$this->assign('credit_card_number',
CRM_Utils_System::mungeCreditCard($this->_params['credit_card_number'])
);
$this->assign('credit_card_type', CRM_Utils_Array::value('credit_card_type', $this->_params));
}
$this->_params['ip_address'] = CRM_Utils_System::ipAddress();
self::formatCreditCardDetails($this->_params);
}
/**
* Format credit card details like:
* 1. Retrieve last 4 digit from credit card number as pan_truncation
* 2. Retrieve credit card type id from name
*
* @param array $params
*
* @return void
*/
public static function formatCreditCardDetails(&$params) {
if (in_array('credit_card_type', array_keys($params))) {
$params['card_type_id'] = CRM_Core_PseudoConstant::getKey('CRM_Core_BAO_FinancialTrxn', 'card_type_id', $params['credit_card_type']);
}
if (!empty($params['credit_card_number']) && empty($params['pan_truncation'])) {
$params['pan_truncation'] = substr($params['credit_card_number'], -4);
}
}
/**
* Add the billing address to the contact who paid.
*
* Note that this function works based on the presence or otherwise of billing fields & can be called regardless of
* whether they are 'expected' (due to assumptions about the payment processor type or the setting to collect billing
* for pay later.
*/
protected function processBillingAddress() {
$fields = array();
$fields['email-Primary'] = 1;
$this->_params['email-5'] = $this->_params['email-Primary'] = $this->_contributorEmail;
// now set the values for the billing location.
foreach (array_keys($this->_fields) as $name) {
$fields[$name] = 1;
}
$fields["address_name-{$this->_bltID}"] = 1;
//ensure we don't over-write the payer's email with the member's email
if ($this->_contributorContactID == $this->_contactID) {
$fields["email-{$this->_bltID}"] = 1;
}
list($hasBillingField, $addressParams) = CRM_Contribute_BAO_Contribution::getPaymentProcessorReadyAddressParams($this->_params, $this->_bltID);
$fields = $this->formatParamsForPaymentProcessor($fields);
if ($hasBillingField) {
$addressParams = array_merge($this->_params, $addressParams);
// CRM-18277 don't let this get passed in because we don't want contribution source to override contact source.
// Ideally we wouldn't just randomly merge everything into addressParams but just pass in a relevant array.
// Note this source field is covered by a unit test.
if (isset($addressParams['source'])) {
unset($addressParams['source']);
}
//here we are setting up the billing contact - if different from the member they are already created
// but they will get billing details assigned
CRM_Contact_BAO_Contact::createProfileContact($addressParams, $fields,
$this->_contributorContactID, NULL, NULL,
CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Contact', $this->_contactID, 'contact_type')
);
}
$this->assignBillingName($this->_params);
}
/**
* Get default values for billing fields.
*
* @todo this function still replicates code in several other places in the code.
*
* Also - the call to getProfileDefaults possibly covers the state_province & country already.
*
* @param $defaults
*
* @return array
*/
protected function getBillingDefaults($defaults) {
// set default country from config if no country set
$config = CRM_Core_Config::singleton();
if (empty($defaults["billing_country_id-{$this->_bltID}"])) {
$defaults["billing_country_id-{$this->_bltID}"] = $config->defaultContactCountry;
}
if (empty($defaults["billing_state_province_id-{$this->_bltID}"])) {
$defaults["billing_state_province_id-{$this->_bltID}"] = $config->defaultContactStateProvince;
}
$billingDefaults = $this->getProfileDefaults('Billing', $this->_contactID);
return array_merge($defaults, $billingDefaults);
}
/**
* Get the default payment instrument id.
*
* @return int
*/
protected function getDefaultPaymentInstrumentId() {
$paymentInstrumentID = CRM_Utils_Request::retrieve('payment_instrument_id', 'Integer');
if ($paymentInstrumentID) {
return $paymentInstrumentID;
}
return key(CRM_Core_OptionGroup::values('payment_instrument', FALSE, FALSE, FALSE, 'AND is_default = 1'));
}
/**
* Add the payment processor select to the form.
*
* @param bool $isRequired
* Is it a mandatory field.
* @param bool $isBuildRecurBlock
* True if we want to build recur on change
* @param bool $isBuildAutoRenewBlock
* True if we want to build autorenew on change.
*/
protected function addPaymentProcessorSelect($isRequired, $isBuildRecurBlock = FALSE, $isBuildAutoRenewBlock = FALSE) {
if (!$this->_mode) {
return;
}
$js = ($isBuildRecurBlock ? array('onChange' => "buildRecurBlock( this.value ); return false;") : NULL);
if ($isBuildAutoRenewBlock) {
$js = array('onChange' => "buildAutoRenew( null, this.value, '{$this->_mode}');");
}
$element = $this->add('select',
'payment_processor_id',
ts('Payment Processor'),
array_diff_key($this->_processors, array(0 => 1)),
$isRequired,
$js
);
// The concept of _online is not really explained & the code is old
// @todo figure out & document.
if ($this->_online) {
$element->freeze();
}
}
}

View file

@ -0,0 +1,488 @@
<?php
/*
+--------------------------------------------------------------------+
| CiviCRM version 4.7 |
+--------------------------------------------------------------------+
| Copyright CiviCRM LLC (c) 2004-2017 |
+--------------------------------------------------------------------+
| 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 |
+--------------------------------------------------------------------+
*/
/**
*
* @package CRM
* @copyright CiviCRM LLC (c) 2004-2017
*/
class CRM_Contribute_Form_AdditionalInfo {
/**
* Build the form object for Premium Information.
*
* Called from the CRM_Contribute_Form_Contribute function and seemingly nowhere else.
*
* Probably this should be on the form that uses it since it is not used on multiple forms.
*
* Putting it on this class doesn't seem to reduce complexity.
*
* @param CRM_Core_Form $form
*/
public static function buildPremium(&$form) {
//premium section
$form->add('hidden', 'hidden_Premium', 1);
$sel1 = $sel2 = array();
$dao = new CRM_Contribute_DAO_Product();
$dao->is_active = 1;
$dao->find();
$min_amount = array();
$sel1[0] = ts('-select product-');
while ($dao->fetch()) {
$sel1[$dao->id] = $dao->name . " ( " . $dao->sku . " )";
$min_amount[$dao->id] = $dao->min_contribution;
$options = explode(',', $dao->options);
foreach ($options as $k => $v) {
$options[$k] = trim($v);
}
if ($options[0] != '') {
$sel2[$dao->id] = $options;
}
$form->assign('premiums', TRUE);
}
$form->_options = $sel2;
$form->assign('mincontribution', $min_amount);
$sel = &$form->addElement('hierselect', "product_name", ts('Premium'), 'onclick="showMinContrib();"');
$js = "<script type='text/javascript'>\n";
$formName = 'document.forms.' . $form->getName();
for ($k = 1; $k < 2; $k++) {
if (!isset($defaults['product_name'][$k]) || (!$defaults['product_name'][$k])) {
$js .= "{$formName}['product_name[$k]'].style.display = 'none';\n";
}
}
$sel->setOptions(array($sel1, $sel2));
$js .= "</script>\n";
$form->assign('initHideBoxes', $js);
$form->addDate('fulfilled_date', ts('Fulfilled'), FALSE, array('formatType' => 'activityDate'));
$form->addElement('text', 'min_amount', ts('Minimum Contribution Amount'));
}
/**
* Build the form object for Additional Details.
*
* @param CRM_Core_Form $form
*/
public static function buildAdditionalDetail(&$form) {
//Additional information section
$form->add('hidden', 'hidden_AdditionalDetail', 1);
$attributes = CRM_Core_DAO::getAttribute('CRM_Contribute_DAO_Contribution');
$form->addDateTime('thankyou_date', ts('Thank-you Sent'), FALSE, array('formatType' => 'activityDateTime'));
// add various amounts
$nonDeductAmount = &$form->add('text', 'non_deductible_amount', ts('Non-deductible Amount'),
$attributes['non_deductible_amount']
);
$form->addRule('non_deductible_amount', ts('Please enter a valid monetary value for Non-deductible Amount.'), 'money');
if ($form->_online) {
$nonDeductAmount->freeze();
}
$feeAmount = &$form->add('text', 'fee_amount', ts('Fee Amount'),
$attributes['fee_amount']
);
$form->addRule('fee_amount', ts('Please enter a valid monetary value for Fee Amount.'), 'money');
if ($form->_online) {
$feeAmount->freeze();
}
$netAmount = &$form->add('text', 'net_amount', ts('Net Amount'),
$attributes['net_amount']
);
$form->addRule('net_amount', ts('Please enter a valid monetary value for Net Amount.'), 'money');
if ($form->_online) {
$netAmount->freeze();
}
$element = &$form->add('text', 'invoice_id', ts('Invoice ID'),
$attributes['invoice_id']
);
if ($form->_online) {
$element->freeze();
}
else {
$form->addRule('invoice_id',
ts('This Invoice ID already exists in the database.'),
'objectExists',
array('CRM_Contribute_DAO_Contribution', $form->_id, 'invoice_id')
);
}
$element = $form->add('text', 'creditnote_id', ts('Credit Note ID'),
$attributes['creditnote_id']
);
if ($form->_online) {
$element->freeze();
}
else {
$form->addRule('creditnote_id',
ts('This Credit Note ID already exists in the database.'),
'objectExists',
array('CRM_Contribute_DAO_Contribution', $form->_id, 'creditnote_id')
);
}
$form->add('select', 'contribution_page_id',
ts('Online Contribution Page'),
array(
'' => ts('- select -'),
) +
CRM_Contribute_PseudoConstant::contributionPage()
);
$form->add('textarea', 'note', ts('Notes'), array("rows" => 4, "cols" => 60));
$statusName = CRM_Contribute_PseudoConstant::contributionStatus(NULL, 'name');
if ($form->_id && $form->_values['contribution_status_id'] == array_search('Cancelled', $statusName)) {
$netAmount->freeze();
$feeAmount->freeze();
}
}
/**
* used by CRM/Pledge/Form/Pledge.php
*
* Build the form object for PaymentReminders Information.
*
* @param CRM_Core_Form $form
*/
public static function buildPaymentReminders(&$form) {
//PaymentReminders section
$form->add('hidden', 'hidden_PaymentReminders', 1);
$form->add('text', 'initial_reminder_day', ts('Send Initial Reminder'), array('size' => 3));
$form->addRule('initial_reminder_day', ts('Please enter a valid reminder day.'), 'positiveInteger');
$form->add('text', 'max_reminders', ts('Send up to'), array('size' => 3));
$form->addRule('max_reminders', ts('Please enter a valid No. of reminders.'), 'positiveInteger');
$form->add('text', 'additional_reminder_day', ts('Send additional reminders'), array('size' => 3));
$form->addRule('additional_reminder_day', ts('Please enter a valid additional reminder day.'), 'positiveInteger');
}
/**
* Process the Premium Information.
*
* @param array $params
* @param int $contributionID
* @param int $premiumID
* @param array $options
*/
public static function processPremium($params, $contributionID, $premiumID = NULL, $options = array()) {
$selectedProductID = $params['product_name'][0];
$selectedProductOptionID = CRM_Utils_Array::value(1, $params['product_name']);
$dao = new CRM_Contribute_DAO_ContributionProduct();
$dao->contribution_id = $contributionID;
$dao->product_id = $selectedProductID;
$dao->fulfilled_date = CRM_Utils_Date::processDate($params['fulfilled_date'], NULL, TRUE);
$isDeleted = FALSE;
//CRM-11106
$premiumParams = array(
'id' => $selectedProductID,
);
$productDetails = array();
CRM_Contribute_BAO_ManagePremiums::retrieve($premiumParams, $productDetails);
$dao->financial_type_id = CRM_Utils_Array::value('financial_type_id', $productDetails);
if (!empty($options[$selectedProductID])) {
$dao->product_option = $options[$selectedProductID][$selectedProductOptionID];
}
if ($premiumID) {
$ContributionProduct = new CRM_Contribute_DAO_ContributionProduct();
$ContributionProduct->id = $premiumID;
$ContributionProduct->find(TRUE);
if ($ContributionProduct->product_id == $selectedProductID) {
$dao->id = $premiumID;
}
else {
$ContributionProduct->delete();
$isDeleted = TRUE;
}
}
$dao->save();
//CRM-11106
if ($premiumID == NULL || $isDeleted) {
$premiumParams = array(
'cost' => CRM_Utils_Array::value('cost', $productDetails),
'currency' => CRM_Utils_Array::value('currency', $productDetails),
'financial_type_id' => CRM_Utils_Array::value('financial_type_id', $productDetails),
'contributionId' => $contributionID,
);
if ($isDeleted) {
$premiumParams['oldPremium']['product_id'] = $ContributionProduct->product_id;
$premiumParams['oldPremium']['contribution_id'] = $ContributionProduct->contribution_id;
}
CRM_Core_BAO_FinancialTrxn::createPremiumTrxn($premiumParams);
}
}
/**
* Process the Note.
*
*
* @param array $params
* @param int $contactID
* @param int $contributionID
* @param int $contributionNoteID
*/
public static function processNote($params, $contactID, $contributionID, $contributionNoteID = NULL) {
//process note
$noteParams = array(
'entity_table' => 'civicrm_contribution',
'note' => $params['note'],
'entity_id' => $contributionID,
'contact_id' => $contactID,
);
$noteID = array();
if ($contributionNoteID) {
$noteID = array("id" => $contributionNoteID);
$noteParams['note'] = $noteParams['note'] ? $noteParams['note'] : "null";
}
CRM_Core_BAO_Note::add($noteParams, $noteID);
}
/**
* Process the Common data.
*
* @param array $params
* @param array $formatted
* @param CRM_Core_Form $form
*/
public static function postProcessCommon(&$params, &$formatted, &$form) {
$fields = array(
'non_deductible_amount',
'total_amount',
'fee_amount',
'net_amount',
'trxn_id',
'invoice_id',
'creditnote_id',
'campaign_id',
'contribution_page_id',
);
foreach ($fields as $f) {
$formatted[$f] = CRM_Utils_Array::value($f, $params);
}
if (!empty($params['thankyou_date']) && !CRM_Utils_System::isNull($params['thankyou_date'])) {
$formatted['thankyou_date'] = CRM_Utils_Date::processDate($params['thankyou_date'], $params['thankyou_date_time']);
}
else {
$formatted['thankyou_date'] = 'null';
}
if (!empty($params['is_email_receipt'])) {
$params['receipt_date'] = $formatted['receipt_date'] = date('YmdHis');
}
//special case to handle if all checkboxes are unchecked
$customFields = CRM_Core_BAO_CustomField::getFields('Contribution',
FALSE,
FALSE,
CRM_Utils_Array::value('financial_type_id',
$params
)
);
$formatted['custom'] = CRM_Core_BAO_CustomField::postProcess($params,
CRM_Utils_Array::value('id', $params, NULL),
'Contribution'
);
}
/**
* Send email receipt.
*
* @param CRM_Core_Form $form
* instance of Contribution form.
* @param array $params
* (reference ) an assoc array of name/value pairs.
* @param bool $ccContribution
* is it credit card contribution.
*
* @return array
*/
public static function emailReceipt(&$form, &$params, $ccContribution = FALSE) {
$form->assign('receiptType', 'contribution');
// Retrieve Financial Type Name from financial_type_id
$params['contributionType_name'] = CRM_Core_DAO::getFieldValue('CRM_Financial_DAO_FinancialType',
$params['financial_type_id']);
if (!empty($params['payment_instrument_id'])) {
$paymentInstrument = CRM_Contribute_PseudoConstant::paymentInstrument();
$params['paidBy'] = $paymentInstrument[$params['payment_instrument_id']];
if ($params['paidBy'] != 'Check' && isset($params['check_number'])) {
unset($params['check_number']);
}
}
// retrieve individual prefix value for honoree
if (isset($params['soft_credit'])) {
$softCreditTypes = $softCredits = array();
foreach ($params['soft_credit'] as $key => $softCredit) {
$softCredits[$key] = array(
'Name' => $softCredit['contact_name'],
'Amount' => CRM_Utils_Money::format($softCredit['amount'], $softCredit['currency']),
);
$softCreditTypes[$key] = $softCredit['soft_credit_type_label'];
}
$form->assign('softCreditTypes', $softCreditTypes);
$form->assign('softCredits', $softCredits);
}
// retrieve premium product name and assigned fulfilled
// date to template
if (!empty($params['hidden_Premium'])) {
if (isset($params['product_name']) &&
is_array($params['product_name']) &&
!empty($params['product_name'])
) {
$productDAO = new CRM_Contribute_DAO_Product();
$productDAO->id = $params['product_name'][0];
$productOptionID = $params['product_name'][1];
$productDAO->find(TRUE);
$params['product_name'] = $productDAO->name;
$params['product_sku'] = $productDAO->sku;
if (empty($params['product_option']) && !empty($form->_options[$productDAO->id])) {
$params['product_option'] = $form->_options[$productDAO->id][$productOptionID];
}
}
if (!empty($params['fulfilled_date'])) {
$form->assign('fulfilled_date', CRM_Utils_Date::processDate($params['fulfilled_date']));
}
}
$form->assign('ccContribution', $ccContribution);
if ($ccContribution) {
$form->assignBillingName($params);
$form->assign('address', CRM_Utils_Address::getFormattedBillingAddressFieldsFromParameters(
$params,
$form->_bltID
));
$date = CRM_Utils_Date::format($params['credit_card_exp_date']);
$date = CRM_Utils_Date::mysqlToIso($date);
$form->assign('credit_card_type', CRM_Utils_Array::value('credit_card_type', $params));
$form->assign('credit_card_exp_date', $date);
$form->assign('credit_card_number',
CRM_Utils_System::mungeCreditCard($params['credit_card_number'])
);
}
else {
//offline contribution
// assigned various dates to the templates
$form->assign('receipt_date', CRM_Utils_Date::processDate($params['receipt_date']));
if (!empty($params['cancel_date'])) {
$form->assign('cancel_date', CRM_Utils_Date::processDate($params['cancel_date']));
}
if (!empty($params['thankyou_date'])) {
$form->assign('thankyou_date', CRM_Utils_Date::processDate($params['thankyou_date']));
}
if ($form->_action & CRM_Core_Action::UPDATE) {
$form->assign('lineItem', empty($form->_lineItems) ? FALSE : $form->_lineItems);
}
}
//handle custom data
if (!empty($params['hidden_custom'])) {
$contribParams = array(array('contribution_id', '=', $params['contribution_id'], 0, 0));
if ($form->_mode == 'test') {
$contribParams[] = array('contribution_test', '=', 1, 0, 0);
}
//retrieve custom data
$customGroup = array();
foreach ($form->_groupTree as $groupID => $group) {
$customFields = $customValues = array();
if ($groupID == 'info') {
continue;
}
foreach ($group['fields'] as $k => $field) {
$field['title'] = $field['label'];
$customFields["custom_{$k}"] = $field;
}
//build the array of customgroup contain customfields.
CRM_Core_BAO_UFGroup::getValues($params['contact_id'], $customFields, $customValues, FALSE, $contribParams);
$customGroup[$group['title']] = $customValues;
}
//assign all custom group and corresponding fields to template.
$form->assign('customGroup', $customGroup);
}
$form->assign_by_ref('formValues', $params);
list($contributorDisplayName,
$contributorEmail
) = CRM_Contact_BAO_Contact_Location::getEmailDetails($params['contact_id']);
$form->assign('contactID', $params['contact_id']);
$form->assign('contributionID', $params['contribution_id']);
if (!empty($params['currency'])) {
$form->assign('currency', $params['currency']);
}
if (!empty($params['receive_date'])) {
$form->assign('receive_date', CRM_Utils_Date::processDate($params['receive_date']));
}
$template = CRM_Core_Smarty::singleton();
$taxAmt = $template->get_template_vars('dataArray');
$eventTaxAmt = $template->get_template_vars('totalTaxAmount');
$prefixValue = Civi::settings()->get('contribution_invoice_settings');
$invoicing = CRM_Utils_Array::value('invoicing', $prefixValue);
if ((!empty($taxAmt) || isset($eventTaxAmt)) && (isset($invoicing) && isset($prefixValue['is_email_pdf']))) {
$isEmailPdf = TRUE;
}
else {
$isEmailPdf = FALSE;
}
list($sendReceipt, $subject, $message, $html) = CRM_Core_BAO_MessageTemplate::sendTemplate(
array(
'groupName' => 'msg_tpl_workflow_contribution',
'valueName' => 'contribution_offline_receipt',
'contactId' => $params['contact_id'],
'contributionId' => $params['contribution_id'],
'from' => $params['from_email_address'],
'toName' => $contributorDisplayName,
'toEmail' => $contributorEmail,
'isTest' => $form->_mode == 'test',
'PDFFilename' => ts('receipt') . '.pdf',
'isEmailPdf' => $isEmailPdf,
)
);
return $sendReceipt;
}
}

View file

@ -0,0 +1,649 @@
<?php
/*
+--------------------------------------------------------------------+
| CiviCRM version 4.7 |
+--------------------------------------------------------------------+
| Copyright CiviCRM LLC (c) 2004-2017 |
+--------------------------------------------------------------------+
| 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 |
+--------------------------------------------------------------------+
*/
/**
*
* @package CRM
* @copyright CiviCRM LLC (c) 2004-2017
*/
/**
* This form records additional payments needed when event/contribution is partially paid.
*/
class CRM_Contribute_Form_AdditionalPayment extends CRM_Contribute_Form_AbstractEditPayment {
public $_contributeMode = 'direct';
/**
* Related component whose financial payment is being processed.
*
* @var string
*/
protected $_component = NULL;
/**
* Id of the component entity
*/
public $_id = NULL;
protected $_owed = NULL;
protected $_refund = NULL;
/**
* @deprecated - use parent $this->contactID
*
* @var int
*/
protected $_contactId = NULL;
protected $_contributorDisplayName = NULL;
protected $_contributorEmail = NULL;
protected $_toDoNotEmail = NULL;
protected $_paymentType = NULL;
protected $_contributionId = NULL;
protected $fromEmailId = NULL;
protected $_fromEmails = NULL;
protected $_view = NULL;
public $_action = NULL;
public function preProcess() {
parent::preProcess();
$this->_id = CRM_Utils_Request::retrieve('id', 'Positive', $this, TRUE);
// @todo don't set this - rely on parent $this->contactID
$this->_contactId = CRM_Utils_Request::retrieve('cid', 'Positive', $this, TRUE);
$this->_component = CRM_Utils_Request::retrieve('component', 'String', $this, TRUE);
$this->_view = CRM_Utils_Request::retrieve('view', 'String', $this, FALSE);
$this->assign('component', $this->_component);
$this->assign('id', $this->_id);
$this->assign('suppressPaymentFormButtons', $this->isBeingCalledFromSelectorContext());
if ($this->_view == 'transaction' && ($this->_action & CRM_Core_Action::BROWSE)) {
$paymentInfo = CRM_Contribute_BAO_Contribution::getPaymentInfo($this->_id, $this->_component, TRUE);
$title = ts('View Payment');
if ($this->_component == 'event') {
$info = CRM_Event_BAO_Participant::participantDetails($this->_id);
$title .= " - {$info['title']}";
}
CRM_Utils_System::setTitle($title);
$this->assign('transaction', TRUE);
$this->assign('payments', $paymentInfo['transaction']);
return;
}
$this->_fromEmails = CRM_Core_BAO_Email::getFromEmail();
$entityType = 'contribution';
if ($this->_component == 'event') {
$entityType = 'participant';
$this->_contributionId = CRM_Core_DAO::getFieldValue('CRM_Event_DAO_ParticipantPayment', $this->_id, 'contribution_id', 'participant_id');
$eventId = CRM_Core_DAO::getFieldValue('CRM_Event_DAO_Participant', $this->_id, 'event_id', 'id');
$this->_fromEmails = CRM_Event_BAO_Event::getFromEmailIds($eventId);
}
else {
$this->_contributionId = $this->_id;
$this->_fromEmails['from_email_id'] = CRM_Core_BAO_Email::getFromEmail();
}
$paymentInfo = CRM_Core_BAO_FinancialTrxn::getPartialPaymentWithType($this->_id, $entityType);
$paymentDetails = CRM_Contribute_BAO_Contribution::getPaymentInfo($this->_id, $this->_component, FALSE, TRUE);
$this->_amtPaid = $paymentDetails['paid'];
$this->_amtTotal = $paymentDetails['total'];
if (!empty($paymentInfo['refund_due'])) {
$paymentAmt = $this->_refund = $paymentInfo['refund_due'];
$this->_paymentType = 'refund';
}
elseif (!empty($paymentInfo['amount_owed'])) {
$paymentAmt = $this->_owed = $paymentInfo['amount_owed'];
$this->_paymentType = 'owed';
}
else {
CRM_Core_Error::fatal(ts('No payment information found for this record'));
}
if (!empty($this->_mode) && $this->_paymentType == 'refund') {
CRM_Core_Error::fatal(ts('Credit card payment is not for Refund payments use'));
}
list($this->_contributorDisplayName, $this->_contributorEmail) = CRM_Contact_BAO_Contact_Location::getEmailDetails($this->_contactId);
$this->assign('contributionMode', $this->_mode);
$this->assign('contactId', $this->_contactId);
$this->assign('paymentType', $this->_paymentType);
$this->assign('paymentAmt', abs($paymentAmt));
$this->setPageTitle($this->_refund ? ts('Refund') : ts('Payment'));
}
/**
* Is this function being called from a datatable selector.
*
* If so we don't want to show the buttons.
*/
protected function isBeingCalledFromSelectorContext() {
return CRM_Utils_Request::retrieve('selector', 'Positive');
}
/**
* This virtual function is used to set the default values of
* various form elements
*
* access public
*
* @return array
* reference to the array of default values
*/
/**
* @return array
*/
public function setDefaultValues() {
if ($this->_view == 'transaction' && ($this->_action & CRM_Core_Action::BROWSE)) {
return NULL;
}
$defaults = array();
if ($this->_mode) {
CRM_Core_Payment_Form::setDefaultValues($this, $this->_contactId);
$defaults = array_merge($defaults, $this->_defaults);
}
if (empty($defaults['trxn_date'])) {
$defaults['trxn_date'] = date('Y-m-d H:i:s');
}
if ($this->_refund) {
$defaults['total_amount'] = abs($this->_refund);
}
elseif ($this->_owed) {
$defaults['total_amount'] = number_format($this->_owed, 2);
}
// Set $newCredit variable in template to control whether link to credit card mode is included
$this->assign('newCredit', CRM_Core_Config::isEnabledBackOfficeCreditCardPayments());
return $defaults;
}
/**
* Build the form object.
*/
public function buildQuickForm() {
if ($this->_view == 'transaction' && ($this->_action & CRM_Core_Action::BROWSE)) {
$this->addButtons(array(
array(
'type' => 'cancel',
'name' => ts('Done'),
'spacing' => '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;',
'isDefault' => TRUE,
),
)
);
return;
}
CRM_Core_Payment_Form::buildPaymentForm($this, $this->_paymentProcessor, FALSE, TRUE, CRM_Utils_Request::retrieve('payment_instrument_id', 'Integer'));
$this->add('select', 'payment_processor_id', ts('Payment Processor'), $this->_processors, NULL);
$attributes = CRM_Core_DAO::getAttribute('CRM_Financial_DAO_FinancialTrxn');
$label = ($this->_refund) ? ts('Refund Amount') : ts('Payment Amount');
$this->addMoney('total_amount',
$label,
TRUE,
$attributes['total_amount'],
TRUE, 'currency', NULL
);
//add receipt for offline contribution
$this->addElement('checkbox', 'is_email_receipt', ts('Send Receipt?'));
$this->add('select', 'from_email_address', ts('Receipt From'), $this->_fromEmails['from_email_id']);
$this->add('textarea', 'receipt_text', ts('Confirmation Message'));
$dateLabel = ($this->_refund) ? ts('Refund Date') : ts('Date Received');
$this->addField('trxn_date', array('entity' => 'FinancialTrxn', 'label' => $dateLabel, 'context' => 'Contribution'), FALSE, FALSE);
if ($this->_contactId && $this->_id) {
if ($this->_component == 'event') {
$eventId = CRM_Core_DAO::getFieldValue('CRM_Event_DAO_Participant', $this->_id, 'event_id', 'id');
$event = CRM_Event_BAO_Event::getEvents(0, $eventId);
$this->assign('eventName', $event[$eventId]);
}
}
$this->assign('displayName', $this->_contributorDisplayName);
$this->assign('component', $this->_component);
$this->assign('email', $this->_contributorEmail);
$js = NULL;
// render backoffice payment fields only on offline mode
if (!$this->_mode) {
$js = array('onclick' => "return verify( );");
$this->add('select', 'payment_instrument_id',
ts('Payment Method'),
array('' => ts('- select -')) + CRM_Contribute_PseudoConstant::paymentInstrument(),
TRUE,
array('onChange' => "return showHideByValue('payment_instrument_id','4','checkNumber','table-row','select',false);")
);
$this->add('text', 'check_number', ts('Check Number'), $attributes['financial_trxn_check_number']);
$this->add('text', 'trxn_id', ts('Transaction ID'), array('class' => 'twelve') + $attributes['trxn_id']);
$this->add('text', 'fee_amount', ts('Fee Amount'),
$attributes['fee_amount']
);
$this->addRule('fee_amount', ts('Please enter a valid monetary value for Fee Amount.'), 'money');
$this->add('text', 'net_amount', ts('Net Amount'),
$attributes['net_amount']
);
$this->addRule('net_amount', ts('Please enter a valid monetary value for Net Amount.'), 'money');
}
$buttonName = $this->_refund ? 'Record Refund' : 'Record Payment';
$this->addButtons(array(
array(
'type' => 'upload',
'name' => ts('%1', array(1 => $buttonName)),
'js' => $js,
'isDefault' => TRUE,
),
array(
'type' => 'cancel',
'name' => ts('Cancel'),
),
)
);
$mailingInfo = Civi::settings()->get('mailing_backend');
$this->assign('outBound_option', $mailingInfo['outBound_option']);
$this->addFormRule(array('CRM_Contribute_Form_AdditionalPayment', 'formRule'), $this);
}
/**
* @param $fields
* @param $files
* @param $self
*
* @return array
*/
public static function formRule($fields, $files, $self) {
$errors = array();
if ($self->_paymentType == 'owed' && $fields['total_amount'] > $self->_owed) {
$errors['total_amount'] = ts('Payment amount cannot be greater than owed amount');
}
if ($self->_paymentType == 'refund' && $fields['total_amount'] != abs($self->_refund)) {
$errors['total_amount'] = ts('Refund amount must equal refund due amount.');
}
$netAmt = $fields['total_amount'] - CRM_Utils_Array::value('fee_amount', $fields, 0);
if (!empty($fields['net_amount']) && $netAmt != $fields['net_amount']) {
$errors['net_amount'] = ts('Net amount should be equal to the difference between payment amount and fee amount.');
}
if ($self->_paymentProcessor['id'] === 0 && empty($fields['payment_instrument_id'])) {
$errors['payment_instrument_id'] = ts('Payment method is a required field');
}
return $errors;
}
/**
* Process the form submission.
*/
public function postProcess() {
$submittedValues = $this->controller->exportValues($this->_name);
$this->submit($submittedValues);
$childTab = 'contribute';
if ($this->_component == 'event') {
$childTab = 'participant';
}
$session = CRM_Core_Session::singleton();
$session->replaceUserContext(CRM_Utils_System::url('civicrm/contact/view',
"reset=1&cid={$this->_contactId}&selectedChild={$childTab}"
));
}
/**
* Process Payments.
* @param array $submittedValues
*
*/
public function submit($submittedValues) {
$this->_params = $submittedValues;
$this->beginPostProcess();
$this->_contributorContactID = $this->_contactID;
$this->processBillingAddress();
$participantId = NULL;
if ($this->_component == 'event') {
$participantId = $this->_id;
}
$contributionStatuses = CRM_Core_PseudoConstant::get('CRM_Contribute_DAO_Contribution',
'contribution_status_id',
array('labelColumn' => 'name')
);
$contributionStatusID = CRM_Core_DAO::getFieldValue('CRM_Contribute_DAO_Contribution', $this->_contributionId, 'contribution_status_id');
if ($contributionStatuses[$contributionStatusID] == 'Pending') {
civicrm_api3('Contribution', 'create',
array(
'id' => $this->_contributionId,
'contribution_status_id' => array_search('Partially paid', $contributionStatuses),
'is_pay_later' => 0,
)
);
}
if ($this->_mode) {
// process credit card
$this->assign('contributeMode', 'direct');
$this->processCreditCard();
}
$defaults = array();
$contribution = civicrm_api3('Contribution', 'getsingle', array(
'return' => array("contribution_status_id"),
'id' => $this->_contributionId,
));
$contributionStatusId = CRM_Utils_Array::value('contribution_status_id', $contribution);
$result = CRM_Contribute_BAO_Contribution::recordAdditionalPayment($this->_contributionId, $this->_params, $this->_paymentType, $participantId);
// Fetch the contribution & do proportional line item assignment
$params = array('id' => $this->_contributionId);
$contribution = CRM_Contribute_BAO_Contribution::retrieve($params, $defaults, $params);
CRM_Contribute_BAO_Contribution::addPayments(array($contribution), $contributionStatusId);
if ($this->_contributionId && CRM_Core_Permission::access('CiviMember')) {
$membershipPaymentCount = civicrm_api3('MembershipPayment', 'getCount', array('contribution_id' => $this->_contributionId));
if ($membershipPaymentCount) {
$this->ajaxResponse['updateTabs']['#tab_member'] = CRM_Contact_BAO_Contact::getCountComponent('membership', $this->_contactID);
}
}
if ($this->_contributionId && CRM_Core_Permission::access('CiviEvent')) {
$participantPaymentCount = civicrm_api3('ParticipantPayment', 'getCount', array('contribution_id' => $this->_contributionId));
if ($participantPaymentCount) {
$this->ajaxResponse['updateTabs']['#tab_participant'] = CRM_Contact_BAO_Contact::getCountComponent('participant', $this->_contactID);
}
}
$statusMsg = ts('The payment record has been processed.');
// send email
if (!empty($result) && !empty($this->_params['is_email_receipt'])) {
$this->_params['contact_id'] = $this->_contactId;
$this->_params['contribution_id'] = $this->_contributionId;
// to get 'from email id' for send receipt
$this->fromEmailId = $this->_params['from_email_address'];
$sendReceipt = $this->emailReceipt($this->_params);
if ($sendReceipt) {
$statusMsg .= ' ' . ts('A receipt has been emailed to the contributor.');
}
}
CRM_Core_Session::setStatus($statusMsg, ts('Saved'), 'success');
}
public function processCreditCard() {
$config = CRM_Core_Config::singleton();
$session = CRM_Core_Session::singleton();
$now = date('YmdHis');
$fields = array();
// we need to retrieve email address
if ($this->_context == 'standalone' && !empty($this->_params['is_email_receipt'])) {
list($this->userDisplayName,
$this->userEmail
) = CRM_Contact_BAO_Contact_Location::getEmailDetails($this->_contactId);
$this->assign('displayName', $this->userDisplayName);
}
$this->formatParamsForPaymentProcessor($this->_params);
$this->_params['amount'] = $this->_params['total_amount'];
// @todo - stop setting amount level in this function & call the CRM_Price_BAO_PriceSet::getAmountLevel
// function to get correct amount level consistently. Remove setting of the amount level in
// CRM_Price_BAO_PriceSet::processAmount. Extend the unit tests in CRM_Price_BAO_PriceSetTest
// to cover all variants.
$this->_params['amount_level'] = 0;
$this->_params['currencyID'] = CRM_Utils_Array::value('currency',
$this->_params,
$config->defaultCurrency
);
if (!empty($this->_params['trxn_date'])) {
$this->_params['receive_date'] = $this->_params['trxn_date'];
}
if (empty($this->_params['receive_date'])) {
$this->_params['receive_date'] = date('YmdHis');
}
if (empty($this->_params['invoice_id'])) {
$this->_params['invoiceID'] = md5(uniqid(rand(), TRUE));
}
else {
$this->_params['invoiceID'] = $this->_params['invoice_id'];
}
$this->assign('address', CRM_Utils_Address::getFormattedBillingAddressFieldsFromParameters(
$this->_params,
$this->_bltID
));
//Add common data to formatted params
$params = $this->_params;
CRM_Contribute_Form_AdditionalInfo::postProcessCommon($params, $this->_params, $this);
// at this point we've created a contact and stored its address etc
// all the payment processors expect the name and address to be in the
// so we copy stuff over to first_name etc.
$paymentParams = $this->_params;
$paymentParams['contactID'] = $this->_contactId;
CRM_Core_Payment_Form::mapParams($this->_bltID, $this->_params, $paymentParams, TRUE);
$paymentParams['contributionPageID'] = NULL;
if (!empty($this->_params['is_email_receipt'])) {
$paymentParams['email'] = $this->_contributorEmail;
$paymentParams['is_email_receipt'] = TRUE;
}
else {
$paymentParams['is_email_receipt'] = $this->_params['is_email_receipt'] = FALSE;
}
$result = NULL;
if ($paymentParams['amount'] > 0.0) {
try {
// force a reget of the payment processor in case the form changed it, CRM-7179
$payment = Civi\Payment\System::singleton()->getByProcessor($this->_paymentProcessor);
$result = $payment->doPayment($paymentParams);
}
catch (\Civi\Payment\Exception\PaymentProcessorException $e) {
Civi::log()->error('Payment processor exception: ' . $e->getMessage());
$urlParams = "action=add&cid={$this->_contactId}&id={$this->_contributionId}&component={$this->_component}&mode={$this->_mode}";
CRM_Core_Error::statusBounce(CRM_Utils_System::url($e->getMessage(), 'civicrm/payment/add', $urlParams));
}
}
if (!empty($result)) {
$this->_params = array_merge($this->_params, $result);
}
if (empty($this->_params['receive_date'])) {
$this->_params['receive_date'] = $now;
}
$this->set('params', $this->_params);
// set source if not set
if (empty($this->_params['source'])) {
$userID = $session->get('userID');
$userSortName = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Contact', $userID,
'sort_name'
);
$this->_params['source'] = ts('Submit Credit Card Payment by: %1', array(1 => $userSortName));
}
}
/**
* Function to send email receipt.
*
* @param array $params
*
* @return bool
*/
public function emailReceipt(&$params) {
// email receipt sending
// send message template
if ($this->_component == 'event') {
// fetch event information from participant ID using API
$eventId = civicrm_api3('Participant', 'getvalue', array(
'return' => "event_id",
'id' => $this->_id,
));
$event = civicrm_api3('Event', 'getsingle', array('id' => $eventId));
$this->assign('event', $event);
$this->assign('isShowLocation', $event['is_show_location']);
if (CRM_Utils_Array::value('is_show_location', $event) == 1) {
$locationParams = array(
'entity_id' => $eventId,
'entity_table' => 'civicrm_event',
);
$location = CRM_Core_BAO_Location::getValues($locationParams, TRUE);
$this->assign('location', $location);
}
}
// assign payment info here
$paymentConfig['confirm_email_text'] = CRM_Utils_Array::value('confirm_email_text', $params);
$this->assign('paymentConfig', $paymentConfig);
$this->assign('totalAmount', $this->_amtTotal);
$isRefund = ($this->_paymentType == 'refund') ? TRUE : FALSE;
$this->assign('isRefund', $isRefund);
if ($isRefund) {
$this->assign('totalPaid', $this->_amtPaid);
$this->assign('refundAmount', $params['total_amount']);
}
else {
$balance = $this->_amtTotal - ($this->_amtPaid + $params['total_amount']);
$paymentsComplete = ($balance == 0) ? 1 : 0;
$this->assign('amountOwed', $balance);
$this->assign('paymentAmount', $params['total_amount']);
$this->assign('paymentsComplete', $paymentsComplete);
}
$this->assign('contactDisplayName', $this->_contributorDisplayName);
// assign trxn details
$this->assign('trxn_id', CRM_Utils_Array::value('trxn_id', $params));
$this->assign('receive_date', CRM_Utils_Array::value('trxn_date', $params));
$this->assign('paidBy', CRM_Core_PseudoConstant::getLabel(
'CRM_Contribute_BAO_Contribution',
'payment_instrument_id',
$params['payment_instrument_id']
));
$this->assign('checkNumber', CRM_Utils_Array::value('check_number', $params));
$sendTemplateParams = array(
'groupName' => 'msg_tpl_workflow_contribution',
'valueName' => 'payment_or_refund_notification',
'contactId' => $this->_contactId,
'PDFFilename' => ts('notification') . '.pdf',
);
// try to send emails only if email id is present
// and the do-not-email option is not checked for that contact
if ($this->_contributorEmail && !$this->_toDoNotEmail) {
if (array_key_exists($params['from_email_address'], $this->_fromEmails['from_email_id'])) {
$receiptFrom = $params['from_email_address'];
}
$sendTemplateParams['from'] = $receiptFrom;
$sendTemplateParams['toName'] = $this->_contributorDisplayName;
$sendTemplateParams['toEmail'] = $this->_contributorEmail;
}
list($mailSent, $subject, $message, $html) = CRM_Core_BAO_MessageTemplate::sendTemplate($sendTemplateParams);
return $mailSent;
}
/**
* Wrapper for unit testing the post process submit function.
*
* @param array $params
* @param string|null $creditCardMode
* @param string $entityType
*
* @throws \CiviCRM_API3_Exception
*/
public function testSubmit($params, $creditCardMode = NULL, $entityType = 'contribute') {
$this->_bltID = 5;
// Required because processCreditCard calls set method on this.
$_SERVER['REQUEST_METHOD'] = 'GET';
$this->controller = new CRM_Core_Controller();
$this->assignPaymentRelatedVariables();
if (!empty($params['contribution_id'])) {
$this->_contributionId = $params['contribution_id'];
$paymentInfo = CRM_Core_BAO_FinancialTrxn::getPartialPaymentWithType($this->_contributionId, $entityType);
$paymentDetails = CRM_Contribute_BAO_Contribution::getPaymentInfo($this->_contributionId, $entityType, FALSE, TRUE);
$this->_amtPaid = $paymentDetails['paid'];
$this->_amtTotal = $paymentDetails['total'];
if (!empty($paymentInfo['refund_due'])) {
$this->_refund = $paymentInfo['refund_due'];
$this->_paymentType = 'refund';
}
elseif (!empty($paymentInfo['amount_owed'])) {
$this->_owed = $paymentInfo['amount_owed'];
$this->_paymentType = 'owed';
}
}
if (!empty($params['contact_id'])) {
$this->_contactId = $params['contact_id'];
}
if ($creditCardMode) {
$this->_mode = $creditCardMode;
}
$this->_fields = array();
$this->set('cid', $this->_contactId);
parent::preProcess();
$this->submit($params);
}
}

View file

@ -0,0 +1,329 @@
<?php
/*
+--------------------------------------------------------------------+
| CiviCRM version 4.7 |
+--------------------------------------------------------------------+
| Copyright CiviCRM LLC (c) 2004-2017 |
+--------------------------------------------------------------------+
| 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 |
+--------------------------------------------------------------------+
*/
/**
*
* @package CRM
* @copyright CiviCRM LLC (c) 2004-2017
*/
/**
* This class provides support for canceling recurring subscriptions.
*/
class CRM_Contribute_Form_CancelSubscription extends CRM_Core_Form {
protected $_paymentProcessorObj = NULL;
protected $_userContext = NULL;
protected $_mode = NULL;
protected $_mid = NULL;
protected $_coid = NULL;
protected $_crid = NULL;
protected $_selfService = FALSE;
/**
* Set variables up before form is built.
*/
public function preProcess() {
$this->_mid = CRM_Utils_Request::retrieve('mid', 'Integer', $this, FALSE);
$this->_crid = CRM_Utils_Request::retrieve('crid', 'Integer', $this, FALSE);
if ($this->_crid) {
$this->_paymentProcessorObj = CRM_Financial_BAO_PaymentProcessor::getProcessorForEntity($this->_crid, 'recur', 'obj');
$this->_subscriptionDetails = CRM_Contribute_BAO_ContributionRecur::getSubscriptionDetails($this->_crid);
$this->assign('frequency_unit', $this->_subscriptionDetails->frequency_unit);
$this->assign('frequency_interval', $this->_subscriptionDetails->frequency_interval);
$this->assign('amount', $this->_subscriptionDetails->amount);
$this->assign('installments', $this->_subscriptionDetails->installments);
// Are we cancelling a recurring contribution that is linked to an auto-renew membership?
if ($this->_subscriptionDetails->membership_id) {
$this->_mid = $this->_subscriptionDetails->membership_id;
}
}
if ($this->_mid) {
$this->_mode = 'auto_renew';
// CRM-18468: crid is more accurate than mid for getting
// subscriptionDetails, so don't get them again.
if (!$this->_crid) {
$this->_paymentProcessorObj = CRM_Financial_BAO_PaymentProcessor::getProcessorForEntity($this->_mid, 'membership', 'obj');
$this->_subscriptionDetails = CRM_Contribute_BAO_ContributionRecur::getSubscriptionDetails($this->_mid, 'membership');
}
$membershipTypes = CRM_Member_PseudoConstant::membershipType();
$membershipTypeId = CRM_Core_DAO::getFieldValue('CRM_Member_DAO_Membership', $this->_mid, 'membership_type_id');
$this->assign('membershipType', CRM_Utils_Array::value($membershipTypeId, $membershipTypes));
}
$this->_coid = CRM_Utils_Request::retrieve('coid', 'Integer', $this, FALSE);
if ($this->_coid) {
if (CRM_Contribute_BAO_Contribution::isSubscriptionCancelled($this->_coid)) {
CRM_Core_Error::fatal(ts('The recurring contribution looks to have been cancelled already.'));
}
$this->_paymentProcessorObj = CRM_Financial_BAO_PaymentProcessor::getProcessorForEntity($this->_coid, 'contribute', 'obj');
$this->_subscriptionDetails = CRM_Contribute_BAO_ContributionRecur::getSubscriptionDetails($this->_coid, 'contribution');
$this->assign('frequency_unit', $this->_subscriptionDetails->frequency_unit);
$this->assign('frequency_interval', $this->_subscriptionDetails->frequency_interval);
$this->assign('amount', $this->_subscriptionDetails->amount);
$this->assign('installments', $this->_subscriptionDetails->installments);
}
if (
(!$this->_crid && !$this->_coid && !$this->_mid) ||
(!$this->_subscriptionDetails)
) {
CRM_Core_Error::fatal('Required information missing.');
}
if (!CRM_Core_Permission::check('edit contributions')) {
$userChecksum = CRM_Utils_Request::retrieve('cs', 'String', $this, FALSE);
if (!CRM_Contact_BAO_Contact_Utils::validChecksum($this->_subscriptionDetails->contact_id, $userChecksum)) {
CRM_Core_Error::fatal(ts('You do not have permission to cancel this recurring contribution.'));
}
$this->_selfService = TRUE;
}
$this->assign('self_service', $this->_selfService);
// handle context redirection
CRM_Contribute_BAO_ContributionRecur::setSubscriptionContext();
CRM_Utils_System::setTitle($this->_mid ? ts('Cancel Auto-renewal') : ts('Cancel Recurring Contribution'));
$this->assign('mode', $this->_mode);
if ($this->_subscriptionDetails->contact_id) {
list($this->_donorDisplayName, $this->_donorEmail)
= CRM_Contact_BAO_Contact::getContactDetails($this->_subscriptionDetails->contact_id);
}
}
/**
* Build the form object.
*/
public function buildQuickForm() {
// Determine if we can cancel recurring contribution via API with this processor
$cancelSupported = $this->_paymentProcessorObj->supports('CancelRecurring');
if ($cancelSupported) {
$searchRange = array();
$searchRange[] = $this->createElement('radio', NULL, NULL, ts('Yes'), '1');
$searchRange[] = $this->createElement('radio', NULL, NULL, ts('No'), '0');
$this->addGroup(
$searchRange,
'send_cancel_request',
ts('Send cancellation request to %1 ?',
array(1 => $this->_paymentProcessorObj->_processorName))
);
}
$this->assign('cancelSupported', $cancelSupported);
if ($this->_donorEmail) {
$this->add('checkbox', 'is_notify', ts('Notify Contributor?'));
}
if ($this->_mid) {
$cancelButton = ts('Cancel Automatic Membership Renewal');
}
else {
$cancelButton = ts('Cancel Recurring Contribution');
}
$type = 'next';
if ($this->_selfService) {
$type = 'submit';
}
$this->addButtons(array(
array(
'type' => $type,
'name' => $cancelButton,
'spacing' => '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;',
'isDefault' => TRUE,
),
array(
'type' => 'cancel',
'name' => ts('Not Now'),
),
)
);
}
/**
* Set default values for the form.
*
* @return array
* array of default values
*/
public function setDefaultValues() {
return array(
'is_notify' => 1,
'send_cancel_request' => 1,
);
}
/**
* Process the form submission.
*/
public function postProcess() {
$status = $message = NULL;
$cancelSubscription = TRUE;
$params = $this->controller->exportValues($this->_name);
if ($this->_selfService) {
// for self service force sending-request & notify
if ($this->_paymentProcessorObj->supports('cancelRecurring')) {
$params['send_cancel_request'] = 1;
}
if ($this->_donorEmail) {
$params['is_notify'] = 1;
}
}
if (CRM_Utils_Array::value('send_cancel_request', $params) == 1) {
$cancelParams = array('subscriptionId' => $this->_subscriptionDetails->subscription_id);
$cancelSubscription = $this->_paymentProcessorObj->cancelSubscription($message, $cancelParams);
}
if (is_a($cancelSubscription, 'CRM_Core_Error')) {
CRM_Core_Error::displaySessionError($cancelSubscription);
}
elseif ($cancelSubscription) {
$activityParams
= array(
'subject' => $this->_mid ? ts('Auto-renewal membership cancelled') : ts('Recurring contribution cancelled'),
'details' => $message,
);
$cancelStatus = CRM_Contribute_BAO_ContributionRecur::cancelRecurContribution(
$this->_subscriptionDetails->recur_id,
NULL,
$activityParams
);
if ($cancelStatus) {
$tplParams = array();
if ($this->_mid) {
$inputParams = array('id' => $this->_mid);
CRM_Member_BAO_Membership::getValues($inputParams, $tplParams);
$tplParams = $tplParams[$this->_mid];
$tplParams['membership_status']
= CRM_Core_DAO::getFieldValue('CRM_Member_DAO_MembershipStatus', $tplParams['status_id']);
$tplParams['membershipType']
= CRM_Core_DAO::getFieldValue('CRM_Member_DAO_MembershipType', $tplParams['membership_type_id']);
$status = ts('The automatic renewal of your %1 membership has been cancelled as requested. This does not affect the status of your membership - you will receive a separate notification when your membership is up for renewal.', array(1 => $tplParams['membershipType']));
$msgTitle = 'Membership Renewal Cancelled';
$msgType = 'info';
}
else {
$tplParams['recur_frequency_interval'] = $this->_subscriptionDetails->frequency_interval;
$tplParams['recur_frequency_unit'] = $this->_subscriptionDetails->frequency_unit;
$tplParams['amount'] = $this->_subscriptionDetails->amount;
$tplParams['contact'] = array('display_name' => $this->_donorDisplayName);
$status = ts('The recurring contribution of %1, every %2 %3 has been cancelled.',
array(
1 => $this->_subscriptionDetails->amount,
2 => $this->_subscriptionDetails->frequency_interval,
3 => $this->_subscriptionDetails->frequency_unit,
)
);
$msgTitle = 'Contribution Cancelled';
$msgType = 'success';
}
if (CRM_Utils_Array::value('is_notify', $params) == 1) {
if ($this->_subscriptionDetails->contribution_page_id) {
CRM_Core_DAO::commonRetrieveAll(
'CRM_Contribute_DAO_ContributionPage',
'id',
$this->_subscriptionDetails->contribution_page_id,
$value,
array('title', 'receipt_from_name', 'receipt_from_email')
);
$receiptFrom
= '"' . CRM_Utils_Array::value('receipt_from_name', $value[$this->_subscriptionDetails->contribution_page_id]) .
'" <' .
$value[$this->_subscriptionDetails->contribution_page_id]['receipt_from_email'] .
'>';
}
else {
$domainValues = CRM_Core_BAO_Domain::getNameAndEmail();
$receiptFrom = "$domainValues[0] <$domainValues[1]>";
}
// send notification
$sendTemplateParams
= array(
'groupName' => $this->_mode == 'auto_renew' ? 'msg_tpl_workflow_membership' : 'msg_tpl_workflow_contribution',
'valueName' => $this->_mode == 'auto_renew' ? 'membership_autorenew_cancelled' : 'contribution_recurring_cancelled',
'contactId' => $this->_subscriptionDetails->contact_id,
'tplParams' => $tplParams,
//'isTest' => $isTest, set this from _objects
'PDFFilename' => 'receipt.pdf',
'from' => $receiptFrom,
'toName' => $this->_donorDisplayName,
'toEmail' => $this->_donorEmail,
);
list($sent) = CRM_Core_BAO_MessageTemplate::sendTemplate($sendTemplateParams);
}
}
else {
$msgType = 'error';
$msgTitle = ts('Error');
if ($params['send_cancel_request'] == 1) {
$status = ts('Recurring contribution was cancelled successfully by the processor, but could not be marked as cancelled in the database.');
}
else {
$status = ts('Recurring contribution could not be cancelled in the database.');
}
}
}
else {
$status = ts('The recurring contribution could not be cancelled.');
$msgTitle = 'Error Cancelling Contribution';
$msgType = 'error';
}
$session = CRM_Core_Session::singleton();
$userID = $session->get('userID');
if ($userID && $status) {
$session->setStatus($status, $msgTitle, $msgType);
}
elseif (!$userID) {
if ($status) {
CRM_Utils_System::setUFMessage($status);
// keep result as 1, since we not displaying anything on the redirected page anyway
return CRM_Utils_System::redirect(CRM_Utils_System::url('civicrm/contribute/subscriptionstatus',
"reset=1&task=cancel&result=1"));
}
}
}
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,322 @@
<?php
/*
+--------------------------------------------------------------------+
| CiviCRM version 4.7 |
+--------------------------------------------------------------------+
| Copyright CiviCRM LLC (c) 2004-2017 |
+--------------------------------------------------------------------+
| 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 |
+--------------------------------------------------------------------+
*/
/**
*
* @package CRM
* @copyright CiviCRM LLC (c) 2004-2017
*/
/**
* Form for thank-you / success page - 3rd step of online contribution process.
*/
class CRM_Contribute_Form_Contribution_ThankYou extends CRM_Contribute_Form_ContributionBase {
/**
* Membership price set status.
*/
public $_useForMember;
/**
* Set variables up before form is built.
*/
public function preProcess() {
parent::preProcess();
$this->_params = $this->get('params');
$this->_lineItem = $this->get('lineItem');
$is_deductible = $this->get('is_deductible');
$this->assign('is_deductible', $is_deductible);
$this->assign('thankyou_title', CRM_Utils_Array::value('thankyou_title', $this->_values));
$this->assign('thankyou_text', CRM_Utils_Array::value('thankyou_text', $this->_values));
$this->assign('thankyou_footer', CRM_Utils_Array::value('thankyou_footer', $this->_values));
$this->assign('max_reminders', CRM_Utils_Array::value('max_reminders', $this->_values));
$this->assign('initial_reminder_day', CRM_Utils_Array::value('initial_reminder_day', $this->_values));
CRM_Utils_System::setTitle(CRM_Utils_Array::value('thankyou_title', $this->_values));
// Make the contributionPageID available to the template
$this->assign('contributionPageID', $this->_id);
$this->assign('isShare', $this->_values['is_share']);
$this->_params['is_pay_later'] = $this->get('is_pay_later');
$this->assign('is_pay_later', $this->_params['is_pay_later']);
if ($this->_params['is_pay_later']) {
$this->assign('pay_later_receipt', $this->_values['pay_later_receipt']);
}
$this->assign('is_for_organization', CRM_Utils_Array::value('is_for_organization', $this->_params));
}
/**
* Overwrite action, since we are only showing elements in frozen mode
* no help display needed
*
* @return int
*/
public function getAction() {
if ($this->_action & CRM_Core_Action::PREVIEW) {
return CRM_Core_Action::VIEW | CRM_Core_Action::PREVIEW;
}
else {
return CRM_Core_Action::VIEW;
}
}
/**
* Build the form object.
*/
public function buildQuickForm() {
// FIXME: Some of this code is identical to Confirm.php and should be broken out into a shared function
$this->assignToTemplate();
$this->_ccid = $this->get('ccid');
$productID = $this->get('productID');
$option = $this->get('option');
$membershipTypeID = $this->get('membershipTypeID');
$this->assign('receiptFromEmail', CRM_Utils_Array::value('receipt_from_email', $this->_values));
if ($productID) {
CRM_Contribute_BAO_Premium::buildPremiumBlock($this, $this->_id, FALSE, $productID, $option);
}
$params = $this->_params;
$invoiceSettings = Civi::settings()->get('contribution_invoice_settings');
$invoicing = CRM_Utils_Array::value('invoicing', $invoiceSettings);
// Make a copy of line items array to use for display only
$tplLineItems = $this->_lineItem;
if ($invoicing) {
$getTaxDetails = FALSE;
$taxTerm = CRM_Utils_Array::value('tax_term', $invoiceSettings);
foreach ($this->_lineItem as $key => $value) {
foreach ($value as $k => $v) {
if (isset($v['tax_rate'])) {
if ($v['tax_rate'] != '') {
$getTaxDetails = TRUE;
// Cast to float to display without trailing zero decimals
$tplLineItems[$key][$k]['tax_rate'] = (float) $v['tax_rate'];
}
}
}
}
$this->assign('getTaxDetails', $getTaxDetails);
$this->assign('taxTerm', $taxTerm);
$this->assign('totalTaxAmount', $params['tax_amount']);
}
if ($this->_priceSetId && !CRM_Core_DAO::getFieldValue('CRM_Price_DAO_PriceSet', $this->_priceSetId, 'is_quick_config')) {
$this->assign('lineItem', $tplLineItems);
}
else {
if (is_array($membershipTypeID)) {
$membershipTypeID = current($membershipTypeID);
}
$this->assign('is_quick_config', 1);
$this->_params['is_quick_config'] = 1;
}
$this->assign('priceSetID', $this->_priceSetId);
$this->assign('useForMember', $this->get('useForMember'));
if (!empty($this->_values['honoree_profile_id']) && !empty($params['soft_credit_type_id'])) {
$softCreditTypes = CRM_Core_OptionGroup::values("soft_credit_type", FALSE);
$this->assign('soft_credit_type', $softCreditTypes[$params['soft_credit_type_id']]);
CRM_Contribute_BAO_ContributionSoft::formatHonoreeProfileFields($this, $params['honor']);
$fieldTypes = array('Contact');
$fieldTypes[] = CRM_Core_BAO_UFGroup::getContactType($this->_values['honoree_profile_id']);
$this->buildCustom($this->_values['honoree_profile_id'], 'honoreeProfileFields', TRUE, 'honor', $fieldTypes);
}
$qParams = "reset=1&amp;id={$this->_id}";
//pcp elements
if ($this->_pcpId) {
$qParams .= "&amp;pcpId={$this->_pcpId}";
$this->assign('pcpBlock', TRUE);
foreach (array(
'pcp_display_in_roll',
'pcp_is_anonymous',
'pcp_roll_nickname',
'pcp_personal_note',
) as $val) {
if (!empty($this->_params[$val])) {
$this->assign($val, $this->_params[$val]);
}
}
}
$this->assign('qParams', $qParams);
if ($membershipTypeID) {
$transactionID = $this->get('membership_trx_id');
$membershipAmount = $this->get('membership_amount');
$renewalMode = $this->get('renewal_mode');
$this->assign('membership_trx_id', $transactionID);
$this->assign('membership_amount', $membershipAmount);
$this->assign('renewal_mode', $renewalMode);
$this->buildMembershipBlock(
$this->_membershipContactID,
FALSE,
$membershipTypeID,
TRUE,
NULL
);
if (!empty($params['auto_renew'])) {
$this->assign('auto_renew', TRUE);
}
}
$this->_separateMembershipPayment = $this->get('separateMembershipPayment');
$this->assign("is_separate_payment", $this->_separateMembershipPayment);
if (empty($this->_ccid)) {
$this->buildCustom($this->_values['custom_pre_id'], 'customPre', TRUE);
$this->buildCustom($this->_values['custom_post_id'], 'customPost', TRUE);
}
if (!empty($this->_values['onbehalf_profile_id']) &&
!empty($params['onbehalf']) &&
($this->_values['is_for_organization'] == 2 ||
!empty($params['is_for_organization'])
) && empty($this->_ccid)
) {
$fieldTypes = array('Contact', 'Organization');
$contactSubType = CRM_Contact_BAO_ContactType::subTypes('Organization');
$fieldTypes = array_merge($fieldTypes, $contactSubType);
if (is_array($this->_membershipBlock) && !empty($this->_membershipBlock)) {
$fieldTypes = array_merge($fieldTypes, array('Membership'));
}
else {
$fieldTypes = array_merge($fieldTypes, array('Contribution'));
}
$this->buildCustom($this->_values['onbehalf_profile_id'], 'onbehalfProfile', TRUE, 'onbehalf', $fieldTypes);
}
$this->assign('trxn_id',
CRM_Utils_Array::value('trxn_id',
$this->_params
)
);
$this->assign('receive_date',
CRM_Utils_Date::mysqlToIso(CRM_Utils_Array::value('receive_date', $this->_params))
);
$defaults = array();
$fields = array();
foreach ($this->_fields as $name => $dontCare) {
if ($name != 'onbehalf' || $name != 'honor') {
$fields[$name] = 1;
}
}
$fields['state_province'] = $fields['country'] = $fields['email'] = 1;
$contact = $this->_params = $this->controller->exportValues('Main');
foreach ($fields as $name => $dontCare) {
if (isset($contact[$name])) {
$defaults[$name] = $contact[$name];
if (substr($name, 0, 7) == 'custom_') {
$timeField = "{$name}_time";
if (isset($contact[$timeField])) {
$defaults[$timeField] = $contact[$timeField];
}
}
elseif (in_array($name, array(
'addressee',
'email_greeting',
'postal_greeting',
)) && !empty($contact[$name . '_custom'])
) {
$defaults[$name . '_custom'] = $contact[$name . '_custom'];
}
}
}
$this->_submitValues = array_merge($this->_submitValues, $defaults);
$this->setDefaults($defaults);
$values['entity_id'] = $this->_id;
$values['entity_table'] = 'civicrm_contribution_page';
CRM_Friend_BAO_Friend::retrieve($values, $data);
$tellAFriend = FALSE;
if ($this->_pcpId) {
if ($this->_pcpBlock['is_tellfriend_enabled']) {
$this->assign('friendText', ts('Tell a Friend'));
$subUrl = "eid={$this->_pcpId}&blockId={$this->_pcpBlock['id']}&pcomponent=pcp";
$tellAFriend = TRUE;
}
}
elseif (!empty($data['is_active'])) {
$friendText = $data['title'];
$this->assign('friendText', $friendText);
$subUrl = "eid={$this->_id}&pcomponent=contribute";
$tellAFriend = TRUE;
}
if ($tellAFriend) {
if ($this->_action & CRM_Core_Action::PREVIEW) {
$url = CRM_Utils_System::url("civicrm/friend",
"reset=1&action=preview&{$subUrl}"
);
}
else {
$url = CRM_Utils_System::url("civicrm/friend",
"reset=1&{$subUrl}"
);
}
$this->assign('friendURL', $url);
}
$isPendingOutcome = TRUE;
try {
// A payment notification update could have come in at any time. Check at the last minute.
$contributionStatusID = civicrm_api3('Contribution', 'getvalue', array(
'id' => CRM_Utils_Array::value('contributionID', $params),
'return' => 'contribution_status_id',
'invoice_id' => CRM_Utils_Array::value('invoiceID', $params),
));
if (CRM_Core_PseudoConstant::getName('CRM_Contribute_BAO_Contribution', 'contribution_status_id', $contributionStatusID) === 'Pending'
&& !empty($params['payment_processor_id'])
) {
$isPendingOutcome = TRUE;
}
else {
$isPendingOutcome = FALSE;
}
}
catch (CiviCRM_API3_Exception $e) {
}
$this->assign('isPendingOutcome', $isPendingOutcome);
$this->freeze();
// can we blow away the session now to prevent hackery
// CRM-9491
$this->controller->reset();
}
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,238 @@
<?php
/*
+--------------------------------------------------------------------+
| CiviCRM version 4.7 |
+--------------------------------------------------------------------+
| Copyright CiviCRM LLC (c) 2004-2017 |
+--------------------------------------------------------------------+
| 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 |
+--------------------------------------------------------------------+
*/
/**
*
* @package CRM
* @copyright CiviCRM LLC (c) 2004-2017
*/
class CRM_Contribute_Form_ContributionCharts extends CRM_Core_Form {
/**
* Year of chart.
*
* @var int
*/
protected $_year = NULL;
/**
* The type of chart.
*
* @var string
*/
protected $_chartType = NULL;
public function preProcess() {
$this->_year = CRM_Utils_Request::retrieve('year', 'Int', $this);
$this->_chartType = CRM_Utils_Request::retrieve('type', 'String', $this);
$buildChart = FALSE;
if ($this->_year || $this->_chartType) {
$buildChart = TRUE;
}
$this->assign('buildChart', $buildChart);
$this->postProcess();
}
/**
* Build the form object.
*/
public function buildQuickForm() {
//p3 = Three dimensional pie chart.
//bvg = Vertical bar chart
$this->addElement('select', 'chart_type', ts('Chart Style'), array(
'bvg' => ts('Bar'),
'p3' => ts('Pie'),
)
);
$defaultValues['chart_type'] = $this->_chartType;
$this->setDefaults($defaultValues);
//take available years from database to show in drop down
$currentYear = date('Y');
$years = array();
if (!empty($this->_years)) {
if (!array_key_exists($currentYear, $this->_years)) {
$this->_years[$currentYear] = $currentYear;
krsort($this->_years);
}
foreach ($this->_years as $k => $v) {
$years[substr($k, 0, 4)] = substr($k, 0, 4);
}
}
$this->addElement('select', 'select_year', ts('Select Year (for monthly breakdown)'), $years);
$this->setDefaults(array(
'select_year' => ($this->_year) ? $this->_year : $currentYear,
));
}
/**
* Process the form after the input has been submitted and validated.
*/
public function postProcess() {
$config = CRM_Core_Config::singleton();
$chartType = 'bvg';
if ($this->_chartType) {
$chartType = $this->_chartType;
}
$selectedYear = date('Y');
if ($this->_year) {
$selectedYear = $this->_year;
}
//take contribution information monthly
$chartInfoMonthly = CRM_Contribute_BAO_Contribution_Utils::contributionChartMonthly($selectedYear);
$chartData = $abbrMonthNames = array();
if (is_array($chartInfoMonthly)) {
for ($i = 1; $i <= 12; $i++) {
$abbrMonthNames[$i] = strftime('%b', mktime(0, 0, 0, $i, 10, 1970));
}
foreach ($abbrMonthNames as $monthKey => $monthName) {
$val = CRM_Utils_Array::value($monthKey, $chartInfoMonthly['By Month'], 0);
// don't include zero value month.
if (!$val && ($chartType != 'bvg')) {
continue;
}
//build the params for chart.
$chartData['by_month']['values'][$monthName] = $val;
}
$chartData['by_month']['legend'] = 'By Month' . ' - ' . $selectedYear;
// handle onclick event.
$chartData['by_month']['on_click_fun_name'] = 'byMonthOnClick';
$chartData['by_month']['yname'] = ts('Contribution');
}
//take contribution information by yearly
$chartInfoYearly = CRM_Contribute_BAO_Contribution_Utils::contributionChartYearly();
//get the years.
$this->_years = $chartInfoYearly['By Year'];
$hasContributions = FALSE;
if (is_array($chartInfoYearly)) {
$hasContributions = TRUE;
$chartData['by_year']['legend'] = 'By Year';
$chartData['by_year']['values'] = $chartInfoYearly['By Year'];
// handle onclick event.
$chartData['by_year']['on_click_fun_name'] = 'byYearOnClick';
$chartData['by_year']['yname'] = ts('Total Amount');
}
$this->assign('hasContributions', $hasContributions);
// process the data.
$chartCnt = 1;
$monthlyChart = $yearlyChart = FALSE;
foreach ($chartData as $chartKey => & $values) {
$chartValues = CRM_Utils_Array::value('values', $values);
if (!is_array($chartValues) || empty($chartValues)) {
continue;
}
if ($chartKey == 'by_year') {
$yearlyChart = TRUE;
if (!empty($config->fiscalYearStart) && ($config->fiscalYearStart['M'] !== 1 || $config->fiscalYearStart['d'] !== 1)) {
$values['xLabelAngle'] = 45;
}
else {
$values['xLabelAngle'] = 0;
}
}
if ($chartKey == 'by_month') {
$monthlyChart = TRUE;
}
$values['divName'] = "open_flash_chart_{$chartKey}";
$funName = ($chartType == 'bvg') ? 'barChart' : 'pieChart';
// build the chart objects.
$values['object'] = CRM_Utils_OpenFlashChart::$funName($values);
//build the urls.
$urlCnt = 0;
foreach ($chartValues as $index => $val) {
$urlParams = NULL;
if ($chartKey == 'by_month') {
$monthPosition = array_search($index, $abbrMonthNames);
$startDate = CRM_Utils_Date::format(array('Y' => $selectedYear, 'M' => $monthPosition));
$endDate = date('Ymd', mktime(0, 0, 0, $monthPosition + 1, 0, $selectedYear));
$urlParams = "reset=1&force=1&status=1&start={$startDate}&end={$endDate}&test=0";
}
elseif ($chartKey == 'by_year') {
if (!empty($config->fiscalYearStart) && ($config->fiscalYearStart['M'] != 1 || $config->fiscalYearStart['d'] != 1)) {
$startDate = date('Ymd', mktime(0, 0, 0, $config->fiscalYearStart['M'], $config->fiscalYearStart['d'], substr($index, 0, 4)));
$endDate = date('Ymd', mktime(0, 0, 0, $config->fiscalYearStart['M'], $config->fiscalYearStart['d'], (substr($index, 0, 4)) + 1));
}
else {
$startDate = CRM_Utils_Date::format(array('Y' => substr($index, 0, 4)));
$endDate = date('Ymd', mktime(0, 0, 0, 13, 0, substr($index, 0, 4)));
}
$urlParams = "reset=1&force=1&status=1&start={$startDate}&end={$endDate}&test=0";
}
if ($urlParams) {
$values['on_click_urls']["url_" . $urlCnt++] = CRM_Utils_System::url('civicrm/contribute/search',
$urlParams, TRUE, FALSE, FALSE
);
}
}
// calculate chart size.
$xSize = 400;
$ySize = 300;
if ($chartType == 'bvg') {
$ySize = 250;
$xSize = 60 * count($chartValues);
// reduce x size by 100 for by_month
if ($chartKey == 'by_month') {
$xSize -= 100;
}
//hack to show tooltip.
if ($xSize < 150) {
$xSize = 150;
}
}
$values['size'] = array('xSize' => $xSize, 'ySize' => $ySize);
}
// finally assign this chart data to template.
$this->assign('hasYearlyChart', $yearlyChart);
$this->assign('hasByMonthChart', $monthlyChart);
$this->assign('hasOpenFlashChart', empty($chartData) ? FALSE : TRUE);
$this->assign('openFlashChartData', json_encode($chartData));
}
}

View file

@ -0,0 +1,480 @@
<?php
/*
+--------------------------------------------------------------------+
| CiviCRM version 4.7 |
+--------------------------------------------------------------------+
| Copyright CiviCRM LLC (c) 2004-2017 |
+--------------------------------------------------------------------+
| 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 |
+--------------------------------------------------------------------+
*/
/**
*
* @package CRM
* @copyright CiviCRM LLC (c) 2004-2017
*/
/**
* Contribution Page form.
*/
class CRM_Contribute_Form_ContributionPage extends CRM_Core_Form {
/**
* The page id saved to the session for an update.
*
* @var int
*/
protected $_id;
/**
* The pledgeBlock id saved to the session for an update.
*
* @var int
*/
protected $_pledgeBlockID;
/**
* Are we in single form mode or wizard mode?
*
* @var boolean
*/
protected $_single;
/**
* Is this the first page?
*
* @var boolean
*/
protected $_first = FALSE;
/**
* Is this the last page?
*
* @var boolean
*/
protected $_last = FALSE;
/**
* Store price set id.
*
* @var int
*/
protected $_priceSetID = NULL;
protected $_values;
/**
* Explicitly declare the entity api name.
*/
public function getDefaultEntity() {
return 'Contribution';
}
/**
* Set variables up before form is built.
*/
public function preProcess() {
// current contribution page id
$this->_id = CRM_Utils_Request::retrieve('id', 'Positive',
$this, FALSE, NULL, 'REQUEST'
);
$this->assign('contributionPageID', $this->_id);
// get the requested action
$this->_action = CRM_Utils_Request::retrieve('action', 'String',
// default to 'browse'
$this, FALSE, 'browse'
);
// setting title and 3rd level breadcrumb for html page if contrib page exists
if ($this->_id) {
$title = CRM_Core_DAO::getFieldValue('CRM_Contribute_DAO_ContributionPage', $this->_id, 'title');
if ($this->_action == CRM_Core_Action::UPDATE) {
$this->_single = TRUE;
}
}
// CRM-16776 - show edit/copy/create buttons on Profiles Tab if user has required permission.
if (CRM_Core_Permission::check('administer CiviCRM')) {
$this->assign('perm', TRUE);
}
// set up tabs
CRM_Contribute_Form_ContributionPage_TabHeader::build($this);
if ($this->_action == CRM_Core_Action::UPDATE) {
CRM_Utils_System::setTitle(ts('Configure Page - %1', array(1 => $title)));
}
elseif ($this->_action == CRM_Core_Action::VIEW) {
CRM_Utils_System::setTitle(ts('Preview Page - %1', array(1 => $title)));
}
elseif ($this->_action == CRM_Core_Action::DELETE) {
CRM_Utils_System::setTitle(ts('Delete Page - %1', array(1 => $title)));
}
//cache values.
$this->_values = $this->get('values');
if (!is_array($this->_values)) {
$this->_values = array();
if (isset($this->_id) && $this->_id) {
$params = array('id' => $this->_id);
CRM_Core_DAO::commonRetrieve('CRM_Contribute_DAO_ContributionPage', $params, $this->_values);
CRM_Contribute_BAO_ContributionPage::setValues($this->_id, $this->_values);
}
$this->set('values', $this->_values);
}
// Check permission to edit contribution page
if (CRM_Financial_BAO_FinancialType::isACLFinancialTypeStatus() && $this->_action & CRM_Core_Action::UPDATE) {
$financialTypeID = CRM_Contribute_PseudoConstant::financialType($this->_values['financial_type_id']);
if (!CRM_Core_Permission::check('edit contributions of type ' . $financialTypeID)) {
CRM_Core_Error::fatal(ts('You do not have permission to access this page.'));
}
}
// Preload libraries required by the "Profiles" tab
$schemas = array('IndividualModel', 'OrganizationModel', 'ContributionModel');
if (in_array('CiviMember', CRM_Core_Config::singleton()->enableComponents)) {
$schemas[] = 'MembershipModel';
}
CRM_UF_Page_ProfileEditor::registerProfileScripts();
CRM_UF_Page_ProfileEditor::registerSchemas($schemas);
}
/**
* Build the form object.
*/
public function buildQuickForm() {
$this->applyFilter('__ALL__', 'trim');
$session = CRM_Core_Session::singleton();
$this->_cancelURL = CRM_Utils_Array::value('cancelURL', $_POST);
if (!$this->_cancelURL) {
$this->_cancelURL = CRM_Utils_System::url('civicrm/admin/contribute', 'reset=1');
}
if ($this->_cancelURL) {
$this->addElement('hidden', 'cancelURL', $this->_cancelURL);
}
if ($this->_single) {
$buttons = array(
array(
'type' => 'next',
'name' => ts('Save'),
'spacing' => '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;',
'isDefault' => TRUE,
),
array(
'type' => 'upload',
'name' => ts('Save and Done'),
'spacing' => '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;',
'subName' => 'done',
),
);
if (!$this->_last) {
$buttons[] = array(
'type' => 'submit',
'name' => ts('Save and Next'),
'spacing' => '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;',
'subName' => 'savenext',
);
}
$buttons[] = array(
'type' => 'cancel',
'name' => ts('Cancel'),
);
$this->addButtons($buttons);
}
else {
$buttons = array();
if (!$this->_first) {
$buttons[] = array(
'type' => 'back',
'name' => ts('Previous'),
'spacing' => '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;',
);
}
$buttons[] = array(
'type' => 'next',
'name' => ts('Continue'),
'spacing' => '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;',
'isDefault' => TRUE,
);
$buttons[] = array(
'type' => 'cancel',
'name' => ts('Cancel'),
);
$this->addButtons($buttons);
}
$session->replaceUserContext($this->_cancelURL);
// views are implemented as frozen form
if ($this->_action & CRM_Core_Action::VIEW) {
$this->freeze();
$this->addElement('button', 'done', ts('Done'), array('onclick' => "location.href='civicrm/admin/custom/group?reset=1&action=browse'"));
}
// don't show option for contribution amounts section if membership price set
// this flag is sent to template
$membershipBlock = new CRM_Member_DAO_MembershipBlock();
$membershipBlock->entity_table = 'civicrm_contribution_page';
$membershipBlock->entity_id = $this->_id;
$membershipBlock->is_active = 1;
$hasMembershipBlk = FALSE;
if ($membershipBlock->find(TRUE) &&
($setID = CRM_Price_BAO_PriceSet::getFor('civicrm_contribution_page', $this->_id, NULL, 1))
) {
$extends = CRM_Core_DAO::getFieldValue('CRM_Price_DAO_PriceSet', $setID, 'extends');
if ($extends && $extends == CRM_Core_Component::getComponentID('CiviMember')) {
$hasMembershipBlk = TRUE;
}
}
// set value in DOM that membership price set exists
CRM_Core_Resources::singleton()->addSetting(array('memberPriceset' => $hasMembershipBlk));
}
/**
* Set default values for the form. Note that in edit/view mode
* the default values are retrieved from the database
*
*
* @return array
* defaults
*/
public function setDefaultValues() {
//some child classes calling setdefaults directly w/o preprocess.
$this->_values = $this->get('values');
if (!is_array($this->_values)) {
$this->_values = array();
if (isset($this->_id) && $this->_id) {
$params = array('id' => $this->_id);
CRM_Core_DAO::commonRetrieve('CRM_Contribute_DAO_ContributionPage', $params, $this->_values);
}
$this->set('values', $this->_values);
}
$defaults = $this->_values;
$config = CRM_Core_Config::singleton();
if (isset($this->_id)) {
//set defaults for pledgeBlock values.
$pledgeBlockParams = array(
'entity_id' => $this->_id,
'entity_table' => ts('civicrm_contribution_page'),
);
$pledgeBlockDefaults = array();
CRM_Pledge_BAO_PledgeBlock::retrieve($pledgeBlockParams, $pledgeBlockDefaults);
if ($this->_pledgeBlockID = CRM_Utils_Array::value('id', $pledgeBlockDefaults)) {
$defaults['is_pledge_active'] = TRUE;
}
$pledgeBlock = array(
'is_pledge_interval',
'max_reminders',
'initial_reminder_day',
'additional_reminder_day',
'pledge_start_date',
'is_pledge_start_date_visible',
'is_pledge_start_date_editable',
);
foreach ($pledgeBlock as $key) {
$defaults[$key] = CRM_Utils_Array::value($key, $pledgeBlockDefaults);
if ($key == 'pledge_start_date' && CRM_Utils_Array::value($key, $pledgeBlockDefaults)) {
$defaultPledgeDate = (array) json_decode($pledgeBlockDefaults['pledge_start_date']);
$pledgeDateFields = array(
'pledge_calendar_date' => 'calendar_date',
'pledge_calendar_month' => 'calendar_month',
);
$defaults['pledge_default_toggle'] = key($defaultPledgeDate);
foreach ($pledgeDateFields as $key => $value) {
if (array_key_exists($value, $defaultPledgeDate)) {
$defaults[$key] = reset($defaultPledgeDate);
$this->assign($key, reset($defaultPledgeDate));
}
}
}
}
if (!empty($pledgeBlockDefaults['pledge_frequency_unit'])) {
$defaults['pledge_frequency_unit'] = array_fill_keys(explode(CRM_Core_DAO::VALUE_SEPARATOR,
$pledgeBlockDefaults['pledge_frequency_unit']
), '1');
}
// fix the display of the monetary value, CRM-4038
if (isset($defaults['goal_amount'])) {
$defaults['goal_amount'] = CRM_Utils_Money::format($defaults['goal_amount'], NULL, '%a');
}
// get price set of type contributions
//this is the value for stored in db if price set extends contribution
$usedFor = 2;
$this->_priceSetID = CRM_Price_BAO_PriceSet::getFor('civicrm_contribution_page', $this->_id, $usedFor, 1);
if ($this->_priceSetID) {
$defaults['price_set_id'] = $this->_priceSetID;
}
if (!empty($defaults['end_date'])) {
list($defaults['end_date'], $defaults['end_date_time']) = CRM_Utils_Date::setDateDefaults($defaults['end_date']);
}
if (!empty($defaults['start_date'])) {
list($defaults['start_date'], $defaults['start_date_time']) = CRM_Utils_Date::setDateDefaults($defaults['start_date']);
}
}
else {
$defaults['is_active'] = 1;
// set current date as start date
list($defaults['start_date'], $defaults['start_date_time']) = CRM_Utils_Date::setDateDefaults();
}
if (!empty($defaults['recur_frequency_unit'])) {
$defaults['recur_frequency_unit'] = array_fill_keys(explode(CRM_Core_DAO::VALUE_SEPARATOR,
$defaults['recur_frequency_unit']
), '1');
}
else {
# CRM 10860
$defaults['recur_frequency_unit'] = array('month' => 1);
}
// confirm page starts out enabled
if (!isset($defaults['is_confirm_enabled'])) {
$defaults['is_confirm_enabled'] = 1;
}
return $defaults;
}
/**
* Process the form.
*/
public function postProcess() {
$pageId = $this->get('id');
//page is newly created.
if ($pageId && !$this->_id) {
$session = CRM_Core_Session::singleton();
$session->pushUserContext(CRM_Utils_System::url('civicrm/admin/contribute', 'reset=1'));
}
}
public function endPostProcess() {
// make submit buttons keep the current working tab opened, or save and next tab
if ($this->_action & CRM_Core_Action::UPDATE) {
$className = CRM_Utils_String::getClassName($this->_name);
//retrieve list of pages from StateMachine and find next page
//this is quite painful because StateMachine is full of protected variables
//so we have to retrieve all pages, find current page, and then retrieve next
$stateMachine = new CRM_Contribute_StateMachine_ContributionPage($this);
$states = $stateMachine->getStates();
$statesList = array_keys($states);
$currKey = array_search($className, $statesList);
$nextPage = (array_key_exists($currKey + 1, $statesList)) ? $statesList[$currKey + 1] : '';
//unfortunately, some classes don't map to subpage names, so we alter the exceptions
switch ($className) {
case 'Contribute':
$attributes = $this->getVar('_attributes');
$subPage = strtolower(basename(CRM_Utils_Array::value('action', $attributes)));
$subPageName = ucfirst($subPage);
if ($subPage == 'friend') {
$nextPage = 'custom';
}
else {
$nextPage = 'settings';
}
break;
case 'MembershipBlock':
$subPage = 'membership';
$subPageName = 'MembershipBlock';
$nextPage = 'thankyou';
break;
default:
$subPage = strtolower($className);
$subPageName = $className;
$nextPage = strtolower($nextPage);
if ($subPage == 'amount') {
$nextPage = 'membership';
}
elseif ($subPage == 'thankyou') {
$nextPage = 'friend';
}
break;
}
CRM_Core_Session::setStatus(ts("'%1' information has been saved.",
array(1 => $subPageName)
), ts('Saved'), 'success');
$this->postProcessHook();
if ($this->controller->getButtonName('submit') == "_qf_{$className}_next") {
CRM_Utils_System::redirect(CRM_Utils_System::url("civicrm/admin/contribute/{$subPage}",
"action=update&reset=1&id={$this->_id}"
));
}
elseif ($this->controller->getButtonName('submit') == "_qf_{$className}_submit_savenext") {
if ($nextPage) {
CRM_Utils_System::redirect(CRM_Utils_System::url("civicrm/admin/contribute/{$nextPage}",
"action=update&reset=1&id={$this->_id}"
));
}
else {
CRM_Utils_System::redirect(CRM_Utils_System::url("civicrm/admin/contribute",
"reset=1"
));
}
}
else {
CRM_Utils_System::redirect(CRM_Utils_System::url("civicrm/admin/contribute", 'reset=1'));
}
}
}
/**
* Use the form name to create the tpl file name.
*
* @return string
*/
/**
* @return string
*/
public function getTemplateFileName() {
if ($this->controller->getPrint() || $this->getVar('_id') <= 0 ||
($this->_action & CRM_Core_Action::DELETE) ||
(CRM_Utils_String::getClassName($this->_name) == 'AddProduct')
) {
return parent::getTemplateFileName();
}
else {
// hack lets suppress the form rendering for now
self::$_template->assign('isForm', FALSE);
return 'CRM/Contribute/Form/ContributionPage/Tab.tpl';
}
}
}

View file

@ -0,0 +1,286 @@
<?php
/*
+--------------------------------------------------------------------+
| CiviCRM version 4.7 |
+--------------------------------------------------------------------+
| Copyright CiviCRM LLC (c) 2004-2017 |
+--------------------------------------------------------------------+
| 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 |
+--------------------------------------------------------------------+
*/
/**
*
* @package CRM
* @copyright CiviCRM LLC (c) 2004-2017
*/
/**
* form to process actions fo adding product to contribution page
*/
class CRM_Contribute_Form_ContributionPage_AddProduct extends CRM_Contribute_Form_ContributionPage {
protected $_products;
protected $_pid;
/**
* Pre process the form.
*/
public function preProcess() {
parent::preProcess();
$this->_products = CRM_Contribute_PseudoConstant::products($this->_id);
$this->_pid = CRM_Utils_Request::retrieve('pid', 'Positive',
$this, FALSE, 0
);
if ($this->_pid) {
$dao = new CRM_Contribute_DAO_PremiumsProduct();
$dao->id = $this->_pid;
$dao->find(TRUE);
$temp = CRM_Contribute_PseudoConstant::products();
$this->_products[$dao->product_id] = $temp[$dao->product_id];
}
//$this->_products = array_merge(array('' => '-- Select Product --') , $this->_products );
}
/**
* Set default values for the form.
*
* Note that in edit/view mode the default values are retrieved from the database.
*/
public function setDefaultValues() {
$defaults = array();
if ($this->_pid) {
$dao = new CRM_Contribute_DAO_PremiumsProduct();
$dao->id = $this->_pid;
$dao->find(TRUE);
$defaults['product_id'] = $dao->product_id;
$defaults['financial_type_id'] = $dao->financial_type_id;
$defaults['weight'] = $dao->weight;
}
else {
$dao = new CRM_Contribute_DAO_Product();
$dao->id = key($this->_products);
$dao->find(TRUE);
$defaults['financial_type_id'] = $dao->financial_type_id;
}
if (!isset($defaults['weight']) || !($defaults['weight'])) {
$pageID = CRM_Utils_Request::retrieve('id', 'Positive',
$this, FALSE, 0
);
$dao = new CRM_Contribute_DAO_Premium();
$dao->entity_table = 'civicrm_contribution_page';
$dao->entity_id = $pageID;
$dao->find(TRUE);
$premiumID = $dao->id;
$sql = 'SELECT max( weight ) as max_weight FROM civicrm_premiums_product WHERE premiums_id = %1';
$params = array(1 => array($premiumID, 'Integer'));
$dao = CRM_Core_DAO::executeQuery($sql, $params);
$dao->fetch();
$defaults['weight'] = $dao->max_weight + 1;
}
RETURN $defaults;
}
/**
* Build the form object.
*/
public function buildQuickForm() {
$urlParams = 'civicrm/admin/contribute/premium';
if ($this->_action & CRM_Core_Action::DELETE) {
$session = CRM_Core_Session::singleton();
$url = CRM_Utils_System::url($urlParams, 'reset=1&action=update&id=' . $this->_id);
$session->pushUserContext($url);
if (CRM_Utils_Request::retrieve('confirmed', 'Boolean',
CRM_Core_DAO::$_nullObject, '', '', 'GET'
)
) {
$dao = new CRM_Contribute_DAO_PremiumsProduct();
$dao->id = $this->_pid;
$dao->delete();
CRM_Core_Session::setStatus(ts('Selected Premium Product has been removed from this Contribution Page.'), ts('Saved'), 'success');
CRM_Utils_System::redirect($url);
}
$this->addButtons(array(
array(
'type' => 'next',
'name' => ts('Delete'),
'spacing' => '&nbsp;&nbsp;&nbsp;&nbsp;',
'isDefault' => TRUE,
),
array(
'type' => 'cancel',
'name' => ts('Cancel'),
),
)
);
return;
}
if ($this->_action & CRM_Core_Action::PREVIEW) {
CRM_Contribute_BAO_Premium::buildPremiumPreviewBlock($this, NULL, $this->_pid);
$this->addButtons(array(
array(
'type' => 'next',
'name' => ts('Done with Preview'),
'isDefault' => TRUE,
),
)
);
return;
}
$session = CRM_Core_Session::singleton();
$url = CRM_Utils_System::url($urlParams, 'reset=1&action=update&id=' . $this->_id);
$session->pushUserContext($url);
$this->add('select', 'product_id', ts('Select the Product') . ' ', $this->_products, TRUE);
$this->addElement('text', 'weight', ts('Order'), CRM_Core_DAO::getAttribute('CRM_Contribute_DAO_PremiumsProduct', 'weight'));
$financialType = CRM_Contribute_PseudoConstant::financialType();
$premiumFinancialType = array();
CRM_Core_PseudoConstant::populate(
$premiumFinancialType,
'CRM_Financial_DAO_EntityFinancialAccount',
$all = TRUE,
$retrieve = 'entity_id',
$filter = NULL,
'account_relationship = 8'
);
$costFinancialType = array();
CRM_Core_PseudoConstant::populate(
$costFinancialType,
'CRM_Financial_DAO_EntityFinancialAccount',
$all = TRUE,
$retrieve = 'entity_id',
$filter = NULL,
'account_relationship = 7'
);
$productFinancialType = array_intersect($costFinancialType, $premiumFinancialType);
foreach ($financialType as $key => $financialTypeName) {
if (!in_array($key, $productFinancialType)) {
unset($financialType[$key]);
}
}
// Check permissioned financial types
CRM_Financial_BAO_FinancialType::getAvailableFinancialTypes($financialType, CRM_Core_Action::ADD);
if (count($financialType)) {
$this->assign('financialType', $financialType);
}
$this->add(
'select',
'financial_type_id',
ts('Financial Type'),
array('' => ts('- select -')) + $financialType
);
$this->addRule('weight', ts('Please enter integer value for weight'), 'integer');
$session->pushUserContext(CRM_Utils_System::url($urlParams, 'action=update&reset=1&id=' . $this->_id));
if ($this->_single) {
$this->addButtons(array(
array(
'type' => 'next',
'name' => ts('Save'),
'spacing' => '&nbsp;&nbsp;&nbsp;&nbsp;',
'isDefault' => TRUE,
),
array(
'type' => 'cancel',
'name' => ts('Cancel'),
),
)
);
}
else {
parent::buildQuickForm();
}
}
/**
* Process the form.
*/
public function postProcess() {
// get the submitted form values.
$params = $this->controller->exportValues($this->_name);
$urlParams = 'civicrm/admin/contribute/premium';
if ($this->_action & CRM_Core_Action::PREVIEW) {
$session = CRM_Core_Session::singleton();
$url = CRM_Utils_System::url($urlParams, 'reset=1&action=update&id=' . $this->_id);
$single = $session->get('singleForm');
CRM_Utils_System::redirect($url);
return;
}
if ($this->_action & CRM_Core_Action::DELETE) {
$session = CRM_Core_Session::singleton();
$url = CRM_Utils_System::url($urlParams, 'reset=1&action=update&id=' . $this->_id);
$dao = new CRM_Contribute_DAO_PremiumsProduct();
$dao->id = $this->_pid;
$dao->delete();
CRM_Core_Session::setStatus(ts('Selected Premium Product has been removed from this Contribution Page.'), ts('Saved'), 'success');
CRM_Utils_System::redirect($url);
}
else {
$session = CRM_Core_Session::singleton();
$url = CRM_Utils_System::url($urlParams, 'reset=1&action=update&id=' . $this->_id);
if ($this->_pid) {
$params['id'] = $this->_pid;
}
$dao = new CRM_Contribute_DAO_Premium();
$dao->entity_table = 'civicrm_contribution_page';
$dao->entity_id = $this->_id;
$dao->find(TRUE);
$premiumID = $dao->id;
$params['premiums_id'] = $premiumID;
$oldWeight = NULL;
if ($this->_pid) {
$oldWeight = CRM_Core_DAO::getFieldValue('CRM_Contribute_DAO_PremiumsProduct', $this->_pid, 'weight', 'id');
}
// updateOtherWeights needs to filter on premiums_id
$filter = array('premiums_id' => $params['premiums_id']);
$params['weight'] = CRM_Utils_Weight::updateOtherWeights('CRM_Contribute_DAO_PremiumsProduct', $oldWeight, $params['weight'], $filter);
$dao = new CRM_Contribute_DAO_PremiumsProduct();
$dao->copyValues($params);
$dao->save();
CRM_Utils_System::redirect($url);
}
}
/**
* Return a descriptive name for the page, used in wizard header
*
* @return string
*/
public function getTitle() {
return ts('Add Premium to Contribution Page');
}
}

View file

@ -0,0 +1,843 @@
<?php
/*
+--------------------------------------------------------------------+
| CiviCRM version 4.7 |
+--------------------------------------------------------------------+
| Copyright CiviCRM LLC (c) 2004-2017 |
+--------------------------------------------------------------------+
| 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 |
+--------------------------------------------------------------------+
*/
/**
*
* @package CRM
* @copyright CiviCRM LLC (c) 2004-2017
*/
/**
* form to process actions on the group aspect of Custom Data
*/
class CRM_Contribute_Form_ContributionPage_Amount extends CRM_Contribute_Form_ContributionPage {
/**
* Contribution amount block.
*
* @var array
*/
protected $_amountBlock = array();
/**
* Constants for number of options for data types of multiple option.
*/
const NUM_OPTION = 11;
/**
* Build the form object.
*/
public function buildQuickForm() {
// do u want to allow a free form text field for amount
$this->addElement('checkbox', 'is_allow_other_amount', ts('Allow other amounts'), NULL, array('onclick' => "minMax(this);showHideAmountBlock( this, 'is_allow_other_amount' );"));
$this->add('text', 'min_amount', ts('Minimum Amount'), array('size' => 8, 'maxlength' => 8));
$this->addRule('min_amount', ts('Please enter a valid money value (e.g. %1).', array(1 => CRM_Utils_Money::format('9.99', ' '))), 'money');
$this->add('text', 'max_amount', ts('Maximum Amount'), array('size' => 8, 'maxlength' => 8));
$this->addRule('max_amount', ts('Please enter a valid money value (e.g. %1).', array(1 => CRM_Utils_Money::format('99.99', ' '))), 'money');
//CRM-12055
$this->add('text', 'amount_label', ts('Contribution Amounts Label'));
$default = array($this->createElement('radio', NULL, NULL, NULL, 0));
$this->add('hidden', "price_field_id", '', array('id' => "price_field_id"));
$this->add('hidden', "price_field_other", '', array('id' => "price_field_option"));
for ($i = 1; $i <= self::NUM_OPTION; $i++) {
// label
$this->add('text', "label[$i]", ts('Label'), CRM_Core_DAO::getAttribute('CRM_Core_DAO_OptionValue', 'label'));
$this->add('hidden', "price_field_value[$i]", '', array('id' => "price_field_value[$i]"));
// value
$this->add('text', "value[$i]", ts('Value'), CRM_Core_DAO::getAttribute('CRM_Core_DAO_OptionValue', 'value'));
$this->addRule("value[$i]", ts('Please enter a valid money value (e.g. %1).', array(1 => CRM_Utils_Money::format('99.99', ' '))), 'money');
// default
$default[] = $this->createElement('radio', NULL, NULL, NULL, $i);
}
$this->addGroup($default, 'default');
$this->addElement('checkbox', 'amount_block_is_active', ts('Contribution Amounts section enabled'), NULL, array('onclick' => "showHideAmountBlock( this, 'amount_block_is_active' );"));
$this->addElement('checkbox', 'is_monetary', ts('Execute real-time monetary transactions'));
$paymentProcessors = CRM_Financial_BAO_PaymentProcessor::getAllPaymentProcessors('live');
$recurringPaymentProcessor = $futurePaymentProcessor = $paymentProcessor = array();
if (!empty($paymentProcessors)) {
foreach ($paymentProcessors as $id => $processor) {
if ($id != 0) {
$paymentProcessor[$id] = $processor['name'];
}
if (CRM_Utils_Array::value('is_recur', $processor)) {
$recurringPaymentProcessor[] = $id;
}
if (CRM_Utils_Array::value('object', $processor) && $processor['object']->supports('FutureRecurStartDate')) {
$futurePaymentProcessor[] = $id;
}
}
}
if (count($recurringPaymentProcessor)) {
$this->assign('recurringPaymentProcessor', $recurringPaymentProcessor);
}
if (count($futurePaymentProcessor)) {
$this->assign('futurePaymentProcessor', $futurePaymentProcessor);
}
if (count($paymentProcessor)) {
$this->assign('paymentProcessor', $paymentProcessor);
}
$this->addCheckBox('payment_processor', ts('Payment Processor'),
array_flip($paymentProcessor),
NULL, NULL, NULL, NULL,
array('&nbsp;&nbsp;', '&nbsp;&nbsp;', '&nbsp;&nbsp;', '<br/>')
);
//check if selected payment processor supports recurring payment
if (!empty($recurringPaymentProcessor)) {
$this->addElement('checkbox', 'is_recur', ts('Recurring Contributions'), NULL,
array('onclick' => "showHideByValue('is_recur',true,'recurFields','table-row','radio',false);")
);
$this->addCheckBox('recur_frequency_unit', ts('Supported recurring units'),
CRM_Core_OptionGroup::values('recur_frequency_units', FALSE, FALSE, TRUE),
NULL, NULL, NULL, NULL,
array('&nbsp;&nbsp;', '&nbsp;&nbsp;', '&nbsp;&nbsp;', '<br/>'), TRUE
);
$this->addElement('checkbox', 'is_recur_interval', ts('Support recurring intervals'));
$this->addElement('checkbox', 'is_recur_installments', ts('Offer installments'));
}
// add pay later options
$this->addElement('checkbox', 'is_pay_later', ts('Pay later option'), NULL);
$this->addElement('textarea', 'pay_later_text', ts('Pay later label'),
CRM_Core_DAO::getAttribute('CRM_Contribute_DAO_ContributionPage', 'pay_later_text'),
FALSE
);
$this->add('wysiwyg', 'pay_later_receipt', ts('Pay Later Instructions'), CRM_Core_DAO::getAttribute('CRM_Contribute_DAO_ContributionPage', 'pay_later_receipt'));
$this->addElement('checkbox', 'is_billing_required', ts('Billing address required'));
//add partial payment options
// add price set fields
$price = CRM_Price_BAO_PriceSet::getAssoc(FALSE, 'CiviContribute');
if (CRM_Utils_System::isNull($price)) {
$this->assign('price', FALSE);
}
else {
$this->assign('price', TRUE);
}
$this->add('select', 'price_set_id', ts('Price Set'),
array(
'' => ts('- none -'),
) + $price,
NULL, array('onchange' => "showHideAmountBlock( this.value, 'price_set_id' );")
);
//CiviPledge fields.
$config = CRM_Core_Config::singleton();
if (in_array('CiviPledge', $config->enableComponents)) {
$this->assign('civiPledge', TRUE);
$this->addElement('checkbox', 'is_pledge_active', ts('Pledges'),
NULL, array('onclick' => "showHideAmountBlock( this, 'is_pledge_active' ); return showHideByValue('is_pledge_active',true,'pledgeFields','table-row','radio',false);")
);
$this->addCheckBox('pledge_frequency_unit', ts('Supported pledge frequencies'),
CRM_Core_OptionGroup::values('recur_frequency_units', FALSE, FALSE, TRUE),
NULL, NULL, NULL, NULL,
array('&nbsp;&nbsp;', '&nbsp;&nbsp;', '&nbsp;&nbsp;', '<br/>'), TRUE
);
$this->addElement('checkbox', 'is_pledge_interval', ts('Allow frequency intervals'));
$this->addElement('text', 'initial_reminder_day', ts('Send payment reminder'), array('size' => 3));
$this->addElement('text', 'max_reminders', ts('Send up to'), array('size' => 3));
$this->addElement('text', 'additional_reminder_day', ts('Send additional reminders'), array('size' => 3));
if (!empty($futurePaymentProcessor)) {
// CRM-18854
$this->addElement('checkbox', 'adjust_recur_start_date', ts('Adjust Recurring Start Date'), NULL,
array('onclick' => "showHideByValue('adjust_recur_start_date',true,'recurDefaults','table-row','radio',false);")
);
$this->addDate('pledge_calendar_date', ts('Specific Calendar Date'));
$month = CRM_Utils_Date::getCalendarDayOfMonth();
$this->add('select', 'pledge_calendar_month', ts('Specific day of Month'), $month);
$pledgeDefaults = array(
'contribution_date' => ts('Day of Contribution'),
'calendar_date' => ts('Specific Calendar Date'),
'calendar_month' => ts('Specific day of Month'),
);
$this->addRadio('pledge_default_toggle', ts('Recurring Contribution Start Date Default'), $pledgeDefaults, array('allowClear' => FALSE), '<br/><br/>');
$this->addElement('checkbox', 'is_pledge_start_date_visible', ts('Show Recurring Donation Start Date?'), NULL);
$this->addElement('checkbox', 'is_pledge_start_date_editable', ts('Allow Edits to Recurring Donation Start date?'), NULL);
}
}
//add currency element.
$this->addCurrency('currency', ts('Currency'));
$this->addFormRule(array('CRM_Contribute_Form_ContributionPage_Amount', 'formRule'), $this);
parent::buildQuickForm();
}
/**
* Set default values for the form. Note that in edit/view mode
* the default values are retrieved from the database
*
*
* @return array
*/
public function setDefaultValues() {
$defaults = parent::setDefaultValues();
if (empty($defaults['pay_later_text'])) {
$defaults['pay_later_text'] = ts('I will send payment by check');
}
if (!empty($defaults['amount_block_is_active'])) {
if ($priceSetId = CRM_Price_BAO_PriceSet::getFor('civicrm_contribution_page', $this->_id, NULL)) {
if ($isQuick = CRM_Core_DAO::getFieldValue('CRM_Price_DAO_PriceSet', $priceSetId, 'is_quick_config')) {
$this->assign('isQuick', $isQuick);
//$priceField = CRM_Core_DAO::getFieldValue( 'CRM_Price_DAO_PriceField', $priceSetId, 'id', 'price_set_id' );
$options = $pFIDs = array();
$priceFieldParams = array('price_set_id' => $priceSetId);
$priceFields = CRM_Core_DAO::commonRetrieveAll('CRM_Price_DAO_PriceField', 'price_set_id', $priceSetId, $pFIDs, $return = array(
'html_type',
'name',
'is_active',
'label',
));
foreach ($priceFields as $priceField) {
if ($priceField['id'] && $priceField['html_type'] == 'Radio' && $priceField['name'] == 'contribution_amount') {
$defaults['price_field_id'] = $priceField['id'];
$priceFieldOptions = CRM_Price_BAO_PriceFieldValue::getValues($priceField['id'], $options, 'id', 1);
if (empty($priceFieldOptions)) {
continue;
}
$countRow = 0;
$defaults['amount_label'] = $priceField['label'];
foreach ($options as $optionId => $optionValue) {
$countRow++;
$defaults['value'][$countRow] = $optionValue['amount'];
$defaults['label'][$countRow] = CRM_Utils_Array::value('label', $optionValue);
$defaults['name'][$countRow] = CRM_Utils_Array::value('name', $optionValue);
$defaults['weight'][$countRow] = $optionValue['weight'];
$defaults["price_field_value"][$countRow] = $optionValue['id'];
if ($optionValue['is_default']) {
$defaults['default'] = $countRow;
}
}
}
elseif ($priceField['id'] && $priceField['html_type'] == 'Text' && $priceField['name'] = 'other_amount' && $priceField['is_active']) {
$defaults['price_field_other'] = $priceField['id'];
if (!isset($defaults['amount_label'])) {
$defaults['amount_label'] = $priceField['label'];
}
}
}
}
}
if (empty($defaults['amount_label'])) {
$defaults['amount_label'] = ts('Contribution Amount');
}
if (!empty($defaults['value']) && is_array($defaults['value'])) {
// CRM-4038: fix value display
foreach ($defaults['value'] as & $amount) {
$amount = trim(CRM_Utils_Money::format($amount, ' '));
}
}
}
// fix the display of the monetary value, CRM-4038
if (isset($defaults['min_amount'])) {
$defaults['min_amount'] = CRM_Utils_Money::format($defaults['min_amount'], NULL, '%a');
}
if (isset($defaults['max_amount'])) {
$defaults['max_amount'] = CRM_Utils_Money::format($defaults['max_amount'], NULL, '%a');
}
if (!empty($defaults['payment_processor'])) {
$defaults['payment_processor'] = array_fill_keys(explode(CRM_Core_DAO::VALUE_SEPARATOR,
$defaults['payment_processor']
), '1');
}
return $defaults;
}
/**
* Global form rule.
*
* @param array $fields
* The input form values.
* @param array $files
* The uploaded files if any.
* @param $self
*
*
* @return bool|array
* true if no errors, else array of errors
*/
public static function formRule($fields, $files, $self) {
$errors = array();
//as for separate membership payment we has to have
//contribution amount section enabled, hence to disable it need to
//check if separate membership payment enabled,
//if so disable first separate membership payment option
//then disable contribution amount section. CRM-3801,
$membershipBlock = new CRM_Member_DAO_MembershipBlock();
$membershipBlock->entity_table = 'civicrm_contribution_page';
$membershipBlock->entity_id = $self->_id;
$membershipBlock->is_active = 1;
$hasMembershipBlk = FALSE;
if ($membershipBlock->find(TRUE)) {
if (!empty($fields['amount_block_is_active']) &&
($setID = CRM_Price_BAO_PriceSet::getFor('civicrm_contribution_page', $self->_id, NULL, 1))
) {
$extends = CRM_Core_DAO::getFieldValue('CRM_Price_DAO_PriceSet', $setID, 'extends');
if ($extends && $extends == CRM_Core_Component::getComponentID('CiviMember')) {
$errors['amount_block_is_active'] = ts('You cannot use a Membership Price Set when the Contribution Amounts section is enabled. Click the Memberships tab above, and select your Membership Price Set on that form. Membership Price Sets may include additional fields for non-membership options that require an additional fee (e.g. magazine subscription) or an additional voluntary contribution.');
return $errors;
}
}
$hasMembershipBlk = TRUE;
if ($membershipBlock->is_separate_payment && empty($fields['amount_block_is_active'])) {
$errors['amount_block_is_active'] = ts('To disable Contribution Amounts section you need to first disable Separate Membership Payment option from Membership Settings.');
}
//CRM-16165, Don't allow reccuring contribution if membership block contain any renewable membership option
$membershipTypes = unserialize($membershipBlock->membership_types);
if (!empty($fields['is_recur']) && !empty($membershipTypes)) {
if (!$membershipBlock->is_separate_payment) {
$errors['is_recur'] = ts('You need to enable Separate Membership Payment when online contribution page is configured for both Membership and Recurring Contribution.');
}
elseif (count(array_filter($membershipTypes)) != 0) {
$errors['is_recur'] = ts('You cannot enable both Recurring Contributions and Auto-renew memberships on the same online contribution page.');
}
}
}
// CRM-18854 Check if recurring start date is in the future.
if (CRM_Utils_Array::value('pledge_calendar_date', $fields)) {
if (date('Ymd') > date('Ymd', strtotime($fields['pledge_calendar_date']))) {
$errors['pledge_calendar_date'] = ts('The recurring start date cannot be prior to the current date.');
}
}
//check for the amount label (mandatory)
if (!empty($fields['amount_block_is_active']) && empty($fields['price_set_id']) && empty($fields['amount_label'])) {
$errors['amount_label'] = ts('Please enter the contribution amount label.');
}
$minAmount = CRM_Utils_Array::value('min_amount', $fields);
$maxAmount = CRM_Utils_Array::value('max_amount', $fields);
if (!empty($minAmount) && !empty($maxAmount)) {
$minAmount = CRM_Utils_Rule::cleanMoney($minAmount);
$maxAmount = CRM_Utils_Rule::cleanMoney($maxAmount);
if ((float ) $minAmount > (float ) $maxAmount) {
$errors['min_amount'] = ts('Minimum Amount should be less than Maximum Amount');
}
}
if (isset($fields['is_pay_later'])) {
if (empty($fields['pay_later_text'])) {
$errors['pay_later_text'] = ts('Please enter the text for the \'pay later\' checkbox displayed on the contribution form.');
}
if (empty($fields['pay_later_receipt'])) {
$errors['pay_later_receipt'] = ts('Please enter the instructions to be sent to the contributor when they choose to \'pay later\'.');
}
}
// don't allow price set w/ membership signup, CRM-5095
if ($priceSetId = CRM_Utils_Array::value('price_set_id', $fields)) {
// don't allow price set w/ membership.
if ($hasMembershipBlk) {
$errors['price_set_id'] = ts('You cannot enable both a Contribution Price Set and Membership Signup on the same online contribution page.');
}
}
else {
if (isset($fields['is_recur'])) {
if (empty($fields['recur_frequency_unit'])) {
$errors['recur_frequency_unit'] = ts('At least one recurring frequency option needs to be checked.');
}
}
// validation for pledge fields.
if (!empty($fields['is_pledge_active'])) {
if (empty($fields['pledge_frequency_unit'])) {
$errors['pledge_frequency_unit'] = ts('At least one pledge frequency option needs to be checked.');
}
if (!empty($fields['is_recur'])) {
$errors['is_recur'] = ts('You cannot enable both Recurring Contributions AND Pledges on the same online contribution page.');
}
}
// If Contribution amount section is enabled, then
// Allow other amounts must be enabled OR the Fixed Contribution
// Contribution options must contain at least one set of values.
if (!empty($fields['amount_block_is_active'])) {
if (empty($fields['is_allow_other_amount']) &&
!$priceSetId
) {
//get the values of amount block
$values = CRM_Utils_Array::value('value', $fields);
$isSetRow = FALSE;
for ($i = 1; $i < self::NUM_OPTION; $i++) {
if ((isset($values[$i]) && (strlen(trim($values[$i])) > 0))) {
$isSetRow = TRUE;
}
}
if (!$isSetRow) {
$errors['amount_block_is_active'] = ts('If you want to enable the \'Contribution Amounts section\', you need to either \'Allow Other Amounts\' and/or enter at least one row in the \'Fixed Contribution Amounts\' table.');
}
}
}
}
if (!empty($fields['payment_processor']) && $financialType = CRM_Contribute_BAO_Contribution::validateFinancialType($self->_defaultValues['financial_type_id'])) {
$errors['payment_processor'] = ts("Financial Account of account relationship of 'Expense Account is' is not configured for Financial Type : ") . $financialType;
}
if (!empty($fields['is_recur_interval'])) {
foreach (array_keys($fields['payment_processor']) as $paymentProcessorID) {
$paymentProcessorTypeId = CRM_Core_DAO::getFieldValue(
'CRM_Financial_DAO_PaymentProcessor',
$paymentProcessorID,
'payment_processor_type_id'
);
$paymentProcessorType = CRM_Core_PseudoConstant::paymentProcessorType(FALSE, $paymentProcessorTypeId, 'name');
}
}
return $errors;
}
/**
* Process the form.
*/
public function postProcess() {
// get the submitted form values.
$params = $this->controller->exportValues($this->_name);
//update 'is_billing_required'
if (empty($params['is_pay_later'])) {
$params['is_billing_required'] = 0;
}
if (array_key_exists('payment_processor', $params)) {
if (array_key_exists(CRM_Core_DAO::getFieldValue('CRM_Financial_DAO_PaymentProcessor', 'AuthNet',
'id', 'payment_processor_type_id'
),
CRM_Utils_Array::value('payment_processor', $params)
)) {
CRM_Core_Session::setStatus(ts(' Please note that the Authorize.net payment processor only allows recurring contributions and auto-renew memberships with payment intervals from 7-365 days or 1-12 months (i.e. not greater than 1 year).'), '', 'alert');
}
}
// check for price set.
$priceSetID = CRM_Utils_Array::value('price_set_id', $params);
// get required fields.
$fields = array(
'id' => $this->_id,
'is_recur' => FALSE,
'min_amount' => "null",
'max_amount' => "null",
'is_monetary' => FALSE,
'is_pay_later' => FALSE,
'is_billing_required' => FALSE,
'is_recur_interval' => FALSE,
'is_recur_installments' => FALSE,
'recur_frequency_unit' => "null",
'default_amount_id' => "null",
'is_allow_other_amount' => FALSE,
'amount_block_is_active' => FALSE,
);
$resetFields = array();
if ($priceSetID) {
$resetFields = array('min_amount', 'max_amount', 'is_allow_other_amount');
}
if (empty($params['is_recur'])) {
$resetFields = array_merge($resetFields, array('is_recur_interval', 'recur_frequency_unit'));
}
foreach ($fields as $field => $defaultVal) {
$val = CRM_Utils_Array::value($field, $params, $defaultVal);
if (in_array($field, $resetFields)) {
$val = $defaultVal;
}
if (in_array($field, array(
'min_amount',
'max_amount',
))) {
$val = CRM_Utils_Rule::cleanMoney($val);
}
$params[$field] = $val;
}
if ($params['is_recur']) {
$params['recur_frequency_unit'] = implode(CRM_Core_DAO::VALUE_SEPARATOR,
array_keys($params['recur_frequency_unit'])
);
$params['is_recur_interval'] = CRM_Utils_Array::value('is_recur_interval', $params, FALSE);
$params['is_recur_installments'] = CRM_Utils_Array::value('is_recur_installments', $params, FALSE);
}
if (CRM_Utils_Array::value('adjust_recur_start_date', $params)) {
$fieldValue = '';
$pledgeDateFields = array(
'calendar_date' => 'pledge_calendar_date',
'calendar_month' => 'pledge_calendar_month',
);
if ($params['pledge_default_toggle'] == 'contribution_date') {
$fieldValue = json_encode(array('contribution_date' => date('m/d/Y')));
}
else {
foreach ($pledgeDateFields as $key => $pledgeDateField) {
if (CRM_Utils_Array::value($pledgeDateField, $params) && $params['pledge_default_toggle'] == $key) {
$fieldValue = json_encode(array($key => $params[$pledgeDateField]));
break;
}
}
}
$params['pledge_start_date'] = $fieldValue;
}
else {
$params['pledge_start_date'] = '';
$params['adjust_recur_start_date'] = 0;
$params['is_pledge_start_date_visible'] = 0;
$params['is_pledge_start_date_editable'] = 0;
}
if (!CRM_Utils_Array::value('is_pledge_start_date_visible', $params)) {
$params['is_pledge_start_date_visible'] = 0;
}
if (!CRM_Utils_Array::value('is_pledge_start_date_editable', $params)) {
$params['is_pledge_start_date_editable'] = 0;
}
if (array_key_exists('payment_processor', $params) &&
!CRM_Utils_System::isNull($params['payment_processor'])
) {
$params['payment_processor'] = implode(CRM_Core_DAO::VALUE_SEPARATOR, array_keys($params['payment_processor']));
}
else {
$params['payment_processor'] = 'null';
}
$contributionPage = CRM_Contribute_BAO_ContributionPage::create($params);
$contributionPageID = $contributionPage->id;
// prepare for data cleanup.
$deleteAmountBlk = $deletePledgeBlk = $deletePriceSet = FALSE;
if ($this->_priceSetID) {
$deletePriceSet = TRUE;
}
if ($this->_pledgeBlockID) {
$deletePledgeBlk = TRUE;
}
if (!empty($this->_amountBlock)) {
$deleteAmountBlk = TRUE;
}
if ($contributionPageID) {
if (!empty($params['amount_block_is_active'])) {
// handle price set.
if ($priceSetID) {
// add/update price set.
$deletePriceSet = FALSE;
if (!empty($params['price_field_id']) || !empty($params['price_field_other'])) {
$deleteAmountBlk = TRUE;
}
CRM_Price_BAO_PriceSet::addTo('civicrm_contribution_page', $contributionPageID, $priceSetID);
}
else {
$deletePriceSet = FALSE;
// process contribution amount block
$deleteAmountBlk = FALSE;
$labels = CRM_Utils_Array::value('label', $params);
$values = CRM_Utils_Array::value('value', $params);
$default = CRM_Utils_Array::value('default', $params);
$options = array();
for ($i = 1; $i < self::NUM_OPTION; $i++) {
if (isset($values[$i]) &&
(strlen(trim($values[$i])) > 0)
) {
$options[] = array(
'label' => trim($labels[$i]),
'value' => CRM_Utils_Rule::cleanMoney(trim($values[$i])),
'weight' => $i,
'is_active' => 1,
'is_default' => $default == $i,
);
}
}
/* || !empty($params['price_field_value']) || CRM_Utils_Array::value( 'price_field_other', $params )*/
if (!empty($options) || !empty($params['is_allow_other_amount'])) {
$fieldParams['is_quick_config'] = 1;
$noContriAmount = NULL;
$usedPriceSetId = CRM_Price_BAO_PriceSet::getFor('civicrm_contribution_page', $this->_id, 3);
if (!(!empty($params['price_field_id']) || !empty($params['price_field_other'])) && !$usedPriceSetId) {
$pageTitle = strtolower(CRM_Utils_String::munge($this->_values['title'], '_', 245));
$setParams['title'] = $this->_values['title'];
if (!CRM_Core_DAO::getFieldValue('CRM_Price_BAO_PriceSet', $pageTitle, 'id', 'name')) {
$setParams['name'] = $pageTitle;
}
elseif (!CRM_Core_DAO::getFieldValue('CRM_Price_BAO_PriceSet', $pageTitle . '_' . $this->_id, 'id', 'name')) {
$setParams['name'] = $pageTitle . '_' . $this->_id;
}
else {
$timeSec = explode(".", microtime(TRUE));
$setParams['name'] = $pageTitle . '_' . date('is', $timeSec[0]) . $timeSec[1];
}
$setParams['is_quick_config'] = 1;
$setParams['financial_type_id'] = CRM_Utils_Array::value('financial_type_id', $this->_values);
$setParams['extends'] = CRM_Core_Component::getComponentID('CiviContribute');
$priceSet = CRM_Price_BAO_PriceSet::create($setParams);
$priceSetId = $priceSet->id;
}
elseif ($usedPriceSetId && empty($params['price_field_id'])) {
$priceSetId = $usedPriceSetId;
}
else {
if ($priceFieldId = CRM_Utils_Array::value('price_field_id', $params)) {
foreach ($params['price_field_value'] as $arrayID => $fieldValueID) {
if (empty($params['label'][$arrayID]) && empty($params['value'][$arrayID]) && !empty($fieldValueID)) {
CRM_Price_BAO_PriceFieldValue::setIsActive($fieldValueID, '0');
unset($params['price_field_value'][$arrayID]);
}
}
if (implode('', $params['price_field_value'])) {
$fieldParams['id'] = CRM_Utils_Array::value('price_field_id', $params);
$fieldParams['option_id'] = $params['price_field_value'];
}
else {
$noContriAmount = 0;
CRM_Price_BAO_PriceField::setIsActive($priceFieldId, '0');
}
}
else {
$priceFieldId = CRM_Utils_Array::value('price_field_other', $params);
}
$priceSetId = CRM_Core_DAO::getFieldValue('CRM_Price_DAO_PriceField', $priceFieldId, 'price_set_id');
}
CRM_Price_BAO_PriceSet::addTo('civicrm_contribution_page', $this->_id, $priceSetId);
if (!empty($options)) {
$editedFieldParams = array(
'price_set_id' => $priceSetId,
'name' => 'contribution_amount',
);
$editedResults = array();
$noContriAmount = 1;
CRM_Price_BAO_PriceField::retrieve($editedFieldParams, $editedResults);
if (empty($editedResults['id'])) {
$fieldParams['name'] = strtolower(CRM_Utils_String::munge("Contribution Amount", '_', 245));
}
else {
$fieldParams['id'] = CRM_Utils_Array::value('id', $editedResults);
}
$fieldParams['price_set_id'] = $priceSetId;
$fieldParams['is_active'] = 1;
$fieldParams['weight'] = 2;
if (!empty($params['is_allow_other_amount'])) {
$fieldParams['is_required'] = 0;
}
else {
$fieldParams['is_required'] = 1;
}
$fieldParams['label'] = $params['amount_label'];
$fieldParams['html_type'] = 'Radio';
$fieldParams['option_label'] = $params['label'];
$fieldParams['option_amount'] = $params['value'];
$fieldParams['financial_type_id'] = CRM_Utils_Array::value('financial_type_id', $this->_values);
foreach ($options as $value) {
$fieldParams['option_weight'][$value['weight']] = $value['weight'];
}
$fieldParams['default_option'] = $params['default'];
$priceField = CRM_Price_BAO_PriceField::create($fieldParams);
}
if (!empty($params['is_allow_other_amount']) && empty($params['price_field_other'])) {
$editedFieldParams = array(
'price_set_id' => $priceSetId,
'name' => 'other_amount',
);
$editedResults = array();
CRM_Price_BAO_PriceField::retrieve($editedFieldParams, $editedResults);
if (!$priceFieldID = CRM_Utils_Array::value('id', $editedResults)) {
$fieldParams = array(
'name' => 'other_amount',
'label' => ts('Other Amount'),
'price_set_id' => $priceSetId,
'html_type' => 'Text',
'financial_type_id' => CRM_Utils_Array::value('financial_type_id', $this->_values),
'is_display_amounts' => 0,
'weight' => 3,
);
$fieldParams['option_weight'][1] = 1;
$fieldParams['option_amount'][1] = 1;
if (!$noContriAmount) {
$fieldParams['is_required'] = 1;
$fieldParams['option_label'][1] = $fieldParams['label'] = $params['amount_label'];
}
else {
$fieldParams['is_required'] = 0;
$fieldParams['option_label'][1] = $fieldParams['label'] = ts('Other Amount');
}
$priceField = CRM_Price_BAO_PriceField::create($fieldParams);
}
else {
if (empty($editedResults['is_active'])) {
$fieldParams = $editedResults;
if (!$noContriAmount) {
$priceFieldValueID = CRM_Core_DAO::getFieldValue('CRM_Price_DAO_PriceFieldValue', $priceFieldID, 'id', 'price_field_id');
CRM_Core_DAO::setFieldValue('CRM_Price_DAO_PriceFieldValue', $priceFieldValueID, 'label', $params['amount_label']);
$fieldParams = array(
'is_required' => 1,
'label' => $params['amount_label'],
'id' => $priceFieldID,
);
}
$fieldParams['is_active'] = 1;
$priceField = CRM_Price_BAO_PriceField::add($fieldParams);
}
}
}
elseif (empty($params['is_allow_other_amount']) && !empty($params['price_field_other'])) {
CRM_Price_BAO_PriceField::setIsActive($params['price_field_other'], '0');
}
elseif ($priceFieldID = CRM_Utils_Array::value('price_field_other', $params)) {
$priceFieldValueID = CRM_Core_DAO::getFieldValue('CRM_Price_DAO_PriceFieldValue', $priceFieldID, 'id', 'price_field_id');
if (!$noContriAmount) {
$fieldParams = array(
'is_required' => 1,
'label' => $params['amount_label'],
'id' => $priceFieldID,
);
CRM_Price_BAO_PriceField::add($fieldParams);
CRM_Core_DAO::setFieldValue('CRM_Price_DAO_PriceFieldValue', $priceFieldValueID, 'label', $params['amount_label']);
}
else {
CRM_Core_DAO::setFieldValue('CRM_Price_DAO_PriceField', $priceFieldID, 'is_required', 0);
CRM_Core_DAO::setFieldValue('CRM_Price_DAO_PriceFieldValue', $priceFieldValueID, 'label', ts('Other Amount'));
}
}
}
if (!empty($params['is_pledge_active'])) {
$deletePledgeBlk = FALSE;
$pledgeBlockParams = array(
'entity_id' => $contributionPageID,
'entity_table' => ts('civicrm_contribution_page'),
);
if ($this->_pledgeBlockID) {
$pledgeBlockParams['id'] = $this->_pledgeBlockID;
}
$pledgeBlock = array(
'pledge_frequency_unit',
'max_reminders',
'initial_reminder_day',
'additional_reminder_day',
'pledge_start_date',
'is_pledge_start_date_visible',
'is_pledge_start_date_editable',
);
foreach ($pledgeBlock as $key) {
$pledgeBlockParams[$key] = CRM_Utils_Array::value($key, $params);
}
$pledgeBlockParams['is_pledge_interval'] = CRM_Utils_Array::value('is_pledge_interval',
$params, FALSE
);
$pledgeBlockParams['pledge_start_date'] = CRM_Utils_Array::value('pledge_start_date',
$params, FALSE
);
// create pledge block.
CRM_Pledge_BAO_PledgeBlock::create($pledgeBlockParams);
}
}
}
else {
if (!empty($params['price_field_id']) || !empty($params['price_field_other'])) {
$usedPriceSetId = CRM_Price_BAO_PriceSet::getFor('civicrm_contribution_page', $this->_id, 3);
if ($usedPriceSetId) {
if (!empty($params['price_field_id'])) {
CRM_Price_BAO_PriceField::setIsActive($params['price_field_id'], '0');
}
if (!empty($params['price_field_other'])) {
CRM_Price_BAO_PriceField::setIsActive($params['price_field_other'], '0');
}
}
else {
$deleteAmountBlk = TRUE;
$deletePriceSet = TRUE;
}
}
}
// delete pledge block.
if ($deletePledgeBlk) {
CRM_Pledge_BAO_PledgeBlock::deletePledgeBlock($this->_pledgeBlockID);
}
// delete previous price set.
if ($deletePriceSet) {
CRM_Price_BAO_PriceSet::removeFrom('civicrm_contribution_page', $contributionPageID);
}
if ($deleteAmountBlk) {
$priceField = !empty($params['price_field_id']) ? $params['price_field_id'] : CRM_Utils_Array::value('price_field_other', $params);
if ($priceField) {
$priceSetID = CRM_Core_DAO::getFieldValue('CRM_Price_DAO_PriceField', $priceField, 'price_set_id');
CRM_Price_BAO_PriceSet::setIsQuickConfig($priceSetID, 0);
}
}
}
parent::endPostProcess();
}
/**
* Return a descriptive name for the page, used in wizard header
*
* @return string
*/
public function getTitle() {
return ts('Amounts');
}
}

View file

@ -0,0 +1,208 @@
<?php
/*
+--------------------------------------------------------------------+
| CiviCRM version 4.7 |
+--------------------------------------------------------------------+
| Copyright CiviCRM LLC (c) 2004-2017 |
+--------------------------------------------------------------------+
| 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 |
+--------------------------------------------------------------------+
*/
/**
* @package CRM
* @copyright CiviCRM LLC (c) 2004-2017
*/
/**
* Form to process actions on the group aspect of Custom Data.
*/
class CRM_Contribute_Form_ContributionPage_Custom extends CRM_Contribute_Form_ContributionPage {
/**
* Build the form object.
*/
public function buildQuickForm() {
// Register 'contact_1' model
$entities = array();
$entities[] = array('entity_name' => 'contact_1', 'entity_type' => 'IndividualModel');
$allowCoreTypes = array_merge(array('Contact', 'Individual'), CRM_Contact_BAO_ContactType::subTypes('Individual'));
$allowSubTypes = array();
// Register 'contribution_1'
$financialTypeId = CRM_Core_DAO::getFieldValue('CRM_Contribute_DAO_ContributionPage', $this->_id, 'financial_type_id');
$allowCoreTypes[] = 'Contribution';
//CRM-15427
$allowSubTypes['ContributionType'] = array($financialTypeId);
$entities[] = array(
'entity_name' => 'contribution_1',
'entity_type' => 'ContributionModel',
'entity_sub_type' => '*',
);
// If applicable, register 'membership_1'
$member = CRM_Member_BAO_Membership::getMembershipBlock($this->_id);
if ($member && $member['is_active']) {
//CRM-15427
$entities[] = array(
'entity_name' => 'membership_1',
'entity_type' => 'MembershipModel',
'entity_sub_type' => '*',
);
$allowCoreTypes[] = 'Membership';
$allowSubTypes['MembershipType'] = explode(',', $member['membership_types']);
}
//CRM-15427
$this->addProfileSelector('custom_pre_id', ts('Include Profile') . '<br />' . ts('(top of page)'), $allowCoreTypes, $allowSubTypes, $entities, TRUE);
$this->addProfileSelector('custom_post_id', ts('Include Profile') . '<br />' . ts('(bottom of page)'), $allowCoreTypes, $allowSubTypes, $entities, TRUE);
$this->addFormRule(array('CRM_Contribute_Form_ContributionPage_Custom', 'formRule'), $this);
parent::buildQuickForm();
}
/**
* Set default values for the form.
*
* Note that in edit/view mode the default values are retrieved from the database.
*/
public function setDefaultValues() {
$defaults = parent::setDefaultValues();
$defaults['custom_pre_id'] = $this->_values['custom_pre_id'];
$defaults['custom_post_id'] = $this->_values['custom_post_id'];
return $defaults;
}
/**
* Process the form.
*/
public function postProcess() {
// get the submitted form values.
$params = $this->controller->exportValues($this->_name);
if ($this->_action & CRM_Core_Action::UPDATE) {
$params['id'] = $this->_id;
}
$transaction = new CRM_Core_Transaction();
// also update uf join table
$ufJoinParams = array(
'is_active' => 1,
'module' => 'CiviContribute',
'entity_table' => 'civicrm_contribution_page',
'entity_id' => $this->_id,
);
// first delete all past entries
CRM_Core_BAO_UFJoin::deleteAll($ufJoinParams);
if (!empty($params['custom_pre_id'])) {
$ufJoinParams['weight'] = 1;
$ufJoinParams['uf_group_id'] = $params['custom_pre_id'];
CRM_Core_BAO_UFJoin::create($ufJoinParams);
}
unset($ufJoinParams['id']);
if (!empty($params['custom_post_id'])) {
$ufJoinParams['weight'] = 2;
$ufJoinParams['uf_group_id'] = $params['custom_post_id'];
CRM_Core_BAO_UFJoin::create($ufJoinParams);
}
$transaction->commit();
parent::endPostProcess();
}
/**
* Return a descriptive name for the page, used in wizard header
*
* @return string
*/
public function getTitle() {
return ts('Include Profiles');
}
/**
* Global form rule.
*
* @param array $fields
* The input form values.
*
* @param $files
* @param object $form
*
* @return bool|array
* true if no errors, else array of errors
*/
public static function formRule($fields, $files, $form) {
$errors = array();
$preProfileType = $postProfileType = NULL;
// for membership profile make sure Membership section is enabled
// get membership section for this contribution page
$dao = new CRM_Member_DAO_MembershipBlock();
$dao->entity_table = 'civicrm_contribution_page';
$dao->entity_id = $form->_id;
$membershipEnable = FALSE;
if ($dao->find(TRUE) && $dao->is_active) {
$membershipEnable = TRUE;
}
if ($fields['custom_pre_id']) {
$preProfileType = CRM_Core_BAO_UFField::getProfileType($fields['custom_pre_id']);
}
if ($fields['custom_post_id']) {
$postProfileType = CRM_Core_BAO_UFField::getProfileType($fields['custom_post_id']);
}
$errorMsg = ts('You must enable the Membership Block for this Contribution Page if you want to include a Profile with Membership fields.');
if (($preProfileType == 'Membership') && !$membershipEnable) {
$errors['custom_pre_id'] = $errorMsg;
}
if (($postProfileType == 'Membership') && !$membershipEnable) {
$errors['custom_post_id'] = $errorMsg;
}
$behalf = (!empty($form->_values['onbehalf_profile_id'])) ? $form->_values['onbehalf_profile_id'] : NULL;
if ($fields['custom_pre_id']) {
$errorMsg = ts('You should move the membership related fields in the "On Behalf" profile for this Contribution Page');
if ($preProfileType == 'Membership' && $behalf) {
$errors['custom_pre_id'] = isset($errors['custom_pre_id']) ? $errors['custom_pre_id'] . $errorMsg : $errorMsg;
}
}
if ($fields['custom_post_id']) {
$errorMsg = ts('You should move the membership related fields in the "On Behalf" profile for this Contribution Page');
if ($postProfileType == 'Membership' && $behalf) {
$errors['custom_post_id'] = isset($errors['custom_post_id']) ? $errors['custom_post_id'] . $errorMsg : $errorMsg;
}
}
return empty($errors) ? TRUE : $errors;
}
}

View file

@ -0,0 +1,143 @@
<?php
/*
+--------------------------------------------------------------------+
| CiviCRM version 4.7 |
+--------------------------------------------------------------------+
| Copyright CiviCRM LLC (c) 2004-2017 |
+--------------------------------------------------------------------+
| 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 |
+--------------------------------------------------------------------+
*/
/**
*
* @package CRM
* @copyright CiviCRM LLC (c) 2004-2017
*/
/**
* This class is to build the form for Deleting Group.
*/
class CRM_Contribute_Form_ContributionPage_Delete extends CRM_Contribute_Form_ContributionPage {
/**
* Page title.
*
* @var string
*/
protected $_title;
/**
* Check if there are any related contributions.
*/
protected $_relatedContributions;
/**
* Set variables up before form is built.
*/
public function preProcess() {
//Check if there are contributions related to Contribution Page
parent::preProcess();
//check for delete
if (!CRM_Core_Permission::checkActionPermission('CiviContribute', $this->_action)) {
CRM_Core_Error::fatal(ts('You do not have permission to access this page.'));
}
$dao = new CRM_Contribute_DAO_Contribution();
$dao->contribution_page_id = $this->_id;
if ($dao->find(TRUE)) {
$this->_relatedContributions = TRUE;
$this->assign('relatedContributions', TRUE);
}
}
/**
* Build the form object.
*/
public function buildQuickForm() {
$this->_title = CRM_Core_DAO::getFieldValue('CRM_Contribute_DAO_ContributionPage', $this->_id, 'title');
$this->assign('title', $this->_title);
//if there are contributions related to Contribution Page
//then onle cancel button is displayed
$buttons = array();
if (!$this->_relatedContributions) {
$buttons[] = array(
'type' => 'next',
'name' => ts('Delete Contribution Page'),
'isDefault' => TRUE,
);
}
$buttons[] = array(
'type' => 'cancel',
'name' => ts('Cancel'),
);
$this->addButtons($buttons);
}
/**
* Process the form when submitted.
*/
public function postProcess() {
$transaction = new CRM_Core_Transaction();
// first delete the join entries associated with this contribution page
$dao = new CRM_Core_DAO_UFJoin();
$params = array(
'entity_table' => 'civicrm_contribution_page',
'entity_id' => $this->_id,
);
$dao->copyValues($params);
$dao->delete();
//next delete the membership block fields
$dao = new CRM_Member_DAO_MembershipBlock();
$dao->entity_table = 'civicrm_contribution_page';
$dao->entity_id = $this->_id;
$dao->delete();
//next delete the pcp block fields
$dao = new CRM_PCP_DAO_PCPBlock();
$dao->entity_table = 'civicrm_contribution_page';
$dao->entity_id = $this->_id;
$dao->delete();
// need to delete premiums. CRM-4586
CRM_Contribute_BAO_Premium::deletePremium($this->_id);
// price set cleanup, CRM-5527
CRM_Price_BAO_PriceSet::removeFrom('civicrm_contribution_page', $this->_id);
// finally delete the contribution page
$dao = new CRM_Contribute_DAO_ContributionPage();
$dao->id = $this->_id;
$dao->delete();
$transaction->commit();
CRM_Core_Session::setStatus(ts("The contribution page '%1' has been deleted.", array(1 => $this->_title)), ts('Deleted'), 'success');
}
}

View file

@ -0,0 +1,158 @@
<?php
/*
+--------------------------------------------------------------------+
| CiviCRM version 4.7 |
+--------------------------------------------------------------------+
| Copyright CiviCRM LLC (c) 2004-2017 |
+--------------------------------------------------------------------+
| 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 |
+--------------------------------------------------------------------+
*/
/**
*
* @package CRM
* @copyright CiviCRM LLC (c) 2004-2017
*/
/**
* Form to process actions on Premiums.
*/
class CRM_Contribute_Form_ContributionPage_Premium extends CRM_Contribute_Form_ContributionPage {
/**
* Set default values for the form.
*/
public function setDefaultValues() {
$defaults = array();
if (isset($this->_id)) {
$dao = new CRM_Contribute_DAO_Premium();
$dao->entity_table = 'civicrm_contribution_page';
$dao->entity_id = $this->_id;
$dao->find(TRUE);
CRM_Core_DAO::storeValues($dao, $defaults);
}
return $defaults;
}
/**
* Build the form object.
*/
public function buildQuickForm() {
$attributes = CRM_Core_DAO::getAttribute('CRM_Contribute_DAO_Premium');
$this->addElement('checkbox', 'premiums_active', ts('Premiums Section Enabled?'), NULL);
$this->addElement('text', 'premiums_intro_title', ts('Title'), $attributes['premiums_intro_title']);
$this->add('textarea', 'premiums_intro_text', ts('Introductory Message'), 'rows=5, cols=50');
$this->add('text', 'premiums_contact_email', ts('Contact Email') . ' ', $attributes['premiums_contact_email']);
$this->addRule('premiums_contact_email', ts('Please enter a valid email address.') . ' ', 'email');
$this->add('text', 'premiums_contact_phone', ts('Contact Phone'), $attributes['premiums_contact_phone']);
$this->addRule('premiums_contact_phone', ts('Please enter a valid phone number.'), 'phone');
$this->addElement('checkbox', 'premiums_display_min_contribution', ts('Display Minimum Contribution Amount?'));
// CRM-10999 Control label and position for No Thank-you radio button
$this->add('text', 'premiums_nothankyou_label', ts('No Thank-you Label'), $attributes['premiums_nothankyou_label']);
$positions = array(1 => ts('Before Premiums'), 2 => ts('After Premiums'));
$this->add('select', 'premiums_nothankyou_position', ts('No Thank-you Option'), $positions);
$showForm = TRUE;
if ($this->_single) {
if ($this->_id) {
$daoPremium = new CRM_Contribute_DAO_Premium();
$daoPremium->entity_id = $this->_id;
$daoPremium->entity_table = 'civicrm_contribution_page';
$daoPremium->premiums_active = 1;
if ($daoPremium->find(TRUE)) {
$showForm = FALSE;
}
}
}
$this->assign('showForm', $showForm);
parent::buildQuickForm();
$this->addFormRule(array('CRM_Contribute_Form_ContributionPage_Premium', 'formRule'), $this);
$premiumPage = new CRM_Contribute_Page_Premium();
$premiumPage->browse();
}
/**
* Validation.
*
* @param array $params
* (ref.) an assoc array of name/value pairs.
*
* @return bool|array
* mixed true or array of errors
*/
public static function formRule($params) {
$errors = array();
if (!empty($params['premiums_active'])) {
if (empty($params['premiums_nothankyou_label'])) {
$errors['premiums_nothankyou_label'] = ts('No Thank-you Label is a required field.');
}
}
return empty($errors) ? TRUE : $errors;
}
/**
* Process the form.
*/
public function postProcess() {
// get the submitted form values.
$params = $this->controller->exportValues($this->_name);
// we do this in case the user has hit the forward/back button
$dao = new CRM_Contribute_DAO_Premium();
$dao->entity_table = 'civicrm_contribution_page';
$dao->entity_id = $this->_id;
$dao->find(TRUE);
$premiumID = $dao->id;
if ($premiumID) {
$params['id'] = $premiumID;
}
$params['premiums_active'] = CRM_Utils_Array::value('premiums_active', $params, FALSE);
$params['premiums_display_min_contribution'] = CRM_Utils_Array::value('premiums_display_min_contribution', $params, FALSE);
$params['entity_table'] = 'civicrm_contribution_page';
$params['entity_id'] = $this->_id;
$dao = new CRM_Contribute_DAO_Premium();
$dao->copyValues($params);
$dao->save();
parent::endPostProcess();
}
/**
* Return a descriptive name for the page, used in wizard header
*
* @return string
*/
public function getTitle() {
return ts('Premiums');
}
}

View file

@ -0,0 +1,427 @@
<?php
/*
+--------------------------------------------------------------------+
| CiviCRM version 4.7 |
+--------------------------------------------------------------------+
| Copyright CiviCRM LLC (c) 2004-2017 |
+--------------------------------------------------------------------+
| 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 |
+--------------------------------------------------------------------+
*/
/**
*
* @package CRM
* @copyright CiviCRM LLC (c) 2004-2017
*/
class CRM_Contribute_Form_ContributionPage_Settings extends CRM_Contribute_Form_ContributionPage {
/**
* Set variables up before form is built.
*/
public function preProcess() {
parent::preProcess();
}
/**
* Set default values for the form.
*/
public function setDefaultValues() {
$defaults = parent::setDefaultValues();
$soft_credit_types = CRM_Core_OptionGroup::values('soft_credit_type', TRUE, FALSE, FALSE, NULL, 'name');
if ($this->_id) {
$title = CRM_Core_DAO::getFieldValue('CRM_Contribute_DAO_ContributionPage',
$this->_id,
'title'
);
CRM_Utils_System::setTitle(ts('Title and Settings') . " ($title)");
foreach (array('on_behalf', 'soft_credit') as $module) {
$ufJoinDAO = new CRM_Core_DAO_UFJoin();
$ufJoinDAO->module = $module;
$ufJoinDAO->entity_id = $this->_id;
$ufJoinDAO->entity_table = 'civicrm_contribution_page';
if ($ufJoinDAO->find(TRUE)) {
$jsonData = CRM_Contribute_BAO_ContributionPage::formatModuleData($ufJoinDAO->module_data, TRUE, $module);
if ($module == 'soft_credit') {
$defaults['honoree_profile'] = $ufJoinDAO->uf_group_id;
$defaults = array_merge($defaults, $jsonData);
$defaults['honor_block_is_active'] = $ufJoinDAO->is_active;
}
else {
$defaults['onbehalf_profile_id'] = $ufJoinDAO->uf_group_id;
$defaults = array_merge($defaults, $jsonData);
$defaults['is_organization'] = $ufJoinDAO->is_active;
}
}
else {
if ($module == 'soft_credit') {
$ufGroupDAO = new CRM_Core_DAO_UFGroup();
$ufGroupDAO->name = 'honoree_individual';
if ($ufGroupDAO->find(TRUE)) {
$defaults['honoree_profile'] = $ufGroupDAO->id;
}
$defaults['soft_credit_types'] = array(
CRM_Utils_Array::value('in_honor_of', $soft_credit_types),
CRM_Utils_Array::value('in_memory_of', $soft_credit_types),
);
}
else {
$ufGroupDAO = new CRM_Core_DAO_UFGroup();
$ufGroupDAO->name = 'on_behalf_organization';
if ($ufGroupDAO->find(TRUE)) {
$defaults['onbehalf_profile_id'] = $ufGroupDAO->id;
}
$defaults['for_organization'] = ts('I am contributing on behalf of an organization.');
$defaults['is_for_organization'] = 1;
}
}
}
}
else {
$ufGroupDAO = new CRM_Core_DAO_UFGroup();
$ufGroupDAO->name = 'honoree_individual';
if ($ufGroupDAO->find(TRUE)) {
$defaults['honoree_profile'] = $ufGroupDAO->id;
}
$defaults['soft_credit_types'] = array(
CRM_Utils_Array::value('in_honor_of', $soft_credit_types),
CRM_Utils_Array::value('in_memory_of', $soft_credit_types),
);
}
return $defaults;
}
/**
* Build the form object.
*/
public function buildQuickForm() {
$this->_first = TRUE;
$attributes = CRM_Core_DAO::getAttribute('CRM_Contribute_DAO_ContributionPage');
// financial Type
CRM_Financial_BAO_FinancialType::getAvailableFinancialTypes($financialTypes, CRM_Core_Action::ADD);
$financialOptions = array(
'options' => $financialTypes,
);
if (!CRM_Core_Permission::check('administer CiviCRM Financial Types')) {
$financialOptions['context'] = 'search';
}
$this->addSelect('financial_type_id', $financialOptions, TRUE);
// name
$this->add('text', 'title', ts('Title'), $attributes['title'], TRUE);
//CRM-7362 --add campaigns.
CRM_Campaign_BAO_Campaign::addCampaign($this, CRM_Utils_Array::value('campaign_id', $this->_values));
$this->add('wysiwyg', 'intro_text', ts('Introductory Message'), $attributes['intro_text']);
$this->add('wysiwyg', 'footer_text', ts('Footer Message'), $attributes['footer_text']);
//Register schema which will be used for OnBehalOf and HonorOf profile Selector
CRM_UF_Page_ProfileEditor::registerSchemas(array('OrganizationModel', 'HouseholdModel'));
// is on behalf of an organization ?
$this->addElement('checkbox', 'is_organization', ts('Allow individuals to contribute and / or signup for membership on behalf of an organization?'), NULL, array('onclick' => "showHideByValue('is_organization',true,'for_org_text','table-row','radio',false);showHideByValue('is_organization',true,'for_org_option','table-row','radio',false);"));
//CRM-15787 - If applicable, register 'membership_1'
$member = CRM_Member_BAO_Membership::getMembershipBlock($this->_id);
$coreTypes = array('Contact', 'Organization');
$entities[] = array(
'entity_name' => array('contact_1'),
'entity_type' => 'OrganizationModel',
);
if ($member && $member['is_active']) {
$coreTypes[] = 'Membership';
$entities[] = array(
'entity_name' => array('membership_1'),
'entity_type' => 'MembershipModel',
);
}
$allowCoreTypes = array_merge($coreTypes, CRM_Contact_BAO_ContactType::subTypes('Organization'));
$allowSubTypes = array();
$this->addProfileSelector('onbehalf_profile_id', ts('Organization Profile'), $allowCoreTypes, $allowSubTypes, $entities);
$options = array();
$options[] = $this->createElement('radio', NULL, NULL, ts('Optional'), 1);
$options[] = $this->createElement('radio', NULL, NULL, ts('Required'), 2);
$this->addGroup($options, 'is_for_organization', '');
$this->add('textarea', 'for_organization', ts('On behalf of Label'), array('rows' => 2, 'cols' => 50));
// collect goal amount
$this->add('text', 'goal_amount', ts('Goal Amount'), array('size' => 8, 'maxlength' => 12));
$this->addRule('goal_amount', ts('Please enter a valid money value (e.g. %1).', array(1 => CRM_Utils_Money::format('99.99', ' '))), 'money');
// is confirmation page enabled?
$this->addElement('checkbox', 'is_confirm_enabled', ts('Use a confirmation page?'));
// is this page shareable through social media ?
$this->addElement('checkbox', 'is_share', ts('Allow sharing through social media?'));
// is this page active ?
$this->addElement('checkbox', 'is_active', ts('Is this Online Contribution Page Active?'));
// should the honor be enabled
$this->addElement('checkbox', 'honor_block_is_active', ts('Honoree Section Enabled'), NULL, array('onclick' => "showHonor()"));
$this->add('text', 'honor_block_title', ts('Honoree Section Title'), array('maxlength' => 255, 'size' => 45));
$this->add('textarea', 'honor_block_text', ts('Honoree Introductory Message'), array('rows' => 2, 'cols' => 50));
$this->addSelect('soft_credit_types', array(
'label' => ts('Honor Types'),
'entity' => 'ContributionSoft',
'field' => 'soft_credit_type_id',
'multiple' => TRUE,
'class' => 'huge',
));
$entities = array(
array(
'entity_name' => 'contact_1',
'entity_type' => 'IndividualModel',
),
);
$allowCoreTypes = array_merge(array(
'Contact',
'Individual',
'Organization',
'Household',
), CRM_Contact_BAO_ContactType::subTypes('Individual'));
$allowSubTypes = array();
$this->addProfileSelector('honoree_profile', ts('Honoree Profile'), $allowCoreTypes, $allowSubTypes, $entities);
if (!empty($this->_submitValues['honor_block_is_active'])) {
$this->addRule('soft_credit_types', ts('At least one value must be selected if Honor Section is active'), 'required');
$this->addRule('honoree_profile', ts('Please select a profile used for honoree'), 'required');
}
// add optional start and end dates
$this->addDateTime('start_date', ts('Start Date'));
$this->addDateTime('end_date', ts('End Date'));
$this->addFormRule(array('CRM_Contribute_Form_ContributionPage_Settings', 'formRule'), $this);
parent::buildQuickForm();
}
/**
* Global validation rules for the form.
*
* @param array $values
* Posted values of the form.
*
* @param $files
* @param $self
*
* @return array
* list of errors to be posted back to the form
*/
public static function formRule($values, $files, $self) {
$errors = array();
$contributionPageId = $self->_id;
//CRM-4286
if (strstr($values['title'], '/')) {
$errors['title'] = ts("Please do not use '/' in Title");
}
// ensure on-behalf-of profile meets minimum requirements
if (!empty($values['is_organization'])) {
if (empty($values['onbehalf_profile_id'])) {
$errors['onbehalf_profile_id'] = ts('Please select a profile to collect organization information on this contribution page.');
}
else {
$requiredProfileFields = array('organization_name', 'email');
if (!CRM_Core_BAO_UFGroup::checkValidProfile($values['onbehalf_profile_id'], $requiredProfileFields)) {
$errors['onbehalf_profile_id'] = ts('Profile does not contain the minimum required fields for an On Behalf Of Organization');
}
}
}
//CRM-11494
$start = CRM_Utils_Date::processDate($values['start_date']);
$end = CRM_Utils_Date::processDate($values['end_date']);
if (($end < $start) && ($end != 0)) {
$errors['end_date'] = ts('End date should be after Start date.');
}
if (!empty($self->_values['payment_processor']) && $financialType = CRM_Contribute_BAO_Contribution::validateFinancialType($values['financial_type_id'])) {
$errors['financial_type_id'] = ts("Financial Account of account relationship of 'Expense Account is' is not configured for Financial Type : ") . $financialType;
}
//dont allow on behalf of save when
//pre or post profile consists of membership fields
if ($contributionPageId && !empty($values['is_organization'])) {
$ufJoinParams = array(
'module' => 'CiviContribute',
'entity_table' => 'civicrm_contribution_page',
'entity_id' => $contributionPageId,
);
list($contributionProfiles['custom_pre_id'],
$contributionProfiles['custom_post_id']
) = CRM_Core_BAO_UFJoin::getUFGroupIds($ufJoinParams);
$conProfileType = NULL;
if ($contributionProfiles['custom_pre_id']) {
$preProfileType = CRM_Core_BAO_UFField::getProfileType($contributionProfiles['custom_pre_id']);
if ($preProfileType == 'Membership') {
$conProfileType = "'Includes Profile (top of page)'";
}
}
if ($contributionProfiles['custom_post_id']) {
$postProfileType = CRM_Core_BAO_UFField::getProfileType($contributionProfiles['custom_post_id']);
if ($postProfileType == 'Membership') {
$conProfileType = empty($conProfileType) ? "'Includes Profile (bottom of page)'" : "{$conProfileType} and 'Includes Profile (bottom of page)'";
}
}
if (!empty($conProfileType)) {
$errors['is_organization'] = ts("You should move the membership related fields configured in %1 to the 'On Behalf' profile for this Contribution Page", array(1 => $conProfileType));
}
}
return $errors;
}
/**
* Process the form.
*/
public function postProcess() {
// get the submitted form values.
$params = $this->controller->exportValues($this->_name);
// we do this in case the user has hit the forward/back button
if ($this->_id) {
$params['id'] = $this->_id;
}
else {
$session = CRM_Core_Session::singleton();
$params['created_id'] = $session->get('userID');
$params['created_date'] = date('YmdHis');
$config = CRM_Core_Config::singleton();
$params['currency'] = $config->defaultCurrency;
}
$params['is_confirm_enabled'] = CRM_Utils_Array::value('is_confirm_enabled', $params, FALSE);
$params['is_share'] = CRM_Utils_Array::value('is_share', $params, FALSE);
$params['is_active'] = CRM_Utils_Array::value('is_active', $params, FALSE);
$params['is_credit_card_only'] = CRM_Utils_Array::value('is_credit_card_only', $params, FALSE);
$params['honor_block_is_active'] = CRM_Utils_Array::value('honor_block_is_active', $params, FALSE);
$params['is_for_organization'] = !empty($params['is_organization']) ? CRM_Utils_Array::value('is_for_organization', $params, FALSE) : 0;
$params['start_date'] = CRM_Utils_Date::processDate($params['start_date'], $params['start_date_time'], TRUE);
$params['end_date'] = CRM_Utils_Date::processDate($params['end_date'], $params['end_date_time'], TRUE);
$params['goal_amount'] = CRM_Utils_Rule::cleanMoney($params['goal_amount']);
if (!$params['honor_block_is_active']) {
$params['honor_block_title'] = NULL;
$params['honor_block_text'] = NULL;
}
$dao = CRM_Contribute_BAO_ContributionPage::create($params);
$ufJoinParams = array(
'is_organization' => array(
'module' => 'on_behalf',
'entity_table' => 'civicrm_contribution_page',
'entity_id' => $dao->id,
),
'honor_block_is_active' => array(
'module' => 'soft_credit',
'entity_table' => 'civicrm_contribution_page',
'entity_id' => $dao->id,
),
);
foreach ($ufJoinParams as $index => $ufJoinParam) {
if (!empty($params[$index])) {
// first delete all past entries
CRM_Core_BAO_UFJoin::deleteAll($ufJoinParam);
$ufJoinParam['uf_group_id'] = $params[$index];
$ufJoinParam['weight'] = 1;
$ufJoinParam['is_active'] = 1;
if ($index == 'honor_block_is_active') {
$ufJoinParam['uf_group_id'] = $params['honoree_profile'];
$ufJoinParam['module_data'] = CRM_Contribute_BAO_ContributionPage::formatModuleData($params, FALSE, 'soft_credit');
}
else {
$ufJoinParam['uf_group_id'] = $params['onbehalf_profile_id'];
$ufJoinParam['module_data'] = CRM_Contribute_BAO_ContributionPage::formatModuleData($params, FALSE, 'on_behalf');
}
CRM_Core_BAO_UFJoin::create($ufJoinParam);
}
else {
if ($index == 'honor_block_is_active') {
$params['honor_block_title'] = NULL;
$params['honor_block_text'] = NULL;
}
else {
$params['for_organization'] = NULL;
}
//On subsequent honor_block_is_active uncheck, disable(don't delete)
//that particular honoree profile entry in UFjoin table, CRM-13981
$ufId = CRM_Core_BAO_UFJoin::findJoinEntryId($ufJoinParam);
if ($ufId) {
$ufJoinParam['uf_group_id'] = CRM_Core_BAO_UFJoin::findUFGroupId($ufJoinParam);
$ufJoinParam['is_active'] = 0;
CRM_Core_BAO_UFJoin::create($ufJoinParam);
}
}
}
$this->set('id', $dao->id);
if ($this->_action & CRM_Core_Action::ADD) {
$url = 'civicrm/admin/contribute/amount';
$urlParams = "action=update&reset=1&id={$dao->id}";
// special case for 'Save and Done' consistency.
if ($this->controller->getButtonName('submit') == '_qf_Amount_upload_done') {
$url = 'civicrm/admin/contribute';
$urlParams = 'reset=1';
CRM_Core_Session::setStatus(ts("'%1' information has been saved.",
array(1 => $this->getTitle())
), ts('Saved'), 'success');
}
CRM_Utils_System::redirect(CRM_Utils_System::url($url, $urlParams));
}
parent::endPostProcess();
}
/**
* Return a descriptive name for the page, used in wizard header
*
* @return string
*/
public function getTitle() {
return ts('Title and Settings');
}
}

View file

@ -0,0 +1,224 @@
<?php
/*
+--------------------------------------------------------------------+
| CiviCRM version 4.7 |
+--------------------------------------------------------------------+
| Copyright CiviCRM LLC (c) 2004-2017 |
+--------------------------------------------------------------------+
| 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 |
+--------------------------------------------------------------------+
*/
/**
*
* @package CRM
* @copyright CiviCRM LLC (c) 2004-2017
*/
/**
* Helper class to build navigation links.
*/
class CRM_Contribute_Form_ContributionPage_TabHeader {
/**
* @param CRM_Core_Form $form
*
* @return array
*/
public static function build(&$form) {
$tabs = $form->get('tabHeader');
if (!$tabs || empty($_GET['reset'])) {
$tabs = self::process($form);
$form->set('tabHeader', $tabs);
}
$form->assign_by_ref('tabHeader', $tabs);
CRM_Core_Resources::singleton()
->addScriptFile('civicrm', 'templates/CRM/common/TabHeader.js', 1, 'html-header')
->addSetting(array(
'tabSettings' => array(
'active' => self::getCurrentTab($tabs),
),
));
return $tabs;
}
/**
* @param CRM_Core_Form $form
*
* @return array
*/
public static function process(&$form) {
if ($form->getVar('_id') <= 0) {
return NULL;
}
$tabs = array(
'settings' => array(
'title' => ts('Title'),
'link' => NULL,
'valid' => FALSE,
'active' => FALSE,
'current' => FALSE,
),
'amount' => array(
'title' => ts('Amounts'),
'link' => NULL,
'valid' => FALSE,
'active' => FALSE,
'current' => FALSE,
),
'membership' => array(
'title' => ts('Memberships'),
'link' => NULL,
'valid' => FALSE,
'active' => FALSE,
'current' => FALSE,
),
'thankyou' => array(
'title' => ts('Receipt'),
'link' => NULL,
'valid' => FALSE,
'active' => FALSE,
'current' => FALSE,
),
'friend' => array(
'title' => ts('Tell a Friend'),
'link' => NULL,
'valid' => FALSE,
'active' => FALSE,
'current' => FALSE,
),
'custom' => array(
'title' => ts('Profiles'),
'link' => NULL,
'valid' => FALSE,
'active' => FALSE,
'current' => FALSE,
),
'premium' => array(
'title' => ts('Premiums'),
'link' => NULL,
'valid' => FALSE,
'active' => FALSE,
'current' => FALSE,
),
'widget' => array(
'title' => ts('Widgets'),
'link' => NULL,
'valid' => FALSE,
'active' => FALSE,
'current' => FALSE,
),
'pcp' => array(
'title' => ts('Personal Campaigns'),
'link' => NULL,
'valid' => FALSE,
'active' => FALSE,
'current' => FALSE,
),
);
$contribPageId = $form->getVar('_id');
CRM_Utils_Hook::tabset('civicrm/admin/contribute', $tabs, array('contribution_page_id' => $contribPageId));
$fullName = $form->getVar('_name');
$className = CRM_Utils_String::getClassName($fullName);
// Hack for special cases.
switch ($className) {
case 'Contribute':
$attributes = $form->getVar('_attributes');
$class = strtolower(basename(CRM_Utils_Array::value('action', $attributes)));
break;
case 'MembershipBlock':
$class = 'membership';
break;
default:
$class = strtolower($className);
break;
}
if (array_key_exists($class, $tabs)) {
$tabs[$class]['current'] = TRUE;
$qfKey = $form->get('qfKey');
if ($qfKey) {
$tabs[$class]['qfKey'] = "&qfKey={$qfKey}";
}
}
if ($contribPageId) {
$reset = !empty($_GET['reset']) ? 'reset=1&' : '';
foreach ($tabs as $key => $value) {
if (!isset($tabs[$key]['qfKey'])) {
$tabs[$key]['qfKey'] = NULL;
}
$tabs[$key]['link'] = CRM_Utils_System::url(
"civicrm/admin/contribute/{$key}",
"{$reset}action=update&id={$contribPageId}{$tabs[$key]['qfKey']}"
);
$tabs[$key]['active'] = $tabs[$key]['valid'] = TRUE;
}
//get all section info.
$contriPageInfo = CRM_Contribute_BAO_ContributionPage::getSectionInfo(array($contribPageId));
foreach ($contriPageInfo[$contribPageId] as $section => $info) {
if (!$info) {
$tabs[$section]['valid'] = FALSE;
}
}
}
return $tabs;
}
/**
* @param $form
*/
public static function reset(&$form) {
$tabs = self::process($form);
$form->set('tabHeader', $tabs);
}
/**
* @param $tabs
*
* @return int|string
*/
public static function getCurrentTab($tabs) {
static $current = FALSE;
if ($current) {
return $current;
}
if (is_array($tabs)) {
foreach ($tabs as $subPage => $pageVal) {
if ($pageVal['current'] === TRUE) {
$current = $subPage;
break;
}
}
}
$current = $current ? $current : 'settings';
return $current;
}
}

View file

@ -0,0 +1,133 @@
<?php
/*
+--------------------------------------------------------------------+
| CiviCRM version 4.7 |
+--------------------------------------------------------------------+
| Copyright CiviCRM LLC (c) 2004-2017 |
+--------------------------------------------------------------------+
| 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 |
+--------------------------------------------------------------------+
*/
/**
*
* @package CRM
* @copyright CiviCRM LLC (c) 2004-2017
*/
/**
* Form to configure thank-you messages and receipting features for an online contribution page.
*/
class CRM_Contribute_Form_ContributionPage_ThankYou extends CRM_Contribute_Form_ContributionPage {
/**
* Set default values for the form.
*
* Note that in edit/view mode the default values are retrieved from the database.
*/
public function setDefaultValues() {
return parent::setDefaultValues();
}
/**
* Build the form object.
*/
public function buildQuickForm() {
$this->registerRule('emailList', 'callback', 'emailList', 'CRM_Utils_Rule');
// thank you title and text (html allowed in text)
$this->add('text', 'thankyou_title', ts('Thank-you Page Title'), CRM_Core_DAO::getAttribute('CRM_Contribute_DAO_ContributionPage', 'thankyou_title'), TRUE);
$attributes = CRM_Core_DAO::getAttribute('CRM_Contribute_DAO_ContributionPage', 'thankyou_text') + array('class' => 'collapsed');
$this->add('wysiwyg', 'thankyou_text', ts('Thank-you Message'), $attributes);
$this->add('wysiwyg', 'thankyou_footer', ts('Thank-you Footer'), $attributes);
$this->addElement('checkbox', 'is_email_receipt', ts('Email Receipt to Contributor?'), NULL, array('onclick' => "showReceipt()"));
$this->add('text', 'receipt_from_name', ts('Receipt From Name'), CRM_Core_DAO::getAttribute('CRM_Contribute_DAO_ContributionPage', 'receipt_from_name'));
$this->add('text', 'receipt_from_email', ts('Receipt From Email'), CRM_Core_DAO::getAttribute('CRM_Contribute_DAO_ContributionPage', 'receipt_from_email'));
$this->add('textarea', 'receipt_text', ts('Receipt Message'), CRM_Core_DAO::getAttribute('CRM_Contribute_DAO_ContributionPage', 'receipt_text'));
$this->add('text', 'cc_receipt', ts('CC Receipt To'), CRM_Core_DAO::getAttribute('CRM_Contribute_DAO_ContributionPage', 'cc_receipt'));
$this->addRule('cc_receipt', ts('Please enter a valid list of comma delimited email addresses'), 'emailList');
$this->add('text', 'bcc_receipt', ts('BCC Receipt To'), CRM_Core_DAO::getAttribute('CRM_Contribute_DAO_ContributionPage', 'bcc_receipt'));
$this->addRule('bcc_receipt', ts('Please enter a valid list of comma delimited email addresses'), 'emailList');
parent::buildQuickForm();
$this->addFormRule(array('CRM_Contribute_Form_ContributionPage_ThankYou', 'formRule'), $this);
}
/**
* Global form rule.
*
* @param array $fields
* The input form values.
* @param array $files
* The uploaded files if any.
* @param array $options
* Additional user data.
*
* @return bool|array
* true if no errors, else array of errors
*/
public static function formRule($fields, $files, $options) {
$errors = array();
// if is_email_receipt is set, the receipt message must be non-empty
if (!empty($fields['is_email_receipt'])) {
//added for CRM-1348
$email = trim(CRM_Utils_Array::value('receipt_from_email', $fields));
if (empty($email) || !CRM_Utils_Rule::email($email)) {
$errors['receipt_from_email'] = ts('A valid Receipt From Email address must be specified if Email Receipt to Contributor is enabled');
}
}
return $errors;
}
/**
* Process the form.
*/
public function postProcess() {
// get the submitted form values.
$params = $this->controller->exportValues($this->_name);
$params['id'] = $this->_id;
$params['is_email_receipt'] = CRM_Utils_Array::value('is_email_receipt', $params, FALSE);
if (!$params['is_email_receipt']) {
$params['receipt_from_name'] = NULL;
$params['receipt_from_email'] = NULL;
$params['receipt_text'] = NULL;
$params['cc_receipt'] = NULL;
$params['bcc_receipt'] = NULL;
}
$dao = CRM_Contribute_BAO_ContributionPage::create($params);
parent::endPostProcess();
}
/**
* Return a descriptive name for the page, used in wizard header
*
* @return string
*/
public function getTitle() {
return ts('Thanks and Receipt');
}
}

View file

@ -0,0 +1,279 @@
<?php
/*
+--------------------------------------------------------------------+
| CiviCRM version 4.7 |
+--------------------------------------------------------------------+
| Copyright CiviCRM LLC (c) 2004-2017 |
+--------------------------------------------------------------------+
| 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 |
+--------------------------------------------------------------------+
*/
/**
*
* @package CRM
* @copyright CiviCRM LLC (c) 2004-2017
*/
class CRM_Contribute_Form_ContributionPage_Widget extends CRM_Contribute_Form_ContributionPage {
protected $_colors;
protected $_widget;
public function preProcess() {
parent::preProcess();
$this->_widget = new CRM_Contribute_DAO_Widget();
$this->_widget->contribution_page_id = $this->_id;
if (!$this->_widget->find(TRUE)) {
$this->_widget = NULL;
}
else {
$this->assign('widget_id', $this->_widget->id);
// check of home url is set, if set then it flash widget might be in use.
$this->assign('showStatus', FALSE);
if ($this->_widget->url_homepage) {
$this->assign('showStatus', TRUE);
}
}
$this->assign('cpageId', $this->_id);
$config = CRM_Core_Config::singleton();
$title = CRM_Core_DAO::getFieldValue('CRM_Contribute_DAO_ContributionPage',
$this->_id,
'title'
);
$this->_fields = array(
'title' => array(
ts('Title'),
'text',
FALSE,
$title,
),
'url_logo' => array(
ts('URL to Logo Image'),
'text',
FALSE,
NULL,
),
'button_title' => array(
ts('Button Title'),
'text',
FALSE,
ts('Contribute!'),
),
);
$this->_colorFields = array(
'color_title' => array(
ts('Title Text Color'),
'text',
FALSE,
'#2786C2',
),
'color_bar' => array(
ts('Progress Bar Color'),
'text',
FALSE,
'#2786C2',
),
'color_main_text' => array(
ts('Additional Text Color'),
'text',
FALSE,
'#FFFFFF',
),
'color_main' => array(
ts('Background Color'),
'text',
FALSE,
'#96C0E7',
),
'color_main_bg' => array(
ts('Background Color Top Area'),
'text',
FALSE,
'#B7E2FF',
),
'color_bg' => array(
ts('Border Color'),
'text',
FALSE,
'#96C0E7',
),
'color_about_link' => array(
ts('Button Text Color'),
'text',
FALSE,
'#556C82',
),
'color_button' => array(
ts('Button Background Color'),
'text',
FALSE,
'#FFFFFF',
),
'color_homepage_link' => array(
ts('Homepage Link Color'),
'text',
FALSE,
'#FFFFFF',
),
);
}
/**
* Set default values for the form.
*/
public function setDefaultValues() {
$defaults = array();
// check if there is a widget already created
if ($this->_widget) {
CRM_Core_DAO::storeValues($this->_widget, $defaults);
}
else {
foreach ($this->_fields as $name => $val) {
$defaults[$name] = $val[3];
}
foreach ($this->_colorFields as $name => $val) {
$defaults[$name] = $val[3];
}
$defaults['about'] = CRM_Core_DAO::getFieldValue('CRM_Contribute_DAO_ContributionPage',
$this->_id,
'intro_text'
);
}
$showHide = new CRM_Core_ShowHideBlocks();
$showHide->addHide('id-colors');
$showHide->addToTemplate();
return $defaults;
}
public function buildQuickForm() {
$attributes = CRM_Core_DAO::getAttribute('CRM_Contribute_DAO_Widget');
$this->addElement('checkbox',
'is_active',
ts('Enable Widget?'),
NULL,
array('onclick' => "widgetBlock(this)")
);
$this->add('wysiwyg', 'about', ts('About'), $attributes['about']);
foreach ($this->_fields as $name => $val) {
$this->add($val[1],
$name,
$val[0],
$attributes[$name],
$val[2]
);
}
foreach ($this->_colorFields as $name => $val) {
$this->add($val[1],
$name,
$val[0],
$attributes[$name],
$val[2]
);
}
$this->assign_by_ref('fields', $this->_fields);
$this->assign_by_ref('colorFields', $this->_colorFields);
$this->_refreshButtonName = $this->getButtonName('refresh');
$this->addElement('submit',
$this->_refreshButtonName,
ts('Save and Preview')
);
parent::buildQuickForm();
$this->addFormRule(array('CRM_Contribute_Form_ContributionPage_Widget', 'formRule'), $this);
}
/**
* Validation.
*
* @param array $params
* (ref.) an assoc array of name/value pairs.
*
* @param $files
* @param $self
*
* @return bool|array
* mixed true or array of errors
*/
public static function formRule($params, $files, $self) {
$errors = array();
if (!empty($params['is_active'])) {
if (empty($params['title'])) {
$errors['title'] = ts('Title is a required field.');
}
if (empty($params['about'])) {
$errors['about'] = ts('About is a required field.');
}
foreach ($params as $key => $val) {
if (substr($key, 0, 6) == 'color_' && empty($params[$key])) {
$errors[$key] = ts('%1 is a required field.', array(1 => $self->_colorFields[$key][0]));
}
}
}
return empty($errors) ? TRUE : $errors;
}
public function postProcess() {
//to reset quickform elements of next (pcp) page.
if ($this->controller->getNextName('Widget') == 'PCP') {
$this->controller->resetPage('PCP');
}
// get the submitted form values.
$params = $this->controller->exportValues($this->_name);
if ($this->_widget) {
$params['id'] = $this->_widget->id;
}
$params['contribution_page_id'] = $this->_id;
$params['is_active'] = CRM_Utils_Array::value('is_active', $params, FALSE);
$params['url_homepage'] = 'null';
$widget = new CRM_Contribute_DAO_Widget();
$widget->copyValues($params);
$widget->save();
$buttonName = $this->controller->getButtonName();
if ($buttonName == $this->_refreshButtonName) {
return;
}
parent::endPostProcess();
}
/**
* Return a descriptive name for the page, used in wizard header
*
* @return string
*/
public function getTitle() {
return ts('Widget Settings');
}
}

View file

@ -0,0 +1,269 @@
<?php
/*
+--------------------------------------------------------------------+
| CiviCRM version 4.7 |
+--------------------------------------------------------------------+
| Copyright CiviCRM LLC (c) 2004-2017 |
+--------------------------------------------------------------------+
| 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 |
+--------------------------------------------------------------------+
*/
/**
*
* @package CRM
* @copyright CiviCRM LLC (c) 2004-2017
*/
/**
* This class generates form components for Payment-Instrument.
*/
class CRM_Contribute_Form_ContributionView extends CRM_Core_Form {
/**
* Set variables up before form is built.
*/
public function preProcess() {
$id = $this->get('id');
$params = array('id' => $id);
$context = CRM_Utils_Request::retrieve('context', 'String', $this);
$this->assign('context', $context);
$values = CRM_Contribute_BAO_Contribution::getValuesWithMappings($params);
if (CRM_Financial_BAO_FinancialType::isACLFinancialTypeStatus() && $this->_action & CRM_Core_Action::VIEW) {
$financialTypeID = CRM_Contribute_PseudoConstant::financialType($values['financial_type_id']);
CRM_Financial_BAO_FinancialType::checkPermissionedLineItems($id, 'view');
if (CRM_Financial_BAO_FinancialType::checkPermissionedLineItems($id, 'edit', FALSE)) {
$this->assign('canEdit', TRUE);
}
if (CRM_Financial_BAO_FinancialType::checkPermissionedLineItems($id, 'delete', FALSE)) {
$this->assign('canDelete', TRUE);
}
if (!CRM_Core_Permission::check('view contributions of type ' . $financialTypeID)) {
CRM_Core_Error::fatal(ts('You do not have permission to access this page.'));
}
}
elseif ($this->_action & CRM_Core_Action::VIEW) {
$this->assign('noACL', TRUE);
}
CRM_Contribute_BAO_Contribution::resolveDefaults($values);
// @todo - I believe this cancelledStatus is unused - if someone reaches the same conclusion
// by grepping then the next few lines can go.
$cancelledStatus = TRUE;
$status = CRM_Contribute_PseudoConstant::contributionStatus(NULL, 'name');
if (CRM_Utils_Array::value('contribution_status_id', $values) == array_search('Cancelled', $status)) {
$cancelledStatus = FALSE;
}
$this->assign('cancelledStatus', $cancelledStatus);
if (!empty($values['contribution_page_id'])) {
$contribPages = CRM_Contribute_PseudoConstant::contributionPage(NULL, TRUE);
$values['contribution_page_title'] = CRM_Utils_Array::value(CRM_Utils_Array::value('contribution_page_id', $values), $contribPages);
}
// get received into i.e to_financial_account_id from last trxn
$financialTrxnId = CRM_Core_BAO_FinancialTrxn::getFinancialTrxnId($values['contribution_id'], 'DESC');
$values['to_financial_account'] = '';
if (!empty($financialTrxnId['financialTrxnId'])) {
$values['to_financial_account_id'] = CRM_Core_DAO::getFieldValue('CRM_Financial_DAO_FinancialTrxn', $financialTrxnId['financialTrxnId'], 'to_financial_account_id');
if ($values['to_financial_account_id']) {
$values['to_financial_account'] = CRM_Contribute_PseudoConstant::financialAccount($values['to_financial_account_id']);
}
$values['payment_processor_id'] = CRM_Core_DAO::getFieldValue('CRM_Financial_DAO_FinancialTrxn', $financialTrxnId['financialTrxnId'], 'payment_processor_id');
if ($values['payment_processor_id']) {
$values['payment_processor_name'] = CRM_Core_DAO::getFieldValue('CRM_Financial_DAO_PaymentProcessor', $values['payment_processor_id'], 'name');
}
}
if (!empty($values['contribution_recur_id'])) {
$sql = "SELECT installments, frequency_interval, frequency_unit FROM civicrm_contribution_recur WHERE id = %1";
$params = array(1 => array($values['contribution_recur_id'], 'Integer'));
$dao = CRM_Core_DAO::executeQuery($sql, $params);
if ($dao->fetch()) {
$values['recur_installments'] = $dao->installments;
$values['recur_frequency_unit'] = $dao->frequency_unit;
$values['recur_frequency_interval'] = $dao->frequency_interval;
}
}
$groupTree = CRM_Core_BAO_CustomGroup::getTree('Contribution', NULL, $id, 0, CRM_Utils_Array::value('financial_type_id', $values));
CRM_Core_BAO_CustomGroup::buildCustomDataView($this, $groupTree, FALSE, NULL, NULL, NULL, $id);
$premiumId = NULL;
if ($id) {
$dao = new CRM_Contribute_DAO_ContributionProduct();
$dao->contribution_id = $id;
if ($dao->find(TRUE)) {
$premiumId = $dao->id;
$productID = $dao->product_id;
}
}
if ($premiumId) {
$productDAO = new CRM_Contribute_DAO_Product();
$productDAO->id = $productID;
$productDAO->find(TRUE);
$this->assign('premium', $productDAO->name);
$this->assign('option', $dao->product_option);
$this->assign('fulfilled', $dao->fulfilled_date);
}
// Get Note
$noteValue = CRM_Core_BAO_Note::getNote(CRM_Utils_Array::value('id', $values), 'civicrm_contribution');
$values['note'] = array_values($noteValue);
// show billing address location details, if exists
if (!empty($values['address_id'])) {
$addressParams = array('id' => CRM_Utils_Array::value('address_id', $values));
$addressDetails = CRM_Core_BAO_Address::getValues($addressParams, FALSE, 'id');
$addressDetails = array_values($addressDetails);
$values['billing_address'] = $addressDetails[0]['display'];
}
//assign soft credit record if exists.
$SCRecords = CRM_Contribute_BAO_ContributionSoft::getSoftContribution($values['contribution_id'], TRUE);
if (!empty($SCRecords['soft_credit'])) {
$this->assign('softContributions', $SCRecords['soft_credit']);
unset($SCRecords['soft_credit']);
}
//assign pcp record if exists
foreach ($SCRecords as $name => $value) {
$this->assign($name, $value);
}
$lineItems = array();
$displayLineItems = FALSE;
if ($id) {
$lineItems = array(CRM_Price_BAO_LineItem::getLineItemsByContributionID(($id)));
$firstLineItem = reset($lineItems[0]);
if (empty($firstLineItem['price_set_id'])) {
// CRM-20297 All we care is that it's not QuickConfig, so no price set
// is no problem.
$displayLineItems = TRUE;
}
else {
try {
$priceSet = civicrm_api3('PriceSet', 'getsingle', array(
'id' => $firstLineItem['price_set_id'],
'return' => 'is_quick_config, id',
));
$displayLineItems = !$priceSet['is_quick_config'];
}
catch (CiviCRM_API3_Exception $e) {
throw new CRM_Core_Exception('Cannot find price set by ID');
}
}
}
$this->assign('lineItem', $lineItems);
$this->assign('displayLineItems', $displayLineItems);
$values['totalAmount'] = $values['total_amount'];
$this->assign('displayLineItemFinancialType', TRUE);
//do check for campaigns
if ($campaignId = CRM_Utils_Array::value('campaign_id', $values)) {
$campaigns = CRM_Campaign_BAO_Campaign::getCampaigns($campaignId);
$values['campaign'] = $campaigns[$campaignId];
}
if ($values['contribution_status'] == 'Refunded') {
$this->assign('refund_trxn_id', CRM_Core_BAO_FinancialTrxn::getRefundTransactionTrxnID($id));
}
// assign values to the template
$this->assign($values);
$invoiceSettings = Civi::settings()->get('contribution_invoice_settings');
$invoicing = CRM_Utils_Array::value('invoicing', $invoiceSettings);
$this->assign('invoicing', $invoicing);
$this->assign('isDeferred', CRM_Utils_Array::value('deferred_revenue_enabled', $invoiceSettings));
if ($invoicing && isset($values['tax_amount'])) {
$this->assign('totalTaxAmount', $values['tax_amount']);
}
$displayName = CRM_Contact_BAO_Contact::displayName($values['contact_id']);
$this->assign('displayName', $displayName);
// Check if this is default domain contact CRM-10482
if (CRM_Contact_BAO_Contact::checkDomainContact($values['contact_id'])) {
$displayName .= ' (' . ts('default organization') . ')';
}
// omitting contactImage from title for now since the summary overlay css doesn't work outside of our crm-container
CRM_Utils_System::setTitle(ts('View Contribution from') . ' ' . $displayName);
// add viewed contribution to recent items list
$url = CRM_Utils_System::url('civicrm/contact/view/contribution',
"action=view&reset=1&id={$values['id']}&cid={$values['contact_id']}&context=home"
);
$title = $displayName . ' - (' . CRM_Utils_Money::format($values['total_amount'], $values['currency']) . ' ' . ' - ' . $values['financial_type'] . ')';
$recentOther = array();
if (CRM_Core_Permission::checkActionPermission('CiviContribute', CRM_Core_Action::UPDATE)) {
$recentOther['editUrl'] = CRM_Utils_System::url('civicrm/contact/view/contribution',
"action=update&reset=1&id={$values['id']}&cid={$values['contact_id']}&context=home"
);
}
if (CRM_Core_Permission::checkActionPermission('CiviContribute', CRM_Core_Action::DELETE)) {
$recentOther['deleteUrl'] = CRM_Utils_System::url('civicrm/contact/view/contribution',
"action=delete&reset=1&id={$values['id']}&cid={$values['contact_id']}&context=home"
);
}
CRM_Utils_Recent::add($title,
$url,
$values['id'],
'Contribution',
$values['contact_id'],
NULL,
$recentOther
);
$contributionStatus = $status[$values['contribution_status_id']];
if (in_array($contributionStatus, array('Partially paid', 'Pending refund'))
|| ($contributionStatus == 'Pending' && $values['is_pay_later'])
) {
if ($contributionStatus == 'Pending refund') {
$this->assign('paymentButtonName', ts('Record Refund'));
}
else {
$this->assign('paymentButtonName', ts('Record Payment'));
}
$this->assign('addRecordPayment', TRUE);
$this->assign('contactId', $values['contact_id']);
$this->assign('componentId', $id);
$this->assign('component', 'contribution');
}
}
/**
* Build the form object.
*/
public function buildQuickForm() {
$this->addButtons(array(
array(
'type' => 'cancel',
'name' => ts('Done'),
'spacing' => '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;',
'isDefault' => TRUE,
),
));
}
}

View file

@ -0,0 +1,368 @@
<?php
/*
+--------------------------------------------------------------------+
| CiviCRM version 4.7 |
+--------------------------------------------------------------------+
| Copyright CiviCRM LLC (c) 2004-2017 |
+--------------------------------------------------------------------+
| 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 |
+--------------------------------------------------------------------+
*/
/**
*
* @package CRM
* @copyright CiviCRM LLC (c) 2004-2017
*/
/**
* This class generates form components for Premiums.
*/
class CRM_Contribute_Form_ManagePremiums extends CRM_Contribute_Form {
/**
* Pre process the form.
*/
public function preProcess() {
parent::preProcess();
}
/**
* Set default values for the form.
*/
public function setDefaultValues() {
$defaults = parent::setDefaultValues();
if ($this->_id) {
$params = array('id' => $this->_id);
CRM_Contribute_BAO_ManagePremiums::retrieve($params, $tempDefaults);
$imageUrl = (isset($tempDefaults['image'])) ? $tempDefaults['image'] : "";
if (isset($tempDefaults['image']) && isset($tempDefaults['thumbnail'])) {
$defaults['imageUrl'] = $tempDefaults['image'];
$defaults['thumbnailUrl'] = $tempDefaults['thumbnail'];
$defaults['imageOption'] = 'thumbnail';
// assign thumbnailUrl to template so we can display current image in update mode
$this->assign('thumbnailUrl', $defaults['thumbnailUrl']);
}
else {
$defaults['imageOption'] = 'noImage';
}
if (isset($tempDefaults['thumbnail']) && isset($tempDefaults['image'])) {
$this->assign('thumbURL', $tempDefaults['thumbnail']);
$this->assign('imageURL', $tempDefaults['image']);
}
if (isset($tempDefaults['period_type'])) {
$this->assign('showSubscriptions', TRUE);
}
}
return $defaults;
}
/**
* Build the form object.
*/
public function buildQuickForm() {
parent::buildQuickForm();
$this->setPageTitle(ts('Premium Product'));
if ($this->_action & CRM_Core_Action::PREVIEW) {
CRM_Contribute_BAO_Premium::buildPremiumPreviewBlock($this, $this->_id);
return;
}
if ($this->_action & CRM_Core_Action::DELETE) {
return;
}
$this->applyFilter('__ALL__', 'trim');
$this->add('text', 'name', ts('Name'), CRM_Core_DAO::getAttribute('CRM_Contribute_DAO_Product', 'name'), TRUE);
$this->addRule('name', ts('A product with this name already exists. Please select another name.'), 'objectExists', array(
'CRM_Contribute_DAO_Product',
$this->_id,
));
$this->add('text', 'sku', ts('SKU'), CRM_Core_DAO::getAttribute('CRM_Contribute_DAO_Product', 'sku'));
$this->add('textarea', 'description', ts('Description'), 'rows=3, cols=60');
$image['image'] = $this->createElement('radio', NULL, NULL, ts('Upload from my computer'), 'image', 'onclick="add_upload_file_block(\'image\');');
$image['thumbnail'] = $this->createElement('radio', NULL, NULL, ts('Display image and thumbnail from these locations on the web:'), 'thumbnail', 'onclick="add_upload_file_block(\'thumbnail\');');
$image['default_image'] = $this->createElement('radio', NULL, NULL, ts('Use default image'), 'default_image', 'onclick="add_upload_file_block(\'default\');');
$image['noImage'] = $this->createElement('radio', NULL, NULL, ts('Do not display an image'), 'noImage', 'onclick="add_upload_file_block(\'noImage\');');
$this->addGroup($image, 'imageOption', ts('Premium Image'));
$this->addRule('imageOption', ts('Please select an option for the premium image.'), 'required');
$this->addElement('text', 'imageUrl', ts('Image URL'));
$this->addElement('text', 'thumbnailUrl', ts('Thumbnail URL'));
$this->add('file', 'uploadFile', ts('Image File Name'), 'onChange="select_option();"');
$this->add('text', 'price', ts('Market Value'), CRM_Core_DAO::getAttribute('CRM_Contribute_DAO_Product', 'price'), TRUE);
$this->addRule('price', ts('Please enter the Market Value for this product.'), 'money');
$this->add('text', 'cost', ts('Actual Cost of Product'), CRM_Core_DAO::getAttribute('CRM_Contribute_DAO_Product', 'cost'));
$this->addRule('price', ts('Please enter the Actual Cost of Product.'), 'money');
$this->add('text', 'min_contribution', ts('Minimum Contribution Amount'), CRM_Core_DAO::getAttribute('CRM_Contribute_DAO_Product', 'min_contribution'), TRUE);
$this->addRule('min_contribution', ts('Please enter a monetary value for the Minimum Contribution Amount.'), 'money');
$this->add('textarea', 'options', ts('Options'), 'rows=3, cols=60');
$this->add('select', 'period_type', ts('Period Type'), array(
'' => '- select -',
'rolling' => 'Rolling',
'fixed' => 'Fixed',
));
$this->add('text', 'fixed_period_start_day', ts('Fixed Period Start Day'), CRM_Core_DAO::getAttribute('CRM_Contribute_DAO_Product', 'fixed_period_start_day'));
$this->add('Select', 'duration_unit', ts('Duration Unit'), array('' => '- select period -') + CRM_Core_SelectValues::getPremiumUnits());
$this->add('text', 'duration_interval', ts('Duration'), CRM_Core_DAO::getAttribute('CRM_Contribute_DAO_Product', 'duration_interval'));
$this->add('Select', 'frequency_unit', ts('Frequency Unit'), array('' => '- select period -') + CRM_Core_SelectValues::getPremiumUnits());
$this->add('text', 'frequency_interval', ts('Frequency'), CRM_Core_DAO::getAttribute('CRM_Contribute_DAO_Product', 'frequency_interval'));
//Financial Type CRM-11106
$financialType = CRM_Contribute_PseudoConstant::financialType();
$premiumFinancialType = array();
CRM_Core_PseudoConstant::populate(
$premiumFinancialType,
'CRM_Financial_DAO_EntityFinancialAccount',
$all = TRUE,
$retrieve = 'entity_id',
$filter = NULL,
'account_relationship = 8'
);
$costFinancialType = array();
CRM_Core_PseudoConstant::populate(
$costFinancialType,
'CRM_Financial_DAO_EntityFinancialAccount',
$all = TRUE,
$retrieve = 'entity_id',
$filter = NULL,
'account_relationship = 7'
);
$productFinancialType = array_intersect($costFinancialType, $premiumFinancialType);
foreach ($financialType as $key => $financialTypeName) {
if (!in_array($key, $productFinancialType)) {
unset($financialType[$key]);
}
}
if (count($financialType)) {
$this->assign('financialType', $financialType);
}
$this->add(
'select',
'financial_type_id',
ts('Financial Type'),
array('' => ts('- select -')) + $financialType
);
$this->add('checkbox', 'is_active', ts('Enabled?'));
$this->addFormRule(array('CRM_Contribute_Form_ManagePremiums', 'formRule'));
$this->addButtons(array(
array(
'type' => 'upload',
'name' => ts('Save'),
'isDefault' => TRUE,
),
array(
'type' => 'cancel',
'name' => ts('Cancel'),
),
)
);
$this->assign('productId', $this->_id);
}
/**
* Function for validation.
*
* @param array $params
* (ref.) an assoc array of name/value pairs.
* @param $files
*
* @return bool|array
* mixed true or array of errors
*/
public static function formRule($params, $files) {
// If choosing to upload an image, then an image must be provided
if (CRM_Utils_Array::value('imageOption', $params) == 'image'
&& empty($files['uploadFile']['name'])
) {
$errors['uploadFile'] = ts('A file must be selected');
}
// If choosing to use image URLs, then both URLs must be present
if (CRM_Utils_Array::value('imageOption', $params) == 'thumbnail') {
if (!$params['imageUrl']) {
$errors['imageUrl'] = ts('Image URL is Required');
}
if (!$params['thumbnailUrl']) {
$errors['thumbnailUrl'] = ts('Thumbnail URL is Required');
}
}
// CRM-13231 financial type required if product has cost
if (!empty($params['cost']) && empty($params['financial_type_id'])) {
$errors['financial_type_id'] = ts('Financial Type is required for product having cost.');
}
if (!$params['period_type']) {
if ($params['fixed_period_start_day'] || $params['duration_unit'] || $params['duration_interval'] ||
$params['frequency_unit'] || $params['frequency_interval']
) {
$errors['period_type'] = ts('Please select the Period Type for this subscription or service.');
}
}
if ($params['period_type'] == 'fixed' && !$params['fixed_period_start_day']) {
$errors['fixed_period_start_day'] = ts('Please enter a Fixed Period Start Day for this subscription or service.');
}
if ($params['duration_unit'] && !$params['duration_interval']) {
$errors['duration_interval'] = ts('Please enter the Duration Interval for this subscription or service.');
}
if ($params['duration_interval'] && !$params['duration_unit']) {
$errors['duration_unit'] = ts('Please enter the Duration Unit for this subscription or service.');
}
if ($params['frequency_interval'] && !$params['frequency_unit']) {
$errors['frequency_unit'] = ts('Please enter the Frequency Unit for this subscription or service.');
}
if ($params['frequency_unit'] && !$params['frequency_interval']) {
$errors['frequency_interval'] = ts('Please enter the Frequency Interval for this subscription or service.');
}
return empty($errors) ? TRUE : $errors;
}
/**
* Process the form submission.
*/
public function postProcess() {
// If previewing, don't do any post-processing
if ($this->_action & CRM_Core_Action::PREVIEW) {
return;
}
// If deleting, then only delete and skip the rest of the post-processing
if ($this->_action & CRM_Core_Action::DELETE) {
CRM_Contribute_BAO_ManagePremiums::del($this->_id);
CRM_Core_Session::setStatus(
ts('Selected Premium Product type has been deleted.'),
ts('Deleted'), 'info');
return;
}
$params = $this->controller->exportValues($this->_name);
// Clean the the money fields
$moneyFields = array('cost', 'price', 'min_contribution');
foreach ($moneyFields as $field) {
$params[$field] = CRM_Utils_Rule::cleanMoney($params[$field]);
}
$ids = array();
if ($this->_action & CRM_Core_Action::UPDATE) {
$ids['premium'] = $this->_id;
}
$this->_processImages($params);
// Save to database
$premium = CRM_Contribute_BAO_ManagePremiums::add($params, $ids);
CRM_Core_Session::setStatus(
ts("The Premium '%1' has been saved.", array(1 => $premium->name)),
ts('Saved'), 'success');
}
/**
* Look at $params to find form info about images. Manipulate images if
* necessary. Then alter $params to point to the newly manipulated images.
*
* @param array $params
*/
protected function _processImages(&$params) {
$defaults = array(
'imageOption' => 'noImage',
'uploadFile' => array('name' => ''),
'image' => '',
'thumbnail' => '',
'imageUrl' => '',
'thumbnailUrl' => '',
);
$params = array_merge($defaults, $params);
// User is uploading an image
if ($params['imageOption'] == 'image') {
$imageFile = $params['uploadFile']['name'];
try {
$params['image'] = CRM_Utils_File::resizeImage($imageFile, 200, 200, "_full");
$params['thumbnail'] = CRM_Utils_File::resizeImage($imageFile, 50, 50, "_thumb");
}
catch (CRM_Core_Exception $e) {
$params['image'] = self::_defaultImage();
$params['thumbnail'] = self::_defaultThumbnail();
$msg = ts('The product has been configured to use a default image.');
CRM_Core_Session::setStatus($e->getMessage() . " $msg", ts('Notice'), 'alert');
}
}
// User is specifying existing URLs for the images
elseif ($params['imageOption'] == 'thumbnail') {
$params['image'] = $params['imageUrl'];
$params['thumbnail'] = $params['thumbnailUrl'];
}
// User wants a default image
elseif ($params['imageOption'] == 'default_image') {
$params['image'] = self::_defaultImage();
$params['thumbnail'] = self::_defaultThumbnail();
}
}
/**
* Returns the path to the default premium image
* @return string
*/
protected static function _defaultImage() {
$config = CRM_Core_Config::singleton();
return $config->resourceBase . 'i/contribute/default_premium.jpg';
}
/**
* Returns the path to the default premium thumbnail
* @return string
*/
protected static function _defaultThumbnail() {
$config = CRM_Core_Config::singleton();
return $config->resourceBase . 'i/contribute/default_premium_thumb.jpg';
}
}

View file

@ -0,0 +1,470 @@
<?php
/*
+--------------------------------------------------------------------+
| CiviCRM version 4.7 |
+--------------------------------------------------------------------+
| Copyright CiviCRM LLC (c) 2004-2017 |
+--------------------------------------------------------------------+
| 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 |
+--------------------------------------------------------------------+
*/
/**
*
* @package CRM
* @copyright CiviCRM LLC (c) 2004-2017
*/
/**
* Advanced search, extends basic search.
*/
class CRM_Contribute_Form_Search extends CRM_Core_Form_Search {
/**
* The params that are sent to the query.
*
* @var array
*/
protected $_queryParams;
/**
* Are we restricting ourselves to a single contact.
*
* @var boolean
*/
protected $_single = FALSE;
/**
* Are we restricting ourselves to a single contact.
*
* @var boolean
*/
protected $_limit = NULL;
/**
* Prefix for the controller.
*/
protected $_prefix = "contribute_";
/**
* Processing needed for buildForm and later.
*/
public function preProcess() {
$this->set('searchFormName', 'Search');
$this->_searchButtonName = $this->getButtonName('refresh');
$this->_actionButtonName = $this->getButtonName('next', 'action');
$this->_done = FALSE;
// @todo - is this an error - $this->_defaults is used.
$this->defaults = array();
/*
* we allow the controller to set force/reset externally, useful when we are being
* driven by the wizard framework
*/
$this->_reset = CRM_Utils_Request::retrieve('reset', 'Boolean');
$this->_force = CRM_Utils_Request::retrieve('force', 'Boolean', $this, FALSE);
$this->_limit = CRM_Utils_Request::retrieve('limit', 'Positive', $this);
$this->_context = CRM_Utils_Request::retrieve('context', 'String', $this, FALSE, 'search');
$this->assign("context", $this->_context);
// get user submitted values
// get it from controller only if form has been submitted, else preProcess has set this
if (!empty($_POST)) {
$this->_formValues = $this->controller->exportValues($this->_name);
}
else {
$this->_formValues = $this->get('formValues');
}
//membership ID
$memberShipId = CRM_Utils_Request::retrieve('memberId', 'Positive', $this);
if (isset($memberShipId)) {
$this->_formValues['contribution_membership_id'] = $memberShipId;
}
$participantId = CRM_Utils_Request::retrieve('participantId', 'Positive', $this);
if (isset($participantId)) {
$this->_formValues['contribution_participant_id'] = $participantId;
}
if ($this->_force) {
$this->postProcess();
$this->set('force', 0);
}
$sortID = NULL;
if ($this->get(CRM_Utils_Sort::SORT_ID)) {
$sortID = CRM_Utils_Sort::sortIDValue($this->get(CRM_Utils_Sort::SORT_ID),
$this->get(CRM_Utils_Sort::SORT_DIRECTION)
);
}
$this->_queryParams = CRM_Contact_BAO_Query::convertFormValues($this->_formValues);
$selector = new CRM_Contribute_Selector_Search($this->_queryParams,
$this->_action,
NULL,
$this->_single,
$this->_limit,
$this->_context
);
$prefix = NULL;
if ($this->_context == 'user') {
$prefix = $this->_prefix;
}
$this->assign("{$prefix}limit", $this->_limit);
$this->assign("{$prefix}single", $this->_single);
$controller = new CRM_Core_Selector_Controller($selector,
$this->get(CRM_Utils_Pager::PAGE_ID),
$sortID,
CRM_Core_Action::VIEW,
$this,
CRM_Core_Selector_Controller::TRANSFER,
$prefix
);
$controller->setEmbedded(TRUE);
$controller->moveFromSessionToTemplate();
$this->assign('contributionSummary', $this->get('summary'));
}
/**
* Set defaults.
*
* @return array
*/
public function setDefaultValues() {
if (empty($this->_defaults['contribution_status'])) {
$this->_defaults['contribution_status'][1] = 1;
}
return $this->_defaults;
}
/**
* Build the form object.
*/
public function buildQuickForm() {
parent::buildQuickForm();
$this->addSortNameField();
$this->_group = CRM_Core_PseudoConstant::nestedGroup();
// multiselect for groups
if ($this->_group) {
$this->add('select', 'group', ts('Groups'), $this->_group, FALSE,
array('id' => 'group', 'multiple' => 'multiple', 'class' => 'crm-select2')
);
}
// multiselect for tags
$contactTags = CRM_Core_BAO_Tag::getTags();
if ($contactTags) {
$this->add('select', 'contact_tags', ts('Tags'), $contactTags, FALSE,
array('id' => 'contact_tags', 'multiple' => 'multiple', 'class' => 'crm-select2')
);
}
CRM_Contribute_BAO_Query::buildSearchForm($this);
$rows = $this->get('rows');
if (is_array($rows)) {
if (!$this->_single) {
$this->addRowSelectors($rows);
}
$permission = CRM_Core_Permission::getPermission();
$queryParams = $this->get('queryParams');
$softCreditFiltering = FALSE;
if (!empty($queryParams)) {
$softCreditFiltering = CRM_Contribute_BAO_Query::isSoftCreditOptionEnabled($queryParams);
}
$tasks = CRM_Contribute_Task::permissionedTaskTitles($permission, $softCreditFiltering);
$this->addTaskMenu($tasks);
}
}
/**
* Get the label for the sortName field if email searching is on.
*
* (email searching is a setting under search preferences).
*
* @return string
*/
protected function getSortNameLabelWithEmail() {
return ts('Contributor Name or Email');
}
/**
* Get the label for the sortName field if email searching is off.
*
* (email searching is a setting under search preferences).
*
* @return string
*/
protected function getSortNameLabelWithOutEmail() {
return ts('Contributor Name');
}
/**
* The post processing of the form gets done here.
*
* Key things done during post processing are
* - check for reset or next request. if present, skip post processing.
* - now check if user requested running a saved search, if so, then
* the form values associated with the saved search are used for searching.
* - if user has done a submit with new values the regular post submission is
* done.
* The processing consists of using a Selector / Controller framework for getting the
* search results.
*/
public function postProcess() {
if ($this->_done) {
return;
}
$this->_done = TRUE;
if (!empty($_POST)) {
$this->_formValues = $this->controller->exportValues($this->_name);
}
$this->fixFormValues();
// We don't show test records in summaries or dashboards
if (empty($this->_formValues['contribution_test']) && $this->_force && !empty($this->_context) && $this->_context == 'dashboard') {
$this->_formValues["contribution_test"] = 0;
}
foreach (array(
'contribution_amount_low',
'contribution_amount_high',
) as $f) {
if (isset($this->_formValues[$f])) {
$this->_formValues[$f] = CRM_Utils_Rule::cleanMoney($this->_formValues[$f]);
}
}
$config = CRM_Core_Config::singleton();
if (!empty($_POST)) {
$specialParams = array(
'financial_type_id',
'contribution_soft_credit_type_id',
'contribution_status_id',
'contribution_source',
'contribution_trxn_id',
'contribution_page_id',
'contribution_product_id',
'invoice_id',
'payment_instrument_id',
'contribution_batch_id',
);
CRM_Contact_BAO_Query::processSpecialFormValue($this->_formValues, $specialParams);
$tags = CRM_Utils_Array::value('contact_tags', $this->_formValues);
if ($tags && !is_array($tags)) {
unset($this->_formValues['contact_tags']);
$this->_formValues['contact_tags'][$tags] = 1;
}
if ($tags && is_array($tags)) {
unset($this->_formValues['contact_tags']);
foreach ($tags as $notImportant => $tagID) {
$this->_formValues['contact_tags'][$tagID] = 1;
}
}
$group = CRM_Utils_Array::value('group', $this->_formValues);
if ($group && !is_array($group)) {
unset($this->_formValues['group']);
$this->_formValues['group'][$group] = 1;
}
if ($group && is_array($group)) {
unset($this->_formValues['group']);
foreach ($group as $groupID) {
$this->_formValues['group'][$groupID] = 1;
}
}
}
CRM_Core_BAO_CustomValue::fixCustomFieldValue($this->_formValues);
$this->_queryParams = CRM_Contact_BAO_Query::convertFormValues($this->_formValues);
$this->set('formValues', $this->_formValues);
$this->set('queryParams', $this->_queryParams);
$buttonName = $this->controller->getButtonName();
if ($buttonName == $this->_actionButtonName) {
// check actionName and if next, then do not repeat a search, since we are going to the next page
// hack, make sure we reset the task values
$stateMachine = $this->controller->getStateMachine();
$formName = $stateMachine->getTaskFormName();
$this->controller->resetPage($formName);
return;
}
$sortID = NULL;
if ($this->get(CRM_Utils_Sort::SORT_ID)) {
$sortID = CRM_Utils_Sort::sortIDValue($this->get(CRM_Utils_Sort::SORT_ID),
$this->get(CRM_Utils_Sort::SORT_DIRECTION)
);
}
$this->_queryParams = CRM_Contact_BAO_Query::convertFormValues($this->_formValues);
$selector = new CRM_Contribute_Selector_Search($this->_queryParams,
$this->_action,
NULL,
$this->_single,
$this->_limit,
$this->_context
);
$selector->setKey($this->controller->_key);
$prefix = NULL;
if ($this->_context == 'basic' || $this->_context == 'user') {
$prefix = $this->_prefix;
}
$controller = new CRM_Core_Selector_Controller($selector,
$this->get(CRM_Utils_Pager::PAGE_ID),
$sortID,
CRM_Core_Action::VIEW,
$this,
CRM_Core_Selector_Controller::SESSION,
$prefix
);
$controller->setEmbedded(TRUE);
$query = &$selector->getQuery();
if ($this->_context == 'user') {
$query->setSkipPermission(TRUE);
}
$summary = &$query->summaryContribution($this->_context);
$this->set('summary', $summary);
$this->assign('contributionSummary', $summary);
$controller->run();
}
/**
* Use values from $_GET if force is set to TRUE.
*
* Note that this means that GET over-rides POST. This was a historical decision & the reasoning is not explained.
*/
public function fixFormValues() {
if (!$this->_force) {
return;
}
$status = CRM_Utils_Request::retrieve('status', 'String');
if ($status) {
$this->_formValues['contribution_status_id'] = array($status => 1);
$this->_defaults['contribution_status_id'] = array($status => 1);
}
$pcpid = (array) CRM_Utils_Request::retrieve('pcpid', 'String', $this);
if ($pcpid) {
// Add new pcpid to the tail of the array...
foreach ($pcpid as $pcpIdList) {
$this->_formValues['contribution_pcp_made_through_id'][] = $pcpIdList;
}
// and avoid any duplicate
$this->_formValues['contribution_pcp_made_through_id'] = array_unique($this->_formValues['contribution_pcp_made_through_id']);
}
$cid = CRM_Utils_Request::retrieve('cid', 'Positive', $this);
if ($cid) {
$cid = CRM_Utils_Type::escape($cid, 'Integer');
if ($cid > 0) {
$this->_formValues['contact_id'] = $cid;
// @todo - why do we retrieve these when they are not used?
list($display, $image) = CRM_Contact_BAO_Contact::getDisplayAndImage($cid);
$this->_defaults['sort_name'] = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Contact', $cid,
'sort_name'
);
// also assign individual mode to the template
$this->_single = TRUE;
}
}
$lowDate = CRM_Utils_Request::retrieve('start', 'Timestamp');
if ($lowDate) {
$lowDate = CRM_Utils_Type::escape($lowDate, 'Timestamp');
$date = CRM_Utils_Date::setDateDefaults($lowDate);
$this->_formValues['contribution_date_low'] = $this->_defaults['contribution_date_low'] = $date[0];
}
$highDate = CRM_Utils_Request::retrieve('end', 'Timestamp');
if ($highDate) {
$highDate = CRM_Utils_Type::escape($highDate, 'Timestamp');
$date = CRM_Utils_Date::setDateDefaults($highDate);
$this->_formValues['contribution_date_high'] = $this->_defaults['contribution_date_high'] = $date[0];
}
if ($highDate || $lowDate) {
//set the Choose Date Range value
$this->_formValues['contribution_date_relative'] = 0;
}
$this->_limit = CRM_Utils_Request::retrieve('limit', 'Positive',
$this
);
$test = CRM_Utils_Request::retrieve('test', 'Boolean');
if (isset($test)) {
$test = CRM_Utils_Type::escape($test, 'Boolean');
$this->_formValues['contribution_test'] = $test;
}
//Recurring id
$recur = CRM_Utils_Request::retrieve('recur', 'Positive', $this, FALSE);
if ($recur) {
$this->_formValues['contribution_recur_id'] = $recur;
$this->_formValues['contribution_recurring'] = 1;
}
//check for contribution page id.
$contribPageId = CRM_Utils_Request::retrieve('pid', 'Positive', $this);
if ($contribPageId) {
$this->_formValues['contribution_page_id'] = $contribPageId;
}
//give values to default.
$this->_defaults = $this->_formValues;
}
/**
* Return a descriptive name for the page, used in wizard header.
*
* @return string
*/
public function getTitle() {
return ts('Find Contributions');
}
}

View file

@ -0,0 +1,79 @@
<?php
/*
+--------------------------------------------------------------------+
| CiviCRM version 4.7 |
+--------------------------------------------------------------------+
| Copyright CiviCRM LLC (c) 2004-2017 |
+--------------------------------------------------------------------+
| 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 |
+--------------------------------------------------------------------+
*/
/**
*
* @package CRM
* @copyright CiviCRM LLC (c) 2004-2017
*/
class CRM_Contribute_Form_SearchContribution extends CRM_Core_Form {
/**
* Build the form object.
*/
public function buildQuickForm() {
$attributes = CRM_Core_DAO::getAttribute('CRM_Contribute_DAO_ContributionPage', 'title');
$attributes['style'] = 'width: 90%';
$this->add('text', 'title', ts('Find'), $attributes);
$financial_account = CRM_Contribute_PseudoConstant::financialType();
foreach ($financial_account as $contributionId => $contributionName) {
$this->addElement('checkbox', "financial_type_id[$contributionId]", 'Financial Type', $contributionName);
}
CRM_Campaign_BAO_Campaign::addCampaignInComponentSearch($this);
$this->addButtons(array(
array(
'type' => 'refresh',
'name' => ts('Search'),
'isDefault' => TRUE,
),
));
}
public function postProcess() {
$params = $this->controller->exportValues($this->_name);
$parent = $this->controller->getParent();
$parent->set('searchResult', 1);
if (!empty($params)) {
$fields = array('title', 'financial_type_id', 'campaign_id');
foreach ($fields as $field) {
if (isset($params[$field]) &&
!CRM_Utils_System::isNull($params[$field])
) {
$parent->set($field, $params[$field]);
}
else {
$parent->set($field, NULL);
}
}
}
}
}

View file

@ -0,0 +1,227 @@
<?php
/*
+--------------------------------------------------------------------+
| CiviCRM version 4.7 |
+--------------------------------------------------------------------+
| Copyright CiviCRM LLC (c) 2004-2017 |
+--------------------------------------------------------------------+
| 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 |
+--------------------------------------------------------------------+
*/
/**
*
* @package CRM
* @copyright CiviCRM LLC (c) 2004-2017
*/
/**
* This class build form elements for select existing or create new soft block.
*/
class CRM_Contribute_Form_SoftCredit {
/**
* Function used to build form element for soft credit block.
*
* @param CRM_Core_Form $form
*
* @return \CRM_Core_Form
*/
public static function buildQuickForm(&$form) {
if (!empty($form->_honor_block_is_active)) {
$ufJoinDAO = new CRM_Core_DAO_UFJoin();
$ufJoinDAO->module = 'soft_credit';
$ufJoinDAO->entity_id = $form->_id;
if ($ufJoinDAO->find(TRUE)) {
$jsonData = CRM_Contribute_BAO_ContributionPage::formatModuleData($ufJoinDAO->module_data, TRUE, 'soft_credit');
if ($jsonData) {
foreach (array('honor_block_title', 'honor_block_text') as $name) {
$form->assign($name, $jsonData[$name]);
}
$softCreditTypes = CRM_Core_OptionGroup::values("soft_credit_type", FALSE);
// radio button for Honor Type
foreach ($jsonData['soft_credit_types'] as $value) {
$honorTypes[$value] = $form->createElement('radio', NULL, NULL, $softCreditTypes[$value], $value);
}
$form->addGroup($honorTypes, 'soft_credit_type_id', NULL)->setAttribute('allowClear', TRUE);
}
}
return $form;
}
// by default generate 10 blocks
$item_count = 11;
$showSoftCreditRow = 2;
if ($form->getAction() & CRM_Core_Action::UPDATE) {
$form->_softCreditInfo = CRM_Contribute_BAO_ContributionSoft::getSoftContribution($form->_id, TRUE);
}
elseif (!empty($form->_pledgeID)) {
//Check and select most recent completed contrubtion and use it to retrieve
//soft-credit information to use as default for current pledge payment, CRM-13981
$pledgePayments = CRM_Pledge_BAO_PledgePayment::getPledgePayments($form->_pledgeID);
foreach ($pledgePayments as $id => $record) {
if ($record['contribution_id']) {
$softCredits = CRM_Contribute_BAO_ContributionSoft::getSoftContribution($record['contribution_id'], TRUE);
if ($record['status'] == 'Completed' && count($softCredits) > 0) {
$form->_softCreditInfo = $softCredits;
}
}
}
}
if (property_exists($form, "_softCreditInfo")) {
if (!empty($form->_softCreditInfo['soft_credit'])) {
$showSoftCreditRow = count($form->_softCreditInfo['soft_credit']);
$showSoftCreditRow++;
}
}
for ($rowNumber = 1; $rowNumber <= $item_count; $rowNumber++) {
$form->addEntityRef("soft_credit_contact_id[{$rowNumber}]", ts('Contact'), array('create' => TRUE));
$form->addMoney("soft_credit_amount[{$rowNumber}]", ts('Amount'), FALSE, NULL, FALSE);
$form->addSelect("soft_credit_type[{$rowNumber}]", array(
'entity' => 'contribution_soft',
'field' => 'soft_credit_type_id',
'label' => ts('Type'),
));
if (!empty($form->_softCreditInfo['soft_credit'][$rowNumber]['soft_credit_id'])) {
$form->add('hidden', "soft_credit_id[{$rowNumber}]",
$form->_softCreditInfo['soft_credit'][$rowNumber]['soft_credit_id']);
}
}
self::addPCPFields($form);
$form->assign('showSoftCreditRow', $showSoftCreditRow);
$form->assign('rowCount', $item_count);
$form->addElement('hidden', 'sct_default_id',
CRM_Core_OptionGroup::getDefaultValue("soft_credit_type"),
array('id' => 'sct_default_id')
);
}
/**
* Add PCP fields for the new contribution form and others.
*
* @param CRM_Core_Form &$form
* The form being built.
* @param string $suffix
* A suffix to add to field names.
*/
public static function addPCPFields(&$form, $suffix = '') {
// CRM-7368 allow user to set or edit PCP link for contributions
$siteHasPCPs = CRM_Contribute_PseudoConstant::pcPage();
if (!CRM_Utils_Array::crmIsEmptyArray($siteHasPCPs)) {
$form->assign('siteHasPCPs', 1);
// Fixme: Not a true entityRef field. Relies on PCP.js.tpl
$form->add('text', "pcp_made_through_id$suffix", ts('Credit to a Personal Campaign Page'), array('class' => 'twenty', 'placeholder' => ts('- select -')));
// stores the label
$form->add('hidden', "pcp_made_through$suffix");
$form->addElement('checkbox', "pcp_display_in_roll$suffix", ts('Display in Honor Roll?'), NULL);
$form->addElement('text', "pcp_roll_nickname$suffix", ts('Name (for Honor Roll)'));
$form->addElement('textarea', "pcp_personal_note$suffix", ts('Personal Note (for Honor Roll)'));
}
}
/**
* Function used to set defaults for soft credit block.
*
* @param $defaults
* @param $form
*/
public static function setDefaultValues(&$defaults, &$form) {
//Used to hide/unhide PCP and/or Soft-credit Panes
$noPCP = $noSoftCredit = TRUE;
if (!empty($form->_softCreditInfo['soft_credit'])) {
$noSoftCredit = FALSE;
foreach ($form->_softCreditInfo['soft_credit'] as $key => $value) {
$defaults["soft_credit_amount[$key]"] = CRM_Utils_Money::format($value['amount'], NULL, '%a');
$defaults["soft_credit_contact_id[$key]"] = $value['contact_id'];
$defaults["soft_credit_type[$key]"] = $value['soft_credit_type'];
}
}
if (!empty($form->_softCreditInfo['pcp_id'])) {
$noPCP = FALSE;
$pcpInfo = $form->_softCreditInfo;
$pcpId = CRM_Utils_Array::value('pcp_id', $pcpInfo);
$pcpTitle = CRM_Core_DAO::getFieldValue('CRM_PCP_DAO_PCP', $pcpId, 'title');
$contributionPageTitle = CRM_PCP_BAO_PCP::getPcpPageTitle($pcpId, 'contribute');
$defaults['pcp_made_through'] = CRM_Utils_Array::value('sort_name', $pcpInfo) . " :: " . $pcpTitle . " :: " . $contributionPageTitle;
$defaults['pcp_made_through_id'] = CRM_Utils_Array::value('pcp_id', $pcpInfo);
$defaults['pcp_display_in_roll'] = CRM_Utils_Array::value('pcp_display_in_roll', $pcpInfo);
$defaults['pcp_roll_nickname'] = CRM_Utils_Array::value('pcp_roll_nickname', $pcpInfo);
$defaults['pcp_personal_note'] = CRM_Utils_Array::value('pcp_personal_note', $pcpInfo);
}
$form->assign('noSoftCredit', $noSoftCredit);
$form->assign('noPCP', $noPCP);
}
/**
* Global form rule.
*
* @param array $fields
* The input form values.
*
* @param $errors
* @param $self
*
* @return array
* Array of errors
*/
public static function formRule($fields, $errors, $self) {
$errors = array();
// if honor roll fields are populated but no PCP is selected
if (empty($fields['pcp_made_through_id'])) {
if (!empty($fields['pcp_display_in_roll']) || !empty($fields['pcp_roll_nickname']) ||
CRM_Utils_Array::value('pcp_personal_note', $fields)
) {
$errors['pcp_made_through_id'] = ts('Please select a Personal Campaign Page, OR uncheck Display in Honor Roll and clear both the Honor Roll Name and the Personal Note field.');
}
}
if (!empty($fields['soft_credit_amount'])) {
$repeat = array_count_values($fields['soft_credit_contact_id']);
foreach ($fields['soft_credit_amount'] as $key => $val) {
if (!empty($fields['soft_credit_contact_id'][$key])) {
if ($repeat[$fields['soft_credit_contact_id'][$key]] > 1) {
$errors["soft_credit_contact_id[$key]"] = ts('You cannot enter multiple soft credits for the same contact.');
}
if ($self->_action == CRM_Core_Action::ADD && $fields['soft_credit_amount'][$key]
&& (CRM_Utils_Rule::cleanMoney($fields['soft_credit_amount'][$key]) > CRM_Utils_Rule::cleanMoney($fields['total_amount']))
) {
$errors["soft_credit_amount[$key]"] = ts('Soft credit amount cannot be more than the total amount.');
}
if (empty($fields['soft_credit_amount'][$key])) {
$errors["soft_credit_amount[$key]"] = ts('Please enter the soft credit amount.');
}
}
}
}
return $errors;
}
}

View file

@ -0,0 +1,251 @@
<?php
/*
+--------------------------------------------------------------------+
| CiviCRM version 4.7 |
+--------------------------------------------------------------------+
| Copyright CiviCRM LLC (c) 2004-2017 |
+--------------------------------------------------------------------+
| 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 |
+--------------------------------------------------------------------+
*/
/**
*
* @package CRM
* @copyright CiviCRM LLC (c) 2004-2017
*/
/**
* This class generates form components for relationship.
*/
class CRM_Contribute_Form_Task extends CRM_Core_Form {
/**
* The task being performed.
*
* @var int
*/
protected $_task;
/**
* The additional clause that we restrict the search with.
*
* @var string
*/
protected $_componentClause = NULL;
/**
* The array that holds all the component ids.
*
* @var array
*/
protected $_componentIds;
/**
* The array that holds all the contribution ids.
*
* @var array
*/
protected $_contributionIds;
/**
* The array that holds all the contact ids.
*
* @var array
*/
public $_contactIds;
/**
* The array that holds all the mapping contribution and contact ids.
*
* @var array
*/
protected $_contributionContactIds = array();
/**
* The flag to tell if there are soft credits included.
*
* @var boolean
*/
public $_includesSoftCredits = FALSE;
/**
* Build all the data structures needed to build the form.
*/
public function preProcess() {
self::preProcessCommon($this);
}
/**
* @param CRM_Core_Form $form
* @param bool $useTable
*/
public static function preProcessCommon(&$form, $useTable = FALSE) {
$form->_contributionIds = array();
$values = $form->controller->exportValues($form->get('searchFormName'));
$form->_task = CRM_Utils_Array::value('task', $values);
$contributeTasks = CRM_Contribute_Task::tasks();
$form->assign('taskName', CRM_Utils_Array::value($form->_task, $contributeTasks));
$ids = array();
if (isset($values['radio_ts']) && $values['radio_ts'] == 'ts_sel') {
foreach ($values as $name => $value) {
if (substr($name, 0, CRM_Core_Form::CB_PREFIX_LEN) == CRM_Core_Form::CB_PREFIX) {
$ids[] = substr($name, CRM_Core_Form::CB_PREFIX_LEN);
}
}
}
else {
$queryParams = $form->get('queryParams');
$isTest = FALSE;
foreach ($queryParams as $fields) {
if ($fields[0] == 'contribution_test') {
$isTest = TRUE;
break;
}
}
if (!$isTest) {
$queryParams[] = array(
'contribution_test',
'=',
0,
0,
0,
);
}
$returnProperties = array('contribution_id' => 1);
$sortOrder = $sortCol = NULL;
if ($form->get(CRM_Utils_Sort::SORT_ORDER)) {
$sortOrder = $form->get(CRM_Utils_Sort::SORT_ORDER);
//Include sort column in select clause.
$sortCol = trim(str_replace(array('`', 'asc', 'desc'), '', $sortOrder));
$returnProperties[$sortCol] = 1;
}
$form->_includesSoftCredits = CRM_Contribute_BAO_Query::isSoftCreditOptionEnabled($queryParams);
$query = new CRM_Contact_BAO_Query($queryParams, $returnProperties, NULL, FALSE, FALSE,
CRM_Contact_BAO_Query::MODE_CONTRIBUTE
);
// @todo the function CRM_Contribute_BAO_Query::isSoftCreditOptionEnabled should handle this
// can we remove? if not why not?
if ($form->_includesSoftCredits) {
$contactIds = $contributionContactIds = array();
$query->_rowCountClause = " count(civicrm_contribution.id)";
$query->_groupByComponentClause = " GROUP BY contribution_search_scredit_combined.id, contribution_search_scredit_combined.contact_id, contribution_search_scredit_combined.scredit_id ";
}
else {
$query->_distinctComponentClause = ' civicrm_contribution.id';
$query->_groupByComponentClause = ' GROUP BY civicrm_contribution.id ';
}
$result = $query->searchQuery(0, 0, $sortOrder);
while ($result->fetch()) {
$ids[] = $result->contribution_id;
if ($form->_includesSoftCredits) {
$contactIds[$result->contact_id] = $result->contact_id;
$contributionContactIds["{$result->contact_id}-{$result->contribution_id}"] = $result->contribution_id;
}
}
$result->free();
$form->assign('totalSelectedContributions', $form->get('rowCount'));
}
if (!empty($ids)) {
$form->_componentClause = ' civicrm_contribution.id IN ( ' . implode(',', $ids) . ' ) ';
$form->assign('totalSelectedContributions', count($ids));
}
if (!empty($form->_includesSoftCredits) && !empty($contactIds)) {
$form->_contactIds = $contactIds;
$form->_contributionContactIds = $contributionContactIds;
}
$form->_contributionIds = $form->_componentIds = $ids;
$form->set('contributionIds', $form->_contributionIds);
//set the context for redirection for any task actions
$session = CRM_Core_Session::singleton();
$qfKey = CRM_Utils_Request::retrieve('qfKey', 'String', $form);
$urlParams = 'force=1';
if (CRM_Utils_Rule::qfKey($qfKey)) {
$urlParams .= "&qfKey=$qfKey";
}
$searchFormName = strtolower($form->get('searchFormName'));
if ($searchFormName == 'search') {
$session->replaceUserContext(CRM_Utils_System::url('civicrm/contribute/search', $urlParams));
}
else {
$session->replaceUserContext(CRM_Utils_System::url("civicrm/contact/search/$searchFormName",
$urlParams
));
}
}
/**
* Sets contribution Ids for unit test.
*
* @param array $contributionIds
*/
public function setContributionIds($contributionIds) {
$this->_contributionIds = $contributionIds;
}
/**
* Given the contribution id, compute the contact id
* since its used for things like send email
*/
public function setContactIDs() {
if (!$this->_includesSoftCredits) {
$this->_contactIds = &CRM_Core_DAO::getContactIDsFromComponent(
$this->_contributionIds,
'civicrm_contribution'
);
}
}
/**
* Simple shell that derived classes can call to add buttons to
* the form with a customized title for the main Submit
*
* @param string $title
* Title of the main button.
* @param string $nextType
* Button type for the form after processing.
* @param string $backType
* @param bool $submitOnce
*/
public function addDefaultButtons($title, $nextType = 'next', $backType = 'back', $submitOnce = FALSE) {
$this->addButtons(array(
array(
'type' => $nextType,
'name' => $title,
'isDefault' => TRUE,
),
array(
'type' => $backType,
'name' => ts('Cancel'),
),
)
);
}
}

View file

@ -0,0 +1,240 @@
<?php
/*
+--------------------------------------------------------------------+
| CiviCRM version 4.7 |
+--------------------------------------------------------------------+
| Copyright CiviCRM LLC (c) 2004-2017 |
+--------------------------------------------------------------------+
| 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 |
+--------------------------------------------------------------------+
*/
/**
*
* @package CRM
* @copyright CiviCRM LLC (c) 2004-2017
*/
/**
* This class provides the functionality for batch profile update for contributions.
*/
class CRM_Contribute_Form_Task_Batch extends CRM_Contribute_Form_Task {
/**
* The title of the group
*
* @var string
*/
protected $_title;
/**
* Maximum profile fields that will be displayed
*/
protected $_maxFields = 9;
/**
* Variable to store redirect path
*/
protected $_userContext;
/**
* Build all the data structures needed to build the form.
*/
public function preProcess() {
// initialize the task and row fields
parent::preProcess();
//get the contact read only fields to display.
$readOnlyFields = array_merge(array('sort_name' => ts('Name')),
CRM_Core_BAO_Setting::valueOptions(CRM_Core_BAO_Setting::SYSTEM_PREFERENCES_NAME,
'contact_autocomplete_options',
TRUE, NULL, FALSE, 'name', TRUE
)
);
//get the read only field data.
$returnProperties = array_fill_keys(array_keys($readOnlyFields), 1);
$contactDetails = CRM_Contact_BAO_Contact_Utils::contactDetails($this->_contributionIds,
'CiviContribute', $returnProperties
);
$this->assign('contactDetails', $contactDetails);
$this->assign('readOnlyFields', $readOnlyFields);
}
/**
* Build the form object.
*/
public function buildQuickForm() {
$ufGroupId = $this->get('ufGroupId');
if (!$ufGroupId) {
CRM_Core_Error::fatal('ufGroupId is missing');
}
$this->_title = ts('Update multiple contributions') . ' - ' . CRM_Core_BAO_UFGroup::getTitle($ufGroupId);
CRM_Utils_System::setTitle($this->_title);
$this->addDefaultButtons(ts('Save'));
$this->_fields = array();
$this->_fields = CRM_Core_BAO_UFGroup::getFields($ufGroupId, FALSE, CRM_Core_Action::VIEW);
// remove file type field and then limit fields
$suppressFields = FALSE;
$removehtmlTypes = array('File', 'Autocomplete-Select');
foreach ($this->_fields as $name => $field) {
if ($cfID = CRM_Core_BAO_CustomField::getKeyID($name) &&
in_array($this->_fields[$name]['html_type'], $removehtmlTypes)
) {
$suppressFields = TRUE;
unset($this->_fields[$name]);
}
//fix to reduce size as we are using this field in grid
if (is_array($field['attributes']) && !empty($this->_fields[$name]['attributes']['size']) && $this->_fields[$name]['attributes']['size'] > 19) {
//shrink class to "form-text-medium"
$this->_fields[$name]['attributes']['size'] = 19;
}
}
$this->_fields = array_slice($this->_fields, 0, $this->_maxFields);
$this->addButtons(array(
array(
'type' => 'submit',
'name' => ts('Update Contribution(s)'),
'isDefault' => TRUE,
),
array(
'type' => 'cancel',
'name' => ts('Cancel'),
),
)
);
$this->assign('profileTitle', $this->_title);
$this->assign('componentIds', $this->_contributionIds);
//load all campaigns.
if (array_key_exists('contribution_campaign_id', $this->_fields)) {
$this->_componentCampaigns = array();
CRM_Core_PseudoConstant::populate($this->_componentCampaigns,
'CRM_Contribute_DAO_Contribution',
TRUE, 'campaign_id', 'id',
' id IN (' . implode(' , ', array_values($this->_contributionIds)) . ' ) '
);
}
// It is possible to have fields that are required in CiviCRM not be required in the
// profile. Overriding that here. Perhaps a better approach would be to
// make them required in the schema & read that up through getFields functionality.
$requiredFields = array('receive_date');
//fix for CRM-2752
$customFields = CRM_Core_BAO_CustomField::getFields('Contribution');
foreach ($this->_contributionIds as $contributionId) {
$typeId = CRM_Core_DAO::getFieldValue("CRM_Contribute_DAO_Contribution", $contributionId, 'financial_type_id');
foreach ($this->_fields as $name => $field) {
$entityColumnValue = array();
if ($customFieldID = CRM_Core_BAO_CustomField::getKeyID($name)) {
$customValue = CRM_Utils_Array::value($customFieldID, $customFields);
if (!empty($customValue['extends_entity_column_value'])) {
$entityColumnValue = explode(CRM_Core_DAO::VALUE_SEPARATOR,
$customValue['extends_entity_column_value']
);
}
if (!empty($entityColumnValue[$typeId]) ||
CRM_Utils_System::isNull(CRM_Utils_Array::value($typeId, $entityColumnValue))
) {
CRM_Core_BAO_UFGroup::buildProfile($this, $field, NULL, $contributionId);
}
}
else {
// handle non custom fields
if (in_array($field['name'], $requiredFields)) {
$field['is_required'] = TRUE;
}
CRM_Core_BAO_UFGroup::buildProfile($this, $field, NULL, $contributionId);
}
}
}
$this->assign('fields', $this->_fields);
// don't set the status message when form is submitted.
$buttonName = $this->controller->getButtonName('submit');
if ($suppressFields && $buttonName != '_qf_Batch_next') {
CRM_Core_Session::setStatus(ts("File or Autocomplete-Select type field(s) in the selected profile are not supported for Update multiple contributions."), ts('Unsupported Field Type'), 'error');
}
$this->addDefaultButtons(ts('Update Contributions'));
}
/**
* Set default values for the form.
*/
public function setDefaultValues() {
if (empty($this->_fields)) {
return;
}
$defaults = array();
foreach ($this->_contributionIds as $contributionId) {
CRM_Core_BAO_UFGroup::setProfileDefaults(NULL, $this->_fields, $defaults, FALSE, $contributionId, 'Contribute');
}
return $defaults;
}
/**
* Process the form after the input has been submitted and validated.
*/
public function postProcess() {
$params = $this->exportValues();
if (isset($params['field'])) {
foreach ($params['field'] as $contributionID => $value) {
$value['id'] = $contributionID;
if (!empty($value['financial_type'])) {
$value['financial_type_id'] = $value['financial_type'];
}
$value['options'] = array(
'reload' => 1,
);
$contribution = civicrm_api3('Contribution', 'create', $value);
$contribution = $contribution['values'][$contributionID];
// @todo add check as to whether the status is updated.
if (!empty($value['contribution_status_id'])) {
// @todo - use completeorder api or make api call do this.
CRM_Contribute_BAO_Contribution::transitionComponentWithReturnMessage($contribution['id'],
$value['contribution_status_id'],
CRM_Utils_Array::value("field[{$contributionID}][contribution_status_id]", $this->_defaultValues),
$contribution['receive_date']
);
}
}
CRM_Core_Session::setStatus(ts("Your updates have been saved."), ts('Saved'), 'success');
}
else {
CRM_Core_Session::setStatus(ts("No updates have been saved."), ts('Not Saved'), 'alert');
}
}
}

View file

@ -0,0 +1,127 @@
<?php
/*
+--------------------------------------------------------------------+
| CiviCRM version 4.7 |
+--------------------------------------------------------------------+
| Copyright CiviCRM LLC (c) 2004-2017 |
+--------------------------------------------------------------------+
| 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 |
+--------------------------------------------------------------------+
*/
/**
*
* @package CRM
* @copyright CiviCRM LLC (c) 2004-2017
*/
/**
* This class provides the functionality to delete a group of contributions.
*
* This class provides functionality for the actual deletion.
*/
class CRM_Contribute_Form_Task_Delete extends CRM_Contribute_Form_Task {
/**
* Are we operating in "single mode", i.e. deleting one
* specific contribution?
*
* @var boolean
*/
protected $_single = FALSE;
/**
* Build all the data structures needed to build the form.
*/
public function preProcess() {
//check for delete
if (!CRM_Core_Permission::checkActionPermission('CiviContribute', CRM_Core_Action::DELETE)) {
CRM_Core_Error::fatal(ts('You do not have permission to access this page.'));
}
parent::preProcess();
}
/**
* Build the form object.
*/
public function buildQuickForm() {
$count = 0;
if (CRM_Financial_BAO_FinancialType::isACLFinancialTypeStatus()) {
foreach ($this->_contributionIds as $key => $id) {
$finTypeID = CRM_Core_DAO::getFieldValue('CRM_Contribute_DAO_Contribution', $id, 'financial_type_id');
if (!CRM_Core_Permission::check('delete contributions of type ' . CRM_Contribute_PseudoConstant::financialType($finTypeID))) {
unset($this->_contributionIds[$key]);
$count++;
}
// Now check for lineItems
if ($lineItems = CRM_Price_BAO_LineItem::getLineItemsByContributionID($id)) {
foreach ($lineItems as $items) {
if (!CRM_Core_Permission::check('delete contributions of type ' . CRM_Contribute_PseudoConstant::financialType($items['financial_type_id']))) {
unset($this->_contributionIds[$key]);
$count++;
break;
}
}
}
}
}
if ($count && empty($this->_contributionIds)) {
CRM_Core_Session::setStatus(ts('1 contribution could not be deleted.', array('plural' => '%count contributions could not be deleted.', 'count' => $count)), ts('Error'), 'error');
$this->addButtons(array(
array(
'type' => 'back',
'name' => ts('Cancel'),
),
)
);
}
elseif ($count && !empty($this->_contributionIds)) {
CRM_Core_Session::setStatus(ts('1 contribution will not be deleted.', array('plural' => '%count contributions will not be deleted.', 'count' => $count)), ts('Warning'), 'warning');
$this->addDefaultButtons(ts('Delete Contributions'), 'done');
}
else {
$this->addDefaultButtons(ts('Delete Contributions'), 'done');
}
}
/**
* Process the form after the input has been submitted and validated.
*/
public function postProcess() {
$deleted = $failed = 0;
foreach ($this->_contributionIds as $contributionId) {
if (CRM_Contribute_BAO_Contribution::deleteContribution($contributionId)) {
$deleted++;
}
else {
$failed++;
}
}
if ($deleted) {
$msg = ts('%count contribution deleted.', array('plural' => '%count contributions deleted.', 'count' => $deleted));
CRM_Core_Session::setStatus($msg, ts('Removed'), 'success');
}
if ($failed) {
CRM_Core_Session::setStatus(ts('1 could not be deleted.', array('plural' => '%count could not be deleted.', 'count' => $failed)), ts('Error'), 'error');
}
}
}

View file

@ -0,0 +1,97 @@
<?php
/*
+--------------------------------------------------------------------+
| CiviCRM version 4.7 |
+--------------------------------------------------------------------+
| Copyright CiviCRM LLC (c) 2004-2017 |
+--------------------------------------------------------------------+
| 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 |
+--------------------------------------------------------------------+
*/
/**
*
* @package CRM
* @copyright CiviCRM LLC (c) 2004-2017
*/
/**
* This class provides the functionality to email a group of contacts.
*/
class CRM_Contribute_Form_Task_Email extends CRM_Contribute_Form_Task {
/**
* Are we operating in "single mode", i.e. sending email to one
* specific contact?
*
* @var boolean
*/
public $_single = FALSE;
public $_noEmails = FALSE;
/**
* All the existing templates in the system.
*
* @var array
*/
public $_templates = NULL;
/**
* Build all the data structures needed to build the form.
*/
public function preProcess() {
CRM_Contact_Form_Task_EmailCommon::preProcessFromAddress($this);
parent::preProcess();
// we have all the contribution ids, so now we get the contact ids
parent::setContactIDs();
$this->assign('single', $this->_single);
}
/**
* Build the form object.
*/
public function buildQuickForm() {
//enable form element
$this->assign('emailTask', TRUE);
CRM_Contact_Form_Task_EmailCommon::buildQuickForm($this);
}
/**
* Process the form after the input has been submitted and validated.
*/
public function postProcess() {
CRM_Contact_Form_Task_EmailCommon::postProcess($this);
}
/**
* List available tokens for this form.
*
* @return array
*/
public function listTokens() {
$tokens = CRM_Core_SelectValues::contactTokens();
$tokens = array_merge(CRM_Core_SelectValues::contributionTokens(), $tokens);
return $tokens;
}
}

View file

@ -0,0 +1,683 @@
<?php
/*
+--------------------------------------------------------------------+
| CiviCRM version 4.7 |
+--------------------------------------------------------------------+
| Copyright CiviCRM LLC (c) 2004-2017 |
+--------------------------------------------------------------------+
| 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 |
+--------------------------------------------------------------------+
*/
use Dompdf\Dompdf;
use Dompdf\Options;
/**
*
* @package CRM
* @copyright CiviCRM LLC (c) 2004-2017
*/
/**
* This class provides the functionality to email a group of
* contacts.
*/
class CRM_Contribute_Form_Task_Invoice extends CRM_Contribute_Form_Task {
/**
* Are we operating in "single mode", i.e. updating the task of only
* one specific contribution?
*
* @var boolean
*/
public $_single = FALSE;
/**
* Gives all the statues for conribution.
*/
public $_contributionStatusId;
/**
* Gives the HTML template of PDF Invoice.
*/
public $_messageInvoice;
/**
* This variable is used to assign parameters for HTML template of PDF Invoice.
*/
public $_invoiceTemplate;
/**
* Selected output.
*/
public $_selectedOutput;
/**
* Build all the data structures needed to build the form.
*/
public function preProcess() {
$id = CRM_Utils_Request::retrieve('id', 'Positive', $this, FALSE);
if ($id) {
$this->_contributionIds = array($id);
$this->_componentClause = " civicrm_contribution.id IN ( $id ) ";
$this->_single = TRUE;
$this->assign('totalSelectedContributions', 1);
// set the redirection after actions
$contactId = CRM_Utils_Request::retrieve('cid', 'Positive', $this, FALSE);
$url = CRM_Utils_System::url('civicrm/contact/view/contribution',
"action=view&reset=1&id={$id}&cid={$contactId}&context=contribution&selectedChild=contribute"
);
CRM_Core_Session::singleton()->pushUserContext($url);
}
else {
parent::preProcess();
}
// check that all the contribution ids have status Completed, Pending, Refunded.
$this->_contributionStatusId = CRM_Contribute_PseudoConstant::contributionStatus(NULL, 'name');
$status = array('Completed', 'Pending', 'Refunded');
$statusId = array();
foreach ($this->_contributionStatusId as $key => $value) {
if (in_array($value, $status)) {
$statusId[] = $key;
}
}
$Id = implode(",", $statusId);
$query = "SELECT count(*) FROM civicrm_contribution WHERE contribution_status_id NOT IN ($Id) AND {$this->_componentClause}";
$count = CRM_Core_DAO::singleValueQuery($query);
if ($count != 0) {
CRM_Core_Error::statusBounce(ts('Please select only contributions with Completed, Pending, Refunded status.'));
}
// we have all the contribution ids, so now we get the contact ids
parent::setContactIDs();
$this->assign('single', $this->_single);
$qfKey = CRM_Utils_Request::retrieve('qfKey', 'String', $this);
$urlParams = 'force=1';
if (CRM_Utils_Rule::qfKey($qfKey)) {
$urlParams .= "&qfKey=$qfKey";
}
$url = CRM_Utils_System::url('civicrm/contribute/search', $urlParams);
$breadCrumb = array(
array(
'url' => $url,
'title' => ts('Search Results'),
),
);
CRM_Utils_System::appendBreadCrumb($breadCrumb);
$this->_selectedOutput = CRM_Utils_Request::retrieve('select', 'String', $this);
$this->assign('selectedOutput', $this->_selectedOutput);
if ($this->_selectedOutput == 'email') {
CRM_Utils_System::setTitle(ts('Email Invoice'));
}
else {
CRM_Utils_System::setTitle(ts('Print Contribution Invoice'));
}
}
/**
* Build the form object.
*/
public function buildQuickForm() {
$session = CRM_Core_Session::singleton();
$this->preventAjaxSubmit();
if (CRM_Core_Permission::check('administer CiviCRM')) {
$this->assign('isAdmin', 1);
}
$contactID = $session->get('userID');
$contactEmails = CRM_Core_BAO_Email::allEmails($contactID);
$emails = array();
$fromDisplayName = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Contact',
$contactID, 'display_name'
);
foreach ($contactEmails as $emailId => $item) {
$email = $item['email'];
if ($email) {
$emails[$emailId] = '"' . $fromDisplayName . '" <' . $email . '> ';
}
if (isset($emails[$emailId])) {
$emails[$emailId] .= $item['locationType'];
if ($item['is_primary']) {
$emails[$emailId] .= ' ' . ts('(preferred)');
}
$emails[$emailId] = htmlspecialchars($emails[$emailId]);
}
}
$fromEmailAddress = CRM_Core_OptionGroup::values('from_email_address');
foreach ($fromEmailAddress as $key => $email) {
$fromEmailAddress[$key] = htmlspecialchars($fromEmailAddress[$key]);
}
$fromEmail = CRM_Utils_Array::crmArrayMerge($emails, $fromEmailAddress);
$this->add('select', 'from_email_address', ts('From Email Address'), array('' => '- select -') + $fromEmail);
if ($this->_selectedOutput != 'email') {
$this->addElement('radio', 'output', NULL, ts('Email Invoice'), 'email_invoice');
$this->addElement('radio', 'output', NULL, ts('PDF Invoice'), 'pdf_invoice');
$this->addRule('output', ts('Selection required'), 'required');
$this->addFormRule(array('CRM_Contribute_Form_Task_Invoice', 'formRule'));
}
else {
$this->addRule('from_email_address', ts('From Email Address is required'), 'required');
}
$this->add('wysiwyg', 'email_comment', ts('If you would like to add personal message to email please add it here. (If sending to more then one receipient the same message will be sent to each contact.)'), array(
'rows' => 2,
'cols' => 40,
));
$this->addButtons(array(
array(
'type' => 'upload',
'name' => $this->_selectedOutput == 'email' ? ts('Send Email') : ts('Process Invoice(s)'),
'isDefault' => TRUE,
),
array(
'type' => 'cancel',
'name' => ts('Cancel'),
),
)
);
}
/**
* Global validation rules for the form.
*
* @param array $values
*
* @return array
* list of errors to be posted back to the form
*/
public static function formRule($values) {
$errors = array();
if ($values['output'] == 'email_invoice' && empty($values['from_email_address'])) {
$errors['from_email_address'] = ts("From Email Address is required");
}
return $errors;
}
/**
* Process the form after the input has been submitted and validated.
*/
public function postProcess() {
$params = $this->controller->exportValues($this->_name);
self::printPDF($this->_contributionIds, $params, $this->_contactIds);
}
/**
* Process the PDf and email with activity and attachment on click of Print Invoices.
*
* @param array $contribIDs
* Contribution Id.
* @param array $params
* Associated array of submitted values.
* @param array $contactIds
* Contact Id.
*/
public static function printPDF($contribIDs, &$params, $contactIds) {
// get all the details needed to generate a invoice
$messageInvoice = array();
$invoiceTemplate = CRM_Core_Smarty::singleton();
$invoiceElements = CRM_Contribute_Form_Task_PDF::getElements($contribIDs, $params, $contactIds);
// gives the status id when contribution status is 'Refunded'
$contributionStatusID = CRM_Contribute_PseudoConstant::contributionStatus(NULL, 'name');
$refundedStatusId = CRM_Utils_Array::key('Refunded', $contributionStatusID);
$cancelledStatusId = CRM_Utils_Array::key('Cancelled', $contributionStatusID);
$pendingStatusId = CRM_Utils_Array::key('Pending', $contributionStatusID);
// getting data from admin page
$prefixValue = Civi::settings()->get('contribution_invoice_settings');
foreach ($invoiceElements['details'] as $contribID => $detail) {
$input = $ids = $objects = array();
if (in_array($detail['contact'], $invoiceElements['excludeContactIds'])) {
continue;
}
$input['component'] = $detail['component'];
$ids['contact'] = $detail['contact'];
$ids['contribution'] = $contribID;
$ids['contributionRecur'] = NULL;
$ids['contributionPage'] = NULL;
$ids['membership'] = CRM_Utils_Array::value('membership', $detail);
$ids['participant'] = CRM_Utils_Array::value('participant', $detail);
$ids['event'] = CRM_Utils_Array::value('event', $detail);
if (!$invoiceElements['baseIPN']->validateData($input, $ids, $objects, FALSE)) {
CRM_Core_Error::fatal();
}
$contribution = &$objects['contribution'];
$input['amount'] = $contribution->total_amount;
$input['invoice_id'] = $contribution->invoice_id;
$input['receive_date'] = $contribution->receive_date;
$input['contribution_status_id'] = $contribution->contribution_status_id;
$input['organization_name'] = $contribution->_relatedObjects['contact']->organization_name;
$objects['contribution']->receive_date = CRM_Utils_Date::isoToMysql($objects['contribution']->receive_date);
$addressParams = array('contact_id' => $contribution->contact_id);
$addressDetails = CRM_Core_BAO_Address::getValues($addressParams);
// to get billing address if present
$billingAddress = array();
foreach ($addressDetails as $address) {
if (($address['is_billing'] == 1) && ($address['is_primary'] == 1) && ($address['contact_id'] == $contribution->contact_id)) {
$billingAddress[$address['contact_id']] = $address;
break;
}
elseif (($address['is_billing'] == 0 && $address['is_primary'] == 1) || ($address['is_billing'] == 1) && ($address['contact_id'] == $contribution->contact_id)) {
$billingAddress[$address['contact_id']] = $address;
}
}
if (!empty($billingAddress[$contribution->contact_id]['state_province_id'])) {
$stateProvinceAbbreviation = CRM_Core_PseudoConstant::stateProvinceAbbreviation($billingAddress[$contribution->contact_id]['state_province_id']);
}
else {
$stateProvinceAbbreviation = '';
}
if ($contribution->contribution_status_id == $refundedStatusId || $contribution->contribution_status_id == $cancelledStatusId) {
if (is_null($contribution->creditnote_id)) {
$creditNoteId = CRM_Contribute_BAO_Contribution::createCreditNoteId();
CRM_Core_DAO::setFieldValue('CRM_Contribute_DAO_Contribution', $contribution->id, 'creditnote_id', $creditNoteId);
}
else {
$creditNoteId = $contribution->creditnote_id;
}
}
if (!$contribution->invoice_number) {
$contribution->invoice_number = CRM_Contribute_BAO_Contribution::getInvoiceNumber($contribution->id);
}
//to obtain due date for PDF invoice
$contributionReceiveDate = date('F j,Y', strtotime(date($input['receive_date'])));
$invoiceDate = date("F j, Y");
$dueDate = date('F j, Y', strtotime($contributionReceiveDate . "+" . $prefixValue['due_date'] . "" . $prefixValue['due_date_period']));
if ($input['component'] == 'contribute') {
$lineItem = CRM_Price_BAO_LineItem::getLineItemsByContributionID($contribID);
}
else {
$eid = $contribution->_relatedObjects['participant']->id;
$lineItem = CRM_Price_BAO_LineItem::getLineItems($eid, 'participant', NULL, TRUE, FALSE, TRUE);
}
$resultPayments = civicrm_api3('Payment', 'get', array(
'sequential' => 1,
'contribution_id' => $contribID,
));
$amountPaid = 0;
foreach ($resultPayments['values'] as $singlePayment) {
// Only count payments that have been (status =) completed.
if ($singlePayment['status_id'] == 1) {
$amountPaid += $singlePayment['total_amount'];
}
}
$amountDue = ($input['amount'] - $amountPaid);
// retrieving the subtotal and sum of same tax_rate
$dataArray = array();
$subTotal = 0;
foreach ($lineItem as $taxRate) {
if (isset($dataArray[(string) $taxRate['tax_rate']])) {
$dataArray[(string) $taxRate['tax_rate']] = $dataArray[(string) $taxRate['tax_rate']] + CRM_Utils_Array::value('tax_amount', $taxRate);
}
else {
$dataArray[(string) $taxRate['tax_rate']] = CRM_Utils_Array::value('tax_amount', $taxRate);
}
$subTotal += CRM_Utils_Array::value('subTotal', $taxRate);
}
// to email the invoice
$mailDetails = array();
$values = array();
if ($contribution->_component == 'event') {
$daoName = 'CRM_Event_DAO_Event';
$pageId = $contribution->_relatedObjects['event']->id;
$mailElements = array(
'title',
'confirm_from_name',
'confirm_from_email',
'cc_confirm',
'bcc_confirm',
);
CRM_Core_DAO::commonRetrieveAll($daoName, 'id', $pageId, $mailDetails, $mailElements);
$values['title'] = CRM_Utils_Array::value('title', $mailDetails[$contribution->_relatedObjects['event']->id]);
$values['confirm_from_name'] = CRM_Utils_Array::value('confirm_from_name', $mailDetails[$contribution->_relatedObjects['event']->id]);
$values['confirm_from_email'] = CRM_Utils_Array::value('confirm_from_email', $mailDetails[$contribution->_relatedObjects['event']->id]);
$values['cc_confirm'] = CRM_Utils_Array::value('cc_confirm', $mailDetails[$contribution->_relatedObjects['event']->id]);
$values['bcc_confirm'] = CRM_Utils_Array::value('bcc_confirm', $mailDetails[$contribution->_relatedObjects['event']->id]);
$title = CRM_Utils_Array::value('title', $mailDetails[$contribution->_relatedObjects['event']->id]);
}
elseif ($contribution->_component == 'contribute') {
$daoName = 'CRM_Contribute_DAO_ContributionPage';
$pageId = $contribution->contribution_page_id;
$mailElements = array(
'title',
'receipt_from_name',
'receipt_from_email',
'cc_receipt',
'bcc_receipt',
);
CRM_Core_DAO::commonRetrieveAll($daoName, 'id', $pageId, $mailDetails, $mailElements);
$values['title'] = CRM_Utils_Array::value('title', CRM_Utils_Array::value($contribution->contribution_page_id, $mailDetails));
$values['receipt_from_name'] = CRM_Utils_Array::value('receipt_from_name', CRM_Utils_Array::value($contribution->contribution_page_id, $mailDetails));
$values['receipt_from_email'] = CRM_Utils_Array::value('receipt_from_email', CRM_Utils_Array::value($contribution->contribution_page_id, $mailDetails));
$values['cc_receipt'] = CRM_Utils_Array::value('cc_receipt', CRM_Utils_Array::value($contribution->contribution_page_id, $mailDetails));
$values['bcc_receipt'] = CRM_Utils_Array::value('bcc_receipt', CRM_Utils_Array::value($contribution->contribution_page_id, $mailDetails));
$title = CRM_Utils_Array::value('title', CRM_Utils_Array::value($contribution->contribution_page_id, $mailDetails));
}
$source = $contribution->source;
$config = CRM_Core_Config::singleton();
if (!isset($params['forPage'])) {
$config->doNotAttachPDFReceipt = 1;
}
// get organization address
$domain = CRM_Core_BAO_Domain::getDomain();
$locParams = array('contact_id' => $domain->contact_id);
$locationDefaults = CRM_Core_BAO_Location::getValues($locParams);
if (isset($locationDefaults['address'][1]['state_province_id'])) {
$stateProvinceAbbreviationDomain = CRM_Core_PseudoConstant::stateProvinceAbbreviation($locationDefaults['address'][1]['state_province_id']);
}
else {
$stateProvinceAbbreviationDomain = '';
}
if (isset($locationDefaults['address'][1]['country_id'])) {
$countryDomain = CRM_Core_PseudoConstant::country($locationDefaults['address'][1]['country_id']);
}
else {
$countryDomain = '';
}
// parameters to be assign for template
$tplParams = array(
'title' => $title,
'component' => $input['component'],
'id' => $contribution->id,
'source' => $source,
'invoice_number' => $contribution->invoice_number,
'invoice_id' => $contribution->invoice_id,
'resourceBase' => $config->userFrameworkResourceURL,
'defaultCurrency' => $config->defaultCurrency,
'amount' => $contribution->total_amount,
'amountDue' => $amountDue,
'amountPaid' => $amountPaid,
'invoice_date' => $invoiceDate,
'dueDate' => $dueDate,
'notes' => CRM_Utils_Array::value('notes', $prefixValue),
'display_name' => $contribution->_relatedObjects['contact']->display_name,
'lineItem' => $lineItem,
'dataArray' => $dataArray,
'refundedStatusId' => $refundedStatusId,
'pendingStatusId' => $pendingStatusId,
'cancelledStatusId' => $cancelledStatusId,
'contribution_status_id' => $contribution->contribution_status_id,
'subTotal' => $subTotal,
'street_address' => CRM_Utils_Array::value('street_address', CRM_Utils_Array::value($contribution->contact_id, $billingAddress)),
'supplemental_address_1' => CRM_Utils_Array::value('supplemental_address_1', CRM_Utils_Array::value($contribution->contact_id, $billingAddress)),
'supplemental_address_2' => CRM_Utils_Array::value('supplemental_address_2', CRM_Utils_Array::value($contribution->contact_id, $billingAddress)),
'supplemental_address_3' => CRM_Utils_Array::value('supplemental_address_3', CRM_Utils_Array::value($contribution->contact_id, $billingAddress)),
'city' => CRM_Utils_Array::value('city', CRM_Utils_Array::value($contribution->contact_id, $billingAddress)),
'stateProvinceAbbreviation' => $stateProvinceAbbreviation,
'postal_code' => CRM_Utils_Array::value('postal_code', CRM_Utils_Array::value($contribution->contact_id, $billingAddress)),
'is_pay_later' => $contribution->is_pay_later,
'organization_name' => $contribution->_relatedObjects['contact']->organization_name,
'domain_organization' => $domain->name,
'domain_street_address' => CRM_Utils_Array::value('street_address', CRM_Utils_Array::value('1', $locationDefaults['address'])),
'domain_supplemental_address_1' => CRM_Utils_Array::value('supplemental_address_1', CRM_Utils_Array::value('1', $locationDefaults['address'])),
'domain_supplemental_address_2' => CRM_Utils_Array::value('supplemental_address_2', CRM_Utils_Array::value('1', $locationDefaults['address'])),
'domain_supplemental_address_3' => CRM_Utils_Array::value('supplemental_address_3', CRM_Utils_Array::value('1', $locationDefaults['address'])),
'domain_city' => CRM_Utils_Array::value('city', CRM_Utils_Array::value('1', $locationDefaults['address'])),
'domain_postal_code' => CRM_Utils_Array::value('postal_code', CRM_Utils_Array::value('1', $locationDefaults['address'])),
'domain_state' => $stateProvinceAbbreviationDomain,
'domain_country' => $countryDomain,
'domain_email' => CRM_Utils_Array::value('email', CRM_Utils_Array::value('1', $locationDefaults['email'])),
'domain_phone' => CRM_Utils_Array::value('phone', CRM_Utils_Array::value('1', $locationDefaults['phone'])),
);
if (isset($creditNoteId)) {
$tplParams['creditnote_id'] = $creditNoteId;
}
$pdfFileName = $contribution->invoice_number . ".pdf";
$sendTemplateParams = array(
'groupName' => 'msg_tpl_workflow_contribution',
'valueName' => 'contribution_invoice_receipt',
'contactId' => $contribution->contact_id,
'tplParams' => $tplParams,
'PDFFilename' => $pdfFileName,
);
$session = CRM_Core_Session::singleton();
$contactID = $session->get('userID');
//CRM-16319 - we dont store in userID in case the user is doing multiple
//transactions etc
if (empty($contactID)) {
$contactID = $session->get('transaction.userID');
}
// Fix Invoice email doesnot send out when completed payment using Paypal
if (empty($contactID)) {
$contactID = current($contactIds);
}
$contactEmails = CRM_Core_BAO_Email::allEmails($contactID);
$emails = array();
$fromDisplayName = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Contact',
$contactID, 'display_name'
);
foreach ($contactEmails as $emailId => $item) {
$email = $item['email'];
if ($email) {
$emails[$emailId] = '"' . $fromDisplayName . '" <' . $email . '> ';
}
}
$fromEmail = CRM_Utils_Array::crmArrayMerge($emails, CRM_Core_OptionGroup::values('from_email_address'));
// from email address
if (isset($params['from_email_address'])) {
$fromEmailAddress = CRM_Utils_Array::value($params['from_email_address'], $fromEmail);
}
// condition to check for download PDF Invoice or email Invoice
if ($invoiceElements['createPdf']) {
list($sent, $subject, $message, $html) = CRM_Core_BAO_MessageTemplate::sendTemplate($sendTemplateParams);
if (isset($params['forPage'])) {
return $html;
}
else {
$mail = array(
'subject' => $subject,
'body' => $message,
'html' => $html,
);
if ($mail['html']) {
$messageInvoice[] = $mail['html'];
}
else {
$messageInvoice[] = nl2br($mail['body']);
}
}
}
elseif ($contribution->_component == 'contribute') {
$email = CRM_Contact_BAO_Contact::getPrimaryEmail($contribution->contact_id);
$sendTemplateParams['tplParams'] = array_merge($tplParams, array('email_comment' => $invoiceElements['params']['email_comment']));
$sendTemplateParams['from'] = $fromEmailAddress;
$sendTemplateParams['toEmail'] = $email;
$sendTemplateParams['cc'] = CRM_Utils_Array::value('cc_receipt', $values);
$sendTemplateParams['bcc'] = CRM_Utils_Array::value('bcc_receipt', $values);
list($sent, $subject, $message, $html) = CRM_Core_BAO_MessageTemplate::sendTemplate($sendTemplateParams);
// functions call for adding activity with attachment
$pdfFileName = "{$invoiceNumber}.pdf";
$fileName = self::putFile($html, $pdfFileName);
self::addActivities($subject, $contribution->contact_id, $fileName, $params);
}
elseif ($contribution->_component == 'event') {
$email = CRM_Contact_BAO_Contact::getPrimaryEmail($contribution->contact_id);
$sendTemplateParams['tplParams'] = array_merge($tplParams, array('email_comment' => $invoiceElements['params']['email_comment']));
$sendTemplateParams['from'] = $fromEmailAddress;
$sendTemplateParams['toEmail'] = $email;
$sendTemplateParams['cc'] = CRM_Utils_Array::value('cc_confirm', $values);
$sendTemplateParams['bcc'] = CRM_Utils_Array::value('bcc_confirm', $values);
list($sent, $subject, $message, $html) = CRM_Core_BAO_MessageTemplate::sendTemplate($sendTemplateParams);
// functions call for adding activity with attachment
$pdfFileName = "{$invoiceNumber}.pdf";
$fileName = self::putFile($html, $pdfFileName);
self::addActivities($subject, $contribution->contact_id, $fileName, $params);
}
$invoiceTemplate->clearTemplateVars();
}
if ($invoiceElements['createPdf']) {
if (isset($params['forPage'])) {
return $html;
}
else {
$pdfFileName = "{$invoiceNumber}.pdf";
CRM_Utils_PDF_Utils::html2pdf($messageInvoice, $pdfFileName, FALSE, array(
'margin_top' => 10,
'margin_left' => 65,
'metric' => 'px',
));
// functions call for adding activity with attachment
$fileName = self::putFile($html, $pdfFileName);
self::addActivities($subject, $contactIds, $fileName, $params);
CRM_Utils_System::civiExit();
}
}
else {
if ($invoiceElements['suppressedEmails']) {
$status = ts('Email was NOT sent to %1 contacts (no email address on file, or communication preferences specify DO NOT EMAIL, or contact is deceased).', array(1 => $invoiceElements['suppressedEmails']));
$msgTitle = ts('Email Error');
$msgType = 'error';
}
else {
$status = ts('Your mail has been sent.');
$msgTitle = ts('Sent');
$msgType = 'success';
}
CRM_Core_Session::setStatus($status, $msgTitle, $msgType);
}
}
/**
* Add activity for Email Invoice and the PDF Invoice.
*
* @param string $subject
* Activity subject.
* @param array $contactIds
* Contact Id.
* @param string $fileName
* Gives the location with name of the file.
* @param array $params
* For invoices.
*
*/
static public function addActivities($subject, $contactIds, $fileName, $params) {
$session = CRM_Core_Session::singleton();
$userID = $session->get('userID');
$config = CRM_Core_Config::singleton();
$config->doNotAttachPDFReceipt = 1;
if (!empty($params['output']) && $params['output'] == 'pdf_invoice') {
$activityTypeID = CRM_Core_PseudoConstant::getKey(
'CRM_Activity_DAO_Activity',
'activity_type_id',
'Downloaded Invoice'
);
}
else {
$activityTypeID = CRM_Core_PseudoConstant::getKey(
'CRM_Activity_DAO_Activity',
'activity_type_id',
'Emailed Invoice'
);
}
$activityParams = array(
'subject' => $subject,
'source_contact_id' => $userID,
'target_contact_id' => $contactIds,
'activity_type_id' => $activityTypeID,
'activity_date_time' => date('YmdHis'),
'attachFile_1' => array(
'uri' => $fileName,
'type' => 'application/pdf',
'location' => $fileName,
'upload_date' => date('YmdHis'),
),
);
CRM_Activity_BAO_Activity::create($activityParams);
}
/**
* Create the Invoice file in upload folder for attachment.
*
* @param string $html
* Content for pdf in html format.
*
* @param string $name
*
* @return string
* Name of file which is in pdf format
*/
static public function putFile($html, $name = 'Invoice.pdf') {
$options = new Options();
$options->set('isRemoteEnabled', TRUE);
$doc = new DOMPDF($options);
$doc->load_html($html);
$doc->render();
$html = $doc->output();
$config = CRM_Core_Config::singleton();
$fileName = $config->uploadDir . $name;
file_put_contents($fileName, $html);
return $fileName;
}
/**
* Callback to perform action on Print Invoice button.
*/
public static function getPrintPDF() {
$contributionId = CRM_Utils_Request::retrieve('id', 'Positive', CRM_Core_DAO::$_nullObject, FALSE);
$contributionIDs = array($contributionId);
$contactId = CRM_Utils_Request::retrieve('cid', 'Positive', CRM_Core_DAO::$_nullObject, FALSE);
$params = array('output' => 'pdf_invoice');
CRM_Contribute_Form_Task_Invoice::printPDF($contributionIDs, $params, $contactId);
}
}

View file

@ -0,0 +1,308 @@
<?php
/*
+--------------------------------------------------------------------+
| CiviCRM version 4.7 |
+--------------------------------------------------------------------+
| Copyright CiviCRM LLC (c) 2004-2017 |
+--------------------------------------------------------------------+
| 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 |
+--------------------------------------------------------------------+
*/
/**
*
* @package CRM
* @copyright CiviCRM LLC (c) 2004-2017
*/
/**
* This class provides the functionality to email a group of
* contacts.
*/
class CRM_Contribute_Form_Task_PDF extends CRM_Contribute_Form_Task {
/**
* Are we operating in "single mode", i.e. updating the task of only
* one specific contribution?
*
* @var boolean
*/
public $_single = FALSE;
protected $_rows;
/**
* Build all the data structures needed to build the form.
*/
public function preProcess() {
$id = CRM_Utils_Request::retrieve('id', 'Positive',
$this, FALSE
);
if ($id) {
$this->_contributionIds = array($id);
$this->_componentClause = " civicrm_contribution.id IN ( $id ) ";
$this->_single = TRUE;
$this->assign('totalSelectedContributions', 1);
}
else {
parent::preProcess();
}
// check that all the contribution ids have pending status
$query = "
SELECT count(*)
FROM civicrm_contribution
WHERE contribution_status_id != 1
AND {$this->_componentClause}";
$count = CRM_Core_DAO::singleValueQuery($query);
if ($count != 0) {
CRM_Core_Error::statusBounce("Please select only online contributions with Completed status.");
}
$this->assign('single', $this->_single);
$qfKey = CRM_Utils_Request::retrieve('qfKey', 'String', $this);
$urlParams = 'force=1';
if (CRM_Utils_Rule::qfKey($qfKey)) {
$urlParams .= "&qfKey=$qfKey";
}
$url = CRM_Utils_System::url('civicrm/contribute/search', $urlParams);
$breadCrumb = array(
array(
'url' => $url,
'title' => ts('Search Results'),
),
);
CRM_Contact_Form_Task_EmailCommon ::preProcessFromAddress($this, FALSE);
// we have all the contribution ids, so now we get the contact ids
parent::setContactIDs();
CRM_Utils_System::appendBreadCrumb($breadCrumb);
CRM_Utils_System::setTitle(ts('Print Contribution Receipts'));
}
/**
* Build the form object.
*/
public function buildQuickForm() {
$this->addElement('radio', 'output', NULL, ts('Email Receipts'), 'email_receipt',
array(
'onClick' => "document.getElementById('selectPdfFormat').style.display = 'none';
document.getElementById('selectEmailFrom').style.display = 'block';")
);
$this->addElement('radio', 'output', NULL, ts('PDF Receipts'), 'pdf_receipt',
array('onClick' => "document.getElementById('selectPdfFormat').style.display = 'block';")
);
$this->addRule('output', ts('Selection required'), 'required');
$this->add('select', 'pdf_format_id', ts('Page Format'),
array(0 => ts('- default -')) + CRM_Core_BAO_PdfFormat::getList(TRUE)
);
$this->add('checkbox', 'receipt_update', ts('Update receipt dates for these contributions'), FALSE);
$this->add('checkbox', 'override_privacy', ts('Override privacy setting? (Do not email / Do not mail)'), FALSE);
$this->add('select', 'fromEmailAddress', ts('From Email'), $this->_fromEmails, FALSE, array('class' => 'crm-select2 huge'));
$this->addButtons(array(
array(
'type' => 'next',
'name' => ts('Process Receipt(s)'),
'isDefault' => TRUE,
),
array(
'type' => 'back',
'name' => ts('Cancel'),
),
)
);
}
/**
* Set default values.
*/
public function setDefaultValues() {
$defaultFormat = CRM_Core_BAO_PdfFormat::getDefaultValues();
return array('pdf_format_id' => $defaultFormat['id'], 'receipt_update' => 1, 'override_privacy' => 0);
}
/**
* Process the form after the input has been submitted and validated.
*/
public function postProcess() {
// get all the details needed to generate a receipt
$message = array();
$template = CRM_Core_Smarty::singleton();
$params = $this->controller->exportValues($this->_name);
$elements = self::getElements($this->_contributionIds, $params, $this->_contactIds);
foreach ($elements['details'] as $contribID => $detail) {
$input = $ids = $objects = array();
if (in_array($detail['contact'], $elements['excludeContactIds'])) {
continue;
}
$input['component'] = $detail['component'];
$ids['contact'] = $detail['contact'];
$ids['contribution'] = $contribID;
$ids['contributionRecur'] = NULL;
$ids['contributionPage'] = NULL;
$ids['membership'] = CRM_Utils_Array::value('membership', $detail);
$ids['participant'] = CRM_Utils_Array::value('participant', $detail);
$ids['event'] = CRM_Utils_Array::value('event', $detail);
if (!$elements['baseIPN']->validateData($input, $ids, $objects, FALSE)) {
CRM_Core_Error::fatal();
}
$contribution = &$objects['contribution'];
// set some fake input values so we can reuse IPN code
$input['amount'] = $contribution->total_amount;
$input['is_test'] = $contribution->is_test;
$input['fee_amount'] = $contribution->fee_amount;
$input['net_amount'] = $contribution->net_amount;
$input['trxn_id'] = $contribution->trxn_id;
$input['trxn_date'] = isset($contribution->trxn_date) ? $contribution->trxn_date : NULL;
$input['receipt_update'] = $params['receipt_update'];
$input['contribution_status_id'] = $contribution->contribution_status_id;
$input['paymentProcessor'] = empty($contribution->trxn_id) ? NULL :
CRM_Core_DAO::singleValueQuery("SELECT payment_processor_id
FROM civicrm_financial_trxn
WHERE trxn_id = %1
LIMIT 1", array(
1 => array($contribution->trxn_id, 'String')));
// CRM_Contribute_BAO_Contribution::composeMessageArray expects mysql formatted date
$objects['contribution']->receive_date = CRM_Utils_Date::isoToMysql($objects['contribution']->receive_date);
$values = array();
if (isset($params['fromEmailAddress']) && !$elements['createPdf']) {
// CRM-19129 Allow useres the choice of From Email to send the receipt from.
$fromEmail = $params['fromEmailAddress'];
$from = CRM_Utils_Array::value($fromEmail, $this->_emails);
$fromDetails = explode(' <', $from);
$input['receipt_from_email'] = substr(trim($fromDetails[1]), 0, -1);
$input['receipt_from_name'] = str_replace('"', '', $fromDetails[0]);
}
$mail = CRM_Contribute_BAO_Contribution::sendMail($input, $ids, $objects['contribution']->id, $values,
$elements['createPdf']);
if ($mail['html']) {
$message[] = $mail['html'];
}
else {
$message[] = nl2br($mail['body']);
}
// reset template values before processing next transactions
$template->clearTemplateVars();
}
if ($elements['createPdf']) {
CRM_Utils_PDF_Utils::html2pdf($message,
'civicrmContributionReceipt.pdf',
FALSE,
$elements['params']['pdf_format_id']
);
CRM_Utils_System::civiExit();
}
else {
if ($elements['suppressedEmails']) {
$status = ts('Email was NOT sent to %1 contacts (no email address on file, or communication preferences specify DO NOT EMAIL, or contact is deceased).', array(1 => $elements['suppressedEmails']));
$msgTitle = ts('Email Error');
$msgType = 'error';
}
else {
$status = ts('Your mail has been sent.');
$msgTitle = ts('Sent');
$msgType = 'success';
}
CRM_Core_Session::setStatus($status, $msgTitle, $msgType);
}
}
/**
* Declaration of common variables for Invoice and PDF.
*
*
* @param array $contribIds
* Contribution Id.
* @param array $params
* Parameter for pdf or email invoices.
* @param array $contactIds
* Contact Id.
*
* @return array
* array of common elements
*
*/
static public function getElements($contribIds, $params, $contactIds) {
$pdfElements = array();
$pdfElements['contribIDs'] = implode(',', $contribIds);
$pdfElements['details'] = CRM_Contribute_Form_Task_Status::getDetails($pdfElements['contribIDs']);
$pdfElements['baseIPN'] = new CRM_Core_Payment_BaseIPN();
$pdfElements['params'] = $params;
$pdfElements['createPdf'] = FALSE;
if (!empty($pdfElements['params']['output']) &&
($pdfElements['params']['output'] == "pdf_invoice" || $pdfElements['params']['output'] == "pdf_receipt")
) {
$pdfElements['createPdf'] = TRUE;
}
$excludeContactIds = array();
if (!$pdfElements['createPdf']) {
$returnProperties = array(
'email' => 1,
'do_not_email' => 1,
'is_deceased' => 1,
'on_hold' => 1,
);
list($contactDetails) = CRM_Utils_Token::getTokenDetails($contactIds, $returnProperties, FALSE, FALSE);
$pdfElements['suppressedEmails'] = 0;
$suppressedEmails = 0;
foreach ($contactDetails as $id => $values) {
if (empty($values['email']) ||
(empty($params['override_privacy']) && !empty($values['do_not_email']))
|| CRM_Utils_Array::value('is_deceased', $values)
|| !empty($values['on_hold'])
) {
$suppressedEmails++;
$pdfElements['suppressedEmails'] = $suppressedEmails;
$excludeContactIds[] = $values['contact_id'];
}
}
}
$pdfElements['excludeContactIds'] = $excludeContactIds;
return $pdfElements;
}
}

View file

@ -0,0 +1,174 @@
<?php
/*
+--------------------------------------------------------------------+
| CiviCRM version 4.7 |
+--------------------------------------------------------------------+
| Copyright CiviCRM LLC (c) 2004-2017 |
+--------------------------------------------------------------------+
| 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 |
+--------------------------------------------------------------------+
*/
/**
*
* @package CRM
* @copyright CiviCRM LLC (c) 2004-2017
*/
/**
* This class provides the functionality to create PDF letter for a group of contacts or a single contact.
*/
class CRM_Contribute_Form_Task_PDFLetter extends CRM_Contribute_Form_Task {
/**
* All the existing templates in the system.
*
* @var array
*/
public $_templates = NULL;
public $_single = NULL;
public $_cid = NULL;
/**
* Build all the data structures needed to build the form.
*/
public function preProcess() {
$this->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);
}
/**
* This virtual function is used to set the default values of
* various form elements
*
* access public
*
* @return array
* reference to the array of default values
*/
/**
* @return array
*/
public 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);
}
else {
$defaults['thankyou_update'] = 1;
}
$defaults = $defaults + CRM_Contact_Form_Task_PDFLetterCommon::setDefaultValues();
return $defaults;
}
/**
* Build the form object.
*/
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('Thank-you Letter 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('- no grouping -'),
'contact_id' => ts('Contact'),
'contribution_recur_id' => ts('Contact and Recurring'),
'financial_type_id' => ts('Contact and Financial Type'),
'campaign_id' => ts('Contact and Campaign'),
'payment_instrument_id' => ts('Contact and Payment Method'),
);
$this->addElement('select', 'group_by', ts('Group contributions by'), $options, array(), "<br/>", FALSE);
// this was going to be free-text but I opted for radio options in case there was a script injection risk
$separatorOptions = array('comma' => 'Comma', 'td' => 'Horizontal Table Cell', 'tr' => 'Vertical Table Cell', 'br' => 'Line Break');
$this->addElement('select', 'group_by_separator', ts('Separator (grouped contributions)'), $separatorOptions);
$emailOptions = array(
'' => ts('Generate PDFs for printing (only)'),
'email' => ts('Send emails where possible. Generate printable PDFs for contacts who cannot receive email.'),
'both' => ts('Send emails where possible. Generate printable PDFs for all contacts.'),
);
if (CRM_Core_Config::singleton()->doNotAttachPDFReceipt) {
$emailOptions['pdfemail'] = ts('Send emails with an attached PDF where possible. Generate printable PDFs for contacts who cannot receive email.');
$emailOptions['pdfemail_both'] = ts('Send emails with an attached PDF where possible. Generate printable PDFs for all contacts.');
}
$this->addElement('select', 'email_options', ts('Print and email options'), $emailOptions, array(), "<br/>", FALSE);
$this->addButtons(array(
array(
'type' => 'upload',
'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.
*/
public function postProcess() {
CRM_Contribute_Form_Task_PDFLetterCommon::postProcess($this);
}
/**
* List available tokens for this form.
*
* @return array
*/
public function listTokens() {
$tokens = CRM_Core_SelectValues::contactTokens();
$tokens = array_merge(CRM_Core_SelectValues::contributionTokens(), $tokens);
return $tokens;
}
}

View file

@ -0,0 +1,428 @@
<?php
/**
* This class provides the common functionality for creating PDF letter for
* one or a group of contact ids.
*/
class CRM_Contribute_Form_Task_PDFLetterCommon extends CRM_Contact_Form_Task_PDFLetterCommon {
/**
* Process the form after the input has been submitted and validated.
*
* @param CRM_Contribute_Form_Task $form
* @param array $formValues
*/
public static function postProcess(&$form, $formValues = NULL) {
if (empty($formValues)) {
$formValues = $form->controller->exportValues($form->getName());
}
list($formValues, $categories, $html_message, $messageToken, $returnProperties) = self::processMessageTemplate($formValues);
$isPDF = FALSE;
$emailParams = array();
if (!empty($formValues['email_options'])) {
$returnProperties['email'] = $returnProperties['on_hold'] = $returnProperties['is_deceased'] = $returnProperties['do_not_email'] = 1;
$emailParams = array(
'subject' => $formValues['subject'],
);
// 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 = isset($formValues['receipt_update']) ? $formValues['receipt_update'] : FALSE;
$thankyou_update = isset($formValues['thankyou_update']) ? $formValues['thankyou_update'] : FALSE;
$nowDate = date('YmdHis');
$receipts = $thanks = $emailed = 0;
$updateStatus = '';
$task = 'CRM_Contribution_Form_Task_PDFLetterCommon';
$realSeparator = ', ';
$tableSeparators = array(
'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'], array('td', 'tr'))) {
$realSeparator = $tableSeparators[$formValues['group_by_separator']];
}
elseif ($formValues['group_by_separator'] == 'br') {
$realSeparator = "<br />";
}
}
$separator = '****~~~~';// a placeholder in case the separator is common in the string - e.g ', '
$groupBy = $formValues['group_by'];
// skip some contacts ?
$skipOnHold = isset($form->skipOnHold) ? $form->skipOnHold : FALSE;
$skipDeceased = isset($form->skipDeceased) ? $form->skipDeceased : TRUE;
$contributionIDs = $form->getVar('_contributionIds');
if ($form->_includesSoftCredits) {
//@todo - comment on what is stored there
$contributionIDs = $form->getVar('_contributionContactIds');
}
list($contributions, $contacts) = self::buildContributionArray($groupBy, $contributionIDs, $returnProperties, $skipOnHold, $skipDeceased, $messageToken, $task, $separator, $form->_includesSoftCredits);
$html = array();
$contactHtml = $emailedHtml = array();
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] = self::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 (self::emailLetter($contact, $html[$contributionId], $isPDF, $formValues, $emailParams)) {
$emailed++;
if (!stristr($formValues['email_options'], 'both')) {
$emailedHtml[$contributionId] = TRUE;
}
}
}
$contact['is_sent'][$groupBy][$groupByID] = TRUE;
}
// update dates (do it for each contribution including grouped recurring contribution)
//@todo - the 2 calls below bypass all hooks. Using the api would possibly be slower than one call but not than 2
if ($receipt_update) {
$result = CRM_Core_DAO::setFieldValue('CRM_Contribute_DAO_Contribution', $contributionId, 'receipt_date', $nowDate);
if ($result) {
$receipts++;
}
}
if ($thankyou_update) {
$result = CRM_Core_DAO::setFieldValue('CRM_Contribute_DAO_Contribution', $contributionId, 'thankyou_date', $nowDate);
if ($result) {
$thanks++;
}
}
}
// This seems silly, but the old behavior was to first check `_cid`
// and then use the provided `$contactIds`. Probably not even necessary,
// but difficult to audit.
$contactIds = $form->_cid ? array($form->_cid) : array_keys($contacts);
self::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.', array(1 => $emailed));
}
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);
}
if (!empty($html)) {
// ie. we have only sent emails - lets no show a white screen
CRM_Utils_System::civiExit(1);
}
}
/**
* 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 = array('contribution');
foreach ($relevantEntities as $entity) {
if (isset($tokens[$entity]) && is_array($tokens[$entity])) {
foreach ($tokens[$entity] as $token) {
if (!self::isHtmlTokenInTableCell($token, $entity, $html)) {
return FALSE;
}
}
}
}
return TRUE;
}
/**
* Check that the token only appears in a table cell. The '</td><td>' separator cannot otherwise work
* Calculate the number of times it appears IN the cell & the number of times it appears - should be the same!
*
* @param $token
* @param $entity
* @param $textToSearch
*
* @return bool
*/
public static function isHtmlTokenInTableCell($token, $entity, $textToSearch) {
$tokenToMatch = $entity . '.' . $token;
$dontCare = array();
$within = preg_match_all("|<td.+?{" . $tokenToMatch . "}.+?</td|si", $textToSearch, $dontCare);
$total = preg_match_all("|{" . $tokenToMatch . "}|", $textToSearch, $dontCare);
return ($within == $total);
}
/**
*
* @param string $html_message
* @param array $contact
* @param array $contribution
* @param array $messageToken
* @param bool $grouped
* Does this letter represent more than one contribution.
* @param string $separator
* What is the preferred letter separator.
* @return string
*/
private static function resolveTokens($html_message, $contact, $contribution, $messageToken, $grouped, $separator) {
$categories = self::getTokenCategories();
$tokenHtml = CRM_Utils_Token::replaceContactTokens($html_message, $contact, TRUE, $messageToken);
if ($grouped) {
$tokenHtml = CRM_Utils_Token::replaceMultipleContributionTokens($separator, $tokenHtml, $contribution, TRUE, $messageToken);
}
else {
// no change to normal behaviour to avoid risk of breakage
$tokenHtml = CRM_Utils_Token::replaceContributionTokens($tokenHtml, $contribution, TRUE, $messageToken);
}
$tokenHtml = CRM_Utils_Token::replaceHookTokens($tokenHtml, $contact, $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");
}
return $tokenHtml;
}
/**
* Generate the contribution array from the form, we fill in the contact details and determine any aggregation
* around contact_id of contribution_recur_id
*
* @param string $groupBy
* @param array $contributionIDs
* @param array $returnProperties
* @param bool $skipOnHold
* @param bool $skipDeceased
* @param array $messageToken
* @param string $task
* @param string $separator
* @param bool $isIncludeSoftCredits
*
* @return array
*/
public static function buildContributionArray($groupBy, $contributionIDs, $returnProperties, $skipOnHold, $skipDeceased, $messageToken, $task, $separator, $isIncludeSoftCredits) {
$contributions = $contacts = array();
foreach ($contributionIDs as $item => $contributionId) {
// Basic return attributes available to the template.
$returnValues = array('contact_id', 'total_amount', 'financial_type', 'receive_date', 'contribution_campaign_title');
if (!empty($messageToken['contribution'])) {
$returnValues = array_merge($messageToken['contribution'], $returnValues);
}
// retrieve contribution tokens listed in $returnProperties using Contribution.Get API
$contribution = civicrm_api3('Contribution', 'getsingle', array(
'id' => $contributionId,
'return' => $returnValues,
));
$contribution['campaign'] = CRM_Utils_Array::value('contribution_campaign_title', $contribution);
$contributions[$contributionId] = $contribution;
if ($isIncludeSoftCredits) {
//@todo find out why this happens & add comments
list($contactID) = explode('-', $item);
$contactID = (int) $contactID;
}
else {
$contactID = $contribution['contact_id'];
}
if (!isset($contacts[$contactID])) {
$contacts[$contactID] = array();
$contacts[$contactID]['contact_aggregate'] = 0;
$contacts[$contactID]['combined'] = $contacts[$contactID]['contribution_ids'] = array();
}
$contacts[$contactID]['contact_aggregate'] += $contribution['total_amount'];
$groupByID = empty($contribution[$groupBy]) ? 0 : $contribution[$groupBy];
$contacts[$contactID]['contribution_ids'][$groupBy][$groupByID][$contributionId] = TRUE;
if (!isset($contacts[$contactID]['combined'][$groupBy]) || !isset($contacts[$contactID]['combined'][$groupBy][$groupByID])) {
$contacts[$contactID]['combined'][$groupBy][$groupByID] = $contribution;
$contacts[$contactID]['aggregates'][$groupBy][$groupByID] = $contribution['total_amount'];
}
else {
$contacts[$contactID]['combined'][$groupBy][$groupByID] = self::combineContributions($contacts[$contactID]['combined'][$groupBy][$groupByID], $contribution, $separator);
$contacts[$contactID]['aggregates'][$groupBy][$groupByID] += $contribution['total_amount'];
}
}
// Assign the available contributions before calling tokens so hooks parsing smarty can access it.
// Note that in core code you can only use smarty here if enable if for the whole site, incl
// CiviMail, with a big performance impact.
// Hooks allow more nuanced smarty usage here.
CRM_Core_Smarty::singleton()->assign('contributions', $contributions);
foreach ($contacts as $contactID => $contact) {
$tokenResolvedContacts = CRM_Utils_Token::getTokenDetails(array('contact_id' => $contactID),
$returnProperties,
$skipOnHold,
$skipDeceased,
NULL,
$messageToken,
$task
);
$contacts[$contactID] = array_merge($tokenResolvedContacts[0][$contactID], $contact);
}
return array($contributions, $contacts);
}
/**
* We combine the contributions by adding the contribution to each field with the separator in
* between the existing value and the new one. We put the separator there even if empty so it is clear what the
* value for previous contributions was
*
* @param array $existing
* @param array $contribution
* @param string $separator
*
* @return array
*/
public static function combineContributions($existing, $contribution, $separator) {
foreach ($contribution as $field => $value) {
$existing[$field] = isset($existing[$field]) ? $existing[$field] . $separator : '';
$existing[$field] .= $value;
}
return $existing;
}
/**
* We are going to retrieve the combined contribution and if smarty mail is enabled we
* will also assign an array of contributions for this contact to the smarty template
*
* @param array $contact
* @param array $contributions
* @param $groupBy
* @param int $groupByID
*/
public static function assignCombinedContributionValues($contact, $contributions, $groupBy, $groupByID) {
CRM_Core_Smarty::singleton()->assign('contact_aggregate', $contact['contact_aggregate']);
CRM_Core_Smarty::singleton()
->assign('contributions', array_intersect_key($contributions, $contact['contribution_ids'][$groupBy][$groupByID]));
CRM_Core_Smarty::singleton()->assign('contribution_aggregate', $contact['aggregates'][$groupBy][$groupByID]);
}
/**
* Send pdf by email.
*
* @param array $contact
* @param string $html
*
* @param $is_pdf
* @param array $format
* @param array $params
*
* @return bool
*/
public static function emailLetter($contact, $html, $is_pdf, $format = array(), $params = array()) {
try {
if (empty($contact['email'])) {
return FALSE;
}
$mustBeEmpty = array('do_not_email', 'is_deceased', 'on_hold');
foreach ($mustBeEmpty as $emptyField) {
if (!empty($contact[$emptyField])) {
return FALSE;
}
}
$defaults = array(
'toName' => $contact['display_name'],
'toEmail' => $contact['email'],
'text' => '',
'html' => $html,
);
if (empty($params['from'])) {
$emails = CRM_Core_BAO_Email::getFromEmail();
$emails = array_keys($emails);
$defaults['from'] = array_pop($emails);
}
if (!empty($params['subject'])) {
$defaults['subject'] = $params['subject'];
}
else {
$defaults['subject'] = ts('Thank you for your contribution/s');
}
if ($is_pdf) {
$defaults['html'] = ts('Please see attached');
$defaults['attachments'] = array(CRM_Utils_Mail::appendPDF('ThankYou.pdf', $html, $format));
}
$params = array_merge($defaults);
return CRM_Utils_Mail::send($params);
}
catch (CRM_Core_Exception $e) {
return FALSE;
}
}
/**
* @param $contact
* @param $formValues
* @param $contribution
* @param $groupBy
* @param $contributions
* @param $realSeparator
* @param $tableSeparators
* @param $messageToken
* @param $html_message
* @param $separator
* @param $categories
* @param bool $grouped
* @param int $groupByID
*
* @return string
*/
protected static function generateHtml(&$contact, $contribution, $groupBy, $contributions, $realSeparator, $tableSeparators, $messageToken, $html_message, $separator, $grouped, $groupByID) {
static $validated = FALSE;
$html = NULL;
self::assignCombinedContributionValues($contact, $contributions, $groupBy, $groupByID);
if (empty($groupBy) || empty($contact['is_sent'][$groupBy][$groupByID])) {
if (!$validated && in_array($realSeparator, $tableSeparators) && !self::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.'));
}
$validated = TRUE;
$html = str_replace($separator, $realSeparator, self::resolveTokens($html_message, $contact, $contribution, $messageToken, $grouped, $separator));
}
return $html;
}
}

View file

@ -0,0 +1,136 @@
<?php
/*
+--------------------------------------------------------------------+
| CiviCRM version 4.7 |
+--------------------------------------------------------------------+
| Copyright CiviCRM LLC (c) 2004-2017 |
+--------------------------------------------------------------------+
| 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 |
+--------------------------------------------------------------------+
*/
/**
*
* @package CRM
* @copyright CiviCRM LLC (c) 2004-2017
*/
/**
* This class provides the functionality for batch profile update for contributions.
*/
class CRM_Contribute_Form_Task_PickProfile extends CRM_Contribute_Form_Task {
/**
* The title of the group
*
* @var string
*/
protected $_title;
/**
* Maximum contributions that should be allowed to update
*/
protected $_maxContributions = 100;
/**
* Variable to store redirect path
*/
protected $_userContext;
/**
* Build all the data structures needed to build the form.
*/
public function preProcess() {
// initialize the task and row fields
parent::preProcess();
$session = CRM_Core_Session::singleton();
$this->_userContext = $session->readUserContext();
CRM_Utils_System::setTitle(ts('Update multiple contributions'));
$validate = FALSE;
//validations
if (count($this->_contributionIds) > $this->_maxContributions) {
CRM_Core_Session::setStatus(ts("The maximum number of contributions you can select for Update multiple contributions is %1. You have selected %2. Please select fewer contributions from your search results and try again.", array(
1 => $this->_maxContributions,
2 => count($this->_contributionIds),
)), ts('Update multiple records error'), 'error');
$validate = TRUE;
}
// than redirect
if ($validate) {
CRM_Utils_System::redirect($this->_userContext);
}
}
/**
* Build the form object.
*/
public function buildQuickForm() {
$types = array('Contribution');
$profiles = CRM_Core_BAO_UFGroup::getProfiles($types, TRUE);
if (empty($profiles)) {
CRM_Core_Session::setStatus(ts("You will need to create a Profile containing the %1 fields you want to edit before you can use Update multiple contributions. Navigate to Administer CiviCRM > Customize Data and Screens > CiviCRM Profile to configure a Profile. Consult the online Administrator documentation for more information.", array(1 => $types[0])), ts('Profile Required'), 'error');
CRM_Utils_System::redirect($this->_userContext);
}
$ufGroupElement = $this->add('select', 'uf_group_id', ts('Select Profile'),
array(
'' => ts('- select profile -'),
) + $profiles, TRUE
);
$this->addDefaultButtons(ts('Continue'));
}
/**
* Add local and global form rules.
*/
public function addRules() {
$this->addFormRule(array('CRM_Contribute_Form_Task_PickProfile', 'formRule'));
}
/**
* Global validation rules for the form.
*
* @param array $fields
* Posted values of the form.
*
* @return array
* list of errors to be posted back to the form
*/
public static function formRule($fields) {
return TRUE;
}
/**
* Process the form after the input has been submitted and validated.
*/
public function postProcess() {
$params = $this->exportValues();
$this->set('ufGroupId', $params['uf_group_id']);
// also reset the batch page so it gets new values from the db
$this->controller->resetPage('Batch');
}
}

View file

@ -0,0 +1,97 @@
<?php
/*
+--------------------------------------------------------------------+
| CiviCRM version 4.7 |
+--------------------------------------------------------------------+
| Copyright CiviCRM LLC (c) 2004-2017 |
+--------------------------------------------------------------------+
| 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 |
+--------------------------------------------------------------------+
*/
/**
*
* @package CRM
* @copyright CiviCRM LLC (c) 2004-2017
*/
/**
* This class provides the functionality to print contribution records.
*/
class CRM_Contribute_Form_Task_Print extends CRM_Contribute_Form_Task {
/**
* Build all the data structures needed to build the form.
*/
public function preProcess() {
parent::preprocess();
// set print view, so that print templates are called
$this->controller->setPrint(1);
// get the formatted params
$queryParams = $this->get('queryParams');
$sortID = NULL;
if ($this->get(CRM_Utils_Sort::SORT_ID)) {
$sortID = CRM_Utils_Sort::sortIDValue($this->get(CRM_Utils_Sort::SORT_ID),
$this->get(CRM_Utils_Sort::SORT_DIRECTION)
);
}
$selector = new CRM_Contribute_Selector_Search($queryParams, $this->_action, $this->_componentClause);
$controller = new CRM_Core_Selector_Controller($selector, NULL, $sortID, CRM_Core_Action::VIEW, $this, CRM_Core_Selector_Controller::SCREEN);
$controller->setEmbedded(TRUE);
$controller->run();
}
/**
* Build the form object.
*
* It consists of
* - displaying the QILL (query in local language)
* - displaying elements for saving the search
*/
public function buildQuickForm() {
//
// just need to add a javascript to popup the window for printing
//
$this->addButtons(array(
array(
'type' => 'next',
'name' => ts('Print Contributions'),
'js' => array('onclick' => 'window.print()'),
'isDefault' => TRUE,
),
array(
'type' => 'back',
'name' => ts('Done'),
),
)
);
}
/**
* Process the form after the input has been submitted and validated.
*/
public function postProcess() {
// redirect to the main search page after printing is over
}
}

View file

@ -0,0 +1,59 @@
<?php
/*
+--------------------------------------------------------------------+
| CiviCRM version 4.7 |
+--------------------------------------------------------------------+
| Copyright CiviCRM LLC (c) 2004-2017 |
+--------------------------------------------------------------------+
| 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 |
+--------------------------------------------------------------------+
*/
/**
*
* @package CRM
* @copyright CiviCRM LLC (c) 2004-2017
*/
/**
* Used for displaying results
*/
class CRM_Contribute_Form_Task_Result extends CRM_Contribute_Form_Task {
/**
* Build all the data structures needed to build the form.
*/
public function preProcess() {
}
/**
* Build the form object.
*/
public function buildQuickForm() {
$this->addButtons(array(
array(
'type' => 'done',
'name' => ts('Done'),
'isDefault' => TRUE,
),
)
);
}
}

View file

@ -0,0 +1,87 @@
<?php
/*
+--------------------------------------------------------------------+
| CiviCRM version 4.7 |
+--------------------------------------------------------------------+
| Copyright CiviCRM LLC (c) 2004-2017 |
+--------------------------------------------------------------------+
| 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 |
+--------------------------------------------------------------------+
*/
/**
*
* @package CRM
* @copyright CiviCRM LLC (c) 2004-2017
*/
/**
* This class provides the functionality to save a search
* Saved Searches are used for saving frequently used queries
*/
class CRM_Contribute_Form_Task_SearchTaskHookSample extends CRM_Contribute_Form_Task {
/**
* Build all the data structures needed to build the form.
*/
public function preProcess() {
parent::preProcess();
$rows = array();
// display name and contribution details of all selected contacts
$contribIDs = implode(',', $this->_contributionIds);
$query = "
SELECT co.total_amount as amount,
co.receive_date as receive_date,
co.source as source,
ct.display_name as display_name
FROM civicrm_contribution co
INNER JOIN civicrm_contact ct ON ( co.contact_id = ct.id )
WHERE co.id IN ( $contribIDs )";
$dao = CRM_Core_DAO::executeQuery($query,
CRM_Core_DAO::$_nullArray
);
while ($dao->fetch()) {
$rows[] = array(
'display_name' => $dao->display_name,
'amount' => $dao->amount,
'source' => $dao->source,
'receive_date' => $dao->receive_date,
);
}
$this->assign('rows', $rows);
}
/**
* Build the form object.
*/
public function buildQuickForm() {
$this->addButtons(array(
array(
'type' => 'done',
'name' => ts('Done'),
'isDefault' => TRUE,
),
)
);
}
}

View file

@ -0,0 +1,350 @@
<?php
/*
+--------------------------------------------------------------------+
| CiviCRM version 4.7 |
+--------------------------------------------------------------------+
| Copyright CiviCRM LLC (c) 2004-2017 |
+--------------------------------------------------------------------+
| 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 |
+--------------------------------------------------------------------+
*/
/**
*
* @package CRM
* @copyright CiviCRM LLC (c) 2004-2017
*/
/**
* This class provides the functionality to email a group of contacts.
*/
class CRM_Contribute_Form_Task_Status extends CRM_Contribute_Form_Task {
/**
* Are we operating in "single mode", i.e. updating the task of only
* one specific contribution?
*
* @var boolean
*/
public $_single = FALSE;
protected $_rows;
/**
* Build all the data structures needed to build the form.
*/
public function preProcess() {
$id = CRM_Utils_Request::retrieve('id', 'Positive',
$this, FALSE
);
if ($id) {
$this->_contributionIds = array($id);
$this->_componentClause = " civicrm_contribution.id IN ( $id ) ";
$this->_single = TRUE;
$this->assign('totalSelectedContributions', 1);
}
else {
parent::preProcess();
}
// check that all the contribution ids have pending status
$query = "
SELECT count(*)
FROM civicrm_contribution
WHERE contribution_status_id != 2
AND {$this->_componentClause}";
$count = CRM_Core_DAO::singleValueQuery($query,
CRM_Core_DAO::$_nullArray
);
if ($count != 0) {
CRM_Core_Error::statusBounce(ts('Please select only online contributions with Pending status.'));
}
// we have all the contribution ids, so now we get the contact ids
parent::setContactIDs();
$this->assign('single', $this->_single);
}
/**
* Build the form object.
*/
public function buildQuickForm() {
$status = CRM_Contribute_PseudoConstant::contributionStatus();
unset($status[2]);
unset($status[5]);
unset($status[6]);
$this->add('select', 'contribution_status_id',
ts('Contribution Status'),
$status,
TRUE
);
$contribIDs = implode(',', $this->_contributionIds);
$query = "
SELECT c.id as contact_id,
co.id as contribution_id,
c.display_name as display_name,
co.total_amount as amount,
co.receive_date as receive_date,
co.source as source,
co.payment_instrument_id as paid_by,
co.check_number as check_no
FROM civicrm_contact c,
civicrm_contribution co
WHERE co.contact_id = c.id
AND co.id IN ( $contribIDs )";
$dao = CRM_Core_DAO::executeQuery($query,
CRM_Core_DAO::$_nullArray
);
// build a row for each contribution id
$this->_rows = array();
$attributes = CRM_Core_DAO::getAttribute('CRM_Contribute_DAO_Contribution');
$defaults = array();
$now = date("m/d/Y");
$paidByOptions = array('' => ts('- select -')) + CRM_Contribute_PseudoConstant::paymentInstrument();
while ($dao->fetch()) {
$row['contact_id'] = $dao->contact_id;
$row['contribution_id'] = $dao->contribution_id;
$row['display_name'] = $dao->display_name;
$row['amount'] = $dao->amount;
$row['source'] = $dao->source;
$row['trxn_id'] = &$this->addElement('text', "trxn_id_{$row['contribution_id']}", ts('Transaction ID'));
$this->addRule("trxn_id_{$row['contribution_id']}",
ts('This Transaction ID already exists in the database. Include the account number for checks.'),
'objectExists',
array('CRM_Contribute_DAO_Contribution', $dao->contribution_id, 'trxn_id')
);
$row['fee_amount'] = &$this->add('text', "fee_amount_{$row['contribution_id']}", ts('Fee Amount'),
$attributes['fee_amount']
);
$this->addRule("fee_amount_{$row['contribution_id']}", ts('Please enter a valid amount.'), 'money');
$defaults["fee_amount_{$row['contribution_id']}"] = 0.0;
$row['trxn_date'] = $this->addDate("trxn_date_{$row['contribution_id']}", FALSE,
ts('Receipt Date'), array('formatType' => 'activityDate')
);
$defaults["trxn_date_{$row['contribution_id']}"] = $now;
$this->add("text", "check_number_{$row['contribution_id']}", ts('Check Number'));
$defaults["check_number_{$row['contribution_id']}"] = $dao->check_no;
$this->add("select", "payment_instrument_id_{$row['contribution_id']}", ts('Payment Method'), $paidByOptions);
$defaults["payment_instrument_id_{$row['contribution_id']}"] = $dao->paid_by;
$this->_rows[] = $row;
}
$this->assign_by_ref('rows', $this->_rows);
$this->setDefaults($defaults);
$this->addButtons(array(
array(
'type' => 'next',
'name' => ts('Update Pending Status'),
'isDefault' => TRUE,
),
array(
'type' => 'back',
'name' => ts('Cancel'),
),
)
);
$this->addFormRule(array('CRM_Contribute_Form_Task_Status', 'formRule'));
}
/**
* Global validation rules for the form.
*
* @param array $fields
* Posted values of the form.
*
* @return array
* list of errors to be posted back to the form
*/
public static function formRule($fields) {
$seen = $errors = array();
foreach ($fields as $name => $value) {
if (strpos($name, 'trxn_id_') !== FALSE) {
if ($fields[$name]) {
if (array_key_exists($value, $seen)) {
$errors[$name] = ts('Transaction ID\'s must be unique. Include the account number for checks.');
}
$seen[$value] = 1;
}
}
if ((strpos($name, 'check_number_') !== FALSE) && $value) {
$contribID = substr($name, 13);
if ($fields["payment_instrument_id_{$contribID}"] != CRM_Core_OptionGroup::getValue('payment_instrument', 'Check', 'name')) {
$errors["payment_instrument_id_{$contribID}"] = ts("Payment Method should be Check when a check number is entered for a contribution.");
}
}
}
return empty($errors) ? TRUE : $errors;
}
/**
* Process the form after the input has been submitted and validated.
*/
public function postProcess() {
$params = $this->controller->exportValues($this->_name);
// submit the form with values.
self::processForm($this, $params);
CRM_Core_Session::setStatus(ts('Contribution status has been updated for selected record(s).'), ts('Status Updated'), 'success');
}
/**
* Process the form with submitted params.
*
* Also supports unit test.
*
* @param CRM_Core_Form $form
* @param array $params
*
* @throws \Exception
*/
public static function processForm($form, $params) {
$statusID = CRM_Utils_Array::value('contribution_status_id', $params);
$baseIPN = new CRM_Core_Payment_BaseIPN();
$transaction = new CRM_Core_Transaction();
// get the missing pieces for each contribution
$contribIDs = implode(',', $form->_contributionIds);
$details = self::getDetails($contribIDs);
$template = CRM_Core_Smarty::singleton();
// for each contribution id, we just call the baseIPN stuff
foreach ($form->_rows as $row) {
$input = $ids = $objects = array();
$input['component'] = $details[$row['contribution_id']]['component'];
$ids['contact'] = $row['contact_id'];
$ids['contribution'] = $row['contribution_id'];
$ids['contributionRecur'] = NULL;
$ids['contributionPage'] = NULL;
$ids['membership'] = CRM_Utils_Array::value('membership', $details[$row['contribution_id']]);
$ids['participant'] = CRM_Utils_Array::value('participant', $details[$row['contribution_id']]);
$ids['event'] = CRM_Utils_Array::value('event', $details[$row['contribution_id']]);
if (!$baseIPN->validateData($input, $ids, $objects, FALSE)) {
CRM_Core_Error::fatal();
}
$contribution = &$objects['contribution'];
$contributionStatuses = CRM_Contribute_PseudoConstant::contributionStatus(NULL,
'name'
);
if ($statusID == array_search('Cancelled', $contributionStatuses)) {
$baseIPN->cancelled($objects, $transaction);
$transaction->commit();
continue;
}
elseif ($statusID == array_search('Failed', $contributionStatuses)) {
$baseIPN->failed($objects, $transaction);
$transaction->commit();
continue;
}
// status is not pending
if ($contribution->contribution_status_id != array_search('Pending',
$contributionStatuses
)
) {
$transaction->commit();
continue;
}
// set some fake input values so we can reuse IPN code
$input['amount'] = $contribution->total_amount;
$input['is_test'] = $contribution->is_test;
$input['fee_amount'] = $params["fee_amount_{$row['contribution_id']}"];
$input['check_number'] = $params["check_number_{$row['contribution_id']}"];
$input['payment_instrument_id'] = $params["payment_instrument_id_{$row['contribution_id']}"];
$input['net_amount'] = $contribution->total_amount - $input['fee_amount'];
if (!empty($params["trxn_id_{$row['contribution_id']}"])) {
$input['trxn_id'] = trim($params["trxn_id_{$row['contribution_id']}"]);
}
else {
$input['trxn_id'] = $contribution->invoice_id;
}
$input['trxn_date'] = CRM_Utils_Date::processDate($params["trxn_date_{$row['contribution_id']}"], date('H:i:s'));
// @todo calling baseIPN like this is a pattern in it's last gasps. Call contribute.completetransaction api.
$baseIPN->completeTransaction($input, $ids, $objects, $transaction, FALSE);
// reset template values before processing next transactions
$template->clearTemplateVars();
}
}
/**
* @param $contributionIDs
*
* @return array
*/
public static function &getDetails($contributionIDs) {
$query = "
SELECT c.id as contribution_id,
c.contact_id as contact_id ,
mp.membership_id as membership_id ,
pp.participant_id as participant_id ,
p.event_id as event_id
FROM civicrm_contribution c
LEFT JOIN civicrm_membership_payment mp ON mp.contribution_id = c.id
LEFT JOIN civicrm_participant_payment pp ON pp.contribution_id = c.id
LEFT JOIN civicrm_participant p ON pp.participant_id = p.id
WHERE c.id IN ( $contributionIDs )";
$rows = array();
$dao = CRM_Core_DAO::executeQuery($query,
CRM_Core_DAO::$_nullArray
);
$rows = array();
while ($dao->fetch()) {
$rows[$dao->contribution_id]['component'] = $dao->participant_id ? 'event' : 'contribute';
$rows[$dao->contribution_id]['contact'] = $dao->contact_id;
if ($dao->membership_id) {
if (!array_key_exists('membership', $rows[$dao->contribution_id])) {
$rows[$dao->contribution_id]['membership'] = array();
}
$rows[$dao->contribution_id]['membership'][] = $dao->membership_id;
}
if ($dao->participant_id) {
$rows[$dao->contribution_id]['participant'] = $dao->participant_id;
}
if ($dao->event_id) {
$rows[$dao->contribution_id]['event'] = $dao->event_id;
}
}
return $rows;
}
}

View file

@ -0,0 +1,418 @@
<?php
/*
+--------------------------------------------------------------------+
| CiviCRM version 4.7 |
+--------------------------------------------------------------------+
| Copyright CiviCRM LLC (c) 2004-2017 |
+--------------------------------------------------------------------+
| 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 |
+--------------------------------------------------------------------+
*/
/**
*
* @package CRM
* @copyright CiviCRM LLC (c) 2004-2017
*/
/**
* This class generates form components for processing a contribution.
*/
class CRM_Contribute_Form_UpdateBilling extends CRM_Core_Form {
protected $_crid = NULL;
protected $_coid = NULL;
protected $_mode = NULL;
protected $_subscriptionDetails = NULL;
protected $_selfService = FALSE;
public $_bltID = NULL;
/**
* @var array current payment processor including a copy of the object in 'object' key
*/
public $_paymentProcessor = array();
/**
* Set variables up before form is built.
*/
public function preProcess() {
$this->_mid = CRM_Utils_Request::retrieve('mid', 'Integer', $this, FALSE);
$this->_crid = CRM_Utils_Request::retrieve('crid', 'Integer', $this, FALSE);
if ($this->_crid) {
$this->_paymentProcessor = CRM_Financial_BAO_PaymentProcessor::getProcessorForEntity($this->_crid, 'recur', 'info');
$this->_paymentProcessor['object'] = CRM_Financial_BAO_PaymentProcessor::getProcessorForEntity($this->_crid, 'recur', 'obj');
$this->_subscriptionDetails = CRM_Contribute_BAO_ContributionRecur::getSubscriptionDetails($this->_crid);
// Are we cancelling a recurring contribution that is linked to an auto-renew membership?
if ($this->_subscriptionDetails->membership_id) {
$this->_mid = $this->_subscriptionDetails->membership_id;
}
}
$this->_coid = CRM_Utils_Request::retrieve('coid', 'Integer', $this, FALSE);
if ($this->_coid) {
$this->_paymentProcessor = CRM_Financial_BAO_PaymentProcessor::getProcessorForEntity($this->_coid, 'contribute', 'info');
$this->_paymentProcessor['object'] = CRM_Financial_BAO_PaymentProcessor::getProcessorForEntity($this->_coid, 'contribute', 'obj');
$this->_subscriptionDetails = CRM_Contribute_BAO_ContributionRecur::getSubscriptionDetails($this->_coid, 'contribution');
}
if ($this->_mid) {
$this->_paymentProcessor = CRM_Financial_BAO_PaymentProcessor::getProcessorForEntity($this->_mid, 'membership', 'info');
$this->_paymentProcessor['object'] = CRM_Financial_BAO_PaymentProcessor::getProcessorForEntity($this->_mid, 'membership', 'obj');
$this->_subscriptionDetails = CRM_Contribute_BAO_ContributionRecur::getSubscriptionDetails($this->_mid, 'membership');
$membershipTypes = CRM_Member_PseudoConstant::membershipType();
$membershipTypeId = CRM_Core_DAO::getFieldValue('CRM_Member_DAO_Membership', $this->_mid, 'membership_type_id');
$this->assign('membershipType', CRM_Utils_Array::value($membershipTypeId, $membershipTypes));
$this->_mode = 'auto_renew';
}
if ((!$this->_crid && !$this->_coid && !$this->_mid) || (!$this->_subscriptionDetails)) {
CRM_Core_Error::fatal('Required information missing.');
}
if (!CRM_Core_Permission::check('edit contributions')) {
$userChecksum = CRM_Utils_Request::retrieve('cs', 'String', $this, FALSE);
if (!CRM_Contact_BAO_Contact_Utils::validChecksum($this->_subscriptionDetails->contact_id, $userChecksum)) {
CRM_Core_Error::fatal(ts('You do not have permission to cancel subscription.'));
}
$this->_selfService = TRUE;
}
if (!$this->_paymentProcessor['object']->isSupported('updateSubscriptionBillingInfo')) {
CRM_Core_Error::fatal(ts("%1 processor doesn't support updating subscription billing details.",
array(1 => $this->_paymentProcessor['object']->_processorName)
));
}
$this->assign('paymentProcessor', $this->_paymentProcessor);
$this->assignBillingType();
$this->assign('frequency_unit', $this->_subscriptionDetails->frequency_unit);
$this->assign('frequency_interval', $this->_subscriptionDetails->frequency_interval);
$this->assign('amount', $this->_subscriptionDetails->amount);
$this->assign('installments', $this->_subscriptionDetails->installments);
$this->assign('mode', $this->_mode);
// handle context redirection
CRM_Contribute_BAO_ContributionRecur::setSubscriptionContext();
}
/**
* Set the default values of various form elements.
*
* @return array
* Default values
*/
public function setDefaultValues() {
$this->_defaults = array();
if ($this->_subscriptionDetails->contact_id) {
$fields = array();
$names = array(
'first_name',
'middle_name',
'last_name',
"street_address-{$this->_bltID}",
"city-{$this->_bltID}",
"postal_code-{$this->_bltID}",
"country_id-{$this->_bltID}",
"state_province_id-{$this->_bltID}",
);
foreach ($names as $name) {
$fields[$name] = 1;
}
$fields["state_province-{$this->_bltID}"] = 1;
$fields["country-{$this->_bltID}"] = 1;
$fields["email-{$this->_bltID}"] = 1;
$fields['email-Primary'] = 1;
CRM_Core_BAO_UFGroup::setProfileDefaults($this->_subscriptionDetails->contact_id, $fields, $this->_defaults);
// use primary email address if billing email address is empty
if (empty($this->_defaults["email-{$this->_bltID}"]) &&
!empty($this->_defaults['email-Primary'])
) {
$this->_defaults["email-{$this->_bltID}"] = $this->_defaults['email-Primary'];
}
foreach ($names as $name) {
if (!empty($this->_defaults[$name])) {
$this->_defaults['billing_' . $name] = $this->_defaults[$name];
}
}
}
$config = CRM_Core_Config::singleton();
// set default country from config if no country set
if (empty($this->_defaults["billing_country_id-{$this->_bltID}"])) {
$this->_defaults["billing_country_id-{$this->_bltID}"] = $config->defaultContactCountry;
}
return $this->_defaults;
}
/**
* Build the form object.
*/
public function buildQuickForm() {
$type = 'next';
if ($this->_selfService) {
$type = 'submit';
}
$this->addButtons(array(
array(
'type' => $type,
'name' => ts('Save'),
'isDefault' => TRUE,
),
array(
'type' => 'cancel',
'name' => ts('Cancel'),
),
)
);
CRM_Core_Payment_Form::buildPaymentForm($this, $this->_paymentProcessor, TRUE, TRUE);
$this->addFormRule(array('CRM_Contribute_Form_UpdateBilling', 'formRule'), $this);
}
/**
* Global form rule.
*
* @param array $fields
* The input form values.
* @param array $files
* The uploaded files if any.
* @param CRM_Core_Form $self
*
*
* @return bool|array
* true if no errors, else array of errors
*/
public static function formRule($fields, $files, $self) {
$errors = array();
CRM_Core_Form::validateMandatoryFields($self->_fields, $fields, $errors);
// validate the payment instrument values (e.g. credit card number)
CRM_Core_Payment_Form::validatePaymentInstrument($self->_paymentProcessor['id'], $fields, $errors, NULL);
return empty($errors) ? TRUE : $errors;
}
/**
* Process the form.
*/
public function postProcess() {
$params = $this->controller->exportValues($this->_name);
$status = NULL;
// now set the values for the billing location.
foreach ($this->_fields as $name => $value) {
$fields[$name] = 1;
}
$fields["email-{$this->_bltID}"] = 1;
$processorParams = array();
foreach ($params as $key => $val) {
$key = str_replace('billing_', '', $key);
list($key) = explode('-', $key);
$processorParams[$key] = $val;
}
$processorParams['state_province'] = CRM_Core_PseudoConstant::stateProvince($params["billing_state_province_id-{$this->_bltID}"], FALSE);
$processorParams['country'] = CRM_Core_PseudoConstant::country($params["billing_country_id-{$this->_bltID}"], FALSE);
$processorParams['month'] = $processorParams['credit_card_exp_date']['M'];
$processorParams['year'] = $processorParams['credit_card_exp_date']['Y'];
$processorParams['subscriptionId'] = $this->_subscriptionDetails->subscription_id;
$processorParams['amount'] = $this->_subscriptionDetails->amount;
$updateSubscription = $this->_paymentProcessor['object']->updateSubscriptionBillingInfo($message, $processorParams);
if (is_a($updateSubscription, 'CRM_Core_Error')) {
CRM_Core_Error::displaySessionError($updateSubscription);
}
elseif ($updateSubscription) {
$ctype = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Contact', $this->_subscriptionDetails->contact_id, 'contact_type');
$contact = &CRM_Contact_BAO_Contact::createProfileContact($params,
$fields,
$this->_subscriptionDetails->contact_id,
NULL,
NULL,
$ctype
);
// build tpl params
if ($this->_subscriptionDetails->membership_id) {
$inputParams = array('id' => $this->_subscriptionDetails->membership_id);
CRM_Member_BAO_Membership::getValues($inputParams, $tplParams);
$tplParams = $tplParams[$this->_subscriptionDetails->membership_id];
$tplParams['membership_status'] = CRM_Core_DAO::getFieldValue('CRM_Member_DAO_MembershipStatus', $tplParams['status_id']);
$tplParams['membershipType'] = CRM_Core_DAO::getFieldValue('CRM_Member_DAO_MembershipType', $tplParams['membership_type_id']);
$status = ts('Billing details for your automatically renewed %1 membership have been updated.',
array(1 => $tplParams['membershipType'])
);
$msgTitle = ts('Details Updated');
$msgType = 'success';
}
else {
$status = ts('Billing details for the recurring contribution of %1, every %2 %3 have been updated.',
array(
1 => $this->_subscriptionDetails->amount,
2 => $this->_subscriptionDetails->frequency_interval,
3 => $this->_subscriptionDetails->frequency_unit,
)
);
$msgTitle = ts('Details Updated');
$msgType = 'success';
$tplParams = array(
'recur_frequency_interval' => $this->_subscriptionDetails->frequency_interval,
'recur_frequency_unit' => $this->_subscriptionDetails->frequency_unit,
'amount' => $this->_subscriptionDetails->amount,
);
}
// format new address for display
$addressParts = array("street_address", "city", "postal_code", "state_province", "country");
foreach ($addressParts as $part) {
$addressParts[$part] = CRM_Utils_Array::value($part, $processorParams);
}
$tplParams['address'] = CRM_Utils_Address::format($addressParts);
// format old address to store in activity details
$this->_defaults["state_province-{$this->_bltID}"] = CRM_Core_PseudoConstant::stateProvince($this->_defaults["state_province-{$this->_bltID}"], FALSE);
$this->_defaults["country-{$this->_bltID}"] = CRM_Core_PseudoConstant::country($this->_defaults["country-{$this->_bltID}"], FALSE);
$addressParts = array("street_address", "city", "postal_code", "state_province", "country");
foreach ($addressParts as $part) {
$key = "{$part}-{$this->_bltID}";
$addressParts[$part] = CRM_Utils_Array::value($key, $this->_defaults);
}
$this->_defaults['address'] = CRM_Utils_Address::format($addressParts);
// format new billing name
$name = $processorParams['first_name'];
if (!empty($processorParams['middle_name'])) {
$name .= " {$processorParams['middle_name']}";
}
$name .= ' ' . $processorParams['last_name'];
$name = trim($name);
$tplParams['billingName'] = $name;
// format old billing name
$name = $this->_defaults['first_name'];
if (!empty($this->_defaults['middle_name'])) {
$name .= " {$this->_defaults['middle_name']}";
}
$name .= ' ' . $this->_defaults['last_name'];
$name = trim($name);
$this->_defaults['billingName'] = $name;
$message .= "
<br/><br/>New Billing Name and Address
<br/>==============================
<br/>{$tplParams['billingName']}
<br/>{$tplParams['address']}
<br/><br/>Previous Billing Name and Address
<br/>==================================
<br/>{$this->_defaults['billingName']}
<br/>{$this->_defaults['address']}";
$activityParams = array(
'source_contact_id' => $this->_subscriptionDetails->contact_id,
'activity_type_id' => CRM_Core_OptionGroup::getValue('activity_type',
'Update Recurring Contribution Billing Details',
'name'
),
'subject' => ts('Recurring Contribution Billing Details Updated'),
'details' => $message,
'activity_date_time' => date('YmdHis'),
'status_id' => CRM_Core_OptionGroup::getValue('activity_status',
'Completed',
'name'
),
);
$session = CRM_Core_Session::singleton();
$cid = $session->get('userID');
if ($cid) {
$activityParams['target_contact_id'][] = $activityParams['source_contact_id'];
$activityParams['source_contact_id'] = $cid;
}
CRM_Activity_BAO_Activity::create($activityParams);
// send notification
if ($this->_subscriptionDetails->contribution_page_id) {
CRM_Core_DAO::commonRetrieveAll('CRM_Contribute_DAO_ContributionPage', 'id',
$this->_subscriptionDetails->contribution_page_id, $value, array(
'title',
'receipt_from_name',
'receipt_from_email',
)
);
$receiptFrom = '"' . CRM_Utils_Array::value('receipt_from_name', $value[$this->_subscriptionDetails->contribution_page_id]) . '" <' . $value[$this->_subscriptionDetails->contribution_page_id]['receipt_from_email'] . '>';
}
else {
$domainValues = CRM_Core_BAO_Domain::getNameAndEmail();
$receiptFrom = "$domainValues[0] <$domainValues[1]>";
}
list($donorDisplayName, $donorEmail) = CRM_Contact_BAO_Contact::getContactDetails($this->_subscriptionDetails->contact_id);
$tplParams['contact'] = array('display_name' => $donorDisplayName);
$date = CRM_Utils_Date::format($processorParams['credit_card_exp_date']);
$tplParams['credit_card_exp_date'] = CRM_Utils_Date::mysqlToIso($date);
$tplParams['credit_card_number'] = CRM_Utils_System::mungeCreditCard($processorParams['credit_card_number']);
$tplParams['credit_card_type'] = $processorParams['credit_card_type'];
$sendTemplateParams = array(
'groupName' => $this->_subscriptionDetails->membership_id ? 'msg_tpl_workflow_membership' : 'msg_tpl_workflow_contribution',
'valueName' => $this->_subscriptionDetails->membership_id ? 'membership_autorenew_billing' : 'contribution_recurring_billing',
'contactId' => $this->_subscriptionDetails->contact_id,
'tplParams' => $tplParams,
'isTest' => $this->_subscriptionDetails->is_test,
'PDFFilename' => 'receipt.pdf',
'from' => $receiptFrom,
'toName' => $donorDisplayName,
'toEmail' => $donorEmail,
);
list($sent) = CRM_Core_BAO_MessageTemplate::sendTemplate($sendTemplateParams);
}
else {
$status = ts('There was some problem updating the billing details.');
$msgTitle = ts('Update Error');
$msgType = 'error';
}
$session = CRM_Core_Session::singleton();
$userID = $session->get('userID');
if ($userID && $status) {
$session->setStatus($status, $msgTitle, $msgType);
}
elseif (!$userID) {
if ($status) {
CRM_Utils_System::setUFMessage($status);
}
$result = (int) ($updateSubscription && isset($ctype));
if (isset($tplParams)) {
$session->set('resultParams', $tplParams);
}
return CRM_Utils_System::redirect(CRM_Utils_System::url('civicrm/contribute/subscriptionstatus',
"reset=1&task=billing&result={$result}"));
}
}
}

View file

@ -0,0 +1,373 @@
<?php
/*
+--------------------------------------------------------------------+
| CiviCRM version 4.7 |
+--------------------------------------------------------------------+
| Copyright CiviCRM LLC (c) 2004-2017 |
+--------------------------------------------------------------------+
| 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 |
+--------------------------------------------------------------------+
*/
/**
* @package CRM
* @copyright CiviCRM LLC (c) 2004-2017
*/
/**
* This class generates form components generic to recurring contributions.
*
* It delegates the work to lower level subclasses and integrates the changes
* back in. It also uses a lot of functionality with the CRM API's, so any change
* made here could potentially affect the API etc. Be careful, be aware, use unit tests.
*/
class CRM_Contribute_Form_UpdateSubscription extends CRM_Core_Form {
/**
* The recurring contribution id, used when editing the recurring contribution.
*
* @var int
*/
protected $contributionRecurID = NULL;
protected $_coid = NULL;
protected $_subscriptionDetails = NULL;
protected $_selfService = FALSE;
public $_paymentProcessor = NULL;
public $_paymentProcessorObj = NULL;
/**
* Fields that affect the schedule and are defined as editable by the processor.
*
* @var array
*/
protected $editableScheduleFields = array();
/**
* The id of the contact associated with this recurring contribution.
*
* @var int
*/
public $_contactID;
/**
* Pre-processing for the form.
*
* @throws \Exception
*/
public function preProcess() {
$this->setAction(CRM_Core_Action::UPDATE);
$this->contributionRecurID = CRM_Utils_Request::retrieve('crid', 'Integer', $this, FALSE);
if ($this->contributionRecurID) {
$this->_paymentProcessor = CRM_Contribute_BAO_ContributionRecur::getPaymentProcessor($this->contributionRecurID);
if (!$this->_paymentProcessor) {
CRM_Core_Error::statusBounce(ts('There is no valid processor for this subscription so it cannot be edited.'));
}
$this->_paymentProcessorObj = $this->_paymentProcessor['object'];
$this->_subscriptionDetails = CRM_Contribute_BAO_ContributionRecur::getSubscriptionDetails($this->contributionRecurID);
}
$this->_coid = CRM_Utils_Request::retrieve('coid', 'Integer', $this, FALSE);
if ($this->_coid) {
$this->_paymentProcessor = CRM_Financial_BAO_PaymentProcessor::getProcessorForEntity($this->_coid, 'contribute', 'info');
$this->_paymentProcessorObj = CRM_Financial_BAO_PaymentProcessor::getProcessorForEntity($this->_coid, 'contribute', 'obj');
$this->_subscriptionDetails = CRM_Contribute_BAO_ContributionRecur::getSubscriptionDetails($this->_coid, 'contribution');
$this->contributionRecurID = $this->_subscriptionDetails->recur_id;
}
elseif ($this->contributionRecurID) {
$this->_coid = CRM_Core_DAO::getFieldValue('CRM_Contribute_DAO_Contribution', $this->contributionRecurID, 'id', 'contribution_recur_id');
}
if (!$this->contributionRecurID || !$this->_subscriptionDetails) {
CRM_Core_Error::statusBounce(ts('Required information missing.'));
}
if ($this->_subscriptionDetails->membership_id && $this->_subscriptionDetails->auto_renew) {
CRM_Core_Error::statusBounce(ts('You cannot update the subscription.'));
}
if (!CRM_Core_Permission::check('edit contributions')) {
$userChecksum = CRM_Utils_Request::retrieve('cs', 'String', $this, FALSE);
if (!CRM_Contact_BAO_Contact_Utils::validChecksum($this->_subscriptionDetails->contact_id, $userChecksum)) {
CRM_Core_Error::statusBounce(ts('You do not have permission to update subscription.'));
}
$this->_selfService = TRUE;
}
$this->assign('self_service', $this->_selfService);
$this->editableScheduleFields = $this->_paymentProcessorObj->getEditableRecurringScheduleFields();
$changeHelpText = $this->_paymentProcessorObj->getRecurringScheduleUpdateHelpText();
if (!in_array('amount', $this->editableScheduleFields)) {
// Not sure if this is good behaviour - maintaining this existing behaviour for now.
CRM_Core_Session::setStatus($changeHelpText, ts('Warning'), 'alert');
}
else {
$this->assign('changeHelpText', $changeHelpText);
}
$alreadyHardCodedFields = array('amount', 'installments');
foreach ($this->editableScheduleFields as $editableScheduleField) {
if (!in_array($editableScheduleField, $alreadyHardCodedFields)) {
$this->addField($editableScheduleField, array('entity' => 'ContributionRecur'));
}
}
$this->assign('editableScheduleFields', array_diff($this->editableScheduleFields, $alreadyHardCodedFields));
$this->assign('paymentProcessor', $this->_paymentProcessor);
$this->assign('frequency_unit', $this->_subscriptionDetails->frequency_unit);
$this->assign('frequency_interval', $this->_subscriptionDetails->frequency_interval);
if ($this->_subscriptionDetails->contact_id) {
list($this->_donorDisplayName, $this->_donorEmail) = CRM_Contact_BAO_Contact::getContactDetails($this->_subscriptionDetails->contact_id);
}
CRM_Utils_System::setTitle(ts('Update Recurring Contribution'));
// Handle context redirection.
CRM_Contribute_BAO_ContributionRecur::setSubscriptionContext();
}
/**
* Set default values for the form.
*
* Note that in edit/view mode the default values are retrieved from the database.
*/
public function setDefaultValues() {
$this->_defaults = array();
$this->_defaults['amount'] = $this->_subscriptionDetails->amount;
$this->_defaults['installments'] = $this->_subscriptionDetails->installments;
$this->_defaults['campaign_id'] = $this->_subscriptionDetails->campaign_id;
$this->_defaults['financial_type_id'] = $this->_subscriptionDetails->financial_type_id;
$this->_defaults['is_notify'] = 1;
foreach ($this->editableScheduleFields as $field) {
$this->_defaults[$field] = $this->_subscriptionDetails->$field;
}
return $this->_defaults;
}
/**
* Actually build the components of the form.
*/
public function buildQuickForm() {
// CRM-16398: If current recurring contribution got > 1 lineitems then make amount field readonly
$amtAttr = array('size' => 20);
$lineItems = CRM_Price_BAO_LineItem::getLineItemsByContributionID($this->_coid);
if (count($lineItems) > 1) {
$amtAttr += array('readonly' => TRUE);
}
$this->addMoney('amount', ts('Recurring Contribution Amount'), TRUE, $amtAttr,
TRUE, 'currency', $this->_subscriptionDetails->currency, TRUE
);
$this->add('text', 'installments', ts('Number of Installments'), array('size' => 20), FALSE);
if ($this->_donorEmail) {
$this->add('checkbox', 'is_notify', ts('Notify Contributor?'));
}
if (CRM_Core_Permission::check('edit contributions')) {
CRM_Campaign_BAO_Campaign::addCampaign($this, $this->_subscriptionDetails->campaign_id);
}
if (CRM_Contribute_BAO_ContributionRecur::supportsFinancialTypeChange($this->contributionRecurID)) {
$this->addEntityRef('financial_type_id', ts('Financial Type'), array('entity' => 'FinancialType'), !$this->_selfService);
}
$type = 'next';
if ($this->_selfService) {
$type = 'submit';
}
// define the buttons
$this->addButtons(array(
array(
'type' => $type,
'name' => ts('Save'),
'isDefault' => TRUE,
),
array(
'type' => 'cancel',
'name' => ts('Cancel'),
),
)
);
}
/**
* Called after the user submits the form.
*/
public function postProcess() {
// store the submitted values in an array
$params = $this->exportValues();
if ($this->_selfService && $this->_donorEmail) {
// for self service force notify
$params['is_notify'] = 1;
}
// if this is an update of an existing recurring contribution, pass the ID
$params['id'] = $this->_subscriptionDetails->recur_id;
$message = '';
$params['subscriptionId'] = $this->_subscriptionDetails->subscription_id;
$updateSubscription = TRUE;
if ($this->_paymentProcessorObj->isSupported('changeSubscriptionAmount')) {
$updateSubscription = $this->_paymentProcessorObj->changeSubscriptionAmount($message, $params);
}
if (is_a($updateSubscription, 'CRM_Core_Error')) {
CRM_Core_Error::displaySessionError($updateSubscription);
$status = ts('Could not update the Recurring contribution details');
$msgTitle = ts('Update Error');
$msgType = 'error';
}
elseif ($updateSubscription) {
// save the changes
$result = CRM_Contribute_BAO_ContributionRecur::add($params);
$status = ts('Recurring contribution has been updated to: %1, every %2 %3(s) for %4 installments.',
array(
1 => CRM_Utils_Money::format($params['amount'], $this->_subscriptionDetails->currency),
2 => $this->_subscriptionDetails->frequency_interval,
3 => $this->_subscriptionDetails->frequency_unit,
4 => $params['installments'],
)
);
$msgTitle = ts('Update Success');
$msgType = 'success';
$msg = ts('Recurring Contribution Updated');
$contactID = $this->_subscriptionDetails->contact_id;
if ($this->_subscriptionDetails->amount != $params['amount']) {
$message .= "<br /> " . ts("Recurring contribution amount has been updated from %1 to %2 for this subscription.",
array(
1 => CRM_Utils_Money::format($this->_subscriptionDetails->amount, $this->_subscriptionDetails->currency),
2 => CRM_Utils_Money::format($params['amount'], $this->_subscriptionDetails->currency),
)) . ' ';
if ($this->_subscriptionDetails->amount < $params['amount']) {
$msg = ts('Recurring Contribution Updated - increased installment amount');
}
else {
$msg = ts('Recurring Contribution Updated - decreased installment amount');
}
}
if ($this->_subscriptionDetails->installments != $params['installments']) {
$message .= "<br /> " . ts("Recurring contribution installments have been updated from %1 to %2 for this subscription.", array(
1 => $this->_subscriptionDetails->installments,
2 => $params['installments'],
)) . ' ';
}
$activityParams = array(
'source_contact_id' => $contactID,
'activity_type_id' => CRM_Core_OptionGroup::getValue('activity_type',
'Update Recurring Contribution',
'name'
),
'subject' => $msg,
'details' => $message,
'activity_date_time' => date('YmdHis'),
'status_id' => CRM_Core_OptionGroup::getValue('activity_status',
'Completed',
'name'
),
);
$session = CRM_Core_Session::singleton();
$cid = $session->get('userID');
if ($cid) {
$activityParams['target_contact_id'][] = $activityParams['source_contact_id'];
$activityParams['source_contact_id'] = $cid;
}
CRM_Activity_BAO_Activity::create($activityParams);
if (!empty($params['is_notify'])) {
// send notification
if ($this->_subscriptionDetails->contribution_page_id) {
CRM_Core_DAO::commonRetrieveAll('CRM_Contribute_DAO_ContributionPage', 'id',
$this->_subscriptionDetails->contribution_page_id, $value, array(
'title',
'receipt_from_name',
'receipt_from_email',
)
);
$receiptFrom = '"' . CRM_Utils_Array::value('receipt_from_name', $value[$this->_subscriptionDetails->contribution_page_id]) . '" <' . $value[$this->_subscriptionDetails->contribution_page_id]['receipt_from_email'] . '>';
}
else {
$domainValues = CRM_Core_BAO_Domain::getNameAndEmail();
$receiptFrom = "$domainValues[0] <$domainValues[1]>";
}
list($donorDisplayName, $donorEmail) = CRM_Contact_BAO_Contact::getContactDetails($contactID);
$tplParams = array(
'recur_frequency_interval' => $this->_subscriptionDetails->frequency_interval,
'recur_frequency_unit' => $this->_subscriptionDetails->frequency_unit,
'amount' => CRM_Utils_Money::format($params['amount']),
'installments' => $params['installments'],
);
$tplParams['contact'] = array('display_name' => $donorDisplayName);
$tplParams['receipt_from_email'] = $receiptFrom;
$sendTemplateParams = array(
'groupName' => 'msg_tpl_workflow_contribution',
'valueName' => 'contribution_recurring_edit',
'contactId' => $contactID,
'tplParams' => $tplParams,
'isTest' => $this->_subscriptionDetails->is_test,
'PDFFilename' => 'receipt.pdf',
'from' => $receiptFrom,
'toName' => $donorDisplayName,
'toEmail' => $donorEmail,
);
list($sent) = CRM_Core_BAO_MessageTemplate::sendTemplate($sendTemplateParams);
}
}
$session = CRM_Core_Session::singleton();
$userID = $session->get('userID');
if ($userID && $status) {
CRM_Core_Session::setStatus($status, $msgTitle, $msgType);
}
elseif (!$userID) {
if ($status) {
CRM_Utils_System::setUFMessage($status);
}
// keep result as 1, since we not displaying anything on the redirected page anyway
return CRM_Utils_System::redirect(CRM_Utils_System::url('civicrm/contribute/subscriptionstatus',
"reset=1&task=update&result=1"));
}
}
/**
* Explicitly declare the form context.
*/
public function getDefaultContext() {
return 'create';
}
}