Plugin Development: WordPress processes twice on post update. How to skip process on the first?

When you create a plugin and set up a process function, WordPress will run the plugin process function twice upon clicking the update button. I believe the first process is for the versioning (revision) post, and the second the actual post.

Now, I’ve got an INSERT function in my process, so it is now inserting the data twice.

What is the best way to ensure that processing doesn’t happen while creating the revision and and only on the actual post processing?

* Note: Targeting WordPress 3.0+ *

An Example (complete plugin):

<?php
/*
Plugin Name: Something Amazing
Plugin URI: http://www.somewhere.com/
Description: Displays something.
Author: Some guy
Version: 1.0
Author URI: http://www.somewhere.com/
*/
function call_something() {
 return new something();
}
if (is_admin()) add_action('load-post.php','call_something');

class something {

 public function __construct() {
  add_action('add_meta_boxes',array(&$this,'something_add_boxes'));
  add_action('save_post',array(&$this,'something_process'),1,1);
 }

 public function something_add_boxes() {
  add_meta_box('something','Some Thing',array(&$this,'something_form'),'post','side','default');
 }

 public function something_form($post,$args) {
  echo '<p><input type="text" name="somethingnew" /></p>';
 }

 public function something_process($id) {
  echo 'hey there! I\'m going to cause a redirect warning, but you will see this line twice per submit!';
  //do_something_amazing();
 }
}
?>

Perhaps there is a better hook to use to process that doesn’t make it write twice?

5 Answers
5

@Steve Functions hook to save_post are always called twice, WordPress call functions hooked to save_post twice because:

  • first time it saves the post revision.
  • second time it saves the actual post.

NOTE: If you have disabled post revisions using define('WP_POST_REVISIONS', false); then the save_post hook will be fired only once when the actual post will be saved.

I just tested the following code and it works as expected and the echo only runs once in the something_process function.

NOTE: the way I have hooked to save_post

<?php
/*
Plugin Name: Something Amazing
Plugin URI: http://www.somewhere.com/
Description: Displays something.
Author: Some guy
Version: 1.0
Author URI: http://www.somewhere.com/
*/
function call_something() {
 return new something();
}
if (is_admin()) add_action('load-post.php','call_something');

class something {

 public function __construct() {
  add_action('add_meta_boxes',array(&$this,'something_add_boxes'));
  add_action('save_post',array(&$this,'something_process'),1,2);
 }

 public function something_add_boxes() {
  add_meta_box('something','Some Thing',array(&$this,'something_form'),'post','side','default');
 }

 public function something_form($post,$args) {
  echo '<p><input type="text" name="somethingnew" /></p>';
 }

 public function something_process($id, $post_object) {
    // don't run the echo if this is an auto save
    if ( defined('DOING_AUTOSAVE') && DOING_AUTOSAVE )
        return;

    // don't run the echo if the function is called for saving revision.
    if ( $post_object->post_type == 'revision' )
        return;

  echo 'hey there! I\'m going to cause a redirect warning, but you will see this line twice per submit!';
  //do_something_amazing();
 }
}
?>

Leave a Comment