Initial survey bundle import
This commit is contained in:
@@ -0,0 +1,273 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Mummert\SurveyBundle\Controller\FrontendModule;
|
||||
|
||||
use Contao\Config;
|
||||
use Contao\CoreBundle\Controller\FrontendModule\AbstractFrontendModuleController;
|
||||
use Contao\CoreBundle\DependencyInjection\Attribute\AsFrontendModule;
|
||||
use Contao\CoreBundle\Twig\FragmentTemplate;
|
||||
use Contao\FrontendUser;
|
||||
use Contao\ModuleModel;
|
||||
use Contao\PageModel;
|
||||
use Mummert\SurveyBundle\Form\Model\SurveyConditionData;
|
||||
use Mummert\SurveyBundle\Form\Model\SurveyEditorData;
|
||||
use Mummert\SurveyBundle\Form\Model\SurveyQuestionData;
|
||||
use Mummert\SurveyBundle\Form\SurveyConditionEditorType;
|
||||
use Mummert\SurveyBundle\Form\SurveyEditorType;
|
||||
use Mummert\SurveyBundle\Form\SurveyQuestionEditorType;
|
||||
use Mummert\SurveyBundle\Model\SurveyModel;
|
||||
use Mummert\SurveyBundle\Repository\SurveyConditionRepository;
|
||||
use Mummert\SurveyBundle\Repository\SurveyEditorRepository;
|
||||
use Mummert\SurveyBundle\Repository\SurveyQuestionRepository;
|
||||
use Mummert\SurveyBundle\Repository\SurveyRepository;
|
||||
use Mummert\SurveyBundle\Security\SurveyEditorVoter;
|
||||
use Mummert\SurveyBundle\Service\SurveyEditorService;
|
||||
use Mummert\SurveyBundle\Service\SurveySubmissionService;
|
||||
use Symfony\Component\HttpFoundation\RedirectResponse;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
#[AsFrontendModule(type: 'member_survey_edit', category: 'survey', template: 'frontend/member_survey_edit')]
|
||||
final class MemberSurveyEditController extends AbstractFrontendModuleController
|
||||
{
|
||||
public function __construct(
|
||||
private readonly SurveyRepository $surveyRepository,
|
||||
private readonly SurveyQuestionRepository $surveyQuestionRepository,
|
||||
private readonly SurveyConditionRepository $surveyConditionRepository,
|
||||
private readonly SurveyEditorRepository $surveyEditorRepository,
|
||||
private readonly SurveyEditorService $surveyEditorService,
|
||||
private readonly SurveySubmissionService $surveySubmissionService,
|
||||
) {
|
||||
}
|
||||
|
||||
protected function getResponse(FragmentTemplate $template, ModuleModel $model, Request $request): Response
|
||||
{
|
||||
$user = $this->getUser();
|
||||
|
||||
if (!$user instanceof FrontendUser) {
|
||||
$template->set('loginRequired', true);
|
||||
$template->set('backUrl', $this->resolveListUrl($model));
|
||||
|
||||
return $template->getResponse();
|
||||
}
|
||||
|
||||
$survey = $this->resolveSurvey($request, $user);
|
||||
|
||||
if ($survey instanceof SurveyModel && $request->isMethod('POST') && $request->request->has('_survey_action')) {
|
||||
return $this->handleAction($survey, $request, $model);
|
||||
}
|
||||
|
||||
$questionChoices = $survey instanceof SurveyModel ? $this->buildQuestionChoices((int) $survey->id) : [];
|
||||
$surveyForm = $this->createNamed('survey_meta', SurveyEditorType::class, $survey instanceof SurveyModel ? SurveyEditorData::fromModel($survey) : new SurveyEditorData());
|
||||
$surveyForm->handleRequest($request);
|
||||
|
||||
if ($surveyForm->isSubmitted() && $surveyForm->isValid()) {
|
||||
try {
|
||||
if ($survey instanceof SurveyModel) {
|
||||
$this->surveyEditorService->updateSurvey($survey, (int) $user->id, $surveyForm->getData());
|
||||
$this->addFlash('success', 'Die Umfrage wurde gespeichert.');
|
||||
|
||||
return new RedirectResponse($this->buildEditUrl($model, (int) $survey->id));
|
||||
}
|
||||
|
||||
$createdSurvey = $this->surveyEditorService->createSurvey((int) $user->id, $surveyForm->getData());
|
||||
$this->addFlash('success', 'Die Umfrage wurde angelegt.');
|
||||
|
||||
return new RedirectResponse($this->buildEditUrl($model, (int) $createdSurvey->id));
|
||||
} catch (\Throwable $exception) {
|
||||
$this->addFlash('error', $exception->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
if (!$survey instanceof SurveyModel) {
|
||||
$template->set('loginRequired', false);
|
||||
$template->set('createMode', true);
|
||||
$template->set('surveyForm', $surveyForm->createView());
|
||||
$template->set('backUrl', $this->resolveListUrl($model));
|
||||
$template->set('publicUrl', null);
|
||||
$template->set('survey', null);
|
||||
$template->set('questionForm', null);
|
||||
$template->set('conditionForm', null);
|
||||
$template->set('questions', []);
|
||||
$template->set('conditions', []);
|
||||
$template->set('editors', []);
|
||||
$template->set('submissions', []);
|
||||
$template->set('activeQuestionId', 0);
|
||||
$template->set('activeConditionId', 0);
|
||||
|
||||
return $template->getResponse();
|
||||
}
|
||||
|
||||
$activeQuestion = $this->resolveActiveQuestion($request, (int) $survey->id);
|
||||
$activeCondition = $this->resolveActiveCondition($request, (int) $survey->id);
|
||||
$questionForm = $this->createNamed('survey_question', SurveyQuestionEditorType::class, $activeQuestion ? SurveyQuestionData::fromModel($activeQuestion) : new SurveyQuestionData(), [
|
||||
'question_choices' => $this->buildQuestionChoices((int) $survey->id),
|
||||
]);
|
||||
$conditionForm = $this->createNamed('survey_condition', SurveyConditionEditorType::class, $activeCondition ? SurveyConditionData::fromModel($activeCondition) : new SurveyConditionData(), [
|
||||
'question_choices' => $questionChoices,
|
||||
]);
|
||||
|
||||
$questionForm->handleRequest($request);
|
||||
$conditionForm->handleRequest($request);
|
||||
|
||||
if ($questionForm->isSubmitted() && $questionForm->isValid()) {
|
||||
try {
|
||||
$this->surveyEditorService->saveQuestion($survey, $questionForm->getData(), $activeQuestion ? (int) $activeQuestion->id : 0);
|
||||
$this->addFlash('success', $activeQuestion ? 'Die Frage wurde aktualisiert.' : 'Die Frage wurde angelegt.');
|
||||
|
||||
return new RedirectResponse($this->buildEditUrl($model, (int) $survey->id));
|
||||
} catch (\Throwable $exception) {
|
||||
$this->addFlash('error', $exception->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
if ($conditionForm->isSubmitted() && $conditionForm->isValid()) {
|
||||
try {
|
||||
$this->surveyEditorService->saveCondition($survey, $conditionForm->getData(), $activeCondition ? (int) $activeCondition->id : 0);
|
||||
$this->addFlash('success', $activeCondition ? 'Die Bedingung wurde aktualisiert.' : 'Die Bedingung wurde angelegt.');
|
||||
|
||||
return new RedirectResponse($this->buildEditUrl($model, (int) $survey->id));
|
||||
} catch (\Throwable $exception) {
|
||||
$this->addFlash('error', $exception->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
$template->set('loginRequired', false);
|
||||
$template->set('createMode', false);
|
||||
$template->set('survey', $survey);
|
||||
$template->set('surveyForm', $surveyForm->createView());
|
||||
$template->set('questionForm', $questionForm->createView());
|
||||
$template->set('conditionForm', $conditionForm->createView());
|
||||
$template->set('questions', $this->surveyQuestionRepository->findAllBySurvey((int) $survey->id));
|
||||
$template->set('conditions', $this->surveyConditionRepository->findOverviewBySurvey((int) $survey->id));
|
||||
$template->set('editors', $this->surveyEditorRepository->findEditorsBySurvey((int) $survey->id));
|
||||
$template->set('submissions', $this->surveySubmissionService->getSubmissionOverview($survey));
|
||||
$template->set('activeQuestionId', $activeQuestion ? (int) $activeQuestion->id : 0);
|
||||
$template->set('activeConditionId', $activeCondition ? (int) $activeCondition->id : 0);
|
||||
$template->set('backUrl', $this->resolveListUrl($model));
|
||||
$template->set('publicUrl', $this->resolveReaderUrl($model, (string) $survey->alias));
|
||||
|
||||
return $template->getResponse();
|
||||
}
|
||||
|
||||
private function resolveSurvey(Request $request, FrontendUser $user): ?SurveyModel
|
||||
{
|
||||
$surveyId = (int) $request->query->get('survey', 0);
|
||||
|
||||
if ($surveyId <= 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$survey = $this->surveyRepository->findById($surveyId);
|
||||
|
||||
if (!$survey instanceof SurveyModel) {
|
||||
throw new \RuntimeException('Die Umfrage wurde nicht gefunden.');
|
||||
}
|
||||
|
||||
$this->denyAccessUnlessGranted(SurveyEditorVoter::EDIT, $survey);
|
||||
|
||||
return $survey;
|
||||
}
|
||||
|
||||
private function handleAction(SurveyModel $survey, Request $request, ModuleModel $model): Response
|
||||
{
|
||||
$action = (string) $request->request->get('_survey_action');
|
||||
$itemId = (int) $request->request->get('item_id', 0);
|
||||
$token = (string) $request->request->get('_token');
|
||||
|
||||
if (!$this->isCsrfTokenValid($action.'-'.$itemId, $token)) {
|
||||
throw new \RuntimeException('Ungueltiger CSRF-Token.');
|
||||
}
|
||||
|
||||
try {
|
||||
if ('delete-question' === $action) {
|
||||
$this->surveyEditorService->deleteQuestion($survey, $itemId);
|
||||
$this->addFlash('success', 'Die Frage wurde geloescht.');
|
||||
}
|
||||
|
||||
if ('delete-condition' === $action) {
|
||||
$this->surveyEditorService->deleteCondition($survey, $itemId);
|
||||
$this->addFlash('success', 'Die Bedingung wurde geloescht.');
|
||||
}
|
||||
} catch (\Throwable $exception) {
|
||||
$this->addFlash('error', $exception->getMessage());
|
||||
}
|
||||
|
||||
return new RedirectResponse($this->buildEditUrl($model, (int) $survey->id));
|
||||
}
|
||||
|
||||
private function resolveActiveQuestion(Request $request, int $surveyId): mixed
|
||||
{
|
||||
$questionId = (int) $request->query->get('question', 0);
|
||||
|
||||
return $questionId > 0 ? $this->surveyQuestionRepository->findByIdForSurvey($surveyId, $questionId) : null;
|
||||
}
|
||||
|
||||
private function resolveActiveCondition(Request $request, int $surveyId): mixed
|
||||
{
|
||||
$conditionId = (int) $request->query->get('condition', 0);
|
||||
$condition = $conditionId > 0 ? $this->surveyConditionRepository->findById($conditionId) : null;
|
||||
|
||||
if (null === $condition || (int) $condition->pid !== $surveyId) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $condition;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<int, string>
|
||||
*/
|
||||
private function buildQuestionChoices(int $surveyId, int $excludeQuestionId = 0): array
|
||||
{
|
||||
$choices = [];
|
||||
|
||||
foreach ($this->surveyQuestionRepository->findAllBySurvey($surveyId) as $question) {
|
||||
if ($excludeQuestionId > 0 && (int) $question->id === $excludeQuestionId) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$choices[(int) $question->id] = sprintf('#%d %s', (int) $question->id, (string) $question->question);
|
||||
}
|
||||
|
||||
return $choices;
|
||||
}
|
||||
|
||||
private function resolveListUrl(ModuleModel $model): string
|
||||
{
|
||||
$page = $this->resolvePage((int) ($model->surveyListPage ?? 0)) ?? $this->getPageModel();
|
||||
|
||||
return $page instanceof PageModel ? $this->generateContentUrl($page) : '/';
|
||||
}
|
||||
|
||||
private function resolveReaderUrl(ModuleModel $model, string $publicAlias): ?string
|
||||
{
|
||||
$page = $this->resolvePage((int) $this->getContaoAdapter(Config::class)->get('surveyReaderPage'));
|
||||
|
||||
if (!$page instanceof PageModel) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $this->generateContentUrl($page, ['auto_item' => $publicAlias]);
|
||||
}
|
||||
|
||||
private function buildEditUrl(ModuleModel $model, int $surveyId): string
|
||||
{
|
||||
$page = $this->getPageModel();
|
||||
|
||||
return $page instanceof PageModel ? $this->generateContentUrl($page, ['survey' => $surveyId]) : $this->resolveListUrl($model);
|
||||
}
|
||||
|
||||
private function resolvePage(int $pageId): ?PageModel
|
||||
{
|
||||
if ($pageId <= 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$page = $this->getContaoAdapter(PageModel::class)->findById($pageId);
|
||||
|
||||
return $page instanceof PageModel ? $page : null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Mummert\SurveyBundle\Controller\FrontendModule;
|
||||
|
||||
use Contao\Config;
|
||||
use Contao\CoreBundle\Controller\FrontendModule\AbstractFrontendModuleController;
|
||||
use Contao\CoreBundle\DependencyInjection\Attribute\AsFrontendModule;
|
||||
use Contao\CoreBundle\Twig\FragmentTemplate;
|
||||
use Contao\FrontendUser;
|
||||
use Contao\ModuleModel;
|
||||
use Contao\PageModel;
|
||||
use Mummert\SurveyBundle\Repository\SurveyRepository;
|
||||
use Mummert\SurveyBundle\Service\SurveySubmissionService;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
#[AsFrontendModule(type: 'member_survey_list', category: 'survey', template: 'frontend/member_survey_list')]
|
||||
final class MemberSurveyListController extends AbstractFrontendModuleController
|
||||
{
|
||||
public function __construct(
|
||||
private readonly SurveyRepository $surveyRepository,
|
||||
private readonly SurveySubmissionService $surveySubmissionService,
|
||||
) {
|
||||
}
|
||||
|
||||
protected function getResponse(FragmentTemplate $template, ModuleModel $model, Request $request): Response
|
||||
{
|
||||
$user = $this->getUser();
|
||||
|
||||
if (!$user instanceof FrontendUser) {
|
||||
$template->set('loginRequired', true);
|
||||
$template->set('surveys', []);
|
||||
$template->set('createUrl', null);
|
||||
|
||||
return $template->getResponse();
|
||||
}
|
||||
|
||||
$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'));
|
||||
$items = [];
|
||||
|
||||
foreach ($this->surveyRepository->findEditableByMember((int) $user->id) as $survey) {
|
||||
$surveyId = (int) $survey['id'];
|
||||
$isCompletedInCurrentSession = $this->surveySubmissionService->hasFinishedSubmissionForSurvey($surveyId, $request->getSession());
|
||||
|
||||
$items[] = [
|
||||
'id' => $surveyId,
|
||||
'title' => (string) $survey['title'],
|
||||
'description' => (string) ($survey['description'] ?? ''),
|
||||
'isLocked' => !empty($survey['isLocked']),
|
||||
'published' => !empty($survey['published']),
|
||||
'questionCount' => (int) ($survey['questionCount'] ?? 0),
|
||||
'answerCount' => (int) ($survey['answerCount'] ?? 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,
|
||||
];
|
||||
}
|
||||
|
||||
$template->set('loginRequired', false);
|
||||
$template->set('surveys', $items);
|
||||
$template->set('createUrl', $editPage instanceof PageModel ? $this->generateContentUrl($editPage) : null);
|
||||
|
||||
return $template->getResponse();
|
||||
}
|
||||
|
||||
private function resolvePage(int $pageId): ?PageModel
|
||||
{
|
||||
if ($pageId <= 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$page = $this->getContaoAdapter(PageModel::class)->findById($pageId);
|
||||
|
||||
return $page instanceof PageModel ? $page : null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,126 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Mummert\SurveyBundle\Controller\FrontendModule;
|
||||
|
||||
use Contao\CoreBundle\Controller\FrontendModule\AbstractFrontendModuleController;
|
||||
use Contao\CoreBundle\DependencyInjection\Attribute\AsFrontendModule;
|
||||
use Contao\CoreBundle\Twig\FragmentTemplate;
|
||||
use Contao\ModuleModel;
|
||||
use Mummert\SurveyBundle\Form\Model\SurveyAnswerData;
|
||||
use Mummert\SurveyBundle\Form\SurveyQuestionAnswerType;
|
||||
use Mummert\SurveyBundle\Repository\SurveyRepository;
|
||||
use Mummert\SurveyBundle\Service\SurveyFlowService;
|
||||
use Mummert\SurveyBundle\Service\SurveySubmissionService;
|
||||
use Symfony\Component\HttpFoundation\RedirectResponse;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
#[AsFrontendModule(type: 'show_survey', category: 'survey', template: 'frontend/show_survey')]
|
||||
final class ShowSurveyController extends AbstractFrontendModuleController
|
||||
{
|
||||
public function __construct(
|
||||
private readonly SurveyRepository $surveyRepository,
|
||||
private readonly SurveyFlowService $surveyFlowService,
|
||||
private readonly SurveySubmissionService $surveySubmissionService,
|
||||
) {
|
||||
}
|
||||
|
||||
protected function getResponse(FragmentTemplate $template, ModuleModel $model, Request $request): Response
|
||||
{
|
||||
$publicAlias = $this->resolvePublicAlias($request);
|
||||
|
||||
if ('' === $publicAlias) {
|
||||
$template->set('errorMessage', 'Es wurde kein oeffentlicher Link auf der Anzeigeseite gefunden.');
|
||||
$template->set('question', null);
|
||||
$template->set('surveyForm', null);
|
||||
$template->set('isComplete', false);
|
||||
$template->set('answers', []);
|
||||
$template->set('survey', null);
|
||||
$template->set('progress', ['current' => 0, 'total' => 0, 'percentage' => 0]);
|
||||
|
||||
return $template->getResponse();
|
||||
}
|
||||
|
||||
$survey = $this->surveyRepository->findByPublicAlias($publicAlias, true);
|
||||
|
||||
if (null === $survey) {
|
||||
$template->set('errorMessage', 'Die Umfrage wurde nicht gefunden oder ist nicht veroeffentlicht.');
|
||||
$template->set('question', null);
|
||||
$template->set('surveyForm', null);
|
||||
$template->set('isComplete', false);
|
||||
$template->set('answers', []);
|
||||
$template->set('survey', null);
|
||||
$template->set('progress', ['current' => 0, 'total' => 0, 'percentage' => 0]);
|
||||
|
||||
return $template->getResponse();
|
||||
}
|
||||
|
||||
if ($htmlHeadBag = $this->getHtmlHeadBag()) {
|
||||
$htmlHeadBag->setTitle((string) $survey->title);
|
||||
}
|
||||
|
||||
$submission = $this->surveySubmissionService->resolveActiveSubmission($survey, $request->getSession(), null);
|
||||
$question = $this->surveyFlowService->resolveCurrentQuestion($survey, $submission);
|
||||
|
||||
if (null === $question && '1' !== (string) $submission->isFinished) {
|
||||
$template->set('errorMessage', 'Diese Umfrage ist noch nicht vollstaendig eingerichtet. Es fehlt eine gueltige erste Frage oder eine verknuepfte Folgefrage ist nicht mehr verfuegbar.');
|
||||
$template->set('question', null);
|
||||
$template->set('surveyForm', null);
|
||||
$template->set('isComplete', false);
|
||||
$template->set('answers', []);
|
||||
$template->set('survey', $survey);
|
||||
$template->set('progress', ['current' => 0, 'total' => 0, 'percentage' => 0]);
|
||||
|
||||
return $template->getResponse();
|
||||
}
|
||||
|
||||
if (null === $question) {
|
||||
$template->set('errorMessage', null);
|
||||
$template->set('survey', $survey);
|
||||
$template->set('progress', $this->surveyFlowService->getProgress($survey, null));
|
||||
$template->set('question', null);
|
||||
$template->set('surveyForm', null);
|
||||
$template->set('isComplete', true);
|
||||
$template->set('answers', $this->surveySubmissionService->getAnswersForSubmission($submission));
|
||||
|
||||
return $template->getResponse();
|
||||
}
|
||||
|
||||
$answerData = new SurveyAnswerData();
|
||||
$form = $this->createForm(SurveyQuestionAnswerType::class, $answerData, ['question' => $question]);
|
||||
$form->handleRequest($request);
|
||||
|
||||
if ($form->isSubmitted() && $form->isValid()) {
|
||||
$normalizedAnswer = $this->surveySubmissionService->storeAnswer($survey, $submission, $question, $answerData->answer);
|
||||
$nextQuestion = $this->surveyFlowService->determineNextQuestion($survey, $question, $normalizedAnswer);
|
||||
$this->surveySubmissionService->advance($submission, $nextQuestion);
|
||||
|
||||
return new RedirectResponse($request->getUri());
|
||||
}
|
||||
|
||||
$template->set('errorMessage', null);
|
||||
$template->set('survey', $survey);
|
||||
$template->set('progress', $this->surveyFlowService->getProgress($survey, $question));
|
||||
$template->set('question', $question);
|
||||
$template->set('surveyForm', $form->createView());
|
||||
$template->set('isComplete', false);
|
||||
$template->set('answers', []);
|
||||
|
||||
return $template->getResponse();
|
||||
}
|
||||
|
||||
private function resolvePublicAlias(Request $request): string
|
||||
{
|
||||
$candidate = $request->attributes->get('auto_item');
|
||||
|
||||
if (\is_string($candidate) && '' !== trim($candidate)) {
|
||||
return trim($candidate);
|
||||
}
|
||||
|
||||
$queryValue = (string) $request->query->get('auto_item', '');
|
||||
|
||||
return trim($queryValue);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Mummert\SurveyBundle\Controller\FrontendModule;
|
||||
|
||||
use Contao\Config;
|
||||
use Contao\CoreBundle\Controller\FrontendModule\AbstractFrontendModuleController;
|
||||
use Contao\CoreBundle\DependencyInjection\Attribute\AsFrontendModule;
|
||||
use Contao\CoreBundle\Twig\FragmentTemplate;
|
||||
use Contao\ModuleModel;
|
||||
use Mummert\SurveyBundle\Repository\SurveyRepository;
|
||||
use Mummert\SurveyBundle\Service\SurveyResultsViewService;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
|
||||
|
||||
#[AsFrontendModule(type: 'survey_results', category: 'survey', template: 'frontend/show_survey_results')]
|
||||
final class ShowSurveyResultsController extends AbstractFrontendModuleController
|
||||
{
|
||||
public function __construct(
|
||||
private readonly SurveyRepository $surveyRepository,
|
||||
private readonly SurveyResultsViewService $surveyResultsViewService,
|
||||
private readonly UrlGeneratorInterface $urlGenerator,
|
||||
) {
|
||||
}
|
||||
|
||||
protected function getResponse(FragmentTemplate $template, ModuleModel $model, Request $request): Response
|
||||
{
|
||||
$publicAlias = $this->resolvePublicAlias($request);
|
||||
|
||||
if ('' === $publicAlias) {
|
||||
$template->set('errorMessage', 'Es wurde kein Umfrage-Link auf der Ergebnisseite gefunden.');
|
||||
$template->set('survey', null);
|
||||
$template->set('questionResults', []);
|
||||
$template->set('completedSubmissionCount', 0);
|
||||
|
||||
return $template->getResponse();
|
||||
}
|
||||
|
||||
$survey = $this->surveyRepository->findByPublicAlias($publicAlias, false);
|
||||
|
||||
if (null === $survey) {
|
||||
$template->set('errorMessage', 'Die Umfrage wurde nicht gefunden.');
|
||||
$template->set('survey', null);
|
||||
$template->set('questionResults', []);
|
||||
$template->set('completedSubmissionCount', 0);
|
||||
|
||||
return $template->getResponse();
|
||||
}
|
||||
|
||||
if ($htmlHeadBag = $this->getHtmlHeadBag()) {
|
||||
$htmlHeadBag->setTitle((string) $survey->title.' - Ergebnisse');
|
||||
}
|
||||
|
||||
$resultsData = $this->surveyResultsViewService->buildForSurvey($survey);
|
||||
|
||||
$template->set('errorMessage', null);
|
||||
$template->set('survey', $survey);
|
||||
$template->set('completedSubmissionCount', $resultsData['completedSubmissionCount']);
|
||||
$template->set('downloadUrl', $this->buildDownloadUrl((string) $survey->alias));
|
||||
$template->set('pdfDownloadUrl', $this->hasGotenbergConfiguration() ? $this->buildPdfDownloadUrl((string) $survey->alias) : null);
|
||||
$template->set('questionResults', $resultsData['questionResults']);
|
||||
|
||||
return $template->getResponse();
|
||||
}
|
||||
|
||||
private function buildDownloadUrl(string $alias): string
|
||||
{
|
||||
return $this->urlGenerator->generate('mummert_survey_results_export', ['alias' => $alias]);
|
||||
}
|
||||
|
||||
private function buildPdfDownloadUrl(string $alias): string
|
||||
{
|
||||
return $this->urlGenerator->generate('mummert_survey_results_pdf_export', ['alias' => $alias]);
|
||||
}
|
||||
|
||||
private function hasGotenbergConfiguration(): bool
|
||||
{
|
||||
return '' !== trim((string) Config::get('surveyGotenbergUrl'));
|
||||
}
|
||||
|
||||
private function resolvePublicAlias(Request $request): string
|
||||
{
|
||||
$candidate = $request->attributes->get('auto_item');
|
||||
|
||||
if (\is_string($candidate) && '' !== trim($candidate)) {
|
||||
return trim($candidate);
|
||||
}
|
||||
|
||||
return trim((string) $request->query->get('auto_item', ''));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Mummert\SurveyBundle\Controller;
|
||||
|
||||
use Mummert\SurveyBundle\Repository\SurveyRepository;
|
||||
use Mummert\SurveyBundle\Service\SurveyResultsExportService;
|
||||
use Mummert\SurveyBundle\Service\SurveyResultsPdfService;
|
||||
use Mummert\SurveyBundle\Service\SurveyResultsViewService;
|
||||
use Mummert\SurveyBundle\Service\SurveySubmissionService;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||
use Symfony\Component\Routing\Attribute\Route;
|
||||
|
||||
final class SurveyResultsExportController
|
||||
{
|
||||
public function __construct(
|
||||
private readonly SurveyRepository $surveyRepository,
|
||||
private readonly SurveyResultsViewService $surveyResultsViewService,
|
||||
private readonly SurveySubmissionService $surveySubmissionService,
|
||||
private readonly SurveyResultsExportService $surveyResultsExportService,
|
||||
private readonly SurveyResultsPdfService $surveyResultsPdfService,
|
||||
) {
|
||||
}
|
||||
|
||||
#[Route('/umfrage-ergebnisse-export/{alias}', name: 'mummert_survey_results_export', defaults: ['_scope' => 'frontend'], requirements: ['alias' => '[^/]+'], methods: ['GET'])]
|
||||
public function __invoke(string $alias): Response
|
||||
{
|
||||
$survey = $this->surveyRepository->findByPublicAlias($alias, false);
|
||||
|
||||
if (null === $survey) {
|
||||
throw new NotFoundHttpException('Die Umfrage wurde nicht gefunden.');
|
||||
}
|
||||
|
||||
$finishedSubmissions = array_values(array_filter(
|
||||
$this->surveySubmissionService->getSubmissionOverview($survey),
|
||||
static fn (array $submission): bool => '1' === (string) ($submission['isFinished'] ?? '')
|
||||
));
|
||||
|
||||
return $this->surveyResultsExportService->createExcelExportResponse($survey, $finishedSubmissions);
|
||||
}
|
||||
|
||||
#[Route('/umfrage-ergebnisse-pdf/{alias}', name: 'mummert_survey_results_pdf_export', defaults: ['_scope' => 'frontend'], requirements: ['alias' => '[^/]+'], methods: ['GET'])]
|
||||
public function pdf(string $alias): Response
|
||||
{
|
||||
$survey = $this->surveyRepository->findByPublicAlias($alias, false);
|
||||
|
||||
if (null === $survey) {
|
||||
throw new NotFoundHttpException('Die Umfrage wurde nicht gefunden.');
|
||||
}
|
||||
|
||||
$resultsData = $this->surveyResultsViewService->buildForSurvey($survey);
|
||||
|
||||
return $this->surveyResultsPdfService->createPdfExportResponse(
|
||||
$survey,
|
||||
$resultsData['completedSubmissionCount'],
|
||||
$resultsData['questionResults'],
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user