mercoledì 28 ottobre 2009

Lyra, visualizzazione commenti articolo

Quando abbiamo generato i dati di prova per lo sviluppo ed il test iniziale dell'applicazione (symfony, creazione dati di prova (fixtures)), si sono inclusi alcuni record di commenti legati agli articoli. Non è stata per ora scritta alcuna funzione di visualizzazione di questi dati ed è il momento di provvedere.

La gestione dei commenti sarà integrata nel cms, le funzionalità minime che dovranno essere previste sono almeno le seguenti:

  • attivazione e disattivazione dei commenti su singoli articoli o categorie (etichette);
  • possibilità di limitare solo agli utenti registrati l'inserimento dei commenti o consentirlo anche agli utenti anonimi;
  • pubblicazione automatica o moderazione dei commenti;
  • protezione da spam tramite captcha o altre misure anti-robot sul modulo di inserimento commenti;
  • filtri contro i contenuti o link indesiderati nei commenti;
  • notifiche dell'inserimento / approvazione di un commento;
  • possibilità di ricevere i commenti inseriti su un articolo / categoria via e-mail o feed.

La lista può non essere completa. Chiaramente non tutto può essere sviluppato adesso, quindi inizieremo con le funzioni di visualizzazione.

Poiché la lista dei commenti viene visualizzata quando l'articolo è a tutta pagina dovremo intervenire sul codice dell'azione show del modulo article ed il relativo template (showSuccess.php), mentre la funzione per estrarre dal database la lista dei commenti relativi ad un determinato articolo deve essere implementata in una classe del modello.

Azione

apps/frontend/modules/article/actions/actions.class.php

class articleActions extends sfActions
{
...
  public function executeShow(sfWebRequest $request)
  {   
    ...
    $this->comments = $this->item->getActiveComments();
  }
...
} // fine class articleActions

$this->item contiene il record articolo da visualizzare ritornato dal metodo find() nella parte del codice che ho omesso e che abbiamo visto in Lyra, visualizzazione articolo.

Modello

LyraArticle

lib/model/doctrine/LyraArticle.class.php

class LyraArticle extends BaseLyraArticle
{
...
  public function getActiveComments()
  {
    return $this->getActiveCommentsQuery()
      ->execute();
  }
  protected function getActiveCommentsQuery()
  {
    $q = Doctrine::getTable('LyraComment')
      ->getActiveItemsQuery();

    $q->andWhere($q->getRootAlias() .'.article_id = ?', $this->getId());
      
    return $q;
  }
} // fine classe LyraArticle

LyraCommentTable

lib/model/doctrine/LyraCommentTable.class.php

class LyraCommentTable extends Doctrine_Table
{
  public function getActiveItemsQuery() {
    $q = $this->createQuery('c');

    $q->andWhere('c.is_active = ?', true);
    $q->addOrderBy('c.created_at DESC');

    return $q;
  }
}

La query SQL per la selezione dei commenti da visualizzare viene generata da due classi: LyraCommentTable genera la parte che seleziona i commenti pubblicati (campo is_active è true) e imposta il criterio di ordinamento, LyraArticle aggiunge un criterio di selezione basato sull'ID articolo.

Sembrano troppi metodi per costruire una query semplice, ma il fatto è che non resterà così semplice: dovranno necessariamente essere previste delle condizioni di visualizzazione e dei criteri di selezione e ordinamento dei commenti dipendenti da parametri di configurazione. Ad esempio:

  • la configurazione articoli dovrà prevedere la possibilità di disattivare la visualizzazione dei commenti su un singolo articolo;
  • la configurazione commenti dovrà consentire di impostare diversi criteri di ordinamento in aggiunta all'ordinamento per data discendente fisso come adesso.

Mi sembra opportuno che la prima condizione sia verificata in LyraArticle e il secondo parametro impostato in LyraCommentTable: tra tutte le condizioni che determinano la visibilità e l'aspetto della lista dei commenti ogni classe gestisce quelle che dipendono dall'oggetto che le compete. Almeno al momento mi torna bene fatto così, se mi sbaglio ci sarà il tempo di correggere.

Template

apps/frontend/modules/article/templates/showSuccess.php
...
<?php
if(count($comments)) {
  include_partial('article/comments', array('comments'=>$comments));
}
?> // fine showSuccess.php

Per visualizzare i commenti si utilizza un partial, ormai ne abbiamo incontrati diversi negli articoli precedenti.

apps/frontend/modules/article/templates/_comments.php

<?php use_helper('Date');?>
<h2 id="comments"><?php echo __('HEAD_COMMENTS') ?></h2>
<?php foreach($comments as $comment):?>
<div class="comment-wrapper">
<div class="comment-header">
  <?php
  $author = $comment->getAuthorName();
  if($comment->getAuthorUrl()) {
    $author = link_to($author, $comment->getAuthorUrl());
  }
  echo __('COMMENT_HEADER',
    array(
      '%name%'=>'<span class="author">' . $author . '</span>',
      '%date%'=>'<span class="date">' . format_date($comment->getCreatedAt(),'dd MMMM yyyy') . '</span>',
      '%time%'=>'<span class="time">' . format_date($comment->getCreatedAt(),'HH:mm') . '</span>'
    ));
  ?>
</div>
<div class="comment-content"><?php echo $comment->getContent()?></div>
</div>
<?php endforeach;?>

L'unica cosa rilevante da notare è l'uso della funzione helper per la traduzione (__()) per creare l'intestazione del commento, la riga che contiene autore, data ed eventuale link al sito web dell'autore. È la prima volta che ne vediamo l'uso con parametri (%name%, %date%, %time%). Nel file di lingua abbiamo:

apps/frontend/i18n/it/messages.xml

...
  <trans-unit id="20">
    <source>COMMENT_HEADER</source>
    <target>%name% il %date% alle %time%</target>
  </trans-unit>
...

Che produce questa intestazione.

L'uso di una costante nel file di lingua oltre che alla traduzione serve a modificare l'intestazione senza toccare il codice. Ad esempio modificando COMMENT_HEADER in questo modo

  <trans-unit id="20">
    <source>COMMENT_HEADER</source>
    <target>il %date% alle %time% %name% ha scritto</target>
  </trans-unit>

avremo questo risultato.

Sono state necessarie anche modifiche al file web/css/main.css per inserire le classi necessarie alla formattazione dei commenti. I dettagli sono su Google Code (revisione 14) come del resto tutto il codice riportato sopra. La prossima volta creeremo il form per l'inserimento di un commento.

Nessun commento:

Posta un commento

Nota. Solo i membri di questo blog possono postare un commento.