[system] / trunk / webwork-modperl / lib / WeBWorK / ContentGenerator / Instructor / ProblemList.pm Repository:
ViewVC logotype

View of /trunk/webwork-modperl/lib/WeBWorK/ContentGenerator/Instructor/ProblemList.pm

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1006 - (download) (as text) (annotate)
Wed Jun 4 02:59:55 2003 UTC (9 years, 11 months ago) by gage
File size: 9289 byte(s)
Added ProblemList (from Dennis' folder) and committed it to CVS
--Mike

    1 ################################################################################
    2 # WeBWorK mod_perl (c) 2000-2002 WeBWorK Project
    3 # $Id$
    4 ################################################################################
    5 
    6 package WeBWorK::ContentGenerator::Instructor::ProblemList;
    7 use base qw(WeBWorK::ContentGenerator::Instructor);
    8 
    9 =head1 NAME
   10 
   11 WeBWorK::ContentGenerator::Instructor::ProblemList - List and edit problems in a set
   12 
   13 =cut
   14 
   15 use strict;
   16 use warnings;
   17 use CGI qw();
   18 use WeBWorK::Utils qw(readDirectory list2hash max);
   19 use WeBWorK::DB::Record::Set;
   20 
   21 use constant PROBLEM_FIELDS =>[qw(source_file value max_attempts)];
   22 use constant PROBLEM_USER_FIELDS => [qw(problem_seed status num_correct num_incorrect)];
   23 
   24 sub problemElementHTML {
   25   my ($fieldName, $fieldValue, $size, $override, $overrideValue) = @_;
   26   my $attributeHash = {type=>"text",name=>$fieldName,value=>$fieldValue};
   27   $attributeHash->{size} = $size if defined $size;
   28 
   29   my $html = CGI::input($attributeHash);
   30   if (defined $override) {
   31     $attributeHash->{name} = "${fieldName}_override";
   32     $attributeHash->{value} = ($override ? $overrideValue : "");
   33     $html = "default:".CGI::br().$html.CGI::br()
   34       . CGI::checkbox({
   35         type => "checkbox",
   36         name => "override",
   37         label => "override:",
   38         value => $fieldName,
   39         checked => ($override ? 1 : 0)
   40       })
   41       . CGI::br()
   42       . CGI::input($attributeHash);
   43   }
   44 
   45   return $html;
   46 }
   47 
   48 # pay no attention to the argument list.  Here's what you pass:
   49 # directoryListHTML($level, $selected, $libraryRoot, @path)
   50 sub directoryListHTML {
   51   my ($level, $selected, @path) = @_;
   52   $selected = [$selected] unless ref $selected eq "ARRAY";
   53   my $dirName = join "/", @path[0..$level];
   54   my @contents = sort grep {m/\.pg$/ or -d $dirName.'/'.$_ and not m/^\.{1,2}$/} readDirectory($dirName);
   55   my %contentsPretty = map {$_ => (-d $dirName.'/'.$_ ? $_.'/' : $_)} @contents;
   56 
   57   my $html = ($level eq "0" ? "problem library" : $path[$level]) . CGI::br();
   58   $html .= CGI::scrolling_list({
   59     name=>"directory_level_$level",
   60     values=>\@contents,
   61     labels=>\%contentsPretty,
   62     default=>$selected,
   63     multiple=>'true',
   64     size=>"20",
   65   });
   66   $html .= CGI::br()
   67     . CGI::input({type=>"submit", name=>"open_add_$level", value=>"Open/Add"});
   68 }
   69 
   70 sub initialize {
   71   my ($self, $setName) = @_;
   72   my $r = $self->{r};
   73   my $db = $self->{db};
   74   my $ce = $self->{ce};
   75   my $setRecord = $db->getGlobalSet($setName);
   76   my @editForUser = $r->param('editForUser');
   77   # some useful booleans
   78   my $forUsers = scalar(@editForUser);
   79   my $forOneUser = $forUsers == 1;
   80 
   81   # build a quick lookup table
   82   my %overrides = list2hash $r->param('override');
   83 
   84   # the Problem form was submitted
   85   if (defined($r->param('submit_problem_changes'))) {
   86     foreach my $problem ($r->param('deleteProblem')) {
   87       $db->deleteGlobalProblem($setName, $problem);
   88     }
   89     my @problemList = $db->listGlobalProblems($setName);
   90     foreach my $problem (@problemList) {
   91       my $problemRecord = $db->getGlobalProblem($setName, $problem);
   92       foreach my $field (@{PROBLEM_FIELDS()}) {
   93         my $paramName = "problem_${problem}_${field}";
   94         if (defined($r->param($paramName))) {
   95           $problemRecord->$field($r->param($paramName));
   96         }
   97       }
   98       $db->putGlobalProblem($problemRecord);
   99 
  100       if ($forOneUser) {
  101         my $userProblemRecord = $db->getUserProblem($editForUser[0], $setName, $problem);
  102         foreach my $field (@{PROBLEM_USER_FIELDS()}) {
  103           my $paramName = "problem_${problem}_${field}";
  104           if (defined($r->param($paramName))) {
  105             $userProblemRecord->$field($r->param($paramName));
  106           }
  107         }
  108         $userProblemRecord->attempted($userProblemRecord->num_correct + $userProblemRecord->num_incorrect);
  109         foreach my $field (@{PROBLEM_FIELDS()}) {
  110           my $paramName = "problem_${problem}_${field}";
  111           if (defined($r->param("${paramName}_override"))) {
  112             if (exists $overrides{$paramName}) {
  113               $userProblemRecord->$field($r->param("${paramName}_override"));
  114             } else {
  115               $userProblemRecord->$field(undef);
  116             }
  117 
  118             $db->putUserProblem($userProblemRecord);
  119           }
  120         }
  121 
  122       }
  123     }
  124   # The file list field was submitted
  125   } elsif (defined $r->param('fileBrowsing')) {
  126     my $libraryRoot = $ce->{courseDirs}->{templates};
  127     my $count = 0;
  128     my $done = 0;
  129     my @path = ();
  130     my $freeProblemID = max($db->listGlobalProblems($setName)) + 1;
  131     while (defined $r->param("directory_level_$count") and not $done) {
  132       my @selected = $r->param("directory_level_$count");
  133       my $dirFound = 0;
  134       # If any directories are selected, "cd" into the first one and stop processing this level.
  135       foreach my $selected (@selected) {
  136         if (-d join "/", $libraryRoot, @path, $selected) {
  137           push @path, $selected;
  138           $dirFound = 1;
  139           last;
  140         }
  141       }
  142       # Otherwise, create a new global problem for each of the files selected
  143       unless ($dirFound) {
  144         foreach my $selected (@selected) {
  145           my $file = join "/", @path, $selected;
  146           my $problemRecord = new WeBWorK::DB::Record::Problem;
  147           $problemRecord->problem_id($freeProblemID++);
  148           $problemRecord->set_id($setName);
  149           $problemRecord->source_file($file);
  150           $problemRecord->value("1");
  151           $problemRecord->max_attempts("-1");
  152           $db->addGlobalProblem($problemRecord);
  153         }
  154         $done = 1;
  155       }
  156 
  157       if (defined $r->param("open_add_$count")) {
  158         $done = 1;
  159       }
  160       $count++;
  161     }
  162     $self->{path} = [@path];
  163   }
  164 
  165 }
  166 
  167 sub title {
  168   my ($self, $setName) = @_;
  169   return "Problems in ".$self->{ce}->{courseName}." : ".$setName;
  170 }
  171 
  172 sub body {
  173   my ($self, $setName) = @_;
  174   my $r = $self->{r};
  175   my $db = $self->{db};
  176   my $ce = $self->{ce};
  177   my $courseName = $ce->{courseName};
  178   my $setRecord = $db->getGlobalSet($setName);
  179   my @editForUser = $r->param('editForUser');
  180   # some useful booleans
  181   my $forUsers = scalar(@editForUser);
  182   my $forOneUser = $forUsers == 1;
  183 
  184   ## Problems Form ##
  185   my @problemList = $db->listGlobalProblems($setName);
  186   print CGI::a({name=>"problems"});
  187   print CGI::h2({}, "Problems");
  188   if (scalar(@problemList)) {
  189     print CGI::start_form({method=>"POST", action=>$r->uri.'#problems'});
  190     print CGI::start_table({border=>1, cellpadding=>4});
  191     print CGI::Tr({}, CGI::th({}, [
  192       ($forUsers ? () : ("Delete?")),
  193       "Problem",
  194       ($forUsers ? ("Status", "Problem Seed") : ()),
  195       "Source File", "Max. Attempts", "Weight",
  196       ($forUsers ? ("Number Correct", "Number Incorrect") : ())
  197     ]));
  198     foreach my $problem (sort {$a <=> $b} @problemList) {
  199       my $problemRecord = $db->getGlobalProblem($setName, $problem);
  200       my $problemID = $problemRecord->problem_id;
  201       my $userProblemRecord;
  202       my %problemOverrideArgs;
  203 
  204       if ($forOneUser) {
  205         $userProblemRecord = $db->getUserProblem($editForUser[0], $setName, $problem);
  206         foreach my $field (@{PROBLEM_FIELDS()}) {
  207           $problemOverrideArgs{$field} = [defined $userProblemRecord->$field, $userProblemRecord->$field];
  208         }
  209   #   } elsif ($forUsers) {
  210   #     foreach my $field (@{PROBLEM_FIELDS()}) {
  211   #       $problemOverrideArgs{$field} = ["", ""];
  212   #     }
  213       } else {
  214         foreach my $field (@{PROBLEM_FIELDS()}) {
  215           $problemOverrideArgs{$field} = [undef, undef];
  216         }
  217       }
  218 
  219       print CGI::Tr({},
  220         CGI::td({}, [
  221           ($forUsers ? () : (CGI::input({type=>"checkbox", name=>"deleteProblem", value=>$problemID}))),
  222           CGI::a({href=>$ce->{webworkURLs}->{root}."/$courseName/instructor/pgProblemEditor/".$setName.'/'.$problemID.'?'.$self->url_authen_args}, $problemID),
  223           ($forUsers ? (
  224             problemElementHTML("problem_${problemID}_status", $userProblemRecord->status, "7"),
  225             problemElementHTML("problem_${problemID}_problem_seed", $userProblemRecord->problem_seed, "7"),
  226           ) : ()),
  227           problemElementHTML("problem_${problemID}_source_file", $problemRecord->source_file, "40", @{$problemOverrideArgs{source_file}}),
  228           problemElementHTML("problem_${problemID}_max_attempts",$problemRecord->max_attempts,"7", @{$problemOverrideArgs{max_attempts}}),
  229           problemElementHTML("problem_${problemID}_value",$problemRecord->value,"7", @{$problemOverrideArgs{value}}),
  230           ($forUsers ? (
  231             problemElementHTML("problem_${problemID}_num_correct", $userProblemRecord->num_correct, "7"),
  232             problemElementHTML("problem_${problemID}_num_incorrect", $userProblemRecord->num_incorrect, "7")
  233           ) : ())
  234         ])
  235 
  236       )
  237     }
  238     print CGI::end_table();
  239     print $self->hiddenEditForUserFields(@editForUser);
  240     print $self->hidden_authen_fields;
  241     print CGI::input({type=>"submit", name=>"submit_problem_changes", value=>"Save Problem Changes"});
  242     print CGI::end_form();
  243   } else {
  244     print CGI::p("This set doesn't contain any problems yet.");
  245   }
  246 
  247   unless ($forUsers) {
  248     my $libraryRoot = $ce->{courseDirs}->{templates};
  249     my @path = defined $self->{path} ? @{$self->{path}} : ();
  250     unshift @path, $libraryRoot;
  251     print CGI::a({name=>"addProblem"});
  252     print CGI::h3({}, "Add Problem(s)");
  253     print CGI::start_form({method=>"post", action=>$r->uri.'#addProblem'});
  254     print CGI::input({type=>"hidden", name=>"fileBrowsing", value=>"Yes"});
  255     print CGI::start_table();
  256     my $columns = "";
  257     for (my $counter = 0; $counter < scalar(@path); $counter++) {
  258       $columns .= CGI::td(directoryListHTML ($counter, (exists $path[$counter+1] ? $path[$counter+1] : []), @path));
  259     }
  260     print CGI::Tr($columns);
  261     print CGI::end_table();
  262     print $self->hidden_authen_fields;
  263     print CGI::end_form();
  264   }
  265 
  266   return "";
  267 }
  268 
  269 1;

aubreyja at gmail dot com
ViewVC Help
Powered by ViewVC 1.0.9