replace MySqlManager with Db

This commit is contained in:
francois
2018-04-11 20:20:23 +02:00
parent 5c7dd8d4c2
commit 8bb84c1a24
4 changed files with 38 additions and 810 deletions

View File

@@ -1,157 +0,0 @@
<?php
class Auth extends PhpObject
{
const ALGO = PASSWORD_DEFAULT;
const COST = 12;
const TOKEN_SEP = '|';
const USER_COOKIE_PASS = 'checksum';
const DEFAULT_PASS = 'planeum01';
/**
* Database Connection
* @var MySqlManager
*/
private $oMySql;
private $iUserId;
private $sApiKey;
public function __construct($oMySql, $sApiKey='')
{
$this->oMySql = $oMySql;
$this->setUserId(0);
$this->sApiKey = $sApiKey;
$this->autoLogIn();
}
private function setUserId($iUserId)
{
$this->iUserId = $iUserId;
}
public function getUserId()
{
return $this->iUserId;
}
public function isLoggedIn()
{
return ($this->getUserId() > 0);
}
public function logMeIn($sToken)
{
$sDesc = '';
if($sToken!='')
{
$sLoginToken = addslashes(strstr($sToken, self::TOKEN_SEP, true));
$sPassToken = substr(strstr($sToken, self::TOKEN_SEP), strlen(self::TOKEN_SEP));
if($sLoginToken!='' && $sPassToken!='')
{
$asEmpl = $this->oMySql->selectRow("EMPLOYEE", array('MD5(EMAIL)'=>$sLoginToken));
if(!empty($asEmpl))
{
if(self::CheckPassword($sPassToken, $asEmpl['PASS']))
{
$this->setUserId($asEmpl['ID']);
$this->resetAuthCookie($this->getUserId());
}
else $sDesc = 'mot de passe incorrect';
}
else $sDesc = 'email inconnu';
}
else $sDesc = 'token corrompu';
}
else $sDesc = 'Aucune information reçue par le serveur';
return CvTheque::getJsonResult($this->isLoggedIn(), $sDesc);
}
public function autoLogIn()
{
if(isset($_COOKIE[self::USER_COOKIE_PASS]))
{
$sCookie = $_COOKIE[self::USER_COOKIE_PASS];
$iUserId = addslashes(strstr($sCookie, self::TOKEN_SEP, true));
$sCookie = substr(strstr($sCookie, self::TOKEN_SEP), strlen(self::TOKEN_SEP));
$asEmpl = $this->oMySql->selectRow("EMPLOYEE", array('ID'=>$iUserId));
if(!empty($asEmpl))
{
if($sCookie==$asEmpl['COOKIE'])
{
$this->setUserId($asEmpl['ID']);
//Reset pass once a day
if(mb_substr($asEmpl['LED'], 0, 10) != date('Y-m-d')) $this->resetAuthCookie($this->getUserId());
}
else $this->addError('token corrompu pour le user '.$asEmpl['ID']);
}
else $this->addError('Utilisateur '.$iUserId.' inconnu');
}
}
//TODO integrate with logMeIn()
public function checkApiKey($sApiKey)
{
return ($this->sApiKey!='' && $sApiKey==$this->sApiKey);
}
public function resetPass($iUserId=0)
{
if($iUserId>0) $asUsers = array($iUserId);
else $asUsers = $this->oMySql->selectRows(array('select'=>array('ID'), 'from'=>'EMPLOYEE'));
foreach($asUsers as $iUserId)
{
$sToken = $this->HashPassword(self::getLoginToken(self::DEFAULT_PASS));
$this->oMySql->updateRow('EMPLOYEE', array('ID'=>$iUserId), array('pass'=>$sToken));
}
}
private static function getLoginToken($sPass)
{
//Add Server Name
$sServerName = array_key_exists('SERVER_NAME', $_SERVER)?$_SERVER['SERVER_NAME']:$_SERVER['PWD'];
$sAppPath = 'http://'.str_replace('http://', '', $sServerName.dirname($_SERVER['SCRIPT_NAME']));
$_GET['serv_name'] = $sAppPath.(mb_substr($sAppPath, -1)!='/'?'/':'');
return md5($sPass.$_GET['serv_name']);
}
private function resetAuthCookie($iUserId)
{
$sNewPass = self::getAuthCookie($iUserId);
$iTimeLimit = time()+60*60*24*30;
//mysqli_query($con, "UPDATE EMPLOYEE SET COOKIE = '".addslashes($sNewPass)."' WHERE ID = ".$iUserId);
$this->oMySql->updateRow("EMPLOYEE", array("ID"=>$iUserId), array("COOKIE"=>$sNewPass));
setcookie(self::USER_COOKIE_PASS, $iUserId.self::TOKEN_SEP.$sNewPass, $iTimeLimit);
}
private static function getAuthCookie()
{
return self::HashPassword
(
$_SERVER['HTTP_USER_AGENT'].
$_SERVER['REMOTE_ADDR'].
$_SERVER['REQUEST_TIME'].
mb_strstr(microtime(), ' ', true).
$_SERVER['SERVER_SIGNATURE'].
$_SERVER['SERVER_ADMIN']
);
}
private static function HashPassword($sPass)
{
return password_hash($sPass, self::ALGO, array('cost'=>self::COST));
}
private static function CheckPassword($sPass, $sHash)
{
return password_verify($sPass, $sHash);
}
}
?>

