Add survey duplication actions
This commit is contained in:
@@ -12,6 +12,7 @@ $GLOBALS['TL_DCA']['tl_survey'] = [
|
||||
'ctable' => ['tl_survey_content', 'tl_survey_condition', 'tl_survey_editor', 'tl_survey_submission'],
|
||||
'enableVersioning' => true,
|
||||
'onload_callback' => [
|
||||
[SurveyDcaListener::class, 'handleDuplicateSurveyAction'],
|
||||
[SurveyDcaListener::class, 'refreshSurveyBackendStateIndex'],
|
||||
],
|
||||
'onsubmit_callback' => [
|
||||
@@ -69,6 +70,12 @@ $GLOBALS['TL_DCA']['tl_survey'] = [
|
||||
'primary' => true,
|
||||
'button_callback' => [SurveyDcaListener::class, 'generatePublishedWarningButton'],
|
||||
],
|
||||
'duplicateSurvey' => [
|
||||
'label' => &$GLOBALS['TL_LANG']['tl_survey']['duplicateSurvey'],
|
||||
'href' => 'key=duplicateSurvey',
|
||||
'icon' => 'copy.svg',
|
||||
'button_callback' => [SurveyDcaListener::class, 'generateDuplicateSurveyButton'],
|
||||
],
|
||||
'delete' => [
|
||||
'label' => ['Löschen', 'Eintrag wirklich löschen?'],
|
||||
'href' => 'act=delete',
|
||||
|
||||
@@ -25,6 +25,9 @@ $GLOBALS['TL_LANG']['tl_survey']['assignedMembers'] = ['Zugewiesene Mitglieder',
|
||||
$GLOBALS['TL_LANG']['tl_survey']['assignedMembersFilter'] = ['Zugewiesene Benutzer', 'Filtert die Liste nach einem zugewiesenen Benutzer.'];
|
||||
$GLOBALS['TL_LANG']['tl_survey']['assignedMembersSummary'] = ['Zugewiesene Benutzer', 'Kommagetrennte Liste der zugewiesenen Benutzer.'];
|
||||
$GLOBALS['TL_LANG']['tl_survey']['copyPublicLink'] = ['Link kopieren', 'Den öffentlichen Link in die Zwischenablage kopieren'];
|
||||
$GLOBALS['TL_LANG']['tl_survey']['duplicateSurvey'] = ['Duplizieren', 'Diese Umfrage mit allen Fragen duplizieren'];
|
||||
$GLOBALS['TL_LANG']['tl_survey']['duplicateSurveyConfirm'] = 'Sind Sie sicher, dass Sie die Umfrage "%s" mit allen Fragen duplizieren wollen?';
|
||||
$GLOBALS['TL_LANG']['tl_survey']['duplicateSurveyDone'] = 'Die Umfrage "%s" wurde dupliziert.';
|
||||
$GLOBALS['TL_LANG']['tl_survey']['showResults'] = ['Ergebnisse anzeigen', 'Die Ergebnisse dieser Umfrage im Frontend anzeigen'];
|
||||
$GLOBALS['TL_LANG']['tl_survey']['createdBy'] = ['Angelegt von', 'ID des erstellenden Mitglieds.'];
|
||||
$GLOBALS['TL_LANG']['tl_survey']['updatedBy'] = ['Aktualisiert von', 'ID des zuletzt bearbeitenden Mitglieds.'];
|
||||
|
||||
@@ -25,6 +25,9 @@ $GLOBALS['TL_LANG']['tl_survey']['assignedMembers'] = ['Assigned members', 'Choo
|
||||
$GLOBALS['TL_LANG']['tl_survey']['assignedMembersFilter'] = ['Assigned users', 'Filters the list by an assigned user.'];
|
||||
$GLOBALS['TL_LANG']['tl_survey']['assignedMembersSummary'] = ['Assigned users', 'Comma-separated list of assigned users.'];
|
||||
$GLOBALS['TL_LANG']['tl_survey']['copyPublicLink'] = ['Copy link', 'Copy the public link to the clipboard'];
|
||||
$GLOBALS['TL_LANG']['tl_survey']['duplicateSurvey'] = ['Duplicate', 'Duplicate this survey with all questions'];
|
||||
$GLOBALS['TL_LANG']['tl_survey']['duplicateSurveyConfirm'] = 'Are you sure you want to duplicate the survey "%s" with all questions?';
|
||||
$GLOBALS['TL_LANG']['tl_survey']['duplicateSurveyDone'] = 'The survey "%s" has been duplicated.';
|
||||
$GLOBALS['TL_LANG']['tl_survey']['showResults'] = ['Show results', 'Display the results of this survey in the frontend'];
|
||||
$GLOBALS['TL_LANG']['tl_survey']['createdBy'] = ['Created by', 'ID of the creating member.'];
|
||||
$GLOBALS['TL_LANG']['tl_survey']['updatedBy'] = ['Updated by', 'ID of the member who last edited it.'];
|
||||
|
||||
@@ -326,10 +326,11 @@
|
||||
|
||||
.survey-list-card__footer {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
align-items: baseline;
|
||||
justify-content: space-between;
|
||||
gap: 0.75rem;
|
||||
flex-wrap: wrap;
|
||||
margin-top: .3em;
|
||||
}
|
||||
|
||||
.survey-list-card__stats {
|
||||
@@ -409,29 +410,25 @@
|
||||
}
|
||||
|
||||
.survey-visibility-dot {
|
||||
width: 2.2rem;
|
||||
height: 2.2rem;
|
||||
aspect-ratio: 1;
|
||||
height: 42px;
|
||||
border-radius: 999px;
|
||||
border: 1px solid rgba(162, 168, 180, 0.62);
|
||||
background: #7f8793;
|
||||
background: #a6adb7;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
cursor: pointer;
|
||||
transition: background 0.18s ease, border-color 0.18s ease, box-shadow 0.18s ease;
|
||||
transition: background 0.18s ease;
|
||||
}
|
||||
|
||||
.survey-visibility-dot.is-on {
|
||||
background: #0a8378;
|
||||
border-color: rgba(0, 174, 151, 0.68);
|
||||
box-shadow: 0 0 0 0.18rem rgba(0, 174, 151, 0.14);
|
||||
background: #0a832e;
|
||||
}
|
||||
|
||||
.survey-button-row {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 0.5rem;
|
||||
margin-top: 0.65rem;
|
||||
}
|
||||
|
||||
.survey-button-row--form-actions {
|
||||
|
||||
@@ -61,6 +61,13 @@
|
||||
{% if survey.resultsUrl %}
|
||||
<a class="survey-button secondary" href="{{ survey.resultsUrl }}" target="_blank" rel="noreferrer">{{ 'survey.list.show_results'|trans }}</a>
|
||||
{% endif %}
|
||||
<form method="post" class="survey-question-action-form">
|
||||
<input type="hidden" name="REQUEST_TOKEN" value="{{ contao.request_token }}">
|
||||
<input type="hidden" name="_survey_action" value="duplicate-survey">
|
||||
<input type="hidden" name="item_id" value="{{ survey.id }}">
|
||||
<input type="hidden" name="_token" value="{{ csrf_token('duplicate-survey-' ~ survey.id) }}">
|
||||
<button class="survey-button secondary" onclick="return confirm('{{ 'survey.list.duplicate_confirm'|trans({'%title%': survey.title|striptags|trim})|e('js') }}');">{{ 'survey.list.duplicate'|trans }}</button>
|
||||
</form>
|
||||
<form method="post" class="survey-question-action-form">
|
||||
<input type="hidden" name="REQUEST_TOKEN" value="{{ contao.request_token }}">
|
||||
<input type="hidden" name="_survey_action" value="delete-survey">
|
||||
|
||||
@@ -90,6 +90,11 @@ final class MemberSurveyListController extends AbstractFrontendModuleController
|
||||
$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.');
|
||||
|
||||
@@ -6,22 +6,30 @@ namespace Mummert\SurveyBundle\EventListener;
|
||||
|
||||
use Contao\Config;
|
||||
use Contao\CoreBundle\DataContainer\DataContainerOperation;
|
||||
use Contao\CoreBundle\Exception\RedirectResponseException;
|
||||
use Contao\CoreBundle\Routing\ContentUrlGenerator;
|
||||
use Contao\CoreBundle\Framework\ContaoFramework;
|
||||
use Contao\DataContainer;
|
||||
use Contao\Image;
|
||||
use Contao\Input;
|
||||
use Contao\Message;
|
||||
use Contao\PageModel;
|
||||
use Contao\StringUtil;
|
||||
use Contao\System;
|
||||
use Doctrine\DBAL\Connection;
|
||||
use Mummert\SurveyBundle\Repository\SurveyEditorRepository;
|
||||
use Mummert\SurveyBundle\Repository\SurveyQuestionRepository;
|
||||
use Mummert\SurveyBundle\Repository\SurveyRepository;
|
||||
use Mummert\SurveyBundle\Service\SurveyEditorService;
|
||||
use Mummert\SurveyBundle\Service\SurveyCategoryAssignmentService;
|
||||
use Symfony\Component\HttpFoundation\RequestStack;
|
||||
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
|
||||
|
||||
final class SurveyDcaListener
|
||||
{
|
||||
private ?SurveyEditorService $surveyEditorService;
|
||||
private ?RequestStack $requestStack;
|
||||
|
||||
public function __construct(
|
||||
private readonly SurveyRepository $surveyRepository,
|
||||
private readonly SurveyQuestionRepository $surveyQuestionRepository,
|
||||
@@ -30,7 +38,11 @@ final class SurveyDcaListener
|
||||
private readonly ContaoFramework $framework,
|
||||
private readonly Connection $connection,
|
||||
private readonly ContentUrlGenerator $contentUrlGenerator,
|
||||
?SurveyEditorService $surveyEditorService = null,
|
||||
?RequestStack $requestStack = null,
|
||||
) {
|
||||
$this->surveyEditorService = $surveyEditorService;
|
||||
$this->requestStack = $requestStack;
|
||||
}
|
||||
|
||||
public function generateSurveyAlias(mixed $value, DataContainer $dataContainer): string
|
||||
@@ -114,6 +126,51 @@ final class SurveyDcaListener
|
||||
));
|
||||
}
|
||||
|
||||
public function generateDuplicateSurveyButton(DataContainerOperation $operation): void
|
||||
{
|
||||
$row = $operation->getRecord() ?? [];
|
||||
$title = trim(strip_tags((string) ($row['title'] ?? '')));
|
||||
$confirmText = sprintf(
|
||||
$GLOBALS['TL_LANG']['tl_survey']['duplicateSurveyConfirm'] ?? 'Sind Sie sicher, dass Sie die Umfrage "%s" mit allen Fragen duplizieren wollen?',
|
||||
'' !== $title ? $title : '#'.(string) ($row['id'] ?? 0),
|
||||
);
|
||||
|
||||
$operation['label'] = $GLOBALS['TL_LANG']['tl_survey']['duplicateSurvey'][0] ?? 'Duplizieren';
|
||||
$operation['title'] = $GLOBALS['TL_LANG']['tl_survey']['duplicateSurvey'][1] ?? 'Diese Umfrage mit allen Fragen duplizieren';
|
||||
$operation['icon'] = 'copy.svg';
|
||||
$operation['attributes']
|
||||
->set('onclick', sprintf('if(!confirm(%s))return false;Backend.getScrollOffset()', json_encode($confirmText, JSON_THROW_ON_ERROR)))
|
||||
->set('data-contao--tooltips-target', 'tooltip')
|
||||
;
|
||||
}
|
||||
|
||||
public function handleDuplicateSurveyAction(): void
|
||||
{
|
||||
if ('duplicateSurvey' !== (string) Input::get('key')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$surveyId = (int) Input::get('id');
|
||||
|
||||
try {
|
||||
$survey = $this->surveyRepository->findById($surveyId);
|
||||
|
||||
if (null === $survey) {
|
||||
throw new \RuntimeException('Die Umfrage wurde nicht gefunden.');
|
||||
}
|
||||
|
||||
$duplicate = $this->getSurveyEditorService()->duplicateSurvey($survey);
|
||||
Message::addConfirmation(sprintf(
|
||||
$GLOBALS['TL_LANG']['tl_survey']['duplicateSurveyDone'] ?? 'Die Umfrage "%s" wurde dupliziert.',
|
||||
(string) $duplicate->title,
|
||||
));
|
||||
} catch (\Throwable $exception) {
|
||||
Message::addError($exception->getMessage());
|
||||
}
|
||||
|
||||
throw new RedirectResponseException($this->buildBackendListUrl());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<int, string>
|
||||
*/
|
||||
@@ -496,4 +553,54 @@ final class SurveyDcaListener
|
||||
{
|
||||
return (int) $this->framework->getAdapter(Config::class)->get($settingKey);
|
||||
}
|
||||
|
||||
private function buildBackendListUrl(): string
|
||||
{
|
||||
$request = $this->getRequestStack()->getCurrentRequest();
|
||||
|
||||
if (null === $request) {
|
||||
return '/contao';
|
||||
}
|
||||
|
||||
$query = $request->query->all();
|
||||
unset($query['key'], $query['id']);
|
||||
|
||||
$url = $request->getBaseUrl().$request->getPathInfo();
|
||||
|
||||
if ([] !== $query) {
|
||||
$url .= '?'.http_build_query($query);
|
||||
}
|
||||
|
||||
return $url;
|
||||
}
|
||||
|
||||
private function getSurveyEditorService(): SurveyEditorService
|
||||
{
|
||||
if ($this->surveyEditorService instanceof SurveyEditorService) {
|
||||
return $this->surveyEditorService;
|
||||
}
|
||||
|
||||
$service = System::getContainer()->get(SurveyEditorService::class);
|
||||
|
||||
if (!$service instanceof SurveyEditorService) {
|
||||
throw new \RuntimeException('SurveyEditorService konnte nicht geladen werden.');
|
||||
}
|
||||
|
||||
return $this->surveyEditorService = $service;
|
||||
}
|
||||
|
||||
private function getRequestStack(): RequestStack
|
||||
{
|
||||
if ($this->requestStack instanceof RequestStack) {
|
||||
return $this->requestStack;
|
||||
}
|
||||
|
||||
$service = System::getContainer()->get('request_stack');
|
||||
|
||||
if (!$service instanceof RequestStack) {
|
||||
throw new \RuntimeException('RequestStack konnte nicht geladen werden.');
|
||||
}
|
||||
|
||||
return $this->requestStack = $service;
|
||||
}
|
||||
}
|
||||
@@ -94,8 +94,9 @@ final class SurveyRepository
|
||||
'category' => serialize($this->normalizeCategoryIds($data['category'] ?? [])),
|
||||
'description' => (string) ($data['description'] ?? ''),
|
||||
'published' => '',
|
||||
'isActive' => '',
|
||||
'isActive' => '1',
|
||||
'isLocked' => '',
|
||||
'isTemplate' => !empty($data['isTemplate']) ? '1' : '',
|
||||
'createdBy' => $memberId,
|
||||
'updatedBy' => $memberId,
|
||||
'createdAt' => $now,
|
||||
|
||||
@@ -4,9 +4,11 @@ declare(strict_types=1);
|
||||
|
||||
namespace Mummert\SurveyBundle\Service;
|
||||
|
||||
use Doctrine\DBAL\Connection;
|
||||
use Mummert\SurveyBundle\Form\Model\SurveyConditionData;
|
||||
use Mummert\SurveyBundle\Form\Model\SurveyEditorData;
|
||||
use Mummert\SurveyBundle\Form\Model\SurveyQuestionData;
|
||||
use Mummert\SurveyBundle\Model\SurveyContentModel;
|
||||
use Mummert\SurveyBundle\Model\SurveyModel;
|
||||
use Mummert\SurveyBundle\Repository\SurveyConditionRepository;
|
||||
use Mummert\SurveyBundle\Repository\SurveyEditorRepository;
|
||||
@@ -21,6 +23,7 @@ final class SurveyEditorService
|
||||
private readonly SurveyConditionRepository $surveyConditionRepository,
|
||||
private readonly SurveyEditorRepository $surveyEditorRepository,
|
||||
private readonly SurveyCategoryAssignmentService $surveyCategoryAssignmentService,
|
||||
private readonly Connection $connection,
|
||||
) {
|
||||
}
|
||||
|
||||
@@ -99,6 +102,113 @@ final class SurveyEditorService
|
||||
$this->surveyRepository->deleteCascade((int) $survey->id);
|
||||
}
|
||||
|
||||
public function duplicateSurvey(SurveyModel $survey, ?int $actorMemberId = null): SurveyModel
|
||||
{
|
||||
return $this->connection->transactional(function () use ($survey, $actorMemberId): SurveyModel {
|
||||
$sourceSurveyId = (int) $survey->id;
|
||||
$memberIds = $this->surveyEditorRepository->findMemberIdsBySurvey($sourceSurveyId);
|
||||
$duplicate = $this->surveyRepository->create($actorMemberId ?? (int) ($survey->createdBy ?? 0), [
|
||||
'title' => $this->buildDuplicateTitle((string) $survey->title),
|
||||
'description' => (string) ($survey->description ?? ''),
|
||||
'category' => $survey->category,
|
||||
'isTemplate' => '1' === (string) ($survey->isTemplate ?? ''),
|
||||
]);
|
||||
|
||||
$duplicateSurveyId = (int) $duplicate->id;
|
||||
|
||||
if ([] !== $memberIds) {
|
||||
$this->surveyEditorRepository->syncMembersForSurvey($duplicateSurveyId, $memberIds);
|
||||
}
|
||||
|
||||
$duplicateQuestions = [];
|
||||
$questionIdMap = [];
|
||||
$sourceQuestions = $this->surveyQuestionRepository->findAllBySurvey($sourceSurveyId);
|
||||
|
||||
foreach ($sourceQuestions as $sourceQuestion) {
|
||||
$newQuestion = $this->surveyQuestionRepository->create($duplicateSurveyId, [
|
||||
'type' => (string) $sourceQuestion->type,
|
||||
'question' => (string) $sourceQuestion->question,
|
||||
'description' => (string) ($sourceQuestion->description ?? ''),
|
||||
'mandatory' => '1' === (string) $sourceQuestion->mandatory,
|
||||
'published' => '1' === (string) $sourceQuestion->published,
|
||||
'allowMaybe' => '1' === (string) ($sourceQuestion->allowMaybe ?? ''),
|
||||
'allowMultiple' => '1' === (string) ($sourceQuestion->allowMultiple ?? ''),
|
||||
'answerOption1' => (string) ($sourceQuestion->answerOption1 ?? ''),
|
||||
'answerOption2' => (string) ($sourceQuestion->answerOption2 ?? ''),
|
||||
'answerOption3' => (string) ($sourceQuestion->answerOption3 ?? ''),
|
||||
'answerOption4' => (string) ($sourceQuestion->answerOption4 ?? ''),
|
||||
'answerOption5' => (string) ($sourceQuestion->answerOption5 ?? ''),
|
||||
'answerOption6' => (string) ($sourceQuestion->answerOption6 ?? ''),
|
||||
'answerOption7' => (string) ($sourceQuestion->answerOption7 ?? ''),
|
||||
'answerOption8' => (string) ($sourceQuestion->answerOption8 ?? ''),
|
||||
'answerOption9' => (string) ($sourceQuestion->answerOption9 ?? ''),
|
||||
'answerOption10' => (string) ($sourceQuestion->answerOption10 ?? ''),
|
||||
'rangeMin' => (int) ($sourceQuestion->rangeMin ?? 0),
|
||||
'rangeMax' => (int) ($sourceQuestion->rangeMax ?? 10),
|
||||
'rangeStep' => (int) ($sourceQuestion->rangeStep ?? 1),
|
||||
'jumpOnYes' => 0,
|
||||
'jumpOnNo' => 0,
|
||||
]);
|
||||
|
||||
$sourceQuestionId = (int) $sourceQuestion->id;
|
||||
$questionIdMap[$sourceQuestionId] = (int) $newQuestion->id;
|
||||
$duplicateQuestions[$sourceQuestionId] = $newQuestion;
|
||||
}
|
||||
|
||||
foreach ($sourceQuestions as $sourceQuestion) {
|
||||
$sourceQuestionId = (int) $sourceQuestion->id;
|
||||
$duplicateQuestion = $duplicateQuestions[$sourceQuestionId] ?? null;
|
||||
|
||||
if (!$duplicateQuestion instanceof SurveyContentModel) {
|
||||
throw new \RuntimeException('Fragenkopie konnte nicht vervollständigt werden.');
|
||||
}
|
||||
|
||||
$this->surveyQuestionRepository->update($duplicateQuestion, [
|
||||
'type' => (string) $sourceQuestion->type,
|
||||
'question' => (string) $sourceQuestion->question,
|
||||
'description' => (string) ($sourceQuestion->description ?? ''),
|
||||
'mandatory' => '1' === (string) $sourceQuestion->mandatory,
|
||||
'published' => '1' === (string) $sourceQuestion->published,
|
||||
'allowMaybe' => '1' === (string) ($sourceQuestion->allowMaybe ?? ''),
|
||||
'allowMultiple' => '1' === (string) ($sourceQuestion->allowMultiple ?? ''),
|
||||
'answerOption1' => (string) ($sourceQuestion->answerOption1 ?? ''),
|
||||
'answerOption2' => (string) ($sourceQuestion->answerOption2 ?? ''),
|
||||
'answerOption3' => (string) ($sourceQuestion->answerOption3 ?? ''),
|
||||
'answerOption4' => (string) ($sourceQuestion->answerOption4 ?? ''),
|
||||
'answerOption5' => (string) ($sourceQuestion->answerOption5 ?? ''),
|
||||
'answerOption6' => (string) ($sourceQuestion->answerOption6 ?? ''),
|
||||
'answerOption7' => (string) ($sourceQuestion->answerOption7 ?? ''),
|
||||
'answerOption8' => (string) ($sourceQuestion->answerOption8 ?? ''),
|
||||
'answerOption9' => (string) ($sourceQuestion->answerOption9 ?? ''),
|
||||
'answerOption10' => (string) ($sourceQuestion->answerOption10 ?? ''),
|
||||
'rangeMin' => (int) ($sourceQuestion->rangeMin ?? 0),
|
||||
'rangeMax' => (int) ($sourceQuestion->rangeMax ?? 10),
|
||||
'rangeStep' => (int) ($sourceQuestion->rangeStep ?? 1),
|
||||
'jumpOnYes' => $questionIdMap[(int) ($sourceQuestion->jumpOnYes ?? 0)] ?? 0,
|
||||
'jumpOnNo' => $questionIdMap[(int) ($sourceQuestion->jumpOnNo ?? 0)] ?? 0,
|
||||
]);
|
||||
}
|
||||
|
||||
foreach ($this->surveyConditionRepository->findOverviewBySurvey($sourceSurveyId) as $condition) {
|
||||
$sourceQuestionId = $questionIdMap[(int) ($condition['sourceQuestion'] ?? 0)] ?? 0;
|
||||
|
||||
if ($sourceQuestionId <= 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->surveyConditionRepository->create($duplicateSurveyId, [
|
||||
'sourceQuestion' => $sourceQuestionId,
|
||||
'answerValue' => (string) ($condition['answerValue'] ?? ''),
|
||||
'targetQuestion' => $questionIdMap[(int) ($condition['targetQuestion'] ?? 0)] ?? 0,
|
||||
]);
|
||||
}
|
||||
|
||||
$this->surveyRepository->refreshListMetadata($duplicateSurveyId);
|
||||
|
||||
return $this->surveyRepository->findById($duplicateSurveyId) ?? throw new \RuntimeException('Umfragekopie konnte nicht angelegt werden.');
|
||||
});
|
||||
}
|
||||
|
||||
public function saveCondition(SurveyModel $survey, SurveyConditionData $data, int $conditionId = 0): void
|
||||
{
|
||||
$this->assertUnlocked($survey);
|
||||
@@ -133,4 +243,15 @@ final class SurveyEditorService
|
||||
throw new \RuntimeException('Die Fragen dieser Umfrage können nach der Veröffentlichung oder nach ersten Teilnahmen nicht mehr geändert werden.');
|
||||
}
|
||||
}
|
||||
|
||||
private function buildDuplicateTitle(string $title): string
|
||||
{
|
||||
$title = trim($title);
|
||||
|
||||
if ('' === $title) {
|
||||
$title = 'Neue Umfrage';
|
||||
}
|
||||
|
||||
return mb_substr($title.' - Kopie', 0, 255);
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,8 @@ 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."
|
||||
create: "Neue Umfrage anlegen"
|
||||
duplicate: "Duplizieren"
|
||||
duplicate_confirm: "Sind Sie sicher, dass Sie die Umfrage \"%title%\" mit allen Fragen duplizieren wollen?"
|
||||
delete: "Löschen"
|
||||
delete_confirm: "Umfrage wirklich löschen? Damit werden auch alle Fragen, Antworten und Ergebnisse endgültig gelöscht. Alternativ können Sie die Umfrage auch einfach vorübergehend deaktivieren."
|
||||
delete_confirm_second: "Wirklich sicher?"
|
||||
|
||||
@@ -2,6 +2,8 @@ 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."
|
||||
create: "Create new survey"
|
||||
duplicate: "Duplicate"
|
||||
duplicate_confirm: "Are you sure you want to duplicate the survey \"%title%\" with all questions?"
|
||||
delete: "Delete"
|
||||
delete_confirm: "Delete this survey? This will permanently remove all questions, answers, and results as well. Alternatively, you can simply deactivate the survey temporarily."
|
||||
delete_confirm_second: "Are you really sure?"
|
||||
|
||||
Reference in New Issue
Block a user