Installation
composer require 2lenet/entity-file-bundle
Run migrations (if applicable) and bundle installation:
php bin/console lle:entity-file:install
Basic Configuration
Add a configuration for your entity in config/lle_entity_file.yaml:
lle_entity_file:
configurations:
seller_logos:
class: "App\Entity\Seller"
storage_adapter: "lle_entity_file.storage.default"
This creates a folder data/seller_logos for storing files.
First Use Case
Attach a file to an entity (e.g., Seller) in a controller or service:
use LLE\EntityFileBundle\Entity\FileEntity;
$seller = $entityManager->getRepository(Seller::class)->find(1);
$fileEntity = new FileEntity();
$fileEntity->setEntity($seller);
$fileEntity->setFile('path/to/logo.png');
$entityManager->persist($fileEntity);
$entityManager->flush();
File Attachment
Use FileEntity to associate files with entities:
$fileEntity = new FileEntity();
$fileEntity->setEntity($yourEntity); // e.g., Product, User
$fileEntity->setFile($filePathOrStream);
$fileEntity->setMetadata(['mime_type' => 'image/png']);
$entityManager->persist($fileEntity);
Retrieving Files Fetch files for an entity:
$files = $entityManager->getRepository(FileEntity::class)
->findBy(['entity' => $seller, 'entityClass' => Seller::class]);
URL-Based File Handling
For remote files (e.g., URLs), use the RetrieveFromUrl service:
$service = $container->get('lle_entity_file.retrieve_from_url');
$fileEntity = $service->retrieve('https://example.com/logo.png', $seller);
Crudit Integration
Use the Crudit trait in your entity to simplify file management:
use LLE\EntityFileBundle\Crudit\CruditTrait;
class Seller implements CruditInterface
{
use CruditTrait;
// ...
}
This auto-generates file-related CRUD methods (e.g., addFile, removeFile).
Custom Storage Adapters
Extend LLE\EntityFileBundle\Storage\Adapter\AbstractAdapter to support cloud storage (S3, FTP):
# config/packages/lle_entity_file.yaml
lle_entity_file:
storage:
s3_adapter:
service_id: 'oneup_flysystem.s3_adapter'
Update your configuration to use the new adapter:
seller_logos:
storage_adapter: "lle_entity_file.storage.s3_adapter"
Validation Validate file types/sizes in your entity or form:
use Symfony\Component\Validator\Constraints as Assert;
class Product
{
/**
* @Assert\File(
* maxSize="2M",
* mimeTypes={"image/jpeg", "image/png"}
* )
*/
private $image;
}
Event Listeners Trigger actions on file upload (e.g., generate thumbnails):
namespace App\EventListener;
use LLE\EntityFileBundle\Event\FileUploadEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class FileUploadSubscriber implements EventSubscriberInterface
{
public static function getSubscribedEvents()
{
return [
FileUploadEvent::NAME => 'onFileUpload',
];
}
public function onFileUpload(FileUploadEvent $event)
{
// Process file (e.g., resize)
}
}
API Responses Serialize file URLs in API responses:
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
class SellerController extends AbstractController
{
public function show(Seller $seller): JsonResponse
{
$files = $seller->getFiles(); // Assuming CruditTrait
$fileUrls = array_map(fn($file) => $file->getUrl(), $files);
return $this->json(['seller' => $seller, 'files' => $fileUrls]);
}
}
Entity-File Relationship
entityClass in FileEntity can cause queries to fail.$files = $entityManager->getRepository(FileEntity::class)
->findBy(['entity' => $seller, 'entityClass' => Seller::class]);
Storage Adapter Misconfiguration
InvalidArgumentException.lle_entity_file.yaml match your flysystem configuration.File Deletion
Cascade in Doctrine or manually delete files in a preRemove event:
use Doctrine\ORM\Event\PreRemoveEventArgs;
public function preRemove(PreRemoveEventArgs $args)
{
$entity = $args->getEntity();
if ($entity instanceof FileEntity) {
$this->fileManager->delete($entity->getFile());
}
}
Crudit Trait Overhead
public function addFile(FileEntity $file)
{
if (!$this->canAddFile($file)) {
throw new \RuntimeException('Invalid file');
}
parent::addFile($file);
}
Log File Operations Enable debug mode to log file operations:
# config/packages/dev/lle_entity_file.yaml
lle_entity_file:
debug: true
Check FileEntity Metadata Debug missing files by inspecting metadata:
$file = $entityManager->find(FileEntity::class, $id);
var_dump($file->getMetadata()); // Check 'path', 'url', etc.
Storage Adapter Issues
php bin/console debug:container lle_entity_file.storage.default
$adapter = $container->get('lle_entity_file.storage.default');
var_dump($adapter->listContents(''));
Custom FileEntity Fields
Extend FileEntity to add custom fields (e.g., altText):
namespace App\Entity;
use LLE\EntityFileBundle\Entity\FileEntity as BaseFileEntity;
class FileEntity extends BaseFileEntity
{
private $altText;
// Getters/setters, Doctrine mappings
}
Dynamic Configurations Load configurations dynamically (e.g., from database):
$configs = $entityManager->getRepository(Config::class)->findAll();
foreach ($configs as $config) {
$bundleConfig[$config->getName()] = [
'class' => $config->getEntityClass(),
'storage_adapter' => $config->getStorageAdapter(),
];
}
Batch Processing
Use Symfony’s Messenger for async file processing:
$message = new ProcessFileMessage($fileEntity->getId());
$this->messageBus->dispatch($message);
Access Control Restrict file access via voters:
use Symfony\Component\Security\Core\Authorization\Voter\VoterInterface;
class FileVoter implements VoterInterface
{
public function supports(string $attribute, $subject): bool
{
return $subject instanceof FileEntity && $attribute === 'VIEW';
}
public function vote(..., FileEntity $file): bool
{
return $file->getEntity()->getUser() === $user;
}
}
How can I help you explore Laravel packages today?