<?php
/**
 * Validierungs-Plugin
 *
 * @package federleicht
 * @subpackage plugin
 */

/**
 * Validierungsklasse
 */
class validation {
	/**
	 * Instanzvariablen
	 */
	var $error_msg;
	var $rules;

	/**
	 * Konstruktor
	 */
	function validation() {
	}

	/**
	 * Fehlermeldungen aus Datenbank holen
	 */
	function get_errormsg($datamodel) {
		$result = $datamodel->retrieve('language', '*', "tld = '".LANG."'");
		foreach( $result as $key => $value) {
			if ( substr($key, 0, 6) != 'error_' ) continue;
			$id = substr($key, 6);

			if ( !$this->rule_exists($id) )	$this->create_rule($id);
			$this->update_rule($id, FALSE, $value);
		}
	}

	/**
	 * Prüfausdruck hinzufügen
	 *
	 * Prüfausdruck wird zur Liste hinzugefügt. Der Rückgabewert zeigt an,
	 * ob das erfolgreich war.
	 *
	 * @param string $id  	ID des zu überprüfenden Datenfeldes
	 * @param string $type	Art der Überprüfung. Gültige Werte sind
	 *                    	- string	
	 *                    	- number	
	 *                    	- email 	
	 *                    	- regexp 	
	 * @param string $rule	zusätzliche Überprüfungsregel
	 *                      mögliche Werte sind
	 *                      - optional
	 *                      - multiline
	 *                      - [eine Mengenangabe nach RegEx-Syntax]
	 *                      - [ein regulärer Ausdruck]
	 * @return boolean
	 */
	function set_rule($id, $type, $rule='') {
		if ( !is_string($id) ) $id = (string) $id;
		if ( !is_string($type) ) $type = (string) $type;
		if ( !is_string($rule) ) $rule = (string) $rule;

		$start = '/^';
		$end = '$/';

		switch ($type) {
		case 'string':
			$regexp = '[- _a-zA-ZäüößÄÖÜ]';
			break;

		case 'number':
			$regexp = '[- 0-9]';
			break;

		case 'email':
			$regexp = '([A-Za-z0-9](([\w.-][^._-]*){0,61})[A-Za-z0-9])@([A-Za-z0-9]([A-Za-z0-9-]{0,61})?[A-Za-z0-9]\.)+([A-Za-z]{2,6})';
			break;

		case 'regex':
		case 'regexp':
			$regexp = $rule;
			$start = '';
			$end = '';
			$rule = '';
			break;

		default:
			$regexp = '.';
			break;
		}

		if ( preg_match('/(\{[,0-9]+\}|[*+?]{1,2})/', $rule) ) {
			$count = $rule;
		} elseif ( $type != 'regexp' AND $type != 'regex' ) {
			$rule .= ' ';
			$pieces = explode(' ', $rule);
			if ( in_array('optional',  $pieces) ) { 
				$count = '*'; 
			} else { 
				$count = '+'; 
			}

			if ( in_array('multiline', $pieces) ) $end = $end . 'm';
		} else {
			$count = '';
		}

		if ( !$this->rule_exists($id) )	$this->create_rule($id);
		$this->update_rule($id, $start . $regexp . $count . $end, FALSE);
		return TRUE;
	}

	/**
	 * Fehlermeldung zu einer Prüfregel hinzufügen
	 *
	 * @param string $id  	ID des zu überprüfenden Datenfeldes
	 * @param string $msg 	Fehlermeldung, falls die Prüfung Eingabefehler 
	 *                    	feststellt
	 * @return boolean
	 */
	function set_msg($id, $msg) {
		if ( !is_string($id) ) $id = (string) $id;
		if ( !is_string($msg) ) $msg = (string) $msg;

		if ( !$this->rule_exists($id) )	$this->create_rule($id);
		$this->update_rule($id, FALSE, $msg);
		return TRUE;
	}

	/**
	 * Formulardaten validieren
	 *
	 * Die Formulardaten werden anhand regulärer Ausdrücke auf Plausibilität 
	 * geprüft.
	 *
	 * @param array &$data Referenz auf Formulardaten
	 * @return array
	 */
	function validate_form(&$data) {
		if ( !is_array($data) ) return FALSE; 

		$rules = $this->get_rules();
		if ( empty($rules) ) return FALSE;
		$errors = array();

		foreach( $rules as $field=>$rule ) {
			if ( !preg_match($rule['regexp'], $data[$field]) ) {
				# unset($data['field']);
				$errors[] = $rule['error'];
			}
		}

		return $errors;
	}

	/**
	 * Javascript mit Regeln für die Formulardatenvalidierung zurückgeben
	 *
	 * Es wird eine JS mit den Regeln für die Validierung der Formulardaten 
	 * zurückgegeben.
	 * Außerdem wird der HTML-Code für das Einbinden des allgemeinen
	 * Validierungsskripts angefügt.
	 *
	 * @return string
	 */
	function get_js() {
		$form_variables = $this->get_rules();
		if ( empty($form_variables) ) return FALSE;

		$js = "var validationSet = {\n";
		$entries = array();
		foreach ($form_variables as $name => $properties) {
			$entries[] = "\t'".$name."': { 'regexp': ".$properties['regexp'].", 'error': ' ".addslashes($properties['error'])."'}";
		}
		$js .= implode(",\n", $entries) . "\n";
		$js .= "}\n";

		$html = '<script type="text/javascript">'."\n".'// <[CDATA['."\n";
		$html .= $js;
		$html .= '// ]]>'."\n".'</script>'."\n";
		$html .= '<script type="text/javascript" src="/public/js/validation.js"></script>'."\n";
		return $html;
	}

	################### Verwaltungsfunktionen ###########################
	/**
	 * Prüfen, ob Regel existiert
	 *
	 * @param string $id
	 * @return boolean
	 */
	function rule_exists($id) {
		return ( isset($this->rules[$id]) );
	}

	/**
	 * Regelarray erzeugen
	 *
	 * @param string $id
	 */
	function create_rule($id) {
		if ( $this->rule_exists($id) ) return;

		$this->rules[$id] = array(
			'regexp'=>'/.*/',
			'error'=>'Error in '.$id
		);
	}

	/**
	 * Regel aktualisieren
	 */
	function update_rule($id, $regex=FALSE, $msg=FALSE) {
		if ( !$this->rule_exists($id) ) return;

		if ( $regex !== FALSE ) $this->rules[$id]['regexp'] = $regex;
		if ( $msg !== FALSE ) $this->rules[$id]['error'] = $msg;
	}

	/**
	 * Regel entfernen
	 */
	function remove_rule($id) {
		if ( !$this->rule_exists($id) ) return;

		unset ($this->rules[$id]);
	}

	/**
	 * Regeln als Array zurückgeben
	 */
	function get_rules() {
		return $this->rules;
	}
	############### Ende der Verwaltungsfunktionen ######################
}
?>
