✅ Notícias, temas e plug-ins da WEB e do WordPress. Aqui compartilhamos dicas e as melhores soluções para sites.

Mantendo um status de postagem ao atualizar uma postagem do WordPress

31

Acabei de terminar um recurso para um projeto que usa uma combinação de tipos de postagem personalizados, importações de dados e atualização de postagens existentes ao excluir um usuário (ou conjunto de usuários).

Há um problema, porém:

Digamos que você tenha uma postagem publicada no momento (ou seja, seu ‘post_status’ está definido como ‘publicar’), mas, quando você atualiza a postagem via wp_update_post, seu atributo post_status é definido como ‘futuro’.

Em outras palavras, sempre que você atualiza programaticamente uma postagem, o status da postagem é definido como ‘Agendado’ (de acordo com a interface do usuário) e ‘futuro’ (de acordo com a coluna do banco de dados).

Então o que dá?

Status da postagem ao atualizar

De um modo geral, não sou fã de fazer algo funcionar, descobrir que funciona e passar para a próxima tarefa, a menos que entenda exatamente por que não funcionou [como esperado] em primeiro lugar.

Isso não quer dizer que não haja momentos em que as restrições tenham causado isso (pelo menos durante o horário de trabalho). Mas se é meia-noite, eu conserto um bug e não tenho certeza se entendi por que aparentemente estava quebrado em primeiro lugar, é melhor ficar acordado e descobrir, certo?

É como a versão do programador do viés de custo afundado.

De qualquer forma, conforme descrito acima, aqui está a essência do problema:

  1. Um determinado post existe no WordPress.
  2. Quando um usuário é excluído, o sistema verifica se determinado conteúdo existe em uma determinada postagem e, em caso afirmativo, o remove.
  3. A postagem é então atualizada usando uma função da API do WordPress.

Tudo funciona muito bem, exceto que há um problema: sempre que a postagem é atualizada programaticamente, ela marca o status da postagem como ‘futuro’ no banco de dados, definindo o item de linha da postagem na  visualização Todas as postagens como "Agendado".

Duas soluções

Existem duas maneiras de corrigir esse problema:

  1. Execute uma consulta rápida diretamente no banco de dados para corrigir o problema.
  2. Atualize os argumentos da postagem para usar o horário adequado no GMT (falarei mais sobre isso em um momento).

Se você optar pela primeira solução, certifique-se de usar a função prepare e certifique-se de executar a consulta depois que a função de atualização for retornada.

<?php

// First, update the post using the available WordPress API.
wp_update_post( $post );

/**
 * If the post status attribute of the post that was just updated
 * maintains the 'publish' post setatus, then manually update the 
 * database column.
 */
if ('publish' === $post->post_status) {

    global $wpdb;
    $wpdb->query(
        $wpdb->prepare(
            "
            UPDATE $wpdb->posts
            SET post_status = '%s'
            WHERE ID = %d
            ",
            'publish',
            $post->ID) );
}

Se você optar pela segunda solução, atualize explicitamente as propriedades do objeto post antes de passá-lo para a função de atualização.

<?php

$event_post->post_date_gmt = gmdate( 'Y-m-d H:i:s', $event_post->post_date_gmt );
wp_update_post( $event_post );

Não sou de dizer que não há lugar para nenhuma dessas soluções ao trabalhar em um projeto, mas a pergunta permanece:

Por que o WordPress está marcando uma postagem agendada para o futuro quando a postagem, antes de passar pelo procedimento de atualização, foi definida para publicação?

E se você não estiver familiarizado com o restante dos argumentos que são passados ​​ao WordPress ao atualizar um post, levará algum tempo para rastreá-lo.

Entendendo o problema

Para evitar escrever uma consulta direta ao banco de dados, opto pela segunda solução porque é mais limpa (embora não a torne menos confusa).

Para descobrir por que esse comportamento acontece, você pode perguntar a outro desenvolvedor ou depurar o código. Dado que eu estava trabalhando nisso tarde da noite, optei pelo último.

Executando o depurador e o código de rastreamento através de post.php.

Não vou falar sobre todos os pontos de interrupção e relógios que defini, então tentarei ser o mais conciso possível.

Primeiro, quando o código for executado pela função wp_update_post, ele encontrará este bloco de código :

<?php

if ('attachment' !== $post_type) {
    if ('publish' == $post_status) {
        $now = gmdate('Y-m-d H:i:59');
        if (mysql2date('U', $post_date_gmt, false) > mysql2date('U', $now, false)) {
            $post_status = 'future';
        }
    } elseif ('future' == $post_status) {
        $now = gmdate('Y-m-d H:i:59');
        if (mysql2date('U', $post_date_gmt, false) <= mysql2date('U', $now, false)) {
            $post_status = 'publish';
        }
    }
}

Observe que dentro da condicional, não estamos trabalhando com um anexo e estamos trabalhando com um status de postagem de ‘publicar’. Então, vamos acertar a primeira condicional dentro da condicional externa (um pouco confuso, não é?).

Agora há uma variável, $post_status, mantendo um valor de publicação, mas não é atribuída a nenhuma propriedade específica da postagem atual. Se você continuar rastreando o código, você encontrará a próxima linha :

<?php

$post_parent = apply_filters( 'wp_insert_post_parent', $post_parent, $post_ID, compact( array_keys( $postarr) ), $postarr );

Aqui, você verá que está trabalhando com um conjunto de chaves de matriz contidas na variável $postarr. Esta variável é usada anteriormente no código (veja aqui no Trac). E se você olhar de perto, verá que primeiro verifica se a propriedade post_date_gmt está vazia ou se está tudo zerado.

E como não é, ele usará o valor que especificamos na propriedade quando inicialmente chamamos a função :

<?php

if (empty( $postarr['post_date_gmt']) || '0000-00-00 00:00:00' == $postarr['post_date_gmt']) {
        if (! in_array( $post_status, array( 'draft', 'pending', 'auto-draft') )) {
            $post_date_gmt = get_gmt_from_date( $post_date );
        } else {
            $post_date_gmt = '0000-00-00 00:00:00';
        }
    } else {
        $post_date_gmt = $postarr['post_date_gmt'];
    }

Espere.

Por que voltar para a função quando o código já passou por isso? Essa é a natureza da depuração. Às vezes você vê variáveis ​​e não pensa nada sobre elas apenas para ver que são usadas, configuradas, manipuladas, combinadas ou qualquer outra coisa posteriormente no código.

Essa é a realidade disso.

Mas de qualquer forma, por causa disso, a propriedade manterá o valor que fornecemos antes de chamar a função de atualização. Normalmente, este será o mesmo valor de quando a função foi iniciada, mas pode haver momentos em que você queira, digamos, descartar uma postagem.

E isso é motivo para usar wp_delete_post. Mas tem suas ressalvas, especialmente em torno dos tipos de postagem personalizados.

Isso fica em outro post, no entanto.

Fonte de gravação: tommcfarlin.com

Este site usa cookies para melhorar sua experiência. Presumiremos que você está ok com isso, mas você pode cancelar, se desejar. Aceitar Consulte Mais informação