<?php
/**
 * Ce fichier permet de declarer la classe table.
 *
 * @package openmairie
 * @link http://www.openmairie.org/
 * @version SVN : $Id$
 */

/**
 *
 */
(defined("PATH_OPENMAIRIE") ? "" : define("PATH_OPENMAIRIE", ""));
require_once PATH_OPENMAIRIE."om_debug.inc.php";
(defined("DEBUG") ? "" : define("DEBUG", PRODUCTION_MODE));
require_once PATH_OPENMAIRIE."om_logger.class.php";
require_once PATH_OPENMAIRIE."om_message.class.php";

/**
 * Cette classe permet de 'tabler' les champs suivant une requete
 */
class table {
    
    /**
     * Nom de l'objet metier
     * @var string
     */
    var $aff;
    
    /**
     * Critere from de la requete
     * @var string
     */
    var $table;
    
    /**
     * Nombre d'enregistrement(s) par page
     * @var integer
     */
    var $serie;
    
    /**
     * Tableau des champs a afficher
     * @var array
     */
    var $champAffiche;
    
    /**
     * Tableau des champs sur lesquels la recherche est effectuee
     * @var array
     */
    var $champRecherche;
    
    /**
     * Critere de tri de la requete
     * @var string
     */
    var $tri;
    
    /**
     * Clause de selection dans la requete
     * @var string
     */
    var $selection;
    
    /**
     * Requete
     * @var string
     */
    var $sql;
    
    /**
     * Requete qui compte le nombre d'enregistrement
     * @var string
     */
    var $sqlC;
    
    /**
     * Requete qui compte le nombre d'enregistrement si il y a un group by
     * @var string
     */
    var $sqlG;
    
    /**
     *
     *
     */
    var $db;
    
    /**
     *
     */
    var $options;
    
    /**
     * Constructeur
     *
     * Cette methode permet d'affecter tous les parametres aux attributs de la
     * classe auxquels ils correspondent
     * 
     * @param string $aff Nom de l'objet metier
     * @param string $table Critere from de la requete
     * @param integer $serie Nombre d'enregistrement(s) par page
     * @param array $champAffiche Tableau des champs a afficher
     * @param array $champRecherche Tableau des champs sur lesquels la
     *                              recherche est effectuee
     * @param string $tri Critere de tri de la requete
     * @param string $selection Clause de selection dans la requete
     * @param string $edition Lien vers edition pdf
     * 
     * @return void
     */
    function __construct($aff, $table, $serie, $champAffiche, $champRecherche, $tri, $selection, $edition = "", $options = array()) {
        
        // Logger
        $this->addToLog("__construct()", EXTRA_VERBOSE_MODE);
        
        $this->aff = $aff;
        $this->table = $table;
        $this->serie = $serie;
        $this->champAffiche = $champAffiche;
        $this->champRecherche = $champRecherche;
        $this->tri = $tri;
        $this->selection = $selection;
        $this->edition = $edition;
        $this->options = $options;
        
    }
    
    /**
     *
     */
    function __destruct() {
        // Logger
        $this->addToLog("__destruct()", EXTRA_VERBOSE_MODE);
    }
    
    /**
     *
     */
    function setParams($params = array()) {
        
        $this->params = $params;
        
    }
    
    /**
     *
     */
    function getParam($param = NULL) {
        
        if ($param != NULL and isset($this->params[$param])) {
            return $this->params[$param];
        } else {
            return "";
        }
        
    }
    
    /**
     *
     */
    function setParam($param = NULL, $value = NULL) {
        
        if ($param != NULL) {
            $this->params[$param] = $value;
        } else {
            return;
        }
        
    }
    
    /**
     *
     */
    function getKeyForColumnName($columnname = "") {
        
        //
        $fields = array();
        foreach($this->champAffiche as $key => $value) {
            $tab = array();
            $tab = preg_split("/[ )]as /", $value);
            if (count($tab) > 1) {
                $fields[$key] = trim($tab[0]);
            } else {
                $fields[$key] = trim($value);
            }
        }
        //
        return array_search($columnname, $fields);
        
    }
    
    /**
     *
     */
    function composeURL($params = array()) {
        
        // aff correspond au fichier vers lesquels tous les liens vont pointer
        // (exemple : ../scr/tab.php ou ../scr/soustab.php)
        $return =  $this->aff."?";
        
        //
        foreach ($params as $param => $value) {
            if (!array_key_exists($param, $this->params)) {
                $return .= $param."=".$params[$param]."&amp;";
            }
        }
        foreach ($this->params as $param => $value) {
            if (isset($params[$param])) {
                $return .= $param."=".$params[$param]."&amp;";
            } else {
                $return .= $param."=".$value."&amp;";
            }
        }
        if ($return != "") {
            substr($return, 0, strlen($return)-5);
        }
        
        //
        return $return;
        
    }
    
    /**
     *
     */
    function countHrefColumns($href = array()) {
        
        $nbcol_header = 0;
        $nbcol_data = 0;
        
        foreach($href as $key => $value) {
            
            if ($key == 0) {
                if (isset($href[$key]['lien']) and $href[$key]['lien'] != ""
                    and $href[$key]['lien'] != "#") {
                   $nbcol_header = 1;
                }
            } else {
                if (isset($href[$key]['lien']) and $href[$key]['lien'] != ""
                    and $href[$key]['lien'] != "#" and $href[$key]['lib'] != "") {
                    $nbcol_data += 1;
                }
            }
            
        }
        
        return $nbcol_data;
        
    }
    
