NEW Allow skipping validation on write (#11202)

This commit is contained in:
Guy Sartorelli 2024-04-19 10:35:36 +12:00 committed by GitHub
parent 4be3dd5cd1
commit dcc6863401
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 19 additions and 7 deletions

View File

@ -1345,7 +1345,7 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity
*
* @return ValidationException Exception generated by this write, or null if valid
*/
protected function validateWrite()
protected function validateWrite(bool $skipValidation = false)
{
if ($this->ObsoleteClassName) {
return new ValidationException(
@ -1354,6 +1354,10 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity
);
}
if ($skipValidation) {
return null;
}
// Note: Validation can only be disabled at the global level, not per-model
if (DataObject::config()->uninherited('validation_enabled')) {
$result = $this->validate();
@ -1369,10 +1373,10 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity
*
* @throws ValidationException
*/
protected function preWrite()
protected function preWrite(bool $skipValidation = false)
{
// Validate this object
if ($writeException = $this->validateWrite()) {
if ($writeException = $this->validateWrite($skipValidation)) {
// Used by DODs to clean up after themselves, eg, Versioned
$this->invokeWithExtensions('onAfterSkippedWrite');
throw $writeException;
@ -1560,15 +1564,16 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity
* {@link getManyManyComponents()}. Default to `false`. The parameter can also be provided in
* the form of an array: `['recursive' => true, skip => ['Page'=>[1,2,3]]`. This avoid infinite
* loops when one DataObject are components of each other.
* @param boolean $skipValidation Skip validation of data
* @return int The ID of the record
* @throws ValidationException Exception that can be caught and handled by the calling function
*/
public function write($showDebug = false, $forceInsert = false, $forceWrite = false, $writeComponents = false)
public function write($showDebug = false, $forceInsert = false, $forceWrite = false, $writeComponents = false, bool $skipValidation = false)
{
$now = DBDatetime::now()->Rfc2822();
// Execute pre-write tasks
$this->preWrite();
$this->preWrite($skipValidation);
// Check if we are doing an update or an insert
$isNewRecord = !$this->isInDB() || $forceInsert;

View File

@ -1519,6 +1519,13 @@ class DataObjectTest extends SapphireTest
$this->assertTrue($validatedObject->isInDB(), "Validated object was not saved to database");
}
public function testWriteSkipValidation(): void
{
$validatedObject = new DataObjectTest\ValidatedObject();
$validatedObject->write(skipValidation: true);
$this->assertTrue($validatedObject->isInDB(), "Validated object was not saved to database");
}
public function testSubclassCreation()
{
/* Creating a new object of a subclass should set the ClassName field correctly */

View File

@ -33,7 +33,7 @@ class TreeNode extends DataObject implements TestOnly
'Children' => self::class,
];
public function write($showDebug = false, $forceInsert = false, $forceWrite = false, $writeComponents = false)
public function write($showDebug = false, $forceInsert = false, $forceWrite = false, $writeComponents = false, bool $skipValidation = false)
{
// Force the component to fetch its Parent and Cycle relation so we have components to recursively write
$this->Parent;
@ -42,7 +42,7 @@ class TreeNode extends DataObject implements TestOnly
// Count a write attempts
$this->WriteCount++;
return parent::write($showDebug, $forceInsert, $forceWrite, $writeComponents);
return parent::write($showDebug, $forceInsert, $forceWrite, $writeComponents, $skipValidation);
}
/**