Archive for category Software Development

GoMySQL 0.2

Today the latest version of GoMySQL is available from the Github repository.

This is a beta version and can be obtained by checking out the master branch.

This version includes bug fixes and standardisation of function format, it will also include some new features which will be added over the next few days.

  • Share/Bookmark

First Go Library

My first library written in the Go programming language, GoMySQL, is now complete and available to download from my projects pages.

The library fully implements the MySQL protocol and supports the majority of the common features found in other libraries, including:

  • Single queries
  • Multiple queries
  • Change database
  • Prepared statements

There are a number of other libraries available for Go, but none of them (as yet) implement the full protocol.

To download visit the GoMySQL project page.

  • Share/Bookmark

jQuery chat plugin

The aim of the plugin is to provide a Facebook-like chatroom that can easily be added to any website. The plugin is written in Javascript and makes heavy use of the jQuery library to simplify implementation and integration.

The proposed features are:

  • Changable online status
  • Auto-away
  • Chatrooms
  • Private messaging
  • Friends list
  • Anything else that looks cool!

I have finished work on version 0.1 which is the first working version, here are a few screenshots:

The Status Menu

The status menu

The Friends List

The friends list

An example chat room

An example chat room

I have not added private messaging yet, but this will be added in a future version.

Targets for version 0.2:

  • Add private messaging
  • Improve PHP callback API
  • Improve speed of message display
  • Look at using persistent AJAX requests (Comet)
  • Share/Bookmark

WordPress Plugin – Final tweaks

The plugin is now pretty much finished, there are certainly other options that could be added such as page summaries via AJAX, custom image sizes for specific preview etc but for now the only thing that is really left to do is to add a quicktag option so that the plugin can be easily used from the post editor.

This is very simple to do, first I have created a hook to add a script file:

add_action(‘admin_print_scripts’, array(&$this, ‘Admin_Script’));

This script is only loaded within the admin (hence the action is ‘admin_print_scripts’) and it tells WordPress which function to get the script definition.

The Admin_Script function attaches a simple Javascript file to add the quicktag:

/**
 * Load admin javascipt file
 *
 * @return void
 */

function Admin_Script() {
        wp_enqueue_script(‘wp-thumbshot-preview’,
                          plugin_dir_url(__FILE__) . ‘wp-thumbshot-preview.js’,
                          array(‘quicktags’),
                          ’0.1′);
}

It’s fairly obvious what this does, worth noting that quicktags is a prerequisite (so that the quicktags Javascript functions are loaded first).

The Javascript file ‘wp-thumbshot-preview.js’ contains the quicktag definition:

edButtons[edButtons.length] =
        new edButton(‘preview’,
                     ‘preview’,
                     ‘[preview]‘,
                     ‘[/preview]‘,
                     );

Now in the code editor there is a ‘preview’ button so that the plugin’s preview tags can be auto completed!

  • Share/Bookmark

WordPress Plugin – Admin options page

The next step following the database integration is a simple settings page to change the plugin options. This is achieved with another hook to add an item to the menu in the admin area:

add_action(‘admin_menu’,  array(&$this, ‘Admin_Menu’));

This alone doesn’t do anything other than telling WordPress to call the ‘Admin_Menu’ function at the right time, the function then tells WordPress the menu item to add and which page to open via the add_options_page API function:

/**
 * Create admin menu settings item
 *
 * @return void
 */

function Admin_Menu() {
        add_options_page(‘Thumbshot Preview Settings’,
                         ‘Thumbshot Preview’,
                         8,
                         basename(__FILE__),
                         array(&$this, ‘Admin_Settings’));
}

This creates the page link on the menu as ‘Thumbshot Preview’ and informs which file (the current plugin PHP file) and which function to call ‘Admin_Settings’. The number 8 refers to the user level required to access the page, in this case it is only available to the WordPress admin.

The Admin_Settings function simply outputs some HTML and also provides some very basic form validation and obviously also does the database updates. I have copied the styles and layouts from a standard WordPress settings page to ensure my page is consistent with the default styles. Here is the completed function:

/**
 * Display the admin setting page
 *
 * @return void
 */

function Admin_Settings() {
        $msg = null;
        // If form submitted save options
        if ($_SERVER[‘REQUEST_METHOD’] == ‘POST’) {
                // If free mode, very loose validation as most options are not needed
                if ($_POST[‘tsp_mode’] == ‘free’) {
                        update_option(‘WP_Thumbshot_Preview_Mode’, ‘free’);
                        if (is_numeric($_POST[‘tsp_cid’])) {
                                update_option(‘WP_Thumbshot_Preview_Cid’, $_POST[‘tsp_cid’]);
                        }
                        if (is_numeric($_POST[‘tsp_width’])) {
                                update_option(‘WP_Thumbshot_Preview_Width’, $_POST[‘tsp_width’]);
                        }
                        if (is_numeric($_POST[‘tsp_height’])) {
                                update_option(‘WP_Thumbshot_Preview_Height’, $_POST[‘tsp_height’]);
                        }
                        $msg = ‘Settings saved.’;
                }
                // For paid mode make sure the cid is numeric or do not save anything
                if ($_POST[‘tsp_mode’] == ‘paid’) {
                        if (is_numeric($_POST[‘tsp_cid’])) {
                                update_option(‘WP_Thumbshot_Preview_Mode’, ‘paid’);
                                update_option(‘WP_Thumbshot_Preview_Cid’, $_POST[‘tsp_cid’]);
                                if (is_numeric($_POST[‘tsp_width’])) {
                                        update_option(‘WP_Thumbshot_Preview_Width’, $_POST[‘tsp_width’]);
                                }
                                if (is_numeric($_POST[‘tsp_height’])) {
                                        update_option(‘WP_Thumbshot_Preview_Height’, $_POST[‘tsp_height’]);
                                }
                                $msg = ‘Settings saved.’;
                        } else {
                                $msg = ‘Please enter a valid user id.’;
                        }
                }
                // Refresh options
                $this->Populate_Settings();
        }
        // Display the page HTML, kinda dirty but quick!
        echo
<div class="wrap">
        <div id="icon-options-general" class="icon32"><br /></div>
        <h2>Thumbshot Preview Settings</h2>’
.(!is_null($msg) ? ‘<div style="background-color: #fffbcc;" id="message" class="updated fade"><p><strong>’.$msg.‘</strong></p></div>’ : null).
        <form method="post">
                <input type="hidden" name="action" value="update" />
                <table class="form-table">
                        <tr valign="top">
                                <th scope="row"><label for="tsp_mode">Plugin mode</lable></th>
                                <td>
                                        <select name="tsp_mode" id="tsp_mode">
                                                <option ‘
.($this->mode == ‘free’ ? ‘selected="selected" ‘ : null).‘value="free">Free</option>
                                                <option ‘
.($this->mode == ‘paid’ ? ‘selected="selected" ‘ : null).‘value="paid">Paid</option>
                                        </select>
                                        <span class="description">If you have a <a href="http://www.thumbshots.com/">Thumbshots.com</a> account select paid otherwise use the free <a href="http://www.thumbshots.org/">Thumbshots.org</a> service.</span>
                                </td>
                        </tr>
                        <tr valign="top">
                                <th scope="row"><label for="tsp_cid">User ID</lable></th>
                                <td>
                                        <input name="tsp_cid" id="tsp_cid" type="text" value="’
.$this->cid.‘" class="small-text" />
                                        <span class="description">Your <a href="http://www.thumbshots.com/">Thumbshots.com</a> user id. [Paid service only]</span>
                                </td>
                        </tr>
                        <tr valign="top">
                                <th scope="row"><label for="tsp_width">Default image width</lable></th>
                                <td>
                                        <input name="tsp_width" id="tsp_width" type="text" value="’
.$this->width.‘" class="small-text" />
                                        <span class="description">The default preview image width. [Paid service only]</span>
                                </td>
                        </tr>
                        <tr valign="top">
                                <th scope="row"><label for="tsp_height">Default image height</lable></th>
                                <td>
                                        <input name="tsp_height" id="tsp_height" type="text" value="’
.$this->height.‘" class="small-text" />
                                        <span class="description">The default preview image height. [Paid service only]</span>
                                </td>
                        </tr>
                </table>
                <p class="submit">
                        <input type="submit" name="Submit" class="button-primary" value="Save Changes" />
                </p>
        </form>
</div>
        ‘
;
}

The validation here isn’t perfect, but it does the job. Considering the simplicity of this plugin it doesn’t really make much sense to spend time making it any more complex than this. It would be nice to use templates for the HTML as well but again as this is a simple plugin it doesn’t really warrant the complexity.

