isAuthenticated(); $authUser = $isAuthenticated && is_array($_SESSION['desktop_auth']['user'] ?? null) ? $_SESSION['desktop_auth']['user'] : []; $authGroups = array_values(array_map('strval', (array) ($authUser['groups'] ?? []))); $visibleApps = AppVisibility::filterByGroups($registry->all(), $authGroups); $widgets = $widgetRegistry->all(); $skins = SkinResolver::all(); if ($method === 'GET') { respond($service->buildBootstrapPayload($authUser, $visibleApps, $widgets, $skins)); } if ($method !== 'PUT') { respond(['error' => 'Method not allowed.'], 405); } $rawBody = file_get_contents('php://input'); $decoded = json_decode($rawBody !== false ? $rawBody : '', true); if (!is_array($decoded)) { respond(['error' => 'Invalid JSON payload.'], 400); } $before = $service->load($authUser, $visibleApps, $widgets, $skins); $after = $service->save($decoded, $authUser, $visibleApps, $widgets, $skins); $payload = $service->buildBootstrapPayload($authUser, $visibleApps, $widgets, $skins); $payload['preferences'] = $after; $payload['meta']['requires_reload'] = requiresReload($before, $after); respond($payload); /** * @param array $payload */ function respond(array $payload, int $statusCode = 200): never { http_response_code($statusCode); echo json_encode($payload, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_THROW_ON_ERROR); exit; } /** * @param array $before * @param array $after */ function requiresReload(array $before, array $after): bool { $beforeSkin = (string) ($before['desktop']['active_skin'] ?? ''); $afterSkin = (string) ($after['desktop']['active_skin'] ?? ''); $beforeApps = array_values(array_map('strval', (array) ($before['apps']['enabled_ids'] ?? []))); $afterApps = array_values(array_map('strval', (array) ($after['apps']['enabled_ids'] ?? []))); sort($beforeApps); sort($afterApps); return $beforeSkin !== $afterSkin || $beforeApps !== $afterApps; }