0

I try to get multiple event in caldav using a multiget request as explain here: http://sabre.io/dav/building-a-caldav-client

or here: Reading Apple/iCloud calendar data using PHP/CalDAV

It's suppose to be as simple as passing:

<?xml version="1.0" encoding="UTF-8"?>
<B:calendar-multiget xmlns:B="urn:ietf:params:xml:ns:caldav">  
  <A:prop xmlns:A="DAV:">        
  <B:calendar-data/>
  </A:prop>
  <A:href xmlns:A="DAV:">/calendars/__uids__/DE6BFE56-B3DC-4C60-A9C7-ED05A45AAC92/calendar/00ECD3D1-72D0-4F56-9011-71A6180F848C.ics</A:href>
</B:calendar-multiget>

I'm using PHP to pass the XML request. But the XML response don't have any calendar-data:

SimpleXMLElement Object
(
    [response] => SimpleXMLElement Object
        (
            [href] => /calendars/__uids__/DE6BFE56-B3DC-4C60-A9C7-ED05A45AAC92/calendar/00ECD3D1-72D0-4F56-9011-71A6180F848C.ics
            [propstat] => SimpleXMLElement Object
                (
                    [prop] => SimpleXMLElement Object
                        (
                            [calendar-data] => SimpleXMLElement Object
                                (
                                )

                        )

                    [status] => HTTP/1.1 200 OK
                )

        )

)

I use simplexml_load_string and print_r to display the result. How can I get the calendar-data?

GET method work fine but is too slow when I wan't to update >50 events.

EDIT: I can make it work using Curl in Terminal as suggested by hnh. But it doesn't work using curl in php. Here is the code I use (url element, log, pass, xml request are the same as the one use in terminal):

$xml= '<C:calendar-multiget xmlns="DAV:" xmlns:C="urn:ietf:params:xml:ns:caldav"><prop><C:calendar-data/></prop><href>/calendars/__uids__/DE6BFE56-B3DC-4C60-A9C7-ED05A45AAC92/calendar/94DA9025-02E5-4313-BF81-66641BC5989F.ics</href><href>/calendars/__uids__/DE6BFE56-B3DC-4C60-A9C7-ED05A45AAC92/calendar/175CA348-8877-4CDF-B19D-4C66E191F4B4.ics</href></C:calendar-multiget>';

$user = "MyLogin";
$pw= "MyPsw";
$url = "https://localhost:443/calendars/__uids__/DE6BFE56-B3DC-4C60-A9C7-ED05A45AAC92/calendar/";

$data = doRequest($user, $pw, $url, $xml);
print "<pre>";
print_r($data);
print "</pre>";

function doRequest($user, $pw, $url, $xml)
    {
        $c=curl_init($url);
        curl_setopt($c, CURLOPT_HTTPHEADER, array("Depth: 1", "Content-Type: text/xml; charset='UTF-8'", "User-Agent: DAVKit/4.0.1 (730); CalendarStore/4.0.1 (973); iCal/4.0.1 (1374); Mac OS X/10.6.2 (10C540)"));
        curl_setopt($c, CURLOPT_HEADER, 0);
        curl_setopt($c, CURLOPT_SSL_VERIFYHOST, 0);
        curl_setopt($c, CURLOPT_SSL_VERIFYPEER, 0);
        curl_setopt($c, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
        curl_setopt($c, CURLOPT_USERPWD, $user.":".$pw);
        curl_setopt($c, CURLOPT_CUSTOMREQUEST, "REPORT");
        curl_setopt($c, CURLOPT_POSTFIELDS, $xml);
        curl_setopt($c, CURLOPT_RETURNTRANSFER, 1);
        $data=curl_exec($c);
        curl_close($c);

        return $data;
    }

It doesn't return any calendar data:

/calendars/__uids__/DE6BFE56-B3DC-4C60-A9C7-ED05A45AAC92/calendar/175CA348-8877-4CDF-B19D-4C66E191F4B4.ics

  HTTP/1.1 200 OK

/calendars/__uids__/DE6BFE56-B3DC-4C60-A9C7-ED05A45AAC92/calendar/94DA9025-02E5-4313-BF81-66641BC5989F.ics

  HTTP/1.1 200 OK
Community
  • 1
  • 1
Vincent
  • 11
  • 5

2 Answers2

1

Actually, Curl request return the data. The problem is the data display. As the calendar data is return as CDATA, you have to use LIBXML_NOCDATA to display it:

simplexml_load_string($data, 'SimpleXMLElement', LIBXML_NOCDATA)
Vincent
  • 11
  • 5
0

The request has many superfluous namespace definitions, but looks OK to me. This would be a shorter version:

<?xml version="1.0" encoding="UTF-8"?>
<C:calendar-multiget xmlns="DAV:" xmlns:C="urn:ietf:params:xml:ns:caldav">
  <prop><C:calendar-data/></prop>
  <href>/calendars/__uids__/DE6BFE56-B3DC-4C60-A9C7-ED05A45AAC92/calendar/00ECD3D1-72D0-4F56-9011-71A6180F848C.ics</href>
</C:calendar-multiget>

Did you try the request in curl, to figure out what the server returns? Like that:

curl -u "login:pwd" -X REPORT --data \
  '<C:calendar-multiget xmlns="DAV:" xmlns:C="urn:ietf:params:xml:ns:caldav"><prop><C:calendar-data/></prop><href>/calendars/__uids__/DE6BFE56-B3DC-4C60-A9C7-ED05A45AAC92/calendar/00ECD3D1-72D0-4F56-9011-71A6180F848C.ics</href></C:calendar-multiget>' \
  http://yourserver:8008/calendars/__uids__/DE6BFE56-B3DC-4C60-A9C7-ED05A45AAC92/calendar/
hnh
  • 13,957
  • 6
  • 30
  • 40
  • It looks to work using curl. I'll do some more test to use it in php. I'll keep you inform. Thanks. – Vincent Feb 25 '14 at 23:08
  • After some more test, I can't make it work using php. It doesn't return any calendar data. I edit my question with the code I use. I imagine, the problem come from my curl request. – Vincent Feb 26 '14 at 09:10
  • Probably not relevant in the context, BUT: Setting the UA to something your are not, like "iCal/4.0.1" is generally a very bad idea. The servers might send something different in such cases to work around bugs specific to those UAs (including invalid CalDAV, XML, etc :-). – hnh Feb 26 '14 at 22:23
  • Try to log the actual request it sends as explained in this: http://stackoverflow.com/questions/866946/how-can-i-see-the-request-headers-made-by-curl-when-sending-a-request-to-the-ser – hnh Feb 26 '14 at 22:26
  • Your right setting fake UA is a bad idea. Most part of my code come from: [link](https://github.com/muhlba91/icloud/blob/master/PHP/icloud.php). I hadn't change it for test purpose. I log the actual request. I wrote it in a new answer for readability purpose. – Vincent Feb 26 '14 at 23:37