diff --git a/forms/Form.php b/forms/Form.php index 58fd3a639..a2adef1f5 100644 --- a/forms/Form.php +++ b/forms/Form.php @@ -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, diff --git a/forms/Validator.php b/forms/Validator.php index 76c0aa61c..3cd447edd 100755 --- a/forms/Validator.php +++ b/forms/Validator.php @@ -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. . Usually "bad|message|validation|required", which renders differently + * if sapphire/css/Form.css is included. + * + * @return array + */ + function getErrors() { return $this->errors; }