Installation
composer require dwr/avatar-bundle
Register the bundle in config/bundles.php (Symfony 4+) or AppKernel.php (Symfony 2/3):
// Symfony 4+
Dwr\AvatarBundle\DwrAvatarBundle::class => ['all' => true],
Configuration
Add to config/packages/dwr_avatar.yaml (Symfony 4+) or app/config/config.yml (Symfony 2/3):
dwr_avatar:
default_avatar: '%kernel.project_dir%/path/to/default.png'
upload_directory: '%kernel.project_dir%/var/avatars'
allowed_extensions: ['jpg', 'jpeg', 'png', 'gif']
max_width: 200
max_height: 200
First Use Case Generate an avatar from a user-uploaded file in a controller:
use Dwr\AvatarBundle\Generator\AvatarGenerator;
public function uploadAvatar(Request $request)
{
$file = $request->files->get('avatar');
$generator = $this->get('dwr_avatar.generator');
$avatarPath = $generator->generate($file, 'user_' . $this->getUser()->getId());
return new Response('Avatar saved to: ' . $avatarPath);
}
Twig Integration
Use the avatar Twig filter in templates:
<img src="{{ avatar(user.avatarPath, 50, 50) }}" alt="User Avatar">
Avatar Generation
$generator = $this->get('dwr_avatar.generator');
$path = $generator->generate($uploadedFile, 'filename_prefix');
Dwr\AvatarBundle\Generator\UrlAvatarGenerator service:
$urlGenerator = $this->get('dwr_avatar.url_generator');
$path = $urlGenerator->generate('https://example.com/image.jpg', 'filename_prefix');
Dynamic Resizing Override default dimensions per request:
$path = $generator->generate($file, 'filename', 100, 100);
Fallback Avatars
Configure a default avatar in config and handle missing files gracefully:
<img src="{{ avatar(user.avatarPath, 50, 50, 'default') }}">
Batch Processing Process multiple avatars in a loop (e.g., for bulk user imports):
foreach ($users as $user) {
$file = $user->getAvatarFile();
$generator->generate($file, 'user_' . $user->getId());
}
Entity Integration
Add a avatarPath property to your User entity and update it post-upload:
public function setAvatarFile($file)
{
$generator = $this->get('dwr_avatar.generator');
$this->avatarPath = $generator->generate($file, 'user_' . $this->id);
}
Form Handling
Use Symfony’s File type in forms:
$builder->add('avatar', FileType::class, [
'label' => 'Profile Picture',
'mapped' => false,
]);
Cache Control Append a query string to avatar URLs to bypass cache:
<img src="{{ avatar(user.avatarPath, 50, 50) }}?v={{ user.updatedAt|date('U') }}">
Security Restrict avatar uploads to trusted users and validate file types:
$generator->setAllowedExtensions(['jpg', 'png']); // Override config per request
GD Extension Requirement
Ensure php-gd is installed and enabled. Test with:
php -m | grep gd
If missing, install via:
sudo apt-get install php-gd # Debian/Ubuntu
sudo yum install php-gd # CentOS/RHEL
File Permissions
The upload_directory must be writable by the web server (e.g., www-data or nginx):
chmod -R 775 var/avatars
chown -R www-data:www-data var/avatars
Image Corruption
if (!$file->isValid() || !in_array($file->guessExtension(), $allowedExtensions)) {
throw new \RuntimeException('Invalid file');
}
Symfony 4+ Autowiring The bundle predates Symfony 4’s autowiring. Explicitly type-hint services:
public function __construct(
private AvatarGenerator $avatarGenerator,
private UrlAvatarGenerator $urlAvatarGenerator
) {}
Log Generation Errors Enable debug mode and check logs for GD errors:
# config/packages/monolog.yaml
handlers:
main:
type: stream
path: "%kernel.logs_dir%/%kernel.environment%.log"
level: debug
Verify Generated Paths Log the output path to confirm files are saved:
$path = $generator->generate($file, 'test');
\Log::debug('Avatar saved to:', ['path' => $path]);
Check File Existence Debug missing avatars with:
if (!file_exists($avatarPath)) {
throw new \RuntimeException("Avatar not found at: $avatarPath");
}
Custom Avatar Styles
Extend the Dwr\AvatarBundle\Generator\AvatarGenerator to add filters (e.g., grayscale):
use GdImage;
public function generate($file, $filename, $width = null, $height = null)
{
$image = $this->createImage($file);
imagefilter($image, IMG_FILTER_GRAYSCALE); // Custom filter
return $this->saveImage($image, $filename, $width, $height);
}
Dynamic Default Avatars Override the default avatar per user (e.g., based on gender):
public function getDefaultAvatarPath($user)
{
return $user->isMale()
? $this->container->getParameter('male_default_avatar')
: $this->container->getParameter('female_default_avatar');
}
Cloud Storage Integration Replace local file saving with AWS S3 or similar:
public function saveImage($image, $filename, $width, $height)
{
$path = $this->generateRemotePath($filename);
$this->s3Client->putObject([
'Bucket' => 'avatars-bucket',
'Key' => $path,
'Body' => $this->imageToBytes($image),
]);
return $path;
}
Relative vs. Absolute Paths
Use %kernel.project_dir% for portability:
upload_directory: '%kernel.project_dir%/var/avatars'
Avoid hardcoding paths like /var/www/avatars.
Case Sensitivity
allowed_extensions is case-sensitive. Use lowercase:
allowed_extensions: ['jpg', 'png'] # Not ['JPG', 'PNG']
Legacy Symfony 2 Compatibility
For Symfony 2, ensure the bundle is loaded after the FrameworkBundle in AppKernel.php:
new Dwr\AvatarBundle\DwrAvatarBundle(),
Environment-Specific Configs
Override settings per environment (e.g., disable uploads in test):
# config/packages/dwr_avatar_test.yaml
dwr_avatar:
upload_directory: null # Disable uploads in tests
How can I help you explore Laravel packages today?