Skip to content

cesurapp/storage-bundle

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

24 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Storage Bundle

App Tester Software License

Symfony file storage abstraction bundle with support for local and cloud storage providers.

  • No database dependency - Pure file storage operations
  • S3-compatible - Uses async-aws/s3 for cloud storage
  • Multiple devices - Configure and use multiple storage providers simultaneously
  • Fully tested - Complete test coverage for all drivers

Supported Drivers

  • Local - Filesystem-based storage
  • Cloudflare R2 - S3-compatible object storage
  • BackBlaze B2 - S3-compatible object storage

Installation

Requires Symfony 8 and PHP 8.4+

composer require cesurapp/storage-bundle

Configuration

Create config/packages/storage.yaml:

storage:
  default: main  # Default storage device
  devices:
    # Local filesystem storage
    local:
      driver: local
      root: "%kernel.project_dir%/storage/files"

    # Cloudflare R2 storage
    main:
      driver: cloudflare
      root: /
      accessKey: "your_access_key"
      secretKey: "your_secret_key"
      bucket: "your_bucket_name"
      region: "auto"
      endPoint: "https://your-account-id.r2.cloudflarestorage.com"

    # BackBlaze B2 storage
    backblaze:
      driver: backblaze
      root: /
      accessKey: "your_key_id"
      secretKey: "your_application_key"
      bucket: "your_bucket_name"
      region: "us-west-001"  # See BackBlaze regions

Available Regions (BackBlaze)

use Cesurapp\StorageBundle\Driver\BackBlaze;

BackBlaze::US_WEST_001;      // us-west-001
BackBlaze::US_WEST_002;      // us-west-002
BackBlaze::US_WEST_003;      // us-west-003
BackBlaze::US_WEST_004;      // us-west-004
BackBlaze::EU_CENTRAL_001;   // eu-central-001
BackBlaze::EU_CENTRAL_002;   // eu-central-002
BackBlaze::EU_CENTRAL_003;   // eu-central-003
BackBlaze::EU_CENTRAL_004;   // eu-central-004

Usage

use Cesurapp\StorageBundle\Storage\Storage;

class FileController
{
    public function upload(Storage $storage): void
    {
        // Upload file (uses default device)
        $storage->upload('/tmp/photo.jpg', 'users/123/photo.jpg');

        // Write content directly
        $storage->write('Hello World', 'documents/hello.txt', 'text/plain');

        // Check if file exists
        if ($storage->exists('users/123/photo.jpg')) {
            // Get file URL
            $url = $storage->getUrl('users/123/photo.jpg');

            // Get file size
            $size = $storage->getSize('users/123/photo.jpg');

            // Get MIME type
            $mime = $storage->getMimeType('users/123/photo.jpg');
        }

        // Download file content
        $content = $storage->download('users/123/photo.jpg');

        // Download as resource
        $resource = $storage->downloadResource('users/123/photo.jpg');

        // Download as chunks (cloud only)
        foreach ($storage->downloadChunk('large-file.zip') as $chunk) {
            echo $chunk;
        }

        // Delete file
        $storage->delete('users/123/photo.jpg');
    }
}

Using Specific Storage Device

// Use a specific storage device instead of default
$storage->device('local')->upload('/tmp/file.pdf', 'documents/file.pdf');
$storage->device('backblaze')->upload('/tmp/backup.zip', 'backups/backup.zip');

Upload with Metadata (Cloud Only)

$storage->upload('/tmp/photo.jpg', 'users/123/photo.jpg', [
    'ContentType' => 'image/jpeg',
    'CacheControl' => 'max-age=3600',
    'Metadata' => [
        'user-id' => '123',
        'uploaded-by' => 'admin'
    ]
]);

Pre-signed URLs (Cloud Only)

// Generate temporary access URL (expires in 1 hour)
$client = $storage->device('main')->getClient();
$presignedUrl = $client->getPresignedUrl(
    'bucket-name',
    'path/to/file.jpg',
    new \DateTimeImmutable('+1 hour')
);

Local Driver Specific Methods

$localDriver = $storage->device('local');

// Get file hash (MD5)
$hash = $localDriver->getFileHash('documents/file.pdf');

// Get directory size
$size = $localDriver->getDirectorySize('users/123/');

// Get partition free space
$freeSpace = $localDriver->getPartitionFreeSpace();

// Get partition total space
$totalSpace = $localDriver->getPartitionTotalSpace();

// Move file
$localDriver->move('/tmp/file.pdf', 'documents/moved-file.pdf');

// Delete directory
$localDriver->deletePath('temp/uploads/');

Testing

Tests for cloud providers require access credentials. Tests without credentials are automatically skipped.

Configure Test Credentials

Edit phpunit.xml.dist:

<!-- BackBlaze Test Keys -->
<server name="BACKBLAZE_ACCESS_KEY" value="your_key_id"/>
<server name="BACKBLAZE_SECRET" value="your_application_key"/>
<server name="BACKBLAZE_BUCKET" value="your_test_bucket"/>

<!-- CloudFlare R2 Test Keys -->
<server name="CLOUDFLARE_R2_ACCESS_KEY" value="your_access_key"/>
<server name="CLOUDFLARE_R2_SECRET" value="your_secret_key"/>
<server name="CLOUDFLARE_R2_ENDPOINT" value="https://your-account-id.r2.cloudflarestorage.com"/>
<server name="CLOUDFLARE_R2_BUCKET" value="your_test_bucket"/>

Run Tests

composer test

API Reference

For detailed usage guidelines and best practices, see GUIDELINES.md

License

MIT License - see LICENSE for details

About

Symfony Storage Bundle

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages