/**
  * 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;
 }