View File

@@ -3,7 +3,7 @@
/** /**
* Main Class * Main Class
* @author franzz * @author franzz
* @version 2.1 * @version 2.2
*/ */
abstract class Main extends PhpObject abstract class Main extends PhpObject
{ {
@@ -23,7 +23,7 @@ abstract class Main extends PhpObject
//Objects //Objects
protected $oClassManagement; protected $oClassManagement;
protected $oMySql; protected $oDb;
//private $oTranslator; //private $oTranslator;
//... //...
@@ -44,27 +44,27 @@ abstract class Main extends PhpObject
* @param ClassManagement $oClassManagement * @param ClassManagement $oClassManagement
* @param string $sLang * @param string $sLang
*/ */
public function __construct($oClassManagement, $sProcessPage/*, $sLang=''*/) public function __construct($oClassManagement, $sProcessPage, $asMandatoryClasses=array()/*, $sLang=''*/)
{ {
parent::__construct(__CLASS__, Settings::DEBUG); parent::__construct(__CLASS__, Settings::DEBUG);
$this->oClassManagement = $oClassManagement; $this->oClassManagement = $oClassManagement;
//Load classes //Load classes
$this->oClassManagement->incClass('mask'); $asMandatoryClasses[] = array('name'=>'mask', 'project'=>false);
$asMandatoryClasses[] = array('name'=>'db', 'project'=>false);
foreach($asMandatoryClasses as $asClass) $this->oClassManagement->incClass($asClass['name'], $asClass['project']);
$this->setContext($sProcessPage); $this->setContext($sProcessPage);
//$this->oClassManagement->incClass('translator'); //$this->oClassManagement->incClass('translator');
$this->oClassManagement->incClass('mysqlmanager');
//$this->oClassManagement->incClass('auth'); //$this->oClassManagement->incClass('auth');
//... //...
//Init objects //Init objects
//$this->setLanguage($sLang); //$this->setLanguage($sLang);
//$this->oTranslator = new Translator($this->getLanguage()); //$this->oTranslator = new Translator($this->getLanguage());
$this->oMySql = new MySqlManager(Settings::DB_SERVER, Settings::DB_LOGIN, Settings::DB_PASS, Settings::DB_NAME, $this->getSqlOptions() , Settings::DB_ENC); $this->oDb = new Db(Settings::DB_SERVER, Settings::DB_LOGIN, Settings::DB_PASS, Settings::DB_NAME, $this->getSqlOptions() , Settings::DB_ENC);
if($this->oMySql->sDbState == MySqlManager::DB_NO_DATA) $this->install(); if($this->oDb->sDbState == Db::DB_NO_DATA) $this->install();
//...
} }
protected abstract function install(); protected abstract function install();
@@ -97,7 +97,7 @@ abstract class Main extends PhpObject
/* Building main pages */ /* Building main pages */
public function getMainPage($asGlobalVars=array(), $sMainPage='index') public function getMainPage($asGlobalVars=array(), $sMainPage='index', $asMainPageTags=array())
{ {
$asGlobalVars['consts'] = array('success'=>self::SUCCESS, 'error'=>self::ERROR, 'process_page'=>$this->asContext['process_page']); $asGlobalVars['consts'] = array('success'=>self::SUCCESS, 'error'=>self::ERROR, 'process_page'=>$this->asContext['process_page']);
@@ -106,11 +106,14 @@ abstract class Main extends PhpObject
foreach($asPages as $sPage) foreach($asPages as $sPage)
{ {
$sPageContent = $this->getPageContent($sPage); $sPageContent = $this->getPageContent($sPage);
if($sPage==$sMainPage) $sMainPageContent = $sPageContent; if($sPage!=$sMainPage) $asGlobalVars['consts']['pages'][$sPage] = $sPageContent;
else $asGlobalVars['consts']['pages'][$sPage] = $sPageContent;
} }
return str_replace('asGlobalVars', json_encode($asGlobalVars), $sMainPageContent); $oMainMask = new Mask($sMainPage);
$oMainMask->setTag('GLOBAL_VARS', json_encode($asGlobalVars));
$oMainMask->setTags($asMainPageTags);
return $oMainMask->getMask();
} }
protected function getPageContent($sPage) protected function getPageContent($sPage)
@@ -118,7 +121,7 @@ abstract class Main extends PhpObject
return /*utf8_encode(*/file_get_contents(self::MASKS_FOLDER.$sPage.'.html')/*)*/; return /*utf8_encode(*/file_get_contents(self::MASKS_FOLDER.$sPage.'.html')/*)*/;
} }
/* DB structure. See MySqlManager::__construct */ /* DB structure. See Db::__construct */
protected abstract function getSqlOptions(); protected abstract function getSqlOptions();

