201created/media-bundle
A PHP media bundle from 201created intended for managing media assets in web applications. The README currently contains only placeholder text, so documented setup, configuration, and feature details are minimal; review the package source for actual usage.
First, verify the framework before you run composer require. Despite the assessment title, every artifact points to this being a Symfony bundle (201Created\MediaBundle, *Bundle naming, a model.xml touched in a patch release, and explicit "Support for PHP 8 and Symfony 6" release notes). There is no service provider, no vendor:publish, no Laravel package discovery. If your target is Laravel, treat this as "framework-agnostic PHP I will wrap myself" and budget for the bridge; if you expected a drop-in Laravel package, stop here and compare against spatie/laravel-medialibrary or a plain Flysystem wrapper first.
Minimal steps (Symfony path):
composer require 201created/media-bundle:2.1.0 (or whichever tag the spike validates). Do not use ^ constraints; there are zero dependents and no stated compatibility matrix, so you are the compatibility matrix.config/bundles.php (Symfony) or equivalent — this is the step a README would normally show you, and it does not exist. Read vendor/201created/media-bundle/src/ and the DependencyInjection/ folder to learn the bundle alias and config key before guessing.bin/console debug:config <alias> and bin/console debug:container --tag=<whatever the compiler pass tags> to discover the actual service IDs and configuration tree. This is your substitute for documentation.Where to look first. The README is literally the string test123 — it is not a source of truth. Go directly to:
src/ for the public API surface (the media entity/abstraction and the upload entry point)DependencyInjection/Configuration.php for the real config schemaResources/config/ (or config/) for service wiring, especially anything registering PostProcessorPoolmodel.xml — the presence of this in a patch changelog tells you the persistence/entity model is bundled and versioned here, so read it to understand the table shape before you write migrationsFirst use case. Attach a single image to one existing Doctrine entity and render it. That exercises the whole stack — storage write, metadata persistence, entity relation, and (if any processors are pre-registered by default) the post-processing pool. Keep it on an internal/admin surface so a hiccup during evaluation is recoverable.
Put a seam between your domain and the bundle. The single most useful day-to-day pattern given the undocumented state is to define your own narrow contract and implement it with bundle calls behind it:
interface MediaStore
{
public function attach(object $entity, UploadedFile $file): MediaRef;
public function url(MediaRef $ref, ?string $variant = null): string;
public function delete(MediaRef $ref): void;
}
Domain code depends on MediaStore, not on 201Created\MediaBundle\*. When the spike reveals the real API (or when you fork), you change one adapter class rather than every call site. This also makes the build-vs-buy decision reversible, which matters for a package with 3 stars and no dependents.
Attach via the entity relation, not raw IDs. The bundle's value proposition is "attach media to your Doctrine models." Model the relation on your entity (one-to-one for an avatar, one-to-many for a gallery) and let the bundle own the media record. Verify during the spike whether it creates its own table or writes polymorphically — that determines whether your migrations reference its table or extend it.
Treat PostProcessorPool as an extension point, not a default. The 1.5.2 patch touching PostProcessorPool.php is the one concrete signal about derived-asset generation (thumbnails, resized variants). The day-to-day pattern is: register your processors into the pool, keep each processor small and idempotent, and assume synchronous execution until proven otherwise. If it runs inline on upload, wrap the call in your own queued job so a slow resize doesn't tie up a PHP worker:
// Your job, not the bundle's
final class StoreMediaJob implements ShouldQueue
{
public function handle(MediaStore $store): void
{
$store->attach($this->entity, $this->file);
}
}
Because you control the seam, you can move the upload off the request path immediately and defer the question of whether the bundle's pool is queue-backed.
Storage configuration lives in config, swap adapters behind it. The stated purpose is a reusable media abstraction across backends. Configure local disk in dev/test and S3-compatible storage in staging early — the spike should prove both, because "swappable adapters" is the claim the whole adoption case rests on. If swapping requires code changes, that's a finding, not a footnote.
Strangler/feature-flag pattern for adoption. Route one non-critical upload surface (admin avatar, internal attachment) through the bundle behind a flag, keep the legacy handler warm, and run a full sprint before migrating the media table. Do not plan a phased "full migration" until that pilot has produced evidence — the prior planning artifacts assumed documentation and production validation that do not exist.
Test against a fake filesystem. Use an in-memory or temp-directory adapter in tests so integration tests don't hit S3, and assert on both the persisted media record and the storage write — post-processor failures can leave one without the other.
test123. Do not scope work from it, do not quote it in a design doc, and do not assume any documented public API. The source is the spec; budget a timeboxed source read (2–3 days) before committing to any roadmap item.Content-Disposition at your edge before exposing any upload endpoint to low-trust users. The model.xml/entity path handling in particular deserves a tenant-prefix review if you're multi-tenant.debug:container will show you the real service IDs and which compiler pass registers the pool; the profiler's Doctrine panel shows the media table writes. Because there's no docs, keep a running one-page internal API reference from the spike — it's the difference between a second engineer onboarding in an hour versus a day.How can I help you explore Laravel packages today?