--- loncom/interface/lonmodifycourse.pm 2010/03/08 22:31:27 1.50 +++ loncom/interface/lonmodifycourse.pm 2013/03/01 05:01:26 1.60 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # handler for DC-only modifiable course settings # -# $Id: lonmodifycourse.pm,v 1.50 2010/03/08 22:31:27 raeburn Exp $ +# $Id: lonmodifycourse.pm,v 1.60 2013/03/01 05:01:26 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -39,18 +39,22 @@ use lib '/home/httpd/lib/perl'; use LONCAPA; sub get_dc_settable { - my ($type) = @_; + my ($type,$cdom) = @_; if ($type eq 'Community') { return ('courseowner'); } else { - return ('courseowner','coursecode','authtype','autharg'); + my @items = ('courseowner','coursecode','authtype','autharg'); + if (&showcredits($cdom)) { + push(@items,'defaultcredits'); + } + return @items; } } sub autoenroll_keys { - my $internals = ['coursecode','courseowner','authtype','autharg','autoadds','autodrops', - 'autostart','autoend','sectionnums','crosslistings', - 'co-owners']; + my $internals = ['coursecode','courseowner','authtype','autharg','defaultcredits', + 'autoadds','autodrops','autostart','autoend','sectionnums', + 'crosslistings','co-owners']; my $accessdates = ['default_enrollment_start_date','default_enrollment_end_date']; return ($internals,$accessdates); } @@ -114,6 +118,10 @@ sub get_enrollment_settings { || $type eq "autharg" || $type eq "coursecode" || $type eq "crosslistings") { $enrollvar{$type} = $settings{$item}; + } elsif ($type eq 'defaultcredits') { + if (&showcredits($cdom)) { + $enrollvar{$type} = $settings{$item}; + } } elsif ($type eq 'courseowner') { if ($settings{$item} =~ /^[^:]+:[^:]+$/) { $enrollvar{$type} = $settings{$item}; @@ -149,7 +157,7 @@ sub print_course_search_page { 'instcodefilter','ownerfilter', 'coursefilter']; my $filter = {}; - my ($numtitles,$cctitle,$dctitle); + my ($numtitles,$cctitle,$dctitle,@codetitles); my $ccrole = 'cc'; if ($type eq 'Community') { $ccrole = 'co'; @@ -163,7 +171,8 @@ sub print_course_search_page { $r->print('

'.&mt('Search for a course in the [_1] domain',$domdesc).'

'); } $r->print(&Apache::lonpickcourse::build_filters($filterlist,$type, - undef,undef,$filter,$action,\$numtitles,'modifycourse')); + undef,undef,$filter,$action,\$numtitles,'modifycourse', + undef,undef,undef,\@codetitles)); if ($type eq 'Community') { $r->print(&mt('Actions available after searching for a community:').'

'. '

'.$lt{'cour'}.'

'.$disp_table.'

'. ''.$lt{'back'}.''."\n". &hidden_form_elements(). @@ -381,11 +438,11 @@ sub print_setquota { my $hidden_elements = &hidden_form_elements(); my $helpitem = &Apache::loncommon::help_open_topic('Modify_Course_Quota'); $r->print(< +

$lt{'cquo'} $cdesc

$helpitem $lt{'gpqu'}: Mb      - +

