Laravel-medialibrary: Feature wishlist for medialibrary v7

Created on 21 Nov 2017  ยท  66Comments  ยท  Source: spatie/laravel-medialibrary

We are currently buillding v7 of the medialibrary. We'll work on this:

  • add Vue components to help with uploading / administering media
  • add a controller to handle requests coming from those Vue components
  • add support for responsive images / srcset (see #810)
  • uploading stuff directly to S3
  • add support for Media Collections, so you can specify how many items and what kind of items are allow in a collection
  • general cleanup

Your ideas can help in us making medialibrary better. Feel free to add any feature requests to this issue.

Most helpful comment

Little idea: add the concept of a "single-file" collection that replaces the current media if there's already something uploaded for that model.

All 66 comments

Chunked uploading for large assets could be a useful feature

Ability to separate originals and conversions in different parent directories.

./public/storage/media-library/{modelType}/{modelId}/{mediaId}/{originalfilename}.jpg
./public/media/{mediaId}/conversion1.jpg
./public/media/{mediaId}/conversion2.jpg

Because usually it's better to backup originals only. It is possible now, but a bit tricky and needs a lot of additional code. Also adding modelType and modelId to directory structure of originals will make it much more easier to navigate, though they are usually not needed for conversions.

Being able to select a focal point for an image would be great for resizing. i.e. a user could get an image to resize around a point in the top left, instead of in the centre, if that was more appropriate.

  • A simplified way of generating a unique filename when adding a file.
  • Storing conversions in db , still not sure why manipulations are stored in the db and conversions aren't

Ability to create a private media collection. All media of this collections are served via Laravel and user can attach some authorization logic (i.e. who has the permission to access this file etc.). This is useful when working with files containing personal data (i.e. PDF scan of signed contract full of personal data).

@palypster you can already add extra info to a media object via custom properties. You can use those custom properties in your gate checks.

This might be pushing it but optional image cropping in the vue component would be amazing.

Afaik, there is no easy way to name a file on a disk atm. I think it would be useful for SEO to being able to name files... i.e.: /media/1/users-freekmurze.jpg, /media/1/users-freekmurze_thumbnail.jpg, /media/1/[email protected]...

@ipalaus I think the function is called usingFileName('name')

I haven't tested it but I know usingName() is used for changing the name. I'm assuming usingFileName is for changing the file name. I don't think the documentation has all the available methods, but the video has some great info!

This is potentially against the core idea of this package, so feel free to turn it down, but here it goes: ability to have media not attached to a model.

Why would this be useful? I recently wanted to upload images using json before the model was created, and assign them after creation, but it was not possible.

It's a common problem, not strictly related to this package, and the usual solution is to create an empty model, attach the media, and update with the rest of the data afterwards; or upload to a temp folder, get the url, use a cron job to clean up unused media, etc.

But it would be nice if I could attach files to a collection, not a model, get their ids back or something so I could find them later, and attach the files when necessary. This would also allow moving images between models and things like that.

The problem I see with the idea is that it would probably make the API and the flow of using the package more complicated, and the fantastic usability of this package is what originally brought me here. I guess I don't know what I want :sweat_smile:.

Ability to customize conversion file name, for now it's hard-coded in https://github.com/spatie/laravel-medialibrary/blob/36f25439883d2f15b0afe81e31e788f87bca481b/src/FileManipulator.php#L86-L90
And overriding conversion's url in getPathRelativeToRoot using custom_url_generator_class will generate 404 links

Little idea: add the concept of a "single-file" collection that replaces the current media if there's already something uploaded for that model.

@sebastiandedeyne I very much like that idea. We can now easily implement this via the new media collection definitions.

$this
   ->addMediaCollection('avatar')
   ->singleFile()
   -> ...

Ability to version media. For example I'm currently writing an app that has one file associated with each model. I want to update that model with a new file but have the old file still associated as an older version.

Ideally I want to create a revisions model and then move that file along with it's conversions to a revisions directory and associate it with the new revision without having to recreate the conversions.

I'm afraid that use case is a bit too far away of the problem medialibrary is trying to solve. You can leverage custom properties to add version numbers to your media objects.

Ok that makes sense.

Is there a way to move a media association from one model to another? Detach from one model and attach to another model?

It would be very nice if it was possible to convert images with custom shapes.

For example if I want to do a square crop but then I want it to be a png of a circle shape inside the square

@vesper8 don't think we are going to support that. Under the hood this package uses our image package which in it's turn uses Glide. If Glide were to support your use case, image and media-library would support it too.

Add the ability to select a custom morph name ๐Ÿค”

@ludo237 why do you want that? Feel free to submit a PR against the v7 branch.

@freekmurze at the moment I am brainstorming, follow me a little bit here:

Sometimes it could be useful to edit the current $table->morphs("model"); property inside the migration stub for any reason, the only thing that needs to be updated is the media method inside HasMediaTrait

    public function media()
    {
        return $this->morphMany(config('medialibrary.media_model'), 'model');
    }

it would be nice if the model string comes from another configuration key, something like config('medialibrary.media_model_key'), for backwards compatibility the default config value will be model.

What do you think about?

I have had to currently extend this library to do the following I can raise it as a pr if you find it useful/ a needed feature.

We currently run cloud front on top of our s3 and an uploaded file can potentially take up to 30 minutes to sync across all the servers. The feature that I built allows you to switch to the CDN address after the file is x minutes old.

Basically it will use the direct address for the first x minutes then use the CDN address after.

Hope that makes sense.

@tjmartin69 feel free to send a pr for that

Many-many relationship after then it become the only one solution for image galleries :+1:

Would it be possible to add a second parameter to only delete media for certain collections

deleteMedia->($id, String|Array $collections)

Support for VIPS would be nice. There is a abstraction class for Imagine

The hardest part is getting the extension on a production environment as it's a PECL based extension.

Or just support for the command line tool VIPSThumbnail Especially the Smart Cropping Options can be a very welcome addition over calculating the entropy using PHP.

This package aims to be a simple, easy installable solution for media management. In that context requiring installing a PECL extension does not compute :-)

