Upgrading from SabreDAV 2.1 to 3.0

sabre/dav 3.0 is the latest and greatest version. This release contains a lot of incremental improvements that improve the code-base and improve compatibility with various clients.

New features

API Changes and BC breaks

The following few chapters detail all the BC breaking changes that have been made. We've ordered them loosely in order of likelihood that the changes are relevant to you. Chances are that if you have never done any custom sabre/dav development, only the first item might be relevant to you.

Updated database structure

This only matters if you used the property storage PDO backend and plugin.

Because of the changes that were made to the propertystorage system, a few database changes have to be made as well. If you take advantage of the property storage system you must run the migration script.

To do so, simply fire up:

bin/migrateto30.php 

in your terminal. Doing so will display help information on how to do the update. You should really make a backup first.

Changed Authentication backend API.

This affects you if you created a custom authentication backend.

Specifically, if you extended AbstractBasic or AbstractDigest, there is nothing you have to change, but if you directly implemented Sabre\DAV\Auth\Backend\BackendInterface you have to be aware there's a big difference.

Before there was a single authentication method, where you had to do all your authentication work. Now we've split that up into a check and challenge method.

By splitting these two up, it becomes possible to use multiple authentication backends, where each backend can make an attempt to authenticate the user.

The authentication backends can now also control the exact principal that the user will be, allowing for much more complex principal systems.

Changed browser plugin

The browser plugin got a lot of new features, but its source also got reorganized. If you extended the browser plugin because you wanted to add your own branding, it will probably break.

Removed Sabre\DAV\Client methods.

The following two methods were removed from Sabre\DAV\Client:

These methods had already been deprecated a long time ago, but now they are finally gone. To achieve the same results, it's possible to call the addCurlSetting method.

Deprecated Sabre\DAV\Client::$propertyMap

The Sabre\DAV\Client::$propertyMap property has been deprecated. It still works and exists, but will be removed in a future version.

The property is now simply a reference to $client->xml->elementMap, which is the correct way to use this feature now.

Changed all constructors for all PDO backends

In versions before this one, it was possible to specify database table names right in the PDO backend. This allowed you to override the default table names.

Some of these constructors became quite large, so in version 2.1 we simply changed all of these to public properties instead, deprecating setting these in the constructor.

Starting 3.0 we also fully removed these. This means that if your code looked something like this:

$backend = new Sabre\CalDAV\Backend\PDO($pdo, 'my_calendar_table');

It must now be changed to

$backend = new Sabre\CalDAV\Backend\PDO($pdo);
$backend->calendarTableName = 'my_calendar_table';

Introducing sabre/uri

sabre/dav now makes use of the new sabre/uri library. Because of this occasion we removed the Sabre\DAV\URIUtil class, as all its functions were already solved in the new library. If you used this class, take a look at the sabre/uri docs to find out how to migrate.

Renamed UserAddressBooks.

To improve clarity and consistency, Sabre\CardDAV\UserAddressBooks has been renamed to Sabre\CardDAV\AddressBookHome.

If you ever needed to instantiate this class manually, make sure you change the name.

Changed class and interface names

Because of the introduction of sabre/xml into sabre/dav, we had to rewrite almost every class dealing with xml code. We also took this opportunity to improve the organization of xml-related code.

If you've ever manually instantiated a property class, you might need to change this to the new class name.

This is table contains all the changed class names.

