http://www.mediawiki.org/wiki/Special:Code/MediaWiki/95821

Revision: 95821
Author:   khorn
Date:     2011-08-30 23:27:19 +0000 (Tue, 30 Aug 2011)
Log Message:
-----------
Now able to see the results of a transaction on the globalcollect results page. 
Nothing has been abstracted out yet, really. That's the next step.

Modified Paths:
--------------
    
branches/fundraising/extensions/DonationInterface/globalcollect_gateway/globalcollect.adapter.php
    
branches/fundraising/extensions/DonationInterface/globalcollect_gateway/globalcollect_gateway.body.php
    
branches/fundraising/extensions/DonationInterface/globalcollect_gateway/globalcollect_gateway.php

Modified: 
branches/fundraising/extensions/DonationInterface/globalcollect_gateway/globalcollect.adapter.php
===================================================================
--- 
branches/fundraising/extensions/DonationInterface/globalcollect_gateway/globalcollect.adapter.php
   2011-08-30 22:29:06 UTC (rev 95820)
+++ 
branches/fundraising/extensions/DonationInterface/globalcollect_gateway/globalcollect.adapter.php
   2011-08-30 23:27:19 UTC (rev 95821)
@@ -14,13 +14,19 @@
        private $xmlDoc;
        
        function __construct($data){
+               //TODO: Squish ALL the globals here, in the constructor. 
+               //easier to abstract out that way. 
                global $wgGatewayTest;
                
                $this->postdata = $data;
                
+               //TODO: Make a Thing in which we do things like this. 
+               $this->postdata['amount'] = $this->postdata['amount'] * 100;
                
+               
                $returnTitle = Title::newFromText( 'Donate-thanks/en' );
                $returnto = $returnTitle->getFullURL();
+               $returnto = "http://www.katiehorn.com";;
                
                //this DEFINITELY needs to be defined in the parent class, and 
contain everything anybody might want to know.
                $this->postdatadefaults = array(
@@ -46,12 +52,22 @@
                        'COUNTRYCODE' => 'country',
                        'MERCHANTREFERENCE' => 'order_id',
                        'RETURNURL' => 'returnto', //I think. It might not even 
BE here yet. Boo-urns. 
-                       'IPADDRESS' => 'user_ip' //TODO: Not sure if this 
should be OUR ip, or the user's ip. Hurm.
+                       'IPADDRESS' => 'user_ip', //TODO: Not sure if this 
should be OUR ip, or the user's ip. Hurm.
+                       
                );
                
+               $this->return_value_map  = array(
+                       'OK' => true,
+                       'NOK' => false,
+               );
+               
                global $wgGlobalCollectURL, $wgGlobalCollectMerchantID;
+               if ($wgGatewayTest){
+                       $this->url = $wgGlobalCollectURL;
+               } else {
+                       $this->url = $wgGlobalCollectURL;
+               }
                
-               $this->url = $wgGlobalCollectURL;
                
                $this->accountInfo = array(
 //                     'PAYMENTPRODUCTID' => '3', //actually, these are almost 
certainly transaction-specific.
@@ -61,6 +77,7 @@
                        'VERSION' => "1.0",
                );
                
+               //oof. This is getting a little long and unwieldy. Maybe we 
should build it. Or maybe that sucks. I can't tell yet.
                /* General idea here:
                 * This bad boy will (probably) contain the structure of all 
possible transactions as defined by the gateway. 
                 * First array key: Some way for us to id the transaction. 
Doesn't actually have to be the gateway's name for it, but
@@ -80,7 +97,7 @@
                                                'ACTION',
                                                'META' => array(
                                                        'MERCHANTID',
-                                                       'IPADDRESS',
+//                                                     'IPADDRESS',
                                                        'VERSION'
                                                ),
                                                'PARAMS' => array(
@@ -109,12 +126,61 @@
                                        'HOSTEDINDICATOR' => '1',
                                        'PAYMENTPRODUCTID' => '3',
                                ),
-                       )
+                               'result' => array( //just like the rest: This 
is still in flux. But the idea here is that this is the sctucture you'd scan 
for. 
+                                       'RESULT' => 'value'
+                               ),
+                               'result_errors' => array(
+                                       'ERROR' => array(
+                                               'CODE' => 'value', //as opposed 
to "attribute", which would imply that it belongs to the parent...
+                                               'MESSAGE' => 'value',
+                                       )
+                               ),
+                               'result_data' => array(
+                                       'ROW' => array(
+                                               //uhh... presumably we'd look 
for some Stuff in here. 
+                                       )
+                               )
+                       ),
+                       'TEST_CONNECTION' => array(
+                               'request' => array(
+                                       'REQUEST' => array(
+                                               'ACTION',
+                                               'META' => array(
+                                                       'MERCHANTID',
+//                                                     'IPADDRESS',
+                                                       'VERSION'
+                                               ),
+                                               'PARAMS' => array()
+                                       )
+                               ),
+                               'values' => array(
+                                       'ACTION' => 'TEST_CONNECTION'
+                               ),
+                               'result' => array( //just like the rest: This 
is still in flux. But the idea here is that this is the sctucture you'd scan 
for. 
+                                       'RESULT' => 'value'
+                               ),
+                               'result_errors' => array(
+                                       'ERROR' => array(
+                                               'CODE' => 'value', //as opposed 
to "attribute", which would imply that it belongs to the parent...
+                                               'MESSAGE' => 'value',
+                                       )
+                               ),
+                               'result_data' => array(
+                                       'ROW' => array(
+                                               //uhh... presumably we'd look 
for some Stuff in here. 
+                                       )
+                               )
+                       ),
                );
        
        }
        
-       function getValue($gateway_field_name, $transaction){
+       function getCommunicationType(){
+               return 'xml'; //'xml' or 'namevalue'.
+       }
+       
+       
+       function getValue($gateway_field_name, $transaction = ''){
                //How do we determine the value of a field asked for in a 
particular transaction? 
                
                //If there's a hard-coded value in the transaction definition, 
use that.
@@ -150,30 +216,31 @@
                
        }
 
-       function buildRequestXML($transaction){
+       function buildRequestXML(){
                $this->xmlDoc = new DomDocument('1.0');
                $node = $this->xmlDoc->createElement('XML');
                
-               $structure = $this->transactions[$transaction]['request'];
+               $structure = 
$this->transactions[$this->currentTransaction()]['request'];
                
-               $this->buildTransactionNodes($transaction, $structure, $node);
+               $this->buildTransactionNodes($structure, $node);
                $this->xmlDoc->appendChild($node);
                return $this->xmlDoc->saveXML();
        }
        
        
-       function buildTransactionNodes($transaction, $structure, &$node){
+       function buildTransactionNodes($structure, &$node){
+               $transaction = $this->currentTransaction();
                
                if (!is_array($structure)){ //this is a weird case that 
shouldn't ever happen. I'm just being... thorough. But, yeah: It's like... the 
base-1 case. 
-                       $this->appendNodeIfValue($structure, $transaction, 
$node);
+                       $this->appendNodeIfValue($structure, $node);
                } else {
                        foreach ($structure as $key => $value){
                                if (!is_array($value)){
                                        //do not use $key. $key is meaningless 
in this case.                    
-                                       $this->appendNodeIfValue($value, 
$transaction, $node);
+                                       $this->appendNodeIfValue($value, $node);
                                } else {
                                        $keynode = 
$this->xmlDoc->createElement($key);
-                                       
$this->buildTransactionNodes($transaction, $value, $keynode);
+                                       $this->buildTransactionNodes( $value, 
$keynode);
                                        $node->appendChild($keynode);
                                }
                        }
@@ -181,180 +248,299 @@
                //not actually returning anything. It's all side-effects. 
Because I suck like that. 
        }
        
-       function appendNodeIfValue($value, $transaction, &$node){
-               $nodevalue = $this->getValue($value, $transaction);
+       function appendNodeIfValue($value, &$node){
+               $nodevalue = $this->getValue($value, 
$this->currentTransaction());
                if ($nodevalue !== '' && $nodevalue !== false){
                        $temp = $this->xmlDoc->createElement($value, 
$nodevalue);
                        $node->appendChild($temp);
                }
        }
        
-       function sendRequestXML($transaction){
-               $xml = $this->buildRequestXML($transaction);
+       function do_transaction($transaction){
+               $this->currentTransaction($transaction);
+               if ($this->getCommunicationType() === 'xml'){
+                       $xml = $this->buildRequestXML();
+                       $response = $this->curl_transaction($xml);
+                       //put the response in a universal form, and return it. 
+               }
                
+               //TODO: Actually pull these from somewhere legit. 
+               if ($response['status'] === true){
+                       $response['message'] = "$transaction Transaction 
Successful!";
+               } elseif ($response['status'] === false){
+                       $response['message'] = "$transaction Transaction 
FAILED!";
+               } else {
+                       $response['message'] = "$transaction Transaction... 
weird. I have no idea what happened there.";
+               }
+               
+               return $response;
+               
+               //speaking of universal form: 
+               //$result['status'] = something I wish could be boiled down to 
a bool, but that's way too optimistic, I think.
+               //$result['message'] = whatever we want to display back? 
+               //$result['errors'][]['code'] = their error code
+               //$result['errors'][]['value'] = Error message
+               //$result['return'][$whatever] = values they pass back to us 
for whatever reason. We might... log it, or pieces of it, or something? 
        }
+       
+       function getCurlBaseOpts(){
+               //I chose to return this as a function so it's easy to 
override. 
+               //TODO: probably this for all the junk I currently have stashed 
in the constructor.
+               //...maybe. 
+               global $wgGlobalCollectTimeout, $wgPayflowGatewayUseHTTPProxy;
+               $opts = array(
+                       CURLOPT_URL => $this->url,
+                       //CURLOPT_USERAGENT => Http::userAgent(),
+                       CURLOPT_HEADER => 1,
+                       CURLOPT_RETURNTRANSFER => 1,
+                       CURLOPT_TIMEOUT => $wgGlobalCollectTimeout,
+                       //CURLOPT_FOLLOWLOCATION => 0,
+                       //CURLOPT_SSL_VERIFYPEER => 0,
+                       //CURLOPT_SSL_VERIFYHOST => 2,
+                       //CURLOPT_FORBID_REUSE => true,
+                       CURLOPT_POST => 1,
+               );
 
+               // set proxy settings if necessary
+               if ( $wgPayflowGatewayUseHTTPProxy ) {
+                       $opts[CURLOPT_HTTPPROXYTUNNEL] = 1;
+                       $opts[CURLOPT_PROXY] = $wgPayflowGatewayHTTPProxy;
+               }
+               return $opts;
+       }
+       
+       
+       function getCurlBaseHeaders(){
+               $headers = array (
+                       'Content-Type: text/' . $this->getCommunicationType() . 
'; charset=utf-8',
+               //      'X-VPS-Client-Timeout: 45',
+               //      'X-VPS-Request-ID:' . 
$this->postdatadefaults['order_id'],
+               );
+               return $headers;
+       }
+       
+       private function currentTransaction($transaction = ''){ //get&set in 
one!
+               static $current_transaction;
+               if ($transaction != ''){
+                       $current_transaction = $transaction;
+               }
+               if (!isset($current_transaction)){
+                       return false;
+               }
+               return $current_transaction;
+       }
+
        /**
         * Sends a name-value pair string to Payflow gateway
         *
-        * @param $data Array: array of user input
-        * @param $payflow_data Array: array of necessary Payflow variables to
-        *                                              include in string (i.e. 
Vendor, password)
+        * @param $data String: The exact thing we want to send.
         */
-       private function fnGlobalCollectProcessTransaction( $data, 
$payflow_data ) {
-               global $wgOut, $wgDonationTestingMode, 
$wgPayflowGatewayUseHTTPProxy, $wgPayflowGatewayHTTPProxy, 
$wgGlobalCollectTimeout;
+       private function curl_transaction( $data ) {
+               global $wgOut; //TODO: Uhm, this shouldn't touch the view. 
Something further upstream should decide what to do with this. 
 
-               // update contribution tracking
-               $this->updateContributionTracking( $data, defined( 'OWA' ) );
+               // TODO: This, but way before we get here. 
+               //$this->updateContributionTracking( $data, defined( 'OWA' ) );
 
-               // create payflow query string, include string lengths
-               $queryArray = array(
-                       'TRXTYPE' => $payflow_data['trxtype'],
-                       'TENDER'  => $payflow_data['tender'],
-                       'USER'  => $payflow_data['user'],
-                       'VENDOR' => $payflow_data['vendor'],
-                       'PARTNER' => $payflow_data['partner'],
-                       'PWD' => $payflow_data['password'],
-                       'ACCT'  => $data['card_num'],
-                       'EXPDATE' => $data['expiration'],
-                       'AMT' => $data['amount'],
-                       'FIRSTNAME' => $data['fname'],
-                       'LASTNAME' => $data['lname'],
-                       'STREET' => $data['street'],
-                       'CITY' => $data['city'],
-                       'STATE' => $data['state'],
-                       'COUNTRY' => $data['country'],
-                       'ZIP' => $data['zip'],
-                       'INVNUM' => $data['order_id'],
-                       'CVV2' => $data['cvv'],
-                       'CURRENCY' => $data['currency'],
-                       'VERBOSITY' => $payflow_data['verbosity'],
-                       'CUSTIP' => $payflow_data['user_ip'],
-               );
-
-               foreach ( $queryArray as $name => $value ) {
-                       $query[] = $name . '[' . strlen( $value ) . ']=' . 
$value;
-               }
-
-               $queryString = implode( '&', $query );
-
-               $payflow_query = $queryString;
-
                // assign header data necessary for the curl_setopt() function
-               $user_agent = Http::userAgent();
-               $headers[] = 'Content-Type: text/namevalue';
-               $headers[] = 'Content-Length : ' . strlen( $payflow_query );
-               $headers[] = 'X-VPS-Client-Timeout: 45';
-               $headers[] = 'X-VPS-Request-ID:' . $data['order_id'];
+               
                $ch = curl_init();
-               $paypalPostTo = isset ( $wgDonationTestingMode ) ? 'testingurl' 
: 'paypalurl';
-               curl_setopt( $ch, CURLOPT_URL, $payflow_data[ $paypalPostTo ] );
-               curl_setopt( $ch, CURLOPT_HTTPHEADER, $headers );
-               curl_setopt( $ch, CURLOPT_USERAGENT, $user_agent );
-               curl_setopt( $ch, CURLOPT_HEADER, 1 );
-               curl_setopt( $ch, CURLOPT_RETURNTRANSFER, 1 );
-               curl_setopt( $ch, CURLOPT_TIMEOUT, $wgGlobalCollectTimeout );
-               curl_setopt( $ch, CURLOPT_FOLLOWLOCATION, 0 );
-               curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, 0 );
-               curl_setopt( $ch, CURLOPT_POSTFIELDS, $payflow_query );
-               curl_setopt( $ch, CURLOPT_SSL_VERIFYHOST,  2 );
-               curl_setopt( $ch, CURLOPT_FORBID_REUSE, true );
-               curl_setopt( $ch, CURLOPT_POST, 1 );
-
-               // set proxy settings if necessary
-               if ( $wgPayflowGatewayUseHTTPProxy ) {
-                       curl_setopt( $ch, CURLOPT_HTTPPROXYTUNNEL, 1 );
-                       curl_setopt( $ch, CURLOPT_PROXY, 
$wgPayflowGatewayHTTPProxy );
+               
+               $headers = $this->getCurlBaseHeaders();
+               $headers[] = 'Content-Length: ' . strlen( $data );
+               
+               self::log("Sending Data: " . $data);
+               
+               $curl_opts = $this->getCurlBaseOpts();
+               $curl_opts[CURLOPT_HTTPHEADER] = $headers;
+               $curl_opts[CURLOPT_POSTFIELDS] = $data;
+               
+               foreach ($curl_opts as $option => $value){
+                       curl_setopt($ch, $option, $value);
                }
 
                // As suggested in the PayPal developer forum sample code, try 
more than once to get a response
                // in case there is a general network issue
                $i = 1;
+               
+               $return = array();
 
                while ( $i++ <= 3 ) {
-                       self::log( $data[ 'order_id' ] . ' Preparing to send 
transaction to GlobalCollect' );
-                       $result = curl_exec( $ch );
-                       $headers = curl_getinfo( $ch );
+                       self::log( $this->postdatadefaults['order_id'] . ' 
Preparing to send transaction to GlobalCollect' );
+                       $return['result'] = curl_exec( $ch );
+                       $return['headers'] = curl_getinfo( $ch );
 
-                       if ( $headers['http_code'] != 200 && 
$headers['http_code'] != 403 ) {
-                               self::log( $data[ 'order_id' ] . ' Failed 
sending transaction to GlobalCollect, retrying' );
+                       if ( $return['headers']['http_code'] != 200 && 
$return['headers']['http_code'] != 403 ) {
+                               self::log( $this->postdatadefaults['order_id'] 
. ' Failed sending transaction to GlobalCollect, retrying' );
                                sleep( 1 );
-                       } elseif ( $headers['http_code'] == 200 || 
$headers['http_code'] == 403 ) {
-                               self::log( $data[ 'order_id' ] . ' Finished 
sending transaction to GlobalCollect' );
+                       } elseif ( $return['headers']['http_code'] == 200 || 
$return['headers']['http_code'] == 403 ) {
+                               self::log( $this->postdatadefaults['order_id'] 
. ' Finished sending transaction to GlobalCollect' );
                                break;
                        }
                }
 
-               if ( $headers['http_code'] != 200 ) {
-                       $wgOut->addHTML( '<h3>No response from credit card 
processor.  Please try again later!</h3><p>' );
+               if ( $return['headers']['http_code'] != 200 ) {
+                       $return['result'] = false;
+                       //TODO: i18n here! 
+                       $return['message'] = 'No response from credit card 
processor.  Please try again later!';
                        $when = time();
-                       self::log( $data[ 'order_id' ] . ' No response from 
credit card processor: ' . curl_error( $ch ) );
+                       self::log( $this->postdatadefaults['order_id'] . ' No 
response from credit card processor: ' . curl_error( $ch ) );
                        curl_close( $ch );
-                       return;
+                       return $return;
                }
 
                curl_close( $ch );
+               self::log("Results: " . print_r($return['result'], true));      
        
+               
+//             if ($this->getCommunicationType() === 'namevalue'){
+//                     $return['result'] = strstr( $return['result'], 'RESULT' 
);
+//                     //TODO: Finish this for namevalue. 
+//             }
+               if ($this->getCommunicationType() === 'xml'){
+                       //$return['result'] = 
$this->stripResponseHeaders($return['result']);
+                       $return['status'] = 
$this->parseXMLResponse($return['result']);
+               }
+               
+               return $return;
 
-               // get result string
-               $result = strstr( $result, 'RESULT' );
-
                // parse string and display results to the user
-               $this->fnPayflowGetResults( $data, $result );
+               //TODO: NO NO NO. NO DISPLAY HERE. 
+               //$this->fnPayflowGetResults( $data, $return['result'] );
        }
+       
+       function parseXMLResponse($rawResponse){
+               //TODO: Something.
+               $rawXML = $this->stripResponseHeaders($rawResponse);
+               if ($rawXML === false){
+                       return false;
+               }
+               $realXML = new DomDocument('1.0');
+               self::log("Here is the Raw XML: " . $rawXML);
+               $realXML->loadXML(trim($rawXML));
 
+               $aok = true;
+               
+               //find the node specified by the transaction structure. 
+               //TODO: Error handling, because: Ugh. 
+               $result_structure = 
$this->transactions[$this->currentTransaction()]['result']; 
+               if(is_array($result_structure)){
+                       foreach ($result_structure as $key=>$value){ //should 
only be one. 
+                               foreach($realXML->getElementsByTagName($key) as 
$node) {
+                                       if ($value === 'value') { //...stupid. 
But it's 'value' as opposed to 'attribute'
+                                               if 
(array_key_exists($node->nodeValue, $this->return_value_map) && 
$this->return_value_map[$node->nodeValue] !==  true){
+                                                       $aok = false;
+                                               }                               
                
+                                       }
+                                       if ($value === 'attribute') {
+                                               //TODO: Figure this out. This 
should mean the key name of one array up, which sounds painful.
+                                       }
+                                       if (is_array($value)){
+                                               //TODO: ...this is looking like 
a recursive deal, here. Again. So do that. 
+                                       }
+                               }
+                       }
+               }
+               
+               //TODO: Make this... you know: abstracty.
+               if ($aok === false){
+                       foreach($realXML->getElementsByTagName('ERROR') as 
$node) {
+                               $errdata = '';
+                               foreach($node->childNodes as $childnode){
+                                       $errdata .= "\n" . $childnode->nodeName 
. " " . $childnode->nodeValue;
+//                                     if ($childnode->nodeName == "CODE"){
+//                                             //Excellent place to deal with 
the particular codes if we want to.
+//                                     }
+                               }
+                               self::log("ON NOES! ERROR: $errdata");
+                       }
+               } else {
+                       self::log("Response OK");
+               }
+               
+               //TODO: The bit where you strip all the response data that we 
might want to save, toss it into an array, and hand it back.
+               //We need to be handing more back here than just the... success 
or failure. Things need to be processed! I mean, probably.
+               
 
+               return $aok;
+       }
 
+       function stripResponseHeaders($rawResponse){
+               $xmlStart = strpos($rawResponse, '<?xml');
+               if ($xmlStart == false){ //I totally saw this happen one time. 
No XML, just <RESPONSE>...
+                       $xmlStart = strpos($rawResponse, '<RESPONSE');
+               }
+               if ($xmlStart == false){ //Still false. Your Head Asplode.
+                       self::log("Wow, that was so messed up I couldn't even 
parse the response, so here's the thing in its entirety:\n" . $rawResponse, 
true);
+                       return false;
+               }
+               $justXML = substr($rawResponse, $xmlStart);
+               return $justXML;
+       }
+       
+       
+       public static function log( $msg, $identifier='globalcollect_gateway', 
$log_level=LOG_INFO ) {
+               global $wgGlobalCollectGatewayUseSyslog;
+               
+               // if we're not using the syslog facility, use wfDebugLog
+               if ( !$wgGlobalCollectGatewayUseSyslog ) {
+                       wfDebugLog( $identifier, $msg );
+                       return;
+               }
+               
+               // otherwise, use syslogging
+               openlog( $identifier, LOG_ODELAY, LOG_SYSLOG );
+               syslog( $log_level, $msg );
+               closelog();     
+       }
 
 
+       //_______________________________________________________________
+       //copied from  payflowpro_gateway/includes/payflowUser.inc
 
-//_______________________________________________________________
-//copied from  payflowpro_gateway/includes/payflowUser.inc
+       /**
+        * Fetch and return the 'order_id' for a transaction
+        * 
+        * Since transactions to PayPal are initially matched internally on 
their end
+        * with the 'order_id' field, but we don't actually care what the order 
id is,
+        * we generate a sufficiently random number to avoid duplication. 
+        * 
+        * We go ahead and always generate a random order id becuse if PayPal 
detects
+        * the same order_id more than once, it considers the request a 
duplicate, even
+        * if the data is completely different.
+        * 
+        * @return int
+        */
+       function getOrderId() {
+               return $this->generateOrderId();
+       }
 
-/**
- * Fetch and return the 'order_id' for a transaction
- * 
- * Since transactions to PayPal are initially matched internally on their end
- * with the 'order_id' field, but we don't actually care what the order id is,
- * we generate a sufficiently random number to avoid duplication. 
- * 
- * We go ahead and always generate a random order id becuse if PayPal detects
- * the same order_id more than once, it considers the request a duplicate, even
- * if the data is completely different.
- * 
- * @return int
- */
-function getOrderId() {
-       return $this->generateOrderId();
-}
+       /**
+        * Generate an internal order id
+        * 
+        * This is only used internally for tracking a user's 'session' with 
the credit
+        * card form.  I mean 'session' in the sense of the moment a credit 
card page
+        * is loaded for the first time (nothing posted to it - a discrete 
donation 
+        * session) as opposed to the $_SESSION - as the $_SESSION id could 
potentially
+        * not change between contribution attempts.
+        */
+       function getInternalOrderId() {
+               global $wgRequest;
 
-/**
- * Generate an internal order id
- * 
- * This is only used internally for tracking a user's 'session' with the credit
- * card form.  I mean 'session' in the sense of the moment a credit card page
- * is loaded for the first time (nothing posted to it - a discrete donation 
- * session) as opposed to the $_SESSION - as the $_SESSION id could potentially
- * not change between contribution attempts.
- */
-function getInternalOrderId() {
-       global $wgRequest;
-       
-       // is an order_id already set?
-       //TODO: Change all these to look instead at $this->postdata... I think.
-       $i_order_id = $wgRequest->getText( 'i_order_id', 0 );
-       
-       // if the form was not just posted OR there's no order_id set, generate 
one.
-       if ( !$wgRequest->wasPosted() || !$i_order_id ) {
-               $i_order_id = $this->generateOrderId();
+               // is an order_id already set?
+               //TODO: Change all these to look instead at $this->postdata... 
I think.
+               $i_order_id = $wgRequest->getText( 'i_order_id', 0 );
+
+               // if the form was not just posted OR there's no order_id set, 
generate one.
+               if ( !$wgRequest->wasPosted() || !$i_order_id ) {
+                       $i_order_id = $this->generateOrderId();
+               }
+
+               return $i_order_id;
        }
 
-       return $i_order_id;
+       /**
+        * Generate an order id
+        */
+       function generateOrderId() {
+               return (double) microtime() * 1000000 . mt_rand(1000, 9999);
+       }
 }
-
-/**
- * Generate an order id
- */
-function generateOrderId() {
-       return (double) microtime() * 1000000 . mt_rand();
-}
-}
\ No newline at end of file

Modified: 
branches/fundraising/extensions/DonationInterface/globalcollect_gateway/globalcollect_gateway.body.php
===================================================================
--- 
branches/fundraising/extensions/DonationInterface/globalcollect_gateway/globalcollect_gateway.body.php
      2011-08-30 22:29:06 UTC (rev 95820)
+++ 
branches/fundraising/extensions/DonationInterface/globalcollect_gateway/globalcollect_gateway.body.php
      2011-08-30 23:27:19 UTC (rev 95821)
@@ -104,6 +104,17 @@
                // track the number of attempts the user has made
                $numAttempt = $wgRequest->getVal( 'numAttempt', 0 );
 
+               
+               
+               
+               
+               
+               
+               
+               
+               
+               
+               
                // Get array of default account values necessary for Payflow
 //             require_once( 'includes/payflowUser.inc' );
 
@@ -150,29 +161,17 @@
 
                // Populate form data
 //             $data = $this->fnGetFormData( $amount, $numAttempt, $token, 
$payflow_data['order_id'], $payflow_data['i_order_id'] );
-               $data = $this->fnGetFormData( $amount, $numAttempt, null, null, 
null );
 
-                                       
-               //This is just me screwing around. 
-               $dir = dirname( __FILE__ ) . '/';
-               require_once($dir . 'globalcollect.adapter.php');
-               $adapter = new GlobalCollectAdapter($data);
-               error_log(print_r($data, true));
-               error_log($adapter->buildRequestXML( 'INSERT_ORDERWITHPAYMENT' 
));
-               //$wgOut->addHTML('<pre>' . $adapter->buildRequestXML( 
'INSERT_ORDERWITHPAYMENT' ) . '</pre>');
                
                
-               /**
-                *  handle PayPal redirection
-                *
-                *  if paypal redirection is enabled 
($wgPayflowGatewayPaypalURL must be defined)
-                *  and the PaypalRedirect form value must be true
-                */
-               if ( $wgRequest->getText( 'PaypalRedirect', 0 ) ) {
-                       $this->paypalRedirect( $data );
-                       return;
-               }
+               
+               
+               
+               
+               
+               $data = $this->fnGetFormData( $amount, $numAttempt, null, null, 
null );
 
+               
                // dispatch forms/handling
 //             if ( $token_match ) {
                        if ( $data['payment_method'] == 'processed' ) {
@@ -187,40 +186,55 @@
                                        $this->fnPayflowDisplayForm( $data, 
$this->errors );
                                } else { // The submitted form data is valid, 
so process it
                                        // allow any external validators to 
have their way with the data
-                                       self::log( $data[ 'order_id' ] . " 
Preparing to query MaxMind" );
-                                       wfRunHooks( 'PayflowGatewayValidate', 
array( &$this, &$data ) );
-                                       self::log( $data[ 'order_id' ] . ' 
Finished querying Maxmind' );
-
-                                       // if the transaction was flagged for 
review
-                                       if ( $this->action == 'review' ) {
-                                               // expose a hook for external 
handling of trxns flagged for review
-                                               wfRunHooks( 
'PayflowGatewayReview', array( &$this, &$data ));
-                                       }
-
-                                       // if the transaction was flagged to be 
'challenged'
-                                       if ( $this->action == 'challenge' ) {
-                                               // expose a hook for external 
handling of trxns flagged for challenge (eg captcha)
-                                               wfRunHooks( 
'PayflowGatewayChallenge', array( &$this, &$data ) );
-                                       }
-
-                                       // if the transaction was flagged for 
rejection
-                                       if ( $this->action == 'reject' ) {
-                                               // expose a hook for external 
handling of trxns flagged for rejection
-                                               wfRunHooks( 
'PayflowGatewayReject', array( &$this, &$data ) );
-
-                                               
$this->fnPayflowDisplayDeclinedResults( '' );
-                                               
$this->fnPayflowUnsetEditToken();
-                                       }
-
-                                       // if the transaction was flagged for 
processing
-                                       if ( $this->action == 'process' ) {
-                                               // expose a hook for external 
handling of trxns ready for processing
-                                               wfRunHooks( 
'PayflowGatewayProcess', array( &$this, &$data ) );
-                                               
$this->fnGlobalCollectProcessTransaction( $data, $payflow_data );
-                                       }
-
-                                       // expose a hook for any post processing
-                                       wfRunHooks( 
'PayflowGatewayPostProcess', array( &$this, &$data ) );
+                                       
+                                       
+                                       
+                                       //This is just me screwing around. 
+                                       $dir = dirname( __FILE__ ) . '/';
+                                       require_once($dir . 
'globalcollect.adapter.php');
+                                       $adapter = new 
GlobalCollectAdapter($data);
+                                       self::log("Data used for adapter init: 
" . print_r($data, true));
+                                       $result = $adapter->do_transaction( 
'INSERT_ORDERWITHPAYMENT' );
+                                       //$result = $adapter->do_transaction( 
'TEST_CONNECTION' );
+                                       
+                                       $wgOut->addHTML($result['message']);
+               
+               
+                                       
+//                                     self::log( $data[ 'order_id' ] . " 
Preparing to query MaxMind" );
+//                                     wfRunHooks( 'PayflowGatewayValidate', 
array( &$this, &$data ) );
+//                                     self::log( $data[ 'order_id' ] . ' 
Finished querying Maxmind' );
+//
+//                                     // if the transaction was flagged for 
review
+//                                     if ( $this->action == 'review' ) {
+//                                             // expose a hook for external 
handling of trxns flagged for review
+//                                             wfRunHooks( 
'PayflowGatewayReview', array( &$this, &$data ));
+//                                     }
+//
+//                                     // if the transaction was flagged to be 
'challenged'
+//                                     if ( $this->action == 'challenge' ) {
+//                                             // expose a hook for external 
handling of trxns flagged for challenge (eg captcha)
+//                                             wfRunHooks( 
'PayflowGatewayChallenge', array( &$this, &$data ) );
+//                                     }
+//
+//                                     // if the transaction was flagged for 
rejection
+//                                     if ( $this->action == 'reject' ) {
+//                                             // expose a hook for external 
handling of trxns flagged for rejection
+//                                             wfRunHooks( 
'PayflowGatewayReject', array( &$this, &$data ) );
+//
+//                                             
$this->fnPayflowDisplayDeclinedResults( '' );
+//                                             
$this->fnPayflowUnsetEditToken();
+//                                     }
+//
+//                                     // if the transaction was flagged for 
processing
+//                                     if ( $this->action == 'process' ) {
+//                                             // expose a hook for external 
handling of trxns ready for processing
+//                                             wfRunHooks( 
'PayflowGatewayProcess', array( &$this, &$data ) );
+//                                             
$this->fnGlobalCollectProcessTransaction( $data, $payflow_data );
+//                                     }
+//
+//                                     // expose a hook for any post processing
+//                                     wfRunHooks( 
'PayflowGatewayPostProcess', array( &$this, &$data ) );
                                }
                        } else {
                                // Display form for the first time
@@ -361,122 +375,15 @@
                } elseif ( preg_match( '/^6(?:011|5[0-9]{2})[0-9]{12}$/', 
$data[ 'card_num' ] ) ) { // discover
                        $data[ 'card' ] = 'discover';
                } else { // an invalid credit card number was entered
-                       $error_result = '1';
-                       $error[ 'card_num' ] = wfMsg( 
'globalcollect_gateway-error-msg-card-num' );
+               //TODO: Make sure this is uncommented when you commit for 
reals! 
+                       //$error_result = '1';
+                       //$error[ 'card_num' ] = wfMsg( 
'globalcollect_gateway-error-msg-card-num' );
                }
                
                return $error_result;
        }
 
        /**
-        * Sends a name-value pair string to Payflow gateway
-        *
-        * @param $data Array: array of user input
-        * @param $payflow_data Array: array of necessary Payflow variables to
-        *                                              include in string (i.e. 
Vendor, password)
-        */
-       private function fnGlobalCollectProcessTransaction( $data, 
$payflow_data ) {
-               global $wgOut, $wgDonationTestingMode, 
$wgPayflowGatewayUseHTTPProxy, $wgPayflowGatewayHTTPProxy, 
$wgGlobalCollectTimeout;
-
-               // update contribution tracking
-               $this->updateContributionTracking( $data, defined( 'OWA' ) );
-
-               // create payflow query string, include string lengths
-               $queryArray = array(
-                       'TRXTYPE' => $payflow_data['trxtype'],
-                       'TENDER'  => $payflow_data['tender'],
-                       'USER'  => $payflow_data['user'],
-                       'VENDOR' => $payflow_data['vendor'],
-                       'PARTNER' => $payflow_data['partner'],
-                       'PWD' => $payflow_data['password'],
-                       'ACCT'  => $data['card_num'],
-                       'EXPDATE' => $data['expiration'],
-                       'AMT' => $data['amount'],
-                       'FIRSTNAME' => $data['fname'],
-                       'LASTNAME' => $data['lname'],
-                       'STREET' => $data['street'],
-                       'CITY' => $data['city'],
-                       'STATE' => $data['state'],
-                       'COUNTRY' => $data['country'],
-                       'ZIP' => $data['zip'],
-                       'INVNUM' => $data['order_id'],
-                       'CVV2' => $data['cvv'],
-                       'CURRENCY' => $data['currency'],
-                       'VERBOSITY' => $payflow_data['verbosity'],
-                       'CUSTIP' => $payflow_data['user_ip'],
-               );
-
-               foreach ( $queryArray as $name => $value ) {
-                       $query[] = $name . '[' . strlen( $value ) . ']=' . 
$value;
-               }
-
-               $queryString = implode( '&', $query );
-
-               $payflow_query = $queryString;
-
-               // assign header data necessary for the curl_setopt() function
-               $user_agent = Http::userAgent();
-               $headers[] = 'Content-Type: text/namevalue';
-               $headers[] = 'Content-Length : ' . strlen( $payflow_query );
-               $headers[] = 'X-VPS-Client-Timeout: 45';
-               $headers[] = 'X-VPS-Request-ID:' . $data['order_id'];
-               $ch = curl_init();
-               $paypalPostTo = isset ( $wgDonationTestingMode ) ? 'testingurl' 
: 'paypalurl';
-               curl_setopt( $ch, CURLOPT_URL, $payflow_data[ $paypalPostTo ] );
-               curl_setopt( $ch, CURLOPT_HTTPHEADER, $headers );
-               curl_setopt( $ch, CURLOPT_USERAGENT, $user_agent );
-               curl_setopt( $ch, CURLOPT_HEADER, 1 );
-               curl_setopt( $ch, CURLOPT_RETURNTRANSFER, 1 );
-               curl_setopt( $ch, CURLOPT_TIMEOUT, $wgGlobalCollectTimeout );
-               curl_setopt( $ch, CURLOPT_FOLLOWLOCATION, 0 );
-               curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, 0 );
-               curl_setopt( $ch, CURLOPT_POSTFIELDS, $payflow_query );
-               curl_setopt( $ch, CURLOPT_SSL_VERIFYHOST,  2 );
-               curl_setopt( $ch, CURLOPT_FORBID_REUSE, true );
-               curl_setopt( $ch, CURLOPT_POST, 1 );
-
-               // set proxy settings if necessary
-               if ( $wgPayflowGatewayUseHTTPProxy ) {
-                       curl_setopt( $ch, CURLOPT_HTTPPROXYTUNNEL, 1 );
-                       curl_setopt( $ch, CURLOPT_PROXY, 
$wgPayflowGatewayHTTPProxy );
-               }
-
-               // As suggested in the PayPal developer forum sample code, try 
more than once to get a response
-               // in case there is a general network issue
-               $i = 1;
-
-               while ( $i++ <= 3 ) {
-                       self::log( $data[ 'order_id' ] . ' Preparing to send 
transaction to GlobalCollect' );
-                       $result = curl_exec( $ch );
-                       $headers = curl_getinfo( $ch );
-
-                       if ( $headers['http_code'] != 200 && 
$headers['http_code'] != 403 ) {
-                               self::log( $data[ 'order_id' ] . ' Failed 
sending transaction to GlobalCollect, retrying' );
-                               sleep( 1 );
-                       } elseif ( $headers['http_code'] == 200 || 
$headers['http_code'] == 403 ) {
-                               self::log( $data[ 'order_id' ] . ' Finished 
sending transaction to GlobalCollect' );
-                               break;
-                       }
-               }
-
-               if ( $headers['http_code'] != 200 ) {
-                       $wgOut->addHTML( '<h3>No response from credit card 
processor.  Please try again later!</h3><p>' );
-                       $when = time();
-                       self::log( $data[ 'order_id' ] . ' No response from 
credit card processor: ' . curl_error( $ch ) );
-                       curl_close( $ch );
-                       return;
-               }
-
-               curl_close( $ch );
-
-               // get result string
-               $result = strstr( $result, 'RESULT' );
-
-               // parse string and display results to the user
-               $this->fnPayflowGetResults( $data, $result );
-       }
-
-       /**
         * "Reads" the name-value pair result string returned by Payflow and 
creates corresponding error messages
         *
         * @param $data Array: array of user input
@@ -1294,10 +1201,10 @@
        }
        
        public static function log( $msg, $identifier='globalcollect_gateway', 
$log_level=LOG_INFO ) {
-               global $wgPayflowGatewayUseSyslog;
+               global $wgGlobalCollectGatewayUseSyslog;
                
                // if we're not using the syslog facility, use wfDebugLog
-               if ( !$wgPayflowGatewayUseSyslog ) {
+               if ( !$wgGlobalCollectGatewayUseSyslog ) {
                        wfDebugLog( $identifier, $msg );
                        return;
                }

Modified: 
branches/fundraising/extensions/DonationInterface/globalcollect_gateway/globalcollect_gateway.php
===================================================================
--- 
branches/fundraising/extensions/DonationInterface/globalcollect_gateway/globalcollect_gateway.php
   2011-08-30 22:29:06 UTC (rev 95820)
+++ 
branches/fundraising/extensions/DonationInterface/globalcollect_gateway/globalcollect_gateway.php
   2011-08-30 23:27:19 UTC (rev 95821)
@@ -18,6 +18,8 @@
         'url' => 
'http://www.mediawiki.org/wiki/Extension:GlobalCollectGateway',
 );
 
+$wgGlobalCollectGatewayUseSyslog = false;
+
 // Set up the new special page
 $dir = dirname( __FILE__ ) . '/';
 $wgAutoloadClasses['GlobalCollectGateway'] = $dir . 
'globalcollect_gateway.body.php';
@@ -50,15 +52,15 @@
 
 // set defaults, these should be assigned in LocalSettings.php
 $wgGlobalCollectURL = 'https://ps.gcsip.nl/wdl/wdl';
-//$wgGlobalCollectTestingURL = 'https://pilot-globalcollect.paypal.com'; // 
GlobalCollect testing URL
+$wgGlobalCollectTestingURL = 'https://'; // GlobalCollect testing URL
 
 $wgGlobalCollectMerchantID = ''; // GlobalCollect ID
 
 // a boolean to determine if we're in testing mode
 $wgGlobalCollectGatewayTest = FALSE;
 
-// timeout in seconds for communicating with paypal
-$wgGlobalCollectTimeout = 5;
+// timeout in seconds for communicating with [gateway]
+$wgGlobalCollectTimeout = 2;
 
 /**
  * The default form to use
@@ -131,13 +133,6 @@
 $wgGlobalCollectAllowedHtmlForms = array(      $wgGlobalCollectHtmlFormDir . 
"/demo.html" );
 
 /**
- * Configure GlobalCollectproGateway to use syslog for log messages rather 
than wfDebugLog
- * 
- * @var bool
- */
-$wgGlobalCollectGatewayUseSyslog = false;
-
-/**
  * Configure price cieling and floor for valid contribution amount.  Values 
  * should be in USD.
  */


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

Reply via email to