diff --git a/mvc/Model.php b/mvc/Model.php
index 428f203..15404be 100755
--- a/mvc/Model.php
+++ b/mvc/Model.php
@@ -131,9 +131,11 @@
 			foreach ($fields as $field)
 			{
 				$fieldInfo = array();
+				$fieldInfo['NAME'] = $field['Field'];
 				$fieldInfo['NULL'] = $field['Null'] == 'NO' ? false : true;
 				$fieldInfo['AUTO_INCREMENT'] = $field['Extra'] == 'auto_increment' ? true : false;
 				$fieldInfo['PRIMARY'] = $field['Key'] == 'PRI' ? true : false;
+				$fieldInfo['FOREIGN'] = $field['Key'] == 'MUL' ? true : false;
 				$fieldInfo['UNIQUE'] = $field['Key'] == 'UNI' ? true : false;
 				$fieldInfo['TYPE'] = mb_convert_case(preg_replace('#[^a-z]#ui', '', $field['Type']), MB_CASE_UPPER);
 				$fieldInfo['SIZE'] = filter_var($field['Type'], FILTER_SANITIZE_NUMBER_INT);
@@ -145,6 +147,53 @@
 			return $return;
 		}
 
+		/**
+		 * Cette finction retourne la table et le champs référent pour un champ avec une foreign key
+		 * @param string $table : Le nom de la table qui contient le champ
+		 * @param string $field : Le nom du champ
+		 * @return mixed : False en cas d'erreur, un tableau avec 'table' en index pour la table et 'field' pour le champ
+		 */
+		public function getReferenceForForeign ($table, $field)
+		{
+			if (!$this->fieldExist($field, $table))
+			{
+				return false;
+			}
+
+			$query = 'SELECT referenced_table_name as table_name, referenced_column_name as field_name FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE WHERE table_name = :table AND column_name = :field AND referenced_table_name IS NOT NULL';
+			
+			$params = array(
+				'table' => $table,
+				'field' => $field,
+			);
+
+			return $this->runQuery($query, $params, self::FETCH);
+		}
+
+		/**
+		 * Cette fonction retourne les valeurs possibles pour un champ muni d'une clef étrangère
+		 * @param string $table : Le nom de la table qui contient le champ
+		 * @param string $field : Le nom du champ
+		 * @return mixed : Retourne les valeurs possible sous forme d'un tableau
+		 */
+		public function getPossibleValuesForForeign ($table, $field)
+		{
+			if (!$this->fieldExist($field, $table))
+			{
+				return false;
+			}
+
+			//On recupère le champs référence pour la foreign key
+			if (!$reference = $this->getReferenceForForeign($table, $field))
+			{
+				return false;
+			}
+
+			//On recupère les valeurs possible de la table
+			$query = 'SELECT DISTINCT ' . $reference['field_name'] . ' as possible_value FROM ' . $reference['table_name'];
+			return $this->runQuery($query);
+		}
+
 		/**
 		 * Cette fonction permet de compter le nombre de ligne d'une table
 		 * @param string $table : Le nom de la table à compter
@@ -246,8 +295,8 @@
 		/**
 		 * Cette fonction permet de récupérer des lignes en fonction de restrictions
 		 * @param string $table : Le nom de la table dans laquelle on veux recuperer la ligne
-		 * @param array $restrictions : Les restrictions que l'on veux appliquer
-		 * @param string $order_by : Le nom de la colonne par laquelle on veux trier les résultats. Si non fourni, tri automatique
+		 * @param array $restrictions : Les restrictions sous la forme "label" => "valeur". Un operateur '<, >, <=, >=, !' peux précder le label pour modifier l'opérateur par défaut (=)
+		 * @param mixed $order_by : Le nom de la colonne par laquelle on veux trier les résultats ou son numero. Si non fourni, tri automatique
 		 * @param string $desc : L'ordre de tri (asc ou desc). Si non défini, ordre par défaut (ASC)
 		 * @param string $limit : Le nombre maximum de résultats à récupérer (par défaut pas le limite)
 		 * @param string $offset : Le nombre de résultats à ignorer (par défaut pas de résultats ignorés)
@@ -266,27 +315,66 @@
 			//On gère les restrictions
 			$wheres = array();
 			$params = array();
-
+			$i = 0;
 			foreach ($restrictions as $label => $value)
 			{
+				//Pour chaque restriction, on essaye de detecter un "! ou < ou > ou <= ou >="
+				$first_char = mb_substr($label, 0, 1);
+				$second_char = mb_substr($label, 1, 1);
+
+				switch(true)
+				{
+					//Important de traiter <= & >= avant < & >
+					case ('<=' == $first_char . $second_char) :
+						$trueLabel = mb_substr($label, 2);
+						$operator = '<=';
+						break;
+
+					case ('>=' == $first_char . $second_char) :
+						$trueLabel = mb_substr($label, 2);
+						$operator = '>=';
+						break;
+
+					case ('!' == $first_char) :
+						$trueLabel = mb_substr($label, 1);
+						$operator = '!=';
+						break;
+
+					case ('<' == $first_char) :
+						$trueLabel = mb_substr($label, 1);
+						$operator = '<';
+						break;
+
+					case ('>' == $first_char) :
+						$trueLabel = mb_substr($label, 1);
+						$operator = '>';
+						break;
+
+					default :
+						$trueLabel = $label;
+						$operator = '=';
+				}
+
 				//Si le champs pour la restriction n'existe pas on retourne false
-				if (!array_key_exists($label, $fields))
+				if (!array_key_exists($trueLabel, $fields))
 				{
 					return false;
 				}
-				
+
 				//On ajoute la restriction au WHERE
-				$params['where_' . $label] = $value;
-				$wheres[] = $label . ' = :where_' . $label . ' ';
+				$params['where_' . $trueLabel . $i] = $value;
+				$wheres[] = $trueLabel . ' ' . $operator . ' :where_' . $trueLabel . $i . ' ';
+				$i++;
 			}
 
-			$query = "SELECT " . $this->getColumnsForTable($table) . " FROM " . $table . " WHERE 1 " . (count($wheres) ? 'AND ' : '') . implode('AND ', $wheres);
+			$query = "SELECT * FROM " . $table . " WHERE 1 " . (count($wheres) ? 'AND ' : '') . implode('AND ', $wheres);
 
 			if ($order_by)
 			{
-				if ($this->fieldExist($order_by, $table))
+				//Si le champs existe ou si c'est un numeric inférieur ou egale au nombre  de champs dispo
+				if (array_key_exists($order_by, $fields) || (is_numeric($order_by) && $order_by <= count($fields)))
 				{
-					$query .= ' ORDER BY '. $order_by;
+					$query .= ' ORDER BY ' . $order_by;
 					if ($desc) 
 					{
 						$query .= ' DESC';
@@ -307,9 +395,11 @@
 
 			if ($limit !== false)
 			{
+				$limit = (int)$limit;
 				$req->bindParam(':limit', $limit, PDO::PARAM_INT);
 				if ($offset !== false)
 				{
+					$offset = (int)$offset;
 					$req->bindParam(':offset', $offset, PDO::PARAM_INT);
 				}
 			}
@@ -322,6 +412,7 @@
 
 			$req->setFetchMode(PDO::FETCH_ASSOC);
 			$req->execute();
+
 			return $req->fetchAll();
 		}
 
@@ -330,7 +421,7 @@
 		 * @param string $table : Le nom de la table dans laquelle on veux insérer des données
 		 * @param string $primary : La clef primaire qui sert à identifier la ligne a modifier
 		 * @param array $datas : Les données à insérer au format "champ" => "valeur"
-		 * @param array $restrictions : Un tableau des restrictions à appliquer sous forme "champ" => "valeur". Par défaut un tableau vide
+		 * @param array $restrictions : Les restrictions pour la mise à jour sous la forme "label" => "valeur". Un operateur '<, >, <=, >=, !' peux précder le label pour modifier l'opérateur par défaut (=)
 		 * @return mixed : False en cas d'erreur, sinon le nombre de lignes modifiées
 		 */
 		public function updateTableWhere ($table, $datas, $restrictions = array())
@@ -365,17 +456,56 @@
 
 			//On gère les restrictions
 			$wheres = array();
+			$i = 0;
 			foreach ($restrictions as $label => $value)
 			{
+				//Pour chaque restriction, on essaye de detecter un "! ou < ou > ou <= ou >="
+				$first_char = mb_substr($label, 0, 1);
+				$second_char = mb_substr($label, 1, 1);
+
+				switch(true)
+				{
+					//Important de traiter <= & >= avant < & >
+					case ('<=' == $first_char . $second_char) :
+						$trueLabel = mb_substr($label, 2);
+						$operator = '<=';
+						break;
+
+					case ('>=' == $first_char . $second_char) :
+						$trueLabel = mb_substr($label, 2);
+						$operator = '>=';
+						break;
+
+					case ('!' == $first_char) :
+						$trueLabel = mb_substr($label, 1);
+						$operator = '!=';
+						break;
+
+					case ('<' == $first_char) :
+						$trueLabel = mb_substr($label, 1);
+						$operator = '<';
+						break;
+
+					case ('>' == $first_char) :
+						$trueLabel = mb_substr($label, 1);
+						$operator = '>';
+						break;
+
+					default :
+						$trueLabel = $label;
+						$operator = '=';
+				}
+
 				//Si le champs pour la restriction n'existe pas on retourne false
-				if (!array_key_exists($label, $fields))
+				if (!array_key_exists($trueLabel, $fields))
 				{
 					return false;
 				}
-				
+
 				//On ajoute la restriction au WHERE
-				$params['where_' . $label] = $value;
-				$wheres[] = $label . ' = :where_' . $label . ' ';
+				$params['where_' . $trueLabel . $i] = $value;
+				$wheres[] = $trueLabel . ' ' . $operator . ' :where_' . $trueLabel . $i . ' ';
+				$i++;
 			}
 
 			//On fabrique la requete
