Decorating models


There are breaking changes with regards to model decoration! See upgrade guide to upgrade your models. You can also view the legacy documentation here.

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'] in site/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 any new stdClass() lines. – example
  • Remove the $f = parent::__model(__CLASS__, $f); line and leave only return $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
Outlast Web & Mobile Development (c) 2023 | Privacy Policy |