0) { PermissionService::getUserPermissions($currentUserId, true); } $uuid = trim((string) ($id ?? '')); $user = $uuid !== '' ? UserService::findByUuid($uuid) : null; if (!$user) { Flash::error('User not found', 'admin/users', 'user_not_found'); Router::redirect('admin/users'); } $userId = (int) ($user['id'] ?? 0); $canViewUsers = PermissionService::userHas($currentUserId, PermissionService::USERS_VIEW); $canUpdateUser = PermissionService::userHas($currentUserId, PermissionService::USERS_UPDATE); $canUpdateSelf = PermissionService::userHas($currentUserId, PermissionService::USERS_SELF_UPDATE); $canUpdateAssignments = PermissionService::userHas($currentUserId, PermissionService::USERS_UPDATE_ASSIGNMENTS); $isOwnAccount = $currentUserId === $userId; $canEditUser = $isOwnAccount ? ($canUpdateUser || $canUpdateSelf) : $canUpdateUser; $canEditAssignments = $canEditUser && $canUpdateAssignments; if (!$isOwnAccount && !TenantScopeService::canAccess('users', $userId, $currentUserId)) { Router::redirect('error/forbidden'); return; } if (!$canViewUsers && !$canEditUser) { Router::redirect('error/forbidden'); return; } $creatorId = (int) ($user['created_by'] ?? 0); if ($creatorId > 0) { $creator = UserService::findById($creatorId); if ($creator) { $creatorName = trim(($creator['first_name'] ?? '') . ' ' . ($creator['last_name'] ?? '')); $user['created_by_label'] = $creatorName !== '' ? $creatorName : ($creator['email'] ?? ''); $user['created_by_uuid'] = $creator['uuid'] ?? null; } } $modifierId = (int) ($user['modified_by'] ?? 0); if ($modifierId > 0) { $modifier = UserService::findById($modifierId); if ($modifier) { $modifierName = trim(($modifier['first_name'] ?? '') . ' ' . ($modifier['last_name'] ?? '')); $user['modified_by_label'] = $modifierName !== '' ? $modifierName : ($modifier['email'] ?? ''); $user['modified_by_uuid'] = $modifier['uuid'] ?? null; } } $activeChangedById = (int) ($user['active_changed_by'] ?? 0); if ($activeChangedById > 0) { $activeChanger = UserService::findById($activeChangedById); if ($activeChanger) { $activeChangerName = trim(($activeChanger['first_name'] ?? '') . ' ' . ($activeChanger['last_name'] ?? '')); $user['active_changed_by_label'] = $activeChangerName !== '' ? $activeChangerName : ($activeChanger['email'] ?? ''); $user['active_changed_by_uuid'] = $activeChanger['uuid'] ?? null; } } $errors = []; $form = $user; // Users with tenants.update permission can see ALL tenants (to assign new tenants to users) $canManageTenants = PermissionService::userHas($currentUserId, PermissionService::TENANTS_UPDATE); $allowedTenantIds = $canManageTenants ? null : TenantScopeService::getUserTenantIds($currentUserId); $tenants = TenantService::list(); if ($allowedTenantIds) { $tenants = array_values(array_filter($tenants, static function (array $tenant) use ($allowedTenantIds): bool { $tenantId = (int) ($tenant['id'] ?? 0); return $tenantId > 0 && in_array($tenantId, $allowedTenantIds, true); })); } elseif (!$canManageTenants && TenantScopeService::isStrict()) { $tenants = []; } $selectedTenantIds = UserTenantRepository::listTenantIdsByUserId($userId); if ($allowedTenantIds) { $selectedTenantIds = array_values(array_intersect($selectedTenantIds, $allowedTenantIds)); } $primaryTenantId = (int) ($user['primary_tenant_id'] ?? 0); if (!$primaryTenantId && count($selectedTenantIds) === 1) { $primaryTenantId = (int) $selectedTenantIds[0]; $user['primary_tenant_id'] = $primaryTenantId; } $roles = RoleService::listActive(); $selectedRoleIds = UserRoleRepository::listRoleIdsByUserId($userId); $permissionRows = RolePermissionRepository::listPermissionsWithRolesByRoleIds($selectedRoleIds); $departments = DepartmentService::listForUserAssignments($selectedTenantIds, []); $selectedDepartmentIds = UserDepartmentRepository::listDepartmentIdsByUserId($userId); if ($selectedDepartmentIds) { $departments = DepartmentService::listForUserAssignments($selectedTenantIds, $selectedDepartmentIds); } $passwordResets = []; if ($canViewUsers || $canEditUser) { $passwordResets = PasswordResetRepository::listByUserId($userId, 25); } $rememberTokens = []; if ($canViewUsers || $canEditUser) { $rememberTokens = RememberTokenRepository::listByUserId($userId, 25); } // Keep initial $isOwnAccount/$canEditUser values for view permissions. if (isset($_POST['email'])) { if (!$canEditUser) { Router::redirect('error/forbidden'); return; } $result = UserService::updateFromAdmin($userId, $_POST, $currentUserId); $form = $result['form'] ?? $form; $errors = $result['errors'] ?? []; $tenantIds = UserService::normalizeIdInput($_POST['tenant_ids'] ?? []); if ($allowedTenantIds) { $tenantIds = array_values(array_intersect($tenantIds, $allowedTenantIds)); } elseif (!$canManageTenants && TenantScopeService::isStrict()) { $tenantIds = []; } $selectedTenantIds = $tenantIds; $primaryTenantId = (int) ($_POST['primary_tenant_id'] ?? 0); $selectedRoleIds = UserService::normalizeIdInput($_POST['role_ids'] ?? []); $selectedDepartmentIds = UserService::normalizeIdInput($_POST['department_ids'] ?? []); $departments = DepartmentService::listForUserAssignments($selectedTenantIds, $selectedDepartmentIds); if ($result['ok'] ?? false) { if ($canEditAssignments) { UserService::syncTenants($userId, $tenantIds); UserService::syncRoles($userId, $selectedRoleIds); UserService::syncDepartments($userId, $selectedDepartmentIds); // Update session if editing own account (tenant assignments changed) if ($currentUserId === $userId) { AuthService::loadTenantDataIntoSession($userId); } } if ($currentUserId === $userId && isset($form['theme'])) { $themes = appThemes(); $themeValue = strtolower(trim((string) ($form['theme'] ?? ''))); $_SESSION['user']['theme'] = isset($themes[$themeValue]) ? $themeValue : appDefaultTheme(); } if ($currentUserId === $userId && isset($form['locale'])) { $_SESSION['user']['locale'] = $form['locale']; I18n::$locale = $form['locale']; } $action = (string) ($_POST['action'] ?? 'save'); if ($action === 'save_close') { Flash::success('User updated', 'admin/users', 'user_updated'); Router::redirect('admin/users'); } else { Flash::success('User updated', "admin/users/edit/{$uuid}", 'user_updated'); Router::redirect("admin/users/edit/{$uuid}"); } } } Buffer::set('title', $isOwnAccount ? t('My account') : t('Edit user'));