I've come up with a way to bring the event categories along to the full calendar page so that you can use them to add classes, etc. on event render.
I think there must be a better way though, and was hoping someone else might have suggestions.
The easy part:
in the /display_objects/calendar/index.cfm (either site or theme level).
add method to fullCalendar init.
,eventRender : function(event, element, view){
if(event.categories && event.categories.length){
//convert to lower case & remove spaces
classStr = event.categories.replace(/ /g, "-").toLowerCase();
element.addClass(classStr);
}
}
This function requires 'categories' be part of the data return, which is the difficult part.
I found a better way to do it in the sql that is used to retrieve the event query, but wasn't able to use the mura '.addJoin()' method to actually get it to work, so I did the following instead:
in the file \requirements\mura\content\contentCalendarUtilityBean.cfc
modify function fullCalendarFormat() to be (added 2 lines for 'categories')
public any function fullCalendarFormat(required query data) {
var serializer = new mura.jsonSerializer()
.asString('id')
.asString('url')
.asDate('start')
.asDate('end')
.asString('title')
.asString('categories');
var qoq = new Query();
qoq.setDBType('query');
qoq.setAttributes(rs=arguments.data);
qoq.setSQL('
SELECT
url as [url]
, contentid as [id]
, menutitle as [title]
, displaystart as [start]
, displaystop as [end]
, categories as [categories]
FROM rs
');
local.rsQoQ = qoq.execute().getResult();
return serializer.serialize(local.rsQoQ);
}
This will allow a return of the categories to the event Calendar, provided you can get one.
Now the part that I'm not sold on.
For the function getCalendarItems()
I tried using the '.addJoin()', but it didn't seem to work, so I had to write queries & query-of-queries.
public any function getCalendarItems(
calendarid='#variables.$.content('contentid')#'
, start='#variables.$.event('year')#-#variables.$.event('month')#-1'
, end=''
, categoryid='#variables.$.event('categoryid')#'
, tag='#variables.$.event('tag')#'
, siteid='#variables.$.event('siteid')#'
, returnFormat='query'
) {
var tp = variables.$.initTracePoint('mura.content.contentCalendarUtilityBean.getCalendarItems');
var local = {};
local.contentBean = variables.$.getBean('content').loadBy(contentid=arguments.calendarid, siteid=arguments.siteid);
local.applyPermFilter = variables.$.siteConfig('extranet') == 1
&& variables.$.getBean('permUtility').setRestriction(local.contentBean.getCrumbArray()).restrict == 1;
if ( local.contentBean.getIsNew() || local.contentBean.getType() != 'Calendar' ) {
return QueryNew('url,contentid,menutitle,displaystart,displaystop');
}
// Start Date
if ( !IsDate(arguments.start) ) {
arguments.start = CreateDate(Year(Now()), Month(Now()), 1);
}
// End Date
if ( !IsDate(arguments.end) || ( IsDate(arguments.end) && Fix(arguments.end) < Fix(arguments.start) ) ) {
arguments.end = CreateDate(Year(arguments.start), Month(arguments.start), DaysInMonth(arguments.start));
}
// start and end dates
local.displaystart = DateFormat(arguments.start, 'yyyy-mm-dd');
local.displaystop = DateFormat(arguments.end, 'yyyy-mm-dd');
// the calendar feed
local.feed = variables.$.getBean('feed')
.setMaxItems(0) // get all records
.setNextN(0) // no pagination
.setSiteID(arguments.siteid)
.addParam(
relationship='AND'
,field='tcontent.parentid'
,condition='EQ'
,criteria=local.contentBean.getContentID()
)
// filter records with a displayStart date that is before the displayStop date
.addParam(
relationship='AND'
,field='tcontent.displaystart'
,condition='LTE'
,criteria=local.displaystop
)
// OPEN GROUPING
// filter records with a displayStop date that occurs after the displayStart date
// OR doesn't have one at all
.addParam(relationship='andOpenGrouping')
.addParam(
field='tcontent.displaystop'
,condition='GTE'
,criteria=local.displaystart
)
.addParam(
relationship='OR'
,field='tcontent.displaystop'
,criteria='null'
)
.addParam(relationship='closeGrouping');
// CLOSE GROUPING
// Filter on CategoryID
if ( Len(arguments.categoryid) && IsValid('uuid', arguments.categoryid) ) {
local.feed.setCategoryID(arguments.categoryid);
}
// Filter on Tags
if ( Len(arguments.tag) ) {
local.feed.addParam(
relationship='AND'
,field='tcontenttags.tag'
,condition='CONTAINS'
,criteria=URLDecode(arguments.tag)
);
}
// THIS IS WHERE USING addJoin() WOULD HAVE BEEN IDEAL.
// INSTEAD, CATEGORIES HAVE TO BE QUERIED SEPARATELY.
// the recordset/query
local.rs = local.feed.getQuery(from=local.displaystart, to=local.displaystop, applyPermFilter=local.applyPermFilter);
// ADDED TO INCLUDE CATEGORIES
local.catsQ = new query();
local.catsQ.setSQL("
SELECT DISTINCT tcontentcategories.name as catname, tcontentcategoryassign.contentID
FROM tcontentcategories
LEFT JOIN tcontentcategoryassign with (nolock) on (tcontentcategoryassign.categoryID = tcontentcategories.categoryID)
WHERE tcontentcategoryassign.contentID is not null
AND tcontentcategoryassign.contentID in ( :catslist )
");
//param to only fetch categories of events that were fetched, to keep down overhead
local.catsQ.addParam(
name='catslist'
, cfsqltype='cf_sql_varchar'
, value=valueList(local.rs.contentID)
, list='true'
);
local.cats=local.catsQ.execute().getResult();
// prepare to add URL column
// MODIFIED TO ALSO INCLUDE A CATEGORIES FIELD
qoq = new query();
qoq.setDBType('query');
qoq.setAttributes( rs1=local.cats );
QueryAddColumn(local.rs, 'URL', []);
QueryAddColumn(local.rs, 'CATEGORIES', []); //ADDED
for ( local.i=1; local.i<=local.rs.recordcount; local.i++ ) {
// add URL to rs
local.rs['URL'][i] = variables.$.createHref(filename=local.rs['filename'][i]);
// convert dates to UTC, then use browser's local tz settings to output the dates/times
/*
local.tempstart = DateConvert('local2utc', local.rs['displaystart'][i]);
local.tempend = DateConvert('local2utc', local.rs['displaystop'][i]);
local.rs['displaystart'][i] = isoDateTimeFormat(local.rs['displaystart'][i]);
local.rs['displaystop'][i] = isoDateTimeFormat(local.rs['displaystop'][i]);
*/
local.rs['CATEGORIES'][i] = ""; //ADDED
// TRY TO LINK CATEGORIES TO CONTENT
qoq.clearParams();
qoq.setSQL('SELECT * FROM rs1 where contentID = :cid ');
qoq.addParam(
name='cid'
, cfsqltype='cf_sql_varchar'
, value=local.rs['contentID'][i]
);
rsQoQ = qoq.execute().getResult();
if(rsQOQ.recordcount){
local.rs['CATEGORIES'][i] = valueList(rsQoQ.catname); //ACTUALLY ADD CATEGORIES TO QUERY RETURN
}
}
local.rs = filterCalendarItems(data=local.rs, maxItems=0);
variables.$.commitTracePoint(tp);
return arguments.returnFormat == 'iterator'
? variables.$.getBean('contentIterator').setQuery(local.rs)
: local.rs;
}
Needless to say, this is non update-safe, and it seems to me that this is a lot of modification for something that should have been simple.
Perhaps the best approach would be to modify the feed getQuery() function to always include categories, and all this file modification could go away?