Reduce the cost of maintaining your ExpressionEngine add-ons with CI_Model

Patrick Pohler
ExpressionEngine Pros
5 min readAug 3, 2014

The concept of DRY (Don’t Repeat Yourself) is a critical skill to master in writing solid, professional, and maintainable code.

ExpressionEngine is built on top of CodeIgniter, and while the framework is showing it’s age compared to the new hotness that is Laravel, it does have some decent tools for code re-use.

Sorry CodeIgniter fans, just having fun. I’ll take CI over whatever the hell is going on with Wordpress.

One tool is the CodeIgniter Model class (CI_Model), Models are simply classes designed to contain your application data and are responsible for managing data between your application and the underlying database.

Wait, doesn’t ExpressionEngine’s Database class do the same thing?

Not quite, the DB class is great for working with the database, however it isn’t a very reusable way to do common tasks of saving and retrieving data for your application.

Say you have a table for your add-on called exp_posts. To save a new post you’d use the insert command of the Database class:

$data = array( ‘title’ => ‘My title’ , ‘name’ => ‘My Name’ , ‘date’ => ‘My date’
);

ee()->db->insert(‘posts’, $data);

Seems simple right? Well say you have this code in a few places in your add-on to insert new posts. You also have code to pull the posts from the database. Now you need to add a new column to the posts table and use it in your add-on.

Uh-oh, you’ll have to now update all of the places were you’re working with data from the posts table. It’s not a big deal for maybe one table, but as your add-on grows in complexity suddenly every change becomes more of a hassle and starts creating a large number of bugs in your code.

It’s cute until they drink all the coffee and don’t make a fresh pot.

What we need is a way to encapsulate the idea of a Post into a class were we only have one file we have to maintain when we need to make a change.

https://gist.github.com/patpohler/e9267edc5f65af21afd9

Above is an example of how I structure the model classes in my add-ons. You can see we have the common CRUD (Create, Read, Update, Delete) methods. It’s pretty similar to the CodeIgniter documentation with a few differences:

  • A method called _get_table() which returns the table name, this is handy because it allows us to refer to the table name once rather than having to repeat the table name in every db statement. I made this a private method instead of an attribute because if it was a class attribute, CI’s insert and update methods would assume that it was a table field.
  • Two methods, _set_model_for_save() and _set_model_for_return() which handles the mapping between the fields in the table and the properties of the class

You’ll also note that for one of the properties author_secret we’re encrypting and decrypting the data before and after saving in the mapping methods. By using a Model class I’m able to easily enforce the business rule that this field has to be encrypted when saving to the database. If I ever need to adjust or change this rule (or encrypt other fields) it’s as simple as modifying a few lines in this one class.

Using the model class is pretty straightforward. If you create a subfolder in your add-on folder called models you can use CodeIngiter’s Loader class to instanantiate the model. Here’s an example using my ExpressionEngine module for Rets Rabbit.

If you use the model method of the Loader class, EE will look in your add-on’s models subfolder. Afterwards you can access the model class by using ee()->Rets_config.

Saving data using the becomes really simple, here’s an example of how I use the class to save a new configuration.

Now this is pretty great. But there’s one more bit of refactoring we can do on our model classes to make sure we’re using DRY principles.

Do you remember the three private methods I used in my Post example class: _get_table, _set_model_for_save, _set_model_for_return? Well it turns out that they are the only methods that change from model to model. This means we’re repeating the exact same methods: get, get_by_site_id, insert, and update, which isn’t very DRY.

We can fix this by creating an abstract base class and inheriting our model classes off of it. An abstract base class is like a document template, it contains a common set of reusable code that other classes can derive from.

https://gist.github.com/patpohler/225fe68324e6bdfb0e68

If you mark a class as abstract you are letting PHP know that it shouldn’t instantiated the class directly, it’s only purpose is to be inherited (if you try to use the class directly, PHP will throw an error). If you mark methods as abstract, you’re telling PHP that those methods must be defined in the child classes. The rest of the methods and properties are common to all classes and won’t have to be defined (unless a child class needs to override them).

Now our Post class looks a lot simpler.

https://gist.github.com/patpohler/1a93b2c9a5495e83b200

Now whenever I need to add a new Model to my add-on, all I have to do is create a model class that inherits from Base_model and then modify the three protected methods to fit the data I’m storing.

Code re-usability is the mark of a true professional, it’s not sexy, but reliable and maintainable code will help you deal better with support issues help other developers understand and work with your code. As we’ve seen above, CodeIgniter gives us some decent tools to help us encapsulate our data into model classes and keep things DRY.

Patrick is the owner of the development agency Anecka. He also writes articles and guides for freelancers to help improve their development productivity at PatPohler.com.

--

--

Patrick Pohler
ExpressionEngine Pros

Helps real estate firms improve online lead response time w/ tech. Runs real estate API service RetsRabbit.com, blogs at PatPohler.com