r97106 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r97105‎ | r97106 | r97107 >
Date:22:09, 14 September 2011
Author:khorn
Status:resolved (Comments)
Tags:fundraising 
Comment:
DonationInterface's GlobalCollect gateway can now post server-side through existing forms. (Though doing so would certainly be Bad if the forms we're using have credit card fields... but it's okay for testing purposes until we have more gateway-specific forms and a working whitelist)
Modified paths:
  • /branches/fundraising/extensions/DonationInterface/donationinterface.php (modified) (history)
  • /branches/fundraising/extensions/DonationInterface/gateway_common/DonationData.php (modified) (history)
  • /branches/fundraising/extensions/DonationInterface/gateway_common/gateway.adapter.php (modified) (history)
  • /branches/fundraising/extensions/DonationInterface/globalcollect_gateway/globalcollect.adapter.php (modified) (history)
  • /branches/fundraising/extensions/DonationInterface/globalcollect_gateway/globalcollect_gateway.body.php (modified) (history)
  • /branches/fundraising/extensions/DonationInterface/modules (added) (history)
  • /branches/fundraising/extensions/DonationInterface/modules/jquery.donationInterface.js (added) (history)
  • /branches/fundraising/extensions/DonationInterface/payflowpro_gateway/payflowpro_gateway.php (modified) (history)

Diff [purge]

Index: branches/fundraising/extensions/DonationInterface/donationinterface.php
@@ -89,6 +89,17 @@
9090 # Unit tests
9191 $wgHooks['UnitTestsList'][] = 'efDonationInterfaceUnitTests';
9292
 93+//
 94+//// Resource modules
 95+//$wgResourceTemplate = array(
 96+// 'localBasePath' => $donationinterface_dir . 'modules',
 97+// 'remoteExtPath' => 'DonationInterface/modules',
 98+//);
 99+//$wgResourceModules['jquery.donationInterface'] = array(
 100+// 'scripts' => 'jquery.donationInterface.js',
 101+// 'dependencies' => 'jquery.json',
 102+//) + $wgResourceTemplate;
 103+
93104 function efDonationInterfaceUnitTests( &$files ) {
94105 $files[] = dirname( __FILE__ ) . '/tests/GatewayAdapterTest.php';
95106 $files[] = dirname( __FILE__ ) . '/tests/DonationDataTest.php';
Index: branches/fundraising/extensions/DonationInterface/payflowpro_gateway/payflowpro_gateway.php
@@ -174,7 +174,7 @@
175175 /**
176176 * Hook to supply the page address of the payment gateway
177177 *
178 - * The user will be redirected here with supplied data with input data appended (GET).
 178+ * The user will redirected here with supplied data with input data appended (GET).
179179 * For example, if $url[$key] = index.php?title=Special:PayflowProGateway
180180 * the result might look like this: http://www.yourdomain.com/index.php?title=Special:PayflowProGateway&amount=75.00&currency_code=USD&payment_method=payflow
181181 */
Index: branches/fundraising/extensions/DonationInterface/globalcollect_gateway/globalcollect_gateway.body.php
@@ -20,7 +20,7 @@
2121 * Holds the GlobalCollect response from a transaction
2222 * @var array
2323 */
24 - public $payflow_response = array();
 24+ public $payflow_response = array( );
2525
2626 /**
2727 * A container for the form class
@@ -34,7 +34,7 @@
3535 * An array of form errors
3636 * @var array
3737 */
38 - public $errors = array();
 38+ public $errors = array( );
3939
4040 /**
4141 * Constructor - set up the new special page
@@ -53,7 +53,7 @@
5454 */
5555 public function execute( $par ) {
5656 global $wgRequest, $wgOut, $wgExtensionAssetsPath,
57 - $wgPayFlowProGatewayCSSVersion;
 57+ $wgPayFlowProGatewayCSSVersion;
5858
5959 $wgOut->addExtensionStyle(
6060 $wgExtensionAssetsPath . '/DonationInterface/gateway_forms/css/gateway.css?284' .
@@ -90,9 +90,9 @@
9191 </script>
9292 EOT;
9393 $wgOut->addHeadItem( 'logolinkoverride', $js );
94 -
 94+
9595 $this->setHeaders();
96 -
 96+
9797 //TODO: This is short-circuiting what I really want to do here.
9898 //so stop it.
9999 $data = $this->adapter->getDisplayData();
@@ -116,45 +116,44 @@
117117 // allow any external validators to have their way with the data
118118 $result = $this->adapter->do_transaction( 'INSERT_ORDERWITHPAYMENT' );
119119 //$result = $this->adapter->do_transaction( 'TEST_CONNECTION' );
120 -
121 - if (!empty($result['errors'])){
122 - $wgOut->addHTML("<ul>");
123 - foreach ($result['errors'] as $code => $value){
124 - $wgOut->addHTML("<li>Error $code: $value");
 120+
 121+ $wgOut->addHTML( $result['message'] );
 122+ if ( !empty( $result['errors'] ) ) {
 123+ $wgOut->addHTML( "<ul>" );
 124+ foreach ( $result['errors'] as $code => $value ) {
 125+ $wgOut->addHTML( "<li>Error $code: $value" );
125126 }
126 - $wgOut->addHTML("</ul>");
 127+ $wgOut->addHTML( "</ul>" );
127128 }
128 -
129 - if (!empty($result['data'])){
130 - // Create new page here with iframe.
131 - $paymentFrame = Xml::openElement( 'iframe',
132 - array(
133 - 'id' => 'globalcollectframe',
134 - 'name' => 'globalcollectframe',
135 - 'width' => '680',
136 - 'height' => '300',
137 - 'frameborder' => '0',
138 - 'style' => 'display:block;',
139 - 'src' => $result['data']['FORMACTION']
140 - )
141 - );
142 - $paymentFrame .= Xml::closeElement( 'iframe' );
 129+
 130+ if ( !empty( $result['data'] ) ) {
 131+ $wgOut->addHTML( "<ul>" );
 132+ foreach ( $result['data'] as $key => $value ) {
 133+ $wgOut->addHTML( "<li>$key: $value" );
 134+ }
 135+ $wgOut->addHTML( "</ul>" );
143136
144 - $wgOut->addHTML( $paymentFrame );
145 - }
146 -
147 - /*
148 - $wgOut->addHTML($result['message']);
149 - if (!empty($result['data'])){
150 - $wgOut->addHTML("<ul>");
151 - foreach ($result['data'] as $key => $value){
152 - $wgOut->addHTML("<li>$key: $value");
 137+ if (array_key_exists('FORMACTION', $result['data'])){
 138+ $paymentFrame = Xml::openElement( 'iframe',
 139+ array(
 140+ 'id' => 'globalcollectframe',
 141+ 'name' => 'globalcollectframe',
 142+ 'width' => '680',
 143+ 'height' => '300',
 144+ 'frameborder' => '0',
 145+ 'style' => 'display:block;',
 146+ 'src' => $result['data']['FORMACTION']
 147+ )
 148+ );
 149+ $paymentFrame .= Xml::closeElement( 'iframe' );
 150+
 151+ $wgOut->addHTML( $paymentFrame );
 152+
153153 }
154 - $wgOut->addHTML("</ul>");
155154 }
156 - */
157155
158156
 157+
159158 // self::log( $data[ 'order_id' ] . " Preparing to query MaxMind" );
160159 // wfRunHooks( 'PayflowGatewayValidate', array( &$this, &$data ) );
161160 // self::log( $data[ 'order_id' ] . ' Finished querying Maxmind' );
@@ -348,7 +347,7 @@
349348 */
350349 private function fnPayflowGetResults( $data, $result ) {
351350 // prepare NVP response for sorting and outputting
352 - $responseArray = array();
 351+ $responseArray = array( );
353352
354353 /**
355354 * The result response string looks like:
@@ -474,7 +473,7 @@
475474 public function prepareStompTransaction( $data, $responseArray, $responseMsg ) {
476475 $countries = $this->getCountries();
477476
478 - $transaction = array();
 477+ $transaction = array( );
479478
480479 // include response message
481480 $transaction['response'] = $responseMsg;
Index: branches/fundraising/extensions/DonationInterface/globalcollect_gateway/globalcollect.adapter.php
@@ -12,6 +12,25 @@
1313 */
1414 function stageData() {
1515 $this->postdata['amount'] = $this->postdata['amount'] * 100;
 16+
 17+ switch ( $this->postdata['card_type'] ) {
 18+ case 'visa':
 19+ $this->postdata['card_type'] = 1;
 20+ break;
 21+ case 'mastercard':
 22+ $this->postdata['card_type'] = 3;
 23+ break;
 24+ case 'american':
 25+ $this->postdata['card_type'] = 2;
 26+ break;
 27+ case 'discover':
 28+ $this->postdata['card_type'] = 128;
 29+ break;
 30+ }
 31+
 32+ $this->postdata['expiry'] = $this->postdata['expiration']; //. ($this->postdata['year'] % 100);
 33+ $this->postdata['card_num'] = str_replace(' ', '', $this->postdata['card_num']);
 34+
1635 }
1736
1837 function defineAccountInfo() {
@@ -32,6 +51,17 @@
3352 'MERCHANTREFERENCE' => 'order_id',
3453 'RETURNURL' => 'returnto', //TODO: Fund out where the returnto URL is supposed to be coming from.
3554 'IPADDRESS' => 'user_ip', //TODO: Not sure if this should be OUR ip, or the user's ip. Hurm.
 55+ 'PAYMENTPRODUCTID' => 'card_type',
 56+ 'CVV' => 'cvv',
 57+ 'EXPIRYDATE' => 'expiry',
 58+ 'CREDITCARDNUMBER' => 'card_num',
 59+ 'FIRSTNAME' => 'fname',
 60+ 'SURNAME' => 'lname',
 61+ 'STREET' => 'street',
 62+ 'CITY' => 'city',
 63+ 'STATE' => 'state',
 64+ 'ZIP' => 'zip',
 65+ 'EMAIL' => 'email',
3666 );
3767 }
3868
@@ -71,14 +101,23 @@
72102 'COUNTRYCODE',
73103 'HOSTEDINDICATOR',
74104 'RETURNURL',
 105+ 'CVV',
 106+ 'EXPIRYDATE',
 107+ 'CREDITCARDNUMBER',
 108+ 'FIRSTNAME',
 109+ 'SURNAME',
 110+ 'STREET',
 111+ 'CITY',
 112+ 'STATE',
 113+ 'ZIP',
 114+ 'EMAIL',
75115 )
76116 )
77117 )
78118 ),
79119 'values' => array(
80120 'ACTION' => 'INSERT_ORDERWITHPAYMENT',
81 - 'HOSTEDINDICATOR' => '1',
82 - 'PAYMENTPRODUCTID' => '3',
 121+ 'HOSTEDINDICATOR' => '1'
83122 ),
84123 );
85124
@@ -165,6 +204,24 @@
166205 }
167206 }
168207 }
 208+
 209+ foreach ( $response->getElementsByTagName( 'ORDER' ) as $node ) {
 210+ foreach ( $node->childNodes as $childnode ) {
 211+ if ( trim( $childnode->nodeValue ) != '' ) {
 212+ $data['RequestOrder-' . $childnode->nodeName] = $childnode->nodeValue;
 213+ }
 214+ }
 215+ }
 216+
 217+ foreach ( $response->getElementsByTagName( 'PAYMENT' ) as $node ) {
 218+ foreach ( $node->childNodes as $childnode ) {
 219+ if ( trim( $childnode->nodeValue ) != '' ) {
 220+ $data['RequestPayment-' . $childnode->nodeName] = $childnode->nodeValue;
 221+ }
 222+ }
 223+ }
 224+
 225+
