--- loncom/interface/lonparmset.pm 2009/02/24 18:20:49 1.435 +++ loncom/interface/lonparmset.pm 2009/03/30 15:57:26 1.439 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # Handler to set parameters for assessments # -# $Id: lonparmset.pm,v 1.435 2009/02/24 18:20:49 hauer Exp $ +# $Id: lonparmset.pm,v 1.439 2009/03/30 15:57:26 bisitz Exp $ # # Copyright Michigan State University Board of Trustees # @@ -1076,12 +1076,20 @@ sub print_td { my ($r,$which,$defbg,$result,$outpar,$mprefix,$value,$typeoutpar,$display)=@_; $r->print(''); - 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(''."\n"); } @@ -1797,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], @@ -2268,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 @@ -2278,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; @@ -2453,7 +2512,14 @@ sub crsenv { my $SelectStyleFile=&mt('Select Style File'); my $SelectSpreadsheetFile=&mt('Select Spreadsheet File'); my $output=''; + my $output_SB = ''; # will be replaced by "$output" when all changes are done my $can_categorize; + my %lt=&Apache::lonlocal::texthash( + 'par' => 'Parameter', + 'val' => 'Value', + 'set' => 'Set?', + 'sav' => 'Save', + ); if (! exists($values{'con_lost'})) { my %descriptions= ('url' => ''.&mt('Top Level Map').'
'. @@ -2599,69 +2665,91 @@ 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); - if ($can_toggle_cat) { - push(@Display_Order,'hidefromcat'); - } - if ($can_categorize) { - push(@Display_Order,'categories'); - } - push (@Display_Order,('grading', - 'externalsyllabus', - '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', - 'allow_discussion_post_editing', - 'languages', - 'timezone', - 'datelocale', - 'nothideprivileged', - 'rndseed', - 'receiptalg', - 'problem_stream_switch', - 'suppress_tries', - 'suppress_embed_prompt', - 'default_paper_size', - 'print_header_format', - 'disable_receipt_display', - 'spreadsheet_default_classcalc', - 'spreadsheet_default_studentcalc', - 'spreadsheet_default_assesscalc', - 'hideemptyrows', - 'default_enrollment_start_date', - 'default_enrollment_end_date', - 'tthoptions', - 'texengine', - 'disablesigfigs', - 'disableexampointprint', - 'task_messages','task_grading')); - foreach my $parameter (sort(keys(%values))) { - unless (($parameter =~ m/^internal\./)||($parameter =~ m/^metadata\./) || - ($parameter =~ m/^selfenroll_/) || ($parameter =~ /_selfenroll$/) - || ($parameter eq 'type')) { - if (! $descriptions{$parameter}) { - $descriptions{$parameter}=$parameter; - push(@Display_Order,$parameter); - } - } - } - - foreach my $parameter (@Display_Order) { - my $description = $descriptions{$parameter}; - # onchange is javascript to automatically check the 'Set' button. - my $onchange = 'onFocus="javascript:window.document.forms'. - "['envform'].elements['".$parameter."_setparmval']". - '.checked=true;"'; - $output .= &Apache::loncommon::start_data_table_row(). - ''.$description.''; + + +# The following code is kept to have access to the old version of display order + +# my @Display_Order = ('url','description','courseid','cloners'); +# (my $can_toggle_cat,$can_categorize) = &can_modify_catsettings($dom); +# if ($can_toggle_cat) { +# push(@Display_Order,'hidefromcat'); +# } +# if ($can_categorize) { +# push(@Display_Order,'categories'); +# } +# push (@Display_Order,('grading', +# 'externalsyllabus', +# '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', +# 'allow_discussion_post_editing', +# 'languages', +# 'timezone', +# 'datelocale', +# 'rolenames', +# 'nothideprivileged', +# 'rndseed', +# 'receiptalg', +# 'problem_stream_switch', +# 'suppress_tries', +# 'suppress_embed_prompt', +# 'default_paper_size', +# 'print_header_format', +# 'disable_receipt_display', +# 'spreadsheet_default_classcalc', +# 'spreadsheet_default_studentcalc', +# 'spreadsheet_default_assesscalc', +# 'hideemptyrows', +# 'default_enrollment_start_date', +# 'default_enrollment_end_date', +# 'tthoptions', +# 'texengine', +# 'disablesigfigs', +# 'disableexampointprint', +# 'task_messages','task_grading')); +# foreach my $parameter (sort(keys(%values))) { +# unless (($parameter =~ m/^internal\./)||($parameter =~ m/^metadata\./) || +# ($parameter =~ m/^selfenroll_/) || ($parameter =~ /_selfenroll$/) +# || ($parameter eq 'type') || +# ($parameter =~ m/^(cc|in|ta|ep|ad|st)\.plaintext$/)) { +# if (! $descriptions{$parameter}) { +# $descriptions{$parameter}=$parameter; +# push(@Display_Order,$parameter); +# } +# } +# } + + + + +# ---------------------------------------------------------------- +# Begin: New Version with Parameter Categories + + sub parameter_row { + # Create parameter line for course environment screen + my ($parameter, $description) = @_; + my $output = ''; + + # Column 1/3: Descritive text of current parameter + $output = &Apache::loncommon::start_data_table_row() + .''.$description.''; + + # Column 2/3: Input field (Sometimes special field(s), depending on parameter) +# ------------------------------- + # onchange is javascript to automatically check the 'Set' button. + my $onchange = 'onFocus="javascript:window.document.forms' + ."['envform'].elements['".$parameter."_setparmval']" + .'.checked=true;"'; if ($parameter =~ /^default_enrollment_(start|end)_date$/) { $output .= ''. &Apache::lonhtmlcommon::date_setter('envform', @@ -2686,7 +2774,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 '') { @@ -2702,17 +2810,294 @@ sub crsenv { $values{'categories'}.'" />'. ''; - } else { - $output .= ''. - &Apache::lonhtmlcommon::textbox($parameter.'_value', - $values{$parameter}, - 40,$onchange).''; - } - $output .= ''. - &Apache::lonhtmlcommon::checkbox($parameter.'_setparmval'). - ''; - $output .= &Apache::loncommon::end_data_table_row()."\n"; - } + } else { # Display default textbox in all other cases + $output .= '' + .&Apache::lonhtmlcommon::textbox($parameter.'_value', + $values{$parameter}, + 40, + $onchange) + .''; +# ------------------------------- + } + + # Column 3/3: Check Box (in most cases) + unless ($parameter eq 'rolenames') { + $output .= '' + .&Apache::lonhtmlcommon::checkbox($parameter.'_setparmval') + .''; + } + $output .= &Apache::loncommon::end_data_table_row(); + + return $output; + } + + + + + # Parameter Category Names + my %parm_cat_names = &Apache::lonlocal::texthash ( + 'cat_0' => 'Parameter Category Zero', + 'cat_1' => 'Parameter Category One', + 'cat_2' => 'Parameter Category Two', + 'cat_3' => 'Parameter Category Three', + 'cat_4' => 'Parameter Category Four', + 'cat_5' => 'Parameter Category Five', + 'cat_6' => 'Parameter Category Six', + 'cat_7' => 'Parameter Category Seven', + 'cat_can' => 'Parameter Category Can', + 'cat_custom' => 'Parameter Category Custom', + ); + + # Link Parameter Categories with Parameters + my %parm_cat_parms = ( + 'cat_0' => [ + 'url', + 'description', + 'courseid', + 'cloners' + ], + 'cat_1' => [ + 'grading', + 'externalsyllabus', + 'default_xml_style', + 'pageseparators' + ], + 'cat_2' => [ + 'question.email', + 'question.email.text', + 'comment.email', + 'comment.email.text', + 'policy.email', + 'policy.email.text', + ], + 'cat_3' => [ + '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', + 'allow_discussion_post_editing', + ], + 'cat_4' => [ + 'languages', + 'timezone', + 'datelocale', + 'rolenames', + 'nothideprivileged', + 'rndseed', + 'receiptalg', + 'problem_stream_switch', + 'suppress_tries', + 'suppress_embed_prompt', + 'default_paper_size', + 'print_header_format', + 'disable_receipt_display', + ], + 'cat_5' => [ + 'spreadsheet_default_classcalc', + 'spreadsheet_default_studentcalc', + 'spreadsheet_default_assesscalc', + 'hideemptyrows', + ], + 'cat_6' => [ + 'default_enrollment_start_date', + 'default_enrollment_end_date', + ], + 'cat_7' => [ + 'tthoptions', + 'texengine', + 'disablesigfigs', + 'disableexampointprint', + 'task_messages', + 'task_grading', + ], + ); + + # Add special parameters depending on special context to parameter categories hash + my @can_cats; + (my $can_toggle_cat,$can_categorize) = &can_modify_catsettings($dom); + if ($can_toggle_cat) { + push(@can_cats,'hidefromcat'); + } + if ($can_categorize) { + push(@can_cats,'categories'); + } + $parm_cat_parms{'cat_can'} = [@can_cats]; + + # Add custom parameters to parameter categories hash + my @custom_cats; + foreach my $parameter (sort(keys(%values))) { + unless (($parameter =~ m/^internal\./)||($parameter =~ m/^metadata\./) || + ($parameter =~ m/^selfenroll_/) || ($parameter =~ /_selfenroll$/) + || ($parameter eq 'type') || + ($parameter =~ m/^(cc|in|ta|ep|ad|st)\.plaintext$/)) { + if (! $descriptions{$parameter}) { + $descriptions{$parameter}=$parameter; + push(@custom_cats,$parameter); + } + } + } + $parm_cat_parms{'cat_custom'} = [@custom_cats]; + + +# Old output structure: + +#$start_table +#$start_header_row +#$lt{'par'}$lt{'val'}$lt{'set'} +#$end_header_row +#$output +#$end_table + + +# Display Parameter List Overview +# Provide hyperlinks to detailed parameter settings +$output_SB .= '' + .'

