diff --git a/docs/changelog/6.x.x.txt b/docs/changelog/6.x.x.txt index c6b3b0abf..55e4aa125 100644 --- a/docs/changelog/6.x.x.txt +++ b/docs/changelog/6.x.x.txt @@ -36,6 +36,15 @@ - Added some processing functions to programatically add meta tags, javascript, and link tags to the head block of a page from anywhere within webgui. + - Templatized the Survey. + - Survey now allows for a configurable number of responses from a single user. + - Survey now allows for a configurable number of questions per page. + - Survey now shows progress indicator. + - Survey can now draw from a pool of questions, but does not have to use all + of them. + - Removed depricated functionality from Paginator (see docs/migration.txt). + - Added template variable mechanism to paginator. + - Added a limit option to the page list in the paginator. - Fixed a bug in AdminBar's clipboard code where a standard hash was used instead of a CPHash for database access. (Thanks to Steve Simms.) diff --git a/docs/migration.txt b/docs/migration.txt index 34d82e8dd..46de2dd84 100644 --- a/docs/migration.txt +++ b/docs/migration.txt @@ -81,8 +81,19 @@ WebGUI::Form::dateTime() and WebGUI::HTMLForm->dateTime() no longer have because there is only one field to represent both the date and the time, unlike before. + 5.2 Database Links The database links API was changed in 6.0. The getHash function was removed and replaced with a getList function that returns a hash reference. + +5.3 Paginator + +In 6.0 almost all of the paginator methods were modified in an incompatible +way, including the constructor. We removed depricated parameters from the methods, +which will cause pagination not to function in items that have not been updated. + + + + diff --git a/docs/upgrades/upgrade_5.9.9-6.0.0.pl b/docs/upgrades/upgrade_5.9.9-6.0.0.pl index 6cbdc9547..2757fdbf4 100644 --- a/docs/upgrades/upgrade_5.9.9-6.0.0.pl +++ b/docs/upgrades/upgrade_5.9.9-6.0.0.pl @@ -412,6 +412,7 @@ while (my $data = $a->hashRef) { } $a->finish; WebGUI::SQL->write("alter table SQLReport drop column template"); +WebGUI::SQL->write("alter table SQLReport drop column convertCarriageReturns"); @@ -466,6 +467,54 @@ WebGUI::SQL->write("update page set wobjectPrivileges=$session{setting}{wobjectP WebGUI::SQL->write("delete from settings where name='wobjectPrivileges'"); +#-------------------------------------------- +print "\tMigrating surveys.\n" unless ($quiet); +WebGUI::SQL->write("alter table Survey_response rename Survey_questionResponse"); +WebGUI::SQL->write("update Survey_questionResponse set userId='1' where userId='c4ca4238'"); +WebGUI::SQL->write("alter table Survey_questionResponse drop primary key"); +WebGUI::SQL->write("alter table Survey_questionResponse add primary key (Survey_questionId, Survey_answerId, Survey_responseId)"); +WebGUI::SQL->write("create table Survey_response (Survey_id int, Survey_responseId int not null primary key, userId varchar(11), + username varchar(255), ipAddress varchar(15), startDate int, endDate int, isComplete int not null default 0)"); +my $a = WebGUI::SQL->read("select Survey_id from Survey"); +while (my ($surveyId) = $a->array) { + my $b = WebGUI::SQL->read("select distinct userId from Survey_questionResponse where Survey_id=$surveyId"); + while (my ($userId) = $b->array) { + my ($username,$ipAddress) = WebGUI::SQL->quickArray("select username,ipAddress from Survey_questionResponse where Survey_id=$surveyId and + userId=".quote($userId)); + WebGUI::SQL->write("insert into (Survey_id, Survey_responseId, userId, username, isComplete, ipAddress) values ($surveyId, + ".getNextId("Survey_responseId")." ,".quote($userId).", ".quote($username).", 1, ".quote($ipAddress).")"); + } + $b->finish; + $b = WebGUI::SQL->read("select distinct ipAddress from Survey_questionResponse where Survey_id=$surveyId and userId='1'"); + while (my ($ipAddress) = $b->array) { + WebGUI::SQL->write("insert into (Survey_id, Survey_responseId, userId, username, isComplete, ipAddress) values ( + $surveyId, ".getNextId("Survey_responseId")." ,'1', 'Visitor', 1, ".quote($ipAddress).")"); + } + $b->finish; +} +$a->finish; +$a = WebGUI::SQL->read("select Survey_id, Survey_responseId, userId, ipAddress from Survey_response"); +while (my $data = $a->hashRef) { + my ($end) = WebGUI::SQL->quickArray("select max(dateOfResponse) from Survey_questionResponse where Survey_id=".$data->{Survey_id}." + and ((userId=".quote($data->{userId})." and userId<>1) or (userId=1 and ipAddress=".quote($data->{ipAddress})."))"); + my ($start) = WebGUI::SQL->quickArray("select min(dateOfResponse) from Survey_questionResponse where Survey_id=".$data->{Survey_id}." + and ((userId=".quote($data->{userId})." and userId<>1) or (userId=1 and ipAddress=".quote($data->{ipAddress})."))"); + WebGUI::SQL->write("update Survey_response set startDate=$start, endDate=$end where Survey_responseId=".$data->{Survey_responseId}); + WebGUI::SQL->quickArray("update Survey_questionResponse set Survey_responseId=".$data->{Survey_responseId}." where Survey_id=".$data->{Survey_id}." + and ((userId=".quote($data->{userId})." and userId<>1) or (userId=1 and ipAddress=".quote($data->{ipAddress})."))"); +} +$a->finish; +WebGUI::SQL->write("alter table Survey_questionResponse drop column userId"); +WebGUI::SQL->write("alter table Survey_questionResponse drop column username"); +WebGUI::SQL->write("alter table Survey_questionResponse drop column ipAddress"); +WebGUI::SQL->write("alter table Survey add column questionsPerPage int not null default 1"); +WebGUI::SQL->write("alter table Survey add column responseTemplateId int not null default 1"); +WebGUI::SQL->write("alter table Survey add column reportcardTemplateId int not null default 1"); +WebGUI::SQL->write("alter table Survey add column overviewTemplateId int not null default 1"); +WebGUI::SQL->write("alter table Survey add column maxResponsesPerUser int not null default 1"); +WebGUI::SQL->write("alter table Survey add column questionsPerResponse int not null default 9999999"); + + WebGUI::Session::close(); diff --git a/docs/upgrades/upgrade_5.9.9-6.0.0.sql b/docs/upgrades/upgrade_5.9.9-6.0.0.sql index cead1d8a6..593dbdf53 100644 --- a/docs/upgrades/upgrade_5.9.9-6.0.0.sql +++ b/docs/upgrades/upgrade_5.9.9-6.0.0.sql @@ -309,7 +309,23 @@ UPDATE userProfileData set fieldData = '2' where fieldName = 'richEditor' and fi UPDATE userProfileData set fieldData = '3' where fieldName = 'richEditor' and fieldData = 'midas'; UPDATE userProfileData set fieldData = '4' where fieldName = 'richEditor' and fieldData = 'classic'; UPDATE userProfileData set fieldData = '5' where fieldName = 'richEditor' and fieldData = 'lastResort'; --- DataForm +delete from international where namespace='Survey' and internationalId=68; +delete from international where namespace='SQLReport' and internationalId=3; +delete from international where namespace='SQLReport' and internationalId=13; +delete from international where languageId=1 and namespace='Survey' and internationalId=87; +insert into international (internationalId,languageId,namespace,message,lastUpdated,context) values (87,1,'Survey','Click here to start a new response.', 1075639972,'A label indicating that the user could start a new survey/quiz response by clicking.'); +delete from international where languageId=1 and namespace='Survey' and internationalId=86; +insert into international (internationalId,languageId,namespace,message,lastUpdated,context) values (86,1,'Survey','Progress', 1075639914,'A label indicating how far the user has progressed through the survey\r\n'); +delete from international where languageId=1 and namespace='Survey' and internationalId=85; +insert into international (internationalId,languageId,namespace,message,lastUpdated,context) values (85,1,'Survey','Questions Per Response', 1075639549,'Ask the user how many questions should be displayed to the user per time taking the survey.'); +delete from international where languageId=1 and namespace='Survey' and internationalId=84; +insert into international (internationalId,languageId,namespace,message,lastUpdated,context) values (84,1,'Survey','Max Responses Per User', 1075639389,'Ask the user how many responses the user should be able to submit to the survey.'); +delete from international where languageId=1 and namespace='Survey' and internationalId=83; +insert into international (internationalId,languageId,namespace,message,lastUpdated,context) values (83,1,'Survey','Questions Per Page', 1075639327,'Ask the user how many questions should be displayed per page on the survey.'); +INSERT INTO template VALUES (1,'Default Overview Report','

\n\n\n \"> \n •\n \"> \n •\n \"> \n
\n \"> \n •\n \"> \n •\n \"> \n •\n \"> \n
\n\n

\n\n\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \">\n \n \n \n \n
\');\">
\n \n

\n \n

\n
\n
\n \n
\n \');\">\n
\n
\">\n \n

\n \n

\n \n
\n \n
\n
\n
\n
\n
\n


\n\n
\n\n\n\n
\n · · \n
\n
\n\n','Survey/Overview'); +INSERT INTO template VALUES (1,'Default Gradebook Report','

\n\n\n \"> \n •\n \"> \n •\n \"> \n
\n \"> \n •\n \"> \n •\n \"> \n •\n \"> \n
\n\n

\n\n\n\n \n \n\n\n \n \n \n\n\n
\">/%
\n\n\n\n
\n · · \n
\n
\n','Survey/Gradebook'); +INSERT INTO template VALUES (1,'Default Survey','\n

\n
\n\n\n\n

\n\n\n\n\n \n \n \n \n \n

\n : / \n
\n :% \n
\n
\n \n

\">\n
\n \n \n \n \n \n \n \n \n
\n \n

\n
\n
\n
\n \n
\n
\n
\n
\n
\n : /
\n \n : /
\n :% / 100%
\n
\n
\n
\n \n \n \">\n
\n \n\n \n \n \n \n \n\n
\n
\n\n \"> \n •\n \"> \n •\n \"> \n
\n \"> \n •\n \"> \n •\n \"> \n •\n \"> \n
\n\n\n\n

\n \">\n

\n \n \n \n
\n
\n
\n','Survey'); +INSERT INTO template VALUES (1,'Default Response','

\n\n\n \"> \n •\n \"> \n •\n \"> \n\n\">

\n:
\n:
\n: \n\n

\n\n\n
\n \n\n \n \n \n \n \n\n \n \n \n \n\n
\n \n \n
\n

\n','Survey/Response'); CREATE TABLE DataForm_tab ( wobjectId int(11) NOT NULL default '0', label varchar(255) NOT NULL default '', @@ -329,4 +345,7 @@ INSERT INTO international VALUES (101,'DataForm',1,'Label',NULL,NULL); INSERT INTO international VALUES (100,'DataForm',1,'Are you certain that you want to delete this tab ?',NULL,NULL); INSERT INTO template VALUES (1,'Mail Form','\r\n

\r\n\r\n\r\n\r\n
    \r\n\r\n
  • \r\n\r\n
\r\n
\r\n\r\n\r\n

\r\n\r\n\r\n\r\n \">\r\n · \">\r\n \r\n · \">\r\n \r\n \r\n · \">\r\n · \">\r\n \r\n

\r\n\r\n\r\n\r\n\r\n\r\n \r\n \r\n \r\n\r\n\r\n
\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n *\r\n
\r\n
\r\n\r\n\r\n','DataForm'); INSERT INTO template VALUES (4,'Tab Form','\r\n

\r\n
\r\n\r\n\r\n
    \r\n \r\n
  • \r\n \r\n
\r\n
\r\n\r\n\r\n

\r\n\r\n\r\n\r\n \">\r\n · \">\r\n \r\n · \">\r\n \r\n \r\n · \">\r\n · \">\r\n \r\n

\r\n\r\n\r\n\r\n

\r\n \r\n )\" id=\"tab\" class=\"tab\">\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n *\r\n \r\n
\r\n \r\n
\r\n
\r\n \r\n
\r\n
\r\n
\r\n \r\n
\r\n\r\n\r\n','DataForm'); --- DataForm + + + + diff --git a/lib/WebGUI/Paginator.pm b/lib/WebGUI/Paginator.pm index 40c154aef..f27f21ead 100644 --- a/lib/WebGUI/Paginator.pm +++ b/lib/WebGUI/Paginator.pm @@ -18,6 +18,7 @@ use strict; use WebGUI::International; use WebGUI::Session; use WebGUI::URL; +use WebGUI::Utility; =head1 NAME @@ -30,9 +31,11 @@ Package that paginates rows of arbitrary data for display on the web. =head1 SYNOPSIS use WebGUI::Paginator; - $p = WebGUI::Paginator->new("/index.pl/page_name?this=that",\@row); + $p = WebGUI::Paginator->new("/index.pl/page_name?this=that"); + $p->setDataByArrayRef(\@array); $p->setDataByQuery($sql); + $p->appendTemplateVars($hashRef); $html = $p->getBar; $html = $p->getBarAdvanced; $html = $p->getBarSimple; @@ -57,31 +60,55 @@ These methods are available from this class: #------------------------------------------------------------------- -=head2 getBar ( [ pageNumber ] ) +=head2 appendTemplateVars ( hashRef ) -Returns the pagination bar including First, Previous, Next, and last links. If there's only one page, nothing is returned. +Adds paginator template vars to a hash reference. =over -=item pageNumber +=item hashRef -Defaults to the page you're currently viewing. This is mostly here as an override and probably has no real use. +The hash reference to append the variables to. =back =cut +sub appendTemplateVars { + my $self = shift; + my $var = shift; + $var->{'pagination.firstpage'} = $self->getFirstPageLink; + $var->{'pagination.lastpage'} = $self->getLastPageLink; + $var->{'pagination.nextpage'} = $self->getNextPageLink; + $var->{'pagination.previouspage'} = $self->getPreviousPageLink; + $var->{'pagination.pageNumber'} = $self->getPageNumber; + $var->{'pagination.pageCount'} = $self->getNumberOfPages; + $var->{'pagination.pageCount.isMultiple'} = ($self->getNumberOfPages > 1); + $var->{'pagination.pageList'} = $self->getPageLinks; + $var->{'pagination.pageList.upTo10'} = $self->getPageLinks(10); + $var->{'pagination.pageList.upTo20'} = $self->getPageLinks(20); +} + + +#------------------------------------------------------------------- + +=head2 getBar ( ) + +Returns the pagination bar including First, Previous, Next, and last links. If there's only one page, nothing is returned. + +=cut + sub getBar { my ($output); if ($_[0]->getNumberOfPages > 1) { $output = ''; return $output; } else { @@ -92,33 +119,25 @@ sub getBar { #------------------------------------------------------------------- -=head2 getBarAdvanced ( [ pageNumber ] ) +=head2 getBarAdvanced ( ) Returns the pagination bar including First, Previous, Page Numbers, Next, and Last links. If there's only one page, nothing is returned. -=over - -=item pageNumber - -Defaults to the page you're currently viewing. This is mostly here as an override and probably has no real use. - -=back - =cut sub getBarAdvanced { my ($output); if ($_[0]->getNumberOfPages > 1) { $output = ''; return $output; } else { @@ -129,27 +148,19 @@ sub getBarAdvanced { #------------------------------------------------------------------- -=head2 getBarSimple ( [ pageNumber ] ) +=head2 getBarSimple ( ) Returns the pagination bar including only Previous and Next links. If there's only one page, nothing is returned. -=over - -=item pageNumber - -Defaults to the page you're currently viewing. This is mostly here as an override and probably has no real use. - -=back - =cut sub getBarSimple { my ($output); if ($_[0]->getNumberOfPages > 1) { $output = ''; return $output; } else { @@ -160,29 +171,21 @@ sub getBarSimple { #------------------------------------------------------------------- -=head2 getBarTraditional ( [ pageNumber ] ) +=head2 getBarTraditional ( ) Returns the pagination bar including Previous, Page Numbers, and Next links. If there's only one page, nothing is returned. -=over - -=item pageNumber - -Defaults to the page you're currently viewing. This is mostly here as an override and probably has no real use. - -=back - =cut sub getBarTraditional { my ($output); if ($_[0]->getNumberOfPages > 1) { $output = ''; return $output; } else { @@ -193,23 +196,15 @@ sub getBarTraditional { #------------------------------------------------------------------- -=head2 getFirstPageLink ( [ pageNumber ] ) +=head2 getFirstPageLink ( ) Returns a link to the first page's data. -=over - -=item pageNumber - -Defaults to the page you're currently viewing. This is mostly here as an override and probably has no real use. - -=back - =cut sub getFirstPageLink { my ($text, $pn); - $pn = $_[1] || $_[0]->getPageNumber; + $pn = $_[0]->getPageNumber; $text = '|<'.WebGUI::International::get(404); if ($pn > 1) { return 'getPageNumber; + $pn = $_[0]->getPageNumber; $text = WebGUI::International::get(92).'»'; if ($pn < $_[0]->getNumberOfPages) { return ''.$text.''; @@ -362,55 +341,63 @@ sub getPageNumber { #------------------------------------------------------------------- -=head2 getPageLinks ( [ pageNumber ] ) +=head2 getPageLinks ( [ limit ] ) Returns links to all pages in this paginator. =over -=item pageNumber +=iten limit -Defaults to the page you're currently viewing. This is mostly here as an override and probably has no real use. +An integer representing the maximum number of page links to return. Defaultly all page links will be returned. =back =cut sub getPageLinks { - my ($i, $output, $pn); - $pn = $_[1] || $_[0]->getPageNumber; - for ($i=0; $i<$_[0]->getNumberOfPages; $i++) { + my $self = shift; + my $limit = shift; + my $pn = $self->getPageNumber; + my @pages; + for (my $i=0; $i<$self->getNumberOfPages; $i++) { if ($i+1 == $pn) { - $output .= ' '.($i+1).' '; + push(@pages,($i+1)); } else { - $output .= ' '.($i+1).' '; + push(@pages,''.($i+1).''); } } - return $output; + if ($limit) { + my $output; + my $i = 1; + my $minPage = $self->getPageNumber - round($limit/2); + my $maxPage = $minPage + $limit; + my $start = ($minPage > 0) ? $minPage : 1; + my $end = ($maxPage < $self->getPageNumber) ? $maxPage : $self->getPageNumber; + foreach my $page (@pages) { + if ($i <= $end && $i >= $start) { + $output .= $page.' '; + } + $i++; + } + return $output; + } else { + return join(" ",@pages); + } } #------------------------------------------------------------------- -=head2 getPreviousPageLink ( [ pageNumber ] ) +=head2 getPreviousPageLink ( ) Returns a link to the previous page's data. -=over - -=item pageNumber - -Defaults to the page you're currently viewing. This is mostly here as an override and probably has no real use. - -=back - =cut sub getPreviousPageLink { my ($text, $pn); - $pn = $_[1] || $_[0]->getPageNumber; + $pn = $_[0]->getPageNumber; $text = '«'.WebGUI::International::get(91); if ($pn > 1) { return ''.$text.''; @@ -435,7 +422,7 @@ sub getRowCount { #------------------------------------------------------------------- -=head2 new ( currentURL, rowArrayRef [, paginateAfter, pageNumber, formVar ] ) +=head2 new ( currentURL [, paginateAfter, pageNumber, formVar ] ) Constructor. @@ -445,17 +432,13 @@ Constructor. The URL of the current page including attributes. The page number will be appended to this in all links generated by the paginator. -=item rowArrayRef - -An array reference to all the rows of data for this page. - =item paginateAfter The number of rows to display per page. If left blank it defaults to 50. =item pageNumber -By default the paginator uses a form variable of "pn" to determine the page number. If you wish it to use some other variable, then specify the page number here. +By default the page number will be determined by looking at $session{form}{pn}. If that is empty the page number will be defaulted to "1". If you'd like to override the page number specify it here. =item formVar @@ -467,16 +450,38 @@ Specify the form variable the paginator should use in it's links. Defaults to " sub new { my ($class, $currentURL, $rowsPerPage, $rowRef, $formVar, $pageRef, $pn); - $class = $_[0]; - $currentURL = $_[1]; - $rowRef = $_[2]; - $rowsPerPage = $_[3] || 25; - $formVar = $_[5] || "pn"; - $pn = $_[4] || $session{form}{$formVar} || 1; - my $totalRows = $#{$rowRef}; - bless {_url => $currentURL, _rpp => $rowsPerPage, _totalRows=>$totalRows , _rowRef => $rowRef, _formVar => $formVar, _pn => $pn}, $class; + my $class = shift; + my $currentURL = shift; + my $rowsPerPage = shift || 25; + my $formVar = shift || "pn"; + my $pn = shift || $session{form}{$formVar} || 1; + bless {_url => $currentURL, _rpp => $rowsPerPage, _formVar => $formVar, _pn => $pn}, $class; } +#------------------------------------------------------------------- + +=head2 setDataByArrayRef ( arrayRef ) + +Provide the paginator with data by giving it an array reference. + +=over + +=item arrayRef + +The array reference that contains the data to be paginated. + +=back + +=cut + +sub setDataByArrayRef { + my $self = shift; + my $rowRef = shift; + $self->{_rowRef} = $rowRef; + $self->{_totalRows} = $#{$rowRef}; +} + + #------------------------------------------------------------------- =head2 setDataByQuery ( query [, dbh, unconditional ] ) diff --git a/lib/WebGUI/Wobject/Survey.pm b/lib/WebGUI/Wobject/Survey.pm index 798f1b66a..af21e27ff 100644 --- a/lib/WebGUI/Wobject/Survey.pm +++ b/lib/WebGUI/Wobject/Survey.pm @@ -28,7 +28,7 @@ our @ISA = qw(WebGUI::Wobject); #------------------------------------------------------------------- -sub _addAnswer { +sub addAnswer { $_[0]->setCollateral("Survey_answer","Survey_answerId",{ Survey_id=>$_[0]->get("Survey_id"), Survey_questionId=>$_[2], @@ -38,32 +38,16 @@ sub _addAnswer { } #------------------------------------------------------------------- -sub _setAnswerType { - $_[0]->setCollateral("Survey_question","Survey_questionId",{ - Survey_questionId=>$_[2], - Survey_id=>$_[0]->get("Survey_id"), - answerFieldType=>$_[1] - },1,0,"Survey_id"); +sub completeResponse { + my $self = shift; + my $responseId = shift; + WebGUI::SQL->setRow("Survey_response","Survey_responseId",{ + 'Survey_responseId'=>$responseId, + isComplete=>1 + }); + WebGUI::Session::deleteScratch($self->getResponseIdString); } -#------------------------------------------------------------------- -sub _submenu { - my ($output, $key); - return $_[1] if ($session{form}{makePrintable}); - $output = ' -
'; - $output .= $_[1]; - $output .= ''; - $output .= '
  • '.WebGUI::International::get(62,$_[0]->get("namespace")).''; - $output .= '
  • '.WebGUI::International::get(63,$_[0]->get("namespace")).''; - $output .= '
  • '.WebGUI::International::get(64,$_[0]->get("namespace")).''; - $output .= '
  • '.WebGUI::International::get(65,$_[0]->get("namespace")).''; - $output .= '
  • '.WebGUI::International::get(61,$_[0]->get("namespace")).''; - $output .= '
  • '.WebGUI::International::get(59,$_[0]->get("namespace")).''; - $output .= '
  • '.WebGUI::International::get(60,$_[0]->get("namespace")).''; - $output .= '
  • '; - return $output; -} #------------------------------------------------------------------- sub duplicate { @@ -103,6 +87,219 @@ sub duplicate { $a->finish; } +#------------------------------------------------------------------- +sub generateResponseId { + my $self = shift; + my $varname = $self->getResponseIdString; + if ($session{scratch}{$varname}) { + $self->completeResponse; + } + my $ipAddress = $self->getIp; + my $userId = $self->getUserId; + my $responseId = WebGUI::SQL->setRow("Survey_response","Survey_responseId",{ + 'Survey_responseId'=>"new", + userId=>$userId, + ipAddress=>$ipAddress, + username=>$session{user}{username}, + startDate=>WebGUI::DateTime::time(), + 'Survey_id'=>$self->get("Survey_id") + }); + WebGUI::Session::setScratch($varname,$responseId); + return $session{scratch}{$varname}; +} + +#------------------------------------------------------------------- +sub getIp { + my $self = shift; + my $ip = ($self->get("anonymous")) ? substr(md5_hex($session{env}{REMOTE_ADDR}),0,8) : $session{env}{REMOTE_ADDR}; + return $ip; +} + + + +#------------------------------------------------------------------- +sub getMenuVars { + my $self = shift; + my %var; + $var{'user.canViewReports'} = (WebGUI::Privilege::isInGroup($self->get("groupToViewReports"))); + $var{'delete.all.responses.url'} = WebGUI::URL::page('func=deleteAllResponses&wid='.$self->get("wobjectId")); + $var{'delete.all.responses.label'} = WebGUI::International::get(73,$self->get("namespace")); + $var{'export.answers.url'} = WebGUI::URL::page('func=exportAnswers&wid='.$self->get("wobjectId")); + $var{'export.answers.label'} = WebGUI::International::get(62,$self->get("namespace")); + $var{'export.questions.url'} = WebGUI::URL::page('func=exportQuestions&wid='.$self->get("wobjectId")); + $var{'export.questions.label'} = WebGUI::International::get(63,$self->get("namespace")); + $var{'export.responses.url'} = WebGUI::URL::page('func=exportResponses&wid='.$self->get("wobjectId")); + $var{'export.responses.label'} = WebGUI::International::get(64,$self->get("namespace")); + $var{'export.composite.url'} = WebGUI::URL::page('func=exportComposite&wid='.$self->get("wobjectId")); + $var{'export.composite.label'} = WebGUI::International::get(65,$self->get("namespace")); + $var{'report.gradebook.url'} = WebGUI::URL::page('func=viewGradebook&wid='.$self->get("wobjectId")); + $var{'report.gradebook.label'} = WebGUI::International::get(61,$self->get("namespace")); + $var{'report.overview.url'} = WebGUI::URL::page('func=viewStatisticalOverview&wid='.$self->get("wobjectId")); + $var{'report.overview.label'} = WebGUI::International::get(59,$self->get("namespace")); + $var{'survey.url'} = WebGUI::URL::page(); + $var{'survey.label'} = WebGUI::International::get(60,$self->get("namespace")); + return \%var; +} + +#------------------------------------------------------------------- +sub getQuestionCount { + my $self = shift; + my ($count) = WebGUI::SQL->quickArray("select count(*) from Survey_question where Survey_id=".$self->get("Survey_id")); + return ($count < $self->getValue("questionsPerResponse")) ? $count : $self->getValue("questionsPerResponse"); +} + +#------------------------------------------------------------------- +sub getQuestionsLoop { + my $self = shift; + my $responseId = shift; + my @ids; + if ($self->get("questionOrder") eq "sequential") { + @ids = $self->getSequentialQuestionIds($responseId); + } elsif ($self->get("questionOrder") eq "response") { + @ids = $self->getResponseDrivenQuestionIds($responseId); + } else { + @ids = $self->getRandomQuestionIds($responseId); + } + my $length = $#ids+1; + my $i = 1; + my @loop; + my $questionResponseCount = $self->getQuestionResponseCount($responseId); + while ($i <= $length && $i<= $self->get("questionsPerPage") && ($questionResponseCount + $i) <= $self->getValue("questionsPerResponse")) { + push(@loop,$self->getQuestionVars($ids[($i-1)])); + $i++; + } + return \@loop; +} + + +#------------------------------------------------------------------- +sub getQuestionResponseCount { + my $self = shift; + my $responseId = shift; + my ($count) = WebGUI::SQL->quickArray("select count(*) from Survey_questionResponse where Survey_responseId=".$responseId); + return $count; +} + +#------------------------------------------------------------------- +sub getQuestionVars { + my $self = shift; + my $questionId = shift; + my %var; + my $question = WebGUI::SQL->getRow("Survey_question","Survey_questionId",$questionId); + $var{'question.question'} = $question->{question}; + $var{'question.allowComment'} = $question->{allowComment}; + $var{'question.id'} = $question->{Survey_questionId}; + $var{'question.comment.field'} = WebGUI::Form::textarea({ + name=>'comment_'.$questionId + }); + $var{'question.comment.label'} = WebGUI::International::get(51,$self->get("namespace")); + if ($question->{answerFieldType} eq "text") { + my ($answer) = WebGUI::SQL->quickArray("select Survey_answerId from Survey_answer where Survey_questionId=".$question->{Survey_questionId}); + $var{'question.answer.field'} = WebGUI::Form::hidden({ + name=>'answerId_'.$questionId, + value=>$answer + }); + $var{'question.answer.field'} .= WebGUI::Form::text({ + name=>'textResponse_'.$questionId + }); + } else { + my $answer = WebGUI::SQL->buildHashRef("select Survey_answerId,answer from Survey_answer where Survey_questionId=".$question->{Survey_questionId}." order by sequenceNumber"); + if ($question->{randomizeAnswers}) { + $answer = randomizeHash($answer); + } + $var{'question.answer.field'} = WebGUI::Form::radioList({ + options=>$answer, + name=>"answerId_".$questionId, + vertical=>1 + }); + } + return \%var; +} + +#------------------------------------------------------------------- +sub getRandomQuestionIds { + my $self = shift; + my $responseId = shift; + my @usedQuestionIds = WebGUI::SQL->buildArray("select Survey_questionId from Survey_questionResponse where Survey_responseId=".$responseId); + my $where = " where Survey_id=".$self->get("Survey_id"); + if ($#usedQuestionIds+1 > 0) { + $where .= " and Survey_questionId not in (".join(",",@usedQuestionIds).")"; + } + my @questions = WebGUI::SQL->buildArray("select Survey_questionId from Survey_question".$where); + randomizeArray(\@questions); + return @questions; +} + +#------------------------------------------------------------------- +sub getResponseCount { + my $self = shift; + my $ipAddress = $self->getIp; + my $userId = $self->getUserId; + my ($count) = WebGUI::SQL->quickArray("select count(*) from Survey_response where Survey_id=".$self->get("Survey_id")." and + ((userId<>1 and userId=".quote($userId).") or ( userId=1 and ipAddress=".quote($ipAddress)."))"); + return $count; +} + + +#------------------------------------------------------------------- +sub getResponseDrivenQuestionIds { + my $self = shift; + my $responseId = shift; + my $previousResponse = WebGUI::SQL->quickHashRef("select Survey_questionId, Survey_answerId from Survey_questionResponse + where Survey_responseId=$responseId order by dateOfResponse desc"); + my $questionId; + my @questions; + if (defined $previousResponse) { + ($questionId) = WebGUI::SQL->quickArray("select gotoQuestion from Survey_answer where + Survey_answerId=".$previousResponse->{Survey_answerId}); + unless ($questionId > 0) { + ($questionId) = WebGUI::SQL->quickArray("select gotoQuestion from Survey_question where + Survey_questionId=".$previousResponse->{Survey_questionId}); + } + unless ($questionId > 0) { + $questionId = undef; + } + } else { + ($questionId) = WebGUI::SQL->quickArray("select Survey_questionId from Survey_question where Survey_responseId=$responseId + order by sequenceNumber"); + } + push(@questions,$questionId); + return @questions; +} + +#------------------------------------------------------------------- +sub getResponseId { + my $self = shift; + return $session{scratch}{$self->getResponseIdString}; +} + +#------------------------------------------------------------------- +sub getResponseIdString { + my $self = shift; + return "Survey-".$self->get("Survey_id")."-ResponseId"; +} + + +#------------------------------------------------------------------- +sub getSequentialQuestionIds { + my $self = shift; + my $responseId = shift; + my @usedQuestionIds = WebGUI::SQL->buildArray("select Survey_questionId from Survey_questionResponse where Survey_responseId=".$responseId); + my $where = " where Survey_id=".$self->get("Survey_id"); + if ($#usedQuestionIds+1 > 0) { + $where = " and Survey_questionId not in (".join(",",@usedQuestionIds).")"; + } + my @questions = WebGUI::SQL->buildArray("select Survey_questionId from Survey_question $where order by sequenceNumber"); + return @questions; +} + +#------------------------------------------------------------------- +sub getUserId { + my $self = shift; + my $userId = ($self->get("anonymous") && $session{user}{userId} != 1) ? substr(md5_hex($session{user}{userId}),0,8) : $session{user}{userId}; + return $userId; +} + #------------------------------------------------------------------- sub name { return WebGUI::International::get(1,$_[0]->get("namespace")); @@ -131,7 +328,26 @@ sub new { anonymous=>{ defaultValue=>0 }, - } + maxResponsesPerUser=>{ + defaultValue=>1, + fieldType=>"integer" + }, + questionsPerResponse=>{ + defaultValue=>99999, + fieldType=>"integer" + }, + questionsPerPage=>{ + defaultValue=>1, + fieldType=>"integer" + }, + reportcardTemplateId=>{ + defaultValue=>1 + }, + overviewTemplateId=>{ + defaultValue=>1 + } + }, + -useTemplate=>1 ); bless $self, $class; } @@ -148,6 +364,24 @@ sub purge { } +#------------------------------------------------------------------- +sub responseIsComplete { + my $self = shift; + my $responseId = shift; + my $response = WebGUI::SQL->getRow("Survey_response","Survey_responseId",$responseId); + return $response->{isComplete}; +} + + +#------------------------------------------------------------------- +sub setAnswerType { + $_[0]->setCollateral("Survey_question","Survey_questionId",{ + Survey_questionId=>$_[2], + Survey_id=>$_[0]->get("Survey_id"), + answerFieldType=>$_[1] + },1,0,"Survey_id"); +} + #------------------------------------------------------------------- sub uiLevel { return 5; @@ -188,32 +422,32 @@ sub www_deleteQuestionConfirm { } #------------------------------------------------------------------- -sub www_deleteResponses { +sub www_deleteResponse { return "" unless (WebGUI::Privilege::isInGroup($_[0]->get("groupToViewReports"))); - return $_[0]->_submenu($_[0]->confirm(WebGUI::International::get(72,$_[0]->get("namespace")), - WebGUI::URL::page('func=deleteResponsesConfirm&wid='.$_[0]->get("wobjectId").'&uid=' - .$session{form}{uid}.'&ip='.$session{form}{ip}))); + return $_[0]->confirm(WebGUI::International::get(72,$_[0]->get("namespace")), + WebGUI::URL::page('func=deleteResponseConfirm&wid='.$_[0]->get("wobjectId").'&responseId='.$session{form}{responseId})); } #------------------------------------------------------------------- -sub www_deleteResponsesConfirm { +sub www_deleteResponseConfirm { return "" unless (WebGUI::Privilege::isInGroup($_[0]->get("groupToViewReports"))); - WebGUI::SQL->write("delete from Survey_response where ((userId='$session{form}{uid}' - and userId<>1) or (userId=1 and ipAddress='$session{form}{ip}')) and Survey_id=".$_[0]->get("Survey_id")); + WebGUI::SQL->write("delete from Survey_response where Survey_responseId=".$session{form}{responseId}); + WebGUI::SQL->write("delete from Survey_questionResponse where Survey_responseId=".$session{form}{responseId}); return $_[0]->www_viewGradebook; } #------------------------------------------------------------------- sub www_deleteAllResponses { return "" unless (WebGUI::Privilege::isInGroup($_[0]->get("groupToViewReports"))); - return $_[0]->_submenu($_[0]->confirm(WebGUI::International::get(74,$_[0]->get("namespace")), - WebGUI::URL::page('func=deleteAllResponsesConfirm&wid='.$_[0]->get("wobjectId")))); + return $_[0]->confirm(WebGUI::International::get(74,$_[0]->get("namespace")), + WebGUI::URL::page('func=deleteAllResponsesConfirm&wid='.$_[0]->get("wobjectId"))); } #------------------------------------------------------------------- sub www_deleteAllResponsesConfirm { return "" unless (WebGUI::Privilege::isInGroup($_[0]->get("groupToViewReports"))); WebGUI::SQL->write("delete from Survey_response where Survey_id=".$_[0]->get("Survey_id")); + WebGUI::SQL->write("delete from Survey_questionResponse where Survey_id=".$_[0]->get("Survey_id")); return ""; } @@ -225,7 +459,7 @@ sub www_edit { my $layout = WebGUI::HTMLForm->new; my $privileges = WebGUI::HTMLForm->new; $properties->hidden("Survey_id",($_[0]->get("Survey_id") || getNextId("Survey_id"))); - $layout->select( + $layout->selectList( -name=>"questionOrder", -options=>{ sequential => WebGUI::International::get(5,$_[0]->get("namespace")), @@ -235,7 +469,12 @@ sub www_edit { -label=>WebGUI::International::get(8,$_[0]->get("namespace")), -value=>[$_[0]->getValue("questionOrder")] ); - $properties->select( + $layout->integer( + -name=>"questionsPerPage", + -value=>$_[0]->getValue("questionsPerPage"), + -label=>WebGUI::International::get(83,$_[0]->get("namespace")) + ); + $properties->selectList( -name=>"mode", -options=>{ survey => WebGUI::International::get(9,$_[0]->get("namespace")), @@ -244,11 +483,21 @@ sub www_edit { -label=>WebGUI::International::get(11,$_[0]->get("namespace")), -value=>[$_[0]->getValue("mode")] ); - $properties->yesNo( - -name=>"anonymous", - -value=>$_[0]->getValue("anonymous"), - -label=>WebGUI::International::get(81,$_[0]->get("namespace")) - ); + $properties->yesNo( + -name=>"anonymous", + -value=>$_[0]->getValue("anonymous"), + -label=>WebGUI::International::get(81,$_[0]->get("namespace")) + ); + $properties->integer( + -name=>"maxResponsesPerUser", + -value=>$_[0]->getValue("maxResponsesPerUser"), + -label=>WebGUI::International::get(84,$_[0]->get("namespace")) + ); + $properties->integer( + -name=>"questionsPerResponse", + -value=>$_[0]->getValue("questionsPerResponse"), + -label=>WebGUI::International::get(85,$_[0]->get("namespace")) + ); $privileges->group( -name=>"groupToTakeSurvey", -value=>[$_[0]->getValue("groupToTakeSurvey")], @@ -275,20 +524,6 @@ sub www_edit { -headingId=>2, -helpId=>1 ); - if ($_[0]->get("wobjectId") ne "new") { - $output .= ''.WebGUI::International::get(30,$_[0]->get("namespace")).'

    '; - $sth = WebGUI::SQL->read("select Survey_questionId,question from Survey_question where Survey_id=" - .$_[0]->get("Survey_id")." order by sequenceNumber"); - while (%data = $sth->hash) { - $output .= deleteIcon('func=deleteQuestion&wid='.$_[0]->get("wobjectId").'&qid='.$data{Survey_questionId}) - .editIcon('func=editQuestion&wid='.$_[0]->get("wobjectId").'&qid='.$data{Survey_questionId}) - .moveUpIcon('func=moveQuestionUp&wid='.$_[0]->get("wobjectId").'&qid='.$data{Survey_questionId}) - .moveDownIcon('func=moveQuestionDown&wid='.$_[0]->get("wobjectId").'&qid='.$data{Survey_questionId}) - .' '.$data{question}.'
    '; - } - $sth->finish; - } return $output; } @@ -465,35 +700,33 @@ sub www_editQuestionSave { $session{form}{aid} = "new"; return $_[0]->www_editAnswer(); } elsif ($session{form}{proceed} eq "addTextAnswer") { - $_[0]->_setAnswerType("text",$session{form}{qid}); - $_[0]->_addAnswer(0,$session{form}{qid}); + $_[0]->setAnswerType("text",$session{form}{qid}); + $_[0]->addAnswer(0,$session{form}{qid}); } elsif ($session{form}{proceed} eq "addBooleanAnswer") { - $_[0]->_addAnswer(31,$session{form}{qid}); - $_[0]->_addAnswer(32,$session{form}{qid}); + $_[0]->addAnswer(31,$session{form}{qid}); + $_[0]->addAnswer(32,$session{form}{qid}); return $_[0]->www_editQuestion(); } elsif ($session{form}{proceed} eq "addOpinionAnswer") { - $_[0]->_addAnswer(33,$session{form}{qid}); - $_[0]->_addAnswer(34,$session{form}{qid}); - $_[0]->_addAnswer(35,$session{form}{qid}); - $_[0]->_addAnswer(36,$session{form}{qid}); - $_[0]->_addAnswer(37,$session{form}{qid}); - $_[0]->_addAnswer(38,$session{form}{qid}); - $_[0]->_addAnswer(39,$session{form}{qid}); + $_[0]->addAnswer(33,$session{form}{qid}); + $_[0]->addAnswer(34,$session{form}{qid}); + $_[0]->addAnswer(35,$session{form}{qid}); + $_[0]->addAnswer(36,$session{form}{qid}); + $_[0]->addAnswer(37,$session{form}{qid}); + $_[0]->addAnswer(38,$session{form}{qid}); + $_[0]->addAnswer(39,$session{form}{qid}); return $_[0]->www_editQuestion(); } elsif ($session{form}{proceed} eq "addFrequencyAnswer") { - $_[0]->_addAnswer(40,$session{form}{qid}); - $_[0]->_addAnswer(41,$session{form}{qid}); - $_[0]->_addAnswer(42,$session{form}{qid}); - $_[0]->_addAnswer(43,$session{form}{qid}); - $_[0]->_addAnswer(39,$session{form}{qid}); + $_[0]->addAnswer(40,$session{form}{qid}); + $_[0]->addAnswer(41,$session{form}{qid}); + $_[0]->addAnswer(42,$session{form}{qid}); + $_[0]->addAnswer(43,$session{form}{qid}); + $_[0]->addAnswer(39,$session{form}{qid}); return $_[0]->www_editQuestion(); } elsif ($session{form}{proceed} eq "addQuestion") { $session{form}{qid} eq "new"; return $_[0]->www_editQuestion(); - } elsif ($session{form}{proceed} eq "backToPage") { - return "" } - return $_[0]->www_edit; + return ""; } #------------------------------------------------------------------- @@ -560,332 +793,261 @@ sub www_moveQuestionUp { #------------------------------------------------------------------- sub www_respond { - return "" unless (WebGUI::Privilege::isInGroup($_[0]->get("groupToTakeSurvey"))); - return "" unless ($session{form}{Survey_answerId} ne ""); - my $userId = ($_[0]->get("anonymous")) ? substr(md5_hex($session{user}{userId}),0,8) : $session{user}{userId}; - my ($previousResponse) = WebGUI::SQL->quickArray("select count(*) from Survey_response - where Survey_answerId=$session{form}{Survey_answerId} and ((userId='".$userId."' and userId<>1) - or (userId=1 and ipAddress='".$session{form}{ip}."'))"); - return "" if ($previousResponse); - my $answer = $_[0]->getCollateral("Survey_answer","Survey_answerId",$session{form}{Survey_answerId}); - my $response = $session{form}{response} || $answer->{answer}; - $_[0]->setCollateral("Survey_response","Survey_responseId",{ - Survey_responseId=>"new", - Survey_answerId=>$session{form}{Survey_answerId}, - Survey_questionId=>$answer->{Survey_questionId}, - Survey_id=>$answer->{Survey_id}, - comment=>$session{form}{comment}, - response=>$response, - userId=>($_[0]->get("anonymous")) ? substr(md5_hex($session{user}{userId}),0,8) : $session{user}{userId}, - username=>($_[0]->get("anonymous")) ? substr(md5_hex($session{user}{username}),0,8) : $session{user}{username}, - dateOfResponse=>time(), - ipAddress=>($_[0]->get("anonymous")) ? substr(md5_hex($session{env}{REMOTE_ADDR}),0,8) : $session{env}{REMOTE_ADDR} - },0,0); + my $self = shift; + return "" unless (WebGUI::Privilege::isInGroup($self->get("groupToTakeSurvey"))); + my $varname = $self->getResponseIdString; + return "" unless ($session{scratch}{$varname}); + my $userId = ($self->get("anonymous")) ? substr(md5_hex($session{user}{userId}),0,8) : $session{user}{userId}; + foreach my $key (keys %{$session{form}}) { + if ($key =~ /answerId_(\d+)/) { + my $id = $1; + my ($previousResponse) = WebGUI::SQL->quickArray("select count(*) from Survey_questionResponse + where Survey_answerId=".$session{form}{"answerId_".$id}." and Survey_responseId=".$session{scratch}{$varname}); + next if ($previousResponse); + my $answer = $self->getCollateral("Survey_answer","Survey_answerId",$session{form}{"answerId_".$id}); + my $response = $session{form}{"textResponse_".$id} || $answer->{answer}; + WebGUI::SQL->write("insert into Survey_questionResponse (Survey_answerId,Survey_questionId,Survey_responseId,Survey_id,comment,response,dateOfResponse) values ( + ".$answer->{Survey_answerId}.", ".$answer->{Survey_questionId}.", ".$session{scratch}{$varname}.", ".$answer->{Survey_id}.", + ".quote($session{form}{"comment_".$id}).", ".quote($response).", ".WebGUI::DateTime::time().")"); + } + } + my $responseCount = $self->getQuestionResponseCount($session{scratch}{$varname}); + if ($responseCount >= $self->getValue("questionsPerResponse") || $responseCount >= $self->getQuestionCount) { + WebGUI::SQL->setRow("Survey_response","Survey_responseId",{ + isComplete=>1, + endDate=>WebGUI::DateTime::time(), + Survey_responseId=>$session{scratch}{$varname} + }); + } return ""; } #------------------------------------------------------------------- sub www_view { - my ($output, $f, $previous, $questionOrder, $previousResponse, $question, $ipAddress, $userId); - $ipAddress = ($_[0]->get("anonymous")) ? substr(md5_hex($session{env}{REMOTE_ADDR}),0,8) : $session{env}{REMOTE_ADDR}; - $userId = ($_[0]->get("anonymous")) ? substr(md5_hex($session{user}{userId}),0,8) : $session{user}{userId}; - $output = $_[0]->displayTitle; - $output .= $_[0]->description; - if (WebGUI::Privilege::isInGroup($_[0]->get("groupToViewReports"))) { - $output .= '' - .WebGUI::International::get(68,$_[0]->get("namespace")).'

    '; - } - if (WebGUI::Privilege::isInGroup($_[0]->get("groupToTakeSurvey"))) { - $previousResponse = WebGUI::SQL->quickHashRef("select Survey_questionId, Survey_answerId from Survey_response - where Survey_id=".$_[0]->get("Survey_id") - ." and ((userId='$userId' and userId<>1) or (userId=1 and - ipAddress='$ipAddress')) order by dateOfResponse desc"); - $questionOrder = $_[0]->get("questionOrder"); - if ($previousResponse->{Survey_questionId}) { - if ($questionOrder eq "random") { - my @questions = WebGUI::SQL->buildArray("select Survey_questionId from Survey_response - where Survey_id=".$_[0]->get("Survey_id")." and ((userId='$userId' - and userId<>1) or (userId=1 and ipAddress='$ipAddress'))"); - if ($#questions >= 0) { - @questions = WebGUI::SQL->buildArray("select Survey_questionId from Survey_question - where Survey_id=".$_[0]->get("Survey_id") - ." and Survey_questionId not in (".join(",",@questions).")"); - } - if ($#questions >= 0) { - $question = $_[0]->getCollateral("Survey_question","Survey_questionId", - $questions[rand($#questions+1)]); - } - } - if ($questionOrder eq "response" && $previousResponse->{Survey_answerId}) { - my ($responseDriver) = WebGUI::SQL->quickArray("select gotoQuestion from Survey_answer where - Survey_answerId=".$previousResponse->{Survey_answerId}); - if ($responseDriver) { - $question = $_[0]->getCollateral("Survey_question","Survey_questionId",$responseDriver); - } else { - $questionOrder = "sequential"; - } - undef $question if ($responseDriver < 0); # Terminate Survey - } - if ($questionOrder eq "sequential" && $previousResponse->{Survey_questionId}) { - my $previousQuestion = $_[0]->getCollateral("Survey_question","Survey_questionId", - $previousResponse->{Survey_questionId}); - $previousQuestion->{sequenceNumber} = 0 unless($previousQuestion->{sequenceNumber}); - $question = WebGUI::SQL->quickHashRef("select * from Survey_question where Survey_id=" - .$_[0]->get("Survey_id")." and sequenceNumber>".$previousQuestion->{sequenceNumber} - ." order by sequenceNumber"); - } - } else { - if ($questionOrder eq "random") { - my @questions = WebGUI::SQL->buildArray("select Survey_questionId from Survey_question - where Survey_id=".$_[0]->get("Survey_id")); - $question = $_[0]->getCollateral("Survey_question","Survey_questionId", - $questions[rand($#questions+1)]); - if ($question->{Survey_questionId} eq "new") { - delete $question->{Survey_questionId}; - } - } else { - $question = WebGUI::SQL->quickHashRef("select * from Survey_question - where Survey_id=".$_[0]->get("Survey_id")." order by sequenceNumber"); - } - } - if ($question->{Survey_questionId}) { - $output .= $question->{question}; - $f = WebGUI::HTMLForm->new; - $f->hidden("func","respond"); - $f->hidden("wid",$_[0]->get("wobjectId")); - if ($question->{answerFieldType} eq "text") { - my ($answer) = WebGUI::SQL->quickArray("select Survey_answerId from Survey_answer where - Survey_questionId=".$question->{Survey_questionId}); - $f->hidden("Survey_answerId",$answer); - $f->text( - -name=>"response" - ); - } else { - my $answer = WebGUI::SQL->buildHashRef("select Survey_answerId,answer from Survey_answer - where Survey_questionId=".$question->{Survey_questionId}." order by sequenceNumber"); - if ($question->{randomizeAnswers}) { - $answer = randomizeHash($answer); - } - $f->radioList( - -options=>$answer, - -name=>"Survey_answerId", - -vertical=>1 - ); - } - if ($question->{allowComment}) { - $f->textarea( - -name=>"comment", - -label=>WebGUI::International::get(51,$_[0]->get("namespace")) - ); - } - $f->submit(WebGUI::International::get(50,$_[0]->get("namespace"))); - $output .= $f->print; - } else { - if ($_[0]->get("mode") eq "survey") { - $output .= WebGUI::International::get(46,$_[0]->get("namespace")); - } else { - $output .= WebGUI::International::get(47,$_[0]->get("namespace")); - my ($questionCount) = WebGUI::SQL->quickArray("select count(*) from Survey_question - where Survey_id=".$_[0]->get("Survey_id")); - my ($correctCount) = WebGUI::SQL->quickArray("select count(*) from Survey_response a, - Survey_answer b where a.Survey_id=".$_[0]->get("Survey_id")." - and ((userId='$userId' and userId<>1) or - (userId=1 and ipAddress='$ipAddress')) - and a.Survey_answerId=b.Survey_answerId and b.isCorrect=1"); - if ($questionCount > 0) { - $output .= "

    ".WebGUI::International::get(52,$_[0]->get("namespace")).": " - .$correctCount."/".$questionCount - ."
    ".WebGUI::International::get(54,$_[0]->get("namespace")).": " - .round(($correctCount/$questionCount)*100)."%

    "; - } - } - } - } else { - if ($_[0]->get("mode") eq "survey") { - $output .= WebGUI::International::get(48,$_[0]->get("namespace")); - } else { - $output .= WebGUI::International::get(49,$_[0]->get("namespace")); - } - } - return $output; -} - -#------------------------------------------------------------------- -sub www_viewComments { - return "" unless (WebGUI::Privilege::isInGroup($_[0]->get("groupToViewReports"))); - my ($output, $sth, $comment); - $output = '

    '.WebGUI::International::get(57,$_[0]->get("namespace")).'

    '; - $sth = WebGUI::SQL->read("select comment from Survey_response where Survey_questionId=".$session{form}{qid}); - while (($comment) = $sth->array) { - $output .= $comment."

    \n"; + my $self = shift; + my $var = $self->getMenuVars; + $var->{'question.add.url'} = WebGUI::URL::page('wid='.$self->get("wobjectId").'&func=editQuestion&qid=new'); + $var->{'question.add.label'} = WebGUI::International::get(30,$self->get("namespace")); + my @edit; + my $sth = WebGUI::SQL->read("select Survey_questionId,question from Survey_question where Survey_id=".$self->get("Survey_id")." order by sequenceNumber"); + while (my %data = $sth->hash) { + push(@edit,{ + 'question.edit.controls'=>deleteIcon('func=deleteQuestion&wid='.$self->get("wobjectId").'&qid='.$data{Survey_questionId}) + .editIcon('func=editQuestion&wid='.$self->get("wobjectId").'&qid='.$data{Survey_questionId}) + .moveUpIcon('func=moveQuestionUp&wid='.$self->get("wobjectId").'&qid='.$data{Survey_questionId}) + .moveDownIcon('func=moveQuestionDown&wid='.$self->get("wobjectId").'&qid='.$data{Survey_questionId}), + 'question.edit.question'=>$data{question}, + 'question.edit.id'=>$data{Survey_questionId} + }); + $var->{'question.edit_loop'} = \@edit; } $sth->finish; - return $_[0]->_submenu($output); + $var->{'user.canTakeSurvey'} = WebGUI::Privilege::isInGroup($self->get("groupToTakeSurvey")); + if ($var->{'user.canTakeSurvey'}) { + $var->{'response.Id'} = $self->getResponseId(); + $var->{'response.Count'} = $self->getResponseCount; + $var->{'user.isFirstResponse'} = ($var->{'response.Count'} == 0 && !(exists $var->{'response.id'})); + $var->{'user.canRespondAgain'} = ($var->{'response.Count'} < $self->get("maxResponsesPerUser")); + if (($var->{'user.isFirstResponse'}) || ($session{form}{startNew} && $var->{'user.canRespondAgain'})) { + $var->{'response.id'} = $self->generateResponseId; + } + if ($var->{'response.Id'}) { + $var->{'questions.soFar.count'} = $self->getQuestionResponseCount($var->{'response.Id'}); + ($var->{'questions.correct.Count'}) = WebGUI::SQL->quickArray("select count(*) from Survey_questionResponse a, Survey_answer b where a.Survey_responseId=" + .$var->{'response.Id'}." and a.Survey_answerId=b.Survey_answerId and b.isCorrect=1"); + if ($var->{'questions.soFar.count'} > 0) { + $var->{'questions.correct.percent'} = round(($var->{'questions.correct.count'}/$var->{'questions.soFar.count'})*100) + } + $var->{'response.isComplete'} = $self->responseIsComplete($var->{'response.Id'}); + $var->{question_loop} = $self->getQuestionsLoop($var->{'response.Id'}); + } + } + $var->{'form.header'} = WebGUI::Form::formHeader() + .WebGUI::Form::hidden({ + name=>'wid', + value=>$self->get("wobjectId"), + }) + .WebGUI::Form::hidden({ + name=>'func', + value=>'respond' + }); + $var->{'form.footer'} = ''; + $var->{'form.submit'} = WebGUI::Form::submit({ + value=>WebGUI::International::get(50,$self->get("namespace")) + }); + $var->{'questions.sofar.label'} = WebGUI::International::get(86,$self->get("namespace")); + $var->{'start.newResponse.label'} = WebGUI::International::get(87,$self->get("namespace")); + $var->{'start.newResponse.url'} = WebGUI::URL::page("wid=".$self->get("wobjectId")."&func=view&startNew=1"); + $var->{'thanks.survey.label'} = WebGUI::International::get(46,$self->get("namespace")); + $var->{'thanks.quiz.label'} = WebGUI::International::get(47,$self->get("namespace")); + $var->{'questions.total'} = $self->getQuestionCount; + $var->{'questions.correct.count.label'} = WebGUI::International::get(52,$self->get("namespace")); + $var->{'questions.correct.percent.label'} = WebGUI::International::get(54,$self->get("namespace")); + $var->{'mode.isSurvey'} = ($self->get("mode") eq "survey"); + $var->{'survey.noprivs.label'} = WebGUI::International::get(48,$self->get("namespace")); + $var->{'quiz.noprivs.label'} = WebGUI::International::get(49,$self->get("namespace")); + return $self->processTemplate($self->getValue("templateId"),$var); } #------------------------------------------------------------------- sub www_viewGradebook { - return "" unless (WebGUI::Privilege::isInGroup($_[0]->get("groupToViewReports"))); - my ($output, $p, $users, $user); - $output = '

    '.WebGUI::International::get(71,$_[0]->get("namespace")).'

    '; - $p = WebGUI::Paginator->new(WebGUI::URL::page('func=viewGradebook&wid='.$_[0]->get("wobjectId"))); - $p->setDataByQuery("select userId,username,ipAddress from Survey_response - group by userId,username,ipAddress order by username,ipAddress"); - $users = $p->getPageData; - my ($questionCount) = WebGUI::SQL->quickArray("select count(*) from Survey_question - where Survey_id=".$_[0]->get("Survey_id")); - $output .= ''; - $output .= ' - - '; - foreach $user (@$users) { - $output .= ''; - $output .= ''; - my ($correctCount) = WebGUI::SQL->quickArray("select count(*) from Survey_response a, - Survey_answer b where a.Survey_id=".$_[0]->get("Survey_id")." - and ((userId='".$user->{userId}."' and userId<>1) or - (userId=1 and ipAddress='".$user->{ipAddress}."')) - and a.Survey_answerId=b.Survey_answerId and b.isCorrect=1"); - $output .= ''; - $output .= ''; - $output .= ''; + my $self = shift; + return "" unless (WebGUI::Privilege::isInGroup($self->get("groupToViewReports"))); + my $var = $self->getMenuVars; + $var->{title} = WebGUI::International::get(71,$self->get("namespace")); + my $p = WebGUI::Paginator->new(WebGUI::URL::page('func=viewGradebook&wid='.$self->get("wobjectId"))); + $p->setDataByQuery("select userId,username,ipAddress,Survey_responseId,startDate,endDate from Survey_response + where isComplete=1 and Survey_id=".$self->get("Survey_id")." order by username,ipAddress,startDate"); + my $users = $p->getPageData; + ($var->{'question.Count'}) = WebGUI::SQL->quickArray("select count(*) from Survey_question where Survey_id=".$self->get("Survey_id")); + $var->{'response.user.label'} = WebGUI::International::get(67,$self->get("namespace")); + $var->{'response.count.label'} = WebGUI::International::get(52,$self->get("namespace")); + $var->{'response.percent.label'} = WebGUI::International::get(54,$self->get("namespace")); + my @responseloop; + foreach my $user (@$users) { + my ($correctCount) = WebGUI::SQL->quickArray("select count(*) from Survey_questionResponse a left join + Survey_answer b on a.Survey_answerId=b.Survey_answerId where a.Survey_responseId=".$user->{Survey_responseId} + ." and b.isCorrect=1"); + push(@responseloop, { + 'response.url'=>WebGUI::URL::page('func=viewIndividualSurvey&wid='.$self->get("wobjectId") + .'&responseId='.$user->{Survey_responseId}), + 'response.user.name'=>($user->{userId} == 1) ? $user->{ipAddress} : $user->{username}, + 'response.count.correct' => $correctCount, + 'response.percent' => round(($correctCount/$var->{'question.Count'})*100) + }); } - $output .= '
    '.WebGUI::International::get(67,$_[0]->get("namespace")).''.WebGUI::International::get(52,$_[0]->get("namespace")).''.WebGUI::International::get(54,$_[0]->get("namespace")).'
    '; - if ($user->{userId} == 1) { - $output .= $user->{ipAddress}; - } else { - $output .= $user->{username}; - } - $output .= ''.$correctCount.'/'.$questionCount.''.round(($correctCount/$questionCount)*100).'
    '; - $output .= $p->getBarTraditional; - return $_[0]->_submenu($output); + $var->{response_loop} = \@responseloop; + $p->appendTemplateVars($var); + return $self->processTemplate($self->getValue("gradebookTemplateId"),$var,"Survey/Gradebook"); } #------------------------------------------------------------------- sub www_viewIndividualSurvey { - return "" unless (WebGUI::Privilege::isInGroup($_[0]->get("groupToViewReports"))); - my ($output, $questions, $sth, $qdata, $rdata, $adata, $p); - $output = '

    '.WebGUI::International::get(70,$_[0]->get("namespace")).'

    '; - $output .= ''.WebGUI::International::get(69,$_[0]->get("namespace")).'

    '; - my ($start) = WebGUI::SQL->quickArray("select min(dateOfResponse) from Survey_response - where Survey_id=".$_[0]->get("Survey_id")." and ((userId='".$session{form}{uid}."' and userId<>1) - or (userId=1 and ipAddress='".$session{form}{ip}."'))"); - my ($end) = WebGUI::SQL->quickArray("select max(dateOfResponse) from Survey_response - where Survey_id=".$_[0]->get("Survey_id")." and ((userId='".$session{form}{uid}."' and userId<>1) - or (userId=1 and ipAddress='".$session{form}{ip}."'))"); - $output .= ''.WebGUI::International::get(76,$_[0]->get("namespace")).': '.epochToHuman($start).'
    '; - $output .= ''.WebGUI::International::get(77,$_[0]->get("namespace")).': '.epochToHuman($end).'
    '; - $output .= ''.WebGUI::International::get(78,$_[0]->get("namespace")).': '.int(($end-$start)/60).' ' - .WebGUI::International::get(79,$_[0]->get("namespace")).', '.(($end-$start)%60).' ' - .WebGUI::International::get(80,$_[0]->get("namespace")).'

    '; - $p = WebGUI::Paginator->new(WebGUI::URL::page('func=viewIndividualSurvey&wid='.$_[0]->get("wobjectId") - .'&uid='.$session{form}{uid}.'&ip='.$session{form}{ip})); - $p->setDataByQuery("select Survey_questionId,question,answerFieldType from Survey_question - where Survey_id=".$_[0]->get("Survey_id")." order by sequenceNumber"); - $questions = $p->getPageData; - foreach $qdata (@$questions) { - $output .= ''.$qdata->{question}.'
    ' - .''; + my $self = shift; + return "" unless (WebGUI::Privilege::isInGroup($self->get("groupToViewReports"))); + my $var = $self->getMenuVars; + $var->{'title'} = WebGUI::International::get(70,$self->get("namespace")); + $var->{'delete.url'} = WebGUI::URL::page('func=deleteResponse&wid='.$self->get("wobjectId").'&responseId='.$session{form}{responseId}); + $var->{'delete.label'} = WebGUI::International::get(69,$self->get("namespace")); + my $response = WebGUI::SQL->getRow("Survey_response","Survey_responseId",$session{form}{responseId}); + $var->{'start.date.label'} = WebGUI::International::get(76,$self->get("namespace")); + $var->{'start.date.epoch'} = $response->{startDate}; + $var->{'start.date.human'} = epochToHuman($response->{startDate},"%z"); + $var->{'start.time.human'} = epochToHuman($response->{startDate},"%Z"); + $var->{'end.date.label'} = WebGUI::International::get(77,$self->get("namespace")); + $var->{'end.date.epoch'} = $response->{endDate}; + $var->{'end.date.human'} = epochToHuman($response->{endDate},"%z"); + $var->{'end.time.human'} = epochToHuman($response->{endDate},"%Z"); + $var->{'duration.label'} = WebGUI::International::get(78,$self->get("namespace")); + $var->{'duration.minutes'} = int(($response->{end} - $response->{start})/60); + $var->{'duration.minutes.label'} = WebGUI::International::get(79,$self->get("namespace")); + $var->{'duration.seconds'} = (($response->{endDate} - $response->{start})%60); + $var->{'duration.seconds.label'} = WebGUI::International::get(80,$self->get("namespace")); + $var->{'answer.label'} = WebGUI::International::get(19,$self->get("namespace")); + $var->{'response.label'} = WebGUI::International::get(66,$self->get("namespace")); + $var->{'comment.label'} = WebGUI::International::get(57,$self->get("namespace")); + my $a = WebGUI::SQL->read("select Survey_questionId,question,answerFieldType from Survey_question + where Survey_id=".$self->get("Survey_id")." order by sequenceNumber"); + my @questionloop; + while (my $qdata = $a->hashRef) { + my @aid; + my @answer; if ($qdata->{answerFieldType} eq "radioList") { - $output .= ''; } - $output .= ''; - $rdata = WebGUI::SQL->quickHashRef("select Survey_answerId,response,comment from Survey_response - where Survey_questionId=".$qdata->{Survey_questionId}." - and ((userId='".$session{form}{uid}."' and userId<>1) - or (userId=1 and ipAddress='".$session{form}{ip}."'))"); - $output .= ''; - if ($rdata->{comment} ne "") { - $output .= '' - .''; - } - $output .= "
    ' - .WebGUI::International::get(19,$_[0]->get("namespace")).''; - $sth = WebGUI::SQL->read("select Survey_answerId,answer from Survey_answer + my $sth = WebGUI::SQL->read("select Survey_answerId,answer from Survey_answer where Survey_questionId=".$qdata->{Survey_questionId}." and isCorrect=1 order by sequenceNumber"); - while ($adata = $sth->hashRef) { - $output .= $adata->{answer}.'
    '; + while (my $adata = $sth->hashRef) { + push(@aid,$adata->{Survey_answerId}); + push(@answer,$adata->{answer}); } $sth->finish; - $output .= '
    ' - .WebGUI::International::get(66,$_[0]->get("namespace")).''.$rdata->{response}.'
    ' - .WebGUI::International::get(57,$_[0]->get("namespace")).''.$rdata->{comment}.'

    \n"; + my $rdata = WebGUI::SQL->quickHashRef("select Survey_answerId,response,comment from Survey_questionResponse + where Survey_questionId=".$qdata->{Survey_questionId}." and Survey_responseId=".$session{form}{responseId}); + push(@questionloop,{ + question => $qdata->{question}, + 'question.id'=>$qdata->{Survey_questionId}, + 'question.isRadioList' => ($qdata->{answerFieldType} eq "radioList"), + 'question.response' => $rdata->{response}, + 'question.comment' => $rdata->{comment}, + 'question.isCorrect' => isIn($rdata->{Survey_answerId}, @aid), + 'question.answer' => join(", ",@answer), + }); } - return $_[0]->_submenu($output); -} - -#------------------------------------------------------------------- -sub www_viewResponses { - return "" unless (WebGUI::Privilege::isInGroup($_[0]->get("groupToViewReports"))); - my ($output, $sth, $response); - $output = '

    '.WebGUI::International::get(66,$_[0]->get("namespace")).'

    '; - $sth = WebGUI::SQL->read("select response from Survey_response where Survey_questionId=".$session{form}{qid}); - while (($response) = $sth->array) { - $output .= $response."

    \n"; - } - $sth->finish; - return $_[0]->_submenu($output); + $a->finish; + $var->{question_loop} = \@questionloop; + return $self->processTemplate($self->getValue("responseTemplateId"),$var,"Survey/Response"); } #------------------------------------------------------------------- sub www_viewStatisticalOverview { - return "" unless (WebGUI::Privilege::isInGroup($_[0]->get("groupToViewReports"))); - my ($output, $p, $questions, $question, $sth, $answer, $totalResponses, $data); - $output = '

    '.WebGUI::International::get(58,$_[0]->get("namespace")).'

    '; - $output .= ''.WebGUI::International::get(73,$_[0]->get("namespace")).'

    '; - $p = WebGUI::Paginator->new(WebGUI::URL::page('func=viewStatisticalOverview&wid='.$_[0]->get("wobjectId"))); + my $self = shift; + return "" unless (WebGUI::Privilege::isInGroup($self->get("groupToViewReports"))); + my $var = $self->getMenuVars; + $var->{title} = WebGUI::International::get(58,$self->get("namespace")); + my $p = WebGUI::Paginator->new(WebGUI::URL::page('func=viewStatisticalOverview&wid='.$self->get("wobjectId"))); $p->setDataByQuery("select Survey_questionId,question,answerFieldType,allowComment from Survey_question - where Survey_id=".$_[0]->get("Survey_id")." order by sequenceNumber"); - $questions = $p->getPageData; - foreach $question (@$questions) { - $output .= ''.$question->{question}.''; + where Survey_id=".$self->get("Survey_id")." order by sequenceNumber"); + my $questions = $p->getPageData; + my @questionloop; + $var->{'answer.label'} = WebGUI::International::get(19,$self->get("namespace")); + $var->{'response.count.label'} = WebGUI::International::get(53,$self->get("namespace")); + $var->{'response.percent.label'} = WebGUI::International::get(54,$self->get("namespace")); + $var->{'show.responses.label'} = WebGUI::International::get(55,$self->get("namespace")); + $var->{'show.comments.label'} = WebGUI::International::get(56,$self->get("namespace")); + foreach my $question (@$questions) { + my @answerloop; + my ($totalResponses) = WebGUI::SQL->quickArray("select count(*) from Survey_questionResponse where Survey_questionId=".$question->{Survey_questionId}); if ($question->{answerFieldType} eq "radioList") { - $output .= ''; - $output .= ' - - '; - ($totalResponses) = WebGUI::SQL->quickArray("select count(*) from Survey_response - where Survey_questionId=".$question->{Survey_questionId}); - $sth = WebGUI::SQL->read("select Survey_answerId,answer,isCorrect from Survey_answer where + my $sth = WebGUI::SQL->read("select Survey_answerId,answer,isCorrect from Survey_answer where Survey_questionId=".$question->{Survey_questionId}." order by sequenceNumber"); - while ($answer = $sth->hashRef) { - if ($answer->{isCorrect}) { - $output .= ''; - } else { - $output .= ''; - } - $output .= ''; - ($data) = WebGUI::SQL->quickArray("select count(*) from Survey_response - where Survey_answerId=".$answer->{Survey_answerId}); - $output .= ''; - $output .= ''; - $output .= ''; + my @commentloop; + my $sth2 = WebGUI::SQL->read("select comment from Survey_questionResponse where Survey_answerId=".$answer->{Survey_answerId}); + while (my ($comment) = $sth2->array) { + push(@commentloop,{ + 'answer.comment'=>$comment + }); + } + $sth2->finish; + push(@answerloop,{ + 'answer.isCorrect'=>$answer->{isCorrect}, + 'answer' => $answer->{answer}, + 'answer.response.count' =>$numResponses, + 'answer.response.percent' =>$responsePercent, + 'comment_loop'=>\@commentloop + }); } $sth->finish; - $output .= "
    '.WebGUI::International::get(19,$_[0]->get("namespace")).''.WebGUI::International::get(53,$_[0]->get("namespace")).''.WebGUI::International::get(54,$_[0]->get("namespace")).'
    '.$answer->{answer}.''.$data.''; + while (my $answer = $sth->hashRef) { + my ($numResponses) = WebGUI::SQL->quickArray("select count(*) from Survey_questionResponse where Survey_answerId=".$answer->{Survey_answerId}); + my $responsePercent; if ($totalResponses) { - $output .= round(($data/$totalResponses)*100); + $responsePercent = round(($numResponses/$totalResponses)*100); } else { - $output .= '0'; + $responsePercent = 0; } - $output .= '
    "; } else { - $output .= '
    '.WebGUI::International::get(55,$_[0]->get("namespace")) - .'
    '; + my $sth = WebGUI::SQL->read("select response,comment from Survey_questionResponse where Survey_questionId=".$question->{Survey_questionId}); + while (my $response = $sth->hashRef) { + push(@answerloop,{ + 'answer.response'=>$response->{response}, + 'answer.comment'=>$response->{comment} + }); + } + $sth->finish; } - if ($question->{allowComment}) { - $output .= ''.WebGUI::International::get(56,$_[0]->get("namespace")).''; - } - $output .= '


    '; + push(@questionloop,{ + question=>$question->{question}, + 'question.id'=>$question->{Survey_questionId}, + 'question.isRadioList' => ($question->{answerFieldType} eq "radioList"), + 'question.response.total' => $totalResponses, + 'answer_loop'=>\@answerloop, + 'question.allowComment'=>$question->{allowComment} + }); } - $output .= $p->getBarTraditional; - return $_[0]->_submenu($output); + $var->{question_loop} = \@questionloop; + $p->appendTemplateVars($var); + return $self->processTemplate($self->getValue("overviewTemplateId"),$var,"Survey/Overview"); } 1;