Adamw has submitted this change and it was merged.

Change subject: Wire up the new RapidError form functionality so we can 
actually use it.
......................................................................


Wire up the new RapidError form functionality so we can actually use it.

Change-Id: Id0c81b1dfc07cbf5fb247c145e677465cf732210
---
M gateway_common/DonationData.php
M gateway_common/gateway.adapter.php
M gateway_forms/RapidHtml.php
M special/GatewayFormChooser.php
4 files changed, 172 insertions(+), 9 deletions(-)

Approvals:
  Adamw: Verified; Looks good to me, approved
  jenkins-bot: Verified



diff --git a/gateway_common/DonationData.php b/gateway_common/DonationData.php
index 03b76ae..7339b22 100644
--- a/gateway_common/DonationData.php
+++ b/gateway_common/DonationData.php
@@ -1181,6 +1181,25 @@
        }
 
        /**
+        * Returns an array of field names we need in order to retry a payment
+        * after the session has been destroyed by... overzealousness.
+        */
+       public static function getRetryFields() {
+               $fields = array (
+                       'gateway',
+                       'country',
+                       'currency_code',
+                       'amount',
+                       'language',
+                       'utm_source',
+                       'utm_medium',
+                       'utm_campaign',
+                       'payment_method',
+               );
+               return $fields;
+       }
+
+       /**
         * Basically, this is a wrapper for the $wgRequest wasPosted function 
that 
         * won't give us notices if we weren't even a web request. 
         * I realize this is pretty lame. 
diff --git a/gateway_common/gateway.adapter.php 
b/gateway_common/gateway.adapter.php
index a4bfe2a..2a43ee4 100644
--- a/gateway_common/gateway.adapter.php
+++ b/gateway_common/gateway.adapter.php
@@ -369,6 +369,19 @@
         * @return mixed Page URL in string format, or false if none is set.  
         */
        public function getFailPage() {
+               //Prefer RapidFail.
+               if ( self::getGlobal( "RapidFailPage" ) ) {
+                       $data = $this->getData_Unstaged_Escaped();
+
+                       //choose which fail page to go for.
+                       try {
+                               $fail_ffname = 
GatewayFormChooser::getBestErrorForm( $data['gateway'], 
$data['payment_method'], $data['payment_submethod'] );
+                       } catch ( Exception $e ) {
+                               $this->log( $this->getLogMessagePrefix() . 
"Cannot determine best error form. " . $e->getMessage(), LOG_ERR );
+                       }
+
+                       return GatewayFormChooser::buildPaymentsFormURL( 
$fail_ffname, $this->getRetryData() );
+               }
                $page = self::getGlobal( "FailPage" );
                if ( $page ) {
 
@@ -2866,6 +2879,10 @@
         * $wgDonationInterfaceAllowedHtmlForms
         */
        public function session_pushRapidHTMLForm( $form_key ) {
+               if ( strlen( $form_key ) === 0 ) {
+                       return;
+               }
+
                self::session_ensure();
 
                if ( !is_array( self::session_getData( 'PaymentForms' ) ) ) {
@@ -3037,4 +3054,18 @@
                return $match;
        }
 
+       /**
+        * Retrieve the data we will need in order to retry a payment.
+        * This is useful in the event that we have just killed a session before
+        * the next retry.
+        * @return array Data required for a payment retry.
+        */
+       public function getRetryData() {
+               $params = array ( );
+               foreach ( $this->dataObj->getRetryFields() as $field ) {
+                       $params[$field] = $this->getData_Unstaged_Escaped( 
$field );
+               }
+               return $params;
+       }
+
 }
diff --git a/gateway_forms/RapidHtml.php b/gateway_forms/RapidHtml.php
index 32e8fbb..6cb0369 100644
--- a/gateway_forms/RapidHtml.php
+++ b/gateway_forms/RapidHtml.php
@@ -490,8 +490,19 @@
                        if ( $allowedForms[$form_key]['special_type'] === 
'error' ) {
                                //add data we're going to need for the error 
page!
                                $back_form = 
$this->gateway->session_getLastRapidHTMLForm();
+
+                               //TODO: What to do if $back_form doesn't exist, 
because session expire
+                               //TODO: Also, what to do if they just have... 
no required data.
+
+                               $params = array (
+                                       'gateway' => 
$this->gateway->getIdentifier()
+                               );
+                               if ( !$this->gateway->session_hasDonorData() ) {
+                                       $preserve = 
$this->gateway->getRetryData();
+                                       $params = array_merge( $preserve, 
$params );
+                               }
                                //If this is just the one thing, we might move 
this inside DonationData for clarity's sake...
-                               $this->gateway->addData( array ( 'ffname_retry' 
=> GatewayFormChooser::buildPaymentsFormURL( $back_form ) ) );
+                               $this->gateway->addData( array ( 'ffname_retry' 
=> GatewayFormChooser::buildPaymentsFormURL( $back_form, $params ) ) );
                        }
                } else {
                        //No special type... let's add this to the form stack 
and call it good.
diff --git a/special/GatewayFormChooser.php b/special/GatewayFormChooser.php
index 35940b0..d549543 100644
--- a/special/GatewayFormChooser.php
+++ b/special/GatewayFormChooser.php
@@ -72,9 +72,16 @@
        }
 
        /**
+        * Build a URL to a payments form, with the data that we have.
+        * If we have supplied no form_key, it will build a URL to the form
+        * chooser itself, so we can get a new one that satisfies the
+        * requirements specified in $other_params
         * $other_params will override everything except $form_key (ffname)
-        * @param type $form_key
-        * @param type $other_params
+        * @param string $form_key The ffname we would like to go back to. In
+        * the event that none is supplied, you'll go back to the Form Chooser
+        * to get one.
+        * @param array $other_params An array of any params that DonationData
+        * will harvest and understand.
         */
        static function buildPaymentsFormURL( $form_key, $other_params = array 
( ) ) {
                // And... construct the URL
@@ -90,15 +97,38 @@
 
                $params = array_merge( $params, $other_params );
 
-               $form_info = self::getFormDefinition( $form_key );
+               $rechoose = false;
+               if ( !strlen( $form_key ) ) {
+                       //send them to the form chooser itself.
+                       $rechoose = true;
+               }
 
-               if ( DataValidator::value_appears_in( 'redirect', $form_info ) 
) {
-                       $params['redirect'] = '1';
+               $specialpage = '';
+               if ( $rechoose ) {
+                       $specialpage = 'GatewayFormChooser';
+               } else {
+                       $form_info = self::getFormDefinition( $form_key );
+
+                       if ( DataValidator::value_appears_in( 'redirect', 
$form_info ) ) {
+                               $params['redirect'] = '1';
+                       }
+
+                       //support for multi-gateway forms, and error forms
+                       $gateway = $form_info['gateway'];
+
+                       if ( is_array( $gateway ) ) {
+                               if ( array_key_exists( 'gateway', $params ) && 
in_array( $params['gateway'], $gateway ) ) {
+                                       $gateway = $params['gateway'];
+                               } else {
+                                       throw new MWException( __FUNCTION__ . " 
Cannot determine appropriate gateway to use for ffname '$form_key'. " );
+                               }
+                       }
+
+                       $specialpage = ucfirst( $gateway ) . "Gateway";
                }
 
                // set the default redirect
-               //TODO: this is going to be a problem here if we start defining 
more than one gateway per form.
-               return self::getTitleFor( ucfirst( $form_info['gateway'] ) . 
"Gateway" )->getLocalUrl( $params );
+               return self::getTitleFor( $specialpage )->getLocalUrl( $params 
);
        }
 
        /**
@@ -152,7 +182,13 @@
                                unset( $forms[$name] );
                                continue;
                        }
-                       
+
+                       // filter out all special forms (like error pages)
+                       if ( array_key_exists( 'special_type', $meta ) ) {
+                               unset( $forms[$name] );
+                               continue;
+                       }
+
                        //filter on country
                        if ( !is_null( $country ) && 
!DataValidator::value_appears_in( $country, $meta['countries'] ) ) {
                                unset( $forms[$name] );
@@ -329,4 +365,70 @@
                }
                return null;
        }
+
+       /**
+        * Get the best defined error form for all your error form needs!
+        * ...based on gateway, method, and optional submethod.
+        * @global array $wgDonationInterfaceAllowedHtmlForms Contains all 
whitelisted forms and meta data
+        * @param string $gateway The gateway used for the payment that failed
+        * @param string $payment_method The code for the payment method that 
failed
+        * @param string $payment_submethod Code for the payment submethod that 
failed
+        */
+       static function getBestErrorForm( $gateway, $payment_method, 
$payment_submethod = null ) {
+               global $wgDonationInterfaceAllowedHtmlForms;
+               $error_forms = array ( );
+               foreach ( $wgDonationInterfaceAllowedHtmlForms as $ffname => 
$data ) {
+                       if ( array_key_exists( 'special_type', $data ) && 
$data['special_type'] === 'error' ) {
+                               $is_match = true;
+                               $group = 2; //default group
+                               //check to make sure it fits our needs.
+                               if ( is_array( $data['gateway'] ) ) {
+                                       if ( !in_array( $gateway, 
$data['gateway'] ) ) {
+                                               $is_match = false;
+                                       }
+                               } else { //not an array
+                                       if ( $data['gateway'] !== $gateway ) {
+                                               $is_match = false;
+                                       }
+                               }
+
+                               if ( $is_match ) {
+                                       //if no payment methods specified in 
the error form, we don't have to throw it away...
+                                       if ( array_key_exists( 
'payment_methods', $data ) ) {
+                                               if ( !array_key_exists( 
$payment_method, $data['payment_methods'] ) ) {
+                                                       //key exists, but we're 
not in there.
+                                                       $is_match = false;
+                                               } else {
+                                                       $group = 1; //payment 
method specificity
+                                                       if ( !is_null( 
$payment_submethod ) && !in_array( $payment_submethod, $data['payment_methods'] 
) && !in_array( 'ALL', $data['payment_methods'] ) ) {
+                                                               $is_match = 
false;
+                                                       } else {
+                                                               $group = 0; 
//payment submethod specificity
+                                                       }
+                                               }
+                                       }
+                               }
+
+                               if ( $is_match ) {
+                                       $error_forms[$group][$ffname] = $data;
+                               }
+                       }
+               }
+
+               if ( !sizeof( $error_forms ) ) {
+                       throw new MWException( __FUNCTION__ . "No RapidHTML 
Error form found for gateway '$gateway', method '$payment_method', submethod 
'$payment_submethod'" );
+               }
+
+               //sort the error_forms by $group; get the most specific form 
defined
+               ksort( $error_forms );
+
+               //Currently, $error_forms[$group][$ffname] = $data,
+               //with the most specific error forms in the top $group.
+               //So, get rid of all but the top group and collapse.
+               $error_forms = reset( $error_forms ); //top group
+               //now, $error_forms[$ffname] = $data. So, return the top key.
+               reset( $error_forms ); //top form from that group (there must 
be at least one for the key to exist)
+               return key( $error_forms );
+       }
+
 }

-- 
To view, visit https://gerrit.wikimedia.org/r/90448
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: merged
Gerrit-Change-Id: Id0c81b1dfc07cbf5fb247c145e677465cf732210
Gerrit-PatchSet: 3
Gerrit-Project: mediawiki/extensions/DonationInterface
Gerrit-Branch: master
Gerrit-Owner: Katie Horn <[email protected]>
Gerrit-Reviewer: Adamw <[email protected]>
Gerrit-Reviewer: Katie Horn <[email protected]>
Gerrit-Reviewer: Mwalker <[email protected]>
Gerrit-Reviewer: jenkins-bot

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to