save_post 작업에서 업데이트 및 새 게시물 확인


21

save_post 조치 내에서 새 게시물이 작성되는지 또는 기존 게시물이 업데이트 중인지 판별 할 수 있습니까?


나는 이것이 가능하지 않다고 생각합니다. @moraleida의 답변 아래 내 의견을 참조하십시오. 새 게시물인지 업데이트 중인지 왜 알아야합니까? 해결 방법이나 다른 방법이있을 수 있습니다.
Stephen Harris

답변:


16

WordPress 버전 3.7 이후. -IIRC- save_post후크 -Code Reference :save_postCodex :save_post 에서 후크 및 후크 사용법에 대한 자세한 정보 : - $update이를 결정하는 데 사용할 수 있는 세 번째 매개 변수 가 있습니다.

@param int $ post_ID 게시물 ID.
@param WP_Post $ post 포스트 오브젝트.
@param bool $ update 업데이트중인 기존 게시물인지 여부입니다.


노트 :

$update항상 그런 것은 아닙니다 true. 아래 코드를 통해 직접 테스트하고 테스트 할 수 있습니다. 그러나 최적의 이름과는 거리가 멀기 때문에 잘 문서화되어 있지 않으므로 잘못된 예상을 만듭니다. 아래 코드는 일부 디버깅에 사용될 수 있습니다. 그렇지 않으면 정보 / 메시지가 표시되지 않기 때문에 코드 실행을 언제 가로 챌지를 사용해야합니다. 기만적인 행동의 원인은 수정 및 자동 저장을 처리하는 것입니다.이 기능은 비활성화 될 수 있지만 권장하지 않으며 테스트하지 않았습니다. 이것이 Trac Ticket을 보증하는지 확실 하지 않으므로 티켓을 열지 않았습니다. 그렇다고 생각되면 링크를 따라 직접하십시오. 그 외에도 의견에 명시된 바와 같이 특정 문제가 있으면 새로운 질문을 게시하십시오.

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
$update가 새 게시물 인 경우에도 매개 변수는 항상 사실이다. 따라서이 매개 변수는 쓸모가 없습니다. 그것이 전혀 효과가 없었는지 확실하지 않지만 최신 버전의 wordpress 4.8에 문서화 된 방식으로 작동하지 않는 것은 확실합니다.
Solomon Closson

@SolomonClosson을 살펴보면 wp_publish_post그렇습니다. 그러나의 사용법에 대해서는 사실이 아닙니다 wp_insert_post. 디버그 함수를 작성하고 답변에 추가합니다.
Nicolai

@SolomonClosson 실제적인 구체적인 문제가 있다면, 새로운 질문을하십시오. 디버그 기능의 개정판에서 설명을 살펴보십시오.
Nicolai

save_post후크는 항상하지 않도록이되지 않은 다른 후크에 대해 말하기, 다른 후크와 무슨 상관이 TRUE로 설정되어있는 3 매개 변수가 있습니다. 나는 당신의 대답의 고리에 대해 이야기하고 있습니다. 이것은 올바르지 않습니다.
Solomon Closson

@SolomonClosson으로 나는 후크가 두 번 발생 말했다 wp_insert_post(), wp_publish_post(). 후자는 미래의 게시물 일 뿐이며 $update항상로 설정되어 있습니다 true. 그렇지 않으면,에 관해서 wp_insert_post(), $update항상하지 않습니다 true.
Nicolai

11

이 확인을 수행하는 방법 (후크 기능 내)은 게시 날짜와 수정 날짜를 비교하는 것입니다 (표준화를 위해 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 초의 차이를 허용합니다. 게시물.


1
때로는 post_date_gmtis 2019-03-12 01:31:30post_modified_gmtis 2019-03-12 01:31:31입니다. :(
He Yifei 何 一 非

1
@HeYifei 何 一 非 좋은 지적, 처리가 주어진 초의 끝에서 시작되면, 이것은 일어날 수 있습니다. 답변을 업데이트했습니다. 감사합니다
James Cushing

여러분, 정보 일뿐입니다. 게시물을 복원하고 삭제하면 후크가 시작됩니다.
멜빈

6

설정하기 전에 사용자 정의 값이 있는지 확인했습니다. 그렇게하면 새로 작성된 게시물 인 경우 사용자 정의 값이 아직 존재하지 않습니다.

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

이것이 작동하려면 먼저 add_post_meta를 사용하여 사용자 정의 필드를 작성해야합니까?
MF1

코덱별로 : add_post_meta () 함수 대신 [update_post_meta]를 사용할 수 있습니다. codex.wordpress.org/Function_Reference/update_post_meta
hereswhatidid

플러그인 활성화를 통해 코드 후크가 활성화되기 전에 게시물이 작성된 경우 실패 할 수 있습니다. 오래된 게시물에는 메타 세트가 없으므로 첫 번째 업데이트는 새로운 것으로 간주됩니다.
Vasu Chawla

4

"업데이트"파레 미터를 사용한 ialocin의 예 :

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
이를 구성하는 더 좋은 방법은 업데이트 블록을 먼저 배치 if($update)하고 새 블록을 먼저 수행 하거나 유지하면서을 사용하는 것 if( ! $update )입니다. 후자는 OP를 더 잘 연습하고 삼항 연산자
James Cushing

1

업데이트 코드에는 pre_post_update 작업 후크를 사용하고 새 포스트 코드에는 save_post를 사용할 수 있습니다. 게시물이 업데이트되기 전에 작동합니다.


4
save_post후크는 게시물이 작성되고 업데이트 될 때 (WordPress가 데이터베이스에 저장 한 후) 모두 발생합니다. pre_post_update게시물이 업데이트 될 때 시작되지만 게시물이 업데이트 되기 전에 시작 됩니다. 이는 중요 할 수 있습니다.
Stephen Harris

1

Darshan Thanki가 암시하고 (스티븐 해리스가 더 자세히 설명했듯이) 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 (shocking ...)에서 유효하지 않기 때문에 해당 변수를 함수 범위로 가져 오는 것이 작동하지 않으므로 전역입니다.

이것은 save_post이벤트 내 / 후에 만 ​​실제로 안정적으로 사용될 수 있습니다 (적어도 우리가하는 일에 충분합니다).


0

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

그러나 이것은 테스트되지 않았습니다. =)


3
save_post게시물 자체에 도착할 때 이미 데이터베이스에 저장되었으므로 get_posts현재 게시물을 반환합니다.
Stephen Harris

사실, 코덱스에서 확인했습니다. 헤드 업 주셔서 감사합니다.
moraleida

0

A는 기능을 내장하고 데이터베이스에 더 첨가는 포함하지 않을 것이다 사용하는 또 다른 방법 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()더 적합한 시나리오를 빌드하기 위해 리턴 할 수있는 다양한 문자열을 고려할 수 있습니다 .

get_post_status ()게시 상태는 Codex를 참조하십시오.

가능한 값은 다음과 같습니다.

  • '게시'-게시 된 게시물 또는 페이지
  • '보류 중'-게시물 검토 대기 중
  • '임시'-임시 상태의 게시물
  • '자동 초안'-컨텐츠가없는 새로 작성된 게시물
  • '미래'-미래에 게시 할 게시물
  • '비공개'-로그인하지 않은 사용자에게는 보이지 않습니다
  • '상속'-개정판. get_children을 참조하십시오.
  • 'trash'-게시물이 휴지통에 있습니다. 버전 2.9로 추가되었습니다.

나는 이것이 요청 된 것을하지 않는다고 생각합니다. 새 게시물을 작성한 다음 'Publish' save_post()를 누르면 처음으로 실행되지만 get_post_status()게시 중에는 게시 중일 때에도 '초안'이 아니라 '출시'가 이미 실행 됩니다.
cgogolin
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.