type ?? ''); $user = $this->getUser(); if (!$user instanceof FrontendUser) { $template->set('loginRequired', true); $template->set('surveys', []); $template->set('createUrl', null); $template->set('templatesOnly', $templatesOnly); return $template->getResponse(); } if ($request->isMethod('POST') && $request->request->has('_survey_action')) { return $this->handleAction($request, (int) $user->id); } $editPage = $templatesOnly ? null : $this->resolvePage((int) ($model->surveyEditPage ?? 0)); $readerPage = $this->resolvePage((int) $this->getContaoAdapter(Config::class)->get('surveyReaderPage')); $resultsPage = $this->resolvePage((int) $this->getContaoAdapter(Config::class)->get('surveyResultsPage')); $items = []; foreach ($this->surveyRepository->findEditableByMember((int) $user->id, $templatesOnly) as $survey) { $surveyId = (int) $survey['id']; $alias = (string) $survey['alias']; $items[] = [ 'id' => $surveyId, 'title' => (string) $survey['title'], 'description' => (string) ($survey['description'] ?? ''), 'isTemplate' => !empty($survey['isTemplate']), 'isActive' => !empty($survey['isActive']), 'isLocked' => !empty($survey['isLocked']), 'published' => !empty($survey['published']), 'questionCount' => (int) ($survey['questionCount'] ?? 0), 'participationCount' => (int) ($survey['participationCount'] ?? 0), 'editUrl' => $editPage instanceof PageModel ? $this->generateContentUrl($editPage, ['survey' => $surveyId]) : null, 'publicUrl' => $readerPage instanceof PageModel ? $this->generateContentUrl($readerPage, ['parameters' => '/'.$alias]) : null, // Absolute URL für den "Link kopieren"-Button, damit der geteilte // Link auch außerhalb der Seite funktioniert. 'copyUrl' => $readerPage instanceof PageModel ? $this->generateContentUrl($readerPage, ['parameters' => '/'.$alias], UrlGeneratorInterface::ABSOLUTE_URL) : null, 'draftUrl' => $readerPage instanceof PageModel ? $this->generateContentUrl($readerPage, ['parameters' => '/'.$alias, 'preview' => '1']) : null, 'resultsUrl' => $resultsPage instanceof PageModel ? $this->generateContentUrl($resultsPage, ['parameters' => '/'.$alias]) : null, ]; } if ($templatesOnly && [] === $items) { return new Response(''); } $template->set('loginRequired', false); $template->set('surveys', $items); $template->set('createUrl', !$templatesOnly && $editPage instanceof PageModel ? $this->generateContentUrl($editPage, ['create' => '1']) : null); $template->set('templatesOnly', $templatesOnly); return $template->getResponse(); } private function handleAction(Request $request, int $memberId): Response { $surveyId = (int) $request->request->get('item_id', 0); $action = (string) $request->request->get('_survey_action'); $token = (string) $request->request->get('_token', ''); if ($surveyId <= 0 || '' === $action) { throw new \RuntimeException('Ungültige Umfrage-Aktion.'); } // Session-basierter Symfony-Token (wie im Editor): zuverlässig für // eingeloggte Mitglieder. Der Contao-REQUEST_TOKEN ist cookie-gebunden // und im Frontend-Fragment-Flow nicht stabil verfügbar. if (!$this->isCsrfTokenValid($action.'-'.$surveyId, $token)) { throw new \RuntimeException('Ungültiger CSRF-Token.'); } $survey = $this->resolveEditableSurvey($surveyId, $memberId); try { if ('duplicate-survey' === $action) { $duplicate = $this->surveyEditorService->duplicateSurvey($survey, $memberId); $this->addFlash('success', sprintf('Die Umfrage "%s" wurde als Kopie angelegt.', (string) $duplicate->title)); } if ('publish-survey' === $action) { $this->surveyEditorService->publishSurvey($survey, $memberId); $this->addFlash('success', 'Die Umfrage ist jetzt veröffentlicht.'); } if ('toggle-active' === $action) { $isActive = $this->surveyEditorService->toggleSurveyActive($survey, $memberId); $this->addFlash('success', $isActive ? 'Die Umfrage ist jetzt wieder aktiv.' : 'Die Umfrage wurde vorübergehend deaktiviert.'); } if ('delete-survey' === $action) { $this->surveyEditorService->deleteSurvey($survey); $this->addFlash('success', 'Die Umfrage mit allen Fragen, Antworten und Ergebnissen wurde gelöscht.'); } } catch (\Throwable $exception) { $this->addFlash('error', $exception->getMessage()); } return new RedirectResponse($request->getBaseUrl().$request->getPathInfo()); } private function resolveEditableSurvey(int $surveyId, int $memberId): SurveyModel { $survey = $this->surveyRepository->findById($surveyId); if (!$survey instanceof SurveyModel || !$this->surveyEditorRepository->isEditor($surveyId, $memberId)) { throw new \RuntimeException('Sie dürfen diese Umfrage nicht bearbeiten.'); } return $survey; } private function resolvePage(int $pageId): ?PageModel { if ($pageId <= 0) { return null; } $page = $this->getContaoAdapter(PageModel::class)->findById($pageId); return $page instanceof PageModel ? $page : null; } }