Skip to content

Mappers de données (Couche de Transformation)

Les Mappers sont des classes spécialisées dont le rôle unique est de convertir des structures de données "brutes" ( objets WP_Post, tableaux ACF, réponses d'API) en objets de données typés et prévisibles appelés DTO (Data Transfer Objects).

Cette couche fait office de "traducteur" entre l'infrastructure (WordPress/Base de données) et la vue (Templates Blade).

Rôle et Responsabilités

  • Extraction : Extraire les données pertinentes de sources complexes ou imbriquées.
  • Nettoyage : Assurer des valeurs par défaut (fallback) pour éviter les erreurs null dans les vues.
  • Formatage : Transformer des formats techniques (ex: format de date, IDs d'images) en formats utilisables (ex: URLs d'images, chaînes lisibles).
  • Abstraction : Isoler les fonctions natives de WordPress (get_field, get_permalink, etc.) pour que la vue n'en dépende pas.

Structure Type d'un Mapper

Un Mapper suit généralement une structure multi-entrées pour s'adapter à toutes les situations :

php
namespace App\Mappers;

use App\Data\YourDataObject;
use App\Support\Models\BaseModel;

class ExampleMapper
{
    /**
     * Transforme un objet natif WordPress (Post, Term, User)
     */
    public function fromModel(BaseModel $post): YourDataObject
    {
        return new YourDataObject(
            title: $post->title(),
            // ... logique de mapping
        );
    }

    /**
     * Transforme un tableau associatif (ex: issu de get_field())
     */
    public function fromArray(array $data): YourDataObject
    {
        return new YourDataObject(
            title: $data['title'] ?? '',
            // ... logique de mapping
        );
    }

    /**
     * Fournit un état cohérent pour les previews ou placeholders
     */
    public function fake(): YourDataObject
    {
        return new YourDataObject(
            title: "Titre d'exemple",
        );
    }

    /**
    * YourDataObject devrait avoir une methode isNull() qui teste si le title est vide.
    * 
    * @return CardData
    */
    public function null(): YourDataObject
    {
        return new YourDataObject(
            title: "",
        );
    }
}

Intégration dans le flux de données

Le Mapper intervient généralement juste après la récupération des données par un Repository ou directement dans un Composant/Bloc.

Dans un Bloc (ACF Composer)

L'utilisation d'un Mapper dans la méthode with() permet de garder la logique de traitement hors de la vue.

php
public function __construct(public PostMapper $postMapper, public PostQueryRepository $postQueryRepository) {}
public function with()
{
    $featured = $this->postQueryRepository->featured();

    return [
        'featured' => $featured ? $this->postMapper->fromModel($featured) : $this->postMapper->null(),
    ];

Transformation de collection

Pour transformer une liste de résultats issue d'une PostQuery :

php
$posts = $postQuery->latest(5);
$postMapper = new PostMapper();
$items = collect($posts)->map(fn($post) => $postMapper->fromModel($post))->toArray();

Avantages de l'approche

AvantageDescription
RobustesseEmpêche les crashs de templates grâce au typage et aux valeurs par défaut (Null Object Pattern).
MaintenanceSi la structure d'un champ ACF change, vous ne modifiez que le Mapper, pas vos 15 fichiers Blade.
Clean CodeVos fichiers Blade sont débarrassés des fonctions PHP complexes et ne contiennent que de l'affichage.
UniformitéPlusieurs mappers peuvent retourner le même DTO (ex: un PostMapper et un SearchMapper retournent tous deux un CardData).

Bonnes pratiques

  1. Souveraineté du Data : Un Mapper doit toujours retourner un objet Data ou un tableau d'objet Data. Ne jamais retourner de tableau associatif.
  2. Pas de logique métier : Un Mapper transforme la donnée d'un Model vers un Data.
  3. Utilisation de méthodes statiques de création : Dans les DTO complexes, n'hésitez pas à utiliser des méthodes comme ImageData::fromId($id) à l'intérieur de votre Mapper pour déléguer la sous-transformation.