✅ Notizie, temi, plugin WEB e WordPress. Qui condividiamo suggerimenti e le migliori soluzioni per siti web.

Mantenere lo stato di un post durante l’aggiornamento di un post di WordPress

17

Ho appena terminato una funzionalità per un progetto che utilizza una combinazione di tipi di post personalizzati, importazione di dati e aggiornamento di post esistenti quando si elimina un utente (o un insieme di utenti).

C’è un problema, però:

Supponiamo che tu abbia un post attualmente pubblicato (ovvero, "post_status" è impostato su "pubblica") ma, quando aggiorni il post tramite wp_update_post, il suo attributo post_status è impostato su "futuro".

In altre parole, ogni volta che aggiorni un post a livello di codice, lo stato del post è impostato su "Programmato" (secondo l’interfaccia utente) e "futuro" (secondo la colonna del database).

Allora cosa dà?

Stato del post durante l’aggiornamento

In generale, non sono un fan di far funzionare qualcosa, scoprire che funziona e passare all’attività successiva a meno che non capisca esattamente perché non ha funzionato [come previsto] in primo luogo.

Questo non vuol dire che non ci siano momenti in cui i vincoli hanno causato ciò (almeno durante l’orario di lavoro). Ma se è mezzanotte, risolvo un bug e poi non sono del tutto sicuro di capire perché apparentemente era rotto in primo luogo, potrei anche stare sveglio e capirlo, giusto?

È come la versione del programmatore della distorsione dei costi irrecuperabili.

Ad ogni modo, come descritto sopra, ecco l’essenza del problema:

  1. Un determinato post esiste in WordPress.
  2. Quando un utente viene eliminato, il sistema controlla se esiste un determinato contenuto all’interno di un determinato post e, in tal caso, lo rimuove.
  3. Il post viene quindi aggiornato utilizzando una funzione API di WordPress.

Tutto funziona alla grande tranne che c’è un problema: ogni volta che il post viene aggiornato a livello di codice, contrassegna lo stato del post come "futuro" nel database, impostando infine l’elemento pubblicitario del post nella  visualizzazione Tutti i post come "Programmato".

Due soluzioni

Esistono due modi per risolvere questo problema:

  1. Eseguire una query rapida direttamente sul database per risolvere il problema.
  2. Aggiorna gli argomenti del post per utilizzare l’ora corretta in GMT (ne parlerò più in un momento).

Se si opta per la prima soluzione, assicurarsi di utilizzare la funzione di preparazione e assicurarsi di eseguire la query dopo la restituzione della funzione di aggiornamento.

<?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 opti per la seconda soluzione, aggiorna in modo esplicito le proprietà dell’oggetto post prima di passarlo alla funzione di aggiornamento.

<?php

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

Non sono uno che dice che non c’è posto per nessuna di queste soluzioni quando si lavora su un progetto, ma la domanda rimane:

Perché WordPress contrassegna un post programmato per il futuro quando il post, prima di passare alla procedura di aggiornamento, era impostato per la pubblicazione?

E se non hai familiarità con il resto degli argomenti che vengono passati a WordPress durante l’aggiornamento di un post, ci vorrà del tempo per rintracciarlo.

Capire il problema

Per evitare di scrivere una query diretta sul database, scelgo di scegliere la seconda soluzione perché è più pulita (anche se non la rende meno confusa).

Per capire perché si verifica questo comportamento, puoi chiedere a un altro sviluppatore o eseguire il debug del codice. Dato che ci stavo lavorando a tarda notte, ho optato per quest’ultimo.

Eseguire il debugger e tracciare il codice tramite post.php.

Non parlerò di tutti i breakpoint e gli orologi che ho impostato, quindi cercherò di renderlo il più conciso possibile.

Innanzitutto, quando il codice viene eseguito tramite la funzione wp_update_post, incontrerà questo blocco di codice :

<?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';
        }
    }
}

Nota che all’interno del condizionale, non stiamo lavorando con un allegato e stiamo lavorando con uno stato del post di "pubblica". Quindi raggiungeremo il primo condizionale all’interno del condizionale esterno (un po’ confuso non è vero?).

Ora c’è una variabile, $post_status, che mantiene un valore di pubblicazione ma non è assegnata a nessuna proprietà particolare del post corrente. Se continui a tracciare il codice, ti imbatterai nella riga successiva :

<?php

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

Qui vedrai che funziona con un insieme di chiavi di array che sono contenute nella variabile $postarr. Questa variabile è usata in precedenza nel codice (vedi qui su Trac). E se guardi da vicino, vedrai che prima controlla se la proprietà post_date_gmt è vuota o se è tutto azzerato.

E poiché non lo è, utilizzerà il valore che abbiamo specificato nella proprietà quando inizialmente abbiamo chiamato la funzione :

<?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'];
    }

Attesa.

Perché tornare nella funzione quando il codice è già stato eseguito oltre? Questa è la natura del debug. A volte vedi variabili e non pensi a niente solo per vedere che sono usate, impostate, manipolate, combinate o qualsiasi altra cosa più avanti nel codice.

Questa è la realtà.

Ma comunque, per questo motivo, la proprietà manterrà il valore che abbiamo fornito prima di chiamare la funzione di aggiornamento. Di solito, questo sarà lo stesso valore di quando la funzione è stata avviata, ma a volte potresti voler eliminare un post.

E questo è il motivo per usare wp_delete_post. Ma ha anche i suoi avvertimenti, specialmente sui tipi di post personalizzati.

Questo entra in un altro post, però.

Fonte di registrazione: tommcfarlin.com

This website uses cookies to improve your experience. We'll assume you're ok with this, but you can opt-out if you wish. Accept Read More