@ -1,26 +0,0 @@ |
||||
<?php |
||||
|
||||
/** |
||||
* Library include file |
||||
* |
||||
* This file is deprecated, don't use it! |
||||
* Instead, use the specific includes files that are in the sub-packages. |
||||
* |
||||
* Sabre/DAV/includes.php |
||||
* Sabre/HTTP/includes.php |
||||
* |
||||
* etc.. |
||||
* |
||||
* This file contains all includes to the rest of the SabreDAV library |
||||
* Make sure the lib/ directory is in PHP's include_path. |
||||
* |
||||
* @package Sabre |
||||
* @deprecated Don't use this file, it will be remove in a future version |
||||
* @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved. |
||||
* @author Evert Pot (http://www.rooftopsolutions.nl/) |
||||
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License |
||||
*/ |
||||
|
||||
include 'Sabre/HTTP/includes.php'; |
||||
include 'Sabre/DAV/includes.php'; |
||||
|
||||
@ -0,0 +1,231 @@ |
||||
<?php |
||||
|
||||
/** |
||||
* Every CalDAV backend must at least implement this interface. |
||||
* |
||||
* @package Sabre |
||||
* @subpackage CalDAV |
||||
* @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved. |
||||
* @author Evert Pot (http://www.rooftopsolutions.nl/) |
||||
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License |
||||
*/ |
||||
interface Sabre_CalDAV_Backend_BackendInterface { |
||||
|
||||
/** |
||||
* Returns a list of calendars for a principal. |
||||
* |
||||
* Every project is an array with the following keys: |
||||
* * id, a unique id that will be used by other functions to modify the |
||||
* calendar. This can be the same as the uri or a database key. |
||||
* * uri, which the basename of the uri with which the calendar is |
||||
* accessed. |
||||
* * principaluri. The owner of the calendar. Almost always the same as |
||||
* principalUri passed to this method. |
||||
* |
||||
* Furthermore it can contain webdav properties in clark notation. A very |
||||
* common one is '{DAV:}displayname'. |
||||
* |
||||
* @param string $principalUri |
||||
* @return array |
||||
*/ |
||||
public function getCalendarsForUser($principalUri); |
||||
|
||||
/** |
||||
* Creates a new calendar for a principal. |
||||
* |
||||
* If the creation was a success, an id must be returned that can be used to reference |
||||
* this calendar in other methods, such as updateCalendar. |
||||
* |
||||
* @param string $principalUri |
||||
* @param string $calendarUri |
||||
* @param array $properties |
||||
* @return void |
||||
*/ |
||||
public function createCalendar($principalUri,$calendarUri,array $properties); |
||||
|
||||
/** |
||||
* Updates properties for a calendar. |
||||
* |
||||
* The mutations array uses the propertyName in clark-notation as key, |
||||
* and the array value for the property value. In the case a property |
||||
* should be deleted, the property value will be null. |
||||
* |
||||
* This method must be atomic. If one property cannot be changed, the |
||||
* entire operation must fail. |
||||
* |
||||
* If the operation was successful, true can be returned. |
||||
* If the operation failed, false can be returned. |
||||
* |
||||
* Deletion of a non-existent property is always successful. |
||||
* |
||||
* Lastly, it is optional to return detailed information about any |
||||
* failures. In this case an array should be returned with the following |
||||
* structure: |
||||
* |
||||
* array( |
||||
* 403 => array( |
||||
* '{DAV:}displayname' => null, |
||||
* ), |
||||
* 424 => array( |
||||
* '{DAV:}owner' => null, |
||||
* ) |
||||
* ) |
||||
* |
||||
* In this example it was forbidden to update {DAV:}displayname. |
||||
* (403 Forbidden), which in turn also caused {DAV:}owner to fail |
||||
* (424 Failed Dependency) because the request needs to be atomic. |
||||
* |
||||
* @param mixed $calendarId |
||||
* @param array $mutations |
||||
* @return bool|array |
||||
*/ |
||||
public function updateCalendar($calendarId, array $mutations); |
||||
|
||||
/** |
||||
* Delete a calendar and all it's objects |
||||
* |
||||
* @param mixed $calendarId |
||||
* @return void |
||||
*/ |
||||
public function deleteCalendar($calendarId); |
||||
|
||||
/** |
||||
* Returns all calendar objects within a calendar. |
||||
* |
||||
* Every item contains an array with the following keys: |
||||
* * id - unique identifier which will be used for subsequent updates |
||||
* * calendardata - The iCalendar-compatible calendar data |
||||
* * uri - a unique key which will be used to construct the uri. This can be any arbitrary string. |
||||
* * lastmodified - a timestamp of the last modification time |
||||
* * etag - An arbitrary string, surrounded by double-quotes. (e.g.: |
||||
* ' "abcdef"') |
||||
* * calendarid - The calendarid as it was passed to this function. |
||||
* * size - The size of the calendar objects, in bytes. |
||||
* |
||||
* Note that the etag is optional, but it's highly encouraged to return for |
||||
* speed reasons. |
||||
* |
||||
* The calendardata is also optional. If it's not returned |
||||
* 'getCalendarObject' will be called later, which *is* expected to return |
||||
* calendardata. |
||||
* |
||||
* If neither etag or size are specified, the calendardata will be |
||||
* used/fetched to determine these numbers. If both are specified the |
||||
* amount of times this is needed is reduced by a great degree. |
||||
* |
||||
* @param mixed $calendarId |
||||
* @return array |
||||
*/ |
||||
public function getCalendarObjects($calendarId); |
||||
|
||||
/** |
||||
* Returns information from a single calendar object, based on it's object |
||||
* uri. |
||||
* |
||||
* The returned array must have the same keys as getCalendarObjects. The |
||||
* 'calendardata' object is required here though, while it's not required |
||||
* for getCalendarObjects. |
||||
* |
||||
* @param mixed $calendarId |
||||
* @param string $objectUri |
||||
* @return array |
||||
*/ |
||||
public function getCalendarObject($calendarId,$objectUri); |
||||
|
||||
/** |
||||
* Creates a new calendar object. |
||||
* |
||||
* It is possible return an etag from this function, which will be used in |
||||
* the response to this PUT request. Note that the ETag must be surrounded |
||||
* by double-quotes. |
||||
* |
||||
* However, you should only really return this ETag if you don't mangle the |
||||
* calendar-data. If the result of a subsequent GET to this object is not |
||||
* the exact same as this request body, you should omit the ETag. |
||||
* |
||||
* @param mixed $calendarId |
||||
* @param string $objectUri |
||||
* @param string $calendarData |
||||
* @return string|null |
||||
*/ |
||||
public function createCalendarObject($calendarId,$objectUri,$calendarData); |
||||
|
||||
/** |
||||
* Updates an existing calendarobject, based on it's uri. |
||||
* |
||||
* It is possible return an etag from this function, which will be used in |
||||
* the response to this PUT request. Note that the ETag must be surrounded |
||||
* by double-quotes. |
||||
* |
||||
* However, you should only really return this ETag if you don't mangle the |
||||
* calendar-data. If the result of a subsequent GET to this object is not |
||||
* the exact same as this request body, you should omit the ETag. |
||||
* |
||||
* @param mixed $calendarId |
||||
* @param string $objectUri |
||||
* @param string $calendarData |
||||
* @return string|null |
||||
*/ |
||||
public function updateCalendarObject($calendarId,$objectUri,$calendarData); |
||||
|
||||
/** |
||||
* Deletes an existing calendar object. |
||||
* |
||||
* @param mixed $calendarId |
||||
* @param string $objectUri |
||||
* @return void |
||||
*/ |
||||
public function deleteCalendarObject($calendarId,$objectUri); |
||||
|
||||
/** |
||||
* Performs a calendar-query on the contents of this calendar. |
||||
* |
||||
* The calendar-query is defined in RFC4791 : CalDAV. Using the |
||||
* calendar-query it is possible for a client to request a specific set of |
||||
* object, based on contents of iCalendar properties, date-ranges and |
||||
* iCalendar component types (VTODO, VEVENT). |
||||
* |
||||
* This method should just return a list of (relative) urls that match this |
||||
* query. |
||||
* |
||||
* The list of filters are specified as an array. The exact array is |
||||
* documented by Sabre_CalDAV_CalendarQueryParser. |
||||
* |
||||
* Note that it is extremely likely that getCalendarObject for every path |
||||
* returned from this method will be called almost immediately after. You |
||||
* may want to anticipate this to speed up these requests. |
||||
* |
||||
* This method provides a default implementation, which parses *all* the |
||||
* iCalendar objects in the specified calendar. |
||||
* |
||||
* This default may well be good enough for personal use, and calendars |
||||
* that aren't very large. But if you anticipate high usage, big calendars |
||||
* or high loads, you are strongly adviced to optimize certain paths. |
||||
* |
||||
* The best way to do so is override this method and to optimize |
||||
* specifically for 'common filters'. |
||||
* |
||||
* Requests that are extremely common are: |
||||
* * requests for just VEVENTS |
||||
* * requests for just VTODO |
||||
* * requests with a time-range-filter on either VEVENT or VTODO. |
||||
* |
||||
* ..and combinations of these requests. It may not be worth it to try to |
||||
* handle every possible situation and just rely on the (relatively |
||||
* easy to use) CalendarQueryValidator to handle the rest. |
||||
* |
||||
* Note that especially time-range-filters may be difficult to parse. A |
||||
* time-range filter specified on a VEVENT must for instance also handle |
||||
* recurrence rules correctly. |
||||
* A good example of how to interprete all these filters can also simply |
||||
* be found in Sabre_CalDAV_CalendarQueryFilter. This class is as correct |
||||
* as possible, so it gives you a good idea on what type of stuff you need |
||||
* to think of. |
||||
* |
||||
* @param mixed $calendarId |
||||
* @param array $filters |
||||
* @return array |
||||
*/ |
||||
public function calendarQuery($calendarId, array $filters); |
||||
|
||||
} |
||||
@ -0,0 +1,47 @@ |
||||
<?php |
||||
|
||||
/** |
||||
* Adds caldav notification support to a backend. |
||||
* |
||||
* Note: This feature is experimental, and may change in between different |
||||
* SabreDAV versions. |
||||
* |
||||
* Notifications are defined at: |
||||
* http://svn.calendarserver.org/repository/calendarserver/CalendarServer/trunk/doc/Extensions/caldav-notifications.txt |
||||
* |
||||
* These notifications are basically a list of server-generated notifications |
||||
* displayed to the user. Users can dismiss notifications by deleting them. |
||||
* |
||||
* The primary usecase is to allow for calendar-sharing. |
||||
* |
||||
* @package Sabre |
||||
* @subpackage CalDAV |
||||
* @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved. |
||||
* @author Evert Pot (http://www.rooftopsolutions.nl/) |
||||
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License |
||||
*/ |
||||
interface Sabre_CalDAV_Backend_NotificationSupport extends Sabre_CalDAV_Backend_BackendInterface { |
||||
|
||||
/** |
||||
* Returns a list of notifications for a given principal url. |
||||
* |
||||
* The returned array should only consist of implementations of |
||||
* Sabre_CalDAV_Notifications_INotificationType. |
||||
* |
||||
* @param string $principalUri |
||||
* @return array |
||||
*/ |
||||
public function getNotificationsForPrincipal($principalUri); |
||||
|
||||
/** |
||||
* This deletes a specific notifcation. |
||||
* |
||||
* This may be called by a client once it deems a notification handled. |
||||
* |
||||
* @param string $principalUri |
||||
* @param Sabre_CalDAV_Notifications_INotificationType $notification |
||||
* @return void |
||||
*/ |
||||
public function deleteNotification($principalUri, Sabre_CalDAV_Notifications_INotificationType $notification); |
||||
|
||||
} |
||||
@ -0,0 +1,238 @@ |
||||
<?php |
||||
|
||||
/** |
||||
* Adds support for sharing features to a CalDAV server. |
||||
* |
||||
* Note: This feature is experimental, and may change in between different |
||||
* SabreDAV versions. |
||||
* |
||||
* Early warning: Currently SabreDAV provides no implementation for this. This |
||||
* is, because in it's current state there is no elegant way to do this. |
||||
* The problem lies in the fact that a real CalDAV server with sharing support |
||||
* would first need email support (with invite notifications), and really also |
||||
* a browser-frontend that allows people to accept or reject these shares. |
||||
* |
||||
* In addition, the CalDAV backends are currently kept as independent as |
||||
* possible, and should not be aware of principals, email addresses or |
||||
* accounts. |
||||
* |
||||
* Adding an implementation for Sharing to standard-sabredav would contradict |
||||
* these goals, so for this reason this is currently not implemented, although |
||||
* it may very well in the future; but probably not before SabreDAV 2.0. |
||||
* |
||||
* The interface works however, so if you implement all this, and do it |
||||
* correctly sharing _will_ work. It's not particularly easy, and I _urge you_ |
||||
* to make yourself acquainted with the following document first: |
||||
* |
||||
* https://trac.calendarserver.org/browser/CalendarServer/trunk/doc/Extensions/caldav-sharing.txt |
||||
* |
||||
* An overview |
||||
* =========== |
||||
* |
||||
* Implementing this interface will allow a user to share his or her calendars |
||||
* to other users. Effectively, when a calendar is shared the calendar will |
||||
* show up in both the Sharer's and Sharee's calendar-home root. |
||||
* This interface adds a few methods that ensure that this happens, and there |
||||
* are also a number of new requirements in the base-class you must now follow. |
||||
* |
||||
* |
||||
* How it works |
||||
* ============ |
||||
* |
||||
* When a user shares a calendar, the addShare() method will be called with a |
||||
* list of sharees that are now added, and a list of sharees that have been |
||||
* removed. |
||||
* Removal is instant, but when a sharee is added the sharee first gets a |
||||
* chance to accept or reject the invitation for a share. |
||||
* |
||||
* After a share is accepted, the calendar will be returned from |
||||
* getUserCalendars for both the sharer, and the sharee. |
||||
* |
||||
* If the sharee deletes the calendar, only their share gets deleted. When the |
||||
* owner deletes a calendar, it will be removed for everybody. |
||||
* |
||||
* |
||||
* Notifications |
||||
* ============= |
||||
* |
||||
* During all these sharing operations, a lot of notifications are sent back |
||||
* and forward. |
||||
* |
||||
* Whenever the list of sharees for a calendar has been changed (they have been |
||||
* added, removed or modified) all sharees should get a notification for this |
||||
* change. |
||||
* This notification is always represented by: |
||||
* |
||||
* Sabre_CalDAV_Notifications_Notification_Invite |
||||
* |
||||
* In the case of an invite, the sharee may reply with an 'accept' or |
||||
* 'decline'. These are always represented by: |
||||
* |
||||
* Sabre_CalDAV_Notifications_Notification_Invite |
||||
* |
||||
* |
||||
* Calendar access by sharees |
||||
* ========================== |
||||
* |
||||
* As mentioned earlier, shared calendars must now also be returned for |
||||
* getCalendarsForUser for sharees. A few things change though. |
||||
* |
||||
* The following properties must be specified: |
||||
* |
||||
* 1. {http://calendarserver.org/ns/}shared-url |
||||
* |
||||
* This property MUST contain the url to the original calendar, that is.. the |
||||
* path to the calendar from the owner. |
||||
* |
||||
* 2. {http://sabredav.org/ns}owner-principal |
||||
* |
||||
* This is a url to to the principal who is sharing the calendar. |
||||
* |
||||
* 3. {http://sabredav.org/ns}read-only |
||||
* |
||||
* This should be either 0 or 1, depending on if the user has read-only or |
||||
* read-write access to the calendar. |
||||
* |
||||
* Only when this is done, the calendar will correctly be marked as a calendar |
||||
* that's shared to him, thus allowing clients to display the correct interface |
||||
* and ACL enforcement. |
||||
* |
||||
* If a sharee deletes their calendar, only their instance of the calendar |
||||
* should be deleted, the original should still exists. |
||||
* Pretty much any 'dead' WebDAV properties on these shared calendars should be |
||||
* specific to a user. This means that if the displayname is changed by a |
||||
* sharee, the original is not affected. This is also true for: |
||||
* * The description |
||||
* * The color |
||||
* * The order |
||||
* * And any other dead properties. |
||||
* |
||||
* Properties like a ctag should not be different for multiple instances of the |
||||
* calendar. |
||||
* |
||||
* Lastly, objects *within* calendars should also have user-specific data. The |
||||
* two things that are user-specific are: |
||||
* * VALARM objects |
||||
* * The TRANSP property |
||||
* |
||||
* This _also_ implies that if a VALARM is deleted by a sharee for some event, |
||||
* this has no effect on the original VALARM. |
||||
* |
||||
* Understandably, the this last requirement is one of the hardest. |
||||
* Realisticly, I can see people ignoring this part of the spec, but that could |
||||
* cause a different set of issues. |
||||
* |
||||
* |
||||
* Publishing |
||||
* ========== |
||||
* |
||||
* When a user publishes a url, the server should generate a 'publish url'. |
||||
* This is a read-only url, anybody can use to consume the calendar feed. |
||||
* |
||||
* Calendars are in one of two states: |
||||
* * published |
||||
* * unpublished |
||||
* |
||||
* If a calendar is published, the following property should be returned |
||||
* for each calendar in getCalendarsForPrincipal. |
||||
* |
||||
* {http://calendarserver.org/ns/}publish-url |
||||
* |
||||
* This element should contain a {DAV:}href element, which points to the |
||||
* public url that does not require authentication. Unlike every other href, |
||||
* this url must be absolute. |
||||
* |
||||
* Ideally, the following property is always returned |
||||
* |
||||
* {http://calendarserver.org/ns/}pre-publish-url |
||||
* |
||||
* This property should contain the url that the calendar _would_ have, if it |
||||
* were to be published. iCal uses this to display the url, before the user |
||||
* will actually publish it. |
||||
* |
||||
* |
||||
* Selectively disabling publish or share feature |
||||
* ============================================== |
||||
* |
||||
* If Sabre_CalDAV_Property_AllowedSharingModes is returned from |
||||
* getCalendarsByUser, this allows the server to specify wether either sharing, |
||||
* or publishing is supported. |
||||
* |
||||
* This allows a client to determine in advance which features are available, |
||||
* and update the interface appropriately. If this property is not returned by |
||||
* the backend, the SharingPlugin automatically injects it and assumes both |
||||
* features are available. |
||||
* |
||||
* @package Sabre |
||||
* @subpackage CalDAV |
||||
* @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved. |
||||
* @author Evert Pot (http://www.rooftopsolutions.nl/) |
||||
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License |
||||
*/ |
||||
interface Sabre_CalDAV_Backend_SharingSupport extends Sabre_CalDAV_Backend_NotificationSupport { |
||||
|
||||
/** |
||||
* Updates the list of shares. |
||||
* |
||||
* The first array is a list of people that are to be added to the |
||||
* calendar. |
||||
* |
||||
* Every element in the add array has the following properties: |
||||
* * href - A url. Usually a mailto: address |
||||
* * commonName - Usually a first and last name, or false |
||||
* * summary - A description of the share, can also be false |
||||
* * readOnly - A boolean value |
||||
* |
||||
* Every element in the remove array is just the address string. |
||||
* |
||||
* Note that if the calendar is currently marked as 'not shared' by and |
||||
* this method is called, the calendar should be 'upgraded' to a shared |
||||
* calendar. |
||||
* |
||||
* @param mixed $calendarId |
||||
* @param array $add |
||||
* @param array $remove |
||||
* @return void |
||||
*/ |
||||
function updateShares($calendarId, array $add, array $remove); |
||||
|
||||
/** |
||||
* Returns the list of people whom this calendar is shared with. |
||||
* |
||||
* Every element in this array should have the following properties: |
||||
* * href - Often a mailto: address |
||||
* * commonName - Optional, for example a first + last name |
||||
* * status - See the Sabre_CalDAV_SharingPlugin::STATUS_ constants. |
||||
* * readOnly - boolean |
||||
* * summary - Optional, a description for the share |
||||
* |
||||
* @param mixed $calendarId |
||||
* @return array |
||||
*/ |
||||
function getShares($calendarId); |
||||
|
||||
/** |
||||
* This method is called when a user replied to a request to share. |
||||
* |
||||
* If the user chose to accept the share, this method should return the |
||||
* newly created calendar url. |
||||
* |
||||
* @param string href The sharee who is replying (often a mailto: address) |
||||
* @param int status One of the SharingPlugin::STATUS_* constants |
||||
* @param string $calendarUri The url to the calendar thats being shared |
||||
* @param string $inReplyTo The unique id this message is a response to |
||||
* @param string $summary A description of the reply |
||||
* @return null|string |
||||
*/ |
||||
function shareReply($href, $status, $calendarUri, $inReplyTo, $summary = null); |
||||
|
||||
/** |
||||
* Publishes a calendar |
||||
* |
||||
* @param mixed $calendarId |
||||
* @param bool $value |
||||
* @return void |
||||
*/ |
||||
function setPublishStatus($calendarId, $value); |
||||
|
||||
} |
||||
@ -0,0 +1,32 @@ |
||||
<?php |
||||
|
||||
/** |
||||
* Sabre_CalDAV_Exception_InvalidComponentType |
||||
* |
||||
* @package Sabre |
||||
* @subpackage CalDAV |
||||
* @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved. |
||||
* @author Evert Pot (http://www.rooftopsolutions.nl/) |
||||
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License |
||||
*/ |
||||
class Sabre_CalDAV_Exception_InvalidComponentType extends Sabre_DAV_Exception_Forbidden { |
||||
|
||||
/** |
||||
* Adds in extra information in the xml response. |
||||
* |
||||
* This method adds the {CALDAV:}supported-calendar-component as defined in rfc4791 |
||||
* |
||||
* @param Sabre_DAV_Server $server |
||||
* @param DOMElement $errorNode |
||||
* @return void |
||||
*/ |
||||
public function serialize(Sabre_DAV_Server $server,DOMElement $errorNode) { |
||||
|
||||
$doc = $errorNode->ownerDocument; |
||||
|
||||
$np = $doc->createElementNS(Sabre_CalDAV_Plugin::NS_CALDAV,'cal:supported-calendar-component'); |
||||
$errorNode->appendChild($np); |
||||
|
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,48 @@ |
||||
<?php |
||||
|
||||
/** |
||||
* This interface represents a Calendar that can be shared with other users. |
||||
* |
||||
* @package Sabre |
||||
* @subpackage CalDAV |
||||
* @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved. |
||||
* @author Evert Pot (http://www.rooftopsolutions.nl/) |
||||
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License |
||||
*/ |
||||
interface Sabre_CalDAV_IShareableCalendar extends Sabre_CalDAV_ICalendar { |
||||
|
||||
/** |
||||
* Updates the list of shares. |
||||
* |
||||
* The first array is a list of people that are to be added to the |
||||
* calendar. |
||||
* |
||||
* Every element in the add array has the following properties: |
||||
* * href - A url. Usually a mailto: address |
||||
* * commonName - Usually a first and last name, or false |
||||
* * summary - A description of the share, can also be false |
||||
* * readOnly - A boolean value |
||||
* |
||||
* Every element in the remove array is just the address string. |
||||
* |
||||
* @param array $add |
||||
* @param array $remove |
||||
* @return void |
||||
*/ |
||||
function updateShares(array $add, array $remove); |
||||
|
||||
/** |
||||
* Returns the list of people whom this calendar is shared with. |
||||
* |
||||
* Every element in this array should have the following properties: |
||||
* * href - Often a mailto: address |
||||
* * commonName - Optional, for example a first + last name |
||||
* * status - See the Sabre_CalDAV_SharingPlugin::STATUS_ constants. |
||||
* * readOnly - boolean |
||||
* * summary - Optional, a description for the share |
||||
* |
||||
* @return array |
||||
*/ |
||||
function getShares(); |
||||
|
||||
} |
||||
@ -0,0 +1,22 @@ |
||||
<?php |
||||
|
||||
/** |
||||
* This interface represents a Calendar that is shared by a different user. |
||||
* |
||||
* @package Sabre |
||||
* @subpackage CalDAV |
||||
* @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved. |
||||
* @author Evert Pot (http://www.rooftopsolutions.nl/) |
||||
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License |
||||
*/ |
||||
interface Sabre_CalDAV_ISharedCalendar extends Sabre_CalDAV_ICalendar { |
||||
|
||||
/** |
||||
* This method should return the url of the owners' copy of the shared |
||||
* calendar. |
||||
* |
||||
* @return string |
||||
*/ |
||||
function getSharedUrl(); |
||||
|
||||
} |
||||
@ -0,0 +1,169 @@ |
||||
<?php |
||||
|
||||
/** |
||||
* This node represents a list of notifications. |
||||
* |
||||
* It provides no additional functionality, but you must implement this |
||||
* interface to allow the Notifications plugin to mark the collection |
||||
* as a notifications collection. |
||||
* |
||||
* This collection should only return Sabre_CalDAV_Notifications_INode nodes as |
||||
* its children. |
||||
* |
||||
* @package Sabre |
||||
* @subpackage CalDAV |
||||
* @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved. |
||||
* @author Evert Pot (http://www.rooftopsolutions.nl/) |
||||
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License |
||||
*/ |
||||
class Sabre_CalDAV_Notifications_Collection extends Sabre_DAV_Collection implements Sabre_CalDAV_Notifications_ICollection, Sabre_DAVACL_IACL { |
||||
|
||||
/** |
||||
* The notification backend |
||||
* |
||||
* @var Sabre_CalDAV_Backend_NotificationSupport |
||||
*/ |
||||
protected $caldavBackend; |
||||
|
||||
/** |
||||
* Principal uri |
||||
* |
||||
* @var string |
||||
*/ |
||||
protected $principalUri; |
||||
|
||||
/** |
||||
* Constructor |
||||
* |
||||
* @param Sabre_CalDAV_Backend_NotificationSupport $caldavBackend |
||||
* @param string $principalUri |
||||
*/ |
||||
public function __construct(Sabre_CalDAV_Backend_NotificationSupport $caldavBackend, $principalUri) { |
||||
|
||||
$this->caldavBackend = $caldavBackend; |
||||
$this->principalUri = $principalUri; |
||||
|
||||
} |
||||
|
||||
/** |
||||
* Returns all notifications for a principal |
||||
* |
||||
* @return array |
||||
*/ |
||||
public function getChildren() { |
||||
|
||||
$children = array(); |
||||
$notifications = $this->caldavBackend->getNotificationsForPrincipal($this->principalUri); |
||||
|
||||
foreach($notifications as $notification) { |
||||
|
||||
$children[] = new Sabre_CalDAV_Notifications_Node( |
||||
$this->caldavBackend, |
||||
$this->principalUri, |
||||
$notification |
||||
); |
||||
} |
||||
|
||||
return $children; |
||||
|
||||
} |
||||
|
||||
/** |
||||
* Returns the name of this object |
||||
* |
||||
* @return string |
||||
*/ |
||||
public function getName() { |
||||
|
||||
return 'notifications'; |
||||
|
||||
} |
||||
|
||||
/** |
||||
* Returns the owner principal |
||||
* |
||||
* This must be a url to a principal, or null if there's no owner |
||||
* |
||||
* @return string|null |
||||
*/ |
||||
public function getOwner() { |
||||
|
||||
return $this->principalUri; |
||||
|
||||
} |
||||
|
||||
/** |
||||
* Returns a group principal |
||||
* |
||||
* This must be a url to a principal, or null if there's no owner |
||||
* |
||||
* @return string|null |
||||
*/ |
||||
public function getGroup() { |
||||
|
||||
return null; |
||||
|
||||
} |
||||
|
||||
/** |
||||
* Returns a list of ACE's for this node. |
||||
* |
||||
* Each ACE has the following properties: |
||||
* * 'privilege', a string such as {DAV:}read or {DAV:}write. These are |
||||
* currently the only supported privileges |
||||
* * 'principal', a url to the principal who owns the node |
||||
* * 'protected' (optional), indicating that this ACE is not allowed to |
||||
* be updated. |
||||
* |
||||
* @return array |
||||
*/ |
||||
public function getACL() { |
||||
|
||||
return array( |
||||
array( |
||||
'principal' => $this->getOwner(), |
||||
'privilege' => '{DAV:}read', |
||||
'protected' => true, |
||||
), |
||||
array( |
||||
'principal' => $this->getOwner(), |
||||
'privilege' => '{DAV:}write', |
||||
'protected' => true, |
||||
) |
||||
); |
||||
|
||||
} |
||||
|
||||
/** |
||||
* Updates the ACL |
||||
* |
||||
* This method will receive a list of new ACE's as an array argument. |
||||
* |
||||
* @param array $acl |
||||
* @return void |
||||
*/ |
||||
public function setACL(array $acl) { |
||||
|
||||
throw new Sabre_DAV_Exception_NotImplemented('Updating ACLs is not implemented here'); |
||||
|
||||
} |
||||
|
||||
/** |
||||
* Returns the list of supported privileges for this node. |
||||
* |
||||
* The returned data structure is a list of nested privileges. |
||||
* See Sabre_DAVACL_Plugin::getDefaultSupportedPrivilegeSet for a simple |
||||
* standard structure. |
||||
* |
||||
* If null is returned from this method, the default privilege set is used, |
||||
* which is fine for most common usecases. |
||||
* |
||||
* @return array|null |
||||
*/ |
||||
public function getSupportedPrivilegeSet() { |
||||
|
||||
return null; |
||||
|
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,22 @@ |
||||
<?php |
||||
|
||||
/** |
||||
* This node represents a list of notifications. |
||||
* |
||||
* It provides no additional functionality, but you must implement this |
||||
* interface to allow the Notifications plugin to mark the collection |
||||
* as a notifications collection. |
||||
* |
||||
* This collection should only return Sabre_CalDAV_Notifications_INode nodes as |
||||
* its children. |
||||
* |
||||
* @package Sabre |
||||
* @subpackage CalDAV |
||||
* @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved. |
||||
* @author Evert Pot (http://www.rooftopsolutions.nl/) |
||||
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License |
||||
*/ |
||||
interface Sabre_CalDAV_Notifications_ICollection extends Sabre_DAV_ICollection { |
||||
|
||||
|
||||
} |
||||
@ -0,0 +1,38 @@ |
||||
<?php |
||||
|
||||
/** |
||||
* This node represents a single notification. |
||||
* |
||||
* The signature is mostly identical to that of Sabre_DAV_IFile, but the get() method |
||||
* MUST return an xml document that matches the requirements of the |
||||
* 'caldav-notifications.txt' spec. |
||||
* |
||||
* For a complete example, check out the Notification class, which contains |
||||
* some helper functions. |
||||
* |
||||
* @package Sabre |
||||
* @subpackage CalDAV |
||||
* @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved. |
||||
* @author Evert Pot (http://www.rooftopsolutions.nl/) |
||||
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License |
||||
*/ |
||||
interface Sabre_CalDAV_Notifications_INode { |
||||
|
||||
/** |
||||
* This method must return an xml element, using the |
||||
* Sabre_CalDAV_Notifications_INotificationType classes. |
||||
* |
||||
* @return Sabre_DAVNotification_INotificationType |
||||
*/ |
||||
function getNotificationType(); |
||||
|
||||
/** |
||||
* Returns the etag for the notification. |
||||
* |
||||
* The etag must be surrounded by litteral double-quotes. |
||||
* |
||||
* @return string |
||||
*/ |
||||
function getETag(); |
||||
|
||||
} |
||||
@ -0,0 +1,43 @@ |
||||
<?php |
||||
|
||||
/** |
||||
* This interface reflects a single notification type. |
||||
* |
||||
* @package Sabre |
||||
* @subpackage CalDAV |
||||
* @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved. |
||||
* @author Evert Pot (http://www.rooftopsolutions.nl/) |
||||
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License |
||||
*/ |
||||
interface Sabre_CalDAV_Notifications_INotificationType extends Sabre_DAV_PropertyInterface { |
||||
|
||||
/** |
||||
* This method serializes the entire notification, as it is used in the |
||||
* response body. |
||||
* |
||||
* @param Sabre_DAV_Server $server |
||||
* @param DOMElement $node |
||||
* @return void |
||||
*/ |
||||
function serializeBody(Sabre_DAV_Server $server, \DOMElement $node); |
||||
|
||||
/** |
||||
* Returns a unique id for this notification |
||||
* |
||||
* This is just the base url. This should generally be some kind of unique |
||||
* id. |
||||
* |
||||
* @return string |
||||
*/ |
||||
function getId(); |
||||
|
||||
/** |
||||
* Returns the ETag for this notification. |
||||
* |
||||
* The ETag must be surrounded by literal double-quotes. |
||||
* |
||||
* @return string |
||||
*/ |
||||
function getETag(); |
||||
|
||||
} |
||||
@ -0,0 +1,188 @@ |
||||
<?php |
||||
|
||||
/** |
||||
* This node represents a single notification. |
||||
* |
||||
* The signature is mostly identical to that of Sabre_DAV_IFile, but the get() method |
||||
* MUST return an xml document that matches the requirements of the |
||||
* 'caldav-notifications.txt' spec. |
||||
|
||||
* @package Sabre |
||||
* @subpackage CalDAV |
||||
* @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved. |
||||
* @author Evert Pot (http://www.rooftopsolutions.nl/) |
||||
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License |
||||
*/ |
||||
class Sabre_CalDAV_Notifications_Node extends Sabre_DAV_File implements Sabre_CalDAV_Notifications_INode, Sabre_DAVACL_IACL { |
||||
|
||||
/** |
||||
* The notification backend |
||||
* |
||||
* @var Sabre_CalDAV_Backend_NotificationSupport |
||||
*/ |
||||
protected $caldavBackend; |
||||
|
||||
/** |
||||
* The actual notification |
||||
* |
||||
* @var Sabre_CalDAV_Notifications_INotificationType |
||||
*/ |
||||
protected $notification; |
||||
|
||||
/** |
||||
* Owner principal of the notification |
||||
* |
||||
* @var string |
||||
*/ |
||||
protected $principalUri; |
||||
|
||||
/** |
||||
* Constructor |
||||
* |
||||
* @param Sabre_CalDAV_Backend_NotificationSupport $caldavBackend |
||||
* @param string $principalUri |
||||
* @param Sabre_CalDAV_Notifications_INotificationType $notification |
||||
*/ |
||||
public function __construct(Sabre_CalDAV_Backend_NotificationSupport $caldavBackend, $principalUri, Sabre_CalDAV_Notifications_INotificationType $notification) { |
||||
|
||||
$this->caldavBackend = $caldavBackend; |
||||
$this->principalUri = $principalUri; |
||||
$this->notification = $notification; |
||||
|
||||
} |
||||
|
||||
/** |
||||
* Returns the path name for this notification |
||||
* |
||||
* @return id |
||||
*/ |
||||
public function getName() { |
||||
|
||||
return $this->notification->getId() . '.xml'; |
||||
|
||||
} |
||||
|
||||
/** |
||||
* Returns the etag for the notification. |
||||
* |
||||
* The etag must be surrounded by litteral double-quotes. |
||||
* |
||||
* @return string |
||||
*/ |
||||
public function getETag() { |
||||
|
||||
return $this->notification->getETag(); |
||||
|
||||
} |
||||
|
||||
/** |
||||
* This method must return an xml element, using the |
||||
* Sabre_CalDAV_Notifications_INotificationType classes. |
||||
* |
||||
* @return Sabre_DAVNotification_INotificationType |
||||
*/ |
||||
public function getNotificationType() { |
||||
|
||||
return $this->notification; |
||||
|
||||
} |
||||
|
||||
/** |
||||
* Deletes this notification |
||||
* |
||||
* @return void |
||||
*/ |
||||
public function delete() { |
||||
|
||||
$this->caldavBackend->deleteNotification($this->getOwner(), $this->notification); |
||||
|
||||
} |
||||
|
||||
/** |
||||
* Returns the owner principal |
||||
* |
||||
* This must be a url to a principal, or null if there's no owner |
||||
* |
||||
* @return string|null |
||||
*/ |
||||
public function getOwner() { |
||||
|
||||
return $this->principalUri; |
||||
|
||||
} |
||||
|
||||
/** |
||||
* Returns a group principal |
||||
* |
||||
* This must be a url to a principal, or null if there's no owner |
||||
* |
||||
* @return string|null |
||||
*/ |
||||
public function getGroup() { |
||||
|
||||
return null; |
||||
|
||||
} |
||||
|
||||
/** |
||||
* Returns a list of ACE's for this node. |
||||
* |
||||
* Each ACE has the following properties: |
||||
* * 'privilege', a string such as {DAV:}read or {DAV:}write. These are |
||||
* currently the only supported privileges |
||||
* * 'principal', a url to the principal who owns the node |
||||
* * 'protected' (optional), indicating that this ACE is not allowed to |
||||
* be updated. |
||||
* |
||||
* @return array |
||||
*/ |
||||
public function getACL() { |
||||
|
||||
return array( |
||||
array( |
||||
'principal' => $this->getOwner(), |
||||
'privilege' => '{DAV:}read', |
||||
'protected' => true, |
||||
), |
||||
array( |
||||
'principal' => $this->getOwner(), |
||||
'privilege' => '{DAV:}write', |
||||
'protected' => true, |
||||
) |
||||
); |
||||
|
||||
} |
||||
|
||||
/** |
||||
* Updates the ACL |
||||
* |
||||
* This method will receive a list of new ACE's as an array argument. |
||||
* |
||||
* @param array $acl |
||||
* @return void |
||||
*/ |
||||
public function setACL(array $acl) { |
||||
|
||||
throw new Sabre_DAV_Exception_NotImplemented('Updating ACLs is not implemented here'); |
||||
|
||||
} |
||||
|
||||
/** |
||||
* Returns the list of supported privileges for this node. |
||||
* |
||||
* The returned data structure is a list of nested privileges. |
||||
* See Sabre_DAVACL_Plugin::getDefaultSupportedPrivilegeSet for a simple |
||||
* standard structure. |
||||
* |
||||
* If null is returned from this method, the default privilege set is used, |
||||
* which is fine for most common usecases. |
||||
* |
||||
* @return array|null |
||||
*/ |
||||
public function getSupportedPrivilegeSet() { |
||||
|
||||
return null; |
||||
|
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,276 @@ |
||||
<?php |
||||
|
||||
use Sabre_CalDAV_SharingPlugin as SharingPlugin; |
||||
|
||||
/** |
||||
* This class represents the cs:invite-notification notification element. |
||||
* |
||||
* @package Sabre |
||||
* @subpackage CalDAV |
||||
* @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved. |
||||
* @author Evert Pot (http://www.rooftopsolutions.nl/) |
||||
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License |
||||
*/ |
||||
class Sabre_CalDAV_Notifications_Notification_Invite extends Sabre_DAV_Property implements Sabre_CalDAV_Notifications_INotificationType { |
||||
|
||||
/** |
||||
* A unique id for the message |
||||
* |
||||
* @var string |
||||
*/ |
||||
protected $id; |
||||
|
||||
/** |
||||
* Timestamp of the notification |
||||
* |
||||
* @var DateTime |
||||
*/ |
||||
protected $dtStamp; |
||||
|
||||
/** |
||||
* A url to the recipient of the notification. This can be an email |
||||
* address (mailto:), or a principal url. |
||||
* |
||||
* @var string |
||||
*/ |
||||
protected $href; |
||||
|
||||
/** |
||||
* The type of message, see the SharingPlugin::STATUS_* constants. |
||||
* |
||||
* @var int |
||||
*/ |
||||
protected $type; |
||||
|
||||
/** |
||||
* True if access to a calendar is read-only. |
||||
* |
||||
* @var bool |
||||
*/ |
||||
protected $readOnly; |
||||
|
||||
/** |
||||
* A url to the shared calendar. |
||||
* |
||||
* @var string |
||||
*/ |
||||
protected $hostUrl; |
||||
|
||||
/** |
||||
* Url to the sharer of the calendar |
||||
* |
||||
* @var string |
||||
*/ |
||||
protected $organizer; |
||||
|
||||
/** |
||||
* The name of the sharer. |
||||
* |
||||
* @var string |
||||
*/ |
||||
protected $commonName; |
||||
|
||||
/** |
||||
* A description of the share request |
||||
* |
||||
* @var string |
||||
*/ |
||||
protected $summary; |
||||
|
||||
/** |
||||
* The Etag for the notification |
||||
* |
||||
* @var string |
||||
*/ |
||||
protected $etag; |
||||
|
||||
/** |
||||
* The list of supported components |
||||
* |
||||
* @var Sabre_CalDAV_Property_SupportedCalendarComponentSet |
||||
*/ |
||||
protected $supportedComponents; |
||||
|
||||
/** |
||||
* Creates the Invite notification. |
||||
* |
||||
* This constructor receives an array with the following elements: |
||||
* |
||||
* * id - A unique id |
||||
* * etag - The etag |
||||
* * dtStamp - A DateTime object with a timestamp for the notification. |
||||
* * type - The type of notification, see SharingPlugin::STATUS_* |
||||
* constants for details. |
||||
* * readOnly - This must be set to true, if this is an invite for |
||||
* read-only access to a calendar. |
||||
* * hostUrl - A url to the shared calendar. |
||||
* * organizer - Url to the sharer principal. |
||||
* * commonName - The real name of the sharer (optional). |
||||
* * summary - Description of the share, can be the same as the |
||||
* calendar, but may also be modified (optional). |
||||
* * supportedComponents - An instance of |
||||
* Sabre_CalDAV_Property_SupportedCalendarComponentSet. |
||||
* This allows the client to determine which components |
||||
* will be supported in the shared calendar. This is |
||||
* also optional. |
||||
* |
||||
* @param array $values All the options |
||||
*/ |
||||
public function __construct(array $values) { |
||||
|
||||
$required = array( |
||||
'id', |
||||
'etag', |
||||
'href', |
||||
'dtStamp', |
||||
'type', |
||||
'readOnly', |
||||
'hostUrl', |
||||
'organizer', |
||||
); |
||||
foreach($required as $item) { |
||||
if (!isset($values[$item])) { |
||||
throw new InvalidArgumentException($item . ' is a required constructor option'); |
||||
} |
||||
} |
||||
|
||||
foreach($values as $key=>$value) { |
||||
if (!property_exists($this, $key)) { |
||||
throw new InvalidArgumentException('Unknown option: ' . $key); |
||||
} |
||||
$this->$key = $value; |
||||
} |
||||
|
||||
} |
||||
|
||||
/** |
||||
* Serializes the notification as a single property. |
||||
* |
||||
* You should usually just encode the single top-level element of the |
||||
* notification. |
||||
* |
||||
* @param Sabre_DAV_Server $server |
||||
* @param DOMElement $node |
||||
* @return void |
||||
*/ |
||||
public function serialize(Sabre_DAV_Server $server, \DOMElement $node) { |
||||
|
||||
$prop = $node->ownerDocument->createElement('cs:invite-notification'); |
||||
$node->appendChild($prop); |
||||
|
||||
} |
||||
|
||||
/** |
||||
* This method serializes the entire notification, as it is used in the |
||||
* response body. |
||||
* |
||||
* @param Sabre_DAV_Server $server |
||||
* @param DOMElement $node |
||||
* @return void |
||||
*/ |
||||
public function serializeBody(Sabre_DAV_Server $server, \DOMElement $node) { |
||||
|
||||
$doc = $node->ownerDocument; |
||||
|
||||
$dt = $doc->createElement('cs:dtstamp'); |
||||
$this->dtStamp->setTimezone(new \DateTimezone('GMT')); |
||||
$dt->appendChild($doc->createTextNode($this->dtStamp->format('Ymd\\THis\\Z'))); |
||||
$node->appendChild($dt); |
||||
|
||||
$prop = $doc->createElement('cs:invite-notification'); |
||||
$node->appendChild($prop); |
||||
|
||||
$uid = $doc->createElement('cs:uid'); |
||||
$uid->appendChild( $doc->createTextNode($this->id) ); |
||||
$prop->appendChild($uid); |
||||
|
||||
$href = $doc->createElement('d:href'); |
||||
$href->appendChild( $doc->createTextNode( $this->href ) ); |
||||
$prop->appendChild($href); |
||||
|
||||
$nodeName = null; |
||||
switch($this->type) { |
||||
|
||||
case SharingPlugin::STATUS_ACCEPTED : |
||||
$nodeName = 'cs:invite-accepted'; |
||||
break; |
||||
case SharingPlugin::STATUS_DECLINED : |
||||
$nodeName = 'cs:invite-declined'; |
||||
break; |
||||
case SharingPlugin::STATUS_DELETED : |
||||
$nodeName = 'cs:invite-deleted'; |
||||
break; |
||||
case SharingPlugin::STATUS_NORESPONSE : |
||||
$nodeName = 'cs:invite-noresponse'; |
||||
break; |
||||
|
||||
} |
||||
$prop->appendChild( |
||||
$doc->createElement($nodeName) |
||||
); |
||||
$hostHref = $doc->createElement('d:href', $server->getBaseUri() . $this->hostUrl); |
||||
$hostUrl = $doc->createElement('cs:hosturl'); |
||||
$hostUrl->appendChild($hostHref); |
||||
$prop->appendChild($hostUrl); |
||||
|
||||
$access = $doc->createElement('cs:access'); |
||||
if ($this->readOnly) { |
||||
$access->appendChild($doc->createElement('cs:read')); |
||||
} else { |
||||
$access->appendChild($doc->createElement('cs:read-write')); |
||||
} |
||||
$prop->appendChild($access); |
||||
|
||||
$organizerHref = $doc->createElement('d:href', $server->getBaseUri() . $this->organizer); |
||||
$organizerUrl = $doc->createElement('cs:organizer'); |
||||
if ($this->commonName) { |
||||
$commonName = $doc->createElement('cs:common-name'); |
||||
$commonName->appendChild($doc->createTextNode($this->commonName)); |
||||
$organizerUrl->appendChild($commonName); |
||||
} |
||||
$organizerUrl->appendChild($organizerHref); |
||||
$prop->appendChild($organizerUrl); |
||||
|
||||
if ($this->summary) { |
||||
$summary = $doc->createElement('cs:summary'); |
||||
$summary->appendChild($doc->createTextNode($this->summary)); |
||||
$prop->appendChild($summary); |
||||
} |
||||
if ($this->supportedComponents) { |
||||
|
||||
$xcomp = $doc->createElement('cal:supported-calendar-component-set'); |
||||
$this->supportedComponents->serialize($server, $xcomp); |
||||
$prop->appendChild($xcomp); |
||||
|
||||
} |
||||
|
||||
} |
||||
|
||||
/** |
||||
* Returns a unique id for this notification |
||||
* |
||||
* This is just the base url. This should generally be some kind of unique |
||||
* id. |
||||
* |
||||
* @return string |
||||
*/ |
||||
public function getId() { |
||||
|
||||
return $this->id; |
||||
|
||||
} |
||||
|
||||
/** |
||||
* Returns the ETag for this notification. |
||||
* |
||||
* The ETag must be surrounded by literal double-quotes. |
||||
* |
||||
* @return string |
||||
*/ |
||||
public function getETag() { |
||||
|
||||
return $this->etag; |
||||
|
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,216 @@ |
||||
<?php |
||||
|
||||
use Sabre_CalDAV_SharingPlugin as SharingPlugin; |
||||
|
||||
/** |
||||
* This class represents the cs:invite-reply notification element. |
||||
* |
||||
* @package Sabre |
||||
* @subpackage CalDAV |
||||
* @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved. |
||||
* @author Evert Pot (http://www.rooftopsolutions.nl/) |
||||
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License |
||||
*/ |
||||
class Sabre_CalDAV_Notifications_Notification_InviteReply extends Sabre_DAV_Property implements Sabre_CalDAV_Notifications_INotificationType { |
||||
|
||||
/** |
||||
* A unique id for the message |
||||
* |
||||
* @var string |
||||
*/ |
||||
protected $id; |
||||
|
||||
/** |
||||
* Timestamp of the notification |
||||
* |
||||
* @var DateTime |
||||
*/ |
||||
protected $dtStamp; |
||||
|
||||
/** |
||||
* The unique id of the notification this was a reply to. |
||||
* |
||||
* @var string |
||||
*/ |
||||
protected $inReplyTo; |
||||
|
||||
/** |
||||
* A url to the recipient of the original (!) notification. |
||||
* |
||||
* @var string |
||||
*/ |
||||
protected $href; |
||||
|
||||
/** |
||||
* The type of message, see the SharingPlugin::STATUS_ constants. |
||||
* |
||||
* @var int |
||||
*/ |
||||
protected $type; |
||||
|
||||
/** |
||||
* A url to the shared calendar. |
||||
* |
||||
* @var string |
||||
*/ |
||||
protected $hostUrl; |
||||
|
||||
/** |
||||
* A description of the share request |
||||
* |
||||
* @var string |
||||
*/ |
||||
protected $summary; |
||||
|
||||
/** |
||||
* Notification Etag |
||||
* |
||||
* @var string |
||||
*/ |
||||
protected $etag; |
||||
|
||||
/** |
||||
* Creates the Invite Reply Notification. |
||||
* |
||||
* This constructor receives an array with the following elements: |
||||
* |
||||
* * id - A unique id |
||||
* * etag - The etag |
||||
* * dtStamp - A DateTime object with a timestamp for the notification. |
||||
* * inReplyTo - This should refer to the 'id' of the notification |
||||
* this is a reply to. |
||||
* * type - The type of notification, see SharingPlugin::STATUS_* |
||||
* constants for details. |
||||
* * hostUrl - A url to the shared calendar. |
||||
* * summary - Description of the share, can be the same as the |
||||
* calendar, but may also be modified (optional). |
||||
*/ |
||||
public function __construct(array $values) { |
||||
|
||||
$required = array( |
||||
'id', |
||||
'etag', |
||||
'href', |
||||
'dtStamp', |
||||
'inReplyTo', |
||||
'type', |
||||
'hostUrl', |
||||
); |
||||
foreach($required as $item) { |
||||
if (!isset($values[$item])) { |
||||
throw new InvalidArgumentException($item . ' is a required constructor option'); |
||||
} |
||||
} |
||||
|
||||
foreach($values as $key=>$value) { |
||||
if (!property_exists($this, $key)) { |
||||
throw new InvalidArgumentException('Unknown option: ' . $key); |
||||
} |
||||
$this->$key = $value; |
||||
} |
||||
|
||||
} |
||||
|
||||
/** |
||||
* Serializes the notification as a single property. |
||||
* |
||||
* You should usually just encode the single top-level element of the |
||||
* notification. |
||||
* |
||||
* @param Sabre_DAV_Server $server |
||||
* @param DOMElement $node |
||||
* @return void |
||||
*/ |
||||
public function serialize(Sabre_DAV_Server $server, \DOMElement $node) { |
||||
|
||||
$prop = $node->ownerDocument->createElement('cs:invite-reply'); |
||||
$node->appendChild($prop); |
||||
|
||||
} |
||||
|
||||
/** |
||||
* This method serializes the entire notification, as it is used in the |
||||
* response body. |
||||
* |
||||
* @param Sabre_DAV_Server $server |
||||
* @param DOMElement $node |
||||
* @return void |
||||
*/ |
||||
public function serializeBody(Sabre_DAV_Server $server, \DOMElement $node) { |
||||
|
||||
$doc = $node->ownerDocument; |
||||
|
||||
$dt = $doc->createElement('cs:dtstamp'); |
||||
$this->dtStamp->setTimezone(new \DateTimezone('GMT')); |
||||
$dt->appendChild($doc->createTextNode($this->dtStamp->format('Ymd\\THis\\Z'))); |
||||
$node->appendChild($dt); |
||||
|
||||
$prop = $doc->createElement('cs:invite-reply'); |
||||
$node->appendChild($prop); |
||||
|
||||
$uid = $doc->createElement('cs:uid'); |
||||
$uid->appendChild($doc->createTextNode($this->id)); |
||||
$prop->appendChild($uid); |
||||
|
||||
$inReplyTo = $doc->createElement('cs:in-reply-to'); |
||||
$inReplyTo->appendChild( $doc->createTextNode($this->inReplyTo) ); |
||||
$prop->appendChild($inReplyTo); |
||||
|
||||
$href = $doc->createElement('d:href'); |
||||
$href->appendChild( $doc->createTextNode($this->href) ); |
||||
$prop->appendChild($href); |
||||
|
||||
$nodeName = null; |
||||
switch($this->type) { |
||||
|
||||
case SharingPlugin::STATUS_ACCEPTED : |
||||
$nodeName = 'cs:invite-accepted'; |
||||
break; |
||||
case SharingPlugin::STATUS_DECLINED : |
||||
$nodeName = 'cs:invite-declined'; |
||||
break; |
||||
|
||||
} |
||||
$prop->appendChild( |
||||
$doc->createElement($nodeName) |
||||
); |
||||
$hostHref = $doc->createElement('d:href', $server->getBaseUri() . $this->hostUrl); |
||||
$hostUrl = $doc->createElement('cs:hosturl'); |
||||
$hostUrl->appendChild($hostHref); |
||||
$prop->appendChild($hostUrl); |
||||
|
||||
if ($this->summary) { |
||||
$summary = $doc->createElement('cs:summary'); |
||||
$summary->appendChild($doc->createTextNode($this->summary)); |
||||
$prop->appendChild($summary); |
||||
} |
||||
|
||||
} |
||||
|
||||
/** |
||||
* Returns a unique id for this notification |
||||
* |
||||
* This is just the base url. This should generally be some kind of unique |
||||
* id. |
||||
* |
||||
* @return string |
||||
*/ |
||||
public function getId() { |
||||
|
||||
return $this->id; |
||||
|
||||
} |
||||
|
||||
/** |
||||
* Returns the ETag for this notification. |
||||
* |
||||
* The ETag must be surrounded by literal double-quotes. |
||||
* |
||||
* @return string |
||||
*/ |
||||
public function getETag() { |
||||
|
||||
return $this->etag; |
||||
|
||||
} |
||||
} |
||||
@ -0,0 +1,179 @@ |
||||
<?php |
||||
|
||||
/** |
||||
* SystemStatus notification |
||||
* |
||||
* This notification can be used to indicate to the user that the system is |
||||
* down. |
||||
* |
||||
* @package Sabre |
||||
* @subpackage CalDAV |
||||
* @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved. |
||||
* @author Evert Pot (http://www.rooftopsolutions.nl/) |
||||
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License |
||||
*/ |
||||
class Sabre_CalDAV_Notifications_Notification_SystemStatus extends Sabre_DAV_Property implements Sabre_CalDAV_Notifications_INotificationType { |
||||
|
||||
const TYPE_LOW = 1; |
||||
const TYPE_MEDIUM = 2; |
||||
const TYPE_HIGH = 3; |
||||
|
||||
/** |
||||
* A unique id |
||||
* |
||||
* @var string |
||||
*/ |
||||
protected $id; |
||||
|
||||
/** |
||||
* The type of alert. This should be one of the TYPE_ constants. |
||||
* |
||||
* @var int |
||||
*/ |
||||
protected $type; |
||||
|
||||
/** |
||||
* A human-readable description of the problem. |
||||
* |
||||
* @var string |
||||
*/ |
||||
protected $description; |
||||
|
||||
/** |
||||
* A url to a website with more information for the user. |
||||
* |
||||
* @var string |
||||
*/ |
||||
protected $href; |
||||
|
||||
/** |
||||
* Notification Etag |
||||
* |
||||
* @var string |
||||
*/ |
||||
protected $etag; |
||||
|
||||
/** |
||||
* Creates the notification. |
||||
* |
||||
* Some kind of unique id should be provided. This is used to generate a |
||||
* url. |
||||
* |
||||
* @param string $id |
||||
* @param string $etag |
||||
* @param int $type |
||||
* @param string $description |
||||
* @param string $href |
||||
*/ |
||||
public function __construct($id, $etag, $type = self::TYPE_HIGH, $description = null, $href = null) { |
||||
|
||||
$this->id = $id; |
||||
$this->type = $type; |
||||
$this->description = $description; |
||||
$this->href = $href; |
||||
$this->etag = $etag; |
||||
|
||||
} |
||||
|
||||
/** |
||||
* Serializes the notification as a single property. |
||||
* |
||||
* You should usually just encode the single top-level element of the |
||||
* notification. |
||||
* |
||||
* @param Sabre_DAV_Server $server |
||||
* @param DOMElement $node |
||||
* @return void |
||||
*/ |
||||
public function serialize(Sabre_DAV_Server $server, \DOMElement $node) { |
||||
|
||||
switch($this->type) { |
||||
case self::TYPE_LOW : |
||||
$type = 'low'; |
||||
break; |
||||
case self::TYPE_MEDIUM : |
||||
$type = 'medium'; |
||||
break; |
||||
default : |
||||
case self::TYPE_HIGH : |
||||
$type = 'high'; |
||||
break; |
||||
} |
||||
|
||||
$prop = $node->ownerDocument->createElement('cs:systemstatus'); |
||||
$prop->setAttribute('type', $type); |
||||
|
||||
$node->appendChild($prop); |
||||
|
||||
} |
||||
|
||||
/** |
||||
* This method serializes the entire notification, as it is used in the |
||||
* response body. |
||||
* |
||||
* @param Sabre_DAV_Server $server |
||||
* @param DOMElement $node |
||||
* @return void |
||||
*/ |
||||
public function serializeBody(Sabre_DAV_Server $server, \DOMElement $node) { |
||||
|
||||
switch($this->type) { |
||||
case self::TYPE_LOW : |
||||
$type = 'low'; |
||||
break; |
||||
case self::TYPE_MEDIUM : |
||||
$type = 'medium'; |
||||
break; |
||||
default : |
||||
case self::TYPE_HIGH : |
||||
$type = 'high'; |
||||
break; |
||||
} |
||||
|
||||
$prop = $node->ownerDocument->createElement('cs:systemstatus'); |
||||
$prop->setAttribute('type', $type); |
||||
|
||||
if ($this->description) { |
||||
$text = $node->ownerDocument->createTextNode($this->description); |
||||
$desc = $node->ownerDocument->createElement('cs:description'); |
||||
$desc->appendChild($text); |
||||
$prop->appendChild($desc); |
||||
} |
||||
if ($this->href) { |
||||
$text = $node->ownerDocument->createTextNode($this->href); |
||||
$href = $node->ownerDocument->createElement('d:href'); |
||||
$href->appendChild($text); |
||||
$prop->appendChild($href); |
||||
} |
||||
|
||||
$node->appendChild($prop); |
||||
|
||||
} |
||||
|
||||
/** |
||||
* Returns a unique id for this notification |
||||
* |
||||
* This is just the base url. This should generally be some kind of unique |
||||
* id. |
||||
* |
||||
* @return string |
||||
*/ |
||||
public function getId() { |
||||
|
||||
return $this->id; |
||||
|
||||
} |
||||
|
||||
/* |
||||
* Returns the ETag for this notification. |
||||
* |
||||
* The ETag must be surrounded by literal double-quotes. |
||||
* |
||||
* @return string |
||||
*/ |
||||
public function getETag() { |
||||
|
||||
return $this->etag; |
||||
|
||||
} |
||||
} |
||||
@ -0,0 +1,72 @@ |
||||
<?php |
||||
|
||||
/** |
||||
* AllowedSharingModes |
||||
* |
||||
* This property encodes the 'allowed-sharing-modes' property, as defined by |
||||
* the 'caldav-sharing-02' spec, in the http://calendarserver.org/ns/ |
||||
* namespace. |
||||
* |
||||
* This property is a representation of the supported-calendar_component-set |
||||
* property in the CalDAV namespace. It simply requires an array of components, |
||||
* such as VEVENT, VTODO |
||||
* |
||||
* @package Sabre |
||||
* @subpackage CalDAV |
||||
* @see https://trac.calendarserver.org/browser/CalendarServer/trunk/doc/Extensions/caldav-sharing-02.txt |
||||
* @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved. |
||||
* @author Evert Pot (http://www.rooftopsolutions.nl/) |
||||
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License |
||||
*/ |
||||
class Sabre_CalDAV_Property_AllowedSharingModes extends Sabre_DAV_Property { |
||||
|
||||
/** |
||||
* Whether or not a calendar can be shared with another user |
||||
* |
||||
* @var bool |
||||
*/ |
||||
protected $canBeShared; |
||||
|
||||
/** |
||||
* Whether or not the calendar can be placed on a public url. |
||||
* |
||||
* @var bool |
||||
*/ |
||||
protected $canBePublished; |
||||
|
||||
/** |
||||
* Constructor |
||||
* |
||||
* @param bool $canBeShared |
||||
* @param bool $canBePublished |
||||
* @return void |
||||
*/ |
||||
public function __construct($canBeShared, $canBePublished) { |
||||
|
||||
$this->canBeShared = $canBeShared; |
||||
$this->canBePublished = $canBePublished; |
||||
|
||||
} |
||||
|
||||
/** |
||||
* Serializes the property in a DOMDocument |
||||
* |
||||
* @param Sabre_DAV_Server $server |
||||
* @param DOMElement $node |
||||
* @return void |
||||
*/ |
||||
public function serialize(Sabre_DAV_Server $server,DOMElement $node) { |
||||
|
||||
$doc = $node->ownerDocument; |
||||
if ($this->canBeShared) { |
||||
$xcomp = $doc->createElement('cs:can-be-shared'); |
||||
$node->appendChild($xcomp); |
||||
} |
||||
if ($this->canBePublished) { |
||||
$xcomp = $doc->createElement('cs:can-be-published'); |
||||
$node->appendChild($xcomp); |
||||
} |
||||
|
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,173 @@ |
||||
<?php |
||||
|
||||
use Sabre_CalDAV_SharingPlugin as SharingPlugin; |
||||
|
||||
/** |
||||
* Invite property |
||||
* |
||||
* This property encodes the 'invite' property, as defined by |
||||
* the 'caldav-sharing-02' spec, in the http://calendarserver.org/ns/ |
||||
* namespace. |
||||
* |
||||
* @package Sabre |
||||
* @subpackage CalDAV |
||||
* @see https://trac.calendarserver.org/browser/CalendarServer/trunk/doc/Extensions/caldav-sharing-02.txt |
||||
* @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved. |
||||
* @author Evert Pot (http://www.rooftopsolutions.nl/) |
||||
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License |
||||
*/ |
||||
class Sabre_CalDAV_Property_Invite extends Sabre_DAV_Property { |
||||
|
||||
/** |
||||
* The list of users a calendar has been shared to. |
||||
* |
||||
* @var array |
||||
*/ |
||||
protected $users; |
||||
|
||||
/** |
||||
* Creates the property. |
||||
* |
||||
* Users is an array. Each element of the array has the following |
||||
* properties: |
||||
* |
||||
* * href - Often a mailto: address |
||||
* * commonName - Optional, for example a first and lastname for a user. |
||||
* * status - One of the SharingPlugin::STATUS_* constants. |
||||
* * readOnly - true or false |
||||
* * summary - Optional, description of the share |
||||
* |
||||
* @param array $users |
||||
*/ |
||||
public function __construct(array $users) { |
||||
|
||||
$this->users = $users; |
||||
|
||||
} |
||||
|
||||
/** |
||||
* Returns the list of users, as it was passed to the constructor. |
||||
* |
||||
* @return array |
||||
*/ |
||||
public function getValue() { |
||||
|
||||
return $this->users; |
||||
|
||||
} |
||||
|
||||
/** |
||||
* Serializes the property in a DOMDocument |
||||
* |
||||
* @param Sabre_DAV_Server $server |
||||
* @param DOMElement $node |
||||
* @return void |
||||
*/ |
||||
public function serialize(Sabre_DAV_Server $server,DOMElement $node) { |
||||
|
||||
$doc = $node->ownerDocument; |
||||
foreach($this->users as $user) { |
||||
|
||||
$xuser = $doc->createElement('cs:user'); |
||||
|
||||
$href = $doc->createElement('d:href'); |
||||
$href->appendChild($doc->createTextNode($user['href'])); |
||||
$xuser->appendChild($href); |
||||
|
||||
if (isset($user['commonName']) && $user['commonName']) { |
||||
$commonName = $doc->createElement('cs:common-name'); |
||||
$commonName->appendChild($doc->createTextNode($user['commonName'])); |
||||
$xuser->appendChild($commonName); |
||||
} |
||||
|
||||
switch($user['status']) { |
||||
|
||||
case SharingPlugin::STATUS_ACCEPTED : |
||||
$status = $doc->createElement('cs:invite-accepted'); |
||||
$xuser->appendChild($status); |
||||
break; |
||||
case SharingPlugin::STATUS_DECLINED : |
||||
$status = $doc->createElement('cs:invite-declined'); |
||||
$xuser->appendChild($status); |
||||
break; |
||||
case SharingPlugin::STATUS_NORESPONSE : |
||||
$status = $doc->createElement('cs:invite-noresponse'); |
||||
$xuser->appendChild($status); |
||||
break; |
||||
case SharingPlugin::STATUS_INVALID : |
||||
$status = $doc->createElement('cs:invite-invalid'); |
||||
$xuser->appendChild($status); |
||||
break; |
||||
|
||||
} |
||||
|
||||
$xaccess = $doc->createElement('cs:access'); |
||||
|
||||
if ($user['readOnly']) { |
||||
$xaccess->appendChild( |
||||
$doc->createElement('cs:read') |
||||
); |
||||
} else { |
||||
$xaccess->appendChild( |
||||
$doc->createElement('cs:read-write') |
||||
); |
||||
} |
||||
$xuser->appendChild($xaccess); |
||||
|
||||
if (isset($user['summary']) && $user['summary']) { |
||||
$summary = $doc->createElement('cs:summary'); |
||||
$summary->appendChild($doc->createTextNode($user['summary'])); |
||||
$xuser->appendChild($summary); |
||||
} |
||||
|
||||
$node->appendChild($xuser); |
||||
|
||||
} |
||||
|
||||
} |
||||
|
||||
/** |
||||
* Unserializes the property. |
||||
* |
||||
* This static method should return a an instance of this object. |
||||
* |
||||
* @param DOMElement $prop |
||||
* @return Sabre_DAV_IProperty |
||||
*/ |
||||
static function unserialize(DOMElement $prop) { |
||||
|
||||
$xpath = new \DOMXPath($prop->ownerDocument); |
||||
$xpath->registerNamespace('cs', Sabre_CalDAV_Plugin::NS_CALENDARSERVER); |
||||
$xpath->registerNamespace('d', 'DAV:'); |
||||
|
||||
$users = array(); |
||||
|
||||
foreach($xpath->query('cs:user', $prop) as $user) { |
||||
|
||||
$status = null; |
||||
if ($xpath->evaluate('boolean(cs:invite-accepted)', $user)) { |
||||
$status = SharingPlugin::STATUS_ACCEPTED; |
||||
} elseif ($xpath->evaluate('boolean(cs:invite-declined)', $user)) { |
||||
$status = SharingPlugin::STATUS_DECLINED; |
||||
} elseif ($xpath->evaluate('boolean(cs:invite-noresponse)', $user)) { |
||||
$status = SharingPlugin::STATUS_NORESPONSE; |
||||
} elseif ($xpath->evaluate('boolean(cs:invite-invalid)', $user)) { |
||||
$status = SharingPlugin::STATUS_INVALID; |
||||
} else { |
||||
throw new Sabre_DAV_Exception('Every cs:user property must have one of cs:invite-accepted, cs:invite-declined, cs:invite-noresponse or cs:invite-invalid'); |
||||
} |
||||
$users[] = array( |
||||
'href' => $xpath->evaluate('string(d:href)', $user), |
||||
'commonName' => $xpath->evaluate('string(cs:common-name)', $user), |
||||
'readOnly' => $xpath->evaluate('boolean(cs:access/cs:read)', $user), |
||||
'summary' => $xpath->evaluate('string(cs:summary)', $user), |
||||
'status' => $status, |
||||
); |
||||
|
||||
} |
||||
|
||||
return new self($users); |
||||
|
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,99 @@ |
||||
<?php |
||||
|
||||
/** |
||||
* schedule-calendar-transp property. |
||||
* |
||||
* This property is a representation of the schedule-calendar-transp property. |
||||
* This property is defined in RFC6638 (caldav scheduling). |
||||
* |
||||
* Its values are either 'transparent' or 'opaque'. If it's transparent, it |
||||
* means that this calendar will not be taken into consideration when a |
||||
* different user queries for free-busy information. If it's 'opaque', it will. |
||||
* |
||||
* @package Sabre |
||||
* @subpackage CalDAV |
||||
* @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved. |
||||
* @author Evert Pot (http://www.rooftopsolutions.nl/) |
||||
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License |
||||
*/ |
||||
class Sabre_CalDAV_Property_ScheduleCalendarTransp extends Sabre_DAV_Property { |
||||
|
||||
const TRANSPARENT = 'transparent'; |
||||
const OPAQUE = 'opaque'; |
||||
|
||||
protected $value; |
||||
|
||||
/** |
||||
* Creates the property |
||||
* |
||||
* @param string $value |
||||
*/ |
||||
public function __construct($value) { |
||||
|
||||
if ($value !== self::TRANSPARENT && $value !== self::OPAQUE) { |
||||
throw new \InvalidArgumentException('The value must either be specified as "transparent" or "opaque"'); |
||||
} |
||||
$this->value = $value; |
||||
|
||||
} |
||||
|
||||
/** |
||||
* Returns the current value |
||||
* |
||||
* @return string |
||||
*/ |
||||
public function getValue() { |
||||
|
||||
return $this->value; |
||||
|
||||
} |
||||
|
||||
/** |
||||
* Serializes the property in a DOMDocument |
||||
* |
||||
* @param Sabre_DAV_Server $server |
||||
* @param DOMElement $node |
||||
* @return void |
||||
*/ |
||||
public function serialize(Sabre_DAV_Server $server,DOMElement $node) { |
||||
|
||||
$doc = $node->ownerDocument; |
||||
switch($this->value) { |
||||
case self::TRANSPARENT : |
||||
$xval = $doc->createElement('cal:transparent'); |
||||
break; |
||||
case self::OPAQUE : |
||||
$xval = $doc->createElement('cal:opaque'); |
||||
break; |
||||
} |
||||
|
||||
$node->appendChild($xval); |
||||
|
||||
} |
||||
|
||||
/** |
||||
* Unserializes the DOMElement back into a Property class. |
||||
* |
||||
* @param DOMElement $node |
||||
* @return Sabre_CalDAV_Property_ScheduleCalendarTransp |
||||
*/ |
||||
static function unserialize(DOMElement $node) { |
||||
|
||||
$value = null; |
||||
foreach($node->childNodes as $childNode) { |
||||
switch(Sabre_DAV_XMLUtil::toClarkNotation($childNode)) { |
||||
case '{' . Sabre_CalDAV_Plugin::NS_CALDAV . '}opaque' : |
||||
$value = self::OPAQUE; |
||||
break; |
||||
case '{' . Sabre_CalDAV_Plugin::NS_CALDAV . '}transparent' : |
||||
$value = self::TRANSPARENT; |
||||
break; |
||||
} |
||||
} |
||||
if (is_null($value)) |
||||
return null; |
||||
|
||||
return new self($value); |
||||
|
||||
} |
||||
} |
||||
@ -1,68 +0,0 @@ |
||||
<?php |
||||
|
||||
/** |
||||
* CalDAV server |
||||
* |
||||
* Deprecated! Warning: This class is now officially deprecated |
||||
* |
||||
* This script is a convenience script. It quickly sets up a WebDAV server |
||||
* with caldav and ACL support, and it creates the root 'principals' and |
||||
* 'calendars' collections. |
||||
* |
||||
* Note that if you plan to do anything moderately complex, you are advised to |
||||
* not subclass this server, but use Sabre_DAV_Server directly instead. This |
||||
* class is nothing more than an 'easy setup'. |
||||
* |
||||
* @package Sabre |
||||
* @subpackage CalDAV |
||||
* @deprecated Don't use this class anymore, it will be removed in version 1.7. |
||||
* @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved. |
||||
* @author Evert Pot (http://www.rooftopsolutions.nl/) |
||||
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License |
||||
*/ |
||||
class Sabre_CalDAV_Server extends Sabre_DAV_Server { |
||||
|
||||
/** |
||||
* The authentication realm |
||||
* |
||||
* Note that if this changes, the hashes in the auth backend must also |
||||
* be recalculated. |
||||
* |
||||
* @var string |
||||
*/ |
||||
public $authRealm = 'SabreDAV'; |
||||
|
||||
/** |
||||
* Sets up the object. A PDO object must be passed to setup all the backends. |
||||
* |
||||
* @param PDO $pdo |
||||
*/ |
||||
public function __construct(PDO $pdo) { |
||||
|
||||
/* Backends */ |
||||
$authBackend = new Sabre_DAV_Auth_Backend_PDO($pdo); |
||||
$calendarBackend = new Sabre_CalDAV_Backend_PDO($pdo); |
||||
$principalBackend = new Sabre_DAVACL_PrincipalBackend_PDO($pdo); |
||||
|
||||
/* Directory structure */ |
||||
$tree = array( |
||||
new Sabre_CalDAV_Principal_Collection($principalBackend), |
||||
new Sabre_CalDAV_CalendarRootNode($principalBackend, $calendarBackend), |
||||
); |
||||
|
||||
/* Initializing server */ |
||||
parent::__construct($tree); |
||||
|
||||
/* Server Plugins */ |
||||
$authPlugin = new Sabre_DAV_Auth_Plugin($authBackend,$this->authRealm); |
||||
$this->addPlugin($authPlugin); |
||||
|
||||
$aclPlugin = new Sabre_DAVACL_Plugin(); |
||||
$this->addPlugin($aclPlugin); |
||||
|
||||
$caldavPlugin = new Sabre_CalDAV_Plugin(); |
||||
$this->addPlugin($caldavPlugin); |
||||
|
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,72 @@ |
||||
<?php |
||||
|
||||
/** |
||||
* This object represents a CalDAV calendar that can be shared with other |
||||
* users. |
||||
* |
||||
* @package Sabre |
||||
* @subpackage CalDAV |
||||
* @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved. |
||||
* @author Evert Pot (http://www.rooftopsolutions.nl/) |
||||
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License |
||||
*/ |
||||
class Sabre_CalDAV_ShareableCalendar extends Sabre_CalDAV_Calendar implements Sabre_CalDAV_IShareableCalendar { |
||||
|
||||
/** |
||||
* Updates the list of shares. |
||||
* |
||||
* The first array is a list of people that are to be added to the |
||||
* calendar. |
||||
* |
||||
* Every element in the add array has the following properties: |
||||
* * href - A url. Usually a mailto: address |
||||
* * commonName - Usually a first and last name, or false |
||||
* * summary - A description of the share, can also be false |
||||
* * readOnly - A boolean value |
||||
* |
||||
* Every element in the remove array is just the address string. |
||||
* |
||||
* @param array $add |
||||
* @param array $remove |
||||
* @return void |
||||
*/ |
||||
public function updateShares(array $add, array $remove) { |
||||
|
||||
$this->caldavBackend->updateShares($this->calendarInfo['id'], $add, $remove); |
||||
|
||||
} |
||||
|
||||
/** |
||||
* Returns the list of people whom this calendar is shared with. |
||||
* |
||||
* Every element in this array should have the following properties: |
||||
* * href - Often a mailto: address |
||||
* * commonName - Optional, for example a first + last name |
||||
* * status - See the Sabre_CalDAV_SharingPlugin::STATUS_ constants. |
||||
* * readOnly - boolean |
||||
* * summary - Optional, a description for the share |
||||
* |
||||
* @return array |
||||
*/ |
||||
public function getShares() { |
||||
|
||||
return $this->caldavBackend->getShares($this->calendarInfo['id']); |
||||
|
||||
} |
||||
|
||||
/** |
||||
* Marks this calendar as published. |
||||
* |
||||
* Publishing a calendar should automatically create a read-only, public, |
||||
* subscribable calendar. |
||||
* |
||||
* @param bool $value |
||||
* @return void |
||||
*/ |
||||
public function setPublishStatus($value) { |
||||
|
||||
$this->caldavBackend->setPublishStatus($this->calendarInfo['id'], $value); |
||||
|
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,98 @@ |
||||
<?php |
||||
|
||||
/** |
||||
* This object represents a CalDAV calendar that is shared by a different user. |
||||
* |
||||
* @package Sabre |
||||
* @subpackage CalDAV |
||||
* @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved. |
||||
* @author Evert Pot (http://www.rooftopsolutions.nl/) |
||||
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License |
||||
*/ |
||||
class Sabre_CalDAV_SharedCalendar extends Sabre_CalDAV_Calendar implements Sabre_CalDAV_ISharedCalendar { |
||||
|
||||
/** |
||||
* Constructor |
||||
* |
||||
* @param Sabre_DAVACL_IPrincipalBackend $principalBackend |
||||
* @param Sabre_CalDAV_Backend_BackendInterface $caldavBackend |
||||
* @param array $calendarInfo |
||||
*/ |
||||
public function __construct(Sabre_DAVACL_IPrincipalBackend $principalBackend, Sabre_CalDAV_Backend_BackendInterface $caldavBackend, $calendarInfo) { |
||||
|
||||
$required = array( |
||||
'{http://calendarserver.org/ns/}shared-url', |
||||
'{http://sabredav.org/ns}owner-principal', |
||||
'{http://sabredav.org/ns}read-only', |
||||
); |
||||
foreach($required as $r) { |
||||
if (!isset($calendarInfo[$r])) { |
||||
throw new InvalidArgumentException('The ' . $r . ' property must be specified for SharedCalendar(s)'); |
||||
} |
||||
} |
||||
|
||||
parent::__construct($principalBackend, $caldavBackend, $calendarInfo); |
||||
|
||||
} |
||||
|
||||
/** |
||||
* This method should return the url of the owners' copy of the shared |
||||
* calendar. |
||||
* |
||||
* @return string |
||||
*/ |
||||
public function getSharedUrl() { |
||||
|
||||
return $this->calendarInfo['{http://calendarserver.org/ns/}shared-url']; |
||||
|
||||
} |
||||
|
||||
/** |
||||
* Returns the owner principal |
||||
* |
||||
* This must be a url to a principal, or null if there's no owner |
||||
* |
||||
* @return string|null |
||||
*/ |
||||
public function getOwner() { |
||||
|
||||
return $this->calendarInfo['{http://sabredav.org/ns}owner-principal']; |
||||
|
||||
} |
||||
|
||||
/** |
||||
* Returns a list of ACE's for this node. |
||||
* |
||||
* Each ACE has the following properties: |
||||
* * 'privilege', a string such as {DAV:}read or {DAV:}write. These are |
||||
* currently the only supported privileges |
||||
* * 'principal', a url to the principal who owns the node |
||||
* * 'protected' (optional), indicating that this ACE is not allowed to |
||||
* be updated. |
||||
* |
||||
* @return array |
||||
*/ |
||||
public function getACL() { |
||||
|
||||
// The top-level ACL only contains access information for the true |
||||
// owner of the calendar, so we need to add the information for the |
||||
// sharee. |
||||
$acl = parent::getACL(); |
||||
$acl[] = array( |
||||
'privilege' => '{DAV:}read', |
||||
'principal' => $this->calendarInfo['principaluri'], |
||||
'protected' => true, |
||||
); |
||||
if (!$this->calendarInfo['{http://sabredav.org/ns}read-only']) { |
||||
$acl[] = array( |
||||
'privilege' => '{DAV:}write', |
||||
'principal' => $this->calendarInfo['principaluri'], |
||||
'protected' => true, |
||||
); |
||||
} |
||||
return $acl; |
||||
|
||||
} |
||||
|
||||
|
||||
} |
||||
@ -0,0 +1,475 @@ |
||||
<?php |
||||
|
||||
/** |
||||
* This plugin implements support for caldav sharing. |
||||
* |
||||
* This spec is defined at: |
||||
* http://svn.calendarserver.org/repository/calendarserver/CalendarServer/trunk/doc/Extensions/caldav-sharing.txt |
||||
* |
||||
* See: |
||||
* Sabre_CalDAV_Backend_SharingSupport for all the documentation. |
||||
* |
||||
* Note: This feature is experimental, and may change in between different |
||||
* SabreDAV versions. |
||||
* |
||||
* @package Sabre |
||||
* @subpackage CalDAV |
||||
* @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved. |
||||
* @author Evert Pot (http://www.rooftopsolutions.nl/) |
||||
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License |
||||
*/ |
||||
class Sabre_CalDAV_SharingPlugin extends Sabre_DAV_ServerPlugin { |
||||
|
||||
/** |
||||
* These are the various status constants used by sharing-messages. |
||||
*/ |
||||
const STATUS_ACCEPTED = 1; |
||||
const STATUS_DECLINED = 2; |
||||
const STATUS_DELETED = 3; |
||||
const STATUS_NORESPONSE = 4; |
||||
const STATUS_INVALID = 5; |
||||
|
||||
/** |
||||
* Reference to SabreDAV server object. |
||||
* |
||||
* @var Sabre_DAV_Server |
||||
*/ |
||||
protected $server; |
||||
|
||||
/** |
||||
* This method should return a list of server-features. |
||||
* |
||||
* This is for example 'versioning' and is added to the DAV: header |
||||
* in an OPTIONS response. |
||||
* |
||||
* @return array |
||||
*/ |
||||
public function getFeatures() { |
||||
|
||||
return array('calendarserver-sharing'); |
||||
|
||||
} |
||||
|
||||
/** |
||||
* Returns a plugin name. |
||||
* |
||||
* Using this name other plugins will be able to access other plugins |
||||
* using Sabre_DAV_Server::getPlugin |
||||
* |
||||
* @return string |
||||
*/ |
||||
public function getPluginName() { |
||||
|
||||
return 'caldav-sharing'; |
||||
|
||||
} |
||||
|
||||
/** |
||||
* This initializes the plugin. |
||||
* |
||||
* This function is called by Sabre_DAV_Server, after |
||||
* addPlugin is called. |
||||
* |
||||
* This method should set up the required event subscriptions. |
||||
* |
||||
* @param Sabre_DAV_Server $server |
||||
* @return void |
||||
*/ |
||||
public function initialize(Sabre_DAV_Server $server) { |
||||
|
||||
$this->server = $server; |
||||
//$server->resourceTypeMapping['Sabre_CalDAV_IShareableCalendar'] = '{' . Sabre_CalDAV_Plugin::NS_CALENDARSERVER . '}shared-owner'; |
||||
$server->resourceTypeMapping['Sabre_CalDAV_ISharedCalendar'] = '{' . Sabre_CalDAV_Plugin::NS_CALENDARSERVER . '}shared'; |
||||
|
||||
array_push( |
||||
$this->server->protectedProperties, |
||||
'{' . Sabre_CalDAV_Plugin::NS_CALENDARSERVER . '}invite', |
||||
'{' . Sabre_CalDAV_Plugin::NS_CALENDARSERVER . '}allowed-sharing-modes', |
||||
'{' . Sabre_CalDAV_Plugin::NS_CALENDARSERVER . '}shared-url' |
||||
); |
||||
|
||||
$this->server->subscribeEvent('beforeGetProperties', array($this, 'beforeGetProperties')); |
||||
$this->server->subscribeEvent('afterGetProperties', array($this, 'afterGetProperties')); |
||||
$this->server->subscribeEvent('updateProperties', array($this, 'updateProperties')); |
||||
$this->server->subscribeEvent('unknownMethod', array($this,'unknownMethod')); |
||||
|
||||
} |
||||
|
||||
/** |
||||
* This event is triggered when properties are requested for a certain |
||||
* node. |
||||
* |
||||
* This allows us to inject any properties early. |
||||
* |
||||
* @param string $path |
||||
* @param Sabre_DAV_INode $node |
||||
* @param array $requestedProperties |
||||
* @param array $returnedProperties |
||||
* @return void |
||||
*/ |
||||
public function beforeGetProperties($path, Sabre_DAV_INode $node, &$requestedProperties, &$returnedProperties) { |
||||
|
||||
if ($node instanceof Sabre_CalDAV_IShareableCalendar) { |
||||
if (($index = array_search('{' . Sabre_CalDAV_Plugin::NS_CALENDARSERVER . '}invite', $requestedProperties))!==false) { |
||||
|
||||
unset($requestedProperties[$index]); |
||||
$returnedProperties[200]['{' . Sabre_CalDAV_Plugin::NS_CALENDARSERVER . '}invite'] = |
||||
new Sabre_CalDAV_Property_Invite( |
||||
$node->getShares() |
||||
); |
||||
|
||||
} |
||||
|
||||
} |
||||
if ($node instanceof Sabre_CalDAV_ISharedCalendar) { |
||||
if (($index = array_search('{' . Sabre_CalDAV_Plugin::NS_CALENDARSERVER . '}shared-url', $requestedProperties))!==false) { |
||||
|
||||
unset($requestedProperties[$index]); |
||||
$returnedProperties[200]['{' . Sabre_CalDAV_Plugin::NS_CALENDARSERVER . '}shared-url'] = |
||||
new Sabre_DAV_Property_Href( |
||||
$node->getSharedUrl() |
||||
); |
||||
|
||||
} |
||||
|
||||
} |
||||
|
||||
} |
||||
|
||||
/** |
||||
* This method is triggered *after* all properties have been retrieved. |
||||
* This allows us to inject the correct resourcetype for calendars that |
||||
* have been shared. |
||||
* |
||||
* @param string $path |
||||
* @param array $properties |
||||
* @param Sabre_DAV_INode $node |
||||
* @return void |
||||
*/ |
||||
public function afterGetProperties($path, &$properties, Sabre_DAV_INode $node) { |
||||
|
||||
if ($node instanceof Sabre_CalDAV_IShareableCalendar) { |
||||
if (isset($properties[200]['{DAV:}resourcetype'])) { |
||||
if (count($node->getShares())>0) { |
||||
$properties[200]['{DAV:}resourcetype']->add( |
||||
'{' . Sabre_CalDAV_Plugin::NS_CALENDARSERVER . '}shared-owner' |
||||
); |
||||
} |
||||
} |
||||
$propName = '{' . Sabre_CalDAV_Plugin::NS_CALENDARSERVER . '}allowed-sharing-modes'; |
||||
if (array_key_exists($propName, $properties[404])) { |
||||
unset($properties[404][$propName]); |
||||
$properties[200][$propName] = new Sabre_CalDAV_Property_AllowedSharingModes(true,false); |
||||
} |
||||
|
||||
} |
||||
|
||||
} |
||||
|
||||
/** |
||||
* This method is trigged when a user attempts to update a node's |
||||
* properties. |
||||
* |
||||
* A previous draft of the sharing spec stated that it was possible to use |
||||
* PROPPATCH to remove 'shared-owner' from the resourcetype, thus unsharing |
||||
* the calendar. |
||||
* |
||||
* Even though this is no longer in the current spec, we keep this around |
||||
* because OS X 10.7 may still make use of this feature. |
||||
* |
||||
* @param array $mutations |
||||
* @param array $result |
||||
* @param Sabre_DAV_INode $node |
||||
* @return void |
||||
*/ |
||||
public function updateProperties(array &$mutations, array &$result, Sabre_DAV_INode $node) { |
||||
|
||||
if (!$node instanceof Sabre_CalDAV_IShareableCalendar) |
||||
return; |
||||
|
||||
if (!isset($mutations['{DAV:}resourcetype'])) { |
||||
return; |
||||
} |
||||
|
||||
// Only doing something if shared-owner is indeed not in the list. |
||||
if($mutations['{DAV:}resourcetype']->is('{' . Sabre_CalDAV_Plugin::NS_CALENDARSERVER . '}shared-owner')) return; |
||||
|
||||
$shares = $node->getShares(); |
||||
$remove = array(); |
||||
foreach($shares as $share) { |
||||
$remove[] = $share['href']; |
||||
} |
||||
$node->updateShares(array(), $remove); |
||||
|
||||
// We're marking this update as 200 OK |
||||
$result[200]['{DAV:}resourcetype'] = null; |
||||
|
||||
// Removing it from the mutations list |
||||
unset($mutations['{DAV:}resourcetype']); |
||||
|
||||
} |
||||
|
||||
/** |
||||
* This event is triggered when the server didn't know how to handle a |
||||
* certain request. |
||||
* |
||||
* We intercept this to handle POST requests on calendars. |
||||
* |
||||
* @param string $method |
||||
* @param string $uri |
||||
* @return null|bool |
||||
*/ |
||||
public function unknownMethod($method, $uri) { |
||||
|
||||
if ($method!=='POST') { |
||||
return; |
||||
} |
||||
|
||||
// Only handling xml |
||||
$contentType = $this->server->httpRequest->getHeader('Content-Type'); |
||||
if (strpos($contentType,'application/xml')===false && strpos($contentType,'text/xml')===false) |
||||
return; |
||||
|
||||
// Making sure the node exists |
||||
try { |
||||
$node = $this->server->tree->getNodeForPath($uri); |
||||
} catch (Sabre_DAV_Exception_NotFound $e) { |
||||
return; |
||||
} |
||||
|
||||
|
||||
$dom = Sabre_DAV_XMLUtil::loadDOMDocument($this->server->httpRequest->getBody(true)); |
||||
|
||||
$documentType = Sabre_DAV_XMLUtil::toClarkNotation($dom->firstChild); |
||||
|
||||
switch($documentType) { |
||||
|
||||
// Dealing with the 'share' document, which modified invitees on a |
||||
// calendar. |
||||
case '{' . Sabre_CalDAV_Plugin::NS_CALENDARSERVER . '}share' : |
||||
|
||||
// We can only deal with IShareableCalendar objects |
||||
if (!$node instanceof Sabre_CalDAV_IShareableCalendar) { |
||||
return; |
||||
} |
||||
|
||||
// Getting ACL info |
||||
$acl = $this->server->getPlugin('acl'); |
||||
|
||||
// If there's no ACL support, we allow everything |
||||
if ($acl) { |
||||
$acl->checkPrivileges($uri, '{DAV:}write'); |
||||
} |
||||
|
||||
$mutations = $this->parseShareRequest($dom); |
||||
|
||||
$node->updateShares($mutations[0], $mutations[1]); |
||||
|
||||
$this->server->httpResponse->sendStatus(200); |
||||
// Adding this because sending a response body may cause issues, |
||||
// and I wanted some type of indicator the response was handled. |
||||
$this->server->httpResponse->setHeader('X-Sabre-Status', 'everything-went-well'); |
||||
|
||||
// Breaking the event chain |
||||
return false; |
||||
|
||||
// The invite-reply document is sent when the user replies to an |
||||
// invitation of a calendar share. |
||||
case '{'. Sabre_CalDAV_Plugin::NS_CALENDARSERVER.'}invite-reply' : |
||||
|
||||
// This only works on the calendar-home-root node. |
||||
if (!$node instanceof Sabre_CalDAV_UserCalendars) { |
||||
return; |
||||
} |
||||
|
||||
// Getting ACL info |
||||
$acl = $this->server->getPlugin('acl'); |
||||
|
||||
// If there's no ACL support, we allow everything |
||||
if ($acl) { |
||||
$acl->checkPrivileges($uri, '{DAV:}write'); |
||||
} |
||||
|
||||
$message = $this->parseInviteReplyRequest($dom); |
||||
|
||||
$url = $node->shareReply( |
||||
$message['href'], |
||||
$message['status'], |
||||
$message['calendarUri'], |
||||
$message['inReplyTo'], |
||||
$message['summary'] |
||||
); |
||||
|
||||
$this->server->httpResponse->sendStatus(200); |
||||
// Adding this because sending a response body may cause issues, |
||||
// and I wanted some type of indicator the response was handled. |
||||
$this->server->httpResponse->setHeader('X-Sabre-Status', 'everything-went-well'); |
||||
|
||||
if ($url) { |
||||
$dom = new DOMDocument('1.0', 'UTF-8'); |
||||
$dom->formatOutput = true; |
||||
|
||||
$root = $dom->createElement('cs:shared-as'); |
||||
foreach($this->server->xmlNamespaces as $namespace => $prefix) { |
||||
$root->setAttribute('xmlns:' . $prefix, $namespace); |
||||
} |
||||
|
||||
$dom->appendChild($root); |
||||
$href = new Sabre_DAV_Property_Href($url); |
||||
|
||||
$href->serialize($this->server, $root); |
||||
$this->server->httpResponse->setHeader('Content-Type','application/xml'); |
||||
$this->server->httpResponse->sendBody($dom->saveXML()); |
||||
|
||||
} |
||||
|
||||
// Breaking the event chain |
||||
return false; |
||||
|
||||
case '{' . Sabre_CalDAV_Plugin::NS_CALENDARSERVER . '}publish-calendar' : |
||||
|
||||
// We can only deal with IShareableCalendar objects |
||||
if (!$node instanceof Sabre_CalDAV_IShareableCalendar) { |
||||
return; |
||||
} |
||||
|
||||
// Getting ACL info |
||||
$acl = $this->server->getPlugin('acl'); |
||||
|
||||
// If there's no ACL support, we allow everything |
||||
if ($acl) { |
||||
$acl->checkPrivileges($uri, '{DAV:}write'); |
||||
} |
||||
|
||||
$node->setPublishStatus(true); |
||||
|
||||
// iCloud sends back the 202, so we will too. |
||||
$this->server->httpResponse->sendStatus(202); |
||||
|
||||
// Adding this because sending a response body may cause issues, |
||||
// and I wanted some type of indicator the response was handled. |
||||
$this->server->httpResponse->setHeader('X-Sabre-Status', 'everything-went-well'); |
||||
|
||||
// Breaking the event chain |
||||
return false; |
||||
|
||||
case '{' . Sabre_CalDAV_Plugin::NS_CALENDARSERVER . '}unpublish-calendar' : |
||||
|
||||
// We can only deal with IShareableCalendar objects |
||||
if (!$node instanceof Sabre_CalDAV_IShareableCalendar) { |
||||
return; |
||||
} |
||||
|
||||
// Getting ACL info |
||||
$acl = $this->server->getPlugin('acl'); |
||||
|
||||
// If there's no ACL support, we allow everything |
||||
if ($acl) { |
||||
$acl->checkPrivileges($uri, '{DAV:}write'); |
||||
} |
||||
|
||||
$node->setPublishStatus(false); |
||||
|
||||
$this->server->httpResponse->sendStatus(200); |
||||
|
||||
// Adding this because sending a response body may cause issues, |
||||
// and I wanted some type of indicator the response was handled. |
||||
$this->server->httpResponse->setHeader('X-Sabre-Status', 'everything-went-well'); |
||||
|
||||
// Breaking the event chain |
||||
return false; |
||||
|
||||
} |
||||
|
||||
|
||||
} |
||||
|
||||
/** |
||||
* Parses the 'share' POST request. |
||||
* |
||||
* This method returns an array, containing two arrays. |
||||
* The first array is a list of new sharees. Every element is a struct |
||||
* containing a: |
||||
* * href element. (usually a mailto: address) |
||||
* * commonName element (often a first and lastname, but can also be |
||||
* false) |
||||
* * readOnly (true or false) |
||||
* * summary (A description of the share, can also be false) |
||||
* |
||||
* The second array is a list of sharees that are to be removed. This is |
||||
* just a simple array with 'hrefs'. |
||||
* |
||||
* @param DOMDocument $dom |
||||
* @return array |
||||
*/ |
||||
protected function parseShareRequest(DOMDocument $dom) { |
||||
|
||||
$xpath = new \DOMXPath($dom); |
||||
$xpath->registerNamespace('cs', Sabre_CalDAV_Plugin::NS_CALENDARSERVER); |
||||
$xpath->registerNamespace('d', 'DAV:'); |
||||
|
||||
|
||||
$set = array(); |
||||
$elems = $xpath->query('cs:set'); |
||||
|
||||
for($i=0; $i < $elems->length; $i++) { |
||||
|
||||
$xset = $elems->item($i); |
||||
$set[] = array( |
||||
'href' => $xpath->evaluate('string(d:href)', $xset), |
||||
'commonName' => $xpath->evaluate('string(cs:common-name)', $xset), |
||||
'summary' => $xpath->evaluate('string(cs:summary)', $xset), |
||||
'readOnly' => $xpath->evaluate('boolean(cs:read)', $xset)!==false |
||||
); |
||||
|
||||
} |
||||
|
||||
$remove = array(); |
||||
$elems = $xpath->query('cs:remove'); |
||||
|
||||
for($i=0; $i < $elems->length; $i++) { |
||||
|
||||
$xremove = $elems->item($i); |
||||
$remove[] = $xpath->evaluate('string(d:href)', $xremove); |
||||
|
||||
} |
||||
|
||||
return array($set, $remove); |
||||
|
||||
} |
||||
|
||||
/** |
||||
* Parses the 'invite-reply' POST request. |
||||
* |
||||
* This method returns an array, containing the following properties: |
||||
* * href - The sharee who is replying |
||||
* * status - One of the self::STATUS_* constants |
||||
* * calendarUri - The url of the shared calendar |
||||
* * inReplyTo - The unique id of the share invitation. |
||||
* * summary - Optional description of the reply. |
||||
* |
||||
* @param DOMDocument $dom |
||||
* @return array |
||||
*/ |
||||
protected function parseInviteReplyRequest(DOMDocument $dom) { |
||||
|
||||
$xpath = new \DOMXPath($dom); |
||||
$xpath->registerNamespace('cs', Sabre_CalDAV_Plugin::NS_CALENDARSERVER); |
||||
$xpath->registerNamespace('d', 'DAV:'); |
||||
|
||||
$hostHref = $xpath->evaluate('string(cs:hosturl/d:href)'); |
||||
if (!$hostHref) { |
||||
throw new Sabre_DAV_Exception_BadRequest('The {' . Sabre_CalDAV_Plugin::NS_CALENDARSERVER . '}hosturl/{DAV:}href element is required'); |
||||
} |
||||
|
||||
return array( |
||||
'href' => $xpath->evaluate('string(d:href)'), |
||||
'calendarUri' => $this->server->calculateUri($hostHref), |
||||
'inReplyTo' => $xpath->evaluate('string(cs:in-reply-to)'), |
||||
'summary' => $xpath->evaluate('string(cs:summary)'), |
||||
'status' => $xpath->evaluate('boolean(cs:invite-accepted)')?self::STATUS_ACCEPTED:self::STATUS_DECLINED |
||||
); |
||||
|
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,107 @@ |
||||
<?php |
||||
|
||||
use Sabre\VObject; |
||||
|
||||
/** |
||||
* VCF Exporter |
||||
* |
||||
* This plugin adds the ability to export entire address books as .vcf files. |
||||
* This is useful for clients that don't support CardDAV yet. They often do |
||||
* support vcf files. |
||||
* |
||||
* @package Sabre |
||||
* @subpackage CardDAV |
||||
* @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved. |
||||
* @author Evert Pot (http://www.rooftopsolutions.nl/) |
||||
* @author Thomas Tanghus (http://tanghus.net/) |
||||
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License |
||||
*/ |
||||
class Sabre_CardDAV_VCFExportPlugin extends Sabre_DAV_ServerPlugin { |
||||
|
||||
/** |
||||
* Reference to Server class |
||||
* |
||||
* @var Sabre_DAV_Server |
||||
*/ |
||||
private $server; |
||||
|
||||
/** |
||||
* Initializes the plugin and registers event handlers |
||||
* |
||||
* @param Sabre_DAV_Server $server |
||||
* @return void |
||||
*/ |
||||
public function initialize(Sabre_DAV_Server $server) { |
||||
|
||||
$this->server = $server; |
||||
$this->server->subscribeEvent('beforeMethod',array($this,'beforeMethod'), 90); |
||||
|
||||
} |
||||
|
||||
/** |
||||
* 'beforeMethod' event handles. This event handles intercepts GET requests ending |
||||
* with ?export |
||||
* |
||||
* @param string $method |
||||
* @param string $uri |
||||
* @return bool |
||||
*/ |
||||
public function beforeMethod($method, $uri) { |
||||
|
||||
if ($method!='GET') return; |
||||
if ($this->server->httpRequest->getQueryString()!='export') return; |
||||
|
||||
// splitting uri |
||||
list($uri) = explode('?',$uri,2); |
||||
|
||||
$node = $this->server->tree->getNodeForPath($uri); |
||||
|
||||
if (!($node instanceof Sabre_CardDAV_IAddressBook)) return; |
||||
|
||||
// Checking ACL, if available. |
||||
if ($aclPlugin = $this->server->getPlugin('acl')) { |
||||
$aclPlugin->checkPrivileges($uri, '{DAV:}read'); |
||||
} |
||||
|
||||
$this->server->httpResponse->setHeader('Content-Type','text/directory'); |
||||
$this->server->httpResponse->sendStatus(200); |
||||
|
||||
$nodes = $this->server->getPropertiesForPath($uri, array( |
||||
'{' . Sabre_CardDAV_Plugin::NS_CARDDAV . '}address-data', |
||||
),1); |
||||
|
||||
$this->server->httpResponse->sendBody($this->generateVCF($nodes)); |
||||
|
||||
// Returning false to break the event chain |
||||
return false; |
||||
|
||||
} |
||||
|
||||
/** |
||||
* Merges all vcard objects, and builds one big vcf export |
||||
* |
||||
* @param array $nodes |
||||
* @return string |
||||
*/ |
||||
public function generateVCF(array $nodes) { |
||||
|
||||
$output = ""; |
||||
|
||||
foreach($nodes as $node) { |
||||
|
||||
if (!isset($node[200]['{' . Sabre_CardDAV_Plugin::NS_CARDDAV . '}address-data'])) { |
||||
continue; |
||||
} |
||||
$nodeData = $node[200]['{' . Sabre_CardDAV_Plugin::NS_CARDDAV . '}address-data']; |
||||
|
||||
// Parsing this node so VObject can clean up the output. |
||||
$output .= |
||||
VObject\Reader::read($nodeData)->serialize(); |
||||
|
||||
} |
||||
|
||||
return $output; |
||||
|
||||
} |
||||
|
||||
} |
||||
|
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 4.2 KiB |
|
Before Width: | Height: | Size: 7.1 KiB After Width: | Height: | Size: 7.1 KiB |
|
Before Width: | Height: | Size: 4.3 KiB After Width: | Height: | Size: 4.3 KiB |
|
Before Width: | Height: | Size: 5.6 KiB After Width: | Height: | Size: 5.6 KiB |
|
Before Width: | Height: | Size: 3.4 KiB After Width: | Height: | Size: 3.4 KiB |
|
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 2.8 KiB |
|
Before Width: | Height: | Size: 3.4 KiB After Width: | Height: | Size: 3.4 KiB |
|
Before Width: | Height: | Size: 5.4 KiB After Width: | Height: | Size: 5.4 KiB |
@ -1,17 +0,0 @@ |
||||
<?php |
||||
|
||||
/** |
||||
* Directory class |
||||
* |
||||
* This class is now deprecated in favor of the Sabre_DAV_Collection class. |
||||
* |
||||
* @package Sabre |
||||
* @subpackage DAV |
||||
* @deprecated Use Sabre_DAV_Collection instead |
||||
* @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved. |
||||
* @author Evert Pot (http://www.rooftopsolutions.nl/) |
||||
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License |
||||
*/ |
||||
abstract class Sabre_DAV_Directory extends Sabre_DAV_Collection { |
||||
} |
||||
|
||||