--- loncom/interface/lonmodifycourse.pm 2009/11/09 03:50:27 1.48 +++ loncom/interface/lonmodifycourse.pm 2010/05/28 17:09:06 1.55 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # handler for DC-only modifiable course settings # -# $Id: lonmodifycourse.pm,v 1.48 2009/11/09 03:50:27 raeburn Exp $ +# $Id: lonmodifycourse.pm,v 1.55 2010/05/28 17:09:06 bisitz Exp $ # # Copyright Michigan State University Board of Trustees # @@ -49,20 +49,30 @@ sub get_dc_settable { sub autoenroll_keys { my $internals = ['coursecode','courseowner','authtype','autharg','autoadds','autodrops', - 'autostart','autoend','sectionnums','crosslistings']; + 'autostart','autoend','sectionnums','crosslistings', + 'co-owners']; my $accessdates = ['default_enrollment_start_date','default_enrollment_end_date']; return ($internals,$accessdates); } sub catalog_settable { - my ($confhash) = @_; + my ($confhash,$type) = @_; my @settable; if (ref($confhash) eq 'HASH') { - if ($confhash->{'togglecats'} ne 'crs') { - push(@settable,'togglecats'); - } - if ($confhash->{'categorize'} ne 'crs') { - push(@settable,'categorize'); + if ($type eq 'Community') { + if ($confhash->{'togglecatscomm'} ne 'comm') { + push(@settable,'togglecats'); + } + if ($confhash->{'categorizecomm'} ne 'comm') { + push(@settable,'categorize'); + } + } else { + if ($confhash->{'togglecats'} ne 'crs') { + push(@settable,'togglecats'); + } + if ($confhash->{'categorize'} ne 'crs') { + push(@settable,'categorize'); + } } } else { push(@settable,('togglecats','categorize')); @@ -97,7 +107,7 @@ sub get_enrollment_settings { } else { $enrollvar{$type} = &Apache::lonlocal::locallocaltime($settings{$item}); } - } elsif ($type eq "sectionnums") { + } elsif (($type eq 'sectionnums') || ($type eq 'co-owners')) { $enrollvar{$type} = $settings{$item}; $enrollvar{$type} =~ s/,/, /g; } elsif ($type eq "authtype" @@ -198,53 +208,81 @@ sub print_course_selection_page { sub print_modification_menu { my ($r,$cdesc,$domdesc,$dom,$type) = @_; &print_header($r,$type); - my ($ccrole,$setquota_text,$setparams_text,$cat_text); + my ($ccrole,$categorytitle,$setquota_text,$setparams_text,$cat_text); if ($type eq 'Community') { $ccrole = 'co'; } else { $ccrole = 'cc'; } - my $action = '/adm/modifycourse'; if ($type eq 'Community') { + $categorytitle = 'View/Modify Community Settings'; $setquota_text = &mt('Total disk space allocated for storage of portfolio files in all groups in a community.'); $setparams_text = 'View/Modify community owner'; $cat_text = 'View/Modify catalog settings for community'; } else { + $categorytitle = 'View/Modify Course Settings'; $setquota_text = &mt('Total disk space allocated for storage of portfolio files in all groups in a course.'); $setparams_text = 'View/Modify course owner, institutional code, and default authentication'; $cat_text = 'View/Modify catalog settings for course'; } - my @menu = - ( - { text => $setparams_text, - phase => 'setparms', - }, - { text => 'View/Modify quota for group portfolio files', - phase => 'setquota', - } - ); + my %domconf = &Apache::lonnet::get_dom('configuration',['coursecategories'],$dom); - my @additional_params = &catalog_settable($domconf{'coursecategories'}); - if (@additional_params > 0) { - push (@menu, { text => $cat_text, - phase => 'catsettings', - }); + my @additional_params = &catalog_settable($domconf{'coursecategories'},$type); + + sub phaseurl { + my $phase = shift; + return "javascript:changePage(document.menu,'$phase')" } - unless ($type eq 'Community') { - push(@menu, - { text => 'Display current settings for automated enrollment', - phase => 'viewparms', - } + my @menu = + ({ categorytitle => $categorytitle, + items => [ + { + linktext => $setparams_text, + url => &phaseurl('setparms'), + permission => 1, + #help => '', + icon => 'crsconf.png', + linktitle => '' + }, + { + linktext => 'View/Modify quota for group portfolio files', + url => &phaseurl('setquota'), + permission => 1, + #help => '', + icon => 'groupportfolioquota.png', + linktitle => '' + }, + { + linktext => $cat_text, + url => &phaseurl('catsettings'), + permission => (@additional_params > 0), + #help => '', + icon => 'ccatconf.png', + linktitle => '' + }, + { + linktext => 'Display current settings for automated enrollment', + url => &phaseurl('viewparms'), + permission => ($type ne 'Community'), + #help => '', + icon => 'roles.png', + linktitle => '' + }, + ] + }, ); - } - my $menu_html = '

'.&mt('View/Modify settings for: '). - ' '.$cdesc.'

