Newsgroup: it.comp.www.php
Titolo: [MVC-long3d] Forse qualcosa non l'ho proprio capita

Se qualcuno ha tempo (e voglia), potrebbe illuminarmi su qualche
concetto mvc?
Allora, ammettiamo di avere una situazione molto semplice,
un'applicazione dove gli utenti si gestiscono i loro documenti, che
sò, delle todo list.
Quindi, mi faccio la mia classe che gestisce i dati, cioè il model; Si
occuperà di reperire i dati, nient'altro: se sono in memcached li
prende da li, se no dal db, quindi tutti i dati relativi a memcached e
db sono in questa classe, che con uno sfarzo di fantasia chiamerò
MyData().
Poi ho una classe controller, MyRoute(), che analizza la richiesta get
e ne estrapola le variabili, esempio se l'url è
/user/add-document/
MyRoute avrà le proprietà subject = user e action = add-document, se
l'url è
/user/edit-document/4
subject = user, action = edit-document, args = 4 (l'id del documento)
La classe View non è un problema, non fà altro che gestire i templates
e renderizzarli per stamparli a video.
Per complicarmi un pò le cose la classe vista controlla anche se la
richiesta proviene da ajax e in tal caso carica i template che, invece
che html, stampano json, e fin qui tutto ok.
Il mio problema è come strutturare le classi degli 'oggetti', cioè
utenti e documenti (che, correggetemi se sbaglio, dovrebbero essere
classi controller e non model).. cosa deve fare e cosa non deve fare
esattamente la classe User e Document?
Esempio: devo creare un nuovo documento.
La classe Document, quindi, io la imposterei più o meno così:
$document = new Document(false);
$form = new Form('new-document');
$form->loadForm();
$form->validate();
if($form->is_valid === true){
    $document->add($form);
}
Ah già, ho anche la classe Form, ma è un banalissimo controller che
legge la definizione di un form da un file json, con render() lo
stampa in html, con validate() controlla che tutti i field siano
corretti in base ai loro attributi (obbligatorio o meno, valore in
ingresso che ci si aspetta, etc..)
Cioè, ammettiamo che ho l'esigenza che ogni documento deve avere un
codice (non l'id, ma un codice alfanumerico) univoco, e ammettiamo che
l'utente me lo deve scrivere a mano.
La classe Form si preoccupa solo che il campo 'codice' non sia vuoto,
non contenga caratteri non permessi, e sia della lunghezza
prestabilita.
Il controllo a db che non sia già presente un documento con lo stesso
codice, lo devo fare nella classe User ma passando dal model MyData,
giusto?
Quindi in Document() avrò un metodo del tipo
private function checkCode(){
    $codice_ok = $this->mydata->checkCode($this->codice);
    if($codice_ok){
        echo "codice già in uso";
        return false;
    }else{
        return true;
    }
}
E in MyData avrò qualcosa del tipo
public function checkCode($code){
     $r = $this->db->query("SELECT id FROM documenti WHERE codice =
$code");
     if($r->numRows() == 0){
         return true;
     }else{
         return false;
    }
}
giusto?
Inoltre, se devo visualizzare l'elenco dei documenti, è consigliabile
creare un'altro controller ListDocuments() o creare un'istanza di
Document nel controller principale?

 tutto ok.
OK, chiami template quello che altri chiamano view, ma non e` un 
problema. La tua classe View e` piu` che altro un motore di templating. :)
 
Il resto l'ho tagliato perche` era appunto basato su concetti errati.
Bye.

 Il resto l'ho tagliato perche` era appunto basato su concetti errati.
ok, solo una cosa: per il discorso delle 'liste' o insiemi di
documenti?
La pratica standard è creare altri metodi, cioè UserListController,
UserListModel, DocumentListController, etc..?
Qui sono molto confuso.
Non voglio avere classi indipendenti, appunto per non avere metodi
rindondanti che, se un domani aggiungo una funzione agli utenti, devo
modificare 2 controller e due model.
Però, non voglio neanche avere un controller che genera n istanze del
UserController, perchè caricare tutte le proprietà di un utente quando
invece, per stampare la lista degli utenti, me ne servono solo tre
(mettiamo nome, cognome, email ad esempio).
Se devo stampare una lista con 50 utenti, non voglio avere 50 istanze
'complete' che mi caricano tutti i dati (nome, cognome, email,
telfono, vita, morte e miracoli) per poi utilizzarne neanche la metà.
Che dici, in UserController creo i metodi loadUserData() e
loadUserDataLight() (o loadUserDataForList())?
Bho, ideologicamente un user e una lista di user sono due cose diverse
e dovrei tenerli separati, ma lavorano sullo stesso oggetto e vorrei
evitare di duplicare le cose inutilmente.

 loadUserDataLight() (o loadUserDataForList())?
Io ci creerei le azioni showUserList(), showUser(), alterUser(), 
createUser(), deleteUser()
Perche` fare un controller solo per showUserList()? Lavori sempre e 
comunque sugli stessi tipi di dati, e la volta che vorrai permettere di 
cancellare una lista di utenti potrai implementare deleteUsers() che 
lavora su un array di User.
Non credo capiti spesso di dover cancellare tutta la lista degli utenti, 
ma nel caso, puoi implementare deleteUserList()
Capisco che ci stai sbattendo il naso volontariamente per imparare e 
capire "the hard way", ma io ti consiglierei, se non di passare 
direttamente a un framework, almeno di leggere un po' di tutorial sui 
vari framework, cosi` ti fai un'idea di come implementano certe idee.
Dopo potrai implementare il tuo per cercare di capire perche` sono state 
fatte certe scelte e non altre, ma almeno parti da una base solida di 
qualcosa gia` implementato, testato e funzionante.
 
Bye.