Laravel Nova + Spatie 媒体库

3

我尝试使用 Laravel Nova 和 Spatie 媒体库。我创建了如下的上传字段:

Image::make('Logo')
        ->store(function (Request $request, $model) {
            $model->addMediaFromRequest('logo')->toMediaCollection('manufacturers');
        }),

看起来没问题,但Nova仍然试图将文件名保存到制造商表中的“logo”列中。

自定义此字段的原始示例是:

File::make('Attachment')
    ->store(function (Request $request, $model) {
        return [
            'attachment' => $request->attachment->store('/', 's3'),
            'attachment_name' => $request->attachment->getClientOriginalName(),
            'attachment_size' => $request->attachment->getSize(),
        ];
    })
4个回答

3

我发现一个解决方法是在模型上设置一个空的mutator。对于你的情况,可以这样做:

class Manufacturer extends Model implements HasMedia
{
    use HasMediaTrait;

    public function setLogoAttribute() {}

    //...
}

这是我的全部实现示例。需要注意的是,目前在Nova 1.0.6版本中,preview() 方法无法正常工作,会返回 thumbnail() 的 URL。 App/GalleryItem
class GalleryItem extends Model implements HasMedia
{
    use HasMediaTrait;

    public function setImageAttribute() {}

    public function registerMediaConversions(Media $media = null)
    {
        $this->addMediaConversion('thumbnail')
            ->fit(Manipulations::FIT_CROP, 64, 64);

        $this->addMediaConversion('preview')
            ->fit(Manipulations::FIT_CROP, 636, 424);

        $this->addMediaConversion('large')
            ->fit(Manipulations::FIT_CONTAIN, 1920, 1080)
            ->withResponsiveImages();
    }

    public function registerMediaCollections()
    {
        $this->addMediaCollection('images')->singleFile();
    }
}

App/Nova/GalleryItem

class GalleryItem extends Resource
{
    public static $model = 'App\GalleryItem';

    public static $with = ['media'];

    public function fields(Request $request)
    {
        return [
            Image::make('Image')
                ->store(function (Request $request, $model) {
                    $model->addMediaFromRequest('image')->toMediaCollection('images');
                })
                ->preview(function () {
                    return $this->getFirstMediaUrl('images', 'preview');
                })
                ->thumbnail(function () {
                    return $this->getFirstMediaUrl('images', 'thumbnail');
                })
                ->deletable(false);
        ];
    }
}

1
为什么使用这些代码下载链接会消失? - Rashad

3
与Nova 3(和Laravel 8)一样,您需要从fillUsingstore方法返回true
File::make('Attachment')
    ->store(function (Request $request, $model) {
        $model->addMediaFromRequest('logo')->toMediaCollection('manufacturers');

        return true;
        // This will tell nova that you have taken care of it yourself.
    })

只要返回除了true以外的任何内容,nova就会认为它需要将某些内容保存到数据库中。如果该字段在数据库中不存在(如预期的spatie-medialibrary),这将导致错误;如果该字段存在但用途不同,则会覆盖您珍贵的数据。

2
Nova允许您从回调函数返回true表示处理已经完成,且不应该自行设置任何属性。
以下是运行回调函数的代码:
protected function fillAttribute(NovaRequest $request, $requestAttribute, $model, $attribute)
{
    //...

    $result = call_user_func($this->storageCallback, $request, $model);

    if ($result === true) {
        return;
    }

    if (! is_array($result)) {
        return $model->{$attribute} = $result;
    }

    foreach ($result as $key => $value) {
        $model->{$key} = $value;
    }
}

所以,true 或者任何空数组都可以达到相同的效果,但个人认为前者更清晰易懂。

1
    Image::make('Logo')
        ->store(function (Request $request, $model) {
            $model->addMediaFromRequest('logo')->toMediaCollection('manufacturers');
        return [];
        }),

也许返回一个空数组可以防止 Nova 保存名称。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接