[system] / branches / gage_dev / webwork2 / lib / WeBWorK / ContentGenerator / Instructor / ProblemSetDetail.pm Repository:
ViewVC logotype

Diff of /branches/gage_dev/webwork2/lib/WeBWorK/ContentGenerator/Instructor/ProblemSetDetail.pm

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

Revision 5709 Revision 5710
329 329
330 # needed for gateway output 330 # needed for gateway output
331 my $gwFields = ''; 331 my $gwFields = '';
332 # $isGWset will come in undef if we don't need to worry about it 332 # $isGWset will come in undef if we don't need to worry about it
333 $isGWset = 0 if ( ! defined( $isGWset ) ); 333 $isGWset = 0 if ( ! defined( $isGWset ) );
334 # are we editing a set version?
335 my $setVersion = (defined($userRecord) && $userRecord->can("version_id")) ? 1 : 0;
334 336
335 # needed for ip restrictions 337 # needed for ip restrictions
336 my $ipFields = ''; 338 my $ipFields = '';
337 my $ipDefaults; 339 my $ipDefaults;
338 my $numLocations = 0; 340 my $numLocations = 0;
362 my %properties = %{ FIELD_PROPERTIES()->{$field} }; 364 my %properties = %{ FIELD_PROPERTIES()->{$field} };
363 365
364 # we don't show the ip restriction option if there are 366 # we don't show the ip restriction option if there are
365 # no defined locations, nor the relax_restrict_ip option 367 # no defined locations, nor the relax_restrict_ip option
366 # if we're not restricting ip access 368 # if we're not restricting ip access
367 next if ( $field eq 'restrict_ip' && ! $numLocations ); 369 next if ( $field eq 'restrict_ip' && ( ! $numLocations || $setVersion ) );
368 next if ($field eq 'relax_restrict_ip' && 370 next if ($field eq 'relax_restrict_ip' &&
369 (! $numLocations || 371 (! $numLocations || $setVersion ||
370 ($forUsers && $userRecord->restrict_ip eq 'No') || 372 ($forUsers && $userRecord->restrict_ip eq 'No') ||
371 (! $forUsers && 373 (! $forUsers &&
372 ( $globalRecord->restrict_ip eq '' || 374 ( $globalRecord->restrict_ip eq '' ||
373 $globalRecord->restrict_ip eq 'No' ) ) ) ); 375 $globalRecord->restrict_ip eq 'No' ) ) ) );
374 376
601 603
602 # finally, figure out what ip selector fields we want to include 604 # finally, figure out what ip selector fields we want to include
603 my @locations = sort {$a cmp $b} ($db->listLocations()); 605 my @locations = sort {$a cmp $b} ($db->listLocations());
604 $numLocations = @locations; 606 $numLocations = @locations;
605 607
608 # we don't show ip selector fields if we're editing a set version
609 if ( defined( $userRecord ) && ! $userRecord->can("version_id") ) {
606 if ( ( ! $forUsers && $globalRecord->restrict_ip && 610 if ( ( ! $forUsers && $globalRecord->restrict_ip &&
607 $globalRecord->restrict_ip ne 'No' ) || 611 $globalRecord->restrict_ip ne 'No' ) ||
608 ( $forUsers && $userRecord->restrict_ip ne 'No' ) ) { 612 ( $forUsers && $userRecord->restrict_ip ne 'No' ) ) {
609 613
610 my @globalLocations = $db->listGlobalSetLocations($setID); 614 my @globalLocations = $db->listGlobalSetLocations($setID);
611 # what ip locations should be selected? 615 # what ip locations should be selected?
612 my @defaultLocations = (); 616 my @defaultLocations = ();
613 if ( $forUsers && 617 if ( $forUsers &&
614 ! $db->countUserSetLocations($userID, $setID) ) { 618 ! $db->countUserSetLocations($userID, $setID) ) {
615 @defaultLocations = @globalLocations; 619 @defaultLocations = @globalLocations;
616 $ipOverride = 0; 620 $ipOverride = 0;
617 } elsif ( $forUsers ) { 621 } elsif ( $forUsers ) {
618 @defaultLocations = $db->listUserSetLocations($userID, $setID); 622 @defaultLocations = $db->listUserSetLocations($userID, $setID);
619 $ipOverride = 1; 623 $ipOverride = 1;
620 } else { 624 } else {
621 @defaultLocations = @globalLocations; 625 @defaultLocations = @globalLocations;
622 } 626 }
623 my $ipDefaults = join(', ', @globalLocations); 627 my $ipDefaults = join(', ', @globalLocations);
624 628
625 my $ipSelector = CGI::scrolling_list({ 629 my $ipSelector = CGI::scrolling_list({
626 -name => "set.$setID.selected_ip_locations", 630 -name => "set.$setID.selected_ip_locations",
627 -values => [ @locations ], 631 -values => [ @locations ],
628 -default => [ @defaultLocations ], 632 -default => [ @defaultLocations ],
629 -size => 5, 633 -size => 5,
630 -multiple => 'true'}); 634 -multiple => 'true'});
631 635
632 my $override = ($forUsers) ? 636 my $override = ($forUsers) ?
633 CGI::checkbox({ type => "checkbox", 637 CGI::checkbox({ type => "checkbox",
634 name => "set.$setID.selected_ip_locations.override", 638 name => "set.$setID.selected_ip_locations.override",
635 label => "", 639 label => "",
636 checked => $ipOverride }) : ''; 640 checked => $ipOverride }) : '';
637 $ipFields .= CGI::Tr({-valign=>'top'}, 641 $ipFields .= CGI::Tr({-valign=>'top'},
638 CGI::td({}, [ $override, 642 CGI::td({}, [ $override,
639 'Restrict Locations', 643 'Restrict Locations',
640 $ipSelector, 644 $ipSelector,
641 $forUsers ? 645 $forUsers ?
642 " $ipDefaults" : '', ] 646 " $ipDefaults" : '', ]
643 ), 647 ),
644 ); 648 );
649 }
645 } 650 }
646 return($gwFields, $ipFields, $numLocations, $procFields); 651 return($gwFields, $ipFields, $numLocations, $procFields);
647} 652}
648 653
649sub proctoredFieldHTML { 654sub proctoredFieldHTML {
854 my $db = $r->db; 859 my $db = $r->db;
855 my $ce = $r->ce; 860 my $ce = $r->ce;
856 my $authz = $r->authz; 861 my $authz = $r->authz;
857 my $user = $r->param('user'); 862 my $user = $r->param('user');
858 my $setID = $r->urlpath->arg("setID"); 863 my $setID = $r->urlpath->arg("setID");
864
865 ## we're now allowing setID to come in as setID,v# to edit a set
866 ## version; catch this first
867 my $editingSetVersion = 0;
868 if ( $setID =~ /,v(\d+)$/ ) {
869 $editingSetVersion = $1;
870 $setID =~ s/,v(\d+)$//;
871 }
872
859 my $setRecord = $db->getGlobalSet($setID); # checked 873 my $setRecord = $db->getGlobalSet($setID); # checked
860 die "global set $setID not found." unless $setRecord; 874 die "global set $setID not found." unless $setRecord;
861 875
862 $self->{set} = $setRecord; 876 $self->{set} = $setRecord;
863 my @editForUser = $r->param('editForUser'); 877 my @editForUser = $r->param('editForUser');
867 881
868 # Check permissions 882 # Check permissions
869 return unless ($authz->hasPermissions($user, "access_instructor_tools")); 883 return unless ($authz->hasPermissions($user, "access_instructor_tools"));
870 return unless ($authz->hasPermissions($user, "modify_problem_sets")); 884 return unless ($authz->hasPermissions($user, "modify_problem_sets"));
871 885
886 ## if we're editing a versioned set, it only makes sense to be
887 ## editing it for one user
888 return if ( $editingSetVersion && ! $forOneUser );
872 889
873 my %properties = %{ FIELD_PROPERTIES() }; 890 my %properties = %{ FIELD_PROPERTIES() };
874 891
875 # takes a hash of hashes and inverts it 892 # takes a hash of hashes and inverts it
876 my %undoLabels; 893 my %undoLabels;
952 # not the most robust treatment of the problem 969 # not the most robust treatment of the problem
953 # (FIXME) 970 # (FIXME)
954 971
955 # DBFIXME use a WHERE clause, iterator 972 # DBFIXME use a WHERE clause, iterator
956 my @userRecords = $db->getUserSets(map { [$_, $setID] } @editForUser); 973 my @userRecords = $db->getUserSets(map { [$_, $setID] } @editForUser);
974 # if we're editing a set version, we want to edit
975 # edit that instead of the userset, so get it
976 # too.
977 my $userSet = $userRecords[0];
978 my $setVersion = 0;
979 if ( $editingSetVersion ) {
980 $setVersion =
981 $db->getSetVersion($editForUser[0],
982 $setID,
983 $editingSetVersion);
984 @userRecords = ( $setVersion );
985 }
986
957 foreach my $record (@userRecords) { 987 foreach my $record (@userRecords) {
958 foreach my $field ( @{ SET_FIELDS() } ) { 988 foreach my $field ( @{ SET_FIELDS() } ) {
959 next unless canChange($forUsers, $field); 989 next unless canChange($forUsers, $field);
960 my $override = $r->param("set.$setID.$field.override"); 990 my $override = $r->param("set.$setID.$field.override");
961 991
1004 # $set->hide_score_by_problem eq 'N' 1034 # $set->hide_score_by_problem eq 'N'
1005 # if ( $record->hide_score eq 'N' ) { 1035 # if ( $record->hide_score eq 'N' ) {
1006 # $record->hide_score_by_problem('N'); 1036 # $record->hide_score_by_problem('N');
1007 # } 1037 # }
1008 #################### 1038 ####################
1039 if ( $editingSetVersion ) {
1040 $db->putSetVersion( $record );
1041 } else {
1009 $db->putUserSet($record); 1042 $db->putUserSet($record);
1043 }
1010 } 1044 }
1011 1045
1012 ####################################################### 1046 #######################################################
1013 # Save IP restriction Location information 1047 # Save IP restriction Location information
1014 ####################################################### 1048 #######################################################
1015 # FIXME: it would be nice to have this in the field values 1049 # FIXME: it would be nice to have this in the field values
1016 # hash, so that we don't have to assume that we can 1050 # hash, so that we don't have to assume that we can
1017 # override this information for users 1051 # override this information for users
1018 1052
1053 ## should we allow resetting set locations for set versions? this
1054 ## requires either putting in a new set of database routines
1055 ## to deal with the versioned setID, or fudging it at this end
1056 ## by manually putting in the versioned ID setID,v#. neither
1057 ## of these seems desirable, so for now it's not allowed
1058 if ( ! $editingSetVersion ) {
1019 if ( $r->param("set.$setID.selected_ip_locations.override") ) { 1059 if ( $r->param("set.$setID.selected_ip_locations.override") ) {
1020 foreach my $record ( @userRecords ) { 1060 foreach my $record ( @userRecords ) {
1021 my $userID = $record->user_id; 1061 my $userID = $record->user_id;
1022 my @selectedLocations = $r->param("set.$setID.selected_ip_locations"); 1062 my @selectedLocations = $r->param("set.$setID.selected_ip_locations");
1023 my @userSetLocations = $db->listUserSetLocations($userID,$setID); 1063 my @userSetLocations = $db->listUserSetLocations($userID,$setID);
1024 my @addSetLocations = (); 1064 my @addSetLocations = ();
1025 my @delSetLocations = (); 1065 my @delSetLocations = ();
1026 foreach my $loc ( @selectedLocations ) { 1066 foreach my $loc ( @selectedLocations ) {
1027 push( @addSetLocations, $loc ) if ( ! grep( /^$loc$/, @userSetLocations ) ); 1067 push( @addSetLocations, $loc ) if ( ! grep( /^$loc$/, @userSetLocations ) );
1068 }
1069 foreach my $loc ( @userSetLocations ) {
1070 push( @delSetLocations, $loc ) if ( ! grep( /^$loc$/, @selectedLocations ) );
1071 }
1072 # then update the user set_locations
1073 foreach ( @addSetLocations ) {
1074 my $Loc = $db->newUserSetLocation;
1075 $Loc->set_id( $setID );
1076 $Loc->user_id( $userID );
1077 $Loc->location_id($_);
1078 $db->addUserSetLocation($Loc);
1079 }
1080 foreach ( @delSetLocations ) {
1081 $db->deleteUserSetLocation($userID,$setID,$_);
1082 }
1028 } 1083 }
1029 foreach my $loc ( @userSetLocations ) {
1030 push( @delSetLocations, $loc ) if ( ! grep( /^$loc$/, @selectedLocations ) );
1031 }
1032 # then update the user set_locations
1033 foreach ( @addSetLocations ) {
1034 my $Loc = $db->newUserSetLocation;
1035 $Loc->set_id( $setID );
1036 $Loc->user_id( $userID );
1037 $Loc->location_id($_);
1038 $db->addUserSetLocation($Loc);
1039 }
1040 foreach ( @delSetLocations ) {
1041 $db->deleteUserSetLocation($userID,$setID,$_);
1042 }
1043 }
1044 } else { 1084 } else {
1045 # if override isn't selected, then we want 1085 # if override isn't selected, then we want
1046 # to be sure that there are no 1086 # to be sure that there are no
1047 # set_locations_user entries setting around 1087 # set_locations_user entries setting around
1048 foreach my $record ( @userRecords ) { 1088 foreach my $record ( @userRecords ) {
1049 my $userID = $record->user_id; 1089 my $userID = $record->user_id;
1050 my @userLocations = $db->listUserSetLocations($userID,$setID); 1090 my @userLocations = $db->listUserSetLocations($userID,$setID);
1051 foreach ( @userLocations ) { 1091 foreach ( @userLocations ) {
1052 $db->deleteUserSetLocation($userID,$setID,$_); 1092 $db->deleteUserSetLocation($userID,$setID,$_);
1093 }
1053 } 1094 }
1054 } 1095 }
1055 } 1096 }
1056 } else { 1097 } else {
1057 foreach my $field ( @{ SET_FIELDS() } ) { 1098 foreach my $field ( @{ SET_FIELDS() } ) {
1224 # Since we're editing for specific users, we don't allow the GlobalProblem record to be altered on that same page 1265 # Since we're editing for specific users, we don't allow the GlobalProblem record to be altered on that same page
1225 # So we only need to make changes to the UserProblem record and only then if we are overriding a value 1266 # So we only need to make changes to the UserProblem record and only then if we are overriding a value
1226 # in the GlobalProblem record or for fields unique to the UserProblem record. 1267 # in the GlobalProblem record or for fields unique to the UserProblem record.
1227 1268
1228 my @userIDs = @editForUser; 1269 my @userIDs = @editForUser;
1270
1271 my @userProblemRecords;
1272 if ( ! $editingSetVersion ) {
1229 my @userProblemIDs = map { [$_, $setID, $problemID] } @userIDs; 1273 my @userProblemIDs = map { [$_, $setID, $problemID] } @userIDs;
1230 # DBFIXME where clause? iterator? 1274 # DBFIXME where clause? iterator?
1231 my @userProblemRecords = $db->getUserProblems(@userProblemIDs); 1275 @userProblemRecords = $db->getUserProblems(@userProblemIDs);
1276 } else {
1277 ## (we know that we're only editing for one user)
1278 @userProblemRecords =
1279 ( $db->getMergedProblemVersion( $userIDs[0], $setID, $editingSetVersion, $problemID ) );
1280 }
1281
1232 foreach my $record (@userProblemRecords) { 1282 foreach my $record (@userProblemRecords) {
1233 1283
1234 my $changed = 0; # keep track of any changes, if none are made, avoid unnecessary db accesses 1284 my $changed = 0; # keep track of any changes, if none are made, avoid unnecessary db accesses
1235 foreach my $field ( @{ PROBLEM_FIELDS() } ) { 1285 foreach my $field ( @{ PROBLEM_FIELDS() } ) {
1236 next unless canChange($forUsers, $field); 1286 next unless canChange($forUsers, $field);
1259 my $unlabel = $undoLabels{$field}->{$param}; 1309 my $unlabel = $undoLabels{$field}->{$param};
1260 $param = $unlabel if defined $unlabel; 1310 $param = $unlabel if defined $unlabel;
1261 $changed ||= changed($record->$field, $param); 1311 $changed ||= changed($record->$field, $param);
1262 $record->$field($param); 1312 $record->$field($param);
1263 } 1313 }
1314 if ( ! $editingSetVersion ) {
1264 $db->putUserProblem($record) if $changed; 1315 $db->putUserProblem($record) if $changed;
1316 } else {
1317 $db->putProblemVersion($record) if $changed;
1318 }
1265 } 1319 }
1266 } else { 1320 } else {
1267 # Since we're editing for ALL set users, we will make changes to the GlobalProblem record. 1321 # Since we're editing for ALL set users, we will make changes to the GlobalProblem record.
1268 # We may also have instances where a field is unique to the UserProblem record but we want 1322 # We may also have instances where a field is unique to the UserProblem record but we want
1269 # all users to (at least initially) have the same value 1323 # all users to (at least initially) have the same value
1318 } 1372 }
1319 } 1373 }
1320 } 1374 }
1321 } 1375 }
1322 1376
1323 # Mark the specified problems as correct for all users 1377 # Mark the specified problems as correct for all users (not applicable when editing a set
1378 # version, because this only shows up when editing for users or editing the
1379 # global set/problem, not for one user)
1324 foreach my $problemID ($r->param('markCorrect')) { 1380 foreach my $problemID ($r->param('markCorrect')) {
1325 # DBFIXME where clause, iterator 1381 # DBFIXME where clause, iterator
1326 my @userProblemIDs = map { [$_, $setID, $problemID] } ($forUsers ? @editForUser : $db->listProblemUsers($setID, $problemID)); 1382 my @userProblemIDs = map { [$_, $setID, $problemID] } ($forUsers ? @editForUser : $db->listProblemUsers($setID, $problemID));
1327 # if the set is not a gateway set, this requires going through the 1383 # if the set is not a gateway set, this requires going through the
1328 # user_problems and resetting their status; if it's a gateway set, 1384 # user_problems and resetting their status; if it's a gateway set,
1355 } 1411 }
1356 } 1412 }
1357 } 1413 }
1358 } 1414 }
1359 1415
1360 # Delete all problems marked for deletion 1416 # Delete all problems marked for deletion (not applicable when editing
1417 # for users)
1361 foreach my $problemID ($r->param('deleteProblem')) { 1418 foreach my $problemID ($r->param('deleteProblem')) {
1362 $db->deleteGlobalProblem($setID, $problemID); 1419 $db->deleteGlobalProblem($setID, $problemID);
1363 } 1420 }
1364 1421
1365 ##################################################################### 1422 #####################################################################
1521 my $authz = $r->authz; 1578 my $authz = $r->authz;
1522 my $userID = $r->param('user'); 1579 my $userID = $r->param('user');
1523 my $urlpath = $r->urlpath; 1580 my $urlpath = $r->urlpath;
1524 my $courseID = $urlpath->arg("courseID"); 1581 my $courseID = $urlpath->arg("courseID");
1525 my $setID = $urlpath->arg("setID"); 1582 my $setID = $urlpath->arg("setID");
1583
1584 ## we're now allowing setID to come in as setID,v# to edit a set
1585 ## version; catch this first
1586 my $editingSetVersion = 0;
1587 my $fullSetID = $setID;
1588 if ( $setID =~ /,v(\d+)$/ ) {
1589 $editingSetVersion = $1;
1590 $setID =~ s/,v(\d+)$//;
1591 }
1592
1526 my $setRecord = $db->getGlobalSet($setID) or die "No record for global set $setID."; 1593 my $setRecord = $db->getGlobalSet($setID) or die "No record for global set $setID.";
1527 1594
1528 my $userRecord = $db->getUser($userID) or die "No record for user $userID."; 1595 my $userRecord = $db->getUser($userID) or die "No record for user $userID.";
1529 # Check permissions 1596 # Check permissions
1530 return CGI::div({class=>"ResultsWithError"}, "You are not authorized to access the Instructor tools.") 1597 return CGI::div({class=>"ResultsWithError"}, "You are not authorized to access the Instructor tools.")
1532 1599
1533 return CGI::div({class=>"ResultsWithError"}, "You are not authorized to modify problems.") 1600 return CGI::div({class=>"ResultsWithError"}, "You are not authorized to modify problems.")
1534 unless $authz->hasPermissions($userRecord->user_id, "modify_problem_sets"); 1601 unless $authz->hasPermissions($userRecord->user_id, "modify_problem_sets");
1535 1602
1536 my @editForUser = $r->param('editForUser'); 1603 my @editForUser = $r->param('editForUser');
1604
1605 return CGI::div({class=>"ResultsWithError"}, "Versions of a set can only be " .
1606 "edited for one user at a time.") if ( $editingSetVersion && @editForUser != 1 );
1537 1607
1538 # Check that every user that we're editing for has a valid UserSet 1608 # Check that every user that we're editing for has a valid UserSet
1539 my @assignedUsers; 1609 my @assignedUsers;
1540 my @unassignedUsers; 1610 my @unassignedUsers;
1541 if (scalar @editForUser) { 1611 if (scalar @editForUser) {
1555 } elsif (scalar @editForUser == 0) { 1625 } elsif (scalar @editForUser == 0) {
1556 print CGI::div({class=>"ResultsWithError"}, "None of the selected users are assigned to this set: " . CGI::b(join(", ", @unassignedUsers))); 1626 print CGI::div({class=>"ResultsWithError"}, "None of the selected users are assigned to this set: " . CGI::b(join(", ", @unassignedUsers)));
1557 print CGI::div({class=>"ResultsWithError"}, "Global set data will be shown instead of user specific data"); 1627 print CGI::div({class=>"ResultsWithError"}, "Global set data will be shown instead of user specific data");
1558 } 1628 }
1559 } 1629 }
1560 1630
1561 # some useful booleans 1631 # some useful booleans
1562 my $forUsers = scalar(@editForUser); 1632 my $forUsers = scalar(@editForUser);
1563 my $forOneUser = $forUsers == 1; 1633 my $forOneUser = $forUsers == 1;
1634
1635 # and check that if we're editing a set version for a user, that
1636 # it exists as well
1637 if ( $editingSetVersion && ! $db->existsSetVersion( $editForUser[0], $setID, $editingSetVersion ) ) {
1638 return CGI::div({class=>"ResultsWithError"}, "The set-version ($setID, version $editingSetVersion) is not assigned to user $editForUser[0].");
1639 }
1564 1640
1565 # If you're editing for users, initially their records will be different but 1641 # If you're editing for users, initially their records will be different but
1566 # if you make any changes to them they will be the same. 1642 # if you make any changes to them they will be the same.
1567 # if you're editing for one user, the problems shown should be his/hers 1643 # if you're editing for one user, the problems shown should be his/hers
1568 my $userToShow = $forUsers ? $editForUser[0] : $userID; 1644 my $userToShow = $forUsers ? $editForUser[0] : $userID;
1572 1648
1573 # DBFIXME no need to get ID lists -- counts would be fine 1649 # DBFIXME no need to get ID lists -- counts would be fine
1574 my $userCount = $db->listUsers(); 1650 my $userCount = $db->listUsers();
1575 my $setCount = $db->listGlobalSets(); # if $forOneUser; 1651 my $setCount = $db->listGlobalSets(); # if $forOneUser;
1576 my $setUserCount = $db->countSetUsers($setID); 1652 my $setUserCount = $db->countSetUsers($setID);
1577 my $userSetCount = $db->countUserSets($editForUser[0]) if $forOneUser; 1653# if $forOneUser;
1654 my $userSetCount = ($forOneUser && @editForUser) ? $db->countUserSets($editForUser[0]) : 0;
1578 1655
1579 1656
1580 my $editUsersAssignedToSetURL = $self->systemLink( 1657 my $editUsersAssignedToSetURL = $self->systemLink(
1581 $urlpath->newFromModule( 1658 $urlpath->newFromModule(
1582 "WeBWorK::ContentGenerator::Instructor::UsersAssignedToSet", 1659 "WeBWorK::ContentGenerator::Instructor::UsersAssignedToSet",
1586 "WeBWorK::ContentGenerator::Instructor::UserDetail", 1663 "WeBWorK::ContentGenerator::Instructor::UserDetail",
1587 courseID => $courseID, userID => $editForUser[0])) if $forOneUser; 1664 courseID => $courseID, userID => $editForUser[0])) if $forOneUser;
1588 1665
1589 1666
1590 my $setDetailPage = $urlpath -> newFromModule($urlpath->module, courseID => $courseID, setID => $setID); 1667 my $setDetailPage = $urlpath -> newFromModule($urlpath->module, courseID => $courseID, setID => $setID);
1668 my $fullsetDetailPage = $urlpath -> newFromModule($urlpath->module, courseID => $courseID, setID => $fullSetID);
1591 my $setDetailURL = $self->systemLink($setDetailPage, authen=>0); 1669 my $setDetailURL = $self->systemLink($fullsetDetailPage, authen=>0);
1592
1593 1670
1594 my $userCountMessage = CGI::a({href=>$editUsersAssignedToSetURL}, $self->userCountMessage($setUserCount, $userCount)); 1671 my $userCountMessage = CGI::a({href=>$editUsersAssignedToSetURL}, $self->userCountMessage($setUserCount, $userCount));
1595 my $setCountMessage = CGI::a({href=>$editSetsAssignedToUserURL}, $self->setCountMessage($userSetCount, $setCount)) if $forOneUser; 1672 my $setCountMessage = CGI::a({href=>$editSetsAssignedToUserURL}, $self->setCountMessage($userSetCount, $setCount)) if $forOneUser;
1596 1673
1597 $userCountMessage = "The set $setID is assigned to " . $userCountMessage . "."; 1674 $userCountMessage = "The set $setID is assigned to " . $userCountMessage . ".";
1601 ############################################## 1678 ##############################################
1602 # calculate links for the users being edited: 1679 # calculate links for the users being edited:
1603 ############################################## 1680 ##############################################
1604 my @userLinks = (); 1681 my @userLinks = ();
1605 foreach my $userID (@editForUser) { 1682 foreach my $userID (@editForUser) {
1606 my $u = $db->getUser($userID); 1683 my $u = $db->getUser($userID);
1607 my $email_address = $u->email_address; 1684 my $email_address = $u->email_address;
1608 my $line = $u->last_name.", ".$u->first_name."  (".CGI::a({-href=>"mailto:$email_address"},"email "). $u->user_id."). Assigned to "; 1685 my $line = $u->last_name.", " . $u->first_name . "  (" .
1686 CGI::a({-href=>"mailto:$email_address"},"email "). $u->user_id .
1687 "). ";
1688 if ( ! $editingSetVersion ) {
1689 $line .= "Assigned to ";
1609 my $editSetsAssignedToUserURL = $self->systemLink( 1690 my $editSetsAssignedToUserURL = $self->systemLink(
1610 $urlpath->newFromModule( 1691 $urlpath->newFromModule(
1611 "WeBWorK::ContentGenerator::Instructor::UserDetail", 1692 "WeBWorK::ContentGenerator::Instructor::UserDetail",
1612 courseID => $courseID, userID => $u->user_id)); 1693 courseID => $courseID, userID => $u->user_id));
1613 $line .= CGI::a({href=>$editSetsAssignedToUserURL}, 1694 $line .= CGI::a({href=>$editSetsAssignedToUserURL},
1614 $self->setCountMessage($db->countUserSets($u->user_id), $setCount)); 1695 $self->setCountMessage($db->countUserSets($u->user_id),
1696 $setCount));
1697 } else {
1698 my $editSetLink = $self->systemLink( $setDetailPage,
1699 params=>{effectiveUser=>$u->user_id,
1700 editForUser =>$u->user_id} );
1701 $line .= "Edit set " . CGI::a({href=>$editSetLink},$setID) .
1702 " for this user.";
1703 }
1615 unshift @userLinks,$line; 1704 unshift @userLinks,$line;
1616 } 1705 }
1617 @userLinks = sort @userLinks; 1706 @userLinks = sort @userLinks;
1618 1707
1708 # handy messages when editing gateway sets
1709 my $gwmsg = ( $isGatewaySet && ! $editingSetVersion ) ?
1710 CGI::br() . CGI::em("To edit a specific student version of this set, " .
1711 "edit (all of) her/his assigned sets.") : "";
1712 my $vermsg = ( $editingSetVersion ) ? ", test $editingSetVersion" : "";
1713
1619 print CGI::table({border=>2,cellpadding=>10}, 1714 print CGI::table({border=>2,cellpadding=>10},
1620 CGI::Tr({}, 1715 CGI::Tr({},
1621 CGI::td([ 1716 CGI::td([
1622 "Editing problem set ".CGI::strong($setID)." data for these individual students:".CGI::br(). 1717 "Editing problem set ".CGI::strong($setID . $vermsg)." data for these individual students:".CGI::br().
1623 CGI::strong(join CGI::br(), @userLinks), 1718 CGI::strong(join CGI::br(), @userLinks),
1624 CGI::a({href=>$self->systemLink($setDetailPage) },"Edit set ".CGI::strong($setID)." data for ALL students assigned to this set."), 1719 CGI::a({href=>$self->systemLink($setDetailPage) },"Edit set ".CGI::strong($setID)." data for ALL students assigned to this set.") . $gwmsg,
1625 1720
1626 ]) 1721 ])
1627 ) 1722 )
1628 ); 1723 );
1629 } else { 1724 } else {
1711 1806
1712 # this is kind of a hack -- we need to get a user record here, so we can 1807 # this is kind of a hack -- we need to get a user record here, so we can
1713 # pass it to FieldTable, so FieldTable can pass it to FieldHTML, so 1808 # pass it to FieldTable, so FieldTable can pass it to FieldHTML, so
1714 # FieldHTML doesn't have to fetch it itself. 1809 # FieldHTML doesn't have to fetch it itself.
1715 my $userSetRecord = $db->getUserSet($userToShow, $setID); 1810 my $userSetRecord = $db->getUserSet($userToShow, $setID);
1811
1812 my $templateUserSetRecord;
1813 # send in the set version if we're editing for versions
1814 if ( $editingSetVersion ) {
1815 $templateUserSetRecord = $userSetRecord;
1816 $userSetRecord = $db->getSetVersion( $userToShow, $setID, $editingSetVersion );
1817 }
1716 1818
1717 print CGI::Tr({}, CGI::td({}, [ 1819 print CGI::Tr({}, CGI::td({}, [
1718 $self->FieldTable($userToShow, $setID, undef, $setRecord, $userSetRecord), 1820 $self->FieldTable($userToShow, $setID, undef, $setRecord, $userSetRecord),
1719 ])); 1821 ]));
1720 print CGI::end_table(); 1822 print CGI::end_table();
1850 my (%UserProblems, %MergedProblems); 1952 my (%UserProblems, %MergedProblems);
1851 if ($forOneUser) { 1953 if ($forOneUser) {
1852 my @userKeypartsRef = map { [$editForUser[0], $setID, $_] } @problemIDList; 1954 my @userKeypartsRef = map { [$editForUser[0], $setID, $_] } @problemIDList;
1853 # DBFIXME shouldn't need to get key list here 1955 # DBFIXME shouldn't need to get key list here
1854 @UserProblems{@problemIDList} = $db->getUserProblems(@userKeypartsRef); 1956 @UserProblems{@problemIDList} = $db->getUserProblems(@userKeypartsRef);
1957 if ( ! $editingSetVersion ) {
1855 @MergedProblems{@problemIDList} = $db->getMergedProblems(@userKeypartsRef); 1958 @MergedProblems{@problemIDList} = $db->getMergedProblems(@userKeypartsRef);
1959 } else {
1960 my @userversionKeypartsRef = map { [$editForUser[0], $setID, $editingSetVersion, $_] } @problemIDList;
1961 @MergedProblems{@problemIDList} = $db->getMergedProblemVersions(@userversionKeypartsRef);
1962 }
1856 } 1963 }
1857 1964
1858 if (scalar @problemIDList) { 1965 if (scalar @problemIDList) {
1859 1966
1860 print CGI::start_table({border=>1, cellpadding=>4}); 1967 print CGI::start_table({border=>1, cellpadding=>4});
1877 $problemRecord = $MergedProblems{$problemID}; # already fetched above --sam 1984 $problemRecord = $MergedProblems{$problemID}; # already fetched above --sam
1878 } else { 1985 } else {
1879 #$problemRecord = $db->getGlobalProblem($setID, $problemID); 1986 #$problemRecord = $db->getGlobalProblem($setID, $problemID);
1880 $problemRecord = $GlobalProblems{$problemID}; # already fetched above --sam 1987 $problemRecord = $GlobalProblems{$problemID}; # already fetched above --sam
1881 } 1988 }
1882 1989
1883 #$self->addgoodmessage(""); 1990 #$self->addgoodmessage("");
1884 #$self->addbadmessage($problemRecord->toString()); 1991 #$self->addbadmessage($problemRecord->toString());
1885 1992
1886 1993 # when we're editing a set version, we want to be sure to
1994 # use the merged problem in the edit, because we could
1995 # be using problem groups (for which the problem is generated
1996 # and then stored in the problem version)
1997 my $problemToShow = ( $editingSetVersion ) ?
1998 $MergedProblems{$problemID} : $UserProblems{$problemID};
1999
1887 my $editProblemPage = $urlpath->new(type => 'instructor_problem_editor_withset_withproblem', args => { courseID => $courseID, setID => $setID, problemID => $problemID }); 2000 my $editProblemPage = $urlpath->new(type => 'instructor_problem_editor_withset_withproblem', args => { courseID => $courseID, setID => $fullSetID, problemID => $problemID });
1888 my $editProblemLink = $self->systemLink($editProblemPage, params => { make_local_copy => 0 }); 2001 my $editProblemLink = $self->systemLink($editProblemPage, params => { make_local_copy => 0 });
1889 2002
1890 2003
1891 # FIXME: should we have an "act as" type link here when editing for multiple users? 2004 # FIXME: should we have an "act as" type link here when editing for multiple users?
1892 my $viewProblemPage = $urlpath->new(type => 'problem_detail', args => { courseID => $courseID, setID => $setID, problemID => $problemID }); 2005 my $viewProblemPage = $urlpath->new(type => 'problem_detail', args => { courseID => $courseID, setID => $setID, problemID => $problemID });
1933 CGI::Tr({}, CGI::td({}, CGI::a({href => $viewProblemLink, target=>"WW_View"}, "Try it" . ($forOneUser ? " (as $editForUser[0])" : "")))) . 2046 CGI::Tr({}, CGI::td({}, CGI::a({href => $viewProblemLink, target=>"WW_View"}, "Try it" . ($forOneUser ? " (as $editForUser[0])" : "")))) .
1934 ($forUsers ? "" : CGI::Tr({}, CGI::td({}, CGI::checkbox({name => "deleteProblem", value => $problemID, label => "Delete it?"})))) . 2047 ($forUsers ? "" : CGI::Tr({}, CGI::td({}, CGI::checkbox({name => "deleteProblem", value => $problemID, label => "Delete it?"})))) .
1935# CGI::Tr({}, CGI::td({}, "Delete it?" . CGI::input({type => "checkbox", name => "deleteProblem", value => $problemID}))) . 2048# CGI::Tr({}, CGI::td({}, "Delete it?" . CGI::input({type => "checkbox", name => "deleteProblem", value => $problemID}))) .
1936 ($forOneUser ? "" : CGI::Tr({}, CGI::td({}, CGI::checkbox({name => "markCorrect", value => $problemID, label => "Mark Correct?"})))) . 2049 ($forOneUser ? "" : CGI::Tr({}, CGI::td({}, CGI::checkbox({name => "markCorrect", value => $problemID, label => "Mark Correct?"})))) .
1937 CGI::end_table(), 2050 CGI::end_table(),
1938 $self->FieldTable($userToShow, $setID, $problemID, $GlobalProblems{$problemID}, $UserProblems{$problemID}, $isGatewaySet), 2051 $self->FieldTable($userToShow, $setID, $problemID, $GlobalProblems{$problemID}, $problemToShow, $isGatewaySet),
1939# A comprehensive list of problems is just TOO big to be handled well 2052# A comprehensive list of problems is just TOO big to be handled well
1940# comboBox({ 2053# comboBox({
1941# name => "set.$setID.$problemID", 2054# name => "set.$setID.$problemID",
1942# request => $r, 2055# request => $r,
1943# default => $problemRecord->{problem_id}, 2056# default => $problemRecord->{problem_id},
1948 join ("\n", $self->FieldHTML( 2061 join ("\n", $self->FieldHTML(
1949 $userToShow, 2062 $userToShow,
1950 $setID, 2063 $setID,
1951 $problemID, 2064 $problemID,
1952 $GlobalProblems{$problemID}, # pass previously fetched global record to FieldHTML --sam 2065 $GlobalProblems{$problemID}, # pass previously fetched global record to FieldHTML --sam
1953 $UserProblems{$problemID}, # pass previously fetched user record to FieldHTML --sam 2066 $problemToShow, # pass previously fetched user record to FieldHTML --sam
1954 "source_file" 2067 "source_file"
1955 )) . 2068 )) .
1956 CGI::br() . 2069 CGI::br() .
1957 ($error ? 2070 ($error ?
1958 CGI::div({class=>"ResultsWithError", style=>"font-weight: bold"}, $error) 2071 CGI::div({class=>"ResultsWithError", style=>"font-weight: bold"}, $error)
1978 print CGI::p("When changing problem numbers, we will move the problem to be ". CGI::em("before"). " the chosen number."); 2091 print CGI::p("When changing problem numbers, we will move the problem to be ". CGI::em("before"). " the chosen number.");
1979 2092
1980 } else { 2093 } else {
1981 print CGI::p(CGI::b("This set doesn't contain any problems yet.")); 2094 print CGI::p(CGI::b("This set doesn't contain any problems yet."));
1982 } 2095 }
1983 # always allow one to add a new problem. 2096 # always allow one to add a new problem, unless we're editing a set version
1984 print CGI::checkbox({ 2097 if ( ! $editingSetVersion ) {
1985 label=> "Add", 2098 print CGI::checkbox({ label=> "Add",
1986 name=>"add_blank_problem", value=>"1"} 2099 name=>"add_blank_problem", value=>"1"}
1987 ),CGI::input({ 2100 ),CGI::input({
1988 name=>"add_n_problems", 2101 name=>"add_n_problems",
1989 size=>2, 2102 size=>2,
1990 value=>1 2103 value=>1 },
1991 },
1992 "blank problem template(s) to end of homework set" 2104 "blank problem template(s) to end of homework set"
1993 ), 2105 );
2106 }
1994 CGI::br(),CGI::br(), 2107 print CGI::br(),CGI::br(),
1995 CGI::input({type=>"submit", name=>"submit_changes", value=>"Save Changes"}), 2108 CGI::input({type=>"submit", name=>"submit_changes", value=>"Save Changes"}),
1996 CGI::input({type=>"submit", name=>"handle_numbers", value=>"Reorder problems only"}), 2109 CGI::input({type=>"submit", name=>"handle_numbers", value=>"Reorder problems only"}),
1997 "(Any unsaved changes will be lost.)" 2110 "(Any unsaved changes will be lost.)";
1998 ;
1999 2111
2000
2001
2002 #my $editNewProblemPage = $urlpath->new(type => 'instructor_problem_editor_withset_withproblem', args => { courseID => $courseID, setID => $setID, problemID =>'new_problem' }); 2112 #my $editNewProblemPage = $urlpath->new(type => 'instructor_problem_editor_withset_withproblem', args => { courseID => $courseID, setID => $setID, problemID =>'new_problem' });
2003 #my $editNewProblemLink = $self->systemLink($editNewProblemPage, params => { make_local_copy => 1, file_type => 'blank_problem' }); 2113 #my $editNewProblemLink = $self->systemLink($editNewProblemPage, params => { make_local_copy => 1, file_type => 'blank_problem' });
2004 # This next feature isn't fully supported and is causing problems. Remove for now. #FIXME 2114 # This next feature isn't fully supported and is causing problems. Remove for now. #FIXME
2005 #print CGI::p( CGI::a({href=>$editNewProblemLink},'Edit'). ' a new blank problem'); 2115 #print CGI::p( CGI::a({href=>$editNewProblemLink},'Edit'). ' a new blank problem');
2006 2116

Legend:
Removed from v.5709  
changed lines
  Added in v.5710

aubreyja at gmail dot com
ViewVC Help
Powered by ViewVC 1.0.9