<?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;
}
}