hence the command line option :) But perhaps it's a better fit for the Spatie Image over this library.

@tjmartin69 yes please do the pull request if you have already done the hard work <3

@freekmurze @ludo237 I will do it this weekend when I will have some free time.

@freekmurze Would you like this against the v7 branch?

Wish the 1st.

The package to use the Storage facade to access disks so we can Storage::fake() and not litter the actual disks with testing images. I know the package is tested and I don't need to duplicate "test_files_are_able_to_be_uploaded", however on routes that require images to he sent with the response due to validation, it would be great to just fake the storage on tests that hit those routes so they are cleaned up for us automatically.

Previously you've mentioned just switching the disk manually - which does work - but with Laravel giving us the power to fake storage so easily - unless there is package crippling issues with using the storage facade - it would be awesome.

I've just been doing this at the end of my tests: Media::all()->each->delete();
but consistency is key.

Wish the 2nd.

Ability to have the original image saved to different disk than the generated images.


Either way - super excited for the new version - sounds like its gonna be wicked. Thanks Spatie team!

@freekmurze @ludo237 Added the PR for the cdn domain here - https://github.com/spatie/laravel-medialibrary/pull/874

Keep original filename and create directories for each conversion

Image names are very relevant for SEO.

.. and this is the only thing holding me back from using this great library.

Therefor I suggest this feature resulting in a directory structure like this

media/
โ”œโ”€โ”€ 1/
โ”‚   โ”œโ”€โ”€ my-very-descriptive-filename.jpg
โ”‚   โ”œโ”€โ”€ thumb
โ”‚   โ”‚   โ””โ”€โ”€ my-very-descriptive-filename.jpg
โ”‚   โ”œโ”€โ”€ preview
โ”‚   โ”‚   โ””โ”€โ”€ my-very-descriptive-filename.jpg
โ”‚   โ””โ”€โ”€ full
โ”‚       โ””โ”€โ”€ my-very-descriptive-filename.jpg
โ”œโ”€โ”€ 2/
โ”‚   โ”œโ”€โ”€ this-filename-says-everything.jpg
โ”‚   โ”œโ”€โ”€ thumb
โ”‚   โ”‚   โ””โ”€โ”€ this-filename-says-everything.jpg
โ”‚   โ”œโ”€โ”€ preview
โ”‚   โ”‚   โ””โ”€โ”€ this-filename-says-everything.jpg
โ”‚   โ””โ”€โ”€ full
โ”‚       โ””โ”€โ”€ this-filename-says-everything.jpg
โ”œโ”€โ”€ .../ 

Additional benefit would be that you can easily cleanup specific conversions from the filesystem

I'm aware that you can achieve a similar solution by using by overwriting getPath() from the PathGenerator using the slug of the Eloquent model resulting in a directory structure like this:

media/
โ”œโ”€โ”€ slug-of-my-article/
โ”‚   โ”œโ”€โ”€ my-very-descriptive-filename.jpg
โ”‚   โ”œโ”€โ”€ conversions
โ”‚   โ”‚   โ”œโ”€โ”€ thumb.jpg
โ”‚   โ”‚   โ”œโ”€โ”€ preview.jpg
โ”‚   โ”‚   โ””โ”€โ”€ full.jpg
โ”œโ”€โ”€ slug-of-another-article/
โ”‚   โ”œโ”€โ”€ this-filename-says-everything.jpg
โ”‚   โ””โ”€โ”€ conversions
โ”‚       โ”œโ”€โ”€ thumb.jpg
โ”‚       โ”œโ”€โ”€ preview.jpg
โ”‚       โ””โ”€โ”€ full.jpg
โ”œโ”€โ”€ .../ 

But I think solution 1 is the better approach for SEO.
Please let me know your opinion on this.

Thanks in advance
pp

@pixelpeter like you mentioned you already can do a lot with a custom PathGenerator. In v7 the names conversions files will start with the name of the original file.

A new method to clone a model with all media items e.g. $media->replicateWithMedia()

v7 will have a copy method on Media, so you can easily implement the cloning you described yourself.

New idea:
When uploading pdf files with more than 1 page every page should optional generated as convertions so you can display all pages as jpg. (gallery, lightbox)

@divdax This could result in a lot of unwanted conversions if that behaviour is unwanted. Best to take care of that in your own app.

Another vote here for @javi-dev suggestion about allowing media not attached to a model. My use case is similar I think.

I have a "create" form for my product model, and I want to allow media to be uploaded and stored via AJAX prior to the form being submitted.

I'd store the IDs of the created media models in the form, so I can associate them with the product model when it's finally created.

So, I'd expect to be able to do something like this in my AJAX upload handler:

$product = new Product();
$mediaItem = $product->addMedia($request->file('file'))->toMediaCollection('product-images');
return [
    'id'    => $mediaItem->id,
    'url'   => $mediaItem->getUrl(),
];

@freekmurze this request might already be listed or supported. Would be great if one could e.g. give a default file/object per model or media-collection via a property or trait class e.g. defaultMedia = 'profile.jpg', whatever way.

Usecase: User profile image, if the user did not up upload a profile image the default would be returned, which of course would be a stand-alone file that is not directly related to any model but would be run through the same conversions as defined in the model where the property was defined.

When it is to be displayed an no media exist it is returned as the "placeholder". I think it would be better if it is an explicit method call just as a stupid example method-name "mediaOrDefault" or method parameter that is passed in.

This comes from always writing the same old code to do this over and over, but if supported in the medialibrary package the leverage of the conversions, etc. would ensure that even placeholder images are exactly treated and returned in the same way than actual media, which is a huge boost in consistency.

or something like this...

$this->addMediaCollection('images')
->acceptFiles(function (File $file, HasMedia $model) {
   return $file->mimeType == 'image/jpg';
})
->applyConversions(.....)
->useDisk('s3')
->placeholder( function() {
   $this->filename('default_profile.jpg') //throws exception if mime-type is not the same as the parent collection
   ->useDisk('local') //location of the default file
});

this request might already be listed or supported. Would be great if one could e.g. give a default file/object per model or media-collection via a property or trait class e.g. defaultMedia = 'profile.jpg', whatever way.

good suggestion, I'll see if I can implement this in a clean way.

I hope you will implement many to many relationship, really not need is when i want put same picture or pdf file to the two post and i need add them twice. This is not optimizing and clearing, a lot of not required files.

Many to many relations won't be added. Possibly we'll open source a demo project that shows you how you can build a WordPress like medialibrary with this package.

@freekmurze @timacdonald I would really appreciate using the storage mechanism consequently in this package. As already discussed, feature testing actions where media library is involved is currently quite complicated. It could be so easy if we could use Storage::fake($disk) instead.

Any update on a release date for V7? Really keen for the multi downloads feature :)

