Sorry if this is already answered on here. I looked around and couldn't see any answers to my question so I thought I'd post my own.

I'm building a plugin for a client that gathers customer feedback on a recent project that has been completed.

The admin would use the system to send a "prompt" to the customer asking them for their feedback with a link to a form on the site.

I have created a custom post type called "customer_prompts" which only has a title field and a few custom fields which are stored in a custom database table, not post meta.

Below is my code for the save_post action. It seems that when I hit publish, it does not fire the save_post action and only saves the title value to wp_posts.

add_action('save_post', 'save_prompt');
function save_prompt($post_id){
$post = get_post($post_id);

    if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) 

    if ( 'customer_prompt' == $_POST['post_type'] ) 
        if ( !current_user_can( 'edit_page', $post_id ) )
        if ( !current_user_can( 'edit_post', $post_id ) )

    global $wpdb;

    $prompt_id = com_create_guid();
    $customer_feedback_name = $_POST['_sdg_customer_feedback_name'];
    $customer_feedback_email = $_POST['_sdg_customer_feedback_email'];
    $salesperson = $_POST['_sdg_salesperson'];

    $values = array(
        'id' => $prompt_id, 
        'sdg_customer_name' => $customer_feedback_name,
        'sdg_customer_email' => $customer_feedback_email,
        'sdg_salesperson' => $salesperson,
        'sdg_post_id' => $post->id

    $insert = $wpdb->insert($table_name, $values);

    if($insert) {
        mail($customer_feedback_email, 'hello', 'hello');


Any help would be greatly appreciated as I cannot work out what is going on here.

Thanks, Jamie.

  • Does it work if you remove the tests for the post type and capabilities? There could be a logic error.
    – fuxia
    Dec 10, 2012 at 16:35
  • I tried commenting them out, still no luck. Dec 10, 2012 at 16:43
  • try using first example from codex[1] [1]: codex.wordpress.org/Plugin_API/Action_Reference/save_post)
    – M-R
    Dec 10, 2012 at 16:55
  • Tried that but still doesn't work. It seems that the save_post action is running when you create a new post from the sidebar, but doesn't run when you hit publish. I've tried a few different action hooks such as publish_post and edit_post but neither of those work. Dec 11, 2012 at 9:06
  • A simple print of $_POST global variable and die(); method at the beginning of the function should tell you what is in the $_POST array to ensure wordpress picked it correctly, also ensure the meta id is correctly placed in "name" value of the input field, if this is correct. Then you should find out the error quickly. Dec 4, 2020 at 10:21

6 Answers 6


The "save_post" action is only called when we actually changed something in the post page form. If we just press the update button, without changing anything, the "save_post" action is not called.

This is important if we are editing a custom post type where we had custom meta boxes. If we rely on the "save_post" action and only change stuff on our custom meta boxes, nothing will happen.

The solution is to use the "pre_post_update" action hook, instead of "save_post"


  • This doesn't work if you're clicking "Preview Changes".
    – Sam Rueby
    Jan 18, 2018 at 21:58

edit Have you tried placing print_r('hello world'); die(); after function save_prompt($post_id){ to make sure the function actually does get picked up by the action hook? /edit

Several Issue could be in play:

1: Your global wpdb needs to be at the very top of your function, before all your if conditional statements.

2: Your $_POST variables should have conditionals of if(isset($_POST['food')) to check if the data being posted is actually being set before reaching your function, otherwise is may be causing a fatal error, causing the data not to be entered to the DB.

3: Try global $post at the top of the function, then you can call the post's variables such as $post->post_type as an object through the $post variable.

4: Add $wpdb->print_errors; die(); after $insert = $wpdb->insert($table_name, $values); incase your DB query is incorrect.

Hopefully one of those should fix your problem.

  • Taking a global variable into the function scope must happen before it is used, but not necessary at the top of a function.
    – fuxia
    Dec 11, 2012 at 9:53
  • For best practices though, came across several instances where globals have failed for not being at the top of a function. Dec 11, 2012 at 10:04
  • I did try echoing something at the very top of the function which did appear at the very top of the page after clicking "Add new" on the sidebar but once you click publish this disappears as though the function is not being fired when publish is clicked. I tried all your other suggestions and still no luck. I think it may be a case of the function not being fired at all but can't work out why. Dec 11, 2012 at 12:00

First off, I would suggest setting up your WordPress site to be easy to debug http://codex.wordpress.org/Debugging_in_WordPress

That way, it's easy to see stuff ;)

For action hook, I believe you need to hook it like this:

add_action('save_post', 'save_prompt', 10, 2);
function save_prompt( $post_id, $post ){
//do whatever

the save_post hook passes 2 arguments.


This happened to me. Turned out I had a page-template set (a post-meta value for _wp_page_template) to a template that no longer existed, after having switched themes. This bit of code in wp-includes/post.php:

if ( ! empty( $postarr['page_template'] ) ) {
    $post->page_template = $postarr['page_template'];
    $page_templates = wp_get_theme()->get_page_templates( $post );
    if ( 'default' != $postarr['page_template'] && ! isset( $page_templates[ $postarr['page_template'] ] ) ) {
        if ( $wp_error ) {
            return new WP_Error( 'invalid_page_template', __( 'Invalid page template.' ) );

aborts before firing save_post.


i think the var_dump in add_action('save_post', callback function is not showing!


$fp = fopen('c:\data.txt', 'w');
fwrite($fp, print_r($post_id, true));

and check if 'data.txt' exists, yes it is true by save_post.



I had this exact problem as well and thought I'd add to the potential answers, to help save someone some time. It was a very simple problem that took me days to identify (I'm' a little balder at the moment - and feel a bit silly)...

It turns out that a metabox form that was being generated contained a "action" field that was overwriting the "action" field of the WordPress generated form - the form was only being used on a custom post and thus the the wrong action was being passed to WordPress on POST to 'wp-admin/post.php' and it ended up being handled by the default handler (at the end of the switch statement).

Another side-effect was that on update or publish, WordPress redirected to the built-in post index, instead of right back to the edited post.

The solution was to remove the 'action' hidden form element for the metabox.

I hope this helps somebody out there...

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.