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.

All other Modules /

Discuss all other Modules here.

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

Event Calendar - Need help: Output/Template Question


Go to End


4 Posts   1723 Views

Avatar
bummzack

Community Member, 904 Posts

7 October 2009 at 2:26am

Hi there

I'm trying to create a custom Calendar view (template) for a client of mine. Let's illustrate this with a small example.
Imagine the following (simplified) Structure

CalendarPage
+-- Event A
	+-- Date 10/10/2009
	+-- Date 11/15/2009
+-- Event B
	+-- Date 10/08/2009
	+-- Date 11/17/2009

The (summarized) output for this would usually look like this:

Event B (10/08/2009)
	See also: Event B (11/17/2009)
Event A (10/10/2009)
	See also: Event B (11/15/2009)
Event A (11/15/2009)
	See also: Event B (10/10/2009)
Event B (11/17/2009)
	See also: Event B (10/08/2009)

Now, what I'd like to do would be something like this:

Event B (10/08/2009)
	Also on: 11/17/2009
Event A (10/10/2009)
	Also on: 11/15/2009

So basically list every event just once and list all its dates there.

I don't know if this is already doable with a vanilla install of the EventCalendar Module. I already though about overriding the Calendar::Events method, but there's so much code and no documentation, so it's pretty hard to figure out what has to be changed/reimplemented.

Any pointers are greatly appreciated. Thanks

Avatar
UncleCheese

Forum Moderator, 4102 Posts

7 October 2009 at 3:01am

Your best bet may be to sub out the Calendar, Event, and DateTime classes and overload the Events() function, however, provided you're not using recursion or announcements, you can do this very easily by creating a custom template and avoiding the Events() function all together. The reason the Events function is such a black box is because it has to account for announcements, recurring events, and take into account your default view, etc. Without those complications, it's as simple as returning Children.

<% control Children %>
<h2>$Title</h2>
<% control DateTimes.First %>
$_Dates
<% end_control %>
<h3>See Also</h3>
<ul>
<!-- sort of a hack here -->
<% control DateTimes %>
<% if First %><% else %><li>$_Dates</li><% end_if %>
<% end_control %>
</ul>
<% end_control %>

Avatar
UncleCheese

Forum Moderator, 4102 Posts

7 October 2009 at 3:03am

Actually, it's not that easy. You need something more advanced than Children() to make the result set date range aware.

If you can write a function that returns the Children of the calendar filtered by start/end date, I'll definitely check it in to the module.

Avatar
bummzack

Community Member, 904 Posts

7 October 2009 at 10:19pm

Edited: 07/10/2009 10:27pm

Hey UncleCheese

Thanks for the replies. I first had to get my head around how you did things..
I first tried to filter the CalendarEvent children and return these... that didn't work however. Until I noticed, that I have to return a set of CalendarDateTime
Almost started to pull my hair out there :)

So here's my solution to the problem. It's not very elegant and might not work for all cases. Maybe you see some room for improvement:

public function DistinctEvents(){
	$start = new sfDate($this->start_date);
	$sd = $start->date();
	
	$end = $this->end_date !== null 
			? new sfDate($this->end_date)
			: new sfDate($start->addMonth(Calendar::$defaultFutureMonths));
		
	$ed = $end->date();
	
	$query = new SQLQuery(
		't.ID AS \'ID\'',
		array(
			'CalendarDateTime t', 
			'LEFT JOIN CalendarEvent e ON t.EventID = e.ID', 
			'LEFT JOIN SiteTree s ON e.ID = s.ID'),
		"ParentID={$this->ID}
		AND (
			(StartDate <= '$sd' AND EndDate >= '$ed') OR
			(StartDate BETWEEN '$sd' AND '$ed') OR
			(EndDate BETWEEN '$sd' AND '$ed')
		)",
		'StartDate ASC, EndDate ASC',
		'EventID'
	);
	
	$result = $query->execute();
	if($result->numRecords() == 0)
		return false;
		
	$set = new DataObjectSet();
	foreach($result as $row){
		$set->push(DataObject::get_by_id($this->getEventDateTimeClass(), $row['ID']));
	}
	return $set;
}

Edit Just for clarification: Above method should be placed in your custom subclass of Calendar_Controller