✅ Nowości, motywy, wtyczki WEB i WordPress. Tutaj dzielimy się wskazówkami i najlepszymi rozwiązaniami dla stron internetowych.

Utrzymywanie statusu posta podczas aktualizacji posta WordPress

22

Właśnie skończyłem funkcję dla projektu, która używa kombinacji niestandardowych typów postów, importu danych i aktualizacji istniejących postów podczas usuwania użytkownika (lub zestawu użytkowników).

Jest jednak jeden problem:

Powiedzmy, że masz post, który jest aktualnie opublikowany (to znaczy, że „post_status" jest ustawiony na „publish”), ale kiedy aktualizujesz post przez wp_update_post, jego atrybut post_status jest ustawiony na „przyszłość”.

W słowach porządkowych, za każdym razem, gdy programowo aktualizujesz wpis, stan wpisu jest ustawiany na „Zaplanowany” (zgodnie z interfejsem użytkownika) i „przyszły” (zgodnie z kolumną bazy danych).

Więc co daje?

Status postu podczas aktualizacji

Ogólnie rzecz biorąc, nie jestem fanem tego, aby coś działało, dowiadywania się, że to działa, i przechodzenia do następnego zadania, chyba że rozumiem dokładnie, dlaczego to nie działało [zgodnie z oczekiwaniami] w pierwszej kolejności.

Nie oznacza to, że nie ma sytuacji, w których ograniczenia spowodowały to zjawisko (przynajmniej w godzinach pracy). Ale jeśli jest północ, naprawiam błąd, a potem nie jestem do końca pewien, czy rozumiem, dlaczego najwyraźniej został zepsuty w pierwszej kolejności, równie dobrze mogę nie spać i zrozumieć to dobrze?

Przypomina to programistyczną wersję sunk cost bias.

W każdym razie, jak opisano powyżej, oto sedno problemu:

  1. Dany post istnieje w WordPressie.
  2. Po usunięciu użytkownika system sprawdza, czy w danym poście istnieje określona treść, a jeśli tak, usuwa ją.
  3. Post jest następnie aktualizowany za pomocą funkcji API WordPress.

Wszystko działa świetnie, z wyjątkiem problemu: za każdym razem, gdy post jest programowo aktualizowany, oznacza to status posta jako „przyszły” w bazie danych, ostatecznie ustawiając element wiersza posta w  widoku Wszystkie posty jako „Zaplanowany”.

Dwa rozwiązania

Istnieją dwa sposoby rozwiązania tego problemu:

  1. Uruchom szybkie zapytanie bezpośrednio w bazie danych, aby rozwiązać problem.
  2. Zaktualizuj argumenty posta, aby używały właściwego czasu w GMT (więcej o tym za chwilę).

Jeśli zdecydujesz się na pierwsze rozwiązanie, upewnij się, że korzystasz z funkcji przygotowania i wykonujesz zapytanie po zwróceniu funkcji aktualizacji.

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

Jeśli zdecydujesz się na drugie rozwiązanie, zaktualizuj jawnie właściwości obiektu post przed przekazaniem go do funkcji aktualizacji.

<?php

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

Nie mówię, że podczas pracy nad projektem nie ma miejsca na żadne z tych rozwiązań, ale pozostaje pytanie:

Dlaczego WordPress zaznacza post zaplanowany na przyszłość, gdy post, przed przejściem przez procedurę aktualizacji, miał zostać opublikowany?

A jeśli nie znasz pozostałych argumentów, które są przekazywane do WordPressa podczas aktualizacji posta, wyśledzenie go zajmie trochę czasu.

Zrozumienie problemu

Aby uniknąć pisania bezpośredniego zapytania do bazy danych, decyduję się na drugie rozwiązanie, ponieważ jest ono czystsze (chociaż nie czyni go mniej mylącym).

Aby dowiedzieć się, dlaczego tak się dzieje, możesz poprosić innego programistę lub debugować kod. Biorąc pod uwagę, że pracowałem nad tym późno w nocy, zdecydowałem się na to drugie.

Uruchamianie debugera i śledzenie kodu przez post.php.

Nie zamierzam omawiać wszystkich punktów przerwania i zegarków, które ustawiłem, więc postaram się, aby było to jak najbardziej zwięzłe.

Po pierwsze, gdy kod zostanie uruchomiony przez funkcję wp_update_post, napotka ten blok kodu :

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

Zwróć uwagę, że w warunku nie pracujemy z załącznikiem i pracujemy ze statusem posta „opublikuj”. Więc uderzymy w pierwszy warunek w ramach zewnętrznego warunku (trochę mylące, prawda?).

Teraz istnieje zmienna $post_status, która utrzymuje wartość publikowania, ale nie jest przypisana do żadnej konkretnej właściwości bieżącego posta. Jeśli będziesz kontynuować śledzenie kodu, natkniesz się na następny wiersz :

<?php

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

Tutaj zobaczysz, że pracuje on z zestawem kluczy tablicowych zawartych w zmiennej $postarr. Ta zmienna jest używana wcześniej w kodzie (zobacz ją tutaj na Tracu). A jeśli przyjrzysz się uważnie, zobaczysz, że najpierw sprawdza, czy właściwość post_date_gmt jest pusta lub czy jest wyzerowana.

A ponieważ tak nie jest, użyje wartości określonej we właściwości , gdy początkowo wywołaliśmy funkcję :

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

Czekać.

Po co wracać do funkcji, gdy kod już ją przekroczył? Taka jest natura debugowania. Czasami widzisz zmienne i nie myślisz o nich, tylko po to, by zobaczyć, że są używane, ustawiane, manipulowane, łączone lub cokolwiek innego w dalszej części kodu.

Taka jest rzeczywistość.

Ale tak czy inaczej, z tego powodu właściwość zachowa wartość, którą podaliśmy przed wywołaniem funkcji aktualizacji. Zwykle będzie to ta sama wartość, co przy uruchomieniu funkcji, ale mogą się zdarzyć sytuacje, w których chcesz, powiedzmy, skasować post.

I to jest podstawa do używania wp_delete_post. Ale ma też swoje zastrzeżenia, szczególnie w przypadku niestandardowych typów postów.

To jednak trafia do innego postu.

Źródło nagrywania: tommcfarlin.com

Ta strona korzysta z plików cookie, aby poprawić Twoje wrażenia. Zakładamy, że nie masz nic przeciwko, ale możesz zrezygnować, jeśli chcesz. Akceptuję Więcej szczegółów