Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

File Upload Bundle Laravel Package

ns/file-upload-bundle

A file upload bundle for PHP applications that streamlines handling uploaded files, including validation, storage, and integration with your existing framework setup.

View on GitHub
Deep Wiki
Context7

Getting Started

The ns/file-upload-bundle is a Symfony bundle (not Laravel — it's a classic Symfony Bundle registered in config/bundles.php). First steps:

  1. Install via Composer:
    composer require noblet-solutions/file-upload-bundle
    
  2. Register the bundle in config/bundles.php:
    return [
        // ...
        NobletSolutions\FileUploadBundle\NobletFileUploadBundle::class => ['all' => true],
    ];
    
  3. Configure the upload target. The bundle expects a writable directory (usually public/uploads or var/uploads):
    # config/packages/noblet_file_upload.yaml
    noblet_file_upload:
        upload_dir: '%kernel.project_dir%/public/uploads'
        web_path: '/uploads'
    
  4. First use case: an entity that has a file/image field. Add the bundle's upload trait (or extend its base entity), point the bundle at the file property, and let the bundle's Doctrine listener move the file from the temporary path into your configured directory on prePersist/preUpdate.

Look first at:

  • The bundle's DependencyInjection/Configuration.php for exact config keys.
  • The Entity/ (or Model/) folder for the base entity/trait your domain entities should extend.
  • The EventListener/ or EventListener/UploadListener.php file — that's where the pre-persist file-moving logic lives and where debugging usually lands you.

Implementation Patterns

Entity via trait / base class

use NobletSolutions\FileUploadBundle\Model\FileUploadTrait;

class Document
{
    use FileUploadTrait;
    // ...
}

The trait typically supplies $file, $path, $getFile(), $setFile(), and an internal temp-file holder. Your entity never worries about where the file lives — the listener does the filesystem work.

Annotated upload field

Because the bundle uses a Doctrine event listener, it discovers which property to upload by annotation/attribute on the entity property:

#[Uploadable(targetField: 'file')]
private ?File $file = null;

Confirm the exact attribute name against the bundle's source — this is the single most common integration failure point.

Controller + Form

$form = $this->createForm(DocumentType::class, new Document());
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
    $em->persist($form->getData());
    $em->flush(); // listener fires here, file is moved
}

The upload happens on flush, not on form submit. Anything you inspect before flush() still shows the temp path.

Uploader service (manual use)

For files not tied to an entity (CSV imports, async jobs), inject the uploader directly:

public function __construct(private FileUploaderInterface $uploader) {}

$path = $this->uploader->upload($uploadedFile);

This is the escape hatch when Doctrine listeners are awkward (e.g., DTOs, batch imports).

Form type integration

The bundle usually ships an UploadType/FileType form element that handles the UploadedFile → File translation. Prefer it over Symfony's plain FileType so the temporary-file metadata the listener expects is set.

Workflow tip

  • Treat the uploader service as the primary API, and the listener as convenience glue.
  • For async or queue-driven uploads, bypass the listener entirely and call the uploader, then persist the path yourself.

Gotchas and Tips

  • Symfony vs. Laravel framing. Despite generic "file upload bundle" descriptions, this is a Symfony bundle. It will not work in a Laravel app without significant adaptation. If your team is Laravel-first, budget for a bridge service rather than trying to "composer require" it in.
  • Writable directory is on you. The bundle moves files but does not create the target directory. Add mkdir in bootstrap or a deployment step, and set ownership (e.g., www-data) — a silent false from rename() is the classic first-bug.
  • Listeners rely on annotations/attributes. If the property is not detected, the file is never moved and the DB ends up with a temp path like /tmp/phpXXXX. Log the resolved target field when debugging.
  • preUpdate does not fire without a change. Doctrine skips updates when no mapped field changed. If a user re-uploads the same filename with the same path, the listener may not run — force a field change ($entity->setUpdatedAt(new \DateTime())) or call $em->getUnitOfWork()->recomputeChangeSet(...).
  • Filename collisions. Check whether the bundle sanitises/renames files. If not, two uploads of report.pdf overwrite each other. Decorate the uploader service and prefix with a UUID/hash.
  • Old-file cleanup. Most lightweight bundles do not delete the previous file on update. Handle this in your entity setter or a custom postUpdate listener.
  • Cache. After changing config or your entity's upload field, run bin/console cache:clear — the annotation reader caches metadata aggressively.
  • Extension point. The uploader is normally an interface (FileUploaderInterface); override the noblet_file_upload.uploader service alias in services.yaml to swap in your own implementation (S3, Flysystem, virus scanning).
  • Validation is not your friend here. Size/MIME limits are usually not enforced by the bundle. Add @Assert\File(maxSize=...) on the entity property — otherwise you inherit whatever php.ini allows.
  • Testing. In functional tests, the Doctrine listener will try to rename() real files. Point upload_dir at %kernel.cache_dir%/test-uploads in config/packages/test/noblet_file_upload.yaml and clean up in tearDown().
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle
glavweb/extra-bundle
glavweb/api-bundle
glavweb/admin-bundle
adachsoft/api-version-bundle
elsayed85/laravel-api-exceptions
ouhssini/laravel-demo-mode
daworks/ncloud-outbound-mailer-driver
gp247/cms
ignibyte/aic-gates
nexa-merchant/blog
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
cgv/localized-resource