<?php
// Dépendance vers l'interface CallbackFormControl //
include_once('CallbackFormControl.inter.php');

/**
 * Classe qui gère le contrôle des données des formulaires
 * 
 * @author Olivier Arteau
 */

class FormControl {
	private static $PREDEFINED = array (
		'EN_Alphabet' => 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ',
		'IT_Alphabet' => 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZéèêëàâäáiîïíìôöòóûüùúÿ',
		'Space' => '\\s',
		'SpaceChar' => '\\s\\r\\n\\t',
		'CRLF' => '\\r\\n',
		'Number' => '0123456789',
		'Majuscule' => 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
		'Minuscule' => 'abcdefghijklmnopqrstuvwxyz'
	);
	
	private static $PREFORMATTED = array (
		'Alphabet' => '/^[a-zA-Zéèêëàâäáiîïíìôöòóûüùúÿ]+$/',
		'Email' => '/^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4}$/'
	);
	
	private static $PREFORMATTED_INSTRUCTION = '/^{:([A-Za-z]+):}$/';
	private static $PREDEFINED_INSTRUCTION = '/^{([A-Za-z_+-\\\\"]+)}$/';
	
	/**
	 * Vérifie si les données envoyés par un formulaire sont valides.
	 * 
	 * @param	(Array)					$formData	Données du formulaire
	 * @param	(Array)					$format		Format que les données doivent être pour être valide
	 * @param	(CallbackFormControl)	$obj		Si vous voulez faire un traitement particulier sur chaque élément selon qu'il est valide ou non
	 * 
	 * @return	(Boolean)							Si le formulaire est valide
	 */
	
	public static function checkForm(array $formData, array $format, CallbackFormControl $obj = null) {
		$isValid = true;
		
		// Si aucun callback, on en mets un vide //
		if ($obj == null)
			$obj = new EmptyCallbackFormControl();
			
		foreach ($format as $key=>$value) {
			$regexp = '';
			
			if (isset($formData[$key])) {
				// Pour les formats prédéfinis //
				if (preg_match(self::$PREFORMATTED_INSTRUCTION, $value, $matches) > 0) {
					if (isset(self::$PREFORMATTED[$matches[1]])) {
						$regexp = self::$PREFORMATTED[$matches[1]];
					} else {
						throw new Exception('Format prédéfini inconnu.');
					}
				// Pour les formats prédéfini sous le format {XXXX+AAAA-BBB+DDD-"abcd"} //
				} else if (preg_match(self::$PREDEFINED_INSTRUCTION, $value, $matches) > 0) {
					$content = $matches[1];
					$lstContent = preg_split('/[+-]/', $content);
					$regexp = '/^[';
					$charList = '';
					$indexInContent = -1;
					
					for ($i=0; $i<count($lstContent); $i++) {
						if (!isset(self::$PREDEFINED[$lstContent[$i]]) && $lstContent[$i]{0} != '"')
							continue;
						
						$charset = ($lstContent[$i]{0} != '"') ?
							self::$PREDEFINED[$lstContent[$i]] :
							substr($lstContent[$i], 1, -1);
						
						if ($i == 0 || $content{$indexInContent} == '+') {
							$charList .= $charset;
						} else {
							for ($x=0; $x<strlen($charset); $x++) {
								$charList = str_replace($charset{$x},'',$charList);
							}
						}
						
						$indexInContent += strlen($lstContent[$i]) + 1;
					}
					
					$regexp .= $charList .']+$/';
				// Pour le cas où l'utilisateur a mis lui même son expression régulière //
				} else {
					$regexp = $value;
				}
			} else {
				$isValid = false;
				$obj->onEachValue($key, false);
				continue;
			}
			
			// Test avec le regexp //
			if (preg_match($regexp, $formData[$key]) == 0) {
				$obj->onEachValue($key, false);
				$isValid = false;
			} else {
				$obj->onEachValue($key, true);
			}
		}
		
		return $isValid;
	}
}
?>