--- loncom/interface/courseprefs.pm 2014/06/09 20:36:56 1.49.2.14 +++ loncom/interface/courseprefs.pm 2015/06/09 21:22:55 1.72 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # Handler to set configuration settings for a course # -# $Id: courseprefs.pm,v 1.49.2.14 2014/06/09 20:36:56 raeburn Exp $ +# $Id: courseprefs.pm,v 1.72 2015/06/09 21:22:55 damieng Exp $ # # Copyright Michigan State University Board of Trustees # @@ -217,6 +217,7 @@ use Apache::lonhtmlcommon(); use Apache::lonconfigsettings; use Apache::lonrelrequtils; use Apache::lonparmset; +use Apache::courseclassifier; use Apache::lonlocal; use LONCAPA qw(:DEFAULT :match); @@ -309,7 +310,7 @@ sub handler { idnu => 'Course ID or number', unco => 'Unique code', desc => 'Course Description', - cred => 'Student credits', + cred => 'Student credits', ownr => 'Course Owner', cown => 'Course Co-owners', catg => 'Categorize course', @@ -381,7 +382,7 @@ sub handler { 'co-owners' => $lt{'cown'}, 'description' => $lt{'desc'}, 'courseid' => $lt{'idnu'}, - 'uniquecode' => $lt{'unco'}, + 'uniquecode' => $lt{'unco'}, 'categories' => $lt{'catg'}, 'hidefromcat' => $lt{'excc'}, 'cloners' => $lt{'clon'}, @@ -463,13 +464,15 @@ sub handler { help => 'Course_Prefs_Display', ordered => ['default_xml_style','pageseparators', 'disable_receipt_display','texengine', - 'tthoptions'], + 'tthoptions','uselcmath','usejsme'], itemtext => { default_xml_style => 'Default XML style file', pageseparators => 'Visibly Separate Items on Pages', disable_receipt_display => 'Disable display of problem receipts', texengine => 'Force use of a specific math rendering engine', tthoptions => 'Default set of options to pass to tth/m when converting TeX', + uselcmath => 'Student formula entry uses inline preview, not DragMath pop-up', + usejsme => 'Molecule editor uses JSME (HTML5) in place of JME (Java)', }, }, 'grading' => @@ -490,7 +493,7 @@ sub handler { help => 'Course_Prefs_Printouts', ordered => ['problem_stream_switch','suppress_tries', 'default_paper_size','print_header_format', - 'disableexampointprint'], + 'disableexampointprint','canuse_pdfforms'], itemtext => { problem_stream_switch => 'Allow problems to be split over pages', suppress_tries => 'Suppress number of tries in printing', @@ -538,7 +541,7 @@ sub handler { \@prefs_order,\%prefs,\%values, $cnum,undef,\@allitems,'coursepref'); } elsif ($phase eq 'display') { - my $jscript = &get_jscript($cid,$cdom,$phase,$crstype); + my $jscript = &get_jscript($cid,$cdom,$phase,$crstype,\%values); my @allitems = &get_allitems(%prefs); &Apache::lonconfigsettings::display_settings($r,$cdom,$phase,$context, \@prefs_order,\%prefs,\%values,undef,$jscript,\@allitems,$crstype,'coursepref'); @@ -784,7 +787,7 @@ sub process_changes { my @clonedoms; if (exists($env{'form.cloners_activate'})) { my $actnum = $env{'form.cloners_activate'}; - if ($actnum ne '') { + if ($actnum ne '-1') { if ($env{'form.cloners_dom_'.$actnum} ne '') { my $clonedom = $env{'form.cloners_dom_'.$actnum}; if (&check_clone($clonedom,$disallowed) eq 'ok') { @@ -802,7 +805,7 @@ sub process_changes { my $clonedom = $env{'form.cloners_dom_'.$i}; if (&check_clone($clonedom,$disallowed) eq 'ok') { if (!grep(/^\*:\Q$clonedom\E$/,@clonedoms)) { - push (@clonedoms,'*:'.$clonedom); + push(@clonedoms,'*:'.$clonedom); } } } @@ -848,6 +851,37 @@ sub process_changes { } } } + if (ref($values) eq 'HASH') { + my (@code_order,%codedefaults); + &Apache::lonnet::auto_instcode_defaults($cdom,\%codedefaults, + \@code_order); + my $clonebycode; + if ($env{'form.cloners_instcode'}) { + if (@code_order > 0) { + my @standardnames = &Apache::loncommon::get_standard_codeitems(); + my %local_to_standard; + for (my $i=0; $i<@code_order; $i++) { + $local_to_standard{$code_order[$i]} = $standardnames[$i]; + } + foreach my $item (@code_order) { + my $key = $local_to_standard{$item}; + if ($key ne '') { + if ($env{'form.'.$key}) { + $clonebycode .= $key.'='.&escape($env{'form.'.$key}).'&'; + } + } + } + $clonebycode =~ s/\&$//; + } + } + if ($clonebycode) { + if ($newvalues{$entry}) { + $newvalues{$entry} .= ','.$clonebycode; + } else { + $newvalues{$entry} = $clonebycode; + } + } + } } if (ref($disallowed) eq 'HASH') { if (ref($disallowed->{'cloners'}) eq 'HASH') { @@ -1047,14 +1081,14 @@ sub process_changes { my ($classorder,$classtitles) = &discussion_vote_classes(); my $fontchange = 0; foreach my $class (@{$classorder}) { - my $ext_entry = $entry.'_'.$class; + my $ext_entry = $entry.'_'.$class; my $size = $env{'form.'.$ext_entry.'_size'}; my $unit = $env{'form.'.$ext_entry.'_unit'}; my $weight = $env{'form.'.$ext_entry.'_weight'}; my $style = $env{'form.'.$ext_entry.'_style'}; my $other = $env{'form.'.$ext_entry.'_other'}; $size =~ s/,//g; - $unit =~ s/,//g; + $unit =~ s/,//g; $weight =~ s/,//g; $style =~ s/,//g; $other =~ s/[^\w;:\s\-\%.]//g; @@ -1062,7 +1096,7 @@ sub process_changes { $newvalues{$ext_entry} = join(',',($size.$unit,$weight,$style,$other)); my $current = $values->{$ext_entry}; if ($values->{$ext_entry} eq '') { - $current = ',,,'; + $current = ',,,'; } if ($newvalues{$ext_entry} ne $current) { $changes->{$ext_entry} = $newvalues{$ext_entry}; @@ -1071,7 +1105,7 @@ sub process_changes { } if ($fontchange) { $changes->{$entry} = 1; - } + } } elsif ($entry eq 'nothideprivileged') { my @curr_nothide; my @new_nothide; @@ -1146,7 +1180,7 @@ sub process_changes { my $newtext = $maxnum-1; $newhdr[$env{'form.printfmthdr_pos_'.$newtext}] = $env{'form.printfmthdr_text_'.$newtext}; $newvalues{$entry} = join('',@newhdr); - } elsif (($entry eq 'languages') || + } elsif (($entry eq 'languages') || ($entry eq 'checkforpriv')) { my $settings; my $total = $env{'form.'.$entry.'_total'}; @@ -1162,7 +1196,7 @@ sub process_changes { } if ($env{'form.'.$entry.'_'.$total} ne '') { my $new = $env{'form.'.$entry.'_'.$total}; - if ($entry eq 'languages') { + if ($entry eq 'languages') { my %langchoices = &get_lang_choices(); if ($langchoices{$new}) { $settings .= $new; @@ -1405,7 +1439,7 @@ sub store_changes { $displayval = &Apache::lonlocal::locallocaltime($displayval); } elsif ($key eq 'categories') { $displayval = $env{'form.categories_display'}; - } elsif ($key eq 'canuse_pdfforms') { + } elsif (($key eq 'canuse_pdfforms') || ($key eq 'usejsme') || ($key eq 'uselcmath')) { if ($changes->{$item}{$key} eq '1') { $displayval = &mt('Yes'); } elsif ($changes->{$item}{$key} eq '0') { @@ -1682,12 +1716,93 @@ sub get_course { } sub get_jscript { - my ($cid,$cdom,$phase,$crstype) = @_; + my ($cid,$cdom,$phase,$crstype,$settings) = @_; my ($can_toggle_cat,$can_categorize) = &can_modify_catsettings($cdom,$crstype); - my ($jscript,$categorize_js,$loncaparev_js); + my ($jscript,$categorize_js,$loncaparev_js,$instcode_js); my $stubrowse_js = &Apache::loncommon::studentbrowser_javascript(); my $browse_js = &Apache::loncommon::browser_and_searcher_javascript('parmset'); my $cloners_js = &cloners_javascript($phase); + my @code_order; + if ($crstype ne 'Community') { + if (ref($settings) eq 'HASH') { + my %codedefaults; + &Apache::lonnet::auto_instcode_defaults($cdom,\%codedefaults, + \@code_order); + if (@code_order > 0) { + if ($phase eq 'display') { + my @actions = &Apache::loncommon::get_env_multiple('form.actions'); + if (grep(/^courseinfo$/,@actions)) { + if ($settings->{'cloners'} ne '') { + unless ($settings->{'cloners'} eq '*') { + my @cloners = split(/,/,$settings->{'cloners'}); + my @standardnames = &Apache::loncommon::get_standard_codeitems(); + my %local_to_standard; + for (my $i=0; $i<@code_order; $i++) { + $local_to_standard{$code_order[$i]} = $standardnames[$i]; + } + foreach my $cloner (@cloners) { + if (($cloner !~ /^\Q*:\E$match_domain$/) && + ($cloner !~ /^$match_username\:$match_domain$/)) { + foreach my $item (split(/\&/,$cloner)) { + my ($key,$val) = split(/\=/,$item); + $val = &unescape($val); + foreach my $code (@code_order) { + if ($key eq $local_to_standard{$code}) { + $env{'form.'.$key} = $val; + } + } + } + } + } + } + } + } + } + my @codetitles; + (undef,$instcode_js) = + &Apache::courseclassifier::instcode_selectors($cdom,'display',undef, + \@codetitles); + $instcode_js .= <'."\n". ''."\n".$stubrowse_js."\n"; return $jscript; @@ -1766,7 +1881,7 @@ function update_cloners(caller,num) { if (document.$formname.cloners_activate[i].value == '0') { document.$formname.cloners_activate[i].checked = false; } - if (document.$formname.cloners_activate[i].value == '') { + if (document.$formname.cloners_activate[i].value == '-1') { document.$formname.cloners_activate[i].checked = true; } } @@ -1823,9 +1938,10 @@ sub print_courseinfo { unless ((ref($settings) eq 'HASH') && (ref($ordered) eq 'ARRAY') && (ref($itemtext) eq 'HASH')) { return; } - my ($cathash,$categoriesform,$autocoowner); + my ($cathash,$categoriesform,$autocoowner,$clonedefaults); my %domconf = - &Apache::lonnet::get_dom('configuration',['coursecategories','autoenroll'],$cdom); + &Apache::lonnet::get_dom('configuration', + ['coursecategories','autoenroll','coursedefaults'],$cdom); if (ref($domconf{'coursecategories'}) eq 'HASH') { $cathash = $domconf{'coursecategories'}{'cats'}; if (ref($cathash) eq 'HASH') { @@ -1837,10 +1953,58 @@ sub print_courseinfo { if (ref($domconf{'autoenroll'}) eq 'HASH') { $autocoowner = $domconf{'autoenroll'}{'co-owners'}; } + my ($currcanclone,@code_order,$cloner_instcode); + my %codedefaults; + &Apache::lonnet::auto_instcode_defaults($cdom,\%codedefaults, + \@code_order); + if ($settings->{'cloners'}) { + unless ($settings->{'cloners'} eq '*') { + my @currclone = split(/,/,$settings->{'cloners'}); + foreach my $item (@currclone) { + unless ($item eq '*') { + if (($item !~ /\:/) && ($item =~ /=/)) { + $cloner_instcode = 1; + } + } + } + } + } + if (ref($domconf{'coursedefaults'}) eq 'HASH') { + my $canclone = $domconf{'coursedefaults'}{'canclone'}; + if (ref($canclone) eq 'HASH') { + if (ref($canclone->{'instcode'}) eq 'ARRAY') { + if ($settings->{'internal.coursecode'}) { + my @posscodes; + if (@code_order > 0) { + $currcanclone = 'instcode'; + foreach my $item (@{$canclone->{'instcode'}}) { + if (grep(/^\Q$item\E$/,@code_order)) { + push(@posscodes,$item); + } + } + my $codestr = join(' + ',@posscodes); + $clonedefaults = &mt('Default for official courses is to also allow cloning if [_1] match in cloner and cloned.', + '"'.$codestr.'"').'
'; + } + } + } + } elsif ($canclone eq 'domain') { + $clonedefaults = &mt('Default is for any course requester in [_1] domain to be able to clone.', + ''.$cdom.'').'
'; + $currcanclone = 'domain'; + } + if ($clonedefaults) { + if ($settings->{'cloners'} ne '') { + $clonedefaults .= '
'.&mt('Default does [_1]not[_2] currently apply because values have been set in the course.','',''); + } else { + $clonedefaults .= &mt('Default is disregarded if [_1]any[_2] values are set here in the course.','',''); + } + $clonedefaults = '

