<?php
/**
 * OM_TABLE - Surcharge du core
 *
 * @package opencimetiere
 * @version SVN : $Id$
 */

require_once PATH_OPENMAIRIE."om_table.class.php";

/**
 * Définition de la classe 'om_table' (table).
 *
 * Cette classe permet la surcharge de certaines méthodes de
 * la classe table du framework pour des besoins spécifiques
 * de l'application.
 */
class om_table extends table {

    /**
     * Surcharge de la méthode display() pour corriger le calcul du colspan
     * de la ligne "Aucun enregistrement" en prenant en compte les actions
     * à gauche (actions_number_l) en plus des actions contextuelles (actions_number_c).
     */
    public function display($params = array(), $actions = array(), $db = NULL, $class = "tab", $onglet = false) {
        if (! empty($params['get']) && $params['get'] === 'nombre_resultat') {
            $this->setParams($params);
            $this->composeSearchTab();
            $this->composeQuery();
            echo '<span id="tab_total_element">'.$this->get_nombre_resultat($this->sqlC, $this->tri).'</span>';
            return;
        }
        //
        $this->displayGlobalContainerStart();
        //
        $this->displayToolbarContainerStart();
        //
        $this->saveUserActions($actions);
        $this->saveActionsNumber();

        //
        $this->db = $db;

        //
        $this->setParams($params);
        $this->setParam("style", $class);
        $this->setParam("onglet", $onglet);

        // Construction de la recherche
        $this->composeSearchTab();

        // En mode onglet, on n'affiche pas le formulaire de recherche
        if ($onglet == false) {
            //
            $display_search = true;
            foreach($this->options as $option) {
                if ($option["type"] == "search") {
                    $display_search = $option["display"];
                }
            }
            //
            if ($display_search) {
                //
                $this->displaySearchContainerStart();
                //
                $this->displaySearch();
                //
                $this->displaySearchContainerEnd();
            }
        }

        /**
         * GLOBAL ACTIONS
         */
        //
        $this->process_global_action_validity();
        // En mode onglet, on n'affiche pas les lien vers les actions
        if ($onglet == false) {
            //
            $this->process_global_action_edition();
            $this->process_global_action_export();
        }
        //
        $this->display_global_actions();

        // Construction de la requete
        $this->composeQuery();

        // Execution de la requete a partir de l'enregistrement $premier avec
        // la limite $this->serie + 1
        // Ajouter un element par rapport a ce qui est attendu permet de
        // determiner si il y a une page suivante a afficher ou pas.
        $res = $db->limitquery($this->sql, intval($this->getParam("premier")), ($this->serie + 1));

        $this->addToLog(__METHOD__."(): db->limitquery(\"".$this->sql."\", ".intval($this->getParam("premier")).", ".$this->serie.");", VERBOSE_MODE);

        $this->f->isDatabaseError($res);

        // Recuperation des infos sur la table
        // ( oracle: recuperation immediate  (en dynamique) )
        $info = $this->getColumnsName($res);

        //
        $nbligne = $res->numrows();
        $display_pagination = true;
        foreach($this->options as $option) {
            if ($option["type"] == "pagination") {
                $display_pagination = $option["display"];
            }
        }
        if ($display_pagination) {
            // Affichage de la pagination
            echo "<!-- tab-pagination -->\n";
            $this->displayPagination(
                $nbligne,
                $this->get_nombre_resultat($this->sqlC, $this->tri, $this->f->getParameter('statement_timeout')),
                $class,
                $onglet
            );
        }

        //
        $this->displayToolbarContainerEnd();
        //
        $this->displayTableContainerStart();
        //
        $this->displayTableStart($class);

        // Temporisation de l'affichage du contenu de la table
        ob_start();

        // Affichage de la ligne d'entete du tableau
        // false car tab non dynamique (pas d'onglet)
        $this->displayHeader($info, $class, $onglet);

        // Calcul du nombre de colonnes
        $nbchamp = count($info);

        // Gestion d'une classe css differente une ligne sur deux
        $odd = 0;

        // Affichage des lignes de tableaux
        echo "\t<!-- tab-data -->\n";
        echo "\t<tbody>\n";

        // Si aucun resultat, on affiche une ligne avec un message
        // indiquant qu'il n'y a aucun enregistrement
        if ($nbligne == 0) {

            $colspan = $nbchamp;
            // SURCHARGE : ajout de la condition || $this->actions_number_l > 0
            if ($this->actions_number_c > 0 || $this->actions_number_l > 0) {
                $colspan += 1;
            }

            echo "\t<tr class=\"".$class."-data empty\">\n";
            echo "<td colspan=\"".$colspan."\">";
            echo __("Aucun enregistrement.");
            echo "</td>";
            echo "\t</tr>\n";

        }

        // On différencie le tab_actions par défaut de celui de la
        // ligne pour qu'il ne s'incrémente pas à chaque résultat.
        $tab_actions_default = $this->actions["left"];
        $tab_actions_default_order = $this->actions_order_l;
        $tab_actions_default_number = $this->actions_number_l;

        // Boucle sur les resultats de la requete
        $nb_element_affiche = 0;
        while ($row =& $res->fetchRow() && $nb_element_affiche < $this->serie) {
            $nb_element_affiche++;
            // Gestion des options
            $option_style = "";
            $option_href = false;
            $option_tab_action = false;

            // pour chaque option
            foreach($this->options as $option) {

                // s'il s'agit d'une conditon
                if ($option["type"] == "condition") {

                    // pour chaque cas
                    foreach($option["case"] as $case) {

                        if (isset($row[$this->getKeyForColumnName($option["field"])])
                            and in_array($row[$this->getKeyForColumnName($option["field"])], $case["values"])) {

                            $option_style .= (isset($case["style"]) ? " ".$case["style"] : "");

                            if (isset($case["href"])) {

                                $option_href = array($case["href"]);
                                // case['href'][1] : action de contenu
                                if (key_exists(1, $case["href"])) {
                                    $this->actions['content'] = $case['href'][1];
                                }
                            }

                            // Si on rencontre le cas tab_action on mémorise l'option
                            // qui sera toujours left puisque destinée au tableau
                            if (isset($case["tab_actions"])) {

                                // Si c'est la première condition on crée l'option
                                if ($option_tab_action == false) {
                                    $option_tab_action = $case["tab_actions"]["left"];
                                } else { // sinon on la fusionne
                                    $option_tab_action = array_merge($option_tab_action, $case["tab_actions"]["left"]);
                                }
                            }
                        }
                    }
                }
            }

            // si au moins un tab action est défini
            if ($option_tab_action != false) {

                // on l'(les) ajoute à la fin du tableau d'actions
                $this->actions["left"] =
                array_merge($this->actions["left"], $option_tab_action);

                // on l'(les) ajoute à la fin de liste ordonnée des actions
                foreach ($option_tab_action as $action_title => $action_properties) {

                    $this->actions_order_l[strval($action_properties["ordre"])] = array(0 => $action_title);
                    // On incrémente le nombre d'actions pour la largeur de la colonne
                    $this->actions_number_l ++;
                }

                // On crée un nouveau tableau dont la clé et la valeur
                // sont l'ordre de l'action.
                $action_array = array();
                foreach ($this->actions_order_l as $action_order => $value)
                {
                    $action_array[$action_order] = $action_order;
                }

                // Cela nous permet de trier la liste ordonnée par la valeur de l'ordre
                // (nécessaire car la liste est associative : l'ordre est un string).
                array_multisort($action_array, SORT_ASC, $this->actions_order_l);
            }

            // si un href est défini
            if ($option_href != false) {

                // on retient le nouveau tableau d'actions
                $links = $option_href;

                // on retient le nombre d'actions
                $nbr_actions_l = $this->countActions($option_href[0]);

            } else {

                // on retient le nombre d'actions
                $nbr_actions_l = $this->actions_number_l;

                // On récupère l'ordre des actions prédéfinies
                $links = $this->actions_order_l;
            }

            // on met a jour le nombre maximal d'actions
            if ($nbr_actions_l > $this->max_actions_number) {
                $this->max_actions_number = $nbr_actions_l;
            }

            // Affichage d'une ligne de tableau
            echo "\t\t<tr";
            echo " class=\"";
            echo $class."-data";
            echo $option_style;
            echo " ".($odd % 2 == 0 ? "odd" : "even");
            echo "\">\n";

            // Gestion d'une classe css differente une ligne sur deux
            $odd += 1;

            //
            if ($this->actions_number_c > 0
                or $this->actions_number_l > 0) {

                echo "\t\t\t<td class=\"icons\">";
                echo "&nbsp;";
            }

            // Affichage des actions a gauche
            foreach ($links as $order => $actions) {

                foreach($actions as $key => $action) {

                    // dans le cas ou une condition est satisfaite
                    if (is_array($action)) {
                        $conf = $action;

                    // dans tous les autres cas
                    } else {
                        $conf = $this->actions['left'][$action];
                    }

                    if (isset($conf['lien']) and
                        $conf['lien'] != '' and $conf['lien'] != '#'
                        and (isset($conf['lib']) and $conf['lib'] != '')) {

                        /* la fonction ajaxIt n'est pas appelee si l'action
                           est defini a la maniere openmairie < 4.3.0 ou
                           qu'il est explicitement dit de ne pas utiliser
                           d'ajax */

                        $no_ajax = false;
                        if (strpos((string)$key, 'retro_') !== false or
                            (isset($conf['ajax'])) and $conf['ajax'] == false) {

                            $no_ajax = true;
                        }
                        // debut lien 1ere colonne table : consulter ...
                        //
                        //*
                        $action_id = "action-";
                        if($onglet === false) {
                            $action_id .= "tab-";
                        } else {
                            $action_id .= "soustab-";
                        }
                        $action_id .= $this->getParam("obj")."-left-".$action."-".urlencode($row[0]);
                        $params = array(
                               "onglet" => $onglet,
                               "no_ajax" => $no_ajax,
                               "lien" => (isset($conf['lien']) ? $conf['lien'] : ""),
                               "row" => $row[0],
                               "id" => (isset($conf['id']) ? $conf['id'] : ""),
                               "obj" => $this->getParam("obj"),
                               "lib" => (isset($conf['lib']) ? $conf['lib'] : ""),
                               "identifier" => $action_id
                        );
                        if (isset($conf['target'])) {
                            $params["target"] = $conf['target'];
                        }

                        if (isset($conf['type']) === true && $conf['type'] === 'action-direct') {
                            $params["class"] = 'action-direct';
                        }
                        $this->f->layout->display_table_lien_data_colonne_une($params);
                    }
                }
            }

            // Récupération des tab_actions par défaut
            $this->actions["left"] = $tab_actions_default;
            $this->actions_order_l = $tab_actions_default_order;
            $this->actions_number_l = $tab_actions_default_number;

            if ($this->actions_number_c > 0
                or $this->actions_number_l > 0) {
                echo "</td>\n";
            }

            // pour chaque colonne du tableau
            foreach ($row as $key => $elem) {

                // gestion des actions de contenu
                $content = '';

                // affichage de l'action specifique si elle existe
                if (isset($this->actions['specific_content'][$key])) {
                    $content = $this->actions['specific_content'][$key];

                // sinon affichage de l'action de contenu si elle existe
                } else if (isset($this->actions['content'])) {
                    $content = $this->actions['content'];
                }

                // affichage de la cellule
                echo "\t\t\t<td ";
                echo "class=\"col-".$key."";

                // gestion des classes
                if ($key == 0) {
                    echo " firstcol";
                }

                if ($key == count($row)-1) {
                    echo " lastcol";
                }

                if (is_numeric($elem)) {
                    echo " right";
                }

                echo "\"";
                echo ">";

                // affichage d'un lien mailto si on detecte une adresse mail valide
                if ($this->f->checkValidEmailAddress($elem)) {
                    echo "<a href='mailto:".$elem."' ";
                    echo "title=\"".__("Envoyer un mail a cette adresse")."\">";
                    echo "<span class=\"ui-icon ui-icon-mail-closed\">&nbsp;</span>";
                    echo "</a>";
                }

                // si une action de contenu existe
                if (!empty($content) and isset($content['lien'])
                    and $content['lien'] != ''
                    and $content['lien'] != '#') {

                    if (!isset($content['id'])) {
                        $content['id'] = "";
                    }

                    /* la fonction ajaxIt n'est pas appelee si l'action
                       est defini a la maniere openmairie < 4.3.0 ou
                       qu'il est explicitement dit de ne pas utiliser
                       d'ajax */

                    $no_ajax = false;
                    if (isset($content['ajax']) and $content['ajax'] == false) {

                        $no_ajax = true;
                    }

                    // affichage du correspondant a l'action
                    echo "<a class='lienTable' ";

                    if ($onglet == false or $no_ajax === true) {
                        echo "href=\"".$content['lien'].
                             urlencode($row[0]).$content['id']."\"";
                    } else {
                        echo "href=\"";
                        echo "#";
                        echo "\" ";
                        echo " onclick=\"ajaxIt('";
                        echo  $this->getParam("obj")."','";
                        echo $content['lien'].urlencode($row[0]);
                        echo $content['id'];
                        echo "');\"";
                    }

                    echo ">";
                    echo $elem;
                    echo "</a>";
                } else {
                    echo $elem;
                }
                echo "</td>\n";
            }

            // Fermeture de la balise ligne de tableau
            echo "\t\t</tr>\n";
        }

        // Recuperation du contenu de la table
        $output = ob_get_clean();

        // Ajout du nombre d'actions a la classe actions-max-
        $output = str_replace('actions-max-',
                              'actions-max-'.$this->max_actions_number,
                              $output);

        // Affichage du contenu de la table
        echo $output;

        // Fermeture de la balise tbody
        echo "\t</tbody>\n";

        // Fermeture de la balise table
        echo "</table>\n";

        // Libere le resultat de la requete
        $res->free();
        //
        $this->displayTableContainerEnd();
        //
        $this->displayGlobalContainerEnd();
    }

}
