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   2893 Views

Avatar
MrElf

Community Member, 9 Posts

4 August 2008 at 4:45pm

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

Forum Moderator, 922 Posts

4 August 2008 at 5:33pm

Edited: 04/08/2008 5:39pm

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

Community Member, 9 Posts

4 August 2008 at 8:35pm

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

Community Member, 9 Posts

5 August 2008 at 1:30pm

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

Forum Moderator, 922 Posts

5 August 2008 at 4:08pm

Edited: 05/08/2008 4:12pm

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

Forum Moderator, 5513 Posts

5 August 2008 at 9:41pm

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

Forum Moderator, 922 Posts

6 August 2008 at 7:15pm

Good point Will, forgot you could do that too!