View File

@@ -1,617 +0,0 @@
<?php
/**
* MySql query manager and generator
* @author franzz
* @version 1.0
*/
class MySqlManager extends PhpObject
{
const DB_NO_CONN = 'ERR_1';
const DB_NO_DATA = 'ERR_2';
const ID_TAG = 'id_';
const MYSQL_TIMESTAMP = 'Y-m-d H:i:s';
public $sDbState;
private $bTrace;
/**
* SQL connection Handle
* @var mysqli
*/
private $oConnection;
private $sDatabase;
private $asOptions;
/**
* Tables & fields descriptions
* array( 'tables'=>array('table_name1'=>array('table_field1', 'table_field2', ...), 'table_name2'=>array(...)),
* 'types'=>array('field1'=>'field_type1', 'field2'=>'field_type2', ...)
* 'constraints'=>array('table_name1'=>'table_contraint1', 'table_name2'=>'table_contraint2', ...),
* 'cascading_delete'=>array('table_name1'=>array('linked_table1', 'linked_table2', ...), 'table_name2'=>...))
* @var Array
*/
public function __construct($sDbServer, $sLogin, $sPass, $sDatabase, $asOptions, $sEncoding='utf8mb4')
{
parent::__construct(__CLASS__, Settings::DEBUG);
$this->sDatabase = $sDatabase;
$this->asOptions = $asOptions;
//$this->oConnection = mysql_connect(self::DB_SERVER, self::DB_LOGIN, self::DB_PASS);
$this->oConnection = new mysqli($sDbServer, $sLogin, $sPass);
$this->syncPhpParams($sEncoding);
/*
$dsn = 'mysql:dbname='.$this->sDatabase.';host='.self::DB_SERVER;
try {$dbh = new PDO($dsn, self::DB_LOGIN, self::DB_PASS);}
catch (PDOException $e) {$this->addError('Connexion échouée : ' . $e->getMessage());}
*/
$this->setTrace(false);
if($this->oConnection->connect_error)
{
$this->addError('bug connection : '.$this->oConnection->connect_error);
$this->sDbState = self::DB_NO_CONN;
}
else
{
if(!$this->oConnection->select_db($this->sDatabase))
{
$this->addError('bug selecting database. Installing...');
$this->sDbState = self::DB_NO_DATA;
}
}
}
private function syncPhpParams($sEncoding)
{
//Characters encoding
$this->oConnection->set_charset($sEncoding); //SET NAMES
//Time zone
$oNow = new DateTime();
$iMins = $oNow->getOffset() / 60;
$iSign = ($iMins < 0)?-1:1;
$iMins = abs($iMins);
$iHours = floor($iMins / 60);
$iMins -= $iHours * 60;
$sOffset = sprintf('%+d:%02d', $iHours*$iSign, $iMins);
$this->setQuery("SET time_zone='{$sOffset}';");
}
public function __destruct()
{
parent::__destruct();
$this->oConnection->close();
}
public function setTrace($bTrace)
{
$this->bTrace = $bTrace;
if($bTrace) $this->setDebug(true);
}
public function getTrace()
{
return $this->bTrace;
}
public function getTables()
{
return array_keys($this->asOptions['tables']);
}
public function install()
{
//Create Database
$this->setQuery("DROP DATABASE IF EXISTS ".$this->sDatabase);
$this->setQuery("CREATE DATABASE ".$this->sDatabase." DEFAULT CHARACTER SET ".Settings::DB_ENC." DEFAULT COLLATE ".Settings::DB_ENC."_general_ci");
$this->oConnection->select_db($this->sDatabase);
//Create tables
@array_walk($this->getInstallQueries(), array($this, 'setQuery'));
}
//For debug purposes
public function getFullInstallQuery()
{
$asInstallQueries = $this->getInstallQueries();
return str_replace("\n", "<br />", implode(";\n\n", $asInstallQueries))."\n\n<!-- \n".implode(";\n\n", $asInstallQueries)."\n -->";
}
private function getInstallQueries()
{
$asTables = $this->getTables();
$asInstallQueries = array_map(array($this, 'getInstallQuery'), $asTables);
$asAlterQueries = $this->getForeignKeyQueries($asTables);
return array_merge($asInstallQueries, $asAlterQueries);
}
private function getInstallQuery($sTableName)
{
$asTableColumns = $this->getTableColumns($sTableName);
$sQuery = "\n".$this->implodeAll($asTableColumns, "` ", "\n", "`", ",")."\n".implode(", \n", $this->getTableConstraints($sTableName));
return "CREATE TABLE `{$sTableName}` ({$sQuery})";
}
private function getForeignKeyQueries($asTableNames)
{
$asForeignKeyQueries = array();
foreach($asTableNames as $sTableName)
{
$asTableColumns = array_keys($this->getTablecolumns($sTableName));
foreach($asTableColumns as $sColumnName)
{
if($this->isId($sColumnName) && $sColumnName!=self::getId($sTableName))
{
$asForeignKeyQueries[] = "ALTER TABLE ".$sTableName." ADD INDEX(`".$sColumnName."`)";
$asForeignKeyQueries[] = "ALTER TABLE ".$sTableName." ADD FOREIGN KEY (`".$sColumnName."`) REFERENCES ".self::getTable($sColumnName)."(`".$sColumnName."`)";
}
}
}
return $asForeignKeyQueries;
}
private function setQuery($sQuery, $sTypeQuery=__FUNCTION__)
{
$this->getQuery($sQuery, $sTypeQuery);
return ($this->oConnection->affected_rows!=0);
}
private function getQuery($sQuery, $sTypeQuery=__FUNCTION__)
{
$sQuery = str_replace(array("\n", "\t"), array(" ", ""), $sQuery);
if($this->getTrace()) $this->addNotice($sQuery);
if(!($oResult = $this->oConnection->query($sQuery)))
{
$this->addError("\nErreur SQL : \n".str_replace("\t", "", $sQuery)."\n\n".str_replace(array("\t", "\n"), "", $this->getLastError()));
}
return $oResult;
}
public function getLastError()
{
return $this->oConnection->error;
}
public function getArrayQuery($sQuery, $bStringOnly=false, $sGroupBy='', $sTypeQuery=__FUNCTION__)
{
$iIndex = 0;
$iColumnCount = 0;
$asResult = array();
$oResult = $this->getQuery($sQuery, true, $sTypeQuery);
if($oResult!==false)
{
while($asCurrentRow = $oResult->fetch_array())
{
if($bStringOnly) $asCurrentRow = $this->arrayKeyFilter($asCurrentRow, 'is_string');
//Add table reel keys
if($sGroupBy!='' && array_key_exists($sGroupBy, $asCurrentRow))
{
$iRowKey = $asCurrentRow[$sGroupBy];
unset($asCurrentRow[$sGroupBy]);
}
else $iRowKey = $iIndex;
//For first loop, check table width
if($iIndex==0) $iColumnCount = count($asCurrentRow);
//One column case : collapse a level
if($iColumnCount==1) $asCurrentRow = array_shift($asCurrentRow);
$asResult[$iRowKey] = $asCurrentRow;
$iIndex++;
}
}
return $asResult;
}
private function getMaxIncrementedValue($sTable)
{
return $this->selectValue($sTable, "MAX(".$this->getId($sTable).")");
}
public static function getId($sTableName, $bFull=false)
{
$sColumnName = self::ID_TAG.self::getText($sTableName);
return $bFull?self::getFullColumnName($sTableName, $sColumnName):$sColumnName;
}
public static function getText($sTableName, $bFull=false)
{
$sColumnName = mb_substr(str_replace('`', '', $sTableName), 0, -1);
$sColumnName = mb_substr($sColumnName, -2)=='ie'?mb_substr($sColumnName, 0, -2).'y':$sColumnName;
return $bFull?self::getFullColumnName($sTableName, $sColumnName):$sColumnName;
}
public static function getFullColumnName($sTableName, $sColumnName)
{
return $sTableName.".".$sColumnName;
}
private function isId($sColumnName, $sTableName='')
{
$asTables = ($sTableName=='')?$this->getTables():array($sTableName);
$asTableIds = array_map(array('self', 'getId'), $asTables);
return in_array($sColumnName, $asTableIds);
}
private function getTable($sTableId)
{
$asTables = $this->getTables();
$asTableIds = array_map(array('self', 'getId'), $asTables);
if(in_array($sTableId, $asTableIds)) return $asTables[array_search($sTableId, $asTableIds)];
else
{
$this->addError('Id '.$sTableId.' pr&eacute;sent dans aucune table');
return false;
}
}
public function getTablecolumns($sTableName)
{
if(!array_key_exists($sTableName, $this->asOptions['tables'])) return false;
$asTableColumns = array(self::getId($sTableName));
foreach($this->asOptions['tables'][$sTableName] as $sFieldName) $asTableColumns[] = $sFieldName;
$asTableColumns[] = 'led';
$asTableName = array_fill(0, count($asTableColumns), $sTableName);
return array_combine($asTableColumns, array_map(array('self', 'getColumnType'), $asTableColumns, $asTableName));
}
private function getColumnType($sColumnName, $sTableName)
{
$sColumnType = '';
switch($sColumnName)
{
case array_key_exists($sColumnName, $this->asOptions['types']):
$sColumnType = $this->asOptions['types'][$sColumnName];
break;
case 'led':
$sColumnType = "TIMESTAMP NOT NULL ON UPDATE CURRENT_TIMESTAMP DEFAULT CURRENT_TIMESTAMP";
break;
case $this->isId($sColumnName, $sTableName):
$sColumnType = "int(10) UNSIGNED auto_increment";
break;
case $this->isId($sColumnName):
$sColumnType = "int(10) UNSIGNED";
break;
}
return $sColumnType;
}
private function getTableConstraints($sTableName)
{
//Primary key
$asTableConstraints = array('PRIMARY' => "PRIMARY KEY (`".self::getId($sTableName)."`)");
//Foreign keys: applied using ALTER TABLE syntax at the end to prevent scheduling CREATE TABLE queries
//Other constraints
if(array_key_exists($sTableName, $this->asOptions['constraints'])) $asTableConstraints[] = $this->asOptions['constraints'][$sTableName];
return $asTableConstraints;
}
private function addQuotes($oData)
{
//TODO remake
$asTrustedFunc = array('CURDATE()', 'NOW()');
$sChar = "'";
if(is_array($oData))
{
$asChar = array_fill(1, count($oData), $sChar);
return array_combine(array_keys($oData), array_map(array($this, 'addQuotes'), $oData, $asChar));
}
else
{
if(in_array($oData, $asTrustedFunc)) return $oData;
else return $sChar.$oData.$sChar;
}
}
private function getLastId()
{
return $this->oConnection->insert_id;
}
public function insertRow($sTableName, $asData)
{
$this->cleanSql($sTableName);
$this->cleanSql($asData);
$asQueryValues = $this->addQuotes($asData);
$sQuery = "INSERT INTO ".$sTableName." (`".implode("`, `", array_keys($asQueryValues))."`) VALUES (".implode(", ", $asQueryValues).")";
return $this->setQuery($sQuery)?$this->getLastId():0;
}
public function updateRow($sTableName, $asConstraints, $asData)
{
return $this->updateRows($sTableName, $asConstraints, $asData, 1);
}
public function updateRows($sTableName, $asConstraints, $asData, $iLimit=0)
{
$sTableIdCol = self::getId($sTableName);
if(!is_array($asConstraints))
{
$asConstraints = array($sTableIdCol=>$asConstraints);
}
$this->cleanSql($sTableName);
$this->cleanSql($iTableId);
$this->cleanSql($asData);
$this->cleanSql($asConstraints);
$asQueryValues = $this->addQuotes($asData);
$asConstraintsValues = $this->addQuotes($asConstraints);
$this->addColumnSelectors($asQueryValues);
$this->addColumnSelectors($asConstraintsValues);
$sLimit = $iLimit>0?" LIMIT $iLimit":"";
$sQuery = "UPDATE {$sTableName} ".
"SET ".$this->implodeAll($asQueryValues, " = ", ", ")." ".
"WHERE ".$this->implodeAll($asConstraintsValues, " = ", " AND ").$sLimit;
$iResult = false;
if($this->setQuery($sQuery) && $iLimit!=1) $iResult = true;
else $iResult = array_key_exists($sTableIdCol, $asConstraints)?$asConstraints[$sTableIdCol]:$this->selectValue($sTableName, $sTableIdCol, $asConstraints);
$this->addError($iResult);
return $iResult;
}
public function insertUpdateRow($sTableName, $asData, $asKeys=array(), $bUpdate=true)
{
$sTableIdName = self::getId($sTableName);
//check for data in the db
if($asKeys==array())
{
$asKeys[] = $sTableIdName;
}
$asValues = array_intersect_key($asData, array_flip($asKeys));
$iTableId = $this->selectValue($sTableName, $sTableIdName, $asValues);
//insert
if(!$iTableId)
{
$iTableId = $this->insertRow($sTableName, $asData);
}
//Update
elseif($bUpdate)
{
if(array_key_exists($sTableIdName, $asData))
{
unset($asData[$sTableIdName]);
}
$this->updateRow($sTableName, $iTableId, $asData);
}
return $iTableId;
}
public function selectInsert($sTableName, $asData, $asKeys=array())
{
return $this->insertUpdateRow($sTableName, $asData, $asKeys, false);
}
public function deleteRow($sTableName, $iTableId)
{
$this->cleanSql($sTableName);
$this->cleanSql($iTableId);
//linked tables
switch($sTableName)
{
case array_key_exists($sTableName, $this->asOptions['cascading_delete']) :
$asTables = array_filter(is_array($sTableName)?$sTableName:array($sTableName) + $this->asOptions['cascading_delete'][$sTableName]);
break;
case is_string($sTableName) :
$asTables = array($sTableName);
break;
case is_array($sTableName):
$asTables = $sTableName;
break;
default:
$asTables = array();
}
foreach($asTables as $sTable)
{
$this->setQuery("DELETE FROM ".$sTable." WHERE ".$this->getId($sTableName)." = ".$iTableId);
}
}
public function emptyTable($sTableName)
{
$this->cleanSql($sTableName);
return $this->setQuery("TRUNCATE ".$sTableName);
}
public function selectList($sTableName, $sColumnName='', $asConstraints=array())
{
$sColumnName = $sColumnName==''?self::getText($sTableName):$sColumnName;
$sIdColumnName = self::getId($sTableName);
return $this->selectRows( array( 'select' => array($sIdColumnName, $sColumnName),
'from' => $sTableName,
'constraint'=> $asConstraints),
true,
$sIdColumnName);
}
public function selectRows($asInfo, $sGroupBy='', $bStringOnly=true)
{
$asAttributes = array('select'=>"SELECT", 'from'=>"FROM", 'join'=>"LEFT JOIN", 'joinOn'=>"LEFT JOIN", 'constraint'=>"WHERE", 'groupBy'=>"GROUP BY", 'orderBy'=>"ORDER BY", 'limit'=>'LIMIT');
$asRowSeparators = array('select'=>", ", 'from'=>"", 'join'=>" LEFT JOIN ", 'joinOn'=>" LEFT JOIN ", 'constraint'=>" AND ", 'groupBy'=>", ", 'orderBy'=>", ", 'limit'=>"");
$asOperators = array('constraint'=>" = ", 'orderBy'=>" ", 'join'=>" USING(", 'joinOn'=>" ON ");
$asEndOfStatement = array('constraint'=>"", 'orderBy'=>"", 'join'=>")", 'joinOn'=>"");
//Get table by key
if($sGroupBy===true)
{
$sGroupBy = self::getId($asInfo['from']);
//Add id to selection
if(isset($asInfo['select']) && $asInfo['select'][0]!="*") $asInfo['select'][] = $sGroupBy;
}
$sQuery = "";
foreach($asAttributes as $sStatement => $sKeyWord)
{
$asSelection = array_key_exists($sStatement, $asInfo)?$asInfo[$sStatement]:array();
if(!is_array($asSelection))
{
$asSelection = array($asSelection);
}
//if provided values
if(!empty($asSelection))
{
$this->cleanSql($asSelection);
if($sStatement=='constraint' && !array_key_exists('constVar', $asInfo))
{
$asSelection = $this->addQuotes($asSelection);
}
$this->addColumnSelectors($asSelection);
$sQuery .= " ".$sKeyWord." ";
//in case of double value input
if(array_key_exists($sStatement, $asOperators))
{
if($sStatement=='constraint' && array_key_exists('constOpe', $asInfo))
{
$asOperators[$sStatement] = $asInfo['constOpe'];
}
elseif($sStatement=='joinOn')
{
$asSimplifiedSelection = array();
foreach($asSelection as $sTable => $asJoinFields)
{
$asSimplifiedSelection[$sTable] = $this->implodeAll($asJoinFields, " = ", " AND ", $sTable.".", ".[/KEY\]");
}
$asSelection = $asSimplifiedSelection;
}
$sQuery .= $this->implodeAll($asSelection, $asOperators[$sStatement], $asRowSeparators[$sStatement], "", $asEndOfStatement[$sStatement]);
}
else
{
$sQuery .= implode($asRowSeparators[$sStatement], $asSelection);
}
}
//default value for select
elseif($sStatement=='select')
{
$sQuery .= " ".$sKeyWord." * ";
}
}
return $this->getArrayQuery($sQuery, $bStringOnly, $sGroupBy);
}
private function addColumnSelectors(&$asSelection)
{
//FIXME get rid of this
$sSqlWord = 'option';
$sKey = array_search($sSqlWord, $asSelection);
if($sKey!==false)
{
$asSelection[$sKey] = "`".$asSelection[$sKey]."`";
}
elseif(array_key_exists($sSqlWord, $asSelection))
{
$asSelection["`".$sSqlWord."`"] = $asSelection[$sSqlWord];
unset($asSelection[$sSqlWord]);
}
}
public function selectRow($sTableName, $asConstraints=array(), $sColumnName='*')
{
//Table ID directly
if(!is_array($asConstraints)) $asConstraints = array($this->getId($sTableName)=>$asConstraints);
$asRows = $this->selectRows(array('select'=>$sColumnName, 'from'=>$sTableName, 'constraint'=>$asConstraints));
$iCountNb = count($asRows);
switch($iCountNb)
{
case 0 :
$asResult = array();
break;
case $iCountNb > 1 :
$this->addError('Trop de r&eacute;sultats pour un selectRow() : '.$iCountNb.' lignes. Table: '.$sTableName.', contrainte: '.self::implodeAll($asConstraints, '=', ' ').', colonne: '.$sColumnName);
default:
$asResult = array_shift($asRows);
}
return $asResult;
}
public function selectValue($sTableName, $sColumnName, $oConstraints=array())
{
if(!is_array($oConstraints))
{
$oConstraints = array($this->getId($sTableName)=>$oConstraints);
}
$oResult = $this->selectRow($sTableName, $oConstraints, $sColumnName);
return empty($oResult)?false:$oResult;
}
public function pingValue($sTableName, $oConstraints)
{
return $this->selectValue($sTableName, 'COUNT(1)', $oConstraints);
}
public function cleanSql(&$oData)
{
$this->cleanData($oData);
$oData = $this->cleanData($oData);
}
//TODO déplacer dans ToolBox::implodeAll
public static function implodeAll($asText, $asKeyValueSeparator='', $sRowSeparator='', $sKeyPre='', $sValuePost=false)
{
if($sValuePost===false)
{
$sValuePost = $sKeyPre;
}
$asCombinedText = array();
//if unique value for key value separator
if(!is_array($asKeyValueSeparator) && !empty($asText))
{
$asKeyValueSeparator = array_combine(array_keys($asText), array_fill(0, count($asText), $asKeyValueSeparator));
}
$asFrom = array('[/KEY\]', '[/VALUE\]');
foreach($asText as $sKey=>$sValue)
{
$asTo = array($sKey, $sValue);
$sRepKeyPre = str_replace($asFrom, $asTo, $sKeyPre);
$asRepKeyValueSeparator = str_replace($asFrom, $asTo, $asKeyValueSeparator[$sKey]);
$sRepValuePost = str_replace($asFrom, $asTo, $sValuePost);
$asCombinedText[] = $sRepKeyPre.$sKey.$asRepKeyValueSeparator.(is_array($sValue)?implode($sValue):$sValue).$sRepValuePost;
}
return implode($sRowSeparator, $asCombinedText);
}
public static function arrayKeyFilter($asArray, $sCallBack)
{
$asValidKeys = array_flip(array_filter(array_keys($asArray), $sCallBack));
return array_intersect_key($asArray, $asValidKeys);
}
public function cleanData($oData)
{
if(!is_array($oData))
{
return $this->oConnection->real_escape_string($oData);
}
elseif(count($oData)>0)
{
$asKeys = array_map(array($this, 'cleanData'), array_keys($oData));
$asValues = array_map(array($this, 'cleanData'), $oData);
return array_combine($asKeys, $asValues);
}
}
}
?>

