[3733] | 1 | <?php |
---|
| 2 | /** |
---|
| 3 | * A Class for connecting to a caldav server |
---|
| 4 | * |
---|
| 5 | * @package awl |
---|
| 6 | * removed curl - now using fsockopen |
---|
| 7 | * changed 2009 by Andres Obrero - Switzerland andres@obrero.ch |
---|
| 8 | * |
---|
| 9 | * @subpackage caldav |
---|
| 10 | * @author Andrew McMillan <debian@mcmillan.net.nz> |
---|
| 11 | * @copyright Andrew McMillan |
---|
| 12 | * @license http://gnu.org/copyleft/gpl.html GNU GPL v2 |
---|
| 13 | */ |
---|
| 14 | |
---|
| 15 | |
---|
| 16 | /** |
---|
| 17 | * A class for accessing DAViCal via CalDAV, as a client |
---|
| 18 | * |
---|
| 19 | * @package awl |
---|
| 20 | */ |
---|
| 21 | class CalDAVClient { |
---|
| 22 | /** |
---|
| 23 | * Server, username, password, calendar |
---|
| 24 | * |
---|
| 25 | * @var string |
---|
| 26 | */ |
---|
| 27 | var $base_url, $user, $pass, $calendar, $entry, $protocol, $server, $port; |
---|
| 28 | |
---|
| 29 | /** |
---|
| 30 | * The useragent which is send to the caldav server |
---|
| 31 | * |
---|
| 32 | * @var string |
---|
| 33 | */ |
---|
| 34 | var $user_agent = 'DAViCalClient'; |
---|
| 35 | |
---|
| 36 | var $headers = array(); |
---|
| 37 | var $body = ""; |
---|
| 38 | var $requestMethod = "GET"; |
---|
| 39 | var $httpRequest = ""; // for debugging http headers sent |
---|
| 40 | var $xmlRequest = ""; // for debugging xml sent |
---|
| 41 | var $httpResponse = ""; // for debugging http headers received |
---|
| 42 | var $xmlResponse = ""; // for debugging xml received |
---|
| 43 | |
---|
| 44 | /** |
---|
| 45 | * Constructor, initialises the class |
---|
| 46 | * |
---|
| 47 | * @param string $base_url The URL for the calendar server |
---|
| 48 | * @param string $user The name of the user logging in |
---|
| 49 | * @param string $pass The password for that user |
---|
| 50 | * @param string $calendar The name of the calendar (not currently used) |
---|
| 51 | */ |
---|
| 52 | function CalDAVClient( $base_url, $user, $pass, $calendar = '' ) { |
---|
| 53 | $this->user = $user; |
---|
| 54 | $this->pass = $pass; |
---|
| 55 | $this->calendar = $calendar; |
---|
| 56 | $this->headers = array(); |
---|
| 57 | |
---|
| 58 | if ( preg_match( '#^(https?)://([a-z0-9.-]+)(:([0-9]+))?(/.*)$#', $base_url, $matches ) ) { |
---|
| 59 | $this->server = $matches[2]; |
---|
| 60 | $this->base_url = $matches[5]; |
---|
| 61 | if ( $matches[1] == 'https' ) { |
---|
| 62 | $this->protocol = 'ssl'; |
---|
| 63 | $this->port = 443; |
---|
| 64 | } |
---|
| 65 | else { |
---|
| 66 | $this->protocol = 'tcp'; |
---|
| 67 | $this->port = 80; |
---|
| 68 | } |
---|
| 69 | if ( $matches[4] != '' ) { |
---|
| 70 | $this->port = intval($matches[4]); |
---|
| 71 | } |
---|
| 72 | } |
---|
| 73 | else { |
---|
| 74 | trigger_error("Invalid URL: '".$base_url."'", E_USER_ERROR); |
---|
| 75 | } |
---|
| 76 | } |
---|
| 77 | |
---|
| 78 | /** |
---|
| 79 | * Adds an If-Match or If-None-Match header |
---|
| 80 | * |
---|
| 81 | * @param bool $match to Match or Not to Match, that is the question! |
---|
| 82 | * @param string $etag The etag to match / not match against. |
---|
| 83 | */ |
---|
| 84 | function SetMatch( $match, $etag = '*' ) { |
---|
| 85 | $this->headers[] = sprintf( "%s-Match: %s", ($match ? "If" : "If-None"), $etag); |
---|
| 86 | } |
---|
| 87 | |
---|
| 88 | /* |
---|
| 89 | * Add a Depth: header. Valid values are 0, 1 or infinity |
---|
| 90 | * |
---|
| 91 | * @param int $depth The depth, default to infinity |
---|
| 92 | */ |
---|
| 93 | function SetDepth( $depth = '0' ) { |
---|
| 94 | $this->headers[] = 'Depth: '. ($depth == '1' ? "1" : ($depth == 'infinity' ? $depth : "0") ); |
---|
| 95 | } |
---|
| 96 | |
---|
| 97 | /** |
---|
| 98 | * Add a Depth: header. Valid values are 1 or infinity |
---|
| 99 | * |
---|
| 100 | * @param int $depth The depth, default to infinity |
---|
| 101 | */ |
---|
| 102 | function SetUserAgent( $user_agent = null ) { |
---|
| 103 | if ( !isset($user_agent) ) $user_agent = $this->user_agent; |
---|
| 104 | $this->user_agent = $user_agent; |
---|
| 105 | } |
---|
| 106 | |
---|
| 107 | /** |
---|
| 108 | * Add a Content-type: header. |
---|
| 109 | * |
---|
| 110 | * @param int $type The content type |
---|
| 111 | */ |
---|
| 112 | function SetContentType( $type ) { |
---|
| 113 | $this->headers[] = "Content-type: $type"; |
---|
| 114 | } |
---|
| 115 | |
---|
| 116 | /** |
---|
| 117 | * Split response into httpResponse and xmlResponse |
---|
| 118 | * |
---|
| 119 | * @param string Response from server |
---|
| 120 | */ |
---|
| 121 | function ParseResponse( $response ) { |
---|
| 122 | $pos = strpos($response, '<?xml'); |
---|
| 123 | if ($pos === false) { |
---|
| 124 | $this->httpResponse = trim($response); |
---|
| 125 | } |
---|
| 126 | else { |
---|
| 127 | $this->httpResponse = trim(substr($response, 0, $pos)); |
---|
| 128 | $this->xmlResponse = trim(substr($response, $pos)); |
---|
| 129 | } |
---|
| 130 | } |
---|
| 131 | |
---|
| 132 | /** |
---|
| 133 | * Output http request headers |
---|
| 134 | * |
---|
| 135 | * @return HTTP headers |
---|
| 136 | */ |
---|
| 137 | function GetHttpRequest() { |
---|
| 138 | return $this->httpRequest; |
---|
| 139 | } |
---|
| 140 | /** |
---|
| 141 | * Output http response headers |
---|
| 142 | * |
---|
| 143 | * @return HTTP headers |
---|
| 144 | */ |
---|
| 145 | function GetHttpResponse() { |
---|
| 146 | return $this->httpResponse; |
---|
| 147 | } |
---|
| 148 | /** |
---|
| 149 | * Output xml request |
---|
| 150 | * |
---|
| 151 | * @return raw xml |
---|
| 152 | */ |
---|
| 153 | function GetXmlRequest() { |
---|
| 154 | return $this->xmlRequest; |
---|
| 155 | } |
---|
| 156 | /** |
---|
| 157 | * Output xml response |
---|
| 158 | * |
---|
| 159 | * @return raw xml |
---|
| 160 | */ |
---|
| 161 | function GetXmlResponse() { |
---|
| 162 | return $this->xmlResponse; |
---|
| 163 | } |
---|
| 164 | |
---|
| 165 | /** |
---|
| 166 | * Send a request to the server |
---|
| 167 | * |
---|
| 168 | * @param string $relative_url The URL to make the request to, relative to $base_url |
---|
| 169 | * |
---|
| 170 | * @return string The content of the response from the server |
---|
| 171 | */ |
---|
| 172 | function DoRequest( $relative_url = "" ) { |
---|
| 173 | if(!defined("_FSOCK_TIMEOUT")){ define("_FSOCK_TIMEOUT", 10); } |
---|
| 174 | $headers = array(); |
---|
| 175 | |
---|
| 176 | $headers[] = $this->requestMethod." ". $this->base_url . $relative_url . " HTTP/1.1"; |
---|
| 177 | $headers[] = "Authorization: Basic ".base64_encode($this->user .":". $this->pass ); |
---|
| 178 | $headers[] = "Host: ".$this->server .":".$this->port; |
---|
| 179 | |
---|
| 180 | foreach( $this->headers as $ii => $head ) { |
---|
| 181 | $headers[] = $head; |
---|
| 182 | } |
---|
| 183 | $headers[] = "Content-Length: " . strlen($this->body); |
---|
| 184 | $headers[] = "User-Agent: " . $this->user_agent; |
---|
| 185 | $headers[] = 'Connection: close'; |
---|
| 186 | $this->httpRequest = join("\r\n",$headers); |
---|
| 187 | $this->xmlRequest = $this->body; |
---|
| 188 | |
---|
| 189 | $fip = fsockopen( $this->protocol . '://' . $this->server, $this->port, $errno, $errstr, _FSOCK_TIMEOUT); //error handling? |
---|
| 190 | if ( !(get_resource_type($fip) == 'stream') ) return false; |
---|
| 191 | if ( !fwrite($fip, $this->httpRequest."\r\n\r\n".$this->body) ) { fclose($fip); return false; } |
---|
| 192 | $rsp = ""; |
---|
| 193 | while( !feof($fip) ) { $rsp .= fgets($fip,8192); } |
---|
| 194 | fclose($fip); |
---|
| 195 | |
---|
| 196 | $this->headers = array(); // reset the headers array for our next request |
---|
| 197 | $this->ParseResponse($rsp); |
---|
| 198 | return $rsp; |
---|
| 199 | } |
---|
| 200 | |
---|
| 201 | |
---|
| 202 | /** |
---|
| 203 | * Send an OPTIONS request to the server |
---|
| 204 | * |
---|
| 205 | * @param string $relative_url The URL to make the request to, relative to $base_url |
---|
| 206 | * |
---|
| 207 | * @return array The allowed options |
---|
| 208 | */ |
---|
| 209 | function DoOptionsRequest( $relative_url = "" ) { |
---|
| 210 | $this->requestMethod = "OPTIONS"; |
---|
| 211 | $this->body = ""; |
---|
| 212 | $headers = $this->DoRequest($relative_url); |
---|
| 213 | $options_header = preg_replace( '/^.*Allow: ([a-z, ]+)\r?\n.*/is', '$1', $headers ); |
---|
| 214 | $options = array_flip( preg_split( '/[, ]+/', $options_header )); |
---|
| 215 | return $options; |
---|
| 216 | } |
---|
| 217 | |
---|
| 218 | |
---|
| 219 | |
---|
| 220 | /** |
---|
| 221 | * Send an XML request to the server (e.g. PROPFIND, REPORT, MKCALENDAR) |
---|
| 222 | * |
---|
| 223 | * @param string $method The method (PROPFIND, REPORT, etc) to use with the request |
---|
| 224 | * @param string $xml The XML to send along with the request |
---|
| 225 | * @param string $relative_url The URL to make the request to, relative to $base_url |
---|
| 226 | * |
---|
| 227 | * @return array An array of the allowed methods |
---|
| 228 | */ |
---|
| 229 | function DoXMLRequest( $request_method, $xml, $relative_url = '' ) { |
---|
| 230 | $this->body = $xml; |
---|
| 231 | $this->requestMethod = $request_method; |
---|
| 232 | $this->SetContentType("text/xml"); |
---|
| 233 | return $this->DoRequest($relative_url); |
---|
| 234 | } |
---|
| 235 | |
---|
| 236 | |
---|
| 237 | |
---|
| 238 | /** |
---|
| 239 | * Get a single item from the server. |
---|
| 240 | * |
---|
| 241 | * @param string $relative_url The part of the URL after the calendar |
---|
| 242 | */ |
---|
| 243 | function DoGETRequest( $relative_url ) { |
---|
| 244 | $this->body = ""; |
---|
| 245 | $this->requestMethod = "GET"; |
---|
| 246 | return $this->DoRequest( $relative_url ); |
---|
| 247 | } |
---|
| 248 | |
---|
| 249 | |
---|
| 250 | /** |
---|
| 251 | * PUT a text/icalendar resource, returning the etag |
---|
| 252 | * |
---|
| 253 | * @param string $relative_url The URL to make the request to, relative to $base_url |
---|
| 254 | * @param string $icalendar The iCalendar resource to send to the server |
---|
| 255 | * @param string $etag The etag of an existing resource to be overwritten, or '*' for a new resource. |
---|
| 256 | * |
---|
| 257 | * @return string The content of the response from the server |
---|
| 258 | */ |
---|
| 259 | function DoPUTRequest( $relative_url, $icalendar, $etag = null ) { |
---|
| 260 | $this->body = $icalendar; |
---|
| 261 | |
---|
| 262 | $this->requestMethod = "PUT"; |
---|
| 263 | if ( $etag != null ) { |
---|
| 264 | $this->SetMatch( ($etag != '*'), $etag ); |
---|
| 265 | } |
---|
| 266 | $this->SetContentType("text/icalendar"); |
---|
| 267 | $headers = $this->DoRequest($relative_url); |
---|
| 268 | |
---|
| 269 | /** |
---|
| 270 | * RSCDS will always return the real etag on PUT. Other CalDAV servers may need |
---|
| 271 | * more work, but we are assuming we are running against RSCDS in this case. |
---|
| 272 | */ |
---|
| 273 | $etag = preg_replace( '/^.*Etag: "?([^"\r\n]+)"?\r?\n.*/is', '$1', $headers ); |
---|
| 274 | return $etag; |
---|
| 275 | } |
---|
| 276 | |
---|
| 277 | |
---|
| 278 | /** |
---|
| 279 | * DELETE a text/icalendar resource |
---|
| 280 | * |
---|
| 281 | * @param string $relative_url The URL to make the request to, relative to $base_url |
---|
| 282 | * @param string $etag The etag of an existing resource to be deleted, or '*' for any resource at that URL. |
---|
| 283 | * |
---|
| 284 | * @return int The HTTP Result Code for the DELETE |
---|
| 285 | */ |
---|
| 286 | function DoDELETERequest( $relative_url, $etag = null ) { |
---|
| 287 | $this->body = ""; |
---|
| 288 | |
---|
| 289 | $this->requestMethod = "DELETE"; |
---|
| 290 | if ( $etag != null ) { |
---|
| 291 | $this->SetMatch( true, $etag ); |
---|
| 292 | } |
---|
| 293 | $this->DoRequest($relative_url); |
---|
| 294 | return $this->resultcode; |
---|
| 295 | } |
---|
| 296 | |
---|
| 297 | |
---|
| 298 | /** |
---|
| 299 | * Given XML for a calendar query, return an array of the events (/todos) in the |
---|
| 300 | * response. Each event in the array will have a 'href', 'etag' and '$response_type' |
---|
| 301 | * part, where the 'href' is relative to the calendar and the '$response_type' contains the |
---|
| 302 | * definition of the calendar data in iCalendar format. |
---|
| 303 | * |
---|
| 304 | * @param string $filter XML fragment which is the <filter> element of a calendar-query |
---|
| 305 | * @param string $relative_url The URL relative to the base_url specified when the calendar was opened. Default ''. |
---|
| 306 | * @param string $report_type Used as a name for the array element containing the calendar data. @deprecated |
---|
| 307 | * |
---|
| 308 | * @return array An array of the relative URLs, etags, and events from the server. Each element of the array will |
---|
| 309 | * be an array with 'href', 'etag' and 'data' elements, corresponding to the URL, the server-supplied |
---|
| 310 | * etag (which only varies when the data changes) and the calendar data in iCalendar format. |
---|
| 311 | */ |
---|
| 312 | function DoCalendarQuery( $filter, $relative_url = '' ) { |
---|
| 313 | |
---|
| 314 | $xml = <<<EOXML |
---|
| 315 | <?xml version="1.0" encoding="utf-8" ?> |
---|
| 316 | <C:calendar-query xmlns:D="DAV:" xmlns:C="urn:ietf:params:xml:ns:caldav"> |
---|
| 317 | <D:prop> |
---|
| 318 | <C:calendar-data/> |
---|
| 319 | <D:getetag/> |
---|
| 320 | </D:prop>$filter |
---|
| 321 | </C:calendar-query> |
---|
| 322 | EOXML; |
---|
| 323 | |
---|
| 324 | $this->DoXMLRequest( 'REPORT', $xml, $relative_url ); |
---|
| 325 | $xml_parser = xml_parser_create_ns('UTF-8'); |
---|
| 326 | $this->xml_tags = array(); |
---|
| 327 | xml_parser_set_option ( $xml_parser, XML_OPTION_SKIP_WHITE, 1 ); |
---|
| 328 | xml_parse_into_struct( $xml_parser, $this->xmlResponse, $this->xml_tags ); |
---|
| 329 | xml_parser_free($xml_parser); |
---|
| 330 | |
---|
| 331 | $report = array(); |
---|
| 332 | foreach( $this->xml_tags as $k => $v ) { |
---|
| 333 | switch( $v['tag'] ) { |
---|
| 334 | case 'DAV::RESPONSE': |
---|
| 335 | if ( $v['type'] == 'open' ) { |
---|
| 336 | $response = array(); |
---|
| 337 | } |
---|
| 338 | elseif ( $v['type'] == 'close' ) { |
---|
| 339 | $report[] = $response; |
---|
| 340 | } |
---|
| 341 | break; |
---|
| 342 | case 'DAV::HREF': |
---|
| 343 | $response['href'] = basename( $v['value'] ); |
---|
| 344 | break; |
---|
| 345 | case 'DAV::GETETAG': |
---|
| 346 | $response['etag'] = preg_replace('/^"?([^"]+)"?/', '$1', $v['value']); |
---|
| 347 | break; |
---|
| 348 | case 'URN:IETF:PARAMS:XML:NS:CALDAV:CALENDAR-DATA': |
---|
| 349 | $response['data'] = $v['value']; |
---|
| 350 | break; |
---|
| 351 | } |
---|
| 352 | } |
---|
| 353 | return $report; |
---|
| 354 | } |
---|
| 355 | |
---|
| 356 | |
---|
| 357 | /** |
---|
| 358 | * Get the events in a range from $start to $finish. The dates should be in the |
---|
| 359 | * format yyyymmddThhmmssZ and should be in GMT. The events are returned as an |
---|
| 360 | * array of event arrays. Each event array will have a 'href', 'etag' and 'event' |
---|
| 361 | * part, where the 'href' is relative to the calendar and the event contains the |
---|
| 362 | * definition of the event in iCalendar format. |
---|
| 363 | * |
---|
| 364 | * @param timestamp $start The start time for the period |
---|
| 365 | * @param timestamp $finish The finish time for the period |
---|
| 366 | * @param string $relative_url The URL relative to the base_url specified when the calendar was opened. Default ''. |
---|
| 367 | * |
---|
| 368 | * @return array An array of the relative URLs, etags, and events, returned from DoCalendarQuery() @see DoCalendarQuery() |
---|
| 369 | */ |
---|
| 370 | function GetEvents( $start = null, $finish = null, $relative_url = '' ) { |
---|
| 371 | $filter = ""; |
---|
| 372 | if ( isset($start) && isset($finish) ) |
---|
| 373 | $range = "<C:time-range start=\"$start\" end=\"$finish\"/>"; |
---|
| 374 | else |
---|
| 375 | $range = ''; |
---|
| 376 | |
---|
| 377 | $filter = <<<EOFILTER |
---|
| 378 | <C:filter> |
---|
| 379 | <C:comp-filter name="VCALENDAR"> |
---|
| 380 | <C:comp-filter name="VEVENT"> |
---|
| 381 | $range |
---|
| 382 | </C:comp-filter> |
---|
| 383 | </C:comp-filter> |
---|
| 384 | </C:filter> |
---|
| 385 | EOFILTER; |
---|
| 386 | |
---|
| 387 | return $this->DoCalendarQuery($filter, $relative_url); |
---|
| 388 | } |
---|
| 389 | |
---|
| 390 | |
---|
| 391 | /** |
---|
| 392 | * Get the todo's in a range from $start to $finish. The dates should be in the |
---|
| 393 | * format yyyymmddThhmmssZ and should be in GMT. The events are returned as an |
---|
| 394 | * array of event arrays. Each event array will have a 'href', 'etag' and 'event' |
---|
| 395 | * part, where the 'href' is relative to the calendar and the event contains the |
---|
| 396 | * definition of the event in iCalendar format. |
---|
| 397 | * |
---|
| 398 | * @param timestamp $start The start time for the period |
---|
| 399 | * @param timestamp $finish The finish time for the period |
---|
| 400 | * @param boolean $completed Whether to include completed tasks |
---|
| 401 | * @param boolean $cancelled Whether to include cancelled tasks |
---|
| 402 | * @param string $relative_url The URL relative to the base_url specified when the calendar was opened. Default ''. |
---|
| 403 | * |
---|
| 404 | * @return array An array of the relative URLs, etags, and events, returned from DoCalendarQuery() @see DoCalendarQuery() |
---|
| 405 | */ |
---|
| 406 | function GetTodos( $start, $finish, $completed = false, $cancelled = false, $relative_url = "" ) { |
---|
| 407 | |
---|
| 408 | if ( $start && $finish ) { |
---|
| 409 | $time_range = <<<EOTIME |
---|
| 410 | <C:time-range start="$start" end="$finish"/> |
---|
| 411 | EOTIME; |
---|
| 412 | } |
---|
| 413 | |
---|
| 414 | // Warning! May contain traces of double negatives... |
---|
| 415 | $neg_cancelled = ( $cancelled === true ? "no" : "yes" ); |
---|
| 416 | $neg_completed = ( $cancelled === true ? "no" : "yes" ); |
---|
| 417 | |
---|
| 418 | $filter = <<<EOFILTER |
---|
| 419 | <C:filter> |
---|
| 420 | <C:comp-filter name="VCALENDAR"> |
---|
| 421 | <C:comp-filter name="VTODO"> |
---|
| 422 | <C:prop-filter name="STATUS"> |
---|
| 423 | <C:text-match negate-condition="$neg_completed">COMPLETED</C:text-match> |
---|
| 424 | </C:prop-filter> |
---|
| 425 | <C:prop-filter name="STATUS"> |
---|
| 426 | <C:text-match negate-condition="$neg_cancelled">CANCELLED</C:text-match> |
---|
| 427 | </C:prop-filter>$time_range |
---|
| 428 | </C:comp-filter> |
---|
| 429 | </C:comp-filter> |
---|
| 430 | </C:filter> |
---|
| 431 | EOFILTER; |
---|
| 432 | |
---|
| 433 | return $this->DoCalendarQuery($filter, $relative_url); |
---|
| 434 | } |
---|
| 435 | |
---|
| 436 | |
---|
| 437 | /** |
---|
| 438 | * Get the calendar entry by UID |
---|
| 439 | * |
---|
| 440 | * @param uid |
---|
| 441 | * @param string $relative_url The URL relative to the base_url specified when the calendar was opened. Default ''. |
---|
| 442 | * |
---|
| 443 | * @return array An array of the relative URL, etag, and calendar data returned from DoCalendarQuery() @see DoCalendarQuery() |
---|
| 444 | */ |
---|
| 445 | function GetEntryByUid( $uid, $relative_url = '' ) { |
---|
| 446 | $filter = ""; |
---|
| 447 | if ( $uid ) { |
---|
| 448 | $filter = <<<EOFILTER |
---|
| 449 | <C:filter> |
---|
| 450 | <C:comp-filter name="VCALENDAR"> |
---|
| 451 | <C:comp-filter name="VEVENT"> |
---|
| 452 | <C:prop-filter name="UID"> |
---|
| 453 | <C:text-match icollation="i;octet">$uid</C:text-match> |
---|
| 454 | </C:prop-filter> |
---|
| 455 | </C:comp-filter> |
---|
| 456 | </C:comp-filter> |
---|
| 457 | </C:filter> |
---|
| 458 | EOFILTER; |
---|
| 459 | } |
---|
| 460 | |
---|
| 461 | return $this->DoCalendarQuery($filter, $relative_url); |
---|
| 462 | } |
---|
| 463 | |
---|
| 464 | |
---|
| 465 | /** |
---|
| 466 | * Get the calendar entry by HREF |
---|
| 467 | * |
---|
| 468 | * @param string $href The href from a call to GetEvents or GetTodos etc. |
---|
| 469 | * @param string $relative_url The URL relative to the base_url specified when the calendar was opened. Default ''. |
---|
| 470 | * |
---|
| 471 | * @return string The iCalendar of the calendar entry |
---|
| 472 | */ |
---|
| 473 | function GetEntryByHref( $href, $relative_url = '' ) { |
---|
| 474 | return $this->DoGETRequest( $relative_url . $href ); |
---|
| 475 | } |
---|
| 476 | |
---|
| 477 | } |
---|
| 478 | |
---|
| 479 | /** |
---|
| 480 | * Usage example |
---|
| 481 | * |
---|
| 482 | * $cal = new CalDAVClient( "http://calendar.example.com/caldav.php/username/calendar/", "username", "password", "calendar" ); |
---|
| 483 | * $options = $cal->DoOptionsRequest(); |
---|
| 484 | * if ( isset($options["PROPFIND"]) ) { |
---|
| 485 | * // Fetch some information about the events in that calendar |
---|
| 486 | * $cal->SetDepth(1); |
---|
| 487 | * $folder_xml = $cal->DoXMLRequest("PROPFIND", '<?xml version="1.0" encoding="utf-8" ?><propfind xmlns="DAV:"><prop><getcontentlength/><getcontenttype/><resourcetype/><getetag/></prop></propfind>' ); |
---|
| 488 | * } |
---|
| 489 | * // Fetch all events for February |
---|
| 490 | * $events = $cal->GetEvents("20070101T000000Z","20070201T000000Z"); |
---|
| 491 | * foreach ( $events AS $k => $event ) { |
---|
| 492 | * do_something_with_event_data( $event['data'] ); |
---|
| 493 | * } |
---|
| 494 | * $acc = array(); |
---|
| 495 | * $acc["google"] = array( |
---|
| 496 | * "user"=>"kunsttherapie@gmail.com", |
---|
| 497 | * "pass"=>"xxxxx", |
---|
| 498 | * "server"=>"ssl://www.google.com", |
---|
| 499 | * "port"=>"443", |
---|
| 500 | * "uri"=>"https://www.google.com/calendar/dav/kunsttherapie@gmail.com/events/", |
---|
| 501 | * ); |
---|
| 502 | * |
---|
| 503 | * $acc["davical"] = array( |
---|
| 504 | * "user"=>"some_user", |
---|
| 505 | * "pass"=>"big secret", |
---|
| 506 | * "server"=>"calendar.foo.bar", |
---|
| 507 | * "port"=>"80", |
---|
| 508 | * "uri"=>"http://calendar.foo.bar/caldav.php/some_user/home/", |
---|
| 509 | * ); |
---|
| 510 | * //******************************* |
---|
| 511 | * |
---|
| 512 | * $account = $acc["davical"]; |
---|
| 513 | * |
---|
| 514 | * //******************************* |
---|
| 515 | * $cal = new CalDAVClient( $account["uri"], $account["user"], $account["pass"], "", $account["server"], $account["port"] ); |
---|
| 516 | * $options = $cal->DoOptionsRequest(); |
---|
| 517 | * print_r($options); |
---|
| 518 | * |
---|
| 519 | * //******************************* |
---|
| 520 | * //******************************* |
---|
| 521 | * |
---|
| 522 | * $xmlC = <<<PROPP |
---|
| 523 | * <?xml version="1.0" encoding="utf-8" ?> |
---|
| 524 | * <D:propfind xmlns:D="DAV:" xmlns:C="http://calendarserver.org/ns/"> |
---|
| 525 | * <D:prop> |
---|
| 526 | * <D:displayname /> |
---|
| 527 | * <C:getctag /> |
---|
| 528 | * <D:resourcetype /> |
---|
| 529 | * |
---|
| 530 | * </D:prop> |
---|
| 531 | * </D:propfind> |
---|
| 532 | * PROPP; |
---|
| 533 | * //if ( isset($options["PROPFIND"]) ) { |
---|
| 534 | * // Fetch some information about the events in that calendar |
---|
| 535 | * // $cal->SetDepth(1); |
---|
| 536 | * // $folder_xml = $cal->DoXMLRequest("PROPFIND", $xmlC); |
---|
| 537 | * // print_r( $folder_xml); |
---|
| 538 | * //} |
---|
| 539 | * |
---|
| 540 | * // Fetch all events for February |
---|
| 541 | * $events = $cal->GetEvents("20090201T000000Z","20090301T000000Z"); |
---|
| 542 | * foreach ( $events as $k => $event ) { |
---|
| 543 | * print_r($event['data']); |
---|
| 544 | * print "\n---------------------------------------------\n"; |
---|
| 545 | * } |
---|
| 546 | * |
---|
| 547 | * //******************************* |
---|
| 548 | * //******************************* |
---|
| 549 | */ |
---|