## Getting Started
### Minimal Setup
1. **Installation**
Add the bundle via Composer:
```bash
composer require austral/entity-file-bundle
Enable it in config/bundles.php:
Austral\EntityFileBundle\EntityFileBundle::class => ['all' => true],
Configuration Publish the default config:
php bin/console austral:entity-file:install
Update config/packages/austral_entity_file.yaml to define:
upload_dir (e.g., %kernel.project_dir%/public/uploads)allowed_mime_types (e.g., ['image/jpeg', 'image/webp'])squoosh_cli_path (if using Squoosh for compression)First Use Case: Basic File Upload
Create an entity with a File property (e.g., Product):
use Austral\EntityBundle\Interfaces\FileInterface;
class Product implements FileInterface
{
#[ORM\Column(type: 'string', nullable: true)]
private ?string $fileId = null;
// Getters/setters for fileId
}
Use the FileUploader service in a controller:
use Austral\EntityFileBundle\Services\FileUploader;
public function uploadFile(Request $request, FileUploader $uploader): Response
{
$product = new Product();
$file = $request->files->get('file');
$uploader->upload($product, $file, 'product_image');
// Persist $product...
}
Uploading Files
FileUploader::upload($entity, $file, $fieldName).FileUploader::uploadMultiple($entity, $files, $fieldName).Constraints (e.g., @Assert\File) or custom validators from the bundle.Thumbnail Generation
Configure thumbnails in config/packages/austral_entity_file.yaml:
austral_entity_file:
thumbnails:
product_thumb:
size: [200, 200]
mode: outbound
extension: webp
Generate thumbnails via:
$uploader->generateThumbnail($entity, 'product_image', 'product_thumb');
File Downloads
Use the FileDownloader service:
use Austral\EntityFileBundle\Services\FileDownloader;
public function downloadFile(FileDownloader $downloader, string $fileId): Response
{
return $downloader->download($fileId);
}
File Deletion
$uploader->delete($entity, 'product_image');
prePersist/preUpdate to auto-upload files:
use Austral\EntityFileBundle\Services\FileUploader;
use Doctrine\ORM\Event\LifecycleEventArgs;
public function prePersist(LifecycleEventArgs $args): void
{
$entity = $args->getObject();
if ($entity instanceof FileInterface && $entity->getFile() && !$entity->getFileId()) {
$uploader = $this->container->get(FileUploader::class);
$uploader->upload($entity, $entity->getFile(), 'file');
}
}
FileType from the bundle for seamless uploads:
$builder->add('file', FileType::class, [
'label' => 'Product Image',
'mapped' => false,
'required' => false,
]);
squoosh-cli is installed globally or set squoosh_cli_path in config. Compression is auto-applied for WebP files (configure via compression key in YAML).WebP Rotation Loss
imagine/imagine directly to preserve metadata before compression:
use Imagine\Gd\Imagine;
$image = (new Imagine())->open($filePath);
$image->rotate($entity->getRotationAngle());
$image->save($filePath);
Multi-Object Uploads
foreach ($entities as $entity) {
$uploader->upload($entity, $request->files->get('file_' . $entity->getId()), 'file');
}
File Permissions
upload_dir lacks write permissions.chmod -R 775 %kernel.project_dir%/public/uploads
Squoosh CLI Dependency
squoosh-cli is missing or misconfigured.squoosh --help
# config/packages/dev/monolog.yaml
monolog:
handlers:
main:
level: debug
FileUploader::getFilePath($entity, $fieldName) to debug stored paths.Austral\EntityBundle\Interfaces\FileInterface (or the updated interface in v3.1.0+).Custom Thumbnail Filters
Extend Austral\EntityFileBundle\Services\ThumbnailGenerator to add filters (e.g., watermarks):
class CustomThumbnailGenerator extends ThumbnailGenerator
{
protected function applyFilters(Imagine\ImageInterface $image): Imagine\ImageInterface
{
$image = parent::applyFilters($image);
// Add custom logic (e.g., watermark)
return $image;
}
}
Register the service in services.yaml:
Austral\EntityFileBundle\Services\ThumbnailGenerator:
alias: App\Services\CustomThumbnailGenerator
Pre/Post Upload Hooks Subscribe to events via Symfony’s event dispatcher:
use Austral\EntityFileBundle\Events\FileUploadEvent;
$dispatcher->addListener(FileUploadEvent::UPLOAD, function (FileUploadEvent $event) {
// Pre-upload logic (e.g., validate file content)
});
Custom File Storage
Override the default storage adapter by implementing Austral\EntityFileBundle\Storage\FileStorageInterface and binding it in services.yaml:
austral.entity_file.storage:
class: App\Storage\CustomFileStorage
arguments: ['@filesystem']
$fieldName is omitted, the bundle defaults to file. Override this in your entity’s getFileField() method.MimeTypeGuesser by default. For stricter validation, extend the FileValidator service.id) before upload.
```markdown
### Laravel-Specific Adaptations
While this bundle is Symfony-focused, here’s how to adapt it for Laravel (using Symfony’s components):
1. **Installation**
Use `composer require austral/entity-file-bundle` and manually load the bundle in `bootstrap/app.php`:
```php
$app->register(\Austral\EntityFileBundle\EntityFileBundle::class);
Configuration Publish config via:
php artisan vendor:publish --tag=austral_entity_file_config
Update config/austral_entity_file.php.
Service Binding
Bind Symfony services to Laravel’s container in AppServiceProvider:
public function register(): void
{
$this->app->bind(\Austral\EntityFileBundle\Services\FileUploader::class);
}
Doctrine Integration
Use laravel-doctrine or cycle-orm to bridge Doctrine with Laravel. Example for prePersist:
use Doctrine\ORM\Event\LifecycleEventArgs;
use Austral\EntityFileBundle\Services\FileUploader;
public function prePersist(LifecycleEventArgs $args): void
How can I help you explore Laravel packages today?