mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 12:05:37 +00:00
Merge pull request #5377 from open-sausages/pulls/4.0/api-exempt-validation
API Allow actions to declare they are exempt from validation themselves
This commit is contained in:
commit
84193b00fd
@ -158,6 +158,27 @@ reusable and would not be possible within the `CMS` or other automated `UI` but
|
||||
return $this->redirectBack();
|
||||
}
|
||||
}
|
||||
|
||||
## Exempt validation actions
|
||||
|
||||
In some cases you might need to disable validation for specific actions. E.g. actions which discard submitted
|
||||
data may not need to check the validity of the posted content.
|
||||
|
||||
You can disable validation on individual using one of two methods:
|
||||
|
||||
|
||||
:::php
|
||||
$actions = new FieldList(
|
||||
$action = FormAction::create('doSubmitForm', 'Submit')
|
||||
);
|
||||
$form = new Form($controller, 'MyForm', $fields, $actions);
|
||||
|
||||
// Disable actions on the form action themselves
|
||||
$action->setValidationExempt(true);
|
||||
|
||||
// Alternatively, you can whitelist individual actions on the form object by name
|
||||
$form->setValidationExemptActions(['doSubmitForm']);
|
||||
|
||||
|
||||
## Server-side validation messages
|
||||
|
||||
|
@ -89,6 +89,7 @@
|
||||
* `hasStages` is addded to check if an object has a given stage.
|
||||
* `stageTable` is added to get the table for a given class and stage.
|
||||
* `ChangeSet` and `ChangeSetItem` have been added for batch publishing of versioned dataobjects.
|
||||
* `FormAction::setValidationExempt` can be used to turn on or off form validation for individual actions
|
||||
|
||||
### Front-end build tooling for CMS interface
|
||||
|
||||
|
@ -712,6 +712,22 @@ class Form extends RequestHandler {
|
||||
return $this->validationExemptActions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Passed a FormAction, returns true if that action is exempt from Form validation
|
||||
*
|
||||
* @param FormAction $action
|
||||
* @return bool
|
||||
*/
|
||||
public function actionIsValidationExempt($action) {
|
||||
if ($action->getValidationExempt()) {
|
||||
return true;
|
||||
}
|
||||
if (in_array($action->actionName(), $this->getValidationExemptActions())) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert this form to another format.
|
||||
* @param FormTransformation $format
|
||||
@ -1342,8 +1358,8 @@ class Form extends RequestHandler {
|
||||
* @return boolean
|
||||
*/
|
||||
public function validate(){
|
||||
$buttonClicked = $this->buttonClicked();
|
||||
if($buttonClicked && in_array($buttonClicked->actionName(), $this->getValidationExemptActions())) {
|
||||
$action = $this->buttonClicked();
|
||||
if($action && $this->actionIsValidationExempt($action)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -39,6 +39,13 @@ class FormAction extends FormField {
|
||||
*/
|
||||
protected $buttonContent = null;
|
||||
|
||||
/**
|
||||
* Should validation be skipped when performing this action?
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $validationExempt = false;
|
||||
|
||||
/**
|
||||
* Create a new action button.
|
||||
*
|
||||
@ -173,6 +180,26 @@ class FormAction extends FormField {
|
||||
return $this->useButtonTag;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set whether this action can be performed without validating the data
|
||||
*
|
||||
* @param bool $exempt
|
||||
* @return $this
|
||||
*/
|
||||
public function setValidationExempt($exempt = true) {
|
||||
$this->validationExempt = $exempt;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get whether this action can be performed without vaidating the data
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function getValidationExempt() {
|
||||
return $this->validationExempt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Does not transform to readonly by purpose.
|
||||
* Globally disabled buttons would break the CMS.
|
||||
|
@ -298,6 +298,28 @@ class FormTest extends FunctionalTest {
|
||||
),
|
||||
'Form->sessionMessage() shows up after reloading the form'
|
||||
);
|
||||
|
||||
// Test this same behaviour, but with a form-action exempted via instance
|
||||
$response = $this->submitForm(
|
||||
'Form_Form',
|
||||
'action_doSubmitActionExempt',
|
||||
array(
|
||||
'Email' => 'test@test.com'
|
||||
)
|
||||
);
|
||||
|
||||
// The required message should be empty if validation was skipped
|
||||
$items = $this->cssParser()->getBySelector('#Form_Form_SomeRequiredField_Holder .required');
|
||||
$this->assertEmpty($items);
|
||||
|
||||
// And the session message should show up is submitted successfully
|
||||
$this->assertPartialMatchBySelector(
|
||||
'#Form_Form_error',
|
||||
array(
|
||||
'Validation bypassed!'
|
||||
),
|
||||
'Form->sessionMessage() shows up after reloading the form'
|
||||
);
|
||||
}
|
||||
|
||||
public function testSessionValidationMessage() {
|
||||
@ -773,8 +795,10 @@ class FormTest_Controller extends Controller implements TestOnly {
|
||||
new NumericField('Number')
|
||||
),
|
||||
new FieldList(
|
||||
new FormAction('doSubmit'),
|
||||
new FormAction('doSubmitValidationExempt')
|
||||
FormAction::create('doSubmit'),
|
||||
FormAction::create('doSubmitValidationExempt'),
|
||||
FormAction::create('doSubmitActionExempt')
|
||||
->setValidationExempt(true)
|
||||
),
|
||||
new RequiredFields(
|
||||
'Email',
|
||||
@ -797,6 +821,11 @@ class FormTest_Controller extends Controller implements TestOnly {
|
||||
return $this->redirectBack();
|
||||
}
|
||||
|
||||
public function doSubmitActionExempt($data, $form, $request) {
|
||||
$form->sessionMessage('Validation bypassed!', 'good');
|
||||
return $this->redirectBack();
|
||||
}
|
||||
|
||||
public function getViewer($action = null) {
|
||||
return new SSViewer('BlankPage');
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user