--- loncom/interface/lonparmset.pm 2009/01/20 16:38:39 1.421 +++ loncom/interface/lonparmset.pm 2009/03/29 18:25:33 1.438 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # Handler to set parameters for assessments # -# $Id: lonparmset.pm,v 1.421 2009/01/20 16:38:39 bisitz Exp $ +# $Id: lonparmset.pm,v 1.438 2009/03/29 18:25:33 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -848,12 +848,13 @@ sub plink { my ($hour,$min,$sec,$val)=&preset_defaults($parmname); unless (defined($winvalue)) { $winvalue=$val; } my $valout = &valout($value,$type,1); + my $unencmarker = $marker; foreach my $item (\$type, \$dis, \$winvalue, \$marker, \$return, \$call, \$hour, \$min, \$sec) { $$item = &HTML::Entities::encode($$item,'"<>&'); $$item =~ s/\'/\\\'/g; } - return ''); - } else { + } else { $parm=~s|\[.*\]\s||g; } my $automatic=&rulescache(($which=~/\_([^\_]+)$/)[0].'_triggers'); if ($automatic) { $parm.='
'.&mt('Automatically sets').' '.join(', ',split(/\:/,$automatic)).'
'; } - $r->print(''); + $r->print(''); my $thismarker=$which; $thismarker=~s/^parameter\_//; @@ -1075,12 +1076,20 @@ sub print_td { my ($r,$which,$defbg,$result,$outpar,$mprefix,$value,$typeoutpar,$display)=@_; $r->print(''."\n"); } @@ -1181,9 +1190,15 @@ sub extractResourceInformation { # my $name=&Apache::lonnet::metadata($srcf,$key.'.name'); if (!exists($$allparms{$name}) || $$allparms{$name} =~ m/^\s*$/ ) { - my $display= &Apache::lonnet::metadata($srcf,$key.'.display'); - my $parmdis = $display; - $parmdis =~ s/\s*\[Part.*$//g; + my ($display,$parmdis); + $display = &standard_parameter_names($name); + if ($display eq '') { + $display= &Apache::lonnet::metadata($srcf,$key.'.display'); + $parmdis = $display; + $parmdis =~ s/\s*\[Part.*$//g; + } else { + $parmdis = $display; + } $$allparms{$name}=$parmdis; if (ref($defkeytype)) { $$defkeytype{$name}= @@ -1307,17 +1322,17 @@ sub parmmenu { ENDSCRIPT $r->print(); - $r->print("\n
'. + return '
'. ''. $valout.'
'; @@ -972,14 +973,14 @@ sub print_row { if ($parmlev eq 'full') { $r->print('
' .$$part{$which}.''.$parm.''.$parm.''); - if ($which<11 || $which > 12) { - $r->print(&plink($$typeoutpar[$which], - $$display{$value},$$outpar[$which], - $mprefix."$which",'parmform.pres','psub')); + my $nolink = 0; + if ($which == 11 || $which == 12) { + $nolink = 1; + } elsif ($mprefix =~ /availablestudent\&$/) { + if ($which > 3) { + $nolink = 1; + } + } + if ($nolink) { + $r->print(&valout($$outpar[$which],$$typeoutpar[$which])); } else { - $r->print(&valout($$outpar[$which],$$typeoutpar[$which])); + $r->print(&plink($$typeoutpar[$which], + $$display{$value},$$outpar[$which], + $mprefix."$which",'parmform.pres','psub')); } $r->print('
"); + $r->print("\n".'
'); my $cnt=0; foreach $tempkey (&keysindisplayorder($allparms,$keyorder)) { $r->print("\n".''); + $r->print(' />'.($$allparms{$tempkey}=~/\S/ ? $$allparms{$tempkey} + : $tempkey) + .''); $cnt++; if ($cnt==3) { $r->print("\n"); @@ -1325,7 +1340,7 @@ ENDSCRIPT } } $r->print('' - .'' + .'' .'
' .'
'.&mt('Parameter Selection').'' .'' @@ -1601,12 +1616,12 @@ sub sortmenu { my ($r,$sortorder)=@_; $r->print('

'); @@ -1790,6 +1805,39 @@ sub assessparms { my @values=split(/\&\&\&/,$env{'form.pres_value'}); my @types=split(/\&\&\&/,$env{'form.pres_type'}); for (my $i=0;$i<=$#markers;$i++) { + if ($markers[$i] =~ /^[\d.]+\&0_availablestudent\&(1|2|3)$/) { + my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'}; + my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'}; + my (@ok_slots,@fail_slots,@del_slots); + my $courseopt=&Apache::lonnet::get_courseresdata($cnum,$cdom); + my ($level,@all) = + &parmval_by_symb('0.availablestudent',$pssymb,'',$uname,$udom, + $csec,$cgroup,$courseopt); + foreach my $slot_name (split(/:/,$values[$i])) { + next if ($slot_name eq ''); + if (&update_slots($slot_name,$cdom,$cnum,$pssymb,$uname,$udom) eq 'ok') { + push(@ok_slots,$slot_name); + + } else { + push(@fail_slots,$slot_name); + } + } + if (@ok_slots) { + $values[$i] = join(':',@ok_slots); + } else { + $values[$i] = ''; + } + if ($all[$level] ne '') { + my @existing = split(/:/,$all[$level]); + foreach my $slot_name (@existing) { + if (!grep(/^\Q$slot_name\E$/,split(/:/,$values[$i]))) { + if (&delete_slots($slot_name,$cdom,$cnum,$uname,$udom,$pssymb) eq 'ok') { + push(@del_slots,$slot_name); + } + } + } + } + } $message.=&storeparm(split(/\&/,$markers[$i]), $values[$i], $types[$i], @@ -1816,12 +1864,13 @@ sub assessparms { if (!$pssymb) { $r->print(''); if ($parmlev ne 'general') { $r->print(''); } - $r->print('
'); &levelmenu($r,\%alllevs,$parmlev); + $r->print(''); &mapmenu($r,\%allmaps,$pschp,\%maptitles); $r->print('
'); + $r->print('
'); &displaymenu($r,\%allparms,\%allparts,\@pscat,\@psprt,\%keyorder); } else { my ($map,$id,$resource)=&Apache::lonnet::decode_symb($pssymb); @@ -1968,7 +2017,16 @@ ENDTABLEHEADFOUR if (grep $_ eq $tempkeyp, @catmarker) { $part{$_}=&Apache::lonnet::metadata($uri,$_.'.part'); $name{$_}=&Apache::lonnet::metadata($uri,$_.'.name'); - $display{$_}=&Apache::lonnet::metadata($uri,$_.'.display'); + my $parmdis=&Apache::lonnet::metadata($uri,$_.'.display'); + if ($allparms{$name{$_}} ne '') { + my $identifier; + if ($parmdis =~ /(\s*\[Part.*)$/) { + $identifier = $1; + } + $display{$_} = $allparms{$name{$_}}.$identifier; + } else { + $display{$_} = $parmdis; + } unless ($display{$_}) { $display{$_}=''; } $display{$_}.=' ('.$name{$_}.')'; $default{$_}=&Apache::lonnet::metadata($uri,$_); @@ -2075,7 +2133,16 @@ ENDTABLEHEADFOUR if ((grep $_ eq $fullkeyp, @catmarker) &&(!$name{$tempkeyp})) { $part{$tempkeyp}="0"; $name{$tempkeyp}=&Apache::lonnet::metadata($uri,$fullkeyp.'.name'); - $display{$tempkeyp}=&Apache::lonnet::metadata($uri,$fullkeyp.'.display'); + my $parmdis=&Apache::lonnet::metadata($uri,$fullkeyp.'.display'); + if ($allparms{$name{$tempkeyp}} ne '') { + my $identifier; + if ($parmdis =~ /(\s*\[Part.*)$/) { + $identifier = $1; + } + $display{$tempkeyp} = $allparms{$name{$tempkeyp}}.$identifier; + } else { + $display{$tempkeyp} = $parmdis; + } unless ($display{$tempkeyp}) { $display{$tempkeyp}=''; } $display{$tempkeyp}.=' ('.$name{$tempkeyp}.')'; $display{$tempkeyp} =~ s/_\w+_/_0_/; @@ -2112,7 +2179,7 @@ ENDTABLEHEADFOUR ,''.$coursename.'' ) ."
\n" - ); + ); #---------------------------------------------------------------- print table $r->print('

