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

Relay Blob Connector Filesystem Bundle Laravel Package

dbp/relay-blob-connector-filesystem-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Prerequisites:

    • Install dbp/relay-blob-bundle (parent package) via Composer:
      composer require dbp/relay-blob-bundle
      
    • Ensure DbpRelayCoreBundle is installed (required by the parent bundle).
  2. Install the Filesystem Connector:

    composer require dbp/relay-blob-connector-filesystem-bundle
    
  3. Register the Bundle: Add to config/bundles.php before DbpRelayBlobBundle:

    Dbp\Relay\BlobBundle\DbpRelayBlobConnectorFilesystemBundle::class => ['all' => true],
    
  4. Configure Storage Path: Publish the default config and update config/packages/dbp_relay_blob.yaml:

    dbp_relay_blob:
        datasystems:
            filesystem:
                connector: filesystem
                options:
                    path: '%kernel.project_dir%/var/blobs'  # Customize path
    
  5. First Use Case: Upload a blob via the Relay API (e.g., using multipart/form-data):

    curl -X POST -F "file=@/path/to/file.jpg" http://your-app/_relay/blob
    

    Verify the file exists at the configured path.


Implementation Patterns

Core Workflows

  1. Blob Storage:

    • Files are stored as-is in the filesystem under the configured path.
    • Example structure:
      /var/blobs/
        ├── {uuid}/
        │   ├── original_filename.ext
        │   └── ... (metadata files if added later)
      
  2. Integration with Relay API:

    • Use the Relay API endpoint (/_relay/blob) for all blob operations.
    • Example cURL commands:
      # Upload
      curl -X POST -F "file=@image.png" http://app/_relay/blob
      
      # Get share link (temporary)
      curl -X POST http://app/_relay/blob/share --data '{"blobId":"uuid-here"}'
      
      # Delete
      curl -X DELETE http://app/_relay/blob --data '{"blobId":"uuid-here"}'
      
  3. Symfony Service Integration:

    • Access the filesystem connector via dependency injection:
      use Dbp\Relay\BlobBundle\Service\DatasystemProviderServiceInterface;
      
      class MyService {
          public function __construct(
              private DatasystemProviderServiceInterface $filesystemProvider
          ) {}
      
          public function storeFile($file) {
              $blob = $this->filesystemProvider->store($file, 'filesystem');
              return $blob->getId();
          }
      }
      
  4. Customizing Storage:

    • Override the path in config or dynamically via environment variables:
      options:
          path: '%env(RELAY_BLOB_PATH)%'
      
  5. Share Links:

    • Generate short-lived links (default: 1 hour expiry) via the API.
    • Customize expiry time by extending the bundle (see "Gotchas").

Advanced Patterns

  1. Multi-Datasystem Setup: Combine with other connectors (e.g., S3) in config/packages/dbp_relay_blob.yaml:

    datasystems:
        filesystem:
            connector: filesystem
            options: { path: '%kernel.project_dir%/var/blobs' }
        s3:
            connector: aws_s3
            options: { ... }
    
  2. Event Listeners: Hook into blob events (e.g., BlobStoredEvent) to trigger post-upload actions:

    use Dbp\Relay\BlobBundle\Event\BlobStoredEvent;
    use Symfony\Component\EventDispatcher\EventSubscriberInterface;
    
    class BlobSubscriber implements EventSubscriberInterface {
        public static function getSubscribedEvents() {
            return [
                BlobStoredEvent::class => 'onBlobStored',
            ];
        }
    
        public function onBlobStored(BlobStoredEvent $event) {
            // Custom logic (e.g., log, notify, transform)
        }
    }
    
  3. Testing:

    • Use a temporary directory for tests:
      use Symfony\Component\Filesystem\Filesystem;
      
      $fs = new Filesystem();
      $fs->mkdir(sys_get_temp_dir().'/relay_blob_tests');
      $this->container->setParameter('kernel.project_dir', sys_get_temp_dir());
      

Gotchas and Tips