Here is a screen shot of the settings page:

Thumbshots Preview Settings

Note: The functions listed here are used as part of the object defined in my previous post.

  • Share/Bookmark

WordPress Plugin – Database integration

The next step with the plugin is to add some database integration so the plugin options can be stored in the WordPress database. This is really simple as the API provides funtions for this in the form of the functions add_option, get_option, update_option and delete_option.

To ensure that the database is populated with some defaults, a hook can be added to do this:

register_activation_hook(__FILE__,   array(&$this, ‘Activate’));
/**
 * Activation function – adds database settings
 *
 * @return void
 */

function Activate() {
        add_option(‘WP_Thumbshot_Preview_Mode’,   ‘free’, , ‘yes’);
        add_option(‘WP_Thumbshot_Preview_Cid’,    ,     , ‘yes’);
        add_option(‘WP_Thumbshot_Preview_Width’,  ’160′,  , ‘yes’);
        add_option(‘WP_Thumbshot_Preview_Height’, ’120′,  , ‘yes’);
}

This will be triggered when a user installs the plugin and the default options will be saved to the WordPress options database.

I have also added a deactivation hook to clean up the options from the database when the plugin is deactivated:

register_deactivation_hook(__FILE__, array(&$this, ‘Deactivate’));
/**
 * Deactivation function – removes database settings
 *
 * @return void
 */

function Deactivate() {
        delete_option(‘WP_Thumbshot_Preview_Mode’);
        delete_option(‘WP_Thumbshot_Preview_Cid’);
        delete_option(‘WP_Thumbshot_Preview_Width’);
        delete_option(‘WP_Thumbshot_Preview_Height’);
}

The default options are set to use the free version of Thumbshots, so the plugin instantly works on activation without any changes to the default settings. To complete the database integration I have also added a function to get the default options from the database when the plugin is loaded (this function is run from the constructor):

/**
 * Populate settings from WP
 *
 * @return void
 */

function Populate_Settings() {
        // Usage mode (defaults to free if database settings are missing)
        if (($mode = get_option(‘WP_Thumbshot_Preview_Mode’)) !== false) {
                $this->mode = $mode;
        }
        // Thumbshots cid for paid mode
        if (($cid = get_option(‘WP_Thumbshot_Preview_Cid’)) !== false) {
                $this->cid = $cid;
        }
        // Image width for paid mode
        if (($width = get_option(‘WP_Thumbshot_Preview_Width’)) !== false) {
                $this->width = $width;
        }
        // Image height for paid mode
        if (($height = get_option(‘WP_Thumbshot_Preview_Height’)) !== false) {
                $this->height = $height;
        }
}

Note: The functions listed here are used as part of the object defined in my previous post.

  • Share/Bookmark

WordPress Plugin – Further deveopment

Now that I have a very simple working plugin it’s time for a little clean up.

Before I start adding addition functions and build additional features in messy procedural style it makes sense at this state to make it object orientated. WordPress continues to support PHP 4.3 and upwards, hence the plugin should also support PHP 4 configurations.

Here is the class made from the original function, variables have been moved to the object’s global scope, the hooks are included in the constructor and the Render() function now contains the regex replacements:

class WP_Thumbshot_Preview {

        /**
         * Which mode to use, free or paid.
         *
         * @var string
         */

        var $mode = ‘free’;

        /**
         * The user id (for paid mode).
         *
         * @var integer
         */

        var $cid;

        /**
         * The image width
         *
         * @var integer
         */

        var $width;

        /**
         * The image height
         *
         * @var integer
         */

        var $height;

        /**
         * Constructor
         *
         * @return void
         */

        function WP_Thumbshot_Preview() {
                add_filter(‘the_content’, array(&$this, ‘Render’));
        }

        /**
         * Render the content
         *
         * @param $content string
         * @return string
         */

        function Render($content) {
                // Free mode
                if ($this->mode == ‘free’) {
                        $content = preg_replace("/\[preview\](.+?)\[\/preview\]/i",
                                                "<a href=\"$1\" target=\"_blank\"><img src=\"http://open.thumbshots.org/image.aspx?url=$1\" /></a><br />
                                                 <a href=\"$1\" target=\"_blank\">$1</a>"
,
                                                $content);
                }
                // Paid mode
                if ($this->mode == ‘paid’) {
                        $content = preg_replace("/\[preview\](.+?)\[\/preview\]/i",
                                                "<a href=\"$1\" target=\"_blank\"><img src=\"http://simple.thumbshots.com/image.aspx?cid=$this->cid&v=1&w=$this->width&h=$this->height&url=$1\" /></a><br />
                                                 <a href=\"$1\" target=\"_blank\">$1</a>"
,
                                                $content);
                }
                return $content;
        }
}

