Când este ștersă coloana 'post_content_filtered' din baza de date de WordPress?
Unele pluginuri WordPress (deși foarte puține) utilizează coloana post_content_filtered
din baza de date pentru a salva anumite informații legate de un articol.
De exemplu, Markdown on Save stochează versiunea Markdown a unui articol separat în coloana post_content_formatted
și HTML-ul parsat în coloana post_content
, astfel încât atunci când pluginul este dezactivat, articolele nu vor afișa Markdown (deoarece HTML este stocat în post_content
).
Am realizat că post_content_filtered
este folosită în mare parte pentru stocare temporară, adică conținutul din coloană se pierde (sau este șters) atunci când:
faceti modificări unui articol (titlu, taguri, categorii etc.) folosind opțiunea 'Editare Rapidă'
un articol programat este (automat) publicat
efectuați editări în masă ale articolelor
treceți între reviziile unui articol
un articol este salvat dintr-un editor extern (adică nu din editorul de articole WordPress)
Întrebări:
În ce alte situații sunt șterse datele din coloana
post_content_filtered
?Există vreo modalitate de a preveni acest lucru? (Adică, există vreo cale de a ne asigura că datele sunt stocate permanent, așa cum este tratată coloana
post_content
?)

Fiecare actualizare a postării în WordPress este gestionată de funcția wp_update_post
.
Această funcție are câteva valori implicite, iar pentru post_content_filtered
valoarea implicită este '' (șir gol).
Odată ce valorile implicite sunt combinate cu argumentele transmise funcției prin wp_parse_args
, înseamnă că de fiecare dată când o postare este actualizată și post_content_filtered
nu este transmis explicit, acesta este setat la un șir gol.
Acum ne putem întreba: când este transmis explicit post_content_filtered
către wp_update_post
? Răspunsul este: niciodată de către WordPress.
Deci, pentru prima întrebare:
În ce alte situații sunt șterse datele din coloana post_content_filtered?
Răspunsul scurt este: de fiecare dată când o postare este actualizată, indiferent de motiv.
Rețineți că schimbarea unui singur câmp este o actualizare, în special, fiecare schimbare de stare este o actualizare, de ex. din ciornă în publicat, din așteptare în publicat, din viitor în publicat, din publicat în coșul de gunoi (ștergerea unei postări), și așa mai departe...
Dacă ceva se schimbă într-o postare, atunci post_content_filtered
este șters; singura excepție este atunci când post_content_filtered
este transmis explicit către wp_update_post
, și, după cum s-a menționat deja, acest lucru nu se întâmplă niciodată în WordPress.
Există vreo modalitate de a preveni acest lucru cu totul? (Adică, există o modalitate de a ne asigura că datele sunt stocate permanent?
Dacă ai creat acel câmp cu codul tău și dorești să-l păstrezi, trebuie să urmărești fiecare actualizare efectuată de WordPress și să preîntâmpini modificarea.
Aceasta poate părea o muncă grea, dar dacă citești prima propoziție din acest răspuns, "Fiecare actualizare a postării în WordPress este gestionată de funcția wp_update_post
", înțelegi că singurul lucru necesar este să te uiți la acea funcție, care, din fericire, are diferite cârlige.
Cârligul pe care îl sugerez este wp_insert_post_data
din 2 motive:
- Rulează înainte de actualizare, așa că nu trebuie să recuperezi dar poți preveni
- Primește 2 parametri: datele pe care funcția le va actualiza și un tablou cu parametrii transmiși, care (în cazul actualizării) conțin ID-ul postării
Deci, folosind un simplu get_post
poți compara cum este postarea acum și cum va fi postarea: dacă nu-ți place ceva, poți să-l schimbi.
Să codificăm:
add_filter( 'wp_insert_post_data', 'preserve_content_filtered', 999, 2 );
function preserve_content_filtered ( $data, $postarr ) {
/* Dacă aceasta nu este o actualizare, nu avem nimic de făcut */
if ( ! isset($postarr['ID']) || ! $postarr['ID'] ) return $data;
/*
* Dorești să filtrezi pe tipul de postare?
* Ar trebui, pentru a preveni probleme la tipuri de postare precum elementele de meniu.
*/
if ( ! in_array( $data['post_type'], array( 'post', 'page' ) ) ) return $data;
/* Cum este postarea acum, înainte de actualizare */
$before = get_post( $postarr['ID'] );
/* Dacă content_filtered este deja gol, nu avem nimic de păstrat */
if ( empty( $before->post_content_filtered ) ) return $data;
if ( empty( $data['post_content_filtered'] ) ) {
/*
* Hei! WordPress vrea să ne șteargă valoarea post_content_filtered...
* Să prevenim acest lucru!
*/
$data['post_content_filtered'] = $before->post_content_filtered;
}
return $data;
}
Există o posibilă problemă, unde funcția anterioară previne orice ștergere a post_content_filtered
. Și dacă tu, din orice motiv, vrei să-l ștergi?
Am spus că fiecare modificare a postării în WP este gestionată de wp_update_post
, dar tu nu ești WordPress.
Poți scrie o funcție precum:
function reset_post_content_filtered( $postid ) {
global $wpdb;
$wpdb->query( $wpdb->prepare(
"UPDATE $wpdb->posts SET `post_content_filtered` = '' WHERE `ID` = %d", $postid
) );
}
Fiind o interogare $wpdb
, aceasta nu declanșează filtrul nostru, astfel încât resetarea se face fără probleme, și oriunde în codul tău ai nevoie să resetezi post_content_filtered
, poți apela această funcție.
Poți crea și un metabox cu un buton 'Șterge conținutul filtrat' și când acest buton este apăsat, apelează pur și simplu funcția ta reset_post_content_filtered
, de exemplu prin Ajax.
