public function get_google_calendar_link($event_id = false)
 {
     // via http://stackoverflow.com/a/21653600/1119655
     if (!$event_id) {
         $event = get_post();
     } else {
         $event = get_post($event_id);
     }
     if (!is_object($event) || $event->post_type != 'sc_event') {
         return;
     }
     $event_date = sc_get_event_date($event->ID);
     $event_time = sc_get_event_time($event->ID);
     $event_description = apply_filters('sc_ical_event_description', $event->post_content, $event);
     $event_description = apply_filters('sc_google_calendar_event_description', $event_description, $event);
     $event_description = sc_html2plain($event_description);
     $args = array('event_name' => get_the_title($event->ID), 'start_date' => $event_date . ' ' . $event_time['start'], 'end_date' => $event_date . ' ' . $event_time['end'], 'details' => $event_description, 'location' => '');
     if (function_exists('sc_get_event_address')) {
         if ($address = sc_get_event_address($event->ID, ', ')) {
             $args['location'] = $address;
         }
     }
     $args = apply_filters('sc_google_calendar_link_data', $args, $event);
     // Convert the time to the weird Google Calendar time format
     $start_date = date('Y-m-d H:i:s', strtotime($args['start_date']));
     $end_date = date('Y-m-d H:i:s', strtotime($args['end_date']));
     $date = $this->get_google_calendar_time_format($start_date, $end_date);
     unset($args['start_date']);
     unset($args['end_date']);
     $args['dates'] = $date;
     $args['text'] = $args['event_name'];
     unset($args['event_name']);
     $args = array_map('trim', $args);
     $args = array_map('urlencode', $args);
     // Google Calendar links require these paramters
     $args['action'] = 'TEMPLATE';
     $args['sf'] = 'true';
     $args['output'] = 'xml';
     $link = add_query_arg($args, 'https://www.google.com/calendar/render');
     return $link;
 }
 public function ical_feed()
 {
     global $wp_query;
     if (!have_posts()) {
         $wp_query->set_404();
         $wp_query->max_num_pages = 0;
         header('Content-Type: text/html; charset=' . get_option('blog_charset'), true);
         locate_template('404.php', true);
         die;
     }
     $display_format = '';
     if (isset($_GET['format'])) {
         $display_format = strtolower($_GET['format']);
     }
     if ($display_format == 'xml') {
         nocache_headers();
         header('Content-Type: text/xml; charset=' . get_option('blog_charset'), true);
     }
     if ($display_format == 'json') {
         nocache_headers();
         header('Content-Type: application/json; charset=' . get_option('blog_charset'), true);
     }
     //TODO: Add filters for these things
     $calendar_name = get_bloginfo('name') . ' Events';
     $calendar_description = 'Events found on ' . get_site_url();
     $timezone = get_option('timezone_string');
     // define time zone
     $args = array('unique_id' => get_site_url(), 'TZID' => $timezone);
     $v = new vcalendar($args);
     // create a new calendar instance
     $v->setProperty('method', 'PUBLISH');
     // required of some calendar software
     $v->setProperty('x-wr-calname', $calendar_name);
     // required of some calendar software
     $v->setProperty('X-WR-CALDESC', $calendar_description);
     // required of some calendar software
     $v->setProperty('X-WR-TIMEZONE', $timezone);
     // required of some calendar software
     $xprops = array('X-LIC-LOCATION' => $timezone);
     // required of some calendar software
     iCalUtilityFunctions::createTimezone($v, $timezone, $xprops);
     // create timezone component(-s) opt. 1 based on present date
     while (have_posts()) {
         the_post();
         $event_id = get_the_ID();
         $event = get_post($event_id);
         $event_date = sc_get_event_date($event_id);
         $event_time = sc_get_event_time($event_id);
         $event_start = strtotime($event_date . ' ' . $event_time['start']);
         $event_end = strtotime($event_date . ' ' . $event_time['end']);
         $event_location = '';
         if (function_exists('sc_get_event_address')) {
             $event_location = sc_get_event_address();
         }
         $event_description = apply_filters('sc_ical_event_description', get_the_content(), $event);
         $event_description = sc_html2plain($event_description);
         $vevent =& $v->newComponent('vevent');
         // create an event calendar component
         $start = array('year' => date('Y', $event_start), 'month' => date('n', $event_start), 'day' => date('j', $event_start), 'hour' => date('G', $event_start), 'min' => date('i', $event_start), 'sec' => date('s', $event_start));
         $vevent->setProperty('dtstart', $start);
         $end = array('year' => date('Y', $event_end), 'month' => date('n', $event_end), 'day' => date('j', $event_end), 'hour' => date('G', $event_end), 'min' => date('i', $event_end), 'sec' => date('s', $event_end));
         $vevent->setProperty('dtend', $end);
         $vevent->setProperty('LOCATION', $event_location);
         // property name - case independent
         if (function_exists('sc_get_the_organizer')) {
             $organizer_details = sc_get_the_organizer($event_id);
             $organizer_details = array_filter($organizer_details);
             if (isset($organizer_details['name']) && isset($organizer_details['email'])) {
                 $organizer_args = array('CN' => $organizer_details['name']);
                 $x_params = array('Phone', 'Website');
                 foreach ($x_params as $param) {
                     $lowercase_param = strtolower($param);
                     if (isset($organizer_details[$lowercase_param])) {
                         $arg_key = 'X-' . $param;
                         $val = $organizer_details[$lowercase_param];
                         $organizer_args[$arg_key] = $val;
                     }
                 }
                 $vevent->setProperty('organizer', $organizer_details['email'], $organizer_args);
             }
         }
         $vevent->setProperty('summary', $event->post_title);
         $vevent->setProperty('description', $event_description);
     }
     // all calendar components are described in rfc5545
     // a complete method list in iCalcreator manual
     iCalUtilityFunctions::createTimezone($v, $timezone, $xprops);
     // create timezone component(-s) opt. 2
     // based on all start dates in events (i.e. dtstart)
     if ($display_format == 'xml') {
         echo iCal2XML($v);
         exit;
     }
     if ($display_format == 'json') {
         $xml = simplexml_load_string(iCal2XML($v));
         echo json_encode($xml);
         exit;
     }
     $v->returnCalendar();
     // redirect calendar file to browser
     exit;
 }