26 var $base_url, $user, $pass, $calendar, $entry, $protocol, $server, $port;
33 var $user_agent =
'DAViCalClient';
35 var $headers = array();
37 var $requestMethod =
"GET";
38 var $httpRequest =
"";
40 var $httpResponse =
"";
41 var $xmlResponse =
"";
51 function __construct( $base_url, $user, $pass, $calendar =
'' ) {
54 $this->calendar = $calendar;
55 $this->headers = array();
57 if ( preg_match(
'#^(https?)://([a-z0-9.-]+)(:([0-9]+))?(/.*)$#', $base_url, $matches ) ) {
58 $this->server = $matches[2];
59 $this->base_url = $matches[5];
60 if ( $matches[1] ==
'https' ) {
61 $this->protocol =
'ssl';
65 $this->protocol =
'tcp';
68 if ( $matches[4] !=
'' ) {
69 $this->port = intval($matches[4]);
73 trigger_error(
"Invalid URL: '".$base_url.
"'", E_USER_ERROR);
84 $this->headers[] = sprintf(
"%s-Match: %s", ($match ?
"If" :
"If-None"), $etag);
93 $this->headers[] =
'Depth: '. ($depth ==
'1' ?
"1" : ($depth ==
'infinity' ? $depth :
"0") );
102 if ( !isset($user_agent) ) $user_agent = $this->user_agent;
103 $this->user_agent = $user_agent;
112 $this->headers[] =
"Content-type: $type";
121 $pos = strpos($response,
'<?xml');
122 if ($pos ===
false) {
123 $this->httpResponse = trim($response);
126 $this->httpResponse = trim(substr($response, 0, $pos));
127 $this->xmlResponse = trim(substr($response, $pos));
137 return $this->httpRequest;
145 return $this->httpResponse;
153 return $this->xmlRequest;
161 return $this->xmlResponse;
172 if(!defined(
"_FSOCK_TIMEOUT")){ define(
"_FSOCK_TIMEOUT", 10); }
175 $headers[] = $this->requestMethod.
" ". $this->base_url . $relative_url .
" HTTP/1.1";
176 $headers[] =
"Authorization: Basic ".base64_encode($this->user .
":". $this->pass );
177 $headers[] =
"Host: ".$this->server .
":".$this->port;
179 foreach( $this->headers as $ii => $head ) {
182 $headers[] =
"Content-Length: " . strlen($this->body);
183 $headers[] =
"User-Agent: " . $this->user_agent;
184 $headers[] =
'Connection: close';
185 $this->httpRequest = join(
"\r\n",$headers);
186 $this->xmlRequest = $this->body;
188 $fip = fsockopen( $this->protocol .
'://' . $this->server, $this->port, $errno, $errstr, _FSOCK_TIMEOUT);
189 if ( !(get_resource_type($fip) ==
'stream') )
return false;
190 if ( !fwrite($fip, $this->httpRequest.
"\r\n\r\n".$this->body) ) { fclose($fip);
return false; }
192 while( !feof($fip) ) { $rsp .= fgets($fip,8192); }
195 $this->headers = array();
209 $this->requestMethod =
"OPTIONS";
211 $headers = $this->
DoRequest($relative_url);
212 $options_header = preg_replace(
'/^.*Allow: ([a-z, ]+)\r?\n.*/is',
'$1', $headers );
213 $options = array_flip( preg_split(
'/[, ]+/', $options_header ));
230 $this->requestMethod = $request_method;
244 $this->requestMethod =
"GET";
245 return $this->
DoRequest( $relative_url );
259 $this->body = $icalendar;
261 $this->requestMethod =
"PUT";
262 if ( $etag !=
null ) {
263 $this->
SetMatch( ($etag !=
'*'), $etag );
266 $headers = $this->
DoRequest($relative_url);
272 $etag = preg_replace(
'/^.*Etag: "?([^"\r\n]+)"?\r?\n.*/is',
'$1', $headers );
288 $this->requestMethod =
"DELETE";
289 if ( $etag !=
null ) {
293 return $this->resultcode;
313 <?xml version=
"1.0" encoding=
"utf-8" ?>
314 <C:calendar-query xmlns:D=
"DAV:" xmlns:C=
"urn:ietf:params:xml:ns:caldav">
323 $xml_parser = xml_parser_create_ns(
'UTF-8');
324 $this->xml_tags = array();
325 xml_parser_set_option ( $xml_parser, XML_OPTION_SKIP_WHITE, 1 );
326 xml_parse_into_struct( $xml_parser, $this->xmlResponse, $this->xml_tags );
327 xml_parser_free($xml_parser);
330 foreach( $this->xml_tags as $k => $v ) {
331 switch( $v[
'tag'] ) {
332 case 'DAV::RESPONSE':
333 if ( $v[
'type'] ==
'open' ) {
336 elseif ( $v[
'type'] ==
'close' ) {
337 $report[] = $response;
341 $response[
'href'] = basename( $v[
'value'] );
344 $response[
'etag'] = preg_replace(
'/^"?([^"]+)"?/',
'$1', $v[
'value']);
346 case 'URN:IETF:PARAMS:XML:NS:CALDAV:CALENDAR-DATA':
347 $response[
'data'] = $v[
'value'];
368 function GetEvents( $start =
null, $finish =
null, $relative_url =
'' ) {
370 if ( isset($start) && isset($finish) )
371 $range =
"<C:time-range start=\"$start\" end=\"$finish\"/>";
375 $filter = <<<EOFILTER
377 <C:comp-filter name=
"VCALENDAR">
378 <C:comp-filter name=
"VEVENT">
404 function GetTodos( $start, $finish, $completed =
false, $cancelled =
false, $relative_url =
"" ) {
406 if ( $start && $finish ) {
407 $time_range = <<<EOTIME
408 <C:time-range start=
"$start" end=
"$finish"/>
413 $neg_cancelled = ( $cancelled ===
true ?
"no" :
"yes" );
414 $neg_completed = ( $cancelled ===
true ?
"no" :
"yes" );
416 $filter = <<<EOFILTER
418 <C:comp-filter name=
"VCALENDAR">
419 <C:comp-filter name=
"VTODO">
420 <C:prop-filter name=
"STATUS">
421 <C:text-match negate-condition=
"$neg_completed">COMPLETED</C:text-match>
423 <C:prop-filter name=
"STATUS">
424 <C:text-match negate-condition=
"$neg_cancelled">CANCELLED</C:text-match>
425 </C:prop-filter>$time_range
446 $filter = <<<EOFILTER
448 <C:comp-filter name=
"VCALENDAR">
449 <C:comp-filter name=
"VEVENT">
450 <C:prop-filter name=
"UID">
451 <C:text-match icollation=
"i;octet">$uid</C:text-match>
SetMatch( $match, $etag=' *')
DoOptionsRequest( $relative_url="")
GetEntryByUid( $uid, $relative_url='')
GetTodos( $start, $finish, $completed=false, $cancelled=false, $relative_url="")
DoCalendarQuery( $filter, $url='')
DoXMLRequest( $request_method, $xml, $url=null)
ParseResponse( $response)
DoPUTRequest( $relative_url, $icalendar, $etag=null)
DoCalendarQuery( $filter, $relative_url='')
GetEvents( $start=null, $finish=null, $relative_url='')
GetEntryByHref( $href, $relative_url='')
DoXMLRequest( $request_method, $xml, $relative_url='')
DoDELETERequest( $relative_url, $etag=null)
SetUserAgent( $user_agent=null)
DoGETRequest( $relative_url)
__construct( $base_url, $user, $pass, $calendar='')
DoRequest( $relative_url="")