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

Diff of /trunk/webwork2/lib/WeBWorK/ContentGenerator/Instructor/Index.pm

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

Revision 996 Revision 1716
1################################################################################ 1################################################################################
2# WeBWorK mod_perl (c) 2000-2002 WeBWorK Project 2# WeBWorK Online Homework Delivery System
3# $Id$ 3# Copyright © 2000-2003 The WeBWorK Project, http://openwebwork.sf.net/
4# $CVSHeader: webwork-modperl/lib/WeBWorK/ContentGenerator/Instructor/Index.pm,v 1.23 2003/12/18 23:15:34 sh002i Exp $
5#
6# This program is free software; you can redistribute it and/or modify it under
7# the terms of either: (a) the GNU General Public License as published by the
8# Free Software Foundation; either version 2, or (at your option) any later
9# version, or (b) the "Artistic License" which comes with this package.
10#
11# This program is distributed in the hope that it will be useful, but WITHOUT
12# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13# FOR A PARTICULAR PURPOSE. See either the GNU General Public License or the
14# Artistic License for more details.
4################################################################################ 15################################################################################
5 16
6package WeBWorK::ContentGenerator::Instructor::Index; 17package WeBWorK::ContentGenerator::Instructor::Index;
7use base qw(WeBWorK::ContentGenerator::Instructor); 18use base qw(WeBWorK::ContentGenerator::Instructor);
8 19
12 23
13=cut 24=cut
14 25
15use strict; 26use strict;
16use warnings; 27use warnings;
28use Apache::Constants qw(:common REDIRECT DONE);
17use CGI qw(); 29use CGI qw();
30sub pre_header_initialize {
31 my ($self, $setName, $problemNumber) = @_;
32 my $r = $self->{r};
33 my $ce = $self->{ce};
34 my $db = $self->{db};
35 my $authz = $self->{authz};
36 my $userName = $r->param('user');
37 my $effectiveUserName = $r->param('effectiveUser');
38 my $key = $r->param('key');
39 my $user = $db->getUser($userName); #checked
40 die "user $user (real user) not found." unless $user;
41 my $effectiveUser = $db->getUser($effectiveUserName); #checked
42 die "effective user $effectiveUser not found. One 'acts as' the effective user." unless $effectiveUser;
43 my $PermissionLevelRecord = $db->getPermissionLevel($userName); #checked
44 die "permisson level for user $userName not found." unless $PermissionLevelRecord;
45 my $permissionLevel = $PermissionLevelRecord->permission();
46
47
48
49 unless ($authz->hasPermissions($userName, "modify_student_data")) {
50 $self->{submitError} = "You are not authorized to modify student data";
51 return;
52 }
53 my @submit_actions = qw(student-dates act-as-student edit-set-dates reset-password assign-passwords
54 set-stats drop-students edit-students-sets edit-sets student-stats edit-class-data
55 add-students send-email score-sets);
56 foreach my $act (@submit_actions) {
57 $self->{current_action } .= "The action <$act> "". $r->param($act) . "" was requested"
58 if defined($r->param($act));
59 }
60 $self->{selected_sets} = "Set(s) chosen: " . join(" ", $r->param("setList"));
61 $self->{selected_users} = "Student(s) chosen: " .join(" ", $r->param("classList")) ;
62# Redirect actions
63 defined($r->param('student-dates')) && do {
64 #FIXME will only do one student and one set at a time
65 # it would be good to be able to do many sets for many student
66 # this would require a separate module
67 my $root = $ce->{webworkURLs}->{root};
68 my $courseName = $ce->{courseName};
69 my @userList = $r->param("classList");
70 # can only become the first user listed.
71 my $student = shift @userList;
72 my @setList = $r->param("setList");
73 # can only become the first user listed.
74 my $setName = shift @setList;
75 my $uri="$root/$courseName/instructor/sets/$setName/?editForUser=$student&".$self->url_authen_args;
76 $r->header_out(Location => $uri);
77 $self->{noContent} = 1; # forces redirect
78 return;
79 };
80 defined($r->param('act-as-student')) && do {
81 # fix url and redirect
82 my @userList = $r->param("classList");
83 # can only become the first user listed.
84 my $effectiveUser = shift @userList;
85 my @setList = $r->param("setList");
86 my $setName = shift @setList;
87 my $root = $ce->{webworkURLs}->{root};
88 my $courseName = $ce->{courseName};
89
90 my $uri="$root/$courseName/$setName/?effectiveUser=$effectiveUser&".$self->url_authen_args;
91 #FIXME does the display mode need to be defined?
92 #FIXME url_authen_args also includes an effective user, so the new one must come first.
93 # even that might not work with every browser since there are two effective User assignments.
94 $r->header_out(Location => $uri);
95 $self->{noContent} = 1; # forces redirect
96 return;
97 };
98 defined($r->param('edit-set-dates')) && do {
99 #FIXME this should be replaced by redirecting to a module where you can edit
100 # dates for several sets at once
101 my $root = $ce->{webworkURLs}->{root};
102 my $courseName = $ce->{courseName};
103 my @setList = $r->param("setList");
104 # can only become the first user listed.
105 my $setName = shift @setList;
106 my $uri="$root/$courseName/instructor/sets/$setName/?".$self->url_authen_args;
107 $r->header_out(Location => $uri);
108 $self->{noContent} = 1; # forces redirect
109 return;
110 };
111 defined($r->param('reset-password')) && do {
112 # FIXME this should allow me to assign studentID to a number of students
113 # requires a new module
114 my @userList = $r->param("classList");
115 # can only become the first user listed.
116 my $effectiveUser = shift @userList;
117 my @setList = $r->param("setList");
118 my $setName = shift @setList;
119 my $root = $ce->{webworkURLs}->{root};
120 my $courseName = $ce->{courseName};
121
122 my $uri="$root/$courseName/options/?effectiveUser=$effectiveUser&".$self->url_authen_args;
123 #FIXME does the display mode need to be defined?
124 #FIXME url_authen_args also includes an effective user, so the new one must come first.
125 # even that might not work with every browser since there are two effective User assignments.
126 $r->header_out(Location => $uri);
127 $self->{noContent} = 1; # forces redirect
128 return;
129 };
130 defined($r->param('assign-passwords')) && do {
131 my @userList = $r->param("classList");
132 # can only become the first user listed.
133 my $effectiveUser = shift @userList;
134 my @setList = $r->param("setList");
135 my $setName = shift @setList;
136 my $root = $ce->{webworkURLs}->{root};
137 my $courseName = $ce->{courseName};
138
139 my $uri="$root/$courseName/options/?effectiveUser=$effectiveUser&".$self->url_authen_args;
140 #FIXME does the display mode need to be defined?
141 #FIXME url_authen_args also includes an effective user, so the new one must come first.
142 # even that might not work with every browser since there are two effective User assignments.
143 $r->header_out(Location => $uri);
144 $self->{noContent} = 1; # forces redirect
145 return;
146 };
147 defined($r->param('set-stats')) && do {
148 my $root = $ce->{webworkURLs}->{root};
149 my $courseName = $ce->{courseName};
150 my @setList = $r->param("setList");
151 # can only become the first user listed.
152 my $setName = shift @setList;
153 my $uri="$root/$courseName/instructor/stats/set/$setName?".$self->url_authen_args;
154 $r->header_out(Location => $uri);
155 $self->{noContent} = 1; # forces redirect
156 return;
157 };
158 defined($r->param('drop-students')) && do {
159 #FIXME this operation should be made faster
160 my $root = $ce->{webworkURLs}->{root};
161 my $courseName = $ce->{courseName};
162 my @setList = $r->param("setList");
163 # can only become the first user listed.
164 my $setName = shift @setList;
165 my $uri="$root/$courseName/instructor/users/?".$self->url_authen_args;
166 $r->header_out(Location => $uri);
167 $self->{noContent} = 1; # forces redirect
168 return;
169 };
170 defined($r->param('edit-students-sets')) && do {
171 my $root = $ce->{webworkURLs}->{root};
172 my $courseName = $ce->{courseName};
173 my @userList = $r->param("classList");
174 # can only become the first user listed.
175 my $student = shift @userList;
176 my @setList = $r->param("setList");
177 # can only become the first user listed.
178 my $setName = shift @setList;
179 my $uri="$root/$courseName/instructor/sets/$setName/?editForUser=$student&".$self->url_authen_args;
180 $r->header_out(Location => $uri);
181 $self->{noContent} = 1; # forces redirect
182 return;
183 };
184 defined($r->param('edit-sets')) && do {
185 my $root = $ce->{webworkURLs}->{root};
186 my $courseName = $ce->{courseName};
187 my @setList = $r->param("setList");
188 # can only become the first user listed.
189 my $setName = shift @setList;
190 my $uri="$root/$courseName/instructor/sets/$setName/?".$self->url_authen_args;
191 $r->header_out(Location => $uri);
192 $self->{noContent} = 1; # forces redirect
193 return;
194 };
195 defined($r->param('student-stats')) && do {
196 my $root = $ce->{webworkURLs}->{root};
197 my $courseName = $ce->{courseName};
198 my @userList = $r->param("classList");
199 # can only become the first user listed.
200 my $studentName = shift @userList;
201 my $uri="$root/$courseName/instructor/stats/student/$studentName?".$self->url_authen_args;
202 $r->header_out(Location => $uri);
203 $self->{noContent} = 1; # forces redirect
204 return;
205 };
206 defined($r->param('edit-class-data')) && do {
207 my $root = $ce->{webworkURLs}->{root};
208 my $courseName = $ce->{courseName};
209 #my @setList = $r->param("setList");
210 ## can only become the first user listed.
211 #my $setName = shift @setList;
212 # ...not sure what those are about
213 # get list of users selected
214 my @userIDs = $r->param("classList");
215 my $uri="$root/$courseName/instructor/users/?";
216 $uri .= join("&", map { "visible_users=$_" } @userIDs);
217 $uri .= "&editMode=1",
218 $uri .= "&" . $self->url_authen_args;
219 $r->header_out(Location => $uri);
220 $self->{noContent} = 1; # forces redirect
221 return;
222 };
223 defined($r->param('add-students')) && do {
224 my $root = $ce->{webworkURLs}->{root};
225 my $courseName = $ce->{courseName};
226
227 my $uri="$root/$courseName/instructor/add_users/?".$self->url_authen_args;
228 $r->header_out(Location => $uri);
229 $self->{noContent} = 1; # forces redirect
230 return;
231 };
232 defined($r->param('send-email')) && do {
233 my $root = $ce->{webworkURLs}->{root};
234 my $courseName = $ce->{courseName};
235
236 my $uri="$root/$courseName/instructor/send_mail/?".$self->url_authen_args;
237 $r->header_out(Location => $uri);
238 $self->{noContent} = 1; # forces redirect
239 return;
240 };
241 defined($r->param('score-sets')) && do {
242 my $root = $ce->{webworkURLs}->{root};
243 my $courseName = $ce->{courseName};
244
245 my $uri="$root/$courseName/instructor/scoring/?scoreSelected=Score%20Selected&".$self->url_authen_args;
246 my @selectedSets = $r->param('setList');
247 $uri .= "&selectedSet=$_" foreach (@selectedSets);
248 $r->header_out(Location => $uri);
249 $self->{noContent} = 1; # forces redirect
250 return;
251 };
252
253}
254# override contentGenerator header routine for now
255# FIXME
256sub header {
257 my $self = shift;
258 return REDIRECT if $self->{noContent};
259 my $r = $self->{r};
260 $r->content_type('text/html');
261 $r->send_http_header();
262 return OK;
263}
264sub initialize {
265 my ($self) = @_;
266 my $r = $self->{r};
267 my $db = $self->{db};
268 my $ce = $self->{ce};
269 my $authz = $self->{authz};
270 my $user = $r->param('user');
271
272 unless ($authz->hasPermissions($user, "modify_student_data")) {
273 $self->{submitError} = "You are not authorized to modify student data";
274 return;
275 }
276
277#############################################################################################
278# gather database data
279#############################################################################################
280 # FIXME this might be better done in body? We don't always need all of this data. or do we?
281# Obtaining the list of users
282 $WeBWorK::timer->continue("Begin listing users") if defined $WeBWorK::timer;
283 my @userNames = $db->listUsers; # checked
284 $WeBWorK::timer->continue("End listing users") if defined $WeBWorK::timer;
285 $WeBWorK::timer->continue("Begin obtaining users") if defined $WeBWorK::timer;
286 my @user_records = $db->getUsers(@userNames); # checked
287 $WeBWorK::timer->continue("End obtaining users: ".@user_records) if defined $WeBWorK::timer;
288
289 # store data
290 $self->{ra_users} = \@userNames;
291 $self->{ra_user_records} = \@user_records;
292
293# Obtaining list of sets:
294 $WeBWorK::timer->continue("Begin listing sets") if defined $WeBWorK::timer;
295 my @setNames = $db->listGlobalSets();
296 $WeBWorK::timer->continue("End listing sets") if defined $WeBWorK::timer;
297 my @set_records = ();
298 $WeBWorK::timer->continue("Begin obtaining sets") if defined $WeBWorK::timer;
299 @set_records = $db->getGlobalSets( @setNames);
300 $WeBWorK::timer->continue("End obtaining sets: ".@set_records) if defined $WeBWorK::timer;
301# foreach my $name (@setNames) {
302# my $set_record;
303# $set_record = $db->getMergedSet($user,$name,) ;
304#
305# #warn "Adding set $name", ref($set_record);
306# push @set_records, $set_record;
307# }
308
309
310 # store data
311 $self->{ra_sets} = \@setNames;
312 $self->{ra_set_records} = \@set_records;
313
314}
315sub path {
316 my $self = shift;
317 my $args = $_[-1];
318
319 my $ce = $self->{ce};
320 my $root = $ce->{webworkURLs}->{root};
321 my $courseName = $ce->{courseName};
322 return $self->pathMacro($args,
323 "Home" => "$root",
324 $courseName => "$root/$courseName",
325 "Instructor Tools" => "",
326 );
327}
18 328
19sub title { 329sub title {
20 my $self = shift; 330 my $self = shift;
21 return "Instructor tools for ".$self->{ce}->{courseName}; 331 return "Instructor Tools";
22} 332}
23 333
24sub body { 334sub body {
25 my $self = shift; 335 my $self = shift;
26 my $r = $self->{r}; 336 my $r = $self->{r};
27 my $ce = $self->{ce}; 337 my $ce = $self->{ce};
338 my $db = $self->{db};
339 my $authz = $self->{authz};
28 my $courseName = $ce->{courseName}; 340 my $courseName = $ce->{courseName};
29 my $authen_args = $self->url_authen_args(); 341 my $authen_args = $self->url_authen_args();
30 342 my $user = $r->param('user');
31 my $prof_url = $ce->{webworkURLs}->{oldProf}; 343 my $prof_url = $ce->{webworkURLs}->{oldProf};
32 my $full_url = "$prof_url?course=$courseName&$authen_args"; 344 my $full_url = "$prof_url?course=$courseName&$authen_args";
33 my $userEditorURL = "users/?" . $self->url_args; 345 my $userEditorURL = "users/?" . $self->url_args;
34 my $problemSetEditorURL = "set/?" . $self->url_args; 346 my $problemSetEditorURL = "sets/?" . $self->url_args;
347 my $statsURL = "stats/?" . $self->url_args;
348 my $emailURL = "send_mail/?" . $self->url_args;
349 my $scoringURL = "scoring/?" . $self->url_args;
350 my $filexferURL = "files/?" . $self->url_args;
351 my $actionURL = $r->uri;
352
353 return CGI::em('You are not authorized to access the Instructor tools.') unless $authz->hasPermissions($user, 'access_instructor_tools');
354
35 355
36 return 356
37 CGI::p("\n". 357 print join("",
38 CGI::a({href=>$userEditorURL}, "Users"). " - View and edit data and settings for users of $courseName" . CGI::br(). "\n". 358 CGI::h2("Quick access to commonly used instructor tools"),
39 CGI::a({href=>$problemSetEditorURL}, "Problem Sets"). " - View and edit settings for problem sets in $courseName".CGI::br()."\n" 359 CGI::start_form(-method=>"POST", -action=>$actionURL),"\n",
40 )."\n".CGI::hr()."\n". 360 $self->hidden_authen_fields,"\n",
41 CGI::p( 361 CGI::start_table({-border=>2,-cellpadding=>5}),
42 CGI::b("NOTE: ") . 362 CGI::Tr({ -align=>'center'},
43 "The Instructor Tools in this preview release of WeBWorK 363 CGI::td({colspan=>2},[
44 2.0 are not stable or complete. If you need reliable and 364 CGI::input({type=>'submit',value=>'Add students...',name=>'add-students'}),
45 stable course editing features, than at this time you 365 CGI::input({type=>'submit',value=>'Send email...',name=>'send-email'}),
46 will need to use the Professor tools from WeBWorK 1.8 366 ]
47 or earlier. Use the links below to go to the Professor 367 ),
48 pages of your system's WeBWorK 1.x installation." 368
49 )."\n". 369
50 CGI::ul( 370 ),
51 CGI::li( 371 CGI::Tr({ -align=>'center'},
52 CGI::a({-href=>$full_url}, "Go to Professor pages") 372 CGI::td({colspan=>1},[
53 ). 373
54 CGI::li( 374 CGI::input({type=>'submit',value=>'Reset password',name=>'reset-password'}),
55 CGI::a({-href=>$full_url, -target=>"_new"}, "Open Professor pages in new window") 375 CGI::input({type=>'submit',value=>'Assign passwords...',name=>'assign-passwords'}),
376 CGI::input({type=>'submit',value=>'View set statistics...',name=>'set-stats'}),
377 CGI::input({type=>'submit',value=>'Edit set(s) dates...',name=>'edit-set-dates'})
378 ]
56 ) 379 )
380
381 ),
382 CGI::Tr({ -align=>'center'},
383 CGI::td({colspan=>1},[
384 CGI::input({type=>'submit',value=>'View student statistics...',name=>'student-stats'}),
385 CGI::input({type=>'submit',value=>'Edit class data for students...',name=>'edit-class-data'}),
386 CGI::input({type=>'submit',value=>'Edit set(s) data...',name=>'edit-sets'}),
387 CGI::input({type=>'submit',value=>'Score selected set(s)...',name=>'score-sets'}),
388 ]
389 ),
390 ),
391
392
393 CGI::Tr({ -align=>'center'},
394 CGI::td({colspan=>2},[
395 $self->popup_user_form,
396 $self->popup_set_form,
397 ]
398 )
399
400 ),
401 CGI::Tr({ -align=>'center'},
402 CGI::td({colspan=>1},[
403
404 CGI::input({type=>'submit',value=>'Edit student(s)/set(s) dates',name=>'student-dates'}),
405 CGI::input({type=>'submit',value=>'Act as student in set...',name=>'act-as-student'}),
406 ]
407 ),
408 CGI::td({colspan=>2},
409 CGI::input({type=>'submit',value=>'Edit student(s) data for selected set(s)...',name=>'edit-students-sets'}),
410
411
412 )
413
414 ),
415
416 CGI::Tr({ -align=>'center'},
417 CGI::td({colspan=>2},[
418 CGI::input({type=>'submit',value=>'Drop student(s)',name=>'drop-students'}),
419 ' '
420 ]
421 ),
422
423
424 ),
425
426 CGI::end_table(),
427 CGI::end_form()
57 ); 428 );
429 print join("",
430 CGI::start_table({-border=>2,-cellpadding=>20}),
431 CGI::Tr({-align=>'center'},
432 CGI::td([
433 CGI::a({href=>$userEditorURL}, "User List"),
434 CGI::a({href=>$problemSetEditorURL}, "Set List"),
435 CGI::a({-href=>$emailURL}, "Mail Merge"),
436 CGI::a({-href=>$scoringURL}, "Scoring"),
437 CGI::a({-href=>$statsURL}, "Statistics"),
438 CGI::a({-href=>$emailURL}, "File Transfer"),
439 ]),
440 "\n",
441 ),
442
443# CGI::Tr({ -align=>'center'},
444# CGI::td([
445#
446# ]),
447# "\n",
448# ),
449 CGI::Tr({ -align=>'left'},
450 CGI::td({-colspan=>6},
451 CGI::a({-href=>$full_url}, 'WeBWorK 1.x Instructor Tools'),
452 " (" . CGI::a({-href=>$full_url, -target=>'_new'}, 'open in a new window') . ")",
453 ),
454 "\n",
455 ),
456 CGI::end_table(),
457 );
58} 458}
459sub addStudentForm {
460 my $self = shift;
461 my $r = $self->{r};
462
463 # Add a student form
464 join( "",
465 CGI::p("Add new students"),
466 CGI::start_form({method=>"post", action=>$r->uri()}),
467 $self->hidden_authen_fields(),
468 CGI::start_table({border=>'1', cellpadding=>'2'}),
469 CGI::Tr({},
470 CGI::th({},
471 ['Last Name', 'First Name', 'Student ID', 'Login Name', 'Email Address', 'Section','Recitation', 'Comment']
472 )
473 ),
474 CGI::Tr({},
475 CGI::td({},
476 [ CGI::input({name=>'last_name'}),
477 CGI::input({name=>'first_name'}),
478 CGI::input({name=>'student_id',size=>'16'}),
479 CGI::input({name=>'new_user_id',size=>'10'}),
480 CGI::input({name=>'email_address'}),
481 CGI::input({name=>'section',size=>'10'}),
482 CGI::input({name=>'recitation',size=>'10'}),
483 CGI::input({name=>'comment'}),
484
485
486 ]
487 )
488 ),
489 CGI::end_table(),
490 CGI::submit({name=>"addStudent", value=>"Add Student"}),
491 CGI::end_form(),
492 );
59 493
494
495
496
497
498
499}
500sub popup_user_form {
501 my $self = shift;
502 my $r = $self->{r};
503 my $authz = $self->{authz};
504 my $user = $r->param('user');
505 my $db = $self->{db};
506 my $ce = $self->{ce};
507 my $root = $ce->{webworkURLs}->{root};
508 my $courseName = $ce->{courseName};
509
510 # return CGI::em("You are not authorized to access the Instructor tools.") unless $authz->hasPermissions($user, "access_instructor_tools");
511
512 # This code will require changing if the permission and user tables ever have different keys.
513 my @users = ();
514 my $ra_user_records = $self->{ra_user_records};
515 my %classlistLabels = ();# %$hr_classlistLabels;
516 my @user_records = sort { ( lc($a->section) cmp lc($b->section) ) ||
517 ( lc($a->last_name) cmp lc($b->last_name )) } @{$ra_user_records};
518 foreach my $ur (@{user_records}) {
519 $classlistLabels{$ur->user_id} = $ur->last_name. ', '. $ur->first_name.' - '.$ur->section.' '.$ur->user_id;
520 push(@users, $ur->user_id);
521 }
522 return CGI::popup_menu(-name=>'classList',
523 -values=>\@users,
524 -labels=>\%classlistLabels,
525 -size => 10,
526 -multiple => 1,
527 #-default=>$user
528 ),
529
530
531}
532sub popup_set_form {
533 my $self = shift;
534 my $r = $self->{r};
535 my $authz = $self->{authz};
536 my $user = $r->param('user');
537 my $db = $self->{db};
538 my $ce = $self->{ce};
539 my $root = $ce->{webworkURLs}->{root};
540 my $courseName = $ce->{courseName};
541
542 # return CGI::em("You are not authorized to access the Instructor tools.") unless $authz->hasPermissions($user, "access_instructor_tools");
543
544 # This code will require changing if the permission and user tables ever have different keys.
545 my @setNames = ();
546 my $ra_set_records = $self->{ra_set_records};
547 my %setLabels = ();# %$hr_classlistLabels;
548 my @set_records = sort {$a->set_id cmp $b->set_id } @{$ra_set_records};
549 foreach my $sr (@set_records) {
550 $setLabels{$sr->set_id} = $sr->set_id;
551 push(@setNames, $sr->set_id); # reorder sets
552 }
553 return CGI::popup_menu(-name=>'setList',
554 -values=>\@setNames,
555 -labels=>\%setLabels,
556 -size => 10,
557 -multiple => 1,
558 #-default=>$user
559 ),
560
561
562}
601; 5631;
61 564
62__END__ 565__END__
63 566
64=head1 AUTHOR 567=head1 AUTHOR

Legend:
Removed from v.996  
changed lines
  Added in v.1716

aubreyja at gmail dot com
ViewVC Help
Powered by ViewVC 1.0.9