<?php
/**
 * Třída pro validaci uživatelského vstupu
 * @author milda
 * @copyright Milan Lempera  2009
 */
class Validate {

/**
 * chyby při poslední validaci
 * @var array
 */
  static private $errors = array();
 
/**
 * chybové zprávy pro validaci
 * @var array
 */
  static private $validatemessage = array('required' => 'Pole %name nesmí být prázdné', 
                                          'remote'   => 'Pole %name neprošlo validací', 
                                          'minlength' => 'Pole %name musí mít minimálně %val znaků',
                                          'maxlength' => 'Pole %name může mít maximálně %val znaků',
                                          'rangelength' => 'Pole %name musí mít délku v rozsahu %val znaků',
                                          'min'   => 'Pole %name nesmí obsahovat hodnotu menší než %val',
                                          'max'   => 'Pole %name nesmí obsahovat hodnotu větší než %val',
                                          'range' => 'Pole %name musí být v rozsahu %val',                             
                                          'email' => 'Pole %name musí obsahovat validní e-mail',
                                          'url'	  => 'Pole %name musí obsahovat validní URL adresu',
                                          'date'  => 'Pole %name musí obsahovat validní datum např.(10/10/2009)',
                                          'dateISO' => 'Pole %name musí obsahovat validní datum např.(2009-10-10)',
                                          'dateDE'  => 'Pole %name musí obsahovat validní datum např.(1.12.2008)',
                                          'number'	  => 'Pole %name musí obsahovat validní číslo (k oddělení desetin použijte tečku)',
                                          'numberDE'  => 'Pole %name musí obsahovat validní číslo (k oddělení desetin použijte čárku)',
                                          'digits'	  => 'Pole %name musí obsahovat celé číslo',
                                          'accept'	  => 'Pole %name může obsahovat pouze následující soubory %val', // "jpg|jpeg"
                                          'equalTo'	  => 'Pole %name musí být stejné jako %legend',  // "#identifikator"
                                          'creditcard' => 'Pole %name musí obsahovat platné číslo kreditní karty',  // 446-667-651
                                    	  	'telefon'	   => 'Pole %name musí obsahovat platné telefonní číslo (např.&nbsp;777123123,&nbsp;nebo&nbsp;+420777123)',
                                    	  	'url_bezw'   => 'Pole %name musí obsahovat url adresu ve formátu www.adresa.cz, případně www.adresa.cz/adr'
                                          );

  static function error() {

    $ret = '<br />';
    foreach(self::$errors as $item) {
      $ret .= '<span> &rarr '.$item.'</span><br />';
    }
    return $ret;

  }

  
  static function entita($entita, $new = false) {

  	$ret = true;
  	$legend = $entita->label;

  	self::stateValidate($entita);

  	foreach($entita->validate as $field=>$valid) {
	    if ( (@$valid['required'] != 'true') AND ( empty($_POST[$field]) ) ) {
        continue(1);
    	}

      foreach($valid as $key=>$value) {
  
        if (self::check(@$_POST[$field], $key, $value) != true) {
  
          $ret = false;
          $err = self::$validatemessage[$key];
        	if ($key == 'range' OR $key == 'rangelength') {
            $value = substr($value, 1);
        	  $value = substr($value, 0, -1);
        	  $va = explode(',', $value);
        	  if ($va[0] == $va[1]) {
        	    $value = $va[0];
        	  }
        	  else {
        	    $value = $va[0].' až '.$va[1];
        	  }
        	}
        	$leg = @$legend[$field];
        	if (empty($leg)) {
        	  $leg = $field;
        	}
        	$err = str_replace('%name', '<b>'.$leg.'</b>', $err);
          $err = str_replace('%val',  '<b>'.$value.'</b>', $err);
          if ($key == 'equalTo') {
            $err = str_replace('%legend', '<b>'.$legend[$value].'</b>', $err);
          }
  				
          self::$errors[] = $err;
        	   //break 1;
        }
      }
  	}
  	return $ret;
  }

