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.

We've moved the forum!

Please use forum.silverstripe.org for any new questions (announcement).
The forum archive will stick around, but will be read only.

You can also use our Slack channel or StackOverflow to ask for help.
Check out our community overview for more options to contribute.

Archive /

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

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

Displaying the next event


Go to End


7 Posts   3944 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, 5523 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!