0

When a post is created, I need to auto-generate a PDF version of the post. The problem is that the global $post object is mostly empty except for the post ID. I need to get the newly created post's slug because the name of the PDF file needs to match the slug of the page.

add_action( 'save_post', 'my_save_post' );
function my_save_post($post_id) {
    global $post;

    if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) return;

    $pdf = new PDF();
    $pdf->createPDF( $post );

    // Debug
    print_r( $post );
    die();
}

If I Publish the new post, then go back and update the post, the $post variable contains all the correct data, but if it's a new post the object is empty. I've also tried the edit_post and post_updated hooks, but in every case the slug and most other data doesn't exist in the $post variable.

*Updated hook and result of print_r($post):

add_action( 'save_post', 'my_save_post', 10, 3 );
function my_save_post( $post_id, $post, $update ) {
    if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) return;
    if ( 'auto-draft' === $post->post_status ) return;

    $pdf = new PDF();
    $pdf->createPDF( $post );

    // Debug
    print_r( $post );
    die();
}

And here's the result of the print_r:

WP_Post Object
(
    [ID] => 593
    [post_author] => 1
    [post_date] => 2017-11-20 18:29:36
    [post_date_gmt] => 2017-11-20 18:29:36
    [post_content] => 
    [post_title] => 
    [post_excerpt] => 
    [post_status] => publish
    [comment_status] => closed
    [ping_status] => closed
    [post_password] => 
    [post_name] => 593
    [to_ping] => 
    [pinged] => 
    [post_modified] => 2017-11-20 18:29:36
    [post_modified_gmt] => 2017-11-20 18:29:36
    [post_content_filtered] => 
    [post_parent] => 0
    [guid] => http://localhost:8888/testsite/?post_type=publication&p=593
    [menu_order] => 0
    [post_type] => publication
    [post_mime_type] => 
    [comment_count] => 0
    [filter] => raw
)
1

The first time that save_post fires it is when WordPress is creating an auto draft. See Why does save_post action fire when creating a new post?

To fix, just check to see if the passed $post variable has a post status of auto-draft.

add_action( 'save_post', 'my_save_post', 10, 3 );
function my_save_post( $post_id, $post, $update ) {
    if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) return;
    if( 'auto-draft' === $post->post_status ) return;
    $pdf = new PDF();
    $pdf->createPDF( $post );
}
  • I actually tried that already, but $post still didn’t contain most of the post data. I also tried adding another check after that to make sure $post->post_name was not empty, and it never passed that check when I published the post until I pressed the Update button. – Gavin Nov 20 '17 at 18:23
  • You're checking on the passed $post variable and not the global $post variable? Because in your sample code, you're using the global. – Nathan Johnson Nov 20 '17 at 18:35
  • Yep, I changed that function to include all 3 parameters and added the 10, 3 bit to the add_action. I'll update my question to include the updated function and the result of print_r($post). Thanks for the help. – Gavin Nov 20 '17 at 18:39
  • I can't reproduce this behavior. Have you tested the above code on a fresh install of WordPress with no plugins and a default theme? – Nathan Johnson Nov 20 '17 at 18:52
  • Ya know, I think your instincts are right. I'm using Advanced Custom Fields and when I saved a normal post (not a custom post type) the $post variable contained more data. It still didn't contain the post_name, but this tells me this problem has to do with the custom fields. Thanks for taking the time to help me get to the bottom of this :) – Gavin Nov 20 '17 at 19:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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