WP Query to set post thumbnail for existing old posts

I found this PHP code that will set the first attached image as the post thumbnail. https://wordpress.stackexchange.com/a/23768

Is it possible to loop through old posts that have attachments using WP_Query() to set the post thumbnail for old posts? If the post has more than 1 attachement, I’d like to set the first attachment as the post thumbnail.

Read More

I’d like to do this only once to get everything up to date, then I can incorporate the PHP code from the answer above to modify new posts going forward.

As requested, here is the code from the aforementioned linked answer.

function myprefix_main_image() {
$attachments = get_children( 'post_parent='.$post->ID.'&post_type=attachment&post_mime_type=image&order=desc' );
if( $attachments ) {
    $keys = array_reverse( $attachments );
    set_post_thumbnail( $post->ID, $keys[0]->ID );
}; 

}

Related posts

Leave a Reply

1 comment

  1. The first step is to loop through all the posts:

    $wpse87964query = new WP_Query();
    

    Now, that will get all the posts; but we’re only interested in posts that don’t have a featured image set. WordPress stores the featured image via a post custom meta field: _thumbnail_id; so, we can use that in a meta query, to get only the posts that don’t have a set featured image:

    $wpse87964query_args = array(
        'nopaging' => true,
        meta_query( array(
            array(
                'key' => '_thumbnail_id',
                'compare' => 'NOT EXISTS'
            )
        ) )
    )
    $wpse87964query = new WP_Query( wpse87964query_args );
    

    Now, set up the loop:

    if ( $wpse87964query->have_posts() ) : while ( $wpse87964query->have_posts() ) : $wpse87964query->the_post();
    
    // CODE WILL GO HERE
    
    endwhile; endif;
    wp_reset_postdata();
    

    Now, query for attachments:

    $attachments = get_children( 'post_parent=' . get_the_ID() . '&post_type=attachment&post_mime_type=image&order=desc' );
    if( $attachments ) {
        $keys = array_reverse( $attachments );
        set_post_thumbnail( get_the_ID(), $keys[0]->ID );
    };
    

    Now wrap the whole thing inside a function, so you can call it somewhere, or hook it into something:

    function wpse87964_set_post_thumbnails() {
    
        // Query args
        $wpse87964query_args = array(
            'nopaging' => true,
            meta_query( array(
                array(
                    'key' => '_thumbnail_id',
                    'compare' => 'NOT EXISTS'
                )
            ) )
        )
        // Run query
        $wpse87964query = new WP_Query( wpse87964query_args );
    
        // Open query loop
        if ( $wpse87964query->have_posts() ) : while ( $wpse87964query->have_posts() ) : $wpse87964query->the_post();
    
            // Query post attachments
            $attachments = get_children( 'post_parent=' . get_the_ID() . '&post_type=attachment&post_mime_type=image&order=desc' );
            if( $attachments ) {
                $keys = array_reverse( $attachments );
                set_post_thumbnail( get_the_ID(), $keys[0]->ID );
            };
    
        // Close query loop
        endwhile; endif;
        wp_reset_postdata();
    
    }
    

    You can improve this function, by stepping through the posts in batches, or by defining your own post custom meta to query against, so that you only process each post once, etc.