skip to Main Content

When I need to hook code to the "moment a post is added or updated" in WordPress, the WordPress API provides me with save_post() hook.

Nice and easy to add an action to it, so we can perform our own custom logic whenever a post is updated or created. Simple example:

add_action( 'save_post', 'our_own_logic', 10,3 );
 
function our_own_logic( $post_id, $post, $update ) {
    //custom logic here
}

Now, I am working on a project where a third party (Linnworks), updates the posts thru a PUT REST request.
Whenever "they" update the post thru that PUT request, it seems the save_post() action is simply not fired.

At least, any code hooked to save_post() does not trigger, I tried with a simple error logging inside a save_post() and then made sure third party triggers its PUT action at which point nothing is logged, whereas if any other PHP or manual call to save_post does trigger the code.

Thus my question, since I am not very experienced with REST:
How would we detect/hook into the moment when a REST PUT request updates a post (WooCommerce product in this case but it doesn’t really matter)

By my modest knowledge, save_post is fired at the end of wp_insert_post() which is the core function that’s run whenever a post is inserted or updated (wp_update_post() calls it internally). This includes when the post is updated via the classic editor and the block editor (Gutenberg), as well whenever it’s updated via the REST API.

The only reason it wouldn’t fire is if the post was being updated via SQL directly (via a plugin or otherwise), or when only post meta is updated via a function.

So by my knowledge any REST interaction with the post should trigger the save_post hook!
But, it does not, according my tests.

Can anyone shed some light on this?

2

Answers


  1. Chosen as BEST ANSWER

    The issue here is that the third party (Linnworks in this case) updates ONLY the postmeta of the product (stock quantity in this case)

    save_post in this case is NOT fired because the post is not saved, only the postmeta is.

    Hence we need to hook to update_post_meta() or updated_{$meta_type}_meta

    Then, since the third party updates the meta (wether it does it thru REST or else type of function) the code we hook to the above action will fire.

    Bottom line, the whole issue is that save_post() is only fired if something in the _posts table changes, which is the case when we update the post in the backend with the GUI, even if we just changed a post meta, but it is not the case when a function updates the meta directly, in which case, save_post() is never triggered.

    I actually just should have read my own words in the question better:

    By my modest knowledge, save_post is fired at the end of wp_insert_post() which is the core function that’s run whenever a post is inserted or updated (wp_update_post() calls it internally). This includes when the post is updated via the classic editor and the block editor (Gutenberg), as well whenever it’s updated via the REST API.

    The only reason it wouldn’t fire is if the post was being updated via SQL directly (via a plugin or otherwise), or when only post meta is updated via a function.


  2. Once you get the request, you can make a function and call it or can write procedurally.

    /**
     * @params $request API request
     */
    function proccess_request(WP_REST_Request $request)
    {
        // process request
        ...
        // finally update the post
        wp_update_post($data);
    
    }
    

    Now get the request

    $request = WP_REST_Request('params', ...) // or get it in your way
    
    // than call function
    process_request($request)
    

    Or perform procedurally

    $request->get_body()
    
    // process request
    ...
    // finally update the post
    wp_update_post($data);
    

    find more here https://developer.wordpress.org/reference/classes/wp_rest_request/

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search