feat: rewrite workshop_admin UI – remove adapter terminology, make configurations primary

Agent-Logs-Url: https://github.com/GameServerPanel/GSP/sessions/3fc88263-c1c0-46f6-95f1-7070fc6f9d02

Co-authored-by: iaretechnician <2749183+iaretechnician@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot] 2026-05-04 16:56:38 +00:00 committed by GitHub
parent e799f5ee5d
commit 86f825e388
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 98 additions and 80 deletions

View file

@ -31,9 +31,17 @@ class WorkshopProfileController
public function handle(): void public function handle(): void
{ {
global $db;
$userId = (int)($_SESSION['user_id'] ?? 0);
if (!$db->isAdmin($userId)) {
print_failure($this->lang['error_admin_only'] ?? 'Administrator access required.');
return;
}
echo '<link rel="stylesheet" type="text/css" href="modules/steam_workshop/steam_workshop.css" />'; echo '<link rel="stylesheet" type="text/css" href="modules/steam_workshop/steam_workshop.css" />';
$action = $_GET['sw_action'] ?? 'profiles'; $action = $_GET['sw_action'] ?? 'list';
if ($_SERVER['REQUEST_METHOD'] === 'POST') { if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$postAction = $_POST['sw_action'] ?? ''; $postAction = $_POST['sw_action'] ?? '';
@ -48,6 +56,7 @@ class WorkshopProfileController
} }
switch ($action) { switch ($action) {
case 'config_form':
case 'profile_form': case 'profile_form':
$this->handleForm((int)($_GET['profile_id'] ?? 0)); $this->handleForm((int)($_GET['profile_id'] ?? 0));
break; break;

View file

@ -105,54 +105,59 @@ return [
'error_missing_query' => 'Enter a search term before querying the Workshop.', 'error_missing_query' => 'Enter a search term before querying the Workshop.',
// ------------------------------------------------------- // -------------------------------------------------------
// Workshop profile admin (WorkshopProfileController) // Workshop game configuration admin (WorkshopProfileController)
// ------------------------------------------------------- // -------------------------------------------------------
'nav_workshop_profiles' => 'Workshop Profiles (DB)', 'config_heading_list' => 'Workshop Game Configurations',
'profile_heading_list' => 'Workshop Game Profiles', 'config_intro' => 'One configuration per supported game. Each configuration controls how SteamCMD downloads and installs Workshop mods for servers of that game type.',
'profile_intro' => 'One profile per supported game. Each profile drives mod install and caching behaviour.', 'config_btn_create' => 'Add Game Configuration',
'profile_btn_create' => 'Create Profile', 'config_list_empty' => 'No Workshop configurations defined yet. Add one for each game that supports Steam Workshop mods.',
'profile_list_empty' => 'No Workshop profiles defined yet.', 'config_confirm_delete' => 'Delete this Workshop configuration? Servers using it will no longer have Workshop mod support.',
'config_back_list' => 'Back to configurations',
'config_heading_edit' => 'Edit Workshop Configuration: %s',
'config_heading_create' => 'Add Workshop Game Configuration',
'config_steamcmd_heading' => 'How mods are downloaded',
'config_steamcmd_note' => 'Workshop mods are downloaded using SteamCMD with the command: +workshop_download_item {app_id} {mod_id}. The cache path below is where SteamCMD stores downloaded mod files on the agent machine. The install path below is where those files are copied into the game server directory.',
'config_label_app_id' => 'Steam App ID',
'config_hint_app_id' => 'The Steam App ID used with +workshop_download_item, e.g. 107410 for Arma 3',
'config_hint_game_key' => 'Short identifier matching the game XML key, e.g. arma3_linux',
'config_section_copy' => 'Copy / sync method',
'config_hint_launch_tpl' => 'Extra launch parameters added when this game has Workshop mods enabled. E.g. -mod=@{mod_id}',
'config_label_enabled' => 'Configuration enabled (allows servers to use Workshop mods for this game)',
'profile_col_game' => 'Game', 'profile_col_game' => 'Game',
'profile_col_key' => 'Game Key', 'profile_col_key' => 'Game Key',
'profile_col_method' => 'Copy Method', 'profile_col_method' => 'Install Method',
'profile_col_restart' => 'Restart?', 'profile_col_restart' => 'Restart?',
'profile_col_status' => 'Status', 'profile_col_status' => 'Status',
'profile_confirm_delete' => 'Delete this Workshop profile? This will not affect already-installed server mods.',
'profile_back_adapters' => 'Back to adapter management',
'profile_back_list' => 'Back to profiles',
'profile_heading_edit' => 'Edit Workshop Profile: %s',
'profile_heading_create' => 'Create Workshop Profile',
'profile_saved' => 'Workshop profile saved.',
'profile_save_error' => 'Failed to save Workshop profile.',
'profile_deleted' => 'Workshop profile deleted.',
'profile_delete_error' => 'Failed to delete Workshop profile.',
'profile_not_found' => 'Profile not found.',
'profile_section_basic' => 'Basic info', 'profile_section_basic' => 'Basic info',
'profile_section_paths' => 'Paths & templates', 'profile_section_paths' => 'Paths & templates',
'profile_section_copy' => 'Copy / sync method',
'profile_section_config' => 'Config & launch parameters', 'profile_section_config' => 'Config & launch parameters',
'profile_section_flags' => 'Flags', 'profile_section_flags' => 'Flags',
'profile_label_game_name' => 'Game name', 'profile_label_game_name' => 'Game name',
'profile_label_os' => 'Supported OS', 'profile_label_os' => 'Supported OS',
'profile_label_cache_path' => 'Cache path template', 'profile_label_cache_path' => 'SteamCMD cache path template',
'profile_hint_cache_path' => 'Where SteamCMD downloads mods on the agent. E.g. {steamcmd_path}/steamapps/workshop/content/{workshop_app_id}/{mod_id}', 'profile_hint_cache_path' => 'Where SteamCMD downloads mods on the agent. E.g. {steamcmd_path}/steamapps/workshop/content/{workshop_app_id}/{mod_id}',
'profile_label_install_path' => 'Install path template', 'profile_label_install_path' => 'Server install path template',
'profile_hint_install_path' => 'Server-side mod directory. E.g. {server_path}/mods/{mod_folder}', 'profile_hint_install_path' => 'Where mod files are placed inside the game server directory. E.g. {server_path}/mods/{mod_folder}',
'profile_label_folder_name' => 'Mod folder name template', 'profile_label_folder_name' => 'Mod folder name template',
'profile_hint_folder_name' => 'Folder name for each mod. Default: @{mod_id}', 'profile_hint_folder_name' => 'Folder name for each mod inside the install path. Default: @{mod_id}',
'profile_label_copy_method' => 'Copy method', 'profile_label_copy_method' => 'Method used to copy mod files from SteamCMD cache to the server',
'profile_label_install_script'=> 'Custom install script (admin-defined only, optional)', 'profile_label_install_script'=> 'Custom install script (optional, admin-defined)',
'profile_hint_install_script' => 'Only used when copy method is custom_script. Template variables are replaced before execution.', 'profile_hint_install_script' => 'Only used when copy method is custom_script. Template variables are replaced before execution.',
'profile_label_config_tpl' => 'Config file template (optional)', 'profile_label_config_tpl' => 'Config file template (optional)',
'profile_label_launch_tpl' => 'Launch parameter template (optional)', 'profile_label_launch_tpl' => 'Launch parameter template (optional)',
'profile_label_requires_restart' => 'Restart required after mod install/update', 'profile_label_requires_restart' => 'Server restart required after mod install or update',
'profile_label_enabled' => 'Profile enabled',
'profile_template_vars' => 'Available: {home_id} {agent_id} {workshop_app_id} {mod_id} {mod_title} {mod_folder} {steamcmd_path} {server_path} {install_path} {cache_path}', 'profile_template_vars' => 'Available: {home_id} {agent_id} {workshop_app_id} {mod_id} {mod_title} {mod_folder} {steamcmd_path} {server_path} {install_path} {cache_path}',
'profile_saved' => 'Workshop configuration saved.',
'profile_save_error' => 'Failed to save Workshop configuration.',
'profile_deleted' => 'Workshop configuration deleted.',
'profile_delete_error' => 'Failed to delete Workshop configuration.',
'profile_not_found' => 'Configuration not found.',
'button_delete' => 'Delete',
'error_game_key_invalid' => 'Game key may only contain letters, digits, underscores, dots, and hyphens.', 'error_game_key_invalid' => 'Game key may only contain letters, digits, underscores, dots, and hyphens.',
'error_game_name_required' => 'Game name is required.', 'error_game_name_required' => 'Game name is required.',
'error_app_id_required' => 'Workshop App ID is required (numeric).', 'error_app_id_required' => 'Workshop App ID is required (numeric).',
'error_cache_path_required' => 'Cache path template is required.', 'error_cache_path_required' => 'SteamCMD cache path template is required.',
'error_install_path_required' => 'Install path template is required.', 'error_install_path_required' => 'Server install path template is required.',
// ------------------------------------------------------- // -------------------------------------------------------
// User mod management (WorkshopModController) // User mod management (WorkshopModController)

View file

@ -584,3 +584,24 @@
color: #777; color: #777;
font-size: 0.9rem; font-size: 0.9rem;
} }
/* Info box used on the configuration form to explain SteamCMD usage */
.sw-info-box {
background: #e8f4fd;
border: 1px solid #b3d7f5;
border-radius: 4px;
padding: 0.75rem 1rem;
margin-bottom: 1.25rem;
font-size: 0.9rem;
}
.sw-info-box strong {
display: block;
margin-bottom: 0.25rem;
}
.sw-info-box p {
margin: 0;
color: #2c5f8a;
}

View file

@ -6,8 +6,8 @@ declare(strict_types=1);
$isEdit = $profileId > 0 && $profile !== null; $isEdit = $profileId > 0 && $profile !== null;
$heading = $isEdit $heading = $isEdit
? sprintf($lang['profile_heading_edit'] ?? 'Edit Workshop Profile: %s', htmlspecialchars($profile['game_name'] ?? '')) ? sprintf($lang['config_heading_edit'] ?? 'Edit Workshop Configuration: %s', htmlspecialchars($profile['game_name'] ?? ''))
: ($lang['profile_heading_create'] ?? 'Create Workshop Profile'); : ($lang['config_heading_create'] ?? 'Add Workshop Game Configuration');
$v = static function (string $key, array $profile, string $default = ''): string { $v = static function (string $key, array $profile, string $default = ''): string {
return htmlspecialchars((string)($profile[$key] ?? $default), ENT_QUOTES); return htmlspecialchars((string)($profile[$key] ?? $default), ENT_QUOTES);
@ -15,14 +15,19 @@ $v = static function (string $key, array $profile, string $default = ''): string
$osList = ['linux' => 'Linux', 'windows' => 'Windows']; $osList = ['linux' => 'Linux', 'windows' => 'Windows'];
$currentOs = array_filter(explode(',', (string)($profile['supported_os'] ?? 'linux'))); $currentOs = array_filter(explode(',', (string)($profile['supported_os'] ?? 'linux')));
$methodList = ['rsync' => 'rsync (Linux)', 'robocopy' => 'robocopy (Windows)', 'custom_script' => 'custom_script']; $methodList = ['rsync' => 'rsync (Linux)', 'robocopy' => 'robocopy (Windows)', 'custom_script' => 'Custom script'];
$curMethod = (string)($profile['copy_method'] ?? 'rsync'); $curMethod = (string)($profile['copy_method'] ?? 'rsync');
$tplVarNote = $lang['profile_template_vars'] ?? 'Available: {home_id} {agent_id} {workshop_app_id} {mod_id} {mod_title} {mod_folder} {steamcmd_path} {server_path} {install_path} {cache_path}'; $tplVarNote = $lang['profile_template_vars'] ?? 'Available: {home_id} {agent_id} {workshop_app_id} {mod_id} {mod_title} {mod_folder} {steamcmd_path} {server_path} {install_path} {cache_path}';
?> ?>
<div class="sw-admin sw-profile-form"> <div class="sw-admin sw-profile-form">
<h3><?php echo $heading; ?></h3> <h3><?php echo $heading; ?></h3>
<p><a href="?m=steam_workshop&p=workshop_admin&sw_action=profiles">&larr; <?php echo htmlspecialchars($lang['profile_back_list'] ?? 'Back to profiles'); ?></a></p> <p><a href="?m=steam_workshop&p=workshop_admin">&larr; <?php echo htmlspecialchars($lang['config_back_list'] ?? 'Back to configurations'); ?></a></p>
<div class="sw-info-box">
<strong><?php echo htmlspecialchars($lang['config_steamcmd_heading'] ?? 'How mods are downloaded'); ?></strong>
<p><?php echo htmlspecialchars($lang['config_steamcmd_note'] ?? 'Workshop mods are downloaded using SteamCMD: +workshop_download_item <App ID> <Mod ID>. The cache path below is where SteamCMD stores downloaded content on the agent. The install path is where the mod files are copied into the game server directory.'); ?></p>
</div>
<form method="post" action="?m=steam_workshop&p=workshop_admin" class="sw-form"> <form method="post" action="?m=steam_workshop&p=workshop_admin" class="sw-form">
<input type="hidden" name="sw_action" value="profile_save"> <input type="hidden" name="sw_action" value="profile_save">
@ -34,6 +39,7 @@ $tplVarNote = $lang['profile_template_vars'] ?? 'Available: {home_id} {agent_id
<div class="sw-form__grid"> <div class="sw-form__grid">
<label> <label>
<?php echo htmlspecialchars($lang['label_game_key'] ?? 'Game key'); ?> <em>*</em> <?php echo htmlspecialchars($lang['label_game_key'] ?? 'Game key'); ?> <em>*</em>
<small><?php echo htmlspecialchars($lang['config_hint_game_key'] ?? 'Short identifier matching the game XML key, e.g. arma3_linux'); ?></small>
<input type="text" name="game_key" value="<?php echo $v('game_key', $profile ?? []); ?>" <input type="text" name="game_key" value="<?php echo $v('game_key', $profile ?? []); ?>"
pattern="[A-Za-z0-9_\-.]+" required maxlength="100" pattern="[A-Za-z0-9_\-.]+" required maxlength="100"
<?php echo $isEdit ? 'readonly' : ''; ?>> <?php echo $isEdit ? 'readonly' : ''; ?>>
@ -44,7 +50,8 @@ $tplVarNote = $lang['profile_template_vars'] ?? 'Available: {home_id} {agent_id
required maxlength="255"> required maxlength="255">
</label> </label>
<label> <label>
<?php echo htmlspecialchars($lang['label_adapter_app_id'] ?? 'Workshop App ID'); ?> <em>*</em> <?php echo htmlspecialchars($lang['config_label_app_id'] ?? 'Steam App ID'); ?> <em>*</em>
<small><?php echo htmlspecialchars($lang['config_hint_app_id'] ?? 'The Steam App ID used with +workshop_download_item, e.g. 107410 for Arma 3'); ?></small>
<input type="text" name="workshop_app_id" <input type="text" name="workshop_app_id"
value="<?php echo $v('workshop_app_id', $profile ?? []); ?>" value="<?php echo $v('workshop_app_id', $profile ?? []); ?>"
pattern="[0-9]+" required maxlength="32"> pattern="[0-9]+" required maxlength="32">
@ -69,22 +76,22 @@ $tplVarNote = $lang['profile_template_vars'] ?? 'Available: {home_id} {agent_id
<small class="sw-hint"><?php echo htmlspecialchars($tplVarNote); ?></small> <small class="sw-hint"><?php echo htmlspecialchars($tplVarNote); ?></small>
<label> <label>
<?php echo htmlspecialchars($lang['profile_label_cache_path'] ?? 'Cache path template'); ?> <em>*</em> <?php echo htmlspecialchars($lang['profile_label_cache_path'] ?? 'SteamCMD cache path template'); ?> <em>*</em>
<small><?php echo htmlspecialchars($lang['profile_hint_cache_path'] ?? 'Where SteamCMD downloads mods on the agent. E.g. {steamcmd_path}/steamapps/workshop/content/{workshop_app_id}/{mod_id}'); ?></small> <small><?php echo htmlspecialchars($lang['profile_hint_cache_path'] ?? 'Where SteamCMD downloads mods on the agent. E.g. {steamcmd_path}/steamapps/workshop/content/{workshop_app_id}/{mod_id}'); ?></small>
<input type="text" name="cache_path_template" <input type="text" name="cache_path_template"
value="<?php echo $v('cache_path_template', $profile ?? []); ?>" required> value="<?php echo $v('cache_path_template', $profile ?? []); ?>" required>
</label> </label>
<label> <label>
<?php echo htmlspecialchars($lang['profile_label_install_path'] ?? 'Install path template'); ?> <em>*</em> <?php echo htmlspecialchars($lang['profile_label_install_path'] ?? 'Server install path template'); ?> <em>*</em>
<small><?php echo htmlspecialchars($lang['profile_hint_install_path'] ?? 'Server-side mod directory. E.g. {server_path}/mods/{mod_folder}'); ?></small> <small><?php echo htmlspecialchars($lang['profile_hint_install_path'] ?? 'Where mod files are placed inside the game server directory. E.g. {server_path}/mods/{mod_folder}'); ?></small>
<input type="text" name="install_path_template" <input type="text" name="install_path_template"
value="<?php echo $v('install_path_template', $profile ?? []); ?>" required> value="<?php echo $v('install_path_template', $profile ?? []); ?>" required>
</label> </label>
<label> <label>
<?php echo htmlspecialchars($lang['profile_label_folder_name'] ?? 'Mod folder name template'); ?> <?php echo htmlspecialchars($lang['profile_label_folder_name'] ?? 'Mod folder name template'); ?>
<small><?php echo htmlspecialchars($lang['profile_hint_folder_name'] ?? 'Folder name for each mod. Default: @{mod_id}'); ?></small> <small><?php echo htmlspecialchars($lang['profile_hint_folder_name'] ?? 'Folder name for each mod inside the install path. Default: @{mod_id}'); ?></small>
<input type="text" name="folder_name_template" <input type="text" name="folder_name_template"
value="<?php echo $v('folder_name_template', $profile ?? [], '@{mod_id}'); ?>"> value="<?php echo $v('folder_name_template', $profile ?? [], '@{mod_id}'); ?>">
</label> </label>
@ -92,9 +99,9 @@ $tplVarNote = $lang['profile_template_vars'] ?? 'Available: {home_id} {agent_id
<!-- Copy method --> <!-- Copy method -->
<fieldset> <fieldset>
<legend><?php echo htmlspecialchars($lang['profile_section_copy'] ?? 'Copy / sync method'); ?></legend> <legend><?php echo htmlspecialchars($lang['config_section_copy'] ?? 'Copy / sync method'); ?></legend>
<label> <label>
<?php echo htmlspecialchars($lang['profile_label_copy_method'] ?? 'Copy method'); ?> <?php echo htmlspecialchars($lang['profile_label_copy_method'] ?? 'Method used to copy mod files from SteamCMD cache to the server'); ?>
<select name="copy_method"> <select name="copy_method">
<?php foreach ($methodList as $mVal => $mLabel): ?> <?php foreach ($methodList as $mVal => $mLabel): ?>
<option value="<?php echo $mVal; ?>" <?php echo $curMethod === $mVal ? 'selected' : ''; ?>> <option value="<?php echo $mVal; ?>" <?php echo $curMethod === $mVal ? 'selected' : ''; ?>>
@ -105,7 +112,7 @@ $tplVarNote = $lang['profile_template_vars'] ?? 'Available: {home_id} {agent_id
</label> </label>
<label> <label>
<?php echo htmlspecialchars($lang['profile_label_install_script'] ?? 'Custom install script (admin-defined only, optional)'); ?> <?php echo htmlspecialchars($lang['profile_label_install_script'] ?? 'Custom install script (optional, admin-defined)'); ?>
<small><?php echo htmlspecialchars($lang['profile_hint_install_script'] ?? 'Only used when copy method is custom_script. Template variables are replaced before execution.'); ?></small> <small><?php echo htmlspecialchars($lang['profile_hint_install_script'] ?? 'Only used when copy method is custom_script. Template variables are replaced before execution.'); ?></small>
<textarea name="install_script" rows="4"><?php echo $v('install_script', $profile ?? []); ?></textarea> <textarea name="install_script" rows="4"><?php echo $v('install_script', $profile ?? []); ?></textarea>
</label> </label>
@ -120,6 +127,7 @@ $tplVarNote = $lang['profile_template_vars'] ?? 'Available: {home_id} {agent_id
</label> </label>
<label> <label>
<?php echo htmlspecialchars($lang['profile_label_launch_tpl'] ?? 'Launch parameter template (optional)'); ?> <?php echo htmlspecialchars($lang['profile_label_launch_tpl'] ?? 'Launch parameter template (optional)'); ?>
<small><?php echo htmlspecialchars($lang['config_hint_launch_tpl'] ?? 'Extra launch parameters added when this game has Workshop mods enabled. E.g. -mod=@{mod_id}'); ?></small>
<input type="text" name="launch_param_template" <input type="text" name="launch_param_template"
value="<?php echo $v('launch_param_template', $profile ?? []); ?>"> value="<?php echo $v('launch_param_template', $profile ?? []); ?>">
</label> </label>
@ -131,12 +139,12 @@ $tplVarNote = $lang['profile_template_vars'] ?? 'Available: {home_id} {agent_id
<label class="sw-checkbox"> <label class="sw-checkbox">
<input type="checkbox" name="requires_restart" value="1" <input type="checkbox" name="requires_restart" value="1"
<?php echo !empty($profile['requires_restart']) ? 'checked' : ''; ?>> <?php echo !empty($profile['requires_restart']) ? 'checked' : ''; ?>>
<span><?php echo htmlspecialchars($lang['profile_label_requires_restart'] ?? 'Restart required after mod install/update'); ?></span> <span><?php echo htmlspecialchars($lang['profile_label_requires_restart'] ?? 'Server restart required after mod install or update'); ?></span>
</label> </label>
<label class="sw-checkbox"> <label class="sw-checkbox">
<input type="checkbox" name="enabled" value="1" <input type="checkbox" name="enabled" value="1"
<?php echo ($profile['enabled'] ?? 1) ? 'checked' : ''; ?>> <?php echo ($profile['enabled'] ?? 1) ? 'checked' : ''; ?>>
<span><?php echo htmlspecialchars($lang['profile_label_enabled'] ?? 'Profile enabled'); ?></span> <span><?php echo htmlspecialchars($lang['config_label_enabled'] ?? 'Configuration enabled (allows servers to use Workshop mods for this game)'); ?></span>
</label> </label>
</fieldset> </fieldset>
@ -144,7 +152,7 @@ $tplVarNote = $lang['profile_template_vars'] ?? 'Available: {home_id} {agent_id
<button class="btn primary" type="submit"> <button class="btn primary" type="submit">
<?php echo htmlspecialchars($lang['button_save'] ?? 'Save'); ?> <?php echo htmlspecialchars($lang['button_save'] ?? 'Save'); ?>
</button> </button>
<a class="btn" href="?m=steam_workshop&p=workshop_admin&sw_action=profiles"> <a class="btn" href="?m=steam_workshop&p=workshop_admin">
<?php echo htmlspecialchars($lang['button_cancel'] ?? 'Cancel'); ?> <?php echo htmlspecialchars($lang['button_cancel'] ?? 'Cancel'); ?>
</a> </a>
</div> </div>

View file

@ -5,15 +5,15 @@ declare(strict_types=1);
?> ?>
<div class="sw-admin sw-profiles"> <div class="sw-admin sw-profiles">
<div class="sw-admin__intro"> <div class="sw-admin__intro">
<h3><?php echo htmlspecialchars($lang['profile_heading_list'] ?? 'Workshop Game Profiles'); ?></h3> <h3><?php echo htmlspecialchars($lang['config_heading_list'] ?? 'Workshop Game Configurations'); ?></h3>
<p><?php echo htmlspecialchars($lang['profile_intro'] ?? 'One profile per supported game. Each profile drives mod install and caching behaviour.'); ?></p> <p><?php echo htmlspecialchars($lang['config_intro'] ?? 'One configuration per supported game. Each configuration controls how SteamCMD downloads and installs Workshop mods for servers of that game type.'); ?></p>
<a class="btn primary" href="?m=steam_workshop&p=workshop_admin&sw_action=profile_form"> <a class="btn primary" href="?m=steam_workshop&p=workshop_admin&sw_action=config_form">
<?php echo htmlspecialchars($lang['profile_btn_create'] ?? 'Create Profile'); ?> <?php echo htmlspecialchars($lang['config_btn_create'] ?? 'Add Game Configuration'); ?>
</a> </a>
</div> </div>
<?php if (empty($profiles)): ?> <?php if (empty($profiles)): ?>
<p class="sw-empty"><?php echo htmlspecialchars($lang['profile_list_empty'] ?? 'No Workshop profiles defined yet.'); ?></p> <p class="sw-empty"><?php echo htmlspecialchars($lang['config_list_empty'] ?? 'No Workshop configurations defined yet. Add one for each game that supports Steam Workshop mods.'); ?></p>
<?php else: ?> <?php else: ?>
<table class="table sw-profiles__table"> <table class="table sw-profiles__table">
<thead> <thead>
@ -22,7 +22,7 @@ declare(strict_types=1);
<th><?php echo htmlspecialchars($lang['profile_col_key'] ?? 'Game Key'); ?></th> <th><?php echo htmlspecialchars($lang['profile_col_key'] ?? 'Game Key'); ?></th>
<th>App ID</th> <th>App ID</th>
<th>OS</th> <th>OS</th>
<th><?php echo htmlspecialchars($lang['profile_col_method'] ?? 'Copy Method'); ?></th> <th><?php echo htmlspecialchars($lang['profile_col_method'] ?? 'Install Method'); ?></th>
<th><?php echo htmlspecialchars($lang['profile_col_restart'] ?? 'Restart?'); ?></th> <th><?php echo htmlspecialchars($lang['profile_col_restart'] ?? 'Restart?'); ?></th>
<th><?php echo htmlspecialchars($lang['profile_col_status'] ?? 'Status'); ?></th> <th><?php echo htmlspecialchars($lang['profile_col_status'] ?? 'Status'); ?></th>
<th><?php echo htmlspecialchars($lang['admin_col_actions'] ?? 'Actions'); ?></th> <th><?php echo htmlspecialchars($lang['admin_col_actions'] ?? 'Actions'); ?></th>
@ -36,7 +36,7 @@ declare(strict_types=1);
<td><?php echo htmlspecialchars($profile['workshop_app_id']); ?></td> <td><?php echo htmlspecialchars($profile['workshop_app_id']); ?></td>
<td><?php echo htmlspecialchars($profile['supported_os']); ?></td> <td><?php echo htmlspecialchars($profile['supported_os']); ?></td>
<td><?php echo htmlspecialchars($profile['copy_method']); ?></td> <td><?php echo htmlspecialchars($profile['copy_method']); ?></td>
<td><?php echo $profile['requires_restart'] ? '✔' : '✘'; ?></td> <td><?php echo $profile['requires_restart'] ? '&#10004;' : '&#10008;'; ?></td>
<td> <td>
<?php if ($profile['enabled']): ?> <?php if ($profile['enabled']): ?>
<span class="sw-badge sw-badge--enabled"><?php echo htmlspecialchars($lang['status_enabled'] ?? 'Enabled'); ?></span> <span class="sw-badge sw-badge--enabled"><?php echo htmlspecialchars($lang['status_enabled'] ?? 'Enabled'); ?></span>
@ -46,15 +46,15 @@ declare(strict_types=1);
</td> </td>
<td class="sw-actions"> <td class="sw-actions">
<a class="btn secondary" <a class="btn secondary"
href="?m=steam_workshop&p=workshop_admin&sw_action=profile_form&profile_id=<?php echo (int)$profile['id']; ?>"> href="?m=steam_workshop&p=workshop_admin&sw_action=config_form&profile_id=<?php echo (int)$profile['id']; ?>">
<?php echo htmlspecialchars($lang['button_edit'] ?? 'Edit'); ?> <?php echo htmlspecialchars($lang['button_edit'] ?? 'Edit'); ?>
</a> </a>
<form method="post" action="?m=steam_workshop&p=workshop_admin" class="sw-inline-delete"> <form method="post" action="?m=steam_workshop&p=workshop_admin" class="sw-inline-delete">
<input type="hidden" name="sw_action" value="profile_delete"> <input type="hidden" name="sw_action" value="profile_delete">
<input type="hidden" name="profile_id" value="<?php echo (int)$profile['id']; ?>"> <input type="hidden" name="profile_id" value="<?php echo (int)$profile['id']; ?>">
<button type="submit" class="btn danger" <button type="submit" class="btn danger"
onclick="return confirm('<?php echo htmlspecialchars($lang['profile_confirm_delete'] ?? 'Delete this Workshop profile?'); ?>')"> onclick="return confirm('<?php echo htmlspecialchars($lang['config_confirm_delete'] ?? 'Delete this Workshop configuration? Servers using it will no longer have Workshop mod support.'); ?>')">
<?php echo htmlspecialchars($lang['button_delete_adapter'] ?? 'Delete'); ?> <?php echo htmlspecialchars($lang['button_delete'] ?? 'Delete'); ?>
</button> </button>
</form> </form>
</td> </td>
@ -63,11 +63,4 @@ declare(strict_types=1);
</tbody> </tbody>
</table> </table>
<?php endif; ?> <?php endif; ?>
<hr>
<p>
<a href="?m=steam_workshop&p=workshop_admin">&larr;
<?php echo htmlspecialchars($lang['profile_back_adapters'] ?? 'Back to adapter management'); ?>
</a>
</p>
</div> </div>

View file

@ -1,7 +1,6 @@
<?php <?php
declare(strict_types=1); declare(strict_types=1);
require_once __DIR__ . '/controllers/AdminWorkshopController.php';
require_once __DIR__ . '/controllers/WorkshopProfileController.php'; require_once __DIR__ . '/controllers/WorkshopProfileController.php';
function exec_ogp_module(): void function exec_ogp_module(): void
@ -9,23 +8,6 @@ function exec_ogp_module(): void
global $db; global $db;
echo '<h2>' . get_lang('steam_workshop') . '</h2>'; echo '<h2>' . get_lang('steam_workshop') . '</h2>';
// Route to the DB-driven profile manager when requested $controller = new WorkshopProfileController($db);
$swAction = $_GET['sw_action'] ?? '';
$profileActions = ['profiles', 'profile_form'];
$postAction = $_POST['sw_action'] ?? '';
$profilePostActions = ['profile_save', 'profile_delete'];
if (in_array($swAction, $profileActions, true) || in_array($postAction, $profilePostActions, true)) {
$controller = new WorkshopProfileController($db);
$controller->handle();
return;
}
// Default: legacy XML adapter manager + tab link to profiles
echo '<p><a class="btn secondary" href="?m=steam_workshop&p=workshop_admin&sw_action=profiles">'
. (function_exists('get_lang') ? get_lang('nav_workshop_profiles') : 'Workshop Profiles')
. '</a></p>';
$controller = new AdminWorkshopController($db);
$controller->handle(); $controller->handle();
} }