Quando a coluna 'post_content_filtered' no banco de dados é limpa pelo WordPress?

29

Alguns plugins do WordPress (embora muito poucos) usam a post_content_filteredcoluna no banco de dados para salvar alguns dados relacionados a uma postagem.

Por exemplo, o Markdown on Save armazena a versão de markdown de uma postagem separadamente na post_content_formattedcoluna e o HTML analisado na post_contentcoluna, para que, quando o plug-in for desativado, as postagens não exibam o Markdown (porque o HTML está armazenado post_content).

Agora, percebi que post_content_filteredé praticamente usado para armazenamento temporário, ou seja, o conteúdo da coluna é perdido (ou limpo) quando:

  • você faz alterações em uma postagem (título, tags, categorias etc.) usando a opção "Edição rápida"

  • uma postagem agendada é (automaticamente) publicada

  • você faz edições em massa nas postagens

  • você alterna entre revisões de uma postagem

  • uma postagem é salva de um editor externo (ou seja, não o editor de postagem do WordPress)

Questões:

  1. Em que outras situações os dados da post_content_filteredcoluna são limpos?

  2. Existe uma maneira de impedir que isso aconteça? (Quero dizer, existe uma maneira de garantir que os dados sejam armazenados permanentemente, a maneira como a post_contentcoluna é tratada?)

sou eu
fonte

Respostas:

29

Toda atualização de post no WordPress é tratada pela wp_update_postfunção.

Essa função possui alguns padrões e post_content_filteredo valor padrão é '' (sequência vazia).

Uma vez que os padrões são mesclados com os argumentos passados ​​para funcionar wp_parse_args, significa que toda vez que uma postagem é atualizada e post_content_filterednão é explicitamente passada, ela é definida como uma sequência vazia.

Agora podemos perguntar: quando é post_content_filteredexplicitamente passado para wp_update_post? A resposta é: nunca pelo WordPress.

Então, para sua primeira pergunta:

Em que outras situações os dados na coluna post_content_filtered são limpos?

A resposta curta é: sempre que uma postagem é atualizada, por qualquer motivo .

Observe que alterar apenas um campo é uma atualização, em particular, toda mudança de status é uma atualização, por exemplo, rascunho a publicar, pendência para publicação, publicação futura, publicação no lixo (uma exclusão de postagem) e assim por diante ...

Se algo mudar em uma postagem, post_content_filteredé limpo; A única exceção é quando post_content_filteredé explicitamente passado para o wp_update_postWordPress e, como já foi dito, isso nunca é feito.

Existe uma maneira de impedir que isso aconteça? (Quero dizer, existe uma maneira de garantir que os dados sejam armazenados permanentemente?

Se você criar esse campo com o seu código, e quiser preservá-lo, precisará examinar todas as atualizações realizadas pelo WordPress e impedir a alteração.

Isso pode parecer um trabalho árduo, mas se você ler a primeira frase desta resposta, " Toda atualização de post no WordPress é tratada pela wp_update_postfunção ", você entende que a única coisa necessária é olhar para essa função, que felizmente tem ganchos diferentes .

O gancho que eu sugiro é o wp_insert_post_datapor 2 razões:

  • Ele é executado antes da atualização, portanto você não precisa se recuperar, mas pode impedir
  • Passa 2 parâmetros: os dados que a função vai atualizar e uma matriz dos parâmetros passados ​​que (em caso de atualização) contêm o ID da postagem

Portanto, usando um simples, get_postvocê pode comparar como a postagem está agora e como será a postagem: se você não gostar de algo, pode alterá-lo.

Vamos codificar:

add_filter( 'wp_insert_post_data', 'preserve_content_filtered', 999, 2 );

function preserve_content_filtered ( $data, $postarr ) {

    /* If this is not an update, we have nothing to do */
    if ( ! isset($postarr['ID']) || ! $postarr['ID'] ) return $data;

    /*
     * Do you want you filter per post_type?
     * You should, to prevent issues on post type like menu items.
     */
    if ( ! in_array( $data['post_type'], array( 'post', 'page' ) ) ) return $data;

    /* How post is now, before the update */
    $before = get_post( $postarr['ID'] ); 

    /* If content_filtered is already empty we have nothing to preserve */
    if ( empty( $before->post_content_filtered ) ) return $data;

    if ( empty( $data['post_content_filtered'] ) ) {
        /*
         * Hey! WordPress wants to clear our valuable post_content_filtered...
         * Let's prevent it!
         */
        $data['post_content_filtered'] = $before->post_content_filtered;
    }

    return $data;

}

Existe um problema possível, em que a função anterior impede qualquer post_content_filtered limpeza. E se você , por qualquer motivo, quiser limpá-lo?

Eu disse que todas as alterações pós-WP são tratadas wp_update_post, mas você não é o WordPress.

Você pode escrever uma função como:

function reset_post_content_filtered( $postid ) {
    global $wpdb;
    $wpdb->query( $wpdb->prepare(
        "UPDATE $wpdb->posts SET `post_content_filtered` = '' WHERE `ID` = %d", $postid
    ) );
}

Sendo uma $wpdbconsulta, ele não aciona nosso filtro; portanto, a redefinição é feita sem problemas; em todo o código que você precisa redefinir post_content_filtered, você pode chamar essa função.

Você também pode criar uma metabox com o botão 'Limpar conteúdo filtrado' e, quando clicar nesse botão, basta chamar sua reset_post_content_filteredfunção, por exemplo, através do Ajax.

gmazzap
fonte