Apakah mungkin dalam tindakan save_post untuk menentukan apakah itu posting baru yang dibuat atau posting yang ada sedang diperbarui?
Apakah mungkin dalam tindakan save_post untuk menentukan apakah itu posting baru yang dibuat atau posting yang ada sedang diperbarui?
Jawaban:
Sejak WordPress versi 3.7. - IIRC - save_post
hook - informasi lebih lanjut tentang hook dan penggunaannya di Code Reference:save_post
dan Codex:save_post
- memiliki parameter ketiga $update
yang dapat digunakan untuk menentukan hal itu.
@par int $ post_ID ID Posting.
@param WP_Post $ post Objek posting.
@param bool $ update Apakah ini postingan yang ada sedang diperbarui atau tidak.
catatan:
$update
tidak selalu true
- Anda dapat melihat dan mengujinya sendiri dengan kode di bawah ini. Ini tidak didokumentasikan dengan baik, mungkin jauh dari nama yang optimal, dan karenanya menciptakan harapan yang menyesatkan. Kode di bawah ini dapat digunakan untuk debugging, bermain-main dengan kapan untuk mencegat eksekusi kode, karena jika tidak, Anda tidak akan melihat informasi / pesan. Saya pikir, biang keladinya dalam perilaku menipu adalah penanganan revisi dan penyelamatan otomatis - yang bisa dinonaktifkan, tetapi saya tidak merekomendasikannya, dan belum mengujinya. Tidak yakin apakah ini menjamin Tiket Trac , jadi saya tidak membukanya, jika menurut Anda, ikuti tautannya dan lakukan sendiri. Selain itu, seperti yang dinyatakan dalam komentar, jika Anda memiliki masalah khusus, posting pertanyaan baru.
add_action( 'save_post', 'debug_save_post_update', 10, 3 );
function debug_save_post_update( $ID, $post, $update ) {
echo '<pre>';
print_r( $post ); echo '<br>';
echo '$update == ';
echo $update ? 'true' : 'false';
//conditions
if( ! $update && $post->post_status == "auto-draft" ) {
// applies to new post
echo ' && $post->post_status == "auto-draft"';
//die();
} else if ( ! $update ) {
// applies basically to the (auto saved) revision
//die();
} else {
// applies to updating a published post
// when there is a revision, which is normally the case,
// standard behavior of WordPress, then it is considered
// an update, which is where the confusion sets in
// there are other methods, like checking time or post status
// depending on your use case it might be more appropriate
// to use one of those alternatives
//die();
}
echo '</pre>';
//die();
}
$update
parameter adalah selalu benar bahkan ketika itu adalah posting baru. Jadi parameter ini tidak berguna. Tidak yakin apakah itu pernah berhasil sama sekali, tetapi pasti tidak berfungsi seperti yang didokumentasikan dalam versi terbaru dari wordpress 4.8.
wp_publish_post
, maka ya. Tapi itu tidak benar untuk penggunaannya wp_insert_post
. Saya telah menulis fungsi debug, saya menambahkannya ke jawabannya.
save_post
kait memiliki parameter-3 yang selalu diatur ke TRUE, jadi tidak yakin apa ini ada hubungannya dengan kait lainnya, tidak berbicara tentang kait lainnya. Saya sedang berbicara tentang jawaban Anda. Ini salah.
wp_insert_post()
, wp_publish_post()
. Yang terakhir hanya posting masa depan, ada $update
diatur untuk selalu true
. Kalau tidak, dalam hal wp_insert_post()
, $update
tidak selalu true
.
Cara saya melakukan pemeriksaan ini (dalam fungsi terkait) adalah membandingkan tanggal posting dan tanggal yang dimodifikasi (dalam GMT untuk standarisasi)
function check_new_vs_update( $post_id ){
$myPost = get_post($post_id);
$post_created = new DateTime( $myPost->post_date_gmt );
$post_modified = new DateTime( $myPost->post_modified_gmt );
if( abs( $post_created->diff( $post_modified )->s ) <= 1 ){
// New post
}else{
// Updated post
}
}
add_action('save_post', 'check_new_vs_update' );
Ini berfungsi karena meskipun pada saat pembuatan posting memiliki tanggal 'dimodifikasi' yang melekat padanya, yang persis sama dengan tanggal 'dibuat', tetapi kami mengizinkan varian 1 detik, jika kedua detik berlalu selama pembuatan pos.
post_date_gmt
is 2019-03-12 01:31:30
dan the post_modified_gmt
is 2019-03-12 01:31:31
. :(
Saya akhirnya hanya memeriksa keberadaan nilai khusus sebelum menyetelnya. Dengan begitu, jika itu adalah kiriman yang baru dibuat, nilai khusus belum akan ada.
function attributes_save_postdata($post_id) {
if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) return;
if (!wp_verify_nonce($_POST['_attributes_noncename'], plugin_basename(__FILE__))) return;
if ('page' == $_POST['post_type']) {
if (!current_user_can('edit_page', $post_id)) return;
} else {
if (!current_user_can('edit_post', $post_id)) return;
}
$termid = get_post_meta($post_id, '_termid', true);
if ($termid != '') {
// it's a new record
$termid = 'update';
} else {
// it's an existing record
}
update_post_meta($post_id, '_termid', $termid);
}
add_action('save_post', 'attributes_save_postdata');
Contoh jawaban ialocin dengan paremeter "perbarui":
function save_func($ID, $post,$update) {
if($update == false) {
// do something if its first time publish
} else {
// Do something if its update
}
}
add_action( 'save_post', 'save_func', 10, 3 );
if($update)
atau menjaga blok baru terlebih dahulu tetapi menggunakan if( ! $update )
. Yang terakhir akan mendapatkan OP menjadi praktik yang lebih baik dan lebih disukai daripada metode Anda dengan standar pengkodean WordPress dalam kasus-kasus seperti operator ternary
Anda dapat menggunakan kait tindakan pre_post_update untuk kode pembaruan dan save_post untuk kode posting baru. Ini berfungsi sebelum sebuah posting diperbarui.
save_post
hook dipecat baik ketika posting dibuat dan diperbarui (setelah WordPress telah disimpan ke database). pre_post_update
dipecat ketika posting diperbarui, tetapi sebelum posting diperbarui - ini bisa menjadi penting.
Seperti Darshan Thanki mengisyaratkan (dan Stephen Harris lebih lanjut diuraikan), Anda dapat menggunakan pre_post_update
untuk keuntungan Anda.
global $___new_post;
$___new_post = true;
add_action(
'pre_post_update',
function() {
global $___new_post;
$___new_post = false;
},
0
);
function is_new_post() {
global $___new_post;
return $___new_post;
}
Alasan mengapa saya menggunakan global adalah karena function is_new_post() use ( &$new_post )
tidak valid dalam PHP (mengejutkan ...) jadi menarik variabel itu ke dalam lingkup fungsi tidak berfungsi - maka global.
Perhatikan bahwa ini benar-benar hanya dapat digunakan secara andal di dalam / setelah save_post
acara (yang biasanya cukup, setidaknya untuk apa yang kita lakukan dengannya).
Ketika save_post dipicu, semua informasi tentang pos itu sudah tersedia, jadi secara teori Anda bisa menggunakan
function f4553265_check_post() {
if (!get_posts($post_id)) {
// if this is a new post get_posts($post_id) should return null
} else {
// $post_id already exists on the database
}
}
add_action('save_post','f4553265_check_post');
ini belum teruji. =)
save_post
pos itu sendiri sudah disimpan ke database - demikian juga get_posts
akan mengembalikan pos saat ini.
Pendekatan lain yang menggunakan fungsi built-in dan tidak ada penambahan ke database akan melibatkan get_post_status()
.
$post_status = get_post_status();
if ( $post_status != 'draft' ) {
//draft
} else {
//not a draft: can be published, pending, etc.
}
Namun perhatikan bahwa mungkin tidak tepat jika Anda berencana untuk mengatur kembali status ke "draft" nanti - instruksi Anda akan diulangi saat berikutnya Anda akan memperbarui posting. Tergantung pada konteksnya, Anda mungkin ingin mempertimbangkan berbagai string yang dapat dikembalikan dengan get_post_status()
membangun skenario yang lebih tepat.
Lihat Codex untuk get_post_status () dan Status Posting
Nilai yang mungkin adalah:
- 'publish' - Posting atau halaman yang dipublikasikan
- 'tertunda' - pos adalah peninjauan tertunda
- 'draft' - posting dalam status draft
- 'auto-draft' - posting yang baru dibuat, tanpa konten
- 'masa depan' - sebuah posting untuk diterbitkan di masa depan
- 'pribadi' - tidak terlihat oleh pengguna yang tidak masuk
- 'mewarisi' - sebuah revisi. lihat get_children.
- 'trash' - pos ada di trashbin. ditambahkan dengan Versi 2.9.
save_post()
dieksekusi untuk pertama kalinya, tetapi selama eksekusi get_post_status()
sudah kembali 'terbitkan' dan bukan 'draft', meskipun itu hanya dalam proses penerbitan.