This is a security release, upgrading is strongly recommended
mediable.allowed_remote_hosts configuration which allows restricting remote URL source adapters to a whitelist. Wildcard subdomains may be specified with *.example.com syntax. By default, all hosts are allowed.mediable.allowed_remote_hosts allow list is provided, the RemoteUrlAdapter will reject private IP addresses and localhost by default, to prevent Server-Side Request Forgery (SSRF) attacks. [CVE-2026-49969]mediable.allowed_remote_schemes configuration which allows restricting remote URL source adapters to a whitelist of allowed URL schemes (e.g. http, https, ftp, etc.). By default, only https is allowed. When modifying this configuration, it may also be necessary to modify the source_adapters pattern matching.. characters from path segments. This prevents attackers from using directory traversal patterns like ../ as well as preventing potential issues with certain filesystems where . characters in directory names may cause unexpected behaviour. [CVE-2026-49970]mediable.file_sanitizers configuration which allows specifying custom sanitizers for rewriting file contents to strip out security risks before they are uploaded. A sanitizer must implements the Plank\Mediable\Sanitizers\SanitizerInterface interface.SvgSanitizer which will strip executable javascript and other untrusted content from image/svg+xml files, which can result in stored XSS if rendered directly to a webpage. By default, this sanitizer is applied to all uploaded SVG files. It can be disabled by removing it from the mediable.sanitizers config array. [CVE-2026-49971]mediable.forbidden_file_extensions configuration and MediaUploader::setForbiddenExtensions() which allows specifying a blacklist of file extensions that are forbidden to be uploaded. Any file extension which is considered executable by your Apache or Nginx configuration should be included in this list. A number of common executable file extensions are included in this list by default to prevent remote code execution exploits.script.php.jpg becomes script-php.jpg). This prevents remote code execution from double extension bypass due to common Apache and Nginx misconfigurationsmediable.forbidden_mime_types configuration and MediaUploader::setForbiddenMimeTypes() which allows specifying a blacklist of MIME types that are forbidden to be uploaded.Plank\Mediable\Enum\OnDuplicateBehaviour enum.MediaUploaderConfiguration class. Most MediaUploader instance properties are moved to this class. The MediaUploader class now accepts this as a constructor argument instead of an array of configs.MediaUploader::beforeSave() now accepts a \Closure instead of a callable for better static analysis and type safety.intervention/image driver based on the available extensions.plank/laravel-mediable and intervention/image-laravel at the same timeintervention/image-laravel package to the composer suggests listMediableInterfacewithAltAttribute() method to set the alt attribute on the generated media record.MediaUploader::applyImageManipulation() to make changes to the original uploaded image during the upload process.MediaUploader::validateHash() to ensure that the hash of the uploaded file matches a particular value during upload. Supports any hashing algorithm supported by PHP's hash() function.MediaUploader::preferClientMimeType() to indicate that the MIME type provided by the source should be used instead, if provided. The default behaviour can be configured with the 'prefer_client_mime_type' key in the config/mediable.php file.MediaUploader::useHashForFilename() method now accepts an optional parameter to specify which hashing algorithm to use to generate the filename. Supports any hashing algorithm supported by PHP's hash() function.makePublic()/makePrivate() methods are not called, instead of assuming public visibility.data:image/jpeg;base64,....All SourceAdapter classes have been significantly refactored.
temp:// to avoid repeated HTTP requests.getStreamResource() method. The method has been replaced with the getStream(): StreamInterface, which returns a PSR-7 stream implementation instead.hash(string $algo): string method which is expected to return the hash of the file contents using the specified algorithm.filename() and extension() method is now nullable. If the adapter cannot determine the value from the information available, it should return null.getContents() method. The getStream()->getContents() method may be used instead.getSource() method. No replacement.path() method. No replacement.valid() method. SourceAdapters should now throw an exception with a more helpful message from the constructor if the source is not valid.jpegoptim, pngquant, optipng, gifsicle, etc.)config/mediable.php file to specify the optimization tools to use and their arguments.ImageManipulation::noOptimization() and ImageManipulation::optimize(?array $optimizers = null) methods to allow overriding the defaults set in the config file.ImageManipulation::useHashForFilename() method now accepts an optional parameter to specify which hashing algorithm to use to generate the filename. Supports any hashing algorithm supported by PHP's hash() function.ImageManipulation::usingHashForFilename() method has been renamed to ImageManipulation::isUsingHashForFilename() to avoid confusion with the useHashForFilename() method.alt attribute to the Media model.url attribute which will generate a URL for the file (equivalent to the getUrl() method).MediableCollection annotions to support generic types.\Plank\Mediable\Stream class in favor of the guzzlehttp/psr7 implementation. This removes the direct dependency on the psr/http-message library.\Plank\Mediable\HandlesMediaUploadExceptions::transformMediaUploadException() parameter and return type changed from \Exception to \Throwable.application/octet-stream (changed in recent version of Flysystem)MediaUploader::onDuplicateReplaceWithVariants() which behaves similar to onDuplicateReplace() but will also delete any variants of the replaced Media record.onDuplicateUpdate() failing if file exists but without a matching model.MediaUploader Facade returning the same instanceImageManipulator now uses $media->contents() instead of $media->stream(), as Intervention Image loads the whole file into memory anyways, and the former seems to have fewer hiccups for various cloud filesystems.CreateImageVariants job.attachMedia() and SyncMedia() (Thanks @hailwood!)MediableCollection::delete() methodMediableCollection::delete()MediableCollection::delete()., -, _, and / for directories). Will automatically attempt to transliterate UTF-8 accented characters and ligatures into their ASCII equivalent, all other characters will be converted to hyphens.Media::stream() method to easily retrieve a PSR-7 compatible Stream.league/flysystem to allow minor version bumpsMedia::moveToDisk() and Media::copyToDisk() now correctly transfer file visibility to the new disk.Media::moveToDisk() and Media::copyToDisk() methods.Media::$size property is now cast as int, fixing a TypeError. (Thanks @boumanb!)RemoteUrlAdapter, StreamAdapter, and StreamResourceAdapter potentially returning an incorrect filename and/or extension if the query params of the URL contains certain characters.getClientSize() method deprecated in Symphony 4.1 with getSize()MediaUploader::replace() and MediaUploader::import() methods as wellurl() methodMediaUrlException when the file does not have public visibility. This removes the need to read IO for files local disks or to make HTTP calls for files on s3 disks.LocalUrlGenerator::getPublicPath()'prefix' config of local disks. Value should be included in the 'url' config instead.getStreamResource to SourceAdapterInterface, uploader will now attempt to use a stream to reduce memory usage.delete() method to MediableCollection for mass deleting media records and files.MediaUploader::verifyFile() to apply validation to a source without uploading (Thanks @JulesPrimo)MediaUploader::beforeSave() to allow editing custom fields on Media records before they are saved (Thanks @JulesPrimo)MediaUploader::onDuplicateIncrement() behaviour adjusted to use hyphens instead of parenthesis (Thanks @ryankilf!)Media::copyTo() method (Thanks @johannesschobel!)Mediable::lastMedia() convenience method (Thanks @pet1330!)S3UrlGenerator now generates the url directly with S3 client, instead of with the FilesystemAdapter::url() method, which was only added in Laravel 5.2.15wherePivotIn() used in eager loading, which was only added in Laravel 5.3onDuplicateDelete action of the MediaUploader now manually deletes the Media record and the file on disk, instead of depending on the record existing to clean its own file.MediaUploader (Thanks @sebdesign)MediaUploader (Thanks @sebdesign)MediaUploader (Thanks @sebdesign)Mediable::getOrderValueForTags.Media::scopeForPathOnDisk not working when path does not contain a directory (Thanks @geidelguerra!).MediaUploader's OnDuplicateError behaviour (Thanks @geidelguerra!).attachMedia() or syncMedia() receiving the same order value.attachMedia() to optimize the number of executed queries.Mediable models now remember the order in which Media is attached to each tag.MediaUploader methods.MediaUploader on-duplicate behaviour. Thanks @jdhmtl.MediaUploader can now generate filenames using hash of file contents (Thanks @geidelguerra!).import() and update() methods to MediaUploader.Mediable relationship not connecting to custom Media subclass defined in config.Mediable::getTagsForMedia() now properly rehydrates media if necessary.Mediable::load() now looks for media that is either the $relationship key or value.Mediable, and MediaCollection.How can I help you explore Laravel packages today?