include_once('functions.php'); class DB_Util { ## L'objet a été initialisé var $IsInit = false; ## retour par défaut des méthodes Search, GetJoinedObj, GetLinkDB_Obj, DistinctInTbl var $ReturnType = 'OBJECT'; var $INSERT_IGNORE = false; static $DEBUG = false; static $NB_QUERY = 0; function SetReturnType($v) { $this->ReturnType = $v; } function GetReturnType() { return $this->ReturnType; } function ReturnResult(&$r) { switch ($this->ReturnType) { case 'NO_CACHE': case 'COLLECTION': return new Collection($this, $r); break; case 'ASSOC': return $this->ReturnAssoc($r); break; case 'KEY': return $this->ReturnKeys($r); break; case 'COUNT': return $this->ReturnCount($r); break; case 'OBJECT': default: return $this->ReturnObj($r); break; } } function Init() { $this->IsInit = true; if ($this->Id == 0) { return false; } if (!($Nfo = $this->LoadInTbl())) { $this->Id = 0; } return $Nfo; } /* * Renvoie le nom de la table + nom de la colonne primaire */ function GetColName() { return $this->getTblName().'.'.$this->ColName; } function getTblName() { if ($this->getDBName()) { return $this->getDBName().'.'.$this->TblName; } else { return $this->TblName; } } /* * Renvoie le nom de la table + nom de la colonne primaire * dans la table définie par le paramètre $o * $o (Objet) => recherche de la table de jointure * $o (String) => concaténation simple */ function GetFK($o) { if (is_object($o)) { return $this->GetJoinTbl($o).'.'.$this->ColName; } else if (is_string($o)) { return $o.'.'.$this->ColName; } else { $Error = 'Erreur lors de l\'appel GetFK pour la classe '.get_class($this); $Error .= __FILE__.' , ligne '.__LINE__; die ($Error); } } /* $S : Liste des colonnes à sélectionner dans la table $W : clause WHERE $T : Table(s) $L : LIMIT array(OFFSET, NOMBRE) */ function LoadInTbl($S = array(), $W = array(), $T = '', $L = array(), $O = '') { $L = $this->BuilLimit($L); $S = (sizeof($S) > 0)?join(", ", $S):"*"; $W = $this->BuildWhere((sizeof($W) > 0)?$W:$this); $T = $this->BuildTblList($T); if (strlen($O) > 0) $O = $this->BuildOrder($O); $q = ' SELECT '.$S.' FROM '.$T.' '.$W.' '.$O.' '.$L; if (self::$DEBUG) { echo '
'.$q.''; } self::$NB_QUERY ++; $r = db_query($q); if ($L != '') { $t = array(); while($tmp = db_fetch_assoc($r)) { array_push($t, $tmp); } } else { $t = db_fetch_assoc($r); } db_free_result($r); return $t; } /* function BuildWhere($W, $Default = null) { if (is_array($W)) { if (sizeof($W) > 0) { $tmp = array(); foreach ($W as $v) { if (is_object($v)) { array_push($tmp, $v->ColName.' = '.(is_string($v->Id)?"'".$v->Id."'":$v->Id)); } else if (is_string($v) or is_int($v)) { array_push($tmp, $v); } } $W = 'WHERE '.join("\nAND ", $tmp); } else { $W = ''; } } else if (is_object($W)) { if (get_class($W) == 'DB_Object_Collection') { $OBJ = Factory::Build($W->class); $W = 'WHERE '.$OBJ->ColName.' IN ('.join(', ', $W->get_keys()).')'; } else { $W = 'WHERE '.$W->ColName.' = '.$W->Id; } } else if (is_string($W)) { $W = 'WHERE '.$W; } if (strlen($W) == 0 && isset($Default)) { $W = $this->BuildWhere($Default); } return $W; } */ function BuildWhere($W, $Default = null) { if (is_array($W)) { if (sizeof($W) > 0) { $tmp = array(); foreach ($W as $v) { if (is_object($v)) { array_push($tmp, $v->ColName.' = '.(is_string($v->Id)?"'".$v->Id."'":$v->Id)); } else if (is_string($v) or is_int($v)) { array_push($tmp, $v); } } $W = 'WHERE '.join("\nAND ", $tmp); } else { $W = ''; } } else if (is_object($W)) { if (get_class($W) == 'DB_Object_Collection') { if (get_class($this) == $W->class) { $W = 'WHERE '.$this->ColName.' IN ('.join(', ', $W->get_keys()).')'; } else { $p = $this->getProperties(); foreach ($p as $property) { if (@$property['class'] == $W->class) { if ($property['type'] == 'ext-object') { $OBJ = Factory::Build($W->class); $W = 'WHERE '.$this->ColName.' IN ( SELECT DISTINCT('.$this->ColName.') FROM '.$OBJ->getTblName().' WHERE '.$OBJ->ColName.' IN ('.join(', ', $W->get_keys()).') )'; } else if ($property['type'] == 'object') { $OBJ = Factory::Build($W->class); $W = 'WHERE '.$OBJ->ColName.' IN ('.join(', ', $W->get_keys()).')'; } break; } } } } else { $W = 'WHERE '.$W->ColName.' = '.$W->Id; } } else if (is_string($W)) { $W = 'WHERE '.$W; } if (strlen($W) == 0 && isset($Default)) { $W = $this->BuildWhere($Default); } return $W; } function BuilLimit($L) { return (sizeof($L) == 2 && $L[0] >= 0 && $L[1] > 0)?'LIMIT '.$L[0].', '.$L[1]:''; } function BuildOrder($O, $T = array()) { $AddPrefix = ($this->BuildTblList() == $this->BuildTblList($T)); //V. originale if (is_array($O) && sizeof($O) > 0) { return 'ORDER BY '.join(', ', $O); } else if (is_string($O) && strlen($O) > 0) { return 'ORDER BY '.$O; } else if (!empty($this->OrdCol) && $AddPrefix) { return 'ORDER BY '.($AddPrefix?$this->BuildTblList().'.':'').join(', ', $this->OrdCol); } else { return ''; } /* V. buggée if (is_array($O) && sizeof($O) > 0) { return 'ORDER BY '.join(', ', $O); } else if (is_string($O) && strlen($O) > 0) { return 'ORDER BY '.$O; } else if (!empty($this->OrdCol)) { return $this->BuildOrder($this->OrdCol, $T); } else { return ''; } */ /* if (is_array($O) && sizeof($O) > 0) { return 'ORDER BY '.join(', ', $O); } else if (is_string($O) && strlen($O) > 0) { return 'ORDER BY '.($AddPrefix?$this->BuildTblList().'.':'').$O; } else if (!empty($this->OrdCol)) { return $this->BuildOrder($this->OrdCol, $T); } else { return ''; } */ } function BuildTblList($T = '') { if (is_array($T) && sizeof($T) > 0) { return join(', ', $T); } else if (is_string($T) && strlen($T) > 0) { return $T; } else if (is_object($T) && isset($T->TblName)) { return $T->TblName; } else { return $this->TblName; } } function GetJoinTbl(&$Obj) { $PREFIX = defined('TBL_PREFIX')?TBL_PREFIX:''; if (defined('TBL_PREFIX_ALT')) { $PREFIX = TBL_PREFIX_ALT; } else if ($this->getTblPrefix()) { $PREFIX = $this->getTblPrefix(); } /* ATTENTION: bug à corriger Tout plante lorsque le préfix est également contenu dans le nom de la base */ $Tbl1 = str_replace($PREFIX, '', $this->TblName); $Tbl2 = str_replace($PREFIX, '', $Obj->TblName); if ($this->getDBName()) { $Tbl1 = str_replace($this->getDBName().'.', '', $Tbl1); $PREFIX = $this->getDBName().'.'.$PREFIX; } if ($Obj->getDBName()) { $Tbl2 = str_replace($Obj->getDBName().'.', '', $Tbl2); } if ($Tbl1 < $Tbl2) { return $PREFIX.$Tbl1.'_'.$Tbl2; } else { return $PREFIX.$Tbl2.'_'.$Tbl1; } } function ReturnObj($r) { if (!$r || db_num_rows($r) <= 0) { return false; } $Collection = new DB_Object_Collection(get_class($this)); while ($t = db_fetch_assoc($r)) { $Collection->add(intval($t[$this->ColName])); } db_free_result($r); return $Collection; } function ReturnKeys($r) { if (!$r || db_num_rows($r) <= 0) { return false; } $l = array(); while ($t = db_fetch_assoc($r)) { array_push($l, intval($t[$this->ColName])); } db_free_result($r); return $l; } function ReturnAssoc($r) { if (!$r || db_num_rows($r) <= 0) { return false; } $l = array(); while ($t = db_fetch_assoc($r)) { $l[intval($t[$this->ColName])] = $t; } db_free_result($r); return $l; } function ReturnCount($r) { if (db_num_rows($r)) { $l = db_num_rows($r); } else { $l = 0; } db_free_result($r); return $l; } /* $W : clause WHERE $O : Order $L : LIMIT array(OFFSET, NOMBRE) $T : Table(s) */ function Search($W = array(), $O = array(), $L = array(), $T = array()) { if (strlen($this->BuildOrder($O, $T)) == 0 && isset($this->OrdCol)) { $O = $this->OrdCol; } $q = ' SELECT DISTINCT('.$this->ColName.') FROM '.$this->BuildTblList($T).' '. $this->BuildWhere($W).' '. $this->BuildOrder($O, $T).' '. $this->BuilLimit($L); if (self::$DEBUG) { echo '
'.$q.''; } self::$NB_QUERY ++; $r = db_query($q); return $this->ReturnResult($r); } /* $VAL = array(colonne sql => valeur) $T = Table(s) $Ignore : tenir compte des contraintes d'unicité $Delayed : insertion delayed */ function InsertInTbl($VAL = array(), $T = '', $IGNORE = false, $DELAYED = false) { ## Insertion d'une écriture ds la table de l'objet en cours ## $VAL[Col] = Val if (sizeof($VAL) < 1) return false; $Col = array_keys($VAL); $Val = array_values($VAL); if (sizeof($Col) != sizeof($Val)) return false; $T = $this->BuildTblList($T); foreach ($Val as $k => $v) { $Val[$k] = is_string($v)?"'".$v."'":$v; } if (func_num_args() < 3) { $IGNORE = $this->INSERT_IGNORE; } $q = ' INSERT '.($DELAYED?'DELAYED':'').' '.($IGNORE?'IGNORE':'').' INTO '.$T.' ('.join(', ', $Col).') VALUES ('.join(', ', $Val).') '; if (self::$DEBUG) { echo '
'.$q.''; } self::$NB_QUERY ++; if ($r = db_query($q)) { db_free_result($r); $ID = db_insert_id(); } else { $ID = 0; } return $ID; } /* $VAL = array(colonne sql => valeur) $T = Table(s) $A = paramètre AND (en plus de la clause WHERE ColName = Id) */ function UpdateInTbl($VAL = array(), $T = '', $A = array()) { ## Modification d'une écriture ds la table de l'objet en cours ## $VAL[Col] = Val if (sizeof($VAL) < 1) return false; $T = $this->BuildTblList($T); $SET = array(); foreach ($VAL as $k => $v) { $SET[] = $k.' = '.(is_string($v)?"'".$v."'":$v); } if (is_string($A) && strlen($A) > 0) { $A = array($A); } else if (!is_array($A)) { $A = array($A); } array_push($A, $this); $W = $this->BuildWhere($A); $q = ' UPDATE '.$T.' SET '.join(", \n", $SET).' '.$W; if (self::$DEBUG) { echo '
'.$q.''; } self::$NB_QUERY ++; if ($r = db_query($q)) { db_free_result($r); return true; } else { return false; } } function CountInTbl($T = array(), $W = array(), $Option = array()) { ## Récupère le nombre d'occurences de l'objet courant ## dans la table $Tbl $W = $this->BuildWhere($W, $this); $T = $this->BuildTblList($T); $O = (sizeof($Option) > 0)?join("\n", $Option):''; $q = ' SELECT COUNT(*) FROM '.$T.' '.$W.' '.$O; if (self::$DEBUG) { echo '
'.$q.''; } self::$NB_QUERY ++; $r = db_query($q); if (db_num_rows($r) == 1) { $t = db_fetch_row($r); $NUMBER = intval($t[0]); db_free_result($r); } else { $NUMBER = 0; } return $NUMBER; } function RemoveFromTbl($T = '', $A = array(), $Optimize = true) { ## Enlève une occurence d'un objet d'une table ($Tbl) if (is_string($A) && strlen($A) > 0) { $A = array($A); } else if (is_object($A) && $A->Id > 0) { $A = array($A); } if ($this->Id > 0) { array_push($A, $this); } $W = $this->BuildWhere($A); $T = $this->BuildTblList($T); $q = ' DELETE FROM '.$T.' '.$W; if (self::$DEBUG) { echo '
'.$q.''; } self::$NB_QUERY ++; db_query($q); } /** --------------------------------------------------------- --------------------- BEGIN OBSO ----------------------- --------------------------------------------------------- **/ function RemoveFromDB() { ## Enlève une occurence de toute la base ## Utilise la variable $InDB (propre à chaque classe) foreach($this->InDB as $k => $v) $this->RemoveFromTbl($v, array(), false); } function RecordQuery($q) { } /* $Id : tableau de clefs renvoie une liste d'objet */ function InitList($Id) { if (!empty($Id) && is_array($Id) && sizeof($Id) > 0) { return $this->Search($this->BuildIn($Id)); } return false; } function BuildIn($a, $T = '') { foreach ($a as $v) { if (is_object($v) && get_class($v) == get_class($this)) { $a = array_keys($a); } break; } return ((is_string($T) && strlen($T) > 0)?$this->BuildTblList($T).'.':'').$this->ColName.' IN ('.join(', ', $a).')'; } function SetInitialisation($v) { $this->Initialisation = $v; } /* * Assigne une liste d'objet à une instance * args (object): passage de n objets en argument * La méthode "object->classname" est appelé dans l'instance */ function AssignObjects() { $numArgs = func_num_args(); if ($numArgs > 0) { for ($i = 0; $i < $numArgs; $i ++) { $o = func_get_arg($i); if (is_object($o)) { $c = get_class($o); if (method_exists($this, 'Set'.$c)) { call_user_method('Set'.$c, $this, $o); } } } } } /** --------------------------------------------------------- --------------------- END OBSO ------------------------- --------------------------------------------------------- **/ function GetJoinedObj(&$Obj, $W = array(), $O = array(), $L = array()) { $Tbl = array($this->GetJoinTbl($Obj), $Obj->TblName); $L = $this->BuilLimit($L); $O = $this->BuildOrder($O, $Tbl); if (is_string($W) && strlen($W) > 0) { $W = array($W); } else if (is_object($W) && $W->Id > 0) { $W = array($W); } else if (!is_array($W)) { $W = array(); } if ($Obj->Id > 0) { array_push($W, $this->GetJoinTbl($Obj).'.'.$Obj->ColName.' = '.$Obj->Id); } array_push($W, $this->GetJoinTbl($Obj).'.'.$this->ColName.' = '.$this->Id); array_push($W, $this->GetJoinTbl($Obj).'.'.$Obj->ColName.' = '.$Obj->BuildTblList().'.'.$Obj->ColName); $W = $this->BuildWhere($W); $q = ' SELECT '.$this->GetJoinTbl($Obj).'.'.$Obj->ColName.' FROM '.$this->BuildTblList($Tbl).' '.$W.' '.$O.' '.$L; $r = db_query($q); self::$NB_QUERY ++; if (self::$DEBUG) { echo '
'.$q.''; } return $Obj->ReturnResult($r); } function InsertThreeJoinedObj(&$Obj_1, &$Obj_2, $Additional_Cols = array()) { ## Insertion dans une table de jointure à 3 clés ## Seuls le 1er objet est pris en compte pour déterminer le nom de la table de jointure if ($Obj_1->Id == 0 || $Obj_2->Id == 0 || $this->Id == 0) { return false; } $a = array($Obj_2->ColName => $Obj_2->Id); if (is_array($Additional_Cols) && sizeof($Additional_Cols) > 0) { $a = array_merge($a, $Additional_Cols); } $this->InsertJoinedObj($Obj_1, $a); } function InsertJoinedObj(&$Obj, $Additional_Cols = array()) { if ($Obj->Id == 0 || $this->Id == 0) { return false; } $a = array( $this->ColName => $this->Id, $Obj->ColName => $Obj->Id, ); if (is_array($Additional_Cols) && sizeof($Additional_Cols) > 0) { $a = array_merge($a, $Additional_Cols); } $this->InsertInTbl($a, $this->GetJoinTbl($Obj), true); } function CountJoinedObj(&$Obj, $W = array()) { $Tbl = array($this->GetJoinTbl($Obj), $Obj->TblName); if (is_string($W) && strlen($W) > 0) { $W = array($W); } else if (is_object($W) && $W->Id > 0) { $W = array($W); } array_push($W, $this, $this->GetJoinTbl($Obj).'.'.$Obj->ColName.' = '.$Obj->BuildTblList().'.'.$Obj->ColName); $q = ' SELECT COUNT('.$this->GetJoinTbl($Obj).'.'.$Obj->ColName.') FROM '.$this->BuildTblList($Tbl).' '.$this->BuildWhere($W); $r = db_query($q); if (self::$DEBUG) { echo '
'.$q.''; } self::$NB_QUERY ++; if (db_num_rows($r) == 1) { $t = db_fetch_row($r); db_free_result($r); $NUMBER = intval($t[0]); } else { $NUMBER = 0; } return $NUMBER; } function RemoveJoinedObj() { $nObj = func_num_args(); if ($nObj == 0) return false; $Primary_Obj = func_get_arg(0); if ($Primary_Obj->Id == 0 || $this->Id == 0) return false; $Where = array($Primary_Obj); if ($nObj > 1) { for ($i = 1; $i < $nObj; $i ++) { $Tmp_Obj = func_get_arg($i); if (is_object($Tmp_Obj)) { array_push($Where, $Tmp_Obj); } } unset($Tmp_Obj); } $this->RemoveFromTbl($this->GetJoinTbl($Primary_Obj), $Where); } function DistinctInTbl($Tbl, $O = array(), $L = array()) { $q = ' SELECT DISTINCT('.$this->GetColName().') FROM '.$Tbl.', '.$this->TblName.' WHERE '.$this->GetFK($Tbl).' = '.$this->GetColName().' '.$this->BuildOrder($O, $Tbl).' '.$this->BuilLimit($L).' '; $r = db_query($q); return $this->ReturnResult($r); } function getFormList($W = array()) { $C = $this->LabelCol; $O = $this->OrdCol; $q = ' SELECT '.$this->ColName.', CONCAT_WS(\' \', '.join(', ', $C).') AS Label FROM '.$this->TblName.' '.$this->BuildWhere($W).' '.$this->BuildOrder($O); if (self::$DEBUG) { echo '
'.$q.''; } self::$NB_QUERY ++; return db_query($q); } function getSelectedInFormList($SELECTED = array()) { ## Objet DB_Object_Collection if (is_object($SELECTED)) { if (get_class($SELECTED) == 'DB_Object_Collection') { $SELECTED = $SELECTED->get_keys(); } else { $SELECTED = array($SELECTED->Id); } } else if (is_array($SELECTED)) { if (sizeof($SELECTED) == 0) { if ($this->Id > 0) { $SELECTED = array($this->Id); } else { $SELECTED = array(); } } } else { $SELECTED = array(); } return $SELECTED; } function ToOption($W = array(), $SELECTED = array()) { ## Renvoie une liste d'options pour un select $SELECTED = $this->getSelectedInFormList($SELECTED); $r = $this->getFormList($W); $O = ''; while ($t = db_fetch_assoc($r)) { $SEL = (in_array($t[$this->ColName], $SELECTED))?' selected':''; $O .= ''."\n"; } db_free_result($r); return $O; } function ToCheckbox($W = array(), $SELECTED = array(), $VARNAME = 'checkbox', $HTML_OPTION = array()) { $SELECTED = $this->getSelectedInFormList($SELECTED); $r = $this->getFormList($W); $SEPARATOR = isset($HTML_OPTION['SEPARATOR'])?$HTML_OPTION['SEPARATOR']:'