## Getting Started
1. **Installation**: Require the package via Composer:
```bash
composer require becklyn/ddd-file-store:^5.0
becklyn/ddd-symfony-bridge 3 in this version.use Becklyn\DddFileStore\FileStore;
use Becklyn\DddFileStore\FileMetadata;
$fileStore = app(FileStore::class);
$metadata = new FileMetadata('user-uploads', 'document.pdf');
$fileStore->store($metadata, fopen('path/to/local/file', 'r'));
config/packages/becklyn_ddd_file_store.yaml:
becklyn_ddd_file_store:
storage: 'local' # or 's3', 'gcs', etc.
local:
directory: '%kernel.project_dir%/public/uploads'
FileStoredEvent or FileDeletedEvent:
use Becklyn\DddFileStore\Event\FileStoredEvent;
// In a Symfony service or controller
$this->eventDispatcher->dispatch(new FileStoredEvent($metadata, $filePath));
use Becklyn\Ddd\SymfonyBridge\Aggregate\AggregateRoot;
class DocumentAggregate extends AggregateRoot
{
public function attachFile(FileMetadata $metadata, $fileContent): void
{
$this->fileStore->store($metadata, $fileContent);
$this->recordThat(new FileAttached($metadata->getFileName()));
}
}
FileStore into repositories to handle file persistence alongside domain entities:
use Becklyn\Ddd\SymfonyBridge\Repository\Repository;
class DocumentRepository extends Repository
{
public function __construct(private FileStore $fileStore) {}
public function saveWithFile(Document $document, $fileContent): void
{
$this->fileStore->store($document->getFileMetadata(), $fileContent);
$this->save($document);
}
}
becklyn_ddd_file_store:
storage: 's3'
s3:
bucket: 'my-bucket'
region: 'eu-west-1'
credentials:
key: '%env(S3_KEY)%'
secret: '%env(S3_SECRET)%'
$fileStore->setStorage('gcs'); // If configured
becklyn/ddd-symfony-bridge:^3 must upgrade to ^5. Update dependencies and check for API changes in the bridge (e.g., event names, service IDs).File Metadata Validation: The package validates FileMetadata objects strictly. Ensure:
$metadata = new FileMetadata(
'valid-storage-key', // Must match configured storage
'document.pdf', // Must include extension
'application/pdf' // MIME type recommended
);
Errors like InvalidStorageKeyException or InvalidFileExtensionException may appear if metadata is malformed.
Storage Backend Issues: For S3/GCS, verify IAM roles/credentials and network connectivity. Use Symfony’s monolog to log storage operations:
# config/packages/monolog.yaml
monolog:
handlers:
file_store:
type: stream
path: "%kernel.logs_dir%/file_store.log"
level: debug
channels: ["file_store"]
Custom Storage Adapters: Extend the package by implementing Becklyn\DddFileStore\Storage\StorageInterface:
use Becklyn\DddFileStore\Storage\StorageInterface;
class CustomStorage implements StorageInterface
{
public function store(FileMetadata $metadata, $content): string
{
// Custom logic (e.g., Azure Blob Storage)
return $this->uploadToAzure($metadata, $content);
}
}
Register the adapter in Symfony’s services:
services:
Becklyn\DddFileStore\Storage\StorageInterface: '@custom_storage'
Event Subscribers: Create subscribers for file events to trigger side effects (e.g., notifications, analytics):
use Becklyn\DddFileStore\Event\FileStoredEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class FileStoredSubscriber implements EventSubscriberInterface
{
public static function getSubscribedEvents(): array
{
return [
FileStoredEvent::class => 'onFileStored',
];
}
public function onFileStored(FileStoredEvent $event): void
{
// Send email, log analytics, etc.
}
}
$fileStore->store($metadata, fopen('large_file.zip', 'r'));
FileMetadata objects if frequently reused (e.g., in a Symfony cache pool):
$metadata = $this->cache->get('file_metadata_' . $id, fn() => $this->loadMetadata());
How can I help you explore Laravel packages today?