--- loncom/interface/lonrequestcourse.pm 2009/12/20 01:58:48 1.41.2.2
+++ loncom/interface/lonrequestcourse.pm 2010/12/05 17:27:00 1.41.2.11
@@ -1,7 +1,7 @@
# The LearningOnline Network
# Request a course
#
-# $Id: lonrequestcourse.pm,v 1.41.2.2 2009/12/20 01:58:48 raeburn Exp $
+# $Id: lonrequestcourse.pm,v 1.41.2.11 2010/12/05 17:27:00 raeburn Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -128,13 +128,21 @@ sub handler {
if ($r->header_only) {
return OK;
}
-
&Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
['action','showdom','cnum','state','crstype']);
&Apache::lonhtmlcommon::clear_breadcrumbs();
- my $dom = &get_course_dom();
- my $action = $env{'form.action'};
+ my $action = $env{'form.reqaction'};
my $state = $env{'form.state'};
+ my $context;
+ &generate_page($r,$action,$state,$context);
+ return OK;
+}
+
+sub generate_page {
+ my ($r,$action,$state,$context) = @_;
+ &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
+ ['action','showdom','cnum','state','crstype']);
+ my $dom = &get_course_dom();
my (%states,%stored);
my ($jscript,$uname,$udom,$result,$warning);
@@ -143,12 +151,19 @@ sub handler {
$states{'log'} = ['filter','display'];
$states{'new'} = ['courseinfo','enrollment','personnel','review','process'];
- if ($dom eq 'gcitest') {
+ if ($dom =~ /^\w+citest$/) {
$states{'new'} = ['courseinfo','review','process'];
+ if ($env{'form.concepttest'} eq 'editmyown') {
+ push(@{$states{'new'}},'chooseitems','uploadroster','enrolling');
+ } elsif (($env{'form.concepttest'} eq 'defchosen') ||
+ (($env{'form.concepttest'} eq 'cloning') && (!$env{'form.cloneroster'}))) {
+ push(@{$states{'new'}},'uploadroster','enrolling');
+ } else {
+ push(@{$states{'new'}},'done');
+ }
}
-
if (($action eq 'new') && ($env{'form.crstype'} eq 'official')) {
- unless ($env{'form.state'} eq 'crstype') {
+ unless ($state eq 'crstype') {
unshift(@{$states{'new'}},'codepick');
}
}
@@ -167,13 +182,17 @@ sub handler {
enrollment => 'Access Dates',
personnel => 'Personnel',
review => 'Review',
- process => 'Result',
+ process => 'Request Outcome',
pick_request => 'Display Summary',
details => 'Request Details',
cancel => 'Cancel Request',
removal => 'Outcome',
+ chooseitems => 'Saved Test',
+ uploadroster => 'Upload Roster',
+ enrolling => 'Completed',
+ done => 'Completed',
);
- if ($dom eq 'gcitest') {
+ if ($dom =~ /^\w+citest$/) {
$trail{'crstype'} = 'Building a Test';
$trail{'courseinfo'} = 'Test Information';
}
@@ -282,9 +301,12 @@ sub handler {
$env{'form.clonedom'} = $dom;
}
if ($state eq 'crstype') {
- $jscript = &mainmenu_javascript();
+ $jscript = &mainmenu_javascript($action);
} else {
$jscript = &Apache::lonhtmlcommon::set_form_elements($elementsref,\%stored);
+ if ($state eq 'courseinfo') {
+ $jscript .= &cloning_javascript();
+ }
}
}
@@ -292,7 +314,7 @@ sub handler {
$jscript .= "\n".&Apache::loncommon::userbrowser_javascript();
}
- my $loaditems = &onload_action($action,$state);
+ my $loaditems = &onload_action($action,$state,$dom);
my (%can_request,%request_domains);
my $canreq =
@@ -307,6 +329,10 @@ sub handler {
$jscript,$loaditems,$crumb,$newinstcode,
$codechk,$checkedcode,$description,
\@invalidcrosslist);
+ if ($state eq 'chooseitems' || $state eq 'uploadroster' ||
+ $state eq 'enrolling') {
+ return $canreq;
+ }
}
} else {
$r->print(&header('Course/Community Requests').$crumb.
@@ -337,10 +363,11 @@ sub handler {
} else {
&print_main_menu($r,\%can_request,\%states,$dom,$jscript,'',$crumb,\%request_domains);
}
- return OK;
+ return;
}
sub mainmenu_javascript {
+ my ($action) = @_;
return <<"END";
function setType(courseForm) {
for (var i=0; i 1) {
+ for (var i=0; i 'requestcrs',
+ uploadroster => 'studentform',
+ enrolling => 'requestcrs',
+ done => 'requestcrs',
+ );
+ my $lastidx;
+ for (my $i=0; $i<@{$states->{$action}}; $i++) {
+ if ($$state eq $states->{$action}[$i]) {
+ $lastidx = $i;
+ last;
+ }
+ }
for (my $i=0; $i<@{$states->{$action}}; $i++) {
if ($$state eq $states->{$action}[$i]) {
&Apache::lonhtmlcommon::add_breadcrumb(
@@ -427,13 +483,34 @@ sub get_breadcrumbs {
}
);
} else {
- &Apache::lonhtmlcommon::add_breadcrumb(
+ if (($$state eq 'chooseitems') || ($$state eq 'uploadroster') ||
+ ($$state eq 'enrolling') || ($$state eq 'done')) {
+ if (($states->{$action}[$i] ne 'process') &&
+ ($states->{$action}[$i] ne 'chooseitems') &&
+ ($states->{$action}[$i] ne 'uploadroster') &&
+ ($states->{$action}[$i] ne 'enrolling') &&
+ ($states->{$action}[$i] ne 'done')) {
+ &Apache::lonhtmlcommon::add_breadcrumb(
+ { href => '/adm/requestcourse',
+ text => "$trail->{$states->{$action}[$i]}",
+ }
+ );
+ } else {
+ my $diff = $i-$lastidx;
+ &Apache::lonhtmlcommon::add_breadcrumb(
+ { href => "javascript:history.go($diff)",
+ text => "$trail->{$states->{$action}[$i]}", }
+ );
+ }
+ } else {
+ &Apache::lonhtmlcommon::add_breadcrumb(
{ href => "javascript:backPage(document.requestcrs,'$states->{$action}[$i]')",
text => "$trail->{$states->{$action}[$i]}", }
- );
- }
- }
- }
+ );
+ }
+ }
+ }
+ }
} else {
&Apache::lonhtmlcommon::add_breadcrumb(
{text=>$firstcrumb});
@@ -458,11 +535,13 @@ sub header {
if (ref($args) eq 'HASH') {
my %loadhash = (
'add_entries' => $loaditems,
+ 'function' => 'norole',
);
my %arghash = (%loadhash,%{$args});
- $args = \%arghash;
+ $args = \%arghash;
} else {
- $args = {'add_entries' => $loaditems,};
+ $args = {'add_entries' => $loaditems,
+ 'function' => 'norole'};
}
}
return &Apache::loncommon::start_page($bodytitle,$jscript.$jsextra,$args);
@@ -480,6 +559,7 @@ sub form_elements {
},
courseinfo => {
cdescr => 'text',
+ cloning => 'radio',
clonecrs => 'text',
clonedom => 'selectbox',
datemode => 'radio',
@@ -515,11 +595,17 @@ sub form_elements {
},
);
my %servers = &Apache::lonnet::get_servers($dom,'library');
- if ($dom eq 'gcitest') {
+ if ($dom =~ /^\w+citest$/) {
%{$elements{'new'}{'courseinfo'}} = (
cdescr => 'text',
- concepttest => 'radio',
+ concepttest => 'radio',
);
+ $elements{'new'}{'enrollment'}{'timezone'} = 'selectbox';
+ if (&show_cloneable()) {
+ $elements{'new'}{'courseinfo'}{'clonecrs'} = 'selectbox';
+ $elements{'new'}{'courseinfo'}{'clonedom'} = 'hidden';
+ $elements{'new'}{'courseinfo'}{'cloneroster'} = 'checkbox';
+ }
}
my $numlib = keys(%servers);
if ($numlib > 1) {
@@ -527,7 +613,7 @@ sub form_elements {
} else {
$elements{'new'}{'courseinfo'}{'chome'} = 'hidden';
}
- if ($dom eq 'gcitest') {
+ if ($dom =~ /^\w+citest$/) {
my %mergedhash = (%{$elements{'new'}{'courseinfo'}},%{$elements{'new'}{'enrollment'}});
%{$elements{'new'}{'courseinfo'}} = %mergedhash;
}
@@ -625,10 +711,7 @@ sub onload_action {
if ($state eq 'crstype') {
$loaditems{'onload'} = 'javascript:setAction(document.mainmenu_action);javascript:setType(document.mainmenu_coursetype)';
} else {
- $loaditems{'onload'} = 'javascript:setFormElements(document.requestcrs)';
- }
- if (($state eq 'process') && ($env{'form.concepttest'} eq 'editmyown')) {
- $loaditems{'onload'} = 'javascript:setInitialVisibility()';
+ $loaditems{'onload'} = 'javascript:setFormElements(document.requestcrs);';
}
}
return \%loaditems;
@@ -656,12 +739,12 @@ sub print_main_menu {
}
my $js;
- unless ($dom eq 'gcitest') {
+ unless ($dom =~ /^\w+citest$/) {
$js = <<"END";
function nextPage(formname) {
var crschoice = document.mainmenu_coursetype.crstype.value;
- var actionchoice = document.mainmenu_action.action.value;
+ var actionchoice = document.mainmenu_action.reqaction.value;
if (check_can_request(crschoice,actionchoice) == true) {
if ((actionchoice == 'new') && (crschoice == 'official')) {
nextstate = 'codepick';
@@ -669,7 +752,7 @@ function nextPage(formname) {
$nextstate_setter
}
formname.crstype.value = crschoice;
- formname.action.value = actionchoice;
+ formname.reqaction.value = actionchoice;
formname.state.value= nextstate;
formname.submit();
}
@@ -747,7 +830,7 @@ END
}
}
- if ($dom eq 'gcitest') {
+ if ($dom =~ /^\w+citest$/) {
my $formname = 'requestcrs';
my $nexttext = &mt('Continue');
$r->print(&header($pagetitle,$js.$jscript,$loaditems).$crumb.
@@ -755,13 +838,14 @@ END
''.&mt('Creation of a course "container" and setting of access dates').' '.
''.&mt('Assembly of a valid test from Concept Inventory questions').' '.
''.&mt('Enrollment of students').' '.
- '
'.&mt('When assembling a test you may either:').
- ' '.&mt('(a) have a valid test built automatically by the WebCenter, or').' '.&mt('(b) select the questions to include by combining questions chosen from eleven bins with four mandatory questions.').'
'.&mt('The most efficient way to enroll students is to upload a text file containing usernames and passwords.').' '.&mt("Students' full e-mail addresses should be used as their usernames to ensure uniqueness.").'
'.
+ '
'.&mt('When assembling a test you may:').
+ ' '.&mt('(a) have a valid test built automatically by the WebCenter, or').' '.&mt('(b) select the questions to include by combining questions chosen from eleven bins with four mandatory questions, or').
+ ' '.&mt('(c) copy one of your existing tests (including optional copying of the student roster)').'
'.&mt('The most efficient way to enroll students is to upload a text file containing usernames and passwords.').' '.&mt("Students' e-mail addresses must be used as their usernames to ensure uniqueness.").'
'.
'
'.
@@ -814,7 +898,7 @@ END
my $nexttext = &mt('Next');
$r->print(&Apache::lonhtmlcommon::row_title(&mt('Action')).'
');
@@ -878,8 +962,13 @@ END
if (($action eq 'new') || ($action eq 'view')) {
$js .= <print(&header($title,$js.$jscript,$loaditems,$jsextra).$crumb);
+ return if (($state eq 'chooseitems') || ($state eq 'uploadroster') ||
+ ($state eq 'enrolling'));
&print_request_form($r,$action,$state,$page,$states,$dom,$newinstcode,
$codechk,$checkedcode,$description,$invalidcrosslist);
} elsif ($action eq 'view') {
@@ -942,7 +1035,7 @@ END
$title = &mt('Pending course/community requests');
}
$r->print(''.$title.' '."\n".$form."\n".
- &print_request_status($dom).'
');
+ &print_request_status($dom,$action,$state).'');
} elsif ($state eq 'details') {
my (@codetitles,%cat_titles,%cat_order,@code_order,$instcode,$code_chk);
my $origcnum = $env{'form.cnum'};
@@ -1028,7 +1121,7 @@ END
}
$r->print(''.&mt('Request Cancellation').' '."\n".$form."\n".
' '."\n".
- ' '."\n".
+ ' '."\n".
' '."\n".
' '."\n");
if ($result eq 'ok') {
@@ -1311,29 +1404,29 @@ sub print_request_form {
&Apache::lonhtmlcommon::end_pick_box().'
');
} else {
$next = $states->{$action}[$page+2];
- $r->print(&courseinfo_form($dom,$formname,$crstype,$next));
+ $r->print(&courseinfo_form($dom,$formname,$state,$crstype,$next));
}
} else {
if ($crstype eq 'official') {
$next = $states->{$action}[$page+2];
}
- $r->print(&courseinfo_form($dom,$formname,$crstype,$next));
+ $r->print(&courseinfo_form($dom,$formname,$state,$crstype,$next));
}
} elsif ($prev eq 'codepick') {
if ($instcode eq '') {
$prev = $states->{$action}[$page-2];
}
- $r->print(&courseinfo_form($dom,$formname,$crstype,$next,$description));
+ $r->print(&courseinfo_form($dom,$formname,$state,$crstype,$next,$description));
} elsif ($state eq 'enrollment') {
if ($crstype eq 'official') {
&Apache::lonnet::auto_possible_instcodes($dom,\@codetitles,\%cat_titles,
\%cat_order,\@code_order);
}
- $r->print(&print_enrollment_menu($formname,$instcode,$dom,\@codetitles,
+ $r->print(&print_enrollment_menu($formname,$state,$instcode,$dom,\@codetitles,
\%cat_titles,\%cat_order,\@code_order,
$invalidcrosslist));
} elsif ($state eq 'personnel') {
- $r->print(&print_personnel_menu($dom,$formname,$crstype,$invalidcrosslist));
+ $r->print(&print_personnel_menu($dom,$formname,$state,$crstype,$invalidcrosslist));
} elsif ($state eq 'review') {
my (%alerts,%rulematch,%inst_results,%curr_rules,%got_rules,%disallowmsg);
my $now = time;
@@ -1428,13 +1521,13 @@ sub print_request_form {
} else {
$navtxt{'next'} = &mt('Submit course request');
}
- } elsif ($state eq 'process') {
+ } elsif ($state eq 'process') {
if ($crstype eq 'official') {
&Apache::lonnet::auto_possible_instcodes($dom,\@codetitles,\%cat_titles,
\%cat_order,\@code_order);
}
my ($storeresult,$result) = &print_request_outcome($r,$dom,\@codetitles,
- \@code_order);
+ \@code_order,$formname);
$r->print($result);
if (($storeresult eq 'ok') || ($storeresult eq 'created')) {
$r->print('');
@@ -1447,6 +1540,8 @@ sub print_request_form {
}
return;
}
+ } elsif ($state eq 'uploadroster') {
+ &roster_upload_form($r,$output,$formname);
}
my @excluded = &get_excluded_elements($dom,$states,$action,$state);
if ($state eq 'personnel') {
@@ -1481,12 +1576,39 @@ sub print_request_form {
if ($state eq 'enrollment') {
push(@excluded,'crosslisttotal');
}
- $r->print(&Apache::lonhtmlcommon::echo_form_input(\@excluded).'');
- &display_navbuttons($r,$dom,$formname,$prev,$navtxt{'prev'},$next,
- $navtxt{'next'},$state);
+ if ($state eq 'done') {
+ $r->print(&done_display());
+ } else {
+ $r->print(&Apache::lonhtmlcommon::echo_form_input(\@excluded));
+ &display_navbuttons($r,$dom,$formname,$prev,$navtxt{'prev'},$next,
+ $navtxt{'next'},$state);
+ }
+ $r->print('');
return;
}
+sub done_display {
+ return '
'.&mt('Concept Test creation is complete').' '.
+ ''.&mt('The following management tools are available via the "[_1]Manage Tests[_2]" tab, or from the toolbar on the [_3]Concept Test Contents[_4] page.[_5]',
+ '',' ','',' ',' ').
+ '
'.
+ ''.
+ '';
+}
+
sub get_cancreate_status {
my ($persondom,$personname,$dom) = @_;
my ($rules,$ruleorder) =
@@ -1551,16 +1673,25 @@ sub get_excluded_elements {
if (grep(/^instcode_/,@excluded)) {
push(@excluded,'instcode');
}
+ if ($env{'form.initmap'}) {
+ push(@excluded,'initmap');
+ }
+ if ($env{'form.output'}) {
+ push(@excluded,'output');
+ }
return @excluded;
}
sub print_enrollment_menu {
- my ($formname,$instcode,$dom,$codetitles,$cat_titles,$cat_order,$code_order,
- $invalidcrosslist) =@_;
+ my ($formname,$state,$instcode,$dom,$codetitles,$cat_titles,$cat_order,
+ $code_order,$invalidcrosslist) =@_;
my ($sections,$autoenroll,$access_dates,$output,$hasauto);
my $starttime = time;
- my $endtime = time+(6*30*24*60*60); # 6 months from now, approx
-
+ my $diff = 6*30*24*60*60; # 6 months from now, approx
+ if (&Apache::loncommon::needs_gci_custom()) {
+ $diff = 7*24*60*60; # 7 days from now, approx
+ }
+ my $endtime = $starttime+$diff;
my %accesstitles = (
'start' => 'Default start access',
'end' => 'Default end access',
@@ -1597,7 +1728,7 @@ sub print_enrollment_menu {
&Apache::lonhtmlcommon::row_title(&mt('Add another')).
' '.
' '.&mt('Add?').&Apache::lonhtmlcommon::row_closure();
$sections .= &Apache::lonhtmlcommon::row_headline.
''.&mt('Crosslisted courses for auto-enrollment').' '.
@@ -1608,25 +1739,25 @@ sub print_enrollment_menu {
$autoenroll =
&Apache::lonhtmlcommon::row_title(&Apache::loncommon::help_open_topic('Course_Request_Autoadd').' '.&mt('Add registered students automatically')).
''.
- ' '.
+ ' '.
&mt('Yes').' '.(' 'x3).''.
- ' '.
+ ' '.
&mt('No').' '.
&Apache::lonhtmlcommon::row_closure(1).
&Apache::lonhtmlcommon::row_title(&Apache::loncommon::help_open_topic('Course_Request_Autodrop').' '.&mt('Drop unregistered students automatically')).
''.
- ' '.
+ ' '.
&mt('Yes').' '.(' 'x3).''.
- ' '.
+ ' '.
&mt('No').' '.
&Apache::lonhtmlcommon::row_closure(1).
&date_setting_table($starttime,$endtime,$formname,'enroll',
- $hasauto,%enrolltitles);
+ $hasauto,$dom,%enrolltitles);
}
}
my $access_dates =
&date_setting_table($starttime,$endtime,$formname,'access',$hasauto,
- %accesstitles);
+ $dom,%accesstitles);
if ($sections) {
$output .= $sections;
}
@@ -1643,10 +1774,18 @@ sub print_enrollment_menu {
}
$output .= &Apache::lonhtmlcommon::row_headline('Access').
''.$header.' '.
- &Apache::lonhtmlcommon::row_closure(1).
- $access_dates
+ &Apache::lonhtmlcommon::row_closure(1);
+ if ($dom =~ /^\w+citest$/) {
+ my $includeempty = 1;
+ my $timezone = &Apache::lonlocal::gettimezone();
+ $output .= &Apache::lonhtmlcommon::row_title('Time zone').
+ &Apache::loncommon::select_timezone('timezone',$timezone,
+ undef,$includeempty).
+ &Apache::lonhtmlcommon::row_closure(1);
+ }
+ $output .= $access_dates;
}
- if ($dom eq 'gcitest') {
+ if ($dom =~ /^\w+citest$/) {
return $output;
} else {
return ''.&Apache::lonhtmlcommon::start_pick_box().$output.
@@ -1713,17 +1852,29 @@ sub inst_section_selector {
}
sub date_setting_table {
- my ($starttime,$endtime,$formname,$prefix,$hasauto,%datetitles) = @_;
+ my ($starttime,$endtime,$formname,$prefix,$hasauto,$dom,%datetitles) = @_;
my ($perpetual,$table);
+ my $no_hh_mm_ss = 1;
+ my $hide_timezone;
+ if (&Apache::loncommon::needs_gci_custom()) {
+ $no_hh_mm_ss = '';
+ if ($dom =~ /^\w+citest$/) {
+ if ($prefix eq 'access') {
+ $hide_timezone = 1;
+ }
+ }
+ }
my $startform = &Apache::lonhtmlcommon::date_setter($formname,$prefix.'start',
- $starttime,'','','',1,'','','',1);
+ $starttime,'','','',$no_hh_mm_ss,'','','',1,$hide_timezone);
my $endform = &Apache::lonhtmlcommon::date_setter($formname,$prefix.'end',
- $endtime,'','','',1,'','','',1);
+ $endtime,'','','',$no_hh_mm_ss,'','','',1,$hide_timezone);
my $closure = '';
if ($prefix eq 'access') {
- $perpetual = ' '.
- ' '.
- &mt('No end date').' ';
+ unless (&Apache::loncommon::needs_gci_custom()) {
+ $perpetual = ' '.
+ ' '.
+ &mt('No end date').' ';
+ }
$closure = '1';
}
@@ -1752,7 +1903,7 @@ sub date_setting_table {
}
sub print_personnel_menu {
- my ($dom,$formname,$crstype,$invalidcrosslist) = @_;
+ my ($dom,$formname,$state,$crstype,$invalidcrosslist) = @_;
my $output;
if ($crstype eq 'official') {
if (&Apache::lonnet::auto_run('',$dom)) {
@@ -1865,7 +2016,7 @@ sub print_personnel_menu {
$output .= &Apache::lonhtmlcommon::row_title(&mt('Add another')).
' '.
' '.&mt('Add?').&Apache::lonhtmlcommon::row_closure(1).
&Apache::lonhtmlcommon::end_pick_box().'
';
if ($crstype eq 'community') {
@@ -1894,7 +2045,7 @@ sub current_lc_sections {
}
sub print_request_status {
- my ($dom) = @_;
+ my ($dom,$action,$state) = @_;
my %statusinfo = &Apache::lonnet::dump('courserequests',$env{'user.domain'},
$env{'user.name'},'^status:'.$dom);
my ($output,$formname,%queue_by_date);
@@ -1937,9 +2088,9 @@ sub print_request_status {
}
$formname = 'requestcrs';
my @sortedtimes = sort {$a <=> $b} (keys(%queue_by_date));
- $output = ' '."\n".
+ $output = ' '."\n".
- ' '."\n".
+ ' '."\n".
' '."\n".
' '."\n".
' '."\n";
@@ -2086,7 +2237,7 @@ sub viewdetails_javascript {
function nextPage(formname,nextstate) {
if (nextstate == "modify") {
formname.state.value = "personnel";
- formname.action.value = "new";
+ formname.reqaction.value = "new";
} else {
formname.state.value = nextstate;
}
@@ -2243,18 +2394,23 @@ sub print_review {
}
my %ctxt = &clone_text();
- if ($dom eq 'gcitest') {
+ if ($dom =~ /^\w+citest$/) {
$inst_headers .= ''.&mt('Test Questions').' ';
my $concepttest;
if ($env{'form.concepttest'} eq 'defchosen') {
$concepttest = 'Auto-generated';
} elsif ($env{'form.concepttest'} eq 'editmyown') {
$concepttest = 'Manually selected';
+ } elsif ($env{'form.concepttest'} eq 'cloning') {
+ $concepttest = 'Copied from existing test';
}
- $inst_values .= ''.$concepttest.' ';
- } else {
- $inst_headers .= ''.&mt('Clone From').' ';
- if (($env{'form.clonecrs'} =~ /^$match_name$/) &&
+ $inst_values .= ''.$concepttest.(' 'x2).' ';
+ }
+ if (&show_cloneable()) {
+ $inst_headers .= ''.&mt('Copy From').' ';
+ if ((($env{'form.cloning'}) ||
+ (($dom =~ /^\w+citest$/) && ($env{'form.concepttest'} eq 'cloning'))) &&
+ ($env{'form.clonecrs'} =~ /^$match_name$/) &&
($env{'form.clonedom'} =~ /^$match_domain$/)) {
my $canclone = &Apache::loncoursequeueadmin::can_clone_course($env{'user.name'},
$env{'user.domain'},$env{'form.clonecrs'},$env{'form.clonedom'},
@@ -2263,21 +2419,35 @@ sub print_review {
my %courseenv = &Apache::lonnet::userenvironment($env{'form.clonedom'},
$env{'form.clonecrs'},('description','internal.coursecode'));
if (keys(%courseenv) > 0) {
- $inst_headers .= ''.$ctxt{'dsh'}.' ';
+ if ($dom =~ /^\w+citest$/) {
+ $inst_headers .= ''.$ctxt{'ros'}.' ';
+ } else {
+ $inst_headers .= ''.$ctxt{'dsh'}.' ';
+ }
$inst_values .= ''.$courseenv{'description'}.' ';
my $cloneinst = $courseenv{'internal.coursecode'};
if ($cloneinst ne '') {
$inst_values .= $cloneinst.' '.&mt('in').' '.$env{'form.clonedom'};
} else {
- $inst_values .= &mt('from').' '.$env{'form.clonedom'};
+ unless ($dom =~ /^\w+citest$/) {
+ $inst_values .= &mt('from').' '.$env{'form.clonedom'};
+ }
}
- $inst_values .= ' ';
- if ($env{'form.datemode'} eq 'preserve') {
- $inst_values .= $ctxt{'prd'};
- } elsif ($env{'form.datemode'} eq 'shift') {
- $inst_values .= &mt('Shift dates by [_1] days',$env{'form.dateshift'});
+ $inst_values .= (' 'x2).' ';
+ if ($dom =~ /^\w+citest$/) {
+ if ($env{'form.cloneroster'}) {
+ $inst_values .= &mt('Yes');
+ } else {
+ $inst_values .= &mt('No');
+ }
} else {
- $inst_values .= $ctxt{'ncd'};
+ if ($env{'form.datemode'} eq 'preserve') {
+ $inst_values .= $ctxt{'prd'};
+ } elsif ($env{'form.datemode'} eq 'shift') {
+ $inst_values .= &mt('Shift dates by [_1] days',$env{'form.dateshift'});
+ } else {
+ $inst_values .= $ctxt{'ncd'};
+ }
}
$inst_values .= ' ';
} else {
@@ -2290,14 +2460,26 @@ sub print_review {
$inst_values .= ''.&mt('None').' ';
}
}
+ my $tz;
+ if ($dom =~ /^\w+citest$/) {
+ if (&Apache::lonlocal::gettimezone($env{'form.timezone'}) ne 'local') {
+ $tz = $env{'form.timezone'};
+ } else {
+ $tz = &Apache::lonlocal::gettimezone();
+ }
+ $enroll_headers .= ''.&mt('Time Zone').' ';
+ }
$enroll_headers .= ''.&mt('Access Starts').' '.
''.&mt('Access Ends').' ';
- my ($accessstart,$accessend) = &dates_from_form('accessstart','accessend');
- $enroll_values .= ''.&Apache::lonlocal::locallocaltime($accessstart).' ';
+ my ($accessstart,$accessend) = &dates_from_form('accessstart','accessend',$tz);
+ if ($dom =~ /^\w+citest$/) {
+ $enroll_values .= ''.$tz.' ';
+ }
+ $enroll_values .= ''.&Apache::lonlocal::locallocaltime($accessstart,$tz).' ';
if ($accessend == 0) {
$enroll_values .= ''.&mt('No end date').' ';
} else {
- $enroll_values .= ''.&Apache::lonlocal::locallocaltime($accessend).' ';
+ $enroll_values .= ''.&Apache::lonlocal::locallocaltime($accessend,$tz).' ';
}
my $container = 'Course';
@@ -2408,9 +2590,9 @@ sub print_review {
}
sub dates_from_form {
- my ($startname,$endname) = @_;
- my $startdate = &Apache::lonhtmlcommon::get_date_from_form($startname);
- my $enddate = &Apache::lonhtmlcommon::get_date_from_form($endname);
+ my ($startname,$endname,$timezone) = @_;
+ my $startdate = &Apache::lonhtmlcommon::get_date_from_form($startname,$timezone);
+ my $enddate = &Apache::lonhtmlcommon::get_date_from_form($endname,$timezone);
if ($endname eq 'accessend') {
if (exists($env{'form.no_end_date'}) ) {
$enddate = 0;
@@ -2420,7 +2602,7 @@ sub dates_from_form {
}
sub courseinfo_form {
- my ($dom,$formname,$crstype,$next,$description) = @_;
+ my ($dom,$formname,$state,$crstype,$next,$description) = @_;
my %lt = &Apache::lonlocal::texthash(
official => 'You must provide a (brief) course description.',
community => 'You must provide a (brief) community description.'
@@ -2437,30 +2619,54 @@ function validateForm() {
}
nextPage(document.$formname,'$next');
}
+
+function toggleCloning() {
+ var willclone;
+ if (document.$formname.cloning.length > 1) {
+ for (var i=0; i
ENDJS
my $title = &mt('Brief Course Description');
my $desctitle = &mt('Description');
- if ($dom eq 'gcitest') {
+ if ($dom =~ /^\w+citest$/) {
$title = &mt('Concept Test Course Information');
$desctitle = &mt('Concept Test Title');
}
- my $clonetitle = &mt('Clone content and settings from an existing course?');
+ my $clonetitle = &mt('Copy content and settings from an existing course?');
if ($crstype eq 'community') {
$title = &mt('Brief Community Description');
- $clonetitle = &mt('Clone content and settings from an existing community?');
+ $clonetitle = &mt('Copy content and settings from an existing community?');
}
- my $output .= $js_validate."\n".''.&Apache::lonhtmlcommon::start_pick_box().
+ my $output .= $js_validate."\n".&Apache::lonhtmlcommon::start_pick_box().
&Apache::lonhtmlcommon::row_headline().
'
'.&Apache::loncommon::help_open_topic('Course_Request_Description').' '.$title.' '.
&Apache::lonhtmlcommon::row_closure(1).
&Apache::lonhtmlcommon::row_title($desctitle).
- '
';
- if ($dom eq 'gcitest') {
+ '
';
+ my $showclone;
+ if ($dom =~ /^\w+citest$/) {
+ $showclone = &show_cloneable();
+ } else {
+ $showclone = 1;
+ }
+ if ($dom =~ /^\w+citest$/) {
$output .= &Apache::lonhtmlcommon::row_closure(1).
- &concepttest_form();
+ &concepttest_form($showclone,$dom);
}
my ($home_server_pick,$numlib) =
&Apache::loncommon::home_server_form_item($dom,'chome',
@@ -2471,31 +2677,82 @@ ENDJS
}
$output .= $home_server_pick.
&Apache::lonhtmlcommon::row_closure();
- if ($dom eq 'gcitest') {
+ if ($showclone && $dom !~ /^\w+citest$/) {
+ $output .= &Apache::lonhtmlcommon::row_headline().
+ '
'.&Apache::loncommon::help_open_topic('Course_Request_Clone').' '.$clonetitle.
+ ' '.
+ &mt('Yes').(' 'x2).''.
+ ' '.&mt('No').' '.
+ ' '.
+ &Apache::lonhtmlcommon::row_closure(1).
+ &Apache::lonhtmlcommon::row_headline().
+ '
'.
+ &Apache::lonhtmlcommon::start_pick_box().
+ &clone_form($dom,$formname,$crstype).
+ &Apache::lonhtmlcommon::end_pick_box().'
';
+ }
+ if ($dom =~ /^\w+citest$/) {
my ($instcode,@codetitles,%cat_titles,%cat_order,@code_order);
my $invalidcrosslist = [];
- $output .= &print_enrollment_menu($formname,$instcode,$dom,
+ $output .= &print_enrollment_menu($formname,$state,$instcode,$dom,
\@codetitles,\%cat_titles,\%cat_order,
\@code_order,$invalidcrosslist);
- } else {
- $output .=
- &Apache::lonhtmlcommon::row_headline().
- '
'.&Apache::loncommon::help_open_topic('Course_Request_Clone').' '.$clonetitle.' '.
- &Apache::lonhtmlcommon::row_closure(1).
- &clone_form($dom,$formname,$crstype);
}
- $output .= &Apache::lonhtmlcommon::end_pick_box().'
'."\n";
+ $output .= &Apache::lonhtmlcommon::end_pick_box()."\n";
return $output;
}
sub concepttest_form {
- return &Apache::lonhtmlcommon::row_title(&mt('Questions included in Concept Test')).
- ' '.
- &mt('Automatically selected by WebCenter').
- ''.
- ' '.
- &mt('Chosen by you from Concept Inventory').
- ' ';
+ my ($showclone,$dom) = @_;
+ my $output = &Apache::lonhtmlcommon::row_title(&mt('Questions included in Concept Test')).
+ ''.
+ ' '.
+ &mt('Chosen by you from Concept Inventory').
+ ' '.
+ ''.
+ ' '.
+ &mt('Automatically selected by WebCenter').
+ ' ';
+ if ($showclone) {
+ $output .= ''.
+ ' '.
+ &mt('Copied from existing Test: ').
+ ' '.&select_oldtest().(' ' x2).
+ ' '.
+ ' '.
+ &mt('Copy roster').' ';
+ }
+ return $output;
+}
+
+sub select_oldtest {
+ my $output = ''.
+ ' ';
+ my %courses = &Apache::loncommon::existing_gcitest_courses('cc');
+ my %Sortby;
+ foreach my $course (sort(keys(%courses))) {
+ next unless (ref($courses{$course}) eq 'HASH');
+ my $clean_title = $courses{$course}{'description'};
+ $clean_title =~ s/\W+//g;
+ if ($clean_title eq '') {
+ $clean_title = $courses{$course}{'description'};
+ }
+ push(@{$Sortby{$clean_title}},$course);
+ }
+ my @sorted_courses = sort { lc($a) cmp lc($b) } (keys(%Sortby));
+ foreach my $item (@sorted_courses) {
+ foreach my $course (@{$Sortby{$item}}) {
+ my ($cdom,$cnum) = split('_',$course);
+ if (($cdom =~ /^\w+citest$/) && (ref($courses{$course}) eq 'HASH')) {
+ my $cdesc = $courses{$course}{'description'};
+ $output .= ''.$cdesc.' ';
+ }
+ }
+ }
+ $output .= ' ';
+ return $output;
}
sub clone_form {
@@ -2531,8 +2788,9 @@ sub clone_text {
'dmn' => 'Domain',
'dsh' => 'Date Shift',
'ncd' => 'Do not clone date parameters',
- 'prd' => 'Clone date parameters as-is',
+ 'prd' => 'Copy date parameters as-is',
'shd' => 'Shift date parameters by number of days',
+ 'ros' => 'Copy Roster',
);
}
@@ -2719,7 +2977,7 @@ sub display_navbuttons {
}
sub print_request_outcome {
- my ($r,$dom,$codetitles,$code_order) = @_;
+ my ($r,$dom,$codetitles,$code_order,$formname) = @_;
my ($output,$cnum,$now,$req_notifylist,$crstype,$enrollstart,$enrollend,
%sections,%crosslistings,%personnel,@baduname,@missingdom,%domconfig,);
my $sectotal = $env{'form.sectotal'};
@@ -2756,6 +3014,10 @@ sub print_request_outcome {
push(@instsections,$sec);
}
$sections{$i}{'loncapa'} = $env{'form.loncapasec_'.$i};
+ $sections{$i}{'loncapa'} =~ s/\W//g;
+ if ($sections{$i}{'loncapa'} eq 'none') {
+ $sections{$i}{'loncapa'} = '';
+ }
}
}
}
@@ -2837,7 +3099,7 @@ sub print_request_outcome {
push(@baduname,$uname.':'.$udom);
}
}
- my ($accessstart,$accessend) = &dates_from_form('accessstart','accessend');
+ my ($accessstart,$accessend) = &dates_from_form('accessstart','accessend',$env{'form.timezone'});
my $autodrops = 0;
if ($env{'form.autodrops'}) {
$autodrops = $env{'form.autodrops'};
@@ -2855,11 +3117,16 @@ sub print_request_outcome {
}
my $clonecrs = '';
my $clonedom = '';
- if (($env{'form.clonecrs'} =~ /^($match_courseid)$/) &&
+ if ((($env{'form.cloning'}) ||
+ (($dom =~ /^\w+citest$/) && ($env{'form.concepttest'} eq 'cloning'))) &&
+ ($env{'form.clonecrs'} =~ /^($match_courseid)$/) &&
($env{'form.clonedom'} =~ /^($match_domain)$/)) {
+ if ($dom =~ /^\w+citest$/) {
+ $env{'form.clonedom'} = $dom;
+ }
my $clonehome = &Apache::lonnet::homeserver($env{'form.clonecrs'},
$env{'form.clonedom'});
- if ($clonehome ne 'no_host') {
+ if ($clonehome ne 'no_host') {
my $canclone =
&Apache::loncoursequeueadmin::can_clone_course($env{'user.name'},
$env{'user.domain'},$env{'form.clonecrs'},$env{'form.clonedom'},
@@ -2895,17 +3162,27 @@ sub print_request_outcome {
accessend => $accessend,
personnel => \%personnel,
};
- if ($dom eq 'gcitest') {
+ if ($dom =~ /^\w+citest$/) {
+ my $template = &get_template($dom);
if ($env{'form.concepttest'} eq 'editmyown') {
$details->{'firstres'} = 'nav';
} else {
$details->{'firstres'} = 'blank';
}
- $details->{'clonedom'} = 'gci';
- $details->{'clonecrs'} = '8v226795a882b4bcagcil1';
+ if ($env{'form.concepttest'} eq 'cloning') {
+ if (($clonecrs) && ($clonedom =~ /^\w+citest$/)) {
+ $details->{'cloneroster'} = $env{'form.cloneroster'};
+ } elsif ($template) {
+ $details->{'clonedom'} = $dom;
+ $details->{'clonecrs'} = $template;
+ }
+ } else {
+ $details->{'clonedom'} = $dom,
+ $details->{'clonecrs'} = $template,
+ }
$details->{'datemode'} = 'delete';
}
- my (@inststatuses,$storeresult,$creationresult);
+ my (@inststatuses,$storeresult,$creationresult,$donedisplay);
my $val = &get_processtype($dom,$crstype,\@inststatuses,\%domconfig);
if ($val eq '') {
if ($crstype eq 'official') {
@@ -2997,13 +3274,56 @@ sub print_request_outcome {
} else {
$output = ''.&mt('Your course request has been processed and the course has been created.');
}
- if ($dom eq 'gcitest') {
+ if ($dom =~ /^\w+citest$/) {
my $caller = 'requestcrs';
+ my $timezone;
+ if (&Apache::lonlocal::gettimezone($env{'form.timezone'}) ne 'local') {
+ $timezone = $env{'form.timezone'};
+ } else {
+ $timezone = Apache::lonlocal::gettimezone();
+ }
&acquire_cc_role($dom,$cnum,'cc./'.$dom.'/'.$cnum);
my %parmresult =
&store_crsparms($dom,$cnum,$now,$accessstart,$accessend);
- &Apache::londocsgci::setdefaults();
- if ($env{'form.concepttest'} eq 'defchosen') {
+ &Apache::londocsgci::setdefaults($dom);
+ my %crsenvhash = (
+ suppress_tries => 'yes',
+ timezone => $timezone,
+ );
+ my $putresult = &Apache::lonnet::put('environment',\%crsenvhash,$dom,$cnum);
+ if ($env{'form.concepttest'} eq 'cloning') {
+ &Apache::lonuserstate::readmap($dom.'/'.$cnum);
+ if (($clonecrs) && ($clonedom =~ /^\w+citest$/)) {
+ my $cloneid = $clonedom.'/'.$clonecrs;
+ my %clonedesc = &Apache::lonnet::coursedescription($cloneid,{'one_time' => 1});
+ my $oldcdesc = $clonedesc{'description'};
+ $output .= ' '.&mt('A concept test has been copied from your existing test: [_1].',''.$oldcdesc.' ').'
';
+ if ($env{'form.cloneroster'}) {
+ $output .= ' '.&mt('You requested copying of the old student roster to the new course.');
+ if ($logmsg =~ /\Q\0\E/) {
+ my @logging = split("\0",$logmsg);
+ if (@logging) {
+ $output .= ''.$logging[-1].'
';
+ }
+ }
+ $output .= ''.
+ ''.&mt('Access starts:').' '.
+ &Apache::lonlocal::locallocaltime($accessstart,$timezone).' '.
+ ''.&mt('Access ends:').' '.&Apache::lonlocal::locallocaltime($accessend,$timezone).' '.
+ ' ';
+ $r->print($output);
+ $output = '';
+ $donedisplay = 1;
+ } else {
+ &roster_upload_form($r,$output,$formname);
+ $output = '';
+ }
+ } else {
+ $output .= '';
+ &roster_upload_form($r,$output,$formname);
+ $output = '';
+ }
+ } elsif ($env{'form.concepttest'} eq 'defchosen') {
$output .= ' ';
my $error = &Apache::londocsgci::store($caller,$dom,$cnum);
if ($error) {
@@ -3014,17 +3334,11 @@ sub print_request_outcome {
&Apache::lonuserstate::readmap($dom.'/'.$cnum);
$output .= &mt('A concept test has also been generated.');
}
- $output .= ''.
- ''.&mt('If you have a text file available containing student e-mail addresses and initial passwords, you may upload it now.').' '.
- &mt('You may also enroll students at a later date by visiting the [_1]"Menu"[_2] page and choosing: [_1]"Manage Enrollment"[_2].','',' ').'
'.
- '');
+ $output .= '';
+ &roster_upload_form($r,$output,$formname);
$output = '';
} else {
- $output .= ' '.&mt('The next step is to chose which questions are to be included in the Concept Test.').'';
+ $output .= ' '.&mt('The next step is to chose which questions are to be included in the Concept Test.').' ';
$r->print($output);
&Apache::londocsgci::editor($r,'requestcrs',$dom,$cnum);
$output = '';
@@ -3123,6 +3437,9 @@ sub print_request_outcome {
}
}
if ($creationresult ne '') {
+ if ($donedisplay) {
+ $r->print(' '.&done_display());
+ }
return ($creationresult,$output);
} else {
return ($storeresult,$output);
@@ -3156,7 +3473,14 @@ sub update_requestors_roles {
@roles = ($ccrole);
}
foreach my $role (@roles) {
- my $start = $now;
+ my $refresh=$env{'user.refresh.time'};
+ if ($refresh eq '') {
+ $refresh = $env{'user.login.time'};
+ }
+ if ($refresh eq '') {
+ $refresh = $now;
+ }
+ my $start = $refresh-1;
my $end = '0';
if ($role eq 'st') {
if ($details->{'accessstart'} ne '') {
@@ -3311,7 +3635,7 @@ sub store_crsparms {
type => 'date_end',
},
problemstatus => {
- value => 'no_feedback_ever',
+ value => 'no',
type => 'string_problemstatus',
},
maxtries => {
@@ -3337,6 +3661,58 @@ sub store_crsparms {
return %parmresult;
}
+sub roster_upload_form {
+ my ($r,$output,$formname,$titletext) = @_;
+ my $title = &mt('Request Processed');
+ if ($titletext ne '') {
+ $title = $titletext;
+ }
+ $r->print(<<"ENDJS");
+
+
+ENDJS
+ $r->print(''.$title.' '.$output.
+ ''.&mt('Course roster file upload').' ');
+ $r->print(''.&mt('If you have a text file available containing student e-mail addresses and initial passwords, you may upload it now.').' '.
+ &mt('You may also enroll students later with the [_1]"Enrollment/Activity"[_2] utility in the management toolbar.','',' ').'
'.
+ &mt('Upload roster file now?').' '.
+ ' '.
+ &mt('Yes').(' 'x2).''.
+ ' '.&mt('No').' '.
+ ' '.
+ ' '.
+ '
'.
+ '
');
+}
+
sub notification_information {
my ($disposition,$req_notifylist,$cnum,$now) = @_;
my %emails = &Apache::loncommon::getemails();
@@ -3664,5 +4040,25 @@ sub generate_date_items {
return;
}
+sub show_cloneable {
+ my $showclone;
+ if (&Apache::loncommon::needs_gci_custom()) {
+ my %courses = &Apache::loncommon::existing_gcitest_courses('cc');
+ my $numcourses = scalar(keys(%courses));
+ return $numcourses;
+ } else {
+ return 1;
+ }
+}
+
+sub get_template {
+ my ($cdom) = @_;
+ my %template = (
+ gcitest => '8v226795a882b4bcagcil1',
+ slcitest => '8v226795a882b4bcagcil1',
+ );
+ return $template{$cdom};
+}
+
1;