Customiser un flux Atom ou Rss avec Zend_Feed_Writer

logo-zend-frameworkSuite de notre aventure dans la jungle de Zend_Feed_Writer. Maintenant qu’on sait faire un flux standard, nous allons le modifier quelque peu.

Reprenons l’exemple:

<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title type="text">Titre</title>
  <link rel="self" type="application/atom+xml" href="/"/>
  <id>Ze Id</id>
  <entry>
    <title>entrée</title>
    <link rel="alternate" type="text/html" href=""/>
  </entry>
</feed>

Pour obtenir la balise link, en vert, nous nous sommes servi de $f->setFeedLink(‘/’,’atom’); Cette fonction a pour effet d’ajouter l’url en paramètre au conteneur ($_data[‘feedLinks’]).

Voilà qui est bien mais comment faire si l’on souhaite changer le type ou l’attribut rel, voire même ajouter un attribut?

Contexte

Lors de l’export atom par exemple, le moteur va lancer le rendu de toutes les balises standards via les méthodes appropriées (voir dans la classe Zend_Feed_Writer_Renderer_Entry_Atom). Ces méthodes vont chercher l’information dans le conteneur de données ($_data) et créer les élements XML qui vont bien.
Pour modifier des balises ou des attributs, Zend_Feed_Writer fait alors appel à des extensions. Il y a les extensions pour le conteneur et celles pour le rendu.
Le rendu des extensions est demandé une fois que le rendu standard est terminé.

Il existe un certains nombre d’extensions disponibles dans le framework pour les specifications les plus connues : Content, DublinCore, Itunes, Slash, Threading et WellFormedWeb.

Imaginons que nous souhaitons créer une extension pour ajouter le support des spécifications Open Publication Distribution System. Il est dit dans cette spec que l’attribut type du tag <link rel=self> doit être

application/atom+xml;profile=opds-catalog;kind=navigation

Nouvelle extension

Sous le répertoire library du projet, créer l’arborescence et un fichier Opds/Feed/Writer/Extension/Opds/Renderer/Feed.php

Créer la classe de cette façon

<?php
/**
 * @see Zend_Feed_Writer_Extension_RendererAbstract
 */
require_once 'Zend/Feed/Writer/Extension/RendererAbstract.php';

class Opds_Feed_Writer_Extension_Opds_Renderer_Feed
    extends Zend_Feed_Writer_Extension_RendererAbstract
{
    /**
     * Set to TRUE if a rendering method actually renders something. This
     * is used to prevent premature appending of a XML namespace declaration
     * until an element which requires it is actually appended.
     * @var bool
     */
    protected $_called = false;

    /**
     * Render feed
     * @return void
     */
    public function render()
    {
        if (strtolower($this->getType()) != 'atom') {
            return;
        }
        $this->_setFeedLinks($this->_dom, $this->_base);
        if ($this->_called) {
            $this->_appendNamespaces();
        }
    }

    /**
     * Append namespaces to feed element
     *
     * @return void
     */
    protected function _appendNamespaces()
    {
        $this->getRootElement()->setAttribute('xmlns:opds',
            'http://opds-spec.org/2010/catalog');
    }

    /**
     * Set feed link elements
     *
     * @param  DOMDocument $dom
     * @param  DOMElement $root
     * @return void
     */
    protected function _setFeedLinks(DOMDocument $dom, DOMElement $root)
    {
        $links = $root->getElementsByTagName('link');
        foreach ($links as $link) {
            if ($link->getAttribute('rel') == 'self') {
                $mime  = 'application/atom+xml;profile=opds-catalog;kind=navigation';
                $link->setAttribute('type', $mime);
            }
        }
        $this->_called = true;
    }
}

Le point d’entrée est la méthode render(), c’est elle qui est appelée pour chaque extension.
C’est _setFeedLink qui va ensuite modifier l’attribut « type » de l’élement.
_called permet de savoir si au moins une fonction de l’extension a été appelée et, le cas échéant, ajoute l’espace de nom correspondant à la spécification via _appendNamespaces().

Enregistrement de l’extension

Pour que la méthode render soit appelée automatiquement, il faut enregistrer l’extension.
Dans le contrôleur, ajouter  dans la méthode init() les instructions:

Zend_Feed_Writer::addPrefixPath('Opds_Feed_Writer_Extension', 'Opds/Feed/Writer/Extension');
Zend_Feed_Writer::registerExtension('Opds');

Résultat

Si tout va bien, le résultat devrait être:

<link rel="self" type="application/atom+xml;profile=opds-catalog;kind=navigation" href="/"/>

De la même façon, on peut ajouter des tags non standards en utilisant une extension de conteneur et une extension de rendu.

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *