/** * Assembles the data for the API to return. * @param integer $id The Contribution Tracking ID. * @param array $params Original (staged) request paramaters. */ function doReturn($id, $params) { // foreach ($params as $key=>$value){ // if ($value != ''){ // $this->getResult()->addValue(array('returns', 'parrot'), $key, $value); // } // } $params['contribution_tracking_id'] = $id; $repost = ContributionTrackingProcessor::getRepostFields($params); $this->getResult()->addValue(array('returns', 'action'), 'url', $repost['action']); foreach ($repost['fields'] as $key => $value) { $this->getResult()->addValue(array('returns', 'fields'), $key, $value); } }
function execute($language) { global $wgRequest, $wgOut, $wgContributionTrackingReturnToURLDefault; if (!preg_match('/^[a-z-]+$/', $language)) { $language = 'en'; } $this->lang = Language::factory($language); $this->setHeaders(); $wgOut->setPageTitle(''); $gateway = $wgRequest->getText('gateway'); if (!in_array($gateway, array('paypal', 'moneybookers'))) { $wgOut->showErrorPage('contrib-tracking-error', 'contrib-tracking-error-text'); return; } // Store the contribution data if ($wgRequest->getVal('contribution_tracking_id')) { $contribution_tracking_id = $wgRequest->getVal('contribution_tracking_id', 0); } else { $tracked_contribution = array('note' => $wgRequest->getVal('comment'), 'referrer' => $wgRequest->getVal('referrer'), 'anonymous' => $wgRequest->getCheck('comment-option', false) ? false : true, 'utm_source' => $wgRequest->getVal('utm_source'), 'utm_medium' => $wgRequest->getVal('utm_medium'), 'utm_campaign' => $wgRequest->getVal('utm_campaign'), 'optout' => $wgRequest->getCheck('email-opt', false) ? false : true, 'language' => $wgRequest->getVal('language'), 'owa_session' => $wgRequest->getVal('owa_session'), 'owa_ref' => $wgRequest->getVal('owa_ref', null)); $contribution_tracking_id = ContributionTrackingProcessor::saveNewContribution($tracked_contribution); } $params = array('gateway' => $gateway, 'tshirt' => $wgRequest->getVal('tshirt'), 'return' => $wgRequest->getText('returnto', "Donate-thanks/{$language}"), 'currency_code' => $wgRequest->getText('currency_code', 'USD'), 'fname' => $wgRequest->getText('fname', null), 'lname' => $wgRequest->getText('lname', null), 'email' => $wgRequest->getText('email', null), 'address1' => $wgRequest->getText('address1', null), 'city' => $wgRequest->getText('city', null), 'state' => $wgRequest->getText('state', null), 'zip' => $wgRequest->getText('zip', null), 'country' => $wgRequest->getText('country', null), 'address_override' => $wgRequest->getText('address_override', '0'), 'recurring_paypal' => $wgRequest->getText('recurring_paypal'), 'amount' => $wgRequest->getVal('amount'), 'amount_given' => $wgRequest->getVal('amountGiven'), 'contribution_tracking_id' => $contribution_tracking_id, 'language' => $language); if ($params['tshirt']) { $params['size'] = $wgRequest->getText('size'); $params['premium_language'] = $wgRequest->getText('premium_language'); } foreach ($params as $key => $value) { if ($value === "" || $value === null) { unset($params[$key]); } } $repost = ContributionTrackingProcessor::getRepostFields($params); #$wgOut->addWikiText( "{{2009/Donate-banner/$language}}" ); $wgOut->addHTML($this->msgWiki('contrib-tracking-submitting')); // Output the repost form $output = '<form method="post" name="contributiontracking" action="' . $repost['action'] . '">'; foreach ($repost['fields'] as $key => $value) { $output .= '<input type="hidden" name="' . htmlspecialchars($key) . '" value="' . htmlspecialchars($value) . '" />'; } $output .= $this->msgWiki('contrib-tracking-redirect'); // Offer a button to post the form if the user has no Javascript support $output .= '<noscript>'; $output .= $this->msgWiki('contrib-tracking-continue'); $output .= '<input type="submit" value="' . $this->msg('contrib-tracking-button') . '" />'; $output .= '</noscript>'; $output .= '</form>'; $wgOut->addHTML($output); // Automatically post the form if the user has Javascript support $wgOut->addHTML('<script type="text/javascript">document.contributiontracking.submit();</script>'); }
/** * tests the getLanguage function. * NOTE: Static vars are involved here. * Assertions: * getLanguage with no parameters returns english (if none of the * previous tests set the var differently. Static vars have tricky initial * conditions...) * Passing getLanguage a different language than the one previously in * use will cause the var to reset to the explicit language. Messages should * be sent in the new language. */ function testGetLanguage() { $messageKey = 'contributiontracking'; $messageBG = 'Проследяване на дарението'; $messageEN = 'Contribution tracking'; $code = ContributionTrackingProcessor::getLanguage(); $this->assertEquals($code, 'en', "Default language is not US (or your test has a hangover)"); $params['language'] = 'bg'; $code = ContributionTrackingProcessor::getLanguage($params); $this->assertEquals($params['language'], $code, "Returned language is not the one we just sent."); $message = ContributionTrackingProcessor::msg($messageKey); $this->assertEquals($message, $messageBG, "Returned language is not the one we just sent."); $params['language'] = 'en'; $code = ContributionTrackingProcessor::getLanguage($params); $this->assertEquals($params['language'], $code, "Returned language is not the one we just sent."); $message = ContributionTrackingProcessor::msg($messageKey); $this->assertEquals($message, $messageEN, "Returned language is not the one we just sent."); }
/** * Inserts a new or updates a record in the contribution_tracking table. * * @return mixed Contribution tracking ID or false on failure */ public function saveContributionTrackingData() { if ($this->gateway->isBatchProcessor()) { // We aren't learning anything new about the donation, so just return. return false; } $ctid = $this->getVal('contribution_tracking_id'); $tracking_data = $this->getCleanTrackingData(true); $db = ContributionTrackingProcessor::contributionTrackingConnection(); if (!$db) { // TODO: This might be a critical failure; do we want to throw an exception instead? $this->logger->error('Failed to create a connect to contribution_tracking database'); return false; } if ($ctid) { // We're updating a record, but only if we actually have data to update if (count($tracking_data)) { $db->update('contribution_tracking', $tracking_data, array('id' => $ctid)); } } else { // We need a new record // set the time stamp if it's not already set if (!isset($tracking_data['ts']) || !strlen($tracking_data['ts'])) { $tracking_data['ts'] = $db->timestamp(); } // Store the contribution data if ($db->insert('contribution_tracking', $tracking_data)) { $ctid = $db->insertId(); } else { $this->logger->error('Failed to create a new contribution_tracking record'); return false; } } return $ctid; }
/** * Update contribution_tracking table * * @param array $data Form data * @param bool $force If set to true, will ensure that contribution tracking is updated */ public function updateContributionTracking($force = false) { // ony update contrib tracking if we're coming from a single-step landing page // which we know with cc# in utm_source or if force=true or if contribution_tracking_id is not set if (!$force && !preg_match("/cc[0-9]/", $this->getVal('utm_source')) && is_numeric($this->getVal('contribution_tracking_id'))) { return; } $db = ContributionTrackingProcessor::contributionTrackingConnection(); if (!$db) { return true; } ///wait, what? TODO: This line was straight copied from the _gateway.body. Find out if there's a good reason we're not returning false here. // if contrib tracking id is not already set, we need to insert the data, otherwise update if (!$this->getVal('contribution_tracking_id')) { $tracked_contribution = $this->getCleanTrackingData(); $this->setVal('contribution_tracking_id', $this->insertContributionTracking($tracked_contribution)); } else { $tracked_contribution = $this->getCleanTrackingData(true); $db->update('contribution_tracking', $tracked_contribution, array('id' => $this->getVal('contribution_tracking_id'))); } }
public function getUTMInfoFromDB() { $db = ContributionTrackingProcessor::contributionTrackingConnection(); if (!$db) { die("There is something terribly wrong with your Contribution Tracking database. fixit."); return null; } $ctid = $this->getData_Unstaged_Escaped('contribution_tracking_id'); $data = array(); // if contrib tracking id is not already set, we need to insert the data, otherwise update if ($ctid) { $res = $db->select('contribution_tracking', array('utm_source', 'utm_campaign', 'utm_medium', 'ts'), array('id' => $ctid)); foreach ($res as $thing) { $data['utm_source'] = $thing->utm_source; $data['utm_campaign'] = $thing->utm_campaign; $data['utm_medium'] = $thing->utm_medium; $data['ts'] = $thing->ts; $msg = ''; foreach ($data as $key => $val) { $msg .= "{$key} = {$val} "; } $this->log("{$ctid}: Found UTM Data. {$msg}"); echo "{$msg}\n"; return $data; } } //if we got here, we can't find anything else... $this->log("{$ctid}: FAILED to find UTM Source value. Using default."); return $data; }
/** * * @param string $function This is the function name that identifies the * stopwatch that should have already been started with the getStopwatch * function. * @param string $additional Additional information about the thing we're * currently timing. Meant to be easily searchable. * @param string $vars Intended to be particular values of any variables * that might be of interest. */ public function saveCommunicationStats($function = '', $additional = '', $vars = '') { static $saveStats = null; static $saveDB = null; if ($saveStats === null) { $saveStats = self::getGlobal('SaveCommStats'); } if (!$saveStats) { return; } if ($saveDB === null) { $db = ContributionTrackingProcessor::contributionTrackingConnection(); if ($db->tableExists('communication_stats')) { $saveDB = true; } else { $saveDB = false; } } $params = array('contribution_id' => $this->getData_Unstaged_Escaped('contribution_tracking_id'), 'duration' => $this->getStopwatch($function), 'gateway' => self::getGatewayName(), 'function' => $function, 'vars' => $vars, 'additional' => $additional); if ($saveDB) { $db = ContributionTrackingProcessor::contributionTrackingConnection(); $params['ts'] = $db->timestamp(); $db->insert('communication_stats', $params); } else { //save to syslog. But which syslog? $msg = ''; foreach ($params as $key => $val) { $msg .= "{$key}:{$val} - "; } self::log($msg, LOG_INFO, '_commstats'); } }
/** * @param $updater DatabaseUpdater * @return bool */ function efContributionTrackingLoadUpdates($updater = null) { $dir = dirname(__FILE__) . '/'; if ($updater === null) { global $wgExtNewTables, $wgExtNewFields; $wgExtNewTables[] = array('contribution_tracking', $dir . 'ContributionTracking.sql'); $wgExtNewTables[] = array('contribution_tracking_owa_ref', $dir . 'ContributionTracking_OWA_ref.sql'); $wgExtNewFields[] = array('contribution_tracking', 'owa_session', $dir . 'patch-owa.sql'); } else { global $wgContributionTrackingDBname; if ($updater->getDB()->getDBname() === $wgContributionTrackingDBname) { $updater->addExtensionTable('contribution_tracking', $dir . 'ContributionTracking.sql'); $updater->addExtensionTable('contribution_tracking_owa_ref', $dir . 'ContributionTracking_OWA_ref.sql'); $updater->addExtensionUpdate(array('addField', 'contribution_tracking', 'owa_session', $dir . 'patch-owa.sql', true)); } else { //We are configured not to use the main mediawiki db. //Unless the updater is modified not to run //'LoadExtensionSchemaUpdates' hooks in its constructor (or do so //conditionally), we're going to have to do these manually. $ctDB = ContributionTrackingProcessor::contributionTrackingConnection(); if (!$ctDB->tableExists('contribution_tracking')) { $ctDB->sourceFile($dir . 'ContributionTracking.sql'); } if (!$ctDB->tableExists('contribution_tracking_owa_ref')) { $ctDB->sourceFile($dir . 'ContributionTracking_OWA_ref.sql'); } if (!$ctDB->fieldExists('contribution_tracking', 'owa_session')) { $ctDB->sourceFile($dir . 'patch-owa.sql'); } } } return true; }
/** * Gets a message in the local language * @param string $key Message key * @return string translated message */ static function msg($key) { return wfMsgExt($key, array('escape', 'language' => ContributionTrackingProcessor::getLanguage())); }
/** * Tests to make sure the contribution was saved in the database properly. * Assertions: * The saved contribution ID is reposted to paypal * Each parameter saved to the contribution_tracking table is identical * to the value we were trying to save, in the row matching the ID passed to * paypal * The owa_ref URL value is stored in the owa_ref table, and referenced * by the correct id in the owa_ref column * */ function testExecuteForContributionSave() { //TODO: Test inserting pure garbage. $complete = array('comment' => 'Interstitial Save', 'referrer' => 'phpunit_interstitial', 'comment-option' => 'yep', 'utm_source' => 'here', 'utm_medium' => 'large', 'utm_campaign' => 'testy01', 'language' => 'en', 'owa_session' => 'foo2', 'owa_ref' => 'execute_save', 'gateway' => 'paypal', 'amount' => '6.60'); $table1_check = $complete; $table1_check['anonymous'] = 0; $table1_check['optout'] = 1; $table1_check['note'] = $complete['comment']; unset($table1_check['owa_ref']); unset($table1_check['comment']); unset($table1_check['comment-option']); unset($table1_check['gateway']); unset($table1_check['amount']); $page_xml = $this->getPageHTML($complete); //We're using paypal, one-time, so the ID will come back in the hidden "custom" field $reposters = array(); foreach ($page_xml->getElementsByTagName('input') as $node) { $attributes = $this->getNodeAttributes($node); if ($attributes['type'] == 'hidden') { $reposters[$attributes['name']] = $attributes['value']; } } $this->assertTrue(is_numeric($reposters['custom']), "The saved transaction ID was not found"); $db = ContributionTrackingProcessor::contributionTrackingConnection(); $row = $db->selectRow('contribution_tracking', '*', array('id' => $reposters['custom'])); foreach ($table1_check as $key => $value) { $this->assertEquals($value, $row->{$key}, "{$key} does not match in the database."); } $row = $db->selectRow('contribution_tracking_owa_ref', '*', array('id' => $row->owa_ref)); $this->assertEquals($complete['owa_ref'], $row->url, "OWA Reference lookup does not match"); }
public function getUTMInfoFromDB() { if ($this->getData_Unstaged_Escaped('utm_source')) { // We already have the info. return array(); } if (!class_exists('ContributionTrackingProcessor')) { $this->logger->error('We needed to get contribution_tracking data but cannot on this platform!'); return array(); } $db = ContributionTrackingProcessor::contributionTrackingConnection(); if (!$db) { $this->logger->error('There is something terribly wrong with your Contribution Tracking database. fixit.'); throw new RuntimeException('Might as well fall over.'); } $ctid = $this->getData_Unstaged_Escaped('contribution_tracking_id'); $data = array(); // if contrib tracking id is not already set, we need to insert the data, otherwise update if ($ctid) { $res = $db->select('contribution_tracking', array('utm_source', 'utm_campaign', 'utm_medium', 'ts'), array('id' => $ctid)); foreach ($res as $thing) { $data['utm_source'] = $thing->utm_source; $data['utm_campaign'] = $thing->utm_campaign; $data['utm_medium'] = $thing->utm_medium; $data['ts'] = $thing->ts; $msg = ''; foreach ($data as $key => $val) { $msg .= "{$key} = {$val} "; } $this->logger->info("{$ctid}: Found UTM Data. {$msg}"); return $data; } } //if we got here, we can't find anything else... $this->logger->error("{$ctid}: FAILED to find UTM Source value. Using default."); return $data; }