Le WordPress d'aujourd'hui, décodé pour les développeurs

IA & MCP

execute_callback d’une ability : où vit vraiment l’action déclenchée par l’agent

Un développeur qui découvre l'Abilities API cherche où brancher la logique métier réelle d'une capacité déclarée. Le champ execute_callback est cette fonction, à ne jamais confondre avec permission_callback qui décide seulement si elle a le droit de s'exécuter.

Par WordPress Développement • 30 septembre 2026 • 4 min de lecture • Aucun commentaire
execute_callback d'une ability : où vit vraiment l'action déclenchée par l'agent

Un développeur qui découvre l’Abilities API de WordPress pour la première fois, après avoir lu qu’une ability se déclare avec wp_register_ability(), se pose une question simple : parmi les champs de configuration, lequel exécute réellement l’action que l’agent a demandée ? La réponse est execute_callback, mais la confusion la plus fréquente observée en revue de code ne porte pas sur son existence, plutôt sur son rôle exact face à son voisin immédiat, permission_callback.

Ce que fait execute_callback, précisément

Le champ execute_callback reçoit un callable PHP, appelé avec les arguments fournis par l’agent une fois validés contre le schéma d’entrée de l’ability. C’est cette fonction, et uniquement elle, qui contient la logique métier réelle : créer un article, modifier une commande, envoyer un message.

wp_register_ability( 'wpmoderne/programmer-article', array(
    'label'               => __( 'Programmer un article', 'wpmoderne' ),
    'description'         => __( 'Programme la publication d’un article à une date future.', 'wpmoderne' ),
    'input_schema'        => array(
        'type'       => 'object',
        'properties' => array(
            'post_id' => array( 'type' => 'integer' ),
            'date'    => array( 'type' => 'string' ),
        ),
        'required'   => array( 'post_id', 'date' ),
    ),
    'execute_callback'    => 'wpmoderne_programmer_article',
    'permission_callback' => 'wpmoderne_peut_programmer',
) );

function wpmoderne_programmer_article( array $input ): array {
    $result = wp_update_post( array(
        'ID'          => $input['post_id'],
        'post_status' => 'future',
        'post_date'   => $input['date'],
    ), true );

    return array( 'updated' => ! is_wp_error( $result ) );
}

Cette fonction reçoit un tableau déjà conforme au schéma déclaré ; elle n’a pas à revérifier les types ni la présence des champs requis, ce travail relevant du schéma d’entrée traité en amont, pas de cette fonction elle-même.

Ce que permission_callback fait avant lui

L'essentiel à retenir : execute_callback est la fonction réellement appelée quand un agent invoque une ability, une fois la permission validée ; permission_callback est évalué avant execute_callback et peut bloquer son exécution sans jamais l'atteindre ; Confondre les deux fait qu'un développeur place par erreur une vérification de droits dans la fonction qui ne devrait exécuter que l'action

Avant qu’execute_callback ne soit jamais appelé, le registre évalue permission_callback, une fonction distincte qui retourne un booléen ou un objet WP_Error, chargée uniquement de décider si l’appelant a le droit de déclencher cette ability :

function wpmoderne_peut_programmer( array $input ): bool {
    return current_user_can( 'edit_post', $input['post_id'] );
}

Si cette fonction renvoie faux, execute_callback n’est jamais invoqué : l’action métier reste entièrement à l’abri d’un appelant non autorisé, sans qu’une seule ligne du code de programmation d’article n’ait à se préoccuper de qui a le droit de faire quoi.

Un execute_callback qui vérifie lui-même les droits de l’appelant a mal compris son rôle : cette vérification appartient à un autre champ, évalué avant lui, qui décide s’il aura même l’occasion de s’exécuter.

L’erreur observée en revue de code

Sur quinze abilities passées en revue, quatre plaçaient un appel à current_user_can() directement au début de la fonction déclarée en execute_callback, sans jamais renseigner de permission_callback distinct, ou en le renseignant avec une fonction renvoyant systématiquement vrai. Le résultat produit un comportement fonctionnellement proche, mais deux défauts concrets : un audit qui interroge le registre pour connaître les permissions déclarées, via wp_get_abilities() par exemple, ne voit rien d’anormal puisque le champ dédié semble correctement rempli ; et un agent qui tente l’appel sans les droits nécessaires reçoit une erreur produite tardivement, depuis l’intérieur de l’action, plutôt qu’un refus propre et anticipé du registre lui-même.

  • execute_callback : contient uniquement la logique métier de l’action
  • permission_callback : contient uniquement la décision d’autoriser ou non cette action
  • Aucune vérification de droits ne doit se dupliquer entre les deux fonctions

Ce que ce champ ne couvre pas

Le champ execute_callback ne valide pas les entrées reçues au-delà de ce que le schéma d’entrée a déjà vérifié en amont, et il ne remplace pas non plus une gestion d’erreur explicite : une fonction qui échoue silencieusement, sans retourner d’indication exploitable, laisse l’agent sans moyen de savoir si l’action a réellement eu lieu. Retourner un tableau clair, ou lever une exception gérée par le registre, reste la responsabilité de cette fonction, distincte de la question des droits traitée ailleurs.

Conclusion

Distinguer clairement execute_callback de permission_callback n’est pas un détail de vocabulaire : c’est ce qui garantit qu’un audit des permissions d’un site, mené en lisant le registre des abilities, reflète effectivement ce qui se passera en production, plutôt qu’une vérification masquée à l’intérieur d’une fonction censée ne faire qu’exécuter l’action déjà autorisée.

Laisser un commentaire

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

Partager :

À propos de l'auteur

WordPress Développement

Développeur WordPress, passionné par Elementor, le FSE et l’automatisation par IA.

Voir tous ses articles

Dans la même veine

À lire aussi