Spencer FengSpencer Feng

Category: wordpress

Using namespaces and autoloading with Composer in WordPress plugins

Namespace and autoload are not widely adopted when it comes to WordPress plugin development, since WordPress’s commitment to backward compatibility with PHP as old as 5.2.4, whereas, namespace is only available since version 5.3.0. In addition, Composer requires PHP 5.3.2+. However, if you are creating a WordPress website which will be run on a server whose PHP version is newer than to 5.3.2, you are safe to use namespace and autoload with Compser.

In this tutorial, I will create a WordPress plugin which generates a shortcode which displays today’s date. First, I will use require_once to include classes and then I will use namespace and autoload with Composer to include classes. Without further ado, let’s get started now.

Creating the Plugin Directory

We need a bootstrap file and some folders to contain the PHP classes we will create inside the folder of our plugin. Let’s go ahead and create them now:

Then, let’s open the plugin bootstrap file and add the following block of code to the top of it, so that our plugin can be activated through the WordPress Plugin activation screen.

<?php 
/**
 * Plugin Name: Namespace Autoload with Composer Demo
 * Plugin URI: https://www.spencerfeng.com.au/using-namespaces-and-autoloading-with-composer-in-wordpress-plugins
 * Description: Learn how to use namespaces and autoloading with composer in WordPress plugins.
 * Version: 0.1.0
 * Author: Spencer Feng
 * Author URI: https://www.spencerfeng.com.au
 * License: GPL2
 */

Then, if you can go to the WordPress Plugin Page in the administration area to activate it, though nothing will happen after you activate it, since we have not add any functionality to our plugin.

Adding a shortcode

Next, we are going to create the class which generates the the shortcode. Let’s create a file called ‘DisplayTodaysDateShortcode.php’ in the ‘inc/classes/Shortcodes’ directory and add the following code to it:

<?php 
/**
 * This is the class responsible for the 'display_todays_date' shortcode.
 */

class DisplayTodaysDateShortcode
{
    public function register($atts, $content = null)
    {
        return 'Today is ' . date("d/m/Y");
    }

    public function init()
    {
        add_shortcode('display_todays_date', array($this, 'register'));
    }
}

As you can see, the handle of this shortcode is ‘display_todays_date’ and it displays today’s date.

Create the class for the plugin

Then we are going to create the class where we can register all the shortcodes that might be created in the plugin, though we only have one shortcode in this plugin. Let’s create a file called ‘Plugin.php’ in the ‘inc/classes’ directory and then paste the code below to it:

<?php 
/**
 * This is the class for this plugin.
 */

class Plugin
{
    private $shortcodes;

    public function __construct()
    {
        $this->shortcodes = array();
    }

    public function addShortcode($shortcode) 
    {
        array_push($this->shortcodes, $shortcode);
    }

    private function registerShortcodes()
    {
        if (count($this->shortcodes)) {
            foreach ($this->shortcodes as $shortcode) {
                $shortcode->init();
            }
        }
    }

    public function init()
    {
        // Register all shortcodes 
        $this->registerShortcodes();
    }
}

The ‘Plugin’ class has an array which contains all the shortcodes classes and we can use its ‘init()’ method to register all shortcodes in the container.

Instantiate the classes

Now, let’s go back to the plugin bootstrap file ‘namespace-autoload-with-composer-demo.php’ and put the code below to it after the comments at the top:

define('BASE_PATH', plugin_dir_path(__FILE__));
define('BASE_URL', plugin_dir_url(__FILE__));

// include the classes
require_once BASE_PATH . 'inc/classes/Shortcodes/DisplayTodaysDateShortcode.php';
require_once BASE_PATH . 'inc/classes/Plugin.php';

// instantiate classes
$shortcode = new DisplayTodaysDateShortcode();
$plugin    = new Plugin();

// register all shortcodes
$plugin->addShortcode($shortcode);

// initialise the plugin
$plugin->init();

Now, if you add the shortcode [display_todays_date] to a page, you will see the current date of your local time, like the screenshot below:

Integrate Composer into the plugin

Since the plugin is working now, it is time for us to update it so that it can use namespace and autoload. The first thing to do is to integrate Composer into it. Composer is a dependency manager for PHP which allows you to pull in all the required libraries, dependancies and manage them all in one place for your project. In this tutorial, we will not cover that aspect of Composer, instead, we will utilise the autoload function that comes with Composer for our WordPress plugin.

First, you need to install Composer on your computer if do not have it already. Composer provides detailed installation instructions on its official website. If you are a Linux / Unix / OSX user, please click here for the instructions. If you are a Windows user, please click here for the instructions.

Once we have Composer installed on our computer, let’s create a file called ‘composer.json’ in the root folder of the plugin and then add the code below to it:

{
    "autoload": {
        "psr-4": {
            "Spencerfeng\\NamespaceAutoloadWithComposerDemo\\": "inc/classes"
        }
    }
}

What the code does is that it maps the namespace “Spencer\NamespaceAutoloadWithComposerDemo” the “inc/classes” directory in our plugin.

Now let’s open the command-line tool and run the below command in the root directory of the plugin:

$ composer install

After running this command, we can see that a ‘vendor’ folder was added to the root folder of the plugin:

There are several files in the ‘vendor’ folder, but the only file we need to touch is the ‘vendor/autoload.php’ file which returns a loader object that contains the information we need to instruct the system on how to map namespace to its corresponding directory.

Let’s include ‘vendor/autoload.php’ in our plugin bootstrap file ‘namespace-autoload-with-composer-demo.php’  just below the code where we define 2 constants:

// include the Composer autoload file
require BASE_PATH . 'vendor/autoload.php';

Add namespace to our classes

Now since we have our loader in place, let’s go to add  namespace to the classes.

Please add the code below to the ‘inc/classes/Shortcodes/DisplayTodaysDateShortcode.php’ file, just above the class definition:

namespace Spencerfeng\NamespaceAutoloadWithComposerDemo\Shortcodes;

Please add the code below to the ‘inc/classes/Plugin.php’ file, just above the class definition:

namespace Spencerfeng\NamespaceAutoloadWithComposerDemo;

Load classes in the plugin bootstrap file

Now, since all the classes in the plugin are namespaced, we are going to change the way of loading them in the plugin bootstrap file.

Let’s navigate to the plugin bootstrap file and replace the code below:

// include the classes
require_once BASE_PATH . 'inc/classes/Shortcodes/DisplayTodaysDateShortcode.php';
require_once BASE_PATH . 'inc/classes/Plugin.php';

with:

use Spencerfeng\NamespaceAutoloadWithComposerDemo\Shortcodes;
use Spencerfeng\NamespaceAutoloadWithComposerDemo\Plugin;

Then let’s replace the code which we instantiate the ‘DisplayTodaysDateShortcode’ class:

$shortcode = new DisplayTodaysDateShortcode();

with:

$shortcode = new Shortcodes\DisplayTodaysDateShortcode();

What we do with the above changes is that we use the ‘use’ PHP keyword to import the ‘Plugin’ class and the ‘Spencerfeng\NamespaceAutoloadWithComposerDemo\Shortcodes’ namespace to the current scope and since the ‘DisplayTodaysDateShortcode’ class is in the ‘Spencerfeng\NamespaceAutoloadWithComposerDemo\Shortcodes’ namespace, when we instantiate the class, we need to prepend the namespace.

Now, if you go to the page where the shortcode is added, you can see that the text that the shortocde generates is still there.

You can view the source code for this tutorial on GitHub.

Please sign up to my Newsletter if you want to get notified when new tutorials are available.

×