Khi nào cột 'post_content_filtered' trong cơ sở dữ liệu bị xóa bởi WordPress?


29

Một số plugin WordPress (mặc dù rất ít) sử dụng post_content_filteredcột trong cơ sở dữ liệu để lưu một số dữ liệu liên quan đến bài đăng.

Ví dụ: Markdown on Save lưu trữ phiên bản đánh dấu của một bài đăng riêng biệt trong post_content_formattedcột và HTML được phân tích cú pháp trong post_contentcột, để khi plugin bị vô hiệu hóa, các bài đăng sẽ không xuất hiện Markdown (vì HTML được lưu trữ post_content).

Bây giờ, tôi nhận ra rằng nó post_content_filteredđược sử dụng khá nhiều cho việc lưu trữ tạm thời, tức là nội dung trong cột bị mất (hoặc bị xóa) khi:

  • bạn thay đổi bài đăng (tiêu đề, thẻ, danh mục, v.v.) bằng tùy chọn 'Chỉnh sửa nhanh'

  • một bài viết theo lịch trình được (tự động) xuất bản

  • bạn chỉnh sửa hàng loạt bài viết

  • bạn chuyển đổi giữa các phiên bản của bài viết

  • một bài đăng được lưu từ trình chỉnh sửa bên ngoài (tức là không phải trình chỉnh sửa bài WordPress)

Câu hỏi:

  1. Trong những tình huống khác, dữ liệu trong post_content_filteredcột bị xóa?

  2. Có cách nào để ngăn chặn điều này xảy ra không? (Ý tôi là, có cách nào để đảm bảo rằng dữ liệu được lưu trữ vĩnh viễn, cách post_contentxử lý cột không?)

Câu trả lời:


29

Mỗi bài cập nhật trong WordPress được xử lý bởi wp_update_postchức năng.

Hàm này có một số post_content_filteredgiá trị mặc định và đối với giá trị mặc định là '' (chuỗi trống).

Khi các giá trị mặc định được hợp nhất với các đối số được truyền vào chức năng thông qua wp_parse_argsnó có nghĩa là mỗi khi một bài đăng được cập nhật và post_content_filteredkhông được thông qua rõ ràng, nó sẽ được đặt thành một chuỗi trống.

Bây giờ chúng ta có thể hỏi: khi nào thì post_content_filteredrõ ràng được chuyển đến wp_update_post? Trả lời là: không bao giờ bằng WordPress.

Vì vậy, cho câu hỏi đầu tiên của bạn:

Trong những tình huống khác, dữ liệu trong cột post_content_filtered bị xóa?

Câu trả lời ngắn gọn là: mỗi khi một bài viết được cập nhật, vì bất kỳ lý do nào .

Lưu ý rằng chỉ thay đổi một trường một bản cập nhật, cụ thể, mọi thay đổi trạng thái là một bản cập nhật, ví dụ: dự thảo để xuất bản, chờ xuất bản, trong tương lai để xuất bản, xuất bản vào thùng rác (xóa bài), v.v.

Nếu một cái gì đó thay đổi trong một bài viết, sau đó post_content_filteredsẽ bị xóa; ngoại lệ duy nhất là khi post_content_filteredđược chuyển đến một cách rõ ràng wp_update_postvà như đã nói, điều này không bao giờ được thực hiện bởi WordPress.

Có cách nào để ngăn chặn điều này xảy ra không? (Ý tôi là, có cách nào để đảm bảo rằng dữ liệu được lưu trữ vĩnh viễn không?

Nếu bạn tạo trường đó bằng mã của mình và bạn muốn giữ nó, bạn phải xem mọi bản cập nhật được thực hiện bởi WordPress và ngăn chặn sự thay đổi.

Điều này nghe có vẻ khó, nhưng nếu bạn đọc câu đầu tiên trong câu trả lời này, " Mọi cập nhật bài đăng trong WordPress đều được xử lý bởi wp_update_postchức năng ", bạn hiểu rằng điều duy nhất cần thiết là xem xét chức năng đó, may mắn có các móc khác nhau .

Móc mà tôi đề nghị là wp_insert_post_datavì 2 lý do:

  • Nó chạy trước khi cập nhật, vì vậy bạn không phải khôi phục nhưng bạn có thể ngăn chặn
  • Nó truyền 2 tham số: dữ liệu mà hàm sẽ cập nhật và một mảng các tham số đã truyền, (trong trường hợp cập nhật) có chứa ID của bài đăng

Vì vậy, bằng cách sử dụng một cách đơn giản, get_postbạn có thể so sánh bài viết hiện tại như thế nào và bài đăng sẽ như thế nào: nếu bạn không thích thứ gì đó, bạn có thể thay đổi nó.

Hãy để mã:

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;

}

Có một vấn đề có thể xảy ra, trong đó chức năng trước đó ngăn chặn mọi hoạt động post_content_filtered làm sạch. Và nếu bạn , vì lý do nào, muốn xóa nó?

Tôi đã nói rằng mọi thay đổi bài đăng trên WP đều được xử lý wp_update_post, nhưng bạn không phải là WordPress.

Bạn có thể viết một hàm như:

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

Là một $wpdbtruy vấn, nó không kích hoạt bộ lọc của chúng tôi, vì vậy việc thiết lập lại không có vấn đề gì và ở mọi nơi trong mã bạn cần đặt lại post_content_filtered, bạn có thể gọi hàm này.

Bạn cũng có thể tạo metabox bằng nút 'Xóa nội dung được lọc' và khi nhấp vào nút này, chỉ cần gọi reset_post_content_filteredchức năng của bạn , ví dụ như qua Ajax.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.