| … | |
… | |
| 120 | } |
120 | } |
| 121 | |
121 | |
| 122 | |
122 | |
| 123 | ############# List of sets of problems in templates directory |
123 | ############# List of sets of problems in templates directory |
| 124 | |
124 | |
| 125 | sub getalllibsets { |
125 | sub get_problem_directories { |
| 126 | my $ce = shift; |
126 | my $ce = shift; |
| 127 | my @all_library_sets = get_library_sets(1, $ce->{courseDirs}->{templates}); |
127 | my @all_problem_directories = get_library_sets(1, $ce->{courseDirs}->{templates}); |
| 128 | my $includetop = shift @all_library_sets; |
128 | my $includetop = shift @all_problem_directories; |
| 129 | my $j; |
129 | my $j; |
| 130 | for ($j=0; $j<scalar(@all_library_sets); $j++) { |
130 | for ($j=0; $j<scalar(@all_problem_directories); $j++) { |
| 131 | $all_library_sets[$j] =~ s|^$ce->{courseDirs}->{templates}/?||; |
131 | $all_problem_directories[$j] =~ s|^$ce->{courseDirs}->{templates}/?||; |
| 132 | } |
132 | } |
| 133 | @all_library_sets = sort @all_library_sets; |
133 | @all_problem_directories = sort @all_problem_directories; |
| 134 | unshift @all_library_sets, ' -- Top -- ' if($includetop); |
134 | unshift @all_problem_directories, ' -- Top -- ' if($includetop); |
| 135 | return (\@all_library_sets); |
135 | return (\@all_problem_directories); |
| 136 | } |
136 | } |
| 137 | |
137 | |
| 138 | ### The browsing panel has three versions |
138 | ### The browsing panel has three versions |
| 139 | ##### Version 1 is local problems |
139 | ##### Version 1 is local problems |
| 140 | sub browse_local_panel { |
140 | sub browse_local_panel { |
| 141 | my $self = shift; |
141 | my $self = shift; |
| 142 | my $library_selected = shift; |
142 | my $library_selected = shift; |
| 143 | |
143 | |
| 144 | my $list_of_sets= getalllibsets($self->r->ce); |
144 | my $list_of_prob_dirs= get_problem_directories($self->r->ce); |
| 145 | my $libstr = ""; |
145 | if(scalar(@$list_of_prob_dirs) == 0) { |
|
|
146 | $library_selected = "Found no directories containing problems"; |
|
|
147 | unshift @{$list_of_prob_dirs}, $library_selected; |
|
|
148 | } else { |
| 146 | my $default_value = "Select a Local Problem Collection"; |
149 | my $default_value = "Select a Local Problem Collection"; |
| 147 | $libstr = CGI::br() . CGI::em($self->{libmsg}) if($self->{libmsg}); |
|
|
| 148 | |
|
|
| 149 | if (not $library_selected or $library_selected eq $default_value) { |
150 | if (not $library_selected or $library_selected eq $default_value) { |
| 150 | unshift @{$list_of_sets}, $default_value; |
151 | unshift @{$list_of_prob_dirs}, $default_value; |
| 151 | $library_selected = $default_value; |
152 | $library_selected = $default_value; |
| 152 | } |
153 | } |
| 153 | |
154 | } |
| 154 | |
155 | |
| 155 | print CGI::Tr(CGI::td({-class=>"InfoPanel"}, "Local Problems: ", |
156 | print CGI::Tr(CGI::td({-class=>"InfoPanel"}, "Local Problems: ", |
| 156 | CGI::popup_menu(-name=> 'library_sets', |
157 | CGI::popup_menu(-name=> 'library_sets', |
| 157 | -values=>$list_of_sets, |
158 | -values=>$list_of_prob_dirs, |
| 158 | -default=> $library_selected), |
159 | -default=> $library_selected), |
| 159 | CGI::br(), |
160 | CGI::br(), |
| 160 | CGI::submit(-name=>"view_local_set", -value=>"View Problems"), |
161 | CGI::submit(-name=>"view_local_set", -value=>"View Problems"), |
| 161 | $libstr |
|
|
| 162 | )); |
162 | )); |
| 163 | } |
163 | } |
| 164 | |
164 | |
| 165 | ##### Version 2 is local problem sets |
165 | ##### Version 2 is local problem sets |
| 166 | sub browse_mysets_panel { |
166 | sub browse_mysets_panel { |
| 167 | my $self = shift; |
167 | my $self = shift; |
| 168 | my $library_selected = shift; |
168 | my $library_selected = shift; |
| 169 | my $list_of_local_sets = shift; |
169 | my $list_of_local_sets = shift; |
| 170 | my $default_value = "Select a Problem Set"; |
170 | my $default_value = "Select a Problem Set"; |
| 171 | |
171 | |
| 172 | my $libstr = CGI::br() . CGI::em($self->{libmsg}) if($self->{libmsg}); |
|
|
| 173 | |
|
|
| 174 | if(scalar(@$list_of_local_sets) == 0) { |
172 | if(scalar(@$list_of_local_sets) == 0) { |
| 175 | $list_of_local_sets = ['There are no local sets yet']; |
173 | $list_of_local_sets = ['There are no local sets yet']; |
| 176 | } elsif (not $library_selected or $library_selected eq $default_value) { |
174 | } elsif (not $library_selected or $library_selected eq $default_value) { |
| 177 | unshift @{$list_of_local_sets}, $default_value; |
175 | unshift @{$list_of_local_sets}, $default_value; |
| 178 | $library_selected = $default_value; |
176 | $library_selected = $default_value; |
| … | |
… | |
| 182 | CGI::popup_menu(-name=> 'library_sets', |
180 | CGI::popup_menu(-name=> 'library_sets', |
| 183 | -values=>$list_of_local_sets, |
181 | -values=>$list_of_local_sets, |
| 184 | -default=> $library_selected), |
182 | -default=> $library_selected), |
| 185 | CGI::br(), |
183 | CGI::br(), |
| 186 | CGI::submit(-name=>"view_mysets_set", -value=>"View This Set"), |
184 | CGI::submit(-name=>"view_mysets_set", -value=>"View This Set"), |
| 187 | $libstr |
|
|
| 188 | )); |
185 | )); |
| 189 | } |
186 | } |
| 190 | |
187 | |
| 191 | ##### Version 3 is the problem library |
188 | ##### Version 3 is the problem library |
| 192 | |
189 | |
| … | |
… | |
| 208 | return; |
205 | return; |
| 209 | } |
206 | } |
| 210 | # Test if the Library directory exists. If not, try to make it |
207 | # Test if the Library directory exists. If not, try to make it |
| 211 | unless(-d "$ce->{courseDirs}->{templates}/Library") { |
208 | unless(-d "$ce->{courseDirs}->{templates}/Library") { |
| 212 | unless(symlink($libraryRoot, "$ce->{courseDirs}->{templates}/Library")) { |
209 | unless(symlink($libraryRoot, "$ce->{courseDirs}->{templates}/Library")) { |
| 213 | $self->{libmsg} .= <<"HERE"; |
210 | my $msg = <<"HERE"; |
| 214 | You are missing the directory <code>templates/Library</code>, which is needed |
211 | You are missing the directory <code>templates/Library</code>, which is needed |
| 215 | for the Problem Library to function. It should be a link pointing to |
212 | for the Problem Library to function. It should be a link pointing to |
| 216 | <code>$libraryRoot</code>, which you set in <code>conf/global.conf</code>. |
213 | <code>$libraryRoot</code>, which you set in <code>conf/global.conf</code>. |
| 217 | I tried to make the link for you, but that failed. Check the permissions |
214 | I tried to make the link for you, but that failed. Check the permissions |
| 218 | in your <code>templates</code> directory. |
215 | in your <code>templates</code> directory. |
| 219 | HERE |
216 | HERE |
|
|
217 | $self->addmessage(CGI::div({class=>"ResultsWithError"}, $msg)); |
| 220 | } |
218 | } |
| 221 | } |
219 | } |
| 222 | |
220 | |
| 223 | my $default_chap = "All Chapters"; |
221 | my $default_chap = "All Chapters"; |
| 224 | my $default_sect = "All Sections"; |
222 | my $default_sect = "All Sections"; |
| 225 | |
|
|
| 226 | my $libstr = CGI::br() . CGI::em($self->{libmsg}) if($self->{libmsg}); |
|
|
| 227 | |
223 | |
| 228 | my @chaps = WeBWorK::Utils::ListingDB::getAllChapters($r->{ce}); |
224 | my @chaps = WeBWorK::Utils::ListingDB::getAllChapters($r->{ce}); |
| 229 | unshift @chaps, $default_chap; |
225 | unshift @chaps, $default_chap; |
| 230 | my $chapter_selected = $r->param('library_chapters') || $default_chap; |
226 | my $chapter_selected = $r->param('library_chapters') || $default_chap; |
| 231 | |
227 | |
| … | |
… | |
| 270 | # CGI::td({-colspan=>2}, CGI::textfield(-name=>"keywords", |
266 | # CGI::td({-colspan=>2}, CGI::textfield(-name=>"keywords", |
| 271 | # -default=>"Keywords not implemented yet", |
267 | # -default=>"Keywords not implemented yet", |
| 272 | # -override=>1, -size=>60))), |
268 | # -override=>1, -size=>60))), |
| 273 | CGI::Tr(CGI::td({-colspan=>3},CGI::submit(-name=>"lib_view", -value=>"View Problems"))), |
269 | CGI::Tr(CGI::td({-colspan=>3},CGI::submit(-name=>"lib_view", -value=>"View Problems"))), |
| 274 | CGI::end_table(), |
270 | CGI::end_table(), |
| 275 | $libstr |
|
|
| 276 | )); |
271 | )); |
| 277 | } |
272 | } |
| 278 | |
273 | |
| 279 | sub make_top_row { |
274 | sub make_top_row { |
| 280 | my $self = shift; |
275 | my $self = shift; |
| … | |
… | |
| 285 | my $have_local_sets = scalar(@$list_of_local_sets); |
280 | my $have_local_sets = scalar(@$list_of_local_sets); |
| 286 | my $browse_which = $data{browse_which}; |
281 | my $browse_which = $data{browse_which}; |
| 287 | my $library_selected = $r->param('library_sets'); |
282 | my $library_selected = $r->param('library_sets'); |
| 288 | my $set_selected = $r->param('local_sets'); |
283 | my $set_selected = $r->param('local_sets'); |
| 289 | |
284 | |
| 290 | my $list_of_sets; |
|
|
| 291 | my ($dis1, $dis2, $dis3) = ("","",""); |
285 | my ($dis1, $dis2, $dis3) = ("","",""); |
| 292 | $dis1 = '-disabled' if($browse_which eq 'browse_library'); |
286 | $dis1 = '-disabled' if($browse_which eq 'browse_library'); |
| 293 | $dis2 = '-disabled' if($browse_which eq 'browse_local'); |
287 | $dis2 = '-disabled' if($browse_which eq 'browse_local'); |
| 294 | $dis3 = '-disabled' if($browse_which eq 'browse_mysets'); |
288 | $dis3 = '-disabled' if($browse_which eq 'browse_mysets'); |
| 295 | |
|
|
| 296 | my $locstr = ""; |
|
|
| 297 | $locstr = CGI::br() . CGI::em($self->{localmsg}) if($self->{localmsg}); |
|
|
| 298 | |
289 | |
| 299 | my $these_widths = "width: 27ex"; |
290 | my $these_widths = "width: 27ex"; |
| 300 | print CGI::Tr(CGI::td({-class=>"InfoPanel", -align=>"center"}, |
291 | print CGI::Tr(CGI::td({-class=>"InfoPanel", -align=>"center"}, |
| 301 | CGI::submit(-name=>"browse_library", -value=>"Browse Problem Library", -style=>$these_widths, $dis1), |
292 | CGI::submit(-name=>"browse_library", -value=>"Browse Problem Library", -style=>$these_widths, $dis1), |
| 302 | CGI::submit(-name=>"browse_local", -value=>"Browse Local Problems", -style=>$these_widths, $dis2), |
293 | CGI::submit(-name=>"browse_local", -value=>"Browse Local Problems", -style=>$these_widths, $dis2), |
| … | |
… | |
| 336 | " ", |
327 | " ", |
| 337 | CGI::textfield(-name=>"new_set_name", |
328 | CGI::textfield(-name=>"new_set_name", |
| 338 | -default=>"Name for new set here", |
329 | -default=>"Name for new set here", |
| 339 | -override=>1, -size=>30), |
330 | -override=>1, -size=>30), |
| 340 | CGI::br(), |
331 | CGI::br(), |
| 341 | $locstr |
|
|
| 342 | )); |
332 | )); |
| 343 | |
333 | |
| 344 | print CGI::Tr(CGI::td({-bgcolor=>"black"})); |
334 | print CGI::Tr(CGI::td({-bgcolor=>"black"})); |
| 345 | |
335 | |
| 346 | print CGI::Tr(CGI::td({-class=>"InfoPanel", -align=>"center"}, |
336 | print CGI::Tr(CGI::td({-class=>"InfoPanel", -align=>"center"}, |
| … | |
… | |
| 406 | CGI::hidden(-name=>"filetrial$cnt", -default=>[$sourceFileName]). |
396 | CGI::hidden(-name=>"filetrial$cnt", -default=>[$sourceFileName]). |
| 407 | CGI::p($problem_output), |
397 | CGI::p($problem_output), |
| 408 | )); |
398 | )); |
| 409 | } |
399 | } |
| 410 | |
400 | |
| 411 | sub title { |
|
|
| 412 | return "Problem Set Maker"; |
|
|
| 413 | } |
|
|
| 414 | |
401 | |
| 415 | sub body { |
402 | sub pre_header_initialize { |
| 416 | my ($self) = @_; |
403 | my ($self) = @_; |
| 417 | |
|
|
| 418 | my $r = $self->r; |
404 | my $r = $self->r; |
| 419 | my $ce = $r->ce; # course environment |
405 | ## For all cases, lets set some things |
|
|
406 | $self->{error}=0; |
|
|
407 | my $ce = $r->ce; |
| 420 | my $db = $r->db; # database |
408 | my $db = $r->db; |
| 421 | my $j; # garden variety counter |
409 | |
| 422 | |
410 | |
| 423 | my $userName = $r->param('user'); |
411 | my $userName = $r->param('user'); |
| 424 | |
|
|
| 425 | my $user = $db->getUser($userName); # checked |
412 | my $user = $db->getUser($userName); # checked |
| 426 | die "record for user $userName (real user) does not exist." |
413 | die "record for user $userName (real user) does not exist." |
| 427 | unless defined $user; |
414 | unless defined $user; |
| 428 | |
|
|
| 429 | ### Check that this is a professor |
|
|
| 430 | my $authz = $r->authz; |
415 | my $authz = $r->authz; |
| 431 | unless ($authz->hasPermissions($userName, "modify_problem_sets")) { |
416 | unless ($authz->hasPermissions($userName, "modify_problem_sets")) { |
| 432 | print "User $userName returned " . |
417 | return(""); # Error message already produced in the body |
| 433 | $authz->hasPermissions($user, "modify_problem_sets") . |
418 | } |
| 434 | " for permission"; |
419 | |
| 435 | return(CGI::em("You are not authorized to access the Instructor tools.")); |
420 | ## Now one action we have to deal with here |
|
|
421 | if ($r->param('edit_local')) { |
|
|
422 | my $urlpath = $r->urlpath; |
|
|
423 | my $db = $r->db; |
|
|
424 | my $checkset = $db->getGlobalSet($r->param('local_sets')); |
|
|
425 | if (not defined($checkset)) { |
|
|
426 | $self->{error} = 1; |
|
|
427 | $self->addmessage(CGI::div({class=>"ResultsWithError"}, 'You need to select a "Current Set" before you can edit it.')); |
|
|
428 | } else { |
|
|
429 | my $page = $urlpath->newFromModule('WeBWorK::ContentGenerator::Instructor::ProblemSetEditor', setID=>$r->param('local_sets'), courseID=>$urlpath->arg("courseID")); |
|
|
430 | my $url = $self->systemLink($page); |
|
|
431 | $self->reply_with_redirect($url); |
| 436 | } |
432 | } |
|
|
433 | } |
| 437 | |
434 | |
|
|
435 | ## Next, lots of set up so that errors can be reported with message() |
| 438 | |
436 | |
| 439 | ############# List of problems we have already printed |
437 | ############# List of problems we have already printed |
| 440 | |
438 | |
| 441 | my @past_problems = get_past_problem_files($r); |
439 | my @past_problems = get_past_problem_files($r); |
| 442 | my (@pg_files, @pg_html); |
440 | my @pg_files=(); |
| 443 | my $use_previous_problems = 1; |
441 | my $use_previous_problems = 1; |
| 444 | my $first_shown = $r->param('first_shown') || 0; |
442 | my $first_shown = $r->param('first_shown') || 0; |
| 445 | my $last_shown = $r->param('last_shown'); |
443 | my $last_shown = $r->param('last_shown'); |
| 446 | if (not defined($last_shown)) { |
444 | if (not defined($last_shown)) { |
| 447 | $last_shown = -1; |
445 | $last_shown = -1; |
| 448 | } |
446 | } |
| 449 | my @all_past_list = (); # these are include requested, but not shown |
447 | my @all_past_list = (); # these are include requested, but not shown |
| 450 | $j = 0; |
448 | my $j = 0; |
| 451 | while (defined($r->param("all_past_list$j"))) { |
449 | while (defined($r->param("all_past_list$j"))) { |
| 452 | push @all_past_list, $r->param("all_past_list$j"); |
450 | push @all_past_list, $r->param("all_past_list$j"); |
| 453 | $j++; |
451 | $j++; |
| 454 | } |
452 | } |
| 455 | |
453 | |
| 456 | ############# Default of which problem selector to display |
454 | ############# Default of which problem selector to display |
| 457 | |
455 | |
| 458 | my $browse_which = 'browse_local'; |
456 | my $browse_which = $r->param('browse_which') || 'browse_local'; |
| 459 | $browse_which = $r->param('browse_which') if defined($r->param('browse_which')); |
|
|
| 460 | |
457 | |
| 461 | my $problem_seed = $r->param('problem_seed') || 0; |
458 | my $problem_seed = $r->param('problem_seed') || 0; |
| 462 | $r->param('problem_seed', $problem_seed); # if it wasn't defined before |
459 | $r->param('problem_seed', $problem_seed); # if it wasn't defined before |
| 463 | |
460 | |
| 464 | ########### Start the logic through if elsif elsif ... |
461 | ########### Start the logic through if elsif elsif ... |
| … | |
… | |
| 489 | ##### View problems selected from the local list |
486 | ##### View problems selected from the local list |
| 490 | |
487 | |
| 491 | } elsif ($r->param('view_local_set')) { |
488 | } elsif ($r->param('view_local_set')) { |
| 492 | |
489 | |
| 493 | my $set_to_display = $r->param('library_sets'); |
490 | my $set_to_display = $r->param('library_sets'); |
| 494 | if (not defined($set_to_display) or $set_to_display eq "Select a Local Problem Collection") { |
491 | if (not defined($set_to_display) or $set_to_display eq "Select a Local Problem Collection" or $set_to_display eq "Found no directories containing problems") { |
| 495 | $self->{libmsg} = "You need to select a set to view."; |
492 | $self->addmessage(CGI::div({class=>"ResultsWithError"}, |
|
|
493 | 'You need to select a set to view.')); |
| 496 | } else { |
494 | } else { |
| 497 | $set_to_display = '.' if $set_to_display eq ' -- Top -- '; |
495 | $set_to_display = '.' if $set_to_display eq ' -- Top -- '; |
| 498 | @pg_files = list_pg_files($ce->{courseDirs}->{templates}, |
496 | @pg_files = list_pg_files($ce->{courseDirs}->{templates}, |
| 499 | "$set_to_display"); |
497 | "$set_to_display"); |
| 500 | $use_previous_problems=0; |
498 | $use_previous_problems=0; |
| … | |
… | |
| 506 | |
504 | |
| 507 | my $set_to_display = $r->param('library_sets'); |
505 | my $set_to_display = $r->param('library_sets'); |
| 508 | if (not defined($set_to_display) |
506 | if (not defined($set_to_display) |
| 509 | or $set_to_display eq "Select a Problem Set" |
507 | or $set_to_display eq "Select a Problem Set" |
| 510 | or $set_to_display eq 'There are no local sets yet') { |
508 | or $set_to_display eq 'There are no local sets yet') { |
|
|
509 | $self->addmessage(CGI::div({class=>"ResultsWithError"}, |
| 511 | $self->{libmsg} = "You need to select a set from this course to view."; |
510 | "You need to select a set from this course to view.")); |
| 512 | } else { |
511 | } else { |
| 513 | my @problemList = $db->listGlobalProblems($set_to_display); |
512 | my @problemList = $db->listGlobalProblems($set_to_display); |
| 514 | my $problem; |
513 | my $problem; |
| 515 | @pg_files=(); |
514 | @pg_files=(); |
| 516 | for $problem (@problemList) { |
515 | for $problem (@problemList) { |
| … | |
… | |
| 544 | $use_previous_problems=0; |
543 | $use_previous_problems=0; |
| 545 | |
544 | |
| 546 | ##### Edit the current local problem set |
545 | ##### Edit the current local problem set |
| 547 | |
546 | |
| 548 | } elsif ($r->param('edit_local')) { ## Jump to set edit page |
547 | } elsif ($r->param('edit_local')) { ## Jump to set edit page |
| 549 | # This is handled in pre_header_initialize -- it redirects |
548 | |
| 550 | # If there is an error, so no redirect, we want to be ready |
549 | ; # already handled |
| 551 | # and do something here |
550 | |
| 552 | |
551 | |
| 553 | ##### Make a new local problem set |
552 | ##### Make a new local problem set |
| 554 | |
553 | |
| 555 | } elsif ($r->param('new_local_set')) { |
554 | } elsif ($r->param('new_local_set')) { |
| 556 | if ($r->param('new_set_name') !~ /^[\w.-]*$/) { |
555 | if ($r->param('new_set_name') !~ /^[\w.-]*$/) { |
|
|
556 | $self->addmessage(CGI::div({class=>"ResultsWithError"}, |
| 557 | $self->{localmsg} = "The name ".$r->param('new_set_name')." is not a valid set name. Use only letters, digits, -, _, and ."; |
557 | "The name ".$r->param('new_set_name')." is not a valid set name. Use only letters, digits, -, _, and .")); |
| 558 | } else { |
558 | } else { |
| 559 | my $newSetName = $r->param('new_set_name'); |
559 | my $newSetName = $r->param('new_set_name'); |
| 560 | $newSetName =~ s/^set//; |
560 | $newSetName =~ s/^set//; |
| 561 | $newSetName =~ s/\.def$//; |
561 | $newSetName =~ s/\.def$//; |
| 562 | $r->param('local_sets',$newSetName); |
562 | $r->param('local_sets',$newSetName); |
| 563 | my $newSetRecord = $db->getGlobalSet($newSetName); |
563 | my $newSetRecord = $db->getGlobalSet($newSetName); |
| 564 | if (defined($newSetRecord)) { |
564 | if (defined($newSetRecord)) { |
| 565 | $self->{localmsg} = "The set name $newSetName is already in use. Pick a different name if you would like to start a new set."; |
565 | $self->addmessage(CGI::div({class=>"ResultsWithError"}, "The set name $newSetName is already in use. Pick a different name if you would like to start a new set.")); |
| 566 | } else { # Do it! |
566 | } else { # Do it! |
| 567 | $newSetRecord = $db->{set}->{record}->new(); |
567 | $newSetRecord = $db->{set}->{record}->new(); |
| 568 | $newSetRecord->set_id($newSetName); |
568 | $newSetRecord->set_id($newSetName); |
| 569 | $newSetRecord->set_header(""); |
569 | $newSetRecord->set_header(""); |
| 570 | $newSetRecord->problem_header(""); |
570 | $newSetRecord->problem_header(""); |
| … | |
… | |
| 585 | @selected = map {$_->[0]} @pg_files; |
585 | @selected = map {$_->[0]} @pg_files; |
| 586 | |
586 | |
| 587 | if (scalar(@selected)>0) { # if some are to be added, they need a place to go |
587 | if (scalar(@selected)>0) { # if some are to be added, they need a place to go |
| 588 | $localSet = $r->param('local_sets'); |
588 | $localSet = $r->param('local_sets'); |
| 589 | if (not defined($localSet)) { |
589 | if (not defined($localSet)) { |
|
|
590 | $self->addmessage(CGI::div({class=>"ResultsWithError"}, |
| 590 | $self->{localmsg} = "Trying to add problems to something, you did not select a current set name as a target."; |
591 | 'You are trying to add problems to something, but you did not select a "Current Set" name as a target.')); |
| 591 | } else { |
592 | } else { |
| 592 | my $newSetRecord = $db->getGlobalSet($localSet); |
593 | my $newSetRecord = $db->getGlobalSet($localSet); |
| 593 | if (not defined($newSetRecord)) { |
594 | if (not defined($newSetRecord)) { |
| 594 | $self->{localmsg} = "You need to select a local problem set to add the problems to."; |
595 | $self->addmessage(CGI::div({class=>"ResultsWithError"}, |
|
|
596 | 'You are trying to add problems to something, but you did not select a "Current Set" name as a target.')); |
| 595 | } else { |
597 | } else { |
| 596 | add_selected($self, $db, $localSet, @selected); |
598 | add_selected($self, $db, $localSet, @selected); |
| 597 | } |
599 | } |
| 598 | } |
600 | } |
| 599 | } |
601 | } |
| … | |
… | |
| 644 | } else { |
646 | } else { |
| 645 | $first_shown = 0; |
647 | $first_shown = 0; |
| 646 | $last_shown = scalar(@pg_files)<MAX_SHOW ? scalar(@pg_files) : MAX_SHOW; |
648 | $last_shown = scalar(@pg_files)<MAX_SHOW ? scalar(@pg_files) : MAX_SHOW; |
| 647 | $last_shown--; # to make it an array index |
649 | $last_shown--; # to make it an array index |
| 648 | } |
650 | } |
|
|
651 | ############# Now store data in self for retreival by body |
|
|
652 | $self->{first_shown} = $first_shown; |
|
|
653 | $self->{last_shown} = $last_shown; |
|
|
654 | $self->{browse_which} = $browse_which; |
|
|
655 | $self->{problem_seed} = $problem_seed; |
|
|
656 | $self->{pg_files} = \@pg_files; |
|
|
657 | $self->{all_set_defs} = \@all_set_defs; |
| 649 | |
658 | |
|
|
659 | } |
|
|
660 | |
|
|
661 | |
|
|
662 | sub title { |
|
|
663 | return "Problem Set Maker"; |
|
|
664 | } |
|
|
665 | |
|
|
666 | sub body { |
|
|
667 | my ($self) = @_; |
|
|
668 | |
|
|
669 | my $r = $self->r; |
|
|
670 | my $ce = $r->ce; # course environment |
|
|
671 | my $db = $r->db; # database |
|
|
672 | my $j; # garden variety counter |
|
|
673 | |
|
|
674 | my $userName = $r->param('user'); |
|
|
675 | |
|
|
676 | my $user = $db->getUser($userName); # checked |
|
|
677 | die "record for user $userName (real user) does not exist." |
|
|
678 | unless defined $user; |
|
|
679 | |
|
|
680 | ### Check that this is a professor |
|
|
681 | my $authz = $r->authz; |
|
|
682 | unless ($authz->hasPermissions($userName, "modify_problem_sets")) { |
|
|
683 | print "User $userName returned " . |
|
|
684 | $authz->hasPermissions($user, "modify_problem_sets") . |
|
|
685 | " for permission"; |
|
|
686 | return(CGI::div({class=>'ResultsWithError'}, |
|
|
687 | CGI::em("You are not authorized to access the Instructor tools."))); |
|
|
688 | } |
|
|
689 | |
|
|
690 | ########## Extract information computed in pre_header_initialize |
|
|
691 | |
|
|
692 | my $first_shown = $self->{first_shown}; |
|
|
693 | my $last_shown = $self->{last_shown}; |
|
|
694 | my $browse_which = $self->{browse_which}; |
|
|
695 | my $problem_seed = $self->{problem_seed}; |
|
|
696 | my @pg_files = @{$self->{pg_files}}; |
|
|
697 | my @all_set_defs = @{$self->{all_set_defs}}; |
|
|
698 | |
| 650 | @pg_html=($last_shown>=$first_shown) ? |
699 | my @pg_html=($last_shown>=$first_shown) ? |
| 651 | renderProblems($r,$user, @pg_files[$first_shown..$last_shown]) : (); |
700 | renderProblems($r,$user, @pg_files[$first_shown..$last_shown]) : (); |
| 652 | |
701 | |
| 653 | ########## Top part |
702 | ########## Top part |
| 654 | print CGI::startform({-method=>"POST", -action=>$r->uri}), |
703 | print CGI::startform({-method=>"POST", -action=>$r->uri}), |
| 655 | $self->hidden_authen_fields, |
704 | $self->hidden_authen_fields, |
| … | |
… | |
| 697 | return ""; |
746 | return ""; |
| 698 | } |
747 | } |
| 699 | |
748 | |
| 700 | ############################################## End of Body |
749 | ############################################## End of Body |
| 701 | |
750 | |
| 702 | sub pre_header_initialize { |
|
|
| 703 | my ($self) = @_; |
|
|
| 704 | my $r = $self->r; |
|
|
| 705 | ## For all cases, lets set some things |
|
|
| 706 | $self->{error}=0; |
|
|
| 707 | $self->{libmsg}=""; |
|
|
| 708 | $self->{localmsg}=""; |
|
|
| 709 | |
|
|
| 710 | |
|
|
| 711 | ### Maybe FIXME: this needs to check permissions before doing anything |
|
|
| 712 | |
|
|
| 713 | ## Now one action we have to deal with here |
|
|
| 714 | if ($r->param('edit_local')) { |
|
|
| 715 | my $urlpath = $r->urlpath; |
|
|
| 716 | my $db = $r->db; |
|
|
| 717 | my $checkset = $db->getGlobalSet($r->param('local_sets')); |
|
|
| 718 | if (not defined($checkset)) { |
|
|
| 719 | $self->{error} = 1; |
|
|
| 720 | $self->{localmsg} = "You need to select a local set before you can edit it."; |
|
|
| 721 | return(); |
|
|
| 722 | } |
|
|
| 723 | my $page = $urlpath->newFromModule('WeBWorK::ContentGenerator::Instructor::ProblemSetEditor', setID=>$r->param('local_sets'), courseID=>$urlpath->arg("courseID")); |
|
|
| 724 | my $url = $self->systemLink($page); |
|
|
| 725 | $self->reply_with_redirect($url); |
|
|
| 726 | } |
|
|
| 727 | } |
|
|
| 728 | |
|
|
| 729 | |
|
|
| 730 | # SKEL: To emit your own HTTP header, uncomment this: |
751 | # SKEL: To emit your own HTTP header, uncomment this: |
| 731 | # |
752 | # |
| 732 | #sub header { |
753 | #sub header { |
| 733 | # my ($self) = @_; |
754 | # my ($self) = @_; |
| 734 | # |
755 | # |