I am trying to trigger an extra function as soon as a certain custom post type is published

function insert_table_products($post_id, $post) {
    if ($post->post_type == 'custom-products') {
        global $wpdb;
        $custom_meta = get_post_meta($post_id);
        $attachments = new Attachments('my_attachments');
        if ($attachments->exist()) :
            $my_index = 0;
            $use_image = new SplFileInfo($attachments->url($my_index));
            $use_main_image = $use_image->getFilename();

                'products', array(
            'product_code' => $custom_meta['product_code'][0],
            'product_name' => $post->post_title,
            'product_img_name' => $use_main_image,
            'price' => $custom_meta['product_price'][0], //$POST['acf-field-price_patch'],
            'product_inventory' => $custom_meta['product_stock'][0], //$POST['fields[field_54df75e760b5e]'],
add_filter('publish_post', 'insert_table_products', 10, 2);
//add_action( 'publish_post', 'insert_table_products', 10, 2);

Neither of the hooks work. I expected the print_r to show some data

BTW, I have also a update function, triggered by

//add_filter('edit_post', 'update_table_products', 10, 2);

which also doesn't seem to work correctly.

Any ideas?

  • 1
    You should consider using the hook mentioned by @PieterGoosen and additionally you might want to add a if( class_exists( 'Attachments' ) ) check into your code so it won't break if the corresponding external plugin is removed.
    – birgire
    Commented Feb 15, 2015 at 16:17
  • @birgire great spot :-) Commented Feb 15, 2015 at 16:19
  • ps: it's rather surprising at first to see that the add_action function definition is actually only a single line of code, namely a call to the add_filter() function ;-)
    – birgire
    Commented Feb 15, 2015 at 16:34
  • @birgire wow never looked into the add_action function, that indeed is suprising. Thanks for the class_exists suggestion!
    – alex
    Commented Feb 15, 2015 at 17:00

1 Answer 1


publish_post doesn't work for custom post types, the correct hook (action hook) is publish_{$custom_post_type}. You should use add_action() as this is an action hook.

I also tend to make use of the transition_post_status hook which is a much more universal hook as it fires everytime a post's status is changed regardless. You can use $old_status and $new_status to check the previous and new status of a post then do something.

For a new post, you can something like this: (Requires PHP 5.3+)

add_action( 'transition_post_status', function ( $new_status, $old_status, $post )

    if( 'publish' == $new_status && 'publish' != $old_status && $post->post_type == 'my_post_type' ) {


}, 10, 3 );


For post edits/updates, using transition_post_status, you can do

add_action( 'transition_post_status', function ( $new_status, $old_status, $post )

    if( 'publish' == $new_status && 'publish' == $old_status && $post->post_type == 'my_post_type' ) {


}, 10, 3 );

For further reading regarding post status transition, you can check out the codex


Custom fields, built in and from the advanced custom fields plugin uses the save_post hook, which runs after post transition, so trying to add custom fields won't work on here

For custom post types, a new hook was introduced called save_post_{$post_type} to make things easier. This hook is also recommended by the ACF forum to update custom fields.

  • Going to try both your suggestion tx a lot
    – alex
    Commented Feb 15, 2015 at 16:14
  • hi pieter, i am trying your first suggestion and i am getting an WordPress database error: [Duplicate entry 'xxx' for key 'product_code'] each time. So i echoed some variables and i think $custom_meta = get_post_meta($post_id); is empty. Now i have rewritten it by get_post_meta($post->ID); but only on refresh i see data but a duplicat key. your second suggestion is just for new posts(inserts) and doesn't apply for edit/updates, right?
    – alex
    Commented Feb 16, 2015 at 13:26
  • 1
    The second method can be used in many ways, not just for new posts. For edits/updates you can do if( 'publish' == $new_status && 'publish' == $old_status && $post->post_type == 'my_post_type' ) Commented Feb 16, 2015 at 13:51
  • Tx again, i see the triggers are working but $custom_meta = get_post_meta($post->ID); seems to be empty. How can i fix this? Are the custom fields not yet attached?? i am using advanced custom fields (wordpress.org/plugins/advanced-custom-fields)
    – alex
    Commented Feb 17, 2015 at 9:54
  • 1
    See my update. Hope that helps Commented Feb 17, 2015 at 10:50

Your Answer

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

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