เป็นไปได้หรือไม่ภายในการกระทำ save_post เพื่อตรวจสอบว่ามีการสร้างโพสต์ใหม่หรือโพสต์ที่มีอยู่กำลังอัปเดตหรือไม่
เป็นไปได้หรือไม่ภายในการกระทำ save_post เพื่อตรวจสอบว่ามีการสร้างโพสต์ใหม่หรือโพสต์ที่มีอยู่กำลังอัปเดตหรือไม่
คำตอบ:
ตั้งแต่ WordPress เวอร์ชั่น 3.7 - IIRC - the save_post
hook - ข้อมูลเพิ่มเติมเกี่ยวกับ hook และการใช้งานที่การอ้างอิงรหัส:save_post
และCodex:save_post
- มีพารามิเตอร์ตัวที่สาม$update
ซึ่งสามารถใช้เพื่อกำหนดได้
@param int $ post_ID รหัสโพสต์
@param WP_Post $ โพสต์วัตถุโพสต์
@param bool $ update ไม่ว่าจะเป็นโพสต์ที่มีอยู่จะถูกอัพเดทหรือไม่
บันทึก:
$update
ไม่เสมอtrue
- คุณสามารถดูและทดสอบด้วยตัวคุณเองด้วยรหัสด้านล่าง มันไม่ได้รับการบันทึกไว้อย่างดีแม้ว่าอาจจะห่างไกลจากชื่อที่เหมาะสมและด้วยเหตุนี้จึงสร้างความคาดหวังที่ทำให้เข้าใจผิด รหัสด้านล่างนี้สามารถใช้สำหรับการแก้ไขข้อบกพร่องบางอย่างเล่นรอบเมื่อมีการสกัดกั้นการดำเนินการรหัสเพราะมิฉะนั้นคุณจะไม่เห็นข้อมูล / ข้อความ ฉันคิดว่าผู้ร้ายที่มีพฤติกรรมหลอกลวงคือการจัดการการแก้ไขและการบันทึกอัตโนมัติ - ซึ่งอาจปิดใช้งานได้ แต่ฉันไม่แนะนำและไม่ได้ทดสอบ ไม่แน่ใจว่านี่จะรับประกันตั๋ว Tracหรือไม่ดังนั้นฉันไม่ได้เปิดถ้าคุณคิดอย่างนั้นโปรดไปที่ลิงค์และทำมันเอง นอกเหนือจากที่ระบุไว้ในความคิดเห็นหากคุณมีปัญหาเฉพาะให้โพสต์คำถามใหม่
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
พารามิเตอร์เป็นจริงเสมอแม้เมื่อมีการโพสต์ใหม่ ดังนั้นพารามิเตอร์นี้ไม่มีประโยชน์ ไม่แน่ใจว่ามันใช้งานได้จริงหรือไม่ แต่แน่นอนว่านรกไม่ทำงานในแบบที่บันทึกไว้ใน wordpress 4.8 เวอร์ชันล่าสุด
wp_publish_post
นั่นก็ใช่ wp_insert_post
แต่ที่ไม่เป็นความจริงสำหรับการใช้งานใน ฉันได้เขียนฟังก์ชั่นการแก้ปัญหาฉันเพิ่มลงในคำตอบ
save_post
เบ็ดมีพารามิเตอร์ที่ 3 ที่ตั้งเสมอ TRUE จึงไม่แน่ใจว่าสิ่งนี้จะทำอย่างไรกับตะขออื่น ๆ ไม่พูดเกี่ยวกับตะขออื่น ๆ ฉันกำลังพูดถึงเบ็ดในคำตอบของคุณ สิ่งนี้ไม่ถูกต้อง
wp_insert_post()
ที่ผมกล่าวว่าเบ็ดที่เกิดขึ้นสองครั้งwp_publish_post()
, หลังมีการโพสต์ในอนาคตเท่านั้นที่มีการตั้งค่าที่จะเสมอ$update
true
มิฉะนั้นในการไปwp_insert_post()
, ไม่ได้เสมอ$update
true
วิธีที่ฉันทำการตรวจสอบนี้ (ภายในฟังก์ชั่น hooked) คือการเปรียบเทียบวันที่โพสต์และวันที่แก้ไข (ใน GMT สำหรับมาตรฐาน)
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' );
สิ่งนี้ทำงานได้แม้ในขณะที่สร้างโพสต์นั้นมีวันที่ 'แก้ไข' ซึ่งติดตั้งอยู่ซึ่งตรงกับวันที่ 'สร้าง' แต่เราอนุญาตให้มีความแปรปรวน 1 วินาทีในกรณีที่มีการทำเครื่องหมายที่สองในระหว่างการสร้าง โพสต์
post_date_gmt
เป็น2019-03-12 01:31:30
และเป็นpost_modified_gmt
2019-03-12 01:31:31
:(
ฉันลงเอยเพียงแค่ตรวจสอบว่ามีค่าที่กำหนดเองก่อนที่จะตั้งค่าหรือไม่ ด้วยวิธีนี้ถ้าเป็นการโพสต์ที่สร้างขึ้นใหม่ค่าที่กำหนดเองจะยังไม่มีอยู่
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');
ตัวอย่างคำตอบ ialocin ด้วย "ปรับปรุง" paremeter:
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)
หรือรักษาบล็อกใหม่ครั้งแรก if( ! $update )
แต่การใช้ หลังจะได้รับ OP ไปสู่การปฏิบัติที่ดีขึ้นและเป็นที่ต้องการมากกว่าวิธีการของคุณโดยมาตรฐานการเข้ารหัส WordPress ในกรณีเช่นผู้ประกอบการที่สาม
คุณสามารถใช้ pre_post_update action hook สำหรับรหัสอัปเดตและ save_post สำหรับรหัสโพสต์ใหม่ ใช้งานได้ก่อนมีการอัปเดตโพสต์
save_post
hook ถูกไล่ออกทั้งเมื่อโพสต์ถูกสร้างและอัปเดต (หลังจาก WordPress บันทึกไปยังฐานข้อมูลแล้ว) pre_post_update
ถูกเรียกใช้เมื่อมีการอัปเดตโพสต์ แต่ก่อนโพสต์จะได้รับการอัปเดตซึ่งอาจมีความสำคัญ
ดังที่ Darshan Thanki พูดถึง (และ Stephen Harris เพิ่มเติมอย่างละเอียด) คุณสามารถใช้pre_post_update
เพื่อประโยชน์ของคุณ
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;
}
เหตุผลที่ฉันใช้ globals นั้นเป็นเพราะfunction is_new_post() use ( &$new_post )
ไม่ถูกต้องใน PHP (ตกตะลึง ... ) ดังนั้นการดึงตัวแปรนั้นลงในขอบเขตฟังก์ชั่นใช้งานไม่ได้ - ดังนั้นทั่วโลก
โปรดทราบว่าสิ่งนี้สามารถใช้งานได้อย่างน่าเชื่อถือภายใน / หลังจากsave_post
เหตุการณ์ (ซึ่งโดยปกติจะเพียงพอแล้วอย่างน้อยสำหรับสิ่งที่เรากำลังทำอยู่)
เมื่อมีการทริกเกอร์ save_post ข้อมูลทั้งหมดเกี่ยวกับโพสต์นั้นมีอยู่แล้วดังนั้นในทางทฤษฎีคุณสามารถใช้
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');
แม้ว่านี่จะยังไม่ได้ทดสอบ =)
save_post
โพสต์ตัวเองจะถูกบันทึกไว้ในฐานข้อมูลแล้วดังนั้นget_posts
จะส่งคืนโพสต์ปัจจุบัน
get_post_status()
วิธีการที่ใช้ในตัวฟังก์ชั่นและนอกเหนือไปจากฐานข้อมูลไม่มีจะเกี่ยวข้องอีก
$post_status = get_post_status();
if ( $post_status != 'draft' ) {
//draft
} else {
//not a draft: can be published, pending, etc.
}
โปรดทราบว่าอาจไม่เหมาะสมหากคุณวางแผนที่จะตั้งสถานะในภายหลังเป็น "ฉบับร่าง" - คำแนะนำของคุณจะถูกทำซ้ำในครั้งต่อไปที่คุณจะอัปเดตโพสต์ ขึ้นอยู่กับบริบทคุณอาจต้องการพิจารณาสตริงต่างๆที่สามารถส่งคืนได้get_post_status()
เพื่อสร้างสถานการณ์ที่เหมาะสมยิ่งขึ้น
ดู Codex สำหรับget_post_status ()และสถานะการโพสต์
ค่าที่เป็นไปได้คือ:
- 'เผยแพร่' - โพสต์หรือหน้าที่เผยแพร่
- 'รอการอนุมัติ' - โพสต์กำลังรอการตรวจสอบ
- 'ฉบับร่าง' - โพสต์ในสถานะฉบับร่าง
- 'auto-draft' - โพสต์ที่สร้างขึ้นใหม่โดยไม่มีเนื้อหา
- 'อนาคต' - โพสต์เพื่อเผยแพร่ในอนาคต
- 'ส่วนตัว' - ไม่ปรากฏแก่ผู้ใช้ที่ไม่ได้เข้าสู่ระบบ
- 'สืบทอด' - การแก้ไข ดูที่ get_children
- 'ถังขยะ' - โพสต์อยู่ในถังขยะ เพิ่มด้วยเวอร์ชัน 2.9
save_post()
จะถูกดำเนินการเป็นครั้งแรก แต่ในระหว่างการดำเนินการget_post_status()
นั้นจะส่งคืน 'เผยแพร่' และไม่ใช่ 'ฉบับร่าง' แม้ว่าจะอยู่ในขั้นตอนการเผยแพร่เท่านั้น