option_name); } public function enqueue_assets() { // Enqueue FullCalendar JS and CSS from plugin folder (ensure these files exist) wp_enqueue_script( 'fwp-calendar-fullcalendar-js', plugins_url('fullcalendar.min.js', __FILE__), [], '6.1.8', true ); wp_enqueue_script( 'fwp-calendar-js', plugins_url('calendar.js', __FILE__), ['fwp-calendar-fullcalendar-js'], false, true ); } public function settings_page() { ?>

Free WordPress Calendar Settings

option_name, []); if (!is_array($urls)) { $urls = array_filter(array_map('trim', explode("\n", $urls))); } ?>
iCal URLs
$url): ?>
'', 'show_upcoming' => 'true', ], $atts); $show_upcoming = filter_var($atts['show_upcoming'], FILTER_VALIDATE_BOOLEAN); $urls = get_option($this->option_name, []); if (!is_array($urls)) $urls = []; if ($atts['id'] !== '') { $key = intval($atts['id']) - 1; if (isset($urls[$key])) { $urls = [$urls[$key]]; } else { return '

Invalid calendar ID.

'; } } $events = []; foreach ($urls as $url) { $url = trim($url); $ics_content = @file_get_contents(trim($url)); if (!$ics_content) { error_log("FWP Calendar: Failed to fetch ICS from $url"); continue; } try { $parser = new ICal(); $parser->initString($ics_content); // <-- This is the fix } catch (Exception $e) { error_log('FWP Calendar: Failed to parse ICS: ' . $e->getMessage()); continue; } foreach ($parser->events() as $event) { $start_ts = method_exists($parser, 'iCalDateToTimestamp') ? $parser->iCalDateToTimestamp($event->dtstart) : strtotime($event->dtstart); $end_ts = isset($event->dtend) ? (method_exists($parser, 'iCalDateToTimestamp') ? $parser->iCalDateToTimestamp($event->dtend) : strtotime($event->dtend)) : $start_ts; $events[] = [ 'title' => $event->summary ?? 'No Title', 'start' => date('c', $start_ts), 'end' => date('c', $end_ts), 'url' => $event->url ?? '', ]; } } ob_start(); ?>
'; echo '

Upcoming Events

'; } return ob_get_clean(); } } new FWP_Calendar();