我试图通过卷曲从某个CalDAV服务器(在这种情况下是贝加尔)获取所有事件。该任务的基础教程是this。
根据本教程,请求应如下所示:
PROPFIND /calendars/johndoe/home/ HTTP/1.1
Depth: 0
Prefer: return-minimal
Content-Type: application/xml; charset=utf-8
<d:propfind xmlns:d="DAV:" xmlns:cs="http://calendarserver.org/ns/">
<d:prop>
<d:displayname />
<cs:getctag />
</d:prop>
</d:propfind>
这是我的实施:
$headers = array(
'Content-Type: application/xml; charset=utf-8',
'Depth: 0',
'Prefer: return-minimal'
);
$fp = fopen(dirname(__FILE__).'/getEventCURLError.txt', 'w');
$url = "http://xxx.ch/dav/cal.php/calendars/john/john-cal/";
$userpwd = "john:12345";
// prepare request body
$doc = new DOMDocument('1.0', 'utf-8');
$doc->formatOutput = true;
$query = $doc->createElement('c:calendar-query');
$query->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:c', 'urn:ietf:params:xml:ns:caldav');
$query->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:d', 'DAV:');
$prop = $doc->createElement('d:prop');
$prop->appendChild($doc->createElement('d:getetag'));
$prop->appendChild($doc->createElement('c:calendar-data'));
$query->appendChild($prop);
$doc->appendChild($query);
$body = $doc->saveXML();
echo "Body: " . $body . "<br>";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_USERPWD, $userpwd);
curl_setopt($ch, CURLOPT_VERBOSE, 1);
curl_setopt($ch, CURLOPT_STDERR, $fp);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PROPFIND');
curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
$response = curl_exec($ch);
curl_close($ch);
print_r($response);
$xml = simplexml_load_string($response);
print_r($xml)
输出是这样的:
Body:
/dav/cal.php/calendars/john/john-cal/HTTP/1.1 200 OK
SimpleXMLElement Object ( )
即使我在日历中有很多活动,但它们似乎并没有被退回。我在这做错了什么?任何意见都表示赞赏。
答案 0 :(得分:2)
大概你的代码不起作用,因为你正在使用带有PROPFIND请求的日历查询REPORT实体。
$query = $doc->createElement('c:calendar-query');
...
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PROPFIND');
PROPFIND请求期望请求中的propfind实体,而不是日历查询实体,如原始示例所示:
PROPFIND /calendars/johndoe/home/ HTTP/1.1
Depth: 0
Prefer: return-minimal
Content-Type: application/xml; charset=utf-8
<d:propfind xmlns:d="DAV:" xmlns:cs="http://calendarserver.org/ns/">
<d:prop>
<d:displayname />
<cs:getctag />
</d:prop>
</d:propfind>
您有两种选择,要么创建正确的日历查询REPORT(即执行curl_setopt($ ch,CURLOPT_CUSTOMREQUEST,&#39; REPORT&#39;)),要么发出正确的PROPFIND请求实体。 我说后者是更好的选择。
答案 1 :(得分:0)
此请求不适用于从caldav获取事件。它用于检索日历信息,即calendarName,calendarId等。请参阅https://tools.ietf.org/html/rfc4791#section-7.8.1以查找事件
Method-: REPORT
Content type-: application/xml; charset=utf-8
Header -: Depth : 1
URL-:GET /<ICLOUD_USER_ID>/calendars/
Set credentials
Following is RequestContent-:
<C:calendar-query xmlns:D='DAV:'
xmlns:C='urn:ietf:params:xml:ns:caldav'>
<D:prop>
<D:getetag/>
<C:calendar-data>
<C:comp name='VCALENDAR'>
<C:prop name='VERSION'/>
<C:comp name='VEVENT'>
<C:prop name='SUMMARY'/>
<C:prop name='DESCRIPTION'/>
<C:prop name='STATUS'/>
<C:prop name='TRANSP'/>
<C:prop name='ATTENDEE'/>
<C:prop name='UID'/>
<C:prop name='DTSTART'/>
<C:prop name='DTEND'/>
<C:prop name='DURATION'/>
<C:prop name='RRULE'/>
<C:prop name='RDATE'/>
<C:prop name='EXRULE'/>
<C:prop name='EXDATE'/>
<C:prop name='RECURRENCE-ID'/>
</C:comp>
</C:comp>
</C:calendar-data>
</D:prop>
<C:filter>
<C:comp-filter name='VCALENDAR'>
<C:comp-filter name='VEVENT'>
<C:time-range start='20160524T000000Z'
end='20160526T000000Z'/>
</C:comp-filter>
</C:comp-filter>
</C:filter>
</C:calendar-query>