[system] / trunk / webwork-modperl / lib / WeBWorK / ContentGenerator / CourseAdmin.pm Repository:
ViewVC logotype

Diff of /trunk/webwork-modperl/lib/WeBWorK/ContentGenerator/CourseAdmin.pm

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

Revision 1945 Revision 1960
26use strict; 26use strict;
27use warnings; 27use warnings;
28use CGI::Pretty qw(); 28use CGI::Pretty qw();
29use Data::Dumper; 29use Data::Dumper;
30use WeBWorK::Utils qw(cryptPassword); 30use WeBWorK::Utils qw(cryptPassword);
31use WeBWorK::Utils::CourseManagement qw(addCourse); 31use WeBWorK::Utils::CourseManagement qw(addCourse deleteCourse listCourses);
32 32
33# SKEL: If you need to do any processing before the HTTP header is sent, do it 33# SKEL: If you need to do any processing before the HTTP header is sent, do it
34# in this method: 34# in this method:
35# 35#
36#sub pre_header_initialize { 36#sub pre_header_initialize {
127 my $ce = $r->ce; 127 my $ce = $r->ce;
128 my $db = $r->db; 128 my $db = $r->db;
129 my $authz = $r->authz; 129 my $authz = $r->authz;
130 my $urlpath = $r->urlpath; 130 my $urlpath = $r->urlpath;
131 131
132 print CGI::h2("Create a new course"); 132 print CGI::p({style=>"text-align: center"},
133 CGI::a({href=>$self->systemLink($urlpath, params=>{subDisplay=>"add_course"})}, "Add Course"),
134 #" | ",
135 #CGI::a({href=>$self->systemLink($urlpath, params=>{subDisplay=>"rename_course"})}, "Rename Course"),
136 " | ",
137 CGI::a({href=>$self->systemLink($urlpath, params=>{subDisplay=>"delete_course"})}, "Delete Course"),
138 );
133 139
134 my $add_step_max = 4; # the step that actually creates the course 140 print CGI::hr();
135 141
136 my $add_step = $r->param("add_step") || 0; 142 my $subDisplay = $r->param("subDisplay");
143 if (defined $subDisplay) {
137 144
138 my $new_courseID = $r->param("new_courseID"); 145 if ($subDisplay eq "add_course") {
139 my $new_dbLayout = $r->param("new_dbLayout"); 146 if (defined $r->param("add_course")) {
140 my $new_skipDBCreation = $r->param("new_skipDBCreation"); 147 my @errors = $self->add_course_validate;
141 my $new_sql_host = $r->param("new_sql_host"); 148 if (@errors) {
142 my $new_sql_port = $r->param("new_sql_port"); 149 print CGI::div({class=>"ResultsWithError"},
143 my $new_sql_username = $r->param("new_sql_username"); 150 CGI::p("Please correct the following errors and try again:"),
144 my $new_sql_password = $r->param("new_sql_password"); 151 CGI::ul(CGI::li(\@errors)),
145 my $new_sql_database = $r->param("new_sql_database"); 152 );
146 my $new_sql_wwhost = $r->param("new_sql_wwhost"); 153 $self->add_course_form;
147 my $new_gdbm_globalUserID = $r->param("new_gdbm_globalUserID"); 154 } else {
148 my $new_initial_userID = $r->param("new_initial_userID"); 155 $self->do_add_course;
149 my $new_initial_password = $r->param("new_initial_password"); 156 }
150 157 } else {
151 # "back up" if certain fields aren't filled in 158 $self->add_course_form;
152 159 }
153 if ($add_step > 0) {
154 $add_step = 0 if $new_courseID eq "" or $new_dbLayout eq "";
155 }
156
157 if ($add_step > 1 and not $new_skipDBCreation) {
158 if ($new_dbLayout eq "sql") {
159 $add_step = 1 if $new_sql_username eq "" or $new_sql_password eq ""
160 or $new_sql_database eq "" or $new_sql_wwhost eq "";
161 } elsif ($new_dbLayout eq "gdbm") {
162 $add_step = 1 if $new_gdbm_globalUserID eq "";
163 } 160 }
161
162 elsif ($subDisplay eq "delete_course") {
163 if (defined $r->param("delete_course")) {
164 # validate or confirm
165 my @errors = $self->delete_course_validate;
166 if (@errors) {
167 print CGI::div({class=>"ResultsWithError"},
168 CGI::p("Please correct the following errors and try again:"),
169 CGI::ul(CGI::li(\@errors)),
170 );
171 $self->delete_course_form;
172 } else {
173 $self->delete_course_confirm;
174 }
175 } elsif (defined $r->param("confirm_delete_course")) {
176 # validate and delete
177 my @errors = $self->delete_course_validate;
178 if (@errors) {
179 print CGI::div({class=>"ResultsWithError"},
180 CGI::p("Please correct the following errors and try again:"),
181 CGI::ul(CGI::li(\@errors)),
182 );
183 $self->delete_course_form;
184 } else {
185 $self->do_delete_course;
186 }
187 } else {
188 # form only
189 $self->delete_course_form;
190 }
164 } 191 }
165 192
166 if ($add_step > 2) {
167 $add_step = 2 if $new_initial_userID ne "" and $new_initial_password eq "";
168 } 193 }
169 194
170 my $ce2; 195 return "";
171 if ($new_courseID) { 196}
197
198sub add_course_form {
199 my ($self) = @_;
200 my $r = $self->r;
201 my $ce = $r->ce;
202 #my $db = $r->db;
203 #my $authz = $r->authz;
204 #my $urlpath = $r->urlpath;
205
206 my $add_courseID = $r->param("add_courseID") || "";
207 my $add_dbLayout = $r->param("add_dbLayout") || "";
208 my $add_sql_host = $r->param("add_sql_host") || "";
209 my $add_sql_port = $r->param("add_sql_port") || "";
210 my $add_sql_username = $r->param("add_sql_username") || "";
211 my $add_sql_password = $r->param("add_sql_password") || "";
212 my $add_sql_database = $r->param("add_sql_database") || "";
213 my $add_sql_wwhost = $r->param("add_sql_wwhost") || "";
214 my $add_gdbm_globalUserID = $r->param("add_gdbm_globalUserID") || "";
215 my $add_initial_userID = $r->param("add_initial_userID") || "";
216 my $add_initial_password = $r->param("add_initial_password") || "";
217
218 my @dbLayouts = sort keys %{ $ce->{dbLayouts} };
219
172 $ce2 = WeBWorK::CourseEnvironment->new( 220 my $ce2 = WeBWorK::CourseEnvironment->new(
173 $ce->{webworkDirs}->{root}, 221 $ce->{webworkDirs}->{root},
174 $ce->{webworkURLs}->{root}, 222 $ce->{webworkURLs}->{root},
175 "FAKE_PG_ROOT", # heh, there's no way to get the PG root out... damn. 223 $ce->{pg}->{directories}->{root},
176 $new_courseID, 224 "COURSENAME",
177 ); 225 );
226
227 my $dbi_source = do {
228 # find the most common SQL source (stolen from CourseManagement.pm)
229 my %sources;
230 foreach my $table (keys %{ $ce2->{dbLayouts}->{sql} }) {
231 $sources{$ce2->{dbLayouts}->{sql}->{$table}->{source}}++;
178 } 232 }
233 my $source;
234 if (keys %sources > 1) {
235 foreach my $curr (keys %sources) {
236 $source = $curr if @{ $sources{$curr} } > @{ $sources{$source} };
237 }
238 } else {
239 ($source) = keys %sources;
240 }
241 $source;
242 };
179 243
180 if ($add_step >= 0 and $add_step < $add_step_max) { 244 print CGI::h2("Add Course");
245
181 print CGI::start_form("POST", $r->uri); 246 print CGI::start_form("POST", $r->uri);
182 print $self->hidden_authen_fields; 247 print $self->hidden_authen_fields;
183 print CGI::hidden("add_step", 1); 248 print $self->hidden_fields("subDisplay");
249
250 print CGI::p("Specify a name for the new course.");
251
184 print CGI::table({class=>"FormLayout"}, 252 print CGI::table({class=>"FormLayout"},
185 CGI::Tr( 253 CGI::Tr(
186 CGI::th({class=>"LeftHeader"}, "Course Name:"), 254 CGI::th({class=>"LeftHeader"}, "Course Name:"),
187 CGI::td( 255 CGI::td(CGI::textfield("add_courseID", $add_courseID, 25)),
188 CGI::textfield(
189 -name => "new_courseID",
190 -value => defined $new_courseID ? $new_courseID : "",
191 -size => 50,
192 ),
193 ), 256 ),
257 );
258
259 print CGI::p("Select a database layout below. Some database layouts require additional information.");
260
261 #print CGI::start_Tr();
262 #print CGI::th({class=>"LeftHeader"}, "Database Layout:");
263 #print CGI::start_td();
264
265 foreach my $dbLayout (@dbLayouts) {
266 print CGI::start_table({class=>"FormLayout"});
267
268 # we generate singleton radio button tags ourselves because it's too much of a pain to do it with CGI.pm
269 print CGI::Tr(
270 CGI::td({style=>"text-align: right"},
271 '<input type="radio" name="add_dbLayout" value="' . $dbLayout . '"'
272 . ($add_dbLayout eq $dbLayout ? " checked" : "") . ' />',
194 ), 273 ),
195 CGI::Tr( 274 CGI::td($dbLayout),
196 CGI::th({class=>"LeftHeader"}, "Database Layout:"),
197 CGI::td(
198 CGI::popup_menu(
199 -name => "new_dbLayout",
200 -values => [ sort keys %{ $ce->{dbLayouts} } ],
201 -default => defined $new_dbLayout ? $new_dbLayout : "",
202 ),
203 ),
204 ),
205 CGI::Tr({class=>"ButtonRow"},
206 CGI::td({colspan=>2},
207 CGI::submit(
208 -name => "create_course",
209 -value => ($add_step > 0 ? "Change" : "Continue"),
210 ),
211 ),
212 ),
213 ); 275 );
214 print CGI::end_form(); 276
215 }
216
217 if ($add_step >= 1 and $add_step < $add_step_max) {
218 print CGI::hr(); 277 print CGI::start_Tr();
278 print CGI::td(); # for indentation :(
279 print CGI::start_td();
219 280
220 print CGI::start_form("POST", $r->uri);
221 print $self->hidden_authen_fields;
222 print CGI::hidden("add_step", 2);
223
224 print CGI::hidden("new_courseID", $new_courseID);
225 print CGI::hidden("new_dbLayout", $new_dbLayout);
226 print CGI::hidden("new_skipDBCreation", $new_skipDBCreation);
227
228 # there are specific things we're doing per database layout:
229 if ($new_dbLayout eq "sql") { 281 if ($dbLayout eq "sql") {
230 {
231 # find the most common SQL source (stolen from CourseManagement.pm)
232 my %sources;
233 foreach my $table (keys %{ $ce2->{dbLayouts}->{sql} }) {
234 $sources{$ce2->{dbLayouts}->{sql}->{$table}->{source}}++;
235 }
236 my $source;
237 if (keys %sources > 1) {
238 foreach my $curr (keys %sources) {
239 $source = $curr if @{ $sources{$curr} } > @{ $sources{$source} };
240 }
241 } else {
242 ($source) = keys %sources;
243 }
244
245 print CGI::p( 282 print CGI::p(
246 CGI::checkbox( 283 "The SQL settings you enter below must match the settings in the DBI source",
247 -name => "new_skipDBCreation", 284 " specification ", CGI::tt($dbi_source), ". Replace ", CGI::tt("COURSENAME"),
248 -checked => $new_skipDBCreation, 285 " with the course name you entered above."
249 -value => "1",
250 -label => "Skip database creation",
251 ),
252 CGI::br(),
253 "If this is selected, you need not fill in the SQL settings below. However, you must create the database manually before creating this course.",
254 ); 286 );
255
256 # print instructions
257 print CGI::p("The SQL settings you enter below must match the settings in this DBI source specification:");
258 print CGI::p({style=>"text-align:center"}, CGI::tt($source));
259 if (keys %sources > 1) {
260 print CGI::p("Note that there is more than one DBI source in this database layout. Only tables using the most common source (above) will be created.");
261 }
262 }
263
264 print CGI::start_table({class=>"FormLayout"}); 287 print CGI::start_table({class=>"FormLayout"});
265 print CGI::Tr( 288 print CGI::Tr(
266 CGI::th({class=>"LeftHeader"}, "SQL Server Host:"), 289 CGI::th({class=>"LeftHeader"}, "SQL Server Host:"),
267 CGI::td( 290 CGI::td(
268 CGI::textfield( 291 CGI::textfield("add_sql_host", $add_sql_host, 25),
269 -name => "new_sql_host",
270 -value => defined $new_sql_host ? $new_sql_host : "",
271 -size => 50,
272 ),
273 CGI::br(), 292 CGI::br(),
274 CGI::small("Leave blank to use the default host."), 293 CGI::small("Leave blank to use the default host."),
275 ), 294 ),
276 ); 295 );
277 print CGI::Tr( 296 print CGI::Tr(
278 CGI::th({class=>"LeftHeader"}, "SQL Server Port:"), 297 CGI::th({class=>"LeftHeader"}, "SQL Server Port:"),
279 CGI::td( 298 CGI::td(
280 CGI::textfield( 299 CGI::textfield("add_sql_port", $add_sql_port, 25),
281 -name => "new_sql_port",
282 -value => defined $new_sql_port ? $new_sql_port : "",
283 -size => 50,
284 ),
285 CGI::br(), 300 CGI::br(),
286 CGI::small("Leave blank to use the default port."), 301 CGI::small("Leave blank to use the default port."),
287 ), 302 ),
288 ); 303 );
289 print CGI::Tr( 304 print CGI::Tr(
290 CGI::th({class=>"LeftHeader"}, "SQL Admin Username:"), 305 CGI::th({class=>"LeftHeader"}, "SQL Admin Username:"),
291 CGI::td( 306 CGI::td(CGI::textfield("add_sql_username", $add_sql_username, 25)),
292 CGI::textfield(
293 -name => "new_sql_username",
294 -value => defined $new_sql_username ? $new_sql_username : "",
295 -size => 50,
296 ),
297 ),
298 ); 307 );
299 print CGI::Tr( 308 print CGI::Tr(
300 CGI::th({class=>"LeftHeader"}, "SQL Admin Password:"), 309 CGI::th({class=>"LeftHeader"}, "SQL Admin Password:"),
301 CGI::td( 310 CGI::td(CGI::password_field("add_sql_password", $add_sql_password, 25)),
302 CGI::password_field(
303 -name => "new_sql_password",
304 -value => defined $new_sql_password ? $new_sql_password : "",
305 -size => 50,
306 ),
307 ),
308 ); 311 );
309 print CGI::Tr( 312 print CGI::Tr(
310 CGI::th({class=>"LeftHeader"}, "SQL Database Name:"), 313 CGI::th({class=>"LeftHeader"}, "SQL Database Name:"),
311 CGI::td( 314 CGI::td(CGI::textfield("add_sql_database", $add_sql_database, 25)),
312 CGI::textfield(
313 -name => "new_sql_database",
314 -value => defined $new_sql_database ? $new_sql_database : "",
315 -size => 50,
316 ),
317 ),
318 ); 315 );
319 print CGI::Tr( 316 print CGI::Tr(
320 CGI::th({class=>"LeftHeader"}, "WeBWorK Host:"), 317 CGI::th({class=>"LeftHeader"}, "WeBWorK Host:"),
321 CGI::td( 318 CGI::td(
322 CGI::textfield( 319 CGI::textfield("add_sql_wwhost", $add_sql_wwhost || "localhost", 25),
323 -name => "new_sql_wwhost",
324 -value => defined $new_sql_wwhost ? $new_sql_wwhost : "localhost",
325 -size => 50,
326 ),
327 CGI::br(), 320 CGI::br(),
328 CGI::small("If the SQL server does not run on the same host as WeBWorK, enter the host name of the WeBWorK server as seen by the SQL server."), 321 CGI::small("If the SQL server does not run on the same host as WeBWorK, enter the host name of the WeBWorK server as seen by the SQL server."),
329 ), 322 ),
330 ); 323 );
324 print CGI::end_table();
331 } elsif ($new_dbLayout eq "gdbm") { 325 } elsif ($dbLayout eq "gdbm") {
332 print CGI::start_table({class=>"FormLayout"}); 326 print CGI::start_table({class=>"FormLayout"});
333 print CGI::Tr( 327 print CGI::Tr(
334 CGI::th({class=>"LeftHeader"}, "GDBM Global User ID:"), 328 CGI::th({class=>"LeftHeader"}, "GDBM Global User ID:"),
335 CGI::td( 329 CGI::td(CGI::textfield("add_gdbm_globalUserID", $add_gdbm_globalUserID || "professor", 25)),
336 CGI::textfield(
337 -name => "new_gdbm_globalUserID",
338 -value => defined $new_gdbm_globalUserID ? $new_gdbm_globalUserID : "global_user",
339 -size => 50,
340 ),
341 ),
342 ); 330 );
331 print CGI::end_table();
343 } 332 }
344 333
334 print CGI::end_td();
335 print CGI::end_Tr();
336 print CGI::end_table();
337 }
338
339
340 print CGI::p("To add an initial user to the new course, enter a user ID and password below. If you do not do so, you will not be able to log into the course.");
341
342 print CGI::table({class=>"FormLayout"},
343 CGI::Tr(
344 CGI::th({class=>"LeftHeader"}, "Professor User ID:"),
345 CGI::td(CGI::textfield("add_initial_userID", $add_initial_userID || "professor", 25)),
346 ),
347 CGI::Tr(
348 CGI::th({class=>"LeftHeader"}, "Professor Password:"),
349 CGI::td(CGI::password_field("add_initial_password", $add_initial_password, 25)),
350 ),
351 );
352
353 print CGI::p({style=>"text-align: center"}, CGI::submit("add_course", "Add Course"));
354
355 print CGI::end_form();
356}
357
358sub add_course_validate {
359 my ($self) = @_;
360 my $r = $self->r;
361 my $ce = $r->ce;
362 #my $db = $r->db;
363 #my $authz = $r->authz;
364 #my $urlpath = $r->urlpath;
365
366 my $add_courseID = $r->param("add_courseID") || "";
367 my $add_dbLayout = $r->param("add_dbLayout") || "";
368 my $add_sql_host = $r->param("add_sql_host") || "";
369 my $add_sql_port = $r->param("add_sql_port") || "";
370 my $add_sql_username = $r->param("add_sql_username") || "";
371 my $add_sql_password = $r->param("add_sql_password") || "";
372 my $add_sql_database = $r->param("add_sql_database") || "";
373 my $add_sql_wwhost = $r->param("add_sql_wwhost") || "";
374 my $add_gdbm_globalUserID = $r->param("add_gdbm_globalUserID") || "";
375 my $add_initial_userID = $r->param("add_initial_userID") || "";
376 my $add_initial_password = $r->param("add_initial_password") || "";
377
378 my @errors;
379
380 if ($add_courseID eq "") {
381 push @errors, "You must specify a course name.";
382 }
383
384 if ($add_dbLayout eq "") {
385 push @errors, "You must select a database layout.";
386 } else {
387 if (exists $ce->{dbLayouts}->{$add_dbLayout}) {
388 if ($add_dbLayout eq "sql") {
389 push @errors, "You must specify the SQL admin username." if $add_sql_username eq "";
390 push @errors, "You must specify the SQL admin password." if $add_sql_password eq "";
391 push @errors, "You must specify the SQL confirm_delete_course." if $add_sql_database eq "";
392 push @errors, "You must specify the WeBWorK host." if $add_sql_wwhost eq "";
393 } elsif ($add_dbLayout eq "gdbm") {
394 push @errors, "You must specify the GDBM global user ID." if $add_gdbm_globalUserID eq "";
395 }
396 } else {
397 push @errors, "The database layout $add_dbLayout doesn't exist.";
345 398 }
346 print CGI::Tr({class=>"ButtonRow"}, 399 }
347 CGI::td({colspan=>2}, 400
348 CGI::submit( 401 if ($add_initial_userID ne "") {
402 push @errors, "You must specify a professor password." if $add_initial_password eq "";
403 }
404
405 return @errors;
406}
407
408sub do_add_course {
409 my ($self) = @_;
410 my $r = $self->r;
411 my $ce = $r->ce;
412 my $db = $r->db;
413 #my $authz = $r->authz;
414 my $urlpath = $r->urlpath;
415
416 my $add_courseID = $r->param("add_courseID") || "";
417 my $add_dbLayout = $r->param("add_dbLayout") || "";
418 my $add_sql_host = $r->param("add_sql_host") || "";
419 my $add_sql_port = $r->param("add_sql_port") || "";
420 my $add_sql_username = $r->param("add_sql_username") || "";
421 my $add_sql_password = $r->param("add_sql_password") || "";
422 my $add_sql_database = $r->param("add_sql_database") || "";
423 my $add_sql_wwhost = $r->param("add_sql_wwhost") || "";
424 my $add_gdbm_globalUserID = $r->param("add_gdbm_globalUserID") || "";
425 my $add_initial_userID = $r->param("add_initial_userID") || "";
426 my $add_initial_password = $r->param("add_initial_password") || "";
427
428 my $ce2 = WeBWorK::CourseEnvironment->new(
429 $ce->{webworkDirs}->{root},
430 $ce->{webworkURLs}->{root},
431 $ce->{pg}->{directories}->{root},
432 $add_courseID,
433 );
434
435 my %dbOptions;
436 if ($add_dbLayout eq "sql") {
437 $dbOptions{host} = $add_sql_host if $add_sql_host ne "";
438 $dbOptions{port} = $add_sql_port if $add_sql_port ne "";
439 $dbOptions{username} = $add_sql_username;
440 $dbOptions{password} = $add_sql_password;
441 $dbOptions{database} = $add_sql_database;
442 $dbOptions{wwhost} = $add_sql_wwhost;
443 }
444
445 my @users;
446 if ($add_initial_userID ne "") {
447 my $User = $db->newUser(
448 user_id => $add_initial_userID,
449 status => "C",
450 );
451 my $Password = $db->newPassword(
452 user_id => $add_initial_userID,
453 password => cryptPassword($add_initial_password),
454 );
455 my $PermissionLevel = $db->newPermissionLevel(
456 user_id => $add_initial_userID,
457 permission => "10",
458 );
459 push @users, [ $User, $Password, $PermissionLevel ];
460 }
461
462 eval {
463 addCourse(
464 courseID => $add_courseID,
465 ce => $ce2,
466 courseOptions => { dbLayoutName => $add_dbLayout },
467 dbOptions => \%dbOptions,
468 users => \@users,
469 );
470 };
471
472 if ($@) {
473 my $error = $@;
474 print CGI::div({class=>"ResultsWithError"},
475 CGI::p("An error occured while creating the course $add_courseID:"),
476 CGI::tt(CGI::escapeHTML($error)),
477 );
478 } else {
479 print CGI::div({class=>"ResultsWithoutError"},
480 CGI::p("Successfully created the course $add_courseID"),
481 );
482 my $newCoursePath = $urlpath->newFromModule("WeBWorK::ContentGenerator::ProblemSets",
483 courseID => $add_courseID);
484 my $newCourseURL = $self->systemLink($newCoursePath, authen => 0);
485 print CGI::div({style=>"text-align: center"},
486 CGI::a({href=>$newCourseURL}, "Log into $add_courseID"),
487 );
488 }
489}
490
491################################################################################
492
493sub delete_course_form {
494 my ($self) = @_;
495 my $r = $self->r;
496 my $ce = $r->ce;
497 #my $db = $r->db;
498 #my $authz = $r->authz;
499 #my $urlpath = $r->urlpath;
500
501 my $delete_courseID = $r->param("delete_courseID") || "";
502 my $delete_sql_host = $r->param("delete_sql_host") || "";
503 my $delete_sql_port = $r->param("delete_sql_port") || "";
504 my $delete_sql_username = $r->param("delete_sql_username") || "";
505 my $delete_sql_password = $r->param("delete_sql_password") || "";
506 my $delete_sql_database = $r->param("delete_sql_database") || "";
507
508 my @courseIDs = listCourses($ce);
509
510 my %courseLabels; # records... heh.
511 foreach my $courseID (@courseIDs) {
512 my $tempCE = WeBWorK::CourseEnvironment->new(
513 $ce->{webworkDirs}->{root},
514 $ce->{webworkURLs}->{root},
515 $ce->{pg}->{directories}->{root},
516 $courseID,
517 );
518 $courseLabels{$courseID} = "$courseID (" . $tempCE->{dbLayoutName} . ")";
519 }
520
521 print CGI::h2("Delete Course");
522
523 print CGI::start_form("POST", $r->uri);
524 print $self->hidden_authen_fields;
525 print $self->hidden_fields("subDisplay");
526
527 print CGI::p("Select a course to delete.");
528
529 print CGI::table({class=>"FormLayout"},
530 CGI::Tr(
531 CGI::th({class=>"LeftHeader"}, "Course Name:"),
532 CGI::td(
533 CGI::scrolling_list(
349 -name => "add_course", 534 -name => "delete_courseID",
350 -value => ($add_step > 1 ? "Change" : "Continue"), 535 -values => \@courseIDs,
536 -default => $delete_courseID,
537 -size => 10,
538 -multiple => 0,
539 -labels => \%courseLabels,
351 ), 540 ),
352 ), 541 ),
542 ),
353 ); 543 );
544
545 print CGI::p(
546 "If the course's database layout (indicated in parentheses above) is "
547 . CGI::b("sql") . ", supply the SQL connections information requested below."
548 );
549
550 print CGI::start_table({class=>"FormLayout"});
551 print CGI::Tr(
552 CGI::th({class=>"LeftHeader"}, "SQL Server Host:"),
553 CGI::td(
554 CGI::textfield("delete_sql_host", $delete_sql_host, 25),
555 CGI::br(),
556 CGI::small("Leave blank to use the default host."),
557 ),
558 );
559 print CGI::Tr(
560 CGI::th({class=>"LeftHeader"}, "SQL Server Port:"),
561 CGI::td(
562 CGI::textfield("delete_sql_port", $delete_sql_port, 25),
563 CGI::br(),
564 CGI::small("Leave blank to use the default port."),
565 ),
566 );
567 print CGI::Tr(
568 CGI::th({class=>"LeftHeader"}, "SQL Admin Username:"),
569 CGI::td(CGI::textfield("delete_sql_username", $delete_sql_username, 25)),
570 );
571 print CGI::Tr(
572 CGI::th({class=>"LeftHeader"}, "SQL Admin Password:"),
573 CGI::td(CGI::password_field("delete_sql_password", $delete_sql_password, 25)),
574 );
575 print CGI::Tr(
576 CGI::th({class=>"LeftHeader"}, "SQL Database Name:"),
577 CGI::td(CGI::textfield("delete_sql_database", $delete_sql_database, 25)),
578 );
354 print CGI::end_table(); 579 print CGI::end_table();
580
581 print CGI::p({style=>"text-align: center"}, CGI::submit("delete_course", "Delete Course"));
582
355 print CGI::end_form(); 583 print CGI::end_form();
584}
585
586sub delete_course_validate {
587 my ($self) = @_;
588 my $r = $self->r;
589 my $ce = $r->ce;
590 #my $db = $r->db;
591 #my $authz = $r->authz;
592 my $urlpath = $r->urlpath;
593
594 my $delete_courseID = $r->param("delete_courseID") || "";
595 my $delete_sql_host = $r->param("delete_sql_host") || "";
596 my $delete_sql_port = $r->param("delete_sql_port") || "";
597 my $delete_sql_username = $r->param("delete_sql_username") || "";
598 my $delete_sql_password = $r->param("delete_sql_password") || "";
599 my $delete_sql_database = $r->param("delete_sql_database") || "";
600
601 my @courseIDs = listCourses($ce);
602
603 my %courseLabels; # records... heh.
604 foreach my $courseID (@courseIDs) {
605 my $tempCE = WeBWorK::CourseEnvironment->new(
606 $ce->{webworkDirs}->{root},
607 $ce->{webworkURLs}->{root},
608 $ce->{pg}->{directories}->{root},
609 $courseID,
610 );
611 $courseLabels{$courseID} = "$courseID (" . $tempCE->{dbLayoutName} . ")";
612 }
613
614 my @errors;
615
616 if ($delete_courseID eq "") {
617 push @errors, "You must specify a course name.";
618 } elsif ($delete_courseID eq $urlpath->arg("courseID")) {
619 push @errors, "You cannot delete the course you are currently using.";
620 }
621
622 my $ce2 = WeBWorK::CourseEnvironment->new(
623 $ce->{webworkDirs}->{root},
624 $ce->{webworkURLs}->{root},
625 $ce->{pg}->{directories}->{root},
626 $delete_courseID,
627 );
628
629 if ($ce2->{dbLayoutName} eq "sql") {
630 push @errors, "You must specify the SQL admin username." if $delete_sql_username eq "";
631 push @errors, "You must specify the SQL admin password." if $delete_sql_password eq "";
632 push @errors, "You must specify the SQL database name." if $delete_sql_database eq "";
633 }
634
635 return @errors;
636}
637
638sub delete_course_confirm {
639 my ($self) = @_;
640 my $r = $self->r;
641 my $ce = $r->ce;
642 #my $db = $r->db;
643 #my $authz = $r->authz;
644 #my $urlpath = $r->urlpath;
645
646 print CGI::h2("Delete Course");
647
648 my $delete_courseID = $r->param("delete_courseID") || "";
649 my $delete_sql_host = $r->param("delete_sql_host") || "";
650 my $delete_sql_port = $r->param("delete_sql_port") || "";
651 my $delete_sql_database = $r->param("delete_sql_database") || "";
652
653 my $ce2 = WeBWorK::CourseEnvironment->new(
654 $ce->{webworkDirs}->{root},
655 $ce->{webworkURLs}->{root},
656 $ce->{pg}->{directories}->{root},
657 $delete_courseID,
658 );
659
660 if ($ce2->{dbLayoutName} eq "sql") {
661 print CGI::p("Are you sure you want to delete the course " . CGI::b($delete_courseID)
662 . "? All course files and data and the following database will be destroyed."
663 . " There is no undo available.");
664
665 print CGI::table({class=>"FormLayout"},
666 CGI::Tr(
667 CGI::th({class=>"LeftHeader"}, "SQL Server Host:"),
668 CGI::td($delete_sql_host || "system default"),
669 ),
670 CGI::Tr(
671 CGI::th({class=>"LeftHeader"}, "SQL Server Port:"),
672 CGI::td($delete_sql_port || "system default"),
673 ),
674 CGI::Tr(
675 CGI::th({class=>"LeftHeader"}, "SQL Database Name:"),
676 CGI::td($delete_sql_database),
677 ),
678 );
679 } else {
680 print CGI::p("Are you sure you want to delete the course " . CGI::b($delete_courseID)
681 . "? All course files and data will be destroyed. There is no undo available.");
682 }
683
684 print CGI::start_form("POST", $r->uri);
685 print $self->hidden_authen_fields;
686 print $self->hidden_fields("subDisplay");
687 print $self->hidden_fields(qw/delete_courseID delete_sql_host delete_sql_port delete_sql_username delete_sql_password delete_sql_database/);
688
689 print CGI::p({style=>"text-align: center"},
690 CGI::submit("decline_delete_course", "Don't delete"),
691 "&nbsp;",
692 CGI::submit("confirm_delete_course", "Delete"),
693 );
694
695 print CGI::end_form();
696}
697
698sub do_delete_course {
699 my ($self) = @_;
700 my $r = $self->r;
701 my $ce = $r->ce;
702 #my $db = $r->db;
703 #my $authz = $r->authz;
704 #my $urlpath = $r->urlpath;
705
706 my $delete_courseID = $r->param("delete_courseID") || "";
707 my $delete_sql_host = $r->param("delete_sql_host") || "";
708 my $delete_sql_port = $r->param("delete_sql_port") || "";
709 my $delete_sql_username = $r->param("delete_sql_username") || "";
710 my $delete_sql_password = $r->param("delete_sql_password") || "";
711 my $delete_sql_database = $r->param("delete_sql_database") || "";
712
713 my $ce2 = WeBWorK::CourseEnvironment->new(
714 $ce->{webworkDirs}->{root},
715 $ce->{webworkURLs}->{root},
716 $ce->{pg}->{directories}->{root},
717 $delete_courseID,
718 );
719
720 my %dbOptions;
721 if ($ce2->{dbLayoutName} eq "sql") {
722 $dbOptions{host} = $delete_sql_host if $delete_sql_host ne "";
723 $dbOptions{port} = $delete_sql_port if $delete_sql_port ne "";
724 $dbOptions{username} = $delete_sql_username;
725 $dbOptions{password} = $delete_sql_password;
726 $dbOptions{database} = $delete_sql_database;
727 }
728
729 eval {
730 deleteCourse(
731 courseID => $delete_courseID,
732 ce => $ce2,
733 dbOptions => \%dbOptions,
734 );
356 } 735 };
357 736
358 if ($add_step >= 2 and $add_step < $add_step_max) { 737 if ($@) {
359 print CGI::hr(); 738 my $error = $@;
739 print CGI::div({class=>"ResultsWithError"},
740 CGI::p("An error occured while deleting the course $delete_courseID:"),
741 CGI::tt(CGI::escapeHTML($error)),
742 );
743 } else {
744 print CGI::div({class=>"ResultsWithoutError"},
745 CGI::p("Possibly deleted the course $delete_courseID. (We need better error checking in deleteCourse().)"),
746 );
360 747
361 print CGI::start_form("POST", $r->uri); 748 print CGI::start_form("POST", $r->uri);
362 print $self->hidden_authen_fields; 749 print $self->hidden_authen_fields;
363 print CGI::hidden("add_step", 4); 750 print $self->hidden_fields("subDisplay");
364 751
365 print CGI::hidden("new_courseID", $new_courseID); 752 print CGI::p({style=>"text-align: center"}, CGI::submit("decline_delete_course", "OK"),);
366 print CGI::hidden("new_dbLayout", $new_dbLayout);
367 print CGI::hidden("new_skipDBCreation", $new_skipDBCreation);
368 print CGI::hidden("new_sql_host", $new_sql_host);
369 print CGI::hidden("new_sql_port", $new_sql_port);
370 print CGI::hidden("new_sql_username", $new_sql_username);
371 print CGI::hidden("new_sql_password", $new_sql_password);
372 print CGI::hidden("new_sql_database", $new_sql_database);
373 print CGI::hidden("new_sql_wwhost", $new_sql_wwhost);
374 print CGI::hidden("new_gdbm_globalUserID", $new_gdbm_globalUserID);
375 753
376 print CGI::start_table({class=>"FormLayout"});
377 print CGI::Tr(
378 CGI::th({class=>"LeftHeader"}, "Professor User ID:"),
379 CGI::td(
380 CGI::textfield(
381 -name => "new_initial_userID",
382 -value => defined $new_initial_userID ? $new_initial_userID : "professor",
383 -size => 50,
384 ),
385 CGI::br(),
386 CGI::small("Leave blank to skip user creation."),
387 ),
388 );
389 print CGI::Tr(
390 CGI::th({class=>"LeftHeader"}, "Professor Password:"),
391 CGI::td(
392 CGI::password_field(
393 -name => "new_initial_password",
394 -value => defined $new_initial_password ? $new_initial_password : "",
395 -size => 50,
396 ),
397 ),
398 );
399 print CGI::Tr({class=>"ButtonRow"},
400 CGI::td({colspan=>2},
401 CGI::submit(
402 -name => "add_course",
403 -value => ($add_step > 1 ? "Change" : "Continue"),
404 ),
405 ),
406 );
407 print CGI::end_table();
408 print CGI::end_form(); 754 print CGI::end_form();
409 } 755 }
410
411 if ($add_step >= 3 and $add_step < $add_step_max) {
412 print CGI::hr();
413
414 print CGI::start_form("POST", $r->uri);
415 print $self->hidden_authen_fields;
416 print CGI::hidden("add_step", 4);
417
418 print CGI::hidden("new_courseID", $new_courseID);
419 print CGI::hidden("new_dbLayout", $new_dbLayout);
420 print CGI::hidden("new_skipDBCreation", $new_skipDBCreation);
421 print CGI::hidden("new_sql_host", $new_sql_host);
422 print CGI::hidden("new_sql_port", $new_sql_port);
423 print CGI::hidden("new_sql_username", $new_sql_username);
424 print CGI::hidden("new_sql_password", $new_sql_password);
425 print CGI::hidden("new_sql_database", $new_sql_database);
426 print CGI::hidden("new_sql_wwhost", $new_sql_wwhost);
427 print CGI::hidden("new_gdbm_globalUserID", $new_gdbm_globalUserID);
428 print CGI::hidden("new_initial_userID", $new_initial_userID);
429 print CGI::hidden("new_initial_password", $new_initial_password);
430
431 print CGI::p("Ready to create the new course. Click ", CGI::b("Create"), "below to do so:");
432 print CGI::submit(
433 -name => "create_course",
434 -value => "Create",
435 );
436 }
437
438 if ($add_step == $add_step_max) {
439 # we're creating the course
440
441 my %dbOptions;
442 if ($new_dbLayout eq "sql") {
443 $dbOptions{host} = $new_sql_host if $new_sql_host ne "";
444 $dbOptions{port} = $new_sql_port if $new_sql_port ne "";
445 $dbOptions{username} = $new_sql_username;
446 $dbOptions{password} = $new_sql_password;
447 $dbOptions{database} = $new_sql_database;
448 $dbOptions{wwhost} = $new_sql_wwhost;
449 }
450
451 my @users;
452 if ($new_initial_userID ne "") {
453 my $User = $db->newUser(
454 user_id => $new_initial_userID,
455 status => "C",
456 );
457 my $Password = $db->newPassword(
458 user_id => $new_initial_userID,
459 password => cryptPassword($new_initial_password),
460 );
461 my $PermissionLevel = $db->newPermissionLevel(
462 user_id => $new_initial_userID,
463 permission => "10",
464 );
465 push @users, [ $User, $Password, $PermissionLevel ];
466 }
467
468 eval {
469 addCourse(
470 courseID => $new_courseID,
471 ce => $ce2,
472 courseOptions => { dbLayoutName => $new_dbLayout },
473 dbOptions => \%dbOptions,
474 users => \@users,
475 )
476 };
477
478 if ($@) {
479 my $error = $@;
480 print CGI::div({class=>"ResultsWithError"},
481 CGI::p("An error occured while creating the course $new_courseID:"),
482 CGI::tt(CGI::escapeHTML($error)),
483 );
484 } else {
485 print CGI::div({class=>"ResultsWithoutError"},
486 CGI::p("Successfully created the course $new_courseID"),
487 );
488 }
489 }
490
491 return "";
492} 756}
493 757
4941; 7581;

Legend:
Removed from v.1945  
changed lines
  Added in v.1960

aubreyja at gmail dot com
ViewVC Help
Powered by ViewVC 1.0.9