    /**
     *
     */
    function getColumnsName($resource = NULL) {
        //
        if ($resource == NULL) {
            return;
        }
        //
        $info = $resource->tableInfo();
        // Logger
        $this->addToLog("getColumnsName(): ".print_r($info, true), EXTRA_VERBOSE_MODE);
        //
        return $info;
    }
    
    /**
     * 
     * 
     * @param array $params
     * @param array $href
     * @param mixed $db
     * @param string $style Prefixe de la classe CSS a utiliser
     * @param boolean $onglet
     * @return void
     */
    function display($params = array(), $href = array(), $db = NULL, $class = "tab", $onglet = false) {
        
        //
        $this->db = $db;
        
        //
        $this->setParams($params);
        
        // Construction de la recherche
        $this->composeSearchTab();
        
        // En mode onglet, on n'affiche pas le formulaire de recherche ni
        // l'edition pdf
        if ($onglet == false) {
            
            $display_search = true;
            foreach($this->options as $option) {
                if ($option["type"] == "search") {
                    $display_search = $option["display"];
                }
            }
            
            if ($display_search) {
                $this->displaySearch();
            }
            
            $this->displayEdition();
            
        }
        
        // Construction de la requete
        $this->composeQuery();
        
        // Calcul du nombre total de resultats de la requete
        $nbligne = $db->getOne($this->sqlC);
        // Logger
        $this->addToLog("display(): db->getone(\"".$this->sqlC."\");", VERBOSE_MODE);
        
        // Calcul du nombre total de resultats different si on detecte un
        // group by dans la requete
        if (preg_match("/group by/i", $this->tri) == 1) {
            $res1 = $db->query($this->sqlG);
            // Logger
            $this->addToLog("display(): db->query(\"".$this->sqlG."\");", VERBOSE_MODE);
            //
            $nbligne = $res1->numRows();
        }
        
        // Execution de la requete a partir de l'enregistrement $premier avec 
        // la limite $this->serie 
        $res = $db->limitquery($this->sql, $this->getParam("premier"), $this->serie);
        // Logger
        $this->addToLog("display(): db->limitquery(\"".$this->sql."\", ".$this->getParam("premier").", ".$this->serie.");", VERBOSE_MODE);

        // Verification d'erreur sur le resultat de la requete
        if (database::isError($res)) {
            
            // Appel de la methode de gestion des erreurs
            echo "<pre>";
            echo $res->getDebugInfo()."\n".$res->getMessage();
            echo "</pre>";
            echo "</div></div>";
            die();
            
        } else {
            
            // Lorsque magic_quotes est active, tous les caracteres
            // ' (guillemets simples), " (guillemets doubles), \ (antislash)
            // et NUL sont echappes avec un antislash alors on supprime les
            // antislashs de la chaine $recherche
            // A VOIR
            if (get_magic_quotes_gpc()) {
                $this->setParam("recherche", StripSlashes($this->getParam("recherche")));
            }
            
            // Recuperation des infos sur la table
            // ( oracle: recuperation immediate  (en dynamique) )
            $info = $this->getColumnsName($res);
            
            //
            $display_pagination = true;
            foreach($this->options as $option) {
                if ($option["type"] == "pagination") {
                    $display_pagination = $option["display"];
                }
            }
            if ($display_pagination) {
                // Affichage de la pagination
                echo "<!-- tab-pagination -->\n";
                $this->displayPagination($nbligne, $class, $onglet);
            }
            
            // Affichage de la table
            echo "<!-- tab-tab -->\n";
            echo "<table class=\"".$class."-tab\">\n";
            
            // Affichage de la ligne d'entete du tableau
            // false car tab non dynamique (pas d'onglet)
            $this->displayHeader($href, $info, $class, $onglet);
            
            // Calcul du nombre de colonnes
            $nbchamp = count($info);
            
            // Gestion d'une classe css differente une ligne sur deux
            $odd = 0;
            
            // Affichage des lignes de tableaux
            echo "\t<!-- tab-data -->\n";
            
            // Si aucun resultat, on affiche une ligne avec un message
            // indiquant qu'il n'y a aucun enregistrement
            if ($nbligne == 0) {
                
                echo "\t<tr class=\"".$class."-data empty\">\n";
                echo "<td colspan=\"".(count($href)+$nbchamp)."\">";
                echo _("Aucun enregistrement.");
                echo "</td>";
                echo "\t</tr>\n";
                
            }
            
            $countHrefColumns = $this->countHrefColumns($href);
            
            // Boucle sur les resultats de la requete
            while ($row =& $res->fetchRow()) {
                // Gestion des options
                $option_style = "";
                $option_href = false;
                foreach($this->options as $option) {
                    if ($option["type"] == "condition") {
                        foreach($option["case"] as $case) {
                            if (isset($row[$this->getKeyForColumnName($option["field"])])
                                and in_array($row[$this->getKeyForColumnName($option["field"])], $case["values"])) {
                                $option_style .= (isset($case["style"]) ? " ".$case["style"] : "");
                                if (isset($case["href"])) {
                                    $option_href = $case["href"];
                                }
                            }
                        }
                    }
                }
                
                //
                $links = $href;
                if ($option_href != false) {
                    $links = $option_href;
                }
                
                // Affichage d'une ligne de tableau
                echo "\t<tr";
                echo " class=\"";
                echo $class."-data";
                echo $option_style;
                echo " ".($odd % 2 == 0 ? "odd" : "even");
                echo "\">\n";
                
                // Gestion d'une classe css differente une ligne sur deux
                $odd += 1;
                
                //
                if ($countHrefColumns != 0) {
                    echo "\t\t<td class=\"icons\">";
                    echo "&nbsp;";
                }
                
                // Affichage des liens en debut de ligne
                foreach ($links as $key => $elem) {
                    
                    // Les liens a afficher en debut de tableau sont les
                    // valeurs href[2] a [n] donc > 1
                    if ($key > 0
                        and $links[$key]['lien'] != ""
                        and $links[$key]['lien'] != "#"
                        and $links[$key]['lib'] != "") {
                        
                        //
                        echo "<a ";
                        if ($onglet == false or $key > 2) {
                            echo "href=\"".$links[$key]['lien'].urlencode($row[0]).$links[$key]['id']."\"";
                            // Ajout de l'attribut target a blank si le 
                            // parametre est present
                            if (isset($links[$key]['target']) and $links[$key]['target'] == "_blank") {
                                echo " target=\"_blank\" ";
                            }
                        } else {
                            // Ajout de l'attribut target a blank si le 
                            // parametre est present
                            if (isset($links[$key]['target']) and $links[$key]['target'] == "_blank") {
                                echo "href=\"".$links[$key]['lien'].urlencode($row[0]).$links[$key]['id']."\"";
                                echo " target=\"_blank\" ";
                            } else {
                                // Sinon appel javascript pour rechargement du
                                // bloc en ajax
                                echo "href=\"";
                                echo "#";
                                echo "\" ";
                                echo " onclick=\"ajaxIt('".$this->getParam("obj")."','";
                                echo $links[$key]['lien'].urlencode($row[0]).$links[$key]['id'];
                                echo "');\"";
                            }
                        }
                        echo ">";
                        echo $links[$key]['lib'];
                        echo "</a>";
                        echo "&nbsp;";
                        
                    }
                    
                }
                
                //
                if ($countHrefColumns != 0) {
                    echo "</td>\n";
                }
                
                // Verification du lien hypertexte de href[1]
                if ($links[1]['lien'] != "" and $links[1]['lien'] != "#") {
                    
                    // Pour chaque colonne du tableau
                    foreach ($row as $key => $elem) {
                        
                        // Affichage de la cellule avec le lien
                        echo "\t\t<td ";
                        echo "class=\"col-".$key."";
                        if ($key == 0) {
                            echo " firstcol";
                        }
                        if ($key == count($row)-1) {
                            echo " lastcol";
                        }
                        if (is_numeric($elem)) {
                            echo " right";
                        }
                        if (preg_match("/@/", $elem)) {
                            echo " left";
                        }
                        echo "\"";
                        echo ">";
                        
                        // Affichage d'un lien mailto si on detecte un @
                        if (preg_match("/@/", $elem)) {
                            echo "<a href='mailto:".$elem."' ";
                            echo "title=\""._("Envoyer un mail a cette adresse")."\">";
                            echo "<span class=\"ui-icon ui-icon-mail-closed\"></span>";
                            echo "</a>";
                        }
                        
                        //
                        echo "<a class='lienTable' ";
                        if ($onglet == false) {
                            if ($nbchamp > 1) {
                                echo "href=\"".$links[1]['lien'].urlencode($row[0])."&amp;idz=".urlencode($row[1]).$links[1]['id']."\"";
                            } else {
                                echo "href=\"".$links[1]['lien'].urlencode($row[0]).$links[1]['id']."\"";
                            }
                        } else {
                            echo "href=\"";
                            echo "#";
                            echo "\" ";
                            echo " onclick=\"ajaxIt('".$this->getParam("obj")."','";
                            echo $links[1]['lien'].urlencode($row[0]).$links[1]['id'];
                            echo "');\"";
                        }
                        echo ">";
                        echo $elem;
                        echo "</a>";
                        echo "</td>\n";
                        
                    }
                    
                } else {
                    
                    // Pour chaque colonne du tableau
                    foreach ($row as $key => $elem) {
                        
                        // Affichage de la cellule sans lien
                        echo "\t\t<td ";
                        echo "class=\"col-".$key."";
                        if ($key == 0) {
                            echo " firstcol";
                        }
                        if ($key == count($row)-1) {
                            echo " lastcol";
                        }
                        if (is_numeric($elem)) {
                            echo " right";
                        }
                        if (preg_match("/@/", $elem)) {
                            echo " left";
                        }
                        echo "\"";
                        echo ">";
                        
                        // Affichage d'un lien mailto si on detecte un @
                        if (preg_match("/@/", $elem)) {
                            echo "<a href='mailto:".$elem."' ";
                            echo "title=\""._("Envoyer un mail a cette adresse")."\">";
                            echo "<span class=\"ui-icon ui-icon-mail-closed\"></span>";
                            echo "</a>";
                        }
                        
                        //
                        echo $elem;
                        echo "</td>\n";
                        
                    }
                    
                }
                
                // Fermeture de la balise ligne de tableau
                echo "\t</tr>\n";
                
            }
            
            // Fermeture de la balise table
            echo "</table>\n";
            
            // Libere le resultat de la requete
            $res->free();
            
        }
        
        
    }
    
