Models for WordPress
WordPress is great. We can use it for building simple websites, forums and we can even use it to build quite complex web apps. The almost endless supply of WordPress plugins means anyone can easily add lots of functionality to a site using a “professional” theme bought for less than £50 on ThemeForrest. But, for me though there is one (hand on heart, there is actually a few) big problem with WordPress, it’s ORM. Wordpress relies on the two tables `wp_post` and `wp_postmeta` to hold the data for all post types, this makes abstracting this data into a model with it’s own functionality very difficult. This problem is magnified by the fact that WP_Post can not be extended, resulting in developers using functional code to extract and manipulate post meta data in the page template. This isn’t a big problem if you are just using WordPress as a blog but if you have lots of different custom post types and they all need to behave slightly differently it can get very messy.
“WordPress was not built for making large sites. It was originally designed as a blogging platform, if you're going to build an application you should use a framework not a blogging CMS” — You
True, but WordPress is not just used as a blogging platform anymore. It’s simple back-end means literally anyone can administrate a site with ease. Not to mention, in this age of startups Wordpress is the perfect platform to build a prototype or MVP at low cost and with only an entry level knowledge of PHP. It’s abundance of blog posts (case in point) and forums also means that should a user encounter a problem it’s more often than not already been solved by someone in the community.
Admit it, we’ve all done this before when building WordPress themes. This is not only stomach-churning to look at but it’s next to impossible to maintain. If you want to display post meta data on the front end you can not do it without adding logic code to the page template.
“WP_Post uses the magic method __get() which allows access to the post’s meta data” — You
True, but what if this data is in a url safe form because you're using an ACF select box? Or, if you want the meta to default to a specific value if the data has not been set? Impossible.
So, to solve these problems, I created WP_Model. A class that can be extended to allow active record style access to your post and it’s meta data. WP_Model allows you to describe what meta_data and taxonomies you want and the relevant data will be auto loaded into the object. It can be used on both already existing CPTs and new ones. WP_Model is designed so it can be used with just a basic understanding of PHP and WordPress. In addition, more advanced features like virtual properties and custom finders make it even easier to reuse code, define relationships and prevent logic code from being in your template files. The class has been influenced by themes found in Laravel’s Eloquent and CakePHP.
To install this class simply require WP_Model with composer.
$ composer require anthonybudd/WP_Model
If you're not using composer, you can download the WP_Model class and require it at the top of your functions.php file.
To make your first model you will need to create a class that extends WP_Model and has the properties $postType and $attributes.
$postType will be the name of the post type $attributes will be an Array of post meta keys. Keys listed in the $attributes array will be auto loaded whenever the class is instantiated. Read More
To register your post type add either of the static functions below to your functions.php file. If you provide the register function with an array of arguments, this array will be sent directly to the second argument of Wordpress’s register_post_type() function.
Note: This is just a helper method and does not need to be used. If you have already registered a custom post type (for example, on an existing CPT) you will not need to use this method.
To Create your first model, you instantiate an instance of your class, in this case, Product. The constructor can take an array as an argument, these properties are loaded into the model.
To save your model use the method save() this will save your post to the `wp_posts` table and save all of it’s relevant data to the `wp_postmeta` table. Insert() will save the post automatically.
find() will return an instantiated model if a post exists in the database with the ID. If the post cannot be found it will return NULL.
To find multiple posts by ID you can use the in() method. This will return an array of models.
where() is a simple interface into WP_Query, the method can accept two string arguments (meta_value and meta_key). For complex queries, supply the method with a single array as the argument. The array will be automatically broken down into tax queries and meta queries, WP_Query will then be executed and the method will return an array of instantiated models. Read More.
delete() will trash the post.
If you would like to add virtual properties to your models, you can do this by creating a public property named $virtual. This array will be all of the virtual properties. Next, you will need to create a method named the virtual property name and prefixed with ‘_get’. This method will need to be in camelcase. For example, the virtual property named “humanWeight” will trigger the method _getHumanWeight()
Virtual properties can be used to create pseudo relationships. In the example below, the virtual property seller will return an instance of the seller object.
WP_Model has an events system, this is the best way to hook into WP_Model’s core functions. All events with the suffix -ing fire as soon as the method has been called. All events with the suffix -ed will be fired at the very end of the method. All events will be supplied with the model that triggered the event. Read more.
The $new property will return true if the model has not been saved in the Database yet.
The $dirty property will return true if the data in the model is different from what’s currently stored in the database. Read more.
WP_Model’s helper methods are designed to make working with Wordpress easier. They are all methods that we write in to our projects at one time or another. Read more.
Congratulations! If you have read all the above and not just scrolled here, you now know everything you need to know to get started with WP_Model. It’s as simple as that. There’s lots of other features I haven't mentioned in this post like custom finder methods, hard deleting, patching and serialisation. If you want to read the full documentation check out WP_Model on github.