spatie / laravel-medialibrary

Associate files with Eloquent models
https://spatie.be/docs/laravel-medialibrary
MIT License
5.78k stars 1.07k forks source link

Feature wishlist for medialibrary v7 #858

Closed freekmurze closed 6 years ago

freekmurze commented 6 years ago

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

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

agustinprod commented 6 years ago

Chunked uploading for large assets could be a useful feature

plakhin commented 6 years ago

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.

ryankilf commented 6 years ago

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.

Christophvh commented 6 years ago
palypster commented 6 years ago

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).

freekmurze commented 6 years ago

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

amirshawn commented 6 years ago

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

ipalaus commented 6 years ago

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/users-freekmurze@x2.jpg...

amirshawn commented 6 years ago

@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!

javi-dev commented 6 years ago

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:.

freekmurze commented 6 years ago

Good be nice as well: https://twitter.com/bmichotte/status/933621483770957824

ttphi88 commented 6 years ago

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

sebastiandedeyne commented 6 years ago

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

freekmurze commented 6 years ago

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

$this
   ->addMediaCollection('avatar')
   ->singleFile()
   -> ...
bcreeves commented 6 years ago

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.

freekmurze commented 6 years ago

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.

bcreeves commented 6 years ago

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?

vesper8 commented 6 years ago

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

freekmurze commented 6 years ago

@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.

ludo237 commented 6 years ago

Add the ability to select a custom morph name 🤔

freekmurze commented 6 years ago

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

ludo237 commented 6 years ago

@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?

tjmartin69 commented 6 years ago

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.

freekmurze commented 6 years ago

@tjmartin69 feel free to send a pr for that

antonkomarev commented 6 years ago

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

MaximVanhove commented 6 years ago

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

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

renebakx commented 6 years ago

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.

freekmurze commented 6 years ago

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

renebakx commented 6 years ago

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

ludo237 commented 6 years ago

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

tjmartin69 commented 6 years ago

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

@freekmurze Would you like this against the v7 branch?

timacdonald commented 6 years ago

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!

tjmartin69 commented 6 years ago

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

pixelpeter commented 6 years ago

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

freekmurze commented 6 years ago

@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.

divdax commented 6 years ago

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

freekmurze commented 6 years ago

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

divdax commented 6 years ago

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)

freekmurze commented 6 years ago

@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.

leewillis77 commented 6 years ago

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(),
];
slakbal commented 6 years ago

@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
});
freekmurze commented 6 years ago

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.

AdrianKuriata commented 6 years ago

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.

freekmurze commented 6 years ago

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.

MannikJ commented 6 years ago

@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.

robjbrain commented 6 years ago

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

freekmurze commented 6 years ago

Probably somewhere between beginning of March, end of May.

ghost commented 6 years ago
freekmurze commented 6 years ago

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

freekmurze commented 6 years ago

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!