Fonctions obsolètes dans une classe de plugin

8

Je mets à jour un de mes plugins et je suis un peu coincé avec des fonctions obsolètes.

À l'origine, mon plugin avait une variable globale et la classe principale du plugin était instanciée et stockée dans la variable globale. De cette façon, les utilisateurs pourraient utiliser le global pour accéder aux fonctions de la classe de plugin.

$GLOBALS['my_custom_plugin'] = new my_custom_plugin();

Ensuite, par exemple, dans ma FAQ, j'avais un code qui montrait comment supprimer l'une des fonctions de ma classe d'un hook spécifique et l'ajouter à un autre hook:

function move_input(){ 
    global $my_custom_plugin;
    remove_action( 'before_main_content', array( $my_custom_plugin, 'display_input') );
    add_action( 'after_main_content', array( $my_custom_plugin, 'display_input' ) );
}
add_action( 'wp_head' , 'move_input' );

Maintenant, dans ma mise à jour, la display_input()fonction a été déplacée dans une autre classe et je veux que les gens sachent comment y accéder. J'ai essayé de remplacer la fonction d'origine (dans la classe principale du plugin) par l'avis de désapprobation suivant:

public function display_input() { 
    _deprecated_function( 'display_price', '2.0', 'my_custom_plugin()->display->display_input' );
    return $this->display->display_input();
}

Cependant, les fonctions add_actionet remove_actionne semblent pas déclencher l'avis de dépréciation. Bizarrement, la suppression complète de la fonction ne provoque pas non plus d'erreur, même siarray( $my_custom_plugin, 'display_input') n'existe pas.

Si quelqu'un essaie d'accéder directement à la fonction:

$my_custom_plugin->display_input();

Ensuite, je vois les avis de débogage. Est-ce le résultat attendu _deprecated_function()? ou est-ce que je manque quelque chose? Est-il possible d'afficher un avis de débogage lorsque quelqu'un essaie de supprimer ou d'ajouter une action à l'aide d'une fonction obsolète?

Mise à jour

J'ai réalisé que je ne voyais tout simplement pas le message de débogage pour le add_actioncar je l'ajoutais assez bas sur la page. #facepalm! Cependant, je ne vois toujours aucun avis de débogage pour le remove_action.

helgatheviking
la source
call_user_func(function(){trigger_error('hello?');});Travaux intéressants , mais il échoue dans un rappel enregistré par add_action.
fuxia
Se préparer pour facepalm, mais est-ce une question ou une déclaration?
helgatheviking
Juste un résultat de test. Je suis aussi surpris.
fuxia
Ok, donc je ne l' ai pas vraiment quoi que ce soit négligé, qui est juste comment il est ?
helgatheviking
2
Oh, Query Monitor a caché le message dans ma configuration. Le message pour add_action()était réellement là. remove_action()ne peut pas être manipulé comme ça.
fuxia

Réponses:

2

Rappels non existants

L'une des bonnes choses est que ni l'un do_action()ni l'autre apply_filters()ne déclenchent d'erreur si aucun rappel n'est présent. Cela signifie que c'est le moyen le plus sûr d'insérer des données de plugin dans des modèles: si un plugin est désactivé et do_action()/ apply_filters()ne trouve pas le rappel dans le $wp_filterstableau global , rien ne se passe.

Sortie d'erreur

Maintenant, quand tu appelles remove_filter() la fonction / méthode qui a initialement accroché le rappel, le rappel sera simplement supprimé du tableau global, ce qui signifie que le rappel ne sera jamais exécuté car il n'est plus enregistré.

La solution est simple: supprimez le rappel après son déclenchement, en le supprimant de l'intérieur du rappel lui-même.

Suppression des rappels

Nous savons tous que le plugin WPs "API" est pénible à supprimer. Le problème est principalement la construction étrange pour ajouter des noms "uniques" aux clés du global $wp_filter;tableau. Une solution très simple consiste à simplement utiliser __METHOD__et appeler les filtres que vous souhaitez supprimer dans un contexte statique:

class FOoooo
{
    public function __construct()
    {
        add_filter( 'hook', array( __CLASS__, 'bar' ) );
    }
    public static function bar( $baz )
    {
        remove_filter( current_filter(), __METHOD__ );

        return $baz;
    }
}

Bien que ce ne soit pas agréable, c'est ... une sorte de solution pour certains cas d'utilisation. Mais ne pensez même pas à retirer une fermeture.

Ci-dessus supprime simplement le rappel, l'exécute toujours. Vous pouvez toujours aller plus loin et utiliser remove_all_actions()(ou remove_all_filters()).

// Check if a callback is attached and tell about the deprecated stuff
if ( has_action( 'before_main_content' ) )
    _deprecated_function( 'display_price', '2.0', 'my_custom_plugin()->display->display_input' );
// Remove the callback
remove_all_actions( 'before_main_content' );

Vous pourriez peut-être même aller plus loin, extraire le rappel du tableau de filtres globaux et le rattacher au nouveau crochet / filtre (s'ils sont compatibles).

kaiser
la source
Merci Kaiser! Ceci est une réponse impressionnante et détaillée. J'essaierai de le tester demain.
helgatheviking