<?php
/**
 * Ce fichier permet de declarer la classe gen.
 *
 * @package openmairie_exemple
 * @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";

/*
 * classe gen
 * principe de base : gerer les infos du sgbd pour constituer l application
 *         table
 *         champ : nom, type , longueur
 *         cle primaire
 *         cle secondaire
 *
 *
 * pre requis du modele de donnees decoulant du principe de base
 * - le nom de la cle primaire est le nom de la table
 * - la cle secondaire est le nom de la table en lien
 * - si la cle est numerique, elle est automatique et elle est masquee en creation
 * - si un champ om_collectivite, alors c est une gestion en multicollectivite
 *
 * principes de generation
 * - champ blob non pris en compte dans table.inc et dans pdf
 * - affichage des dates en francais dans table.inc
 * - uniquement champ text dans champRecherche de table.inc
 * - si le nom du champ est une porte le nom d une table, il est cree une cle secondaire
 *   avec un champ select : la cle est conserve, les champs affiches sont le 1 et le 2 de
 *   la table secondaire
 *
 *- mise a niveau openMairie 4.00 07/09/2010 : voir documentation
 *  om4.1.0 mise a niveau repertoire ../gen/dyn/standard ou autre
 */
class gen {

    /**
     *
     * @var object Objet instance de utils
     */
    var $f = null;

    /**
     *
     */
    var $db = NULL;

    var $msg=""; // message en retour user
    var $table; // table
    var $typecle; // cle numerique ou alpha
    var $base; // base de la table
    var $sgbd; // mysql ou pgsql
    var $option ; // nom du groupe dans le menu ou tableau de bord
    var $longueur=0; // longueur de l enregistrement
    var $info; // description de la table
    var $entete; // entete de fichier
    var $clesecondaire = array(); // cles secondaires
    var $geom = array(); // champs geom
    var $sousformulaires = array(); // table en sousformulaire
    var $tablebase = array(); // tables de la base
    var $multi=1; // table avec champ om_collectivite

    /**
     * @var string nom de la colonne cle primaire
     */
    var $primary_key;

    /**
     * Liste des cles etrangeres de la table actuelle.
     *
     * array_keys : noms des cles etrangeres.
     * array_values : tableaux d'informations sur les tables etrangeres.
     *
     * @var array(string)
     */
    var $foreign_tables = array();

    /**
     * Liste des couples "table.colonne" faisant reference a la table actuelle.
     *
     * array_keys : index numerique.
     * array_values : chaines de caracteres de la forme "table.colonne".
     *
     * @var array(string)
     */
    var $other_tables = array();

    /**
     * @var array(string) nom des colonnes uniques
     */
    var $unique_key = array();

    /**
     * @var array(string) nom des colonnes d'une cle uniques
     */
    var $unique_multiple_key = array();

    /**
     * @var strung libelle de la table actuelle
     */
    var $libelle = '';

    /**
     * var array(string) liste des colonnes NOT NULL
     */
    var $_columns_notnull = array();

    /**
     * @var boolean existance de la colonne om_validite_debut
     */
    var $_om_validite_debut = false;

    /**
     * @var boolean existance de la colonne om_validite_fin
     */
    var $_om_validite_fin = false;

    function gen($table, &$db, $base, $sgbd, $dyn, $schema) {
        // 
        if (isset($GLOBALS["f"])) {
            $this->f = $GLOBALS["f"];
        }
        // DEFINITION DES VARIABLES DE CLASSE
        //
        $this->table = $table;
        //
        $this->db = $db;
        //
        $this->base = $base;
        //
        $this->sgbd = $sgbd;
        //
        if (in_array($table, array('om_etat', 'om_sousetat', 'om_lettretype',
                                   'om_requete', 'om_logo', ))){
            $this->option = "parametrage";
        }
        elseif (strpos($table,"om_") === 0){
            $this->option = "administration";
        }
        else{
            $this->option = "application";
        }
        $this->ent="_(\"".$this->option."\").\" -> \"._(\"".$this->table."\");";
        // entete ==============================================
        // 1ere ligne = balise php
        // 2eme ligne = balise cvs
        // 3eme ligne gen openmairie date et heure de generation
        // attention repris en modification de fichier
        // =====================================================
        $this->entete = "<?php\n//\$Id\$ \n//gen openMairie le ".date('d/m/Y H:i')."\n";
        // RECUPERATION DE LA LISTE DE TOUTES LES TABLES DE LA BASE DE DONNEES
        // Construction de la requete
        if ($sgbd == "mysql") {
            $sql = "SHOW TABLES FROM `".DB_PREFIXE.$base."`";
        }
        if ($sgbd == "pgsql") {
            $sql = "select tablename from pg_tables where schemaname='".$schema."' UNION select viewname from pg_views where schemaname='".$schema."'";
        }
        // Execution de la requete
        $res1 = $this->db->query($sql);
        // Logger
        $this->addToLog("gen(): db->query(\"".$sql."\");", VERBOSE_MODE);
        // Verification d'erreur
        if (database::isError($res1)) {
            // database::isError($resource = NULL, $forcereturn = false)
            // cette methode envoi un die() lorsqu'il y a une erreur et que le
            // parametre $forcereturn est a false (valeur par defaut)
            die();
        }
        // Recuperation de la liste de toutes les tables de la base de donnees
        while ($row =& $res1->fetchRow()) {
            // On enleve de la liste les sequences et la table sur laquelle
            // on est en train de faire la generation
            if (substr($row[0], -3, 3) != "seq" and $row[0] != $table) {
                //
                array_push($this->tablebase, $row[0]);
            }
        }
        $this->msg="<span class=\"bold\">"._("Table")." : ".$this->table."</span><br />";
        // Recuperation des informations de la table
        $this->info = $this->db->tableInfo(DB_PREFIXE.$this->table);

        // recuperation de la cle primaire
        $this->primary_key = $this->get_primary_key($this->table);

        // initialisation de la liste des colonnes NOT NULL
        $this->_init_constraint_notnull();

        // Logger
        $this->addToLog("gen(): DB PEAR \$this->info = ".print_r($this->info, true), EXTRA_VERBOSE_MODE);
        
        // Chargement des tables de cles uniques et uniques multiple
        $this->set_unique_key($this->table);
        
        // Taille d'affichage du champ text (nombre de lignes)
        $max = 6;
        
        // Taille d'affichage du champ text (nombre de colonnes)
        $taille = 80;
        
        // Taille d'affichage du champ par defaut dans le cas ou nous sommes
        // dans l'impossibilite de determiner la taille du champ
        $pgsql_taille_defaut = 20;
        
        // Taille d'affichage du champ minimum pour ne pas afficher des
        // champs trop petits ou la saisie serait impossible
        $pgsql_taille_minimum = 10;
        
        // Taille d'affichage du champ maximum pour ne pas afficher des
        // champs trop grands ou le formulaire depasserait de l'ecran
        $pgsql_taille_maximum = 30;
        
        // 
        $pgsql_longueur_date = 12; // taille d'affichage de la date '
        
        //
        if (file_exists ("../gen/dyn/form.inc.php")){
            include ("../gen/dyn/form.inc.php");
            $this->msg.="<br />"._("Chargement du parametrage")." ../gen/dyn/form.inc.php";
        } elseif (file_exists ("../gen/dyn/form.inc")){
            include ("../gen/dyn/form.inc");
            $this->msg.="<br />"._("Chargement du parametrage")." ../gen/dyn/form.inc";
        }


        // CLES ETRANGERE
        // Initialisation de la liste des clés étrangères (contraintes
        // FOREIGN KEY) de la table en cours vers les autres tables
        $this->_init_foreign_tables();
        // SOUS FORMULAIRE
        // Initialisation de la liste des clés étrangères (contraintes
        // FOREIGN KEY) des autres tables vers la table en cours
        $this->_init_other_tables();

        // POSTULAT DE DEPART SUR LES TYPES DE DONNEES
        // variable chaine = string
        // variable numerique = int
        // variable textareal = blob
        // SPECIFICITES PGSQL POUR LES INFORMATIONS SUR LES COLONNES DE LA TABLE
        if ($sgbd == 'pgsql') {
            // Recherche des attributs dans les tables systèmes de PostgreSQL
            // Constitution d'une table de valeurs des colonnes de la table
            // utilisation de ces valeurs pour le générateur
            //
            // initialisation du tableau associatif comportant les attributs de champs
            $attchamps=array();
            // requête donnant les attributs par champ
            $sql = "SELECT attname, attnotnull, atttypmod FROM pg_attribute WHERE ";
            $sql .= "attrelid = '".DB_PREFIXE.$this->table."'::regclass ";
            $sql .= "AND attstattarget = -1;";
            $res =& $db->query($sql);
            //remplissage du tableau associatif
            while ($res->fetchInto($row, DB_FETCHMODE_ASSOC) ) {
                // Remplissage de la table des attributs de champs
                // DB_FETCHMODE_ORDERED
                $attchamps[$row["attname"]]=array("attnotnull"=> $row["attnotnull"], "atttypmod"=>$row["atttypmod"]);
            }
            // Logger
            $this->addToLog("gen(): db->query(\"".$sql."\");", VERBOSE_MODE);
            if (database::isError($res, true)) {
                if (DEBUG >= DEBUG_MODE) {
                    echo "Erreur";
                }
            }
            // boucle sur les champs de la table openmairie pour définir les attributs des champs
            for ($t = 0; $t < sizeof($this->info); $t++) {
                // test d'existence du champ dans les résultats de requête
                if ( isset( $attchamps[$this->info[$t]["name"]] ) ) {
                    // la valeur existe
                    // champ notnull
                    $this->info[$t]["notnull"] = $attchamps[$this->info[$t]["name"]]["attnotnull"];
                    // champ atttypmod : fixer la taille pour les champs ayant len à -1
                    if ($this->info[$t]["len"] == -1) {
                        $this->info[$t]["len"] = $attchamps[$this->info[$t]["name"]]["atttypmod"]-4;
                        //
                        $this->info[$t]["max_saisie"] = $this->info[$t]["len"];
                        //
                        if ($this->info[$t]["len"] < $pgsql_taille_minimum) {
                            $this->info[$t]["taille_affichage"] = $pgsql_taille_minimum;
                        } elseif ($this->info[$t]["len"] > $pgsql_taille_maximum) {
                            $this->info[$t]["taille_affichage"] = $pgsql_taille_maximum;
                        } else {
                            $this->info[$t]["taille_affichage"] = $this->info[$t]["len"];
                        }
                    }
                } else {
                    // la valeur n'existe pas ; on utilise les valeurs par défaut
                    // champ notnull
                    $this->info[$t]["notnull"] = 'f';
                    // champ atttypmod : fixer la taille pour les champs ayant len à -1
                    if ($this->info[$t]["len"] == -1) {
                        $this->info[$t]["len"] = $pgsql_taille_defaut;
                        //
                        $this->info[$t]["taille_affichage"] = $this->info[$t]["len"];
                        $this->info[$t]["max_saisie"] = $this->info[$t]["len"];
                    }
                }
                // Taille des champs numeriques XXX Completer les tailles de champs en fonction des types
                if ($this->info[$t]["type"] == "int2") {
                    $this->info[$t]["type"] = "int";
                    $this->info[$t]["len"] = 6;
                } elseif ($this->info[$t]["type"] == "int4") {
                    $this->info[$t]["type"] = "int";
                    $this->info[$t]["len"] = 11;
                } elseif ($this->info[$t]["type"] == "int8") {
                    $this->info[$t]["type"] = "int";
                    $this->info[$t]["len"] = 20;
                } elseif (substr($this->info[$t]["type"], 0, 3) == "int") {
                    $this->info[$t]["len"] = 11;
                    $this->info[$t]["type"] = "int";
                } elseif (substr($this->info[$t]["type"], 0, 5) == "float"
                    or $this->info[$t]["type"] == "numeric"
                    or $this->info[$t]["type"] == "money") {
                    // float a gerer avec la recuperation des attributs dans la base
                    $this->info[$t]["type"] = "float";
                    $this->info[$t]["len"] = 20;
                } elseif ($this->info[$t]["type"] == "bpchar"
                    or $this->info[$t]["type"] == "char"
                    or $this->info[$t]["type"] == "varchar"
                    or $this->info[$t]["type"] == "character varying") {
                    // STRING
                    $this->info[$t]["type"] = "string";
                } elseif ($this->info[$t]["type"] == "text") {
                    // text = len -1
                    // TEXT
                    $this->info[$t]["type"] = "blob";
                    $this->info[$t]["max_saisie"] = $max;
                    $this->info[$t]["taille_affichage"] = $taille;
                } elseif ($this->info[$t]["type"] == "boolean") {
                    // BOOL
                    $this->info[$t]["type"] = "bool";
                } elseif ($this->info[$t]["type"] == "date") { // date = len 4
                    // Taille des colonnes de type DATE
                    $this->info[$t]["len"] = $pgsql_longueur_date;
                } elseif ($this->info[$t]["type"] == "geometry") {
                    $this->info[$t]["type"] = "geom";
                }
            }
        }
        // SPECIFICITES MYSQL POUR LES INFORMATIONS SUR LES COLONNES DE LA TABLE
        if ($sgbd == "mysql") {
            //
            for ($t =0; $t < sizeof($this->info); $t++) {
                // NULL / NOT NULL
                // Gestion de l'attribut not null pour mysql
                if (strpos($this->info[$t]["flags"], "not_null") !== false) {
                    $this->info[$t]["notnull"] = 't';
                } else {
                    $this->info[$t]["notnull"] = 'f';
                }
                // INT
                if ($this->info[$t]["type"] == "int") {
                    $this->info[$t]["type"] = "int";
                    if ($this->info[$t]["len"] == 1) {
                        // gestion du tinyint comme booléen
                        $this->info[$t]["len"] = 1;
                    } elseif($this->info[$t]["len"] <= 2) {
                        $this->info[$t]["len"] = 6;
                    } elseif ($this->info[$t]["len"] <= 4) {
                        $this->info[$t]["len"] = 11;
                    } elseif ($this->info[$t]["len"] <= 8) {
                        $this->info[$t]["len"] = 20;
                    }
                } elseif ($this->info[$t]["type"] == "decimal"
                    or $this->info[$t]["type"] == "real"
                    or $this->info[$t]["type"] == "double") {
                    // float a gerer avec la recuperation des attributs dans la base
                    $this->info[$t]["type"] = "float";
                    $this->info[$t]["len"] = 20;
                }
                // STRING
                if ($this->info[$t]["type"] =="char"
                    or $this->info[$t]["type"] =="varchar"
                    or $this->info[$t]["type"] =="string") {
                    // char len = 1 (meme pour longueur =10) / character : bpchar len=-1 / character varying : varchar len=-1
                    $this->info[$t]["type"] = "string";
                    // TAILLE & MAX
                    $this->info[$t]["max_saisie"] = $this->info[$t]["len"];
                    if ($this->info[$t]["len"] < $pgsql_taille_minimum) {
                        $this->info[$t]["taille_affichage"] = $pgsql_taille_minimum;
                    } elseif ($this->info[$t]["len"] > $pgsql_taille_maximum) {
                        $this->info[$t]["taille_affichage"] = $pgsql_taille_maximum;
                    } else {
                        $this->info[$t]["taille_affichage"] = $this->info[$t]["len"];
                    }
                }
                // BOOL
                // Gestion du booleen pour mysql en partant du principe que
                // tout champ de type entier et de taille 1 est un booleen
                if ($this->info[$t]["type"] == "int"
                    && $this->info[$t]["len"] == "1") {
                    $this->info[$t]["type"] = "bool";
                }
                // BLOB
                if ($this->info[$t]["type"] == "blob") {
                    $this->info[$t]["max_saisie"] = $max;
                    $this->info[$t]["taille_affichage"] = $taille;
                }
            }
        }
        // TRAITEMENT STANDARD DES INFORMATIONS SUR LES COLONNES DE LA TABLE
        // Boucle sur chaque champ de la table
        foreach ($this->info as $elem) {

            if ($elem['name'] == 'om_validite_debut') {
                $this->_om_validite_debut = true;
            }

            if ($elem['name'] == 'om_validite_fin') {
                $this->_om_validite_fin = true;
            }

            // longueur enregistrement (sans blob)
            if($elem["type"]!="blob") // exclusion des blob (mysql)
                $this->longueur= $this->longueur+$elem["len"];

            // cle num ou alpha_num
            if($elem['name'] == $this->primary_key) {
                if($elem['type'] == 'string') {
                    $this->typecle = 'A';
                } else {
                    $this->typecle = 'N';
                }
            } // primary key

            // table multi ayant un champ om_collectivite
            if ($elem["name"] == 'om_collectivite') {
                //
                $this->multi = "2";
            }

            // champs geom
            if ($elem["type"] == "geom"){
                array_push($this->geom, $elem["name"]);
            }
        }

        // Logger
        $this->addToLog("gen(): \$this->info = ".print_r($this->info, true), EXTRA_VERBOSE_MODE);
    }

    /**
     * Permet de vérifier si une table fait partie du framework ou non.
     *
     * Le générateur adopte un comportement différent si la table générée fait
     * partie du framework. Cette méthode indique si c'est le cas ou non. 
     * 
     * @param $table string Le nom de la table.
     *
     * @return boolean
     */
    function is_omframework_table($table = null) {
        //
        if (is_null($table)) {
            //
            return false;
        }
        //
        if (substr($table, 0, 3) != "om_") {
            //
            return false;
        }
        //
        return true;
    }




    /* FONCTIONS GENERIQUES
     * lecture - ecriture de fichier
     * nomfichier : nom du fichier
     * contenu : contenu a ecrire ou retourne en lecture
     * modif_table : modification a apporter dans un fichier
     */

    function ecrirefichier($nomfichier,$contenu){
        if($this->is_editable($nomfichier)) {
            // le fichier est genere seulement s'il est different de l'existant
            // la ligne date et heure de generation n'est pas prise en compte
            if (!$this->stream_slightly_equals_file($contenu, $nomfichier)) {

                $inf = fopen($nomfichier,"w");
                fwrite($inf,$contenu);
                fclose($inf);
                $this->msg.="<br /><span class=\"gen-ok bold\"> "._('Generation de')." ".
                     $nomfichier." </span>";

            // sinon il n'est pas re-ecrit sur le disque
            } else {
                $this->msg .= "<br /><span class=\"\">"._("Aucun changement de")." ".$nomfichier;
                $this->msg .= " </span> ";
            }
            return true;
        } else {
            $this->msg .= "<br /><span class=\"gen-error\">"._("Erreur de droits d'ecriture sur").' '.$nomfichier;
            $this->msg .= " </span> ";
            return false;
        }
    }

    function supprimerfichier($nomfichier){
        if(is_writable($nomfichier)) {
             unlink($nomfichier);
             $this->msg.="<br /><span class=\"bold gen-ok\">  "._('Supression de')." ".$nomfichier." "." </span> ";
        } else {
            if(!file_exists($nomfichier)) {
                $this->msg.="<br /><span class=\"bold\"> "._('Fichier inexistant ou illisible')." ".$nomfichier." </span> ";
            } else {
                $this->msg.="<br /><span class=\"bold gen-error\"> "._('Impossible de supprimer')." ".$nomfichier." </span> ";
            }
            
        }
    }

    function lirefichier($nomfichier){
          fopen($nomfichier,"r");
          $contenu = file($nomfichier);
          return $contenu;
    }

    /*
     * affichage des dates au format francais
     *
     */

    function champaffichedatemysql($temp, $alias=null) {

        if ($alias == null) {
            $alias = $temp;
        }

        // avec sequence d echappement
        return "'concat(substring(".$temp.",9,2),\'/\',substring(".$temp.",6,2),\'/\',substring(".$temp.",1,4)) as ".$alias."'";
    }

    function champaffichedatepgsql($temp, $alias=null) {

        if ($alias == null) {
            $alias = $temp;
        }

        // avec sequence d echappement
        return "'to_char(".$temp." ,\'DD/MM/YYYY\') as \"'._(\"".$alias."\").'\"'";
        //return "(substring(".$temp.",9,2),\'||\',substring(".$temp.",6,2),\'||\',substring(".$temp.",1,4)) as ".$temp;
    }

    function champaffichedatepdfmysql($temp){
        // avec sequence d echappement
        return "concat(substring(".$temp.",9,2),'/',substring(".$temp.",6,2),'/',substring(".$temp.",1,4)) as ".$temp;
    }

    function champaffichedatepdfpgsql($temp){
        // sans sequence d echappement
        return "to_char(".$temp." ,'DD/MM/YYYY') as ".$temp;
        //return "(substring(".$temp.",9,2),'||',substring(".$temp.",6,2),'||',substring(".$temp.",1,4)) as ".$temp;
    }

    /*
     * contenus table.inc table.form.inc table.obj.inc
     */

    /**
     * Construit le contenu du script [sql/<OM_DB_PHPTYPE>/<TABLE>.inc.php].
     *
     * @return string
     */
    function table_sql_inc() {

        //
        if ($this->is_omframework_table($this->table)) {
            //
            $template = "%s
include \"../core/sql/%s/%s.inc.php\";

?>
";
        } else {
            //
            $template = "%s
include \"../gen/sql/%s/%s.inc.php\";

?>
";
        }
        //
        return sprintf(
            $template,
            $this->entete,
            $this->sgbd,
            $this->table
        );

    }

    /**
     * Construit le contenu du script [core/sql/<OM_DB_PHPTYPE>/<TABLE>.inc.php].
     *
     * @return string
     */
    function table_sql_inc_core() {

        //
        if ($this->is_omframework_table($this->table)) {
            //
            $template = "%s
include \"../gen/sql/%s/%s.inc.php\";

?>
";
            //
            return sprintf(
                $template,
                $this->entete,
                $this->sgbd,
                $this->table
            );
        } else {
            //
            return "";
        }

    }

    /**
     * Construit le contenu du script [gen/sql/<OM_DB_PHPTYPE>/<TABLE>.inc.php].
     *
     * @param $dyn mixed Fichier de paramétrage.
     * @return string
     */
    function table_sql_inc_gen($dyn = null) {
        // Initialisation des variables de travail
        $champaffiche = "";
        $champnonaffiche = "";
        $champrecherche = "";
        //Test si plusieurs cles etrangeres vers la meme table
        $fkLinkedTable=array();
        foreach ($this->foreign_tables as $value) {
            $fkLinkedTable[]=$value['foreign_table_name'];
        }
        //Tableau avec nom de table comme cle et nombre d'occurence comme valeurs
        $countLinkedTable=array_count_values($fkLinkedTable);
        //
        $tri = ""; // champ de tri

        // table du libelle
        $libelle_t = '';
        // colonne du libelle
        $libelle_c = '';
        // alias de la table du libelle
        $alias = '';

        // recuperation du libelle
        $libelle = $this->get_libelle();

        // si la colonne du libelle est une cle etrangere
        // on utilise le libelle de la table etrangere pour le trier
        if (in_array($libelle, $this->clesecondaire)) {
            if($countLinkedTable[$this->foreign_tables[$libelle]['foreign_table_name']]>1) {
                $alias = $this->foreign_tables[$libelle]['foreign_table_name'].
                            array_search($libelle, $this->clesecondaire);
            } else {
                $alias = $this->foreign_tables[$libelle]['foreign_table_name'];
            }
            $libelle_t = $this->foreign_tables[$libelle]['foreign_table_name'];
            $libelle_c = $this->get_libelle_of($libelle_t);

        // sinon on affiche la colonne telle quelle
        } else {
            $alias = $this->table;
            $libelle_t = $this->table;
            $libelle_c = $libelle;
        }

        // creation de la clause ORDER BY
        $tri = 'ORDER BY';
        $tri .= ' ';

        // affichage des valeurs NULL en dernier pour MySQL
        if (OM_DB_PHPTYPE == 'mysql') {
            $tri .= 'ISNULL('.$alias.'.'.$libelle_c.') ASC,';
            $tri .= ' ';
        }

        // ordre croissant explicite
        $tri .= $alias.'.'.$libelle_c.' ASC';

        // affichage des valeurs NULL en dernier pour PostgresSQL
        if (OM_DB_PHPTYPE == 'pgsql') {
            $tri .= ' ';
            $tri .= 'NULLS LAST';
        }

        $serie = 15; // nombre d'enregistrement par page
        $ico = "../img/ico_application.png"; // icone de l'application
        //
        if (file_exists ("../gen/dyn/form.inc.php")){
            include ("../gen/dyn/form.inc.php");
            $this->msg.="<br />"._("Chargement du parametrage")." ../gen/dyn/form.inc.php";
        } elseif (file_exists ("../gen/dyn/form.inc")){
            include ("../gen/dyn/form.inc");
            $this->msg.="<br />"._("Chargement du parametrage")." ../gen/dyn/form.inc";
        }

        // Inclusion du fichier de paramétrage du générateur gen/dyn/tab.inc.php
        //
        if (file_exists("../gen/dyn/tab.inc.php")) {
            //
            include "../gen/dyn/tab.inc.php";
        }
        
        //
        $edition=$this->table;
        
        // On ajoute la clé primaire dans le champaffiche et le champrecherche
        // en première position
        $champaffiche.= "\n    '".$this->table.".".$this->primary_key." as \"'._(\"".$this->primary_key."\").'\"',";
        $champrecherche.= "\n    '".$this->table.".".$this->primary_key." as \"'._(\"".$this->primary_key."\").'\"',";

        // variable suivant champs : champaffiche et champrecherche
        // $champaffiche; // tableau des noms des champs affiches dans table.inc
        // $champrecherche; // tableau des noms des champs de recherche dans table.inc
        foreach ($this->info as $elem) {

            if ($elem['name'] == $this->primary_key) {
                continue;
            }

            //
            $is_field_in_overrided_list = NULL;
            if (isset(${$this->table})) {
                if (in_array($elem["name"], ${$this->table})) {
                    $is_field_in_overrided_list = true;
                } else {
                    $is_field_in_overrided_list = false;
                }
            }
            // pas d affichage de blob en tableinc
            // affichage au format date
            $temp ='champaffichedate'.$this->sgbd;
            //
            if ($elem["type"] != "blob" 
                && !($this->multi == 2 && $elem["name"] == "om_collectivite" && $this->table != "om_collectivite")
                && $is_field_in_overrided_list !== false) {
                //
                $champaffiche.="\n    ";
                //
                if ($elem["type"] == "date") {
                    //
                    $champaffiche .= $this->$temp($this->table.".".$elem["name"], $elem["name"]).",";
                } elseif ($elem["type"] == "bool") {
                    //
                    if ($this->sgbd == "mysql") {
                        //
                        $champaffiche.= "\"case ".$this->table.".".$elem["name"]." when 1 then 'Oui' else 'Non' end as \\\"\"._(\"".$elem["name"]."\").\"\\\"\",";
                    } elseif ($this->sgbd == "pgsql") {
                        //
                        $champaffiche.= "\"case ".$this->table.".".$elem["name"]." when 't' then 'Oui' else 'Non' end as \\\"\"._(\"".$elem["name"]."\").\"\\\"\",";
                    }
                } else {

                    // Si le champ que nous sommes en train d'afficher est une cle secondaire
                    if (!empty($this->clesecondaire) && in_array($elem["name"], $this->clesecondaire)) {

                        $ftable = $this->foreign_tables[$elem["name"]]['foreign_table_name'];

                        // recuperation du libelle
                        $flibelle = $this->get_libelle_of($ftable);

                        if($countLinkedTable[$this->foreign_tables[$elem["name"]]['foreign_table_name']]>1) {
                            $champaffiche.= "'$ftable".
                                array_search($elem["name"], $this->clesecondaire).
                                '.'.$flibelle;
                        } else {
                            $champaffiche.= "'".$ftable.".".$flibelle;
                        }
                        
                    } else {
                        $champaffiche.= "'".$this->table.".".$elem["name"];
                    }

                    $champaffiche.= ' ';
                    $champaffiche.= "as \"'._(\"".$elem["name"]."\").'\"',";
                }
            } else {
                $champnonaffiche.="\n    ";
                $champnonaffiche.= "'".$this->table.".".$elem["name"]." as \"'._(\"".$elem["name"]."\").'\"',";
            }
            // 
            if (($elem["type"] == "string" || $elem["type"] == "int" || $elem["type"] == "float") && $is_field_in_overrided_list !== false) {
                //
                if ($this->multi == 2 && $elem["name"] == "om_collectivite" && $this->table != "om_collectivite") {
                    //
                } else {

                    $champrecherche.="\n    ";
                    // Si le champ que nous sommes en train d'afficher est une cle secondaire
                    if (!empty($this->clesecondaire) && in_array($elem["name"], $this->clesecondaire)) {

                        $ftable = $this->foreign_tables[$elem["name"]]['foreign_table_name'];

                        // recuperation du libelle
                        $flibelle = $this->get_libelle_of($ftable);
                        if($countLinkedTable[$this->foreign_tables[$elem["name"]]['foreign_table_name']]>1) {
                            $champrecherche.= "'".$ftable.array_search($elem["name"], $this->clesecondaire).".".$flibelle." ";
                        } else {
                            $champrecherche.= "'".$ftable.".".$flibelle." ";
                        }
                    } else {
                         $champrecherche.="'".$this->table.".".$elem["name"]." ";
                    }

                    $champrecherche.= "as \"'._(\"".$elem["name"]."\").'\"',";
                }
            }
        }
        // creation de table.inc.php
        $tableinc= $this->entete;
        $tableinc.="\n\$DEBUG=0;";
        $tableinc.="\n\$serie=".$serie.";";
        $tableinc.="\n\$ico=\"".$ico."\";";
        $tableinc.="\n\$ent = ".$this->ent;

        if ($this->is_om_validite() == true) {
            $tableinc.="\n\$om_validite = true;";
        }

        $tableinc.="\nif(!isset(\$premier)) \$premier='';";
        $tableinc.="\nif(!isset(\$recherche1)) \$recherche1='';";
        $tableinc.="\nif(!isset(\$tricolsf)) \$tricolsf='';";
        $tableinc.="\nif(!isset(\$premiersf)) \$premiersf='';";
        $tableinc.="\nif(!isset(\$selection)) \$selection='';";
        $tableinc.="\nif(!isset(\$retourformulaire)) \$retourformulaire='';";
        // idz entete onglet
        $tableinc.="\nif (isset(\$idx) && \$idx != ']' && trim(\$idx) != '') {";
        $tableinc.="\n    \$ent .= \"->&nbsp;\".\$idx.\"&nbsp;\";";
        $tableinc.="\n}";
        $tableinc.="\nif (isset(\$idz) && trim(\$idz) != '') {";
        $tableinc.="\n    \$ent .= \"&nbsp;\".strtoupper(\$idz).\"&nbsp;\";";
        $tableinc.="\n}";
        // ***
        // TABLE
        $tableinc .= "\n// FROM ";
        $tableinc .= "\n\$table = DB_PREFIXE.\"".$this->table;
        //
        if (!empty($this->clesecondaire)) {
            //
            foreach ($this->clesecondaire as $key => $elem) {
                //
                if (isset($this->foreign_tables[$elem])) {
                    $tableinc .= "\n    LEFT JOIN \".DB_PREFIXE.\"".$this->foreign_tables[$elem]["foreign_table_name"]." ";
                    $ftable=$this->foreign_tables[$elem]['foreign_table_name'];
                    if($countLinkedTable[$ftable]>1) {
                        $tableinc .= "as $ftable".$key." ";
                    }
                    $tableinc .= "\n        ON ".$this->table.".".$elem."=";
                    if($countLinkedTable[$ftable]>1) {
                        $tableinc .= "$ftable".$key;
                    } else {
                        $tableinc .=  $ftable;
                    }
                    $tableinc .= ".".$this->foreign_tables[$elem]["foreign_column_name"]." ";
                    
                } else {
                    //
                    $tableinc .= "\n    LEFT JOIN \".DB_PREFIXE.\"".$elem." as a".$key." ";
                    $tableinc .= "\n        ON ".$this->table.".".$elem."=a".$key.".".$elem." ";
                }
            }
        }
        //
        $tableinc.= "\";";
        // CHAMP AFFICHE
        $tableinc .= "\n// SELECT ";
        $tableinc.="\n\$champAffiche = array(".$champaffiche."\n    );";

        if ($this->multi == 2 && $this->table != 'om_collectivite') {
            if (isset($countLinkedTable["om_collectivite"])
                && $countLinkedTable["om_collectivite"] > 1) {
                $alias = 'om_collectivite'.
                            array_search('om_collectivite', $this->clesecondaire).
                            '.libelle';
            } else {
                $alias = 'om_collectivite.libelle';
            }

            $tableinc .= "\n//\nif (\$_SESSION['niveau'] == '2') {";
            $tableinc .= "\n    array_push(\$champAffiche, \"".$alias." as \\\"\"._(\"collectivite\").\"\\\"\");";
            $tableinc .= "\n}";
        }
        $tableinc.="\n//\n\$champNonAffiche = array(".$champnonaffiche."\n    );";
        $tableinc.="\n//\n\$champRecherche = array(".$champrecherche."\n    );";
        if ($this->multi == 2 && $this->table != 'om_collectivite') {
            if (isset($countLinkedTable["om_collectivite"])
                && $countLinkedTable["om_collectivite"] > 1) {
                $alias = 'om_collectivite'.
                            array_search('om_collectivite', $this->clesecondaire).
                            '.libelle';
            } else {
                $alias = 'om_collectivite.libelle';
            }
            
            $tableinc .= "\n//\nif (\$_SESSION['niveau'] == '2') {";
            $tableinc .= "\n    array_push(\$champRecherche, \"".$alias." as \\\"\"._(\"collectivite\").\"\\\"\");";
            $tableinc .= "\n}";
        }
        $tableinc.="\n\$tri=\"".$tri."\";";
        $tableinc.="\n\$edition=\"".$edition."\";";
        // les sous formulaires
        // href
        $tableinc.=$this->selection_inc();
        $tableinc.=$this->sousformulaire_inc();
        $tableinc.="\n?>";
        return $tableinc;
    }

