diff --git a/Survey.sql b/Survey.sql new file mode 100644 index 000000000..b1c3b5fda --- /dev/null +++ b/Survey.sql @@ -0,0 +1,106 @@ +-- MySQL dump 10.11 +-- +-- Host: localhost Database: www_survey_com +-- ------------------------------------------------------ +-- Server version 5.0.67 + +/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; +/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; +/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; +/*!40101 SET NAMES utf8 */; +/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; +/*!40103 SET TIME_ZONE='+00:00' */; +/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; +/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; +/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; +/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; + +-- +-- Table structure for table `Survey` +-- + +DROP TABLE IF EXISTS `Survey`; +SET @saved_cs_client = @@character_set_client; +SET character_set_client = utf8; +CREATE TABLE `Survey` ( + `groupToTakeSurvey` varchar(22) character set utf8 collate utf8_bin NOT NULL default '2', + `groupToViewReports` varchar(22) character set utf8 collate utf8_bin NOT NULL default '3', + `responseTemplateId` varchar(22) character set utf8 collate utf8_bin NOT NULL default '', + `overviewTemplateId` varchar(22) character set utf8 collate utf8_bin NOT NULL default '', + `maxResponsesPerUser` int(11) NOT NULL default '1', + `gradebookTemplateId` varchar(22) character set utf8 collate utf8_bin NOT NULL default '', + `assetId` varchar(22) character set utf8 collate utf8_bin NOT NULL default '', + `templateId` varchar(22) character set utf8 collate utf8_bin NOT NULL default '', + `revisionDate` bigint(20) NOT NULL default '0', + `surveyEditTemplateId` varchar(22) NOT NULL, + `answerEditTemplateId` varchar(22) NOT NULL, + `questionEditTemplateId` varchar(22) NOT NULL, + `sectionEditTemplateId` varchar(22) NOT NULL, + `surveyTakeTemplateId` varchar(22) NOT NULL, + `surveyQuestionsId` varchar(22) NOT NULL, + `exitURL` varchar(512) default NULL, + `surveyJSON` longblob, + PRIMARY KEY (`assetId`,`revisionDate`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; +SET character_set_client = @saved_cs_client; + +-- +-- Table structure for table `Survey_response` +-- + +DROP TABLE IF EXISTS `Survey_response`; +SET @saved_cs_client = @@character_set_client; +SET character_set_client = utf8; +CREATE TABLE `Survey_response` ( + `assetId` varchar(22) character set utf8 collate utf8_bin NOT NULL, + `Survey_responseId` varchar(22) character set utf8 collate utf8_bin NOT NULL default '', + `userId` varchar(22) default NULL, + `username` varchar(255) default NULL, + `ipAddress` varchar(15) default NULL, + `startDate` bigint(20) NOT NULL default '0', + `endDate` bigint(20) NOT NULL default '0', + `isComplete` int(11) NOT NULL default '0', + `anonId` varchar(255) default NULL, + `responseJSON` longblob, + PRIMARY KEY (`Survey_responseId`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; +SET character_set_client = @saved_cs_client; + +-- +-- Table structure for table `Survey_tempReport` +-- + +DROP TABLE IF EXISTS `Survey_tempReport`; +SET @saved_cs_client = @@character_set_client; +SET character_set_client = utf8; +CREATE TABLE `Survey_tempReport` ( + `assetId` varchar(22) NOT NULL, + `Survey_responseId` varchar(22) NOT NULL, + `order` smallint(5) unsigned NOT NULL, + `sectionNumber` smallint(5) unsigned NOT NULL, + `sectionName` varchar(512) default NULL, + `questionNumber` smallint(5) unsigned NOT NULL, + `questionName` varchar(512) default NULL, + `questionComment` mediumtext, + `answerNumber` smallint(5) unsigned default NULL, + `answerValue` mediumtext, + `answerComment` mediumtext, + `entryDate` bigint(20) unsigned NOT NULL COMMENT 'UTC Unix Time', + `isCorrect` tinyint(3) unsigned default NULL, + `value` int(11) default NULL, + `fileStoreageId` varchar(22) default NULL COMMENT 'Not implemented yet', + PRIMARY KEY (`assetId`,`Survey_responseId`,`order`), + KEY `assetId` (`assetId`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; +SET character_set_client = @saved_cs_client; +/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; + +/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; +/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; +/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; +/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; +/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; +/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; +/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; + +-- Dump completed on 2008-10-24 21:38:00 diff --git a/lib/WebGUI/Asset/Wobject/Survey.pm b/lib/WebGUI/Asset/Wobject/Survey.pm index 555e764e0..fa7b558f3 100644 --- a/lib/WebGUI/Asset/Wobject/Survey.pm +++ b/lib/WebGUI/Asset/Wobject/Survey.pm @@ -38,6 +38,11 @@ sub definition { hoverHelp=>"A Survey System", label=>"Template ID" }, + groupToEditSurvey => { + fieldType => 'group', + defaultValue => 4, + label => "Group to edit survey", + }, groupToTakeSurvey => { fieldType => 'group', defaultValue => 2, @@ -552,6 +557,7 @@ sub prepareView { sub purge { my $self = shift; $self->session->db->write("delete from Survey_response where assetId = ?",[$self->getId()]); + $self->session->db->write("delete from Survey_tempReport where assetId = ?",[$self->getId()]); $self->session->db->write("delete from Survey where assetId = ?",[$self->getId()]); return $self->SUPER::purge; } @@ -589,12 +595,13 @@ returns the output. sub view { my $self = shift; my %var; + $var{'edit_survey_url'} = $self->getUrl('func=editSurvey'); $var{'take_survey_url'} = $self->getUrl('func=takeSurvey'); + $var{'view_reports_url'} = $self->getUrl('func=viewReports'); $var{'user_canTakeSurvey'} = $self->session->user->isInGroup($self->get("groupToTakeSurvey")); - - $var{'user_canTakeSurvey'} = 1; - + $var{'user_canViewReports'} = $self->session->user->isInGroup($self->get("groupToViewReports")); + $var{'user_canEditSurvey'} = $self->session->user->isInGroup($self->get("groupToEditSurvey")); my $out = $self->processTemplate(\%var,undef,$self->{_viewTemplate}); return $out; @@ -842,14 +849,18 @@ sub loadBothJSON{ #------------------------------------------------------------------- sub loadResponseJSON{ my $self = shift; +$self->log("1"); my $jsonHash = shift; my $rId = shift; + $rId = defined $rId ? $rId : $self->{responseId}; + if(defined $self->response and ! defined $rId){return;} - if(defined $self->response){return;} +$self->log("loading $rId"); - $jsonHash = $self->session->db->quickScalar("select surveyJSON from Survey where assetId = ?",[$self->getId]) if(! defined $jsonHash); - - $self->{response} = WebGUI::Asset::Wobject::Survey::ResponseJSON->new($jsonHash,$self->session->errorHandler, $rId, $self->survey); + $jsonHash = $self->session->db->quickScalar("select responseJSON from Survey_response where assetId = ? and Survey_responseId = ?", + [$self->getId,$rId]) if(! defined $jsonHash); +$self->log("jsonhash was ".(length $jsonHash)); + $self->{response} = WebGUI::Asset::Wobject::Survey::ResponseJSON->new($jsonHash,$self->session->errorHandler, $self->survey); } #------------------------------------------------------------------- @@ -984,7 +995,67 @@ $self->session->errorHandler->error("Can take was NOT already defined"); } +#------------------------------------------------------------------- +sub www_viewReports { + my $self = shift; + $self->loadTempReportTable(); + return "" unless ($self->session->user->isInGroup($self->get("groupToViewReports"))); + 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); +} + +#------------------------------------------------------------------- +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); + unless (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; +} +sub loadTempReportTable{ + my $self = shift; + + $self->loadSurveyJSON(); + my $refs = $self->session->db->buildArrayRefOfHashRefs("select * from Survey_response where assetId = ?",[$self->getId()]); + $self->session->db->write("delete from Survey_tempReport where assetId = ?",[$self->getId()]); + for my $ref(@$refs){ + $self->loadResponseJSON(undef,$ref->{Survey_responseId}); + my $count = 1; + for my $q(@{$self->response->returnResponseForReporting()}){ + 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]); + 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->{comment},$a->{time},$a->{isCorrect},$a->{value},undef]); + } + } + } + return 1; +} +sub log{ + my $self = shift; + $self->session->errorHandler->error(shift); +} 1; diff --git a/lib/WebGUI/Asset/Wobject/Survey/ResponseJSON.pm b/lib/WebGUI/Asset/Wobject/Survey/ResponseJSON.pm index 606875c60..d385e5ae7 100644 --- a/lib/WebGUI/Asset/Wobject/Survey/ResponseJSON.pm +++ b/lib/WebGUI/Asset/Wobject/Survey/ResponseJSON.pm @@ -8,12 +8,10 @@ sub new{ my $class = shift; my $json = shift; my $log = shift; - my $rId = shift; my $survey = shift; my $self = {}; $self->{survey} = $survey; $self->{log} = $log; - $self->{responseId} = $rId; my $temp = decode_json($json) if defined $json; $self->{surveyOrder} = defined $temp->{surveyOrder} ? $temp->{surveyOrder} : [];#an array of question addresses, with the third member being an array of answers $self->{responses} = defined $temp->{responses} ? $temp->{responses} : {}; @@ -34,10 +32,9 @@ Forks are passed in to show where to branch the new order. sub createSurveyOrder{ my $self = shift; -# my $fork = shift || []; my $order; my $qstarting = 0; -eval{ + for(my $s = 0; $s <= $#{$self->survey->sections()}; $s++){ #create question order for section my @qorder; @@ -61,17 +58,8 @@ eval{ @aorder = (($qstarting .. $#{$self->survey->question([$s,$_])->{answers}})); } push(@$order,[$s,$_,\@aorder]); -# if(@$fork == 2){ -# if($$fork[0][0] == $s and $$fork[0][1] == $_){ -# $s = $$fork[1][0]-1; -# $qstarting = $$fork[1][1]; -# last; -# } -# } } } -}; -$self->log($@) if($@); $self->{surveyOrder} = $order; } sub shuffle { @@ -90,6 +78,7 @@ sub freeze{ delete $temp{survey}; return encode_json(\%temp); } + #the index of the last surveyOrder entry shown sub lastResponse{ my $self = shift; @@ -162,6 +151,7 @@ $self->log("There are questions to be submitted in this section"); $terminal = 1; $terminalUrl = $question->{terminalUrl}; } + $self->responses->{$question->{id}}->{comment} = $responses->{$question->{id}."comment"}; for my $answer(@{$question->{answers}}){ if(defined($responses->{$answer->{id}}) and $responses->{$answer->{id}} =~ /\S/){ @@ -169,11 +159,13 @@ $self->log("There are questions to be submitted in this section"); $aAnswered = 1; if($mcTypes{$question->{questionType}}){ $self->responses->{$answer->{id}}->{value} = $answer->{recordedAnswer}; +$self->log("Recorded Answer ".$answer->{recordedAnswer}); } else{ +$self->log("Returned Answer ".$responses->{$answer->{id}}); $self->responses->{$answer->{id}}->{value} = $responses->{$answer->{id}}; } - + $self->responses->{$answer->{id}}->{'time'} = time(); $self->responses->{$answer->{id}}->{comment} = $responses->{$answer->{id}."comment"}; if($answer->{terminal}){ @@ -250,7 +242,6 @@ $self->log("next sectionid is $nextSectionId"); my $section = $self->nextSection(); $self->log("Section text is ".$section->{text}); $section->{'text'} =~ s/\[\[([^\%]*?)\]\]/$self->getPreviousAnswer($1)/eg; -# $section->{'text'} =~ s/(\[\[\%.*?\]\])/$self->getRandomText($responseId,$1)/eg; $self->log("qperpage $qPerPage"); @@ -290,6 +281,41 @@ $self->log("ENDING THE SURVEY\n\n\n") if($self->lastResponse > $#{$self->surveyO return 0; } +sub returnResponseForReporting{ + my $self = shift; + my @responses = (); + for my $entry(@{$self->surveyOrder}){ + if(@$entry == 1){ + next; + } + my @answers; + for (@{$$entry[2]}){ + if(defined $self->responses->{"$$entry[0]-$$entry[1]-$_"}){ + $self->responses->{"$$entry[0]-$$entry[1]-$_"}->{id} = $_; + if($self->survey->answer([$$entry[0],$$entry[1],$_])->{isCorrect}){ + my $value; + if($self->survey->answer([$$entry[0],$$entry[1],$_])->{value} =~ /\w/){ + $value = $self->survey->answer([$$entry[0],$$entry[1],$_])->{value}; + }else{ + $value = $self->survey->question([$$entry[0],$$entry[1]])->{value}; + } + $self->responses->{"$$entry[0]-$$entry[1]-$_"}->{value} = $value; + $self->responses->{"$$entry[0]-$$entry[1]-$_"}->{isCorrect} = 1; + }else{ + $self->responses->{"$$entry[0]-$$entry[1]-$_"}->{isCorrect} = 0; + } + push(@answers,($self->responses->{"$$entry[0]-$$entry[1]-$_"})); + } + } + push(@responses,({'section',$$entry[0],'question',$$entry[1], + 'sectionName',$self->survey->section([$$entry[0]])->{variable}, + 'questionName',$self->survey->question([$$entry[0],$$entry[1]])->{variable}, + 'questionComment',$self->responses->{"$$entry[0]-$$entry[1]"}->{comment}, + 'answers',\@answers})); + } +$self->log(Dumper @responses); + return \@responses; +} #the actual responses to the survey. A response is for a question and is accessed by the exact same address as a survey member. #Questions only contain the comment and an array of answer Responses. diff --git a/lib/WebGUI/Asset/Wobject/Survey/SurveyJSON.pm b/lib/WebGUI/Asset/Wobject/Survey/SurveyJSON.pm index 6c4483f59..506ceb45a 100644 --- a/lib/WebGUI/Asset/Wobject/Survey/SurveyJSON.pm +++ b/lib/WebGUI/Asset/Wobject/Survey/SurveyJSON.pm @@ -150,12 +150,14 @@ sub update{ my $object; my $newQuestion = 0; if(@$address == 1){ +$self->log("A section"); $object = $self->section($address); if(! defined $object){ $object = $self->newSection(); push(@{$self->sections},$object); } }elsif(@$address == 2){ +$self->log("A question"); $object = $self->question($address); if(! defined $object){ my $newQuestion = 1; @@ -163,6 +165,7 @@ sub update{ push(@{$self->questions($address)},$object); } }elsif(@$address == 3){ +$self->log("A answer"); $object = $self->answer($address); if(! defined $object){ $object = $self->newAnswer(); @@ -175,6 +178,7 @@ sub update{ } } for my $key(keys %$object){ +$self->log("$key $$object{$key}"); $object->{$key} = $ref->{$key} if(defined $$ref{$key}); } } @@ -263,8 +267,8 @@ sub newQuestion{ 'maxAnswers',1, 'value',1, 'textInButton',0, - 'terminal',0, - 'terminalUrl','', +# 'terminal',0, +# 'terminalUrl','', 'type','question' ); $members{answers} = []; diff --git a/lib/WebGUI/i18n/English/Asset_Survey.pm b/lib/WebGUI/i18n/English/Asset_Survey.pm index 312d8e306..7b7e795a0 100644 --- a/lib/WebGUI/i18n/English/Asset_Survey.pm +++ b/lib/WebGUI/i18n/English/Asset_Survey.pm @@ -15,8 +15,8 @@ our $I18N = { message => q|Take Survey|, lastUpdated => 1224686319 }, - 'view results' => { - message => q|View Reports|, + 'view reports' => { + message => q|View Results|, lastUpdated => 1224686319 }, 'continue button' => { @@ -127,7 +127,7 @@ our $I18N = { message => q|Question type:|, lastUpdated => 1224686319 }, - 'randomzied words' => { + 'randomized words' => { message => q|Randomized words:|, lastUpdated => 1224686319 }, @@ -155,7 +155,7 @@ our $I18N = { message => q|Maximum number of answers:|, lastUpdated => 1224686319 }, - 'qrequired' => { + 'required' => { message => q|Required|, lastUpdated => 1224686319 }, diff --git a/survey_templates.wgpkg b/survey_templates.wgpkg index dd0ee2015..ed0c8eb99 100644 Binary files a/survey_templates.wgpkg and b/survey_templates.wgpkg differ