I am creating a plugin which syncs both standard WP data and custom fields within a custom meta box on post edit pages, to an external resource using SQL queries. However my functions are currently only working when managing single posts and I am trying to add support for existing bulk actions (Move to Trash, Restore From Trash, and Edit). Right now my sync function is hooked into save_post and I have added support for deleting from my external resource using 'wp_trash_post' and reinserting using 'untrashed_post' (although the this only works when clicking Restore from within the Trash, and not when clicking Undo in the admin notice after Trashing). Here is the code which is located in the __construct for my add metabox class:

add_action( 'save_post', array( $this, 'save_post_function' ) ); //which eventually calls myOtherClass::runs_sync_to_external_resource_SQL_query($post_id);
add_action( 'wp_trash_post', 'my_delete_function' );
function my_delete_function( $post_id ){
    myClass::runs_delete_from_resource_SQL_query($post_id);
}
add_action( 'untrashed_post', 'my_undelete_function' );
function my_undelete_function($post_id) {
    myOtherClass::runs_sync_to_external_resource_SQL_query($post_id);
}

I have read this blog post about adding custom bulk actions (which seems to be the go to reference on the topic), but it is not quite what I am looking for as I do not need to modify the bulk actions select drop down and add a custom action, but simply hook into the existing trash and restore bulk actions.

Additionally, I am going to need to hook into the Edit bulk action because some the data being synced to my external resource can be edited from that action (categories, tags, post format and post status).

Lastly, I need to get the Undo button to run my restore function. I suspect that it doesn't work because its tied to bulk actions though.

Any advice? Thanks in advance

EDIT: Here is the revised code from above using status transition hooks:

add_action( 'save_post', array( $this, 'save_post_function' ) ); //which eventually calls pluginname_sync::pluginname_syncpost($post->ID);
add_action( 'transition_post_status', 'cp_sync', 10, 3 );
function cp_sync( $new_status, $old_status, $post ) {
            if ( $old_status == 'publish'  &&  $new_status != 'publish' ) {
                pluginname_sync::pluginname_delete($post->ID);
            }
            if ( $old_status != 'publish'  &&  $new_status == 'publish' ) {
                pluginname_sync::pluginname_syncpost($post->ID);
            }
        }
  • Reading your code, you may be interested in status transitions hooks. – cybmeta Nov 6 '15 at 14:48
  • Hey thanks, this looks promising. I will have to play around with it. Right now in my save_post callback I have this code to determine whether to delete or insert/update: if (get_post_status( $post_id ) != 'publish') { myClass::runs_delete_from_resource_SQL_query($post_id); } else { myOtherClass::runs_sync_to_external_resource_SQL_query($post_id); } because I only need posts with the Published status to sync. But post transitions might work better in the long run. – T Andrew Nov 6 '15 at 15:30
  • Still looking for a solution to this. I was just googling again and came across this post, got excited until I realized it was my own. Using status transition hooks simplified some processes, but the same problems still remain. Need to hook into the ajax based bulk actions and quick edit. – T Andrew Nov 15 '15 at 0:00
  • Without more information, I'm still think that you don't need to hook into bulk actions and quick edit but in post status transitions I mentioned before; maybe wp_insert_post action and some of the delete post actions described here. Please, try to explain deeply what you are trying to do and why you need to do hook into bulk actions and quick edit. For now I think you are trying the wrong way. – cybmeta Nov 15 '15 at 8:45
  • The plugin that I am creating is syncing data from wordpress to an external database. Therefore when a post is trashed, edited, or untrashed, I need to run my sync functions. Since it possible to trash, edit and untrash using the bulk actions, I need to ensure that the sync functions are performed for each of post being trashed, edited or untrashed. It seems that the status transitions hook functions are not firing when using the bulk actions. Revising the original post with the new code. – T Andrew Nov 15 '15 at 22:46
up vote 1 down vote accepted

As you describe, you want to sync data when a post is trashed, edited or untrashed. You are trying with save_post action, but it fires only on post edit screens (according with codex, this action fires on import, post/page edit form, xmlrpc, or post by email), so you think you need to hook also on bulk actions and quick edit but you are wrong. There are not specific saving actions that are triggered when a post is edited through bulk actions or quick edit (the link you posted about adding custom bulck actions is for that, to add custom bulk actions, not for perform tasks on predefined bulk actions).

From my point of view, there is nothing more appropiate for post status transitions than syncing data.

You have tried post status transitions but with wrong logic. For example, you run de delete sync function when a post transits from be published to not published, but this situation doesn't mean a post is deleted: a not published post can be trashed, a draft, a future post, etc.

Let's see some examples:

add_action( 'transition_post_status', 'cp_sync', 10, 3 );
function cp_sync( $new_status, $old_status, $post ) {

    // Check $old_status also if you need specific actions
    // when the post transits from a specific status

    if ( $new_status == 'draft' ) {
        // The post is now draft, no matter what status it had previously
        // sync draft posts here
    }

    if ( $new_status == 'publish' ) {
        // The post is now published, no matter what status it had previously
       // sync published posts here
    }

    if ( $new_status == 'trashed' ) {
        // The post is now in the trash, no matter what status it had previously
        // sync trashed posts here
    }

    // Cotinue checking more post statues if you need (future, private, etc)
    // For a complete list, see https://codex.wordpress.org/Post_Status_Transitions 

}

There is not status transition for deleted post, you must use any of the actions described in the docs for delete_post action; I would use before_delete_post if you need to catch all the post data:

add_action( 'before_delete_post', 'my_func' );
function my_func( $postid ){
    // Post has been deleted
    pluginname_sync::pluginname_delete( $postid );
}

EDIT

Exmpale: Sync only published posts, delete the rest from external database:

add_action( 'transition_post_status', 'cp_sync', 10, 3 );
function cp_sync( $new_status, $old_status, $post ) {

    // This will cover the transition from any status to published,
    // including published to published.
    if ( $new_status == 'publish' ) {
        pluginname_sync::pluginname_syncpost($post->ID);
    } else {
        pluginname_sync::pluginname_delete($post->ID);
    }

}
add_action( 'before_delete_post', 'my_func' );
function my_func( $postid ){
    pluginname_sync::pluginname_delete( $postid );
}
  • Thanks for replying. I will try this out. But just to be clear, I only want data for published posts. If the post has a status other than published it should be removed from the external database. That is why I had old status=published new status != published. Do you think that it makes a difference? – T Andrew Nov 16 '15 at 12:56
  • If you only want published post be on the other database, checking $new_status == 'publish' (not published) should be enough. See edited answer. – cybmeta Nov 16 '15 at 14:04
  • 1
    I have figured out the problem! Your response indicating that it should be working, helped the lightbulb go off, and it turns out the problem had nothing to do with what we have been discussing. Problem was I was only including the php file containing the sync class and add_action( 'transition_post_status' ... ); only on load-post.php and load-post-new.php so it was only working on an individual post basis. I moved the code so that it loads on all admin screens and the bulk actions are working fine. This implementation of TPS looks much simpler though, and I will be sure to use it. Thanks! – T Andrew Nov 16 '15 at 15:06

Your Answer

 
discard

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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