--- loncom/interface/lonparmset.pm 2007/06/20 21:06:51 1.371 +++ loncom/interface/lonparmset.pm 2007/10/05 17:56:29 1.376.2.1 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # Handler to set parameters for assessments # -# $Id: lonparmset.pm,v 1.371 2007/06/20 21:06:51 albertel Exp $ +# $Id: lonparmset.pm,v 1.376.2.1 2007/10/05 17:56:29 albertel Exp $ # # Copyright Michigan State University Board of Trustees # @@ -67,16 +67,6 @@ use Apache::longroup; use Apache::lonrss; use LONCAPA qw(:DEFAULT :match); -# --- Caches local to lonparmset - -my $parmhashid; -my %parmhash; -my $symbsid; -my %symbs; -my $rulesid; -my %rules; - -# --- end local caches ################################################## ################################################## @@ -119,8 +109,6 @@ sub parmval { sub parmval_by_symb { my ($what,$symb,$def,$uname,$udom,$csec,$cgroup,$courseopt)=@_; -# load caches - &cacheparmhash(); my $useropt; if ($uname ne '' && $udom ne '') { @@ -167,7 +155,7 @@ sub parmval_by_symb { # ------------------------------------------------------ third, check map parms - my $thisparm=$parmhash{$symbparm}; + my $thisparm=&parmhash($symbparm); if (defined($thisparm)) { $outpar[11]=$thisparm; $result=11; } if (defined($$courseopt{$courselevelr})) { @@ -228,58 +216,90 @@ sub parmval_by_symb { return ($result,@outpar); } -sub resetparmhash { - $parmhashid=''; -} -sub cacheparmhash { - if ($parmhashid eq $env{'request.course.fn'}) { return; } - my %parmhashfile; - if (tie(%parmhashfile,'GDBM_File', - $env{'request.course.fn'}.'_parms.db',&GDBM_READER(),0640)) { - %parmhash=%parmhashfile; - untie %parmhashfile; - $parmhashid=$env{'request.course.fn'}; - } -} -sub resetsymbcache { - $symbsid=''; +# --- Caches local to lonparmset + + +sub reset_caches { + &resetparmhash(); + &resetsymbcache(); + &resetrulescache(); } -sub symbcache { - my $id=shift; - if ($symbsid ne $env{'request.course.id'}) { - %symbs=(); +{ + my $parmhashid; + my %parmhash; + sub resetparmhash { + undef($parmhashid); + undef(%parmhash); } - unless ($symbs{$id}) { - my $navmap = Apache::lonnavmaps::navmap->new(); - if ($id=~/\./) { - my $resource=$navmap->getById($id); - $symbs{$id}=$resource->symb(); - } else { - my $resource=$navmap->getByMapPc($id); - $symbs{$id}=&Apache::lonnet::declutter($resource->src()); + + sub cacheparmhash { + if ($parmhashid eq $env{'request.course.fn'}) { return; } + my %parmhashfile; + if (tie(%parmhashfile,'GDBM_File', + $env{'request.course.fn'}.'_parms.db',&GDBM_READER(),0640)) { + %parmhash=%parmhashfile; + untie(%parmhashfile); + $parmhashid=$env{'request.course.fn'}; } - $symbsid=$env{'request.course.id'}; } - return $symbs{$id}; -} - -sub resetrulescache { - $rulesid=''; -} + + sub parmhash { + my ($id) = @_; + &cacheparmhash(); + return $parmhash{$id}; + } + } + +{ + my $symbsid; + my %symbs; + sub resetsymbcache { + undef($symbsid); + undef(%symbs); + } + + sub symbcache { + my $id=shift; + if ($symbsid ne $env{'request.course.id'}) { + undef(%symbs); + } + if (!$symbs{$id}) { + my $navmap = Apache::lonnavmaps::navmap->new(); + if ($id=~/\./) { + my $resource=$navmap->getById($id); + $symbs{$id}=$resource->symb(); + } else { + my $resource=$navmap->getByMapPc($id); + $symbs{$id}=&Apache::lonnet::declutter($resource->src()); + } + $symbsid=$env{'request.course.id'}; + } + return $symbs{$id}; + } + } -sub rulescache { - my $id=shift; - if ($rulesid ne $env{'request.course.id'} - && !defined($rules{$id})) { - my $dom = $env{'course.'.$env{'request.course.id'}.'.domain'}; - my $crs = $env{'course.'.$env{'request.course.id'}.'.num'}; - %rules=&Apache::lonnet::dump('parmdefactions',$dom,$crs); - $rulesid=$env{'request.course.id'}; +{ + my $rulesid; + my %rules; + sub resetrulescache { + undef($rulesid); + undef(%rules); + } + + sub rulescache { + my $id=shift; + if ($rulesid ne $env{'request.course.id'} + && !defined($rules{$id})) { + my $dom = $env{'course.'.$env{'request.course.id'}.'.domain'}; + my $crs = $env{'course.'.$env{'request.course.id'}.'.num'}; + %rules=&Apache::lonnet::dump('parmdefactions',$dom,$crs); + $rulesid=$env{'request.course.id'}; + } + return $rules{$id}; } - return $rules{$id}; } sub preset_defaults { @@ -345,7 +365,6 @@ sub storeparm { # - new type # - username # - userdomain - my %recstack; sub storeparm_by_symb { my ($symb,$spnam,$snum,$nval,$ntype,$uname,$udom,$csec,$recflag,$cgroup)=@_; @@ -944,7 +963,7 @@ sub extractResourceInformation { # allparms is a hash of parameter names # my $name=&Apache::lonnet::metadata($srcf,$key.'.name'); - if (!exists($$allparms{$name})) { + if (!exists($$allparms{$name}) || $$allparms{$name} =~ m/^\s*$/ ) { my $display= &Apache::lonnet::metadata($srcf,$key.'.display'); my $parmdis = $display; $parmdis =~ s/\[Part.*$//g; @@ -1081,7 +1100,9 @@ ENDSCRIPT if ($$pscat[0] eq "all" || grep $_ eq $tempkey, @{$pscat}) { $r->print(' checked'); } - $r->print('>'.$$allparms{$tempkey}.''); + $r->print('>'.($$allparms{$tempkey}=~/\S/ ? $$allparms{$tempkey} + : $tempkey) + .''); $cnt++; if ($cnt==3) { $r->print("\n"); @@ -2080,13 +2101,13 @@ sub crsenv { # # Let the user know we made the changes if ($name && defined($value)) { - my $failed_cloners; + my %failed_cloners; if ($name eq 'cloners') { $value =~ s/\s//g; $value =~ s/^,//; $value =~ s/,$//; # check requested clones are valid users. - $failed_cloners = &check_cloners(\$value,\@oldcloner); + %failed_cloners = &check_cloners(\$value,\@oldcloner); } my $put_result = &Apache::lonnet::put('environment', {$name=>$value},$dom,$crs); @@ -2103,17 +2124,34 @@ sub crsenv { $setoutput.=&mt('Unable to set').' '.$name.' '.&mt('to'). ' '.$value.' '.&mt('due to').' '.$put_result.'.
'; } - if (($name eq 'cloners') && ($failed_cloners)) { - $setoutput.= &mt('Unable to include').' - '.$failed_cloners.', '. - &mt('reason').' - '.&mt('LON-CAPA user(s) do(es) not exist'). - '.
'.&mt('Please '). - ' '. - &mt('add the user(s)').', '. - &mt('and then return to the '). - ''. - &mt('Course Parameters page').' '. - &mt('to add the new user(s) to the list of possible cloners'). - '.
'; + if (($name eq 'cloners') && (keys(%failed_cloners) > 0)) { + $setoutput.= &mt('Unable to include').': '; + my @fails; + my $num = 0; + if (defined($failed_cloners{'format'})) { + $fails[$num] .= ''.$failed_cloners{'format'}. + ', '.&mt('reason').' - '. + &mt('Invalid format'); + $num ++; + } + if (defined($failed_cloners{'domain'})) { + $fails[$num] .= ''.$failed_cloners{'domain'}. + ', '.&mt('reason').' - '. + &mt('Domain does not exist'); + $num ++; + } + if (defined($failed_cloners{'newuser'})) { + $fails[$num] .= ''.$failed_cloners{'newuser'}. ', '.&mt('reason').' - '. + &mt('LON-CAPA user(s) do(es) not exist.'). + '.
'.&mt('Please '). + ' '. + &mt('add the user(s)').', '. + &mt('and then return to the '). + ''. + &mt('Course Parameters page').' '. + &mt('to add the new user(s) to the list of possible cloners'); + } + $setoutput .= join(';  ',@fails).'.
'; } } } @@ -2144,9 +2182,13 @@ sub crsenv { '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.'), + 'cloners' => ''.&mt('Users allowed to clone course').'
(user:domain,user:domain,*:domain)
'.&mt('Users with active Course Coordinator role in course are permitted to clone and need not be included.
+Use *:domain to allow course to be cloned by anyone in the specified domain.
+Use * to allow unrestricted cloning in all domains.'), 'grading' => ''.&mt('Grading').'
'. '"standard", "external", or "spreadsheet" '.&Apache::loncommon::help_open_topic('GradingOptions'), + 'task_grading' => ''.&mt('Bridge Task Grading').'
'. + &mt('Instructors and TAs in sections, when grading bridge tasks, should be allowed to grade other sections, "[_1]" they are allowed (this is the default), "[_2]" no, they can only grade their own section','any','section'), 'default_xml_style' => ''.&mt('Default XML Style File').' '. '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.'), - + 'student_classlist_portfiles' => ''.&mt('Include link to accessible portfolio files').'
'.&mt('"[_1]" for link to each a listing of each student\'s files.','yes'), + 'student_classlist_opt_in' => ''.&mt("Student's agreement needed for listing in student-viewable roster").'
'.&mt('"[_1]" to require students to opt-in to listing in the roster (on the roster page).','yes'), 'plc.roles.denied'=> ''.&mt('Disallow live chatroom use for Roles'). '
"st": '. &mt('student').', "ta": '. @@ -2263,6 +2306,8 @@ sub crsenv { 'default_xml_style','pageseparators', 'question.email','question.email.text','comment.email','comment.email.text','policy.email','policy.email.text', 'student_classlist_view', + 'student_classlist_opt_in', + 'student_classlist_portfiles', 'plc.roles.denied','plc.users.denied', 'pch.roles.denied','pch.users.denied', 'allow_limited_html_in_feedback', @@ -2286,7 +2331,7 @@ sub crsenv { 'texengine', 'disablesigfigs', 'disableexampointprint', - 'task_messages' + 'task_messages','task_grading', ); foreach my $parameter (sort(keys(%values))) { unless (($parameter =~ m/^internal\./)||($parameter =~ m/^metadata\./)) { @@ -2722,8 +2767,8 @@ ENDOVER my @selected_sections = &Apache::loncommon::get_env_multiple('form.Section'); @selected_sections = ('all') if (! @selected_sections); - foreach (@selected_sections) { - if ($_ eq 'all') { + foreach my $sec (@selected_sections) { + if ($sec eq 'all') { @selected_sections = ('all'); } } @@ -2743,6 +2788,9 @@ ENDOVER \%mapp, \%symbp,\%maptitles,\%uris, \%keyorder,\%defkeytype); + if (grep {$_ eq 'all'} (@psprt)) { + @psprt = keys(%allparts); + } # Menu to select levels, etc $r->print(' @@ -2980,7 +3028,6 @@ sub parse_key { $data{'realm_type'} = 'folder'; $data{'realm_title'} = &Apache::lonnet::gettitle($data{'realm'}); ($data{'realm_exists'}) = &Apache::lonnet::is_on_map($data{'realm'}); - &Apache::lonnet::logthis($1." siad ". $data{'realm_exists'} ); } elsif ($middle) { $data{'realm'} = $middle; $data{'realm_type'} = 'symb'; @@ -3027,48 +3074,63 @@ where $action is add or drop, and $clone user for whom cloning ability is to be changed in course. =cut - + ################################################## ################################################## sub extract_cloners { my ($clonelist,$allowclone) = @_; if ($clonelist =~ /,/) { - @{$allowclone} = split/,/,$clonelist; + @{$allowclone} = split(/,/,$clonelist); } else { $$allowclone[0] = $clonelist; } } - sub check_cloners { my ($clonelist,$oldcloner) = @_; - my ($clean_clonelist,$disallowed); + my ($clean_clonelist,%disallowed); my @allowclone = (); &extract_cloners($$clonelist,\@allowclone); foreach my $currclone (@allowclone) { - if (!grep/^$currclone$/,@$oldcloner) { - my ($uname,$udom) = split/:/,$currclone; - if ($uname && $udom) { - if (&Apache::lonnet::homeserver($uname,$udom) eq 'no_host') { - $disallowed .= $currclone.','; + if (!grep(/^\Q$currclone\E$/,@$oldcloner)) { + if ($currclone eq '*') { + $clean_clonelist .= $currclone.','; + } else { + my ($uname,$udom) = split(/:/,$currclone); + if ($uname eq '*') { + if ($udom =~ /^$match_domain$/) { + if (!&Apache::lonnet::domain($udom)) { + $disallowed{'domain'} .= $currclone.','; + } else { + $clean_clonelist .= $currclone.','; + } + } else { + $disallowed{'format'} .= $currclone.','; + } + } elsif ($currclone !~/^($match_username)\:($match_domain)$/) { + $disallowed{'format'} .= $currclone.','; } else { - $clean_clonelist .= $currclone.','; + if (&Apache::lonnet::homeserver($uname,$udom) eq 'no_host') { + $disallowed{'newuser'} .= $currclone.','; + } else { + $clean_clonelist .= $currclone.','; + } } } } else { $clean_clonelist .= $currclone.','; } } - if ($disallowed) { - $disallowed =~ s/,$//; + foreach my $key (keys(%disallowed)) { + $disallowed{$key} =~ s/,$//; } if ($clean_clonelist) { $clean_clonelist =~ s/,$//; } $$clonelist = $clean_clonelist; - return $disallowed; -} + return %disallowed; +} sub change_clone { my ($clonelist,$oldcloner) = @_; @@ -3081,43 +3143,47 @@ sub change_clone { my @allowclone; &extract_cloners($clonelist,\@allowclone); 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; + if (!grep(/^$currclone$/,@$oldcloner)) { + if ($currclone ne '*') { + ($uname,$udom) = split(/:/,$currclone); + if ($uname && $udom && $uname ne '*') { + if (&Apache::lonnet::homeserver($uname,$udom) ne '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); } - &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'} .= $_.','; + if (!grep(/^\Q$oldclone\E$/,@allowclone)) { + if ($oldclone ne '*') { + ($uname,$udom) = split(/:/,$oldclone); + if ($uname && $udom && $uname ne '*' ) { + if (&Apache::lonnet::homeserver($uname,$udom) ne '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 my $crs (@currclonecrs) { + if ($crs ne $clone_crs) { + $newclonecrs{'cloneable'} .= $crs.','; + } } + $newclonecrs{'cloneable'} =~ s/,$//; + } else { + $newclonecrs{'cloneable'} = ''; } - $newclonecrs{'cloneable'} =~ s/,$//; - } else { - $newclonecrs{'cloneable'} = ''; + &Apache::lonnet::put('environment',\%newclonecrs,$udom,$uname); } - &Apache::lonnet::put('environment',\%newclonecrs,$udom,$uname); } } } @@ -3943,14 +4009,15 @@ sub check_for_course_info { Main handler. Calls &assessparms and &crsenv subroutines. =cut + ################################################## ################################################## -# use Data::Dumper; - sub handler { my $r=shift; + &reset_caches(); + if ($r->header_only) { &Apache::loncommon::content_type($r,'text/html'); $r->send_http_header; @@ -3985,10 +4052,6 @@ sub handler { $r->send_http_header; - # id numbers can change on re-ordering of folders - - &resetsymbcache(); - # # Main switch on form.action and form.state, as appropriate # @@ -4057,6 +4120,8 @@ sub handler { } return HTTP_NOT_ACCEPTABLE; } + &reset_caches(); + return OK; }