'.$clonedefaults; + } + } if (!defined($categoriesform)) { $categoriesform = &mt('No categories defined in this domain.'); } - my ($can_toggle_cat,$can_categorize) = &can_modify_catsettings($cdom,$crstype); my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'}; @@ -1887,7 +2051,8 @@ sub print_courseinfo { }, 'cloners' => { text => ''.&mt($itemtext->{'cloners'}).'
'. - &mt('Owner and Coordinators included automatically'), + &mt('Owner and Coordinators included automatically'). + $clonedefaults, input => 'textbox', size => '40' }, @@ -1934,7 +2099,7 @@ sub print_courseinfo { next if (!$env{'course.'.$env{'request.course.id'}.'.internal.uniquecode'}); } unless (($item eq 'cloners') || ($item eq 'rolenames')) { - $colspan = 2; + $colspan = 2; } $count ++; if (exists $items{$item}{advanced} && $items{$item}{advanced} == 1) { @@ -1958,12 +2123,13 @@ sub print_courseinfo { } $datatable .= 'onchange="javascript:update_cloners('. "'cloners_all'".');" />'.&mt('Yes').''. - (' 'x2).''. + '{$item} ne '*') { $datatable .= ' checked="checked" '; } $datatable .= ' onchange="javascript:update_cloners('. - "'cloners_all'".');"/>'.&mt('No').''. + "'cloners_all'".');" />'.&mt('No').''. &Apache::loncommon::end_data_table_row(). &Apache::loncommon::end_data_table(). ''.&Apache::loncommon::end_data_table_row(). &Apache::loncommon::end_data_table(); + if (@code_order > 0) { + my (%cat_items,@codetitles,%cat_titles,%cat_order); + my ($jscript,$totcodes,$numtitles,$lasttitle) = + &Apache::courseclassifier::instcode_selectors_data($cdom,'display', + \%cat_items,\@codetitles, + \%cat_titles,\%cat_order); + my $showncodes = 'off'; + my $checkedoff = ' checked="checked"'; + my $checkedon = ''; + if ($cloner_instcode) { + $checkedon = $checkedoff; + $checkedoff = ''; + $showncodes = 'on'; + } + $datatable .= '
'.&mt('Or'). @@ -1971,7 +2137,11 @@ sub print_courseinfo { &Apache::loncommon::start_data_table(); my @cloners; if ($settings->{$item} eq '') { - $datatable .= &new_cloners_dom_row($cdom,'0'); + my $default; + if ($currcanclone eq 'domain') { + $default = '0'; + } + $datatable .= &new_cloners_dom_row($cdom,'0',$default); } elsif ($settings->{$item} ne '*') { my @entries = split(/,/,$settings->{$item}); if (@entries > 0) { @@ -2030,6 +2200,37 @@ sub print_courseinfo { $items{$item}{'size'}). '
'.&mt('And'). + '
'. + &Apache::loncommon::start_data_table(). + &Apache::loncommon::start_data_table_row(). + ''. + &mt('Cloning by official course(s) based on course category').(' 'x2). + ''. + (' '). + ''. + &Apache::courseclassifier::build_instcode_selectors($numtitles, + $lasttitle,\%cat_items,\@codetitles,\%cat_titles,\%cat_order, + $showncodes,'LC_cloners_instcodes','LC_cloners_instcode'). + ''.&Apache::loncommon::end_data_table_row(). + &Apache::loncommon::end_data_table(); + } } elsif ($item eq 'rolenames') { $datatable .= ''. &Apache::loncommon::start_data_table(); @@ -2073,12 +2274,12 @@ sub print_courseinfo { if ($clonesrc =~ m{/$match_domain/$match_courseid}) { my %clonesrcinfo = &Apache::lonnet::coursedescription($clonesrc); if ($clonesrcinfo{'description'}) { - $clonedfrom = $clonesrcinfo{'description'}.' '.($clonesrc); + $clonedfrom = $clonesrcinfo{'description'}.' '.($clonesrc); } } $datatable .= $clonedfrom; } elsif ($item eq 'uniquecode') { - my $code = $env{'course.'.$env{'request.course.id'}.'.internal.uniquecode'}; + my $code = $env{'course.'.$env{'request.course.id'}.'.internal.uniquecode'}; if ($code) { $datatable .= $code; } @@ -2125,12 +2326,12 @@ sub print_courseinfo { } elsif ($uploaded) { $datatable .= &mt('Uploaded file'); } else { - $datatable .= &mt('Standard template'); + $datatable .= &mt('Standard template'); } $datatable .= (' ' x 2). &mt('[_1]View[_2]', '', - ''); + ''); } elsif ($item eq 'loncaparev') { my $loncaparev = $env{'course.'.$env{'request.course.id'}.'.internal.releaserequired'}; my $showreqd; @@ -2151,19 +2352,24 @@ sub print_courseinfo { } sub new_cloners_dom_row { - my ($newdom,$num) = @_; - my $output; + my ($newdom,$num,$default) = @_; + my ($output,$checkedon,$checkedoff); if ($newdom ne '') { + if ($num eq $default) { + $checkedon = 'checked="checked" '; + } else { + $checkedoff = 'checked="checked" '; + } $output .= &Apache::loncommon::start_data_table_row(). ''. &mt('Any user in domain:').' '.$newdom.''. (' 'x2).''.(' 'x2). ' @@ -2300,7 +2507,7 @@ ENDSCRIPT sub display_loncaparev_constraints { my ($r,$navmap,$loncaparev,$crstype) = @_; - my ($reqdmajor,$reqdminor); + my ($reqdmajor,$reqdminor); my $cid = $env{'request.course.id'}; my $cdom = $env{'course.'.$cid.'.domain'}; my $cnum = $env{'course.'.$cid.'.num'}; @@ -2319,100 +2526,132 @@ sub display_loncaparev_constraints { my (%fromparam,%rowspan,%bymap,%byresource,@scopeorder,%toshow,%allmaps, %byresponsetype,%bysubmission,%fromblocks); @scopeorder = ('all','section/group','user'); + my $now = time; my $resourcedata = &Apache::lonparmset::readdata($cnum,$cdom); if (ref($resourcedata) eq 'HASH') { foreach my $key (keys(%{$resourcedata})) { + my %found; foreach my $item (keys(%Apache::lonrelrequtils::checkparms)) { if ($key =~ /(\Q$item\E)$/) { - if (ref($Apache::lonrelrequtils::checkparms{$item}) eq 'ARRAY') { - my $value = $resourcedata->{$key}; - if ($item eq 'examcode') { - if (&Apache::lonnet::validCODE($value)) { - $value = 'valid'; - } else { - $value = ''; - } - } - my ($middle,$scope,$which,$level,$map,$resource); - if (grep(/^\Q$value\E$/,@{$Apache::lonrelrequtils::checkparms{$item}})) { - my $stdtype = &Apache::lonparmset::standard_parameter_types($item); - my $stdname = &Apache::lonparmset::standard_parameter_names($item); - my $valname = &get_param_description($stdtype,$value); - my $rev = $Apache::lonnet::needsrelease{'parameter:'.$item.':'.$value}; - my $start = $cid.'.'; - if ($key =~ /^\Q$start\E(\[useropt\:($match_username\:$match_domain)\]\.)/) { - $middle = $1; - $which = $2; - $scope = 'user'; - } elsif ($key =~ /^\Q$start\E(\[(\w+)\]\.)/) { - $middle = $1; - $which = $2; - $scope = 'section/group'; - } else { - $scope = 'all'; - } - my $what="$stdname=$valname"; - if ($key =~ /^\Q$start$middle\E\w+\.\Q$item\E$/) { - $level = 'general'; - if ($scope eq 'all') { - if (ref($fromparam{$rev}{$scope}) eq 'ARRAY') { - unless(grep(/^\Q$what\E$/,@{$fromparam{$rev}{$scope}})) { - push(@{$fromparam{$rev}{$scope}},$what); - } - } else { - push(@{$fromparam{$rev}{$scope}},$what); - } - } else { - if (ref($fromparam{$rev}{$scope}{$which}) eq 'ARRAY') { - unless (grep(/^\Q$what\E$/,@{$fromparam{$rev}{$scope}{$which}})) { - push(@{$fromparam{$rev}{$scope}{$which}},$what); - } - } else { - push(@{$fromparam{$rev}{$scope}{$which}},$what); - } - } - $rowspan{$rev} ++; - } elsif ($key =~ /^\Q$start$middle\E(.+)___\(all\).\w+\.\Q$item\E$/) { - $level = 'folder'; - $map = $1; - if ($scope eq 'all') { - if (ref($bymap{$map}{$rev}{$scope}) eq 'ARRAY') { - unless(grep(/^\Q$what\E$/,@{$bymap{$map}{$rev}{$scope}})) { - push(@{$bymap{$map}{$rev}{$scope}},$what); - } - } else { - push(@{$bymap{$map}{$rev}{$scope}},$what); - } - } else { - if (ref($bymap{$map}{$rev}{$scope}{$which}) eq 'ARRAY') { - unless(grep(/^\Q$what\E$/,@{$bymap{$map}{$rev}{$scope}{$which}})) { - push(@{$bymap{$map}{$rev}{$scope}{$which}},$what); - } - } else { - push(@{$bymap{$map}{$rev}{$scope}{$which}},$what); - } - } - } elsif ($key =~ /^\Q$start$middle\E(.+)\.\w+\.\Q$item\E$/) { - $level = 'resource'; - $resource = $1; - if ($scope eq 'all') { - if (ref($byresource{$resource}{$rev}{$scope}) eq 'ARRAY') { - unless(grep(/^\Q$what\E$/,@{$byresource{$resource}{$rev}{$scope}})) { - push(@{$byresource{$resource}{$rev}{$scope}},$what); - } - } else { - push(@{$byresource{$resource}{$rev}{$scope}},$what); - } - } else { - if (ref($byresource{$resource}{$rev}{$scope}{$which}) eq 'ARRAY') { - unless (grep(/^\Q$what\E$/,@{$byresource{$resource}{$rev}{$scope}{$which}})) { - push(@{$byresource{$resource}{$rev}{$scope}{$which}},$what); - } - } else { - push(@{$byresource{$resource}{$rev}{$scope}{$which}},$what); - } - } - } + if (ref($Apache::lonrelrequtils::checkparms{$item}) eq 'ARRAY') { + my $value = $resourcedata->{$key}; + if ($item eq 'examcode') { + if (&Apache::lonnet::validCODE($value)) { + $value = 'valid'; + } else { + $value = ''; + } + } elsif ($item eq 'printstartdate') { + if ($value =~ /^\d+$/) { + if ($value > $now) { + $value = 'future'; + } + } + } elsif ($item eq 'printenddate') { + if ($value =~ /^\d+$/) { + if ($value < $now) { + $value = 'past'; + } + } + } + if (grep(/^\Q$value\E$/,@{$Apache::lonrelrequtils::checkparms{$item}})) { + my $stdtype = &Apache::lonparmset::standard_parameter_types($item); + $found{$item}{'valname'} = &get_param_description($stdtype,$value); + $found{$item}{'rev'} = $Apache::lonnet::needsrelease{'parameter:'.$item.':'.$value.':'}; + } + } + } + } + foreach my $item (keys(%Apache::lonrelrequtils::checkparmsmatch)) { + if (ref($Apache::lonrelrequtils::checkparmsmatch{$item}) eq 'ARRAY') { + my $value = $resourcedata->{$key}; + foreach my $valuematch (@{$Apache::lonrelrequtils::checkparmsmatch{$item}}) { + if ($value =~ /$valuematch/) { + my $stdtype = &Apache::lonparmset::standard_parameter_types($item); + $found{$item}{'valname'} = &get_param_description($stdtype,$value,1); + $found{$item}{'rev'} = + $Apache::lonnet::needsrelease{'parameter:'.$item.'::'.$valuematch}; + last; + } + } + } + } + foreach my $item (keys(%found)) { + my $stdname = &Apache::lonparmset::standard_parameter_names($item); + my $rev = $found{$item}{'rev'}; + my $valname = $found{$item}{'valname'}; + my ($middle,$scope,$which,$level,$map,$resource); + my $start = $cid.'.'; + if ($key =~ /^\Q$start\E(\[useropt\:($match_username\:$match_domain)\]\.)/) { + $middle = $1; + $which = $2; + $scope = 'user'; + } elsif ($key =~ /^\Q$start\E(\[(\w+)\]\.)/) { + $middle = $1; + $which = $2; + $scope = 'section/group'; + } else { + $scope = 'all'; + } + my $what="$stdname=$valname"; + if ($key =~ /^\Q$start$middle\E\w+\.\Q$item\E$/) { + $level = 'general'; + if ($scope eq 'all') { + if (ref($fromparam{$rev}{$scope}) eq 'ARRAY') { + unless(grep(/^\Q$what\E$/,@{$fromparam{$rev}{$scope}})) { + push(@{$fromparam{$rev}{$scope}},$what); + } + } else { + push(@{$fromparam{$rev}{$scope}},$what); + } + } else { + if (ref($fromparam{$rev}{$scope}{$which}) eq 'ARRAY') { + unless (grep(/^\Q$what\E$/,@{$fromparam{$rev}{$scope}{$which}})) { + push(@{$fromparam{$rev}{$scope}{$which}},$what); + } + } else { + push(@{$fromparam{$rev}{$scope}{$which}},$what); + } + } + $rowspan{$rev} ++; + } elsif ($key =~ /^\Q$start$middle\E(.+)___\(all\).\w+\.\Q$item\E$/) { + $level = 'folder'; + $map = $1; + if ($scope eq 'all') { + if (ref($bymap{$map}{$rev}{$scope}) eq 'ARRAY') { + unless(grep(/^\Q$what\E$/,@{$bymap{$map}{$rev}{$scope}})) { + push(@{$bymap{$map}{$rev}{$scope}},$what); + } + } else { + push(@{$bymap{$map}{$rev}{$scope}},$what); + } + } else { + if (ref($bymap{$map}{$rev}{$scope}{$which}) eq 'ARRAY') { + unless(grep(/^\Q$what\E$/,@{$bymap{$map}{$rev}{$scope}{$which}})) { + push(@{$bymap{$map}{$rev}{$scope}{$which}},$what); + } + } else { + push(@{$bymap{$map}{$rev}{$scope}{$which}},$what); + } + } + } elsif ($key =~ /^\Q$start$middle\E(.+)\.\w+\.\Q$item\E$/) { + $level = 'resource'; + $resource = $1; + if ($scope eq 'all') { + if (ref($byresource{$resource}{$rev}{$scope}) eq 'ARRAY') { + unless(grep(/^\Q$what\E$/,@{$byresource{$resource}{$rev}{$scope}})) { + push(@{$byresource{$resource}{$rev}{$scope}},$what); + } + } else { + push(@{$byresource{$resource}{$rev}{$scope}},$what); + } + } else { + if (ref($byresource{$resource}{$rev}{$scope}{$which}) eq 'ARRAY') { + unless (grep(/^\Q$what\E$/,@{$byresource{$resource}{$rev}{$scope}{$which}})) { + push(@{$byresource{$resource}{$rev}{$scope}{$which}},$what); + } + } else { + push(@{$byresource{$resource}{$rev}{$scope}{$which}},$what); } } } @@ -2512,7 +2751,7 @@ sub display_loncaparev_constraints { if (ref($fromblocks{$type}) eq 'HASH') { foreach my $rev (keys(%{$fromblocks{$type}})) { my ($major,$minor) = split(/\./,$rev); - ($reqdmajor,$reqdminor) = + ($reqdmajor,$reqdminor) = &Apache::lonrelrequtils::update_reqd_loncaparev($major,$minor,$reqdmajor,$reqdminor); $output .= &Apache::loncommon::start_data_table_row(). ''.$rev.''.$lt{$type}.''; @@ -2592,7 +2831,7 @@ sub display_loncaparev_constraints { &Apache::lonrelrequtils::update_reqd_loncaparev($major,$minor, $reqdmajor,$reqdminor); $checkedrev{$key} = 1; - } + } push(@{$byresponsetype{$symb}{$rev}},$key); $allmaps{$enclosing_map} = 1; } @@ -2611,9 +2850,9 @@ sub display_loncaparev_constraints { } foreach my $map (keys(%allmaps)) { my $mapres = $navmap->getResourceByUrl($map); - my $mapsymb = $mapres->symb(); - $toshow{$mapsymb} = 1; if (ref($mapres)) { + my $mapsymb = $mapres->symb(); + $toshow{$mapsymb} = 1; my $pcslist = $mapres->map_hierarchy(); if ($pcslist ne '') { foreach my $pc (split(/,/,$pcslist)) { @@ -2836,18 +3075,52 @@ sub releases_by_map { } sub get_param_description { - my ($stdtype,$value) = @_; - my $name = $value; - my $paramstrings = &Apache::lonparmset::standard_string_options($stdtype); - unless (ref($paramstrings) eq 'ARRAY') { - return $name; + my ($stdtype,$value,$regexp) = @_; + my ($name,$parammatches,$paramstrings,@possibles); + $paramstrings = &Apache::lonparmset::standard_string_options($stdtype); + if ($regexp) { + $parammatches = &Apache::lonparmset::standard_string_matches($stdtype); + if (ref($parammatches) eq 'ARRAY') { + @possibles = @{$parammatches}; + } else { + undef($regexp); + $name = $value; + } } - foreach my $possibilities (@{$paramstrings}) { + unless ($regexp) { + $name = $value; + if (ref($paramstrings) eq 'ARRAY') { + @possibles = @{$paramstrings}; + } else { + return $name; + } + } + foreach my $possibilities (@possibles) { next unless (ref($possibilities) eq 'ARRAY'); - my ($thing, $description) = @{ $possibilities }; - if ($thing eq $value) { - $name = $description; - last; + my $gotregexmatch = ''; + if ($regexp) { + last if ($gotregexmatch); + my ($item,$pattern) = @{ $possibilities }; + if ($value =~ /$pattern/) { + if (ref($paramstrings) eq 'ARRAY') { + foreach my $possibles (@{$paramstrings}) { + next unless (ref($possibles) eq 'ARRAY'); + my ($thing,$description) = @{$possibles}; + if ($thing eq $item) { + $name = $description; + $gotregexmatch = 1; + last; + } + } + last if ($gotregexmatch); + } + } + } else { + my ($thing,$description) = @{ $possibilities }; + if ($thing eq $value) { + $name = $description; + last; + } } } return $name; @@ -3019,7 +3292,7 @@ sub print_localization { $count ++; my $colspan; unless ($item eq 'languages') { - $colspan = 2; + $colspan = 2; } $datatable .= &item_table_row_start($items{$item}{text},$count,undef,$colspan); if ($item eq 'timezone') { @@ -3139,8 +3412,8 @@ sub print_feedback { } if ($position eq 'top') { my $includeempty = 0; - $datatable .= ''. - &user_table($cdom,$item,\@sections, + $datatable .= ''. + &user_table($cdom,$item,\@sections, $settings->{$item},\%lt); } else { $datatable .= &Apache::lonhtmlcommon::textbox($item.'.text', @@ -3329,15 +3602,15 @@ sub print_discussion { my $colspan; if ($item eq 'allow_limited_html_in_feedback') { $colspan = 2; - } + } $datatable .= &item_table_row_start($items{$item}{text},$count,undef,$colspan); if ($item eq 'plc.roles.denied') { $datatable .= ''. ''.&role_checkboxes($cdom,$cnum,$item,$settings). '
'; } elsif ($item eq 'plc.users.denied') { - $datatable .= ''. - &user_table($cdom,$item,undef, + $datatable .= ''. + &user_table($cdom,$item,undef, $settings->{$item},\%lt); } elsif ($item eq 'pch.roles.denied') { $datatable .= ''. @@ -3366,7 +3639,7 @@ sub print_discussion { ''.&mt('font-size').''. ''.&mt('font-weight').''. ''.&mt('font-style').''. - ''.&mt('Other css').''. + ''.&mt('Other css').''. &Apache::loncommon::end_data_table_row(). &set_discussion_fonts($cdom,$cnum,$item,$settings). &Apache::loncommon::end_data_table().'
'; @@ -3538,7 +3811,7 @@ sub set_discussion_fonts { sub discussion_vote_classes { my $classorder = ['twoplus','oneplus','zero','oneminus','twominus']; - my %classtitles = &Apache::lonlocal::texthash( + my %classtitles = &Apache::lonlocal::texthash( 'twoplus' => 'Two sigma above mean', 'oneplus' => 'One sigma above mean', 'zero' => 'Within one sigma of mean', @@ -3604,7 +3877,7 @@ sub print_classlists { 'defaultcredits' => { text => ''.&mt($itemtext->{'defaultcredits'}).'', }, - + 'nothideprivileged' => { text => ''.&mt($itemtext->{'nothideprivileged'}).'', input => 'checkbox', @@ -3684,6 +3957,14 @@ sub print_appearance { input => 'textbox', size => 40, }, + 'uselcmath' => { + text => ''.&mt($itemtext->{'uselcmath'}).'', + input => 'radio', + }, + 'usejsme' => { + text => ''.&mt($itemtext->{'usejsme'}).'', + input => 'radio', + }, ); return &make_item_rows($cdom,\%items,$ordered,$settings,$rowtotal,$crstype,'appearance'); } @@ -3700,11 +3981,12 @@ sub print_grading { input => 'selectbox', options => { standard => &mt('Standard: shows points'), + categories => &mt('Categories: shows points according to categories'), external => &mt('External: shows number of completed parts and totals'), externalnototals => &mt('External: shows only number of completed parts'), spreadsheet => &mt('Spreadsheet: (with link to detailed scores)'), }, - order => ['standard','external','externalnototals','spreadsheet'], + order => ['standard','categories','external','externalnototals','spreadsheet'], }, 'rndseed' => { text => ''.&mt($itemtext->{'rndseed'}).''. @@ -3945,20 +4227,30 @@ sub item_table_row_end { } sub yesno_radio { - my ($item,$settings) = @_; + my ($item,$settings,$unsetdefault,$valueyes,$valueno) = @_; my $itemon = ' '; my $itemoff = ' checked="checked" '; + if (($valueyes eq '') && ($valueno eq '')) { + $valueyes = 'yes'; + $valueno = ''; + } if (ref($settings) eq 'HASH') { - if ($settings->{$item} eq 'yes') { + if ($settings->{$item} eq $valueyes) { $itemon = $itemoff; $itemoff = ' '; } + unless (exists($settings->{$item})) { + if ($unsetdefault eq $valueyes) { + $itemon = $itemoff; + $itemoff = ' '; + } + } } return ' '. + $itemon.' value="'.$valueyes.'" />'.&mt('Yes').' '. ''; + $itemoff.' value="'.$valueno.'" />'.&mt('No').'
'; } sub select_from_options { @@ -4043,7 +4335,16 @@ sub make_item_rows { &Apache::lonhtmlcommon::date_setter('display',$item, $settings->{$item}); } elsif ($items->{$item}{input} eq 'radio') { - $datatable .= &yesno_radio($item,$settings); + my ($unsetdefault,$valueyes,$valueno); + if (($item eq 'usejsme') || ($item eq 'uselcmath')) { + my %domdefs = &Apache::lonnet::get_domain_defaults($cdom); + unless ($domdefs{$item} eq '0') { + $unsetdefault = 1; + } + $valueyes = "1"; + $valueno = "0"; + } + $datatable .= &yesno_radio($item,$settings,$unsetdefault,$valueyes,$valueno); } elsif ($items->{$item}{input} eq 'selectbox') { my $curr = $settings->{$item}; $datatable .= @@ -4079,7 +4380,7 @@ sub nothidepriv_row { } } if ($settings->{'checkforpriv'}) { - @checkdoms = split(/,/,$settings->{'checkforpriv'}); + @checkdoms = split(/,/,$settings->{'checkforpriv'}); } } push(@checkdoms,$cdom); @@ -4093,7 +4394,7 @@ sub nothidepriv_row { if ($end == -1 || $start == -1) { next; } - foreach my $dom (@checkdoms) { + foreach my $dom (@checkdoms) { if (&Apache::lonnet::privileged($uname,$udom,\@checkdoms,['dc','su'])) { unless (grep(/^\Q$user\E$/,@privusers)) { push(@privusers,$user); @@ -4119,7 +4420,8 @@ sub nothidepriv_row { ' '. - ''. + '
'. ''; } $datatable .= ''; @@ -4159,7 +4461,7 @@ sub checkforpriv_row { my $domdesc = &Apache::lonnet::domain($currdom,'description'); if ($domdesc eq '') { $domdesc = $currdom; - } + } $datatable .= &Apache::loncommon::start_data_table_row(). ''. @@ -4171,13 +4473,13 @@ sub checkforpriv_row { &mt('Delete').''. &Apache::loncommon::end_data_table_row(); $num ++; - unless (grep(/^\Q$currdom\E$/,@excdoms)) { + unless (grep(/^\Q$currdom\E$/,@excdoms)) { push(@excdoms,$currdom); } } } if ((scalar(keys(%domains)) - scalar(@excdoms)) > 0) { - $datatable .= + $datatable .= &Apache::loncommon::start_data_table_row(). ''. &mt('Additional domain:'). '
'. @@ -4372,17 +4674,19 @@ sub change_clone { foreach my $currclone (@allowclone) { if (!grep(/^$currclone$/,@$oldcloner)) { if ($currclone ne '*') { - my ($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; + if ($currclone =~ /:/) { + my ($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); } } } @@ -4392,24 +4696,26 @@ sub change_clone { foreach my $oldclone (@$oldcloner) { if (!grep(/^\Q$oldclone\E$/,@allowclone)) { if ($oldclone ne '*') { - my ($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.','; + if ($oldclone =~ /:/) { + my ($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); } } }