使用 Laravel Livewire 和 Filepond 处理文件上传和重新排序

Handling File uploads and reorder with Laravel Livewire and Filepond

我的应用程序中有一个表单,允许用户创建 post,同时将多个图像上传到正在创建的 post。

我正在使用 Laravel Livewire 和 Filepond 来实现这一点。

我遇到的问题是我需要允许用户重新排序图像(因为它是一个画廊,顺序很重要),并在提交表单时将顺序保存在数据库中。

我 运行 关注的另一个问题是允许用户稍后编辑他们的 post。我需要将他们预先存在的 post 图像加载到 filepond 中,还允许他们上传更多、删除、and/or 重新排序。

当用户保存 post 我需要能够更新我的数据库和文件系统。

几天来我一直在努力解决这个问题,但没有成功。所有在线信息都是如何上传文件,但没有关于如何重新排序或预填充现有文件的信息。

如有任何帮助,我们将不胜感激。

这是我目前的参考代码:

<div
    x-data=""
    x-init="
       
        FilePond.setOptions({
            allowMultiple: true,
            allowReorder: true,
            itemInsertLocation: 'after',
            server: {
                process: (fieldName, file, metadata, load, error, progress, abort, transfer, options) => {
                    @this.upload('images', file, load, error, progress)
                },
                revert: (filename, load) => {
                    @this.removeUpload('images', filename, load)
                },
                load: (source, load, error, progress, abort, headers) => {
                    var myRequest = new Request(source);
                    fetch(myRequest).then(function(response) {
                      response.blob().then(function(myBlob) {
                        load(myBlob)
                      });
                    });
                },
            },
        });
        const pond = FilePond.create($refs.input, {
            acceptedFileTypes: ['image/png', 'image/jpeg'],
            maxFileSize: '7MB',
            allowImageCrop: true,
            allowReorder: true,
            allowImageResize: true,
            imageResizeTargetWidth: '1000px',
            imageResizeTargetHeight: '1000px',
            filePosterMaxHeight: '256px',
            files: {{ $existingImages }} // used for when editing a post and it already has images. see php component on how I set this variable
            
        });

    "
>
    <div wire:ignore wire:key="images">
        <div class="form-group text-center">
            <input
                id="image-upload"
                type="file"
                x-ref="input"
                multiple
                data-allow-reorder="true"
                data-max-file-size="3MB"
                data-max-files="10"
            >
        </div>
    </div>
</div>

我的 livewire PHP 组件:

    public $images = [];
    public $existingImages;

    public function mountMedia($post) {
        if($post){
            $this->existingImages = $post->images->map(function ($image) use ($post) {
                return [
                    'source' => $image->id,
                    'options' => [
                        'type' => 'local',
                        'file' => [
                            'name' => $image->getUrl(),
                            'size' => $image->file_size,
                            'type' => $image->mime_type,
                        ],
                        'metadata' => [
                            'poster' => $image->getUrl(),
                            'position' => $image->position
                        ],
                    ],
                ];

            });
        }
    }
    public function saveImage($file, $post, $position) {
        // Create a unique random string
        $randString = Str::random(3);
        // Get time
        $time = time();
        // Set file name
        $filename = $time. '-' . $randString.'-'.auth()->user()->id;
        $extension = '.'.$file->getClientOriginalExtension();

        // Save images for gallery 
        $regImage = $file->storeAs('/'. $post->id, $filename.$extension, 'post_images');

           
        // Create a new image in db
        Image::create([
            'user_id'       => auth()->user()->id,
            'post_id'       => $post->id,
            'position'      => $position,
            'filename'      => $filename,
            'extension'     => $extension,
            'src'           => 'post_images',
            'mime_type'     => $file->getMimeType(),
            'file_size'     => $file->getSize(),
        ]);
    }

    public function saveMedia($post) {
        // Make sure user owns post
        abort_unless($post->user_id == auth()->user()->id, 403);

        // Set default position
        $position = 1;

        // Save each image
        foreach ($this->images as $file) {
           $this->saveImage($file, $post, $position);
            // Increment position for next image
            $position++;
        }
    }
}

为了在 Livewire 中对项目进行排序,我会使用 https://github.com/livewire/sortable。 Sortable 非常容易使用。

对于 filepond,如果以后要再次使用原始图像,我会保存该图像以及与编辑后的版本的关系。