Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

I have an interesting problem which I am sure someone here can solve. I have gone through a bunch of different plugins and code snippets in search for the perfect code to extract a primary image to be associated with a post.

If the new WP 3.0 featured image element is used then there is of course no issue but there are a bunch of situations where a post may not have a "featured image" assigned. In these situations if you were to use the standard code of:

<?php echo the_post_thumbnail( array(200,200) ); ?>

in your template... nothing is going to be displayed.

For these type of situations I am looking for the perfect solution. Essentially, what I need is the ability to have a type of "failover" when the_post_thumbnail does not exist but I also still need the ability to set the image size just like I can with the code from the_post_thumbnail.

This "failover" I believe should have two steps to it:

  1. Check the "Media Gallery" for this post and locate the image with the highest sort order (or added post parent as shown in the plugin below)
  2. If no sort order is set or if blank then extract the first image from the post content.

The good news is that for the two points above I seem to have found two separate snips of code which take care of these requests individually (copied below for review) however nothing which combines all three of these elements in one.

So, to recap: Instead of doing a bunch of if/then calls to check if a post thumbnail exists and then running a check against the code below I was hoping that someone might be able to provide a clean/combined function which would allow me to echo a single function along with size variables which can achieve all three these goals as mentioned above.

HERE ARE THE BITS OF CODE MENTIONED ABOVE:


FOR #1: Get the First Image based off the order from the Media Gallery: This code works by first looking for any attachments in the wp_posts database table that have a “post_parent” ID that matches the current post and as a second step for posts with multiple image attachments, returning the attachment with its “menu_order” field set to “1″. If no image attachments match the current post ID, the plugin returns “false”.

// AUTOMATICALLY EXTRACT IMAGES BASED ON ASSOCIATED GALLERY ORDER
// THIS CODE EXTRACTS THE FIRST IMAGE BASED ON THE ORDER IN THE MEDIA GALLERY
// PLUGIN FROM: http://mekosh.org/projects/ordered-thumbnails
   function ordered_thumbnails( $display = 'true', $class='' ) {
    global $post;
    // get all image attachments for this post
    $images = get_children( array( 'post_type' => 'attachment', 'post_parent' => $post->ID, 'post_mime_type' => 'image', order=>"asc" ) );
    // if the post has image attachments
    if( $images !== false ) {
        // find the image in position 1
        foreach($images as $i) {
            if ( $i->menu_order == 1 ) {
                $img_id = $i->ID;
            }
        }
        // if the images were unordered
        if ( $img_id == '' ) {
            $i = array_slice( $images, 0, 1 );
            $img_id = $i[0]->ID;
        }
        // get image data
        $image = wp_get_attachment_image_src( $img_id, 'thumbnail' );
        $result = array(
            'url'       => $image[0],
            'width' => $image[1],
            'height'    => $image[2]
        );
        // should the image be displayed or should data be returned as an array?
        if ( $display == 'true' ) {
            return _e( '<img src="'.$result['url'].'" width="'.$result['width'].'" height="'.$result['height'].'" class="'.$class.'" />' );
        } else {
            return $result;
        }
    } else {
        // post does not have any image attachments
        return (bool) false;
    }
   }
// create template tag "ordered_thumbnails"
   add_action( 'ordered_thumbnails', 'ordered_thumbnails', 2 );

FOR #2: Extract the first image from the post content

// THIS CODE GETS THE FIRST IMAGE EXTRACTED DIRECTLY FROM THE POST CONTENT

    function bm_extract_string($start, $end, $original) {
    $original = stristr($original, $start);
    $trimmed = stristr($original, $end);
    return substr($original, strlen($start), -strlen($trimmed));
    }
    function getFirstImage() {
    $content = get_the_content();
    $pic_string = bm_extract_string('src="','" ',$content);
    $imagesize = getimagesize($pic_string);
    list($width, $height, $type, $attr) = getimagesize($pic_string);
    $link = get_permalink();
    $title = get_the_title($post->post_title);
    echo '<a href="'.$link.'" style="background:url('.$pic_string.'); display:block; width:'.$width.'px; height:'.$height.'px;" title="'.$title.'"></a>';
    }
share|improve this question
    
@all I found a solution to my problem which I have provided below in case anyone is interested. Thanks to everyone who attempted to provide a solution. –  NetConstructor.com Sep 20 '10 at 6:33
add comment

4 Answers

I suggest to check out Get the Image plugin. Basically it is single function that acts as flexible and configurable wrapper to mine posts for images via different methods (post meta fields, featured images, attached images, images in post body).

share|improve this answer
add comment
up vote 1 down vote accepted

Here is the solution to my problem for anyone who is interested.

Include this in your functions.php file

require_once('custom/extract-post-thumbnail.php');
    $extract_img = new extract_post_image();
    add_filter( 'post_thumbnail_html', array(&$extract_img, 'get_post_image'),1,5 );