    function selection_inc(){
        $contenu='';
        // selection suivant cle secondaire et multi collectivite
        if($this->multi==2){
            if ($this->is_om_validite() == true) {
                $contenu.="\n\$wehere_om_validite='';";
            }
            $contenu.="\nif (\$_SESSION['niveau']== '2')";

            if ($this->is_om_validite() == true) {
                $contenu.="\n    \$selection=' WHERE ".$this->filter_om_validite($this->table)."';";
            } else {
                $contenu.="\n    \$selection='';";
            }

            $contenu.="\nelse {";
            $contenu.="\n    \$selection=\" where ".$this->table;
            $contenu.=".om_collectivite = '\".\$_SESSION['collectivite'].\"'";

            if ($this->is_om_validite() == true) {
                $contenu.=$this->filter_om_validite($this->table, true);
                $contenu.="\";";
                $contenu.="\n    \$where_om_validite='".$this->filter_om_validite($this->table, true)."';";
            } else {
                $contenu.="\";";
                
            }
            $contenu.="\n}";

        }else{
            if ($this->is_om_validite() == true) {
                $contenu.="\n\$selection=' WHERE ".$this->filter_om_validite($this->table)."';";
            } else {
                $contenu.="\n\$selection='';";
            }
        }

        if(!empty($this->clesecondaire)){

            $ftables = array();
            
            foreach ($this->foreign_tables as $key => $infos) {

                if (!key_exists($infos['foreign_table_name'], $ftables)) {
                    $ftables[$infos['foreign_table_name']] = array($key);
                } else {
                    if (!in_array($key, $ftables[$infos['foreign_table_name']])) {
                        array_push($ftables[$infos['foreign_table_name']], $key);
                    }
                }
            }

            foreach ($ftables as $table => $columns) {
                $contenu.="\nif (\$retourformulaire== '".$table."') {";

                if ($this->is_om_validite() == true) {
                    $contenu .= "\n    \$where_om_validite='";
                    $contenu .= $this->filter_om_validite($this->table,
                                                          true)."';";
                }

                if ($this->multi == 2) {
                    $contenu .= "\n    if (\$_SESSION['niveau']== '2'){";
                    $contenu .= "\n        \$selection=\" WHERE (";

                    $contenu_tmp = '';
                    foreach ($columns as $column) {
                        $contenu_tmp .= $this->table.'.';
                        $contenu_tmp .= $column." ='\".\$idx.\"'";
                        $contenu_tmp .= ' OR ';
                    }
                    $contenu .= substr($contenu_tmp, 0, strlen($contenu_tmp)-4);

                    $contenu .= ')';

                    if ($this->is_om_validite() == true) {
                        $contenu.=$this->filter_om_validite($this->table, true);
                        $contenu.="\";";
                    } else {
                        $contenu.="\";";
                    }

                    $contenu .= "\n    }else{";
                    $contenu .= "\n        \$selection=\" WHERE (";

                    $contenu_tmp = '';
                    foreach ($columns as $column) {
                        $contenu_tmp .= $this->table.'.';
                        $contenu_tmp .= $column." ='\".\$idx.\"'";
                        $contenu_tmp .= ' OR ';
                    }
                    $contenu .= substr($contenu_tmp, 0, strlen($contenu_tmp)-4);

                    $contenu .= ')';

                    $contenu .= ' AND '.$this->table.'.om_collectivite = ';
                    $contenu .= "'\".\$_SESSION['collectivite'].\"'";

                    if ($this->is_om_validite() == true) {
                        $contenu.=$this->filter_om_validite($this->table, true);
                    }

                    $contenu .= "\";";
                    $contenu .= "\n    }";

                } else {

                    $contenu .= "\n    \$selection=\" WHERE (";

                    $contenu_tmp = '';
                    foreach ($columns as $column) {
                        $contenu_tmp .= $this->table.'.';
                        $contenu_tmp .= $column." ='\".\$idx.\"'";
                        $contenu_tmp .= ' OR ';
                    }
                    $contenu .= substr($contenu_tmp, 0, strlen($contenu_tmp)-4);

                    $contenu .= ')';

                    if ($this->is_om_validite() == true) {
                        $contenu .= $this->filter_om_validite($this->table, true);
                    }

                    $contenu .= "\";";
                }
                $contenu .= "\n}";
            }
        }

        if ($this->is_om_validite() == true) {
            $contenu.="\n\n";
            $contenu.="if (isset(\$_GET['valide']) and \$_GET['valide'] == 'false') {\n";
            $contenu.="    if (!isset(\$where_om_validite) or ";
            $contenu.="(isset(\$where_om_validite) and \$where_om_validite == '')) {\n";
            $contenu.="        if (trim(\$selection) != '') {\n";
            $contenu.="            \$selection = '';\n";
            $contenu.="        }\n";
            $contenu.="    } else {\n";
            $contenu.="        \$selection = trim(str_replace(\$where_om_validite, '', \$selection));\n";
            $contenu.="    }\n";
            $contenu.="}\n";
        }

        return $contenu;
    }

    function sousformulaire_inc(){

        $code = '';

        if (!empty($this->sousformulaires)) {
            foreach($this->sousformulaires as $sousformulaire) {
                $code .= "\n    ";
                $code .= "'".$sousformulaire."',";
            }
            
            $code = "\n\$sousformulaire = array(".$code.");";
        }

        return $code;
    }

    /**
     * Construit le contenu du script [sql/<OM_DB_PHPTYPE>/<TABLE>.form.inc.php].
     *
     * @return string
     */
    function table_sql_forminc() {

        //
        if ($this->is_omframework_table($this->table)) {
            //
            $template = "%s
include \"../core/sql/%s/%s.form.inc.php\";

?>
";
        } else {
            //
            $template = "%s
include \"../gen/sql/%s/%s.form.inc.php\";

?>
";
        }
        //
        return sprintf(
            $template,
            $this->entete,
            $this->sgbd,
            $this->table
        );

    }

    /**
     * Construit le contenu du script [core/sql/<OM_DB_PHPTYPE>/<TABLE>.form.inc.php].
     *
     * @return string
     */
    function table_sql_forminc_core() {

        //
        if ($this->is_omframework_table($this->table)) {
            //
            $template = "%s
include \"../gen/sql/%s/%s.form.inc.php\";

?>
";
            //
            return sprintf(
                $template,
                $this->entete,
                $this->sgbd,
                $this->table
            );
        } else {
            //
            return "";
        }

    }

    /**
     * Construit le contenu du script [gen/sql/<OM_DB_PHPTYPE>/<TABLE>.form.inc.php].
     *
     * @param $dyn mixed Fichier de paramétrage.
     * @return string
     */
    function table_sql_forminc_gen($dyn = null){
        // blob
        $max=6; // nb de ligne blob
        $taille=80; // taille du blob
        // pgsql
        $pgsql_taille_defaut = 20; // taille du champ par defaut si retour pg_field_prtlen =0
        $pgsql_taille_minimum = 10; // taille minimum d affichage d un champ
        $pgsql_longueur_date=12; // taille d'affichage de la date '
        $ico = "../img/ico_application.png"; // icone de l'application
        if (file_exists ("../gen/dyn/form.inc.php")){
            include ("../gen/dyn/form.inc.php");
            $this->msg.="<br />"._("Chargement du parametrage")." ../gen/dyn/form.inc.php";
        } elseif (file_exists ("../gen/dyn/form.inc")){
            include ("../gen/dyn/form.inc");
            $this->msg.="<br />"._("Chargement du parametrage")." ../gen/dyn/form.inc";
        }   
        //
        $champ="";
        foreach($this->info as $elem){
                $champ.= "\n    \"".$elem["name"]."\",";
        }
        $champ =  substr($champ,0,strlen($champ)-1);
        $tableforminc= $this->entete;
        $tableforminc.="\n\$DEBUG=0;";
        $tableforminc.="\n\$ico=\"".$ico."\";";
        $tableforminc.="\n\$ent = ".$this->ent;
        $tableforminc.="\n\$tableSelect=DB_PREFIXE.\"".$this->table."\";";
        $tableforminc.="\n\$champs=array(".$champ.");";
        $tableforminc.=$this->sql_select();
        $tableforminc.="\n?>";
        return $tableforminc;
    }

    function sql_select(){
    // select si cle secondaire
        if(!empty($this->clesecondaire)){
            $contenu ="\n//champs select";
            foreach($this->clesecondaire as $elem){

                if (isset($this->foreign_tables[$elem])) {

                    // recherche de la table et de la cle primaire
                    $ftable = $this->foreign_tables[$elem]['foreign_table_name'];
                    $fprimary_key = $this->foreign_tables[$elem]['foreign_column_name'];

                    $contenu .= "\n\$sql_".$elem."=\"SELECT ";
                    $contenu .= $ftable.'.'.$fprimary_key;
                    $contenu .= ', ';

                    // recuperation du libelle
                    $libelle = $this->get_libelle_of($ftable);

                    $contenu .= $ftable.'.'.$libelle;
                    $contenu .= " FROM \".DB_PREFIXE.\"".$this->foreign_tables[$elem]["foreign_table_name"];
                } else {

                    // on ne passe jamais ici
                    $ftable = $elem;
                    $contenu.="\n\$sql_".$elem."=\"SELECT * FROM \".DB_PREFIXE.\"".$elem;
                }

                if ($this->check_om_validite($ftable) == true) {
                    $contenu.=" WHERE ".$this->filter_om_validite($ftable);
                }

                if (isset($this->foreign_tables[$elem])) {
                    $contenu.=" ORDER BY ".$ftable.'.'.$this->get_libelle_of($ftable)." ASC";
                }

                $contenu.="\";";

                // creation de la requete sql_object_by_id
                $fprimary_key = $this->get_primary_key($ftable);
                $flibelle = $this->get_libelle_of($ftable);
                $infos = $this->db->tableInfo(DB_PREFIXE.$ftable);

                $contenu .= "\n";
                $contenu .= "\$sql_".$elem."_by_id = \"";
                $contenu .= "SELECT ".$ftable.'.'.$fprimary_key.", ".$ftable.'.'.$flibelle.' ';
                $contenu .= "FROM \".DB_PREFIXE.\"".$ftable." ";

                if (strtolower(substr($infos[0]['type'], 0, 3)) == 'int') {
                    $id = "<idx>";
                } else {
                    $id = "'<idx>'";
                }

                $contenu .= "WHERE ".$fprimary_key." = ".$id."\";";
            }
            return $contenu;
        }// fin clesecondaire
    }// fin sql_select

    /**
     * Construit le contenu du script [obj/<TABLE>.class.php].
     *
     * Cette méthode permet de générer la définition de la classe qui est
     * définie dans le dossier obj/ et qui étend la classe définit dans le
     * dossier gen/obj/. Cette classe a pour objectif de contenir les
     * surcharges spécifiques aux objets en questions dans l'applicatif.
     *
     * @return string
     */
    function table_obj_class() {
        //
        if ($this->is_omframework_table($this->table)) {
            //
            $template = "%s
require_once \"../core/obj/%s.class.php\";

class %s extends %s_core {

    function %s(\$id, &\$db, \$debug) {
        \$this->constructeur(\$id, \$db, \$debug);
    }

}

?>
";
        } else {
            //
            $template = "%s
require_once \"../gen/obj/%s.class.php\";

class %s extends %s_gen {

    function %s(\$id, &\$db, \$debug) {
        \$this->constructeur(\$id, \$db, \$debug);
    }

}

?>
";
        }
        //
        return sprintf(
            $template,
            $this->entete,
            $this->table,
            $this->table,
            $this->table,
            $this->table
        );

    }

    /**
     * Construit le contenu du script [core/obj/<TABLE>.class.php].
     *
     * Cette méthode permet de générer la définition de la classe qui est
     * définie dans le dossier core/obj/ et qui étend la classe définit dans le
     * dossier gen/obj/. Cette classe a pour objectif de contenir les
     * surcharges spécifiques aux objets en questions dans l'applicatif.
     *
     * @return string
     */
    function table_obj_class_core() {

        //
        if ($this->is_omframework_table($this->table)) {
            //
            $template = "%s
require_once \"../gen/obj/%s.class.php\";

class %s_core extends %s_gen {

}

?>
";
            //
            return sprintf(
                $template,
                $this->entete,
                $this->table,
                $this->table,
                $this->table,
                $this->table
            );
        } else {
            //
            return "";
        }

    }

