darvinstudio/darvin-image-bundle
Installation
composer require darvinstudio/darvin-image-bundle
Enable the bundle in config/bundles.php:
return [
// ...
DarvinStudio\DarvinImageBundle\DarvinImageBundle::class => ['all' => true],
];
Configuration Publish the default config:
php bin/console darvin:image:install
Update config/packages/darvin_image.yaml to define:
storage_path: Local filesystem or cloud storage (e.g., AWS S3).allowed_formats: Whitelist of permitted image types (e.g., ['jpg', 'png', 'webp']).default_quality: JPEG/PNG compression level (1–100).First Use Case Upload an image via a Symfony form:
// src/Form/ImageUploadType.php
use DarvinStudio\DarvinImageBundle\Form\Type\ImageType;
$builder->add('image', ImageType::class, [
'label' => 'Upload Image',
'required' => false,
]);
Process the upload in a controller:
// src/Controller/ImageController.php
use DarvinStudio\DarvinImageBundle\Entity\Image;
public function upload(Request $request)
{
$image = new Image();
$form = $this->createForm(ImageType::class, $image);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$image->upload(); // Auto-resizes, validates, and saves
return new JsonResponse(['path' => $image->getPath()]);
}
}
Image Upload & Processing
upload():
allowed_formats.default_dimensions (configurable per entity).thumbnail_config is set).width, height, filesize).$image->setWidth(800); // Override default width
$image->setQuality(85); // Adjust compression
$image->upload();
Entity Integration
DarvinStudio\DarvinImageBundle\Entity\Image or use traits:
// src/Entity/Product.php
use DarvinStudio\DarvinImageBundle\Entity\ImageTrait;
class Product
{
use ImageTrait;
// ...
}
# config/doctrine/Product.orm.yml
DarvinStudio\DarvinImageBundle\Entity\Image:
oneToOne:
mapping: true
targetEntity: App\Entity\Product
inversedBy: image
Dynamic Thumbnails
darvin_image.yaml:
thumbnail_config:
product_grid:
width: 300
height: 300
crop: true
product_detail:
width: 800
height: 800
quality: 90
$thumbnail = $image->getThumbnail('product_grid');
Cloud Storage
DarvinStudio\DarvinImageBundle\Storage\CloudStorage:
# config/packages/darvin_image.yaml
storage:
adapter: aws_s3
config:
bucket: my-bucket
region: us-east-1
credentials:
key: "%env(AWS_KEY)%"
secret: "%env(AWS_SECRET)%"
VichUploaderBundle for advanced features (e.g., onUpload, onRemove hooks).use ApiPlatform\Core\Annotation\ApiResource;
use DarvinStudio\DarvinImageBundle\Entity\Image;
#[ApiResource]
class Product
{
#[ApiProperty(iri: 'getImage')]
public Image $image;
}
src attribute in Twig:
<img src="{{ image.getWebPath('product_detail') }}" alt="{{ product.name }}">
Configuration Overrides
framework/filesystem). Explicitly set storage_path to avoid issues.php bin/console cache:clear
File Permissions
storage_path is writable by the web server user (e.g., www-data):
chmod -R 775 var/storage
Thumbnail Caching
darvin_image.yaml:
thumbnail_cache:
enabled: true
ttl: 86400 # 1 day
Doctrine Lifecycle Events
onFlush/onFlush listeners, ensure the Image entity is persisted before upload:
$product->setImage($image);
$entityManager->persist($product);
$entityManager->flush(); // Required before $image->upload()
Large Files
upload_max_filesize, post_max_size) may block uploads. Adjust in php.ini or .htaccess:
upload_max_filesize = 20M
post_max_size = 20M
Image entity for errors property:
if ($image->hasErrors()) {
dd($image->getErrors()); // Array of validation messages
}
darvin_image.yaml:
debug: true
Logs will appear in var/log/darvin_image.log.Custom Storage Adapters
DarvinStudio\DarvinImageBundle\Storage\StorageInterface for custom backends (e.g., Google Cloud Storage):
class CustomStorage implements StorageInterface
{
public function save(FileInfo $file): string { /* ... */ }
public function delete(string $path): void { /* ... */ }
}
services:
DarvinStudio\DarvinImageBundle\Storage\StorageInterface:
alias: App\Storage\CustomStorage
Pre/Post Upload Hooks
// src/EventListener/ImageUploadListener.php
use DarvinStudio\DarvinImageBundle\Event\ImageUploadEvent;
class ImageUploadListener
{
public function onUpload(ImageUploadEvent $event)
{
if ($event->getImage()->getMimeType() === 'image/jpeg') {
$event->setQuality(90); // Modify quality dynamically
}
}
}
services.yaml:
services:
App\EventListener\ImageUploadListener:
tags:
- { name: kernel.event_listener, event: darvin.image.upload, method: onUpload }
Dynamic Resizing
services:
DarvinStudio\DarvinImageBundle\Service\ImageResizer:
class: App\Service\CustomImageResizer
arguments:
$defaultWidth: 1200
resize() method to add filters (e.g., sharpening):
use Imagine\Image\Box;
use Imagine\Image\Imagine;
class CustomImageResizer
{
public function resize(Imagine $image, Box $size): Imagine
{
$image->resize($size);
$image->sharpen(10); // Add custom filter
return $image;
}
}
DarvinImageBundle\Command\ProcessImagesCommand to regenerate thumbnails for existing images:
php bin/console darvin:image:process --entity=App\Entity\Product --property=image
Image entities manually:
$qb = $entityManager->createQueryBuilder()
How can I help you explore Laravel packages today?