Create a new file and name it "extract-post-thumbnail.php", place it into a folder named "custom" and place that within the the same directory that your themes functions.php file is located. Finally, past the code below into this file.

<?php
class extract_post_image {
    public $html;
    public $post_id;
    public $post_image_id;
    public $size;
    public $attr;
    public function extract_post_image()  {
    }
    public function get_post_image ($html,$post_id, $post_image_id, $size, $attr) {
$this->html = $html;
        $this->post_id = $post_id;
        $this->post_image_id = $post_image_id;
        $this->size = $size;
        $this->attr = $attr;
    if ($this->html == '') {
         $this->post_image_id = $this->get_post_image_id ();
         if ($this->post_image_id) {
           do_action( 'begin_fetch_post_thumbnail_html', $this->post_id, $this->post_image_id, $this->size ); 
        $this->html = wp_get_attachment_image( $this->post_image_id, $this->size, false, $this->attr );
        do_action( 'end_fetch_post_thumbnail_html', $this->post_id, $this->post_image_id, $this->size );
    } else {
        $this->html = $this->get_image_in_content ();
    }
    }
    return $this->html;
}
public function get_post_image_id () {
    $images = get_children(
    array(
        'post_parent' => $this->post_id,
        'post_status' => 'inherit',
        'post_type' => 'attachment',
        'post_mime_type' => 'image',
        'order' => 'ASC',
        'orderby' => 'menu_order',
        'numberposts' => 1
        )
    );
    if ($images) {
        foreach ($images as $img) {
        $img_id = $img->ID;
        }
        return $img->ID;
        } else {
           return NULL;
        }
}
public function remote_file_exists($image) {
    if ( @file($image)) {
        return true;
    }
    return false;
}
public function get_image_in_content () {
    $my_post = get_post($this->post_id);
    preg_match_all( '|<img.*?src=[\'"](.*?)[\'"].*?>|i', $my_post->post_content, $matches );
    if ( isset( $matches ) ) {
            $image = $matches[1][0];
    if ( $matches[1][0] && $this->remote_file_exists($image) ) {
            $altpattern = '/alt=([\'"])?(.*?)\\1/';
            preg_match($altpattern, $matches[0][0], $m);
            $alt = $m[2];
            $default_attr = array(
            'src'   => $image,
            'class' => "attachment-$size",
            'alt'   => $alt
        );
            $this->attr = wp_parse_args($this->attr, $default_attr);
        $attr = array_map( 'esc_attr', $this->attr );
        $attributes = '';
        foreach ( $this->attr as $name => $value ) {
            $attributes .= " $name=" . '"' . $value . '"';
        }
           $imgwh = getimagesize($image);
           $imgsize = image_constrain_size_for_editor($imgwh[0], $imgwh[1], $this->size);
           $wh = image_hwstring($imgsize[0], $imgsize[1]);
           $this->html = ' <img '.$attributes.' '.$wh.' />';
                return $this->html;
        }
        } else {
        return NULL;
        }
}
}
?>
share|improve this answer
    
there are few things that don't make sense to me - Why do you need regexes to find the 1st image from the content? get_children should take care of finding any image attachments. You don't need to handle remote images, just add width/height attributes to the thumbnail <img> tag and let the browser handle that. Also what's the reason behind using OOP in this situation? –  onetrickpony Dec 17 '10 at 15:38
add comment

@NetConstructor,

This function will not solve all your issues but I thought it would help. It gets the first image attached to a post and adds the medium sized image to the_content If no sort order is set it will get the image with the "0" sort order. It does not extract anything from the post content and if the image is in the post content it will be displayed 2 times.

I used it for a client who had trouble inserting images in posts. With this function he only has to click the "add media" button, upload the image and click save without having to "insert" it.

function the_image($size = 'medium' , $class = ”){
global $post;

//setup the attachment array
$att_array = array(
'post_parent' => $post->ID,
'post_type' => 'attachment',
'post_mime_type' => 'image',
'order_by' => 'menu_order'
);

//get the post attachments
$attachments = get_children($att_array);

//make sure there are attachments
if (is_array($attachments)){
//loop through them
foreach($attachments as $att){
//find the one we want based on its characteristics
if ( $att->menu_order == 0){
$image_src_array = wp_get_attachment_image_src($att->ID, $size);

//get url – 1 and 2 are the x and y dimensions
$url = $image_src_array[0];
$caption = $att->post_excerpt;
$image_html = '<img src="%s" alt="%s" />';

//combine the data
$html = sprintf($image_html,$url,$caption,$class);

//echo the result
echo $html;
}
}
}
}
share|improve this answer
    
although this is not what I am looking for I appreciate you providing the code. I am however really looking for a specific solution here which I feel many others will find value in –  NetConstructor.com Sep 17 '10 at 18:03
add comment

You can check the helpful code snippets here I found them useful to pull out the first image from post.

share|improve this answer
1  
An answer should be more than just a link to an external site. Please add a solution. –  toscho May 24 '12 at 18:18
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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