    /**
     *
     *
     * @param array $href
     * @param array $info
     * @param string $style Prefixe de la classe CSS a utiliser
     * @param boolean $onglet
     * @return void
     */
    function displayHeader($href, $info, $class = "tab", $onglet = false) {
        
        //
        echo "\t<!-- tab-head -->\n";
        
        // Ouverture de la ligne
        echo "\t<tr class=\"ui-tabs-nav ui-accordion ui-state-default ".$class."-title\">\n";
        
        $countHrefColumns = $this->countHrefColumns($href);
        
        // Affichage de la premiere cellule : lien ajouter href[0]
        if ($href[0]['lien'] != "" and $href[0]['lien'] != "#") {
            
            // Ouverture de la cellule
            echo "\t\t<th class=\"icons\"";
            //echo "colspan=\"".$countHrefColumns."\"";
            echo ">";
            
            // 
            echo "<a href=\"";
            // si sousform genere en ajax
            if ($onglet) {
                
                echo "#";
                echo "\" ";
                echo " onclick=\"ajaxIt('".$this->getParam("obj")."','";
                echo $href[0]['lien'].$href[0]['id'];
                echo "');";
                
            } else {
                
                echo $href[0]['lien'].$href[0]['id'];
                
            }
            echo "\"";
            echo ">";
            echo $href[0]['lib'];
            echo "</a>";
            
            //
            echo "</th>\n";
            
        } else {
            
            if ($countHrefColumns != 0) {
                
                // Ouverture de la cellule
                echo "\t\t<th ";
                //echo "colspan=\"".$countHrefColumns."\"";
                echo ">";
                
                //
                echo "&nbsp;";
                
                //
                echo "</th>\n";
                
            }
            
        }
        
        //
        $i = 0;
        
        // Formatage des tableaux contenant les parametres de recherche pour
        // permettre d'afficher la loupe sur les champs en question
        $lowerChampRecherche = array();
        foreach ($this->champRecherche as $key => $val) {
            $lowerChampRecherche[$key] = trim(mb_strtolower($val));
        }
        $lowerSearchTabDisplay = array();
        foreach ($this->searchTab["display"] as $key => $val) {
            $lowerSearchTabDisplay[$key] = trim(mb_strtolower($val));
        }
        
        // Nom des champs en entete de colonne
        foreach ($info as $key => $elem) {
            
            // Fleche sur colonne triee
            if ($this->getParam("tricol") != "" and $this->getParam("tricol") == $key) {
                $fleche_tri="<span class=\"ui-icon ui-icon-triangle-1-s\"><!-- --></span> ";
            } else {
                $fleche_tri="<span class=\"ui-icon ui-icon-triangle-1-e\"><!-- --></span> ";
            }
            
            //
            echo "\t\t<th class=\"title\">";
            //
            echo "<span class=\"name\">";
            //
            echo "<a href=\"";
            //
            if ($onglet) {
                echo "#";
                echo "\"";
                echo " onclick=\"ajaxIt('".$this->getParam("obj")."','";
            }
            //
            $params = array("tricol" => $key);
            echo $this->composeURL($params);
            //
            if ($onglet) {
                echo "');";
            }
            echo "\"";
            echo ">";
            echo $fleche_tri;
            echo ucwords($elem['name']);
            echo "</a>";
            //
            echo "</span>";
            // Affichage d'une icone de loupe sur les colonnes ou une recherche
            // est possible
            if (in_array($elem['name'], $lowerChampRecherche) or
                in_array($elem['name'], $lowerSearchTabDisplay) or
                in_array("\"".$elem['name']."\"", $lowerSearchTabDisplay) or
                in_array("*".$elem['name'], $lowerChampRecherche) or
                in_array("*\"".$elem['name']."\"", $lowerChampRecherche)) {
                echo "<span class=\"ui-icon ui-icon-search\"";
                echo " title=\""._("Recherche possible sur ce champ")."\">";
                echo "("._("Recherche possible sur ce champ").")";
                echo "</span>";
            }
            //
            echo "</th>\n";
            
        }
        
        //
        echo "\t</tr>\n";
        
    }
    
