Descontinuando funções em uma classe de plug-in

8

Estou atualizando um dos meus plugins e estou um pouco preso com as funções obsoletas.

Originalmente, meu plugin tinha uma variável global e a classe principal do plugin foi instanciada e armazenada na variável global. Dessa forma, os usuários podem usar o global para acessar funções na classe de plug-in.

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

Então, por exemplo, no meu FAQ, eu tinha um código que mostrava como remover uma das funções da minha classe de um gancho específico e adicionar a um gancho diferente:

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

Agora, na minha atualização, a display_input()função foi movida para outra classe e quero que as pessoas saibam como acessá-la. Tentei substituir a função original (na classe principal do plug-in) pelo seguinte aviso de descontinuação:

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

No entanto, as funções add_actione remove_actionparecem não acionar o aviso de descontinuação. Estranhamente, remover completamente a função não causa um erro, mesmo que array( $my_custom_plugin, 'display_input')não exista.

Se alguém tentar acessar a função diretamente:

$my_custom_plugin->display_input();

Então eu vejo os avisos de depuração. É este o resultado esperado _deprecated_function()? Ou eu estou esquecendo de alguma coisa? É possível mostrar um aviso de depuração quando alguém tenta remover ou adicionar uma ação usando uma função obsoleta?

Atualizar

Percebi que simplesmente não estava vendo a mensagem de depuração para a página add_actionque estava adicionando. #facepalm! No entanto, ainda não estou vendo nenhum aviso de depuração para o arquivo remove_action.

helgatheviking
fonte
call_user_func(function(){trigger_error('hello?');});Trabalhos interessantes , mas falham em um retorno de chamada registrado por add_action.
fuxia
Preparando-se para o facepalm, mas isso é uma pergunta ou uma afirmação?
22814 helgatheviking
Apenas um resultado de teste. Também estou surpreso.
fuxia
Ok, então eu realmente não esqueci nada, é assim que é ?
22814 helgatheviking
2
Ah, o Query Monitor ocultou a mensagem na minha configuração. A mensagem para add_action()estava realmente lá. remove_action()não pode ser tratado assim.
fuxia

Respostas:

2

Retornos de chamada inexistentes

Uma das coisas boas é, que nem do_action(), nem apply_filters()fazer disparador um erro se uma chamada de retorno não está presente. Isso significa que é a maneira mais segura de inserir dados do plug-in nos modelos: se um plug-in estiver desativado e do_action()/ apply_filters()não encontrar o retorno de chamada na $wp_filtersmatriz global , nada acontecerá.

Saída de erro

Agora, quando você está chamando remove_filter()a função / método que originalmente conectou o retorno de chamada, o retorno de chamada simplesmente será removido da matriz global, o que significa que o retorno de chamada nunca será executado, pois não está mais registrado.

A solução é simples: remova o retorno de chamada depois que foi acionado, removendo-o do próprio retorno de chamada.

Remoção de retornos de chamada

Todos sabemos que o plug-in "API" dos WPs é um problema quando se trata de remover. O problema é principalmente a construção estranha de adicionar nomes "exclusivos" às chaves da global $wp_filter;matriz. Uma solução muito simples é usar __METHOD__e chamar filtros que você deseja remover no contexto estático:

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

        return $baz;
    }
}

Embora isso não seja legal, é ... uma espécie de solução para alguns casos de uso. Mas nem pense em remover um fechamento.

Acima, apenas remove o retorno de chamada, ainda o executa. Ainda assim, você pode ir além e usar 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' );

Talvez você possa ir além, extrair o retorno de chamada da matriz de filtros globais e reconectá-lo ao novo gancho / filtro (se eles forem compatíveis).

kaiser
fonte
Obrigado Kaiser! Esta é uma resposta impressionante e detalhada. Vou tentar testá-lo amanhã.
helgatheviking