PHPBlog.it

symfony: moduli e azioni

SymfonyQuesta volta si inizia davvero con il codice PHP. Passiamo quindi realmente alla pratica dopo le prime puntate di introduzione del progetto.

Iniziamo generando tre moduli per la nostra applicazione frontend:

php symfony generate:module frontend forum
php symfony generate:module frontend thread
php symfony generate:module frontend user

Questo creerà tre directory all’interno di apps/frontend/modules/, contenenti a loro volta le cartelle template e actions.

Ora apriamo il file apps/frontend/config/routing.yml e modifichiamolo per renderlo come segue:

homepage:
  url:   /
  param: { module: forum, action: index }

view_forum_by_id:
  url:   /view-forum/:id
  param: { module: forum, action: viewById }
  requirements: { id: \d+ }

view_forum_by_title:
  url:   /view-forum/:title
  param: { module: forum, action: viewByTitle }

Questo file spiega le regole di routing che la nostra applicazione dovrà seguire. Ad ogni regola corrisponde un nome (hompage, view_forum_by_id, e view_forum_by_title) seguita da un pattern per l’url a cui la regola dovrà sottostare, dai parametri della regola, ed eventualmente da dei requisiti a cui i parametri devono corrispondere.
Prendiamo per esempio la regola view_forum_by_id: deve avere un url che “matchi” il pattern /view-forum/:id, ovvero deve iniziare con uno slash, la stringa view-forum, un altro slash e una variabile id (distinta dai due punti :). Nella sezione param indichiamo che nel caso l’url corrisponda a questa regola, symfony deve richiamare il modulo forum e l’azione viewById.
Con requirements poi, restringiamo il valore di id ai soli interi, tramite la notazione \d+ (vedasi espressioni regolari).

Le regole sono in ordine di priorità, quindi la prima che combacia con l’url richiesto sarà quella applicata.
Per questo è opportuno lasciare alla fine del file le regole predefinite

default_symfony:
  url:   /symfony/:action/*
  param: { module: default }

default_index:
  url:   /:module
  param: { action: index }

default:
  url:   /:module/:action/*

In modo che in ogni caso di trovi qualche corrispondenza.

Ora modifichiamo il file apps/frontend/modules/forum/actions/actions.class.php, cerchiamo il metodo executeIndex e al posto del forward pre-inserito scriviamo noi questo:

  $this->redirect('@view_forum_by_id?id=1');

In questo modo effettuiamo un redirect, con destinazione la regola view_forum_by_id (specificata dalla presenza della @ prima del nome), assegnando ad id il valore 1. Il forum con id 1 è quello pre-definito, che è padre di tutti i sotto-forum.

Andiamo ora oltre, e aggiungiamo i seguenti metodi:

public function executeViewByID()
{
    // Retrieves data using the forum id
    $forumID = $this->getRequest()->hasParameter('id') ? $this->getRequest()->getParameter('id') : 1;
    $this->forum = ForumPeer::retrieveByPk($forumID);
    $this->forward404Unless($this->forum);

    $this->findData($forumID);

    // Set a common template
    $this->setTemplate('view');
}
public function executeViewByTitle()
{
    // Retrieves data using the forum title
    $forumTitle = $this->getRequest()->hasParameter('title') ? $this->getRequest()->getParameter('title') : 'Main';
    $c = new Criteria();
    $c->add(ForumPeer::TITLE, $forumTitle);
    $this->forum = ForumPeer::doSelectOne($c);
    $this->forward404Unless($this->forum);
    $forumID = $this->forum->getId();

    // Executes a common function for addictional infos
    $this->findData($forumID);

    // Set a common template
    $this->setTemplate('view');
}
private function findData($forumID)
{
    $c = new Criteria();
    $c->add(ForumPeer::PARENT_ID, $forumID);
    $this->childs = ForumPeer::doSelect($c);
    $c = new Criteria();
    $c->add(ThreadPeer::FORUM_ID, $forumID);
    $this->threads = ThreadPeer::doSelect($c);
}

In symfony i metodi che iniziano con execute, e sono seguiti da un nome (la cui prima lettera maiuscola) sono delle azioni richiamabili dal browser. In questo caso executeViewByID ed executeViewByTitle sono due azioni valide, mentre findData è un metodo richiamato dai due per eseguire del codice in comune, quindi non è un azione, e lo si dichiara privato e senza la keyword execute.

Ora andiamo a vedere nel dettaglio ciò che accade nelle azioni:

1    $forumID = $this->getRequest()->hasParameter('id') ? $this->getRequest()->getParameter('id') : 1;
2    $this->forum = ForumPeer::retrieveByPk($forumID);
3    $this->forward404Unless($this->forum);

4    $this->findData($forumID);

5    $this->setTemplate('view');

Riga 1
Espressione ternaria: se l’oggetto request ha il parametro id, allora assegniamo a $forumID quel valore, altrimenti assegniamo 1 (il valore di default).
Riga 2
A $this->forum assegniamo il risultato della ricerca tramite chiave primaria (metodo statico retrieveByPk, ovvero Primary Key) con valore $forumID sull’oggetto ForumPeer, ovvero la rappresentazione della tabella (l’oggetto Forum, a cui appartiene $this->forum è la rappresentazione della singola tupla).
Riga 3
Redirezioniamo l’elaborazione ad una pagina di 404 a meno che $this->forum non abbia un valore valido.
Riga 4
Richiamiamo il metodo findData, che esegue un’elaborazione in comune ai due viewBy*.
Riga 5
I due viewBy* utilizzando lo stesso template, quindi tramite questa istruzione assegno a quest’azione il template view.

Ora nel metodo privato findData

1    $c = new Criteria();
2    $c->add(ForumPeer::PARENT_ID, $forumID);
3    $this->childs = ForumPeer::doSelect($c);
4    $c = new Criteria();
5    $c->add(ThreadPeer::FORUM_ID, $forumID);
6    $this->threads = ThreadPeer::doSelect($c);

Riga 1
Creiamo una nuova istanza della classe Criteria, ovvero la classe utilizzata per realizzare le query.
Riga 2
Specifichiamo che il valore di forums.parent_id (rappresentato dalla costante ForumPeer::PARENT_ID) deve valere $forumID
Riga 3
All’array $this->childs assegniamo tutte le corrispondenze della query preparata
Riga 4,5,6
Stesso significato delle precedenti, solo che al posto di ottenere i forum “figli” ottengo i thread appartenenti a quel forum

Oggi abbiamo visto le azioni di base, la prossima volta (per non appesantire troppo il post) vedremo il template associato a queste azioni, più alcune cose sulla gestione dell’utente.
Per eventuali dubbi ci sono i commenti, sarò felice di rispondere, quindi non siate timidi. :-) Alla prossima!

Commenti

  • Questo articolo è stato segnalato su ZicZac.it….

  • Lascia un Commento

    *