mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 14:05:37 +02:00
Merge pull request #10047 from madmatt/pulls/extend-hydrate
NEW Add extension point to DataObject->hydrate()
This commit is contained in:
commit
b5c3b60502
@ -462,6 +462,7 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity
|
||||
static::class,
|
||||
DataObjectSchema::INCLUDE_CLASS | DataObjectSchema::DB_ONLY
|
||||
);
|
||||
|
||||
foreach ($fields as $field => $fieldSpec) {
|
||||
$fieldClass = strtok($fieldSpec, ".");
|
||||
if (!array_key_exists($field, $record)) {
|
||||
@ -469,6 +470,21 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity
|
||||
}
|
||||
}
|
||||
|
||||
// Extension point to hydrate additional fields into this object during construction.
|
||||
// Return an array of field names => raw values from your augmentHydrateFields extension method.
|
||||
$extendedAdditionalFields = $this->extend('augmentHydrateFields');
|
||||
foreach ($extendedAdditionalFields as $additionalFields) {
|
||||
foreach ($additionalFields as $field => $value) {
|
||||
$this->record[$field] = $value;
|
||||
|
||||
// If a corresponding lazy-load field exists, remove it as the value has been provided
|
||||
$lazyName = $field . '_Lazy';
|
||||
if (array_key_exists($lazyName, $this->record)) {
|
||||
unset($this->record[$lazyName]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->original = $this->record;
|
||||
$this->changed = [];
|
||||
$this->changeForced = false;
|
||||
|
@ -19,6 +19,7 @@ use SilverStripe\ORM\FieldType\DBVarchar;
|
||||
use SilverStripe\ORM\ManyManyList;
|
||||
use SilverStripe\ORM\Tests\DataObjectTest\Company;
|
||||
use SilverStripe\ORM\Tests\DataObjectTest\Player;
|
||||
use SilverStripe\ORM\Tests\DataObjectTest\Team;
|
||||
use SilverStripe\ORM\Tests\DataObjectTest\TreeNode;
|
||||
use SilverStripe\Security\Member;
|
||||
use SilverStripe\View\ViewableData;
|
||||
@ -211,6 +212,31 @@ class DataObjectTest extends SapphireTest
|
||||
$this->assertSame(5, $player->ID);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see SilverStripe\ORM\Tests\DataObjectTest\Team_Extension
|
||||
*/
|
||||
public function testConstructHydratesAugmentedValues()
|
||||
{
|
||||
// When creating a DataObject from singleton, DataObject::hydrate() isn't called
|
||||
$team = new Team([], DataObject::CREATE_SINGLETON);
|
||||
$this->assertNull($team->CustomHydratedField);
|
||||
|
||||
// Similarly, when hydrating by creating a DataObject from nothing, hydrate() isn't called
|
||||
$team2 = new Team([]);
|
||||
$id = $team2->write();
|
||||
$this->assertNull($team2->CustomHydratedField);
|
||||
|
||||
// However when rebuilding an object from the database, it is and we can expect our extension to execute
|
||||
/** @var Team $team3 */
|
||||
$team3 = Team::get()->byID($id);
|
||||
$this->assertTrue($team3->CustomHydratedField);
|
||||
|
||||
// Also when rebuilding an object in memory, hydrate() is called and our extension should execute
|
||||
/** @var Team $team4 */
|
||||
$team4 = $team->newClassInstance(Team::class);
|
||||
$this->assertTrue($team4->CustomHydratedField);
|
||||
}
|
||||
|
||||
public function testValidObjectsForBaseFields()
|
||||
{
|
||||
$obj = new DataObjectTest\ValidatedObject();
|
||||
|
@ -12,6 +12,7 @@ use SilverStripe\ORM\ManyManyList;
|
||||
* @property string DatabaseField
|
||||
* @property array SalaryCap
|
||||
* @property string FoundationYear
|
||||
* @property bool CustomHydratedField
|
||||
* @method Player Captain()
|
||||
* @method Player Founder()
|
||||
* @method Player HasOneRelationship()
|
||||
|
@ -23,4 +23,11 @@ class Team_Extension extends DataExtension implements TestOnly
|
||||
{
|
||||
return "extended dynamic field";
|
||||
}
|
||||
|
||||
public function augmentHydrateFields()
|
||||
{
|
||||
return [
|
||||
'CustomHydratedField' => true,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user