Image
WordPress and Composer

Hey there! I've been a WordPress developer for 4+ years now. In my old job, I managed a single WordPress site while still learning how to code. In the WordPress ecosystem, composer has not really been adopted in a substantial way and so when I came to work at Rad Campaign I had very little understanding of composer. Rad Campaign manages lots of websites that are on a number of different content management systems and frameworks. Drupal and Laravel for instance make great use of composer and installing modules or Laravel packages is typically done with a swift 'composer require' in the command line. Thus, if I wanted to make myself useful on any other projects, I had to learn a thing or two about composer and just like most things in the coding world, once I learned how to use it, I could no longer live without it.

Using composer, has greatly changed the way I build WordPress plugins and themes. The biggest difference for me came when I started using composer instead of requiring all of my source files in my project at the head of my executing script or writing some "spl_auto_register" function at the head of that same script.  So lets say we have the following project structure:

Image
folder structure for wordpress composer plugin example

Since this project is a WordPress Plugin, when the plugin is activated, WordPress will execute the "composer_autoload_plugin.php" file (this file is what I mean by "my executing script"). In the past, to get all of the files in my "src" directory loaded, I would have dome something like this in "composer_autoload_plugin.php":

<?php
// require all of our src files
require_once('./src/Interfaces/GreetInterface.php');
require_once('./src/Greeters/Mean.php');
require_once('./src/Greeters/Nice.php');
require_once('./src/GreetGenerator.php');
// ... rest of code

Here you can see how crazy this can get, especially if I had a plugin that has a lot of source code. Alternatively, you could write your own autoloader using 'spl_autoload_register' but then you'd have to stick to your own conventions and test rather significantly to make sure it works. 

There is a really cheap and easy way forward: use composer

Step 1: Make sure you have composer installed

For steps on how to install composer, click here. If you aren't sure simply type `which composer` in your linux command line. If nothing comes up, you need to install composer.

Step 2: Initiate composer in your project

From the base root of your project, fire up composer and follow the prompt to define your own composer.json. This will create a composer.json in the base of your project.

> composer init

 

Step 3: Configure the autoloader

We need to tell composer how to create the autoloader. To do this, you need to open up your composer.json in your favorite text editor (I use Sublime Text, Xaq uses vim (because he's a wizard), maybe you use atom, really it doesn't matter). Add "autoload" as a key to the composer configuration. 

The value to the "autoload" key will be  a dictionary keyed by the autoloading standard you want to use. The value for the standard will either be an array or a dictionary based on what composer expects. Here's all of the possible autoload keys that composer accepts with examples on how they are configured. I like to use the PSR-4 standard for all my classes and will also frequently use the "files" rule to load any individual file that might provide some procedural functions like a "helpers.php." For the PSR-4 standard, the value will be a dictionary keyed by your "main namespace" and each namespace defines the folder that roots that namespace. Here's an example:

Image
Example composer.json

Here you can see that the PSR-4 standard is a great way to load classes based on location in your project. I won't go too deep into how the PSR-4 standard works but basically it will allow you to define a namespace, and then all sub namespaces will be directories in your project from which you told composer where the root of your main namespace starts. And finally, in this standard, the class name will match the file name. For more information on the PSR-4 standard click here.

So, from this, lets say I ask for a class "RAD_COMPOSER\Examples\GreatExample". Wherever this class is invoked in my plugin, once it is invoked, composer's autoloader will try and fulfill this invocation by looking in "src/Examples/" and will look for a file named "GreatExample.php" for the class. If it can't find the class, it will throw an error that the class was not found or it doesn't exist.

Step 4: Run `composer install` from your plugin root directory. 

Doing this now will create the autoloader and put it in the "./vendor" directory.  Remember our code example at the beginning of this article for the main plugin execution file with all of the "require_once" statements (in this example it is "composer_autoload_plugin.php")? Well now all you have to do is the following:

<?php

// require all of our src files

require_once(plugin_dir_path(__FILE__) . '/vendor/autoload.php');

// ... rest of code

 

From here on out, whenever we try to do something like `new RAD_COMPOSER\GreeterGenerator();`, your application will know to find that class in `./src`. If we try to do something like `new RAD_COMPOSER\Greeters\Mean()`, your application will automatically look for the class in `./src/Greeters/Mean.php`. Please note though that `RAD_COMPOSER\Greeters\Mean` must exist in that file. Thus you will have to namespace that file appropriately like so:

<?php

// ./src/Greeters/Mean.php

namespace RAD_COMPOSER\Greeters;


class Mean {

// ... rest of code

}

 

Step 5 (Optional Last Step): Change the name of the vendor directory.

If you, like me, are writing a plugin that requires the autoloader, you will need that autoloader to ship with the rest of your code. If you use git, it's pretty common in git tracked projects to ignore any "vendor" directories in the project's main `.gitignore` file. For this reason, it can be pretty useful to change the composer install directory so that any `.gitignore` files found higher up in the project don't accidentally ignore your install directory. To do this all you need to do is put the following in your composer.json (without the comments).

{

    // rest of composer.json

    "config": {

        "vendor-dir": "lib"

    },

    // rest of composer.json

}

 

Now composer will install the autoloader in a directory named "lib" instead of in the vendor directory. Open back up your main plugin execution file, again in this example it is "composer_autoload_plugin.php", and change "./vendor/autoload.php" to "./lib/autoload.php" like so:

<?php

// require all of our src files

require_once( plugin_dir_path(__FILE__) . '/lib/autoload.php'); // <- change happening here

// ... rest of code

 

Conclusion

As you can see it's really not that difficult to use composer and set up the autoloader for your project. A really nice benefit of doing it this way is that you will be enforcing on yourself some pretty well known standards, in this example, the PSR-4 standard. Standards like these are well documented. Using widely used, well documented standards that were created by the open source community means that there is a really good chance that whomever comes along later to fix your code or add features will either instantly recognize the pattern or will have resources on the web to find the pattern and know where to add new classes or find broken ones. Thanks for reading this far and happy coding!