One of the major goals of the MasterPress API is to provide an interface to your content and data that is as concise as possible. An important mechanism the API uses to achieve this is the concept of a class delegate, which is basically a class that provides its methods to another class, but not by way of class extension. This is much easier to illustrate with a concrete example.
Each of the MasterPress field types are represented by a class deriving from the MPFT class, which allows them to provide their own mini-API appropriate to the type of data they hold. When you access a MasterPress field from a field set though, you will never be directly interacting with an object based on one of these classes, you’re always interacting with the MEOW_Field class. Suppose we have a post type field set called “details” and a date field called start_date.
Example 1: Class anatomy for field access
In example 1 we now have a variable called $start_date which is a MEOW_Field. If you look at the documentation for the MPFT_DatePicker class, you’ll notice that it has a “date” function that can format dates for us, which we can call like so:
Example 2: Calling our date function
So pretty obvious stuff, right? Indeed it is, but MEOW_Field doesn’t have a date method. This is where the concept of class delegates applies; the MEOW_Field class dynamically delegates property access and method calls to the MPFT_DatePicker class. Put another way, MPFT_DatePicker is a delegate (noun) for MEOW_Field. This delegation is once again achieved by using PHP5’s magic methods to forward the call or property access on to the delegate.
The net effect of class delegates is that you can call any method from a class delegate as if it was part of the original class. This is an important point when browsing the Class Reference. Classes that have a delegate will list the delegate at the top of the page, next to the class they extend:
Figure 1: The Delegate in our Class Reference
When you see this, follow the delegate class link to see other methods you can call on the class you were originally looking at. We even show the delegate with the same icon as the extended class, to reinforce the fact that they behave the same way externally.
Why not just extend the class?
There’s a few reasons we can’t just extend the class to provide additional methods:
- Most classes in the API already extend another class, and PHP only allows single-inheritance.
- In the case of fields and field types, the class delegate is determined at runtime based on the defined type of the field. Class definitions in PHP are declared to extend another class in their source code – you can’t extend dynamically.
Delegates of Delegates
Astute readers may have noticed that in Figure 1 MPFT_Image delegates to the WOOF_Image class, but we’d already said that field type classes like MPFT_Image were delegates of MEOW_Field. The API can indeed support one delegate object delegating to another, with the net result being that the original object supports methods from both delegates.
Don’t fret or bend your mind too much – but just know that when we show code like this:
Example 3: Resizing the image in our photo class - simple on the surface
… it is this very mechanism that enables us to call WOOF_Image::resize on the photo field. This goes back to the point in our opening paragraph – the aim of the MasterPress API is to allow us to write front-end theme code that is as concise as possible. Without delegates of delegates, you might have needed to do this:
Example 4: One extra property would flex your memory...
This is not tremendously difficult, but it would definitely require a bit more of your grey-matter 🙂