Bonjour à tous,
j'ai suivis l'excellent tuto pour faire un site et A à Z et j'ai un petit soucis !
j'aimerai mettre en place un menu arborescent dynamique mais c'est la que je bloque !

Ma table menu se présente comme ceci :

ID | IDparent | nom
1 | 0 | Services
2 | 0 | Contact
3 | 1 | Impressions
4 | 1 | Studio
5 | 1 | Tirage
6 | 0 | Livre d'or

et j'aimerai obtenir le résultat suivant :

Services

  • Impressions
  • Studio
  • Tirage
    Contact
    Livre d'or
    ...

J'arrive bien a avoir le menu principal avec IDparent 0 mais pas le sous menu en liaison avec la rubrique correspondante cad Services -> Impressions,Studio,Tirage

Comme dans le tuto faire un site de A à Z je dois créer une fonction dans PagesController.php (situé dans le dossier controller) donc je charge bien ma table avec la fonction getMenu()(dans PagesController.php) les données que je recupere sur ma page default.php (dossier layout) mais mon sous menu n'apparait pas !

J’espère avoir été assez clair dans mon explication et que quelqu'un pourra m'aider ! Merci d'avance

22 réponses


Gregory
Réponse acceptée

Et si tu fais ça?

<ul class="sf-menu">
                    <?php foreach($pagesMenu as $p): ?>
                        $v->SousMenu = $this->request('Pages','getsousMenu',$v->id); ?>
                        <li class="current"><a href="<?php echo Router::url('pages/view/id:'.$p->idRubrique_menu); ?>" title="<?php echo $p->nom; ?>"><em><?php echo $p->nom; ?></em><strong></strong></a>
                            <ul>
                            <?php foreach($v->SousMenu as $pp): ?>
                                <li><a href="<?php echo Router::url('pages/view/id:'.$pp->idRubrique_menu); ?>" title="<?php echo $pp->nom; ?>"><?php echo $pp->nom; ?></a>
                                </li>
                            <?php endforeach; ?>
                            </ul>
                        </li>
                    <?php endforeach; ?>
                    </ul>

Tu utilise Cakephp? ou c'est développer un site de A à Z en php tous court?

je développe un site tout court sans framework

dans ta requête sql tu fait un select de toutes les pages dont IDparent = 0.
Tu récupère le tableau et tu le passe dans une nouvelle fonction.
Cette fonction exécute une requête qui pour chaque élément du tableau, on récupère dans un sous taleau les pages qui ont un IDparent = ID de l'élément du tableau.

Là tu as un tableau du genre:

[ListePage]{
    [0] => {
        id => '1';
        nom => 'page1';
    },
    [1] => {
        id => '2';
        nom => 'page2';
        pages => {
            [0] => {
                id => '4';
                nom => 'page4';
            },
            [1] => {
                id => '5';
                nom => 'page5';
            }
        }
    },
    [2] => {
        id => '3';
        nom => 'page3';
    }
}

ok merci pour ta réponse,j’essaie ça de suite !!!

Voici mes deux fonctions comme tu me l'as conseillé :

//Permet de récupérer les pages pour le menu

    function getMenu(){
        $this->loadModel('Rubrique_menu');
        $m'menu'] = $this->Rubrique_menu->find(array(
            'conditions' => array('IDparent' => 0)
            ));
        return $m'menu'];
    }

    // Permet de récupérer les pages pour le sousmenu

    function getsousMenu($id){
        $this->loadModel('Rubrique_menu');
        $m'sousmenu'] = $this->Rubrique_menu->find(array(
            'conditions' => array('IDparent' => $id)
            ));
        return $m'sousmenu'];
    }

Dans ma page d'accueil j'appelle le menu comme ceci :

<?php $pagesMenu = $this->request('Pages','getMenu'); ?>
<?php $pagesSousMenu = $this->request('Pages','getsousMenu($pagesMenu)'); ?>
                    <?php foreach($pagesMenu as $p): ?>
                        <li><a href="<?php echo Router::url('pages/view/id:'.$p->idRubrique_menu); ?>" title="<?php echo $p->nom; ?>"><?php echo $p->nom; ?></a></li> 
                    <?php endforeach; ?>

Est ce que je suis dans le bon ?

