Kiểm tra cập nhật so với bài đăng mới trên hành động save_post


21

Có thể trong hành động save_post để xác định xem đó là một bài viết mới được tạo ra hay một bài đăng hiện có đang được cập nhật?


Tôi không nghĩ rằng điều này là có thể. Xem bình luận của tôi dưới đây câu trả lời của @ moraleida. Tại sao bạn cần biết nếu đó là một bài viết mới hoặc đang được cập nhật? Có thể có một cách làm việc xung quanh hoặc một cách tiếp cận khác.
Stephen Harris

Câu trả lời:


16

Kể từ phiên bản WordPress 3.7. - IIRC - save_posthook - thông tin thêm về hook và cách sử dụng của nó tại Code Reference:save_postCodex:save_post - có tham số thứ ba $updatecó thể được sử dụng để xác định điều đó.

@param int $ post_ID ID bài.
@param WP_Post $ đăng bài Đối tượng.
@param bool $ update Cho dù đây có phải là một bài viết đang được cập nhật hay không.


Chú thích:

$updatekhông phải lúc nào cũng vậy true- bạn có thể tự mình xem và kiểm tra nó với mã bên dưới. Nó không được ghi chép tốt mặc dù, có thể xa được đặt tên tối ưu, và do đó tạo ra những kỳ vọng sai lệch. Mã bên dưới có thể được sử dụng cho một số gỡ lỗi, chơi xung quanh khi nào để chặn thực thi mã, vì nếu không bạn sẽ không thấy thông tin / tin nhắn. Tôi nghĩ, thủ phạm trong hành vi lừa đảo là việc xử lý các sửa đổi và lưu tự động - có thể bị vô hiệu hóa, nhưng tôi không khuyến nghị điều đó và đã không kiểm tra nó. Không chắc chắn điều này có đảm bảo Vé Trac không , vì vậy tôi đã không mở, nếu bạn nghĩ vậy, vui lòng theo liên kết và tự làm. Bên cạnh đó, như đã nêu trong các bình luận, nếu bạn có một vấn đề cụ thể, hãy đăng một câu hỏi mới.

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();
}

3
Các $updatetham số là luôn luôn đúng ngay cả khi nó là một bài viết mới. Vì vậy, tham số này là vô dụng. Không chắc nó có hoạt động được không, nhưng chắc chắn rằng địa ngục không hoạt động theo cách nó được ghi lại trong phiên bản mới nhất của wordpress 4.8.
Solomon Closson

@SolomonClosson Nếu bạn xem wp_publish_post, thì có. Nhưng điều đó không đúng với việc sử dụng nó wp_insert_post. Tôi đã viết một hàm gỡ lỗi, tôi thêm nó vào câu trả lời.
Nicolai

@SolomonClosson Nếu bạn có một vấn đề cụ thể thực sự, xin vui lòng đặt một câu hỏi mới. Hãy xem các bản sửa đổi cho chức năng gỡ lỗi một lời giải thích.
Nicolai

Các save_postmóc có một tham số thứ 3 mà luôn đặt là TRUE, vì vậy không chắc chắn điều này đã làm với móc khác, chứ không phải nói về móc khác. Tôi đang nói về cái móc trong câu trả lời của bạn. Điều này là không chính xác.
Solomon Closson

@SolomonClosson Như tôi đã nói móc đang xảy ra hai lần: wp_insert_post(), wp_publish_post(). Sau này chỉ là bài viết trong tương lai, có $updateđược đặt luôn true. Mặt khác, liên quan đến wp_insert_post(), $updatekhông phải luôn luôn true.
Nicolai

11

Cách tôi thực hiện kiểm tra này (trong chức năng được nối) là so sánh ngày đăng và ngày sửa đổi (theo GMT để chuẩn hóa)

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' );

Điều này hoạt động vì ngay cả khi tạo bài đăng cũng có ngày 'được sửa đổi' kèm theo ngày, chính xác giống như ngày 'được tạo', nhưng chúng tôi cho phép chênh lệch 1 giây trong trường hợp một giây trôi qua trong quá trình tạo bài.


1
Đôi khi post_date_gmt2019-03-12 01:31:30post_modified_gmt2019-03-12 01:31:31. :(
Anh Yifei 何 一 非

1
@HeYifei 何 一 điểm tốt, nếu quá trình xử lý bắt đầu vào cuối một giây nhất định, điều này có thể xảy ra. Tôi đã cập nhật câu trả lời của mình, cảm ơn
James Cushing

Các bạn, chỉ là một thông tin. Các hook được bắn vào khôi phục và xóa một bài.
melvin

6

Tôi cuối cùng chỉ kiểm tra sự tồn tại của một giá trị tùy chỉnh trước khi đặt nó. Theo cách đó, nếu đó là một bài đăng mới được tạo, giá trị tùy chỉnh sẽ không tồn tại.

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');

Để làm việc này, trước tiên bạn có phải tạo trường tùy chỉnh bằng add_post_meta không?
MF1

Theo Codex: [update_post_meta] có thể được sử dụng thay cho hàm add_post_meta (). codex.wordpress.org/Function_Reference/update_post_meta
hereswhatidid

Điều này có thể thất bại, nếu bài viết được tạo trước khi hook code được kích hoạt thông qua kích hoạt plugin. Các bài đăng cũ hơn không có bộ meta, do đó bản cập nhật đầu tiên cho chúng sẽ được coi là mới.
Vasu Chawla

4

Ví dụ về câu trả lời của ialocin với paremeter "update":

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 );

2
Một cách tốt hơn để cấu trúc điều này sẽ là đặt khối cập nhật lên trước, cho phép chỉ thực hiện if($update)hoặc giữ khối mới trước nhưng sử dụng if( ! $update ). Cái sau sẽ giúp OP thực hành tốt hơn và được ưa thích hơn phương pháp của bạn bởi các tiêu chuẩn mã hóa WordPress trong các trường hợp như toán tử ternary
James Cushing

1

Bạn có thể sử dụng hook hành động pre_post_update cho mã cập nhật và save_post cho mã bài đăng mới. Nó hoạt động trước khi một bài viết được cập nhật.


4
save_posthook được kích hoạt cả khi bài đăng được tạo và cập nhật (sau khi WordPress đã lưu nó vào cơ sở dữ liệu). pre_post_updateđược kích hoạt khi một bài viết được cập nhật, nhưng trước khi bài viết được cập nhật - điều này có thể quan trọng.
Stephen Harris

1

Như Darshan Thanki gợi ý (và Stephen Harris nói thêm chi tiết), bạn có thể sử dụng pre_post_updatelợi thế của mình.

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;
}

Lý do tại sao tôi sử dụng toàn cầu là vì function is_new_post() use ( &$new_post )không hợp lệ trong PHP (gây sốc ...) nên việc kéo biến đó vào phạm vi hàm không hoạt động - do đó là toàn cầu.

Lưu ý rằng điều này thực sự chỉ có thể được sử dụng một cách đáng tin cậy trong / sau save_postsự kiện (thường là đủ, ít nhất là cho những gì chúng tôi đang làm với nó).


0

Khi save_post được kích hoạt, tất cả thông tin về bài đăng đó đã có sẵn, vì vậy về lý thuyết bạn có thể sử dụng

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');

Điều này chưa được kiểm tra, mặc dù. =)


3
Vào thời điểm bạn nhận được save_postbài đăng, nó đã được lưu vào cơ sở dữ liệu - vì vậy get_postssẽ trả lại bài đăng hiện tại.
Stephen Harris

Đúng, chỉ cần kiểm tra nó trong Codex. Cảm ơn cho những người đứng đầu lên.
moraleida

0

Một cách tiếp cận khác sử dụng hàm tích hợp và không bổ sung vào cơ sở dữ liệu sẽ liên quan get_post_status().

$post_status = get_post_status();
if ( $post_status != 'draft' ) {
    //draft
} else { 
    //not a draft: can be published, pending, etc. 
}

Tuy nhiên, xin lưu ý rằng điều đó có thể không phù hợp nếu sau đó bạn dự định đặt lại trạng thái thành "bản nháp" - hướng dẫn của bạn sẽ được lặp lại vào lần tiếp theo bạn sẽ cập nhật bài đăng. Tùy thuộc vào ngữ cảnh, bạn có thể muốn xem xét các chuỗi khác nhau có thể được trả về get_post_status()để xây dựng một kịch bản phù hợp hơn.

Xem Codex cho get_post_status ()Trạng thái bài

Các giá trị có thể là:

  • 'xuất bản' - Một bài đăng hoặc trang được xuất bản
  • 'Đang chờ xử lý' - bài đăng đang chờ xem xét
  • 'bản nháp' - một bài đăng trong trạng thái bản nháp
  • 'tự động phác thảo' - một bài đăng mới được tạo, không có nội dung
  • 'Tương lai' - một bài đăng để xuất bản trong tương lai
  • 'Riêng tư' - không hiển thị đối với người dùng chưa đăng nhập
  • 'kế thừa' - một bản sửa đổi. xem get_children.
  • 'thùng rác' - bài viết nằm trong thùng rác. được thêm vào với Phiên bản 2.9.

Tôi không nghĩ rằng điều này làm những gì được yêu cầu. Nếu tôi tạo một bài đăng mới và sau đó nhấn 'Xuất bản', save_post()được thực hiện lần đầu tiên, nhưng trong quá trình thực hiện đó get_post_status()đã trả về 'xuất bản' và không phải là 'bản nháp', mặc dù nó chỉ đang trong quá trình xuất bản.
cgogolin
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.