From ebef19f81d8d89eb846585134f94bee504832a99 Mon Sep 17 00:00:00 2001 From: Rico Kritz Date: Mon, 9 Apr 2018 14:55:45 +0200 Subject: [PATCH 01/10] fixed lots of typos, missing parameter types, return types and @throw tags in SimpleCalDAVClient's PHPDoc which makes it much easier to work with this package in PHP IDEs (like PHPStorm e.g.) and added support for DateTime objects in getEvents and getTODOs (see convertToGmtString in SimpleCalDAVClient) --- CalDAVClient.php | 2 +- SimpleCalDAVClient.php | 178 +++++++++++++++++++++++++---------------- 2 files changed, 108 insertions(+), 72 deletions(-) diff --git a/CalDAVClient.php b/CalDAVClient.php index 10a2eb6..89f0a16 100644 --- a/CalDAVClient.php +++ b/CalDAVClient.php @@ -1065,7 +1065,7 @@ function GetEntryByUid( $uid, $relative_url = null ) { * * @param string $href The href from a call to GetEvents or GetTodos etc. * - * @return string The iCalendar of the calendar entry + * @return array The iCalendar of the calendar entry */ function GetEntryByHref( $href ) { //$href = str_replace( rawurlencode('/'),'/',rawurlencode($href)); diff --git a/SimpleCalDAVClient.php b/SimpleCalDAVClient.php index 2cebbea..b58aee4 100644 --- a/SimpleCalDAVClient.php +++ b/SimpleCalDAVClient.php @@ -48,6 +48,8 @@ require_once('CalDAVObject.php'); class SimpleCalDAVClient { + + /** @var CalDAVClient $client */ private $client; private $url; @@ -56,15 +58,15 @@ class SimpleCalDAVClient { * Connects to a CalDAV-Server. * * Arguments: - * @param $url URL to the CalDAV-server. E.g. http://exam.pl/baikal/cal.php/username/calendername/ - * @param $user Username to login with - * @param $pass Password to login with + * @param string $url URL to the CalDAV-server. E.g. http://exam.pl/baikal/cal.php/username/calendername/ + * @param string $user Username to login with + * @param string $pass Password to login with * * Debugging: * @throws CalDAVException - * For debugging purposes, just sorround everything with try { ... } catch (Exception $e) { echo $e->__toString(); } + * For debugging purposes, just surround everything with try { ... } catch (Exception $e) { echo $e->__toString(); } */ - function connect ( $url, $user, $pass ) + public function connect ( $url, $user, $pass ) { // Connect to CalDAV-Server and log in @@ -101,7 +103,7 @@ function connect ( $url, $user, $pass ) else // Unknown status { - throw new CalDAVException('Recieved unknown HTTP status while checking the connection after establishing it', $client); + throw new CalDAVException('Received unknown HTTP status while checking the connection after establishing it', $client); } } @@ -114,13 +116,13 @@ function connect ( $url, $user, $pass ) * Requests a list of all accessible calendars on the server * * Return value: - * @return an array of CalDAVCalendar-Objects (see CalDAVCalendar.php), representing all calendars accessible by the current principal (user). + * @return CalDAVCalendar[] an array of CalDAVCalendar-Objects (see CalDAVCalendar.php), representing all calendars accessible by the current principal (user). * * Debugging: - * @throws CalDAVException - * For debugging purposes, just sorround everything with try { ... } catch (Exception $e) { echo $e->__toString(); exit(-1); } + * @throws Exception + * For debugging purposes, just surround everything with try { ... } catch (Exception $e) { echo $e->__toString(); exit(-1); } */ - function findCalendars() + public function findCalendars() { if(!isset($this->client)) throw new Exception('No connection. Try connect().'); @@ -130,13 +132,16 @@ function findCalendars() /** * function setCalendar() * - * Sets the actual calendar to work with + * Sets the current calendar to work with + * + * Arguments: + * @param CalDAVCalendar $calendar Calendar to be set as current calendar. * * Debugging: - * @throws CalDAVException - * For debugging purposes, just sorround everything with try { ... } catch (Exception $e) { echo $e->__toString(); exit(-1); } + * @throws Exception + * For debugging purposes, just surround everything with try { ... } catch (Exception $e) { echo $e->__toString(); exit(-1); } */ - function setCalendar ( CalDAVCalendar $calendar ) + public function setCalendar ( CalDAVCalendar $calendar ) { if(!isset($this->client)) throw new Exception('No connection. Try connect().'); @@ -156,13 +161,14 @@ function setCalendar ( CalDAVCalendar $calendar ) * Notice: The iCalendar-data contains the unique ID which specifies where the event is being saved. * * Return value: - * @return An CalDAVObject-representation (see CalDAVObject.php) of your created resource + * @return CalDAVObject An CalDAVObject-representation (see CalDAVObject.php) of your created resource * * Debugging: + * @throws Exception * @throws CalDAVException - * For debugging purposes, just sorround everything with try { ... } catch (Exception $e) { echo $e->__toString(); exit(-1); } + * For debugging purposes, just surround everything with try { ... } catch (Exception $e) { echo $e->__toString(); exit(-1); } */ - function create ( $cal ) + public function create ( $cal ) { // Connection and calendar set? if(!isset($this->client)) throw new Exception('No connection. Try connect().'); @@ -176,12 +182,12 @@ function create ( $cal ) $result = $this->client->GetEntryByHref( $this->url.$uid.'.ics' ); if ( $this->client->GetHttpResultCode() == '200' ) { throw new CalDAVException($this->url.$uid.'.ics already exists. UID not unique?', $this->client); } else if ( $this->client->GetHttpResultCode() == '404' ); - else throw new CalDAVException('Recieved unknown HTTP status', $this->client); + else throw new CalDAVException('Received unknown HTTP status', $this->client); // Put it! $newEtag = $this->client->DoPUTRequest( $this->url.$uid.'.ics', $cal ); - - // PUT-request successfull? + + // PUT-request successful? if ( $this->client->GetHttpResultCode() != '201' ) { if ( $this->client->GetHttpResultCode() == '204' ) // $url.$uid.'.ics' already existed on server @@ -191,7 +197,7 @@ function create ( $cal ) else // Unknown status { - throw new CalDAVException('Recieved unknown HTTP status', $this->client); + throw new CalDAVException('Received unknown HTTP status', $this->client); } } @@ -203,18 +209,19 @@ function create ( $cal ) * Changes a calendar resource (event, todo, etc.) on the CalDAV-Server. * * Arguments: - * @param $href See CalDAVObject.php - * @param $cal The new iCalendar-data that should be used to overwrite the old one. - * @param $etag See CalDAVObject.php + * @param string $href See CalDAVObject.php + * @param string $new_data The new iCalendar-data that should be used to overwrite the old one. + * @param string $etag See CalDAVObject.php * * Return value: - * @return An CalDAVObject-representation (see CalDAVObject.php) of your changed resource + * @return CalDAVObject An CalDAVObject-representation (see CalDAVObject.php) of your changed resource * * Debugging: + * @throws Exception * @throws CalDAVException - * For debugging purposes, just sorround everything with try { ... } catch (Exception $e) { echo $e->__toString(); exit(-1); } + * For debugging purposes, just surround everything with try { ... } catch (Exception $e) { echo $e->__toString(); exit(-1); } */ - function change ( $href, $new_data, $etag ) + public function change ( $href, $new_data, $etag ) { // Connection and calendar set? if(!isset($this->client)) throw new Exception('No connection. Try connect().'); @@ -222,9 +229,9 @@ function change ( $href, $new_data, $etag ) // Does $href exist? $result = $this->client->GetEntryByHref($href); - if ( $this->client->GetHttpResultCode() == '200' ); + if ( $this->client->GetHttpResultCode() == '200' ); else if ( $this->client->GetHttpResultCode() == '404' ) throw new CalDAVException('Can\'t find '.$href.' on the server', $this->client); - else throw new CalDAVException('Recieved unknown HTTP status', $this->client); + else throw new CalDAVException('Received unknown HTTP status', $this->client); // $etag correct? if($result[0]['etag'] != $etag) { throw new CalDAVException('Wrong entity tag. The entity seems to have changed.', $this->client); } @@ -232,10 +239,10 @@ function change ( $href, $new_data, $etag ) // Put it! $newEtag = $this->client->DoPUTRequest( $href, $new_data, $etag ); - // PUT-request successfull? + // PUT-request successful? if ( $this->client->GetHttpResultCode() != '204' && $this->client->GetHttpResultCode() != '200' ) { - throw new CalDAVException('Recieved unknown HTTP status', $this->client); + throw new CalDAVException('Received unknown HTTP status', $this->client); } return new CalDAVObject($href, $new_data, $newEtag); @@ -243,17 +250,18 @@ function change ( $href, $new_data, $etag ) /** * function delete() - * Delets an event or a TODO from the CalDAV-Server. + * Deletes an event or a TODO from the CalDAV-Server. * * Arguments: - * @param $href See CalDAVObject.php - * @param $etag See CalDAVObject.php + * @param string $href See CalDAVObject.php + * @param string $etag See CalDAVObject.php * * Debugging: + * @throws Exception * @throws CalDAVException - * For debugging purposes, just sorround everything with try { ... } catch (Exception $e) { echo $e->__toString(); exit(-1); } + * For debugging purposes, just surround everything with try { ... } catch (Exception $e) { echo $e->__toString(); exit(-1); } */ - function delete ( $href, $etag ) + public function delete ( $href, $etag ) { // Connection and calendar set? if(!isset($this->client)) throw new Exception('No connection. Try connect().'); @@ -269,10 +277,10 @@ function delete ( $href, $etag ) // Do the deletion $this->client->DoDELETERequest($href, $etag); - // Deletion successfull? + // Deletion successful? if ( $this->client->GetHttpResultCode() != '200' and $this->client->GetHttpResultCode() != '204' ) { - throw new CalDAVException('Recieved unknown HTTP status', $this->client); + throw new CalDAVException('Received unknown HTTP status', $this->client); } } @@ -281,36 +289,37 @@ function delete ( $href, $etag ) * Gets a all events from the CalDAV-Server which lie in a defined time interval. * * Arguments: - * @param $start The starting point of the time interval. Must be in the format yyyymmddThhmmssZ and should be in - * GMT. If omitted the value is set to -infinity. - * @param $end The end point of the time interval. Must be in the format yyyymmddThhmmssZ and should be in - * GMT. If omitted the value is set to +infinity. + * @param DateTime|string|null $start The starting point of the time interval. Must be in the format yyyymmddThhmmssZ and should be in + * GMT. If omitted the value is set to -infinity. + * @param DateTime|string|null $end The end point of the time interval. Must be in the format yyyymmddThhmmssZ and should be in + * GMT. If omitted the value is set to +infinity. * * Return value: - * @return an array of CalDAVObjects (See CalDAVObject.php), representing the found events. + * @return \CalDAVObject[] an array of CalDAVObjects (See CalDAVObject.php), representing the found events. * * Debugging: + * @throws Exception * @throws CalDAVException - * For debugging purposes, just sorround everything with try { ... } catch (Exception $e) { echo $e->__toString(); exit(-1); } + * For debugging purposes, just surround everything with try { ... } catch (Exception $e) { echo $e->__toString(); exit(-1); } */ - function getEvents ( $start = null, $end = null ) + public function getEvents ( $start = null, $end = null ) { // Connection and calendar set? if(!isset($this->client)) throw new Exception('No connection. Try connect().'); if(!isset($this->client->calendar_url)) throw new Exception('No calendar selected. Try findCalendars() and setCalendar().'); // Are $start and $end in the correct format? - if ( ( isset($start) and ! preg_match( '#^\d\d\d\d\d\d\d\dT\d\d\d\d\d\dZ$#', $start, $matches ) ) - or ( isset($end) and ! preg_match( '#^\d\d\d\d\d\d\d\dT\d\d\d\d\d\dZ$#', $end, $matches ) ) ) - { trigger_error('$start or $end are in the wrong format. They must have the format yyyymmddThhmmssZ and should be in GMT', E_USER_ERROR); } + $start = $this->convertToGmtString($start); + $end = $this->convertToGmtString($end); + // Get it! $results = $this->client->GetEvents( $start, $end ); - // GET-request successfull? + // GET-request successful? if ( $this->client->GetHttpResultCode() != '207' ) { - throw new CalDAVException('Recieved unknown HTTP status', $this->client); + throw new CalDAVException('Received unknown HTTP status', $this->client); } // Reformat @@ -326,38 +335,38 @@ function getEvents ( $start = null, $end = null ) * given criteria. * * Arguments: - * @param $start The starting point of the time interval. Must be in the format yyyymmddThhmmssZ and should be in - * GMT. If omitted the value is set to -infinity. - * @param $end The end point of the time interval. Must be in the format yyyymmddThhmmssZ and should be in - * GMT. If omitted the value is set to +infinity. - * @param $complete Filter for completed tasks (true) or for uncompleted tasks (false). If omitted, the function will return both. - * @param $cancelled Filter for cancelled tasks (true) or for uncancelled tasks (false). If omitted, the function will return both. + * @param DateTime|string|null $start The starting point of the time interval. Must be in the format yyyymmddThhmmssZ and should be in + * GMT. If omitted the value is set to -infinity. + * @param DateTime|string|null $end The end point of the time interval. Must be in the format yyyymmddThhmmssZ and should be in + * GMT. If omitted the value is set to +infinity. + * @param bool $completed Filter for completed tasks (true) or for uncompleted tasks (false). If omitted, the function will return both. + * @param bool $cancelled Filter for cancelled tasks (true) or for uncancelled tasks (false). If omitted, the function will return both. * * Return value: - * @return an array of CalDAVObjects (See CalDAVObject.php), representing the found TODOs. + * @return CalDAVObject[] an array of CalDAVObjects (See CalDAVObject.php), representing the found TODOs. * * Debugging: + * @throws Exception * @throws CalDAVException - * For debugging purposes, just sorround everything with try { ... } catch (Exception $e) { echo $e->__toString(); exit(-1); } + * For debugging purposes, just surround everything with try { ... } catch (Exception $e) { echo $e->__toString(); exit(-1); } */ - function getTODOs ( $start = null, $end = null, $completed = null, $cancelled = null ) + public function getTODOs ( $start = null, $end = null, $completed = null, $cancelled = null ) { // Connection and calendar set? if(!isset($this->client)) throw new Exception('No connection. Try connect().'); if(!isset($this->client->calendar_url)) throw new Exception('No calendar selected. Try findCalendars() and setCalendar().'); // Are $start and $end in the correct format? - if ( ( isset($start) and ! preg_match( '#^\d\d\d\d\d\d\d\dT\d\d\d\d\d\dZ$#', $start, $matches ) ) - or ( isset($end) and ! preg_match( '#^\d\d\d\d\d\d\d\dT\d\d\d\d\d\dZ$#', $end, $matches ) ) ) - { trigger_error('$start or $end are in the wrong format. They must have the format yyyymmddThhmmssZ and should be in GMT', E_USER_ERROR); } - + $start = $this->convertToGmtString($start); + $end = $this->convertToGmtString($end); + // Get it! $results = $this->client->GetTodos( $start, $end, $completed, $cancelled ); - // GET-request successfull? + // GET-request successful? if ( $this->client->GetHttpResultCode() != '207' ) { - throw new CalDAVException('Recieved unknown HTTP status', $this->client); + throw new CalDAVException('Received unknown HTTP status', $this->client); } // Reformat @@ -377,16 +386,17 @@ function getTODOs ( $start = null, $end = null, $completed = null, $cancelled = * See http://www.rfcreader.com/#rfc4791_line1524 for more information about how to write filters on your own. * * Arguments: - * @param $filterXML The stuff, you want to send encapsulated in the -tag. + * @param string $filterXML The stuff, you want to send encapsulated in the -tag. * * Return value: - * @return an array of CalDAVObjects (See CalDAVObject.php), representing the found calendar resources. + * @return CalDAVObject[] an array of CalDAVObjects (See CalDAVObject.php), representing the found calendar resources. * * Debugging: + * @throws Exception * @throws CalDAVException - * For debugging purposes, just sorround everything with try { ... } catch (Exception $e) { echo $e->__toString(); exit(-1); } + * For debugging purposes, just surround everything with try { ... } catch (Exception $e) { echo $e->__toString(); exit(-1); } */ - function getCustomReport ( $filterXML ) + public function getCustomReport ( $filterXML ) { // Connection and calendar set? if(!isset($this->client)) throw new Exception('No connection. Try connect().'); @@ -398,10 +408,10 @@ function getCustomReport ( $filterXML ) // Get it! $results = $this->client->DoCalendarQuery(''.$filterXML.''); - // GET-request successfull? + // GET-request successful? if ( $this->client->GetHttpResultCode() != '207' ) { - throw new CalDAVException('Recieved unknown HTTP status', $this->client); + throw new CalDAVException('Received unknown HTTP status', $this->client); } // Reformat @@ -410,6 +420,32 @@ function getCustomReport ( $filterXML ) return $report; } + + + /** + * Converts the given time to a string in the following format: yyyymmddThhmmssZ where T and Z + * are the letters themselves. + * @param DateTime|string|null $time Time to be converted. When given as null it will be + * directly returned as null. When given as string in a wrong format an error will get + * triggered. + * @return null|string + */ + protected function convertToGmtString($time) + { + if (!isset($time)) return null; + + // Convert $time from DateTime object to string in GMT/UTC time. + if ($time instanceof DateTime) + { + $time->setTimezone(new DateTimeZone('GMT')); + $time = $time->format('Ymd\THis\Z'); + } + // Check format + elseif ( ! preg_match( '/^\d{8}T\d{6}Z$/', $time ) ) + trigger_error('$start or $end are in the wrong format. They must have the format yyyymmddThhmmssZ and should be in GMT', E_USER_ERROR); + + return $time; + } } ?> From 6200fe854a103c12334e423e9c24f586477c373a Mon Sep 17 00:00:00 2001 From: Rico Kritz Date: Tue, 10 Apr 2018 09:27:25 +0200 Subject: [PATCH 02/10] added another missing PHPDoc parameter type --- SimpleCalDAVClient.php | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/SimpleCalDAVClient.php b/SimpleCalDAVClient.php index b58aee4..0d3e3aa 100644 --- a/SimpleCalDAVClient.php +++ b/SimpleCalDAVClient.php @@ -147,9 +147,8 @@ public function setCalendar ( CalDAVCalendar $calendar ) $this->client->SetCalendar($this->client->first_url_part.$calendar->getURL()); - // Is there a '/' at the end of the calendar_url? - if ( ! preg_match( '#^.*?/$#', $this->client->calendar_url, $matches ) ) { $this->url = $this->client->calendar_url.'/'; } - else { $this->url = $this->client->calendar_url; } + // Add trailing slash to url if not already existing. + $this->url = preg_replace('#(?client->calendar_url); } /** @@ -157,8 +156,8 @@ public function setCalendar ( CalDAVCalendar $calendar ) * Creates a new calendar resource on the CalDAV-Server (event, todo, etc.). * * Arguments: - * @param $cal iCalendar-data of the resource you want to create. - * Notice: The iCalendar-data contains the unique ID which specifies where the event is being saved. + * @param string $cal iCalendar-data of the resource you want to create. + * Notice: The iCalendar-data contains the unique ID which specifies where the event is being saved. * * Return value: * @return CalDAVObject An CalDAVObject-representation (see CalDAVObject.php) of your created resource From 0a9d6ba683a721a163717a3647de44b1b95ccbcd Mon Sep 17 00:00:00 2001 From: Rico Kritz Date: Tue, 10 Apr 2018 11:05:52 +0200 Subject: [PATCH 03/10] CalDAVObject has the CalDAVCalendar it was fetched from as property now --- CalDAVObject.php | 28 ++++++++++++++++++++++++++-- SimpleCalDAVClient.php | 24 ++++++++++++++++++------ 2 files changed, 44 insertions(+), 8 deletions(-) diff --git a/CalDAVObject.php b/CalDAVObject.php index 6cf94c4..df5324a 100644 --- a/CalDAVObject.php +++ b/CalDAVObject.php @@ -16,6 +16,7 @@ * The assignment of an entity tag ensures, that you know what you are changing/deleting. It ensures, that no one * changed the resource between your viewing of the resource and your change/delete-request. Assigning an entity tag * provides you of accidently destroying the work of others. + * cal: The {@link CalDAVCalendar} this object belongs to. * * @package simpleCalDAV * @@ -26,26 +27,49 @@ class CalDAVObject { private $data; private $etag; - public function __construct ($href, $data, $etag) { + /** + * @param string $href + * @param string $data + * @param string $etag + * @param CalDAVCalendar|null $cal + */ + public function __construct ($href, $data, $etag, $cal = null) { $this->href = $href; $this->data = $data; $this->etag = $etag; + $this->cal = $cal; } // Getter - + /** + * @return string + */ public function getHref () { return $this->href; } + /** + * @return string + */ public function getData () { return $this->data; } + /** + * @return string + */ public function getEtag () { return $this->etag; } + + /** + * Returns the {@link CalDAVCalendar} this object belongs to. + * @return CalDAVCalendar|null + */ + public function getCalendar() { + return $this->cal; + } } ?> \ No newline at end of file diff --git a/SimpleCalDAVClient.php b/SimpleCalDAVClient.php index 0d3e3aa..52f09c8 100644 --- a/SimpleCalDAVClient.php +++ b/SimpleCalDAVClient.php @@ -49,6 +49,8 @@ class SimpleCalDAVClient { + /** @var CalDAVCalendar|null $calendar The currently set calendar. */ + private $calendar; /** @var CalDAVClient $client */ private $client; private $url; @@ -145,6 +147,7 @@ public function setCalendar ( CalDAVCalendar $calendar ) { if(!isset($this->client)) throw new Exception('No connection. Try connect().'); + $this->calendar = $calendar; $this->client->SetCalendar($this->client->first_url_part.$calendar->getURL()); // Add trailing slash to url if not already existing. @@ -200,7 +203,7 @@ public function create ( $cal ) } } - return new CalDAVObject($this->url.$uid.'.ics', $cal, $newEtag); + return new CalDAVObject($this->url.$uid.'.ics', $cal, $newEtag, $this->calendar); } /** @@ -244,7 +247,7 @@ public function change ( $href, $new_data, $etag ) throw new CalDAVException('Received unknown HTTP status', $this->client); } - return new CalDAVObject($href, $new_data, $newEtag); + return new CalDAVObject($href, $new_data, $newEtag, $this->calendar); } /** @@ -323,7 +326,7 @@ public function getEvents ( $start = null, $end = null ) // Reformat $report = array(); - foreach($results as $event) $report[] = new CalDAVObject($this->url.$event['href'], $event['data'], $event['etag']); + foreach($results as $event) $report[] = new CalDAVObject($this->url.$event['href'], $event['data'], $event['etag'], $this->calendar); return $report; } @@ -370,11 +373,20 @@ public function getTODOs ( $start = null, $end = null, $completed = null, $cance // Reformat $report = array(); - foreach($results as $event) $report[] = new CalDAVObject($this->url.$event['href'], $event['data'], $event['etag']); + foreach($results as $event) $report[] = new CalDAVObject($this->url.$event['href'], $event['data'], $event['etag'], $this->calendar); return $report; } - + + /** + * Returns the currently selected {@link CalDAVCalendar calendar} or null if none is selected. + * @return CalDAVCalendar|null + */ + public function getCalendar() + { + return $this->calendar; + } + /** * function getCustomReport() * Sends a custom request to the server @@ -415,7 +427,7 @@ public function getCustomReport ( $filterXML ) // Reformat $report = array(); - foreach($results as $event) $report[] = new CalDAVObject($this->url.$event['href'], $event['data'], $event['etag']); + foreach($results as $event) $report[] = new CalDAVObject($this->url.$event['href'], $event['data'], $event['etag'], $this->calendar); return $report; } From cdf6ab3d5cb39d4c23bdfc4d2c455b3fc6619d77 Mon Sep 17 00:00:00 2001 From: Rico Kritz Date: Tue, 10 Apr 2018 11:16:39 +0200 Subject: [PATCH 04/10] moved the multiple times used client and calendar checks into separate functions to increase code readability and reduce redundancy --- SimpleCalDAVClient.php | 52 +++++++++++++++++++++++++++++------------- 1 file changed, 36 insertions(+), 16 deletions(-) diff --git a/SimpleCalDAVClient.php b/SimpleCalDAVClient.php index 52f09c8..2698480 100644 --- a/SimpleCalDAVClient.php +++ b/SimpleCalDAVClient.php @@ -78,7 +78,7 @@ public function connect ( $url, $user, $pass ) if( ! $client->isValidCalDAVServer() ) { - if( $client->GetHttpResultCode() == '401' ) // unauthorisized + if( $client->GetHttpResultCode() == '401' ) // unauthorized { throw new CalDAVException('Login failed', $client); } @@ -93,7 +93,7 @@ public function connect ( $url, $user, $pass ) // Check for errors if( $client->GetHttpResultCode() != '200' ) { - if( $client->GetHttpResultCode() == '401' ) // unauthorisized + if( $client->GetHttpResultCode() == '401' ) // unauthorized { throw new CalDAVException('Login failed', $client); } @@ -126,7 +126,7 @@ public function connect ( $url, $user, $pass ) */ public function findCalendars() { - if(!isset($this->client)) throw new Exception('No connection. Try connect().'); + $this->checkClient(); return $this->client->FindCalendars(true); } @@ -145,7 +145,7 @@ public function findCalendars() */ public function setCalendar ( CalDAVCalendar $calendar ) { - if(!isset($this->client)) throw new Exception('No connection. Try connect().'); + $this->checkClient(); $this->calendar = $calendar; $this->client->SetCalendar($this->client->first_url_part.$calendar->getURL()); @@ -173,8 +173,7 @@ public function setCalendar ( CalDAVCalendar $calendar ) public function create ( $cal ) { // Connection and calendar set? - if(!isset($this->client)) throw new Exception('No connection. Try connect().'); - if(!isset($this->client->calendar_url)) throw new Exception('No calendar selected. Try findCalendars() and setCalendar().'); + $this->checkCalendar(); // Parse $cal for UID if (! preg_match( '#^UID:(.*?)\r?\n?$#m', $cal, $matches ) ) { throw new Exception('Can\'t find UID in $cal'); } @@ -226,8 +225,7 @@ public function create ( $cal ) public function change ( $href, $new_data, $etag ) { // Connection and calendar set? - if(!isset($this->client)) throw new Exception('No connection. Try connect().'); - if(!isset($this->client->calendar_url)) throw new Exception('No calendar selected. Try findCalendars() and setCalendar().'); + $this->checkCalendar(); // Does $href exist? $result = $this->client->GetEntryByHref($href); @@ -266,8 +264,7 @@ public function change ( $href, $new_data, $etag ) public function delete ( $href, $etag ) { // Connection and calendar set? - if(!isset($this->client)) throw new Exception('No connection. Try connect().'); - if(!isset($this->client->calendar_url)) throw new Exception('No calendar selected. Try findCalendars() and setCalendar().'); + $this->checkCalendar(); // Does $href exist? $result = $this->client->GetEntryByHref($href); @@ -307,8 +304,7 @@ public function delete ( $href, $etag ) public function getEvents ( $start = null, $end = null ) { // Connection and calendar set? - if(!isset($this->client)) throw new Exception('No connection. Try connect().'); - if(!isset($this->client->calendar_url)) throw new Exception('No calendar selected. Try findCalendars() and setCalendar().'); + $this->checkCalendar(); // Are $start and $end in the correct format? $start = $this->convertToGmtString($start); @@ -355,8 +351,7 @@ public function getEvents ( $start = null, $end = null ) public function getTODOs ( $start = null, $end = null, $completed = null, $cancelled = null ) { // Connection and calendar set? - if(!isset($this->client)) throw new Exception('No connection. Try connect().'); - if(!isset($this->client->calendar_url)) throw new Exception('No calendar selected. Try findCalendars() and setCalendar().'); + $this->checkCalendar(); // Are $start and $end in the correct format? $start = $this->convertToGmtString($start); @@ -410,8 +405,7 @@ public function getCalendar() public function getCustomReport ( $filterXML ) { // Connection and calendar set? - if(!isset($this->client)) throw new Exception('No connection. Try connect().'); - if(!isset($this->client->calendar_url)) throw new Exception('No calendar selected. Try findCalendars() and setCalendar().'); + $this->checkCalendar(); // Get report! $this->client->SetDepth('1'); @@ -432,6 +426,32 @@ public function getCustomReport ( $filterXML ) return $report; } + /** + * Checks whether a calendar is selected and throws an exception if not. Also calls {@link checkClient} before. + * @throws Exception + * @return bool + */ + protected function checkCalendar() + { + $this->checkClient(); + if (!isset($this->client->calendar_url)) + throw new Exception('No calendar selected. Try findCalendars() and setCalendar().'); + + return true; + } + + /** + * Checks whether the client is set properly and throws an exception if not. + * @throws Exception + * @return bool + */ + protected function checkClient() + { + if (!isset($this->client)) + throw new Exception('No connection. Try connect().'); + + return true; + } /** * Converts the given time to a string in the following format: yyyymmddThhmmssZ where T and Z From b4837a3b3a7d3e73f8341ab7b73f9e70d50230cb Mon Sep 17 00:00:00 2001 From: Rico Kritz Date: Tue, 10 Apr 2018 11:42:47 +0200 Subject: [PATCH 05/10] added getAllEvents and getAllTODOs function that can fetch events and todos from all available calendars --- SimpleCalDAVClient.php | 83 +++++++++++++++++++++++++++++++++++++++--- 1 file changed, 77 insertions(+), 6 deletions(-) diff --git a/SimpleCalDAVClient.php b/SimpleCalDAVClient.php index 2698480..bcc643c 100644 --- a/SimpleCalDAVClient.php +++ b/SimpleCalDAVClient.php @@ -14,11 +14,14 @@ * - connect() * - findCalendars() * - setCalendar() + * - getCalendar() * - create() * - change() * - delete() * - getEvents() + * - getAllEvents() * - getTODOs() + * - getAllTODOs() * - getCustomReport() * * All of those functions - except the last one - are realy easy to use, self-explanatory and are @@ -285,7 +288,8 @@ public function delete ( $href, $etag ) /** * function getEvents() - * Gets a all events from the CalDAV-Server which lie in a defined time interval. + * Gets all events from the current calendar on the CalDAV-Server which lie in a defined time + * interval. * * Arguments: * @param DateTime|string|null $start The starting point of the time interval. Must be in the format yyyymmddThhmmssZ and should be in @@ -310,7 +314,6 @@ public function getEvents ( $start = null, $end = null ) $start = $this->convertToGmtString($start); $end = $this->convertToGmtString($end); - // Get it! $results = $this->client->GetEvents( $start, $end ); @@ -326,19 +329,52 @@ public function getEvents ( $start = null, $end = null ) return $report; } + + /** + * Returns all the events from all available calendars passing its parameters directly to + * {@link getEvents}. + * + * @param DateTime|string|null $start Interval start as either DateTime object or GMT string (yyyymmddThhmmssZ). + * @param DateTime|string|null $end Interval end as either DateTime object or GMT string (yyyymmddThhmmssZ). + * + * @return CalDAVObject[] + * + * @throws Exception + * @throws CalDAVException + */ + public function getAllEvents($start = null, $end = null) + { + // remember the current calendar + $current_calendar = $this->getCalendar(); + + // fetch all events + $events = array(); + foreach ($this->findCalendars() as $calendar) { + $this->setCalendar($calendar); + $events[] = $this->getEvents($start, $end); + } + + // flatten two dimensional array + $events = call_user_func_array('array_merge', $events); + + // restore previously set calendar + $this->setCalendar($current_calendar); + + return $events; + } /** * function getTODOs() - * Gets a all TODOs from the CalDAV-Server which lie in a defined time interval and match the - * given criteria. + * Gets all TODOs from the current calendar on the CalDAV-Server which lie in a defined time + * interval and match the given criteria. * * Arguments: * @param DateTime|string|null $start The starting point of the time interval. Must be in the format yyyymmddThhmmssZ and should be in * GMT. If omitted the value is set to -infinity. * @param DateTime|string|null $end The end point of the time interval. Must be in the format yyyymmddThhmmssZ and should be in * GMT. If omitted the value is set to +infinity. - * @param bool $completed Filter for completed tasks (true) or for uncompleted tasks (false). If omitted, the function will return both. - * @param bool $cancelled Filter for cancelled tasks (true) or for uncancelled tasks (false). If omitted, the function will return both. + * @param bool|null $completed Filter for completed tasks (true) or for uncompleted tasks (false). If omitted, the function will return both. + * @param bool|null $cancelled Filter for cancelled tasks (true) or for uncancelled tasks (false). If omitted, the function will return both. * * Return value: * @return CalDAVObject[] an array of CalDAVObjects (See CalDAVObject.php), representing the found TODOs. @@ -373,6 +409,41 @@ public function getTODOs ( $start = null, $end = null, $completed = null, $cance return $report; } + /** + * Returns all the TODOs from all available calendars passing its parameters directly to + * {@link getTodos}. + * + * @param DateTime|string|null $start Interval start as either DateTime object or GMT string (yyyymmddThhmmssZ). + * @param DateTime|string|null $end Interval end as either DateTime object or GMT string (yyyymmddThhmmssZ). + * @param bool|null $completed Returns completed (true), uncompleted (false) or both (null). + * @param bool|null $cancelled Returns cancelled (true), uncancelled (false) or both (null). + * + * @return CalDAVObject[] + * + * @throws Exception + * @throws CalDAVException + */ + public function getAllTODOs($start = null, $end = null, $completed = null, $cancelled = null) + { + // remember the current calendar + $current_calendar = $this->getCalendar(); + + // fetch all TODOs + $todos = array(); + foreach ($this->findCalendars() as $calendar) { + $this->setCalendar($calendar); + $todos[] = $this->getTODOs($start, $end, $completed, $cancelled); + } + + // flatten two dimensional array + $todos = call_user_func_array('array_merge', $todos); + + // restore previously set calendar + $this->setCalendar($current_calendar); + + return $todos; + } + /** * Returns the currently selected {@link CalDAVCalendar calendar} or null if none is selected. * @return CalDAVCalendar|null From 87d08b79b858285ebc86bb52cf8f8724b634c6de Mon Sep 17 00:00:00 2001 From: Rico Kritz Date: Tue, 10 Apr 2018 12:16:47 +0200 Subject: [PATCH 06/10] renamed README to README.md (Markdown) --- README => README.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename README => README.md (100%) diff --git a/README b/README.md similarity index 100% rename from README rename to README.md From 5f9fe84b8d2f7585a8b0ade1f6fecdb0fb3045b4 Mon Sep 17 00:00:00 2001 From: Rico Kritz Date: Tue, 10 Apr 2018 12:22:21 +0200 Subject: [PATCH 07/10] changed README to Markdown syntax --- README.md | 53 ++++++++++++++++++++++++++++++++++------------------- 1 file changed, 34 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index cd39f07..0a446de 100644 --- a/README.md +++ b/README.md @@ -1,59 +1,74 @@ simpleCalDAV +============ Copyright 2014 Michael Palm -Table of content -1. About -2. Requirements -3. Installation -4. How to get started -5. Example Code +Table of contents +----------------- + +1. [About](#1-about) +2. [Requirements](#2-requirements) +3. [Installation](#3-installation) +4. [How to get started](#4-how-to-get-started) +5. [Example Code](#5-example-code) ------------------------ -1. About +## 1. About -simpleCalDAV is a php library that allows you to connect to a calDAV-server to get event-, todo- and free/busy-calendar resources from the server, to change them, to delete them, to create new ones, etc. -simpleCalDAV was made and tested for connections to the CalDAV-server Baikal 0.2.7. But it should work with any other CalDAV-server too. +simpleCalDAV is a php library that allows you to connect to a calDAV-server to get event-, todo- +and free/busy-calendar resources from the server, to change them, to delete them, to create new +ones, etc. +simpleCalDAV was made and tested for connections to the CalDAV-server Baikal 0.2.7. But it should +work with any other CalDAV-server too. It contains the following functions: - connect() - findCalendars() - setCalendar() + - getCalendar() - create() - change() - delete() - getEvents() + - getAllEvents() - getTODOs() + - getAllTODOs() - getCustomReport() -All of those functions are really easy to use, self-explanatory and are deliverd with a big innitial comment, which explains all needed arguments and the return values. +All of those functions are really easy to use, self-explanatory and are delivered with a big initial +comment, which explains all needed arguments and the return values. -This library is heavily based on AgenDAV caldav-client-v2.php by Jorge López Pérez which again is heavily based on DAViCal caldav-client-v2.php by Andrew McMillan . -Actually, I hardly added any features. The main point of my work is to make everything straight forward and easy to use. You can use simpleCalDAV whithout a deeper understanding of the calDAV-protocol. +This library is heavily based on AgenDAV caldav-client-v2.php by Jorge López Pérez +which again is heavily based on DAViCal caldav-client-v2.php by Andrew McMillan +. +Actually, I hardly added any features. The main point of my work is to make everything straight +forward and easy to use. You can use simpleCalDAV whithout a deeper understanding of the +calDAV-protocol. -2. Requirements +## 2. Requirements Requirements of this library are - The php extension cURL ( http://www.php.net/manual/en/book.curl.php ) -3. Installation +## 3. Installation Just navigate into a directory on your server and execute -git clone https://github.com/wvrzel/simpleCalDAV.git + + git clone https://github.com/wvrzel/simpleCalDAV.git Assure yourself that cURL is installed. -Import SimpleCalDAVClient.php in your code and you are ready to go ;-) +Import `SimpleCalDAVClient.php` in your code and you are ready to go ;-) -4. How to get started +## 4. How to get started -Read the comments in SimpleCalDAVClient.php and the example code. +Read the comments in `SimpleCalDAVClient.php` and the example code. -5. Example Code +## 5. Example Code Example code is provided under "/example code/". From a88ecd0b3389bf42bac0eaa268efcd62c3102f02 Mon Sep 17 00:00:00 2001 From: Rico Kritz Date: Tue, 10 Apr 2018 15:03:57 +0200 Subject: [PATCH 08/10] bugfix: setCalendar ignores null values now --- README.md | 2 +- SimpleCalDAVClient.php | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 0a446de..6af1a71 100644 --- a/README.md +++ b/README.md @@ -43,7 +43,7 @@ This library is heavily based on AgenDAV caldav-client-v2.php by Jorge López P which again is heavily based on DAViCal caldav-client-v2.php by Andrew McMillan . Actually, I hardly added any features. The main point of my work is to make everything straight -forward and easy to use. You can use simpleCalDAV whithout a deeper understanding of the +forward and easy to use. You can use simpleCalDAV without a deeper understanding of the calDAV-protocol. diff --git a/SimpleCalDAVClient.php b/SimpleCalDAVClient.php index bcc643c..58f4c6e 100644 --- a/SimpleCalDAVClient.php +++ b/SimpleCalDAVClient.php @@ -148,6 +148,8 @@ public function findCalendars() */ public function setCalendar ( CalDAVCalendar $calendar ) { + if (!isset($calendar)) return; + $this->checkClient(); $this->calendar = $calendar; From 24ce35be63b9041f9fe7c6bb1d0eabbbcf6141f5 Mon Sep 17 00:00:00 2001 From: Rico Kritz Date: Wed, 11 Apr 2018 15:23:12 +0200 Subject: [PATCH 09/10] prevented some warnings --- SimpleCalDAVClient.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/SimpleCalDAVClient.php b/SimpleCalDAVClient.php index 58f4c6e..d80c1d7 100644 --- a/SimpleCalDAVClient.php +++ b/SimpleCalDAVClient.php @@ -360,7 +360,8 @@ public function getAllEvents($start = null, $end = null) $events = call_user_func_array('array_merge', $events); // restore previously set calendar - $this->setCalendar($current_calendar); + if (isset($current_calendar)) + $this->setCalendar($current_calendar); return $events; } @@ -441,7 +442,8 @@ public function getAllTODOs($start = null, $end = null, $completed = null, $canc $todos = call_user_func_array('array_merge', $todos); // restore previously set calendar - $this->setCalendar($current_calendar); + if (isset($current_calendar)) + $this->setCalendar($current_calendar); return $todos; } From 3759bce5bb719b7f0c07c388b430f397e951adb4 Mon Sep 17 00:00:00 2001 From: Rico Kritz Date: Tue, 17 Apr 2018 14:59:47 +0200 Subject: [PATCH 10/10] bugfix --- SimpleCalDAVClient.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/SimpleCalDAVClient.php b/SimpleCalDAVClient.php index d80c1d7..10832d4 100644 --- a/SimpleCalDAVClient.php +++ b/SimpleCalDAVClient.php @@ -357,7 +357,8 @@ public function getAllEvents($start = null, $end = null) } // flatten two dimensional array - $events = call_user_func_array('array_merge', $events); + if (!empty($events)) + $events = call_user_func_array('array_merge', $events); // restore previously set calendar if (isset($current_calendar)) @@ -439,7 +440,8 @@ public function getAllTODOs($start = null, $end = null, $completed = null, $canc } // flatten two dimensional array - $todos = call_user_func_array('array_merge', $todos); + if (!empty($todos)) + $todos = call_user_func_array('array_merge', $todos); // restore previously set calendar if (isset($current_calendar))