Upgrading from SabreDAV 1.0 to 1.2
To keep the SabreDAV simple to use and to extend, I wanted to make a few changes.
Distribution
Before SabreDAV was distributed as a single .tgz. This is now a zip file. The pear installation is separate and comes as 4 separate packages.
- Sabre
- Sabre_HTTP
- Sabre_DAV
- Sabre_CalDAV
This forces a clearer separation of concerns and allows people to ignore packages they might not need.
All of these are installable from the PEAR channel. The old package must be uninstalled for installation to succeed. This process goes as follows:
pear uninstall Sabre_DAV
# If you hadn't added the new channel:
pear channel-discover pear.sabredav.org
pear install Sabre Sabre_HTTP Sabre_DAV Sabre_CalDAV
Sabre_DAV_Auth_*
Backends structure changed
If you had your own Authentication backend defined, based on
Sabre_DAV_Auth_Backend_Abstract
you need to change that declaration to
Sabre_DAV_Auth_Backend_AbstractDigest
.
The 'Abstract' backend class can be used to create any generic authentication backend, instead of just HTTP Digest.
In addition, some method signatures were changed:
Old code:
class MyAuthenticationClass extends Sabre_DAV_Auth_Backend_Abstract {
function getDigestHash($userName) {
// This function would normally return the digest hash
// This method is removed in favor of getUserInfo
}
function getUsers() {
// Before this method would return a 'userId' per user
// This should now be the uri.
// This is still optional to implement.
}
}
New code:
class MyAuthenticationClass extends Sabre_DAV_Auth_Backend_AbstractDigest {
function getUserInfo($realm, $username) {
// This function returns user information
// based on the realm and username
// the returned data is an array. The array must contain the
// following 2 keys:
// 1. uri This is a path to the user. The path does not have to exist
// unless CalDAV or similar standards have to be implemented.
// It's a good idea to name it '/principals/username'
// 2. digestHash This is the digest hash that was used to returned
// from the old getDigestHash function.
}
function getUsers() {
// Before this method would return a 'userId' per user
// This should now be the uri.
// This is still optional to implement.
}
}
Sabre_DAV comes with both a File
and a PDO
authentication backend, which
can be used as an easy reference.
PermissionDenied exception is now called Forbidden
Old code:
throw new Sabre_DAV_Exception_PermissionDenied('Message..');
New code:
throw new Sabre_DAV_Exception_Forbidden('Message..');
Full backwards compatibility is provided, but 'PermissionDenied' will be removed at some point in the future.
IDirectory is now called ICollection
The IDirectory interface has gotten renamed to ICollection. The signature has not changed.
Old code:
class MyClass implements Sabre_DAV_IDirectory {
/* .... */
}
New code:
class MyClass implements Sabre_DAV_ICollection {
/* .... */
}
Property updating has changed quite a bit
If you implemented custom properties, and specifically updating custom properties in your plugins or Nodes, take note.
The old request and response was quite complicated, but this was simplified quite a bit.
Old code:
function updateProperties($mutations) {
// mutations is an array that looked something
// like this:
$mutations = array(
array(Sabre_DAV_Server::PROP_SET, '{http://www.example.org/ns}nodename', 'value'),
array(Sabre_DAV_Server::PROP_REMOVE, '{http://www.example.org/ns}nodename2'),
);
// The returned value contains a list of all the properties again, along
// with the statuscode for the change.
return array(
array('{http://www.example.org/ns}nodename', 201),
array('{http://www.example.org/ns}nodename2', 200),
);
}
New code:
function updateProperties($mutations) {
// Mutations is now a simple list. If a value is null
// it should be removed.
// It looks kind of like this:
$mutations = array(
'{http://www.example.org/ns}nodename' => 'value',
'{http://www.example.org/ns}nodename2' => null,
);
// The returned value should now simply be 'true' for
// success, or false or an exception for failure.
return true;
// If you do want to tell the client in detail which mutation
// caused the request to fail, it is still allowed in this new
// return structure:
return array(
// Permission denied
403 => array(
'{http://www.example.org/ns}nodename' => null,
),
424 => array(
'{http://www.example.org/ns}nodename2' => null,
),
);
// The values are always null in the previous array. This format
// was chosen because it has the exact same structure as the result
// of PROPFIND, which also generates a multi-status response.
}
Locks_File backend now requires a constructor argument
The Sabre_DAV_Locks_Backend_FS
class now requires an argument. The argument
specifies where lock information is stored:
$backend = Sabre_DAV_Locks_Backend_FS('/path/to/locks/directory');
Before the locks backend would use the same directory PHP uses to store session files, but this was considered a poor choice. So it seems better to make the user choose this one.
XML namespace change
All custom SabreDAV properties used to fall under the following namespace:
- http://www.rooftopsolutions.nl/NS/sabredav
This has been changed to:
- http://sabredav.org/ns
"Sabre.autoload.php" and "Sabre.includes.php"
The lib/Sabre.includes.php
file is now deprecated and should no longer be
used. Because Sabre_DAV is split up over multiple packages, this no longer
makes sense.
In the future this might come back as lib/Sabre/DAV/includes.php
,
lib/Sabre/HTTP/includes.php
, etc.
The autoload file is now moved from:
lib/Sabre.autoload.php
to:
lib/Sabre/autoload.php
This makes more sense for packaging. The old one also still works, but will be removed at one point in the future.