Skip to content

Instantly share code, notes, and snippets.

@viruthagiri
Forked from sbressler/sample_plugin.php
Created February 15, 2012 18:53
Show Gist options
  • Save viruthagiri/1838120 to your computer and use it in GitHub Desktop.
Save viruthagiri/1838120 to your computer and use it in GitHub Desktop.
Sample plugin to demonstrate the basics of WordPress actions and filters, as well as storing plugin settings
<?php
/*
Plugin Name: Sample Plugin
Plugin URI: http://www.scottbressler.com/blog/plugins/
Description: Sample plugin to demonstrate the basics of WordPress actions and filters, as well as storing plugin settings. This plugin adds content to the end of posts. This can be achieved when publishing the post or each time the post is displayed, as specified by the plugin's settings. The text appended is also specified in the settings.
Version: 1.1
Author: Scott Bressler
Author URI: http://www.scottbressler.com/blog/
License: GPL2
*/
// Read more about the basics of writing a plugin here: http://codex.wordpress.org/Writing_a_Plugin.
// Check if the class exists before defining it to avoid any naming collisions.
if ( !class_exists('Sample_Plugin') ) {
// Wrap everything in a class to avoid any variable or function naming collisions.
class Sample_Plugin {
// Because of the following const declarations, this plugin is PHP5 only!
/**
* String used as key in database under which to store this plugin's settings.
*/
const sample_plugin_settings = 'sample-plugin';
/**
* String with which to prefix all apply_filters calls in the plugin.
*/
const filters_prefix = 'sample_plugin';
/**
* Instantiate the class, adding actions into admin_init and init for to hook our filters.
*/
function __construct() {
// Core hooks to allow the plugin to use WordPress hooks on initialization
add_action( 'admin_init', array( &$this, 'add_admin_hooks' ) );
add_action( 'init', array( &$this, 'add_frontend_filters' ) );
// Hook into plugin activation/deletion
register_activation_hook(__FILE__, array( &$this, 'set_default_sample_plugin_options' ) );
if ( function_exists( 'register_uninstall_hook' ) )
register_uninstall_hook( __FILE__, array( &$this, 'sample_plugin_uninstall' ) );
}
/**
* Add admin hooks.
*/
function add_admin_hooks() {
if ( $this->should_append_on_publication() ) {
// Add a filter to wp_insert_post_data called append_on_publish (declared below), with priority 10 and passing 2 parameters
add_filter( 'wp_insert_post_data', array( &$this, 'append_on_publish' ), 10, 2 );
add_filter( self::filters_prefix . 'append_on_publish', array( &$this, 'append_to_content' ) );
}
$this->add_sample_plugin_settings();
}
/**
* Filter posts when they change statuses from auto-draft to publish to append a string.
*
* @param array $sanitized_post Sanitized post data to insert into the database.
* @param array $raw_post Raw post data from the compose form.
* @return array The sanitized post with the appropriate filters applied to it.
* @see Core filter: wp_insert_post_data
*/
function append_on_publish( $sanitized_post, $raw_post ) {
// If the status is changing from auto-draft to publish, add the text specified by the plugin's settings.
// This logic is far from foolproof, but it's a decent mechanism to add text the first time it is published.
if ( $raw_post['original_post_status'] === 'auto-draft' && $raw_post['post_status'] === 'publish') {
$sanitized_post['post_content'] = apply_filters( self::filters_prefix . 'append_on_publish', $sanitized_post['post_content'] );
}
return $sanitized_post;
}
/**
* Add front-end filters.
*/
function add_frontend_filters() {
if ( !$this->should_append_on_publication() ) {
// Append text when displaying the content of every post using the filter "the_content"
add_filter( 'the_content', array( &$this, 'append_to_content' ) );
// Also add a FB Like button to all posts
// Add with priority 1000 (very low priority) so we are certain that this text will be appended absolutely last to the post.
add_filter( self::filters_prefix . 'append_to_content', array( &$this, 'add_fb_like_button' ), 1000 );
}
// Append generic text to all posts
add_filter( self::filters_prefix . 'append_to_content', array( &$this, 'append_generic_text' ) );
}
/**
* Apply a filter to the given string to allow appending to it.
*
* @param string $content The string to which to add text.
* @return string The filtered string.
*/
function append_to_content( $content ) {
$content .= apply_filters( self::filters_prefix . 'append_to_content', '' );
return $content;
}
/**
* Append the text set by the plugin's options to the given string and return it.
*
* @param string $end_of_content The string to which to add text.
* @return string The appended string.
*/
function append_generic_text( $end_of_content ) {
$options = get_option( self::sample_plugin_settings );
$string_to_append = $options['append_text'];
return $end_of_content . $string_to_append;
}
/**
* Add a Facebook Like button for the current post to posts when the post itself is being viewed (is_single is true).
*
* @param string $end_of_content The current string to append to content.
* @return string The appended string given with a Facebook Like button added.
* @see http://developers.facebook.com/docs/reference/plugins/like
* @see http://php.net/manual/en/function.urlencode.php
*/
function add_fb_like_button( $end_of_content ) {
global $post;
if ( is_single( $post ) ) {
// Use PHP function urlencode() to turn all non-alphanumeric characters into their hex equivalent to the link works
$end_of_content .= '<iframe src="http://www.facebook.com/plugins/like.php?href='
. urlencode( get_permalink( $post->ID ) )
. '&amp;layout=box_count&amp;show_faces=true&amp;width=450&amp;action=like&amp;colorscheme=light&amp;height=65" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:450px; height:65px;" allowTransparency="true"></iframe>';
}
return $end_of_content;
}
/**
* Add the plugin's settings sections and fields. Since there are only two fields, we'll add them to the "Writing" page in the admin.
* A new settings page could be added using add_options_page().
*/
function add_sample_plugin_settings() {
add_settings_section( self::sample_plugin_settings,
'Sample Plugin Settings',
array( &$this, 'sample_plugin_settings_section' ),
'writing' );
add_settings_field( 'append_text',
'Text to append<br /><small><em>Limited HTML may be used</em></small>',
array( &$this, 'sample_plugin_append_text' ),
'writing',
self::sample_plugin_settings );
add_settings_field( 'append_on_publication',
'Append on publication',
array( &$this, 'sample_plugin_append_on_publication' ),
'writing',
self::sample_plugin_settings );
// Register the setting so that it automagically gets saved into the database and its fields are sanitized.
register_setting( 'writing',
self::sample_plugin_settings,
array( &$this, 'sample_plugin_validate_settings' ) );
}
/**
* Add the settings section, which is pretty much just a header.
*/
function sample_plugin_settings_section() {
echo "<p>Enter the text below that should be appended to all posts.</p>";
}
/**
* Add the textarea to allow input for what should be appended to posts.
*/
function sample_plugin_append_text() {
$options = get_option( self::sample_plugin_settings );
$option_key = 'append_text';
// Let's use a little bit of HTML5 with placeholder text. Degrades nicely.
echo "<textarea name='" . self::sample_plugin_settings . "[$option_key]' cols='50' placeholder='Enter text here to append to all posts'>" . $options[$option_key] . "</textarea>";
}
/**
* Add the checkbox to decide whether text should be appended on publication or display.
*/
function sample_plugin_append_on_publication() {
$options = get_option( self::sample_plugin_settings );
$option_key = 'append_on_publication';
$append_on_publication = $options[$option_key];
$explanation = "Check this box if the above text should only be added when a post is published. Uncheck it if the text should be added each time the post is displayed.";
echo "<input type='checkbox' name='" . self::sample_plugin_settings . "[$option_key]' id='" . self::sample_plugin_settings . "[$option_key]' value='1' " . checked(1, $append_on_publication, false) . " />";
echo "<label for='" . self::sample_plugin_settings . "[$option_key]' style='margin-left:5px'>$explanation</label>";
}
/**
* Sanitize the plugin settings and return the full options array.
*
* @param array Settings array from settings page, unsanitized.
* @return array Sanitized settings array with other plugin options added back in.
* @see wp_kses_post
* @see http://ottopress.com/2010/wp-quickie-kses/
* @see http://lists.automattic.com/pipermail/wp-hackers/2010-October/035389.html
*/
function sample_plugin_validate_settings($input) {
// Retrieve the current settings so we don't lose any data already in the array.
$options = get_option( self::sample_plugin_settings );
// Normally you might want to iterate through the input array and sanitize each key/value differently.
// Here there are only two keys/values, so we'll process each manually.
$options['append_text'] = wp_kses_post( $input['append_text'] );
// See: http://lists.automattic.com/pipermail/wp-hackers/2010-October/035397.html
$options['append_on_publication'] = !empty( $input['append_on_publication'] );
return $options;
}
/**
* Determine from the plugin settings whether content should be appended on publication (when a post is first
* published - normally happens once) or on display (happens every time the post is displayed).
*
* @return True if content should be appended on publication (once),
* false if content should be appended whenever viewing posts on the front-end.
*/
function should_append_on_publication() {
$options = get_option( self::sample_plugin_settings );
return empty( $options ) || $options['append_on_publication'];
}
/**
* Add default options to the database, or run any update script required with a new version of the plugin.
*/
function set_default_sample_plugin_options() {
// Set up the default options
$default_options = array(
'append_text' => '',
'append_on_publication' => true,
'version' => '1.1',
);
// Get the currently installed options, if there are any
$installed_options = get_option( self::sample_plugin_settings );
if ( empty( $installed_options ) ) {
// If no options are currently installed, install the default options
add_option( self::sample_plugin_settings, $default_options );
$installed_options = $default_options;
} else if ( array_key_exists( 'version', $installed_options )
&& $this->version_number_as_float( $installed_options['version'] )
< $this->version_number_as_float( $default_options['version'] ) ) {
// Update plugin to some future version greater than 1.1
$installed_options['version'] = $default_options['version'];
update_option( self::sample_plugin_settings, $installed_options );
}
}
/**
* Delete options from the database when the plugin is uninstalled.
*/
function sample_plugin_uninstall() {
delete_option( self::sample_plugin_settings );
}
/**
* Returns a float value representing the provided string version. e.g. 1.0.1 will be returned as 1.01.
* This is useful for version number comparisons.
*
* @param string The version in x.y.z format (ad infinitum).
* @return float A float representing the current version number in major.minor format.
*/
function version_number_as_float( $version ) {
$version_numbers = explode('.', $version);
for ($i = 0, $multiplier = 1; $i < count( $version_numbers ); ++$i, $multiplier /= 10)
$version_float += $version_numbers[$i] * $multiplier;
return $version_float;
}
} // end class Sample_Plugin
}
// Initialize plugin and save (prefixed!) in global context in case someone else wants to use it.
global $bressler_sample_plugin;
$bressler_sample_plugin = new Sample_Plugin();
?>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment