Skip to content

Instantly share code, notes, and snippets.

@monoman81
Created April 16, 2021 18:40
Show Gist options
  • Save monoman81/cec2e19c079b198aa7344fefc0462c84 to your computer and use it in GitHub Desktop.
Save monoman81/cec2e19c079b198aa7344fefc0462c84 to your computer and use it in GitHub Desktop.
Filament Relation Managers and Spatie Media Library
<?php
namespace App\Filament\Resources\Admin\ProductResource\RelationManagers;
use Filament\Resources\RelationManager\CreateRecord;
class CreateMediaRecord extends CreateRecord
{
public function getMediaRealPath()
{
$temporaryUploadedFile = $this->getTemporaryUploadedFile('record.media');
if ($temporaryUploadedFile)
return $temporaryUploadedFile->getRealPath();
return '';
}
public function create($another = false)
{
$manager = $this->manager;
$this->callHook('beforeValidate');
$this->validateTemporaryUploadedFiles();
$this->validate();
$this->callHook('afterValidate');
$this->callHook('beforeCreate');
//The parent model (Product) is accesed using $this->owner
$mediaPath = $this->getMediaRealPath();
if ($mediaPath !== '')
$this->owner->attachMedia($mediaPath, $this->record['name']);
$this->callHook('afterCreate');
$this->emit('refreshRelationManagerList', $manager);
if ($another)
{
$this->fillRecord();
$this->dispatchBrowserEvent('notify', __($manager::$createModalCreatedMessage));
return;
}
$this->dispatchBrowserEvent('close', "{$manager}RelationManagerCreateModal");
}
}
<?php
namespace App\Filament\Resources\Admin\ProductResource\RelationManagers;
use Filament\Resources\Forms\Components;
use Filament\Resources\Forms\Form;
use Filament\Resources\RelationManager;
use Filament\Resources\Tables\Columns;
use Filament\Resources\Tables\Filter;
use Filament\Resources\Tables\Table;
use Illuminate\Support\Facades\Storage;
class MediaRelationManager extends RelationManager
{
public static $primaryColumn = 'name';
public static $relationship = 'media';
protected static $components = [
'attach' => RelationManager\AttachRecord::class,
'create' => CreateMediaRecord::class,
'edit' => RelationManager\EditRecord::class,
'list' => ListMediaRecords::class, //RelationManager\ListRecords::class,
];
public static function form(Form $form)
{
return $form->schema([
Components\TextInput::make('name')
->autofocus()
->maxLength(100)
->rules(['required'])
->placeholder('Ingresa un nombre para identificar la imagen en la lista')
->label('Nombre Imagen'),
Components\FileUpload::make('media')
->image()
->label('Imagen del Producto'),
]);
}
//Using getValueUsing again for display. But i couldn't find how to refer the media using the parent model so
//i cheated a little using Storage::disk to the storage path + how spatie create subfolders with the record id and the filename.
public static function table(Table $table)
{
return $table->columns([
Columns\Text::make('name')
->primary()
->label('Nombre'),
Columns\Image::make('image')
->label('Imagen')
->size(80)
->getValueUsing(
fn($record) => Storage::disk('products')->url($record->id.'/'.$record->file_name)
),
])->filters([
]);
}
}
<?php
namespace App\Models\Admin;
use App\Services\Skuable\HasSku;
use App\Services\Skuable\SkuOptions;
use Cviebrock\EloquentSluggable\Sluggable;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Support\Str;
use Spatie\MediaLibrary\Conversions\Conversion;
use Spatie\MediaLibrary\HasMedia;
use Spatie\MediaLibrary\InteractsWithMedia;
use Spatie\MediaLibrary\MediaCollections\Models\Media;
class Product extends Model implements HasMedia
{
use HasFactory, Sluggable, SoftDeletes, InteractsWithMedia, HasSku;
...
public function attachMedia($path, $fileName = '') : self
{
$extension = Str::afterLast($path, '.');
if ($fileName === '')
$fileName = strtolower(str_replace(['#', '/', '\\', ' '], '-', $this->sku)).'_'.$this->id;
$this->addMedia($path)
->usingFileName($fileName.'.'.$extension)
->usingName($fileName)
->toMediaCollection('products');
return $this;
}
public function registerMediaCollections(): void
{
$this->addMediaCollection('products')
->useDisk('products')
->acceptsMimeTypes([
'image/jpeg',
'image/png',
'image/svg+xml',
'image/webp',
'image/gif',
'image/svg',
]);
}
public function registerMediaConversions(Media $media = null): void
{
$this->addMediaConversion('thumb')
->width(65)
->height(65)
->sharpen(10)
->keepOriginalImageFormat()
->nonQueued();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment