/**
	 * Get the source code of a model from his table
	 * 
	 * @param string $tableName the table name 
	 * @param string $db the alias of the database on which the model is located
	 * @return string $contentM the source code
	 */
	protected function getModelSource($tableName,$db)
	{
		$arrayConvertTypes = array(
			'varchar'	=>	'string',
			'tinyint'	=>	'int',
			'text'		=>	'string',
			'date'		=>	'string',
			'smallint'	=>	'int',
			'mediumint'	=>	'int',
			'int'		=>	'int',
			'bigint'	=>	'int',
			'float'		=>	'float | int',
			'double'	=>	'float | int',
			'decimal'	=>	'float',
			'datetime'	=>	'string',
			'timestamp'	=>	'int',
			'time'		=>	'string | int',
			'year'		=>	'int',
			'char'		=>	'string',
			'tinyblob'	=>	'string',
			'tinytext'	=>	'string',
			'blob'		=>	'string',
			'mediumblob'=>	'string',
			'mediumtext'=>	'string',
			'longblob'	=>	'string',
			'longtext'	=>	'string',
			'enum'		=>	'string',
			'set'		=>	'string',
			'bool'		=>	'int',
			'binary'	=>	'string',
			'varbinary'	=>	'string'
		);
		$sql 		= SLS_Sql::getInstance();
		$className 	= ucfirst($db)."_".SLS_String::tableToClass($tableName);
		$file 		= ucfirst($db).".".SLS_String::tableToClass($tableName);
		
		// Create empty source
		$contentM = "";
		$primaryKey = "";
		$multiLanguage = 'false';
		$sql->changeDb($db);
		$columns = $sql->showColumns($tableName);
		$fileName = ucfirst($db).".".SLS_String::tableToClass($tableName).".model.php";
		$primaryKey = "";
		$pathsHandle = file_get_contents($this->_generic->getPathConfig("configSls")."/types.xml");
		$xmlType = new SLS_XMLToolbox($pathsHandle);
		$pathsHandle = file_get_contents($this->_generic->getPathConfig("configSls")."/fks.xml");
		$xmlFk = new SLS_XMLToolbox($pathsHandle);
		$pathsHandle = file_get_contents($this->_generic->getPathConfig("configSls")."/filters.xml");
		$xmlFilter = new SLS_XMLToolbox($pathsHandle);
		$fkMethods = array();
		$uniquesMultilang = array();
				
		// Create Model		
		$contentM = '<?php'."\n".
				   '/**'."\n".
				   ' * Object '.$className.''."\n".
				   ' * @author SillySmart'."\n".
				   ' * @copyright SillySmart'."\n".
				   ' * @package Mvc.Models.Objects'."\n".
				   ' * @see Sls.Models.Core.SLS_FrontModel'."\n".
				   ' * @since 1.0'."\n".
				   ' */'."\n".
				   'class '.$className.' extends SLS_FrontModel'."\n".
				   '{'."\n".
					   t(1).'/**'."\n".
				       t(1).' * Class variables'."\n".
					   t(1).' */'."\n";				   
		$pkFound = false;
		for($i=0 ; $i<$count=count($columns) ; $i++)
		{
			if (!$pkFound && $columns[$i]->Key == "PRI")
			{
				$primaryKey = SLS_String::removePhpChars($columns[$i]->Field);
				$pkFound = true;
			}
			if ($columns[$i]->Field == "pk_lang" && $columns[$i]->Key == "PRI")
				$multiLanguage = 'true';
			$contentM .= t(1).'protected $__'.SLS_String::removePhpChars($columns[$i]->Field).';'."\n";
		}
		
		$contentM .= t(1).'protected $_table = "'.$tableName.'";'."\n".
					 t(1).'protected $_db = "'.$db.'";'."\n".
					 t(1).'protected $_primaryKey = "'.$primaryKey.'";'."\n";
		
		// Show create table
		if ($multiLanguage == 'true')
		{
			$create = array_shift($sql->select("SHOW CREATE TABLE `".$tableName."`"));
			$instructions = array_map("trim",explode("\n",$create->{Create." ".Table}));						
			foreach($instructions as $instruction)
			{
				if (SLS_String::startsWith($instruction,"UNIQUE KEY"))
				{
					$uniqueColumns = explode(",",SLS_String::substrBeforeFirstDelimiter(SLS_String::substrAfterFirstDelimiter($instruction,"("),")"));
					if (count($uniqueColumns) == 2 && in_array("`pk_lang`",$uniqueColumns))
					{
						$uniqueColumn = array_shift($uniqueColumns);
						if ($uniqueColumn == "`pk_lang`")
							$uniqueColumn = array_shift($uniqueColumns);
							
						$uniquesMultilang[] = str_replace("`","",$uniqueColumn);
					}
				}
			}
		}
					 
		// Get FKs to create access reference functions
		$fks = $xmlFk->getTagsAttributes("//sls_configs/entry[@tableFk='".$db."_".$tableName."']",array("columnFk","tablePk"));
		$fkFunctions = "";
		$fkCursor = "";
		for($i=0 ; $i<$count=count($fks) ; $i++)
		{
			$tablePk = $fks[$i]["attributes"][1]["value"];
			$functionName = SLS_String::fullTrim(ucwords(SLS_String::stringToUrl(SLS_String::tableToClass(SLS_String::substrAfterFirstDelimiter($tablePk,"_"))," ",false)),"");
			$functionName{0} = strtolower($functionName{0});
			$functionNameModified = $functionName;
			while(in_array($functionNameModified,$fkMethods))							
				$functionNameModified = $functionName."_".($fkCursor = (empty($fkCursor)) ? 2 : $fkCursor+1);			
			$fkMethods[] = $functionNameModified;
			$fkFunctions .= "'".$functionNameModified."'";
			if ($i < ($count - 1))
				$fkFunctions .= ", ";
		}
				
		$contentM .= t(1).'protected $_fks = array('.$fkFunctions.');'."\n";
		
		$contentM .= t(1).'public $_typeErrors = array();'."\n\n".
					 t(1).'/**'."\n".
				     t(1).' * Constructor '.$className.''."\n".
				     t(1).' * @author SillySmart'."\n".
				     t(1).' * @copyright SillySmart'."\n".
				     t(1).' * @param bool $mutlilanguage true if multilanguage content, else false'."\n".
				     t(1).' */'."\n".
					 t(1).'public function __construct($multilanguage='.$multiLanguage.')'."\n".
					 t(1).'{'."\n".
						 t(2).'parent::__construct($multilanguage);'."\n".
						 t(2).'$this->buildDefaultValues();'."\n".
					 t(1).'}'."\n\n";
		
		$contentM .= t(1).'/**'."\n".
				     t(1).' * Build default values for specific columns'."\n".
				     t(1).' * @author SillySmart'."\n".
				     t(1).' * @copyright SillySmart'."\n".
				     t(1).' */'."\n".
					 t(1).'public function buildDefaultValues()'."\n".
					 t(1).'{'."\n";
		
		for($i=0 ; $i<$count=count($columns) ; $i++)
		{
			$columnType = (strpos($columns[$i]->Type, "(")) ? SLS_String::substrBeforeFirstDelimiter(strtolower($columns[$i]->Type), "(") : $columns[$i]->Type;
			$functionName = "set".SLS_String::fullTrim(ucwords(SLS_String::stringToUrl(str_replace("_"," ",SLS_String::removePhpChars($columns[$i]->Field))," ",false)),"");
			
			if ($columns[$i]->Null == "NO")
			{			
				// Dates
				if ($columnType == "date" || $columnType == "datetime" || $columnType == "timestamp" || $columnType == "year" || $columnType == "time")
				{
					switch ($columnType)
					{
						case "date":
							$contentM .= t(2).'$this->__'.$columns[$i]->Field.' = date("Y-m-d");'."\n";
							break;
						case "time":
							$contentM .= t(2).'$this->__'.$columns[$i]->Field.' = date("H:i:s");'."\n";
							break;
						case "datetime":
							$contentM .= t(2).'$this->__'.$columns[$i]->Field.' = date("Y-m-d H:i:s");'."\n";
							break;
						case "timestamp":
							$contentM .= t(2).'$this->__'.$columns[$i]->Field.' = date("Y-m-d H:i:s");'."\n";
							break;
						case "year":
							$contentM .= t(2).'$this->__'.$columns[$i]->Field.' = date("Y");'."\n";
							break;
					}
				}
				
				// Uniqid
				$result = $xmlType->getTags("//sls_configs/entry[@table='".$db."_".$tableName."' and @column='".SLS_String::removePhpChars($columns[$i]->Field)."' and @type='uniqid']");
				if (!empty($result))
				{
					$contentM .= t(2).'$this->__'.$columns[$i]->Field.' = substr(md5(time().substr(sha1(microtime()),0,rand(12,25))),mt_rand(1,20),40);'."\n";
				}
				
				// IP Address
				$result = array_shift($xmlType->getTags("//sls_configs/entry[@table='".$db."_".$tableName."' and @column='".SLS_String::removePhpChars($columns[$i]->Field)."' and (@type='ip_both' or @type='ip_v4' or @type='ip_v6')]/@type"));
				if (!empty($result))
				{
					$contentM .= t(2).'$this->__'.$columns[$i]->Field.' = $_SERVER["REMOTE_ADDR"];'."\n";
				}
			}
		}
		$contentM .= t(1).'}'."\n\n";
		
		for($i=0 ; $i<$count=count($columns) ; $i++)
		{
			$isPassword = false;
			
			if ($columns[$i]->Key != "PRI")
			{
				$column = SLS_String::removePhpChars($columns[$i]->Field);
				$columnType = (strpos($columns[$i]->Type, "(")) ? SLS_String::substrBeforeFirstDelimiter(strtolower($columns[$i]->Type), "(") : $columns[$i]->Type;
				$functionName = "set".SLS_String::fullTrim(ucwords(SLS_String::stringToUrl(str_replace("_"," ",$column)," ",false)),"");
				
				$contentM .= t(1).'/**'."\n".
						     t(1).' * Set the value of '.$column.''."\n".
						     t(1).' * Errors can be catched with the public variable $this->_typeErrors[\''.$column.'\']'."\n".
						     t(1).' * @author SillySmart'."\n".
						     t(1).' * @copyright SillySmart'."\n".
						     t(1).' * @param '.$arrayConvertTypes[$columnType].' $value'."\n".
						     t(1).' * @return bool true if updated, false if not'."\n".
						     t(1).' */'."\n".
							 t(1).'public function '.$functionName.'($value';
				
				if ($columns[$i]->Default !== null)
					$contentM .= '="'.SLS_String::addSlashesToString($columns[$i]->Default,false).'"';
					
				$contentM .= ')'."\n";
				$contentM .= t(1).'{'."\n";
				
				// Nullable case
				if ($columns[$i]->Null == "YES")
				{
					$contentM .= t(2).'if (empty($value))'."\n".
								 t(2).'{'."\n".
									 t(3).'$this->__set(\''.$column.'\', $value);'."\n".
									 t(3).'$this->flushError(\''.$column.'\');'."\n".
									 t(3).'return true;'."\n".
								 t(2).'}'."\n\n";
				}
				
				// Recover Fk
				$res = $xmlFk->getTagsByAttributes("//sls_configs/entry",array("tableFk","columnFk"),array($db."_".$tableName,$column));
				if (!empty($res))
				{
					$tableTm = substr($res,(strpos($res,'tablePk="')+9),(strpos($res,'"/>')-(strpos($res,'tablePk="')+9)));							
					$tablePk = SLS_String::substrAfterFirstDelimiter($tableTm,"_");
					$dbPk 	 = SLS_String::substrBeforeFirstDelimiter($tableTm,"_");
					$contentM .= 	 t(2).'$this->_generic->useModel("'.SLS_String::tableToClass($tablePk).'","'.$dbPk.'","user");'."\n".
									 t(2).'$object = new '.ucfirst($dbPk).'_'.SLS_String::tableToClass($tablePk).'();'."\n".
									 t(2).'if ($object->getModel($value) === false)'."\n".										 
									 t(2).'{'."\n".
										 t(3).'$this->_typeErrors[\''.SLS_String::addSlashes($column, 'QUOTES').'\'] = "E_KEY";'."\n".
										 t(3).'return false;'."\n".
									 t(2).'}'."\n".										 
									 t(2).'$this->__set(\''.$column.'\', $value);'."\n".
									 t(2).'$this->flushError(\''.$column.'\');'."\n".
									 t(2).'return true;'."\n".
								 t(1).'}'."\n\n";
				}
				
				// If not a fk
				else
				{
					// Check filters
					$results = $xmlFilter->getTags("//sls_configs/entry[@table='".$db."_".$tableName."' and @column='".$column."']/@filter");														
					for($j=0 ; $j<$countJ=count($results) ; $j++)
					{									
						switch($results[$j])
						{
							case "hash":
								$isPassword = true;
								$contentM .= t(2).'if (empty($value))'."\n".
										 	 	t(3).'$value = $this->__'.$column.';'."\n";
								break;
							default:
								$contentM .= t(2).'$value = SLS_String::filter($value,"'.$results[$j].'");'."\n";
								break;
						}
					}
					if (count($results) > 0)
						$contentM .= "\n";
						
					$result = $xmlType->getTags("//sls_configs/entry[@table='".$db."_".$tableName."' and @column='".$column."']");
					
					// Force specific type numeric
					if ($this->containsRecursive($columnType,array("int","float","double","decimal","real")))
					{
						$typeExists =($xmlType->getTag("//sls_configs/entry[@table='".$db."_".$tableName."' and @column='".$column."']/@type"));
						if (empty($typeExists))
						{
							file_get_contents($this->_generic->getFullPath("SLS_Bo",
																		  "AddType",
																		  array("name" => strtolower($db."_".$tableName),
																		  		"column" => $column,
																		  		"reload" => "true",
																		  		"type" => "num",
																		  		"num" => (SLS_String::contains($columns[$i]->Type,"unsigned")) ? "gte" : "all",
																		  		"token"	 => sha1(substr($this->_generic->getSiteConfig("privateKey"), 0, 3).substr($this->_generic->getSiteConfig("privateKey"), strlen($this->_generic->getSiteConfig("privateKey"))-3))),
																		  true));
							$xmlType->refresh();
						}
					}
					if (!empty($result))
					{
						$type = "";
						$array = array('color','uniqid','email','ip_both','ip_v4','ip_v6','url','file_all','file_img','position','num_all','num_gt','num_gte','num_lt','num_lte','complexity');
						for($j=0 ; $j<count($array) ; $j++)
						{
							$result = $xmlType->getTags("//sls_configs/entry[@table='".$db."_".$tableName."' and @column='".$column."' and @type='".$array[$j]."']");
							if (!empty($result))
							{
								$type = $array[$j];
								switch($type)
								{
									case "position":
										$contentM .= t(2).'if ($value == "" || $value == null || !is_int(intval($value)) || intval($value) < 0)'."\n".
											         t(2).'{'."\n".
												         t(3).'$this->_typeErrors[\''.SLS_String::addSlashes($column, 'QUOTES').'\'] = "E_TYPE";'."\n".
												         t(3).'return false;'."\n".
											         t(2).'}'."\n\n".
													 t(2).'$qbd = new SLS_QueryBuilder();'."\n".
													 t(2).'$old_'.$column.' = $this->__'.$column.';'."\n".
													 t(2).'if (empty($old_'.$column.'))'."\n".
											         t(2).'{'."\n".
											         	t(3).'$qbd->update()'."\n".
													         t(4).'->from("'.$tableName.'")'."\n".
													         t(4).'->set("`'.$column.'` = `'.$column.'` + 1")'."\n".
													         t(4).'->where($qbd->expr()->gte("'.$column.'",$value))'."\n".
															 t(4).'->groupBy("`'.$primaryKey.'`")'."\n".
													         t(4).'->execute();'."\n".
											         t(2).'}'."\n".
											         t(2).'else'."\n".
											         t(2).'{'."\n".
												    	 t(3).'if ($old_'.$column.' != $value)'."\n".
												    	 t(3).'{'."\n".
											    		 	t(4).'$qbd->update()'."\n".
													    		 t(5).'->from("'.$tableName.'")'."\n".
													    		 t(5).'->set("`'.$column.'` = `'.$column.'` ".(($old_'.$column.' < $value) ? "-" : "+")." 1")'."\n".
													    		 t(5).'->where($qbd->expr()->{($old_'.$column.' < $value) ? "gt" : "gte"}("'.$column.'",($old_'.$column.' < $value) ? $old_'.$column.' : $value))'."\n".
													    		 t(5).'->whereAnd($qbd->expr()->{($old_'.$column.' < $value) ? "lte" : "lt"}("'.$column.'",($old_'.$column.' < $value) ? $value : $old_'.$column.'))'."\n".
																 t(5).'->groupBy("`'.$primaryKey.'`")'."\n".
													    		 t(5).'->execute();'."\n".
														 	t(4).'$qbd->update()'."\n".
													    		 t(5).'->from("'.$tableName.'")'."\n".
													    		 t(5).'->set($qbd->expr()->eq("'.$column.'",$value))'."\n".
													    		 t(5).'->where($qbd->expr()->eq("'.$primaryKey.'",$this->__'.$primaryKey.'))'."\n".
																 t(5).'->groupBy("`'.$primaryKey.'`")'."\n".
													    		 t(5).'->execute();'."\n".
											    		 t(3).'}'."\n".													 
											    	 t(2).'}'."\n\n";
										break;
									case "color":
										$contentM .= t(2).'if (!ctype_xdigit($value))'."\n";
										$contentM .= t(2).'{'."\n".
														 t(3).'$this->_typeErrors[\''.SLS_String::addSlashes($column, 'QUOTES').'\'] = "E_TYPE";'."\n".
														 t(3).'return false;'."\n".
													 t(2).'}'."\n\n";
										break;
									case "uniqid":										
										$contentM .= t(2).'if (empty($value))'."\n".
													 	t(3).'$value = substr(md5(time().substr(sha1(microtime()),0,rand(12,25))),mt_rand(1,20),40);'."\n\n";
										break;
									case "email":
										$contentM .= t(2).'if (!SLS_String::validateEmail($value))'."\n";
										$contentM .= t(2).'{'."\n".
												 		 t(3).'$this->_typeErrors[\''.SLS_String::addSlashes($column, 'QUOTES').'\'] = "E_TYPE";'."\n".
												 		 t(3).'return false;'."\n".
											 		 t(2).'}'."\n\n";
										break;
									case "url":
										$contentM .= t(2).'if (!SLS_String::isValidUrl($value))'."\n";
										$contentM .= t(2).'{'."\n".
												 		 t(3).'$this->_typeErrors[\''.SLS_String::addSlashes($column, 'QUOTES').'\'] = "E_TYPE";'."\n".
												 		 t(3).'return false;'."\n".
											 		 t(2).'}'."\n\n";
										break;
									case (in_array($type,array("ip_both","ip_v4","ip_v6"))):
										$type = SLS_String::substrAfterLastDelimiter($type,"_");
										
										$contentM .= t(2).'if (empty($value))'."\n".
													 	t(3).'$value = $_SERVER["REMOTE_ADDR"];'."\n\n";
										$contentM .= t(2).'if (!SLS_String::isIp($value,"'.$type.'"))'."\n";
										$contentM .= t(2).'{'."\n".
														 t(3).'$this->_typeErrors[\''.SLS_String::addSlashes($column, 'QUOTES').'\'] = "E_TYPE";'."\n".
														 t(3).'return false;'."\n".
													 t(2).'}'."\n\n";												
										break;
									case (in_array($type,array("num_all","num_gt","num_gte","num_lt","num_lte"))):
										$type = SLS_String::substrAfterLastDelimiter($type,"_");										
										switch($type)
										{
											case "gt": 	$operator = "<="; 	break;
											case "gte": $operator = "<"; 	break;
											case "lt": 	$operator = ">="; 	break;
											case "lte": $operator = ">"; 	break;
										}
										if ($type != 'all')
										{
											$contentM .= t(2).'if ($value '.$operator.' 0)'."\n";
											$contentM .= t(2).'{'."\n".
													 		 t(3).'$this->_typeErrors[\''.SLS_String::addSlashes($column, 'QUOTES').'\'] = "E_TYPE";'."\n".
													 		 t(3).'return false;'."\n".
												 		 t(2).'}'."\n\n";
										}
										break;
									case "complexity":
										$rules = $xmlType->getTag("//sls_configs/entry[@table='".$db."_".$tableName."' and @column='".$column."']/@rules");										
										$rules = explode("|",$rules);
										$complexityMin = false; 
										foreach($rules as $rule)
										{
											if (SLS_String::startsWith($rule,"min"))
											{
												$complexityMin = SLS_String::substrAfterFirstDelimiter($rule,"min");
												unset($rules[array_shift(array_keys($rules,$rule))]);
											}
											else
												$rules[array_shift(array_keys($rules,$rule))] = '"'.$rule.'"';
										}
										$rules = implode(",",$rules);
										$contentM .= t(2).'$complexity = array('.$rules.');'."\n".
													 t(2).'if ((in_array("lc",$complexity) && preg_match(\'`[[:lower:]]`\', $value) === 0) || (in_array("uc",$complexity) && preg_match(\'`[[:upper:]]`\', $value) === 0) || (in_array("digit",$complexity) && preg_match(\'`[[:digit:]]`\', $value) === 0) || (in_array("wild",$complexity) && preg_match(\'`[^a-zA-Z0-9]`\', $value) === 0))'."\n".
													 t(2).'{'."\n".
														t(3).'$this->_typeErrors[\''.SLS_String::addSlashes($column, 'QUOTES').'\'] = "E_COMPLEXITY";'."\n".
														t(3).'return false;'."\n".
													 t(2).'}'."\n\n";
										if (is_numeric($complexityMin))
											$contentM .= t(2).'if (strlen(utf8_decode($value)) < '.$complexityMin.')'."\n".
														 t(2).'{'."\n".
															t(3).'$this->_typeErrors[\''.SLS_String::addSlashes($column, 'QUOTES').'\'] = "E_LENGTH";'."\n".
															t(3).'return false;'."\n".
														 t(2).'}'."\n\n";
										break;
									case "file_all":
										$contentM .= t(2).'if (!empty($this->__'.$column.') && $this->__'.$column.' != "'.$columns[$i]->Default.'" && $this->__'.$column.' != $value && SLS_String::startsWith((is_array($value)) ? ((array_key_exists("data",$value)) ? $value["data"]["tmp_name"] : $value["tmp_name"]) : $value, $this->getTable()."/"))'."\n".
													 t(2).'{'."\n".
														 t(3).'$this->deleteFiles(array("'.$column.'"));'."\n".
														 t(3).'$this->__'.$column.' = "__Uploads/__Deprecated/".$this->__'.$column.';'."\n".
														 t(3).'$this->save();'."\n".
													 t(2).'}'."\n\n".
													 t(2).'if (is_array($value))'."\n".
													 t(2).'{'."\n".
													 	t(3).'if (array_key_exists("size",$value) && is_array($value["size"]))'."\n".
															t(4).'$size = $value["size"];'."\n".
														t(3).'if (array_key_exists("data",$value))'."\n".
															t(4).'$value = $value["data"];'."\n";
										if ($columns[$i]->Null == "YES") 
											$contentM .= t(3).'if ($value["error"] == 4)'."\n".
														 t(3).'{'."\n".
															 t(4).'$this->__set(\''.$column.'\',(empty($this->__'.$column.')) ? "" : $this->__'.$column.');'."\n".
															 t(4).'$this->flushError(\''.$column.'\');'."\n".
															 t(4).'return true;'."\n".
														 t(3).'}'."\n";
										$contentM .= t(3).'if ($value["error"] == 1 || $value["error"] == 2)'."\n".
													 t(3).'{'."\n".
														 t(4).'$this->_typeErrors[\''.SLS_String::addSlashes($column, 'QUOTES').'\'] = "E_SIZE";'."\n".
														 t(4).'return false;'."\n".
													 t(3).'}'."\n".
													 t(3).'else'."\n".
													 t(3).'{'."\n".
														 t(4).'try {'."\n".
															 t(5).'if (!file_exists($this->_generic->getPathConfig("files").$this->_table))'."\n".
														 	 	t(6).'mkdir($this->_generic->getPathConfig("files").$this->_table,0755);'."\n\n".
															 t(5).'$token = substr(md5(time().substr(sha1(microtime()),0,rand(5,12))),mt_rand(1,20),10);'."\n".
															 t(5).'$fileName = SLS_String::sanitize(SLS_String::substrBeforeLastDelimiter($value["name"],"."),"_")."_".$token.".".SLS_String::substrAfterLastDelimiter($value["name"],".");'."\n".
															 t(5).'rename($value["tmp_name"],$this->_generic->getPathConfig("files").$this->_table."/".$fileName);'."\n".
															 t(5).'$value = $this->_table."/".$fileName;'."\n".
														 t(4).'}'."\n".
														 t(4).'catch (Exception $e) {'."\n".
															 t(5).'$this->_typeErrors[\''.SLS_String::addSlashes($column, 'QUOTES').'\'] = "E_WRITE";'."\n".
															 t(5).'return false;'."\n".
														 t(4).'}'."\n".
													 t(3).'}'."\n".
													 t(2).'}'."\n\n";
										break;
									case "file_img":
										$contentM .= t(2).'if (!empty($this->__'.$column.') && $this->__'.$column.' != "'.$columns[$i]->Default.'" && $this->__'.$column.' != $value && SLS_String::startsWith((is_array($value)) ? ((array_key_exists("data",$value)) ? $value["data"]["tmp_name"] : $value["tmp_name"]) : $value, $this->getTable()."/"))'."\n".
													 t(2).'{'."\n".
														 t(3).'$this->deleteFiles(array("'.$column.'"));'."\n".
														 t(3).'$this->__'.$column.' = "__Uploads/__Deprecated/".$this->__'.$column.';'."\n".
														 t(3).'$this->save();'."\n".
													 t(2).'}'."\n\n".
													 t(2).'if (is_array($value))'."\n".
													 t(2).'{'."\n".
													 	t(3).'if (array_key_exists("size",$value) && is_array($value["size"]))'."\n".
															t(4).'$size = $value["size"];'."\n".
														t(3).'if (array_key_exists("data",$value))'."\n".
															t(4).'$value = $value["data"];'."\n";
										if ($columns[$i]->Null == "YES")
											$contentM .= t(3).'if ($value["error"] == 4)'."\n".
														 t(3).'{'."\n".
															 t(4).'$this->__set(\''.$column.'\',(empty($this->__'.$column.')) ? "" : $this->__'.$column.');'."\n".
															 t(4).'$this->flushError(\''.$column.'\');'."\n".
															 t(4).'return true;'."\n".
														 t(3).'}'."\n";
										$contentM .= t(3).'if ($value["error"] == 1 || $value["error"] == 2)'."\n".
													 t(3).'{'."\n".
														 t(4).'$this->_typeErrors[\''.SLS_String::addSlashes($column, 'QUOTES').'\'] = "E_SIZE";'."\n".
														 t(4).'return false;'."\n".
													 t(3).'}'."\n".
													 t(3).'else'."\n".
													 t(3).'{'."\n".
														 t(4).'try {'."\n".
															 t(5).'if (!file_exists($this->_generic->getPathConfig("files").$this->_table))'."\n".
												 			 	t(6).'mkdir($this->_generic->getPathConfig("files").$this->_table,0755);'."\n\n".
															 t(5).'$tmpName = $value["tmp_name"];'."\n".
															 t(5).'if (!SLS_String::startsWith($tmpName,$this->_generic->getPathConfig("files")) || !SLS_String::contains($tmpName,"."))'."\n".
															 t(5).'{'."\n".
																 t(6).'if (!file_exists($this->_generic->getPathConfig("files")."__Uploads"))'."\n".
																 	t(7).'@mkdir($this->_generic->getPathConfig("files")."__Uploads");'."\n".
																 t(6).'if (!file_exists($this->_generic->getPathConfig("files")."__Uploads/__Deprecated"))'."\n".
																 	t(7).'@mkdir($this->_generic->getPathConfig("files")."__Uploads/__Deprecated");'."\n".
																 t(6).'$newName = $this->_generic->getPathConfig("files")."__Uploads/__Deprecated/".SLS_String::substrAfterLastDelimiter($tmpName,"/").((!SLS_String::contains($tmpName,".")) ? ".".SLS_String::substrAfterLastDelimiter($value["name"],".") : "");'."\n".
																 t(6).'rename($tmpName,$newName);'."\n".
																 t(6).'$tmpName = $newName;'."\n".
															 t(5).'}'."\n".
															 t(5).'$token = substr(md5(time().substr(sha1(microtime()),0,rand(5,12))),mt_rand(1,20),10);'."\n".
															 t(5).'$fileName = SLS_String::sanitize(SLS_String::substrBeforeLastDelimiter($value["name"],"."),"_")."_".$token;'."\n".
														 	 t(5).'$extension = pathinfo($tmpName, PATHINFO_EXTENSION);'."\n\n".
															 t(5).'// Check img'."\n".
															 t(5).'$img = new SLS_Image($tmpName);'."\n".
															 t(5).'if ($img->getParam("existed"))'."\n".
															 t(5).'{'."\n".
																 t(6).'// Default crop'."\n".
																 t(6).'if (empty($size))'."\n".
																 	t(7).'$size = array("x" => "0", "y" => "0", "w" => $img->getParam("width"), "h" => $img->getParam("height"));'."\n\n".
																 t(6).'// Crop image'."\n".
																 t(6).'$img->crop($size["x"],$size["y"],$size["w"],$size["h"]);'."\n".											 
																 t(6).'// Check thumbs'."\n".
																 t(6).'$xmlType = new SLS_XMLToolbox(file_get_contents($this->_generic->getPathConfig("configSls")."/types.xml"));'."\n".
																 t(6).'$result = array_shift($xmlType->getTagsAttribute("//sls_configs/entry[@table=\'".$this->getDatabase()."_".$this->getTable()."\' and @column=\''.$column.'\' and @type=\'file_img\']","thumbs"));'."\n".
																 t(6).'$thumbs = unserialize(str_replace("||#||",\'"\',$result["attribute"]));'."\n".
																 t(6).'if (!empty($thumbs))'."\n".
																 t(6).'{'."\n".
																	 t(7).'for($i=0 ; $i<$count=count($thumbs) ; $i++)'."\n".
																	 t(7).'{'."\n".
															 			t(8).'$img->transform($thumbs[$i]["width"],$thumbs[$i]["height"],$this->_generic->getPathConfig("files").$this->_table."/".$fileName.$thumbs[$i]["suffix"].".".$extension,$extension);'."\n".
																	 t(7).'}'."\n".
															 	 t(6).'}'."\n\n".
															 	 t(6).'// Move original'."\n".
															 	 t(6).'rename($tmpName,$this->_generic->getPathConfig("files").$this->_table."/".$fileName.".".$extension);'."\n".
															 t(5).'}'."\n".
															 t(5).'else'."\n".
															 t(5).'{'."\n".
																 t(6).'$this->_typeErrors[\''.SLS_String::addSlashes($column, 'QUOTES').'\'] = "E_TYPE";'."\n".
																 t(6).'return false;'."\n".
															 t(5).'}'."\n".
															 t(5).'$value = $this->_table."/".$fileName.".".$extension;'."\n".
														 t(4).'}'."\n".
														 t(4).'catch (Exception $e) {'."\n".
															 t(5).'$this->_typeErrors[\''.SLS_String::addSlashes($column, 'QUOTES').'\'] = "E_WRITE";'."\n".
															 t(5).'return false;'."\n".
														 t(4).'}'."\n".
													 t(3).'}'."\n".
												t(2).'}'."\n\n";
										break;
								}
								break;
							}
						}
					}
					 			 
					// Not Nullable
					if ($columns[$i]->Null == "NO")
					{
						$contentM .= t(2).'if ($value === "")'."\n".
									 t(2).'{'."\n".
										 t(3).'$this->_typeErrors[\''.SLS_String::addSlashes($column, 'QUOTES').'\'] = "E_EMPTY";'."\n".
										 t(3).'return false;'."\n".
									 t(2).'}'."\n\n";
					}
					
					if ($isPassword)
					{
						$result = array_shift($xmlFilter->getTagsAttribute("//sls_configs/entry[@table='".$db."_".$tableName."' and @column='".$column."']","hash"));
						$hash = (empty($result["attribute"])) ? "sha1" : $result["attribute"];
						$contentM .= t(2).'if ($value != $this->__'.$column.')'."\n".
									 	t(3).'$value = SLS_String::filter($value,"hash","'.$hash.'");'."\n\n";
					}
					
					// Not Nullable
					if ($columns[$i]->Null == "NO")
					{
						$contentM .= t(2).'if (is_null($value))'."\n".
									 t(2).'{'."\n".
										 t(3).'$this->_typeErrors[\''.SLS_String::addSlashes($column, 'QUOTES').'\'] = "E_NULL";'."\n".
										 t(3).'return false;'."\n".
									 t(2).'}'."\n\n";
					}
					
					// Check change
					$contentM .= t(2).'if ($this->__'.$column.' == $value)'."\n".
								 t(2).'{'."\n".
									t(3).'$this->flushError(\''.$column.'\');'."\n".								 
					 			 	t(3).'return true;'."\n".
					 			 t(2).'}'."\n\n";
					
					// Unique
					if ($columns[$i]->Key == "UNI" || in_array($column,$uniquesMultilang))
					{
						$contentM .= t(2).'if (!$this->isUnique(\''.SLS_String::addSlashes($column, 'QUOTES').'\',$value))'."\n".
									 t(2).'{'."\n".
										 t(3).'$this->_typeErrors[\''.SLS_String::addSlashes($column, 'QUOTES').'\'] = "E_UNIQUE";'."\n".
										 t(3).'return false;'."\n".
									 t(2).'}'."\n\n";
					}
					
					// Float types
					if (SLS_String::startsWith($columnType,"float") || SLS_String::startsWith($columnType,"double") || SLS_String::startsWith($columnType,"decimal"))
					{
						$length = SLS_String::substrBeforeFirstDelimiter(SLS_String::substrAfterFirstDelimiter(SLS_String::substrBeforeLastDelimiter($columns[$i]->Type, ')'), '('), ",");
						if (empty($length))
							$length = "25";
						$contentM .= t(2).'$decimal = (strpos($value, \',\')) ? str_replace(\',\', \'.\', $value) : (!strpos($value, \'.\')) ? $value.\'.0\' : $value;'."\n".									
									 t(2).'if (!is_numeric($decimal))'."\n".
									 t(2).'{'."\n".
										 t(3).'$this->_typeErrors[\''.SLS_String::addSlashes($column, 'QUOTES').'\'] = "E_TYPE";'."\n".
										 t(3).'return false;'."\n".
									 t(2).'}'."\n\n".
									 t(2).'if ((strlen($decimal)-1) > '.$length.')'."\n".
									 t(2).'{'."\n".
										 t(3).'$this->_typeErrors[\''.SLS_String::addSlashes($column, 'QUOTES').'\'] = "E_LENGTH";'."\n".
										 t(3).'return false;'."\n".
									 t(2).'}'."\n\n";
					}
					
					// Enum types
					else if ($columnType == "enum" || $columnType == "set")
					{						
						$values = SLS_String::substrAfterFirstDelimiter(SLS_String::substrBeforeLastDelimiter($columns[$i]->Type, "')"), "('");
						
						if ($columnType == "enum")
						{
							$contentM .= t(2).'$values = explode("\',\'", "'.str_replace("''", "\'", $values).'");'."\n".									
										 t(2).'if (!in_array($value, $values))'."\n".
										 t(2).'{'."\n".
											 t(3).'$this->_typeErrors[\''.SLS_String::addSlashes($column, 'QUOTES').'\'] = "E_CONTENT";'."\n".
											 t(3).'return false;'."\n".
										 t(2).'}'."\n\n";
						}
						else
						{
							$contentM .= t(2).'$values = explode("\',\'", "'.str_replace("''", "\'", $values).'");'."\n".
										 t(2).'$valueE = explode(",",$value);'."\n".
								         t(2).'foreach($valueE as $set)'."\n".
								         t(2).'{'."\n".
											 t(3).'if (!in_array($set, $values))'."\n".
											 t(3).'{'."\n".
												 t(4).'$this->_typeErrors[\''.SLS_String::addSlashes($column, 'QUOTES').'\'] = "E_CONTENT";'."\n".
												 t(4).'return false;'."\n".
											 t(3).'}'."\n".
										 t(2).'}'."\n\n";
						}									 
					}
					else 
					{						
						if (strpos($columns[$i]->Type, "("))
						{
							$length = SLS_String::substrAfterFirstDelimiter(SLS_String::substrBeforeLastDelimiter($columns[$i]->Type, ")"), "(");
							$contentM .= t(2).'if (strlen(utf8_decode($value)) > '.$length.')'."\n".
										 t(2).'{'."\n".
											 t(3).'$this->_typeErrors[\''.SLS_String::addSlashes($column, 'QUOTES').'\'] = "E_LENGTH";'."\n".
											 t(3).'return false;'."\n".
										 t(2).'}'."\n\n";
						}
						if(SLS_String::endsWith($columnType, "int"))
						{
							$contentM .= t(2).'if (!is_numeric($value))'."\n".
										 t(2).'{'."\n".
											 t(3).'$this->_typeErrors[\''.SLS_String::addSlashes($column, 'QUOTES').'\'] = "E_TYPE";'."\n".
											 t(3).'return false;'."\n".
										 t(2).'}'."\n\n";
						}
						else if ($columnType == "date" || $columnType == "datetime" || $columnType == "timestamp")
						{
							switch ($columnType)
							{
								case "date":
									$contentM .= t(2).'if (!SLS_Date::isDate($value))'."\n";
									break;
								case "datetime":
									$contentM .= t(2).'if (!SLS_Date::isDateTime($value))'."\n";
									break;
								case "timestamp":
									$contentM .= t(2).'if (!SLS_Date::isDateTime($value))'."\n";
									break;
							}
							$contentM .= t(2).'{'."\n".
											 t(3).'$this->_typeErrors[\''.SLS_String::addSlashes($column, 'QUOTES').'\'] = "E_TYPE";'."\n".
											 t(3).'return false;'."\n".
										 t(2).'}'."\n\n";
						}
						else if ($columnType == "time" || $columnType == "year")
						{
							switch ($columnType)
							{
								case "time":
									$contentM .= t(2).'if (strpos(\':\', $value) && substr_count($value, \':\') != 2)'."\n".
	 											 t(2).'{'."\n".
		 											 t(3).'$this->_typeErrors[\''.SLS_String::addSlashes($column, 'QUOTES').'\'] = "E_TYPE";'."\n".
													 t(3).'return false;'."\n".
												 t(2).'}'."\n\n".
												 t(2).'$check = explode(\':\', $value);'."\n".	
												 t(2).'if (count($check) == 1 && !is_numeric($check[0]))'."\n".	
												 t(2).'{'."\n".
		 											 t(3).'$this->_typeErrors[\''.SLS_String::addSlashes($column, 'QUOTES').'\'] = "E_TYPE";'."\n".
													 t(3).'return false;'."\n".
												 t(2).'}'."\n".
												 t(2).'else if ((count($check) > 1) && (!is_numeric($check[0]) || (!is_numeric($check[1]) || strlen($check[1]) > 2) || (!is_numeric($check[2]) || strlen($check[2]) > 2)))'."\n".	
												 t(2).'{'."\n".
		 											 t(3).'$this->_typeErrors[\''.SLS_String::addSlashes($column, 'QUOTES').'\'] = "E_TYPE";'."\n".
													 t(3).'return false;'."\n".
												 t(2).'}'."\n\n";
									break;
								case "year":
									$contentM .= t(2).'if (!mktime(0, 0, 0, 0, 0, $value))'."\n".
	 											 t(2).'{'."\n".
		 											 t(3).'$this->_typeErrors[\''.SLS_String::addSlashes($column, 'QUOTES').'\'] = "E_TYPE";'."\n".
													 t(3).'return false;'."\n".
												 t(2).'}'."\n\n";
									break;
							}
						}
						
					}
					$contentM .= 		t(2).'$this->__set(\''.$column.'\', $value);'."\n".
										t(2).'$this->flushError(\''.$column.'\');'."\n".
										t(2).'return true;'."\n".
									t(1).'}'."\n\n";
				}
			}						
		}
		
		// Get FKs to create access reference functions
		$fks = $xmlFk->getTagsAttributes("//sls_configs/entry[@tableFk='".$db."_".$tableName."']",array("columnFk","tablePk"));
		$fkMethods = array();
		$fkCursor = "";
		for($i=0 ; $i<$count=count($fks) ; $i++)
		{
			$columnFk = $fks[$i]["attributes"][0]["value"];
			$tablePk = $fks[$i]["attributes"][1]["value"];
			
			$functionName = SLS_String::fullTrim(ucwords(SLS_String::stringToUrl(SLS_String::tableToClass(SLS_String::substrAfterFirstDelimiter($tablePk,"_"))," ",false)),"");
			$functionName{0} = strtolower($functionName{0});
			$functionNameModified = $functionName;
			while(in_array($functionNameModified,$fkMethods))							
				$functionNameModified = $functionName."_".($fkCursor = (empty($fkCursor)) ? 2 : $fkCursor+1);			
			$fkMethods[] = $functionNameModified;
			$contentM .= t(1).'/**'."\n".
					     t(1).' * Get the instance of '.SLS_String::substrAfterFirstDelimiter($tablePk,"_").'\'s Model described by '.$columnFk.''."\n".  
					     t(1).' * @author SillySmart'."\n".
					     t(1).' * @copyright SillySmart'."\n".
					     t(1).' * @return '.SLS_String::tableToClass($tablePk).' $object the instance of '.SLS_String::substrAfterFirstDelimiter($tablePk,"_").'\'s Model'."\n".
					     t(1).' */'."\n".
						 t(1).'public function '.$functionNameModified.'()'."\n".
						 t(1).'{'."\n".
							 t(2).'$this->_generic->useModel("'.SLS_String::tableToClass(SLS_String::substrAfterFirstDelimiter($tablePk,"_")).'","'.SLS_String::substrBeforeFirstDelimiter($tablePk,"_").'","user");'."\n".
						     t(2).'$object = new '.ucfirst(SLS_String::substrBeforeFirstDelimiter($tablePk,"_")).'_'.SLS_String::tableToClass(SLS_String::substrAfterFirstDelimiter($tablePk,"_")).'();'."\n".
						     t(2).'$object->getModel($this->__'.$columnFk.');'."\n".
						     t(2).'return $object;'."\n".
						 t(1).'}';
			$contentM .= ($i == ($count-1)) ? "\n" : "\n\n";
		}
		
		$contentM .= '}'."\n".
					 '?>';
		
		return $contentM;
	}
	public function action()
	{
		set_time_limit(0);
		
		$user = $this->hasAuthorative();
		$errors = array();
		$sql = SLS_Sql::getInstance();
		$xml = $this->getXML();
		$xml = $this->makeMenu($xml);

		// Get all models
		$models = array();
		$handle = opendir($this->_generic->getPathConfig("models"));
		while (false !== ($file = readdir($handle)))
		{
			if (!is_dir($this->_generic->getPathConfig("models")."/".$file) && substr($file, 0, 1) != ".") 
			{
				$modelExploded = explode(".",$file);
				array_push($models,strtolower($modelExploded[0]).".".$modelExploded[1]);
			}
		}
		
		// If reload
		if ($this->_http->getParam("reload")=="true")
		{
			// Get the tables dude wants to generate
			$tablesG = ($this->_http->getParam("tables")=="") ? array() : $this->_http->getParam("tables");
			
			// Foreach tables, generate model
			foreach($tablesG as $tableG)
			{
				$db = Sls_String::substrBeforeFirstDelimiter($tableG,".");
				$table = Sls_String::substrAfterFirstDelimiter($tableG,".");
				
				// Change db if it's required
				if ($sql->getCurrentDb() != $db)
					$sql->changeDb($db);
				
				// If table exists
				if ($sql->tableExists($table))
				{					
					$columns = $sql->showColumns($table);
					$tableName = $table;
					$currentTable = array("table"=>$db.".".$tableName,"errors"=>array());
					$fieldsOk = true;
					$className = ucfirst($db)."_".SLS_String::tableToClass($tableName);
					$fileName  = ucfirst($db).".".SLS_String::tableToClass($table).".model.php";					
															
					for($i=0 ; $i<$count=count($columns) ; $i++)
					{						
						// Check forbidden chars
						if (SLS_String::removePhpChars($columns[$i]->Field) != $columns[$i]->Field)
						{
							$error = array("column"=>$columns[$i]->Field,"column_clean"=>SLS_String::removePhpChars($columns[$i]->Field));
							array_push($currentTable["errors"],$error);
							$fieldsOk = false;
						}
					}
					
					// If all ok with special chars for the current model
					if ($fieldsOk)
					{
						// Check real fks
						$create = array_shift($sql->select("SHOW CREATE TABLE `".$table."`"));						
						$queries = array_map("trim",explode("\n",$create->{Create." ".Table}));						
						foreach($queries as $query)
						{
							if (SLS_String::startsWith($query,"CONSTRAINT"))
							{
								$tableFk = strtolower($db."_".$tableName);
								$columnFk = SLS_String::substrBeforeFirstDelimiter(SLS_String::substrAfterFirstDelimiter($query,"FOREIGN KEY (`"),"`)");
								$tablePk = $db."_".SLS_String::tableToClass(SLS_String::substrBeforeFirstDelimiter(SLS_String::substrAfterFirstDelimiter($query,"REFERENCES `"),"`"));
								$onDelete = strtolower(SLS_String::stringToUrl(trim(SLS_String::substrBeforeFirstDelimiter(SLS_String::substrAfterFirstDelimiter($query,"ON DELETE"),"ON UPDATE")),"_"));
								$labelPk = "";
								$columns = $sql->showColumns(SLS_String::substrBeforeFirstDelimiter(SLS_String::substrAfterFirstDelimiter($query,"REFERENCES `"),"`"));
								for($i=0 ; $i<$count=count($columns) ; $i++)
								{
									if ($columns[$i]->Key != "PRI" && $columns[$i]->Field != "pk_lang" && SLS_String::contains($columns[$i]->Type,"char"))
									{
										$labelPk = $columns[$i]->Field;
										break;
									}
								}
								if (empty($labelPk))
									$labelPk = SLS_String::substrBeforeFirstDelimiter(SLS_String::substrAfterFirstDelimiter($query,"REFERENCES `".SLS_String::substrBeforeFirstDelimiter(SLS_String::substrAfterFirstDelimiter($query,"REFERENCES `"),"`")."` (`"),"`)");
								$xmlNode = '<entry tableFk="'.$tableFk.'" columnFk="'.$columnFk.'" multilanguage="false" ondelete="'.$onDelete.'" labelPk="'.$labelPk.'" tablePk="'.$tablePk.'" />';
								
								$xmlFk = new SLS_XMLToolbox(file_get_contents($this->_generic->getPathConfig("configSls")."/fks.xml"));
								$result = $xmlFk->getTags("//sls_configs/entry[@tableFk='".$tableFk."' and @columnFk='".$columnFk."' and @tablePk='".$tablePk."']");
								if (!empty($result))
								{
									$xmlTmp = $xmlFk->deleteTags("//sls_configs/entry[@tableFk='".$tableFk."' and @columnFk='".$columnFk."' and @tablePk='".$tablePk."']");
									$xmlFk->saveXML($this->_generic->getPathConfig("configSls")."/fks.xml",$xmlTmp);
									$xmlFk = new SLS_XMLToolbox(file_get_contents($this->_generic->getPathConfig("configSls")."/fks.xml"));
								}
								
								$xmlFk->appendXMLNode("//sls_configs",$xmlNode);
								$xmlFk->saveXML($this->_generic->getPathConfig("configSls")."/fks.xml",$xmlFk->getXML());
							}
						}
						
						// Generate Model						
						$contentM = $this->getModelSource($tableName,$db);						
						$status = touch($this->_generic->getPathConfig("models")."/".$fileName);
						if ($status)					
							file_put_contents($this->_generic->getPathConfig("models").$fileName,$contentM);
						
						// Create SQL
						$fileNameS = ucfirst($db).".".SLS_String::tableToClass($table).".sql.php";
						$contentS = '<?php'."\n".
								   '/**'."\n".
								   '* Object '.$className.'Sql'."\n".
								   '* @author SillySmart'."\n".
								   '* @copyright SillySmart'."\n".
								   '* @package Mvc.Models.Objects'."\n".
								   '* @see Sls.Models.Core.SLS_FrontModel'."\n".
								   '* @since 1.0'."\n".
								   '*/'."\n".
								   'class '.$className.'Sql extends SLS_FrontModelSql'."\n".
								   '{'."\n".
								   ''."\n".
								   '}'."\n".
								   '?>';
						if ($status)
							$status2 = touch($this->_generic->getPathConfig("modelsSql")."/".$fileNameS);
						if ($status2)					
							file_put_contents($this->_generic->getPathConfig("modelsSql")."/".$fileNameS,$contentS);					 
					}
					else					
						array_push($errors,$currentTable);					
				}
			}
			// If no errors
			if (empty($errors))
			{
				$controllers = $this->_generic->getTranslatedController("SLS_Bo","Models");
				$this->_generic->redirect($controllers['controller']."/".$controllers['scontroller']);
			}
			else
			{	
				// Get all models
				$models = array();
				$handle = opendir($this->_generic->getPathConfig("models"));
				while (false !== ($file = readdir($handle))) 			
					if (!is_dir($this->_generic->getPathConfig("models")."/".$file) && substr($file, 0, 1) != ".") 
					{
						$modelExploded = explode(".",$file);
						array_push($models,strtolower($modelExploded[0]).".".$modelExploded[1]);
					}
					
				// Form errors
				$xml->startTag("errors");
				for($i=0 ; $i<$count=count($errors) ; $i++)
				{
					$xml->startTag("error");
					$xml->addFullTag("table",SLS_String::substrAfterFirstDelimiter($errors[$i]["table"],"."),true);
					$xml->addFullTag("db",SLS_String::substrBeforeFirstDelimiter($errors[$i]["table"],"."),true);
					$xml->startTag("columns");
					for($j=0 ; $j<$count2=count($errors[$i]["errors"]) ; $j++)
					{
						$xml->startTag("column");
						$xml->addFullTag("old",$errors[$i]["errors"][$j]["column"],true);
						$xml->addFullTag("new",$errors[$i]["errors"][$j]["column_clean"],true);
						$xml->endTag("column");
					}
					$xml->endTag("columns");
					$xml->endTag("error");
				}
				$xml->endTag("errors");				
			}
		}
		
		// Foreach db
		$dbs = $sql->getDbs();
		$allDbs = array();	
		
		foreach($dbs as $db)
		{
			$allDbs[$db] = array();
			
			// Change db
			$sql->changeDb($db);
			
			// Get all tables
			$tables = $sql->showTables();						
			for($i=0 ; $i<$count=count($tables) ; $i++)
			{
				$allDbs[$db][$tables[$i]->Name] = array("name" 	=> $tables[$i]->Name,
														"existed" => (in_array($db.".".SLS_String::tableToClass($tables[$i]->Name),$models)) ? 'true' : 'false');				
			}
		}
		
		asort($allDbs,SORT_REGULAR);
		uksort($allDbs,array($this, 'unshiftDefaultDb'));
		
		$xml->startTag("dbs");
		foreach($allDbs as $key => $db)
		{
			asort($db,SORT_REGULAR);
			
			$xml->startTag("db");
			$xml->addFullTag("name",$key,true);
			$xml->startTag("tables");
			foreach($db as $tableCur)
			{
				if (!SLS_String::startsWith(strtolower($tableCur["name"]),"sls_graph"))
				{
					$xml->startTag("table");				
					$xml->addFullTag("name",$tableCur["name"]);
					$xml->addFullTag("existed",$tableCur["existed"]);
					$xml->endTag("table");
				}
			}
			$xml->endTag("tables");
			$xml->endTag("db");
		}
		$xml->endTag("dbs");
			
		$this->saveXML($xml);
	}