If you’ve not read the first post in this series, I recommend it, as we’re starting to get into writing object-oriented code for WordPress through the use of the Widgets API.
The series is going to capture a few things:
- show you the basic skeleton of a widget and why it’s object-oriented,
- discuss what things you should be able to notice and why
- update the Widget Boilerplate directly on this site first and then push it out to GitHub,
- build a widget using the API with the boilerplate as the foundation for our work.
But before doing that, I want to make sure that everyone reading this is caught up on the core principles of object-oriented programming and has everything needed to build out an object-oriented solution for WordPress.
To that end, I recommend the following:
- Two Pillars of Object-Oriented Programming: Part 1 of 2
- Two Pillars of Object-Oriented Programming: Part 2 of 2
- Abstract Classes, Part 1 – Abstracting Behavior
- Abstract Classes, Part 2 – Abstract Classes and Interfaces
- The Independent WordPress Developer
If you’ve read all of that content, great. You’re going to be well-prepared for this post and the upcoming posts. If not, there may be some holes in the rest of what you’re about to read, but the gist of the post should be clear enough.
What’s The Deal, Exactly?
Here’s the thing: Last week, I shared a bit of code along with some information about the Widgets API. I’m going to be revisiting that a little bit more in this post before we get into the more coding intensive part for two reasons:
- I want everyone reading this to be on the same page as it relates to writing object-oriented code (at the very least, in this context),
- I recognize that people are coming from different backgrounds and I want to make sure we’re all on the same page as much as possible before proceeding.
If you have experience with writing object-oriented code, especially in an advanced capacity, this may seem simpler to you; otherwise, I hope this is going to arm you with everything you need to detect object-oriented practices not only concerning this API but when reading others’ code, too.
How to Detect Object-Oriented Programming
Perhaps a natural first question is why do we need to be able to detect, read, or understand object-oriented programming before actually writing it?
A Word About Bad Code
The short answer to that is this:
You don’t need to, but I it’s helpful. If you’re able to read object-oriented programming, you’re going to have a head start in taking advantage in what it offers as a paradigm because you’re going to build on the strategies and work done by others in other projects.
This doesn’t mean we won’t read the bad code, but we’ll do what we can to identify bad code, identify the problematic areas, and then do what we can to avoid incorporating it into our work.
For now, though, let’s take a look at the Widgets API to see what we can do to detect object-oriented programming.
Back To Object-Oriented Programming
In the previous post, I outlined two things that indicate the API is object-oriented (at least to some degree):
- the use of the extends keyword,
- functions that we must implement.
The reason I want to revisit this topic is that it identifies two key things that are part of core object-oriented principles: Inheritance and function implementation (which is often part of abstract classes).
A note before we look at the above:
When you look at the source of the WP_Widget class, you’ll notice that there aren’t abstract methods. But some of the functions that we must implement, which I’ll mention later in this post, are prime candidates for abstract methods. And I’ll discuss why, too.
Let’s separate the topics above into two separate sections: Inheritance and Abstractions.
I covered inheritance is relative depth in the previous post, so I won’t belabor the point here. I’ll offer a few words, but I’m much more interested in discussing abstraction which I’ll do so in a moment.
Before going too far into this, though, please refer to the following code:
But first, we can recognize that any class that implements the Widgets API must use inheritance simply because of the extends keyword.
This means that there’s a level of functionality that we’re going to inherit (or to get for free) and there’s a level of functionality that we must implement on our own.
From the PHP manual:
For example, when you extend a class, the subclass inherits all of the public and protected methods from the parent class. Unless a class overrides those methods, they will retain their original functionality.
When you inherit functionality from a class, though, you may find that it’s important to strictly call the parent’s constructor (in our __construct function).
But this raises what I believe to be one of the most important issues with inheritance in PHP (and the entire reason I wanted to include this section): Do we need to call the parent constructor explicitly?
Also according to the manual:
Parent constructors are not called implicitly if the child class defines a constructor. In order to run a parent constructor, a call to parent::__construct() within the child constructor is required. If the child does not define a constructor then it may be inherited from the parent class just like a normal class method (if it was not declared as private).
But we can simplify this. Perhaps this is easier to remember:
- If our class uses inheritance but doesn’t define a constructor, the parent constructor is called.
- If our class uses inheritance but does define a constructor, the parent construct must be explicitly called.
Or perhaps even more simply:
- If our class does not define a constructor, the code will default to the parents’ constructor.
Make sense? In short, if we define our properties, initialization, and code in a constructor, the first line of our class’ constructor should be a call to the parent constructor.
To be absolutely clear, the source code of WP_Widget class does not include abstract methods. Part of this has to do with how the class is built, part of this has to do with backwards compatibility, and features of PHP5.
This doesn’t mean that we can’t identify what functions could be marked as abstract, though. In fact, I think it makes a case as to which classes should be made abstract. But first, let’s define abstract functions.
When inheriting from an abstract class, all methods marked abstract in the parent’s class declaration must be defined by the child; additionally, these methods must be defined with the same (or a less restricted) visibility.
When looking at the source of our widget:
I think it’s fair to say that the form function could be marked as abstract because it’s unique to our implementation. Another way of thinking about abstract functions from a programming standpoint is to ask yourself: Which functions will require unique functionality?
And in this case, the form function is precisely that because each widget will be uniquely different regarding what it renders. The widget function could also be marked as abstract because it outputs the content of the widget. This content is, naturally, based on the functionality we’ve implemented in our implementation.
Furthermore, the source code of the WP_Widget class itself says:
function WP_Widget::widget() must be over-ridden in a sub-class.’
This is precisely the type of function that should be marked as abstract. Because PHP will throw an error if a function is marked as abstract and not implemented. We did not need any die function calls or anything like that.
The other functions, though, aren’t necessarily going to need to be marked as abstract and here’s why:
- __construct will call the parent’s constructor, at the most basic level, and this is necessary to initialize the base class. Don’t forget, though; we can add our properties to this method that are unique to our class.
- update uses functionality in the parent class for serializing information.
Thus, we’re left with two functions that could be marked as abstract in a more modern iteration of the class.
At this point, we should all be on the same page as it relates to object-oriented code. At least as far as we can get through a series of blog posts.
Starting in the next post, we’re going to get back to writing code.
That is, we’ll revisit the WordPress Widget Boilerplate and I’m going to be refactoring it in its current state to adopt more modern PHP standards.
I’m going to share the changes I’m making, the justifications as to why, and then I’ll also talk about the type of widget we’re going to be building based on the boilerplate (and we can do so).