[system] / branches / rel-2-1-patches / webwork2 / lib / WeBWorK / ContentGenerator / ProblemSet.pm Repository:
ViewVC logotype

View of /branches/rel-2-1-patches/webwork2/lib/WeBWorK/ContentGenerator/ProblemSet.pm

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2980 - (download) (as text) (annotate)
Wed Nov 3 19:52:01 2004 UTC (8 years, 6 months ago)
File size: 13066 byte(s)
This commit was manufactured by cvs2svn to create branch 'rel-2-1-patches'.

    1 ################################################################################
    2 # WeBWorK Online Homework Delivery System
    3 # Copyright © 2000-2003 The WeBWorK Project, http://openwebwork.sf.net/
    4 # $CVSHeader: webwork2/lib/WeBWorK/ContentGenerator/ProblemSet.pm,v 1.57 2004/09/05 18:00:23 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::ProblemSet;
   18 use base qw(WeBWorK::ContentGenerator);
   19 
   20 =head1 NAME
   21 
   22 WeBWorK::ContentGenerator::ProblemSet - display an index of the problems in a
   23 problem set.
   24 
   25 =cut
   26 
   27 use strict;
   28 use warnings;
   29 use CGI qw(*ul *li);
   30 use WeBWorK::PG;
   31 use WeBWorK::Timing;
   32 use WeBWorK::Utils qw(sortByName);
   33 
   34 sub initialize {
   35   my ($self) = @_;
   36   my $r = $self->r;
   37   my $db = $r->db;
   38   my $urlpath = $r->urlpath;
   39   my $authz = $r->authz;
   40 
   41   my $setName = $urlpath->arg("setID");
   42   my $userName = $r->param("user");
   43   my $effectiveUserName = $r->param("effectiveUser");
   44 
   45   my $user            = $db->getUser($userName); # checked
   46   my $effectiveUser   = $db->getUser($effectiveUserName); # checked
   47   my $set             = $db->getMergedSet($effectiveUserName, $setName); # checked
   48 
   49   die "user $user (real user) not found."  unless $user;
   50   die "effective user $effectiveUserName  not found. One 'acts as' the effective user."  unless $effectiveUser;
   51 
   52   # FIXME: some day it would be nice to take out this code and consolidate the two checks
   53 
   54   # because of the database fix, we have to split our invalidSet check into two parts
   55   # First, if $set is undefined then $setName was never valid
   56   $self->{invalidSet} = not defined $set;
   57   return if $self->{invalidSet};
   58 
   59   # Database fix (in case of undefined published values)
   60   # this is only necessary because some people keep holding to ww1.9 which did not have a published field
   61   # make sure published is set to 0 or 1
   62   if ($set->published ne "0" and $set->published ne "1") {
   63     my $globalSet = $db->getGlobalSet($set->set_id);
   64     $globalSet->published("1"); # defaults to published
   65     $db->putGlobalSet($globalSet);
   66     $set = $db->getMergedSet($effectiveUserName, $set->set_id);
   67   }
   68 
   69   # Second, a set is invalid if it is still unpublished and the user does not have the right permissions
   70   $self->{invalidSet} = !($set->published || $authz->hasPermissions($userName, "view_unpublished_sets"));
   71   return if $self->{invalidSet};
   72 
   73   my $publishedText = ($set->published) ? "visible to students." : "hidden from students.";
   74   my $publishedClass = ($set->published) ? "Published" : "Unpublished";
   75   $self->addmessage(CGI::p("This set is " . CGI::font({class=>$publishedClass}, $publishedText))) if $authz->hasPermissions($userName, "view_unpublished_sets");
   76 
   77   $self->{userName}        = $userName;
   78   $self->{user}            = $user;
   79   $self->{effectiveUser}   = $effectiveUser;
   80   $self->{set}             = $set;
   81 
   82   ##### permissions #####
   83 
   84   $self->{isOpen} = time >= $set->open_date || $authz->hasPermissions($userName, "view_unopened_sets");
   85 }
   86 
   87 sub nav {
   88   my ($self, $args) = @_;
   89   my $r = $self->r;
   90   my $urlpath = $r->urlpath;
   91 
   92   my $courseID = $urlpath->arg("courseID");
   93   #my $problemSetsPage = $urlpath->newFromModule("WeBWorK::ContentGenerator::ProblemSets", courseID => $courseID);
   94   my $problemSetsPage = $urlpath->parent;
   95 
   96   my @links = ("Problem Sets" , $r->location . $problemSetsPage->path, "navUp");
   97   return $self->navMacro($args, "", @links);
   98 }
   99 
  100 sub siblings {
  101   my ($self) = @_;
  102   my $r = $self->r;
  103   my $db = $r->db;
  104   my $authz = $r->authz;
  105   my $urlpath = $r->urlpath;
  106 
  107 
  108   my $courseID = $urlpath->arg("courseID");
  109   my $user = $r->param('user');
  110   my $eUserID = $r->param("effectiveUser");
  111   my @setIDs = sortByName(undef, $db->listUserSets($eUserID));
  112   # do not show unpublished siblings unless user is allowed to view unpublished sets
  113   unless ($authz->hasPermissions($user, "view_unpublished_sets") ) {
  114     @setIDs    = grep {my $visible = $db->getGlobalSet( $_)->published; (defined($visible))? $visible : 1}
  115                        @setIDs;
  116   }
  117   print CGI::start_ul({class=>"LinksMenu"});
  118   print CGI::start_li();
  119   print CGI::span({style=>"font-size:larger"}, "Problem Sets");
  120   print CGI::start_ul();
  121 
  122   # FIXME: setIDs contain no info on published/unpublished so unpublished sets are still printed
  123   $WeBWorK::timer->continue("Begin printing sets from listUserSets()") if defined $WeBWorK::timer;
  124   foreach my $setID (@setIDs) {
  125     my $setPage = $urlpath->newFromModule("WeBWorK::ContentGenerator::ProblemSet",
  126       courseID => $courseID, setID => $setID);
  127     print CGI::li(CGI::a({href=>$self->systemLink($setPage)}, $setID)) ;
  128   }
  129   $WeBWorK::timer->continue("End printing sets from listUserSets()") if defined $WeBWorK::timer;
  130 
  131   # FIXME: when database calls are faster, this will get rid of unpublished sibling links
  132   #$WeBWorK::timer->continue("Begin printing sets from getMergedSets()") if defined $WeBWorK::timer;
  133   #my @userSetIDs = map {[$eUserID, $_]} @setIDs;
  134   #my @sets = $db->getMergedSets(@userSetIDs);
  135   #foreach my $set (@sets) {
  136   # my $setPage = $urlpath->newFromModule("WeBWorK::ContentGenerator::ProblemSet", courseID => $courseID, setID => $set->set_id);
  137   # print CGI::li(CGI::a({href=>$self->systemLink($setPage)}, $set->set_id)) unless !(defined $set && ($set->published || $authz->hasPermissions($user, "view_unpublished_sets"));
  138   #}
  139   #$WeBWorK::timer->continue("Begin printing sets from getMergedSets()") if defined $WeBWorK::timer;
  140 
  141   print CGI::end_ul();
  142   print CGI::end_li();
  143   print CGI::end_ul();
  144 
  145   return "";
  146 }
  147 
  148 sub info {
  149   my ($self) = @_;
  150   my $r = $self->r;
  151   my $ce = $r->ce;
  152   my $db = $r->db;
  153   my $authz = $r->authz;
  154   my $urlpath = $r->urlpath;
  155 
  156   return "" unless $self->{isOpen};
  157 
  158   my $courseID = $urlpath->arg("courseID");
  159   my $setID = $r->urlpath->arg("setID");
  160 
  161   my $userID = $r->param("user");
  162   my $eUserID = $r->param("effectiveUser");
  163 
  164   my $effectiveUser = $db->getUser($eUserID); # checked
  165   my $set  = $db->getMergedSet($eUserID, $setID); # checked
  166 
  167   die "effective user $eUserID not found. One 'acts as' the effective user." unless $effectiveUser;
  168   # FIXME: this was already caught in initialize()
  169   die "set $setID for effectiveUser $eUserID not found." unless $set;
  170 
  171   my $psvn = $set->psvn();
  172 
  173   my $screenSetHeader = $set->set_header || $ce->{webworkFiles}->{screenSnippets}->{setHeader};
  174   my $displayMode     = $ce->{pg}->{options}->{displayMode};
  175 
  176   if (defined $r->param("editMode") and $r->param("editMode") eq "temporaryFile") {
  177     $screenSetHeader = "$screenSetHeader.$userID.tmp";
  178     $displayMode = $r->param("displayMode") if $r->param("displayMode");
  179   }
  180 
  181   return "" unless defined $screenSetHeader and $screenSetHeader;
  182 
  183   # decide what to do about problem number
  184   my $problem = WeBWorK::DB::Record::UserProblem->new(
  185     problem_id => 0,
  186     set_id => $set->set_id,
  187     login_id => $effectiveUser->user_id,
  188     source_file => $screenSetHeader,
  189     # the rest of Problem's fields are not needed, i think
  190   );
  191 
  192   my $pg = WeBWorK::PG->new(
  193     $ce,
  194     $effectiveUser,
  195     $r->param('key'),
  196     $set,
  197     $problem,
  198     $psvn,
  199     {}, # no form fields!
  200     { # translation options
  201       displayMode     => $displayMode,
  202       showHints       => 0,
  203       showSolutions   => 0,
  204       processAnswers  => 0,
  205     },
  206   );
  207 
  208   if (defined($set) and $set->set_header and $authz->hasPermissions($userID, "modify_problem_sets")) {
  209     #FIXME ?  can't edit the default set header this way
  210     my $editorPage = $urlpath->newFromModule("WeBWorK::ContentGenerator::Instructor::PGProblemEditor",
  211       courseID => $courseID, setID => $set->set_id, problemID => 0);
  212     my $editorURL = $self->systemLink($editorPage);
  213 
  214     print CGI::p(CGI::b("Set Info"), " ",
  215       CGI::a({href=>$editorURL}, "[edit]"));
  216   } else {
  217     print CGI::p(CGI::b("Set Info"));
  218   }
  219 
  220   if ($pg->{flags}->{error_flag}) {
  221     print CGI::div({class=>"ResultsWithError"}, $self->errorOutput($pg->{errors}, $pg->{body_text}));
  222   } else {
  223     print $pg->{body_text};
  224   }
  225 
  226   return "";
  227 }
  228 
  229 sub body {
  230   my ($self) = @_;
  231   my $r = $self->r;
  232   my $ce = $r->ce;
  233   my $db = $r->db;
  234   my $urlpath = $r->urlpath;
  235 
  236   my $courseID = $urlpath->arg("courseID");
  237   my $setName = $urlpath->arg("setID");
  238   my $effectiveUser = $r->param('effectiveUser');
  239 
  240   my $set = $db->getMergedSet($effectiveUser, $setName);  # checked
  241   # FIXME: this was already caught in initialize()
  242   # die "set $setName for user $effectiveUser not found" unless $set;
  243 
  244   if ($self->{invalidSet}) {
  245     return CGI::div({class=>"ResultsWithError"},
  246       CGI::p("The selected problem set ($setName) is not a valid set for $effectiveUser."));
  247   }
  248 
  249   unless ($self->{isOpen}) {
  250     return CGI::div({class=>"ResultsWithError"},
  251       CGI::p("This problem set is not available because it is not yet open."));
  252   }
  253 
  254   #my $hardcopyURL =
  255   # $ce->{webworkURLs}->{root} . "/"
  256   # . $ce->{courseName} . "/"
  257   # . "hardcopy/$setName/?" . $self->url_authen_args;
  258 
  259   my $hardcopyPage = $urlpath->newFromModule("WeBWorK::ContentGenerator::Hardcopy",
  260     courseID => $courseID, setID => $setName);
  261   my $hardcopyURL = $self->systemLink($hardcopyPage);
  262 
  263   print CGI::p(CGI::a({href=>$hardcopyURL}, "Download a hardcopy of this problem set."));
  264 
  265   print CGI::start_table();
  266   print CGI::Tr(
  267     CGI::th("Name"),
  268     CGI::th("Attempts"),
  269     CGI::th("Remaining"),
  270     CGI::th("Status"),
  271   );
  272 
  273   my @problemNumbers = $db->listUserProblems($effectiveUser, $setName);
  274   foreach my $problemNumber (sort { $a <=> $b } @problemNumbers) {
  275     my $problem = $db->getMergedProblem($effectiveUser, $setName, $problemNumber); # checked
  276     die "problem $problemNumber in set $setName for user $effectiveUser not found." unless $problem;
  277     print $self->problemListRow($set, $problem);
  278   }
  279 
  280   print CGI::end_table();
  281 
  282   ## feedback form
  283   #my $ce = $self->{ce};
  284   #my $root = $ce->{webworkURLs}->{root};
  285   #my $courseName = $ce->{courseName};
  286   #my $feedbackURL = "$root/$courseName/feedback/";
  287   #print
  288   # CGI::start_form(-method=>"POST", -action=>$feedbackURL),"\n",
  289   # $self->hidden_authen_fields,"\n",
  290   # CGI::hidden("module",             __PACKAGE__),"\n",
  291   # CGI::hidden("set",                $self->{set}->set_id),"\n",
  292   # CGI::hidden("problem",            ""),"\n",
  293   # CGI::hidden("displayMode",        $self->{displayMode}),"\n",
  294   # CGI::hidden("showOldAnswers",     ''),"\n",
  295   # CGI::hidden("showCorrectAnswers", ''),"\n",
  296   # CGI::hidden("showHints",          ''),"\n",
  297   # CGI::hidden("showSolutions",      ''),"\n",
  298   # CGI::p({-align=>"left"},
  299   #   CGI::submit(-name=>"feedbackForm", -label=>"Email instructor")
  300   # ),
  301   # CGI::endform(),"\n";
  302 
  303   # feedback form url
  304   my $feedbackPage = $urlpath->newFromModule("WeBWorK::ContentGenerator::Feedback",
  305     courseID => $courseID);
  306   my $feedbackURL = $self->systemLink($feedbackPage, authen => 0); # no authen info for form action
  307 
  308   #print feedback form
  309   print
  310     CGI::start_form(-method=>"POST", -action=>$feedbackURL),"\n",
  311     $self->hidden_authen_fields,"\n",
  312     CGI::hidden("module",             __PACKAGE__),"\n",
  313     CGI::hidden("set",                $self->{set}->set_id),"\n",
  314     CGI::hidden("problem",            ''),"\n",
  315     CGI::hidden("displayMode",        $self->{displayMode}),"\n",
  316     CGI::hidden("showOldAnswers",     ''),"\n",
  317     CGI::hidden("showCorrectAnswers", ''),"\n",
  318     CGI::hidden("showHints",          ''),"\n",
  319     CGI::hidden("showSolutions",      ''),"\n",
  320     CGI::p({-align=>"left"},
  321       CGI::submit(-name=>"feedbackForm", -label=>"Email instructor")
  322     ),
  323     CGI::endform(),"\n";
  324 
  325   return "";
  326 }
  327 
  328 sub problemListRow($$$) {
  329   my ($self, $set, $problem) = @_;
  330   my $r = $self->r;
  331   my $urlpath = $r->urlpath;
  332 
  333   my $courseID = $urlpath->arg("courseID");
  334   my $setID = $set->set_id;
  335   my $problemID = $problem->problem_id;
  336 
  337   my $interactiveURL = $self->systemLink(
  338     $urlpath->newFromModule("WeBWorK::ContentGenerator::Problem",
  339       courseID => $courseID, setID => $setID, problemID => $problemID)
  340   );
  341 
  342   my $interactive = CGI::a({-href=>$interactiveURL}, "Problem $problemID");
  343   my $attempts = $problem->num_correct + $problem->num_incorrect;
  344   my $remaining = $problem->max_attempts < 0
  345     ? "unlimited"
  346     : $problem->max_attempts - $attempts;
  347   my $rawStatus = $problem->status || 0;
  348   my $status;
  349   $status = eval{ sprintf("%.0f%%", $rawStatus * 100)}; # round to whole number
  350   $status = 'unknown(FIXME)' if $@; # use a blank if problem status was not defined or not numeric.
  351                                     # FIXME  -- this may not cover all cases.
  352 
  353   my $msg = ($problem->value) ? "" : "(This problem will not count towards your grade.)";
  354 
  355   return CGI::Tr(CGI::td({-nowrap=>1, -align=>"center"}, [
  356     $interactive,
  357     $attempts,
  358     $remaining,
  359     $status . " " . $msg,
  360   ]));
  361 }
  362 
  363 1;

aubreyja at gmail dot com
ViewVC Help
Powered by ViewVC 1.0.9