125 lines
3.7 KiB
PHP
125 lines
3.7 KiB
PHP
|
<?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)];
|
||
|
}
|
||
|
}
|