fixed #10565: Survey: add question doing double-create
This commit is contained in:
parent
3fccab7743
commit
b5186bfbab
5 changed files with 79 additions and 31 deletions
|
|
@ -1,6 +1,7 @@
|
||||||
7.7.12
|
7.7.12
|
||||||
- Updated auth to allow sending back of non-text/html mime types.
|
- Updated auth to allow sending back of non-text/html mime types.
|
||||||
- fixed #10564: edit branch progress bar goes kablooey
|
- fixed #10564: edit branch progress bar goes kablooey
|
||||||
|
- fixed #10565: Survey: add question doing double-create
|
||||||
|
|
||||||
7.7.11
|
7.7.11
|
||||||
- Fixed a bug where empty version tags were not deleted. (Martin Kamerbeek / Oqapi)
|
- Fixed a bug where empty version tags were not deleted. (Martin Kamerbeek / Oqapi)
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ use Getopt::Long;
|
||||||
use WebGUI::Session;
|
use WebGUI::Session;
|
||||||
use WebGUI::Storage;
|
use WebGUI::Storage;
|
||||||
use WebGUI::Asset;
|
use WebGUI::Asset;
|
||||||
|
use WebGUI::Asset::Wobject::Survey;
|
||||||
|
|
||||||
my $toVersion = '7.7.12';
|
my $toVersion = '7.7.12';
|
||||||
my $quiet; # this line required
|
my $quiet; # this line required
|
||||||
|
|
@ -31,6 +31,7 @@ my $quiet; # this line required
|
||||||
my $session = start(); # this line required
|
my $session = start(); # this line required
|
||||||
|
|
||||||
# upgrade functions go here
|
# upgrade functions go here
|
||||||
|
surveyCleanUp($session);
|
||||||
|
|
||||||
finish($session); # this line required
|
finish($session); # this line required
|
||||||
|
|
||||||
|
|
@ -44,6 +45,38 @@ finish($session); # this line required
|
||||||
# print "DONE!\n" unless $quiet;
|
# print "DONE!\n" unless $quiet;
|
||||||
#}
|
#}
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------------
|
||||||
|
sub surveyCleanUp {
|
||||||
|
my $session = shift;
|
||||||
|
print "\tRemoving extra properties that may have crept into surveyJSON... " unless $quiet;
|
||||||
|
|
||||||
|
my $sth = $session->db->read('select assetId, revisionDate from Survey');
|
||||||
|
|
||||||
|
while (my ($assetId, $revision) = $sth->array) {
|
||||||
|
my $survey = WebGUI::Asset->new($session, $assetId, 'WebGUI::Asset::Wobject::Survey', $revision);
|
||||||
|
|
||||||
|
# Remove recursive properties that snuck into the mold
|
||||||
|
if (my $mold = $survey->surveyJSON->mold) {
|
||||||
|
$mold->{question}{answers} = [];
|
||||||
|
$mold->{section}{questions} = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
# Remove keys that should never have been added to sections/questions/answers
|
||||||
|
for my $s (@{$survey->surveyJSON->sections}) {
|
||||||
|
for my $q (@{$s->{questions} || []}) {
|
||||||
|
for my $a (@{$q->{answers} || []}) {
|
||||||
|
delete $a->{$_} for qw(delete copy removetype addtype func);
|
||||||
|
}
|
||||||
|
delete $q->{$_} for qw(delete copy removetype addtype func);
|
||||||
|
}
|
||||||
|
delete $s->{$_} for qw(delete copy removetype addtype func);
|
||||||
|
}
|
||||||
|
$survey->persistSurveyJSON;
|
||||||
|
}
|
||||||
|
|
||||||
|
print "DONE!\n" unless $quiet;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
# -------------- DO NOT EDIT BELOW THIS LINE --------------------------------
|
# -------------- DO NOT EDIT BELOW THIS LINE --------------------------------
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -828,9 +828,7 @@ sub www_submitObjectEdit {
|
||||||
return $self->session->privilege->insufficient()
|
return $self->session->privilege->insufficient()
|
||||||
unless $self->session->user->isInGroup( $self->get('groupToEditSurvey') );
|
unless $self->session->user->isInGroup( $self->get('groupToEditSurvey') );
|
||||||
|
|
||||||
my $params = $self->session->form->paramsHashRef();
|
return $self->submitObjectEdit( $self->session->form->paramsHashRef );
|
||||||
|
|
||||||
return $self->submitObjectEdit($params);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#-------------------------------------------------------------------
|
#-------------------------------------------------------------------
|
||||||
|
|
@ -989,10 +987,13 @@ See L<WebGUI::Asset::Wobject::Survey::SurveyJSON/Address Parameter>
|
||||||
|
|
||||||
sub deleteObject {
|
sub deleteObject {
|
||||||
my ( $self, $address ) = @_;
|
my ( $self, $address ) = @_;
|
||||||
|
|
||||||
|
$self->session->log->debug("Deleting object: " . join '-', @$address);
|
||||||
|
|
||||||
# Each object checks the ref and then either updates or passes it to the correct child.
|
# Each object checks the ref and then either updates or passes it to the correct child.
|
||||||
# New objects will have an index of -1.
|
# New objects will have an index of -1.
|
||||||
my $message = $self->surveyJSON_remove($address);
|
my $message = $self->surveyJSON_remove($address);
|
||||||
|
$self->session->log->debug(Dumper($self->surveyJSON->{_sections}));
|
||||||
|
|
||||||
# The parent address of the deleted object is returned.
|
# The parent address of the deleted object is returned.
|
||||||
if ( @{$address} == 1 ) {
|
if ( @{$address} == 1 ) {
|
||||||
|
|
@ -1054,13 +1055,15 @@ sub www_dragDrop {
|
||||||
my @bid = split /-/, $p->{before}->{id};
|
my @bid = split /-/, $p->{before}->{id};
|
||||||
|
|
||||||
my $target = $self->surveyJSON->getObject( \@tid );
|
my $target = $self->surveyJSON->getObject( \@tid );
|
||||||
$self->surveyJSON_remove( \@tid, 1 );
|
$self->surveyJSON->remove( \@tid, 1 );
|
||||||
my $address = [0];
|
my $address = [0];
|
||||||
if ( @tid == 1 ) {
|
if ( @tid == 1 ) {
|
||||||
|
|
||||||
#sections can only be inserted after another section so chop off the question and answer portion of
|
#sections can only be inserted after another section so chop off the question and answer portion of
|
||||||
$#bid = 0;
|
$#bid = 0;
|
||||||
$bid[0] = -1 if ( !defined $bid[0] );
|
$bid[0] = -1 if ( !defined $bid[0] );
|
||||||
|
|
||||||
|
$self->session->log->debug("Moving section $bid[0] to $tid[0]");
|
||||||
|
|
||||||
#If target is being moved down, then before has just moved up do to the target being deleted
|
#If target is being moved down, then before has just moved up do to the target being deleted
|
||||||
$bid[0]-- if($tid[0] < $bid[0]);
|
$bid[0]-- if($tid[0] < $bid[0]);
|
||||||
|
|
@ -1924,7 +1927,6 @@ sub persistSurveyJSON {
|
||||||
|
|
||||||
my $data = $self->surveyJSON->freeze();
|
my $data = $self->surveyJSON->freeze();
|
||||||
$self->update({surveyJSON=>$data});
|
$self->update({surveyJSON=>$data});
|
||||||
# $self->session->db->write( 'update Survey set surveyJSON = ? where assetId = ?', [ $data, $self->getId ] );
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -244,21 +244,21 @@ sub newObject {
|
||||||
|
|
||||||
if ( $count == 0 ) {
|
if ( $count == 0 ) {
|
||||||
# Add a new section to the end of the list of sections..
|
# Add a new section to the end of the list of sections..
|
||||||
push @{ $self->sections }, $self->newSection();
|
push @{ $self->{_sections} }, $self->newSection();
|
||||||
|
|
||||||
# Update $address with the index of the newly created section
|
# Update $address with the index of the newly created section
|
||||||
$address->[0] = $self->lastSectionIndex;
|
$address->[0] = $self->lastSectionIndex;
|
||||||
}
|
}
|
||||||
elsif ( $count == 1 ) {
|
elsif ( $count == 1 ) {
|
||||||
# Add a new question to the end of the list of questions in section located at $address
|
# Add a new question to the end of the list of questions in section located at $address
|
||||||
push @{ $self->questions($address) }, $self->newQuestion($address);
|
push @{ $self->section($address)->{questions} }, $self->newQuestion($address);
|
||||||
|
|
||||||
# Update $address with the index of the newly created question
|
# Update $address with the index of the newly created question
|
||||||
$address->[1] = $self->lastQuestionIndex($address);
|
$address->[1] = $self->lastQuestionIndex($address);
|
||||||
}
|
}
|
||||||
elsif ( $count == 2 ) {
|
elsif ( $count == 2 ) {
|
||||||
# Add a new answer to the end of the list of answers in section/question located at $address
|
# Add a new answer to the end of the list of answers in section/question located at $address
|
||||||
push @{ $self->answers($address) }, $self->newAnswer($address);
|
push @{ $self->question($address)->{answers} }, $self->newAnswer($address);
|
||||||
|
|
||||||
# Update $address with the index of the newly created answer
|
# Update $address with the index of the newly created answer
|
||||||
$address->[2] = $self->lastAnswerIndex($address);
|
$address->[2] = $self->lastAnswerIndex($address);
|
||||||
|
|
@ -674,18 +674,21 @@ sub uncompress {
|
||||||
my ($smold, $qmold, $amold) = @{$self->mold}{'section', 'question', 'answer'};
|
my ($smold, $qmold, $amold) = @{$self->mold}{'section', 'question', 'answer'};
|
||||||
|
|
||||||
# Iterate over all objects, adding back in the missing properties
|
# Iterate over all objects, adding back in the missing properties
|
||||||
for my $s (@{$sections || []}) {
|
for my $s (@$sections) {
|
||||||
for my $q (@{$s->{questions} || []}) {
|
for my $q (@{$s->{questions} || []}) {
|
||||||
for my $a (@{$q->{answers} || []}) {
|
for my $a (@{$q->{answers} || []}) {
|
||||||
while (my($key, $value) = each %$amold) {
|
while (my($key, $value) = each %$amold) {
|
||||||
|
next if ref $value;
|
||||||
$a->{$key} = $value unless exists $a->{$key};
|
$a->{$key} = $value unless exists $a->{$key};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
while (my($key, $value) = each %$qmold) {
|
while (my($key, $value) = each %$qmold) {
|
||||||
|
next if ref $value;
|
||||||
$q->{$key} = $value unless exists $q->{$key};
|
$q->{$key} = $value unless exists $q->{$key};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
while (my($key, $value) = each %$smold) {
|
while (my($key, $value) = each %$smold) {
|
||||||
|
next if ref $value;
|
||||||
$s->{$key} = $value unless exists $s->{$key};
|
$s->{$key} = $value unless exists $s->{$key};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -751,7 +754,7 @@ sub update {
|
||||||
$object = $self->section($address);
|
$object = $self->section($address);
|
||||||
if ( !defined $object ) {
|
if ( !defined $object ) {
|
||||||
$object = $self->newSection();
|
$object = $self->newSection();
|
||||||
push @{ $self->sections }, $object;
|
push @{ $self->{_sections} }, $object;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
elsif ( $count == 2 ) {
|
elsif ( $count == 2 ) {
|
||||||
|
|
@ -759,7 +762,7 @@ sub update {
|
||||||
if ( !defined $object ) {
|
if ( !defined $object ) {
|
||||||
$object = $self->newQuestion();
|
$object = $self->newQuestion();
|
||||||
$newQuestion = 1; # make note that a new question was created
|
$newQuestion = 1; # make note that a new question was created
|
||||||
push @{ $self->questions($address) }, $object;
|
push @{ $self->section($address)->{questions} }, $object;
|
||||||
}
|
}
|
||||||
# If questionType supplied, see if we need to update all of the answers to reflect the new questionType
|
# If questionType supplied, see if we need to update all of the answers to reflect the new questionType
|
||||||
if ( $properties->{questionType} && $properties->{questionType} ne $object->{questionType} ) {
|
if ( $properties->{questionType} && $properties->{questionType} ne $object->{questionType} ) {
|
||||||
|
|
@ -770,17 +773,26 @@ sub update {
|
||||||
$object = $self->answer($address);
|
$object = $self->answer($address);
|
||||||
if ( !defined $object ) {
|
if ( !defined $object ) {
|
||||||
$object = $self->newAnswer();
|
$object = $self->newAnswer();
|
||||||
push @{ $self->answers($address) }, $object;
|
push @{ $self->question($address)->{answers} }, $object;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$self->_handleSpecialAnswerUpdates($address,$properties);
|
$self->_handleSpecialAnswerUpdates($address,$properties);
|
||||||
|
|
||||||
|
my $validSectionProps = $self->newSection;
|
||||||
|
my $validQuestionProps = $self->newQuestion;
|
||||||
|
my $validAnswerProps = $self->newAnswer;
|
||||||
|
|
||||||
# Update $object with all of the data in $properties
|
# Update $object with all of the data in $properties
|
||||||
while (my ($key, $value) = each %{$properties}) {
|
while (my ($key, $value) = each %{$properties}) {
|
||||||
if (defined $value) {
|
if (defined $value) {
|
||||||
$object->{$key} = $value;
|
$object->{$key} = $value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Only allow properties that we know about
|
||||||
|
delete $object->{$key} if $count == 1 and !exists $validSectionProps->{$key};
|
||||||
|
delete $object->{$key} if $count == 2 and !exists $validQuestionProps->{$key};
|
||||||
|
delete $object->{$key} if $count == 3 and !exists $validAnswerProps->{$key};
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
@ -849,15 +861,15 @@ sub insertObject {
|
||||||
|
|
||||||
# Use splice to rearrange the relevant array of objects..
|
# Use splice to rearrange the relevant array of objects..
|
||||||
if ( $count == 1 ) {
|
if ( $count == 1 ) {
|
||||||
splice @{ $self->sections($address) }, sIndex($address) +1, 0, $object;
|
splice @{ $self->{_sections} }, sIndex($address) +1, 0, $object;
|
||||||
$address->[0]++;
|
$address->[0]++;
|
||||||
}
|
}
|
||||||
elsif ( $count == 2 ) {
|
elsif ( $count == 2 ) {
|
||||||
splice @{ $self->questions($address) }, qIndex($address) + 1, 0, $object;
|
splice @{ $self->section($address)->{questions} }, qIndex($address) + 1, 0, $object;
|
||||||
$address->[1]++;
|
$address->[1]++;
|
||||||
}
|
}
|
||||||
elsif ( $count == 3 ) {
|
elsif ( $count == 3 ) {
|
||||||
splice @{ $self->answers($address) }, aIndex($address) + 1, 0, $object;
|
splice @{ $self->question($address)->{answers} }, aIndex($address) + 1, 0, $object;
|
||||||
$address->[2]++;
|
$address->[2]++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -903,21 +915,21 @@ sub copy {
|
||||||
|
|
||||||
if ( $count == 1 ) {
|
if ( $count == 1 ) {
|
||||||
# Clone the indexed section onto the end of the list of sections..
|
# Clone the indexed section onto the end of the list of sections..
|
||||||
push @{ $self->sections }, clone $self->section($address);
|
push @{ $self->{_sections} }, clone $self->section($address);
|
||||||
|
|
||||||
# Update $address with the index of the newly created section
|
# Update $address with the index of the newly created section
|
||||||
$address->[0] = $self->lastSectionIndex;
|
$address->[0] = $self->lastSectionIndex;
|
||||||
}
|
}
|
||||||
elsif ( $count == 2 ) {
|
elsif ( $count == 2 ) {
|
||||||
# Clone the indexed question onto the end of the list of questions..
|
# Clone the indexed question onto the end of the list of questions..
|
||||||
push @{ $self->questions($address) }, clone $self->question($address);
|
push @{ $self->section($address)->{questions} }, clone $self->question($address);
|
||||||
|
|
||||||
# Update $address with the index of the newly created question
|
# Update $address with the index of the newly created question
|
||||||
$address->[1] = $self->lastQuestionIndex($address);
|
$address->[1] = $self->lastQuestionIndex($address);
|
||||||
}
|
}
|
||||||
elsif ( $count == 3 ) {
|
elsif ( $count == 3 ) {
|
||||||
# Clone the indexed answer onto the end of the list of answers..
|
# Clone the indexed answer onto the end of the list of answers..
|
||||||
push @{ $self->answers($address) }, clone $self->answer($address);
|
push @{ $self->question($address)->{answers} }, clone $self->answer($address);
|
||||||
|
|
||||||
# Update $address with the index of the newly created answer
|
# Update $address with the index of the newly created answer
|
||||||
$address->[2]++;
|
$address->[2]++;
|
||||||
|
|
@ -969,14 +981,14 @@ sub remove {
|
||||||
if ( $count == 1 ) {
|
if ( $count == 1 ) {
|
||||||
# Make sure the first section isn't removed unless we REALLY want to
|
# Make sure the first section isn't removed unless we REALLY want to
|
||||||
if ( sIndex($address) != 0 || defined $movingOverride ) {
|
if ( sIndex($address) != 0 || defined $movingOverride ) {
|
||||||
splice @{ $self->sections }, sIndex($address), 1;
|
splice @{ $self->{_sections} }, sIndex($address), 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
elsif ( $count == 2 ) {
|
elsif ( $count == 2 ) {
|
||||||
splice @{ $self->questions($address) }, qIndex($address), 1;
|
splice @{ $self->section($address)->{questions} }, qIndex($address), 1;
|
||||||
}
|
}
|
||||||
elsif ( $count == 3 ) {
|
elsif ( $count == 3 ) {
|
||||||
splice @{ $self->answers($address) }, aIndex($address), 1;
|
splice @{ $self->question($address)->{answers} }, aIndex($address), 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
@ -1190,7 +1202,7 @@ Returns a reference to all the sections in this object.
|
||||||
|
|
||||||
sub sections {
|
sub sections {
|
||||||
my $self = shift;
|
my $self = shift;
|
||||||
return $self->{_sections};
|
return $self->{_sections} || [];
|
||||||
}
|
}
|
||||||
|
|
||||||
=head2 mold
|
=head2 mold
|
||||||
|
|
@ -1259,7 +1271,7 @@ Returns the total number of Sections
|
||||||
|
|
||||||
sub totalSections {
|
sub totalSections {
|
||||||
my $self = shift;
|
my $self = shift;
|
||||||
return scalar @{ $self->sections || [] };
|
return scalar @{ $self->sections };
|
||||||
}
|
}
|
||||||
|
|
||||||
=head2 totalQuestions ($address)
|
=head2 totalQuestions ($address)
|
||||||
|
|
@ -1277,7 +1289,7 @@ sub totalQuestions {
|
||||||
my ($address) = validate_pos(@_, { type => ARRAYREF, optional => 1 });
|
my ($address) = validate_pos(@_, { type => ARRAYREF, optional => 1 });
|
||||||
|
|
||||||
if ($address) {
|
if ($address) {
|
||||||
return scalar @{ $self->questions($address) || [] };
|
return scalar @{ $self->questions($address) };
|
||||||
} else {
|
} else {
|
||||||
my $count = 0;
|
my $count = 0;
|
||||||
for my $sIndex (0 .. $self->lastSectionIndex) {
|
for my $sIndex (0 .. $self->lastSectionIndex) {
|
||||||
|
|
@ -1302,7 +1314,7 @@ sub totalAnswers {
|
||||||
my ($address) = validate_pos(@_, { type => ARRAYREF, optional => 1 });
|
my ($address) = validate_pos(@_, { type => ARRAYREF, optional => 1 });
|
||||||
|
|
||||||
if ($address) {
|
if ($address) {
|
||||||
return scalar @{ $self->answers($address) || [] };
|
return scalar @{ $self->answers($address) };
|
||||||
} else {
|
} else {
|
||||||
my $count = 0;
|
my $count = 0;
|
||||||
for my $sIndex (0 .. $self->lastSectionIndex) {
|
for my $sIndex (0 .. $self->lastSectionIndex) {
|
||||||
|
|
@ -1521,11 +1533,11 @@ sub questions {
|
||||||
my ($address) = validate_pos(@_, { type => ARRAYREF, optional => 1});
|
my ($address) = validate_pos(@_, { type => ARRAYREF, optional => 1});
|
||||||
|
|
||||||
if ($address) {
|
if ($address) {
|
||||||
return $self->sections->[ $address->[0] ]->{questions};
|
return $self->sections->[ $address->[0] ]->{questions} || [];
|
||||||
} else {
|
} else {
|
||||||
my $questions;
|
my $questions;
|
||||||
push @$questions, @{$_->{questions} || []} for @{$self->sections};
|
push @$questions, @{$_->{questions} || []} for @{$self->sections};
|
||||||
return $questions;
|
return $questions || [];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1579,7 +1591,7 @@ sub answers {
|
||||||
my $self = shift;
|
my $self = shift;
|
||||||
my ($address) = validate_pos(@_, { type => ARRAYREF});
|
my ($address) = validate_pos(@_, { type => ARRAYREF});
|
||||||
|
|
||||||
return $self->sections->[ $address->[0] ]->{questions}->[ $address->[1] ]->{answers};
|
return $self->sections->[ $address->[0] ]->{questions}->[ $address->[1] ]->{answers} || [];
|
||||||
}
|
}
|
||||||
|
|
||||||
=head2 answer ($address)
|
=head2 answer ($address)
|
||||||
|
|
|
||||||
|
|
@ -1980,7 +1980,7 @@ cmp_deeply(
|
||||||
$address = $s->newObject([0]);
|
$address = $s->newObject([0]);
|
||||||
is(scalar @{$s->questions}, 1, '..now 1 question');
|
is(scalar @{$s->questions}, 1, '..now 1 question');
|
||||||
is(scalar @{$s->questions([0])}, 1, '..in the first section');
|
is(scalar @{$s->questions([0])}, 1, '..in the first section');
|
||||||
is($s->questions([2]), undef, '..and none in the second section (which doesnt even exist)');
|
cmp_deeply($s->questions([2]), [], '..and none in the second section (which doesnt even exist)');
|
||||||
|
|
||||||
# Add a question to second section
|
# Add a question to second section
|
||||||
$address = $s->newObject([1]);
|
$address = $s->newObject([1]);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue