Saltar a contenido

Gestión subida de ficheros

La carga de ficheros es algo muy común en las aplicaciones de hoy en día. En este apartado vamos a ver los pasos que debemos dar para implementar la carga de archivos con Laravel en nuestro proyecto reactivo.

En esta parte seguiremos haciendo uso del formulario que hemos creado en el apartado anterior, por lo que gran parte del código está ya creado. Ahora vamos a ver lo que realmente necesitamos para la gestión de ficheros en nuestro proyecto reactivo.

Controlador

Lo primero que debemos hacer es implementar un recurso rest para la carga de ficheros. Esto lo haremos sobre el controlador, en este caso PostController.php. Esta función de subida deberá darnos un JSON.

<?php 

function upload(Request $request, Post $post) {

        $data['image'] = $filename = time() . '.'. $request->image->extension();
        $request->image->move(public_path('image'), $filename);

        // Esto actualizará el post siempre que en el modelo la imagen se llame 'image'
        $post->update($data);

        return response()->json($post);
    }

Ahora debemos añadir la ruta en nuestro fichero api.php:

Route::post('post/upload/{post}',[PostController::class, 'upload']);
Puedes realizar una prueba con Postman eligiendo el método POST y el tipo de datos como form-data de tipo file.

Implementación en Vue

Una vez que nuestro proyecto es capaz de subir ficheros y actualizar en la base de datos, toca hacerlo de una manera más amigable para el usuario. En este punto retomamos el fichero que creamos en el apartado anterior. Seguimos haciendo uso de Oruga UI, pero sería parecido si lo hiciésemos sin él o con Tailwind.

<div class="flex gap-2 mt-5" v-if="post">
    <o-field>
        <o-upload v-model="file">
            <o-button tag="upload-tag" variant="primary">
                <o-icon icon="upload"></o-icon>
                <span>Click to upload</span>
            </o-button>
        </o-upload>
    </o-field>

    <o-button icon-left="upload" @click="upload">
        Upload
    </o-button>     
</div>
Y la parte de Vue, añadimos la parte de gestión del upload.

<script>
export default {

    methods: {

        upload(){
            const formData = new FormData()

            formData.append('image', this.file)
            this.$axios.post('/api/post/upload/'+this.post.id, formData, {
                headers: {
                    'Content-Type' : 'multipart/form-data'
                }
            }).then((res)=> {
                console.log(res);
            })
        },
    }
}
</script>

Con esto ya tendríamos una simple gestión de subida de ficheros, pero sin control alguno de errores.

Manejo de errores en el formulario

En todo proceso que interviene un usuario debemos de dar la información de lo que está pasando en nuestro proyecto, y es por eso que debemos gestionar los diferentes errores que se pueden dar en nuestro proceso de subida de ficheros a nuestro servidor.

De entrada, comenzamos con el controlador, donde indicaremos las extensiones aceptadas y el tamaño máximo que permitimos.:

<?php
function upload(Request $request, Post $post) {

    $request->validate([
        'image' => 'required|mimes:jpg,jpeg,png,gif|max:10240'
    ]);

    $data['image'] = $filename = time() . '.'. $request->image->extension();

    $request->image->move(public_path('image'), $filename);
    $post->update($data);

    return response()->json($post);
}

Seguidamente variamos el componente:

<div class="flex gap-2 mt-5" v-if="post">
    <o-field :message="fileError" :variant="fileError ? 'danger' : 'primary'">
        <o-upload v-model="file">
            <o-button tag="upload-tag" variant="primary">
                <o-icon icon="upload"></o-icon>
                <span>Click to upload</span>
            </o-button>
        </o-upload>
    </o-field>

    <o-button icon-left="upload" @click="upload">
        Upload
    </o-button>     
</div>

Y finalmente el control en Vue:

export default {
    async mounted() {
    },
    data() {
        return {
            fileError:'',
            file: null,
        }
    },
    methods: {

        upload(){
            this.fileError=''
            const formData = new FormData()

            formData.append('image', this.file)
            this.$axios.post('/api/post/upload/'+this.post.id, formData, {
                headers: {
                    'Content-Type' : 'multipart/form-data'
                }
            }).then((res)=> {}).catch((error)=> {
                this.fileError=error.response.data.message
            })
        },

    },

}

Con esto tendríamos el control de la subida de archivos realizado tanto en la parte de Laravel (controlador) como en Vue (componente).

Actividad

  • 🧪 PR 909. (RA9 / CE9c CE9d CE9e / IC2 / 5p) - Permite que el docente pueda subir un fichero de corrección en PDF a cada alumno.