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

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.