diff --git a/README.md b/README.md index 3f28be08..ae05d50e 100644 --- a/README.md +++ b/README.md @@ -164,6 +164,10 @@ class MyCustomLink extends Link } ``` +## Custom link validation + +Custom links can have validation set using standard [model validation]([https://docs.silverstripe.org/en/5/developer_guides/forms/validation/#model-validation). + ## Migrating from Shae Dawson's Linkable module https://github.com/sheadawson/silverstripe-linkable diff --git a/lang/en.yml b/lang/en.yml index 37f9f86e..be99a113 100644 --- a/lang/en.yml +++ b/lang/en.yml @@ -3,6 +3,8 @@ en: CREATE_LINK: 'Create link' MENUTITLE: 'Link fields' UPDATE_LINK: 'Update link' + SilverStripe\LinkField\Form\ExternalLinkField: + INVALID: 'Please enter a valid URL' SilverStripe\LinkField\Form\Traits\AllowedLinkClassesTrait: INVALID_TYPECLASS: '"{class}": {typeclass} is not a valid Link Type' INVALID_TYPECLASS_EMPTY: '"{class}": Allowed types cannot be empty' @@ -16,14 +18,15 @@ en: SINGULARNAME: 'Email Link' db_Email: Email SilverStripe\LinkField\Models\ExternalLink: - EXTERNAL_URL_FIELD: 'External url' + EXTERNAL_URL_FIELD: 'External URL' + EXTERNAL_URL_FIELD_DESCRIPTION: 'Ensure the URL starts with http:// or https://' LINKLABEL: 'Link to external URL' PLURALNAME: 'External Links' PLURALS: one: 'An External Link' other: '{count} External Links' SINGULARNAME: 'External Link' - db_ExternalUrl: 'External url' + db_ExternalUrl: 'External URL' SilverStripe\LinkField\Models\FileLink: CANNOT_VIEW_FILE: 'Cannot view file' FILE_DOES_NOT_EXIST: 'File does not exist' diff --git a/src/Form/ExternalLinkField.php b/src/Form/ExternalLinkField.php new file mode 100644 index 00000000..31c9c6b4 --- /dev/null +++ b/src/Form/ExternalLinkField.php @@ -0,0 +1,55 @@ +value = trim($this->value ?? ''); + if ($this->value && !preg_match(self::PHP_RX, $this->value)) { + $validator->validationError( + $this->name, + _t(__CLASS__ . '.INVALID', 'Please enter a valid URL'), + 'validation' + ); + $result = false; + } + return $this->extendValidationResult($result, $validator); + } + + /** + * This is passed to the frontent via FormField::getSchemaValidation() + * and used in Validator.js + */ + public function getSchemaValidation() + { + $rules = parent::getSchemaValidation(); + $rules['regex'] = ['pattern' => self::JS_RX]; + return $rules; + } +} diff --git a/src/Models/EmailLink.php b/src/Models/EmailLink.php index 2b074161..dde0ea0e 100644 --- a/src/Models/EmailLink.php +++ b/src/Models/EmailLink.php @@ -4,6 +4,8 @@ use SilverStripe\Forms\EmailField; use SilverStripe\Forms\FieldList; +use SilverStripe\Forms\CompositeValidator; +use SilverStripe\Forms\RequiredFields; /** * A link to an Email address. @@ -55,4 +57,11 @@ public function getMenuTitle(): string { return _t(__CLASS__ . '.LINKLABEL', 'Link to email address'); } + + public function getCMSCompositeValidator(): CompositeValidator + { + $validator = parent::getCMSCompositeValidator(); + $validator->addValidator(RequiredFields::create(['Email'])); + return $validator; + } } diff --git a/src/Models/ExternalLink.php b/src/Models/ExternalLink.php index c724d906..22048869 100644 --- a/src/Models/ExternalLink.php +++ b/src/Models/ExternalLink.php @@ -3,6 +3,9 @@ namespace SilverStripe\LinkField\Models; use SilverStripe\Forms\FieldList; +use SilverStripe\Forms\CompositeValidator; +use SilverStripe\Forms\RequiredFields; +use SilverStripe\LinkField\Form\ExternalLinkField; /** * A link to an external URL. @@ -27,8 +30,13 @@ class ExternalLink extends Link public function getCMSFields(): FieldList { $this->beforeUpdateCMSFields(function (FieldList $fields) { - $linkField = $fields->dataFieldByName('ExternalUrl'); - $linkField->setTitle(_t(__CLASS__ . '.EXTERNAL_URL_FIELD', 'External url')); + $field = ExternalLinkField::create('ExternalUrl'); + $field->setTitle(_t(__CLASS__ . '.EXTERNAL_URL_FIELD', 'External URL')); + $field->setDescription(_t( + __CLASS__ . '.EXTERNAL_URL_FIELD_DESCRIPTION', + 'Ensure the URL starts with http:// or https://' + )); + $fields->replaceField('ExternalUrl', $field); }); return parent::getCMSFields(); } @@ -51,4 +59,11 @@ public function getMenuTitle(): string { return _t(__CLASS__ . '.LINKLABEL', 'Link to external URL'); } + + public function getCMSCompositeValidator(): CompositeValidator + { + $validator = parent::getCMSCompositeValidator(); + $validator->addValidator(RequiredFields::create(['ExternalUrl'])); + return $validator; + } } diff --git a/src/Models/FileLink.php b/src/Models/FileLink.php index 452d7684..c0c8afbb 100644 --- a/src/Models/FileLink.php +++ b/src/Models/FileLink.php @@ -4,6 +4,8 @@ use SilverStripe\Assets\File; use SilverStripe\Forms\FieldList; +use SilverStripe\Forms\CompositeValidator; +use SilverStripe\Forms\RequiredFields; /** * A link to a File in the CMS @@ -71,4 +73,11 @@ public function getMenuTitle(): string { return _t(__CLASS__ . '.LINKLABEL', 'Link to a file'); } + + public function getCMSCompositeValidator(): CompositeValidator + { + $validator = parent::getCMSCompositeValidator(); + $validator->addValidator(RequiredFields::create(['File'])); + return $validator; + } } diff --git a/src/Models/PhoneLink.php b/src/Models/PhoneLink.php index 0a72031b..a509c4ab 100644 --- a/src/Models/PhoneLink.php +++ b/src/Models/PhoneLink.php @@ -3,6 +3,9 @@ namespace SilverStripe\LinkField\Models; use SilverStripe\Forms\FieldList; +use SilverStripe\Forms\CompositeValidator; +use SilverStripe\Forms\RequiredFields; +use SilverStripe\LinkField\Form\PhoneField; /** * A link to a phone number @@ -25,8 +28,8 @@ class PhoneLink extends Link public function getCMSFields(): FieldList { $this->beforeUpdateCMSFields(function (FieldList $fields) { - $linkField = $fields->dataFieldByName('Phone'); - $linkField->setTitle(_t(__CLASS__ . '.PHONE_FIELD', 'Phone')); + $field = $fields->dataFieldByName('Phone'); + $field->setTitle(_t(__CLASS__ . '.PHONE_FIELD', 'Phone')); $fields->removeByName('OpenInNew'); }); return parent::getCMSFields(); @@ -50,4 +53,11 @@ public function getMenuTitle(): string { return _t(__CLASS__ . '.LINKLABEL', 'Phone number'); } + + public function getCMSCompositeValidator(): CompositeValidator + { + $validator = parent::getCMSCompositeValidator(); + $validator->addValidator(RequiredFields::create(['Phone'])); + return $validator; + } } diff --git a/src/Models/SiteTreeLink.php b/src/Models/SiteTreeLink.php index 023ec7c9..aed10875 100644 --- a/src/Models/SiteTreeLink.php +++ b/src/Models/SiteTreeLink.php @@ -8,6 +8,8 @@ use SilverStripe\Forms\FieldList; use SilverStripe\Forms\TextField; use SilverStripe\Forms\TreeDropdownField; +use SilverStripe\Forms\CompositeValidator; +use SilverStripe\Forms\RequiredFields; /** * A link to a Page in the CMS @@ -147,4 +149,11 @@ public function getMenuTitle(): string { return _t(__CLASS__ . '.LINKLABEL', 'Page on this site'); } + + public function getCMSCompositeValidator(): CompositeValidator + { + $validator = parent::getCMSCompositeValidator(); + $validator->addValidator(RequiredFields::create(['PageID'])); + return $validator; + } }