Zend FR

Consultez la FAQ sur le ZF avant de poster une question

Vous n'êtes pas identifié.

#1 26-06-2008 14:22:30

Papytruc
Nouveau membre
Date d'inscription: 26-06-2008
Messages: 3

[ZEND MVC] Affichage arborescence / éléments imbriqués

Bonjour,
Voilà, j'ai une petite problèmatique et je n'arrive pas à la résoudre malgré mes recherches.
Je dois afficher une sorte d'arborescence du type categorie->sous_categorie->sous_sous_categorie.
Le tout est extrait d'une base de données.
Le problème est que j'arrive à afficher toutes les catégories mais que je n'arrive pas à afficher
les sous-catégories correspondantes juste en-dessous.
En clair, je veux avoir un truc du genre
Categorie1
    Sous_cat_a
    Sous_cat_b
Categorie2
    Sous_cat_c
etc...

Tout ce que j'arrive à afficher c'est
Catégorie1
Catégorie2
Catégorie3
avec des liens vers une liste des sous-catégories correspondantes.
Si quelqu'un a une idée, je suis à votre écoute.
Merci d'avance.

Hors ligne

 

#2 26-06-2008 17:22:52

Kaimite
Membre
Lieu: Marseille
Date d'inscription: 16-06-2008
Messages: 144
Site web

Re: [ZEND MVC] Affichage arborescence / éléments imbriqués

Attention ça va être un peu long !!!

Pour commencer j'ai une table avec tout mon arbo dedans.
La table gère les sous rubriques sur un nombre de sous niveaux illimité.

Code:

+-----+-----+-------------+------+------+
| uid | mid |     nom     | mere | rang |
+-----+-----+-------------+------+------+
|  0  |  0  | Categorie 1 |   1  |   1  |
+-----+-----+-------------+------+------+
|  1  |  1  | Sous cat A  |   0  |   1  |
+-----+-----+-------------+------+------+
|  2  |  1  | Sous cat B  |   0  |   2  |
+-----+-----+-------------+------+------+
|  3  |  0  | Categorie 2 |   1  |   2  |
+-----+-----+-------------+------+------+
|  4  |  3  | Sous cat C  |   0  |   1  |
+-----+-----+-------------+------+------+

mid représente l'i de la rubrique mère
mere vaut 1 ou 0 et permet de savoir si une rubrique a des enfants
Le rang te permet classer tes rubriques


Ensuite il faut utiliser des fonctions récursives pour chercher les enfants en cascade.

Je me suis fait une classe pour générer mes menus et voici en gros comment ça fonctionne...

1 - Tu recherche les liens du 1er niveau
2 - Pour chacun de ces liens tu créé l'élement <li> correpondant.
3 - Si un des liens a des enfants on relance 2 pour chaque enfant qui va relancer 3 qui va relancer 2 etc..
4 - on renvoie le menu fini

L'utlisation des listes imbriqués te permet de gérer simplement l'indentation de chaque niveau.

Code:

<?php

class Arborescence_Menu {
    function __contruct ( $uid = "" ) {
        $this -> uid = $uid;
    }
    
    protected function renvoyerCodeRubrique ($uid) {
        $infosRubrique = Requete("SELECT * FROM `arborescence` WHERE `uid`");
        
        $codeRetour = "<li>";
        
        $codeRetour .= $infosRubrique['nom'];
        
        /**
         * Si la rubrique est une mere on retourne le menu de ses enfants
         * J'utilise une fonction pour pouvoir faire des tests spécifiques
         **/
        if ( $this -> estRubriqueMere ($uid) ) {
            $lesEnfants = Requete("SELECT `uid` FROM `arborescence` WHERE `mid` = " . $uid . " ORDER BY `rang` ");
            $codeRetour .= "<ul>";
            $codeRetour .= $this -> renvoyerSousMenu($lesEnfants);
            $codeRetour .= "</ul>";
        }
        
        $codeRetour .= "</li>";
        
        return $codeRetour;
    }
    
    protected function renvoyerSousMenu ($listeEnfants) {
        
        /**
         * La recursivité se trouve ici !
         * Pour chaquen enfant on apelle $this -> renvoyerCodeRubrique() 
         * Qui appelera à son tour $this -> renvoyerSousMenu() avec les enfants de l'enfant
         * Et ainsi de suite..
         **/
        
        $sousNiveau = array();
        foreach ( $listeEnfants as $idEnfant ) {
            $sousNiveau[] = $this -> renvoyerCodeRubrique ($idEnfant);
        }
        
        return implode($sousNiveau);
        
    }
    
    protected function estMere ($uid) {
        
        /**
         * Ici tu peux faire différents tes pour savoir si tu renvoi les enfants de cette rubrique ou non
         * Par exemple si tu veux limiter le nombre de niveau de ton arbo, si tu présente cette arbo 
         * sur le front-office ou l'espace d'admin etc.
         **/
        
        return true;
    }
    