    /**
     * Methode d'affichage de l'edition
     *
     * Cette methode permet d'afficher un lien vers l'edition pdf
     * 
     * @param string $style Prefixe de la classe CSS a utiliser
     * @return void
     */
    function displayEdition($style = "tab") {
        
        if ($this->edition != "") {
            
            echo "<!-- tab-edition -->\n";
            // Ouverture du conteneur
            echo "<div class=\"".$style."-edition\">\n";
            
            // Affichage du lien vers le fichier php d'edition pdf
            echo "<a href=\"".$this->edition."\" ";
            echo "title=\""._("Edition")." ".$this->getParam("obj")."\" ";
            echo "target='_blank'>";
            
            // Affichage de l'image representant l'edition
            echo "<span class=\"om-icon om-icon-25 print-25\">"._("Edition")."</span>";
            
            // Fermeture de la balise lien
            echo "</a>";
            
            // Fermeture du conteneur
            echo "</div>\n";
        }
        
    }
    
    /**
     *
     */
    function composeSearchTab() {
        
        //
        $this->searchTab = array(
            "display" => array(),
            "query" => array(),
        );
        //
        foreach($this->champRecherche as $key => $elem) {
            //
            if (!preg_match("/\*/", $elem)) {
                //
                $tab = preg_split("/[ )]as /", $elem);
                //
                if (count($tab) > 1) {
                    $display = $tab[1];
                    $query = $tab[0];
                } else {
                    $display = $query = $elem;
                }
                //
                array_push($this->searchTab["display"], str_replace("\"", "", $display));
                array_push($this->searchTab["query"], str_replace("\"", "", $query));
            }
        }
        
    }
    
    /**
     * Methode permettant l'affichage de la recherche
     *
     * Cette methode permet d'afficher le formulaire de recherche
     *
     * @param string $style Prefixe de la classe CSS a utiliser
     * @return void
     */
    function displaySearch($style = "tab") {
        
        //
        echo "<!-- tab-search -->\n";
        
        // Affichage de la table
        echo "<div class=\"".$style."-search ui-widget-content ui-corner-all\">\n";
        
        // Affichage du formulaire
        echo "\t<form action=\"";
        $params = array("validation" => 0, "premier" => 0);
        echo $this->composeURL($params);
        echo "\" method=\"post\" id=\"f1\" name=\"f1\">\n";
        
        // Affichage du champ permettant la saisie du terme a rechercher
        echo "\t\t<input type=\"text\" name=\"recherche\" ";
        echo "value=\"".$this->getParam("recherche")."\" ";
        echo "class=\"champFormulaire\" />\n";
        
        // Affichage du champ select permettant de choisir le champ sur lequel
        // doit agir la recherche
        echo "\t\t<select name=\"selectioncol\" class=\"champFormulaire\">\n";
        if ($this->getParam("selectioncol") == "") {
            echo "\t\t\t<option value=\"\" selected=\"selected\">"._("Tous")."</option>\n";
            foreach($this->searchTab["display"] as $key => $elem) {
                echo "\t\t\t<option value=\"".$key."\">".$elem."</option>\n";
            }
        } else {
            echo "\t\t\t<option value=\"\">"._("Tous")."</option>\n";
            foreach($this->searchTab["display"] as $key => $elem) {
                if($this->getParam("selectioncol") == $key) {
                    echo "\t\t\t<option value=\"".$key."\" selected=\"selected\">".$elem."</option>\n";
                } else {
                    echo "\t\t\t<option value=\"".$key."\">".$elem."</option>\n";
                }
            }
        }
        echo "\t\t</select>\n";
        
        // Affichage du bouton de soumission du formulaire
        echo "\t\t<button type=\"submit\" name=\"s1\">";
        echo _("Recherche");
        echo "</button>\n";
        
        
        // Fermeture de la balise formulaire
        echo "\t</form>\n";
        
        // Fermeture de la balise table
        echo "</div>\n";
        
    }
    
