Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
Vendo A/B Test script for NATS
<?php
//NATS' tracker url (with a trailing slash)
$natsTrackUrl = 'http://natsv4.staging.vend-o.com/track/';
//NATS' signup url
$natsSignupUrl = 'http://natsv4.staging.vend-o.com/signup/signup.php';
$configuration = array(
//maps all current tours of SiteID 11 to the new tour (88) configured for the Vendo A/B test
'11.*' => '88', //assumes the current tours' traffic is being processed by the other biller. The new tour 88 sends the traffic to Vendo.
//The A/B split will occur between all the current tours (A) and the new one configured for Vendo (B)
);
$abTester = new VendoABTester($configuration, $natsTrackUrl, $natsSignupUrl);
$abTester->performTest();
class VendoABTester
{
protected $_config;
protected $_testAvailable;
protected $_natsUrl;
protected $_currentNatsCode;
protected $_newNatsCode;
protected $_requestType;
public function __construct(array $config, $trackUrl, $signupUrl)
{
$this->_config = $config;
$this->_testAvailable = false;
$this->_natsUrl = $natsUrl;
$this->dectectSiteAndTour();
/**
* We need to identify where the traffic is coming from:
* /track/(.+) ?
* or /signup/signup.php ?
*/
if (empty($_GET['signup'])) {//the apache rule appends this
$this->_requestType = 'track';
$this->_natsUrl = $trackUrl;
} else {
$this->_requestType = 'signup';
$this->_natsUrl = $signupUrl;
}
$this->_requestType = empty($_GET['signup']) ? 'track' : 'signup';
}
/**
* Decodes the NATS code and checks whether the site+tour combination is configured to be A/B tested or not.
* Check http://nats.yourdomain.com/admin_codes.php to get the details on how the NATS codes get generated.
*/
public function dectectSiteAndTour()
{
$this->_testAvailable = false;
if (!empty($_GET['nats'])) {
//we need to decode the code that NATS generated (see http://nats.yourdomain.com/admin_codes.php)
$this->_currentNatsCode = base64_decode($_GET['nats']);
@list($affId, $programId, $siteId, $tourId, $other1, $other2, $other3, $other4, $other5) = explode('.', $this->_currentNatsCode);
if (!empty($siteId) && !empty($tourId)) {
//do we have a specific rule for the current siteId and tourId?
if (isset($this->_config[$siteId . '.' . $tourId])) {
$newTourId = $this->_config[$siteId . '.' . $tourId];
$this->_testAvailable = true;
//do we have a catch-all rule for this siteId?
} elseif (isset($this->_config[$siteId . '.*'])
//this condition prevents to A/B on a previous A/B
&& $this->_config[$siteId . '.*'] != $tourId
) {
$newTourId = $this->_config[$siteId . '.*'];
$this->_testAvailable = true;
}
if ($this->_testAvailable) {
$this->_newNatsCode = implode('.', array(
$affId, $programId, $siteId, $newTourId,
$other1, $other2, $other3, $other4, $other5,
));
}
} else {
//something is not OK in the NATS code. We'll have to ignore this request.
$this->_testAvailable = false;
}
}
}
/**
* Tells whether the site+tour combination is configured to be A/B tested or not
*/
public function testAvailable()
{
return $this->_testAvailable;
}
/**
* Flips a coin and picks the nats code that will take the user to Vendo or to the other biller
* Redirects the user back to NATS
*/
public function performTest()
{
$url = '';
$natsCode = base64_encode($this->_currentNatsCode);
if ($this->_testAvailable) {
//flip the coin
$random = mt_rand(1, 100);
if ($random > 50) {
//process with Vendo
$natsCode = base64_encode($this->_newNatsCode);
}
}
if ($this->_requestType == 'track') {
$url = $this->_natsUrl . $natsCode . '?vendoab=1';
} else {
$queryString = parse_str($_SERVER['QUERY_STRING']);
unset($queryString['signup']);
$queryString['nats'] = $natsCode;
$queryString['vendoab'] = 1;
$url = $this->_natsUrl . '?' . http_build_query($queryString);
}
//We use the vendoab=1 parameter to tell apache to take the user to the original tour's flow
//(i.e. apache won't redirect the user to this script again)
header('Location: ' . $url);
exit;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment