Le contexte

Sur le panneau d'admin de baccalaureat.sn, je gère les logs de téléchargement des annales. Je voulais afficher deux colonnes qui ne correspondent à aucune propriété mappée de l'entité : le libellé humain de l'épreuve et un badge premium.

Le symptôme

public function configureFields(string $pageName): iterable
{
    yield TextField::new('epreuveLabel', 'Épreuve');
    yield TextField::new('isPremium', 'Premium');
}

Résultat : colonnes vides, ou exception Neither the property "epreuveLabel" nor one of the methods ... exist.

Pourquoi ça casse

EasyAdmin part du principe qu'un Field correspond à une propriété accessible via PropertyAccess. Pour un champ qui n'existe pas sur l'entité, il faut le déclarer virtuel.

La solution

yield TextField::new('epreuveLabel', 'Épreuve')
    ->setVirtual(true)
    ->formatValue(fn ($value, $entity) => sprintf(
        '%s — %s (%s)',
        $entity->getMatiere(),
        $entity->getSerie(),
        $entity->getAnnee()
    ));

Pour un rendu HTML, un template dédié :

yield TextField::new('isPremium', 'Premium')
    ->setVirtual(true)
    ->setTemplatePath('admin/field/premium_badge.html.twig');
{% if entity.instance.account and entity.instance.account.isPremium %}
    Premium
{% else %}
    Gratuit
{% endif %}

Point qui m'a coûté une heure : dans un template de champ EasyAdmin, l'entité réelle est sous entity.instance, pas entity.

Ce que je retiens

  • setVirtual(true) dès qu'un champ ne correspond pas à une propriété Doctrine.
  • formatValue() reçoit ($value, $entity) — pratique pour composer une valeur.
  • Dans les templates de champ : entity.instance pour l'objet.