Installation:
composer require 2lenet/attachment-bundle
Add the bundle to config/bundles.php:
return [
// ...
Lle\AttachmentBundle\LleAttachmentBundle::class => ['all' => true],
];
Routing:
Add to config/routes.yaml:
lle_attachment:
resource: "@LleAttachmentBundle/Resources/config/routing/routes.yaml"
First Use Case: Embed the attachment widget in a Twig template:
{{ render_attachment(entity) }}
This renders an upload widget for the given entity.
Uploading Attachments:
Use {{ render_attachment(entity) }} to generate an upload form for an entity. The bundle assumes the entity has a files or attachments property (adjustable via configuration).
Displaying Attachments: Render a downloadable list of attachments with:
{{ list_attachment(entity) }}
This generates an unordered list (<ul>) of links to download attachments.
Grouped Attachments:
Filter attachments by a field (e.g., pdf) in EasyAdminPlus or Twig:
{{ render_attachment(entity, {'field': 'pdf'}) }}
Or in EasyAdminPlus:
fields:
- { type: 'tab', id: 'documents', label: 'Documents', action: 'lle.attachment', options: {'field': 'pdf'} }
Integration with EasyAdminPlus: Embed attachments in an EasyAdminPlus CRUD show view:
show:
title: 'Show Item'
fields:
- { property: 'name', type: 'string' }
- { type: 'tab', id: 'attachments', label: 'Attachments', action: 'lle.attachment' }
Custom Entity Mapping:
Configure the bundle to work with custom entity properties or relationships. Override the default files or attachments property in config/packages/lle_attachment.yaml:
lle_attachment:
attachment_property: 'custom_attachments' # Override default
Dynamic Attachment Groups:
Use the field option to dynamically render attachments for nested entities (e.g., item.examens):
{% for examen in item.examens %}
<h3>{{ examen.title }}</h3>
{{ render_attachment(examen, {'field': 'documents'}) }}
{% endfor %}
Validation and Storage:
The bundle handles file uploads and storage (default: public/uploads/). Customize storage paths or validation rules by extending the bundle’s services or creating a custom form type.
API Integration:
For API endpoints, use the underlying controller (lle.attachment.show.action) to fetch attachments programmatically. Example:
// In a custom controller
$this->renderAttachmentAction($entity, ['field' => 'pdf']);
Entity Property Mismatch:
The bundle defaults to files or attachments properties. If your entity uses a different property (e.g., documents), configure it in lle_attachment.yaml:
lle_attachment:
attachment_property: 'documents'
Failure to do so will result in errors or no attachments being rendered.
Routing Conflicts:
The bundle’s routes are prefixed with lle_attachment. Ensure no naming conflicts with existing routes. If using Symfony Flex, manually add the routes to config/routes.yaml until a recipe is available.
File Storage Permissions:
The bundle stores files in public/uploads/ by default. Ensure the directory is writable:
mkdir -p public/uploads
chmod -R 775 public/uploads
EasyAdminPlus Integration:
The action field in EasyAdminPlus requires the exact alias lle.attachment. Typos (e.g., lle_attachment) will break rendering.
No Built-in Validation: The bundle does not include file type/size validation by default. Extend the form type or use Symfony’s validation constraints:
# config/validation.yaml
Lle\AttachmentBundle\Form\AttachmentType:
constraints:
- File:
maxSize: 1024k
mimeTypes: ['application/pdf']
Check Controller Alias:
If {{ render_attachment(entity) }} fails, verify the controller alias lle.attachment is correctly mapped in routing/routes.yaml.
Entity Debugging: Dump the entity to confirm the attachment property exists:
{{ dump(entity.vars) }}
Look for files, attachments, or your custom property.
Symfony Profiler:
Use the profiler to inspect the lle.attachment.show.action controller call and debug parameters or errors.
Log File Uploads: Enable debug mode to log file uploads:
# config/packages/dev/monolog.yaml
handlers:
main:
type: stream
path: "%kernel.logs_dir%/%kernel.environment%.log"
level: debug
Custom Form Types:
Extend the default AttachmentType to add fields or validation:
// src/Form/ExtendedAttachmentType.php
namespace App\Form;
use Lle\AttachmentBundle\Form\AttachmentType;
class ExtendedAttachmentType extends AttachmentType {
public function buildForm(FormBuilderInterface $builder, array $options) {
$builder->add('custom_field', TextType::class);
}
}
Override the bundle’s service in config/services.yaml:
Lle\AttachmentBundle\Form\AttachmentType: '@App\Form\ExtendedAttachmentType'
Storage Backend:
Replace the default storage handler (e.g., for AWS S3). Implement a custom service tagged as lle_attachment.storage:
services:
App\Service\CustomAttachmentStorage:
tags:
- { name: lle_attachment.storage }
Twig Extensions:
Extend the Twig functions to add custom logic. Override the bundle’s AttachmentTwigExtension:
// src/Twig/AppExtension.php
namespace App\Twig;
use Lle\AttachmentBundle\Twig\AttachmentTwigExtension;
class AppExtension extends AttachmentTwigExtension {
public function renderAttachment($entity, $options = []) {
// Custom logic
return parent::renderAttachment($entity, $options);
}
}
Register the extension in config/services.yaml:
Lle\AttachmentBundle\Twig\AttachmentTwigExtension: '@App\Twig\AppExtension'
Event Listeners: Listen to attachment upload events to trigger post-processing (e.g., image resizing):
// src/EventListener/AttachmentListener.php
namespace App\EventListener;
use Lle\AttachmentBundle\Event\AttachmentUploadEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class AttachmentListener implements EventSubscriberInterface {
public static function getSubscribedEvents() {
return [
AttachmentUploadEvent::NAME => 'onAttachmentUpload',
];
}
public function onAttachmentUpload(AttachmentUploadEvent $event) {
// Custom logic (e.g., resize images)
}
}
How can I help you explore Laravel packages today?