Old class name New class name
Sabre\CalDAV\Notifications\INotificationType Sabre\CalDAV\Xml\Notification\NotificationInterface
Sabre\CalDAV\Notifications\Notification\Invite Sabre\CalDAV\Xml\Notification\Invite
Sabre\CalDAV\Notifications\Notification\InviteReply Sabre\CalDAV\Xml\Notification\InviteReply
Sabre\CalDAV\Notifications\Notification\SystemStatus Sabre\CalDAV\Xml\Notification\SystemStatus
Sabre\CalDAV\Property\AllowedSharingModes Sabre\CalDAV\Xml\Property\AllowedSharingModes
Sabre\CalDAV\Property\EmailAddressSet Sabre\CalDAV\Xml\Property\EmailAddressSet
Sabre\CalDAV\Property\Invite Sabre\CalDAV\Xml\Property\Invite
Sabre\CalDAV\Property\ScheduleCalendarTransp Sabre\CalDAV\Xml\Property\ScheduleCalendarTransp
Sabre\CalDAV\Property\SupportedCalendarComponentSet Sabre\CalDAV\Xml\Property\SupportedCalendarComponentSet
Sabre\CalDAV\Property\SupportedCalendarData Sabre\CalDAV\Xml\Property\SupportedCalendarData
Sabre\CalDAV\Property\SupportedCollationSet Sabre\CalDAV\Xml\Property\SupportedCollationSet
Sabre\CardDAV\Property\SupportedAddressData Sabre\CardDAV\Xml\Property\SupportedAddressData
Sabre\CardDAV\Property\SupportedCollationSet Sabre\CardDAV\Xml\Property\SupportedCollationSet
Sabre\DAV\Property Sabre\Xml\Element
Sabre\DAV\Property\GetLastModified Sabre\DAV\Xml\Property\GetLastModified
Sabre\DAV\Property\Href Sabre\DAV\Xml\Property\Href
Sabre\DAV\Property\HrefList Sabre\DAV\Xml\Property\Href
Sabre\DAV\Property\IHref Sabre\DAV\Xml\Property\Href
Sabre\DAV\Property\LockDiscovery Sabre\DAV\Xml\Property\LockDiscovery
Sabre\DAV\Property\ResourceType Sabre\DAV\Xml\Property\ResourceType
Sabre\DAV\Property\Response Sabre\DAV\Xml\Element\Response
Sabre\DAV\Property\SupportedLock Sabre\DAV\Xml\Element\SupportedLock
Sabre\DAV\Property\SupportedMethodList Sabre\DAV\Xml\Element\SupportedMethodList
Sabre\DAV\Property\SupportedReportSet Sabre\DAV\Xml\Element\SupportedReportSet
Sabre\DAVACL\Property\Acl Sabre\DAVACL\Xml\Property\Acl
Sabre\DAVACL\Property\AclRestrictions Sabre\DAVACL\Xml\Property\AclRestrictions
Sabre\DAVACL\Property\CurrentUserPrivilegeSet Sabre\DAVACL\Xml\Property\CurrentUserPrivilegeSet
Sabre\DAVACL\Property\Principal Sabre\DAVACL\Xml\Property\Principal
Sabre\DAVACL\Property\SupportedPrivilegeSet Sabre\DAVACL\Xml\Property\SupportedPrivilegeSet

Deleted deprecated classes

Because of the changed XML functionality, and because we wanted to remove code that has been deprecated in previous versions, the following classes have been removed from the source:

Class name
Sabre\CalDAV\CalendarQueryParser
Sabre\CalDAV\CalendarRootNode
Sabre\CalDAV\UserCalendars
Sabre\CardDAV\AddressBookQueryParser
Sabre\DAV\Exception\FileNotFound
Sabre\DAV\Locks\Backend\FS
Sabre\DAV\PartialUpdate\IFile
Sabre\DAV\Property\ResponseList

XML Api changes

If you ever manually wrote or parsed xml or made your own custom properties, this might be relevant to you.

Before you could set your own custom xml namespaces with the xmlNamespaces property on the server class. This has now changed.

If your code was:

$server->xmlNamespaces['http://example.org/ns'] = 'ex';

It should now be:

$server->xml->namespaceMap['http://example.org/ns'] = 'ex';

If you had any custom complex properties, you need to make a similar change:

Old:

$server->propertyMap['{http://example.org/ns}element'] = 'MyElement';

New:

$server->xml->elementMap['{http://example.org/ns}element'] = 'MyElement';

Support for the Prefer header changed.

sabre/dav supported rfc7240 before it was an official rfc. Unfortunately when it became an rfc, the syntax slightly changed.

In version 3.0 we now support the new syntax (with backwards compatibility for the old syntax, as it's still broadly used). The internal API now uses the keywords that matches the new syntax, and no longer the old one.

This means that if you manually called $server->getHTTPPrefer() anywhere, you now get a different array back.

Old array:

[
    "return-asynch" => true,
    "return-minimal" => true,
    "return-representation" => true,
    "strict" => true,
    "lenient" => true,
    "wait" => 10
]

New array:

[
    "respond-async" => true,
    "return" => "minimal",
    "handling" => "strict",
    "wait" => 10,
]

The changes are:

FSExt no longer stores custom properties.

Because a few versions ago, the property storage plugin was introduced, it was no longer deemed needed to also store custom properties in these classes:

If you do need similar behavior, set up the property storage plugin. No way has been provided to migrate this data though, if you do really need this, we'll be happy to help you do it. Contact us on the mailing list.

Creating custom collections

If you call $server->createCollection(), or if you have a custom class implementing Sabre\DAV\IExtendedCollection, be aware that instead of a list of properties, you will now receive a Sabre\DAV\MKCol object.

This object works really similarly to Sabre\DAV\PropPatch and allows plugins to intercept specific properties when "extended MKCOL" requests are being made.

This was critical for ensuring that the property storage plugin could behave as expected for MKCOL.

The report event changed.

Before 3.0, the report event handlers would get an instance of the DOMDocument representing the report. Now they receive the parsed output from sabre/xml instead.

Going into this is a bit too much for this guide. If you are one of the really few that actually used this event, drop us a line. We'd be more than happy to make time for you and help you upgrade.