[system] / trunk / webwork2 / lib / WeBWorK / ContentGenerator / ProblemSets.pm Repository:
ViewVC logotype

Annotation of /trunk/webwork2/lib/WeBWorK/ContentGenerator/ProblemSets.pm

Parent Directory Parent Directory | Revision Log Revision Log


Revision 7053 - (view) (download) (as text)

1 : sh002i 455 ################################################################################
2 : sh002i 1663 # WeBWorK Online Homework Delivery System
3 : sh002i 5319 # Copyright 2000-2007 The WeBWorK Project, http://openwebwork.sf.net/
4 : glarose 6282 # $CVSHeader: webwork2/lib/WeBWorK/ContentGenerator/ProblemSets.pm,v 1.94 2010/01/31 02:31:04 apizer Exp $
5 : sh002i 1663 #
6 :     # This program is free software; you can redistribute it and/or modify it under
7 :     # the terms of either: (a) the GNU General Public License as published by the
8 :     # Free Software Foundation; either version 2, or (at your option) any later
9 :     # version, or (b) the "Artistic License" which comes with this package.
10 :     #
11 :     # This program is distributed in the hope that it will be useful, but WITHOUT
12 :     # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13 :     # FOR A PARTICULAR PURPOSE. See either the GNU General Public License or the
14 :     # Artistic License for more details.
15 : sh002i 455 ################################################################################
16 :    
17 : malsyned 353 package WeBWorK::ContentGenerator::ProblemSets;
18 : gage 7023 use base qw(WeBWorK);
19 : sh002i 818 use base qw(WeBWorK::ContentGenerator);
20 : malsyned 353
21 : sh002i 455 =head1 NAME
22 :    
23 :     WeBWorK::ContentGenerator::ProblemSets - Display a list of built problem sets.
24 :    
25 :     =cut
26 :    
27 : malsyned 441 use strict;
28 :     use warnings;
29 : gage 4230 #use CGI qw(-nosticky );
30 :     use WeBWorK::CGI;
31 : sh002i 3485 use WeBWorK::Debug;
32 : sh002i 4015 use WeBWorK::Utils qw(readFile sortByName path_is_subdir);
33 : gage 6936 use WeBWorK::Localize;
34 : sh002i 2498 # what do we consider a "recent" problem set?
35 :     use constant RECENT => 2*7*24*60*60 ; # Two-Weeks in seconds
36 :    
37 : sh002i 1903 sub info {
38 :     my ($self) = @_;
39 :     my $r = $self->r;
40 :     my $ce = $r->ce;
41 :     my $db = $r->db;
42 :     my $urlpath = $r->urlpath;
43 : toenail 2398 my $authz = $r->authz;
44 : sh002i 1903
45 :     my $courseID = $urlpath->arg("courseID");
46 : toenail 2398 my $user = $r->param("user");
47 : sh002i 1903
48 :     my $course_info = $ce->{courseFiles}->{course_info};
49 :    
50 :     if (defined $course_info and $course_info) {
51 :     my $course_info_path = $ce->{courseDirs}->{templates} . "/$course_info";
52 :    
53 : gage 7023 print CGI::start_div({-class=>"info-wrapper"});
54 : sh002i 3943 print CGI::start_div({class=>"info-box", id=>"InfoPanel"});
55 : sh002i 3925
56 : sh002i 1903 # deal with instructor crap
57 : sh002i 3925 my $editorURL;
58 : toenail 2398 if ($authz->hasPermissions($user, "access_instructor_tools")) {
59 : sh002i 1903 if (defined $r->param("editMode") and $r->param("editMode") eq "temporaryFile") {
60 : gage 3888 $course_info_path = $r->param("sourceFilePath");
61 : dpvc 4159 $course_info_path = $ce->{courseDirs}{templates}.'/'.$course_info_path unless $course_info_path =~ m!^/!;
62 : sh002i 4015 die "sourceFilePath is unsafe!" unless path_is_subdir($course_info_path, $ce->{courseDirs}->{templates});
63 : gage 6936 $self->addmessage(CGI::div({class=>'temporaryFile'}, $r->maketext("Viewing temporary file: "), $course_info_path));
64 : sh002i 1903 }
65 :    
66 : gage 6936 my $editorPage = $urlpath->newFromModule("WeBWorK::ContentGenerator::Instructor::PGProblemEditor", $r, courseID => $courseID);
67 : sh002i 3925 $editorURL = $self->systemLink($editorPage, params => { file_type => "course_info" });
68 : sh002i 1903 }
69 : sh002i 3925
70 : sh002i 4021 if ($editorURL) {
71 : gage 6936 print CGI::h2($r->maketext("Course Info"), CGI::a({href=>$editorURL, target=>"WW_Editor"}, $r->maketext("~[edit~]")));
72 : sh002i 4021 } else {
73 : gage 6936 print CGI::h2($r->maketext("Course Info"));
74 : sh002i 4021 }
75 :    
76 : gage 3035 if (-f $course_info_path) { #check that it's a plain file
77 : sh002i 1903 my $text = eval { readFile($course_info_path) };
78 :     if ($@) {
79 :     print CGI::div({class=>"ResultsWithError"},
80 :     CGI::p("$@"),
81 :     );
82 :     } else {
83 :     print $text;
84 :     }
85 :     }
86 : sh002i 3925
87 : sh002i 3943 print CGI::end_div();
88 : gage 7023 print CGI::end_div();
89 : sh002i 3943
90 : sh002i 1903 return "";
91 :     }
92 :     }
93 : gage 2480 sub help { # non-standard help, since the file path includes the course name
94 :     my $self = shift;
95 :     my $args = shift;
96 :     my $name = $args->{name};
97 :     $name = lc('course home') unless defined($name);
98 :     $name =~ s/\s/_/g;
99 :     $self->helpMacro($name);
100 :     }
101 : gage 3035 sub initialize {
102 :    
103 :    
104 :    
105 :     # get result and send to message
106 :     my ($self) = @_;
107 :     my $r = $self->r;
108 :     my $authz = $r->authz;
109 :     my $urlpath = $r->urlpath;
110 :    
111 :     my $user = $r->param("user");
112 :     my $effectiveUser = $r->param("effectiveUser");
113 :     if ($authz->hasPermissions($user, "access_instructor_tools")) {
114 :     # get result and send to message
115 :     my $status_message = $r->param("status_message");
116 :     $self->addmessage(CGI::p("$status_message")) if $status_message;
117 :    
118 :    
119 :     }
120 :     }
121 : malsyned 353 sub body {
122 : sh002i 1903 my ($self) = @_;
123 :     my $r = $self->r;
124 :     my $ce = $r->ce;
125 :     my $db = $r->db;
126 : toenail 2398 my $authz = $r->authz;
127 : sh002i 1903 my $urlpath = $r->urlpath;
128 :    
129 : gage 1722 my $user = $r->param("user");
130 :     my $effectiveUser = $r->param("effectiveUser");
131 :     my $sort = $r->param("sort") || "status";
132 : sh002i 1903
133 :     my $courseName = $urlpath->arg("courseID");
134 :    
135 : gage 6936 my $hardcopyPage = $urlpath->newFromModule("WeBWorK::ContentGenerator::Hardcopy", $r, courseID => $courseName);
136 : sh002i 1903 my $actionURL = $self->systemLink($hardcopyPage, authen => 0); # no authen info for form action
137 : sh002i 683
138 : glarose 3851 # we have to get sets and versioned sets separately
139 : sh002i 4518 # DBFIXME don't get ID lists, use WHERE clauses and iterators
140 : sh002i 1229 my @setIDs = $db->listUserSets($effectiveUser);
141 : sh002i 1650 my @userSetIDs = map {[$effectiveUser, $_]} @setIDs;
142 : glarose 4804
143 : sh002i 3485 debug("Begin collecting merged sets");
144 : sh002i 1650 my @sets = $db->getMergedSets( @userSetIDs );
145 : glarose 5507
146 : sh002i 3485 debug("Begin fixing merged sets");
147 : sh002i 2738
148 : gage 6775 # Database fix (in case of undefined visible values)
149 : sh002i 2738 # this may take some extra time the first time but should NEVER need to be run twice
150 : gage 6775 # this is only necessary because some people keep holding to ww1.9 which did not have a visible field
151 : sh002i 4518 # DBFIXME this should be in the database layer (along with other "fixes" of its ilk)
152 : sh002i 2738 foreach my $set (@sets) {
153 : gage 6775 # make sure visible is set to 0 or 1
154 :     if ( $set and $set->visible ne "0" and $set->visible ne "1") {
155 : sh002i 2738 my $globalSet = $db->getGlobalSet($set->set_id);
156 : gage 6775 $globalSet->visible("1"); # defaults to visible
157 : sh002i 2738 $db->putGlobalSet($globalSet);
158 :     $set = $db->getMergedSet($effectiveUser, $set->set_id);
159 :     } else {
160 :     die "set $set not defined" unless $set;
161 :     }
162 :     }
163 : glarose 3377
164 : apizer 6158 foreach my $set (@sets) {
165 :     # make sure enable_reduced_scoring is set to 0 or 1
166 :     if ( $set and $set->enable_reduced_scoring ne "0" and $set->enable_reduced_scoring ne "1") {
167 :     my $globalSet = $db->getGlobalSet($set->set_id);
168 :     $globalSet->enable_reduced_scoring("0"); # defaults to disabled
169 :     $db->putGlobalSet($globalSet);
170 :     $set = $db->getMergedSet($effectiveUser, $set->set_id);
171 :     } else {
172 :     die "set $set not defined" unless $set;
173 :     }
174 :     }
175 :    
176 : glarose 3377 # gateways/versioned sets require dealing with output data slightly
177 :     # differently, so check for those here
178 : sh002i 3485 debug("Begin set-type check");
179 : glarose 3377 my $existVersions = 0;
180 : glarose 3851 my @gwSets = ();
181 :     my @nonGWsets = ();
182 : glarose 5507 my %gwSetNames = (); # this is necessary because we get a setname
183 :     # for all versions of g/w tests
184 : glarose 3377 foreach ( @sets ) {
185 :     if ( defined( $_->assignment_type() ) &&
186 :     $_->assignment_type() =~ /gateway/ ) {
187 :     $existVersions = 1;
188 : glarose 5507
189 :     push( @gwSets, $_ ) if ( ! defined($gwSetNames{$_->set_id}) );
190 :     $gwSetNames{$_->set_id} = 1;
191 : glarose 3851 } else {
192 :     push( @nonGWsets, $_ );
193 : glarose 3377 }
194 :     }
195 : glarose 4838 # now get all user set versions that we need
196 : glarose 4804 my @vSets = ();
197 : glarose 4864 # we need the template sets below, so also make an indexed list of those
198 :     my %gwSetsBySetID = ();
199 : glarose 4804 foreach my $set ( @gwSets ) {
200 : glarose 4864 $gwSetsBySetID{$set->set_id} = $set;
201 :    
202 :     my @setVer = $db->listSetVersions( $effectiveUser, $set->set_id );
203 :     my @setVerIDs = map { [ $effectiveUser, $set->set_id, $_ ] } @setVer;
204 :     push( @vSets, $db->getMergedSetVersions( @setVerIDs ) );
205 : glarose 4804 }
206 : glarose 3851
207 :     # set sort method
208 : glarose 3377 $sort = "status" unless $sort eq "status" or $sort eq "name";
209 :    
210 :     # now set the headers for the table
211 :     my $nameHeader = $sort eq "name"
212 : gage 6936 ? CGI::u($r->maketext("Name"))
213 :     : CGI::a({href=>$self->systemLink($urlpath, params=>{sort=>"name"})}, $r->maketext("Name"));
214 : glarose 3377 my $statusHeader = $sort eq "status"
215 : gage 6936 ? CGI::u($r->maketext("Status"))
216 :     : CGI::a({href=>$self->systemLink($urlpath, params=>{sort=>"status"})}, $r->maketext("Status"));
217 : gage 3416 # print the start of the form
218 : glarose 3377
219 : gage 3416 print CGI::start_form(-method=>"POST",-action=>$actionURL),
220 :     $self->hidden_authen_fields;
221 :    
222 : gage 7053 # and send the start of the table
223 : gage 7023 # UPDATE - ghe3
224 :     # This table now contains a summary and a caption, scope attributes for the column headers, and no longer prints a column for 'Sel.' (due to it having been merged with the second column for accessibility purposes).
225 :     print CGI::start_table({-summary=>"This table lists out the available homework sets for this class, along with its current status. Click on the link on the name of the homework sets to take you to the problems in that homework set. Clicking on the links in the table headings will sort the table by the field it corresponds to. You can also select sets for download to PDF or TeX format using the radio buttons or checkboxes next to the problem set names, and then clicking on the 'Download PDF or TeX Hardcopy for Selected Sets' button at the end of the table. There is also a clear button and an Email instructor button at the end of the table.", -class=>"problem_set_table"});
226 :     print CGI::caption($r->maketext("Homework Sets"));
227 : glarose 3377 if ( ! $existVersions ) {
228 : gage 4259 print CGI::Tr({},
229 : gage 7023 CGI::th({-scope=>"col"},$nameHeader),
230 :     CGI::th({-scope=>"col"},$statusHeader),
231 : glarose 3377 );
232 :     } else {
233 :     print CGI::Tr(
234 : gage 7023 CGI::th({-scope=>"col"},$nameHeader),
235 :     CGI::th({-scope=>"col"},$r->maketext("Test Score")),
236 :     CGI::th({-scope=>"col"},$r->maketext("Test Date")),
237 :     CGI::th({-scope=>"col"},$statusHeader),
238 : glarose 3377 );
239 :     }
240 :    
241 : sh002i 3485 debug("Begin sorting merged sets");
242 : glarose 5507
243 :     # before building final set lists, exclude proctored gateway sets
244 :     # for users without permission to view them
245 :     my $viewPr = $authz->hasPermissions( $user, "view_proctored_tests" );
246 :     @gwSets = grep {$_->assignment_type !~ /proctored/ || $viewPr} @gwSets;
247 : sh002i 1229
248 : glarose 3851 if ( $sort eq 'name' ) {
249 :     @nonGWsets = sortByName("set_id", @nonGWsets);
250 :     @gwSets = sortByName("set_id", @gwSets);
251 :     } elsif ( $sort eq 'status' ) {
252 :     @nonGWsets = sort byUrgency @nonGWsets;
253 :     @gwSets = sort byUrgency @gwSets;
254 :     }
255 : glarose 4864 # we sort set versions by name
256 : glarose 4838 @vSets = sortByName(["set_id", "version_id"], @vSets);
257 : glarose 3851
258 :     # put together a complete list of sorted sets to consider
259 : glarose 4804 @sets = (@nonGWsets, @gwSets );
260 : sh002i 2498
261 : sh002i 3485 debug("End preparing merged sets");
262 : glarose 4804
263 :     # we do regular sets and the gateway set templates separately
264 :     # from the actual set-versions, to avoid managing a tricky test
265 :     # for a version number that may not exist
266 : sh002i 683 foreach my $set (@sets) {
267 : gage 1667 die "set $set not defined" unless $set;
268 : gage 2178
269 : gage 6775 if ($set->visible || $authz->hasPermissions($user, "view_hidden_sets")) {
270 : glarose 3377 print $self->setListRow($set, $authz->hasPermissions($user, "view_multiple_sets"), $authz->hasPermissions($user, "view_unopened_sets"),$existVersions,$db);
271 : toenail 2097 }
272 : sh002i 449 }
273 : glarose 4804 foreach my $set (@vSets) {
274 :     die "set $set not defined" unless $set;
275 :    
276 : gage 6775 if ($set->visible || $authz->hasPermissions($user, "view_hidden_sets")) {
277 : gage 7023 print $self->setListRow($set, $authz->hasPermissions($user, "view_multiple_sets"), $authz->hasPermissions($user, "view_unopened_sets"),$existVersions,$db,1, $gwSetsBySetID{$set->{set_id}}, "ethet" ); # 1 = gateway, versioned set
278 : glarose 4804 }
279 :     }
280 : malsyned 441
281 : sh002i 449 print CGI::end_table();
282 : gage 7023 my $pl = ($authz->hasPermissions($user, "view_multiple_sets") ? "s" : "");
283 :     # print CGI::p(CGI::submit(-name=>"hardcopy", -label=>$r->maketext("Download Hardcopy for Selected [plural,_1,Set,Sets]",$pl)));
284 :    
285 :     # UPDATE - ghe3
286 :     # Added reset button to form.
287 : gage 7053 print CGI::start_div({-class=>"problem_set_options"});
288 : gage 7023 print CGI::p(WeBWorK::CGI_labeled_input(-type=>"reset", -input_attr=>{-value=>$r->maketext("Clear")}));
289 :     print CGI::p(WeBWorK::CGI_labeled_input(-type=>"submit", -input_attr=>{-name=>"hardcopy", -value=>$r->maketext("Download PDF or TeX Hardcopy for Selected Sets")}));
290 : sh002i 449 print CGI::endform();
291 : malsyned 441
292 : sh002i 3625 ## feedback form url
293 : gage 6936 #my $feedbackPage = $urlpath->newFromModule("WeBWorK::ContentGenerator::Feedback", $r, courseID => $courseName);
294 : sh002i 3625 #my $feedbackURL = $self->systemLink($feedbackPage, authen => 0); # no authen info for form action
295 :     #
296 :     ##print feedback form
297 :     #print
298 :     # CGI::start_form(-method=>"POST", -action=>$feedbackURL),"\n",
299 :     # $self->hidden_authen_fields,"\n",
300 :     # CGI::hidden("module", __PACKAGE__),"\n",
301 :     # CGI::hidden("set", ''),"\n",
302 :     # CGI::hidden("problem", ''),"\n",
303 :     # CGI::hidden("displayMode", ''),"\n",
304 :     # CGI::hidden("showOldAnswers", ''),"\n",
305 :     # CGI::hidden("showCorrectAnswers", ''),"\n",
306 :     # CGI::hidden("showHints", ''),"\n",
307 :     # CGI::hidden("showSolutions", ''),"\n",
308 :     # CGI::p({-align=>"left"},
309 :     # CGI::submit(-name=>"feedbackForm", -label=>"Email instructor")
310 :     # ),
311 :     # CGI::endform(),"\n";
312 : gage 1500
313 : sh002i 3625 print $self->feedbackMacro(
314 :     module => __PACKAGE__,
315 :     set => "",
316 :     problem => "",
317 :     displayMode => "",
318 :     showOldAnswers => "",
319 :     showCorrectAnswers => "",
320 :     showHints => "",
321 :     showSolutions => "",
322 :     );
323 : gage 7053 print CGI::end_div();
324 : sh002i 669
325 : sh002i 449 return "";
326 : malsyned 353 }
327 :    
328 : gage 7023 # UPDATE - ghe3
329 :     # this subroutine now combines the $control and $interactive elements, by using the $interactive element as the $control element's label.
330 :    
331 : sh002i 1903 sub setListRow {
332 : glarose 4804 my ($self, $set, $multiSet, $preOpenSets, $existVersions, $db,
333 : glarose 4864 $gwtype, $tmplSet) = @_;
334 : sh002i 1903 my $r = $self->r;
335 :     my $ce = $r->ce;
336 : glarose 4872 my $authz = $r->authz;
337 :     my $user = $r->param("user");
338 : sh002i 1903 my $urlpath = $r->urlpath;
339 : glarose 4804 $gwtype = 0 if ( ! defined( $gwtype ) );
340 : glarose 4864 $tmplSet = $set if ( ! defined( $tmplSet ) );
341 : sh002i 449
342 : gage 1489 my $name = $set->set_id;
343 : glarose 4804 my $urlname = ( $gwtype == 1 ) ? "$name,v" . $set->version_id : $name;
344 :    
345 : sh002i 1903 my $courseName = $urlpath->arg("courseID");
346 : sh002i 469
347 : glarose 3377 my $problemSetPage;
348 :    
349 :     if ( ! defined( $set->assignment_type() ) ||
350 :     $set->assignment_type() !~ /gateway/ ) {
351 : gage 6936 $problemSetPage = $urlpath->newFromModule("WeBWorK::ContentGenerator::ProblemSet", $r,
352 : glarose 4804 courseID => $courseName, setID => $urlname);
353 : glarose 3377 } elsif( $set->assignment_type() !~ /proctored/ ) {
354 :    
355 : gage 6936 $problemSetPage = $urlpath->newFromModule("WeBWorK::ContentGenerator::GatewayQuiz", $r,
356 : glarose 4804 courseID => $courseName, setID => $urlname);
357 : glarose 3377 } else {
358 :    
359 : gage 6936 $problemSetPage = $urlpath->newFromModule("WeBWorK::ContentGenerator::GatewayQuiz", $r,
360 : glarose 4804 courseID => $courseName, setID => $urlname);
361 : glarose 3377 }
362 :    
363 : gage 3000 my $interactiveURL = $self->systemLink($problemSetPage,
364 :     params=>{ displayMode => $self->{displayMode},
365 :     showOldAnswers => $self->{will}->{showOldAnswers}
366 :     }
367 :     );
368 : glarose 4309
369 : glarose 4804 # check to see if this is a template gateway assignment
370 :     $gwtype = 2 if ( defined( $set->assignment_type() ) &&
371 :     $set->assignment_type() =~ /gateway/ && ! $gwtype );
372 :     # and get problemRecords if we're dealing with a versioned set, so that
373 :     # we can test status and scores
374 :     # FIXME: should we really have to get the merged
375 :     # problem_versions here? it looks that way, because
376 :     # otherwise we don't inherit things like the problem
377 :     # value properly.
378 :     my @problemRecords =
379 :     $db->getAllProblemVersions($set->user_id(), $set->set_id(),
380 :     $set->version_id())
381 :     if ( $gwtype == 1 );
382 :    
383 : glarose 3377 # the conditional here should be redundant. ah well.
384 :     $interactiveURL =~ s|/quiz_mode/|/proctored_quiz_mode/| if
385 :     ( defined( $set->assignment_type() ) &&
386 :     $set->assignment_type() eq 'proctored_gateway' );
387 : sh002i 1903
388 : gage 7023 $name =~ s/_/ /g;
389 :     # this is the link to the homework assignment
390 :     my $interactive = CGI::a({-href=>$interactiveURL}, "$name");
391 :    
392 : sh002i 737 my $control = "";
393 :    
394 : glarose 4838 my $setIsOpen = 0;
395 :     my $status = '';
396 : glarose 4309 if ( $gwtype ) {
397 : glarose 4804 if ( $gwtype == 1 ) {
398 : gage 6458 unless (ref($problemRecords[0]) ) {warn "Error: problem not defined in set $name"; return()}
399 : glarose 4804 if ( $problemRecords[0]->num_correct() +
400 :     $problemRecords[0]->num_incorrect() >=
401 : gage 7053 ( ( !($set->attempts_per_version()) ) ? 0 : $set->attempts_per_version() ) ) {
402 : gage 6936 $status = $r->maketext("completed.");
403 : glarose 5326 } elsif ( time() > $set->due_date() +
404 : glarose 4804 $self->r->ce->{gatewayGracePeriod} ) {
405 : gage 6936 $status = $r->maketext("over time: closed.");
406 : glarose 4804 } else {
407 : gage 6936 $status = $r->maketext("open: complete by [_1]",
408 :     $self->formatDateTime($set->due_date()));
409 : glarose 4804 }
410 : glarose 4838 # we let people go back to old tests
411 :     $setIsOpen = 1;
412 : glarose 4804
413 : glarose 5723 # reset the link to give the test number
414 :     my $vnum = $set->version_id;
415 :     $interactive = CGI::a({-href=>$interactiveURL},
416 : gage 7023 $r->maketext("[_1] (test [_2])", $name, $vnum));
417 : glarose 5723 } else {
418 : glarose 4804 my $t = time();
419 :     if ( $t < $set->open_date() ) {
420 : gage 6936 $status = $r->maketext("will open on [_1]", $self->formatDateTime($set->open_date));
421 : glarose 5723 if ( $preOpenSets ) {
422 :     # reset the link
423 :     $interactive = CGI::a({-href=>$interactiveURL},
424 : gage 7023 $r->maketext("Take [_1] test", $name));
425 : glarose 5723 } else {
426 :     $control = "";
427 : gage 7023 $interactive = $r->maketext("[_1] test", $name);
428 : glarose 5723 }
429 : glarose 4804 } elsif ( $t < $set->due_date() ) {
430 : gage 6936 $status = $r->maketext("now open, due ") . $self->formatDateTime($set->due_date);
431 : glarose 4838 $setIsOpen = 1;
432 : glarose 5723 $interactive = CGI::a({-href=>$interactiveURL},
433 : gage 7023 $r->maketext("Take [_1] test", $name));
434 : glarose 4804 } else {
435 : gage 7023 $status = $r->maketext("Closed");
436 : glarose 5723
437 :     if ( $authz->hasPermissions( $user, "record_answers_after_due_date" ) ) {
438 :     $interactive = CGI::a({-href=>$interactiveURL},
439 : gage 7023 $r->maketext("Take [_1] test", $name));
440 : glarose 5723 } else {
441 : gage 7023 $interactive = $r->maketext("[_1] test", $name);
442 : glarose 5723 }
443 : glarose 4804 }
444 : glarose 3377 }
445 : glarose 4804
446 : glarose 3377 # old conditional
447 :     } elsif (time < $set->open_date) {
448 : gage 6936 $status = $r->maketext("will open on [_1]", $self->formatDateTime($set->open_date));
449 : sh002i 739 $control = "" unless $preOpenSets;
450 :     $interactive = $name unless $preOpenSets;
451 : sh002i 449 } elsif (time < $set->due_date) {
452 : gage 6936 $status = $r->maketext("now open, due ") . $self->formatDateTime($set->due_date);
453 : apizer 6193 my $enable_reduced_scoring = $set->enable_reduced_scoring;
454 :     my $reducedScoringPeriod = $ce->{pg}->{ansEvalDefaults}->{reducedScoringPeriod};
455 :     if ($reducedScoringPeriod > 0 and $enable_reduced_scoring ) {
456 :     my $reducedScoringPeriodSec = $reducedScoringPeriod*60; # $reducedScoringPeriod is in minutes
457 :     my $beginReducedScoringPeriod = $self->formatDateTime($set->due_date() - $reducedScoringPeriodSec);
458 :     # $status .= '. <FONT COLOR="#cc6600">Reduced Credit starts ' . $beginReducedScoringPeriod . '</FONT>';
459 : gage 7023 $status .= CGI::div({-class=>"ResultsAlert"}, $r->maketext("Reduced Credit Starts: [_1]", $beginReducedScoringPeriod));
460 : apizer 6193
461 :     }
462 : glarose 4838 $setIsOpen = 1;
463 : sh002i 449 } elsif (time < $set->answer_date) {
464 : gage 6936 $status = $r->maketext("closed, answers on [_1]", $self->formatDateTime($set->answer_date));
465 : sh002i 2498 } elsif ($set->answer_date <= time and time < $set->answer_date +RECENT ) {
466 : gage 6936 $status = $r->maketext("closed, answers recently available");
467 : sh002i 449 } else {
468 : gage 6936 $status = $r->maketext("closed, answers available");
469 : sh002i 449 }
470 : gage 7053
471 :     if ($multiSet) {
472 :     if ( $gwtype < 2 ) {
473 :     $control = WeBWorK::CGI_labeled_input(
474 :     -type=>"checkbox",
475 :     -id=>$name . ($gwtype ? ",v" . $set->version_id : ''),
476 :     -label_text=>$interactive,
477 :     -input_attr=>{
478 :     -name=>"selected_sets",
479 :     -value=>$name . ($gwtype ? ",v" . $set->version_id : '')
480 :     }
481 :     );
482 :     } else {
483 :     $control = $interactive;
484 :     }
485 :     } else {
486 :     if ( $gwtype < 2 ) {
487 :     my $n = $name . ($gwtype ? ",v" . $set->version_id : '');
488 :     $control = WeBWorK::CGI_labeled_input(
489 :     -type=>"radio",
490 :     -id=>$n,
491 :     -label_text=>$interactive,
492 :     -input_attr=>{
493 :     -name=>"selected_sets",
494 :     -value=>$n
495 :     }
496 :     );
497 :     } else {
498 :     $control = $interactive;
499 :     }
500 :     }
501 : glarose 4838
502 : gage 6775 my $visiblityStateClass = ($set->visible) ? "visible" : "hidden";
503 : toenail 2097
504 : gage 6775 $status = CGI::font({class=>$visiblityStateClass}, $status) if $preOpenSets;
505 : toenail 2097
506 : glarose 3377 # check to see if we need to return a score and a date column
507 :     if ( ! $existVersions ) {
508 :     return CGI::Tr(CGI::td([
509 :     $control,
510 :     $status,
511 :     ]));
512 :     } else {
513 : glarose 5723 my ( $startTime, $score );
514 : glarose 3377
515 : jj 3542 if ( defined( $set->assignment_type() ) &&
516 : glarose 4804 $set->assignment_type() =~ /gateway/ && $gwtype == 1 ) {
517 : gage 6405 $startTime = localtime($set->version_creation_time() || 0); #fixes error message for undefined creation_time
518 : glarose 3377
519 : glarose 4872 if ( $authz->hasPermissions($user, "view_hidden_work") ||
520 : glarose 4921 $set->hide_score_by_problem eq 'Y' ||
521 :     $set->hide_score() eq 'N' ||
522 :     ( $set->hide_score eq 'BeforeAnswerDate' && time > $tmplSet->answer_date() ) ) {
523 :     # find score
524 : glarose 4804
525 : sh002i 4518 # DBFIXME we can do this math in the database, i think
526 : glarose 4692 my $possible = 0;
527 :     $score = 0;
528 :     foreach my $pRec ( @problemRecords ) {
529 : glarose 6282 my $pval = $pRec->value() ? $pRec->value() : 1;
530 : glarose 4692 if ( defined( $pRec ) &&
531 :     $score ne 'undef' ) {
532 : glarose 6282 $score += $pRec->status()*$pval || 0;
533 : glarose 4692 } else {
534 :     $score = 'undef';
535 :     }
536 : glarose 6282 $possible += $pval;
537 : jj 3542 }
538 : glarose 4692 $score = "$score/$possible";
539 :     } else {
540 :     $score = "n/a";
541 : jj 3542 }
542 :     } else {
543 :     $startTime = '&nbsp;';
544 :     $score = $startTime;
545 : glarose 3377 }
546 : jj 3542 return CGI::Tr(CGI::td([
547 :     $control,
548 :     $score,
549 :     $startTime,
550 :     $status,
551 :     ]));
552 : glarose 3377 }
553 : sh002i 449 }
554 : sh002i 1903
555 : sh002i 919 sub byname { $a->set_id cmp $b->set_id; }
556 : sh002i 683
557 : sh002i 2498 sub byUrgency {
558 :     my $mytime = time;
559 :     my @a_parts = ($a->answer_date + RECENT <= $mytime) ? (4, $a->open_date, $a->due_date, $a->set_id)
560 :     : ($a->answer_date <= $mytime and $mytime < $a->answer_date + RECENT) ? (3, $a-> answer_date, $a-> due_date, $a->set_id)
561 :     : ($a->due_date <= $mytime and $mytime < $a->answer_date ) ? (2, $a->answer_date, $a->due_date, $a->set_id)
562 :     : ($mytime < $a->open_date) ? (1, $a->open_date, $a->due_date, $a->set_id)
563 :     : (0, $a->due_date, $a->open_date, $a->set_id);
564 :     my @b_parts = ($b->answer_date + RECENT <= $mytime) ? (4, $b->open_date, $b->due_date, $b->set_id)
565 :     : ($b->answer_date <= $mytime and $mytime < $b->answer_date + RECENT) ? (3, $b-> answer_date, $b-> due_date, $b->set_id)
566 :     : ($b->due_date <= $mytime and $mytime < $b->answer_date ) ? (2, $b->answer_date, $b->due_date, $b->set_id)
567 :     : ($mytime < $b->open_date) ? (1, $b->open_date, $b->due_date, $b->set_id)
568 :     : (0, $b->due_date, $b->open_date, $b->set_id);
569 :     my $returnIt=0;
570 :     while (scalar(@a_parts) > 1) {
571 :     if ($returnIt = ( (shift @a_parts) <=> (shift @b_parts) ) ) {
572 :     return($returnIt);
573 :     }
574 :     }
575 :     return ( $a_parts[0] cmp $b_parts[0] );
576 :     }
577 :    
578 : malsyned 353 1;

aubreyja at gmail dot com
ViewVC Help
Powered by ViewVC 1.0.9