    /**
     * 
     *
     * @param integer $nbligne
     * @param string $style Prefixe de la classe CSS a utiliser
     * @param boolean $onglet
     * @return void
     */
    function displayPagination($nbligne, $style = "tab", $onglet = false) {
        
        // Ouverture du conteneur de la pagination
        echo "<div class=\"".$style."-pagination ui-state-default ui-corner-top ui-tabs-selected ui-state-active\">\n";
        
        echo "<div class=\"pagination-nb\">";
        
        // Si il y a une page precedente
        if ($this->getParam("premier") > 0) {
            
            // Calcul du premier enregistrement de la page precedente
            $precedent = $this->getParam("premier") - $this->serie;
            
            // Affichage du lien vers la page precedente
            echo " <a href=\"";
            //
            if ($onglet) {
                echo "#";
                echo "\" ";
                echo "onclick=\"ajaxIt('".$this->getParam("obj")."','";
            }
            //
            $params = array("premier" => $precedent);
            echo $this->composeURL($params);
            //
            if ($onglet) {
                echo "');";
            }
            echo "\" ";
            echo "title=\""._("Page precedente")."\" ";
            echo "class=\"pagination-prev\"";
            echo ">";
            
            // Affichage de l'image representant la page precedente
            echo "<span class=\"ui-icon ui-icon-circle-triangle-w\">"._("Page precedente")."</span>";
            
            // Fermeture de la balise lien
            echo "</a> ";
            
        }
        
        // Affichage du conteneur de message de pagination
        echo "<span class=\"pagination-text\">";
        
        // Valeur du dernier enregistrement pour l'utilisateur
        $dernieraffiche = $this->getParam("premier") + $this->serie;
        
        // Controle du dernier affiche
        if ($dernieraffiche > $nbligne) {
            $dernieraffiche = $nbligne;
        }
        
        // Valeur du premier enregistrement pour l'utilisateur
        $premieraffiche = $this->getParam("premier") + 1;
        
        // Construction du message de pagination
        $varTemp = $premieraffiche." - ".$dernieraffiche." ";
        $varTemp .= _("enregistrement(s) sur")." ".$nbligne;
        
        // Affichage du message de pagination
        if (strcmp($this->getParam("recherche"), "")) {
            echo $varTemp." = [".$this->getParam("recherche")."] ";
        } else {
            echo $varTemp." ";
        }
        
        // Fermeture de la balise span
        echo "</span>";
        
        // Si il y a une page suivante
        if ($this->getParam("premier") + $this->serie < $nbligne) {
            
            // Calcul du premier enregistrement de la page suivante
            $suivant = $this->getParam("premier") + $this->serie;
            
            // Affichage du lien vers la page suivante
            echo " <a href=\"";
            //
            if ($onglet) {
                echo "#";
                echo "\" ";
                echo "onclick=\"ajaxIt('".$this->getParam("obj")."','";
            }
            //
            $params = array("premier" => $suivant);
            echo $this->composeURL($params);
            //
            if ($onglet) {
                echo "');";
            }
            echo "\" ";
            echo "title=\""._("Page suivante")."\" ";
            echo "class=\"pagination-next\"";
            echo ">";
            
            // Affichage de l'image representant la page suivante
            echo "<span class=\"ui-icon ui-icon-circle-triangle-e\">"._("Page suivante")."</span>";
            
            // Fermeture de la balise lien
            echo "</a> ";
            
        }
        
        
        echo "</div>";
        
        //
        $display_pagination_select = true;
        foreach($this->options as $option) {
            if ($option["type"] == "pagination_select") {
                $display_pagination_select = $option["display"];
            }
        }
        //
        if ($display_pagination_select == true) {
            // Affichage de la pagination dans un select
            // Si plus d'une page
            if ($nbligne > $this->serie) {
                
                //
                echo "<div class=\"pagination-select\">";
                
                // Affichage du formulaire
                echo "<form action=\"\">\n";
                
                // Calcul du nombre de page
                if (($nbligne % $this->serie) == 0) {
                    $nbpage = (int)($nbligne / $this->serie);
                } else {
                    $nbpage = (int)($nbligne / $this->serie) + 1;
                }
                
                // Affichage du mot Page
                echo "&nbsp;"._('Page')."&nbsp;";
                
                // Affichage de la liste de choix
                echo "<select name=\"page\" size='1' ";
                if ($onglet) {
                    echo "onchange=\"ajaxIt('".$this->getParam("obj")."', '";
                    $params = array("premier" => "'+this.value+'");
                    echo $this->composeURL($params);
                    echo "');";
                    echo "\"";
                } else {
                    echo "onchange=\"allerpage(this);\"";
                }
                echo " class='champFormulaire' >";
                
                // Boucle sur le nombre de page pour l'affichage de chaque item de
                // la liste
                for ($i = 1; $i <= $nbpage; $i++) {
                    
                    // Affichage de l'item selectionne sur la page en cours
                    if (($i - 1) * $this->serie == $this->getParam("premier")) {
                        echo "<option value=\"".($i - 1) * $this->serie."\" selected=\"selected\">";
                        echo $i." / ".$nbpage;
                        echo "</option>";
                    } else {
                        echo "<option value=\"".($i - 1) * $this->serie."\">";
                        echo $i." / ".$nbpage;
                        echo "</option>";
                    }
                    
                }
                
                // Fermeture de la balise liste de choix
                echo "</select>";
                
                echo "<script type=\"text/javascript\">";
                echo "function allerpage(select) { ";
                echo "location=\"";
                echo $this->aff;
                echo "?";
                echo "obj=".$this->getParam("obj");
                echo "&premier=\"+select.value+\"";
                echo "&recherche=".urlencode($this->getParam("recherche"));
                echo "&tricol=".$this->getParam("tricol");
                echo "&selectioncol=".$this->getParam("selectioncol");
                echo "&nom=".$this->getParam("nom");
                echo "&prenom=".$this->getParam("prenom");
                echo "&marital=".$this->getParam("marital");
                echo "&datenaissance=".$this->getParam("datenaissance");
                echo "&exact=".$this->getParam("exact");
                echo "\";";
                echo "} ";
                echo "</script>";
                
                // Fermeture de la balise formulaire
                echo "</form>\n";
                
                //
                echo "</div>";
            }
        }
        
        echo "<div class=\"visualClear\"><!-- --></div>";
        
        // Fermeture du conteneur de la pagination
        echo "</div>\n";
        
    }

    /**
     * Fonction formatDateForSearch
     *
     * convertit la date 00/00/0000 en 0000-00-00 (compatibilite requete SQL)
     *
     * @param date $date date format 00/00/0000
     * 
     */
    function formatDateForSearch($search) {
        if(strpos($search, "/")) {
            $date = str_replace("/","-",$search);
            $dateFormat = preg_split("/-/",$date);
            $nbcaract =  strlen($date);
            if( count($dateFormat) > 1 && strpos($date,"-") == 2  ){
                $value = "";
                switch($nbcaract){
                    case "10": // 00/00/0000
                        $split = preg_split("/-/",$date); 
                        $jour = $split[0]; 
                        $mois = $split[1];
                        $annee = $split[2];
                        $value = $annee."-".$mois."-".$jour; 
                        break;
                    case "7": // 00/0000
                        $split = preg_split("/-/",$date); 
                        $mois = $split[0]; 
                        $annee = $split[1]; 
                        $value = $annee."-".$mois."-"; 
                        break;
                    case "5": // 00/00
                        $split = preg_split("/-/",$date);
                        $jour = $split[0];
                        $mois = $split[1];
                        $value = '-'.$mois.'-'.$jour;
                        break;
                }
                return $value;
            }
        }
        return $search;
    }
    
