Extending DataObject
models
You can add properties and methods to existing DataObject
subclasses like Member
without hacking core code or subclassing by using an Extension
. See the Extending Silverstripe CMS guide for more information.
The following documentation outlines some common hooks that the Extension
API provides specifically for managing
data records. Note that this is not an exhaustive list - we encourage you to look at the source code to see what other extension hooks are available.
Avoid using the hooks shown here for checking permissions or validating data - there are specific mechanisms for handling those scenarios. See permissions and validation respectively.
onBeforeWrite
You can customise saving behavior for each DataObject
, e.g. for adding workflow or data customization. The function is
triggered when calling write()
to save the object to the database. This includes saving a page in the CMS or altering
a record via code.
Example: Make sure the player has a valid and unique player number for their team when being assigned a new team.
namespace App\Model;
use SilverStripe\ORM\DataObject;
class Player extends DataObject
{
private static $db = [
// ...
'Number' => 'Int',
];
private static $has_one = [
'Team' => Team::class,
];
protected function onBeforeWrite()
{
// Use $this->isInDb() to check if the record is being written to the database for the first time
if (!$this->isInDb() && $this->Team()->exists()) {
$this->Number = $this->Team()->getAvailablePlayerNumber();
}
// If the player changed teams
if ($this->isChanged('TeamID') && $this->Team()->exists()) {
// If the player's number is already used by someone else on this team
if (in_array($this->Number, $this->Team()->Players()->exclude('ID', $this->ID)->column('Number'))) {
// Assign a new player number
$this->Number = $this->Team()->getAvailablePlayerNumber();
}
}
// CAUTION: You are required to call parent::onBeforeWrite(), otherwise
// SilverStripe will not execute the request.
parent::onBeforeWrite();
}
}
onBeforeDelete
Triggered before executing delete()
on an existing object. It can be useful if you need to make sure you clean up some other data/files/etc which aren't directly associated with the actual DataObject
record.
namespace App\Model;
use SilverStripe\ORM\DataObject;
class Player extends DataObject
{
// ...
protected function onBeforeDelete()
{
/* Do some cleanup here relevant to your project before deleting the actual database record */
// CAUTION: You are required to call parent::onBeforeDelete(), otherwise
// SilverStripe will not execute the request.
parent::onBeforeDelete();
}
}
Note: There are no separate methods for onBeforeCreate()
and onBeforeUpdate()
. Please check $this->isInDb()
to toggle
these two modes, as shown in the example above.