Kiedy kolumna „post_content_filtered” w bazie danych jest czyszczona przez WordPress?

29

Niektóre wtyczki WordPress (choć bardzo niewiele) używają post_content_filteredkolumny w bazie danych do zapisywania niektórych danych związanych z postem.

Na przykład Markdown on Save przechowuje wersję Markdown posta osobno w post_content_formattedkolumnie i przeanalizowany HTML w post_contentkolumnie, aby po wyłączeniu wtyczki posty nie wyrzucały Markdown (ponieważ HTML jest przechowywany post_content).

Teraz zdałem sobie sprawę, że post_content_filteredjest on w dużej mierze wykorzystywany do tymczasowego przechowywania, tj. Zawartość w kolumnie jest tracona (lub usuwana), gdy:

  • wprowadzasz zmiany we wpisie (tytuł, tagi, kategorie itp.) za pomocą opcji „Szybka edycja”

  • zaplanowany post jest (automatycznie) publikowany

  • dokonujesz zbiorczych edycji postów

  • przełączasz między wersjami postu

  • post jest zapisywany z zewnętrznego edytora (tj. nie edytora postów WordPress)

Pytania:

  1. W jakich innych sytuacjach dane w post_content_filteredkolumnie są usuwane?

  2. Czy istnieje sposób, aby w ogóle temu zapobiec? (Mam na myśli, czy istnieje sposób, aby upewnić się, że dane są przechowywane trwale, tak jak post_contentkolumna jest traktowana?)

to ja
źródło

Odpowiedzi:

29

Każda aktualizacja wiadomości w WordPress jest obsługiwana przez wp_update_postfunkcję.

Ta funkcja ma pewne wartości domyślne, a dla post_content_filteredwartości domyślnej jest to ciąg pusty.

Gdy wartości domyślne zostaną scalone z argumentami przekazanymi do funkcji za pośrednictwem wp_parse_args, oznacza to, że za każdym razem, gdy post jest aktualizowany i post_content_filterednie jest jawnie przekazywany, zostaje ustawiony pusty ciąg.

Teraz możemy zapytać: kiedy jest to post_content_filteredwyraźnie przekazywane wp_update_post? Odpowiedź brzmi: nigdy przez WordPress.

Więc na twoje pierwsze pytanie:

W jakich innych sytuacjach dane w kolumnie post_content_filtered są usuwane?

Krótka odpowiedź brzmi: za każdym razem, gdy post jest aktualizowany, z dowolnego powodu .

Należy pamiętać, że zmiana tylko jednego pola jest aktualizacją, w szczególności każda zmiana statusu jest aktualizacją, np. Wersja robocza do opublikowania, oczekuje na publikację, przyszłość do opublikowania, opublikuj do kosza (post post delete) i tak dalej ...

Jeśli coś zmieni się w poście, post_content_filteredzostanie ono usunięte; Jedynym wyjątkiem jest sytuacja, gdy post_content_filteredjest to jawnie przekazywane wp_update_posti jak już wspomniano, WordPress nigdy tego nie robi.

Czy istnieje sposób, aby w ogóle temu zapobiec? (Mam na myśli, czy istnieje sposób, aby upewnić się, że dane są przechowywane na stałe?

Jeśli utworzysz to pole za pomocą swojego kodu i chcesz go zachować, musisz spojrzeć na każdą aktualizację wykonaną przez WordPress i zapobiec zmianie.

Może to zabrzmieć jak ciężka praca, ale jeśli przeczytasz pierwsze zdanie w tej odpowiedzi: „ Każda aktualizacja wiadomości w WordPress jest obsługiwana przez wp_update_postfunkcję ”, rozumiesz, że jedyne, czego potrzeba, to spojrzeć na tę funkcję, która na szczęście ma różne zaczepy .

Sugerowany przeze mnie haczyk jest z wp_insert_post_data2 powodów:

  • Działa przed aktualizacją, więc nie musisz się odzyskiwać, ale możesz temu zapobiec
  • Przekazuje 2 parametry: dane, które funkcja ma zaktualizować, oraz tablicę przekazanych parametrów, które (w przypadku aktualizacji) zawierają identyfikator posta

Tak więc za pomocą prostego narzędzia get_postmożesz porównać, jaki jest teraz post i jaki będzie post: jeśli coś ci się nie podoba, możesz to zmienić.

Kodujmy:

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;

}

Istnieje możliwość, że poprzednia funkcja uniemożliwia każde post_content_filtered czyszczenie. A jeśli ty , z jakiegokolwiek powodu, chcesz go usunąć?

Powiedziałem, że każda zmiana postu WP jest obsługiwana przez wp_update_post, ale nie jesteś WordPress.

Możesz napisać funkcję taką jak:

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

Jako $wpdbzapytanie nie uruchamia naszego filtra, więc resetowanie odbywa się bez problemu, a wszędzie w kodzie trzeba zresetować post_content_filtered, możesz wywołać tę funkcję.

Możesz także utworzyć metaboks za pomocą przycisku „Wyczyść filtrowaną zawartość”, a po kliknięciu tego przycisku po prostu wywołaj swoją reset_post_content_filteredfunkcję, np. Przez Ajax.

gmazzap
źródło