Skip to main content

This site requires you to update your browser. Your browsing experience maybe affected by not having the most up to date version.

DataObjectManager Module

Discuss the DataObjectManager module, and the related ImageGallery module.

Moderators: martimiz, UncleCheese, Sean, biapar, Willr, Ingo, swaiba, simon_w

Random image from album

Go to End

14 Posts   2128 Views

Samba Sam

12 February 2010 at 7:18pm Community Member, 85 Posts

On my home page I want to disply a large single testimonial image that randomly changes every time a visitor comes to the site.
Any suggestions on how to set that up. I can get as far as setting up testimonial data objects to create a gallery, I just don't know how to the display-a-singular-image randomly part.

Thanks in advance,


12 February 2010 at 9:07pm (Last edited: 12 February 2010 9:09pm), Community Member, 101 Posts


a quick way (some thing like this)

in your Controller

   function MainShow(){
      $ThumbURL = DataObject::get('YourDataObject', '','Rand()','','1');
      return $ThumbURL;


<% control MainShow %>
<img src="$URL" />

   <% end_control %>


13 February 2010 at 3:18am (Last edited: 13 February 2010 3:19am), 4085 Posts

It's a little cleaner if you just return a single image. That way you don't need a control.

$ThumbURL = DataObject::get_one('YourDataObject', '',true,'Rand()');


Samba Sam

14 February 2010 at 4:48pm Community Member, 85 Posts

Thanks for the quick response, guys! Sam


15 February 2010 at 11:47am Community Member, 243 Posts

Hmmm, depending on the scale of your site, sorting by RAND() is really bad. It's slow and really could cause problems if you have a lot of objects in the DB.

This is some code i use to get one random object:

function getRandomObject() {
if ($do = DataObject::get('YourDataObject')) {
return $do->getRange(rand(0,$do->Count() - 1),1);

This uses php to pick a random object rather than MySQL.


15 February 2010 at 12:35pm 4085 Posts

Looks like a lesser of two evils, here, guys. RAND() is hog on the DB side, no doubt, but getRange() isn't exactly the leanest function in the world, either. It creates a new set, and loops through the records it already has in memory, creating duplicates for the set matching your range.

If performance is really an issue, I think you might have to look outside of the Sapphire framework. For most sites, I think either of these solutions will be fine.

Samba Sam

16 February 2010 at 3:35am (Last edited: 16 February 2010 3:37am), Community Member, 85 Posts

Hi Folks,
So I can't get any of the previously suggested solutions to work.
Solution #1 (PatJnr) , I get no image, no code in template.

Solution #2 (Uncle Cheese) gives me the following error: Uncaught Exception: Object->__call(): the method 'fortemplate' does not exist on 'Testimonial'

Solution #3(Pigeon) I get a random number link (e.g., "#1") displaying with the following extra code inserted in the template:
<ul id="Menu1"><li onclick="location.href = this.getElementsByTagName('a')[0].href"><a href="">#1</a></li></ul>

Here is my code:

class Testimonial extends DataObject
static $db = array (
'Caption' => 'Varchar(50)'

static $has_one = array (
'TestimonialPage' => 'TestimonialPage',
'TestimonialImage' => 'Image'

public function getDOMThumbnail()
return $this->TestimonialImage()->CroppedImage(50,50);

function getCMSFields()
return new FieldSet(
new ImageField('TestimonialImage'),
new TextField('Caption','Caption')

class TestimonialPage extends Page {

   static $has_many = array (
    'Testimonials' => 'Testimonial'

   function getCMSFields() {
      $fields = parent::getCMSFields();
      $manager = new ImageDataObjectManager(
          'Testimonials',// Source name
          'Testimonial',// Source class
          'TestimonialImage',// File name on DataObject
          array('Caption' => 'Caption'),

      $manager->setBrowseButtonText("Upload (JPG only)");
   return $fields;
} /* end SiteTree */

class TestimonialPage_Controller extends Page_Controller {
/* example 2 */
   function RandomTestimonial (){
    $ImageURL = DataObject::get_one('Testimonial', '',true,'Rand()');
    return $ImageURL; }
/* example 3 */
   function getRandomObject() {
      if ($do = DataObject::get('Testimonial')) {
      return $do->getRange(rand(0,$do->Count() - 1),1);

} /* end Controller */

templates/layout/ (example 2)
<div id="Mainbody">$RandomTestimonial</div>

templates/layout/ (example 3)
<div id="Mainbody">$getRandomObject</div>

I wasn't sure if I was to give the object source name or class in the DataObject::get('Testimonial')) part. I tried doing both with no luck.

Anymore help would be greatly appreciated.


16 February 2010 at 4:13am Community Member, 901 Posts

What you get by your function is the DataObject, not the image.
Either change your function to:

function RandomTestimonial (){
   if($dob = DataObject::get_one('Testimonial', '',true,'Rand()'))
      return $dob->TestimonialImage();

   return null;

Or write something like this in your template:

<div id="Mainbody">$RandomTestimonial.TestimonialImage</div>

Go to Top