    /**
     * Méthode permettant de transformer les caractères avec accents en caractères sans,
     * ainsi que modifier la casse en minuscule
     */
    function stripAccentsUtf8($string) {
        $string = mb_strtolower($string, 'UTF-8');
        $string = str_replace(
            array(
                'à', 'â', 'ä', 'á', 'ã', 'å',
                'î', 'ï', 'ì', 'í',
                'ô', 'ö', 'ò', 'ó', 'õ', 'ø',
                'ù', 'û', 'ü', 'ú',
                'é', 'è', 'ê', 'ë',
                'ç', 'ÿ', 'ñ',
                ),
            array(
                'a', 'a', 'a', 'a', 'a', 'a',
                'i', 'i', 'i', 'i',
                'o', 'o', 'o', 'o', 'o', 'o',
                'u', 'u', 'u', 'u',
                'e', 'e', 'e', 'e',
                'c', 'y', 'n',
                ),
        $string
        );

        return $string;
    }
    /**
     * Methode de construction de la requete
     *
     * Cette methode permet de construire les trois requetes sql sqlC et sqlG
     * en concatenant les differents parametres
     *
     * @return void
     */
    function composeQuery() {
        // Concatenation des champAffiche avec des virgules pour composer la
        // clause SELECT
        $champ = "";
        foreach ($this->champAffiche as $elem) {
            $champ = $champ."".$elem.",";
        }
        $champ = substr($champ, 0, strlen($champ) - 1);
        
        // Prise en compte du tri de la colonne
        $tri = $this->tri;
        if ($this->getParam("tricol") != ""
            and isset($this->champAffiche[$this->getParam("tricol")])) {
            
            // Tricol est la cle du tableau de champ, il faut recuperer le
            // champ pour l'integrer dans la requete on verifie si un 'as' est
            // present pour s'en servir
            $tricol = $this->champAffiche[$this->getParam("tricol")];
            $tab = preg_split("/[ )]as /", $tricol);
            if (count($tab) > 1) {
                // Mysql ne prend pas en compte le tri sur les alias
                // il est donc nécessaire pour ce moteur de base de données
                // d'utiliser la première partie avant l'alias pour la clause
                // order by
                if ($this->db->phptype == "mysql") {
                    $tricol = $tab[0];
                } else {
                    $tricol = $tab[1];
                }
            }

            
            //echo $tricol;
            // Si $tri n'est pas vide alors il faut inserer le nouveau cahmp
            // de tri en premier dans le ORDER BY
            if ($tri) { 
                $tri = str_replace("order by ", "order by ".$tricol.",", $tri);
            } else {
                $tri = " order by ".$tricol."";
            }
            
        }
        
        // Si la recherche est vide
        if ($this->getParam("recherche") == "") {
            
            // Construction de la requete
            $this->sql = "SELECT ".$champ." ";
            $this->sql .= "FROM ".$this->table." ";
            $this->sql .= $this->selection." ";
            $this->sql .= $tri;
            
            // Construction de la requete qui compte le nombre d'enregistrement
            $this->sqlC = "select count(*) from ".$this->table." ";
            $this->sqlC .= $this->selection;
            
        } else {
            
            // Si la clause de selection n'est pas vide, il n'est pas
            // necessaire d'ajouter le WHERE
            if ($this->selection != "") {
                
                // Construction de la requete
                $this->sql = "SELECT ".$champ." ";
                $this->sql .= "FROM ".$this->table." ";
                $this->sql .= $this->selection." and (";
                
            } else {
                
                // Construction de la requete
                $this->sql = "SELECT ".$champ." ";
                $this->sql .= "FROM ".$this->table." ";
                $this->sql .= "where (";
                
            }
            $value = $this->formatDateForSearch($this->getParam("recherche"));
            
            // Construction de la clause WHERE avec les champs de recherche
            $sqlw = "";
            // Si la recherche est faite sur tout les champs possibles
            if ($this->getParam("selectioncol") == "") {
                // On boucle sur chaque champ afin de construire la requête
                foreach ($this->searchTab["query"] as $key => $elem) {
                        
                    // Lorsque magic_quotes est active, tous les caracteres
                    // ' (guillemets simples), " (guillemets doubles),
                    // \ (antislash) et NUL sont echappes avec un antislash
                    // alors on supprime ou on ajouter les antislashs de la
                    // chaine $recherche si besoin
                    if (!get_magic_quotes_gpc()) {
                        // Si postgresql est utilisé on utilise pg_escape_string
                        // sinon AddSlashes
                        if ($this->db->phptype == "pgsql") {
                            $sqlw .= " lower(translate(".$elem.iconv("UTF-8",HTTPCHARSET,"::varchar,'àáâãäçèéêëìíîïñòóôõöùúûüýÿÀÁÂÃÄÇÈÉÊËÌÍÎÏÑÒÓÔÕÖÙÚÛÜÝ','aaaaaceeeeiiiinooooouuuuyyaaaaaceeeeiiiinooooouuuuy')) ");
                            // Si la locale est utf-8 (mode normal) on enlève les accents
                            // et on échappe les caractères spéciaux
                            // sinon on encode la chaîne recherchée en utf-8
                            if(HTTPCHARSET=='UTF-8') {
                                $sqlw .= " like '%".$this->stripAccentsUtf8(pg_escape_string($value))."%' OR ";
                            } else {
                                $sqlw .= " like '%".$this->stripAccentsUtf8(pg_escape_string(iconv(HTTPCHARSET,"UTF-8",$value)))."%' OR ";
                            }
                        } else {
                            $sqlw .= " lower(".$elem.") like '%".$this->stripAccentsUtf8(AddSlashes(iconv(HTTPCHARSET,"UTF-8",$value)))."%' OR ";
                        }
                    } else {
                        // Si postgresql est utilisé on utilise pg_escape_string
                        // sinon AddSlashes
                        if ($this->db->phptype == "pgsql") {
                            $sqlw .= " lower(translate(".$elem.iconv("UTF-8",HTTPCHARSET,"::varchar,'àáâãäçèéêëìíîïñòóôõöùúûüýÿÀÁÂÃÄÇÈÉÊËÌÍÎÏÑÒÓÔÕÖÙÚÛÜÝ','aaaaaceeeeiiiinooooouuuuyyaaaaaceeeeiiiinooooouuuuy')) ");
                            // Si la locale est utf-8 (mode normal) on enlève les accents
                            // et on échappe les caractères spéciaux
                            // sinon on encode la chaîne recherchée en utf-8
                            if(HTTPCHARSET=='UTF-8') {
                                $sqlw .= " like '%".$this->stripAccentsUtf8($value)."%' OR ";
                            } else {
                                $sqlw .= " like '%".$this->stripAccentsUtf8(iconv(HTTPCHARSET,"UTF-8",$value))."%' OR ";
                            }
                        } else {
                            $sqlw .= " lower(".$elem.") like '%".strtolower(addslashes($this->getParam("recherche")))."%' or ";
                        }
                    }
                    
                }
                
            } else {
                
                // Si un seul champ de recherche est séléctionné
                if (isset($this->searchTab["query"][$this->getParam("selectioncol")])) {
                    // Récupération du nom du champ
                    $champrecherche = $this->searchTab["query"][$this->getParam("selectioncol")];
                    // Lorsque magic_quotes est active, tous les caracteres
                    // ' (guillemets simples), " (guillemets doubles),
                    // \ (antislash) et NUL sont echappes avec un antislash
                    // alors on supprime ou on ajouter les antislashs de la
                    // chaine $recherche si besoin
                    if (!get_magic_quotes_gpc()) {
                        // Si postgresql est utilisé on utilise pg_escape_string
                        // sinon AddSlashes
                        if ($this->db->phptype == "pgsql") {
                            $sqlw .= " lower(translate(".$champrecherche.iconv("UTF-8",HTTPCHARSET,"::varchar,'àáâãäçèéêëìíîïñòóôõöùúûüýÿÀÁÂÃÄÇÈÉÊËÌÍÎÏÑÒÓÔÕÖÙÚÛÜÝ','aaaaaceeeeiiiinooooouuuuyyaaaaaceeeeiiiinooooouuuuy')) ");
                            // Si la locale est utf-8 (mode normal) on enlève les accents
                            // et on échappe les caractères spéciaux
                            // sinon on encode la chaîne recherchée en utf-8
                            if(HTTPCHARSET=='UTF-8') {
                                $sqlw .= " like '%".$this->stripAccentsUtf8(pg_escape_string($value))."%' OR ";
                            } else {
                                $sqlw .= " like '%".$this->stripAccentsUtf8(pg_escape_string(iconv(HTTPCHARSET,"UTF-8",$value)))."%' OR ";
                            }
                        } else {
                            $sqlw .= " lower(".$champrecherche.") like '%".strtolower(addslashes($this->getParam("recherche")))."%' or ";
                        }
                    } else {
                        // Si postgresql est utilisé on utilise pg_escape_string
                        // sinon AddSlashes
                        if ($this->db->phptype == "pgsql") {
                            $sqlw .= " lower(translate(".$champrecherche.iconv("UTF-8",HTTPCHARSET,"::varchar,'àáâãäçèéêëìíîïñòóôõöùúûüýÿÀÁÂÃÄÇÈÉÊËÌÍÎÏÑÒÓÔÕÖÙÚÛÜÝ','aaaaaceeeeiiiinooooouuuuyyaaaaaceeeeiiiinooooouuuuy')) ");
                            // Si la locale est utf-8 (mode normal) on enlève les accents
                            // et on échappe les caractères spéciaux
                            // sinon on encode la chaîne recherchée en utf-8
                            if(HTTPCHARSET=='UTF-8')
                                $sqlw .= " like '%".$this->stripAccentsUtf8($value)."%' OR ";
                            else
                                $sqlw .= " like '%".$this->stripAccentsUtf8(iconv(HTTPCHARSET,"UTF-8",$value))."%' OR ";
                        } else {
                            $sqlw .= " lower(".$champrecherche.") like '%".strtolower($this->getParam("recherche"))."%' or ";
                        }
                    }
                }
                
            }
            $sqlw = substr($sqlw, 0, strlen($sqlw) - 3).")";

            // Construction de la requete
            $this->sql .= $sqlw." ".$tri;
            
            // Si la clause de selection n'est pas vide, il n'est pas
            // necessaire d'ajouter le WHERE
            if ($this->selection != "") {
                
                // Construction de la requete qui compte le nombre
                // d'enregistrement
                $this->sqlC = "select count(*) ";
                $this->sqlC .= "from ".$this->table." ";
                $this->sqlC .= $this->selection." and (".$sqlw ;
                
            } else {
                
                // Construction de la requete qui compte le nombre
                // d'enregistrement
                $this->sqlC = "select count(*) ";
                $this->sqlC .= "from ".$this->table." ";
                $this->sqlC .= "where (".$sqlw;
                
            }
            
        }
        
        // Construction de la requete qui compte le nombre d'enregistrement si
        // il y a un group by
        $this->sqlG = $this->sqlC." ".$this->tri;
        
    }

    // {{{ Gestion des messages de debug
    
    /**
     *
     */
    function addToLog($message, $type = DEBUG_MODE) {
        //
        logger::instance()->log("class ".get_class($this)." - ".$message, $type);
    }
    
    // }}}
}

?>