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

Entity File Bundle Laravel Package

2lenet/entity-file-bundle

EntityFileBundle lets Symfony entities attach and manage files through configurable FlySystem storage adapters, with simple save, retrieve, access, delete, rename, and move operations via a per-configuration manager.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit. Despite the framing in the brief, this is a Symfony bundle, not a Laravel package. It targets Doctrine ORM entities, Symfony bundle configuration (lle_entity_file.yaml), Symfony routing, and the Symfony security layer; storage is delegated to FlySystem via the FlySystem Symfony Bundle. The core abstraction is sound: one configuration maps exactly one entity class to exactly one storage adapter plus policy settings (role, disposition, entity_file_class), with a manager resolved through EntityFileLoader::get($configName). That gives clean multi-bucket semantics (seller logos vs. product photos) without custom code. Extensibility is reasonable: a custom EntityFileInterface implementation plus EntityFileTrait allows domain metadata, and paths are caller-supplied, enabling dynamic partitioning (Y-m/id.xml).

Integration feasibility. Low ceremony for an existing Symfony/Doctrine app: one Composer require, bundle registration, one YAML block, one entity class, one schema migration, and an optional route import. The bundle does not ship a first-class migration, so the entity_file table (and the indexes added in 1.2.4) must be generated and owned by the consuming application. UI value is gated on 2LE's Crudit bundle (EntityFileBrick); without Crudit, you get service-layer file handling and two controller routes but build your own front end. For Laravel/Eloquent stacks this is effectively a non-starter — no service provider, no config/filesystems.php support, no Eloquent events, and no Doctrine unless you have deliberately adopted doctrine/orm in Laravel.

Technical risk.

  • Adoption risk (high). 3 stars, 0 dependents, and no visible external consumers means no field validation, no third-party bug reports, and no ecosystem of answers. Effectively an internal 2LE component published to Packagist.
  • Vendor concentration (high). Maintenance is one agency with a handful of named contributors. Symfony 7/8 compatibility and PHPStan level 8 fixes show active stewardship, but there is no LTS or deprecation policy.
  • Security model granularity (high). Route access is gated by a single configured role for the whole configuration. Any user holding that role can read any file under that config by iterating IDs or guessing paths; PUBLIC_ACCESS disables gating entirely. Fine-grained ownership requires a custom Symfony voter — which the README acknowledges but does not demonstrate.
  • Path handling (medium). The readbypath route accepts an arbitrary path query parameter; safety depends on FlySystem's path normalization and the bundle's own guarding. Needs explicit traversal testing before exposure.
  • Consistency (medium). save() writes the file and returns an entity the caller must persist/flush; delete() removes both entity and file; move() requires a manual flush. Failure between storage write and DB commit produces orphans or dangling rows, and there is no transactional or compensating mechanism.
  • Missing capabilities (medium). No validation (MIME, size, dimensions), no image processing or thumbnails, no virus scanning, no async/queue path, no signed URLs or CDN offload, no range/streaming semantics beyond readStream(), no audit trail.
  • Data quality flag. The stated last release of 2026-09-09 is in the future; confirm actual tags and CHANGELOG against the repository before citing currency.
  • Score context. A composite of 22/100 with opportunity 36 is consistent with "usable but unproven" — not a signal of technical deficiency, but of thin evidence.

Key questions.

  1. What are the exact composer.json constraints for Symfony, PHP, Doctrine DBAL, FlySystem, and Crudit? FlySystem v1 → v3 is a breaking API shift.
  2. Is there a test suite and CI, and does it cover the controller routes, voter integration, and storage failures?
  3. What is the migration story for the entity_file table, and are schema changes treated as semver-major?
  4. Does the bundle perform any authorization beyond the config-level role? Can a voter be injected per request without forking?
  5. Is the path parameter validated against traversal, and how are storage exceptions translated to HTTP responses?
  6. What is 2LE's support commitment, and is there an internal owner willing to fork under MIT if maintenance lapses?

Integration Approach

Stack fit. Adopt only where the stack is Symfony 6.4/7/8 with Doctrine ORM and FlySystemBundle already (or acceptably) in place. If the platform is Laravel/Eloquent, stop here and evaluate spatie/laravel-medialibrary; the cost of introducing Doctrine purely to use this bundle is not justified by its scope. If the platform is Symfony but uses a bespoke upload layer, the bundle replaces that layer rather than complementing it — plan for removal, not coexistence.

