/**
	 * Action Dir Rights
	 *
	 */
	public function action() 
	{
		$this->setInstallationStep(array(0=>"SLS_Init",1=>"Initialization"), array(0=>"DirRights",1=>"Directories"));
		
		// Check files rights
		$pathsToCheck = array(
		"actionsControllers",			"models",		"modelsSql",			"views",				"viewsHeaders",
		"viewsBody",					"viewsGenerics","plugins",				"langs",				"actionLangs",			
		"css",							"scripts",		"js",					"jsStatics",			"jsDyn", 
		"configSecure", 				"configSls",	"genericLangs");
		
		$xmlToolBox = $this->getXML();
		$xmlToolBox->startTag("directories");
		$nextStep = true;
		foreach ($pathsToCheck as $path)
		{	$xmlToolBox->startTag("directory");		
			
			(!is_writable($this->_generic->getPathConfig($path))) ? $xmlToolBox->addFullTag("writable", 0) : $xmlToolBox->addFullTag("writable", 1);
			(!is_readable($this->_generic->getPathConfig($path))) ? $xmlToolBox->addFullTag("readable", 0) : $xmlToolBox->addFullTag("readable", 1);
			(is_dir($this->_generic->getPathConfig($path))) ? $xmlToolBox->addFullTag("path", realpath($this->_generic->getPathConfig($path)), true) : $xmlToolBox->addFullTag("path", SLS_String::substrBeforeLastDelimiter($_SERVER['SCRIPT_FILENAME'],'/').substr($this->_generic->getPathConfig($path), 0, (strlen($this->_generic->getPathConfig($path))-1)), true);
			(!is_writable($this->_generic->getPathConfig($path)) || !is_readable($this->_generic->getPathConfig($path))) ? $nextStep = false : "";
			$xmlToolBox->endTag("directory");		
		}		
		$xmlToolBox->endTag("directories"); 
		if (!$nextStep) 
			$xmlToolBox->addFullTag("next", 0); 
		else
		{
			$xmlToolBox->addFullTag("next", 1);
		}
		$this->_generic->registerLink('authentication', 'SLS_Init', 'Authentication');
		$this->saveXML($xmlToolBox);	
		($nextStep) ? $this->setInstallationStep(array(0=>"SLS_Init",1=>"Initialization"), array(0=>"Authentication",1=>"Authentication")) : false;		
	}
	/**
	 * Get the XML of the static controller
	 *
	 * @access public
	 * @return string $xml the xml
	 * @since 1.0
	 */
	public function getXML()
	{
		if ($this->_onSide == 'user')
		{
			$this->_xmlToolBox->endTag(SLS_String::substrBeforeLastDelimiter(get_class($this), "Controller"));
		}
		return $this->_xmlToolBox->getXML('noHeader');
	}	
	public function action()
	{
		$user = $this->hasAuthorative();
		$xml = $this->getXML();
		$xml = $this->makeMenu($xml);
		
		$xml->startTag("templates");
		$handle = opendir($this->_generic->getPathConfig("viewsTemplates"));
		while($file = readdir($handle))
		{
			if (is_file($this->_generic->getPathConfig("viewsTemplates").$file) && substr($file, 0, 1) != ".")
			{
				$fileName 	= SLS_String::substrBeforeLastDelimiter($file,".");
				$extension 	= SLS_String::substrAfterLastDelimiter($file,".");
				
				if ($extension == "xsl" && $fileName != "__default")
				{
					$xml->startTag("template");
					$xml->addFullTag("name",$fileName,true);					
					$xml->endTag("template");
				}
			}
		}
		closedir($handle);
		$xml->addFullTag("url_add",$this->_generic->getFullPath("SLS_Bo","AddTemplate"),true);
		$xml->addFullTag("url_delete",$this->_generic->getFullPath("SLS_Bo","DeleteTemplate",array(),false),true);
		$xml->endTag("templates");		
		
		$xml->startTag("generics");
		$handle = opendir($this->_generic->getPathConfig("viewsGenerics"));
		while($file = readdir($handle))
		{
			if (is_file($this->_generic->getPathConfig("viewsGenerics").$file) && substr($file, 0, 1) != ".")
			{
				$fileName 	= SLS_String::substrBeforeLastDelimiter($file,".");
				$extension 	= SLS_String::substrAfterLastDelimiter($file,".");
				
				if ($extension == "xsl")
				{
					$xml->startTag("generic");
					$xml->addFullTag("name",$fileName,true);					
					$xml->endTag("generic");
				}
			}
		}
		closedir($handle);
		$xml->addFullTag("url_add",$this->_generic->getFullPath("SLS_Bo","AddGeneric"),true);
		$xml->addFullTag("url_delete",$this->_generic->getFullPath("SLS_Bo","DeleteGeneric",array(),false),true);
		$xml->endTag("generics");		
		
		$this->saveXML($xml);		
	}
	public function action()
	{
		$user 	= $this->hasAuthorative();
		$plugId = $this->_http->getParam('Plugin');
		$field 	= $this->_http->getParam('Field');
		$action = $this->_http->getParam('Action');
		$controllers = $this->_generic->getTranslatedController('SLS_Bo', 'EditPlugin');
		
		if (empty($plugId) || SLS_PluginsManager::isExists($plugId) === false)
			$this->dispatch('SLS_Bo', 'Plugins');
		
		$plugin = new SLS_PluginsManager($plugId);
		$xmlPlug = $plugin->getXML();
		
		if (empty($field) || empty($action))
			$this->redirect($controllers['controller']."/".$controllers['scontroller']."/Plugin/".$plugId.".sls");
		
				
		$xpath = "//".str_replace("|||", "/", str_replace("|$|", "]", str_replace("$|$", "[", $field)));
		
		$clonable = array_shift($xmlPlug->getTags($xpath."/@clonable"));
		if ($clonable != 1)
			$this->redirect($controllers['controller']."/".$controllers['scontroller']."/Plugin/".$plugId.".sls");
		
		$nodeName = SLS_String::substrBeforeLastDelimiter($xpath, "[");
			
		if ($action == "del" && count($xmlPlug->getTags($nodeName)) > 1)
		{
			$xmlPlug->deleteTags($xpath, 1);
		}
		if ($action == "add")
		{
			$node = new SLS_XMLToolbox($xmlPlug->getNode($xpath));
			$parent = SLS_String::substrBeforeLastDelimiter($xpath, "/");
			$xmlPlug->appendXMLNode($xpath, $node->getXml('noHeader'), 1, "after");
			$newIndex = SLS_String::substrBeforeLastDelimiter(SLS_String::substrAfterLastDelimiter($xpath, "["), "]");
			$newIndex++;
			$newNode = SLS_String::substrBeforeLastDelimiter($xpath, "[")."[".$newIndex."]";
			if ($xmlPlug->countChilds($newNode) == 0)
				$xmlPlug->setTag($newNode, "", false);
			else 
				$xmlPlug = $this->removeRecursiveValues($newNode, $xmlPlug);
			

			
			$xmlPlug->setTagAttributes($newNode, array("alias"=>uniqid()));
			
			
		}
		$plugin->saveXML($xmlPlug);		
		$this->redirect($controllers['controller']."/".$controllers['scontroller']."/Plugin/".$plugId.".sls");
	}
	public function action()
	{
		$user 	= $this->hasAuthorative();
		$xml = $this->makeMenu($this->getXML());
		$slsXml = $this->_generic->getCoreXML('sls');
		$errors = array();
		$syncServer = array_shift($slsXml->getTags("slsnetwork"));
		$action = $this->_http->getParam('Action');
		$serverID = $this->_http->getParam("Server");
		$pluginID = $this->_http->getParam("Plugin");
		$this->registerLink("CREATE", "SLS_Bo", "CreatePlugin");
		$controllers = $this->_generic->getTranslatedController('SLS_Bo', 'SearchPlugin');
		
		$serversJSON = @file_get_contents($syncServer);
		if ($serversJSON === false ||empty($serversJSON))
			$errors[] = "You are not connected to internet or synchronisation server is temporaly unavailable";
		else 
		{			
			$servers = json_decode($serversJSON);
			$pluginsServers = $servers->servers->plugins;
			$plugins = array();
			
			$xml->startTag("servers");
			
			foreach ($pluginsServers as $pluginsServer)
			{				
				$serverContent = @file_get_contents($pluginsServer->url);				
				
				$xml->startTag("server", array("name"=>$pluginsServer->name,"id"=>$pluginsServer->id));
					$xml->addFullTag("url", $pluginsServer->url, true, array("status"=>($serverContent === false || empty($serverContent)) ? "0" : "1"));

					if ($serverContent !== false && !empty($serverContent))
					{
						$serverContent = json_decode($serverContent);
						
						
						$xml->startTag("plugins");
						$plugs = $serverContent->plugins;
						foreach ($plugs as $plug)
						{
							
							// If we want to download this Plugin
							if ($action == "Download" && $pluginsServer->id == $serverID && $plug->id == $pluginID)
							{
								$way = $this->_http->getParam('Way');
								$pluginXML = $this->_generic->getPluginXml("plugins");
								if (count($pluginXML->getTags("//plugins/plugin[@id = '".$plug->id."']")) == 0 && count($pluginXML->getTags("//plugins/plugin[@code = '".$plug->code."' and @beta='1']")) == 0)
								{
									if (SLS_Remote::remoteFileExists($plug->file) != 0)
										$errors[] = $plug->name." is unavailable";
									else 
									{
										$filename = $this->_generic->getPathConfig("coreTmpDownload")."Plugins/".SLS_String::substrAfterLastDelimiter($plug->file, "/");
										if (!is_dir($this->_generic->getPathConfig("coreTmpDownload")."Plugins"))
											mkdir($this->_generic->getPathConfig("coreTmpDownload")."Plugins");
										$result = @copy($plug->file, $filename);
										if ($result === false)
											$errors[] = "The download of ".$plug->name." has failed";
										else 
										{
											$tar = new SLS_Tar();
											if ($tar->openTAR($filename) === false)
												$errors[] = "Plugin archive is corrupted";
											else 
											{
												$hasConf = false;
												$isFile = true;
												$pathName = "";
												foreach ($tar->directories as $directory)
												{
													if (SLS_String::startsWith($directory['name'], "Sources/"))
													{
														$dirName = SLS_String::substrAfterFirstDelimiter($directory['name'], "Sources/");
														if (!empty($dirName))
														{
															if (!is_dir($this->_generic->getPathConfig("plugins").$dirName))
																mkdir($this->_generic->getPathConfig("plugins").$dirName);
															if (empty($pathName))
																$pathName = (strpos($dirName, "/") !== false) ? SLS_String::substrBeforeLastDelimiter($dirName, "/") : $dirName;
															
															$isFile = false;
														}
													}
												}
												
												foreach ($tar->files as $file)
												{
													
													$copy = true;
													if (SLS_String::startsWith($file['name'], "Configs/") && SLS_String::endsWith($file['name'], ".xml"))
													{
														$hasConf = true;
														$copy = @file_put_contents($this->_generic->getPathConfig("configPlugins").$plug->id."_".$plug->code.".xml", $file['file']);
													}
													if (SLS_String::startsWith($file['name'], 'Sources/'))
													{
														if ($isFile === true && $pathName == "")
															$pathName = SLS_String::substrAfterFirstDelimiter($file['name'], "Sources/");
														$realPathFile = $this->_generic->getPathConfig("plugins").SLS_String::substrAfterFirstDelimiter($file['name'], "Sources/");
														$copy = @file_put_contents($realPathFile, $file['file']);
													}
													if ($copy === false)
													{
														$errors[] = "The copy of ".$file['name']." has failed";
													}
												}
												
												if (empty($errors))
												{
													$newPlugin = new SLS_XMLToolbox(false);
													$newPlugin->startTag("plugin", array("code"=>$plug->code,"id"=>$plug->id,"version"=>$plug->version,"compability"=>$plug->compability,"customizable"=>($hasConf) ? "1" : "0","file"=>($isFile)?"1":"0","path"=>$pathName));
														$newPlugin->addFullTag("name", $plug->name, true);
														$newPlugin->addFullTag("description", $plug->desc, true);
														$newPlugin->addFullTag("author", $plug->author, true);
														$newPlugin->addFullTag("dependencies", "", false);
													$newPlugin->endTag("plugin");
													$pluginXML->appendXMLNode("//plugins", $newPlugin->getXML('noHeader'));
													file_put_contents($this->_generic->getPathConfig("configPlugins")."plugins.xml", $pluginXML->getXML());
												}
												if (is_file($filename))
													unlink($filename);
											}
										}
									}
								}
								if ($way == "Maj")
								{
									$this->goDirectTo("SLS_Bo", "Plugins");
								}
								
							}//  /If we want to download this Plugin
							
							// We list all Plugins available on this server
							$exist = SLS_PluginsManager::isExists($plug->id);
							if ($exist)
							{
								$plugin = new SLS_PluginsManager($plug->id);
							}
							$xml->startTag("plugin", array("version"=>$plug->version,"code"=>$plug->code,"id"=>$plug->id,"compability"=>((float)$plug->compability<=(float)array_shift($slsXml->getTags("version"))) ? "1" : "0","has"=>($exist)?"1":"0"));
							$xml->addFullTag("name", $plug->name, true);
							$xml->addFullTag("doc", $pluginsServer->domain.$plug->doc, true);
							$xml->addFullTag("dl", $controllers['protocol']."://".$this->_generic->getSiteConfig("domainName")."/".$controllers['controller']."/".$controllers['scontroller']."/Action/Download/Server/".$pluginsServer->id."/Plugin/".$plug->id.".sls");
							$xml->addFullTag("desc", $plug->desc, true);
							$xml->addFullTag("author", $plug->author, true);
							$xml->endTag("plugin");
						}
						$xml->endTag("plugins");
					}
					
				$xml->endTag("server");
			}
			$xml->endTag("servers");
		}
		if (!empty($errors))
		{
			$xml->startTag("errors");
			foreach ($errors as $error)
				$xml->addFullTag("error", $error, true);
			$xml->endTag("errors");
		}		
		$this->saveXML($xml);
	}
	/**
	 * Constructor
	 *
	 * @access public
	 * @since 1.0
	 */
	public function __construct($xml,$db,$table,$forward=true)
	{
		parent::__construct();
		
		$this->_xml = $xml;
		$this->_db_alias = $db;
		$this->_table = $table;
		$this->_forward = $forward;
		
		# Objects
		$className = ucfirst(strtolower($this->_db_alias))."_".SLS_String::tableToClass($this->_table);
		$this->_generic->useModel(SLS_String::tableToClass($this->_table),ucfirst(strtolower($this->_db_alias)),"user");
		$this->_object = new $className();
		$this->_table = $this->_object->getTable();
		$this->_clone = new $className();
		$this->_columns = array();
		$this->_filters = array();
		$this->_types = array();
		# /Objects
				
		# Params
		$ids = $this->_http->getParam("id");
		$ids = (SLS_String::contains($ids,"|")) ? explode("|",$ids) : array($ids);
		# /Params
		
		# Types
		$types = $this->_db->showColumns($this->_table);
		for($i=0 ; $i<$count=count($types) ; $i++)
		{
			$nativeType = "text";
			switch($types[$i]->Type)
			{
				case (false !== $typeMatch = $this->containsRecursive($types[$i]->Type,array("int","float","double","decimal","real"))):
					$nativeType = "number";
					break;
				case (false !== $typeMatch = $this->containsRecursive($types[$i]->Type,array("year","datetime","timestamp","time","date"))):
					$nativeType = "date_".$typeMatch;
					break;
			}
			$this->_types[$types[$i]->Field] = $nativeType;
		}
		# /Types
		
		# Blocking specificities
		$specificities = $this->_xmlType->getTagsAttributes("//sls_configs/entry[@table='".$this->_db_alias."_".$this->_table."' and (@type='position' or @type='uniqid' or @type='email')]",array("column","type"));
		for($i=0 ; $i<$count=count($specificities) ; $i++)
		{	
			$column = $specificities[$i]["attributes"][0]["value"];
			$type = $specificities[$i]["attributes"][1]["value"];
			if (!array_key_exists($column,$this->_columns))
				$this->_columns[$column] = $type;
		}
		$filters = $this->_xmlFilter->getTags("//sls_configs/entry[@table='".$this->_db_alias."_".$this->_table."' and @filter='hash']/@column");
		# Blocking specificities
		
		# Perform clone
		if ($this->_object->isMultilanguage())
		{
			$siteLangs = $this->_lang->getSiteLangs();
			unset($siteLangs[array_search($this->_defaultLang,$siteLangs)]);
			array_unshift($siteLangs,$this->_defaultLang);
			$langs = $siteLangs;
		}
		else
			$langs =  array($this->_defaultLang);
		
		// Recordsets to clone
		$nbClone = 0;
		foreach($ids as $id)
		{
			// Next id
			$cloneId = $this->_object->giveNextId();
			
			// Each lang
			foreach($langs as $lang)
			{
				if ($this->_object->isMultilanguage())
					$this->_clone->setModelLanguage($lang);
					
				// Get recordset
				if ($this->_object->getModel($id) === true)
				{
					// Foreach column
					foreach($this->_object->getParams() as $key => $value)
					{
						if ($key == $this->_object->getPrimaryKey() || $key == "pk_lang")
							continue;
						
						// Setter
						$functionName = "set".SLS_String::fullTrim(ucwords(SLS_String::stringToUrl(str_replace("_"," ",$key)," ",false)),"");
						
						// Specific type ?
						if (array_key_exists($key,$this->_columns) && $this->_columns[$key] != "email")
						{
							// Default lang
							if ($lang == $this->_defaultLang && in_array($this->_columns[$key],array("uniqid","position")))
							{
								// Regenerate uniqid
								if ($this->_columns[$key] == "uniqid")
									$value = substr(md5(time().substr(sha1(microtime()),0,rand(12,25))),mt_rand(1,20),40);
								// Get next position
								else if ($this->_columns[$key] == "position")
								{
									$record = array_shift($this->_db->select("SELECT MAX(`".$key."`) AS max_position FROM `".$this->_table."` "));
									$value = (!empty($record->max_position) && is_numeric($record->max_position) && $record->max_position > 0) ? ($record->max_position+1) : 1;
								}
							}
							// Take the default lang value
							else
								$value = $this->_clone->__get($key);
						}
						
						// Set
						if (in_array($key,$filters))
							$this->_clone->__set($key,$value);
						else
							$this->_clone->$functionName($value);
						
						// Unique error ?
						if ($this->_clone->getError($key) == "E_UNIQUE")
						{	
							if (array_key_exists($key,$this->_columns) && $this->_columns[$key] == "email")
								$value = "clone_".time()."@".((substr_count($this->_generic->getSiteConfig("domainName"),".") > 1) ? SLS_String::substrAfterLastDelimiter(SLS_String::substrBeforeLastDelimiter($this->_generic->getSiteConfig("domainName"),"."),".").".".SLS_String::substrAfterLastDelimiter($this->_generic->getSiteConfig("domainName"),".") : $this->_generic->getSiteConfig("domainName"));
							else
							{
								switch($this->_types[$key])
								{
									case "number":
										$record = array_shift($this->_db->select("SELECT MAX(`".$key."`) AS max_nb FROM `".$this->_table."` "));
										$value = (!empty($record->max_nb) && is_numeric($record->max_nb)) ? ($record->max_nb+1) : 1;
										break;
									case (SLS_String::startsWith($this->_types[$key],"date_")):
										$record = array_shift($this->_db->select("SELECT MAX(`".$key."`) AS max_date FROM `".$this->_table."` "));
										$value = (!empty($record->max_date)) ? ($record->max_date) : "";
										$dateType = SLS_String::substrAfterFirstDelimiter($this->_types[$key],"date_");
										switch($dateType)
										{
											case (in_array($dateType,array("year","timestamp"))):
												$value = $value + 1;
												break;
											case "date":
												$value = SLS_Date::timestampToDate(strtotime("+ 1 second",SLS_Date::dateToTimestamp($value)));
												break;
											case "datetime":
												$value = SLS_Date::timestampToDateTime(strtotime("+ 1 second",SLS_Date::dateTimeToTimestamp($value)));
												break;
											case "time":
												$value = sls_string::substrAfterFirstDelimiter(SLS_Date::timestampToDateTime(strtotime("+ 1 second",SLS_Date::dateTimeToTimestamp(date("Y-m-d")." ".$value)))," ");
												break;
										}
										break;
									default:
										$value = substr(md5(time().substr(sha1(microtime()),0,rand(12,5))),mt_rand(1,5),10);
										break;
								}
							}
							
							$this->_clone->$functionName($value);
						}
					}
					
					$errors = $this->_clone->getErrors();
					
					if (empty($errors))
					{
						$this->_clone->create($cloneId);
						$nbClone += 1;
					}
				}
			}
			$this->_clone->clear();
		}
		if ($this->_object->isMultilanguage() && is_numeric($nbClone) && $nbClone > 0)
			$nbClone = floor($nbClone / count($langs));
		# Perform clone
		
		# Notif
		if (!empty($nbClone) && $nbClone !== false && is_numeric($nbClone))
			$this->pushNotif("success",($nbClone==1) ? $GLOBALS[$GLOBALS['PROJECT_NAME']]['JS']['SLS_BO_GENERIC_SUBMIT_SUCCESS_CLONE'] : sprintf($GLOBALS[$GLOBALS['PROJECT_NAME']]['JS']['SLS_BO_GENERIC_SUBMIT_SUCCESS_CLONES'],$nbClone));
		else
			$this->pushNotif("error",$GLOBALS[$GLOBALS['PROJECT_NAME']]['JS']['SLS_BO_GENERIC_SUBMIT_ERROR_CLONE']);
		# /Notif
			
		if ($this->_async)
		{
			if ($nbClone !== false && is_numeric($nbClone) && $nbClone > 0)
			{
				$this->_render["status"] = "OK";
				$this->_render["result"]["message"] = ($nbClone==1) ? $GLOBALS[$GLOBALS['PROJECT_NAME']]['JS']['SLS_BO_GENERIC_SUBMIT_SUCCESS_CLONE'] : sprintf($GLOBALS[$GLOBALS['PROJECT_NAME']]['JS']['SLS_BO_GENERIC_SUBMIT_SUCCESS_CLONES'],$nbClone);
				$rememberList = (is_array($this->_session->getParam("SLS_BO_LIST"))) ? $this->_session->getParam("SLS_BO_LIST") : array();
				if (array_key_exists($this->_db_alias."_".$this->_table,$rememberList) && !empty($rememberList[$this->_db_alias."_".$this->_table]))
					$this->_render["forward"] = $this->_generic->getSiteConfig("protocol")."://".$this->_generic->getSiteConfig("domainName")."/".$rememberList[$this->_db_alias."_".$this->_table];
				else
					$this->_render["forward"] = $this->_generic->getFullPath($this->_boController,"List".ucfirst(strtolower($this->_db_alias))."_".SLS_String::tableToClass($this->_table));
			}
			else
				$this->_render["result"]["message"] = $GLOBALS[$GLOBALS['PROJECT_NAME']]['JS']['SLS_BO_ASYNC_ERROR'];
			echo json_encode($this->_render);
			die();
		}
		else
		{	
			# Forward
			if ($this->_forward)
			{
				$rememberList = (is_array($this->_session->getParam("SLS_BO_LIST"))) ? $this->_session->getParam("SLS_BO_LIST") : array();
				if (array_key_exists($this->_db_alias."_".$this->_table,$rememberList) && !empty($rememberList[$this->_db_alias."_".$this->_table]))
					$this->_generic->redirect($rememberList[$this->_db_alias."_".$this->_table]);
				else
					$this->_generic->forward($this->_boController,"List".ucfirst(strtolower($this->_db_alias))."_".SLS_String::tableToClass($this->_table));
			}
			# /Forward
		}
	}
	/**
	 * 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;
	}
	/**
	 * Action Home
	 *
	 */
	public function action() 
	{
		$this->secureURL();
		
		$this->_generic->registerLink('GlobalSettings', 'SLS_Init', 'GlobalSettings');
		$handle = file_get_contents($this->_generic->getPathConfig("configSls").'charset.xml');
		$handle2 = file_get_contents($this->_generic->getPathConfig("configSls").'timezone.xml');
		$xml = $this->getXML();
		$xml->addFullTag("charsets", SLS_String::substrBeforeLastDelimiter(SLS_String::substrAfterFirstDelimiter($handle, "<sls_configs>"), "</sls_configs>"), false);
		$xml->addFullTag("timezones", SLS_String::substrBeforeLastDelimiter(SLS_String::substrAfterFirstDelimiter($handle2, "<sls_configs>"), "</sls_configs>"), false);
				
		$errors = array();
		
		$domain 		= SLS_String::trimSlashesFromString($this->_http->getParam('settings_domain'));
		$protocol 		= SLS_String::trimSlashesFromString($this->_http->getParam('settings_protocol'));
		$project 		= SLS_String::trimSlashesFromString($this->_http->getParam('settings_project'));
		$description 	= SLS_String::trimSlashesFromString($this->_http->getParam('settings_description'));
		$keywords 		= SLS_String::trimSlashesFromString($this->_http->getParam('settings_keywords'));
		$author		 	= SLS_String::trimSlashesFromString($this->_http->getParam('settings_author'));
		$copyright	 	= SLS_String::trimSlashesFromString($this->_http->getParam('settings_copyright'));
		$extension 		= ($this->_http->getParam('settings_extension') == "") ? "sls" : SLS_String::trimSlashesFromString($this->_http->getParam('settings_extension'));
		$charset 		= SLS_String::trimSlashesFromString($this->_http->getParam('settings_charset'));
		$doctype 		= SLS_String::trimSlashesFromString($this->_http->getParam('settings_doctype'));
		$bo 			= SLS_String::trimSlashesFromString($this->_http->getParam('settings_bo'));
		$timezone_area	= SLS_String::trimSlashesFromString($this->_http->getParam('settings_timezone_area'));
		$timezone_city	= SLS_String::trimSlashesFromString($this->_http->getParam('settings_timezone_area_'.$timezone_area));
		
		$xmlTmp = new SLS_XMLToolbox($handle);		
		$allowedCharsets = $xmlTmp->getTags("//sls_configs/charset/code");
		
		if ($this->_http->getParam('globalSettings_reload') == "true")
		{	
			if (empty($domain))
				array_push($errors,"You must fill your main domain name");
			if ($protocol != 'http' && $protocol != 'https')
				array_push($errors,"You must choose a correct Protocol");
			if (empty($project))
				array_push($errors,"You must fill your project name");
			if (empty($description))
				array_push($errors,"You must fill your project description");
			if (empty($author))
				$author = $project;
			if (empty($copyright))
				$copyright = $domain;
			if (empty($extension))
				array_push($errors,"You must fill your default extension");
			if (empty($bo))
				array_push($errors,"You must fill your access to your SillySmart's Back-Office");
			if (!in_array($charset,$allowedCharsets))
				array_push($errors,"You must choose a valid charset");
			if (empty($doctype))
				array_push($errors,"You must choose your default doctype");
			if (empty($timezone_area) || empty($timezone_city))
				array_push($errors,"You must choose your default timezone");
							
			if (empty($errors))
			{
				$key = substr(md5($domain).sha1($project).uniqid(microtime()),mt_rand(5,10),mt_rand(20,32));
				$coreXml = $this->_generic->getSiteXML();
				$coreXml->setTag('//configs/domainName', "<domain alias='__default' default='1' js='true' isSecure='false' lang=''><![CDATA[".$domain."]]></domain>", false);
				$coreXml->setTag('//configs/protocol',$protocol);
				$coreXml->setTag('//configs/defaultExtension',$extension);
				$coreXml->setTag('//configs/projectName',$project);
				$coreXml->setTag('//configs/versionName',date("Ymd")."-dev");
				$coreXml->setTag('//configs/metaDescription',$description);
				$coreXml->setTag('//configs/metaKeywords',$keywords);
				$coreXml->setTag('//configs/metaAuthor',$author);
				$coreXml->setTag('//configs/metaCopyright',$copyright);
				$coreXml->setTag('//configs/privateKey',$key);
				$coreXml->setTag('//configs/defaultCharset',strtoupper($charset));
				$coreXml->setTag('//configs/defaultDoctype',$doctype);
				$coreXml->setTag('//configs/defaultTimezone',$timezone_area."/".$timezone_city);
				file_put_contents($this->_generic->getPathConfig("configSecure")."site.xml", $coreXml->getXML());
				$controllersXml = $this->_generic->getControllersXML();
				$controllersXml->setTag("//controllers/controller[@name='SLS_Bo']/controllerLangs/controllerLang",$bo);
				
				$uniqs = array();
				$metas = array();
				
				// Generate Controllers IDS
				$slsControllers = $controllersXml->getTags("//controllers/controller[@side='sls']/@name");	
				$slsLangs = $controllersXml->getTags("//controllers/controller[@side='sls'][1]/scontrollers/scontroller[1]/scontrollerLangs/scontrollerLang/@lang");
				foreach ($slsControllers as $slsController)
				{
					// Take a random id and set it
					$uniq = uniqid("c_");
					while(in_array($uniq, $uniqs))					
						$uniq = uniqid("c_");					
					array_push($uniqs, $uniq);
					$controllersXml->setTagAttributes("//controllers/controller[@name='".$slsController."' and @side='sls']", array("id"=>$uniq));
					
					// Generate Actions IDS
					$slsActions = $controllersXml->getTags("//controllers/controller[@side='sls' and @name='".$slsController."']/scontrollers/scontroller/@name");					
					foreach ($slsActions as $slsAction)
					{
						// Take a random id and set it
						$uniq = uniqid("a_");
						while(in_array($uniq, $uniqs))						
							$uniq = uniqid("a_");						
						array_push($uniqs, $uniq);
						$controllersXml->setTagAttributes("//controllers/controller[@name='".$slsController."' and @side='sls']/scontrollers/scontroller[@name='".$slsAction."']", array("id"=>$uniq));
						
						// Get title attribute, save it into array and delete this attribute
						$tmpArray = array();
						foreach ($slsLangs as $lang)
						{
							$tmpArray[$lang] = array_shift($controllersXml->getTags("//controllers/controller[@name='".$slsController."' and @side='sls']/scontrollers/scontroller[@name='".$slsAction."']/scontrollerLangs/scontrollerLang[@lang='".$lang."']/@title"));
							$controllersXml->deleteTagAttribute("//controllers/controller[@name='".$slsController."' and @side='sls']/scontrollers/scontroller[@name='".$slsAction."']/scontrollerLangs/scontrollerLang[@lang='".$lang."']","title");
						}
						$metas[$uniq] = $tmpArray;
					}	
				}
				
				// Update metas.xml
				$metaXml = '';
				foreach($metas as $key => $value)
				{
					$metaXml .= '<action id="'.$key.'">';
					foreach ($value as $lang => $title)
						$metaXml .=	'<title lang="'.$lang.'"><![CDATA['.$title.']]></title>';
					$metaXml .=	'<robots><![CDATA[noindex, nofollow]]></robots>';
					$metaXml .= '</action>';
				}
				$metaO = new SLS_XMLToolbox(file_get_contents($this->_generic->getPathConfig("configSls")."metas.xml"));
				$metaO->appendXML("//sls_configs",$metaXml);
				$metaO->saveXML($this->_generic->getPathConfig("configSls")."metas.xml");
				
				// Overwrite template __default
				$this->createXslTemplate("__default",$doctype);
				
				file_put_contents($this->_generic->getPathConfig("configSecure")."controllers.xml", $controllersXml->getXML());
				$this->setInstallationStep(array(0=>"SLS_Init",1=>"Initialization"), array(0=>"International",1=>"International"));
				return $this->_generic->dispatch("SLS_Init", "International");
			}
			else
			{
				$xml->startTag("errors");
				foreach ($errors as $error)
					$xml->addFullTag("error", $error, true);
				$xml->endTag("errors");
				
				$xml->addFullTag("domain",$domain,true);
				$xml->addFullTag("protocol",$protocol,true);
				$xml->addFullTag("project",$project,true);
				$xml->addFullTag("description",$description,true);
				$xml->addFullTag("keywords",$keywords,true);
				$xml->addFullTag("author",$author,true);
				$xml->addFullTag("copyright",$copyright,true);
				$xml->addFullTag("extension",$extension,true);
				$xml->addFullTag("charset",$charset,true);
				$xml->addFullTag("doctype",$doctype,true);
				$xml->addFullTag("bo",$bo,true);
				$xml->startTag("timezone");
					$xml->addFullTag("area",$timezone_area,true);
					$xml->addFullTag("city",$timezone_city,true);
				$xml->endTag("timezone");				
			}
		}
		else
		{
			$timezone = date_default_timezone_get();
			$xml->addFullTag("domain",$_SERVER['HTTP_HOST'].(($_SERVER['SCRIPT_NAME'] != "/index.php") ? SLS_String::substrBeforeFirstDelimiter($_SERVER['SCRIPT_NAME'],"/index.php") : ""),true);
			$xml->addFullTag("protocol",(SLS_String::startsWith($_SERVER['SERVER_PROTOCOL'],'HTTPS')) ? 'https' : 'http',true);
			$xml->addFullTag("author","SillySmart",true);
			$xml->addFullTag("extension","sls",true);
			$xml->startTag("timezone");
				$xml->addFullTag("area",(empty($timezone) || !SLS_String::contains($timezone,'/')) ? 'Europe' : SLS_String::substrBeforeFirstDelimiter($timezone,'/'),true);
				$xml->addFullTag("city",(empty($timezone) || !SLS_String::contains($timezone,'/')) ? 'Paris' : SLS_String::substrAfterFirstDelimiter($timezone,'/'),true);
			$xml->endTag("timezone");
			$xml->addFullTag("bo","Manage",true);
		}
		
		$this->saveXML($xml);
	}
