DTSTART is not an object'.$event['DTSTART']);
return (false); /* it is set, but it is not an aobject ? */ }
}
else { /* possibly an undated, non repeating VTODO or Vjournal- no repeating to be done if no DTSTART, and no RDATE */
$dt = '-nodtstart';
if (!isset($event['RDATE'])) {
if (isset ($event['UID']))
$newevents[$event['UID']] = $event;
else
amr_tell_admin_the_error('There is an invalid event. It has no UID:'.print_r($event,true));
return ($newevents); /* possibly an undated, non repeating VTODO or Vjournal- no repeating to be done if no DTSTART, and no RDATE */
}
else {
echo ('This event is invalid. It has no DTSTART, but does have RDATE. Not allowed according to ical spec.');
return(false);
/***check for repeating RDATEs if no start date */
}
}
/* To handle modifications, use a key to the events, so can match any later mods with a repeating event we may have generated */
$seq = empty($event['SEQUENCE']) ? '0' : $event['SEQUENCE']; /* begin setting up the event key that will help us check for modifications - semingly duplicates!*/
if (!isset($event['UID'])) $event['UID'] = 'NoUID';
/* there is no repeating rule, so just copy over */
if (isset ($event['RECURRENCE-ID'])) { /* a modification or exceptions to a repeating instance ? */
// $recdate = $dt;
if (isset ($_GET['debugexc'])) {echo '
RECURRENCE-ID:'; var_dump($event['RECURRENCE-ID']);}
if (is_array($event['RECURRENCE-ID'])) { /* just take first, should only be one */
$recdateobj = $event['RECURRENCE-ID'][0];
$recdate = $recdateobj->format('YmdHis'); // purely identifies specifc instances of a repeating rule are affected by the exception/modification
//20140721 - lost the month in ymd somehow - added back
if (isset ($_GET['debugexc'])) {echo '
Flag recurrence modification for '.$recdate; }
}
else if (is_object($event['RECURRENCE-ID'])) { /* Then it is a date instance which has been modified . We need to overwrite the appropriate repeating dates. This is done later? *** */
$recdateobj = $event['RECURRENCE-ID'];
$recdate = $recdateobj->format('YmdHis');
if (isset ($_GET['debugexc'])) {echo '
RecurrenceID date to check against event rrule.' ;echo($recdate);}
}
else { /**** should deal with THISANDFUTURE or THISANDPRIOR EG:
RECURRENCE-ID;RANGE=THISANDPRIOR:19980401T133000Z */
echo '
THISAND.... modification to repeating event encountered. This cannot be dealt with yet'; var_dump($event['RECURRENCE-ID']);
}
if ( amr_event_should_be_shown($event,$astart, $aend) or
amr_falls_between($recdateobj, $astart, $aend) or /* If the modification relates to an event instance (ie date) that is in range */
amr_is_same_day ($recdateobj, $astart) or /* if on same day, may be an all day event - will constrain finally later */
amr_is_same_day ($recdateobj, $aend)
) /* OR the new date is in our display range, */{
$key = $event['UID'].' '.$recdate.' '.$seq.'999'; /* By virtue of being a recurrence id it should override a non recurrence (ie normal) even if they have the same sequence */
$newevents[$key] = $event; /* so we drop the old events used to generate the repeats */
$newevents[$key]['EventDate'] = new Datetime(); //if cloning dont need tz
$newevents[$key]['EventDate'] = clone $dtstart;
if (!(amr_create_enddate($newevents[$key]))) {if (ICAL_EVENTS_DEBUG) echo ' ** No end date - is it an alarm? ';};
}
else {
if (isset ($_GET['debugexc'])) {
echo '
'.$recdate.' not in range and '.$dtstart->format('c').' not in range' ;
// debug_print_event ($event);
}
return(false); /* the modification and the instance that it relates to are not in our date range */
}
}
else { /* It is not a recurrence id, may be a repeating, or solo */
if (isset($dtstart) ) {
if ( amr_is_before ($dtstart, $aend) ) { /* If the start is after our end limit, then skip this event */
//var_dump($event);
if (isset($event['RRULE']) or (isset($event['RDATE']))) {
/* if have, must use dtstart in case we are dependent on it's characteristics,. We can exclude too early dates later on */
$repeats = amr_repeat_anevent($event, $astart, $aend, $limit ); /**** try for a more efficient start? */
if (isset($_GET['rdebug']) or ICAL_EVENTS_DEBUG) {
if (count($repeats) > 0) echo '
Create repeats: '.count($repeats);
}
/* now need to convert back to a full event by copying the event data for each repeat */
if (is_array($repeats) and (count($repeats) > 0)) {
foreach ($repeats as $i => $r) {
$repkey = $event['UID'].' '.$r->format('YmdHis').' '.$seq; /* Don't use timezone - some recurrence id's maybe created with universal dates */
if (isset ($newevents[$repkey])) {
// error_log('Unexpected Duplication of Repeating Event '.$repkey.' - error in ical file or error in plugin?'); // only happened on weird rrule - may be valid anyway so as not to miss anything
}
$newevents[$repkey] = $event; // copy the event data over - note objects will point to same object unless we clone Use duration or new /clone Enddate
$newevents[$repkey]['EventDate'] = new Datetime(); //if cloning dont need tz
$newevents[$repkey]['EventDate'] = clone $r;
// if (ICAL_EVENTS_DEBUG) {echo '
Created '.$newevents[$repkey]['EventDate']->format('YmdHis l'); }
if (!amr_create_enddate($newevents[$repkey])) {
if (ICAL_EVENTS_DEBUG) echo ' ** No end date created, maybe just a start? ';
};
}
}
}
else {
$key = $event['UID'].' '.$dt.' '.$seq; /* No Recurrence id and no RRULE or RDATE */
$newevents[$key] = $event; // copy the event data over - note objects will point to same object - is this an issue? Use duration or new /clone Enddate
$newevents[$key]['EventDate'] = new Datetime(); //if cloning dont need tz
$newevents[$key]['EventDate'] = clone $dtstart;
if (isset ($newevents[$key]['DURATION'] )) {
amr_create_enddate ($newevents[$key]); //changed because EndDate not same as DTEND if all day
}
}
}
}
else { // no starting date
$key = $event['UID'].' '.$dt.' '.$seq;
$newevents[$key] = $event;
$newevents[$key]['EventDate'] = '';
}
}
if (ICAL_EVENTS_DEBUG) {echo '
number of newevents = '.count($newevents);}
return ($newevents);
}
/*
* Constrain the list of COMPONENTS to those which fall between the
* specified start and end time, up to the specified number of
* events.
* Note; MUST take RECURRENCE -ID if the recurrence date is in range (even though the DTSTART may not be), as they may be modifying a date that is within the range
*/
function amr_constrain_components($events, $start, $end, $limit) {
global $amr_limits;
$newevents = $events;
/* should we be moving to destination date */
if ((count($newevents) < 1) or (!is_array($newevents)))
return (false);
$newevents = apply_filters('amr_events_before_sort', $newevents); // used for example to exclude private events
$newevents = amr_sort_by_key($newevents , 'EventDate');
$newevents = apply_filters('amr_events_after_sort', $newevents);
if (isset($_GET["debug"])) {
//var_dump($newevents);
echo '
Sorted '.count($newevents).' events';
echo '
first '.$newevents[0]['EventDate']->format('c');
echo '
last '.$newevents[count($newevents)-1]['EventDate']->format('c');
echo '
start '.$start->format('c');
echo '
end '.$end->format('c');
echo '
Now constrain them...
';
}
$constrained = array();
$count = 0;
foreach ($newevents as $k => $event) {
//
if (isset ($event['EventDate']) and (is_object ($event['EventDate']))) {
if (amr_falls_between($event['EventDate'], $start, $end) OR
(isset($event['EndDate']) and
(amr_falls_between($event['EndDate'], $start, $end) OR /* end date will catch those all day ones that are untimed or those that h ave not yet finished !! */
(amr_falls_between($start, $event['EventDate'], $event['EndDate'])))) ) /* catch those that start before our start and end after our start */
{
$constrained[] = $event;
if (isset($_GET['debugall'])) {
echo '
Choosing no: '.$k.' '. $event['EventDate']->format('c').' ending '. (isset($event['EndDate'])? $event['EndDate']->format('c'): ' no end'); }
++$count;
}
if (isset($_GET['debugall'])) {
echo '
Not choosing?'.$k.' '
. $event['EventDate']->format('c').' ending '
. (isset($event['EndDate'])? $event['EndDate']->format('c'): ' no end');
}
}
else {
$constrained[] = $event;
if (isset($_GET['debugall'])) {
echo '
Whats happening?'; var_dump( $event);
}
}
if ($count >= $limit) break;
}
if (isset($amr_limits['eventsoffset']) and (!empty($amr_limits['eventsoffset']))) {
if (function_exists('amr_do_events_offset')) {
$constrained = amr_do_events_offset ($constrained);
}
}
//if (ICAL_EVENTS_DEBUG) {echo '
Constrained =';var_dump($constrained);}
$constrained = apply_filters('amr_events_after_sort_and_constrain', $constrained);
return $constrained;
}
/*
* generate repeating events down to nonrepeating events at the corresponding repeat time.
For ease of processing the repeat arrays will initially be ISO 8601 date (added in PHP 5) eg: 2004-02-12T15:19:21+00:00
we will then convert them to date time objects
*/
function amr_process_icalevents($events, $l_start, $aend, $limit) {
$astart = amr_newdatetime(); // l_start was getting overwritten somewhere which messed up recurring logic
$astart = clone $l_start;
$dates = array();
//echo'
Check gen repeats '; var_dump($events);
foreach ($events as $i=> $event) {
amr_derive_dates ($event); /* basic clean up only - removing unnecessary arrays etc */
$more = amr_generate_repeats($event, $astart, $aend, $limit);
if (ICAL_EVENTS_DEBUG) {echo '
'.$i.' number of more events = '.count($more);}
if (is_array($more))
$dates = array_merge ($dates,$more) ;
if (ICAL_EVENTS_DEBUG) {echo '
number of dates = '.count($dates);}
//amrical_mem_debug('before unset '.$i);
//unset($more);
//amrical_mem_debug('After event '.$i);
}
if (ICAL_EVENTS_DEBUG) {echo '
No.Dates= '.count($dates); } //
if ((is_array($dates)) and (count($dates) > 1)) { /* must be > 1 for tere to be a duplicate! */
amr_arrayobj_unique2($dates); /* remove any duplicate in the values , check UID and Seq. This may arise if we have many VEVENTS relating to one event */
//if (ICAL_EVENTS_DEBUG) { echo '
Now have '.count($dates). ' after duplicates check.';}
}
return ($dates) ;
}
function process_icalurl($url) {
global $amr_limits;
/* cache the url if necessary, and then parse it into basic nested structure */
amrical_mem_debug('Before Process ical url');
$file = amr_cache_url(str_ireplace('webcal://', 'http://',$url),$amr_limits['cache']);
if (!($file)) {
echo '
'.sprintf(__('Unable to load or cache ical calendar %s','amr-ical-events-list'),$url);
return false;
}
amrical_mem_debug('Before parse ical url');
$ical = amr_parse_ical($file);
if (! (is_array($ical) )) {
echo '!';
return($ical);
}
$ical['icsurl'] = $url;
return ($ical);
}
function amr_echo_parameters() {
global $amr_limits;
foreach ($amr_limits as $i=> $v) {
if (!(in_array($i, array('cache',
'eventscache',
'pagination',
'headings',
'show_views',
'calendar_properties',
'show_month_nav',
'day_links',
'eventpoststoo') ))) {
$label = __($i,'amr-ical-events-list').' = ';
if (is_object($v)) $t[] = $label.$v->format('j M i:s');
else if (!empty($v)) $t[] = $label.$v;
}
}
$text = implode (', ',$t);
return ($text);
}
function amr_string($s) {
/* Maybe check for a calendar name and if it exists, then use it for styling? - NOt NOW */
return(str_replace(array (' ','.','-',',','"',"'"), '', $s));
}
function suggest_other_icalplugin($featuretext) {
?>
$v) {
if (!empty($v)) {
if (is_object($v))
$string .= ' '.$i.'='.$v->format('Ymd:H');
else {
if (is_array($v)) $string .= ' '.$i.'='.implode($v);
else $string .= ' '.$i.'='.$v;
}
}
}
if (isset($_GET['debugcache'])) echo '
string for key of cache =
'.$string.'';
$key = md5( $string );
return ($key);
}
function amr_GET_cached_events_from_db($criteria) { //NLR ?
global $amr_limits;
if (version_compare(5.3, PHP_VERSION, '>')) {
if (isset($_GET['debugcache']))echo 'NB: No event transient caching possible yet because objects do not serialise properly in php < 5.3';
return(false);
}
else return (false) ; /* until we upgrade ourselves and can test properly - icdsoft do not have yet */
if (isset($_GET['debugcache'])) echo 'Trying cache =
';
//---- build the key
$key = amr_GET_events_cache_key($criteria);
// ----now see if we have a cache
$cache = get_transient('amr_events');
if ( is_array($cache) && isset( $cache[ $key ] ) ) {
if (isset($_GET['debugcache'])) echo ('
we got an events cache with key '.$key);
// var_dump($cache[ $key ]); die('let see');
return ( $cache[$key] );
}
else {
if (isset($_GET['debugcache'])) echo ('No events cached - requery
');
return false;
}
}
function amr_set_cached_events_from_db($criteria, $events) { //NLR?
global $amr_options; /*** nb when we get back to this -when hosts are on 5.3 or for some other reason, fetch in hours eventscache */
global $amr_limits;
//---- build the key
$key = amr_GET_events_cache_key($criteria);
if (isset($_GET['debugcache'])) echo 'Setting cache with key = '.$key.'
';
// ----now see if we have a cache
$cache = get_transient('amr_events');
$cache[$key] = $events;
set_transient('amr_events', $cache, 60*20); /* save transient for 20 mins */
if (isset($_GET['debugcache'])) echo ('cache set '.$key.'
');
return true;
}
function amr_process_icalspec($criteria, $l_start, $end, $no_events, $icalno=0) {
/* parameters - an array of urls, an array of limits (actually in amr_limits) */
global $amr_options,
$amr_limits,
$amr_listtype,
$amrW,
$amrtotalevents,
$change_view_allowed,
$amr_doing_icallist, /* use to prevent the eventinfo shortcode echoing data to the screen when in ical event list mode */
$amr_one_page_events_cache; /* if widget and calendar doing same thing */
$amr_doing_icallist = true;
if (!empty($amrW))
$w = 'w'; /* so we know if we are in the widget or not */
else
$w = '';
if (!empty($criteria['show_in_events_timezone'])) // if we want event timezones, not website timezone
add_filter ('amr_show_in_events_timezone', 'amr_show_in_events_timezone', 10, 2);
if (!empty($criteria['exclude_in_progress']))
add_filter ('amr_events_after_sort_and_constrain', 'amr_events_exclude_in_progress');
if (!empty($criteria['sort_later_events_first']))
add_filter ('amr_events_after_sort_and_constrain', 'amr_events_sort_later_events_first');
$icals = false;
if ((isset($amr_limits['eventpoststoo'])) and ($amr_limits['eventpoststoo'])) {
if (function_exists('amr_ical_from_posts')) {
$events = amr_ical_from_posts($criteria);
if (!empty($events)) {
$icals = amr_make_ical_from_posts($events, $criteria);
if (ICAL_EVENTS_DEBUG) {
echo '
Got calendars from posts :'.count($icals).' events='.count($events).'
';
}
}
else {
if (ICAL_EVENTS_DEBUG) { echo '
No events found with this criteria
';
}
}
}
else {
if (ICAL_EVENTS_DEBUG) { echo '
Function amr_ical_from_posts not found
'; }
if (empty($criteria['urls'])) {
suggest_other_icalplugin (__('No url entered - did you want events from posts ?','amr-ical-events-list' ));
}
//else _e("huh?");
}
}
else if (ICAL_EVENTS_DEBUG) echo '
Ignore events posts ';
/* ------------------------------ check for urls and do those too, or only */
$icals2 = array();
if (!empty($criteria['urls'])) {
foreach ($criteria['urls'] as $i => $url) {
$icals2[$i] = process_icalurl($url);
if (!(is_array($icals2[$i])))
unset ($icals2[$i]);
else if (function_exists('amr_mimic_taxonomies'))
$icals2[$i] = amr_mimic_taxonomies ($icals2[$i]) ; // filter by category_name
}
}
if (!empty($icals) ) { // we got some events
if (!empty($icals2) )
$icals = array_merge($icals, $icals2 );
}
else
if (!empty($icals2) ) {
$icals = $icals2; // we got no events from posts, just from ics
}
/* ------------------------------now we have potentially a bunch of calendars in the ical array, each with properties and items */
/* Merge then constrain by options */
$components = array(); /* all components actually, not just events */
if (isset ($icals) and is_array($icals)) { /* if we have some parsed data */
foreach ($icals as $j => $ical) { /* for each Ics file within an ICal spec*/
if ((!isset($amr_options['listtypes'][$amr_listtype]['component'])) or (count($amr_options['listtypes'][$amr_listtype]['component']) < 1))
_e('No ical components requested for display','amr-ical-events-list');
else {
foreach ($amr_options['listtypes'][$amr_listtype]['component'] as $i => $c) { /* for each component type requested */
if ($c) { /* If this component was requested, merge the items from Ical items into events */
if (!empty($ical[$i]) and is_array($ical[$i])) { /* Eg: if we have an array $ical['VEVENT'] etc*/
foreach ($ical[$i] as $k => $a) { /* save the component type so we can style accordingly */
$ical[$i][$k]['type'] = $i;
$ical[$i][$k]['name'] = 'cal'.$j; /* save the name for styling */
}
if (!empty($components) ) {
$components = array_merge ($components, $ical[$i]);
}
else
$components = $ical[$i];
}
}
}
}
}
If (ICAL_EVENTS_DEBUG) echo '
Got x events '.count($components);
amrical_mem_debug('Before process');
$components = amr_process_icalevents($components, $l_start, $end, $no_events);
amrical_mem_debug('Before constrain');
$amrtotalevents = count($components);
$components = amr_constrain_components($components, $l_start, $end, $no_events);
$amr_last_date_time = amr_save_last_event_date($components);
If (ICAL_EVENTS_DEBUG) {
echo '
After constrain No dates:'.count($components).' and last event date time is: ';
if (is_object($amr_last_date_time)) echo $amr_last_date_time->format('c');
//var_dump($amr_last_date_time);
}
}
amrical_mem_debug('Before listing');
if (isset ($icals) and is_array($icals)) {
/* amr here is the main html code *** */
if (isset($amr_limits['calendar_properties']) )
$do_prop = $amr_limits['calendar_properties'];
else
$do_prop = true;
if ($do_prop) {
$tid = $w.'calprop'.$icalno;
$class = 'vcalendar '.$w.'icalprop '; //20110222
$thecal = amr_list_properties ($icals, $tid, $class); /* list the calendar properties if requested */
}
else $thecal = '';
if ((!amr_doing_box_calendar())
and empty($components) ) {
$thecal .= amr_handle_no_events ();
}
else {
$tid = '';
$class = ' ical ';
$thecal .= amr_list_events($components, $tid, $class, $show_views=true);
}
}
else $thecal = ''; /* the urls were not valid or some other error ocurred, for this spec, we have nothing to print */
/* amr end of core calling code --- */
if (!empty($amr_options['do_grouping_js']) ) {
$thecal .= amr_ical_load_frontend_scripts();
}
amrical_mem_debug('After generating listing');
return ($thecal);
}
function amr_save_last_event_date($events) { // must have been sorted
global $amr_last_date_time;
if (is_array($events)) {
$lastevent = end($events);
if (!empty($lastevent['EventDate'])) {
$amr_last_date_time = $lastevent['EventDate'];
return $amr_last_date_time;
}
else {
if (ICAL_EVENTS_DEBUG) { echo ' No last date time in:'; var_dump($lastevent);}
}
}
else {
if (ICAL_EVENTS_DEBUG) { echo ' Events not an array'; var_dump($events);}
}
// else will not save a last date.
}
function amr_GET_params ($attributes=array()) {
/* We are passed the widget or shortcode attributes,
check them, get what we can there, then check for passed parameters (form or query string )
Anything unset we will get from the default settings for that listtype.
The defaults list type is 1.
then set the amr_limits (note the calendar options may overwrite these)
*/
global $amr_limits, /* has days, events, start ? end ?*/
$amr_listtype,
$amr_liststyle,
$amr_options,
$amr_groupings,
$amr_fields_needed ,
$amr_event_columns, // 20151018 add so we can use easily
$amr_formats,
$amr_globaltz,
$change_view_allowed,
$amr_calendar_url,
$amrW; // indicates if widget,
$amr_options = amr_GETset_options();
//
$defaults = array( /* defaults array for shortcode , - these override limits if they exist in limit, */
'listtype' => $amr_listtype,
'startoffset' => '',
'hoursoffset' => '',
'monthsoffset' => '',
'daysoffset'=> '',
'start' => '', /* date('Ymd'), */
'days' => '',
'events' => '',
'months' => '', /* if we have months, start at begin of month and ignore days? */
'hours' => '',
'weeks' => '',
'tz' => '',
'eventpoststoo' => '1',
'agenda' => '',
'calendar' => '',
'eventmap' => '0',
'show_views' => '1',
'show_month_nav' => '0',
'show_look_more' => '0',
'day_links' => '1',
'month_year_dropdown' => '0',
'month_prev_next' => '0',
'calendar_properties' => '1',
'pagination' => '1',
'headings' => '1',
'ignore_query' => '',
'grouping' => '',
'more_url' => '',
'no_filters' => '0',
'sort_later_events_first' => '0',
'exclude_in_progress' => '0'
);
$shortcode_params = shortcode_atts( $defaults, $attributes ) ;
//
if (!empty ($attributes) ) { // if there is stuff left - must be urls
foreach ($attributes as $i => $v) {
if (is_numeric ($i) or ($i == 'ics')) { // ie if it is a value passed with no name, we expect only urls like that
if (substr($v, 0 ,1) == ':') { /* attempt to maintain old filter compatibity */
$shortcode_params['urls'][$i] = substr ($v, 1);
}
$v2 = (str_ireplace('webcal://', 'http://',$v)); //keep the webcal
if ((function_exists('filter_var')) and (!filter_var($v2, FILTER_VALIDATE_URL))) { /* rejecting a valid URL on php 5.2.14 */
echo ''.sprintf(__('Invalid Ical URL %s','amr-ical-events-list'), $v2).'
';
if (current_user_can('administrator')) {
echo 'Notes to admin only (does not show if not logged in as admin):
- If you have put [ical in the widget - take it out!
- the php validation functon does not cope with internationalised domain, please contact the developer if this affects you.
';
}
}
else
$shortcode_params['urls'][$i] = esc_url_raw($v);
unset ($attributes[$i]);
}
} // end foreach
} //end if
// handle taxonomies we do not even know about yet
/* get the parameters we want out of the attributes, supplying defaults for anything missing */
/* but now we may have missed taxonomies etc as the defaults do not know about them, so get the diff */
if (!empty($attributes)) {
//var_dump($attributes);
//var_dump($shortcode_params); // - this could be multi-d array due to urls so array diff will throw a notice in php 5.4
// maybe extract somehow ourselves? or use array_diff_key instead /****
$taxo_selection = array_diff_key($attributes,$shortcode_params);
}
// if we had some taxos, marge them into shortcode selection
if (!empty($taxo_selection))
$shortcode_params = array_merge ($shortcode_params,$taxo_selection );
$allow_query = (!isset($shortcode_params['ignore_query']) or !($shortcode_params['ignore_query']) );
$ignore_query_all = (isset($shortcode_params['ignore_query']) and ($shortcode_params['ignore_query'] == 'all') );
unset ($shortcode_params['ignore_query']);
if ($allow_query) {
//
parse_str($_SERVER['QUERY_STRING'], $queryargs); /* Get anything passed in the query string that will override shortcodes */
// check for posted values to get around that pesky problem
if (isset($_GET['start'])) $queryargs['start'] = $_GET['start'];
foreach ($queryargs as $i=>$arg) {
$queryargs[$i] = filter_var($arg, FILTER_SANITIZE_STRING); //Strip tags,
}
if ($change_view_allowed) { // for upcoming events widget, may want to allow query of days etc, but not the listtype change
if (isset($queryargs['calendar']))
$queryargs['listtype'] = $queryargs['calendar'];
if (isset($queryargs['agenda']) )
$queryargs['listtype'] = $queryargs['agenda'];
}
unset($queryargs['page_id']);
unset($queryargs['debug']);
If (isset($_GET['debugq'])) {echo '
Query allowed, attributes/args to consider adding:
'; var_dump($queryargs); }
$shortcode_params = array_merge ($shortcode_params, $queryargs);
/* If the input arrays have the same string keys, then the later value for that key will overwrite the previous one.
If, however, the arrays contain numeric keys, the later value will not overwrite the original value, but will be appended.
*/
// if (ICAL_EVENTS_DEBUG) {echo '
After merge with query args
'; var_dump($shortcode_params); }
//unset($queryargs['listtype']);
}
else if (isset($_GET['debugq'])) {echo '
Ignoring most query parameters ';}
//
// save the global list type first
if (!empty($shortcode_params['listtype'])) {
$amr_listtype = $shortcode_params['listtype'];
unset($shortcode_params['listtype']);
}
// unset($attributes['listtype']);
if ($change_view_allowed and $allow_query) { // then we will NOT ignore these query parameters as that will break our navigation
//if (ICAL_EVENTS_DEBUG) {echo '
Allowed to change views';}
if (isset($_GET['listtype']))
$amr_listtype = intval ( $_GET['listtype']);
if (isset($_GET['eventmap']))
$amr_listtype = 'eventmap'; // havent figured this out yet
}
// check the listtype here ?
if (empty($amr_options['listtypes'][$amr_listtype])) {
if (current_user_can('administrator') ) {
echo (sprintf(__('System error - event list type %s missing - please inform administrator.', 'amr-ical-events-list'),$amr_listtype));
_e('Now using an available list type to list events','amr-ical-events-list');
}
$amr_listtype = amr_first_available_listtype ();
}
$amr_liststyle = (isset ($amr_options['listtypes'][$amr_listtype]['general']['ListHTMLStyle']))
? $amr_options['listtypes'][$amr_listtype]['general']['ListHTMLStyle']
: $amr_liststyle = 'table';//; 'list'
if (!empty ($shortcode_params['more_url']) ) {
$amr_calendar_url = esc_url($shortcode_params['more_url']);
unset($shortcode_params['more_url']);
}
// always respond to start
// if (in_array ($amr_liststyle, array('smallcalendar','largecalendar', 'weekscalendar'))) {
// then query args overeride even if we have ignore query
if (!$ignore_query_all) {
if (isset($_GET['start']))
$queryargs['start'] = $_GET['start']; //need here too
if (!empty($queryargs['start'])) {
$shortcode_params['start'] = abs ((int) $queryargs['start']);
if (ICAL_EVENTS_DEBUG) {echo '
START = '.$shortcode_params['start'];}
// $shortcode_params['start'] = (substr((string) $shortcode_params['start'],0,6).'01'); //set to month start - done in month shortcdoe?
}
if (!empty($queryargs['months']))
$shortcode_params['months'] = abs( (int) $queryargs['months']);
if (!empty($queryargs['tz']))
$shortcode_params['tz'] = filter_var($queryargs['tz'],FILTER_SANITIZE_STRING);
}
else if (isset($_GET['debugall'])) echo '
** Ignoring all query parameters';
//----------------------------------------------------------------------------------------------------------------- now do thelimits array
// then get the limits for that list type
$amr_limits = $amr_options['listtypes'][$amr_listtype]['limit']; /* get the default limits */
if ($amr_liststyle === 'weekscalendar') {
$amr_limits['weeks'] = 2; // default for horizontal calendar
}
if (($amr_liststyle === 'largecalendar') or $amr_liststyle === 'smallcalendar') {
if (empty($amr_limits['months'])) $amr_limits['months'] = 1; // default for horizontal calendar
}
// now check groupings
$gg = '';
if (!empty($shortcode_params['grouping']))
$gg = ucwords($shortcode_params['grouping']);
unset($shortcode_params['grouping']);
if (!empty($_GET['grouping']))
$gg = ucwords($_GET['grouping']);
if (!($gg == '')) {
unset($amr_options['listtypes'][$amr_listtype]['grouping']);
if (array_key_exists($gg,$amr_groupings)) { // if it is a valid grouping
$amr_options['listtypes'][$amr_listtype]['grouping'][$gg] = true;
unset ($shortcode_params['grouping']);
}
}
if (!empty ($shortcode_params ) ) {
foreach ($shortcode_params as $i => $v) { // must be atts not limits as atts may hold more then limits - limits just has initial limits
if (in_array($i, array(
'headings',
'show_views',
'agenda',
'eventmap',
'calendar',
'eventpoststoo',
'pagination',
'calendar_properties',
'no_filters',
'show_month_nav',
'show_look_more',
'day_links',
'more_url',
'month_year_dropdown',
'month_prev_next'
) )) {
$amr_limits[$i] = abs (intval ( $v));
unset($shortcode_params[$i]); // only unset if empty what??? - else will lose others
}
else {
if (in_array($i, array('days','events','months','listtype','hours', 'weeks'
,'daysoffset', 'startoffset', 'hoursoffset','monthsoffset'))) {
if (!empty($v))
$amr_limits[$i] = (int)$v ; // can be negative, so no abs
unset($shortcode_params[$i]);
}
}
}
if (!empty($amr_limits['listtype'])) {
$amr_listtype = $amr_limits['listtype'];
if (ICAL_EVENTS_DEBUG) echo '
listtype set to: ';
}
}
// else might be a taxonomy or categeory etc ... pass through - not if we have filtered string
/* ----check if we want to overwrite the wordpress timezone */
if (!(empty($shortcode_params['tz']))) // allows one to overwrite the timezone
$amr_globaltz = timezone_open ($shortcode_params['tz']);
unset ($shortcode_params['preview']); //clear it out so we do not pass to wp query
unset ($shortcode_params['tz']); //clear it out so we do not pass to wp query
If (isset($_GET['tzdebug'])) {
echo 'Plugin/Wordpress Timezone:'.timezone_name_GET($amr_globaltz);
echo ', current offset is '.$amr_globaltz->getOffset(date_create('now',$amr_globaltz))/(60*60).'
';
}
//-------------------------------
$pos_int_options = array("options"=> array("min_range"=>1, "max_range"=>1000));
$neg_int_options = array("options"=> array("min_range"=>-1000, "max_range"=>1000));
/* check non url parameters */
if (empty ($shortcode_params['start'])) {
$amr_limits['start'] = date_create('now',$amr_globaltz);
}
else {
$amr_limits['start'] = abs((int) $shortcode_params['start']);
}
unset ($shortcode_params['start']); // clear it out so we do not pass it to wp query
// work out whether we are doing a calendar or not. calendars must still respond to at least the month navigation
foreach ($amr_limits as $i => $a) { // create our date objects
if (($i === 'start') or ($i === 'end')) {
if (!(is_object($a))) {
$dateok = checkdate(substr($a,4,2), /* month */
substr($a,6,2), /* day*/
substr($a,0,4));/* year */
if ($dateok) {
$amr_limits[$i] = date_create($a,$amr_globaltz);
if (!is_object($amr_limits[$i])) {
amr_tell_error ($i.' '
.__('Date could not be converted to date object.', 'amr-ical-events-list')
.__('Check date and global timezone.', 'amr-ical-events-list')
);
var_dump($amr_limits[$i]);
var_dump($amr_globaltz);
}
}
else {
_e('Invalid Start Date', 'amr-ical-events-list');
echo '
'.$i.' '.$a;
$amr_limits[$i] = date_create('now',$amr_globaltz);
}
}
/* else all is okay - we have default date of now */
}
}
if (!empty( $shortcode_params['daysoffset'])) { /* keeping startoffset for old version compatibility, but allowing for daysoffset for compatibility with other offsets */
$amr_limits['startoffset'] = (int) $shortcode_params['daysoffset']; // can be negative
}
/* ---- check for urls that are either passed by query or form, or are in the shortcode with a number or not ie: not ics = */
//set up global for easier access
$amr_formats = $amr_options['listtypes'][$amr_listtype]['format'];
// now adjust our start dta if necessary
if (!empty($amr_limits['startoffset'])) {
$daysoffset = (int)($amr_limits['startoffset']);
if ($daysoffset > 0) $daysoffset = '+'.(string)$daysoffset.' days';
else $daysoffset = (string)$daysoffset.' days';
date_modify($amr_limits['start'],$daysoffset) ;
}
//
if (!empty($amr_limits['hoursoffset'])) {
$hrsoffset = (int)($amr_limits['hoursoffset']);
if ($hrsoffset > 0) $hrsoffset = '+'.(string)$hrsoffset.' hours';
else $hrsoffset = (string)$hrsoffset.' hours';
date_modify($amr_limits['start'],$hrsoffset) ; /*** as per request from jd */
}
//
if (!empty($amr_limits['monthsoffset'])) {
$mthsoffset = (int)($amr_limits['monthsoffset']);
if ($mthsoffset >= 0) $mthsoffset = '+'.(string)$mthsoffset.' months';
else $mthsoffset = (string)$mthsoffset.' months';
date_modify($amr_limits['start'],$mthsoffset) ;
}
//
if (!empty($amr_limits['hours'])) { /* then set the time to the beginning of the day , and get rid of months and days */
date_time_set ($amr_limits['start'],$amr_limits['start']->format('G'),0,0); /* set the time to beginning of the hour */
unset ($amr_limits['days']);
unset ($amr_limits['months']);
}
if (!empty($amr_limits['months'])) {/* then set the date to the beginning of the month and get rid of days */
$days = (int) $amr_limits['start']->format('d');
if ($days > 1) $amr_limits['start']->modify('-'.($days-1).' days');
date_time_set ($amr_limits['start'],0,0,0);
unset ($amr_limits['days']);
}
//
if (empty($amr_limits['hours'])) {/* else use the days and then set the time to the beginning of the day */
date_time_set ($amr_limits['start'],0,0,0);
}
$wkst = ical_GET_weekstart(); // get the wp start of week
if (isset($_GET['debugwks'])) echo '
wkst = '.$wkst;
if (!empty($amr_limits['weeks'])) { // weeks overrides all else
$amr_limits['start'] = amr_GET_human_start_of_week ($amr_limits['start'], $wkst); /* set to start of week */
$amr_limits['days'] = $amr_limits['weeks'] * 7;
unset ($amr_limits['hours']);
if (isset($_GET['debugwks'])) { echo '
Start set to = '.$amr_limits['start']->format('c');}
}
// now find our end date - may get overridden if calendar
if (is_object($amr_limits['start'])) {
$amr_limits['end'] = new Datetime(); //if cloning dont need tz
$amr_limits['end'] = clone $amr_limits['start'];
}
else { // something horribly wrong here
amr_tell_eror (__('Error: Start data of range is not a date object. Please advise administrator','amr-ical-events-list'));
var_dump($amr_limits['start']);
}
if (!empty($amr_limits['months']))
date_modify($amr_limits['end'],'+'.($amr_limits['months']).' months') ;
if (!empty($amr_limits['days']))
date_modify($amr_limits['end'],'+'.($amr_limits['days']).' days') ;
if (!empty($amr_limits['hours']))
date_modify($amr_limits['end'],'+'.($amr_limits['hours']).' hours') ;
else date_modify($amr_limits['end'],'-1 second') ; /* so that we do not include events starting in the next time period */
if (isset($_GET['debug'])) echo '
end = '.$amr_limits['end']->format('c');
// date_time_set ($amr_limits['end'],23,59,59); // if we have this, do we need the -1 second below?
If (isset($_GET['debugq'])) {
echo '
Before passing others
';
var_dump($shortcode_params);
echo amr_echo_parameters();
}
$amr_event_columns = prepare_order_and_sequence ($amr_options['listtypes'][$amr_listtype]['compprop']); //do once earlier
$amr_fields_needed = amr_extract_fields($amr_event_columns); // setup global
return ($shortcode_params); // only return params needed for wp query ?
}
function amr_GET_id_for_shortcode () { // allows for the possibility of multiple shortcodes in one page.
global $amr_icalno;
if (!(isset($amr_icalno))) $amr_icalno = 0;
else $amr_icalno= $amr_icalno + 1;
if ($amr_icalno == 0) $idnum= '';
else $idnum = $amr_icalno;
$id = ' id="events_wrap'.$idnum.'" ';
return ($id);
}
function amr_do_ical_shortcode ($attributes, $content = null) {
global $amr_limits,
$change_view_allowed,
$amr_ical_am_doing;/* used to give each ical table a unique id on a page or post */
// This is the main function. It replaces [iCal URL]'s with events. Each as a separate list
/* Allow multiple urls and only one listtype */
/* merge atts with this array, so we will have a default list */
global $amr_been_here;
/* Test because if some numbskull puts the ical or events shortcodes IN an event.
*/
if (amr_a_nested_event_shortcode ()) return (false); //someone entered an event shortcode into event content - causing a loop of events lists inside event lists
$change_view_allowed = true;
$amr_ical_am_doing = 'list';
$defaults['listtype'] = 1;
$defaults['eventpoststoo'] = '0';
$defaults['show_views'] = 0;
$defaults['show_month_nav'] = 0;
$defaults['headings'] = 0;
if (empty($attributes))
$atts = $defaults;
else
$atts = array_merge( $defaults, $attributes ) ;
$criteria = amr_GET_params ($atts); /* strip out and set any other attstributes - they will set the limits table */
/* separate out the other possible variables like list type, then just have the urls */
$content = amr_process_icalspec(
$criteria,
$amr_limits['start'],
$amr_limits['end'],
$amr_limits['events']);
$id = amr_GET_id_for_shortcode();
$html = ''.$content.'
';
/* we made it out the other end with out looping ?*/
$amr_been_here = false;
return ($html);
}
function amr_do_smallcal_shortcode ($attributes) {
global $amr_limits,
$amr_listtype,
$change_view_allowed,
$amr_icalno,
$amr_ical_am_doing,
$amr_been_here;
// treat as widget anyway to avoid view changes etc
// This is the main function. It replaces [iCal URL]'s with events. Each as a separate list if no listtype set it to 8
/* Allow multiple urls and only one listtype */
/* merge atts with this array, so we will have a default list */
$change_view_allowed = true;
$amr_ical_am_doing = 'smallcalendar';
// set defaults, can be overridden by shortcode parameters
$defaults['listtype'] = 8;
$defaults['months'] = 1;
$defaults['show_views'] = 0;
$defaults['ignore_query'] = 0;
if (amr_a_nested_event_shortcode ()) return (false); //someone entered an event shortcode into event content - causing a loop of events lists inside event lists
if (empty($attributes)) $attributes = array();
$atts = array_merge( $defaults, $attributes ) ;
$criteria = amr_GET_params ($atts); /* strip out and set any other attstributes - they will set the limits table */
// remove the custom post type parameter as it will cause us to lose all others and just show 1 event
/* separate out the other possible variables like list type, then just have the urls */
$id = amr_GET_id_for_shortcode(); // need this to increment icalno
$content = amr_process_icalspec(
$criteria,
$amr_limits['start'],
$amr_limits['end'],
$amr_limits['events'],
$amr_icalno);
$change_view_allowed = true; // reset the global
if (isset ($amr_limits['months']) and ($amr_limits['months'] > 1))
$id = ' id="multismallcalendar" ';
$html = ''.$content.'
';
/* we made it out the other end with out looping ?*/
$amr_been_here = false;
return ($html);
}
function amr_do_largecal_shortcode ($attributes, $content = null) {
global $amr_limits,
$amr_listtype,
$change_view_allowed,
$amr_ical_am_doing,
$amr_icalno,
$amr_been_here;
;/* used to give each ical table a unique id on a page or post */
// This is the main function. It replaces [iCal URL]'s with events. Each as a separate list if no listtype set it to 8
/* Allow multiple urls and only one listtype */
/* merge atts with this array, so we will have a default list */
if (amr_a_nested_event_shortcode ()) return (false); //someone entered an event shortcode into event content - causing a loop of events lists inside event lists
$change_view_allowed = true;
$amr_ical_am_doing = 'largecalendar';
$defaults['listtype'] = 9;
$defaults['months'] = 1;
$defaults['show_month_nav'] = 1; // default is on in calendar
if (empty($attributes)) $atts = $defaults;
else $atts = array_merge( $defaults, $attributes ) ;
$criteria = amr_GET_params ($atts); /* strip out and set any other attstributes - they will set the limits table */
/* criteria will be any selection */
/* separate out the other possible variables like list type, then just have the urls */
$id = amr_GET_id_for_shortcode(); // need this to increment icalno
$content = amr_process_icalspec($criteria,
$amr_limits['start'],
$amr_limits['end'],
$amr_limits['events'],
$amr_icalno);
$html = ''.$content.'
';
/* we made it out the other end with out looping ?*/
$amr_been_here = false;
return ($html);
}
function amr_do_weekscal_shortcode ($attributes, $content = null) {
global $amr_limits,
$amr_listtype,
$change_view_allowed,
$amr_ical_am_doing,
$amr_icalno,
$amr_been_here;/* used to give each ical table a unique id on a page or post */
// This is the main function. It replaces [iCal URL]'s with events. Each as a separate list if no listtype set it to 8
/* Allow multiple urls and only one listtype */
/* merge atts with this array, so we will have a default list */
if (amr_a_nested_event_shortcode ()) return (false); //someone entered an event shortcode into event content - causing a loop of events lists inside event lists
$change_view_allowed = true;
$amr_ical_am_doing = 'weekscalendar';
$defaults['listtype'] = 11;
$defaults['weeks'] = 2;
$defaults['months'] = 0;
$defaults['days'] = 14;
$defaults['show_month_nav'] = 1; // will actually do weeks
$defaults['show_views'] = '';
if (empty($attributes))
$atts = $defaults;
else
$atts = array_merge( $defaults, $attributes ) ;
$criteria = amr_GET_params ($atts); /* strip out and set any other attstributes - they will set the limits table */
/* criteria will be any selection */
/* separate out the other possible variables like list type, then just have the urls */
$id = amr_GET_id_for_shortcode(); // need this to increment icalno
$content = amr_process_icalspec($criteria,
$amr_limits['start'],
$amr_limits['end'],
$amr_limits['events'],
$amr_icalno);
$html = ''.$content.'
';
/* we made it out the other end with out looping ?*/
$amr_been_here = false;
return ($html);
}
function amr_first_available_listtype() {
global $amr_options;
if (isset ($amr_options['listtypes']['4']))
return('4'); // use the widget list type if still there as least offensive general purpose list type
$keys = array_keys($amr_options['listtypes']);
return (array_shift($keys));
}
function amr_GET_set_start_for_nav () { // gets or sets a date object to the begiinging of the curremt month, or the passed date
if (isset($_GET['start'])) {
$starttxt = intval ($_GET['start']);
$starttxt = substr($starttxt,0,4).'-'.substr($starttxt,4,2).'-'.substr($starttxt,6,2);
$nstart = amr_newDateTime($starttxt);
}
else {
$nstart = amr_newDateTime(''); // must always set to first of month for dropdown to work
$y = $nstart->format('Y');
$m = $nstart->format('m');
$nstart->setDate($y,$m,'01');
}
return ($nstart);
}
/*
/* --------------------------------------------------------------------- */
function amr_ical_widget_init() {
register_widget('amr_ical_widget');
register_widget('amr_icalendar_widget');
}
function amrical_add_scripts() {
wp_enqueue_script('jquery');
wp_enqueue_script('jquery-ui-core');
}
function amrical_add_adminstyle() {
if ((stristr ($_SERVER['QUERY_STRING'],'manage_amr_ical'))
or (stristr ($_SERVER['QUERY_STRING'],'manage_event_listing'))) {
$myStyleUrl = ICALLISTPLUGINURL.'css/icaladmin.css';
$myStyleFile = ICALLISTPLUGINDIR.'css/icaladmin.css';
if ( file_exists($myStyleFile) ) {
wp_register_style('amricaladmin', $myStyleUrl);
wp_enqueue_style( 'amricaladmin');
}
}
}
function amr_ical_exception_handler($exception) {
echo __("Uncaught exception: ", 'amr-ical-events-list') , $exception->getMessage(), "\n";
_e('
An error in the input data may prevent correct display of this page. Please advise the administrator as soon as possible.', 'amr-ical-events-list');
}
function amr_notice_listtypes_converted () { // from version < 4.0 to version 4.0
echo (''
.__('Your existing saved list types have been converted. If you wish to return to the earlier version of the plugin, you will have to reset the list types and reapply your changes. Or use your DB backup to set the amr-ical-events-list option back to previous version. You do have regular backups right? ','amr-ical-events-list').'
');
echo '
';
}
function amr_ical_include_scripts() { // only load js if requested
global $amr_listtype,$amr_options,$amr_doing_icallist;
// csss required for widgets etc, so allow general load
if (empty($amr_doing_icallist)) return;
if (empty($amr_options['do_grouping_js'])) return;
$url = plugins_url().'/amr-ical-events-list/js/amr-ical.js';
// wp_register_script( 'amr-ical', $url.'amr-ical.js', array( 'jquery'), false, false);
wp_enqueue_script( 'amr-ical', $url, array( 'jquery'), false, true); // true for in footer
}
function amr_ical_load_frontend_scripts() { // only load js if requested
// csss required for widgets etc, so allow general load
wp_enqueue_script('jquery');
// later amr_ical_load_date_picker();
}
/**
Adds a links directly to the settings page from the plugin page
*/
function amr_plugin_links($links, $file) {
if ( $file == 'amr-ical-events-list/amr-ical-events-list.php' ) {
$links[] = ''
. __('Settings', 'amr-ical-events-list') . "";
$links[] = "" . __('List Type Settings', 'amr-ical-events-list') . "";
$links[] = "" . __('Documentation', 'amr-ical-events-list') . "";
}
return $links;
} // end plugin_links()
function amr_exclude_private_events($events) { // may later want to change this to show if owner is logged in?
foreach ($events as $i => $event) {
if (!empty($event['CLASS']) and (
(($event['CLASS'] ==='PRIVATE') or $event['CLASS'] ==='CONFIDENTIAL') )) {
unset ($events[$i]);
if (ICAL_EVENTS_DEBUG) echo '
Private event excluded';
}
}
return ($events);
}
//201703 remove - it is interfering with php 7 exception handling. We had this for a reason - will painful support go up? We actually only want this if we are running in the ics file handler and there is crap data that has suddenly appeared in the input file - tough ?
//set_exception_handler('amr_ical_exception_handler');
//amr_ical_initialise (); // setup all basic settings, like globals and constants etc
add_action('plugins_loaded' , 'amr_ical_initialise' ); // so can check debug
if (is_admin() ) {
add_action('admin_init' , 'amrical_add_adminstyle');
add_action('admin_menu' , 'amrical_add_options_panel');
add_action('admin_print_scripts', 'amrical_add_scripts');
}
else { // add_action('wp_head' , 'amr_ical_events_style');
add_action('wp_print_styles' , 'amr_ical_events_style');
add_action('wp_enqueue_scripts' , 'amr_ical_load_frontend_scripts' ); //enque jquery
add_action('wp_footer' , 'amr_ical_include_scripts' ); // add js to footer
}
add_action('widgets_init' , 'amr_ical_widget_init');
// as per ottos post for language packs
//add_action( 'init' , 'amr_ical_load_text' );
add_shortcode('iCal' , 'amr_do_ical_shortcode');
add_shortcode('ical' , 'amr_do_ical_shortcode'); // in case people make mistake
add_shortcode('smallcalendar' , 'amr_do_smallcal_shortcode');
add_shortcode('largecalendar' , 'amr_do_largecal_shortcode');
add_shortcode('weekscalendar' , 'amr_do_weekscal_shortcode');
add_shortcode('expandall' , 'amr_expand_all');
register_activation_hook(__FILE__, 'amr_ical_events_list_record_version');
add_filter('plugin_row_meta', 'amr_plugin_links', 10, 2);
add_filter('amr_events_before_sort', 'amr_exclude_private_events',10,1);
//add_action('plugins_loaded', 'amr_debug_time'); // removed for now - 'only' a debug function wrt to load times and somehow functionnotfound in mutisite.
?>