If you approach a lot of WordPress plugin development from an object-oriented perspective, then you’re eventually going to hit a point where you’re not doing a lot of interaction directly with WordPress core itself.

And, in my mind, that’s a good thing. It’s a sign of an architecture that you’re properly structuring your code. That is:

  1. You have WordPress sitting at the foundational level,
  2. You have a set of classes that are sitting just above WordPress responsible for sending information to and from WordPress between the plugin,
  3. And you have the rest of your code that comprises the rest of the functionality.

How this is implemented can vary, but the general way I picture this is the same way I tend to think of the standard N-tier application where you have the data layer, application layer, and front-end.

Except for this time, you have the WordPress, a layer for communicating with WordPress and the rest of your code, and, you know, the rest of your code.

Stop Plugin Execution: How a plugin may be organized.

How a plugin may be organized.

So what happens when you want to stop plugin execution when it has to interact with a third-party dependency and should only execute if that dependency is present?

Stop Plugin Execution

Because of the nature of PHP and WordPress, there are some ways this can be done. The code I’m going to share doesn’t prescribe the way to do it.

Instead, this is a way to do it (which has been pulled from something that’s in development). Further, I’ll show how it interacts with a few other components of the plugins, as well.

1. The Constructor

If you read enough articles about WordPress and object-oriented programming, then you’re likely going to find that constructors should not be used to define hooks. And I agree.

It creates an unnecessary level of coupling, and it makes testing things harder. What, then, is the purpose of a constructor in WordPress-based code?

I use it for the same reasons you would expect in any other language: To initialize the properties of the class. In the code below, you’re going to see three things:

  1. I initialize a property,
  2. I check to see if a third-party dependency exists,
  3. If it doesn’t, then I add an error message,
  4. I update the property.

Sure, it’s verbose, but it also doesn’t resort to clever code for initializing values.

(The older I’ve gotten, the more I’ve grown fond of specific code as it makes it easier to read, pick up, and get going with at a faster rate than the alternative.)

2. The Initialization Method

Since we aren’t using a constructor to work with WordPress hooks, this functionality should exist within the context of another method.

This gives us a dedicated place to put this type of functionality, de-couple it from the rest of the class, and have it interact with WordPress only when the method is explicitly invoked.

But remember, the whole point of what I’m getting at has to do with stopping the execution of a plugin – not where to place hooks.

So let’s say that the third-party dependency doesn’t exist, then what? Recall in the constructor, a property was set that will allow us to determine if we should move forward with setting up hooks or not:

And when that’s in place, the rest of the code won’t execute.

A Lot of Words, a Little Code

It sounds like a lot of explanation for such very little code.

But a portion of this is also to try to convey the significance of having parts of a WordPress-based project separated from the rest of core so that the parts can interact with themselves without explicitly needing to talk with core all the time.


