Your browser doesn't support the features required by impress.js, so you are presented with a simplified version of this presentation.

For the best experience please use the latest Chrome, Safari or Firefox browser.

Use a spacebar or arrow keys to navigate

WC 401: Object-oriented Plugin Development

WordCamp Phoenix 2013

Erick Hitter

Design Engineer @ Automattic

@ethitter

About Me

Why OOP?

 

Because it rocks!

Why OOP?

 

Namespacing: Procedural

 

<?php
function my_plugin_init() {
	// stuff
}
add_action( 'init', 'my_plugin_init' );

function my_plugin_theme_setup() {
	// more stuff
}
add_action( 'after_setup_theme', 'my_plugin_theme_setup' );
?>

Namespacing: OOP

 

<?php
class My_Plugin {
	…

	public function action_init() {
		// stuff
	}

	public function action_after_setup_theme() {
		// more stuff
	}

	…
}
?>

Reduced Repetition: Procedural

 

<?php
function my_plugin_init() {
	register_post_type( 'my_post_type', array( … ) );

	register_taxonomy( 'my_taxonomy', 'my_post_type', array( … ) );
}
add_action( 'init', 'my_plugin_init' );
?>

Reduced Repetion: OOP

 

<?php
class My_Plugin {
	protected $post_type = 'my_post_type';
	protected $taxonomy  = 'my_taxonomy';

	…

	public function action_init() {
		register_post_type( $this->post_type, array( … ) );

		register_taxonomy( $this->taxonomy, $this->post_type, array( … ) );
	}

	…
}
?>

Code Security

 

Smarter Extensibility

 

It's the WordPress Way

 

 

And so on…

OOP Terminology

procedural
not OOP PHP
property
OOP's equivalent of a variable.
method
OOP's equivalent of a function.
instance
a discrete incarnation of a class.

Not having a CS background or understanding of why there are different terms to refer to what is functionally the same, I interchange the two.

A Basic Class

 

<?php
class My_Plugin {

	public function __construct() {
		add_action( 'init', array( $this, 'action_init' ) );

		add_filter( 'the_content', array( $this, 'filter_the_content' ) );
	}

	public function action_init() {
		// stuff
	}

	public function filter_the_content( $content ) {
		// more stuff

		return $content;
	}
}

new My_Plugin;
?>

Caveats

 

A Better* Plugin Class

 

Introducing our new friend, the Singleton.

 

Assumption: you're using a class to encapsulate your plugin code, and only once instance of said code should exist.

The Singleton

 

<?php
class My_Plugin {
	private static $__instance = null;

	private function __construct() {}

	public static function instance() {
		if ( ! is_a( self::$__instance, __CLASS__ ) ) {
			self::$__instance = new self;
			self::$__instance->setup();
		}

		return self::$__instance;
	}

	private function setup() {
		add_action( 'init', array( $this, 'action_init' ) );

		add_filter( 'the_content', array( $this, 'filter_the_content' ) );
	}

	…
}

My_Plugin::instance();
?>

The Singleton

 

<?php
class My_Plugin {
	private static $__instance = null;

	private function __construct() {}

	public static function instance() {
		if ( ! is_a( self::$__instance, __CLASS__ ) ) {
			self::$__instance = new self;
			self::$__instance->setup();
		}

		return self::$__instance;
	}

	private function setup() {
		add_action( 'init', array( $this, 'action_init' ) );

		add_filter( 'the_content', array( $this, 'filter_the_content' ) );
	}

	…
}

My_Plugin::instance();
?>

The Singleton

 

<?php
class My_Plugin {
	private static $__instance = null;

	private function __construct() {}

	public static function instance() {
		if ( ! is_a( self::$__instance, __CLASS__ ) ) {
			self::$__instance = new self;
			self::$__instance->setup();
		}

		return self::$__instance;
	}

	private function setup() {
		add_action( 'init', array( $this, 'action_init' ) );

		add_filter( 'the_content', array( $this, 'filter_the_content' ) );
	}

	…
}

My_Plugin::instance();
?>

The Singleton

 

<?php
class My_Plugin {
	private static $__instance = null;

	private function __construct() {}

	public static function instance() {
		if ( ! is_a( self::$__instance, __CLASS__ ) ) {
			self::$__instance = new self;
			self::$__instance->setup();
		}

		return self::$__instance;
	}

	private function setup() {
		add_action( 'init', array( $this, 'action_init' ) );

		add_filter( 'the_content', array( $this, 'filter_the_content' ) );
	}

	…
}

My_Plugin::instance();
?>

Questions so far?

On to more examples!