169226 self::log( "Returned Data: " . print_r( $data, true ) );
170227 return $data;
171228 }
Index: branches/fundraising/extensions/DonationInterface/modules/jquery.donationInterface.js
@@ -0,0 +1,214 @@
 2+/**
 3+ * Turns any form with the bare minimum "appropriate" fields into a form that
 4+ * can get a donor to a gateway with no interstitial page.
 5+ * To use:
 6+ * *) Install the ContributionTracking Extension.
 7+ * *) Include this module on a page.
 8+ * *) On that page, create a form that contains (at least) the fields
 9+ * required by ApiContributionTracking.
 10+ * *) Make sure that form's submit button has a unique ID.
 11+ * *) Assign that button the class of "ajax_me".
 12+ *
 13+ * @author Katie Horn <khorn@wikimedia.org>
 14+ */
 15+
 16+( function( $ ) {
 17+
 18+ /**
 19+ * Binds the onclick function to everything with a class of "ajax_me".
 20+ */
 21+ $.bindAjaxControls = function(){
 22+ $(".ajax_me:disabled").removeAttr("disabled");
 23+ $(".ajax_me").click(function() {
 24+ this.disabled = true;
 25+ $.goAjax(this.id);
 26+ return false; //prevent regular form submission.
 27+ //TODO: Think about the button disabling and enabling.
 28+ //TODO: also think about a barber pole. That would go here.
 29+ });
 30+ //$("form")
 31+ }
 32+
 33+ /**
 34+ * Turns the first parent form from the passing object, to an object we can
 35+ * pass to the API.
 36+ * Takes the button ID in string form.
 37+ */
 38+ $.prepareXML = function(buttonID){
 39+ buttonID = "#" + buttonID;
 40+ var form = $(buttonID).parents("form:first");
 41+ var xmlnode = $("#xml_structure");
 42+ var xml = $("#xml_structure").html();
 43+
 44+ delete form.attr( 'action' );
 45+ delete form.attr( 'method' );
 46+
 47+
 48+ //window.alert(xml);
 49+
 50+ //xmlnode.find("merchantid").html("NEW VALUE");
 51+ //window.alert( xmlnode.find("merchantid").html() );
 52+
 53+ var serializedForm = form.serializeArray();
 54+ var sendData = $.stageData(serializedForm);
 55+
 56+ //TODO: Yeah, this works, but... grow up.
 57+// for (key in sendData){
 58+// if(xml.indexOf("@" + key) > 0){
 59+// xml = xml.replace("@" + key, sendData[key]);
 60+// //finalObj[serializedForm[key]['name']] = serializedForm[key]['value'];
 61+// }
 62+// }
 63+
 64+ //Wow. The next business works. Crizzy.
 65+
 66+ $.each(xmlnode.find("order").children() , function (index) {
 67+ var keyname = $(this).text().replace("@", "");
 68+ if (sendData[keyname]){
 69+ $(this).html(sendData[keyname]);
 70+ } else {
 71+ $(this).remove();
 72+ }
 73+ });
 74+ $.each(xmlnode.find("payment").children() , function (index) {
 75+ var keyname = $(this).text().replace("@", "");
 76+ if (sendData[keyname]){
 77+ $(this).html(sendData[keyname]);
 78+ } else {
 79+ $(this).remove();
 80+ }
 81+ });
 82+
 83+
 84+ //xml = $("#xml_structure").find("request").html();
 85+ xml = $("#xml_structure").html();
 86+ window.alert(xml);
 87+ return xml;
 88+ }
 89+
 90+ $.stageData = function(serializedForm) {
 91+ var finalObj = {};
 92+
 93+ for (key in serializedForm){
 94+ if(serializedForm[key]['value'] != ""){
 95+ finalObj[serializedForm[key]['name']] = serializedForm[key]['value'];
 96+ }
 97+ }
 98+
 99+ if (finalObj['emailAdd']){
 100+ finalObj['email'] = finalObj['emailAdd'];
 101+ delete finalObj['emailAdd'];
 102+ }
 103+
 104+ finalObj['amount'] = finalObj['amount'] * 100;
 105+ //do the rest of the staging here.
 106+
 107+ $.debugPostObjectWithAlert(finalObj);
 108+
 109+ return finalObj;
 110+ }
 111+
 112+ $(document).ajaxError(function(event, request, settings, thrown){
 113+ var display = '';
 114+ for (key in event){
 115+ display += "event " + key + " : " + event[key] + "\r\n";
 116+ }
 117+ for (key in event['data']){
 118+ display += "event data " + key + " : " + event[key] + "\r\n";
 119+ }
 120+ for (key in request){
 121+ display += "request " + key + " : " + event[key] + "\r\n";
 122+ }
 123+ for (key in settings){
 124+ display += "settings " + key + " : " + event[key] + "\r\n";
 125+ }
 126+ for (key in thrown){
 127+ display += "thrown " + key + " : " + event[key] + "\r\n";
 128+ }
 129+ window.alert("Ajax Error!\r\n" + display);
 130+ });
 131+
 132+ $.makeAndPostForm = function (postData){
 133+ if ($('#hideyform').length){
 134+ $('#hideyform').empty(); //just in case something is already hiding in the hideyform.
 135+ } else {
 136+ $('<div id="hideyform"></div>').appendTo('body');
 137+ }
 138+ $('<form id="immediate_repost" action="https://ps.gcsip.nl/wdl/wdl" method="POST"></form>').appendTo('#hideyform');
 139+ $('<input type="hidden" id="xml" name="xml" value="' + postData +'">').appendTo('#immediate_repost');
 140+ $('#immediate_repost').submit();
 141+ window.alert("Form Submitted! Go look...");
 142+ }
 143+
 144+
 145+ /**
 146+ * Sends the formatted ajax request to the API, turns the result into a
 147+ * hidden form, and immediately posts that form on return.
 148+ * Takes the button ID in string form.
 149+ */
 150+ $.goAjax = function(buttonID) {
 151+
 152+ var postData = $.prepareXML(buttonID);
 153+ //postData.action = "contributiontracking";
 154+ $.makeAndPostForm(postData);
 155+ return false;
 156+
 157+
 158+ var processAjaxReturn = function(data, status){
 159+ //TODO: Improve the language of the success and error dialogs.
 160+
 161+ window.alert("Return! " + data);
 162+
 163+ if(status != "success"){
 164+ window.alert("Status: " + status);
 165+ $(buttonID).removeAttr("disabled");
 166+ $(".ajax_me:disabled").removeAttr("disabled");
 167+ return;
 168+ }
 169+
 170+ if(data["error"]){
 171+ //TODO: localization. And i18n. And stuff.
 172+ window.alert("The following error has occurred:\r\n" + data["error"]["info"]);
 173+ $(buttonID).removeAttr("disabled");
 174+ $(".ajax_me:disabled").removeAttr("disabled");
 175+ return;
 176+ }
 177+
 178+ if ($('#hideyform').length){
 179+ $('#hideyform').empty(); //just in case something is already hiding in the hideyform.
 180+ } else {
 181+ $('<div id="hideyform"></div>').appendTo('body');
 182+ }
 183+ $('<form id="immediate_repost" action="' + data["returns"]["action"]["url"] + '"></form>').appendTo('#hideyform');
 184+ for (key in data["returns"]["fields"]) {
 185+ $('<input type="hidden" id="' + key +'" name="' + key +'" value="' + data["returns"]["fields"][key] +'">').appendTo('#immediate_repost');
 186+ }
 187+ $('#immediate_repost').submit();
 188+
 189+ }
 190+
 191+// $.post(
 192+// //mw.config.get('wgScriptPath') + '/api.php',
 193+// 'https://ps.gcsip.nl/wdl/wdl',
 194+// //'http://ps.gcsip.nl/wdl/wdl',
 195+// //'http://www.katiehorn.com/nonsense/',
 196+// postData,
 197+// processAjaxReturn,
 198+// 'xml');
 199+ }
 200+
 201+ /**
 202+ * Just for easy debugging. Should not actually be called anywhere.
 203+ * TODO: Take this out when we know we're done here.
 204+ */
 205+ $.debugPostObjectWithAlert = function(object){
 206+ var contents = "";
 207+ for (key in object){
 208+ contents += key + " = " + object[key] + "\r\n";
 209+ }
 210+ window.alert(contents);
 211+ }
 212+
 213+} )( jQuery );
 214+
 215+$.bindAjaxControls();
