Dans un précédent billet, nous avons vu comment créer un weblog basique avec l'admin-generator de Symfony. Nous allons reprendre là où nous en étions et ajouter la liste des commentaires à notre back-office de gestion des billets grâce à un simple appel de composant, qui n'est autre qu'un template partiel associé à un contrôleur dédié.

Création du module de gestion des commentaires en back-office

Si ce n'est déjà fait, on crée notre module de gestion des commentaires

# symfony propel-init-admin back comments Comment

Création du composant qui va lister les commentaires d'un billet

Bien. On va maintenant créer un composant postcomments qui affichera la liste des commentaires associés à un objet Post, en créant un nouveau fichier apps/back/modules/posts/actions/components.class.php et en y insérent le contenu ci-dessous :

<?php
class postsComponents extends sfComponents 
{
  
  /**
   * List comments for a given Post
   * 
   */
  public function executePostcomments()
  {
    $post_id = $this->getRequestParameter('id');
    if (!is_null($post_id))
    {
      $c = new Criteria();
      $c->add(CommentPeer::POST_ID, $post_id);
      $c->addDescendingOrderByColumn(CommentPeer::CREATED_AT);
      $this->comments = CommentPeer::doSelect($c);
    }
  }
  
}

On crée maintenant le template partiel associé au contrôleur, dans le fichier apps/back/modules/posts/templates/_postcomments.php :

<?php if (isset($comments)): ?>
  <?php if (count($comments) > 0): ?>
    <?php use_helper('Comment', 'Text') ?>
    <dl>
    <?php foreach ($comments as $comment): ?>
      <dt>
        <?php echo sprintf('Posté le <strong>%s</strong> par <strong>%s</strong> :', 
                           format_date($comment->getCreatedAt(), 'd/MM/yyyy à H:m'),
                           format_comment_author($comment->getAuthor(),
                                                 $comment->getSite())) ?>
      </dt>
      <dd>
        <?php echo simple_format_text($comment->getContent()) ?>
      </dd>
      <dd>
        [<?php echo link_to('Éditer', 'comments/edit?id='.$comment->getId()) ?>]
        [<?php echo link_to('Supprimer', 
                            'comments/delete?id='.$comment->getId(),
                            'confirm=Êtes-vous sûr ?') ?>]
      </dd>
    <?php endforeach; ?>
    </dl>
  <?php else: ?>
    <p>No comment yet.</p>
  <?php endif; ?>
<?php endif; ?>

Utilisation d'un helper pour des tâches courantes de templating

La fonction format_comment_author est un helper maison, que nous définissons dans un nouveau fichier lib/helper/CommentHelper.php :

<?php
/**
 * Returns a formatted html string for author including website link if any
 * 
 * @param  string   $name
 * @param  string   $site
 * @param  boolean  $nofollow
 * @return string 
 */
function format_comment_author($name, $site=null, $nofollow=true)
{
  if (!is_null($site) && preg_match('/^http/i', $site))
  {
    return sprintf('<a href="%s"%s>%s</a>', 
                   $site, 
                   $nofollow === true ? ' rel="nofollow"' : '',
                   $name);
  }
  else
  {
    return $name;
  }
}

Mise à jour du back-office de gestion des billets

Ceci fait, modifions le fichier de configuration du back-office d'administration des billets créé précemment et situé dans le fichier apps/back/modules/posts/config/generator.yml, afin d'appeller notre nouveau composant postcomments pour la vue d'édition d'un billet :

  [...]

    # Customisation du formulaire d'ajout/édition
    edit:
      
      [...]

      # Affichage d'une sélection de champs
      display:         [author_id, title, excerpt, body, post_sections, ~postcomments]

Vous noterez le caractère ~ précedant le nom du composant : encore une convention Symfony qui nous simplifie la vie :)

Gestion de l'échappement

Vous avez tous déjà entendu parler des failles XSS ? Pour nous en prémunir partiellement, nous allons activer l'échappement automatique des contenus passés à une vue, en ajoutant ces directives dans le fichier apps/back/config/settings.yml :

all:
  .settings:
    escaping_strategy: both
    escaping_method:   ESC_ENTITIES

Ainsi, dans notre cas toutes les chaînes seront échappées en entités HTML pour plus de sécurité. Pour plus d'information, rendez-vous dans la section dédiée de la documentation officielle.

Au final, voici ce que ça donne quand on édite un billet :

Affichage des commentaires d'un billet

Champs virtuels

Notre liste de billets, pour l'instant, ne nous informe pas pour chacun le nombre de commentaires associés. On va y remédier simplement en créant un getter ad-hoc dans notre objet de donnée Post et en appellant le champs virtuel associé. Dans le fichier lib/model/Post.php, on rajoute la méthode suivante :

public function getCommentsNumber()
  {
    return $this->countComments();
  }

Et dans le fichier apps/back/modules/posts/config/generator.yml, on affiche le champs virtuel comments_number dans la vue en liste :

  [...]

    # Customisation des colones de la vue en liste
    list:
      display:         [=title, excerpt, Author, comments_number, created_at, updated_at]

Voici ce que ça donne :

Liste des billets, avec nombre de commentaires associés

En conclusion

Voila, notre application prend forme doucement. On pourrait passez des heures à ajouter des détails par-ci par-là, mais je vous laisse le faire en compagnie de la documentation :)