Onde, quando e como liberar corretamente as regras de reescrita no escopo de um plug-in?

10

Estou tendo um problema estranho com as regras de reescrita que não estão funcionando corretamente.

Eu tentei usar flush_rewrite_rules();e flush_rewrite_rules(true);.

Eu também tentei globalizar $wp_rewriteusando $wp_rewrite->flush_rules();e$wp_rewrite->flush_rules(true);

Nenhum dos quais parece estar liberando as regras de reescrita corretamente. Essas chamadas estão realmente liberando as regras de reescrita quando chamadas. Como eu sei disso? Usando a solução para depuração, reescreva a liberação da regra .

Atualmente, reescrevi regras liberadas na ativação e desativação de plug-ins. Não há problemas lá.

Eu tenho uma página de configurações de administração do plug-in para os usuários configurarem o plug-in. Algumas das configurações ajustam a estrutura do link permanente, portanto, as regras de reescrita precisam ser liberadas na página de configurações de administração do plug-in "Salvar configurações". (Usa o padrão update_option();) para salvar as configurações.

Gostaria de observar que, dependendo das configurações especificadas, tipos de postagem personalizados são criados para corresponder às configurações especificadas pelo usuário. Portanto, as regras de reescrita devem ser liberadas imediatamente após as configurações serem salvas. É aqui que as coisas não estão funcionando adequadamente.

A solução de link acima para depurar regras de reescrita fornecidas por @toschoestá exibindo que está liberando toneladas de regras de reescrita. No entanto, ao visitar o item singular de tipo de postagem personalizado, ou mesmo o archive de tipo de postagem personalizado, cada um deles retorna como erros 404.

O tipo de postagem personalizada é registrado corretamente e apropriadamente. Sei com certeza que não é esse o problema.

Imediatamente após a configuração da página de administração do plug-in, salve. Os tipos de postagem personalizados são criados, a estrutura do link permanente é ajustada e todas as regras de reescrita tentam ser liberadas.

Os tipos de postagem personalizados são carregados sempre e carregados initnormalmente.

Por algum motivo, as regras de reescrita não estão funcionando corretamente, porque, como eu disse antes, visitar seções singulares ou de arquivamento do tipo de postagem personalizada retorna erros 404.

Agora, a parte estranha, se tudo o que faço é simplesmente visitar a página de configurações de administração de links permanentes e, em seguida, voltar ao front-end para exibir seções singulares ou de arquivo do tipo de postagem personalizada, elas funcionam magicamente conforme o esperado.

O que essa página de configurações de permalinks de administração faz que eu não estou fazendo para permitir que as regras de reescrita sejam niveladas adequadamente e as minhas não?

Quero dizer, como uma solução temporária, redireciono o usuário para a página de configurações de permalinks de administração depois de salvar a página de configurações de administração do plug-in, mas essa não é uma solução ideal. Eu preferiria que as regras de reescrita apenas nivelassem corretamente no código do meu plug-in.

Existe um certo ponto no WordPress em que a liberação das regras de reescrita simplesmente não libera TODAS as regras?

admin_menu - A página de configurações do plug-in é adicionada à administração do WordPress.

add_options_page() - A página de configurações do plug-in é adicionada no menu Configurações.

A página de configurações é renderizada no retorno de chamada para add_options_page(). Também é aqui que $_POSTé processado a atualização das configurações do plug-in e a liberação das regras de reescrita.

Como essa já é uma pergunta longa, eu estaria disposto a fornecer blocos de código (se ajudar) em um link externo que ajudasse a produzir uma resposta válida.

Michael Ecklund
fonte
11
parece que talvez você tenha entendido errado a ordem das coisas, é difícil dizer sem ver algum código. a página de administração permalinks apenas chama flush_rewrite_rules, o que exclui a rewrite_rulesopção e a regenera, você pode abrir o arquivo wp-admin/options-permalinks.phpe ver onde isso acontece. como essa operação exclui toda a opção, não é possível liberar parcialmente as regras.
Milo
@ Milo, acho que você está certo. Eu tenho uma classe que é carregada na initqual registra os tipos de postagem. Imaginei que as configurações da página estavam sendo salvas e a página seria recarregada ... depois acionando o initgancho novamente para registrar os tipos de postagem necessários. Então, imaginei que os tipos de postagem já seriam carregados, e tudo que eu precisava fazer era atualizar a opção e liberar as regras de reescrita na página de configurações do plug-in. Vou postar uma resposta de como descobri uma solução.
Michael Ecklund
Apenas um aviso flush_rewrite_rules () no meu plug-in acabou fazendo parte do problema para mim. Eu apaguei o gancho php e acabei atualizando os permalinks manualmente e meus erros do CPT 404 desapareceram.
myol

