One of the things that many of us see (and are guilty of abusing) are WordPress plugin constructors.
If you’re using object-oriented programming, you’re likely familiar with constructors. However, the purpose they serve isn’t always clear at least in the world of WordPress.
The definition of a constructor well-defined in Wikipedia:
In class-based object-oriented programming, a constructor (abbreviation: ctor) in a class is a special type of subroutine called to create an object. It prepares the new object for use, often accepting arguments that the constructor uses to set required member variables.
But here’s the key thing to notice for anyone working with constructors and object-oriented programming in WordPress plugin development:
It prepares the new object for use, often accepting arguments that the constructor uses to set required member variables.
And this is where many of us, and WordPress plugin developers, fail. We abuse constructors for a purpose they are not intended.
WordPress Plugin Constructors
If you’re not familiar with member variables, think of them like this:
Member variables are characteristics of a class (that ultimately become a class) that help describe it.
For example, if you’re creating a Post, then member variables may be its title, its content, its publication date, and its author. All of these member variables will be set in some way when the object is created.
They could be initialized to a certain value, or they could be set to an empty value like an empty string, a zero, or null.
But in WordPress, we often see something completely different. Instead, we end up defining calls to hooks (both actions and filters) within the constructor.
Here’s the basic litmus test of where calls to hooks belong:
If constructors are meant to initialize member variables, is a call to a hook a way to initialize member variables?
You could probably rationalize some wrap-around reason as to why, but that in-and-of-itself should give you your answer.
And simply put: No. Constructors should not be used to make calls to WordPress hooks. They should be used to set member variables and nothing more.
How, Then, Do We Call Hooks?
Depending on who you ask, you may get a number of different responses to this, but my preferred method – for now, at least (since this can change over time) – is to create an initialization method that takes care of this.
There is at least two primary of advantages for doing this:
- It allows us to instantiate a class and test its business logic outside of WordPress.
- It allows us to hook into WordPress only when needed by calling the initialization method.
When we separate the logic like this, it makes it easier to write unit tests against our classes without needing to load WordPress to test them. In short, it de-couples our code from WordPress.
That said, when we need to test against WordPress, we can still load the class. We just make one extra method call. That is, we call the initialization method so that the call into WordPress is made.
From there, we’re able to test the functionality against WordPress.
So the next time you set out to make a class specifically designed to work against WordPress, to be testable both outside WordPress and against WordPress, and that follows solid object-oriented best practices, try structuring your work like the sample code above.