share annotaion validation rules between form and persistence - php

one "simple" question: http://mwop.net/blog/2012-07-02-zf2-beta5-forms.html
is it possible to use the zf2 zend form annotation validation rules without using zend form, so i can share the validation rules between a model validator (e.g. using for check if the model is correct before persisting it) and the zend form validation?
if my "name" should be not empty and between 5 and 20 characters, it is the same rule for the form and the model.
i hope i pointed it out clearly
Roman

Well, since all data that the models are getting would be from user input or the database, you shouldn't need to test the models itself, too. THe data inside the database should be correct!
IE: trust your own data but not the users?
But if you still wanna do that, i guess you could build the form with the AnnotationBuilder, then get the InputFilters from the Form (im sure there's a method, maybe on per-element-basis) and then use those inside your models - but as my first paragraph implies, i see this as a quite useless point :)
As for multi usable input filters, best thing would be to write own classes extending Zend\InputFilter\InputFilter on a per model basis. When you build your form then you can attach that class as the filter definition via $form->setInputFilter($myModelInputFilterClass) and you could also call that class inside your models to run your data through those filters. I haven't done this manually but it should work.
The only pitfall i guess might happen if you run into required statements. Checking on a per element basis, i don't know if that will work, too. As the InputFilter checks against all given filters. Though if you import a full CSV-Sheet or something you'd have a populateFromCsv() function or something that then checks all data anyways i guess.

Related

How to avoid bloating the controller code in CodeIgniter?

Controllers are there in MVC pattern to process user input and output. So, input validation and response preparation should be done in a controller.
For instance, I have a controller method "save" which:
looks for input data
runs a validator on the data
if inputs are valid, loads an appropriate model, sets its fields to input values, and calls its save() method
if inputs are invalid, prepares data to re-load the edit form, shows the form
All this sequence creates quite a mess of linear code. I'd like to separate it somehow. Do I move the validation part to a model? Sounds wrong? Do I create a special "library" class to handle inputs?
In Asp.Net MVC this would be better as they have implemented the "object binder" pattern. Hence, the validation and model field binding goes away and controller gets much lighter. Is there something similar for CodeIgniter?
It is not widely accepted that controllers do validation, I do them in model as per "keep your models fat, controllers thin and views dumb".
It depends on the business logic what is a valid phone number and so on, so it only makes sense for me to have it in model.
I would do exactly as you have eluded to and put as much logic into your models as possible. Controllers really should, imo, be used for initiating services and preparing data for views.
You should as much code reusable, ie validators, filters etc..

Codeigniter form validation to model logic

I'm working on my first CodeIgniter application and have encountered some confusion around handling post data.
More specifically, I understand the role of $this->form_validation->set_rules(), and how set_value() works to repopulate input values when the validation failed, but what I can't figure out is if $this->input->post is the same value as the set_value equivalent.
I understand that the majority of validation rules would have a boolean result, however what about ones like trim|htmlspecialchars - these also have the benefit of preparing the data for db queries.
So in my model, can I access the inputs after being processed by the Form Validation library, or should I do the additional preparation inside the model directly onto $this->input->post('variable')?
My gut tells me that I should add final processing like htmlspecialchars right before the SQL in the model, as it is really a db specific operation (I would not want & instead of & in my form inputs, but I would want & in the database).
Incidentally in my reading I did come across $this->validation->variable which would appear to have been the answer to my question in previous CI versions.
They are similar, but not exactly the same.
You would use $this->input->post('variable'); within the controller only. This variable will be validated and cleaned (if you decide to clean it with xss_clean or apply any other prepping functions).
set_value() should only be used within the Views. While this is not essential, the real value of doing this opposed to using $this->input->post is you can set a "default" value as the 2nd parameter which is automatically used if the post value is empty.
As mentioned set_value() is strictly for repopulating form inputs - nothing else. For example, set_checkbox() is going to return something like checked="checked" which is obviously not what you want to send to your model.
There's room for argument about where the input validation and prepping should be handled, but most will agree that it should be done in the controller.
You can do additional processing in the model if you wish, but generally you don't want to be accessing $_POST from the model - it makes the model less useful. Not all data is going to be coming straight from the user, so it's better to prep the data beforehand and send it as a new array/object to the model. The model should not care where the data is coming from.
Let the form validation library and controller layer process the user input (what it's intended for), and the model can process the data you send to it.
Developer
I work both frame work cakephp and codeignator. I feel best thing cakephp data validation. spouse you have 8 fields form you create validation in controller with designator. After validation all fields is empty if you fill 8 fields and by mistake 1 fields miss then after validation codeignator data validation refresh page and empty all fields.
but in cake php just opposite data validation create in model you create one time validation and use some thins when you call model then call validation exp: add,edit.

How does the CodeIgniter DataMapper ORM know which set of validation rules to apply?

I am using the CodeIgniter DataMapper ORM, but there is something that I don't quite understand.
In this example, http://datamapper.wanwizard.eu/pages/examples/login.html, you can see that there are some $validation rules defined on the User model class.
Inside the login function, you can also see that it calls $this->validate()->get(). When the validation function is run, it should check against all rules from $validation.
What I don't understand is, for the login use case, only username and password need to be validated but you can see there are other validation rules unrelated to this use case in the example. Specifically, there is a confirm_password rule defined on $validation and this rule obviously is only for the update use case, rather than the login use case.
Since I don't see any codes that bypass these unrelated rules in the example, how does the DataMapper ORM actually know these unrelated rules can be bypassed in the login function?
Many thanks to you all.
Maybe the solution is to make 2 models: one is "login"(for table user), and other one is "register"(also for table user). Then, when you want to login, just use login model of user. I think that this is true purpose of models. (now you have 2 sets of validation in 2 models)
Datamapper's validation method ignores rules for fields not part of the object. So the confirm_password rule won't trigged unless the object has a property by that field name.
Data validation rules should be in the model, not in the controller, as it is the only entry point to your data, and it ensures all data going into the database is validation. It also answers to DRY, you don't want to define validation rules in every controller that uses the model.
Given this fact, it is simple to define the rules for extra fields that might be on your CRUD forms as well and keep it all in one place.
Calling an object's validate() function is all that's needed to have the validation rules applied. Note that validate is automatically run whenever you perform a save() call without parameters. You can also run or validate()->get() on an object to get a matching record using the objects current field values.
http://datamapper.wanwizard.eu/pages/validation.html
I think simply because validation will run using the objects current fields, and the "confirm_password" field is a "non-database table field".
For login use form_validation library and only verify username/password, for registration you can use DataMapper and in you model add a rule confirm_password must match password but do not add required rule in confirm_password.. that should do it

Define "Validation in the Model"

There have been a couple of discussions regarding the location of user input validation:
Should validation be done in Form objects, or the model?
Where do you do your validation? model, controller or view
These discussions were quite old, so I wanted to ask the question again to see if anyone had any fresh input. If not, I apologise in advance.
If you come from the Validation in the Model camp - does Model mean OOP representation of data (i.e. Active Record/Data Mapper) as "Entity" (to borrow the DDD terminology) - in which case you would, I assume, want all Model classes to inherit common validation constraints. Or can these rules simply be part of a Service in the Model - i.e. a Validation service? For example, could you consider Zend_Form and it's validation classes part of the Model? The concept of a Domain Model does not appear to be limited to Entities, and so validation may not necessarily need to be confined to this Entities.
It seems that you would require a lot of potentially superfluous handing of values and responses back and forth between forms and "Entities" - and in some instances you may not persist the data recieved from user input, or recieve it from user input at all.
I much prefer to put validation in the model, personally. Security considerations of course are beyond the scope of what a model should be used for, but nothing says that a model is updated in exactly one place by exactly one form. By putting type validation and sanity checking outside the model, you have to validate every time you set anything on it, which leads to copy/pasted code that's difficult to update.
I use Zend_Form as part of my models - models are creating the Zend_Form objects. I go this way because Zend_Form is not about the form rendering only; backed up with Zend_Validate and Zend_Filter it is a very powerful tool (my fav from the ZF stack). Matthew Weier O'Phinney wrote a nice post about using Zend_Forms in models: http://weierophinney.net/matthew/archives/200-Using-Zend_Form-in-Your-Models.html
Data validation should be on its own, called by the controller just before committing to the model.
Haven't used PHP and haven't worked with Zend framework (have heard though), but I really like Jimmy`s blog post about validation from domain driven design perspective.
I considered many different approaches of data validation, and decided that best way of validation - it's validation before entity creation, since validation it's something which can be very dependent from context, and entity itself should not perform validation, because entity should always be in valid state.
So maybe best approach - use separate validation classes to validate data before passing it to entity constructor.
When handling user input, you should definitely handle all logic-oriented validation outside the model.
The model doesn't care about your business logic. The model doesn't care if your start date is after your end date - all the model cares about is that the date is a valid entry for that particular field in the database. It checks the data, sees a properly formatted date and moves on to the next one, because the model's entire realm of responsibility is to ensure the smooth flow of data to and from a data source.
Classes like Zend_Form are nothing more than abstractions of your view.

Should you validate in the Model? (Symfony based question, but related to general MVC)

This is a quick question relating to Symfony, but could be a general MVC question.
I have a class in my model, for example, WebUser. This class has a property of email_address. This value must be unique to each WebUser.
Now, I've made it so all my Symfony forms validate that the email_address is unique for the given WebUser, however I'm wondering if I should add this validation to the model as well?
But this also got me thinking, should you actually validate every set() method in the model? It seems a wise enough decision to make sure no erroneous data ends up in the database, however most (if not all) data has to go through the controllers, which validate as well. So to me it seems I'm running the same validation twice and it just seems pointless?
What are your thoughts on this? I'm still leaning towards validation in the model as that makes the most sense as it dictates the business logic.
If you should validate in the model, how do you throw an appropriate set() error in Symfony that is handled correctly by the form framework?
Thanks.
I disagree with "Validation should be part of domain logic, not front-end logic".
Validation is a complex functional part of your application and must be context aware. ie. you have to know is the user is logged in, what kind of credentials she has, the status of the request/form and so on. Models instead must be context agnostic (to work in any environment not only http request but also cli etc.) so they don't know about the user, the state and the http request. This is a strong requirement for the testability of your model classes.
For the summentioned reason functional validation must belong to the form which knows the application state (ie. session). symfony helps a lot with the sfValidator* classes which belongs to the form component indeed. That's the reason why forms are tested with functional testing.
Data validation should be in the model instead (ie. check if the value is an integer or a string, check if it's null and so on). This is easily accomplished with the Doctrine in-schema validation rules.
I can't speak specifically to Symfony, but I know that I purposely shun Zend Framework's form validation, and instead validate on my models (Zend Framework does not provide its own Model component, so it has no actual opinion on the matter).
There's nothing wrong with validating on the form, but I think you should also be validating on the model. Validating on the form might be useful for quick and easy input checking, especially if the processing logic is complex - you won't waste time working with data that's obviously bad.
Reasons I think model validation is best:
There's a chance a model will alter the data after it passes through the form and before it goes into the DB
Validation should be part of domain logic, not front-end logic (I realize Symfony seems to disagree).
Validation state travels with the model object, instead of the form object.
If you're not totally sold validating only in the model, a combination of the two sounds like a good solution.
EDIT: At the end of the day, it might make the most sense to just go with your framework on this. If Symfony seems most opinionated toward validation in the controller, and doesn't provide an easy path for validation in the model, just go with what they want you to do (or the direction in which the Symfony community leans). Fighting your framework is never fun.
I can't help out with the symfony part but most MVC-Frameworks do validation in the model, since this is the only place inside a MVC environment where validation should be.
This goes for the validation of the model's attributes of course.
I Think You Should User MVC Validator Tool Ket Insted of using others rely on modelstate its easyer and also testable and its based on formcollected not to the model that give you free run way
Regards MArwan HAfez

Categories