0

I am looking to extend the below code to select a random featured image based on a specific category. The below works but uses an overall list of images to pull from vs a list of images based on specific categories. In the below, any image starting wtih "UF-" is selected at random to be used as the featured image.

Can someone help point me in the right direction? Ideally, looking to have several images for each category that are used at random.

function autoset_featured() {
     global $post;
     $already_has_thumb = has_post_thumbnail($post->ID);
     if (!$already_has_thumb)  {
         $attached_image = get_children( "post_parent=$post->ID&post_type=attachment&post_mime_type=image&numberposts=1" );
         if ($attached_image) {
              foreach ($attached_image as $attachment_id => $attachment) {
                   set_post_thumbnail($post->ID, $attachment_id);
              }
         } else {
              set_post_thumbnail($post->ID, get_image());
         }
     }
}

function get_image(){
     $list = array();
     $data = array();

     $media_query = new WP_Query(
                    array(  'post_status' => 'inherit',
                            'post_parent' => 0,
                            'post_type' => 'attachment',
                            'post_mime_type' => 'image/jpeg'
              ));

     foreach ($media_query->posts as $post) {
          $fullpath = wp_get_attachment_url($post->ID);
      $list     = (explode("/", $fullpath));
      $string   = $post->ID.'|'.$list[sizeof($list)-1];

          if (substr($list[sizeof($list)-1],0,3) == 'UF-') {
            array_push($data,(explode("|", $string)));
                $idx      = mt_rand(0, count($data)-1);
        $img_id   = $data[$idx][0];
          }
     }

     return $img_id;
}

add_action('the_post', 'autoset_featured');
add_action('save_post', 'autoset_featured');
add_action('draft_to_publish', 'autoset_featured');
add_action('new_to_publish', 'autoset_featured');
add_action('pending_to_publish', 'autoset_featured');
add_action('future_to_publish', 'autoset_featured');

1 Answer 1

3

First of all when you call the get_image function pass the post categories slugs as param.

Edit your autoset_featured function replacing

...
} else {
   set_post_thumbnail($post->ID, get_image());
}
...

with:

... 
} else {
  $cat_slugs = wp_get_post_terms($post->ID, 'event-categories', array("fields" => "slugs"));
  $image = get_image( $cat_slugs );
  if ( image ) set_post_thumbnail($post->ID, $image);
}
...

Then edit the get_image to something like this:

function get_image( $cats = array() ) {
  $media_query = new WP_Query(
    array(
      'post_status' => 'inherit',
      'post_parent' => 0,
      'post_type' => 'attachment',
      'post_mime_type' => 'image/jpeg',
      // set 'orderby' to 'rand' will randomize results order
      'orderby' => 'rand',

      // READ CAREFULLY:
      // if in the title of all images intended to be used as thumbnail
      // you put something that contain 'UF' you can use the 's' param
      // retrieving less results and so improving performance
      // in that case uncomment next line
      // 's' => 'UF'

    )
  );

  if ( $media_query->have_posts() ) {

    $lastid = false; // just an early setup

    // loop through images
    foreach ($media_query->posts as $post) {

      // get current image url
      $fullpath = wp_get_attachment_url($post->ID);

      // if current image name doesn't start with 'UF-' skip it
      if ( strpos( basename($fullpath), 'UF-' ) !== 0 ) continue;

      // if the original post has no categories assigned, return first image ID
      // images are random ordered, so first one is random one
      if ( empty($cats) ) return $post->ID;    

      // get current image file name (without extension) and remove the 'UF-' part
      $name = pathinfo( basename($fullpath), PATHINFO_FILENAME);
      $nameNoUF = str_replace('UF-', '', $name); 

      // $nameNoUF contain something like 'category-name-01'
      // because 'UF-' at beginning and extension were both removed

      // save the current image ID in a helper variable for future possible use
      $lastid = $post->ID;

      // loop through categories and if $nameNoUF start with a category slug,
      // return the image ID.
      // this way every image named like 'UF-category-name-01.jpg' match
      foreach ( $cats as $cat ) {
        if ( strpos($nameNoUF, $cat) === 0 ) return $post->ID;
      }
    }
    // if we are here no category related image was found, so return the last image ID
    // images are random ordered, so last one is random one
    return $lastid;
  }
  // no images found at all, sorry, return false (no thumbnail will be setted)
  return false;
}

As suggested in inline comments to use the s parameter in query to retrieve the images that has 'UF' in title or content to limit results. Of course this need you add that string to images title or content.

Inline comments should explain how the function works.

Hope it helps.

12
  • This does appear to select only "UF-" labeled images but does not seem to do it based on category. Example: UF-outdoors.jpg where "outdoors" is the slug. I did not mention originally that I use custom post types for the posts which also use a custom taxonomy of "event-categories". Not sure how that plays into all this. Also, I don't see where this can select multiple images for the use on the same category. Seems to just select "UF-" labeled images at random.
    – RonnieT
    Sep 12, 2013 at 14:02
  • @RonnieT code supports only standard category. Do you want support both category and custom tax or only custom tax? The selection by category is done in by if (in_array($noUF,(array)$cats)) return $post->ID; but to work you have also to modify your autoset_featured function as shown in first lines of the answer. The code also support only 1 image per category, if you want support more images per category, how would you name it, 'UF-outdoors-1.jpg', 'UF-outdoors-2.jpg' and so on? Also, yes, there is a bug that can return non 'UF-' named images. Answer my question and I'll edit answer.
    – gmazzap
    Sep 12, 2013 at 14:14
  • My setup only requires the use for custom tax, in my case "event-categories". I need to support multiple images per category. Yes, naming such as "UF-outdoors-1.jpg, -2, -3 etc. is ideal.
    – RonnieT
    Sep 12, 2013 at 14:32
  • This is magic and works! The only issue is with the 's' => 'UF'`. When this is uncommented, no image is selected as a featured image. Any thoughts as to why this might be failing?
    – RonnieT
    Sep 12, 2013 at 18:00
  • Just to clarify my last comment, the title of these images in the media manager is UF-outdoor-01 and so on
    – RonnieT
    Sep 12, 2013 at 18:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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