+// This script grabs the events from zwift.com/events and makes them available in ical form so you can use them in your calendar
+// Disclaimer: This is script created for myself to use in my calendar, and is NOT supported or related to Zwift in any way
+ private $url = "http://zwift.com/json/events";
+ private $cachefile = "cache.txt";
+ private $cachetime = "600";
+ private $output = FALSE;
+ header('Content-type: text/calendar; charset=utf-8');
+ header('Content-Disposition: attachment; filename=zwift_events.ics');
+ // Try to get the data from cache
+ $this->output = $this->get_cache();
+ // No data, query zwift
+ if($this->output === FALSE){
+ $data = $this->get_data_from_zwift();
+ $this->create_output($data);
+ throw new Exception("Sorry, I wasn't able to grab the latest data from Zwift");
+ $this->set_cache($this->output);
+ // Print everything and exit
+ function create_output($data){
+ $data = json_decode($data);
+ throw new Exception("Retrieved data incorrect");
+ $this->output = $this->header();
+ foreach($data as $id => $event){
+ $this->output .= $this->event($event);
+ $this->output .= $this->footer();
+ if(!file_exists($this->cachefile)){
+ file_put_contents($this->cachefile, "");
+ $cache = file_get_contents($this->cachefile);
+ // If the file is empty
+ if(strlen($cache) < 100){
+ // if it is modified longer than given time ago
+ if((filemtime($this->cachefile) + $this->cachetime) < time()){
+ function set_cache($data){
+ file_put_contents($this->cachefile, $data);
+ function get_data_from_zwift(){
+ return file_get_contents($this->url);
+ function dateToCal($timestamp) {
+ return date('Ymd\THis\Z', $timestamp);
+ function escapeString($string) {
+ $string = str_replace("\n", "\\n", $string);
+ return preg_replace('/([\,;])/','\\\$1', $string);
+ return "BEGIN:VCALENDAR\n" .
+ "PRODID:-//onlinephpfunctions.com//zwift 1.0//EN\n";
+ function event($event){
+ return "BEGIN:VEVENT" .
+ "\nDESCRIPTION:" . $this->escapeString($event->description) .
+ "\nDTEND:" . $this->dateToCal($event->start + $event->durationInSeconds) .
+ "\nDTSTAMP:" . $this->dateToCal($event->start) .
+ "\nDTSTART:" . $this->dateToCal($event->start) .
+ "\nLOCATION:" . $this->escapeString($event->route) .
+ "\nSUMMARY:" . $this->escapeString($event->name) . // Go to Zwift.com/events for full details" // . $this->escapeString($event->description) . "
+ return "\nEND:VCALENDAR\n";
+$zwift_events = new zwift_ics();