SHARE
TWEET

Vendo A/B testing script

Vendo Mar 13th, 2015 87 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. <?php
  2. //NATS' tracker url (with a trailing slash)
  3. $natsTrackUrl = 'http://natsv4.staging.vend-o.com/track/';
  4. //NATS' signup url
  5. $natsSignupUrl = 'http://natsv4.staging.vend-o.com/signup/signup.php';
  6.  
  7. $configuration = array(
  8.     //maps all current tours of SiteID 11 to the new tour (88) configured for the Vendo A/B test
  9.     '11.*' => '88',
  10.     //The A/B split will occur between all the current tours (A) and the new one configured for Vendo (B)
  11. );
  12.  
  13. $abTester = new VendoABTester($configuration, $natsTrackUrl, $natsSignupUrl);
  14. $abTester->performTest();
  15.  
  16. class VendoABTester
  17. {
  18.     protected $_config;
  19.     protected $_testAvailable;
  20.     protected $_natsUrl;
  21.     protected $_currentNatsCode;
  22.     protected $_newNatsCode;
  23.     protected $_requestType;
  24.  
  25.     public function __construct(array $config, $trackUrl, $signupUrl)
  26.     {
  27.         $this->_config = $config;
  28.         $this->_testAvailable = false;
  29.         $this->_natsUrl = $natsUrl;
  30.         $this->dectectSiteAndTour();
  31.         /**
  32.          * We need to identify where the traffic is coming from:
  33.          * /track/(.+) ?
  34.          * or /signup/signup.php ?
  35.          */
  36.         if (empty($_GET['signup'])) {//the apache rule appends this
  37.             $this->_requestType = 'track';
  38.             $this->_natsUrl = $trackUrl;
  39.         } else {
  40.             $this->_requestType = 'signup';
  41.             $this->_natsUrl = $signupUrl;
  42.         }
  43.         $this->_requestType = empty($_GET['signup']) ? 'track' : 'signup';
  44.     }
  45.  
  46.     /**
  47.      * Decodes the NATS code and checks whether the site+tour combination is configured to be A/B tested or not.
  48.      * Check http://nats.yourdomain.com/admin_codes.php to get the details on how the NATS codes get generated.
  49.      */
  50.     public function dectectSiteAndTour()
  51.     {
  52.         $this->_testAvailable = false;
  53.         if (!empty($_GET['nats'])) {
  54.             //we need to decode the code that NATS generated (see http://nats.yourdomain.com/admin_codes.php)
  55.             $this->_currentNatsCode = base64_decode($_GET['nats']);
  56.             @list($affId, $programId, $siteId, $tourId, $other1, $other2, $other3, $other4, $other5) = explode('.', $this->_currentNatsCode);
  57.             if (!empty($siteId) && !empty($tourId)) {
  58.                 //do we have a specific rule for the current siteId and tourId?
  59.                 if (isset($this->_config[$siteId . '.' . $tourId])) {
  60.                     $newTourId = $this->_config[$siteId . '.' . $tourId];
  61.                     $this->_testAvailable = true;
  62.                 //do we have a catch-all rule for this siteId?
  63.                 } elseif (isset($this->_config[$siteId . '.*'])
  64.                          //this condition prevents to A/B on a previous A/B
  65.                           &&  $this->_config[$siteId . '.*'] != $tourId
  66.                 ) {
  67.                     $newTourId = $this->_config[$siteId . '.*'];
  68.                     $this->_testAvailable = true;
  69.                 }
  70.                 if ($this->_testAvailable) {
  71.                     $this->_newNatsCode = implode('.', array(
  72.                         $affId, $programId, $siteId, $newTourId,
  73.                         $other1, $other2, $other3, $other4, $other5,
  74.                     ));
  75.                 }
  76.             } else {
  77.                 //something is not OK in the NATS code. We'll have to ignore this request.
  78.                 $this->_testAvailable = false;
  79.             }
  80.         }
  81.     }
  82.  
  83.     /**
  84.      * Tells whether the site+tour combination is configured to be A/B tested or not
  85.      */
  86.     public function testAvailable()
  87.     {
  88.         return $this->_testAvailable;
  89.     }
  90.  
  91.     /**
  92.      * Flips a coin and picks the nats code that will take the user to Vendo or to the other biller
  93.      * Redirects the user back to NATS
  94.      */
  95.     public function performTest()
  96.     {
  97.         $url = '';
  98.         $natsCode = base64_encode($this->_currentNatsCode);
  99.  
  100.         if ($this->_testAvailable) {
  101.             //flip the coin
  102.             $random = mt_rand(1, 100);
  103.             if ($random > 50) {
  104.                 //process with Vendo
  105.                 $natsCode = base64_encode($this->_newNatsCode);
  106.             }
  107.         }
  108.  
  109.         if ($this->_requestType == 'track') {
  110.             $url = $this->_natsUrl . $natsCode . '?vendoab=1';
  111.         } else {
  112.             $queryString = parse_str($_SERVER['QUERY_STRING']);
  113.             unset($queryString['signup']);
  114.             $queryString['nats'] = $natsCode;
  115.             $queryString['vendoab'] = 1;
  116.             $url = $this->_natsUrl . '?' . http_build_query($queryString);
  117.         }
  118.  
  119.         //We use the vendoab=1 parameter to tell apache to take the user to the original tour's flow
  120.         //(i.e. apache won't redirect the user to this script again)
  121.         header('Location: ' . $url);
  122.         exit;
  123.     }
  124. }
RAW Paste Data
Top