안녕하세요. 린치핀소프트 한광희입니다.

 

이번 포스트에서 소개하는 save_post 액션 훅은 포스트 작성 후 내용들이 DB에 저장된 후에 활성화 되는 액션 훅입니다. 플러그인이나 테마 개발에 있어서 포스트의 데이터 처리나 추가 작업을 트리거처럼 자동화하기 위해서 사용할 때 유용한 액션 훅입니다.

특히나 사용자가 입력한 데이터들이 DB에 저장된 후에 활성화 되므로 저장된 DB의 내용을 수정 또는 검증하여 재갱신하거나 처리할 수도 있습니다. 이용자가 저장 또는 수정한 포스트(페이지)의 데이터들은 DB에 저장되어 있으므로 post_id를 통해 get_post($post_id), get_postmeta() 등의 함수를 이용하여 저장된 데이터를 조회할 수 있습니다.

 

function my_project_updated_send_email( $post_id ) {

	// If this is just a revision, don't send the email.
	if ( wp_is_post_revision( $post_id ) )
		return;

	$post_title = get_the_title( $post_id );
	$post_url = get_permalink( $post_id );
	$subject = 'A post has been updated';

	$message = "A post has been updated on your website:\n\n";
	$message .= $post_title . ": " . $post_url;

	// Send email to admin.
	wp_mail( 'admin@example.com', $subject, $message );
}
add_action( 'save_post', 'my_project_updated_send_email' );

위의 예제는 워드프레스 코덱스에서 예시하고 있는 save_post 액션 훅의 예제입니다. 위 예제는 포스트가 생성 또는 수정 된 후에 리비전인지 체크 후 이메일로 생성된 포스트의 제목과 URL을 발신하고 있는 예제입니다.

여기서 눈여겨 확인할 점은 리비전인지 체크 후 리비전일때는 return 을 기술하여 다음의 소스코드 행이 실행되지 않도록 하고 있습니다. 이처럼 save_post 액션 훅은 포스트 타입이 포스트,페이지인 개체에서 뿐만 아니라 리비전 에서도 활성화 됩니다.(각 플러그인과 테마의 개발마다 다르겠지만 보통 리비전까지 처리하는 경우는 저도 많이 보지 못했습니다.)

 

 

// this function makes all posts in the default category private

function set_private_categories($post_id) {
	// If this is a revision, get real post ID
	if ( $parent_id = wp_is_post_revision( $post_id ) ) 
		$post_id = $parent_id;

	// Get default category ID from options
	$defaultcat = get_option( 'default_category' );

	// Check if this post is in default category
	if ( in_category( $defaultcat, $post_id ) ) {
		// unhook this function so it doesn't loop infinitely
		remove_action( 'save_post', 'set_private_categories' );

		// update the post, which calls save_post again
		wp_update_post( array( 'ID' => $post_id, 'post_status' => 'private' ) );

		// re-hook this function
		add_action( 'save_post', 'set_private_categories' );
	}
}
add_action( 'save_post', 'set_private_categories' );

 

다음 예시는 save_post 액션 콜백함수에서 wp_update_post() 함수를 호출하여 업데이트할때의 주의 사항입니다.(이 예제도 워드프레스 코덱스에 나와있는 예시입니다)

여기서 소스코드를 살펴보면 wp_update_post() 이전에 remove_action(‘save_post’,’set_private_categories’); 액션 훅을 삭제하고 있습니다. 이는 wp_update_post() 역시도 포스트를 수정하는 함수이므로 이때에도 save_post 액션 훅이 활성화 되어 “무한 루프(infinite loop)”에 빠지게 됩니다. 그러므로 이를 예방하기 위해 remove_action()을 이용하여 훅을 비활성화 해주고 있는 것입니다.

wp_update_post() 처리 이후에는 다시 비활성화 했던 훅을 add_action(‘save_post’)를 추가하여 다시 활성화 해주고 있습니다.

 

 

이 밖에도 save_post 액션 훅 콜백함수로서 2번째 매개변수인 $post를 이용하여 특정 CPT(Custom Post Type) 일 때만 처리를 하게끔 한다거나 등의 처리도 가능합니다.

function save_action($post_id,$post,$update){
  if ( wp_is_post_revision($post_id)) return;
  if( $post->post_type != 'lcp') return;

  if(get_the_title($post_id) == '')
  {
    $serial = get_post_meta($post_id, 'lcp_serial',true);

  if(!empty($serial))
  {
    $lcp_post = array(
      'ID' => $post_id,
      'post_title' => $serial
      );
    remove_action('save_post',array($this,'save_action'));
    wp_update_post($lcp_post);
    add_action('save_post', array($this,'save_action'));
    }
  }
}

위 예시는 $post 매개 변수를 활용하여 CPT를 확인 후 처리해주고 있는 소스의 예시입니다.