<?php | |
/* | |
Plugin Name: Optimizely | |
Description: Runs Optimizely experiments. | |
Author: koop, evansolomon | |
Version: 0.2 | |
*/ | |
class WPCOM_Optimizely { | |
public $version; | |
public $url; | |
private $_checks = array(); | |
function __construct( $project_id, $version ) { | |
$this->version = $version; | |
// Generate project JavaScript URL | |
$scheme = is_ssl() ? 'https' : 'http'; | |
$this->url = "{$scheme}://cdn.optimizely.com/js/{$project_id}.js"; | |
add_filter( 'optimizely_maybe_experiment', array( $this, 'checks' ), 10, 3 ); | |
$this->add_check( array( $this, 'disabled_sites' ) ); | |
$this->add_check( array( $this, 'language' ) ); | |
$this->add_check( array( $this, 'front_page_only' ) ); | |
$this->add_check( array( $this, 'logged_out_users' ) ); | |
$this->add_check( array( $this, 'user_id_floor' ) ); | |
} | |
/** | |
* Potentially run an experiment. | |
* | |
* The 'optimizely_maybe_experiment' filter determines whether to run a given experiment. | |
* | |
* If any experiment is added, the Optimizely project script will be included. | |
* | |
* For each added experiment, the wpcom_optimizely.$EXPERIMENT_SLUG variable will | |
* be defined in JavaScript. | |
*/ | |
function maybe_experiment( $experiment ) { | |
// If the optimizely_maybe_experiment filter returns false, bail. | |
if ( ! apply_filters( 'optimizely_maybe_experiment', true, $experiment->args, $experiment ) ) | |
return; | |
// Enqueue the Optimizely script | |
wp_enqueue_script( 'optimizely', $this->url, array('jquery'), $this->version ); | |
// Register the slug through JavaScript | |
wp_localize_script( 'optimizely', 'wpcom_optimizely', array( $experiment->slug => true ) ); | |
} | |
/** | |
* Provides a shorthand for validating an experiment via callbacks. | |
* If any check returns 'false' (explicitly), the experiment will not run. | |
*/ | |
function add_check( $callback, $param = false ) { | |
$this->_checks[] = $callback; | |
} | |
/** | |
* Attached to the optimizely_maybe_experiment filter. | |
* Runs our checks. If any return 'false', bail! | |
*/ | |
function checks( $enable_exp, $args, $experiment ) { | |
foreach ( $this->_checks as $check ) { | |
if ( false === call_user_func( $check, $args, $experiment ) ) | |
return false; | |
} | |
return $enable_exp; | |
} | |
/** | |
* Disables all experiments for select sites. | |
*/ | |
function disabled_sites( $args ) { | |
global $blog_id; | |
switch ( $blog_id ) { | |
case 24588526: // TechCrunch | |
return false; | |
} | |
} | |
/** | |
* Optionally limits targets by user language. | |
* | |
* Determined by the boolean 'language' argument. Default 'en', for ENglish. | |
*/ | |
function language( $args ) { | |
// If a language isn't set, we always want the experiment to run. | |
if ( empty( $args['language'] ) ) | |
return true; | |
if ( $args['language'] != get_bloginfo( 'language' ) ) | |
return false; | |
} | |
/** | |
* Optionally limits targets only to front page. | |
* | |
* Determined by the boolean 'front_page_only' argument. Default false, for all pages. | |
*/ | |
function front_page_only( $args ) { | |
if ( $args['front_page_only'] ) | |
return is_home(); | |
} | |
/** | |
* Optionally limits targets only to logged out users. | |
* | |
* Determined by the boolean 'logged_out_users' argument. Default false, for all users. | |
*/ | |
function logged_out_users( $args ) { | |
if ( $args['logged_out_users'] ) | |
return ! is_user_logged_in(); | |
} | |
/** | |
* Optionally limits targets only to new users, defined by minimum user_id. | |
* | |
* Determined by the integer 'user_id_floor' argument. Default 0, for all users. | |
*/ | |
function user_id_floor( $args ) { | |
if ( $args['user_id_floor'] ) { | |
global $current_user; | |
return ( $args['user_id_floor'] < $current_user->ID ); | |
} | |
} | |
} | |
class WPCOM_Optimizely_Experiment { | |
public $slug; | |
public $args; | |
public $project; | |
/** | |
* Register a new Optimizely experiment. | |
* | |
* @param $slug string | |
* @param $args array - Optional. | |
* | |
* 'actions' => Evaluates the experiment on a specific actions. | |
* If not provided, experiment evaluates immediately. Default ''. | |
* Accepts a string or array. Arrays can be used to hook to multiple actions. | |
* 'language' => Limits an experiment by user language. Default 'en'. | |
*/ | |
function __construct( $project, $slug, $args = array() ) { | |
$defaults = array( | |
'actions' => '', | |
'language' => 'en', | |
'front_page_only' => false, | |
'logged_out_users' => false, | |
'user_id_floor' => 0, | |
); | |
$args = wp_parse_args( $args, $defaults ); | |
$this->project = $project; | |
$this->slug = $slug; | |
$this->args = $args; | |
if ( empty( $args['actions'] ) ) | |
$this->maybe_load(); | |
elseif( is_array( $args['actions'] ) ) { | |
foreach( $args['actions'] as $action ) { | |
add_action( $action, array( $this, 'maybe_load' ) ); | |
} | |
} | |
else | |
add_action( $args['actions'], array( $this, 'maybe_load' ) ); | |
} | |
function maybe_load() { | |
$this->project->maybe_experiment( $this ); | |
} | |
} | |
$wpcom_optimizely = new WPCOM_Optimizely( 7144006, '201111130a' ); | |
/** | |
* Add a new Optimizely experiment. | |
*/ | |
function optimizely_experiment( $slug, $args = array() ) { | |
global $wpcom_optimizely; | |
new WPCOM_Optimizely_Experiment( $wpcom_optimizely, $slug, $args ); | |
} | |
/** | |
* Example experiment using multiple actions | |
*/ | |
optimizely_experiment( 'fake_test', array( | |
'actions' => array( 'load-themes.php', 'load-post-new.php' ), | |
) ); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment