| 1 | ################################################################################ |
1 | ################################################################################ |
| 2 | # WeBWorK Online Homework Delivery System |
2 | # WeBWorK Online Homework Delivery System |
| 3 | # Copyright © 2000-2006 The WeBWorK Project, http://openwebwork.sf.net/ |
3 | # Copyright © 2000-2006 The WeBWorK Project, http://openwebwork.sf.net/ |
| 4 | # $CVSHeader: webwork2/lib/WeBWorK/ContentGenerator/CourseAdmin.pm,v 1.42 2005/11/07 21:20:57 sh002i Exp $ |
4 | # $CVSHeader: webwork2/lib/WeBWorK/ContentGenerator/CourseAdmin.pm,v 1.43 2006/01/25 23:13:52 sh002i Exp $ |
| 5 | # |
5 | # |
| 6 | # This program is free software; you can redistribute it and/or modify it under |
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 |
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 |
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. |
9 | # version, or (b) the "Artistic License" which comes with this package. |
| … | |
… | |
| 28 | use CGI qw(); |
28 | use CGI qw(); |
| 29 | use Data::Dumper; |
29 | use Data::Dumper; |
| 30 | use File::Temp qw/tempfile/; |
30 | use File::Temp qw/tempfile/; |
| 31 | use WeBWorK::CourseEnvironment; |
31 | use WeBWorK::CourseEnvironment; |
| 32 | use IO::File; |
32 | use IO::File; |
|
|
33 | use WeBWorK::Debug; |
| 33 | use WeBWorK::Utils qw(cryptPassword writeLog listFilesRecursive); |
34 | use WeBWorK::Utils qw(cryptPassword writeLog listFilesRecursive); |
| 34 | use WeBWorK::Utils::CourseManagement qw(addCourse renameCourse deleteCourse listCourses archiveCourse); |
35 | use WeBWorK::Utils::CourseManagement qw(addCourse renameCourse deleteCourse listCourses archiveCourse); |
| 35 | use WeBWorK::Utils::DBImportExport qw(dbExport dbImport); |
36 | use WeBWorK::Utils::DBImportExport qw(dbExport dbImport); |
| 36 | |
|
|
| 37 | # put the following database layouts at the top of the list, in this order |
|
|
| 38 | our @DB_LAYOUT_ORDER = qw/sql_single gdbm sql/; |
|
|
| 39 | |
|
|
| 40 | our %DB_LAYOUT_DESCRIPTIONS = ( |
|
|
| 41 | gdbm => CGI::i("Deprecated. Uses GDBM databases to record WeBWorK data. Use this layout if the course must be used with WeBWorK 1.x."), |
|
|
| 42 | sql => CGI::i("Deprecated. Uses a separate SQL database to record WeBWorK data for each course."), |
|
|
| 43 | sql_single => "Uses a single SQL database to record WeBWorK data for all courses using this layout. This is the recommended layout for new courses.", |
|
|
| 44 | ); |
|
|
| 45 | |
37 | |
| 46 | sub pre_header_initialize { |
38 | sub pre_header_initialize { |
| 47 | my ($self) = @_; |
39 | my ($self) = @_; |
| 48 | my $r = $self->r; |
40 | my $r = $self->r; |
| 49 | my $ce = $r->ce; |
41 | my $ce = $r->ce; |
| … | |
… | |
| 364 | my $add_sql_wwhost = $r->param("add_sql_wwhost") || ""; |
356 | my $add_sql_wwhost = $r->param("add_sql_wwhost") || ""; |
| 365 | my $add_gdbm_globalUserID = $r->param("add_gdbm_globalUserID") || ""; |
357 | my $add_gdbm_globalUserID = $r->param("add_gdbm_globalUserID") || ""; |
| 366 | |
358 | |
| 367 | my @dbLayouts = do { |
359 | my @dbLayouts = do { |
| 368 | my @ordered_layouts; |
360 | my @ordered_layouts; |
| 369 | foreach my $layout (@DB_LAYOUT_ORDER) { |
361 | foreach my $layout (@{$ce->{dbLayout_order}}) { |
| 370 | if (exists $ce->{dbLayouts}->{$layout}) { |
362 | if (exists $ce->{dbLayouts}->{$layout}) { |
| 371 | push @ordered_layouts, $layout; |
363 | push @ordered_layouts, $layout; |
| 372 | } |
364 | } |
| 373 | } |
365 | } |
| 374 | |
366 | |
| … | |
… | |
| 387 | $ce->{webworkDirs}->{root}, |
379 | $ce->{webworkDirs}->{root}, |
| 388 | $ce->{webworkURLs}->{root}, |
380 | $ce->{webworkURLs}->{root}, |
| 389 | $ce->{pg}->{directories}->{root}, |
381 | $ce->{pg}->{directories}->{root}, |
| 390 | "COURSENAME", |
382 | "COURSENAME", |
| 391 | ); |
383 | ); |
| 392 | |
|
|
| 393 | my $dbi_source = do { |
|
|
| 394 | # find the most common SQL source (stolen from CourseManagement.pm) |
|
|
| 395 | my %sources; |
|
|
| 396 | foreach my $table (keys %{ $ce2->{dbLayouts}->{sql} }) { |
|
|
| 397 | $sources{$ce2->{dbLayouts}->{sql}->{$table}->{source}}++; |
|
|
| 398 | } |
|
|
| 399 | my $source; |
|
|
| 400 | if (keys %sources > 1) { |
|
|
| 401 | foreach my $curr (keys %sources) { |
|
|
| 402 | $source = $curr if not defined $source or |
|
|
| 403 | $sources{$curr} > $sources{$source}; |
|
|
| 404 | } |
|
|
| 405 | } else { |
|
|
| 406 | ($source) = keys %sources; |
|
|
| 407 | } |
|
|
| 408 | $source; |
|
|
| 409 | }; |
|
|
| 410 | |
384 | |
| 411 | my @existingCourses = listCourses($ce); |
385 | my @existingCourses = listCourses($ce); |
| 412 | @existingCourses = sort { lc($a) cmp lc ($b) } @existingCourses; #make sort case insensitive |
386 | @existingCourses = sort { lc($a) cmp lc ($b) } @existingCourses; #make sort case insensitive |
| 413 | |
387 | |
| 414 | print CGI::h2("Add Course"); |
388 | print CGI::h2("Add Course"); |
| … | |
… | |
| 498 | print CGI::p("Select a database layout below."); |
472 | print CGI::p("Select a database layout below."); |
| 499 | |
473 | |
| 500 | foreach my $dbLayout (@dbLayouts) { |
474 | foreach my $dbLayout (@dbLayouts) { |
| 501 | print CGI::start_table({class=>"FormLayout"}); |
475 | print CGI::start_table({class=>"FormLayout"}); |
| 502 | |
476 | |
| 503 | my $dbLayoutLabel = (defined $DB_LAYOUT_DESCRIPTIONS{$dbLayout}) |
477 | my $dbLayoutLabel = (defined $ce->{dbLayout_descr}{$dbLayout}) |
| 504 | ? "$dbLayout - $DB_LAYOUT_DESCRIPTIONS{$dbLayout}" |
478 | ? "$dbLayout - " . $ce->{dbLayout_descr}{$dbLayout} |
| 505 | : $dbLayout; |
479 | : $dbLayout; |
| 506 | |
480 | |
| 507 | # we generate singleton radio button tags ourselves because it's too much of a pain to do it with CGI.pm |
481 | # we generate singleton radio button tags ourselves because it's too much of a pain to do it with CGI.pm |
| 508 | print CGI::Tr( |
482 | print CGI::Tr( |
| 509 | CGI::td({style=>"text-align: right"}, |
483 | CGI::td({style=>"text-align: right"}, |
| … | |
… | |
| 511 | . ($add_dbLayout eq $dbLayout ? " checked" : "") . ' />', |
485 | . ($add_dbLayout eq $dbLayout ? " checked" : "") . ' />', |
| 512 | ), |
486 | ), |
| 513 | CGI::td($dbLayoutLabel), |
487 | CGI::td($dbLayoutLabel), |
| 514 | ); |
488 | ); |
| 515 | |
489 | |
| 516 | print CGI::start_Tr(); |
|
|
| 517 | print CGI::td(); # for indentation :( |
|
|
| 518 | print CGI::start_td(); |
|
|
| 519 | |
|
|
| 520 | |
|
|
| 521 | if ($dbLayout eq "sql") { |
|
|
| 522 | |
|
|
| 523 | print CGI::p({style=>'font-style:italic'},"The following information is only required for the deprecated sql database format:"); |
|
|
| 524 | print CGI::start_table({class=>"FormLayout"}); |
|
|
| 525 | print CGI::Tr(CGI::td({colspan=>2}, |
|
|
| 526 | "Enter the user ID and password for an SQL account with sufficient permissions to create a new database." |
|
|
| 527 | ) |
|
|
| 528 | ); |
|
|
| 529 | print CGI::Tr( |
|
|
| 530 | CGI::th({class=>"LeftHeader"}, "SQL Admin Username:"), |
|
|
| 531 | CGI::td(CGI::textfield("add_sql_username", $add_sql_username, 25)), |
|
|
| 532 | ); |
|
|
| 533 | print CGI::Tr( |
|
|
| 534 | CGI::th({class=>"LeftHeader"}, "SQL Admin Password:"), |
|
|
| 535 | CGI::td(CGI::password_field("add_sql_password", $add_sql_password, 25)), |
|
|
| 536 | ); |
|
|
| 537 | |
|
|
| 538 | print CGI::Tr(CGI::td({colspan=>2}, |
|
|
| 539 | "The optionial SQL settings you enter below must match the settings in the DBI source" |
|
|
| 540 | . " specification " . CGI::tt($dbi_source) . ". Replace " . CGI::tt("COURSENAME") |
|
|
| 541 | . " with the course name you entered above." |
|
|
| 542 | ) |
|
|
| 543 | ); |
|
|
| 544 | print CGI::Tr( |
|
|
| 545 | CGI::th({class=>"LeftHeader"}, "SQL Server Host:"), |
|
|
| 546 | CGI::td( |
|
|
| 547 | CGI::textfield("add_sql_host", $add_sql_host, 25), |
|
|
| 548 | CGI::br(), |
|
|
| 549 | CGI::small("Leave blank to use the default host."), |
|
|
| 550 | ), |
|
|
| 551 | ); |
|
|
| 552 | print CGI::Tr( |
|
|
| 553 | CGI::th({class=>"LeftHeader"}, "SQL Server Port:"), |
|
|
| 554 | CGI::td( |
|
|
| 555 | CGI::textfield("add_sql_port", $add_sql_port, 25), |
|
|
| 556 | CGI::br(), |
|
|
| 557 | CGI::small("Leave blank to use the default port."), |
|
|
| 558 | ), |
|
|
| 559 | ); |
|
|
| 560 | |
|
|
| 561 | print CGI::Tr( |
|
|
| 562 | CGI::th({class=>"LeftHeader"}, "SQL Database Name:"), |
|
|
| 563 | CGI::td( |
|
|
| 564 | CGI::textfield("add_sql_database", $add_sql_database, 25), |
|
|
| 565 | CGI::br(), |
|
|
| 566 | CGI::small("Leave blank to use the name ", CGI::tt("webwork_COURSENAME"), "."), |
|
|
| 567 | ), |
|
|
| 568 | ); |
|
|
| 569 | print CGI::Tr( |
|
|
| 570 | CGI::th({class=>"LeftHeader"}, "WeBWorK Host:"), |
|
|
| 571 | CGI::td( |
|
|
| 572 | CGI::textfield("add_sql_wwhost", $add_sql_wwhost || "localhost", 25), |
|
|
| 573 | CGI::br(), |
|
|
| 574 | 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."), |
|
|
| 575 | ), |
|
|
| 576 | ); |
|
|
| 577 | print CGI::end_table(); |
|
|
| 578 | } elsif ($dbLayout eq "gdbm") { |
|
|
| 579 | print CGI::p({style=>"font-style: italic"},"The following information is only required for the deprecated gdbm database format:"); |
|
|
| 580 | print CGI::start_table({class=>"FormLayout"}); |
|
|
| 581 | print CGI::Tr( |
|
|
| 582 | CGI::th({class=>"LeftHeader"}, "GDBM Global User ID:"), |
|
|
| 583 | CGI::td(CGI::textfield("add_gdbm_globalUserID", $add_gdbm_globalUserID || "global_user", 25)), |
|
|
| 584 | ); |
|
|
| 585 | print CGI::end_table(); |
|
|
| 586 | } |
|
|
| 587 | |
|
|
| 588 | print CGI::end_td(); |
|
|
| 589 | print CGI::end_Tr(); |
|
|
| 590 | print CGI::end_table(); |
490 | print CGI::end_table(); |
| 591 | } |
491 | } |
| 592 | |
492 | |
| 593 | print CGI::p({style=>"text-align: center"}, CGI::submit("add_course", "Add Course")); |
493 | print CGI::p({style=>"text-align: center"}, CGI::submit("add_course", "Add Course")); |
| 594 | |
494 | |