Laravel-medialibrary: Problems deleting files when use CustomPathGenerator

Created on 27 Jul 2017  路  11Comments  路  Source: spatie/laravel-medialibrary

I'm using this custom path generator:

class CustomPathGenerator implements PathGenerator
{
    /*
     * Get the path for the given media, relative to the root storage path.
     */
    public function getPath(Media $media) : string
    {
        $model_type = str_replace('App\\', '', $media->model_type);
        return $model_type.'/'.$media->model_id.'/';
    }
    /*
     * Get the path for conversions of the given media, relative to the root storage path.
     * @return string
     */
    public function getPathForConversions(Media $media) : string
    {
        return $this->getPath($media).$media->name.'_variants/';
    }
}

It's working fine all may media has been organized as follow:

User:
       1:
          MEDIA01
          MEDIA01_VARIANTS:
             thumb
             portrait
             poster
          MEDIA02
          MEDIA02_VARIANTS:
             thumb
             portrait
             poster
       2:
          MEDIA03
          MEDIA03_VARIANTS:
             thumb
             portrait
             poster

The problems happens when i need to delete any media file from an model,
If i issue a command like Media::find('MEDIA01')->delete() it will be delete the entire User->1 tree files, not only 'MEDIA01' related files.

Most helpful comment

This post helped me out, so I wanted to share one possible improvement
$model_type = class_basename($media->model_type);

All 11 comments

That's not too good.

Could you PR a failing test for me to work on?

Hy @freekmurze, how should i do that?

The tests regarding custom paths are located here: https://github.com/spatie/laravel-medialibrary/blob/master/tests/PathGenerator.

You should add a test that mimics what you're doing in your real app.

If you don't have experience with testing, I'll do it whenever I have some time (might take a while though).

You can also already help by finding a fix in the code of the medialibrary that would solve your problem.

Hi @freekmurze, i really will try to do that.
Could you help me to find where exactly is the code that delete files from disk?
I will be happy to try solve that and contribute to the project.

The problems seems to be, that deletion is issued in directory not in file, and with custom path i'm using i'm not using a directory per media file. Only grouping medias of same "model" into same directory, i this case, the deletion is been issued to model directory.

Yeah, this is a limitation of the package. It will always return the entire directory of a media item.The easiest solution would be to reorganise your media so a directory only contains the orginal and conversions of a unique media item.

Hi,
I'd changed my custom path to use each media into a exclusive directory and works fine to me.

<?php
namespace App;

use Spatie\MediaLibrary\Media;
use Spatie\MediaLibrary\PathGenerator\PathGenerator;
class CustomPathGenerator implements PathGenerator
{
    /*
     * Get the path for the given media, relative to the root storage path.
     */
    public function getPath(Media $media) : string
    {
        $model_type = str_replace('App\\', '', $media->model_type);
        return $model_type.'/'.$media->model_id.'/'.md5($media->id).'/';
    }
    /*
     * Get the path for conversions of the given media, relative to the root storage path.
     * @return string
     */
    public function getPathForConversions(Media $media) : string
    {
        return $this->getPath($media).'formats/';
    }
}

馃憤

This post helped me out, so I wanted to share one possible improvement
$model_type = class_basename($media->model_type);

Thanks a lot @rafaelsisweb! You save my life, It work for me:

Collection_name:
-Media_ID1
--file.exp
-Media_ID2
--file2.exp

class BasePathGenerator implements PathGenerator
{
/*
* Get the path for the given media, relative to the root storage path.
*/
public function getPath(Media $media): string
{
return $this->getBasePath($media).'/'.$media->id.'/';
}

/*
 * Get the path for conversions of the given media, relative to the root storage path.
 */
public function getPathForConversions(Media $media): string
{
    return $this->getBasePath($media).'/conversions/';
}

/*
 * Get the path for responsive images of the given media, relative to the root storage path.
 */
public function getPathForResponsiveImages(Media $media): string
{
    return $this->getBasePath($media).'/responsive-images/';
}

/*
 * Get a unique base path for the given media.
 */
protected function getBasePath(Media $media): string
{
    return $media->collection_name;
}

}

Was this page helpful?
0 / 5 - 0 ratings