Decorating models
Introduction to model decoration
Model decoration is a way to split a single model definition into multiple files. The goal is to ease the burden of maintaining large code bases by modularizing a model class. This permits the usual Outlast Framework workflow of modularized plugins to seamlessly work together.
Unlike standard OOP extending, decoration will add feature to the original model definitions rather than creating a separate model class. Any time you interact with the model, you will continue to use the original model name.
In Outlast Framework, model decoration is very similar to the Categories feature in Objective C.
The benefits of decoration
Let’s assume we have a project where we want to add a few fields to the User
model.
We could just copy over everything from the plugin to the app level (app hierarchy would result in that the /app/model/user.model.php
file is more important than /plugins/user/model/user.model.php
) and modify the full user model. The downside of this approach is that if we make any modification at a later date to the plugin version (such as fixing bugs, adding new methods, fields, or features) these features would be overwritten by the app-level copy of the User model and would thus be ignored.
We could also use standard OOP extend
. But in this case we have to define a new class and each time we refer to the child class, we have to actually use the name of the child class. This breaks modular code.
With Outlast Framework model decoration, we take the original User
model (such that all features, methods, and fields of the plugin-level model file are preserved) and we simply add a few additional features at the app-level. All modular code on the plugin- or system-level will continue to function as before, without modification.
Adding features to existing models
Most projects require you to add fields or features to existing models on the app level. To do this, simply create a new file with the same name as your parent model in /app/model/
and extend the parent model as you would in any standard OOP. Current naming convension is that you preface your app-level model name with App, so an extension of User
become AppUser
on the app level. To clarify, here’s an example:
@todo add example here!
When you want to add features on the plugin-level, you should create decoratable models so that others can further extend it with app-level features. Models that are on the app-level and do not extend the zajDecoratable
class cannot be extended and decorated in the way described here.
Creating decoratable models
For app-level models it is enough just to extend existing plugin and system models. However, if you are creating a plugin-level model, you want to ensure that programmers will be able to extend the model with additional features in other plugins and on the app-level.
Decoratable models need to extend the zajModelDecoratable
class. Here’s an example of how they are defined:
@todo add example here
Models that are created like this can be be further extended.
Upgrading to model decoration 2.0
The model decoration 2.0
feature introduces a more advanced and more OOP-friendly way of handling model extension and decoration. The new features also come with breaking changes so you will need to perform the following steps on each repository that you move to the new feature set:
- Set each submodule (plugins and system) to the
release/model-decoration-2.0
branch. (This will not be needed once this is merged into master.) - Search for
$zajconf['feature_model_decoration_enabled']
insite/index.php
and set it to true. If the line does not exist yet, add it to the feature enable/disable section (~line 128 in the file.) – example - You will need to remove
__construct
and__callStatic
methods from all of your models. – example - Add the
$f
parameter to each__model()
method and remove anynew stdClass()
lines. – example - Remove the
$f = parent::__model(__CLASS__, $f);
line and leave onlyreturn $f;
at the end of your__model()
method. – example - This should be already done, but any models in your plugins should extend the new
zajModelDecoratable
class. – example