Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
PHP to fetch a calendar from iCloud with authentication and CalDAV
<?php
// get this data by logging into icloud.com on the calendars page and looking at the dev tools
// as per https://translate.google.com/translate?sl=de&tl=en&js=y&prev=_t&hl=de&ie=UTF-8&u=http%3A%2F%2Fnico-beuermann.de%2Fblogging%2Farchives%2F115-Zugriff-auf-iCloud-Kalender-mit-Thunderbird.html&edit-text=&act=url
$account = array(
'server' => '', // note, this will be p12 or something, not P0; see the server that iclod.com serves json from
'icloudid' => '', // the "dsid"
'appleid' => '', // your Apple ID; will be an email address
'pass' => '', // password for your Apple ID
'calid' => '' // the "pGuid"
);
$url = 'https://' . $account['server'] . '-caldav.icloud.com/' .
$account['icloudid']. '/calendars/' . $account['calid'] . '/';
$headers = array(
'Content-Type: text/xml',
'Depth: 1'
);
$body = "<propfind xmlns='DAV:'><prop><calendar-data xmlns='urn:ietf:params:xml:ns:caldav'/></prop></propfind>";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_USERPWD, $account["appleid"] . ":" . $account["pass"]);
curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
curl_setopt($ch, CURLOPT_USERAGENT, 'curl/7.35.0');
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PROPFIND");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$data = curl_exec($ch);
curl_close($ch);
// suppress warnings because PHP < 5.3 complains about not being able to parse xmlns DAV
@$xml = simplexml_load_string($data);
$events = array();
$timezone = null;
$header = "BEGIN:VCALENDAR\nCALSCALE:GREGORIAN\nPRODID:-//Apple Inc.//iOS 9.1//EN\nVERSION:2.0";
$footer = "END:VCALENDAR\n";
// combine all the separate iCal files into one big iCal file
foreach($xml->response as $response) {
foreach($response->propstat as $propstat) {
$caldata = $propstat->prop->{'calendar-data'};
if (strlen($caldata) == 0) { continue; }
$accum_timezone = array();
$in_timezone = false;
$accum_event = array();
$in_event = false;
foreach(explode("\n", $caldata) as $line) {
if ($line == "BEGIN:VTIMEZONE" && is_null($timezone)) { $in_timezone = true; }
if ($line == "BEGIN:VEVENT") { $in_event = true; }
if ($in_timezone) { $accum_timezone[] = $line; }
if ($in_event) { $accum_event[] = $line; }
if ($line == "END:VTIMEZONE") {
$in_timezone = false;
if (count($accum_timezone) > 0) {
$timezone = join("\n", $accum_timezone);
}
}
if ($line == "END:VEVENT") {
$in_event = false;
if (count($accum_event) > 0) {
$events[] = join("\n", $accum_event);
}
}
}
}
}
header("Content-Type: text/calendar");
echo $header . "\n" . $timezone . "\n" . join("\n", $events) . "\n" . $footer;
?>
@unfinishedCode

This comment has been minimized.

Copy link

@unfinishedCode unfinishedCode commented Apr 9, 2016

Very helpful! Thanks for sharing!

@sahilsarpal15

This comment has been minimized.

Copy link

@sahilsarpal15 sahilsarpal15 commented Dec 14, 2016

can you tell how to create a new calendar

@AmanjotKaurDT

This comment has been minimized.

Copy link

@AmanjotKaurDT AmanjotKaurDT commented Feb 28, 2017

How to get the pGuid

@matthew-lymer

This comment has been minimized.

Copy link

@matthew-lymer matthew-lymer commented Oct 19, 2017

Hi,

I'm trying to get this working, but it just returns nothing (I've got all of the parameters, and receiving no errors). Are there any known issues? Or restrictions beyond those made in the comments?

Is anyone able to support me?

Thanks

@jduffas

This comment has been minimized.

Copy link

@jduffas jduffas commented Jan 31, 2018

hello,
I got some errors on line 35,
in fact it seems it can't log in calendar...
does things have changed in apple server?
for exemple is adress still pxx-caldav.icloud.com/ or is it now pxx-calendarws.icloud.com

@jduffas

This comment has been minimized.

Copy link

@jduffas jduffas commented Jan 31, 2018

and on ical, is work calendar pGuid still "work" ?

@JasonJXB

This comment has been minimized.

Copy link

@JasonJXB JasonJXB commented Jun 11, 2018

How to get the pGuid

@nullcookies

This comment has been minimized.

Copy link

@nullcookies nullcookies commented May 16, 2019

Is this code still working?

@jduffas

This comment has been minimized.

Copy link

@jduffas jduffas commented Nov 27, 2020

I think it doesn't but I don't understand why...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.