Because there are many breaking changes an upgrade is not that easy. There are many edge cases this guide does not cover. We accept PRs to improve this guide.
Upgrading from v9 to v10 is straightforward. The biggest change is that we dropped support for PHP 7, and are using PHP 8 features.
- add a
json
columngenerated_conversions
to themedia
table (take a look at the default migration for the exact definition). You should copy the values you now have in thegenerated_conversions
key of thecustom_properties
column togenerated_conversions
- You can create this migration by running
php artisan make:migration AddGeneratedConversionsToMediaTable
. - Here is the content that should be in the migration file
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;
use Spatie\MediaLibrary\MediaCollections\Models\Media;
class AddGeneratedConversionsToMediaTable extends Migration {
/**
* Run the migrations.
*
* @return void
*/
public function up() {
if ( ! Schema::hasColumn( 'media', 'generated_conversions' ) ) {
Schema::table( 'media', function ( Blueprint $table ) {
$table->json( 'generated_conversions' )->nullable();
} );
}
Media::query()
->where(function ($query) {
$query->whereNull('generated_conversions')
->orWhere('generated_conversions', '')
->orWhereRaw("JSON_TYPE(generated_conversions) = 'NULL'");
})
->whereRaw("JSON_LENGTH(custom_properties) > 0")
->update([
'generated_conversions' => DB::raw("JSON_EXTRACT(custom_properties, '$.generated_conversions')"),
// OPTIONAL: Remove the generated conversions from the custom_properties field as well:
// 'custom_properties' => DB::raw("JSON_REMOVE(custom_properties, '$.generated_conversions')")
]);
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down() {
/* Restore the 'generated_conversions' field in the 'custom_properties' column if you removed them in this migration
Media::query()
->whereRaw("JSON_TYPE(generated_conversions) != 'NULL'")
->update([
'custom_properties' => DB::raw("JSON_SET(custom_properties, '$.generated_conversions', generated_conversions)")
]);
*/
Schema::table( 'media', function ( Blueprint $table ) {
$table->dropColumn( 'generated_conversions' );
} );
}
}
- rename
conversion_file_namer
key in themedia-library
config tofile_namer
. This will support both the conversions and responsive images from now on. More info in our docs. - You will also need to change the value of this configuration key as the previous class was removed, the new default value is
Spatie\MediaLibrary\Support\FileNamer\DefaultFileNamer::class
- in several releases of v8 config options were added. We recommend going over your config file in
config/media-library.php
and add any options that are present in the default config file that ships with this package.
-
internally the media library has been restructured and nearly all namespaces have changed. Class names remained the same. In your application code hunt to any usages of classes that start with
Spatie\MediaLibrary
. Take a look in the source code of medialibrary what the new namespace of the class is and use that. -
rename
config/medialibrary.php
toconfig/media-library.php
-
update in
config/media-library.php
themedia_model
toSpatie\MediaLibrary\MediaCollections\Models\Media::class
-
all medialibrary commands have been renamed from
medialibrary:xxx
tomedia-library:xxx
. Make sure to update all media library commands in your console kernel. -
the
Spatie\MediaLibrary\HasMedia\HasMediaTrait
has been renamed toSpatie\MediaLibrary\InteractsWithMedia
. Make sure to update this in all models that use media. Also make sure that they implement theHasMedia
interface, see Preparing your model. -
Add a
conversions_disk
field to themedia
table ( varchar 255 nullable; you'll find the definition in the migrations file of the package) and for each row copy the value ofdisk
toconversions_disk
. -
Add a
uuid
field to themedia
table ( char 36 nullable) and fill each row with a unique value, preferably auuid
You can use this snippet (in e.g. tinker) to fill the uuid
field:
use Spatie\MediaLibrary\MediaCollections\Models\Media;
Media::cursor()->each(
fn (Media $media) => $media->update(['uuid' => Str::uuid()])
);
- Url generation has been vastly simplified. You should set the
url_generator
in themedia-library
config file toSpatie\MediaLibrary\Support\UrlGenerator\DefaultUrlGenerator::class
. It will be able to handle most disks. - remove the
s3.domain
key from themedia-library
config file - spatie/pdf-to-image is now a suggestion dependency. Make sure to install it, if you want to create thumbnails for PDFs or SVGs
registerMediaConversions
andregisterMediaCollections
should now use thevoid
return type.- if the
path_generator
key in themedia-library
config file was set tonull
, change the value toSpatie\MediaLibrary\Support\PathGenerator\DefaultPathGenerator::class
- if the
url_generator
key in themedia-library
config file was set tonull
, change the value toSpatie\MediaLibrary\Support\UrlGenerator\DefaultUrlGenerator::class
- the
rawUrlEncodeFilename
method onBaseUrlGenerator
has been removed. Remove all calls in your own code to this method. getConversionFile
onConversion
now accepts aMedia
instance instead of astring
. In normal circumstance you wouldn't have used this function directly.- the default collection name for responsive images was changed from
medialibrary_original
tomedia_library_original
which requires you to update theresponsive_images
column and rename all generated files with that collection name. This is an example migration of how to do that (read through the code and make sure it does what you want):
use Illuminate\Contracts\Filesystem\Factory;
use Illuminate\Database\Migrations\Migration;
use App\Models\Media;
use Spatie\MediaLibrary\Support\PathGenerator\PathGeneratorFactory;
class RenameResponsiveImagesCollectionNameInMedia extends Migration
{
const OLD_COLLECTION_NAME = 'medialibrary_original';
const NEW_COLLECTION_NAME = 'media_library_original';
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
$this->change(self::OLD_COLLECTION_NAME, self::NEW_COLLECTION_NAME);
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
$this->change(self::NEW_COLLECTION_NAME, self::OLD_COLLECTION_NAME);
}
public function change(string $from, string $to)
{
/** @var Factory $filesystem */
$filesystem = app(Factory::class);
$pathGenerator = PathGeneratorFactory::create();
// Find media with the old collection name is present
Media::query()
->withoutGlobalScopes()
->whereNotNull('responsive_images->' . $from)
->cursor()
->each(function($media) use ($from, $to, $filesystem, $pathGenerator) {
// Change the old collection key
$responsive_images = array_merge(
$media->responsive_images,
[
$to => $media->responsive_images[$from],
$from => null
]
);
// Remove it completely
unset($responsive_images[$from]);
// Responsive image path for this media
$directory = $pathGenerator->getPathForResponsiveImages($media);
// Media disk
$disk = $filesystem->disk($media->disk);
foreach($responsive_images[$to]['urls'] as &$filename) {
// Replace the old collection name with the new one
$newFilename = str_replace(
$from,
$to,
$filename
);
// If the old file exists move it on disk
if($disk->exists($directory . $filename)) {
$disk->move($directory . $filename, $directory . $newFilename);
// Update the new array by ref
$filename = $newFilename;
}
}
// Save the new array
$media->responsive_images = $responsive_images;
$media->save();
});
}
}
- Before
hasGeneratedConversion
will work, the custom properties of every media item will have to be re-written in the database, or all conversions must be regenerated. This won't break any existing code, but in order to use the new feature, you will need to do a manual update of your media items.
- The
Filesystem
interface is removed, and theDefaultFilesystem
implementation is renamed toFilesystem
. If you want your own filesystem implementation, you should extend theFilesystem
class. - The method
Filesytem::renameFile(Media $media, string $oldFileName)
was renamed toFilesystem::syncFileNames(Media $media)
. If you're using your own implementation ofFilesystem
, please update the method signature. - The
default_filesystem
config key has been changed todisk_name
. - The
custom_url_generator_class
andcustom_path_generator_class
config keys have been changed tourl_generator
andpath_generator
. (commit ba46d8008d26542c9a5ef0e39f779de801cd4f8f)
- add the
responsive_images
column in the media table:$table->json('responsive_images');
- rename the
use Spatie\MediaLibrary\HasMedia\Interfaces\HasMedia;
interface touse Spatie\MediaLibrary\HasMedia\HasMedia;
- rename the
use Spatie\MediaLibrary\HasMedia\Interfaces\HasMediaConversions;
interface touse Spatie\MediaLibrary\HasMedia\HasMedia;
as well (the distinction was removed). - all converted files should now start with the name of the original file. One way to achieve this is to navigate to your storage/media folder and run
find -type d -name "conversions" -exec rm -rf {} \;
(bash) to remove all existing converted files and then runphp artisan medialibrary:regenerate
to automatically recreate them with the proper file names. Spatie\MediaLibrary\Media
has been moved toSpatie\MediaLibrary\Models\Media
. Update the namespace import ofMedia
accross your app- The method definitions of
Spatie\MediaLibrary\Filesystem\Filesystem::add
andSpatie\MediaLibrary\Filesystem\Filesystem::copyToMediaLibrary
are changed, they now use nullable string typehints for$targetFileName
and$type
.
- the signature of
registerMediaConversions
has been changed.
Change every instance of
public function registerMediaConversions()
to
public function registerMediaConversions(Media $media = null)
- change the
defaultFilesystem
key in the config file todefault_filesystem
- add the
image_optimizers
key from the default config file to your config file. - be aware that the media library will now optimize all conversions by default. If you do not want this tack on
nonOptimized
to all your media conversions. toMediaLibrary
has been removed. UsetoMediaCollection
instead.toMediaLibraryOnCloudDisk
has been removed. UsetoMediaCollectionOnCloudDisk
instead.
- rename
config/laravel-medialibrary
toconfig/medialibrary.php
. Some keys have been added or renamed. Please compare your config file againt the one provided by this package - all calls to
toCollection
andtoCollectionOnDisk
andtoMediaLibraryOnDisk
should be renamed totoMediaLibrary
- media conversions are now handled by
spatie/image
. Convert all manipulations on your conversion to manipulations supported byspatie/image
. - add a
mime_type
column to themedia
table, manually populate the column with the right values. - calls to
getNestedCustomProperty
,setNestedCustomProperty
,forgetNestedCustomProperty
andhasNestedCustomProperty
should be replaced by their non-nested counterparts. - All exceptions have been renamed. If you were catching media library specific exception please look up the new name in /src/Exceptions.
- be aware
getMedia
and related functions now return only the media from thedefault
collection image_generators
have now been added to the config file.
- All exceptions have been renamed. If you were catching media library specific exception please look up the new name in /src/Exceptions.
- Glide has been upgraded from 0.3 in 1.0. Glide renamed some operations in their 1.0 release, most notably the
crop
andfit
ones. If you were using those in your conversions refer the Glide documentation how they should be changed.
You can upgrade from v2 to v3 by performing these renames in your model that has media.
Spatie\MediaLibrary\HasMediaTrait
has been renamed toSpatie\MediaLibrary\HasMedia\HasMediaTrait
.Spatie\MediaLibrary\HasMedia
has been renamed toSpatie\MediaLibrary\HasMedia\Interfaces\HasMediaConversions
Spatie\MediaLibrary\HasMediaWithoutConversions
has been renamed toSpatie\MediaLibrary\HasMedia\Interfaces\HasMedia
In the config file you should rename the filesystem
-option to default_filesystem
.
In the db the temp
-column must be removed. Add these columns:
- disk (varchar, 255)
- custom_properties (text) You should set the value of disk column in all rows to the name the default_filesystem specified in the config file.
Note that this behaviour has changed:
- when calling
getMedia()
without providing a collection name all media will be returned (whereas previously only media from the default collection would be returned) - calling
hasMedia()
without a collection name returns true if any given collection contains files (wheres previously it would only return try if files were present in the default collection) - the
addMedia
-function has been replaced by a fluent interface.
Because v2 is a complete rewrite a simple upgrade path is not available. If you want to upgrade completely remove the v1 package and follow install instructions of v2.