2

I'm new to this package since I usually use the image intervention. So the problem is whenever I save an image, it is saving in storage directory instead of in public directory. I tried to review the documentation and did some research and didn't see any answer. Please see my code below for saving.

$user->addMediaFromRequest('avatar')->toMediaCollection('avatars');

Package:

https://spatie.be/docs/laravel-medialibrary/v7/introduction

apokryfos
  • 38,771
  • 9
  • 70
  • 114
Blues Clues
  • 1,694
  • 3
  • 31
  • 72
  • you need to make your own class extending default PathGenerator, read https://spatie.be/docs/laravel-medialibrary/v7/advanced-usage/using-a-custom-directory-structure section – Alzafan Christian Sep 11 '20 at 13:09
  • @AlzafanChristian Can you add an example and more details? The documentation is a bit confusing. – Blues Clues Sep 11 '20 at 13:56
  • @Jonjie I would not recommend saving the images in the `/public` directory, instead save them in the `storage/app/public` directory and create a symlink from `public/storage` to `storage/app/public`, as explained [here](https://laravel.com/docs/7.x/filesystem#the-public-disk). – Remul Sep 11 '20 at 14:49
  • @Remul I appreciate your recommendation. But may I know the reason why? – Blues Clues Sep 11 '20 at 20:09

1 Answers1

6

you can simply define the filesystem config with $user->addMediaFromRequest('avatar')->toMediaCollection('avatars', 'disk');

here is how im using the package(simple usage), if you need it later

on my model:

use Spatie\MediaLibrary\HasMedia\HasMedia;
use Spatie\MediaLibrary\HasMedia\HasMediaTrait;
use Spatie\MediaLibrary\Models\Media;
class User extends Model implements HasMedia
{
use HasMediaTrait;
public function registerMediaCollections()
{
    $this
    ->addMediaCollection('avatar')
    ->singleFile()
    ->useDisk('public');
    ->useFallbackUrl(asset('/images/default-user.png'))
    ->useFallbackPath(public_path('/images/default-user.png'));
}

public function registerMediaConversions(Media $media = null)
{
    $this->addMediaConversion('avatar-thumb')->width(120)->height(120);
}
...

to get the file-url im using model accessor, added this function in my model:

public function getAvatarAttribute()
{
    $file = $this->getMedia('avatar')->first();

    if($file) {
      $file->url = $file->getUrl();
      $file->thumbnail = $file->getUrl('avatar-thumb'));
      $file->alternate = $file->getCustomProperty('alternate') ?: $file->file_name;
    }else{
      $file = new \StdClass;
      $file->url = $this->getFallbackMediaUrl('avatar');
      $file->thumbnail = public_path('/images/default-user-thumb.png');
      $file->alternate = 'avatar.png';
    }

    return $file;
}

also using custom path, in config\medialibrary.php set this array 'path_generator' => Path\To\Your\Class::class,

then the class :

use Spatie\MediaLibrary\Models\Media;
use Spatie\MediaLibrary\PathGenerator\PathGenerator as PathGenerators;

class PathGenerator implements PathGenerators
{
public function getPath(Media $media): string
{
    return $this->getBasePath($media).'/';
}

public function getPathForConversions(Media $media): string
{
    return $this->getBasePath($media).'/conversions/';
}

public function getPathForResponsiveImages(Media $media): string
{
    return $this->getBasePath($media).'/responsive-images/';
}

protected function getBasePath(Media $media): string
{
    //here im using trait to generate default path, e.g: path/mimes/avatar/media->id
    //its up to you to define folder structure, just make sure each folder
    //for conversions has unique name, or else it will be deleted
    $base_folder = $this->get_base_folder($media->mime_type);
    return "{$base_folder}/{$media->collection_name}/{$media->getKey()}";
}
}