Mettre en place un flux XML personnalisé

Créé le 17/04/2019

Dernière mise à jour le 17/04/2019

Étiquettes

Lors du développement d'un site, il arrive parfois de devoir mettre en place un flux XML. Même si désormais c'est plutôt le format JSON qui domine, il reste des applications déjà développées qui nécessitent des données au format XML.

Avec les modules de webservices de Drupal 8, que ce soit avec le noyau ou avec des modules communautaires en compléments, il est possible d'obtenir des contenus au format XML.

Mais parfois la structure du flux XML est tellement spécifique qu'il vaut mieux faire un développement.

Voici des exemples de code permettant de générer un tel flux.

Fichier xml_feed_example.info.yml

Pour déclarer le module.

name: XML feed example
description: "Provides example to make a XML feed."
type: module
core: 8.x

Fichier xml_feed_example.module

Pour permettre d'avoir un template Twig et ainsi structurer le XML comme souhaité.

<?php

/**
 * @file
 * Contains hook implementations for xml_feed_example module.
 */

/**
 * Implements hook_theme().
 */
function xml_feed_example_theme($existing, $type, $theme, $path) {
  return [
    'xml_feed_example' => [
      'variables' => [
        'items' => [],
      ],
    ],
  ];
}

Fichier xml_feed_example.routing.yml

Pour déclarer l'URL de notre flux.

xml_feed_example.feed:
  path: '/feed.xml'
  defaults:
    _controller: '\Drupal\xml_feed_example\Controller\FeedController::feed'
  requirements:
    _permission: 'access content'

Fichier templates/xml-feed-example.html.twig

Simplifié pour l'exemple.

<?xml version="1.0" encoding="UTF-8" ?>
<datas>
  {% for item in items %}
    <data>
      <Title>{{ item.title }}</Title>
    </data>
  {% endfor %}
</datas>

Fichier src/Controller/FeedController.php

<?php

namespace Drupal\xml_feed_example\Controller;

use Drupal\Core\Cache\CacheableMetadata;
use Drupal\Core\Cache\CacheableResponse;
use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\Render\RendererInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Class FeedController.
 */
class FeedController extends ControllerBase {

  /**
   * Renderer service.
   *
   * @var \Drupal\Core\Render\RendererInterface
   */
  protected $renderer;

  /**
   * Constructor.
   *
   * @param \Drupal\Core\Render\RendererInterface $renderer
   *   The renderer service.
   */
  public function __construct(
    RendererInterface $renderer
  ) {
    $this->renderer = $renderer;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container) {
    return new static(
      $container->get('renderer')
    );
  }

  /**
   * XML feed.
   *
   * @return \Drupal\Core\Cache\CacheableResponseInterface
   *   Return the XML feed.
   */
  public function feed() {
    $items = [];
    $cache = new CacheableMetadata();

    // Adapter la récupération des données à vos besoins.
    $nodes = $this->entityTypeManager()->getStorage('node')->loadMultiple();
    foreach ($nodes as $node) {
      $cache->addCacheableDependency($node);

      $data = [];
      $data['title'] = $node->label();
      $items[] = $data;
    }

    $datas = [
      '#theme' => 'xml_feed_example',
      '#items' => $items,
    ];
    $cache->applyTo($datas);

    $content = $this->renderer->renderRoot($datas);

    $response = new CacheableResponse();
    $response->setContent($content);
    $response->addCacheableDependency($cache);
    $response->headers->set('Content-Type', 'xml');
    // Si l'on souhaite obtenir le flux sous forme de fichier téléchargé.
    //$response->headers->set('Content-Disposition', 'attachment; filename="feed.xml"');

    return $response;
  }

}

Ajouter un commentaire