Skip to content

Instantly share code, notes, and snippets.

@evansolomon
Created October 10, 2011 17:37
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save evansolomon/1275892 to your computer and use it in GitHub Desktop.
Save evansolomon/1275892 to your computer and use it in GitHub Desktop.
WordPress.com plugin for running Optimizely experiments
<?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