This is much tidier than before :)

Now to make everything work all that is required is an instance of the object:

new WP_Thumbshot_Preview();
  • Share/Bookmark

My first WordPress Plugin

As I have an account with Thumbshots.com I thought it would be nice to include it on my blog and have preview images of links in posts. Despite the 1000′s of WordPress plugins available, unfortunately none of them worked specifically for Thumbshots. :(

I noticed there were a few similar plugins which worked with alternative thumbnail sites, so initially thought that I could hack them up a bit to use with Thumbshots. Another dead end, none of them seamed to have the features I was looking for.

So it looks like I’ll have to make a plugin…

In the whole 24 hours I have been using this version of WordPress I have been impressed with how it has evolved since I last used it, especially in that it is so easy to use. Plugin development is no exception to this.

There are 2 versions of Thumbshots, both a free and paid version (on .org and .com respectively), so it makes sense that if I am to eventually get this plugin to a point where I can publish it that it should support both. The free one can also be used ‘out of the box’ without an account or any configuration, whereas the paid one obviously requires an account and additional settings.

To get the plugin to work I needed to create the plugin information which is simply stuck in a comment block and WordPress recognises it, it looks something like this:

/*
Plugin Name: WP Thumbshot Preview
Plugin URI: http://www.philbayfield.com
Description: Add a preview image to a link using <a href="http://www.thumbshots.org/">Thumbshots.org</a> or <a href="http://www.thumbshots.com/">Thumbshots.com</a> account.
Version: 0.1
Author: Phil Bayfield
Author URI: http://www.philbayfield.com
/*

Secondly I needed a short function to perform the core functionality of the plugin. To enable the user to choose when they want to see a preview it made sense to use bbcode style tags so it could be easily used when adding or editing a post. Any URL wrapped in [preview] tags would be converted to a link with thumbnail image. I’ve hard coded the settings for now for testing purposes, the end result is this function:

/**
* Content filter function
*
* @param $content string
* @return string
*/

function wp_thumbshot_preview($content) {
        /**
        * Plugin usage mode (free or paid)
        *
        * @var string
        * @todo this needs to be replaced with a get_option call
        */

        $mode = ‘paid’;
        // Paid mode
        if ($mode == ‘paid’) {
                /**
                * Thumbshots user id
                *
                * @var integer
                * @todo this needs to be replaced with a get_option call
                */

                $cid    = 1508;
                /**
                * Image width
                *
                * @var integer
                * @todo this needs to be replaced with a get_option call
                */

                $width  = 160;
                /**
                * Image height
                *
                * @var integer
                * @todo this needs to be replaced with a get_option call
                */

                $height = 120;
                // Replace all [preview] tags
                $content = preg_replace("/\[preview\](.+?)\[\/preview\]/i",
                                        "<a href=\"$1\" target=\"_blank\"><img src=\"http://simple.thumbshots.com/image.aspx?cid=$cid&v=1&w=$width&h=$height&url=$1\" /></a><br />
                                         <a href=\"$1\" target=\"_blank\">$1</a>"
,
                                        $content);
        // Free mode
        } else {
                // Replace all [preview] tags
                $content = preg_replace("/\[preview\](.+?)\[\/preview\]/i",
                                        "<a href=\"$1\" target=\"_blank\"><img src=\"http://open.thumbshots.org/image.aspx?url=$1\" /></a><br />
                                         <a href=\"$1\" target=\"_blank\">$1</a>"
,
                                        $content);
        }
        return $content;
}

Finally to get this to work a hook is required which tells WordPress to run my new function on the post content:

add_filter(‘the_content’,‘wp_thumbshot_preview’);

That’s it, all done, this is what it produces:




To do:

  • Add default values
  • Store default values in the database
  • Modify the function to retrieve the settings from the database
  • Add a page in the admin console to customise the settings
  • Convert the plugin to OO format
  • Share/Bookmark