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

View of /branches/rel-2-2-dev/webwork2/lib/WeBWorK/ContentGenerator/Instructor/UserDetail.pm

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3972 - (download) (as text) (annotate)
Wed Jan 25 23:12:05 2006 UTC (7 years, 3 months ago) by sh002i
File size: 17455 byte(s)
update copyright date range -- 2000-2006. this is probably overkill,
since there are some files that were created after 2000 and some files
that were last modified before 2006.

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

aubreyja at gmail dot com
ViewVC Help
Powered by ViewVC 1.0.9