Join the conversation! 3 Comments

  1. Hey Tom,

    Sounds like you’re working on a more complex site there. I’ve faced similar issues as well, where a single project is a combination of several dozens of custom plugin in combination with another dozen third-party premium plugins.

    I’ve opted for a different way of dealing with this, as I wanted to not only solve the problem of missing dependencies, but also that of loading order, where dependencies might be installed, but will only be loaded in a plugin that comes at an alphabetically later stage.

    Here’s what I did, and how that solved my problem(s)…

    First of all, I decided that plugins do not simply start adding actions and filters nilly-willy. I wanted to have a bit more structure (in terms of conventions). So, every single of my plugins has 1 or more “Service Provider(s)”. Each “Service Provider” provides 1 or more “Service(s)”. The “Service” is the one that hooks into the WordPress Plugin API and does actual stuff.

    To solve dependencies, each “Service Provider” will declare its dependencies, and each dependency is a “Service” identifier. When a “Service Provider” is being added to the Service Locator, its dependencies are checked, and when they are all present, it gets told to register its “Service(s)”.

    Furthermore, to also solve loading order, there’s a Queue in place. So, if the dependencies are not all met, the “Service Provider” gets enqueued. Then, each time a new “Service Provider” has been registered, the Queue gets checked to see if there’s one that now has all its dependencies being met.

    You can see this logic here in the Service Locator component I’m using: https://github.com/brightnucleus/service-locator/blob/master/src/Container.php#L136-L156

    So, if “ZoomServiceProvider” depends on the “LensServiceProvider”->”ZoomLens” Service, the WordPress plugin loading order would normally make this fail. With the above algorithm, the “ZoomServiceProvider” will be enqueued until after the “LensServiceProvider” has been added and provides the “ZoomLens” Service.

    Final Problem to solve… How can we now check for third-party plugins as dependencies? After all, they don’t know anything about our Service (Provider) system. To be able to integrate them in the dependency and loading order resolution, I added “Virtual Services”. Basically, the “VirtualServiceProvider” has a collection of closures, and for each closure that evaluates to true, it will register a corresponding “Virtual Service”.

    These closures can be something like return class_exists( 'GFForms );to create a Virtual ServiceGravityForms, but also something likereturn is_admin();to create a Virtual ServiceIsAdmin`. This makes it very easy to only load functionality conditionally.

    As this all is very structured, I was even able to build a small debugging plugin, that always show the state of the architecture in the admin bar, with quick stats about active and enqueued service provider, and a tree where I can verify the loading order. This makes dependency issues very obvious.

    This stuff has been running on a handful of sites in production so far, and has proved to be very reliable.

    Phew, I did try to keep this short, okay? :)



  2. Good article. Maintaining layers and boundaries is definitely a challenge within any complex application, and as far as I’m concerned, even more so in a complex WordPress application.

    One friendly bit of advice I have to add though, is that you should avoid injecting your container directly into classes as this is considered Service Location. Service Location spawns a host of issues and is considered by many to be an anti pattern and should be avoided. It is highly recommend to use a Dependency Injection container instead.

    One of the big problems with Service Location is that your classes are controlling their dependencies which violates the inversion of control principle. In your example, you have your class retrieving the “settings-messenger” from the container. So the class is controlling the specific class it will use. But what if you wanted to change that at run time to be some other type of class? For example, what if “settings-messenger” only works with standard HTTP requests, but you now want to use this class via command line, or REST API? By injecting your dependencies INTO your classes, your system is in control of what your class will receive, not the class itself (hence what they mean by inversion of control).

    A Dependency Injection Container is capable of recursively inspecting your class’s constructor parameters, and injecting those dependencies for you, as well as any dependencies those classes may have (and so on and so on…). They will often function similar to what Alain described with services being configured in Closures that don’t actually instantiate anything until they are required. Since the DI container knows both how to construct all of your classes, and what those classes themselves require, it can manage your dependencies for you. Good ones can handle straight forward dependencies with little to no configuration whatsoever.

    So your classes simply have to declare their dependencies as constructor parameters and are free from having to retrieve and validate everything themselves. This keeps your business logic classes cleaner and free to focus on what they are meant to do instead of having to devote their code to finding stuff. But more importantly, you can now change things at run time with no negative effects on the class itself.

    And this is where interfaces come into play. By type hinting in your class constructor for an interface instead of a concrete class, then ANY class satisfying the interface can be supplied. So if MessengerInterface is required instead of the specific “settings-messenger” class, then your external system can, at run time, choose the one that is most appropriate for the current request. Maybe MessengerForRestApi or MessengerForCli ? Not sure what those would actually be, but hey, you would have that option. And again, a good DI Container can manage this for you.

    My favourite, although not one we use at Event Espresso, is the Dice container by Tom Butler (https://github.com/Level-2/Dice). Pretty powerful and wild stuff for such a small bit of code. Gosh I wish WordPress would bump it’s minimum PHP version up to at least 5.4!!!

    Oh hey, so that went really far off topic from what the point of your article was, so to steer things back on course, I guess I should explain how one would solve the issue presented in this article within the context of what I explained above. If you were to use Dependency Injection instead of Service Location, then your DI Container would simply throw some sort of ServiceNotFoundException when it couldn’t find the missing third party dependency (like you see happening in the container Alain linked to). Then your Controller or other downstream class would just have to catch that Exception, and ideally convert it into a more user friendly admin notice explaining that “Dependency X was not found and needs to be made available for Y to work.” Your class doesn’t have to bother with setting flags for whether to run or not if that dependency doesn’t exist, because it wouldn’t even load.

    So not only are your business logic classes free from having to find and validate their dependencies themselves, but they are also free from having to manage the error handling and whether to continue loading when things go wrong. This means even less boilerplate needing to to duplicated and added to all of your classes that have dependencies. Since everything is handled by some lower level class that’s sitting in that layer between WordPress and the meat of your application, your class is left to focus solely on what it was intended to do.

    Hope this helps someone avoid some of the pain I had to learn the hard way.

    Really enjoy your blog Tom.

    • There’s so much I’d love to respond to in your comment, but both you and Alain have brought up points that I think would be better for a forum or even a podcast.

      It’s good stuff – it’s just so long!

      Regardless, I really appreciate you taking the time to offer all of this as well as your compliments on the blog!

Leave a Reply