From 5ab18c6f0463091fe431c92762d0dae5f38deb47 Mon Sep 17 00:00:00 2001 From: Steve Boyd Date: Mon, 23 Sep 2024 19:03:35 +1200 Subject: [PATCH] NEW DBField validation --- _config/model.yml | 2 ++ src/Forms/EmailField.php | 25 +++++++++----------- src/ORM/DataObject.php | 7 +++++- src/ORM/FieldType/DBEmail.php | 43 +++++++++++++++++++++++++++++++++++ src/ORM/FieldType/DBField.php | 6 +++++ 5 files changed, 68 insertions(+), 15 deletions(-) create mode 100644 src/ORM/FieldType/DBEmail.php diff --git a/_config/model.yml b/_config/model.yml index 4046feddb..8e6840244 100644 --- a/_config/model.yml +++ b/_config/model.yml @@ -20,6 +20,8 @@ SilverStripe\Core\Injector\Injector: class: SilverStripe\ORM\FieldType\DBDecimal Double: class: SilverStripe\ORM\FieldType\DBDouble + Email: + class: SilverStripe\ORM\FieldType\DBEmail Enum: class: SilverStripe\ORM\FieldType\DBEnum Float: diff --git a/src/Forms/EmailField.php b/src/Forms/EmailField.php index 68ea66d41..46efac9f7 100644 --- a/src/Forms/EmailField.php +++ b/src/Forms/EmailField.php @@ -2,6 +2,9 @@ namespace SilverStripe\Forms; +use SilverStripe\Core\Validation\ConstraintValidator; +use Symfony\Component\Validator\Constraints; + /** * Text input field with validation for correct email format according to RFC 2822. */ @@ -18,32 +21,26 @@ class EmailField extends TextField } /** - * 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])?$'; + $result = true; + $message = _t('SilverStripe\\Forms\\EmailField.VALIDATION', 'Please enter an email address'); + $validationResult = ConstraintValidator::validate( + $this->value, + new Constraints\Email(message: $message) + ); - // Escape delimiter characters. - $safePattern = str_replace('/', '\\/', $pattern ?? ''); - - if ($this->value && !preg_match('/' . $safePattern . '/i', $this->value ?? '')) { + if (!$validationResult->isValid()) { $validator->validationError( $this->name, - _t('SilverStripe\\Forms\\EmailField.VALIDATION', 'Please enter an email address'), - 'validation' + $validationResult->getMessages()[0]['message'], ); - $result = false; } diff --git a/src/ORM/DataObject.php b/src/ORM/DataObject.php index 178db68e5..2be88d367 100644 --- a/src/ORM/DataObject.php +++ b/src/ORM/DataObject.php @@ -1230,7 +1230,12 @@ class DataObject extends ModelData implements DataObjectInterface, i18nEntityPro public function validate() { $result = ValidationResult::create(); - $this->extend('updateValidate', $result); + $specs = static::getSchema()->fieldSpecs(static::class); + foreach (array_keys($specs) as $fieldName) { + $dbField = $this->dbObject($fieldName); + $result->combineAnd($dbField->validate()); + } + $this->extend('updateValidate', $validationResult); return $result; } diff --git a/src/ORM/FieldType/DBEmail.php b/src/ORM/FieldType/DBEmail.php new file mode 100644 index 000000000..8b12bd712 --- /dev/null +++ b/src/ORM/FieldType/DBEmail.php @@ -0,0 +1,43 @@ +combineAnd( + ConstraintValidator::validate( + $this->getValue(), + new Constraints\Email(message: $message), + $this->getName() + ) + ); + $this->extend('updateValidate', $result); + return $result; + } + + public function scaffoldFormField(?string $title = null, array $params = []): ?FormField + { + // Set field with appropriate size + $field = EmailField::create($this->name, $title); + $field->setMaxLength($this->getSize()); + + // Allow the user to select if it's null instead of automatically assuming empty string is + if (!$this->getNullifyEmpty()) { + return NullableField::create($field); + } + return $field; + } +} diff --git a/src/ORM/FieldType/DBField.php b/src/ORM/FieldType/DBField.php index 38efb5758..39f170572 100644 --- a/src/ORM/FieldType/DBField.php +++ b/src/ORM/FieldType/DBField.php @@ -10,6 +10,8 @@ use SilverStripe\Forms\TextField; use SilverStripe\ORM\Filters\SearchFilter; use SilverStripe\ORM\Queries\SQLSelect; use SilverStripe\Model\ModelData; +use SilverStripe\Core\Validation\ValidationResult; +use Symfony\Component\Validator\Constraints\Valid; /** * Single field in the database. @@ -43,6 +45,10 @@ use SilverStripe\Model\ModelData; */ abstract class DBField extends ModelData implements DBIndexable { + public function validate(): ValidationResult + { + return ValidationResult::create(); + } /** * Raw value of this field