Digital Sovereignty for everyone

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

  • id (required): slug, unique within its home across all providers
  • owner: 0 for a collection shared by the site, or the owning user’s ID
  • displayname, description
  • writable: whether PUT and DELETE are offered
  • state: anything that, when it changes, means every resource must be resent (for example what the viewer may see, or a card format version)
  • site_id (since 0.3.0): the site whose change log feeds the collection, the current site by default. Set it when the data is not per site (network-wide personal data, or another site’s content served on the user’s home site), so changes are recorded and read in one place.
  • Calendars only: color (#RRGGBB), components (default VEVENT; VTODO, VJOURNAL) and, since 0.3.0, order (Apple’s calendar-order)

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

  • LH_DAV_Setup_Profile::get_setup_details(): the current user’s server, well-known and principal URLs, homes, username and collections (with item counts). Needs the access capability.
  • LH_DAV_Change_Log::get_entries( $args ): change log rows newest first, filtered by site_id, collection, resource, since, limit (up to 500), plus the latest and pruned-through sequences. Needs install_plugins.
  • LH_DAV_Setup_Profile::return_download_url(): a nonce-carrying setup profile link for the current user, or an empty string. Since 0.3.0 the profile leaves out contacts or calendars when the user has no collections of that kind on the site.
  • LH_DAV_Registry::get_collections(), get_manager() and is_manageable().

If you like this plugin please consider making a donation to further development

Install LHero.org

lhero.org

Open it straight from your home screen, full screen and quicker to load.

  1. Tap the Share button . If you cannot see it, tap ••• first.
  2. Scroll down and tap Add to Home Screen.
  3. Tap Add.
  1. Tap the browser menu â‹®.
  2. Tap Install app or Add to Home screen.
  1. In the menu bar, choose File, then Add to Dock.

Use your browser's menu to install this site or add it to your home screen.