$hidden_elements $lt{'back'} @@ -394,6 +451,45 @@ ENDDOCUMENT return; } +sub print_set_anonsurvey_threshold { + my ($r,$cdom,$cnum,$cdesc,$type) = @_; + my %lt = &Apache::lonlocal::texthash( + 'resp' => 'Responder threshold for anonymous survey submissions display:', + 'sufa' => 'Anonymous survey submissions displayed when responders exceeds', + 'modi' => 'Save', + 'back' => 'Pick another action', + ); + my %settings = &Apache::lonnet::get('environment',['internal.anonsurvey_threshold'],$cdom,$cnum); + my $threshold = $settings{'internal.anonsurvey_threshold'}; + if ($threshold eq '') { + my %domconfig = + &Apache::lonnet::get_dom('configuration',['coursedefaults'],$cdom); + if (ref($domconfig{'coursedefaults'}) eq 'HASH') { + $threshold = $domconfig{'coursedefaults'}{'anonsurvey_threshold'}; + if ($threshold eq '') { + $threshold = 10; + } + } else { + $threshold = 10; + } + } + &print_header($r,$type); + my $hidden_elements = &hidden_form_elements(); + my $helpitem = &Apache::loncommon::help_open_topic('Modify_Anonsurvey_Threshold'); + $r->print(< +

$lt{'resp'} $cdesc

+

+$helpitem $lt{'sufa'}:      + +

+$hidden_elements +$lt{'back'} + +ENDDOCUMENT + return; +} + sub print_catsettings { my ($r,$cdom,$cnum,$cdesc,$type) = @_; &print_header($r,$type); @@ -562,14 +658,21 @@ sub print_course_modification_page { &Apache::loncommon::help_open_topic('Modify_Course_Instcode'). ' '.&mt('Course Code'))."\n". ''. - &Apache::lonhtmlcommon::row_closure(). - &Apache::lonhtmlcommon::row_title( - &Apache::loncommon::help_open_topic('Modify_Course_Defaultauth'). - ' '.&mt('Default Authentication method'))."\n". - $authenitems."\n". - &Apache::lonhtmlcommon::row_closure(). - &Apache::lonhtmlcommon::row_title( - &Apache::loncommon::help_open_topic('Modify_Course_Owner'). + &Apache::lonhtmlcommon::row_closure()); + if (&showcredits($cdom)) { + $r->print(&Apache::lonhtmlcommon::row_title( + &Apache::loncommon::help_open_topic('Modify_Course_Credithours'). + ' '.&mt('Credits (students)'))."\n". + ''. + &Apache::lonhtmlcommon::row_closure()); + } + $r->print(&Apache::lonhtmlcommon::row_title( + &Apache::loncommon::help_open_topic('Modify_Course_Defaultauth'). + ' '.&mt('Default Authentication method'))."\n". + $authenitems."\n". + &Apache::lonhtmlcommon::row_closure(). + &Apache::lonhtmlcommon::row_title( + &Apache::loncommon::help_open_topic('Modify_Course_Owner'). ' '.&mt('Course Owner'))."\n"); } $r->print($ownertable."\n".&Apache::lonhtmlcommon::row_closure(1). @@ -580,7 +683,7 @@ sub print_course_modification_page { } else { $r->print('javascript:verify_message(this.form);"'); } - $r->print('value="'.$lt{'gobt'}.'" />

'); + $r->print(' value="'.$lt{'gobt'}.'" />

'); return; } @@ -641,12 +744,15 @@ sub modify_course { unless ($type eq 'Community') { push(@items,('internal.coursecode','internal.authtype','internal.autharg', 'internal.sectionnums','internal.crosslistings')); + if (&showcredits($cdom)) { + push(@items,'internal.defaultcredits'); + } } my %settings = &Apache::lonnet::get('environment',\@items,$cdom,$cnum); my $description = $settings{'description'}; - my ($ccrole,$response,$chgresponse,$nochgresponse,$reply,%currattr,%newattr,%cenv,%changed, - @changes,@nochanges,@sections,@xlists,@warnings); - my @modifiable_params = &get_dc_settable($type); + my ($ccrole,$response,$chgresponse,$nochgresponse,$reply,%currattr,%newattr, + %cenv,%changed,@changes,@nochanges,@sections,@xlists,@warnings); + my @modifiable_params = &get_dc_settable($type,$cdom); foreach my $param (@modifiable_params) { $currattr{$param} = $settings{'internal.'.$param}; } @@ -665,7 +771,7 @@ sub modify_course { $sections[0] = $settings{'internal.sectionnums'}; } } - unless ($settings{'internal.crosslistings'} eq'') { + unless ($settings{'internal.crosslistings'} eq '') { if ($settings{'internal.crosslistings'} =~ m/,/) { @xlists = split/,/,$settings{'internal.crosslistings'}; } else { @@ -704,6 +810,12 @@ sub modify_course { $changed{'code'} = 1; } } + + if (&showcredits($cdom) && exists($env{'form.defaultcredits'})) { + $newattr{'defaultcredits'} =~ s/[^\d\.]//g; + $newattr{'defaultcredits'}=$env{'form.defaultcredits'}; + } + } if ( exists($env{'form.courseowner'}) ) { @@ -768,6 +880,8 @@ sub modify_course { push(@warnings,&mt('There is no owner associated with this LON-CAPA course.'). '
'.&mt('If automated enrollment at your institution requires validation of course owners, automated enrollment will fail.')); } else { + my %crsenv = &Apache::lonnet::get('environment',['internal.co-owners'],$cdom,$cnum); + my $coowners = $crsenv{'internal.co-owners'}; if (@sections > 0) { if ($changed{'code'}) { foreach my $sec (@sections) { @@ -776,13 +890,13 @@ sub modify_course { my $inst_course_id = $newattr{'coursecode'}.$1; my $course_check = &Apache::lonnet::auto_validate_courseID($cnum,$cdom,$inst_course_id); if ($course_check eq 'ok') { - my $outcome = &Apache::lonnet::auto_new_course($cnum,$cdom,$inst_course_id,$newattr{'courseowner'}); + my $outcome = &Apache::lonnet::auto_new_course($cnum,$cdom,$inst_course_id,$newattr{'courseowner'},$coowners); unless ($outcome eq 'ok') { - push(@warnings,&mt('If automatic enrollment is enabled for "[_1]" automated enrollment may fail for "[_2]" - section: [_3], for the following reason: "[_4]"',$description,$newattr{'coursecode'},$instsec,$outcome).'
'); + push(@warnings,&mt('If automatic enrollment is enabled for "[_1]", automated enrollment may fail for "[_2]" - section: [_3] for the following reason: "[_4]".',$description,$newattr{'coursecode'},$instsec,$outcome).'
'); } } else { - push(@warnings,&mt('If automatic enrollment is enabled for "[_1]" automated enrollment may fail for "[_2]" - section: [_3], for the following reason: "[_4]"',$description,$newattr{'coursecode'},$instsec,$course_check)); + push(@warnings,&mt('If automatic enrollment is enabled for "[_1]", automated enrollment may fail for "[_2]" - section: [_3] for the following reason: "[_4]".',$description,$newattr{'coursecode'},$instsec,$course_check)); } } else { push(@warnings,&mt('If automatic enrollment is enabled for "[_1]", automated enrollment may fail for "[_2]" - section: [_3], because this is not a valid section entry.',$description,$newattr{'coursecode'},$sec)); @@ -793,23 +907,23 @@ sub modify_course { if ($sec =~ m/^(.+):/) { my $instsec = $1; my $inst_course_id = $newattr{'coursecode'}.$instsec; - my $outcome = &Apache::lonnet::auto_new_course($cnum,$cdom,$inst_course_id,$newattr{'courseowner'}); + my $outcome = &Apache::lonnet::auto_new_course($cnum,$cdom,$inst_course_id,$newattr{'courseowner'},$coowners); unless ($outcome eq 'ok') { - push(@warnings,&mt('If automatic enrollment is enabled for "[_1]", automated enrollment may fail for "[_2]" - section [_3] for the following reason: "[_4]".',$description,$newattr{'coursecode'},$instsec,$outcome)); + push(@warnings,&mt('If automatic enrollment is enabled for "[_1]", automated enrollment may fail for "[_2]" - section: [_3] for the following reason: "[_4]".',$description,$newattr{'coursecode'},$instsec,$outcome)); } } else { - push(@warnings,&mt('If automatic enrollment is enabled for "[_1]", automated enrollment may fail for "[_2]" - section [_3] because this is not a valid section entry.',$description,$newattr{'coursecode'},$sec)); + push(@warnings,&mt('If automatic enrollment is enabled for "[_1]", automated enrollment may fail for "[_2]" - section: [_3], because this is not a valid section entry.',$description,$newattr{'coursecode'},$sec)); } } } } else { - push(@warnings,&mt('As no section numbers are currently listed for "[_1]" automated enrollment will not occur for any sections of institutional course code: "[_2]".',$description,$newattr{'coursecode'})); + push(@warnings,&mt('As no section numbers are currently listed for "[_1]", automated enrollment will not occur for any sections of institutional course code: "[_2]".',$description,$newattr{'coursecode'})); } if ( (@xlists > 0) && ($changed{'owner'}) ) { foreach my $xlist (@xlists) { if ($xlist =~ m/^(.+):/) { my $instxlist = $1; - my $outcome = &Apache::lonnet::auto_new_course($cnum,$cdom,$instxlist,$newattr{'courseowner'}); + my $outcome = &Apache::lonnet::auto_new_course($cnum,$cdom,$instxlist,$newattr{'courseowner'},$coowners); unless ($outcome eq 'ok') { push(@warnings,&mt('If automatic enrollment is enabled for "[_1]", automated enrollment may fail for crosslisted class "[_2]" for the following reason: "[_3]".',$description,$instxlist,$outcome)); } @@ -877,20 +991,26 @@ sub update_coowners { } if ($settings->{'internal.courseowner'} ne $newattr->{'courseowner'}) { my $oldowner_to_coowner; + my @types = ('co-owners'); if (($newattr->{'coursecode'}) && ($autocoowners)) { my $oldowner = $settings->{'internal.courseowner'}; if ($cchash{$oldowner.':cc'}) { - if ($settings->{'internal.co-owner'}) { - my @current = split(',',$settings->{'internal.co-owners'}); - unless (grep(/^\Q$oldowner\E$/,@current)) { + my ($result,$desc) = &Apache::lonnet::auto_validate_instcode($cnum,$cdom,$newattr->{'coursecode'},$oldowner); + if ($result eq 'valid') { + if ($settings->{'internal.co-owner'}) { + my @current = split(',',$settings->{'internal.co-owners'}); + unless (grep(/^\Q$oldowner\E$/,@current)) { + $oldowner_to_coowner = 1; + } + } else { $oldowner_to_coowner = 1; } - } else { - $oldowner_to_coowner = 1; } } + } else { + push(@types,'pendingco-owners'); } - foreach my $type ('co-owners','pendingco-owners') { + foreach my $type (@types) { if ($settings->{'internal.'.$type}) { my @current = split(',',$settings->{'internal.'.$type}); my $newowner = $newattr->{'courseowner'}; @@ -925,10 +1045,10 @@ sub update_coowners { my %pendinghash = ( 'internal.pendingco-owners' => $pendingcoowners, ); - my $putresult = &put('environment',\%pendinghash,$cdom,$cnum); + my $putresult = &Apache::lonnet::put('environment',\%pendinghash,$cdom,$cnum); if ($putresult eq 'ok') { if ($env{'course.'.$cid.'.num'} eq $cnum) { - &appenv({'course.'.$cid.'.internal.pendingco-owners' => $pendingcoowners}); + &Apache::lonnet::appenv({'course.'.$cid.'.internal.pendingco-owners' => $pendingcoowners}); } } } else { @@ -957,18 +1077,22 @@ sub update_coowners { if ($designhash{$cdom.'.autoassign.co-owners'}) { my @newcoowners = (); if ($settings->{'internal.co-owners'}) { - my @currcoown = split(',',$settings->{'internal.coowners'}); + my @currcoown = split(',',$settings->{'internal.co-owners'}); my ($updatecoowners,$delcoowners); foreach my $person (@currcoown) { - my ($result,$desc) = &Apache::lonnet::valid_instcode(); + my ($result,$desc) = &Apache::lonnet::auto_validate_instcode($cnum,$cdom,$newattr->{'coursecode'},$person); if ($result eq 'valid') { push(@newcoowners,$person); } } foreach my $item (sort(keys(%cchash))) { my ($uname,$udom,$urole) = split(':',$item); + next if ($uname.':'.$udom eq $newattr->{'courseowner'}); unless (grep(/^\Q$uname\E:\Q$udom\E$/,@newcoowners)) { - push(@newcoowners,$uname.':'.$udom); + my ($result,$desc) = &Apache::lonnet::auto_validate_instcode($cnum,$cdom,$newattr->{'coursecode'},$uname.':'.$udom); + if ($result eq 'valid') { + push(@newcoowners,$uname.':'.$udom); + } } } if (@newcoowners) { @@ -1029,7 +1153,7 @@ sub modify_quota { } else { if ($putreply eq 'ok') { my %updatedsettings = &Apache::lonnet::get('environment',['internal.coursequota'],$cdom,$cnum); - $r->print(&mt('The disk space allocated for group portfolio files is now: [_1] Mb.',$updatedsettings{'internal.coursequota'})); + $r->print(&mt('The disk space allocated for group portfolio files is now: [_1] Mb.',''.$updatedsettings{'internal.coursequota'}.'')); my $usage = &Apache::longroup::sum_quotas($cdom.'_'.$cnum); if ($usage >= $updatedsettings{'internal.coursequota'}) { my $newoverquota; @@ -1063,6 +1187,62 @@ sub modify_quota { return; } +sub modify_anonsurvey_threshold { + my ($r,$cdom,$cnum,$cdesc,$domdesc,$type) = @_; + &print_header($r,$type); + $r->print('
'."\n". + '

'.&mt('Responder threshold required for display of anonymous survey submissions:'). + ' '.$cdesc.'


'); + my %oldsettings = &Apache::lonnet::get('environment',['internal.anonsurvey_threshold'],$cdom,$cnum); + my %domconfig = + &Apache::lonnet::get_dom('configuration',['coursedefaults'],$cdom); + my $defaultthreshold; + if (ref($domconfig{'coursedefaults'}) eq 'HASH') { + $defaultthreshold = $domconfig{'coursedefaults'}{'anonsurvey_threshold'}; + if ($defaultthreshold eq '') { + $defaultthreshold = 10; + } + } else { + $defaultthreshold = 10; + } + if ($env{'form.threshold'} eq '') { + $r->print(&mt('The proposed responder threshold for display of anonymous survey submissions was blank, so the threshold is unchanged.')); + } else { + my $newthreshold = $env{'form.threshold'}; + if ($newthreshold =~ /^\s*(\d+)\s*$/) { + $newthreshold = $1; + if ($oldsettings{'internal.anonsurvey_threshold'} eq $env{'form.threshold'}) { + $r->print(&mt('Responder threshold for anonymous survey submissions display remains unchanged: [_1].',$env{'form.threshold'})); + } else { + my %cenv = ( + 'internal.anonsurvey_threshold' => $env{'form.threshold'}, + ); + my $putreply = &Apache::lonnet::put('environment',\%cenv,$cdom, + $cnum); + if (($oldsettings{'internal.anonsurvey_threshold'} eq '') && + ($env{'form.threshold'} == $defaultthreshold)) { + $r->print(&mt('The responder threshold for display of anonymous survey submissions is the default for this domain: [_1].',$defaultthreshold)); + } else { + if ($putreply eq 'ok') { + my %updatedsettings = &Apache::lonnet::get('environment',['internal.anonsurvey_threshold'],$cdom,$cnum); + $r->print(&mt('The responder threshold for display of anonymous survey submissions is now: [_1].',''.$updatedsettings{'internal.anonsurvey_threshold'}.'')); + } else { + $r->print(&mt('An error occurred storing the responder threshold for anonymous submissions display: '). + $putreply); + } + } + } + } else { + $r->print(&mt('The proposed responder threshold for display of anonymous submissions contained invalid characters, so the threshold is unchanged.')); + } + } + $r->print('

'. + ''. + &mt('Pick another action').''); + $r->print(&hidden_form_elements().'

'); + return; +} + sub modify_catsettings { my ($r,$cdom,$cnum,$cdesc,$domdesc,$type) = @_; &print_header($r,$type); @@ -1200,7 +1380,7 @@ sub print_header { $phase = $env{'form.phase'}; } my $js = qq| - + |; if ($phase eq 'setparms') { - $js .= qq| - -|; + $js .= $javascript_validations; } elsif ($phase eq 'courselist') { $js .= qq| - + +function hide_searching() { + if (document.getElementById('searching')) { + document.getElementById('searching').style.display = 'none'; + } + return; +} + |; } elsif ($phase eq 'setquota') { - $js .= <<'ENDSCRIPT'; - + +ENDSCRIPT + } elsif ($phase eq 'setanon') { + my $invalid = &mt('The responder threshold you entered is invalid.'); + my $alert = &mt('You must enter a positive integer.'); + my $regexp = ' /^\s*\d+\s*$/'; + $js .= <<"ENDSCRIPT"; + +function verify_anon_threshold() { + var newthreshold = document.setanon.threshold.value; + var num_reg = $regexp; + if (num_reg.test(newthreshold)) { + if (newthreshold > 0) { + changePage(document.setanon,'processthreshold'); + } else { + alert("$invalid\\n$alert"); + return false; + } + } else { + alert("$invalid\\n$alert"); + return false; + } + return true; +} + ENDSCRIPT } + my $starthash; if ($env{'form.phase'} eq 'ccrole') { $starthash = { add_entries => {'onload' => "javascript:document.ccrole.submit();"}, }; + } elsif ($phase eq 'courselist') { + $starthash = { + add_entries => {'onload' => "hide_searching();"}, + }; } $r->print(&Apache::loncommon::start_page('View/Modify Course/Community Settings', - $js,$starthash)); + &Apache::lonhtmlcommon::scripttag($js), + $starthash)); my $bread_text = "View/Modify Courses/Communities"; if ($type eq 'Community') { $bread_text = 'Community Settings'; @@ -1324,6 +1541,7 @@ sub course_settings_descrip { 'notifylist' => 'Course Coordinators to be notified of enrollment changes', 'sectionnums' => 'Course section number:LON-CAPA section', 'crosslistings' => 'Crosslisted class:LON-CAPA section', + 'defaultcredits' => 'Credits', ); } return %longtype; @@ -1333,11 +1551,20 @@ sub hidden_form_elements { my $hidden_elements = &Apache::lonhtmlcommon::echo_form_input(['gosearch','updater','coursecode', 'prevphase','numlocalcc','courseowner','login','coursequota','intarg', - 'locarg','krbarg','krbver','counter','hidefromcat','usecategory'])."\n". + 'locarg','krbarg','krbver','counter','hidefromcat','usecategory', + 'threshold','defaultcredits'])."\n". ''; return $hidden_elements; } +sub showcredits { + my ($dom) = @_; + my %domdefaults = &Apache::lonnet::get_domain_defaults($dom); + if ($domdefaults{'officialcredits'} || $domdefaults{'unofficialcredits'}) { + return 1; + } +} + sub handler { my $r = shift; if ($r->header_only) { @@ -1421,7 +1648,21 @@ sub handler { ({href=>"javascript:changePage(document.$phase,'$phase')", text=>"Result"}); &modify_quota($r,$cdom,$cnum,$cdesc,$domdesc,$type); - } elsif ($phase eq 'viewparms') { + } elsif ($phase eq 'setanon') { + &Apache::lonhtmlcommon::add_breadcrumb + ({href=>"javascript:changePage(document.$phase,'$phase')", + text=>"Threshold for anonymous submissions display"}); + &print_set_anonsurvey_threshold($r,$cdom,$cnum,$cdesc,$type); + + } elsif ($phase eq 'processthreshold') { + &Apache::lonhtmlcommon::add_breadcrumb + ({href=>"javascript:changePage(document.$phase,'setanon')", + text=>"Threshold for anonymous submissions display"}); + &Apache::lonhtmlcommon::add_breadcrumb + ({href=>"javascript:changePage(document.$phase,'$phase')", + text=>"Result"}); + &modify_anonsurvey_threshold($r,$cdom,$cnum,$cdesc,$domdesc,$type); + } elsif ($phase eq 'viewparms') { &Apache::lonhtmlcommon::add_breadcrumb ({href=>"javascript:changePage(document.$phase,'viewparms')", text=>"Display settings"});