Migration path. Run a bounded spike on one non-critical entity (e.g., seller logos) before committing:

  1. Register the bundle and create a dedicated FlySystem storage (flysystem.yaml) pointing at a non-production directory; do not rely on the default data/<config> path for anything persistent.
  2. Generate and review the Doctrine migration for entity_file, including the 1.2.4 indexes; hand-tune column types and add FKs matching house conventions.
  3. Subclass the entity with EntityFileTrait and add domain fields (uploader, checksum, original name, retention) at creation time — retrofitting metadata later is a data migration.
  4. Implement a custom voter keyed on entity ownership/tenant and wire it in place of the config-level role; test PUBLIC_ACCESS is unreachable for private configs.
  5. Import routes only if the built-in controller meets your auth and cache-header requirements; otherwise keep the service layer and write thin controllers that use readStream().
  6. Backfill existing files with a one-off script that writes to storage first, then inserts rows, then verifies checksums; run dual-write with the legacy path for one release.

Compatibility. Pin exact versions and verify against the target Symfony minor before merging. Crudit must move in lockstep if the brick is used — a Crudit upgrade can break the admin UI independently of this bundle. FlySystem adapter configuration lives in the FlySystem bundle, so storage credentials and visibility rules are owned outside this package; document that boundary explicitly.

Sequencing. Spike and security design first (weeks 1–2), schema and backfill second (week 3), route/UI cutover third (week 4), legacy decommission last with a rollback window. Gate each stage on a contract test suite you write yourself — assume none is provided.

Operational Impact

Maintenance. Treat this as a vendored dependency, not a community library. Pin to a minor version, mirror the repository internally, and budget roughly 10–15% of one engineer's time per year for Symfony major-version bumps and security patches. MIT licensing makes forking viable; decide the fork trigger in advance (e.g., no release within 90 days of a Symfony major). Watch two upgrade surfaces: Symfony framework majors and FlySystem majors.

Support. No SLA, no commercial backing, no dependents to consult. Issue response is best-effort via GitHub. Escalation is the agency relationship, not a support contract. Internal runbooks must cover storage adapter failures, permission misconfiguration, and orphan-file cleanup, because none of that is documented.

Scaling. Metadata grows linearly with files in the application database — acceptable, but keep the table lean and rely on the added indexes for lookups by config and entity. The real ceiling is delivery: file bytes are streamed through PHP via the bundle's controller, consuming application workers and bandwidth with no CDN, cache headers, or signed-URL offload. At meaningful volume, front the storage with Nginx X-Accel-Redirect or presigned object-storage URLs and bypass the controller. Local-disk storage is unsuitable for multi-node or containerized deployments; object storage must be chosen up front if horizontal scaling is on the roadmap. No queue integration means large uploads sit inside the request cycle.

Failure modes. (1) Non-atomic write-then-flush — storage succeeds, DB fails, orphaned files accumulate; add a reconciliation job. (2) delete() removes the physical file, so a failed flush leaves a row pointing at nothing — decide ordering deliberately and log both sides. (3) move() silently diverges if the caller forgets flush(). (4) Over-broad role values or an accidental PUBLIC_ACCESS expose private documents; enforce via config linting in CI. (5) read() on a large file loads it fully into memory — prefer readStream(). (6) Storage adapter misconfiguration surfaces as FlySystem exceptions rather than user-facing errors; wrap at the boundary.

Ramp-up. A Symfony developer can ship a basic attachment flow in a day from the README; the undocumented parts — schema ownership, the security model, failure semantics, and Crudit integration — take closer to a week. Write an internal one-pager covering storage config location, voter behavior, and the persist/flush contract, and require tests on upload, delete, and unauthorized access as part of onboarding. Do not assume the README's brevity reflects simplicity; it reflects missing detail.

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.
xiloryx/log-collector
a21ns1g4ts/filament-stripe
la-php/laravel-admin
artisan-build/community-prompts
vleroy/smart
ayles-software/laravel-australian-public-holidays
cboxdk/laravel-id-spatie
cboxdk/laravel-id-billing
cboxdk/laravel-id-billing-bridge
simple-as-fuck/php-performance-log
hsluv/hsluv
seampact/codegen
seampact/hooks
seampact/ir
mehedimi/laravel-amp-mail
happones/laravel-vue-i18n-generator
jwerd/inertia-table
siberfx/flysystem-wasabi
hollyit/token-replace
ippanelcom/laravel-sdk