Tôi có một loại bài đăng tùy chỉnh Event
có chứa các trường tùy chỉnh bắt đầu và kết thúc ngày / lần (như metaboxes trong màn hình chỉnh sửa bài đăng).
Tôi muốn đảm bảo rằng một Sự kiện không thể được công bố (hoặc lên lịch) mà không được điền ngày, vì điều đó sẽ gây ra vấn đề với các mẫu hiển thị dữ liệu Sự kiện (bên cạnh thực tế đó là một yêu cầu cần thiết!). Tuy nhiên, tôi muốn có thể có các sự kiện Dự thảo không có ngày hợp lệ trong khi chúng đang được chuẩn bị.
Tôi đã nghĩ đến việc móc nối save_post
để kiểm tra, nhưng làm thế nào tôi có thể ngăn chặn sự thay đổi trạng thái xảy ra?
EDIT1: Đây là hook tôi đang sử dụng để lưu post_meta.
// Save the Metabox Data
function ep_eventposts_save_meta( $post_id, $post ) {
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE )
return;
if ( !isset( $_POST['ep_eventposts_nonce'] ) )
return;
if ( !wp_verify_nonce( $_POST['ep_eventposts_nonce'], plugin_basename( __FILE__ ) ) )
return;
// Is the user allowed to edit the post or page?
if ( !current_user_can( 'edit_post', $post->ID ) )
return;
// OK, we're authenticated: we need to find and save the data
// We'll put it into an array to make it easier to loop though
//debug
//print_r($_POST);
$metabox_ids = array( '_start', '_end' );
foreach ($metabox_ids as $key ) {
$events_meta[$key . '_date'] = $_POST[$key . '_date'];
$events_meta[$key . '_time'] = $_POST[$key . '_time'];
$events_meta[$key . '_timestamp'] = $events_meta[$key . '_date'] . ' ' . $events_meta[$key . '_time'];
}
$events_meta['_location'] = $_POST['_location'];
if (array_key_exists('_end_timestamp', $_POST))
$events_meta['_all_day'] = $_POST['_all_day'];
// Add values of $events_meta as custom fields
foreach ( $events_meta as $key => $value ) { // Cycle through the $events_meta array!
if ( $post->post_type == 'revision' ) return; // Don't store custom data twice
$value = implode( ',', (array)$value ); // If $value is an array, make it a CSV (unlikely)
if ( get_post_meta( $post->ID, $key, FALSE ) ) { // If the custom field already has a value
update_post_meta( $post->ID, $key, $value );
} else { // If the custom field doesn't have a value
add_post_meta( $post->ID, $key, $value );
}
if ( !$value )
delete_post_meta( $post->ID, $key ); // Delete if blank
}
}
add_action( 'save_post', 'ep_eventposts_save_meta', 1, 2 );
EDIT2: và đây là những gì tôi đang cố sử dụng để kiểm tra dữ liệu bài đăng sau khi lưu vào cơ sở dữ liệu.
add_action( 'save_post', 'ep_eventposts_check_meta', 99, 2 );
function ep_eventposts_check_meta( $post_id, $post ) {
//check that metadata is complete when a post is published
//print_r($_POST);
if ( $_POST['post_status'] == 'publish' ) {
$custom = get_post_custom($post_id);
//make sure both dates are filled
if ( !array_key_exists('_start_timestamp', $custom ) || !array_key_exists('_end_timestamp', $custom )) {
$post->post_status = 'draft';
wp_update_post($post);
}
//make sure start < end
elseif ( $custom['_start_timestamp'] > $custom['_end_timestamp'] ) {
$post->post_status = 'draft';
wp_update_post($post);
}
else {
return;
}
}
}
Vấn đề chính với điều này là một vấn đề thực sự được mô tả trong một câu hỏi khác : sử dụng wp_update_post()
bên trong một save_post
cái móc sẽ kích hoạt một vòng lặp vô hạn.
EDIT3: Tôi đã tìm ra một cách để làm điều đó, bằng cách móc wp_insert_post_data
thay vì save_post
. Vấn đề duy nhất là bây giờ post_status
được hoàn nguyên, nhưng bây giờ một thông báo sai lệch có nội dung "Đăng bài đã xuất bản" hiển thị (bằng cách thêm &message=6
vào URL được chuyển hướng), nhưng trạng thái được đặt thành Dự thảo.
add_filter( 'wp_insert_post_data', 'ep_eventposts_check_meta', 99, 2 );
function ep_eventposts_check_meta( $data, $postarr ) {
//check that metadata is complete when a post is published, otherwise revert to draft
if ( $data['post_type'] != 'event' ) {
return $data;
}
if ( $postarr['post_status'] == 'publish' ) {
$custom = get_post_custom($postarr['ID']);
//make sure both dates are filled
if ( !array_key_exists('_start_timestamp', $custom ) || !array_key_exists('_end_timestamp', $custom )) {
$data['post_status'] = 'draft';
}
//make sure start < end
elseif ( $custom['_start_timestamp'] > $custom['_end_timestamp'] ) {
$data['post_status'] = 'draft';
}
//everything fine!
else {
return $data;
}
}
return $data;
}