stormcelltech/mediauploader
Stormcelltech MediaUploader is a Laravel/PHP package for simplifying media and file uploads. It provides helpers to handle, store, and manage uploaded files, streamlining upload workflows and keeping media storage organized in your application.
v1.0.2 is a patch release on the v1.0.x line — no breaking changes are implied by the version bump, so if you were already on v1.0.1 you can run composer update stormcelltech/mediauploader and keep your existing flow. New adopters start here:
composer require stormcelltech/mediauploader
php artisan vendor:publish --tag=mediauploader-config
php artisan vendor:publish --tag=mediauploader-migrations
php artisan migrate
Tags are the usual convention; if a tag is missing, run vendor:publish without a tag and pick the provider's items from the list.FILESYSTEM_DISK in .env (or the package's disk key in config/mediauploader.php) to the disk you actually want media on. For public URLs from a local disk, run php artisan storage:link.User, Post) so $model->media() / attach helpers become available.Where to look first: the published config file (disk, path, size limits, conversion settings), then the package's trait/contract to see what relationships and methods it registers on your models.
Upload through a service, not the controller. Keep controllers thin: validate in a FormRequest, then call the package's upload/store API (or a small MediaService wrapper around it). This keeps the upload path reusable from jobs, commands, and API endpoints.
Attach-then-convert. The reliable order is: store the original file, create the media record, associate it with the model, then dispatch conversions/thumbnails. Persisting the record first means a failed conversion leaves a usable original rather than an orphaned file with no row.
Queue the expensive work. Image resizing/thumbnailing should run in a queued job (ShouldQueue) so the HTTP request returns fast. Make conversions idempotent — regenerating a thumbnail should overwrite, not duplicate.
Replace semantics, not accumulate. For single-file fields (avatar, logo), explicitly delete or detach the previous media before attaching the new one. For galleries, append and manage ordering separately. Decide this per field and encode it in the service layer, not ad hoc in each controller.
API responses. Wrap media in an API Resource so URLs, dimensions, and mime types have one canonical shape. Don't leak raw storage paths — return the disk's url() output.
Disk abstraction. Always go through Storage::disk($config['disk']) rather than public_path() or direct filesystem calls, so moving from public to s3 is a config change rather than a refactor.
Testing. Use Storage::fake('media') and UploadedFile::fake()->image(...) in feature tests; assert the file exists on the fake disk and the DB row is correct. This catches path and visibility bugs without touching real storage.
storage:link is not optional for public local disks. Missing symlink = 404s on every URL while the file exists on disk.upload_max_filesize and post_max_size in php.ini (and any nginx client_max_body_size) must exceed the package's configured max size, or you get silent empty $_FILES / 413s that look like package bugs.mimes/mimetypes rules rather than trusting client-supplied extensions; verify the stored file's detected type if you accept user uploads.php -m on the worker host too.config/mediauploader.php in a cached environment, run php artisan config:clear; stale config is the most common "my disk change didn't apply" cause.deleting hook or a scheduled cleanup command that reconciles DB rows against disk contents..env between web and worker is a classic silent failure.v1.0.1...v1.0.2 for any behavioral fixes (path normalization, mime detection, queue handling) that might change output for existing files before rolling to production.How can I help you explore Laravel packages today?