diff --git a/docs/upgrades/packages-7.7.6/root_import_survey_default-feedback.wgpkg b/docs/upgrades/packages-7.7.6/root_import_survey_default-feedback.wgpkg new file mode 100644 index 000000000..ed73251eb Binary files /dev/null and b/docs/upgrades/packages-7.7.6/root_import_survey_default-feedback.wgpkg differ diff --git a/docs/upgrades/packages-7.7.6/root_import_survey_default-survey.wgpkg b/docs/upgrades/packages-7.7.6/root_import_survey_default-survey.wgpkg index c7df236cb..77153babd 100644 Binary files a/docs/upgrades/packages-7.7.6/root_import_survey_default-survey.wgpkg and b/docs/upgrades/packages-7.7.6/root_import_survey_default-survey.wgpkg differ diff --git a/docs/upgrades/upgrade_7.7.5-7.7.6.pl b/docs/upgrades/upgrade_7.7.5-7.7.6.pl index e2abc490a..7fee6449c 100644 --- a/docs/upgrades/upgrade_7.7.5-7.7.6.pl +++ b/docs/upgrades/upgrade_7.7.5-7.7.6.pl @@ -36,6 +36,7 @@ addEuVatDbColumns( $session ); addShippingDrivers( $session ); addTransactionTaxColumns( $session ); addListingsCacheTimeoutToMatrix( $session ); +addSurveyFeedbackTemplateColumn( $session ); finish($session); @@ -116,7 +117,7 @@ sub addShippingDrivers { sub addEuVatDbColumns { my $session = shift; print "\tAdding columns for improved VAT number checking..." unless $quiet; - + $session->db->write( 'alter table tax_eu_vatNumbers add column viesErrorCode int(3) default NULL' ); print "Done\n" unless $quiet; @@ -135,6 +136,16 @@ sub addTransactionTaxColumns { } +#---------------------------------------------------------------------------- +sub addSurveyFeedbackTemplateColumn { + my $session = shift; + print "\tAdding columns for Survey Feedback Template..." unless $quiet; + $session->db->write("alter table Survey add column `feedbackTemplateId` char(22)"); + + print "Done\n" unless $quiet; + +} + # -------------- DO NOT EDIT BELOW THIS LINE -------------------------------- #---------------------------------------------------------------------------- diff --git a/lib/WebGUI/Asset/Wobject/Survey.pm b/lib/WebGUI/Asset/Wobject/Survey.pm index 448f70a79..9a7d5c623 100644 --- a/lib/WebGUI/Asset/Wobject/Survey.pm +++ b/lib/WebGUI/Asset/Wobject/Survey.pm @@ -168,6 +168,14 @@ sub definition { defaultValue => 'AjhlNO3wZvN5k4i4qioWcg', namespace => 'Survey/Edit', }, + feedbackTemplateId => { + tab => 'display', + fieldType => 'template', + defaultValue => 'nWNVoMLrMo059mDRmfOp9g', + label => $i18n->get('Feedback Template'), + hoverHelp => $i18n->get('Feedback Template help'), + namespace => 'Survey/Feedback', + }, overviewTemplateId => { tab => 'display', fieldType => 'template', @@ -1212,16 +1220,15 @@ sub view { my $self = shift; my $var = $self->getMenuVars; - my ($lastResponseCompleteCode, $lastResponseEndDate) = $self->getLastResponseDetails(); - - $var->{lastResponseCompleted} = $lastResponseCompleteCode == 1; - $var->{lastResponseEndDate} = WebGUI::DateTime->new($self->session, $lastResponseEndDate)->toUserTimeZone; - $var->{lastResponseTimedOut} = $lastResponseCompleteCode == 3; + my $responseDetails = $self->getResponseDetails(); + + # Add lastResponse template vars + for my $tv qw(endDate feedback complete restart timeout timeoutRestart) { + $var->{"lastResponse\u$tv"} = $responseDetails->{$tv}; + } $var->{maxResponsesSubmitted} = !$self->canTakeSurvey(); - my $out = $self->processTemplate( $var, undef, $self->{_viewTemplate} ); - - return $out; + return $self->processTemplate( $var, undef, $self->{_viewTemplate} ); } #------------------------------------------------------------------- @@ -1251,57 +1258,91 @@ sub getMenuVars { #------------------------------------------------------------------- -=head2 getLastResponseDetails ( ) +=head2 getResponseDetails ( [$responseId] ) -Gets the completeCode and endDate for the most recent response +Looks up details about a given response. + +=head3 responseId + +A specific responseId to use. If none given, the most recent completed response is used. =cut -sub getLastResponseDetails { +sub getResponseDetails { my $self = shift; - - my ($lastResponseCompleteCode, $lastResponseEndDate); - - my $userId = $self->session->user->userId(); - my $anonId - = $self->session->form->process('userid') - || $self->session->http->getCookies->{Survey2AnonId} - || undef; - $anonId && $self->session->http->setCookie( Survey2AnonId => $anonId ); - my $ip = $self->session->env->getIp; - my $string; - - if ( $anonId or $userId != 1 ) { - $string = 'userId'; - if ($anonId) { - $string = 'anonId'; - $userId = $anonId; - } - my $responseId - = $self->session->db->quickScalar( - "select Survey_responseId from Survey_response where $string = ? and assetId = ? and isComplete = 0", - [ $userId, $self->getId() ] ); - if ( !$responseId ) { - ($lastResponseCompleteCode, $lastResponseEndDate) = $self->session->db->quickArray( - "select isComplete, endDate from Survey_response where $string = ? and assetId = ? and isComplete > 0 order by endDate desc limit 1", - [ $userId, $self->getId() ] - ); - } - - } - elsif ( $userId == 1 ) { - my $responseId = $self->session->db->quickScalar( - 'select Survey_responseId from Survey_response where userId = ? and ipAddress = ? and assetId = ? and isComplete = 0', - [ $userId, $ip, $self->getId() ] + my $responseId = shift; + + my ($lastResponseCompleteCode, $lastResponseEndDate, $rJSON); + + if ( $responseId ) { + ($lastResponseCompleteCode, $lastResponseEndDate, $rJSON) = $self->session->db->quickArray( + 'select isComplete, endDate, responseJSON from Survey_response where responseId = ?', [ $responseId ] ); - if ( !$responseId ) { - ($lastResponseCompleteCode, $lastResponseEndDate) = $self->session->db->quickArray( - 'select isComplete, endDate from Survey_response where userId = ? and ipAddress = ? and assetId = ? and isComplete > 0 order by endDate desc limit 1', + } else { + my $userId = $self->session->user->userId(); + my $anonId + = $self->session->form->process('userid') + || $self->session->http->getCookies->{Survey2AnonId} + || undef; + $anonId && $self->session->http->setCookie( Survey2AnonId => $anonId ); + my $ip = $self->session->env->getIp; + my $string; + + if ( $anonId or $userId != 1 ) { + $string = 'userId'; + if ($anonId) { + $string = 'anonId'; + $userId = $anonId; + } + my $lastResponseId + = $self->session->db->quickScalar( + "select Survey_responseId from Survey_response where $string = ? and assetId = ? and isComplete = 0", + [ $userId, $self->getId() ] ); + if ( !$lastResponseId ) { + ($lastResponseCompleteCode, $lastResponseEndDate, $rJSON) = $self->session->db->quickArray( + "select isComplete, endDate, responseJSON from Survey_response where $string = ? and assetId = ? and isComplete > 0 order by endDate desc limit 1", + [ $userId, $self->getId() ] + ); + } + } + elsif ( $userId == 1 ) { + my $lastResponseId = $self->session->db->quickScalar( + 'select Survey_responseId from Survey_response where userId = ? and ipAddress = ? and assetId = ? and isComplete = 0', [ $userId, $ip, $self->getId() ] ); + if ( !$lastResponseId ) { + ($lastResponseCompleteCode, $lastResponseEndDate, $rJSON) = $self->session->db->quickArray( + 'select isComplete, endDate, responseJSON from Survey_response where userId = ? and ipAddress = ? and assetId = ? and isComplete > 0 order by endDate desc limit 1', + [ $userId, $ip, $self->getId() ] + ); + } } } - return ($lastResponseCompleteCode, $lastResponseEndDate); + + # Process the feedback text + my $feedback; + my $tags = {}; + if ($rJSON) { + $rJSON = from_json($rJSON) || {}; + + # All tags become template vars + $tags = $rJSON->{tags} || {}; + $tags->{complete} = $lastResponseCompleteCode == 1; + $tags->{restart} = $lastResponseCompleteCode == 2; + $tags->{timeout} = $lastResponseCompleteCode == 3; + $tags->{timeoutRestart} = $lastResponseCompleteCode == 4; + $tags->{endDate} = $lastResponseEndDate && WebGUI::DateTime->new($self->session, $lastResponseEndDate)->toUserTimeZone; + $feedback = $self->processTemplate($tags, $self->get('feedbackTemplateId') || 'nWNVoMLrMo059mDRmfOp9g'); + } + return { + completeCode => $lastResponseCompleteCode, + endDate => $tags->{endDate}, + feedback => $feedback, + complete => $tags->{complete}, + restart => $tags->{restart}, + timeout => $tags->{timeout}, + timeoutRestart => $tags->{timeoutRestart}, + }; } #------------------------------------------------------------------- diff --git a/lib/WebGUI/Help/Asset_Survey.pm b/lib/WebGUI/Help/Asset_Survey.pm index b68148f88..307bef875 100644 --- a/lib/WebGUI/Help/Asset_Survey.pm +++ b/lib/WebGUI/Help/Asset_Survey.pm @@ -15,9 +15,8 @@ our $HELP = { }, ], variables => [ - { 'name' => 'lastResponseCompleted help' }, - { 'name' => 'lastResponseTimedOut help' }, { 'name' => 'maxResponsesSubmitted' }, + { 'name' => 'lastResponseFeedback', description => 'lastResponseFeedback help' }, ], related => [ { tag => 'gradebook report template', @@ -35,6 +34,9 @@ our $HELP = { { tag => 'survey answer edit template', namespace => 'Asset_Survey' }, + { tag => 'survey feedback template', + namespace => 'Asset_Survey' + }, ] }, @@ -98,6 +100,9 @@ our $HELP = { { tag => 'survey answer edit template', namespace => 'Asset_Survey' }, + { tag => 'survey feedback template', + namespace => 'Asset_Survey' + }, ] }, @@ -166,7 +171,10 @@ our $HELP = { }, { tag => 'survey answer edit template', namespace => 'Asset_Survey' - }, + }, + { tag => 'survey feedback template', + namespace => 'Asset_Survey' + }, ] }, @@ -211,6 +219,9 @@ our $HELP = { { tag => 'statistical overview report template', namespace => 'Asset_Survey' }, + { tag => 'survey feedback template', + namespace => 'Asset_Survey' + }, ] }, @@ -255,6 +266,9 @@ our $HELP = { { tag => 'statistical overview report template', namespace => 'Asset_Survey' }, + { tag => 'survey feedback template', + namespace => 'Asset_Survey' + }, ] }, @@ -294,6 +308,9 @@ our $HELP = { { tag => 'statistical overview report template', namespace => 'Asset_Survey' }, + { tag => 'survey feedback template', + namespace => 'Asset_Survey' + }, ] }, @@ -366,7 +383,43 @@ our $HELP = { { 'name' => 'responseTemplateId' }, ], }, - + + 'survey feedback template' => { + title => 'survey feedback template variables title', + body => 'survey feedback template body', + isa => [], + fields => [], + variables => [ + { name => 'complete', description => 'response complete help' }, + { name => 'restart', description => 'response complete help' }, + { name => 'timeout', description => 'response timeout help' }, + { name => 'timeoutRestart', description => 'response timeout restart help' }, + { name => 'endDate', description => 'response endDate help' }, + ], + related => [ + { tag => 'survey template', + namespace => 'Asset_Survey' + }, + { tag => 'statistical overview report template', + namespace => 'Asset_Survey' + }, + { tag => 'gradebook report template', + namespace => 'Asset_Survey' + }, + { tag => 'survey section edit template', + namespace => 'Asset_Survey' + }, + { tag => 'survey question edit template', + namespace => 'Asset_Survey' + }, + { tag => 'survey answer edit template', + namespace => 'Asset_Survey' + }, + { tag => 'survey feedback template', + namespace => 'Asset_Survey' + }, + ] + }, }; 1; diff --git a/lib/WebGUI/i18n/English/Asset_Survey.pm b/lib/WebGUI/i18n/English/Asset_Survey.pm index eaee68574..350dead92 100644 --- a/lib/WebGUI/i18n/English/Asset_Survey.pm +++ b/lib/WebGUI/i18n/English/Asset_Survey.pm @@ -490,6 +490,17 @@ our $I18N = { message => q|The template to display the main page of the survey.|, lastUpdated => 0, }, + + 'Feedback Template' => { + message => q|Feedback Template|, + lastUpdated => 0, + }, + + 'Feedback Template help' => { + message => q|The template used to display response feedback.|, + lastUpdated => 0, + }, + 'do after timelimit label' => { message => q|Do After Time Limit:|, lastUpdated => 1224686319, @@ -925,32 +936,54 @@ directly inside the answer_loop for other types of questions.|, lastUpdated => 1078223096 }, - 'lastResponseCompleted' => { - message => q|You completed this Survey|, - lastUpdated => 1242180657, - }, - - 'lastResponseTimedOut' => { - message => q|Your last Survey response timed out|, + 'response complete' => { + message => q|Survey Response completed|, lastUpdated => 1242180657, }, - 'lastResponseCompleted help' => { - message => q|A boolean indicating whether the current user's last response was completed.|, - context => q|Description of a template variable for a template Help page.|, - lastUpdated => 0, + 'response complete help' => { + message => q|A boolean flag indicating whether the Survey Response completed|, + lastUpdated => 1242180657, }, - 'lastResponseEndDate help' => { - message => q|The date that the user's last response was completed.|, - context => q|Description of a template variable for a template Help page.|, - lastUpdated => 0, + 'response restart' => { + message => q|Survey Response restarted|, + lastUpdated => 1242180657, }, - - 'lastResponseTimedOut help' => { - message => q|A boolean indicating whether the current user's last response timed out.|, - context => q|Description of a template variable for a template Help page.|, - lastUpdated => 0, + + 'response restart help' => { + message => q|A boolean flag indicating whether the Survey Response restarted|, + lastUpdated => 1242180657, + }, + + 'response timeout' => { + message => q|Survey Response timed out|, + lastUpdated => 1242180657, + }, + + 'response timeout help' => { + message => q|A boolean flag indicating whether the Survey Response timed out|, + lastUpdated => 1242180657, + }, + + 'response timeout restart' => { + message => q|Survey Response restarted due to a timeout|, + lastUpdated => 1242180657, + }, + + 'response timeout restart help' => { + message => q|A boolean flag indicating whether the Survey Response restarted as a result of a timeout|, + lastUpdated => 1242180657, + }, + + 'response endDate help' => { + message => q|A localised date/time string indicating when the response ended|, + lastUpdated => 1242180657, + }, + + 'survey feedback template body' => { + message => q|All data tagged in survey expressions is also made available as template variables|, + lastUpdated => 1242180657, }, 'maxResponsesSubmitted' => { @@ -970,6 +1003,12 @@ directly inside the answer_loop for other types of questions.|, context => q|Description of a template variable for a template Help page.|, lastUpdated => 0, }, + + 'lastResponseFeedback help' => { + message => q|The templated response feedback text|, + context => q|Description of a template variable for a template Help page.|, + lastUpdated => 0, + }, 'user_canEditSurvey' => { message => q|A boolean indicating whether the current user can edit the survey.|, diff --git a/t/Asset/Wobject/Survey/ExpressionEngine.t b/t/Asset/Wobject/Survey/ExpressionEngine.t index b2fd409e3..2b5c603ae 100644 --- a/t/Asset/Wobject/Survey/ExpressionEngine.t +++ b/t/Asset/Wobject/Survey/ExpressionEngine.t @@ -22,7 +22,7 @@ my $session = WebGUI::Test->session; #---------------------------------------------------------------------------- # Tests -my $tests = 55; +my $tests = 56; plan tests => $tests + 1; #---------------------------------------------------------------------------- @@ -79,6 +79,7 @@ SKIP: { q{jump { answered(n) && !answered(X) } target}, # answered() works q{jump { value(multi) eq 'answer1, answer2' } target}, # multi-answer question stringifies in scalar context q{jump { (value(multi))[1] eq 'answer2' } target}, # multi-answer question returns list in list context + q{ sub mySub { return $_[0] + 2 } jump { mySub(1) == 3 } target } # expressions can define and use subs ); my @should_not_jump = (