Funzioni obsolete in una classe di plugin


8

Sto aggiornando uno dei miei plugin e sono un po 'bloccato con funzioni deprecanti.

Inizialmente, il mio plugin aveva una variabile globale e la classe principale del plugin era istanziata e memorizzata nella variabile globale. In questo modo gli utenti potrebbero utilizzare il globale per accedere alle funzioni nella classe plugin.

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

Quindi, ad esempio, nelle mie FAQ avevo il codice che mostrava come rimuovere una delle funzioni della mia classe da un hook specifico e aggiungerlo a un hook diverso:

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' );

Ora, nel mio aggiornamento la display_input()funzione è stata spostata in un'altra classe e voglio far sapere alle persone come accedervi. Ho provato a sostituire la funzione originale (nella classe principale del plugin) con il seguente avviso di deprecazione:

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

Tuttavia, le funzioni add_actione remove_actionnon sembrano attivare l'avviso di ammortamento. Stranamente, la rimozione completa della funzione non causa un errore, anche se array( $my_custom_plugin, 'display_input')non esiste.

Se qualcuno tenta di accedere direttamente alla funzione:

$my_custom_plugin->display_input();

Quindi vedo gli avvisi di debug. È questo il risultato atteso per _deprecated_function()? Oppure mi sfugge qualcosa? È possibile mostrare un avviso di debug quando qualcuno tenta di rimuovere o aggiungere un'azione utilizzando una funzione obsoleta?

Aggiornare

Mi sono reso conto che semplicemente non vedevo il messaggio di debug per add_actioncome lo stavo aggiungendo abbastanza in basso nella pagina. #facepalm! Tuttavia, non vedo ancora alcun avviso di debug per remove_action.


call_user_func(function(){trigger_error('hello?');});Opere interessanti , ma non riesce in un callback registrato per add_action.
fuxia

Prepararsi per facepalm, ma è una domanda o una dichiarazione?
Helgatheviking

Solo un risultato del test. Anche io sono sorpreso.
fuxia

Ok, quindi non ho davvero trascurato nulla, è così ?
Helgatheviking

2
Oh, Query Monitor ha nascosto il messaggio nella mia configurazione. Il messaggio add_action()era effettivamente lì. remove_action()non può essere gestito in questo modo.
fuxia

Risposte:


2

Richiamate inesistenti

Una delle cose belle è che nessuno dei due do_action(), né apply_filters()fa scattare un errore se non è presente un callback. Ciò significa che è il modo più sicuro per inserire i dati dei plug-in nei modelli: se un plug-in è disattivato e do_action()/ apply_filters()non trova il callback $wp_filtersnell'array globale , non accade nulla.

Uscita errore

Ora quando si chiama remove_filter()la funzione / metodo che ha originariamente agganciato il callback, il callback verrà semplicemente rimosso dall'array globale, il che significa che il callback non verrà mai eseguito poiché non è più registrato.

La soluzione è semplice: rimuovere il callback dopo che è stato attivato, rimuovendolo dall'interno del callback stesso.

Rimozione di callback

Sappiamo tutti che il plugin WPs "API" è un problema quando si tratta di rimuovere. Il problema è principalmente lo strano costrutto di aggiungere nomi "unici" alle chiavi global $wp_filter;dell'array. Una soluzione molto semplice è semplicemente usare __METHOD__e chiamare i filtri che si desidera rimuovere in un contesto statico:

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

        return $baz;
    }
}

Anche se questo non è carino, è ... una sorta di soluzione per alcuni casi d'uso. Ma non pensare nemmeno a rimuovere una chiusura.

Sopra rimuove solo il callback, lo esegue comunque. Puoi comunque andare oltre e usare remove_all_actions()(o 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' );

Potresti anche andare oltre, estrarre il callback dall'array di filtri globali e ricollegarlo al nuovo hook / filtro (se sono compatibili).


Grazie Kaiser! Questa è una risposta fantastica e dettagliata. Proverò a provarlo domani.
Helgatheviking,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.