### Copy Server Example File Source: https://sabre.io/dav/caldav Copies the example CalDAV server configuration file to your project directory. This file contains the basic setup for the server. ```bash cp examples/calendarserver.php calendarserver.php ``` -------------------------------- ### Base URI Configuration Examples Source: https://sabre.io/dav/baseuri These values should be used with `$server->setBaseUri(...)` to match the example server file URLs. ```string /sabredav/server.php ``` ```string /sabredav/calendarserver.php ``` ```string /sabredav/addressbookserver.php ``` ```string /sabredav/groupwareserver.php ``` -------------------------------- ### Example Email Address for Discovery Source: https://sabre.io/dav/service-discovery Format for email-based account setup in supported clients. ```text john@example.org ``` -------------------------------- ### Principal Backend Prefix Examples Source: https://sabre.io/dav/principals Example prefixes that the PrincipalBackend must handle when using custom structures. ```text principals/users principals/groups ``` -------------------------------- ### Deploy Server Endpoint Source: https://sabre.io/dav/carddav Copies the example addressbook server script to the project root. ```bash cp examples/addressbookserver.php addressbookserver.php ``` -------------------------------- ### Example SabreDAV Server File URLs Source: https://sabre.io/dav/baseuri These are example URLs for accessing your SabreDAV server, depending on how you've set up your server file. ```http http://server.example.org/sabredav/server.php ``` ```http http://server.example.org/sabredav/calendarserver.php ``` ```http http://server.example.org/sabredav/addressbookserver.php ``` ```http http://server.example.org/sabredav/groupwareserver.php ``` -------------------------------- ### Full SabreDAV URL Example Source: https://sabre.io/dav/baseuri An example of a full URL to a resource within a SabreDAV server. ```http http://server.example.org/sabredav/server.php/files/photo.jpg ``` -------------------------------- ### Basic SabreDAV Server Setup Source: https://sabre.io/dav/per-user-directories Initializes a Sabre\DAV\Server with a custom collection and adds an authentication plugin. ```php addPlugin($authPlugin); $server->exec(); ``` -------------------------------- ### SabreDAV Server Setup with User Retrieval Source: https://sabre.io/dav/per-user-directories Reorganizes server setup to retrieve the current user's name via the authentication plugin before server execution. ```php getUserName(); $tree = [ new MyServer\HomeCollection(); ]; $server = new Sabre\DAV\Server($tree); $server->addPlugin($authPlugin); $server->exec(); ``` -------------------------------- ### Server Configuration Comparison Source: https://sabre.io/dav/principals Comparison of standard server setup versus the custom implementation required for non-standard paths. ```php $principalBackend = new Acme\PrincipalBackend(); $caldavBackend = new Sabre\CalDAV\Backend\PDO($pdo); $carddavBackend = new Sabre\CardDAV\Backend\PDO($pdo); $nodes = [ new Sabre\DAVACL\PrincipalCollection($principalBackend) new Sabre\CalDAV\CalendarRoot($principalBackend, $caldavBackend), new Sabre\CalDAV\AddressBookRoot($principalBackend, $carddavBackend), ]; $server = new Sabre\DAV\Server($nodes); $server->addPlugin(Sabre\CalDAV\Plugin()); $server->addPlugin(Sabre\CardDAV\Plugin()); $server->exec(); ``` ```php $principalBackend = new Acme\PrincipalBackend(); $caldavBackend = new Sabre\CalDAV\Backend\PDO($pdo); $carddavBackend = new Sabre\CardDAV\Backend\PDO($pdo); $nodes = [ new Sabre\DAV\SimpleCollection('principals', [ new Sabre\DAVACL\PrincipalCollection($principalBackend, 'principals/users') new Sabre\DAVACL\PrincipalCollection($principalBackend, 'principals/groups') ] new Sabre\DAV\SimpleCollection('calendars', [ new Acme\CalendarRoot($principalBackend, $caldavBackend, 'principals/users'), new Acme\CalendarRoot($principalBackend, $caldavBackend, 'principals/groups'), ] new Sabre\DAV\SimpleCollection('addressbooks', [ new Acme\AddressBookRoot($principalBackend, $carddavBackend, 'principals/users'), new Acme\AddressBookRoot($principalBackend, $carddavBackend, 'principals/groups'), ] ]; $server = new Sabre\DAV\Server($nodes); $server->addPlugin(Acme\CalDAVPlugin()); $server->addPlugin(Acme\CardDAVPlugin()); $server->exec(); ``` -------------------------------- ### Implement custom authentication backend Source: https://sabre.io/dav/extending-sabredav Example of extending the AbstractBasic authentication backend within a custom namespace. ```php ``` -------------------------------- ### Clean URL Example Source: https://sabre.io/dav/baseuri An example of a desired 'clean' URL structure for accessing SabreDAV resources. ```http http://server.example.org/files/photo.jpg ``` -------------------------------- ### Basic SabreDAV Server Setup Source: https://sabre.io/dav/virtual-filesystems Use this snippet to initialize a SabreDAV server, expose a local directory, and set the base URI. Ensure a 'public' directory exists. ```php use Sabre\DAV; // Make sure there is a directory in your current directory named 'public'. We will be exposing that directory to WebDAV $publicDir = new MyDirectory('public'); // The object tree needs in turn to be passed to the server class $server = new DAV\Server($publicDir); // We're required to set the base uri, it is recommended to put your webdav server on a root of a domain $server->setBaseUri('/'); // And off we go! $server->exec(); ``` -------------------------------- ### Configure Domain for Client Discovery Source: https://sabre.io/dav/service-discovery Example of a domain name used as a server URL for client discovery. ```text dav.example.org ``` -------------------------------- ### Install SabreDAV with Composer Source: https://sabre.io/dav/install Use this command to add the sabre/dav dependency to your project and install the latest stable version. ```bash composer require sabre/dav ~4.6.0 ``` -------------------------------- ### MyDirectory Class Implementation Source: https://sabre.io/dav/virtual-filesystems Example implementation of a read-only directory class extending `Sabre\DAV\Collection`. ```PHP use Sabre\DAV; class MyDirectory extends DAV\Collection { private $myPath; function __construct($myPath) { $this->myPath = $myPath; } function getChildren() { $children = array(); foreach(scandir($this->myPath) as $node) { if ($node[0]==='.') continue; $children[] = $this->getChild($node); } return $children; } function getChild($name) { $path = $this->myPath . '/' . $name; if (!file_exists($path)) { throw new DAV\Exception\NotFound('The file with name: ' . $name . ' could not be found'); } if ($name[0]=='.') throw new DAV\Exception\NotFound('Access denied'); if (is_dir($path)) { return new MyDirectory($path); } else { return new MyFile($path); } } function childExists($name) { return file_exists($this->myPath . '/' . $name); } function getName() { return basename($this->myPath); } } ``` -------------------------------- ### Evolution User Agent Strings Source: https://sabre.io/dav/clients/evolution Examples of User-Agent headers sent by different versions of Evolution. ```text Evolution/2.28.1 Evolution/3.2.3 ``` -------------------------------- ### MyDirectory Class Implementation for Read-Only Filesystem Source: https://sabre.io/dav/virtual-filesystems This class extends Sabre\DAV\Collection to implement a read-only directory. It requires methods for getting children, getting a specific child, checking child existence, and getting the directory name. It handles file system traversal and exceptions for non-existent or inaccessible files. ```php use Sabre\DAV; class MyDirectory extends DAV\Collection { private $myPath; function __construct($myPath) { $this->myPath = $myPath; } function getChildren() { $children = array(); // Loop through the directory, and create objects for each node foreach(scandir($this->myPath) as $node) { // Ignoring files staring with . if ($node[0]==='.') continue; $children[] = $this->getChild($node); } return $children; } function getChild($name) { $path = $this->myPath . '/' . $name; // We have to throw a NotFound exception if the file didn't exist if (!file_exists($path)) { throw new DAV\Exception\NotFound('The file with name: ' . $name . ' could not be found'); } // Some added security if ($name[0]=='.') throw new DAV\Exception\NotFound('Access denied'); if (is_dir($path)) { return new MyDirectory($path); } else { return new MyFile($path); } } function childExists($name) { return file_exists($this->myPath . '/' . $name); } function getName() { return basename($this->myPath); } } ``` -------------------------------- ### Generate Hash via Command Line Source: https://sabre.io/dav/authentication Example of generating an MD5 hash for a specific user, realm, and password combination. ```bash $ php -r "echo md5('foo:SabreDAV:bar');" 5790c3784a79a018d1186528df520e11 ``` -------------------------------- ### Custom Principal URL Structure Source: https://sabre.io/dav/principals Example of desired custom URL structures for users and groups. ```text principals/users/username principals/groups/groupname ``` -------------------------------- ### MyFile Class Implementation Source: https://sabre.io/dav/virtual-filesystems Example implementation of a read-only file class extending `Sabre\DAV\File`. ```PHP use Sabre\DAV; class MyFile extends DAV\File { private $myPath; function __construct($myPath) { $this->myPath = $myPath; } function getName() { return basename($this->myPath); } function get() { return fopen($this->myPath,'r'); } function getSize() { return filesize($this->myPath); } function getETag() { return '"' . md5_file($this->myPath) . '"'; } } ``` -------------------------------- ### Example htdigest File Content Source: https://sabre.io/dav/authentication A sample entry for an htdigest file using the generated hash. ```text foo:SabreDAV:5790c3784a79a018d1186528df520e11 ``` -------------------------------- ### Request Initial Sync Token Source: https://sabre.io/dav/building-a-caldav-client Use this PROPFIND request to get the initial sync-token from the server. Ensure the server supports the 'sync' extension. ```http PROPFIND /calendars/johndoe/home/ HTTP/1.1 Depth: 0 Content-Type: application/xml; charset=utf-8 ``` ```http /calendars/johndoe/home/ My calendar 3145 http://sabredav.org/ns/sync-token/3145 HTTP/1.1 200 OK ``` -------------------------------- ### Common WebDAVFS User Agents Source: https://sabre.io/dav/clients/finder Examples of User-Agent strings sent by the macOS WebDAV client. ```text WebDAVFS/1.5 (01508000) Darwin/9.2.2 (i386) WebDAVFS/1.7 (01708000) Darwin/9.4.0 (i386) WebDAVFS/1.7 (01708000) Darwin/9.6.0 (i386) ``` -------------------------------- ### Handle Windows Lock-Token Headers Source: https://sabre.io/dav/clients/windows Examples of the standard and non-standard Lock-Token headers sent by Windows clients. ```text Lock-Token: ``` ```text Lock-Token: opaquelocktoken:98b0726b-b34f-4778-9c35-da3927b6fe36 ``` -------------------------------- ### Access Server URL Source: https://sabre.io/dav/carddav Example URL format for accessing the deployed CardDAV server in a web browser. ```text http://www.example.org/~every/sabredav/addressbookserver.php/ ``` -------------------------------- ### Example Discovery URL Source: https://sabre.io/dav/service-discovery The URL clients attempt to access based on the domain part of an email address. ```text http://example.org/.well-known/caldav ``` -------------------------------- ### Define data model paths Source: https://sabre.io/dav/caldav-carddav-integration-guide Examples of URL structures for principals, calendars, and addressbooks in the SabreDAV data model. ```text /calendars/homer@example.org/ ``` ```text /calendars/homer@example.org/work ``` ```text /calendars/homer@example.org/work/meeting.ics ``` ```text /addressbooks/homer@example.org ``` ```text /addressbooks/homer@example.org/book1 ``` ```text /addressbooks/homer@example.org/book1/marge.vcf ``` -------------------------------- ### DavFS User Agent strings Source: https://sabre.io/dav/clients/davfs Examples of user agent strings reported by different versions of the davfs2 client. ```text davfs2/1.1.2 neon/0.26.2 davfs2/1.4.7 neon/0.30.0 ``` -------------------------------- ### Office 2011 for Mac PROPFIND Request Source: https://sabre.io/dav/clients/msoffice Example of a PROPFIND request made by Microsoft Office 2011 for Mac when using the 'Open URL' feature. This request includes specific headers and a detailed property find. ```http PROPFIND /filename.docx HTTP/1.1 From: 127.0.0.1 User-Agent: Microsoft Office Accept: */* Accept-Language: en Translate: f Brief: t Depth: 0 Content-Type: text/xml; charset=utf-8 Content-Length: 236 Connection: Keep-Alive Host: localhost:80 ``` -------------------------------- ### Create MySQL Tables Source: https://sabre.io/dav/caldav Creates the necessary tables in the MySQL database named 'sabredav'. Adjust username, password, and host as per your MySQL setup. ```bash cat examples/sql/mysql.* | mysql -u root -p sabredav -h 127.0.0.1 ``` -------------------------------- ### iCal User Agent Strings Source: https://sabre.io/dav/clients/ical Examples of user agent strings observed from various versions of iCal and Mac OS X. ```text DAVKit/3.0.6 (661); CalendarStore/3.0.8 (860); iCal/3.0.8 (1287); Mac OS X/10.5.8 (9L31a) DAVKit/4.0.1 (730); CalendarStore/4.0.1 (973); iCal/4.0.1 (1374); Mac OS X/10.6.2 (10C540) Mac_OS_X/10.9.2 (13C64) CalendarAgent/176 ``` -------------------------------- ### PROPFIND Response with Unsupported Ctag Source: https://sabre.io/dav/building-a-carddav-client This example shows a PROPFIND response where the server does not support the 'ctag' property, returning a '404 Not Found' for it while still providing the 'displayname'. Status codes within the multistatus response apply to individual properties. ```xml HTTP/1.1 207 Multi-status Content-Type: application/xml; charset=utf-8 /addressbooks/johndoe/contacts/ My Address Book HTTP/1.1 200 OK HTTP/1.1 404 Not Found ``` -------------------------------- ### Restrict Property Storage Paths Source: https://sabre.io/dav/property-storage Configure the pathFilter callback to control which paths can store properties. This example prevents storage in paths starting with 'foo'. ```php $propertyStorage = new \Sabre\DAV\PropertyStorage\Plugin($storageBackend); $propertyStorage->pathFilter = function($path) { if (strpos('foo', $path)===0) { return false; } else { return true; } }; ``` -------------------------------- ### Instantiate SabreDAV Server with Plugins Source: https://sabre.io/dav/per-user-directories This snippet demonstrates how to set up the SabreDAV server, including authentication and ACL plugins, and adding custom principal collections to the server tree. ```php addPlugin($authPlugin); $aclPlugin = new Sabre\DAV\ACL\Plugin(); $server->addPlugin($aclPlugin); $server->exec(); ``` -------------------------------- ### Create User and Proxy Principals Source: https://sabre.io/dav/caldav-proxy SQL commands to initialize a user account and the required read/write proxy sub-principals. ```sql INSERT INTO users (username, digesta1) VALUES ('jsmith',MD5('jsmith:SabreDAV:mypassword')); INSERT INTO principals (uri, email, displayname) VALUES ('principals/jsmith','jsmith@example.org','John Smith'); -- Now the special principals INSERT INTO principals (uri) VALUES ('principals/jsmith/calendar-proxy-read'); INSERT INTO principals (uri) VALUES ('principals/jsmith/calendar-proxy-write'); ``` -------------------------------- ### Setup ICSExportPlugin Source: https://sabre.io/dav/ics-export-plugin Add the ICSExportPlugin to your SabreDAV server to enable iCalendar exports. After setup, append '?export' to a calendar URL to trigger a download. ```php $icsPlugin = new \Sabre\CalDAV\ICSExportPlugin(); $server->addPlugin($icsPlugin); ``` -------------------------------- ### Configure File Authentication Backend Source: https://sabre.io/dav/authentication Initializes the File authentication backend using an htdigest-formatted file. ```php use Sabre\DAV\Auth; $authBackend = new Auth\Backend\File('/path/to/htdigest'); $authBackend->setRealm('SabreDAV'); $authPlugin = new Auth\Plugin($authBackend); // Adding the plugin to the server. $server->addPlugin($authPlugin); ``` -------------------------------- ### Initialize SQLite Database Source: https://sabre.io/dav/carddav Creates the data directory and imports the schema from the provided SQL files into a new SQLite database. ```bash mkdir data/ cat examples/sql/sqlite.* | sqlite3 data/db.sqlite ``` -------------------------------- ### Multi-status Response for ETag Query Source: https://sabre.io/dav/building-a-carddav-client Example response containing etags for contacts in the addressbook. ```HTTP HTTP/1.1 207 Multi-status Content-Type: application/xml; charset=utf-8 /addressbooks/johndoe/contacts/abc-def-fez-123454657.vcf "2134-888" HTTP/1.1 200 OK /addressbooks/johndoe/contacts/acme-12345.vcf "9999-2344" HTTP/1.1 200 OK ``` -------------------------------- ### Example vCard 4.0 structure Source: https://sabre.io/dav/building-a-carddav-client A basic representation of a vCard 4.0 contact entry. ```text BEGIN:VCARD VERSION:4.0 FN:Evert Pot N:Pot;Evert;;; END:VCARD ``` -------------------------------- ### Add PDO Property Storage Backend Source: https://sabre.io/dav/property-storage Instantiate the PDO backend, add the PropertyStorage plugin to the server, and configure it. ```php $storageBackend = new Sabre\DAV\PropertyStorage\Backend\PDO($pdo); $propertyStorage = new \Sabre\DAV\PropertyStorage\Plugin($storageBackend); $server->addPlugin($propertyStorage); ``` -------------------------------- ### Configure and Run SabreDAV Server Source: https://sabre.io/dav/gettingstarted Set up the SabreDAV server with a root directory, base URI, lock manager, and browser plugin. The server is then executed to handle WebDAV requests. ```php setBaseUri('/url/to/server.php'); // The lock manager is reponsible for making sure users don't overwrite // each others changes. $lockBackend = new DAV\Locks\Backend\File('data/locks'); $lockPlugin = new DAV\Locks\Plugin($lockBackend); $server->addPlugin($lockPlugin); // This ensures that we get a pretty index in the browser, but it is // optional. $server->addPlugin(new DAV\Browser\Plugin()); // All we need to do now, is to fire up the server $server->exec(); ``` -------------------------------- ### Initialize a CalDAV server Source: https://sabre.io/dav/caldav-carddav-integration-guide Configures a basic CalDAV server instance with authentication, principal, and calendar backends using PDO. ```php setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION); //Mapping PHP errors to exceptions function exception_error_handler($errno, $errstr, $errfile, $errline ) { throw new ErrorException($errstr, 0, $errno, $errfile, $errline); } set_error_handler("exception_error_handler"); // Files we need require_once 'vendor/autoload.php'; // Backends $authBackend = new DAV\Auth\Backend\PDO($pdo); $principalBackend = new DAVACL\PrincipalBackend\PDO($pdo); $calendarBackend = new CalDAV\Backend\PDO($pdo); // Directory tree $tree = array( new DAVACL\PrincipalCollection($principalBackend), new CalDAV\CalendarRoot($principalBackend, $calendarBackend) ); // The object tree needs in turn to be passed to the server class $server = new DAV\Server($tree); // You are highly encouraged to set your WebDAV server base url. Without it, // SabreDAV will guess, but the guess is not always correct. Putting the // server on the root of the domain will improve compatibility. $server->setBaseUri('/'); // Authentication plugin $authPlugin = new DAV\Auth\Plugin($authBackend,'SabreDAV'); $server->addPlugin($authPlugin); // CalDAV plugin $caldavPlugin = new CalDAV\Plugin(); $server->addPlugin($caldavPlugin); // CardDAV plugin $carddavPlugin = new CardDAV\Plugin(); $server->addPlugin($carddavPlugin); // ACL plugin $aclPlugin = new DAVACL\Plugin(); $server->addPlugin($aclPlugin); // Support for html frontend $browser = new DAV\Browser\Plugin(); $server->addPlugin($browser); // And off we go! $server->exec(); ``` -------------------------------- ### Fetch Individual vCard Source: https://sabre.io/dav/building-a-carddav-client Retrieve the data for a specific vCard using a GET request. ```HTTP GET /addressbooks/johndoe/contacts/abc-def-fez-123454657.vcf ``` -------------------------------- ### Configure DNS SRV Records Source: https://sabre.io/dav/service-discovery Example SRV records for secured CalDAV and CardDAV services. ```text _carddavs._tcp 86400 IN SRV 10 20 443 dav.example.org. _caldavs._tcp 86400 IN SRV 10 20 443 dav.example.org. ``` -------------------------------- ### Configure Principals Collection Source: https://sabre.io/dav/acl Set up a principal backend and add a principal collection to the server tree. ```php use Sabre\DAVACL, Sabre\DAV; // Assuming we have a database connection $principalBackend = new DAVACL\PrincipalBackend\PDO($pdo); $tree = array( new DAVACL\PrincipalCollection($principalBackend), new My_Own_Collection_Class(), ); $server = new DAV\Server($tree); $aclPlugin = new DAVACL\Plugin(); $server->addPlugin($aclPlugin); $server->exec(); ``` -------------------------------- ### Identify Windows Username Format Source: https://sabre.io/dav/clients/windows Example of an incorrectly prepended NT domain in a username string. ```text MYDOMAIN\\username ``` -------------------------------- ### Create SabreDAV Client Object Source: https://sabre.io/dav/davclient Instantiate the SabreDAV client with necessary settings. The 'baseUri' is mandatory; 'userName', 'password', and 'proxy' are optional. ```php use Sabre\DAV\Client; include 'vendor/autoload.php'; $settings = array( 'baseUri' => 'http://example.org/dav/', 'userName' => 'user', 'password' => 'password', 'proxy' => 'locahost:8888', ); $client = new Client($settings); ``` -------------------------------- ### Instantiate PDO Principal Backend Source: https://sabre.io/dav/principals Use this to add principals to your WebDAV tree using a PDO-compatible database. Ensure your database schema matches the required structure for principals. ```php $pdo = new PDO('sqlite:...'); $principalBackend = new Sabre\DAVACL\PrincipalBackend\PDO($pdo); $nodes = [ new Sabre\DAVACL\PrincipalCollection($principalBackend) ]; ``` -------------------------------- ### SabreDAV Error Response Source: https://sabre.io/dav/baseuri This is an example of a common error response when the base URI is not correctly configured. ```xml 2.0.4 Sabre\DAV\Exception\NotFound File not found: sabredav in 'root' ``` -------------------------------- ### Enable Evolution WebDAV Debugging Source: https://sabre.io/dav/clients/evolution Set the environment variable and execute the addressbook factory to capture debug logs. ```bash export WEBDAV_DEBUG=all ./e-addressbook-factory ``` -------------------------------- ### Handle multi-status response Source: https://sabre.io/dav/building-a-caldav-client Example of a 207 Multi-status response containing calendar data for multiple objects. ```HTTP HTTP/1.1 207 Multi-status Content-Type: application/xml; charset=utf-8 /calendars/johndoe/home/132456762153245.ics "2134-314" BEGIN:VCALENDAR VERSION:2.0 CALSCALE:GREGORIAN BEGIN:VTODO UID:132456762153245 SUMMARY:Do the dishes DUE:20121028T115600Z END:VTODO END:VCALENDAR HTTP/1.1 200 OK /calendars/johndoe/home/132456-34365.ics "5467-323" BEGIN:VCALENDAR VERSION:2.0 CALSCALE:GREGORIAN BEGIN:VEVENT UID:132456-34365 SUMMARY:Weekly meeting DTSTART:20120101T120000 DURATION:PT1H RRULE:FREQ=WEEKLY END:VEVENT END:VCALENDAR HTTP/1.1 200 OK ``` -------------------------------- ### Configure Well-Known Redirects Source: https://sabre.io/dav/service-discovery Webserver configuration redirects for CalDAV and CardDAV discovery. ```text http://dav.example.org/.well-known/caldav -> root of your dav server http://dav.example.org/.well-known/carddav -> root of your dav server ``` -------------------------------- ### Initialize SimpleCollection with a root node Source: https://sabre.io/dav/simplecollection Create a static directory tree by passing a name and an array of child nodes to the SimpleCollection constructor. ```php use Sabre\DAV; $root = new DAV\SimpleCollection('root',array( new DAV\SimpleCollection('users'), new DAV\SimpleCollection('files'), new DAV\SimpleCollection('home') )); $server = new DAV\Server($root); ``` -------------------------------- ### Connect to a WebDAV server with Cadaver Source: https://sabre.io/dav/clients/cadaver Use this command to initiate a connection to a specific WebDAV URL. ```bash $ cadaver [url] ``` -------------------------------- ### Initialize SQLite Database Source: https://sabre.io/dav/caldav Initializes the SQLite database file using provided SQL scripts. This command assumes you are in your main project directory. ```bash cat examples/sql/sqlite.* | sqlite3 data/db.sqlite ``` -------------------------------- ### Handle propFind events Source: https://sabre.io/dav/writing-plugins Use the propFind event to intercept property requests. The set method forces a value, while handle only sets it if not already present. ```php use Sabre\DAV\PropFind; use Sabre\DAV\INode; function addProperty(PropFind $propfind, INode $node) { // This gives _every_ node a `{DAV:}displayname` of 'foo'. $propFind->set('{DAV:}displayname', 'foo'); } $server->on('propFind', 'addProperty'); ``` ```php function addProperty(PropFind $propfind, INode $node) { // This gives nodes without a displayname the value 'foo'. $propFind->handle('{DAV:}displayname', 'foo'); } ``` ```php function addProperty(PropFind $propfind, INode $node) { // This gives nodes without a displayname the value 'foo'. $propFind->handle('{DAV:}displayname', function() { return 'foo'; }); } ``` -------------------------------- ### Configure PDO Authentication Backend Source: https://sabre.io/dav/authentication Initializes the PDO authentication backend for MySQL or SQLite databases and attaches it to the server. ```php use Sabre\DAV\Auth; $pdo = new \PDO('sqlite:data/db.sqlite'); // or alternatively: // $pdo = new \PDO('mysql:dbname=sabredav','username','password'); // Throwing exceptions when PDO comes across an error: $pdo->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION); // Creating the backend. $authBackend = new Auth\Backend\PDO($pdo); // We're assuming that the realm name is called 'SabreDAV'. $authBackend->setRealm('SabreDAV'); // Creating the plugin. $authPlugin = new Auth\Plugin($authBackend); // Adding the plugin to the server. $server->addPlugin($authPlugin); ``` -------------------------------- ### Equivalent Percent-Encoded URLs Source: https://sabre.io/dav/character-encoding Examples of technically equivalent URLs that may be treated as distinct by poorly implemented clients. ```text http://example.org/~evert http://example.org/%7eevert http://example.org/%7Eevert ``` -------------------------------- ### Map WebDAV Drive via Command Line Source: https://sabre.io/dav/clients/windows Use the net use command to map a WebDAV share to a drive letter. ```bash net use * http://example.org/dav/ ``` -------------------------------- ### Enable Basic Authentication via Registry File Source: https://sabre.io/dav/clients/windows Save this content as a .reg file to update the Windows registry for WebClient Basic Authentication support. ```registry [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\WebClient\Parameters] "UseBasicAuth"=dword:00000001 "BasicAuthLevel"=dword:00000002 ``` -------------------------------- ### Include Autoloader Source: https://sabre.io/dav/gettingstarted Include the Composer autoloader to make SabreDAV classes available. Ensure the path is correct for your installation. ```php require 'vendor/autoload.php'; ``` -------------------------------- ### Set Directory Permissions Source: https://sabre.io/dav/gettingstarted Make the 'data' and 'public' directories world-writable to allow the server to create and manage files. ```bash chmod a+rwx data public ``` -------------------------------- ### Configure IMAP Authentication Backend Source: https://sabre.io/dav/authentication Initializes the IMAP authentication backend to authenticate against an IMAP server. ```php use Sabre\DAV\Auth; // Set IMAP flags according to your needs. // The connection will be opened read-only. // https://php.net/manual/de/function.imap-open.php $mailbox = '{localhost:993/notls}'; // Creating the backend. $authBackend = new Auth\Backend\IMAP($mailbox); // We're assuming that the realm name is called 'SabreDAV'. $authBackend->setRealm('SabreDAV'); // Creating the plugin. $authPlugin = new Auth\Plugin($authBackend); // Adding the plugin to the server. $server->addPlugin($authPlugin); ``` -------------------------------- ### Define a User Home Collection Source: https://sabre.io/dav/per-user-directories Extends Sabre\DAV\Collection to create a base for user-specific directories. Assumes prior setup of virtual filesystems. ```php users as $user) { $result[] = new FS\Directory($path . '/' . $user); } return $result; } function getName() { return 'home'; } } ```