Upgrading from SabreDAV 1.2 to 1.3

A few changes were needed in SabreDAV to improve future compatibility, unfortunately this breaks backwards compatibility. The changes are minimal though.

Etags must be surrounded by double-quotes

This was a bug in SabreDAV since the start. All Etags must be surrounded by double-quotes everywhere. The best way to implement this was to enforce all getETag methods to include the quotes.

If your code looked like this:

function getETag() {

    return $this->myETag;


ensure it's changed to this:

function getETag() {

    return '"' . $this->myETag . '"';


Sabre_DAV_PermissionDenied and Sabre_DAV_IDirectory are removed

The Sabre_DAV_PermissionDenied class is replaced by the Sabre_DAV_Forbidden class.

The Sabre_DAV_IDirectory interface is replaced by the Sabre_DAV_ICollection interface.

If you use either of these, this affects you. These classes were already deprecated in 1.1.1, but now finally removed.

Sabre_DAV_ICollection interface has nodeExists method

If you rolled your custom Collections, and you directly 'implemented' Sabre_DAV_ICollection, without using one of the helper classes, you must now implement nodeExists($path).

This method takes a path-part, and must return true or false.

beforeMethod and unknownMethod now receive new arguments

If you are a plugin developer, and rely on either of these events, this is relevant to you.

Both the beforeMethod and unknownMethod event now receive a $method and $uri argument.

You should now use this $uri argument, instead of relying on Sabre_DAV_Server::getRequestUri().

While it won't affect you in the short-term, if future plugins are going to re-route requests to new uri's, the getRequestUri() method will return the original uri, and not the uri it was rerouted to.

ObjectTree now cached

If you are a plugin developer, this might be relevant.

ObjectTree now caches nodes where possible. This is a huge performance increase, especially for complex systems such as the CalDAV plugin.

The cache is per-request, and not stored in an external cache system.

If you were manually adding new nodes on the fly, deleting, copying or moving from your plugin, make sure you clear the cache.

To do this, call $tree->markDirty($path); Where $path is the subtree you want to evict from the cache.

To take advantage of the cache, use the new Tree methods:

If you developed your custom tree, using Sabre_DAV_ObjectTree as the parent-class, and overriding either copy(), move() or copyNode(), also make sure you call markDirty($path) after any tree-mutation.