\ No newline at end of file
Property changes on: branches/fundraising/extensions/DonationInterface/modules/jquery.donationInterface.js
___________________________________________________________________
Added: svn:eol-style
1216 + native
Index: branches/fundraising/extensions/DonationInterface/gateway_common/gateway.adapter.php
@@ -164,7 +164,7 @@
165165 return $gotten[$globalname];
166166 }
167167
168 - function getValue( $gateway_field_name ) {
 168+ function getValue( $gateway_field_name, $token = false ) {
169169 if ( empty( $this->transactions ) ) {
170170 //TODO: These dies should all just throw fatal errors instead.
171171 die( 'Transactions structure is empty! Aborting.' );
@@ -190,6 +190,9 @@
191191
192192 //If there's a value in the post data (name-translated by the var_map), use that.
193193 if ( array_key_exists( $gateway_field_name, $this->var_map ) ) {
 194+ if ($token === true){ //we just want the field name to use, so short-circuit all that mess.
 195+ return '@' . $this->var_map[$gateway_field_name];
 196+ }
194197 if ( array_key_exists( $this->var_map[$gateway_field_name], $this->postdata ) &&
195198 $this->postdata[$this->var_map[$gateway_field_name]] !== '' ) {
196199 //if it was sent, use that.
@@ -217,19 +220,19 @@
218221 return $this->xmlDoc->saveXML();
219222 }
220223
221 - function buildTransactionNodes( $structure, &$node ) {
 224+ function buildTransactionNodes( $structure, &$node, $js = false ) {
222225 $transaction = $this->currentTransaction();
223226
224227 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.
225 - $this->appendNodeIfValue( $structure, $node );
 228+ $this->appendNodeIfValue( $structure, $node, $js );
226229 } else {
227230 foreach ( $structure as $key => $value ) {
228231 if ( !is_array( $value ) ) {
229232 //do not use $key. $key is meaningless in this case.
230 - $this->appendNodeIfValue( $value, $node );
 233+ $this->appendNodeIfValue( $value, $node, $js );
231234 } else {
232235 $keynode = $this->xmlDoc->createElement( $key );
233 - $this->buildTransactionNodes( $value, $keynode );
 236+ $this->buildTransactionNodes( $value, $keynode, $js );
234237 $node->appendChild( $keynode );
235238 }
236239 }
@@ -237,30 +240,55 @@
238241 //not actually returning anything. It's all side-effects. Because I suck like that.
239242 }
240243
241 - function appendNodeIfValue( $value, &$node ) {
242 - $nodevalue = $this->getValue( $value );
 244+ function appendNodeIfValue( $value, &$node, $js = false ) {
 245+ $nodevalue = $this->getValue( $value, $js );
243246 if ( $nodevalue !== '' && $nodevalue !== false ) {
244247 $temp = $this->xmlDoc->createElement( $value, $nodevalue );
245248 $node->appendChild( $temp );
246249 }
247250 }
 251+
 252+ //TODO: You can actually take this out if we never ever want to use ajax for a gateway.
 253+ function buildTransactionFormat($transaction){
 254+ $this->currentTransaction( $transaction );
 255+ $this->xmlDoc = new DomDocument( '1.0' );
 256+ $node = $this->xmlDoc->createElement( 'XML' );
248257
 258+ $structure = $this->transactions[$this->currentTransaction()]['request'];
 259+
 260+ $this->buildTransactionNodes( $structure, $node, true );
 261+ $this->xmlDoc->appendChild( $node );
 262+ $xml = $this->xmlDoc->saveXML();
 263+ $xmlStart = strpos($xml, "<XML>");
 264+ self::log("XML START" . $xmlStart);
 265+ $xml = substr( $xml, $xmlStart );
 266+ self::log("XML stubby thing..." . $xml);
 267+
 268+ return $xml;
 269+ }
 270+
249271 function do_transaction( $transaction ) {
250272 $this->currentTransaction( $transaction );
251273 //update the contribution tracking data
252274 $this->dataObj->updateContributionTracking( defined( 'OWA' ) );
253275 if ( $this->getCommunicationType() === 'xml' ) {
 276+ $this->getStopwatch(__FUNCTION__);
254277 $xml = $this->buildRequestXML();
 278+ $this->saveCommunicationStats("-BuildingRequestXML");
 279+ $this->getStopwatch(__FUNCTION__, true);
255280 $returned = $this->curl_transaction( $xml );
 281+ $this->saveCommunicationStats();
256282 //put the response in a universal form, and return it.
257283 }
258284
259285 if ( $this->getCommunicationType() === 'namevalue' ) {
260286 $namevalue = $this->postdata;
 287+ $this->getStopwatch(__FUNCTION__);
261288 $returned = $this->curl_transaction( $namevalue );
 289+ $this->saveCommunicationStats();
262290 //put the response in a universal form, and return it.
263291 }
264 -
 292+
265293 self::log( "RETURNED FROM CURL:" . print_r( $returned, true ) );
266294 if ( $returned['result'] === false ) { //couldn't make contact. Bail.
267295 return $returned;
@@ -485,5 +513,33 @@
486514 $c = get_called_class();
487515 return $c::IDENTIFIER;
488516 }
 517+
 518+ public function getStopwatch($string, $reset = false){
 519+ static $start = null;
 520+ $now = microtime(true);
489521
 522+ if ($start == null || $reset === true){
 523+ $start = $now;
 524+ }
 525+ $clock = round($now - $start, 4);
 526+ self::log("\nClock at $string: $clock ($now)");
 527+ return $clock;
 528+ }
 529+
 530+ function saveCommunicationStats( $additional = '' ) { //easier than looking at logs...
 531+ $params = array();
 532+ if (self::getGlobal('SaveCommStats')){ //TODO: I should do this for real at some point.
 533+ $db = ContributionTrackingProcessor::contributionTrackingConnection();
 534+ $params['contribution_id'] = $this->dataObj->getVal( 'contribution_tracking_id' );
 535+ $params['ts'] = $db->timestamp();
 536+ $params['duration'] = $this->getStopwatch(__FUNCTION__);
 537+ $params['gateway'] = self::getGatewayName() . $additional;
 538+
 539+ //can we check to see if the table exists? Bah, I should almost certianly do this Fer Reals.
 540+
 541+ $db->insert( 'communication_stats', $params );
 542+ }
 543+
 544+ }
 545+
490546 }
Index: branches/fundraising/extensions/DonationInterface/gateway_common/DonationData.php
@@ -151,7 +151,7 @@
152152 'size' => $wgRequest->getText( 'size' ),
153153 'premium_language' => $wgRequest->getText( 'premium_language', "en" ),
154154 'card_num' => str_replace( ' ', '', $wgRequest->getText( 'card_num' ) ),
155 - 'card_type' => $wgRequest->getText( 'card' ),
 155+ 'card_type' => $wgRequest->getText( 'card_type' ),
156156 'expiration' => $wgRequest->getText( 'mos' ) . substr( $wgRequest->getText( 'year' ), 2, 2 ),
157157 'cvv' => $wgRequest->getText( 'cvv' ),
158158 'currency' => $wgRequest->getText( 'currency_code' ),

Follow-up revisions

RevisionCommit summaryAuthorDate
r99282Now checks to see if the communication_stats table exists in our Contribution...khorn23:43, 7 October 2011

Comments

#Comment by Khorn (WMF) (talk | contribs)   18:41, 23 September 2011

Please note that this branch is in the middle of a serious refactoring, and is by no means ready to be merged back into trunk. (Latest DonationInterface branch rev at the time of this comment is r97833.)

#Comment by Awjrichards (talk | contribs)   00:44, 30 September 2011
+			//can we check to see if the table exists? Bah, I should almost certianly do this Fer Reals. 
+
+			$db->insert( 'communication_stats', $params );

Yes, we can. Take a look at the db documentation - you probably need to get a list of available tables and determine if the one you want is in it, although I could've sworn there was once a method like 'tableExists( $tablename )' but that could be a memory born from feverish dreams long ago. [1]

#Comment by Khorn (WMF) (talk | contribs)   23:44, 7 October 2011

As of r99282, we're checking to see if the table is there before we try to write to it.

Status & tagging log