Example #9
0
	/**
	 * Bind dependencies between mysql table and static|component|controller|action into controller_bind.json.
	 * This file is used to know if we need to flush cached files when we insert/update/delete datas into tables.
	 * 
	 * @access private
	 * @param string $query the sql select query you have to analyze
	 * @since 1.0.9
	 */
	private function logDependencies($query)
	{
		// If cache enabled, don't log dependencies
		if ($this->_generic->isCache())
			return true;
		
		// Objects
		$log = false;
		$query = strtolower($query);
		$tables = array();
				
		// Force explain on the query to grep tables
		$explains = $this->select("EXPLAIN ".$query);		
		for($i=0 ; $i<$count=count($explains) ; $i++)
			$tables[] = $explains[$i]->table;
		
		// Check all tables > real table name or f****n alias ?
		for($i=0 ; $i<$count=count($tables) ; $i++)
		{		
			if (!in_array($tables[$i],$this->_tables))
			{				
				if (SLS_String::endsWith($query," ".$tables[$i]))				
					$tables[$i] = str_replace('`','',SLS_String::substrAfterLastDelimiter(trim(SLS_String::substrBeforeLastDelimiter($query," ".$tables[$i]))," "));				
				else	
					$tables[$i] = str_replace('`','',SLS_String::substrAfterLastDelimiter(trim(SLS_String::substrBeforeFirstDelimiter($query," ".$tables[$i]." "))," "));
				
					
				if (!in_array($tables[$i],$this->_tables))
					unset($tables[$i]);
			}
		}
		
		if (!empty($tables))
		{			
			$traces = debug_backtrace();		
			for($i=0 ; $i<$count=count($traces) ; $i++)
			{
				$file = $traces[$i]["file"];
				if (SLS_String::contains($file,$this->_generic->getPathConfig("staticsControllers")))
				{
					$log = true;
					$name = strtolower(SLS_String::substrBeforeFirstDelimiter(SLS_String::substrAfterFirstDelimiter($file,$this->_generic->getPathConfig("staticsControllers")),".controller.php"));
					foreach($tables as $table)
						$this->_cache->addBind($table,"statics",$name);
					break;
				}
				if (SLS_String::contains($file,$this->_generic->getPathConfig("componentsControllers")))
				{
					$log = true;					 
					$name = strtolower(SLS_String::substrBeforeFirstDelimiter(SLS_String::substrAfterFirstDelimiter($file,$this->_generic->getPathConfig("componentsControllers")),".controller.php"));
					foreach($tables as $table)
						$this->_cache->addBind($table,"components",$name);
					break;
				}
				if (SLS_String::contains($file,$this->_generic->getPathConfig("actionsControllers")))
				{
					$log = true;
					if (SLS_String::contains($file,"/__") && SLS_String::contains($file,".protected.php"))
					{
						$name = strtolower(SLS_String::substrAfterFirstDelimiter($this->_generic->getControllerId(),"_"));
						foreach($tables as $table)
							$this->_cache->addBind($table,"controllers",$name);
						break;
					}
					else
					{
						$name = strtolower(SLS_String::substrAfterFirstDelimiter($this->_generic->getActionId(),"_"));
						foreach($tables as $table)
							$this->_cache->addBind($table,"actions",$name);
						break;
					}
				}
			}
			if ($log)			
				$this->_cache->saveBind();				
		}
	}
