Perhaps not the snappiest title for a blog post, but it does sum up what I’m hoping to do with this one. When I started work on Pressmonkey – our lovely WordPress plugin for scheduling tweets – I was surprised that many WordPress best practices looked so old fashioned. It turned out there were good reasons for a lot of that but, as a dyed in the wool object-oriented developer I was uncomfortable with the prospect of slinging around global variables and creating 2000 line source code monsters.

No, I wanted to carve out a nice quiet namespace for my plugin and then, within that, further break down my project into packages. Something like

page/
persist/
service/
widgets/

And what’s more, I didn’t want fiddle around with require_once statements. I wanted my use statements to be enough on their own.

Of course, if you’re already using Composer, and the autoload.php file it generates, in your projects you know where I’m going with this – since that’s exactly they give you.

Let’s kick things off with a new plugin: happyhappyfuntime:

<?php
/**
* Plugin Name: Happyhappyfuntime
* Plugin URI: https://getinstance.com
* Description: All the fun stuff. And happy.
* Version: 1.0.0
* Author: mz 
* Author URI: https://getinstance.com
*/

If I save that in a directory named happyhappyfuntime and a file named happyhappyfuntime.php and throw them both in in my plugins directory, that's enough to get something up and running. Here's the evidence:

Now I could proceed to create add_action calls and new functions in happyhappyfuntime.php. But I want my namespaces and encapsulation damn it, so I'm going to foreswear all but the basics in this top-level file.

In order to get started, I need two things. Firstly (assuming I haven't already done this) I must get Composer. I can manage that by heading to the aptly named getcomposer.org and following the simple instructions. Secondly, I need to create a file named composer.json. I can put all sorts of things in there (see previous posts about using Composer to manage your WordPress site, for example) - but today I'm only interested in autoload.

I'm going to work with a namespace called getinstance\happyhappyfuntime (though I'm already wishing I'd chosen a shorter frivolous name). In order to generate the autoload file I need to map my namespace to the local filesystem:


{
    "autoload": {
        "psr-4": {
            "getinstance\\happyhappyfuntime\\": ["src/"]
        }
    }
}

In fact, I don't need to place that src/ in an array because I'm only specifying one directory, but I like to use this structure so when I add tests or other files that I want to simultaneously live under different root directories and within the same namespace, I can add these new roots to this list with minimal work.

Now I have a directory with two files - happyhappyfuntime.php and composer.json. In order to generate my autoload file I just need to invoke Composer:


$ composer install
Loading composer repositories with package information
Updating dependencies (including require-dev)
Nothing to install or update
Generating autoload files

Let's see what it has generated:


$ find .
.
./composer.json
./vendor
./vendor/composer
./vendor/composer/autoload_classmap.php
./vendor/composer/installed.json
./vendor/composer/LICENSE
./vendor/composer/autoload_static.php
./vendor/composer/autoload_psr4.php
./vendor/composer/autoload_namespaces.php
./vendor/composer/autoload_real.php
./vendor/composer/ClassLoader.php
./vendor/autoload.php
./happyhappyfuntime.php

Of primary interest to me is one file: vendor/autoload.php. It's this I have to require in order to ensure that the autoload magic works.

Now I'm ready to add a little functionality to my plugin. I'm going to create a root class and name it HappyPlugin. In order for it to be found I must place it in the src/ directory in a file named HappyPlugin.php. Note that, thanks to my configuration in composer.json, I don't need to place it in src/getinstance/happyhappyfuntime/. I have made the first part of the namespace implicit. Also check that the case of your filename and that of your class match exactly. Not all operating systems are as forgiving of differences as others.

Here is the class:


namespace getinstance\happyhappyfuntime;

class HappyPlugin
{
    public function init()
    {
        \add_action('wp_footer', array($this, "happyAlert"));
    }

    public function happyAlert()
    {
?>
        
<?php
    }

    public static function runner()
    {
        $pluginx = new HappyPlugin();
        $pluginx->init();
    }
}

You might be familiar with this structure if you've ever created a Java class that can be run from the command line. I define a static method named runner() which is responsible for instantiating and initialising the class. The class itself consists of an init() method in which I associate a method - happyAlert() - with the wp_footer hook.

happyAlert() aims to be to plugin development what the blink tag was to late 90s Web design - so much fun! It throws up a JavaScript alert. Of course, the class still needs to be kicked off from somewhere. I return to happyhappyfuntime.php and add a couple of lines:


/**
* Plugin Name: Happyhappyfuntime
* Plugin URI: https://getinstance.com
* Description: All the fun stuff. And happy.
* Version: 1.0.0
* Author: mz 
* Author URI: https://getinstance.com
*/

require_once("vendor/autoload.php");
getinstance\happyhappyfuntime\HappyPlugin::runner();

I use one of the few require_once statements I'm going to need while coding this plugin - that call acquires the autoload file - and ensures that properly named and referenced classes will be automatically included at instantiation time. Then I call the runner() method.

And I'm done!

So what have I won? At first glance, of course, I've written more code than I need - but as the happyhappyfuntime plugin grows, I'll begin to see benefits in terms of code organisation and reusability.

Imagine, for example, that I need routines for connecting to the database and making service calls, and managing widgets (all of which Pressmonkey does, in fact). Rather than have these in one place making a single class file flabby and hard to read, I can place the functionality in classes within discreet packages and use them in the plugin class's header.


namespace getinstance\happyhappyfuntime;

use getinstance\happyfuntime\persist\GetAllTheFun;
use getinstance\happyfuntime\service\FunFeed;
use getinstance\happyfuntime\widgets\FrownieBeGones;

Then I can intantiate them cleanly as needed:


        $persist = new GetAllTheFun();
        $facts = $persist->getFunFacts();
        $feed = new FunFeed();
        $thought = $feed->thoughtOfTheDay();
        $widgets = new FrownieBeGones();
        $happyjs = $widgets->frownieObliteratorJs();

Notice the lack of tortured require_once paths.

Another benefit of this approach is encapsulation. If you fill a plugin file (or a theme's functions.php file) with functions (as opposed to methods under a namespace) you risk clashing with other functions either in the core or in other plugins.

The happyhappyfuntime plugin, on the other hand embeds its action method within a class


\add_action('wp_footer', array($this, "happyAlert"));

so there is almost no risk of collision.

The last question is a tricky one. Do we bundle the vendor directory generated by Composer in our distributed plugin? Best practice would suggest the answer is no. You should generally install packages via composer at install time. But that wouldn't work for most users. Until such time as standard tools exist in core to deploy plugins via composer, and thus handle dependencies, I think we have to hold our noses and commit vendor vendor with the rest of our plugin.