All checks were successful
Deploy / deploy (push) Successful in 1m5s
260 lines
7.9 KiB
PHP
260 lines
7.9 KiB
PHP
<?php
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Avatar;
|
|
|
|
final class Croodles
|
|
{
|
|
public static function key(): string
|
|
{
|
|
return 'croodles';
|
|
}
|
|
|
|
public static function label(): string
|
|
{
|
|
return 'Croodles';
|
|
}
|
|
|
|
public static function defaultSeed(): string
|
|
{
|
|
return 'papa-kind-treff';
|
|
}
|
|
|
|
public static function defaultConfig(): array
|
|
{
|
|
return array_merge([
|
|
'beardVariant' => '',
|
|
'eyesVariant' => '',
|
|
'headVariant' => '',
|
|
'mouthVariant' => '',
|
|
'mustacheVariant' => '',
|
|
'noseVariant' => '',
|
|
'topVariant' => '',
|
|
'baseColor' => '',
|
|
'eyepatchColor' => '',
|
|
'glassesColor' => '',
|
|
'topColor' => '',
|
|
'backgroundColor' => '',
|
|
], self::colorCompanionDefaults());
|
|
}
|
|
|
|
public static function options(): array
|
|
{
|
|
return [
|
|
'beardVariant' => ['' => 'Keine'] + self::variantOptions(5),
|
|
'eyesVariant' => ['' => 'Keine'] + self::variantOptions(16),
|
|
'headVariant' => ['' => 'Keine'] + self::variantOptions(8),
|
|
'mouthVariant' => ['' => 'Keine'] + self::variantOptions(18),
|
|
'mustacheVariant' => ['' => 'Keine'] + self::variantOptions(4),
|
|
'noseVariant' => ['' => 'Keine'] + self::variantOptions(9),
|
|
'topVariant' => ['' => 'Keine'] + self::variantOptions(29),
|
|
];
|
|
}
|
|
|
|
public static function componentDefinitions(): array
|
|
{
|
|
return [
|
|
'headVariant' => ['label' => 'Kopf'],
|
|
'eyesVariant' => ['label' => 'Augen'],
|
|
'noseVariant' => ['label' => 'Nase'],
|
|
'mouthVariant' => ['label' => 'Mund'],
|
|
'topVariant' => ['label' => 'Top'],
|
|
'beardVariant' => ['label' => 'Bart'],
|
|
'mustacheVariant' => ['label' => 'Schnurrbart'],
|
|
];
|
|
}
|
|
|
|
public static function colorDefinitions(): array
|
|
{
|
|
return [
|
|
'baseColor' => ['label' => 'Basisfarbe', 'default' => '#e7ba9a'],
|
|
'eyepatchColor' => ['label' => 'Augenklappe', 'default' => '#283341'],
|
|
'glassesColor' => ['label' => 'Brille', 'default' => '#283341'],
|
|
'topColor' => ['label' => 'Top-Farbe', 'default' => '#4f6ea8'],
|
|
'backgroundColor' => ['label' => 'Hintergrund', 'default' => '#f2eadf'],
|
|
];
|
|
}
|
|
|
|
public static function normalizeSeed(string $seed): string
|
|
{
|
|
$seed = strtolower(trim($seed));
|
|
$seed = preg_replace('/[^a-z0-9]+/', '-', $seed) ?: '';
|
|
$seed = trim($seed, '-');
|
|
|
|
if ($seed === '') {
|
|
$seed = self::defaultSeed();
|
|
}
|
|
|
|
return substr($seed, 0, 100);
|
|
}
|
|
|
|
public static function normalizeConfig(array $input): array
|
|
{
|
|
$defaults = self::defaultConfig();
|
|
$normalized = [];
|
|
|
|
foreach ($defaults as $key => $defaultValue) {
|
|
if (array_key_exists($key, self::colorDefinitions())) {
|
|
$normalized[$key] = self::normalizeColor((string)($input[$key] ?? $defaultValue));
|
|
continue;
|
|
}
|
|
if (str_ends_with($key, 'Fill')) {
|
|
$normalized[$key] = self::normalizeFill((string)($input[$key] ?? $defaultValue));
|
|
continue;
|
|
}
|
|
if (str_ends_with($key, 'FillStops')) {
|
|
$normalized[$key] = self::normalizeFillStops($input[$key] ?? $defaultValue);
|
|
continue;
|
|
}
|
|
if (str_ends_with($key, 'Angle')) {
|
|
$normalized[$key] = self::normalizeAngle($input[$key] ?? $defaultValue);
|
|
continue;
|
|
}
|
|
|
|
$normalized[$key] = self::normalizeVariant((string)($input[$key] ?? $defaultValue));
|
|
}
|
|
|
|
return $normalized;
|
|
}
|
|
|
|
public static function buildQuery(string $seed, array $config): array
|
|
{
|
|
$config = self::normalizeConfig($config);
|
|
$query = ['seed' => self::normalizeSeed($seed)];
|
|
$componentFields = array_keys(self::componentDefinitions());
|
|
|
|
foreach ($componentFields as $field) {
|
|
$probability = preg_replace('/Variant$/', 'Probability', $field);
|
|
if ($config[$field] === '') {
|
|
$query[$probability] = '0';
|
|
continue;
|
|
}
|
|
|
|
$query[$field] = $config[$field];
|
|
$query[$probability] = '100';
|
|
}
|
|
|
|
foreach (array_keys(self::colorDefinitions()) as $field) {
|
|
if ($config[$field] !== '') {
|
|
$query[$field] = $config[$field];
|
|
foreach (self::colorCompanionFields($field) as $companionField) {
|
|
if ($config[$companionField] !== '') {
|
|
$query[$companionField] = $config[$companionField];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return $query;
|
|
}
|
|
|
|
public static function queryToConfig(array $query): array
|
|
{
|
|
$config = self::defaultConfig();
|
|
|
|
foreach (array_keys(self::componentDefinitions()) as $field) {
|
|
$config[$field] = self::normalizeVariant((string)($query[$field] ?? ''));
|
|
$probability = (int)($query[preg_replace('/Variant$/', 'Probability', $field)] ?? 100);
|
|
if ($probability <= 0) {
|
|
$config[$field] = '';
|
|
}
|
|
}
|
|
|
|
foreach (array_keys(self::colorDefinitions()) as $field) {
|
|
$config[$field] = self::normalizeColor((string)($query[$field] ?? ''));
|
|
foreach (self::colorCompanionFields($field) as $companionField) {
|
|
$config[$companionField] = (string)($query[$companionField] ?? '');
|
|
}
|
|
}
|
|
|
|
return self::normalizeConfig($config);
|
|
}
|
|
|
|
public static function fallbackSvg(string $seed, string $label = 'Avatar'): string
|
|
{
|
|
return Lorelei::fallbackSvg($seed, $label);
|
|
}
|
|
|
|
private static function normalizeVariant(string $value): string
|
|
{
|
|
$value = strtolower(trim($value));
|
|
if ($value === '') {
|
|
return '';
|
|
}
|
|
|
|
return preg_match('/^variant\d{2}$/', $value) === 1 ? $value : '';
|
|
}
|
|
|
|
private static function normalizeColor(string $value): string
|
|
{
|
|
$value = strtolower(trim($value));
|
|
if ($value === '') {
|
|
return '';
|
|
}
|
|
|
|
return preg_match('/^#[0-9a-f]{6}$/', $value) === 1 ? $value : '';
|
|
}
|
|
|
|
private static function normalizeFill(string $value): string
|
|
{
|
|
$value = strtolower(trim($value));
|
|
if ($value === '') {
|
|
return '';
|
|
}
|
|
|
|
return in_array($value, ['solid', 'linear', 'radial'], true) ? $value : '';
|
|
}
|
|
|
|
private static function normalizeFillStops(mixed $value): string
|
|
{
|
|
if ($value === '' || $value === null) {
|
|
return '';
|
|
}
|
|
|
|
$number = max(2, min(8, (int)$value));
|
|
return (string)$number;
|
|
}
|
|
|
|
private static function normalizeAngle(mixed $value): string
|
|
{
|
|
if ($value === '' || $value === null) {
|
|
return '';
|
|
}
|
|
|
|
$number = max(-360, min(360, (int)$value));
|
|
return (string)$number;
|
|
}
|
|
|
|
private static function colorCompanionDefaults(): array
|
|
{
|
|
$defaults = [];
|
|
foreach (array_keys(self::colorDefinitions()) as $field) {
|
|
foreach (self::colorCompanionFields($field) as $companionField) {
|
|
$defaults[$companionField] = '';
|
|
}
|
|
}
|
|
|
|
return $defaults;
|
|
}
|
|
|
|
private static function colorCompanionFields(string $field): array
|
|
{
|
|
return [
|
|
$field . 'Fill',
|
|
$field . 'FillStops',
|
|
$field . 'Angle',
|
|
];
|
|
}
|
|
|
|
private static function variantOptions(int $count): array
|
|
{
|
|
$options = [];
|
|
for ($index = 1; $index <= $count; $index++) {
|
|
$key = sprintf('variant%02d', $index);
|
|
$options[$key] = 'Variante ' . $index;
|
|
}
|
|
|
|
return $options;
|
|
}
|
|
}
|