Installation:
composer require ajroudsoftwares/image-cropper
php bin/console assets:install
Basic Form Integration:
Add the ImageCropperType to your form class:
use AjroudSoftwares\ImageCropperBundle\Form\ImageCropperType;
$builder->add('image', ImageCropperType::class, [
'label' => 'Crop Image',
'required' => false,
]);
First Use Case:
@ImageCropper/Form/image_cropper_type.html.twig (for customization)Basic Image Cropping:
$builder->add('profileImage', ImageCropperType::class, [
'label' => 'Profile Picture',
'mapped' => true,
'data_class' => null, // Handles file uploads automatically
]);
Predefined Aspect Ratio:
$builder->add('banner', ImageCropperType::class, [
'cropperOptions' => [
'aspectRatio' => 16 / 9, // Enforces 16:9 ratio
'viewMode' => 2, // Only show the crop area
],
]);
Custom Crop Dimensions:
$builder->add('thumbnail', ImageCropperType::class, [
'cropperSizeOptions' => [
'width' => 300,
'height' => 300,
],
]);
Handling Submitted Data:
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => UploadedFile::class, // Default for file uploads
]);
}
Validation:
$builder->add('image', ImageCropperType::class, [
'constraints' => [
new File([
'maxSize' => '1024k',
'mimeTypes' => ['image/jpeg', 'image/png'],
'mimeTypesMessage' => 'Please upload a valid image (JPEG/PNG).',
]),
],
]);
Asset Management:
Ensure assets:install is run post-installation to register CropperJS assets.
For production, use assets:install --symlink or configure Webpack Encore.
Twig Customization:
Override the default template by extending @ImageCropper/Form/image_cropper_type.html.twig in your theme.
Example:
{% extends '@ImageCropper/Form/image_cropper_type.html.twig' %}
{% block cropper_js_options %}
{{ parent() }}
{{ include('your_theme/_cropper_extras.js.twig') }}
{% endblock %}
Symfony UX Integration: Combine with Symfony UX for a seamless experience:
// config/packages/framework.yaml
framework:
assets:
json_manifest_path: '%kernel.project_dir%/public/build/assets.json'
Entity Mapping:
Use data_class to bind to entities with file fields (e.g., UploadedFile or custom DTOs).
Asset Loading:
php bin/console assets:install and clear cache (php bin/console cache:clear).File Upload Limits:
upload_max_filesize or post_max_size.php.ini or use client-side compression before upload.Twig Template Overrides:
CropperJS Initialization:
Data Binding:
data_class is misconfigured.UploadedFile or a custom class with a file property.Check Browser Console:
Look for errors like Uncaught ReferenceError: Cropper is not defined (missing assets) or Failed to load resource (CORS issues).
Symfony Profiler: Inspect form data under the "Request" tab to verify uploaded files and cropper options.
Log Cropper Options: Temporarily log options in your template to debug:
{{ dump(cropperOptions) }}
CropperJS Options:
autoCrop or checkOrientation may require additional dependencies (e.g., exif-js).'cropperOptions' => [
'checkOrientation' => true,
],
Responsive Design:
.image-cropper-container {
max-width: 100%;
overflow: hidden;
}
Multiple Instances:
'attr' => ['id' => 'unique-cropper-id'],
Custom Cropper Events:
crop.end) via JavaScript:
document.querySelector('.image-cropper').addEventListener('crop.end', function(e) {
console.log('Crop coordinates:', e.detail.x, e.detail.y);
});
Server-Side Processing:
FileUploadHandler or a service to process cropped images:
// src/Service/ImageCropperService.php
public function cropImage(UploadedFile $file, array $cropData): string
{
// Use Intervention Image or Imagick to crop $file based on $cropData
}
Dynamic Options:
$builder->add('image', ImageCropperType::class, [
'cropperOptions' => $this->getCropperOptionsFromRequest(),
]);
Fallback for Non-JS Users:
{% if app.request.isXmlHttpRequest or not app.request.headers.get('X-Requested-With') == 'XMLHttpRequest' %}
{% include 'fallback_image_upload.html.twig' %}
{% endif %}
How can I help you explore Laravel packages today?