Skip to content
Permalink
Branch: master
Find file Copy path
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
816 lines (763 sloc) 29.4 KB
<?php
/**
* @file Copyright iATS Payments (c) 2014
* Author: Alan Dixon.
*
* This file is a part of CiviCRM published extension.
*
* This extension 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.
*
* It 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 with this program; if not, see http://www.gnu.org/licenses/
*/
//opcache_reset();
require_once 'iats.civix.php';
use CRM_Iats_ExtensionUtil as E;
/* First American requires a "category" for ACH transaction requests */
define('FAPS_DEFAULT_ACH_CATEGORY_TEXT', 'CiviCRM ACH');
/**
* Implements hook_civicrm_config().
*
* @link http://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_config
*/
function iats_civicrm_config(&$config) {
_iats_civix_civicrm_config($config);
}
/**
* Implements hook_civicrm_xmlMenu().
*
* @link http://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_xmlMenu
*/
function iats_civicrm_xmlMenu(&$files) {
_iats_civix_civicrm_xmlMenu($files);
}
/**
* Implements hook_civicrm_install().
*
* @link http://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_install
* TODO: don't require iATS if we're not installing the old processors.
*/
function iats_civicrm_install() {
if (!class_exists('SoapClient')) {
$session = CRM_Core_Session::singleton();
$session->setStatus(ts('The PHP SOAP extension is not installed on this server, but is required for this extension'), ts('iATS Payments Installation'), 'error');
}
_iats_civix_civicrm_install();
}
/**
* Implements hook_civicrm_postInstall().
*
* @link http://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_postInstall
*/
function iats_civicrm_postInstall() {
_iats_civix_civicrm_postInstall();
}
/**
* Implements hook_civicrm_uninstall().
*
* @link http://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_uninstall
*/
function iats_civicrm_uninstall() {
_iats_civix_civicrm_uninstall();
}
/**
* Implements hook_civicrm_enable().
*
* @link http://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_enable
*/
function iats_civicrm_enable() {
if (!class_exists('SoapClient')) {
$session = CRM_Core_Session::singleton();
$session->setStatus(ts('The PHP SOAP extension is not installed on this server, but is required for this extension'), ts('iATS Payments Installation'), 'error');
}
_iats_civix_civicrm_enable();
}
/**
* Implements hook_civicrm_disable().
*
* @link http://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_disable
*/
function iats_civicrm_disable() {
_iats_civix_civicrm_disable();
}
/**
* Implements hook_civicrm_upgrade().
*
* @link http://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_upgrade
*/
function iats_civicrm_upgrade($op, CRM_Queue_Queue $queue = NULL) {
return _iats_civix_civicrm_upgrade($op, $queue);
}
/**
* Implements hook_civicrm_managed().
*
* Generate a list of entities to create/deactivate/delete when this module
* is installed, disabled, uninstalled.
*
* @link http://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_managed
*/
function iats_civicrm_managed(&$entities) {
_iats_civix_civicrm_managed($entities);
}
/**
* Implements hook_civicrm_caseTypes().
*
* Generate a list of case-types.
*
* Note: This hook only runs in CiviCRM 4.4+.
*
* @link http://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_caseTypes
*/
function iats_civicrm_caseTypes(&$caseTypes) {
_iats_civix_civicrm_caseTypes($caseTypes);
}
/**
* Implements hook_civicrm_angularModules().
*
* Generate a list of Angular modules.
*
* Note: This hook only runs in CiviCRM 4.5+. It may
* use features only available in v4.6+.
*
* @link http://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_angularModules
*/
function iats_civicrm_angularModules(&$angularModules) {
_iats_civix_civicrm_angularModules($angularModules);
}
/**
* Implements hook_civicrm_alterSettingsFolders().
*
* @link http://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_alterSettingsFolders
*/
function iats_civicrm_alterSettingsFolders(&$metaDataFolders = NULL) {
_iats_civix_civicrm_alterSettingsFolders($metaDataFolders);
}
/**
* Implements hook_civicrm_entityTypes().
*
* Declare entity types provided by this module.
*
* @link http://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_entityTypes
*/
function iats_civicrm_entityTypes(&$entityTypes) {
_iats_civix_civicrm_entityTypes($entityTypes);
}
// --- Functions below this ship commented out. Uncomment as required. ---
/**
* Implements hook_civicrm_preProcess().
*
* @link http://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_preProcess
*
function iats_civicrm_preProcess($formName, &$form) {
} // */
/**
* Implements hook_civicrm_navigationMenu().
*
* @link http://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_navigationMenu
*
function iats_civicrm_navigationMenu(&$menu) {
_iats_civix_insert_navigation_menu($menu, 'Mailings', array(
'label' => E::ts('New subliminal message'),
'name' => 'mailing_subliminal_message',
'url' => 'civicrm/mailing/subliminal',
'permission' => 'access CiviMail',
'operator' => 'OR',
'separator' => 0,
));
_iats_civix_navigationMenu($menu);
} // */
/**
* Implements hook_civicrm_check().
*/
function iats_civicrm_check(&$messages) {
if (!class_exists('SoapClient')) {
$messages[] = new CRM_Utils_Check_Message(
'iats_soap',
ts('The SOAP extension for PHP %1 is not installed on this server, but is required for this extension.', array(1 => phpversion())),
ts('iATS Payments Installation'),
\Psr\Log\LogLevel::CRITICAL,
'fa-flag'
);
}
}
/**
* Utility function to get domain info.
*
* Get values from the civicrm_domain table, or a domain setting.
* May be called multiple times, so be efficient.
*/
function _iats_civicrm_domain_info($key) {
static $domain, $settings;
if (empty($domain)) {
$domain = civicrm_api3('Domain', 'getsingle', array('current_domain' => TRUE));
}
if (!isset($settings)) {
$settings = array();
}
switch ($key) {
case 'version':
return explode('.', $domain['version']);
default:
if (isset($domain[$key])) {
return $domain[$key];
}
elseif (isset($settings[$key])) {
return $settings[$key];
}
else {
try{
$setting = civicrm_api3('Setting', 'getvalue', array('name' => $key));
if (is_string($setting)) {
$settings[$key] = $setting;
return $setting;
}
}
catch (CiviCRM_API3_Exception $e) {
// ignore errors
}
// This remaining code is now very legacy, from earlier Civi versions and should soon be retired.
if (!empty($domain['config_backend'])) {
$config_backend = unserialize($domain['config_backend']);
if (!empty($config_backend[$key])) {
$settings[$key] = $config_backend[$key];
return $config_backend[$key];
}
}
}
// Uncomment one or more of these lines to find out what it was we were looking for and didn't find.
// CRM_Core_Error::debug_var('domain', $domain);
// CRM_Core_Error::debug_var($key, $settings);
// CRM_Core_Error::debug_var($key, $setting);
}
}
/* START utility functions to allow this extension to work with different civicrm version */
// removed, 1.7 release
/* END functions to allow this extension to work with different civicrm version */
/**
* Utility to get the next available menu key.
*/
function _iats_getMenuKeyMax($menuArray) {
$max = array(max(array_keys($menuArray)));
foreach ($menuArray as $v) {
if (!empty($v['child'])) {
$max[] = _iats_getMenuKeyMax($v['child']);
}
}
return max($max);
}
/**
*
*/
function iats_civicrm_navigationMenu(&$navMenu) {
$pages = array(
'admin_page' => array(
'label' => 'iATS Payments Admin',
'name' => 'iATS Payments Admin',
'url' => 'civicrm/iATSAdmin',
'parent' => array('Contributions'),
'permission' => 'access CiviContribute,administer CiviCRM',
'operator' => 'AND',
'separator' => NULL,
'active' => 1,
),
'settings_page' => array(
'label' => 'iATS Payments Settings',
'name' => 'iATS Payments Settings',
'url' => 'civicrm/admin/contribute/iatssettings',
'parent' => array('Administer', 'CiviContribute'),
'permission' => 'access CiviContribute,administer CiviCRM',
'operator' => 'AND',
'separator' => NULL,
'active' => 1,
),
);
foreach ($pages as $item) {
// Check that our item doesn't already exist.
$menu_item_search = array('url' => $item['url']);
$menu_items = array();
CRM_Core_BAO_Navigation::retrieve($menu_item_search, $menu_items);
if (empty($menu_items)) {
$path = implode('/', $item['parent']);
unset($item['parent']);
_iats_civix_insert_navigation_menu($navMenu, $path, $item);
}
}
}
/**
* Hook_civicrm_buildForm.
* Do a Drupal 7 style thing so we can write smaller functions.
*/
function iats_civicrm_buildForm($formName, &$form) {
$fname = 'iats_civicrm_buildForm_' . $formName;
if (function_exists($fname)) {
// CRM_Core_Error::debug_var('overridden formName',$formName);
$fname($form);
}
// Else echo $fname;.
}
/**
*
*/
function iats_civicrm_pageRun(&$page) {
$fname = 'iats_civicrm_pageRun_' . $page->getVar('_name');
if (function_exists($fname)) {
$fname($page);
}
}
/**
* Modify the recurring contribution (subscription) page.
* Display extra information about recurring contributions using iATS, and
* link to iATS CustomerLink display and editing pages.
*/
function iats_civicrm_pageRun_CRM_Contribute_Page_ContributionRecur($page) {
// Get the corresponding (most recently created) iATS customer code record
// we'll also get the expiry date and last four digits (at least, our best information about that).
$extra = array();
$crid = CRM_Utils_Request::retrieve('id', 'Integer', $page, FALSE);
try {
$recur = civicrm_api3('ContributionRecur', 'getsingle', array('id' => $crid));
}
catch (CiviCRM_API3_Exception $e) {
return;
}
$type = _iats_civicrm_is_iats($recur['payment_processor_id']);
if (!$type || empty($recur['payment_token_id'])) {
return;
}
try {
$payment_token = civicrm_api3('PaymentToken', 'getsingle', [
'id' => $recur['payment_token_id'],
]);
$customer_code = $payment_token['token'];
$extra['iATS Customer Code'] = $customer_code;
$customerLinkView = CRM_Utils_System::url('civicrm/contact/view/iatscustomerlink',
'reset=1&cid=' . $recur['contact_id'] . '&customerCode=' . $customer_code . '&paymentProcessorId=' . $recur['payment_processor_id'] . '&is_test=' . $recur['is_test']);
$extra['customerLink'] = "<a href='$customerLinkView'>View</a>";
if ($type == 'iATSService' || $type == 'iATSServiceSWIPE') {
$customerLinkEdit = CRM_Utils_System::url('civicrm/contact/edit/iatscustomerlink',
'reset=1&cid=' . $recur['contact_id'] . '&customerCode=' . $customer_code . '&paymentProcessorId=' . $recur['payment_processor_id'] . '&is_test=' . $recur['is_test']);
$extra['customerLink'] .= " | <a href='$customerLinkEdit'>Edit</a>";
$processLink = CRM_Utils_System::url('civicrm/contact/iatsprocesslink',
'reset=1&cid=' . $recur['contact_id'] . '&customerCode=' . $customer_code . '&paymentProcessorId=' . $recur['payment_processor_id'] . '&crid=' . $crid . '&is_test=' . $recur['is_test']);
$extra['customerLink'] .= " | <a href='$processLink'>Process</a>";
$expiry = str_split($dao->expiry, 2);
$extra['expiry'] = '20' . implode('-', $expiry);
}
}
catch (CiviCRM_API3_Exception $e) {
return;
}
if (!count($extra)) {
return;
}
$template = CRM_Core_Smarty::singleton();
foreach ($extra as $key => $value) {
$template->assign($key, $value);
}
CRM_Core_Region::instance('page-body')->add(array(
'template' => 'CRM/Iats/ContributionRecur.tpl',
));
CRM_Core_Resources::singleton()->addScriptFile('com.iatspayments.civicrm', 'js/subscription_view.js');
}
/**
* Hook_civicrm_merge
* Deal with contact merges - our custom iats customer code table contains contact id's as a check, it might need to be updated.
*/
function iats_civicrm_merge($type, &$data, $mainId = NULL, $otherId = NULL, $tables = NULL) {
if ('cidRefs' == $type) {
$data['civicrm_iats_customer_codes'] = array('cid');
$data['civicrm_iats_verify'] = array('cid');
}
}
/**
* Hook_civicrm_pre.
*
* Handle special cases of creating contribution (regular and recurring) records when using IATS Payments.
*
* 1. CiviCRM assumes all recurring contributions need to be confirmed using the IPN mechanism. This is not true for iATS recurring contributions.
* So when creating a contribution that is part of a recurring series, test for status = 2, and set to status = 1 instead, unless we're using the fixed day feature
* Do this only for the initial contribution record.
* The (subsequent) recurring contributions' status id is set explicitly in the job that creates it, this modification breaks that process.
*
* 2. For ACH/EFT, we also have the opposite problem - all contributions will need to verified by iATS and only later set to status success or
* failed via the acheft verify job. We also want to modify the payment instrument from CC to ACH/EFT
*
* TODO: update this code with constants for the various id values of 1 and 2.
* TODO: CiviCRM should have nicer ways to handle this.
*/
function iats_civicrm_pre($op, $objectName, $objectId, &$params) {
// Since this function gets called a lot, quickly determine if I care about the record being created.
if (('create' == $op) && ('Contribution' == $objectName) && !empty($params['contribution_status_id'])) {
// watchdog('iats_civicrm','hook_civicrm_pre for Contribution <pre>@params</pre>',array('@params' => print_r($params));
// figure out the payment processor id, not nice.
$version = CRM_Utils_System::version();
$payment_processor_id = !empty($params['payment_processor']) ? $params['payment_processor'] :
(!empty($params['contribution_recur_id']) ? _iats_civicrm_get_payment_processor_id($params['contribution_recur_id']) :
0);
if ($type = _iats_civicrm_is_iats($payment_processor_id)) {
$settings = CRM_Core_BAO_Setting::getItem('iATS Payments Extension', 'iats_settings');
$allow_days = empty($settings['days']) ? array('-1') : $settings['days'];
switch ($type . $objectName) {
// Cc contribution, test if it's been set to status 2 on a recurring contribution.
case 'iATSServiceContribution':
case 'iATSServiceSWIPEContribution':
// For civi version before 4.6.6, we had to force the status to 1.
if ((2 == $params['contribution_status_id'])
&& !empty($params['contribution_recur_id'])
&& (max($allow_days) <= 0)
&& (version_compare($version, '4.6.6') < 0)
) {
// But only for the first one.
$count = civicrm_api3('Contribution', 'getcount', array('contribution_recur_id' => $params['contribution_recur_id']));
if (
(is_array($count) && empty($count['result']))
|| empty($count)
) {
// watchdog('iats_civicrm','hook_civicrm_pre updating status_id for objectName @id, count <pre>!count</pre>, params <pre>!params</pre>, ',array('@id' => $objectName, '!count' => print_r($count,TRUE),'!params' => print_r($params,TRUE)));.
$params['contribution_status_id'] = 1;
}
}
break;
case 'iATSServiceACHEFTContribution':
// ach/eft contribution: update the payment instrument if it's still showing cc or empty
if ($params['payment_instrument_id'] <= 1) {
$params['payment_instrument_id'] = 2;
}
// And push the status to 2 if civicrm thinks it's 1, i.e. for one-time contributions
// in other words, never create ach/eft contributions as complete, always push back to pending and verify.
if ($params['contribution_status_id'] == 1) {
$params['contribution_status_id'] = 2;
}
break;
}
}
// watchdog('iats_civicrm','ignoring hook_civicrm_pre for objectName @id',array('@id' => $objectName));.
}
// If I've set fixed monthly recurring dates, force any iats (non uk dd) recurring contribution schedule records to comply.
if (('ContributionRecur' == $objectName) && ('create' == $op || 'edit' == $op) && !empty($params['payment_processor_id'])) {
if ($type = _iats_civicrm_is_iats($params['payment_processor_id'])) {
if (!empty($params['next_sched_contribution_date'])) {
$settings = CRM_Core_BAO_Setting::getItem('iATS Payments Extension', 'iats_settings');
$allow_days = empty($settings['days']) ? array('-1') : $settings['days'];
// Force one of the fixed days, and set the cycle_day at the same time.
if (0 < max($allow_days)) {
$init_time = ('create' == $op) ? time() : strtotime($params['next_sched_contribution_date']);
$from_time = CRM_Iats_Transaction::contributionrecur_next($init_time, $allow_days);
$params['next_sched_contribution_date'] = date('YmdHis', $from_time);
// Day of month without leading 0.
$params['cycle_day'] = date('j', $from_time);
}
}
// Fix a civi bug while I'm here.
if (empty($params['installments'])) {
$params['installments'] = '0';
}
}
}
}
function iats_get_setting($key = NULL) {
static $settings;
if (empty($settings)) {
$settings = CRM_Core_BAO_Setting::getItem('iATS Payments Extension', 'iats_settings');
}
return empty($key) ? $settings : (isset($settings[$key]) ? $settings[$key] : '');
}
/**
* The contribution itself doesn't tell you which payment processor it came from
* So we have to dig back via the contribution_recur_id that it is associated with.
*/
function _iats_civicrm_get_payment_processor_id($contribution_recur_id) {
$params = array(
'id' => $contribution_recur_id,
);
try {
$result = civicrm_api3('ContributionRecur', 'getsingle', $params);
}
catch (CiviCRM_API3_Exception $e) {
return FALSE;
}
if (empty($result['payment_processor_id'])) {
return FALSE;
// TODO: log error.
}
return $result['payment_processor_id'];
}
/**
* Utility function to see if a payment processor id is using one of the iATS payment processors.
*
* This function relies on our naming convention for the iats payment processor classes, staring with the string Payment_iATSService.
*/
function _iats_civicrm_is_iats($payment_processor_id) {
if (empty($payment_processor_id)) {
return FALSE;
}
$params = array(
'id' => $payment_processor_id,
);
try {
$result = civicrm_api3('PaymentProcessor', 'getsingle', $params);
}
catch (CiviCRM_API3_Exception $e) {
return FALSE;
}
if (empty($result['class_name'])) {
return FALSE;
// TODO: log error.
}
$type = substr($result['class_name'], 0, 19);
$subtype = substr($result['class_name'], 19);
return ('Payment_iATSService' == $type) ? 'iATSService' . $subtype : FALSE;
}
/**
* Internal utility function: return the id's of any iATS processors matching various conditions.
*
* class: the payment object class name to match (prefixed w/ 'Payment_')
* processors: an array of payment processors indexed by id to filter by
* params: an array of additional params to pass to the api call.
*/
function _iats_filter_payment_processors($class, $processors = array(), $params = array()) {
$list = array();
$params['class_name'] = ['LIKE' => 'Payment_' . $class];
// Set the domain id if not passed in.
if (!array_key_exists('domain_id', $params)) {
$params['domain_id'] = CRM_Core_Config::domainID();
}
$params['sequential'] = FALSE; // return list indexed by processor id
$result = civicrm_api3('PaymentProcessor', 'get', $params);
if (0 == $result['is_error'] && count($result['values']) > 0) {
$list = (0 < count($processors)) ? array_intersect_key($result['values'], $processors) : $result['values'];
}
return $list;
}
/**
* Internal utility function: return a list of the payment processors attached
* to a contribution form of variable class
* */
function _iats_get_form_payment_processors($form) {
$form_class = get_class($form);
if ($form_class == 'CRM_Financial_Form_Payment') {
// We're on CRM_Financial_Form_Payment, we've got just one payment processor
$id = $form->_paymentProcessor['id'];
return array($id => $form->_paymentProcessor);
}
else {
// Handle the legacy: event and contribution page forms
if (empty($form->_paymentProcessors)) {
if (empty($form->_paymentProcessorIDs)) {
return;
}
else {
return array_fill_keys($form->_paymentProcessorIDs, 1);
}
}
else {
return $form->_paymentProcessors;
}
}
}
/**
*
*/
function iats_getCurrency($form) {
// getting the currency depends on the form class
$form_class = get_class($form);
$currency = '';
switch($form_class) {
case 'CRM_Contribute_Form_Contribution':
case 'CRM_Contribute_Form_Contribution_Main':
case 'CRM_Member_Form_Membership':
$currency = $form->_values['currency'];
break;
case 'CRM_Financial_Form_Payment':
// This is the new ajax-loaded payment form.
$currency = $form->getCurrency();
break;
case 'CRM_Event_Form_Participant':
case 'CRM_Event_Form_Registration_Register':
$currency = $form->_values['event']['currency'];
break;
}
if (empty($currency)) {
// This may occur in edge cases, so don't break, though the form won't be rendered correctly.
// See comment on civicrm core commit f61437d
CRM_Core_Error::debug_var($form_class, $form);
}
return $currency;
}
/**
* Provide helpful links to backend-ish payment pages for ACH/EFT, since the backend credit card pages don't work/apply
* Could do the same for swipe?
*/
function iats_civicrm_buildForm_CRM_Contribute_Form_Search(&$form) {
// Ignore invocations that aren't for a specific contact, e.g. the civicontribute dashboard.
if (empty($form->_defaultValues['contact_id'])) {
return;
}
$contactID = $form->_defaultValues['contact_id'];
$acheft = _iats_filter_payment_processors('iATSServiceACHEFT', array(), array('is_active' => 1, 'is_test' => 0));
$acheft_backoffice_links = array();
// For each ACH/EFT payment processor, try to provide a different mechanism for 'backoffice' type contributions
// note: only offer payment pages that provide iATS ACH/EFT exclusively.
foreach (array_keys($acheft) as $pp_id) {
$params = array('is_active' => 1, 'payment_processor' => $pp_id);
$result = civicrm_api3('ContributionPage', 'get', $params);
if (0 == $result['is_error'] && count($result['values']) > 0) {
foreach ($result['values'] as $page) {
$url = CRM_Utils_System::url('civicrm/contribute/transact', 'reset=1&cid=' . $contactID . '&id=' . $page['id']);
$acheft_backoffice_links[] = array('url' => $url, 'title' => $page['title']);
}
}
}
if (count($acheft_backoffice_links)) {
CRM_Core_Resources::singleton()->addVars('iatspayments', array('backofficeLinks' => $acheft_backoffice_links));
CRM_Core_Resources::singleton()->addScriptFile('com.iatspayments.civicrm', 'js/contribute_form_search.js');
}
}
/**
* If this recurring contribution sequence is using an iATS payment processor,
* modify the recurring contribution cancelation form to exclude the confusing message about sending the request to the backend.
*/
function iats_civicrm_buildForm_CRM_Contribute_Form_CancelSubscription(&$form) {
$crid = CRM_Utils_Request::retrieve('crid', 'Integer', $form, FALSE);
try {
$recur = civicrm_api3('ContributionRecur', 'getsingle', array('id' => $crid));
}
catch (CiviCRM_API3_Exception $e) {
return;
}
if (_iats_civicrm_is_iats($recur['payment_processor_id'])) {
if ($form->elementExists('send_cancel_request')) {
$form->removeElement('send_cancel_request');
}
}
}
/**
* Add some functionality to the update subscription form for recurring contributions.
*/
function iats_civicrm_buildForm_CRM_Contribute_Form_UpdateSubscription(&$form) {
/* For 4.7, we implement getEditableRecurringScheduleFields but still need this for additional niceness */
// Only do this if the user is allowed to edit contributions. A more stringent permission might be smart.
if (!CRM_Core_Permission::check('edit contributions')) {
return;
}
// Only mangle this form for recurring contributions using iATS
$payment_processor_type = empty($form->_paymentProcessor) ? substr(get_class($form->_paymentProcessorObj),9) : $form->_paymentProcessor['class_name'];
if ( (0 !== strpos($payment_processor_type, 'Payment_iATSService'))
&& (0 !== strpos($payment_processor_type, 'Payment_Faps')) ){
return;
}
$settings = civicrm_api3('Setting', 'getvalue', array('name' => 'iats_settings'));
// don't do this if the site administrator has disabled it.
if (!empty($settings['no_edit_extra'])) {
return;
}
$allow_days = empty($settings['days']) ? array('-1') : $settings['days'];
if (0 < max($allow_days)) {
$userAlert = ts('Your next scheduled contribution date will automatically be updated to the next allowable day of the month: %1',
array(1 => implode(', ', $allow_days)));
CRM_Core_Session::setStatus($userAlert, ts('Warning'), 'alert');
}
$crid = CRM_Utils_Request::retrieve('crid', 'Integer', $form, FALSE);
/* get the recurring contribution record and the contact record, or quit */
try {
$recur = civicrm_api3('ContributionRecur', 'getsingle', array('id' => $crid));
}
catch (CiviCRM_API3_Exception $e) {
return;
}
try {
$contact = civicrm_api3('Contact', 'getsingle', array('id' => $recur['contact_id']));
}
catch (CiviCRM_API3_Exception $e) {
return;
}
try {
$pp = civicrm_api3('PaymentProcessor', 'getsingle', array('id' => $recur['payment_processor_id']));
}
catch (CiviCRM_API3_Exception $e) {
$pp = array();
}
// Turn off default notification checkbox, because that's a better default.
$defaults = array('is_notify' => 0);
$edit_fields = array(
'contribution_status_id' => 'Status',
'next_sched_contribution_date' => 'Next Scheduled Contribution',
'start_date' => 'Start Date',
'is_email_receipt' => 'Email receipt for each Contribution in this Recurring Series',
);
$dupe_fields = array();
// To be a good citizen, I check if core or another extension hasn't already added these fields
// and don't add them again if they have.
foreach (array_keys($edit_fields) as $fid) {
if ($form->elementExists($fid)) {
unset($edit_fields[$fid]);
$dupe_fields[] = str_replace('_','-',$fid);
}
elseif (isset($recur[$fid])) {
$defaults[$fid] = $recur[$fid];
}
}
// Use this in my js to identify which fields need to be removed from the tpl I inject below
CRM_Core_Resources::singleton()->addVars('iatspayments', array('dupeSubscriptionFields' => $dupe_fields));
foreach ($edit_fields as $fid => $label) {
switch($fid) {
case 'contribution_status_id':
$contributionStatus = CRM_Contribute_PseudoConstant::contributionStatus(NULL, 'name');
$form->addElement('select', 'contribution_status_id', ts('Status'), $contributionStatus);
break;
case 'is_email_receipt':
$receiptStatus = array('0' => 'No', '1' => 'Yes');
$form->addElement('select', $fid, ts($label), $receiptStatus);
break;
default:
$form->addDateTime($fid, ts($label));
break;
}
}
$form->setDefaults($defaults);
// Now add some more fields for display only
/* Add in the contact's name */
$form->addElement('static', 'contact', $contact['display_name']);
// get my pp, if available.
$pp_label = empty($pp['name']) ? $form->_paymentProcessor['name'] : $pp['name'];
$form->addElement('static', 'payment_processor', $pp_label);
$label = CRM_Contribute_Pseudoconstant::financialType($recur['financial_type_id']);
$form->addElement('static', 'financial_type', $label);
$labels = CRM_Contribute_Pseudoconstant::paymentInstrument();
$label = $labels[$recur['payment_instrument_id']];
$form->addElement('static', 'payment_instrument', $label);
$form->addElement('static', 'failure_count', $recur['failure_count']);
CRM_Core_Region::instance('page-body')->add(array(
'template' => 'CRM/Iats/Subscription.tpl',
));
CRM_Core_Resources::singleton()->addScriptFile('com.iatspayments.civicrm', 'js/subscription.js');
}
function iats_civicrm_buildForm_CRM_Contribute_Form_UpdateBilling(&$form) {
// add hidden form field for the contribution recur ID taken from URL
// if not specified directly, look it up via a membership ID
$crid = CRM_Utils_Array::value('crid', $_GET);
if (!$crid) {
$mid = CRM_Utils_Array::value('mid', $_GET);
if ($mid) {
try {
$crid = civicrm_api3('Membership', 'getvalue', array(
'id' => $mid,
'return' => 'contribution_recur_id',
));
}
catch (CiviCRM_API3_Exception $e) {
$crid = 0;
}
}
}
if ($crid) {
$form->addElement('hidden', 'crid', $crid);
}
}
You can’t perform that action at this time.