【问题标题】:Get events from CalDAV server using curl使用 curl 从 CalDAV 服务器获取事件
【发布时间】:2014-12-10 15:55:14
【问题描述】:

我正在尝试使用 curl 从某个 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 ( )

尽管我的日历中有很多事件,但它们似乎没有返回。我在这里做错了什么?任何意见表示赞赏。

【问题讨论】:

    标签: php events dom curl caldav


    【解决方案1】:

    您的代码可能不起作用,因为您正在使用带有 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>
    

    您有两个选择,要么创建一个适当的日历查询报告(即执行 curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'REPORT')),要么发出一个适当的 PROPFIND 请求实体。 我会说后者是更好的选择。

    【讨论】:

    • 将其更改为“报告”会引发此异常:Sabre\DAV\Exception\BadRequest Only one filter element is allowed 1.8.7 SimpleXMLElement Object ( )
    • 我猜这是因为请求中的日历查询不包含实际的查询元素。日历查询需要过滤器,检查:tools.ietf.org/html/rfc4791#section-9.5。但如前所述,您可能应该使用 PROPFIND (或同步报告,取决于您想要做什么)。
    【解决方案2】:

    此请求不是为了从 caldav 获取事件。它用于检索日历信息,即 calendarName、calendarId 等。请参阅 https://www.rfc-editor.org/rfc/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>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-10-29
      • 2018-06-30
      • 1970-01-01
      • 1970-01-01
      • 2018-04-14
      • 2013-02-01
      • 1970-01-01
      • 2016-11-19
      相关资源
      最近更新 更多