I have a couple of projects that are requiring polling a large DB of images for random images, but each pool of images usually contains 3-4 duplicate images. I am also seeing cases where using image_get_random() is even pulling up duplicate images when only 4 images are request, which looks wrong.

I thought about modifying the image.module at these lines:

/**
 * Fetch a random N image(s) - optionally from a given term.
 */
function image_get_random($count = 1, $tid = 0) {
  if ($tid != 0) {
    $result = db_query_range(db_rewrite_sql("SELECT n.nid FROM {term_node} tn LEFT JOIN {node} n ON n.nid=tn.nid WHERE n.type='image' AND n.status=1 AND tn.tid=%d ORDER BY RAND()"), $tid, 0, $count);
  }
  else {
    $result = db_query_range(db_rewrite_sql("SELECT n.nid FROM {node} n WHERE n.type='image' AND n.status=1 ORDER BY RAND()"), 0, $count);
  }
  $output = array();
  while ($nid = db_fetch_object($result)) {
    $output[] = node_load(array('nid' => $nid->nid));
  }
  return $output;
}

I think the use of db_distinct_field(); is in order, but i can't seem to figure out how to get it to work with the current entries and output the same data but just unique/distinct data.

CommentFileSizeAuthor
#3 image_distinct_random.patch1.22 KBdrewish
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

drewish’s picture

what do you mean by db_distinct_field()? that's not a drupal function as far as i can tell...

beekerstudios’s picture

yah it is it's part of drupal API. I don't care how it's done, I just want the random images to be unique. If I grab 10 images, I want them to all be different. It looks kind of lame to have duplicate, or even triplets of the same image up. It looks broken, and not by design.

drewish’s picture

Category: support » task
Status: Active » Needs review
FileSize
1.22 KB

humm, i don't really think it's meant to be called directly. it's used as part of db_rewrite_sql(). i think what you really want to do is just add DISTINCT to the SQL query.

beekerstudios’s picture

I did try this but cast it off as being "wrong" because after trying to use it I was still seeing duplicate images be pulled up. I wasn't sure why so I thought maybe the mySQL statement was wrong. Looks like the use of the function was breaking the distinct randomness of the array pull.

I was doing this:

$time_get = time();
$thumbs = 0;
while ($thumbs<50) {
$images = (image_get_random($count = 1, $tid = 0));
print "<div>";
$img = theme('imagecache', 'square100', $images[0]->images['preview']);
print l($img, $images[0]->images['preview'], array('title'=>$images[0]->title,'rel'=>'lightbox[side_'.$time_get.']'), NULL, NULL, FALSE, TRUE);
print "</div><p>".$images[0]->title."</p>";
$thumbs++;
}

When I should have been doing this.

$time_get = time();
$images_arr = (image_get_random($count = 5, $tid = 0));
	foreach ($images_arr as $images){
print "<div>";
$img = theme('imagecache', 'square100', $images->images['preview']);
print l($img, $images->images['preview'], array('title'=>$images->title,'rel'=>'lightbox[side_'.$time_get.']'), NULL, NULL, FALSE, TRUE);
print "</div>";
}

See the results here (on the right hand side):
http://www.engr.sjsu.edu/about/gallery

As well as part of an xml output for a flash app here:
http://www.engr.sjsu.edu/flash_interface.php

FYI this fix should be committed, I don't know why you'd want random "duplicate" images. I could only see this being a problem if you were requesting more images than existed in a gallery. Even then wouldn't the db pull just be truncated.

drewish’s picture

are you saying that the patch i posted and let me know if that fixes the issue for you?

beekerstudios’s picture

Yah I think the patch is good, I didn't actually use it, but I made the same changes in my image.module for the function. I think this change should be made to the module and not just be a patch. Not to sound like a broken record, but I really can't see why you'd want random 'duplicate' images, so I think using DISTINCT in the sql statement is a necessity, not sure why nobody saw this earlier.

drewish’s picture

Status: Needs review » Fixed

beekerstudios, i usually hold off on committing a patch until i can get some confirmation that it actually works. that's why i needed you to confirm it. it's been committed to HEAD, DRUPAL-5 and DRUPAL-5--2.

olythebest’s picture

i tried to add the DISTINCT in the image.module manually because i dont really know how to use patches files but i still get duplicates

function image_get_random($count = 1, $tid = 0) {
  if ($tid != 0) {
    $result = db_query_range(db_rewrite_sql("SELECT DISTINCT n.nid FROM {term_node} tn LEFT JOIN {node} n ON n.nid=tn.nid WHERE n.type='image' AND n.status=1 AND tn.tid=%d ORDER BY RAND()"), $tid, 0, $count);
  }
  else {
    $result = db_query_range(db_rewrite_sql("SELECT DISTINCT n.nid FROM {node} n WHERE n.type='image' AND n.status=1 ORDER BY RAND()"), 0, $count);
  }
  $output = array();
  while ($nid = db_fetch_object($result)) {
    $output[] = node_load(array('nid' => $nid->nid));
  }
  return $output;
}
beekerstudios’s picture

Olythebest: It could be the way you are calling it. Can you explain where/how you are calling it? I was using it in a custom block as described above, and using a while statement wrapped around the function and calling the function at each loop instead of one db call and then doing a for loop on the array output. If you are also trying to grab more images than you have in image gallery it could also return duplicate images (but I think with DISTINCT maybe not).

Drewish: I completely understand, I just don't typically like using the patches since they themselves can be broken and bork my already made modifications to my modules. (obviously backing up the module would be in order). I do think this modification is worthwhile so hopefully it sticks.

olythebest’s picture

hey beekerstudios

I am using a block to call it :

<?php
  $gallery_name='Footer Images';
  $term = taxonomy_get_term_by_name($gallery_name);
  $tid = $term[0]->tid;
  $thumbs = 0;
  while ($thumbs<8) {
  $images = (image_get_random($count = 1, $tid));
  print l(image_display($images[0], 'preview'),'', array(), null, null, FALSE, TRUE);
  $thumbs++;
}
?>

I tried to use your example in http://drupal.org/node/53987 but it was giving me an error that i couldnt fix

beekerstudios’s picture

As I suspected, this is exactly the snippet of PHP I was using. If this modifcation gets committed to the module, that handbook page needs to be edited in a bad way. I already added a comment on the page about how it's not the best method anyways.

So back to the point, your PHP should look like this:

<?php
  $gallery_name='Footer Images';
  $term = taxonomy_get_term_by_name($gallery_name);
  $tid = $term[0]->tid;
  $thumbs = 8;
$images_arr = (image_get_random($count = $thumbs, $tid = 0));
foreach ($images_arr as $images){
  print l(image_display($images, 'preview'),'', array(), null, null, FALSE, TRUE);
}
?>

As you can see doing this only makes one db query, and then loops through the output array of the db query, much more efficient, and it will get you the results you are looking for.

olythebest’s picture

thanks a lot beekerstudios worked like a charm

Anonymous’s picture

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for two weeks with no activity.

underpressure’s picture

3 Random thumbnail images that link to the image nodes.

  $gallery_name='image';
  $term = taxonomy_get_term_by_name($gallery_name);
  $tid = $term[0]->tid;
  $thumbs = 3;
  $images_arr = (image_get_random($count = $thumbs, $tid = 0));
foreach ($images_arr as $images){
  print l(image_display($images, 'thumbnail'),'node/'.$images->nid, array(), null, null, FALSE, TRUE);
}