From 38621a92424f76ca99471b4885e1bcaf028b1b27 Mon Sep 17 00:00:00 2001 From: Peter Hartmann <peter@hartmanncomputer.com> Date: Thu, 9 Mar 2017 03:43:37 -0500 Subject: [PATCH] put #155 to bed, extend Core Form --- CRM/Core/Form/Stripe.php | 16 +++++ CRM/Core/Payment/Stripe.php | 113 +++++++++++++++--------------------- js/civicrm_stripe.js | 38 ++++++------ stripe.php | 30 +++++----- 4 files changed, 98 insertions(+), 99 deletions(-) create mode 100644 CRM/Core/Form/Stripe.php diff --git a/CRM/Core/Form/Stripe.php b/CRM/Core/Form/Stripe.php new file mode 100644 index 00000000..828e2ea5 --- /dev/null +++ b/CRM/Core/Form/Stripe.php @@ -0,0 +1,16 @@ +<?php + +/* + * Form Class for Stripe + */ + +class CRM_Core_Form_Stripe extends CRM_Core_Form { + + /** + * Function to access protected payProcessors array in event registraion forms + */ + public static function get_ppids(&$form) { + $payprocessorIds = $form->_paymentProcessors; + return $payprocessorIds; + } +} diff --git a/CRM/Core/Payment/Stripe.php b/CRM/Core/Payment/Stripe.php index f7e2214d..68c5407d 100644 --- a/CRM/Core/Payment/Stripe.php +++ b/CRM/Core/Payment/Stripe.php @@ -231,30 +231,20 @@ class CRM_Core_Payment_Stripe extends CRM_Core_Payment { return $return; } - /** - * Implementation of hook_civicrm_validateForm(). - * - * Prevent server validation of cc fields - * - * @param $formName - the name of the form - * @param $fields - Array of name value pairs for all 'POST'ed form values - * @param $files - Array of file properties as sent by PHP POST protocol - * @param $form - reference to the form object - * @param $errors - Reference to the errors array. - * - */ - /** * Implementation of hook_civicrm_buildForm(). * * @param $form - reference to the form object */ public function buildForm(&$form) { - $stripe_key = self::stripe_get_key($form); - // If this is not a form Stripe is involved in, do nothing. - if (empty($stripe_key)) { - return; - } + $stripe_ppid = self::get_stripe_ppid($form); + + // Add the ID to our form so our js can tell if Stripe has been selected. + $form->addElement('hidden', 'stripe_id', $stripe_ppid, array('id' => 'stripe-id')); + + $stripe_key = self::stripe_get_key($stripe_ppid); + $form->addElement('hidden', 'stripe_pub_key', $stripe_key, array('id' => 'stripe-pub-key')); + $params = $form->get('params'); // Contrib forms store this in $params, Event forms in $params[0]. if (!empty($params[0]['stripe_token'])) { @@ -267,7 +257,15 @@ class CRM_Core_Payment_Stripe extends CRM_Core_Payment { $form->setAttribute('class', $form->getAttribute('class') . ' stripe-payment-form'); $form->addElement('hidden', 'stripe_token', $stripe_token, array('id' => 'stripe-token')); } - self::stripe_add_stripe_js($stripe_key, $form); + + // Add the Civi version so we can accommodate different versions in civicrm_stripe.js. + if (self::get_civi_version() <= '4.7.0') { + $ext_mode = 1; + } + else { + $ext_mode = 2; + } + $form->addElement('hidden', 'ext_mode', $ext_mode, array('id' => 'ext-mode')); // Add email field as it would usually be found on donation forms. if (!isset($form->_elementIndex['email']) && !empty($form->userEmail)) { @@ -275,74 +273,59 @@ class CRM_Core_Payment_Stripe extends CRM_Core_Payment { } } - /** - * Return the stripe api public key (aka password) - * - * If this form could conceiveably now or at any time in the future - * contain a Stripe payment processor, return the api public key for - * that processor. - */ - public static function stripe_get_key($form) { + public static function get_stripe_ppid($form) { if (empty($form->_paymentProcessor)) { return; } - // Only return first value if Stripe is the only/default. - if ($form->_paymentProcessor['payment_processor_type'] == 'Stripe') { - if (isset($form->_paymentProcessor['password'])) { - return $form->_paymentProcessor['password']; - } + // Determine if we are dealing with a webform in CiviCRM 4.7. Those don't have a + // _paymentProcessors array and only have one payprocesssor. + if (get_class($form) == 'CRM_Financial_Form_Payment') { + return $stripe_ppid = $form->_paymentProcessor['id']; } - - // Otherwise we need to look through all active payprocs and find Stripe. - $is_test = 0; - if (isset($form->_mode)) { - $is_test = $form->_mode == 'live' ? 0 : 1; - } - - // The _paymentProcessors array seems to be the most reliable way to find - // if the form is using Stripe. - if (!empty($form->_paymentProcessors)) { - foreach ($form->_paymentProcessors as $pp) { - if ($pp['payment_processor_type'] == 'Stripe') { - if (!empty($pp['password'])) { - return $pp['password']; - } - // We have a match. - return self::stripe_get_key_for_name($pp['name'], $is_test); + else { + // Find a Stripe pay processor ascociated with this Civi form and find the ID. + // $payProcessors = $form->_paymentProcessors; + $payProcessors = CRM_Core_Form_Stripe::get_ppids($form); + foreach ($payProcessors as $payProcessor) { + if ($payProcessor['class_name'] == 'Payment_Stripe') { + return $stripe_ppid = $payProcessor['id']; + break; } } } - // Return NULL if this is not a form with Stripe involved. - return NULL; + // None of the payprocessors are Stripe. + if (empty($stripe_ppid)) { + return; + } } /** - * Given a payment processor name, return the pub key. + * Given a payment processor id, return the pub key. */ - public function stripe_get_key_for_name($name, $is_test) { + public function stripe_get_key($stripe_ppid) { try { - $params = array('name' => $name, 'is_test' => $is_test); - $results = civicrm_api3('PaymentProcessor', 'get', $params); - if ($results['count'] == 1) { - $result = array_pop($results['values']); - return $result['password']; - } + $result = civicrm_api3('PaymentProcessor', 'getvalue', array( + 'return' => "password", + 'id' => $stripe_ppid, + )); } catch (CiviCRM_API3_Exception $e) { return NULL; } + return $result; } /** - * Add publishable key and event bindings for Stripe.js. + * Return the CiviCRM version we're running. */ - public function stripe_add_stripe_js($stripe_key, $form) { - $form->addElement('hidden', 'stripe_pub_key', $stripe_key, array('id' => 'stripe-pub-key')); - CRM_Core_Resources::singleton()->addScriptFile('com.drastikbydesign.stripe', 'js/civicrm_stripe.js', 0); + public function get_civi_version() { + $version = civicrm_api3('Domain', 'getvalue', array( + 'return' => "version", + 'current_domain' => true, + )); + return $version; } - - /** * Submit a payment using Stripe's PHP API: * https://stripe.com/docs/api?lang=php diff --git a/js/civicrm_stripe.js b/js/civicrm_stripe.js index d7185161..a18bf887 100644 --- a/js/civicrm_stripe.js +++ b/js/civicrm_stripe.js @@ -117,7 +117,7 @@ $form.submit(function (event) { // Don't handle submits generated by the CiviDiscount button. if ($form.data('cividiscount-dont-handle') == 1) { - debugging('pvjwy'); + debugging('debug: pvjwy (Discount is in play)'); return true; } if (isWebform) { @@ -156,47 +156,45 @@ if (currentTotal == 0 && !additionalParticipants) { // This is also hit when "Going back", but we already have stripe_token. debugging('ozlkf'); - return true; + // This should not happen on Confirm Contribution, but seems to on 4.6 for some reason. + //return true; } } } // Handle multiple payment options and Stripe not being chosen. if ($form.find(".crm-section.payment_processor-section").length > 0) { + var extMode = $('#ext-mode').val(); + var stripeProcessorId = $('#stripe-id').val(); // Support for CiviCRM 4.6 and 4.7 multiple payment options - if (($form.find('input[name="payment_processor"]:checked').length) || ($form.find('input[name="payment_processor_id"]:checked').length)) { - processorId = $form.find(('input[name="payment_processor"]:checked')||('input[name="payment_processor_id"]:checked').val()); - if (!($form.find('input[name="stripe_token"]').length) || ($('#stripe-id').length && $('#stripe-id').val() != processorId)) { - debugging('kfoej'); - return true; - } + if (extMode == 1) { + var chosenProcessorId = $form.find('input[name="payment_processor"]:checked').val(); + } + else if (extMode == 2) { + var chosenProcessorId = $form.find('input[name="payment_processor_id"]:checked').val(); } - else { - // No payment processor is checked. - debugging('qlmvy'); + // Bail if we're not using Stripe or are using pay later (option value '0' in payment_processor radio group). + if ((chosenProcessorId != stripeProcessorId) || (chosenProcessorId == 0)) { + debugging('debug: kfoej (Not a Stripe transaction, or pay-later)'); return true; } } - - // Handle pay later (option value '0' in payment_processor radio group). - if (($form.find('input[name="payment_processor"]:checked').length && !parseInt($form.find('input[name="payment_processor"]:checked').val())) - || ($form.find('input[name="payment_processor_id"]:checked').length && !parseInt($form.find('input[name="payment_processor_id"]:checked').val()))) { - debugging('ynhpz'); - return true; + else { + debugging('debug: qlmvy (Stripe is the only payprocessor here)'); } // Handle reuse of existing token if ($form.find("input#stripe-token").val()) { $form.find("input#credit_card_number").removeAttr('name'); $form.find("input#cvv2").removeAttr('name'); - debugging('zpqef'); + debugging('debug: zpqef (Re-using Stripe token)'); return true; } // If there's no credit card field, no use in continuing (probably wrong // context anyway) if (!$form.find('#credit_card_number').length) { - debugging('gvzod'); + debugging('debug: gvzod (No credit card field)'); return true; } @@ -221,7 +219,7 @@ exp_year: cc_year }, stripeResponseHandler); - debugging('ywkvh'); + debugging('debug: ywkvh (Getting Stripe token)'); return false; }); }); diff --git a/stripe.php b/stripe.php index ccb952df..f7701012 100644 --- a/stripe.php +++ b/stripe.php @@ -170,32 +170,34 @@ function stripe_civicrm_managed(&$entities) { return; } // If Stripe is active here. - if (isset($form->_elementIndex['stripe_token'])) { - if ($form->elementExists('credit_card_number')) { - $cc_field = $form->getElement('credit_card_number'); - $form->removeElement('credit_card_number', true); - $form->addElement($cc_field); - } - if ($form->elementExists('cvv2')) { - $cvv2_field = $form->getElement('cvv2'); - $form->removeElement('cvv2', true); - $form->addElement($cvv2_field); + if ($form->_paymentProcessor['class_name'] == 'Payment_Stripe') { + if (isset($form->_elementIndex['stripe_token'])) { + if ($form->elementExists('credit_card_number')) { + $cc_field = $form->getElement('credit_card_number'); + $form->removeElement('credit_card_number', true); + $form->addElement($cc_field); + } + if ($form->elementExists('cvv2')) { + $cvv2_field = $form->getElement('cvv2'); + $form->removeElement('cvv2', true); + $form->addElement($cvv2_field); + } } + } else { + return; } } /** * Implementation of hook_civicrm_alterContent * + * Adding civicrm_stripe.js in a way that works for webforms and Civi forms. + * * @return void */ function stripe_civicrm_alterContent( &$content, $context, $tplName, &$object ) { if($context == 'form' && !empty($object->_paymentProcessor['class_name'])) { if($object->_paymentProcessor['class_name'] == 'Payment_Stripe') { - $stripe_key = CRM_Core_Payment_Stripe::stripe_get_key($object); - if(empty($stripe_key)) { - return; - } $stripeJSURL = CRM_Core_Resources::singleton()->getUrl('com.drastikbydesign.stripe', 'js/civicrm_stripe.js'); $content .= "<script src='{$stripeJSURL}'></script>"; } -- GitLab