Newsgroup: it.comp.www.php
Titolo: Zend Framework viste "innestate"

ciao,
ho un grande dubbio sulle viste di ZendFramework (ma è applicabile a 
qualsiasi framework mvc)
Se ho due tabelle tra loro collegate da una relazione uno a molti tipo 
Persone -> automobili dove ogni persona puo' avere N auto, come faccio 
la vista della tabella che mostra tutte le persone con le relative auto?
In ZF farei:
model/persona
model/auto
PersonaController
AutoController
e le varie viste
views/scripts/persona/index.phtml
views/scripts/auto/index.phtml
ecc ecc.
Ora, nel metodo index di AutoController avro' qualcosa del tipo:
$p = new Persona();
$this->view->persone = $p->fetchAll();
e nella relativa vista views/scripts/persona/index.phtml
foreach ($this->persone as $persona)
   echo $persona->nome
   .....
Ma se adesso volessi mostrare di fianco ad ogni persona (quindi nella 
stessa pagina) la lista delle sue auto come devo fare?
Io ho creato nel controller auto la funzione getAutoPersona($id_pers) 
che dato un id_persona mi ritorna la lista delle sue auto formattata 
opportunamente attraverso la vista get-auto-persona. E questo funziona 
correttamente quando voglio vedere la lista delle auto di una persona in 
   una singola pagina.
Il problema è che non so come fare nel controller di Persona a 
richiamare per ogni persona la lista delle sue auto e assegnarla alla 
vista. Sempre ammesso che sia il controller di Persona il posto giusto 
dove fare questo.
Per ora ho fatto cosi':
Nella vista di views/scripts/persona/index.phtml
ho messo
foreach ($this->persone as $persona)
   {
   echo $persona->nome
   $a = new Auto();
   $lista_auto = $a->fetchAll($persona->id_pers);
   foreach ($lista_auto as $auto)
     {
     // stampo tutte le caratteristiche della auto che mi interessano
     }
   }
Ma ovviamente non è il posto giusto dove mettere questo tipo di codice 
direi .... vero?
Sperando di essermi spiegato ringrazio già chiunque sia in grado di 
darmi una indicazione sul modo migliore di procedere.

 la vista della tabella che mostra tutte le persone con le relative auto?
Hai due possibilita` (forse di piu` :)
La prima e` di lasciare il controller attuale che ti genera il pezzo di 
view (solo la ul e relativi li), e richiamarlo tramite $this->action() 
dalla view.
I vantaggi sono che isoli di piu` la generazione della lista, e quindi 
puoi usarla pari pari anche in altre viste o per richiedere la stessa 
lista via AJAX.
Lo svantaggio e` che e` una vista parziale, quindi se l'utente richiama 
quella action direttamente vede la lista senza l'html intorno, quindi 
niente foglio di stile o javascript inclusi nell'header, ecc. ecc.
Uno svantaggio di poco conto, secondo me, visto che l'utente non dovrebbe 
nemmeno sapere che c'e` questa action.
La seconda possibilita`, che non esclude la prima ma anzi andrebbe 
integrata, e` di creare un model anche per la riga di DB.
Per questo io di solito chiamo PersonaList la classe "tabella" (extends 
Zend_Db_Table) e Persona la classe "riga" (extends Zend_Db_Table_Row).
Quindi configuri PersonaList per usare Persona come "oggetto riga" nelle 
query (basta un protected $_rowClass="Persona" tra gli attributi), e nella 
classe Persona crei un metodo getAllAutos() (o simile) che contiene 
praticamente questo (personalizzabile a piacere con order e altro):
public function getAllAutos()
{
 $autolist = new AutoList();
 $select = $autolist->select()
  ->where("proprietario = ?", $this->id)
 ;
 return $autolist->fetchAll($select);
}
Nella view (o nel controller) poi ti bastera` usare
foreach ($persona->getAllAutos() as $auto) {
 echo $auto->modello;
}
Il vantaggio e` evidente :) Inglobi nel model le operazioni di cui si deve 
occupare il model (e non il controller): recuperare informazioni relative 
al model stesso.
Lo svantaggio e` che crei un legame piu` stretto tra Persona e Auto 
(Persona da` per scontato che esista una classe AutoList e non puo` 
"vivere" senza), e per alcuni estremisti della OOP e` una cosa da evitare 
il piu` possibile. :)
Secondo me invece fa parte della logica dell'applicazione ed e` il modo 
piu` veloce di procedere, pur rispettando i ruoli.
Bye.

 piu` veloce di procedere, pur rispettando i ruoli.
Yes, concordo !
Grazie ancora
ciao
Mauro
P.S.
Cercando una soluzione mi ero imbattuto anche nell'utilizzo di 
findDependentRowset che dalla descrizione sembrava fare al caso mio, ma 
non sono riuscito ancora ad applicare. Tu per caso lo conosci?

 non sono riuscito ancora ad applicare. Tu per caso lo conosci?
Ho letto il pezzo di manuale credo una decina di volte e non ho ancora 
capito bene come sfruttarlo al meglio.
Mi trovo piu` a mio agio costruendo le select a mano, soprattutto quando 
devo incrociare 3 o piu` tabelle.
In teoria ci sarebbero anche delle funzioni "implicite" tipo 
getAutobyPersona() che non serve definire ma che il fw interpreta da solo, 
ma nemmeno queste le ho mai capite benissimo. :)
Bye.