Fixes to Survey reporting and performance improvements
Fix: Survey export simple/transposed results to csv or tab Fix: loadTempReportTable handling of revisionDates (and documentation) Fix: returnResponseForReporting handling of mc questions NYTProf performance improvements Added some very basic Survey reporting tests
This commit is contained in:
parent
ea51ba559e
commit
280e902c09
8 changed files with 422 additions and 273 deletions
|
|
@ -2390,9 +2390,64 @@ sub www_viewStatisticalOverview {
|
|||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 export ( $options )
|
||||
|
||||
Triggers the user's browser to download the given content as a file
|
||||
|
||||
Accepts the following options:
|
||||
|
||||
=over 4
|
||||
|
||||
=item content (optional)
|
||||
|
||||
The content to return. If not specified, the sql param is used.
|
||||
|
||||
=item sql (optional)
|
||||
|
||||
An sql string to use to look up content.
|
||||
|
||||
=item sqlParams (optional)
|
||||
|
||||
An array of sql positional parameters.
|
||||
|
||||
=item format
|
||||
|
||||
Either C<csv> or C<tab>
|
||||
|
||||
=item name
|
||||
|
||||
The filename to use for the downloadable content
|
||||
|
||||
=back
|
||||
|
||||
=cut
|
||||
|
||||
sub export {
|
||||
my $self = shift;
|
||||
my %opts = validate(@_, { content => 0, sql => 0, sqlParams => {default => []}, format => { default => 'csv' }, name => 1 });
|
||||
|
||||
my $format = lc $opts{format};
|
||||
$format = 'csv' unless $format eq 'csv' || $format eq 'tab';
|
||||
|
||||
# Content is either passed in, or we lookup via SQL query
|
||||
my $content = $opts{content};
|
||||
if (!$content) {
|
||||
|
||||
# Use the appropriate SQL 'quick' method
|
||||
my $method = $format eq 'csv' ? 'quickCSV' : 'quickTab';
|
||||
$content = $self->session->db->$method( $opts{sql}, $opts{sqlParams} );
|
||||
}
|
||||
|
||||
my $filename = $self->session->url->escape( $self->get("title") . "_$opts{name}.$format" );
|
||||
$self->session->http->setFilename($filename,"text/$format");
|
||||
return $content;
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 www_exportSimpleResults ()
|
||||
|
||||
Exports transposed results in a tab deliniated file.
|
||||
Exports transposed results as CSV (or tabbed depending on the C<format> form param)
|
||||
|
||||
=cut
|
||||
|
||||
|
|
@ -2402,21 +2457,21 @@ sub www_exportSimpleResults {
|
|||
return $self->session->privilege->insufficient()
|
||||
if !$self->session->user->isInGroup( $self->get('groupToViewReports'));
|
||||
|
||||
$self->loadTempReportTable();
|
||||
|
||||
my $filename = $self->session->url->escape( $self->get('title') . '_results.tab' );
|
||||
my $content
|
||||
= $self->session->db->quickTab(
|
||||
'select * from Survey_tempReport t where t.assetId=? order by t.Survey_responseId, t.order',
|
||||
[ $self->getId() ] );
|
||||
return $self->export( $filename, $content );
|
||||
$self->loadTempReportTable( ignoreRevisionDate => 1 );
|
||||
|
||||
return $self->export(
|
||||
sql => 'select * from Survey_tempReport t where t.assetId=? order by t.Survey_responseId, t.order',
|
||||
sqlParams => [ $self->getId() ],
|
||||
format => scalar $self->session->form->process('format'),
|
||||
name => 'simple',
|
||||
);
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 www_exportTransposedResults ()
|
||||
|
||||
Returns transposed results as a tabbed file.
|
||||
Returns transposed results as CSV (or tabbed depending on the C<format> form param)
|
||||
|
||||
=cut
|
||||
|
||||
|
|
@ -2425,21 +2480,22 @@ sub www_exportTransposedResults {
|
|||
return $self->session->privilege->insufficient()
|
||||
if !$self->session->user->isInGroup( $self->get('groupToViewReports') );
|
||||
|
||||
$self->loadTempReportTable();
|
||||
|
||||
my $filename = $self->session->url->escape( $self->get('title') . '_transposedResults.tab' );
|
||||
my $content
|
||||
= $self->session->db->quickTab(
|
||||
'select r.userId, r.username, r.ipAddress, r.startDate, r.endDate, r.isComplete, t.*'
|
||||
. ' from Survey_tempReport t'
|
||||
. ' left join Survey_response r using(Survey_responseId)'
|
||||
. ' where t.assetId=?'
|
||||
. ' order by r.userId, r.Survey_responseId, t.order',
|
||||
[ $self->getId() ] );
|
||||
return $self->export( $filename, $content );
|
||||
$self->loadTempReportTable( ignoreRevisionDate => );
|
||||
|
||||
return $self->export(
|
||||
sql => <<END_SQL,
|
||||
select r.userId, r.username, r.ipAddress, r.startDate, r.endDate, r.isComplete, t.*
|
||||
from Survey_tempReport t
|
||||
left join Survey_response r using(Survey_responseId)
|
||||
where t.assetId = ?
|
||||
order by r.userId, r.Survey_responseId, t.order
|
||||
END_SQL
|
||||
sqlParams => [ $self->getId() ],
|
||||
format => scalar $self->session->form->process('format'),
|
||||
name => 'transposed',
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 www_exportStructure
|
||||
|
|
@ -2522,78 +2578,86 @@ END_HTML
|
|||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 export($filename,$content)
|
||||
|
||||
Exports the data in $content to $filename, then forwards the user to $filename.
|
||||
|
||||
=head3 $filename
|
||||
|
||||
The name of the file you want exported.
|
||||
|
||||
=head3 $content
|
||||
|
||||
The data you want exported (CSV, tab, whatever).
|
||||
|
||||
=cut
|
||||
|
||||
sub export {
|
||||
my $self = shift;
|
||||
my $filename = shift;
|
||||
$filename =~ s/[^\w\d\.]/_/g;
|
||||
my $content = shift;
|
||||
|
||||
# Create a temporary directory to store files if it doesn't already exist
|
||||
my $store = WebGUI::Storage->createTemp( $self->session );
|
||||
my $tmpDir = $store->getPath();
|
||||
my $filepath = $store->getPath($filename);
|
||||
if ( !open TEMP, ">$filepath" ) {
|
||||
return 'Error - Could not open temporary file for writing. Please use the back button and try again';
|
||||
}
|
||||
print TEMP $content;
|
||||
close TEMP;
|
||||
my $fileurl = $store->getUrl($filename);
|
||||
|
||||
$self->session->http->setRedirect($fileurl);
|
||||
|
||||
return undef;
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 loadTempReportTable
|
||||
|
||||
Loads the responses from the survey into the Survey_tempReport table, so that other or custom reports can be ran against this data.
|
||||
|
||||
Accepts the following options:
|
||||
|
||||
=over 4
|
||||
|
||||
=item ignoreRevisionDate
|
||||
|
||||
Normally it only makes sense to compare responses for the current revisionDate (because the Survey structure can change
|
||||
between revisions). This flag tells us to ignore response revisionDate.
|
||||
|
||||
=back
|
||||
|
||||
=cut
|
||||
|
||||
sub loadTempReportTable {
|
||||
my $self = shift;
|
||||
my $self = shift;
|
||||
my %opts = validate(@_, { ignoreRevisionDate => 0 });
|
||||
|
||||
my $refs = $self->session->db->buildArrayRefOfHashRefs( 'select * from Survey_response where assetId = ?',
|
||||
[ $self->getId() ] );
|
||||
# Remove old temp report data
|
||||
$self->session->db->write( 'delete from Survey_tempReport where assetId = ?', [ $self->getId() ] );
|
||||
for my $ref (@{$refs}) {
|
||||
$self->responseJSON( undef, $ref->{Survey_responseId} );
|
||||
my $count = 1;
|
||||
for my $q ( @{ $self->responseJSON->returnResponseForReporting() } ) {
|
||||
|
||||
# Build the sql that will select all responses
|
||||
my $sql = 'select * from Survey_response where assetId = ?';
|
||||
|
||||
# Mostly it only makes sense to export responses for a single revisionDate (because Survey
|
||||
# structure can change between revisions)
|
||||
$sql .= ' and revisionDate = ' . $self->session->db->quote($self->get('revisionDate')) unless $opts{ignoreRevisionDate};
|
||||
|
||||
# Populate the temp report table with new data
|
||||
my $refs = $self->session->db->buildArrayRefOfHashRefs( $sql, [ $self->getId() ] );
|
||||
for my $ref ( @{$refs} ) {
|
||||
|
||||
# Inject the responseJSON
|
||||
$self->responseJSON( $ref->{responseJSON}, $ref->{Survey_responseId} );
|
||||
|
||||
my $order = 1;
|
||||
for my $q ( @{ $self->responseJSON->responseReport } ) {
|
||||
if ( @{ $q->{answers} } == 0 and $q->{comment} =~ /\w/ ) {
|
||||
$self->session->db->write(
|
||||
'insert into Survey_tempReport VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)', [
|
||||
$self->getId(), $ref->{Survey_responseId}, $count++, $q->{section},
|
||||
$q->{sectionName}, $q->{question}, $q->{questionName}, $q->{questionComment},
|
||||
undef, undef, undef, undef,
|
||||
undef, undef, undef
|
||||
'insert into Survey_tempReport VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)',
|
||||
[ $self->getId(), # assetId
|
||||
$ref->{Survey_responseId}, # Survey_responseId
|
||||
$order++, # order
|
||||
$q->{section},, # sectionNumber
|
||||
$q->{sectionName}, # sectionName
|
||||
$q->{question}, # questionNumber
|
||||
$q->{questionName}, # questionName
|
||||
$q->{questionComment}, # questionComment
|
||||
undef,
|
||||
undef,
|
||||
undef,
|
||||
undef,
|
||||
undef,
|
||||
undef,
|
||||
undef
|
||||
]
|
||||
);
|
||||
next;
|
||||
}
|
||||
for my $a ( @{ $q->{answers} } ) {
|
||||
$self->session->db->write(
|
||||
'insert into Survey_tempReport VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)', [
|
||||
$self->getId(), $ref->{Survey_responseId}, $count++, $q->{section},
|
||||
$q->{sectionName}, $q->{question}, $q->{questionName}, $q->{questionComment},
|
||||
$a->{id}, $a->{value}, $a->{verbatim}, $a->{time},
|
||||
$a->{isCorrect}, $a->{value}, undef
|
||||
'insert into Survey_tempReport VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)',
|
||||
[ $self->getId(), # assetId
|
||||
$ref->{Survey_responseId}, # Survey_responseId
|
||||
$order++, # order
|
||||
$q->{section}, # sectionNumber
|
||||
$q->{sectionName}, # sectionName
|
||||
$q->{question}, # questionNumber
|
||||
$q->{questionName}, # questionName
|
||||
$q->{questionComment}, # questionComment
|
||||
$a->{id}, # answerNumber
|
||||
$a->{value}, # answerValue
|
||||
$a->{verbatim}, # answerComment
|
||||
$a->{time}, # entryDate
|
||||
$a->{isCorrect}, # isCorrect
|
||||
$a->{score}, # value (e.g. answer score)
|
||||
undef # fileStoreageId
|
||||
]
|
||||
);
|
||||
}
|
||||
|
|
@ -2602,34 +2666,6 @@ sub loadTempReportTable {
|
|||
return 1;
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 www_editDefaultQuestions
|
||||
|
||||
Allows a user to edit the *site wide* default multiple choice questions displayed when adding questions to a survey.
|
||||
|
||||
=cut
|
||||
|
||||
sub www_editDefaultQuestions{
|
||||
my $self = shift;
|
||||
my $warning = shift;
|
||||
my $session = $self->session;
|
||||
my ($output);
|
||||
my $bundleId = $session->form->process("bundleId");
|
||||
|
||||
if($bundleId eq 'new'){
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
if($warning){$output .= "$warning";}
|
||||
# $output .= $tabForm->print;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 www_downloadDefaultQuestionTypes
|
||||
|
|
@ -2642,39 +2678,12 @@ sub www_downloadDefaultQuestionTypes{
|
|||
my $self = shift;
|
||||
return $self->session->privilege->insufficient()
|
||||
if !$self->session->user->isInGroup( $self->get('groupToViewReports') );
|
||||
|
||||
my $content = to_json($self->surveyJSON->{multipleChoiceTypes});
|
||||
return $self->export( "WebGUI-Survey-DefaultQuestionTypes.json", $content );
|
||||
$self->session->http->setFilename('WebGUI-Survey-DefaultQuestionTypes.json', "application/json");
|
||||
return $content;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 www_deleteTest ( )
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue