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 :
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.
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 :
$posts = $postQuery->latest(5);
$postMapper = new PostMapper();
$items = collect($posts)->map(fn($post) => $postMapper->fromModel($post))->toArray();Avantages de l'approche
| Avantage | Description |
|---|---|
| Robustesse | Empêche les crashs de templates grâce au typage et aux valeurs par défaut (Null Object Pattern). |
| Maintenance | Si la structure d'un champ ACF change, vous ne modifiez que le Mapper, pas vos 15 fichiers Blade. |
| Clean Code | Vos 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
- Souveraineté du Data : Un Mapper doit toujours retourner un objet
Dataou un tableau d'objetData. Ne jamais retourner de tableau associatif. - Pas de logique métier : Un Mapper transforme la donnée d'un
Modelvers unData. - 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.