laravel-vuexy-admin/Services/AvatarInitialsService.php

125 lines
3.7 KiB
PHP
Raw Permalink Normal View History

2025-03-07 00:29:07 -06:00
<?php
namespace Koneko\VuexyAdmin\Services;
use Illuminate\Support\Facades\Storage;
use Intervention\Image\ImageManager;
use Intervention\Image\Typography\FontFactory;
class AvatarInitialsService
{
protected $avatarDisk = 'public';
protected $initialAvatarDir = 'initial-avatars';
protected $avatarWidth = 512;
protected $avatarHeight = 512;
protected const INITIAL_MAX_LENGTH = 3;
protected const AVATAR_BACKGROUND = '#EBF4FF';
protected const AVATAR_COLORS = [
'#7367f0',
'#808390',
'#28c76f',
'#ff4c51',
'#ff9f43',
'#00bad1',
'#4b4b4b',
];
/**
* Genera o retorna el avatar basado en las iniciales.
*
* @param string $name Nombre completo del usuario.
*
* @return \Illuminate\Http\Response Respuesta con la imagen generada.
*/
public function getAvatarImage($name)
{
$color = $this->getAvatarColor($name);
$background = ltrim(self::AVATAR_BACKGROUND, '#');
$size = ($this->avatarWidth + $this->avatarHeight) / 2;
$initials = self::getInitials($name);
$cacheKey = "avatar-{$initials}-{$color}-{$background}-{$size}";
$path = "{$this->initialAvatarDir}/{$cacheKey}.png";
$storagePath = storage_path("app/public/{$path}");
if (Storage::disk($this->avatarDisk)->exists($path)) {
return response()->file($storagePath);
}
$image = $this->createAvatarImage($name, $color, self::AVATAR_BACKGROUND, $size);
Storage::disk($this->avatarDisk)->put($path, $image->toPng(indexed: true));
return response()->file($storagePath);
}
/**
* Crea la imagen del avatar con las iniciales.
*
* @param string $name Nombre completo.
* @param string $color Color del texto.
* @param string $background Color de fondo.
* @param int $size Tamaño de la imagen.
*
* @return \Intervention\Image\Image La imagen generada.
*/
protected function createAvatarImage($name, $color, $background, $size)
{
$driver = config('image.driver', 'gd');
$manager = new ImageManager($driver);
$initials = self::getInitials($name);
$fontPath = __DIR__ . '/../storage/fonts/OpenSans-Bold.ttf';
$image = $manager->create($size, $size)
->fill($background);
$image->text(
$initials,
$size / 2,
$size / 2,
function (FontFactory $font) use ($color, $size, $fontPath) {
$font->file($fontPath);
$font->size($size * 0.4);
$font->color($color);
$font->align('center');
$font->valign('middle');
}
);
return $image;
}
/**
* Calcula las iniciales a partir del nombre.
*
* @param string $name Nombre completo.
*
* @return string Iniciales en mayúsculas.
*/
public static function getInitials($name)
{
if (empty($name)) {
return 'NA';
}
$initials = implode('', array_map(function ($word) {
return mb_substr($word, 0, 1);
}, explode(' ', $name)));
return strtoupper(substr($initials, 0, self::INITIAL_MAX_LENGTH));
}
/**
* Selecciona un color basado en el nombre.
*
* @param string $name Nombre del usuario.
*
* @return string Color seleccionado.
*/
public function getAvatarColor($name)
{
// Por ejemplo, se puede basar en la suma de los códigos ASCII de las letras del nombre
$hash = array_sum(array_map('ord', str_split($name)));
return self::AVATAR_COLORS[$hash % count(self::AVATAR_COLORS)];
}
}