Example #10
0
	/**
	 * Get the URL of the customer back-office menu
	 * 
	 * @access public
	 * @return string the url of the {{USER_BO}}/BoMenu
	 * @since 1.1
	 */
	public function urlBoMenu()
	{
		$params = array_merge_recursive($_POST,$_GET);
		if (SLS_String::endsWith($params['smode'], SLS_Generic::getInstance()->getSiteConfig('defaultExtension')))		
            $params['smode'] = SLS_String::substrBeforeLastDelimiter($params['smode'], '.'.SLS_Generic::getInstance()->getSiteConfig('defaultExtension'));
		$explode = explode("/", $params['smode']);
		$params['smode'] = array_shift($explode);
		$queryString = "";
		$params = array_chunk($explode, 2);		
		for($i=0 ; $i<$count=count($params) ; $i++)		
			if (count($params[$i]) == 2)
				$queryString .= (($i == 0) ? '' : '&').$params[$i][0].'='.(($params[$i][1] != "|sls_empty|") ? $params[$i][1] : "");
		$queryString = str_replace(array("=","&"),"/",$queryString);
		$controllerBo = $this->_generic->getBo();
		if (!empty($controllerBo))
		{
			$controllers = $this->_generic->translateActionId($this->_generic->getActionId($controllerBo,"BoMenu"));
			return $this->_generic->getSiteConfig("protocol")."://".$this->_generic->getSiteConfig("domainName")."/".$controllers["controller"]."/".$controllers["scontroller"]."/".$queryString.".".$this->_generic->getSiteConfig("defaultExtension");
		}
		else
			return "";
	}
	public function action()
	{
		$user 	= $this->hasAuthorative();
		$xml 	= $this->getXML();
		$xml	= $this->makeMenu($xml);
		$siteXML = $this->_generic->getSiteXML();
		
		$errors = array();
		$aliases = array();
		$domains = array();
		
		// Prod Deployment		
		$env = $this->_http->getParam("Env");
		if (empty($env))
			$env = "prod";
		$finalFile = ($this->_http->getParam("ProdDeployment") == "true") ? "site_".$env.".xml" : "site.xml";
		$isInBatch = ($this->_http->getParam("CompleteBatch") == "true") ? true : false;
		$xml->addFullTag("is_batch",($isInBatch) ? "true" : "false",true);
		$xml->addFullTag("is_prod",($this->_http->getParam("ProdDeployment") == "true") ? "true" : "false",true);
		$xml->addFullTag("env",$env,true);
		
		// Get default values
		if ($this->_http->getParam("ProdDeployment") == "true" && file_exists($this->_generic->getRoot().$this->_generic->getPathConfig("configSecure")."/site_".$env.".xml"))
		{			
			$xmlSite = new SLS_XMLToolbox(file_get_contents($this->_generic->getRoot().$this->_generic->getPathConfig("configSecure")."/site_".$env.".xml"));
			
			$defaultDomain 				= $xmlSite->getTag("//configs/domainName/domain");
			$defaultProject				= $xmlSite->getTag("//configs/projectName");
			$defaultVersion				= $xmlSite->getTag("//configs/versionName");
			$defaultExtension			= $xmlSite->getTag("//configs/defaultExtension");
			$defaultCharset				= $xmlSite->getTag("//configs/defaultCharset");
			$defaultDoctype				= $xmlSite->getTag("//configs/defaultDoctype");
			$timezone_area				= SLS_String::substrBeforeFirstDelimiter($xmlSite->getTag("//configs/defaultTimezone"),"/");
			$timezone_city				= SLS_String::substrAfterFirstDelimiter($xmlSite->getTag("//configs/defaultTimezone"),"/"); 
			$defaultLang 				= $xmlSite->getTag("//configs/defaultLang");
			$defaultdomainSessionShare 	= $xmlSite->getTag("//configs/domainSession");
		}
		else
		{
			$defaultDomain 				= $this->_generic->getSiteConfig("domainName");
			$defaultProject				= $this->_generic->getSiteConfig("projectName");
			$defaultVersion				= $this->_generic->getSiteConfig("versionName"); 
			$defaultExtension			= $this->_generic->getSiteConfig("defaultExtension");
			$defaultCharset				= $this->_generic->getSiteConfig("defaultCharset");
			$defaultDoctype				= $this->_generic->getSiteConfig("defaultDcotype");
			$timezone_area				= SLS_String::substrBeforeFirstDelimiter($this->_generic->getSiteConfig("defaultTimezone"),"/");
			$timezone_city				= SLS_String::substrAfterFirstDelimiter($this->_generic->getSiteConfig("defaultTimezone"),"/"); 
			$defaultLang 				= $this->_generic->getSiteConfig("defaultLang");
			$defaultdomainSessionShare 	= $this->_generic->getSiteConfig("domainSession");
		}
		
		$reload 			= $this->_http->getParam("reload");

		$charsetsXML = new SLS_XMLToolBox(file_get_contents($this->_generic->getPathConfig('configSls')."charset.xml"));
		$charsets = array_map('strtoupper', $charsetsXML->getTags('//sls_configs/charset/code'));
		$handle2 = file_get_contents($this->_generic->getPathConfig("configSls").'timezone.xml');
		$xml->addFullTag("timezones", SLS_String::substrBeforeLastDelimiter(SLS_String::substrAfterFirstDelimiter($handle2, "<sls_configs>"), "</sls_configs>"), false);
		
		$langs = $this->_generic->getSiteXML()->getTags('//configs/langs/name');
			
		if ($reload == "true")
		{			
			$domains = 	$siteXML->getTagsAttributes("//configs/domainName/domain",array("alias"));			
			for($i=0 ; $i<$count=count($domains) ; $i++)
				array_push($aliases,$domains[$i]["attributes"][0]["value"]);
			
			// Get New Parameters
			$exportConfig	= $this->_http->getParam('export');
			
			$domains = array();
			foreach($aliases as $alias)
			{
				$domain = SLS_String::trimSlashesFromString($this->_http->getParam("domain_".$alias, "post"));
				if (SLS_String::endsWith(trim($domain),"/"))
					$domain = SLS_String::substrBeforeLastDelimiter(trim($domain),"/");
				$domains[$alias]= $domain;
			}	
			
			$postProject		= SLS_String::trimSlashesFromString($this->_http->getParam("project", "post"));
			$postVersion		= SLS_String::trimSlashesFromString($this->_http->getParam("version", "post"));
			$postExtension 		= SLS_String::trimSlashesFromString($this->_http->getParam("extension", "post"));
			$postCharset		= SLS_String::trimSlashesFromString($this->_http->getParam("charset", "post"));
			$postDoctype		= SLS_String::trimSlashesFromString($this->_http->getParam("doctype", "post"));
			$timezone_area		= SLS_String::trimSlashesFromString($this->_http->getParam('settings_timezone_area'));
			$timezone_city		= SLS_String::trimSlashesFromString($this->_http->getParam('settings_timezone_area_'.$timezone_area));
			$postLang			= SLS_String::trimSlashesFromString($this->_http->getParam("lang", "post"));
			$domainSessionShare	= SLS_String::trimSlashesFromString($this->_http->getParam("domainSession", "post"));

			if ($this->_http->getParam("domainSessionActive") == "")
				$domainSessionShare = "";		

			foreach($domains as $alias => $domain)
				if (empty($domain))
					array_push($errors, "The Domain name is required for the domain alias ".$alias);
			if (empty($postProject))
				array_push($errors, "The project Name is required");
			if (empty($postVersion))
				array_push($errors, "The version Name is required");
			if (empty($postExtension))
				array_push($errors, "The extension is required");
			if (!in_array($postCharset, $charsets))
				array_push($errors, "The Charset selected is incorrect");
			if (empty($postDoctype))
				array_push($errors, "The doctype is required");
			if (empty($timezone_area) || empty($timezone_city))
				array_push($errors,"You must choose your default timezone");
			if (!in_array($postLang, $langs))
				array_push($errors, "The Default lang selected is incorrect");
			if ($this->_http->getParam("domainSessionActive") != "" && empty($domainSessionShare))
				array_push($errors,"You need to fill the domain pattern from which you want to share session");
			if (empty($errors))
			{
				foreach($domains as $alias => $domain)
					$siteXML->setTag("//configs/domainName/domain[@alias='".$alias."']", $domain, true);
				if ($defaultProject != $postProject)
					 $siteXML->setTag("//configs/projectName", $postProject, true);
				if ($defaultVersion != $postVersion)
					 $siteXML->setTag("//configs/versionName", $postVersion, true);
				if ($defaultExtension != $postExtension)
					 $siteXML->setTag("//configs/defaultExtension", $postExtension, true);
				if ($defaultCharset != $postCharset)
					 $siteXML->setTag("//configs/defaultCharset", $postCharset, true);
				if ($defaultDoctype != $postDoctype)
					 $siteXML->setTag("//configs/defaultDoctype", $postDoctype, true);
				if ($defaultTimezone != $timezone_area."/".$timezone_city)
					 $siteXML->setTag("//configs/defaultTimezone", $timezone_area."/".$timezone_city, true);
				if ($defaultLang != $postLang)
					 $siteXML->setTag("//configs/defaultLang", $postLang, true);
				if ($defaultdomainSessionShare != $domainSessionShare)
					$siteXML->setTag("//configs/domainSession", $domainSessionShare, true);
				if ($exportConfig == "on")
				{
					$date = gmdate('D, d M Y H:i:s');
					header("Content-Type: text/xml"); 
					header('Content-Disposition: attachment; filename='.$finalFile);
					header('Last-Modified: '.$date. ' GMT');
					header('Expires: ' .$date);
					// For This F**k'in Browser
					if(preg_match('/msie|(microsoft internet explorer)/i', $_SERVER['HTTP_USER_AGENT']))
					{
						header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
						header('Pragma: public');
					}
					else
						header('Pragma: no-cache');
					
					print($siteXML->getXML());
					exit; 
				}
				else
				{
					$siteXML->refresh();
					@file_put_contents($this->_generic->getPathConfig("configSecure").$finalFile, $siteXML->getXML());					
					if ($isInBatch)
						$this->_generic->forward("SLS_Bo","DataBaseSettings",array(array("key"=>"ProdDeployment","value"=>"true"),array("key"=>"CompleteBatch","value"=>"true"),array("key"=>"Env","value"=>$env)));
					else if ($this->_http->getParam("ProdDeployment") == "true")
						$this->_generic->forward("SLS_Bo","ProductionDeployment");
				}
			}
			else 
			{
				$xml->startTag('errors');
				foreach ($errors as $error)				
					$xml->addFullTag('error', $error);				
				$xml->endTag('errors');
			}
	
		}
		$this->_generic->eraseCache('Site');
		$xml->startTag("charsets");
		foreach ($charsets as $charset)
			$xml->addFullTag('charset', $charset, true);
		$xml->endTag("charsets");
		
		$xml->startTag("langs");
			foreach ($langs as $lang)
			$xml->addFullTag('lang', $lang, true);
		$xml->endTag("langs");
		
		$xmlSite = (file_exists($this->_generic->getRoot().$this->_generic->getPathConfig("configSecure")."/site_".$env.".xml")) ? new SLS_XMLToolbox(file_get_contents($this->_generic->getRoot().$this->_generic->getPathConfig("configSecure")."/site_".$env.".xml")) : null;
		$xml->startTag("current_values");
			if ($this->_http->getParam("ProdDeployment") == "true" && file_exists($this->_generic->getRoot().$this->_generic->getPathConfig("configSecure")."/site_".$env.".xml"))
				$domains = 	$xmlSite->getTagsAttributes("//configs/domainName/domain",array("alias","default","lang"));
			else
				$domains = 	$siteXML->getTagsAttributes("//configs/domainName/domain",array("alias","default","lang"));
			
			$xml->startTag("domains");
			for($i=0 ; $i<$count=count($domains) ; $i++)
			{
				$alias = $domains[$i]["attributes"][0]["value"];
				$default = ($domains[$i]["attributes"][1]["value"] == 1) ? true : false;
				$domain_lang = $domains[$i]["attributes"][2]["value"];
				$xml->startTag("domain");
					$xml->addFullTag("alias",$alias,true);
					$xml->addFullTag("default",($default) ? "true" : "false",true);
					$xml->addFullTag("domain",$domains[$i]["value"],true);
					$xml->addFullTag("lang",$domain_lang,true);
					$xml->addFullTag("delete_url",$this->_generic->getFullPath("SLS_Bo","DeleteDomain",array(array("key"=>"alias","value"=>$alias))),true);
				$xml->endTag("domain");
			}
			$xml->endTag("domains");
			$xml->addFullTag("project", ($this->_http->getParam("ProdDeployment") == "true" && file_exists($this->_generic->getRoot().$this->_generic->getPathConfig("configSecure")."/site_".$env.".xml")) ? $xmlSite->getTag("//configs/projectName") : $this->_generic->getSiteConfig("projectName"), true);
			$xml->addFullTag("version", ($this->_http->getParam("ProdDeployment") == "true" && file_exists($this->_generic->getRoot().$this->_generic->getPathConfig("configSecure")."/site_".$env.".xml")) ? $xmlSite->getTag("//configs/versionName") : $this->_generic->getSiteConfig("versionName"), true);
			$xml->addFullTag("extension", ($this->_http->getParam("ProdDeployment") == "true" && file_exists($this->_generic->getRoot().$this->_generic->getPathConfig("configSecure")."/site_".$env.".xml")) ? $xmlSite->getTag("//configs/defaultExtension") :$this->_generic->getSiteConfig("defaultExtension"), true);
			$xml->addFullTag("charset", ($this->_http->getParam("ProdDeployment") == "true" && file_exists($this->_generic->getRoot().$this->_generic->getPathConfig("configSecure")."/site_".$env.".xml")) ? $xmlSite->getTag("//configs/defaultCharset") :$this->_generic->getSiteConfig("defaultCharset"), true);
			$xml->addFullTag("doctype", ($this->_http->getParam("ProdDeployment") == "true" && file_exists($this->_generic->getRoot().$this->_generic->getPathConfig("configSecure")."/site_".$env.".xml")) ? $xmlSite->getTag("//configs/defaultDoctype") :$this->_generic->getSiteConfig("defaultDoctype"), true);
			$xml->addFullTag("lang", ($this->_http->getParam("ProdDeployment") == "true" && file_exists($this->_generic->getRoot().$this->_generic->getPathConfig("configSecure")."/site_".$env.".xml")) ? $xmlSite->getTag("//configs/defaultLang") :$this->_generic->getSiteConfig("defaultLang"), true);
			$xml->addFullTag("domain_session", ($this->_http->getParam("ProdDeployment") == "true" && file_exists($this->_generic->getRoot().$this->_generic->getPathConfig("configSecure")."/site_".$env.".xml")) ? $xmlSite->getTag("//configs/domainSession") : ((is_null($this->_generic->getSiteConfig("domainSession"))) ? "" : $this->_generic->getSiteConfig("domainSession")), true);
			$xml->startTag("timezone");
				$xml->addFullTag("area",$timezone_area,true);
				$xml->addFullTag("city",$timezone_city,true);
			$xml->endTag("timezone");
		$xml->endTag("current_values");
		
		$xml->addFullTag("add_domain_url",$this->_generic->getFullPath("SLS_Bo","AddDomain"),true);
		
		$environments = $this->getEnvironments();
		$xml->startTag("environments");
		foreach($environments as $environment)
			$xml->addFullTag("environment",$environment,true);
		$xml->endTag("environments");
		
		$this->saveXML($xml);		
	}
	public function getXML()
	{
		# Objects
		$className = ucfirst(strtolower($this->_db_alias))."_".SLS_String::tableToClass($this->_table);
		$this->_generic->useModel(SLS_String::tableToClass($this->_table),ucfirst(strtolower($this->_db_alias)),"user");
		$this->_object = new $className();
		$this->_table = $this->_object->getTable();
		$this->_gap = 0;
		$boPath = "//sls_configs/entry[@type='table' and @name='".strtolower($className)."']";
		$boExists = $this->_xmlBo->getTag($boPath."/@type");
		if (empty($boExists))		
			$boPath = "//sls_configs/entry/entry[@type='table' and @name='".strtolower($className)."']";
		# /Objects
		
		# User params
		$this->_join = array();
		$this->_where = array();
		$this->_group = array();
		$this->_order = array();
		$this->_limit = array();
		$this->_reload = ($this->_http->getParam("reload-filters") == "true") ? true : false;
		$joins = $this->_xmlBo->getTagsAttributes($boPath."/joins/join",array("table","column"));
		$wheres = $this->_xmlBo->getTagsAttributes($boPath."/wheres/where",array("table","column","value","mode"));
		$groups = $this->_xmlBo->getTagsAttributes($boPath."/groups/group",array("table","column"));
		$orders = $this->_xmlBo->getTagsAttributes($boPath."/orders/order",array("table","column","order"));
		$limits = array_shift($this->_xmlBo->getTagsAttributes($boPath."/limits/limit",array("start","length")));
		if (!empty($joins))
			for($i=0 ; $i<$count=count($joins) ; $i++)
				$this->_join[] = array("table" => SLS_String::substrAfterFirstDelimiter($joins[$i]["attributes"][0]["value"],"_"), "column" => $joins[$i]["attributes"][1]["value"], "mode" => "left");
		if (!empty($wheres) && !$this->_reload)		
			for($i=0 ; $i<$count=count($wheres) ; $i++)
				$this->_where[] = array("column" => SLS_String::substrAfterFirstDelimiter($wheres[$i]["attributes"][0]["value"],"_").".".$wheres[$i]["attributes"][1]["value"], "value" => $wheres[$i]["attributes"][2]["value"], "mode" => $wheres[$i]["attributes"][3]["value"]);
		if (!empty($groups))		
			for($i=0 ; $i<$count=count($groups) ; $i++)
				$this->_group[] = SLS_String::substrAfterFirstDelimiter($groups[$i]["attributes"][0]["value"],"_").".".$groups[$i]["attributes"][1]["value"];
		if (!empty($orders))		
			for($i=0 ; $i<$count=count($orders) ; $i++)
				$this->_order[] = array("column" => SLS_String::substrAfterFirstDelimiter($orders[$i]["attributes"][0]["value"],"_").".".$orders[$i]["attributes"][1]["value"], "order" => $orders[$i]["attributes"][2]["value"]);
		if (!empty($limits))
		{
			$this->_limit["start"] = $limits["attributes"][0]["value"];
			$this->_limit["length"] = $limits["attributes"][1]["value"];
		}		
		# /User params
		
		# Comments
		$this->_comments = array();
		$this->_types = array();
		$commentsTable = array();
		$tables = array($this->_table);
		foreach($this->_join as $joinTable)
			$tables[] = $joinTable["table"];
		foreach($tables as $commentTable)
		{
			if (!array_key_exists($commentTable,$commentsTable))
			{
				$comment = $this->_object->getTableComment($commentTable,$this->_db_alias);
				if (empty($comment))
					$comment = $commentTable;
				if (SLS_String::startsWith($comment,"sls:lang:"))
				{
					$key = strtoupper(SLS_String::substrAfterFirstDelimiter($comment,"sls:lang:"));
					$comment = (empty($GLOBALS[$GLOBALS['PROJECT_NAME']]['XSL'][$key])) ? (empty($GLOBALS[$GLOBALS['PROJECT_NAME']]['JS'][$key]) ? $commentTable : $GLOBALS[$GLOBALS['PROJECT_NAME']]['JS'][$key]) : $GLOBALS[$GLOBALS['PROJECT_NAME']]['XSL'][$key];
				}
				$commentsTable[$commentTable] = $comment;
			}
		}		
		# /Comments
		
		# Columns
		$this->_columns = array();
		$this->_columns = array_merge($this->_columns, $this->getTableColumns($this->_db_alias,$this->_table,$boPath,"",true,true));
		foreach($this->_join as $joinTable)
			$this->_columns = array_merge($this->_columns, $this->getTableColumns($this->_db_alias,$joinTable["table"],$boPath,"",false,true));
		$this->_xml->startTag("columns");
		foreach($this->_columns as $columnName => $infosColumn)
		{
			$this->_xml->startTag("column");
			foreach($infosColumn as $key => $value)
			{
				if ((is_array($value) && !in_array($key,array("choices","values","errors"))) || in_array($key,array("values","errors")))
					continue;
					
				if ($key == "choices")
				{
					$this->_xml->startTag("choices");
					foreach($value as $currentValue)
						$this->_xml->addFullTag("choice",$currentValue,true);
					$this->_xml->endTag("choices");
				}
				else if ($key == "label")
				{
					$this->_xml->addFullTag($key,$value,true);
					$this->_xml->startTag("labels_html");
					$labels = explode(" ",trim($value));
					foreach($labels as $label)
						$this->_xml->addFullTag("label_html",$label,true);
					$this->_xml->endTag("labels_html");
				}
				else
					$this->_xml->addFullTag($key,$value,true);
			}
			$this->_xml->endTag("column");
		}
		$this->_xml->endTag("columns");
		# /Columns
		
		# Reload params		
		// Where
		$filters = $this->_http->getParam("filters");
		if (is_array($filters))
		{
			foreach($filters as $filterTable => $filterColumns)
			{
				foreach($filterColumns as $filterColumn => $infos)
				{	
					$values = (is_array($infos["values"]) && $this->_columns[$filterColumn]["html_type"] != 'input_checkbox') ? $infos["values"] : array($infos["values"]);
					$modes = (is_array($infos["mode"])) ? $infos["mode"] : array($infos["mode"]);
					for($i=0 ; $i<$count=count($values) ; $i++)
					{
						$value = $values[$i];
						$mode = (isset($modes[$i])) ? $modes[$i] : ((isset($modes[0])) ? ($modes[0]) : "");
						$mode = (empty($mode)) ? "equal" : $mode;
						if (is_array($value) && $this->_columns[$filterColumn]["html_type"] == 'input_checkbox')
							$mode = "in";
						
						if (in_array($mode,array("null","notnull")) || (!in_array($mode,array("null","notnull")) && !empty($value)))
						{
							$whereFound = false;
							foreach($this->_where as $where)
							{
								if (SLS_String::contains($where["column"],$filterColumn) && $where["value"] == $value && $where["mode"] == $mode)
								{
									$whereFound = true;
									break;
								}
							}
							if (!$whereFound)
								$this->_where[] = array("column" => $filterTable.".".$filterColumn, "value" => $value, "mode" => $mode);
						}
					}
				}
			}
		}
		// Order
		$orderP = $this->_http->getParam("Order");
		if (!empty($orderP))
		{
			$orderWays = array("ASC","DESC");			
			$orderColumn = SLS_String::substrBeforeLastDelimiter($orderP,"_");
			$orderWay = SLS_String::substrAfterLastDelimiter($orderP,"_");
			if (array_key_exists($orderColumn,$this->_columns))
			{
				if (!in_array(strtoupper($orderWay),$orderWays))
					$orderWay = array_shift($orderWays);
					
				$this->_order = array(array("column" => $orderColumn, "order" => $orderWay));
			}
		}
		// Limit
		$length = $this->_http->getParam("Length");
		if (!empty($length) && $length > 0)
			$this->_limit["length"] = $length;
		# /Reload params
		
		# Default params
		$positionExists = $this->_xmlType->getTag("//sls_configs/entry[@table='".$this->_table."' and @type='position']/@column");
		$lengthExists = $this->_xmlRight->getTag("//sls_configs/entry[@login='******']/settings/setting[@key='list_nb_by_page']");
		$fkRecursiveExists = $this->_xmlFk->getTag("//sls_configs/entry[@tableFk='".strtolower($this->_db_alias."_".$this->_table)."' and @tablePk='".strtolower($this->_db_alias)."_".SLS_String::tableToClass($this->_table)."']/@columnFk");
		// i18n > restrict on current language
		if ($this->_object->isMultilanguage())
		{
			$whereLang = false;
			foreach($this->_where as $where)
			{
				if (SLS_String::contains($where["column"],"pk_lang"))
				{
					$whereLang = true;
					break;
				}
			}
			if (!$whereLang)
				array_unshift($this->_where, array("column" => $this->_table.".pk_lang", "value" => $this->_lang->getLang(), "mode" => "equal"));
				
			if (!empty($this->_join))
			{
				foreach($this->_join as $join)
				{
					$join = (is_array($join) && array_key_exists("table",$join)) ? $join["table"] : $join;
					$this->_generic->useModel(SLS_String::tableToClass($join),$this->_db_alias,"user");
					$joinClass = ucfirst(strtolower($this->_db_alias))."_".SLS_String::tableToClass($join);
					$joinObject = new $joinClass();
					$joinColumns = $joinObject->getColumns();
					if (is_array($joinColumns) && in_array("pk_lang",$joinColumns))
						array_push($this->_where, array("column" => $join.".pk_lang", "value" => $this->_lang->getLang(), "mode" => "equal"));
				}
			}
		}
		// fk on the same model
		if (!empty($fkRecursiveExists))
			$this->_where[] = array("column" => $this->_table.".".$fkRecursiveExists, "value" => "", "mode" => "null");
		// group by PK
		if (empty($this->_group))
			$this->_group = array($this->_object->getPrimaryKey());
		// order by position asc or PK desc
		if (empty($this->_order))
			$this->_order = (empty($positionExists)) ? array(array("column" => $this->_object->getPrimaryKey(), "order" => "DESC")) : array(array("column" => $positionExists, "order" => "ASC"));
		// limit at 0, 20
		if (empty($this->_limit))
		{
			if (!empty($lengthExists) && $lengthExists > 0)
				$this->_limit = array("start" => "0", "length" => $lengthExists);
			else
				$this->_limit = array("start" => "0", "length" => "20");
		}
		# /Default params
		
		# Page infos
		$this->_xml->startTag("page");	
			$this->_xml->startTag("model");
				$this->_xml->addFullTag("db",$this->_db_alias,true);
				$this->_xml->addFullTag("table",$this->_table,true);				
				$this->_xml->addFullTag("label",$comment = trim((empty($commentsTable[$this->_table])) ? $this->_table : $commentsTable[$this->_table]),true);
				$this->_xml->startTag("labels_html");
				$comments = explode(" ",$comment);
				foreach($comments as $comment)
					$this->_xml->addFullTag("label_html",$comment,true);
				$this->_xml->endTag("labels_html");
				$this->_xml->addFullTag("pk",$this->_object->getPrimaryKey(),true);
			$this->_xml->endTag("model");
			$this->_xml->startTag("joins");
			foreach($this->_join as $joinTable)
			{
				$this->_xml->startTag("join");
					$this->_xml->addFullTag("db",$this->_db_alias,true);
					$this->_xml->addFullTag("table",$joinTable["table"],true);
					$this->_xml->addFullTag("column",$joinTable["column"],true);
					$this->_xml->addFullTag("label",$comment = trim((empty($commentsTable[$joinTable["table"]])) ? $joinTable["table"] : $commentsTable[$joinTable["table"]]),true);
					$this->_xml->startTag("labels_html");
					$comments = explode(" ",$comment);
					foreach($comments as $comment)
						$this->_xml->addFullTag("label_html",$comment,true);
					$this->_xml->endTag("labels_html");
				$this->_xml->endTag("join");
			}
			$this->_xml->endTag("joins");
			$pkLangWhereFound = false;
			$this->_xml->startTag("wheres");
			foreach($this->_where as $clause)
			{
				$table  = (SLS_String::contains($clause["column"],".")) ? SLS_String::substrBeforeFirstDelimiter($clause["column"],".") : $this->_table;
				$column = (SLS_String::contains($clause["column"],".")) ? SLS_String::substrAfterFirstDelimiter($clause["column"],".") : $clause["column"];
				if ($column != "pk_lang" || ($column == "pk_lang" && !$pkLangWhereFound))
				{
					if ($column == "pk_lang" && !$pkLangWhereFound)
						$pkLangWhereFound = true;
					
					$this->_xml->startTag("where");
						$this->_xml->addFullTag("table",$table,true);
						$this->_xml->addFullTag("column",$column,true);
						$this->_xml->startTag("values");
						if (is_array($clause["value"]))
						{
							foreach($clause["value"] as $clauseValue)
								$this->_xml->addFullTag("value",$clauseValue,true);
						}
						else
							$this->_xml->addFullTag("value",$clause["value"],true);
						$this->_xml->endTag("values");
						$this->_xml->addFullTag("mode",$clause["mode"],true);
					$this->_xml->endTag("where");
				}
			}
			$this->_xml->endTag("wheres");
			$this->_xml->startTag("groups");
				foreach($this->_group as $groupColumn)
					$this->_xml->addFullTag("group",(SLS_String::contains($groupColumn,".")) ? SLS_String::substrAfterFirstDelimiter($groupColumn,".") : $groupColumn,true);
			$this->_xml->endTag("groups");
			$this->_xml->startTag("order");
				$this->_xml->addFullTag("column",(SLS_String::contains($this->_order[0]["column"],".")) ? SLS_String::substrAfterFirstDelimiter($this->_order[0]["column"],".") : $this->_order[0]["column"],true);
				$this->_xml->addFullTag("way",$this->_order[0]["order"],true);
			$this->_xml->endTag("order");
			$page = ($this->_http->getParam("page") > 1) ? $this->_http->getParam("page") : 1;
			$this->_xml->startTag("limit");
				$this->_xml->addFullTag("start",$this->_limit["start"] = ($page < 2) ? 0 : (($page-1) * $this->_limit["length"]),true);
				$this->_xml->addFullTag("length",$this->_limit["length"],true);
			$this->_xml->endTag("limit");
			$countWhere = $this->_where;
			if (!empty($fkRecursiveExists))
			{
				for($i=0 ; $i<$count=count($countWhere) ; $i++)
				{
					if ($countWhere[$i]["column"] == $this->_table.".".$fkRecursiveExists)
					{
						unset($countWhere[$i]);
						break;
					}
				}
			}
			$this->_xml->addFullTag("total",$this->_object->countModels($this->_table,$this->_join,$countWhere,$this->_group),true);
		$this->_xml->endTag("page");
		# /Page infos
				
		# Recordsets
		$recordsets = $this->_object->searchModels($this->_table,$this->_join,$this->_where,$this->_group,$this->_order,$this->_limit);
		$this->_xml = $this->formatRecordsets($this->_xml,$recordsets,$fkRecursiveExists);
		# Recordsets
		
		# Urls
		$this->_xml->startTag("urls");
			$this->_xml->addFullTag("list",($this->_generic->actionIdExists($this->_generic->getActionId($this->_boController,"List".ucfirst(strtolower($this->_db_alias))."_".SLS_String::tableToClass($this->_table)))) ? $this->_generic->getFullPath($this->_boController,"List".ucfirst(strtolower($this->_db_alias))."_".SLS_String::tableToClass($this->_table)) : "",true,array("authorized" => (SLS_BoRights::isAuthorized("read",ucfirst(strtolower($this->_db_alias))."_".SLS_String::tableToClass($this->_table))) ? "true" : "false"));
			$this->_xml->addFullTag("add",($this->_generic->actionIdExists($this->_generic->getActionId($this->_boController,"Add".ucfirst(strtolower($this->_db_alias))."_".SLS_String::tableToClass($this->_table)))) ? $this->_generic->getFullPath($this->_boController,"Add".ucfirst(strtolower($this->_db_alias))."_".SLS_String::tableToClass($this->_table)) : "",true,array("authorized" => (SLS_BoRights::isAuthorized("add",ucfirst(strtolower($this->_db_alias))."_".SLS_String::tableToClass($this->_table))) ? "true" : "false"));
			$this->_xml->addFullTag("populate",$this->_generic->getFullPath($this->_boController,"BoPopulate",array("Db" => ucfirst(strtolower($this->_db_alias)), "Table" => $this->_table)),true,array("authorized" => (SLS_BoRights::getAdminType() == "developer") ? "true" : "false"));
			$this->_xml->addFullTag("edit",($this->_generic->actionIdExists($this->_generic->getActionId($this->_boController,"Modify".ucfirst(strtolower($this->_db_alias))."_".SLS_String::tableToClass($this->_table)))) ? $this->_generic->getFullPath($this->_boController,"Modify".ucfirst(strtolower($this->_db_alias))."_".SLS_String::tableToClass($this->_table),array("id" => ""),false) : "",true,array("authorized" => (SLS_BoRights::isAuthorized("edit",ucfirst(strtolower($this->_db_alias))."_".SLS_String::tableToClass($this->_table))) ? "true" : "false"));
			$this->_xml->addFullTag("clone",($this->_generic->actionIdExists($this->_generic->getActionId($this->_boController,"Clone".ucfirst(strtolower($this->_db_alias))."_".SLS_String::tableToClass($this->_table)))) ? $this->_generic->getFullPath($this->_boController,"Clone".ucfirst(strtolower($this->_db_alias))."_".SLS_String::tableToClass($this->_table),array("id" => ""),false) : "",true,array("authorized" => (SLS_BoRights::isAuthorized("clone",ucfirst(strtolower($this->_db_alias))."_".SLS_String::tableToClass($this->_table))) ? "true" : "false"));
			$this->_xml->addFullTag("delete",($this->_generic->actionIdExists($this->_generic->getActionId($this->_boController,"Delete".ucfirst(strtolower($this->_db_alias))."_".SLS_String::tableToClass($this->_table)))) ? $this->_generic->getFullPath($this->_boController,"Delete".ucfirst(strtolower($this->_db_alias))."_".SLS_String::tableToClass($this->_table),array("id" => ""),false) : "",true,array("authorized" => (SLS_BoRights::isAuthorized("delete",ucfirst(strtolower($this->_db_alias))."_".SLS_String::tableToClass($this->_table))) ? "true" : "false"));
		$this->_xml->endTag("urls");
		# /Urls
		
		# Remember admin settings
		$nodeExists = $this->_xmlRight->getTag("//sls_configs/entry[@login='******']/@login");
		if (!empty($nodeExists))
		{
			$this->_xmlRight->setTag("//sls_configs/entry[@login='******']/settings/setting[@key='list_nb_by_page']",$this->_limit["length"]);
			$this->_xmlRight->saveXML($this->_generic->getPathConfig("configSls")."/rights.xml");
			$this->_xmlRight->refresh();
		}
		# /Remember admin settings
		
		# Session remember
		$rememberList = $this->_session->getParam("SLS_BO_LIST");
		if (empty($rememberList))
			$rememberList = array();
		$url = SLS_String::substrAfterFirstDelimiter($_SERVER["REQUEST_URI"],(($_SERVER['SCRIPT_NAME'] != "/index.php") ? SLS_String::substrBeforeFirstDelimiter($_SERVER['SCRIPT_NAME'],"/index.php")."/" : "/"));
		if (SLS_String::endsWith($url,$this->_generic->getSiteConfig("defaultExtension")))
			$url = SLS_String::substrBeforeLastDelimiter($url,".".$this->_generic->getSiteConfig("defaultExtension"));
		$query = http_build_query($_POST,"","/");
		$query = str_replace(array("%5B","%5D","=/","="),array("[","]","=|sls_empty|/","/"),preg_replace('/%5B[0-9]+%5D/simU', '%5B%5D', $query));		
		if (SLS_String::endsWith(trim($query),"/"))
			$query = SLS_String::substrBeforeLastDelimiter(trim($query),"/");
		if (!empty($query))
			$url .= "/".$query.((count(explode("/",$query))%2 != 0) ? "/|sls_empty|" : "");		
		if (SLS_String::endsWith($url,"/"))
			$url = SLS_String::substrBeforeLastDelimiter($url,"/");
		$url .= ".".$this->_generic->getSiteConfig("defaultExtension");
		$rememberList[$this->_db_alias."_".$this->_table] = $url;
		$this->_session->setParam("SLS_BO_LIST",$rememberList);		
		# /Session remember
		
		return $this->_xml;
	}
	public function action()
	{
		$user 	= $this->hasAuthorative();
		$xml 	= $this->getXML();
		$xml	= $this->makeMenu($xml);
		$reload = $this->_http->getParam("reload");
		$action = $this->_http->getParam("Action");
		$errors = array();
		$slsXml = $this->_generic->getCoreXML('sls');
		$syncServer = array_shift($slsXml->getTags("slsnetwork"));
		$slsVersion = array_shift($slsXml->getTags("version"));
		$edit = $this->_generic->getTranslatedController('SLS_Bo', 'EditPlugin');		
		$editAppli = $this->_generic->getTranslatedController('SLS_Bo', 'CreatePlugin');		
		
		$pluginsXML = $this->_generic->getPluginXml("plugins");
		// List own Plugins
		if ($action == "")
		{
			$deleteController = $this->_generic->getTranslatedController("SLS_Bo", "DeletePlugin");
			if (($count = count($pluginsXML->getTags("//plugins/plugin[@beta='1']"))) > 0)
			{
				$xml->startTag("own_plugin");
					for($i=1;$i<=$count;$i++)
					{
						$id = array_shift($pluginsXML->getTags("//plugins/plugin[@beta='1'][".$i."]/@id"));
						$xml->startTag("plugin", array("code"=>array_shift($pluginsXML->getTags("//plugins/plugin[@beta='1'][".$i."]/@code")),"id"=>$id));
						$xml->addFullTag("description", array_shift($pluginsXML->getTags("//plugins/plugin[@beta='1'][".$i."]/description")), true);
						$xml->addFullTag("custom", array_shift($pluginsXML->getTags("//plugins/plugin[@beta='1'][".$i."]/@customizable")), true);
						$xml->addFullTag("edit", $edit['protocol']."://".$this->_generic->getSiteConfig('domainName')."/".$edit['controller']."/".$edit['scontroller']."/Plugin/".$id.".sls", true);
						$xml->addFullTag("name", array_shift($pluginsXML->getTags("//plugins/plugin[@beta='1'][".$i."]/name")), true);
						$xml->addFullTag("delete", $deleteController['protocol']."://".$this->_generic->getSiteConfig("domainName")."/".$deleteController['controller']."/".$deleteController['scontroller']."/Plugin/".$id.".sls", true);
						$xml->addFullTag("editAppli", $editAppli['protocol']."://".$this->_generic->getSiteConfig("domainName")."/".$editAppli['controller']."/".$editAppli['scontroller']."/Plugin/".$id."/Action/Edit.sls", true);						
						$xml->endTag("plugin");
						
					}
				$xml->endTag("own_plugin");
			}
			$this->registerLink("CREATE", "SLS_Bo", "CreatePlugin", array("Action"=>"Create"));
			$xml->addFullTag("step", "list", true);
		}
		// Create a new Plugin
		elseif ($action == "Create")
		{
			if ($reload == "true")
			{
				$name = SLS_String::trimSlashesFromString($this->_http->getParam("name"));
				$code = SLS_String::stringToUrl(strtolower(SLS_String::getSafeFilename(SLS_String::trimSlashesFromString($this->_http->getParam("code")))), "", true);
				$output = SLS_String::trimSlashesFromString($this->_http->getParam("output"));
				$custom = SLS_String::trimSlashesFromString($this->_http->getParam("custom"));
				$path = SLS_String::trimSlashesFromString($this->_http->getParam("path"));
				$pathName = SLS_String::stringToUrl(SLS_String::getSafeFilename(ucwords(SLS_String::trimSlashesFromString($this->_http->getParam("code")))), "", false);
				$description = SLS_String::trimSlashesFromString($this->_http->getParam("full_description"));
				
				// Get Plugins Versions
				$serversJSON = @file_get_contents($syncServer);
				$pluginsAvailable = array();
				$filesReserved = array();
				$dirsReserved = array();
				if ($serversJSON !== false && !empty($serversJSON))
				{					
					$servers = json_decode($serversJSON);
					$pluginsServers = $servers->servers->plugins;
					$plugins = array();
					
					foreach ($pluginsServers as $pluginsServer)
					{						
						$serverContent = @file_get_contents($pluginsServer->url);
						if ($serverContent !== false && !empty($serverContent))
						{
							$serverContent = json_decode($serverContent);
							$plugs = $serverContent->plugins;
							foreach ($plugs as $plug)
							{
								$pluginsAvailable[] = $plug->code;
								if ($plug->type == 'file')
									$filesReserved[] = $plug->path;
								else 
									$dirsReserved[] = $plug->path;
							}
						}
					}
				}
				
				$xml->startTag("form");
					$xml->addFullTag("name", $name, true);
					$xml->addFullTag("code", $code, true);
					$xml->addFullTag("custom", $custom, true);
					$xml->addFullTag("path", $path, true);
					$xml->addFullTag("path_name", $pathName, true);
					$xml->addFullTag("fill_description", $description, true);
					if (empty($name))
						$errors[] = "You must fill the common name";
					if (empty($code))
						$errors[] = "You must fill the code name";
					if (empty($output) || ($output != 'yes' && $output != 'no'))
						$errors[] = "Choose if your plugin is an output type";
					if (empty($custom) || ($custom != 'yes' && $custom != 'no'))
						$errors[] = "Choose if your plugin will be customizable";
					if (empty($path) || ($path != 'file' && $path != 'dir'))
						$errors[] = "Choose if your plugin require only a file or multiple files in a directory";	
					if (empty($pathName))
						$errors[] = "You must choose a filename or a directory name";	
					if (empty($description))
						$errors[] = "You must fill the full description in English";	
					if (empty($errors))
					{
						if (in_array($code, $pluginsAvailable))
							$errors[] = "This code name is already in use for another plugin";
						if ($path == 'file' && in_array($pathName.".class.php", $filesReserved))
							$errors[] = "This file name is already in use for another plugin";
						if ($path == 'dir' && in_array($pathName, $dirsReserved))
							$errors[] = "This directory name is already in use for another plugin";
						
						if (empty($errors))
						{
							
							$newId = md5(uniqid($this->_generic->getSiteConfig("privateKey")));
							$pathFile = $this->_generic->getPathConfig("plugins");
							if ($path =="dir")
								$pathFile .= $pathName."/";
							
							if ($output == 'no')
							{
								$str = '<?php'."\n".
										'/**'."\n".
										' * Plugin '.$name."\n". 
										' * '.str_replace("<br />", "\\n * ", nl2br($description))."\n".
										' *'."\n".
										' * @package Plugins'."\n".
										' * @since 1.0'."\n".
										' */'."\n". 
										'class '.$pathName.' extends SLS_PluginGeneric implements SLS_IPlugin'."\n".
										'{'."\n".
										t(1).'public function __construct()'."\n".
										t(1).'{'."\n".
											t(2).'parent::__construct($this);'."\n".
											t(2).'$this->checkDependencies();'."\n".
										t(1).'}'."\n\n".
										t(1).'public function checkDependencies()'."\n".
										t(1).'{'."\n".
										t(1).'}'."\n".
										'}'."\n".
										'?>';
							}
							else 
							{
								$str = '<?php'."\n".
										'/**'."\n".
										' * Plugin '.$name."\n". 
										' * '.str_replace("<br />", "\\n * ", nl2br($description))."\n".
										' *'."\n".
										' * @package Plugins'."\n".
										' * @since 1.0'."\n".
										' */'."\n". 
										'class '.$pathName.' extends SLS_PluginGeneric implements SLS_IPlugin, SLS_IPluginOutput'."\n".
										'{'."\n".
										t(1).'public function __construct()'."\n".
										t(1).'{'."\n".
											t(2).'parent::__construct($this);'."\n".
											t(2).'$this->checkDependencies();'."\n".
										t(1).'}'."\n\n".
										t(1).'public function checkDependencies()'."\n".
										t(1).'{'."\n".
										t(1).'}'."\n".
										'}'."\n".
										'?>';
							}
							
							if (@file_put_contents($pathFile.$pathName.".class.php", $str) === false)
								$errors[] = "Plugin Creation failed";
									
							
							if (empty($errors))
							{
								if ($custom == "yes")
								{
									$str = "<?xml version=\"1.0\" encoding=\"utf-8\"?><plugin><exemple_part writable=\"1\" label=\"Exemple Part\" clonable=\"1\" alias=\"main\"><exemple_row writable=\"1\" label=\"Exemple Row\" type=\"string\" clonable=\"0\" /></exemple_part></plugin>";
									if (@file_put_contents($this->_generic->getPathConfig("configPlugins").$newId."_".$code.".xml", $str) === false)
										$errors[] = "Plugin Creation failed";
								}
								
							}
							if (empty($errors))
							{
								$newPlugin = new SLS_XMLToolbox(false);
								$newPlugin->startTag("plugin", array(
									"beta"=>"1",
									"code"=>$code,
									"id"=>$newId,
									"version"=>"0.1",
									"compability"=>$slsVersion,
									"customizable"=>($custom=="yes")?"1":"0",
									"output"=>($output=="yes")?"1":"0",
									"file"=>($path=="file")?"1":"0",
									"path"=>($path=="file")?$pathName.".class.php" : $pathName
								));
								$newPlugin->addFullTag("name", $name, true);
								$newPlugin->addFullTag("description", $description, true);
								$newPlugin->addFullTag("author", "Me", true);
								$newPlugin->addFullTag("dependencies", "", false);
								$newPlugin->endTag("plugin");
								$pluginsXML->appendXMLNode("//plugins", $newPlugin->getXML('noHeader'));
								file_put_contents($this->_generic->getPathConfig("configPlugins")."plugins.xml", $pluginsXML->getXML());
								$this->goDirectTo("SLS_Bo", "CreatePlugin");
							}
							
						}
						
					}
					
				$xml->endTag("form");
			}
			$xml->addFullTag("step", "create", true);
		}
		elseif ($action == "Edit")
		{
			
			$pluginID = $this->_http->getParam("Plugin");
			if (SLS_PluginsManager::isExists($pluginID) === false)
				$this->goDirectTo("SLS_Bo", "CreatePlugin");
			
			$originalPlugin = new SLS_PluginsManager($pluginID);
				
			if ($reload == "true")
			{
				
				$name = SLS_String::trimSlashesFromString($this->_http->getParam("name"));
				$code = SLS_String::stringToUrl(strtolower(SLS_String::getSafeFilename(SLS_String::trimSlashesFromString($this->_http->getParam("code")))), "", true);
				$output = SLS_String::trimSlashesFromString($this->_http->getParam("output"));
				$custom = SLS_String::trimSlashesFromString($this->_http->getParam("custom"));
				$path = SLS_String::trimSlashesFromString($this->_http->getParam("path"));
				$pathName = SLS_String::stringToUrl(SLS_String::getSafeFilename(ucwords(SLS_String::trimSlashesFromString($this->_http->getParam("code")))), "", false);
				$description = SLS_String::trimSlashesFromString($this->_http->getParam("full_description"));
				
				// Get Plugins Versions
				$serversJSON = @file_get_contents($syncServer);
				$pluginsAvailable = array();
				$filesReserved = array();
				$dirsReserved = array();
				if ($serversJSON !== false && !empty($serversJSON))
				{					
					$servers = json_decode($serversJSON);
					$pluginsServers = $servers->servers->plugins;
					$plugins = array();
					
					foreach ($pluginsServers as $pluginsServer)
					{						
						$serverContent = @file_get_contents($pluginsServer->url);
						if ($serverContent !== false && !empty($serverContent))
						{
							$serverContent = json_decode($serverContent);
							$plugs = $serverContent->plugins;
							foreach ($plugs as $plug)
							{
								$pluginsAvailable[] = $plug->code;
								if ($plug->type == 'file')
									$filesReserved[] = $plug->path;
								else 
									$dirsReserved[] = $plug->path;
							}
						}
					}
				}
				
				$xml->startTag("form");
					$xml->addFullTag("name", $name, true);
					$xml->addFullTag("code", $code, true);
					$xml->addFullTag("custom", $custom, true);
					$xml->addFullTag("path", $path, true);
					$xml->addFullTag("path_name", $pathName, true);
					$xml->addFullTag("fill_description", $description, true);
					if (empty($name))
						$errors[] = "You must fill the common name";
					if (empty($code))
						$errors[] = "You must fill the code name";
					if (empty($output) || ($output != 'yes' && $output != 'no'))
						$errors[] = "Choose if your plugin is an output type";
					if (empty($custom) || ($custom != 'yes' && $custom != 'no'))
						$errors[] = "Choose if your plugin will be customizable";
					if (empty($path) || ($path != 'file' && $path != 'dir'))
						$errors[] = "Choose if your plugin require only a file or multiple files in a directory";	
					if (empty($pathName))
						$errors[] = "You must choose a filename or a directory name";	
					if (empty($description))
						$errors[] = "You must fill the full description in English";	
					if (empty($errors))
					{
						if ($code != $originalPlugin->_code && in_array($code, $pluginsAvailable))
							$errors[] = "This code name is already in use for another plugin";
						if ($pathName.".class.php" != $originalPlugin->_path && $path == 'file' && in_array($pathName.".class.php", $filesReserved))
							$errors[] = "This file name is already in use for another plugin";
						if ($pathName != $originalPlugin->_path && $path == 'dir' && in_array($pathName, $dirsReserved))
							$errors[] = "This directory name is already in use for another plugin";
						if (empty($errors))
						{
							if ($originalPlugin->_file == 1 && $path == 'dir')
							{
								if (!is_dir($this->_generic->getPathConfig("plugins").$originalPlugin->_path))
									mkdir($this->_generic->getPathConfig("plugins").$pathName);
								if (is_file($this->_generic->getPathConfig("plugins").$originalPlugin->_path))
									@unlink($this->_generic->getPathConfig("plugins").$originalPlugin->_path);
								
							}
							if ($originalPlugin->_file == 0 && $path == 'file')
							{
								if (is_dir($this->_generic->getPathConfig("plugins").$originalPlugin->_path))
									$this->_generic->rm_recursive($this->_generic->getPathConfig("plugins").$originalPlugin->_path);
								if ($output == 'no')
								{
									$str = '<?php'."\n".
											'/**'."\n".
											' * Plugin '.$name."\n". 
											' * '.str_replace("<br />", "\\n * ", nl2br($description))."\n".
											' *'."\n".
											' * @package Plugins'."\n".
											' * @since 1.0'."\n".
											' */'."\n". 
											'class '.$pathName.' extends SLS_PluginGeneric implements SLS_IPlugin'."\n".
											'{'."\n".
											t(1).'public function __construct()'."\n".
											t(1).'{'."\n".
												t(2).'parent::__construct($this);'."\n".
												t(2).'$this->checkDependencies();'."\n".
											t(1).'}'."\n\n".
											t(1).'public function checkDependencies()'."\n".
											t(1).'{'."\n".
											t(1).'}'."\n".
											'}'."\n".
											'?>';
								}
								else 
								{
									$str = '<?php'."\n".
											'/**'."\n".
											' * Plugin '.$name."\n". 
											' * '.str_replace("<br />", "\\n * ", nl2br($description))."\n".
											' *'."\n".
											' * @package Plugins'."\n".
											' * @since 1.0'."\n".
											' */'."\n". 
											'class '.$pathName.' extends SLS_PluginGeneric implements SLS_IPlugin, SLS_IPluginOutput'."\n".
											'{'."\n".
											t(1).'public function __construct()'."\n".
											t(1).'{'."\n".
												t(2).'parent::__construct($this);'."\n".
												t(2).'$this->checkDependencies();'."\n".
											t(1).'}'."\n\n".
											t(1).'public function checkDependencies()'."\n".
											t(1).'{'."\n".
											t(1).'}'."\n".
											'}'."\n".
											'?>';
								}
								
								if (@file_put_contents($this->_generic->getPathConfig("plugins").$pathName.".class.php", $str) === false)
									$errors[] = "Plugin Creation failed";
							}
							if ($originalPlugin->_file == 1 && $path == 'file' && $pathName.".class.php" != $originalPlugin->_path)
							{
								if (is_file($this->_generic->getPathConfig("plugins").$originalPlugin->_path))
									rename($this->_generic->getPathConfig("plugins").$originalPlugin->_path, $this->_generic->getPathConfig("plugins").$pathName.".class.php");
							}
							if ($originalPlugin->_file == 0 && $path == 'dir' && $pathName != $originalPlugin->_path)
							{
								if (is_dir($this->_generic->getPathConfig("plugins").$originalPlugin->_path))
									rename($this->_generic->getPathConfig("plugins").$originalPlugin->_path, $this->_generic->getPathConfig("plugins").$pathName);
							}
							if (empty($errors))
							{
								if ($custom == "yes" && $originalPlugin->_customizable == false)
								{
									$str = "<?xml version=\"1.0\" encoding=\"utf-8\"?><plugin><exemple_part writable=\"1\" label=\"Exemple Part\" clonable=\"1\" alias=\"main\"><exemple_row writable=\"1\" label=\"Exemple Row\" type=\"string\" clonable=\"0\" /></exemple_part></plugin>";
									if (@file_put_contents($this->_generic->getPathConfig("configPlugins").$originalPlugin->_id."_".$code.".xml", $str) === false)
										$errors[] = "Plugin Creation failed";
								}
								if ($custom == "no" && $originalPlugin->_customizable == true)
								{
									if (is_file($this->_generic->getPathConfig("configPlugins").$originalPlugin->_id."_".$originalPlugin->_code.".xml"))
										unlink($this->_generic->getPathConfig("configPlugins").$originalPlugin->_id."_".$originalPlugin->_code.".xml");
								}
								
							}
							if (empty($errors))
							{
								if ($code != $originalPlugin->_code)
								{
									$pluginsXML->setTagAttributes("//plugins/plugin[@beta='1' and @id='".$pluginID."']", array("code"=>$code));
									if (is_file($this->_generic->getPathConfig("configPlugins").$originalPlugin->_id."_".$originalPlugin->_code.".xml"))
										rename($this->_generic->getPathConfig("configPlugins").$originalPlugin->_id."_".$originalPlugin->_code.".xml", $this->_generic->getPathConfig("configPlugins").$originalPlugin->_id."_".$code.".xml");
								}
								if (($output == "yes" && $originalPlugin->_output == 0) || ($output == "no" && $originalPlugin->_output == 1))
									$pluginsXML->setTagAttributes("//plugins/plugin[@beta='1' and @id='".$pluginID."']", array("output"=>($output=="yes")?"1":"0"));
								if (($custom == "yes" && $originalPlugin->_customizable == false) || ($custom == "no" && $originalPlugin->_customizable == true))
									$pluginsXML->setTagAttributes("//plugins/plugin[@beta='1' and @id='".$pluginID."']", array("customizable"=>($custom=="yes")?"1":"0"));
								if (($originalPlugin->_file == 1 && $path == 'dir') || ($originalPlugin->_file == 0 && $path == 'file'))
									$pluginsXML->setTagAttributes("//plugins/plugin[@beta='1' and @id='".$pluginID."']", array("file"=>($path=="file")?"1":"0"));
								if (($path == 'file' && $originalPlugin->_path != $pathName.".class.php") || ($path == 'dir' && $originalPlugin->_path != $pathName))
									$pluginsXML->setTagAttributes("//plugins/plugin[@beta='1' and @id='".$pluginID."']", array("path"=>($path=="file")?$pathName.".class.php" : $pathName));
								if ($originalPlugin->_name != $name)
									$pluginsXML->setTag("//plugins/plugin[@beta='1' and @id='".$pluginID."']/name", $name, true);
								if ($originalPlugin->_description != $description)
									$pluginsXML->setTag("//plugins/plugin[@beta='1' and @id='".$pluginID."']/description", $description, true);
								
								file_put_contents($this->_generic->getPathConfig("configPlugins")."plugins.xml", $pluginsXML->getXML());
								$this->goDirectTo("SLS_Bo", "CreatePlugin");
							}
							
						}
						
					}
					
				$xml->endTag("form");
			}
			$originalPlugin = new SLS_PluginsManager($pluginID);
			$xml->startTag("plugin");
				$xml->addFullTag("name", $originalPlugin->_name, true);
				$xml->addFullTag("code", $originalPlugin->_code, true);
				$xml->addFullTag("output", ($originalPlugin->_output == 1)?"yes":"no", true);
				$xml->addFullTag("custom", ($originalPlugin->_customizable)?"yes":"no", true);
				$xml->addFullTag("path", ($originalPlugin->_file==1)?'file':'dir', true);
				$xml->addFullTag("path_name", ($originalPlugin->_file==1)?SLS_String::substrBeforeLastDelimiter($originalPlugin->_path, ".class.php"):$originalPlugin->_path, true);
				$xml->addFullTag("fill_description", $originalPlugin->_description, true);
			$xml->endTag("plugin");
			$xml->addFullTag("step", "edit", true);
		}
		
		if (!empty($errors))
		{
			$xml->startTag("errors");
			foreach ($errors as $error)
				$xml->addFullTag("error", $error, true);
			$xml->endTag("errors");
		}
		
		$this->saveXML($xml);		
	}
	/**
	 * Return all parameters (GET, POST or FILES)
	 *
	 * @access public	 
	 * @param string $type the type you want ('ALL','POST','GET','FILES')
	 * @return array $params array of all paramters
	 * @since 1.0
	 * @example 
	 * var_dump($this->_http->getParams());
	 * // will produce :
	 * array(
  	 * 		"mode"		=> "Home",
  	 * 		"smode"		=> "Welcome",
  	 * 		"..."		=> "..."
	 * )
	 */
	public function getParams($type='all') 
	{
		$type = strtoupper($type);
		if ($type != 'ALL' && $type != 'POST' && $type != 'GET' && $type != 'FILES')
			SLS_Tracing::addTrace(new Exception("To use the method SLS_HttpRequest::getParams(), you need to specify a correct type of value ('all', 'post', 'get' or 'files')"));
		else
		{
			if ($type == 'ALL') 
				return $this->_params;
			elseif ($type == 'POST')			
				return $_POST;
			elseif ($type == 'GET')
			{
				$params = $_GET;
			
				// Strip extension if exists		
				if (SLS_String::endsWith($params['smode'], SLS_Generic::getInstance()->getSiteConfig('defaultExtension')))		
					$params['smode'] = SLS_String::substrBeforeLastDelimiter($params['smode'], '.'.SLS_Generic::getInstance()->getSiteConfig('defaultExtension'));
				// Get smode        
				$explode = explode("/", $params['smode']);
				$params['smode'] = array_shift($explode);		
				// Transform url in classic queryString '?param1=value1&param2=value2...'
				$queryString = "";
				$params = array_chunk($explode, 2);		
				for($i=0 ; $i<$count=count($params) ; $i++)		
					if (count($params[$i]) == 2)
						$queryString .= (($i == 0) ? '' : '&').$params[$i][0].'='.(($params[$i][1] != "|sls_empty|") ? $params[$i][1] : "");		
				// Get all params/values
				parse_str($queryString,$params);		
				if (!empty($params))
				{
					foreach($params as $key => $value)
						$params[$key] = $value;
				}				
				return $params;
			}			
			elseif ($type == 'FILES')
				return $_FILES;
			else 
				return $this->_params;
		}
	}
	/**
	 * Recursive files listing
	 * 
	 * @param array $files array of files
	 * @param string $root path
	 * @param string $extension extension to fetch
	 */
	protected function recursiveList($files,$root,$extension=".js")
	{
		if (SLS_String::endsWith($root,"/"))
			$root = SLS_String::substrBeforeLastDelimiter($root,"/");
		$handle = opendir($root);
		while (false !== ($file = readdir($handle)))
		{			
			if (is_dir($root."/".$file)  && substr($file, 0, 1) != ".")							
				$this->recursiveList($files,$root."/".$file,$extension);			
			if (!is_dir($root."/".$file) && substr($file, 0, 1) != ".")				
				if (SLS_String::endsWith($file,$extension))
					array_push($files,$root."/".$file);					
		}
		return $files;
	}
	public function action()
	{
		$user 	= $this->hasAuthorative();
		$xml 	= $this->getXML();
		$xml	= $this->makeMenu($xml);		
		
		$plugId = $this->_http->getParam('Plugin');
		$reload = $this->_http->getParam('reload', 'post');
		$controllers = $this->_generic->getTranslatedController('SLS_Bo', 'Plugins');
		
		
		if(SLS_PluginsManager::isExists($plugId) === false)
			$this->redirect($controllers['controller']."/".$controllers['scontroller']);
		
		$plugin = new SLS_PluginsManager($plugId);
		$xmlPlug = $plugin->getXML();
		
		
		if (!$plugin->isCustomizable())
			$this->redirect($controllers['controller']."/".$controllers['scontroller']);
		
		$xml->startTag("plugin_infos");
			$xml->addFullTag('name', $plugin->_name);
			$xml->addFullTag('code', $plugin->_code);
			$xml->addFullTag('id', $plugin->_id);
			$xml->addFullTag('version', $plugin->_version);
		$xml->endTag("plugin_infos");
		
		if ($reload == 'true')
		{
			$errors = array();
			$form_memory = array();
			$form_memory = $this->recoverFormValues("//plugin", $xmlPlug, $form_memory);
			$xml->startTag("memory");
			foreach ($form_memory as $key=>$field)
			{
				$xml->startTag("values");
				$xml->addFullTag("name", $key, true);
				$xml->addFullTag("value", $field['value'], true);
				$xml->endTag("values");
				$xpath = $field['xpath'];
				$index = SLS_String::substrBeforeFirstDelimiter(SLS_String::substrAfterLastDelimiter($xpath, "["), "]");
				$xpathNoIndex = SLS_String::substrBeforeLastDelimiter($xpath, "[");
				if (SLS_String::endsWith($key, "_alias"))
				{
					if (count($xmlPlug->getTags($xpathNoIndex."[position() != ".$index." and @alias='".$field['value']."']")) != 0)
						$errors[] = array_shift($xmlPlug->getTags($xpath."/@label"))." alias ".$GLOBALS[$GLOBALS['PROJECT_NAME']]['JS']['SLS_E_UNIQUE'];
					else 
						$xmlPlug->setTagAttributes($xpath, array("alias"=>$field['value']));
				}
				else {
					$is_null = (array_shift($xmlPlug->getTags($xpath."/@null")) == "1") ? true : false;
					switch (array_shift($xmlPlug->getTags($xpath."/@type")))
					{
						case "string" :
							if (!SLS_String::validateString($field['value']) && !$is_null)
								$errors[] = array_shift($xmlPlug->getTags($xpath."/@label"))." ".$GLOBALS[$GLOBALS['PROJECT_NAME']]['JS']['SLS_E_TYPE'];
							else 
								$xmlPlug->setTag($xpath, $field['value']);
							break;
						case "password" :
								if (isset($field['value']))
									$xmlPlug->setTag($xpath, SLS_Security::encrypt($field['value'], $this->_generic->getSiteConfig("privateKey")));
							break;
						case "int" : 
							if (!is_int($field['value']) && !$is_null)
								$errors[] = array_shift($xmlPlug->getTags($xpath."/@label"))." ".$GLOBALS[$GLOBALS['PROJECT_NAME']]['JS']['SLS_E_TYPE'];
							else 
								$xmlPlug->setTag($xpath, $field['value']);
							break;
						case "float" :
							if (!is_float($field['value']) && !$is_null)
								$errors[] = array_shift($xmlPlug->getTags($xpath."/@label"))." ".$GLOBALS[$GLOBALS['PROJECT_NAME']]['JS']['SLS_E_TYPE'];
							else 
								$xmlPlug->setTag($xpath, $field['value']);
							break;
						case "select" : 
							$values = explode("|||", array_shift($xmlPlug->getTags($xpath."/@values")));
							if (!in_array($field['value'], $values))
								$errors[] = array_shift($xmlPlug->getTags($xpath."/@label"))." ".$GLOBALS[$GLOBALS['PROJECT_NAME']]['JS']['SLS_E_CONTENT'];
							else 
								$xmlPlug->setTag($xpath, $field['value']);
							break;
						default:
							break;
					}
				}
				
			}
			$xml->endTag("memory");
			if (!empty($errors))
			{
				$xml->startTag("errors");
					foreach ($errors as $error)
						$xml->addFullTag("error", $error, true);
				$xml->endTag("errors");
			}
			else 
			{
				$xml->addFullTag("success", "ok", true);
				$plugin->saveXML($xmlPlug);
			}
		}
		
		$xml->addFullTag("fields", $plugin->getFields()->getXML('noHeader'), false);	
				
		$this->saveXML($xml);		
	}