@@ -388,7 +518,7 @@
 		/**
 		 * Cette fonction permet de supprimer des lignes d'une table en fonctions de restrictions
 		 * @param string $table : Le nom de la table dans laquelle on veux supprimer la ligne
-		 * @param array $restrictions : Les restrictions pour la suppression sous la forme "label" => "valeur"
+		 * @param array $restrictions : Les restrictions pour la suppression sous la forme "label" => "valeur". Un operateur '<, >, <=, >=, !' peux précder le label pour modifier l'opérateur par défaut (=)
 		 * @return mixed : False en cas d'erreur, sinon le nombre de lignes supprimées
 		 */
 		public function deleteFromTableWhere($table, $restrictions = array())
@@ -403,22 +533,59 @@
 			//On gère les restrictions
 			$wheres = array();
 			$params = array();
-
+			$i = 0;
 			foreach ($restrictions as $label => $value)
 			{
+				//Pour chaque restriction, on essaye de detecter un "! ou < ou > ou <= ou >="
+				$first_char = mb_substr($label, 0, 1);
+				$second_char = mb_substr($label, 1, 1);
+
+				switch(true)
+				{
+					//Important de traiter <= & >= avant < & >
+					case ('<=' == $first_char . $second_char) :
+						$trueLabel = mb_substr($label, 2);
+						$operator = '<=';
+						break;
+
+					case ('>=' == $first_char . $second_char) :
+						$trueLabel = mb_substr($label, 2);
+						$operator = '>=';
+						break;
+
+					case ('!' == $first_char) :
+						$trueLabel = mb_substr($label, 1);
+						$operator = '!=';
+						break;
+
+					case ('<' == $first_char) :
+						$trueLabel = mb_substr($label, 1);
+						$operator = '<';
+						break;
+
+					case ('>' == $first_char) :
+						$trueLabel = mb_substr($label, 1);
+						$operator = '>';
+						break;
+
+					default :
+						$trueLabel = $label;
+						$operator = '=';
+				}
+
 				//Si le champs pour la restriction n'existe pas on retourne false
-				if (!array_key_exists($label, $fields))
+				if (!array_key_exists($trueLabel, $fields))
 				{
 					return false;
 				}
-				
+
 				//On ajoute la restriction au WHERE
-				$params['where_' . $label] = $value;
-				$wheres[] = $label . ' = :where_' . $label . ' ';
+				$params['where_' . $trueLabel . $i] = $value;
+				$wheres[] = $trueLabel . ' ' . $operator . ' :where_' . $trueLabel . $i . ' ';
+				$i++;
 			}
 
 			$query = "DELETE FROM " . $table . " WHERE 1 AND " . implode('AND ', $wheres);
-
 			return $this->runQuery($query, $params, self::ROWCOUNT);
 		}