All checks were successful
Deploy / deploy (push) Successful in 1m7s
150 lines
6.7 KiB
PHP
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);
|
|
}
|
|
}
|