06.27 php saved
jakub
Tags add more
cross model validati  
Note
very first version of cross model validation behavior.
  1. <?php
  2. class CrossModelValidationBehavior extends ModelBehavior  {
  3.     function setup(&$model, $config = array()) {   
  4.         $this->defaultValidationMessage = "Wrong data given!";
  5.     }
  6.    
  7.     function getValidationError($modelObjectName, $fieldName, $validationRule) {       
  8.         if(is_string($validationRule)) {
  9.             return ife($this->validation->$validationRule($this->model->data[$modelObjectName][$fieldName]) == false, $this->defaultValidationMessage, null);         
  10.         }else {        
  11.             if(isset($validationRule['rule'])) {               
  12.                 if(isset($validationRule['allowEmpty']) && empty($this->model->data[$modelObjectName][$fieldName])){
  13.                     if($validationRule['allowEmpty'] === false) {
  14.                         return ife(!empty($validationRule['message']),$validationRule['message'], $this->defaultValidationMessage);
  15.                     } else {
  16.                         return null;                       
  17.                     }
  18.                 }
  19.  
  20.                 if(isset($validationRule['required']) && empty($this->model->data[$modelObjectName][$fieldName])){
  21.                     if($validationRule['required'] === true) {
  22.                         return ife(!empty($validationRule['message']),$validationRule['message'], $this->defaultValidationMessage);
  23.                     } else {
  24.                         return null;                       
  25.                     }
  26.                 }            
  27.                
  28.                 if(is_string($validationRule['rule'])) {
  29.                     return ife($this->validation->$validationRule['rule']($this->model->data[$modelObjectName][$fieldName]) == false,ife(!empty($validationRule['message']),$validationRule['message'], $this->defaultValidationMessage), null);                   
  30.                 } else {
  31.                                        
  32.                     switch($validationRule['rule'][0]) : // asumming that rule name will be given as a first element of array
  33.                         case 'between':
  34.                             return ife($this->validation->$validationRule['rule'][0]($this->model->data[$modelObjectName][$fieldName], $validationRule['rule'][1], $validationRule['rule'][2]) == false, ife(!empty($validationRule['message']),$validationRule['message'], $this->defaultValidationMessage), null);                           
  35.  
  36.                         case 'custom':             
  37.                         case 'decimal':
  38.                         case 'email':
  39.                         case 'equalTo':
  40.                         case 'extension':                                                               
  41.                         case 'maxlegth':
  42.                         case 'minlegth':
  43.                         case 'multiple':                               
  44.                             return ife($this->validation->$validationRule['rule'][0]($this->model->data[$modelObjectName][$fieldName], $validationRule['rule'][1]) == false, ife(!empty($validationRule['message']),$validationRule['message'], $this->defaultValidationMessage), null);
  45.  
  46.                         case 'comparison':
  47.                         case 'phone':
  48.                         case 'postal'
  49.                         case 'range':
  50.                         case 'ssn':        
  51.                             return ife($this->validation->$validationRule['rule'][0]($this->model->data[$modelObjectName][$fieldName], $validationRule['rule'][1],$validationRule['rule'][2]) == false, ife(!empty($validationRule['message']),$validationRule['message'], $this->defaultValidationMessage), null);
  52.                            
  53.                         case 'cc':
  54.                             return ife($this->validation->$validationRule['rule'][0]($this->model->data[$modelObjectName][$fieldName], $validationRule['rule'][1],$validationRule['rule'][2],$validationRule['rule'][3]) == false, ife(!empty($validationRule['message']),$validationRule['message'], $this->defaultValidationMessage), null);
  55.                     endswitch;         
  56.                 }            
  57.                
  58.             } else {
  59.                 foreach($validationRule as $rule):
  60.                     $this->getValidationError($modelObjectName, $fieldName, $rule);
  61.                 endforeach;       
  62.             }
  63.         }
  64.                
  65.     }
  66.    
  67.     function crossValidate(&$modelObject) {
  68.         $validationRules = $modelObject->validate;   
  69.         foreach($validationRules as $fieldName => $validationRule):   
  70.             if(is_string($validationRule) || isset($validationRule['rule'])) {
  71.                 $modelObject->validationErrors[$fieldName] = $this->getValidationError($modelObject->name, $fieldName, $validationRule);                       
  72.             } else {
  73.                 $errorMessages = array();            
  74.                 foreach($validationRule as $rule):
  75.                     $error = $this->getValidationError($modelObject->name, $fieldName, $rule);
  76.                     if(!is_null($error)):
  77.                         array_push($errorMessages,$error);
  78.                     endif;
  79.                 endforeach;
  80.                 if(!empty($errorMessages[0])):
  81.                     for($i=1; $i<=sizeof($errorMessages);$i++):
  82.                         // zamienic na maa litere pierwszy znak kazdego stringa     
  83.                     endfor;
  84.                 endif;                 
  85.                 $errorMessage = implode(', ',$errorMessages);
  86.                 $modelObject->validationErrors[$fieldName] = $errorMessage
  87.             }
  88.         endforeach;  
  89.  
  90.        
  91.         if(empty($this->model->validationErrors)):
  92.             $tmp = implode('',$modelObject->validationErrors);
  93.             if(!empty($tmp)):   
  94.                 $this->model->validationErrors['crossValidaionErrosOccured'] = true;
  95.             endif;
  96.         endif;
  97.        
  98.     }
  99.    
  100.     function searchForModelObject(&$modelObject, $searchedModel) {
  101.         // get all associated models to currently fetched model object
  102.         $modelObjectAssociations = $modelObject->getAssociated();
  103.         // lets see if $searchedModel was already fetched, if not - continue
  104.         if(!in_array($searchedModel, $this->alreadyFound)):
  105.             // was $searchedModel just found ?
  106.             if(array_key_exists($searchedModel, $modelObjectAssociations)) {
  107.                 // has it any validation rules that needs to be performed ?
  108.                 if(!empty($modelObject->$searchedModel->validate)):
  109.                     $this->crossValidate($modelObject->$searchedModel);
  110.                 endif;
  111.                 // put just found model into $this->alreadyFound to avoid multiple searching for same model   
  112.                 array_push($this->alreadyFound, $searchedModel);
  113.             } else {
  114.                 // we didn't find model, so serach for it in all models associated to current one
  115.                 foreach($modelObjectAssociations as $associatedModel => $assotiationType):
  116.                     $this->searchForModelObject($modelObject->$associatedModel, $searchedModel);
  117.                 endforeach;
  118.             }
  119.         endif;
  120.     }
  121.    
  122.  
  123.     function beforeValidate(&$model) {
  124.         // create some reference to our model
  125.         $this->model = & $model;
  126.        
  127.         $this->validation = & Validation::getInstance();
  128.            
  129.         // keeps names of already found models, just to avoid looping, for the begining just skip our primary model.
  130.         $this->alreadyFound = array($model->name);
  131.                        
  132.         $modelBindigs = $model->getAssociated();
  133.         foreach($model->data as $modelName => $modelData):
  134.             $this->searchForModelObject($model, $modelName);
  135.         endforeach;
  136.        
  137.         //$model->validationErrors['crossValidaionErrosOccured'] = true;
  138.     }
  139. }
  140.  
Parsed in 0.342 seconds, using GeSHi 1.0.7.14

Modify this Paste