Add survey duplication actions
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user