Skip to content
Snippets Groups Projects
Commit 3c4b9a85 authored by mattwire's avatar mattwire
Browse files

Drupal Webform: Re-enable hook_civicrm_buildForm and comment in different...

Drupal Webform: Re-enable hook_civicrm_buildForm and comment in different situations we need alterContent and buildForm to load js scripts
parent 52efe677
Branches
Tags
No related merge requests found
......@@ -879,10 +879,12 @@ class CRM_Core_Payment_Stripe extends CRM_Core_Payment {
* @param array $errors
*/
public function validatePaymentInstrument($values, &$errors) {
CRM_Core_Form::validateMandatoryFields($this->getMandatoryFields(), $values, $errors);
// Use $_POST here and not $values - for webform fields are not set in $values, but are in $_POST
CRM_Core_Form::validateMandatoryFields($this->getMandatoryFields(), $_POST, $errors);
if ($this->_paymentProcessor['payment_type'] == 1) {
// Don't validate credit card details as they are not passed (and stripe does this for us)
//CRM_Core_Payment_Form::validateCreditCard($values, $errors, $this->_paymentProcessor['id']);
}
}
}
......@@ -70,7 +70,9 @@ rgburton, Swingline0, BorislavZlatanov, agh1, & jmcclelland
TESTING
--------
1. Test webform submission with payment and user-select, single processor.
2. Test online contribution page with single processor, multi-processor (stripe default, stripe non-default).
3. Test offline contribution page with single processor, multi-processor (stripe default, stripe non-default).
4. Test event registration.
5. Test event registration (cart checkout).
1. Test online contribution page with single processor, multi-processor (stripe default, stripe non-default).
1. Test offline contribution page with single processor, multi-processor (stripe default, stripe non-default).
1. Test event registration.
1. Test event registration (cart checkout).
1. Test offline event registration.
1. Test offline membership.
......@@ -4,8 +4,6 @@
*/
(function($, CRM) {
var buttonText;
// Response from Stripe.createToken.
function stripeResponseHandler(status, response) {
$form = getBillingForm();
......@@ -18,7 +16,7 @@
$(".messages.crm-error.stripe-message").slideUp();
$(".messages.crm-error.stripe-message:first").remove();
}
$form.prepend('<div class="messages crm-error stripe-message">'
$form.prepend('<div class="messages alert alert-block alert-danger error crm-error stripe-message">'
+ '<strong>Payment Error Response:</strong>'
+ '<ul id="errorList">'
+ '<li>Error: ' + response.error.message + '</li>'
......@@ -26,7 +24,7 @@
+ '</div>');
$form.data('submitted', false);
$submit.prop('disabled', false).attr('value', buttonText);
$submit.prop('disabled', false);
}
else {
var token = response['id'];
......@@ -75,27 +73,52 @@
return;
}
$submit = getBillingSubmit();
// If another submit button on the form is pressed (eg. apply discount)
// add a flag that we can set to stop payment submission
$form.data('submit-dont-process', '0');
// Find submit buttons which should not submit payment
$form.find('[type="submit"][formnovalidate="1"], ' +
'[type="submit"][formnovalidate="formnovalidate"], ' +
'[type="submit"].cancel, ' +
'[type="submit"].webform-previous').click( function() {
debugging('adding submit-dont-process');
$form.data('submit-dont-process', 1);
});
$submit.click( function() {
debugging('clearing submit-dont-process');
$form.data('submit-dont-process', 0);
});
// Add a keypress handler to set flag if enter is pressed
$form.find('input#discountcode').keypress( function(e) {
if (e.which === 13) {
$form.data('submit-dont-process', 1);
}
});
var isWebform = getIsWebform();
// For CiviCRM Webforms.
if (isWebform) {
// We need the action field for back/submit to work and redirect properly after submission
if (!($('#action').length)) {
$form.append('<input type="hidden" name="op" id="action" />');
$form.append($('<input type="hidden" name="op" id="action" />'));
}
$(document).keypress(function(event) {
var $actions = $form.find('[type=submit]');
$('[type=submit]').click(function() {
$('#action').val(this.value);
});
// If enter pressed, use our submit function
$form.keypress(function(event) {
if (event.which === 13) {
// Enter was pressed
event.preventDefault();
$('#action').val(this.value);
submit(event);
}
});
$(":submit").click(function() {
$('#action').val(this.value);
});
$('#billingcheckbox:input').hide();
$('label[for="billingcheckbox"]').hide();
var webformPrevious = $('input.webform-previous').first().val();
}
else {
// As we use credit_card_number to pass token, make sure it is empty when shown
......@@ -103,32 +126,21 @@
$form.find("input#cvv2").val('');
}
$submit.removeAttr('onclick');
$form.unbind('submit');
// Intercept form submission.
$form.on('submit', function(event) {
submit(event);
submit(event);
});
function submit(event) {
event.preventDefault();
debugging('submit handler');
$form = getBillingForm();
if ($form.data('submitted') === true) {
// Previously submitted - don't submit again
alert('Form already submitted. Please wait.');
return true;
} else {
// Mark it so that the next submit can be ignored
// ADDED requirement that form be valid
if($form.valid()) {
$form.data('submitted', true);
}
debugging('form already submitted');
return false;
}
$submit = getBillingSubmit();
var isWebform = getIsWebform();
$form = getBillingForm();
// Don't handle submits generated by non-stripe processors
if (!$('input#stripe-pub-key').length) {
......@@ -136,20 +148,21 @@
return true;
}
// Don't handle submits generated by the CiviDiscount button.
if ($form.data('submit-dont-process') === 1) {
debugging('Discount is in play');
if ($form.data('submit-dont-process')) {
debugging('non-payment submit detected - not submitting payment');
$form.get(0).submit();
return true;
}
$submit = getBillingSubmit();
var isWebform = getIsWebform();
if (isWebform) {
var $processorFields = $('.civicrm-enabled[name$="civicrm_1_contribution_1_contribution_payment_processor_id]"]');
if ($('#action').attr('value') === webformPrevious) {
// Don't submit if the webform back button was pressed
debugging('webform back button');
return true;
}
if ($('#wf-crm-billing-total').length) {
if ($('#wf-crm-billing-total').data('data-amount') === '0') {
$totalElement = $('#wf-crm-billing-total');
if ($totalElement.length) {
if ($totalElement.data('data-amount') === '0') {
debugging('webform total is 0');
return true;
}
......@@ -161,9 +174,22 @@
}
}
}
// Disable the submit button to prevent repeated clicks, cache button text, restore if Stripe returns error
buttonText = $submit.attr('value');
$submit.prop('disabled', true).attr('value', 'Processing');
// Lock to prevent multiple submissions
if ($form.data('submitted') === true) {
// Previously submitted - don't submit again
alert('Form already submitted. Please wait.');
return true;
} else {
// Mark it so that the next submit can be ignored
// ADDED requirement that form be valid
if($form.valid()) {
$form.data('submitted', true);
}
}
// Disable the submit button to prevent repeated clicks
$submit.prop('disabled', true);
// Handle multiple payment options and Stripe not being chosen.
if ($form.find(".crm-section.payment_processor-section").length > 0) {
......@@ -206,16 +232,11 @@
}
function getIsWebform() {
if ($('.webform-client-form').length) {
return true;
}
else {
return false;
}
return $('.webform-client-form').length;
}
function getBillingForm() {
return CRM.$('input#stripe-pub-key').closest('form');
return $('input#stripe-pub-key').closest('form');
}
function getBillingSubmit() {
......@@ -223,24 +244,10 @@
var isWebform = getIsWebform();
if (isWebform) {
$submit = $form.find('.button-primary');
$submit = $form.find('[type="submit"].webform-submit');
}
else {
$submit = $form.find('input[type="submit"].validate');
// If another submit button on the form is pressed (eg. apply discount)
// add a flag that we can set to stop payment submission
$form.data('submit-dont-process', '0');
// Find submit buttons with formnovalidate=1 and add an onclick handler to set flag
$form.find('input[type="submit"][formnovalidate="1"], input[type="submit"].cancel').click( function() {
$form.data('submit-dont-process', 1);
});
// Add a keypress handler to set flag if enter is pressed
$form.find('input#discountcode').keypress( function(e) {
if (e.which === 13) {
$form.data('submit-dont-process', 1);
}
});
$submit = $form.find('[type="submit"].validate');
}
return $submit;
}
......
......@@ -188,16 +188,56 @@ function stripe_civicrm_managed(&$entities) {
}
}
// Flag so we don't add the stripe scripts more than once.
static $_stripe_scripts_added;
/**
* Implementation of hook_civicrm_alterContent
*
* Adding civicrm_stripe.js in a way that works for webforms and (some) Civi forms.
* hook_civicrm_buildForm is not called for webforms
*
* @return void
*/
function stripe_civicrm_alterContent( &$content, $context, $tplName, &$object ) {
global $_stripe_scripts_added;
/* Adding stripe js:
* - Webforms don't get scripts added by hook_civicrm_buildForm so we have to user alterContent
* - (Webforms still call buildForm and it looks like they are added but they are not,
* which is why we check for $object instanceof CRM_Financial_Form_Payment here to ensure that
* Webforms always have scripts added).
* - Almost all forms have context = 'form' and a paymentprocessor object.
* - Membership backend form is a 'page' and has a _isPaymentProcessor=true flag.
*
*/
if (($context == 'form' && !empty($object->_paymentProcessor['class_name']))
|| (($context == 'page') && !empty($object->_isPaymentProcessor))) {
if (!$_stripe_scripts_added || $object instanceof CRM_Financial_Form_Payment) {
$stripeJSURL = CRM_Core_Resources::singleton()
->getUrl('com.drastikbydesign.stripe', 'js/civicrm_stripe.js');
$content .= "<script src='{$stripeJSURL}'></script>";
$content .= "<script src='https://js.stripe.com/v2/'></script>";
$_stripe_scripts_added = TRUE;
}
}
}
/**
* Add stripe.js to forms, to generate stripe token
* hook_civicrm_alterContent is not called for all forms (eg. CRM_Contribute_Form_Contribution on backend)
* @param $formName
* @param $form
*/
function stripe_civicrm_buildForm($formName, &$form) {
global $_stripe_scripts_added;
if (!empty($form->_paymentProcessor['class_name'])) {
// civicrm_stripe.js is not included on backend form renewal unless we add it here.
CRM_Core_Resources::singleton()->addScriptUrl('https://js.stripe.com/v2/', 10, 'page-body');
CRM_Core_Resources::singleton()->addScriptFile('com.drastikbydesign.stripe', 'js/civicrm_stripe.js');
if (!$_stripe_scripts_added) {
CRM_Core_Resources::singleton()
->addScriptUrl('https://js.stripe.com/v2/', 10, 'page-body');
CRM_Core_Resources::singleton()
->addScriptFile('com.drastikbydesign.stripe', 'js/civicrm_stripe.js');
}
$_stripe_scripts_added = TRUE;
}
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment