0

I have a problem with hooks being fired multiple times when I press update on a post (page in this example)

I tried everything here: Unable to prevent function using save_post firing twice

But since it looked like I was receiving multiple requests I started to examine the access log.

When I hit update these are the posts sent:

[ip_number] - - [26/Aug/2021:15:31:00 +0000] "POST /wp-json/wp/v2/pages/1373?_locale=user HTTP/2.0" 200 3805 "https://example.com/wp-admin/post.php?post=1373&action=edit" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36"
[ip_number] - - [26/Aug/2021:15:31:00 +0000] "POST /wp-admin/post.php?post=1373&action=edit&meta-box-loader=1&meta-box-loader-nonce=[nonce]&_locale=user HTTP/2.0" 302 0 "https://example.com/wp-admin/post.php?post=1373&action=edit" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36"

So I started to do some logging:

add_action("publish_page", "my_publish_page", 10, 2);
function my_publish_page($postId, $post) {
    error_log("Debug for my_publish_page");
    error_log("postId: " . $postId);
    error_log("GET: ". var_export($_GET, true));
}

And the log file showed:

[26-Aug-2021 15:41:59 UTC] Debug for my_publish_page
[26-Aug-2021 15:41:59 UTC] postId: 1373
[26-Aug-2021 15:41:59 UTC] GET: array (
  '_locale' => 'user',
)
[26-Aug-2021 15:41:59 UTC] Debug for my_publish_page
[26-Aug-2021 15:41:59 UTC] postId: 1373
[26-Aug-2021 15:41:59 UTC] GET: array (
  'post' => '1373',
  'action' => 'edit',
  'meta-box-loader' => '1',
  'meta-box-loader-nonce' => '[nonce]',
  '_locale' => 'user',
)

So, two requests are sent, both trigger the publish_page action hook (and save_post or whatever similar hook you prefer). Both have the publish status for the post and none of them is true for wp_is_post_autosave (or DOING_AUTOSAVE).

I could for example look at the $_GET variable and only trigger my code if, for example $_GET['post'] == $postId, but that seems a bit hacky. Why is this happening, and is there a clean solution to prevent this "double-firing"?

0

I found a solution:

function myAction() {
    if(defined("REST_REQUEST") && REST_REQUEST) {
        return;
    }

    // Do action stuff
}

The request to /wp-json/wp/v2/pages/1373 is a request to the API which defines the constant REST_REQUEST and sets it to true.

If anyone's got an idea why an extra API request is sent, please feel free to add you answer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.