0

I have tried every solution from similar answers and nothing seems to work on Wordpress 5.0 +

When saving a post I want to set its featured image to the first image in the post content.

function auto_set_featured( $post_id, $post, $update ) {
  $images = get_posts( array(
    'post_parent'    => $post_id,
    'post_type'      => 'attachment',
    'post_mime_type' => 'image',
    'posts_per_page' => 1
  ) );

  set_post_thumbnail( $post_id, $images[0]->ID );
}

add_action( 'save_post', 'auto_set_featured', 10, 3);

In set_post_thumbnail() if I set the image id manually it works but it does not seem to pick up $images[0]->ID I'm not sure why this doesn't work.

Note: I'm testing on posts which have multiple images in the content so $images should be returning an array. I also tried using $post->ID and get_the_ID() in the query and it does not work. I also tried adding the post ID manually for post_parent.

3
  • what do you get? any errors?
    – Vishwa
    Commented Apr 26, 2019 at 8:49
  • do a var_dump($images) before set_post_thumbnail and see what you get. Commented Apr 26, 2019 at 8:50
  • @AlexanderHolsgrove it gives array(0) { } so i'm not sure why it is not returning any images. The query seems correct.
    – CyberJ
    Commented Apr 26, 2019 at 8:52

1 Answer 1

0

Have you already used this image in a different post? The post_parent may already be assigned to a different post ID from the one you are on. The code you have will only return images uploaded to this post first.

I've seen a few regex type solutions to this problem, however I think PHPs DOMDocument may be safer. This is also very experimental but seems to work for me:

function auto_set_featured($post_id, $post, $update ) {
    $doc = new DOMDocument();
    libxml_use_internal_errors(true);
    $doc->loadHTML($post->post_content, LIBXML_NOWARNING);
    libxml_clear_errors();

    $images = $doc->getElementsByTagName('img');

    if($images->length > 0) {
        $first_image = $images->item(0)->getAttribute('src');
        $attachment_id = attachment_url_to_postid($first_image);
        if($attachment_id) {
            set_post_thumbnail($post_id, $attachment_id);
        }
    }
}

Should be simple enough to follow, but it loads the post content, and looks for the first img DOMElement. We then use that image URL with attachment_url_to_postid to get the attachment ID, which you pass to set_post_thumbnail as per your code.

2
  • This does not seem to work
    – CyberJ
    Commented Apr 26, 2019 at 11:55
  • Where does it fail? Can you add var_dump($images) and tell me the output? Commented Apr 26, 2019 at 13:31

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