  static function form($id) {
    $registry = Registry::getInstance();
		$form = $registry->$id;
	
  	if (empty($form)) {
  	  return false;
  	}
  
  	$ret = true;
  	$validate = $form['validate'];
  	$legend   = $form['legend'];
  
    	foreach($validate as $field=>$valid) {
      if ( (@$valid['required'] != 'true') AND ( empty($_POST[$field]) ) ) {    
          // pokud není položka povinná a je prázdná, nekontroluje se
          //Debug::getVar($field, $valid,@$validate['required'] != 'true', empty($_POST[$field]),(@$validate['required'] != 'true' AND empty($_POST[$field])));
          continue;
      }
    
      foreach($valid as $key=>$value) {
    
      if (self::check(@$_POST[$field], $key, $value) != true) {
  //Debug::getVar($key,$value, $_POST[$field] );
        $ret = false;
        $err = self::$validatemessage[$key];
      	if ($key == 'range' OR $key == 'rangelength') {
            $value = substr($value, 1);
      	  $value = substr($value, 0, -1);
      	  $va = explode(',', $value);
      	  if ($va[0] == $va[1]) {
      	    $value = $va[0];
      	  }
      	  else {
      	    $value = $va[0].' až '.$va[1];
      	  }
      	}
      	$leg = @$legend[$field];
      	if (empty($leg)) {
      	  $leg = $field;
      	}
      	$err = str_replace('%name', '<b>'.$leg.'</b>', $err);
          $err = str_replace('%val',  '<b>'.$value.'</b>', $err);
          if ($key == 'equalTo') {
            $err = str_replace('%legend', '<b>'.$legend[$value].'</b>', $err);
          }
    
          self::$errors[] = $err;
      	   //break 1;
      	}
      }
    }
    return $ret;
  }

  static private function range($param) {

		$param = substr($param,1);
		$param = substr($param,0,-1);
		return explode(',',$param);
  }

  static public function check($value = '', $type, $param = '') {

    switch($type) {
	  case 'required':
	    return !empty($value) OR is_numeric($value);
	    break;

	  case 'minlength':
        return (strlen($value) >= $param);
	    break;

      case 'maxlength':
        return (strlen($value) <= $param);
	    break;

      case 'rangelength':
        list($min, $max) = self::range($param);
        $lenght = strlen($value);
        return (($lenght <= $max) AND ($lenght >= $min) );
        break;

      case 'min':
        return ($value >= $param);
	    break;

      case 'max':
        return ($value <= $param);
	    break;
	      
      case 'range':
        list($min, $max) = self::range($param);
        return (($value <= $max) AND ($value >= $min) );
	    break;

	  case 'email':
        return (eregi('[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}', $value) !== false);
        break;

      case 'url':
        return (eregi('(http|https|ftp)\://([a-zA-Z0-9\.\-]+(\:[a-zA-Z0-9\.&%\$\-]+)*@)?((25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9])\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[0-9])|([a-zA-Z0-9\-]+\.)*[a-zA-Z0-9\-]+\.[a-zA-Z]{2,4})(\:[0-9]+)?(/[^/][a-zA-Z0-9\.\,\?\'\\/\+&%\$#\=~_\-@]*)*',
          $value) !== false);
        break;
        
      case 'url_bezw':
        return true;
        break;

      case 'equalTo':
        return ($value == $_POST[$param]);
        break;

      case 'date':
        return ereg('^(0?[1-9]|1[012])[- /.](0?[1-9]|[12][0-9]|3[01])[- /.](19|20)[0-9][0-9]$', $value );
        break;

      case 'dateISO':
        return ereg('^(19|20)[0-9][0-9][- -.](0?[1-9]|1[012])[- -.](0?[1-9]|[12][0-9]|3[01])$', $value );
        break;

      case 'dateDE':
        return ereg('^(0?[1-9]|[12][0-9]|3[01])[- \..](0?[1-9]|1[012])[- \..](19|20)[0-9][0-9]$', $value );
        break;

      case 'number':
        return ereg('^[\+-]?([0-9]{1,})\.?([0-9]*)$', $value);
        break;

      case 'numberDE':
        return ereg('^[\+-]?([0-9]{1,}),?([0-9]*)$', $value);
        break;

      case 'digits':
        return ereg('^[\+-]?([0-9]{1,})$', $value);
        break;

      case 'telefon':
        return ereg('^([\+]?)([0-9]{9,12})$', $value);
        break;

      case 'accept':
      	return true;
      	break;

      case 'creditcard':
      case 'remote':
die(__METHOD__.': dodělat validaci typu '.$type);
	    break;

      default:
die(__METHOD__.': neznámí typ validace '.$type);
	    break;
	  }
	}

  static public function stateValidate(& $entita) {

  	$entita->stavy = array($_POST['stav'] => true);
    if (!isset($entita->state_validate[$_POST['stav']] )) {
    	throw new Appliexception(4, 'Pro požadovaný stav neexistují validační pravidla!');
    }

    $entita->stateDiffValidate();
  }
}
?>