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);
	}
	public function action()
	{
		set_time_limit(0);
		
		$user = $this->hasAuthorative();
		$xml = $this->getXML();
		$xml = $this->makeMenu($xml);
		$controllersXML = $this->_generic->getControllersXML();
		$controller = $controllersXML->getTag("//controllers/controller[@isBo='true']/@name");
		$tokenSecret = sha1(substr($this->_generic->getSiteConfig("privateKey"), 0, 3).substr($this->_generic->getSiteConfig("privateKey"), strlen($this->_generic->getSiteConfig("privateKey"))-3));
		$xmlBo = new SLS_XMLToolbox(file_get_contents($this->_generic->getPathConfig("configSls")."/bo.xml"));
		$xmlFk = new SLS_XMLToolbox(file_get_contents($this->_generic->getPathConfig("configSls")."/fks.xml"));
		$xmlType = new SLS_XMLToolbox(file_get_contents($this->_generic->getPathConfig("configSls")."/types.xml"));
		
		// Check if bo controller already exist
		if (empty($controller))
		{
			$xml->startTag("errors");
			$xml->addFullTag("error","Back-office controller could not be found. Please follow the following link to create it.",true);
			$xml->endTag("errors");
		}
		// Else, let's choose the models
		else 
		{
			// If reload
			if ($this->_http->getParam("reload") == "true")
			{
				$modelsWanted = $this->_http->getParam("models");
				$langs = $this->_lang->getSiteLangs();
				
				if (is_array($modelsWanted))
				{
					// Foreach models choose, generate files
					foreach($modelsWanted as $model)
					{
						$db = Sls_String::substrBeforeFirstDelimiter($model,".");
						$table = Sls_String::substrAfterFirstDelimiter($model,".");
						
						# Node into bo.xml
						$boPath = "//sls_configs/entry[@type='table' and @name='".strtolower($db."_".$table)."']";
						$boExists = $xmlBo->getTag($boPath."/@type");
						if (empty($boExists))
							$boPath = "//sls_configs/entry/entry[@type='table' and @name='".strtolower($db."_".$table)."']";
						$boExists = $xmlBo->getTag($boPath);
						if (empty($boExists))
						{
							$this->_generic->useModel(SLS_String::tableToClass($table),ucfirst(strtolower($db)),"user");
							$class = ucfirst(strtolower($db))."_".SLS_String::tableToClass($table);
							$object = new $class();
							$xmlNode = '    <entry type="table" name="'.strtolower($db."_".$table).'" multilanguage="'.(($object->isMultilanguage()) ? "true" : "false").'">'."\n";
							$xmlNode .= '        <columns>'."\n";
							foreach($object->getColumns() as $column)
							{
								// Avoid pk
								$isPk = ($column == $object->getPrimaryKey() || $column == 'pk_lang') ? true : false;
								// Avoid fk
								$fkExist = $xmlFk->getTag("//sls_configs/entry[@tableFk='".strtolower($db."_".$table)."' and @columnFk='".$column."']/@tablePk");
								$isFk = (!empty($fkExist)) ? true : false;
								// Avoid quick edit on type file
								$fileExist = $xmlType->getTag("//sls_configs/entry[@table='".strtolower($db."_".$table)."' and @column='".$column."' and (@type='file_all' or @type='file_img')]/@column");
								$isFile = (!empty($fileExist)) ? true : false;
								
								$xmlNode .= '            <column table="'.strtolower($db."_".$table).'" name="'.$column.'" multilanguage="'.(($object->isMultilanguage() && !$isPk) ? "true" : "false").'" displayFilter="true" displayList="'.(($isFk) ? "false" : "true").'" allowEdit="'.(($isPk || $isFk || $isFile) ? "false" : "true").'" allowHtml="false" />'."\n";
							}
							$xmlNode .= '        </columns>'."\n";
							$xmlNode .= '    </entry>'."\n";
							$xmlBo->appendXMLNode("//sls_configs",$xmlNode);
							$xmlBo->saveXML($this->_generic->getPathConfig("configSls")."/bo.xml",$xmlBo->getXML());
							$xmlBo->refresh();
						}
						# /Node into bo.xml
						
						# BoActions
						$boActions = array("List","Add","Modify","Clone","Delete");
						foreach($boActions as $boAction)
						{
							// Generate Action
							$action = ucfirst(strtolower($boAction)).ucfirst(strtolower($db))."_".SLS_String::tableToClass($table);
							$params = array(0 => array("key" 	=> "reload",
									  				   "value" 	=> "true"),
									  		1 => array("key" 	=> "Controller",
									  				   "value" 	=> $controller),
										 	2 => array("key" 	=> "actionName",
									  				   "value" 	=> $action),
									  		3 => array("key"	=> "token",
									  				   "value"	=> $tokenSecret),
									  		4 => array("key"	=> "template",
									  				   "value" 	=> "bo"),
									  		5 => array("key"	=> "dynamic",
									  				   "value" 	=> "on"),
									  		6 => array("key"	=> "indexes",
									  				   "value"	=> "noindex,nofollow")
										    );
							foreach($langs as $lang)
							{
								$tmpParam = array("key" 	=> $lang."-action",
												  "value" 	=> $action."_".$lang);
								$tmpTitle = array("key" 	=> $lang."-title",
												  "value" 	=> $action);
								array_push($params,$tmpParam);
								array_push($params,$tmpTitle);
							}
							file_get_contents($this->_generic->getFullPath("SLS_Bo",
																		  "AddAction",
																		  $params,
																		  true));
							
							// Erase Action
							if (file_exists($this->_generic->getPathConfig("installDeployement")."Controllers/Actions/{{USER_BO}}/".$boAction."{{DB}}_{{TABLE}}.controller.php"))
							{
								$source = str_replace(array("{{USER_BO}}","{{DB}}","{{TABLE}}"),array($controller,ucfirst(strtolower($db)),SLS_String::tableToClass($table)),file_get_contents($this->_generic->getPathConfig("installDeployement")."Controllers/Actions/{{USER_BO}}/".$boAction."{{DB}}_{{TABLE}}.controller.php"));
								file_put_contents($this->_generic->getPathConfig("actionsControllers").$controller."/".$action.".controller.php",$source);
							}
							
							// Erase View Head
							if (file_exists($this->_generic->getPathConfig("installDeployement")."Views/Headers/{{USER_BO}}/".$boAction."{{DB}}_{{TABLE}}.xsl"))
							{
								$source = str_replace(array("{{USER_BO}}","{{DB}}","{{TABLE}}"),array($controller,ucfirst(strtolower($db)),SLS_String::tableToClass($table)),file_get_contents($this->_generic->getPathConfig("installDeployement")."Views/Headers/{{USER_BO}}/".$boAction."{{DB}}_{{TABLE}}.xsl"));
								file_put_contents($this->_generic->getPathConfig("viewsHeaders").$controller."/".$action.".xsl",$source);
							}
							
							// Erase View Body
							if (file_exists($this->_generic->getPathConfig("installDeployement")."Views/Body/{{USER_BO}}/".$boAction."{{DB}}_{{TABLE}}.xsl"))
							{
								$source = str_replace(array("{{USER_BO}}","{{DB}}","{{TABLE}}"),array($controller,ucfirst(strtolower($db)),SLS_String::tableToClass($table)),file_get_contents($this->_generic->getPathConfig("installDeployement")."Views/Body/{{USER_BO}}/".$boAction."{{DB}}_{{TABLE}}.xsl"));
								file_put_contents($this->_generic->getPathConfig("viewsBody").$controller."/".$action.".xsl",$source);
							}
						}
						# /BoActions
					}
					
					$this->_generic->forward("SLS_Bo","ManageRights");
				}
			}
			
			$sql = SLS_Sql::getInstance();
			$models = $this->getAllModels();			
			$dbs = $sql->getDbs();
			sort($dbs,SORT_REGULAR);
						
			$xml->startTag("dbs");
			foreach($dbs as $db)
			{
				sort($models,SORT_REGULAR);
				
				$xml->startTag("db");
				$xml->addFullTag("name",$db,true);
				$xml->startTag("models");
				for($i=0 ; $i<$count=count($models) ; $i++)
				{
					if (SLS_String::startsWith($models[$i],$db))
					{
						$xml->startTag("model");
						$xml->addFullTag("name",SLS_String::substrAfterFirstDelimiter($models[$i],"."),true);
						$xml->addFullTag("existed",($this->boActionExist(SLS_String::substrAfterFirstDelimiter($models[$i],"."),SLS_String::substrBeforeFirstDelimiter($models[$i],"."))) ? "true" : "false",true);
						$xml->endTag("model");
					}
				}
				$xml->endTag("models");
				$xml->endTag("db");
			}
			$xml->endTag("dbs");
		}
		
		$xml->addFullTag("url_add_controller",$this->_generic->getFullPath("SLS_Bo","AddController",array(0=>array("key"=>"isBo","value"=>"true"))),true);
		$this->saveXML($xml);
	}