    /**
     * Construit le contenu du script [gen/obj/<TABLE>.class.php].
     *
     * Cette méthode permet de générer la définition de la classe qui est 
     * définie dans le dossier gen/obj/ et qui étend la classe 
     * obj/om_dbform.class.php. Cette classe a pour objectif de contenir 
     * les méthodes générées à partir du modèle de données.
     *
     * @param $dyn mixed Fichier de paramétrage.
     * @return string 
     */
    function table_obj_class_gen($dyn = null) {
        // creation de table_gen.obj.php : classe generee
        if (file_exists ("../gen/dyn/form.inc.php")){
            include ("../gen/dyn/form.inc.php");
            $this->msg.="<br />"._("Chargement du parametrage")." ../gen/dyn/form.inc.php";
        } elseif (file_exists ("../gen/dyn/form.inc")){
            include ("../gen/dyn/form.inc");
            $this->msg.="<br />"._("Chargement du parametrage")." ../gen/dyn/form.inc";
        }
        $tableobj=$this->entete;
        // PATH_OPENMAIRIE ***
        $tableobj.="\nrequire_once (\"../obj/om_dbform.class.php\");"; //***
        $tableobj.="\n\nclass ".$this->table."_gen extends om_dbform {";
        $tableobj.="\n    var \$table=\"".$this->table."\";";
        $tableobj.="\n    var \$clePrimaire=\"".$this->primary_key."\";";
        $tableobj.="\n    var \$typeCle=\"".$this->typecle."\";";
        // Tableau des contraintes not null
        $s8="        ";
        if (!empty($this->_columns_notnull)) {
            $tableobj.="\n    var \$required_field=array(\n".$s8."\"".implode("\",\n".$s8."\"", $this->_columns_notnull)."\"\n    );";
        }
        // Tableaux des contraintes uniques
        if(!empty($this->unique_key) OR !empty($this->unique_multiple_key)) {
            $tableobj.="\n    var \$unique_key=array(";
            foreach($this->unique_key as $contraint) {
                $tableobj.="\n      \"".$contraint."\",";
            }
            if(!empty($this->unique_multiple_key)) {
                foreach($this->unique_multiple_key as $multiple) {
                    $tableobj.="\n      array(\"".implode("\",\"", $multiple)."\"),";
                }

            }
            $tableobj.="\n    );";
        }
        $tableobj.="\n    var \$retourformulaire;";
        $tableobj.=$this->objvalf();
        if($this->typecle=="N"){ // cle automatique si numerique
            $tableobj.="\n\n    //=================================================";
            $tableobj.="\n    //cle primaire automatique [automatic primary key]";
            $tableobj.="\n    //==================================================";
            $tableobj.=$this->objid();
            $tableobj.=$this->objvalfajout();
            $tableobj.=$this->objverifierajout();
        }

        $tableobj.=$this->objverifier();

        $tableobj.="\n\n    //==========================";
        $tableobj.="\n    // Formulaire  [form]";
        $tableobj.="\n    //==========================";
        $tableobj.=$this->objtype();
        $tableobj.=$this->objonchange();
        $tableobj.=$this->objtaille();
        $tableobj.=$this->objmax();
        $tableobj.=$this->objlib();
        $tableobj.=$this->objselect();
        $tableobj.=$this->objsetgroupe();
        // multi
        if($this->multi==2)
            $tableobj.=$this->objsetval();
        $tableobj.="\n\n    //==================================";
        $tableobj.="\n    // sous Formulaire  [subform]";
        $tableobj.="\n    //==================================";
        $tableobj.=$this->objsetvalsousformulaire();
        $tableobj.="\n\n    //==================================";
        $tableobj.="\n    // cle secondaire  [secondary key]";
        $tableobj.="\n    //==================================";
        $tableobj.=$this->objclesecondaire();
        $tableobj.="\n\n}// fin classe";
        $tableobj.="\n?>";
        return $tableobj;
    }


    // table.obj

    /**
     *
     */
    function objverifier() {
        $content = '';

        // verification pour les objets a date de validite
        if ($this->is_om_validite() == true) {

            // Entete de la methode
            $content .= "\n";
            $content .= "    /**\n     * Methode verifier\n     */\n";
            $content .= "    function verifier(\$val = array(), &\$db = NULL, \$DEBUG = false) {\n";
            $content .= "        // On appelle la methode de la classe parent\n";
            $content .= "        parent::verifier(\$val, \$db, \$DEBUG);\n";

            $s = "        ";
            
           // om_validite_debut < om_validite_fin
            $content .= "\n";
            $content .= $s."// gestion des dates de validites\n";
            $content .= $s."\$date_debut = \$this->valF['om_validite_debut'];\n";
            $content .= $s."\$date_fin = \$this->valF['om_validite_fin'];\n";
            $content .= "\n";
            $content .= $s."if (\$date_debut != '' and \$date_fin != '') {\n";
            $content .= $s."\n";
            $content .= $s."    \$date_debut = explode('-', \$this->valF['om_validite_debut']);\n";
            $content .= $s."    \$date_fin = explode('-', \$this->valF['om_validite_fin']);\n";
            $content .= "\n";
            $content .= $s."    \$time_debut = mktime(0, 0, 0, \$date_debut[1], \$date_debut[2],\n";
            $content .= $s."                         \$date_debut[0]);\n";
            $content .= $s."    \$time_fin = mktime(0, 0, 0, \$date_fin[1], \$date_fin[2],\n";
            $content .= $s."                         \$date_fin[0]);\n";
            $content .= "\n";
            $content .= $s."    if (\$time_debut > \$time_fin or \$time_debut == \$time_fin) {\n";
            $content .= $s."        \$this->correct = false;\n";
            $content .= $s."        \$this->addToMessage(_('La date de fin de validite doit etre future a la de debut de validite.'));\n";
            $content .= $s."    }\n";
            $content .= $s."}\n";

            $content .= "    }\n";
        }
        //
        return $content;
    }

    function objtype(){
        $tableobj="\n\n    function setType(&\$form,\$maj) {";
        $tableobj.="\n        //type";
        // $tableobj.="\nparent::setType(\$form,\$maj);";
        // ajout ============================================================================
        $tableobj.="\n        if (\$maj==0){ //ajout";
        if($this->typecle=="N") // cle masquee si numerique
            $tableobj.="\n            \$form->setType('".$this->primary_key."','hidden');// cle automatique";
        else // cle text si alpha
            $tableobj.="\n            \$form->setType('".$this->primary_key."','text');";
        $tableobj.=$this->objtype_switch(1);
        $tableobj.="\n        }// fin ajout";
        // modifier =========================================================================
        $tableobj.="\n        if (\$maj==1){ //modifier";
        // cle primaire toujours hiddenstatic
        $tableobj.="\n            \$form->setType('".$this->primary_key."','hiddenstatic');"; //cle
        $tableobj.=$this->objtype_switch(2);
        $tableobj.="\n        }// fin modifier";
        // supprimer ========================================================================
        $tableobj.="\n        if (\$maj==2){ //supprimer";

        foreach($this->info as $elem) {

            if ($elem['name'] == 'om_collectivite' && $this->primary_key == "om_collectivite") {
                $tableobj.="\n            \$form->setType('om_collectivite','hiddenstatic');";
                continue;
            } elseif ($elem['name'] == 'om_collectivite' && $this->primary_key != "om_collectivite") {
                $tableobj.="\n            if(\$_SESSION['niveau']==2) {";
                $tableobj.="\n                \$form->setType('om_collectivite','selectstatic');";
                $tableobj.="\n            } else {";
                $tableobj.="\n                \$form->setType('om_collectivite','hidden');";
                $tableobj.="\n            }";
                continue;
            }

            if (in_array($elem['name'], $this->clesecondaire)) {
                $tableobj.="\n            \$form->setType('".$elem['name']."','selectstatic');";
            } else {
                $tableobj.="\n            \$form->setType('".$elem['name']."','hiddenstatic');";
            }
        }

        $tableobj.="\n        }//fin supprimer";
        // consulter ========================================================================
        $tableobj.="\n        if (\$maj==3){ //consulter";
        $tableobj.="\n            \$form->setType('".$this->primary_key."','static');"; //cle
        $tableobj.=$this->objtype_switch(3);
        $tableobj.="\n        }//fin consulter";
        $tableobj.="\n    }";
        return $tableobj;
    }

    /**
     *
     * Methode permettant de definir le widget de formulaire a utiliser 
     * en fonction du type de champ dans la base de donnees
     *
     * @param $maj integer valeur de l'action de formulaire pour laquelle on souhaite definir les widget
     *
     */
    function objtype_switch($maj){
    // switch suivant type utilise pour function setType
        $tableobj="";
        foreach($this->info as $elem){

            // le type de la cle primaire est deja gere par $this->objtype()
            if ($elem['name'] == $this->primary_key) {
                continue;
            }

            switch ($elem['type']) {
                case "date" :

                    $s = "            ";
                    if($maj==3) {
                        $tableobj .= "\n".$s."\$form->setType('".$elem['name']."','datestatic');";
                    } else {
                        if ($elem['name'] == 'om_validite_debut' or
                            $elem['name'] == 'om_validite_fin') {
                            $tableobj .= "\n";
                            $tableobj .= $s."if (\$this->f->isAccredited(array(\$this->table.'_modifier_validite',";
                            $tableobj .= "\n".$s."                                 \$this->table))) {";
                            $s .= "    ";
                        }

                        $tableobj.="\n".$s."if(\$this->retourformulaire=='')";
                        $tableobj.="\n".$s."    \$form->setType('".$elem['name']."','date');";
                        $tableobj.="\n".$s."else";
                        $tableobj.="\n".$s."    \$form->setType('".$elem['name']."','date2');";

                        if ($elem['name'] == 'om_validite_debut' or
                            $elem['name'] == 'om_validite_fin') {
                            $s = "            ";
                            $tableobj .= "\n".$s."} else {";
                            $tableobj .= "\n".$s."    \$form->setType('".$elem['name']."','hiddenstaticdate');";
                            $tableobj .= "\n".$s."}";
                        }
                    }

                    break;
                case "blob" :
                    if($maj!=3) {
                        $tableobj.="\n            \$form->setType('".$elem['name']."','textarea');";
                    }
                    else {
                        $tableobj.="\n            \$form->setType('".$elem['name']."','textareastatic');";
                    }
                    break;
                case "geom" :
                    $tableobj.="\n            \$form->setType('".$elem['name']."','geom');";
                    break;
                case "bool" :
                    if($maj!=3)
                        $tableobj.="\n            \$form->setType('".$elem['name']."','checkbox');";
                    else
                        $tableobj.="\n            \$form->setType('".$elem['name']."','checkboxstatic');";
                    break;
                default :
                    $temp=0;

                    // select
                    if (!empty($this->clesecondaire)) {

                        $ftables = array();
                        foreach ($this->foreign_tables as $key => $infos) {

                            if (!key_exists($infos['foreign_table_name'], $ftables)) {
                                $ftables[$infos['foreign_table_name']] = array($key);
                            } else {
                                if (!in_array($key, $ftables[$infos['foreign_table_name']])) {
                                    array_push($ftables[$infos['foreign_table_name']], $key);
                                }
                            }
                        }

                        $multiple_fkeys = array();
                        foreach ($ftables as $table => $columns) {
                            if (count($columns) > 1) {
                                $multiple_fkeys = array_merge($multiple_fkeys, $columns);
                            }
                        }

                        foreach ($this->clesecondaire as $elem1) {

                            if($elem['name']==$elem1){
                                $temp=1;
                                if($elem['name']=="om_collectivite"){

                                    $tableobj.="\n            if(\$this->retourformulaire=='om_collectivite')";
                                    $tableobj.="\n                if(\$_SESSION['niveau']==2) {";
                                    if($maj==3) {
                                        $tableobj.="\n                    \$form->setType('om_collectivite','selectstatic');";
                                    } else {
                                        $tableobj.="\n                    \$form->setType('om_collectivite','selecthiddenstatic');";
                                    }
                                    $tableobj.="\n                } else {";
                                    if($maj==3) {
                                        $tableobj.="\n                    \$form->setType('om_collectivite','hidden');";
                                    } else {
                                        $tableobj.="\n                    \$form->setType('om_collectivite','hidden');";
                                    }
                                    $tableobj.="\n                }";
                                    $tableobj.="\n            else";
                                    $tableobj.="\n                if(\$_SESSION['niveau']==2)";
                                    if($maj==3) {
                                        $tableobj.="\n                    \$form->setType('om_collectivite','selectstatic');";
                                    } else {
                                        $tableobj.="\n                    \$form->setType('om_collectivite','select');";
                                    }
                                    $tableobj.="\n                else";
                                    $tableobj.="\n                    \$form->setType('om_collectivite','hidden');";
                                }else{
                                    if($maj==3) {
                                        $tableobj.="\n            \$form->setType('".$elem['name']."','selectstatic');";
                                    } else {

                                        $tableobj.="\n\n            if(\$this->retourformulaire=='".$this->foreign_tables[$elem1]['foreign_table_name']."'\n";
                                        $tableobj.= "               and \$form->val['".$elem1."'] == \$this->getParameter('idxformulaire')) {";
                                        $tableobj.="\n                \$form->setType('".$elem['name']."','selecthiddenstatic');";
                                        $tableobj.="\n            } else {";
                                        $tableobj.="\n                \$form->setType('".$elem['name']."','select');";
                                        $tableobj.="\n            }";
                                    }
                                    
                                }
                            }
                       }// foreach
                    } // clesecondaire
                    if($temp==0) {
                        if($maj==3)
                            $tableobj.="\n            \$form->setType('".$elem['name']."','static');";
                        else
                            $tableobj.="\n            \$form->setType('".$elem['name']."','text');";
                    }
            } // switch
        } // $this->info
        return $tableobj;
    }

    /**
     * Cette méthode génère la méthode setValF() de la classe metier
     */
    function objvalf() {
        //
        $content = "";
        // Entête de la methode
        $content .= "\n";
        $content .= "\n    function setvalF(\$val) {";
        $content .= "\n        //affectation valeur formulaire";
        // Boucle sur chaque colonne
        foreach ($this->info as $elem) {

            // Test sur le type de données
            if ($elem['type'] == "date") {

                // Gestion des champs de type DATE

                // Si la valeur renvoyée par le formulaire n'est pas numérique
                $content .= "\n        if (\$val['".$elem['name']."'] != \"\") {";
                // On affecte la valeur renvoyée retraitée par la méthode de
                // retraitement des dates
                $content .= "\n            \$this->valF['".$elem['name']."'] = \$this->dateDB(\$val['".$elem['name']."']);";
                $content .= "\n        }";
    
                 // Test sur l'attribut NULL du champ
                if ($elem['notnull'] == 'f') {
                    
                    // Soit le champ accepte la valeur NULL
                    // On affecte la valeur NULL
                    $content .= " else {";
                    $content .= "\n            \$this->valF['".$elem['name']."'] = NULL;";
                    $content .= "\n        }";
                }

            } elseif ($elem['type'] == "bool") {

                // Gestion des champs de type BOOLaffectation valeur formulaire

                //
                $content .= "\n        if (\$val['".$elem['name']."'] == 1 || \$val['".$elem['name']."'] == \"t\" || \$val['".$elem['name']."'] == \"Oui\") {";
                $content .= "\n            \$this->valF['".$elem['name']."'] = true;";
                $content .= "\n        } else {";
                $content .= "\n            \$this->valF['".$elem['name']."'] = false;";
                $content .= "\n        }";
            
            } elseif ($elem['type'] == "geom") {
                // gestion des champs geom non pris en compte si valeur vide
                $content .= "\n        if (\$val['".$elem['name']."'] == \"\") {";
				$content .= "\n            unset(\$this->valF['".$elem['name']."']);";
                $content .="\n        } else {";
                // On affecte la valeur du formulaire directement
                $content .="\n            \$this->valF['".$elem['name']."'] = \$val['".$elem['name']."'];";
                $content .="\n        }";
            
            } elseif ($elem['type'] == "int" or $elem['type'] == "float") {

                // Gestion des champs de type INT

                // Si la valeur renvoyée par le formulaire n'est pas numérique
                // => ceci n'est pas sensé arriver car une fonction javascript
                //    vérifie que la saisie est composée uniquement de chiffres
                //    mais ce cas inclut aussi la chaine vide ce qui par contre
                //    arrive fréquemment
                $content .="\n        if (!is_numeric(\$val['".$elem['name']."'])) {";
                // Test sur l'attribut NULL du champ
                if ($elem['notnull'] == 'f') {

                    // Soit le champ accepte la valeur NULL
                    // On affecte la valeur NULL
                    $content .="\n            \$this->valF['".$elem['name']."'] = NULL;";

                } elseif ($elem['notnull'] == 't'
                          && in_array($elem["name"], $this->_columns_notnull)) {

                    // Soit le champ n'accepte pas la valeur NULL et fait partie
                    // des champs requis
                    // On affecte la valeur ""
                    // => sous entendu le champ n'accepte pas la valeur NULL
                    //    donc il est obligatoire donc la méthode vérifier
                    //    des champs requis empêchera le passage de la valeur à
                    //    la base
                    $content .="\n            \$this->valF['".$elem['name']."'] = \"\"; // -> requis";

                } else {
                    
                    // Le cas restant est : le champ n'accepte pas la valeur
                    // NULL et a une valeur par défaut dans la base
                    //
                    // XXX ici il faut affecter la valeur du default de la base
                    //
                    // On affecte la valeur 0
                    $content .="\n            \$this->valF['".$elem['name']."'] = 0; // -> default";
                    
                }
                // Sinon si la valeur renvoyée par le formulaire est numérique
                $content .="\n        } else {";
                // Test si on se trouve sur le champ 'om_collectivite'
                if ($elem['name'] == "om_collectivite") {

                    // Champ 'om_collectivite'
                    // => sous entendu ce champ est forcément de type INT

                    // Si on est en mode MONO
                    $content .="\n            if(\$_SESSION['niveau']==1) {";
                    // On affecte la valeur de la collectivité depuis la
                    // variable de SESSION
                    $content .="\n                \$this->valF['".$elem['name']."'] = \$_SESSION['collectivite'];";
                    // Si on est en mode MULTI
                    $content .="\n            } else {";
                    // On affecte la valeur du formulaire directement
                    $content .="\n                \$this->valF['".$elem['name']."'] = \$val['".$elem['name']."'];";
                    $content .="\n            }";

                } else {

                    // Un autre champ que 'om_collectivite'

                    // On affecte la valeur du formulaire directement
                    $content .="\n            \$this->valF['".$elem['name']."'] = \$val['".$elem['name']."'];";

                }
                //
                $content .="\n        }";

            } elseif ($elem['type'] == "string") {

                // Gestion des champs de type STRING

                // Test sur l'attribut NULL du champ
                if ($elem['notnull'] == 'f') {

                    // Si la valeur renvoyée par le formulaire est une chaine vide
                    $content .="\n        if (\$val['".$elem['name']."'] == \"\") {";
                    // Soit le champ accepte la valeur NULL
                    // On affecte la valeur NULL
                    $content .="\n            \$this->valF['".$elem['name']."'] = NULL;";
                    //
                    $content .="\n        } else {";
                    // On affecte la valeur du formulaire directement
                    $content .="\n            \$this->valF['".$elem['name']."'] = \$val['".$elem['name']."'];";
                    //
                    $content .="\n        }";
                } elseif ($elem['notnull'] == 't'
                          && in_array($elem["name"], $this->_columns_notnull)) {

                    // Soit le champ n'accepte pas la valeur NULL et fait partie
                    // des champs requis
                    // On affecte la valeur ""
                    // => sous entendu le champ n'accepte pas la valeur NULL
                    //    donc il est obligatoire donc la méthode vérifier
                    //    des champs requis empêchera le passage de la valeur à
                    //    la base
                    $content .="\n        \$this->valF['".$elem['name']."'] = \$val['".$elem['name']."'];";

                } else {

                    // Si la valeur renvoyée par le formulaire est une chaine vide
                    $content .="\n        if (\$val['".$elem['name']."'] == \"\") {";
                    // Le cas restant est : le champ n'accepte pas la valeur
                    // NULL et a une valeur par défaut dans la base
                    //
                    // XXX ici il faut affecter la valeur du default de la base
                    //
                    // On affecte la valeur ""
                    $content .="\n            \$this->valF['".$elem['name']."'] = \"\"; // -> default";
                    //
                    $content .="\n        } else {";
                    // On affecte la valeur du formulaire directement
                    $content .="\n            \$this->valF['".$elem['name']."'] = \$val['".$elem['name']."'];";
                    //
                    $content .="\n        }";

                }
            } else {

                // On affecte la valeur du formulaire directement
                $content .="\n            \$this->valF['".$elem['name']."'] = \$val['".$elem['name']."'];";

            }
        }
        // Pied de la methode
        $content .="\n    }";
        //
        return $content;
    }

