--- loncom/interface/lonparmset.pm 2003/11/18 22:18:42 1.136 +++ loncom/interface/lonparmset.pm 2005/02/02 19:23:59 1.181 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # Handler to set parameters for assessments # -# $Id: lonparmset.pm,v 1.136 2003/11/18 22:18:42 albertel Exp $ +# $Id: lonparmset.pm,v 1.181 2005/02/02 19:23:59 albertel Exp $ # # Copyright Michigan State University Board of Trustees # @@ -131,12 +131,12 @@ sub parmval { # -------------------------------------------------------- first, check default - if ($def) { $outpar[11]=$def; $result=11; } + if (defined($def)) { $outpar[11]=$def; $result=11; } # ----------------------------------------------------- second, check map parms my $thisparm=$parmhash{$symbparm}; - if ($thisparm) { $outpar[10]=$thisparm; $result=10; } + if (defined($thisparm)) { $outpar[10]=$thisparm; $result=10; } # --------------------------------------------------------- third, check course @@ -285,7 +285,7 @@ sub plink { sub startpage { - my ($r,$id,$udom,$csec,$uname,$have_assesments)=@_; + my ($r,$id,$udom,$csec,$uname,$have_assesments,$trimheader)=@_; my $bodytag=&Apache::loncommon::bodytag('Set/Modify Course Parameters','', 'onUnload="pclose()"'); @@ -306,6 +306,9 @@ sub startpage { 'oi' => "or ID", 'ad' => "at Domain" ); + my $overallhelp= + &Apache::loncommon::help_open_menu('','Setting Parameters','Course_Setting_Parameters','',10,'Instructor Interface'); + my $assessparmhelp=&Apache::loncommon::help_open_topic("Cascading_Parameters","Assessment Parameters"); $r->print(< @@ -354,12 +357,16 @@ sub startpage { $selscript $bodytag +$overallhelp +ENDHEAD + unless ($trimheader) {$r->print(<

$lt{'cep'}


+$assessparmhelp

$lt{'caphm'}

@@ -370,9 +377,12 @@ $bodytag

+ENDHEAD2 +} + $r->print(<

$lt{'captm'}

-ENDHEAD +ENDHEAD3 if (!$have_assesments) { $r->print(''.&mt('There are no assesment parameters in this course to set.').'
'); @@ -532,7 +542,7 @@ Input: See list below: =item B: hash, id->type, where "type" contains the extension of the file, thus, I. -=item B: hash, id->key list, will contain a comma seperated list of the meta-data keys available for the given id +=item B: hash, id->key list, will contain a comma separated list of the meta-data keys available for the given id =item B: hash, name of parameter->display value (what is the display value?) @@ -571,11 +581,14 @@ sub extractResourceInformation { foreach (keys %$bighash) { if ($_=~/^src\_(\d+)\.(\d+)$/) { + # there are no resources in the 0 level + if ($1 eq '0') { next; } my $mapid=$1; my $resid=$2; my $id=$mapid.'.'.$resid; my $srcf=$$bighash{$_}; - if ($srcf=~/\.(problem|exam|quiz|assess|survey|form)$/) { + if (1) { + $srcf=~/\.(\w+)$/; $$ids[$#$ids+1]=$id; $$typep{$id}=$1; $$keyp{$id}=''; @@ -584,6 +597,10 @@ sub extractResourceInformation { my $key=$_; my $allkey=$1; $allkey=~s/\_/\./g; + if (&Apache::lonnet::metadata($srcf,$key.'.hidden') eq + 'parm') { + next; #hide hidden things + } my $display= &Apache::lonnet::metadata($srcf,$key.'.display'); my $name=&Apache::lonnet::metadata($srcf,$key.'.name'); my $part= &Apache::lonnet::metadata($srcf,$key.'.part'); @@ -608,12 +625,13 @@ sub extractResourceInformation { &Apache::lonnet::declutter($$bighash{'map_id_'.$mapid}); $$mapp{$mapid}=$$mapp{$id}; $$allmaps{$mapid}=$$mapp{$id}; - $$maptitles{$mapid}= - $$bighash{'title_'.$$bighash{'ids_'.&Apache::lonnet::clutter($$mapp{$id})}}; + if ($mapid eq '1') { + $$maptitles{$mapid}='Main Course Documents'; + } else { + $$maptitles{$mapid}=&Apache::lonnet::gettitle(&Apache::lonnet::clutter($$mapp{$id})); + } $$maptitles{$$mapp{$id}}=$$maptitles{$mapid}; - $$symbp{$id}=$$mapp{$id}. - '___'.$resid.'___'. - &Apache::lonnet::declutter($srcf); + $$symbp{$id}=&Apache::lonnet::encode_symb($$mapp{$id},$resid,$srcf); $$symbp{$mapid}=$$mapp{$id}.'___(all)'; } } @@ -678,8 +696,12 @@ sub assessparms { my $message=''; $csec=$ENV{'form.csec'}; - $udom=$ENV{'form.udom'}; - unless ($udom) { $udom=$r->dir_config('lonDefDomain'); } + if ($udom=$ENV{'form.udom'}) { + } elsif ($udom=$ENV{'request.role.domain'}) { + } elsif ($udom=$ENV{'user.domain'}) { + } else { + $udom=$r->dir_config('lonDefDomain'); + } my @pscat=&Apache::loncommon::get_env_multiple('form.pscat'); my $pschp=$ENV{'form.pschp'}; @@ -689,6 +711,7 @@ sub assessparms { my $pssymb=''; my $parmlev=''; + my $trimheader=''; my $prevvisit=$ENV{'form.prevvisit'}; # unless ($parmlev==$ENV{'form.parmlev'}) { @@ -711,11 +734,13 @@ sub assessparms { if (!@pscat) { @pscat=('all'); } $pschp=''; $parmlev = 'full'; + $trimheader='yes'; } elsif ($ENV{'form.symb'}) { $pssymb=$ENV{'form.symb'}; if (!@pscat) { @pscat=('all'); } $pschp=''; $parmlev = 'full'; + $trimheader='yes'; } else { $ENV{'form.url'}=''; } @@ -905,7 +930,7 @@ sub assessparms { my $have_assesments=1; if (scalar(keys(%allkeys)) eq 0) { $have_assesments=0; } - &startpage($r,$id,$udom,$csec,$uname,$have_assesments); + &startpage($r,$id,$udom,$csec,$uname,$have_assesments,$trimheader); if (!$have_assesments) { untie(%bighash); @@ -928,7 +953,9 @@ sub assessparms { my $submitmessage = &mt('Update Section or Specific User'); if (!$pssymb) { - $r->print(''.&mt('Select Parameter Level').''); + $r->print(''.&mt('Select Parameter Level'). + &Apache::loncommon::help_open_topic('Course_Parameter_Levels'). + ''); $r->print('print(' checked') unless (@pscat); - $r->print('>'.&mt('All Parameters').''); - + $r->print(''); my $cnt=0; foreach $tempkey (sort { $allparms{$a} cmp $allparms{$b} } keys %allparms ) { ++$cnt; - $r->print('') unless ($cnt%2); + $r->print('') if ($cnt%2); $r->print(''); + $r->print('>'.$allparms{$tempkey}.''); + } + $r->print(' + +'); $r->print('
print('value="'.$tempkey.'"'); if ($pscat[0] eq "all" || grep $_ eq $tempkey, @pscat) { $r->print(' checked'); } - $r->print('>'.$allparms{$tempkey}.'
+ + + + +
'); # $r->print('Select Parts'); @@ -1136,8 +1176,10 @@ ENDTABLEHEADFOUR my $rid=$_; my ($inmapid)=($rid=~/\.(\d+)$/); - if (($pschp eq 'all') || ($allmaps{$pschp} eq $mapp{$rid}) || - ($pssymb eq $symbp{$rid})) { + if ((!$pssymb && + (($pschp eq 'all') || ($allmaps{$pschp} eq $mapp{$rid}))) + || + ($pssymb && $pssymb eq $symbp{$rid})) { # ------------------------------------------------------ Entry for one resource if ($defbgone eq '"E0E099"') { $defbgone='"E0E0DD"'; @@ -1174,14 +1216,14 @@ ENDTABLEHEADFOUR my $totalparms=scalar keys %name; if ($totalparms>0) { my $firstrow=1; - my $title=$bighash{'title_'.$rid}; - $title=~s/\:/:/g; + my $title=&Apache::lonnet::gettitle($uri); $r->print(''. join(' / ',split(/\//,$uri)). '

'. - "$title"); @@ -1316,6 +1358,7 @@ ENDMAPONE $r->print(''.&mt('Parameter in Effect').''); foreach (sort keys %name) { + $r->print(''); &print_row($r,$_,\%part,\%name,$mapid,\%default, \%type,\%display,$defbgone,$defbgtwo, $parmlev); @@ -1393,6 +1436,7 @@ ENDMAPONE $r->print(''.&mt('Parameter in Effect').''); foreach (sort keys %name) { + $r->print(''); &print_row($r,$_,\%part,\%name,$mapid,\%default, \%type,\%display,$defbgone,$defbgtwo,$parmlev); # $r->print("resource.$part{$_}.$name{$_},$symbp{$mapid}\n"); @@ -1479,13 +1523,34 @@ sub crsenv { if ($name =~ /^default_enrollment_(start|end)_date$/) { $value=&Apache::lonhtmlcommon::get_date_from_form($name.'_value'); } + # Get existing cloners + my @oldcloner = (); + if ($name eq 'cloners') { + my %clonenames=&Apache::lonnet::dump('environment',$dom,$crs,'cloners'); + if ($clonenames{'cloners'} =~ /,/) { + @oldcloner = split/,/,$clonenames{'cloners'}; + } else { + $oldcloner[0] = $clonenames{'cloners'}; + } + } # # Let the user know we made the changes - if ($name) { + if ($name && defined($value)) { + if ($name eq 'cloners') { + $value =~ s/^,//; + $value =~ s/,$//; + } my $put_result = &Apache::lonnet::put('environment', {$name=>$value},$dom,$crs); if ($put_result eq 'ok') { $setoutput.=&mt('Set').' '.$name.' '.&mt('to').' '.$value.'.
'; + if ($name eq 'cloners') { + &change_clone($value,\@oldcloner); + } + # Flush the course logs so course description is immediately updated + if ($name eq 'description' && defined($value)) { + &Apache::lonnet::flushcourselogs(); + } } else { $setoutput.=&mt('Unable to set').' '.$name.' '.&mt('to'). ' '.$value.' '.&mt('due to').' '.$put_result.'.
'; @@ -1499,104 +1564,132 @@ sub crsenv { # -------------------------------------------------------- Get parameters again my %values=&Apache::lonnet::dump('environment',$dom,$crs); + my $SelectStyleFile=&mt('Select Style File'); + my $SelectSpreadsheetFile=&mt('Select Spreadsheet File'); my $output=''; if (! exists($values{'con_lost'})) { my %descriptions= - ('url' => 'Top Level Map '. + ('url' => ''.&mt('Top Level Map').' '. '
". - 'Select Map
'. - 'Modification may make assessment data '. - 'inaccessible', - 'description' => 'Course Description', - 'courseid' => 'Course ID or number
'. - '(internal, optional)', - 'grading' => 'Grading'. - '"standard" or any other value. '. - 'Default for new courses is "standard".', - - 'default_xml_style' => 'Default XML Style File '. + &mt('Select Map').'
'. + &mt('Modification may make assessment data inaccessible'). + '', + 'description' => ''.&mt('Course Description').'', + 'courseid' => ''.&mt('Course ID or number'). + '
'. + '('.&mt('internal').', '.&mt('optional').')', + 'cloners' => ''.&mt('Users allowed to clone course').'
(user:domain,user:domain)
'.&mt('Users with active Course Coordinator role in the course automatically have the right to clone it, and can be omitted from list.'), + 'grading' => ''.&mt('Grading').'
'. + '"standard", "external", or "spreadsheet" '.&Apache::loncommon::help_open_topic('GradingOptions'), + 'default_xml_style' => ''.&mt('Default XML Style File').' '. 'Select Style File
", - 'question.email' => 'Feedback Addresses for Resource Content '. - 'Questions
(user:domain,'. + ",'sty')\">$SelectStyleFile
", + 'question.email' => ''.&mt('Feedback Addresses for Resource Content Question'). + '
(user:domain,'. 'user:domain(section;section;...;*;...),...)', - 'comment.email' => 'Feedback Addresses for Course Content Comments
'. + 'comment.email' => ''.&mt('Feedback Addresses for Course Content Comments').'
'. '(user:domain,user:domain(section;section;...;*;...),...)', - 'policy.email' => 'Feedback Addresses for Course Policy'. + 'policy.email' => ''.&mt('Feedback Addresses for Course Policy').''. '
(user:domain,user:domain(section;section;...;*;...),...)', - 'hideemptyrows' => 'Hide Empty Rows in Spreadsheets
'. - '("yes" for default hiding)', - 'pageseparators' => 'Visibly Separate Items on Pages
'. - '("yes" for visible separation, '. - 'changes will not show until next login)', - - 'plc.roles.denied'=> 'Disallow live chatroom use for '. - 'Roles
"st": '. - 'student, "ta": '. + 'hideemptyrows' => ''.&mt('Hide Empty Rows in Spreadsheets').'
'. + '('.&mt('"[_1]" for default hiding','yes').')', + 'pageseparators' => ''.&mt('Visibly Separate Items on Pages').'
'. + '('.&mt('"[_1]" for visible separation','yes').', '. + &mt('changes will not show until next login').')', + 'student_classlist_view' => ''.&mt('Allow students to view classlist.').''.&mt('("all":students can view all sections,"section":students can only view their own section.blank or "disabled" prevents student view.'), + + 'plc.roles.denied'=> ''.&mt('Disallow live chatroom use for Roles'). + '
"st": '. + &mt('student').', "ta": '. 'TA, "in": '. - 'instructor;
role,role,...) '. + &mt('instructor').';
'.&mt('role,role,...').') '. Apache::loncommon::help_open_topic("Course_Disable_Discussion"), 'plc.users.denied' => - 'Disallow live chatroom use for Users
'. + ''.&mt('Disallow live chatroom use for Users').'
'. '(user:domain,user:domain,...)', - 'pch.roles.denied'=> 'Disallow Resource Discussion for '. - 'Roles
"st": '. + 'pch.roles.denied'=> ''.&mt('Disallow Resource Discussion for Roles'). + '
"st": '. 'student, "ta": '. 'TA, "in": '. 'instructor;
role,role,...) '. Apache::loncommon::help_open_topic("Course_Disable_Discussion"), 'pch.users.denied' => - 'Disallow Resource Discussion for Users
'. + ''.&mt('Disallow Resource Discussion for Users').'
'. '(user:domain,user:domain,...)', 'spreadsheet_default_classcalc' - => 'Default Course Spreadsheet '. + => ''.&mt('Default Course Spreadsheet').' '. 'Select Spreadsheet File
", + ",'spreadsheet')\">$SelectSpreadsheetFile
", 'spreadsheet_default_studentcalc' - => 'Default Student Spreadsheet '. + => ''.&mt('Default Student Spreadsheet').' '. 'Select Spreadsheet File
", + ",'spreadsheet')\">$SelectSpreadsheetFile
", 'spreadsheet_default_assesscalc' - => 'Default Assessment Spreadsheet '. + => ''.&mt('Default Assessment Spreadsheet').' '. 'Select Spreadsheet File
", + ",'spreadsheet')\">$SelectSpreadsheetFile
", 'allow_limited_html_in_feedback' - => 'Allow limited HTML in discussion posts
'. - '(Set value to "yes" to allow)', + => ''.&mt('Allow limited HTML in discussion posts').'
'. + '('.&mt('Set value to "[_1]" to allow',"yes").')', + 'allow_discussion_post_editing' + => ''.&mt('Allow users to edit/delete their own discussion posts').'
'. + '('.&mt('Set value to "[_1]" to allow',"yes").')', 'rndseed' - => 'Randomization algorithm used
'. - 'Modifying this will make problems '. - 'have different numbers and answers', + => ''.&mt('Randomization algorithm used').'
'. + ''.&mt('Modifying this will make problems').' '. + &mt('have different numbers and answers').'', + 'receiptalg' + => ''.&mt('Receipt algorithm used').'
'. + &mt('This controls how receipt numbers are generated.'), + 'suppress_tries' + => ''.&mt('Suppress number of tries in printing').'('. + &mt('yes if supress').')', 'problem_stream_switch' - => 'Allow problems to be split over pages
'. - ' ("yes" if allowed, anything else if not)', + => ''.&mt('Allow problems to be split over pages').'
'. + ' ('.&mt('"[_1]" if allowed, anything else if not','yes').')', + 'default_paper_size' + => ''.&mt('Default paper type').'
'. + ' ('.&mt('supported types').': Letter [8 1/2x11 in], Legal [8 1/2x14 in],'. + ' Tabloid [11x17 in], Executive [7 1/2x10 in], A2 [420x594 mm],'. + ' A3 [297x420 mm], A4 [210x297 mm], A5 [148x210 mm], A6 [105x148 mm])', 'anonymous_quiz' - => 'Anonimous quiz/exam
'. - ' (yes to avoid print students names )', - 'default_enrollment_start_date' => 'Default beginning date '. - 'when enrolling students', - 'default_enrollment_end_date' => 'Default ending date '. - 'when enrolling students', - 'languages' => 'Languages used', + => ''.&mt('Anonymous quiz/exam').'
'. + ' ('.&mt('yes').' '.&mt('to avoid print students names').' )', + 'default_enrollment_start_date' => ''.&mt('Default beginning date when enrolling students').'', + 'default_enrollment_end_date' => ''.&mt('Default ending date when enrolling students').'', + 'nothideprivileged' => ''.&mt('Privileged users that should not be hidden on staff listings').''. + '
(user:domain,user:domain,...)', + 'languages' => ''.&mt('Languages used').'', 'disable_receipt_display' - => 'Disable display of problem receipts
'. - ' ("yes" to disable, anything else if not)' + => ''.&mt('Disable display of problem receipts').'
'. + ' ('.&mt('"[_1]" to disable, anything else if not','yes').')', + 'disablesigfigs' + => ''.&mt('Disable checking of Significant Figures').'
'. + ' ('.&mt('"[_1]" to disable, anything else if not','yes').')', + 'tthoptions' + => ''.&mt('Default set of options to pass to tth/m when converting tex').'' ); - my @Display_Order = ('url','description','courseid','grading', + my @Display_Order = ('url','description','courseid','cloners','grading', 'default_xml_style','pageseparators', 'question.email','comment.email','policy.email', + 'student_classlist_view', 'plc.roles.denied','plc.users.denied', 'pch.roles.denied','pch.users.denied', 'allow_limited_html_in_feedback', + 'allow_discussion_post_editing', 'languages', + 'nothideprivileged', 'rndseed', + 'receiptalg', 'problem_stream_switch', + 'suppress_tries', + 'default_paper_size', 'disable_receipt_display', 'spreadsheet_default_classcalc', 'spreadsheet_default_studentcalc', @@ -1604,12 +1697,16 @@ sub crsenv { 'hideemptyrows', 'default_enrollment_start_date', 'default_enrollment_end_date', + 'tthoptions', + 'disablesigfigs' ); foreach my $parameter (sort(keys(%values))) { - if (! $descriptions{$parameter}) { - $descriptions{$parameter}=$parameter; - push(@Display_Order,$parameter); - } + unless ($parameter =~ m/^internal\./) { + if (! $descriptions{$parameter}) { + $descriptions{$parameter}=$parameter; + push(@Display_Order,$parameter); + } + } } foreach my $parameter (@Display_Order) { my $description = $descriptions{$parameter}; @@ -1646,31 +1743,21 @@ sub crsenv { $onchange.' />'. ''; } + my %lt=&Apache::lonlocal::texthash( + 'par' => 'Parameter', + 'val' => 'Value', + 'set' => 'Set', + 'sce' => 'Set Course Environment' + ); + + my $Parameter=&mt('Parameter'); + my $Value=&mt('Value'); + my $Set=&mt('Set'); + my $browse_js=&Apache::loncommon::browser_and_searcher_javascript('parmset'); $r->print(< LON-CAPA Course Environment @@ -1680,10 +1767,10 @@ $bodytag $setoutput

- + $output
ParameterValueSet?
$lt{'par'}$lt{'val'}$lt{'set'}?
- + @@ -1744,13 +1831,30 @@ ENDOVER push (@deldata,$thiskey); } elsif ($cmd eq 'datepointer') { my $data=&Apache::lonhtmlcommon::get_date_from_form($ENV{$_}); - if ($olddata{$thiskey} ne $data) { $newdata{$thiskey}=$data; } + if (defined($data) and $olddata{$thiskey} ne $data) { $newdata{$thiskey}=$data; } } } } # Store - &Apache::lonnet::del('resourcedata',\@deldata,$dom,$crs); - &Apache::lonnet::put('resourcedata',\%newdata,$dom,$crs); + my $delentries=$#deldata+1; + my @newdatakeys=keys %newdata; + my $putentries=$#newdatakeys+1; + if ($delentries) { + if (&Apache::lonnet::del('resourcedata',\@deldata,$dom,$crs) eq 'ok') { + $r->print('

'.&mt('Deleted [_1] parameter(s)

',$delentries)); + } else { + $r->print('

'. + &mt('Error deleting parameters').'

'); + } + } + if ($putentries) { + if (&Apache::lonnet::put('resourcedata',\%newdata,$dom,$crs) eq 'ok') { + $r->print('

'.&mt('Stored [_1] parameter(s)

',$putentries)); + } else { + $r->print('

'. + &mt('Error storing parameters').'

'); + } + } # Read and display my %resourcedata=&Apache::lonnet::dump('resourcedata',$dom,$crs); my $oldsection=''; @@ -1758,6 +1862,7 @@ ENDOVER my $oldpart=''; my $pointer=0; $tableopen=0; + my $foundkeys=0; foreach my $thiskey (sort keys %resourcedata) { if ($resourcedata{$thiskey.'.type'}) { my ($course,$middle,$part,$name)= @@ -1770,9 +1875,10 @@ ENDOVER $middle=~s/\.$//; my $realm=''.&mt('All Resources').''; if ($middle=~/^(.+)\_\_\_\(all\)$/) { - $realm=''.&mt('Folder/Map').': '.&Apache::lonnet::gettitle($1).''; + $realm=''.&mt('Folder/Map').': '.&Apache::lonnet::gettitle($1).'
('.$1.')
'; } elsif ($middle) { - $realm=''.&mt('Resource').': '.&Apache::lonnet::gettitle($middle).''; + my ($map,$id,$url)=&Apache::lonnet::decode_symb($middle); + $realm=''.&mt('Resource').': '.&Apache::lonnet::gettitle($middle).'
('.$url.' in '.$map.' id: '.$id.')
'; } if ($section ne $oldsection) { $r->print(&tableend()."\n

$section

"); @@ -1795,6 +1901,7 @@ ENDOVER $r->print(&tablestart().''.$name. ':'); + $foundkeys++; if ($resourcedata{$thiskey.'.type'}=~/^date/) { my $jskey='key_'.$pointer; $pointer++; @@ -1813,8 +1920,92 @@ ENDOVER } } - $r->print(&tableend(). - '

'); + $r->print(&tableend().'

'. + ($foundkeys?'':&mt('There are no course or section parameters.')).'

'); +} + +################################################## +################################################## + +=pod + +=item change clone + +Modifies the list of courses a user can clone (stored +in the user's environemnt.db file), called when a +change is made to the list of users allowed to clone +a course. + +Inputs: $action,$cloner +where $action is add or drop, and $cloner is identity of +user for whom cloning ability is to be changed in course. + +Returns: + +=cut + +################################################## +################################################## + + +sub change_clone { + my ($clonelist,$oldcloner) = @_; + my ($uname,$udom); + my $cnum = $ENV{'course.'.$ENV{'request.course.id'}.'.num'}; + my $cdom = $ENV{'course.'.$ENV{'request.course.id'}.'.domain'}; + my $clone_crs = $cnum.':'.$cdom; + + if ($cnum && $cdom) { + my @allowclone = (); + if ($clonelist =~ /,/) { + @allowclone = split/,/,$clonelist; + } else { + $allowclone[0] = $clonelist; + } + foreach my $currclone (@allowclone) { + if (!grep/^$currclone$/,@$oldcloner) { + ($uname,$udom) = split/:/,$currclone; + if ($uname && $udom) { + unless (&Apache::lonnet::homeserver($uname,$udom) eq 'no_host') { + my %currclonecrs = &Apache::lonnet::dump('environment',$udom,$uname,'cloneable'); + if ($currclonecrs{'cloneable'} !~ /\Q$clone_crs\E/) { + if ($currclonecrs{'cloneable'} eq '') { + $currclonecrs{'cloneable'} = $clone_crs; + } else { + $currclonecrs{'cloneable'} .= ','.$clone_crs; + } + &Apache::lonnet::put('environment',\%currclonecrs,$udom,$uname); + } + } + } + } + } + foreach my $oldclone (@$oldcloner) { + if (!grep/^$oldclone$/,@allowclone) { + ($uname,$udom) = split/:/,$oldclone; + if ($uname && $udom) { + unless (&Apache::lonnet::homeserver($uname,$udom) eq 'no_host') { + my %currclonecrs = &Apache::lonnet::dump('environment',$udom,$uname,'cloneable'); + my %newclonecrs = (); + if ($currclonecrs{'cloneable'} =~ /\Q$clone_crs\E/) { + if ($currclonecrs{'cloneable'} =~ /,/) { + my @currclonecrs = split/,/,$currclonecrs{'cloneable'}; + foreach (@currclonecrs) { + unless ($_ eq $clone_crs) { + $newclonecrs{'cloneable'} .= $_.','; + } + } + $newclonecrs{'cloneable'} =~ s/,$//; + } else { + $newclonecrs{'cloneable'} = ''; + } + &Apache::lonnet::put('environment',\%newclonecrs,$udom,$uname); + } + } + } + } + } + } } ################################################## @@ -1858,7 +2049,10 @@ sub handler { # ----------------------------------------------------- Needs to be in a course if (($ENV{'request.course.id'}) && - (&Apache::lonnet::allowed('opa',$ENV{'request.course.id'}))) { + (&Apache::lonnet::allowed('opa',$ENV{'request.course.id'}) || + &Apache::lonnet::allowed('opa',$ENV{'request.course.id'}.'/'. + $ENV{'request.course.sec'}) + )) { &Apache::loncommon::content_type($r,'text/html'); $r->send_http_header;