$ show dustin10/VichUploaderBundle
VichUploaderBundle is a mature Symfony bundle that automates file upload management for Doctrine entities. It listens to Doctrine lifecycle events to inject uploaded files into entities on load, upload them on persist, clean up replaced files on update, and remove files when entities are deleted. The bundle supports ORM, MongoDB ODM, and PHPCR ODM through adapter classes, and provides pluggable storage backends for local filesystem, Flysystem, and Gaufrette (legacy). Configured via attributes, YAML, XML, or a shared PHP mapping configuration, it exposes services for naming, directory organization, metadata reading, and property mapping resolution, plus console commands for debugging mappings and cleaning orphaned files. The architecture is a classic extensible library: a bundle facade registers compiler passes, a dependency injection extension wires services from configuration, and interfaces such as StorageInterface, NamerInterface, DirectoryNamerInterface, and MetadataReaderInterface define seams for customization. Core orchestration lives in UploadHandler and DownloadHandler, while PropertyMappingFactory resolves entity fields to storage and naming strategies. The bundle also ships Twig helpers for rendering asset URLs and form types (VichFileType, VichImageType) with delete/download options, a profiler data collector, a FileRequired validator, and translations in 20+ locales. The codebase is well-tested with unit, integration, and functional tests, and shows deliberate design in areas like immutable namer configuration, a chain directory namer, event cancellation, and clever file-extension guessing. It is actively maintained, follows modern PHP (^8.3) and Symfony (^6.4/^7.4/^8.0), and has clear deprecation paths for legacy features. A few areas such as Gaufrette storage and the older ConfigurableInterface are in maintenance mode, but the core remains current and trustworthy.
The LLM identified 5 files worth highlighting for reuse:
Provides a copy-on-write configuration mechanism for custom namers and directory namers. Each configured instance receives options immutably, returning a new instance rather than mutating shared state. This prevents option leakage between different entity mappings and is a clean, isolated pattern usable in any configurable strategy system.
Implements smart file extension guessing that preserves meaningful extensions like .csv even when a MIME guesser would return a generic extension such as .txt. It is self-contained, easy to extract, and solves a recurring problem in upload pipelines and filename generation.
Defines a shared template-method skeleton for storage backends, centralizing the upload/remove/resolve lifecycle while delegating filesystem-specific operations to concrete implementations. The abstraction keeps storage concerns orthogonal to Doctrine mappings and is a strong pattern for building multi-backend persistence layers.
A self-contained utility that transliterates and sanitizes filenames, replacing non-ASCII characters and reducing strings to safe filesystem identifiers. It has no external coupling, making it directly portable to any PHP project needing deterministic, filesystem-safe filename generation.
A console command that scans mapped entity files against real storage and deletes orphaned files, supporting dry-run previews, batch size limits, and an age threshold. It demonstrates a safe, operationally useful cleanup pattern that can be adapted to any file-storing application.