Parent Directory
|
Revision Log
changed template escape handler functions to grab data from $r->urlpath instead of @_ for compatability with dispatch_new.
1 ################################################################################ 2 # WeBWorK Online Homework Delivery System 3 # Copyright © 2000-2003 The WeBWorK Project, http://openwebwork.sf.net/ 4 # $CVSHeader: webwork-modperl/lib/WeBWorK/ContentGenerator/Instructor/ProblemList.pm,v 1.16 2003/12/18 03:02:19 sh002i Exp $ 5 # 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 ################################################################################ 16 17 package WeBWorK::ContentGenerator::Instructor::ProblemList; 18 use base qw(WeBWorK::ContentGenerator::Instructor); 19 20 =head1 NAME 21 22 WeBWorK::ContentGenerator::Instructor::ProblemList - List and edit problems in a set 23 24 =cut 25 26 use strict; 27 use warnings; 28 use CGI qw(); 29 use WeBWorK::Utils qw(readDirectory list2hash max); 30 use WeBWorK::DB::Record::Set; 31 32 use constant PROBLEM_FIELDS =>[qw(source_file value max_attempts)]; 33 use constant PROBLEM_USER_FIELDS => [qw(problem_seed status num_correct num_incorrect)]; 34 35 sub problemElementHTML { 36 my ($fieldName, $fieldValue, $size, $override, $overrideValue) = @_; 37 my $attributeHash = {type=>"text",name=>$fieldName,value=>$fieldValue}; 38 $attributeHash->{size} = $size if defined $size; 39 my $html; 40 # my $html = CGI::input($attributeHash); 41 42 unless (defined $override) { 43 $html = CGI::input($attributeHash); 44 } else { 45 $html = $fieldValue; 46 $attributeHash->{name} = "${fieldName}.override"; 47 $attributeHash->{value} = ($override ? $overrideValue : ""); 48 $html = "default:".CGI::br().$html.CGI::br() 49 . CGI::checkbox({ 50 type => "checkbox", 51 name => "override", 52 label => "override:", 53 value => $fieldName, 54 checked => ($override ? 1 : 0) 55 }) 56 . CGI::br() 57 . CGI::input($attributeHash); 58 } 59 60 return $html; 61 } 62 63 # pay no attention to the argument list. Here's what you pass: 64 # directoryListHTML($level, $selected, $libraryRoot, @path) 65 sub directoryListHTML { 66 my ($level, $selected, @path) = @_; 67 $selected = [$selected] unless ref $selected eq "ARRAY"; 68 my $dirName = join "/", @path[0..$level]; 69 my $pathInLibrary = join "/", @path[1..$level]; 70 my @contents = sort grep {m/\.pg$/ or -d "$dirName/$_" and not m/^\.{1,2}$/} readDirectory($dirName); 71 my %contentsPretty = map {$pathInLibrary . "/" . $_ => (-d "$dirName/$_" ? "$_/" : $_)} @contents; 72 @contents = map {"$pathInLibrary/$_"} @contents; # Make the full path the actual values, so weird user behavior doesn't hurt. 73 @$selected = map {"$pathInLibrary/$_"} @$selected; 74 75 my $html = ($level eq "0" ? "problem library" : $path[$level]) . CGI::br(); 76 $html .= CGI::scrolling_list({ 77 name=>"directory_level_$level", 78 values=>\@contents, 79 labels=>\%contentsPretty, 80 default=>$selected, 81 multiple=>'true', 82 size=>"20", 83 }); 84 $html .= CGI::br() 85 . CGI::input({type=>"submit", name=>"open_add_$level", value=>"Open/Add"}); 86 } 87 88 sub initialize { 89 my ($self) = @_; 90 my $r = $self->{r}; 91 my $setName = $r->urlpath->arg("setID"); 92 my $db = $self->{db}; 93 my $ce = $self->{ce}; 94 my $authz = $self->{authz}; 95 my $user = $r->param('user'); 96 my $setRecord = $db->getGlobalSet($setName); # checked 97 die "global set $setName not found." unless $setRecord; 98 99 $self->{set} = $setRecord; 100 my @editForUser = $r->param('editForUser'); 101 # some useful booleans 102 my $forUsers = scalar(@editForUser); 103 my $forOneUser = $forUsers == 1; 104 105 unless ($authz->hasPermissions($user, "modify_problem_sets")) { 106 $self->{submitError} = "You are not authorized to modify problem sets"; 107 return; 108 } 109 110 # build a quick lookup table 111 my %overrides = list2hash $r->param('override'); 112 113 # the Problem form was submitted 114 if (defined($r->param('submit_problem_changes'))) { 115 my @problemList = $db->listGlobalProblems($setName); 116 foreach my $problem (@problemList) { 117 my $problemRecord = $db->getGlobalProblem($setName, $problem); # checked 118 die "global $problem for set $setName not found." unless $problemRecord; 119 foreach my $field (@{PROBLEM_FIELDS()}) { 120 my $paramName = "problem.${problem}.${field}"; 121 if (defined($r->param($paramName))) { 122 $problemRecord->$field($r->param($paramName)); 123 } 124 } 125 $db->putGlobalProblem($problemRecord); 126 127 if ($forOneUser) { 128 my $userProblemRecord = $db->getUserProblem($editForUser[0], $setName, $problem); # checked 129 die " problem $problem for set $setName and effective user $editForUser[0] not found" unless $userProblemRecord; 130 foreach my $field (@{PROBLEM_USER_FIELDS()}) { 131 my $paramName = "problem.${problem}.${field}"; 132 if (defined($r->param($paramName))) { 133 $userProblemRecord->$field($r->param($paramName)); 134 } 135 } 136 foreach my $field (@{PROBLEM_FIELDS()}) { 137 my $paramName = "problem.${problem}.${field}"; 138 if (defined($r->param("${paramName}.override"))) { 139 if (exists $overrides{$paramName}) { 140 $userProblemRecord->$field($r->param("${paramName}.override")); 141 } else { 142 $userProblemRecord->$field(undef); 143 } 144 145 } 146 } 147 $db->putUserProblem($userProblemRecord); 148 149 } 150 } 151 foreach my $problem ($r->param('deleteProblem')) { 152 $db->deleteGlobalProblem($setName, $problem); 153 } 154 # The file list field was submitted 155 } elsif (defined $r->param('fileBrowsing')) { 156 my $libraryRoot = $ce->{courseDirs}->{templates}; 157 my $count = 0; 158 my $done = 0; 159 my @path = (); 160 my $freeProblemID = max($db->listGlobalProblems($setName)) + 1; 161 162 while (defined $r->param("directory_level_$count") and not $done) { 163 if (defined $r->param("open_add_$count")) { 164 $done = 1; 165 my @selected = $r->param("directory_level_$count"); 166 my $dirFound = 0; 167 foreach my $selected (@selected) { 168 if (-d "$libraryRoot/$selected") { 169 @path = split "/", $selected; 170 shift @path if $path[0] eq ""; # remove the null element from the begining 171 $dirFound = 1; 172 last; 173 } 174 } 175 # Otherwise, create a new global problem for each of the files selected 176 unless ($dirFound) { 177 foreach my $selected (@selected) { 178 my $file = $selected; 179 @path = split "/", $selected; 180 pop @path; # Remove the file name from the path 181 shift @path if $path[0] eq ""; # remove the null element from the begining 182 my $problemRecord = $db->newGlobalProblem(); 183 $problemRecord->problem_id($freeProblemID++); 184 $problemRecord->set_id($setName); 185 $problemRecord->source_file($file); 186 $problemRecord->value("1"); 187 $problemRecord->max_attempts("-1"); 188 $db->addGlobalProblem($problemRecord); 189 $self->assignProblemToAllSetUsers($problemRecord); 190 } 191 192 } 193 } 194 $count++; 195 } 196 $self->{path} = [@path]; 197 } 198 199 } 200 201 sub path { 202 my $self = shift; 203 my $args = $_[-1]; 204 my $ce = $self->{ce}; 205 my $root = $ce->{webworkURLs}->{root}; 206 my $courseName = $ce->{courseName}; 207 my $set_id = $self->{set}->set_id; 208 return $self->pathMacro($args, 209 "Home" => "$root", 210 $courseName => "$root/$courseName", 211 'instructor' => "$root/$courseName/instructor", 212 'sets' => "$root/$courseName/instructor/sets/", 213 "set $set_id" => "$root/$courseName/instructor/sets/$set_id", 214 'problems' => '', 215 ); 216 } 217 218 sub title { 219 my ($self) = @_; 220 my $r = $self->{r}; 221 my $setName = $r->urlpath->arg("setID"); 222 return "Problems in ".$self->{ce}->{courseName}." : ".$setName; 223 } 224 225 sub body { 226 my ($self) = @_; 227 my $r = $self->{r}; 228 my $setName = $r->urlpath->arg("setID"); 229 my $db = $self->{db}; 230 my $ce = $self->{ce}; 231 my $authz = $self->{authz}; 232 my $user = $r->param('user'); 233 my $courseName = $ce->{courseName}; 234 my $setRecord = $db->getGlobalSet($setName); # checked 235 die "Global set $setName not found." unless $setRecord; 236 my @editForUser = $r->param('editForUser'); 237 # some useful booleans 238 my $forUsers = scalar(@editForUser); 239 my $forOneUser = $forUsers == 1; 240 241 return CGI::em("You are not authorized to access the Instructor tools.") unless $authz->hasPermissions($user, "access_instructor_tools"); 242 243 my $userCount = $db->listUsers(); 244 my $setUserCount = $db->countSetUsers($setName); 245 my $userCountMessage = "This set is assigned to " . $self->userCountMessage($setUserCount, $userCount) . "."; 246 247 if (@editForUser) { 248 print CGI::p("$userCountMessage Editing user-specific overrides for ". CGI::b(join ", ", @editForUser)); 249 } else { 250 print CGI::p($userCountMessage); 251 } 252 253 ## Problems Form ## 254 my @problemList = $db->listGlobalProblems($setName); 255 print CGI::a({name=>"problems"}); 256 print CGI::h2({}, "Problems"); 257 if (scalar(@problemList)) { 258 print CGI::start_form({method=>"POST", action=>$r->uri.'#problems'}); 259 print CGI::start_table({border=>1, cellpadding=>4}); 260 print CGI::Tr({}, CGI::th({}, [ 261 ($forUsers ? () : ("Delete?")), 262 "Problem", 263 ($forUsers ? ("Status", "Problem Seed") : ()), 264 "Source File", "Max. Attempts", "Weight", 265 ($forUsers ? ("Number Correct", "Number Incorrect") : ()) 266 ])); 267 foreach my $problem (sort {$a <=> $b} @problemList) { 268 my $problemRecord = $db->getGlobalProblem($setName, $problem); # checked 269 die "global problem $problem in set $setName not found." unless $problemRecord; 270 my $problemID = $problemRecord->problem_id; 271 my $userProblemRecord; 272 my %problemOverrideArgs; 273 274 if ($forOneUser) { 275 $userProblemRecord = $db->getUserProblem($editForUser[0], $setName, $problem); # checked 276 die "problem $problem for set $setName and user $editForUser[0] not found. " unless $userProblemRecord; 277 foreach my $field (@{PROBLEM_FIELDS()}) { 278 $problemOverrideArgs{$field} = [defined $userProblemRecord->$field, $userProblemRecord->$field]; 279 } 280 # } elsif ($forUsers) { 281 # foreach my $field (@{PROBLEM_FIELDS()}) { 282 # $problemOverrideArgs{$field} = ["", ""]; 283 # } 284 } else { 285 foreach my $field (@{PROBLEM_FIELDS()}) { 286 $problemOverrideArgs{$field} = [undef, undef]; 287 } 288 } 289 290 print CGI::Tr({}, 291 CGI::td({}, [ 292 ($forUsers ? () : (CGI::input({type=>"checkbox", name=>"deleteProblem", value=>$problemID}))), 293 "$problemID " 294 . CGI::a({href=>$ce->{webworkURLs}->{root}."/$courseName/".$setName.'/'.$problemID.'?'.$self->url_authen_args}, "view") 295 . " " 296 . CGI::a({href=>$ce->{webworkURLs}->{root}."/$courseName/instructor/pgProblemEditor/".$setName.'/'.$problemID.'?'.$self->url_authen_args}, "edit") 297 , 298 ($forUsers ? ( 299 problemElementHTML("problem.${problemID}.status", $userProblemRecord->status, "7"), 300 problemElementHTML("problem.${problemID}.problem_seed", $userProblemRecord->problem_seed, "7"), 301 ) : ()), 302 problemElementHTML("problem.${problemID}.source_file", $problemRecord->source_file, "40", @{$problemOverrideArgs{source_file}}), 303 problemElementHTML("problem.${problemID}.max_attempts",$problemRecord->max_attempts,"7", @{$problemOverrideArgs{max_attempts}}), 304 problemElementHTML("problem.${problemID}.value",$problemRecord->value,"7", @{$problemOverrideArgs{value}}), 305 ($forUsers ? ( 306 problemElementHTML("problem.${problemID}.num_correct", $userProblemRecord->num_correct, "7"), 307 problemElementHTML("problem.${problemID}.num_incorrect", $userProblemRecord->num_incorrect, "7") 308 ) : ()) 309 ]) 310 311 ) 312 } 313 print CGI::end_table(); 314 print $self->hiddenEditForUserFields(@editForUser); 315 print $self->hidden_authen_fields; 316 print CGI::input({type=>"submit", name=>"submit_problem_changes", value=>"Save Problem Changes"}); 317 print CGI::end_form(); 318 } else { 319 print CGI::p("This set doesn't contain any problems yet."); 320 } 321 322 unless ($forUsers) { 323 my $libraryRoot = $ce->{courseDirs}->{templates}; 324 my @path = defined $self->{path} ? @{$self->{path}} : (); 325 unshift @path, $libraryRoot; 326 print CGI::a({name=>"addProblem"}); 327 print CGI::h3({}, "Add Problem(s)"); 328 print CGI::start_form({method=>"post", action=>$r->uri.'#addProblem'}); 329 print CGI::input({type=>"hidden", name=>"fileBrowsing", value=>"Yes"}); 330 print CGI::start_table(); 331 my $columns = ""; 332 for (my $counter = 0; $counter < scalar(@path); $counter++) { 333 $columns .= CGI::td(directoryListHTML ($counter, (exists $path[$counter+1] ? $path[$counter+1] : []), @path)); 334 } 335 print CGI::Tr($columns); 336 print CGI::end_table(); 337 print $self->hidden_authen_fields; 338 print CGI::end_form(); 339 } 340 341 return ""; 342 } 343 344 1;
| aubreyja at gmail dot com | ViewVC Help |
| Powered by ViewVC 1.0.9 |