'.&Apache::loncommon::start_data_table() .&Apache::loncommon::start_data_table_header_row() @@ -2128,7 +2195,9 @@ ENDTABLEHEADFOUR \%type,\%display,$defbgone,$defbgtwo,$defbgthree, $parmlev,$uname,$udom,$csec,$cgroup); } - $r->print(&Apache::loncommon::end_data_table().'

'); + $r->print(&Apache::loncommon::end_data_table().'

' + .'' + ); } # end each map } # end of $parmlev eq map #--------------------------------- Entry for parm level general (Course level) @@ -2166,7 +2235,16 @@ ENDTABLEHEADFOUR if ((grep $_ eq $fullkeyp, @catmarker) &&(!$name{$tempkeyp})) { $part{$tempkeyp}="0"; $name{$tempkeyp}=&Apache::lonnet::metadata($uri,$fullkeyp.'.name'); - $display{$tempkeyp}=&Apache::lonnet::metadata($uri,$fullkeyp.'.display'); + my $parmdis=&Apache::lonnet::metadata($uri,$fullkeyp.'.display'); + if ($allparms{$name{$tempkeyp}} ne '') { + my $identifier; + if ($parmdis =~ /(\s*\[Part.*)$/) { + $identifier = $1; + } + $display{$tempkeyp} = $allparms{$name{$tempkeyp}}.$identifier; + } else { + $display{$tempkeyp} = $parmdis; + } unless ($display{$tempkeyp}) { $display{$tempkeyp}=''; } $display{$tempkeyp}.=' ('.$name{$tempkeyp}.')'; $display{$tempkeyp} =~ s/_\w+_/_0_/; @@ -2231,6 +2309,7 @@ sub crsenv { my $crs = $env{'course.'.$env{'request.course.id'}.'.num'}; my (%crsinfo,$chome); + my $crstype = &Apache::loncommon::course_type(); # # Go through list of changes @@ -2241,6 +2320,23 @@ sub crsenv { if ($name eq 'newp') { $name = $env{'form.newp_name'}; } + if ($name =~ /^rolenames_([^_]+)$/) { + $name = $1.'.plaintext'; + my $standardtitle = + &Apache::lonnet::plaintext($1,$crstype,$env{'request.course.id'},1); + my %adv_roles = + &Apache::lonnet::get_course_adv_roles($env{'request.course.id'},1); + if ($value ne '') { + foreach my $role (keys(%adv_roles)) { + if ($role =~ m{^cr/$match_domain/$match_name/\Q$value\E$}) { + $setoutput.= ''. + &mt('Requested replacement title for [_1] role is already used as the name of a custom role ([_2]).',$standardtitle,$value). + '
'; + undef($value); + } + } + } + } if ($name eq 'url') { $value=~s/^\/res\///; my $bkuptime=time; @@ -2291,12 +2387,12 @@ sub crsenv { my ($name,$domain) = split(':',$user); if (!defined($user) || !defined($domain)) { $setoutput.= '
'. - &mt("Invalid email address specified, address must be of the form username:domain what was specified was ([_1])",$user). + &mt("Invalid e-mail address specified, address must be of the form username:domain what was specified was ([_1])",$user). ''; undef($value); } elsif (&Apache::lonnet::homeserver($user,$domain) eq 'no_host') { $setoutput.= '
'. - &mt("Invalid email address specified, user [_1] is unknown.",$name). + &mt("Invalid e-mail address specified, user [_1] is unknown.",$name). ''; undef($value); } @@ -2463,12 +2559,12 @@ sub crsenv { .'('.&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').'
' + 'plc.roles.denied'=> ''.&mt('Disallow chat room use for Roles').'
' .'('.&mt('[_1]: student, [_2]: TA, [_3]: instructor','"st"','"ta"','"in"').')
' .'("'.&mt('role,role,...').'") ' .Apache::loncommon::help_open_topic("Course_Disable_Discussion"), 'plc.users.denied' => - ''.&mt('Disallow live chatroom use for Users').'
'. + ''.&mt('Disallow chat room use for Users').'
'. '("'.&mt('user:domain,user:domain,...').'")', 'pch.roles.denied'=> ''.&mt('Disallow Resource Discussion for Roles').'
' @@ -2543,7 +2639,7 @@ sub crsenv { 'externalsyllabus' => ''.&mt('URL of Syllabus (not using internal handler)').'', 'tthoptions' - => ''.&mt('Default set of options to pass to tth/m when converting tex').'', + => ''.&mt('Default set of options to pass to tth/m when converting TeX').'', 'texengine' => ''.&mt('Force all students in the course to use a specific math rendering engine.').'
' @@ -2562,6 +2658,9 @@ sub crsenv { &mt('Display Categories').'', 'datelocale' => ''.&mt('Locale used for course calendar').'', + 'rolenames' + => ''.&mt('Replacement titles for standard course roles').'
'. + '('.&mt('To replace the standard title for a course role, enter the title you wish to use, otherwise leave blank.').')', ); my @Display_Order = ('url','description','courseid','cloners'); (my $can_toggle_cat,$can_categorize) = &can_modify_catsettings($dom); @@ -2586,6 +2685,7 @@ sub crsenv { 'languages', 'timezone', 'datelocale', + 'rolenames', 'nothideprivileged', 'rndseed', 'receiptalg', @@ -2609,7 +2709,8 @@ sub crsenv { foreach my $parameter (sort(keys(%values))) { unless (($parameter =~ m/^internal\./)||($parameter =~ m/^metadata\./) || ($parameter =~ m/^selfenroll_/) || ($parameter =~ /_selfenroll$/) - || ($parameter eq 'type')) { + || ($parameter eq 'type') || + ($parameter =~ m/^(cc|in|ta|ep|ad|st)\.plaintext$/)) { if (! $descriptions{$parameter}) { $descriptions{$parameter}=$parameter; push(@Display_Order,$parameter); @@ -2649,7 +2750,27 @@ sub crsenv { $output .= ''. &Apache::loncommon::select_datelocale($parameter.'_value', $currdatelocale, - $onchange,$includeempty).''; + $onchange,$includeempty).''; + } elsif ($parameter eq 'rolenames') { + $output.= ''; + foreach my $role ('cc','in','ta','ep','ad','st') { + my $onchange = 'onFocus="javascript:window.document.forms'. + "['envform'].elements['". + $parameter.'_'.$role."_setparmval']". + '.checked=true;"'; + $output.= ''; + } + $output .= '
'.&Apache::lonnet::plaintext($role,$crstype,undef,1). + ''. + &Apache::lonhtmlcommon::textbox($parameter.'_'.$role.'_value', + $values{$role.'.plaintext'}, + 15,$onchange). + '
'; + foreach my $role ('cc','in','ta','ep','ad','st') { + $output .= ''; + } + $output .= '
'.&Apache::lonhtmlcommon::checkbox($parameter.'_'.$role.'_setparmval'). + '
'; } elsif ($parameter eq 'categories') { my $catdisplay; if ($values{'categories'} ne '') { @@ -2671,9 +2792,11 @@ sub crsenv { $values{$parameter}, 40,$onchange).''; } - $output .= ''. - &Apache::lonhtmlcommon::checkbox($parameter.'_setparmval'). - ''; + unless ($parameter eq 'rolenames') { + $output .= ''. + &Apache::lonhtmlcommon::checkbox($parameter.'_setparmval'). + ''; + } $output .= &Apache::loncommon::end_data_table_row()."\n"; } my $onchange = 'onFocus="javascript:window.document.forms'. @@ -3103,7 +3226,7 @@ sub listdata { } if ($part ne $oldpart) { $r->print(&tableend(). - "\n".&mt('Part').": $part"); + "\n".''.&mt('Part').": $part"); $oldpart=$part; } # @@ -3138,7 +3261,7 @@ sub listdata { $r->print(&default_selector($thiskey,$$resourcedata{$thiskey})); } $r->print(''); + $thistype.'" />'); $r->print(''.&Apache::loncommon::end_data_table_row()); } } @@ -3450,7 +3573,7 @@ ENDOVER my $foundkeys=&listdata($r,$resourcedata,$resourcedata,$sortorder); $r->print(&tableend().'

'. - ($foundkeys?'':&mt('There are no parameters.')).'

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

'. &Apache::loncommon::end_page()); } @@ -3882,20 +4005,20 @@ sub output_row { my $multiple_checked; my $single_checked; if ($options =~ m/onlyone/) { - $multiple_checked = ""; - $single_checked = " CHECKED "; + $multiple_checked = ''; + $single_checked = ' checked="checked"'; } else { - $multiple_checked = " CHECKED "; - $single_checked = ""; + $multiple_checked = ' checked="checked"'; + $single_checked = ''; } $output .= &Apache::loncommon::continue_data_table_row(); $output .= ''.(' ' x 10).' - + '.&mt('Student may select multiple choices from list').''; $output .= &Apache::loncommon::end_data_table_row(); $output .= &Apache::loncommon::continue_data_table_row(); $output .= ''.(' ' x 10).' - + '.&mt('Student may select only one choice from list').''; $output .= &Apache::loncommon::end_data_table_row(); } @@ -4324,7 +4447,7 @@ ENDYESNO } $r->print(&Apache::loncommon::end_data_table(). "\n".''."\n". + &mt('Save').'" />'."\n". &Apache::loncommon::end_page()); return; } @@ -4560,6 +4683,94 @@ sub parm_change_log { $r->print(&Apache::loncommon::end_page()); } +sub update_slots { + my ($slot_name,$cdom,$cnum,$symb,$uname,$udom) = @_; + my %slot=&Apache::lonnet::get_slot($slot_name); + if (!keys(%slot)) { + return 'error: slot does not exist'; + } + my $max=$slot{'maxspace'}; + if (!defined($max)) { $max=99999; } + + my %consumed=&Apache::lonnet::dump('slot_reservations',$cdom,$cnum, + "^$slot_name\0"); + my ($tmp)=%consumed; + if ($tmp=~/^error: 2 / ) { + return 'error: unable to determine current slot status'; + } + my $last=0; + foreach my $key (keys(%consumed)) { + my $num=(split('\0',$key))[1]; + if ($num > $last) { $last=$num; } + if ($consumed{$key}->{'name'} eq $uname.':'.$udom) { + return 'ok'; + } + } + + if (scalar(keys(%consumed)) >= $max) { + return 'error: no space left in slot'; + } + my $wanted=$last+1; + + my %reservation=('name' => $uname.':'.$udom, + 'timestamp' => time, + 'symb' => $symb); + + my $success=&Apache::lonnet::newput('slot_reservations', + {"$slot_name\0$wanted" => + \%reservation}, + $cdom, $cnum); + if ($success eq 'ok') { + my %storehash = ( + symb => $symb, + slot => $slot_name, + action => 'reserve', + context => 'parameter', + ); + &Apache::lonnet::instructor_log('slotreservationslog',\%storehash, + '',$uname,$udom,$cnum,$cdom); + + &Apache::lonnet::instructor_log($cdom.'_'.$cnum.'_slotlog',\%storehash, + '',$uname,$udom,$uname,$udom); + } + return $success; +} + +sub delete_slots { + my ($slot_name,$cdom,$cnum,$uname,$udom,$symb) = @_; + my $delresult; + my %consumed = &Apache::lonnet::dump('slot_reservations',$cdom, + $cnum, "^$slot_name\0"); + if (&Apache::lonnet::error(%consumed)) { + return 'error: unable to determine current slot status'; + } + my ($tmp)=%consumed; + if ($tmp=~/^error: 2 /) { + return 'error: unable to determine current slot status'; + } + foreach my $key (keys(%consumed)) { + if ($consumed{$key}->{'name'} eq $uname.':'.$udom) { + my $num=(split('\0',$key))[1]; + my $entry = $slot_name.'\0'.$num; + $delresult = &Apache::lonnet::del('slot_reservations',[$entry], + $cdom,$cnum); + if ($delresult eq 'ok') { + my %storehash = ( + symb => $symb, + slot => $slot_name, + action => 'release', + context => 'parameter', + ); + &Apache::lonnet::instructor_log('slotreservationslog',\%storehash, + 1,$uname,$udom,$cnum,$cdom); + &Apache::lonnet::instructor_log($cdom.'_'.$cnum.'_slotlog',\%storehash, + 1,$uname,$udom,$uname,$udom); + } + } + } + return $delresult; +} + sub check_for_course_info { my $navmap = Apache::lonnavmaps::navmap->new(); return 1 if ($navmap);