Probably somewhere between beginning of March, end of May.

  • having the ability to add wildcard (or regex) manipulations.
    Now a manipulation needs to have a conversion name as the key., so if you want to rotate a picture 90 degrees in a manipulation, and thereafter resize it with 4 conversions this means the rotation has to be specified for the 4 conversions.

@JorisDR we will implement your feature request in v6 soon: https://github.com/spatie/laravel-medialibrary/issues/942

I'm going to close this issue as v7 is coming along nicely and most new features already have been implemented or been decided on. Of course, feel free to suggest improvements / features by opening a new issue.

Thanks all!

Custom exceptions/validation for the addMediaFromUrl method would be nice.

Could you add native support for saving a hash of the file, presumably using file_hash() http://php.net/manual/en/function.hash-file.php

It's a nice way to check for duplicate media.

Of course it can cause problems with large files so it would be good to have an on/off option in the config as well as a max size to try and hash (so it won't bother hashing a file that is too large)

@robjbrain I feel like this is functionality is not generic enough to warrant a place in this package. Add this functionality this in your project.

Can we detach a media from a model without deleting the media? So we can attach it later to another model?

In the latest version of the package there is a move method to move media to another model.

Thanks for your response. But can we detach if from all models? A media not attached to any model, to be attached later.

That way the media library is a more independent ecosystem that can have loose relationships with other parts of the application.

@mokhosh Use the Media model and remove model_type and model_id yourself?

$media->update(['model_type' => '', 'model_id' => 0]);

@divdax I guess all wishes in this wish list could be somehow done the non-elegant way, but I thought this is a reasonable feature to have in future versions.

It could be great to have some methods to get for a collection :

  • the declared sizes
  • the accepted types

It is currently not so easy to get these data.
This could give the opportunity to analyse the results in order to use the model declared collections and conversions to dynamically generate the needed Laravel validations.

Example with a collection with the following declaration :

// registerMediaCollections()
$this->addMediaCollection('logo')->singleFile()->acceptsFile(function(File $file) {
    return $file->mimeType === 'image/jpeg' || $file->mimeType === 'image/png';
});;

// registerMediaConversions(Media $media = null)
$this->addMediaConversion('thumb')->width(40)->height(40)->sharpen(10);
$this->addMediaConversion('email')->width(100)->height(100)->performOnCollections('logo');
$this->addMediaConversion('base')->width(225)->height(225)->performOnCollections('logo');

Could return an array like this :

['logo'] => [
    'types' => ['image/jpeg', 'image/png'],
    'sizes' => [
        'thumb' => [
            'width' => 40,
            'height' => 40,
        ],
        'email' => [
            'width' => 100,
            'height' => 225,
        ],
        ... etc.
    ],
]

Then everyone could use these data for its own purpose.

@Okipa feel free to send a fully documented en tested PR for that.

@freekmurze I'll try when I'll have some free time (full rush right now).

Hi!

Is it possible firstly crop and fit image and then make responsive images?

For example, an uploaded photo firstly will be cropped to 450x300. Then responsive images will be generated from cropped image (450x300).
Something like this:

` $model->addMedia($request->image)->fit('crop', 450, 300)->withResponsiveImages()->toMediaCollection();

Of course I can register multiple Media Conversions. I think this way would be more sensible.

@freekmurze
I have submit a full tested PR for a dynamic validation and legend strings generation implementation proposition here : https://github.com/spatie/laravel-medialibrary/pull/1342.
Have implemented this separately on my project for a while and it definitely saved me from redondant implementations and errors.

So, version 7 is up, I've search for the vue components and found nothing. When will be they available?

We always create stuff we need ourselves. In the client projects we are working on now, we don't need those Vue components.

If you need them, feel free to published them in a repo of your own, i'll gladly add a link to them in the readme of this package.

I'd like to be able to associate a file with multiple collections. Allowing the user to upload a file 1 time and have it "tagged".

This prevents having the user upload a file and then place it in more than one collection. Which then causes the file to be stored more than one time.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Radiergummi picture Radiergummi  ยท  4Comments

aaronfullerton picture aaronfullerton  ยท  4Comments

swash13 picture swash13  ยท  3Comments

Krato picture Krato  ยท  4Comments

kickthemooon picture kickthemooon  ยท  4Comments