permissions->current_user_has_any()) { wp_die(esc_html__('You do not have permission to access this page.', 'support-provisioning-portal')); } $can_view_portal = $this->permissions->current_user_has(SPP_Permissions::VIEW_PORTAL); $can_manage_templates = $this->permissions->current_user_has(SPP_Permissions::MANAGE_TEMPLATES); $can_manage_settings = $this->permissions->current_user_has(SPP_Permissions::MANAGE_SETTINGS); $can_manage_permissions = $this->permissions->current_user_has(SPP_Permissions::MANAGE_PERMISSIONS); ?>

render_notices(); ?>
render_app_root(); } else { $this->render_admin_only_notice(); } ?>
render_settings(); ?>
render_template_management(); } if ($can_manage_permissions) { $this->render_user_access_management(); } ?>
__('Settings saved.', 'support-provisioning-portal'), 'template_saved' => __('Template saved.', 'support-provisioning-portal'), 'template_removed' => __('Template removed from new provisioning.', 'support-provisioning-portal'), 'template_error' => __('Template could not be saved. Check the fields and confirm the VMID exists as a Proxmox QEMU template on the configured node.', 'support-provisioning-portal'), 'user_access_saved' => __('User rights saved.', 'support-provisioning-portal'), 'manager_required' => __('At least one user must keep the Manage user rights permission.', 'support-provisioning-portal'), ]; if (!isset($messages[$notice])) { return; } $class = in_array($notice, ['manager_required', 'template_error'], true) ? 'notice notice-error' : 'notice notice-success'; printf( '

%s

', esc_attr($class), esc_html($messages[$notice]) ); } private function render_admin_only_notice(): void { ?>

repository->admin_templates(); $active_proxmox_ids = $this->repository->active_proxmox_template_ids(); $proxmox_error = null; try { $proxmox_templates = $this->proxmox->list_templates(); } catch (Throwable $error) { $proxmox_templates = []; $proxmox_error = $error->getMessage(); } ?>

CPU cores Memory MB Disk GB Status

users_for_access_table($search); $definitions = SPP_Permissions::definitions(); ?>

permissions->user_ids_with_permission(SPP_Permissions::MANAGE_PERMISSIONS))) : ?>

permissions->for_user((int) $user->ID); $quota = get_user_meta((int) $user->ID, 'spp_memory_quota_mb', true); ?>
display_name !== '' ? $user->display_name : $user->user_login); ?>
$permissions) : ?>
permissions->current_user_has(SPP_Permissions::MANAGE_SETTINGS)) { wp_die(esc_html__('You do not have permission to save these settings.', 'support-provisioning-portal')); } check_admin_referer('spp_save_settings'); update_option('spp_proxmox_mode', $this->posted_string('spp_proxmox_mode') === 'http' ? 'http' : 'mock'); update_option('spp_proxmox_base_url', $this->sanitize_proxmox_base_url($this->posted_string('spp_proxmox_base_url'))); update_option('spp_proxmox_token_id', sanitize_text_field($this->posted_string('spp_proxmox_token_id'))); $token_secret = sanitize_text_field($this->posted_string('spp_proxmox_token_secret')); if ($token_secret !== '') { update_option('spp_proxmox_token_secret', $token_secret); } update_option('spp_proxmox_node', sanitize_text_field($this->posted_string('spp_proxmox_node'))); update_option('spp_quota_user_memory_mb', max(0, absint($this->posted_string('spp_quota_user_memory_mb')))); update_option('spp_quota_global_memory_mb', max(0, absint($this->posted_string('spp_quota_global_memory_mb')))); $this->redirect_to_admin_page('settings_saved'); } public function save_template(): void { if (!$this->permissions->current_user_has(SPP_Permissions::MANAGE_TEMPLATES)) { wp_die(esc_html__('You do not have permission to save templates.', 'support-provisioning-portal')); } check_admin_referer('spp_save_template'); $template_id = absint($this->posted_string('spp_template_id')); $action = sanitize_key($this->posted_string('spp_template_action')); if ($action === 'remove') { if ($template_id < 1) { $this->redirect_to_admin_page('template_error'); } $this->repository->deactivate_template($template_id, get_current_user_id()); $this->redirect_to_admin_page('template_removed'); } $data = $this->posted_template_data(); if ($data === null) { $this->redirect_to_admin_page('template_error'); } if (!$this->proxmox_template_exists((int) $data['proxmox_template_id'])) { $this->redirect_to_admin_page('template_error'); } if ($template_id > 0) { $this->repository->update_template($template_id, $data, get_current_user_id()); } else { $this->repository->upsert_template($data, get_current_user_id()); } $this->redirect_to_admin_page('template_saved'); } public function save_user_access(): void { if (!$this->permissions->current_user_has(SPP_Permissions::MANAGE_PERMISSIONS)) { wp_die(esc_html__('You do not have permission to save user rights.', 'support-provisioning-portal')); } check_admin_referer('spp_save_user_access'); $user_ids = $this->posted_user_ids(); $posted_permissions = isset($_POST['spp_permissions']) ? (array) wp_unslash($_POST['spp_permissions']) : []; $posted_quotas = isset($_POST['spp_memory_quota_mb']) ? (array) wp_unslash($_POST['spp_memory_quota_mb']) : []; if (!$this->save_keeps_permission_manager($user_ids, $posted_permissions)) { $this->redirect_to_admin_page('manager_required'); } foreach ($user_ids as $user_id) { $permissions = isset($posted_permissions[$user_id]) && is_array($posted_permissions[$user_id]) ? SPP_Permissions::sanitize_permissions($posted_permissions[$user_id]) : []; $quota_raw = isset($posted_quotas[$user_id]) ? sanitize_text_field((string) $posted_quotas[$user_id]) : ''; $memory_quota_mb = $quota_raw === '' ? null : max(0, absint($quota_raw)); $this->repository->update_user_access($user_id, $permissions, $memory_quota_mb, get_current_user_id()); } $this->redirect_to_admin_page('user_access_saved'); } /** * @return array */ private function users_for_access_table(string $search): array { $args = [ 'fields' => 'all', 'orderby' => 'display_name', 'order' => 'ASC', 'number' => 200, ]; if ($search !== '') { $args['search'] = '*' . $search . '*'; $args['search_columns'] = ['user_login', 'user_email', 'user_nicename', 'display_name']; } $users = get_users($args); return is_array($users) ? $users : []; } private function render_os_type_select(string $selected): void { $options = [ 'LINUX' => 'Linux', 'WINDOWS' => 'Windows', 'APPLIANCE' => 'Appliance', 'OTHER' => 'Other', ]; ?> proxmox->list_templates() as $template) { if ((int) $template['vmId'] === $vm_id) { return true; } } } catch (Throwable) { return false; } return false; } /** * @return array|null */ private function posted_template_data(): ?array { $name = sanitize_text_field($this->posted_string('spp_template_name')); $proxmox_template_id = absint($this->posted_string('spp_proxmox_template_id')); $description = sanitize_textarea_field($this->posted_string('spp_template_description')); if ($name === '' || $proxmox_template_id < 1 || $description === '') { return null; } return [ 'template_key' => 'pve-template-' . $proxmox_template_id . '-' . sanitize_title($name), 'name' => $name, 'description' => $description, 'os_type' => $this->posted_os_type(), 'cpu_cores' => max(1, absint($this->posted_string('spp_cpu_cores'))), 'memory_mb' => max(128, absint($this->posted_string('spp_memory_mb'))), 'disk_gb' => max(1, absint($this->posted_string('spp_disk_gb'))), 'default_ttl_hours' => max(1, min(720, absint($this->posted_string('spp_default_ttl_hours')))), 'proxmox_template_id' => $proxmox_template_id, 'is_active' => $this->posted_string('spp_is_active') === '1', ]; } private function posted_os_type(): string { $os_type = strtoupper(sanitize_key($this->posted_string('spp_os_type'))); return in_array($os_type, ['LINUX', 'WINDOWS', 'APPLIANCE', 'OTHER'], true) ? $os_type : 'OTHER'; } /** * @return array */ private function posted_user_ids(): array { $raw_user_ids = isset($_POST['spp_user_ids']) ? (array) wp_unslash($_POST['spp_user_ids']) : []; $user_ids = []; foreach ($raw_user_ids as $user_id) { $user_id = absint($user_id); if ($user_id > 0 && !in_array($user_id, $user_ids, true)) { $user_ids[] = $user_id; } } return $user_ids; } /** * @param array $user_ids * @param array $posted_permissions */ private function save_keeps_permission_manager(array $user_ids, array $posted_permissions): bool { $updated_user_ids = array_flip($user_ids); foreach ($this->permissions->user_ids_with_permission(SPP_Permissions::MANAGE_PERMISSIONS) as $manager_id) { if (!isset($updated_user_ids[$manager_id])) { return true; } } foreach ($user_ids as $user_id) { $permissions = isset($posted_permissions[$user_id]) && is_array($posted_permissions[$user_id]) ? SPP_Permissions::sanitize_permissions($posted_permissions[$user_id]) : []; if (in_array(SPP_Permissions::MANAGE_PERMISSIONS, $permissions, true)) { return true; } } return false; } private function redirect_to_admin_page(string $notice): void { wp_safe_redirect(add_query_arg([ 'page' => 'support-provisioning-portal', 'spp_notice' => $notice, ], admin_url('admin.php'))); exit; } }