r101785 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r101784‎ | r101785 | r101786 >
Date:04:15, 3 November 2011
Author:khorn
Status:ok
Tags:
Comment:
Lots going on here, in preparation for re-designing the way we validate and approve a transaction in GlobalCollect.
*) Adds functionality so the gateway can collect bad news from the validation hooks in the action parameter, which is now protected and accessible through get/set functions.
*) Adds a check to all the optional hooks, to see if it is enabled for the current gateway. The upshot of this is that we can now set all the extras parameters for all the gateways.
*) Fixed what should be the last of the non-standardly-named globals
*) Establishes a mechanism for defining pre_ and post_ process functions for each named transaction in a gateway.adapter. These fire (if they exist) during do_transaction.
Modified paths:
  • /trunk/extensions/DonationInterface/donationinterface.php (modified) (history)
  • /trunk/extensions/DonationInterface/extras/conversion_log/conversion_log.body.php (modified) (history)
  • /trunk/extensions/DonationInterface/extras/custom_filters/custom_filters.body.php (modified) (history)
  • /trunk/extensions/DonationInterface/extras/custom_filters/filters/minfraud/minfraud.body.php (modified) (history)
  • /trunk/extensions/DonationInterface/extras/custom_filters/filters/minfraud/minfraud.php (modified) (history)
  • /trunk/extensions/DonationInterface/extras/custom_filters/filters/referrer/referrer.body.php (modified) (history)
  • /trunk/extensions/DonationInterface/extras/custom_filters/filters/source/source.body.php (modified) (history)
  • /trunk/extensions/DonationInterface/extras/minfraud/minfraud.body.php (modified) (history)
  • /trunk/extensions/DonationInterface/extras/minfraud/minfraud.php (modified) (history)
  • /trunk/extensions/DonationInterface/extras/recaptcha/recaptcha.body.php (modified) (history)
  • /trunk/extensions/DonationInterface/gateway_common/gateway.adapter.php (modified) (history)
  • /trunk/extensions/DonationInterface/globalcollect_gateway/globalcollect.adapter.php (modified) (history)
  • /trunk/extensions/DonationInterface/globalcollect_gateway/globalcollect_gateway.body.php (modified) (history)
  • /trunk/extensions/DonationInterface/globalcollect_gateway/globalcollect_resultswitcher.body.php (modified) (history)
  • /trunk/extensions/DonationInterface/payflowpro_gateway/payflowpro.adapter.php (modified) (history)
  • /trunk/extensions/DonationInterface/payflowpro_gateway/payflowpro_gateway.body.php (modified) (history)

Diff [purge]

Index: trunk/extensions/DonationInterface/donationinterface.php
@@ -70,6 +70,7 @@
7171
7272 //and at least one of them is a custom filter.
7373 $optionalParts['CustomFilters'] = true;
 74+ $wgDonationInterfaceEnableCustomFilters = true; //override this for specific gateways to disable
7475 }
7576 }
7677
@@ -363,7 +364,7 @@
364365 * These are evauluated on a >= or <= basis. Please refer to minFraud
365366 * documentation for a thorough explanation of the 'riskScore'.
366367 */
367 - $wgMinFraudActionRanges = array(
 368+ $wgDonationInterfaceMinFraudActionRanges = array(
368369 'process' => array( 0, 100 ),
369370 'review' => array( -1, -1 ),
370371 'challenge' => array( -1, -1 ),
@@ -393,12 +394,12 @@
394395
395396 //Referrer Filter globals
396397 if ( $optionalParts['ReferrerFilter'] === true ){
397 - $wgCustomFiltersRefRules = array( );
 398+ $wgDonationInterfaceCustomFiltersRefRules = array( );
398399 }
399400
400401 //Source Filter globals
401402 if ( $optionalParts['SourceFilter'] === true ){
402 - $wgCustomFiltersSrcRules = array( );
 403+ $wgDonationInterfaceCustomFiltersSrcRules = array( );
403404 }
404405
405406 //Recaptcha globals
Index: trunk/extensions/DonationInterface/payflowpro_gateway/payflowpro_gateway.body.php
@@ -51,11 +51,11 @@
5252 $result = $this->adapter->do_transaction( 'Card' );
5353
5454 // if the transaction was flagged for rejection
55 - if ( $this->adapter->action == 'reject' ) {
 55+ if ( $this->adapter->getValidationAction() == 'reject' ) {
5656 $this->fnPayflowDisplayDeclinedResults( '' );
5757 }
5858
59 - if ( $this->adapter->action == 'process' ) {
 59+ if ( $this->adapter->getValidationAction() == 'process' ) {
6060 $this->fnPayflowDisplayResults( $result );
6161 }
6262 $this->displayResultsForDebug( $result );
Index: trunk/extensions/DonationInterface/payflowpro_gateway/payflowpro.adapter.php
@@ -78,8 +78,6 @@
7979 'TENDER' => 'C',
8080 'VERBOSITY' => 'MEDIUM',
8181 ),
82 - 'do_validation' => true,
83 - 'do_processhooks' => true,
8482 );
8583 }
8684
@@ -208,7 +206,9 @@
209207 function processResponse( $response ) {
210208 //set the transaction result message
211209 $this->setTransactionResult( $response['RESPMSG'], 'txn_message' );
212 - $this->setTransactionResult( $response['PNREF'], 'gateway_txn_id' );
 210+ if ( isset( $response['PNREF'] ) ){
 211+ $this->setTransactionResult( $response['PNREF'], 'gateway_txn_id' );
 212+ }
213213 }
214214
215215 function defineStagedVars() {
@@ -233,5 +233,13 @@
234234 }
235235 }
236236 }
 237+
 238+ protected function pre_process_card(){
 239+ $this->runPreProcessHooks();
 240+ }
 241+
 242+ protected function post_process_card(){
 243+ $this->runPostProcessHooks();
 244+ }
237245
238246 }
Index: trunk/extensions/DonationInterface/extras/custom_filters/custom_filters.body.php
@@ -55,14 +55,18 @@
5656 public function validate() {
5757 // expose a hook for custom filters
5858 wfRunHooks( 'GatewayCustomFilter', array( &$this->gateway_adapter, &$this ) );
59 - $this->gateway_adapter->action = $this->determineAction();
 59+ $localAction = $this->determineAction();
 60+ $this->gateway_adapter->setValidationAction( $localAction );
6061
61 - $log_msg = '"' . $this->gateway_adapter->action . "\"\t\"" . $this->risk_score . "\"";
 62+ $log_msg = '"' . $localAction . "\"\t\"" . $this->risk_score . "\"";
6263 $this->log( $this->gateway_adapter->getData( 'contribution_tracking_id' ), 'Filtered', $log_msg );
6364 return TRUE;
6465 }
6566
6667 static function onValidate( &$gateway_adapter ) {
 68+ if ( !$gateway_adapter->getGlobal( 'EnableCustomFilters' ) ){
 69+ return true;
 70+ }
6771 $gateway_adapter->debugarray[] = 'custom filters onValidate hook!';
6872 return self::singleton( $gateway_adapter )->validate();
6973 }
Index: trunk/extensions/DonationInterface/extras/custom_filters/filters/source/source.body.php
@@ -24,8 +24,8 @@
2525 $source = $this->gateway_adapter->getData( 'utm_source' );
2626
2727 // a very complex filtering algorithm for sources
28 - global $wgCustomFiltersSrcRules;
29 - foreach ( $wgCustomFiltersSrcRules as $regex => $risk_score_modifier ) {
 28+ $srcRules = $this->gateway_adapter->getGlobal( 'CustomFiltersSrcRules' );
 29+ foreach ( $srcRules as $regex => $risk_score_modifier ) {
3030 /**
3131 * Note that regex pattern does not include delimiters.
3232 * These will need to be included in your custom regex patterns.
@@ -47,6 +47,9 @@
4848 }
4949
5050 static function onFilter( &$gateway_adapter, &$custom_filter_object ) {
 51+ if ( !$gateway_adapter->getGlobal( 'EnableSourceFilter' ) ){
 52+ return true;
 53+ }
5154 $gateway_adapter->debugarray[] = 'source onFilter hook!';
5255 return self::singleton( $gateway_adapter, $custom_filter_object )->filter();
5356 }
Index: trunk/extensions/DonationInterface/extras/custom_filters/filters/minfraud/minfraud.body.php
@@ -13,22 +13,25 @@
1414
1515 public function filter( &$custom_filter_object ) {
1616 // see if we can bypass minfraud
17 - if ( $this->can_bypass_minfraud() )
 17+ if ( $this->can_bypass_minfraud() ){
1818 return TRUE;
 19+ }
1920
2021 $minfraud_query = $this->build_query( $this->gateway_adapter->getData() );
2122 $this->query_minfraud( $minfraud_query );
22 - $this->gateway_adapter->action = 'Filter';
 23+
2324
2425 $custom_filter_object->risk_score += $this->minfraud_response['riskScore'];
2526
2627 // Write the query/response to the log
27 - // @fixme this will cause the 'action' to be logged even though it's premature here
28 - $this->log_query( $minfraud_query );
 28+ $this->log_query( $minfraud_query, '' );
2929 return TRUE;
3030 }
3131
32 - static function onFilter( &$gateway_adapter, &$custom_filter_object ) {
 32+ static function onFilter( &$gateway_adapter, &$custom_filter_object ) {
 33+ if ( !$gateway_adapter->getGlobal( 'EnableMinfraud_as_filter' ) ){
 34+ return true;
 35+ }
3336 $gateway_adapter->debugarray[] = 'minfraud onFilter hook!';
3437 return self::singleton( $gateway_adapter )->filter( $custom_filter_object );
3538 }
Index: trunk/extensions/DonationInterface/extras/custom_filters/filters/minfraud/minfraud.php
@@ -10,7 +10,7 @@
1111 *
1212 * This inherits minFraud settings form the main minFraud extension. To make
1313 * transactions run through minFraud outside of custom filters, set
14 - * $wgMinFraudStandalone = TRUE
 14+ * $wgDonationInterfaceEnableMinfraud = TRUE
1515 *
1616 * To install:
1717 * require_once( "$IP/extensions/DonationInterface/extras/custom_filters/filters/minfraud.php" );
@@ -41,7 +41,7 @@
4242 */
4343
4444 function efCustomFiltersMinFraudSetup() {
45 - global $wgMinFraudStandalone, $wgHooks;
46 - if ( !$wgMinFraudStandalone )
 45+ global $wgDonationInterfaceEnableMinfraud, $wgHooks;
 46+ if ( !$wgDonationInterfaceEnableMinfraud )
4747 $wgHooks['GatewayCustomFilter'][] = array( "Gateway_Extras_CustomFilters_MinFraud::onFilter" );
4848 }
Index: trunk/extensions/DonationInterface/extras/custom_filters/filters/referrer/referrer.body.php
@@ -24,8 +24,8 @@
2525 $referrer = $this->gateway_adapter->getData( 'referrer' );
2626
2727 // a very complex filtering algorithm for referrers
28 - global $wgCustomFiltersRefRules;
29 - foreach ( $wgCustomFiltersRefRules as $regex => $risk_score_modifier ) {
 28+ $refRules = $this->gateway_adapter->getGlobal( 'CustomFiltersRefRules' );
 29+ foreach ( $refRules as $regex => $risk_score_modifier ) {
3030 /**
3131 * note that the regex pattern does NOT include delimiters.
3232 * these will need to be included in your custom regex patterns.
@@ -47,6 +47,9 @@
4848 }
4949
5050 static function onFilter( &$gateway_adapter, &$custom_filter_object ) {
 51+ if ( !$gateway_adapter->getGlobal( 'EnableReferrerFilter' ) ){
 52+ return true;
 53+ }
5154 $gateway_adapter->debugarray[] = 'referrer onFilter hook!';
5255 return self::singleton( $gateway_adapter, $custom_filter_object )->filter();
5356 }
Index: trunk/extensions/DonationInterface/extras/minfraud/minfraud.body.php
@@ -17,7 +17,7 @@
1818 /**
1919 * User-definable riskScore ranges for actions to take
2020 *
21 - * Overload with $wgMinFraudActionRanges
 21+ * Overload with $wgDonationInterfaceMinFraudActionRanges
2222 * @var public array
2323 */
2424 public $action_ranges = array(
@@ -42,16 +42,17 @@
4343 parent::__construct( $gateway_adapter );
4444 $dir = dirname( __FILE__ ) . '/';
4545 require_once( $dir . "ccfd/CreditCardFraudDetection.php" );
46 - global $wgMinFraudLicenseKey, $wgMinFraudActionRanges;
 46+ global $wgMinFraudLicenseKey;
4747
4848 // set the minfraud license key, go no further if we don't have it
4949 if ( !$license_key && !$wgMinFraudLicenseKey ) {
5050 throw new MWException( "minFraud license key required but not present." );
5151 }
5252 $this->minfraud_license_key = ( $license_key ) ? $license_key : $wgMinFraudLicenseKey;
53 -
54 - if ( isset( $wgMinFraudActionRanges ) )
55 - $this->action_ranges = $wgMinFraudActionRanges;
 53+
 54+ $gateway_ranges = $gateway_adapter->getGlobal( 'MinFraudActionRanges' );
 55+ if ( !is_null( $gateway_ranges ) )
 56+ $this->action_ranges = $gateway_ranges;
5657 }
5758
5859 /**
@@ -63,33 +64,35 @@
6465 */
6566 public function validate() {
6667 // see if we can bypass minfraud
67 - if ( $this->can_bypass_minfraud() )
 68+ if ( $this->can_bypass_minfraud() ){
6869 return TRUE;
 70+ }
6971
7072 $minfraud_query = $this->build_query( $this->gateway_adapter->getData() );
7173 $this->query_minfraud( $minfraud_query );
72 - $this->gateway_adapter->action = $this->determine_action( $this->minfraud_response['riskScore'] );
 74+ $localAction = $this->determine_action( $this->minfraud_response['riskScore'] );
 75+ $this->gateway_adapter->setValidationAction( $localAction );
7376
7477 // reset the data hash
7578 $this->gateway_adapter->unsetHash();
76 - $this->gateway_adapter->setActionHash( $this->generate_hash( $this->gateway_adapter->action ) );
 79+ $this->gateway_adapter->setActionHash( $this->generate_hash( $localAction ) );
7780 $this->gateway_adapter->setHash( $this->generate_hash( $this->gateway_adapter->getData() ) );
7881
7982 // Write the query/response to the log
80 - $this->log_query( $minfraud_query );
 83+ $this->log_query( $minfraud_query, $localAction );
8184 return TRUE;
8285 }
8386
8487 /**
8588 * Logs a minFraud query and its response
8689 */
87 - public function log_query( $minfraud_query ) {
 90+ public function log_query( $minfraud_query, $action ) {
8891 if ( $this->log_fh ) {
8992 $log_message = '"' . addslashes( $this->gateway_adapter->getData( 'comment' ) ) . '"';
9093 $log_message .= "\t" . '"' . addslashes( $this->gateway_adapter->getData( 'amount' ) . ' ' . $this->gateway_adapter->getData( 'currency' ) ) . '"';
9194 $log_message .= "\t" . '"' . addslashes( json_encode( $minfraud_query ) ) . '"';
9295 $log_message .= "\t" . '"' . addslashes( json_encode( $this->minfraud_response ) ) . '"';
93 - $log_message .= "\t" . '"' . addslashes( $this->gateway_adapter->action ) . '"';
 96+ $log_message .= "\t" . '"' . addslashes( $action ) . '"';
9497 $log_message .= "\t" . '"' . addslashes( $this->gateway_adapter->getData( 'referrer' ) ) . '"';
9598 $this->log( $this->gateway_adapter->getData( 'contribution_tracking_id' ), 'minFraud query', $log_message );
9699 }
@@ -127,7 +130,7 @@
128131 foreach ( $actions as $action ) {
129132 if ( $this->compare_hash( $action_hash, $action ) ) {
130133 // set the action that should be taken
131 - $this->gateway_adapter->action = $action;
 134+ $this->gateway_adapter->setValidationAction( $action );
132135 return TRUE;
133136 }
134137 }
@@ -266,7 +269,10 @@
267270 }
268271 }
269272
270 - static function onValidate( &$gateway_adapter ) {
 273+ static function onValidate( &$gateway_adapter ) {
 274+ if ( !$gateway_adapter->getGlobal( 'EnableMinfraud' ) ){
 275+ return true;
 276+ }
271277 $gateway_adapter->debugarray[] = "minfraud onValidate hook!";
272278 return self::singleton( $gateway_adapter )->validate();
273279 }
Index: trunk/extensions/DonationInterface/extras/minfraud/minfraud.php
@@ -24,7 +24,6 @@
2525
2626 function efMinFraudSetup() {
2727 // if we're in standalone mode, use the GatewayValidate hook
28 - global $wgMinFraudStandalone, $wgHooks;
29 - if ( $wgMinFraudStandalone )
30 - $wgHooks["GatewayValidate"][] = array( 'Gateway_Extras_MinFraud::onValidate' );
 28+ global $wgHooks;
 29+ $wgHooks["GatewayValidate"][] = array( 'Gateway_Extras_MinFraud::onValidate' );
3130 }
Index: trunk/extensions/DonationInterface/extras/conversion_log/conversion_log.body.php
@@ -9,7 +9,7 @@
1010 */
1111 public function post_process() {
1212 // if the trxn has been outright rejected, log it
13 - if ( $this->gateway_adapter->action == 'reject' ) {
 13+ if ( $this->gateway_adapter->getValidationAction() == 'reject' ) {
1414 $this->log(
1515 $this->gateway_adapter->getData( 'contribution_tracking_id' ), 'Rejected'
1616 );
@@ -27,6 +27,9 @@
2828 }
2929
3030 static function onPostProcess( &$gateway_adapter ) {
 31+ if ( !$gateway_adapter->getGlobal( 'EnableConversionLog' ) ){
 32+ return true;
 33+ }
3134 $gateway_adapter->debugarray[] = 'conversion log onPostProcess hook!';
3235 return self::singleton( $gateway_adapter )->post_process();
3336 }
Index: trunk/extensions/DonationInterface/extras/recaptcha/recaptcha.body.php
@@ -43,7 +43,7 @@
4444 if ( $captcha_resp->is_valid ) {
4545 // if validated, update the action and move on
4646 $this->log( $this->gateway_adapter->getData( 'contribution_tracking_id' ), 'Captcha passed' );
47 - $this->gateway_adapter->action = "process";
 47+ $this->gateway_adapter->setValidationAction( 'process' );
4848 return TRUE;
4949 } else {
5050 $this->recap_err = $captcha_resp->error;
@@ -99,6 +99,9 @@
100100 }
101101
102102 static function onChallenge( &$gateway_adapter ) {
 103+ if ( !$gateway_adapter->getGlobal( 'EnableRecaptcha' ) ){
 104+ return true;
 105+ }
103106 $gateway_adapter->debugarray[] = 'recaptcha onChallenge hook!';
104107 return self::singleton( $gateway_adapter )->challenge();
105108 }
Index: trunk/extensions/DonationInterface/globalcollect_gateway/globalcollect_resultswitcher.body.php
@@ -75,19 +75,21 @@
7676 $this->displayResultsForDebug( $result );
7777 //do the switching between the... stuff.
7878
79 - switch ( $this->adapter->getTransactionWMFStatus() ) {
80 - case 'complete':
81 - case 'pending':
82 - case 'pending-poke':
83 - $go = $this->adapter->getThankYouPage();
84 - break;
85 - case 'failed':
86 - $go = $this->getDeclinedResultPage();
87 - break;
 79+ if ( $this->adapter->getTransactionWMFStatus() ){
 80+ switch ( $this->adapter->getTransactionWMFStatus() ) {
 81+ case 'complete':
 82+ case 'pending':
 83+ case 'pending-poke':
 84+ $go = $this->adapter->getThankYouPage();
 85+ break;
 86+ case 'failed':
 87+ $go = $this->getDeclinedResultPage();
 88+ break;
 89+ }
 90+
 91+ $wgOut->addHTML( "<br>Redirecting to page $go" );
 92+ $wgOut->redirect( $go );
8893 }
89 -
90 - $wgOut->addHTML( "<br>Redirecting to page $go" );
91 - $wgOut->redirect( $go );
9294 }
9395 } else {
9496 if ( !$this->adapter->isCache() ) {
Index: trunk/extensions/DonationInterface/globalcollect_gateway/globalcollect_gateway.body.php
@@ -81,8 +81,8 @@
8282 $this->paypalRedirect();
8383 return;
8484 }
 85+
8586
86 -
8787 // dispatch forms/handling
8888 if ( $this->adapter->checkTokens() ) {
8989 if ( $this->adapter->posted ) {
@@ -118,7 +118,6 @@
119119 $this->displayResultsForDebug( $result );
120120
121121 if ( $payment_method == 'cc' ) {
122 -
123122 $this->executeIframeForCreditCard( $result );
124123 }
125124
Index: trunk/extensions/DonationInterface/globalcollect_gateway/globalcollect.adapter.php
@@ -92,8 +92,6 @@
9393 * @todo
9494 * - Does DO_BANKVALIDATION need IPADDRESS? What about the other transactions. Is this the user's IPA?
9595 * - Does DO_BANKVALIDATION need HOSTEDINDICATOR?
96 - * - Does DO_BANKVALIDATION need do_validation?
97 - * - Does DO_BANKVALIDATION need addDonorDataToSession? We should not save bank account information
9896 *
9997 * This method should define:
10098 * - DO_BANKVALIDATION: used prior to INSERT_ORDERWITHPAYMENT for direct debit
@@ -139,10 +137,7 @@
140138 ),
141139 'values' => array(
142140 'ACTION' => 'DO_BANKVALIDATION',
143 - 'HOSTEDINDICATOR' => '1',
144141 ),
145 - 'do_validation' => true,
146 - 'addDonorDataToSession' => false,
147142 );
148143
149144 $this->transactions['INSERT_ORDERWITHPAYMENT'] = array(
@@ -189,8 +184,6 @@
190185 'ACTION' => 'INSERT_ORDERWITHPAYMENT',
191186 'HOSTEDINDICATOR' => '1',
192187 ),
193 - 'do_validation' => true,
194 - 'addDonorDataToSession' => true,
195188 );
196189
197190 $this->transactions['TEST_CONNECTION'] = array(
@@ -230,8 +223,6 @@
231224 'ACTION' => 'GET_ORDERSTATUS',
232225 'VERSION' => '2.0'
233226 ),
234 - 'do_processhooks' => true,
235 - 'pullDonorDataFromSession' => true,
236227 'loop_for_status' => array(
237228 //'pending',
238229 'pending_poke',
@@ -816,5 +807,31 @@
817808 $this->postdata['returnto'] = $this->postdata['returnto'] . '?' . wfArrayToCGI( array( 'order_id' => $this->postdata['order_id'] ) );
818809 }
819810 }
 811+
 812+ protected function pre_process_insert_orderwithpayment(){
 813+ if ( $this->getData( 'payment_method' ) === 'cc' ){
 814+ $this->runPreProcessHooks(); //this is shortly to move elsewhere.
 815+ $this->addDonorDataToSession();
 816+ }
 817+ }
 818+
 819+ protected function pre_process_get_orderstatus(){
 820+ if ( $this->getData( 'payment_method' ) === 'cc' ){
 821+ //if they're set, get CVVRESULT && AVSRESULT
 822+ global $wgRequest;
 823+ $cvv_result = $wgRequest->getVal( 'CVVRESULT', null );
 824+ $avs_result = $wgRequest->getVal( 'AVSRESULT', null );
 825+ if ( !is_null($cvv_result) ){
 826+ $this->debugarray[] = "CVV result: $cvv_result";
 827+ }
 828+ if ( !is_null($avs_result) ){
 829+ $this->debugarray[] = "AVS result: $avs_result";
 830+ }
 831+ }
 832+ }
 833+
 834+ protected function post_process_get_orderstatus(){
 835+ $this->runPostProcessHooks();
 836+ }
820837
821838 }
\ No newline at end of file
Index: trunk/extensions/DonationInterface/gateway_common/gateway.adapter.php
@@ -1,4 +1,5 @@
22 <?php
 3+
34 /**
45 * Wikimedia Foundation
56 *
@@ -136,7 +137,7 @@
137138 protected $form_class;
138139 protected $validation_errors;
139140 protected $current_transaction;
140 - public $action; //Currently, hooks need to be able to set this directly.
 141+ protected $action;
141142 public $debugarray; //TODO: Take me out.
142143
143144 //ALL OF THESE need to be redefined in the children. Much voodoo depends on the accuracy of these constants.
@@ -178,7 +179,7 @@
179180 //TODO: Fix this a bit.
180181
181182 $this->posted = ( $wgRequest->wasPosted() && ( !is_null( $wgRequest->getVal( 'numAttempt', null ) ) ) );
182 -
 183+
183184 $this->setPostDefaults( $postDefaults );
184185 $this->defineTransactions();
185186 $this->defineVarMap();
@@ -241,13 +242,13 @@
242243 */
243244 public function checkTokens() {
244245 $checkResult = $this->dataObj->token_checkTokens();
245 -
 246+
246247 if ( $checkResult ) {
247248 $this->debugarray[] = 'Token Match';
248249 } else {
249250 $this->debugarray[] = 'Token MISMATCH';
250251 }
251 -
 252+
252253 $this->refreshGatewayValueFromSource( 'token' );
253254 return $checkResult;
254255 }
@@ -277,10 +278,10 @@
278279 * @return DonationData
279280 */
280281 public function getDonationData() {
281 -
 282+
282283 return $this->dataObj;
283284 }
284 -
 285+
285286 function getDisplayData( $val = '' ) {
286287 if ( $val === '' ) {
287288 return $this->displaydata;
@@ -338,10 +339,10 @@
339340 * @return array Returns @see GatewayAdapter::$var_map
340341 */
341342 public function getVarMap() {
342 -
 343+
343344 return $this->var_map;
344345 }
345 -
 346+
346347 /**
347348 * This function is used exclusively by the two functions that build
348349 * requests to be sent directly to external payment gateway servers. Those
@@ -374,7 +375,7 @@
375376 }
376377 //Ensures we are using the correct transaction structure for our various lookups.
377378 $transaction = $this->getCurrentTransaction();
378 -
 379+
379380 if ( !$transaction ){
380381 return null;
381382 }
@@ -406,15 +407,15 @@
407408 return $this->postdata[$this->var_map[$gateway_field_name]];
408409 } else {
409410 //return the default for that form value
410 -
 411+
411412 $tempField = isset( $this->var_map[ $gateway_field_name ] ) ? $this->var_map[ $gateway_field_name ] : false;
412 -
 413+
413414 $tempValue = '';
414 -
 415+
415416 if ( $tempField && isset( $this->postdatadefaults[ $tempField ] ) ) {
416417 $tempValue = $this->postdatadefaults[ $tempField ];
417418 }
418 -
 419+
419420 return $tempValue;
420421 }
421422 }
@@ -425,8 +426,7 @@
426427 self::log( $msg, LOG_CRIT );
427428 throw new MWException( $msg );
428429 }
429 -
430 -
 430+
431431 /**
432432 * Returns the current transaction request structure if it exists, otherwise
433433 * returns false.
@@ -439,16 +439,16 @@
440440 if ( !$transaction ){
441441 return false;
442442 }
443 -
444 - if ( empty( $this->transactions ) ||
445 - !array_key_exists( $transaction, $this->transactions ) ||
 443+
 444+ if ( empty( $this->transactions ) ||
 445+ !array_key_exists( $transaction, $this->transactions ) ||
446446 !array_key_exists( 'request', $this->transactions[$transaction] ) ) {
447 -
 447+
448448 $msg = self::getGatewayName() . ": $transaction request structure is empty! No transaction can be constructed.";
449449 self::log( $msg, LOG_CRIT );
450450 throw new MWException( $msg );
451451 }
452 -
 452+
453453 return $this->transactions[$transaction]['request'];
454454 }
455455
@@ -572,7 +572,7 @@
573573 $this->xmlDoc = new DomDocument( '1.0' );
574574 $node = $this->xmlDoc->createElement( 'XML' );
575575
576 - $structure = $this->getTransactionRequestStructure();
 576+ $structure = $this->getTransactionRequestStructure();
577577 if ( !is_array( $structure ) ) {
578578 return '';
579579 }
@@ -621,14 +621,16 @@
622622 //update the contribution tracking data
623623 $this->incrementNumAttempt();
624624
625 - //if we're supposed to add the donor data to the session, do that.
626 - if ( $this->transaction_option( 'addDonorDataToSession' ) ) {
627 - $this->addDonorDataToSession();
628 - }
 625+ //If we have any special pre-process instructions for this
 626+ //transaction, do 'em.
 627+ //NOTE: If you want your transaction to fire off the pre-process
 628+ //hooks, you need to run $this->runPreProcessHooks in a function
 629+ //called
 630+ // 'pre_process' . strtolower($transaction)
 631+ //in the appropriate gateway object.
 632+ $this->executeIfFunctionExists( 'pre_process_' . $transaction );
629633
630 - $this->runPreProcess(); //many hooks get fired here...
631 -
632 - if ( $this->action != 'process' ) {
 634+ if ( $this->getValidationAction() != 'process' ) {
633635 return array(
634636 'status' => false,
635637 //TODO: appropriate messages.
@@ -636,15 +638,10 @@
637639 'errors' => array(
638640 '1000000' => 'pre-process failed you.' //...stupid code.
639641 ),
640 - 'action' => $this->action,
 642+ 'action' => $this->getValidationAction(),
641643 );
642644 }
643645
644 - // expose a hook for external handling of trxns ready for processing
645 - if ( $this->transaction_option( 'do_processhooks' ) ) {
646 - wfRunHooks( 'GatewayProcess', array( &$this ) ); //don't think anybody is using this yet, but you could!
647 - }
648 -
649646 $this->dataObj->updateContributionTracking( defined( 'OWA' ) );
650647
651648 // If the payment processor requires XML, package our data into XML.
@@ -661,15 +658,15 @@
662659 $this->saveCommunicationStats( "buildRequestNameValueString", $transaction ); // save profiling data
663660 }
664661 } catch ( MWException $e ) {
665 - self::log( "Malformed gateway definition. Cannot continue: Aborting.", LOG_CRIT );
 662+ self::log( "Malformed gateway definition. Cannot continue: Aborting.\n" . $e->getMessage(), LOG_CRIT );
666663 return array(
667664 'status' => false,
668665 //TODO: appropriate messages.
669 - 'message' => "$transaction : Malformed gateway definition. Cannot continue: Aborting.",
 666+ 'message' => "$transaction : Malformed gateway definition. Cannot continue: Aborting.\n" . $e->getMessage(),
670667 'errors' => array(
671668 '1000000' => 'Transaction could not be processed due to an internal error.'
672669 ),
673 - 'action' => $this->action,
 670+ 'action' => $this->getValidationAction(),
674671 );
675672 }
676673
@@ -732,16 +729,18 @@
733730 );
734731 }
735732
736 - // expose a hook for any post processing
737 - if ( $this->transaction_option( 'do_processhooks' ) ) {
738 - wfRunHooks( 'GatewayPostProcess', array( &$this ) ); //conversion log (at least)
739 - $this->doStompTransaction();
740 - }
 733+ //If we have any special post-process instructions for this
 734+ //transaction, do 'em.
 735+ //NOTE: If you want your transaction to fire off the post-process
 736+ //hooks, you need to run $this->runPostProcessHooks in a function
 737+ //called
 738+ // 'post_process' . strtolower($transaction)
 739+ //in the appropriate gateway object.
 740+ $this->executeIfFunctionExists( 'post_process_' . $transaction );
741741
742742 //TODO: Actually pull these from somewhere legit.
743743 if ( $this->getTransactionStatus() === true ) {
744744 $this->setTransactionResult( "$transaction Transaction Successful!", 'message' );
745 -
746745 } elseif ( $this->getTransactionStatus() === false ) {
747746 $this->setTransactionResult( "$transaction Transaction FAILED!", 'message' );
748747 } else {
@@ -765,11 +764,8 @@
766765 case 'pending' :
767766 case 'pending-poke' :
768767 $this->unsetAllSessionData();
769 - }
770 - //if we're not actively adding the donor data to the session, kill it.
771 - if ( !$this->transaction_option( 'addDonorDataToSession' ) ) {
772 - $this->dataObj->unsetDonorSessionData(); //just that. Not the whole session.
773768 }
 769+
774770 $this->debugarray[] = 'numAttempt = ' . $this->postdata['numAttempt'];
775771
776772 return $this->getTransactionAllResults();
@@ -832,7 +828,7 @@
833829 $this->current_transaction = $transaction_name;
834830 }
835831 }
836 -
 832+
837833 /**
838834 * Gets the currently set transaction name. This value should only ever be
839835 * set with setCurrentTransaction: A function that ensures the current
@@ -848,7 +844,7 @@
849845 return $this->current_transaction;
850846 }
851847 }
852 -
 848+
853849 /**
854850 * Define payment methods
855851 *
@@ -864,16 +860,16 @@
865861 * @return array Returns the available payment methods for the specific adapter
866862 */
867863 public function getPaymentMethods() {
868 -
 864+
869865 // Define the payment methods if they have not been set yet.
870866 if ( empty( $this->payment_methods ) ) {
871 -
 867+
872868 $this->definePaymentMethods();
873869 }
874 -
 870+
875871 return $this->payment_methods;
876872 }
877 -
 873+
878874 /**
879875 * Define payment methods
880876 *
@@ -892,16 +888,16 @@
893889 * @return array Returns the available payment submethods for the specific adapter
894890 */
895891 public function getPaymentSubmethods() {
896 -
 892+
897893 // Define the payment methods if they have not been set yet.
898894 if ( empty( $this->payment_submethods ) ) {
899 -
 895+
900896 $this->definePaymentSubmethods();
901897 }
902 -
 898+
903899 return $this->payment_methods;
904900 }
905 -
 901+
906902 /**
907903 * Sends a curl request to the gateway server, and gets a response.
908904 * Saves that response to the gateway object with setTransactionResult();
@@ -1214,8 +1210,6 @@
12151211 }
12161212
12171213 /**
1218 - * Called in do_transaction, in the case that we have successfully completed
1219 - * a transaction that has 'do_processhooks' enabled.
12201214 * Saves a stomp frame to the configured server and queue, based on the
12211215 * outcome of our current transaction.
12221216 * The big tricky thing here, is that we DO NOT SET a TransactionWMFStatus,
@@ -1224,9 +1218,15 @@
12251219 * To put it another way, getTransactionWMFStatus should always return
12261220 * false, unless it's new data about a new transaction. In that case, the
12271221 * outcome will be assigned and the proper stomp hook selected.
 1222+ *
 1223+ * Probably called in runPostProcessHooks(), which is itself most likely to
 1224+ * be called through executeFunctionIfExists, later on in do_transaction.
12281225 * @return null
12291226 */
12301227 protected function doStompTransaction() {
 1228+ if ( !$this->getGlobal( 'EnableStomp' ) ){
 1229+ return;
 1230+ }
12311231 $this->debugarray[] = "Attempting Stomp Transaction!";
12321232 $hook = '';
12331233
@@ -1253,13 +1253,12 @@
12541254 //'language' => '',
12551255 );
12561256 $transaction += $this->getDisplayData();
1257 -
 1257+
12581258 try {
12591259 wfRunHooks( $hook, array( $transaction ) );
12601260 } catch ( Exception $e ) {
12611261 self::log( "STOMP ERROR. Could not add message. " . $e->getMessage() , LOG_CRIT );
12621262 }
1263 -
12641263 }
12651264
12661265 function smooshVarsForStaging() {
@@ -1273,8 +1272,23 @@
12741273 //what do we do in the event that we're still nothing? (just move on.)
12751274 }
12761275 }
1277 -
 1276+
12781277 /**
 1278+ * Executes the specified function in $this, if one exists.
 1279+ * NOTE: THIS WILL LCASE YOUR FUNCTION_NAME.
 1280+ * ...I like to keep the voodoo functions tidy.
 1281+ * @param string $function_name The name of the function you're hoping to
 1282+ * execute.
 1283+ * @param mixed $parameter That's right: For now you only get one.
 1284+ */
 1285+ function executeIfFunctionExists( $function_name, $parameter = null ) {
 1286+ $function_name = strtolower( $function_name ); //Because, that's why.
 1287+ if ( method_exists( $this, $function_name ) ) {
 1288+ $this->{$function_name}( $parameter );
 1289+ }
 1290+ }
 1291+
 1292+ /**
12791293 *
12801294 * @param type $type Whatever types of staging you feel like having in your child class.
12811295 * ...but usually request and response. I think.
@@ -1286,11 +1300,9 @@
12871301 //multiple variables.
12881302 foreach ( $this->staged_vars as $field ) {
12891303 $function_name = 'stage_' . $field;
1290 - if ( method_exists( $this, $function_name ) ) {
1291 - $this->{$function_name}( $type );
 1304+ $this->executeIfFunctionExists( $function_name, $type );
12921305 }
12931306 }
1294 - }
12951307
12961308 function getPaypalRedirectURL() {
12971309 $utm_source = $this->getData( 'utm_source' );
@@ -1311,7 +1323,6 @@
13121324 //In fact, put that in addData, and restage anything that's either the explicit key,
13131325 //or any of the calculated keys.
13141326 $this->refreshGatewayValueFromSource( 'utm_source' ); //calculated field!
1315 -
13161327 //update contribution tracking
13171328 $this->dataObj->updateContributionTracking( true );
13181329
@@ -1319,7 +1330,7 @@
13201331 self::log( $ret );
13211332 return $ret;
13221333 }
1323 -
 1334+
13241335 protected function getPaypalData() {
13251336 $paypalkeys = array(
13261337 'contribution_tracking_id',
@@ -1349,7 +1360,7 @@
13501361 'amount',
13511362 'amountGiven',
13521363 'size',
1353 - 'premium_language',
 1364+ 'premium_language',
13541365 );
13551366 $ret = array();
13561367 foreach ( $paypalkeys as $key ){
@@ -1415,7 +1426,7 @@
14161427 * Possible valid statuses are: 'complete', 'pending', 'pending-poke', 'failed' and 'revised'.
14171428 */
14181429 public function getTransactionWMFStatus() {
1419 - if ( array_key_exists( 'WMF_STATUS', $this->transaction_results ) ) {
 1430+ if ( is_array( $this->transaction_results ) && array_key_exists( 'WMF_STATUS', $this->transaction_results ) ) {
14201431 return $this->transaction_results['WMF_STATUS'];
14211432 } else {
14221433 return false;
@@ -1425,6 +1436,13 @@
14261437 /**
14271438 * Sets the WMF Transaction Status. This is the one we care about for
14281439 * switching on behavior.
 1440+ * DO NOT SET THE WMF STATUS unless you've just taken an entire donation
 1441+ * process to completion: This status being set at all, denotes the very end
 1442+ * of the donation process on our end. Further attempts by the same user
 1443+ * will be seen as starting over.
 1444+ * @param string $status Only five strings will do anything good in the rest
 1445+ * of the code so far:
 1446+ * 'complete', 'pending', 'pending-poke', 'failed', 'revised'
14291447 */
14301448 public function setTransactionWMFStatus( $status ) {
14311449 $this->transaction_results['WMF_STATUS'] = $status;
@@ -1508,43 +1526,66 @@
15091527 $this->dataObj->expunge( 'action' );
15101528 }
15111529
1512 - function runPreProcess() {
1513 - global $wgHooks;
1514 - if ( $this->transaction_option( 'do_validation' ) ) {
1515 - if ( !isset( $wgHooks['GatewayValidate'] ) ) {
1516 - //if there ARE no validate hooks, we're okay.
1517 - $this->action = 'process';
1518 - return;
1519 - }
1520 - // allow any external validators to have their way with the data
1521 - self::log( $this->getData( 'contribution_tracking_id' ) . " Preparing to query MaxMind" );
1522 - wfRunHooks( 'GatewayValidate', array( &$this ) );
1523 - self::log( $this->getData( 'contribution_tracking_id' ) . ' Finished querying Maxmind' );
 1530+ /**
 1531+ * Runs all the pre-process hooks that have been enabled and configured in
 1532+ * donationdata.php and/or LocalSettings.php
 1533+ * This function is most likely to be called through
 1534+ * executeFunctionIfExists, early on in do_transaction.
 1535+ */
 1536+ function runPreProcessHooks() {
 1537+ // allow any external validators to have their way with the data
 1538+ self::log( $this->getData( 'contribution_tracking_id' ) . " Preparing to query MaxMind" );
 1539+ wfRunHooks( 'GatewayValidate', array( &$this ) );
 1540+ self::log( $this->getData( 'contribution_tracking_id' ) . ' Finished querying Maxmind' );
15241541
1525 - // if the transaction was flagged for review
1526 - if ( $this->action == 'review' ) {
1527 - // expose a hook for external handling of trxns flagged for review
1528 - wfRunHooks( 'GatewayReview', array( &$this ) );
1529 - }
 1542+ //DO NOT set some variable as getValidationAction() here, and keep
 1543+ //checking that. getValidationAction could change with each one of these
 1544+ //hooks, and this ought to cascade.
 1545+ // if the transaction was flagged for review
 1546+ if ( $this->getValidationAction() == 'review' ) {
 1547+ // expose a hook for external handling of trxns flagged for review
 1548+ wfRunHooks( 'GatewayReview', array( &$this ) );
 1549+ }
15301550
1531 - // if the transaction was flagged to be 'challenged'
1532 - if ( $this->action == 'challenge' ) {
1533 - // expose a hook for external handling of trxns flagged for challenge (eg captcha)
1534 - wfRunHooks( 'GatewayChallenge', array( &$this ) );
1535 - }
 1551+ // if the transaction was flagged to be 'challenged'
 1552+ if ( $this->getValidationAction() == 'challenge' ) {
 1553+ // expose a hook for external handling of trxns flagged for challenge (eg captcha)
 1554+ wfRunHooks( 'GatewayChallenge', array( &$this ) );
15361555
15371556 // if the transaction was flagged for rejection
1538 - if ( $this->action == 'reject' ) {
 1557+ if ( $this->getValidationAction() == 'reject' ) {
15391558 // expose a hook for external handling of trxns flagged for rejection
15401559 wfRunHooks( 'GatewayReject', array( &$this ) );
15411560 $this->unsetAllSessionData();
15421561 }
1543 - } else {
1544 - $this->action = 'process'; //we have to do this so do_transaction doesn't kick out.
 1562+ }
15451563 }
 1564+
 1565+ /**
 1566+ * Runs all the post-process hooks that have been enabled and configured in
 1567+ * donationdata.php and/or LocalSettings.php, including the ActiveMQ/Stomp
 1568+ * hooks.
 1569+ * This function is most likely to be called through
 1570+ * executeFunctionIfExists, later on in do_transaction.
 1571+ */
 1572+ protected function runPostProcessHooks() {
 1573+ // expose a hook for any post processing
 1574+ wfRunHooks( 'GatewayPostProcess', array( &$this ) ); //conversion log (at least)
 1575+ $this->doStompTransaction();
15461576 }
15471577
1548 - function transaction_option( $option_value ) {
 1578+ /**
 1579+ * If there are things about a transaction that we need to stash in the
 1580+ * transaction's definition (defined in a local defineTransactions() ), we
 1581+ * can recall them here. Currently, this is only being used to determine if
 1582+ * we have a transaction whose transmission would require multiple attempts
 1583+ * to wait for a certain status (or set of statuses), but we could do more
 1584+ * with this mechanism if we need to.
 1585+ * @param string $option_value the name of the key we're looking for in the
 1586+ * transaction definition.
 1587+ * @return mixed the transaction's value for that key if it exists, or false.
 1588+ */
 1589+ protected function transaction_option( $option_value ) {
15491590 //ooo, ugly.
15501591 $transaction = $this->getCurrentTransaction();
15511592 if ( !$transaction ){
@@ -1561,7 +1602,7 @@
15621603 }
15631604 return false;
15641605 }
1565 -
 1606+
15661607 /**
15671608 * Instead of pulling all the DonationData back through to update one local
15681609 * value, use this. It updates both postdata (which is intended to be
@@ -1576,7 +1617,7 @@
15771618 * @param string $val The field name that we are looking to retrieve from
15781619 * our DonationData object.
15791620 */
1580 - function refreshGatewayValueFromSource( $val ){
 1621+ function refreshGatewayValueFromSource( $val ) {
15811622 $refreshed = $this->dataObj->getVal( $val );
15821623 if ( !is_null($refreshed) ){
15831624 $this->postdata[$val] = $refreshed;
@@ -1586,5 +1627,48 @@
15871628 unset( $this->displaydata[$val] );
15881629 }
15891630 }
1590 -
1591 -}
 1631+
 1632+ /**
 1633+ * Sets the current validation action. This is meant to be used by the
 1634+ * process hooks, and as such, by default, only worse news than was already
 1635+ * being stored will be retained for the final result.
 1636+ * @param string $action the value you want to set as the action.
 1637+ * @param bool $reset set to true to do a hard set on the action value.
 1638+ * Otherwise, the status will only change if it fails harder than it already
 1639+ * was.
 1640+ */
 1641+ public function setValidationAction( $action, $reset = false ) {
 1642+ //our choices are:
 1643+ $actions = array(
 1644+ 'process' => 0,
 1645+ 'review' => 1,
 1646+ 'challenge' => 2,
 1647+ 'reject' => 3,
 1648+ );
 1649+ if ( !isset( $actions[$action] ) ) {
 1650+ throw new MWException( "Action $action is invalid." );
 1651+ }
 1652+
 1653+ if ( $reset ) {
 1654+ $this->action = $action;
 1655+ return;
 1656+ }
 1657+
 1658+ if ( ( int ) $actions[$action] > ( int ) $actions[$this->getValidationAction()] ) {
 1659+ $this->action = $action;
 1660+ }
 1661+ }
 1662+
 1663+ /**
 1664+ * Returns the current validation action.
 1665+ * This will typically get set and altered by the various enabled process hooks.
 1666+ * @return string the current process action.
 1667+ */
 1668+ public function getValidationAction() {
 1669+ if ( !isset( $this->action ) ) {
 1670+ $this->action = 'process';
 1671+ }
 1672+ return $this->action;
 1673+ }
 1674+
 1675+}
\ No newline at end of file

Follow-up revisions

RevisionCommit summaryAuthorDate
r102236MFT r90286, r100671, r100837, r100950, r101060, r101063, r101064, r101073, r1......khorn03:06, 7 November 2011
r102237MFT r90286, r100671, r100837, r100950, r101060, r101063, r101064, r101073, r1......khorn03:07, 7 November 2011
r102732MFT r100644, r100785, r101785, r102120, r102318, r102332, r102341, r102342, r...awjrichards01:31, 11 November 2011
r104089Missing a curly brace, all the way back from r101785. This explains why the s...khorn21:29, 23 November 2011
r112287MFT r101785, r105938, r105941, r105953, r106109, r106158, r106259, r106366, r...khorn01:29, 24 February 2012

Status & tagging log