Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Dav Services Bundle Laravel Package

baikal/dav-services-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation Add the bundle via Composer:

    composer require baikal/dav-services-bundle
    

    Register the bundle in config/bundles.php:

    return [
        // ...
        Baikal\DavServicesBundle\BaikalDavServicesBundle::class => ['all' => true],
    ];
    
  2. Basic Configuration Configure the bundle in config/packages/baikal_dav_services.yaml:

    baikal_dav_services:
        sabre_dav:
            home_directory: '%kernel.project_dir%/var/dav'
    
  3. First Use Case: Serving a DAV Endpoint Create a route in config/routes.yaml:

    baikal_dav:
        path: /dav
        controller: baikal_dav_services.controller.dav::index
    

    Ensure the var/dav directory exists and is writable:

    mkdir -p var/dav
    chmod -R 775 var/dav
    

Implementation Patterns

Core Workflows

  1. User-Specific DAV Stores Dynamically bind DAV stores to authenticated users via Symfony’s security system:

    // In a controller or event subscriber
    $user = $this->getUser();
    $davStore = $this->container->get('baikal_dav_services.store_factory')->createForUser($user);
    
  2. Customizing DAV Backends Extend the default Sabre\DAV\SimpleFileStorage by creating a custom backend:

    use Sabre\DAV\SimpleFileStorage;
    
    class CustomFileStorage extends SimpleFileStorage {
        public function __construct($path) {
            parent::__construct($path);
            // Add custom logic (e.g., file filtering, permissions)
        }
    }
    

    Register it in the bundle’s configuration:

    baikal_dav_services:
        sabre_dav:
            backend: App\DAV\CustomFileStorage
    
  3. Integrating with Symfony’s Security Use Symfony’s security context to restrict DAV access:

    // In a firewall or access control listener
    if (!$this->security->isGranted('ROLE_DAV_USER')) {
        throw new \Sabre\DAV\Exception\Forbidden('Access denied');
    }
    
  4. File Metadata and Custom Properties Attach custom metadata to files using Sabre’s property system:

    $file = $davStore->getFile('path/to/file.txt');
    $file->setProperty('http://example.com/custom', 'value');
    

Integration Tips

  • Leverage Sabre\DAV Events Listen to Sabre’s DAV events (e.g., afterCreateFile) for auditing or logging:

    $dispatcher = $this->container->get('event_dispatcher');
    $dispatcher->addListener('Sabre\DAV\DAVServer:afterCreateFile', function ($event) {
        // Log file creation
    });
    
  • CORS Configuration If exposing DAV over HTTP, configure CORS in Symfony’s config/packages/nelmio_cors.yaml:

    nelmio_cors:
        defaults:
            allow_origin: ['*']
            allow_methods: ['GET', 'PUT', 'POST', 'DELETE', 'MKCOL', 'PROPFIND', 'COPY', 'MOVE']
            allow_headers: ['*']
            expose_headers: ['*']
            max_age: 3600
    
  • Performance: Caching Cache DAV directory listings for read-heavy workloads:

    $cache = $this->container->get('cache.app');
    $cacheKey = 'dav_listing_' . md5($path);
    if ($cache->has($cacheKey)) {
        return $cache->get($cacheKey);
    }
    

Gotchas and Tips

Pitfalls

  1. Directory Permissions

    • Issue: DAV operations fail with Permission denied errors.
    • Fix: Ensure the home_directory in config is writable by the web server user (e.g., www-data or apache).
      chown -R www-data:www-data var/dav
      chmod -R 775 var/dav
      
  2. Sabre\DAV Version Conflicts

    • Issue: The bundle locks Sabre\DAV to 2.1.3, which may conflict with other packages.
    • Fix: Use replace in composer.json to avoid conflicts:
      "replace": {
          "sabre/dav": "2.1.3"
      }
      
  3. Case-Sensitive Paths

    • Issue: DAV paths are case-sensitive on Linux but not on Windows.
    • Fix: Normalize paths in custom backends:
      $path = strtolower($path); // For Linux consistency
      
  4. Memory Leaks with Large Directories

    • Issue: PROPFIND requests on directories with thousands of files may time out.
    • Fix: Implement pagination or lazy-loading in custom backends.

Debugging

  1. Enable Sabre Debugging Set the Sabre debug mode in config:

    baikal_dav_services:
        sabre_dav:
            debug: true
    

    Check logs in var/log/dev.log for Sabre-specific errors.

  2. HTTP Method Restrictions

    • Issue: Some HTTP methods (e.g., PROPFIND) are blocked by Symfony’s router.
    • Fix: Explicitly allow DAV methods in config/routes.yaml:
      baikal_dav:
          path: /dav
          controller: baikal_dav_services.controller.dav::index
          methods: [GET, PUT, POST, DELETE, MKCOL, PROPFIND, COPY, MOVE, HEAD, OPTIONS]
      
  3. XML Parsing Errors

    • Issue: Malformed XML in PROPFIND responses.
    • Fix: Validate XML output using tools like XMLLint or Symfony’s XmlHelper.

Extension Points

  1. Custom Authentication Override the default authentication by implementing Sabre\DAV\Auth\Plugin:

    use Sabre\DAV\Auth\Plugin;
    
    class CustomAuthPlugin extends Plugin {
        public function check($realm, $user, $password) {
            // Custom logic (e.g., check against Symfony’s UserProvider)
            return $this->security->getUser() !== null;
        }
    }
    

    Register it in the bundle’s config:

    baikal_dav_services:
        sabre_dav:
            auth_plugin: App\DAV\CustomAuthPlugin
    
  2. WebDAV Client Integration Use libraries like sabre/vobject or league/url to interact with the DAV server programmatically:

    $client = new \Sabre\DAV\Client('http://localhost/dav');
    $client->putFile('local/file.txt', 'remote/file.txt');
    
  3. Event-Driven Extensions Extend functionality via Sabre’s event system:

    // Example: Log all file deletions
    $dispatcher->addListener('Sabre\DAV\DAVServer:beforeDelete', function ($event) {
        $this->logger->info('File deleted', ['path' => $event->getPath()]);
    });
    
  4. Custom DAV Properties Define and use custom DAV properties:

    // In a custom backend
    $file->setProperty('http://example.com/x-custom/version', '1.0');
    

    Query them in PROPFIND requests:

    <prop>
        <getpropertybytag xmlns="http://example.com/ns"/>
    </prop>
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle
atriumphp/atrium
sandermuller/package-boost-laravel
sandermuller/boost-skills
redaxo/core
yusufgenc/filament-api-forge
l3aro/rating-star-for-filament
leek/filament-subtenant-scope