¿Cuándo se borra la columna 'post_content_filtered' en la base de datos por WordPress?

29

Algunos complementos de WordPress (aunque muy pocos) usan la post_content_filteredcolumna en la base de datos para guardar algunos datos relacionados con una publicación.

Por ejemplo, Markdown en Guardar almacena la versión de Markdown de una publicación por separado en la post_content_formattedcolumna y el HTML analizado en la post_contentcolumna, de modo que cuando el complemento esté desactivado, las publicaciones no arrojarán Markdown (porque el HTML está almacenado en post_content).

Ahora, me di cuenta de que post_content_filteredse usa bastante para el almacenamiento temporal, es decir, el contenido de la columna se pierde (o borra) cuando:

  • realiza cambios en una publicación (título, etiquetas, categorías, etc.) utilizando la opción 'Edición rápida'

  • una publicación programada se publica (automáticamente)

  • haces ediciones masivas a publicaciones

  • cambia entre revisiones de una publicación

  • una publicación se guarda desde un editor externo (es decir, no el editor de publicaciones de WordPress)

Preguntas:

  1. ¿En qué otras situaciones se post_content_filteredborran los datos de la columna?

  2. ¿Hay alguna manera de evitar que esto suceda? (Quiero decir, ¿hay alguna manera de asegurarse de que los datos se almacenen de forma permanente, la forma en post_contentque se trata la columna?)

soy yo
fuente

Respuestas:

29

Cada actualización de publicación en WordPress es manejada por la wp_update_postfunción.

Esta función tiene algunos valores predeterminados, y para post_content_filteredel valor predeterminado es '' (cadena vacía).

Una vez que los valores predeterminados se fusionan con los argumentos pasados ​​a la función wp_parse_args, significa que cada vez que se actualiza una publicación y post_content_filteredno se pasa explícitamente, se establece en una cadena vacía.

Ahora podemos preguntar: ¿cuándo se post_content_filteredpasa explícitamente a wp_update_post? La respuesta es: nunca por WordPress.

Entonces para su primera pregunta:

¿En qué otras situaciones se borran los datos en la columna post_content_filtered?

La respuesta corta es: cada vez que se actualiza una publicación, por cualquier motivo .

Tenga en cuenta que cambiar solo un campo es una actualización, en particular, cada cambio de estado es una actualización, por ejemplo, borrador para publicar, pendiente de publicación, futuro para publicar, publicar en la papelera (una publicación eliminada), etc.

Si algo cambia en una publicación, entonces post_content_filteredse borra; La única excepción es cuando post_content_filteredse pasa explícitamente a wp_update_post, y como ya se dijo, esto nunca lo hace WordPress.

¿Hay alguna manera de evitar que esto suceda? (Quiero decir, ¿hay alguna manera de asegurarse de que los datos se almacenen permanentemente?

Si crea ese campo con su código y desea preservarlo, debe mirar cada actualización realizada por WordPress y evitar el cambio.

Esto puede sonar como un trabajo duro, pero si lees la primera oración de esta respuesta, " Cada actualización de publicación en WordPress es manejada por la wp_update_postfunción ", entiendes que lo único que se necesita es mirar esa función, que afortunadamente tiene diferentes ganchos .

El gancho que sugiero es wp_insert_post_datapor 2 razones:

  • Se ejecuta antes de la actualización, por lo que no tiene que recuperarse, pero puede evitar
  • Pasa 2 parámetros: los datos que la función se va a actualizar, y una matriz de los parámetros pasados, que (en caso de actualización) contienen el ID de la publicación

Entonces, usando un simple get_post, puede comparar cómo es la publicación ahora y cómo será la publicación: si no le gusta algo, puede cambiarlo.

Codifiquemos:

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;

}

Existe un posible problema, donde la función anterior impide cada post_content_filtered limpieza. Y si usted , por cualquier razón, desea desactivarla?

He dicho que cada cambio de publicación de WP es manejado por wp_update_post, pero usted no es WordPress.

Puedes escribir una función como:

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

Al ser una $wpdbconsulta, no activa nuestro filtro, por lo que el restablecimiento se realiza sin problemas, y en cualquier parte de su código que necesite restablecer post_content_filtered, puede llamar a esta función.

También puede crear un metabox con un botón 'Borrar contenido filtrado' y cuando se hace clic en este botón simplemente llame a su reset_post_content_filteredfunción, por ejemplo, a través de Ajax.

gmazzap
fuente