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.

Archive

Our old forums are still available as a read-only archive.

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

Displaying the next event


Reply

7 Posts   2798 Views

Avatar
MrElf

4 August 2008 at 4:45pm Community Member, 9 Posts

Hi. I'm a relative noob to php/ss development and am having issues getting my head arounf collection itteration.

I have a site with a series of events (EventPage) under a holding page (EventHolder), from which I want to display the following:

On my home page I want to display the next 'n' events that occur in the immediate future relative to the current date/time

On the events page I want to display all events for a particular date range.

While I can see in the demo how to display the events via the DataObject::get() function, I can not find any info on the collection iteration. Can anybody please help.

Thanks muchly.

Avatar
Sean

4 August 2008 at 5:33pm (Last edited: 4 August 2008 5:39pm), Forum Moderator, 921 Posts

In the HomePage.php file (or whatever page type you're wanting to iterate over data on):

class HomePage extends Page {

   function UpcomingEvents($limit = 5) {
      return DataObject::get('EventPage', '', 'Date DESC', '', $limit);
   }

}

class HomePage_Controller extends Page_Controller {

}

In the HomePage.ss template (or respective template for your page type inside templates for your current theme):

You use <% control MyFunctionReturningADataObjectSet %> to iterate over data. DataObject::get() returns a DataObjectSet, so we can iterate over the DataObject's in the set by using <% control UpcomingEvents(5) %> in this case. You'll also note that we used (5), this means you can effectively apply a limit on the records returned from the template, which defaults to 5 if you just use <% control UpcomingEvents %> without the argument.

<% if UpcomingEvents %>
   <ul class="eventList">
   <% control UpcomingEvents(5) %>
      <li>
         <h3>$Title</h3>
         <p>$Content.FirstParagraph ...<a href="$Link">read more</a></p>
      </li>
   <% end_control %>
   </ul>
<% end_if %>

The second and third arguments to DataObject::get() are for filter, and sort respectively. And, the 5th argument is how many items you want to return, so you can effectively establish a limit of how many records to return. This means you can sort by a date, for example:

DataObject::get('EventPage', '', 'EventPage.Date DESC', '', 5);

Pagination can also be applied, if you limit a set.

Here's some useful references in the SS documentation wiki:

http://doc.silverstripe.com/doku.php?id=private:recipes:pagination
http://doc.silverstripe.com/doku.php?id=dataobjectset
http://doc.silverstripe.com/doku.php?id=templates

Hope this explains what you're after!

Sean

Avatar
MrElf

4 August 2008 at 8:35pm Community Member, 9 Posts

Ok I have this worked out so far. What I need to know now is how do I get the nextItem bit.

Is my logic ok?

function NextEvent() {
   $eventHolder = DataObject::get_one("EventHolder");
   $mydataset = DataObject::get("EventPage", "ParentID = $eventHolder->ID", "Date ASC", "", "");

   $count = 1;
   while($count <= $mydataset->Count())
   {
      $dataobj = $mydataset->nextItem;
      if( $dataobj->Date >= getdate());
         break;
      $count = $count + 1;
   };

   return( $dataobj );

   }

Avatar
MrElf

5 August 2008 at 1:30pm Community Member, 9 Posts

Sorted! Thanks to Sean for his help, I came up with something that works.

function NextEvent() {
   $eventHolder = DataObject::get_one("EventHolder");
   $events = DataObject::get("EventPage", "ParentID = $eventHolder->ID", "Date ASC", "", "");

   foreach( $events as $event ) {
      if( $event->Date >= date('Y-m-d') ) {
         break;
         }
      }
   return( $event);
   }
}

Any comments on a better way to do this, ie more efficent would be appreciated.

Avatar
Sean

5 August 2008 at 4:08pm (Last edited: 5 August 2008 4:12pm), Forum Moderator, 921 Posts

function NextEvent() {
$eventHolder = DataObject::get_one("EventHolder");
$events = DataObject::get("EventPage", "ParentID = $eventHolder->ID", "Date ASC", "", "");

foreach( $events as $event ) {
if( $event->Date >= date('Y-m-d') ) {
break;
}
}
return( $event);
}
}

You could do something like this - AFAIK it should work by adding the date check in the WHERE clause instead of looping through the event records after fetching them all.

function NextEvent() {
   $today = date('Y-m-d');
   $eventHolder = DataObject::get_one('EventHolder');
   return DataObject::get_one('EventPage', "ParentID = $eventHolder->ID AND `EventPage`.Date >= '{$today}'", true, "Date ASC");
}

Avatar
Willr

5 August 2008 at 9:41pm Forum Moderator, 5511 Posts

you can use MySQLs NOW() command aswell I would assume

function NextEvent() { ;
$eventHolder = DataObject::get_one('EventHolder');
return DataObject::get_one('EventPage', "ParentID = $eventHolder->ID AND `EventPage`.Date >= NOW()'", true, "Date ASC");
}

Avatar
Sean

6 August 2008 at 7:15pm Forum Moderator, 921 Posts

Good point Will, forgot you could do that too!