Example #17
0
	/**
	 * Format paginate
	 * Since sls 1.0.7: javascript removed, all links are real 
	 *
	 * @access public static
	 * @param int $start offset start
	 * @param int $length results by page
	 * @param int $total total results
	 * @param string $param name of the parameter (default: 'page')
	 * @param string $urlSuffix end of url (default: '.sls')
	 * @param string $aClass <a> className (default: 'pager_link');
	 * @param string $spanClass <span> selected className (default: 'pager_selected');
	 * @param string $dot <span>...</span> dot className (default: 'pager_dot');
	 * @param int $maxNb max number to display (default: 10)
	 * @param int $adj nb adjacent numbers (default: 3)
	 * @return string html string
	 * @since 1.0.1
	 */
	public static function paginate($start,$length,$total,$param="page",$urlSuffix=".sls",$aClass="pager_link",$spanClass="pager_selected",$dotClass="pager_dot",$maxNb=10,$adj=3)
	{
		if ($length == 0 || $total == 0)
			return '';
		
		$current = ($start == 0) ? 1 : ($start/$length)+1;
		$total = ceil($total / $length);
		$pager = '';
		
		$url = (self::startsWith($_SERVER["SERVER_PROTOCOL"],"https") ? "https://" : "http://").$_SERVER["HTTP_HOST"];
		if ($_SERVER["REQUEST_URI"] == "/")		
			$url .= ("/".($_SESSION["current_controller_translated"]."/".$_SESSION["current_action_translated"]));
		else
			$url .= (self::substrBeforeFirstDelimiter(self::substrBeforeFirstDelimiter($_SERVER["REQUEST_URI"],"."),"/".$param."/"));		
		if (self::endsWith($url,"/"))
			$url = self::substrBeforeLastDelimiter($url,"/");
		
		$query = http_build_query($_POST,"","/");
		$query = str_replace(array("%5B","%5D","=/","="),array("[","]","=|sls_empty|/","/"),preg_replace('/%5B[0-9]+%5D/simU', '%5B%5D', $query));		
		if (SLS_String::endsWith(trim($query),"/"))
			$query = SLS_String::substrBeforeLastDelimiter(trim($query),"/");
		if (!empty($query))
			$url .= "/".$query.((count(explode("/",$query))%2 != 0) ? "/|sls_empty|" : "");
		
		if ($total > 1)
		{
			if ($current > 1)
				$pager .= '<a class="'.$aClass.'" href="'.$url.'/'.$param.'/'.($current-1).$urlSuffix.'" >&lt;</a>';
			
			if ($total < ($maxNb/2 + ($adj * 2)))
			{
				$pager .= ($current == 1) ? ('<span class="'.$spanClass.'">1</span>') : ('<a class="'.$aClass.'" href="'.$url.'/'.$param.'/'.(1).$urlSuffix.'">1</a>');
				
				for ($i = 2; $i<=$total; $i++)
				{
					if ($i == $current)
						$pager .= '<span class="'.$spanClass.'">'.$i.'</span>';
					else
						$pager .= '<a class="'.$aClass.'" href="'.$url.'/'.$param.'/'.($i).$urlSuffix.'" >'.$i.'</a>';
				}
			}
			else
			{
				if ($current < 2 + ($adj * 2))
				{
					$pager .= ($current == 1) ? ('<span class="'.$spanClass.'">1</span>') : ('<a class="'.$aClass.'" href="'.$url.'/'.$param.'/'.(1).$urlSuffix.'">1</a>');
					
					for ($i = 2; $i < 4 + ($adj * 2); $i++)
					{
						if ($i == $current)
							$pager .= '<span class="'.$spanClass.'">'.$i.'</span>';
						else
							$pager .= '<a class="'.$aClass.'" href="'.$url.'/'.$param.'/'.($i).$urlSuffix.'">'.$i.'</a>';
					}
					$pager .= '<span class="'.$dotClass.'">...</span>';
					$pager .= '<a class="'.$aClass.'" href="'.$url.'/'.$param.'/'.($total-1).$urlSuffix.'">'.($total-1).'</a>';
					$pager .= '<a class="'.$aClass.'" href="'.$url.'/'.$param.'/'.($total).$urlSuffix.'">'.$total.'</a>';
				}
				else if ( (($adj * 2) + 1 < $current) && ($current < $total - ($adj * 2)) )
				{
					$pager .= '<a class="'.$aClass.'" href="'.$url.'/'.$param.'/'.(1).$urlSuffix.'">'.(1).'</a>';
					$pager .= '<a class="'.$aClass.'" href="'.$url.'/'.$param.'/'.(2).$urlSuffix.'">'.(2).'</a>';	
					$pager .= '<span class="'.$dotClass.'">...</span>';
					
					for ($i = $current - $adj; $i <= $current + $adj; $i++)
					{
						if ($i == $current)
							$pager .= '<span class="'.$spanClass.'">'.$i.'</span>';
						else
							$pager .= '<a class="'.$aClass.'" href="'.$url.'/'.$param.'/'.($i).$urlSuffix.'">'.$i.'</a>';
					}
					$pager .= '<span class="'.$dotClass.'">...</span>';
					$pager .= '<a class="'.$aClass.'" href="'.$url.'/'.$param.'/'.($total-1).$urlSuffix.'">'.($total-1).'</a>';
					$pager .= '<a class="'.$aClass.'" href="'.$url.'/'.$param.'/'.($total).$urlSuffix.'">'.$total.'</a>';
				}
				else
				{
					$pager .= '<a class="'.$aClass.'" href="'.$url.'/'.$param.'/'.(1).$urlSuffix.'">'.(1).'</a>';
					$pager .= '<a class="'.$aClass.'" href="'.$url.'/'.$param.'/'.(2).$urlSuffix.'">'.(2).'</a>';	
					$pager .= '<span class="'.$dotClass.'">...</span>';
								
					for ($i = $total - (2 + ($adj * 2)); $i <= $total; $i++)
					{
						if ($i == $current)
							$pager .= '<span class="'.$spanClass.'">'.$i.'</span>';
						else
							$pager .= '<a class="'.$aClass.'" href="'.$url.'/'.$param.'/'.($i).$urlSuffix.'">'.$i.'</a>';
					}
				}
			}
			
			if ($current < $total)
				$pager .= '<a class="'.$aClass.'" href="'.$url.'/'.$param.'/'.($current+1).$urlSuffix.'" >&gt;</a>';
		}		
		return $pager;
	}
	/**
	 * Count the number of objects of models
	 *	 
	 * @access public
	 * @param string $table the current table to list (default: empty => current model)
	 * @param array $joins the table(s) to join with current table (default: empty => no join)
	 * If you want to natural join: 
	 * <code>array("table_2","table_3","...","table_n")</code> will give 'SELECT * FROM table_1 NATURAL JOIN table_2 NATURAL JOIN table_3 ... NATURAL JOIN table_n'
	 * If you want to join with a specific column: 
	 * <code>array(0=>array("table"=>"table_2","column"=>"column_2"),1=>array("table"=>"table_3","column"=>"column_3"))</code>
	 * If you want to inner/left/right join:
	 * <code>array(0=>array("table"=>"table_2","column"=>"column_2","mode"=>"inner"),1=>array("table"=>"table_3","column"=>"column_3","mode"=>"left"))</code>
	 * @param array $clause the clause wanted (default: empty => no clause)
	 * <code>
	 * array
	 * (
	 *		[0] => array
	 *				(
	 *					["column"] = "column_1",
	 *					["value"] = "value_1", // or array('value1','value2','...','valueN') if "in" mode
	 *					["mode"] = "like" or "notlike" or "beginwith" or "endwith" or "equal" or "notequal" or "lt" or "le" or "ge" or "gt" or "null" or "notnull" or "in"
	 *				)
	 *		[1] => array
	 *				(
	 *					["column"] = "user_department",
	 *					["value"] = "75", // or array('value1','value2','...','valueN') if "in" mode
	 *					["mode"] = "like" or "notlike" or "beginwith" or "endwith" or "equal" or "notequal" or "lt" or "le" or "ge" or "gt" or "null" or "notnull" or "in"
	 *				)
	 * )
	 * </code>
	 * @param array $group a group by (default: empty => no group by)
	 * <code>array("column_1","column_2","...","column_n")</code>
	 * @return int $nbResults the number of objects within limit
	 * @see SLS_FrontModel::searchModels
	 * @since 1.0
	 */
	public function countModels($table,$joins=array(),$clause=array(),$group=array())
	{
		$allowToJoin = false;
		$modeJoin = "inner";
		$modesJoin = array("inner","left","right");
		$columns = array();
		
		/**
		 * TABLE NAME
		 */
		// If table name haven't been filled, try to recover table name from the current model
		if (empty($table))
		{
			$table = (empty($this->_table)) ? substr(get_class($this),0,strlen(get_class($this))-3) : $this->_table;
		}
		// If table name is again empty, throw a Sls Exception
		if (empty($table))
		{
			SLS_Tracing::addTrace(new Exception("Error: Table's name has been omitted"),true);
			return false;
		}
		// If model doesn't exists
		if ($this->_generic->useModel(SLS_String::tableToClass($table),$this->_db->getCurrentDb(),"user") || $this->_generic->useModel(SLS_String::tableToClass($table),$this->_db->getCurrentDb(),"sls"))
		{
			$className = ucfirst(strtolower($this->_db->getCurrentDb()))."_".SLS_String::tableToClass($table);
			$object = new $className();
			foreach($object->getParams() as $key => $value)
				array_push($columns,$key);
		}
		else
		{
			SLS_Tracing::addTrace(new Exception("Error: Table `".$table."` doesn't exist in database `".($this->_db->getCurrentDb())."`"),true);
			return false;
		}
		/**
		 * /TABLE NAME
		 */

		
		/**
		 * JOINS
		 */
		// Get all the columns of the current table
		$columnsMain = $columns;
		$joinMain = $table;
		
		// If we want to join tables
		if (is_array($joins) && !empty($joins))
		{
			// Foreach tables to join
			foreach ($joins as $currentJoin)
			{
				// If we want joins with the clause "using"
				if (is_array($currentJoin))
				{
					// Override join mode ?
					if (array_key_exists("mode",$currentJoin))					
						$modeJoin = (in_array(strtolower($currentJoin["mode"]),$modesJoin)) ? strtolower($currentJoin["mode"]) : array_shift($modesJoin);
				
					$currentJoin = $currentJoin["table"];
				}
				
				// If the table to join doesn't exists in MySQL, throw a Sls Exception
				if (!$this->_generic->useModel(SLS_String::tableToClass($currentJoin),$this->_db->getCurrentDb(),"user") && !$this->_generic->useModel(SLS_String::tableToClass($currentJoin),$this->_db->getCurrentDb(),"sls"))
					SLS_Tracing::addTrace(new Exception("Warning: Table `".$currentJoin."` to join with `".$joinMain."` doesn't exist in database `".(SLS_Generic::getInstance()->getDbConfig("base"))."`"),true);			
				// Else check if we can join
				else 
				{
					$className = ucfirst(strtolower($this->_db->getCurrentDb()))."_".SLS_String::tableToClass($currentJoin);
					$objectJoin = new $className();
					$columnsJoin = array();
					
					// Get all the columns of the table to join
					foreach($objectJoin->getParams() as $key => $value)
						array_push($columnsJoin,$key);
					
					// If we want joins with the clause "using", allow to join and merge the columns of the table to join with all the columns already listed
					if (is_array($currentJoin))
					{
						$allowToJoin = true;
						$columnsMain = array_merge($columnsMain,$columnsJoin);	
					}
					// Else if we want a "NATURAL JOIN", check if we have a common key
					else
					{
						// Foreach columns of the current table
						foreach($columnsMain as $tMain)
						{
							// Foreach columns of the table to join
							foreach($columnsJoin as $tJoin)
							{
								// If we have a common column, allow to join and merge the columns of the table to join with all the columns already listed
								if ($tJoin == $tMain)
								{
									$allowToJoin = true;
									$columnsMain = array_merge($columnsMain,$columnsJoin);
								}
							}
						}
					}
					
					// If we can't join, throw a Sls Exception
					if (!$allowToJoin)
					{
						SLS_Tracing::addTrace(new Exception("Warning: Table `".$currentJoin."` to join with `".$joinMain."` doesn't have a common key"),true);
						$joins = array();
						break;
					}
					
					// Move the reference table
					$joinMain = $currentJoin;
				}
			}
		}
		
		/**
		 * GROUP BY (COUNT DISTINCT group_column instead of *)
		 */
		// If we want a group by
		if (!empty($group) && is_array($group))
		{
			$groupSucceeded = false;
			$columnGroup = array_shift($group);
			// If column on which you want to apply a group by statement is in the list of columns collected on the tables
			$columnGroup = (SLS_String::contains($columnGroup,".")) ? SLS_String::substrAfterLastDelimiter($columnGroup,".") : $columnGroup;
			if (in_array($columnGroup,$columnsMain))
			{
				if (SLS_String::contains($columnGroup,"."))
					$columnGroup = "`".SLS_String::substrBeforeLastDelimiter($columnGroup,".")."`"."."."`".SLS_String::substrAfterLastDelimiter($columnGroup,".")."`";
				else
					$columnGroup = "`".$columnGroup."`";
				
				$groupSucceeded = true;
			}
			// Else, throw a Sls Exception
			else
				SLS_Tracing::addTrace(new Exception("Warning: Column `".$columnGroup."` in group by statement doesn't exist in table `".$table."` (and collected tables to join)"),true);
		}
		/**
		 * /GROUP BY
		 */
		
		// Build the start of the query
		$sql .= "SELECT COUNT(".(($groupSucceeded) ? "DISTINCT(".$columnGroup.") " : "*").") AS total FROM `".$table."` ";
				
		// If we can join, build the join
		if ($allowToJoin && is_array($joins) && !empty($joins))
		{
			foreach ($joins as $currentJoin)
			{
				if (is_array($currentJoin))
					$sql .= strtoupper($modeJoin)." JOIN "."\n".
					"    `".$currentJoin["table"]."` USING(".$currentJoin["column"].") ";
				else
					$sql .= "NATURAL JOIN "."\n".
					"    `".$currentJoin."` ";
			}
		}
		/**
		 * /JOINS
		 */
				
		
		/**
		 * CLAUSE
		 */
		// If we want a clause where
		if (!empty($clause))
		{			
			$lastSucceeded = false;
			// Foreach items to restrict
			for($i=0 ; $i<count($clause) ; $i++)
			{
				// If column on which you want to apply a restrict clause is in the list of columns collected on the tables
				$columnName = (SLS_String::contains($clause[$i]["column"],".")) ? SLS_String::substrAfterLastDelimiter($clause[$i]["column"],".") : $clause[$i]["column"];				
				if (in_array($columnName,$columnsMain))
				{
					$sql .= ($lastSucceeded) ? " AND " : " WHERE ";
					
					// Build the correct statement
					if (SLS_String::contains($clause[$i]["column"],"."))
						$clause[$i]["column"] = "`".SLS_String::substrBeforeLastDelimiter($clause[$i]["column"],".")."`"."."."`".SLS_String::substrAfterLastDelimiter($clause[$i]["column"],".")."`";
					else
						$clause[$i]["column"] = "`".$clause[$i]["column"]."`";
						
					switch($clause[$i]["mode"])
					{
						case "like":
							$sql .= ("LOWER(".$clause[$i]["column"].") LIKE ".$this->_db->quote("%".strtolower($clause[$i]["value"])."%"));
							break;
						case "notlike":
							$sql .= ("LOWER(".$clause[$i]["column"].") NOT LIKE ".$this->_db->quote("%".strtolower($clause[$i]["value"])."%"));
							break;							
						case "beginwith":
							$sql .= ("LOWER(".$clause[$i]["column"].") LIKE ".$this->_db->quote(strtolower($clause[$i]["value"])."%"));
							break;
						case "endwith":
							$sql .= ("LOWER(".$clause[$i]["column"].") LIKE ".$this->_db->quote("%".strtolower($clause[$i]["value"])));
							break;
						case "equal":
							$sql .= ("".$clause[$i]["column"]." = ".$this->_db->quote($clause[$i]["value"]));	
							break;
						case "notequal":
							$sql .= ("".$clause[$i]["column"]." != ".$this->_db->quote($clause[$i]["value"]));	
							break;
						case "lt":
							$sql .= ("".$clause[$i]["column"]." < ".$this->_db->quote($clause[$i]["value"]));
							break;
						case "le":
							$sql .= ("".$clause[$i]["column"]." <= ".$this->_db->quote($clause[$i]["value"]));
							break;
						case "ge":
							$sql .= ("".$clause[$i]["column"]." >= ".$this->_db->quote($clause[$i]["value"]));
							break;
						case "gt":
							$sql .= ("".$clause[$i]["column"]." > ".$this->_db->quote($clause[$i]["value"]));
							break;
						case "null":
							$sql .= ("".$clause[$i]["column"]." IS NULL ");
							break;
						case "notnull":
							$sql .= ("".$clause[$i]["column"]." IS NOT NULL ");
							break;
						case "in":
							$clause[$i]["value"] = (is_array($clause[$i]["value"])) ? array_map(array($this->_db, 'quote'),$clause[$i]["value"]) : $clause[$i]["value"];
							$sql .= ("".$clause[$i]["column"]." IN (".((is_array($clause[$i]["value"]) ? implode(",",$clause[$i]["value"]) : $this->_db->quote($clause[$i]["value"]))).") ");
							break;
						case "notin":
							$clause[$i]["value"] = (is_array($clause[$i]["value"])) ? array_map(array($this->_db, 'quote'),$clause[$i]["value"]) : $clause[$i]["value"];
							$sql .= ("    ".$clause[$i]["column"]." NOT IN (".((is_array($clause[$i]["value"]) ? implode(",",$clause[$i]["value"]) : $this->_db->quote($clause[$i]["value"]))).") ");
							break;
						default:
							$sql .= ("LOWER(".$clause[$i]["column"].") LIKE ".$this->_db->quote("%".strtolower($clause[$i]["value"])."%"));
							break;
					}						
					$lastSucceeded = true;
				}
				// Else, throw a Sls Exception
				else
					SLS_Tracing::addTrace(new Exception("Warning: Column ".$clause[$i]["column"]." in clause where doesn't exist in table `".$table."` (and collected tables to join)"),true);
			}
		}
		/**
		 * /CLAUSE
		 */
		
		
		// Try to execute the built query
		try
		{			
	        $result =  array_shift($this->_db->select($sql));
	        return $result->total;
		}
		catch (Exception $e)
		{			
			SLS_Tracing::addTrace($e,true);
			return false;
		}
	}
	/**
	 * Read recursively path & sub-paths to include components files used by currect action controller
	 *
	 * @access private
	 * @param string $path the root path
	 * @param string $type the type ('core' || 'user')
	 * @since 1.0
	 */
	private function recursiveStaticLoading($path, $type)
	{
		$controllersXML = $this->_generic->getControllersXML();
		
		if ($this->_isCache)
		{			
			$staticsHandle = file_get_contents($this->_generic->getPathConfig("configSecure")."cache.xml");
			$xmlCache = new SLS_XMLToolbox($staticsHandle);	
			$files = $xmlCache->getTags("//components/".$type."/controller/file");
			$names = $xmlCache->getTags("//components/".$type."/controller/name");
			for($i=0;$i<count($files);$i++)
			{				
				$components = array_shift($controllersXML->getTagsAttributes("//controllers/controller/scontrollers/scontroller[@id='".$this->_generic->getActionId()."']",array("components")));				
				if (!empty($components))
				{
					$components = explode(",",$components["attributes"][0]["value"]);
					$components = array_map("trim",$components);
					$components = array_map("strtolower",$components);					
				}
				else
					$components = array();
				
				if (empty($components) || in_array(strtolower(trim(SLS_String::substrBeforeFirstDelimiter(SLS_String::substrAfterLastDelimiter($names[$i], "/"), "Controller"))),$components))
				{
					$this->_generic->_time_checkpoint = microtime(true);
					include_once($this->_generic->getRoot().$files[$i]);
					$name = $names[$i];
					$xml = "";
					
					// Component cache enabled ?
					$componentsName = strtolower(SLS_String::substrBeforeFirstDelimiter($name,"Controller"));					
					$componentsCacheVisibility = $this->_cache->getObject($componentsName,"components","visibility");
					$componentsCacheResponsive = $this->_cache->getObject($componentsName,"components","responsive");
					$componentsCacheExpiration = $this->_cache->getObject($componentsName,"components","expire");					
					$componentsCache = false;					
					
					if ($this->_generic->getSide() == "user" &&
						$this->_generic->getGenericControllerName() != "Default" &&
						!$this->_generic->isBo() && 
						in_array($componentsCacheVisibility,array("public","private")))
					{
						$componentsCache = true;
						
						// Partial xml cached
						if (false !== ($componentsCached = $this->_cache->getCachePartial($componentsCacheExpiration,"component",$componentsName,$componentsCacheVisibility,$componentsCacheResponsive)))
						{				
							$xml = $componentsCached;
							$this->_generic->logTime($this->_generic->monitor($this->_generic->_time_checkpoint),"Cache (Partial): Executing Component Controller", "Controller: ".SLS_String::substrBeforeLastDelimiter($name,"Controller"),"Controller Component");
						}
					}
					
					if (empty($xml))
					{					
						$classObj = new $name();
						$xml = $classObj->getXML();
						$this->_generic->logTime($this->_generic->monitor($this->_generic->_time_checkpoint),"Executing Component Controller", "Controller: ".SLS_String::substrBeforeLastDelimiter($name,"Controller"),"Controller Component");
						
						// Save partial xml component cache
						if ($componentsCache)						
							$this->_cache->saveCachePartial($xml,"component",$componentsName,$componentsCacheVisibility,$componentsCacheResponsive);						
					}
					
					$this->_xmlToolBox->appendXMLNode("//Components/".$type, $xml);					
				}				
			}
		}
		else 
		{
			$searchedExt = array('php');
			$arrayResult = array();
			$arrayResult = $this->_generic->recursiveReadDir($path, $arrayResult, $searchedExt);
			
			$this->_cacheXML->startTag($type);
			for($i=0;$i<$count = count($arrayResult);$i++)
			{
				$components = array_shift($controllersXML->getTagsAttributes("//controllers/controller/scontrollers/scontroller[@id='".$this->_generic->getActionId()."']",array("components")));
				if (!empty($components))
				{
					$components = explode(",",$components["attributes"][0]["value"]);
					$components = array_map("trim",$components);
					$components = array_map("strtolower",$components);					
				}
				else
					$components = array();
				
				$this->_cacheXML->startTag("controller");				
				include_once($arrayResult[$i]);
				$componentName = array_shift(explode(".", SLS_String::substrAfterLastDelimiter($arrayResult[$i], "/")))."Controller";
				
				if (class_exists($componentName))
				{
					$this->_cacheXML->addFullTag("file", $arrayResult[$i], true);
					$this->_cacheXML->addFullTag("name", $componentName, true);
					if (empty($components) || in_array(strtolower(trim(SLS_String::substrBeforeFirstDelimiter(SLS_String::substrAfterLastDelimiter($arrayResult[$i], "/"), ".controller.php"))),$components))
					{
						$this->_generic->_time_checkpoint = microtime(true);
						$classObj = new $componentName();						
						$this->_xmlToolBox->appendXMLNode("//Components/".$type, $classObj->getXML());
						$this->_generic->logTime($this->_generic->monitor($this->_generic->_time_checkpoint),"Executing Component Controller", "Controller: ".SLS_String::substrBeforeLastDelimiter($componentName,"Controller"),"Controller Component");
					}
				}
				$this->_cacheXML->endTag("controller");
			}
			$this->_cacheXML->endTag($type);				
		}
	}
	/**
	 * Construct the XML
	 *
	 * @access public
	 * @since 1.0
	 */
	public function constructXML()
	{
		$this->_cacheXML = new SLS_XMLToolbox(false);
		$this->_cacheActive = $this->_generic->isCache();			
		$this->_xmlToolBox->startTag("XslStatics");
		
		// Recover path of Statics Unloaded
		#$dirStaticsUnloaded = $this->_generic->getPathConfig("viewsGenericsUnloaded");
		$dirStaticsUnloaded = $this->_generic->getPathConfig("viewsGenerics");
		// Recover path of Statics Loaded Body
		#$dirStaticsLoadedBody = $this->_generic->getPathConfig("viewsGenericsLoadedBody");
		// Recover path of Statics Loaded Headers
		#$dirStaticsLoadedHeaders = $this->_generic->getPathConfig("viewsGenericsLoadedHeaders");
		
		// Recover path of SLS Statics Unloaded
		$dirSlsStaticsUnloaded = $this->_generic->getPathConfig("slsViewsGenericsUnloaded");
		// Recover path of SLS Statics Loaded Body
		$dirSlsStaticsLoadedBody = $this->_generic->getPathConfig("slsViewsGenericsLoadedBody");
		// Recover path of SLS Statics Loaded Headers
		$dirSlsStaticsLoadedHeaders = $this->_generic->getPathConfig("slsViewsGenericsLoadedHeaders");
		
		// Recover path of Core Statics Unloaded
		$dirCoreStaticsUnloaded = $this->_generic->getPathConfig("coreViewsGenericsUnloaded");
		// Recover path of Core Statics Loaded Body
		$dirCoreStaticsLoadedBody = $this->_generic->getPathConfig("coreViewsGenericsLoadedBody");
		// Recover path of Core Statics Loaded Headers
		$dirCoreStaticsLoadedHeaders = $this->_generic->getPathConfig("coreViewsGenericsLoadedHeaders");
				
		$xslHandle = file_get_contents($this->_generic->getPathConfig("configSecure")."cache.xml");
		
		// If cache not active
		if (!$this->_cacheActive)
		{						
			$this->_xmlToolBox->startTag("files");
			$this->_cacheXML->startTag("xsls");
			$this->_cacheXML->startTag("files");			
			// Put in cache.xml User Unloaded Files but in current XML only if side == 'user'
			($this->_generic->getSide() == "user") ? $this->_xmlToolBox->startTag("Unloaded") : "";
			$this->_cacheXML->startTag("Unloaded");				
				$this->_arrayStatics['unloaded']['templateName'] = array();
				$this->_arrayStatics['unloaded']['path'] = array();
				$this->_arrayStatics['unloaded']['filename'] = array();				
				$this->recursiveRead($dirStaticsUnloaded, false, $this->_arrayStatics['unloaded']['templateName'], $this->_arrayStatics['unloaded']['path'], $this->_arrayStatics['unloaded']['filename']);								
				array_multisort($this->_arrayStatics['unloaded']['filename'], SORT_ASC, SORT_STRING, $this->_arrayStatics['unloaded']['path'], SORT_ASC, SORT_STRING);				
				for($i=0;$i<count($this->_arrayStatics['unloaded']['filename']);$i++)
				{
					$this->_cacheXML->startTag("xsl");
					($this->_generic->getSide() == "user") ? $this->_xmlToolBox->startTag("xsl") : "";						
						($this->_generic->getSide() == "user") ? $this->_xmlToolBox->addFullTag("file", $this->_arrayStatics['unloaded']['path'][$i], true) : "";
						$this->_cacheXML->addFullTag("file", $this->_arrayStatics['unloaded']['path'][$i], true);					
					($this->_generic->getSide() == "user") ? $this->_xmlToolBox->endTag("xsl") : "";
					$this->_cacheXML->endTag("xsl");
				}				
				unset($this->_arrayStatics['unloaded']);
			$this->_cacheXML->endTag("Unloaded");
			($this->_generic->getSide() == "user") ? $this->_xmlToolBox->endTag("Unloaded") : "";	
			
			// Put in cache.xml the SLS Unloaded Files but in current XML only if side == 'sls'
			($this->_generic->getSide() == "sls") ? $this->_xmlToolBox->startTag("Unloaded") : "";
			$this->_cacheXML->startTag("SlsUnloaded");				
				$this->_arrayStatics['unloaded']['templateName'] = array();
				$this->_arrayStatics['unloaded']['path'] = array();
				$this->_arrayStatics['unloaded']['filename'] = array();				
				$this->recursiveRead($dirSlsStaticsUnloaded, false, $this->_arrayStatics['unloaded']['templateName'], $this->_arrayStatics['unloaded']['path'], $this->_arrayStatics['unloaded']['filename']);				
				array_multisort($this->_arrayStatics['unloaded']['filename'], SORT_ASC, SORT_STRING, $this->_arrayStatics['unloaded']['path'], SORT_ASC, SORT_STRING);
				for($i=0;$i<count($this->_arrayStatics['unloaded']['filename']);$i++)
				{
					$this->_cacheXML->startTag("xsl");
					($this->_generic->getSide() == "sls") ? $this->_xmlToolBox->startTag("xsl") : "";						
						($this->_generic->getSide() == "sls") ? $this->_xmlToolBox->addFullTag("file", $this->_arrayStatics['unloaded']['path'][$i], true) : "";
						$this->_cacheXML->addFullTag("file", $this->_arrayStatics['unloaded']['path'][$i], true);					
					($this->_generic->getSide() == "sls") ? $this->_xmlToolBox->endTag("xsl") : "";
					$this->_cacheXML->endTag("xsl");
				}				
				unset($this->_arrayStatics['unloaded']);
			$this->_cacheXML->endTag("SlsUnloaded");
			($this->_generic->getSide() == "sls") ? $this->_xmlToolBox->endTag("Unloaded") : "";
			
			// Put in cache.xml the Core Unloaded Files &&t in current XML
			$this->_xmlToolBox->startTag("CoreUnloaded");
			$this->_cacheXML->startTag("CoreUnloaded");				
				$this->_arrayStatics['unloaded']['templateName'] = array();
				$this->_arrayStatics['unloaded']['path'] = array();
				$this->_arrayStatics['unloaded']['filename'] = array();				
				$this->recursiveRead($dirCoreStaticsUnloaded, false, $this->_arrayStatics['unloaded']['templateName'], $this->_arrayStatics['unloaded']['path'], $this->_arrayStatics['unloaded']['filename']);				
				array_multisort($this->_arrayStatics['unloaded']['filename'], SORT_ASC, SORT_STRING, $this->_arrayStatics['unloaded']['path'], SORT_ASC, SORT_STRING);
				for($i=0;$i<count($this->_arrayStatics['unloaded']['filename']);$i++)
				{
					$this->_cacheXML->startTag("xsl");
					$this->_xmlToolBox->startTag("xsl");						
						$this->_xmlToolBox->addFullTag("file", $this->_arrayStatics['unloaded']['path'][$i], true);
						$this->_cacheXML->addFullTag("file", $this->_arrayStatics['unloaded']['path'][$i], true);					
					$this->_xmlToolBox->endTag("xsl");
					$this->_cacheXML->endTag("xsl");
				}				
				unset($this->_arrayStatics['unloaded']);
			$this->_cacheXML->endTag("CoreUnloaded");
			$this->_xmlToolBox->endTag("CoreUnloaded");	
			
			// Put in cache.xml the User loaded Body Files but in current XML only if side == user
			($this->_generic->getSide() == "user") ? $this->_xmlToolBox->startTag("Loaded") : "";
			$this->_cacheXML->startTag("Loaded");
				/*($this->_generic->getSide() == "user") ? $this->_xmlToolBox->startTag("Body") : "";
				$this->_cacheXML->startTag("Body");
					$this->_arrayStatics['loadedBody']['templateName'] = array();
					$this->_arrayStatics['loadedBody']['path'] = array();
					$this->_arrayStatics['loadedBody']['filename'] = array();
				$this->recursiveRead($dirStaticsLoadedBody, true, $this->_arrayStatics['loadedBody']['templateName'], $this->_arrayStatics['loadedBody']['path'], $this->_arrayStatics['loadedBody']['filename']);					
				array_multisort($this->_arrayStatics['loadedBody']['filename'], SORT_ASC, SORT_STRING, $this->_arrayStatics['loadedBody']['path'], SORT_ASC, SORT_STRING, $this->_arrayStatics['loadedBody']['templateName'], SORT_ASC, SORT_STRING);
				for($i=0;$i<count($this->_arrayStatics['loadedBody']['filename']);$i++)
				{
					$this->_cacheXML->startTag("xsl");
					($this->_generic->getSide() == "user") ? $this->_xmlToolBox->startTag("xsl") : "";
						($this->_generic->getSide() == "user") ? $this->_xmlToolBox->addFullTag("file", $this->_arrayStatics['loadedBody']['path'][$i], true) : "";
						$this->_cacheXML->addFullTag("file", $this->_arrayStatics['loadedBody']['path'][$i], true);
						($this->_generic->getSide() == "user") ? $this->_xmlToolBox->addFullTag("templateName", $this->_arrayStatics['loadedBody']['templateName'][$i], true) : "";
						$this->_cacheXML->addFullTag("templateName", $this->_arrayStatics['loadedBody']['templateName'][$i], true);						
					($this->_generic->getSide() == "user") ? $this->_xmlToolBox->endTag("xsl") : "";
					$this->_cacheXML->endTag("xsl");
				}
				unset($this->_arrayStatics['loadedBody']);				
				$this->_cacheXML->endTag("Body");
				($this->_generic->getSide() == "user") ?$this->_xmlToolBox->endTag("Body") : "";*/

				// Put in cache.xml the Sls loaded Body Files but in current XML only if side == sls
				($this->_generic->getSide() == "sls") ? $this->_xmlToolBox->startTag("Loaded") : "";
				/*($this->_generic->getSide() == "sls") ? $this->_xmlToolBox->startTag("Body") : "";
				$this->_cacheXML->startTag("SlsBody");
					$this->_arrayStatics['loadedBody']['templateName'] = array();
					$this->_arrayStatics['loadedBody']['path'] = array();
					$this->_arrayStatics['loadedBody']['filename'] = array();
				$this->recursiveRead($dirStaticsLoadedBody, true, $this->_arrayStatics['loadedBody']['templateName'], $this->_arrayStatics['loadedBody']['path'], $this->_arrayStatics['loadedBody']['filename']);					
				array_multisort($this->_arrayStatics['loadedBody']['filename'], SORT_ASC, SORT_STRING, $this->_arrayStatics['loadedBody']['path'], SORT_ASC, SORT_STRING, $this->_arrayStatics['loadedBody']['templateName'], SORT_ASC, SORT_STRING);
				for($i=0;$i<count($this->_arrayStatics['loadedBody']['filename']);$i++)
				{
					$this->_cacheXML->startTag("xsl");
					($this->_generic->getSide() == "sls") ? $this->_xmlToolBox->startTag("xsl") : "";
						($this->_generic->getSide() == "sls") ? $this->_xmlToolBox->addFullTag("file", $this->_arrayStatics['loadedBody']['path'][$i], true) : "";
						$this->_cacheXML->addFullTag("file", $this->_arrayStatics['loadedBody']['path'][$i], true);
						($this->_generic->getSide() == "sls") ? $this->_xmlToolBox->addFullTag("templateName", $this->_arrayStatics['loadedBody']['templateName'][$i], true) : "";
						$this->_cacheXML->addFullTag("templateName", $this->_arrayStatics['loadedBody']['templateName'][$i], true);						
					($this->_generic->getSide() == "sls") ? $this->_xmlToolBox->endTag("xsl") : "";
					$this->_cacheXML->endTag("xsl");
				}
				unset($this->_arrayStatics['loadedBody']);				
				$this->_cacheXML->endTag("SlsBody");
				($this->_generic->getSide() == "sls") ? $this->_xmlToolBox->endTag("Body") : "";*/	
				
				// Put in cache.xml the Core loaded Body Files && in current XML
				$this->_xmlToolBox->startTag("CoreBody");
				$this->_cacheXML->startTag("CoreBody");
					$this->_arrayStatics['loadedBody']['templateName'] = array();
					$this->_arrayStatics['loadedBody']['path'] = array();
					$this->_arrayStatics['loadedBody']['filename'] = array();
				$this->recursiveRead($dirCoreStaticsLoadedBody, true, $this->_arrayStatics['loadedBody']['templateName'], $this->_arrayStatics['loadedBody']['path'], $this->_arrayStatics['loadedBody']['filename']);					
				array_multisort($this->_arrayStatics['loadedBody']['filename'], SORT_ASC, SORT_STRING, $this->_arrayStatics['loadedBody']['path'], SORT_ASC, SORT_STRING, $this->_arrayStatics['loadedBody']['templateName'], SORT_ASC, SORT_STRING);
				for($i=0;$i<count($this->_arrayStatics['loadedBody']['filename']);$i++)
				{
					$this->_cacheXML->startTag("xsl");
					$this->_xmlToolBox->startTag("xsl");						
						$this->_xmlToolBox->addFullTag("file", $this->_arrayStatics['loadedBody']['path'][$i], true);
						$this->_cacheXML->addFullTag("file", $this->_arrayStatics['loadedBody']['path'][$i], true);
						$this->_xmlToolBox->addFullTag("templateName", $this->_arrayStatics['loadedBody']['templateName'][$i], true);
						$this->_cacheXML->addFullTag("templateName", $this->_arrayStatics['loadedBody']['templateName'][$i], true);						
					$this->_xmlToolBox->endTag("xsl");
					$this->_cacheXML->endTag("xsl");
				}
				unset($this->_arrayStatics['loadedBody']);					
				$this->_cacheXML->endTag("CoreBody");
				$this->_xmlToolBox->endTag("CoreBody");	
				
				// Put in cache.xml the User loaded Headers Files but in current XML only if side == user
				/*($this->_generic->getSide() == "user") ? $this->_xmlToolBox->startTag("Headers") : "";
				$this->_cacheXML->startTag("Headers");
					$this->_arrayStatics['loadedHeaders']['templateName'] = array();
					$this->_arrayStatics['loadedHeaders']['path'] = array();
					$this->_arrayStatics['loadedHeaders']['filename'] = array();
					$this->recursiveRead($dirStaticsLoadedHeaders, true, $this->_arrayStatics['loadedHeaders']['templateName'], $this->_arrayStatics['loadedHeaders']['path'], $this->_arrayStatics['loadedHeaders']['filename']);					
					array_multisort($this->_arrayStatics['loadedHeaders']['filename'], SORT_ASC, SORT_STRING, $this->_arrayStatics['loadedHeaders']['path'], SORT_ASC, SORT_STRING, $this->_arrayStatics['loadedHeaders']['templateName'], SORT_ASC, SORT_STRING);
				for($i=0;$i<count($this->_arrayStatics['loadedHeaders']['filename']);$i++)
				{
					$this->_cacheXML->startTag("xsl");
					($this->_generic->getSide() == "user") ? $this->_xmlToolBox->startTag("xsl") : "";						
						($this->_generic->getSide() == "user") ? $this->_xmlToolBox->addFullTag("file", $this->_arrayStatics['loadedHeaders']['path'][$i], true) : "";
						$this->_cacheXML->addFullTag("file", $this->_arrayStatics['loadedHeaders']['path'][$i], true);
						($this->_generic->getSide() == "user") ? $this->_xmlToolBox->addFullTag("templateName", $this->_arrayStatics['loadedHeaders']['templateName'][$i], true) : "";
						$this->_cacheXML->addFullTag("templateName", $this->_arrayStatics['loadedHeaders']['templateName'][$i], true);						
					($this->_generic->getSide() == "user") ? $this->_xmlToolBox->endTag("xsl") : "";
					$this->_cacheXML->endTag("xsl");
				}
				unset($this->_arrayStatics['loadedHeaders']);
				$this->_cacheXML->endTag("Headers");				
				($this->_generic->getSide() == "user") ? $this->_xmlToolBox->endTag("Headers") : "";
				
				// Put in cache.xml the Sls loaded Headers Files but in current XML only if side == sls
				/*($this->_generic->getSide() == "sls") ? $this->_xmlToolBox->startTag("Headers") : "";
				$this->_cacheXML->startTag("SlsHeaders");
					$this->_arrayStatics['loadedHeaders']['templateName'] = array();
					$this->_arrayStatics['loadedHeaders']['path'] = array();
					$this->_arrayStatics['loadedHeaders']['filename'] = array();
					$this->recursiveRead($dirStaticsLoadedHeaders, true, $this->_arrayStatics['loadedHeaders']['templateName'], $this->_arrayStatics['loadedHeaders']['path'], $this->_arrayStatics['loadedHeaders']['filename']);					
					array_multisort($this->_arrayStatics['loadedHeaders']['filename'], SORT_ASC, SORT_STRING, $this->_arrayStatics['loadedHeaders']['path'], SORT_ASC, SORT_STRING, $this->_arrayStatics['loadedHeaders']['templateName'], SORT_ASC, SORT_STRING);
				for($i=0;$i<count($this->_arrayStatics['loadedHeaders']['filename']);$i++)
				{
					$this->_cacheXML->startTag("xsl");
					($this->_generic->getSide() == "sls") ? $this->_xmlToolBox->startTag("xsl") : "";						
						($this->_generic->getSide() == "sls") ? $this->_xmlToolBox->addFullTag("file", $this->_arrayStatics['loadedHeaders']['path'][$i], true) : "";
						$this->_cacheXML->addFullTag("file", $this->_arrayStatics['loadedHeaders']['path'][$i], true);
						($this->_generic->getSide() == "sls") ? $this->_xmlToolBox->addFullTag("templateName", $this->_arrayStatics['loadedHeaders']['templateName'][$i], true) : "";
						$this->_cacheXML->addFullTag("templateName", $this->_arrayStatics['loadedHeaders']['templateName'][$i], true);						
					($this->_generic->getSide() == "sls") ? $this->_xmlToolBox->endTag("xsl") : "";
					$this->_cacheXML->endTag("xsl");
				}
				unset($this->_arrayStatics['loadedHeaders']);
				$this->_cacheXML->endTag("SlsHeaders");
				($this->_generic->getSide() == "sls") ? $this->_xmlToolBox->endTag("Headers") : "";*/
				
				// Put in cache.xml the Core loaded Headers Files && in current XML
				$this->_xmlToolBox->startTag("CoreHeaders");
				$this->_cacheXML->startTag("CoreHeaders");
					$this->_arrayStatics['loadedHeaders']['templateName'] = array();
					$this->_arrayStatics['loadedHeaders']['path'] = array();
					$this->_arrayStatics['loadedHeaders']['filename'] = array();
					$this->recursiveRead($dirCoreStaticsLoadedHeaders, true, $this->_arrayStatics['loadedHeaders']['templateName'], $this->_arrayStatics['loadedHeaders']['path'], $this->_arrayStatics['loadedHeaders']['filename']);					
					array_multisort($this->_arrayStatics['loadedHeaders']['filename'], SORT_ASC, SORT_STRING, $this->_arrayStatics['loadedHeaders']['path'], SORT_ASC, SORT_STRING, $this->_arrayStatics['loadedHeaders']['templateName'], SORT_ASC, SORT_STRING);
				for($i=0;$i<count($this->_arrayStatics['loadedHeaders']['filename']);$i++)
				{
					$this->_cacheXML->startTag("xsl");
					$this->_xmlToolBox->startTag("xsl");						
						$this->_xmlToolBox->addFullTag("file", $this->_arrayStatics['loadedHeaders']['path'][$i], true);
						$this->_cacheXML->addFullTag("file", $this->_arrayStatics['loadedHeaders']['path'][$i], true);
						$this->_xmlToolBox->addFullTag("templateName", $this->_arrayStatics['loadedHeaders']['templateName'][$i], true);
						$this->_cacheXML->addFullTag("templateName", $this->_arrayStatics['loadedHeaders']['templateName'][$i], true);						
					$this->_xmlToolBox->endTag("xsl");
					$this->_cacheXML->endTag("xsl");
				}
				unset($this->_arrayStatics['loadedHeaders']);	
				$this->_cacheXML->endTag("CoreHeaders");
				$this->_xmlToolBox->endTag("CoreHeaders");
				
			$this->_cacheXML->endTag("Loaded");
			$this->_xmlToolBox->endTag("Loaded");
			$this->_cacheXML->endTag("files");
			$this->_xmlToolBox->endTag("files");
			$this->_cacheXML->endTag("xsls");
			$writeXML = new SLS_XMLToolbox($xslHandle);
			$writeXML->overwriteTags("//statics", $this->_cacheXML->getXML());
			$writeXML->saveXML($this->_generic->getPathConfig("configSecure")."cache.xml");			
		}
		else 		
			$this->_xmlToolBox->addValue(SLS_String::substrAfterFirstDelimiter(SLS_String::substrBeforeLastDelimiter($xslHandle, "</xsls>"), "<xsls>"));
		
		$this->_xmlToolBox->endTag("XslStatics");
	}
	/**
	 * Set the title of the current page
	 *
	 * @access protected
	 * @param string $title the title of the current page
	 * @param bool $incremental true to add a new one, false to overwrite
	 * @see SLS_GenericController::setMetaRobots
	 * @see SLS_GenericController::setMetaAuthor
	 * @see SLS_GenericController::setMetaCopyright
	 * @see SLS_GenericController::setMetaKeywords
	 * @see SLS_GenericController::setMetaDescription
	 * @since 1.0
	 */
	protected function setMetaTitle($title="", $incremental=false)
	{
		if (empty($title))
		{
			// Try to recover title from metas.xml			
			$currentTitle = array_shift($this->_generic->getCoreXML('metas')->getTags("//sls_configs/action[@id='".$this->_generic->getActionId()."']/title[@lang='".$this->_generic->getObjectLang()->getLang()."']"));
			if (!empty($currentTitle))
				$this->_pageTitle = $currentTitle." | ".$this->_generic->getSiteConfig("projectName");
			
			// Else, recover title from Controller & Action names
			else 
			{
				if ($this->_generic->getSiteConfig('isInstall') == 1)
				{
					$currentTitle = array_shift($this->_generic->getControllersXML()->getTags("//controllers/controller[@name='".$this->_generic->getGenericControllerName()."']/scontrollers/scontroller[@name='".$this->_generic->getGenericScontrollerName()."']/scontrollerLangs/scontrollerLang[@lang='".$this->_generic->getObjectLang()->getLang()."']/@title"));
					if (!empty($currentTitle))
						$this->_pageTitle = $currentTitle." | ".$this->_generic->getSiteConfig("projectName");
				}
				else 
				{
					$controllers = $this->_generic->getTranslatedController($this->_generic->getGenericControllerName(), $this->_generic->getGenericScontrollerName());
					$this->_pageTitle = $controllers['controller']." - ".$controllers['scontroller']." | ".$this->_generic->getSiteConfig("projectName");
				}
			}
		}
		else
		{
			if ($incremental === false)
			{
				$this->_pageTitle = $title;
				if (!SLS_String::endsWith($this->_pageTitle," | ".$this->_generic->getSiteConfig("projectName")))
					$this->_pageTitle .= " | ".$this->_generic->getSiteConfig("projectName");
			}
			else
			{
				if (SLS_String::endsWith($this->_pageTitle," | ".$this->_generic->getSiteConfig("projectName")))
					$this->_pageTitle = SLS_String::substrBeforeLastDelimiter($this->_pageTitle," | ".$this->_generic->getSiteConfig("projectName"))." ".$title." | ".$this->_generic->getSiteConfig("projectName");
				else
				{
					$this->_pageTitle .= " ".$title;
					if (!SLS_String::endsWith($this->_pageTitle," | ".$this->_generic->getSiteConfig("projectName")))
						$this->_pageTitle .= " | ".$this->_generic->getSiteConfig("projectName");
				}
			}
		}
	}
	/**
	 * Get columns of a given table
	 * 
	 * @param string $db the db alias of the table
	 * @param string $table the wanted table you want to extract columns infos
	 * @param string $boPath xPath of the table in bo.xml
	 * @param string $classFather the father model (if children)
	 * @param bool $needPk if you want primary_key
	 * @param bool $needBoSettings if you want bo listing privileges (list|edit|filter)
	 * @return array $columns columns of the table
	 */
	public function getTableColumns($db,$table,$boPath="",$classFather="",$needPk=false,$needBoSettings=false)
	{
		$infosTable = $this->_db->showColumns($table);
		$isMultilanguage = false; 
		$uniquesMultilang = array();
		$columns = array();
		foreach((is_array($infosTable)) ? $infosTable : array($infosTable) as $infoTable)
		{
			if ($infoTable->Key == "PRI" && $infoTable->Field == "pk_lang")
			{
				$isMultilanguage = true;
				break;
			}
		}
		
		// Show create table
		if ($isMultilanguage)
		{
			$create = array_shift($this->_db->select("SHOW CREATE TABLE `".$table."`"));
			$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 columns
		if (is_array($infosTable))
		{
			foreach($infosTable as $infoTable)
			{
				$pk = "false";
				
				// Switch primary keys
				if ($infoTable->Key == "PRI")
				{
					if (!$needPk)
						continue;
					else
						$pk = "true";
				}
				
				// Column
				$column = array("db" 						=> $db,
								"table" 					=> $table,
								"name" 						=> $infoTable->Field,
								"pk" 						=> $pk,
								"label" 					=> $infoTable->Field,
								"multilanguage" 			=> ($this->_object->isMultilanguage()) ? "true" : "false",
								"native_type" 				=> "string",
								"html_type" 				=> "input_text",
								"specific_type" 			=> "",
								"specific_type_extended" 	=> "",
								"file_uid"					=> uniqid(),
								"image_ratio" 				=> "*",
								"image_thumb"				=> "",
								"image_min_width" 			=> "*",
								"image_min_height" 			=> "*",
								"html" 						=> "false",
								"choices" 					=> array(),	
								"values" 					=> (empty($classFather)) ? $this->_langsValues : array(),
								"errors" 					=> array(),
								"required" 					=> "true",
								"unique" 					=> "false",				
								"default" 					=> "",
								"ac_db" 					=> "",
								"ac_entity" 				=> "",
								"ac_fk"						=> "",
								"ac_column" 				=> "",
								"ac_label" 					=> "",
								"ac_pattern" 				=> "",
								"ac_multiple" 				=> "",
								"min_length" 				=> "",
								"max_length" 				=> "",
								"filters" 					=> "");
				if ($needBoSettings)
				{
					$column["list"] = "true";
					$column["edit"] = "false";
					$column["filter"] = "true";
					
					if (!empty($boPath))
					{
						$columnBoAttributes = array_shift($this->_xmlBo->getTagsAttributes($boPath."/columns/column[@name='".$column["name"]."']",array("displayList","allowEdit","displayFilter")));
						if (!empty($columnBoAttributes))
						{
							$columnBoAttributesOptions 	= array("true","false");
							$column["list"] 			= (in_array($columnBoAttributes["attributes"][0]["value"],$columnBoAttributesOptions)) ? $columnBoAttributes["attributes"][0]["value"] : "true";
							$column["edit"] 			= (in_array($columnBoAttributes["attributes"][1]["value"],$columnBoAttributesOptions)) ? $columnBoAttributes["attributes"][1]["value"] : "false";
							$column["filter"] 			= (in_array($columnBoAttributes["attributes"][2]["value"],$columnBoAttributesOptions)) ? $columnBoAttributes["attributes"][2]["value"] : "true";
						}
					}	
				}
				
				// Comment
				$comment = empty($infoTable->Comment) ? $infoTable->Field : $infoTable->Comment;
				if (SLS_String::startsWith($comment,"sls:lang:"))
				{
					$key = strtoupper(SLS_String::substrAfterFirstDelimiter($comment,"sls:lang:"));
					$comment = (empty($GLOBALS[$GLOBALS['PROJECT_NAME']]['XSL'][$key])) ? (empty($GLOBALS[$GLOBALS['PROJECT_NAME']]['JS'][$key]) ? $infoTable->Field : $GLOBALS[$GLOBALS['PROJECT_NAME']]['JS'][$key]) : $GLOBALS[$GLOBALS['PROJECT_NAME']]['XSL'][$key];
				}
				if (!empty($comment))
					$column["label"] = $comment;
				
				// Native type, possible choices
				$nativeType = $infoTable->Type;
				$columnValues = array();
				switch($nativeType)
				{
					case (false !== $typeMatch = $this->containsRecursive($nativeType,array("int"))):
						$columnType = "int";
						$column["html_type"] = "input_number";
						break;
					case (false !== $typeMatch = $this->containsRecursive($nativeType,array("float","double","decimal","real"))):
						$columnType = "float";
						$column["html_type"] = "input_number";
						break;
					case (false !== $typeMatch = $this->containsRecursive($nativeType,array("year","datetime","timestamp","time","date"))):
						$columnType = ($typeMatch == "timestamp") ? "datetime" : $typeMatch;
						$column["html_type"] = "input_".$typeMatch;
						if ($infoTable->Null == "NO")
						{
							switch ($typeMatch)
							{
								case "year": $column["default"] = date("Y"); 			break;
								case "time": $column["default"] = date("H:i:s"); 		break;
								case "date": $column["default"] = date("Y-m-d"); 		break;
								default: 	 $column["default"] = date("Y-m-d H:i:s"); 	break;
							}
						}
						break;
					case (false !== $typeMatch = $this->containsRecursive($nativeType,array("enum","set"))):
						$columnType = "string";
						$column["html_type"] = ($typeMatch == "enum") ? "input_radio" : "input_checkbox";
						$columnValues = explode("','",SLS_String::substrAfterFirstDelimiter(SLS_String::substrBeforeLastDelimiter($nativeType, "')"), "('"));
						break;
					case (false !== $typeMatch = $this->containsRecursive($nativeType,array("text"))):
						$columnType = "string";
						$column["html_type"] = "input_textarea";
						break;
					default:
						$columnType = "string";
						$column["html_type"] = "input_text";
						break;
				}
				$column["native_type"] = $columnType;
				$column["choices"] = $columnValues;
				
				// MaxLength
				if (SLS_String::contains($infoTable->Type,"(") && SLS_String::endsWith(trim($infoTable->Type),")"))
				{
					$maxLength = SLS_String::substrBeforeFirstDelimiter(SLS_String::substrAfterFirstDelimiter($infoTable->Type,"("),")");
					$column["max_length"] = (is_numeric($maxLength) && $maxLength > 0) ? $maxLength : "";
				}
				
				// Nullable ? unique ? default value ?
				$column["required"] = ($infoTable->Null == "NO") ? "true" : "false";
				$column["unique"] = ($infoTable->Key == "UNI" || in_array($column["name"],$uniquesMultilang)) ? "true" : "false";
				if (empty($column["default"]))
					$column["default"] = (empty($infoTable->Default)) ? "" : $infoTable->Default;
				
				// Allow HTML & i18n
				if (!empty($boPath))
				{
					$columnBoAttributes = array_shift($this->_xmlBo->getTagsAttributes($boPath."/columns/column[@name='".$column["name"]."']",array("allowHtml","multilanguage")));				
					if (!empty($columnBoAttributes))
					{
						$allowHtml = $columnBoAttributes["attributes"][0]["value"];
						$isMultilang = $columnBoAttributes["attributes"][1]["value"];
						$column["html"] = ($allowHtml == "true") ? "true" : "false";
						$column["multilanguage"] = ($isMultilang == "true") ? "true" : "false";
					}
				}
				
				// Specific type & extended
				$typeExists = array_shift($this->_xmlType->getTagsAttributes("//sls_configs/entry[@table='".$this->_db_alias."_".$table."' and @column='".$column["name"]."']",array("type","rules","thumbs")));
				if (!empty($typeExists))
				{
					$specificType = $typeExists["attributes"][0]["value"];
					$specificRules = $typeExists["attributes"][1]["value"];
					$specificThumbs = unserialize(str_replace("||#||",'"',$typeExists["attributes"][2]["value"]));
					$specificTypeExtended = "";
					
					switch($specificType)
					{
						case "address": 	/* Nothing */ 		break;
						case "color": 		/* Nothing */ 		break;
						case "email": 		/* Nothing */ 		break;
						case "url": 		/* Nothing */ 		break;
						case "position":
							$record = array_shift($this->_db->select("SELECT MAX(`".$column["name"]."`) AS max_position FROM `".$table."` "));
							$column["default"] = (!empty($record->max_position) && is_numeric($record->max_position) && $record->max_position > 0) ? ($record->max_position+1) : 1;
							break;
						case "uniqid":
							// Generate uid
							$column["default"] = substr(md5(time().substr(sha1(microtime()),0,rand(12,25))),mt_rand(1,20),(!empty($column["max_length"])) ? $column["max_length"] : 40);
							break;
						case (SLS_String::startsWith($specificType,"num_")):
							// Get numeric settings
							$specificTypeExtended = SLS_String::substrAfterFirstDelimiter($specificType,"num_");
							$specificType = "numeric";
							break;
						case (SLS_String::startsWith($specificType,"ip_")):
							// Get IP settings
							$specificTypeExtended = SLS_String::substrAfterFirstDelimiter($specificType,"ip_");
							$specificType = "ip";
							$column["default"] = $_SERVER['REMOTE_ADDR'];
							break;
						case (SLS_String::startsWith($specificType,"file_")):
							// Get file settings
							$specificTypeExtended = SLS_String::substrAfterFirstDelimiter($specificType,"file_");
							$specificType = "file";
							$column["html_type"] = "input_file";
							if ($specificTypeExtended == "img")
							{	
								if (!empty($specificThumbs))
								{	
									usort($specificThumbs,array($this,'sortThumbsMin'));
									$thumb = array_shift($specificThumbs);
									if (!empty($thumb["suffix"]))
										$column["image_thumb"] =  $thumb["suffix"];
								}
								$column["image_ratio"] = SLS_String::substrBeforeFirstDelimiter($specificRules,"|");
								$column["image_min_width"] = SLS_String::substrBeforeFirstDelimiter(SLS_String::substrAfterFirstDelimiter($specificRules,"|"),"|");
								$column["image_min_height"] = SLS_String::substrAfterLastDelimiter($specificRules,"|");
							}
							break;
						case ($specificType == "complexity" && (!empty($specificRules))):
							// Get complexity settings & minLength
							if (SLS_String::contains($specificRules,"min"))
							{
								$column["min_length"] = SLS_String::substrAfterFirstDelimiter($specificRules,"min");
								$specificRules = SLS_String::substrBeforeFirstDelimiter($specificRules,"min");
								if (SLS_String::endsWith($specificRules,"|"))
									$specificRules = SLS_String::substrBeforeLastDelimiter($specificRules,"|");
							}
							$specificTypeExtended = $specificRules;							
							break;
						default: 			$specificType = "";		break;
					}
					$column["specific_type"] 			= $specificType;
					$column["specific_type_extended"] 	= $specificTypeExtended;
				}
				
				if (!empty($column["default"]) && SLS_String::startsWith($column["html_type"],"input_file"))
					$column["default"] = (file_exists($this->_generic->getPathConfig("files").$column["default"])) ? SLS_String::getUrlFile($column["default"]) : "";
				
				// Filters
				$filters = $this->_xmlFilter->getTags("//sls_configs/entry[@table='".$this->_db_alias."_".$table."' and @column='".$column["name"]."']/@filter");
				for($i=0 ; $i<$count=count($filters) ; $i++)
				{
					if ($filters[$i] == "hash")
						$column["html_type"] = "input_password";
					else
						$column["filters"] .= (((!empty($column["filters"])) ? "|" : "").$filters[$i]);
				}
				
				// pk_lang
				if ($needPk && $isMultilanguage && $infoTable->Field == "pk_lang")
				{
					$column["html_type"] = "input_radio";
					$column["choices"] = $this->_lang->getSiteLangs();
				}
				
				// Fk
				$columnFk = array();
				$fkExists = array_shift($this->_xmlFk->getTagsAttributes("//sls_configs/entry[@tableFk='".$this->_db_alias."_".$table."' and @columnFk='".$column["name"]."']",array("tablePk","labelPk")));
				if (!empty($fkExists))
				{
					$tableAlias = $this->_db_alias;
					$tableFk = $table;
					$tablePk = $fkExists["attributes"][0]["value"];
					$labelPk = $fkExists["attributes"][1]["value"];
					
					$this->_generic->useModel(SLS_String::substrAfterFirstDelimiter($tablePk,"_"),$tableAlias,"user");
					$classFk = ucfirst($tableAlias)."_".SLS_String::tableToClass(SLS_String::substrAfterFirstDelimiter($tablePk,"_"));
					$objectFk = new $classFk();
					$pk = $objectFk->getPrimaryKey();								
					$str = $labelPk;
					$labelPkReal = $labelPk;
					$params = $objectFk->getParams(true,true);								
					foreach($params as $key => $value)
					{
						if (is_array($value))
						{
							foreach($value as $key2 => $value2)
							{
								if (SLS_String::contains($str,$key2))
								{
									$this->_generic->useModel($key,$tableAlias,"user");
									$classFk2 = ucfirst($tableAlias)."_".SLS_String::tableToClass($key);
									$object2 = new $classFk2();
									$str = str_replace($key2,$object2->getColumnComment($key2),$str);
								}
							}
						}
						else
						{			
							if (SLS_String::contains($str,$key))
								$str = str_replace($key,$objectFk->getColumnComment($key),$str);
						}
					}
					$labelPk = $str;
										
					$column["html_type"] = "input_ac";
					$column["ac_db"] = strtolower($tableAlias);
					$column["ac_entity"] = strtolower($tableFk);
					$column["ac_fk"] = $tablePk;
					$column["ac_column"] = $column["name"];
					if (SLS_String::startsWith($labelPk,"sls:lang:"))
					{	
						$globalKey = strtoupper(SLS_String::substrAfterFirstDelimiter($labelPk,"sls:lang:"));
						$labelPk = (empty($GLOBALS[$GLOBALS['PROJECT_NAME']]['XSL'][$globalKey])) ? (empty($GLOBALS[$GLOBALS['PROJECT_NAME']]['JS'][$globalKey]) ? $labelPk : $GLOBALS[$GLOBALS['PROJECT_NAME']]['JS'][$globalKey]) : $GLOBALS[$GLOBALS['PROJECT_NAME']]['XSL'][$globalKey];
					}
					$column["ac_label"] = $labelPk;
					$column["ac_pattern"] = $labelPkReal;
					$column["ac_multiple"] = "false";
					if ($column["required"] == "false")
						$column["default"] = "0";
				}
				else
					$tablePk = null;
				
				if (empty($classFather) || (!empty($classFather) && $classFather != ucfirst($tablePk)))
					$columns[$column["name"]] = $column;
			}
		}
		
		return $columns;
	}
	public function action()
	{
		$user 	= $this->hasAuthorative();
		$xml 	= $this->getXML();
		$xml 	= $this->makeMenu($xml);
		$langs 	= array();
		$appli_langs = array();
		$handle = new SLS_XMLToolbox(file_get_contents($this->_generic->getPathConfig("configSls")."international.xml"));
		$step = 0;
		$errors = array();
		$controllerXML = $this->_generic->getControllersXML();
		$metaXML = new SLS_XMLToolbox(file_get_contents($this->_generic->getPathConfig("configSls")."metas.xml"));
		$appli_langs = $this->_generic->getObjectLang()->getSiteLangs();
		$defaultLang = $this->_generic->getObjectLang()->getDefaultLang();
		
		// If lang have been choose
		if ($this->_http->getParam("step") == "1")
		{
			$lang1 = SLS_String::trimSlashesFromString($this->_http->getParam("lang"));
			$lang  = array_shift($handle->getTags("//sls_configs/sls_country/sls_country_langs/sls_country_lang[node()='".$lang1."']/@iso"));			
			
			if (!in_array($lang,$appli_langs))
			{
				$step = 2;
				$xml->addFullTag("step","2",true);
				$xml->addFullTag("lang_to_add",$lang,true);
			}
			else
			{
				$xml->addFullTag("lang_selected",$lang1,true);
				$xml->startTag("errors");
				$xml->addFullTag("error","This lang already exist in your application",true);
				$xml->endTag("errors");
			}		
		}
		if ($this->_http->getParam("step") == "2" || $step == 2)
		{			
			$lang = (empty($lang)) ? $this->_http->getParam("lang_to_add") : $lang;
			$xml->addFullTag("step","2",true);
			$xml->addFullTag("lang_to_add",$lang,true);
			
			$generics = array(	"MONDAY" 							=> "",
								"TUESDAY" 							=> "",
								"WEDNESDAY" 						=> "",
								"THURSDAY" 							=> "",
								"FRIDAY" 							=> "",
								"SATURDAY" 							=> "",
								"SUNDAY" 							=> "",
								"JANUARY" 							=> "",
								"FEBRUARY" 							=> "",
								"MARCH" 							=> "",
								"APRIL" 							=> "",
								"MAY" 								=> "",
								"JUNE" 								=> "",
								"JULY" 								=> "",
								"AUGUST" 							=> "",
								"SEPTEMBER" 						=> "",
								"OCTOBER" 							=> "",
								"NOVEMBER" 							=> "",
								"DECEMBER" 							=> "",
								"DATE_PATTERN_TIME" 				=> "",
								"DATE_PATTERN_FULL_TIME" 			=> "",
								"DATE_PATTERN_DATE" 				=> "",
								"DATE_PATTERN_MONTH_LITTERAL" 		=> "",
								"DATE_PATTERN_FULL_LITTERAL" 		=> "",
								"DATE_PATTERN_FULL_LITTERAL_TIME" 	=> "",
								"DATE_PATTERN_MONTH_LITTERAL_TIME" 	=> "",
								"DATE_DIFF_Y"						=> "",
								"DATE_DIFF_M"						=> "",
								"DATE_DIFF_W"						=> "",
								"DATE_DIFF_D"						=> "",
								"DATE_DIFF_H"						=> "",
								"DATE_DIFF_I"						=> "",
								"DATE_DIFF_S"						=> "",
								"E_CONTENT" 						=> "",
								"E_EMPTY" 							=> "",
								"E_KEY" 							=> "",
								"E_COMPLEXITY" 						=> "",
								"E_LENGTH" 							=> "",
								"E_NULL" 							=> "",
								"E_UNIQUE" 							=> "",
								"E_TYPE" 							=> "",
								"E_SIZE" 							=> "",
								"E_EXIST" 							=> "",
								"E_WRITE" 							=> "",
								"E_LOGGED" 							=> "",
								"E_AUTHORIZED" 						=> ""
							);									
			// Try to recover generic langs from Deployement
			if (file_exists($this->_generic->getPathConfig("installDeployement")."Langs/Generics/generic.".$lang.".lang.php"))
				include($this->_generic->getPathConfig("installDeployement")."Langs/Generics/generic.".$lang.".lang.php");			
			// Set the default value by english or current lang if has been found in Deployement
			foreach($generics as $key => $value)			
				$generics[$key] = SLS_String::trimSlashesFromString($GLOBALS[$GLOBALS['PROJECT_NAME']]['JS']['SLS_'.$key]);
			
			$controllers = array();
				
			// Recover all controllers
			$controllersA = $controllerXML->getTags("//controllers/controller[@side='user']/@name");
			foreach($controllersA as $controller)
			{
				$id = array_shift($controllerXML->getTags("//controllers/controller[@name='".$controller."']/@id"));
				
				$values = array();
				foreach($appli_langs as $appli_lang)				
					$values[$appli_lang] = array_shift($controllerXML->getTags("//controllers/controller[@name='".$controller."']/controllerLangs/controllerLang[@lang='".$appli_lang."']"));					
				$values[$lang] = SLS_String::trimSlashesFromString($this->_http->getParam($id."_".$lang));
				
				$result = array("id" => $id, "key" => $controller, "values" => $values, "actions" => array());
				array_push($controllers,$result);
			}
			
			// Foreach controllers, recover all actions
			for($i=0 ; $i<$count=count($controllers) ; $i++)
			{
				$controller = $controllers[$i]["key"];
				$actions = $controllerXML->getTags("//controllers/controller[@name='".$controller."']/scontrollers/scontroller/@name");
				$actionsA = array();
				
				foreach($actions as $action)
				{
					$id = array_shift($controllerXML->getTags("//controllers/controller[@name='".$controller."']/scontrollers/scontroller[@name='".$action."']/@id"));
					
					$values = array();
					foreach($appli_langs as $appli_lang)				
						$values[$appli_lang] = array_shift($controllerXML->getTags("//controllers/controller[@name='".$controller."']/scontrollers/scontroller[@name='".$action."']/scontrollerLangs/scontrollerLang[@lang='".$appli_lang."']"));
					$values[$lang] = SLS_String::trimSlashesFromString($this->_http->getParam($id."_".$lang));
					
					$metas = array("title" => array(), "description" => array(), "keywords" => array());
					$titles = array();
					$descriptions = array();
					$keywords = array();
					foreach($appli_langs as $appli_lang)
					{	
						$titles[$appli_lang] = array_shift($metaXML->getTags("//sls_configs/action[@id='".$id."']/title[@lang='".$appli_lang."']"));						
						$descriptions[$appli_lang] = array_shift($metaXML->getTags("//sls_configs/action[@id='".$id."']/description[@lang='".$appli_lang."']"));						
						$keywords[$appli_lang] = array_shift($metaXML->getTags("//sls_configs/action[@id='".$id."']/keywords[@lang='".$appli_lang."']"));										
					}
					$titles[$lang] = SLS_String::trimSlashesFromString($this->_http->getParam("meta_title-".$id."_".$lang));
					$descriptions[$lang] = SLS_String::trimSlashesFromString($this->_http->getParam("meta_description-".$id."_".$lang));
					$keywords[$lang] = SLS_String::trimSlashesFromString($this->_http->getParam("meta_keywords-".$id."_".$lang));
					$metas["title"] = $titles;
					$metas["description"] = $descriptions;
					$metas["keywords"] = $keywords;
					
					$result = array("id" => $id,"key" => $action, "values" => $values, "metas" => $metas);
					array_push($actionsA,$result);
				}
				$controllers[$i]["actions"] = $actionsA;
			}
			
			// If informations have been sent, check if it's good
			if ($this->_http->getParam("reload") == "true")
			{
				$mods = array();
				$smods = array();
				
				// Get all controllers
				foreach($this->_http->getParams() as $key => $value)
				{
					// Controllers case
					if (SLS_String::startsWith($key,"c_"))
					{
						$id = SLS_String::substrBeforeLastDelimiter($key,"_".$lang);
						$mod = array_shift($controllerXML->getTags("//controllers/controller[@id='".$id."']/@name"));
						$mods[$id] = SLS_String::stringToUrl(SLS_String::trimSlashesFromString($value),"",false);						
						if (empty($mods[$id]))
							array_push($errors,"You have to fill the rewrite of the controller '".$mod."'.");
						$modsExisted = $controllerXML->getTags("//controllers/controller/controllerLangs/controllerLang");
						if (in_array($mods[$id],$modsExisted))
							array_push($errors,"The name for rewrite of the controller '".$mod."' is already used, please choose another one.");
					}
					// Actions case
					else if (SLS_String::startsWith($key,"a_"))
					{
						$id = SLS_String::substrBeforeLastDelimiter($key,"_".$lang);
						$smod = array_shift($controllerXML->getTags("//controllers/controller/scontrollers/scontroller[@id='".$id."']/@name"));
						$mod = array_shift($controllerXML->getTags("//controllers/controller[scontrollers/scontroller[@id='".$id."']]/@name"));
						$idC = array_shift($controllerXML->getTags("//controllers/controller[scontrollers/scontroller[@id='".$id."']]/@id"));
						$smods[$id] = SLS_String::stringToUrl(SLS_String::trimSlashesFromString($value),"",false);						
						if (empty($smods[$id]))
							array_push($errors,"You have to fill the rewrite of the action '".$smod."' (controller '".$mod."').");
						$smodsExisted = $controllerXML->getTags("//controllers/controller[@id='".$idC."']/scontrollers/scontroller/scontrollerLangs/scontrollerLang[@lang='".$lang."']");
						if (in_array($smods[$id],$smodsExisted))
							array_push($errors,"The name for rewrite of the action '".$smod."' (controller '".$mod."') is already used by another action of the same controller, please choose another one.");
					}
					// Generics case
					else if (SLS_String::startsWith($key,"generic_"))
					{
						$label = SLS_String::substrAfterFirstDelimiter($key,"generic_");
						if (empty($value))
							array_push($errors,"You have to fill the content of the variable '".$label."'");
						$generics[$label] = strtolower(SLS_String::trimSlashesFromString($value));
					}
				}
				
				// If all cool
				if (empty($errors))
				{
					// controllers.xml
					foreach($mods as $key => $value)
					{
						$str = '<controllerLang lang="'.$lang.'"><![CDATA['.$value.']]></controllerLang>';
						$controllerXML->appendXMLNode("//controllers/controller[@id='".$key."']/controllerLangs",$str);
					}
					foreach($smods as $key => $value)
					{
						$str = '<scontrollerLang lang="'.$lang.'"><![CDATA['.$value.']]></scontrollerLang>';
						$controllerXML->appendXMLNode("//controllers/controller/scontrollers/scontroller[@id='".$key."']/scontrollerLangs",$str);
						
						// metas.xml
						$title = SLS_String::trimSlashesFromString($this->_http->getParam("meta_title-".$key."_".$lang));
						if (empty($title))
							$str = '<title lang="'.$lang.'"/>';
						else 
							$str = '<title lang="'.$lang.'"><![CDATA['.$title.']]></title>';
						$metaXML->appendXMLNode("//sls_configs/action[@id='".$key."']",$str);
						$description = SLS_String::trimSlashesFromString($this->_http->getParam("meta_description-".$key."_".$lang));
						if (empty($description))
							$str = '<description lang="'.$lang.'"/>';
						else 
							$str = '<description lang="'.$lang.'"><![CDATA['.$description.']]></description>';
						$metaXML->appendXMLNode("//sls_configs/action[@id='".$key."']",$str);
						$keyword = SLS_String::trimSlashesFromString($this->_http->getParam("meta_keywords-".$key."_".$lang));
						if (empty($keyword))
							$str = '<keywords lang="'.$lang.'"/>';
						else 
							$str = '<keywords lang="'.$lang.'"><![CDATA['.$keyword.']]></keywords>';
						$metaXML->appendXMLNode("//sls_configs/action[@id='".$key."']",$str);
						// /metas.xml
					}
					$controllerXML->saveXML($this->_generic->getPathConfig("configSecure")."controllers.xml");
					$metaXML->saveXML($this->_generic->getPathConfig("configSls")."metas.xml");
					// /controllers.xml
					
					// site.xml
					$siteXML = $this->_generic->getSiteXML();
					$str = '<name isSecure="false" js="false" active="false"><![CDATA['.$lang.']]></name>';
					$siteXML->appendXMLNode("//configs/langs",$str);
					$siteXML->saveXML($this->_generic->getPathConfig("configSecure")."site.xml");
					// /site.xml
					
					// generic.iso.lang.php
					$fileContent = '<?php'."\n".
								   '/**'."\n".
								   ' * Generic Sls Vars'."\n".
								   ' */'."\n";
					foreach($generics as $key => $value)					
						$fileContent .= '$GLOBALS[$GLOBALS[\'PROJECT_NAME\']][\'JS\'][\'SLS_'.$key.'\'] = "'.str_replace('"','\"',$value).'";'."\n";
					$fileContent .= '?>';
					file_put_contents($this->_generic->getPathConfig("coreGenericLangs")."generic.".$lang.".lang.php",$fileContent);
					// /generic.iso.lang.php
					
					// site.iso.lang.php
					$fileContent =  '<?php'."\n".
									'/**'."\n".
									' * SillySmart Translations'."\n".
									' * Language : '.array_shift($handle->getTags("//sls_configs/sls_country/sls_country_langs/sls_country_lang[node()='".$lang."']/@iso")).' ('.strtoupper($lang).')'."\n".
									' */'."\n\n".
									'?>';
					file_put_contents($this->_generic->getPathConfig("genericLangs")."site.".$lang.".lang.php",str_replace(array("Translations in '".strtoupper($defaultLang)."'","site.".$defaultLang.".lang.php","sentence in ".strtoupper($defaultLang)),array("Translations in '".strtoupper($lang)."'","site.".$lang.".lang.php","sentence in ".strtoupper($lang)),file_get_contents($this->_generic->getPathConfig("genericLangs")."site.".$defaultLang.".lang.php")));
					// /site.iso.lang.php
										
					// Actions langs files
					$directories = array();
					foreach($mods as $key => $value)					
						array_push($directories,array_shift($controllerXML->getTags("//controllers/controller[@id='".$key."']/@name")));
					$this->copyActionsLang($directories,$lang);
					// /Actions langs files
					
					// User_Bo langs
					$controllerBo = $controllerXML->getTag("//controllers/controller[@side='user' and @isBo='true']/@name");
					if (!empty($controllerBo))
					{
						if (file_exists($this->_generic->getPathConfig("installDeployement")."Langs/Actions/{{USER_BO}}/__{{USER_BO}}.".$lang.".lang.php"))
							$langContent = str_replace(array("{{USER_BO}}"),array($controllerBo),file_get_contents($this->_generic->getPathConfig("installDeployement")."Langs/Actions/{{USER_BO}}/__{{USER_BO}}.".$lang.".lang.php"));
						else
							$langContent = str_replace(array("{{USER_BO}}"),array($controllerBo),file_get_contents($this->_generic->getPathConfig("installDeployement")."Langs/Actions/{{USER_BO}}/__{{USER_BO}}.en.lang.php"));
						if (!empty($langContent))
							file_put_contents($this->_generic->getPathConfig("actionLangs").$controllerBo."/__".$controllerBo.".".$lang.".lang.php",$langContent);
					}
					
					// MySQL multilanguage tables
					$handle = opendir($this->_generic->getPathConfig("models"));
					
					// Disable explain
					SLS_Sql::getInstance()->_explain = false;
					
					// Foreach models 
					while (false !== ($file = readdir($handle))) 
					{
						if (!is_dir($this->_generic->getPathConfig("models")."/".$file) && substr($file, 0, 1) != ".") 
						{
							$fileExploded = explode(".",$file);
							if (is_array($fileExploded) && count($fileExploded) == 4)
							{ 
								$db = $fileExploded[0];
								$class = $fileExploded[1];
								$className = $db."_".$class;
								$this->_generic->useModel($class,$db,"user");
								$object = new $className();								
								if ($object->isMultilanguage())
								{
									$results = $object->searchModels($object->getTable(),array(),array(0=>array("column"=>"pk_lang","value"=>$defaultLang,"mode"=>"equal")));
									
									for($i=0 ; $i<$count=count($results) ; $i++)
									{
										$object = new $className();
										$object->setModelLanguage($lang);
										foreach($results[$i] as $column => $col_value)
										{
											if ($column != "pk_lang" && $column != $object->getPrimaryKey())
											{													
												$object->__set($column,$col_value);
											}
										}
										try {
											$object->create($results[$i]->{$object->getPrimaryKey()});
										}
										catch (Exception $e){}
									}									
								}								
							}
						}
					}
					// /MySQL multilanguage tables
					
					// Redirect
					$controllers = $this->_generic->getTranslatedController("SLS_Bo","Langs");
					$this->_generic->redirect($controllers["controller"]."/".$controllers["scontroller"].".sls");
				}
				// Else, form errors
				else
				{
					$xml->startTag("errors");
					foreach($errors as $error)
						$xml->addFullTag("error",$error,true);
					$xml->endTag("errors");
				}				
			}
			
			$xml->startTag("generic_langs");
			foreach($generics as $key => $value)
			{
				$xml->startTag("generic_lang");	
				$xml->addFullTag("key",$key,true);
				$xml->addFullTag("value",$value,true);
				$xml->endTag("generic_lang");
			}
			$xml->endTag("generic_langs");
						
			$xml->startTag("controllers");
			for($i=0 ; $i<$count=count($controllers) ; $i++)
			{
				$xml->startTag("controller");
				$xml->addFullTag("id",$controllers[$i]["id"],true);
				$xml->addFullTag("key",$controllers[$i]["key"],true);
				$xml->startTag("values");
				foreach($controllers[$i]["values"] as $key2 => $value2)
				{
					$xml->startTag("value");
					$xml->addFullTag("key",$key2,true);
					$xml->addFullTag("value",$value2,true);
					$xml->endTag("value");
				}
				$xml->endTag("values");
				$xml->startTag("actions");
				for($j=0 ; $j<$count2=count($controllers[$i]["actions"]) ; $j++)
				{
					$action = $controllers[$i]["actions"];
					$xml->startTag("action");
					$xml->addFullTag("id",$action[$j]["id"],true);
					$xml->addFullTag("key",$action[$j]["key"],true);
					$xml->startTag("values");
					foreach($action[$j]["values"] as $key3 => $value3)
					{
						$xml->startTag("value");
						$xml->addFullTag("key",$key3,true);
						$xml->addFullTag("value",$value3,true);
						$xml->endTag("value");
					}
					$xml->endTag("values");
					$xml->startTag("metas");
					foreach($action[$j]["metas"] as $key4 => $value4)
					{
						$xml->startTag("meta");
						$xml->addFullTag("key",$key4,true);
						$xml->startTag("values");
						foreach($value4 as $key5 => $value5)
						{
							$xml->startTag("value");
							$xml->addFullTag("key",$key5,true);
							$xml->addFullTag("value",$value5,true);
							$xml->endTag("value");
						}
						$xml->endTag("values");
						$xml->endTag("meta");
					}
					$xml->endTag("metas");
					$xml->endTag("action");
				}
				$xml->endTag("actions");
				$xml->endTag("controller");
			}
			$xml->endTag("controllers");
		}
		
		$xpathLangs = $handle->getTags("//sls_configs/sls_country/sls_country_langs/sls_country_lang[@iso != '']");
		foreach ($xpathLangs as $lang)
			if (!in_array(trim($lang), $langs))
				array_push($langs, trim($lang));
		array_multisort($langs, SORT_STRING, SORT_ASC);
		$xml->startTag("langs");
		foreach ($langs as $lang)
			$xml->addFullTag("lang", $lang, true);
		$xml->endTag("langs");
		
		$this->saveXML($xml);
	}	
	public function action()
	{
		$user = $this->hasAuthorative();
		$xml = $this->getXML();
		$xml = $this->makeMenu($xml);
		$errors = array();
		
		$plugin = new SLS_XMLToolbox(file_get_contents($this->_generic->getPathConfig("configPlugins")."/plugins.xml"));
		$pluginMobile = $plugin->getTag("//plugins/plugin[@code='mobile']");
		$pluginMobile = (!empty($pluginMobile)) ? true : false;
		
		$controller = SLS_String::trimSlashesFromString($this->_http->getParam('Controller'));
				
		if (is_file($this->_generic->getPathConfig("staticsControllers").$controller.".controller.php"))
		{
			if ($this->_http->getParam('reload') == 'true')
			{
				$newController = SLS_String::trimSlashesFromString($this->_http->getParam('controllerName'));
				$oldController = SLS_String::trimSlashesFromString($this->_http->getParam('oldName'));
				$cache_visibility = SLS_String::trimSlashesFromString($this->_http->getParam('cache_visibility'));
				$cache_expiration = SLS_String::trimSlashesFromString($this->_http->getParam('cache_expiration'));
				$cache_responsive = SLS_String::trimSlashesFromString($this->_http->getParam('cache_responsive'));
				$toCache = (in_array($cache_visibility,array("public","private"))) ? true : false;
				
				// If responsive wanted
				if ($cache_responsive == "true" && !$pluginMobile)
				{
					// Force Mobile plugin download
					file_get_contents($this->_generic->getFullPath("SLS_Bo",
																  "SearchPlugin",
																  array("Action" => "Download",
																  		"Server" => "4",
																  		"Plugin" => "20",
																  		"token"	 => sha1(substr($this->_generic->getSiteConfig("privateKey"), 0, 3).substr($this->_generic->getSiteConfig("privateKey"), strlen($this->_generic->getSiteConfig("privateKey"))-3))),
																  true));
				}
				
				if (empty($newController))
					array_push($errors, "You must fill the static controller name");
				if (in_array($cache_visibility,array("public","private")) && (!is_numeric($cache_expiration) || $cache_expiration < 0))
					array_push($errors, "Your expiration cache must be a positive time or 0");
				
				$newController = str_replace(" ", "", ucwords(trim(SLS_String::getAlphaString($newController))));
				
				$statics = $this->_generic->recursiveReadDir($this->_generic->getPathConfig("staticsControllers"), array(), array(0=>"php"));
				foreach ($statics as $static)
				{
					if (SLS_String::substrBeforeLastDelimiter(SLS_String::substrAfterLastDelimiter($static, "/"), ".controller.php") == $newController && SLS_String::substrBeforeLastDelimiter(SLS_String::substrAfterLastDelimiter($static, "/"), ".controller.php") != $oldController)
					{
						array_push($errors, "The name '".$newController."' is already in use for a static controller");
						break;
					}
				}
				
				if (empty($errors))
				{
					if ($newController != $oldController)
					{
						$strController = file_get_contents($this->_generic->getPathConfig("staticsControllers").$oldController.".controller.php");
						$strController = str_replace($oldController."Controller", $newController."Controller", $strController);
						file_put_contents($this->_generic->getPathConfig("staticsControllers").$newController.".controller.php", $strController);					
						unlink($this->_generic->getPathConfig("staticsControllers").$oldController.".controller.php");
					}
					
					// Cache
					if (in_array($cache_visibility,array("public","private")))
					{
						$this->_cache->addObject(strtolower($newController),"statics",$cache_visibility,($cache_responsive=="true") ? "responsive" : "no_responsive",$cache_expiration);
						$this->_cache->saveObject();
					}
					else
					{
						$this->_cache->deleteObject(strtolower($newController),"statics");
						$this->_cache->saveObject();
					}
					
					$this->_generic->forward("SLS_Bo", "Controllers");
				}		
				if (!empty($errors))
				{
					$xml->startTag("errors");
						foreach ($errors as $error)
							$xml->addFullTag("error", $error, true);
					$xml->endTag("errors");
				}
				$xml->startTag('form');
					$xml->addFullTag("controllerName", $postControllerName);
					$xml->addFullTag("cache_visibility", $cache_visibility,true);
					$xml->addFullTag("cache_expiration", $cache_expiration,true);
					$xml->addFullTag("cache_responsive", $cache_expiration,true);					
				$xml->endTag('form');
			}
			else
			{
				$xml->startTag('form');
					$xml->addFullTag("controllerName", $controller);
					$xml->addFullTag("cache_visibility", $this->_cache->getObject(strtolower($controller),"statics","visibility"),true);
					$xml->addFullTag("cache_expiration", $this->_cache->getObject(strtolower($controller),"statics","expire"),true);
					$xml->addFullTag("cache_responsive", $this->_cache->getObject(strtolower($controller),"components","responsive"),true);
				$xml->endTag('form');
			}
			
			$xml->startTag('controller');
				$xml->addFullTag("name", $controller, true);
			$xml->endTag('controller');
		}
		else 
		{
			$this->_generic->forward('SLS_Bo', 'Controllers');
		}
		
		$this->saveXML($xml);
	}
	public function action()
	{
		$user 		= $this->hasAuthorative();
		$xml 		= $this->getXML();
		$xml		= $this->makeMenu($xml);
		$siteXML 	= $this->_generic->getSiteXML();
		$langs 		= $this->_lang->getSiteLangs();
		
		$errors = array();
		
		if ($this->_http->getParam("reload") == "true")
		{
			$alias = SLS_String::trimSlashesFromString($this->_http->getParam("alias"));
			$domain = SLS_String::trimSlashesFromString($this->_http->getParam("domain"));
			$lang = SLS_String::trimSlashesFromString($this->_http->getParam("lang"));
			$cdn = $this->_http->getParam("cdn");
			if ($cdn != 'true') 
				$cdn = 'false';
			if (SLS_String::endsWith(trim($domain),"/"))
				$domain = SLS_String::substrBeforeLastDelimiter(trim($domain),"/");
			
			$result = $siteXML->getTag("//configs/domainName/domain[@alias='".$alias."']");
			
			if (empty($alias))
				array_push($errors,"You must choose an alias for your domain name.");
			else if (!empty($result))
				array_push($errors,"This alias is already used by another domain, please choose another.");
			if (empty($domain))
				array_push($errors,"You must fill your domain name.");			
			else if (!SLS_String::isValidUrl("http://".$domain))
				array_push($errors,"This domain is not a valid url.");
				
			if (empty($errors))
			{
				$str_xml = '<domain alias="'.$alias.'" js="true" isSecure="false" cdn="'.$cdn.'" lang="'.$lang.'">'.
								'<![CDATA['.$domain.']]>'.
							'</domain>';
				$siteXML->appendXMLNode("//configs/domainName",$str_xml);
				$siteXML->saveXML($this->_generic->getPathConfig("configSecure")."site.xml");
				$this->_generic->forward("SLS_Bo","GlobalSettings");
			}
			else
			{
				$xml->startTag("domain");
					$xml->addFullTag("alias",$alias,true);
					$xml->addFullTag("domain",$domain,true);
					$xml->addFullTag("cdn",$cdn,true);
					$xml->addFullTag("lang",$lang,true);
				$xml->endTag("domain");
			}
		}
		
		$langsBinded = $siteXML->getTags("//configs/domainName/domain/@lang");		
		foreach($langs as $lang)
			if (in_array($lang,$langsBinded))
				unset($langs[array_shift(array_keys($langs,$lang))]);
		$xml->startTag("langs");		
		foreach($langs as $lang)
			$xml->addFullTag("lang",$lang,true);
		$xml->endTag("langs");
		
		$xml->startTag("errors");
		foreach($errors as $error)
			$xml->addFullTag("error",$error,true);
		$xml->endTag("errors");
		
		$this->saveXML($xml);		
	}
	/**
	 * Action Home
	 *
	 */
	public function action() 
	{
		$this->secureURL();
		$this->_generic->registerLink('International', 'SLS_Init', 'International');
		$errors = array();
		$giveDataStep1 = false;
		$xml = $this->getXML();
		$step = 0;
		$langs = array();
		$handle = new SLS_XMLToolbox(file_get_contents($this->_generic->getPathConfig("configSls")."international.xml"));
		$xpathLangs = $handle->getTags("//sls_configs/sls_country/sls_country_langs/sls_country_lang[@iso != '']");
		foreach ($xpathLangs as $lang)
			if (!in_array(trim($lang), $langs))
				array_push($langs, trim($lang));
		array_multisort($langs, SORT_STRING, SORT_ASC);
		$xml->startTag("langs");
		foreach ($langs as $lang)
			$xml->addFullTag("lang", $lang, true);
		$xml->endTag("langs");
				
		// If reload
		if ($this->_http->getParam('reload_international_step1') == "true")
		{
			// If one lang at least
			$listLangs = SLS_String::trimSlashesFromString($this->_http->getParam("international_langs"));			
			if (empty($listLangs))
				array_push($errors,"You must choose at least one language");
			else
			{
				$xmlIsos = "";
				
				foreach($listLangs as $listLang)
				{
					$iso = array_shift($handle->getTags("//sls_configs/sls_country/sls_country_langs/sls_country_lang[node()='".$listLang."']/@iso"));
					$xmlIsos .= '<name isSecure="false" js="false" active="true"><![CDATA['.$iso.']]></name>';
					if (is_file($this->_generic->getPathConfig("installDeployement")."Langs/Generics/generic.".$iso.".lang.php"))
						copy($this->_generic->getPathConfig("installDeployement")."Langs/Generics/generic.".$iso.".lang.php", $this->_generic->getPathConfig("coreGenericLangs")."generic.".$iso.".lang.php");
				}
				
			}
			if (empty($errors))
			{
				$step = 1;
				$coreXml = $this->_generic->getSiteXML();
				$coreXml->setTag('langs',$xmlIsos,false);
				file_put_contents($this->_generic->getPathConfig("configSecure")."site.xml", $coreXml->getXML());
				$giveDataStep1 = true;
			}
			else
			{
				$step = 0;
				$xml->startTag("errors");
				foreach ($errors as $error)
					$xml->addFullTag("error", $error, true);
				$xml->endTag("errors");
			}
		}
		// Set controllers.xml
		else if ($this->_http->getParam('reload_international_step2') == "true")
		{
			$langs = $this->_generic->getSiteXML()->getTags("//configs/langs/name");
			$listLangs = explode("-", SLS_String::trimSlashesFromString($this->_http->getParam("international_languages")));
			$params = $this->_http->getParams('post');
			
			$userValues = array();
			foreach ($langs as $lang)
				$userValues[$lang] = array();
			
			foreach ($params as $key=>$param)
				if (array_key_exists(SLS_String::substrBeforeFirstDelimiter($key, '_'), $userValues))
					$userValues[SLS_String::substrBeforeFirstDelimiter($key, '_')][SLS_String::substrAfterFirstDelimiter($key, '_')] = SLS_String::trimSlashesFromString($param);
			
			// Check errors
			$errors = array();
			$xml->startTag("InternationalMemory");
			$xml->addFullTag("default", SLS_String::trimSlashesFromString($this->_http->getParam("default_lang")), true);
			foreach ($userValues as $key=>$values) 
			{
				$mods[$key] = array();
				$smods[$key]['home'] = array();
				$smods[$key]['error'] = array();
				
				foreach ($values as $name=>$value)
				{
					$xml->startTag("row");
					$xml->addFullTag("name", $key."_".$name, true);
					$xml->addFullTag("value", SLS_String::trimSlashesFromString($value), true);
					$xml->endTag("row");
					if (substr($name, 0, 11) == "TRANSLATION")
					{
						if (empty($value))
							array_push($errors, "You must fill the translation for ".ucwords(strtolower(str_replace("_", " ", substr($name, 11))))." in ".strtoupper($key));
					}					
				}
				
				if (empty($values['home_mod']))
					array_push($errors, "You must fill a value for the URL of Main Controller in ".strtoupper($key));				
				else if (SLS_String::stringToUrl(SLS_String::trimSlashesFromString($values['home_mod']),"")!=strtolower($values['home_mod']))
					array_push($errors, "You must fill a value for the URL of Main Controller without spaces, accented characters or specials characters in ".strtoupper($key));
				else 
					array_push($mods[$key], $values['home_mod']);				
				if (empty($values['home_desc']))
					array_push($errors, "You must fill a page title for your home page in ".strtoupper($key));
				if (empty($values['home_index']))
					array_push($errors, "You must fill an action value for your home page in ".strtoupper($key));
				else if (SLS_String::stringToUrl(SLS_String::trimSlashesFromString($values['home_index']),"")!=strtolower($values['home_index']))
					array_push($errors, "You must fill an action value for your home page without spaces, accented characters or specials characters in ".strtoupper($key));
				else 
					array_push($smods[$key]['home'], $values['home_index']);
				if (empty($values['error_mod']))
					array_push($errors, "You must fill a value for the URL of Error Controller in ".strtoupper($key));
				else if (SLS_String::stringToUrl(SLS_String::trimSlashesFromString($values['error_mod']),"")!=strtolower($values['error_mod']))
					array_push($errors, "You must fill a value for the URL of Error Controller without spaces, accented characters or specials characters in ".strtoupper($key));
				else 
					array_push($mods[$key], $values['error_mod']);
				if (empty($values['error_400_desc']))
					array_push($errors, "You must fill a page title for your 400 page in ".strtoupper($key));
				if (empty($values['error_401_desc']))
					array_push($errors, "You must fill a page title for your 401 page in ".strtoupper($key));
				if (empty($values['error_403_desc']))
					array_push($errors, "You must fill a page title for your 403 page in ".strtoupper($key));
				if (empty($values['error_404_desc']))
					array_push($errors, "You must fill a page title for your 404 page in ".strtoupper($key));
				if (empty($values['error_500_desc']))
					array_push($errors, "You must fill a page title for your 500 page in ".strtoupper($key));
				if (empty($values['error_307_desc']))
					array_push($errors, "You must fill a page title for your 307 page in ".strtoupper($key));
				if (empty($values['error_302_desc']))
					array_push($errors, "You must fill a page title for your 302 page in ".strtoupper($key));
					
				if (empty($values['error_400_url']))
					array_push($errors, "You must fill a value for the URL of your 400 page in ".strtoupper($key));
				else if (SLS_String::stringToUrl(SLS_String::trimSlashesFromString($values['error_400_url']),"")!=strtolower($values['error_400_url']))
					array_push($errors, "You must fill an action value for the URL of you 400 without spaces, accented characters or specials characters in ".strtoupper($key));
				else 
					array_push($smods[$key]['error'], $values['error_400_url']);
				if (empty($values['error_401_url']))
					array_push($errors, "You must fill a value for the URL of your 401 page in ".strtoupper($key));
				else if (SLS_String::stringToUrl(SLS_String::trimSlashesFromString($values['error_401_url']),"")!=strtolower($values['error_401_url']))
					array_push($errors, "You must fill an action value for the URL of you 401 without spaces, accented characters or specials characters in ".strtoupper($key));
				else 
					array_push($smods[$key]['error'], $values['error_401_url']);
				if (empty($values['error_403_url']))
					array_push($errors, "You must fill a value for the URL of your 403 page in ".strtoupper($key));
				else if (SLS_String::stringToUrl(SLS_String::trimSlashesFromString($values['error_403_url']),"")!=strtolower($values['error_403_url']))
					array_push($errors, "You must fill an action value for the URL of you 403 without spaces, accented characters or specials characters in ".strtoupper($key));
				else 
					array_push($smods[$key]['error'], $values['error_403_url']);
				if (empty($values['error_404_url']))
					array_push($errors, "You must fill a value for the URL of your 404 page in ".strtoupper($key));
				else if (SLS_String::stringToUrl(SLS_String::trimSlashesFromString($values['error_404_url']),"")!=strtolower($values['error_404_url']))
					array_push($errors, "You must fill an action value for the URL of you 404 without spaces, accented characters or specials characters in ".strtoupper($key));
				else 
					array_push($smods[$key]['error'], $values['error_404_url']);
				if (empty($values['error_500_url']))
					array_push($errors, "You must fill a value for the URL of your 500 page in ".strtoupper($key));
				else if (SLS_String::stringToUrl(SLS_String::trimSlashesFromString($values['error_500_url']),"")!=strtolower($values['error_500_url']))
					array_push($errors, "You must fill an action value for the URL of you 500 without spaces, accented characters or specials characters in ".strtoupper($key));
				else 
					array_push($smods[$key]['error'], $values['error_500_url']);
				if (empty($values['error_307_url']))
					array_push($errors, "You must fill a value for the URL of your 307 page in ".strtoupper($key));
				else if (SLS_String::stringToUrl(SLS_String::trimSlashesFromString($values['error_307_url']),"")!=strtolower($values['error_307_url']))
					array_push($errors, "You must fill an action value for the URL of you 307 without spaces, accented characters or specials characters in ".strtoupper($key));
				else 
					array_push($smods[$key]['error'], $values['error_307_url']);
				if (empty($values['error_302_url']))
					array_push($errors, "You must fill a value for the URL of your 302 page in ".strtoupper($key));
				else if (SLS_String::stringToUrl(SLS_String::trimSlashesFromString($values['error_302_url']),"")!=strtolower($values['error_302_url']))
					array_push($errors, "You must fill an action value for the URL of you 302 without spaces, accented characters or specials characters in ".strtoupper($key));
				else 
					array_push($smods[$key]['error'], $values['error_302_url']);
				
				$unikUrl = array();
				foreach ($smods[$key]['error'] as $smod)
					if (!in_array($smod, $unikUrl))
						array_push($unikUrl, $smod);
				
				if (count($unikUrl) != count($smods[$key]['error']))
					array_push($errors, "You cannot set the same Action name for two differents actions in the same language : ".strtoupper($key));
					
			}
			
			$xml->endTag("InternationalMemory");
			if (empty($errors))
			{
				$caIds = array();
				// Set defaut lang
				$siteXML = $this->_generic->getSiteXML();
				$siteXML->setTag("defaultLang", SLS_String::trimSlashesFromString($this->_http->getParam("default_lang")));
				$siteXML->setTagAttributes("//configs/domainName/domain[@default='1']",array("lang" => SLS_String::trimSlashesFromString($this->_http->getParam("default_lang"))));
				file_put_contents($this->_generic->getPathConfig("configSecure")."site.xml", $siteXML->getXML());
				$langs = $this->_generic->getSiteXML()->getTags("//configs/langs/name");
				
				$xmlControllers = $this->_generic->getControllersXML();
				
				// Generate the Home Controller ID and the Default Controller ID
				$homeID = $this->_generic->generateControllerId();
				array_push($caIds, $homeID);
				
				$defaultID = $this->_generic->generateControllerId();
				while (in_array($defaultID, $caIds))
					$defaultID = $this->_generic->generateControllerId();
				array_push($caIds, $defaultID);
				
				// Generate Actions IDs
				// Home/Index
				$indexID = $this->_generic->generateActionId();
				array_push($caIds, $indexID);
				
				// Default/UrlError
				$urlErrorID = $this->_generic->generateActionId();
				while (in_array($urlErrorID, $caIds))
					$urlErrorID = $this->_generic->generateActionId();
				array_push($caIds, $urlErrorID);
				
				// Default/BadRequestError
				$badRequestID = $this->_generic->generateActionId();
				while (in_array($badRequestID, $caIds))
					$badRequestID = $this->_generic->generateActionId();
				array_push($caIds, $badRequestID);
				
				// Default/AuthorizationError
				$authorizationID = $this->_generic->generateActionId();
				while (in_array($authorizationID, $caIds))
					$authorizationID = $this->_generic->generateActionId();
				array_push($caIds, $authorizationID);
				
				// Default/ForbiddenError
				$forbiddenID = $this->_generic->generateActionId();
				while (in_array($forbiddenID, $caIds))
					$forbiddenID = $this->_generic->generateActionId();
				array_push($caIds, $forbiddenID);
				
				// Default/InternalServerError	
				$serverID = $this->_generic->generateActionId();
				while (in_array($serverID, $caIds))
					$serverID = $this->_generic->generateActionId();
				array_push($caIds, $serverID);
				
				// Default/TemporaryRedirectError	
				$redirectID = $this->_generic->generateActionId();
				while (in_array($redirectID, $caIds))
					$redirectID = $this->_generic->generateActionId();
				array_push($caIds, $redirectID);
				
				// Default/MaintenanceError	
				$maintenanceID = $this->_generic->generateActionId();
				while (in_array($maintenanceID, $caIds))
					$maintenanceID = $this->_generic->generateActionId();
				array_push($caIds, $maintenanceID);
								
				$controllerUser['home']['mod'] = "<controller name=\"Home\" side=\"user\" id=\"".$homeID."\"><controllerLangs>";
				$controllerUser['home']['smod'] = "<scontrollers><scontroller name=\"Index\" needParam=\"0\" id=\"".$indexID."\" default=\"1\"><scontrollerLangs>";
				$controllerUser['default']['mod'] = "<controller name=\"Default\" side=\"user\" id=\"".$defaultID."\"><controllerLangs>";
				$controllerUser['default']['smod']['404'] = "<scontrollers><scontroller name=\"UrlError\" needParam=\"0\" id=\"".$urlErrorID."\"><scontrollerLangs>";
				$controllerUser['default']['smod']['400'] = "<scontroller name=\"BadRequestError\" needParam=\"0\" id=\"".$badRequestID."\"><scontrollerLangs>";
				$controllerUser['default']['smod']['401'] = "<scontroller name=\"AuthorizationError\" needParam=\"0\" id=\"".$authorizationID."\"><scontrollerLangs>";
				$controllerUser['default']['smod']['403'] = "<scontroller name=\"ForbiddenError\" needParam=\"0\" id=\"".$forbiddenID."\"><scontrollerLangs>";
				$controllerUser['default']['smod']['500'] = "<scontroller name=\"InternalServerError\" needParam=\"0\" id=\"".$serverID."\"><scontrollerLangs>";
				$controllerUser['default']['smod']['307'] = "<scontroller name=\"TemporaryRedirectError\" needParam=\"0\" id=\"".$redirectID."\"><scontrollerLangs>";
				$controllerUser['default']['smod']['302'] = "<scontroller name=\"MaintenanceError\" needParam=\"0\" id=\"".$maintenanceID."\"><scontrollerLangs>";
				
				$paramsPost = $this->_http->getParams('post');
				
				$handleLangs = new SLS_XMLToolbox(file_get_contents($this->_generic->getPathConfig("configSls")."international.xml"));
				$projectName = array_shift($this->_generic->getSiteXML()->getTags("projectName"));
				
				/* Create Lang files and Lang Directory
				mkdir($this->_generic->getPathConfig("actionLangs")."Home");
				mkdir($this->_generic->getPathConfig("actionLangs")."Default");	
				*/
				$metasXML = $this->_generic->getCoreXML('metas');
				// Add Empty Actions in metas
				foreach ($caIds as $aId)
				{
					$str = "<action id=\"".$aId."\"></action>";
					$metasXML->appendXMLNode("//sls_configs", $str);
				}
				
				// Foreach langs
				foreach ($langs as $lang) 
				{
					// Home controller
					$controllerUser['home']['mod'] 		.= "<controllerLang lang=\"".$lang."\"><![CDATA[".SLS_String::trimSlashesFromString($this->_http->getParam($lang."_home_mod"))."]]></controllerLang>";
					$controllerUser['home']['smod'] 	.= "<scontrollerLang lang=\"".$lang."\"><![CDATA[".SLS_String::trimSlashesFromString($this->_http->getParam($lang."_home_index"))."]]></scontrollerLang>";
					
					$strTitle = "<title lang=\"".$lang."\"><![CDATA[".SLS_String::trimSlashesFromString($this->_http->getParam($lang."_home_desc"))."]]></title>";
					$strTitle .= "<description lang=\"".$lang."\"><![CDATA[".SLS_String::trimSlashesFromString($this->_http->getParam($lang."_home_description"))."]]></description>";
					$strTitle .= "<keywords lang=\"".$lang."\"><![CDATA[".SLS_String::trimSlashesFromString($this->_http->getParam($lang."_home_keywords"))."]]></keywords>";
					$metasXML->appendXMLNode("//sls_configs/action[@id='".$indexID."']", $strTitle);
					
					// Default controller
					$controllerUser['default']['mod'] 			.= "<controllerLang lang=\"".$lang."\"><![CDATA[".SLS_String::trimSlashesFromString($this->_http->getParam($lang."_error_mod"))."]]></controllerLang>";
					$controllerUser['default']['smod']['404']	.= "<scontrollerLang lang=\"".$lang."\"><![CDATA[".SLS_String::trimSlashesFromString($this->_http->getParam($lang."_error_404_url"))."]]></scontrollerLang>";
					$strTitle = "<title lang=\"".$lang."\"><![CDATA[".SLS_String::trimSlashesFromString($this->_http->getParam($lang."_error_404_desc"))."]]></title>";
					$strTitle .= "<description lang=\"".$lang."\"><![CDATA[".SLS_String::trimSlashesFromString($this->_http->getParam($lang."_error_404_description"))."]]></description>";
					$strTitle .= "<keywords lang=\"".$lang."\"><![CDATA[".SLS_String::trimSlashesFromString($this->_http->getParam($lang."_error_404_keywords"))."]]></keywords>";
					$metasXML->appendXMLNode("//sls_configs/action[@id='".$urlErrorID."']", $strTitle);
					
					$controllerUser['default']['smod']['400']	.= "<scontrollerLang lang=\"".$lang."\"><![CDATA[".SLS_String::trimSlashesFromString($this->_http->getParam($lang."_error_400_url"))."]]></scontrollerLang>";
					$strTitle = "<title lang=\"".$lang."\"><![CDATA[".SLS_String::trimSlashesFromString($this->_http->getParam($lang."_error_400_desc"))."]]></title>";
					$strTitle .= "<description lang=\"".$lang."\"><![CDATA[".SLS_String::trimSlashesFromString($this->_http->getParam($lang."_error_400_description"))."]]></description>";
					$strTitle .= "<keywords lang=\"".$lang."\"><![CDATA[".SLS_String::trimSlashesFromString($this->_http->getParam($lang."_error_400_keywords"))."]]></keywords>";
					$metasXML->appendXMLNode("//sls_configs/action[@id='".$badRequestID."']", $strTitle);
					
					$controllerUser['default']['smod']['401']	.= "<scontrollerLang lang=\"".$lang."\"><![CDATA[".SLS_String::trimSlashesFromString($this->_http->getParam($lang."_error_401_url"))."]]></scontrollerLang>";
					$strTitle = "<title lang=\"".$lang."\"><![CDATA[".SLS_String::trimSlashesFromString($this->_http->getParam($lang."_error_401_desc"))."]]></title>";
					$strTitle .= "<description lang=\"".$lang."\"><![CDATA[".SLS_String::trimSlashesFromString($this->_http->getParam($lang."_error_401_description"))."]]></description>";
					$strTitle .= "<keywords lang=\"".$lang."\"><![CDATA[".SLS_String::trimSlashesFromString($this->_http->getParam($lang."_error_401_keywords"))."]]></keywords>";
					$metasXML->appendXMLNode("//sls_configs/action[@id='".$authorizationID."']", $strTitle);
					
					$controllerUser['default']['smod']['403']	.= "<scontrollerLang lang=\"".$lang."\"><![CDATA[".SLS_String::trimSlashesFromString($this->_http->getParam($lang."_error_403_url"))."]]></scontrollerLang>";
					$strTitle = "<title lang=\"".$lang."\"><![CDATA[".SLS_String::trimSlashesFromString($this->_http->getParam($lang."_error_403_desc"))."]]></title>";
					$strTitle .= "<description lang=\"".$lang."\"><![CDATA[".SLS_String::trimSlashesFromString($this->_http->getParam($lang."_error_403_description"))."]]></description>";
					$strTitle .= "<keywords lang=\"".$lang."\"><![CDATA[".SLS_String::trimSlashesFromString($this->_http->getParam($lang."_error_403_keywords"))."]]></keywords>";
					$metasXML->appendXMLNode("//sls_configs/action[@id='".$forbiddenID."']", $strTitle);
					
					$controllerUser['default']['smod']['500']	.= "<scontrollerLang lang=\"".$lang."\"><![CDATA[".SLS_String::trimSlashesFromString($this->_http->getParam($lang."_error_500_url"))."]]></scontrollerLang>";
					$strTitle = "<title lang=\"".$lang."\"><![CDATA[".SLS_String::trimSlashesFromString($this->_http->getParam($lang."_error_500_desc"))."]]></title>";
					$strTitle .= "<description lang=\"".$lang."\"><![CDATA[".SLS_String::trimSlashesFromString($this->_http->getParam($lang."_error_500_description"))."]]></description>";
					$strTitle .= "<keywords lang=\"".$lang."\"><![CDATA[".SLS_String::trimSlashesFromString($this->_http->getParam($lang."_error_500_keywords"))."]]></keywords>";
					$metasXML->appendXMLNode("//sls_configs/action[@id='".$serverID."']", $strTitle);
					
					$controllerUser['default']['smod']['307']	.= "<scontrollerLang lang=\"".$lang."\"><![CDATA[".SLS_String::trimSlashesFromString($this->_http->getParam($lang."_error_307_url"))."]]></scontrollerLang>";
					$strTitle = "<title lang=\"".$lang."\"><![CDATA[".SLS_String::trimSlashesFromString($this->_http->getParam($lang."_error_307_desc"))."]]></title>";
					$strTitle .= "<description lang=\"".$lang."\"><![CDATA[".SLS_String::trimSlashesFromString($this->_http->getParam($lang."_error_307_description"))."]]></description>";
					$strTitle .= "<keywords lang=\"".$lang."\"><![CDATA[".SLS_String::trimSlashesFromString($this->_http->getParam($lang."_error_307_keywords"))."]]></keywords>";
					$metasXML->appendXMLNode("//sls_configs/action[@id='".$redirectID."']", $strTitle);
					
					$controllerUser['default']['smod']['302']	.= "<scontrollerLang lang=\"".$lang."\"><![CDATA[".SLS_String::trimSlashesFromString($this->_http->getParam($lang."_error_302_url"))."]]></scontrollerLang>";
					$strTitle = "<title lang=\"".$lang."\"><![CDATA[".SLS_String::trimSlashesFromString($this->_http->getParam($lang."_error_302_desc"))."]]></title>";
					$strTitle .= "<description lang=\"".$lang."\"><![CDATA[".SLS_String::trimSlashesFromString($this->_http->getParam($lang."_error_302_description"))."]]></description>";
					$strTitle .= "<keywords lang=\"".$lang."\"><![CDATA[".SLS_String::trimSlashesFromString($this->_http->getParam($lang."_error_302_keywords"))."]]></keywords>";
					$metasXML->appendXMLNode("//sls_configs/action[@id='".$maintenanceID."']", $strTitle);
					
					// Generic langs					
					$genericFile = "<?php\n/**\n * Generic Sls Vars\n */\n";
					$length = strlen($lang."_TRANSLATION");
					foreach ($paramsPost as $key=>$value)
					{
						$value = SLS_String::trimSlashesFromString($value);
						
						if (substr($key, 0, $length) == $lang."_TRANSLATION")
						{
							$genericFile .= '$GLOBALS[$GLOBALS[\'PROJECT_NAME\']][\'JS\'][\'SLS_'.substr($key, $length+1).'\'] = "'.$value.'";';
							$genericFile .= "\n";
						}	
						
					}
					$genericFile .= "?>";
					file_put_contents($this->_generic->getPathConfig("coreGenericLangs")."generic.".$lang.".lang.php", $genericFile);
					
					// Generic lang site
					$language = array_shift($handleLangs->getTags("//sls_configs/sls_country/sls_country_langs/sls_country_lang[@iso = '".$lang."']"));
					$contentSiteLang = "<?php\n/**\n * ".$projectName." Translations\n * Language : ".ucwords($language)." (".strtoupper($lang).")\n */\n\n?>";
					file_put_contents($this->_generic->getPathConfig('genericLangs')."site.".$lang.".lang.php", $contentSiteLang);
				}
				
				// Controllers
				$controllerUser['home']['mod'] 				.= "</controllerLangs>";
				$controllerUser['home']['smod']				.= "</scontrollerLangs></scontroller></scontrollers></controller>";
				
				$controllerUser['default']['mod']			.= "</controllerLangs>";
				$controllerUser['default']['smod']['404']	.= "</scontrollerLangs></scontroller>";
				$controllerUser['default']['smod']['400']	.= "</scontrollerLangs></scontroller>";
				$controllerUser['default']['smod']['401']	.= "</scontrollerLangs></scontroller>";
				$controllerUser['default']['smod']['403']	.= "</scontrollerLangs></scontroller>";
				$controllerUser['default']['smod']['307']	.= "</scontrollerLangs></scontroller>";
				$controllerUser['default']['smod']['302']	.= "</scontrollerLangs></scontroller>";
				$controllerUser['default']['smod']['500']	.= "</scontrollerLangs></scontroller></scontrollers></controller>";
				
				// Formation du Flux Final a append
				$flux = $controllerUser['home']['mod'].$controllerUser['home']['smod'].$controllerUser['default']['mod'].$controllerUser['default']['smod']['404'].$controllerUser['default']['smod']['400'].$controllerUser['default']['smod']['401'].$controllerUser['default']['smod']['403'].$controllerUser['default']['smod']['307'].$controllerUser['default']['smod']['302'].$controllerUser['default']['smod']['500'];
				$xmlControllers->appendXMLNode('//controllers', $flux);
				file_put_contents($this->_generic->getPathConfig("configSecure")."controllers.xml", $xmlControllers->getXML());
				
				// Add meta Tags
				$metasXML->appendXMLNode("//sls_configs/action[@id='".$indexID."']", "<robots><![CDATA[index, follow]]></robots>");
				$metasXML->appendXMLNode("//sls_configs/action[@id='".$urlErrorID."']", "<robots><![CDATA[noindex, follow]]></robots>");
				$metasXML->appendXMLNode("//sls_configs/action[@id='".$authorizationID."']", "<robots><![CDATA[noindex, nofollow]]></robots>");
				$metasXML->appendXMLNode("//sls_configs/action[@id='".$serverID."']", "<robots><![CDATA[noindex, nofollow]]></robots>");
				$metasXML->appendXMLNode("//sls_configs/action[@id='".$forbiddenID."']", "<robots><![CDATA[noindex, nofollow]]></robots>");
				$metasXML->appendXMLNode("//sls_configs/action[@id='".$badRequestID."']", "<robots><![CDATA[noindex, nofollow]]></robots>");
				$metasXML->appendXMLNode("//sls_configs/action[@id='".$redirectID."']", "<robots><![CDATA[noindex, nofollow]]></robots>");
				$metasXML->appendXMLNode("//sls_configs/action[@id='".$maintenanceID."']", "<robots><![CDATA[noindex, nofollow]]></robots>");
				file_put_contents($this->_generic->getPathConfig("configSls")."metas.xml", $metasXML->getXML());
				// Déplacement des Fichiers de déploiement
				
				// Controllers
				if (!is_dir($this->_generic->getPathConfig("actionsControllers")."Home"))
					mkdir($this->_generic->getPathConfig("actionsControllers")."Home");
				if (!is_dir($this->_generic->getPathConfig("actionsControllers")."Default"))
					mkdir($this->_generic->getPathConfig("actionsControllers")."Default");
					
				// Langs
				if (!is_dir($this->_generic->getPathConfig("actionLangs")."Home"))
					mkdir($this->_generic->getPathConfig("actionLangs")."Home");
				if (!is_dir($this->_generic->getPathConfig("actionLangs")."Default"))
					mkdir($this->_generic->getPathConfig("actionLangs")."Default");
				
					
				// Generic Site Protected functions
				copy($this->_generic->getPathConfig("installDeployement")."Controllers/Actions/__site.protected.php", $this->_generic->getPathConfig("actionsControllers")."__site.protected.php");
				
				$homeFiles = scandir($this->_generic->getPathConfig("installDeployement")."Controllers/Actions/Home");
				$defaultFiles = scandir($this->_generic->getPathConfig("installDeployement")."Controllers/Actions/Default");

				// Copy Home Files
				foreach ($homeFiles as $file)
				{
					if (substr($file, (strlen($file)-3)) == "php")
					{ 
						copy($this->_generic->getPathConfig("installDeployement")."Controllers/Actions/Home/".$file, $this->_generic->getPathConfig("actionsControllers")."Home/".$file);
						if (SLS_String::startsWith($file, "__"))
						{
							foreach ($langs as $lang)
							{
								$strLang = '<?php'."\n".
													'/**'."\n".
													'* '.strtoupper($lang).' File for all the Controller Home'."\n".
													'* You can create all your sentences variables here. To create it, follow the exemple :'."\n".
													'* '.t(1).'Access it with JS and XSL variable : $GLOBALS[$GLOBALS[\'PROJECT_NAME\']][\'JS\'][\'KEY_OF_YOUR_VARIABLE\'] = "value of your sentence in '.strtoupper($lang).'";'."\n".
													'* '.t(1).'Access it with XSL variable only   : $GLOBALS[$GLOBALS[\'PROJECT_NAME\']][\'XSL\'][\'KEY_OF_YOUR_VARIABLE\'] = "value of your sentence in '.strtoupper($lang).'";'."\n".
													'*'."\n".
													'* '.t(1).'You can customise the value \'KEY_OF_YOUR_VARIABLE\' and "value of your sentence in '.strtoupper($lang).'" '."\n".
													'* @author SillySmart'."\n".
													'* @copyright SillySmart'."\n".
													'* @package Langs.Actions.'.$controller."\n".
													'* @since 1.0'."\n".
													'*'."\n".
													'*/'."\n".
													'?>';
								file_put_contents($this->_generic->getPathConfig("actionLangs")."Home/__Home.".strtolower($lang).".lang.php", $strLang);
							}
						}
						else 
						{
							
							$actionName = trim(SLS_String::substrBeforeFirstDelimiter($file, ".controller"));
							foreach ($langs as $lang)
							{
								$strLang = '<?php'."\n".
													'/**'."\n".
													'* '.strtoupper($lang).' File for the action '.$actionName.' into Home Controller'."\n".
													'* You can create all your sentences variables here. To create it, follow the exemple :'."\n".
													'* '.t(1).'Access it with JS and XSL variable : $GLOBALS[$GLOBALS[\'PROJECT_NAME\']][\'JS\'][\'KEY_OF_YOUR_VARIABLE\'] = "value of your sentence in '.strtoupper($lang).'";'."\n".
													'* '.t(1).'Access it with XSL variable only   : $GLOBALS[$GLOBALS[\'PROJECT_NAME\']][\'XSL\'][\'KEY_OF_YOUR_VARIABLE\'] = "value of your sentence in '.strtoupper($lang).'";'."\n".
													'*'."\n".
													'* '.t(1).'You can customise the value \'KEY_OF_YOUR_VARIABLE\' and "value of your sentence in '.strtoupper($lang).'" '."\n".
													'* @author SillySmart'."\n".
													'* @copyright SillySmart'."\n".
													'* @package Langs.Actions.Home'."\n".
													'* @since 1.0'."\n".
													'*'."\n".
													'*/'."\n".
													'?>';
								file_put_contents($this->_generic->getPathConfig("actionLangs")."Home/".$actionName.".".strtolower($lang).".lang.php", $strLang);
							}
						}
					}
				}
				
				// Copy Default Files
				foreach ($defaultFiles as $file)
				{
					if (substr($file, (strlen($file)-3)) == "php")
					{ 
						copy($this->_generic->getPathConfig("installDeployement")."Controllers/Actions/Default/".$file, $this->_generic->getPathConfig("actionsControllers")."Default/".$file);
						if (SLS_String::startsWith($file, "__"))
						{
							foreach ($langs as $lang)
							{
								$strLang = '<?php'."\n".
													'/**'."\n".
													'* '.strtoupper($lang).' File for all the Controller Default'."\n".
													'* You can create all your sentences variables here. To create it, follow the exemple :'."\n".
													'* '.t(1).'Access it with JS and XSL variable : $GLOBALS[$GLOBALS[\'PROJECT_NAME\']][\'JS\'][\'KEY_OF_YOUR_VARIABLE\'] = "value of your sentence in '.strtoupper($lang).'";'."\n".
													'* '.t(1).'Access it with XSL variable only   : $GLOBALS[$GLOBALS[\'PROJECT_NAME\']][\'XSL\'][\'KEY_OF_YOUR_VARIABLE\'] = "value of your sentence in '.strtoupper($lang).'";'."\n".
													'*'."\n".
													'* '.t(1).'You can customise the value \'KEY_OF_YOUR_VARIABLE\' and "value of your sentence in '.strtoupper($lang).'" '."\n".
													'* @author SillySmart'."\n".
													'* @copyright SillySmart'."\n".
													'* @package Langs.Actions.Default'."\n".
													'* @since 1.0'."\n".
													'*'."\n".
													'*/'."\n".
													'?>';
								file_put_contents($this->_generic->getPathConfig("actionLangs")."Default/__Default.".strtolower($lang).".lang.php", $strLang);
							}
						}
						else 
						{
							
							$actionName = trim(SLS_String::substrBeforeFirstDelimiter($file, ".controller"));
							foreach ($langs as $lang)
							{
								$strLang = '<?php'."\n".
													'/**'."\n".
													'* '.strtoupper($lang).' File for the action '.$actionName.' into Default Controller'."\n".
													'* You can create all your sentences variables here. To create it, follow the exemple :'."\n".
													'* '.t(1).'Access it with JS and XSL variable : $GLOBALS[$GLOBALS[\'PROJECT_NAME\']][\'JS\'][\'KEY_OF_YOUR_VARIABLE\'] = "value of your sentence in '.strtoupper($lang).'";'."\n".
													'* '.t(1).'Access it with XSL variable only   : $GLOBALS[$GLOBALS[\'PROJECT_NAME\']][\'XSL\'][\'KEY_OF_YOUR_VARIABLE\'] = "value of your sentence in '.strtoupper($lang).'";'."\n".
													'*'."\n".
													'* '.t(1).'You can customise the value \'KEY_OF_YOUR_VARIABLE\' and "value of your sentence in '.strtoupper($lang).'" '."\n".
													'* @author SillySmart'."\n".
													'* @copyright SillySmart'."\n".
													'* @package Langs.Actions.Home'."\n".
													'* @since 1.0'."\n".
													'*'."\n".
													'*/'."\n".
													'?>';
								file_put_contents($this->_generic->getPathConfig("actionLangs")."Default/".$actionName.".".strtolower($lang).".lang.php", $strLang);
							}
						}
					}
				}
					
				// Views
				if (!is_dir($this->_generic->getPathConfig("viewsBody")."Home"))
					mkdir($this->_generic->getPathConfig("viewsBody")."Home");
				if (!is_dir($this->_generic->getPathConfig("viewsBody")."Default"))
					mkdir($this->_generic->getPathConfig("viewsBody")."Default");
				if (!is_dir($this->_generic->getPathConfig("viewsHeaders")."Home"))
					mkdir($this->_generic->getPathConfig("viewsHeaders")."Home");
				if (!is_dir($this->_generic->getPathConfig("viewsHeaders")."Default"))
					mkdir($this->_generic->getPathConfig("viewsHeaders")."Default");
				
				$homeBodyFiles = scandir($this->_generic->getPathConfig("installDeployement")."Views/Body/Home");
				$defaultBodyFiles = scandir($this->_generic->getPathConfig("installDeployement")."Views/Body/Default");
				$homeHeadersFiles = scandir($this->_generic->getPathConfig("installDeployement")."Views/Headers/Home");
				$defaultHeadersFiles = scandir($this->_generic->getPathConfig("installDeployement")."Views/Headers/Default");

				// Copy Home Body Views
				foreach ($homeBodyFiles as $file)
					(substr($file, (strlen($file)-3)) == "xsl") ? copy($this->_generic->getPathConfig("installDeployement")."Views/Body/Home/".$file, $this->_generic->getPathConfig("viewsBody")."Home/".$file) : "";
				
				// Copy Default Body Views
				foreach ($defaultBodyFiles as $file)
					(substr($file, (strlen($file)-3)) == "xsl") ? copy($this->_generic->getPathConfig("installDeployement")."Views/Body/Default/".$file, $this->_generic->getPathConfig("viewsBody")."Default/".$file) : "";	
					
				// Copy Home Headers Views
				foreach ($homeHeadersFiles as $file)
					(substr($file, (strlen($file)-3)) == "xsl") ? copy($this->_generic->getPathConfig("installDeployement")."Views/Headers/Home/".$file, $this->_generic->getPathConfig("viewsHeaders")."Home/".$file) : "";
				
				// Copy Default Headers Views
				foreach ($defaultHeadersFiles as $file)
					(substr($file, (strlen($file)-3)) == "xsl") ? copy($this->_generic->getPathConfig("installDeployement")."Views/Headers/Default/".$file, $this->_generic->getPathConfig("viewsHeaders")."Default/".$file) : "";	
				
				
								
				$this->setInstallationStep(array(0=>"SLS_Init",1=>"Initialization"), array(0=>"DataBase",1=>"DataBase"));
				return $this->_generic->dispatch("SLS_Init", "DataBase");				
			}
			else 
			{
				$xml->startTag('errors');			
				foreach ($errors as $error)
					$xml->addFullTag('error', $error, true);
				$xml->endTag('errors');
				$giveDataStep1 = true;
				$step = 1;
			}
			
		}
		// Sinon, default
		else
		{
			$step = 0;
		}
		if ($giveDataStep1 == true)
		{
			$xml->startTag("choose_langs");
			$valueToHidden = "";
			$isos = array();
			foreach($listLangs as $listLang)
			{
				$iso = array_shift($handle->getTags("//sls_configs/sls_country/sls_country_langs/sls_country_lang[node()='".$listLang."']/@iso"));
				array_push($isos, $iso);
				$xml->startTag("choose_lang");					
				$xml->addFullTag("iso",$iso,true);
				$xml->addFullTag("label",$listLang,true);
				$xml->endTag("choose_lang");
				$valueToHidden .= "-".$listLang;
			}
			$xml->endTag("choose_langs");
			$xml->addFullTag("hidden_langs", substr($valueToHidden, 1), true);
			// Récupération des mots à traduire
			$xml->startTag("translate");
			foreach ($isos as $iso)
			{
				$xml->startTag($iso);
					if (is_file($this->_generic->getPathConfig("coreGenericLangs")."generic.".$iso.".lang.php"))
						$handle = fopen($this->_generic->getPathConfig("coreGenericLangs")."generic.".$iso.".lang.php", 'r');
					else 
						$handle = fopen($this->_generic->getPathConfig("coreGenericLangs")."generic.en.lang.php", 'r');
					$array = array();
					while (!feof($handle)) 
					{
						$line = fgets($handle, 4096);
						if (substr($line, 0, 1) == "$")
						{
							$tmpArray = array();
							$tmpArray['name'] =  str_replace("SLS_", "", SLS_String::substrAfterLastDelimiter(SLS_String::substrBeforeLastDelimiter($line, "']"), "['"));
							$tmpArray['value'] = SLS_String::substrBeforeLastDelimiter(SLS_String::substrAfterFirstDelimiter(trim(SLS_String::substrAfterLastDelimiter($line, " = ")), '"'), '"');
							array_push($array, $tmpArray);
						}
					}
					
					foreach ($array as $row)
					{
						$xml->startTag("sentence");
							$xml->addFullTag('name', strtolower(str_replace("_", " ", $row['name'])), true);
							$xml->addFullTag('code', $row['name'], true);
							$xml->addFullTag('value', $row['value'], true);
						$xml->endTag("sentence");
					}
				$xml->endTag($iso);
			}
			$xml->endTag("translate");
		}
		$xml->addFullTag("step", $step, true);
		$this->saveXML($xml);
	}
	/**
	 * Delete files on columns for current tables
	 * 
	 * @access public
	 * @param array $columns columns on which you want to delete specific files (all columns of table if empty)
	 * @since 1.0.8
	 */
	public function deleteFiles($columns=array())
	{
		// Check type files		
		$xmlType = new SLS_XMLToolbox(file_get_contents($this->_generic->getPathConfig("configSls")."/types.xml"));		
		$results = $xmlType->getTagsAttribute("//sls_configs/entry[@table='".$this->getDatabase()."_".$this->getTable()."' and (@type='file_all' or @type='file_img')]","column");
		
		if (empty($columns))
			$columns = $this->getColumns();
		
		if (!empty($results))
		{
			foreach($this->getParams() as $column => $value)
			{
				if (!in_array($column,$columns))
					continue;
				
				$result = array_shift($xmlType->getTagsAttributes("//sls_configs/entry[@table='".$this->getDatabase()."_".$this->getTable()."' and @column='".$column."' and (@type='file_all' or @type='file_img')]",array("type","thumbs")));
				if (!empty($result) && $this->getColumnDefault($column) != $value)
				{					
					$clone = $this->countModels($this->getTable(),array(),array(array("column"=>$column,"value"=>$value,"mode"=>"equal")));
					$type = $result["attributes"][0]["value"];
					
					if (file_exists($this->_generic->getPathConfig("files").$value) && !is_dir($this->_generic->getPathConfig("files").$value) && $clone < 2)
					{
						if (!file_exists($this->_generic->getPathConfig("files")."__Uploads"))
							@mkdir($this->_generic->getPathConfig("files")."__Uploads");
						if (!file_exists($this->_generic->getPathConfig("files")."__Uploads/__Deprecated"))
							@mkdir($this->_generic->getPathConfig("files")."__Uploads/__Deprecated");
						if (!file_exists($this->_generic->getPathConfig("files")."__Uploads/__Deprecated/".$this->getTable()))
							@mkdir($this->_generic->getPathConfig("files")."__Uploads/__Deprecated/".$this->getTable());
						
						if ($type == "file_all")
						{
							try{
								@rename($this->_generic->getPathConfig("files").$value,$this->_generic->getPathConfig("files")."__Uploads/__Deprecated/".$value);
							}
							catch (Exception $e){}
						}
						else
						{
							$thumbs = unserialize(str_replace("||#||",'"',$result["attributes"][1]["value"]));
							@rename($this->_generic->getPathConfig("files").$value,$this->_generic->getPathConfig("files")."__Uploads/__Deprecated/".$value);
							$baseName = $this->_generic->getPathConfig("files").SLS_String::substrBeforeLastDelimiter($value, ".".pathinfo($value,PATHINFO_EXTENSION));
							$baseExtension = pathinfo($value,PATHINFO_EXTENSION);
							
							foreach($thumbs as $thumb)
							{
								if (file_exists($baseName.$thumb["suffix"].".".$baseExtension) && !is_dir($baseName.$thumb["suffix"].".".$baseExtension))
									@rename($baseName.$thumb["suffix"].".".$baseExtension,$this->_generic->getPathConfig("files")."__Uploads/__Deprecated/".SLS_String::substrBeforeLastDelimiter($value, ".".pathinfo($value,PATHINFO_EXTENSION)).$thumb["suffix"].".".pathinfo($value,PATHINFO_EXTENSION));
							}
						}
					} 
				}
			}
		}
	}
	public function action()
	{
		$user = $this->hasAuthorative();
		$xml = $this->getXML();
		$xml = $this->makeMenu($xml);
		$errors = array();
		
		$plugin = new SLS_XMLToolbox(file_get_contents($this->_generic->getPathConfig("configPlugins")."/plugins.xml"));
		$pluginMobile = $plugin->getTag("//plugins/plugin[@code='mobile']");
		$pluginMobile = (!empty($pluginMobile)) ? true : false;
		
		if ($this->_http->getParam('reload') == 'true')
		{
			$controller = SLS_String::trimSlashesFromString($this->_http->getParam('controllerName'));
			$cache_visibility = SLS_String::trimSlashesFromString($this->_http->getParam('cache_visibility'));
			$cache_expiration = SLS_String::trimSlashesFromString($this->_http->getParam('cache_expiration'));
			$cache_responsive = SLS_String::trimSlashesFromString($this->_http->getParam('cache_responsive'));
			
			// If responsive wanted
			if ($cache_responsive == "true" && !$pluginMobile)
			{
				// Force Mobile plugin download
				file_get_contents($this->_generic->getFullPath("SLS_Bo",
															  "SearchPlugin",
															  array("Action" => "Download",
															  		"Server" => "4",
															  		"Plugin" => "20",
															  		"token"	 => sha1(substr($this->_generic->getSiteConfig("privateKey"), 0, 3).substr($this->_generic->getSiteConfig("privateKey"), strlen($this->_generic->getSiteConfig("privateKey"))-3))),
															  true));
			}
			
			if (empty($controller))
				array_push($errors, "You must fill the component controller name");
			if (in_array($cache_visibility,array("public","private")) && (!is_numeric($cache_expiration) || $cache_expiration < 0))
				array_push($errors, "Your expiration cache must be a positive time or 0");
			
			$controller = str_replace(" ", "", ucwords(trim(SLS_String::getAlphaString($controller))));
			
			$components = $this->_generic->recursiveReadDir($this->_generic->getPathConfig("componentsControllers"), array(), array(0=>"php"));
			foreach ($components as $component)
			{
				if (SLS_String::substrBeforeLastDelimiter(SLS_String::substrAfterLastDelimiter($component, "/"), ".controller.php") == $controller)
				{
					array_push($errors, "The name '".$controller."' is already in use for a component controller");
					break;
				}
			}
			
			if (empty($errors))
			{
				$strNewComponent = '<?php'."\n".
						   '/**'."\n".
						   '* Controller Component '.$controller.'Controller'."\n".
						   '*'."\n".
						   '* @author SillySmart'."\n".
						   '* @copyright SillySmart'."\n".
						   '* @package Mvc.Controllers.Components.'.$controller.'Controller'."\n".
						   '* @see Sls.Controllers.Core.SLS_FrontComponent'."\n".
						   '* @since 1.0'."\n".
						   '*/'."\n".
						   'class '.$controller.'Controller extends SLS_FrontComponent implements SLS_IComponent '."\n".
						   '{'."\n".
						   ''."\n".
						   t(1).'public function __construct()'."\n".
						   t(1).'{'."\n".
						   		t(2).'parent::__construct(true);'."\n".
						   t(1).'}'."\n".
						   ''."\n".
						   t(1).'public function constructXML()'."\n".
						   t(1).'{'."\n".
						   		t(2).'// Write here all your instructions to make your Component configuration with xml by $this->_xmlToolBox'."\n".
						   t(1).'}'."\n".
						   ''."\n".
						   '}'."\n".
						   '?>'; 
				file_put_contents($this->_generic->getPathConfig("componentsControllers").$controller.".controller.php", $strNewComponent);

				// Cache
				if (in_array($cache_visibility,array("public","private")))
				{
					$this->_cache->addObject(strtolower($controller),"components",$cache_visibility,($cache_responsive=="true") ? "responsive" : "no_responsive",$cache_expiration);
					$this->_cache->saveObject();
				}
				
				$this->_generic->forward('SLS_Bo', 'Controllers'); 
		
			}
			
			if (!empty($errors))
			{
				$xml->startTag("errors");
					foreach ($errors as $error)
						$xml->addFullTag("error", $error, true);
				$xml->endTag("errors");
				$xml->startTag('form');
					$xml->addFullTag("controllerName", $controller);
					$xml->addFullTag("cache_visibility", $cache_visibility,true);
					$xml->addFullTag("cache_expiration", $cache_expiration,true);
					$xml->addFullTag("cache_responsive", $cache_responsive,true);						
				$xml->endTag('form');
			}
		}
		else
		{
			$xml->startTag('form');
				$xml->addFullTag("controllerName", $controller,true);
				$xml->addFullTag("cache_visibility", "",true);
				$xml->addFullTag("cache_expiration", "0",true);
				$xml->addFullTag("cache_responsive", "",true);
			$xml->endTag('form');
		}
		
		$this->saveXML($xml);
	}
	public function action()
	{
		// Objects
		$xml = $this->getXML();

		$user = $this->hasAuthorative();
		$xml = $this->makeMenu($xml);
		
		$date = $this->_http->getParam("date");
		$dateE = explode("-",$date);
		$dateL = new SLS_Date($date);
		
		if (is_array($dateE) && count($dateE) == 3 && is_dir($this->_generic->getPathConfig("logs")."monitoring/".$dateE[0]."-".$dateE[1]))
		{
			$content = "";
			$i = 0;
			
			while(file_exists($this->_generic->getPathConfig("logs")."monitoring/".$dateE[0]."-".$dateE[1]."/".$dateE[0]."-".$dateE[1]."-".$dateE[2]."_".$i.".log"))
			{
				$content .= file_get_contents($this->_generic->getPathConfig("logs")."monitoring/".$dateE[0]."-".$dateE[1]."/".$dateE[0]."-".$dateE[1]."-".$dateE[2]."_".$i.".log");
				$i++;
			}
			$batchs = explode("#|end|#",$content);
			
			$xml->startTag("batchs");
			$xml->addFullTag("date",$dateL->getDate("FULL_LITTERAL"));
			foreach($batchs as $batch)
			{
				if (!empty($batch))
				{
					$lines = explode("\n",$batch);
					
					$times = array ("Render"			=> 0,
									"XML/XSL Parsing"	=> 0,									
									"MySQL Query"		=> 0,
									"Controller Action"	=> 0,
									"Controller Front"	=> 0,
									"Controller Static" => 0);
					$msg = "";
					$totalTime = 0;
					$endTime = 0;
					
					$xml->startTag("batch");
						$xml->startTag("lines");
						foreach($lines as $line)
						{
							$infos = explode("||",$line);
							$infos = array_map('trim',$infos);
							
							if (count($infos) > 4)
							{
								$times[$infos[0]] += $infos[2];
								if ($infos[0] == "Render")
								{
									$totalTime = $infos[2];
									$endTime = SLS_String::substrAfterFirstDelimiter($infos[1]," ");
								}
								if ($infos[0] == "Controller Front")								
									$msg = SLS_String::substrAfterFirstDelimiter(SLS_String::substrBeforeLastDelimiter($infos[3],")"),"(");
								
								$xml->startTag("line");
									$xml->addFullTag("msg",$infos[3],true);
									$xml->addFullTag("type",$infos[0],true);
									$xml->addFullTag("more",str_replace(array("|n|","|t|","    "),array("<br />","&#160;&#160;","&#160;&#160;&#160;&#160;"),$infos[4]),true);
									$xml->addFullTag("time",SLS_String::substrAfterFirstDelimiter($infos[1]," "),true);
									$xml->addFullTag("duration",$infos[2],true);
								$xml->endTag("line");
							}
						}
						$xml->endTag("lines");
						$xml->startTag("infos");
							$xml->addFullTag("name",$endTime." - ".$msg,true);
							$xml->startTag("times");
								$xml->addFullTag("total",$totalTime,true);
								foreach($times as $key => $value)
									$xml->addFullTag(SLS_String::stringToUrl(trim($key),"_"),$value,true);
							$xml->endTag("times");
						$xml->endTag("infos");
						$sum = 0;
						$xml->startTag("ratios");
						foreach($times as $key => $value)
						{
							if ($key == "Render")
								continue;
							else
								$sum += $value;
								
							$xml->startTag("ratio");
								$xml->addFullTag("label",str_replace(" ","+",trim($key)),true);
								$xml->addFullTag("duration",$times[$key],true);								
								$xml->addFullTag("degree",($totalTime > 0) ? 360 * $value / $totalTime : "360",true);
							$xml->endTag("ratio");
						}
						if ($totalTime - $sum > 0)
						{
							$xml->startTag("ratio");
								$xml->addFullTag("label","Others",true);
								$xml->addFullTag("duration",$sum,true);	
								$xml->addFullTag("degree",($totalTime > 0) ? 360 * $sum / $totalTime : "360",true);
							$xml->endTag("ratio");
						}
						$xml->endTag("ratios");
					$xml->endTag("batch");
				}
			}
			$xml->endTag("batchs");			
		}
		
		$this->saveXML($xml);
	}
	/**
	 * Flush logs (monitoring & application) older than 2 months
	 * 
	 * @access private
	 * @since 1.0.8
	 */
	private function flushLogs()
	{
		$date = SLS_String::substrBeforeLastDelimiter(SLS_Date::timestampToDate(strtotime("-3 month")),"-");
		if (!file_exists($this->getPathConfig("logs")."monitoring"))
			@mkdir($this->getPathConfig("logs")."monitoring");
		$handle = opendir($this->getPathConfig("logs")."monitoring");
		
		// Foreach directories, if it's older than 2 months, delete it
		while (false !== ($dir = readdir($handle)))		
			if (is_dir($this->getPathConfig("logs")."monitoring/".$dir) && substr($dir, 0, 1) != "." && ($dir <= $date))
				$this->rm_recursive($this->getPathConfig("logs")."/monitoring/".$dir);
				
		$handle = opendir($this->getPathConfig("logs"));
		
		// Foreach directories, if it's older than 2 months, delete it
		while (false !== ($dir = readdir($handle)))		
			if (is_dir($this->getPathConfig("logs").$dir) && substr($dir, 0, 1) != "." && $dir != "monitoring" && ($dir <= $date))
				$this->rm_recursive($this->getPathConfig("logs").$dir);
	}