    function objonchange(){
        //
        $counter = 0;
        //
        $tableobj = "\n\n    function setOnchange(&\$form,\$maj) {";
        $tableobj .= "\n    //javascript controle client";
        //
        foreach ($this->info as $elem) {
            //
            if ($elem['type'] == 'date') {
                //
                $counter++;
                //
                $tableobj.="\n        \$form->setOnchange('".$elem['name']."','fdate(this)');";
            } elseif($elem['type'] == 'int') {
                //
                $counter++;
                //
                $tableobj.="\n        \$form->setOnchange('".$elem['name']."','VerifNum(this)');";
            } elseif($elem['type'] == 'float') {
                //
                $counter++;
                //
                $tableobj.="\n        \$form->setOnchange('".$elem['name']."','VerifFloat(this)');";
            }
        }
        //
        $tableobj.="\n    }";
        // Si aucun élément n'est affiché alors inutile de générer la méthode
        if ($counter == 0) {
            //
            $tableobj = "";
        }
        // On renvoi le contenu de la méthode à générer
        return $tableobj;
    }

    /**
     * 
     */
    function objtaille() {
        //
        $content = "";
        // Entete de la methode
        $content .= "\n";
        $content .= "    /**\n     * Methode setTaille\n     */\n";
        $content .= "    function setTaille(&\$form, \$maj) {\n";
        //
        foreach ($this->info as $elem) {
            //
            $content .="        \$form->setTaille(\"".$elem['name']."\", ".(isset($elem['taille_affichage']) ? $elem['taille_affichage'] : $elem['len']).");\n";
        }
        // Pied de la methode
        $content .="    }\n";
        //
        return $content;
    }

    /**
     *
     */
    function objmax() {
        //
        $content = "";
        // Entete de la methode
        $content .= "\n";
        $content .= "    /**\n     * Methode setMax\n     */\n";
        $content .= "    function setMax(&\$form, \$maj) {\n";
        //
        foreach ($this->info as $elem) {
            //
            $content .= "        \$form->setMax(\"".$elem['name']."\", ".(isset($elem['max_saisie']) ? $elem['max_saisie'] : $elem['len']).");\n";
        }
        // Pied de la methode
        $content .="    }\n";
        //
        return $content;
    }

    function objlib(){
        $tableobj="\n\n    function setLib(&\$form,\$maj) {";
        $tableobj.="\n    //libelle des champs";

        foreach($this->info as $elem){

            $tableobj.="\n        \$form->setLib('".$elem['name']."',_('".$elem['name']."')";

            $tableobj.=');';
        }

        $tableobj.="\n    }";
        return $tableobj;
    }


    function objselect() {

        $contenu = '';
        // initialisation des <select> pour chaque cles secondaires
		// AB_C02 D Génération problème affichage dans form du bouton des champs geom
		$contenu .= "\n\n    function setSelect(&\$form, \$maj,&\$db,\$debug) {";
		$contenu .= "\n        if(file_exists (\"../sql/\".\$db->phptype.\"/\".\$this->table.\".form.inc.php\"))";
		$contenu .= "\n            include (\"../sql/\".\$db->phptype.\"/\".\$this->table.\".form.inc.php\");";
		$contenu .= "\n        elseif(file_exists (\"../sql/\".\$db->phptype.\"/\".\$this->table.\".form.inc\"))";
		$contenu .= "\n            include (\"../sql/\".\$db->phptype.\"/\".\$this->table.\".form.inc\");";
		// AB_C02 F Génération problème affichage dans form du bouton des champs geom
        if(!empty($this->clesecondaire)) {
			// AB_C02 D Génération problème affichage dans form du bouton des champs geom
			/*
            $contenu .= "\n\n    function setSelect(&\$form, \$maj,&\$db,\$debug) {";
            $contenu .= "\n        if(file_exists (\"../sql/\".\$db->phptype.\"/\".\$this->table.\".form.inc.php\"))";
            $contenu .= "\n            include (\"../sql/\".\$db->phptype.\"/\".\$this->table.\".form.inc.php\");";
            $contenu .= "\n        elseif(file_exists (\"../sql/\".\$db->phptype.\"/\".\$this->table.\".form.inc\"))";
            $contenu .= "\n            include (\"../sql/\".\$db->phptype.\"/\".\$this->table.\".form.inc\");";
			*/
			// AB_C02 F Génération problème affichage dans form du bouton des champs geom
            foreach($this->clesecondaire as $elem) {
                $contenu.= "\n\n        // ".$elem;

                if (isset($this->foreign_tables[$elem])) {
                    $ftable = $this->foreign_tables[$elem]['foreign_table_name'];
                } else {
                    $ftable = $elem;
                }

                if ($this->check_om_validite($ftable) == true) {
                    $contenu .= "\n        \$this->init_select(\$form, \$db, \$maj, \$debug, \"".$elem."\",";
                    $contenu .= "\n                           \$sql_".$elem.", \$sql_".$elem."_by_id, true);";
                } else {
                    $contenu .= "\n        \$this->init_select(\$form, \$db, \$maj, \$debug, \"".$elem."\",";
                    $contenu .= "\n                           \$sql_".$elem.", \$sql_".$elem."_by_id, false);";
                }
            }
		// AB_C02 D Génération problème affichage dans form du bouton des champs geom
		}
		if(!empty($this->geom)){
			//appel pour multigéométrie
			$nbgeom=0;
			foreach ($this->geom as $elem) {
				$contenu .= "\n            // ".$elem;
				$contenu .= "\n            if(\$maj==1 || \$maj==3){ //modification ou visualisation";
				$contenu .= "\n                \$contenu=array();";
				$contenu .= "\n                \$contenu[0]=array(\"".$this->table."\",\$this->getParameter(\"idx\"),\"".$nbgeom."\");";
				$contenu .= "\n                \$form->setSelect('".$elem."',\$contenu);";
				$contenu .= "\n            }";
				$nbgeom=$nbgeom+1;
			}
		}

		$contenu.="\n    }// fin select";
        //}
		// AB_C02 F Génération problème affichage dans form du bouton des champs geom

        return $contenu;
    }

    function objsetval(){
        // si $this->multi = 2
        // valorisation de la variable $this->retourformulaire
        // valorisation champ cle formulaire en creation et modification
        $contenu="\n\n    function setVal(&\$form,\$maj,\$validation,&\$db,\$DEBUG=null){";
        $contenu.="\n        if(\$validation==0 and \$maj==0 and \$_SESSION['niveau']==1) {";
        $contenu.="\n            \$form->setVal('om_collectivite', \$_SESSION['collectivite']);";
        $contenu.="\n        }// fin validation";
        $contenu.="\n    }// fin setVal";
        return $contenu;
    }


    function objsetvalsousformulaire(){
        // si cle secondaire
        // valorisation de la variable $this->retourformulaire
        // valorisation champ cle formulaire en creation et modification
        $contenu="\n\n    function setValsousformulaire(&\$form,\$maj,\$validation,\$idxformulaire,\$retourformulaire,\$typeformulaire,&\$db,\$DEBUG=null){";
        $contenu.="\n        \$this->retourformulaire = \$retourformulaire;";
        //
        if ($this->multi == 2 && $this->table != "om_collectivite") {
            //
            $contenu.="\n        if(\$validation==0 and \$maj==0 and \$_SESSION['niveau']==1) {";
            $contenu.="\n            \$form->setVal('om_collectivite', \$_SESSION['collectivite']);";
            $contenu.="\n        }// fin validation";
        }
        // clesecondaire
        if (!empty($this->clesecondaire)) {
            $contenu_tmp = "\n        if(\$validation == 0) {";

            $ftables = array();
            foreach ($this->foreign_tables as $key => $infos) {

                if (!key_exists($infos['foreign_table_name'], $ftables)) {
                    $ftables[$infos['foreign_table_name']] = array($key);
                } else {
                    if (!in_array($key, $ftables[$infos['foreign_table_name']])) {
                        array_push($ftables[$infos['foreign_table_name']], $key);
                    }
                }
            }

            $multiple_fkeys = array();
            foreach ($ftables as $table => $columns) {
                if (count($columns) > 1) {
                    $multiple_fkeys = array_merge($multiple_fkeys, $columns);
                }
            }

            $code_exists = false;

            foreach ($this->clesecondaire as $elem){
                if (!in_array($elem, $multiple_fkeys)) {
                    $code_exists = true;
                    $contenu_tmp .= "\n            if(\$retourformulaire =='".$this->foreign_tables[$elem]['foreign_table_name']."')";
                    $contenu_tmp .= "\n                \$form->setVal('".$elem."', \$idxformulaire);";
                }
            }
            $contenu_tmp .= "\n        }// fin validation";

            if ($code_exists == true) {
                $contenu .= $contenu_tmp;
            }

            $code_exists = false;
            $contenu_tmp = "\n        if (\$validation == 0 and \$maj == 0) {";

            $ftables = array();
            foreach ($this->foreign_tables as $key => $infos) {

                if (!key_exists($infos['foreign_table_name'], $ftables)) {
                    $ftables[$infos['foreign_table_name']] = array($key);
                } else {
                    if (!in_array($key, $ftables[$infos['foreign_table_name']])) {
                        array_push($ftables[$infos['foreign_table_name']], $key);
                    }
                }
            }

            $multiple_fkeys = array();
            foreach ($ftables as $table => $columns) {
                if (count($columns) > 1) {
                    $multiple_fkeys = array_merge($multiple_fkeys, $columns);
                }
            }

            foreach ($this->clesecondaire as $elem){
                if (in_array($elem, $multiple_fkeys)) {
                    $code_exists = true;
                    $contenu_tmp .= "\n            if(\$retourformulaire =='".$this->foreign_tables[$elem]['foreign_table_name']."')";
                    $contenu_tmp .= "\n                \$form->setVal('".$elem."', \$idxformulaire);";
                }
            }
            $contenu_tmp .= "\n        }// fin validation";

            if ($code_exists == true) {
                $contenu .= $contenu_tmp;
            }

        } // fin clescondaire
        $contenu.="\n    }// fin setValsousformulaire";
        return $contenu;
        }

    /**
     *
     */
    function objclesecondaire() {
        //
        $content = "";
        // Si il existe des sous-formulaires on surcharge la methode sinon
        // on ne fait rien
        if (!empty($this->sousformulaires)) {
            // Entete de la methode
            $content .= "\n";
            $content .= "    /**\n     * Methode clesecondaire\n     */\n";
            $content .= "    function cleSecondaire(\$id, &\$db = NULL, \$val = array(), \$DEBUG = false) {\n";
            $content .= "        // On appelle la methode de la classe parent\n";
            $content .= "        parent::cleSecondaire(\$id, \$db, \$val, \$DEBUG);\n";

            // boucle sur chaque sous-formulaire
            foreach ($this->other_tables as $config) {

                // $config est de la forme "nom_table.nom_colonne"
                $infos = array();
                $infos =  explode('.', $config);

                // table  -> table ayant une reference vers la table actuelle
                // column -> colonne de cette table faisant reference
                $table = $infos[0];
                $column = $infos[1];

                $content .= "        // Verification de la cle secondaire : ".$table."\n"; 
                $content .= "        \$this->rechercheTable(\$db, \"".$table."\", \"".$column."\", \$id);\n";
            }

            // Pied de la methode
            $content .="    }\n";
        }
        //
        return $content;
    }

    // gen cle automatique

    function objid(){
        $tableobj="\n\n    function setId(&\$db) {";
        $tableobj.="\n    //numero automatique";
        $tableobj.="\n        \$this->valF[\$this->clePrimaire] = \$db->nextId(DB_PREFIXE.\$this->table);";
        $tableobj.="\n    }";
        return $tableobj;
    }

    function objvalfajout(){
        $tableobj="\n\n    function setValFAjout(\$val) {";
        $tableobj.="\n    //numero automatique -> pas de controle ajout cle primaire";
        $tableobj.="\n    }";
        return $tableobj;
    }

    function objverifierajout(){
        $tableobj="\n\n    function verifierAjout() {";
        $tableobj.="\n    //numero automatique -> pas de verfication de cle primaire";
        $tableobj.="\n    }";
        return $tableobj;
    }

    function objsetgroupe() {
        //
        return "";
    }

