<?php namespace Larnet\Osm\Behaviors;
use \October\Rain\Database\Traits\Revisionable as RevisionableTrait;
class Revisionable extends \October\Rain\Database\ModelBehavior
{
use RevisionableTrait;
public function __call($name, $params = null)
{
if (!method_exists($this, $name) || !is_callable($this, $name)) {
return call_user_func_array([$this->model, $name], $params);
}
}
}
We don’t support this because maintaining it is extremely difficult. You can write your own implementation; you should do it to make things predictable and the code robust.
Don’t be afraid to duplicate code and ship it with your plugin to gain the flexibility benefits. Something like this:
<?php namespace Acme\MyPlugin\Behaviors;
use System\Classes\ModelBehavior;
/**
* RevisionableModel implementation of \October\Rain\Database\Traits\Revisionable
*
* Usage:
*
* In the model class definition:
*
* public $implement = [\Acme\MyPlugin\Behaviors\RevisionableModel::class];
*
*/
class RevisionableModel extends ModelBehavior
{
use \October\Rain\Database\Traits\Revisionable;
/**
* __construct the behavior
*/
public function __construct($model)
{
parent::__construct($model);
if (!is_array($this->model->revisionable)) {
throw new Exception(sprintf(
'The $revisionable property in %s must be an array to use the Revisionable behavior.',
get_class($this->model)
));
}
$this->model->bindEvent('model.afterUpdate', function () {
$this->revisionableAfterUpdate();
});
$this->model->bindEvent('model.afterDelete', function () {
$this->revisionableAfterDelete();
});
}
/**
* revisionableAfterUpdate event
*/
public function revisionableAfterUpdate()
{
// every time $this is mentioned, use $this->model
}
}
If you did do this how would you access protected properties on the extended class? Trait allow you access to protected stuff where as a behaviour does not as far as I can tell.
This is true, although it shouldn’t be a problem if the model is well designed.
Generally speaking, using behaviors in models can cause performance problems at scale since each model object requires several companion objects, and it eats up memory fast. This is why traits are preferable.
So doing what you have suggested above would chew up memory then, but needs to be done if if you want to extend a third party class? So traits for your owns classes and extends for ones you cant access is the best approach?
This could create a mess, for example take a plugin with somewhat “ecosystem” or in other words plugins that rely on other plugins. You should extend every plugin if you want your changes to apply into them.