';
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 .= '
';
+ $menu_html .= ''."\n".'
';
if ($type eq 'Community') {
- $menu_html .= '
'.&mt('Community owner (permitted to assign Coordinator roles in the community).').'
';
+ $menu_html .= '
'.&mt('Community owner (permitted to assign Coordinator roles in the community).').'
'."\n".
+ '
'.&mt('Override defaults for who configures self-enrollment for this specific community').'
'."\n";
} else {
- $menu_html .= '
'.&mt('Course owner (permitted to assign Course Coordinator roles in the course).').'
'.
- '
'.&mt("Institutional code and default authentication (both required for auto-enrollment of students from institutional datafeeds).").'
';
- }
- $menu_html .= '
'.$setquota_text.'
'."\n";
+ $menu_html .= '
'.&mt('Course owner (permitted to assign Course Coordinator roles in the course).').'
'."\n".
+ '
'.&mt("Institutional code and default authentication (both required for auto-enrollment of students from institutional datafeeds).").'
'."\n";
+ if (&showcredits($dom)) {
+ $menu_html .= '
'.&mt('Default credits earned by student on course completion.').'
'."\n";
+ }
+ $menu_html .= '
'.&mt('Override defaults for who configures self-enrollment for this specific course.').'
'."\n";
+ }
+ $menu_html .= '
'.$setquota_text.'
'."\n".
+ '
'.$setuploadquota_text.'
'."\n".
+ '
'.$anon_text.'
'."\n";
foreach my $item (@additional_params) {
if ($type eq 'Community') {
if ($item eq 'togglecats') {
- $menu_html .= '
'.&mt('Hiding/unhiding a community from the catalog (although can be [_1]configured[_2] to be modifiable by a Coordinator in community context).','','').'
'."\n";
+ $menu_html .= '
'.&mt('Hiding/unhiding a community from the catalog (although can be [_1]configured[_2] to be modifiable by a Coordinator in community context).','','').'
'.&mt('Hiding/unhiding a course from the course catalog (although can be [_1]configured[_2] to be modifiable by a Course Coordinator in course context).','','').'
'."\n";
+ $menu_html .= '
'.&mt('Hiding/unhiding a course from the course catalog (although can be [_1]configured[_2] to be modifiable by a Course Coordinator in course context).','','').'
'.&mt('[_1] still set to: [_2]',$longtype{$attr},$shown).'
';
}
}
if (($type ne 'Community') && ($changed{'code'} || $changed{'owner'})) {
@@ -763,6 +1106,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) {
@@ -771,13 +1116,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));
@@ -788,23 +1133,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));
}
@@ -816,7 +1161,15 @@ sub modify_course {
}
} else {
foreach my $attr (@modifiable_params) {
- $nochgresponse .= '
'.$longtype{$attr}.' '.&mt('still set to').' "'.$currattr{$attr}.'".
';
+ $reply .= &Apache::lonhtmlcommon::actionbox(\@actions).'';
$r->print($reply);
return;
}
+sub selfenroll_config_status {
+ my ($items,$selfenrolltitles) = @_;
+ my $shown;
+ if ((ref($items) eq 'ARRAY') && (ref($selfenrolltitles) eq 'HASH')) {
+ if (@{$items} > 0) {
+ $shown = '
';
+ foreach my $item (@{$items}) {
+ $shown .= '
'.$selfenrolltitles->{$item}.'
';
+ }
+ $shown .= '
';
+ } else {
+ $shown = &mt('None');
+ }
+ }
+ return $shown;
+}
+
+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.co-owners'});
+ 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);
+ my $lctype = lc($type);
+ my $headline = &mt("Disk space quotas for $lctype: [_1]",
+ ''.$cdesc.'');
$r->print('
'."\n".
- '
'.&mt('Disk space for storage of group portfolio files for:').
+ '
'.$headline.'
');
+ my %oldsettings = &Apache::lonnet::get('environment',['internal.coursequota','internal.uploadquota'],$cdom,$cnum);
+ my %staticdefaults = (
+ coursequota => 20,
+ uploadquota => 500,
+ );
+ my %default;
+ $default{'coursequota'} = $staticdefaults{'coursequota'};
+ my %domdefs = &Apache::lonnet::get_domain_defaults($cdom);
+ $default{'uploadquota'} = $domdefs{'uploadquota'};
+ if ($default{'uploadquota'} eq '') {
+ $default{'uploadquota'} = $staticdefaults{'uploadquota'};
+ }
+ my (%cenv,%showresult);
+ foreach my $item ('coursequota','uploadquota') {
+ if ($env{'form.'.$item} ne '') {
+ my $newquota = $env{'form.'.$item};
+ if ($newquota =~ /^\s*(\d+\.?\d*|\.\d+)\s*$/) {
+ $newquota = $1;
+ if ($oldsettings{'internal.'.$item} == $newquota) {
+ if ($item eq 'coursequota') {
+ $r->print(&mt('The disk space allocated for group portfolio files remains unchanged as [_1] MB.',$newquota).' ');
+ } else {
+ $r->print(&mt('The disk space allocated for files uploaded via the Content Editor remains unchanged as [_1] MB.',$newquota).' ');
+ }
+ } else {
+ $cenv{'internal.'.$item} = $newquota;
+ $showresult{$item} = 1;
+ }
+ } else {
+ if ($item eq 'coursequota') {
+ $r->print(&mt('The proposed group portfolio quota contained invalid characters, so the quota is unchanged.').' ');
+ } else {
+ $r->print(&mt('The proposed quota for content uploaded via the Content Editor contained invalid characters, so the quota is unchanged.').' ');
+
+ }
+ }
+ }
+ }
+ if (keys(%cenv)) {
+ my $putreply = &Apache::lonnet::put('environment',\%cenv,$cdom,
+ $cnum);
+ foreach my $key (sort(keys(%showresult))) {
+ if (($oldsettings{'internal.'.$key} eq '') &&
+ ($env{'form.'.$key} == $default{$key})) {
+ if ($key eq 'uploadquota') {
+ if ($type eq 'Community') {
+ $r->print(&mt('The disk space allocated for files uploaded to this community via the Content Editor is the default quota for this domain: [_1] MB.',
+ $default{$key}).' ');
+ } else {
+ $r->print(&mt('The disk space allocated for files uploaded to this course via the Content Editor is the default quota for this domain: [_1] MB.',
+ $default{$key}).' ');
+ }
+ } else {
+ if ($type eq 'Community') {
+ $r->print(&mt('The disk space allocated for group portfolio files in this community is the default quota for this domain: [_1] MB.',
+ $default{$key}).' ');
+ } else {
+ $r->print(&mt('The disk space allocated for group portfolio files in this course is the default quota for this domain: [_1] MB.',
+ $default{$key}).' ');
+ }
+ }
+ delete($showresult{$key});
+ }
+ }
+ if ($putreply eq 'ok') {
+ my %updatedsettings = &Apache::lonnet::get('environment',['internal.coursequota','internal.uploadquota'],$cdom,$cnum);
+ if ($showresult{'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;
+ if ($usage < $oldsettings{'internal.coursequota'}) {
+ $newoverquota = 'now';
+ }
+ $r->print('
');
+ if ($type eq 'Community') {
+ $r->print(&mt("Disk usage $newoverquota exceeds the quota for this community.").' '.
+ &mt('Upload of new portfolio files and assignment of a non-zero MB quota to new groups in the community will not be possible until some files have been deleted, and total usage is below community quota.'));
+ } else {
+ $r->print(&mt("Disk usage $newoverquota exceeds the quota for this course.").' '.
+ &mt('Upload of new portfolio files and assignment of a non-zero MB quota to new groups in the course will not be possible until some files have been deleted, and total usage is below course quota.'));
+ }
+ $r->print('
');
+ }
+ }
+ if ($showresult{'uploadquota'}) {
+ $r->print(&mt('The disk space allocated for content uploaded directly via the Content Editor is now: [_1] MB.',
+ ''.$updatedsettings{'internal.uploadquota'}.'').' ');
+ }
+ } else {
+ $r->print(&mt('An error occurred storing the quota(s) for group portfolio files and/or uploaded content: ').
+ $putreply);
+ }
+ }
+ $r->print('
'.&mt('Responder threshold required for display of anonymous survey submissions:').
' '.$cdesc.'
');
- my %oldsettings = &Apache::lonnet::get('environment',['internal.coursequota'],$cdom,$cnum);
- my $defaultquota = 20;
- if ($env{'form.coursequota'} ne '') {
- my $newquota = $env{'form.coursequota'};
- if ($newquota =~ /^\s*(\d+\.?\d*|\.\d+)\s*$/) {
- $newquota = $1;
- if ($oldsettings{'internal.coursequota'} eq $env{'form.coursequota'}) {
- $r->print(&mt('The disk space allocated for group portfolio files remains unchanged as [_1] Mb.',$env{'form.coursequota'}));
+ 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.coursequota' => $env{'form.coursequota'},
+ 'internal.anonsurvey_threshold' => $env{'form.threshold'},
);
my $putreply = &Apache::lonnet::put('environment',\%cenv,$cdom,
$cnum);
- if (($oldsettings{'internal.coursequota'} eq '') &&
- ($env{'form.coursequota'} == $defaultquota)) {
- if ($type eq 'Community') {
- $r->print(&mt('The disk space allocated for group portfolio files in this community is the default quota for this domain: [_1] Mb.',$defaultquota));
- } else {
- $r->print(&mt('The disk space allocated for group portfolio files in this course is the default quota for this domain: [_1] Mb.',$defaultquota));
+ if ($putreply eq 'ok') {
+ if ($env{'course.'.$cdom.'_'.$cnum.'.description'} ne '') {
+ &Apache::lonnet::appenv(
+ {'course.'.$cdom.'_'.$cnum.'.internal.anonsurvey_threshold' => $env{'form.threshold'}});
}
+ }
+ 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.coursequota'],$cdom,$cnum);
- $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;
- if ($usage < $oldsettings{'internal.coursequota'}) {
- $newoverquota = 'now';
- }
- $r->print('
');
- if ($type eq 'Community') {
- $r->print(&mt('Disk usage [_1] exceeds the quota for this community.',$newoverquota).' '.
- &mt('Upload of new portfolio files and assignment of a non-zero Mb quota to new groups in the community will not be possible until some files have been deleted, and total usage is below community quota.'));
- } else {
- $r->print(&mt('Disk usage [_1] exceeds the quota for this course.',$newoverquota).' '.
- &mt('Upload of new portfolio files and assignment of a non-zero Mb quota to new groups in the course will not be possible until some files have been deleted, and total usage is below course quota.'));
- }
- $r->print('
');
- }
+ 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 quota for group portfolio files: ').
+ $r->print(&mt('An error occurred storing the responder threshold for anonymous submissions display: ').
$putreply);
}
}
}
} else {
- $r->print(&mt('The new quota requested contained invalid characters, so the quota is unchanged.'));
+ $r->print(&mt('The proposed responder threshold for display of anonymous submissions contained invalid characters, so the threshold is unchanged.'));
}
}
$r->print('