'."\n"; + + my $menu_html = + '

' + .&mt('View/Modify settings for: [_1]', + ''.$cdesc.'') + .'

'."\n".'

'; if ($type eq 'Community') { $menu_html .= &mt('Although almost all community settings can be modified by a Coordinator, the following may only be set or modified by a Domain Coordinator:'); } else { $menu_html .= &mt('Although almost all course settings can be modified by a Course Coordinator, the following may only be set or modified by a Domain Coordinator:'); } - $menu_html .= '

' + .'' + ."\n" + .&hidden_form_elements(); $r->print($menu_html); + $r->print(&Apache::lonhtmlcommon::generate_menu(@menu)); + $r->print(''); return; } @@ -326,7 +361,7 @@ sub print_settings_display { "$longtype{$item}\n". "$enrollvar{$item}\n"; if (grep(/^\Q$item\E$/,@modifiable_params)) { - $disp_table .= ''.&mt('Yes').''."\n"; + $disp_table .= ''.&mt('Yes').''."\n"; } else { $disp_table .= ''.&mt('No').''."\n"; } @@ -399,12 +434,12 @@ sub print_catsettings { $lt{'catset'} = &mt('Catalog Settings for Community'); $lt{'exclude'} = &mt('Exclude from course catalog'); $lt{'categ'} = &mt('Categorize Community'); - $lt{'assi'} = &mt('Assign one or more categories and/or subcategories to this community.'); + $lt{'assi'} = &mt('Assign one or more subcategories to this community.'); } $r->print('
'. '

'.$lt{'catset'}.' '.$cdesc.'

'); my %domconf = &Apache::lonnet::get_dom('configuration',['coursecategories'],$cdom); - my @cat_params = &catalog_settable($domconf{'coursecategories'}); + my @cat_params = &catalog_settable($domconf{'coursecategories'},$type); if (@cat_params > 0) { my %currsettings = &Apache::lonnet::get('environment',['hidefromcat','categories'],$cdom,$cnum); @@ -434,7 +469,7 @@ sub print_catsettings { if (ref($cathash) eq 'HASH') { $r->print($lt{'assi'}.'

'. &Apache::loncommon::assign_categories_table($cathash, - $currsettings{'categories'})); + $currsettings{'categories'},$type)); } else { $r->print(&mt('No categories defined for this domain')); } @@ -626,7 +661,8 @@ sub gather_authenitems { sub modify_course { my ($r,$cdom,$cnum,$cdesc,$domdesc,$type) = @_; my %longtype = &course_settings_descrip($type); - my @items = ('internal.courseowner','description'); + my @items = ('internal.courseowner','description','internal.co-owners', + 'internal.pendingco-owners'); unless ($type eq 'Community') { push(@items,('internal.coursecode','internal.authtype','internal.autharg', 'internal.sectionnums','internal.crosslistings')); @@ -702,7 +738,7 @@ sub modify_course { } } - if ($changed{'owner'} || $changed{'code'}) { + if ($changed{'owner'} || $changed{'code'}) { my %crsinfo = &Apache::lonnet::courseiddump($cdom,'.',1,'.','.',$cnum, undef,undef,'.'); if (ref($crsinfo{$env{'form.pickedcourse'}}) eq 'HASH') { @@ -714,6 +750,9 @@ sub modify_course { } my $chome = &Apache::lonnet::homeserver($cnum,$cdom); my $putres = &Apache::lonnet::courseidput($cdom,\%crsinfo,$chome,'notime'); + if ($putres eq 'ok') { + &update_coowners($cdom,$cnum,$chome,\%settings,\%newattr); + } } } foreach my $param (@modifiable_params) { @@ -765,10 +804,10 @@ sub modify_course { my $outcome = &Apache::lonnet::auto_new_course($cnum,$cdom,$inst_course_id,$newattr{'courseowner'}); 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)); @@ -781,15 +820,15 @@ sub modify_course { my $inst_course_id = $newattr{'coursecode'}.$instsec; my $outcome = &Apache::lonnet::auto_new_course($cnum,$cdom,$inst_course_id,$newattr{'courseowner'}); 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) { @@ -852,6 +891,149 @@ sub modify_course { return; } +sub update_coowners { + my ($cdom,$cnum,$chome,$settings,$newattr) = @_; + return unless ((ref($settings) eq 'HASH') && (ref($newattr) eq 'HASH')); + my %designhash = &Apache::loncommon::get_domainconf($cdom); + my (%cchash,$autocoowners); + if ($designhash{$cdom.'.autoassign.co-owners'}) { + $autocoowners = 1; + %cchash = &Apache::lonnet::get_my_roles($cnum,$cdom,undef,undef,['cc']); + } + 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'}) { + 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 { + push(@types,'pendingco-owners'); + } + foreach my $type (@types) { + if ($settings->{'internal.'.$type}) { + my @current = split(',',$settings->{'internal.'.$type}); + my $newowner = $newattr->{'courseowner'}; + my @newvalues = (); + if (($newowner ne '') && (grep(/^\Q$newowner\E$/,@current))) { + foreach my $person (@current) { + unless ($person eq $newowner) { + push(@newvalues,$person); + } + } + } else { + @newvalues = @current; + } + if ($oldowner_to_coowner) { + push(@newvalues,$settings->{'internal.courseowner'}); + @newvalues = sort(@newvalues); + } + my $newownstr = join(',',@newvalues); + if ($newownstr ne $settings->{'internal.'.$type}) { + if ($type eq 'co-owners') { + my $deleted = ''; + unless (@newvalues) { + $deleted = 1; + } + &Apache::lonnet::store_coowners($cdom,$cnum,$chome, + $deleted,@newvalues); + } else { + my $pendingcoowners; + my $cid = $cdom.'_'.$cnum; + if (@newvalues) { + $pendingcoowners = join(',',@newvalues); + my %pendinghash = ( + 'internal.pendingco-owners' => $pendingcoowners, + ); + my $putresult = &Apache::lonnet::put('environment',\%pendinghash,$cdom,$cnum); + if ($putresult eq 'ok') { + if ($env{'course.'.$cid.'.num'} eq $cnum) { + &Apache::lonnet::appenv({'course.'.$cid.'.internal.pendingco-owners' => $pendingcoowners}); + } + } + } else { + my $delresult = &Apache::lonnet::del('environment',['internal.pendingco-owners'],$cdom,$cnum); + if ($delresult eq 'ok') { + if ($env{'course.'.$cid.'.internal.pendingco-owners'}) { + &Apache::lonnet::delenv('course.'.$cid.'.internal.pendingco-owners'); + } + } + } + } + } elsif ($oldowner_to_coowner) { + &Apache::lonnet::store_coowners($cdom,$cnum,$chome,'', + $settings->{'internal.courseowner'}); + + } + } elsif ($oldowner_to_coowner) { + &Apache::lonnet::store_coowners($cdom,$cnum,$chome,'', + $settings->{'internal.courseowner'}); + } + } + } + if ($settings->{'internal.coursecode'} ne $newattr->{'coursecode'}) { + if ($newattr->{'coursecode'} ne '') { + my %designhash = &Apache::loncommon::get_domainconf($cdom); + if ($designhash{$cdom.'.autoassign.co-owners'}) { + my @newcoowners = (); + if ($settings->{'internal.co-owners'}) { + my @currcoown = split(',',$settings->{'internal.coowners'}); + my ($updatecoowners,$delcoowners); + foreach my $person (@currcoown) { + 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)) { + my ($result,$desc) = &Apache::lonnet::auto_validate_instcode($cnum,$cdom,$newattr->{'coursecode'},$uname.':'.$udom); + if ($result eq 'valid') { + push(@newcoowners,$uname.':'.$udom); + } + } + } + if (@newcoowners) { + my $coowners = join(',',sort(@newcoowners)); + unless ($coowners eq $settings->{'internal.co-owners'}) { + $updatecoowners = 1; + } + } else { + $delcoowners = 1; + } + if ($updatecoowners || $delcoowners) { + &Apache::lonnet::store_coowners($cdom,$cnum,$chome, + $delcoowners,@newcoowners); + } + } else { + foreach my $item (sort(keys(%cchash))) { + my ($uname,$udom,$urole) = split(':',$item); + push(@newcoowners,$uname.':'.$udom); + } + if (@newcoowners) { + &Apache::lonnet::store_coowners($cdom,$cnum,$chome,'', + @newcoowners); + } + } + } + } + } + return; +} + sub modify_quota { my ($r,$cdom,$cnum,$cdesc,$domdesc,$type) = @_; &print_header($r,$type); @@ -933,7 +1115,7 @@ sub modify_catsettings {

'.&mt('Category settings').'

'); my %domconf = &Apache::lonnet::get_dom('configuration',['coursecategories'],$cdom); - my @cat_params = &catalog_settable($domconf{'coursecategories'}); + my @cat_params = &catalog_settable($domconf{'coursecategories'},$type); if (@cat_params > 0) { my (%cenv,@changes,@nochanges); my %currsettings = @@ -1159,8 +1341,8 @@ sub course_settings_descrip { if ($type eq 'Community') { %longtype = &Apache::lonlocal::texthash( 'courseowner' => "Username:domain of community owner", + 'co-owners' => "Username:domain of each co-owner", ); - } else { %longtype = &Apache::lonlocal::texthash( 'authtype' => 'Default authentication method', @@ -1173,6 +1355,7 @@ sub course_settings_descrip { 'default_enrollment_end_date' => 'Date of last student access', 'coursecode' => 'Official course code', 'courseowner' => "Username:domain of course owner", + 'co-owners' => "Username:domain of each co-owner", 'notifylist' => 'Course Coordinators to be notified of enrollment changes', 'sectionnums' => 'Course section number:LON-CAPA section', 'crosslistings' => 'Crosslisted class:LON-CAPA section',