|
IntegrationGuide
IntroductionIf you are looking at SabreDAV to add CalDAV or CarDAV functionality to your existing application, you'll need to roll your own Backend classes. This guide explains how and where to do this. A simple CalDAV serverThe following example illustrates how you can setup a CalDAV server. This is also how you'd want to build up your own server. We're not using the simplified Sabre_CalDAV_Server, as it's only a convenience class and doesn't give you the flexibility of setting everything up manually. <?php
$pdo = new PDO('sqlite:data/db.sqlite');
$pdo->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);
//Mapping PHP errors to exceptions
function exception_error_handler($errno, $errstr, $errfile, $errline ) {
throw new ErrorException($errstr, 0, $errno, $errfile, $errline);
}
set_error_handler("exception_error_handler");
// Files we need
require_once 'lib/Sabre/autoload.php';
// Backends
$authBackend = new Sabre_DAV_Auth_Backend_PDO($pdo);
$principalBackend = new Sabre_DAVACL_PrincipalBackend_PDO($pdo);
$calendarBackend = new Sabre_CalDAV_Backend_PDO($pdo);
// Directory tree
$tree = array(
new Sabre_DAVACL_PrincipalCollection($principalBackend),
new Sabre_CalDAV_CalendarRootNode($principalBackend, $calendarBackend)
);
// The object tree needs in turn to be passed to the server class
$server = new Sabre_DAV_Server($tree);
// You are highly encouraged to set your WebDAV server base url. Without it,
// SabreDAV will guess, but the guess is not always correct. Putting the
// server on the root of the domain will improve compatibility.
$server->setBaseUri('/');
// Authentication plugin
$authPlugin = new Sabre_DAV_Auth_Plugin($authBackend,'SabreDAV');
$server->addPlugin($authPlugin);
// CalDAV plugin
$caldavPlugin = new Sabre_CalDAV_Plugin();
$server->addPlugin($caldavPlugin);
// ACL plugin
$aclPlugin = new Sabre_DAVACL_Plugin();
$server->addPlugin($aclPlugin);
// Support for html frontend
$browser = new Sabre_DAV_Browser_Plugin();
$server->addPlugin($browser);
// And off we go!
$server->exec();
To setup the sqlite database (or mysql, if you prefer), follow the instructions on the CalDAV page. Setting up a CardDAV server is extremely similar. For examples you can also head over to the CardDAV page or check the examples/ directory in the standard SabreDAV distribution. BackendsIf you want to integrate CalDAV into your existing infrastructure, you can do so by creating your own Authentication, Principal and Calendar backends. Depending on your needs you may want to replace all of them, or just the ones that make sense for your application. Your Authentication class needs to implement the Sabre_DAV_Auth_IBackend interface. If you want to use basic or digest authentication (the only widely supported authentication methods) you can also extend Sabre_DAV_Auth_Backend_AbstractDigest or Sabre_DAV_Auth_Backend_AbstractBasic. Sabre_DAV_Auth_Backend_PDO is a decent example for digest authentication. Your Calendar backend needs to extend Sabre_CalDAV_Backend_Abstract. Take a look at Sabre_CalDAV_Backend_PDO for an example. Lastly, the principal backend must implement Sabre_DAVACL_IPrincipalBackend. Principals are in the context of WebDAV either users or groups (or both). For CardDAV, you may also want to extend Sabre_CardDAV_Backend_Abstract, check Sabre_CardDAV_Backend_PDO for an example. Datamodel in a nutshellUsers are called 'principals' in WebDAV terminology. Principals are associated to a url. If your username is homer, the url could be /principals/homer or /principals/homer@example.org CalDAV and CardDAV clients may use this url to gather more information about the user. You must return this url from the Auth backend, and it will be used in the Calendar backend to return all the calendars from a specific user. Calendars are stored under for example: /calendars/homer@example.org/ A user has multiple calendars. An example of a calendar could for example be: /calendars/homer@example.org/work Calendar objects (events, todo's, journals) are stored as resources under this url: /calendars/homer@example.org/work/meeting.ics Similarly, by default addressbooks will be stored under /addressbooks/homer@example.org Specific addressbooks under there: /addressbooks/homer@example.org/book1 and vcards under there: /addressbooks/homer@example.org/book1/marge.vcf UUIDS, id's and urlsThere's a bunch id's you will need to keep track off. When CalDAV clients create new calendar objects, they will store them using a url. This url can look like for example /calendars/user@example.org/1b520550-d7ca-11df-937b-0800200c9a66/22bad740-d7ca-11df-937b-0800200c9a66.ics The last part of this url is the calendar object. You must make sure that when a CalDAV client stores a new object under a url, the client must be able to access the object using that url. This could mean you need to make a new database field for this url. Even though most clients use the uuid.ics format, you can't rely on the url to e an uuid. Any string could be sent, and upper/lowercase can vary. Therefore it's not a true uuid field. The Sabre_CalDAV_Backend_Abstract class also uses a generic 'id' field. This id is never sent to the client. It can hold any content, but it's specifically added to allow you to store for example a database id. Calendar objectsCalendar objects are 'iCalendar' formatted files. They can hold events, todo's or journals (although the latter is extremely uncommon). Generally they only hold one event each, but in the case of a recurring event with exceptions, they can hold multiple. Now, there's a good chance you want to map Calendar objects to an existing datamodel. If you do have to do this, you can do this with the VObject library, which is included with SabreDAV 1.4. The VObject library provides a parser and interface to iCalendar objects very similar to what simplexml does for xml. A simple usage guide can be found here. Although it must be said that the iCalendar standard can be difficult, especially when dealing with timezone and recurrence. If you need to parse out data from the events and todo's to store them in separate fields, I would still recommend keeping the actual full object around in a BLOB. This will ensure that you can easily parse out the data you need, while ensuring all the users' data is kept intact. VCardsVCards' structure are very similarly structured as iCalendars. You can also use the VObject library to work with them. You still need a basic understanding how vcards are structured. The VObject library just helps with parsing, traversing and manipulating them. | |
Thanks for the example!
Some code fixes
// Directory tree $tree = array( - new Sabre_DAV_Auth_PrincipalCollection?($principalBackend), + new Sabre_DAVACL_PrincipalCollection?($principalBackend), // 1.5 API change
-)); +);Thank you, fixed!