query('SELECT DATABASE()')->fetchColumn(); if ($database === '') { return false; } $stmt = $pdo->prepare( 'SELECT COUNT(*) FROM information_schema.columns WHERE table_schema = :schema AND table_name = :table AND column_name = :column' ); $stmt->execute([ ':schema' => $database, ':table' => 'users', ':column' => $columnName, ]); return (int)$stmt->fetchColumn() > 0; } catch (Throwable $e) { return false; } } function og_ensure_users_avatar_column(PDO $pdo): bool { if (og_users_has_column($pdo, 'profile_avatar_file')) { return true; } try { $pdo->exec('ALTER TABLE users ADD COLUMN profile_avatar_file VARCHAR(255) NULL AFTER phone_number'); } catch (Throwable $e) { return og_users_has_column($pdo, 'profile_avatar_file'); } return og_users_has_column($pdo, 'profile_avatar_file'); } function og_get_user_avatar_file(PDO $pdo, int $userId): ?string { if (!og_users_has_column($pdo, 'profile_avatar_file')) { return null; } try { $stmt = $pdo->prepare('SELECT profile_avatar_file FROM users WHERE id = ? LIMIT 1'); $stmt->execute([$userId]); $value = $stmt->fetchColumn(); if (!is_string($value)) { return null; } $file = trim($value); if ($file === '') { return null; } if (!preg_match('/^[A-Za-z0-9._-]{1,255}$/', $file)) { return null; } return $file; } catch (Throwable $e) { return null; } } function og_avatar_file_to_url(?string $avatarFile): ?string { $file = trim((string)$avatarFile); if ($file === '') { return null; } if (!preg_match('/^[A-Za-z0-9._-]{1,255}$/', $file)) { return null; } return '/account/avatar.php?f=' . rawurlencode($file); } function og_avatar_initial(?string $username): string { $name = trim((string)$username); if ($name === '') { return '?'; } if (function_exists('mb_substr') && function_exists('mb_strtoupper')) { return mb_strtoupper(mb_substr($name, 0, 1, 'UTF-8'), 'UTF-8'); } return strtoupper(substr($name, 0, 1)); }