There are several posts and plugins that come close, but just not quite there. I'm migrating 200+ blog posts to a new site. All of the posts have at least one image in them. The new site is utilizing the "Featured Image" and the old site wasn't.

So I need a way to automagically go through all of the posts, remove the first image found from the post, and set it as the featured image.

Most of the solutions I've found take the first image and make it the featured image on the fly, but I need to remove it from the post entirely and set it as the featured image permanently.

  • 1
    Are you comfortable writing code for this? It's not too likely there is the perfect plugin match for what you want and asking for plugin recommendations is not considered in scope here. – Rarst Sep 19 '17 at 14:38
  • Thanks, yeah, I suppose I'll have to figure out how to roll my own solution. – Von Sep 19 '17 at 14:42

To get you started:

Breaking your goal into smaller tasks will help a lot in figuring out how to do this. You probably want to:

  1. Do a custom query that finds all published posts
  2. Use a foreach loop for your query results
  3. Within the loop, find the first image
  4. Set that first image as the featured image (save it as postmeta)
  5. Remove the image from that post's content

You should be able to work out #1 and #2 on your own. For #3, here is code you would place within the foreach loop that will identify the first <img> tag - but you'll want to make sure that you only have images from this site within your posts, because it will grab any <img> within the post, so if you have embedded images from other sites you'll have to make the regex more complex to find the first image from your own domain. This code assumes you have saved your query results to a variable called $item:

// get the full content of the post
$content = $item->get_content();
// find the first <img> tag and save to variable $imageUrl
preg_match('/< *img[^>]*src *= *["\']?([^"\']*)/i', $content, $imageUrl);
// [1] is just the image URL. [0] is most but not all of the <img> tag.
$imageUrl = $imageUrl[1];

Now that you have the URL of the image, you'll need to reverse engineer the attachment ID so that you can then assign that attachment ID as the featured image for your post. Pippin has an excellent little function to do this part:

function pippin_get_image_id($image_url) {
    global $wpdb;
    $attachment = $wpdb->get_col($wpdb->prepare("SELECT ID FROM $wpdb->posts WHERE guid='%s';", $image_url )); 
        return $attachment[0]; 

Place this function above or below your loop, not inside of it, and then back within your loop right after you set $imageUrl:

$imageId = pippin_get_image_id($imageUrl);

Here's an example of setting the featured image programmatically.

Hope this points you down the right path. Play around with it a bit and if you get stuck on a specific part you can come back and post a more specific question about that part.

Your Answer

