Refine survey editor flow and auth styling

This commit is contained in:
Jürgen Mummert
2026-05-25 16:02:47 +02:00
parent e204da60b6
commit a893078945
18 changed files with 1649 additions and 313 deletions
@@ -11,8 +11,11 @@ use Contao\CoreBundle\Twig\FragmentTemplate;
use Contao\FrontendUser;
use Contao\ModuleModel;
use Contao\PageModel;
use Mummert\SurveyBundle\Model\SurveyModel;
use Mummert\SurveyBundle\Repository\SurveyEditorRepository;
use Mummert\SurveyBundle\Repository\SurveyRepository;
use Mummert\SurveyBundle\Service\SurveySubmissionService;
use Mummert\SurveyBundle\Service\SurveyEditorService;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
@@ -21,7 +24,8 @@ final class MemberSurveyListController extends AbstractFrontendModuleController
{
public function __construct(
private readonly SurveyRepository $surveyRepository,
private readonly SurveySubmissionService $surveySubmissionService,
private readonly SurveyEditorRepository $surveyEditorRepository,
private readonly SurveyEditorService $surveyEditorService,
) {
}
@@ -37,6 +41,10 @@ final class MemberSurveyListController extends AbstractFrontendModuleController
return $template->getResponse();
}
if ($request->isMethod('POST') && $request->request->has('_survey_action')) {
return $this->handleAction($request, (int) $user->id);
}
$editPage = $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'));
@@ -44,7 +52,6 @@ final class MemberSurveyListController extends AbstractFrontendModuleController
foreach ($this->surveyRepository->findEditableByMember((int) $user->id) as $survey) {
$surveyId = (int) $survey['id'];
$isCompletedInCurrentSession = $this->surveySubmissionService->hasFinishedSubmissionForSurvey($surveyId, $request->getSession());
$items[] = [
'id' => $surveyId,
@@ -53,20 +60,60 @@ final class MemberSurveyListController extends AbstractFrontendModuleController
'isLocked' => !empty($survey['isLocked']),
'published' => !empty($survey['published']),
'questionCount' => (int) ($survey['questionCount'] ?? 0),
'answerCount' => (int) ($survey['answerCount'] ?? 0),
'participationCount' => (int) ($survey['participationCount'] ?? 0),
'editUrl' => $editPage instanceof PageModel ? $this->generateContentUrl($editPage, ['survey' => $surveyId]) : null,
'publicUrl' => $readerPage instanceof PageModel ? $this->generateContentUrl($readerPage, ['auto_item' => (string) $survey['alias']]) : null,
'resultsUrl' => !$isCompletedInCurrentSession && $resultsPage instanceof PageModel ? $this->generateContentUrl($resultsPage, ['auto_item' => (string) $survey['alias']]) : null,
'resultsUrl' => $resultsPage instanceof PageModel ? $this->generateContentUrl($resultsPage, ['auto_item' => (string) $survey['alias']]) : null,
];
}
$template->set('loginRequired', false);
$template->set('surveys', $items);
$template->set('createUrl', $editPage instanceof PageModel ? $this->generateContentUrl($editPage) : null);
$template->set('createUrl', $editPage instanceof PageModel ? $this->generateContentUrl($editPage, ['create' => '1']) : null);
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 || !$this->isCsrfTokenValid($action.'-'.$surveyId, $token)) {
throw new \RuntimeException('Ungueltiger CSRF-Token.');
}
$survey = $this->resolveEditableSurvey($surveyId, $memberId);
try {
if ('toggle-published' === $action) {
$isPublished = $this->surveyEditorService->toggleSurveyPublished($survey, $memberId);
$this->addFlash('success', $isPublished ? 'Die Umfrage ist jetzt veroeffentlicht.' : 'Die Umfrage ist jetzt nicht mehr veroeffentlicht.');
}
if ('delete-survey' === $action) {
$this->surveyEditorService->deleteSurvey($survey);
$this->addFlash('success', 'Die Umfrage mit allen Fragen, Antworten und Ergebnissen wurde geloescht.');
}
} 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 duerfen diese Umfrage nicht bearbeiten.');
}
return $survey;
}
private function resolvePage(int $pageId): ?PageModel
{
if ($pageId <= 0) {