Zend FR

Consultez la FAQ sur le ZF avant de poster une question

Vous n'êtes pas identifié.

#1 07-08-2008 01:53:26

pozowebs
Membre
Lieu: Gran Canaria
Date d'inscription: 06-07-2008
Messages: 83
Site web

[Résolu][1.5] Fonctions dans une vue / findManyToManyRowset

Bonjour,

je bloque sur la chose suivante (sad): (désolé si l'explication de mon problème est un peu longue...)

J'ai un magasinController.php

Code:

    function indexAction()
    {
        indexAction()

        $magasin= new Magasins();
        $this->view->magasins= $magasin->getMagasins();
    }

getMagasins() est défini dans le modèle et renvoit simplement un fetchAll().

Dans ma vue index.phtml je fais une boucle foreach:

Code:

<?php foreach($this->magasins as $magasin) : ?>
<tr>
    <td><?php echo $this->escape($magasin->name);?></td>
    <td><?php echo $magasin->description;?></td>
<?php endforeach; ?>

Jusqu'ici pas de problème...

Maintenant je voudrais afficher dans ma vue une colonne supplementaire, après name et description, contenant les marques vendues dans le magasin.

Les relations marques <-> magasins (type many to many) sont gardées ainsi en bdd:

Code:

CREATE TABLE `marquesMagasins` (
  `id_marque` int(11) NOT NULL default '0',
  `id_magasin` int(11) NOT NULL default '0',
  PRIMARY KEY  (`id_marque`,`id_magasin`)
) TYPE=MyISAM CHARACTER SET `utf8`;

Et les noms des marques dans une autre table:

Code:

CREATE TABLE `marques` (
  `id` int(11) NOT NULL auto_increment,
  `marque_name` varchar(255) NOT NULL default '',
  PRIMARY KEY  (`id`)
) TYPE=MyISAM CHARACTER SET `utf8`;

Bref, maintenant je ne vois pas du tout comment récuperer ces infos dans ma vue, pour afficher la liste des marques à côté du nom et de la description...

dois-je utiliser un view helper, ou un action helper (lequel des deux, où le placer...?) que je placerai dans le foreach avec en paramètre l'id du magasin ($magasin->id) afin de faire des requeres SQL et de recuperer un tableau avec le resultat... ou bien y a t'il une autre solution de concept qui m'échappe?

Merci a+!  (et merci aux courageux qui ont le courage de lire jusqu'au bout wink)

Dernière modification par pozowebs (08-08-2008 15:44:18)

Hors ligne

 

#2 07-08-2008 09:49:26

fte
Membre
Lieu: 06 13 83
Date d'inscription: 16-05-2008
Messages: 112
Site web

Re: [Résolu][1.5] Fonctions dans une vue / findManyToManyRowset

La bonne pratique c'est de créer la méthode qui retourne les bonnes données dans le modèle, le controleur va juste les transvaser du modèle vers la vue.

getMagasins() doit s'occuper de tes deux jointures, par exemple :

Code:

    public function getPleinDeTrucs( $limiteMaxi= null, $omises= null, $order='vol_id' ) {
        $select = $this->select ();
        $select->limit ( $limiteMaxi, $omises )->order ( $order );

        $select->from ( $this )->setIntegrityCheck ( false )    // pour le join sinon erreur

        ->joinLeft ( array('t1'=> 'ville'), $this->_name.'.villed = t1.ville_id', array ( 'villed_fk'=> 'ville_nom' ) )
        ->joinLeft ( array('t2'=> 'ville'), $this->_name.'.villea = t2.ville_id', array ( 'villea_fk'=> 'ville_nom' ) )
        ->joinLeft ( array('t3'=> 'pilote'), $this->_name.'.pilote_id = t3.pilote_id', array ( 'pilote_id_fk'=> 'pilote_nom' ) )
        ->joinLeft ( array('t4'=> 'avion'), $this->_name.'.avion_id = t4.avion_id', array ( 'avion_id_fk'=> 'avion_nom' ) );

        $r= $this->fetchAll ( $select );
      
        return $r;
    }

Hors ligne

 

#3 07-08-2008 11:36:39

pozowebs
Membre
Lieu: Gran Canaria
Date d'inscription: 06-07-2008
Messages: 83
Site web

Re: [Résolu][1.5] Fonctions dans une vue / findManyToManyRowset

ok, merci pour ce bon exemple, getPleinDeTrucs(),  maintenant ma jointure fonctionne!

Problème suivant: comme je l'ai dit, la relation magasin <-> marques est many to many.

du coup, avec la boucle foreach de mon index.phtml, cela affiche la chose suivante:

Nom           |    Description        | Marque
---------------------------------------------------------
magasin1    |   blabla                | marque1
---------------------------------------------------------
magasin1    |  blabla                 | marque2

Comment puis-je faire pour afficher une seule ligne magasin1 avec dans marque une liste des marques... ?

MErci a+

Hors ligne

 

#4 07-08-2008 14:39:20

fte
Membre
Lieu: 06 13 83
Date d'inscription: 16-05-2008
Messages: 112
Site web

Re: [Résolu][1.5] Fonctions dans une vue / findManyToManyRowset

Si la vue est un tableau html, on peut peut-être utiliser un partialLoop qui ajoute un petit bout de vue tant qu'il y a des objets :

Code:

<?php echo $this->partialLoop( 'index/_ligne.phtml', $this->magasins->nom ) ?>

et dans _ligne.phtml qui s'occupe que d'une ligne, un Select est construit :

Code:

<tr>
<td><? echo $this->nom ?></td>
...
<td><select name="toto" >
<?php foreach($this->droits as $droit) : ?>
<option value="<?php echo .....?>" label="<?php echo ...?>"><?php ... ?></option>
<?php endforeach; ?></td>
</tr>

Dernière modification par fte (07-08-2008 14:40:14)

Hors ligne

 

#5 07-08-2008 15:50:55

pozowebs
Membre
Lieu: Gran Canaria
Date d'inscription: 06-07-2008
Messages: 83
Site web

Re: [Résolu][1.5] Fonctions dans une vue / findManyToManyRowset

au moins je vais remplacer mon foreach par partialLoop, ça fait plus propre dans la vue smile

Mais cela ne resoud pas le problème (à moins que j'ai mal compris).

En effet, dans la suggestion de _ligne.html suivante:

Code:

<tr>
<td><? echo $this->nom ?></td>
...
<td><select name="toto" >
<?php foreach($this->droits as $droit) : ?>
<option value="<?php echo .....?>" label="<?php echo ...?>"><?php ... ?></option>
<?php endforeach; ?></td>
</tr>

Tu fais un foreach sur droits...

Mais suite a ma requetee SQL (join), les infos n'arrivent pas comme ça: j'ai une ligne avec nom1 et marque1, puis ligne suivante avec nom1 et marque2... A aucun moment je ne peux faire de foreach sur "marque"...

ou bien je n'ai rien compris?

En tout cas merci pour ton aide smilesmile

Hors ligne

 

#6 07-08-2008 17:12:49

fte
Membre
Lieu: 06 13 83
Date d'inscription: 16-05-2008
Messages: 112
Site web

Re: [Résolu][1.5] Fonctions dans une vue / findManyToManyRowset

Oups j'avais lu en diagonale, alors là je sèche.

On peut toujours bidouiller getPleinDeTrucs() pour injecter dedans le tableau des marques :

dans le controlleur :

Code:

$magasins= $o->getPleinDeTrucs()->toArray(); // retourne une ligne par magasin

$pourLaVue= Array();

foreach ($magasins as $unMag) {
$b= $p->getMarquesById( $unMag->id )->toArray(); // a faire 
$unMag['Marque']= $b; // on range tout un tableau dedans

array_push( $pourLaVue, $unMag); // on empile les lignes 
}

$this->view->magasins= $pourLaVue;

Mais il y a peut etre plus élégant ici :
http://framework.zend.com/manual/fr/zen … ships.html

Dernière modification par fte (07-08-2008 17:14:00)

Hors ligne

 

#7 07-08-2008 17:32:56

pozowebs
Membre
Lieu: Gran Canaria
Date d'inscription: 06-07-2008
Messages: 83
Site web

Re: [Résolu][1.5] Fonctions dans une vue / findManyToManyRowset

J'avais deja essayé de bidouiller quelque chose avec les Relations de tables, mais sans trop de succès. A relire la doc, c'est vrai qu'il faudrait que je retente le coup.

Bref, je laisse reposer tout ça pour cet après-midi et je me replonge dedans ce soir, sauf si quelqu'un a une meilleure idée wink.

Merci a+

Hors ligne

 

#8 08-08-2008 15:43:31

pozowebs
Membre
Lieu: Gran Canaria
Date d'inscription: 06-07-2008
Messages: 83
Site web

Re: [Résolu][1.5] Fonctions dans une vue / findManyToManyRowset

Yes ça marche!! smile.

J'ai finalement utilisé http://framework.zend.com/manual/fr/zen … ships.html

Résumé des modifs:

Ajout des relations de tables dans les modèles:

Code:

class Magasins extends Zend_Db_Table_Abstract
{
    protected $_name = 'magasins';
    protected $_dependentTables = array('MarquesMagasins');    
}

Code:

class Marques extends Zend_Db_Table_Abstract
{
    protected $_name = 'marques';
    protected $_dependentTables = array('MarquesMagasins');    
}

Code:

class MarquesMagasins extends Zend_Db_Table_Abstract
{
    protected $_name = 'marquesMagasins';

    protected $_referenceMap    = array(
        'Marque' => array(
            'columns'           => array('id_marque'),
            'refTableClass'     => 'Marques',
            'refColumns'        => array('id')
        ),
        'Magasin' => array(
            'columns'           => array('id_magasin'),
            'refTableClass'     => 'Magasins',
            'refColumns'        => array('id')
        )
    );

}

Pas de changements dans mon MagasinController. J'ai seulement une indexAction qui fait un fetchAll sur Magasins, et j'envoie le resultat du fetchAll dans $this->view->magasins

Enfin, dans ma vue index.phtml, voici ce qui me permet d'afficher les differentes marques sur la même ligne que le magasin courant:

Code:

<?php foreach($this->magasins as $magasin) : ?>
<tr>
    <td><?php echo $this->escape($magasin->name);?></td>
    <td><?php echo $magasin->description;?></td>
    <td>
            <?php     
            $magasinsTable      = new Magasins();
            $magasinsRowset     = $magasinsTable->find($magasin->id);
            $currentMagasin     = $magasinsRowset->current();

            $marquesRowset   = $currentMagasin->findManyToManyRowset('Marques', 'MarquesMagasins');

            echo "<ul>";
            foreach($marquesRowset as $marque){
             echo "<li>".$marque->marque_name."</li>";
            }
            echo "</ul>";
            ?>
      </td>
</tr>
<?php endforeach; ?>

Voilà. C'était tout simple. Merci!!! smile

Hors ligne

 

#9 08-08-2008 16:33:32

grandlap
Membre
Date d'inscription: 22-07-2008
Messages: 50

Re: [Résolu][1.5] Fonctions dans une vue / findManyToManyRowset

Salut,

tu peux même l'écrire comme ça

Code:

$marquesRowset   = $currentMagasin->findMarquesViaMarquesMagasins();

mais je m'interroge sur les performances avec cette méthode. Il semblerait (je l'ai lu dans ce forum je crois, mais où...) exécuter une requête pour chaque magasin puisse être plus lourd que de faire une seule requête avec jointure et de créer ensuite un tableau en php à coup de bon vieux foreach.

C'est pourtant clairement moins élégant !

Hors ligne

 

#10 08-08-2008 17:02:31

pozowebs
Membre
Lieu: Gran Canaria
Date d'inscription: 06-07-2008
Messages: 83
Site web

Re: [Résolu][1.5] Fonctions dans une vue / findManyToManyRowset

merci pour la précision. Les commentaires sur ces questions de performances sont bienvenus wink

Hors ligne

 

#11 03-09-2008 14:19:24

fte
Membre
Lieu: 06 13 83
Date d'inscription: 16-05-2008
Messages: 112
Site web

Re: [Résolu][1.5] Fonctions dans une vue / findManyToManyRowset

Pour rebondir sur le sujet de la performance, comment bien mesurer ça ? J'ai fait 3 essais avec une jointure, un findManyToManyRowset et  un findTotoViaTata et le plugin pour firefox Yslow donne environ 400 ms et 600 soit 1/3 fois plus lent sans join.

Hors ligne

 

#12 14-03-2009 11:38:54

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

Re: [Résolu][1.5] Fonctions dans une vue / findManyToManyRowset

merci pour ton exemple, il m'a permis d'arriver à faire ce que je voulais !

mais est-ce qu'il y'a une autre façon de faire ?

Code:

$magasinsTable      = new Magasins();
            $magasinsRowset     = $magasinsTable->find($magasin->id);
            $currentMagasin     = $magasinsRowset->current();
.............

est-ce que ce code peut être mis dans le modèle ou le contrôleur et non dans la vue ? merci

Hors ligne

 

#13 14-03-2009 15:33:21

rdave
Nouveau membre
Date d'inscription: 20-01-2009
Messages: 8

Re: [Résolu][1.5] Fonctions dans une vue / findManyToManyRowset

Le problème c'est que si tu fais "findManyToManyRowset" dans un foreach ca va faire autant de requetes SQL et niveau performances c'est la galère assurée.

A mon humble avis la seule solution c'est les vues SQL. Tu fais une seule requête qui appelle ta vue qui contient toutes les données dont tu as besoins.

Hors ligne

 

#14 15-03-2009 20:17:47

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

Re: [Résolu][1.5] Fonctions dans une vue / findManyToManyRowset

ok, je vois, je connait pas très bien les "vues" en SQL , mais je vais chercher

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