Files
papa-kind-treff.info/src/App/ProfileSettings.php
Lars Gebhardt-Kusche aa86001760
All checks were successful
Deploy / deploy (push) Successful in 1m7s
avatar
2026-07-28 02:03:01 +02:00

150 lines
6.7 KiB
PHP

<?php
declare(strict_types=1);
namespace App;
use App\Avatar\AvatarManager;
use App\Avatar\Lorelei;
final class ProfileSettings
{
private bool $schemaEnsured = false;
private array $columnCache = [];
public function __construct(private \PDO $pdo)
{
}
public function ensureSchema(): void
{
if ($this->schemaEnsured) {
return;
}
if (!$this->hasColumn('user_profiles', 'location_tracking_preference')) {
$this->pdo->exec(
"ALTER TABLE user_profiles
ADD COLUMN location_tracking_preference ENUM('disabled','prompt','enabled')
NOT NULL DEFAULT 'prompt'
AFTER lng"
);
$this->columnCache['user_profiles.location_tracking_preference'] = true;
}
$avatarColumns = [
'avatar_style' => "ALTER TABLE user_profiles ADD COLUMN avatar_style VARCHAR(40) NOT NULL DEFAULT 'lorelei' AFTER location_tracking_preference",
'avatar_seed' => "ALTER TABLE user_profiles ADD COLUMN avatar_seed VARCHAR(100) NOT NULL DEFAULT '' AFTER avatar_style",
'avatar_config_json' => "ALTER TABLE user_profiles ADD COLUMN avatar_config_json TEXT NULL AFTER avatar_seed",
'avatar_preset' => "ALTER TABLE user_profiles ADD COLUMN avatar_preset VARCHAR(64) NOT NULL DEFAULT 'papa-kind-treff' AFTER location_tracking_preference",
'avatar_lorelei_eyes_variant' => "ALTER TABLE user_profiles ADD COLUMN avatar_lorelei_eyes_variant VARCHAR(24) NOT NULL DEFAULT '' AFTER avatar_preset",
'avatar_lorelei_eyebrows_variant' => "ALTER TABLE user_profiles ADD COLUMN avatar_lorelei_eyebrows_variant VARCHAR(24) NOT NULL DEFAULT '' AFTER avatar_lorelei_eyes_variant",
'avatar_lorelei_mouth_variant' => "ALTER TABLE user_profiles ADD COLUMN avatar_lorelei_mouth_variant VARCHAR(24) NOT NULL DEFAULT '' AFTER avatar_lorelei_eyebrows_variant",
'avatar_lorelei_glasses_variant' => "ALTER TABLE user_profiles ADD COLUMN avatar_lorelei_glasses_variant VARCHAR(24) NOT NULL DEFAULT '' AFTER avatar_lorelei_mouth_variant",
'avatar_lorelei_hair_variant' => "ALTER TABLE user_profiles ADD COLUMN avatar_lorelei_hair_variant VARCHAR(24) NOT NULL DEFAULT '' AFTER avatar_lorelei_glasses_variant",
'avatar_lorelei_beard_variant' => "ALTER TABLE user_profiles ADD COLUMN avatar_lorelei_beard_variant VARCHAR(24) NOT NULL DEFAULT '' AFTER avatar_lorelei_hair_variant",
'avatar_lorelei_earrings_variant' => "ALTER TABLE user_profiles ADD COLUMN avatar_lorelei_earrings_variant VARCHAR(24) NOT NULL DEFAULT '' AFTER avatar_lorelei_beard_variant",
];
foreach ($avatarColumns as $column => $sql) {
if (!$this->hasColumn('user_profiles', $column)) {
$this->pdo->exec($sql);
$this->columnCache['user_profiles.' . $column] = true;
}
}
$this->schemaEnsured = true;
}
public function getLocationTrackingPreference(int $userId): string
{
if ($userId <= 0) {
return 'prompt';
}
$this->ensureSchema();
$stmt = $this->pdo->prepare('SELECT location_tracking_preference FROM user_profiles WHERE user_id = :id LIMIT 1');
$stmt->execute(['id' => $userId]);
$value = (string)($stmt->fetchColumn() ?: 'prompt');
return in_array($value, ['disabled', 'prompt', 'enabled'], true) ? $value : 'prompt';
}
public function updateLocationTrackingPreference(int $userId, string $preference): void
{
if ($userId <= 0) {
return;
}
$this->ensureSchema();
$preference = in_array($preference, ['disabled', 'prompt', 'enabled'], true) ? $preference : 'prompt';
$stmt = $this->pdo->prepare('UPDATE user_profiles SET location_tracking_preference = :pref, updated_at = NOW() WHERE user_id = :id');
$stmt->execute([
'pref' => $preference,
'id' => $userId,
]);
}
public function updateAvatar(int $userId, array $avatarConfig): void
{
if ($userId <= 0) {
return;
}
$this->ensureSchema();
$avatar = AvatarManager::normalizeSubmission($avatarConfig, $userId);
$legacy = $avatar['avatar_style'] === Lorelei::key()
? Lorelei::legacyColumnsFromConfig($avatar['avatar_seed'], $avatar['avatar_config_array'])
: Lorelei::legacyColumnsFromConfig($avatar['avatar_seed'], Lorelei::defaultConfig());
$stmt = $this->pdo->prepare(
'UPDATE user_profiles
SET avatar_style = :avatarStyle,
avatar_seed = :avatarSeed,
avatar_config_json = :avatarConfigJson,
avatar_preset = :preset,
avatar_lorelei_eyes_variant = :eyesVariant,
avatar_lorelei_eyebrows_variant = :eyebrowsVariant,
avatar_lorelei_mouth_variant = :mouthVariant,
avatar_lorelei_glasses_variant = :glassesVariant,
avatar_lorelei_hair_variant = :hairVariant,
avatar_lorelei_beard_variant = :beardVariant,
avatar_lorelei_earrings_variant = :earringsVariant,
updated_at = NOW()
WHERE user_id = :id'
);
$stmt->execute([
'avatarStyle' => $avatar['avatar_style'],
'avatarSeed' => $avatar['avatar_seed'],
'avatarConfigJson' => $avatar['avatar_config_json'],
'preset' => $legacy['avatar_preset'],
'eyesVariant' => $legacy['avatar_lorelei_eyes_variant'],
'eyebrowsVariant' => $legacy['avatar_lorelei_eyebrows_variant'],
'mouthVariant' => $legacy['avatar_lorelei_mouth_variant'],
'glassesVariant' => $legacy['avatar_lorelei_glasses_variant'],
'hairVariant' => $legacy['avatar_lorelei_hair_variant'],
'beardVariant' => $legacy['avatar_lorelei_beard_variant'],
'earringsVariant' => $legacy['avatar_lorelei_earrings_variant'],
'id' => $userId,
]);
}
private function hasColumn(string $table, string $column): bool
{
$cacheKey = $table . '.' . $column;
if (array_key_exists($cacheKey, $this->columnCache)) {
return $this->columnCache[$cacheKey];
}
$stmt = $this->pdo->prepare("
SELECT COUNT(*)
FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = :tableName
AND COLUMN_NAME = :columnName
");
$stmt->execute([
'tableName' => $table,
'columnName' => $column,
]);
return $this->columnCache[$cacheKey] = ((int)$stmt->fetchColumn() > 0);
}
}