diff --git a/_build/data/transport.snippets.php b/_build/data/transport.snippets.php
index f2285f3..11c6c50 100644
--- a/_build/data/transport.snippets.php
+++ b/_build/data/transport.snippets.php
@@ -10,14 +10,60 @@ function getSnippetContent($filename) {
$snippets[1]= $modx->newObject('modSnippet');
$snippets[1]->fromArray(array(
'id' => 1,
- 'name' => 'mxcalendar',
+ 'name' => 'mxCalendar',
'description' => 'Displays events in either calendar, list, or detail view.',
- 'snippet' => getSnippetContent($sources['elements'].'snippets/snippet.mxcalendars.php'),
+ 'snippet' => getSnippetContent($sources['elements'].'snippets/snippet.mxcalendar.php'),
),'',true,true);
-$properties = include $sources['data'].'properties/properties.mxcalendars.php';
+$properties = include $sources['data'].'properties/properties.mxcalendar.php';
$snippets[1]->setProperties($properties);
unset($properties);
+//-- Add init snippet (2)
+$snippets[2]= $modx->newObject('modSnippet');
+$snippets[2]->fromArray(array(
+ 'id' => 2,
+ 'name' => 'mxCalendarInit',
+ 'description' => 'Init mxCalendar service.',
+ 'snippet' => getSnippetContent($sources['elements'].'snippets/mxcalendarinit.php'),
+),'',true,true);
+$properties = include $sources['data'].'properties/properties.mxcalendarinit.php';
+$snippets[2]->setProperties($properties);
+unset($properties);
+
+//-- Add getEvents snippet (3)
+$snippets[3]= $modx->newObject('modSnippet');
+$snippets[3]->fromArray(array(
+ 'id' => 3,
+ 'name' => 'mxCalendarGetEvents',
+ 'description' => 'Get events (retrieved from database together with generated on-the-fly by repeat template).',
+ 'snippet' => getSnippetContent($sources['elements'].'snippets/snippet.mxcalendargetevents.php'),
+),'',true,true);
+$properties = include $sources['data'].'properties/properties.mxcalendargetevents.php';
+$snippets[3]->setProperties($properties);
+unset($properties);
+//-- Add sort snippet (4)
+$snippets[4]= $modx->newObject('modSnippet');
+$snippets[4]->fromArray(array(
+ 'id' => 4,
+ 'name' => 'mxCalendarSort',
+ 'description' => 'Sort events.',
+ 'snippet' => getSnippetContent($sources['elements'].'snippets/snippet.mxcalendarsort.php'),
+),'',true,true);
+$properties = include $sources['data'].'properties/properties.mxcalendarsort.php';
+$snippets[4]->setProperties($properties);
+unset($properties);
+
+//-- Add prepare for render snippet (5)
+$snippets[5]= $modx->newObject('modSnippet');
+$snippets[5]->fromArray(array(
+ 'id' => 5,
+ 'name' => 'mxCalendarPrerender',
+ 'description' => 'Prepare events for render.',
+ 'snippet' => getSnippetContent($sources['elements'].'snippets/snippet.mxcalendarprerender.php'),
+),'',true,true);
+$properties = include $sources['data'].'properties/properties.mxcalendarprerender.php';
+$snippets[5]->setProperties($properties);
+unset($properties);
return $snippets;
\ No newline at end of file
diff --git a/core/components/mxcalendars/elements/snippets/snippet.eventSubmission.php b/core/components/mxcalendars/elements/snippets/snippet.eventSubmission.php
index fb0f42e..860b092 100644
--- a/core/components/mxcalendars/elements/snippets/snippet.eventSubmission.php
+++ b/core/components/mxcalendars/elements/snippets/snippet.eventSubmission.php
@@ -1,11 +1,13 @@
getService('mxcalendars','mxCalendars',$modx->getOption('mxcalendars.core_path',null,$modx->getOption('core_path').'components/mxcalendars/').'model/mxcalendars/',$scriptProperties);
-if (!($mxcal instanceof mxCalendars)) return 'Error loading instance of mxCalendars.';
-
-include_once($modx->getOption('mxcalendars.core_path',null,$modx->getOption('core_path').'components/mxcalendars/').'processors/mgr/mxcHelper.php');
+/**
+ * SAMPLE EVENT SUBMISSION HOOK FOR mxFormBuilder
+ *
+ * @var $modx modX
+ * @var $scriptProperties array
+ */
+
+/** @var $mxCal mxCalendars */
+$mxCal = $modx->runSnippet('mxCalendar.init', $scriptProperties);
$allFormFields = $hook->getProperties();
diff --git a/core/components/mxcalendars/elements/snippets/snippet.mxcalendar.php b/core/components/mxcalendars/elements/snippets/snippet.mxcalendar.php
new file mode 100644
index 0000000..49bda44
--- /dev/null
+++ b/core/components/mxcalendars/elements/snippets/snippet.mxcalendar.php
@@ -0,0 +1,322 @@
+runSnippet('mxCalendarInit', $scriptProperties);
+
+/* setup default properties */
+$theme = $modx->getOption('theme',$scriptProperties,'default');// default, traditional
+$excludeCSS = $modx->getOption('excludeCSS', $scriptProperties, 0);
+$resourceId = $modx->getOption('resourceId', $scriptProperties, $modx->resource->get('id'));
+$isLocked = $modx->getOption('isLocked', $scriptProperties, 0);
+$displayType = isset($_REQUEST['detail']) && !$isLocked ? 'detail' : (isset($_REQUEST['displayType']) ? $_REQUEST['displayType'] : $modx->getOption('displayType', $scriptProperties, 'calendar')); //calendar,list,mini
+$eventid = !empty($_REQUEST['mxcid']) ? (int)$_REQUEST['mxcid'] : null;
+//++ Images properties
+$imageLimit = $modx->getOption('limit',$scriptProperties,'15');
+$imageDisable = $modx->getOption('imageDisable',$scriptProperties,0);
+//++ Results query properties
+$eventListStartDate = (isset($_REQUEST['elStartDate']) && !$isLocked ? $_REQUEST['elStartDate'] : $modx->getOption('elStartDate',$scriptProperties,'now'));
+$eventListEndDate = (isset($_REQUEST['elEndDate']) && !$isLocked ? $_REQUEST['elEndDate'] : $modx->getOption('elEndDate',$scriptProperties,'+1 year'));
+$elDirectional = $modx->getOption('elDirectional',$scriptProperties, false);
+$tplElItem = $modx->getOption('tplListItem',$scriptProperties,'el.itemclean');
+$tplElMonthHeading = $modx->getOption('tplListHeading',$scriptProperties,'el.listheading');
+$tplElWrap = $modx->getOption('tplListWrap',$scriptProperties,'el.wrap');
+$tplNoEvents = $modx->getOption('tplNoEvents',$scriptProperties,'el.noevents');
+$eventListLimit = $modx->getOption('eventListlimit',$scriptProperties,'5');
+$sort = $modx->getOption('mxc.sort',$scriptProperties,'startdate');
+$dir = $modx->getOption('mxc.dir',$scriptProperties,'ASC');
+$limit = $modx->getOption('limit',$scriptProperties,'99');
+$limitstart = $modx->getOption('limitstart', $scriptProperties, 0);
+//++ Text|Date Formatting properties
+$dateFormat = $modx->getOption('dateformat', $scriptProperties, '%Y-%m-%d');
+$timeFormat = $modx->getOption('timeformat', $scriptProperties, '%H:%M %p');
+$dateSeperator = $modx->getOption('dateseperator',$scriptProperties, '/');
+//++ Display: Calendar properties
+$activeMonthOnlyEvents = $modx->getOption('activeMonthOnlyEvents', $scriptProperties, 0);
+$highlightToday = $modx->getOption('highlightToday', $scriptProperties, 1);
+$todayClass = $modx->getOption('todayClass', $scriptProperties, 'today');
+$noEventsClass = $modx->getOption('noEventClass', $scriptProperties, 'mxcDayNoEvents');
+$hasEventsClass = $modx->getOption('hasEventsClass', $scriptProperties,'mxcEvents');
+$tplEvent = $modx->getOption('tplEvent',$scriptProperties,'month.inner.container.row.day.eventclean');
+$tplDay = $modx->getOption('tplDay',$scriptProperties,'month.inner.container.row.day');
+$tplWeek = $modx->getOption('tplWeek',$scriptProperties,'month.inner.container.row');
+$tplMonth = $modx->getOption('tplMonth',$scriptProperties,'month.inner.container');
+$tplHeading = $modx->getOption('tplHeading',$scriptProperties,'month.inner.container.row.heading');
+//++Display: Detail
+$tplDetail = $modx->getOption('tplDetail',$scriptProperties,'detail');
+$tplDetailModal = $modx->getOption('tplDetailModal', $scriptProperties, 'detail.modal');
+$tplImageItem = $modx->getOption('tplImageItem', $scriptProperties, 'image');
+$tplVideoItem = $modx->getOption('tplVideoItem', $scriptProperties, 'video');
+$mapWidth = $modx->getOption('mapWidth', $scriptProperties, '500px');
+$mapHeight = $modx->getOption('mapHeight', $scriptProperties, '500px');
+//++Display: Categories
+$showCategories = $modx->getOption('showCategories',$scriptProperties,1);
+$tplCategoryWrap = $modx->getOption('tplCategoryWrap',$scriptProperties,'category.container');
+$tplCategoryItem = $modx->getOption('tplCategoryItem',$scriptProperties,'category.container.item');
+$labelCategoryHeading = $modx->getOption('labelCategoryHeading',$scriptProperties,$mxCal->modx->lexicon('mxcalendars.label_category_heading'));
+//@TODO Possibly add to the properties set
+//++Aux Parameters: AJAX, Modal, etc.*
+$addJQ = $modx->getOption('addJQ', $scriptProperties,1); //-- jQuery is required for the core mxCalendar JS to function
+$jqLibSrc = $modx->getOption('jqLibSrc', $scriptProperties,'https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js');
+$usemxcLib = $modx->getOption('usemxcLib', $scriptProperties,1); //-- Use the stand-a-lone modal windows JS library packaged with mxCalendar
+$ajaxResourceId = $modx->getOption('ajaxResourceId', $scriptProperties, null);
+$ajaxMonthResourceId = $modx->getOption('ajaxMonthResourceId', $scriptProperties, null);
+$modalView = $modx->getOption('modalView', $scriptProperties,1);
+$modalSetWidth = $modx->getOption('modalSetWidth', $scriptProperties,null); //-- Ver > 0.0.3-beta
+$modalSetHeight =$modx->getOption('modalSetHeight', $scriptProperties,null); //-- Ver > 0.0.3-beta
+//@TODO Possibly add to the properties set
+//++Location Specific options for Google Maps v3.x
+$gmapLib = $modx->getOption('gmapLib', $scriptProperties, 'http://maps.google.com/maps/api/js?sensor=false');
+$gmapId = $modx->getOption('gmapId',$scriptProperties, 'map');
+$gmapDefaultZoom = $modx->getOption('gmapDefaultZoom', $scriptProperties, '13');
+$gmapAPIKey = $modx->getOption('gmapAPIKey', $scriptProperties, 'null');
+$gmapRegion = $modx->getOption('gmapRegion', $scriptProperties, '');
+//++ Holiday Support
+$holidays = $modx->getOption('holidays', $scriptProperties, "{'us':{''}}");
+$holidayDisplayEvents = $modx->getOption('holidayDisplayEvents', $scriptProperties, 1);
+//++ Used in very limited cases
+$setTimezone = $modx->getOption('setTimezone', $scriptProperties, null );
+$debugTimezone = $modx->getOption('debugTimezone', $scriptProperties, 0 );
+$debug = $modx->getOption('debug',$scriptProperties,0);
+//++ Set a feed processor timezone adjustment
+$setFeedTZ = $modx->getOption('setFeedTZ', $scriptProperties, null); // Example: FeedId=2; TargetTimeZone=New York; would result in => `{"2":"America/New_York"}`
+//++ Calendar Options (ver >= 1.1.6d-pr)
+// Defaults to blank (ie show all categories).
+if ($categoryFilter = urldecode(isset($_REQUEST['cid']) ? $_REQUEST['cid'] : $modx->getOption('categoryFilter', $scriptProperties, null))) {
+ // Adding comma for retrieving events that are category-agnostic (ie have blank category).
+ $categoryFilter = ",{$categoryFilter}";
+}
+//++ Calendar Options (ver >= 1.1.0-pl)
+// Defaults to blank (ie show all calendars).
+if ($calendarFilter = (isset($_REQUEST['calf']) ? $_REQUEST['calf'] : $modx->getOption('calendarFilter', $scriptProperties, null))) {
+ // Adding comma for retrieving events that are calendar-agnostic (ie have blank calendar).
+ $calendarFilter = ",{$calendarFilter}";
+};
+//++ Context Options (ver >= 1.1.0-pl)
+// Defaults to current context.
+// Could be blank (ie show all contexts).
+if ($contextFilter = ','.(isset($_REQUEST['conf']) ? $_REQUEST['conf'] : $modx->getOption('contextFilter',$scriptProperties, $modx->context->key))) {
+ // Adding comma for retrieving events that are context-agnostic (ie have blank context).
+ $contextFilter = ",{$contextFilter}";
+}
+//++ Form Chunk Filter match name
+$formFilter = $modx->getOption('formFilter',$scriptProperties,'form_');
+//++ Caching Options
+$cacheEnable = $modx->getOption('cacheEnable',$scriptProperties,0);
+$cacheLifetime = $modx->getOption('cacheLifetime',$scriptProperties,null); //3600 would be one hour - and overrides the resource lifetime; leaving null inherits the resource cache lifetime settings
+if (empty($cacheKey)) $cacheKey = $modx->getOption('cache_resource_key', null, 'resource');
+if (empty($cacheHandler)) $cacheHandler = $modx->getOption('cache_resource_handler', null, $modx->getOption(xPDO::OPT_CACHE_HANDLER, null, 'xPDOFileCache'));
+if (!isset($cacheExpires)) $cacheExpires = $cacheLifetime!==null ? (integer)$cacheLifetime : (integer) $modx->getOption('cache_resource_expires', null, $modx->getOption(xPDO::OPT_CACHE_EXPIRES, null, 0));
+if (empty($cacheElementKey)) $cacheElementKey = $modx->resource->getCacheKey() . '/' . md5($modx->toJSON($properties) . implode('', $modx->request->getParameters()));
+$cacheOptions = array(xPDO::OPT_CACHE_KEY => $cacheKey,xPDO::OPT_CACHE_HANDLER => $cacheHandler,xPDO::OPT_CACHE_EXPIRES => $cacheExpires,);
+$results = $modx->cacheManager->get($cacheElementKey, $cacheOptions);
+
+//-- Update to the Timezone
+if(!empty($setTimezone)) $mxCal->setTimeZone($setTimezone,$debugTimezone);
+//-- Update to the Timezone: Manual fix to adjust timezone to match server settings examples.
+//date_default_timezone_set("Europe/Amsterdam");
+//date_default_timezone_set('America/New_York');
+// Process any needed Feeds as setup in mxCalendar Manager
+
+$feed = $modx->getObject('mxCalendarFeed', 10);
+if($feed){
+ $feed->set('nextrunon', 0);
+ $feed-save();
+}
+$mxCal->processFeeds($setFeedTZ);
+if($modx->resource->get('id') != $ajaxResourceId && $modx->resource->get('id') != $ajaxMonthResourceId) {
+ //-- Add mxCalendar Theme CSS to html header (set in snippit properties)
+ if($excludeCSS !== 1 && $excludeCSS !== '1'){
+ $modx->regClientCSS($modx->getOption('mxcalendars.assets_url',null,$modx->getOption('assets_url').'components/mxcalendars/').'themes/'.$theme.'/css/mxcalendar.css');
+ }
+ //-- Add the Shadowbox library info if we are using modal
+ if(($modalView == 'true' || $modalView == 1) && ($usemxcLib == 'true' || $usemxcLib == 1)) {
+ $mxCal->addShadowBox($modalSetWidth,$modalSetHeight);
+ } else { $mxCal->disableModal(); }
+ //-- Add mxCalendar jQuery Library if enabled
+ if($addJQ && $addJQ !== 'false'){
+ $modx->regClientStartupScript($jqLibSrc);
+ //-- Only add the required JS files we need
+ if(!empty($ajaxResourceId) && $modx->resource->get('id') != $ajaxResourceId && $modx->resource->get('id') != $ajaxMonthResourceId)//-- Also requires a valid jQuery library be loaded
+ $modx->regClientStartupScript($mxCal->config['assetsUrl'].'js/web/mxc-calendar.js');
+ }
+}
+if(((int)$cacheEnable === 1 || $cacheEnable === '1') && !empty($results) && $debug !== 1)
+ return $results;
+
+if($debug)
+ var_dump($scriptProperties);
+$elStartDate = strtotime($eventListStartDate);
+if($elStartDate ===false){
+ if($debug) echo 'Could not convert elStartDate value of "'.$elStartDate.'" to proper time stamp.
';
+ $elStartDate = time();
+}
+$elEndDate = strtotime($eventListEndDate);
+if($elEndDate ===false){
+ if($debug) echo 'Could not convert elEndDate value of "'.$elEndDate.'" to proper time stamp.
';
+ $elEndDate = time();
+}
+
+//-- Setup varibles to hold the output
+$debugOutput = array();
+$arrEventsDetail = array();
+$arrEventDates=array();
+$output = '';
+$time_start = microtime(true);
+if($debug) $output .= "
Total Events: ".count($modx->getCollection('mxCalendarEvents'));
+$whereArr = array();
+$eventsArr = array();
+$c = $modx->newQuery('mxCalendarEvents');
+$c->select(array(
+ 'mxCalendarEvents.*',
+));
+// Create the where clause by display type to limit the returned records
+switch ($displayType){
+ case 'list':
+ case 'daily':
+ case 'ical':
+ case 'rss':
+ $sort = 'startdate';
+ if(is_integer($eventid) && $eventid !== null){
+ $whereArr = array(array('mxCalendarEvents.id:='=>$eventid));
+ } elseif (!$elDirectional) {
+ $whereArr = array(array('repeating:=' => 0,'AND:enddate:>=' => $elStartDate,'AND:enddate:<=' => $elEndDate,array('OR:repeating:='=>1,'AND:repeatenddate:>=' => $elStartDate)) );
+ } else {
+ SWITCH($elDirectional){
+ default:
+ case 'f':
+ case 'future':
+ case 'forward':
+ $whereArr = array(array('repeating:=' => 0,array('AND:enddate:>=' => $elStartDate,'OR:enddate:>=' => $elStartDate),array('OR:repeating:='=>1,'AND:repeatenddate:>=' => $elStartDate)) );
+ break;
+ case 'b':
+ case 'p':
+ case 'past':
+ case 'backward':
+ $whereArr = array(array('repeating:=' => 0,array('AND:enddate:<=' => $elStartDate,'OR:enddate:<=' => $elStartDate),array('OR:repeating:='=>1,'AND:repeatenddate:<=' => $elStartDate)) );
+ break;
+ }
+ }
+ break;
+ case 'calendar':
+ case 'mini':
+ default:
+ $dr = $mxCal->getEventCalendarDateRange($activeMonthOnlyEvents);
+ $elStartDate = $dr['start'];
+ $elEndDate = $dr['end'];
+ $whereArr = array(array(
+ 'repeating:=' => 0,
+ 'AND:enddate:>=' => $elStartDate,
+ 'AND:enddate:<=' => $elEndDate
+ ,array('OR:repeating:='=>1,
+ 'AND:repeatenddate:>=' => $elStartDate)
+ ) );
+ break;
+ case 'year':
+ break;
+ case 'detail':
+ $whereArr = array(array('id' => (int)$_REQUEST['detail']));
+ //$whereArr[0]['AND:id:='] = (int)$_REQUEST['detail']; //@TODO Make filter for single events repeating dates
+ break;
+}
+//-- ADD IN THE CONTEXT AND CALENDAR PROPERTY FILTERS
+if (!empty($contextFilter)) {
+ $whereArr['AND:context:IN'] = explode(',',$contextFilter);
+}
+if (!empty($calendarFilter)) {
+ $whereArr['AND:calendar_id:IN'] = explode(',',$calendarFilter);
+}
+if (!empty($categoryFilter)) {
+ foreach (explode(',',$categoryFilter) as $category) {
+ if (empty($category)) {
+ // For blank just show all.
+ break;
+ }
+ if($displayType == 'calendar' || $displayType == 'mini' || $displayType == 'list') {
+ $whereArr[] = array(
+ array('categoryid' => $category),
+ array('OR:categoryid:LIKE' => '%,'.$category.',%'),
+ array('OR:categoryid:LIKE' => '%,'.$category),
+ array('OR:categoryid:LIKE' => $category.',%'),
+ );
+ }
+ }
+}
+$whereArr['mxCalendarEvents.active'] = 1;
+$c->where($whereArr);
+if($displayType != 'detail')
+ $c->sortby($sort,$dir);
+$c->limit($limit,$limitstart);
+
+// Get events.
+list($events, $debugOutputTemp) = $modx->runSnippet('mxCalendarGetEvents', array_merge($scriptProperties, array(
+ 'criteria' => $c,
+ 'debug' => $debug,
+)));
+$debugOutput .= $debugOutputTemp;
+
+// Sort.
+list($events, $debugOutputTemp) = $modx->runSnippet('mxCalendarSort', array_merge($scriptProperties, array(
+ 'events' => $events,
+ 'direction' => $dir,
+ 'debug' => $debug,
+)));
+$debugOutput .= $debugOutputTemp;
+
+// Prepare for render.
+list($events, $debugOutputTemp) = $modx->runSnippet('mxCalendarPrerender', array_merge($scriptProperties, array(
+ 'events' => $events,
+ 'elStartDate' => $elStartDate,
+ 'elEndDate' => $elEndDate,
+ 'displayType' => $displayType,
+ 'debug' => $debug,
+ 'limit' => $limit,
+)));
+$debugOutput .= $debugOutputTemp;
+
+// @todo Refactor Avoid echoing from snippet.
+echo $debugOutput;
+
+// @todo Refactor Turn into render snippet.
+$modx->setPlaceholders(array('dateseperator'=>$dateSeperator));
+//----- NOW GET THE DISPLAY TYPE ------//
+switch ($displayType){
+ case 'list':
+ case 'daily':
+ case 'ical':
+ case 'rss':
+ $output = $mxCal->makeEventList($eventListLimit, $eventsArr, array('tplElItem'=>$tplElItem, 'tplElMonthHeading'=>$tplElMonthHeading, 'tplElWrap'=>$tplElWrap, 'tplImage'=>$tplImageItem, 'tplVideo'=>$tplVIdeoItem, 'tplNoEvents'=>$tplNoEvents),$elStartDate,$elEndDate);
+ break;
+ case 'year':
+ break;
+ case 'detail':
+ if($debug) $output .= 'Total Occurances: '.count($eventsArr).' for Event ID: '.$_REQUEST['detail'].'
';
+ if(isset($resourceId) && $modx->resource->get('id') != $resourceId)
+ $tplDetail = $tplDetailModal;
+ $output .= $mxCal->makeEventDetail($eventsArr,($occurance=$_REQUEST['r']?$_REQUEST['r']:0) , array('tplDetail'=>$tplDetail, 'tplImage'=>$tplImageItem, 'tplVideo'=>$tplVIdeoItem),$mapWidth,$mapHeight,$gmapRegion);
+ //$whereArr[0]['AND:id:='] = (int)$_REQUEST['detail']; //@TODO Make filter for single events repeating dates
+ break;
+ case 'calendar':
+ case 'mini':
+ default:
+ $timer_10 = new makeProcessTime($time_start,$debug);
+ $output = $mxCal->makeEventCalendar($eventsArr,(!empty($ajaxResourceId) && $modalView? $ajaxResourceId : $resourceId),(!empty( $ajaxMonthResourceId) ? $ajaxMonthResourceId : (!empty($ajaxResourceId) ? $ajaxResourceId : $resourceId) ),array('event'=>$tplEvent,'day'=>$tplDay,'week'=>$tplWeek,'month'=>$tplMonth,'heading'=>$tplHeading, 'tplImage'=>$tplImageItem, 'tplVideo'=>$tplVIdeoItem), $contextFilter, $calendarFilter, $highlightToday);
+ $timer_10->end('UI Rendering');
+ break;
+}
+//-- Always allow the category list placeholder to be set
+if($showCategories == true)
+ $modx->setPlaceholder('categories', $mxCal->makeCategoryList($labelCategoryHeading, ($_REQUEST['cid'] ? $_REQUEST['cid'] : null),$resourceId, array('tplCategoryWrap'=>$tplCategoryWrap, 'tplCategoryItem'=>$tplCategoryItem)));
+$mxCal->restoreTimeZone($debugTimezone);
+$time_end = microtime(true);
+$time = $time_end - $time_start;
+if($debug) echo "
mxCalendar processed in $time seconds
\n";
+$modx->cacheManager->set($cacheElementKey, $output, $cacheExpires, $cacheOptions);
+
+return $output;
\ No newline at end of file
diff --git a/core/components/mxcalendars/elements/snippets/snippet.mxcalendargetevents.php b/core/components/mxcalendars/elements/snippets/snippet.mxcalendargetevents.php
new file mode 100644
index 0000000..dc085c8
--- /dev/null
+++ b/core/components/mxcalendars/elements/snippets/snippet.mxcalendargetevents.php
@@ -0,0 +1,117 @@
+runSnippet('mxCalendarInit', $scriptProperties);
+
+$debugOutput = '';
+$debug = $modx->getOption('debug', $scriptProperties);
+$criteria = $modx->getOption('criteria', $scriptProperties, $modx->newQuery('mxCalendarEvents')->select(array(
+ 'mxCalendarEvents.*',
+)));
+$criteria->prepare();
+if($debug) $debugOutput .= '
Filtering calendar date SQL range with: '.strftime('%m/%d/%Y', $elStartDate).' through '.strftime('%m/%d/%Y', $elEndDate).'
';
+if($debug) $debugOutput .= 'SQL: '.$criteria->toSql().'
';
+$queryTimer = new makeProcessTime(null,$debug);
+$mxcalendars = $modx->getCollection('mxCalendarEvents',$criteria);
+$queryTimer->end('mxCalendars Query');
+if($debug) $debugOutput .= "
Returned Events: ".count($mxcalendars).'
';
+$resultLoopTimer = new makeProcessTime(null,$debug);
+$arrEventDates = array();
+/** @var $mxc mxCalendarEvents */
+foreach ($mxcalendars as $mxc) {
+ //-- Convert the object to an array
+ $mxcArray = $mxc->toArray();
+
+ $eStart = new DateTime(date('Y-m-d H:i:s',$mxc->get('startdate')));
+ $eEnd = new DateTime(date('Y-m-d H:i:s',$mxc->get('enddate')));
+
+ $isNew = (version_compare(PHP_VERSION, '5.3.0') >= 0);
+ $diff = $isNew ? $eStart->diff($eEnd) : (object)$mxCal->datediff($mxc->get('startdate'),$mxc->get('enddate'),true);
+ $durYear = $isNew ? $diff->format('%y') : $diff->years;
+ $durMonth = $isNew ? $diff->format('%m') : $diff->months;
+ $durDay = $isNew ? $diff->format('%d') : $diff->days;
+ $durHour = $isNew ? $diff->format('%h') : $diff->hours;
+ $durMin = $isNew ? $diff->format('%i') : $diff->minutes;
+ $durSec = $isNew ? $diff->format('%s') : $diff->seconds;
+
+ //-- return event duration values
+ $mxcArray['durYear'] = !empty($durYear) ? $durYear : null;
+ $mxcArray['durMonth'] = !empty($durMonth) ? $durMonth : null;
+ $mxcArray['durDay'] = !empty($durDay) ? $durDay : null;
+ $mxcArray['durHour'] = !empty($durHour) ? $durHour : null;
+ $mxcArray['durMin'] = !empty($durMin) ? $durMin : null;
+ $mxcArray['durSec'] = !empty($durSec) ? $durSec : null;
+ $mxcArray['mxcmodalClass'] = ($modalView && $ajaxResourceId || isset($_REQUEST['imajax']) ? 'mxcmodal' : '');
+
+ $arrEventsDetail[$mxcArray['id']] = $mxcArray;
+ $arrEventDates[$mxcArray['id']] = array(
+ 'date'=>$mxcArray['startdate'],
+ 'eventId'=>$mxcArray['id'],
+ 'repeatId'=>0,
+ );
+
+ //-- If we have repeating dates and repeating is enabled lets add those to the array
+ if ($mxcArray['repeating'] && ($repeatDates = explode(',', $mxcArray['repeatdates']))) {
+ if($debug) $debugOutput .= 'Repeating Event: '.$mxcArray['title'].'
';
+ if($debug) $debugOutput .= ' ++(0) '.strftime($dateFormat.' '.$timeFormat, $mxcArray['startdate']).'
';
+ $rid = 1;
+ foreach ($repeatDates AS $rDate) {
+ if (empty($rDate)) {
+ continue;
+ }
+ $arrEventDates[$mxcArray['id'].'-'.$rid] = array(
+ 'date'=>$rDate,
+ 'eventId'=>$mxcArray['id'],
+ 'repeatId'=>$rid,
+ );
+ if($debug) $debugOutput .= ' ++('.$rid.') '.strftime($dateFormat.' '.$timeFormat, $rDate).'
';
+ $rid++;
+ }
+ }
+
+ // Add date for each day in a multiple day event ( #127 )
+ if($mxcArray['durDay'] !== null && $mxcArray['durDay'] >= 1){
+ if($debug) $debugOutput .= 'Multiple Day Event: '.$mxcArray['title'].'
';
+
+ /*
+ $i = 1;
+ $endDate = $mxc->get('enddate');
+ while(strtotime('+'.$i.' day', $mxcArray['startdate']) < $endDate){
+ $theSpanDate = strtotime('+'.$i.' day', $mxcArray['startdate']);
+ $arrEventDates[$mxcArray['id'].'_'.$i] = array('date'=>$theSpanDate, 'eventId'=>$mxcArray['id'],'repeatId'=>null);
+ if($debug) $debugOutput .= ' ++('.$i.') '.strftime($dateFormat.' '.$timeFormat, $theSpanDate).'
';
+ $i++;
+ }
+ *
+ */
+
+ for ($i = 1; $i<=$mxcArray['durDay']; $i++) {
+ $theSpanDate = strtotime('+'.$i.' day', $mxcArray['startdate']);
+ $arrEventDates[$mxcArray['id'].'_'.$i] = array(
+ 'date'=>$theSpanDate,
+ 'eventId'=>$mxcArray['id'],
+ 'repeatId'=>null,
+ );
+ if($debug) $debugOutput .= ' ++('.$i.') '.strftime($dateFormat.' '.$timeFormat, $theSpanDate).'
';
+ }
+ }
+
+ //$output .= $mxCal->getChunk($tpl,$mxcArray);
+}
+$resultLoopTimer->end('mxc result set loop');
+
+// Indexed array - in order to be used with list().
+return array($arrEventDates,$debugOutput);
\ No newline at end of file
diff --git a/core/components/mxcalendars/elements/snippets/snippet.mxcalendarinit.php b/core/components/mxcalendars/elements/snippets/snippet.mxcalendarinit.php
new file mode 100644
index 0000000..8644ecb
--- /dev/null
+++ b/core/components/mxcalendars/elements/snippets/snippet.mxcalendarinit.php
@@ -0,0 +1,16 @@
+getOption('core_path');
+$mxCalendarCorePath = $modx->getOption('mxcalendars.core_path',null,"{$corePath}components/mxcalendars/");
+$mxCal = $modx->getService('mxcalendars','mxCalendars',$mxCalendarCorePath.'model/mxcalendars/',$scriptProperties);
+if (!($mxCal instanceof mxCalendars)) throw new Exception('Error loading instance of mxCalendars.');
+include_once "{$mxCalendarCorePath}processors/mgr/mxcHelper.php";
+return $mxCal;
\ No newline at end of file
diff --git a/core/components/mxcalendars/elements/snippets/snippet.mxcalendarprerender.php b/core/components/mxcalendars/elements/snippets/snippet.mxcalendarprerender.php
new file mode 100644
index 0000000..47e453a
--- /dev/null
+++ b/core/components/mxcalendars/elements/snippets/snippet.mxcalendarprerender.php
@@ -0,0 +1,71 @@
+runSnippet('mxCalendarInit', $scriptProperties);
+
+$debugOutput = '';
+$debug = $modx->getOption('debug', $scriptProperties);
+$eventsRaw = $modx->getOption('events', $scriptProperties, array());
+if (empty($eventsRaw)) {
+ $debugOutput .= "No data to prepare for render.\n";
+}
+$elStartDate = $modx->getOption('elStartDate', $scriptProperties);
+$elEndDate = $modx->getOption('elEndDate', $scriptProperties);
+$displayType = $modx->getOption('displayType', $scriptProperties);
+$elDirectional = $modx->getOption('elDirectional',$scriptProperties, false);
+$limit = $modx->getOption('limit',$scriptProperties,'99');
+
+if($debug) $debugOutput .= 'Looping through events list of '.count($arrEventDates).' total.
';
+$ulimit=0;
+
+$arrayEventTimer = new makeProcessTime(null,$debug);
+
+$cnt = 1;
+$events = [];
+foreach ($eventsRaw AS $k=>$e) {
+ $oDetails = $arrEventsDetail[$e['eventId']]; //Get original event (parent) details
+ $oDetails['startdate'] = $e['date'];
+ $oDetails['enddate'] = strtotime('+'.($arrEventsDetail[$e['eventId']]['durDay'] ? $arrEventsDetail[$e['eventId']]['durDay'].' days ' :'').($arrEventsDetail[$e['eventId']]['durHour'] ? $arrEventsDetail[$e['eventId']]['durHour'].' hour ' :'').($arrEventsDetail[$e['eventId']]['durMin'] ? $arrEventsDetail[$e['eventId']]['durMin'].' minute' :''), $e['date']);//$e['date'];//repeatenddate
+ if((
+ (
+ ($oDetails['startdate']>=$elStartDate || $oDetails['enddate'] >= $elStartDate)
+ &&
+ $oDetails['enddate']<=$elEndDate
+ )
+ ||
+ $displayType=='detail' || $displayType=='calendar' || $displayType == 'mini'
+ ||
+ $elDirectional
+ )){
+
+ $oDetails['startdate_fstamp'] = $e['date'];
+ $oDetails['enddate_fstamp'] = $arrEventsDetail[$e['eventId']]['enddate'];
+
+ $oDetails['detailURL'] = $modx->makeUrl((!empty($ajaxResourceId) && (bool)$modalView === true ? $ajaxResourceId : $resourceId),'',array('detail' => $e['eventId'], 'r'=>$e['repeatId']));
+ $events[strftime('%Y-%m-%d', $e['date'])][] = $oDetails;
+ $ulimit++;
+ if($debug) $debugOutput .= $cnt.') '.$ulimit.'['.$limit.']) '.strftime($dateFormat,$e['date']).' '.$e['eventId'].'
';
+ if($ulimit >= $limit && $displayType=='list' ) break;
+ $cnt++;
+ }
+}
+$arrayEventTimer->end('arrEventDates');
+
+// Indexed array - in order to be used with list().
+return array($events,$debugOutput);
\ No newline at end of file
diff --git a/core/components/mxcalendars/elements/snippets/snippet.mxcalendars.php b/core/components/mxcalendars/elements/snippets/snippet.mxcalendars.php
deleted file mode 100644
index 8729a72..0000000
--- a/core/components/mxcalendars/elements/snippets/snippet.mxcalendars.php
+++ /dev/null
@@ -1,449 +0,0 @@
-getService('mxcalendars','mxCalendars',$modx->getOption('mxcalendars.core_path',null,$modx->getOption('core_path').'components/mxcalendars/').'model/mxcalendars/',$scriptProperties);
-if (!($mxcal instanceof mxCalendars)) return 'Error loading instance of mxCalendars.';
-
-include_once($modx->getOption('mxcalendars.core_path',null,$modx->getOption('core_path').'components/mxcalendars/').'processors/mgr/mxcHelper.php');
-
-/* setup default properties */
-$theme = $modx->getOption('theme',$scriptProperties,'default');// default, traditional
-$excludeCSS = $modx->getOption('excludeCSS', $scriptProperties, 0);
-$resourceId = $modx->getOption('resourceId', $scriptProperties, $modx->resource->get('id'));
-$isLocked = $modx->getOption('isLocked', $scriptProperties, 0);
-$displayType = isset($_REQUEST['detail']) && !$isLocked ? 'detail' : (isset($_REQUEST['displayType']) ? $_REQUEST['displayType'] : $modx->getOption('displayType', $scriptProperties, 'calendar')); //calendar,list,mini
-$eventid = !empty($_REQUEST['mxcid']) ? (int)$_REQUEST['mxcid'] : null;
-//++ Images properties
-$imageLimit = $modx->getOption('limit',$scriptProperties,'15');
-$imageDisable = $modx->getOption('imageDisable',$scriptProperties,0);
-//++ Results query properties
-$eventListStartDate = (isset($_REQUEST['elStartDate']) && !$isLocked ? $_REQUEST['elStartDate'] : $modx->getOption('elStartDate',$scriptProperties,'now'));
-$eventListEndDate = (isset($_REQUEST['elEndDate']) && !$isLocked ? $_REQUEST['elEndDate'] : $modx->getOption('elEndDate',$scriptProperties,'+1 year'));
-$elDirectional = $modx->getOption('elDirectional',$scriptProperties, false);
-$tplElItem = $modx->getOption('tplListItem',$scriptProperties,'el.itemclean');
-$tplElMonthHeading = $modx->getOption('tplListHeading',$scriptProperties,'el.listheading');
-$tplElWrap = $modx->getOption('tplListWrap',$scriptProperties,'el.wrap');
-$tplNoEvents = $modx->getOption('tplNoEvents',$scriptProperties,'el.noevents');
-$eventListLimit = $modx->getOption('eventListlimit',$scriptProperties,'5');
-$sort = $modx->getOption('mxc.sort',$scriptProperties,'startdate');
-$dir = $modx->getOption('mxc.dir',$scriptProperties,'ASC');
-$limit = $modx->getOption('limit',$scriptProperties,'99');
-$limitstart = $modx->getOption('limitstart', $scriptProperties, 0);
-//++ Text|Date Formatting properties
-$dateFormat = $modx->getOption('dateformat', $scriptProperties, '%Y-%m-%d');
-$timeFormat = $modx->getOption('timeformat', $scriptProperties, '%H:%M %p');
-$dateSeperator = $modx->getOption('dateseperator',$scriptProperties, '/');
-//++ Display: Calendar properties
-$activeMonthOnlyEvents = $modx->getOption('activeMonthOnlyEvents', $scriptProperties, 0);
-$highlightToday = $modx->getOption('highlightToday', $scriptProperties, 1);
-$todayClass = $modx->getOption('todayClass', $scriptProperties, 'today');
-$noEventsClass = $modx->getOption('noEventClass', $scriptProperties, 'mxcDayNoEvents');
-$hasEventsClass = $modx->getOption('hasEventsClass', $scriptProperties,'mxcEvents');
-$tplEvent = $modx->getOption('tplEvent',$scriptProperties,'month.inner.container.row.day.eventclean');
-$tplDay = $modx->getOption('tplDay',$scriptProperties,'month.inner.container.row.day');
-$tplWeek = $modx->getOption('tplWeek',$scriptProperties,'month.inner.container.row');
-$tplMonth = $modx->getOption('tplMonth',$scriptProperties,'month.inner.container');
-$tplHeading = $modx->getOption('tplHeading',$scriptProperties,'month.inner.container.row.heading');
-//++Display: Detail
-$tplDetail = $modx->getOption('tplDetail',$scriptProperties,'detail');
-$tplDetailModal = $modx->getOption('tplDetailModal', $scriptProperties, 'detail.modal');
-$tplImageItem = $modx->getOption('tplImageItem', $scriptProperties, 'image');
-$tplVideoItem = $modx->getOption('tplVideoItem', $scriptProperties, 'video');
-$mapWidth = $modx->getOption('mapWidth', $scriptProperties, '500px');
-$mapHeight = $modx->getOption('mapHeight', $scriptProperties, '500px');
-//++Display: Categories
-$showCategories = $modx->getOption('showCategories',$scriptProperties,1);
-$tplCategoryWrap = $modx->getOption('tplCategoryWrap',$scriptProperties,'category.container');
-$tplCategoryItem = $modx->getOption('tplCategoryItem',$scriptProperties,'category.container.item');
-$labelCategoryHeading = $modx->getOption('labelCategoryHeading',$scriptProperties,$mxcal->modx->lexicon('mxcalendars.label_category_heading'));
-//@TODO Possibly add to the properties set
-//++Aux Parameters: AJAX, Modal, etc.*
-$addJQ = $modx->getOption('addJQ', $scriptProperties,1); //-- jQuery is required for the core mxCalendar JS to function
-$jqLibSrc = $modx->getOption('jqLibSrc', $scriptProperties,'https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js');
-$usemxcLib = $modx->getOption('usemxcLib', $scriptProperties,1); //-- Use the stand-a-lone modal windows JS library packaged with mxCalendar
-$ajaxResourceId = $modx->getOption('ajaxResourceId', $scriptProperties, null);
-$ajaxMonthResourceId = $modx->getOption('ajaxMonthResourceId', $scriptProperties, null);
-$modalView = $modx->getOption('modalView', $scriptProperties,1);
-$modalSetWidth = $modx->getOption('modalSetWidth', $scriptProperties,null); //-- Ver > 0.0.3-beta
-$modalSetHeight =$modx->getOption('modalSetHeight', $scriptProperties,null); //-- Ver > 0.0.3-beta
-//@TODO Possibly add to the properties set
-//++Location Specific options for Google Maps v3.x
-$gmapLib = $modx->getOption('gmapLib', $scriptProperties, 'http://maps.google.com/maps/api/js?sensor=false');
-$gmapId = $modx->getOption('gmapId',$scriptProperties, 'map');
-$gmapDefaultZoom = $modx->getOption('gmapDefaultZoom', $scriptProperties, '13');
-$gmapAPIKey = $modx->getOption('gmapAPIKey', $scriptProperties, 'null');
-$gmapRegion = $modx->getOption('gmapRegion', $scriptProperties, '');
-//++ Holiday Support
-$holidays = $modx->getOption('holidays', $scriptProperties, "{'us':{''}}");
-$holidayDisplayEvents = $modx->getOption('holidayDisplayEvents', $scriptProperties, 1);
-//++ Used in very limited cases
-$setTimezone = $modx->getOption('setTimezone', $scriptProperties, null );
-$debugTimezone = $modx->getOption('debugTimezone', $scriptProperties, 0 );
-$debug = $modx->getOption('debug',$scriptProperties,0);
-//++ Set a feed processor timezone adjustment
-$setFeedTZ = $modx->getOption('setFeedTZ', $scriptProperties, null); // Example: FeedId=2; TargetTimeZone=New York; would result in => `{"2":"America/New_York"}`
-
-//++ Calendar Options (ver >= 1.1.6d-pr)
-$categoryFilter = urldecode(isset($_REQUEST['cid']) ? $_REQUEST['cid'] : $modx->getOption('categoryFilter', $scriptProperties, null)); //-- Defaults to show all categories
-//++ Calendar Options (ver >= 1.1.0-pl)
-$calendarFilter = isset($_REQUEST['calf']) ? $_REQUEST['calf'] : $modx->getOption('calendarFilter', $scriptProperties, null); //-- Defaults to show all calendars
-//++ Context Options (ver >= 1.1.0-pl)
-$contextFilter = isset($_REQUEST['conf']) ? $_REQUEST['conf'] : $modx->getOption('contextFilter',$scriptProperties, ','.$modx->context->key);//-- Defaults to current context + (blank for all)
-//++ Form Chunk Filter match name
-$formFilter = $modx->getOption('formFilter',$scriptProperties,'form_');
-
-//++ Caching Options
-$cacheEnable = $modx->getOption('cacheEnable',$scriptProperties,0);
-$cacheLifetime = $modx->getOption('cacheLifetime',$scriptProperties,null); //3600 would be one hour - and overrides the resource lifetime; leaving null inherits the resource cache lifetime settings
-if (empty($cacheKey)) $cacheKey = $modx->getOption('cache_resource_key', null, 'resource');
-if (empty($cacheHandler)) $cacheHandler = $modx->getOption('cache_resource_handler', null, $modx->getOption(xPDO::OPT_CACHE_HANDLER, null, 'xPDOFileCache'));
-if (!isset($cacheExpires)) $cacheExpires = $cacheLifetime!==null ? (integer)$cacheLifetime : (integer) $modx->getOption('cache_resource_expires', null, $modx->getOption(xPDO::OPT_CACHE_EXPIRES, null, 0));
-if (empty($cacheElementKey)) $cacheElementKey = $modx->resource->getCacheKey() . '/' . md5($modx->toJSON($properties) . implode('', $modx->request->getParameters()));
-$cacheOptions = array(xPDO::OPT_CACHE_KEY => $cacheKey,xPDO::OPT_CACHE_HANDLER => $cacheHandler,xPDO::OPT_CACHE_EXPIRES => $cacheExpires,);
-$results = $modx->cacheManager->get($cacheElementKey, $cacheOptions);
-
-
-//-- Update to the Timezone
- if(!empty($setTimezone)) $mxcal->setTimeZone($setTimezone,$debugTimezone);
-//-- Update to the Timezone: Manual fix to adjust timezone to match server settings examples.
-//date_default_timezone_set("Europe/Amsterdam");
-//date_default_timezone_set('America/New_York');
-
-// Process any needed Feeds as setup in mxCalendar Manager
-
- $feed = $modx->getObject('mxCalendarFeed', 10);
- if($feed){
- $feed->set('nextrunon', 0);
- $feed-save();
- }
-$mxcal->processFeeds($setFeedTZ);
-
-
-if($modx->resource->get('id') != $ajaxResourceId && $modx->resource->get('id') != $ajaxMonthResourceId) {
- //-- Add mxCalendar Theme CSS to html header (set in snippit properties)
- if($excludeCSS !== 1 && $excludeCSS !== '1'){
- $modx->regClientCSS($modx->getOption('mxcalendars.assets_url',null,$modx->getOption('assets_url').'components/mxcalendars/').'themes/'.$theme.'/css/mxcalendar.css');
- }
-
- //-- Add the Shadowbox library info if we are using modal
- if(($modalView == 'true' || $modalView == 1) && ($usemxcLib == 'true' || $usemxcLib == 1)) {
- $mxcal->addShadowBox($modalSetWidth,$modalSetHeight);
- } else { $mxcal->disableModal(); }
-
- //-- Add mxCalendar jQuery Library if enabled
- if($addJQ && $addJQ !== 'false'){
- $modx->regClientStartupScript($jqLibSrc);
- //-- Only add the required JS files we need
- if(!empty($ajaxResourceId) && $modx->resource->get('id') != $ajaxResourceId && $modx->resource->get('id') != $ajaxMonthResourceId)//-- Also requires a valid jQuery library be loaded
- $modx->regClientStartupScript($mxcal->config['assetsUrl'].'js/web/mxc-calendar.js');
- }
-}
-
-
-if(((int)$cacheEnable === 1 || $cacheEnable === '1') && !empty($results) && $debug !== 1)
- return $results;
-
-if($debug)
-var_dump($scriptProperties);
-
-$elStartDate = strtotime($eventListStartDate);
-if($elStartDate ===false){
- if($debug) echo 'Could not convert elStartDate value of "'.$elStartDate.'" to proper time stamp.
';
- $elStartDate = time();
-
-}
-$elEndDate = strtotime($eventListEndDate);
-if($elEndDate ===false){
- if($debug) echo 'Could not convert elEndDate value of "'.$elEndDate.'" to proper time stamp.
';
- $elEndDate = time();
-}
-
-
-//-- Setup varibles to hold the output
-$debugOutput = array();
-$arrEventsDetail = array();
-$arrEventDates=array();
-$output = '';
-
-$time_start = microtime(true);
-$mxcalendars = $modx->getCollection('mxCalendarEvents');
-if($debug) $output .= "
Total Events: ".count($mxcalendars);
-$whereArr = array();
-$eventsArr = array();
-
-$c = $modx->newQuery('mxCalendarEvents');
-$c->select(array(
- 'mxCalendarEvents.*',
-));
-// Create the where clause by display type to limit the returned records
-switch ($displayType){
- case 'list':
- case 'daily':
- case 'ical':
- case 'rss':
- $sort = 'startdate';
- if(is_integer($eventid) && $eventid !== null){
- $whereArr = array(array('mxCalendarEvents.id:='=>$eventid));
- } elseif (!$elDirectional) {
- $whereArr = array(array('repeating:=' => 0,'AND:enddate:>=' => $elStartDate,'AND:enddate:<=' => $elEndDate,array('OR:repeating:='=>1,'AND:repeatenddate:>=' => $elStartDate)) );
- } else {
- SWITCH($elDirectional){
- default:
- case 'f':
- case 'future':
- case 'forward':
- $whereArr = array(array('repeating:=' => 0,array('AND:enddate:>=' => $elStartDate,'OR:enddate:>=' => $elStartDate),array('OR:repeating:='=>1,'AND:repeatenddate:>=' => $elStartDate)) );
- break;
- case 'b':
- case 'p':
- case 'past':
- case 'backward':
- $whereArr = array(array('repeating:=' => 0,array('AND:enddate:<=' => $elStartDate,'OR:enddate:<=' => $elStartDate),array('OR:repeating:='=>1,'AND:repeatenddate:<=' => $elStartDate)) );
- break;
- }
- }
- break;
- case 'calendar':
- case 'mini':
- default:
- $dr = $mxcal->getEventCalendarDateRange($activeMonthOnlyEvents);
- $elStartDate = $dr['start'];
- $elEndDate = $dr['end'];
- $whereArr = array(array(
- 'repeating:=' => 0,
- 'AND:enddate:>=' => $elStartDate,
- 'AND:enddate:<=' => $elEndDate
- ,array('OR:repeating:='=>1,
- 'AND:repeatenddate:>=' => $elStartDate)
- ) );
- break;
- case 'year':
- break;
- case 'detail':
- $whereArr = array(array('id' => (int)$_REQUEST['detail']));
- //$whereArr[0]['AND:id:='] = (int)$_REQUEST['detail']; //@TODO Make filter for single events repeating dates
- break;
-}
-
-//-- ADD IN THE CONTEXT AND CALENDAR PROPERTY FILTERS
-$whereArr['AND:context:IN'] = explode(',',$contextFilter);
-if(!empty($calendarFilter))
- $whereArr['AND:calendar_id:IN'] = explode(',',$calendarFilter);
-
-
-if($categoryFilter && ($displayType == 'calendar' || $displayType == 'mini' || $displayType == 'list'))
- $whereArr[] = array(
- array('categoryid' => $categoryFilter),
- array('OR:categoryid:LIKE' => '%,'.$categoryFilter.',%'),
- array('OR:categoryid:LIKE' => '%,'.$categoryFilter),
- array('OR:categoryid:LIKE' => $categoryFilter.',%'),
- );
-
-$whereArr['mxCalendarEvents.active'] = 1;
-
-$c->where($whereArr);
-if($displayType != 'detail')
- $c->sortby($sort,$dir);
-$c->limit($limit,$limitstart);
-
-$c->prepare();
-if($debug) echo '
Filtering calendar date SQL range with: '.strftime('%m/%d/%Y', $elStartDate).' through '.strftime('%m/%d/%Y', $elEndDate).'
';
-if($debug) echo 'SQL: '.$c->toSql().'
';
-
-$queryTimer = new makeProcessTime($time_start,$debug);
-$mxcalendars = $modx->getCollection('mxCalendarEvents',$c);
-$queryTimer->end('mxCalendars Query');
-
-if($debug) echo "
Returned Events: ".count($mxcalendars).'
';
-
-
-$resultLoopTimer = new makeProcessTime($time_start,$debug);
-foreach ($mxcalendars as $mxc) {
- //-- Convert the object to an array
- $mxcArray = $mxc->toArray();
-
- $eStart = new DateTime(date('Y-m-d H:i:s',$mxc->get('startdate')));
- $eEnd = new DateTime(date('Y-m-d H:i:s',$mxc->get('enddate')));
-
- $durYear; $durMonth; $durDay; $durHour; $durMin; $durSec;
-
- if(version_compare(PHP_VERSION, '5.3.0') >= 0){
- $diff = $eStart->diff($eEnd);
- $durYear = $diff->format('%y');
- $durMonth = $diff->format('%m');
- $durDay = $diff->format('%d');
- $durHour = $diff->format('%h');
- $durMin = $diff->format('%i');
- $durSec = $diff->format('%s');
- } else {
- $diff = (object)$mxcal->datediff($mxc->get('startdate'),$mxc->get('enddate'),true);
- $durYear = $diff->years;
- $durMonth = $diff->months;
- $durDay = $diff->days;
- $durHour = $diff->hours;
- $durMin = $diff->minutes;
- $durSec = $diff->seconds;
- }
-
- //-- return event duration values
- $mxcArray['durYear'] = !empty($durYear) ? $durYear : null;
- $mxcArray['durMonth'] = !empty($durMonth) ? $durMonth : null;
- $mxcArray['durDay'] = !empty($durDay) ? $durDay : null;
- $mxcArray['durHour'] = !empty($durHour) ? $durHour : null;
- $mxcArray['durMin'] = !empty($durMin) ? $durMin : null;
- $mxcArray['durSec'] = !empty($durSec) ? $durSec : null;
- $mxcArray['mxcmodalClass'] = ($modalView && $ajaxResourceId || isset($_REQUEST['imajax']) ? 'mxcmodal' : '');
-
- $arrEventsDetail[$mxcArray['id']] = $mxcArray;
- $arrEventDates[$mxcArray['id']] = array('date'=>$mxcArray['startdate'], 'eventId'=>$mxcArray['id'],'repeatId'=>0);
-
- //-- If we have repeating dates and repeating is enabled lets add those to the array
- if($mxcArray['repeating'] && count(explode(',', $mxcArray['repeatdates']))){
- if($debug) echo 'Repeating Event: '.$mxcArray['title'].'
';
- if($debug) echo ' ++(0) '.strftime($dateFormat.' '.$timeFormat, $mxcArray['startdate']).'
';
- $rid = 1;
- foreach(explode(',',$mxcArray['repeatdates']) AS $rDate){
- $arrEventDates[$mxcArray['id'].'-'.$rid] = array('date'=>$rDate, 'eventId'=>$mxcArray['id'],'repeatId'=>$rid);
- if($debug) echo ' ++('.$rid.') '.strftime($dateFormat.' '.$timeFormat, $rDate).'
';
- $rid++;
- }
- }
-
- // Add date for each day in a multiple day event ( #127 )
- if($mxcArray['durDay'] !== null && $mxcArray['durDay'] >= 1){
- if($debug) echo 'Multiple Day Event: '.$mxcArray['title'].'
';
-
- /*
- $i = 1;
- $endDate = $mxc->get('enddate');
- while(strtotime('+'.$i.' day', $mxcArray['startdate']) < $endDate){
- $theSpanDate = strtotime('+'.$i.' day', $mxcArray['startdate']);
- $arrEventDates[$mxcArray['id'].'_'.$i] = array('date'=>$theSpanDate, 'eventId'=>$mxcArray['id'],'repeatId'=>null);
- if($debug) echo ' ++('.$i.') '.strftime($dateFormat.' '.$timeFormat, $theSpanDate).'
';
- $i++;
- }
- *
- */
-
- for($i = 1; $i<=$mxcArray['durDay']; $i++){
- $theSpanDate = strtotime('+'.$i.' day', $mxcArray['startdate']);
- $arrEventDates[$mxcArray['id'].'_'.$i] = array('date'=>$theSpanDate, 'eventId'=>$mxcArray['id'],'repeatId'=>null);
- if($debug) echo ' ++('.$i.') '.strftime($dateFormat.' '.$timeFormat, $theSpanDate).'
';
- }
-
- }
-
- //$output .= $mxcal->getChunk($tpl,$mxcArray);
-}
-$resultLoopTimer->end('mxc result set loop');
-
-
-// Obtain a list of columns
-$timer_5 = new makeProcessTime($time_start,$debug);
-foreach ($arrEventDates as $key => $row) {
- $date[$key] = $row['date'];
- $event[$key] = $row['eventId'];
-}
-$timer_5->end('generate list of all columns for sorting');
-
-// Sort the data with volume descending, edition ascending
-// Add $data as the last parameter, to sort by the common key
-if(count($arrEventDates) && $displayType == 'list'){
- $multiSortTimer = new makeProcessTime($time_start,$debug);
- if($dir == 'ASC')
- array_multisort($date, SORT_ASC, $event, SORT_ASC, $arrEventDates);
- else
- array_multisort($date, SORT_DESC, $event, SORT_DESC, $arrEventDates);
- $multiSortTimer->end('array_multisort');
-} else {
- //array_multisort($date, SORT_ASC, $event, SORT_ASC, $arrEventDates);
-}
-
-if(count($arrEventDates)){
- if($debug) echo 'Looping through events list of '.count($arrEventDates).' total.
';
- $ulimit=0;
-
- $arraEventTimer = new makeProcessTime($time_start,$debug);
-
- $cnt = 1;
- foreach($arrEventDates AS $k=>$e){
-
- $oDetails = $arrEventsDetail[$e['eventId']]; //Get original event (parent) details
- $oDetails['startdate'] = $e['date'];
- $oDetails['enddate'] = strtotime('+'.($arrEventsDetail[$e['eventId']]['durDay'] ? $arrEventsDetail[$e['eventId']]['durDay'].' days ' :'').($arrEventsDetail[$e['eventId']]['durHour'] ? $arrEventsDetail[$e['eventId']]['durHour'].' hour ' :'').($arrEventsDetail[$e['eventId']]['durMin'] ? $arrEventsDetail[$e['eventId']]['durMin'].' minute' :''), $e['date']);//$e['date'];//repeatenddate
- if((
- (
- ($oDetails['startdate']>=$elStartDate || $oDetails['enddate'] >= $elStartDate) &&
- $oDetails['enddate']<=$elEndDate
- )
- ||
- $displayType=='detail' || $displayType=='calendar' || $displayType == 'mini'
- ||
- $elDirectional
- )){
-
-
- $oDetails['startdate_fstamp'] = $e['date'];
- $oDetails['enddate_fstamp'] = $arrEventsDetail[$e['eventId']]['enddate'];
-
- $oDetails['detailURL'] = $modx->makeUrl((!empty($ajaxResourceId) && (bool)$modalView === true ? $ajaxResourceId : $resourceId),'',array('detail' => $e['eventId'], 'r'=>$e['repeatId']));
- $eventsArr[strftime('%Y-%m-%d', $e['date'])][] = $oDetails;
- $ulimit++;
- if($debug) echo $cnt.') '.$ulimit.'['.$limit.']) '.strftime($dateFormat,$e['date']).' '.$e['eventId'].'
';
- if($ulimit >= $limit && $displayType=='list' ) break;
- $cnt++;
- }
- }
-
- $arraEventTimer->end('arrEventDates');
-
-} else {
- if($debug) echo 'No valid dates returned.';
-}
-
-$modx->setPlaceholders(array('dateseperator'=>$dateSeperator));
-
-//----- NOW GET THE DISPLAY TYPE ------//
-switch ($displayType){
- case 'list':
- case 'daily':
- case 'ical':
- case 'rss':
- $output = $mxcal->makeEventList($eventListLimit, $eventsArr, array('tplElItem'=>$tplElItem, 'tplElMonthHeading'=>$tplElMonthHeading, 'tplElWrap'=>$tplElWrap, 'tplImage'=>$tplImageItem, 'tplVideo'=>$tplVIdeoItem, 'tplNoEvents'=>$tplNoEvents),$elStartDate,$elEndDate);
- break;
- case 'calendar':
- case 'mini':
- default:
- $timer_10 = new makeProcessTime($time_start,$debug);
- $output = $mxcal->makeEventCalendar($eventsArr,(!empty($ajaxResourceId) && $modalView? $ajaxResourceId : $resourceId),(!empty( $ajaxMonthResourceId) ? $ajaxMonthResourceId : (!empty($ajaxResourceId) ? $ajaxResourceId : $resourceId) ),array('event'=>$tplEvent,'day'=>$tplDay,'week'=>$tplWeek,'month'=>$tplMonth,'heading'=>$tplHeading, 'tplImage'=>$tplImageItem, 'tplVideo'=>$tplVIdeoItem), $contextFilter, $calendarFilter, $highlightToday);
- $timer_10->end('UI Rendering');
- break;
- case 'year':
- break;
- case 'detail':
- if($debug) $output .= 'Total Occurances: '.count($eventsArr).' for Event ID: '.$_REQUEST['detail'].'
';
- if(isset($resourceId) && $modx->resource->get('id') != $resourceId)
- $tplDetail = $tplDetailModal;
- $output .= $mxcal->makeEventDetail($eventsArr,($occurance=$_REQUEST['r']?$_REQUEST['r']:0) , array('tplDetail'=>$tplDetail, 'tplImage'=>$tplImageItem, 'tplVideo'=>$tplVIdeoItem),$mapWidth,$mapHeight,$gmapRegion);
- //$whereArr[0]['AND:id:='] = (int)$_REQUEST['detail']; //@TODO Make filter for single events repeating dates
- break;
-}
-
-//-- Always allow the category list placeholder to be set
-if($showCategories == true)
- $modx->setPlaceholder('categories', $mxcal->makeCategoryList($labelCategoryHeading, ($_REQUEST['cid'] ? $_REQUEST['cid'] : null),$resourceId, array('tplCategoryWrap'=>$tplCategoryWrap, 'tplCategoryItem'=>$tplCategoryItem)));
-
-$mxcal->restoreTimeZone($debugTimezone);
-$time_end = microtime(true);
-$time = $time_end - $time_start;
-if($debug) echo "
mxCalendar processed in $time seconds
\n";
-
-
-$modx->cacheManager->set($cacheElementKey, $output, $cacheExpires, $cacheOptions);
-
-return $output;
\ No newline at end of file
diff --git a/core/components/mxcalendars/elements/snippets/snippet.mxcalendarsort.php b/core/components/mxcalendars/elements/snippets/snippet.mxcalendarsort.php
new file mode 100644
index 0000000..9839074
--- /dev/null
+++ b/core/components/mxcalendars/elements/snippets/snippet.mxcalendarsort.php
@@ -0,0 +1,45 @@
+runSnippet('mxCalendarInit', $scriptProperties);
+
+$debugOutput = '';
+$debug = $modx->getOption('debug', $scriptProperties);
+$events = $modx->getOption('events', $scriptProperties, array());
+// @todo Review Default value is not applied - have to intialize as array explicitly.
+$events = !empty($events) ? $events : array();
+if (empty($events)) {
+ $debugOutput .= "No data to sort.\n";
+}
+$direction = $modx->getOption('direction', $scriptProperties, 'ASC');
+
+// Obtain a list of columns
+$timer_5 = new makeProcessTime(null,$debug);
+$date = array();
+$event = array();
+foreach ($events as $key => $row) {
+ $date[$key] = $row['date'];
+ $event[$key] = $row['eventId'];
+}
+$timer_5->end('generate list of all columns for sorting');
+// Sort the data with volume descending, edition ascending
+// Add $data as the last parameter, to sort by the common key
+$multiSortTimer = new makeProcessTime(null,$debug);
+$dir = ($direction == 'DESC') ? SORT_DESC : SORT_ASC;
+array_multisort($date, $dir, $event, $dir, $events);
+$multiSortTimer->end('array_multisort');
+
+// Indexed array - in order to be used with list().
+return array($events,$debugOutput);
\ No newline at end of file