<?php $pagesMenu = $this->request('Pages','getMenu'); ?>
<?php foreach($pagesMenu as &$v){
    $v'SousMenu'] = $this->request('Pages','getsousMenu('$v'id'])'); ?>
} ?>
<ul>
<?php foreach($pagesMenu as $p): ?>
    <li><a href="<?php echo Router::url('pages/view/id:'.$p->idRubrique_menu); ?>" title="<?php echo $p->nom; ?>"><?php echo $p->nom; ?></a>
        <ul>
        <?php foreach($v'SousMenu'] as $pp): ?>
            <li><a href="<?php echo Router::url('pages/view/id:'.$pp->idRubrique_menu); ?>" title="<?php echo $pp->nom; ?>"><?php echo $pp->nom; ?></a>
            </li>
        <?php endforeach; ?>
        </ul>
    </li>
<?php endforeach; ?>
</ul>

Je pense que je ne me suis pas trompé. Teste ça :)

Je pense aussi que c'est quelques chose comme ca mais j'ai un soucis niveau de mon controller, quand j'essai d'acceder a l'action 'getMenu' ou 'getsousMenu' de la fonction $this->request(); il me met 3 messages d'erreurs :

Notice: Undefined property: PagesController::$getMenu() in C:\Program Files\EasyPHP-5.3.9\www\StudioPhotoJB\class\Controller.php on line 92

Warning: Invalid argument supplied for foreach() in C:\Program Files\EasyPHP-5.3.9\www\StudioPhotoJB\view\layout\default.php on line 45

Warning: Invalid argument supplied for foreach() in C:\Program Files\EasyPHP-5.3.9\www\StudioPhotoJB\view\layout\default.php on line 49

fonction request du controller :

function request($controller,$action){
        $vars = array();
        $controller .= 'Controller';
        require_once ROOT.SEP.'controller'.SEP.$controller.'.php';
        $c = new $controller();
        return $c->$action;

    }

Code que tu m'as conseillé

<?php $pagesMenu = $this->request('Pages','getMenu()'); ?>
                    <?php foreach($pagesMenu as &$v){
                        $v'SousMenu'] = $this->request('Pages','getsousMenu('.$v->id.')'); ?>
                    <?php } ?>
                    <ul class="sf-menu">
                    <?php foreach($pagesMenu as $p): ?>
                        <li><a href="<?php echo Router::url('pages/view/id:'.$p->idRubrique_menu); ?>" title="<?php echo $p->nom; ?>"><?php echo $p->nom; ?></a>
                            <ul>
                            <?php foreach($v'SousMenu'] as $pp): ?>
                                <li><a href="<?php echo Router::url('pages/view/id:'.$pp->idRubrique_menu); ?>" title="<?php echo $pp->nom; ?>"><?php echo $pp->nom; ?></a>
                                </li>
                            <?php endforeach; ?>
                            </ul>
                        </li>
                    <?php endforeach; ?>
                    </ul>

L'erreur la plus importante c'est la première. En gros il te dit qu'il y a une erreur à la ligne 92 de ton fichier Controller.php.

J'imagine que c'est ta fonction request?

Tu pourrais pointer sur la ligne qui nous intéresse?

donc c'est a cette ligne la ->

<?php $pagesMenu = $this->request('Pages','getMenu()'); ?>

le getMenu() donc est récupéré dans ma fonction request à la place de $action

function request($controller,$action){
        $vars = array();
        $controller .= 'Controller';
        require_once ROOT.SEP.'controller'.SEP.$controller.'.php';
        $c = new $controller();
        return $c->$action;

    }

Pour le getsousMenu, j'utilise aussi la fonction request ->

$v'SousMenu'] = $this->request('Pages','getsousMenu('.$v->id.')');

mais la , il me dit Fatal error: Call to undefined method PagesController::getsousMenu(1)()

J'ai encore essayé un petit peu ce weekend mais je n'arrive toujours pas à passer un paramètre dans ma fonction getsousMenu() ! Je ne vois pas ce qui cloche pourtant !

Personne ne saurait comment je peut passer un paramètre dans ma fonction getsousMenu() ?

ben il te faut rajouter un paramètre dans ta fonction request genre request($controller,$action,$param=null) ensuite tu testes si param n'est pas nul pour le passer à ton action

Merci j'avais déjà essayer quelque chose du genre mais je vais réessayer !

J'obtiens un erreur de ce genre

Fatal error: Cannot use object of type stdClass as array

Est ce que je dois mettre $v'SousMenu'] plutot comme ceci $v->SousMenu ???
voici le code

