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 Uploader Bundle Laravel Package

jbouzekri/file-uploader-bundle

A Symfony bundle that streamlines file uploads tied to Doctrine entities, handling storage, file naming, and lifecycle so you can attach and manage uploaded files with minimal boilerplate.

View on GitHub
Deep Wiki
Context7

Getting Started

Read this first: it is a Symfony bundle, not a Laravel package. There is no ServiceProvider, no config/file_uploader.php, no facade, and php artisan vendor:publish will do nothing for you. Installing it into a Laravel app gets you a folder in vendor/ and nothing else — the classes extend Symfony\Bundle\FrameworkBundle\Controller\Controller, hook into the Symfony kernel, and expect AppKernel/bundles.php registration. If you are committed to Laravel, treat this as a reference architecture, not a dependency (see the last pattern under Implementation Patterns for the Laravel-native equivalent).

Assuming you land in a Symfony 3.x/4.x app:

  1. composer require jbouzekri/file-uploader-bundle and register the bundle (AppKernel::registerBundles() or config/bundles.php).
  2. The package is an aggregator. It wires together three things you must also configure independently: OneUpUploaderBundle (the AJAX upload endpoint, naming, storage, validation), LiipImagineBundle (server-side crop/thumbnail filters), and Blueimp jQuery File Upload + Jcrop assets shipped in the bundle's Resources/public.
  3. First place to look: the bundle README's config snippet and the exposed config tree in vendor/jbouzekri/file-uploader-bundle/DependencyInjection/. The exact key names have drifted across releases — trust the README pinned to your installed tag, not blog posts.
  4. First use case to build: avatar upload with crop. Upload goes to a OneUp temp endpoint via XHR, the response filename goes into a hidden form field, and on form submit you claim the temp file into permanent storage through a Liip crop filter.

Implementation Patterns

1. The upload-then-claim (two-phase) pattern. This is the whole architecture, and everything else is sugar. Phase one: XHR POST to the OneUp endpoint, file lands in a temp dir, JSON response returns the generated filename. Phase two: that filename is written into a hidden input, and on form POST you verify the file exists in your temp namespace, then move/copy it into permanent storage and persist the path on the entity. Never persist the temp path — persist the final one.

2. One mapping per image context. Configure a distinct mapping for avatar, cover, product_gallery, etc. Each mapping pairs an OneUp endpoint (own size limit, own MIME whitelist, own namer/storage) with a Liip filter set (own crop dimensions). This keeps validation tight per context instead of one giant "images" bucket with the loosest limits.

3. Crop as a server-side Liip filter, not client pixels. Let the JS crop UI post either a filter-set name or crop coordinates, and apply the crop through Liip Imagine in your controller/service. Trusting client-supplied x/y/w/h to be sane is how you get 10GB PNG decompression bombs; going through a named filter means the dimensions are fixed in config.

4. Form type + constraint, not raw request handling. Wrap the hidden field in a small custom form type (FileUploaderType) that carries the mapping name, and add a custom constraint (TempFileExists) that asserts the submitted filename matches your generated-name scheme and is still present in the temp dir. That constraint is your single security chokepoint — put all the path-traversal and ownership checks there.

5. Collection handling. For galleries, repeat the widget per collection entry but give each a unique DOM target/mapping name — Blueimp attaches to a container by selector, and two widgets with the same selector silently bind to the first one.

6. Lifecycle cleanup. The bundle does not clean up after you. Add a console command/cron to purge temp uploads older than N hours, and use Doctrine lifecycle callbacks (postRemove) to unlink the permanent files when an entity is deleted. Without this you accumulate orphans forever.

7. If you're actually on Laravel, reproduce this in an afternoon: pion/laravel-chunk-upload (or a hand-rolled UploadTempController) + intervention/image for the crop filter + cropperjs/filepond in the Blade view + storage/app/tmp as the claimable namespace. You get the same two-phase flow, no Symfony kernel, and dependencies that aren't from 2018.

Gotchas and Tips

  • Zero dependents, last release 2018-01-12, 23 stars. It targets PHP 7.x and Symfony 3.4/4.0. Symfony 5/6 broke a lot of what it assumes (bundle asset inheritance, Resources/public publishing, the templating bundle). Expect to fork and patch, not just composer update.
  • Asset publishing is the #1 abandonment reason. The old flow is bin/console assets:install --symlink; with Webpack Encore you must manually import the Blueimp/Jcrop JS out of vendor/.../Resources/public. Budget real time for this or you'll never see the crop UI.
  • Temp uploads are usually web-accessible. OneUp's default target sits under web/. Validate extension and MIME, randomize names (uniqid namer), and never trust the hidden field value without confirming the file exists in your temp dir and was created in this session.
  • No CSRF on the upload endpoint. The OneUp route is separate from your form, so the form token isn't present in the XHR. If you need CSRF, enforce it in a OneUp upload listener/event, not the form.
  • Liip cache doesn't invalidate on filter changes. After editing filter dimensions run liip:imagine:cache:remove, and resolve paths at runtime in Twig so you don't emit stale cached thumbnails.
  • OneUp misconfiguration fails late. A missing/wrong namer or storage service id blows up with a confusing 500 at upload time, not at container compile. Before touching JS, debug:router | grep upload and hit the endpoint with curl -F — if curl works, the problem is front-end.
  • Debugging order: curl the endpoint → check var/logs for the OneUp handler exception (the JS error message is useless) → only then look at the JS.
  • Extension points to prefer over patching: OneUp's oneup_uploader.post_upload event / UploadListener for claiming and validation, Liip Imagine custom filters for crop logic, and overriding the bundle's Twig widget template for markup. Overriding those three covers ~90% of customization needs without touching vendor code.
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.
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console