cesurapp / storage-bundle
Symfony storage bundle
Installs: 369
Dependents: 1
Suggesters: 0
Security: 0
Stars: 0
Watchers: 1
Forks: 0
Open Issues: 0
Type:symfony-bundle
pkg:composer/cesurapp/storage-bundle
Requires
- php: >=8.4
- ext-fileinfo: *
- async-aws/s3: ^2.9
- symfony/dependency-injection: ^8.0
- symfony/framework-bundle: ^8.0
- symfony/http-kernel: ^8.0
Requires (Dev)
- php-cs-fixer/shim: ^v3.9
- phpstan/phpstan: ^2.1.33
- phpunit/phpunit: ^12.5
README
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