/** * Save the test. * * @return array Test. */ function save($commit = true) { $this->test['winner'] = $this->cleaned_data['alt']; $this->test['active'] = false; $this->test['stop_dtime'] = gmdate('Y-m-d H:i:s'); $db = Pluf_AB::getDb(); $db->tests->update(array('_id' => $this->cleaned_data['test']), $this->test); return $this->test; }
/** * Get stats for a given funnel. * * @param $funnel string Funnel * @param $period string Time period 'yesterday', ('today'), '7days', 'all' * @param $prop string Property to filter (null) */ public static function getStats($funnel, $period = 'today', $prop = null) { $db = Pluf_AB::getDb(); $steps = array(); for ($i = 1; $i <= 20; $i++) { $steps[$i] = array(); } switch ($period) { case 'yesterday': $q = array('t' => (int) gmdate('Ymd', time() - 86400)); break; case 'today': $q = array('t' => (int) gmdate('Ymd')); break; case '7days': $q = array('t' => array('$gte' => (int) gmdate('Ymd', time() - 604800))); break; case 'all': default: $q = array(); break; } $q['f'] = $funnel; if ($prop) { $q['p.' . $prop] = array('$exists' => true); } $uids = array(); // With very big logs, we will need to find by schunks, this // will be very easy to adapt. foreach ($db->funnellogs->find($q) as $log) { if (!isset($uids[$log['u'] . '##' . $log['s']])) { if ($prop and !isset($log['p'][$prop])) { continue; } $uids[$log['u'] . '##' . $log['s']] = true; $step = $log['s']; $steps[$step]['name'] = $log['sn']; $steps[$step]['id'] = $log['s']; if ($prop and !isset($steps[$step]['props'])) { $steps[$step]['props'] = array(); } $steps[$step]['total'] = isset($steps[$step]['total']) ? $steps[$step]['total'] + 1 : 1; if ($prop) { $steps[$step]['props'][$log['p'][$prop]] = isset($steps[$step]['props'][$log['p'][$prop]]) ? $steps[$step]['props'][$log['p'][$prop]] + 1 : 1; } } } // Now, compile the stats for steps 2 to n // First, we find the "max" for the reference number of // visitors along this funnel. This is $t1 and $tprops[prop] $t1 = 0; foreach ($steps as $step) { if (isset($step['total']) and $step['total'] > $t1) { $t1 = $step['total']; } if ($prop and isset($step['props'])) { foreach ($step['props'] as $v => $t) { if (!isset($tprops[$v])) { $tprops[$v] = $t; continue; } if ($tprops[$v] < $t) { $tprops[$v] = $t; } } } } if ($t1 == 0) { return array(); } $prev_step = null; for ($i = 1; $i <= 20; $i++) { if ($prev_step == null) { } if ($steps[$i]) { $tp = $prev_step['total']; $tn = $steps[$i]['total']; if ($tp) { $steps[$i]['conv'] = sprintf('%01.2f%%', 100.0 - (double) ($tp - $tn) / $tp * 100.0); } else { $steps[$i]['conv'] = 'N/A'; } if ($t1) { $steps[$i]['conv1'] = sprintf('%01.2f%%', 100.0 - (double) ($t1 - $tn) / $t1 * 100.0); } else { $steps[$i]['conv1'] = 'N/A'; } if ($prop) { $steps[$i]['sprops'] = array(); $steps[$i]['sprops1'] = array(); foreach ($steps[$i]['props'] as $v => $t) { if (!isset($tprops[$v])) { $tprops[$v] = $t; } $pv = isset($prev_step['props'][$v]) ? $prev_step['props'][$v] : 0; $steps[$i]['sprops'][$v] = array($t, $pv); $steps[$i]['sprops1'][$v] = array($t, $tprops[$v]); if ($pv) { $steps[$i]['sprops'][$v][] = round(100 * (double) $t / (double) $pv, 2) . '%'; } else { $steps[$i]['sprops'][$v][] = 0; } $steps[$i]['sprops1'][$v][] = round(100 * (double) $t / (double) $tprops[$v], 2) . '%'; } } $steps[$i]['bigtotal'] = $t1; $prev_step = $steps[$i]; } } for ($i = 20; $i >= 1; $i--) { if (!$steps[$i]) { unset($steps[$i]); // We remove the inexisting steps } } return $steps; }
/** * A simple view to redirect a user and convert it. * * To convert the user for the test 'my_test' and redirect it to * the URL 'http://www.example.com' add the following view in your * urls.php: * * <pre> * array('regex' => '#^/goto/example/$#', * 'base' => $base, * 'model' => 'Pluf_AB_Views', * 'method' => 'convRedirect', * 'name' => 'go_to_example', * 'params' => array('url' => 'http://www.example.com', * 'test' => 'my_test') * ); * </pre> * * Try to put a url which reflects the final url after redirection * to minimize the confusion for the user. In this example, in * your code or template you use the named url 'go_to_example'. * */ public function convRedirect($request, $match, $p) { Pluf_AB::convert($p['test'], $request); return new Pluf_HTTP_Response_Redirect($p['url']); }
/** * Get a MongoDB database handle. * * It opens only one connection per request and tries to keep a * persistent connection between the requests. * * The configuration keys used are: * * `pluf_ab_mongo_server`: 'mongodb://localhost:27017' * `pluf_ab_mongo_options`: array('connect' => true, * 'persist' => 'pluf_ab_mongo') * `pluf_ab_mongo_db`: 'pluf_ab' * * If you have a default installation of MongoDB, it should work * out of the box. * */ public static function getDb() { if (self::$db !== null) { return self::$db; } $server = Pluf::f('pluf_ab_mongo_server', 'mongodb://localhost:27017'); $options = Pluf::f('pluf_ab_mongo_options', array('connect' => true, 'persist' => 'pluf_ab_mongo')); $conn = new Mongo($server, $options); self::$db = $conn->selectDB(Pluf::f('pluf_ab_mongo_db', 'pluf_ab')); return self::$db; }