--- loncom/interface/courseprefs.pm 2024/02/25 05:53:47 1.49.2.28.2.20 +++ loncom/interface/courseprefs.pm 2023/12/13 22:12:17 1.128 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # Handler to set configuration settings for a course # -# $Id: courseprefs.pm,v 1.49.2.28.2.20 2024/02/25 05:53:47 raeburn Exp $ +# $Id: courseprefs.pm,v 1.128 2023/12/13 22:12:17 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -372,12 +372,6 @@ sub handler { my %values=&Apache::lonnet::dump('environment',$cdom,$cnum); my %linkprot=&Apache::lonnet::dump('lti',$cdom,$cnum,undef,undef,undef,1); - my %domdefs = &Apache::lonnet::get_domain_defaults($cdom); - unless ($phase eq 'process') { - if (ref($domdefs{'linkprotsuggested'}) eq 'HASH') { - $values{'suggested'} = $domdefs{'linkprotsuggested'}; - } - } my %ltienc = &Apache::lonnet::dump('nohist_ltienc',$cdom,$cnum,undef,undef,undef,1); my %ltitools = &Apache::lonnet::dump('ltitools',$cdom,$cnum,undef,undef,undef,1); my %ltitoolsenc = &Apache::lonnet::dump('nohist_toolsenc',$cdom,$cnum,undef,undef,undef,1); @@ -418,7 +412,7 @@ sub handler { my @prefs_order = ('courseinfo','localization','feedback','discussion', 'classlists','appearance','grading','printouts', 'menuitems','ltitools','linkprot','spreadsheet', - 'bridgetasks','other'); + 'bridgetasks','lti','other'); my %prefs = ( 'courseinfo' => { text => $lt{'gens'}, @@ -469,6 +463,7 @@ sub handler { { text => 'Discussion and Chat', help => 'Course_Prefs_Discussions', ordered => ['pch.roles.denied','pch.users.denied', + 'pac.roles.denied','pac.users.denied', 'plc.roles.denied','plc.users.denied', 'allow_limited_html_in_feedback', 'allow_discussion_post_editing', @@ -478,6 +473,8 @@ sub handler { 'pch.users.denied' => 'No Resource Discussion', 'plc.roles.denied' => 'No Chat room use', 'plc.users.denied' => 'No Chat room use', + 'pac.roles.denied' => 'No Anonymous Resource Discussion', + 'pac.users.denied' => 'No Anonymous Resource Discussion', allow_limited_html_in_feedback => 'Allow limited HTML in discussion', allow_discussion_post_editing => 'Users can edit/delete own discussion posts', discussion_post_fonts => 'Discussion post fonts based on likes/unlikes', @@ -546,7 +543,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', @@ -580,6 +577,18 @@ sub handler { suppress_embed_prompt => 'Hide upload references prompt if uploading file to portfolio', }, }, + 'lti' => + { + text => 'LTI provider settings', + help => 'Course_Prefs_LTIProvider', + ordered => ['lti.override','lti.topmenu','lti.inlinemenu','lti.lcmenu'], + itemtext => { + 'lti.override' => 'Override domain defaults', + 'lti.topmenu' => 'Display LON-CAPA page header', + 'lti.inlinemenu' => 'Display LON-CAPA inline menu', + 'lti.lcmenu' => 'Menu items', + }, + }, 'menuitems' => { text => 'Menu display', @@ -784,38 +793,9 @@ sub print_config_box { '; - if ($action eq 'linkprot') { - if ((ref($settings) eq 'HASH') && (ref($settings->{'suggested'}) eq 'HASH')) { - my $hints; - my $hintcount = 0; - foreach my $key (sort { $a <=> $b } keys(%{$settings->{'suggested'}})) { - if ((ref($settings->{'suggested'}->{$key}) eq 'HASH')) { - if (($settings->{'suggested'}->{$key}-{'name'} ne '') && - ($settings->{'suggested'}->{$key}-{'info'} ne '')) { - my $css_class = $hintcount%2?' class="LC_odd_row"':' class="LC_even_row"'; - $hints .= ''. - ''; - $hintcount ++; - } - } - } - if ($hintcount) { - $output .= ''. - ''. - ''."\n". - ''. - ''. - ''."\n". - $hints; - } - } - } if (exists $item->{'header'}->[0]->{'col1'} || exists $item->{'header'}->[0]->{'col2'}) { - $output .= ' + $output .= ' '; if (($action eq 'courseinfo') || ($action eq 'localization') || @@ -855,6 +835,8 @@ sub print_config_box { $currtools = $settings->{'ltitools'}; } $output .= &print_ltitools($cdom,$cnum,$currtools,\$rowtotal,$crstype,$noedit,'course'); + } elsif ($action eq 'lti') { + $output .= &print_lti($cdom,$settings,$ordered,$itemtext,\$rowtotal,$crstype,$noedit); } elsif ($action eq 'menuitems') { $output .= &print_menuitems('bottom',$cdom,$settings,$itemtext,\$rowtotal,$crstype,$noedit); } elsif ($action eq 'linkprot') { @@ -1295,7 +1277,8 @@ sub process_changes { } } } - } elsif (($entry eq 'plc.roles.denied') || ($entry eq 'pch.roles.denied')) { + } elsif (($entry eq 'plc.roles.denied') || ($entry eq 'pch.roles.denied') || + ($entry eq 'pac.roles.denied')) { my @denied = &Apache::loncommon::get_env_multiple('form.'.$entry); @denied = sort(@denied); my $deniedstr = ''; @@ -1303,7 +1286,8 @@ sub process_changes { $deniedstr = join(',',@denied); } $newvalues{$entry} = $deniedstr; - } elsif (($entry eq 'plc.users.denied') || ($entry eq 'pch.users.denied')) { + } elsif (($entry eq 'plc.users.denied') || ($entry eq 'pch.users.denied') || + ($entry eq 'pac.users.denied')) { my $total = $env{'form.'.$entry.'_total'}; my $userstr = ''; my @denied; @@ -1491,6 +1475,38 @@ sub process_changes { $settings =~ s/,$//; } $newvalues{$entry} = $settings; + } elsif ($action eq 'lti') { + if ($entry eq 'lti.override') { + $newvalues{$entry} = $env{'form.'.$entry}; + } elsif (($entry eq 'lti.topmenu') || ($entry eq 'lti.inlinemenu')) { + if ($env{'form.lti.override'}) { + $newvalues{$entry} = $env{'form.'.$entry}; + } else { + $newvalues{$entry} = ''; + } + } elsif ($entry eq 'lti.lcmenu') { + if (($env{'form.lti.override'}) && + (($env{'form.lti.topmenu'}) || ($env{'form.lti.inlinemenu'}))) { + my @lcmenu = &Apache::loncommon::get_env_multiple('form.lti.lcmenu'); + my @newlcmenu; + if (@lcmenu) { + my @menuitems = ('fullname','coursetitle','role','logout','grades'); + foreach my $item (@menuitems) { + next if (($item eq 'grades') && (!$newvalues{'lti.inlinemenu'})); + if (grep(/^\Q$item\E$/,@lcmenu)) { + push(@newlcmenu,$item); + } + } + } + if (@newlcmenu) { + $newvalues{$entry} = join(',',@newlcmenu); + } else { + $newvalues{$entry} = 'none'; + } + } else { + $newvalues{$entry} = ''; + } + } } elsif ($entry eq 'extresource') { if ($env{'form.'.$entry} =~ /^iframe|tab|window$/) { $newvalues{$entry} = $env{'form.'.$entry}; @@ -2753,6 +2769,22 @@ sub store_changes { } } $displayname = &mt($text); + } elsif ($item eq 'lti') { + if ($key eq 'lti.lcmenu') { + if ($changes->{$item}{$key} eq 'none') { + $displayval = &mt('None of the configurable menu items displayed'); + } else { + my %ltititles = <imenu_titles(); + $displayval = join(', ', map { $ltititles{$_}; } split(/,/,$changes->{$item}{$key})); + } + } else { + if ($changes->{$item}{$key} eq '1') { + $displayval = &mt('Yes'); + } elsif ($changes->{$item}{$key} eq '') { + $displayval = &mt('No'); + } + } + $displayname = &mt($text); } elsif ($item eq 'menuitems') { unless ($changes->{$item}{$key} eq '') { if ($key eq 'menudefault') { @@ -2857,7 +2889,20 @@ sub store_changes { } } elsif ($changes->{$item}{$key} eq '') { push(@delkeys,$key); - if ($item eq 'menuitems') { + if ($item eq 'lti') { + if (($key eq 'lti.override') || (($key ne 'lti.override') && ($env{'form.lti.override'} ne ''))) { + if (($key eq 'lti.lcmenu') && + ((!$env{'form.lti.topmenu'}) && (!$env{'form.lti.inlinemenu'}))) { + $output .= '
  • '.&mt('LTI settings for menu items only saved if page header and/or inline menu is set to be displayed').'
  • '; + } else { + $output .= '
  • '.&Apache::lonhtmlcommon::confirm_success(&mt('[_1] set to [_2]', + ''.$displayname.'', + "'$displayval'")).'
  • '; + } + } elsif (!exists($changes->{$item}{'lti.override'})) { + $output .= '
  • '.&mt('LTI settings only saved if Override is set to "Yes"').'
  • '; + } + } elsif ($item eq 'menuitems') { if ($key eq 'menudefault') { $output .= '
  • '.&mt("Default collection of menu items set to: 'Standard' (all menus shown)").'
  • '; } elsif ($key eq 'menucollections') { @@ -2910,7 +2955,9 @@ sub store_changes { } if (($key eq 'description') || ($key eq 'cloners') || ($key eq 'hidefromcat') || ($key eq 'categories') || - ($key eq 'co-owners')) { + ($key eq 'co-owners') || ($key eq 'lti.override') || + ($key eq 'lti.topmenu') || ($key eq 'lti.inlinemenu') || + ($key eq 'lti.lcmenu')) { push(@need_env_update,$key); } } @@ -3369,6 +3416,8 @@ sub update_env { my @coowners = split(',',$storehash->{'internal.'.$key}); $crsinfo{$env{'request.course.id'}}{'co-owners'} = \@coowners; $count ++; + } elsif ($key =~ /^lti\./) { + &Apache::lonnet::appenv({'course.'.$env{'request.course.id'}.'.'.$key => $storehash->{$key}}); } } if ($count) { @@ -4499,116 +4548,160 @@ sub display_loncaparev_constraints { $Apache::lonrelrequtils::checkcrstypes{$crstype}).''; } my (%fromparam,%rowspan,%bymap,%byresource,@scopeorder,%toshow,%allmaps, - %byresponsetype,%bysubmission,%fromblocks); + %byresponsetype,%bysubmission,%fromblocks,%bycrsrestype); @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 = ''; - } - } elsif ($item eq 'printstartdate') { - if ($value =~ /^\d+$/) { - if ($value > $now) { - $value = 'future'; - } - } - } elsif ($item eq 'printenddate') { - if ($value =~ /^\d+$/) { - if ($value < $now) { - $value = 'past'; - } - } - - } - 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::checkparmvalsmatch)) { + if (ref($Apache::lonrelrequtils::checkparmvalsmatch{$item}) eq 'ARRAY') { + my $value = $resourcedata->{$key}; + foreach my $valuematch (@{$Apache::lonrelrequtils::checkparmvalsmatch{$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(%Apache::lonrelrequtils::checkparmnamesmatch)) { + my $regexp; + if ($item eq 'maplevelrecurse') { + $regexp = '\.(?:sequence|page)___\(rec\)\.'; + } + if ($regexp ne '') { + if ($key =~ /$regexp.*\.(\w+)$/) { + my $name = $1; + my $value = $resourcedata->{$key}; + if ($name eq 'type') { + last unless (($value eq 'problem') || ($value eq 'practice') || ($value eq 'exam') || + ($value eq 'survey') || ($value eq 'surveycred') || ($value eq 'anonsurvey') || + ($value eq 'anonsurveycred') || ($value eq 'randomizetry') || ($value eq 'library')); + } + my $stdtype = &Apache::lonparmset::standard_parameter_types($name); + $found{$name}{'valname'} = &get_param_description($stdtype,$value); + $found{$name}{'extra'} = &mt('Recursive into sub-folders'); + $found{$name}{'rev'} = + $Apache::lonnet::needsrelease{'parameter::::'.$item}; + } + } + } + foreach my $item (keys(%found)) { + my $stdname = &Apache::lonparmset::standard_parameter_names($item); + my $rev = $found{$item}{'rev'}; + my $valname = $found{$item}{'valname'}; + my $extra = $found{$item}{'extra'}; + 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 ($extra) { + $what .= "
    $extra
    "; + } + 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|rec)\).\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); } } } @@ -4726,18 +4819,25 @@ sub display_loncaparev_constraints { if (defined($navmap)) { my %anonsubms=&Apache::lonnet::dump('nohist_anonsurveys',$cdom,$cnum); - my $rev_anonsurv=$Apache::lonnet::needsrelease{'parameter:type:anonsurvey'}; + my $rev_anonsurv=$Apache::lonnet::needsrelease{'parameter:type:anonsurvey::'}; my %randtrysubms=&Apache::lonnet::dump('nohist_randomizetry',$cdom,$cnum); - my $rev_randtry=$Apache::lonnet::needsrelease{'parameter:type:randomizetry'}; + my $rev_randtry=$Apache::lonnet::needsrelease{'parameter:type:randomizetry::'}; + my $rev_exttool=$Apache::lonnet::needsrelease{'course:courserestype:exttool'}; my $stdtype=&Apache::lonparmset::standard_parameter_types('type'); my $stdname=&Apache::lonparmset::standard_parameter_names('type'); my $valanon=&get_param_description($stdtype,'anonsurvey'); my $valrandtry=&get_param_description($stdtype,'randomizetry'); my %checkedrev; - foreach my $res ($navmap->retrieveResources(undef,sub { $_[0]->is_problem() },1,0)) { + foreach my $res ($navmap->retrieveResources(undef,sub { $_[0]->is_problem() || $_[0]->is_tool() },1,0)) { my @parts = @{$res->parts()}; my $symb = $res->symb(); my $enclosing_map = &Apache::lonnet::declutter($res->enclosing_map_src()); + if ($res->is_tool()) { + my $rev = $rev_exttool; + $bycrsrestype{$symb}{$rev} = &mt('External Tool'); + $allmaps{$enclosing_map} = 1; + next; + } foreach my $part (@parts) { if (exists($anonsubms{$symb."\0".$part})) { my $rev = $rev_anonsurv; @@ -4825,6 +4925,7 @@ sub display_loncaparev_constraints { } } } + my $supptools = &Apache::lonnet::count_supptools($cnum,$cdom,1,1); my $mapres_header = '

    '. &mt('Requirements for specific folders or resources'). '

    '; @@ -4839,9 +4940,9 @@ sub display_loncaparev_constraints { $r->print($start_page.$top_header); if ($output) { $r->print($output); - if (defined($navmap)) { + if (defined($navmap) || $supptools) { &show_contents_view($r,$navmap,$cid,\%toshow,\%bymap,\%byresource,\%bysubmission, - \%byresponsetype,\@scopeorder,\%lt); + \%byresponsetype,\%bycrsrestype,\@scopeorder,\%lt,$supptools); } $r->print('

    '); } else { @@ -4859,22 +4960,30 @@ sub display_loncaparev_constraints { sub show_contents_view { my ($r,$navmap,$cid,$toshow,$bymap,$byresource,$bysubmission,$byresponsetype, - $scopeorder,$lt) = @_; - if ((keys(%{$toshow}) > 0) || (keys(%{$byresource}) > 0) || - (keys(%{$bysubmission}) > 0) || (keys(%{$byresponsetype}) > 0)) { - my $location=&Apache::loncommon::lonhttpdurl("/adm/lonIcons"); - my $whitespace = ''; - my $icon = ''; + $bycrsrestype,$scopeorder,$lt,$supptools) = @_; + my $location=&Apache::loncommon::lonhttpdurl("/adm/lonIcons"); + my $whitespace = ''; + my $showmaincontent; + if ((ref($navmap)) && + ((keys(%{$toshow}) > 0) || (keys(%{$byresource}) > 0) || + (keys(%{$bysubmission}) > 0) || (keys(%{$byresponsetype}) > 0) || + (keys(%{$bycrsrestype}) > 0))) { + $showmaincontent = 1; + } + if ($showmaincontent || $supptools) { + $r->print(&Apache::loncommon::start_data_table()); + } + if ($showmaincontent) { + my $icon = ''; my $topmap = $env{'course.'.$cid.'.url'}; - $r->print(&Apache::loncommon::start_data_table(). - &Apache::loncommon::start_data_table_header_row(). + $r->print(&Apache::loncommon::start_data_table_header_row(). ''. ''. &Apache::loncommon::end_data_table_header_row(). &Apache::loncommon::start_data_table_row(). ''); - &releases_by_map($r,$bymap,$topmap,$scopeorder,$lt); - $r->print(&Apache::loncommon::end_data_table_row()); + &releases_by_map($r,$bymap,$topmap,$scopeorder,$lt); + $r->print(&Apache::loncommon::end_data_table_row()); my $it=$navmap->getIterator(undef,undef,undef,1,1,undef); my $curRes; my $depth = 0; @@ -4925,6 +5034,9 @@ sub show_contents_view { if (ref($byresponsetype->{$symb}) eq 'HASH') { $rowspan += scalar(keys(%{$byresponsetype->{$symb}})); } + if (ref($bycrsrestype->{$symb}) eq 'HASH') { + $rowspan += scalar(keys(%{$bycrsrestype->{$symb}})); + } next if (!$rowspan); $icon = ''.
                             &mt('Problem').''; @@ -4989,10 +5101,37 @@ sub show_contents_view { $r->print(''); } $r->print(&Apache::loncommon::end_data_table_row()); + $newrow = 1; + } + if (ref($bycrsrestype->{$symb}) eq 'HASH') { + foreach my $rev (sort(keys(%{$bycrsrestype->{$symb}}))) { + if ($newrow) { + $r->print(&Apache::loncommon::continue_data_table_row()); + } + $r->print(''); + } + $r->print(&Apache::loncommon::end_data_table_row()); } } } } + } + if ($supptools) { + my $icon = ''; + $r->print(&Apache::loncommon::start_data_table_header_row(). + ''. + ''. + &Apache::loncommon::end_data_table_header_row(). + &Apache::loncommon::start_data_table_row(). + ''. + ''. + &Apache::loncommon::end_data_table_row()); + } + if ($showmaincontent || $supptools) { $r->print(&Apache::loncommon::end_data_table()); } return; @@ -5038,18 +5177,67 @@ 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); + if ($stdtype =~ /^string/) { + $paramstrings = &Apache::lonparmset::standard_string_options($stdtype); + } elsif ($stdtype eq 'date_interval') { + $paramstrings = &Apache::lonparmset::standard_interval_options($stdtype); + } + if ($regexp) { + if ($stdtype =~ /^string/) { + $parammatches = &Apache::lonparmset::standard_string_matches($stdtype); + } elsif ($stdtype eq 'date_interval') { + $parammatches = &Apache::lonparmset::standard_interval_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 { + if (($stdtype eq 'date_start') || ($stdtype eq 'date_end')) { + if ($name == 0) { + $name = &mt('Never'); + } elsif (($name ne '') && ($name !~ /\D/)) { + $name = &Apache::lonlocal::locallocaltime($name); + } + } + 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; @@ -5559,6 +5747,20 @@ sub print_discussion { &mt('(specific user(s))'), input => 'checkbox', }, + + 'pac.roles.denied' => { + text => ''.&mt($itemtext->{'pac.roles.denied'}).''. + &Apache::loncommon::help_open_topic("Course_Disable_Anonymous_Discussion").'
    '. + &mt('(role-based)'), + input => 'checkbox', + }, + + 'pac.users.denied' => { + text => ''.&mt($itemtext->{'pac.users.denied'}).'
    '. + &mt('(specific user(s))'), + input => 'checkbox', + }, + 'allow_limited_html_in_feedback' => { text => ''.&mt($itemtext->{'allow_limited_html_in_feedback'}).'', input => 'radio', @@ -5609,6 +5811,14 @@ sub print_discussion { $datatable .= '
    '. - $settings->{'suggested'}->{$key}->{'name'}.'
    '.
    -                                      $settings->{'suggested'}->{$key}->{'info'}.
    -                                      '
    '.&mt('Recommendation(s) for specific launcher application(s)').'
    '.&mt('Launcher Application').''.&mt('Recommendation(s)').'
    '.&mt($item->{'header'}->[0]->{'col1'}).''.&mt('Location').''.&mt('Release').''.&mt('Attribute/Setting').' '.$icon.' '.&mt('Main Content').''.$rev.''.$bycrsrestype->{$symb}{$rev}.''.&mt('Location').''.&mt('Release').''.&mt('Resource Type').' '.$icon.' '.&mt('Supplemental Content').''. + $Apache::lonrelrequtils::exttool{'major'}.'.'. + $Apache::lonrelrequtils::exttool{'minor'}. + ''.&mt('[quant,_1,External Tool,External Tools]', + $supptools).''. &user_table($cdom,$item,undef, $settings->{$item},\%lt,$noedit); + } elsif ($item eq 'pac.roles.denied') { + $datatable .= ''. + ''.&role_checkboxes($cdom,$cnum,$item,$settings,undef,undef,$noedit). + '
    '; + } elsif ($item eq 'pac.users.denied') { + $datatable .= '
    '. + &user_table($cdom,$item,undef, + $settings->{$item},\%lt,$noedit); } elsif ($item eq 'allow_limited_html_in_feedback') { $datatable .= &yesno_radio($item,$settings,undef,undef,undef,$noedit); } elsif ($item eq 'allow_discussion_post_editing') { @@ -5991,15 +6201,16 @@ 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'}).''. - '
    '.'
    '. + '
    '. &mt('Modifying this will make problems have different numbers and answers!'). '', input => 'selectbox', @@ -6712,6 +6923,134 @@ sub ltitools_names { return %lt; } +sub print_lti { + my ($cdom,$settings,$ordered,$itemtext,$rowtotal,$crstype,$noedit) = @_; + unless ((ref($settings) eq 'HASH') && (ref($ordered) eq 'ARRAY') && (ref($itemtext) eq 'HASH')) { + return; + } + my @menuitems = ('fullname','coursetitle','role','logout','grades'); + my %menutitles = <imenu_titles(); + my ($domdefs,$displaydefs); + if ($env{'request.lti.login'}) { + my %lti = &Apache::lonnet::get_domain_lti($cdom,'provider'); + my @domdefsmenu; + if (ref($lti{$env{'request.lti.login'}}) eq 'HASH') { + if ($lti{$env{'request.lti.login'}}{'topmenu'}) { + $domdefs = &mt('Header shown').', '; + } + if ($lti{$env{'request.lti.login'}}{'inlinemenu'}) { + $domdefs .= &mt('Inline menu shown'); + } + $domdefs =~ s/,\s$//; + if (!$domdefs) { + $domdefs = &mt('No header or inline menu shown'); + } + $domdefs = ' ('.&mt('Domain default').': '.$domdefs.')'; + if (ref($lti{$env{'request.lti.login'}}{'lcmenu'}) eq 'ARRAY') { + @domdefsmenu = @{$lti{$env{'request.lti.login'}}{'lcmenu'}}; + } + } + $displaydefs = &mt('Domain defaults'); + if (@domdefsmenu) { + my @diffs = &Apache::loncommon::compare_arrays(\@menuitems,\@domdefsmenu); + if (@diffs) { + my $missing; + foreach my $item (@menuitems) { + unless (grep(/^\Q$item\E$/,@domdefsmenu)) { + $missing .= ' '.$menutitles{$item}.','; + } + } + $missing =~ s/,$//; + $displaydefs .= ': '.&mt('Not shown').' --'.$missing; + } else { + $displaydefs .= ': '.&mt('All shown'); + } + } else { + $displaydefs .= ': '.&mt('Not shown').' -- '.join(', ', map { $menutitles{$_}; } @menuitems); + } + } else { + $displaydefs = &mt('Domain defaults only available in LTI context'); + } + my %items = ( + 'lti.override' => { + text => ''.&mt($itemtext->{'lti.override'}).''.$domdefs, + input => 'radio', + }, + 'lti.topmenu' => { + text => ''.&mt($itemtext->{'lti.topmenu'}).'', + input => 'radio', + }, + 'lti.inlinemenu' => { + text => ''.&mt($itemtext->{'lti.inlinemenu'}).'', + input => 'radio', + }, + 'lti.lcmenu' => { + text => ''.&mt($itemtext->{'lti.lcmenu'}).'
    '.$displaydefs, + input => 'custom', + }, + ); + return &make_item_rows($cdom,\%items,$ordered,$settings,$rowtotal,$crstype,'lti',$noedit); +} + +sub lcmenu_checkboxes { + my ($cdom,$caller,$settings,$crstype,$noedit) = @_; + my @menuitems = ('fullname','coursetitle','role','logout','grades'); + my %menutitles = <imenu_titles(); + my (@current,@domdefs); + if ($env{'request.lti.login'}) { + my %lti = &Apache::lonnet::get_domain_lti($cdom,'provider'); + if (ref($lti{$env{'request.lti.login'}}) eq 'HASH') { + if (ref($lti{$env{'request.lti.login'}}{'lcmenu'}) eq 'ARRAY') { + @domdefs = @{$lti{$env{'request.lti.login'}}{'lcmenu'}}; + } + } + } + if (ref($settings) eq 'HASH') { + if ($settings->{'lti.lcmenu'}) { + unless ($settings->{'lti.lcmenu'} eq 'none') { + @current = split(',',$settings->{'lti.lcmenu'}); + } + } else { + @current = @domdefs; + } + } else { + @current = @domdefs; + } + my $numinrow = 3; + my $count = 0; + my $disabled; + if ($noedit) { + $disabled = ' disabled="disabled"'; + } + my $output = ''; + foreach my $item (@menuitems) { + my $checked = ''; + if (grep(/^\Q$item\E$/,@current)) { + $checked = ' checked="checked" '; + } + my $rem = $count%($numinrow); + if ($rem == 0) { + if ($count > 0) { + $output .= ''; + } + $output .= ''; + } + $output .= ''; + $count ++; + } + my $rem = $count%($numinrow); + my $colsleft = $numinrow - $rem; + if ($colsleft > 1 ) { + $output .= ''; + } elsif ($colsleft == 1) { + $output .= ''; + } + $output .= '
    '. + '  
    '; +} + sub ltimenu_titles { return &Apache::lonlocal::texthash( fullname => 'Full name', @@ -6861,7 +7200,7 @@ sub menuitems_categories { my %categories = ( shown => ['top','inline','foot','main'], text => ['name','role','crs','disc','fdbk'], - links => ['pers','logo','comm','roles','help','logout'], + links => ['pers','logo','menu','comm','roles','help','logout'], list => ['about','prefs','port','wish','anno','rss','srch','brse'], inline => ['cont','grades','chat','people','groups','resv','syll','feeds'], ); @@ -6886,6 +7225,7 @@ sub menuitems_fields { main => 'Access to main menu', pers => 'Personal', logo => 'LON-CAPA', + menu => 'Home', comm => 'Messages', roles => 'Roles/Courses', help => 'Help', @@ -7613,6 +7953,8 @@ sub make_item_rows { $datatable .= &checkforpriv_row($cdom,$item,$settings,$crstype,$noedit); } elsif ($item eq 'print_header_format') { $datatable .= &print_hdrfmt_row($item,$settings,$noedit); + } elsif ($item eq 'lti.lcmenu') { + $datatable .= &lcmenu_checkboxes($cdom,$item,$settings,$crstype,$noedit); } elsif ($item eq 'extresource') { $datatable .= &print_extresource_row($item,$items->{$item},$settings->{$item},$noedit); } elsif ($items->{$item}{input} eq 'dates') { @@ -7632,6 +7974,8 @@ sub make_item_rows { } $valueyes = "1"; $valueno = "0"; + } elsif (($item eq 'lti.topmenu') || ($item eq 'lti.inlinemenu')) { + $valueyes = '1'; } $datatable .= &yesno_radio($item,$settings,$unsetdefault,$valueyes,$valueno,$noedit); } elsif ($items->{$item}{input} eq 'selectbox') {