- How do I install and set up plank/laravel-mediable in a Laravel app?
- Install it with composer require plank/laravel-mediable. On Laravel 5.5 and newer the service provider and MediaUploader facade are auto-discovered, so you can skip manual registration in config/app.php. Publish the config with vendor:publish and run php artisan migrate; since 5.0 the migrations are loaded from the package rather than copied into database/migrations. That is the entire setup, and a proof-of-concept spike is roughly a day of work.
- Which Laravel and PHP versions does laravel-mediable support?
- The 6.x line requires PHP 8.1 or newer and supports Laravel 10 and 11, having dropped PHP 7.4/8.0 and Laravel 8/9. The project follows a hard drop policy, so older package majors target older Laravel majors: 4.4 dropped Laravel below 6, 5.4 dropped 6/7, and 6.0 dropped 8/9. Budget for a coupled major-version package upgrade every time you move Laravel majors.
- How do I attach an uploaded file to an Eloquent model with laravel-mediable?
- Upload with MediaUploader::fromSource($request->file('thumb'))->toDestination('uploads', 'blog/thumbnails')->upload(), which creates a Media record. Then call $post->attachMedia($media, ['thumbnail']) on any model that uses the Mediable trait. No schema changes are needed on your domain models because the link is a polymorphic many-to-many through the package's mediables pivot table. Retrieve it later with $post->getMedia('thumbnail')->first()->getUrl().
- Can multiple models share the same media file?
- Yes. Media connect to models through a many-to-many polymorphic relationship, so one Media row can be attached to any number of records without touching their schemas. Because the tag lives on the pivot column, the same file can be attached to different models under different tags, such as 'thumbnail' on a post and 'download' on a product. Detaching from one model does not affect the file itself or its other attachments.
- How do tags work for organizing media in laravel-mediable?
- Tags are strings stored on the mediables pivot and are how you set and retrieve media for specific purposes such as 'thumbnail', 'featured image', 'gallery', or 'download'. Attach with $model->attachMedia($media, ['gallery']) and read back with $model->getMedia('gallery'), which returns a collection. Because tags are part of the relationship rather than your domain schema, a single model can hold several distinct media sets without extra columns. They are also useful when detaching or replacing a specific slot.
- How do I generate thumbnails or image variants with laravel-mediable?
- Image variants such as thumbnails and responsive sizes are optional and require intervention/image; the 6.0 line supports intervention/image 3.x via intervention/image-laravel. Variant generation is expressed as queued jobs, so your queue workers sit on the feature's critical path and generation is asynchronous. If your admin UX needs synchronous thumbnails you will have to build that yourself. 6.0 also adds image-manipulation-on-upload behavior and an alt attribute column, so pin the minor and read UPGRADING.md before upgrading.
- How do I restrict uploads by file type or extension?
- Uploads can be restricted by MIME type, extension, and/or aggregate type, where a type like 'image' covers JPEG, PNG, and GIF. These restrictions are part of the filesystem-driven configuration, so you define allowed types per destination or disk rather than validating ad hoc in controllers. Rejected uploads fail validation instead of being stored, which keeps your media table consistent with policy. Treat this configuration as your primary upload policy surface and set it deliberately.
- Can I use multiple disks, S3, or tenant-isolated storage with laravel-mediable?
- The package is filesystem-driven on Laravel's Flysystem disks, configured in config/filesystems.php, and supports any number of upload directories with different accessibility. For private storage such as S3 you serve files through temporary or signed URLs, and the changelog shows ongoing fixes to S3 temp URL handling. Private disks mean URLs are generated per request, which affects CDN caching and cost. Multi-tenant isolation may require a custom Media subclass and table, a path the package supports but one that has historically been bug-prone, so validate it in a spike first.
- What happens to files when a model is deleted or an upload fails?
- The package cannot make filesystem and database writes atomic. An upload that lands on disk but fails to persist a Media row leaves an orphan file, and deleting a model does not delete its files unless you explicitly do so. Orphans are the primary long-term cost driver in this design, so plan cleanup from day one via observers or a scheduled pruning job. Because media can be shared across models, you also cannot naively delete a file whenever it is detached.
- Is plank/laravel-mediable actively maintained, and what is the bus factor?
- It is maintained by a single agency, Plank Design, with around 828 GitHub stars, effectively no dependents signal on Packagist, and no commercial support tier. The changelog shows genuine engineering rigor, including PHPStan in CI, streaming source adapters, migration-squashing fixes, and S3 temp URL fixes, but there is no bus factor, so assume you may need to fork and patch. Re-verify the release metadata as well: reported metadata has shown a last release date inconsistent with version 6.0.3, so confirm the current release against Packagist before committing internally.