Created
October 10, 2011 17:37
-
-
Save evansolomon/1275892 to your computer and use it in GitHub Desktop.
WordPress.com plugin for running Optimizely experiments
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?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