BUGFIX Removed hardcoded field value removals in Form->validate() for creditcard info

ENHANCEMENT Optionally returning JSON data or HTML form representations from Form submissions if Form->validate() fails (if HTTP Accept is set to 'application/json')
ENHANCEMENT Limiting usage of prototype-validation responses in Form->validate() to form instances with $javascriptValidationHandler=='prototype' (which is the default setting). This enables us to return richer JSON data on validation errors without making assumptions about javascript methods on clientside through eval'ed responses (specifically Validator.js->validationError())
API CHANGE Deprecated Validator->getError() and Validator->getCombinedError(), use getErrors() instead

git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/sapphire/trunk@72979 467b73ca-7a2a-4603-9d3b-597d59a354a9
This commit is contained in:
Ingo Schommer 2009-03-12 16:47:29 +00:00
parent a97ee0e97d
commit 969a95eff7
2 changed files with 44 additions and 15 deletions

View File

@ -195,7 +195,24 @@ class Form extends RequestHandler {
// Validate the form
if(!$this->validate()) {
if(Director::is_ajax()) {
return FormResponse::respond();
// Special case for legacy Validator.js implementation (assumes eval'ed javascript collected through FormResponse)
if($this->validator->getJavascriptValidationHandler() == 'prototype') {
return FormResponse::respond();
} else {
$acceptType = $request->getHeader('Accept');
if(strpos($acceptType, 'application/json') !== FALSE) {
// Send validation errors back as JSON with a flag at the start
$response = new HTTPResponse(Convert::array2json($this->validator->getErrors()));
$response->addHeader('Content-Type', 'application/json');
} else {
$this->setupFormErrors();
// Send the newly rendered form tag as HTML
$response = new HTTPResponse($this->forTemplate());
$response->addHeader('Content-Type', 'text/html');
}
return $response;
}
} else {
Director::redirectBack();
return;
@ -760,18 +777,13 @@ class Form extends RequestHandler {
* This includes form validation, if it fails, we redirect back
* to the form with appropriate error messages.
* Triggered through {@link httpSubmission()} which is triggered
* @usedby Form->httpSubmission()
*
* @todo Replace hardcoded exclude fields like CreditCardNumber with hook to specify sensitive fields in model
*/
function validate(){
if($this->validator){
$errors = $this->validator->validate();
if($errors){
if(Director::is_ajax()) {
// Send validation errors back as JSON with a flag at the start
//echo "VALIDATIONERROR:" . Convert::array2json($errors);
if(Director::is_ajax() && $this->validator->getJavascriptValidationHandler() == 'prototype') {
FormResponse::status_message(_t('Form.VALIDATIONFAILED', 'Validation failed'), 'bad');
foreach($errors as $error) {
FormResponse::add(sprintf(
@ -781,14 +793,9 @@ class Form extends RequestHandler {
Convert::raw2js($error['messageType'])
));
}
return false;
} else {
$data = $this->getData();
// People will get worried if you leave credit card information in session..
if(isset($data['CreditCardNumber'])) unset($data['CreditCardNumber']);
if(isset($data['DateExpiry'])) unset($data['Expiry']);
// Load errors into session and post back
Session::set("FormInfo.{$this->FormName()}", array(
'errors' => $errors,

View File

@ -113,9 +113,9 @@ abstract class Validator extends Object {
*
* @param $fieldName name of the field
* @param $message error message to display
* @param $messageType optional parameter, gets loaded into the HTML class attribute in the rendered output
* @param $messageType optional parameter, gets loaded into the HTML class attribute in the rendered output. See {@link getErrors()} for details.
*/
function validationError($fieldName,$message,$messageType=''){
function validationError($fieldName, $message, $messageType='') {
$this->errors[] = array(
'fieldName' => $fieldName,
'message' => $message,
@ -124,12 +124,15 @@ abstract class Validator extends Object {
}
/**
* @deprecated 2.4 Use Validator->getCombinedError() and custom code
* @deprecated 2.4 Use Validator->getErrors() and custom code
*/
function showError() {
Debug::show($this->errors);
}
/**
* @deprecated 2.4 Use custom code
*/
function getCombinedError(){
if($this->errors) {
foreach($this->errors as $error){
@ -140,7 +143,26 @@ abstract class Validator extends Object {
return $ret;
}
}
/**
* @deprecated 2.4 Use getErrors()
*/
function getError(){
return $this->getErrors();
}
/**
* Returns all errors found by a previous call to {@link validate()}.
* The array contains the following keys for each error:
* - 'fieldName': the name of the FormField instance
* - 'message': Validation message (optionally localized)
* - 'messageType': Arbitrary type of the message which is rendered as a CSS class in the FormField template,
* e.g. <span class="message (type)">. Usually "bad|message|validation|required", which renders differently
* if sapphire/css/Form.css is included.
*
* @return array
*/
function getErrors() {
return $this->errors;
}