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.
What changed in v4.2 — and what did not. The release note is one line: "Bump gaufrette version." That is a dependency bump, not a feature, not a deprecation, and not a breaking-change notice. It does not alter the core finding: this remains a Symfony bundle with no bundle/extension equivalent in Laravel, and no composer require-and-go path into a Laravel application. The server-side code is still structurally unusable without a rewrite; only the frontend pattern and crop contract are portable.
Two claims in the prior assessment now need correction, and both cut in the package's favour — modestly.
New anomaly that must be resolved before any further work. A v4.2 tag is difficult to reconcile with a bundle whose last known release was January 2018 and whose constraints were Symfony 2.7/3.0-era. Either (a) the version line is not what the prior assessment assumed, (b) a fork or new maintainer has taken over the tag stream, or (c) the release cadence was always higher than observed and the "2018" data point was stale. Any of these materially changes the dependency-resolution question below. This is now the first thing to check, ahead of everything else.
Technical risk — still high, with one delta.
Key questions — revised, reordered:
composer.json before and after, and confirm the tree still resolves under PHP 8.2+ and Symfony 6/7. A resolution failure remains the expected outcome and the clean kill signal.Stack fit — unchanged. If the target is Laravel, do not add this to composer.json. The value proposition is still "a UX pattern for upload-with-crop," roughly two days of native work and far cheaper to own.
Recommended target-state implementation (Laravel) — unchanged:
POST /uploads, Form Request validating mimetypes:image/jpeg,image/png,image/webp and max:10240, write via Storage::disk('s3')->putFile() with a ULID filename. Never trust the client extension.{x, y, width, height} against the stored original; apply with intervention/image in a queued job. Store the crop rect in a JSON column rather than overwriting the original, so re-crop is non-destructive.Migration path if the stack is genuinely Symfony and legacy — unchanged in shape, with a note. Pin to Symfony 3.4 / PHP 7.4, feature-flag the bundle, isolate it behind a dedicated firewall with its own upload storage root, containerize the runtime. Vendor the code and take ownership of the dependency tree. Addition: the Gaufrette bump gives us a slightly better starting position on storage — configure the S3 adapter through the abstraction rather than local disk from day one, so the eventual exit does not include a storage migration as well as a code migration.
Compatibility — still assumed hostile, and now with an extra unknown. The gaufrette bump changes the tree; re-run composer why-not against real app constraints. Budget an hour rather than thirty minutes now, and read the actual diff rather than the release note.
Sequencing (two-week box, revised front end):
composer.json diff audit — which Gaufrette, what came with it, who tagged v4.2. Plus dependency-resolution spike and CV scan. Go/no-go gate.Maintenance — dominant cost, still lands on us, with a marginal reduction. A single dependency bump does not create a maintenance relationship. Any CVE in the chain is ours to patch or mitigate. The upside of v4.2 is narrow but real: it suggests the repo is not entirely unowned, which slightly improves the odds of a future compatibility patch landing without our intervention. Do not plan against that. In the Laravel-native path, maintenance remains routine: two well-maintained libraries and ~300 lines of first-party code.
Support. Still none in any contractual sense. No issue-backlog guarantees, no documentation beyond the README, no community to ask. One release is not a support channel. The cost of debugging from source is unchanged.
Scaling — unchanged. Bundle-era upload flows are synchronous: the request holds the connection through upload, validation, and transform. Under concurrency, PHP-FPM workers saturate and GD/Imagick memory spikes dominate — a single 20MP crop can consume hundreds of MB. The native approach fixes this structurally with direct-to-S3 presigned uploads and queued transforms on a memory-sized worker pool. If we adopt the bundle, put a queue in front of it from day one.
Failure modes to design against — one downgraded:
Ramp-up — unchanged. Deceptively steep. Small but undocumented and opaque; crop config and asset inclusion discoverable only by reading source. 2–3 days for a mid-level engineer to modify it safely, plus a recurring onboarding tax for a framework-adjacent pattern nobody will meet again. The native replacement reads as ordinary Laravel and takes hours.
Recommendation — do not adopt; keep the door ajar but not open. v4.2 is a one-line dependency bump and does not change the decision. It does change the reasoning in two places worth recording: the abandonment claim should be stated as "no demonstrated security or compatibility maintenance since 2018, with one hygiene release," and the storage lock-in concern should be retired in favour of a controller-level verification. Net position: the architecture mismatch for Laravel is still decisive on its own, and the 0.325 score still reads correctly for a package with no dependents and no support commitment in a security-sensitive code path. The 3.36 opportunity score still means "the problem is worth solving," not "this solves it." Budget two engineer-weeks for a native build and treat the repository as a design reference.
Re-evaluation trigger: if a second substantive release lands within two quarters — particularly one citing PHP 8.2+ or Symfony 6/7 compatibility — revisit. A pattern of releases is signal; a single bump is noise.
How can I help you explore Laravel packages today?