web-dev-qa-db-fra.com

add_action dans l'espace de noms ne fonctionne pas

J'ai décidé de créer un espace de nommage pour mon plugin, et je l'ai tout fait fonctionner, sauf dans mon fichier de plugin principal.

J'ai ajouté deux actions dans ce plugin, avant d'appeler la méthode init du plugin.

<?php
namespace myPlugin;

add_action( 'admin_init', 'add_activation_notice' );

function add_activation_notice() {
    add_action( 'admin_notices', 'activation_notice' );
}

function activation_notice() {
    echo 'Notice!';
}

Mais cela jette une erreur

Erreur non capturée : Constante non définie 'myPlugin\myPlugin\add_activation_notice'

Je suis plutôt nouveau dans le domaine des noms, alors je ne sais pas pourquoi cela se produit.

Les deux fonctions add_activation_notice et activation_notice se trouvent dans l'espace de noms myPlugin. La plupart du code, j’ai trouvé des méthodes de référence en ligne à l’intérieur des classes, mais j’ai besoin que celles-ci soient en dehors d’une classe pour pouvoir recevoir la notification d’activation du plug-in.

MODIFIER:

Quand j'essaye avec

add_action( 'admin_init', \add_activation_notice() );

Je reçois

Erreur fatale : Erreur non capturée: appel de la fonction non définie add_activation_notice ()

2
dingo_d

Avant d'aller trop loin dans cette voie, je vous suggère de vous familiariser avec PHP règles de résolution de noms .

Pour répondre à votre question actuelle -

Lorsque vous utilisez des fonctions d'espace de noms, le nom complet de ces fonctions inclut l'espace de noms.

Dans votre exemple, vous avez défini deux fonctions: \myPlugin\add_activation_notice et \myPlugin\activation_notice.

Lorsque vous appelez l'un de ces éléments à partir de l'espace de noms myPlugin, vous pouvez utiliser le nom non qualifié (c'est-à-dire activation_notice()), mais en dehors de l'espace de noms myPlugin, vous devez respecter les règles de résolution de noms ci-dessus.

Dans le cas de add_action() - alors que cet appel est appelé depuis votre espace de nom myPlugin, vous ne transmettez pas la fonction réelle mais le nom de la fonction sous forme de chaîne. WordPress tente ensuite d'appeler cette fonction à partir de l'espace de noms global.

La solution à votre problème devrait être d’inclure l’espace de nom myPlugin dans le nom de la fonction transmis à add_action (accorder une attention particulière à la barre oblique inverse échappée):

add_action( 'admin_init', 'myPlugin\\add_activation_notice' );
add_action( 'admin_notice', 'myPlugin\\activation_notice' );

Ma méthode préférée serait de concaténer la constante magique __NAMESPACE__ , ce qui simplifie un peu les choses si vous décidez un jour de changer vos espaces de noms:

add_action( 'admin_init', __NAMESPACE__ . '\\add_activation_notice' );
add_action( 'admin_notice', __NAMESPACE__ . '\\activation_notice' );
7
ssnepenthe

Le moyen le plus simple serait de placer votre code entre accolades:

namespace myPlugin {

    add_action( 'admin_init', __NAMESPACE__ . '\\add_activation_notice' );

    function add_activation_notice() {
        add_action( 'admin_notice', __NAMESPACE__ . '\\activation_notice' );
    }

    function activation_notice() {
        echo 'Notice!';
    }
}

Sinon, votre action cherchera la fonction activation_notice dans un espace de noms global.

Mettre à jour

Il n'y a pas de crochet admin_notice. Utilisez admin_notices à la place. Essayer:

namespace myPlugin {
    add_action( 'admin_init', __NAMESPACE__ . '\\add_activation_notice');

    function add_activation_notice() {
        add_action( 'admin_notices', __NAMESPACE__ . '\\activation_notice' );
    }

    function activation_notice() {
    ?>
        <div class="notice notice-info is-dismissible">
            <p><?php echo 'Done!'; ?></p>
        </div>
    <?php
    }
}