| 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 | |
| 6 | package WeBWorK::ContentGenerator::Instructor::Index; |
17 | package WeBWorK::ContentGenerator::Instructor::Index; |
| 7 | use base qw(WeBWorK::ContentGenerator::Instructor); |
18 | use base qw(WeBWorK::ContentGenerator::Instructor); |
| 8 | |
19 | |
| … | |
… | |
| 12 | |
23 | |
| 13 | =cut |
24 | =cut |
| 14 | |
25 | |
| 15 | use strict; |
26 | use strict; |
| 16 | use warnings; |
27 | use warnings; |
|
|
28 | use Apache::Constants qw(:common REDIRECT DONE); |
| 17 | use CGI qw(); |
29 | use CGI qw(); |
|
|
30 | sub 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 |
|
|
256 | sub 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 | } |
|
|
264 | sub 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 | } |
|
|
315 | sub 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 | |
| 19 | sub title { |
329 | sub 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 | |
| 24 | sub body { |
334 | sub 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 | } |
|
|
459 | sub 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 | } |
|
|
500 | sub 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 | } |
|
|
532 | sub 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 | } |
| 60 | 1; |
563 | 1; |
| 61 | |
564 | |
| 62 | __END__ |
565 | __END__ |
| 63 | |
566 | |
| 64 | =head1 AUTHOR |
567 | =head1 AUTHOR |