Welcome Guest, Not a member yet? Register   Sign In
Poll: Do we need new solution for Form filtering and validation?
You do not have permission to vote in this poll.
Yes
53.33%
16 53.33%
No
36.67%
11 36.67%
maybe
10.00%
3 10.00%
Total 30 vote(s) 100%
* You voted for this item. [Show Results]

Input filtering and Form validation
#11

(This post was last modified: 04-08-2015, 09:33 AM by sv3tli0.)

Form validation inside a model is not acceptable for me. You don't send requests to models to validate them, this is a joke I hope.

The current rules are nice I don't say that they should be replaced.
What I mean is to move all things outside the controller into a separate Form type class which will handle the form request and it will apply all filters/validation rules (which will contains all callback methods..).
This will clean your controllers and you will have just to call this form element(class) and to run the validation command(method) nothing more..
Best VPS Hosting : Digital Ocean
Reply
#12

(04-08-2015, 09:31 AM)sv3tli0 Wrote: Form validation inside a model is not acceptable for me. You don't send requests to models to validate them, this is a joke I hope.

The current rules are nice I don't say that they should be replaced.
What I mean is to move all things outside the controller into a separate Form type class which will handle the form request and it will apply all filters/validation rules (which will contains all callback methods..).
This will clean your controllers and you will have just to call this form element(class) and to run the validation command(method) nothing more..

I just create a library for that. Each method in the library just contains the rules for the form fields needed and returns the result of $this->form_validation->run()

Then in the controllers, I just do:
PHP Code:
if ($this->form_library->validate_add_user())
{
  
//it validated
}
else
{
  
//validation error

Reply
#13

Ok this is 1 way to make it. In small sites it will be enough.
But its not CI basic way and its not good structural as you have to put all different form types (clients, products, cart items, likes and etc) to 1 lib.

My idea is all those things to be in separate files as templates for each form. Following OOP idea they should be Class's.

This is a feature for the next version not fix of the current one Smile I know that you already have handled such problems in CI 2 and CI 3 but this is not a reason not to change it and make it easier and better in the next CI..
Best VPS Hosting : Digital Ocean
Reply
#14

You don't have to use "1 lib" containing all "groups of rules", you can separate into as many libraries as you need or want. They are just standalone classes (libraries) that uses get_instance() to pull CI into them to access the form validation library, run the rules and return the result of the validation. It sounds basically like the same thing you are wanting when you say "all those things to be in separate files", except nothing in CI needs to change and can be used in any version of CI using current CI methods.
Reply
#15

(04-08-2015, 09:31 AM)sv3tli0 Wrote: Form validation inside a model is not acceptable for me. You don't send requests to models to validate them, this is a joke I hope.

If your view of a model is that it is the central place that handles all business logic for the data, then validating within the model is perfectly fitting the MVC pattern. Typically, though, we seem to treat our Models as the Data Access layer which can be completely separate from the Model itself.

So, really, it's all terminology Smile
Reply
#16

(04-08-2015, 09:31 AM)sv3tli0 Wrote: Form validation inside a model is not acceptable for me. You don't send requests to models to validate them, this is a joke I hope.

The current rules are nice I don't say that they should be replaced.
What I mean is to move all things outside the controller into a separate Form type class which will handle the form request and it will apply all filters/validation rules (which will contains all callback methods..).
This will clean your controllers and you will have just to call this form element(class) and to run the validation command(method) nothing more..

Just food for a thought:

I'm not validating anything in the controller nor in the model

Validating an array other than post did the trick for me

because i've separated Data Objects.
Those objects react based on the different Request Types by creating an array which are passed to the form validation object

And those objects are handled between models and controllers  - thats the reason why i've extended my folder structure to (controllers/models/objects/views)

In my opinion the process of data validation has to be separated from models AND controllers - its something totally different - and those actions tend to blow up your models or controllers (depending on your preferred method)
Reply
#17

Might as well throw my hat into the mix.
The way I view it (and currently do it) is that the model is "incharge" of what the model data should look like and therefore validate it.
You can't add a column to a table for example without getting the mode involved anyway.

As a simple example let's say you have a column which you set to a max length of 32 characters in your database table. The model knows this and therefore when you try to enter 33 characters it fails and says it's to long. You then realize that 64 characters would have been better. Just by changing the code in the model (ie max length from 32 to max length 64) nothing else needs to change (ok maybe a html element attribute in this example but a non PHP dev could do that). The controller say's "hey model is this posted data I got any good?" On fail "Hey model give me a array of the errors to show the user why you didn't like it?" On Pass "Ok can you please save it and let me know if you where able to so I can tell the user?"

The rules are in a array as part of the model
Then I have a mapping like 'insert' & 'update' (also part of the model) which get's the needed rules and run's the validation (and filters - I extended it).

Something like:
$success = $this->validation->validate($the_data,'insert');
$success = $this->validation->validate($the_data,'insert_from_shorter_form');

I always treated the "model" like it was in charge of the data even if it's a file, database table(s), csv file, sftp feed from the moon, etc...

This leaves my controller pretty slim and let's a data "guy" do his thing to make sure the data I am giving him is up to HIS standards.

All that said I think CI should treat the validation library more like it's own thing and not directly attached to form/controllers (They have made changes to reflect this in  recent versions already).

Like somebody else said the library and it's rules work great as they are. I only feel we need to extend it.

I try to think of the Model as 1 Guy, Controller another, and finally View's as a 3rd and none of them like to talk (or talk as little as possible). Of course in real life i'm usually all 3.

DMyers
Reply
#18

my form validator
PHP Code:
<?php

class FormException extends MY_Exception{}

class 
Form_validator{
    private 
$_validator_rules$_errors;
    protected 
$form_data$rules;

    public function 
__construct(){
        
$this->_validator_rules=array(
            
'email'=>array(
                
'type'=>'regexp',
                
'pattern'=>"/^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/",
                
'err_code'=>9901
            
),
            
'url'=>array(
                
'type'=>'regexp',
                
'pattern'=>"/^http:\/\/[A-Za-z0-9]+\.[A-Za-z0-9]+[\/=\?%\-&_~`@[\]\':+!]*([^<>\"])*$/",
                
'err_code'=>9902
            
),
            
'zip'=>array(
                
'type'=>'regexp',
                
'pattern'=>"/^[1-9]\d{5}$/",
                
'err_code'=>9904
            
),
            
'english'=>array(
                
'type'=>'regexp',
                
'pattern'=>"/^[A-Za-z]+$/",
                
'err_code'=>9906
            
),
            
'mobile'=>array(
                
'type'=>'regexp',
                
'pattern'=>"/^((\(\d{3}\))|(\d{3}\-))?13\d{9}$/",
                
'err_code'=>9907
            
),
            
'phone'=>array(
                
'type'=>'regexp',
                
'pattern'=>"/^((\(\d{3}\))|(\d{3}\-))?(\(0\d{2,3}\)|0\d{2,3}-)?[1-9]\d{6,7}$/",
                
'err_code'=>9908
            
),
            
'number'=>array(
                
'type'=>'func',
                
'func'=>function($value){
                    if(!
is_numeric($value)){
                        throw new 
FormException(9909);
                    }
                },
            ),
            
'required'=>array(
                
'type'=>'func',
                
'func'=>function($value){
                    
$value=trim($value);
                    if(
strlen($value)<1){
                        throw new 
FormException(9910);
                    }
                }
            ),
            
'length'=>array(
                
'type'=>'func',
                
'func'=>function($value,$max_len,$min_len=null){
                    
$value=trim($value);
                    
$len=strlen($value);
                    if(
$len>$max_len){
                        throw new 
FormException(9911);
                    }
                    if(
$min_len && $len<$min_len&&$min_len){
                        throw new 
FormException(9912);
                    }
                }
            )
        );
    }

    
/**
     * @param string $name
     * @param array $rule 
 *                     'type'=>'regexp|func'
 *                     'pattern'=>'regexp pattern',
 *                     'func'=>function(){}
     * @param bool $is_overwrite
     *
     * @return bool
     */
    
public function addValidatorRule($name,$rule,$is_overwrite=FALSE){
        if(!
$is_overwrite && isset($this->_validator_rules[$name])){
            return 
FALSE;
        }
        
$this->_validator_rules[$name]=$rule;
        return 
TRUE;
    }

    
/**
     * @return mixed
     */
    
public function getErrors(){
        return 
$this->_errors;
    }

    
/**
     *
     * @param array      $rules
     * @param array|null $form_data
     *
     * @return bool
     */
    
public function setRules($rules$form_data=NULL){
        if(!
$form_data){
            
$form_data=$_POST;
        }
        
$this->form_data=$form_data;
        foreach(
$rules as $name=>$rule){
            if(
is_array($rule)) {
                
$rule_list=$rule;
            }else{
                
$rule_list=array($rule);
            }
            
$this->rules[$name]=$rule_list;
        }
    }

    
/**
     **
     * @return bool
     */
    
public function validate(){
        
$result=TRUE;
        foreach(
$this->rules as $name=>$rules){
            if(!
$this->_isValidate($name,$rules)){
                
$result=FALSE;
            }
        }
        return 
$result;
    }

    
/**
     *
     * @param string $element
     * @param array $rules
     *
     * @return bool
     */
    
private function _isValidate($element,$rules){
        
$result=TRUE;
        try{
            
$form_data=$this->form_data;
            
$value=isset($form_data[$element])?$form_data[$element]:null;
            foreach(
$rules as $name){
                
$rule_info=$this->_parseRule($name);
                
$rule=isset($this->_validator_rules[$rule_info['name']])?$this->_validator_rules[$rule_info['name']]:array();
                if(!
$rule||!is_array($rule)){
                    continue;
                }
                
$type=$rule['type'];
                if(
$type=='regexp'){
                    
$result=preg_match($rule['pattern'],$value)!==FALSE;
                    if(!
$result){
                        throw new 
FormException($rule['err_code']);
                    }
                }
                elseif(
$type=='func'){
                    
$paras=array();
                    if(isset(
$rule_info['paras'])&&is_array($rule_info['paras'])){
                        
$paras=$rule_info['paras'];
                    }
                    
array_unshift($paras,$value);
                    
call_user_func_array($rule['func'],$paras);
                }
            }
        }
        catch(
FormException $e){
            
$this->_errors[$name]=$e->getMessage();
            
$result=FALSE;
        }
        return 
$result;
    }

    
/**
     * parse rule name
     *
     * @param string $rule_name
     *
     * @return array
     */
    
private function _parseRule($rule_name){
        
$rule=explode('(',$rule_name);
        
$rule_info=array(
            
'name'=>isset($rule[0])?$rule[0]:$rule_name,
            
'paras'=>array()
        );
        if(isset(
$rule[1])){
            
$para=str_replace(')','',$rule[1]);
            
$rule_info['paras']=explode(',',$para);
        }
        return 
$rule_info;
    }

Reply




Theme © iAndrew 2016 - Forum software by © MyBB