Diff for /loncom/interface/courseprefs.pm between versions 1.92 and 1.93

version 1.92, 2021/06/07 02:19:51 version 1.93, 2021/08/04 19:59:10
Line 365  sub handler { Line 365  sub handler {
     }      }
   
     my %values=&Apache::lonnet::dump('environment',$cdom,$cnum);      my %values=&Apache::lonnet::dump('environment',$cdom,$cnum);
       my %courselti=&Apache::lonnet::dump('lti',$cdom,$cnum,undef,undef,undef,1);
       if ($courselti{'lock'}) {
           delete($courselti{'lock'});
       }
       $values{'linkprotection'} = \%courselti;
     my @prefs_order = ('courseinfo','localization','feedback','discussion',      my @prefs_order = ('courseinfo','localization','feedback','discussion',
                        'classlists','appearance','grading','printouts',                         'classlists','appearance','grading','printouts',
                        'menuitems','spreadsheet','bridgetasks','lti','other');                         'menuitems','linkprotection','spreadsheet','bridgetasks',
                          'lti','other');
   
     my %prefs = (      my %prefs = (
         'courseinfo' =>          'courseinfo' =>
Line 557  sub handler { Line 563  sub handler {
                          menucollections => 'Menu collections',                           menucollections => 'Menu collections',
                                  },                                   },
                    },                     },
           'linkprotection' =>
                      {
                        text => 'Link protection',
                        help => 'Course_Prefs_Linkprotection',
                        header => [{col1 => 'Item',
                                    col2 => 'Settings',
                                   }],
                      },
         'other' =>          'other' =>
                   { text => 'Other settings',                    { text => 'Other settings',
                     help => 'Course_Prefs_Other',                      help => 'Course_Prefs_Other',
Line 764  sub print_config_box { Line 778  sub print_config_box {
         $output .= &print_lti($cdom,$settings,$ordered,$itemtext,\$rowtotal,$crstype,$noedit);          $output .= &print_lti($cdom,$settings,$ordered,$itemtext,\$rowtotal,$crstype,$noedit);
     } elsif ($action eq 'menuitems') {      } elsif ($action eq 'menuitems') {
         $output .= &print_menuitems('bottom',$cdom,$settings,$itemtext,\$rowtotal,$crstype,$noedit);          $output .= &print_menuitems('bottom',$cdom,$settings,$itemtext,\$rowtotal,$crstype,$noedit);
       } elsif ($action eq 'linkprotection') {
           $output .= &print_linkprotection($cdom,$settings,\$rowtotal,$crstype,$noedit);
     } elsif ($action eq 'other') {      } elsif ($action eq 'other') {
         $output .= &print_other($cdom,$settings,$allitems,\$rowtotal,$crstype,$noedit);          $output .= &print_other($cdom,$settings,$allitems,\$rowtotal,$crstype,$noedit);
     }      }
Line 776  sub print_config_box { Line 792  sub print_config_box {
 }  }
   
 sub process_changes {  sub process_changes {
     my ($cdom,$action,$values,$item,$changes,$allitems,$disallowed,$crstype) = @_;      my ($cdom,$cnum,$action,$values,$item,$changes,$allitems,$disallowed,$crstype) = @_;
     my %newvalues;      my (%newvalues,%courselti,$errors);
     if (ref($item) eq 'HASH') {      if (ref($item) eq 'HASH') {
         if (ref($changes) eq 'HASH') {          if (ref($changes) eq 'HASH') {
             my @ordered;              my @ordered;
Line 794  sub process_changes { Line 810  sub process_changes {
                         }                          }
                     }                      }
                 }                  }
               } elsif ($action eq 'linkprotection') {
                   if (ref($values->{'linkprotection'}) eq 'HASH') {
                       foreach my $id (keys(%{$values->{'linkprotection'}})) {
                           if ($id =~ /^\d+$/) {
                               push(@ordered,$id);
                               unless (ref($values->{'linkprotection'}->{$id}) eq 'HASH') {
                                   $courselti{$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') {              } elsif (ref($item->{'ordered'}) eq 'ARRAY') {
                 if ($action eq 'courseinfo') {                  if ($action eq 'courseinfo') {
                     my ($can_toggle_cat,$can_categorize) =                      my ($can_toggle_cat,$can_categorize) =
Line 931  sub process_changes { Line 962  sub process_changes {
                     } elsif ($values->{'menucollections'}) {                      } elsif ($values->{'menucollections'}) {
                         $changes->{'menucollections'} = '';                          $changes->{'menucollections'} = '';
                     }                      }
                   } elsif ($action eq 'linkprotection') {
                       my %menutitles = &ltimenu_titles();
                       my (@items,%deletions,%itemids,%haschanges);
                       if ($env{'form.linkprot_add'}) {
                           my $name = $env{'form.linkprot_name_add'};
                           $name =~ s/(`)/'/g;
                           my ($newid,$error) = &get_courselti_id($cdom,$cnum,$name);
                           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->{'linkprotection'}) 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->{'linkprotection'}->{$itemid}) eq 'HASH') {
                                       push(@items,$i);
                                       $itemids{$i} = $itemid;
                                       if ((@todelete > 0) && (grep(/^$i$/,@todelete))) {
                                           $deletions{$itemid} = $values->{'linkprotection'}->{$itemid}->{'name'};
                                       }
                                   }
                               }
                           }
   
                       }
                       foreach my $idx (@items) {
                           my $itemid = $itemids{$idx};
                           next unless ($itemid);
                           if (exists($deletions{$itemid})) {
                               $courselti{$itemid} = $deletions{$itemid};
                               $haschanges{$itemid} = 1;
                               next;
                           }
                           my %current;
                           if (ref($values->{'linkprotection'}) eq 'HASH') {
                               if (ref($values->{'linkprotection'}->{$itemid}) eq 'HASH') {
                                   foreach my $key (keys(%{$values->{'linkprotection'}->{$itemid}})) {
                                       $current{$key} = $values->{'linkprotection'}->{$itemid}->{$key};
                                   }
                               }
                           }
                           foreach my $inner ('name','key','secret','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 '') {
                                   $courselti{$itemid}{$inner} = $env{$formitem};
                               }
                           }
                       }
                       if (keys(%haschanges)) {
                           foreach my $entry (keys(%haschanges)) {
                               $changes->{$entry} = $courselti{$entry};
                           }
                       }
                 } else {                  } else {
                     foreach my $entry (@ordered) {                      foreach my $entry (@ordered) {
                         if ($entry eq 'cloners') {                          if ($entry eq 'cloners') {
Line 971  sub process_changes { Line 1074  sub process_changes {
                                     my $clonedom = $env{'form.cloners_newdom'};                                      my $clonedom = $env{'form.cloners_newdom'};
                                     if (&check_clone($clonedom,$disallowed) eq 'ok') {                                      if (&check_clone($clonedom,$disallowed) eq 'ok') {
                                         my $newdom = '*:'.$env{'form.cloners_newdom'};                                          my $newdom = '*:'.$env{'form.cloners_newdom'};
                                         if (@clonedoms) {                                           if (@clonedoms) {
                                             if (!grep(/^\Q$newdom\E$/,@clonedoms)) {                                              if (!grep(/^\Q$newdom\E$/,@clonedoms)) {
                                                 $newvalues{$entry} .= ','.$newdom;                                                  $newvalues{$entry} .= ','.$newdom;
                                             }                                              }
Line 1417  sub process_changes { Line 1520  sub process_changes {
             }              }
         }          }
     }      }
     return;      return $errors;
   }
   
   sub get_courselti_id {
       my ($cdom,$cnum,$name) = @_;
       # get lock on lti db in course
       my $lockhash = {
                         lock => $env{'user.name'}.
                                 ':'.$env{'user.domain'},
                      };
       my $tries = 0;
       my $gotlock = &Apache::lonnet::newput('lti',$lockhash,$cdom,$cnum);
       my ($id,$error);
       while (($gotlock ne 'ok') && ($tries<10)) {
           $tries ++;
           sleep (0.1);
           $gotlock = &Apache::lonnet::newput('lti',$lockhash,$cdom,$cnum);
       }
       if ($gotlock eq 'ok') {
           my %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) {
                   unless (&Apache::lonnet::newput('lti',{ $id => $name },$cdom,$cnum) eq 'ok') {
                       $error = 'nostore';
                   }
               } else {
                   $error = 'nonumber';
               }
           }
           my $dellockoutcome = &Apache::lonnet::del('lti',['lock'],$cdom,$cnum);
       } else {
           $error = 'nolock';
       }
       return ($id,$error);
 }  }
   
 sub get_sec_str {  sub get_sec_str {
Line 1462  sub check_clone { Line 1609  sub check_clone {
 sub store_changes {  sub store_changes {
     my ($cdom,$cnum,$prefs_order,$actions,$prefs,$values,$changes,$crstype) = @_;      my ($cdom,$cnum,$prefs_order,$actions,$prefs,$values,$changes,$crstype) = @_;
     my ($chome,$output);      my ($chome,$output);
     my (%storehash,@delkeys,@need_env_update,@oldcloner);      my (%storehash,@delkeys,@need_env_update,@oldcloner,%oldlinkprot);
     if ((ref($values) eq 'HASH') && (ref($changes) eq 'HASH')) {      if ((ref($values) eq 'HASH') && (ref($changes) eq 'HASH')) {
           if (ref($values->{'linkprotection'}) eq 'HASH') {
               %oldlinkprot = %{$values->{'linkprotection'}};
           }
           delete($values->{'linkprotection'});
         %storehash = %{$values};          %storehash = %{$values};
     } else {      } else {
         if ($crstype eq 'Community') {          if ($crstype eq 'Community') {
Line 1473  sub store_changes { Line 1624  sub store_changes {
         }          }
         return $output;          return $output;
     }      }
       my ($numchanges,$skipstore);
       if (ref($changes) eq 'HASH') {
           $numchanges = scalar(keys(%{$changes}));
           if (($numchanges == 1) && (exists($changes->{'linkprotection'}))) {
               $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 = (      my %yesno = (
                  hidefromcat           => '1',                   hidefromcat           => '1',
                  problem_stream_switch => '1',                   problem_stream_switch => '1',
Line 1485  sub store_changes { Line 1650  sub store_changes {
         if (grep(/^\Q$item\E$/,@{$actions})) {          if (grep(/^\Q$item\E$/,@{$actions})) {
             $output .= '<h3>'.&mt($prefs->{$item}{'text'}).'</h3>';              $output .= '<h3>'.&mt($prefs->{$item}{'text'}).'</h3>';
             if (ref($changes->{$item}) eq 'HASH') {              if (ref($changes->{$item}) eq 'HASH') {
                 if (keys(%{$changes->{$item}}) > 0) {                  if ((keys(%{$changes->{$item}}) > 0) || ($item eq 'linkprotection')) {
                     $output .= &mt('Changes made:').'<ul style="list-style:none;">';                      $output .= &mt('Changes made:').'<ul style="list-style:none;">';
                     if ($item eq 'other') {                      if ($item eq 'other') {
                         foreach my $key (sort(keys(%{$changes->{$item}}))) {                          foreach my $key (sort(keys(%{$changes->{$item}}))) {
Line 1498  sub store_changes { Line 1663  sub store_changes {
                                            "'$storehash{$key}'")).'</li>';                                             "'$storehash{$key}'")).'</li>';
                             }                              }
                         }                          }
                       } elsif ($item eq 'linkprotection') {
                           if (&Apache::lonnet::put('lti',$changes->{'linkprotection'},$cdom,$cnum,1) eq 'ok') {
                               my $hashid=$cdom.'_'.$cnum;
                               &Apache::lonnet::devalidate_cache_new('courselti',$hashid);
                               foreach my $itemid (sort { $a <=> $b } %{$changes->{'linkprotection'}}) {
                                   if (ref($changes->{'linkprotection'}->{$itemid}) eq 'HASH') {
                                       my %values = %{$changes->{'linkprotection'}->{$itemid}};
                                       my %desc = &linkprot_names();
                                       my $display;
                                       foreach my $title ('name','lifetime','version','key','secret') {
                                           if ($title eq 'secret') {
                                               my $length = length($values{$title});
                                               $display .= $desc{$title}.': '.('*' x $length);
                                           } elsif ($title eq 'version') {
                                               if ($values{$title} eq 'LTI-1p0') {
                                                   $display .= $desc{$title}.': 1.1, ';
                                               }
                                           } else {
                                               $display .= $desc{$title}.': '.$values{$title}.', ';
                                           }
                                       }
                                       $output .= '<li>'.&Apache::lonhtmlcommon::confirm_success(&mt('[_1] set to [_2]','<i>'.$itemid.'</i>',
                                                  "'$display'")).'</li>';
                                   } elsif (ref($oldlinkprot{$itemid}) eq 'HASH') {
                                       my $oldname = $oldlinkprot{$itemid}{'name'};
                                       $output .= '<li>'.&Apache::lonhtmlcommon::confirm_success(&mt('Deleted setting for [_1]','<i>'."$itemid ($oldname)".'</i>')).'</li>';
                                   }
                               }
                           } else {
                               $output .= '<li>'.
                                          '<span class="LC_error">'.
                                          &mt('An error occurred when saving changes to link protection settings, which remain unchanged.').
                                          '</span>'.
                                          '</li>';
                           }
                     } else {                      } else {
                         if (ref($prefs->{$item}->{'ordered'}) eq 'ARRAY') {                          if (ref($prefs->{$item}->{'ordered'}) eq 'ARRAY') {
                             my @settings = @{$prefs->{$item}->{'ordered'}};                              my @settings = @{$prefs->{$item}->{'ordered'}};
Line 1785  sub store_changes { Line 1985  sub store_changes {
             }              }
         }          }
     }      }
       if ($skipstore) {
           return $output;
       }
     if (&Apache::lonnet::put('environment',\%storehash,$cdom,$cnum) eq 'ok') {      if (&Apache::lonnet::put('environment',\%storehash,$cdom,$cnum) eq 'ok') {
         if (ref($changes) eq 'HASH') {          if (ref($changes) eq 'HASH') {
             if (ref($changes->{'courseinfo'}) eq 'HASH') {              if (ref($changes->{'courseinfo'}) eq 'HASH') {
Line 5039  sub menucollections_display { Line 5242  sub menucollections_display {
     return $output;      return $output;
 }  }
   
   sub print_linkprotection {
       my ($cdom,$settings,$rowtotal,$crstype,$noedit) = @_;
       unless (ref($settings) eq 'HASH') {
           return;
       }
   
       my %linkprotection;
       my $count = 0;
       my $next = 1;
       my ($datatable,$disabled,$css_class);
       if ($noedit) {
           $disabled = ' disabled="disabled"';
       }
       my %lt = &linkprot_names();
       my $itemcount = 0;
   
       if (ref($settings->{'linkprotection'}) eq 'HASH') {
           if (keys(%{$settings->{'linkprotection'}})) {
               my @current = sort { $a <=> $b } keys(%{$settings->{'linkprotection'}});
               $next += $current[-1];
               for (my $i=0; $i<@current; $i++) {
                   my $num = $current[$i];
                   my %values;
                   if (ref($settings->{'linkprotection'}->{$num}) eq 'HASH') {
                       %values = %{$settings->{'linkprotection'}->{$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><span class="LC_nobreak">'.$lt{'name'}.
                       ':<input type="text" size="15" name="linkprot_name_'.$i.'" value="'.$values{'name'}.'"'.$disabled.' /></span> '.
                       ('&nbsp;'x2).
                       '<span class="LC_nobreak">'.$lt{'version'}.':<select name="linkprot_version_'.$i.'">'.
                       '<option value="LTI-1p0" '.$selected.'>1.1</option></select></span> '."\n".
                       ('&nbsp;'x2).
                       '<span class="LC_nobreak">'.$lt{'lifetime'}.':<input type="text" name="linkprot_lifetime_'.$i.'"'.
                       'value="'.$values{'lifetime'}.'" size="3"'.$disabled.' /></span>'.
                       '<br /><br />'.
                       '<span class="LC_nobreak">'.$lt{'key'}.
                       ':<input type="text" size="25" name="linkprot_key_'.$i.'" value="'.$values{'key'}.'"'.$disabled.' /></span> '.
                       ('&nbsp;'x2).
                       '<span class="LC_nobreak">'.$lt{'secret'}.':'.
                       '<input type="password" size="20" name="linkprot_secret_'.$i.'" value="'.$values{'secret'}.'"'.$disabled.' />'.
                       '<label><input type="checkbox" name="visible" onclick="if (this.checked) { this.form.linkprot_secret_'.$i.'.type='."'text'".' } else { this.form.linkprot_secret_'.$i.'.type='."'password'".' }" />'.&mt('Visible input').'</label>'.
                       '<input type="hidden" name="linkprot_id_'.$i.'" value="'.$num.'" /></span>'.
                       '</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" />'.&mt('Add').'</span></td>'."\n".
                     '<td>'.
                     '<span class="LC_nobreak">'.$lt{'name'}.
                     ':<input type="text" size="15" name="linkprot_name_add" value="" /></span> '."\n".
                     ('&nbsp;'x2).
                     '<span class="LC_nobreak">'.$lt{'version'}.':<select name="linkprot_version_add">'.
                     '<option value="LTI-1p0" selected="selected">1.1</option></select></span> '."\n".
                     ('&nbsp;'x2).
                     '<span class="LC_nobreak">'.$lt{'lifetime'}.':<input type="text" size="3" name="linkprot_lifetime_add" value="300" /></span> '."\n".
                     '<br /><br />'.
                     '<span class="LC_nobreak">'.$lt{'key'}.':<input type="text" size="25" name="linkprot_key_add" value="" /></span> '."\n".
                     ('&nbsp;'x2).
                     '<span class="LC_nobreak">'.$lt{'secret'}.':<input type="password" size="20" name="linkprot_secret_add" value="" />'.
                     '<label><input type="checkbox" name="visible" onclick="if (this.checked) { this.form.linkprot_secret_add.type='."'text'".' } else { this.form.linkprot_secret_add.type='."'password'".' }" />'.&mt('Visible input').'</label></span> '."\n".
                     '</td></tr>';
       $$rowtotal ++;
       return $datatable;;
   }
   
   sub linkprot_names {
       my %lt = &Apache::lonlocal::texthash(
                                             'version'   => 'LTI Version',
                                             'key'       => 'Key',
                                             'lifetime'  => 'Nonce lifetime (s)',
                                             'name'      => 'Launcher Application Name',
                                             'secret'    => 'Secret',
                                           );
       return %lt;
   }
   
 sub print_other {  sub print_other {
     my ($cdom,$settings,$allitems,$rowtotal,$crstype,$noedit) = @_;      my ($cdom,$settings,$allitems,$rowtotal,$crstype,$noedit) = @_;
     unless ((ref($settings) eq 'HASH') && (ref($allitems) eq 'ARRAY')) {      unless ((ref($settings) eq 'HASH') && (ref($allitems) eq 'ARRAY')) {
Line 5061  sub print_other { Line 5355  sub print_other {
                             input => 'textbox',                              input => 'textbox',
                             size  => '30',                              size  => '30',
                            };                             };
     my $output = &make_item_rows($cdom,\%items,\@ordered,$settings,$rowtotal,$crstype,'other',$noedit);      return &make_item_rows($cdom,\%items,\@ordered,$settings,$rowtotal,$crstype,'other',$noedit);
 }  }
   
 sub get_other_items {  sub get_other_items {

Removed from v.1.92  
changed lines
  Added in v.1.93


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>