Pitfalls

  1. Bundle Loading Order:

    • Must register DbpRelayBlobConnectorFilesystemBundle before DbpRelayBlobBundle in config/bundles.php.
    • Failure results in DatasystemProviderServiceInterface not being registered.
  2. Path Permissions:

    • Ensure the configured path is writable by the web server user (e.g., www-data).
    • Debug 500 errors with:
      chmod -R 775 %kernel.project_dir%/var/blobs
      
  3. Share Link Expiry:

    • Default expiry is 1 hour. Customize via a custom connector class (see "Extension Points").
  4. UUID Collisions:

    • The bundle uses UUIDs for filenames. If generating UUIDs manually, ensure uniqueness to avoid overwrites.
  5. Missing Changelog:

    • The package lacks a detailed changelog. Check Git history for breaking changes:
      git log --oneline --grep="fix\|feat" https://github.com/digital-blueprint/relay-blob-connector-filesystem-bundle.git
      

Debugging Tips

  1. Enable Relay Debug Mode: Add to .env:

    RELAY_DEBUG=true
    

    Logs blob operations to var/log/dev.log.

  2. Check Stored Files: Verify files exist at the configured path:

    ls -la %kernel.project_dir%/var/blobs/
    
  3. API Response Errors:

    • 400 Bad Request: Invalid file upload (check Content-Type).
    • 500 Internal Server Error: Check var/log/dev.log for filesystem permission issues.
  4. Dependency Conflicts:

    • Ensure relay-blob-bundle and this connector are on compatible versions (check composer.json constraints).

Extension Points

  1. Custom Connector Class: Extend the default filesystem connector to add features (e.g., custom share link expiry):

    namespace App\Relay\Blob;
    
    use Dbp\Relay\BlobBundle\Connector\FilesystemConnector;
    use Dbp\Relay\BlobBundle\Model\Blob;
    
    class CustomFilesystemConnector extends FilesystemConnector {
        protected function generateShareLink(Blob $blob): string {
            return parent::generateShareLink($blob) . '?expires=' . time() + 86400; // 24h expiry
        }
    }
    

    Register in config/services.yaml:

    services:
        Dbp\Relay\BlobBundle\Service\DatasystemProviderServiceInterface.filesystem:
            class: App\Relay\Blob\CustomFilesystemConnector
            arguments: ['@filesystem']
    
  2. Add Metadata Files: Store additional metadata (e.g., blob.json) alongside files:

    use Symfony\Component\Filesystem\Filesystem;
    
    class MySubscriber implements EventSubscriberInterface {
        public function onBlobStored(BlobStoredEvent $event) {
            $fs = new Filesystem();
            $metadata = [
                'uploaded_at' => (new \DateTime())->format('c'),
                'user_id' => 123,
            ];
            $fs->dumpFile(
                $event->getBlob()->getPath().'/metadata.json',
                json_encode($metadata)
            );
        }
    }
    
  3. Override Default Config: Use config/packages/override/dbp_relay_blob.yaml to avoid merging conflicts:

    dbp_relay_blob:
        datasystems:
            filesystem:
                options:
                    path: '/custom/path'
                    umask: 0002  # Set file permissions
    

Performance Tips

  1. Disable File Locking: If using a high-traffic system, disable file locking in the connector (requires custom class):

    protected function storeFile($file, $path) {
        file_put_contents($path, file_get_contents($file->getPathname()));
        // Skip flock() calls
    }
    
  2. Use symlink for Large Files: For very large files, store the file elsewhere and symlink it to the blob directory:

    $fs->symlink('/large/files/'.$file->getClientOriginalName(), $path);
    
  3. Cache Share Links: Cache generated share links in Redis or APCu to reduce filesystem checks:

    $cache = $this->container->get('cache.app');
    $cache->set('blob_share_'.$blob->getId(), $shareLink, 3
    
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.
comsave/common
alecsammon/php-raml-parser
chrome-php/wrench
lendable/composer-license-checker
typhoon/reflection
mesilov/moneyphp-percentage
mike42/gfx-php
bookdown/themes
aura/view
aura/html
aura/cli
povils/phpmnd
nayjest/manipulator
omnipay/tests
psr-mock/http-message-implementation
psr-mock/http-factory-implementation
psr-mock/http-client-implementation
voku/email-check
voku/urlify
rtheunissen/guzzle-log-middleware