    protected function liensPremierNiveau () {
        
        /**
         * SI $this -> uid est vide alors on recherche toutes les rubriques de 1er niveau.
         * Celles qui n'ont pas de mère !
          ***/
        
        if ( empty( $this -> uid ) ) {
            $Rows = Requete("SELECT `uid` FROM `arborescence` WHERE `mid` = 0 ORDER BY `rang` ");
        }
        
        /**
         * Sinon on recherche les enfants de la rubrique
         **/
        else {
            $Rows = Requete("SELECT `uid` FROM `arborescence` WHERE `mid` = " . $this -> uid . " ORDER BY `rang`");
        }
        
        return $Rows;
        
    }
    
    public function renvoyerCodeMenu () {
        
        /** 
         * ON COMMENCE PAR CHERCHER LES LIENS DU 1ER NIVEAU
         * ILS SERONT RENVOYÉS DANS UN ARRAY QUE L'ON VA PARCOURIR ENSUITE
         */
        $premierNiveau = array();
        
        $liensPremierNiveau = $this -> renvoyerLiensPremierNiveau();
        if ( is_array( $liensPremierNiveau ) ) {
            foreach ( $liensPremierNiveau AS $uidLien ) {
                $premierNiveau[] = $this -> renvoyerCodeRubrique($uidLien);
            }
        }
        else {
            //--> IL N'Y A PAS D'ENFANTS 
        }
        
        //--> VOILA TU AS CHAQUE RUBRIQUE ET SES SOUS RUBRIQUE DANS LES CASES DU TABLEAU $premierNiveau
        
        return "<ul>" . implode($premierNiveau) . "</ul>"; 
        
    }
}

$monMenu = new Arborescence_Menu ();

echo $monMenu -> renvoyerCodeMenu();

?>

Bon, vu comme ça il y a plein de requêtes mais si tu utilise une cache tu peux l'éviter.
Pour ma part ma vrai classe est un peu plus complexe et étend une classe Arborescence qui utilise un système de cache qui m'évite chaque requête.

Tu peux également mettre en cache le code HTML d'un menu généré et éviter les boucles récursives à chaque appel de la page.

Voilà, si t'as besoin de détails n'hésite pas...

Cordialement,
Kaimite

Hors ligne

 

#3 26-06-2008 18:31:25

Papytruc
Nouveau membre
Date d'inscription: 26-06-2008
Messages: 3

Re: [ZEND MVC] Affichage arborescence / éléments imbriqués

Tout d'abord, merci pour ta réponse rapide.
J'ai traversé ton code rapidement et c'est vrai que cela peut être intéressant.
Seulement la solution me paraît un peu trop complexe pour mon problème.
En fait, j'ai déja 3 tables, catégories, sous-categorie et item.Les trois tables sont liées une à une ( Sous_categorie possède une référence de catégorie etc...)
Si je choisis ta solution, il me faut absolument rajouter une table ( arborescence ). N'y aurait-il pas un moyen plus direct?

De plus, je vois que dans ta classe on ajoute des éléments de vue. Genre <li> , est-ce inévitable ?
Dans les tutoriaux que j'ai pu voir, ils utilisaient pas mal les partial / partialloop par exemple pour la vue...
Mais je vois pas du tout comment combiner cela et des classes models issues par exemple de Zend_Db_Abstract.

Je vais continuer ma recherche et si je trouve rien de probant, j'essayerai de m'inspirer de ton code.
Encore merci wink

Cordialement.

Hors ligne

 

#4 26-06-2008 22:28:30

Kaimite
Membre
Lieu: Marseille
Date d'inscription: 16-06-2008
Messages: 144
Site web

Re: [ZEND MVC] Affichage arborescence / éléments imbriqués

J'ai développé cette class avant de me mettre sur Zend donc je n'utilise pas les ressources de Zend.

Mais comme le l'ai dit c'est une version "light" de ma vraie class pour te donner le principe.

Si j'ai bien compris tu as 3 tables.

- Catégories
- Sous cat
- Item

Donc tu cherchere toutes les categories

Pour chaque categorie tu cherche ses sous cats

Pour chaque sous cat tu cherche ses items

Si tu essaie un truc du genre :

Code:

<?php
$listeCats    = array();
$selectCat    = $this -> select() -> from() -> where () -> order ();
$rowsCat    = $this -> fethAll ($selectCat);

foreach ($rowsCat AS $unRowCat) {
    $infosCat = $unRowCat -> toArray();
    
    //--> Recherche des sous categories
    $listeSousCats    = array();
    $selectSousCat     = $this -> select() -> from () -> where ("`cat_id` = ? ", (int) $infosCat['uid']) -> order();
    $rowsSousCat    = $this -> fetchAll($selectSousCat);
    foreach ( $rowsSousCat AS $rowSousCat ) {
        $infosSousCat = $rowSousCat -> toArray();
        
        //--> Recherche des items
        $listeItems    = array();
        $selectItems    = $this -> select() -> from() -> where ("`sous_cat_id` = ? ", (int) $infosSousCat['uid']) -> order();
        $rowsItems        = $this -> fetchAll($selectItems);
        foreach ( $rowsItems AS $rowItem ) {
            $listeItems[]    = $rowItem -> toArray();
        }
        $infosSousCat['items']     = $listeItems;
        $listeSousCat[]            = $infosSousCat;
    }
    $infosCat['sousCat']     = $listeSousCat;
    $listeCats[]            = $infosCat;
}

?>

Bien sur il te faut adapter les différentes requêtes...

Tu obtiens, normalement un array comme celui-ci

Code:

Array
(
    [0] => Array
        (
            [nom] => Categorie 1
            [sousCat] => Array
                (
                    [0] => Array
                        (
                            [nom] => Sous cat 1
                            [items] => Array
                                (
                                    [0] => Array
                                        (
                                            [nom] => item 1
                                        )

                                    [1] => Array
                                        (
                                            [nom] => item 2
                                        )

                                    [2] => Array
                                        (
                                            [nom] => item 3
                                        )

                                )

                        )

                    [1] => Array
                        (
                            [nom] => Sous cat 2
                            [items] => Array
                                (
                                    [0] => Array
                                        (
                                            [nom] => item 1
                                        )

                                    [1] => Array
                                        (
                                            [nom] => item 2
                                        )

                                    [2] => Array
                                        (
                                            [nom] => item 3
                                        )

                                )

                        )

                    [2] => Array
                        (
                            [nom] => Sous cat 3
                            [items] => Array
                                (
                                    [0] => Array
                                        (
                                            [nom] => item 1
                                        )

                                    [1] => Array
                                        (
                                            [nom] => item 2
                                        )

                                    [2] => Array
                                        (
                                            [nom] => item 3
                                        )

                                )

                        )

                )

        )

    [1] => Array
        (
            [nom] => Categorie 2
            [sousCat] => Array
                (
                    [0] => Array
                        (
                            [nom] => Sous cat 1
                            [items] => Array
                                (
                                    [0] => Array
                                        (
                                            [nom] => item 1
                                        )

                                    [1] => Array
                                        (
                                            [nom] => item 2
                                        )

                                    [2] => Array
                                        (
                                            [nom] => item 3
                                        )

                                )

                        )

                    [1] => Array
                        (
                            [nom] => Sous cat 2
                            [items] => Array
                                (
                                    [0] => Array
                                        (
                                            [nom] => item 1
                                        )

                                    [1] => Array
                                        (
                                            [nom] => item 2
                                        )

                                    [2] => Array
                                        (
                                            [nom] => item 3
                                        )

                                )

                        )

                    [2] => Array
                        (
                            [nom] => Sous cat 3
                            [items] => Array
                                (
                                    [0] => Array
                                        (
                                            [nom] => item 1
                                        )

                                    [1] => Array
                                        (
                                            [nom] => item 2
                                        )

                                    [2] => Array
                                        (
                                            [nom] => item 3
                                        )

                                )

                        )

                )

        )

    [2] => Array
        (
            [nom] => Categorie 3
            [sousCat] => Array
                (
                    [0] => Array
                        (
                            [nom] => Sous cat 1
                            [items] => Array
                                (
                                    [0] => Array
                                        (
                                            [nom] => item 1
                                        )

                                    [1] => Array
                                        (
                                            [nom] => item 2
                                        )

                                    [2] => Array
                                        (
                                            [nom] => item 3
                                        )

                                )

                        )

                    [1] => Array
                        (
                            [nom] => Sous cat 2
                            [items] => Array
                                (
                                    [0] => Array
                                        (
                                            [nom] => item 1
                                        )

                                    [1] => Array
                                        (
                                            [nom] => item 2
                                        )

                                    [2] => Array
                                        (
                                            [nom] => item 3
                                        )

                                )

                        )

                    [2] => Array
                        (
                            [nom] => Sous cat 3
                            [items] => Array
                                (
                                    [0] => Array
                                        (
                                            [nom] => item 1
                                        )

                                    [1] => Array
                                        (
                                            [nom] => item 2
                                        )

                                    [2] => Array
                                        (
                                            [nom] => item 3
                                        )

                                )

                        )

                )

        )

)

Cela dit ça te fait toujours pas mal de requêtes alors il va te falloir utiliser un cache

Hors ligne

 

#5 05-02-2009 17:00:41

dev21
Membre
Date d'inscription: 06-01-2009
Messages: 23

Re: [ZEND MVC] Affichage arborescence / éléments imbriqués

je remonte le topic , j'essaie de faire quasi le même principe en utilisant le modèle MVC,

http://www.z-f.fr/forum/viewtopic.php?pid=14647#p14647

je suis bloqué avec mon getChildren()

Hors ligne

 

Pied de page des forums

Propulsé par PunBB
© Copyright 2002–2005 Rickard Andersson
Traduction par punbb.fr

Graphisme réalisé par l'agence Rodolphe Eveilleau
Développement par Kitpages