Problème avec mon algorithme

Le problème exposé dans ce sujet a été résolu.

Bonjour/Bonsoir à tous,

Je développe un projet sous symfony et son moteur twig mais je suis confronté à un problème quant à la construction de mon algorithme, en effet j'ai un tableau comme ceci avec plusieurs entrées qui se répete :

Image utilisateur

J'aimerais pouvoir afficher ce tableau sous ce modèle :

1
2
3
4
5
6
7
8
<div class="grandtitre">titre rubrique
<div class =petittitre">titre ssrubrique
<ul>
<li>titre
<li>titre
</ul>
</div>
</div>

J'ai essayé avec ce code mais ça part en cacahuètes… Mes variables ne sont pas très explicites donc je vous explique un peu : les variables toto me permettent de ne pas répéter plusieurs fois mes titres , et les variables balises me permettent d'ouvrir et fermer les balises lorsque cela est necessaire

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
{% set toto = 'ok' %}
{% set toto2 = 'ok' %}
{% set toto3 = 'ok' %}
{% set balise = 'false' %}
{% set balise2 = 'false' %}

{% for plans in listeRubrique %}

    {% if toto != plans.titreRubrique %}
        {% if balise == 'false' %}
            <div class="grandtitre">
            {% set balise = 'true' %}
        {% else %}  
            </div>
            <div>
        {% endif %}
        <h2>{{plans.titreRubrique}}</h2>
        {% set toto = plans.titreRubrique %}
    {% endif %}

    {% if toto2 != plans.titreSsRubrique %}
        {% if balise2 == 'false' %}
            <div>
            {% set balise2 = 'true' %}
        {% else %}
            fermer balise
            </div>
            <div>
        {% endif %}
        <a>{{plans.titreSsRubrique}}</a>
        {% set toto2 = plans.titreSsRubrique %}
    {% endif %}

{% endfor %}

Me voila bloqué, j'aimerais avoir votre aide ! Merci d'avance des vos réponses .

+0 -0

Salut,

Ton problème peut se résoudre (je n'ai pas regardé dans le détail, mais j'ai déjà fait un truc du genre donc c'est faisable, mais très lourd).

Par contre, il y a selon moi un problème de logique qui fait que tu as ce problème.

En effet, comme tu peux le voir tu as de la redondance dans ta base de données : titre_rubrique1 est répété plusieurs fois, et ce ne devrait pas être le cas.

Étant sous Symfony2, j'en conclus que tu travailles avec Doctrine pour requêter ta base de données.

Tu devrais donc créer un objet Rubrique, avec deux attributs, son nom et un tableau contenant les sous-rubriques.

Les sous-rubriques sont également des objets, avec encore deux attributs, le nom et un tableau contenant tous les objets "plans" liés à cette sous-rubrique.

Tu auras alors deux ManyToOne, une entre Rubrique et Sous-Rubrique, et l'autre entre Sous-Rubrique et Plan.

Une fois ceci fait, tu pourras faire dans ton code des choses comme :

1
2
3
4
5
6
7
8
<?php
{% for rubrique in rubriques %}
    {% for sous-rubrique in rubrique.sous-rubriques %}
        {% for plan in sous-rubrique.plan %}
            {{ plan.name }}
        {% endfor %}
    {% endfor %}
{% endfor %}

Ce qui devrait ensuite pouvoir te permettre de faire tous les traitements que tu veux ;)

Le mieux se serait peut être bien d'adapter ton modèle de données afin d'éviter la redondance.

Mais sinon, si tu ne veux pas changer ton modèle de données, le plus simple, je pense, c'est de garder en mémoire le dernier grand titre et le dernier sous-titre et d'afficher le titre actuel si il est différent du précédent.

Ça qui donnerait un truc dans ce genre là:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
ancien_titre <- ''
ancien_sstitre <- ''
ouvert <- faux;
POUR CHAQUE plans DANS listeRubrique
FAIRE
    SI ancien_titre != plans.titre
    ALORS
        SI ouvert ALORS
            afficher balise_fermante
            ouvert <- faux
        FIN SI

        ancien_titre <- plans.titre
        afficher plans.titre
    FIN SI

    SI ancien_sstitre != plans.sstitre 
    ALORS
        SI ouvert ALORS
            afficher balise_fermante
            ouvert <- faux
        FIN SI

        ancien_sstitre <- plans.sstitre 
        afficher plans.sstitre 
        afficher balise ouvrante
        ouvert <- vrai
    FIN SI

    afficher plans.titre_plan
FIN POUR
+1 -0

Theo > Nope, c'est une solution assez mauvaise, surtout que ses sous-rubriques et ses sous-sous-rubriques ont leur données. S'il en vient à modifier un poil le modèle de ses données, c'est la catastrophe, tant niveau maintenance que perfs en fait.

En soit, la meilleure solution serait celle en effet d'utiliser une représentation intervallaire, mais c'est particulièrement relou à mettre en place avec Doctrine (à moins de savoir s'inspirer du modèle Tree proposé par l'extension Gedmo).

Sinon, si tu ne veux pas te prendre la tête (et éventuellement ne pas retoucher ton modèle), faut faire comme l'a indiqué Nicofuma.

+0 -0

Si la représentation intervallaire convient et que Doctrine pose un problème, il est toujours possible d'utiliser Doctrine sans utiliser la couche ORM (haut niveau) mais seulement la DBAL.

En gros, c'est simplement la couche qui fait l'abstraction de la base de données mais qui utilise les requêtes SQL classiques, comme PDO.

Tu trouveras toutes les infos dans la doc de Symfony2 : http://symfony.com/doc/current/cookbook/doctrine/dbal.html, qui elle même renvoie vers celle de Doctrine au besoin.

Oui mais dans ce cas il se prive des avantages de l'orm, à savoir de récupérer des objets avec lesquels il peut facilement travailler. Si il tient absolument à utiliser la RI (grand bien lui fasse), il peut toujours faire comme la pagination, et passe en deux passes (deux requetes). Une pour sélectionner les identifiants (et juste les identifiants) des objets à sélectionner selon le critère qu'il désire, et une autre où il sélectionne les objets trouvés.

Mais, le probème revient au point un, où comme tout est ramené à un seul niveau (et donc pas par hiérarchie comme tu le suggères, à savoir getChildren()… etc), et on en revient donc à la solution de Nicofuma.

Quitte à me répéter, le plus simple, quitte à ne pas modifier son modèle, est d'adopter l'algo proposé par Nicofuma. Ou, s'il y a modification de la structure, de se démeler avec l'extension Gedmo.

+0 -0

Bonjour à tous,

D'après sa capture d'écran, clairement il a déjà 3 tables représentant chacun un niveau. Donc en faisant une requête sur le plus haut niveau (parent IS NULL) et en faisant les jointures qui vont bien pour éviter le lasy loading, l'algo de Theo convient parfaitement.

Il va récupérer des objets Rubrique qui possède une ManyToOne vers Rubrique accessible par getChildren() par exemple.

+0 -0
Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte