Mateusz Uzdowski | Developer
SilverStripe
http://silverstripe.com/
Phone: +64 4 978 7330 xtn 68
Skype: MateuszUzdowski
In the following paragraphs I will be referring mostly to Django, since I believe its validation system is reliable, flexible and it's certainly the best one that I worked with.
Django uses two very closely related elements, when it comes to forms: Fields are related to the database representation and backend validation of the values. Widgets are frontend representations of fields.
Example:
A TextInput widget is a simple <input type="text" /> field, which can represent multiple fields. Both CharField and EmailField are represented by the same widget (TextInput), but they have different backend validation rules and different default settings/values.\
I believe that we could implement the same mechanism in SilverStripe. It allows for much more flexibility, makes the code a lot cleaner and easier to modify.
The fields (and maybe widgets as well) can have multiple and custom validators. This is also the most handy way to define some common attributes such as the "required" flag which definitely doesn't belong to the validator, min/max values, and default values.
Also, widget could have some basic attributes which would allow to add additional css classes or html attributes. To make it as clear as possible, I have prepared an image to illustrate it on a very basic level: http://wojtekszkutnik.com/gsoc/gsoc1.png
2) Refactoring the validators system
This aspect is closely related to my previous point. SilverStripe should allow easily modifiable, highly flexible per-form and per-field validators - this is absolutely crucial for making Forms something more than just a tool for saving data into Models/DataObjects.
Considering the complexity of this task, probably both the scope and the timeline will be subject to heavy discussion during the following weeks. I have tried to estimate the obvious tasks and schedule some time before the coding phase for heavy discussion.
I haven't included Unit Tests in any description because, obviously, they are developed on a per-feature basis. This leads to a 20-35% increase of development time but eliminates loads of bugs and provides an easy to maintain codebase.
April - May 21 - discussing the project with developers and the community. I believe that the main points of the discussion would be model vs field validation logic and the degree of using DataObject->validate(). Also, this period will probably let us determine a more strict schedule for the project - it obviously has a lot of potential features and choosing their priorities will be as much important as discussing the technical solutions. For instance, the proof of concept for SilverStripe metadata-driven JavaScript validation depends on how extensive the main tasks will be.
May 21 - June 15 - I believe that during this phase we will mostly concentrate on developing a proper FormField implementation (I feel that there will be a lot of rewrites going on over there).
Also, the duration of this period depends on how extensively we'll decide to develop the "ModelForm".
June 15 - June 30 - possibly implementing the form "widgets" described above and separating the interface forms layer from the data management layer.
July 1 - July 15 - implementing validators, constraints and customisation features for fields and widgets
July 15 - July 30 - First steps related to JavaScript/jQuery validation libraries integration (binding them with optional form attributes etc)
cheers,
W.
To view this discussion on the web visit https://groups.google.com/d/msg/silverstripe-dev/-/tq0guFWyjYEJ.
W--
You received this message because you are subscribed to the Google Groups "SilverStripe Core Development" group.
To post to this group, send email to silverst...@googlegroups.com.
To unsubscribe from this group, send email to silverstripe-d...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/silverstripe-dev?hl=en.
To post to this group, send email to silverstripe-dev@googlegroups.com.
To unsubscribe from this group, send email to silverstripe-dev+unsubscribe@googlegroups.com.
* model-level vs field-level vs form-level constraints? More specifically can we get away with model-level validation only?
* should multiple-field validation be included (e.g. day field validation could depend on the month setting)?
* should we allow multiple messages per field (e.g. "the password is too short", and "the password does not contain any numbers" at the same time)?
* and last but not least: how to best decouple validation rules from forms and models?
By the way, just a side note to remember during implementation: I just
stumbled upon a missing feature in Django, which would allow to
group-override error messages. Basically you can't change the default
message (e.g. "This field is required"), you have to specify the
messages on a per-case basis, which just turned out to be a huge
problem for me ;-)
W
Hi,in case you didnt know the NetefxValidator module, you could take a look at it. (written by me and Zauberfisch)Maybe you will get some inspiration for the new validator.This one is only for forms, no validation on model-level.negative:- no validation on the model level- no JS/Jquery validationpositive:- a lot of ValidationRules for all kind of validation included- rules can be combined as complex as you want- multiple field validation- use custom methods for validation- ...Documentation: http://www.netefx.de/Silverstripe-NetefxValidator.phpSo I just wanted to mention this module, because maybe you will get some ideas for the new validator.
From: silverstripe-dev@googlegroups.com [mailto:silverstripe-dev@googlegroups.com] On Behalf Of Stig Lindqvist
Sent: Dienstag, 10. April 2012 00:15
Subject: [silverstripe-dev] Re: [GSoC 2012] Form and Model Validation
Hello!It's good to kick this discussion of since the validation has been nagging me since I've started working with SilverStripe.* model-level vs field-level vs form-level constraints? More specifically can we get away with model-level validation only?* should multiple-field validation be included (e.g. day field validation could depend on the month setting)?From my point of view we have to separate what kind of validation we want on the different levels. My thoughts are that:- Forms should make sure that the data is consistent overall. Example: If checkbox 'Use creditcard', then textfield 'Credit card number' must be filled in.- Fields should ensure that the data is formated according to what specific fields. Example: A textfield for credit card number is a valid credit card.- Models should ensure that the data entered by the user actually "fits" the database. Example: A Boolean isn't a string.* should we allow multiple messages per field (e.g. "the password is too short", and "the password does not contain any numbers" at the same time)?I think so, I want forms that tells a form user what went wrong so I can correct them at once, instead of posting the form until it passes.* and last but not least: how to best decouple validation rules from forms and models?I hope this would include a possibility to inject validators at runtime on Form, Fields and Models.Another suggestion is to use another frameworks validators, like Zend Framework, since it's silly to roll our own. This would separate the validation logic from the presentation of validation messages.Links:--
You received this message because you are subscribed to the Google Groups "SilverStripe Core Development" group.
To view this discussion on the web visit https://groups.google.com/d/msg/silverstripe-dev/-/c96-Wx_Ss8YJ.
To post to this group, send email to silverstripe-dev@googlegroups.com.
To unsubscribe from this group, send email to silverstripe-dev+unsubscribe@googlegroups.com.
I'd probably suggest that rules like this would be better implemented as code rather than options. However, that does make it more difficult to validate on the front-end. One thing we talked about was the idea of validating via an ajax submission, in much the same way that auto-complete lookups happen.
If we post the form data to <formurl>/validate, it could return an 204 OK response, or 412 Validation error response. The 412 response might include a JSON summary of validation errors.
> We need to keep in mind that if we implement these complex rules in the API, we will need to be able to communicate them to the frontend, and probably also support them there on a basic level. This might mean we will be inventing a SS Custom Validation Language (tm) which I think we should avoid :)
Totally agree.
I think that I mentioned some plugins before, here is one of them:
http://www.matiasmancini.com.ar/jquery-plugin-ajax-form-validation-html5.html
If we decided to do frontend validation, we could do something
similiar and implement only the lacking features. I think that it's
doable.
W
W
--
You received this message because you are subscribed to the Google Groups "SilverStripe Core Development" group.
I agree. In my mind, "controller validation" / front-end validation needs to include all the validation that the model provides, *and* any extra validation suitable for the specific action. It does seem like the same notion of validating a set of field values can be used across both model and controller validation.
> Something to consider - model validation doesn't necessarily have to be as rigid as you might think. For example, on a member object I wouldn't make the 'email' field need to be a valid email address (what if I want to create a user with some dummy data in there via code?) but from a frontend form perspective, I don't want users being able to do the same
> class Member {
> public $email;
>
> public $constraints = array(
> 'email' => array('UniqueField', 'Required')
> );
> }
>
> class MemberController {
> public function EditForm() {
> $form = new Form();
> $form->addValidation('email', new EmailFieldValidator());
> }
> }
I agree that this is something that a SilverStripe developer should be able to do. For my own apps, I'd probably put email validation on the model and use put @x.com on the end of my dummy entries, but that's not something the framework should mandate.
However, I don't like that the example talks about "constraints" in one half of the app and "validation" in the other. This seems like an unnecessary distinction. However, the difference between constraints and validation could be useful as follows:
- "constraints" define validation rules that can be expressed as a set of properties rather than procedural code.
- "validation" extends this, adding the kind of validation that needs to be coded.
In other words "constraints" are our "simple" or "out of the box" validation, but that constraints can be used in controllers too.
Something like this:
class Member {
static $db = array(
"Email" => "Varchar",
);
static $constraints = array(
'Email' => array('UniqueField', 'Required')
);
}
class MemberController {
public function EditForm() {
$form = new Form();
$constraints = Member::constraints();
$constraints->add(array("Email" => "ValidEmail"));
$form->addValidation($constraints);
}
}
In terms of implementation, ConstraintSet could be represented as a subclass of a Validator, and both forms and models can have as many Validators as they like.
Alternatively, you could do this:
class MemberController {
public function EditForm() {
$form = new Form();
$form->addValidation(Member::constraints());
$form->addValidation(new ValidEmail("Email"));
}
}
I'm not sure how constraints would interact with JavaScript validation. In principle the data contained in constraints could be passed through to the front-end, but the implementation details could get messy.
To post to this group, send email to silverstripe-dev@googlegroups.com.
To unsubscribe from this group, send email to silverstripe-dev+unsubscribe@googlegroups.com.
To post to this group, send email to silverstripe-dev@googlegroups.com.
To unsubscribe from this group, send email to silverstripe-dev+unsubscribe@googlegroups.com.
Actually, I beg to disagree on this one :) Dummy data for E-mail
fields is te...@example.com or something similiar, and if you try to
put invalid data into the ORM, it should fail validation. Basically,
if you decide to use an E-mail field, the ORM should validate it as an
E-mail - obviously, you can always perform a raw sql query since the
field is usually represented as a varchar field, but ORM should always
validate the data based on the field specs - that's what it is for ;-)
> However, I don't like that the example talks about "constraints" in one half of the app and "validation" in the other. This seems like an unnecessary distinction. However, the difference between constraints and validation could be useful as follows:
>
> - "constraints" define validation rules that can be expressed as a set of properties rather than procedural code.
> - "validation" extends this, adding the kind of validation that needs to be coded.
>
That's pretty much what I had in mind :)
> Your thinking seems to be going in a direction that the developer who provides the specific DBFields/FormFields/FormWidgets is not responsible for defining the specific
> validation rules for these fields - and these only get configured on the compound structures such as model or form?
Actually, from my point of view, the fields should have some basic
validation rules (obviously, the validation rules for role-specific
fields such as an E-mail field, should use more strict validation than
a imple TextField), but the developer should be allowed to define
additional validators for these.
As for $form->addValidation(function($validationContext) { ... });, I
think it's a code design decision - should we allow to change the
validators from any point in the code? Enforcing validation rules on
form definition seems reasonable in most cases - makes the code much
cleaner. We could probably have some backdoor for specific uses, but
in 99,9% of the cases specifying validation rules on form definition
should be enough.
W
W
> However, I don't like that the example talks about "constraints" in one half of the app and "validation" in the other. This seems like an unnecessary distinction. However, the difference between constraints and validation could be useful as follows:
>
> - "constraints" define validation rules that can be expressed as a set of properties rather than procedural code.
> - "validation" extends this, adding the kind of validation that needs to be coded.
>
> Your thinking seems to be going in a direction that the developer who provides the specific DBFields/FormFields/FormWidgets is not responsible for defining the specific> validation rules for these fields - and these only get configured on the compound structures such as model or form?
--
I want to second Stig's suggestion that we should look into reusing existing implementations,
before going off too far into a tangent on new APIs.Symfony's Validator component is already decoupled from their form/model logic.More importantly, it has pluggable "metadata mappers", which means wecan hook build up validators from DataObject statics, as well as our own FormField collections.
When I was naively suggesting to 'reusing existing implementations', I was mostly referring to that we should perhaps not rewrite the validation constrains, since It's something I feel I've been doing over and over.