Imagenes en laravel

En laravel es fácil subir imágenes y guardarlas en el servidor. Es muy útil y permite al usuario subir fotos o imágenes para cualquier cosa como artículos de blog, productos, categorías, etc.

Fichero de configuración filesystems

Lo primero que hay que saber es dónde se van a guardar las fotos en el servidor. Para ello hay que abrir el fichero filesystems.php que contiene toda la configuración referente a ficheros.

config\filesystems.php

Por defecto laravel ubica en la carpeta local el sitio por defecto. Pero para aplicaciones web conviene cambiarlo a la carpeta public. Así habría que cambiar esa línea.

'default' => env('FILESYSTEM_DRIVER', 'local'),
'default' => env('FILESYSTEM_DRIVER', 'public'),

Fichero de configuración .env

Otra opción es configurar en el fichero raíz .env, con la variable FILESYSTEM_DRIVER cambiando la palabra local por public.

.env

FILESYSTEM_DRIVER=public

Crear enlace simbólico de la carpeta public

La carpeta storage\app\public y public\storage deben de ser la misma, para poder acceder sin problemas al interactuar con la página web.

Para que apunten al mismo sitio las dos, se utiliza un enlace simbólico con el siguiente comando.

php artisan storage:link


Así crea el acceso directo de
storage\app\public
public\storage

Para comprobar que funciona correctamente se puede crear un fichero en una carpeta, y ver que también está en la otra carpeta.

Crear imágenes de prueba

En este ejemplo se va a crear imágenes a través de factories, para agregarlo a un artículo o post.

database\factories\PostFactory.php

El contenido del factory sería para crear nombre, contenido de relleno y la imagen.

A la imagen hay que pasarle unos parámetros:

  1. Ubicación de las imágenes
  2. Ancho de la imagen
  3. Alto de la imagen
  4. Categoría, pero como faker en laravel 8 ya no lo utiliza, se pasa null
  5. True/false, true pasa la ruta completa y false solo el nombre de la imagen

Un truco para ubicar en la carpeta pública es concatenar la carpeta como string y el nombre de la imagen (con false), así queda «post/nombredelaimagen»

public function definition()    {
return [ 
'title' => $this->faker->sentence(),
'content' => $this->faker->text(),
'image' => 'posts/' . $this->faker->image('public/storage/posts', 640, 480, null, false) 
];}

Añadir la imagen en fichero

Para que faker pueda añadir los datos a una base de datos, hay que añadir en el fichero de migraciones la línea correspondiente a la imagen dentro del método create.

database\migrations\create_posts_table.php

$table->string('image');

Crear carpetas con faker

Faker no puede crear carpeta por sí solo, así hay que crearlas con anterioridad a ejecutar la creación de imágenes.

Entonces en el DatabaseSeeder hay que indicarlo.

database\seeders\DatabaseSeeder.php

Importar el facade Strorage

use Illuminate\Support\Facades\Storage;

y añadir a la función run el código de eliminación y creación de la carpeta pasada por parámetro.

Storage::deleteDirectory('posts');
Storage::makeDirectory('posts');

Si no crea la carpeta y el seeder da un error de permisos, poner la carpeta con public delante

Storage::makeDirectory('public/posts');

Pero si se ha cambiado el parámetro FILESYSTEM_DRIVER en el fichero filesystems.php y en el fichero .env no tiene porqué dar el error.

Ejecutar migraciones con seeders

Para que se generen los datos de prueba, con las modificaciones de imagen, hay que ejecutar de nuevo las migraciones, además de hacer correr los seeders.

  • Migrate para modificar la base de datos
  • Fresh para borrar datos y generarlos de nuevo
  • –seed para crear los datos de prueba
php artisan migrate:fresh --seed

Imagen en controlador, vista y modelo

Tanto en controlador como en la vista hay que indicarle que se va a trabajar in imágenes

En el controlador o componente

En el controlador o componente hay que importar la clase WithFileUploads y usarla dentro del misma.

use Livewire\WithFileUploads;
use WithFileUploads;

Crear una propiedad image

public $image, $identificador;

Crear el método mount para inicializar al cargar un identificador aleatorio, para que al renderizar de nuevo la vista, se refresque con uno nuevo y no deje la leyenda del fichero anterior.

public function mount(){
$this->identificador = rand();
}

Almacenar la imagen en la carpeta y en la base de datos, y resetea las propiedades. En el ejemplo se implementa en la función save que guarda datos del formulario. Guarda temporal

$image = $this->image->store('posts');
Post::create([

'title' => $this->title,
'content' => $this->content,
'image' => $image
]);
$this->reset(['open', 'title', 'content', 'image']);
$this->identificador = rand();

En la vista

Añadir un input de tipo file y decirle que se conecte con la propiedad image del componente o controlador a través de wire. También el id del identificador pasado aleatoriamente.

<div>
<input type="file"
wire:model="image"
id="{{$identificador}}">
</div>

Mostar la imagen añadida

En la vista añadir la imagen temporal que se está añadiendo, en caso de que que la propiedad image tenga valor. Para saberlo se utiliza el método temporaryUrl.

<div
wire:loading
wire:target="image"
class="text-red-600">
<strong class="font-bold">Cargando imagen...</strong>
<span class="block sm:inline">Esperar que termine subida</span>
</div>

@if ($image)
<img src="{{$image->temporaryUrl()}}">
@endif

En el modelo

Para que se pueda guardar sin errores, hay que incluir en la asignación masiva del modelo, incluyendo la propiedad en la propiedad fillable.

protected $fillable = ['title', 'content', 'image'];

Solucionar error descargar imágenes con faker

Si hay algún problema al generar imágenes o descargarlas con faker, habría que añadir las siguientes dos líneas de código.

  1. Abrir el fichero
    vendor\fakerphp\faker\src\Faker\Provider\Image.php
  2. Buscar la línea de código
    curl_setopt($ch, CURLOPT_FILE, $fp);
  3. Añadir las dos líneas
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);

Con esto se debería solucionar el posible error ocasionado al crear imágenes automáticas

Deja un comentario