Получить события с сервера CalDAV с помощью curl

Я пытаюсь получить все события с определенного сервера CalDAV (в данном случае Baikal) с помощью curl. Базовое руководство по этой задаче — это.

Согласно этому руководству, запрос должен выглядеть примерно так:

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 ( )

Несмотря на то, что у меня много событий в календаре, они, похоже, не возвращаются. Что я здесь делаю неправильно? Любой вклад приветствуется.


person nimrod    schedule 10.12.2014    source источник


Ответы (2)


Предположительно, ваш код не работает, потому что вы используете объект REPORT запроса календаря с запросом PROPFIND.

$query = $doc->createElement('c:calendar-query');

...

curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PROPFIND');

Запрос PROPFIND ожидает в запросе объект propfind, а не объект calendar-query, как показано в исходном примере:

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. Я бы сказал, что последний - лучший выбор.

person hnh    schedule 11.12.2014
comment
Изменение его на «ОТЧЕТ» вызывает это исключение: Sabre\DAV\Exception\BadRequest Only one filter element is allowed 1.8.7 SimpleXMLElement Object ( ) - person nimrod; 11.12.2014
comment
Я предполагаю, что это связано с тем, что запрос календаря в запросе не содержит фактического элемента запроса. Для запроса календаря требуется фильтр, проверьте: tools.ietf.org/html/rfc4791# раздел-9.5. Но, как уже упоминалось, вам, вероятно, все равно следует использовать PROPFIND (или отчет о синхронизации, в зависимости от того, что вы хотите сделать). - person hnh; 12.12.2014

Этот запрос не для получения событий от caldav. Он предназначен для получения информации о календаре, например, имя календаря, идентификатор календаря и т. д. См. 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>
person Priyank Kotiyal    schedule 09.03.2017