Handling File uploads and reorder with Laravel Livewire and Filepond

  filepond, laravel, laravel-livewire

I have a form in my application that allows users to create posts and while doing so upload multiple images to the post being created.

I am using Laravel Livewire and Filepond to achieve this.

The problem I am having is I need to allow the user to reorder the images (as it is a gallery and the order is important), and save the order in the database when the form in submitted.

Another issue I am running into is allowing a user to edit their post later. I need their pre-existing post images loaded in filepond, and also allow them to upload more, delete, and/or reorder.

When the user saves the post I need to be able to update my database and file system.

I’ve been trying to figure this out for days with no luck. All info online is how to upload files, but no info on how to reorder, or prepopulate with pre-existing files.

Any help with this would be greatly appreciated.

Here is my current code for reference:

<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>

My livewire PHP component:

    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++;
        }
    }
}

Source: Laravel

Leave a Reply