[system] / branches / rel-2-3-dev / webwork-modperl / lib / WeBWorK / ContentGenerator / Instructor / UserDetail.pm Repository:
ViewVC logotype

View of /branches/rel-2-3-dev/webwork-modperl/lib/WeBWorK/ContentGenerator/Instructor/UserDetail.pm

Parent Directory Parent Directory | Revision Log Revision Log


Revision 4396 - (download) (as text) (annotate)
Thu Aug 24 21:07:52 2006 UTC (6 years, 8 months ago)
File size: 17484 byte(s)
This commit was manufactured by cvs2svn to create branch 'rel-2-3-dev'.

    1 ################################################################################
    2 # WeBWorK Online Homework Delivery System
    3 # Copyright © 2000-2006 The WeBWorK Project, http://openwebwork.sf.net/
    4 # $CVSHeader:
    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::UserDetail;
   18 use base qw(WeBWorK::ContentGenerator::Instructor);
   19 
   20 =head1 NAME
   21 
   22 WeBWorK::ContentGenerator::Instructor::UserDetail - Detailed User specific information
   23 
   24 =cut
   25 
   26 use strict;
   27 use warnings;
   28 #use CGI qw(-nosticky );
   29 use WeBWorK::CGI;
   30 use WeBWorK::Utils qw(sortByName);
   31 use WeBWorK::Debug;
   32 
   33 use constant DATE_FIELDS => {   open_date    => " Open: ",
   34                               due_date     => " Due : ",
   35                               answer_date  => " Ans : "
   36 };
   37 use constant DATE_FIELDS_ORDER =>[qw(open_date due_date answer_date )];
   38 sub initialize {
   39   my ($self) = @_;
   40   my $r = $self->r;
   41   my $urlpath = $r->urlpath;
   42   my $db = $r->db;
   43   my $authz = $r->authz;
   44   my $userID = $r->param("user");
   45   my $editForUserID = $urlpath->arg("userID");
   46 
   47   return CGI::div({class => "ResultsWithError"}, "You are not authorized to edit user specific information.")
   48     unless $authz->hasPermissions($userID, "access_instructor_tools");
   49 
   50   # templates for getting field names
   51   my $userTemplate = $self->{userTemplate} = $db->newUser;
   52   my $permissionLevelTemplate = $self->{permissionLevelTemplate} = $db->newPermissionLevel;
   53 
   54   # first check to see if a save form has been submitted
   55   return '' unless $r->param('save_button');
   56 
   57   # As it stands we need to check each set to see if it is still assigned
   58   # the forms are not currently set up to simply transmit changes
   59 
   60   #Get the list of sets and the global set records
   61   my @setIDs = $db->listGlobalSets;
   62   my @setRecords = grep { defined $_ } $db->getGlobalSets(@setIDs);
   63 
   64   my @assignedSets = ();
   65   foreach my $setID (@setIDs) {
   66     push @assignedSets, $setID if defined($r->param("set.$setID.assignment"));
   67   }
   68   debug("assignedSets", join(" ", @assignedSets));
   69   my %selectedSets = map { $_ => 1 } @assignedSets;
   70   #debug ##########################
   71     #print STDERR ("aSsigned sets", join(" ",@assignedSets));
   72         #my @params = $r->param();
   73         #print STDERR " parameters ", join(" ", @params);
   74     ###############
   75   #Get the user(s) whose records are to be modified
   76   #  for now: $editForUserID
   77   # check the user exists?  Is this necessary?
   78   my $editUserRecord = $db->getUser($editForUserID);
   79   die "record not found for $editForUserID.\n" unless $editUserRecord;
   80 
   81 
   82   #Perform the desired assignments or deletions
   83   my %userSets = map { $_ => 1 } $db->listUserSets($editForUserID);
   84 
   85   # go through each possible set
   86   debug(" parameters ", join(" ", $r->param()) );
   87   foreach my $setRecord (@setRecords) {
   88     my $setID = $setRecord->set_id;
   89     # does the user want it to be assigned to the selected user
   90     if (exists $selectedSets{$setID}) {
   91         $self->assignSetToUser($editForUserID, $setRecord);
   92         #override dates
   93 
   94 
   95         my $userSetRecord = $db->getUserSet($editForUserID, $setID);
   96         # get the dates
   97 
   98 
   99 
  100         #do checks to see if new dates meet criteria
  101         my $rh_dates = $self->checkDates($setRecord,$setID);
  102         unless  ( $rh_dates->{error} ) { #returns 1 if error
  103           # if no error update database
  104           foreach my $field (keys %{DATE_FIELDS()}) {
  105             if (defined $r->param("set.$setID.$field.override")) {
  106               $userSetRecord->$field($rh_dates->{$field});
  107             } else {
  108               $userSetRecord->$field(undef); #stop override
  109             }
  110           }
  111           $db->putUserSet($userSetRecord);
  112 
  113         }
  114 
  115     } else {
  116       # user asked to NOT have the set assigned to the selected user
  117       # debug("deleteUserSet($editForUserID, $setID)");
  118       $db->deleteUserSet($editForUserID, $setID);
  119       # debug("done deleteUserSet($editForUserID, $setID)");
  120     }
  121   }
  122 
  123   return '';
  124 
  125 
  126 
  127 }
  128 
  129 sub body {
  130   my ($self) = @_;
  131   my $r = $self->r;
  132   my $urlpath = $r->urlpath;
  133   my $db = $r->db;
  134   my $ce = $r->ce;
  135   my $authz = $r->authz;
  136   my $courseID = $urlpath->arg("courseID");
  137   my $editForUserID = $urlpath->arg("userID");
  138   my $userID = $r->param("user");
  139 
  140   my @editForSets = $r->param("editForSets");
  141 
  142   return CGI::div({class => "ResultsWithError"}, "You are not authorized to edit user specific information.")
  143     unless $authz->hasPermissions($userID, "access_instructor_tools");
  144 
  145   my $UserRecord = $db->getUser($editForUserID);
  146   my $PermissionRecord = $db->getPermissionLevel($editForUserID);
  147   my @UserSetIDs = $db->listUserSets($editForUserID);
  148 
  149   my $userName = $UserRecord->first_name . " " . $UserRecord->last_name;
  150 
  151   # templates for getting field names
  152   my $userTemplate = $self->{userTemplate};
  153   my $permissionLevelTemplate = $self->{permissionLevelTemplate};
  154 
  155   # This table can be consulted when display-ready forms of field names are needed.
  156   my %prettyFieldNames = map { $_ => $_ }
  157     $userTemplate->FIELDS();
  158 
  159 #   @prettyFieldNames{qw(
  160 #     #user_id
  161 #     first_name
  162 #     last_name
  163 #     email_address
  164 #     student_id
  165 #     status
  166 #     section
  167 #     recitation
  168 #     comment
  169 #     permission
  170 #   )} = (
  171 #     #"Login Name",
  172 #     "First Name",
  173 #     "Last Name",
  174 #     "Email",
  175 #     "Student ID",
  176 #     "Status",
  177 #     "Section",
  178 #     "Recitation",
  179 #     "Comment",
  180 #     "Permission Level",
  181 #   );
  182 
  183   my @dateFields         = @{DATE_FIELDS_ORDER()};
  184   my $rh_dateFieldLabels =  DATE_FIELDS();
  185 
  186 
  187   # create a link to the SetsAssignedToUser page
  188 #   my $editSetsPath = $urlpath->newFromModule(
  189 #     "WeBWorK::ContentGenerator::Instructor::SetsAssignedToUser",
  190 #     courseID => $courseID,
  191 #     userID => $userID,
  192 #   );
  193 #   my $editSetsAssignedToUserURL = $self->systemLink($editSetsPath);
  194 
  195   # create a message about how many sets have been assigned to this user
  196   my $setCount = $db->countUserSets($editForUserID);
  197 #   my $userCountMessage =  CGI::a({href=>$editSetsAssignedToUserURL}, $setCount . " sets.");
  198 #   $userCountMessage = "The user " . CGI::b($userName . " ($editForUserID)") . " has been assigned " . $userCountMessage;
  199   my $basicInfoPage = $urlpath->new(type =>'instructor_user_list',
  200           args =>{
  201             courseID => $courseID,
  202                   }
  203       );
  204     my $basicInfoUrl = $self->systemLink($basicInfoPage,
  205                                          params =>{visible_users => $editForUserID,
  206                                                    editMode      => 1,
  207                                                   }
  208     );
  209 
  210   print CGI::h4({align=>'center'},"Edit ",CGI::a({href=>$basicInfoUrl},'class list data')," for  $userName ($editForUserID) who has been assigned $setCount sets.");
  211 
  212   #print CGI::h4("User Data");
  213 #   print CGI::start_table({ align=>'center', border=>1,cellpadding=>5});
  214 #   print CGI::Tr(
  215 #     CGI::th(CGI::checkbox({ type => 'checkbox',
  216 #                 name => "edit.basic.info",
  217 #                 label => '',
  218 #                             checked => 0
  219 #         }),"Edit class list data for $editForUserID"),
  220 #         CGI::th(CGI::checkbox({ type => 'checkbox',
  221 #                 name => "change.password",
  222 #                 label => '',
  223 #                             checked => 0
  224 #         }),"Change Password for $editForUserID"));
  225 #
  226 #   print "<tr><td rowspan=\"2\">";
  227 #   ########################################
  228 #   # Basic student data
  229 #   ########################################
  230 #   print CGI::start_table();
  231 #   foreach ($userTemplate->FIELDS()) {
  232 #     next if $_ eq 'user_id';   # don't print login name
  233 #     print CGI::Tr(
  234 #       CGI::td([
  235 #               $prettyFieldNames{$_},
  236 #         CGI::input({ -value => $UserRecord->$_, -size => 25 })
  237 #       ])
  238 #     );
  239 #   }
  240 #   foreach ($permissionLevelTemplate->FIELDS()) {
  241 #     print CGI::Tr(
  242 #       CGI::td([
  243 #               $prettyFieldNames{$_},
  244 #         CGI::input({ -value => $PermissionRecord->$_, -size => 25 })
  245 #       ])
  246 #     );
  247 #   }
  248 #   print CGI::end_table();
  249 #
  250 #   #print CGI::br();
  251 #   print "</td><td valign=\"top\">";
  252 #   ########################################
  253 #   # Change password section
  254 #   ########################################
  255 #   my $profRecord = $db->getUser($userID);
  256 #   my $profName = $profRecord->first_name . " " . $profRecord->last_name;
  257 #   my $poss = "'s ";
  258 #   my $pass = " password ";
  259 #
  260 #   print CGI::start_table();
  261 #   print CGI::Tr(CGI::td(["<b>$profName</b>$poss$pass", CGI::input({ -type => "password", -name => "$userID.password"})]));
  262 #   print CGI::Tr(CGI::td(["<b>$userName</b>$poss new $pass", CGI::input({ -type => "password", -name => "$editForUserID.password.1"})]));
  263 #   print CGI::Tr(CGI::td(["Confirm <b>$userName</b>$poss new $pass", CGI::input({ -type => "password", -name => "$editForUserID.password.2"})]));
  264 #   print CGI::end_table();
  265 #   print "</td></tr>";
  266 #   print CGI::Tr(CGI::th(  #FIXME  enable this once it can be handled
  267 # #     CGI::checkbox({ type => 'checkbox',
  268 # #                 name => "change.login",
  269 # #                 label => '',
  270 # #                             checked => 0
  271 # #         }),
  272 #         "Change login name $editForUserID to ", CGI::input({-name=>'new_login', -value=>''  ,-size=>25})
  273 #   ));
  274 #   print CGI::end_table();
  275 
  276   print CGI::br();
  277 
  278   #print CGI::h4("Sets assigned to $userName");
  279   # construct url for the form
  280   my $userDetailPage = $urlpath->new(type =>'instructor_user_detail',
  281                                  args =>{
  282                                          courseID => $courseID,
  283                                          userID   => $editForUserID, #FIXME eventually this should be a list??
  284                   }
  285   );
  286   my $userDetailUrl = $self->systemLink($userDetailPage,authen=>0);
  287 
  288   my %GlobalSetRecords = map { $_->set_id => $_ } $db->getGlobalSets($db->listGlobalSets());
  289   my @UserSetRefs = map { [$editForUserID, $_] } sortByName(undef, @UserSetIDs);
  290   my %UserSetRecords = map { $_->set_id => $_ } $db->getUserSets(@UserSetRefs);
  291   my @MergedSetRefs = map { [$editForUserID, $_] } sortByName(undef, @UserSetIDs);
  292   my %MergedSetRecords = map { $_->set_id => $_ } $db->getMergedSets(@MergedSetRefs);
  293 
  294   ########################################
  295   # Print warning
  296   ########################################
  297   print CGI::div({-class=>'ResultsWithError'},
  298            "Do not uncheck a set unless you know what you are doing.", CGI::br(),
  299            "There is NO undo for unassigning a set.");
  300 
  301   print CGI::p("To change status (scores or grades) for this student for one
  302                 set, click on the individual set link.");
  303 
  304   print CGI::div({-class=>'ResultsWithError'},"When you uncheck a homework set (and save the changes), you destroy all
  305           of the data for that set for this student.   If you
  306           reassign the set, the student will receive a new version of each problem.
  307           Make sure this is what you want to do before unchecking sets."
  308   );
  309   ########################################
  310   # Assigned sets form
  311   ########################################
  312 
  313   print CGI::start_form( {method=>'post',action=>$userDetailUrl, name=>'UserDetail'}),"\n";
  314   print $self->hidden_authen_fields();
  315   print CGI::p(CGI::submit(-name=>'save_button',-label=>'Save changes',));
  316 
  317   print CGI::start_table({ border=> 1,cellpadding=>5}),"\n";
  318   print CGI::Tr(
  319     CGI::th({align=>'center',colspan=>3}, "Sets assigned to $userName ($editForUserID)")
  320   ),"\n";
  321   print CGI::Tr(
  322     CGI::th({ -align => "center"}, [
  323       "Assigned",
  324       "Edit set for $editForUserID",
  325       "Dates",
  326     ])
  327   ),"\n";
  328   foreach my $setID (sortByName(undef, $db->listGlobalSets())) {
  329     my $GlobalSetRecord = $GlobalSetRecords{$setID};
  330     my $UserSetRecord = $UserSetRecords{$setID};
  331     my $MergedSetRecord = $MergedSetRecords{$setID};
  332     my $setListPage = $urlpath->new(type =>'instructor_set_detail',
  333           args =>{
  334             courseID => $courseID,
  335             setID    => $setID
  336                   }
  337       );
  338     my $url = $self->systemLink($setListPage,
  339                           params =>{effectiveUser => $editForUserID,
  340                                     editForUser   => $editForUserID,
  341     });
  342 
  343     print CGI::Tr(
  344       CGI::td({ -align => "center" }, [
  345         CGI::checkbox({ type => 'checkbox',
  346                 name => "set.$setID.assignment",
  347                 label => '',
  348                 value => 'assigned',
  349                             checked => (defined $MergedSetRecord)
  350                 }),
  351         defined($MergedSetRecord) ? CGI::b(CGI::a({href=>$url},$setID, ) ) : CGI::b($setID, ),
  352         join "\n", $self->DBFieldTable($GlobalSetRecord, $UserSetRecord, $MergedSetRecord, "set", $setID, \@dateFields,$rh_dateFieldLabels),
  353       ])
  354     ),"\n";
  355   }
  356   print CGI::end_table(),"\n";
  357   print CGI::p(CGI::submit(-name=>'save_button',-label=>'Save changes',));
  358   print CGI::end_form(),"\n";
  359   ########################################
  360   # Print warning
  361   ########################################
  362 
  363   CGI::div( {class=>'ResultsWithError'},
  364         "There is NO undo for this function.
  365          Do not use it unless you know what you are doing!  When you unassign
  366          sets using this button, or by unchecking their set names, you destroy all
  367          of the data for those sets for this student."
  368   );
  369 
  370 
  371 # print CGI::start_table();
  372 # print CGI::Tr(
  373 #   CGI::th({ -align => "center"},[
  374 #     "Assigned",
  375 #     "Set Name",
  376 #     "Opens",
  377 #     "Answers Due",
  378 #     "Answers Available",
  379 #   ])
  380 # );
  381 
  382 # foreach my $setID (sortByName(undef, @UserSetIDs)) {
  383 #   my $MergedSetRecord = $MergedSetRecords{$setID};
  384 #   print CGI::Tr(
  385 #     CGI::td({ -align => "center" }, [
  386 #       CGI::checkbox({checked => (defined $MergedSetRecord)}),
  387 #       $setID,
  388 #       CGI::checkbox() .
  389 #       CGI::input({ -value => $self->formatDateTime($MergedSetRecord->open_date), -size => 25}),
  390 #       CGI::checkbox() .
  391 #       CGI::input({ -value => $self->formatDateTime($MergedSetRecord->due_date), -size => 25}),
  392 #       CGI::checkbox() .
  393 #       CGI::input({ -value => $self->formatDateTime($MergedSetRecord->answer_date), -size => 25}),
  394 #     ])
  395 #   );
  396 # }
  397   return '';
  398 }
  399 
  400 sub checkDates {
  401   my $self         = shift;
  402   my $setRecord    = shift;
  403   my $setID        = shift;
  404   my $r            = $self->r;
  405   my %dates = ();
  406   my $error_undefined_override = 0;
  407   my $numerical_date=0;
  408   my $error        = 0;
  409   foreach my $field (@{DATE_FIELDS_ORDER()}) {  # check that override dates can be parsed and are not blank
  410     $dates{$field} = $setRecord->$field;
  411     if (defined  $r->param("set.$setID.$field.override") ){
  412       eval{ $numerical_date = $self->parseDateTime($r->param("set.$setID.$field"))};
  413       unless( $@  ) {
  414           $dates{$field}=$numerical_date;
  415       } else {
  416           $self->addbadmessage("&nbsp;&nbsp;* Badly defined time for set $setID $field. No date changes made:<br/>$@");
  417           $error = 1;
  418       }
  419     }
  420 
  421 
  422   }
  423   return {%dates,error=>1} if $error;    # no point in going on if the dates can't be parsed.
  424 
  425   my ($open_date, $due_date, $answer_date) = map { $dates{$_} } @{DATE_FIELDS_ORDER()};
  426 
  427   if ($answer_date < $due_date || $answer_date < $open_date) {
  428     $self->addbadmessage("Answers cannot be made available until on or after the due date in set $setID!");
  429     $error = 1;
  430   }
  431 
  432   if ($due_date < $open_date) {
  433     $self->addbadmessage("Answers cannot be due until on or after the open date in set $setID!");
  434     $error = 1;
  435   }
  436 
  437   # make sure the dates are not more than 10 years in the future
  438   my $curr_time = time;
  439   my $seconds_per_year = 31_556_926;
  440   my $cutoff = $curr_time + $seconds_per_year*10;
  441   if ($open_date > $cutoff) {
  442     $self->addbadmessage("Error: open date cannot be more than 10 years from now in set $setID");
  443     $error = 1;
  444   }
  445   if ($due_date > $cutoff) {
  446     $self->addbadmessage("Error: due date cannot be more than 10 years from now in set $setID");
  447     $error = 1;
  448   }
  449   if ($answer_date > $cutoff) {
  450     $self->addbadmessage("Error: answer date cannot be more than 10 years from now in set $setID");
  451     $error = 1;
  452   }
  453 
  454 
  455   if ($error) {
  456     $self->addbadmessage("No date changes were saved!");
  457   }
  458   return {%dates,error=>$error};
  459 }
  460 
  461 sub DBFieldTable {
  462   my ($self, $GlobalRecord, $UserRecord, $MergedRecord, $recordType, $recordID, $fieldsRef,$rh_fieldLabels) = @_;
  463 
  464   return CGI::div({class => "ResultsWithError"}, "No record exists for $recordType $recordID") unless defined $GlobalRecord;
  465 
  466   my $r = $self->r;
  467   my @fields = @$fieldsRef;
  468   my @results;
  469   foreach my $field (@fields) {
  470     my $globalValue = $GlobalRecord->$field;
  471     my $userValue = defined $UserRecord ? $UserRecord->$field : $globalValue;
  472     my $mergedValue  = defined $MergedRecord ? $MergedRecord->$field : $globalValue;
  473     push @results,
  474       [$rh_fieldLabels->{$field},
  475        defined $UserRecord ?
  476         CGI::checkbox({
  477           type => "checkbox",
  478           name => "$recordType.$recordID.$field.override",
  479           label => "",
  480           value => $field,
  481           checked => $r->param("$recordType.$recordID.$field.override") || ($mergedValue ne $globalValue ? 1 : 0)
  482         }) : "",
  483         defined $UserRecord ?
  484           (CGI::input({ -name=>"$recordType.$recordID.$field",
  485                         -value => $userValue ? $self->formatDateTime($userValue) : "",
  486                         -size => 25})
  487           ) : "",
  488         $self->formatDateTime($globalValue),
  489       ]
  490 
  491   }
  492 
  493   my @table;
  494   foreach my $row (@results) {
  495     push @table, CGI::Tr(CGI::td({-align => "center"}, $row));
  496   }
  497 
  498   return (CGI::start_table({border => 0}), @table, CGI::end_table());
  499 }
  500 
  501 1;

aubreyja at gmail dot com
ViewVC Help
Powered by ViewVC 1.0.9