Respostas:

4

O melhor lugar para liberar regras de reescrita é na ativação / desativação de plug-in.

function myplugin_activate() {
    // register taxonomies/post types here
    flush_rewrite_rules();
}

register_activation_hook( __FILE__, 'myplugin_activate' );

function myplugin_deactivate() {
    flush_rewrite_rules();
}
register_deactivation_hook( __FILE__, 'myplugin_deactivate' );

Veja o artigo do codex

Pedimos desculpas antecipadamente, mas não respondi completamente à sua pergunta. Portanto, essa é uma resposta um pouco complicada.

helgatheviking
fonte
11
Obrigado pela sua sugestão, mas estou ciente disso. O problema não é sobre a ativação / desativação de plug-ins. Tem a ver com os usuários alterando as configurações para o plug-in já ativo, que ajusta as regras de reescrita, exigindo uma liberação.
Michael Ecklund
11
Achei que poderia ser o caso, mas estava bastante cansado quando estava lendo sua pergunta. A solução da ialocin parece promissora, espero que você tenha resolvido.
helgatheviking
4

Difícil dizer o que há de errado, sem ver seu código. Mas, depois de salvar algumas configurações, é prático conectar-se admin_initcomo mostrado abaixo para liberar suas regras de reescrita.

Código:

add_action('admin_init', 'wpse_123401_plugin_settings_flush_rewrite');
function wpse_123401_plugin_settings_flush_rewrite() {
    if ( get_option('plugin_settings_have_changed') == true ) {
        flush_rewrite_rules();
        update_option('plugin_settings_have_changed', false);
    }
}


Você precisa definir a opção em algum lugar na página de configurações ou para ser exato em algum lugar no processo de salvar as configurações. Fazer isso sem a opção é ruim, porque você não deseja liberar as regras todas as vezes.


Nota: não testado

Nicolai
fonte
2
Ou você poderia usar um transitório, talvez? Mas definitivamente +1 por não liberar as regras em todos os admin_init.
helgatheviking
Claro que você está certo quanto a transitório, acho que optei por *_option()causa da página de configurações. @helgatheviking
Nicolai
Isso foi muito útil. Eu tive uma situação semelhante a Michael. Acabei incorporando a sugestão de helga sobre o uso de um transitório e o coloquei na função de validação das configurações. Acabei precisando definir o transitório como false após a liberação, ou ele continuava liberando a cada carregamento da página de administração até que o transitório expirasse. Então, funcionalmente, usar uma opção ou um transitório era o mesmo. Eu acho que transitório pode ser bom apenas para manter a tabela de opções um pouco mais limpa. Mas um ponto menor.
22414 Matthew Bree
A diferença é pequena, de fato, especialmente se os transitórios são permanentes, sem vencimento, mas é claro que os transitórios têm outros recursos, benefícios que é bom ter. @MatthewLee
Nicolai
3

Eu tinha um arquivo de classe de tipos de postagem responsável por ler as configurações de opções do plug-in e criar os tipos de postagem personalizados necessários com base nas configurações especificadas pelo usuário.

Este arquivo de classe de tipos de postagem foi carregado no gancho init.

Achei que tudo o que eu precisava fazer era atualizar as configurações do plug-in e liberar as regras de reescrita. Como a classe de tipos de postagem já foi carregada com base nas configurações do plug-in. Mas com as páginas de administração, elas são carregadas APÓS o initgancho.

Os tipos de postagem nunca foram realmente registrados, porque as configurações ainda não foram definidas. A classe de registro de tipos de postagem acabou sendo encerrada prematuramente, sem nenhum tipo de postagem registrado.