    function pdf($dyn = null){
        // pdf liste de fichier ancienne version openmairie 1.00
        // les blob (mysql)ne sont pas pris en compte dans le tableau
        // les dates sont au format français
        $temp= $this->entete;
        // parametrage pdf standard
        $longueurtableau= 280;
        $orientation='L';// orientation P-> portrait L->paysage";
        $format='A4';// format A3 A4 A5;
        $police='arial';
        $margeleft=10;// marge gauche;
        $margetop=5;// marge haut;
        $margeright=5;//  marge droite;
        $border=1; // 1 ->  bordure 0 -> pas de bordure";
        $C1=0;// couleur texte  R";
        $C2=0;// couleur texte  V";
        $C3=0;// couleur texte  B";
        $size=10; //taille POLICE";
        $height=4.6; // hauteur ligne tableau ";
        $align='L';
        // fond 2 couleurs
        $fond=1;// 0- > FOND transparent 1 -> fond";
        $C1fond1=234;// couleur fond  R ";
        $C2fond1=240;// couleur fond  V ";
        $C3fond1=245;// couleur fond  B ";
        $C1fond2=255;// couleur fond  R";
        $C2fond2=255;// couleur fond  V";
        $C3fond2=255;// couleur fond  B";
        // spe openelec
        $flagsessionliste=0;// 1 - > affichage session liste ou 0 -> pas d'affichage";
        // titre
        $bordertitre=0; // 1 ->  bordure 0 -> pas de bordure";
        $aligntitre='L'; // L,C,R";
        $heightitre=10;// hauteur ligne titre";
        $grastitre='B';//\$gras='B' -> BOLD OU \$gras=''";
        $fondtitre=0; //0- > FOND transparent 1 -> fond";
        $C1titrefond=181;// couleur fond  R";
        $C2titrefond=182;// couleur fond  V";
        $C3titrefond=188;// couleur fond  B";
        $C1titre=75;// couleur texte  R";
        $C2titre=79;// couleur texte  V";
        $C3titre=81;// couleur texte  B";
        $sizetitre=15;
        // entete colonne
        $flag_entete=1;//entete colonne : 0 -> non affichage , 1 -> affichage";
        $fondentete=1;// 0- > FOND transparent 1 -> fond";
        $heightentete=10;//hauteur ligne entete colonne";
        $C1fondentete=210;// couleur fond  R";
        $C2fondentete=216;// couleur fond  V";
        $C3fondentete=249;// couleur fond  B";
        $C1entetetxt=0;// couleur texte R";
        $C2entetetxt=0;// couleur texte V";
        $C3entetetxt=0;// couleur texte B";
        $C1border=159;// couleur texte  R";
        $C2border=160;// couleur texte  V";
        $C3border=167;// couleur texte  B";
        $bt=1;// border 1ere  et derniere ligne  du tableau par page->0 ou 1";
        if (file_exists ("../gen/dyn/pdf.inc.php")){
           include ("../gen/dyn/pdf.inc.php");
           $this->msg.="<br />"._("Chargement du parametrage")." ../gen/dyn/pdf.inc.php";
        } elseif (file_exists ("../gen/dyn/pdf.inc")){
           include ("../gen/dyn/pdf.inc");
           $this->msg.="<br />"._("Chargement du parametrage")." ../gen/dyn/pdf.inc";
        }
        $temp.="\n\$DEBUG=0;";
        // param sousetat.inc.php
        $temp.="\n\$orientation='".$orientation."';// orientation P-> portrait L->paysage";
        $temp.="\n\$format='".$format."';// format A3 A4 A5";
        $temp.="\n\$police='".$police."';";
        $temp.="\n\$margeleft=".$margeleft.";// marge gauche";
        $temp.="\n\$margetop=".$margetop.";// marge haut";
        $temp.="\n\$margeright=".$margeright.";//  marge droite";
        $temp.="\n\$border=".$border."; // 1 ->  bordure 0 -> pas de bordure";
        $temp.="\n\$C1=".$C1.";// couleur texte  R";
        $temp.="\n\$C2=".$C2.";// couleur texte  V";
        $temp.="\n\$C3=".$C3.";// couleur texte  B";
        $temp.="\n\$size=".$size."; //taille POLICE";
        $height=intval($height); // bug si virgule 4,6
        $temp.="\n\$height=".$height."; // hauteur ligne tableau ";
        $temp.="\n\$align='".$align."';";
        $temp.="\n\$fond=".$fond.";// 0- > FOND transparent 1 -> fond";
        $temp.="\n\$C1fond1=".$C1fond1.";// couleur fond  R 241";
        $temp.="\n\$C2fond1=".$C2fond1.";// couleur fond  V 241";
        $temp.="\n\$C3fond1=".$C3fond1.";// couleur fond  B 241";
        $temp.="\n\$C1fond2=".$C1fond2.";// couleur fond  R";
        $temp.="\n\$C2fond2=".$C2fond2.";// couleur fond  V";
        $temp.="\n\$C3fond2=".$C3fond2.";// couleur fond  B";
        $temp.="\n\$libtitre='Liste ".DB_PREFIXE.$this->table."'; // libelle titre";
        $temp.="\n\$flagsessionliste=".$flagsessionliste.";// 1 - > affichage session liste ou 0 -> pas d'affichage";
        $temp.="\n\$bordertitre=".$bordertitre."; // 1 ->  bordure 0 -> pas de bordure";
        $temp.="\n\$aligntitre='".$aligntitre."'; // L,C,R";
        $temp.="\n\$heightitre=".$heightitre.";// hauteur ligne titre";
        $temp.="\n\$grastitre='".$grastitre."';//\$gras='B' -> BOLD OU \$gras=''";
        $temp.="\n\$fondtitre=".$fondtitre."; //0- > FOND transparent 1 -> fond";
        $temp.="\n\$C1titrefond=".$C1titrefond.";// couleur fond  R";
        $temp.="\n\$C2titrefond=".$C2titrefond.";// couleur fond  V";
        $temp.="\n\$C3titrefond=".$C3titrefond.";// couleur fond  B";
        $temp.="\n\$C1titre=".$C1titre.";// couleur texte  R";
        $temp.="\n\$C2titre=".$C2titre.";// couleur texte  V";
        $temp.="\n\$C3titre=".$C3titre.";// couleur texte  B";
        $temp.="\n\$sizetitre=".$sizetitre.";";
        $temp.="\n\$flag_entete=".$flag_entete.";//entete colonne : 0 -> non affichage , 1 -> affichage";
        $temp.="\n\$fondentete=".$fondentete.";// 0- > FOND transparent 1 -> fond";
        $temp.="\n\$heightentete=".$heightentete.";//hauteur ligne entete colonne";
        $temp.="\n\$C1fondentete=".$C1fondentete.";// couleur fond  R";
        $temp.="\n\$C2fondentete=".$C2fondentete.";// couleur fond  V";
        $temp.="\n\$C3fondentete=".$C3fondentete.";// couleur fond  B";
        $temp.="\n\$C1entetetxt=".$C1entetetxt.";// couleur texte R";
        $temp.="\n\$C2entetetxt=".$C2entetetxt.";// couleur texte V";
        $temp.="\n\$C3entetetxt=".$C3entetetxt.";// couleur texte B";
        $temp.="\n\$C1border=".$C1border.";// couleur texte  R";
        $temp.="\n\$C2border=".$C2border.";// couleur texte  V";
        $temp.="\n\$C3border=".$C3border.";// couleur texte  B";
        // calcul de la taille des colones
        $i=0;
        $j=0;
        $longueur=0; // ***
        $temp1=$longueurtableau;
        $temp3="";
        //$indice=2.5; // indice taille affichage
        $indice =$longueurtableau/$this->longueur;
        $limite =$longueurtableau/2.5;
        $troplong=0;
        $dernierchamp=0;
        if($indice<2.5){
            $this->msg.="<br />->affichage colone incomplet ".$indice."  < 2.5 ";
            foreach($this->info as $elem){
                if($troplong==0){     // ***
                    if($elem['type']!="blob"){
                        $longueur = $longueur + $elem['len'];
                        //$this->msg.="<br>->".$elem['name'].' longueur '.$longueur." ***".$troplong;
                        $dernierchamp++;
                    }
                    //*** A TESTER Longueur de champ
                    if($longueur>=$limite){
                        $troplong=1;
                        $longueur=    $longueur - $elem['len'];
                    }
                }//***
            }
            $dernierchamp=$dernierchamp-2;
            //$this->msg.="<br>->".$dernierchamp.' longueur '.$limite;
            $indice=$longueurtableau/$longueur;
        } else {
            $this->msg.="<br />->affichage colone ok ".$indice." >= 2.5";
            $dernierchamp=sizeof($this->info)-1;
            if($this->info[$dernierchamp]['type']=="blob")//mysql
                $dernierchamp=$dernierchamp-1;
        }
        $seulpassage=0;
        foreach($this->info as $elem){
          if($elem['type']!="blob"){
            if($j<$dernierchamp){
               $temp2= $elem['len']*intval($indice);
               $temp.="\n\$l".$i."=".$temp2."; // largeur colone -> champs ".$i." - ".$elem['name'];
               $temp.="\n\$be".$i."='L';// border entete colone";
               $temp.="\n\$b".$i."='L';// border cellule colone";
               $temp.="\n\$ae".$i."='C'; // align cellule entete colone";
               $temp.="\n\$a".$i."='L';";
               $temp1 = $temp1-$temp2;
               $temp4 = "champaffichedatepdf".$this->sgbd;// fonction date
               if($elem["type"]=="date")
                    $temp3.= $this->$temp4($elem["name"]).",";
               else
                   $temp3.=$elem['name'].", ";
            }else{
             if($seulpassage==0){
               $temp.="\n\$l".$i."=".$temp1."; // largeur colone -> champs".$i." - ".$elem['name'];
               $temp.="\n\$be".$i."='LR';// border entete colone";
               $temp.="\n\$b".$i."='LR';// border cellule colone";
               $temp.="\n\$ae".$i."='C'; // align cellule entete colone";
               $temp.="\n\$a".$i."='L';";
                   $temp4 = "champaffichedatepdf".$this->sgbd;// fonction date
               if($elem["type"]=="date")
                    $temp3.= $this->$temp4($elem["name"]);
               else
                    $temp3.=$elem['name'];
               $seulpassage=1;
              }
            }
            $i++; // compteur champ dans pdf
          }
          $j++; // compteur champ dans tableinfo
        }
        $temp.="\n\$widthtableau=".$longueurtableau.";";
        $temp.="\n\$bt=".$bt.";// border 1ere  et derniere ligne  du tableau par page->0 ou 1";
        $temp.="\n\$sql=\"select ".$temp3." from \".DB_PREFIXE.\"".$this->table."\";";
        $temp.="\n?>";
        return $temp;
    }

    // reqmo
    function reqmo($cle = ""){
        // cle = cle secondaire -> select
        $contenu=$this->entete;
        $contenu.="\n\$reqmo['libelle']=_('reqmo-libelle-".$this->table."');";
        $contenu.="\n\$reqmo['reqmo_libelle']=_('reqmo-libelle-".$this->table."');";
        if ($cle == ""){
            $contenu .= "\n\$ent=_('".$this->table."');";
        } else {
            $contenu .= "\n\$ent=_('".$this->table.'_'.$cle."');";
        }
        // sql
        $temp = "select ";
        $temp1="";
        $temp2="array(";
        $temp3="";
        foreach($this->info as $elem){
            if($cle==""){
                $temp.=" [".$elem['name']."],";
                $temp1.= "\n\$reqmo['".$elem['name']."']='checked';";
                $temp2.="'".$elem['name']."',";
            }elseif($cle==$elem['name']){
                    $temp1.= "\n\$reqmo['".$elem['name']."']=\"select * from \".DB_PREFIXE.\"".$elem['name']."\";";
            }else{
                    $temp.=" [".$elem['name']."],";//sql
                    $temp1.= "\n\$reqmo['".$elem['name']."']='checked';";
                    $temp2.="'".$elem['name']."',";        // tri
            }
        }
        $temp =  substr($temp,0,strlen($temp)-1);
        if($cle!="")
            $temp3 = "where ".$cle." = '[".$cle."]'"; // sql
        $contenu.="\n\$reqmo['sql']=\"".$temp." from \".DB_PREFIXE.\"".$this->table." ".$temp3." order by [tri]\";";
        $temp2 =  substr($temp2,0,strlen($temp2)-1);
        $contenu.="".$temp1;
        $contenu.="\n\$reqmo['tri']=".$temp2.");";
        $contenu.="\n?>";
        return $contenu;
    }


    function import() {
        // creer un fichier d import
        $i=0;
        $contenu=$this->entete;
        $contenu.="\n\$import= \"Insertion dans la table ".$this->table." voir rec/import_utilisateur.inc\";";
        $contenu.="\n\$table= DB_PREFIXE.\"".$this->table."\";";
        if($this->typecle=="N")
            $contenu.="\n\$id='".$this->primary_key."'; // numerotation automatique";
        else
            $contenu.="\n\$id=''; // numerotation non automatique";
        $contenu.="\n\$verrou=1;// =0 pas de mise a jour de la base / =1 mise a jour";
        $contenu.="\n\$DEBUG=0; // =0 pas d affichage messages / =1 affichage detail enregistrement";
        $contenu.="\n\$fic_erreur=1; // =0 pas de fichier d erreur / =1  fichier erreur";
        $contenu.="\n\$fic_rejet=1; // =0 pas de fichier pour relance / =1 fichier relance traitement";
        $contenu.="\n\$ligne1=1;// = 1 : 1ere ligne contient nom des champs / o sinon";
        $contenu.="\n\$obligatoire['".$this->table."']=1;// obligatoire = 1";
        if(!empty($this->clesecondaire)){
            foreach($this->clesecondaire as $elem){
                $contenu.="\n//* cle secondaire=".$elem;
                $contenu.="\n\$exist['".$elem."']=1;//  0=non / 1=oui";
                $contenu.="\n\$sql_exist['".$elem."']= \"select * from \".DB_PREFIXE.\"".$elem." where ".$elem." = '\";";
            }
        }
        foreach($this->info as $elem){
            $contenu.="\n// * champ = ".$elem['name'];
            $contenu.="\n\$zone['".$elem['name']."']='".$i."';";
            $contenu.="\n// \$defaut['".$elem['name']."']='***'; // *** par defaut si non renseigne";
            $i++;
        }
        $contenu.="\n?>";
        return $contenu;
        }

    // {{{ Gestion des messages de debug

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

    /**
     * Retourne en vert si le fichier existe, sinon une erreur en rouge
     *
     * @param string filePath
     */
    function returnFSRightOnFile($filePath) {
        $pathArray=explode("/", $filePath);
        $fileName = array_pop($pathArray);
        $folderPath=implode("/", $pathArray);
        $msg="";
        if (file_exists($filePath)) {
            $msg .= " <span class=\"text-green\">[ "._("Le fichier existe")." ]</span> ";
            if (!is_writable($filePath)) {
                $msg .= " <span class=\"text-red\">[ "._("Pas les droits d'ecriture sur le fichier")." ]</span> ";
            }
        } else {
            //
            if(!file_exists($folderPath)) {
                $msg .= " <span class=\"text-red\">[ "._("Le dossier n'existe pas ou n'est pas accessible")." ]</span> ";
            } elseif(!is_writable($folderPath)) {
                $msg .= " <span class=\"text-red\">[ "._("Le fichier n'existe pas ou n'est pas accessible")." ]</span> ";
                $msg .= " <span class=\"text-red\">[ "._("Pas les droits d'ecriture sur le dossier")." ]</span> ";
            } else {
                $msg .= " <span class=\"text-red\">[ "._("Le fichier n'existe pas ou n'est pas accessible")." ]</span> ";
            }
        }
        
        return $msg;
    }
    // }}}

    // {{{ Methodes - Objets a date de validite

    /**
     * Retourne true si la table traitee actuellement contient les colonnes:
     *      - om_validite_debut
     *      - om_validite_fin
     *
     * Cette methode ne fait aucune requete en base de donnees.
     * Elle se contente de lire les informations analysees par la methode gen().
     *
     * Voir aussi check_om_validite()
     *
     * @return boolean
     */
    function is_om_validite() {
        if ($this->_om_validite_debut == true
            and $this->_om_validite_fin == true) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * Retourne true si la table specifiee contient les colonnes:
     *      - om_validite_debut
     *      - om_validite_fin
     *
     * Cette methode effectue une requete en base de donnees.
     * Utilisez cette methode si la table actuelle != table specifiee.
     *
     * Voir aussi is_om_validite()
     *
     * @return boolean
     */
    function check_om_validite($table) {

        $infos = $this->db->tableInfo(DB_PREFIXE.$table);

        $om_validite_debut = false;
        $om_validite_fin = false;

        foreach ($infos as $column) {

            if ($column['name'] == 'om_validite_debut') {
                $om_validite_debut = true;
            } else if ($column['name'] == 'om_validite_fin') {
                $om_validite_fin = true;
            }
        }

        return $om_validite_debut and $om_validite_fin;
    }

    /**
     * Retourne la condition SQL des objets a date de validite.
     *
     * @return string
     */
    function filter_om_validite($table, $with_operator = false) {

        if ($with_operator == true) {
            $filtre = ' AND ';
        } else {
            $filtre = '';
        }
    
        $filtre .= '(('.$table.'.om_validite_debut IS NULL AND ';
        $filtre .= '('.$table.'.om_validite_fin IS NULL OR '.$table.'.om_validite_fin > CURRENT_DATE))';
        $filtre .= ' OR ';
        $filtre .= '('.$table.'.om_validite_debut <= CURRENT_DATE AND ';
        $filtre .= '('.$table.'.om_validite_fin IS NULL OR '.$table.'.om_validite_fin > CURRENT_DATE)))';
        return $filtre;
    }

    // }}}

    // {{{ Methodes - Initialisation

    /**
     * Cette méthode permet d'initialiser les deux attributs :
     *  - $this->clesecondaire
     *  - $this->foreign_tables
     *
     * Ces deux attributs permettent de gérer la notion de FOREIGN KEY de la
     * table en cours vers les autres tables de la base.
     */
    protected function _init_foreign_tables() {

        //
        $mode = $this->get_general_option("key_constraints_mode");

        //
        if ($mode == "constraints") {

            // MODE 1 - Recherche de FOREIGN KEY en interrogeant les contraintes
            // de la base de données par 'information_schema' 

            //
            $method = "_init_foreign_tables_information_schema_for_".OM_DB_PHPTYPE;
            if (method_exists($this, $method)) {
                $this->$method();
            }

        } elseif ($mode == "postulate") {

            // MODE 2 - Recherche de FOREIGN KEY par le postulat : "le nom d'un
            // champ 'clé étrangère' a pour nom le nom de la table vers laquelle 
            // elle fait référence, et fait référence au champ clé primaire de
            // cette table."

            // Boucle sur chaque champ de la table
            foreach ($this->info as $elem) {
                // Boucle sur chaque table de la base
                foreach ($this->tablebase as $elem1) {
                    // Si le nom de la colonne est identique au nom de la table
                    // et qu'il n'est pas déjà présent dans la liste alors on
                    // l'ajoute
                    if ($elem['name'] == $elem1
                        && !in_array($elem['name'], $this->clesecondaire)) {
                        //
                        array_push($this->clesecondaire, $elem1);
                        //
                        $this->foreign_tables[$elem1] = array(
                            'column_name' => $elem1,
                            'foreign_table_name' => $elem1,
                            'foreign_column_name' =>
                                $this->get_primary_key($elem1)
                        );
                    }
                }
            }

        }

        //
        sort($this->clesecondaire);
        //
        ksort($this->foreign_tables);

    }

    /**
     * Cette méthode permet d'initialiser les deux attributs :
     *  - $this->sousformulaires
     *  - $this->other_tables
     *
     * Ces deux attributs permettent de gérer la notion de FOREIGN KEY des
     * autres tables de la base vers la table en cours.
     */
    protected function _init_other_tables() {

        //
        $mode = $this->get_general_option("key_constraints_mode");

        //
        if ($mode == "constraints") {

            // MODE 1 - Recherche de FOREIGN KEY en interrogeant les contraintes
            // de la base de données par 'information_schema' 

            //
            $method = "_init_other_tables_information_schema_for_".OM_DB_PHPTYPE;
            if (method_exists($this, $method)) {
                $this->$method();
            }

        } elseif ($mode == "postulate") {

            // MODE 2 - Recherche de FOREIGN KEY par le postulat : "le nom d'un
            // champ 'clé étrangère' a pour nom le nom de la table vers laquelle 
            // elle fait référence, et fait référence au champ clé primaire de
            // cette table."

            // Boucle sur chaque table de la base
            foreach ($this->tablebase as $elem1) {
                // Récupération des infos de la table
                $table_infos = $this->db->tableInfo(DB_PREFIXE.$elem1);
                // Boucle sur chaque colonne
                foreach ($table_infos as $column) {
                    // Si le nom de la colonne est identique au nom de la table en
                    // cours et qu'il n'est pas déjà présent dans la liste
                    // alors on l'ajoute
                    if ($column['name'] == $this->table
                        && !in_array($elem1, $this->sousformulaires)) {
                        //
                        array_push($this->sousformulaires, $elem1);
                        //
                        if (!in_array($elem1.'.'.$column['name'], $this->other_tables)) {
                            $this->other_tables[] = $elem1.'.'.$column['name'];
                        }
                    }
                }
            }

        }

        //
        sort($this->sousformulaires);
        //
        sort($this->other_tables);

    }


    /**
     * Cette méthode permet d'initialiser les FOREIGN KEY de la table en cours
     * vers les autres tables de la base en recherchant les contraintes
     * dans la base de données pour MySQL.
     */
    protected function _init_foreign_tables_information_schema_for_mysql() {

        // tables referencees par des cles etrangeres de la table actuelle
        $sql = 'SELECT table_name, '.
                      'column_name,'.
                      'REFERENCED_TABLE_NAME AS foreign_table_name, '.
                      'REFERENCED_COLUMN_NAME AS foreign_column_name '.
                'FROM information_schema.key_column_usage '.
                'WHERE '.
                  'REFERENCED_TABLE_NAME is not NULL '.
                  'AND table_name = \''.$this->table.'\' '.
                  'AND table_schema = \''.$this->base.'\'';

        $foreign_keys = $this->db->query($sql);

        $message =  'gen(): db->query("'.$sql.'");';
        logger::instance()->log('class gen - '.$message, VERBOSE_MODE);

        if (database::isError($foreign_keys)) {
            die();
        }

        //
        while ($key =& $foreign_keys->fetchrow(DB_FETCHMODE_ASSOC)) {
            //
            array_push($this->clesecondaire, $key['column_name']);
            //
            $this->foreign_tables[$key['column_name']] = $key;
        }

    }

    /**
     * Cette méthode permet d'initialiser les FOREIGN KEY de la table en cours
     * vers les autres tables de la base en recherchant les contraintes
     * dans la base de données pour PostGreSQL.
     */
    protected function _init_foreign_tables_information_schema_for_pgsql() {

        // tables referencees par des cles etrangeres de la table actuelle
        $sql = 'SELECT tc.table_name, '.
                      'kcu.column_name,'.
                      'ccu.table_name AS foreign_table_name, '.
                      'ccu.column_name AS foreign_column_name '.
                 'FROM information_schema.table_constraints AS tc '.
                 'JOIN information_schema.key_column_usage AS kcu '.
                   'USING (constraint_schema, constraint_name) '.
                 'JOIN information_schema.constraint_column_usage AS ccu '.
                   'USING (constraint_schema, constraint_name) '.
                'WHERE constraint_type = \'FOREIGN KEY\' '.
                  'AND tc.table_name = \''.$this->table.'\' '.
                  'AND tc.table_schema = \''.OM_DB_SCHEMA.'\'';

        $foreign_keys = $this->db->query($sql);

        $message =  'gen(): db->query("'.$sql.'");';
        logger::instance()->log('class gen - '.$message, VERBOSE_MODE);

        if (database::isError($foreign_keys)) {
            die();
        }

        //
        while ($key =& $foreign_keys->fetchrow(DB_FETCHMODE_ASSOC)) {
            //
            array_push($this->clesecondaire, $key['column_name']);
            //
            $this->foreign_tables[$key['column_name']] = $key;
        }

    }

    /**
     * Cette méthode permet d'initialiser les FOREIGN KEY des autres tables de
     * la base vers la table en cours en recherchant les contraintes dans la
     * base de données pour MySQL.
     */
    protected function _init_other_tables_information_schema_for_mysql() {

        // tables referencees par des cles etrangeres de la table actuelle
        $sql = 'SELECT table_name, '.
                      'column_name,'.
                      'REFERENCED_TABLE_NAME AS foreign_table_name, '.
                      'REFERENCED_COLUMN_NAME AS foreign_column_name '.
                'FROM information_schema.key_column_usage '.
                'WHERE '.
                  'REFERENCED_TABLE_NAME is not NULL '.
                  'AND referenced_table_name = \''.$this->table.'\' '.
                  'AND table_schema = \''.$this->base.'\'';
        
        /* Exemple de restultat avec $this->table = 'om_collectivite'
          
           table_name   |   column_name   | foreign_column_name 
        ----------------+-----------------+---------------------
         om_parametre   | om_collectivite | om_collectivite
         om_utilisateur | om_collectivite | om_collectivite
         exemple        | ville_1         | om_collectivite
         exemple        | ville_2         | om_collectivite
         ... */
        
        $other_tables = $this->db->query($sql);
        
        $this->addToLog("gen(): db->query(\"".$sql."\");", VERBOSE_MODE);
        if (database::isError($other_tables, true)) {
            if (DEBUG >= DEBUG_MODE) {
                echo 'erreur';
            }
        }
        
        while ($table =& $other_tables->fetchrow(DB_FETCHMODE_ASSOC)) {
        
            // initialisation de la liste des sous formulaires, sans doublon
            if (!in_array($table['table_name'], $this->sousformulaires)) {
                array_push($this->sousformulaires, $table['table_name']);
            }
        
            $infos = $table['table_name'].'.'.$table['column_name'];
        
            // initialisation des couples table.colonne sans doublon
            if (!in_array($infos, $this->other_tables)) {
                $this->other_tables[] = $infos;
            }
        
        }

    }

    /**
     * Cette méthode permet d'initialiser les FOREIGN KEY des autres tables de
     * la base vers la table en cours en recherchant les contraintes dans la
     * base de données pour PostGreSQL.
     */
    protected function _init_other_tables_information_schema_for_pgsql() {

        // tables ayant des references vers la table actuelle
        $sql = 'SELECT tc.table_name, '.
                      'kcu.column_name,'.
                      'ccu.column_name AS foreign_column_name '.
                 'FROM information_schema.table_constraints AS tc '.
                 'JOIN information_schema.key_column_usage AS kcu '.
                   'USING (constraint_schema, constraint_name) '.
                 'JOIN information_schema.constraint_column_usage AS ccu '.
                   'USING (constraint_schema, constraint_name) '.
                'WHERE constraint_type = \'FOREIGN KEY\' '.
                  'AND ccu.table_name = \''.$this->table.'\' '.
                  'AND ccu.table_schema = \''.OM_DB_SCHEMA.'\'';

        /* Exemple de restultat avec $this->table = 'om_collectivite'
          
           table_name   |   column_name   | foreign_column_name 
        ----------------+-----------------+---------------------
         om_parametre   | om_collectivite | om_collectivite
         om_utilisateur | om_collectivite | om_collectivite
         exemple        | ville_1         | om_collectivite
         exemple        | ville_2         | om_collectivite
         ... */

        $other_tables = $this->db->query($sql);

        $this->addToLog("gen(): db->query(\"".$sql."\");", VERBOSE_MODE);
        if (database::isError($other_tables, true)) {
            if (DEBUG >= DEBUG_MODE) {
                echo 'erreur';
            }
        }

        while ($table =& $other_tables->fetchrow(DB_FETCHMODE_ASSOC)) {
    
            // initialisation de la liste des sous formulaires, sans doublon
            if (!in_array($table['table_name'], $this->sousformulaires)) {
                array_push($this->sousformulaires, $table['table_name']);
            }

            $infos = $table['table_name'].'.'.$table['column_name'];

            // initialisation des couples table.colonne sans doublon
            if (!in_array($infos, $this->other_tables)) {
                $this->other_tables[] = $infos;
            }

        }

    }

    /**
     *
     */
    protected function _init_constraint_notnull() {

        if (OM_DB_PHPTYPE == 'mysql') {
            //
            $sql = " select column_name, column_default from information_schema.columns ";
            $sql .= " where table_schema='".OM_DB_DATABASE."' ";
            $sql .= " and table_name='".$this->table."' ";
            $sql .= " and is_nullable='NO' ";
            $sql .= " and column_default is NULL ORDER BY column_name; ";
            $res = $this->db->query($sql);
            database::isError($res);
            while ($row =& $res->fetchrow(DB_FETCHMODE_ASSOC)) {
                $this->_columns_notnull[] = strtolower($row['column_name']);
            }
        } elseif (OM_DB_PHPTYPE == 'pgsql') {
            //
            $sql =  'SELECT DISTINCT column_name '.
                    'FROM INFORMATION_SCHEMA.COLUMNS '.
                    'WHERE is_nullable = \'NO\' '.
                        'AND column_default IS NULL '.
                        'AND table_name = \''.$this->table.'\' '.
                        'AND table_schema = \''.OM_DB_SCHEMA.'\' '.
                    'ORDER BY column_name';
            $res_notnull = $this->db->query($sql);
    
            $message =  'gen(): db->query("'.$sql.'");';
            logger::instance()->log('class gen - '.$message, VERBOSE_MODE);
    
            if (database::isError($res_notnull)) {
                die();
            }
            while ($column =& $res_notnull->fetchrow(DB_FETCHMODE_ASSOC)) {
                $this->_columns_notnull[] = $column['column_name'];
            }
        }

    }

    // }}}

    // {{{ Methodes - Utilitaires

    protected function get_libelle() {

        // initialisation du libelle s'il est vide
        if (empty($this->libelle)) {
            $this->libelle = $this->get_libelle_of($this->table);
        }

        return $this->libelle;
    }

    /**
     * Rempli les tableaux unique_key et unique_multiple_key
     *
     * @param string table sur laquelle on cherche les colonnes uniques.
     */
    function set_unique_key($table) {

        if (OM_DB_PHPTYPE == "pgsql") {

            // Sur PostGreSQL des problèmes ont été rencontré avec la cohérence
            // des informations retournées par tableinfo

            //

            $sql = 'SELECT tc.constraint_name, '.
                      'kcu.column_name '.
                 'FROM information_schema.table_constraints AS tc '.
                 'JOIN information_schema.key_column_usage AS kcu '.
                   'USING (constraint_schema, constraint_name) '.
                'WHERE constraint_type = \'UNIQUE\' '.
                  'AND tc.table_name = \''.$this->table.'\' '.
                  'AND tc.table_schema = \''.OM_DB_SCHEMA.'\' '.
                'ORDER BY kcu.column_name';
            
        } else {

            $sql = "SELECT CONSTRAINT_NAME, COLUMN_NAME FROM information_schema.table_constraints ".
                    "JOIN information_schema.key_column_usage k ".
                    "USING(constraint_name,table_schema,table_name) ".
                    "WHERE TABLE_SCHEMA='".OM_DB_DATABASE."' AND CONSTRAINT_TYPE='UNIQUE'  AND TABLE_NAME='".$this->table."' ".
                    "ORDER BY COLUMN_NAME";
        }
        $res_unique_key = $this->db->query($sql);
    
        $message =  'gen(): db->query("'.$sql.'");';
        logger::instance()->log('class gen - '.$message, VERBOSE_MODE);

        if (database::isError($res_unique_key)) {
            die();
        }
        $unique_key=array();
        while ($key =& $res_unique_key->fetchrow(DB_FETCHMODE_ASSOC)) {
            $unique_key[$key['constraint_name']][] = $key['column_name'];
        }
        foreach($unique_key as $unique_constraint) {
            if(count($unique_constraint)>1) {
                $this->unique_multiple_key[] = $unique_constraint;
            } else {
                $this->unique_key[] = $unique_constraint[0];
            }
        }
    }

    /**
     * Compare un flux avec un fichier.
     *
     * L'entete du fichier contenant la date et l'heure de generation n'est pas
     * prise en compte (d'ou le "legerement").
     *
     * Retourne true si:
     *      - le flux et le fichier sont legerement identiques
     *
     * Retourne false si:
     *      - le fichier ne s'ouvre pas
     *      - le flux et le fichier sont differents
     *
     * @return bool 
     */
    function stream_slightly_equals_file($stream, $file) {

        // si le fichier n'existe pas
        if (!file_exists($file)) {
            return false;
        }
        
        $f = fopen($file, 'r');
        // si le fichier ne s'ouvre pas
        if (!$f) {
            return false;
        }

        $i = 0;
        $pointer = strlen($this->entete);

        // boucle sur les lignes du fichier
        while (($line = fgets($f)) !== false) {

            $i++;

            // on saute les lignes d'entete (affichant l'heure)
            if ($i <= substr_count($this->entete, "\n")) {
                continue;
            }

            // si deux lignes sont differentes, $stream et $file sont differents
            if ($line != substr($stream, $pointer, strlen($line))) {
                return false;
            }


            $pointer += strlen($line);
        }

        // les fichiers sont legerement identiques
        return true;
    }

    // }}}

    // {{{

    /**
     *
     */
    public function get_general_option($option = "") {
        //
        if ($option == "") {
            //
            return NULL;
        }
        //
        if (file_exists("../gen/dyn/gen.inc.php")) {
            //
            include "../gen/dyn/gen.inc.php";
        }
        //
        if (isset($$option)) {
            //
            return $$option;
        } else {
            //
            switch ($option) {
                case "key_constraints_mode":
                    return "constraints"; break;
                default:
                    return NULL;
            }
        }
    }

    // }}}

    // {{{ Methodes - Utilitaires statiques

    /**
     * @return bool
     */
    public function is_generable() {

        //
        if (!$this->has_primary_key($this->table, true)) {
            return false;
        }

        //
        if (!$this->foreign_tables_have_primary_key(true)) {
            return false;
        }

        //
        return true;

    }

    /**
     * @return bool
     */
    public function has_primary_key($table, $display_error = true) {

        //
        $primary_key = $this->get_primary_key($table);
        
        //
        if ($primary_key != NULL) {
            //
            return true;
        }
    
        //
        if ($display_error == true) {
            $m = new message();
            $message = _("Generation impossible, aucune cle primaire n'est ".
                         "presente ou plusieurs cles primaires sont presentes ".
                         "dans la table");
            $m->displayMessage('error', $message.' '.$table.'.');
        }
        //
        return false;

    }

    /**
     * @return bool
     */
    public function foreign_tables_have_primary_key($display_error = true) {

        //
        foreach ($this->sousformulaires as $foreign_table_name) {
            //
            if (!$this->has_primary_key($foreign_table_name, $display_error)) {
                //
                return false;
            }
        }
        //
        return true;

    }

    /**
     * Cette méthode permet de récupérer le libellé de la clé primaire de la
     * table passée en paramètre.
     *
     * @return string
     */
    public function get_primary_key($table) {

        //
        $primary_key = "";
        $is_error = false;

        //
        $mode = $this->get_general_option("key_constraints_mode");

        //
        if ($mode == "constraints") {

            // MODE 1 - Recherche de PRIMARY KEY en interrogeant les contraintes
            // de la base de données par 'tableinfo'

            if (OM_DB_PHPTYPE == "pgsql") {

                // Sur PostGreSQL des problèmes ont été rencontré avec la cohérence
                // des informations retournées par tableinfo

                //
                $sql = 'SELECT tc.table_name, '.
                              'kcu.column_name '.
                         'FROM information_schema.table_constraints AS tc '.
                         'JOIN information_schema.key_column_usage AS kcu '.
                           'USING (constraint_schema, constraint_name) '.
                         'JOIN information_schema.constraint_column_usage AS ccu '.
                           'USING (constraint_schema, constraint_name) '.
                        'WHERE constraint_type = \'PRIMARY KEY\' '.
                          'AND tc.table_name = \''.$table.'\' '.
                          'AND tc.table_schema = \''.OM_DB_SCHEMA.'\'';
        
                $res_primary_key = $this->db->query($sql);
        
                $message =  'gen(): db->query("'.$sql.'");';
                logger::instance()->log('class gen - '.$message, VERBOSE_MODE);
        
                if (database::isError($res_primary_key)) {
                    die();
                }
    
                if ($res_primary_key->numrows() > 1) {
                    $primary_key = "";
                    $is_error = true;
                } else {
                    while ($key =& $res_primary_key->fetchrow(DB_FETCHMODE_ASSOC)) {
                        $primary_key = $key['column_name'];
                    }
                }
                
            } else {

                //
                $infos = $this->db->tableInfo(DB_PREFIXE.$table);
                //
                foreach ($infos as $column) {
                    // Si 'tableinfo' nous renvoi le flag 'primary_key' sur une
                    // colonne
                    if (strpos($column['flags'], 'primary_key')) {
                        // Si nous n'avons pas déjà trouvé une clé primaire et qu'il
                        // n'y a pas eu une erreur
                        if ($primary_key == "" && $is_error == false) {
                            // On récupère le libellé de la clé primaire
                            $primary_key = $column['name'];
                        } else {
                            // Si il y a plusieurs clés primaires sur la même table
                            // On re-initialise la clé primaire et on positionne
                            // le marqueur d'erreur à 'true'
                            $primary_key = "";
                            $is_error = true;
                        }
                    }
                }
            }

        } elseif ($mode == "postulate") {

            // MODE 2 - Recherche de PRIMARY KEY par le postulat : "le nom d'un
            // champ 'clé primaire' a pour nom le nom de la table."

            //
            $infos = $this->db->tableInfo(DB_PREFIXE.$table);
            //
            foreach ($infos as $column) {
                //
                if ($column['name'] == $table) {
                    //
                    $primary_key = $table;
                    break;
                }
            }

        }

        // Si on ne trouve aucune clé primaire
        if ($primary_key == "" && $is_error == false) {
            // On positionne le marqueur d'erreur à 'true'
            $is_error = true;
        }

        //
        if ($is_error == true) {
            return NULL;
        }
        //
        return $primary_key;
    }

    /**
     * @return string
     */
    public function get_libelle_of($table) {

        /* Recherche du libelle.
          
          Si il existe une colonne libelle, elle est utilisee.
          Sinon, on utilise la seconde colonne de la table.
          Sinon, on utilise la cle primaire de la table.
        */

        $libelle = '';
        $libelle_exists = false;

        $infos = $this->db->tableInfo(DB_PREFIXE.$table);
        database::isError($infos);

        foreach ($infos as $column) {
            if ($column['name'] == 'libelle') {
                $libelle_exists = true;
                break;
            }
        }

        // si il existe une colonne libelle, elle est utilisee
        if ($libelle_exists == true) {
            $libelle = 'libelle';
        } else {

            // sinon, on utilise la seconde colonne de la table
            if (key_exists(1, $infos)) {
                $libelle = $infos[1]['name'];

            // sinon, on utilise la cle primaire de la table.
            } else {
                $libelle = $this->get_primary_key($table);
            }
        }

        $message = 'get_libelle_of(\''.DB_PREFIXE.$table.'\');';
        $message .= ' ';
        $message .= 'return \''.$libelle.'\';';
        logger::instance()->log('class gen - '.$message, VERBOSE_MODE);

        return $libelle;
    }

    /**
     * Test les droits d'ecriture sur un fichier.
     * @return bool
     */
    public function is_editable($fichier) {
        //Recuperation du dossier parent
        $pathArray=explode("/", $fichier);
        $lib = array_pop($pathArray);
        $folderPath=implode("/", $pathArray);
        // Si le serveur a les droits d'ecriture
        if((!is_writable($fichier) AND file_exists($fichier)) 
        OR (!file_exists($fichier) AND !is_writable($folderPath))) {
            return false;
        } else {
            return true;
        }
    }

    // }}}


    /**
     *
     *
     */
    function get_gen_parameters() {
        //
        $parameters = array();
        //
        $parameters["table_obj_class_gen"] = array(
            "rubrik" => "formulaire",
            "path" => "../gen/obj/".$this->table.".class.php",
            "method" => "table_obj_class_gen",
            "checked_delete" => true,
            "checked_generate" => true,
        );
        //
        if ($this->is_omframework_table($this->table)) {
            //
            $parameters["table_obj_class_core"] = array(
                "rubrik" => "formulaire",
                "path" => "../core/obj/".$this->table.".class.php",
                "method" => "table_obj_class_core",
                "checked_delete" => true,
                "checked_generate" => "not_exists",
            );
        }
        //
        $parameters["table_obj_class"] = array(
            "rubrik" => "formulaire",
            "path" => "../obj/".$this->table.".class.php",
            "method" => "table_obj_class",
            "checked_delete" => true,
            "checked_generate" => "not_exists",
        );
        //
        $parameters["table_sql_inc_gen"] = array(
            "rubrik" => "formulaire",
            "path" => "../gen/sql/".OM_DB_PHPTYPE."/".$this->table.".inc.php",
            "method" => "table_sql_inc_gen",
            "checked_delete" => true,
            "checked_generate" => true,
        );
        //
        if ($this->is_omframework_table($this->table)) {
            //
            $parameters["table_sql_inc_core"] = array(
                "rubrik" => "formulaire",
                "path" => "../core/sql/".OM_DB_PHPTYPE."/".$this->table.".inc.php",
                "method" => "table_sql_inc_core",
                "checked_delete" => true,
                "checked_generate" => "not_exists",
            );
        }
        //
        $parameters["table_sql_inc"] = array(
            "rubrik" => "formulaire",
            "path" => "../sql/".OM_DB_PHPTYPE."/".$this->table.".inc.php",
            "method" => "table_sql_inc",
            "checked_delete" => true,
            "checked_generate" => "not_exists",
        );
        //
        $parameters["table_sql_forminc_gen"] = array(
            "rubrik" => "formulaire",
            "path" => "../gen/sql/".OM_DB_PHPTYPE."/".$this->table.".form.inc.php",
            "method" => "table_sql_forminc_gen",
            "checked_delete" => true,
            "checked_generate" => true,
        );
        //
        if ($this->is_omframework_table($this->table)) {
            //
            $parameters["table_sql_forminc_core"] = array(
                "rubrik" => "formulaire",
                "path" => "../core/sql/".OM_DB_PHPTYPE."/".$this->table.".form.inc.php",
                "method" => "table_sql_forminc_core",
                "checked_delete" => true,
                "checked_generate" => "not_exists",
            );
        }
        //
        $parameters["table_sql_forminc"] = array(
            "rubrik" => "formulaire",
            "path" => "../sql/".OM_DB_PHPTYPE."/".$this->table.".form.inc.php",
            "method" => "table_sql_forminc",
            "checked_delete" => true,
            "checked_generate" => "not_exists",
        );
        //
        $parameters["editioninc"] = array(
            "rubrik" => "edition",
            "path" => "../sql/".OM_DB_PHPTYPE."/".$this->table.".pdf.inc.php",
            "method" => "pdf",
            "checked_delete" => true,
            "checked_generate" => false,
        );
        //
        $parameters["reqmoinc"] = array(
            "rubrik" => "reqmo",
            "path" => "../sql/".OM_DB_PHPTYPE."/".$this->table.".reqmo.inc.php",
            "method" => "reqmo",
            "checked_delete" => true,
            "checked_generate" => false,
        );
        // On ajoute des fichiers générables pour chacune des clés étrangères
        // de l'objet sur lequel on se trouve
        if (!empty($this->clesecondaire)) {
            // On boucle sur chacune des clés étrangères
            foreach ($this->clesecondaire as $elem) {
                //
                $parameters["reqmo_".$elem] = array(
                    "rubrik" => "reqmo",
                    "path" => "../sql/".OM_DB_PHPTYPE."/".$this->table."_".$elem.".reqmo.inc.php",
                    "method" => "reqmo",
                    "method_param" => $elem,
                    "checked_delete" => true,
                    "checked_generate" => false,
                );
            }
        }
        //
        $parameters["importinc"] = array(
            "rubrik" => "divers",
            "path" => "../sql/".OM_DB_PHPTYPE."/".$this->table.".import.inc.php",
            "method" => "import",
            "checked_delete" => true,
            "checked_generate" => false,
        );
        // Rétro-compatibilite : test du fichier .inc si pas de .inc.php
        foreach ($parameters as $key => $elem) {
            // Si le fichier .inc.php n'existe pas
            if (!file_exists($elem["path"])) {
                // Si le fichier .inc existe
                if (file_exists(substr($elem["path"], 0,
                                strlen($elem["path"])-4))) {
                    // Alors on modifie le path
                    $parameters[$key]["path"] = substr(
                        $elem["path"], 
                        0,
                        strlen($elem["path"]) - 4
                    );
               }
            }
        }
        //
        return $parameters;
    }

    function affichecol($col1, $col2, $col3) {
        echo "<tr class=\"tab-data even\">\n";
        echo "\t<td  class=\"col-1\">".$col1."</td>\n";
        echo "\t<td  class=\"col-2\">".$col2."</td>\n";
        echo "\t<td  class=\"col-3\">";
        $param['lien']=$col3;
        $this->f->layout->display_lien($param);
        echo"</td>\n";
        echo "</tr>\n";  
    }
    function affichetitre($titre) {
        echo "<tr class=\"name\">\n";
        echo "\t<td colspan=\"3\">";
        echo $titre;
        echo "</td>\n";
        echo "</tr>\n";
    }
    function afficheinfo($col1, $col2){
        echo "<tr class=\"tab-data odd\">\n";
        echo "\t<td  class=\"col-1\">".$col1."</td>\n";
        echo "\t<td  class=\"col-2\">".$col2."</td>\n";
        echo "</tr>\n";
    }
    function getPathFromFile($filePath) {
        $pathArray=explode("/", $filePath);
        $lib = array_pop($pathArray);
        return implode("/", $pathArray);
    }



    /**
     * ...
     * 
     * @return void
     */
    function display_analyse() {
        //
        $this->f->layout->display_start_fieldset(array(
            "fieldset_class" => "startClosed",
            "legend_content" => _("analyse du modele de donnees"),
        ));

        // Ouverture de la balise tableA VOIR POUR MOBILE
            $param['idcolumntoggle']="genanalyse";
            $this->f->layout->display_table_start_class_default($param);
            $array_entete = array("element","infos");
            echo "<thead><tr class=\"ui-tabs-nav ui-accordion ui-state-default tab-title\">";
            $param = array(
                        "key" => 0,
                        "info" =>  $array_entete
                 );
            $this->f->layout->display_table_cellule_entete_colonnes($param);
            echo "&nbsp;&nbsp;Elements</th>";
            $param = array(
                        "key" => 1,
                        "info" => $array_entete
                 );
            $this->f->layout->display_table_cellule_entete_colonnes($param);
            echo "&nbsp;&nbsp;Infos</th>";
            echo "</tr></thead>";
        // tables de la base
        $contenu = "";
        if (!empty($this->tablebase)) {
            foreach ($this->tablebase as $elem) {
                $contenu .= " [ ".$elem. " ] ";
            }
            $lib = _("Tables de la base de donnees");
            $this->afficheinfo($lib, $contenu);
        } 
        // table
        $contenu = "";
        $lib = _("Table :")." <span class=\"bold\">".$this->table."</span>";
        $contenu .= "[ "._('cle')." ".$this->typecle." - ";
        if ($this->typecle == 'N') { // XXX - Ce test est-il correct ?
            $contenu .= _("cle automatique")." ]";
        } else {
            $contenu .= _("cle manuelle")." ]";
        }
        $contenu .= " <span class=\"bold\">[".$this->primary_key."]</span> ";
        $contenu .=" [ "._('longueur')." "._("enregistrement")." : ".$this->longueur." ]";
        $this->afficheinfo($lib, $contenu); 
        // champs
        $contenu = "";
        $lib = _("Champs");
        foreach ($this->info as $elem) {
            $contenu .= "[ ".$elem["name"]." ".$elem["len"]." ".$elem["type"]." ] ";
        }
        $this->afficheinfo($lib, $contenu); 
        // sous formulaire
        $contenu = "";
        if (!empty($this->sousformulaires)) {
            foreach ($this->sousformulaires as $elem) {
                $contenu .= " [ ".$elem. " ] ";
            }
        }
        $lib= _("Sous formulaire");
        $this->afficheinfo($lib, $contenu);
        // cle secondaire
        $contenu = ""; 
        if (!empty($this->clesecondaire)) {
            foreach ($this->clesecondaire as $elem) {
                $contenu .= " [ ".$elem. " ] ";
            }
        }
        $lib = _("Cle secondaire");
        $this->afficheinfo($lib, $contenu);
        // Fermeture de la balise table
        echo "</table>"; 
        //
        $this->f->layout->display_stop_fieldset();
    }

}

?>
