From f3f9dab184f66818af89ec27be29cd30a03ba0d7 Mon Sep 17 00:00:00 2001 From: Claude Fable 5 Date: Sat, 22 Aug 2026 12:41:34 +0200 Subject: [PATCH] Friendlier logged-out notice with session duration and login link Co-Authored-By: Claude Fable 5 --- .../frontend/member_survey_edit.html.twig | 9 ++- .../frontend/member_survey_list.html.twig | 9 ++- .../MemberSurveyEditController.php | 11 ++++ .../MemberSurveyListController.php | 13 +++- src/Service/SurveyLoginInfoService.php | 59 +++++++++++++++++++ translations/messages.de.yaml | 5 +- translations/messages.en.yaml | 5 +- 7 files changed, 104 insertions(+), 7 deletions(-) create mode 100644 src/Service/SurveyLoginInfoService.php diff --git a/contao/templates/frontend/member_survey_edit.html.twig b/contao/templates/frontend/member_survey_edit.html.twig index c1aadb8..ec27b75 100644 --- a/contao/templates/frontend/member_survey_edit.html.twig +++ b/contao/templates/frontend/member_survey_edit.html.twig @@ -24,7 +24,14 @@ {% endif %} {% if loginRequired %} -
{{ 'survey.edit.login_required'|trans }}
+
+
{{ 'survey.edit.login_required'|trans({'%minutes%': sessionMinutes|default(24)}) }}
+ {% if loginUrl|default(null) %} + + {% endif %} +
{% elseif entryNotAllowed|default(false) %}
{{ 'survey.edit.entry_not_allowed'|trans }}
diff --git a/contao/templates/frontend/member_survey_list.html.twig b/contao/templates/frontend/member_survey_list.html.twig index c3938ab..5ac5fd3 100644 --- a/contao/templates/frontend/member_survey_list.html.twig +++ b/contao/templates/frontend/member_survey_list.html.twig @@ -24,7 +24,14 @@ {% endif %} {% if loginRequired %} -
{{ 'survey.list.login_required'|trans }}
+
+
{{ 'survey.list.login_required'|trans({'%minutes%': sessionMinutes|default(24)}) }}
+ {% if loginUrl|default(null) %} + + {% endif %} +
{% else %}
{% if createUrl %} diff --git a/src/Controller/FrontendModule/MemberSurveyEditController.php b/src/Controller/FrontendModule/MemberSurveyEditController.php index c87328e..978c209 100644 --- a/src/Controller/FrontendModule/MemberSurveyEditController.php +++ b/src/Controller/FrontendModule/MemberSurveyEditController.php @@ -21,6 +21,7 @@ use Mummert\SurveyBundle\Repository\SurveyEditorRepository; use Mummert\SurveyBundle\Repository\SurveyQuestionRepository; use Mummert\SurveyBundle\Repository\SurveyRepository; use Mummert\SurveyBundle\Service\SurveyEditorService; +use Mummert\SurveyBundle\Service\SurveyLoginInfoService; use Mummert\SurveyBundle\Service\SurveyStructureService; use Mummert\SurveyBundle\Service\SurveySubmissionService; use Symfony\Component\DependencyInjection\Attribute\Autowire; @@ -41,6 +42,7 @@ final class MemberSurveyEditController extends AbstractFrontendModuleController private readonly SurveyEditorService $surveyEditorService, private readonly SurveySubmissionService $surveySubmissionService, private readonly SurveyStructureService $surveyStructureService, + private readonly SurveyLoginInfoService $surveyLoginInfoService, private readonly FormFactoryInterface $formFactory, #[Autowire('%kernel.debug%')] private readonly bool $kernelDebug = false, @@ -53,6 +55,8 @@ final class MemberSurveyEditController extends AbstractFrontendModuleController if ($memberId <= 0) { $template->set('loginRequired', true); + $template->set('loginUrl', $this->resolveLoginUrl()); + $template->set('sessionMinutes', $this->surveyLoginInfoService->getSessionLifetimeMinutes()); $template->set('entryNotAllowed', false); $template->set('backUrl', $this->resolveListUrl($model)); $template->set('createQuestionMode', false); @@ -579,4 +583,11 @@ final class MemberSurveyEditController extends AbstractFrontendModuleController return $page instanceof PageModel ? $page : null; } + + private function resolveLoginUrl(): ?string + { + $page = $this->surveyLoginInfoService->findLoginPage(); + + return $page instanceof PageModel ? $this->generateContentUrl($page) : null; + } } diff --git a/src/Controller/FrontendModule/MemberSurveyListController.php b/src/Controller/FrontendModule/MemberSurveyListController.php index fadd444..ff3914a 100644 --- a/src/Controller/FrontendModule/MemberSurveyListController.php +++ b/src/Controller/FrontendModule/MemberSurveyListController.php @@ -15,6 +15,7 @@ use Mummert\SurveyBundle\Model\SurveyModel; use Mummert\SurveyBundle\Repository\SurveyEditorRepository; use Mummert\SurveyBundle\Repository\SurveyRepository; use Mummert\SurveyBundle\Service\SurveyEditorService; +use Mummert\SurveyBundle\Service\SurveyLoginInfoService; use Symfony\Component\HttpFoundation\RedirectResponse; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; @@ -28,6 +29,7 @@ final class MemberSurveyListController extends AbstractFrontendModuleController private readonly SurveyRepository $surveyRepository, private readonly SurveyEditorRepository $surveyEditorRepository, private readonly SurveyEditorService $surveyEditorService, + private readonly SurveyLoginInfoService $surveyLoginInfoService, ) { } @@ -38,6 +40,8 @@ final class MemberSurveyListController extends AbstractFrontendModuleController if (!$user instanceof FrontendUser) { $template->set('loginRequired', true); + $template->set('loginUrl', $this->resolveLoginUrl()); + $template->set('sessionMinutes', $this->surveyLoginInfoService->getSessionLifetimeMinutes()); $template->set('surveys', []); $template->set('createUrl', null); $template->set('templatesOnly', $templatesOnly); @@ -157,4 +161,11 @@ final class MemberSurveyListController extends AbstractFrontendModuleController return $page instanceof PageModel ? $page : null; } -} \ No newline at end of file + + private function resolveLoginUrl(): ?string + { + $page = $this->surveyLoginInfoService->findLoginPage(); + + return $page instanceof PageModel ? $this->generateContentUrl($page) : null; + } +} diff --git a/src/Service/SurveyLoginInfoService.php b/src/Service/SurveyLoginInfoService.php new file mode 100644 index 0000000..b0fb450 --- /dev/null +++ b/src/Service/SurveyLoginInfoService.php @@ -0,0 +1,59 @@ +connection->fetchOne( + <<<'SQL' + SELECT a.pid + FROM tl_content c + INNER JOIN tl_article a ON a.id = c.pid + INNER JOIN tl_module m ON m.id = c.module + INNER JOIN tl_page p ON p.id = a.pid + WHERE c.type = 'module' AND m.type = 'login' AND c.invisible = '' AND a.published = '1' AND p.published = '1' + ORDER BY p.sorting ASC, a.sorting ASC, c.sorting ASC + LIMIT 1 + SQL, + ); + + if (false === $pageId) { + return null; + } + + $page = $this->framework->getAdapter(PageModel::class)->findById((int) $pageId); + + return $page instanceof PageModel ? $page : null; + } + + /** + * Maximale Inaktivitätsdauer einer Sitzung in Minuten (aufgerundet). + */ + public function getSessionLifetimeMinutes(): int + { + $seconds = (int) ini_get('session.gc_maxlifetime'); + + return max(1, (int) ceil(($seconds > 0 ? $seconds : 1440) / 60)); + } +} diff --git a/translations/messages.de.yaml b/translations/messages.de.yaml index e6ad454..39eecb5 100644 --- a/translations/messages.de.yaml +++ b/translations/messages.de.yaml @@ -1,6 +1,7 @@ survey: list: - login_required: "Dieser Bereich verwendet den normalen Contao-Mitgliederlogin. Bitte binden Sie das Modul auf einer geschützten Seite oder mit einer separaten Login-Seite ein." + login_required: "Sie sind nicht oder nicht mehr im Umfragetool des Kinderschutzbund Sachsen e. V. eingeloggt. Für diesen Bereich benötigen Sie ein gültiges Login. Vielleicht haben Sie die maximal zulässige Sitzungsdauer von %minutes% Minuten überschritten." + login_link: "Zur Anmeldung" create: "Neue Umfrage anlegen" duplicate: "Duplizieren" duplicate_confirm: "Sind Sie sicher, dass Sie die Umfrage \"%title%\" mit allen Fragen duplizieren wollen?" @@ -45,7 +46,7 @@ survey: section_hint: "Ein Themenbereich ist keine Frage, sondern eine Überschrift: Alle folgenden Fragen bis zum nächsten Themenbereich gehören dazu. Teilnehmende sehen den Bereich oberhalb jeder Frage." insert_into_section: "Die neue Frage wird am Ende des Themenbereichs „%section%“ eingefügt." insert_before_first_section: "Die neue Frage wird vor dem ersten Themenbereich eingefügt." - login_required: "Dieses Frontendmodul ist für eingeloggte Mitglieder gedacht. Nutzen Sie den normalen Contao-Mitgliederlogin auf einer geschützten Seite." + login_required: "Sie sind nicht oder nicht mehr im Umfragetool des Kinderschutzbund Sachsen e. V. eingeloggt. Für diesen Bereich benötigen Sie ein gültiges Login. Vielleicht haben Sie die maximal zulässige Sitzungsdauer von %minutes% Minuten überschritten." entry_not_allowed: "Diese Seite kann nicht direkt geöffnet werden. Bitte wechseln Sie über die Umfragen-Liste in den Bearbeitungsmodus." create_title: "Neue Umfrage erstellen" label_title: "Titel" diff --git a/translations/messages.en.yaml b/translations/messages.en.yaml index 9b8db12..5e1906e 100644 --- a/translations/messages.en.yaml +++ b/translations/messages.en.yaml @@ -1,6 +1,7 @@ survey: list: - login_required: "This area uses the regular Contao member login. Please place the module on a protected page or provide a separate login page." + login_required: "You are not (or no longer) logged in to the survey tool of Kinderschutzbund Sachsen e. V. A valid login is required for this area. You may have exceeded the maximum session duration of %minutes% minutes." + login_link: "Go to login" create: "Create new survey" duplicate: "Duplicate" duplicate_confirm: "Are you sure you want to duplicate the survey \"%title%\" with all questions?" @@ -45,7 +46,7 @@ survey: section_hint: "A topic section is not a question but a heading: all following questions up to the next section belong to it. Participants see the section above every question." insert_into_section: "The new question will be added at the end of the topic section “%section%”." insert_before_first_section: "The new question will be inserted before the first topic section." - login_required: "This frontend module is intended for logged-in members. Please use the regular Contao member login on a protected page." + login_required: "You are not (or no longer) logged in to the survey tool of Kinderschutzbund Sachsen e. V. A valid login is required for this area. You may have exceeded the maximum session duration of %minutes% minutes." entry_not_allowed: "This page cannot be opened directly. Please switch to edit mode via the survey list." create_title: "Create new survey" label_title: "Title"