View File

@@ -340,40 +340,39 @@ class ToolBox
$iTimeStamp = is_numeric($oTime)?$oTime:strtotime($oTime); $iTimeStamp = is_numeric($oTime)?$oTime:strtotime($oTime);
$sCurTimeStamp = time(); $sCurTimeStamp = time();
$asWeekDays = array('lundi', 'mardi', 'mercredi', 'jeudi', 'vendredi', 'samedi', 'dimanche'); $asWeekDays = array('monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'satursday', 'sunday');
$asMonths = array('janvier', 'février', 'mars', 'avril', 'mai', 'juin', 'juillet', 'at', 'septembre', 'octobre', 'novembre', 'décembre'); $asMonths = array('january', 'february', 'march', 'april', 'may', 'june', 'july', 'august', 'september', 'october', 'november', 'december');
$sSep = '|'; $sSep = '|';
$sFormat = 'Y'.$sSep.'n'.$sSep.'W'.$sSep.'N'.$sSep.'j'.$sSep.'G'; $sFormat = 'Y'.$sSep.'n'.$sSep.'W'.$sSep.'N'.$sSep.'j'.$sSep.'G';
list($sYear, $sMonth, $sWeek, $sWeekDay, $sDay, $sHour) = explode($sSep, date($sFormat, $iTimeStamp)); list($sYear, $sMonth, $sWeek, $sWeekDay, $sDay, $sHour) = explode($sSep, date($sFormat, $iTimeStamp));
list($sCurYear, $sCurMonth, $sCurWeek, $sCurWeekDay, $sCurDay, $sCurHour) = explode($sSep, date($sFormat, $sCurTimeStamp)); list($sCurYear, $sCurMonth, $sCurWeek, $sCurWeekDay, $sCurDay, $sCurHour) = explode($sSep, date($sFormat, $sCurTimeStamp));
$sDesc = ''; $sDesc = '';
if($iTimeStamp>$sCurTimeStamp) $sDesc = 'dans le futur'; if($iTimeStamp>$sCurTimeStamp) $sDesc = 'in the future';
elseif($sCurTimeStamp-$iTimeStamp<60) $sDesc = 'il y a quelques secondes'; elseif($sCurTimeStamp-$iTimeStamp<60) $sDesc = 'a few seconds ago';
elseif($sCurTimeStamp-$iTimeStamp<60*10) $sDesc = 'il y a quelques minutes'; elseif($sCurTimeStamp-$iTimeStamp<60*10) $sDesc = 'a few minutes ago';
elseif($sCurTimeStamp-$iTimeStamp<60*20) $sDesc = 'il y a un quart d\'heure'; elseif($sCurTimeStamp-$iTimeStamp<60*20) $sDesc = '15 minutes ago';
elseif($sCurTimeStamp-$iTimeStamp<60*50) $sDesc = 'il y a une demi-heure'; elseif($sCurTimeStamp-$iTimeStamp<60*50) $sDesc = 'half an hour ago';
elseif($sCurTimeStamp-$iTimeStamp<60*60*2) $sDesc = 'il y a une heure'; elseif($sCurTimeStamp-$iTimeStamp<60*60*2) $sDesc = 'an hour ago';
elseif($sCurTimeStamp-$iTimeStamp<60*60*24 && $sDay==$sCurDay) $sDesc = 'à '.$sHour.'h'; elseif($sCurTimeStamp-$iTimeStamp<60*60*24 && $sDay==$sCurDay) $sDesc = 'at '.$sHour.' o\'clock';
elseif($sCurTimeStamp-$iTimeStamp<60*60*24) $sDesc = 'hier'; elseif($sCurTimeStamp-$iTimeStamp<60*60*24) $sDesc = 'yesterday';
elseif($sCurTimeStamp-$iTimeStamp<60*60*24*7 && $sWeek==$sCurWeek) $sDesc = $asWeekDays[$sWeekDay-1]; elseif($sCurTimeStamp-$iTimeStamp<60*60*24*7 && $sWeek==$sCurWeek) $sDesc = $asWeekDays[$sWeekDay-1];
elseif($sCurTimeStamp-$iTimeStamp<60*60*24*7) $sDesc = $asWeekDays[$sWeekDay-1].' dernier'; elseif($sCurTimeStamp-$iTimeStamp<60*60*24*7) $sDesc = 'last '.$asWeekDays[$sWeekDay-1];
elseif($sCurTimeStamp-$iTimeStamp<60*60*24*9) $sDesc = 'il y a une semaine'; elseif($sCurTimeStamp-$iTimeStamp<60*60*24*9) $sDesc = 'a week ago';
elseif($sCurTimeStamp-$iTimeStamp<60*60*24*12) $sDesc = 'il y a 10 jours'; elseif($sCurTimeStamp-$iTimeStamp<60*60*24*12) $sDesc = '10 days ago';
elseif($sCurTimeStamp-$iTimeStamp<60*60*24*16) $sDesc = 'il y a 2 semaines'; elseif($sCurTimeStamp-$iTimeStamp<60*60*24*16) $sDesc = '2 weeks ago';
elseif($sCurTimeStamp-$iTimeStamp<60*60*24*23) $sDesc = 'il y a 3 semaines'; elseif($sCurTimeStamp-$iTimeStamp<60*60*24*23) $sDesc = '3 weeks ago';
elseif($sCurTimeStamp-$iTimeStamp<60*60*24*31 && $sMonth==$sCurMonth) $sDesc = 'le '.$sDay.' '.$asMonths[$sMonth-1]; elseif($sCurTimeStamp-$iTimeStamp<60*60*24*31 && $sMonth==$sCurMonth) $sDesc = 'on '.$asMonths[$sMonth-1].', '.$sDay;
elseif($sCurTimeStamp-$iTimeStamp<60*60*24*30*2 && $sMonth==($sCurMonth-1)) $sDesc = 'le mois dernier'; elseif($sCurTimeStamp-$iTimeStamp<60*60*24*30*2 && $sMonth==($sCurMonth-1)) $sDesc = 'last month';
elseif($sCurTimeStamp-$iTimeStamp<60*60*24*365 && $sYear==$sCurYear) $sDesc = 'en '.$asMonths[$sMonth-1]; elseif($sCurTimeStamp-$iTimeStamp<60*60*24*365 && $sYear==$sCurYear) $sDesc = 'in '.$asMonths[$sMonth-1];
elseif($sCurTimeStamp-$iTimeStamp<60*60*24*365) $sDesc = 'en '.$asMonths[$sMonth-1].' '.$sYear; elseif($sCurTimeStamp-$iTimeStamp<60*60*24*365) $sDesc = 'in '.$asMonths[$sMonth-1].' '.$sYear;
elseif($sYear==($sCurYear-1)) $sDesc = 'l\'année dernière'; elseif($sYear==($sCurYear-1)) $sDesc = 'last year';
else $sDesc = 'en '.$sYear; else $sDesc = 'in '.$sYear;
//return self::mb_ucfirst($sDesc); //return self::mb_ucfirst($sDesc);
return self::mb_ucfirst($sDesc); return $sDesc;
} }
/** /**
* Worpress function to remove accents * Worpress function to remove accents
* https://core.trac.wordpress.org/browser/trunk/src/wp-includes/formatting.php * https://core.trac.wordpress.org/browser/trunk/src/wp-includes/formatting.php