sheadawson / silverstripe-zenvalidator
为 SilverStripe 提供更快、更简单的客户端和服务器端表单验证
Requires
- silverstripe/framework: ^4 || ^5
Requires (Dev)
- phpunit/phpunit: ^5.7
- silverstripe/vendor-plugin: ^1 || ^2.0
README
描述
ZenValidator旨在通过一个简单的API允许配置服务器端和客户端验证,使SilverStripe表单验证尽可能简单。前端使用Parsley.js进行客户端验证。
安装
composer require sheadawson/silverstripe-zenvalidator
SilverStripe 4 支持
本模块版本仅支持 SilverStripe 4。当前版本尽可能与旧代码保持兼容。SilverStripe 4 的支持仍在进行中,因此您可能遇到一些问题。
您还可以查看这个也使用 ParsleyJS 的其他模块:https://github.com/praxisnetau/silverware-validator
本模块的未来版本将破坏 BC 以促进命名空间类和其他改进。
SilverStripe 3 支持
对于 SilverStripe 3 支持,请使用分支 1。
与现代 jQuery 一起使用
由于 entwine,现代 jQuery 不受支持,因为 entwine.js 中存在一个问题。本模块提供了 entwine 的更新版本,该版本取消了旧版 IE(<9)的支持。
本模块期望您包含自己的 jQuery 版本。然而,为了方便,我们包含了 ZenValidator::globalRequirements 辅助函数。此辅助函数还包括 entwine 的更新版本。
此外,我们尽可能避免使用 entwine。您可以使用以下方式使用旧版行为:
ZenValidator: avoid_entwine: false
验证约束
开箱即用的约束包括
- required
- value(最小值、最大值、范围)
- length(最小值、最大值、范围)
- check(最小值、最大值、范围)
- type(email、url、number、integer、digits、alphanumeric)
- equalto(等于另一个字段的值)
- notequalto(不等于另一个字段的值)
- regex
- remote(通过ajax远程验证)
- dimension(图像宽度、高度、长宽比。仅限 CMS)
用法示例
创建一个表单,添加 ZenValidator。
public function Form(){ $fields = FieldList::create(array( TestField::create('Name'), TextField::create('Username'), TextField::create('Email'), TextField::create('FavoriteColor'), TextField::create('Age'), TextField::create('Website') )); $actions = FieldList::create(FormAction::create('submit', 'submit')); $validator = ZenValidator::create(); return Form::create($this, 'Form', $fields, $actions, $validator); }
以下示例演示了将约束添加到上述表单示例的多种方式。
必填字段
addRequiredFields() 可用于快速、干净地添加必填字段。
必填字段 - 基本示例
$validator->addRequiredFields(array( 'Name', 'Email' ));
必填字段 - 自定义消息
$validator->addRequiredFields(array( 'Name' => 'Please enter your name', 'Email' => 'Please enter your email' ));
其他约束
所有其他约束都通过 setConstraint() 方法添加。此方法接受两个参数:$fieldName 和 $constraint。请参阅以下示例。
值约束
测试最小值、最大值或介于范围值之间的数量
最小值
$validator->setConstraint('Age', Constraint_value::create('min', 18));
最大值
$validator->setConstraint('Age', Constraint_value::create('max', 25));
范围
$validator->setConstraint('Age', Constraint_value::create('range', 18, 25));
长度约束
测试字符串的最小值、最大值或介于范围值之间的长度
最小值
$validator->setConstraint('Username', Constraint_length::create('min', 3));
最大值
$validator->setConstraint('Username', Constraint_length::create('max', 5));
范围
$validator->setConstraint('Username', Constraint_length::create('range', 3, 5));
检查约束
测试选中的元素的最小值、最大值或范围
最小值
$validator->setConstraint('Options', Constraint_check::create('min', 3));
最大值
$validator->setConstraint('Options', Constraint_check::create('max', 5));
范围
$validator->setConstraint('Options', Constraint_check::create('range', 3, 5));
类型约束
Constraint_type 约束可用于验证类型为 email、url、number、integer、digits 或 alphanum 的输入。将上述选项之一作为构造函数的第一个参数传递。
电子邮件
$validator->setConstraint('Email', Constraint_type::create('email'));
网址
$validator->setConstraint('Website', Constraint_type::create('url'));
数字
$validator->setConstraint('Age', Constraint_type::create('number'));
整数
$validator->setConstraint('Age', Constraint_type::create('integer'));
数字
$validator->setConstraint('Age', Constraint_type::create('digits'));
字母数字
$validator->setConstraint('Username', Constraint_type::create('alphanum'));
等于约束
验证值是否与另一个字段的值相同(用于密码确认检查)。
$validator->setConstraint('Username', Constraint_equalto::create('Name'));
不等于约束
验证值是否不同于另一个字段的值(用于避免重复)。
$validator->setConstraint('Surname', Constraint_notequalto::create('FirstName'));
正则表达式验证
检查有效的十六进制颜色,例如...
$validator->setConstraint('FavoriteColor', Constraint_regex::create("/^#(?:[0-9a-fA-F]{3}){1,2}$/"));
远程验证
根据远程URL的响应进行验证。验证基于HTTP状态码。状态码为200将进行验证,其他任何情况都将导致验证错误。
$validator->setConstraint('Username', Constraint_remote::create($this->Link('checkusername')));
上述示例将向与表单相同的控制器中的checkusername方法发送AJAX请求。请求变量var包含与字段名相同的键,将包含要测试的值。因此,我的checkusername方法可能看起来像这样
public function checkusername($request) { $username = $request->requestVar('Username'); // check for existing user with same username if (Member::get()->filter('Username', $username)->count()) { return $this->httpError(400, 'This member already exists'); } else { return $this->getResponse()->setBody(''); } }
Constraint_remote构造函数的所有参数/设置
- $url - 发送验证请求的URL(不包括查询字符串,使用$params)
- $params - 请求变量数组,将随请求发送
- $options - 验证器的键 => 值选项数组(例如:['type' : 'POST', 'dataType' : 'jsonp'])
- $validator - 使用特定的远程验证器。默认验证器为'default'和'reverse'。
默认情况下,ZenValidator使用自定义的异步验证器,它读取4xx响应中的错误消息,并在无效字段下方显示它们(而不是显示通用的消息“此值似乎无效”)。
对于服务器端验证:如果给定相对URL,则将通过Director::test内部获取响应,否则将使用curl从远程URL获取响应。
设置自定义消息
上述示例中的任何一个都可以配置为显示自定义错误消息。例如
$validator->setConstraint( 'FavoriteColor', Constraint_regex::create("/^#(?:[0-9a-fA-F]{3}){1,2}$/") ->setMessage('Please enter a valid HEX color code, starting with a #') );
批量设置约束
$validator->setConstraints(array( 'Name' => 'Age', Constraint_value::create('min', 18), 'Username' => array( Constraint_required::create(), Constraint_type::create('alphanum'), ) ));
setConstraint()方法也是可链的,因此您可以
$validator ->setConstraint('Website', Constraint_type::create('url')) ->setConstraint('Content', Constraint_required::create());
移除约束
$validator->removeConstraint(string $fieldName, string $constraintClassname);
或者
$validator->removeConstraints(string $fieldName);
自定义前端验证行为(Parsley)
您可能希望将验证消息显示在自定义元素中,使用自定义类或任何其他可由Parsley配置的前端验证行为。在这种情况下,可以将Zenvalidator构造函数的第三个参数($defaultJS)设置为false。
$validator = ZenValidator::create(null, true, false);
或者通过yml全局设置
ZenValidator:
default_js: false
这将告诉ZenValidator不要使用默认设置进行初始化,并且将添加类"custom-parsley"到表单中。然后您需要向页面添加一些自定义javascript代码,例如
$('form.custom-parsley').parsley({ errorsWrapper: '<div></div>', errorTemplate: '<small class="error"></small>', errorClass: 'error', errorsContainer: function ( elem, isRadioOrCheckbox ) { return $(elem).parents('.field:first'); }, excluded: 'input[type=button], input[type=submit], input[type=reset], input[type=hidden], :hidden, .ignore-validation' });
警告:如果匹配多个表单,$(elem).parsley()可以返回一个数组(在这种情况下,附加订阅将失败)。如果需要匹配多个元素,请使用以下语法
$.each($('form.parsley').parsley(),function(i,parsleyForm) { parsleyForm.subscribe('parsley:field:validate', function(field) { ... }); });
有关配置设置的完整列表,请参阅Parsley.js
CMS使用
要在CMS中使用ZenValidator,只需在您的自定义Page类型或DataObject类中实现getCMSValidator()方法即可
public function getCMSValidator(){ $validator = ZenValidator::create()->setConstraint( 'Content', Constraint_required::create()->setMessage('Please enter some content') ); // currently parsley validation doesn't work so well in the cms, so disable. $validator->disableParsley(); return $validator; }
图像尺寸约束(仅限CMS)
您可以向图像选择/上传字段添加约束,以确保用户保存的图像大小或形状正确,或者图像具有最小/最大宽度和高度,以防止图像在网站中的显示问题。
注意:验证是在页面保存时运行的,而不是在图像选择或上传时。
宽度
使用此选项要求图像宽度为特定像素数。如果您需要图像为确切的大小,这很有用。
$validator->setConstraint('HeroImage', Constraint_dimension::create('width', 100));
高度
使用此选项要求图像高度为指定像素。
$validator->setConstraint('HeroImage', Constraint_dimension::create('height', 150));
宽度和高度
使用此选项要求宽度和高度都是指定像素。
$validator->setConstraint('HeroImage', Constraint_dimension::create('width_height', 100, 150));
比例
使用此选项要求图像具有特定形状,例如6:4照片,5:5方形等。当您需要图像具有特定形状但大小可以由CSS处理时很有用。
$validator->setConstraint('HeroImage', Constraint_dimension::create('ratio', 16, 9));
最小宽度
使用此功能以确保图像宽度等于或大于指定的像素,方便确保用户不会使用过小的图像,如果通过CSS拉伸可能会降低质量。
$validator->setConstraint('HeroImage', Constraint_dimension::create('min_width', 50));
最小高度
使用此功能以确保图像高度等于或大于指定的像素。
$validator->setConstraint('HeroImage', Constraint_dimension::create('min_height', 75));
最小宽度和高度
使用此功能以确保图像的宽度和高度等于或大于指定的像素。
$validator->setConstraint('HeroImage', Constraint_dimension::create('min_width_height', 50, 75));
最大宽度
使用此功能以确保图像宽度小于或等于指定的像素。方便确保用户不会选择远大于所需的图像,特别是如果这些图像通过CSS设置了最大宽度,这会导致大量带宽浪费。
$validator->setConstraint('HeroImage', Constraint_dimension::create('max_width', 300));
最大高度
使用此功能以确保图像高度小于或等于指定的像素。
$validator->setConstraint('HeroImage', Constraint_dimension::create('max_height', 200));
最大宽度和高度
使用此功能以确保图像的宽度和高度不超过指定的像素。
$validator->setConstraint('HeroImage', Constraint_dimension::create('max_width_height', 300, 200));
验证逻辑 - 条件约束
此功能允许您根据表单上其他字段的值指定在什么条件下应应用或不应应用验证约束。这一概念大量借鉴并补充了Uncle Cheese的显示逻辑模块。请注意,不应用前端逻辑,这仅限于后端。如果您使用显示逻辑,将允许您隐藏在前端不应显示/验证的字段。
验证逻辑示例
您可以使用以下条件
- 等于
- 为空
- 大于
- 小于
- 包含
- 被选中
$country->validateIf('EmailAddress')->isEqualTo('s')->orIf('EmailAddress')->isEqualTo('v');
$field->validateIf('IsChecked')->isEmpty();
额外验证器
您还可以使用社区制作的额外验证器。该模块附带默认验证器
- 比较
- 单词
- 日期ISO
仅当您使用这些验证器时,才会加载JavaScript和语言文件。
无验证
在某些场景中,您可能不希望在提交表单时触发验证(例如:多步骤表单中的“上一步”按钮)。虽然这很容易自行实现,但该模块提供了一个标准的实现方式。
您可以使用“FormActionNoValidation”子类代替标准FormAction类。它将防止客户端和服务器端验证发生。
扩展
您可以通过继承抽象ZenValidatorConstraint类来创建自己的验证约束。有关自定义验证器的前端实现,请参阅Parsley.extend.js。遗憾的是,目前除了代码本身之外,没有真正的文档,所以祝您好运!
有关前端的所有其他内容(触发器、错误类、错误放置等),请参阅Parsley.js文档
维护者
##待办事项
- CMS中的Parsley验证(目前仅限服务器端)(ajax)
- 完成条件验证,即仅当字段x的值为y时才验证约束,文档