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:
- Ubicación de las imágenes
- Ancho de la imagen
- Alto de la imagen
- Categoría, pero como faker en laravel 8 ya no lo utiliza, se pasa null
- True/false, true pasa la ruta completa y false solo el nombre de la imagen
Ejemplo true: public/storage/posts/imagen1.jpg
Ejemplo false: imagen1.jpg
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)
];}
Tener en cuenta que la ruta que se indica al crear la imagen con faker es distinta a la ruta de acceso pública que se llama desde el resto de la aplicación web.
Ruta faker: public/storage/carpeta
Ruta publica: carpeta
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.
- Abrir el fichero
vendor\fakerphp\faker\src\Faker\Provider\Image.php
- Buscar la línea de código
curl_setopt($ch, CURLOPT_FILE, $fp); - 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 una respuesta