Bonjour à vous tous!

J'ai un petit soucis avec une requête sur un projet de construction dynamique de menu où les données viennent d'une base mysql. En effet, les données sont "explosées" dans la table et je dois les regrouper pour pouvoir reconstruire le menu. Là où je bloque, c'est comment regrouper ces données par le champ "origin" qui est mon seul élément qui relie les informations entre elles. De plus, je dois utiliser Laravel pour ce développement.

Base de donnée

Voici ci-dessous la structure actuelle de la base de donnée:

Ce que je veux

Idéalement, ce serait d'obtenir avec une requête un résultat de ce type:

array(
    '578500f7bed7f' => [
        'menuLevel' => 0,
        'menuTitre' => 'Titre du menu',
        'menuParent' => 0,
        'menuUrl' => '/url-du-menu'
    ]
    ... etc pour toutes les entrées de cette table
)

Ce que j'obtiens

Actuellement j'essaie avec les queries et eloquent, mais sans grand succès. J'ai aussi essayé avec les "Group BY" et ce genre de trucs mais là aussi je bloque un peu. Si quelqu'un a déjà eu ce genre de cas et qui pourrait m'éclairer et me donner une direction à suivre ce serait top!

Merci d'avance pour votre temps!

5 réponses


beeInteractive
Auteur
Réponse acceptée

J'ai trouvé en faisant de cette manière finalement:

return DB::table(DB::raw('datas l'))
            ->select(DB::raw('l.origin AS origin, t.value AS titre, l.value AS level, p.value AS parent, u.value AS url'))
            ->where(DB::raw('l.type'), DB::raw('\'menuLevel\''))
            ->where(DB::raw('l.value'), DB::raw(0))
            ->where(DB::raw('l.site_id'), DB::raw($this->id))
            ->join(DB::raw('datas t'), DB::raw('l.origin'), '=', DB::raw('t.origin'))
            ->join(DB::raw('datas p'), DB::raw('p.origin'), '=', DB::raw('l.origin'))
            ->join(DB::raw('datas u'), DB::raw('u.origin'), '=', DB::raw('l.origin'))
            ->where(DB::raw('t.type'), DB::raw('\'menuTitre\''))
            ->where(DB::raw('p.type'), DB::raw('\'menuParent\''))
            ->where(DB::raw('u.type'), DB::raw('\'menuUrl\''))
        ->get();

C'est pas hyper académique mais j'obtiens le résultat souhaité!
Merci pour vos idées!

Bonjour à toi,

Je ne comprend pas très bien ta structure de base table. Il y aurais plus simple à faire je pense, as tu possibilité de modifier celle-ci ?

J'aurais vu quelque chose dans ce style là :

| id | name | link | parent_id |
| 1 | Titre du menu | /titre-du-menu | NULL |
| 2 | Sous menu | /titre-du-menu/sous-menu | 1 |

Avec ce type de structure, tu récupère tous les élements qui ont un parent_id à NULL (qui correspond donc au niveau 0), et ensuite tu peux récupérer tous les menus enfants à celui-ci.

Salut @Azorgh!

Merci pour ta réponse. Alors non, je ne peux malheureusement pas changer la structure de la base de donnée.. Je vois un peu ton idée mais j'ai essayé cette approche mais cela ne correspond pas à ce que je souhaite effectuer.

Salut @beeInteractive,
Tu as éssayer le groupBy() ? En regroupant par la 2scd colonne puis essai un collapse() par exemple ?
[https://laravel.com/docs/5.2/collections#method-collapse](Check ici)

Je rejoins Vlaàd Capo's.
Cependant, utilise le groupBy de la collection que te retourne ta requête et non directement dans la requête.
En gros, avec un :

$menu = Menu::all();
$menu_sorted = $menu->groupBy('identifier');
dd($menu_sorted);

Le debug devrait te donner quelque chose dans le style que tu souhaites.