[system] / trunk / webwork2 / lib / WeBWorK / ContentGenerator / Instructor / UserList.pm Repository:
ViewVC logotype

Annotation of /trunk/webwork2/lib/WeBWorK/ContentGenerator/Instructor/UserList.pm

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1597 - (view) (download) (as text)

1 : sh002i 1567 ################################################################################
2 :     # WeBWorK mod_perl (c) 2000-2002 WeBWorK Project
3 :     # $Id$
4 :     ################################################################################
5 :    
6 : malsyned 832 package WeBWorK::ContentGenerator::Instructor::UserList;
7 :     use base qw(WeBWorK::ContentGenerator::Instructor);
8 :    
9 :     =head1 NAME
10 :    
11 : sh002i 1567 WeBWorK::ContentGenerator::Instructor::UserList - Entry point for User-specific
12 :     data editing
13 : malsyned 832
14 :     =cut
15 :    
16 : sh002i 1594 =for comment
17 :    
18 :     What do we want to be able to do here?
19 :    
20 :     Filter what users are shown:
21 :     - none, all, selected
22 :     - matching user_id, matching section, matching recitation
23 :     Switch from view mode to edit mode:
24 :     - showing visible users
25 :     - showing selected users
26 :     Switch from edit mode to view and save changes
27 :     Switch from edit mode to view and abandon changes
28 :     Delete users:
29 :     - visible
30 :     - selected
31 :     Import users:
32 :     - replace:
33 :     - any users
34 :     - visible users
35 :     - selected users
36 :     - no users
37 :     - add:
38 :     - any users
39 :     - no users
40 :     Export users:
41 :     - export:
42 :     - all
43 :     - visible
44 :     - selected
45 :     - to:
46 :     - existing file on server (overwrite): [ list of files ]
47 :     - new file on server (create): [ filename ]
48 :     - client
49 :    
50 :     =cut
51 :    
52 : malsyned 832 use strict;
53 :     use warnings;
54 :     use CGI qw();
55 : sh002i 1594 use WeBWorK::Utils qw(readFile readDirectory);
56 : malsyned 832
57 : sh002i 1567 use constant HIDE_USERS_THRESHHOLD => 20;
58 : sh002i 1594 use constant EDIT_FORMS => [qw(cancelEdit saveEdit)];
59 :     use constant VIEW_FORMS => [qw(filter edit delete import export)];
60 :     use constant STATE_PARAMS => [qw(user effectiveUser key visible_users no_visible_users prev_visible_users no_prev_visible_users editMode sortField)];
61 : sh002i 1567
62 : sh002i 1594 use constant SORT_SUBS => {
63 :     user_id => \&byUserID,
64 :     first_name => \&byFirstName,
65 :     last_name => \&byLastName,
66 :     email_address => \&byEmailAddress,
67 :     student_id => \&byStudentID,
68 :     status => \&byStatus,
69 :     section => \&bySection,
70 :     recitation => \&byRecitation,
71 :     comment => \&byComment,
72 :     };
73 :    
74 :     use constant FIELD_PROPERTIES => {
75 :     user_id => {
76 :     type => "text",
77 :     size => 8,
78 :     access => "readonly",
79 :     },
80 :     first_name => {
81 :     type => "text",
82 :     size => 10,
83 :     access => "readwrite",
84 :     },
85 :     last_name => {
86 :     type => "text",
87 :     size => 10,
88 :     access => "readwrite",
89 :     },
90 :     email_address => {
91 :     type => "text",
92 :     size => 20,
93 :     access => "readwrite",
94 :     },
95 :     student_id => {
96 :     type => "text",
97 :     size => 11,
98 :     access => "readwrite",
99 :     },
100 :     status => {
101 :     type => "enumerable",
102 :     size => 4,
103 :     access => "readwrite",
104 :     items => {
105 :     "C" => "Enrolled",
106 :     "D" => "Drop",
107 :     "A" => "Audit",
108 :     },
109 :     synonyms => {
110 :     qr/^[ce]/i => "C",
111 :     qr/^[dw]/i => "D",
112 :     qr/^a/i => "A",
113 :     "*" => "C",
114 :     }
115 :     },
116 :     section => {
117 :     type => "text",
118 :     size => 4,
119 :     access => "readwrite",
120 :     },
121 :     recitation => {
122 :     type => "text",
123 :     size => 4,
124 :     access => "readwrite",
125 :     },
126 :     comment => {
127 :     type => "text",
128 :     size => 20,
129 :     access => "readwrite",
130 :     },
131 :     permission => {
132 :     type => "number",
133 :     size => 2,
134 :     access => "readwrite",
135 :     }
136 :     };
137 :    
138 : malsyned 1015 sub initialize {
139 : malsyned 1211 my ($self) = @_;
140 :     my $r = $self->{r};
141 :     my $db = $self->{db};
142 :     my $ce = $self->{ce};
143 :     my $authz = $self->{authz};
144 :     my $user = $r->param('user');
145 :    
146 :     unless ($authz->hasPermissions($user, "modify_student_data")) {
147 :     $self->{submitError} = "You are not authorized to modify student data";
148 :     return;
149 :     }
150 :    
151 :     if (defined($r->param('save_classlist'))) {
152 : sh002i 1584 } elsif (defined($r->param('delete_selected'))) {
153 : malsyned 1214 } elsif (defined($r->param('addStudent'))) {
154 :     my $newUser = $db->newUser;
155 :     my $newPermissionLevel = $db->newPermissionLevel;
156 :     my $newPassword = $db->newPassword;
157 :     $newUser->user_id($r->param('newUserID'));
158 :     $newPermissionLevel->user_id($r->param('newUserID'));
159 :     $newPassword->user_id($r->param('newUserID'));
160 :     $newUser->status('C');
161 :     $newPermissionLevel->permission(0);
162 :     $db->addUser($newUser);
163 :     $db->addPermissionLevel($newPermissionLevel);
164 :     $db->addPassword($newPassword);
165 : malsyned 1211 }
166 : malsyned 1015 }
167 :    
168 : gage 1295 sub title {
169 :     my $self = shift;
170 : sh002i 1567 return "User List";
171 : gage 1295 }
172 :    
173 :     sub path {
174 : sh002i 1567 my $self = shift;
175 :     my $args = $_[-1];
176 : gage 1295 my $ce = $self->{ce};
177 :     my $root = $ce->{webworkURLs}->{root};
178 :     my $courseName = $ce->{courseName};
179 : sh002i 1567
180 : gage 1295 return $self->pathMacro($args,
181 : sh002i 1567 "Home" => "$root",
182 :     $courseName => "$root/$courseName",
183 :     "Instructor Tools" => "$root/$courseName/instructor",
184 :     "User List" => "",
185 : gage 1295 );
186 :     }
187 :    
188 : malsyned 1014 sub body {
189 : malsyned 1015 my ($self, $setID) = @_;
190 : malsyned 1014 my $r = $self->{r};
191 : malsyned 1017 my $authz = $self->{authz};
192 :     my $user = $r->param('user');
193 : malsyned 1110 my $db = $self->{db};
194 : malsyned 1293 my $ce = $self->{ce};
195 :     my $root = $ce->{webworkURLs}->{root};
196 :     my $courseName = $ce->{courseName};
197 : sh002i 1584
198 : sh002i 1594 # templates for getting field names
199 :     my $userTemplate = $self->{userTemplate} = $db->newUser;
200 :     my $permissionLevelTemplate = $self->{permissionLevelTemplate} = $db->newPermissionLevel;
201 :    
202 : sh002i 1567 return CGI::em("You are not authorized to access the Instructor tools.")
203 :     unless $authz->hasPermissions($user, "access_instructor_tools");
204 : sh002i 1584
205 : malsyned 1214 # This table can be consulted when display-ready forms of field names are needed.
206 : sh002i 1594 my %prettyFieldNames = map { $_ => $_ }
207 :     $userTemplate->FIELDS(),
208 :     $permissionLevelTemplate->FIELDS();
209 : sh002i 1567
210 : malsyned 1214 @prettyFieldNames{qw(
211 :     user_id
212 :     first_name
213 :     last_name
214 :     email_address
215 :     student_id
216 :     status
217 :     section
218 :     recitation
219 :     comment
220 :     permission
221 :     )} = (
222 :     "User ID",
223 :     "First Name",
224 :     "Last Name",
225 :     "E-mail",
226 :     "Student ID",
227 :     "Status",
228 :     "Section",
229 :     "Recitation",
230 :     "Comment",
231 :     "Perm. Level"
232 :     );
233 : sh002i 1567
234 : sh002i 1594 ########## set initial values for state fields
235 :    
236 :     my @allUserIDs = $db->listUsers;
237 :     $self->{allUserIDs} = \@allUserIDs;
238 :    
239 :     if (defined $r->param("visible_users")) {
240 :     $self->{visibleUserIDs} = [ $r->param("visible_users") ];
241 :     } elsif (defined $r->param("no_visible_users")) {
242 :     $self->{visibleUserIDs} = [];
243 :     } else {
244 : sh002i 1597 if (@allUserIDs > HIDE_USERS_THRESHHOLD) {
245 :     $self->{visibleUserIDs} = [];
246 :     } else {
247 :     $self->{visibleUserIDs} = [ @allUserIDs ];
248 :     }
249 : sh002i 1594 }
250 :    
251 :     $self->{prevVisibleUserIDs} = $self->{visibleUserIDs};
252 :    
253 :     if (defined $r->param("selected_users")) {
254 :     $self->{selectedUserIDs} = [ $r->param("selected_users") ];
255 :     } else {
256 :     $self->{selectedUserIDs} = [];
257 :     }
258 :    
259 :     $self->{editMode} = $r->param("editMode") || 0;
260 :    
261 :     $self->{sortField} = $r->param("sortField") || "last_name";
262 :    
263 :     ########## call action handler
264 :    
265 :     my $actionID = $r->param("action");
266 :     if ($actionID) {
267 :     unless (grep { $_ eq $actionID } @{ VIEW_FORMS() }, @{ EDIT_FORMS() }) {
268 :     die "Action $actionID not found";
269 :     }
270 :     my $actionHandler = "${actionID}_handler";
271 :     my %genericParams;
272 :     foreach my $param (qw(selected_users)) {
273 :     $genericParams{$param} = [ $r->param($param) ];
274 :     }
275 :     my %actionParams = $self->getActionParams($actionID);
276 :     my %tableParams = $self->getTableParams();
277 :     print CGI::p(
278 : sh002i 1597 "Result of last action performed: ",
279 : sh002i 1594 CGI::i($self->$actionHandler(\%genericParams, \%actionParams, \%tableParams))
280 :     );
281 :     }
282 :    
283 :     ########## retrieve possibly changed values for member fields
284 :    
285 :     #@allUserIDs = @{ $self->{allUserIDs} }; # do we need this one?
286 :     my @visibleUserIDs = @{ $self->{visibleUserIDs} };
287 :     my @prevVisibleUserIDs = @{ $self->{prevVisibleUserIDs} };
288 :     my @selectedUserIDs = @{ $self->{selectedUserIDs} };
289 :     my $editMode = $self->{editMode};
290 :     my $sortField = $self->{sortField};
291 :    
292 :     #warn "visibleUserIDs=@visibleUserIDs\n";
293 :     #warn "prevVisibleUserIDs=@prevVisibleUserIDs\n";
294 :     #warn "selectedUserIDs=@selectedUserIDs\n";
295 :     #warn "editMode=$editMode\n";
296 :    
297 :     ########## get required users
298 :    
299 :     my @Users = @visibleUserIDs ? $db->getUsers(@visibleUserIDs) : ();
300 :    
301 :     # presort users
302 :     my %sortSubs = %{ SORT_SUBS() };
303 :     my $sortSub = $sortSubs{$sortField};
304 :     #@Users = sort $sortSub @Users;
305 :     @Users = sort byLnFnUid @Users;
306 :    
307 :     my @PermissionLevels;
308 :    
309 :     for (my $i = 0; $i < @Users; $i++) {
310 :     my $User = $Users[$i];
311 :     my $PermissionLevel = $db->getPermissionLevel($User->user_id);
312 :    
313 :     unless ($PermissionLevel) {
314 :     # uh oh! no permission level record found!
315 :     warn "added missing permission level for user ", $User->user_id, "\n";
316 :    
317 :     # create a new permission level record
318 :     $PermissionLevel = $db->newPermissionLevel;
319 :     $PermissionLevel->user_id($User->user_id);
320 :     $PermissionLevel->permission(0);
321 :    
322 :     # add it to the database
323 :     $db->addPermissionLevel($PermissionLevel);
324 :     }
325 :    
326 :     $PermissionLevels[$i] = $PermissionLevel;
327 :     }
328 :    
329 :     ########## print beginning of form
330 :    
331 :     print CGI::start_form({method=>"post", action=>$r->uri, name=>"userlist"});
332 :     print $self->hidden_authen_fields();
333 :    
334 :     ########## print state data
335 :    
336 :     print "\n<!-- state data here -->\n";
337 :    
338 :     if (@visibleUserIDs) {
339 :     print CGI::hidden(-name=>"visible_users", -value=>\@visibleUserIDs);
340 :     } else {
341 :     print CGI::hidden(-name=>"no_visible_users", -value=>"1");
342 :     }
343 :    
344 :     if (@prevVisibleUserIDs) {
345 :     print CGI::hidden(-name=>"prev_visible_users", -value=>\@prevVisibleUserIDs);
346 :     } else {
347 :     print CGI::hidden(-name=>"no_prev_visible_users", -value=>"1");
348 :     }
349 :    
350 :     print CGI::hidden(-name=>"editMode", -value=>$editMode);
351 :    
352 :     print CGI::hidden(-name=>"sortField", -value=>$sortField);
353 :    
354 :     print "\n<!-- state data here -->\n";
355 :    
356 :     ########## print action forms
357 :    
358 :     print CGI::start_table({});
359 :     print CGI::Tr({}, CGI::td({-colspan=>2}, "Select an action to perform:"));
360 :    
361 :     my @formsToShow;
362 :     if ($editMode) {
363 :     @formsToShow = @{ EDIT_FORMS() };
364 :     } else {
365 :     @formsToShow = @{ VIEW_FORMS() };
366 :     }
367 :    
368 :     my $i = 0;
369 :     foreach my $actionID (@formsToShow) {
370 :     my $actionForm = "${actionID}_form";
371 :     my $onChange = "document.userlist.action[$i].checked=true";
372 :     my %actionParams = $self->getActionParams($actionID);
373 :    
374 :     print CGI::Tr({-valign=>"top"},
375 :     CGI::td({}, CGI::input({-type=>"radio", -name=>"action", -value=>$actionID})),
376 :     CGI::td({}, $self->$actionForm($onChange, %actionParams))
377 :     );
378 :    
379 :     $i++;
380 :     }
381 :    
382 :     print CGI::Tr({}, CGI::td({-colspan=>2, -align=>"center"},
383 :     CGI::submit(-value=>"Take Action!"))
384 :     );
385 :     print CGI::end_table();
386 :    
387 : sh002i 1597 ########## print table
388 :    
389 :     print CGI::p("Showing ", scalar @visibleUserIDs, " out of ", scalar @allUserIDs, " users.");
390 :    
391 :     $self->printTableHTML(\@Users, \@PermissionLevels, \%prettyFieldNames,
392 :     editMode => $editMode,
393 :     selectedUserIDs => \@selectedUserIDs,
394 :     );
395 :    
396 :    
397 : sh002i 1594 ########## print end of form
398 :    
399 :     print CGI::end_form();
400 :    
401 :     return "";
402 :     }
403 :    
404 :     ################################################################################
405 :     # extract particular params and put them in a hash (values are ARRAYREFs!)
406 :     ################################################################################
407 :    
408 :     sub getActionParams {
409 :     my ($self, $actionID) = @_;
410 :     my $r = $self->{r};
411 :    
412 :     my %actionParams;
413 :     foreach my $param ($r->param) {
414 :     next unless $param =~ m/^action\.$actionID\./;
415 :     $actionParams{$param} = [ $r->param($param) ];
416 :     }
417 :     return %actionParams;
418 :     }
419 :    
420 :     sub getTableParams {
421 :     my ($self) = @_;
422 :     my $r = $self->{r};
423 :    
424 :     my %tableParams;
425 :     foreach my $param ($r->param) {
426 :     next unless $param =~ m/^(?:user|permission)\./;
427 :     $tableParams{$param} = [ $r->param($param) ];
428 :     }
429 :     return %tableParams;
430 :     }
431 :    
432 :     ################################################################################
433 :     # actions and action triggers
434 :     ################################################################################
435 :    
436 : sh002i 1597 # filter, edit, cancelEdit, and saveEdit should stay with the display module and
437 :     # not be real "actions". that way, all actions are shown in view mode and no
438 :     # actions are shown in edit mode.
439 :    
440 : sh002i 1594 sub filter_form {
441 :     my ($self, $onChange, %actionParams) = @_;
442 :     return join("",
443 :     "Show ",
444 :     CGI::popup_menu(
445 :     -name => "action.filter.scope",
446 :     -values => [qw(all none selected)],
447 :     -default => $actionParams{"action.filter.scope"}->[0] || "selected",
448 :     -labels => {
449 :     all => "all users",
450 :     none => "no users",
451 :     selected => "selected users"
452 : malsyned 1261 },
453 : sh002i 1594 -onchange => $onChange,
454 :     ),
455 :     );
456 :     }
457 :    
458 :     # this action handler modifies the "visibleUserIDs" field based on the contents
459 :     # of the "action.filter.scope" parameter and the "selected_users"
460 :     sub filter_handler {
461 :     my ($self, $genericParams, $actionParams, $tableParams) = @_;
462 :    
463 :     my $result;
464 :    
465 :     my $scope = $actionParams->{"action.filter.scope"}->[0];
466 :     if ($scope eq "all") {
467 :     $result = "showing all users";
468 :     $self->{visibleUserIDs} = $self->{allUserIDs};
469 :     } elsif ($scope eq "none") {
470 :     $result = "showing no users";
471 :     $self->{visibleUserIDs} = [];
472 :     } elsif ($scope eq "selected") {
473 :     $result = "showing selected users";
474 :     $self->{visibleUserIDs} = $genericParams->{selected_users}; # an arrayref
475 :     }
476 :    
477 :     return $result;
478 :     }
479 :    
480 :     sub edit_form {
481 :     my ($self, $onChange, %actionParams) = @_;
482 :     return join("",
483 :     "Edit ",
484 :     CGI::popup_menu(
485 :     -name => "action.edit.scope",
486 :     -values => [qw(all visible selected)],
487 : sh002i 1597 -default => $actionParams{"action.edit.scope"}->[0] || "visible",
488 : sh002i 1594 -labels => {
489 :     all => "all users",
490 :     visible => "visible users",
491 :     selected => "selected users"
492 :     },
493 :     -onchange => $onChange,
494 :     ),
495 :     );
496 :     }
497 :    
498 :     sub edit_handler {
499 :     my ($self, $genericParams, $actionParams, $tableParams) = @_;
500 :    
501 :     my $result;
502 :    
503 :     my $scope = $actionParams->{"action.edit.scope"}->[0];
504 :     if ($scope eq "all") {
505 :     $result = "editing all users";
506 :     $self->{visibleUserIDs} = $self->{allUserIDs};
507 :     } elsif ($scope eq "visible") {
508 :     $result = "editing visible users";
509 :     # leave visibleUserIDs alone
510 :     } elsif ($scope eq "selected") {
511 :     $result = "editing selected users";
512 :     $self->{visibleUserIDs} = $genericParams->{selected_users}; # an arrayref
513 :     }
514 :     $self->{editMode} = 1;
515 :    
516 :     return $result;
517 :     }
518 :    
519 :     sub delete_form {
520 :     my ($self, $onChange, %actionParams) = @_;
521 :     return join("",
522 :     "Delete ",
523 :     CGI::popup_menu(
524 :     -name => "action.delete.scope",
525 : sh002i 1597 -values => [qw(visible selected)],
526 : sh002i 1594 -default => $actionParams{"action.delete.scope"}->[0] || "selected",
527 :     -labels => {
528 :     visible => "visible users",
529 :     selected => "selected users"
530 :     },
531 :     -onchange => $onChange,
532 :     ),
533 : sh002i 1597 CGI::em(" Deletion destroys all user-related data and is not undoable!"),
534 : sh002i 1594 );
535 :     }
536 :    
537 :     sub delete_handler {
538 :     my ($self, $genericParams, $actionParams, $tableParams) = @_;
539 :     my $db = $self->{db};
540 :     my $scope = $actionParams->{"action.delete.scope"}->[0];
541 :    
542 :     my @userIDsToDelete;
543 : sh002i 1597 if ($scope eq "visible") {
544 : sh002i 1594 @userIDsToDelete = @{ $self->{visibleUserIDs} };
545 :     } elsif ($scope eq "selected") {
546 :     @userIDsToDelete = @{ $self->{selectedUserIDs} };
547 :     }
548 :    
549 :     my %allUserIDs = map { $_ => 1 } @{ $self->{allUserIDs} };
550 :     my %visibleUserIDs = map { $_ => 1 } @{ $self->{visibleUserIDs} };
551 :     my %selectedUserIDs = map { $_ => 1 } @{ $self->{selectedUserIDs} };
552 :    
553 :     foreach my $userID (@userIDsToDelete) {
554 :     delete $allUserIDs{$userID};
555 :     delete $visibleUserIDs{$userID};
556 :     delete $selectedUserIDs{$userID};
557 :     $db->deleteUser($userID);
558 :     }
559 :    
560 :     $self->{allUserIDs} = [ keys %allUserIDs ];
561 :     $self->{visibleUserIDs} = [ keys %visibleUserIDs ];
562 :     $self->{selectedUserIDs} = [ keys %selectedUserIDs ];
563 :    
564 :     my $num = @userIDsToDelete;
565 :     return "deleted $num user" . ($num == 1 ? "" : "s");
566 :     }
567 :    
568 :     sub import_form {
569 :     my ($self, $onChange, %actionParams) = @_;
570 :     return join(" ",
571 :     "Import users from file",
572 :     CGI::popup_menu(
573 :     -name => "action.import.source",
574 :     -values => [ "", $self->getCSVList() ],
575 :     -default => $actionParams{"action.import.source"}->[0] || "",
576 :     -onchange => $onChange,
577 : sh002i 1597 ),
578 : sh002i 1594 "replacing",
579 :     CGI::popup_menu(
580 :     -name => "action.import.replace",
581 :     -values => [qw(any visible selected none)],
582 :     -default => $actionParams{"action.import.replace"}->[0] || "none",
583 :     -labels => {
584 :     any => "any",
585 :     visible => "visible",
586 :     selected => "selected",
587 :     none => "no",
588 :     },
589 :     -onchange => $onChange,
590 :     ),
591 : sh002i 1597 "existing users and adding",
592 : sh002i 1594 CGI::popup_menu(
593 :     -name => "action.import.add",
594 :     -values => [qw(any none)],
595 :     -default => $actionParams{"action.import.add"}->[0] || "any",
596 :     -labels => {
597 :     any => "any",
598 :     none => "no",
599 :     },
600 :     -onchange => $onChange,
601 :     ),
602 :     "new users",
603 :     );
604 :     }
605 :    
606 :     sub import_handler {
607 :     my ($self, $genericParams, $actionParams, $tableParams) = @_;
608 :    
609 :     my $source = $actionParams->{"action.import.source"}->[0];
610 :     my $add = $actionParams->{"action.import.add"}->[0];
611 :     my $replace = $actionParams->{"action.import.replace"}->[0];
612 :    
613 :     my $fileName = $source;
614 :     my $createNew = $add eq "any";
615 :     my $replaceExisting;
616 :     my @replaceList;
617 :     if ($replace eq "any") {
618 :     $replaceExisting = "any";
619 :     } elsif ($replace eq "none") {
620 :     $replaceExisting = "none";
621 :     } elsif ($replace eq "visible") {
622 :     $replaceExisting = "listed";
623 :     @replaceList = @{ $self->{visibleUserIDs} };
624 :     } elsif ($replace eq "selected") {
625 :     $replaceExisting = "listed";
626 :     @replaceList = @{ $self->{selectedUserIDs} };
627 :     }
628 :    
629 :     my ($replaced, $added, $skipped)
630 :     = $self->importUsersFromCSV($fileName, $createNew, $replaceExisting, @replaceList);
631 :    
632 : sh002i 1597 # make new users visible... do we really want to do this? probably.
633 :     push @{ $self->{visibleUserIDs} }, @$added;
634 :    
635 : sh002i 1594 my $numReplaced = @$replaced;
636 :     my $numAdded = @$added;
637 :     my $numSkipped = @$skipped;
638 :    
639 :     return $numReplaced . " user" . ($numReplaced == 1 ? "" : "s") . " replaced, "
640 :     . $numAdded . " user" . ($numAdded == 1 ? "" : "s") . " added, "
641 :     . $numSkipped . " user" . ($numSkipped == 1 ? "" : "s") . " skipped.";
642 :     }
643 :    
644 :     sub export_form {
645 :     my ($self, $onChange, %actionParams) = @_;
646 : sh002i 1597 return join("",
647 :     "Export ",
648 : sh002i 1594 CGI::popup_menu(
649 :     -name => "action.export.scope",
650 :     -values => [qw(all visible selected)],
651 : sh002i 1597 -default => $actionParams{"action.export.scope"}->[0] || "visible",
652 : sh002i 1594 -labels => {
653 :     all => "all users",
654 :     visible => "visible users",
655 :     selected => "selected users"
656 :     },
657 :     -onchange => $onChange,
658 :     ),
659 : sh002i 1597 " to ",
660 : sh002i 1594 CGI::popup_menu(
661 : sh002i 1597 -name=>"action.export.target",
662 :     -values => [ "new", $self->getCSVList() ],
663 :     -labels => { new => "a new file named:" },
664 :     -default => $actionParams{"action.export.target"}->[0] || "",
665 : sh002i 1594 -onchange => $onChange,
666 : sh002i 1597 ),
667 :     #CGI::br(),
668 :     #"new file to create: ",
669 : sh002i 1594 CGI::textfield(
670 : sh002i 1597 -name => "action.export.new",
671 :     -value => $actionParams{"action.export.new"}->[0] || "",,
672 :     -width => "50",
673 :     -onchange => $onChange,
674 : sh002i 1594 ),
675 : sh002i 1597 CGI::tt(".lst"),
676 : sh002i 1594 );
677 :     }
678 :    
679 : sh002i 1597 sub export_handler {
680 :     my ($self, $genericParams, $actionParams, $tableParams) = @_;
681 :    
682 :     my $scope = $actionParams->{"action.export.scope"}->[0];
683 :     my $target = $actionParams->{"action.export.target"}->[0];
684 :     my $new = $actionParams->{"action.export.new"}->[0];
685 :    
686 :     my $fileName;
687 :     if ($target eq "new") {
688 :     $fileName = $new;
689 :     } else {
690 :     $fileName = $target;
691 :     }
692 :    
693 :     $fileName .= ".lst" unless $fileName =~ m/\.lst$/;
694 :    
695 :     my @userIDsToExport;
696 :     if ($scope eq "all") {
697 :     @userIDsToExport = @{ $self->{allUserIDs} };
698 :     } elsif ($scope eq "visible") {
699 :     @userIDsToExport = @{ $self->{visibleUserIDs} };
700 :     } elsif ($scope eq "selected") {
701 :     @userIDsToExport = @{ $self->{selectedUserIDs} };
702 :     }
703 :    
704 :     $self->exportUsersToCSV($fileName, @userIDsToExport);
705 :    
706 :     return scalar @userIDsToExport . " users exported";
707 :     }
708 :    
709 : sh002i 1594 sub cancelEdit_form {
710 :     my ($self, $onChange, %actionParams) = @_;
711 :     return "Abandon changes";
712 :     }
713 :    
714 :     sub cancelEdit_handler {
715 :     my ($self, $genericParams, $actionParams, $tableParams) = @_;
716 :     my $r = $self->{r};
717 :    
718 :     #$self->{selectedUserIDs} = $self->{visibleUserIDs};
719 :     # only do the above if we arrived here via "edit selected users"
720 :     if (defined $r->param("prev_visible_users")) {
721 :     $self->{visibleUserIDs} = [ $r->param("prev_visible_users") ];
722 :     } elsif (defined $r->param("no_prev_visible_users")) {
723 :     $self->{visibleUserIDs} = [];
724 :     } else {
725 :     # leave it alone
726 :     }
727 :     $self->{editMode} = 0;
728 :    
729 :     return "changes abandoned";
730 :     }
731 :    
732 :     sub saveEdit_form {
733 :     my ($self, $onChange, %actionParams) = @_;
734 :     return "Save changes";
735 :     }
736 :    
737 :     sub saveEdit_handler {
738 :     my ($self, $genericParams, $actionParams, $tableParams) = @_;
739 :     my $r = $self->{r};
740 :     my $db = $self->{db};
741 :    
742 :     my @visibleUserIDs = @{ $self->{visibleUserIDs} };
743 :     foreach my $userID (@visibleUserIDs) {
744 :     my $User = $db->getUser($userID);
745 :     my $PermissionLevel = $db->getPermissionLevel($userID);
746 :    
747 :     foreach my $field ($User->NONKEYFIELDS()) {
748 :     my $param = "user.${userID}.${field}";
749 :     if (defined $tableParams->{$param}->[0]) {
750 :     $User->$field($tableParams->{$param}->[0]);
751 : malsyned 1233 }
752 :     }
753 : sh002i 1594
754 :     foreach my $field ($PermissionLevel->NONKEYFIELDS()) {
755 :     my $param = "permission.${userID}.${field}";
756 :     if (defined $tableParams->{$param}->[0]) {
757 :     $PermissionLevel->$field($tableParams->{$param}->[0]);
758 :     }
759 :     }
760 :    
761 :     $db->putUser($User);
762 :     $db->putPermissionLevel($PermissionLevel);
763 :     }
764 :    
765 :     if (defined $r->param("prev_visible_users")) {
766 :     $self->{visibleUserIDs} = [ $r->param("prev_visible_users") ];
767 :     } elsif (defined $r->param("no_prev_visible_users")) {
768 :     $self->{visibleUserIDs} = [];
769 :     } else {
770 :     # leave it alone
771 :     }
772 :    
773 :     $self->{editMode} = 0;
774 :    
775 :     return "changes saved";
776 :     }
777 :    
778 :     ################################################################################
779 :     # sorts
780 :     ################################################################################
781 :    
782 :     sub byUserID { $a->user_id cmp $b->user_id }
783 :     sub byFirstName { $a->first_name cmp $b->first_name }
784 :     sub byLastName { $a->last_name cmp $b->last_name }
785 :     sub byEmailAddress { $a->email_address cmp $b->email_address }
786 :     sub byStudentID { $a->student_id cmp $b->student_id }
787 :     sub byStatus { $a->status cmp $b->status }
788 :     sub bySection { $a->section cmp $b->section }
789 :     sub byRecitation { $a->recitation cmp $b->recitation }
790 :     sub byComment { $a->comment cmp $b->comment }
791 :    
792 :     sub byLnFnUid { &byLastName || &byFirstName || &byUserID }
793 :    
794 :     ################################################################################
795 :     # utilities
796 :     ################################################################################
797 :    
798 :     # generate labels for section/recitation popup menus
799 :     sub menuLabels {
800 :     my ($self, $hashRef) = @_;
801 :     my %hash = %$hashRef;
802 :    
803 :     my %result;
804 :     foreach my $key (keys %hash) {
805 :     my $count = @{ $hash{$key} };
806 :     my $displayKey = $key || "<none>";
807 :     $result{$key} = "$displayKey ($count users)";
808 :     }
809 :     return %result;
810 :     }
811 :    
812 :     sub getCSVList {
813 :     my ($self) = @_;
814 :     my $ce = $self->{ce};
815 :     my $dir = $ce->{courseDirs}->{templates};
816 :     return grep { not m/^\./ and m/\.lst$/ and -f "$dir/$_" } readDirectory($dir);
817 :     }
818 :    
819 :     sub importUsersFromCSV {
820 :     my ($self, $fileName, $createNew, $replaceExisting, @replaceList) = @_;
821 :     my $ce = $self->{ce};
822 :     my $db = $self->{db};
823 :     my $dir = $ce->{courseDirs}->{templates};
824 :    
825 :     die "illegal character in input: \"/\"" if $fileName =~ m|/|;
826 :     die "won't be able to read from file $dir/$fileName: does it exist? is it readable?"
827 :     unless -r "$dir/$fileName";
828 :    
829 :     my %allUserIDs = map { $_ => 1 } @{ $self->{allUserIDs} };
830 :     my %replaceOK;
831 :     if ($replaceExisting eq "none") {
832 :     %replaceOK = ();
833 :     } elsif ($replaceExisting eq "listed") {
834 :     %replaceOK = map { $_ => 1 } @replaceList;
835 :     } elsif ($replaceExisting eq "any") {
836 :     %replaceOK = %allUserIDs;
837 :     }
838 :    
839 :     my (@replaced, @added, @skipped);
840 :    
841 :     my @contents = split /\n/, readFile("$dir/$fileName");
842 :     foreach my $string (@contents) {
843 :     $string =~ s/^\s+//;
844 :     $string =~ s/\s+$//;
845 :     my (
846 :     $student_id, $last_name, $first_name, $status, $comment,
847 :     $section, $recitation, $email_address, $user_id
848 :     ) = split /\s*,\s*/, $string;
849 :    
850 :     if (exists $allUserIDs{$user_id} and not exists $replaceOK{$user_id}) {
851 :     push @skipped, $user_id;
852 :     next;
853 :     }
854 :    
855 :     if (not exists $allUserIDs{$user_id} and not $createNew) {
856 :     push @skipped, $user_id;
857 :     next;
858 :     }
859 :    
860 :     my $User = $db->newUser;
861 :     $User->user_id($user_id);
862 :     $User->first_name($first_name);
863 :     $User->last_name($last_name);
864 :     $User->email_address($email_address);
865 :     $User->student_id($student_id);
866 :     $User->status($status);
867 :     $User->section($section);
868 :     $User->recitation($recitation);
869 :     $User->comment($comment);
870 :    
871 :     my $PermissionLevel = $db->newPermissionLevel;
872 :     $PermissionLevel->user_id($user_id);
873 :     $PermissionLevel->permission(0);
874 :    
875 :     my $Password = $db->newPassword;
876 :     $Password->user_id($user_id);
877 :     $Password->password($student_id);
878 :    
879 :     if (exists $allUserIDs{$user_id}) {
880 :     $db->putUser($User);
881 :     $db->putPermissionLevel($PermissionLevel);
882 :     $db->putPassword($Password);
883 :     push @replaced, $user_id;
884 :     } else {
885 :     $db->addUser($User);
886 :     $db->addPermissionLevel($PermissionLevel);
887 :     $db->addPassword($Password);
888 :     push @added, $user_id;
889 :     }
890 :     }
891 :    
892 :     return \@replaced, \@added, \@skipped;
893 :     }
894 :    
895 : sh002i 1597 sub exportUsersToCSV {
896 :     my ($self, $fileName, @userIDsToExport) = @_;
897 :     my $ce = $self->{ce};
898 :     my $db = $self->{db};
899 :     my $dir = $ce->{courseDirs}->{templates};
900 :    
901 :     die "illegal character in input: \"/\"" if $fileName =~ m|/|;
902 :    
903 :     open my $fh, ">", "$dir/$fileName"
904 :     or die "failed to open file $dir/$fileName for writing: $!\n";
905 :    
906 :     foreach my $userID (@userIDsToExport) {
907 :     my $User = $db->getUser($userID);
908 :     my @fields = (
909 :     $User->student_id,
910 :     $User->last_name,
911 :     $User->first_name,
912 :     $User->status,
913 :     $User->comment,
914 :     $User->section,
915 :     $User->recitation,
916 :     $User->email_address,
917 :     $User->user_id,
918 :     );
919 :     my $string = join ",", @fields;
920 :     print $fh "$string\n";
921 :     }
922 :    
923 :     close $fh;
924 :     }
925 :    
926 : sh002i 1594 ################################################################################
927 :     # "display" methods
928 :     ################################################################################
929 :    
930 :     sub fieldEditHTML {
931 :     my ($self, $fieldName, $value, $properties) = @_;
932 :     my $size = $properties->{size};
933 :     my $type = $properties->{type};
934 :     my $access = $properties->{access};
935 :     my $items = $properties->{items};
936 :     my $synonyms = $properties->{synonyms};
937 :    
938 :     if ($access eq "readonly") {
939 :     return $value;
940 :     }
941 :    
942 :     if ($type eq "number" or $type eq "text") {
943 :     return CGI::input({type=>"text", name=>$fieldName, value=>$value, size=>$size});
944 :     }
945 :    
946 :     if ($type eq "enumerable") {
947 :     my $matched = undef; # Whether a synonym match has occurred
948 :    
949 :     # Process synonyms for enumerable objects
950 :     foreach my $synonym (keys %$synonyms) {
951 :     if ($synonym ne "*" and $value =~ m/$synonym/) {
952 :     $value = $synonyms->{$synonym};
953 :     $matched = 1;
954 :     }
955 :     }
956 :    
957 :     if (!$matched and exists $synonyms->{"*"}) {
958 :     $value = $synonyms->{"*"};
959 :     }
960 :    
961 :     return CGI::popup_menu({
962 :     name => $fieldName,
963 :     values => [keys %$items],
964 :     default => $value,
965 :     labels => $items,
966 :     });
967 :     }
968 :     }
969 :    
970 :     sub recordEditHTML {
971 :     my ($self, $User, $PermissionLevel, %options) = @_;
972 :     my $r = $self->{r};
973 :     my $ce = $self->{ce};
974 :     my $root = $ce->{webworkURLs}->{root};
975 :     my $courseName = $ce->{courseName};
976 :    
977 :     my $editMode = $options{editMode};
978 :     my $userSelected = $options{userSelected};
979 :    
980 :     my $changeEUserURL = "$root/$courseName?"
981 :     . "user=" . $r->param("user")
982 :     . "&effectiveUser=" . $User->user_id
983 :     . "&key=" . $r->param("key");
984 :    
985 :     my @tableCells;
986 :    
987 :     # Select
988 :     if ($editMode) {
989 :     # column not there
990 :     } else {
991 :     # selection checkbox
992 :     push @tableCells, CGI::checkbox(
993 :     -name => "selected_users",
994 :     -value => $User->user_id,
995 :     -checked => $userSelected,
996 :     -label => "",
997 :     );
998 :     }
999 :    
1000 :     # User ID
1001 :     if ($editMode) {
1002 :     # straight user ID
1003 :     push @tableCells, $User->user_id;
1004 :     } else {
1005 :     # "become user" link
1006 :     push @tableCells, CGI::a({href=>$changeEUserURL}, $User->user_id);
1007 :     }
1008 :    
1009 :     # User Fields
1010 :     foreach my $field ($User->NONKEYFIELDS) {
1011 :     my $fieldName = "user." . $User->user_id . "." . $field,
1012 :     my $fieldValue = $User->$field;
1013 :     my %properties = %{ FIELD_PROPERTIES()->{$field} };
1014 :     $properties{access} = "readonly" unless $editMode;
1015 :     push @tableCells, $self->fieldEditHTML($fieldName, $fieldValue, \%properties);
1016 :     }
1017 :    
1018 :     # PermissionLevel Fields
1019 :     foreach my $field ($PermissionLevel->NONKEYFIELDS) {
1020 :     my $fieldName = "permission." . $PermissionLevel->user_id . "." . $field,
1021 :     my $fieldValue = $PermissionLevel->$field;
1022 :     my %properties = %{ FIELD_PROPERTIES()->{$field} };
1023 :     $properties{access} = "readonly" unless $editMode;
1024 :     push @tableCells, $self->fieldEditHTML($fieldName, $fieldValue, \%properties);
1025 :     }
1026 :    
1027 :     return CGI::Tr({}, CGI::td({}, \@tableCells));
1028 :     }
1029 :    
1030 :     sub printTableHTML {
1031 :     my ($self, $UsersRef, $PermissionLevelsRef, $fieldNamesRef, %options) = @_;
1032 :     my $r = $self->{r};
1033 :     my $userTemplate = $self->{userTemplate};
1034 :     my $permissionLevelTemplate = $self->{permissionLevelTemplate};
1035 :     my @Users = @$UsersRef;
1036 :     my @PermissionLevels = @$PermissionLevelsRef;
1037 :     my %fieldNames = %$fieldNamesRef;
1038 :    
1039 :     my $editMode = $options{editMode};
1040 :     my %selectedUserIDs = map { $_ => 1 } @{ $options{selectedUserIDs} };
1041 :     my $currentSort = $options{currentSort};
1042 :    
1043 :     # names of headings:
1044 :     my @realFieldNames = (
1045 :     $userTemplate->KEYFIELDS,
1046 :     $userTemplate->NONKEYFIELDS,
1047 :     $permissionLevelTemplate->NONKEYFIELDS,
1048 : malsyned 1233 );
1049 :    
1050 : sh002i 1594 my %sortSubs = %{ SORT_SUBS() };
1051 :     #my @stateParams = @{ STATE_PARAMS() };
1052 :     #my $hrefPrefix = $r->uri . "?" . $self->url_args(@stateParams); # $self->url_authen_args
1053 :     my @tableHeadings;
1054 :     foreach my $field (@realFieldNames) {
1055 :     my $result;
1056 :     #if (exists $sortSubs{$field}) {
1057 :     # $result = CGI::a({-href=>"$hrefPrefix&sort=$field"}, $fieldNames{$field});
1058 :     #} else {
1059 :     $result = $fieldNames{$field};
1060 :     #}
1061 :     push @tableHeadings, $result;
1062 :     };
1063 :    
1064 :     # prepend selection checkbox? only if we're NOT editing!
1065 :     unshift @tableHeadings, "Sel." unless $editMode;
1066 :    
1067 :     # print the table
1068 :     if ($editMode) {
1069 :     print CGI::start_table({});
1070 :     } else {
1071 :     print CGI::start_table({-border=>1});
1072 :     }
1073 :    
1074 :     print CGI::Tr({}, CGI::th({}, \@tableHeadings));
1075 :    
1076 :     for (my $i = 0; $i < @Users; $i++) {
1077 :     my $User = $Users[$i];
1078 :     my $PermissionLevel = $PermissionLevels[$i];
1079 :    
1080 :     print $self->recordEditHTML($User, $PermissionLevel,
1081 :     editMode => $editMode,
1082 :     userSelected => exists $selectedUserIDs{$User->user_id}
1083 :     );
1084 :     }
1085 :    
1086 :     print CGI::end_table();
1087 :     }
1088 :    
1089 :     1;
1090 :    
1091 :     __END__
1092 :    
1093 :     my $editMode = 0;
1094 :     if (defined $r->param("edit_selected") or defined $r->param("edit_visible")) {
1095 :     $editMode = 1;
1096 :     }
1097 :    
1098 : sh002i 1567 my @userIDs = $db->listUsers;
1099 :     my @userRecords = $db->getUsers(@userIDs);
1100 :    
1101 :     my (%sections, %recitations);
1102 :     foreach my $user (@userRecords) {
1103 :     push @{$sections{$user->section}}, $user;
1104 :     push @{$recitations{$user->recitation}}, $user;
1105 :     }
1106 :    
1107 :     my $filter_type = $r->param("filter_type")
1108 :     || (@userIDs > HIDE_USERS_THRESHHOLD ? "none" : "all");
1109 :     my $filter_user_id = $filter_type eq "filter_user_id"
1110 :     ? $r->param("filter_user_id") || ""
1111 :     : "";
1112 :     my $filter_section = $filter_type eq "filter_section"
1113 :     ? $r->param("filter_section") || ""
1114 :     : "";
1115 :     my $filter_recitation = $filter_type eq "filter_recitation"
1116 :     ? $r->param("filter_recitation") || ""
1117 :     : "";
1118 :    
1119 : sh002i 1584 # override filter selection if "Edit Selected Users" button is pressed
1120 :     if (defined $r->param("edit_selected")) {
1121 :     $filter_type = "filter_selected";
1122 :     }
1123 :    
1124 : sh002i 1567 if ($filter_type eq "none") {
1125 :     @userRecords = ();
1126 : sh002i 1584 } elsif ($filter_type eq "filter_selected") {
1127 :     @userRecords = ();
1128 :     my @userIDs = $r->param("selectUser");
1129 :     if (@userIDs) {
1130 :     @userRecords = $db->getUsers(@userIDs);
1131 :     }
1132 : sh002i 1567 } elsif ($filter_type eq "filter_user_id") {
1133 :     @userRecords = ();
1134 :     if ($filter_user_id ne "") {
1135 :     my $userRecord = $db->getUser($filter_user_id);
1136 :     @userRecords = ($userRecord) if $userRecord;
1137 :     }
1138 :     } elsif ($filter_type eq "filter_section") {
1139 :     @userRecords = ();
1140 :     @userRecords = @{$sections{$filter_section}}
1141 :     if exists $sections{$filter_section};
1142 :     } elsif ($filter_type eq "filter_recitation") {
1143 :     @userRecords = ();
1144 :     @userRecords = @{$recitations{$filter_recitation}}
1145 :     if exists $recitations{$filter_recitation};
1146 :     }
1147 :    
1148 :     @userRecords = sort {
1149 :     (lc $a->section cmp lc $b->section)
1150 :     || (lc $a->last_name cmp lc $b->last_name)
1151 :     || (lc $a->first_name cmp lc $b->first_name)
1152 :     || (lc $a->user_id cmp lc $b->user_id)
1153 :     } @userRecords;
1154 :    
1155 : malsyned 1211 print CGI::start_form({method=>"post", action=>$r->uri()});
1156 : sh002i 1567 print $self->hidden_authen_fields();
1157 :    
1158 : sh002i 1594 filter options
1159 : sh002i 1567 my %labels = (
1160 :     none => "No users",
1161 : sh002i 1584 all => "All " . scalar @userIDs . " users",
1162 :     filter_selected => "Users selected below",
1163 : sh002i 1567 filter_user_id => "User with ID " . CGI::input({
1164 :     type=>"text",
1165 :     name=>"filter_user_id",
1166 :     value=>$filter_user_id,
1167 :     size=>"20"
1168 :     }),
1169 :     filter_section => "Users in section " . CGI::popup_menu(
1170 :     -name=>"filter_section",
1171 :     -values=>[ keys %sections ],
1172 :     -labels=>{ $self->menuLabels(\%sections) },
1173 :     -default=>$filter_section,
1174 :     ),
1175 :     filter_recitation => "Users in recitation " . CGI::popup_menu(
1176 :     -name=>"filter_recitation",
1177 :     -values=>[ sort keys %recitations ],
1178 :     -labels=>{ $self->menuLabels(\%recitations) },
1179 :     -default=>$filter_recitation,
1180 :     ),
1181 :     );
1182 :    
1183 : sh002i 1584 if ($editMode) {
1184 :     print CGI::hidden(
1185 :     -name=>"filter_type",
1186 :     -value=>"filter_selected",
1187 :     );
1188 :     } else {
1189 :     my $cgi = new CGI;
1190 :     $cgi->autoEscape(0);
1191 :     print "Show:", CGI::br();
1192 :     print $cgi->radio_group(
1193 :     -name=>"filter_type",
1194 :     -values=>[ qw(none all filter_selected filter_user_id filter_section filter_recitation) ],
1195 :     -default=>$filter_type,
1196 :     -linebreak=>"true",
1197 :     -labels=>\%labels,
1198 :     -rows=>3,
1199 :     -columns=>2,
1200 :     );
1201 :     print CGI::submit({name=>"filter", value=>"Filter"});
1202 :     }
1203 :    
1204 : malsyned 1110 print CGI::start_table({});
1205 : malsyned 1214
1206 :     # Table headings, prettied-up
1207 : sh002i 1567 my @tableHeadings = (
1208 : sh002i 1584 ($editMode ? () : "Select"),
1209 : sh002i 1567 map {$prettyFieldNames{$_}} (
1210 :     $userTemplate->KEYFIELDS(),
1211 :     $userTemplate->NONKEYFIELDS(),
1212 :     $permissionLevelTemplate->NONKEYFIELDS(),
1213 :     ),
1214 :     );
1215 :    
1216 :     # now print them
1217 : malsyned 1110 print CGI::Tr({},
1218 : sh002i 1567 CGI::th({}, \@tableHeadings)
1219 : malsyned 1110 );
1220 : sh002i 1567
1221 : sh002i 1584 my @userIDsForHiddenSelectField;
1222 :    
1223 : gage 1473 # process user records
1224 :     foreach my $userRecord (@userRecords) {
1225 :     my $currentUser = $userRecord->user_id;
1226 : sh002i 1584 push @userIDsForHiddenSelectField, $currentUser;
1227 : malsyned 1110 my $permissionLevel = $db->getPermissionLevel($currentUser);
1228 : gage 1357 unless (defined $permissionLevel) {
1229 : sh002i 1567 warn "No permissionLevel record for user $currentUser -- added";
1230 : gage 1473 my $newPermissionLevel = $db->newPermissionLevel;
1231 :     $newPermissionLevel->user_id($currentUser);
1232 :     $newPermissionLevel->permission(0);
1233 :     $db->addPermissionLevel($newPermissionLevel);
1234 : sh002i 1567 $permissionLevel = $newPermissionLevel;
1235 : gage 1473 # permission set to minimum level
1236 : gage 1357 }
1237 : malsyned 1110
1238 : malsyned 1214 # A concise way of printing a row containing a cell for each field, editable unless it's a key
1239 : malsyned 1110 print CGI::Tr({},
1240 :     CGI::td({}, [
1241 : sh002i 1584 ($editMode
1242 :     ? () # don't show selection checkbox if we're in edit mode -- hidden field below
1243 :     #: CGI::input({type=>"checkbox", name=>"selectUser", value=>$currentUser})
1244 :     : CGI::checkbox(
1245 :     -name=>"selectUser",
1246 :     -value=>$currentUser,
1247 :     -checked=>($filter_type eq "filter_selected" and not defined $r->param("editingAllVisibleUsers")),
1248 :     -label=>""
1249 :     )
1250 :     ),
1251 :     ($editMode
1252 :     ? $currentUser
1253 :     : (map {
1254 :     my $changeEUserURL = "$root/$courseName?"
1255 :     . "user=" . $r->param("user")
1256 :     . "&effectiveUser=" . $userRecord->user_id
1257 :     . "&key=" . $r->param("key");
1258 :     CGI::a({href=>$changeEUserURL}, $userRecord->$_)
1259 :     } $userRecord->KEYFIELDS)
1260 :     ),
1261 : malsyned 1233 (map {
1262 : sh002i 1567 $self->fieldEditHTML(
1263 :     "user." . $userRecord->user_id . "." .$_,
1264 :     $userRecord->$_, $fieldProperties{$_});
1265 : malsyned 1233 } $userRecord->NONKEYFIELDS()),
1266 :     (map {
1267 : sh002i 1567 $self->fieldEditHTML(
1268 :     "permission." . $permissionLevel->user_id . "." . $_,
1269 :     $permissionLevel->$_, $fieldProperties{$_});
1270 : malsyned 1233 } $permissionLevel->NONKEYFIELDS()),
1271 : malsyned 1110 ])
1272 :     );
1273 :     }
1274 : malsyned 1214
1275 : sh002i 1567 unless (@userRecords) {
1276 :     print CGI::Tr({},
1277 :     CGI::td({-colspan=>scalar(@tableHeadings), -align=>"center"},
1278 :     "No users match the filter criteria above."
1279 :     ),
1280 :     );
1281 :     }
1282 :    
1283 : malsyned 1110 print CGI::end_table();
1284 : sh002i 1584
1285 :     if ($editMode) {
1286 :     print CGI::hidden(-name=>"selectUser", -value=>[ @userIDsForHiddenSelectField ]);
1287 :     if (defined $r->param("edit_visible")) {
1288 :     print CGI::hidden(-name=>"editingAllVisibleUsers", -value=>1);
1289 :     }
1290 :     }
1291 :    
1292 :     if ($editMode) {
1293 :     print CGI::submit({name=>"discard_chagnes", value=>"Discard Changes to Users"});
1294 :     print CGI::submit({name=>"save_classlist", value=>"Save Changes to Users"});
1295 :     } else {
1296 :     print CGI::submit({name=>"edit_visible", value=>"Edit Visible Users"});
1297 :     print CGI::submit({name=>"edit_selected", value=>"Edit Selected Users"});
1298 :     print CGI::submit({name=>"delete_selected", value=>"Delete Selected Users"});
1299 :     }
1300 :    
1301 : malsyned 1211 print CGI::end_form();
1302 : malsyned 1017
1303 : malsyned 1214 # Add a student form
1304 : sh002i 1584 unless ($editMode) {
1305 :     print CGI::start_form({method=>"post", action=>$r->uri()});
1306 :     print $self->hidden_authen_fields();
1307 :     print "User ID:";
1308 :     print CGI::input({type=>"text", name=>"newUserID", value=>"", size=>"20"});
1309 :     print CGI::submit({name=>"addStudent", value=>"Add User"});
1310 :     print CGI::end_form();
1311 :     }
1312 : malsyned 1214
1313 : malsyned 1014 return "";

aubreyja at gmail dot com
ViewVC Help
Powered by ViewVC 1.0.9