'.&mt('Course Parameter Overview').'

' + .'
' + .'' + .'
'; + + +# Display Parameter Details +my $buttons='
' + .'' + .'
'.&mt('Back to Parameter List').'' + .'
'; + +$output_SB .= '

'.&mt('Course Parameters').'

'; + +foreach my $catkey (keys(%parm_cat_names)) { + $output_SB .= &Apache::loncommon::start_data_table(); + $output_SB .= &Apache::loncommon::start_data_table_empty_row() + .'' + .'' + .'

'.$parm_cat_names{$catkey}.'

' + .'' + .&Apache::loncommon::end_data_table_empty_row + .&Apache::loncommon::start_data_table_header_row() + .''.$lt{'par'}.''.$lt{'val'}.''.$lt{'set'}.'' + .&Apache::loncommon::end_data_table_header_row(); + + foreach my $parameter (@{$parm_cat_parms{$catkey}}) { + my $description = $descriptions{$parameter}; + $output_SB .= ¶meter_row($parameter, $description); + } + $output_SB .= &Apache::loncommon::start_data_table_empty_row() + .'' + .$buttons + .'' + .&Apache::loncommon::end_data_table_empty_row; + $output_SB .= &Apache::loncommon::end_data_table() + . '
'; +} + +$output_SB .= ''; + +# End: New Version with Parameter Categories +# ---------------------------------------------------------------- + + +# # Display Parameter table +# foreach my $parameter (@Display_Order) { +# my $description = $descriptions{$parameter}; +# # onchange is javascript to automatically check the 'Set' button. +# my $onchange = 'onFocus="javascript:window.document.forms'. +# "['envform'].elements['".$parameter."_setparmval']". +# '.checked=true;"'; +# $output .= &Apache::loncommon::start_data_table_row(). +# ''.$description.''; +# +# +# +## ------------------------------- +# if ($parameter =~ /^default_enrollment_(start|end)_date$/) { +# $output .= ''. +# &Apache::lonhtmlcommon::date_setter('envform', +# $parameter.'_value', +# $values{$parameter}, +# $onchange). +# ''; +# } elsif ($parameter eq 'timezone') { +# my $includeempty = 1; +# my $timezone = &Apache::lonlocal::gettimezone(); +# $output .= ''. +# &Apache::loncommon::select_timezone($parameter.'_value', +# $timezone, +# $onchange,$includeempty).''; +# } elsif ($parameter eq 'datelocale') { +# my $includeempty = 1; +# my $locale_obj = &Apache::lonlocal::getdatelocale(); +# my $currdatelocale; +# if (ref($locale_obj)) { +# $currdatelocale = $locale_obj->id(); +# } +# $output .= ''. +# &Apache::loncommon::select_datelocale($parameter.'_value', +# $currdatelocale, +# $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 '') { +# my @curritems = split(/\&/,$values{'categories'}); +# foreach my $item (@curritems) { +# my ($name,$parent,$pos) = split(/:/,$item); +# $catdisplay .= &unescape($name).'&'; +# } +# $catdisplay =~ s/\&$//; +# } +# $output .= ''. +# ''. +# ''; +# } else { +# $output .= ''. +# &Apache::lonhtmlcommon::textbox($parameter.'_value', +# $values{$parameter}, +# 40,$onchange).''; +# } +# ------------------------------- + + +# 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'. '[\'envform\'].elements[\'newp_setparmval\']'. '.checked=true;"'; @@ -2725,12 +3110,6 @@ sub crsenv { ''. &Apache::loncommon::end_data_table_row()."\n"; } - my %lt=&Apache::lonlocal::texthash( - 'par' => 'Parameter', - 'val' => 'Value', - 'set' => 'Set?', - 'sav' => 'Save' - ); my $Parameter=&mt('Parameter'); my $Value=&mt('Value'); @@ -2763,6 +3142,8 @@ $start_page $breadcrumbs
$setoutput +$output_SB +
$start_table $start_header_row @@ -4597,6 +4978,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);