Provider API

A provider plugin implements LH_DAV_Collection_Provider and adds an instance on the lh_dav_collection_providers filter. Its methods are the provider’s service API: permission checks live inside them, and tooling plugins (admin screens, MCP abilities) call them rather than the provider’s storage, so a phone and any tool see the same data under the same rules.

interface LH_DAV_Collection_Provider {
    public function get_component();                                 // 'addressbook' or 'calendar'
    public function get_collections( $user_id );                      // array of collection descriptions
    public function get_resource_index( $collection_id, $user_id );   // name => quoted ETag
    public function get_resources( $collection_id, $names, $user_id );// name => body
    public function put_resource( $collection_id, $name, $body, $user_id ); // new ETag
    public function delete_resource( $collection_id, $name, $user_id );     // true
}

add_filter( 'lh_dav_collection_providers', function ( $providers ) {
    $providers[] = new My_Contacts_Provider();
    return $providers;
} );

Any method may return a WP_Error; a status in its data becomes the HTTP status. Resource names include the extension and must match [A-Za-z0-9._@+-]+.

Collection description

Managing collections from devices

Since 0.3.0 a provider can also implement LH_DAV_Collection_Manager, letting users make collections (MKCALENDAR, or an extended MKCOL per RFC 5689), rename, recolour and reorder them (PROPPATCH) and delete them (DELETE on the collection). LH DAV makes new collections with the first manager in the component whose can_create_collections() says yes, advertises bind on the home when one does, and only lets a user change or delete a collection whose owner is that user.

interface LH_DAV_Collection_Manager {
    public function can_create_collections( $user_id );                          // bool
    public function create_collection( $collection_id, $properties, $user_id );  // true
    public function update_collection( $collection_id, $properties, $user_id );  // true
    public function delete_collection( $collection_id, $user_id );               // true
}
// $properties: displayname, description, color (#RRGGBB or ''), order, components (create only)

PROPPATCH is all or nothing: if any property cannot be changed none is, and the rest report 424. Colour and order are accepted on any collection, and stored only where the user manages it, so a phone recolouring a read-only calendar sees no error.

Recording changes

Writes through DAV are recorded by LH DAV, against the collection’s site_id. Changes made on the site must be recorded by the provider, against the same site, or devices will not see them on the next sync:

LH_DAV_Change_Log::record( 'addressbook', 0, 'members', '42.vcf', 'modified' ); // or 'deleted'; optional sixth argument: site ID

Service API for tooling