From c0a30f1b6a3cb76c880b8879bf99b3fe8316e513 Mon Sep 17 00:00:00 2001 From: Dylan Wagstaff Date: Sun, 17 Jan 2021 15:55:47 +1300 Subject: [PATCH] FIX unrequire fields when they become dataless (#1016) * FIX unrequire fields when they become dataless When fields that collect input data are changed in configuration via the CMS to become fields that no longer collect input data (e.g. TextField -> HTML Block), submitting the resulting form results in a fatal error, server 500 response, etc. due to trying to check if a field without data (ever) has data in it. To circumvent this we can set the required state to false if the field is being converted to one that does not collect data (which FormField API conveniently provides a check for). * Move parent::onBeforeWrite() to top of function Co-authored-by: Steve Boyd --- code/Model/EditableFormField.php | 5 +++++ tests/Model/EditableFormFieldTest.php | 17 +++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/code/Model/EditableFormField.php b/code/Model/EditableFormField.php index b85c67d..fd2f6d1 100755 --- a/code/Model/EditableFormField.php +++ b/code/Model/EditableFormField.php @@ -413,6 +413,11 @@ class EditableFormField extends DataObject { parent::onBeforeWrite(); + $formField = $this->getFormField(); + if ($formField && !$formField->hasData()) { + $this->Required = false; + } + // Set a field name. if (!$this->Name) { // New random name diff --git a/tests/Model/EditableFormFieldTest.php b/tests/Model/EditableFormFieldTest.php index a159384..3058c86 100644 --- a/tests/Model/EditableFormFieldTest.php +++ b/tests/Model/EditableFormFieldTest.php @@ -10,6 +10,7 @@ use SilverStripe\UserForms\Model\EditableFormField; use SilverStripe\UserForms\Model\EditableFormField\EditableCheckbox; use SilverStripe\UserForms\Model\EditableFormField\EditableDropdown; use SilverStripe\UserForms\Model\EditableFormField\EditableFileField; +use SilverStripe\UserForms\Model\EditableFormField\EditableLiteralField; use SilverStripe\UserForms\Model\EditableFormField\EditableOption; use SilverStripe\UserForms\Model\EditableFormField\EditableRadioField; use SilverStripe\UserForms\Model\EditableFormField\EditableTextField; @@ -292,4 +293,20 @@ class EditableFormFieldTest extends FunctionalTest $field = $this->objFromFixture(EditableTextField::class, $fieldName); $this->assertEquals($expected, $field->isDisplayed($data)); } + + public function testChangingDataFieldTypeToDatalessRemovesRequiredSetting() + { + $requiredTextField = $this->objFromFixture(EditableTextField::class, 'required-text'); + $fieldId = $requiredTextField->ID; + $this->assertTrue((bool)$requiredTextField->Required); + + $literalField = $requiredTextField->newClassInstance(EditableLiteralField::class); + $this->assertTrue((bool)$literalField->Required); + + $literalField->write(); + $this->assertFalse((bool)$literalField->Required); + + $updatedField = EditableFormField::get()->byId($fieldId); + $this->assertFalse((bool)$updatedField->Required); + } }