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

EventCalendar and announcements


Go to End


40 Posts   8725 Views

Avatar
alexanm

Community Member, 38 Posts

3 August 2009 at 9:25pm

Edited: 03/08/2009 11:02pm

Hello,

solution for point 2 is to wrap the filter field into a fieldgroup, then the styles are applied correctly...

Thanks
Markus Alexander

Avatar
alexanm

Community Member, 38 Posts

3 August 2009 at 11:05pm

Hello again,

after I have wrapped my custom filter into a field group (as it is done in the CalendarFilterFieldSet.php file) it is rendered like the existing two filters for start and end. The main problem now is, that this field won't be used in the filter after this "workaround". When I remove the FieldGroup the querystring is correctly created with this filter (although it won't work, because the DateTime object is joined with the live suffix). When I add the FieldGroup the filter is missing from the resulting query string...

Any ideas here?

Markus Alexander

Avatar
alexanm

Community Member, 38 Posts

3 August 2009 at 11:11pm

Hello again,

3) After some further investigation I think that I have found a possible solution for my problem, that my custom date time class is not added as a part of the query:

The problem is the query for the recurring events. In the original it says:


	protected function getRecurringEvents($filter = null)
	{
		$suffix = Versioned::current_stage() == "Live" ? "_Live" : "";

		$where = "Recursion = 1 AND ParentID = {$this->ID}";
		$where .= $filter !== null ? " AND " . $filter : "";

		return DataObject::get(
			$this->getEventClass(),
			$where,
			"CalendarDateTime.StartDate ASC",
			"LEFT JOIN CalendarDateTime ON CalendarDateTime.EventID = CalendarEvent{$suffix}.ID"
		);
		
	}

As you can see the CalendarDateTime is hard coded as join for the query. But there is no traversal of the descendant classes of the date time class.

When I hard code the join like this:


	protected function getRecurringEvents($filter = null)
	{
		$suffix = Versioned::current_stage() == "Live" ? "_Live" : "";

		$where = "Recursion = 1 AND ParentID = {$this->ID}";
		$where .= $filter !== null ? " AND " . $filter : "";

		return DataObject::get(
			$this->getEventClass(),
			$where,
			"CalendarDateTime.StartDate ASC",
			"LEFT JOIN CalendarDateTime ON CalendarDateTime.EventID = CalendarEvent{$suffix}.ID"
			. " LEFT JOIN LineDanceDateTime ON CalendarDateTime.ID = LineDanceDateTime.ID"
		);
		
	}

everything works fine. So for me it looks like there should be a traversal of the descendant classes here as it is done with the event objects in the getjoin method.

What do you think about this?

Markus Alexander

Avatar
UncleCheese

Forum Moderator, 4102 Posts

4 August 2009 at 1:38am

Good catch. Thanks for hunting that down. I'll make the update.

Avatar
alexanm

Community Member, 38 Posts

4 August 2009 at 2:31am

Hello Uncle Cheese,

I have also tried to track down number one of my issues:
The main problem, that my datetime descendant (LineDanceDateTime) is added with the '_Live' suffix lies in the function getFiltersForDB:


	public static function getFiltersForDB()
	{
		if($filters = self::getCleanFilters()) {
			$suffix = Versioned::current_stage() == "Live" ? "_Live" : "";
			$for_db = array();
			foreach($filters as $key => $value) {
				$db_field = str_replace("_",".",$key);
				if(stristr($db_field,".") !== false) {
					$parts = explode(".",$db_field);
			
					$table1 = $parts[0] . $suffix;
					$table2 = $parts[1];
					$db_field = $table1.".".$table2;
				}
				else
					$db_field .= $suffix;

				$for_db[] = "$db_field = '$value'";
			}
			return $for_db;
		}
		return false;
	}

The suffic is alway added regardless of the ancestor of the table which is in the [parts[0] array field. Change the function to the following and it will work (although there may be a more elegant solution for this):


	public static function getFiltersForDB()
	{
		if($filters = self::getCleanFilters()) {
			$suffix = Versioned::current_stage() == "Live" ? "_Live" : "";
			$for_db = array();
			foreach($filters as $key => $value) {
				$db_field = str_replace("_",".",$key);
				if(stristr($db_field,".") !== false) {
					$parts = explode(".",$db_field);
					
					if (is_subclass_of($parts[0], 'SiteTree'))
						$table1 = $parts[0] . $suffix;
					else
						$table1 = $parts[0];
					$table2 = $parts[1];
					$db_field = $table1.".".$table2;
				}
				else
					$db_field .= $suffix;

				$for_db[] = "$db_field = '$value'";
			}
			return $for_db;
		}
		return false;
	}

But then the next problem arises: The custom filter is not taken into account for announcements. Changing the function Events() of the Calendar_Controller class to the following fixes this problem:


	public function Events($filter = null, $announcement_filter = null)
	{
		if($filter_list = Calendar::getFiltersForDB()) {
			$filter = (sizeof($filter_list > 1)) ? implode(" AND ", $filter_list) : $filter_list;
			$announcement_filter = (sizeof($filter_list > 1)) ? implode(" AND ", $filter_list) : $filter_list;
		}
		return $this->getModel()->Events($filter, $this->start_date, $this->end_date, ($this->view == "default"), null, $announcement_filter);
	}

For me the custom added filter works for me now, but I am not sure if it breaks anything else. With my special situation this seems to work.

Now I have the only problem, that the custom filter is not taken into account when I place it into a FilterGroup :-(...

Markus Alexander

Avatar
alexanm

Community Member, 38 Posts

4 August 2009 at 2:35am

Edited: 04/08/2009 2:52am

Hello again,

and I have found a typo in CalendarFilterFieldSet:


	public function removeEndFields()
	{
		$this->removeByName('EmdMonth');
		$this->removeByName('EndDay');
		$this->removeByName('EndYear');
	}

I think it should read 'EndMonth'

Markus Alexander

Avatar
UncleCheese

Forum Moderator, 4102 Posts

4 August 2009 at 8:00am

I have just checked in a bunch of changes that address some of the issues you have raised. Let me know if it works for you.

Avatar
alexanm

Community Member, 38 Posts

4 August 2009 at 4:52pm

Hello UncleCheese,

first of all, many thanks for your assistance and very excellent help.
I have tried your the new version. Number 3 of my issues seems to work...

But when I try to use my custom filter I get the following error:

[User Error] Couldn't run query: SELECT `CalendarDateTime`.*, `LineDanceDateTime`.*, `CalendarDateTime`.ID, if(`CalendarDateTime`.ClassName,`CalendarDateTime`.ClassName,'CalendarDateTime') AS RecordClassName FROM `CalendarDateTime` LEFT JOIN `LineDanceDateTime` ON `LineDanceDateTime`.ID = `CalendarDateTime`.ID WHERE (CalendarID=10 AND StartDate BETWEEN '2009-08-04' AND '2009-08-04' AND Array) AND (`CalendarDateTime`.ClassName IN ('LineDanceDateTime')) ORDER BY StartDate ASC Unknown column 'Array' in 'where clause'

Any ideas?

Markus Alexander

Go to Top