--- loncom/interface/courseprefs.pm 2022/04/05 16:55:20 1.49.2.28.2.8 +++ loncom/interface/courseprefs.pm 2024/07/06 16:43:10 1.49.2.31 @@ -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.8 2022/04/05 16:55:20 raeburn Exp $ +# $Id: courseprefs.pm,v 1.49.2.31 2024/07/06 16:43:10 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -52,16 +52,12 @@ This module is used for configuration of =item process_changes() -=item process_linkprot() - =item get_sec_str() =item check_clone() =item store_changes() -=item store_linkprot() - =item update_env() =item display_disallowed() @@ -224,7 +220,6 @@ use Apache::lonparmset; use Apache::courseclassifier; use Apache::lonlocal; use LONCAPA qw(:DEFAULT :match); -use Crypt::CBC; my $registered_cleanup; my $modified_courses; @@ -370,29 +365,9 @@ sub handler { } my %values=&Apache::lonnet::dump('environment',$cdom,$cnum); - my %linkprot=&Apache::lonnet::dump('lti',$cdom,$cnum,undef,undef,undef,1); - my %ltienc = &Apache::lonnet::dump('nohist_ltienc',$cdom,$cnum,undef,undef,undef,1); - foreach my $id (keys(%linkprot)) { - if (ref($linkprot{$id}) eq 'HASH') { - if (ref($ltienc{$id}) eq 'HASH') { - $values{'linkprot'}{$id} = { %{$linkprot{$id}}, %{$ltienc{$id}} }; - } else { - $values{'linkprot'}{$id} = $linkprot{$id}; - } - } - unless ($phase eq 'process') { - if (ref($values{'linkprot'}{$id}) eq 'HASH') { - delete($values{'linkprot'}{$id}{'secret'}); - } - } - } - if ($linkprot{'lock'}) { - delete($linkprot{'lock'}); - } my @prefs_order = ('courseinfo','localization','feedback','discussion', 'classlists','appearance','grading','printouts', - 'menuitems','linkprot','spreadsheet','bridgetasks', - 'other'); + 'spreadsheet','bridgetasks','other'); my %prefs = ( 'courseinfo' => @@ -553,29 +528,6 @@ sub handler { suppress_embed_prompt => 'Hide upload references prompt if uploading file to portfolio', }, }, - 'menuitems' => - { - text => 'Menu display', - help => 'Course_Prefs_Menus', - header => [{col1 => 'Default Menu', - col2 => 'Value',}, - {col1 => 'Menu collections', - col2 => 'Settings', - }], - ordered => ['menudefault','menucollections'], - itemtext => { - menudefault => 'Choose default collection of menu items for course', - menucollections => 'Menu collections', - }, - }, - 'linkprot' => - { - text => 'Link protection', - help => 'Course_Prefs_Linkprotection', - header => [{col1 => 'Item', - col2 => 'Settings', - }], - }, 'other' => { text => 'Other settings', help => 'Course_Prefs_Other', @@ -586,14 +538,10 @@ sub handler { ); if (($phase eq 'process') && ($parm_permission->{'process'})) { my @allitems = &get_allitems(%prefs); - my $result = &Apache::lonconfigsettings::make_changes($r,$cdom,$phase,$context, - \@prefs_order,\%prefs,\%values, - $cnum,undef,\@allitems, - 'coursepref',$parm_permission); - if ((ref($result) eq 'HASH') && (keys(%{$result}))) { - $r->rflush(); - &devalidate_remote_courseprefs($cdom,$cnum,$result); - } + &Apache::lonconfigsettings::make_changes($r,$cdom,$phase,$context, + \@prefs_order,\%prefs,\%values, + $cnum,undef,\@allitems, + 'coursepref',$parm_permission); } elsif (($phase eq 'display') && ($parm_permission->{'display'})) { my $noedit; if (ref($parm_permission) eq 'HASH') { @@ -678,7 +626,7 @@ sub print_config_box { } $output .= '</span></th>'."\n". '</tr>'; - if (($action eq 'feedback') || ($action eq 'classlists') || ($action eq 'menuitems')) { + if (($action eq 'feedback') || ($action eq 'classlists')) { $output .= ' <tr> <td> @@ -703,8 +651,6 @@ sub print_config_box { $output .= &print_feedback('top',$cdom,$settings,$ordered,$itemtext,\$rowtotal,$noedit); } elsif ($action eq 'classlists') { $output .= &print_classlists('top',$cdom,$settings,$itemtext,\$rowtotal,$crstype,$noedit); - } elsif ($action eq 'menuitems') { - $output .= &print_menuitems('top',$cdom,$settings,$itemtext,\$rowtotal,$crstype,$noedit); } $output .= ' </table> @@ -776,17 +722,13 @@ sub print_config_box { } elsif ($action eq 'appearance') { $output .= &print_appearance($cdom,$settings,$ordered,$itemtext,\$rowtotal,$crstype,$noedit); } elsif ($action eq 'grading') { - $output .= &print_grading($cdom,$settings,$ordered,$itemtext,\$rowtotal,$crstype,$noedit); + $output .= &print_grading($cdom,$cnum,$settings,$ordered,$itemtext,\$rowtotal,$crstype,$noedit); } elsif ($action eq 'printouts') { $output .= &print_printouts($cdom,$settings,$ordered,$itemtext,\$rowtotal,$crstype,$noedit); } elsif ($action eq 'spreadsheet') { $output .= &print_spreadsheet($cdom,$settings,$ordered,$itemtext,\$rowtotal,$crstype,$noedit); } elsif ($action eq 'bridgetasks') { $output .= &print_bridgetasks($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') { - $output .= &print_linkprotection($cdom,$cnum,$settings,\$rowtotal,$crstype,$noedit,'course'); } elsif ($action eq 'other') { $output .= &print_other($cdom,$settings,$allitems,\$rowtotal,$crstype,$noedit); } @@ -799,8 +741,8 @@ sub print_config_box { } sub process_changes { - my ($cdom,$cnum,$action,$values,$item,$changes,$allitems,$disallowed,$crstype,$lastactref) = @_; - my (%newvalues,$errors); + my ($cdom,$action,$values,$item,$changes,$allitems,$disallowed,$crstype) = @_; + my %newvalues; if (ref($item) eq 'HASH') { if (ref($changes) eq 'HASH') { my @ordered; @@ -817,18 +759,6 @@ sub process_changes { } } } - } elsif ($action eq 'linkprot') { - if (ref($values->{$action}) eq 'HASH') { - foreach my $id (keys(%{$values->{$action}})) { - if ($id =~ /^\d+$/) { - push(@ordered,$id); - } - } - } - @ordered = sort { $a <=> $b } @ordered; - if (($env{'form.linkprot_add'}) && ($env{'form.linkprot_maxnum'} =~ /^\d+$/)) { - push(@ordered,$env{'form.linkprot_maxnum'}); - } } elsif (ref($item->{'ordered'}) eq 'ARRAY') { if ($action eq 'courseinfo') { my ($can_toggle_cat,$can_categorize) = @@ -891,85 +821,6 @@ sub process_changes { $changes->{$ext_entry} = $newvalues{$ext_entry}; } } - } elsif ($action eq 'menuitems') { - my (%current,@colls); - my $next = 1; - if ($values->{'menucollections'}) { - foreach my $item (split(/;/,$values->{'menucollections'})) { - my ($num,$value) = split(/\%/,$item); - if ($num =~ /^\d+$/) { - unless (grep(/^$num$/,@colls)) { - push(@colls,$num); - } - my @entries = split(/\&/,$value); - foreach my $entry (@entries) { - my ($name,$fields) = split(/=/,$entry); - $current{$num}{$name} = $fields; - } - } - } - } - if (@colls) { - @colls = sort { $a <=> $b } @colls; - $next += $colls[-1]; - } - if ($env{'form.menucollections_add'} eq $next) { - push(@colls,$next); - } - my $currdef = $values->{'menudefault'}; - my $possdef = $env{'form.menudefault'}; - if (($possdef =~ /^\d+$/) && (grep(/^$possdef$/,@colls))) { - if ($currdef ne $possdef) { - $changes->{'menudefault'} = $possdef; - } - } elsif ($currdef) { - $changes->{'menudefault'} = ''; - } - my $menucoll; - if (@colls) { - my ($ordered,$cats) = &menuitems_categories(); - my %shortcats = &menuitems_abbreviations(); - foreach my $num (@colls) { - my ($entry,%include); - map { $include{$_}= 1; } &Apache::loncommon::get_env_multiple('form.menucollections_'.$num); - foreach my $item (@{$ordered}) { - if ($item eq 'shown') { - foreach my $type (@{$cats->{$item}}) { - $entry .= $type.'='; - if ($include{$type}) { - $entry .= 'y'; - } else { - $entry .= 'n'; - } - $entry .= '&'; - } - } else { - $entry .= $shortcats{$item}.'='; - foreach my $type (@{$cats->{$item}}) { - if ($include{$type}) { - $entry .= $type.','; - } - } - $entry =~ s/,$//; - $entry .= '&'; - } - } - $entry =~ s/\&$//; - if ($menucoll) { - $menucoll .= ';'; - } - $menucoll .= $num.'%'.$entry; - } - if ($menucoll ne $values->{'menucollections'}) { - $changes->{'menucollections'} = $menucoll; - } - } elsif ($values->{'menucollections'}) { - $changes->{'menucollections'} = ''; - } - } elsif ($action eq 'linkprot') { - if (ref($values) eq 'HASH') { - $errors = &process_linkprot($cdom,$cnum,$values->{$action},$changes,'course',$lastactref); - } } else { foreach my $entry (@ordered) { if ($entry eq 'cloners') { @@ -1010,7 +861,7 @@ sub process_changes { my $clonedom = $env{'form.cloners_newdom'}; if (&check_clone($clonedom,$disallowed) eq 'ok') { my $newdom = '*:'.$env{'form.cloners_newdom'}; - if (@clonedoms) { + if (@clonedoms) { if (!grep(/^\Q$newdom\E$/,@clonedoms)) { $newvalues{$entry} .= ','.$newdom; } @@ -1413,6 +1264,33 @@ sub process_changes { $settings =~ s/,$//; } $newvalues{$entry} = $settings; + } elsif ($entry eq 'grading') { + if ($env{'form.'.$entry} eq 'standard') { + if ($env{'form.hidetotals'}) { + my %sections = &Apache::loncommon::get_sections($cdom,$cnum); + if (keys(%sections)) { + my @secs = &Apache::loncommon::get_env_multiple('form.hidetotals_sections'); + if (grep(/^all$/,@secs)) { + $newvalues{'hidetotals'} = 'all'; + } elsif (@secs) { + $newvalues{'hidetotals'} = ''; + foreach my $sec (sort {$a <=> $b} @secs) { + if (exists($sections{$sec})) { + $newvalues{'hidetotals'} .= $sec.',' + } + } + $newvalues{'hidetotals'} =~ s/,$//; + } + } else { + $newvalues{'hidetotals'} = 'all'; + } + } + } + if ($newvalues{'hidetotals'} ne $values->{'hidetotals'}) { + $changes->{'hidetotals'} = $newvalues{'hidetotals'}; + $changes->{'grading'} = $env{'form.'.$entry}; + } + $newvalues{$entry} = $env{'form.'.$entry}; } else { $newvalues{$entry} = $env{'form.'.$entry}; } @@ -1426,279 +1304,7 @@ sub process_changes { } } } - return $errors; -} - -sub process_linkprot { - my ($cdom,$cnum,$values,$changes,$context,$lastactref) = @_; - my ($home,$dest,$ltiauth,$privkey,$privnum,$cipher,$errors,%linkprot); - if (ref($values) eq 'HASH') { - foreach my $id (keys(%{$values})) { - if ($id =~ /^\d+$/) { - unless (ref($values->{$id}) eq 'HASH') { - $linkprot{$id} = ''; - } - } - } - } - my %domdefs = &Apache::lonnet::get_domain_defaults($cdom); - my @ids=&Apache::lonnet::current_machine_ids(); - if ($context eq 'domain') { - $home = &Apache::lonnet::domain($cdom,'primary'); - } else { - $home = &Apache::lonnet::homeserver($cnum,$cdom); - } - if ((($context eq 'domain') && ($domdefs{'linkprotenc_dom'})) || - (($context eq 'course') && ($domdefs{'linkprotenc_crs'}))) { - unless (($home eq 'no_host') || ($home eq '')) { - if (grep(/^\Q$home\E$/,@ids)) { - if (ref($domdefs{'privhosts'}) eq 'ARRAY') { - if (grep(/^\Q$home\E$/,@{$domdefs{'privhosts'}})) { - my %privhash = &Apache::lonnet::restore_dom('lti','private',$cdom,$home,1); - $privkey = $privhash{'key'}; - $privnum = $privhash{'version'}; - if (($privnum) && ($privkey ne '')) { - $cipher = Crypt::CBC->new({'key' => $privkey, - 'cipher' => 'DES'}); - } - } - } - } - } - } - if ($context eq 'domain') { - $dest = '/adm/domainprefs'; - $ltiauth = 1; - } else { - $dest = '/adm/courseprefs'; - if (exists($env{'course.'.$env{'request.course.id'}.'.internal.ltiauth'})) { - $ltiauth = $env{'course.'.$env{'request.course.id'}.'.internal.ltiauth'}; - } else { - my %domdefs = &Apache::lonnet::get_domain_defaults($cdom); - $ltiauth = $domdefs{'crsltiauth'}; - } - } - my $switchserver = &check_switchserver($cdom,$cnum,$context,$dest); - my (@items,%deletions,%itemids,%haschanges); - if ($env{'form.linkprot_add'}) { - my $name = $env{'form.linkprot_name_add'}; - $name =~ s/(`)/'/g; - my ($newid,$error) = &get_linkprot_id($cdom,$cnum,$name,$context); - if ($newid) { - $itemids{'add'} = $newid; - push(@items,'add'); - $haschanges{$newid} = 1; - } else { - $errors .= '<span class="LC_error">'. - &mt('Failed to acquire unique ID for link protection'). - '</span>'; - } - } - if (ref($values) eq 'HASH') { - my @todelete = &Apache::loncommon::get_env_multiple('form.linkprot_del'); - my $maxnum = $env{'form.linkprot_maxnum'}; - for (my $i=0; $i<=$maxnum; $i++) { - my $itemid = $env{'form.linkprot_id_'.$i}; - $itemid =~ s/\D+//g; - if ($itemid) { - if (ref($values->{$itemid}) eq 'HASH') { - push(@items,$i); - $itemids{$i} = $itemid; - if ((@todelete > 0) && (grep(/^$i$/,@todelete))) { - $deletions{$itemid} = $values->{$itemid}->{'name'}; - } - } - } - } - } - foreach my $idx (@items) { - my $itemid = $itemids{$idx}; - next unless ($itemid); - if (exists($deletions{$itemid})) { - $linkprot{$itemid} = $deletions{$itemid}; - $haschanges{$itemid} = 1; - next; - } - my %current; - if (ref($values) eq 'HASH') { - if (ref($values->{$itemid}) eq 'HASH') { - foreach my $key (keys(%{$values->{$itemid}})) { - $current{$key} = $values->{$itemid}->{$key}; - } - } - } - foreach my $inner ('name','lifetime','version') { - my $formitem = 'form.linkprot_'.$inner.'_'.$idx; - $env{$formitem} =~ s/(`)/'/g; - if ($inner eq 'lifetime') { - $env{$formitem} =~ s/[^\d.]//g; - } - unless ($idx eq 'add') { - if ($current{$inner} ne $env{$formitem}) { - $haschanges{$itemid} = 1; - } - } - if ($env{$formitem} ne '') { - $linkprot{$itemid}{$inner} = $env{$formitem}; - } - } - if ($ltiauth) { - my $reqitem = 'form.linkprot_requser_'.$idx; - $env{$reqitem} =~ s/(`)/'/g; - unless ($idx eq 'add') { - if ((!$current{'requser'} && $env{$reqitem}) || - ($current{'requser'} && !$env{$reqitem})) { - $haschanges{$itemid} = 1; - } - } - if ($env{$reqitem} == 1) { - $linkprot{$itemid}{'requser'} = $env{$reqitem}; - foreach my $inner ('mapuser','notstudent') { - my $formitem = 'form.linkprot_'.$inner.'_'.$idx; - $env{$formitem} =~ s/(`)/'/g; - if ($inner eq 'mapuser') { - if ($env{$formitem} eq 'other') { - my $mapuser = $env{'form.linkprot_customuser_'.$idx}; - $mapuser =~ s/(`)/'/g; - $mapuser =~ s/^\s+|\s+$//g; - if ($mapuser ne '') { - $linkprot{$itemid}{$inner} = $mapuser; - } else { - delete($linkprot{$itemid}{'requser'}); - last; - } - } elsif ($env{$formitem} eq 'sourcedid') { - $linkprot{$itemid}{$inner} = 'lis_person_sourcedid'; - } elsif ($env{$formitem} eq 'email') { - $linkprot{$itemid}{$inner} = 'lis_person_contact_email_primary'; - } - } else { - $linkprot{$itemid}{$inner} = $env{$formitem}; - } - unless ($idx eq 'add') { - if ($current{$inner} ne $linkprot{$itemid}{$inner}) { - $haschanges{$itemid} = 1; - } - } - } - } - } - unless ($switchserver) { - my $keyitem = 'form.linkprot_key_'.$idx; - $env{$keyitem} =~ s/(`)/'/g; - unless ($idx eq 'add') { - if ($current{'key'} ne $env{$keyitem}) { - $haschanges{$itemid} = 1; - } - } - if ($env{$keyitem} ne '') { - $linkprot{$itemid}{'key'} = $env{$keyitem}; - } - my $secretitem = 'form.linkprot_secret_'.$idx; - $env{$secretitem} =~ s/(`)/'/g; - if ($current{'usable'}) { - if ($env{'form.linkprot_changesecret_'.$idx}) { - if ($env{$secretitem} ne '') { - if ($privnum && $cipher) { - $linkprot{$itemid}{'secret'} = $cipher->encrypt_hex($env{$secretitem}); - $linkprot{$itemid}{'cipher'} = $privnum; - } else { - $linkprot{$itemid}{'secret'} = $env{$secretitem}; - } - $haschanges{$itemid} = 1; - } - } else { - $linkprot{$itemid}{'secret'} = $current{'secret'}; - } - } elsif ($env{$secretitem} ne '') { - if ($privnum && $cipher) { - $linkprot{$itemid}{'secret'} = $cipher->encrypt_hex($env{$secretitem}); - $linkprot{$itemid}{'cipher'} = $privnum; - } else { - $linkprot{$itemid}{'secret'} = $env{$secretitem}; - } - $haschanges{$itemid} = 1; - } - } - } - if (keys(%haschanges)) { - foreach my $entry (keys(%haschanges)) { - $changes->{$entry} = $linkprot{$entry}; - } - if (ref($lastactref) eq 'HASH') { - $lastactref->{'courselti'} = 1'; - } - } - return $errors; -} - -sub get_linkprot_id { - my ($cdom,$cnum,$name,$context) = @_; - # get lock on lti db in course or linkprot db in domain - my $lockhash = { - lock => $env{'user.name'}. - ':'.$env{'user.domain'}, - }; - my $tries = 0; - my $gotlock; - if ($context eq 'domain') { - $gotlock = &Apache::lonnet::newput_dom('linkprot',$lockhash,$cdom); - } else { - $gotlock = &Apache::lonnet::newput('lti',$lockhash,$cdom,$cnum); - } - my ($id,$error); - while (($gotlock ne 'ok') && ($tries<10)) { - $tries ++; - sleep (0.1); - if ($context eq 'domain') { - $gotlock = &Apache::lonnet::newput_dom('linkprot',$lockhash,$cdom); - } else { - $gotlock = &Apache::lonnet::newput('lti',$lockhash,$cdom,$cnum); - } - } - if ($gotlock eq 'ok') { - my %currids; - if ($context eq 'domain') { - %currids = &Apache::lonnet::dump_dom('linkprot',$cdom); - } else { - %currids = &Apache::lonnet::dump('lti',$cdom,$cnum,undef,undef,undef,1); - } - if ($currids{'lock'}) { - delete($currids{'lock'}); - if (keys(%currids)) { - my @curr = sort { $a <=> $b } keys(%currids); - if ($curr[-1] =~ /^\d+$/) { - $id = 1 + $curr[-1]; - } else { - $id = 1; - } - } else { - $id = 1; - } - if ($id) { - if ($context eq 'domain') { - unless (&Apache::lonnet::newput_dom('linkprot',{ $id => $name },$cdom) eq 'ok') { - $error = 'nostore'; - } - } else { - unless (&Apache::lonnet::newput('lti',{ $id => $name },$cdom,$cnum) eq 'ok') { - $error = 'nostore'; - } - } - } else { - $error = 'nonumber'; - } - } - my $dellockoutcome; - if ($context eq 'domain') { - $dellockoutcome = &Apache::lonnet::del_dom('linkprot',['lock'],$cdom); - } else { - $dellockoutcome = &Apache::lonnet::del('lti',['lock'],$cdom,$cnum); - } - } else { - $error = 'nolock'; - } - return ($id,$error); + return; } sub get_sec_str { @@ -1743,12 +1349,8 @@ sub check_clone { sub store_changes { my ($cdom,$cnum,$prefs_order,$actions,$prefs,$values,$changes,$crstype) = @_; my ($chome,$output); - my (%storehash,@delkeys,@need_env_update,@oldcloner,%oldlinkprot); + my (%storehash,@delkeys,@need_env_update,@oldcloner); if ((ref($values) eq 'HASH') && (ref($changes) eq 'HASH')) { - if (ref($values->{'linkprot'}) eq 'HASH') { - %oldlinkprot = %{$values->{'linkprot'}}; - } - delete($values->{'linkprot'}); %storehash = %{$values}; } else { if ($crstype eq 'Community') { @@ -1758,20 +1360,6 @@ sub store_changes { } return $output; } - my ($numchanges,$skipstore); - if (ref($changes) eq 'HASH') { - $numchanges = scalar(keys(%{$changes})); - if (($numchanges == 1) && (exists($changes->{'linkprot'}))) { - $skipstore = 1; - } elsif (!$numchanges) { - if ($crstype eq 'Community') { - $output = &mt('No changes made to community settings.'); - } else { - $output = &mt('No changes made to course settings.'); - } - return $output; - } - } my %yesno = ( hidefromcat => '1', problem_stream_switch => '1', @@ -1797,8 +1385,6 @@ sub store_changes { "'$storehash{$key}'")).'</li>'; } } - } elsif ($item eq 'linkprot') { - $output .= &store_linkprot($cdom,$cnum,'course',$changes->{$item},\%oldlinkprot); } else { if (ref($prefs->{$item}->{'ordered'}) eq 'ARRAY') { my @settings = @{$prefs->{$item}->{'ordered'}}; @@ -1838,6 +1424,40 @@ sub store_changes { unless (($key eq 'co-owners') || ($key eq 'discussion_post_fonts')) { $displayval = $changes->{$item}{$key}; } + if (($item eq 'grading') && ($key eq 'grading')) { + if ($displayval eq 'standard') { + my $hidetotals; + if (exists($changes->{$item}{'hidetotals'})) { + if ($changes->{$item}{'hidetotals'} eq '') { + if (exists($values->{'hidetotals'})) { + push(@delkeys,'hidetotals'); + } + } else { + $hidetotals = $changes->{$item}{'hidetotals'}; + } + } elsif (exists($values->{'hidetotals'})) { + $hidetotals = $values->{'hidetotals'}; + } + if ($hidetotals eq '') { + $displayval = &mt('standard with "hide course totals" set to "No"'); + if (exists($values->{'hidetotals'})) { + push(@delkeys,'hidetotals'); + } + } elsif ($hidetotals =~ /^([\w,]+)$/) { + my $secstr = $1; + my @secs = split(/,/,$secstr); + if (grep(/^all$/,@secs)) { + $displayval = &mt('standard with "hide course totals" set to "Yes" for all users'); + $hidetotals = 'all'; + } else { + $displayval = &mt('standard with "hide course totals" set to "Yes" for users in section(s): [_1]',join(', ',@secs)); + } + $storehash{'hidetotals'} = $hidetotals; + } + } elsif (exists($values->{'hidetotals'})) { + push(@delkeys,'hidetotals'); + } + } if ($item eq 'feedback') { if ($key =~ /^(question|policy|comment)(\.email)\.text$/) { $text = $prefs->{$item}->{'itemtext'}{$1.$2}; @@ -1915,16 +1535,6 @@ sub store_changes { } } $displayname = &mt($text); - } elsif ($item eq 'menuitems') { - unless ($changes->{$item}{$key} eq '') { - if ($key eq 'menudefault') { - $displayname = &mt('Default collection of menu items'); - $displayval = &mt('Collection: [_1]', - $changes->{$item}{$key}); - } elsif ($key eq 'menucollections') { - $displayval = &menucollections_display($changes->{$item}{$key}); - } - } } else { $displayname = &mt($text); } @@ -1988,19 +1598,8 @@ sub store_changes { } } elsif ($changes->{$item}{$key} eq '') { push(@delkeys,$key); - if ($item eq 'menuitems') { - if ($key eq 'menudefault') { - $output .= '<li>'.&mt("Default collection of menu items set to: 'Standard' (all menus shown)").'</li>'; - } elsif ($key eq 'menucollections') { - $output .= '<li>'.&mt('Specific collections of menus no longer available').'</li>'; - } - } else { - $output .= '<li>'.&Apache::lonhtmlcommon::confirm_success(&mt('Deleted setting for [_1]', - '<i>'.$displayname.'</i>')).'</li>'; - } - } elsif ($key eq 'menucollections') { - $output .= '<li>'.&Apache::lonhtmlcommon::confirm_success(&mt('Numbered menu collections:')).'<br />'. - $displayval.'</li>'; + $output .= '<li>'.&Apache::lonhtmlcommon::confirm_success(&mt('Deleted setting for [_1]', + '<i>'.$displayname.'</i>')).'</li>'; } else { $output .= '<li>'.&Apache::lonhtmlcommon::confirm_success(&mt('[_1] set to [_2]', '<i>'.$displayname.'</i>', @@ -2056,9 +1655,6 @@ sub store_changes { } } } - if ($skipstore) { - return $output; - } if (&Apache::lonnet::put('environment',\%storehash,$cdom,$cnum) eq 'ok') { if (ref($changes) eq 'HASH') { if (ref($changes->{'courseinfo'}) eq 'HASH') { @@ -2101,160 +1697,6 @@ sub store_changes { return $output; } -sub store_linkprot { - my ($cdom,$cnum,$context,$changes,$oldlinkprot) = @_; - my ($ltiauth,$home,$lti_save_error,$output,$error,%ltienc,@deletions); - if ($context eq 'domain') { - $ltiauth = 1; - $home = &Apache::lonnet::domain($cdom,'primary'); - } else { - $home = &Apache::lonnet::homeserver($cnum,$cdom); - if (exists($env{'course.'.$env{'request.course.id'}.'.internal.ltiauth'})) { - $ltiauth = $env{'course.'.$env{'request.course.id'}.'.internal.ltiauth'}; - } else { - my %domdefs = &Apache::lonnet::get_domain_defaults($cdom); - $ltiauth = $domdefs{'crsltiauth'}; - } - } - if (ref($changes) eq 'HASH') { - foreach my $id (sort { $a <=> $b } keys(%{$changes})) { - if (ref($changes->{$id}) eq 'HASH') { - if (exists($changes->{$id}->{'key'})) { - $ltienc{$id}{'key'} = $changes->{$id}->{'key'}; - delete($changes->{$id}->{'key'}); - } - if (exists($changes->{$id}->{'secret'})) { - $ltienc{$id}{'secret'} = $changes->{$id}->{'secret'}; - delete($changes->{$id}->{'secret'}); - } elsif (ref($oldlinkprot->{$id}) eq 'HASH') { - if (exists($oldlinkprot->{$id}{'usable'})) { - $changes->{$id}->{'usable'} = 1; - } - if (exists($oldlinkprot->{$id}{'cipher'})) { - $changes->{$id}->{'cipher'} = $oldlinkprot->{$id}{'cipher'}; - } - } - } - } - } - my @ids=&Apache::lonnet::current_machine_ids(); - if (keys(%ltienc) > 0) { - if ($context eq 'domain') { - foreach my $id (keys(%ltienc)) { - if (exists($ltienc{$id}{'secret'})) { - $changes->{$id}->{'usable'} = 1; - } - } - } else { - unless (($home eq 'no_host') || ($home eq '')) { - my $allowed; - foreach my $id (@ids) { if ($id eq $home) { $allowed=1; } } - if ($allowed) { - if (&Apache::lonnet::put('nohist_ltienc',\%ltienc,$cdom,$cnum,1) eq 'ok') { - foreach my $id (keys(%ltienc)) { - if (exists($ltienc{$id}{'secret'})) { - $changes->{$id}->{'usable'} = 1; - } - } - } else { - $lti_save_error = 1; - } - } - } - } - } - unless ($lti_save_error) { - if ($context eq 'course') { - if (&Apache::lonnet::put('lti',$changes,$cdom,$cnum,1) eq 'ok') { - my $hashid=$cdom.'_'.$cnum; - &Apache::lonnet::devalidate_cache_new('courselti',$hashid); - unless (($home eq 'no_host') || ($home eq '')) { - if (grep(/^\Q$home\E$/,@ids)) { - &Apache::lonnet::devalidate_cache_new('courseltienc',$hashid); - } - } - } else { - $lti_save_error = 1; - } - } - unless ($lti_save_error) { - foreach my $id (sort { $a <=> $b } %{$changes}) { - if (ref($changes->{$id}) eq 'HASH') { - my %values = %{$changes->{$id}}; - my %desc = &linkprot_names(); - my $display; - foreach my $title ('name','lifetime','version','key','secret') { - if (($title eq 'key') || ($title eq 'secret')) { - if (ref($ltienc{$id}) eq 'HASH') { - if (exists($ltienc{$id}{$title})) { - if ($title eq 'secret') { - my $length = length($ltienc{$id}{$title}); - $display .= $desc{$title}.': ['.&mt('not shown').'], '; - } else { - $display .= $desc{$title}.': '.$ltienc{$id}{$title}.', '; - } - } - } - } elsif ($title eq 'version') { - if ($values{$title} eq 'LTI-1p0') { - $display .= $desc{$title}.': 1.1, '; - } - } else { - $display .= $desc{$title}.': '.$values{$title}.', '; - } - } - if ($ltiauth) { - if (($values{'requser'}) && ($values{'mapuser'} ne '')) { - if ($values{'mapuser'} eq 'lis_person_contact_email_primary') { - $display .= &mt('Source of username: Email address [_1]', - '(lis_person_contact_email_primary)').', '; - } elsif ($values{'mapuser'} eq 'lis_person_sourcedid') { - $display .= &mt('Source of username: User ID [_1]', - '(lis_person_sourcedid)').', '; - } else { - $display .= &mt('Source of username: [_1]',$values{'mapuser'}).', '; - } - if ($values{'notstudent'} eq 'auth') { - $display .= &mt('Display LON-CAPA login page if no match').', '; - } elsif ($values{'notstudent'} eq 'reject') { - $display .= &mt('Discontinue launch if no match').', '; - } - } - } - $display =~ s/, $//; - $output .= '<li>'.&Apache::lonhtmlcommon::confirm_success(&mt('[_1] set to [_2]','<i>'.$id.'</i>', - "'$display'")).'</li>'; - } elsif (ref($oldlinkprot->{$id}) eq 'HASH') { - my $oldname = $oldlinkprot->{$id}{'name'}; - $output .= '<li>'.&Apache::lonhtmlcommon::confirm_success(&mt('Deleted setting for [_1]','<i>'."$id ($oldname)".'</i>')).'</li>'; - } - } - } else { - $lti_save_error = 1; - } - } - unless ($lti_save_error) { - foreach my $id (sort { $a <=> $b } keys(%{$changes})) { - unless (ref($changes->{$id}) eq 'HASH') { - push(@deletions,$id); - } - } - if (@deletions) { - if ($context eq 'course') { - &Apache::lonnet::del('nohist_ltienc',\@deletions,$cdom,$cnum); - } - } - } - if ($lti_save_error) { - $output .= '<li>'. - '<span class="LC_error">'. - &mt('An error occurred when saving changes to link protection settings, which remain unchanged.'). - '</span>'. - '</li>'; - } - return $output; -} - sub update_env { my ($cnum,$cdom,$chome,$need_env_update,$storehash) = @_; my $count = 0; @@ -2509,86 +1951,48 @@ function syllabusinfo() { } } ENDSCRIPT - my $menuitems_js; + my $grading_js; unless ($noedit) { - my $collections; - my $next = 1; - if (ref($settings) eq 'HASH') { - if ($settings->{'menucollections'} ne '') { - my @current; - foreach my $item (split(/;/,$settings->{'menucollections'})) { - my ($num) = split(/\%/,$item); - if ($num =~ /^\d+$/) { - push(@current,$num); - } - } - $collections = join("','",sort { $a <=> $b } @current); - if ($collections) { - $collections = "'$collections'"; - } - $next += $current[-1]; - } - } - my $deftext = &mt('Standard (all menus shown)'); - $menuitems_js = <<ENDSCRIPT; -function toggleAddmenucoll() { - if (document.getElementById('menucollections_add')) { - var state = 'none'; - var add = document.getElementById('menucollections_add').checked; - if (add) { - state = 'inline-block'; - } - var fieldsets = new Array('shown','text','links','list','inline'); - for (var i=0; i<fieldsets.length; i++) { - if (document.getElementById('addmenucoll_'+fieldsets[i])) { - document.getElementById('addmenucoll_'+fieldsets[i]).style.display = state; - } - } - var box = document.getElementsByClassName('LC_menucoll_add'); - if (box.length) { - for (var i=0; i<box.length; i++) { - if (add) { - box[i].checked = true; - } else { - box[i].checked = false; - } - } - } - if (document.getElementById('menudefault')) { - var menudef = document.getElementById('menudefault'); - var currsel = menudef.selectedIndex; - var colls = new Array($collections); - menudef.options.length = 0; - if (!add) { - if (currsel == 1 + colls.length) { - currsel = 0; - } - } - if (currsel == 0) { - menudef.options[0] = new Option('$deftext','',true,true); + $grading_js = <<"ENDSCRIPT"; +function toggleGrading(form) { + if (document.getElementById('hidetotalsdiv')) { + var totalsdivid = document.getElementById('hidetotalsdiv'); + var selname = form.elements['grading']; + if (selname) { + var current = selname.options[selname.selectedIndex].value + if (current == 'standard') { + totalsdivid.style.display = 'inline-block'; } else { - menudef.options[0] = new Option('$deftext','',false,false); + totalsdivid.style.display = 'none'; } - if (colls.length) { - for (var i=0; i<colls.length; i++) { - var idx = i+1; - if (currsel == colls[i]) { - menudef.options[idx] = new Option(colls[i],colls[i],true,true); - } else { - menudef.options[idx] = new Option(colls[i],colls[i],false,false); + } + } + return; +} + +function toggleHiddenTotalsSec(form) { + if (document.getElementById('sectotalsdiv')) { + var sectotalsdivid = document.getElementById('sectotalsdiv'); + var radioname = form.elements['hidetotals']; + if (radioname) { + if (radioname.length > 0) { + var setvis; + for (var i=0; i<radioname.length; i++) { + if (radioname[i].checked == true) { + if (radioname[i].value == 1) { + sectotalsdivid.style.display = 'inline-block'; + setvis = 1; + } + break; } } - } - if (add) { - var addidx = 1 + colls.length; - if (currsel == addidx) { - menudef.options[addidx] = new Option('$next','$next',true,true); - } else { - menudef.options[addidx] = new Option('$next','$next',false,false); + if (!setvis) { + sectotalsdivid.style.display = 'none'; } } } } + return; } ENDSCRIPT } @@ -2596,8 +2000,7 @@ ENDSCRIPT '// <![CDATA['."\n". $browse_js."\n".$categorize_js."\n".$loncaparev_js."\n". $cloners_js."\n".$instcode_js. - $syllabus_js."\n".$menuitems_js."\n". - &linkprot_javascript()."\n".'//]]>'."\n". + $syllabus_js."\n".$grading_js."\n".'//]]>'."\n". '</script>'."\n".$stubrowse_js."\n"; return $jscript; } @@ -2683,78 +2086,6 @@ function getIndexByName(item) { ENDSCRIPT } -sub linkprot_javascript { - return <<"ENDSCRIPT"; -function toggleLinkProt(form,num,item) { - var radioname = ''; - var currdivid = ''; - var newdivid = ''; - if ((document.getElementById('linkprot_divcurr'+item+'_'+num)) && - (document.getElementById('linkprot_divchg'+item+'_'+num))) { - currdivid = document.getElementById('linkprot_divcurr'+item+'_'+num); - newdivid = document.getElementById('linkprot_divchg'+item+'_'+num); - radioname = form.elements['linkprot_change'+item+'_'+num]; - if (radioname) { - if (radioname.length > 0) { - var setvis; - for (var i=0; i<radioname.length; i++) { - if (radioname[i].checked == true) { - if (radioname[i].value == 1) { - newdivid.style.display = 'inline-block'; - currdivid.style.display = 'none'; - setvis = 1; - } - break; - } - } - if (!setvis) { - newdivid.style.display = 'none'; - currdivid.style.display = 'inline-block'; - } - } - } - } - return; -} - -function toggleLinkProtReqUser(form,item,extra,valon,styleon,num) { - if (document.getElementById('linkprot_'+extra+'_'+num)) { - var extraid = document.getElementById('linkprot_'+extra+'_'+num); - var itemname = form.elements['linkprot_'+item+'_'+num]; - if (itemname) { - if (itemname.length > 0) { - var setvis; - for (var i=0; i<itemname.length; i++) { - if (itemname[i].checked == true) { - if (itemname[i].value == valon) { - extraid.style.display = styleon; - setvis = 1; - } - break; - } - } - if (!setvis) { - extraid.style.display = 'none'; - } - } - } - } - return; -} - -function uncheckLinkProtMakeVis(item,num) { - if (document.getElementById('linkprot_'+item+'_'+num)) { - var currtype = document.getElementById('linkprot_'+item+'_'+num).type; - if (currtype.toLowerCase() == 'checkbox') { - document.getElementById('linkprot_'+item+'_'+num).checked = false; - } - } - return; -} -ENDSCRIPT - -} - sub print_courseinfo { my ($cdom,$settings,$ordered,$itemtext,$rowtotal,$crstype,$noedit) = @_; @@ -4335,7 +3666,7 @@ sub select_recipient { } sub select_sections { - my ($item,$num,$sections,$selected,$noedit) = @_; + my ($item,$num,$sections,$selected,$noedit,$allval) = @_; my ($output,@currsecs,$allsec,$disabled); if (ref($selected) eq 'ARRAY') { @currsecs = @{$selected}; @@ -4351,16 +3682,24 @@ sub select_sections { my $mult; if (@{$sections} > 1) { $mult = ' multiple="multiple"'; + my $size; if (@{$sections} > 3) { - $mult .= ' size="4"'; + $size = 4; + } else { + $size = 1 + scalar(@{$sections}); } + $mult .= ' size="'.$size.'"'; + } + my $name = $item.'_sections'; + unless ($item eq 'hidetotals') { + $name .= '_'.$num; } - $output = '<select name="'.$item.'_sections_'.$num.'"'.$mult.$disabled.'>'. - ' <option value=""'.$allsec.'>'.&mt('All').'</option>'; + $output = '<select name="'.$name.'"'.$mult.$disabled.'>'. + ' <option value="'.$allval.'"'.$allsec.'>'.&mt('All').'</option>'; foreach my $sec (@{$sections}) { my $is_sel; if ((@currsecs) && (grep(/^\Q$sec\E$/,@currsecs))) { - $is_sel = 'selected="selected"'; + $is_sel = ' selected="selected"'; } $output .= '<option value="'.$sec.'"'.$is_sel.'>'.$sec.'</option>'; } @@ -4812,7 +4151,7 @@ sub print_appearance { } sub print_grading { - my ($cdom,$settings,$ordered,$itemtext,$rowtotal,$crstype,$noedit) = @_; + my ($cdom,$cnum,$settings,$ordered,$itemtext,$rowtotal,$crstype,$noedit) = @_; unless ((ref($settings) eq 'HASH') && (ref($ordered) eq 'ARRAY') && (ref($itemtext) eq 'HASH')) { return; } @@ -4831,7 +4170,7 @@ sub print_grading { }, 'rndseed' => { text => '<b>'.&mt($itemtext->{'rndseed'}).'</b>'. - '<span class="LC_warning">'.'<br />'. + '<br /><span class="LC_warning LC_nobreak">'. &mt('Modifying this will make problems have different numbers and answers!'). '</span>', input => 'selectbox', @@ -4863,7 +4202,7 @@ sub print_grading { input => 'radio', }, ); - return &make_item_rows($cdom,\%items,$ordered,$settings,$rowtotal,$crstype,'grading',$noedit); + return &make_item_rows($cdom,\%items,$ordered,$settings,$rowtotal,$crstype,'grading',$noedit,$cnum); } sub print_printouts { @@ -4997,572 +4336,6 @@ sub print_bridgetasks { return &make_item_rows($cdom,\%items,$ordered,$settings,$rowtotal,$crstype,'bridgetasks',$noedit); } -sub ltimenu_titles { - return &Apache::lonlocal::texthash( - fullname => 'Full name', - coursetitle => 'Course title', - role => 'Role', - logout => 'Logout', - grades => 'Grades', - ); -} - -sub print_menuitems { - my ($position,$cdom,$settings,$itemtext,$rowtotal,$crstype,$noedit) = @_; - unless ((ref($settings) eq 'HASH') && (ref($itemtext) eq 'HASH')) { - return; - } - if ($position eq 'top') { - my (%defaultmenu_options,@defaultmenu_order,$addcollection); - if ($settings->{'menucollections'} ne '') { - foreach my $item (split(/;/,$settings->{'menucollections'})) { - my ($num,$value) = split(/\%/,$item); - if ($num =~ /^\d+$/) { - $defaultmenu_options{$num} = $num; - } - } - @defaultmenu_order = sort { $a <=> $b } keys(%defaultmenu_options); - $addcollection = $defaultmenu_order[-1] + 1; - } else { - $addcollection = 1; - } - $defaultmenu_options{$addcollection} = $addcollection; - my %items = ( - 'menudefault' => { - text => '<b>'.&mt($itemtext->{'menudefault'}).'</b><br />'. - &mt("(can be overriden in deep-link context)"), - input => 'selectbox', - options => \%defaultmenu_options, - order => \@defaultmenu_order, - nullval => &mt('Standard (all menus shown)'), - }, - ); - return &make_item_rows($cdom,\%items,['menudefault'],$settings,$rowtotal,$crstype,'menuitems',$noedit); - } else { - my %menu; - my $count = 0; - my $next = 1; - my ($datatable,$disabled); - if ($noedit) { - $disabled = ' disabled="disabled"'; - } - - my ($ordered,$cats) = &menuitems_categories(); - my @order = @{$ordered}; - my %categories = %{$cats}; - my %menutitles = &menuitems_titles(); - my %menufields = &menuitems_fields(); - - if ($settings->{'menucollections'} ne '') { - foreach my $item (split(/;/,$settings->{'menucollections'})) { - my ($num,$value) = split(/\%/,$item); - if ($num =~ /^\d+$/) { - my @entries = split(/\&/,$value); - foreach my $entry (@entries) { - my ($name,$fields) = split(/=/,$entry); - $menu{$num}{$name} = $fields; - } - } - } - if (keys(%menu)) { - my @current = sort { $a <=> $b } keys(%menu); - $next += $current[-1]; - foreach my $num (@current) { - my %checked; - my $on = ' checked="checked"'; - foreach my $key (keys(%{$menu{$num}})) { - if (($key eq 'top') || ($key eq 'inline') || ($key eq 'foot') || ($key eq 'main')) { - if ($menu{$num}{$key} eq 'y') { - $checked{$key} = $on; - } - } else { - foreach my $field (split(/,/,$menu{$num}{$key})) { - if (exists($menufields{$field})) { - $checked{$field} = $on; - } - } - } - } - if (ref($menu{$num}) eq 'HASH') { - $datatable .= &item_table_row_start('<em class="LC_nav_bar">'.$num.'</em>',$count,'','','','LC_left_item'); - foreach my $category (@order) { - if ((ref($categories{$category}) eq 'ARRAY') && (@{$categories{$category}} > 0)) { - $datatable .= '<fieldset style="vertical-align:top; display:inline-block"><legend>'.$menutitles{$category}.'</legend>'."\n"; - if ($category eq 'text') { - $datatable .= '<i>'.&mt('Header').'</i><br />'; - } - foreach my $field (@{$categories{$category}}) { - if ($field eq 'disc') { - $datatable .= '<br /><i>'.&mt('Footer').'</i><br />'; - } - $datatable .= '<label><input type="checkbox" name="menucollections_'.$num.'" value="'.$field.'"'.$checked{$field}.$disabled.' />'. - $menufields{$field}.'</label><br />'; - } - $datatable .= '</fieldset>'; - } - } - $datatable .= &item_table_row_end(); - $count ++; - } - } - } - } elsif ($noedit) { - my $text = &mt('No menu collections defined for this course.'); - $datatable .= &item_table_row_start($text,$count); - } - unless ($noedit) { - my $add = '<label><input type="checkbox" name="menucollections_add" id="menucollections_add" value="'.$next.'" '. - 'onclick="javascript:toggleAddmenucoll();" />'.&mt('Add').'</label>'; - $datatable .= &item_table_row_start($add,$count,'','','','LC_left_item'); - foreach my $category (@order) { - if ((ref($categories{$category}) eq 'ARRAY') && (@{$categories{$category}} > 0)) { - $datatable .= '<fieldset id="addmenucoll_'.$category.'" style="display:none; vertical-align:top;"><legend>'.$menutitles{$category}.'</legend>'."\n"; - foreach my $field (@{$categories{$category}}) { - $datatable .= '<label><input type="checkbox" class="LC_menucoll_add" name="menucollections_'.$next.'" value="'.$field.'"'.$disabled.' />'. - $menufields{$field}.'</label><br />'; - } - $datatable .= '</fieldset>'; - } - } - $datatable .= &item_table_row_end(); - $count ++; - } - return $datatable; - } -} - -sub menuitems_abbreviations { - my %briefcats = ( - text => 'pt', - links => 'p', - list => 'ps', - inline => 's', - ); - return %briefcats; -} - -sub menuitems_categories { - my @order = ('shown','text','links','list','inline'); - my %categories = ( - shown => ['top','inline','foot','main'], - text => ['name','role','crs','disc','fdbk'], - links => ['pers','logo','comm','roles','help','logout'], - list => ['about','prefs','port','wish','anno','rss'], - inline => ['cont','grades','chat','people','groups','resv','syll','feeds'], - ); - return (\@order,\%categories); -} - -sub menuitems_titles { - return &Apache::lonlocal::texthash ( - shown => 'Hierarchy', - text => 'Text', - links => 'Header links', - list => 'Drop-down list', - inline => 'Inline links', - ); -} - -sub menuitems_fields { - return &Apache::lonlocal::texthash ( - top => 'Display header', - inline => 'Display inline menu', - foot => 'Display footer', - main => 'Access to main menu', - pers => 'Personal', - logo => 'LON-CAPA', - comm => 'Messages', - roles => 'Roles/Courses', - help => 'Help', - logout => 'Logout', - name => 'Fullname', - crs => 'Course Title', - role => 'Current Role', - disc => 'Discussion', - fdbk => 'Feedback', - about => 'Information', - prefs => 'Preferences', - port => 'Portfolio', - wish => 'Stored Links', - anno => 'Calendar', - rss => 'RSS Feeds', - cont => 'Contents', - grades => 'Grades', - chat => 'Chat', - people => 'People', - groups => 'Groups', - resv => 'Reservations', - syll => 'Syllabus', - feeds => 'Feeds', - ); -} - -sub menucollections_display { - my ($collections) = @_; - my %menu; - my ($ordered,$cats) = &menuitems_categories(); - my @order = @{$ordered}; - my %categories = %{$cats}; - my %menutitles = &menuitems_titles(); - my %menufields = &menuitems_fields(); - foreach my $item (split(/;/,$collections)) { - my ($num,$value) = split(/\%/,$item); - if ($num =~ /^\d+$/) { - my @entries = split(/\&/,$value); - foreach my $entry (@entries) { - my ($name,$fields) = split(/=/,$entry); - $menu{$num}{$name} = $fields; - } - } - } - my $output = ''; - if (keys(%menu)) { - my @current = sort { $a <=> $b } keys(%menu); - foreach my $num (@current) { - my %checked; - foreach my $key (keys(%{$menu{$num}})) { - if (($key eq 'top') || ($key eq 'inline') || ($key eq 'foot') || ($key eq 'main')) { - if ($menu{$num}{$key} eq 'y') { - $checked{$key} = 1; - } - } else { - foreach my $field (split(/,/,$menu{$num}{$key})) { - if (exists($menufields{$field})) { - $checked{$field} = 1; - } - } - } - } - if (ref($menu{$num}) eq 'HASH') { - $output .= '<fieldset><legend>'.&mt('Collection [_1]',$num).'</legend>'; - foreach my $category (@order) { - if ((ref($categories{$category}) eq 'ARRAY') && (@{$categories{$category}} > 0)) { - $output .= '<fieldset style="vertical-align:top; display:inline-block">'. - '<legend>'.$menutitles{$category}.'</legend>'."\n"; - if ($category eq 'text') { - $output .= '<b>'.&mt('Header Text').'</b><br /><br />'; - } - foreach my $field (@{$categories{$category}}) { - if ($field eq 'disc') { - $output .= '<br /><b>'.&mt('Footer Text').'</b><br /><br />'; - } - if ($checked{$field}) { - $output .= &Apache::lonhtmlcommon::confirm_success($menufields{$field}); - } else { - $output .= &Apache::lonhtmlcommon::confirm_success($menufields{$field},1); - } - $output .= '<br />'; - } - $output .= '</fieldset>'; - } - } - $output .= '</fieldset>'; - } - } - } - return $output; -} - -sub print_linkprotection { - my ($cdom,$cnum,$settings,$rowtotal,$crstype,$noedit,$context) = @_; - - my %linkprotection; - my $count = 0; - my $next = 1; - my ($datatable,$disabled,$css_class,$dest); - if ($noedit) { - $disabled = ' disabled="disabled"'; - } - my %desc = &linkprot_names(); - my %lt = &Apache::lonlocal::texthash ( - 'requ' => 'Required settings', - 'opti' => 'Optional settings', - ); - my $itemcount = 0; - - my $ltiauth; - if ($context eq 'domain') { - $ltiauth = 1; - } else { - if (exists($env{'course.'.$env{'request.course.id'}.'.internal.ltiauth'})) { - $ltiauth = $env{'course.'.$env{'request.course.id'}.'.internal.ltiauth'}; - } else { - my %domdefs = &Apache::lonnet::get_domain_defaults($cdom); - $ltiauth = $domdefs{'crsltiauth'}; - } - } - if ($context eq 'domain') { - $dest = '/adm/domainprefs'; - } else { - $dest = '/adm/courseprefs'; - } - - my ($switchserver,$switchmessage); - $switchserver = &check_switchserver($cdom,$cnum,$context,$dest); - if ($switchserver) { - if ($context eq 'domain') { - $switchmessage = &mt("submit from domain's primary library server: [_1].",$switchserver); - } elsif ($crstype eq 'Community') { - $switchmessage = &mt("submit from community's home server: [_1].",$switchserver); - } else { - $switchmessage = &mt("submit from course's home server: [_1].",$switchserver); - } - } - - if ((ref($settings) eq 'HASH') && (ref($settings->{'linkprot'}) eq 'HASH')) { - if (keys(%{$settings->{'linkprot'}})) { - my @current = sort { $a <=> $b } keys(%{$settings->{'linkprot'}}); - $next += $current[-1]; - for (my $i=0; $i<@current; $i++) { - my $num = $current[$i]; - my %values; - if (ref($settings->{'linkprot'}->{$num}) eq 'HASH') { - %values = %{$settings->{'linkprot'}->{$num}}; - } else { - next; - } - my $selected; - if (($values{'version'} eq 'LTI-1p0') || ($values{'version'} eq '')) { - $selected = ' selected="selected"'; - } - $css_class = $itemcount%2?' class="LC_odd_row"':''; - $datatable .= - '<tr '.$css_class.'><td><span class="LC_nobreak">'. - '<label><input type="checkbox" name="linkprot_del" value="'.$i.'"'.$disabled.' />'. - &mt('Delete?').'</label></span></td><td>'; - my ($usersty,$onclickrequser,%checkedrequser); - if ($ltiauth) { - $usersty = 'display:none'; - $onclickrequser = ' onclick="toggleLinkProtReqUser(this.form,'."'requser','optional','1','block','$i'".');"'; - %checkedrequser = ( - no => ' checked="checked"', - yes => '', - ); - if ($values{'requser'}) { - $checkedrequser{'yes'} = $checkedrequser{'no'}; - $checkedrequser{'no'} = ''; - } - $datatable .= '<fieldset><legend>'.$lt{'requ'}.'</legend>'; - if ($values{'requser'}) { - $usersty = 'display:inline-block'; - } - } - $datatable .= - '<span class="LC_nobreak">'.$desc{'name'}. - ':<input type="text" size="15" name="linkprot_name_'.$i.'" value="'.$values{'name'}.'" autocomplete="off"'.$disabled.' /></span> '. - (' 'x2). - '<span class="LC_nobreak">'.$desc{'version'}.':<select name="linkprot_version_'.$i.'"'.$disabled.'>'. - '<option value="LTI-1p0" '.$selected.'>1.1</option></select></span> '."\n". - (' 'x2). - '<span class="LC_nobreak">'.$desc{'lifetime'}.':<input type="text" name="linkprot_lifetime_'.$i.'"'. - ' value="'.$values{'lifetime'}.'" size="3"'.$disabled.' /></span>'; - if ($ltiauth) { - $datatable .= (' 'x2).'<span class="LC_nobreak">'.$desc{'requser'}.'?'. - '<label><input type="radio" name="linkprot_requser_'.$i.'" value="0"'. - $onclickrequser.$checkedrequser{'no'}.$disabled.' />'.&mt('No').'</label> '. - '<label><input type="radio" name="linkprot_requser_'.$i.'" value="1"'. - $onclickrequser.$checkedrequser{'yes'}.$disabled.' />'.&mt('Yes').'</label></span>'; - } - $datatable .= '<br /><br />'; - if ($values{'key'} ne '') { - $datatable .= '<span class="LC_nobreak">'.$desc{'key'}; - if ($noedit) { - $datatable .= ': ['.&mt('not shown').']'; - } elsif ($switchserver) { - $datatable .= ': ['.&mt('[_1] to view/edit',$switchserver).']'; - } else { - $datatable .= ':<input type="text" size="25" name="linkprot_key_'.$i.'" value="'.$values{'key'}.'" autocomplete="off"'.$disabled.' />'; - } - $datatable .= '</span> '.(' 'x2); - } elsif (!$switchserver) { - $datatable .= '<span class="LC_nobreak">'.$desc{'key'}.':'. - '<input type="text" size="25" name="linkprot_key_'.$i.'" value="'.$values{'key'}.'" autocomplete="off"'.$disabled.' />'. - '</span> '.(' 'x2); - } - if ($switchserver) { - if ($values{'usable'} ne '') { - $datatable .= '<div id="linkprot_divcurrsecret_'.$i.'" style="display:inline-block" /><span class="LC_nobreak">'. - $desc{'secret'}.': ['.&mt('not shown').'] '.(' 'x2).'</span></div>'. - '<span class="LC_nobreak">'.&mt('Change secret?'). - '<label><input type="radio" value="0" name="linkprot_changesecret_'.$i.'" onclick="javascript:toggleLinkProt(this.form,'."'$i','secret'".');" checked="checked"'.$disabled.' />'.&mt('No').'</label>'. - (' 'x2). - '<label><input type="radio" value="1" name="linkprot_changesecret_'.$i.'" onclick="javascript:toggleLinkProt(this.form,'."'$i','secret'".');" '.$disabled.' />'.&mt('Yes').'</label>'.(' 'x2). - '</span><div id="linkprot_divchgsecret_'.$i.'" style="display:none" />'. - '<span class="LC_nobreak"> - '.$switchmessage.'</span>'. - '</div>'; - } elsif ($values{'key'} eq '') { - $datatable .= '<span class="LC_nobreak">'.&mt('Key and Secret are required').' - '.$switchmessage.'</span>'."\n"; - } else { - $datatable .= '<span class="LC_nobreak">'.&mt('Secret required').' - '.$switchmessage.'</span>'."\n"; - } - } else { - if ($values{'usable'} ne '') { - $datatable .= '<div id="linkprot_divcurrsecret_'.$i.'" style="display:inline-block" /><span class="LC_nobreak">'. - $desc{'secret'}.': ['.&mt('not shown').'] '.(' 'x2).'</span></div>'. - '<span class="LC_nobreak">'.&mt('Change?'). - '<label><input type="radio" value="0" name="linkprot_changesecret_'.$i.'" onclick="javascript:toggleLinkProt(this.form,'."'$i','secret'".');" checked="checked"'.$disabled.' />'.&mt('No').'</label>'. - (' 'x2). - '<label><input type="radio" value="1" name="linkprot_changesecret_'.$i.'" onclick="javascript:toggleLinkProt(this.form,'."'$i','secret'".');"'.$disabled.' />'.&mt('Yes'). - '</label> </span><div id="linkprot_divchgsecret_'.$i.'" style="display:none" />'. - '<span class="LC_nobreak">'.&mt('New Secret').':'. - '<input type="password" size="20" name="linkprot_secret_'.$i.'" value="" autocomplete="off"'.$disabled.' />'. - '<label><input type="checkbox" name="linkprot_visible_'.$i.'" id="linkprot_visible_'.$i.'" onclick="if (this.checked) { this.form.linkprot_secret_'.$i.'.type='."'text'".' } else { this.form.linkprot_secret_'.$i.'.type='."'password'".' }"'.$disabled.' />'.&mt('Visible input').'</label>'. - '<input type="hidden" name="linkprot_id_'.$i.'" value="'.$num.'" /></span></div>'; - } else { - $datatable .= - '<span class="LC_nobreak">'.$desc{'secret'}.':'. - '<input type="password" size="20" name="linkprot_secret_'.$i.'" value="" autocomplete="off"'.$disabled.' />'. - '<label><input type="checkbox" name="linkprot_visible_'.$i.'" id="linkprot_visible_'.$i.'" onclick="if (this.checked) { this.form.linkprot_secret_'.$i.'.type='."'text'".' } else { this.form.linkprot_secret_'.$i.'.type='."'password'".' }"'.$disabled.' />'.&mt('Visible input').'</label>'. - '<input type="hidden" name="linkprot_id_'.$i.'" value="'.$num.'" /></span>'; - } - } - if ($ltiauth) { - $datatable .= - '</fieldset>'. - '<fieldset id="linkprot_optional_'.$i.'" style="'.$usersty.'"><legend>'.$lt{'opti'}.'</legend>'. - &linkprot_options($i,$itemcount,$disabled,\%values,\%desc). - '</fieldset>'; - } - $datatable .= '</td></tr>'; - $itemcount ++; - } - } - } - $css_class = $itemcount%2?' class="LC_odd_row"':''; - $datatable .= '<tr '.$css_class.'><td><span class="LC_nobreak">'."\n". - '<input type="hidden" name="linkprot_maxnum" value="'.$next.'" />'."\n". - '<input type="checkbox" name="linkprot_add" value="1"'.$disabled.' />'.&mt('Add').'</span></td>'."\n". - '<td width="100%">'; - my ($usersty,$onclickrequser,%checkedrequser); - if ($ltiauth) { - $usersty = 'display:none'; - $onclickrequser = ' onclick="toggleLinkProtReqUser(this.form,'."'requser','optional','1','block','add'".');"'; - %checkedrequser = ( - no => ' checked="checked"', - yes => '', - ); - $datatable .= '<fieldset><legend>'.$lt{'requ'}.'</legend>'; - } - $datatable .= '<span class="LC_nobreak">'.$desc{'name'}. - ':<input type="text" size="15" name="linkprot_name_add" value="" autocomplete="off"'.$disabled.' /></span> '."\n". - (' 'x2). - '<span class="LC_nobreak">'.$desc{'version'}.':<select name="linkprot_version_add"'.$disabled.'>'. - '<option value="LTI-1p0" selected="selected">1.1</option></select></span> '."\n". - (' 'x2). - '<span class="LC_nobreak">'.$desc{'lifetime'}.':<input type="text" size="3" name="linkprot_lifetime_add" value="300"'.$disabled.' /></span> '."\n"; - if ($ltiauth) { - $datatable .= (' 'x2).'<span class="LC_nobreak">'.$desc{'requser'}.'?'. - '<label><input type="radio" name="linkprot_requser_add" value="0"'. - $onclickrequser.$checkedrequser{'no'}.$disabled.' />'.&mt('No').'</label> '. - '<label><input type="radio" name="linkprot_requser_add" value="1"'. - $onclickrequser.$checkedrequser{'yes'}.$disabled.' />'.&mt('Yes').'</label></span>'; - } - $datatable .= '<br /><br />'; - if ($switchserver) { - $datatable .= '<span class="LC_nobreak">'.&mt('Key and Secret are required').' - '.$switchmessage.'</span>'."\n"; - } else { - $datatable .= '<span class="LC_nobreak">'.$desc{'key'}.':<input type="text" size="25" name="linkprot_key_add" value="" autocomplete="off"'.$disabled.' /></span> '."\n". - (' 'x2). - '<span class="LC_nobreak">'.$desc{'secret'}.':<input type="password" size="20" name="linkprot_secret_add" value="" autocomplete="off"'.$disabled.' />'. - '<label><input type="checkbox" name="linkprot_visible_add" id="linkprot_visible_add" onclick="if (this.checked) { this.form.linkprot_secret_add.type='."'text'".' } else { this.form.linkprot_secret_add.type='."'password'".' }"'.$disabled.' />'.&mt('Visible input').'</label></span> '."\n"; - } - if ($ltiauth) { - $datatable .= '</fieldset>'. - '<fieldset id="linkprot_optional_add" style="'.$usersty.'"><legend>'.$lt{'opti'}.'</legend>'. - &linkprot_options('add',$itemcount,$disabled,{},\%desc). - '</fieldset>'; - } - $datatable .= '</td></tr>'; - $$rowtotal ++; - return $datatable; -} - -sub linkprot_names { - return &Apache::lonlocal::texthash( - 'version' => 'LTI Version', - 'key' => 'Key', - 'lifetime' => 'Nonce lifetime (s)', - 'name' => 'Launcher Application', - 'secret' => 'Secret', - 'requser' => 'Use identity', - 'email' => 'Email address', - 'sourcedid' => 'User ID', - 'other' => 'Other', - 'auth' => 'Display LON-CAPA login page', - 'reject' => 'Discontinue launch process', - ); -} - -sub check_switchserver { - my ($cdom,$cnum,$context,$dest) = @_; - my ($allowed,$switchserver,$home); - if ($context eq 'domain') { - $home = &Apache::lonnet::domain($cdom,'primary'); - } else { - $home = &Apache::lonnet::homeserver($cnum,$cdom); - } - unless (($home eq 'no_host') || ($home eq '')) { - my @ids=&Apache::lonnet::current_machine_ids(); - foreach my $id (@ids) { if ($id eq $home) { $allowed=1; } } - if (!$allowed) { - $switchserver='<a href="/adm/switchserver?otherserver='.$home.'&role='. - &HTML::Entities::encode($env{'request.role'},'\'<>"&'). - '&destinationurl='.$dest.'">'.&mt('Switch Server').'</a>'; - } - } - return $switchserver; -} - -sub linkprot_options { - my ($num,$itemcount,$disabled,$current,$desc) = @_; - my %lt; - if (ref($desc) eq 'HASH') { - %lt = %{$desc}; - } - my $userfieldsty = 'none'; - my (%checked,$userfield); - $checked{'sourcedid'} = ' checked="checked"'; - $checked{'reject'} = ' checked="checked"'; - if (ref($current) eq 'HASH') { - if (($current->{'mapuser'} ne '') && ($current->{'mapuser'} ne 'lis_person_sourcedid')) { - $checked{'sourcedid'} = ''; - if ($current->{'mapuser'} eq 'lis_person_contact_email_primary') { - $checked{'email'} = ' checked="checked"'; - } else { - $checked{'other'} = ' checked="checked"'; - $userfield = $current->{'mapuser'}; - $userfieldsty = 'inline-block'; - } - } - if (($current->{'notstudent'} ne '') && ($current->{'notstudent'} ne 'reject')) { - $checked{'reject'} = ''; - $checked{'auth'} = ' checked="checked"'; - } - } - my $onclickuser = ' onclick="toggleLinkProtReqUser(this.form,'."'mapuser','userfield','other','inline-block','$num'".');"'; - my $output = '<div class="LC_floatleft"><span class="LC_nobreak">'. - &mt('Source of LON-CAPA username in LTI request').': '; - foreach my $option ('sourcedid','email','other') { - $output .= '<label><input type="radio" name="linkprot_mapuser_'.$num.'" value="'.$option.'"'. - $checked{$option}.$onclickuser.$disabled.' />'.$lt{$option}.'</label>'. - ($option eq 'other' ? '' : (' 'x2) ); - } - $output .= '</span></div>'. - '<div class="LC_floatleft" style="display:'.$userfieldsty.';" id="linkprot_userfield_'.$num.'">'. - '<input type="text" name="linkprot_customuser_'.$num.'" '. - 'value="'.$userfield.'"'.$disabled.' /></div>'; - $output .= '<br />'. - '<div class="LC_floatleft"><span class="LC_nobreak">'. - &mt('Action when username is not for an enrolled student').': '; - foreach my $option ('reject','auth') { - $output .= '<label><input type="radio" name="linkprot_notstudent_'.$num.'" value="'.$option.'"'. - $checked{$option}.$disabled.' />'.$lt{$option}.'</label>'. - ($option eq 'auth' ? '' : (' 'x2) ); - } - $output .= '</span></div>'; - return $output; -} - sub print_other { my ($cdom,$settings,$allitems,$rowtotal,$crstype,$noedit) = @_; unless ((ref($settings) eq 'HASH') && (ref($allitems) eq 'ARRAY')) { @@ -5614,23 +4387,17 @@ sub get_other_items { } sub item_table_row_start { - my ($text,$count,$add_class,$colspan,$leftclass,$rightclass) = @_; + my ($text,$count,$add_class,$colspan) = @_; my $output; my $css_class = ($count % 2) ? 'LC_odd_row' : 'LC_even_row'; $css_class = (join(' ',$css_class,$add_class)) unless ($add_class eq ''); - if ($leftclass eq '') { - $leftclass = 'LC_left_item'; - } - if ($rightclass eq '') { - $rightclass = 'LC_right_item'; - } $output .= '<tr class="'.$css_class.'">'."\n". - '<td class="'.$leftclass.'">'.$text. + '<td class="LC_left_item">'.$text. '</td>'; - if ($colspan > 1) { - $output .= '<td class="'.$rightclass.'" colspan="'.$colspan.'">'; + if ($colspan) { + $output .= '<td class="LC_right_item" colspan="'.$colspan.'">'; } else { - $output .= '<td class="'.$rightclass.'">'; + $output .= '<td class="LC_right_item">'; } return $output; } @@ -5640,7 +4407,7 @@ sub item_table_row_end { } sub yesno_radio { - my ($item,$settings,$unsetdefault,$valueyes,$valueno,$noedit) = @_; + my ($item,$settings,$unsetdefault,$valueyes,$valueno,$noedit,$onclick,$reverse) = @_; my $itemon = ' '; my $itemoff = ' checked="checked" '; if (($valueyes eq '') && ($valueno eq '')) { @@ -5662,12 +4429,22 @@ sub yesno_radio { my $disabled; if ($noedit) { $disabled = ' disabled="disabled"'; + } elsif ($onclick) { + $onclick = ' onclick="'.$onclick.'"'; + } + if ($reverse) { + return '<span class="LC_nobreak"><label>'. + '<input type="radio" name="'.$item.'"'. + $itemoff.' value="'.$valueno.'"'.$disabled.$onclick.' />'.&mt('No').'</label> '. + '<label><input type="radio" name="'.$item.'"'. + $itemon.' value="'.$valueyes.'"'.$disabled.$onclick.' />'.&mt('Yes').'</label></span>'; + } else { + return '<span class="LC_nobreak"><label>'. + '<input type="radio" name="'.$item.'"'. + $itemon.' value="'.$valueyes.'"'.$disabled.$onclick.' />'.&mt('Yes').'</label> '. + '<label><input type="radio" name="'.$item.'"'. + $itemoff.' value="'.$valueno.'"'.$disabled.$onclick.' />'.&mt('No').'</label></span>'; } - return '<span class="LC_nobreak"><label>'. - '<input type="radio" name="'.$item.'"'. - $itemon.' value="'.$valueyes.'"'.$disabled.' />'.&mt('Yes').'</label> '. - '<label><input type="radio" name="'.$item.'"'. - $itemoff.' value="'.$valueno.'"'.$disabled.' />'.&mt('No').'</label></span>'; } sub select_from_options { @@ -5723,7 +4500,7 @@ sub select_from_options { } sub make_item_rows { - my ($cdom,$items,$ordered,$settings,$rowtotal,$crstype,$caller,$noedit) = @_; + my ($cdom,$items,$ordered,$settings,$rowtotal,$crstype,$caller,$noedit,$cnum) = @_; my $datatable; if ((ref($items) eq 'HASH') && (ref($ordered) eq 'ARRAY')) { my $count = 0; @@ -5774,16 +4551,63 @@ sub make_item_rows { } $datatable .= &yesno_radio($item,$settings,$unsetdefault,$valueyes,$valueno,$noedit); } elsif ($items->{$item}{input} eq 'selectbox') { - my $id; - if ($caller eq 'menuitems') { - $id = $item; + my ($id,$onchange); + if ($caller eq 'grading') { + if ($item eq 'grading') { + $onchange = ' onchange="javascript:toggleGrading(this.form);"'; + $id = $item; + } } my $curr = $settings->{$item}; $datatable .= &select_from_options($item,$items->{$item}{'order'}, $items->{$item}{'options'},$curr, $items->{$item}{'nullval'}, - undef,undef,undef,$noedit,$id); + undef,undef,$onchange,$noedit,$id); + if ($item eq 'grading') { + my ($unsetdefault,$valueyes,$valueno,$sectionbox); + my $gradingsty = 'none'; + my $gradingsecsty = 'none'; + $unsetdefault = 0; + my (@selsec,@sections,%current); + if ($curr eq 'standard') { + $gradingsty = 'inline-block'; + if (ref($settings) eq 'HASH') { + $current{'hidetotals'} = $settings->{'hidetotals'}; + if ($settings->{'hidetotals'} =~ /^([\w,]+)$/) { + my $secstr = $1; + unless ($secstr eq 'all') { + @selsec = split(/,/,$secstr); + } + $current{'hidetotals'} = 1; + } + } + } + $valueyes = "1"; + $valueno = "0"; + my %sections = &Apache::loncommon::get_sections($cdom,$cnum); + if (keys(%sections)) { + @sections = sort( { $a <=> $b } keys(%sections)); + } + my $onclick = 'javascript:toggleHiddenTotalsSec(this.form);'; + my $sectionbox = '<div id="sectotalsdiv" style="display:'.$gradingsecsty.'; float:right">'; + my $reverse = 1; + if (@sections) { + $sectionbox .= ' ... '.&mt('hidden in sections').': '. + '<div style="position: relative; top: 0%;">'. + &select_sections('hidetotals','',\@sections,\@selsec,$noedit,'all'). + '</div>'; + } + $sectionbox .= '</div>'; + $datatable .= '<fieldset id="hidetotalsdiv" style="display:'.$gradingsty.';">'. + '<legend style="font-weight: normal;">'. + &mt('Hide Course Points Totals').'</legend>'. + '<div style="position: relative; top: 0%; float:left">'. + &yesno_radio('hidetotals',\%current,$unsetdefault,$valueyes,$valueno,$noedit, + $onclick,$reverse).'</div>'. + $sectionbox. + '</fieldset><div style="padding:0;clear:both;margin:0;border:0"></div>'; + } } elsif ($items->{$item}{input} eq 'textbox') { my $disabled; if ($noedit) { @@ -6178,30 +5002,6 @@ sub change_clone { } } } - return; -} - -sub devalidate_remote_courseprefs { - my ($cdom,$cnum,$cachekeys) = @_; - return unless (ref($cachekeys) eq 'HASH'); - my %servers = &Apache::lonnet::internet_dom_servers($cdom); - my %thismachine; - map { $thismachine{$_} = 1; } &Apache::lonnet::current_machine_ids(); - my @posscached = ('courselti'); - if (keys(%servers)) { - foreach my $server (keys(%servers)) { - next if ($thismachine{$server}); - my @cached; - foreach my $name (@posscached) { - if ($cachekeys->{$name}) { - push(@cached,&escape($name).':'.&escape($cdom.'_'.$cnum)); - } - } - if (@cached) { - &Apache::lonnet::remote_devalidate_cache($server,\@cached); - } - } - } return; }