Saya memiliki jenis posting khusus Event
yang berisi bidang tanggal / waktu kustom awal dan akhir (sebagai metabox di layar edit posting).
Saya ingin memastikan bahwa suatu Acara tidak dapat dipublikasikan (atau dijadwalkan) tanpa tanggal yang diisi, karena hal itu akan menyebabkan masalah dengan templat yang menampilkan data Acara (selain fakta bahwa itu merupakan persyaratan yang diperlukan!). Namun, saya ingin dapat memiliki acara Draft yang tidak mengandung tanggal yang valid saat sedang dalam persiapan.
Saya berpikir save_post
untuk melakukan pengecekan, tetapi bagaimana saya bisa mencegah perubahan status terjadi?
EDIT1: Ini adalah kait yang saya gunakan sekarang untuk menyimpan 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: dan inilah yang saya coba gunakan untuk memeriksa data postingan setelah menyimpan ke database.
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;
}
}
}
Masalah utama dengan ini adalah masalah yang sebenarnya dijelaskan dalam pertanyaan lain : menggunakan di wp_update_post()
dalam save_post
kail memicu loop tak terbatas.
EDIT3: Saya menemukan cara untuk melakukannya, dengan mengait wp_insert_post_data
bukannya save_post
. Satu-satunya masalah adalah bahwa sekarang post_status
sudah dikembalikan, tetapi sekarang pesan yang menyesatkan mengatakan "Posting diterbitkan" muncul (dengan menambahkan &message=6
ke URL yang dialihkan), tetapi statusnya diatur ke Konsep.
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;
}
sumber
OK, ini akhirnya bagaimana saya akhirnya melakukannya: panggilan Ajax ke fungsi PHP yang melakukan pengecekan, semacam terinspirasi oleh jawaban ini dan menggunakan tip cerdas dari pertanyaan yang saya ajukan di StackOverflow . Yang penting, saya memastikan bahwa hanya ketika kami ingin mempublikasikan pengecekan selesai, sehingga Draft selalu dapat disimpan tanpa pengecekan. Ini akhirnya menjadi solusi yang lebih mudah untuk benar-benar dicegah publikasi posting. Mungkin membantu orang lain, jadi saya menulisnya di sini.
Pertama, tambahkan Javascript yang diperlukan:
Kemudian, fungsi yang menangani pemeriksaan:
Fungsi ini kembali
true
jika semuanya baik-baik saja, dan mengirimkan formulir untuk mempublikasikan posting oleh saluran normal. Jika tidak, fungsi mengembalikan pesan kesalahan yang ditampilkan sebagaialert()
, dan formulir tidak dikirimkan.sumber
delayed_autosave(); //get data from textarea/tinymce field jQuery('#publish').data("valid", true).trigger('click'); //publish post
Banyak terima kasih.Saya pikir cara terbaik untuk menyelesaikannya adalah bukan MENCEGAH perubahan status agar tidak terjadi sebanyak REVERT jika itu terjadi. Misalnya: Anda mengait
save_post
, dengan prioritas sangat tinggi (sehingga kait akan menyala sangat terlambat, yaitu setelah Anda melakukan meta insert Anda), lalu periksapost_status
pos yang baru saja disimpan, dan perbarui ke tertunda (atau konsep atau terserah) jika tidak memenuhi kriteria Anda.Strategi alternatif adalah mengaitkan
wp_insert_post_data
untuk mengatur post_status secara langsung. Kerugian dari metode ini, sejauh yang saya ketahui, adalah bahwa Anda tidak akan memasukkan postmeta ke dalam database, jadi Anda harus memprosesnya, dll di tempat untuk melakukan pemeriksaan Anda, kemudian memprosesnya lagi untuk memasukkan itu ke dalam basis data ... yang bisa menjadi banyak overhead, baik dalam kinerja atau dalam kode.sumber
save_post
dengan prioritas 1 untuk menyimpan bidang meta dari metabox; apa yang Anda usulkan kemudian adalah memiliki kaitan keduasave_post
dengan prioritas, katakanlah, 99? Apakah ini menjamin integritas? Bagaimana jika karena suatu alasan kait pertama menyala, metadata dimasukkan dan pos diterbitkan, tetapi kait kedua tidak, sehingga Anda berakhir dengan bidang yang tidak valid?post_status
semua dalam satu fungsi yang menjalankan satu panggilan ke kail jika Anda mau.save_post
tetapi itu memicu loop tak terbatas.if( get_post_status( $post_id ) == 'publish' )
apa yang ingin Anda gunakan, karena Anda akan mendefinisikan ulang data$wpdb->posts
, bukan data masuk$_POST[]
.Metode terbaik mungkin JAVASCRIPT:
sumber
Maaf saya tidak bisa memberikan jawaban langsung tetapi saya ingat melakukan sesuatu yang serupa baru-baru ini saya hanya tidak ingat persis bagaimana caranya. Saya pikir saya mungkin melakukannya tentang cara - sesuatu seperti saya telah menjadi nilai default dan jika orang itu tidak mengubahnya saya mengambil ini dalam pernyataan if jadi ->
if(category==default category) {echo "You didn't pick a category!"; return them to the post creation page; }
maaf ini bukan jawaban langsung tetapi harapan ini sedikit membantu.sumber