<?php $pagesMenu = $this->request('Pages','getMenu()'); ?>
                    <?php foreach($pagesMenu as &$v){
                        $v'SousMenu'] = $this->request('Pages','getsousMenu('.$v->id.')'); ?>
                    <?php } ?>
                    <ul class="sf-menu">
                    <?php foreach($pagesMenu as $p): ?>
                        <li><a href="<?php echo Router::url('pages/view/id:'.$p->idRubrique_menu); ?>" title="<?php echo $p->nom; ?>"><?php echo $p->nom; ?></a>
                            <ul>
                            <?php foreach($v'SousMenu'] as $pp): ?>
                                <li><a href="<?php echo Router::url('pages/view/id:'.$pp->idRubrique_menu); ?>" title="<?php echo $pp->nom; ?>"><?php echo $pp->nom; ?></a>
                                </li>
                            <?php endforeach; ?>
                            </ul>
                        </li>
                    <?php endforeach; ?>
                    </ul>

Testes comme ça
$v'SousMenu'] = $this->request('Pages','getsousMenu()',$v->id); ?>

alors voila comment j'ai fait :

<?php $pagesMenu = $this->request('Pages','getMenu'); ?>
                    <?php foreach($pagesMenu as $v){
                        $v->SousMenu = $this->request('Pages','getsousMenu',$v->id); ?>
                    <?php } ?>
                    <ul class="sf-menu">
                    <?php foreach($pagesMenu as $p): ?>
                        <li class="current"><a href="<?php echo Router::url('pages/view/id:'.$p->idRubrique_menu); ?>" title="<?php echo $p->nom; ?>"><em><?php echo $p->nom; ?></em><strong></strong></a>
                            <ul>
                            <?php foreach($v->SousMenu as $pp): ?>
                                <li><a href="<?php echo Router::url('pages/view/id:'.$pp->idRubrique_menu); ?>" title="<?php echo $pp->nom; ?>"><?php echo $pp->nom; ?></a>
                                </li>
                            <?php endforeach; ?>
                            </ul>
                        </li>
                    <?php endforeach; ?>
                    </ul>

Le menu s'affiche bien mais pas le sous menu alors que quand je fait un debug($v) j'obtiens bien :

stdClass Object
(
    [idRubrique_menu] => 3
    [nom] => Services
    [description] => page des servcies
    [date] => 
    [actif] => 1
    [menu] => 1
    [ordre] => 3
    [sousRubrique] => 0
    [slug] => 
    [SousMenu] => Array
        (
            [0] => stdClass Object
                (
                    [idRubrique_menu] => 8
                    [nom] => Tirages pro
                    [description] => page tirage
                    [date] => 
                    [actif] => 1
                    [menu] => 1
                    [ordre] => 8
                    [sousRubrique] => 3
                    [slug] => 
                )
            [1] => stdClass Object
                (
                    [idRubrique_menu] => 9
                    [nom] => Impressions
                    [description] => page impression
                    [date] => 
                    [actif] => 1
                    [menu] => 1
                    [ordre] => 9
                    [sousRubrique] => 3
                    [slug] => 
                )
            [2] => stdClass Object
                (
                    [idRubrique_menu] => 10
                    [nom] => Reportage et studio
                    [description] => page reportage et studio
                    [date] => 
                    [actif] => 1
                    [menu] => 1
                    [ordre] => 10
                    [sousRubrique] => 3
                    [slug] => 
                )
        )
)

tu peux mettre ta fonction request?

voila:

function request($controller,$action,$params = null){
        $vars = array();
        $controller .= 'Controller';
        require_once ROOT.SEP.'controller'.SEP.$controller.'.php';
        $c = new $controller();
        return $c->$action($params);

    }

Super nickel ça marche !!! Un tout grand merci a toi pour ton aide

De rien ;=)
Bon courage pour la suite

bonjour
c'est vrai que ton code marche, mais j'estime que pour lancer la boucle permettant d'afficher les sous menus, il faut tout d'abords vérifier l'existence de ceux-ci, ceci afin d'avoir dans tous les cas un code html propre.
aussi que se passe t-il si un élément du top level menu possède des sous menus de différents niveaux? je ne l'ai pas testé mais une lecture en diagonale me laisse croire que seuls les sous menus de premier niveau sont affichés?
donc à mon avis une amélioration de ce code est nécessaire.