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