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

Upload Bundle Laravel Package

pentatrion/upload-bundle

Pentatrion UploadBundle is a Symfony bundle that simplifies file uploads with Dropzone-powered AJAX uploads, form integration, previews, and server-side handling for robust upload workflows.

View on GitHub
Deep Wiki
Context7

Getting Started

pentatrion/upload-bundle is a Symfony bundle, not a Laravel package — so the first decision is whether you're actually in a Symfony app (or willing to lift the source into a Laravel service). It has 4 stars and 0 dependents, so treat it as a well-structured reference implementation you may need to fork rather than a battle-tested dependency.

Minimal path:

composer require pentatrion/upload-bundle
  1. Register the bundle in config/bundles.php and check config/packages/pentatrion_upload.yaml after bin/console config:dump-reference pentatrion_upload.
  2. Create your entities. Subclass Pentatrion\UploadBundle\Entity\File and TemporaryFile, then point config at them:
    pentatrion_upload:
        file_class: App\Entity\Attachment
        temporary_file_class: App\Entity\TemporaryAttachment
        storage_directory: '%kernel.project_dir%/var/uploads'
    
  3. Run the migration and confirm the storage directory exists and is writable.

Where to look first (in this order): README.md → src/FileManager.php + src/FileManagerInterface.php (the entire public API) → src/DependencyInjection/Configuration.php (every config key) → src/Entity/File.php. The docs are thin; the source is small, so read it.

First use case: a single avatar/image upload on a User profile form using Symfony UX Dropzone. The bundle owns the HTTP endpoint that receives the file, writes it to disk, persists a File row, and returns JSON; your controller just receives the resulting file reference and links it to User.

For a Laravel brain: FileManagerInterface ≈ a service wrapping Storage::disk()->putFileAs(), and the File entity ≈ a Media model. There is no Storage facade, no streams abstraction, no S3 driver — it's local filesystem + Doctrine.

Implementation Patterns

Inject the manager, not the entity. FileManagerInterface is the seam you'll mock in tests:

public function upload(Request $request, FileManagerInterface $fileManager): Response
{
    $file = $fileManager->handleFile($request->files->get('file'), 'avatars/');
    // $file is now a persisted File entity with a generated storage name
}

Temporary → permanent promotion. The typical flow is: JS uploads immediately to a temp area, the form submit posts a token/ID, and your controller promotes it:

  • handleTemporaryFile($temporaryFile) when the form validates
  • deleteTemporaryFiles() on abandon, plus a scheduled cleanup (cron or a kernel.terminate listener)

One-to-many galleries. Store File entities against a parent with OneToMany, and expose getFiles()-style payloads so the frontend Dropzone/FilePond controller can rehydrate the existing list on edit forms. Prefer an explicit ordering column over relying on insertion order.

Validation belongs outside the bundle. Enforce size/MIME with Symfony Validator constraints on a DTO wrapping the File, not with the dropzone config — client-side limits are advisory only.

Testing. Functional-test the upload endpoint with UploadedFile::fake()-equivalent (new UploadedFile($path, 'x.png', 'image/png', null, true)), asserting the JSON shape rather than internals; unit-test your own controller against a mocked FileManagerInterface.

Integration tip. Mirror the bundle's delete endpoint (DELETE on the file route) rather than deleting files directly from your controller, so DB rows and disk stay in sync.

Gotchas and Tips

  • Low bus factor. 4 stars, 0 dependents, sparse docs. Pin the exact version in composer.json, and vendor/fork the FileManager if you depend on it heavily. Budget an hour to read src/ before adopting.
  • Doctrine is not optional. The bundle persists entities. If your app isn't Doctrine-backed (or you're porting to Laravel), you're lifting the file-writing logic, not the bundle — the ORM coupling is the main porting cost.
  • Temporary files leak by default. Nothing garbage-collects the temp directory unless you wire it. Add a scheduled command early; this is the most common production surprise.
  • Entity name collisions. Don't call your subclass File — you'll collide with Symfony\Component\HttpFoundation\File\File in imports. Use Attachment/Media.
  • Storage path resolution. Verify from Configuration.php whether storage_directory is resolved relative to the project dir or the CWD; the safest move is an absolute %kernel.project_dir%-prefixed value. Ensure the web server user can write there.
  • Filename handling. Never trust the original client filename. Let the bundle generate the stored name and keep only a sanitized display name plus the MIME type on your entity.
  • Debugging upload endpoint failures. A 400/415 from the dropzone route almost always means a non-multipart request, a missing CSRF token, or a body payload larger than post_max_size/upload_max_filesize in PHP — check PHP limits before blaming the bundle. Also confirm the route prefix is what the JS controller expects.
  • Extension points that actually work: alias FileManagerInterface to your own service in services.yaml to override behavior, and add metadata fields (alt text, ordering, tenant id) to your File subclass rather than editing the bundle.
  • Version your migrations. Because you own the File entity subclass, treat schema changes as yours; don't expect upstream migrations to cover your added columns.
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