A solução foi:

  1. Atualize as configurações do plug-in.
  2. Carregue o arquivo de classe de tipos de postagem SOMENTE uma vez aqui para que as novas regras de reescrita sejam criadas.
  3. Liberar as regras de reescrita.

(Anteriormente ... faltava o passo 2 - Como mencionado acima ...)

A partir de agora, os tipos de postagem serão carregados no initgancho e já terão configurações especificadas, permitindo que os tipos de postagem sejam criados e emparelhados com as regras de reescrita apropriadas.

Por qualquer motivo, tive que adicionar uma chamada JavaScript para redirecionar para a página atual, depois de executar as três etapas acima.

Também precisei adicionar uma chamada flush_rewrite_rules();na página de configurações de administração do plug-in.

Portanto, para garantir que tudo esteja liberado ...

Etapa 1) Navegue até a página de configurações de administração do plug-in. - descarga inicial.

Etapa 2) Atualize as configurações do plugin. - Segunda descarga.

Etapa 3) A página é redirecionada para a página de configurações do plug-in. Causando a ... Terceira e última descarga (igual à descarga inicial - realizada automaticamente quando a página de configurações do plug-in é visitada)

Não estou dizendo que essa é uma solução prática, mas funcionou para mim. Problema muito estranho e provavelmente tem a ver com minha infraestrutura de codificação.

Michael Ecklund
fonte
1

@ tazo-todua isso funcionou para mim também ao usar multisite.

add_action( 'wpmu_new_blog', 'set_my_permalink_structure', 11, 2 );

function set_my_permalink_structure( $blog_id ) {

    switch_to_blog( $blog_id );

    global $wp_rewrite;
    $wp_rewrite->set_permalink_structure( '/%postname%/' );
    $wp_rewrite->flush_rules();
    $wp_rewrite->init();

    restore_current_blog();
}
stillatmylinux
fonte
0

MINHA solução encontrada foi:

global $wp_rewrite; $wp_rewrite->flush_rules(); $wp_rewrite->init();
T.Todua
fonte
0

Eu estava tendo exatamente o mesmo problema. No meu plugin, tenho tipos de postagem criados dinamicamente. Portanto, eles não podem ser registrados via register_post_type()método estático durante activation_hooke, portanto, ainda não estão ativos quando flush_rewrite_rules()executados durante esse gancho (que normalmente é a maneira recomendada de liberar regras de reescrita).

A solução mais limpa que eu pude encontrar no final foi liberar as regras de reescrita após o registro dos tipos de postagem, mas é claro apenas se essa liberação fosse realmente necessária (porque a operação é lenta). No meu caso, na verdade, tenho vários tipos de postagem personalizados que herdam de uma única classe base e, portanto, era desejável implementar o código que executa a liberação lá.

Se a lavagem é necessária, pode ser decidido observando a saída de get_option( 'rewrite_rules' ):

class MyPostTypeClass {

public final function register_as_custom_post_type() {
    ...   //do all the setup of your post type here     
    $args = array(
                  ... //populate the other arguments as you see fit
                  'rewrite' => array('slug' => 'slug-of-your-post-type')
                 );
    register_post_type('post-type-name-of-your-post-type', $args );

    $rewrite_rules_must_be_fluhed = true;
    foreach( get_option( 'rewrite_rules' ) as $key => $rule)
        if(strpos($key, $args['rewrite']['slug'] ) === 0)
        {
            $rewrite_rules_must_be_fluhed = false;
            break;
        }
    if($rewrite_rules_must_be_fluhed)
        flush_rewrite_rules(true);
}
}

Desvantagens:

  • Depende, até certo ponto, das regras exatas de reescrita que o WP gera durante register_post_type().
  • Verificar se a liberação é necessária durante cada carregamento de página também cria alguma sobrecarga.

Vantagens:

  • Totalmente encapsulado na classe que representa o tipo de postagem.
  • Somente libera as regras de reescrita, se realmente necessário.

Só use isso se você não pode registrar o seu tipo de cargo em uma função estática que podem chamar durante tanto initea activation_hook!

A dependência de como as regras de reescrita geradas durante a register_post_type()aparência pode ser atenuada, substituindo o teste if(strpos($key, $args['rewrite']['slug'] ) === 0)por algo mais elaborado, ou seja, uma expressão regular.

cgogolin
fonte