diff --git a/src/Forms/EmailField.php b/src/Forms/EmailField.php index 68ea66d4199..f484a04feaa 100644 --- a/src/Forms/EmailField.php +++ b/src/Forms/EmailField.php @@ -2,11 +2,14 @@ namespace SilverStripe\Forms; +use SilverStripe\Validation\EmailValidator; + /** - * Text input field with validation for correct email format according to RFC 2822. + * Text input field with validation for correct email format */ class EmailField extends TextField { + protected string $fieldValidatorClass = EmailValidator::class; protected $inputType = 'email'; /** @@ -17,39 +20,6 @@ public function Type() return 'email text'; } - /** - * Validates for RFC 2822 compliant email addresses. - * - * @see http://www.regular-expressions.info/email.html - * @see http://www.ietf.org/rfc/rfc2822.txt - * - * @param Validator $validator - * - * @return string - */ - public function validate($validator) - { - $result = true; - $this->value = trim($this->value ?? ''); - - $pattern = '^[a-z0-9!#$%&\'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&\'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$'; - - // Escape delimiter characters. - $safePattern = str_replace('/', '\\/', $pattern ?? ''); - - if ($this->value && !preg_match('/' . $safePattern . '/i', $this->value ?? '')) { - $validator->validationError( - $this->name, - _t('SilverStripe\\Forms\\EmailField.VALIDATION', 'Please enter an email address'), - 'validation' - ); - - $result = false; - } - - return $this->extendValidationResult($result, $validator); - } - public function getSchemaValidation() { $rules = parent::getSchemaValidation(); diff --git a/src/Forms/FormField.php b/src/Forms/FormField.php index 0d210436b0f..07d426ca79d 100644 --- a/src/Forms/FormField.php +++ b/src/Forms/FormField.php @@ -15,6 +15,8 @@ use SilverStripe\View\AttributesHTML; use SilverStripe\View\SSViewer; use SilverStripe\Model\ModelData; +use SilverStripe\Core\Injector\Injector; +use SilverStripe\Validation\FieldValidator; /** * Represents a field in a form. @@ -87,6 +89,8 @@ class FormField extends RequestHandler /** @see $schemaDataType */ const SCHEMA_DATA_TYPE_STRUCTURAL = 'Structural'; + protected string $fieldValidatorClass; + /** * @var Form */ @@ -1230,16 +1234,29 @@ protected function extendValidationResult(bool $result, Validator $validator): b return $result; } + /** - * Abstract method each {@link FormField} subclass must implement, determines whether the field - * is valid or not based on the value. - * + * Subclasses can define an existing FieldValidatorClass to validate the FormField value + * They may also override this method to provide custom validation logic + * * @param Validator $validator * @return bool */ public function validate($validator) { - return $this->extendValidationResult(true, $validator); + $isValid = true; + if (!isset($this->fieldValidatorClass)) { + return; + } + $args = [$this->getName(), $this->getValue()]; + /** @var FieldValidator $fieldValidator */ + $fieldValidator = Injector::inst()->createWithArgs($this->fieldValidatorClass, $args); + $validationResult = $fieldValidator->validate(); + if (!$validationResult->isValid()) { + $validator->getResult()->combineAnd($validationResult); + $isValid = false; + } + return $this->extendValidationResult($isValid, $validator); } /** diff --git a/src/ORM/FieldType/DBEmail.php b/src/ORM/FieldType/DBEmail.php new file mode 100644 index 00000000000..397c3d8d89d --- /dev/null +++ b/src/ORM/FieldType/DBEmail.php @@ -0,0 +1,9 @@ +fieldValidatorClass)) { + return $result; + } + $args = [$this->getName(), $this->getValue()]; + $fieldValidator = Injector::inst()->createWithArgs($this->fieldValidatorClass, $args); + $validationResult = $fieldValidator->validate(); + if (!$validationResult->isValid()) { + $result->combineAnd($validationResult); + } + return $result; + } + /** * Returns a FormField instance used as a default * for form scaffolding. diff --git a/src/Validation/EmailValidator.php b/src/Validation/EmailValidator.php new file mode 100644 index 00000000000..3db051e0d4b --- /dev/null +++ b/src/Validation/EmailValidator.php @@ -0,0 +1,19 @@ +value, FILTER_VALIDATE_EMAIL)) { + $message = _t('SilverStripe\\Forms\\EmailField.VALIDATION', 'Please enter an email address'); + $result->addFieldError($this->name, $message); + } + return $result; + } +} diff --git a/src/Validation/FieldValidator.php b/src/Validation/FieldValidator.php new file mode 100644 index 00000000000..11cc9311b36 --- /dev/null +++ b/src/Validation/FieldValidator.php @@ -0,0 +1,27 @@ +name = $name; + $this->value = $value; + } + + public function validate(): ValidationResult + { + $result = ValidationResult::create(); + $result = $this->validateValue($result); + return $result; + } + + abstract protected function validateValue(ValidationResult $result): ValidationResult; +}