0

Have few pages in wordpress cms. Whenever any page is published or updated, there is need to do some action (basically call an API to update some data in another backend service).

  • For publish, I am able to identify the point and able to trigger action one time
  • For update, I am not able to identify the point and hence, even if I update the page once, the action is getting trigerred more than once.

Is there a way to know if an already published post was updated and call some function only one time?

Here are the details:

To get the trigger point for actions, I am using transition_post_status action. I am adding a callback which gives me old status, new status and post.

Here is how code looks:

This code is added in functions.php

add_action('transition_post_status', 'update_data_be', 10, 3);

function update_data_be($new_status, $old_status, $post) {
    if ($old_status === 'auto-draft' && $new_status === 'publish' && $post->post_type === 'page') {
        // Ref 1
        call_api(); // Each time a page is published - this runs only one time
    } else if ($new_status === 'publish' && $post->post_type === 'page') {
        // Ref 2
        call_api(); // Each time already published page is updated - this runs twice. 
                    // Need to avoid this from running multiple times
    }
}

function call_api() {
    // Some code to do an API call
}

For publish, since old_status and new_status are different; it is exactly known when post is transitioned from auto-draft to publish and hence call_api is called one time during publish. But the same is not know for update.

Even, I read at multiple places, that hooks can be trigerred multiple times for single update and hence stuck at this point.

Let me know if any additional information is needed.

Update 1: A sample scenario here for more clarity

For each publish and update, I have to call another service and submit wordpress page data.

Suppose I want to create a page P. I will open my wordpress, write in my contents and click on publish button. At this point, update_data_be function is fired many times (since hooks can be fired multiple times) but call_api at Ref 1 in above snippet is executed once due to status checks of old and new. In my backend logs, I see one API call happening. - This is working fine as expected.

Again, I want to update the page. I will open my wordpress, update contents and click on update button. At this point, update_data_be function is fired many times. Also, call_api at Ref 2 is executed twice as old and new status both are published. In my backend logs, I see two API calls happening. I am not able to prevent two API calls from happening. - This is not working as expected as I need to call the API only once.

Hope above scenario clarifies the issue.

Update 2:

Have found a possible solution at https://wordpress.org/support/topic/publish_post-hook-trigger-twice-when-i-publish-post/ but this seems to be editor specific and might fail so not sure to use it.

1 Answer 1

0

You can do something like this.

add_action('publish_page', 'bt_publish_post', 10, 2);
function bt_publish_post ($post_id, $post) {
    // our bt_page_status codes will indicate one of three thing
    // if empty than we know that page is published
    // if 1 we know that page was updated for the first time
    // if 2 we know that page was updated for the second and so on time (2,3,4 stc... times)
    $bt_page_status = get_post_meta($post_id, 'bt_page_status', true);

    if (empty($bt_page_status)) {
        // page is published
        // do some code here

        // now we set bt_page_status to 1 so next time we know that page is being updated for the first time
        update_post_meta($post_id, 'bt_page_status', 1);
    } elseif ($bt_page_status == 1) {
        // page is updated for the first time
        // do some code here

        // now we set bt_page_status to 2 so next time we know that page is being updated for the second and so on time
        update_post_meta($post_id, 'bt_page_status', 2);
    } elseif ($bt_page_status == 2) {
        // page is updated for the second and so on time
        // do some code here

        // if you need more checks you can continue adding them accordingly
    }
}

This will trigger when page is being created or updated while in the publish status.

If you need to run code on other statuses with other conditions let me know =]

5
  • I think this might not work for my case. I don't have to do different actions on different updates. I have to call same API on each update and the API call should happen only once for one update. publish_page hook can be fired more than once for single update. And hence, here also if bt_publish_post is trigerred twice, due to hook getting fired twice, same issue will happen. I have updated my question with an example scenario. Please have a look at it. Jul 22, 2021 at 13:34
  • Have you tried my code? Try using php error_log to see how it works and when each if block is triggered Jul 22, 2021 at 13:36
  • Yes, I tried your code. It is not working. I put error_log in each if block. Each time I update a page, I see function running twice and code in 2 blocks getting triggered. I extended your code to create 6 if-elseif blocks. For publish, first 2 blocks are logged. For next subsequent page updates, 2 next consecutive blocks are triggered for one update. Jul 22, 2021 at 14:10
  • 1
    Could you pust this code so I could run some tests with it? Jul 22, 2021 at 14:10
  • Sure. Since it's an internal company project, I will try to extract out the non-working piece and push it in separate repository to share it with you. Jul 23, 2021 at 6:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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