Diff for /loncom/interface/domainprefs.pm between versions 1.286 and 1.345

version 1.286, 2017/01/18 21:24:39 version 1.345, 2018/12/26 20:10:24
Line 27 Line 27
 #  #
 #  #
 ###############################################################  ###############################################################
 ##############################################################  ###############################################################
   
 =pod  =pod
   
Line 104  $datatable  - HTML containing form eleme Line 104  $datatable  - HTML containing form eleme
   
 In the case of course requests, radio buttons are displayed for each institutional  In the case of course requests, radio buttons are displayed for each institutional
 affiliate type (and also default, and _LC_adv) for each of the course types   affiliate type (and also default, and _LC_adv) for each of the course types 
 (official, unofficial, community, textbook, and placement).    (official, unofficial, community, textbook, placement, and lti).  
 In each case the radio buttons allow the selection of one of four values:    In each case the radio buttons allow the selection of one of four values:  
   
 0, approval, validate, autolimit=N (where N is blank, or a positive integer).  0, approval, validate, autolimit=N (where N is blank, or a positive integer).
Line 219  sub handler { Line 219  sub handler {
                 'serverstatuses','requestcourses','helpsettings',                  'serverstatuses','requestcourses','helpsettings',
                 'coursedefaults','usersessions','loadbalancing',                  'coursedefaults','usersessions','loadbalancing',
                 'requestauthor','selfenrollment','inststatus',                  'requestauthor','selfenrollment','inststatus',
                 'ltitools','ssl','trust'],$dom);                  'ltitools','ssl','trust','lti'],$dom);
       my %encconfig =
           &Apache::lonnet::get_dom('encconfig',['ltitools','lti'],$dom);
       if (ref($domconfig{'ltitools'}) eq 'HASH') {
           if (ref($encconfig{'ltitools'}) eq 'HASH') {
               foreach my $id (keys(%{$domconfig{'ltitools'}})) {
                   if ((ref($domconfig{'ltitools'}{$id}) eq 'HASH') &&
                       (ref($encconfig{'ltitools'}{$id}) eq 'HASH')) {
                       foreach my $item ('key','secret') {
                           $domconfig{'ltitools'}{$id}{$item} = $encconfig{'ltitools'}{$id}{$item};
                       }
                   }
               }
           }
       }
       if (ref($domconfig{'lti'}) eq 'HASH') {
           if (ref($encconfig{'lti'}) eq 'HASH') {
               foreach my $id (keys(%{$domconfig{'lti'}})) {
                   if ((ref($domconfig{'lti'}{$id}) eq 'HASH') &&
                       (ref($encconfig{'lti'}{$id}) eq 'HASH')) {
                       foreach my $item ('key','secret') {
                           $domconfig{'lti'}{$id}{$item} = $encconfig{'lti'}{$id}{$item};
                       }
                   }
               }
           }
       }
     my @prefs_order = ('rolecolors','login','defaults','quotas','autoenroll',      my @prefs_order = ('rolecolors','login','defaults','quotas','autoenroll',
                        'autoupdate','autocreate','directorysrch','contacts',                         'autoupdate','autocreate','directorysrch','contacts',
                        'usercreation','selfcreation','usermodification','scantron',                         'usercreation','selfcreation','usermodification','scantron',
                        'requestcourses','requestauthor','coursecategories',                         'requestcourses','requestauthor','coursecategories',
                        'serverstatuses','helpsettings','coursedefaults',                         'serverstatuses','helpsettings','coursedefaults',
                        'ltitools','selfenrollment','usersessions','ssl','trust');                         'ltitools','selfenrollment','usersessions','ssl','trust','lti');
     my %existing;      my %existing;
     if (ref($domconfig{'loadbalancing'}) eq 'HASH') {      if (ref($domconfig{'loadbalancing'}) eq 'HASH') {
         %existing = %{$domconfig{'loadbalancing'}};          %existing = %{$domconfig{'loadbalancing'}};
Line 265  sub handler { Line 291  sub handler {
                       help => 'Domain_Configuration_LangTZAuth',                        help => 'Domain_Configuration_LangTZAuth',
                       header => [{col1 => 'Setting',                        header => [{col1 => 'Setting',
                                   col2 => 'Value'},                                    col2 => 'Value'},
                                    {col1 => 'Internal Authentication',
                                     col2 => 'Value'},
                                  {col1 => 'Institutional user types',                                   {col1 => 'Institutional user types',
                                   col2 => 'Assignable to e-mail usernames'}],                                    col2 => 'Name displayed'}],
                       print => \&print_defaults,                        print => \&print_defaults,
                       modify => \&modify_defaults,                        modify => \&modify_defaults,
                     },                      },
Line 324  sub handler { Line 352  sub handler {
                                 col2 => 'Value',},                                  col2 => 'Value',},
                                {col1 => 'Recipient(s) for notifications',                                 {col1 => 'Recipient(s) for notifications',
                                 col2 => 'Value',},                                  col2 => 'Value',},
                                  {col1 => 'Nightly status check e-mail',
                                   col2 => 'Settings',},
                                {col1 => 'Ask helpdesk form settings',                                 {col1 => 'Ask helpdesk form settings',
                                 col2 => 'Value',},],                                  col2 => 'Value',},],
                     print => \&print_contacts,                      print => \&print_contacts,
Line 348  sub handler { Line 378  sub handler {
                                 col2 => 'Enabled?'},                                  col2 => 'Enabled?'},
                                {col1 => 'Institutional user type (login/SSO self-creation)',                                 {col1 => 'Institutional user type (login/SSO self-creation)',
                                 col2 => 'Information user can enter'},                                  col2 => 'Information user can enter'},
                                {col1 => 'Self-creation with e-mail as username',                                 {col1 => 'Self-creation with e-mail verification',
                                 col2 => 'Settings'}],                                  col2 => 'Settings'}],
                     print => \&print_selfcreation,                      print => \&print_selfcreation,
                     modify => \&modify_selfcreation,                      modify => \&modify_selfcreation,
Line 486  sub handler { Line 516  sub handler {
                  },                   },
         'ltitools' =>           'ltitools' => 
                  {text => 'External Tools (LTI)',                   {text => 'External Tools (LTI)',
                   help => 'Domain_configuration_LTI_Tools',                    help => 'Domain_Configuration_LTI_Tools',
                   header => [{col1 => 'Setting',                    header => [{col1 => 'Setting',
                               col2 => 'Value',}],                                col2 => 'Value',}],
                   print => \&print_ltitools,                    print => \&print_ltitools,
Line 499  sub handler { Line 529  sub handler {
                               col2 => 'Certificate Status'},                                col2 => 'Certificate Status'},
                              {col1 => 'Connections to other servers',                               {col1 => 'Connections to other servers',
                               col2 => 'Rules'},                                col2 => 'Rules'},
                                {col1 => 'Connections from other servers',
                                 col2 => 'Rules'},
                              {col1 => "Replicating domain's published content",                               {col1 => "Replicating domain's published content",
                               col2 => 'Rules'}],                                col2 => 'Rules'}],
                   print => \&print_ssl,                    print => \&print_ssl,
Line 528  sub handler { Line 560  sub handler {
                   print => \&print_trust,                    print => \&print_trust,
                   modify => \&modify_trust,                    modify => \&modify_trust,
                  },                   },
             'lti' =>
                    {text => 'LTI Provider',
                     help => 'Domain_Configuration_LTI_Provider',
                     header => [{col1 => 'Setting',
                                 col2 => 'Value',}],
                     print => \&print_lti,
                     modify => \&modify_lti,
                    },
     );      );
     if (keys(%servers) > 1) {      if (keys(%servers) > 1) {
         $prefs{'login'}  = { text   => 'Log-in page options',          $prefs{'login'}  = { text   => 'Log-in page options',
Line 581  $javascript_validations Line 621  $javascript_validations
 $coursebrowserjs  $coursebrowserjs
 END  END
         }          }
           if (grep(/^selfcreation$/,@actions)) {
               $js .= &selfcreate_javascript();
           }
         if (grep(/^contacts$/,@actions)) {          if (grep(/^contacts$/,@actions)) {
             $js .= &contacts_javascript();              $js .= &contacts_javascript();
         }          }
Line 673  sub process_changes { Line 716  sub process_changes {
     } elsif ($action eq 'autocreate') {      } elsif ($action eq 'autocreate') {
         $output = &modify_autocreate($dom,%domconfig);          $output = &modify_autocreate($dom,%domconfig);
     } elsif ($action eq 'directorysrch') {      } elsif ($action eq 'directorysrch') {
         $output = &modify_directorysrch($dom,%domconfig);          $output = &modify_directorysrch($dom,$lastactref,%domconfig);
     } elsif ($action eq 'usercreation') {      } elsif ($action eq 'usercreation') {
         $output = &modify_usercreation($dom,%domconfig);          $output = &modify_usercreation($dom,%domconfig);
     } elsif ($action eq 'selfcreation') {      } elsif ($action eq 'selfcreation') {
         $output = &modify_selfcreation($dom,%domconfig);          $output = &modify_selfcreation($dom,$lastactref,%domconfig);
     } elsif ($action eq 'usermodification') {      } elsif ($action eq 'usermodification') {
         $output = &modify_usermodification($dom,%domconfig);          $output = &modify_usermodification($dom,%domconfig);
     } elsif ($action eq 'contacts') {      } elsif ($action eq 'contacts') {
Line 710  sub process_changes { Line 753  sub process_changes {
         $output = &modify_ssl($dom,$lastactref,%domconfig);          $output = &modify_ssl($dom,$lastactref,%domconfig);
     } elsif ($action eq 'trust') {      } elsif ($action eq 'trust') {
         $output = &modify_trust($dom,$lastactref,%domconfig);          $output = &modify_trust($dom,$lastactref,%domconfig);
       } elsif ($action eq 'lti') {
           $output = &modify_lti($r,$dom,$action,$lastactref,%domconfig);
     }      }
     return $output;      return $output;
 }  }
Line 738  sub print_config_box { Line 783  sub print_config_box {
         $output =          $output =
             &Apache::lonuserutils::custom_roledefs_js($context,$crstype,$formname,\%full,               &Apache::lonuserutils::custom_roledefs_js($context,$crstype,$formname,\%full, 
                                                       \@templateroles);                                                        \@templateroles);
       } elsif ($action eq 'ltitools') {
           $output .= &ltitools_javascript($settings);
       } elsif ($action eq 'lti') {
           $output .= &lti_javascript($settings);
     }      }
     $output .=      $output .=
          '<table class="LC_nested_outer">           '<table class="LC_nested_outer">
           <tr>            <tr>
            <th align="left" valign="middle"><span class="LC_nobreak">'.             <th class="LC_left_item LC_middle"><span class="LC_nobreak">'.
            &mt($item->{text}).'&nbsp;'.             &mt($item->{text}).'&nbsp;'.
            &Apache::loncommon::help_open_topic($item->{'help'}).'</span></th>'."\n".             &Apache::loncommon::help_open_topic($item->{'help'}).'</span></th>'."\n".
           '</tr>';            '</tr>';
Line 806  sub print_config_box { Line 855  sub print_config_box {
         if (($action eq 'autoupdate') || ($action eq 'usercreation') ||          if (($action eq 'autoupdate') || ($action eq 'usercreation') ||
             ($action eq 'selfcreation') || ($action eq 'selfenrollment') ||              ($action eq 'selfcreation') || ($action eq 'selfenrollment') ||
             ($action eq 'usersessions') || ($action eq 'coursecategories') ||               ($action eq 'usersessions') || ($action eq 'coursecategories') || 
             ($action eq 'ssl') || ($action eq 'trust') || ($action eq 'contacts')) {              ($action eq 'trust') || ($action eq 'contacts') || ($action eq 'defaults')) {
             if ($action eq 'coursecategories') {              if ($action eq 'coursecategories') {
                 $output .= &print_coursecategories('middle',$dom,$item,$settings,\$rowtotal);                  $output .= &print_coursecategories('middle',$dom,$item,$settings,\$rowtotal);
                 $colspan = ' colspan="2"';                  $colspan = ' colspan="2"';
Line 857  sub print_config_box { Line 906  sub print_config_box {
              </tr>'."\n";               </tr>'."\n";
                 if ($action eq 'coursecategories') {                  if ($action eq 'coursecategories') {
                     $output .= &print_coursecategories('bottom',$dom,$item,$settings,\$rowtotal);                      $output .= &print_coursecategories('bottom',$dom,$item,$settings,\$rowtotal);
                   } elsif ($action eq 'contacts') {
                       $output .= $item->{'print'}->('lower',$dom,$settings,\$rowtotal).'
                </tr>
               </table>
              </td>
             </tr>
             <tr>
              <td>
               <table class="LC_nested">
                <tr class="LC_info_row">
                 <td class="LC_left_item"'.$colspan.'>'.&mt($item->{'header'}->[3]->{'col1'}).'</td>
                 <td class="LC_right_item"'.$colspan.'>'.&mt($item->{'header'}->[3]->{'col2'}).'</td></tr>'.
                              $item->{'print'}->('bottom',$dom,$settings,\$rowtotal).'
               </table>
             </td>
            </tr>
            <tr>';
                 } else {                  } else {
                     $output .= $item->{'print'}->('bottom',$dom,$settings,\$rowtotal);                      $output .= $item->{'print'}->('bottom',$dom,$settings,\$rowtotal);
                 }                  }
Line 866  sub print_config_box { Line 932  sub print_config_box {
                  ($action eq 'defaults') || ($action eq 'directorysrch') ||                   ($action eq 'defaults') || ($action eq 'directorysrch') ||
                  ($action eq 'helpsettings')) {                   ($action eq 'helpsettings')) {
             $output .= $item->{'print'}->('bottom',$dom,$settings,\$rowtotal);              $output .= $item->{'print'}->('bottom',$dom,$settings,\$rowtotal);
           } elsif ($action eq 'ssl') {
               $output .= $item->{'print'}->('connto',$dom,$settings,\$rowtotal).'
               </table>
             </td>
            </tr>
            <tr>
              <td>
               <table class="LC_nested">
                <tr class="LC_info_row">
                 <td class="LC_left_item"'.$colspan.'>'.&mt($item->{'header'}->[2]->{'col1'}).'</td>
                 <td class="LC_right_item"'.$colspan.'>'.&mt($item->{'header'}->[2]->{'col2'}).'</td></tr>'.
                              $item->{'print'}->('connfrom',$dom,$settings,\$rowtotal).'
               </table>
             </td>
            </tr>
            <tr>
              <td>
               <table class="LC_nested">
                <tr class="LC_info_row">
                 <td class="LC_left_item"'.$colspan.'>'.&mt($item->{'header'}->[3]->{'col1'}).'</td>
                 <td class="LC_right_item"'.$colspan.'>'.&mt($item->{'header'}->[3]->{'col2'}).'</td></tr>'.
                              $item->{'print'}->('bottom',$dom,$settings,\$rowtotal);
         } elsif ($action eq 'login') {          } elsif ($action eq 'login') {
             if ($numheaders == 4) {              if ($numheaders == 4) {
                 $output .= &print_login('page',$dom,$confname,$phase,$settings,\$rowtotal).'                  $output .= &print_login('page',$dom,$confname,$phase,$settings,\$rowtotal).'
Line 936  sub print_config_box { Line 1024  sub print_config_box {
            <td>             <td>
             <table class="LC_nested">              <table class="LC_nested">
              <tr class="LC_info_row">               <tr class="LC_info_row">
               <td class="LC_left_item"'.$colspan.' valign="top">'.&mt($item->{'header'}->[4]->{'col1'}).'</td>                <td class="LC_left_item"'.$colspan.' style="vertical-align: top">'.&mt($item->{'header'}->[4]->{'col1'}).'</td>
               <td class="LC_right_item" valign="top">'.&mt($item->{'header'}->[4]->{'col2'}).'</td>                <td class="LC_right_item" style="vertical-align: top">'.&mt($item->{'header'}->[4]->{'col2'}).'</td>
              </tr>'.               </tr>'.
             &print_validation_rows('requestcourses',$dom,$settings,\$rowtotal);              &print_validation_rows('requestcourses',$dom,$settings,\$rowtotal);
         } elsif ($action eq 'requestauthor') {          } elsif ($action eq 'requestauthor') {
Line 952  sub print_config_box { Line 1040  sub print_config_box {
            <td>             <td>
             <table class="LC_nested">              <table class="LC_nested">
              <tr class="LC_info_row">               <tr class="LC_info_row">
               <td class="LC_left_item"'.$colspan.' valign="top">'.                <td class="LC_left_item"'.$colspan.' style="vertical-align: top">'.
                &mt($item->{'header'}->[2]->{'col1'}).'</td>                 &mt($item->{'header'}->[2]->{'col1'}).'</td>
               <td class="LC_right_item" valign="top">'.                <td class="LC_right_item" style="vertical-align: top">'.
                &mt($item->{'header'}->[2]->{'col2'}).'</td>                 &mt($item->{'header'}->[2]->{'col2'}).'</td>
              </tr>'.               </tr>'.
             &print_rolecolors($phase,'author',$dom,$confname,$settings,\$rowtotal).'              &print_rolecolors($phase,'author',$dom,$confname,$settings,\$rowtotal).'
Line 982  sub print_config_box { Line 1070  sub print_config_box {
               <td class="LC_left_item" colspan="2">'.&mt($item->{'header'}->[0]->{'col1'}).'</td>';                <td class="LC_left_item" colspan="2">'.&mt($item->{'header'}->[0]->{'col1'}).'</td>';
         } elsif ($action eq 'serverstatuses') {          } elsif ($action eq 'serverstatuses') {
             $output .= '              $output .= '
               <td class="LC_left_item" valign="top">'.&mt($item->{'header'}->[0]->{'col1'}).                <td class="LC_left_item" style="vertical-align: top">'.&mt($item->{'header'}->[0]->{'col1'}).
               '<br />('.&mt('Automatic access for Dom. Coords.').')</td>';                '<br />('.&mt('Automatic access for Dom. Coords.').')</td>';
   
         } else {          } else {
             $output .= '              $output .= '
               <td class="LC_left_item" valign="top">'.&mt($item->{'header'}->[0]->{'col1'}).'</td>';                <td class="LC_left_item" style="vertical-align: top">'.&mt($item->{'header'}->[0]->{'col1'}).'</td>';
         }          }
         if (defined($item->{'header'}->[0]->{'col3'})) {          if (defined($item->{'header'}->[0]->{'col3'})) {
             $output .= '<td class="LC_left_item" valign="top">'.              $output .= '<td class="LC_left_item" style="vertical-align: top">'.
                        &mt($item->{'header'}->[0]->{'col2'});                         &mt($item->{'header'}->[0]->{'col2'});
             if ($action eq 'serverstatuses') {              if ($action eq 'serverstatuses') {
                 $output .= '<br />(<tt>'.&mt('user1:domain1,user2:domain2 etc.').'</tt>)';                  $output .= '<br />(<tt>'.&mt('user1:domain1,user2:domain2 etc.').'</tt>)';
             }               } 
         } else {          } else {
             $output .= '<td class="LC_right_item" valign="top">'.              $output .= '<td class="LC_right_item" style="vertical-align: top">'.
                        &mt($item->{'header'}->[0]->{'col2'});                         &mt($item->{'header'}->[0]->{'col2'});
         }          }
         $output .= '</td>';          $output .= '</td>';
         if ($item->{'header'}->[0]->{'col3'}) {          if ($item->{'header'}->[0]->{'col3'}) {
             if (defined($item->{'header'}->[0]->{'col4'})) {              if (defined($item->{'header'}->[0]->{'col4'})) {
                 $output .= '<td class="LC_left_item" valign="top">'.                  $output .= '<td class="LC_left_item" style="vertical-align: top">'.
                             &mt($item->{'header'}->[0]->{'col3'});                              &mt($item->{'header'}->[0]->{'col3'});
             } else {              } else {
                 $output .= '<td class="LC_right_item" valign="top">'.                  $output .= '<td class="LC_right_item" style="vertical-align: top">'.
                            &mt($item->{'header'}->[0]->{'col3'});                             &mt($item->{'header'}->[0]->{'col3'});
             }              }
             if ($action eq 'serverstatuses') {              if ($action eq 'serverstatuses') {
Line 1014  sub print_config_box { Line 1102  sub print_config_box {
             $output .= '</td>';              $output .= '</td>';
         }          }
         if ($item->{'header'}->[0]->{'col4'}) {          if ($item->{'header'}->[0]->{'col4'}) {
             $output .= '<td class="LC_right_item" valign="top">'.              $output .= '<td class="LC_right_item" style="vertical-align: top">'.
                        &mt($item->{'header'}->[0]->{'col4'});                         &mt($item->{'header'}->[0]->{'col4'});
         }          }
         $output .= '</tr>';          $output .= '</tr>';
Line 1023  sub print_config_box { Line 1111  sub print_config_box {
             $output .= &print_quotas($dom,$settings,\$rowtotal,$action);              $output .= &print_quotas($dom,$settings,\$rowtotal,$action);
         } elsif (($action eq 'autoenroll') || ($action eq 'autocreate') ||           } elsif (($action eq 'autoenroll') || ($action eq 'autocreate') || 
                  ($action eq 'serverstatuses') || ($action eq 'loadbalancing') ||                    ($action eq 'serverstatuses') || ($action eq 'loadbalancing') || 
                  ($action eq 'ltitools')) {                   ($action eq 'ltitools') || ($action eq 'lti')) {
             $output .= $item->{'print'}->($dom,$settings,\$rowtotal);              $output .= $item->{'print'}->($dom,$settings,\$rowtotal);
         } elsif ($action eq 'scantron') {          } elsif ($action eq 'scantron') {
             $output .= &print_scantronformat($r,$dom,$confname,$settings,\$rowtotal);              $output .= &print_scantronformat($r,$dom,$confname,$settings,\$rowtotal);
Line 1047  sub print_login { Line 1135  sub print_login {
         my $choice = $choices{'disallowlogin'};          my $choice = $choices{'disallowlogin'};
         $css_class = ' class="LC_odd_row"';          $css_class = ' class="LC_odd_row"';
         $datatable .= '<tr'.$css_class.'><td>'.$choice.'</td>'.          $datatable .= '<tr'.$css_class.'><td>'.$choice.'</td>'.
                       '<td align="right"><table><tr><th>'.$choices{'hostid'}.'</th>'.                        '<td style="text-align: right"><table><tr><th>'.$choices{'hostid'}.'</th>'.
                       '<th>'.$choices{'server'}.'</th>'.                        '<th>'.$choices{'server'}.'</th>'.
                       '<th>'.$choices{'serverpath'}.'</th>'.                        '<th>'.$choices{'serverpath'}.'</th>'.
                       '<th>'.$choices{'custompath'}.'</th>'.                        '<th>'.$choices{'custompath'}.'</th>'.
Line 1328  sub print_login { Line 1416  sub print_login {
         my $choice = $choices{'headtag'};          my $choice = $choices{'headtag'};
         $css_class = ' class="LC_odd_row"';          $css_class = ' class="LC_odd_row"';
         $datatable .= '<tr'.$css_class.'><td colspan="2">'.$choice.'</td>'.          $datatable .= '<tr'.$css_class.'><td colspan="2">'.$choice.'</td>'.
                       '<td align="left"><table><tr><th>'.$choices{'hostid'}.'</th>'.                        '<td style="text-align: left"><table><tr><th>'.$choices{'hostid'}.'</th>'.
                       '<th>'.$choices{'current'}.'</th>'.                        '<th>'.$choices{'current'}.'</th>'.
                       '<th>'.$choices{'action'}.'</th>'.                        '<th>'.$choices{'action'}.'</th>'.
                       '<th>'.$choices{'exempt'}.'</th></tr>'."\n";                        '<th>'.$choices{'exempt'}.'</th></tr>'."\n";
Line 1371  sub print_login { Line 1459  sub print_login {
             } else {              } else {
                 $datatable .= '<input type="file" name="loginheadtag_'.$lonhost.'" />';                  $datatable .= '<input type="file" name="loginheadtag_'.$lonhost.'" />';
             }              }
             $datatable .= '</td><td><input type="textbox" name="loginheadtagexempt_'.$lonhost.'" value="'.$exempt.'" /></td></tr>';              $datatable .= '</td><td><input type="text" name="loginheadtagexempt_'.$lonhost.'" value="'.$exempt.'" /></td></tr>';
         }          }
         $datatable .= '</table></td></tr>';          $datatable .= '</table></td></tr>';
     }      }
Line 1531  sub display_color_options { Line 1619  sub display_color_options {
     my $datatable = '<tr'.$css_class.'>'.      my $datatable = '<tr'.$css_class.'>'.
         '<td>'.$choices->{'font'}.'</td>';          '<td>'.$choices->{'font'}.'</td>';
     if (!$is_custom->{'font'}) {      if (!$is_custom->{'font'}) {
         $datatable .=  '<td>'.&mt('Default in use:').'&nbsp;<span id="css_default_'.$role.'_font" style="color: '.$defaults->{'font'}.';">'.$defaults->{'font'}.'</span></td>';          $datatable .=  '<td>'.&mt('Default in use:').'&nbsp;<span class="css_default_'.$role.'_font" style="color: '.$defaults->{'font'}.';">'.$defaults->{'font'}.'</span></td>';
     } else {      } else {
         $datatable .= '<td>&nbsp;</td>';          $datatable .= '<td>&nbsp;</td>';
     }      }
Line 1540  sub display_color_options { Line 1628  sub display_color_options {
     $datatable .= '<td><span class="LC_nobreak">'.      $datatable .= '<td><span class="LC_nobreak">'.
                   '<input type="text" class="colorchooser" size="10" name="'.$role.'_font"'.                    '<input type="text" class="colorchooser" size="10" name="'.$role.'_font"'.
                   ' value="'.$current_color.'" />&nbsp;'.                    ' value="'.$current_color.'" />&nbsp;'.
                   '&nbsp;</td></tr>';                    '&nbsp;</span></td></tr>';
     unless ($role eq 'login') {       unless ($role eq 'login') { 
         $datatable .= '<tr'.$css_class.'>'.          $datatable .= '<tr'.$css_class.'>'.
                       '<td>'.$choices->{'fontmenu'}.'</td>';                        '<td>'.$choices->{'fontmenu'}.'</td>';
         if (!$is_custom->{'fontmenu'}) {          if (!$is_custom->{'fontmenu'}) {
             $datatable .=  '<td>'.&mt('Default in use:').'&nbsp;<span id="css_default_'.$role.'_font" style="color: '.$defaults->{'fontmenu'}.';">'.$defaults->{'fontmenu'}.'</span></td>';              $datatable .=  '<td>'.&mt('Default in use:').'&nbsp;<span class="css_default_'.$role.'_font" style="color: '.$defaults->{'fontmenu'}.';">'.$defaults->{'fontmenu'}.'</span></td>';
         } else {          } else {
             $datatable .= '<td>&nbsp;</td>';              $datatable .= '<td>&nbsp;</td>';
         }          }
Line 1555  sub display_color_options { Line 1643  sub display_color_options {
                       '<input class="colorchooser" type="text" size="10" name="'                        '<input class="colorchooser" type="text" size="10" name="'
       .$role.'_fontmenu"'.        .$role.'_fontmenu"'.
                       ' value="'.$current_color.'" />&nbsp;'.                        ' value="'.$current_color.'" />&nbsp;'.
                       '&nbsp;</td></tr>';                        '&nbsp;</span></td></tr>';
     }      }
     my $switchserver = &check_switchserver($dom,$confname);      my $switchserver = &check_switchserver($dom,$confname);
     foreach my $img (@{$images}) {      foreach my $img (@{$images}) {
Line 1614  sub display_color_options { Line 1702  sub display_color_options {
                         if ($fullwidth ne '' && $fullheight ne '') {                          if ($fullwidth ne '' && $fullheight ne '') {
                             if ($fullwidth > $width && $fullheight > $height) {                               if ($fullwidth > $width && $fullheight > $height) { 
                                 my $size = $width.'x'.$height;                                  my $size = $width.'x'.$height;
                                 system("convert -sample $size $input $output");                                  my @args = ('convert','-sample',$size,$input,$output);
                                   system({$args[0]} @args);
                                 $showfile = "/$imgdir/tn-".$filename;                                  $showfile = "/$imgdir/tn-".$filename;
                             }                              }
                         }                          }
Line 1672  sub display_color_options { Line 1761  sub display_color_options {
     my $bgs_def;      my $bgs_def;
     foreach my $item (@{$bgs}) {      foreach my $item (@{$bgs}) {
         if (!$is_custom->{$item}) {          if (!$is_custom->{$item}) {
             $bgs_def .= '<td><span class="LC_nobreak">'.$choices->{$item}.'</span>&nbsp;<span id="css_default_'.$role.'_'.$item.'" style="background-color: '.$defaults->{'bgs'}{$item}.';">&nbsp;&nbsp;&nbsp;</span><br />'.$defaults->{'bgs'}{$item}.'</td>';              $bgs_def .= '<td><span class="LC_nobreak">'.$choices->{$item}.'</span>&nbsp;<span class="css_default_'.$role.'_'.$item.'" style="background-color: '.$defaults->{'bgs'}{$item}.';">&nbsp;&nbsp;&nbsp;</span><br />'.$defaults->{'bgs'}{$item}.'</td>';
         }          }
     }      }
     if ($bgs_def) {      if ($bgs_def) {
Line 1684  sub display_color_options { Line 1773  sub display_color_options {
                   '<table border="0"><tr>';                    '<table border="0"><tr>';
   
     foreach my $item (@{$bgs}) {      foreach my $item (@{$bgs}) {
         $datatable .= '<td align="center">'.$choices->{$item};          $datatable .= '<td style="text-align: center">'.$choices->{$item};
  my $color = $designs->{'bgs'}{$item} ? $designs->{'bgs'}{$item} : $defaults->{'bgs'}{$item};   my $color = $designs->{'bgs'}{$item} ? $designs->{'bgs'}{$item} : $defaults->{'bgs'}{$item};
         if ($designs->{'bgs'}{$item}) {          if ($designs->{'bgs'}{$item}) {
             $datatable .= '&nbsp;';              $datatable .= '&nbsp;';
Line 1700  sub display_color_options { Line 1789  sub display_color_options {
     my $links_def;      my $links_def;
     foreach my $item (@{$links}) {      foreach my $item (@{$links}) {
         if (!$is_custom->{$item}) {          if (!$is_custom->{$item}) {
             $links_def .= '<td>'.$choices->{$item}.'<br /><span id="css_default_'.$role.'_'.$item.'" style="color: '.$defaults->{'links'}{$item}.';">'.$defaults->{'links'}{$item}.'</span></td>';              $links_def .= '<td>'.$choices->{$item}.'<br /><span class="css_default_'.$role.'_'.$item.'" style="color: '.$defaults->{'links'}{$item}.';">'.$defaults->{'links'}{$item}.'</span></td>';
         }          }
     }      }
     if ($links_def) {      if ($links_def) {
Line 1712  sub display_color_options { Line 1801  sub display_color_options {
                   '<table border="0"><tr>';                    '<table border="0"><tr>';
     foreach my $item (@{$links}) {      foreach my $item (@{$links}) {
  my $color = $designs->{'links'}{$item} ? $designs->{'links'}{$item} : $defaults->{'links'}{$item};   my $color = $designs->{'links'}{$item} ? $designs->{'links'}{$item} : $defaults->{'links'}{$item};
         $datatable .= '<td align="center">'.$choices->{$item}."\n";          $datatable .= '<td style="text-align: center">'.$choices->{$item}."\n";
         if ($designs->{'links'}{$item}) {          if ($designs->{'links'}{$item}) {
             $datatable.='&nbsp;';              $datatable.='&nbsp;';
         }          }
Line 1773  sub login_text_colors { Line 1862  sub login_text_colors {
     my ($img,$role,$logintext,$phase,$choices,$designs,$defaults) = @_;      my ($img,$role,$logintext,$phase,$choices,$designs,$defaults) = @_;
     my $color_menu = '<table border="0"><tr>';      my $color_menu = '<table border="0"><tr>';
     foreach my $item (@{$logintext}) {      foreach my $item (@{$logintext}) {
         $color_menu .= '<td align="center">'.$choices->{$item};          $color_menu .= '<td style="text-align: center">'.$choices->{$item};
         my $color = $designs->{'logintext'}{$item} ? $designs->{'logintext'}{$item} : $defaults->{'logintext'}{$item};          my $color = $designs->{'logintext'}{$item} ? $designs->{'logintext'}{$item} : $defaults->{'logintext'}{$item};
         $color_menu .= '<br /><input type="text" class="colorchooser" size="8" name="'.$role.'_'.$item.'" value="'.$color.          $color_menu .= '<br /><input type="text" class="colorchooser" size="8" name="'.$role.'_'.$item.'" value="'.$color.
                       '" onblur = "javascript:colchg_span('."'css_".$role.'_'.$item."'".',this);" /></td>';                        '" onblur = "javascript:colchg_span('."'css_".$role.'_'.$item."'".',this);" /></td>';
Line 1786  sub image_changes { Line 1875  sub image_changes {
     my ($is_custom,$alt_text,$img_import,$showfile,$fullsize,$role,$img,$imgfile,$logincolors) = @_;      my ($is_custom,$alt_text,$img_import,$showfile,$fullsize,$role,$img,$imgfile,$logincolors) = @_;
     my $output;      my $output;
     if ($img eq 'login') {      if ($img eq 'login') {
             # suppress image for Log-in header          $output = '</td><td>'.$logincolors; # suppress image for Log-in header
     } elsif (!$is_custom) {      } elsif (!$is_custom) {
         if ($img ne 'domlogo') {          if ($img ne 'domlogo') {
             $output .= &mt('Default image:').'<br />';              $output = &mt('Default image:').'<br />';
         } else {          } else {
             $output .= &mt('Default in use:').'<br />';              $output = &mt('Default in use:').'<br />';
         }          }
     }      }
     if ($img eq 'login') { # suppress image for Log-in header      if ($img ne 'login') {
         $output .= '<td>'.$logincolors;  
     } else {  
         if ($img_import) {          if ($img_import) {
             $output .= '<input type="hidden" name="'.$role.'_import_'.$img.'" value="'.$imgfile.'" />';              $output .= '<input type="hidden" name="'.$role.'_import_'.$img.'" value="'.$imgfile.'" />';
         }          }
Line 1808  sub image_changes { Line 1895  sub image_changes {
                        $role.'_del_'.$img.'" value="1" />'.&mt('Delete?').                         $role.'_del_'.$img.'" value="1" />'.&mt('Delete?').
                        '</label>&nbsp;'.&mt('Replace:').'</span><br />';                         '</label>&nbsp;'.&mt('Replace:').'</span><br />';
         } else {          } else {
             $output .= '<td valign="middle">'.$logincolors.&mt('Upload:').'<br />';              $output .= '<td class="LC_middle">'.$logincolors.&mt('Upload:').'<br />';
         }          }
     }      }
     return $output;      return $output;
Line 1827  sub print_quotas { Line 1914  sub print_quotas {
     my $typecount = 0;      my $typecount = 0;
     my ($css_class,%titles);      my ($css_class,%titles);
     if ($context eq 'requestcourses') {      if ($context eq 'requestcourses') {
         @usertools = ('official','unofficial','community','textbook','placement');          @usertools = ('official','unofficial','community','textbook','placement','lti');
         @options =('norequest','approval','validate','autolimit');          @options =('norequest','approval','validate','autolimit');
         %validations = &Apache::lonnet::auto_courserequest_checks($dom);          %validations = &Apache::lonnet::auto_courserequest_checks($dom);
         %titles = &courserequest_titles();          %titles = &courserequest_titles();
Line 2240  sub print_quotas { Line 2327  sub print_quotas {
 }  }
   
 sub print_requestmail {  sub print_requestmail {
     my ($dom,$action,$settings,$rowtotal) = @_;      my ($dom,$action,$settings,$rowtotal,$customcss,$rowstyle) = @_;
     my ($now,$datatable,%currapp);      my ($now,$datatable,%currapp);
     $now = time;      $now = time;
     if (ref($settings) eq 'HASH') {      if (ref($settings) eq 'HASH') {
Line 2252  sub print_requestmail { Line 2339  sub print_requestmail {
     }      }
     my $numinrow = 2;      my $numinrow = 2;
     my $css_class;      my $css_class;
     $css_class = ($$rowtotal%2? ' class="LC_odd_row"':'');      if ($$rowtotal%2) {
           $css_class = 'LC_odd_row';
       }
       if ($customcss) {
           $css_class .= " $customcss";
       }
       $css_class =~ s/^\s+//;
       if ($css_class) {
           $css_class = ' class="'.$css_class.'"';
       }
       if ($rowstyle) {
           $css_class .= ' style="'.$rowstyle.'"';
       }
     my $text;      my $text;
     if ($action eq 'requestcourses') {      if ($action eq 'requestcourses') {
         $text = &mt('Receive notification of course requests requiring approval');          $text = &mt('Receive notification of course requests requiring approval');
Line 2279  sub print_studentcode { Line 2378  sub print_studentcode {
     my ($settings,$rowtotal) = @_;      my ($settings,$rowtotal) = @_;
     my $rownum = 0;       my $rownum = 0; 
     my ($output,%current);      my ($output,%current);
     my @crstypes = ('official','unofficial','community','textbook','placement');      my @crstypes = ('official','unofficial','community','textbook','placement','lti');
     if (ref($settings) eq 'HASH') {      if (ref($settings) eq 'HASH') {
         if (ref($settings->{'uniquecode'}) eq 'HASH') {          if (ref($settings->{'uniquecode'}) eq 'HASH') {
             foreach my $type (@crstypes) {              foreach my $type (@crstypes) {
Line 2406  sub print_textbookcourses { Line 2505  sub print_textbookcourses {
         $datatable .= '<option value="'.$k.'"'.$selstr.'>'.$vpos.'</option>';          $datatable .= '<option value="'.$k.'"'.$selstr.'>'.$vpos.'</option>';
     }      }
     $datatable .= '</select>&nbsp;'."\n".      $datatable .= '</select>&nbsp;'."\n".
                   '<input type="checkbox" name="'.$type.'_addbook" value="1" />'.&mt('Add').'</td>'."\n".                    '<input type="checkbox" name="'.$type.'_addbook" value="1" />'.&mt('Add').'</span></td>'."\n".
                   '<td colspan="2">'.                    '<td colspan="2">'.
                   '<span class="LC_nobreak">'.&mt('Subject:').'<input type="text" size="15" name="'.$type.'_addbook_subject" value="" /></span> '."\n".                    '<span class="LC_nobreak">'.&mt('Subject:').'<input type="text" size="15" name="'.$type.'_addbook_subject" value="" /></span> '."\n".
                   ('&nbsp;'x2).                    ('&nbsp;'x2).
Line 2423  sub print_textbookcourses { Line 2522  sub print_textbookcourses {
         } else {          } else {
             $datatable .= '<input type="file" name="'.$type.'_addbook_image" value="" />';              $datatable .= '<input type="file" name="'.$type.'_addbook_image" value="" />';
         }          }
           $datatable .= '</span>'."\n";
     }      }
     $datatable .= '</span>'."\n".      $datatable .= '<span class="LC_nobreak">'.&mt('LON-CAPA course:').'&nbsp;'.
                   '<span class="LC_nobreak">'.&mt('LON-CAPA course:').'&nbsp;'.  
                   &Apache::loncommon::select_dom_form($env{'request.role.domain'},$type.'_addbook_cdom').                    &Apache::loncommon::select_dom_form($env{'request.role.domain'},$type.'_addbook_cdom').
                   '<input type="text" size="25" name="'.$type.'_addbook_cnum" value="" />'.                    '<input type="text" size="25" name="'.$type.'_addbook_cnum" value="" />'.
                   &Apache::loncommon::selectcourse_link                    &Apache::loncommon::selectcourse_link
                       ('display',$type.'_addbook_cnum',$type.'_addbook_cdom',undef,undef,undef,'Course');                        ('display',$type.'_addbook_cnum',$type.'_addbook_cdom',undef,undef,undef,'Course').
                   '</span></td>'."\n".                    '</span></td>'."\n".
                   '</tr>'."\n";                    '</tr>'."\n";
     $itemcount ++;      $itemcount ++;
Line 2531  ENDSCRIPT Line 2630  ENDSCRIPT
   
 sub ltitools_javascript {  sub ltitools_javascript {
     my ($settings) = @_;      my ($settings) = @_;
     return unless(ref($settings) eq 'HASH');      my $togglejs = &ltitools_toggle_js();
       unless (ref($settings) eq 'HASH') {
           return $togglejs;
       }
     my (%ordered,$total,%jstext);      my (%ordered,$total,%jstext);
     $total = 0;      $total = 0;
     foreach my $item (keys(%{$settings})) {      foreach my $item (keys(%{$settings})) {
Line 2549  sub ltitools_javascript { Line 2651  sub ltitools_javascript {
     return <<"ENDSCRIPT";      return <<"ENDSCRIPT";
 <script type="text/javascript">  <script type="text/javascript">
 // <![CDATA[  // <![CDATA[
 function reorderLTI(form,item) {  function reorderLTITools(form,item) {
     var changedVal;      var changedVal;
 $jstext  $jstext
     var newpos = 'ltitools_add_pos';      var newpos = 'ltitools_add_pos';
Line 2594  $jstext Line 2696  $jstext
 // ]]>  // ]]>
 </script>  </script>
   
   $togglejs
   
   ENDSCRIPT
   }
   
   sub ltitools_toggle_js {
       return <<"ENDSCRIPT";
   <script type="text/javascript">
   // <![CDATA[
   
   function toggleLTITools(form,setting,item) {
       var radioname = '';
       var divid = '';
       if ((setting == 'passback') || (setting == 'roster')) {
           radioname = 'ltitools_'+setting+'_'+item;
           divid = 'ltitools_'+setting+'time_'+item;
           var num = form.elements[radioname].length;
           if (num) {
               var setvis = '';
               for (var i=0; i<num; i++) {
                   if (form.elements[radioname][i].checked) {
                       if (form.elements[radioname][i].value == '1') {
                           if (document.getElementById(divid)) {
                               document.getElementById(divid).style.display = 'inline-block';
                           }
                           setvis = 1;
                       }
                       break;
                   }
               }
           }
           if (!setvis) {
               if (document.getElementById(divid)) {
                   document.getElementById(divid).style.display = 'none';
               }
           }
       }
       if (setting == 'user') {
           divid = 'ltitools_'+setting+'_div_'+item;
           var checkid = 'ltitools_'+setting+'_field_'+item;
           if (document.getElementById(divid)) {
               if (document.getElementById(checkid)) {
                   if (document.getElementById(checkid).checked) {
                       document.getElementById(divid).style.display = 'inline-block';
                   } else {
                       document.getElementById(divid).style.display = 'none';
                   }
               }
           }
       }
       return;
   }
   // ]]>
   </script>
   
   ENDSCRIPT
   }
   
   sub lti_javascript {
       my ($settings) = @_;
       my $togglejs = &lti_toggle_js();
       unless (ref($settings) eq 'HASH') {
           return $togglejs;
       }
       my (%ordered,$total,%jstext);
       $total = 0;
       foreach my $item (keys(%{$settings})) {
           if (ref($settings->{$item}) eq 'HASH') {
               my $num = $settings->{$item}{'order'};
               $ordered{$num} = $item;
           }
       }
       $total = scalar(keys(%{$settings}));
       my @jsarray = ();
       foreach my $item (sort {$a <=> $b } (keys(%ordered))) {
           push(@jsarray,$ordered{$item});
       }
       my $jstext = '    var lti = Array('."'".join("','",@jsarray)."'".');'."\n";
       return <<"ENDSCRIPT";
   <script type="text/javascript">
   // <![CDATA[
   function reorderLTI(form,item) {
       var changedVal;
   $jstext
       var newpos = 'lti_pos_add';
       var maxh = 1 + $total;
       var current = new Array;
       var newitemVal = form.elements[newpos].options[form.elements[newpos].selectedIndex].value;
       if (item == newpos) {
           changedVal = newitemVal;
       } else {
           changedVal = form.elements[item].options[form.elements[item].selectedIndex].value;
           current[newitemVal] = newpos;
       }
       for (var i=0; i<lti.length; i++) {
           var elementName = 'lti_pos_'+lti[i];
           if (elementName != item) {
               if (form.elements[elementName]) {
                   var currVal = form.elements[elementName].options[form.elements[elementName].selectedIndex].value;
                   current[currVal] = elementName;
               }
           }
       }
       var oldVal;
       for (var j=0; j<maxh; j++) {
           if (current[j] == undefined) {
               oldVal = j;
           }
       }
       if (oldVal < changedVal) {
           for (var k=oldVal+1; k<=changedVal ; k++) {
              var elementName = current[k];
              form.elements[elementName].selectedIndex = form.elements[elementName].selectedIndex - 1;
           }
       } else {
           for (var k=changedVal; k<oldVal; k++) {
               var elementName = current[k];
               form.elements[elementName].selectedIndex = form.elements[elementName].selectedIndex + 1;
           }
       }
       return;
   }
   // ]]>
   </script>
   
   $togglejs
   
   ENDSCRIPT
   }
   
   sub lti_toggle_js {
       my %lcauthparmtext = &Apache::lonlocal::texthash (
                               localauth => 'Local auth argument',
                               krb       => 'Kerberos domain',
                            );
       return <<"ENDSCRIPT";
   <script type="text/javascript">
   // <![CDATA[
   
   function toggleLTI(form,setting,item) {
       if (setting == 'requser') {
           var fieldsets = document.getElementsByClassName('ltioption_'+item);
           if (fieldsets.length) {
               var radioname = 'lti_'+setting+'_'+item;
               var num = form.elements[radioname].length;
               if (num) {
                   var setvis = '';
                   for (var i=0; i<num; i++) {
                       if (form.elements[radioname][i].checked) {
                           if (form.elements[radioname][i].value == '1') {
                              setvis = 1;
                              break;
                           }
                       }
                   }
                   for (var j=0; j<fieldsets.length; j++) { 
                       if (setvis) {
                           fieldsets[j].style.display = 'block';
                       } else {
                           fieldsets[j].style.display = 'none';
                       }
                   }
               }
           }
       } else if ((setting == 'user') || (setting == 'crs') || (setting == 'passback')) {
           var radioname = '';
           var divid = '';
           if (setting == 'user') {
               radioname = 'lti_mapuser_'+item;
               divid = 'lti_userfield_'+item;
           } else if (setting == 'crs') {
               radioname = 'lti_mapcrs_'+item;
               divid = 'lti_crsfield_'+item;
           } else {
               radioname = 'lti_passbackformat_'+item;
               divid =  'lti_passback_'+item;
           }
           var num = form.elements[radioname].length;
           if (num) {
               var setvis = '';
               for (var i=0; i<num; i++) {
                  if (form.elements[radioname][i].checked) {
                      if (setting == 'passback') {
                          if (form.elements[radioname][i].value == '1') {
                              if (document.getElementById(divid)) {
                                  document.getElementById(divid).style.display = 'inline-block';
                              }
                              setvis = 1;
                              break;
                          }
                      } else {
                          if (form.elements[radioname][i].value == 'other') {
                              if (document.getElementById(divid)) {
                                  document.getElementById(divid).style.display = 'inline-block';
                              }
                              setvis = 1;
                              break;
                          }
                      }
                  } 
               }
               if (!setvis) {
                   if (document.getElementById(divid)) {
                       document.getElementById(divid).style.display = 'none';
                   }
               }
           }
       } else if ((setting == 'sec') || (setting == 'secsrc')) {
           var numsec = form.elements['lti_crssec_'+item].length;
           if (numsec) {
               var setvis = '';
               for (var i=0; i<numsec; i++) {
                   if (form.elements['lti_crssec_'+item][i].checked) {
                       if (form.elements['lti_crssec_'+item][i].value == '1') {
                           if (document.getElementById('lti_crssecfield_'+item)) {
                               document.getElementById('lti_crssecfield_'+item).style.display = 'inline-block';
                               setvis = 1;
                               var numsrcsec = form.elements['lti_crssecsrc_'+item].length;
                               if (numsrcsec) {
                                   var setsrcvis = '';
                                   for (var j=0; j<numsrcsec; j++) {
                                       if (form.elements['lti_crssecsrc_'+item][j].checked) {
                                           if (form.elements['lti_crssecsrc_'+item][j].value == 'other') {
                                               if (document.getElementById('lti_secsrcfield_'+item)) {
                                                   document.getElementById('lti_secsrcfield_'+item).style.display = 'inline-block';
                                                   setsrcvis = 1;
                                               }
                                           }
                                       }
                                   }
                                   if (!setsrcvis) {
                                       if (document.getElementById('lti_secsrcfield_'+item)) {
                                           document.getElementById('lti_secsrcfield_'+item).style.display = 'none';
                                       }
                                   }
                               }
                           }
                       }
                   }
               }
               if (!setvis) {
                   if (document.getElementById('lti_crssecfield_'+item)) {
                       document.getElementById('lti_crssecfield_'+item).style.display = 'none';
                   }
                   if (document.getElementById('lti_secsrcfield_'+item)) {
                       document.getElementById('lti_secsrcfield_'+item).style.display = 'none';
                   }
               }
           }
       } else if (setting == 'lcauth') {
           var numauth = form.elements['lti_lcauth_'+item].length;
           if (numauth) {
               for (var i=0; i<numauth; i++) {
                   if (form.elements['lti_lcauth_'+item][i].checked) {
                       if (document.getElementById('lti_'+setting+'_parmrow_'+item)) {
                           if ((form.elements['lti_'+setting+'_'+item][i].value == 'internal') || (form.elements['lti_'+setting+'_'+item][i].value == 'lti')) {
                               document.getElementById('lti_'+setting+'_parmrow_'+item).style.display = 'none';
                           } else {
                               document.getElementById('lti_'+setting+'_parmrow_'+item).style.display = 'table-row';
                               if (document.getElementById('lti_'+setting+'_parmtext_'+item)) {
                                   if (form.elements['lti_'+setting+'_'+item][i].value == 'localauth') {
                                       document.getElementById('lti_'+setting+'_parmtext_'+item).innerHTML = "$lcauthparmtext{'localauth'}";
                                   } else {
                                       document.getElementById('lti_'+setting+'_parmtext_'+item).innerHTML = "$lcauthparmtext{'krb'}";
                                   }
                               }
                           }
                       }
                   }
               }
           }
       } else if (setting == 'lcmenu') {
           var menus = new Array('lti_topmenu_'+item,'lti_inlinemenu_'+item);
           var divid = 'lti_menufield_'+item;
           var setvis = '';
           for (var i=0; i<menus.length; i++) {
               var radioname = menus[i];  
               var num = form.elements[radioname].length;
               if (num) {
                   for (var j=0; j<num; j++) {
                       if (form.elements[radioname][j].checked) {
                           if (form.elements[radioname][j].value == '1') {
                               if (document.getElementById(divid)) {
                                   document.getElementById(divid).style.display = 'inline-block';
                               }
                               setvis = 1;
                               break;
                           }
                       }
                   }
               }
               if (setvis == 1) {
                   break;
               }
           }
           if (!setvis) {
               if (document.getElementById(divid)) {
                   document.getElementById(divid).style.display = 'none';
               }
           }
       }
       return;
   }
   // ]]>
   </script>
   
 ENDSCRIPT  ENDSCRIPT
 }  }
   
Line 2676  sub print_autoenroll { Line 3084  sub print_autoenroll {
                   '<td>'.&mt('Failsafe for no drops when institutional data missing').'</td>'.                    '<td>'.&mt('Failsafe for no drops when institutional data missing').'</td>'.
                   '<td class="LC_right_item"><span class="LC_nobreak">'.                    '<td class="LC_right_item"><span class="LC_nobreak">'.
                   '<input type="text" name="autoenroll_failsafe"'.                    '<input type="text" name="autoenroll_failsafe"'.
                   ' value="'.$failsafe.'" size="4" /></td></tr>';                    ' value="'.$failsafe.'" size="4" /></span></td></tr>';
     $$rowtotal += 4;      $$rowtotal += 4;
     return $datatable;      return $datatable;
 }  }
Line 2725  sub print_autoupdate { Line 3133  sub print_autoupdate {
         my $locknamesettings;          my $locknamesettings;
         $datatable .= &insttypes_row($settings,$types,$usertypes,          $datatable .= &insttypes_row($settings,$types,$usertypes,
                                      $dom,$numinrow,$othertitle,                                       $dom,$numinrow,$othertitle,
                                     'lockablenames');                                      'lockablenames',$rowtotal);
         $$rowtotal ++;          $$rowtotal ++;
     } else {      } else {
         my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom);          my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom);
Line 2868  sub print_directorysrch { Line 3276  sub print_directorysrch {
         if (ref($usertypes) eq 'HASH') {          if (ref($usertypes) eq 'HASH') {
             if (keys(%{$usertypes}) > 0) {              if (keys(%{$usertypes}) > 0) {
                 $datatable .= &insttypes_row($settings,$types,$usertypes,$dom,                  $datatable .= &insttypes_row($settings,$types,$usertypes,$dom,
                                              $numinrow,$othertitle,'cansearch');                                               $numinrow,$othertitle,'cansearch',
                                                $rowtotal);
                 $cansrchrow = 1;                  $cansrchrow = 1;
             }              }
         }          }
Line 2957  sub print_contacts { Line 3366  sub print_contacts {
     my $datatable;      my $datatable;
     my @contacts = ('adminemail','supportemail');      my @contacts = ('adminemail','supportemail');
     my (%checked,%to,%otheremails,%bccemails,%includestr,%includeloc,%currfield,      my (%checked,%to,%otheremails,%bccemails,%includestr,%includeloc,%currfield,
         $maxsize,$fields,$fieldtitles,$fieldoptions,$possoptions,@mailings);          $maxsize,$fields,$fieldtitles,$fieldoptions,$possoptions,@mailings,%lonstatus);
     foreach my $type (@mailings) {  
         $otheremails{$type} = '';  
     }  
     if ($position eq 'top') {      if ($position eq 'top') {
         if (ref($settings) eq 'HASH') {          if (ref($settings) eq 'HASH') {
             foreach my $item (@contacts) {              foreach my $item (@contacts) {
Line 2972  sub print_contacts { Line 3378  sub print_contacts {
     } elsif ($position eq 'middle') {      } elsif ($position eq 'middle') {
         @mailings = ('errormail','packagesmail','lonstatusmail','requestsmail',          @mailings = ('errormail','packagesmail','lonstatusmail','requestsmail',
                      'updatesmail','idconflictsmail');                       'updatesmail','idconflictsmail');
           foreach my $type (@mailings) {
               $otheremails{$type} = '';
           }
       } elsif ($position eq 'lower') {
           if (ref($settings) eq 'HASH') {
               if (ref($settings->{'lonstatus'}) eq 'HASH') {
                   %lonstatus = %{$settings->{'lonstatus'}};
               }
           }
     } else {      } else {
         @mailings = ('helpdeskmail','otherdomsmail');          @mailings = ('helpdeskmail','otherdomsmail');
           foreach my $type (@mailings) {
               $otheremails{$type} = '';
           }
         $bccemails{'helpdeskmail'} = '';          $bccemails{'helpdeskmail'} = '';
         $bccemails{'otherdomsmail'} = '';          $bccemails{'otherdomsmail'} = '';
         $includestr{'helpdeskmail'} = '';          $includestr{'helpdeskmail'} = '';
Line 2981  sub print_contacts { Line 3399  sub print_contacts {
         ($fields,$fieldtitles,$fieldoptions,$possoptions) = &helpform_fields();          ($fields,$fieldtitles,$fieldoptions,$possoptions) = &helpform_fields();
     }      }
     if (ref($settings) eq 'HASH') {      if (ref($settings) eq 'HASH') {
         unless ($position eq 'top') {          unless (($position eq 'top') || ($position eq 'lower')) {
             foreach my $type (@mailings) {              foreach my $type (@mailings) {
                 if (exists($settings->{$type})) {                  if (exists($settings->{$type})) {
                     if (ref($settings->{$type}) eq 'HASH') {                      if (ref($settings->{$type}) eq 'HASH') {
Line 3021  sub print_contacts { Line 3439  sub print_contacts {
                 if (exists($settings->{'helpform'}{'maxsize'})) {                  if (exists($settings->{'helpform'}{'maxsize'})) {
                     $maxsize = $settings->{'helpform'}{'maxsize'};                      $maxsize = $settings->{'helpform'}{'maxsize'};
                 } else {                  } else {
                     $maxsize = '1.0';                       $maxsize = '1.0';
                 }                  }
             } else {              } else {
                 if (ref($fields) eq 'ARRAY') {                  if (ref($fields) eq 'ARRAY') {
Line 3038  sub print_contacts { Line 3456  sub print_contacts {
             $to{'adminemail'} = $Apache::lonnet::perlvar{'lonAdmEMail'};              $to{'adminemail'} = $Apache::lonnet::perlvar{'lonAdmEMail'};
             $checked{'errormail'}{'adminemail'} = ' checked="checked" ';              $checked{'errormail'}{'adminemail'} = ' checked="checked" ';
             $checked{'packagesmail'}{'adminemail'} = ' checked="checked" ';              $checked{'packagesmail'}{'adminemail'} = ' checked="checked" ';
             $checked{'lonstatusmail'}{'adminemail'} = ' checked="checked" ';               $checked{'lonstatusmail'}{'adminemail'} = ' checked="checked" ';
             $checked{'requestsmail'}{'adminemail'} = ' checked="checked" ';              $checked{'requestsmail'}{'adminemail'} = ' checked="checked" ';
             $checked{'updatesmail'}{'adminemail'} = ' checked="checked" ';              $checked{'updatesmail'}{'adminemail'} = ' checked="checked" ';
             $checked{'idconflictsmail'}{'adminemail'} = ' checked="checked" ';              $checked{'idconflictsmail'}{'adminemail'} = ' checked="checked" ';
Line 3066  sub print_contacts { Line 3484  sub print_contacts {
                           $to{$item}.'" /></td></tr>';                            $to{$item}.'" /></td></tr>';
             $rownum ++;              $rownum ++;
         }          }
     } else {      } elsif ($position eq 'bottom') {
           $css_class = $rownum%2?' class="LC_odd_row"':'';
           $datatable .= '<tr'.$css_class.'>'.
                         '<td>'.&mt('Extra helpdesk form fields:').'<br />'.
                         &mt('(e-mail, subject, and description always shown)').
                         '</td><td class="LC_left_item">';
           if ((ref($fields) eq 'ARRAY') && (ref($fieldtitles) eq 'HASH') &&
               (ref($fieldoptions) eq 'HASH') && (ref($possoptions) eq 'HASH')) {
               $datatable .= '<table><tr><th>'.&mt('Field').'</th><th>'.&mt('Status').'</th></tr>';
               foreach my $field (@{$fields}) {
                   $datatable .= '<tr><td>'.$fieldtitles->{$field};
                   if (($field eq 'screenshot') || ($field eq 'cc')) {
                       $datatable .= ' '.&mt('(logged-in users)');
                   }
                   $datatable .='</td><td>';
                   my $clickaction;
                   if ($field eq 'screenshot') {
                       $clickaction = ' onclick="screenshotSize(this);"';
                   }
                   if (ref($possoptions->{$field}) eq 'ARRAY') {
                       foreach my $option (@{$possoptions->{$field}}) {
                           my $checked;
                           if ($currfield{$field} eq $option) {
                               $checked = ' checked="checked"';
                           }
                           $datatable .= '<span class="LC_nobreak"><label>'.
                                         '<input type="radio" name="helpform_'.$field.'" '.
                                         'value="'.$option.'"'.$checked.$clickaction.' />'.$fieldoptions->{$option}.
                                         '</label></span>'.('&nbsp;'x2);
                       }
                   }
                   if ($field eq 'screenshot') {
                       my $display;
                       if ($currfield{$field} eq 'no') {
                           $display = ' style="display:none"';
                       }
                       $datatable .= '</td></tr><tr id="help_screenshotsize"'.$display.'>'.
                                     '<td>'.&mt('Maximum size for upload (MB)').'</td><td>'.
                                     '<input type="text" size="5" name="helpform_maxsize" value="'.$maxsize.'" />';
                   }
                   $datatable .= '</td></tr>';
               }
               $datatable .= '</table>';
           }
           $datatable .= '</td></tr>'."\n";
           $rownum ++;
       }
       unless (($position eq 'top') || ($position eq 'lower')) {
         foreach my $type (@mailings) {          foreach my $type (@mailings) {
             $css_class = $rownum%2?' class="LC_odd_row"':'';              $css_class = $rownum%2?' class="LC_odd_row"':'';
             $datatable .= '<tr'.$css_class.'>'.              $datatable .= '<tr'.$css_class.'>'.
Line 3100  sub print_contacts { Line 3565  sub print_contacts {
                               'value="'.$bccemails{$type}.'"  /></fieldset>'.                                'value="'.$bccemails{$type}.'"  /></fieldset>'.
                               '<fieldset><legend>'.&mt('Optional added text').'</legend>'.                                '<fieldset><legend>'.&mt('Optional added text').'</legend>'.
                               &mt('Text automatically added to e-mail:').' '.                                &mt('Text automatically added to e-mail:').' '.
                               '<input type="text" name="'.$type.'_includestr" value="'.$includestr{$type}.'" /><br >'.                                '<input type="text" name="'.$type.'_includestr" value="'.$includestr{$type}.'" /><br />'.
                               '<span class="LC_nobreak">'.&mt('Location:').'&nbsp;'.                                '<span class="LC_nobreak">'.&mt('Location:').'&nbsp;'.
                               '<label><input type="radio" name="'.$type.'_includeloc" value="s"'.$locchecked{'s'}.' />'.&mt('in subject').'</label>'.                                '<label><input type="radio" name="'.$type.'_includeloc" value="s"'.$locchecked{'s'}.' />'.&mt('in subject').'</label>'.
                               ('&nbsp;'x2).                                ('&nbsp;'x2).
Line 3113  sub print_contacts { Line 3578  sub print_contacts {
     }      }
     if ($position eq 'middle') {      if ($position eq 'middle') {
         my %choices;          my %choices;
         $choices{'reporterrors'} = &mt('E-mail error reports to [_1]',          my $corelink = &core_link_msu();
                                     &Apache::loncommon::modal_link('http://loncapa.org/core.html',          $choices{'reporterrors'} = &mt('E-mail error reports to [_1]',$corelink);
                                     &mt('LON-CAPA core group - MSU'),600,500));  
         $choices{'reportupdates'} = &mt('E-mail record of completed LON-CAPA updates to [_1]',          $choices{'reportupdates'} = &mt('E-mail record of completed LON-CAPA updates to [_1]',
                                         &Apache::loncommon::modal_link('http://loncapa.org/core.html',                                          $corelink);
                                         &mt('LON-CAPA core group - MSU'),600,500));          $choices{'reportstatus'} = &mt('E-mail status if errors above threshold to [_1]',$corelink);
         my @toggles = ('reporterrors','reportupdates');          my @toggles = ('reporterrors','reportupdates','reportstatus');
         my %defaultchecked = ('reporterrors'  => 'on',          my %defaultchecked = ('reporterrors'  => 'on',
                               'reportupdates' => 'on');                                'reportupdates' => 'on',
                                 'reportstatus'  => 'on');
         (my $reports,$rownum) = &radiobutton_prefs($settings,\@toggles,\%defaultchecked,          (my $reports,$rownum) = &radiobutton_prefs($settings,\@toggles,\%defaultchecked,
                                                    \%choices,$rownum);                                                     \%choices,$rownum);
         $datatable .= $reports;          $datatable .= $reports;
     } elsif ($position eq 'bottom') {      } elsif ($position eq 'lower') {
         $css_class = $rownum%2?' class="LC_odd_row"':'';          $css_class = $rownum%2?' class="LC_odd_row"':'';
         $datatable .= '<tr'.$css_class.'>'.          my ($threshold,$sysmail,%excluded,%weights);
                       '<td>'.&mt('Extra helpdesk form fields:').'<br />'.          my ($defaults,$names) = &Apache::loncommon::lon_status_items();
                       &mt('(e-mail, subject, and description always shown)').          if ($lonstatus{'threshold'} =~ /^\d+$/) {
                       '</td><td class="LC_left_item">';              $threshold = $lonstatus{'threshold'};
         if ((ref($fields) eq 'ARRAY') && (ref($fieldtitles) eq 'HASH') &&           } else {
             (ref($fieldoptions) eq 'HASH') && (ref($possoptions) eq 'HASH')) {              $threshold = $defaults->{'threshold'};
             $datatable .= '<table><tr><th>'.&mt('Field').'</th><th>'.&mt('Status').'</th></tr>';          }
             foreach my $field (@{$fields}) {          if ($lonstatus{'sysmail'} =~ /^\d+$/) {
                 $datatable .= '<tr><td>'.$fieldtitles->{$field};              $sysmail = $lonstatus{'sysmail'};
                 if (($field eq 'screenshot') || ($field eq 'cc')) {          } else {
                     $datatable .= ' '.&mt('(logged-in users)');              $sysmail = $defaults->{'sysmail'};
           }
           if (ref($lonstatus{'weights'}) eq 'HASH') {
               foreach my $type ('E','W','N','U') {
                   if ($lonstatus{'weights'}{$type} =~ /^\d+$/) {
                       $weights{$type} = $lonstatus{'weights'}{$type};
                   } else {
                       $weights{$type} = $defaults->{$type};
                 }                  }
                 $datatable .='</td><td>';              }
                 my $clickaction;          } else {
                 if ($field eq 'screenshot') {              foreach my $type ('E','W','N','U') {
                     $clickaction = ' onclick="screenshotSize(this);"';                  $weights{$type} = $defaults->{$type};
               }
           }
           if (ref($lonstatus{'excluded'}) eq 'ARRAY') {
               if (@{$lonstatus{'excluded'}} > 0) {
                   map {$excluded{$_} = 1; } @{$lonstatus{'excluded'}};
               }
           }
           $datatable .= '<tr'.$css_class.'>'.
                         '<td class="LC_left_item"><span class="LC_nobreak">'.
                         $titles->{'errorthreshold'}.
                         '</span></td><td class="LC_left_item">'.
                         '<input type="text" name="errorthreshold" value="'.
                         $threshold.'" size="5" /></td></tr>';
           $rownum ++;
           $css_class = $rownum%2?' class="LC_odd_row"':'';
           $datatable .= '<tr'.$css_class.'>'.
                         '<td class="LC_left_item">'.
                         '<span class="LC_nobreak">'.$titles->{'errorweights'}.
                         '</span></td><td class="LC_left_item"><table><tr>';
           foreach my $type ('E','W','N','U') {
               $datatable .= '<td>'.$names->{$type}.'<br />'.
                             '<input type="text" name="errorweights_'.$type.'" value="'.
                             $weights{$type}.'" size="5" /></td>';
           }
           $datatable .= '</tr></table></tr>';
           $rownum ++;
           $css_class = $rownum%2?' class="LC_odd_row"':'';
           $datatable .= '<tr'.$css_class.'><td class="LC_left_item">'.
                         $titles->{'errorexcluded'}.'</td>'.
                         '<td class="LC_left_item"><table>';
           my $numinrow = 4;
           my @ids = sort(values(%Apache::lonnet::serverhomeIDs));
           for (my $i=0; $i<@ids; $i++) {
               my $rem = $i%($numinrow);
               if ($rem == 0) {
                   if ($i > 0) {
                       $datatable .= '</tr>';
                 }                  }
                 if (ref($possoptions->{$field}) eq 'ARRAY') {                  $datatable .= '<tr>';
                     foreach my $option (@{$possoptions->{$field}}) {              }
                         my $checked;              my $check;
                         if ($currfield{$field} eq $option) {              if ($excluded{$ids[$i]}) {
                             $checked = ' checked="checked"';                  $check = ' checked="checked" ';
               }
               $datatable .= '<td class="LC_left_item">'.
                             '<span class="LC_nobreak"><label>'.
                             '<input type="checkbox" name="errorexcluded" '.
                             'value="'.$ids[$i].'"'.$check.' />'.
                             $ids[$i].'</label></span></td>';
           }
           my $colsleft = $numinrow - @ids%($numinrow);
           if ($colsleft > 1 ) {
               $datatable .= '<td colspan="'.$colsleft.'" class="LC_left_item">'.
                             '&nbsp;</td>';
           } elsif ($colsleft == 1) {
               $datatable .= '<td class="LC_left_item">&nbsp;</td>';
           }
           $datatable .= '</tr></table></td></tr>';
           $rownum ++;
           $css_class = $rownum%2?' class="LC_odd_row"':'';
           $datatable .= '<tr'.$css_class.'>'.
                         '<td class="LC_left_item"><span class="LC_nobreak">'.
                         $titles->{'errorsysmail'}.
                         '</span></td><td class="LC_left_item">'.
                         '<input type="text" name="errorsysmail" value="'.
                         $sysmail.'" size="5" /></td></tr>';
           $rownum ++;
       } elsif ($position eq 'bottom') {
           my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom);
           my (@posstypes,%usertypeshash);
           if (ref($types) eq 'ARRAY') {
               @posstypes = @{$types};
           }
           if (@posstypes) {
               if (ref($usertypes) eq 'HASH') {
                   %usertypeshash = %{$usertypes};
               }
               my @overridden;
               my $numinrow = 4;
               if (ref($settings) eq 'HASH') {
                   if (ref($settings->{'overrides'}) eq 'HASH') {
                       foreach my $key (sort(keys(%{$settings->{'overrides'}}))) {
                           if (ref($settings->{'overrides'}{$key}) eq 'HASH') {
                               push(@overridden,$key);
                               foreach my $item (@contacts) {
                                   if ($settings->{'overrides'}{$key}{$item}) {
                                       $checked{'override_'.$key}{$item} = ' checked="checked" ';
                                   }
                               }
                               $otheremails{'override_'.$key} = $settings->{'overrides'}{$key}{'others'};
                               $bccemails{'override_'.$key} = $settings->{'overrides'}{$key}{'bcc'};
                               $includeloc{'override_'.$key} = '';
                               $includestr{'override_'.$key} = '';
                               if ($settings->{'overrides'}{$key}{'include'} ne '') {
                                   ($includeloc{'override_'.$key},$includestr{'override_'.$key}) = 
                                       split(/:/,$settings->{'overrides'}{$key}{'include'},2);
                                   $includestr{'override_'.$key} = &unescape($includestr{'override_'.$key});
                               }
                         }                          }
                         $datatable .= '<span class="LC_nobreak"><label>'.  
                                       '<input type="radio" name="helpform_'.$field.'" '.  
                                       'value="'.$option.'"'.$checked.$clickaction.' />'.$fieldoptions->{$option}.  
                                       '</label></span>'.('&nbsp;'x2);  
                     }                      }
                 }                  }
                 if ($field eq 'screenshot') {              }
                     my $display;              my $customclass = 'LC_helpdesk_override';
                     if ($currfield{$field} eq 'no') {              my $optionsprefix = 'LC_options_helpdesk_';
                         $display = ' style="display:none"';  
                     }              my $onclicktypes = "toggleHelpdeskRow(this.form,'overrides','$customclass','$optionsprefix');";
                     $datatable .= '</td></tr><tr id="help_screenshotsize"'.$display.' />'.   
                                   '<td>'.&mt('Maximum size for upload (MB)').'</td><td>'.              $datatable .= &insttypes_row($settings,$types,$usertypes,$dom,
                                   '<input type="text" size="5" name="helpform_maxsize" value="'.$maxsize.'" />';                                           $numinrow,$othertitle,'overrides',
                                            \$rownum,$onclicktypes,$customclass);
               $rownum ++;
               $usertypeshash{'default'} = $othertitle;
               foreach my $status (@posstypes) {
                   my $css_class;
                   if ($rownum%2) {
                       $css_class = 'LC_odd_row ';
                   }
                   $css_class .= $customclass;
                   my $rowid = $optionsprefix.$status;
                   my $hidden = 1;
                   my $currstyle = 'display:none';
                   if (grep(/^\Q$status\E$/,@overridden)) {
                       $currstyle = 'display:table-row';
                       $hidden = 0;
                   }
                   my $key = 'override_'.$status;
                   $datatable .= &overridden_helpdesk($checked{$key},$otheremails{$key},$bccemails{$key},
                                                     $includeloc{$key},$includestr{$key},$status,$rowid,
                                                     $usertypeshash{$status},$css_class,$currstyle,
                                                     \@contacts,$short_titles);
                   unless ($hidden) {
                       $rownum ++;
                 }                  }
                 $datatable .= '</td></tr>';  
             }              }
             $datatable .= '</table>';  
         }          }
         $datatable .= '</td></tr>'."\n";  
         $rownum ++;  
     }      }
     $$rowtotal += $rownum;      $$rowtotal += $rownum;
     return $datatable;      return $datatable;
 }  }
   
   sub core_link_msu {
       return &Apache::loncommon::modal_link('http://loncapa.org/core.html',
                                             &mt('LON-CAPA core group - MSU'),600,500);
   }
   
   sub overridden_helpdesk {
       my ($checked,$otheremails,$bccemails,$includeloc,$includestr,$type,$rowid,
           $typetitle,$css_class,$rowstyle,$contacts,$short_titles) = @_;
       my $class = 'LC_left_item';
       if ($css_class) {
           $css_class = ' class="'.$css_class.'"';
       }
       if ($rowid) {
           $rowid = ' id="'.$rowid.'"';
       }
       if ($rowstyle) {
           $rowstyle = ' style="'.$rowstyle.'"';
       }
       my ($output,$description);
       $description = &mt('Helpdesk requests from: [_1] in this domain (overrides default)',"<b>$typetitle</b>");
       $output = '<tr'.$css_class.$rowid.$rowstyle.'>'.
                 "<td>$description</td>\n".
                 '<td class="'.$class.'" colspan="2">'.
                 '<fieldset><legend>'.&mt('E-mail recipient(s)').'</legend>'.
                 '<span class="LC_nobreak">';
       if (ref($contacts) eq 'ARRAY') {
           foreach my $item (@{$contacts}) {
               my $check;
               if (ref($checked) eq 'HASH') {
                  $check = $checked->{$item};
               }
               my $title;
               if (ref($short_titles) eq 'HASH') {
                   $title = $short_titles->{$item}; 
               }
               $output .= '<label>'.
                          '<input type="checkbox" name="override_'.$type.'"'.$check.
                          ' value="'.$item.'" />'.$title.'</label>&nbsp;';
           }
       }
       $output .= '</span><br />'.&mt('Others').':&nbsp;&nbsp;'.
                  '<input type="text" name="override_'.$type.'_others" '.
                  'value="'.$otheremails.'"  />';
       my %locchecked;
       foreach my $loc ('s','b') {
           if ($includeloc eq $loc) {
               $locchecked{$loc} = ' checked="checked"';
               last;
           }
       }
       $output .= '<br />'.&mt('Bcc:').('&nbsp;'x6).
                  '<input type="text" name="override_'.$type.'_bcc" '.
                  'value="'.$bccemails.'"  /></fieldset>'.
                  '<fieldset><legend>'.&mt('Optional added text').'</legend>'.
                  &mt('Text automatically added to e-mail:').' '.
                  '<input type="text" name="override_'.$type.'_includestr" value="'.$includestr.'" /><br />'.
                  '<span class="LC_nobreak">'.&mt('Location:').'&nbsp;'.
                  '<label><input type="radio" name="override_'.$type.'_includeloc" value="s"'.$locchecked{'s'}.' />'.&mt('in subject').'</label>'.
                  ('&nbsp;'x2).
                  '<label><input type="radio" name="override_'.$type.'_includeloc" value="b"'.$locchecked{'b'}.' />'.&mt('in body').'</label>'.
                  '</span></fieldset>'.
                  '</td></tr>'."\n";
       return $output;
   }
   
 sub contacts_javascript {  sub contacts_javascript {
     return <<"ENDSCRIPT";      return <<"ENDSCRIPT";
   
Line 3185  sub contacts_javascript { Line 3829  sub contacts_javascript {
 function screenshotSize(field) {  function screenshotSize(field) {
     if (document.getElementById('help_screenshotsize')) {      if (document.getElementById('help_screenshotsize')) {
         if (field.value == 'no') {          if (field.value == 'no') {
             document.getElementById('help_screenshotsize').style.display="none";               document.getElementById('help_screenshotsize').style.display="none";
         } else {          } else {
             document.getElementById('help_screenshotsize').style.display="";              document.getElementById('help_screenshotsize').style.display="";
         }          }
Line 3193  function screenshotSize(field) { Line 3837  function screenshotSize(field) {
     return;      return;
 }  }
   
   function toggleHelpdeskRow(form,checkbox,target,prefix,docount) {
       if (form.elements[checkbox].length != undefined) {
           var count = 0;
           if (docount) {
               for (var i=0; i<form.elements[checkbox].length; i++) {
                   if (form.elements[checkbox][i].checked) {
                       count ++;
                   }
               }
           }
           for (var i=0; i<form.elements[checkbox].length; i++) {
               var type = form.elements[checkbox][i].value;
               if (document.getElementById(prefix+type)) {
                   if (form.elements[checkbox][i].checked) {
                       document.getElementById(prefix+type).style.display = 'table-row';
                       if (count % 2 == 1) {
                           document.getElementById(prefix+type).className = target+' LC_odd_row';
                       } else {
                           document.getElementById(prefix+type).className = target;
                       }
                       count ++;
                   } else {
                       document.getElementById(prefix+type).style.display = 'none';
                   }
               }
           }
       }
       return;
   }
   
   
 // ]]>  // ]]>
 </script>  </script>
   
Line 3219  sub print_helpsettings { Line 3894  sub print_helpsettings {
         my $css_class;          my $css_class;
         my %existing=&Apache::lonnet::dump('roles',$dom,$confname,'rolesdef_');          my %existing=&Apache::lonnet::dump('roles',$dom,$confname,'rolesdef_');
         my (%customroles,%ordered,%current);          my (%customroles,%ordered,%current);
         if (ref($settings->{'adhoc'}) eq 'HASH') {          if (ref($settings) eq 'HASH') {
             %current = %{$settings->{'adhoc'}};              if (ref($settings->{'adhoc'}) eq 'HASH') {
                   %current = %{$settings->{'adhoc'}};
               }
         }          }
         my $count = 0;          my $count = 0;
         foreach my $key (sort(keys(%existing))) {          foreach my $key (sort(keys(%existing))) {
Line 3247  sub print_helpsettings { Line 3924  sub print_helpsettings {
         my $context = 'domprefs';          my $context = 'domprefs';
         my $crstype = 'Course';          my $crstype = 'Course';
         my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom);          my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom);
         my @accesstypes = ('all','none');          my @accesstypes = ('all','dh','da','none');
         my ($numstatustypes,@jsarray);          my ($numstatustypes,@jsarray);
         if (ref($types) eq 'ARRAY') {          if (ref($types) eq 'ARRAY') {
             if (@{$types} > 0) {              if (@{$types} > 0) {
Line 3256  sub print_helpsettings { Line 3933  sub print_helpsettings {
                 @jsarray = ('bystatus');                  @jsarray = ('bystatus');
             }              }
         }          }
         my %domhelpdesk = &Apache::lonnet::get_active_domroles($dom,['dh']);          my %domhelpdesk = &Apache::lonnet::get_active_domroles($dom,['dh','da']);
         if (keys(%domhelpdesk)) {          if (keys(%domhelpdesk)) {
             push(@accesstypes,('inc','exc'));              push(@accesstypes,('inc','exc'));
             push(@jsarray,('notinc','notexc'));              push(@jsarray,('notinc','notexc'));
         }          }
         my $hiddenstr = join("','",@jsarray);          my $hiddenstr = join("','",@jsarray);
         $datatable .= &helpsettings_javascript(\@roles_by_num,$maxnum,$hiddenstr,$formname);  
         my $context = 'domprefs';          my $context = 'domprefs';
         my $crstype = 'Course';          my $crstype = 'Course';
         my $prefix = 'helproles_';          my $prefix = 'helproles_';
Line 3296  sub print_helpsettings { Line 3972  sub print_helpsettings {
             my @templateroles = &Apache::lonuserutils::custom_template_roles($context,$crstype);              my @templateroles = &Apache::lonuserutils::custom_template_roles($context,$crstype);
             $css_class = $itemcount%2?' class="LC_odd_row"':'';              $css_class = $itemcount%2?' class="LC_odd_row"':'';
             my $chgstr = ' onchange="javascript:reorderHelpRoles(this.form,'."'helproles_".$num."_pos'".');"';              my $chgstr = ' onchange="javascript:reorderHelpRoles(this.form,'."'helproles_".$num."_pos'".');"';
             $datatable .= '<tr '.$css_class.'><td valign="top"><b>'.$role.'</b><br />'.              $datatable .= '<tr '.$css_class.'><td style="vertical-align: top"><b>'.$role.'</b><br />'.
                           '<select name="helproles_'.$num.'_pos"'.$chgstr.'>';                            '<select name="helproles_'.$num.'_pos"'.$chgstr.'>';
             for (my $k=0; $k<=$maxnum; $k++) {              for (my $k=0; $k<=$maxnum; $k++) {
                 my $vpos = $k+1;                  my $vpos = $k+1;
Line 3335  sub print_helpsettings { Line 4011  sub print_helpsettings {
         &Apache::lonuserutils::custom_role_privs(\%privs,\%full,\%levels,\%levelscurrent);          &Apache::lonuserutils::custom_role_privs(\%privs,\%full,\%levels,\%levelscurrent);
         my @templateroles = &Apache::lonuserutils::custom_template_roles($context,$crstype);          my @templateroles = &Apache::lonuserutils::custom_template_roles($context,$crstype);
         my $chgstr = ' onchange="javascript:reorderHelpRoles(this.form,'."'helproles_".$count."_pos'".');"';          my $chgstr = ' onchange="javascript:reorderHelpRoles(this.form,'."'helproles_".$count."_pos'".');"';
         $datatable .= '<tr '.$css_class.'><td valign="top"><span class="LC_nobreak"><label>'.          $datatable .= '<tr '.$css_class.'><td style="vertical-align: top"><span class="LC_nobreak"><label>'.
                       '<input type="hidden" name="helproles_maxnum" value="'.$maxnum.'" />'."\n".                        '<input type="hidden" name="helproles_maxnum" value="'.$maxnum.'" />'."\n".
                       '<select name="helproles_'.$count.'_pos"'.$chgstr.'>';                        '<select name="helproles_'.$count.'_pos"'.$chgstr.'>';
         for (my $k=0; $k<$maxnum+1; $k++) {          for (my $k=0; $k<$maxnum+1; $k++) {
Line 3365  sub print_helpsettings { Line 4041  sub print_helpsettings {
                                                                 \@templateroles,$newcust).                                                                  \@templateroles,$newcust).
                       &Apache::lonuserutils::custom_role_table('Course',\%full,\%levels,                        &Apache::lonuserutils::custom_role_table('Course',\%full,\%levels,
                                                                \%levelscurrent,$newcust).                                                                 \%levelscurrent,$newcust).
                       '</fieldset></td></tr>';                        '</fieldset>'.
                         &helpsettings_javascript(\@roles_by_num,$maxnum,$hiddenstr,$formname).
                         '</td></tr>';
         $count ++;          $count ++;
         $$rowtotal += $count;          $$rowtotal += $count;
     }      }
Line 3465  function helpdeskAccess(num) { Line 4143  function helpdeskAccess(num) {
                 shown = Array('notinc');                  shown = Array('notinc');
                 hidden = Array('notexc','bystatus');                  hidden = Array('notexc','bystatus');
             }              }
             if (curraccess == 'all') {              if ((curraccess == 'all') || (curraccess == 'dh') || (curraccess == 'da')) {
                 hidden = Array('notinc','notexc','bystatus');                  hidden = Array('notinc','notexc','bystatus');
             }              }
         }          }
Line 3494  function helpdeskAccess(num) { Line 4172  function helpdeskAccess(num) {
 function toggleHelpdeskItem(num,field) {  function toggleHelpdeskItem(num,field) {
     if (document.getElementById('helproles_'+num+'_'+field)) {      if (document.getElementById('helproles_'+num+'_'+field)) {
         if (document.getElementById('helproles_'+num+'_'+field).className.match(/(?:^|\\s)LC_hidden(?!\\S)/)) {          if (document.getElementById('helproles_'+num+'_'+field).className.match(/(?:^|\\s)LC_hidden(?!\\S)/)) {
             document.getElementById('helproles_'+num+'_'+field).className =               document.getElementById('helproles_'+num+'_'+field).className =
                 document.getElementById('helproles_'+num+'_'+field).className.replace(/(?:^|\\s)LC_hidden(?!\\S)/g ,'');                  document.getElementById('helproles_'+num+'_'+field).className.replace(/(?:^|\\s)LC_hidden(?!\\S)/g ,'');
             if (document.getElementById('helproles_'+num+'_'+field+'_vis')) {              if (document.getElementById('helproles_'+num+'_'+field+'_vis')) {
                 document.getElementById('helproles_'+num+'_'+field+'_vis').value = '$html_js_lt{hide}';                  document.getElementById('helproles_'+num+'_'+field+'_vis').value = '$html_js_lt{hide}';
Line 3522  sub helpdeskroles_access { Line 4200  sub helpdeskroles_access {
     my %lt = &Apache::lonlocal::texthash(      my %lt = &Apache::lonlocal::texthash(
                     'rou'    => 'Role usage',                      'rou'    => 'Role usage',
                     'whi'    => 'Which helpdesk personnel may use this role?',                      'whi'    => 'Which helpdesk personnel may use this role?',
                     'all'    => 'All',                      'all'    => 'All with domain helpdesk or helpdesk assistant role',
                       'dh'     => 'All with domain helpdesk role',
                       'da'     => 'All with domain helpdesk assistant role',
                     'none'   => 'None',                      'none'   => 'None',
                     'status' => 'Determined based on institutional status',                      'status' => 'Determined based on institutional status',
                     'inc'    => 'Include all, but exclude specific personnel',                      'inc'    => 'Include all, but exclude specific personnel',
Line 3612  sub radiobutton_prefs { Line 4292  sub radiobutton_prefs {
     foreach my $item (@{$toggles}) {      foreach my $item (@{$toggles}) {
         $css_class = $itemcount%2?' class="LC_odd_row"':'';          $css_class = $itemcount%2?' class="LC_odd_row"':'';
         $datatable .=          $datatable .=
             '<tr'.$css_class.'><td valign="top">'.              '<tr'.$css_class.'><td style="vertical-align: top">'.
             '<span class="LC_nobreak">'.$choices->{$item}.              '<span class="LC_nobreak">'.$choices->{$item}.
             '</span></td>';              '</span></td>';
         if ($align eq 'left') {          if ($align eq 'left') {
Line 3620  sub radiobutton_prefs { Line 4300  sub radiobutton_prefs {
         } else {          } else {
             $datatable .= '<td class="LC_right_item">';              $datatable .= '<td class="LC_right_item">';
         }          }
         $datatable .=           $datatable .=
             '<span class="LC_nobreak">'.              '<span class="LC_nobreak">'.
             '<label><input type="radio" name="'.              '<label><input type="radio" name="'.
             $item.'" '.$checkedon{$item}.' value="1"'.$onclick.' />'.&mt('Yes').              $item.'" '.$checkedon{$item}.' value="1"'.$onclick.' />'.&mt('Yes').
Line 3652  sub print_ltitools { Line 4332  sub print_ltitools {
     my $confname = $dom.'-domainconfig';      my $confname = $dom.'-domainconfig';
     my $switchserver = &check_switchserver($dom,$confname);      my $switchserver = &check_switchserver($dom,$confname);
     my $maxnum = scalar(keys(%ordered));      my $maxnum = scalar(keys(%ordered));
     my $datatable = &ltitools_javascript($settings);      my $datatable;
     my %lt = &ltitools_names();      my %lt = &ltitools_names();
     my @courseroles = ('cc','in','ta','ep','st');      my @courseroles = ('cc','in','ta','ep','st');
     my @ltiroles = qw(Instructor ContentDeveloper TeachingAssistant Learner);      my @ltiroles = qw(Instructor ContentDeveloper TeachingAssistant Learner);
     my @fields = ('fullname','firstname','lastname','email','user','roles');      my @fields = ('fullname','firstname','lastname','email','roles','user');
     if (keys(%ordered)) {      if (keys(%ordered)) {
         my @items = sort { $a <=> $b } keys(%ordered);          my @items = sort { $a <=> $b } keys(%ordered);
         for (my $i=0; $i<@items; $i++) {          for (my $i=0; $i<@items; $i++) {
             $css_class = $itemcount%2?' class="LC_odd_row"':'';              $css_class = $itemcount%2?' class="LC_odd_row"':'';
             my $item = $ordered{$items[$i]};              my $item = $ordered{$items[$i]};
             my ($title,$key,$secret,$url,$imgsrc,$version);              my ($title,$key,$secret,$url,$lifetime,$imgsrc,%sigsel);
             if (ref($settings->{$item}) eq 'HASH') {              if (ref($settings->{$item}) eq 'HASH') {
                 $title = $settings->{$item}->{'title'};                  $title = $settings->{$item}->{'title'};
                 $url = $settings->{$item}->{'url'};                  $url = $settings->{$item}->{'url'};
                 $key = $settings->{$item}->{'key'};                  $key = $settings->{$item}->{'key'};
                 $secret = $settings->{$item}->{'secret'};                  $secret = $settings->{$item}->{'secret'};
                   $lifetime = $settings->{$item}->{'lifetime'};
                 my $image = $settings->{$item}->{'image'};                  my $image = $settings->{$item}->{'image'};
                 if ($image ne '') {                  if ($image ne '') {
                     $imgsrc = '<img src="'.$image.'" alt="'.&mt('Tool Provider icon').'" />';                      $imgsrc = '<img src="'.$image.'" alt="'.&mt('Tool Provider icon').'" />';
                 }                  }
                   if ($settings->{$item}->{'sigmethod'} eq 'HMAC-256') {
                       $sigsel{'HMAC-256'} = ' selected="selected"';
                   } else {
                       $sigsel{'HMAC-SHA1'} = ' selected="selected"';
                   }
             }              }
             my $chgstr = ' onchange="javascript:reorderLTI(this.form,'."'ltitools_".$item."'".');"';              my $chgstr = ' onchange="javascript:reorderLTITools(this.form,'."'ltitools_".$item."'".');"';
             $datatable .= '<tr '.$css_class.'><td><span class="LC_nobreak">'              $datatable .= '<tr '.$css_class.'><td><span class="LC_nobreak">'
                          .'<select name="ltitools_'.$item.'"'.$chgstr.'>';                           .'<select name="ltitools_'.$item.'"'.$chgstr.'>';
             for (my $k=0; $k<=$maxnum; $k++) {              for (my $k=0; $k<=$maxnum; $k++) {
Line 3689  sub print_ltitools { Line 4375  sub print_ltitools {
                 &mt('Delete?').'</label></span></td>'.                  &mt('Delete?').'</label></span></td>'.
                 '<td colspan="2">'.                  '<td colspan="2">'.
                 '<fieldset><legend>'.&mt('Required settings').'</legend>'.                  '<fieldset><legend>'.&mt('Required settings').'</legend>'.
                 '<span class="LC_nobreak">'.$lt{'title'}.':<input type="text" size="30" name="ltitools_title_'.$i.'" value="'.$title.'" /></span> '.                  '<span class="LC_nobreak">'.$lt{'title'}.':<input type="text" size="20" name="ltitools_title_'.$i.'" value="'.$title.'" /></span> '.
                 ('&nbsp;'x2).                  ('&nbsp;'x2).
                 '<span class="LC_nobreak">'.$lt{'version'}.':<select name="ltitools_version_'.$i.'">'.                  '<span class="LC_nobreak">'.$lt{'version'}.':<select name="ltitools_version_'.$i.'">'.
                 '<option value="LTI-1p0" selected="selected">1.1</option></select></span> '.                  '<option value="LTI-1p0" selected="selected">1.1</option></select></span> '.
                 ('&nbsp;'x2).                  ('&nbsp;'x2).
                 '<span class="LC_nobreak">'.$lt{'msgtype'}.':<select name="ltitools_msgtype_'.$i.'">'.                  '<span class="LC_nobreak">'.$lt{'msgtype'}.':<select name="ltitools_msgtype_'.$i.'">'.
                 '<option value="basic-lti-launch-request" selected="selected">Launch</option></select></span> '.                  '<option value="basic-lti-launch-request" selected="selected">Launch</option></select></span> '.
                   ('&nbsp;'x2).
                   '<span class="LC_nobreak">'.$lt{'sigmethod'}.':<select name="ltitools_sigmethod_'.$i.'">'.
                   '<option value="HMAC-SHA1"'.$sigsel{'HMAC-SHA1'}.'>HMAC-SHA1</option>'.
                   '<option value="HMAC-SHA256"'.$sigsel{'HMAC-SHA256'}.'>HMAC-SHA256</option></select></span>'.
                 '<br /><br />'.                  '<br /><br />'.
                 '<span class="LC_nobreak">'.$lt{'url'}.':<input type="text" size="30" name="ltitools_url_'.$i.'"'.                  '<span class="LC_nobreak">'.$lt{'url'}.':<input type="text" size="40" name="ltitools_url_'.$i.'"'.
                 ' value="'.$url.'" /></span>'.                  ' value="'.$url.'" /></span>'.
                 ('&nbsp;'x2).                  ('&nbsp;'x2).
                 '<span class="LC_nobreak">'.$lt{'key'}.                  '<span class="LC_nobreak">'.$lt{'key'}.':'.
                 '<input type="text" size="25" name="ltitools_key_'.$i.'" value="'.$key.'" /></span> '.                  '<input type="text" size="25" name="ltitools_key_'.$i.'" value="'.$key.'" /></span> '.
                 ('&nbsp;'x2).                  ('&nbsp;'x2).
                   '<span class="LC_nobreak">'.$lt{'lifetime'}.':'.
                   '<input type="text" size="5" name="ltitools_lifetime_'.$i.'" value="'.$lifetime.'" /></span> '.
                   ('&nbsp;'x2).
                 '<span class="LC_nobreak">'.$lt{'secret'}.':'.                  '<span class="LC_nobreak">'.$lt{'secret'}.':'.
                 '<input type="password" size="20" name="ltitools_secret_'.$i.'" value="'.$secret.'" />'.                  '<input type="password" size="20" name="ltitools_secret_'.$i.'" value="'.$secret.'" />'.
                 '<label><input type="checkbox" name="visible" onclick="if (this.checked) { this.form.ltitools_secret_'.$i.'.type='."'text'".' } else { this.form.ltitools_secret_'.$i.'.type='."'password'".' }" />'.&mt('Visible input').'</label>'.                  '<label><input type="checkbox" name="visible" onclick="if (this.checked) { this.form.ltitools_secret_'.$i.'.type='."'text'".' } else { this.form.ltitools_secret_'.$i.'.type='."'password'".' }" />'.&mt('Visible input').'</label>'.
Line 3714  sub print_ltitools { Line 4407  sub print_ltitools {
             if (ref($settings->{$item}->{'display'}) eq 'HASH') {              if (ref($settings->{$item}->{'display'}) eq 'HASH') {
                 if ($settings->{$item}->{'display'}->{'target'} eq 'window') {                  if ($settings->{$item}->{'display'}->{'target'} eq 'window') {
                     $currdisp{'window'} = ' checked="checked"';                      $currdisp{'window'} = ' checked="checked"';
                   } elsif ($settings->{$item}->{'display'}->{'target'} eq 'tab') {
                       $currdisp{'tab'} = ' checked="checked"';
                 } else {                  } else {
                     $currdisp{'iframe'} = ' checked="checked"';                      $currdisp{'iframe'} = ' checked="checked"';
                 }                  }
Line 3723  sub print_ltitools { Line 4418  sub print_ltitools {
                 if ($settings->{$item}->{'display'}->{'height'} =~ /^(\d+)$/) {                  if ($settings->{$item}->{'display'}->{'height'} =~ /^(\d+)$/) {
                      $currdisp{'height'} = $1;                       $currdisp{'height'} = $1;
                 }                  }
                   $currdisp{'linktext'} = $settings->{$item}->{'display'}->{'linktext'};
                   $currdisp{'explanation'} = $settings->{$item}->{'display'}->{'explanation'};
             } else {              } else {
                 $currdisp{'iframe'} = ' checked="checked"';                  $currdisp{'iframe'} = ' checked="checked"';
             }              }
             foreach my $disp ('iframe','window') {              foreach my $disp ('iframe','tab','window') {
                 $datatable .= '<label><input type="radio" name="ltitools_target_'.$i.'" value="'.$disp.'"'.$currdisp{$disp}.' />'.                  $datatable .= '<label><input type="radio" name="ltitools_target_'.$i.'" value="'.$disp.'"'.$currdisp{$disp}.' />'.
                               $lt{$disp}.'</label>'.('&nbsp;'x2);                                $lt{$disp}.'</label>'.('&nbsp;'x2);
             }              }
Line 3736  sub print_ltitools { Line 4433  sub print_ltitools {
                               '<input type="text" name="ltitools_'.$dimen.'_'.$i.'" size="5" value="'.$currdisp{$dimen}.'" /></label>'.                                '<input type="text" name="ltitools_'.$dimen.'_'.$i.'" size="5" value="'.$currdisp{$dimen}.'" /></label>'.
                               ('&nbsp;'x2);                                ('&nbsp;'x2);
             }              }
             $datatable .= '<br />';              $datatable .= '</span><br />'.
                             '<div class="LC_left_float">'.$lt{'linktext'}.'<br />'.
                             '<input type="text" name="ltitools_linktext_'.$i.'" size="25" value="'.$currdisp{'linktext'}.'" /></div>'.
                             '<div class="LC_left_float">'.$lt{'explanation'}.'<br />'.
                             '<textarea name="ltitools_explanation_'.$i.'" rows="5" cols="40">'.$currdisp{'explanation'}.
                             '</textarea></div><div style=""></div><br />';
               my %units = (
                             'passback' => 'days',
                             'roster'   => 'seconds',
                           );
             foreach my $extra ('passback','roster') {              foreach my $extra ('passback','roster') {
                   my $validsty = 'none';
                   my $currvalid;
                 my $checkedon = '';                  my $checkedon = '';
                 my $checkedoff = ' checked="checked"';                  my $checkedoff = ' checked="checked"';
                 if ($settings->{$item}->{$extra}) {                  if ($settings->{$item}->{$extra}) {
                     $checkedon = $checkedoff;                      $checkedon = $checkedoff;
                     $checkedoff = '';                      $checkedoff = '';
                 }                      $validsty = 'inline-block';
                 $datatable .= $lt{$extra}.'&nbsp;'.                      if ($settings->{$item}->{$extra.'valid'} =~ /^\d+\.?\d*$/) {
                               '<label><input type="radio" name="ltitools_'.$extra.'_'.$i.'" value="1"'.$checkedon.' />'.                          $currvalid = $settings->{$item}->{$extra.'valid'};
                               &mt('Yes').'</label>'.('&nbsp;'x2).                      }
                               '<label><input type="radio" name="ltitools_'.$extra.'_'.$i.'" value="0"'.$checkedoff.' />'.                  }
                               &mt('No').'</label>'.('&nbsp;'x4);                  my $onclick = ' onclick="toggleLTITools(this.form,'."'$extra','$i'".');"';
                   $datatable .= '<div class="LC_floatleft"><span class="LC_nobreak">'.$lt{$extra}.'&nbsp;'.
                                 '<label><input type="radio" name="ltitools_'.$extra.'_'.$i.'" value="0"'.$checkedoff.$onclick.' />'.
                                 &mt('No').'</label>'.('&nbsp;'x2).
                                 '<label><input type="radio" name="ltitools_'.$extra.'_'.$i.'" value="1"'.$checkedon.$onclick.' />'.
                                 &mt('Yes').'</label></span></div>'.
                                 '<div class="LC_floatleft" style="display:'.$validsty.';" id="ltitools_'.$extra.'time_'.$i.'">'.
                                 '<span class="LC_nobreak">'.
                                 &mt("at least [_1] $units{$extra} after launch",
                                     '<input type="text" name="ltitools_'.$extra.'valid_'.$i.'" value="'.$currvalid.'" />').
                                 '</span></div><div style="padding:0;clear:both;margin:0;border:0"></div>';
             }              }
             $datatable .= '<br /><br /><span class="LC_nobreak">'.$lt{'icon'}.':&nbsp;';              $datatable .= '<span class="LC_nobreak">'.$lt{'icon'}.':&nbsp;';
             if ($imgsrc) {              if ($imgsrc) {
                 $datatable .= $imgsrc.                  $datatable .= $imgsrc.
                               '<label><input type="checkbox" name="ltitools_image_del"'.                                '<label><input type="checkbox" name="ltitools_image_del"'.
Line 3765  sub print_ltitools { Line 4483  sub print_ltitools {
                 $datatable .= '<input type="file" name="ltitools_image_'.$i.'" value="" />';                  $datatable .= '<input type="file" name="ltitools_image_'.$i.'" value="" />';
             }              }
             $datatable .= '</span></fieldset>';              $datatable .= '</span></fieldset>';
             my (%checkedfields,%rolemaps);              my (%checkedfields,%rolemaps,$userincdom);
             if (ref($settings->{$item}) eq 'HASH') {              if (ref($settings->{$item}) eq 'HASH') {
                 if (ref($settings->{$item}->{'fields'}) eq 'HASH') {                  if (ref($settings->{$item}->{'fields'}) eq 'HASH') {
                     %checkedfields = %{$settings->{$item}->{'fields'}};                      %checkedfields = %{$settings->{$item}->{'fields'}};
                 }                  }
                   $userincdom = $settings->{$item}->{'incdom'};
                 if (ref($settings->{$item}->{'roles'}) eq 'HASH') {                  if (ref($settings->{$item}->{'roles'}) eq 'HASH') {
                     %rolemaps = %{$settings->{$item}->{'roles'}};                      %rolemaps = %{$settings->{$item}->{'roles'}};
                     $checkedfields{'roles'} = 1;                      $checkedfields{'roles'} = 1;
Line 3777  sub print_ltitools { Line 4496  sub print_ltitools {
             }              }
             $datatable .= '<fieldset><legend>'.&mt('User data sent on launch').'</legend>'.              $datatable .= '<fieldset><legend>'.&mt('User data sent on launch').'</legend>'.
                           '<span class="LC_nobreak">';                            '<span class="LC_nobreak">';
               my $userfieldstyle = 'display:none;';
               my $seluserdom = '';
               my $unseluserdom = ' selected="selected"';
             foreach my $field (@fields) {              foreach my $field (@fields) {
                 my $checked;                  my ($checked,$onclick,$id,$spacer);
                 if ($checkedfields{$field}) {                  if ($checkedfields{$field}) {
                     $checked = ' checked="checked"';                      $checked = ' checked="checked"';
                 }                  }
                   if ($field eq 'user') {
                       $id = ' id="ltitools_user_field_'.$i.'"';
                       $onclick = ' onclick="toggleLTITools(this.form,'."'$field','$i'".')"';
                       if ($checked) {
                           $userfieldstyle = 'display:inline-block';
                           if ($userincdom) {
                               $seluserdom = $unseluserdom;
                               $unseluserdom = '';
                           }
                       }
                   } else {
                       $spacer = ('&nbsp;' x2);
                   }
                 $datatable .= '<label>'.                  $datatable .= '<label>'.
                               '<input type="checkbox" name="ltitools_fields_'.$i.'" value="'.$field.'"'.$checked.' />'.                                '<input type="checkbox" name="ltitools_fields_'.$i.'" value="'.$field.'"'.$id.$checked.$onclick.' />'.
                               $lt{$field}.'</label>'.('&nbsp;' x2);                                $lt{$field}.'</label>'.$spacer;
             }              }
             $datatable .= '</span></fieldset>'.              $datatable .= '</span>';
               $datatable .= '<div style="'.$userfieldstyle.'" id="ltitools_user_div_'.$i.'">'.
                             '<span class="LC_nobreak"> : '.
                             '<select name="ltitools_userincdom_'.$i.'">'.
                             '<option value="">'.&mt('Select').'</option>'.
                             '<option value="0"'.$unseluserdom.'>'.&mt('username').'</option>'.
                             '<option value="1"'.$seluserdom.'>'.&mt('username:domain').'</option>'.
                             '</select></span></div>';
               $datatable .= '</fieldset>'.
                           '<fieldset><legend>'.&mt('Role mapping').'</legend><table><tr>';                            '<fieldset><legend>'.&mt('Role mapping').'</legend><table><tr>';
             foreach my $role (@courseroles) {              foreach my $role (@courseroles) {
                 my ($selected,$selectnone);                  my ($selected,$selectnone);
                 if (!$rolemaps{$role}) {                  if (!$rolemaps{$role}) {
                     $selectnone = ' selected="selected"';                      $selectnone = ' selected="selected"';
                 }                  }
                 $datatable .= '<td align="center">'.                   $datatable .= '<td style="text-align: center">'. 
                               &Apache::lonnet::plaintext($role,'Course').'<br />'.                                &Apache::lonnet::plaintext($role,'Course').'<br />'.
                               '<select name="ltitools_roles_'.$role.'_'.$i.'">'.                                '<select name="ltitools_roles_'.$role.'_'.$i.'">'.
                               '<option value=""'.$selectnone.'>'.&mt('Select').'</option>';                                '<option value=""'.$selectnone.'>'.&mt('Select').'</option>';
Line 3817  sub print_ltitools { Line 4560  sub print_ltitools {
                 }                  }
             }              }
             $datatable .= '<fieldset><legend>'.&mt('Configurable in course').'</legend><span class="LC_nobreak">';              $datatable .= '<fieldset><legend>'.&mt('Configurable in course').'</legend><span class="LC_nobreak">';
             foreach my $item ('label','title','target') {              foreach my $item ('label','title','target','linktext','explanation','append') {
                 my $checked;                  my $checked;
                 if ($courseconfig{$item}) {                  if ($courseconfig{$item}) {
                     $checked = ' checked="checked"';                      $checked = ' checked="checked"';
Line 3850  sub print_ltitools { Line 4593  sub print_ltitools {
         }          }
     }      }
     $css_class = $itemcount%2?' class="LC_odd_row"':'';      $css_class = $itemcount%2?' class="LC_odd_row"':'';
     my $chgstr = ' onchange="javascript:reorderLTI(this.form,'."'ltitools_add_pos'".');"';      my $chgstr = ' onchange="javascript:reorderLTITools(this.form,'."'ltitools_add_pos'".');"';
     $datatable .= '<tr '.$css_class.'><td><span class="LC_nobreak">'."\n".      $datatable .= '<tr '.$css_class.'><td><span class="LC_nobreak">'."\n".
                   '<input type="hidden" name="ltitools_maxnum" value="'.$maxnum.'" />'."\n".                    '<input type="hidden" name="ltitools_maxnum" value="'.$maxnum.'" />'."\n".
                   '<select name="ltitools_add_pos"'.$chgstr.'>';                    '<select name="ltitools_add_pos"'.$chgstr.'>';
Line 3863  sub print_ltitools { Line 4606  sub print_ltitools {
         $datatable .= '<option value="'.$k.'"'.$selstr.'>'.$vpos.'</option>';          $datatable .= '<option value="'.$k.'"'.$selstr.'>'.$vpos.'</option>';
     }      }
     $datatable .= '</select>&nbsp;'."\n".      $datatable .= '</select>&nbsp;'."\n".
                   '<input type="checkbox" name="ltitools_add" value="1" />'.&mt('Add').'</td>'."\n".                    '<input type="checkbox" name="ltitools_add" value="1" />'.&mt('Add').'</span></td>'."\n".
                   '<td colspan="2">'.                    '<td colspan="2">'.
                   '<fieldset><legend>'.&mt('Required settings').'</legend>'.                    '<fieldset><legend>'.&mt('Required settings').'</legend>'.
                   '<span class="LC_nobreak">'.$lt{'title'}.':<input type="text" size="30" name="ltitools_add_title" value="" /></span> '."\n".                    '<span class="LC_nobreak">'.$lt{'title'}.':<input type="text" size="20" name="ltitools_add_title" value="" /></span> '."\n".
                   ('&nbsp;'x2).                    ('&nbsp;'x2).
                   '<span class="LC_nobreak">'.$lt{'version'}.':<select name="ltitools_add_version">'.                    '<span class="LC_nobreak">'.$lt{'version'}.':<select name="ltitools_add_version">'.
                   '<option value="LTI-1p0" selected="selected">1.1</option></select></span> '."\n".                    '<option value="LTI-1p0" selected="selected">1.1</option></select></span> '."\n".
                   ('&nbsp;'x2).                    ('&nbsp;'x2).
                   '<span class="LC_nobreak">'.$lt{'msgtype'}.':<select name="ltitools_add_msgtype">'.                    '<span class="LC_nobreak">'.$lt{'msgtype'}.':<select name="ltitools_add_msgtype">'.
                   '<option value="basic-lti-launch-request" selected="selected">Launch</option></select></span> '.                    '<option value="basic-lti-launch-request" selected="selected">Launch</option></select></span> '.
                     '<span class="LC_nobreak">'.$lt{'sigmethod'}.':<select name="ltitools_add_sigmethod">'.
                     '<option value="HMAC-SHA1" selected="selected">HMAC-SHA1</option>'.
                     '<option value="HMAC-SHA256">HMAC-SHA256</option></select></span>'.
                   '<br />'.                    '<br />'.
                   '<span class="LC_nobreak">'.$lt{'url'}.':<input type="text" size="30" name="ltitools_add_url" value="" /></span> '."\n".                    '<span class="LC_nobreak">'.$lt{'url'}.':<input type="text" size="40" name="ltitools_add_url" value="" /></span> '."\n".
                   ('&nbsp;'x2).                    ('&nbsp;'x2).
                   '<span class="LC_nobreak">'.$lt{'key'}.':<input type="text" size="25" name="ltitools_add_key" value="" /></span> '."\n".                    '<span class="LC_nobreak">'.$lt{'key'}.':<input type="text" size="25" name="ltitools_add_key" value="" /></span> '."\n".
                   ('&nbsp;'x2).                    ('&nbsp;'x2).
                     '<span class="LC_nobreak">'.$lt{'lifetime'}.':<input type="text" size="5" name="ltitools_add_lifetime" value="300" /></span> '."\n".
                     ('&nbsp;'x2).
                   '<span class="LC_nobreak">'.$lt{'secret'}.':<input type="password" size="20" name="ltitools_add_secret" value="" />'.                    '<span class="LC_nobreak">'.$lt{'secret'}.':<input type="password" size="20" name="ltitools_add_secret" value="" />'.
                   '<label><input type="checkbox" name="visible" onclick="if (this.checked) { this.form.ltitools_add_secret.type='."'text'".' } else { this.form.ltitools_add_secret.type='."'password'".' }" />'.&mt('Visible input').'</label></span> '."\n".                    '<label><input type="checkbox" name="visible" onclick="if (this.checked) { this.form.ltitools_add_secret.type='."'text'".' } else { this.form.ltitools_add_secret.type='."'password'".' }" />'.&mt('Visible input').'</label></span> '."\n".
                   '</fieldset>'.                    '</fieldset>'.
Line 3885  sub print_ltitools { Line 4633  sub print_ltitools {
                   '<span class="LC_nobreak">'.&mt('Display target:');                    '<span class="LC_nobreak">'.&mt('Display target:');
     my %defaultdisp;      my %defaultdisp;
     $defaultdisp{'iframe'} = ' checked="checked"';      $defaultdisp{'iframe'} = ' checked="checked"';
     foreach my $disp ('iframe','window') {      foreach my $disp ('iframe','tab','window') {
         $datatable .= '<label><input type="radio" name="ltitools_add_target" value="'.$disp.'"'.$defaultdisp{$disp}.' />'.          $datatable .= '<label><input type="radio" name="ltitools_add_target" value="'.$disp.'"'.$defaultdisp{$disp}.' />'.
                       $lt{$disp}.'</label>'.('&nbsp;'x2);                        $lt{$disp}.'</label>'.('&nbsp;'x2);
     }      }
Line 3895  sub print_ltitools { Line 4643  sub print_ltitools {
                       '<input type="text" name="ltitools_add_'.$dimen.'" size="5" /></label>'.                        '<input type="text" name="ltitools_add_'.$dimen.'" size="5" /></label>'.
                       ('&nbsp;'x2);                        ('&nbsp;'x2);
     }      }
     $datatable .= '<br />';      $datatable .= '</span><br />'.
                     '<div class="LC_left_float">'.$lt{'linktext'}.'<br />'.
                     '<input type="text" name="ltitools_add_linktext" size="5" /></div>'.
                     '<div class="LC_left_float">'.$lt{'explanation'}.'<br />'.
                     '<textarea name="ltitools_add_explanation" rows="5" cols="40"></textarea>'.
                     '</div><div style=""></div><br />';
       my %units = (
                     'passback' => 'days',
                     'roster'   => 'seconds',
                   );
       my %defaulttimes = (
                        'passback' => '7',
                        'roster'   => '300',
                      );
     foreach my $extra ('passback','roster') {      foreach my $extra ('passback','roster') {
         $datatable .= $lt{$extra}.'&nbsp;'.          my $onclick = ' onclick="toggleLTITools(this.form,'."'$extra','add'".');"';
                       '<label><input type="radio" name="ltitools_add_'.$extra.'" value="1" />'.          $datatable .= '<div class="LC_floatleft"><span class="LC_nobreak">'.$lt{$extra}.'&nbsp;'.
                       &mt('Yes').'</label>'.('&nbsp;'x2).                        '<label><input type="radio" name="ltitools_'.$extra.'_add" value="0" checked="checked"'.$onclick.' />'.
                       '<label><input type="radio" name="ltitools_add_'.$extra.'" value="0" checked="checked" />'.                        &mt('No').'</label></span>'.('&nbsp;'x2).'<span class="LC_nobreak">'.
                       &mt('No').'</label>'.('&nbsp;'x4);                        '<label><input type="radio" name="ltitools_'.$extra.'_add" value="1"'.$onclick.' />'.
                         &mt('Yes').'</label></span></div>'.
                         '<div class="LC_floatleft" style="display:none;" id="ltitools_'.$extra.'time_add">'.
                         '<span class="LC_nobreak">'.
                         &mt("at least [_1] $units{$extra} after launch",
                             '<input type="text" name="ltitools_'.$extra.'valid_add" value="'.$defaulttimes{$extra}.'" />').
                         '</span></div><div style="padding:0;clear:both;margin:0;border:0"></div>';
     }      }
     $datatable .= '<br /><br /><span class="LC_nobreak">'.$lt{'icon'}.':&nbsp;'.      $datatable .= '<span class="LC_nobreak">'.$lt{'icon'}.':&nbsp;'.
                   '('.&mt('if larger than 21x21 pixels, image will be scaled').')&nbsp;';                    '('.&mt('if larger than 21x21 pixels, image will be scaled').')&nbsp;';
     if ($switchserver) {      if ($switchserver) {
         $datatable .= &mt('Upload to library server: [_1]',$switchserver);          $datatable .= &mt('Upload to library server: [_1]',$switchserver);
Line 3914  sub print_ltitools { Line 4681  sub print_ltitools {
                   '<fieldset><legend>'.&mt('User data sent on launch').'</legend>'.                    '<fieldset><legend>'.&mt('User data sent on launch').'</legend>'.
                   '<span class="LC_nobreak">';                    '<span class="LC_nobreak">';
     foreach my $field (@fields) {      foreach my $field (@fields) {
           my ($id,$onclick,$spacer);
           if ($field eq 'user') {
               $id = ' id="ltitools_user_field_add"';
               $onclick = ' onclick="toggleLTITools(this.form,'."'$field','add'".')"';
           } else {
               $spacer = ('&nbsp;' x2);
           }
         $datatable .= '<label>'.          $datatable .= '<label>'.
                       '<input type="checkbox" name="ltitools_add_fields" value="'.$field.'" />'.                        '<input type="checkbox" name="ltitools_add_fields" value="'.$field.'"'.$id.$onclick.' />'.
                       $lt{$field}.'</label>'.('&nbsp;' x2);                        $lt{$field}.'</label>'.$spacer;
     }      }
     $datatable .= '</span></fieldset>'.      $datatable .= '</span>'.
                   '<fieldset><legend>'.&mt('Role mapping').'</legend><table><tr>';                    '<div style="display:none;" id="ltitools_user_div_add">'.
                     '<span class="LC_nobreak"> : '.
                     '<select name="ltitools_userincdom_add">'.
                     '<option value="" selected="selected">'.&mt('Select').'</option>'.
                     '<option value="0">'.&mt('username').'</option>'.
                     '<option value="1">'.&mt('username:domain').'</option>'.
                     '</select></span></div></fieldset>';
       $datatable .= '<fieldset><legend>'.&mt('Role mapping').'</legend><table><tr>';
     foreach my $role (@courseroles) {      foreach my $role (@courseroles) {
         my ($checked,$checkednone);          my ($checked,$checkednone);
         $datatable .= '<td align="center">'.          $datatable .= '<td style="text-align: center">'.
                       &Apache::lonnet::plaintext($role,'Course').'<br />'.                        &Apache::lonnet::plaintext($role,'Course').'<br />'.
                       '<select name="ltitools_add_roles_'.$role.'">'.                        '<select name="ltitools_add_roles_'.$role.'">'.
                       '<option value="" selected="selected">'.&mt('Select').'</option>';                        '<option value="" selected="selected">'.&mt('Select').'</option>';
Line 3933  sub print_ltitools { Line 4714  sub print_ltitools {
     }      }
     $datatable .= '</tr></table></fieldset>'.      $datatable .= '</tr></table></fieldset>'.
                   '<fieldset><legend>'.&mt('Configurable in course').'</legend><span class="LC_nobreak">';                    '<fieldset><legend>'.&mt('Configurable in course').'</legend><span class="LC_nobreak">';
     foreach my $item ('label','title','target') {      foreach my $item ('label','title','target','linktext','explanation','append') {
          $datatable .= '<label>'.          $datatable .= '<label>'.
                        '<input type="checkbox" name="ltitools_courseconfig" value="'.$item.'" checked="checked" />'.                        '<input type="checkbox" name="ltitools_courseconfig" value="'.$item.'" checked="checked" />'.
                        $lt{'crs'.$item}.'</label>'.('&nbsp;' x2)."\n";                        $lt{'crs'.$item}.'</label>'.('&nbsp;' x2)."\n";
     }      }
     $datatable .= '</span></fieldset>'.      $datatable .= '</span></fieldset>'.
                   '<fieldset><legend>'.&mt('Custom items sent on launch').'</legend>'.                    '<fieldset><legend>'.&mt('Custom items sent on launch').'</legend>'.
Line 3945  sub print_ltitools { Line 4726  sub print_ltitools {
                   '<label><input type="checkbox" name="ltitools_add_custom" value="1" />'.                    '<label><input type="checkbox" name="ltitools_add_custom" value="1" />'.
                   &mt('Add').'</label></span></td><td><input type="text" name="ltitools_add_custom_name" />'.                    &mt('Add').'</label></span></td><td><input type="text" name="ltitools_add_custom_name" />'.
                   '</td><td><input type="text" name="ltitools_add_custom_value" /></td></tr>'.                    '</td><td><input type="text" name="ltitools_add_custom_value" /></td></tr>'.
                   '</table></fieldset></td></tr>'."\n".                    '</table></fieldset>'."\n".
                   '</td>'."\n".                    '</td>'."\n".
                   '</tr>'."\n";                    '</tr>'."\n";
     $itemcount ++;      $itemcount ++;
Line 3954  sub print_ltitools { Line 4735  sub print_ltitools {
   
 sub ltitools_names {  sub ltitools_names {
     my %lt = &Apache::lonlocal::texthash(      my %lt = &Apache::lonlocal::texthash(
                                           'title'     => 'Title',                                            'title'          => 'Title',
                                           'version'   => 'Version',                                            'version'        => 'Version',
                                           'msgtype'   => 'Message Type',                                            'msgtype'        => 'Message Type',
                                             'sigmethod'      => 'Signature Method',
                                             'url'            => 'URL',
                                             'key'            => 'Key',
                                             'lifetime'       => 'Nonce lifetime (s)',
                                             'secret'         => 'Secret',
                                             'icon'           => 'Icon',   
                                             'user'           => 'User',
                                             'fullname'       => 'Full Name',
                                             'firstname'      => 'First Name',
                                             'lastname'       => 'Last Name',
                                             'email'          => 'E-mail',
                                             'roles'          => 'Role',
                                             'window'         => 'Window',
                                             'tab'            => 'Tab',
                                             'iframe'         => 'iFrame',
                                             'height'         => 'Height',
                                             'width'          => 'Width',
                                             'linktext'       => 'Default Link Text',
                                             'explanation'    => 'Default Explanation',
                                             'passback'       => 'Tool can return grades:',
                                             'roster'         => 'Tool can retrieve roster:',
                                             'crstarget'      => 'Display target',
                                             'crslabel'       => 'Course label',
                                             'crstitle'       => 'Course title', 
                                             'crslinktext'    => 'Link Text',
                                             'crsexplanation' => 'Explanation',
                                             'crsappend'      => 'Provider URL',
                                           );
       return %lt;
   }
   
   sub print_lti {
       my ($dom,$settings,$rowtotal) = @_;
       my $itemcount = 1;
       my $maxnum = 0;
       my $css_class;
       my %ordered;
       if (ref($settings) eq 'HASH') {
           foreach my $item (keys(%{$settings})) {
               if (ref($settings->{$item}) eq 'HASH') {
                   my $num = $settings->{$item}{'order'};
                   $ordered{$num} = $item;
               }
           }
       }
       my $maxnum = scalar(keys(%ordered));
       my $datatable;
       my %lt = &lti_names();
       if (keys(%ordered)) {
           my @items = sort { $a <=> $b } keys(%ordered);
           for (my $i=0; $i<@items; $i++) {
               $css_class = $itemcount%2?' class="LC_odd_row"':'';
               my $item = $ordered{$items[$i]};
               my ($key,$secret,$lifetime,$consumer,$requser,$current);
               if (ref($settings->{$item}) eq 'HASH') {
                   $key = $settings->{$item}->{'key'};
                   $secret = $settings->{$item}->{'secret'};
                   $lifetime = $settings->{$item}->{'lifetime'};
                   $consumer = $settings->{$item}->{'consumer'};
                   $requser = $settings->{$item}->{'requser'};
                   $current = $settings->{$item};
               }
               my $onclickrequser = ' onclick="toggleLTI(this.form,'."'requser','$i'".');"';
               my %checkedrequser = (
                                      yes => ' checked="checked"',
                                      no  => '',
                                    );
               if (!$requser) {
                   $checkedrequser{'no'} = $checkedrequser{'yes'};
                   $checkedrequser{'yes'} = '';
               } 
               my $chgstr = ' onchange="javascript:reorderLTI(this.form,'."'lti_pos_".$item."'".');"';
               $datatable .= '<tr '.$css_class.'><td><span class="LC_nobreak">'
                            .'<select name="lti_pos_'.$item.'"'.$chgstr.'>';
               for (my $k=0; $k<=$maxnum; $k++) {
                   my $vpos = $k+1;
                   my $selstr;
                   if ($k == $i) {
                       $selstr = ' selected="selected" ';
                   }
                   $datatable .= '<option value="'.$k.'"'.$selstr.'>'.$vpos.'</option>';
               }
               $datatable .= '</select>'.('&nbsp;'x2).
                   '<label><input type="checkbox" name="lti_del" value="'.$item.'" />'.
                   &mt('Delete?').'</label></span></td>'.
                   '<td colspan="2">'.
                   '<fieldset><legend>'.&mt('Required settings').'</legend>'.
                   '<span class="LC_nobreak">'.$lt{'consumer'}.
                   ':<input type="text" size="15" name="lti_consumer_'.$i.'" value="'.$consumer.'" /></span> '.
                   ('&nbsp;'x2).
                   '<span class="LC_nobreak">'.$lt{'version'}.':<select name="lti_version_'.$i.'">'.
                   '<option value="LTI-1p0" selected="selected">1.1</option></select></span> '.
                   ('&nbsp;'x2).
                   '<span class="LC_nobreak">'.$lt{'lifetime'}.':<input type="text" name="lti_lifetime_'.$i.'"'.
                   'value="'.$lifetime.'" size="3" /></span>'.
                   ('&nbsp;'x2).
                    '<span class="LC_nobreak">'.$lt{'requser'}.':'.
                    '<label><input type="radio" name="lti_requser_'.$i.'" value="1"'.$onclickrequser.$checkedrequser{yes}.' />'.&mt('Yes').'</label>&nbsp;'."\n".
                    '<label><input type="radio" name="lti_requser_'.$i.'" value="0"'.$onclickrequser.$checkedrequser{no}.' />'.&mt('No').'</label></span>'."\n".
                   '<br /><br />'.
                   '<span class="LC_nobreak">'.$lt{'key'}.
                   ':<input type="text" size="25" name="lti_key_'.$i.'" value="'.$key.'" /></span> '.
                   ('&nbsp;'x2).
                   '<span class="LC_nobreak">'.$lt{'secret'}.':'.
                   '<input type="password" size="20" name="lti_secret_'.$i.'" value="'.$secret.'" />'.
                   '<label><input type="checkbox" name="visible" onclick="if (this.checked) { this.form.lti_secret_'.$i.'.type='."'text'".' } else { this.form.lti_secret_'.$i.'.type='."'password'".' }" />'.&mt('Visible input').'</label>'.
                   '<input type="hidden" name="lti_id_'.$i.'" value="'.$item.'" /></span>'.
                   '</fieldset>'.&lti_options($i,$current,$itemcount,%lt).'</td></tr>';
               $itemcount ++;
           }
       }
       $css_class = $itemcount%2?' class="LC_odd_row"':'';
       my $chgstr = ' onchange="javascript:reorderLTI(this.form,'."'lti_pos_add'".');"';
       $datatable .= '<tr '.$css_class.'><td><span class="LC_nobreak">'."\n".
                     '<input type="hidden" name="lti_maxnum" value="'.$maxnum.'" />'."\n".
                     '<select name="lti_pos_add"'.$chgstr.'>';
       for (my $k=0; $k<$maxnum+1; $k++) {
           my $vpos = $k+1;
           my $selstr;
           if ($k == $maxnum) {
               $selstr = ' selected="selected" ';
           }
           $datatable .= '<option value="'.$k.'"'.$selstr.'>'.$vpos.'</option>';
       }
       $datatable .= '</select>&nbsp;'."\n".
                     '<input type="checkbox" name="lti_add" value="1" />'.&mt('Add').'</span></td>'."\n".
                     '<td colspan="2">'.
                     '<fieldset><legend>'.&mt('Required settings').'</legend>'.
                     '<span class="LC_nobreak">'.$lt{'consumer'}.
                     ':<input type="text" size="15" name="lti_consumer_add" value="" /></span> '."\n".
                     ('&nbsp;'x2).
                     '<span class="LC_nobreak">'.$lt{'version'}.':<select name="lti_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="lti_lifetime_add" value="300" /></span> '."\n".
                     ('&nbsp;'x2).
                     '<span class="LC_nobreak">'.$lt{'requser'}.':'.
                     '<label><input type="radio" name="lti_requser_add" value="1" onclick="toggleLTI(this.form,'."'requser','add'".');" checked="checked" />'.&mt('Yes').'</label>&nbsp;'."\n".
                     '<label><input type="radio" name="lti_requser_add" value="0" onclick="toggleLTI(this.form,'."'requser','add'".');" />'.&mt('No').'</label></span>'."\n".
                     '<br /><br />'.
                     '<span class="LC_nobreak">'.$lt{'key'}.':<input type="text" size="25" name="lti_key_add" value="" /></span> '."\n".
                     ('&nbsp;'x2).
                     '<span class="LC_nobreak">'.$lt{'secret'}.':<input type="password" size="20" name="lti_secret_add" value="" />'.
                     '<label><input type="checkbox" name="visible" onclick="if (this.checked) { this.form.lti_secret_add.type='."'text'".' } else { this.form.lti_secret_add.type='."'password'".' }" />'.&mt('Visible input').'</label></span> '."\n".
                     '</fieldset>'.&lti_options('add',undef,$itemcount,%lt).
                     '</td>'."\n".
                     '</tr>'."\n";
       $$rowtotal ++;
       return $datatable;;
   }
   
   sub lti_names {
       my %lt = &Apache::lonlocal::texthash(
                                             'version'   => 'LTI Version',
                                           'url'       => 'URL',                                            'url'       => 'URL',
                                           'key'       => 'Key',                                            'key'       => 'Key',
                                             'lifetime'  => 'Nonce lifetime (s)',
                                             'consumer'  => 'Consumer',
                                           'secret'    => 'Secret',                                            'secret'    => 'Secret',
                                           'icon'      => 'Icon',                                               'requser'   => "User's identity sent",
                                           'user'      => 'Username:domain',                                            'email'     => 'Email address',
                                           'fullname'  => 'Full Name',                                            'sourcedid' => 'User ID',
                                           'firstname' => 'First Name',                                            'other'     => 'Other',
                                           'lastname'  => 'Last Name',                                            'passback'  => 'Can return grades to Consumer:',
                                           'email'     => 'E-mail',                                            'roster'    => 'Can retrieve roster from Consumer:',
                                           'roles'     => 'Role',                                            'topmenu'   => 'Display LON-CAPA page header',
                                           'window'    => 'Window/Tab',                                            'inlinemenu'=> 'Display LON-CAPA inline menu',
                                           'iframe'    => 'iFrame',  
                                           'height'    => 'Height',  
                                           'width'     => 'Width',  
                                           'passback'  => 'Tool can return grades:',  
                                           'roster'    => 'Tool can retrieve roster:',  
                                           'crstarget' => 'Display target',  
                                           'crslabel'  => 'Course label',  
                                           'crstitle'  => 'Course title',   
                                         );                                          );
     return %lt;      return %lt;
 }  }
   
   sub lti_options {
       my ($num,$current,$itemcount,%lt) = @_;
       my (%checked,%rolemaps,$crssecsrc,$userfield,$cidfield);
       $checked{'mapuser'}{'sourcedid'} = ' checked="checked"';
       $checked{'mapcrs'}{'course_offering_sourcedid'} = ' checked="checked"';
       $checked{'makecrs'}{'N'} = '  checked="checked"';
       $checked{'mapcrstype'} = {};
       $checked{'makeuser'} = {};
       $checked{'selfenroll'} = {};
       $checked{'crssec'} = {};
       $checked{'crssecsrc'} = {};
       $checked{'lcauth'} = {};
       $checked{'menuitem'} = {};
       if ($num eq 'add') {
           $checked{'lcauth'}{'lti'} = ' checked="checked"';
       }
       my $userfieldsty = 'none';
       my $crsfieldsty = 'none';
       my $crssecfieldsty = 'none';
       my $secsrcfieldsty = 'none';
       my $passbacksty = 'none';
       my $optionsty = 'block';
       my $lcauthparm;
       my $lcauthparmstyle = 'display:none';
       my $lcauthparmtext;
       my $menusty;
       my $numinrow = 4;
       my %menutitles = &ltimenu_titles();
   
       if (ref($current) eq 'HASH') {
           if (!$current->{'requser'}) {
               $optionsty = 'none';
           }
           if (($current->{'mapuser'} ne '') && ($current->{'mapuser'} ne 'lis_person_sourcedid')) {
               $checked{'mapuser'}{'sourcedid'} = '';
               if ($current->{'mapuser'} eq 'lis_person_contact_email_primary') {
                   $checked{'mapuser'}{'email'} = ' checked="checked"'; 
               } else {
                   $checked{'mapuser'}{'other'} = ' checked="checked"';
                   $userfield = $current->{'mapuser'};
                   $userfieldsty = 'inline-block';
               }
           }
           if (($current->{'mapcrs'} ne '') && ($current->{'mapcrs'} ne 'course_offering_sourcedid')) {
               $checked{'mapcrs'}{'course_offering_sourcedid'} = '';
               if ($current->{'mapcrs'} eq 'context_id') {
                   $checked{'mapcrs'}{'context_id'} = ' checked="checked"'; 
               } else {
                   $checked{'mapcrs'}{'other'} = ' checked="checked"';
                   $cidfield = $current->{'mapcrs'};
                   $crsfieldsty = 'inline-block';
               }
           }
           if (ref($current->{'mapcrstype'}) eq 'ARRAY') {
               foreach my $type (@{$current->{'mapcrstype'}}) {
                   $checked{'mapcrstype'}{$type} = ' checked="checked"';
               }
           }
           if ($current->{'makecrs'}) {
               $checked{'makecrs'}{'Y'} = '  checked="checked"';
           }
           if (ref($current->{'makeuser'}) eq 'ARRAY') {
               foreach my $role (@{$current->{'makeuser'}}) {
                   $checked{'makeuser'}{$role} = ' checked="checked"';
               }
           }
           if ($current->{'lcauth'} =~ /^(internal|localauth|krb4|krb5|lti)$/) {
               $checked{'lcauth'}{$1} = ' checked="checked"';
               unless (($current->{'lcauth'} eq 'lti') || ($current->{'lcauth'} eq 'internal')) {
                   $lcauthparm = $current->{'lcauthparm'};
                   $lcauthparmstyle = 'display:table-row'; 
                   if ($current->{'lcauth'} eq 'localauth') {
                       $lcauthparmtext = &mt('Local auth argument');
                   } else {
                       $lcauthparmtext = &mt('Kerberos domain');
                   }
               }
           }
           if (ref($current->{'selfenroll'}) eq 'ARRAY') {
               foreach my $role (@{$current->{'selfenroll'}}) {
                   $checked{'selfenroll'}{$role} = ' checked="checked"';
               }
           }
           if (ref($current->{'maproles'}) eq 'HASH') {
               %rolemaps = %{$current->{'maproles'}};
           }
           if ($current->{'section'} ne '') {
               $checked{'crssec'}{'Y'} = '  checked="checked"'; 
               $crssecfieldsty = 'inline-block';
               if ($current->{'section'} eq 'course_section_sourcedid') {
                   $checked{'crssecsrc'}{'sourcedid'} = ' checked="checked"';
               } else {
                   $checked{'crssecsrc'}{'other'} = ' checked="checked"';
                   $crssecsrc = $current->{'section'};
                   $secsrcfieldsty = 'inline-block';
               }
           } else {
               $checked{'crssec'}{'N'} = ' checked="checked"';
           }
           if ($current->{'topmenu'}) {
               $checked{'topmenu'}{'Y'} = ' checked="checked"';
           } else {
               $checked{'topmenu'}{'N'} = ' checked="checked"';
           }
           if ($current->{'inlinemenu'}) {
               $checked{'inlinemenu'}{'Y'} = ' checked="checked"';
           } else {
               $checked{'inlinemenu'}{'N'} = ' checked="checked"';
           }
           if (($current->{'topmenu'}) || ($current->{'inlinemenu'})) {
               $menusty = 'inline-block';
               if (ref($current->{'lcmenu'}) eq 'ARRAY') {
                   foreach my $item (@{$current->{'lcmenu'}}) {
                       if (exists($menutitles{$item})) {
                           $checked{'menuitem'}{$item} = ' checked="checked"';
                       }
                   }
               }
           } else {
               $menusty = 'none';
           }
       } else {
           $checked{'makecrs'}{'N'} = ' checked="checked"';
           $checked{'crssec'}{'N'} = ' checked="checked"';
           $checked{'topmenu'}{'N'} = ' checked="checked"';
           $checked{'inlinemenu'}{'Y'} = ' checked="checked"'; 
           $checked{'menuitem'}{'grades'} = ' checked="checked"';
           $menusty = 'inline-block'; 
       }
       my @coursetypes = ('official','unofficial','community','textbook','placement','lti');
       my %coursetypetitles = &Apache::lonlocal::texthash (
                                  official   => 'Official',
                                  unofficial => 'Unofficial',
                                  community  => 'Community',
                                  textbook   => 'Textbook',
                                  placement  => 'Placement Test',
                                  lti        => 'LTI Provider',
       );
       my @authtypes = ('internal','krb4','krb5','localauth');
       my %shortauth = (
                        internal => 'int',
                        krb4 => 'krb4',
                        krb5 => 'krb5',
                        localauth  => 'loc'
                       );
       my %authnames = &authtype_names();
       my @ltiroles = qw(Learner Instructor ContentDeveloper TeachingAssistant Mentor Member Manager Administrator);
       my @lticourseroles = qw(Learner Instructor TeachingAssistant Mentor);
       my @courseroles = ('cc','in','ta','ep','st');
       my $onclickuser = ' onclick="toggleLTI(this.form,'."'user','$num'".');"';
       my $onclickcrs = ' onclick="toggleLTI(this.form,'."'crs','$num'".');"';
       my $onclicksec = ' onclick="toggleLTI(this.form,'."'sec','$num'".');"';
       my $onclicksecsrc = ' onclick="toggleLTI(this.form,'."'secsrc','$num'".')"';
       my $onclicklcauth = ' onclick="toggleLTI(this.form,'."'lcauth','$num'".')"';
       my $onclickmenu = ' onclick="toggleLTI(this.form,'."'lcmenu','$num'".');"';
       my $output = '<fieldset class="ltioption_'.$num.'" style="display:'.$optionsty.'"><legend>'.&mt('Mapping users').'</legend>'.
                    '<div class="LC_floatleft"><span class="LC_nobreak">'.&mt('LON-CAPA username').':&nbsp;';
       foreach my $option ('sourcedid','email','other') {
           $output .= '<label><input type="radio" name="lti_mapuser_'.$num.'" value="'.$option.'"'.
                      $checked{'mapuser'}{$option}.$onclickuser.' />'.$lt{$option}.'</label>'.
                      ($option eq 'other' ? '' : ('&nbsp;'x2) );
       }
       $output .= '</span></div>'.
                  '<div class="LC_floatleft" style="display:'.$userfieldsty.';" id="lti_userfield_'.$num.'">'.
                  '<input type="text" name="lti_customuser_'.$num.'" '.
                  'value="'.$userfield.'" /></div></fieldset>'. 
                  '<fieldset class="ltioption_'.$num.'" style="display:'.$optionsty.'"><legend>'.&mt('Mapping course roles').'</legend><table><tr>';
       foreach my $ltirole (@lticourseroles) {
           my ($selected,$selectnone);
           if ($rolemaps{$ltirole} eq '') {
               $selectnone = ' selected="selected"';
           }
           $output .= '<td style="text-align: center">'.$ltirole.'<br />'.
                      '<select name="lti_maprole_'.$ltirole.'_'.$num.'">'.
                      '<option value=""'.$selectnone.'>'.&mt('Select').'</option>';
           foreach my $role (@courseroles) {
               unless ($selectnone) {
                   if ($rolemaps{$ltirole} eq $role) {
                       $selected = ' selected="selected"';
                   } else {
                       $selected = '';
                   }
               }
               $output .= '<option value="'.$role.'"'.$selected.'>'.
                          &Apache::lonnet::plaintext($role,'Course').
                          '</option>';
           }
           $output .= '</select></td>';
       }
       $output .= '</tr></table></fieldset>'.
                  '<fieldset class="ltioption_'.$num.'" style="display:'.$optionsty.'"><legend>'.&mt('Roles which may create user accounts').'</legend>';
       foreach my $ltirole (@ltiroles) {
           $output .= '<span class="LC_nobreak"><label><input type="checkbox" name="lti_makeuser_'.$num.'" value="'.$ltirole.'"'.
                      $checked{'makeuser'}{$ltirole}.' />'.$ltirole.'</label>&nbsp;</span> ';     
       }
       $output .= '</fieldset>'.
                  '<fieldset class="ltioption_'.$num.'" style="display:'.$optionsty.'"><legend>'.&mt('New user accounts created for LTI users').'</legend>'.
                  '<table>'.
                  &modifiable_userdata_row('lti','instdata_'.$num,$current,$numinrow,$itemcount).
                  '</table>'.
                  '<table class="LC_nested"><tr><td class="LC_left_item">LON-CAPA Authentication</td>'.
                  '<td class="LC_left_item">';
       foreach my $auth ('lti',@authtypes) {
           my $authtext;
           if ($auth eq 'lti') {
               $authtext = &mt('None');
           } else {
               $authtext = $authnames{$shortauth{$auth}};
           }
           $output .= '<span class="LC_nobreak"><label><input type="radio" name="lti_lcauth_'.$num.
                      '" value="'.$auth.'"'.$checked{'lcauth'}{$auth}.$onclicklcauth.' />'.
                      $authtext.'</label></span> &nbsp;';
       }
       $output .= '</td></tr>'.
                  '<tr id="lti_lcauth_parmrow_'.$num.'" style="'.$lcauthparmstyle.'">'.
                  '<td class="LC_right_item" colspan="2"><span class="LC_nobreak">'.
                  '<span id="lti_lcauth_parmtext_'.$num.'">'.$lcauthparmtext.'</span>'.
                  '<input type="text" name="lti_lcauthparm_'.$num.'" value="" /></span></td></tr>'.
                  '</table></fieldset>'.
                  '<fieldset class="ltioption_'.$num.'" style="display:'.$optionsty.'"><legend>'.&mt('Mapping courses').'</legend>'.
                  '<div class="LC_floatleft"><span class="LC_nobreak">'.
                  &mt('Unique course identifier').':&nbsp;';
       foreach my $option ('course_offering_sourcedid','context_id','other') {
           $output .= '<label><input type="radio" name="lti_mapcrs_'.$num.'" value="'.$option.'"'.
                      $checked{'mapcrs'}{$option}.$onclickcrs.' />'.$option.'</label>'.
                      ($option eq 'other' ? '' : ('&nbsp;'x2) );
       }
       $output .= '</span></div><div class="LC_floatleft" style="display:'.$crsfieldsty.';" id="lti_crsfield_'.$num.'">'.
                  '<input type="text" name="lti_mapcrsfield_'.$num.'" value="'.$cidfield.'" />'.
                  '</div><div style="padding:0;clear:both;margin:0;border:0"></div>'.
                  '<span class="LC_nobreak">'.&mt('LON-CAPA course type(s)').':&nbsp;';
       foreach my $type (@coursetypes) {
           $output .= '<label><input type="checkbox" name="lti_mapcrstype_'.$num.'" value="'.$type.'"'.
                      $checked{'mapcrstype'}{$type}.' />'.$coursetypetitles{$type}.'</label>'.
                      ('&nbsp;'x2);
       }
       $output .= '</span></fieldset>'.
                  '<fieldset class="ltioption_'.$num.'" style="display:'.$optionsty.'"><legend>'.&mt('Creating courses').'</legend>'.
                  '<span class="LC_nobreak">'.&mt('Course created (if absent) on Instructor access').':&nbsp;'.
                  '<label><input type="radio" name="lti_makecrs_'.$num.'" value="0"'.
                  $checked{'makecrs'}{'N'}.' />'.&mt('No').'</label>'.('&nbsp;'x2).
                  '<label><input type="radio" name="lti_makecrs_'.$num.'" value="1"'.
                  $checked{'makecrs'}{'Y'}.' />'.&mt('Yes').'</label></span>'.
                  '</fieldset>'.
                  '<fieldset class="ltioption_'.$num.'" style="display:'.$optionsty.'"><legend>'.&mt('Roles which may self-enroll').'</legend>';
       foreach my $lticrsrole (@lticourseroles) {
           $output .= '<span class="LC_nobreak"><label><input type="checkbox" name="lti_selfenroll_'.$num.'" value="'.$lticrsrole.'"'.
                      $checked{'selfenroll'}{$lticrsrole}.' />'.$lticrsrole.'</label>&nbsp;</span> ';
       }
       $output .= '</fieldset>'.
                  '<fieldset class="ltioption_'.$num.'" style="display:'.$optionsty.'"><legend>'.&mt('Course options').'</legend>'.
                  '<div class="LC_floatleft"><span class="LC_nobreak">'.&mt('Assign users to sections').':&nbsp;'.
                  '<label><input type="radio" name="lti_crssec_'.$num.'" value="0"'.
                  $checked{'crssec'}{'N'}.$onclicksec.' />'.&mt('No').'</label>'.('&nbsp;'x2).
                  '<label><input type="radio" name="lti_crssec_'.$num.'" value="1"'.
                  $checked{'crssec'}{'Y'}.$onclicksec.' />'.&mt('Yes').'</label></span></div>'.
                  '<div class="LC_floatleft" style="display:'.$crssecfieldsty.';" id="lti_crssecfield_'.$num.'">'.
                  '<span class="LC_nobreak">'.&mt('From').':<label>'.
                  '<input type="radio" name="lti_crssecsrc_'.$num.'" value="course_section_sourcedid"'.
                  $checked{'crssecsrc'}{'sourcedid'}.$onclicksecsrc.' />'.
                  &mt('Standard field').'</label>'.('&nbsp;'x2).
                  '<label><input type="radio" name="lti_crssecsrc_'.$num.'" value="other"'.
                  $checked{'crssecsrc'}{'other'}.$onclicksecsrc.' />'.&mt('Other').
                  '</label></span></div><div class="LC_floatleft" style="display:'.$secsrcfieldsty.';" id="lti_secsrcfield_'.$num.'">'.
                  '<input type="text" name="lti_customsection_'.$num.'" value="'.$crssecsrc.'" />'.
                  '</div><div style="padding:0;clear:both;margin:0;border:0"></div>';
       my ($pb1p1chk,$pb1p0chk,$onclickpb);
       foreach my $extra ('roster','passback') {
           my $checkedon = '';
           my $checkedoff = ' checked="checked"';
           if ($extra eq 'passback') {
               $pb1p1chk = ' checked="checked"';
               $pb1p0chk = '';
               $onclickpb = ' onclick="toggleLTI(this.form,'."'passback','$num'".');"'; 
           } else {
               $onclickpb = ''; 
           }
           if (ref($current) eq 'HASH') {
               if (($current->{$extra})) {
                   $checkedon = $checkedoff;
                   $checkedoff = '';
                   if ($extra eq 'passback') {
                       $passbacksty = 'inline-block';
                   }
                   if ($current->{'passbackformat'} eq '1.0') {
                       $pb1p0chk =  ' checked="checked"';
                       $pb1p1chk = '';
                   }
               }
           }
           $output .= $lt{$extra}.'&nbsp;'.
                      '<label><input type="radio" name="lti_'.$extra.'_'.$num.'" value="0"'.$checkedoff.$onclickpb.' />'.
                      &mt('No').'</label>'.('&nbsp;'x2).
                      '<label><input type="radio" name="lti_'.$extra.'_'.$num.'" value="1"'.$checkedon.$onclickpb.' />'.
                      &mt('Yes').'</label><br />';
       }
       $output .= '<div class="LC_floatleft" style="display:'.$passbacksty.';" id="lti_passback_'.$num.'">'.
                  '<span class="LC_nobreak">'.&mt('Grade format').
                  '<label><input type="radio" name="lti_passbackformat_'.$num.'" value="1.1"'.$pb1p1chk.' />'.
                  &mt('Outcomes Service (1.1)').'</label>'.('&nbsp;'x2).
                  '<label><input type="radio" name="lti_passbackformat_'.$num.'" value="1.0"'.$pb1p0chk.'/>'.
                  &mt('Outcomes Extension (1.0)').'</label></span></div></fieldset>'.
                  '<fieldset class="ltioption_'.$num.'" style="display:'.$optionsty.'"><legend>'.&mt('Course defaults (Course Coordinator can override)').'</legend>'.
                  '<div class="LC_floatleft"><span class="LC_nobreak">'.$lt{'topmenu'}.':&nbsp;'.
                  '<label><input type="radio" name="lti_topmenu_'.$num.'" value="0"'.
                  $checked{'topmenu'}{'N'}.$onclickmenu.' />'.&mt('No').'</label>'.('&nbsp;'x2).
                  '<label><input type="radio" name="lti_topmenu_'.$num.'" value="1"'.
                  $checked{'topmenu'}{'Y'}.$onclickmenu.' />'.&mt('Yes').'</label></span></div>'.
                  '<div style="padding:0;clear:both;margin:0;border:0"></div>'.
                  '<div class="LC_floatleft"><span class="LC_nobreak">'.$lt{'inlinemenu'}.':&nbsp;'.
                  '<label><input type="radio" name="lti_inlinemenu_'.$num.'" value="0"'.
                  $checked{'inlinemenu'}{'N'}.$onclickmenu.' />'.&mt('No').'</label>'.('&nbsp;'x2).
                  '<label><input type="radio" name="lti_inlinemenu_'.$num.'" value="1"'.
                  $checked{'inlinemenu'}{'Y'}.$onclickmenu.' />'.&mt('Yes').'</label></span></div>';
        $output .='<div style="padding:0;clear:both;margin:0;border:0"></div>'. 
                  '<div class="LC_floatleft" style="display:'.$menusty.';" id="lti_menufield_'.$num.'">'.
                  '<span class="LC_nobreak">'.&mt('Menu items').':&nbsp;';
       foreach my $type ('fullname','coursetitle','role','logout','grades') {
           $output .= '<label><input type="checkbox" name="lti_menuitem_'.$num.'" value="'.$type.'"'.
                      $checked{'menuitem'}{$type}.' />'.$menutitles{$type}.'</label>'.
                      ('&nbsp;'x2);
       }
       $output .= '</span></div></fieldset>';
   #        '<fieldset><legend>'.&mt('Assigning author roles').'</legend>';
   #
   #    $output .= '</fieldset>'.
   #        '<fieldset><legend>'.&mt('Assigning domain roles').'</legend>';
       return $output;
   }
   
   sub ltimenu_titles {
       return &Apache::lonlocal::texthash(
                                           fullname    => 'Full name',
                                           coursetitle => 'Course title',
                                           role        => 'Role',
                                           logout      => 'Logout',
                                           grades      => 'Grades',
       );
   }
   
 sub print_coursedefaults {  sub print_coursedefaults {
     my ($position,$dom,$settings,$rowtotal) = @_;      my ($position,$dom,$settings,$rowtotal) = @_;
     my ($css_class,$datatable,%checkedon,%checkedoff,%defaultchecked,@toggles);      my ($css_class,$datatable,%checkedon,%checkedoff,%defaultchecked,@toggles);
Line 3991  sub print_coursedefaults { Line 5260  sub print_coursedefaults {
         coursecredits        => 'Credits can be specified for courses',          coursecredits        => 'Credits can be specified for courses',
         uselcmath            => 'Math preview uses LON-CAPA previewer (javascript) in place of DragMath (Java)',          uselcmath            => 'Math preview uses LON-CAPA previewer (javascript) in place of DragMath (Java)',
         usejsme              => 'Molecule editor uses JSME (HTML5) in place of JME (Java)',          usejsme              => 'Molecule editor uses JSME (HTML5) in place of JME (Java)',
           texengine            => 'Default method to display mathematics',
         postsubmit           => 'Disable submit button/keypress following student submission',          postsubmit           => 'Disable submit button/keypress following student submission',
         canclone             => "People who may clone a course (besides course's owner and coordinators)",          canclone             => "People who may clone a course (besides course's owner and coordinators)",
         mysqltables          => 'Lifetime (s) of "Temporary" MySQL tables (student performance data) on homeserver',          mysqltables          => 'Lifetime (s) of "Temporary" MySQL tables (student performance data) on homeserver',
     );      );
     my %staticdefaults = (      my %staticdefaults = (
                              texengine            => 'MathJax',
                            anonsurvey_threshold => 10,                             anonsurvey_threshold => 10,
                            uploadquota          => 500,                             uploadquota          => 500,
                            postsubmit           => 60,                             postsubmit           => 60,
Line 4006  sub print_coursedefaults { Line 5277  sub print_coursedefaults {
                             'canuse_pdfforms' => 'off',                              'canuse_pdfforms' => 'off',
                             'uselcmath'       => 'on',                              'uselcmath'       => 'on',
                             'usejsme'         => 'on',                              'usejsme'         => 'on',
                             'canclone'        => 'none',                               'canclone'        => 'none',
                           );                            );
         @toggles = ('canuse_pdfforms','uselcmath','usejsme');          @toggles = ('canuse_pdfforms','uselcmath','usejsme');
           my $deftex = $staticdefaults{'texengine'};
           if (ref($settings) eq 'HASH') {
               if ($settings->{'texengine'}) {
                   if ($settings->{'texengine'} =~ /^(MathJax|mimetex|tth)$/) {
                       $deftex = $settings->{'texengine'};
                   }
               }
           }
           $css_class = $itemcount%2?' class="LC_odd_row"':'';
           my $mathdisp = '<tr'.$css_class.'><td style="vertical-align: top">'.
                          '<span class="LC_nobreak">'.$choices{'texengine'}.
                          '</span></td><td class="LC_right_item">'.
                          '<select name="texengine">'."\n";
           my %texoptions = (
                               MathJax  => 'MathJax',
                               mimetex  => &mt('Convert to Images'),
                               tth      => &mt('TeX to HTML'),
                            );
           foreach my $renderer ('MathJax','mimetex','tth') {
               my $selected = '';
               if ($renderer eq $deftex) {
                   $selected = ' selected="selected"';
               }
               $mathdisp .= '<option value="'.$renderer.'"'.$selected.'>'.$texoptions{$renderer}.'</option>'."\n";
           }
           $mathdisp .= '</select></td></tr>'."\n";
           $itemcount ++;
         ($datatable,$itemcount) = &radiobutton_prefs($settings,\@toggles,\%defaultchecked,          ($datatable,$itemcount) = &radiobutton_prefs($settings,\@toggles,\%defaultchecked,
                                                      \%choices,$itemcount);                                                       \%choices,$itemcount);
           $datatable = $mathdisp.$datatable;
         $css_class = $itemcount%2?' class="LC_odd_row"':'';          $css_class = $itemcount%2?' class="LC_odd_row"':'';
         $datatable .=          $datatable .=
             '<tr'.$css_class.'><td valign="top">'.              '<tr'.$css_class.'><td style="vertical-align: top">'.
             '<span class="LC_nobreak">'.$choices{'canclone'}.              '<span class="LC_nobreak">'.$choices{'canclone'}.
             '</span></td><td class="LC_left_item">';              '</span></td><td class="LC_left_item">';
         my $currcanclone = 'none';          my $currcanclone = 'none';
Line 4045  sub print_coursedefaults { Line 5344  sub print_coursedefaults {
                     $currcanclone = $settings->{'canclone'};                      $currcanclone = $settings->{'canclone'};
                 }                  }
             }              }
         }           }
         foreach my $option (@cloneoptions) {          foreach my $option (@cloneoptions) {
             my ($checked,$additional);              my ($checked,$additional);
             if ($currcanclone eq $option) {              if ($currcanclone eq $option) {
Line 4057  sub print_coursedefaults { Line 5356  sub print_coursedefaults {
                     if ($checked) {                      if ($checked) {
                         $show = 'block';                          $show = 'block';
                     }                      }
                     $additional = '<div id="cloneinstcode" style="display:'.$show.'" />'.                      $additional = '<div id="cloneinstcode" style="display:'.$show.';" />'.
                                   &mt('Institutional codes for new and cloned course have identical:').                                    &mt('Institutional codes for new and cloned course have identical:').
                                   '<br />';                                    '<br />';
                     foreach my $item (@code_order) {                      foreach my $item (@code_order) {
Line 4114  sub print_coursedefaults { Line 5413  sub print_coursedefaults {
                     foreach my $type (@types) {                      foreach my $type (@types) {
                         if (ref($settings->{'postsubmit'}->{'timeout'}) eq 'HASH') {                          if (ref($settings->{'postsubmit'}->{'timeout'}) eq 'HASH') {
                             if ($settings->{'postsubmit'}->{'timeout'}->{$type} =~ /^\d+$/) {                              if ($settings->{'postsubmit'}->{'timeout'}->{$type} =~ /^\d+$/) {
                                 $deftimeout{$type} = $settings->{'postsubmit'}->{'timeout'}->{$type};                                   $deftimeout{$type} = $settings->{'postsubmit'}->{'timeout'}->{$type};
                             } else {                              } else {
                                 $deftimeout{$type} = $staticdefaults{'postsubmit'};                                  $deftimeout{$type} = $staticdefaults{'postsubmit'};
                             }                              }
Line 4165  sub print_coursedefaults { Line 5464  sub print_coursedefaults {
         $datatable .= '<tr'.$css_class.'><td><span class="LC_nobreak">'.          $datatable .= '<tr'.$css_class.'><td><span class="LC_nobreak">'.
                       $choices{'uploadquota'}.                        $choices{'uploadquota'}.
                       '</span></td>'.                        '</span></td>'.
                       '<td align="right" class="LC_right_item">'.                        '<td style="text-align: right" class="LC_right_item">'.
                       '<table><tr>';                        '<table><tr>';
         foreach my $type (@types) {          foreach my $type (@types) {
             $datatable .= '<td align="center">'.&mt($type).'<br />'.              $datatable .= '<td style="text-align: center">'.&mt($type).'<br />'.
                            '<input type="text" name="uploadquota_'.$type.'"'.                             '<input type="text" name="uploadquota_'.$type.'"'.
                            ' value="'.$curruploadquota{$type}.'" size="5" /></td>';                             ' value="'.$curruploadquota{$type}.'" size="5" /></td>';
         }          }
Line 4183  sub print_coursedefaults { Line 5482  sub print_coursedefaults {
                          '<i>'.&mt('Default credits').'</i><br /><table><tr>';                           '<i>'.&mt('Default credits').'</i><br /><table><tr>';
         foreach my $type (@types) {          foreach my $type (@types) {
             next if ($type eq 'community');              next if ($type eq 'community');
             $additional .= '<td align="center">'.&mt($type).'<br />'.              $additional .= '<td style="text-align: center">'.&mt($type).'<br />'.
                            '<input type="text" name="'.$type.'_credits"'.                             '<input type="text" name="'.$type.'_credits"'.
                            ' value="'.$defcredits{$type}.'" size="3" /></td>';                             ' value="'.$defcredits{$type}.'" size="3" /></td>';
         }          }
Line 4207  sub print_coursedefaults { Line 5506  sub print_coursedefaults {
                       '<i>'.&mt('Enter 0 to remain disabled until page reload.').'</i><br />'.                        '<i>'.&mt('Enter 0 to remain disabled until page reload.').'</i><br />'.
                       '<table><tr>';                        '<table><tr>';
         foreach my $type (@types) {          foreach my $type (@types) {
             $additional .= '<td align="center">'.&mt($type).'<br />'.              $additional .= '<td style="text-align: center">'.&mt($type).'<br />'.
                            '<input type="text" name="'.$type.'_timeout" value="'.                             '<input type="text" name="'.$type.'_timeout" value="'.
                            $deftimeout{$type}.'" size="5" /></td>';                             $deftimeout{$type}.'" size="5" /></td>';
         }          }
Line 4225  sub print_coursedefaults { Line 5524  sub print_coursedefaults {
         $datatable .= '<tr'.$css_class.'><td><span class="LC_nobreak">'.          $datatable .= '<tr'.$css_class.'><td><span class="LC_nobreak">'.
                       $choices{'mysqltables'}.                        $choices{'mysqltables'}.
                       '</span></td>'.                        '</span></td>'.
                       '<td align="right" class="LC_right_item">'.                        '<td style="text-align: right" class="LC_right_item">'.
                       '<table><tr>';                        '<table><tr>';
         foreach my $type (@types) {          foreach my $type (@types) {
             $datatable .= '<td align="center">'.&mt($type).'<br />'.              $datatable .= '<td style="text-align: center">'.&mt($type).'<br />'.
                            '<input type="text" name="mysqltables_'.$type.'"'.                             '<input type="text" name="mysqltables_'.$type.'"'.
                            ' value="'.$currmysql{$type}.'" size="5" /></td>';                             ' value="'.$currmysql{$type}.'" size="8" /></td>';
         }          }
         $datatable .= '</tr></table></td></tr>'."\n";          $datatable .= '</tr></table></td></tr>'."\n";
         $itemcount ++;          $itemcount ++;
Line 4428  sub print_validation_rows { Line 5727  sub print_validation_rows {
                               '</label></span> ';                                '</label></span> ';
             }              }
         } elsif ($item eq 'markup') {          } elsif ($item eq 'markup') {
             $datatable .= '<textarea name="'.$caller.'_validation_markup" cols="50" rows="5" wrap="soft">'.              $datatable .= '<textarea name="'.$caller.'_validation_markup" cols="50" rows="5">'.
                            $currvalidation{$item}.                             $currvalidation{$item}.
                               '</textarea>';                                '</textarea>';
         }          }
Line 4450  sub print_validation_rows { Line 5749  sub print_validation_rows {
         my ($numdc,$dctable,$rows) = &active_dc_picker($dom,$numinrow,'radio',          my ($numdc,$dctable,$rows) = &active_dc_picker($dom,$numinrow,'radio',
                                                        'validationdc',%currhash);                                                         'validationdc',%currhash);
         my $css_class = $itemcount%2 ? ' class="LC_odd_row"' : '';          my $css_class = $itemcount%2 ? ' class="LC_odd_row"' : '';
         $datatable .= '</td></tr><tr'.$css_class.'><td>';          $datatable .= '<tr'.$css_class.'><td>';
         if ($numdc > 1) {          if ($numdc > 1) {
             $datatable .= &mt('Course creation processed as: (choose Dom. Coord.)');              $datatable .= &mt('Course creation processed as: (choose Dom. Coord.)');
         } else {          } else {
Line 4652  sub print_ssl { Line 5951  sub print_ssl {
         my @domservers = &Apache::lonnet::get_servers($dom);          my @domservers = &Apache::lonnet::get_servers($dom);
         my %servers = &Apache::lonnet::internet_dom_servers($dom);          my %servers = &Apache::lonnet::internet_dom_servers($dom);
         my %altids = &id_for_thisdom(%servers);          my %altids = &id_for_thisdom(%servers);
         if ($position eq 'middle') {          if (($position eq 'connto') || ($position eq 'connfrom')) {
               my $legacy;
               unless (ref($settings) eq 'HASH') {
                   my $name;
                   if ($position eq 'connto') {
                       $name = 'loncAllowInsecure';
                   } else {
                       $name = 'londAllowInsecure';
                   }
                   my $primarylibserv = &Apache::lonnet::domain($dom,'primary');
                   my @ids=&Apache::lonnet::current_machine_ids();
                   if (($primarylibserv ne '') && (!grep(/^\Q$primarylibserv\E$/,@ids))) {
                       my %what = (
                                      $name => 1,
                                  );
                       my ($result,$returnhash) =
                           &Apache::lonnet::get_remote_globals($primarylibserv,\%what);
                       if ($result eq 'ok') {
                           if (ref($returnhash) eq 'HASH') {
                               $legacy = $returnhash->{$name};
                           }
                       }
                   } else {
                       $legacy = $Apache::lonnet::perlvar{$name};
                   }
               }
             foreach my $type ('dom','intdom','other') {              foreach my $type ('dom','intdom','other') {
                 my %checked;                  my %checked;
                 $css_class = $itemcount%2?' class="LC_odd_row"':'';                  $css_class = $itemcount%2?' class="LC_odd_row"':'';
Line 4679  sub print_ssl { Line 6003  sub print_ssl {
                 unless ($skip) {                  unless ($skip) {
                     $checked{'yes'} = ' checked="checked"';                       $checked{'yes'} = ' checked="checked"'; 
                     if (ref($settings) eq 'HASH') {                      if (ref($settings) eq 'HASH') {
                         if (ref($settings->{'connect'}) eq 'HASH') {                          if (ref($settings->{$position}) eq 'HASH') {
                             if ($settings->{'connect'}->{$type} =~ /^(no|req)$/) {                              if ($settings->{$position}->{$type} =~ /^(no|req)$/) {
                                 $checked{$1} = $checked{'yes'};                                  $checked{$1} = $checked{'yes'};
                                 delete($checked{'yes'});                                   delete($checked{'yes'}); 
                             }                              }
                         }                          }
                       } else {
                           if ($legacy == 0) {
                               $checked{'req'} = $checked{'yes'};
                               delete($checked{'yes'});    
                           }
                     }                      }
                     foreach my $option ('no','yes','req') {                      foreach my $option ('no','yes','req') {
                         $datatable .= '<span class="LC_nobreak"><label>'.                          $datatable .= '<span class="LC_nobreak"><label>'.
                                       '<input type="radio" name="connect_'.$type.'" '.                                        '<input type="radio" name="'.$position.'_'.$type.'" '.
                                       'value="'.$option.'"'.$checked{$option}.' />'.$titles{$option}.                                        'value="'.$option.'"'.$checked{$option}.' />'.$titles{$option}.
                                       '</label></span>'.('&nbsp;'x2);                                        '</label></span>'.('&nbsp;'x2);
                     }                      }
Line 4719  sub ssl_titles { Line 6048  sub ssl_titles {
                dom           => 'LON-CAPA servers/VMs from same domain',                 dom           => 'LON-CAPA servers/VMs from same domain',
                intdom        => 'LON-CAPA servers/VMs from same "internet" domain',                 intdom        => 'LON-CAPA servers/VMs from same "internet" domain',
                other         => 'External LON-CAPA servers/VMs',                 other         => 'External LON-CAPA servers/VMs',
                connect       => 'Connections to other servers',                 connto        => 'Connections to other servers',
                  connfrom      => 'Connections from other servers',
                replication   => 'Replicating content to other institutions',                 replication   => 'Replicating content to other institutions',
                certreq       => 'Client certificate required, but specific domains exempt',                 certreq       => 'Client certificate required, but specific domains exempt',
                nocertreq     => 'No client certificate required, except for specific domains',                 nocertreq     => 'No client certificate required, except for specific domains',
Line 4929  sub spares_row { Line 6259  sub spares_row {
                             <span class="LC_nobreak">'.                              <span class="LC_nobreak">'.
                           &mt('[_1] when busy, offloads to:'                            &mt('[_1] when busy, offloads to:'
                               ,'<b>'.$server.'</b>').'</span><br />'.                                ,'<b>'.$server.'</b>').'</span><br />'.
                           '<span class="LC_nobreak">'."\n".                             '<span class="LC_nobreak">'."\n".
                           '<label><input type="checkbox" name="offloadnow" value="'.$server.'"'.$checkednow.' />'.                            '<label><input type="checkbox" name="offloadnow" value="'.$server.'"'.$checkednow.' />'.
                           '&nbsp;'.&mt('Switch active users on next access').'</label></span>'.                            '&nbsp;'.&mt('Switch active users on next access').'</label></span>'.
                           "\n";                            "\n";
Line 5056  sub print_loadbalancing { Line 6386  sub print_loadbalancing {
     my $numinrow = 1;      my $numinrow = 1;
     my $datatable;      my $datatable;
     my %servers = &Apache::lonnet::internet_dom_servers($dom);      my %servers = &Apache::lonnet::internet_dom_servers($dom);
     my (%currbalancer,%currtargets,%currrules,%existing);      my (%currbalancer,%currtargets,%currrules,%existing,%currcookies);
     if (ref($settings) eq 'HASH') {      if (ref($settings) eq 'HASH') {
         %existing = %{$settings};          %existing = %{$settings};
     }      }
     if ((keys(%servers) > 1) || (keys(%existing) > 0)) {      if ((keys(%servers) > 1) || (keys(%existing) > 0)) {
         &get_loadbalancers_config(\%servers,\%existing,\%currbalancer,          &get_loadbalancers_config(\%servers,\%existing,\%currbalancer,
                                   \%currtargets,\%currrules);                                    \%currtargets,\%currrules,\%currcookies);
     } else {      } else {
         return;          return;
     }      }
Line 5096  sub print_loadbalancing { Line 6426  sub print_loadbalancing {
         my $disabled_div_style = 'display: block';          my $disabled_div_style = 'display: block';
         my $homedom_div_style = 'display: none';          my $homedom_div_style = 'display: none';
         $datatable .= '<tr class="'.$css_class[$cssidx].'">'.          $datatable .= '<tr class="'.$css_class[$cssidx].'">'.
                       '<td rowspan="'.$rownum.'" valign="top">'.                        '<td rowspan="'.$rownum.'" style="vertical-align: top">'.
                       '<p>';                        '<p>';
         if ($lonhost eq '') {          if ($lonhost eq '') {
             $datatable .= '<span class="LC_nobreak">';              $datatable .= '<span class="LC_nobreak">';
Line 5129  sub print_loadbalancing { Line 6459  sub print_loadbalancing {
                 $homedom_div_style = 'display: block';                  $homedom_div_style = 'display: block';
             }              }
         }          }
         $datatable .= '</p></td><td rowspan="'.$rownum.'" valign="top">'.          $datatable .= '</p></td><td rowspan="'.$rownum.'" style="vertical-align: top">'.
                   '<div id="loadbalancing_disabled_'.$balnum.'" style="'.                    '<div id="loadbalancing_disabled_'.$balnum.'" style="'.
                   $disabled_div_style.'">'.$disabledtext.'</div>'."\n".                    $disabled_div_style.'">'.$disabledtext.'</div>'."\n".
                   '<div id="loadbalancing_targets_'.$balnum.'" style="'.$targets_div_style.'">'.&mt('Offloads to:').'<br />';                    '<div id="loadbalancing_targets_'.$balnum.'" style="'.$targets_div_style.'">'.&mt('Offloads to:').'<br />';
Line 5139  sub print_loadbalancing { Line 6469  sub print_loadbalancing {
         my %hostherechecked = (          my %hostherechecked = (
                                   no => ' checked="checked"',                                    no => ' checked="checked"',
                               );                                );
           my %balcookiechecked = (
                                     no => ' checked="checked"', 
                                  );
         foreach my $sparetype (@sparestypes) {          foreach my $sparetype (@sparestypes) {
             my $targettable;              my $targettable;
             for (my $i=0; $i<$numspares; $i++) {              for (my $i=0; $i<$numspares; $i++) {
Line 5194  sub print_loadbalancing { Line 6527  sub print_loadbalancing {
                 }                  }
             }              }
         }          }
           if ($currcookies{$lonhost}) {
               %balcookiechecked = (
                                       yes => ' checked="checked"',
                                   );
           }
         $datatable .= &mt('Hosting on balancer itself').'<br />'.          $datatable .= &mt('Hosting on balancer itself').'<br />'.
                       '<label><input type="radio" name="loadbalancing_target_'.$balnum.'_hosthere" value="no"'.                        '<label><input type="radio" name="loadbalancing_target_'.$balnum.'_hosthere" value="no"'.
                       $hostherechecked{'no'}.' />'.&mt('No').'</label><br />';                        $hostherechecked{'no'}.' />'.&mt('No').'</label><br />';
Line 5202  sub print_loadbalancing { Line 6540  sub print_loadbalancing {
                           'value="'.$sparetype.'"'.$hostherechecked{$sparetype}.' /><i>'.$typetitles{$sparetype}.                            'value="'.$sparetype.'"'.$hostherechecked{$sparetype}.' /><i>'.$typetitles{$sparetype}.
                           '</i></label><br />';                            '</i></label><br />';
         }          }
         $datatable .= '</div></td></tr>'.          $datatable .= &mt('Use balancer cookie').'<br />'.
                         '<label><input type="radio" name="loadbalancing_cookie_'.$balnum.'" value="1"'.
                         $balcookiechecked{'yes'}.' />'.&mt('Yes').'</label><br />'.
                         '<label><input type="radio" name="loadbalancing_cookie_'.$balnum.'" value="0"'.
                         $balcookiechecked{'no'}.' />'.&mt('No').'</label><br />'.
                         '</div></td></tr>'.
                       &loadbalancing_rules($dom,$intdom,$currrules{$lonhost},                        &loadbalancing_rules($dom,$intdom,$currrules{$lonhost},
                                            $othertitle,$usertypes,$types,\%servers,                                             $othertitle,$usertypes,$types,\%servers,
                                            \%currbalancer,$lonhost,                                             \%currbalancer,$lonhost,
Line 5216  sub print_loadbalancing { Line 6559  sub print_loadbalancing {
 }  }
   
 sub get_loadbalancers_config {  sub get_loadbalancers_config {
     my ($servers,$existing,$currbalancer,$currtargets,$currrules) = @_;      my ($servers,$existing,$currbalancer,$currtargets,$currrules,$currcookies) = @_;
     return unless ((ref($servers) eq 'HASH') &&      return unless ((ref($servers) eq 'HASH') &&
                    (ref($existing) eq 'HASH') && (ref($currbalancer) eq 'HASH') &&                     (ref($existing) eq 'HASH') && (ref($currbalancer) eq 'HASH') &&
                    (ref($currtargets) eq 'HASH') && (ref($currrules) eq 'HASH'));                     (ref($currtargets) eq 'HASH') && (ref($currrules) eq 'HASH') &&
                      (ref($currcookies) eq 'HASH'));
     if (keys(%{$existing}) > 0) {      if (keys(%{$existing}) > 0) {
         my $oldlonhost;          my $oldlonhost;
         foreach my $key (sort(keys(%{$existing}))) {          foreach my $key (sort(keys(%{$existing}))) {
Line 5238  sub get_loadbalancers_config { Line 6582  sub get_loadbalancers_config {
                 $currbalancer->{$key} = 1;                  $currbalancer->{$key} = 1;
                 $currtargets->{$key} = $existing->{$key}{'targets'};                  $currtargets->{$key} = $existing->{$key}{'targets'};
                 $currrules->{$key} = $existing->{$key}{'rules'};                  $currrules->{$key} = $existing->{$key}{'rules'};
                   if ($existing->{$key}{'cookie'}) {
                       $currcookies->{$key} = 1;
                   }
             }              }
         }          }
     } else {      } else {
Line 5293  sub loadbalancing_titles { Line 6640  sub loadbalancing_titles {
            '_LC_ipchange'    => &mt('Non-SSO users with IP mismatch'),             '_LC_ipchange'    => &mt('Non-SSO users with IP mismatch'),
                      );                       );
     my @alltypes = ('_LC_adv','_LC_author','_LC_internetdom','_LC_external','_LC_ipchangesso','_LC_ipchange');      my @alltypes = ('_LC_adv','_LC_author','_LC_internetdom','_LC_external','_LC_ipchangesso','_LC_ipchange');
       my @available;
     if (ref($types) eq 'ARRAY') {      if (ref($types) eq 'ARRAY') {
         unshift(@alltypes,@{$types},'default');          @available = @{$types};
     }      }
       unless (grep(/^default$/,@available)) {
           push(@available,'default');
       }
       unshift(@alltypes,@available);
     my %titles;      my %titles;
     foreach my $type (@alltypes) {      foreach my $type (@alltypes) {
         if ($type =~ /^_LC_/) {          if ($type =~ /^_LC_/) {
Line 5336  sub loadbalance_rule_row { Line 6688  sub loadbalance_rule_row {
     }      }
     my $space;      my $space;
     if ($islast && $num == 1) {      if ($islast && $num == 1) {
         $space = '<div display="inline-block">&nbsp;</div>';          $space = '<div style="display:inline-block;">&nbsp;</div>';
     }      }
     my $output =      my $output =
         '<tr class="'.$css_class.'" id="balanceruletr_'.$balnum.'_'.$num.'"><td valign="top">'.$space.          '<tr class="'.$css_class.'" id="balanceruletr_'.$balnum.'_'.$num.'"><td style="vertical-align: top">'.$space.
         '<div id="balanceruletitle_'.$balnum.'_'.$type.'" style="'.$style.'">'.$title.'</div></td>'."\n".          '<div id="balanceruletitle_'.$balnum.'_'.$type.'" style="'.$style.'">'.$title.'</div></td>'."\n".
         '<td valaign="top">'.$space.          '<td valaign="top">'.$space.
         '<div id="balancerule_'.$balnum.'_'.$type.'" style="'.$style.'">'."\n";          '<div id="balancerule_'.$balnum.'_'.$type.'" style="'.$style.'">'."\n";
Line 5422  sub contact_titles { Line 6774  sub contact_titles {
                    'adminemail'      => 'Default Server Admin E-mail address',                     'adminemail'      => 'Default Server Admin E-mail address',
                    'errormail'       => 'Error reports to be e-mailed to',                     'errormail'       => 'Error reports to be e-mailed to',
                    'packagesmail'    => 'Package update alerts to be e-mailed to',                     'packagesmail'    => 'Package update alerts to be e-mailed to',
                    'helpdeskmail'    => "Helpdesk requests for this domain's users",                     'helpdeskmail'    => "Helpdesk requests from all users in this domain",
                    'otherdomsmail'   => 'Helpdesk requests for other (unconfigured) domains',                       'otherdomsmail'   => 'Helpdesk requests from users in other (unconfigured) domains',
                    'lonstatusmail'   => 'E-mail from nightly status check (warnings/errors)',                     'lonstatusmail'   => 'E-mail from nightly status check (warnings/errors)',
                    'requestsmail'    => 'E-mail from course requests requiring approval',                     'requestsmail'    => 'E-mail from course requests requiring approval',
                    'updatesmail'     => 'E-mail from nightly check of LON-CAPA module integrity/updates',                     'updatesmail'     => 'E-mail from nightly check of LON-CAPA module integrity/updates',
                    'idconflictsmail' => 'E-mail from bi-nightly check for multiple users sharing same student/employee ID',                     'idconflictsmail' => 'E-mail from bi-nightly check for multiple users sharing same student/employee ID',
                      'errorthreshold'  => 'Error/warning threshold for status e-mail',
                      'errorsysmail'    => 'Error threshold for e-mail to core group',
                      'errorweights'    => 'Weights used to compute error count',
                      'errorexcluded'   => 'Servers with unsent updates excluded from count',
                  );                   );
     my %short_titles = &Apache::lonlocal::texthash (      my %short_titles = &Apache::lonlocal::texthash (
                            adminemail   => 'Admin E-mail address',                             adminemail   => 'Admin E-mail address',
Line 5444  sub helpform_fields { Line 6800  sub helpform_fields {
                        'cc'         => 'Cc e-mail',                         'cc'         => 'Cc e-mail',
                        'course'     => 'Course Details',                         'course'     => 'Course Details',
                        'section'    => 'Sections',                         'section'    => 'Sections',
                        'screenshot' => 'File upload',                          'screenshot' => 'File upload',
     );      );
     my @fields = ('username','phone','user','course','section','cc','screenshot');      my @fields = ('username','phone','user','course','section','cc','screenshot');
     my %possoptions = (      my %possoptions = (
                         username     => ['yes','no','req'],                          username     => ['yes','no','req'],
                         phone        => ['yes','no','req'],                             phone        => ['yes','no','req'],
                         user         => ['yes','no'],                          user         => ['yes','no'],
                         cc           => ['yes','no'],                           cc           => ['yes','no'],
                         course       => ['yes','no'],                          course       => ['yes','no'],
                         section      => ['yes','no'],                          section      => ['yes','no'],
                         screenshot   => ['yes','no'],                          screenshot   => ['yes','no'],
Line 5486  sub courserequest_titles { Line 6842  sub courserequest_titles {
                                    community  => 'Communities',                                     community  => 'Communities',
                                    textbook   => 'Textbook',                                     textbook   => 'Textbook',
                                    placement  => 'Placement tests',                                     placement  => 'Placement tests',
                                      lti        => 'LTI Provider',
                                    norequest  => 'Not allowed',                                     norequest  => 'Not allowed',
                                    approval   => 'Approval by Dom. Coord.',                                     approval   => 'Approval by DC',
                                    validate   => 'With validation',                                     validate   => 'With validation',
                                    autolimit  => 'Numerical limit',                                     autolimit  => 'Numerical limit',
                                    unlimited  => '(blank for unlimited)',                                     unlimited  => '(blank for unlimited)',
Line 5576  sub print_usercreation { Line 6933  sub print_usercreation {
             }              }
             $datatable .= '<tr'.$css_class.'>'.              $datatable .= '<tr'.$css_class.'>'.
                          '<td><span class="LC_nobreak">'.$lt{$item}.                           '<td><span class="LC_nobreak">'.$lt{$item}.
                          '</span></td><td align="right">';                           '</span></td><td style="text-align: right">';
             my @options = ('any');              my @options = ('any');
             if (ref($rules) eq 'HASH') {              if (ref($rules) eq 'HASH') {
                 if (keys(%{$rules}) > 0) {                  if (keys(%{$rules}) > 0) {
Line 5599  sub print_usercreation { Line 6956  sub print_usercreation {
         }          }
     } else {      } else {
         my @contexts = ('author','course','domain');          my @contexts = ('author','course','domain');
         my @authtypes = ('int','krb4','krb5','loc');          my @authtypes = ('int','krb4','krb5','loc','lti');
         my %checked;          my %checked;
         if (ref($settings) eq 'HASH') {          if (ref($settings) eq 'HASH') {
             if (ref($settings->{'authtypes'}) eq 'HASH') {              if (ref($settings->{'authtypes'}) eq 'HASH') {
Line 5650  sub print_usercreation { Line 7007  sub print_usercreation {
   
 sub print_selfcreation {  sub print_selfcreation {
     my ($position,$dom,$settings,$rowtotal) = @_;      my ($position,$dom,$settings,$rowtotal) = @_;
     my (@selfcreate,$createsettings,$processing,$datatable);      my (@selfcreate,$createsettings,$processing,$emailoptions,$emailverified,
           $emaildomain,$datatable);
     if (ref($settings) eq 'HASH') {      if (ref($settings) eq 'HASH') {
         if (ref($settings->{'cancreate'}) eq 'HASH') {          if (ref($settings->{'cancreate'}) eq 'HASH') {
             $createsettings = $settings->{'cancreate'};              $createsettings = $settings->{'cancreate'};
Line 5667  sub print_selfcreation { Line 7025  sub print_selfcreation {
                 if (ref($createsettings->{'selfcreateprocessing'}) eq 'HASH') {                  if (ref($createsettings->{'selfcreateprocessing'}) eq 'HASH') {
                     $processing = $createsettings->{'selfcreateprocessing'};                      $processing = $createsettings->{'selfcreateprocessing'};
                 }                  }
                   if (ref($createsettings->{'emailoptions'}) eq 'HASH') {
                       $emailoptions = $createsettings->{'emailoptions'};
                   }
                   if (ref($createsettings->{'emailverified'}) eq 'HASH') {
                       $emailverified = $createsettings->{'emailverified'};
                   }
                   if (ref($createsettings->{'emaildomain'}) eq 'HASH') {
                       $emaildomain = $createsettings->{'emaildomain'};
                   }
             }              }
         }          }
     }      }
     my %radiohash;      my %radiohash;
     my $numinrow = 4;      my $numinrow = 4;
     map { $radiohash{'cancreate_'.$_} = 1; } @selfcreate;      map { $radiohash{'cancreate_'.$_} = 1; } @selfcreate;
       my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom);
     if ($position eq 'top') {      if ($position eq 'top') {
         my %choices = &Apache::lonlocal::texthash (          my %choices = &Apache::lonlocal::texthash (
                                                       cancreate_login      => 'Institutional Login',                                                        cancreate_login      => 'Institutional Login',
Line 5688  sub print_selfcreation { Line 7056  sub print_selfcreation {
                                                      \%choices,$itemcount,$onclick);                                                       \%choices,$itemcount,$onclick);
         $$rowtotal += $itemcount;          $$rowtotal += $itemcount;
                   
         my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom);  
   
         if (ref($usertypes) eq 'HASH') {          if (ref($usertypes) eq 'HASH') {
             if (keys(%{$usertypes}) > 0) {              if (keys(%{$usertypes}) > 0) {
                 $datatable .= &insttypes_row($createsettings,$types,$usertypes,                  $datatable .= &insttypes_row($createsettings,$types,$usertypes,
                                              $dom,$numinrow,$othertitle,                                               $dom,$numinrow,$othertitle,
                                              'statustocreate',$$rowtotal);                                               'statustocreate',$rowtotal);
                 $$rowtotal ++;                  $$rowtotal ++;
             }              }
         }          }
Line 5707  sub print_selfcreation { Line 7073  sub print_selfcreation {
         $datatable .= '<tr'.$css_class.'>'.          $datatable .= '<tr'.$css_class.'>'.
                      '<td class="LC_left_item">'.&mt('Mapping of Shibboleth environment variable names to user data fields (SSO auth)').'</td>'.                       '<td class="LC_left_item">'.&mt('Mapping of Shibboleth environment variable names to user data fields (SSO auth)').'</td>'.
                      '<td class="LC_left_item">'."\n".                       '<td class="LC_left_item">'."\n".
                      '<table><tr><td>'."\n";                       '<table>'."\n";
         for (my $i=0; $i<@fields; $i++) {          for (my $i=0; $i<@fields; $i++) {
             $rem = $i%($numperrow);              $rem = $i%($numperrow);
             if ($rem == 0) {              if ($rem == 0) {
Line 5739  sub print_selfcreation { Line 7105  sub print_selfcreation {
         $$rowtotal ++;          $$rowtotal ++;
     } elsif ($position eq 'middle') {      } elsif ($position eq 'middle') {
         my %domconf = &Apache::lonnet::get_dom('configuration',['usermodification'],$dom);          my %domconf = &Apache::lonnet::get_dom('configuration',['usermodification'],$dom);
         my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom);          my @posstypes;
         $usertypes->{'default'} = $othertitle;  
         if (ref($types) eq 'ARRAY') {          if (ref($types) eq 'ARRAY') {
             push(@{$types},'default');              @posstypes = @{$types};
             $usertypes->{'default'} = $othertitle;          }
             foreach my $status (@{$types}) {          unless (grep(/^default$/,@posstypes)) {
                 $datatable .= &modifiable_userdata_row('selfcreate',$status,$domconf{'usermodification'},              push(@posstypes,'default');
                                                        $numinrow,$$rowtotal,$usertypes);          }
                 $$rowtotal ++;          my %usertypeshash;
             }          if (ref($usertypes) eq 'HASH') {
               %usertypeshash = %{$usertypes};
           }
           $usertypeshash{'default'} = $othertitle;
           foreach my $status (@posstypes) {
               $datatable .= &modifiable_userdata_row('selfcreate',$status,$domconf{'usermodification'},
                                                      $numinrow,$$rowtotal,\%usertypeshash);
               $$rowtotal ++;
         }          }
     } else {      } else {
         my %choices = &Apache::lonlocal::texthash (          my %choices = &Apache::lonlocal::texthash (
                                                       cancreate_email => 'E-mail address as username',                            'cancreate_email' => 'Non-institutional username (via e-mail verification)',
                                                   );                                                    );
         my @toggles = sort(keys(%choices));          my @toggles = sort(keys(%choices));
         my %defaultchecked = (          my %defaultchecked = (
                                'cancreate_email' => 'off',                                 'cancreate_email' => 'off',
                              );                               );
         my $itemcount = 0;          my $customclass = 'LC_selfcreate_email';
           my $classprefix = 'LC_canmodify_emailusername_';
           my $optionsprefix = 'LC_options_emailusername_';
         my $display = 'none';          my $display = 'none';
           my $rowstyle = 'display:none';
         if (grep(/^\Qemail\E$/,@selfcreate)) {          if (grep(/^\Qemail\E$/,@selfcreate)) {
             $display = 'block';              $display = 'block';
               $rowstyle = 'display:table-row';
         }          }
         my $onclick = "toggleDisplay(this.form,'emailoptions');";          my $onclick = "toggleRows(this.form,'cancreate_email','selfassign','$customclass','$classprefix','$optionsprefix');";
         my $additional = '<div id="emailoptions" style="display: '.$display.'">';          ($datatable,$$rowtotal) = &radiobutton_prefs(\%radiohash,\@toggles,\%defaultchecked,
                                                        \%choices,$$rowtotal,$onclick);
           $datatable .= &print_requestmail($dom,'selfcreation',$createsettings,$rowtotal,$customclass,
                                            $rowstyle);
           $$rowtotal ++;
           $datatable .= &captcha_choice('cancreate',$createsettings,$$rowtotal,$customclass,
                                         $rowstyle);
           $$rowtotal ++;
           my (@ordered,@posstypes,%usertypeshash);
         my %domdefaults = &Apache::lonnet::get_domain_defaults($dom);          my %domdefaults = &Apache::lonnet::get_domain_defaults($dom);
         my $usertypes = {};          my ($emailrules,$emailruleorder) =
         my $order = [];              &Apache::lonnet::inst_userrules($dom,'email');
         if ((ref($domdefaults{'inststatustypes'}) eq 'HASH') && (ref($domdefaults{'inststatusguest'}) eq 'ARRAY')) {          my $primary_id = &Apache::lonnet::domain($dom,'primary');
             $usertypes = $domdefaults{'inststatustypes'};          my $intdom = &Apache::lonnet::internet_dom($primary_id);
             $order = $domdefaults{'inststatusguest'};          if (ref($types) eq 'ARRAY') {
         }              @posstypes = @{$types};
         if (ref($order) eq 'ARRAY') {          }
             push(@{$order},'default');          if (@posstypes) {
             if (@{$order} > 1) {              unless (grep(/^default$/,@posstypes)) {
                 $usertypes->{'default'} = &mt('Other users');                  push(@posstypes,'default');
                 $additional .= '<table><tr>';              }
                 foreach my $status (@{$order}) {              if (ref($usertypes) eq 'HASH') {
                     $additional .= '<th>'.$usertypes->{$status}.'</th>';                  %usertypeshash = %{$usertypes};
                 }              }
                 $additional .= '</tr><tr>';              my $currassign;
                 foreach my $status (@{$order}) {              if (ref($domdefaults{'inststatusguest'}) eq 'ARRAY') {
                     $additional .= '<td>'.&email_as_username($rowtotal,$processing,$status).'</td>';                  $currassign = {
                                     selfassign => $domdefaults{'inststatusguest'},
                                 };
                   @ordered = @{$domdefaults{'inststatusguest'}};
               } else {
                   $currassign = { selfassign => [] };
               }
               my $onclicktypes = "toggleDataRow(this.form,'selfassign','$customclass','$optionsprefix',);".
                                  "toggleDataRow(this.form,'selfassign','$customclass','$classprefix',1);";
               $datatable .= &insttypes_row($currassign,$types,$usertypes,$dom,
                                            $numinrow,$othertitle,'selfassign',
                                            $rowtotal,$onclicktypes,$customclass,
                                            $rowstyle);
               $$rowtotal ++;
               $usertypeshash{'default'} = $othertitle;
               foreach my $status (@posstypes) {
                   my $css_class;
                   if ($$rowtotal%2) {
                       $css_class = 'LC_odd_row ';
                   }
                   $css_class .= $customclass;
                   my $rowid = $optionsprefix.$status;
                   my $hidden = 1;
                   my $currstyle = 'display:none';
                   if (grep(/^\Q$status\E$/,@ordered)) {
                       $currstyle = $rowstyle;
                       $hidden = 0; 
                   }
                   $datatable .= &noninst_users($processing,$emailverified,$emailoptions,$emaildomain,
                                                $emailrules,$emailruleorder,$settings,$status,$rowid,
                                                $usertypeshash{$status},$css_class,$currstyle,$intdom);
                   unless ($hidden) {
                       $$rowtotal ++;
                 }                  }
                 $additional .= '</tr></table>';  
             } else {  
                 $usertypes->{'default'} = &mt('All users');  
                 $additional .= &email_as_username($rowtotal,$processing);  
             }              }
           } else {
               my $css_class;
               if ($$rowtotal%2) {
                   $css_class = 'LC_odd_row ';
               }
               $css_class .= $customclass;
               $usertypeshash{'default'} = $othertitle;
               $datatable .= &noninst_users($processing,$emailverified,$emailoptions,$emaildomain,
                                            $emailrules,$emailruleorder,$settings,'default','',
                                            $othertitle,$css_class,$rowstyle,$intdom);
               $$rowtotal ++;
         }          }
         $additional .= '</div>'."\n";  
   
         ($datatable,$itemcount) = &radiobutton_prefs(\%radiohash,\@toggles,\%defaultchecked,  
                                                      \%choices,$$rowtotal,$onclick,$additional);  
         $$rowtotal ++;  
         $datatable .= &print_requestmail($dom,'selfcreation',$createsettings,$rowtotal);  
         $$rowtotal ++;  
         my ($infofields,$infotitles) = &Apache::loncommon::emailusername_info();          my ($infofields,$infotitles) = &Apache::loncommon::emailusername_info();
         $numinrow = 1;          $numinrow = 1;
         if (ref($order) eq 'ARRAY') {          if (@posstypes) {
             foreach my $status (@{$order}) {              foreach my $status (@posstypes) {
                   my $rowid = $classprefix.$status;
                   my $datarowstyle = 'display:none';
                   if (grep(/^\Q$status\E$/,@ordered)) { 
                       $datarowstyle = $rowstyle; 
                   }
                 $datatable .= &modifiable_userdata_row('cancreate','emailusername_'.$status,$settings,                  $datatable .= &modifiable_userdata_row('cancreate','emailusername_'.$status,$settings,
                                                        $numinrow,$$rowtotal,$usertypes,$infofields,$infotitles);                                                         $numinrow,$$rowtotal,\%usertypeshash,$infofields,
                 $$rowtotal ++;                                                         $infotitles,$rowid,$customclass,$datarowstyle);
                   unless ($datarowstyle eq 'display:none') {
                       $$rowtotal ++;
                   }
             }              }
           } else {
               $datatable .= &modifiable_userdata_row('cancreate','emailusername_default',$settings,
                                                      $numinrow,$$rowtotal,\%usertypeshash,$infofields,
                                                      $infotitles,'',$customclass,$rowstyle);
         }          }
         my ($emailrules,$emailruleorder) =      }
             &Apache::lonnet::inst_userrules($dom,'email');      return $datatable;
         if (ref($emailrules) eq 'HASH') {  }
             if (keys(%{$emailrules}) > 0) {  
                 $datatable .= &user_formats_row('email',$settings,$emailrules,  sub selfcreate_javascript {
                                                 $emailruleorder,$numinrow,$$rowtotal);      return <<"ENDSCRIPT";
                 $$rowtotal ++;  
   <script type="text/javascript">
   // <![CDATA[
   
   function toggleRows(form,radio,checkbox,target,prefix,altprefix) {
       var x = document.getElementsByClassName(target);
       var insttypes = 0;
       var insttypeRegExp = new RegExp(prefix);
       if ((x.length != undefined) && (x.length > 0)) {
           if (form.elements[radio].length != undefined) {
               for (var i=0; i<form.elements[radio].length; i++) {
                   if (form.elements[radio][i].checked) {
                       if (form.elements[radio][i].value == 1) {
                           for (var j=0; j<x.length; j++) {
                               if (x[j].id == 'undefined') {
                                   x[j].style.display = 'table-row';
                               } else if (insttypeRegExp.test(x[j].id)) {
                                   insttypes ++;
                               } else {
                                   x[j].style.display = 'table-row';
                               }
                           }
                       } else {
                           for (var j=0; j<x.length; j++) {
                               x[j].style.display = 'none';
                           }
                       }
                       break;
                   }
               }
               if (insttypes > 0) {
                   toggleDataRow(form,checkbox,target,altprefix);
                   toggleDataRow(form,checkbox,target,prefix,1);
             }              }
         }          }
         $datatable .= &captcha_choice('cancreate',$createsettings,$$rowtotal);  
     }      }
     return $datatable;      return;
 }  }
   
 sub email_as_username {  function toggleDataRow(form,checkbox,target,prefix,docount) {
     my ($rowtotal,$processing,$type) = @_;      if (form.elements[checkbox].length != undefined) {
     my %choices =          var count = 0;
         &Apache::lonlocal::texthash (          if (docount) {
                                       automatic => 'Automatic approval',              for (var i=0; i<form.elements[checkbox].length; i++) {
                                       approval  => 'Queued for approval',                  if (form.elements[checkbox][i].checked) {
                                     );                      count ++;
     my $output;                  }
     foreach my $option ('automatic','approval') {              }
         my $checked;          }
         if (ref($processing) eq 'HASH') {          for (var i=0; i<form.elements[checkbox].length; i++) {
             if ($type eq '') {                 var type = form.elements[checkbox][i].value;
                 if (!exists($processing->{'default'})) {              if (document.getElementById(prefix+type)) {
                     if ($option eq 'automatic') {                  if (form.elements[checkbox][i].checked) {
                         $checked = ' checked="checked"';                      document.getElementById(prefix+type).style.display = 'table-row';
                       if (count % 2 == 1) {
                           document.getElementById(prefix+type).className = target+' LC_odd_row';
                       } else {
                           document.getElementById(prefix+type).className = target;
                     }                      }
                       count ++;
                 } else {                  } else {
                     if ($processing->{'default'} eq $option) {                      document.getElementById(prefix+type).style.display = 'none';
                         $checked = ' checked="checked"';                  }
               }
           }
       }
       return;
   }
   
   function toggleEmailOptions(form,radio,prefix,altprefix,status) {
       var caller = radio+'_'+status;
       if (form.elements[caller].length != undefined) {
           for (var i=0; i<form.elements[caller].length; i++) {
               if (form.elements[caller][i].checked) {
                   if (document.getElementById(altprefix+'_inst_'+status)) {
                       var curr = form.elements[caller][i].value;
                       if (prefix) {
                           document.getElementById(prefix+'_'+status).style.display = 'none';
                       }
                       document.getElementById(altprefix+'_inst_'+status).style.display = 'none';
                       document.getElementById(altprefix+'_noninst_'+status).style.display = 'none';
                       if (curr == 'custom') {
                           if (prefix) { 
                               document.getElementById(prefix+'_'+status).style.display = 'inline';
                           }
                       } else if (curr == 'inst') {
                           document.getElementById(altprefix+'_inst_'+status).style.display = 'inline';
                       } else if (curr == 'noninst') {
                           document.getElementById(altprefix+'_noninst_'+status).style.display = 'inline';
                     }                      }
                       break;
                 }                  }
             } else {              }
                 if (!exists($processing->{$type})) {          }
                     if ($option eq 'automatic') {      }
                         $checked = ' checked="checked"';  }
   
   // ]]>
   </script>
   
   ENDSCRIPT
   }
   
   sub noninst_users {
       my ($processing,$emailverified,$emailoptions,$emaildomain,$emailrules,
           $emailruleorder,$settings,$type,$rowid,$typetitle,$css_class,$rowstyle,$intdom) = @_; 
       my $class = 'LC_left_item';
       if ($css_class) {
           $css_class = ' class="'.$css_class.'"'; 
       }
       if ($rowid) {
           $rowid = ' id="'.$rowid.'"';
       }
       if ($rowstyle) {
           $rowstyle = ' style="'.$rowstyle.'"';
       }
       my ($output,$description);
       if ($type eq 'default') {
           $description = &mt('Requests for: [_1]',$typetitle);
       } else {
           $description = &mt('Requests for: [_1] (status self-reported)',$typetitle);
       }
       $output = '<tr'.$css_class.$rowid.$rowstyle.'>'.
                 "<td>$description</td>\n".           
                 '<td class="'.$class.'" colspan="2">'.
                 '<table><tr>';
       my %headers = &Apache::lonlocal::texthash( 
                 approve  => 'Processing',
                 email    => 'E-mail',
                 username => 'Username',
       );
       foreach my $item ('approve','email','username') {
           $output .= '<th>'.$headers{$item}.'</th>';
       }
       $output .= '</tr><tr>';
       foreach my $item ('approve','email','username') {
           $output .= '<td style="vertical-align: top">';
           my (%choices,@options,$hashref,$defoption,$name,$onclick,$hascustom);
           if ($item eq 'approve') {
               %choices = &Apache::lonlocal::texthash (
                                                        automatic => 'Automatically approved',
                                                        approval  => 'Queued for approval',
                                                      );
               @options = ('automatic','approval');
               $hashref = $processing;
               $defoption = 'automatic';
               $name = 'cancreate_emailprocess_'.$type;
           } elsif ($item eq 'email') {
               %choices = &Apache::lonlocal::texthash (
                                                        any     => 'Any e-mail',
                                                        inst    => 'Institutional only',
                                                        noninst => 'Non-institutional only',
                                                        custom  => 'Custom restrictions',
                                                      );
               @options = ('any','inst','noninst');
               my $showcustom;
               if (ref($emailrules) eq 'HASH') {
                   if (keys(%{$emailrules}) > 0) {
                       push(@options,'custom');
                       $showcustom = 'cancreate_emailrule';
                       if (ref($settings) eq 'HASH') {
                           if (ref($settings->{'email_rule'}) eq 'ARRAY') {
                               foreach my $rule (@{$settings->{'email_rule'}}) {
                                   if (exists($emailrules->{$rule})) {
                                       $hascustom ++;
                                   }
                               }
                           } elsif (ref($settings->{'email_rule'}) eq 'HASH') {
                               if (ref($settings->{'email_rule'}{$type}) eq 'ARRAY') {
                                   foreach my $rule (@{$settings->{'email_rule'}{$type}}) {
                                       if (exists($emailrules->{$rule})) {
                                           $hascustom ++;
                                       }
                                   }
                               }
                           }
                       }
                   }
               }
               $onclick = ' onclick="toggleEmailOptions(this.form,'."'cancreate_emailoptions','$showcustom',".
                                                        "'cancreate_emaildomain','$type'".');"';
               $hashref = $emailoptions;
               $defoption = 'any';
               $name = 'cancreate_emailoptions_'.$type;
           } elsif ($item eq 'username') {
               %choices = &Apache::lonlocal::texthash (
                                                        all    => 'Same as e-mail',
                                                        first  => 'Omit @domain',
                                                        free   => 'Free to choose',
                                                      );
               @options = ('all','first','free');
               $hashref = $emailverified;
               $defoption = 'all';
               $name = 'cancreate_usernameoptions_'.$type;
           }
           foreach my $option (@options) {
               my $checked;
               if (ref($hashref) eq 'HASH') {
                   if ($type eq '') {
                       if (!exists($hashref->{'default'})) {
                           if ($option eq $defoption) {
                               $checked = ' checked="checked"';
                           }
                       } else {
                           if ($hashref->{'default'} eq $option) {
                               $checked = ' checked="checked"';
                           }
                     }                      }
                 } else {                  } else {
                     if ($processing->{$type} eq $option) {                      if (!exists($hashref->{$type})) {
                         $checked = ' checked="checked"';                          if ($option eq $defoption) {
                               $checked = ' checked="checked"';
                           }
                       } else {
                           if ($hashref->{$type} eq $option) {
                               $checked = ' checked="checked"';
                           }
                     }                      }
                 }                  }
               } elsif (($item eq 'email') && ($hascustom)) {
                   if ($option eq 'custom') {
                       $checked = ' checked="checked"';
                   }
               } elsif ($option eq $defoption) {
                   $checked = ' checked="checked"';
               }
               $output .= '<span class="LC_nobreak"><label>'.
                          '<input type="radio" name="'.$name.'"'.
                          $checked.' value="'.$option.'"'.$onclick.' />'.
                          $choices{$option}.'</label></span><br />';
               if ($item eq 'email') {
                   if ($option eq 'custom') {
                       my $id = 'cancreate_emailrule_'.$type;
                       my $display = 'none';
                       if ($checked) {
                           $display = 'inline';
                       }
                       my $numinrow = 2;
                       $output .= '<fieldset id="'.$id.'" style="display:'.$display.';">'.
                                  '<legend>'.&mt('Disallow').'</legend><table>'.
                                  &user_formats_row('email',$settings,$emailrules,
                                                    $emailruleorder,$numinrow,'',$type);
                                 '</table></fieldset>';
                   } elsif (($option eq 'inst') || ($option eq 'noninst')) {
                       my %text = &Apache::lonlocal::texthash (
                                                                inst    => 'must end:',
                                                                noninst => 'cannot end:',
                                                              );
                       my $value;
                       if (ref($emaildomain) eq 'HASH') {
                           if (ref($emaildomain->{$type}) eq 'HASH') {
                               $value = $emaildomain->{$type}->{$option}; 
                           }
                       }
                       if ($value eq '') {
                           $value = '@'.$intdom;
                       }
                       my $condition = 'cancreate_emaildomain_'.$option.'_'.$type;
                       my $display = 'none';
                       if ($checked) {
                           $display = 'inline';
                       }
                       $output .= '<div id="'.$condition.'" style="display:'.$display.';">'.
                                  '<span class="LC_domprefs_email">'.$text{$option}.'</span> '.
                                  '<input type="text" name="'.$condition.'" value="'.$value.'" size="10" />'.
                                  '</div>';
                   }
             }              }
         } elsif ($option eq 'automatic') {  
             $checked = ' checked="checked"';   
         }  
         my $name = 'cancreate_emailprocess';  
         if (($type ne '') && ($type ne 'default')) {  
             $name .= '_'.$type;  
         }  
         $output .= '<span class="LC_nobreak"><label>'.  
                    '<input type="radio" name="'.$name.'"'.  
                    $checked.' value="'.$option.'" />'.  
                    $choices{$option}.'</label></span>';  
         if ($type eq '') {  
             $output .= '&nbsp;';  
         } else {  
             $output .= '<br />';  
         }          }
           $output .= '</td>'."\n";
     }      }
     $$rowtotal ++;      $output .= "</tr></table></td></tr>\n";
     return $output;      return $output;
 }  }
   
 sub captcha_choice {  sub captcha_choice {
     my ($context,$settings,$itemcount) = @_;      my ($context,$settings,$itemcount,$customcss,$rowstyle) = @_;
     my ($keyentry,$currpub,$currpriv,%checked,$rowname,$pubtext,$privtext,      my ($keyentry,$currpub,$currpriv,%checked,$rowname,$pubtext,$privtext,
         $vertext,$currver);          $vertext,$currver);
     my %lt = &captcha_phrases();      my %lt = &captcha_phrases();
Line 5907  sub captcha_choice { Line 7549  sub captcha_choice {
     } else {      } else {
         $checked{'original'} = ' checked="checked"';          $checked{'original'} = ' checked="checked"';
     }      }
     my $css_class = $itemcount%2?' class="LC_odd_row"':'';      my $css_class;
       if ($itemcount%2) {
           $css_class = 'LC_odd_row';
       }
       if ($customcss) {
           $css_class .= " $customcss";
       }
       $css_class =~ s/^\s+//;
       if ($css_class) {
           $css_class = ' class="'.$css_class.'"';
       }
       if ($rowstyle) {
           $css_class .= ' style="'.$rowstyle.'"';
       }
     my $output = '<tr'.$css_class.'>'.      my $output = '<tr'.$css_class.'>'.
                  '<td class="LC_left_item">'.$rowname.'</td><td class="LC_left_item" colspan="2">'."\n".                   '<td class="LC_left_item">'.$rowname.'</td><td class="LC_left_item" colspan="2">'."\n".
                  '<table><tr><td>'."\n";                   '<table><tr><td>'."\n";
Line 5926  sub captcha_choice { Line 7581  sub captcha_choice {
 # specified for use with the key should be broad enough to accommodate all servers in the LON-CAPA domain.  # specified for use with the key should be broad enough to accommodate all servers in the LON-CAPA domain.
 #  #
     $output .= '</td></tr>'."\n".      $output .= '</td></tr>'."\n".
                '<tr><td>'."\n".                 '<tr><td class="LC_zero_height">'."\n".
                '<span class="LC_nobreak"><span id="'.$context.'_recaptchapubtxt">'.$pubtext.'</span>&nbsp;'."\n".                 '<span class="LC_nobreak"><span id="'.$context.'_recaptchapubtxt">'.$pubtext.'</span>&nbsp;'."\n".
                '<input type="'.$keyentry.'" id="'.$context.'_recaptchapub" name="'.$context.'_recaptchapub" value="'.                 '<input type="'.$keyentry.'" id="'.$context.'_recaptchapub" name="'.$context.'_recaptchapub" value="'.
                $currpub.'" size="40" /></span><br />'."\n".                 $currpub.'" size="40" /></span><br />'."\n".
Line 5942  sub captcha_choice { Line 7597  sub captcha_choice {
 }  }
   
 sub user_formats_row {  sub user_formats_row {
     my ($type,$settings,$rules,$ruleorder,$numinrow,$rowcount) = @_;      my ($type,$settings,$rules,$ruleorder,$numinrow,$rowcount,$status) = @_;
     my $output;      my $output;
     my %text = (      my %text = (
                    'username' => 'new usernames',                     'username' => 'new usernames',
                    'id'       => 'IDs',                     'id'       => 'IDs',
                    'email'    => 'self-created accounts (e-mail)',  
                );                 );
     my $css_class = $rowcount%2?' class="LC_odd_row"':'';      unless ($type eq 'email') {
     $output = '<tr '.$css_class.'>'.          my $css_class = $rowcount%2?' class="LC_odd_row"':'';
               '<td><span class="LC_nobreak">';          $output = '<tr '.$css_class.'>'.
     if ($type eq 'email') {                    '<td><span class="LC_nobreak">'.
         $output .= &mt("Formats disallowed for $text{$type}: ");                    &mt("Format rules to check for $text{$type}: ").
     } else {                    '</td><td class="LC_left_item" colspan="2"><table>';
         $output .= &mt("Format rules to check for $text{$type}: ");  
     }      }
     $output .= '</span></td>'.  
                '<td class="LC_left_item" colspan="2"><table>';  
     my $rem;      my $rem;
     if (ref($ruleorder) eq 'ARRAY') {      if (ref($ruleorder) eq 'ARRAY') {
         for (my $i=0; $i<@{$ruleorder}; $i++) {          for (my $i=0; $i<@{$ruleorder}; $i++) {
Line 5976  sub user_formats_row { Line 7627  sub user_formats_row {
                         if (grep(/^\Q$ruleorder->[$i]\E$/,@{$settings->{$type.'_rule'}})) {                          if (grep(/^\Q$ruleorder->[$i]\E$/,@{$settings->{$type.'_rule'}})) {
                             $check = ' checked="checked" ';                              $check = ' checked="checked" ';
                         }                          }
                       } elsif ((ref($settings->{$type.'_rule'}) eq 'HASH') && ($status ne '')) {
                           if (ref($settings->{$type.'_rule'}->{$status}) eq 'ARRAY') {
                               if (grep(/^\Q$ruleorder->[$i]\E$/,@{$settings->{$type.'_rule'}->{$status}})) {
                                   $check = ' checked="checked" ';
                               }
                           }
                     }                      }
                 }                  }
                   my $name = $type.'_rule';
                   if ($type eq 'email') {
                       $name .= '_'.$status;
                   }
                 $output .= '<td class="LC_left_item">'.                  $output .= '<td class="LC_left_item">'.
                            '<span class="LC_nobreak"><label>'.                             '<span class="LC_nobreak"><label>'.
                            '<input type="checkbox" name="'.$type.'_rule" '.                             '<input type="checkbox" name="'.$name.'" '.
                            'value="'.$ruleorder->[$i].'"'.$check.'/>'.                             'value="'.$ruleorder->[$i].'"'.$check.'/>'.
                            $rules->{$ruleorder->[$i]}{'name'}.'</label></span></td>';                             $rules->{$ruleorder->[$i]}{'name'}.'</label></span></td>';
             }              }
         }          }
         $rem = @{$ruleorder}%($numinrow);          $rem = @{$ruleorder}%($numinrow);
     }      }
     my $colsleft = $numinrow - $rem;      my $colsleft;
       if ($rem) {
           $colsleft = $numinrow - $rem;
       }
     if ($colsleft > 1 ) {      if ($colsleft > 1 ) {
         $output .= '<td colspan="'.$colsleft.'" class="LC_left_item">'.          $output .= '<td colspan="'.$colsleft.'" class="LC_left_item">'.
                    '&nbsp;</td>';                     '&nbsp;</td>';
     } elsif ($colsleft == 1) {      } elsif ($colsleft == 1) {
         $output .= '<td class="LC_left_item">&nbsp;</td>';          $output .= '<td class="LC_left_item">&nbsp;</td>';
     }      }
     $output .= '</tr></table></td></tr>';      $output .= '</tr></table>';
       unless ($type eq 'email') {
           $output .= '</td></tr>';
       }
     return $output;      return $output;
 }  }
   
Line 6029  sub authtype_names { Line 7696  sub authtype_names {
                       krb4   => 'Kerberos 4',                        krb4   => 'Kerberos 4',
                       krb5   => 'Kerberos 5',                        krb5   => 'Kerberos 5',
                       loc    => 'Local',                        loc    => 'Local',
                         lti    => 'LTI',
                   );                    );
     return %lt;      return %lt;
 }  }
Line 6071  sub print_usermodification { Line 7739  sub print_usermodification {
 sub print_defaults {  sub print_defaults {
     my ($position,$dom,$settings,$rowtotal) = @_;      my ($position,$dom,$settings,$rowtotal) = @_;
     my $rownum = 0;      my $rownum = 0;
     my ($datatable,$css_class);      my ($datatable,$css_class,$titles);
       unless ($position eq 'bottom') {
           $titles = &defaults_titles($dom);
       }
     if ($position eq 'top') {      if ($position eq 'top') {
         my @items = ('auth_def','auth_arg_def','lang_def','timezone_def',          my @items = ('auth_def','auth_arg_def','lang_def','timezone_def',
                      'datelocale_def','portal_def');                       'datelocale_def','portal_def');
Line 6084  sub print_defaults { Line 7755  sub print_defaults {
                 $defaults{$item} = $domdefaults{$item};                  $defaults{$item} = $domdefaults{$item};
             }              }
         }          }
         my $titles = &defaults_titles($dom);  
         foreach my $item (@items) {          foreach my $item (@items) {
             if ($rownum%2) {              if ($rownum%2) {
                 $css_class = '';                  $css_class = '';
Line 6095  sub print_defaults { Line 7765  sub print_defaults {
                           '<td><span class="LC_nobreak">'.$titles->{$item}.                            '<td><span class="LC_nobreak">'.$titles->{$item}.
                           '</span></td><td class="LC_right_item" colspan="3">';                            '</span></td><td class="LC_right_item" colspan="3">';
             if ($item eq 'auth_def') {              if ($item eq 'auth_def') {
                 my @authtypes = ('internal','krb4','krb5','localauth');                  my @authtypes = ('internal','krb4','krb5','localauth','lti');
                 my %shortauth = (                  my %shortauth = (
                                  internal => 'int',                                   internal => 'int',
                                  krb4 => 'krb4',                                   krb4 => 'krb4',
                                  krb5 => 'krb5',                                   krb5 => 'krb5',
                                  localauth  => 'loc'                                   localauth  => 'loc',
                                    lti => 'lti',
                                 );                                  );
                 my %authnames = &authtype_names();                  my %authnames = &authtype_names();
                 foreach my $auth (@authtypes) {                  foreach my $auth (@authtypes) {
Line 6132  sub print_defaults { Line 7803  sub print_defaults {
             $datatable .= '</td></tr>';              $datatable .= '</td></tr>';
             $rownum ++;              $rownum ++;
         }          }
       } elsif ($position eq 'middle') {
           my @items = ('intauth_cost','intauth_check','intauth_switch');
           my %defaults;
           if (ref($settings) eq 'HASH') {
               %defaults = %{$settings};
               if ($defaults{'intauth_cost'} !~ /^\d+$/) {
                   $defaults{'intauth_cost'} = 10;
               }
               if ($defaults{'intauth_check'} !~ /^(0|1|2)$/) {
                   $defaults{'intauth_check'} = 0;
               }
               if ($defaults{'intauth_switch'} !~ /^(0|1|2)$/) {
                   $defaults{'intauth_switch'} = 0;
               }
           } else {
               %defaults = (
                             'intauth_cost'   => 10,
                             'intauth_check'  => 0,
                             'intauth_switch' => 0,
                           );
           }
           foreach my $item (@items) {
               if ($rownum%2) {
                   $css_class = '';
               } else {
                   $css_class = ' class="LC_odd_row" ';
               }
               $datatable .= '<tr'.$css_class.'>'.
                             '<td><span class="LC_nobreak">'.$titles->{$item}.
                             '</span></td><td class="LC_left_item" colspan="3">';
               if ($item eq 'intauth_switch') {
                   my @options = (0,1,2);
                   my %optiondesc = &Apache::lonlocal::texthash (
                                      0 => 'No',
                                      1 => 'Yes',
                                      2 => 'Yes, and copy existing passwd file to passwd.bak file',
                                    );
                   $datatable .= '<table width="100%">';
                   foreach my $option (@options) {
                       my $checked = ' ';
                       if ($defaults{$item} eq $option) {
                           $checked = ' checked="checked"';
                       }
                       $datatable .= '<tr><td class="LC_left_item"><span class="LC_nobreak">'.
                                     '<label><input type="radio" name="'.$item.
                                     '" value="'.$option.'"'.$checked.' />'.
                                     $optiondesc{$option}.'</label></span></td></tr>';
                   }
                   $datatable .= '</table>';
               } elsif ($item eq 'intauth_check') {
                   my @options = (0,1,2);
                   my %optiondesc = &Apache::lonlocal::texthash (
                                      0 => 'No',
                                      1 => 'Yes, allow login then update passwd file using default cost (if higher)',
                                      2 => 'Yes, disallow login if stored cost is less than domain default',
                                    );
                   $datatable .= '<table width="100%">';
                   foreach my $option (@options) {
                       my $checked = ' ';
                       my $onclick;
                       if ($defaults{$item} eq $option) {
                           $checked = ' checked="checked"';
                       }
                       if ($option == 2) {
                           $onclick = ' onclick="javascript:warnIntAuth(this);"';
                       }
                       $datatable .= '<tr><td class="LC_left_item"><span class="LC_nobreak">'.
                                     '<label><input type="radio" name="'.$item.
                                     '" value="'.$option.'"'.$checked.$onclick.' />'.
                                     $optiondesc{$option}.'</label></span></td></tr>';
                   }
                   $datatable .= '</table>';
               } else {
                   $datatable .= '<input type="text" name="'.$item.'" value="'.
                                 $defaults{$item}.'" size="3" onblur="javascript:warnIntAuth(this);" />'; 
               }
               $datatable .= '</td></tr>';
               $rownum ++;
           }
     } else {      } else {
         my (%defaults);          my %defaults;
         if (ref($settings) eq 'HASH') {          if (ref($settings) eq 'HASH') {
             if ((ref($settings->{'inststatusorder'}) eq 'ARRAY') && (ref($settings->{'inststatustypes'}) eq 'HASH') &&              if ((ref($settings->{'inststatusorder'}) eq 'ARRAY') && (ref($settings->{'inststatustypes'}) eq 'HASH')) {
                 (ref($settings->{'inststatusguest'}) eq 'ARRAY')) {  
                 my $maxnum = @{$settings->{'inststatusorder'}};                  my $maxnum = @{$settings->{'inststatusorder'}};
                 for (my $i=0; $i<$maxnum; $i++) {                  for (my $i=0; $i<$maxnum; $i++) {
                     $css_class = $rownum%2?' class="LC_odd_row"':'';                      $css_class = $rownum%2?' class="LC_odd_row"':'';
                     my $item = $settings->{'inststatusorder'}->[$i];                      my $item = $settings->{'inststatusorder'}->[$i];
                     my $title = $settings->{'inststatustypes'}->{$item};                      my $title = $settings->{'inststatustypes'}->{$item};
                     my $guestok;  
                     if (grep(/^\Q$item\E$/,@{$settings->{'inststatusguest'}})) {  
                         $guestok = 1;  
                     }  
                     my $chgstr = ' onchange="javascript:reorderTypes(this.form,'."'$item'".');"';                      my $chgstr = ' onchange="javascript:reorderTypes(this.form,'."'$item'".');"';
                     $datatable .= '<tr'.$css_class.'>'.                      $datatable .= '<tr'.$css_class.'>'.
                                   '<td><span class="LC_nobreak">'.                                    '<td><span class="LC_nobreak">'.
Line 6158  sub print_defaults { Line 7903  sub print_defaults {
                         }                          }
                         $datatable .= '<option value="'.$k.'"'.$selstr.'>'.$vpos.'</option>';                          $datatable .= '<option value="'.$k.'"'.$selstr.'>'.$vpos.'</option>';
                     }                      }
                     my ($checkedon,$checkedoff);  
                     $checkedoff = ' checked="checked"';  
                     if ($guestok) {  
                         $checkedon = $checkedoff;  
                         $checkedoff = '';   
                     }  
                     $datatable .= '</select>&nbsp;'.&mt('Internal ID:').'&nbsp;<b>'.$item.'</b>&nbsp;'.                      $datatable .= '</select>&nbsp;'.&mt('Internal ID:').'&nbsp;<b>'.$item.'</b>&nbsp;'.
                                   '<input type="checkbox" name="inststatus_delete" value="'.$item.'" />'.                                    '<input type="checkbox" name="inststatus_delete" value="'.$item.'" />'.
                                   &mt('delete').'</span></td>'.                                    &mt('delete').'</span></td>'.
                                   '<td class="LC_left_item"><span class="LC_nobreak">'.&mt('Name displayed:').                                    '<td class="LC_left_item" colspan="2"><span class="LC_nobreak">'.&mt('Name displayed:').
                                   '<input type="text" size="20" name="inststatus_title_'.$item.'" value="'.$title.'" />'.                                    '<input type="text" size="20" name="inststatus_title_'.$item.'" value="'.$title.'" />'.
                                   '</span></td>'.                                    '</span></td></tr>';
                                   '<td class="LC_right_item"><span class="LC_nobreak">'.  
                                   '<label><input type="radio" value="1" name="inststatus_guest_'.$item.'"'.$checkedon.' />'.  
                                   &mt('Yes').'</label>'.('&nbsp;'x2).  
                                   '<label><input type="radio" value="0" name="inststatus_guest_'.$item.'"'.$checkedoff.' />'.  
                                   &mt('No').'</label></span></td></tr>';  
                 }                  }
                 $css_class = $rownum%2?' class="LC_odd_row"':'';                  $css_class = $rownum%2?' class="LC_odd_row"':'';
                 my $chgstr = ' onchange="javascript:reorderTypes(this.form,'."'addinststatus_pos'".');"';                  my $chgstr = ' onchange="javascript:reorderTypes(this.form,'."'addinststatus_pos'".');"';
Line 6191  sub print_defaults { Line 7925  sub print_defaults {
                 $datatable .= '</select>&nbsp;'.&mt('Internal ID:').                  $datatable .= '</select>&nbsp;'.&mt('Internal ID:').
                               '<input type="text" size="10" name="addinststatus" value="" />'.                                '<input type="text" size="10" name="addinststatus" value="" />'.
                               '&nbsp;'.&mt('(new)').                                '&nbsp;'.&mt('(new)').
                               '</span></td><td class="LC_left_item"><span class="LC_nobreak">'.                                '</span></td><td class="LC_left_item" colspan="2"><span class="LC_nobreak">'.
                               &mt('Name displayed:').                                &mt('Name displayed:').
                               '<input type="text" size="20" name="addinststatus_title" value="" /></span></td>'.                                '<input type="text" size="20" name="addinststatus_title" value="" /></span></td>'.
                               '<td class="LC_right_item"><span class="LC_nobreak">'.  
                               '<label><input type="radio" value="1" name="addinststatus_guest" />'.  
                               &mt('Yes').'</label>'.('&nbsp;'x2).  
                               '<label><input type="radio" value="0" name="addinststatus_guest" />'.  
                               &mt('No').'</label></span></td></tr>';  
                               '</tr>'."\n";                                '</tr>'."\n";
                 $rownum ++;                  $rownum ++;
             }              }
Line 6228  sub defaults_titles { Line 7957  sub defaults_titles {
                    'timezone_def'  => 'Default timezone',                     'timezone_def'  => 'Default timezone',
                    'datelocale_def' => 'Default locale for dates',                     'datelocale_def' => 'Default locale for dates',
                    'portal_def'     => 'Portal/Default URL',                     'portal_def'     => 'Portal/Default URL',
                      'intauth_cost'   => 'Encryption cost for bcrypt (positive integer)',
                      'intauth_check'  => 'Check bcrypt cost if authenticated',
                      'intauth_switch' => 'Existing crypt-based switched to bcrypt on authentication',
                  );                   );
     if ($dom) {      if ($dom) {
         my $uprimary_id = &Apache::lonnet::domain($dom,'primary');          my $uprimary_id = &Apache::lonnet::domain($dom,'primary');
Line 6358  sub print_scantronformat { Line 8090  sub print_scantronformat {
         }          }
         $datatable .= '</span></td>';          $datatable .= '</span></td>';
         if (keys(%error) == 0) {           if (keys(%error) == 0) { 
             $datatable .= '<td valign="bottom">';              $datatable .= '<td style="vertical-align: bottom">';
             if (!$switchserver) {              if (!$switchserver) {
                 $datatable .= &mt('Upload:').'<br />';                  $datatable .= &mt('Upload:').'<br />';
             }              }
Line 6457  sub print_coursecategories { Line 8189  sub print_coursecategories {
                              '<input type="radio" name="coursecat_'.$item.'" value="'.$type.'"'.$ischecked.                               '<input type="radio" name="coursecat_'.$item.'" value="'.$type.'"'.$ischecked.
                              ' />'.$lt{$type}.'</label>&nbsp;';                               ' />'.$lt{$type}.'</label>&nbsp;';
            }             }
            $datatable .= '</td></tr>';             $datatable .= '</span></td></tr>';
            $itemcount ++;             $itemcount ++;
         }          }
         $$rowtotal += $itemcount;          $$rowtotal += $itemcount;
Line 6543  sub print_coursecategories { Line 8275  sub print_coursecategories {
                   $can_catcomm_dom.' value="dom" />'.$level{'dom'}.'</label>&nbsp;'.                    $can_catcomm_dom.' value="dom" />'.$level{'dom'}.'</label>&nbsp;'.
                   '<label><input type="radio" name="categorizecomm"'.                    '<label><input type="radio" name="categorizecomm"'.
                   $can_catcomm_comm.'value="comm" />'.$level{'comm'}.'</label></span></td>'.                    $can_catcomm_comm.'value="comm" />'.$level{'comm'}.'</label></span></td>'.
                   '</tr><tr>'.                    '</tr><tr class="LC_odd_row">'.
                   '<td>'.$title{'togglecatsplace'}.'</td>'.                    '<td>'.$title{'togglecatsplace'}.'</td>'.
                   '<td class="LC_right_item"><span class="LC_nobreak"><label>'.                    '<td class="LC_right_item"><span class="LC_nobreak"><label>'.
                   '<input type="radio" name="togglecatsplace"'.                    '<input type="radio" name="togglecatsplace"'.
Line 6700  sub print_coursecategories { Line 8432  sub print_coursecategories {
                 $datatable .= &initialize_categories($itemcount);                  $datatable .= &initialize_categories($itemcount);
             }              }
         } else {          } else {
             $datatable .= '<td class="LC_right_item">'.$hdritem->{'header'}->[1]->{'col2'}.'</td>'              $datatable .= '<tr><td class="LC_right_item">'.$hdritem->{'header'}->[1]->{'col2'}.'</td></tr>'
                           .&initialize_categories($itemcount);                            .&initialize_categories($itemcount);
         }          }
         $$rowtotal += $itemcount;          $$rowtotal += $itemcount;
Line 6748  sub print_serverstatuses { Line 8480  sub print_serverstatuses {
                       '<span class="LC_nobreak">'.                        '<span class="LC_nobreak">'.
                       '<input type="text" name="'.$type.'_machines" '.                        '<input type="text" name="'.$type.'_machines" '.
                       'value="'.$machineaccess{$type}.'" size="10" />'.                        'value="'.$machineaccess{$type}.'" size="10" />'.
                       '</td></tr>'."\n";                        '</span></td></tr>'."\n";
     }      }
     $$rowtotal += $rownum;      $$rowtotal += $rownum;
     return $datatable;      return $datatable;
Line 6763  sub serverstatus_pages { Line 8495  sub serverstatus_pages {
   
 sub defaults_javascript {  sub defaults_javascript {
     my ($settings) = @_;      my ($settings) = @_;
     return unless (ref($settings) eq 'HASH');       my $intauthcheck = &mt('Warning: disallowing login for an authenticated user if the stored cost is less than the default will require a password reset by/for the user.');
       my $intauthcost = &mt('Warning: bcrypt encryption cost for internal authentication must be an integer.');
       &js_escape(\$intauthcheck);
       &js_escape(\$intauthcost);
       my $intauthjs = <<"ENDSCRIPT";
   
   function warnIntAuth(field) {
       if (field.name == 'intauth_check') {
           if (field.value == '2') {
               alert('$intauthcheck');
           }
       }
       if (field.name == 'intauth_cost') {
           field.value.replace(/\s/g,'');
           if (field.value != '') {
               var regexdigit=/^\\d+\$/;
               if (!regexdigit.test(field.value)) {
                   alert('$intauthcost');
               }
           }
       }
       return;
   }
   
   ENDSCRIPT
   
       if (ref($settings) ne 'HASH') {
           return &Apache::lonhtmlcommon::scripttag($intauthjs);
       }
     if ((ref($settings->{'inststatusorder'}) eq 'ARRAY') && (ref($settings->{'inststatustypes'}) eq 'HASH')) {      if ((ref($settings->{'inststatusorder'}) eq 'ARRAY') && (ref($settings->{'inststatustypes'}) eq 'HASH')) {
         my $maxnum = scalar(@{$settings->{'inststatusorder'}});          my $maxnum = scalar(@{$settings->{'inststatusorder'}});
         if ($maxnum eq '') {          if ($maxnum eq '') {
Line 6817  $jstext Line 8577  $jstext
     return;      return;
 }  }
   
   $intauthjs
   
 // ]]>  // ]]>
 </script>  </script>
   
 ENDSCRIPT  ENDSCRIPT
       } else {
           return &Apache::lonhtmlcommon::scripttag($intauthjs);
     }      }
 }  }
   
Line 6944  sub initialize_categories { Line 8708  sub initialize_categories {
                       communities => 'Communities',                        communities => 'Communities',
                       placement   => 'Placement Tests',                        placement   => 'Placement Tests',
                         );                          );
     my $select0 = ' selected="selected"';      my %selnum = (
     my $select1 = '';                     instcode    => '0',
                      communities => '1',
                      placement   => '2',
                    );
       my %selected;
     foreach my $default ('instcode','communities','placement') {      foreach my $default ('instcode','communities','placement') {
         $css_class = $itemcount%2?' class="LC_odd_row"':'';          $css_class = $itemcount%2?' class="LC_odd_row"':'';
         $chgstr = ' onchange="javascript:reorderCats(this.form,'."'',$default"."_pos','0'".');"';          $chgstr = ' onchange="javascript:reorderCats(this.form,'."'','$default"."_pos','0'".');"';
         if (($default eq 'communities') || ($default eq 'placement')) {          map { $selected{$selnum{$_}} = '' } keys(%selnum);
             $select1 = $select0;          $selected{$selnum{$default}} = ' selected="selected"';
             $select0 = '';  
         }  
         $datatable .= '<tr '.$css_class.'><td><span class="LC_nobreak">'          $datatable .= '<tr '.$css_class.'><td><span class="LC_nobreak">'
                      .'<select name="'.$default.'_pos">'                       .'<select name="'.$default.'_pos"'.$chgstr.'>'
                      .'<option value="0"'.$select0.'>1</option>'                       .'<option value="0"'.$selected{'0'}.'>1</option>'
                      .'<option value="1"'.$select1.'>2</option>'                       .'<option value="1"'.$selected{'1'}.'>2</option>'
                      .'<option value="2">3</option></select>&nbsp;'                       .'<option value="2"'.$selected{'2'}.'>3</option>'
                        .'<option value="3">4</option></select>&nbsp;'
                      .$default_names{$default}                       .$default_names{$default}
                      .'</span></td><td><span class="LC_nobreak">'                       .'</span></td><td><span class="LC_nobreak">'
                      .'<label><input type="radio" name="'.$default.'" value="1" checked="checked" />'                       .'<label><input type="radio" name="'.$default.'" value="1" checked="checked" />'
Line 6972  sub initialize_categories { Line 8739  sub initialize_categories {
                   .'<select name="addcategory_pos"'.$chgstr.'>'                    .'<select name="addcategory_pos"'.$chgstr.'>'
                   .'<option value="0">1</option>'                    .'<option value="0">1</option>'
                   .'<option value="1">2</option>'                    .'<option value="1">2</option>'
                   .'<option value="2" selected="selected">3</option></select>&nbsp;'                    .'<option value="2">3</option>'
                   .&mt('Add category').'</td><td>'.&mt('Name:')                    .'<option value="3" selected="selected">4</option></select>&nbsp;'
                   .'&nbsp;<input type="text" size="20" name="addcategory_name" value="" /></td></tr>';                    .&mt('Add category').'</span></td><td><span class="LC_nobreak">'.&mt('Name:')
                     .'&nbsp;<input type="text" size="20" name="addcategory_name" value="" /></span>'
                     .'</td></tr>';
     return $datatable;      return $datatable;
 }  }
   
Line 7029  sub build_category_rows { Line 8798  sub build_category_rows {
                             pop(@{$path});                              pop(@{$path});
                         }                          }
                     } else {                      } else {
                         $text .= &mt('Add subcategory:').'&nbsp;</span><input type="textbox" size="20" name="addcategory_name_';                          $text .= &mt('Add subcategory:').'&nbsp;</span><input type="text" size="20" name="addcategory_name_';
                         if ($j == $numchildren) {                          if ($j == $numchildren) {
                             $text .= $name;                              $text .= $name;
                         } else {                          } else {
Line 7052  sub build_category_rows { Line 8821  sub build_category_rows {
                 my $colspan;                  my $colspan;
                 if ($parent ne 'instcode') {                  if ($parent ne 'instcode') {
                     $colspan = $maxdepth - $depth - 1;                      $colspan = $maxdepth - $depth - 1;
                     $text .= '<td colspan="'.$colspan.'">'.&mt('Add subcategory:').'<input type="textbox" size="20" name="subcat_'.$name.'" value="" /></td>';                      $text .= '<td colspan="'.$colspan.'">'.&mt('Add subcategory:').'<input type="text" size="20" name="subcat_'.$name.'" value="" /></td>';
                 }                  }
             }              }
         }          }
Line 7061  sub build_category_rows { Line 8830  sub build_category_rows {
 }  }
   
 sub modifiable_userdata_row {  sub modifiable_userdata_row {
     my ($context,$item,$settings,$numinrow,$rowcount,$usertypes,$fieldsref,$titlesref) = @_;      my ($context,$item,$settings,$numinrow,$rowcount,$usertypes,$fieldsref,$titlesref,
           $rowid,$customcss,$rowstyle) = @_;
     my ($role,$rolename,$statustype);      my ($role,$rolename,$statustype);
     $role = $item;      $role = $item;
     if ($context eq 'cancreate') {      if ($context eq 'cancreate') {
         if ($item =~ /^emailusername_(.+)$/) {          if ($item =~ /^(emailusername)_(.+)$/) {
             $statustype = $1;              $role = $1;
             $role = 'emailusername';              $statustype = $2;
             if (ref($usertypes) eq 'HASH') {              if (ref($usertypes) eq 'HASH') {
                 if ($usertypes->{$statustype}) {                  if ($usertypes->{$statustype}) {
                     $rolename = &mt('Data provided by [_1]',$usertypes->{$statustype});                      $rolename = &mt('Data provided by [_1]',$usertypes->{$statustype});
Line 7082  sub modifiable_userdata_row { Line 8852  sub modifiable_userdata_row {
         } else {          } else {
             $rolename = $role;              $rolename = $role;
         }          }
       } elsif ($context eq 'lti') {
           $rolename = &mt('Institutional data used (if available)');
     } else {      } else {
         if ($role eq 'cr') {          if ($role eq 'cr') {
             $rolename = &mt('Custom role');              $rolename = &mt('Custom role');
Line 7102  sub modifiable_userdata_row { Line 8874  sub modifiable_userdata_row {
         %fieldtitles = &Apache::loncommon::personal_data_fieldtitles();          %fieldtitles = &Apache::loncommon::personal_data_fieldtitles();
     }      }
     my $output;      my $output;
     my $css_class = $rowcount%2?' class="LC_odd_row"':'';      my $css_class;
     $output = '<tr '.$css_class.'>'.      if ($rowcount%2) {
           $css_class = 'LC_odd_row';
       }
       if ($customcss) {
           $css_class .= " $customcss";
       }
       $css_class =~ s/^\s+//;
       if ($css_class) {
           $css_class = ' class="'.$css_class.'"';
       }
       if ($rowstyle) {
           $css_class .= ' style="'.$rowstyle.'"';
       }
       if ($rowid) {
           $rowid = ' id="'.$rowid.'"';
       }
       $output = '<tr '.$css_class.$rowid.'>'.
               '<td><span class="LC_nobreak">'.$rolename.'</span></td>'.                '<td><span class="LC_nobreak">'.$rolename.'</span></td>'.
               '<td class="LC_left_item" colspan="2"><table>';                '<td class="LC_left_item" colspan="2"><table>';
     my $rem;      my $rem;
     my %checks;      my %checks;
       my %current;
     if (ref($settings) eq 'HASH') {      if (ref($settings) eq 'HASH') {
         if (ref($settings->{$context}) eq 'HASH') {          my $hashref;
           if ($context eq 'lti') {
               if (ref($settings) eq 'HASH') {
                   $hashref = $settings->{'instdata'};
               }
           } elsif (ref($settings->{$context}) eq 'HASH') {
             if (ref($settings->{$context}->{$role}) eq 'HASH') {              if (ref($settings->{$context}->{$role}) eq 'HASH') {
                 my $hashref = $settings->{$context}->{$role};                  $hashref = $settings->{'lti_instdata'};
                 if ($role eq 'emailusername') {              }
                     if ($statustype) {              if ($role eq 'emailusername') {
                         if (ref($settings->{$context}->{$role}->{$statustype}) eq 'HASH') {                  if ($statustype) {
                             $hashref = $settings->{$context}->{$role}->{$statustype};                      if (ref($settings->{$context}->{$role}->{$statustype}) eq 'HASH') {
                             if (ref($hashref) eq 'HASH') {                           $hashref = $settings->{$context}->{$role}->{$statustype};
                                 foreach my $field (@fields) {  
                                     if ($hashref->{$field}) {  
                                         $checks{$field} = $hashref->{$field};  
                                     }  
                                 }  
                             }  
                         }  
                     }                      }
                 } else {                  }
                     if (ref($hashref) eq 'HASH') {              }
                         foreach my $field (@fields) {          }
                             if ($hashref->{$field}) {          if (ref($hashref) eq 'HASH') { 
                                 $checks{$field} = ' checked="checked" ';              foreach my $field (@fields) {
                             }                  if ($hashref->{$field}) {
                         }                      if ($role eq 'emailusername') {
                           $checks{$field} = $hashref->{$field};
                       } else {
                           $checks{$field} = ' checked="checked" ';
                     }                      }
                 }                  }
             }              }
         }          }
     }      }
         
     for (my $i=0; $i<@fields; $i++) {      my $total = scalar(@fields);
         my $rem = $i%($numinrow);      for (my $i=0; $i<$total; $i++) {
           $rem = $i%($numinrow);
         if ($rem == 0) {          if ($rem == 0) {
             if ($i > 0) {              if ($i > 0) {
                 $output .= '</tr>';                  $output .= '</tr>';
Line 7150  sub modifiable_userdata_row { Line 8941  sub modifiable_userdata_row {
         unless ($role eq 'emailusername') {          unless ($role eq 'emailusername') {
             if (exists($checks{$fields[$i]})) {              if (exists($checks{$fields[$i]})) {
                 $check = $checks{$fields[$i]}                  $check = $checks{$fields[$i]}
             } else {              } elsif ($context ne 'lti') {
                 if ($role eq 'st') {                  if ($role eq 'st') {
                     if (ref($settings) ne 'HASH') {                      if (ref($settings) ne 'HASH') {
                         $check = ' checked="checked" ';                           $check = ' checked="checked" '; 
Line 7160  sub modifiable_userdata_row { Line 8951  sub modifiable_userdata_row {
         }          }
         $output .= '<td class="LC_left_item">'.          $output .= '<td class="LC_left_item">'.
                    '<span class="LC_nobreak">';                     '<span class="LC_nobreak">';
           my $prefix = 'canmodify';
         if ($role eq 'emailusername') {          if ($role eq 'emailusername') {
             unless ($checks{$fields[$i]} =~ /^(required|optional)$/) {              unless ($checks{$fields[$i]} =~ /^(required|optional)$/) {
                 $checks{$fields[$i]} = 'omit';                  $checks{$fields[$i]} = 'omit';
Line 7170  sub modifiable_userdata_row { Line 8962  sub modifiable_userdata_row {
                     $checked='checked="checked" ';                      $checked='checked="checked" ';
                 }                  }
                 $output .= '<label>'.                  $output .= '<label>'.
                            '<input type="radio" name="canmodify_'.$item.'_'.$fields[$i].'" value="'.$option.'" '.$checked.'/>'.                             '<input type="radio" name="'.$prefix.'_'.$item.'_'.$fields[$i].'" value="'.$option.'" '.$checked.'/>'.
                            &mt($option).'</label>'.('&nbsp;' x2);                             &mt($option).'</label>'.('&nbsp;' x2);
             }              }
             $output .= '<i>'.$fieldtitles{$fields[$i]}.'</i>';              $output .= '<i>'.$fieldtitles{$fields[$i]}.'</i>';
         } else {          } else {
               if ($context eq 'lti') {
                   $prefix = 'lti';
               }
             $output .= '<label>'.              $output .= '<label>'.
                        '<input type="checkbox" name="canmodify_'.$role.'" '.                         '<input type="checkbox" name="'.$prefix.'_'.$role.'" '.
                        'value="'.$fields[$i].'"'.$check.'/>'.$fieldtitles{$fields[$i]}.                         'value="'.$fields[$i].'"'.$check.'/>'.$fieldtitles{$fields[$i]}.
                        '</label>';                         '</label>';
         }          }
         $output .= '</span></td>';          $output .= '</span></td>';
         $rem = @fields%($numinrow);  
     }      }
     my $colsleft = $numinrow - $rem;      $rem = $total%$numinrow;
     if ($colsleft > 1 ) {      my $colsleft;
       if ($rem) {
           $colsleft = $numinrow - $rem;
       }
       if ($colsleft > 1) {
         $output .= '<td colspan="'.$colsleft.'" class="LC_left_item">'.          $output .= '<td colspan="'.$colsleft.'" class="LC_left_item">'.
                    '&nbsp;</td>';                     '&nbsp;</td>';
     } elsif ($colsleft == 1) {      } elsif ($colsleft == 1) {
Line 7195  sub modifiable_userdata_row { Line 8993  sub modifiable_userdata_row {
 }  }
   
 sub insttypes_row {  sub insttypes_row {
     my ($settings,$types,$usertypes,$dom,$numinrow,$othertitle,$context,$rownum) = @_;      my ($settings,$types,$usertypes,$dom,$numinrow,$othertitle,$context,$rowtotal,$onclick,
           $customcss,$rowstyle) = @_;
     my %lt = &Apache::lonlocal::texthash (      my %lt = &Apache::lonlocal::texthash (
                       cansearch => 'Users allowed to search',                        cansearch => 'Users allowed to search',
                       statustocreate => 'Institutional affiliation(s) able to create own account (login/SSO)',                        statustocreate => 'Institutional affiliation(s) able to create own account (login/SSO)',
                       lockablenames => 'User preference to lock name',                        lockablenames => 'User preference to lock name',
                         selfassign    => 'Self-reportable affiliations',
                         overrides     => "Override domain's helpdesk settings based on requester's affiliation",
              );               );
     my $showdom;      my $showdom;
     if ($context eq 'cansearch') {      if ($context eq 'cansearch') {
Line 7209  sub insttypes_row { Line 9010  sub insttypes_row {
     if ($context eq 'statustocreate') {      if ($context eq 'statustocreate') {
         $class = 'LC_right_item';          $class = 'LC_right_item';
     }      }
     my $css_class = ' class="LC_odd_row"';      my $css_class;
     if ($rownum ne '') {       if ($$rowtotal%2) {
         $css_class = ($rownum%2? ' class="LC_odd_row"':'');          $css_class = 'LC_odd_row';
       }
       if ($customcss) {
           $css_class .= ' '.$customcss;
       }
       $css_class =~ s/^\s+//;
       if ($css_class) {
           $css_class = ' class="'.$css_class.'"';
       }
       if ($rowstyle) {
           $css_class .= ' style="'.$rowstyle.'"';
       }
       if ($onclick) {
           $onclick = 'onclick="'.$onclick.'" ';
     }      }
     my $output = '<tr'.$css_class.'>'.      my $output = '<tr'.$css_class.'>'.
                  '<td>'.$lt{$context}.$showdom.                   '<td>'.$lt{$context}.$showdom.
Line 7233  sub insttypes_row { Line 9047  sub insttypes_row {
                         if (grep(/^\Q$types->[$i]\E$/,@{$settings->{$context}})) {                          if (grep(/^\Q$types->[$i]\E$/,@{$settings->{$context}})) {
                             $check = ' checked="checked" ';                              $check = ' checked="checked" ';
                         }                          }
                       } elsif (ref($settings->{$context}) eq 'HASH') {
                           if (ref($settings->{$context}->{$types->[$i]}) eq 'HASH') {
                               $check = ' checked="checked" ';
                           }
                     } elsif ($context eq 'statustocreate') {                      } elsif ($context eq 'statustocreate') {
                         $check = ' checked="checked" ';                          $check = ' checked="checked" ';
                     }                      }
Line 7240  sub insttypes_row { Line 9058  sub insttypes_row {
                 $output .= '<td class="LC_left_item">'.                  $output .= '<td class="LC_left_item">'.
                            '<span class="LC_nobreak"><label>'.                             '<span class="LC_nobreak"><label>'.
                            '<input type="checkbox" name="'.$context.'" '.                             '<input type="checkbox" name="'.$context.'" '.
                            'value="'.$types->[$i].'"'.$check.'/>'.                             'value="'.$types->[$i].'"'.$check.$onclick.' />'.
                            $usertypes->{$types->[$i]}.'</label></span></td>';                             $usertypes->{$types->[$i]}.'</label></span></td>';
             }              }
         }          }
         $rem = @{$types}%($numinrow);          $rem = @{$types}%($numinrow);
     }      }
     my $colsleft = $numinrow - $rem;      my $colsleft = $numinrow - $rem;
     if (($rem == 0) && (@{$types} > 0)) {      if ($context eq 'overrides') {
         $output .= '<tr>';          if ($colsleft > 1) {
     }              $output .= '<td colspan="'.$colsleft.'" class="LC_left_item">';
     if ($colsleft > 1) {          } else {
         $output .= '<td colspan="'.$colsleft.'" class="LC_left_item">';              $output .= '<td class="LC_left_item">';
           }
           $output .= '&nbsp;';  
     } else {      } else {
         $output .= '<td class="LC_left_item">';          if ($rem == 0) {
     }              $output .= '<tr>';
     my $defcheck = ' ';          }
     if (ref($settings) eq 'HASH') {            if ($colsleft > 1) {
         if (ref($settings->{$context}) eq 'ARRAY') {              $output .= '<td colspan="'.$colsleft.'" class="LC_left_item">';
             if (grep(/^default$/,@{$settings->{$context}})) {          } else {
               $output .= '<td class="LC_left_item">';
           }
           my $defcheck = ' ';
           if (ref($settings) eq 'HASH') {  
               if (ref($settings->{$context}) eq 'ARRAY') {
                   if (grep(/^default$/,@{$settings->{$context}})) {
                       $defcheck = ' checked="checked" ';
                   }
               } elsif ($context eq 'statustocreate') {
                 $defcheck = ' checked="checked" ';                  $defcheck = ' checked="checked" ';
             }              }
         } elsif ($context eq 'statustocreate') {  
             $defcheck = ' checked="checked" ';  
         }          }
           $output .= '<span class="LC_nobreak"><label>'.
                      '<input type="checkbox" name="'.$context.'" '.
                      'value="default"'.$defcheck.$onclick.' />'.
                      $othertitle.'</label></span>';
     }      }
     $output .= '<span class="LC_nobreak"><label>'.      $output .= '</td></tr></table></td></tr>';
                '<input type="checkbox" name="'.$context.'" '.  
                'value="default"'.$defcheck.'/>'.  
                $othertitle.'</label></span></td>'.  
                '</tr></table></td></tr>';  
     return $output;      return $output;
 }  }
   
Line 7554  sub modify_login { Line 9381  sub modify_login {
             } elsif ($currheadtagurls{$lonhost}) {              } elsif ($currheadtagurls{$lonhost}) {
                 $loginhash{'login'}{'headtag'}{$lonhost}{'url'} = $currheadtagurls{$lonhost};                  $loginhash{'login'}{'headtag'}{$lonhost}{'url'} = $currheadtagurls{$lonhost};
                 if ($currexempt{$lonhost}) {                  if ($currexempt{$lonhost}) {
                     if ((!exists($possexempt{$lonhost})) || ($possexempt{$lonhost} ne $currexempt{$lonhost})) {                       if ((!exists($possexempt{$lonhost})) || ($possexempt{$lonhost} ne $currexempt{$lonhost})) {
                         $changes{'headtag'}{$lonhost} = 1;                          $changes{'headtag'}{$lonhost} = 1;
                     }                      }
                 } elsif ($possexempt{$lonhost}) {                  } elsif ($possexempt{$lonhost}) {
Line 7786  sub modify_login { Line 9613  sub modify_login {
     return $resulttext;      return $resulttext;
 }  }
   
   
 sub check_exempt_addresses {  sub check_exempt_addresses {
     my ($iplist) = @_;      my ($iplist) = @_;
     $iplist =~ s/^\s+//;      $iplist =~ s/^\s+//;
Line 8177  sub display_colorchgs { Line 10003  sub display_colorchgs {
                         } else {                          } else {
                             my $newitem = $confhash->{$role}{$item};                              my $newitem = $confhash->{$role}{$item};
                             if ($key eq 'images') {                              if ($key eq 'images') {
                                 $newitem = '<img src="'.$confhash->{$role}{$item}.'" alt="'.$choices{$item}.'" valign="bottom" />';                                  $newitem = '<img src="'.$confhash->{$role}{$item}.'" alt="'.$choices{$item}.'" style="vertical-align: bottom" />';
                             }                              }
                             $resulttext .= '<li>'.&mt("$choices{$item} set to [_1]",$newitem).'</li>';                              $resulttext .= '<li>'.&mt("$choices{$item} set to [_1]",$newitem).'</li>';
                         }                          }
Line 8304  sub publishlogo { Line 10130  sub publishlogo {
     } else {      } else {
         my $source = $filepath.'/'.$file;          my $source = $filepath.'/'.$file;
         my $logfile;          my $logfile;
         if (!open($logfile,">>$source".'.log')) {          if (!open($logfile,">>",$source.'.log')) {
             return (&mt('No write permission to Authoring Space'));              return (&mt('No write permission to Authoring Space'));
         }          }
         print $logfile          print $logfile
 "\n================= Publish ".localtime()." ================\n".  "\n================= Publish ".localtime()." ================\n".
 $env{'user.name'}.':'.$env{'user.domain'}."\n";  $env{'user.name'}.':'.$env{'user.domain'}."\n";
 # Save the file  # Save the file
         if (!open(FH,'>'.$source)) {          if (!open(FH,">",$source)) {
             &Apache::lonnet::logthis('Failed to create '.$source);              &Apache::lonnet::logthis('Failed to create '.$source);
             return (&mt('Failed to create file'));              return (&mt('Failed to create file'));
         }          }
Line 8372  $env{'user.name'}.':'.$env{'user.domain' Line 10198  $env{'user.name'}.':'.$env{'user.domain'
                 if ($fullwidth ne '' && $fullheight ne '') {                   if ($fullwidth ne '' && $fullheight ne '') { 
                     if ($fullwidth > $thumbwidth && $fullheight > $thumbheight) {                      if ($fullwidth > $thumbwidth && $fullheight > $thumbheight) {
                         my $thumbsize = $thumbwidth.'x'.$thumbheight;                          my $thumbsize = $thumbwidth.'x'.$thumbheight;
                         system("convert -sample $thumbsize $inputfile $outfile");                          my @args = ('convert','-sample',$thumbsize,$inputfile,$outfile);
                           system({$args[0]} @args);
                         chmod(0660, $filepath.'/tn-'.$file);                          chmod(0660, $filepath.'/tn-'.$file);
                         if (-e $outfile) {                          if (-e $outfile) {
                             my $copyfile=$targetdir.'/tn-'.$file;                              my $copyfile=$targetdir.'/tn-'.$file;
Line 8452  sub write_metadata { Line 10279  sub write_metadata {
     {      {
         print $logfile "\nWrite metadata file for ".$targetdir.'/'.$file;          print $logfile "\nWrite metadata file for ".$targetdir.'/'.$file;
         my $mfh;          my $mfh;
         if (open($mfh,'>'.$targetdir.'/'.$file.'.meta')) {          if (open($mfh,">",$targetdir.'/'.$file.'.meta')) {
             foreach (sort(keys(%metadatafields))) {              foreach (sort(keys(%metadatafields))) {
                 unless ($_=~/\./) {                  unless ($_=~/\./) {
                     my $unikey=$_;                      my $unikey=$_;
Line 8486  sub notifysubscribed { Line 10313  sub notifysubscribed {
         next unless (ref($targetsource) eq 'ARRAY');          next unless (ref($targetsource) eq 'ARRAY');
         my ($target,$source)=@{$targetsource};          my ($target,$source)=@{$targetsource};
         if ($source ne '') {          if ($source ne '') {
             if (open(my $logfh,'>>'.$source.'.log')) {              if (open(my $logfh,">>",$source.'.log')) {
                 print $logfh "\nCleanup phase: Notifications\n";                  print $logfh "\nCleanup phase: Notifications\n";
                 my @subscribed=&subscribed_hosts($target);                  my @subscribed=&subscribed_hosts($target);
                 foreach my $subhost (@subscribed) {                  foreach my $subhost (@subscribed) {
Line 8512  sub notifysubscribed { Line 10339  sub notifysubscribed {
 sub subscribed_hosts {  sub subscribed_hosts {
     my ($target) = @_;      my ($target) = @_;
     my @subscribed;      my @subscribed;
     if (open(my $fh,"<$target.subscription")) {      if (open(my $fh,"<","$target.subscription")) {
         while (my $subline=<$fh>) {          while (my $subline=<$fh>) {
             if ($subline =~ /^($match_lonid):/) {              if ($subline =~ /^($match_lonid):/) {
                 my $host = $1;                  my $host = $1;
Line 8554  sub modify_quotas { Line 10381  sub modify_quotas {
         $context = $action;          $context = $action;
     }      }
     if ($context eq 'requestcourses') {      if ($context eq 'requestcourses') {
         @usertools = ('official','unofficial','community','textbook','placement');          @usertools = ('official','unofficial','community','textbook','placement','lti');
         @options =('norequest','approval','validate','autolimit');          @options =('norequest','approval','validate','autolimit');
         %validations = &Apache::lonnet::auto_courserequest_checks($dom);          %validations = &Apache::lonnet::auto_courserequest_checks($dom);
         %titles = &courserequest_titles();          %titles = &courserequest_titles();
Line 8603  sub modify_quotas { Line 10430  sub modify_quotas {
         my @approvalnotify = &Apache::loncommon::get_env_multiple('form.'.$context.'notifyapproval');          my @approvalnotify = &Apache::loncommon::get_env_multiple('form.'.$context.'notifyapproval');
         @approvalnotify = sort(@approvalnotify);          @approvalnotify = sort(@approvalnotify);
         $confhash{'notify'}{'approval'} = join(',',@approvalnotify);          $confhash{'notify'}{'approval'} = join(',',@approvalnotify);
         my @crstypes = ('official','unofficial','community','textbook','placement');          my @crstypes = ('official','unofficial','community','textbook','placement','lti');
         my @hasuniquecode = &Apache::loncommon::get_env_multiple('form.uniquecode');          my @hasuniquecode = &Apache::loncommon::get_env_multiple('form.uniquecode');
         foreach my $type (@hasuniquecode) {          foreach my $type (@hasuniquecode) {
             if (grep(/^\Q$type\E$/,@crstypes)) {              if (grep(/^\Q$type\E$/,@crstypes)) {
Line 8697  sub modify_quotas { Line 10524  sub modify_quotas {
                                     my $newpos = $env{'form.'.$itemid};                                      my $newpos = $env{'form.'.$itemid};
                                     $newpos =~ s/\D+//g;                                      $newpos =~ s/\D+//g;
                                     foreach my $item ('subject','title','publisher','author') {                                      foreach my $item ('subject','title','publisher','author') {
                                         next if ((($item eq 'author') || ($item eq 'publisher')) &&                                           next if ((($item eq 'author') || ($item eq 'publisher')) &&
                                                  ($type eq 'templates'));                                                   ($type eq 'templates'));
                                         $confhash{$type}{$key}{$item} = $env{'form.'.$type.'_'.$item.'_'.$i};                                          $confhash{$type}{$key}{$item} = $env{'form.'.$type.'_'.$item.'_'.$i};
                                         if ($domconfig{$action}{$type}{$key}{$item} ne $confhash{$type}{$key}{$item}) {                                          if ($domconfig{$action}{$type}{$key}{$item} ne $confhash{$type}{$key}{$item}) {
Line 8711  sub modify_quotas { Line 10538  sub modify_quotas {
                                     #FIXME need to obsolete item in RES space                                      #FIXME need to obsolete item in RES space
                                 } elsif ($env{'form.'.$type.'_image_'.$i.'.filename'}) {                                  } elsif ($env{'form.'.$type.'_image_'.$i.'.filename'}) {
                                     my ($cdom,$cnum) = split(/_/,$key);                                      my ($cdom,$cnum) = split(/_/,$key);
                                     my ($imgurl,$error) = &process_textbook_image($r,$dom,$confname,$type.'_image_'.$i,                                      if (&Apache::lonnet::homeserver($cnum,$cdom) eq 'no_host') {
                                                                                   $cdom,$cnum,$type,$configuserok,                                          $errors .= '<li><span class="LC_error">'.&mt('Image not saved: could not find textbook course').'</li>';
                                                                                   $switchserver,$author_ok);                                      } else {
                                     if ($imgurl) {                                          my ($imgurl,$error) = &process_textbook_image($r,$dom,$confname,$type.'_image_'.$i,
                                         $confhash{$type}{$key}{'image'} = $imgurl;                                                                                        $cdom,$cnum,$type,$configuserok,
                                         $changes{$type}{$key} = 1;                                                                                         $switchserver,$author_ok);
                                     }                                          if ($imgurl) {
                                     if ($error) {                                              $confhash{$type}{$key}{'image'} = $imgurl;
                                         &Apache::lonnet::logthis($error);                                              $changes{$type}{$key} = 1; 
                                         $errors .= '<li><span class="LC_error">'.$error.'</span></li>';                                          }
                                     }                                           if ($error) {
                                               &Apache::lonnet::logthis($error);
                                               $errors .= '<li><span class="LC_error">'.$error.'</span></li>';
                                           }
                                       }
                                 } elsif ($domconfig{$action}{$type}{$key}{'image'}) {                                  } elsif ($domconfig{$action}{$type}{$key}{'image'}) {
                                     $confhash{$type}{$key}{'image'} =                                       $confhash{$type}{$key}{'image'} = 
                                         $domconfig{$action}{$type}{$key}{'image'};                                          $domconfig{$action}{$type}{$key}{'image'};
Line 8754  sub modify_quotas { Line 10585  sub modify_quotas {
                     if ($type eq 'textbooks') {                      if ($type eq 'textbooks') {
                         if ($env{'form.'.$type.'_addbook_image.filename'} ne '') {                          if ($env{'form.'.$type.'_addbook_image.filename'} ne '') {
                             my ($cdom,$cnum) = split(/_/,$newbook{$type});                              my ($cdom,$cnum) = split(/_/,$newbook{$type});
                             my ($imageurl,$error) =                              if (&Apache::lonnet::homeserver($cnum,$cdom) eq 'no_host') {
                                 &process_textbook_image($r,$dom,$confname,$type.'_addbook_image',$cdom,$cnum,$type,                                  $errors .= '<li><span class="LC_error">'.&mt('Image not saved: could not find textbook course').'</li>';
                                                         $configuserok,$switchserver,$author_ok);                              } else {
                             if ($imageurl) {                                  my ($imageurl,$error) =
                                 $confhash{$type}{$newbook{$type}}{'image'} = $imageurl;                                      &process_textbook_image($r,$dom,$confname,$type.'_addbook_image',$cdom,$cnum,$type,
                             }                                                              $configuserok,$switchserver,$author_ok);
                             if ($error) {                                  if ($imageurl) {
                                 &Apache::lonnet::logthis($error);                                      $confhash{$type}{$newbook{$type}}{'image'} = $imageurl;
                                 $errors .= '<li><span class="LC_error">'.$error.'</span></li>';                                  }
                                   if ($error) {
                                       &Apache::lonnet::logthis($error);
                                       $errors .= '<li><span class="LC_error">'.$error.'</span></li>';
                                   }
                             }                              }
                         }                          }
                     }                      }
Line 8866  sub modify_quotas { Line 10701  sub modify_quotas {
                     }                      }
                 } elsif ($confhash{'validation'}{'dc'} ne '') {                  } elsif ($confhash{'validation'}{'dc'} ne '') {
                     $changes{'validation'}{'dc'} = $confhash{'validation'}{'dc'};                      $changes{'validation'}{'dc'} = $confhash{'validation'}{'dc'};
                 }                    }
             } else {              } else {
                 if (ref($domconfig{'requestcourses'}) eq 'HASH') {                  if (ref($domconfig{'requestcourses'}) eq 'HASH') {
                     if (ref($domconfig{'requestcourses'}{'validation'}) eq 'HASH') {                      if (ref($domconfig{'requestcourses'}{'validation'}) eq 'HASH') {
Line 9254  sub process_textbook_image { Line 11089  sub process_textbook_image {
         } elsif ($author_ok eq 'ok') {          } elsif ($author_ok eq 'ok') {
             my ($result,$imageurl) =              my ($result,$imageurl) =
                 &publishlogo($r,'upload',$caller,$dom,$confname,                  &publishlogo($r,'upload',$caller,$dom,$confname,
                              "$type/$dom/$cnum/cover",$width,$height);                               "$type/$cdom/$cnum/cover",$width,$height);
             if ($result eq 'ok') {              if ($result eq 'ok') {
                 $url = $imageurl;                  $url = $imageurl;
             } else {              } else {
Line 9272  sub process_textbook_image { Line 11107  sub process_textbook_image {
 sub modify_ltitools {  sub modify_ltitools {
     my ($r,$dom,$action,$lastactref,%domconfig) = @_;      my ($r,$dom,$action,$lastactref,%domconfig) = @_;
     my %domdefaults = &Apache::lonnet::get_domain_defaults($dom,1);      my %domdefaults = &Apache::lonnet::get_domain_defaults($dom,1);
     my ($newid,@allpos,%changes,%confhash,$errors,$resulttext);      my ($newid,@allpos,%changes,%confhash,%encconfig,$errors,$resulttext);
     my $confname = $dom.'-domainconfig';      my $confname = $dom.'-domainconfig';
     my $servadm = $r->dir_config('lonAdmEMail');      my $servadm = $r->dir_config('lonAdmEMail');
     my ($configuserok,$author_ok,$switchserver) = &config_check($dom,$confname,$servadm);      my ($configuserok,$author_ok,$switchserver) = &config_check($dom,$confname,$servadm);
Line 9294  sub modify_ltitools { Line 11129  sub modify_ltitools {
                 $allpos[$position] = $newid;                  $allpos[$position] = $newid;
             }              }
             $changes{$newid} = 1;              $changes{$newid} = 1;
             foreach my $item ('title','url','key','secret') {              foreach my $item ('title','url','key','secret','lifetime') {
                 $env{'form.ltitools_add_'.$item} =~ s/(`)/'/g;                  $env{'form.ltitools_add_'.$item} =~ s/(`)/'/g;
                   if ($item eq 'lifetime') {
                       $env{'form.ltitools_add_'.$item} =~ s/[^\d.]//g;
                   }
                 if ($env{'form.ltitools_add_'.$item}) {                  if ($env{'form.ltitools_add_'.$item}) {
                     $confhash{$newid}{$item} = $env{'form.ltitools_add_'.$item};                      if (($item eq 'key') || ($item eq 'secret')) {
                           $encconfig{$newid}{$item} = $env{'form.ltitools_add_'.$item};
                       } else {
                           $confhash{$newid}{$item} = $env{'form.ltitools_add_'.$item};
                       }
                 }                  }
             }              }
             if ($env{'form.ltitools_add_version'} eq 'LTI-1p0') {              if ($env{'form.ltitools_add_version'} eq 'LTI-1p0') {
Line 9306  sub modify_ltitools { Line 11148  sub modify_ltitools {
             if ($env{'form.ltitools_add_msgtype'} eq 'basic-lti-launch-request') {              if ($env{'form.ltitools_add_msgtype'} eq 'basic-lti-launch-request') {
                 $confhash{$newid}{'msgtype'} = $env{'form.ltitools_add_msgtype'};                  $confhash{$newid}{'msgtype'} = $env{'form.ltitools_add_msgtype'};
             }              }
             foreach my $item ('width','height') {              if ($env{'form.ltitools_add_sigmethod'} eq 'HMAC-SHA256') {
                   $confhash{$newid}{'sigmethod'} = $env{'form.ltitools_add_sigmethod'};
               } else {
                   $confhash{$newid}{'sigmethod'} = 'HMAC-SHA1';
               }
               foreach my $item ('width','height','linktext','explanation') {
                 $env{'form.ltitools_add_'.$item} =~ s/^\s+//;                  $env{'form.ltitools_add_'.$item} =~ s/^\s+//;
                 $env{'form.ltitools_add_'.$item} =~ s/\s+$//;                  $env{'form.ltitools_add_'.$item} =~ s/\s+$//;
                 if ($env{'form.ltitools_add_'.$item} =~ /^\d+$/) {                  if (($item eq 'width') || ($item eq 'height')) {
                     $confhash{$newid}{'display'}{$item} = $env{'form.ltitools_add_'.$item};                      if ($env{'form.ltitools_add_'.$item} =~ /^\d+$/) {
                           $confhash{$newid}{'display'}{$item} = $env{'form.ltitools_add_'.$item};
                       }
                   } else {
                       if ($env{'form.ltitools_add_'.$item} ne '') {
                           $confhash{$newid}{'display'}{$item} = $env{'form.ltitools_add_'.$item}; 
                       }
                 }                  }
             }              }
             if ($env{'form.ltitools_add_target'} eq 'window') {              if ($env{'form.ltitools_add_target'} eq 'window') {
                 $confhash{$newid}{'display'}{'target'} = $env{'form.ltitools_add_target'};                  $confhash{$newid}{'display'}{'target'} = $env{'form.ltitools_add_target'};
               } elsif ($env{'form.ltitools_add_target'} eq 'tab') {
                   $confhash{$newid}{'display'}{'target'} = $env{'form.ltitools_add_target'};
             } else {              } else {
                 $confhash{$newid}{'display'}{'target'} = 'iframe';                  $confhash{$newid}{'display'}{'target'} = 'iframe';
             }              }
             foreach my $item ('passback','roster') {              foreach my $item ('passback','roster') {
                 if ($env{'form.ltitools_add_'.$item}) {                  if ($env{'form.ltitools_'.$item.'_add'}) {
                     $confhash{$newid}{$item} = 1;                      $confhash{$newid}{$item} = 1;
                       if ($env{'form.ltitools_'.$item.'valid_add'} ne '') {
                           my $lifetime = $env{'form.ltitools_'.$item.'valid_add'};
                           $lifetime =~ s/^\s+|\s+$//g;
                           if ($lifetime =~ /^\d+\.?\d*$/) {
                               $confhash{$newid}{$item.'valid'} = $lifetime;
                           }
                       }
                 }                  }
             }              }
             if ($env{'form.ltitools_add_image.filename'} ne '') {              if ($env{'form.ltitools_add_image.filename'} ne '') {
                 my ($imageurl,$error) =                  my ($imageurl,$error) =
                     &process_ltitools_image($r,$dom,$confname,'ltitools_add_image',$dom,                      &process_ltitools_image($r,$dom,$confname,'ltitools_add_image',$newid,
                                             $configuserok,$switchserver,$author_ok);                                              $configuserok,$switchserver,$author_ok);
                 if ($imageurl) {                  if ($imageurl) {
                     $confhash{$newid}{'image'} = $imageurl;                      $confhash{$newid}{'image'} = $imageurl;
Line 9353  sub modify_ltitools { Line 11215  sub modify_ltitools {
                     }                      }
                 }                  }
             }              }
               if (ref($confhash{$newid}{'fields'}) eq 'HASH') {
                   if ($confhash{$newid}{'fields'}{'user'}) {
                       if ($env{'form.ltitools_userincdom_add'}) {
                           $confhash{$newid}{'incdom'} = 1;
                       }
                   }
               }
             my @courseconfig = &Apache::loncommon::get_env_multiple('form.ltitools_courseconfig');              my @courseconfig = &Apache::loncommon::get_env_multiple('form.ltitools_courseconfig');
             foreach my $item (@courseconfig) {              foreach my $item (@courseconfig) {
                 $confhash{$newid}{'crsconf'}{$item} = 1;                  $confhash{$newid}{'crsconf'}{$item} = 1;
Line 9388  sub modify_ltitools { Line 11257  sub modify_ltitools {
         my $maxnum = $env{'form.ltitools_maxnum'};          my $maxnum = $env{'form.ltitools_maxnum'};
         for (my $i=0; $i<=$maxnum; $i++) {          for (my $i=0; $i<=$maxnum; $i++) {
             my $itemid = $env{'form.ltitools_id_'.$i};              my $itemid = $env{'form.ltitools_id_'.$i};
               $itemid =~ s/\D+//g;
             if (ref($domconfig{$action}{$itemid}) eq 'HASH') {              if (ref($domconfig{$action}{$itemid}) eq 'HASH') {
                 if ($deletions{$itemid}) {                  if ($deletions{$itemid}) {
                     if ($domconfig{$action}{$itemid}{'image'}) {                      if ($domconfig{$action}{$itemid}{'image'}) {
Line 9398  sub modify_ltitools { Line 11268  sub modify_ltitools {
                 } else {                  } else {
                     my $newpos = $env{'form.ltitools_'.$itemid};                      my $newpos = $env{'form.ltitools_'.$itemid};
                     $newpos =~ s/\D+//g;                      $newpos =~ s/\D+//g;
                     foreach my $item ('title','url','key','secret') {                      foreach my $item ('title','url','lifetime') {
                         $confhash{$itemid}{$item} = $env{'form.ltitools_'.$item.'_'.$i};                          $confhash{$itemid}{$item} = $env{'form.ltitools_'.$item.'_'.$i};
                         if ($domconfig{$action}{$itemid}{$item} ne $confhash{$itemid}{$item}) {                          if ($domconfig{$action}{$itemid}{$item} ne $confhash{$itemid}{$item}) {
                             $changes{$itemid} = 1;                              $changes{$itemid} = 1;
                         }                          }
                     }                      }
                       foreach my $item ('key','secret') {
                           $encconfig{$itemid}{$item} = $env{'form.ltitools_'.$item.'_'.$i};
                           if ($domconfig{$action}{$itemid}{$item} ne $encconfig{$itemid}{$item}) {
                               $changes{$itemid} = 1;
                           }
                       }
                     if ($env{'form.ltitools_version_'.$i} eq 'LTI-1p0') {                      if ($env{'form.ltitools_version_'.$i} eq 'LTI-1p0') {
                         $confhash{$itemid}{'version'} = $env{'form.ltitools_version_'.$i};                          $confhash{$itemid}{'version'} = $env{'form.ltitools_version_'.$i};
                     }                      }
                     if ($env{'form.ltitools_msgtype_'.$i} eq 'basic-lti-launch-request') {                      if ($env{'form.ltitools_msgtype_'.$i} eq 'basic-lti-launch-request') {
                         $confhash{$itemid}{'msgtype'} = $env{'form.ltitools_msgtype_'.$i};                          $confhash{$itemid}{'msgtype'} = $env{'form.ltitools_msgtype_'.$i};
                     }                      }
                       if ($env{'form.ltitools_sigmethod_'.$i} eq 'HMAC-SHA256') {
                           $confhash{$itemid}{'sigmethod'} = $env{'form.ltitools_sigmethod_'.$i};
                       } else {
                           $confhash{$itemid}{'sigmethod'} = 'HMAC-SHA1'; 
                       }
                       if ($domconfig{$action}{$itemid}{'sigmethod'} eq '') {
                           if ($confhash{$itemid}{'sigmethod'} ne 'HMAC-SHA1') {
                               $changes{$itemid} = 1;
                           }
                       } elsif ($domconfig{$action}{$itemid}{'sigmethod'} ne $confhash{$itemid}{'sigmethod'}) {
                           $changes{$itemid} = 1;
                       }
                     foreach my $size ('width','height') {                      foreach my $size ('width','height') {
                         $env{'form.ltitools_'.$size.'_'.$i} =~ s/^\s+//;                          $env{'form.ltitools_'.$size.'_'.$i} =~ s/^\s+//;
                         $env{'form.ltitools_'.$size.'_'.$i} =~ s/\s+$//;                          $env{'form.ltitools_'.$size.'_'.$i} =~ s/\s+$//;
Line 9422  sub modify_ltitools { Line 11310  sub modify_ltitools {
                             } else {                              } else {
                                 $changes{$itemid} = 1;                                  $changes{$itemid} = 1;
                             }                              }
                           } elsif (ref($domconfig{$action}{$itemid}{'display'}) eq 'HASH') {
                               if ($domconfig{$action}{$itemid}{'display'}{$size} ne '') {
                                   $changes{$itemid} = 1;
                               }
                           }
                       }
                       foreach my $item ('linktext','explanation') {
                           $env{'form.ltitools_'.$item.'_'.$i} =~ s/^\s+//;
                           $env{'form.ltitools_'.$item.'_'.$i} =~ s/\s+$//;
                           if ($env{'form.ltitools_'.$item.'_'.$i} ne '') {
                               $confhash{$itemid}{'display'}{$item} = $env{'form.ltitools_'.$item.'_'.$i};
                               if (ref($domconfig{$action}{$itemid}{'display'}) eq 'HASH') {
                                   if ($domconfig{$action}{$itemid}{'display'}{$item} ne $confhash{$itemid}{'display'}{$item}) {
                                       $changes{$itemid} = 1;
                                   }
                               } else {
                                   $changes{$itemid} = 1;
                               }
                           } elsif (ref($domconfig{$action}{$itemid}{'display'}) eq 'HASH') {
                               if ($domconfig{$action}{$itemid}{'display'}{$item} ne '') {
                                   $changes{$itemid} = 1;
                               }
                         }                          }
                     }                      }
                     if ($env{'form.ltitools_target_'.$i} eq 'window') {                      if ($env{'form.ltitools_target_'.$i} eq 'window') {
                         $confhash{$itemid}{'display'}{'target'} = $env{'form.ltitools_target_'.$i};                          $confhash{$itemid}{'display'}{'target'} = $env{'form.ltitools_target_'.$i};
                       } elsif ($env{'form.ltitools_target_'.$i} eq 'tab') {
                           $confhash{$itemid}{'display'}{'target'} = $env{'form.ltitools_target_'.$i};
                     } else {                      } else {
                         $confhash{$itemid}{'display'}{'target'} = 'iframe';                          $confhash{$itemid}{'display'}{'target'} = 'iframe';
                     }                      }
Line 9439  sub modify_ltitools { Line 11351  sub modify_ltitools {
                     foreach my $extra ('passback','roster') {                      foreach my $extra ('passback','roster') {
                         if ($env{'form.ltitools_'.$extra.'_'.$i}) {                          if ($env{'form.ltitools_'.$extra.'_'.$i}) {
                             $confhash{$itemid}{$extra} = 1;                              $confhash{$itemid}{$extra} = 1;
                               if ($env{'form.ltitools_'.$extra.'valid_'.$i} ne '') {
                                   my $lifetime = $env{'form.ltitools_'.$extra.'valid_'.$i};
                                   $lifetime =~ s/^\s+|\s+$//g;
                                   if ($lifetime =~ /^\d+\.?\d*$/) {
                                       $confhash{$itemid}{$extra.'valid'} = $lifetime;
                                   }
                               }
                         }                          }
                         if ($domconfig{$action}{$itemid}{$extra} ne $confhash{$itemid}{$extra}) {                          if ($domconfig{$action}{$itemid}{$extra} ne $confhash{$itemid}{$extra}) {
                             $changes{$itemid} = 1;                              $changes{$itemid} = 1;
                         }                          }
                           if ($domconfig{$action}{$itemid}{$extra.'valid'} ne $confhash{$itemid}{$extra.'valid'}) {
                               $changes{$itemid} = 1;
                           }
                     }                      }
                     my @courseconfig = &Apache::loncommon::get_env_multiple('form.ltitools_courseconfig_'.$i);                      my @courseconfig = &Apache::loncommon::get_env_multiple('form.ltitools_courseconfig_'.$i);
                     foreach my $item ('label','title','target') {                      foreach my $item ('label','title','target','linktext','explanation','append') {
                         if (grep(/^\Q$item\E$/,@courseconfig)) {                          if (grep(/^\Q$item\E$/,@courseconfig)) {
                             $confhash{$itemid}{'crsconf'}{$item} = 1;                              $confhash{$itemid}{'crsconf'}{$item} = 1;
                             if (ref($domconfig{$action}{$itemid}{'crsconf'}) eq 'HASH') {                              if (ref($domconfig{$action}{$itemid}{'crsconf'}) eq 'HASH') {
Line 9489  sub modify_ltitools { Line 11411  sub modify_ltitools {
                             }                              }
                         }                          }
                     }                      }
                       if (ref($confhash{$itemid}{'fields'}) eq 'HASH') {
                           if ($confhash{$itemid}{'fields'}{'user'}) {
                               if ($env{'form.ltitools_userincdom_'.$i}) {
                                   $confhash{$itemid}{'incdom'} = 1;
                               }
                               if ($domconfig{$action}{$itemid}{'incdom'} ne $confhash{$itemid}{'incdom'}) {
                                   $changes{$itemid} = 1;
                               }
                           }
                       }
                     $allpos[$newpos] = $itemid;                      $allpos[$newpos] = $itemid;
                 }                  }
                 if ($imgdeletions{$itemid}) {                  if ($imgdeletions{$itemid}) {
Line 9584  sub modify_ltitools { Line 11516  sub modify_ltitools {
     my $putresult = &Apache::lonnet::put_dom('configuration',\%ltitoolshash,      my $putresult = &Apache::lonnet::put_dom('configuration',\%ltitoolshash,
                                              $dom);                                               $dom);
     if ($putresult eq 'ok') {      if ($putresult eq 'ok') {
           my %ltienchash = (
                                $action => { %encconfig }
                            );
           &Apache::lonnet::put_dom('encconfig',\%ltienchash,$dom);
         if (keys(%changes) > 0) {          if (keys(%changes) > 0) {
             my $cachetime = 24*60*60;              my $cachetime = 24*60*60;
             &Apache::lonnet::do_cache_new('ltitools',$dom,\%confhash,$cachetime);              my %ltiall = %confhash;
               foreach my $id (keys(%ltiall)) {
                   if (ref($encconfig{$id}) eq 'HASH') {
                       foreach my $item ('key','secret') {
                           $ltiall{$id}{$item} = $encconfig{$id}{$item};
                       }
                   }
               }
               &Apache::lonnet::do_cache_new('ltitools',$dom,\%ltiall,$cachetime);
             if (ref($lastactref) eq 'HASH') {              if (ref($lastactref) eq 'HASH') {
                 $lastactref->{'ltitools'} = 1;                  $lastactref->{'ltitools'} = 1;
             }              }
Line 9610  sub modify_ltitools { Line 11554  sub modify_ltitools {
                     $resulttext .= '</li><ul>';                      $resulttext .= '</li><ul>';
                     my $position = $pos + 1;                      my $position = $pos + 1;
                     $resulttext .= '<li>'.&mt('Order: [_1]',$position).'</li>';                      $resulttext .= '<li>'.&mt('Order: [_1]',$position).'</li>';
                     foreach my $item ('version','msgtype','url','key') {                      foreach my $item ('version','msgtype','sigmethod','url','lifetime') {
                         if ($confhash{$itemid}{$item} ne '') {                          if ($confhash{$itemid}{$item} ne '') {
                             $resulttext .= '<li>'.$lt{$item}.':&nbsp;'.$confhash{$itemid}{$item}.'</li>';                              $resulttext .= '<li>'.$lt{$item}.':&nbsp;'.$confhash{$itemid}{$item}.'</li>';
                         }                          }
                     }                      }
                     if ($confhash{$itemid}{'secret'} ne '') {                      if ($encconfig{$itemid}{'key'} ne '') {
                           $resulttext .= '<li>'.$lt{'key'}.':&nbsp;'.$encconfig{$itemid}{'key'}.'</li>';
                       }
                       if ($encconfig{$itemid}{'secret'} ne '') {
                         $resulttext .= '<li>'.$lt{'secret'}.':&nbsp;';                          $resulttext .= '<li>'.$lt{'secret'}.':&nbsp;';
                         my $num = length($confhash{$itemid}{'secret'});                          my $num = length($encconfig{$itemid}{'secret'});
                         $resulttext .= ('*'x$num).'</li>';                          $resulttext .= ('*'x$num).'</li>';
                     }                      }
                     $resulttext .= '<li>'.&mt('Configurable in course:');                      $resulttext .= '<li>'.&mt('Configurable in course:');
                     my @possconfig = ('label','title','target');                      my @possconfig = ('label','title','target','linktext','explanation','append');
                     my $numconfig = 0;                       my $numconfig = 0; 
                     if (ref($confhash{$itemid}{'crsconf'}) eq 'HASH') {                       if (ref($confhash{$itemid}{'crsconf'}) eq 'HASH') { 
                         foreach my $item (@possconfig) {                          foreach my $item (@possconfig) {
                             if ($confhash{$itemid}{'crsconf'}{$item}) {                              if ($confhash{$itemid}{'crsconf'}{$item}) {
                                 $numconfig ++;                                  $numconfig ++;
                                 $resulttext .= ' '.$lt{'crs'.$item};                                  $resulttext .= ' "'.$lt{'crs'.$item}.'"';
                             }                              }
                         }                          }
                     }                      }
Line 9639  sub modify_ltitools { Line 11586  sub modify_ltitools {
                         $resulttext .= '<li>'.$lt{$item}.'&nbsp;';                          $resulttext .= '<li>'.$lt{$item}.'&nbsp;';
                         if ($confhash{$itemid}{$item}) {                          if ($confhash{$itemid}{$item}) {
                             $resulttext .= &mt('Yes');                              $resulttext .= &mt('Yes');
                               if ($confhash{$itemid}{$item.'valid'}) {
                                   if ($item eq 'passback') {
                                       $resulttext .= ' '.&mt('valid for at least [quant,_1,day] after launch',
                                                              $confhash{$itemid}{$item.'valid'});
                                   } else {
                                       $resulttext .= ' '.&mt('valid for at least [quant,_1,second] after launch',
                                                              $confhash{$itemid}{$item.'valid'});
                                   }
                               }
                         } else {                          } else {
                             $resulttext .= &mt('No');                              $resulttext .= &mt('No');
                         }                          }
Line 9660  sub modify_ltitools { Line 11616  sub modify_ltitools {
                             $displaylist =~ s/,$//;                              $displaylist =~ s/,$//;
                             $resulttext .= '<li>'.$displaylist.'</li>';                              $resulttext .= '<li>'.$displaylist.'</li>';
                         }                          }
                     }                           foreach my $item ('linktext','explanation') {
                               if ($confhash{$itemid}{'display'}{$item}) {
                                   $resulttext .= '<li>'.$lt{$item}.':&nbsp;'.$confhash{$itemid}{'display'}{$item}.'</li>';
                               }
                           }
                       }
                     if (ref($confhash{$itemid}{'fields'}) eq 'HASH') {                      if (ref($confhash{$itemid}{'fields'}) eq 'HASH') {
                         my $fieldlist;                          my $fieldlist;
                         foreach my $field (@allfields) {                          foreach my $field (@allfields) {
Line 9670  sub modify_ltitools { Line 11631  sub modify_ltitools {
                         }                          }
                         if ($fieldlist) {                          if ($fieldlist) {
                             $fieldlist =~ s/,$//;                              $fieldlist =~ s/,$//;
                               if ($confhash{$itemid}{'fields'}{'user'}) {
                                   if ($confhash{$itemid}{'incdom'}) {
                                       $fieldlist .= ' ('.&mt('username:domain').')';
                                   } else {
                                       $fieldlist .= ' ('.&mt('username').')';
                                   }
                               }
                             $resulttext .= '<li>'.&mt('Data sent').':'.$fieldlist.'</li>';                              $resulttext .= '<li>'.&mt('Data sent').':'.$fieldlist.'</li>';
                         }                          }
                     }                      }
Line 9694  sub modify_ltitools { Line 11662  sub modify_ltitools {
                             }                               } 
                         }                          }
                         if ($customlist) {                          if ($customlist) {
                             $resulttext .= '<li>'.&mt('Custom items').':'.$customlist.'</li>';                              $resulttext .= '<li>'.&mt('Custom items').': '.$customlist.'</li>';
                         }                          }
                     }                       } 
                     $resulttext .= '</ul></li>';                      $resulttext .= '</ul></li>';
Line 9790  sub get_ltitools_id { Line 11758  sub get_ltitools_id {
     return ($id,$error);      return ($id,$error);
 }  }
   
   sub modify_lti {
       my ($r,$dom,$action,$lastactref,%domconfig) = @_;
       my %domdefaults = &Apache::lonnet::get_domain_defaults($dom,1);
       my ($newid,@allpos,%changes,%confhash,%encconfig,$errors,$resulttext);
       my (%posslti,%posslticrs,%posscrstype);
       my @courseroles = ('cc','in','ta','ep','st');
       my @ltiroles = qw(Learner Instructor ContentDeveloper TeachingAssistant Mentor Member Manager Administrator);
       my @lticourseroles = qw(Instructor TeachingAssistant Mentor Learner);
       my @coursetypes = ('official','unofficial','community','textbook','placement');
       my %coursetypetitles = &Apache::lonlocal::texthash (
                                  official   => 'Official',
                                  unofficial => 'Unofficial',
                                  community  => 'Community',
                                  textbook   => 'Textbook',
                                  placement  => 'Placement Test',
       );
       my %fieldtitles = &Apache::loncommon::personal_data_fieldtitles();
       my %lt = &lti_names();
       map { $posslti{$_} = 1; } @ltiroles;
       map { $posslticrs{$_} = 1; } @lticourseroles;
       map { $posscrstype{$_} = 1; } @coursetypes;
   
       my %menutitles = &ltimenu_titles();
   
       my (@items,%deletions,%itemids);
       if ($env{'form.lti_add'}) {
           my $consumer = $env{'form.lti_consumer_add'};
           $consumer =~ s/(`)/'/g;
           ($newid,my $error) = &get_lti_id($dom,$consumer);
           if ($newid) {
               $itemids{'add'} = $newid;
               push(@items,'add');
               $changes{$newid} = 1;
           } else {
               my $error = &mt('Failed to acquire unique ID for new LTI configuration');
               $errors .= '<li><span class="LC_error">'.$error.'</span></li>';
           }
       }
       if (ref($domconfig{$action}) eq 'HASH') {
           my @todelete = &Apache::loncommon::get_env_multiple('form.lti_del');
           if (@todelete) {
               map { $deletions{$_} = 1; } @todelete;
           }
           my $maxnum = $env{'form.lti_maxnum'};
           for (my $i=0; $i<=$maxnum; $i++) {
               my $itemid = $env{'form.lti_id_'.$i};
               $itemid =~ s/\D+//g;
               if (ref($domconfig{$action}{$itemid}) eq 'HASH') {
                   if ($deletions{$itemid}) {
                       $changes{$itemid} = $domconfig{$action}{$itemid}{'consumer'};
                   } else {
                      push(@items,$i);
                      $itemids{$i} = $itemid;
                   }
               }
           }
       }
       foreach my $idx (@items) {
           my $itemid = $itemids{$idx};
           next unless ($itemid);
           my $position = $env{'form.lti_pos_'.$idx};
           $position =~ s/\D+//g;
           if ($position ne '') {
               $allpos[$position] = $itemid;
           }
           foreach my $item ('consumer','key','secret','lifetime','requser') {
               my $formitem = 'form.lti_'.$item.'_'.$idx;
               $env{$formitem} =~ s/(`)/'/g;
               if ($item eq 'lifetime') {
                   $env{$formitem} =~ s/[^\d.]//g;
               }
               if ($env{$formitem} ne '') {
                   if (($item eq 'key') || ($item eq 'secret')) {
                       $encconfig{$itemid}{$item} = $env{$formitem};
                   } else {
                       $confhash{$itemid}{$item} = $env{$formitem};
                       unless (($idx eq 'add') || ($changes{$itemid})) {
                           if ($domconfig{$action}{$itemid}{$item} ne $confhash{$itemid}{$item}) {
                               $changes{$itemid} = 1;
                           }
                       }
                   }
               }
           }
           if ($env{'form.lti_version_'.$idx} eq 'LTI-1p0') {
               $confhash{$itemid}{'version'} = $env{'form.lti_version_'.$idx};
           }
           if ($confhash{$itemid}{'requser'}) {
               if ($env{'form.lti_mapuser_'.$idx} eq 'sourcedid') {
                   $confhash{$itemid}{'mapuser'} = 'lis_person_sourcedid'; 
               } elsif ($env{'form.lti_mapuser_'.$idx} eq 'email') {
                   $confhash{$itemid}{'mapuser'} = 'lis_person_contact_email_primary';
               } elsif ($env{'form.lti_mapuser_'.$idx} eq 'other') {
                   my $mapuser = $env{'form.lti_customuser_'.$idx};
                   $mapuser =~ s/(`)/'/g;
                   $mapuser =~ s/^\s+|\s+$//g; 
                   $confhash{$itemid}{'mapuser'} = $mapuser; 
               }
               foreach my $ltirole (@lticourseroles) {
                   my $possrole = $env{'form.lti_maprole_'.$ltirole.'_'.$idx};
                   if (grep(/^\Q$possrole\E$/,@courseroles)) {
                       $confhash{$itemid}{'maproles'}{$ltirole} = $possrole;
                   }
               }
               my @possmakeuser = &Apache::loncommon::get_env_multiple('form.lti_makeuser_'.$idx);
               my @makeuser;
               foreach my $ltirole (sort(@possmakeuser)) {
                   if ($posslti{$ltirole}) {
                       push(@makeuser,$ltirole);
                   }
               }
               $confhash{$itemid}{'makeuser'} = \@makeuser;
               if (@makeuser) {
                   my $lcauth = $env{'form.lti_lcauth_'.$idx};
                   if ($lcauth =~ /^(internal|krb4|krb5|localauth)$/) {
                       $confhash{$itemid}{'lcauth'} = $lcauth;
                       if ($lcauth ne 'internal') {
                           my $lcauthparm = $env{'form.lti_lcauthparm_'.$idx};
                           $lcauthparm =~ s/^(\s+|\s+)$//g;
                           $lcauthparm =~ s/`//g;
                           if ($lcauthparm ne '') {
                               $confhash{$itemid}{'lcauthparm'} = $lcauthparm;
                           }
                       }
                   } else {
                       $confhash{$itemid}{'lcauth'} = 'lti';
                   }
               }
               my @possinstdata =  &Apache::loncommon::get_env_multiple('form.lti_instdata_'.$idx);
               if (@possinstdata) {
                   foreach my $field (@possinstdata) {
                       if (exists($fieldtitles{$field})) {
                           push(@{$confhash{$itemid}{'instdata'}});
                       }
                   }
               }
               if (($env{'form.lti_mapcrs_'.$idx} eq 'course_offering_sourcedid') ||
                   ($env{'form.lti_mapcrs_'.$idx} eq 'context_id'))  {
                   $confhash{$itemid}{'mapcrs'} = $env{'form.lti_mapcrs_'.$idx};
               } elsif ($env{'form.lti_mapcrs_'.$idx} eq 'other') {
                   my $mapcrs = $env{'form.lti_mapcrsfield_'.$idx}; 
                   $mapcrs =~ s/(`)/'/g;
                   $mapcrs =~ s/^\s+|\s+$//g;
                   $confhash{$itemid}{'mapcrs'} = $mapcrs;
               }
               my @posstypes = &Apache::loncommon::get_env_multiple('form.lti_mapcrstype_'.$idx);
               my @crstypes;
               foreach my $type (sort(@posstypes)) {
                   if ($posscrstype{$type}) {
                       push(@crstypes,$type);
                   }
               }
               $confhash{$itemid}{'mapcrstype'} = \@crstypes;
               if ($env{'form.lti_makecrs_'.$idx}) {
                   $confhash{$itemid}{'makecrs'} = 1;
               }
               my @possenroll = &Apache::loncommon::get_env_multiple('form.lti_selfenroll_'.$idx);
               my @selfenroll;
               foreach my $type (sort(@possenroll)) {
                   if ($posslticrs{$type}) {
                       push(@selfenroll,$type);
                   }
               }
               $confhash{$itemid}{'selfenroll'} = \@selfenroll;
               if ($env{'form.lti_crssec_'.$idx}) {
                   if ($env{'form.lti_crssecsrc_'.$idx} eq 'course_section_sourcedid') {
                       $confhash{$itemid}{'section'} = $env{'form.lti_crssecsrc_'.$idx};
                   } elsif ($env{'form.lti_crssecsrc_'.$idx} eq 'other') {
                       my $section = $env{'form.lti_customsection_'.$idx};
                       $section =~ s/(`)/'/g;
                       $section =~ s/^\s+|\s+$//g;
                       if ($section ne '') {
                           $confhash{$itemid}{'section'} = $section;
                       }
                   }
               }
               foreach my $field ('passback','roster','topmenu','inlinemenu') {
                   if ($env{'form.lti_'.$field.'_'.$idx}) {
                       $confhash{$itemid}{$field} = 1;
                   }
               }
               if ($env{'form.lti_passback_'.$idx}) {
                   if ($env{'form.lti_passbackformat_'.$idx} eq '1.0') {
                       $confhash{$itemid}{'passbackformat'} = '1.0';
                   } else {
                       $confhash{$itemid}{'passbackformat'} = '1.1';
                   }
               }
               if ($env{'form.lti_topmenu_'.$idx} || $env{'form.lti_inlinemenu_'.$idx}) {
                   $confhash{$itemid}{lcmenu} = [];
                   my @possmenu = &Apache::loncommon::get_env_multiple('form.lti_menuitem_'.$idx);
                   foreach my $field (@possmenu) {
                       if (exists($menutitles{$field})) {
                           if ($field eq 'grades') {
                               next unless ($env{'form.lti_inlinemenu_'.$idx});
                           }
                           push(@{$confhash{$itemid}{lcmenu}},$field);
                       }
                   }
               }
               unless (($idx eq 'add') || ($changes{$itemid})) {
                   foreach my $field ('mapuser','mapcrs','makecrs','section','passback','roster','lcauth','lcauthparm','topmenu','inlinemenu') {
                       if ($domconfig{$action}{$itemid}{$field} ne $confhash{$itemid}{$field}) {
                           $changes{$itemid} = 1;
                       }
                   }
                   unless ($changes{$itemid}) {
                       if ($domconfig{$action}{$itemid}{'passback'} eq $confhash{$itemid}{'passback'}) {
                           if ($domconfig{$action}{$itemid}{'passbackformat'} ne $confhash{$itemid}{'passbackformat'}) {
                               $changes{$itemid} = 1;
                           }
                       }
                   }
                   foreach my $field ('makeuser','mapcrstype','selfenroll','instdata','lcmenu') {
                       unless ($changes{$itemid}) {
                           if (ref($domconfig{$action}{$itemid}{$field}) eq 'ARRAY') {
                               if (ref($confhash{$itemid}{$field}) eq 'ARRAY') {
                                   my @diffs = &Apache::loncommon::compare_arrays($domconfig{$action}{$itemid}{$field},
                                                                                  $confhash{$itemid}{$field});
                                   if (@diffs) {
                                       $changes{$itemid} = 1;
                                   }
                               } elsif (@{$domconfig{$action}{$itemid}{$field}} > 0) {
                                   $changes{$itemid} = 1;
                               }
                           } elsif (ref($confhash{$itemid}{$field}) eq 'ARRAY') {
                               if (@{$confhash{$itemid}{$field}} > 0) {
                                   $changes{$itemid} = 1;
                               }
                           }
                       }
                   }
                   unless ($changes{$itemid}) {
                       if (ref($domconfig{$action}{$itemid}{'maproles'}) eq 'HASH') {
                           if (ref($confhash{$itemid}{'maproles'}) eq 'HASH') {
                               foreach my $ltirole (keys(%{$domconfig{$action}{$itemid}{'maproles'}})) {
                                   if ($domconfig{$action}{$itemid}{'maproles'}{$ltirole} ne 
                                       $confhash{$itemid}{'maproles'}{$ltirole}) {
                                       $changes{$itemid} = 1;
                                       last;
                                   }
                               }
                               unless ($changes{$itemid}) {
                                   foreach my $ltirole (keys(%{$confhash{$itemid}{'maproles'}})) {
                                       if ($confhash{$itemid}{'maproles'}{$ltirole} ne 
                                           $domconfig{$action}{$itemid}{'maproles'}{$ltirole}) {
                                           $changes{$itemid} = 1;
                                           last;
                                       }
                                   }
                               }
                           } elsif (keys(%{$domconfig{$action}{$itemid}{'maproles'}}) > 0) {
                               $changes{$itemid} = 1;
                           }
                       } elsif (ref($confhash{$itemid}{'maproles'}) eq 'HASH') {
                           unless ($changes{$itemid}) {
                               if (keys(%{$confhash{$itemid}{'maproles'}}) > 0) {
                                   $changes{$itemid} = 1;
                               }
                           }
                       }
                   }
               }
           }
       }
       if (@allpos > 0) {
           my $idx = 0;
           foreach my $itemid (@allpos) {
               if ($itemid ne '') {
                   $confhash{$itemid}{'order'} = $idx;
                   if (ref($domconfig{$action}) eq 'HASH') {
                       if (ref($domconfig{$action}{$itemid}) eq 'HASH') {
                           if ($domconfig{$action}{$itemid}{'order'} ne $idx) {
                               $changes{$itemid} = 1;
                           }
                       }
                   }
                   $idx ++;
               }
           }
       }
       my %ltihash = (
                             $action => { %confhash }
                          );
       my $putresult = &Apache::lonnet::put_dom('configuration',\%ltihash,
                                                $dom);
       if ($putresult eq 'ok') {
           my %ltienchash = (
                                $action => { %encconfig }
                            );
           &Apache::lonnet::put_dom('encconfig',\%ltienchash,$dom);
           if (keys(%changes) > 0) {
               my $cachetime = 24*60*60;
               my %ltiall = %confhash;
               foreach my $id (keys(%ltiall)) {
                   if (ref($encconfig{$id}) eq 'HASH') {
                       foreach my $item ('key','secret') {
                           $ltiall{$id}{$item} = $encconfig{$id}{$item};
                       }
                   }
               }
               &Apache::lonnet::do_cache_new('lti',$dom,\%ltiall,$cachetime);
               if (ref($lastactref) eq 'HASH') {
                   $lastactref->{'lti'} = 1;
               }
               $resulttext = &mt('Changes made:').'<ul>';
               my %bynum;
               foreach my $itemid (sort(keys(%changes))) {
                   my $position = $confhash{$itemid}{'order'};
                   $bynum{$position} = $itemid;
               }
               foreach my $pos (sort { $a <=> $b } keys(%bynum)) {
                   my $itemid = $bynum{$pos};
                   if (ref($confhash{$itemid}) ne 'HASH') {
                       $resulttext .= '<li>'.&mt('Deleted: [_1]',$changes{$itemid}).'</li>';
                   } else {
                       $resulttext .= '<li><b>'.$confhash{$itemid}{'consumer'}.'</b></li><ul>';
                       my $position = $pos + 1;
                       $resulttext .= '<li>'.&mt('Order: [_1]',$position).'</li>';
                       foreach my $item ('version','lifetime') {
                           if ($confhash{$itemid}{$item} ne '') {
                               $resulttext .= '<li>'.$lt{$item}.':&nbsp;'.$confhash{$itemid}{$item}.'</li>';
                           }
                       }
                       if ($encconfig{$itemid}{'key'} ne '') {
                           $resulttext .= '<li>'.$lt{'key'}.':&nbsp;'.$encconfig{$itemid}{'key'}.'</li>';
                       }
                       if ($encconfig{$itemid}{'secret'} ne '') {
                           $resulttext .= '<li>'.$lt{'secret'}.':&nbsp;';
                           my $num = length($encconfig{$itemid}{'secret'});
                           $resulttext .= ('*'x$num).'</li>';
                       }
                       if ($confhash{$itemid}{'requser'}) {
                           if ($confhash{$itemid}{'mapuser'}) {
                               my $shownmapuser;
                               if ($confhash{$itemid}{'mapuser'} eq 'lis_person_sourcedid') {
                                   $shownmapuser = $lt{'sourcedid'}.' (lis_person_sourcedid)';
                               } elsif ($confhash{$itemid}{'mapuser'} eq 'lis_person_contact_email_primary') {
                                   $shownmapuser = $lt{'email'}.' (lis_person_contact_email_primary)';
                               } else {
                                   $shownmapuser = &mt('Other').' ('.$confhash{$itemid}{'mapuser'}.')';
                               }
                               $resulttext .= '<li>'.&mt('LON-CAPA username').': '.$shownmapuser.'</li>';
                           }
                           if (ref($confhash{$itemid}{'maproles'}) eq 'HASH') {
                               my $rolemaps;
                               foreach my $role (@ltiroles) {
                                   if ($confhash{$itemid}{'maproles'}{$role}) {
                                       $rolemaps .= ('&nbsp;'x2).$role.'='.
                                                    &Apache::lonnet::plaintext($confhash{$itemid}{'maproles'}{$role},
                                                                               'Course').',';
                                   }
                               }
                               if ($rolemaps) {
                                   $rolemaps =~ s/,$//;
                                   $resulttext .= '<li>'.&mt('Role mapping:').$rolemaps.'</li>';
                               }
                           }
                           if (ref($confhash{$itemid}{'makeuser'}) eq 'ARRAY') {
                               if (@{$confhash{$itemid}{'makeuser'}} > 0) { 
                                   $resulttext .= '<li>'.&mt('Following roles may create user accounts: [_1]',
                                                             join(', ',@{$confhash{$itemid}{'makeuser'}})).'<br />';
                                   if ($confhash{$itemid}{'lcauth'} eq 'lti') {
                                       $resulttext .= &mt('New users will only be able to authenticate via LTI').'</li>';
                                   } else {
                                       $resulttext .= &mt('New users will be assigned LON-CAPA authentication: [_1]',
                                                          $confhash{$itemid}{'lcauth'});
                                       if ($confhash{$itemid}{'lcauth'} eq 'internal') {
                                           $resulttext .= '; '.&mt('a randomly generated password will be created');
                                       } elsif ($confhash{$itemid}{'lcauth'} eq 'localauth') {
                                           if ($confhash{$itemid}{'lcauthparm'} ne '') {
                                               $resulttext .= ' '.&mt('with argument: [_1]',$confhash{$itemid}{'lcauthparm'});
                                           }
                                       } else {
                                           $resulttext .= '; '.&mt('Kerberos domain: [_1]',$confhash{$itemid}{'lcauthparm'});
                                       }
                                   }
                                   $resulttext .= '</li>';
                               } else {
                                   $resulttext .= '<li>'.&mt('User account creation not permitted.').'</li>';
                               }
                           }
                           if (ref($confhash{$itemid}{'instdata'}) eq 'ARRAY') {
                               if (@{$confhash{$itemid}{'instdata'}} > 0) {
                                   $resulttext .= '<li>'.&mt('Institutional data will be used when creating a new user for: [_1]',
                                                             join(', ',map { $fieldtitles{$_}; } @{$confhash{$itemid}{'instdata'}})).'</li>';
                               } else {
                                   $resulttext .= '<li>'.&mt('No institutional data used when creating a new user.').'</li>';
                               }
                           }
                           if ($confhash{$itemid}{'mapcrs'}) {
                               $resulttext .= '<li>'.&mt('Unique course identifier').': '.$confhash{$itemid}{'mapcrs'}.'</li>';
                           }
                           if (ref($confhash{$itemid}{'mapcrstype'}) eq 'ARRAY') {
                               if (@{$confhash{$itemid}{'mapcrstype'}} > 0) {
                                   $resulttext .= '<li>'.&mt('Mapping for the following LON-CAPA course types: [_1]',
                                                  join(', ',map { $coursetypetitles{$_}; } @coursetypes)).
                                                  '</li>';
                               } else {
                                   $resulttext .= '<li>'.&mt('No mapping to LON-CAPA courses').'</li>';
                               }
                           }
                           if ($confhash{$itemid}{'makecrs'}) {
                               $resulttext .= '<li>'.&mt('Instructor may create course (if absent).').'</li>';
                           } else {
                               $resulttext .= '<li>'.&mt('Instructor may not create course (if absent).').'</li>';
                           }
                           if (ref($confhash{$itemid}{'selfenroll'}) eq 'ARRAY') {
                               if (@{$confhash{$itemid}{'selfenroll'}} > 0) {
                                   $resulttext .= '<li>'.&mt('Self-enrollment for following roles: [_1]',
                                                             join(', ',@{$confhash{$itemid}{'selfenroll'}})).
                                                  '</li>';
                               } else {
                                   $resulttext .= '<li>'.&mt('Self-enrollment not permitted').'</li>';
                               }
                           }
                           if ($confhash{$itemid}{'section'}) {
                               if ($confhash{$itemid}{'section'} eq 'course_section_sourcedid') {
                                   $resulttext .= '<li>'.&mt('User section from standard field:').
                                                        ' (course_section_sourcedid)'.'</li>';  
                               } else {
                                   $resulttext .= '<li>'.&mt('User section from:').' '.
                                                         $confhash{$itemid}{'section'}.'</li>';
                               }
                           } else {
                               $resulttext .= '<li>'.&mt('No section assignment').'</li>';
                           }
                           foreach my $item ('passback','roster','topmenu','inlinemenu') {
                               $resulttext .= '<li>'.$lt{$item}.':&nbsp;';
                               if ($confhash{$itemid}{$item}) {
                                   $resulttext .= &mt('Yes');
                                   if ($item eq 'passback') {
                                       if ($confhash{$itemid}{'passbackformat'} eq '1.0') {
                                           $resulttext .= '&nbsp;('.&mt('Outcomes Extension (1.0)').')';
                                       } elsif ($confhash{$itemid}{'passbackformat'} eq '1.1') {
                                           $resulttext .= '&nbsp;('.&mt('Outcomes Service (1.1)').')';
                                       }
                                   }
                               } else {
                                   $resulttext .= &mt('No');
                               }
                               $resulttext .= '</li>';
                           }
                           if (ref($confhash{$itemid}{'lcmenu'}) eq 'ARRAY') {
                               if (@{$confhash{$itemid}{'lcmenu'}} > 0) {
                                   $resulttext .= '<li>'.&mt('Menu items:').' '.
                                                  join(', ', map { $menutitles{$_}; } (@{$confhash{$itemid}{'lcmenu'}})).'</li>'; 
                               } else {
                                   $resulttext .= '<li>'.&mt('No menu items displayed in header or online menu').'</li>'; 
                               }
                           }
                       }
                       $resulttext .= '</ul></li>';
                   }
               }
               $resulttext .= '</ul>';
           } else {
               $resulttext = &mt('No changes made.');
           }
       } else {
           $errors .= '<li><span class="LC_error">'.&mt('Failed to save changes').'</span></li>';
       }
       if ($errors) {
           $resulttext .= &mt('The following errors occurred: ').'<ul>'.
                          $errors.'</ul>';
       }
       return $resulttext;
   }
   
   sub get_lti_id {
       my ($domain,$consumer) = @_;
       # get lock on lti db
       my $lockhash = {
                         lock => $env{'user.name'}.
                                 ':'.$env{'user.domain'},
                      };
       my $tries = 0;
       my $gotlock = &Apache::lonnet::newput_dom('lti',$lockhash,$domain);
       my ($id,$error);
   
       while (($gotlock ne 'ok') && ($tries<10)) {
           $tries ++;
           sleep (0.1);
           $gotlock = &Apache::lonnet::newput_dom('lti',$lockhash,$domain);
       }
       if ($gotlock eq 'ok') {
           my %currids = &Apache::lonnet::dump_dom('lti',$domain);
           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;
               }
               if ($id) {
                   unless (&Apache::lonnet::newput_dom('lti',{ $id => $consumer },$domain) eq 'ok') {
                       $error = 'nostore';
                   }
               } else {
                   $error = 'nonumber';
               }
           }
           my $dellockoutcome = &Apache::lonnet::del_dom('lti',['lock'],$domain);
       } else {
           $error = 'nolock';
       }
       return ($id,$error);
   }
   
 sub modify_autoenroll {  sub modify_autoenroll {
     my ($dom,$lastactref,%domconfig) = @_;      my ($dom,$lastactref,%domconfig) = @_;
     my ($resulttext,%changes);      my ($resulttext,%changes);
Line 9875  sub modify_autoenroll { Line 12355  sub modify_autoenroll {
             }              }
             if ($changes{'autofailsafe'}) {              if ($changes{'autofailsafe'}) {
                 if ($failsafe ne '') {                  if ($failsafe ne '') {
                     $resulttext .= '<li>'.&mt("$title{'failsafe'} set to [_1]",$failsafe).'</li>';                      $resulttext .= '<li>'.&mt('Failsafe for no drops if institutional data missing for a section set to: [_1]',$failsafe).'</li>';
                 } else {                  } else {
                     $resulttext .= '<li>'.&mt("$title{'failsafe'} deleted");                      $resulttext .= '<li>'.&mt('Failsafe for no drops if institutional data missing for a section: deleted');
                 }                  }
                 &Apache::lonnet::get_domain_defaults($dom,1);                  &Apache::lonnet::get_domain_defaults($dom,1);
                 if (ref($lastactref) eq 'HASH') {                  if (ref($lastactref) eq 'HASH') {
Line 10156  sub modify_autocreate { Line 12636  sub modify_autocreate {
 }  }
   
 sub modify_directorysrch {  sub modify_directorysrch {
     my ($dom,%domconfig) = @_;      my ($dom,$lastactref,%domconfig) = @_;
     my ($resulttext,%changes);      my ($resulttext,%changes);
     my %currdirsrch;      my %currdirsrch;
     if (ref($domconfig{'directorysrch'}) eq 'HASH') {      if (ref($domconfig{'directorysrch'}) eq 'HASH') {
Line 10167  sub modify_directorysrch { Line 12647  sub modify_directorysrch {
     my %title = ( available => 'Institutional directory search available',      my %title = ( available => 'Institutional directory search available',
                   localonly => 'Other domains can search institution',                    localonly => 'Other domains can search institution',
                   lcavailable => 'LON-CAPA directory search available',                    lcavailable => 'LON-CAPA directory search available',
                   lclocalonly => 'Other domains can search LON-CAPA domain',                     lclocalonly => 'Other domains can search LON-CAPA domain',
                   searchby => 'Search types',                    searchby => 'Search types',
                   searchtypes => 'Search latitude');                    searchtypes => 'Search latitude');
     my @offon = ('off','on');      my @offon = ('off','on');
Line 10261  sub modify_directorysrch { Line 12741  sub modify_directorysrch {
             }              }
         }          }
         if (exists($currdirsrch{'lcavailable'})) {          if (exists($currdirsrch{'lcavailable'})) {
              if ($currdirsrch{'lcavailable'} ne $env{'form.dirsrch_domavailable'}) {              if ($currdirsrch{'lcavailable'} ne $env{'form.dirsrch_domavailable'}) {
                  $changes{'lcavailable'} = 1;                  $changes{'lcavailable'} = 1;
              }              }
         } else {          } else {
             if ($env{'form.dirsrch_lcavailable'} eq '1') {              if ($env{'form.dirsrch_lcavailable'} eq '1') {
                 $changes{'lcavailable'} = 1;                  $changes{'lcavailable'} = 1;
             }              }
         }          }
         if (exists($currdirsrch{'localonly'})) {          if (exists($currdirsrch{'localonly'})) {
              if ($currdirsrch{'localonly'} ne $env{'form.dirsrch_instlocalonly'}) {              if ($currdirsrch{'localonly'} ne $env{'form.dirsrch_instlocalonly'}) {
                  $changes{'localonly'} = 1;                  $changes{'localonly'} = 1;
              }              }
         } else {          } else {
             if ($env{'form.dirsrch_instlocalonly'} eq '1') {              if ($env{'form.dirsrch_instlocalonly'} eq '1') {
                 $changes{'localonly'} = 1;                  $changes{'localonly'} = 1;
             }              }
         }          }
         if (exists($currdirsrch{'lclocalonly'})) {          if (exists($currdirsrch{'lclocalonly'})) {
              if ($currdirsrch{'lclocalonly'} ne $env{'form.dirsrch_domlocalonly'}) {              if ($currdirsrch{'lclocalonly'} ne $env{'form.dirsrch_domlocalonly'}) {
                  $changes{'lclocalonly'} = 1;                  $changes{'lclocalonly'} = 1;
              }              }
         } else {          } else {
             if ($env{'form.dirsrch_domlocalonly'} eq '1') {              if ($env{'form.dirsrch_domlocalonly'} eq '1') {
                 $changes{'lclocalonly'} = 1;                  $changes{'lclocalonly'} = 1;
Line 10300  sub modify_directorysrch { Line 12780  sub modify_directorysrch {
             }              }
             if ($changes{'lclocalonly'}) {              if ($changes{'lclocalonly'}) {
                 $resulttext .= '<li>'.&mt("$title{'lclocalonly'} set to: $otherdoms[$env{'form.dirsrch_domlocalonly'}]").'</li>';                  $resulttext .= '<li>'.&mt("$title{'lclocalonly'} set to: $otherdoms[$env{'form.dirsrch_domlocalonly'}]").'</li>';
             }                 }
             if (ref($changes{'cansearch'}) eq 'ARRAY') {              if (ref($changes{'cansearch'}) eq 'ARRAY') {
                 my $chgtext;                  my $chgtext;
                 if (ref($usertypes) eq 'HASH') {                  if (ref($usertypes) eq 'HASH') {
Line 10350  sub modify_directorysrch { Line 12830  sub modify_directorysrch {
                 $resulttext .= '<li>'.&mt($title{'searchtypes'}.' set to: "[_1]"',$chgtext).'</li>';                  $resulttext .= '<li>'.&mt($title{'searchtypes'}.' set to: "[_1]"',$chgtext).'</li>';
             }              }
             $resulttext .= '</ul>';              $resulttext .= '</ul>';
               &Apache::lonnet::do_cache_new('directorysrch',$dom,$dirsrch_hash{'directorysrch'},3600);
               if (ref($lastactref) eq 'HASH') {
                   $lastactref->{'directorysrch'} = 1;
               }
         } else {          } else {
             $resulttext = &mt('No changes made to directory search settings');              $resulttext = &mt('No changes made to directory search settings');
         }          }
Line 10372  sub modify_contacts { Line 12856  sub modify_contacts {
     my @contacts = ('supportemail','adminemail');      my @contacts = ('supportemail','adminemail');
     my @mailings = ('errormail','packagesmail','helpdeskmail','otherdomsmail',      my @mailings = ('errormail','packagesmail','helpdeskmail','otherdomsmail',
                     'lonstatusmail','requestsmail','updatesmail','idconflictsmail');                      'lonstatusmail','requestsmail','updatesmail','idconflictsmail');
     my @toggles = ('reporterrors','reportupdates');      my @toggles = ('reporterrors','reportupdates','reportstatus');
       my @lonstatus = ('threshold','sysmail','weights','excluded');
     my ($fields,$fieldtitles,$fieldoptions,$possoptions) = &helpform_fields();      my ($fields,$fieldtitles,$fieldoptions,$possoptions) = &helpform_fields();
     foreach my $type (@mailings) {      foreach my $type (@mailings) {
         @{$newsetting{$type}} =           @{$newsetting{$type}} = 
Line 10383  sub modify_contacts { Line 12868  sub modify_contacts {
             } else {              } else {
                 $contacts_hash{contacts}{$type}{$item} = 0;                  $contacts_hash{contacts}{$type}{$item} = 0;
             }              }
         }            }
         $others{$type} = $env{'form.'.$type.'_others'};          $others{$type} = $env{'form.'.$type.'_others'};
         $contacts_hash{contacts}{$type}{'others'} = $others{$type};          $contacts_hash{contacts}{$type}{'others'} = $others{$type};
         if (($type eq 'helpdeskmail') || ($type eq 'otherdomsmail')) {          if (($type eq 'helpdeskmail') || ($type eq 'otherdomsmail')) {
Line 10405  sub modify_contacts { Line 12890  sub modify_contacts {
             $contacts_hash{'contacts'}{$item} = $env{'form.'.$item};              $contacts_hash{'contacts'}{$item} = $env{'form.'.$item};
         }          }
     }      }
       my ($lonstatus_defs,$lonstatus_names) = &Apache::loncommon::lon_status_items();
       foreach my $item (@lonstatus) {
           if ($item eq 'excluded') {
               my (%serverhomes,@excluded);
               map { $serverhomes{$_} = 1; } values(%Apache::lonnet::serverhomeIDs);
               my @possexcluded = &Apache::loncommon::get_env_multiple('form.errorexcluded');
               if (@possexcluded) {
                   foreach my $id (sort(@possexcluded)) {
                       if ($serverhomes{$id}) {
                           push(@excluded,$id);
                       }
                   }
               }
               if (@excluded) {
                   $contacts_hash{'contacts'}{'lonstatus'}{$item} = \@excluded;
               }
           } elsif ($item eq 'weights') {
               foreach my $type ('E','W','N') {
                   $env{'form.error'.$item.'_'.$type} =~ s/^\s+|\s+$//g;
                   if ($env{'form.error'.$item.'_'.$type} =~ /^\d+$/) {
                       unless ($env{'form.error'.$item.'_'.$type} == $lonstatus_defs->{$type}) {
                           $contacts_hash{'contacts'}{'lonstatus'}{$item}{$type} =
                               $env{'form.error'.$item.'_'.$type};
                       }
                   }
               }
           } elsif (($item eq 'threshold') || ($item eq 'sysmail')) {
               $env{'form.error'.$item} =~ s/^\s+|\s+$//g;
               if ($env{'form.error'.$item} =~ /^\d+$/) {
                   unless ($env{'form.error'.$item} == $lonstatus_defs->{$item}) {
                       $contacts_hash{'contacts'}{'lonstatus'}{$item} = $env{'form.error'.$item};
                   }
               }
           }
       }
     if ((ref($fields) eq 'ARRAY') && (ref($possoptions) eq 'HASH')) {      if ((ref($fields) eq 'ARRAY') && (ref($possoptions) eq 'HASH')) {
         foreach my $field (@{$fields}) {          foreach my $field (@{$fields}) {
             if (ref($possoptions->{$field}) eq 'ARRAY') {              if (ref($possoptions->{$field}) eq 'ARRAY') {
                 my $value = $env{'form.helpform_'.$field};                  my $value = $env{'form.helpform_'.$field};
                 $value =~ s/^\s+|\s+$//g;                  $value =~ s/^\s+|\s+$//g;
                 if (grep(/^\Q$value\E$/,@{$possoptions->{$field}})) {                  if (grep(/^\Q$value\E$/,@{$possoptions->{$field}})) {
                     $contacts_hash{contacts}{'helpform'}{$field} = $value;                      $contacts_hash{'contacts'}{'helpform'}{$field} = $value;
                     if ($field eq 'screenshot') {                      if ($field eq 'screenshot') {
                         $env{'form.helpform_maxsize'} =~ s/^\s+|\s+$//g;                          $env{'form.helpform_maxsize'} =~ s/^\s+|\s+$//g;
                         if ($env{'form.helpform_maxsize'} =~ /^\d+\.?\d*$/) {                          if ($env{'form.helpform_maxsize'} =~ /^\d+\.?\d*$/) {
                             $contacts_hash{contacts}{'helpform'}{'maxsize'} = $env{'form.helpform_maxsize'};                              $contacts_hash{'contacts'}{'helpform'}{'maxsize'} = $env{'form.helpform_maxsize'};
                         }                          }
                     }                      }
                 }                  }
             }              }
         }          }
     }      }
       my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom);
       my (@statuses,%usertypeshash,@overrides);
       if ((ref($types) eq 'ARRAY') && (@{$types} > 0)) {
           @statuses = @{$types};
           if (ref($usertypes) eq 'HASH') {
               %usertypeshash = %{$usertypes};
           }
       }
       if (@statuses) {
           my @possoverrides = &Apache::loncommon::get_env_multiple('form.overrides');
           foreach my $type (@possoverrides) {
               if (($type ne '') && (grep(/^\Q$type\E$/,@statuses))) {
                   push(@overrides,$type);
               }
           }
           if (@overrides) {
               foreach my $type (@overrides) {
                   my @standard = &Apache::loncommon::get_env_multiple('form.override_'.$type);
                   foreach my $item (@contacts) {
                       if (grep(/^\Q$item\E$/,@standard)) {
                           $contacts_hash{'contacts'}{'overrides'}{$type}{$item} = 1;
                           $newsetting{'override_'.$type}{$item} = 1;
                       } else {
                           $contacts_hash{'contacts'}{'overrides'}{$type}{$item} = 0;
                           $newsetting{'override_'.$type}{$item} = 0;
                       }
                   }
                   $contacts_hash{'contacts'}{'overrides'}{$type}{'others'} = $env{'form.override_'.$type.'_others'};
                   $contacts_hash{'contacts'}{'overrides'}{$type}{'bcc'} = $env{'form.override_'.$type.'_bcc'};
                   $newsetting{'override_'.$type}{'others'} = $env{'form.override_'.$type.'_others'};
                   $newsetting{'override_'.$type}{'bcc'} = $env{'form.override_'.$type.'_bcc'};
                   if (($env{'form.override_'.$type.'_includestr'} ne '') && ($env{'form.override_'.$type.'_includeloc'} =~ /^s|b$/)) {
                       $includestr{$type} = $env{'form.override_'.$type.'_includestr'};
                       $includeloc{$type} = $env{'form.override_'.$type.'_includeloc'};
                       $contacts_hash{'contacts'}{'overrides'}{$type}{'include'} = $includeloc{$type}.':'.&escape($includestr{$type});
                       $newsetting{'override_'.$type}{'include'} = $contacts_hash{'contacts'}{'overrides'}{$type}{'include'};
                   }
               }     
           }
       }
     if (keys(%currsetting) > 0) {      if (keys(%currsetting) > 0) {
         foreach my $item (@contacts) {          foreach my $item (@contacts) {
             if ($to{$item} ne $currsetting{$item}) {              if ($to{$item} ne $currsetting{$item}) {
Line 10441  sub modify_contacts { Line 13001  sub modify_contacts {
             if ($others{$type} ne $currsetting{$type}{'others'}) {              if ($others{$type} ne $currsetting{$type}{'others'}) {
                 push(@{$changes{$type}},'others');                  push(@{$changes{$type}},'others');
             }              }
             if (($type eq 'helpdeskmail') || ($type eq 'otherdomsmail')) {                 if (($type eq 'helpdeskmail') || ($type eq 'otherdomsmail')) {
                 if ($bcc{$type} ne $currsetting{$type}{'bcc'}) {                  if ($bcc{$type} ne $currsetting{$type}{'bcc'}) {
                     push(@{$changes{$type}},'bcc');                       push(@{$changes{$type}},'bcc'); 
                 }                  }
Line 10476  sub modify_contacts { Line 13036  sub modify_contacts {
                 }                  }
             }              }
         }          }
           if (@statuses) {
               if (ref($currsetting{'overrides'}) eq 'HASH') { 
                   foreach my $key (keys(%{$currsetting{'overrides'}})) {
                       if (ref($currsetting{'overrides'}{$key}) eq 'HASH') {
                           if (ref($newsetting{'override_'.$key}) eq 'HASH') {
                               foreach my $item (@contacts,'bcc','others','include') {
                                   if ($currsetting{'overrides'}{$key}{$item} ne $newsetting{'override_'.$key}{$item}) { 
                                       push(@{$changes{'overrides'}},$key);
                                       last;
                                   }
                               }
                           } else {
                               push(@{$changes{'overrides'}},$key);
                           }
                       }
                   }
                   foreach my $key (@overrides) {
                       unless (exists($currsetting{'overrides'}{$key})) {
                           push(@{$changes{'overrides'}},$key);
                       }
                   }
               } else {
                   foreach my $key (@overrides) {
                       push(@{$changes{'overrides'}},$key); 
                   }
               }
           }
           if (ref($currsetting{'lonstatus'}) eq 'HASH') {
               foreach my $key ('excluded','weights','threshold','sysmail') {
                   if ($key eq 'excluded') {
                       if ((ref($contacts_hash{contacts}{lonstatus}) eq 'HASH') &&
                           (ref($contacts_hash{contacts}{lonstatus}{excluded}) eq 'ARRAY')) {
                           if ((ref($currsetting{'lonstatus'}{$key}) eq 'ARRAY') &&
                               (@{$currsetting{'lonstatus'}{$key}})) {
                               my @diffs =
                                   &Apache::loncommon::compare_arrays($contacts_hash{contacts}{lonstatus}{excluded},
                                                                      $currsetting{'lonstatus'}{$key});
                               if (@diffs) {
                                   push(@{$changes{'lonstatus'}},$key);
                               }
                           } elsif (@{$contacts_hash{contacts}{lonstatus}{excluded}}) {
                               push(@{$changes{'lonstatus'}},$key);
                           }
                       } elsif ((ref($currsetting{'lonstatus'}{$key}) eq 'ARRAY') &&
                                (@{$currsetting{'lonstatus'}{$key}})) {
                           push(@{$changes{'lonstatus'}},$key);
                       }
                   } elsif ($key eq 'weights') {
                       if ((ref($contacts_hash{contacts}{lonstatus}) eq 'HASH') &&
                           (ref($contacts_hash{contacts}{lonstatus}{$key}) eq 'HASH')) {
                           if (ref($currsetting{'lonstatus'}{$key}) eq 'HASH') {
                               foreach my $type ('E','W','N','U') {
                                   unless ($contacts_hash{contacts}{lonstatus}{$key}{$type} eq
                                           $currsetting{'lonstatus'}{$key}{$type}) {
                                       push(@{$changes{'lonstatus'}},$key);
                                       last;
                                   }
                               }
                           } else {
                               foreach my $type ('E','W','N','U') {
                                   if ($contacts_hash{contacts}{lonstatus}{$key}{$type} ne '') {
                                       push(@{$changes{'lonstatus'}},$key);
                                       last;
                                   }
                               }
                           }
                       } elsif (ref($currsetting{'lonstatus'}{$key}) eq 'HASH') {
                           foreach my $type ('E','W','N','U') {
                               if ($currsetting{'lonstatus'}{$key}{$type} ne '') {
                                   push(@{$changes{'lonstatus'}},$key);
                                   last;
                               }
                           }
                       }
                   } elsif (($key eq 'threshold') || ($key eq 'sysmail')) {
                       if (ref($contacts_hash{contacts}{lonstatus}) eq 'HASH') {
                           if ($currsetting{'lonstatus'}{$key} =~ /^\d+$/) {
                               if ($currsetting{'lonstatus'}{$key} != $contacts_hash{contacts}{lonstatus}{$key}) {
                                   push(@{$changes{'lonstatus'}},$key);
                               }
                           } elsif ($contacts_hash{contacts}{lonstatus}{$key} =~ /^\d+$/) {
                               push(@{$changes{'lonstatus'}},$key);
                           }
                       } elsif ($currsetting{'lonstatus'}{$key} =~ /^\d+$/) {
                           push(@{$changes{'lonstatus'}},$key);
                       }
                   }
               }
           } else {
               if (ref($contacts_hash{contacts}{lonstatus}) eq 'HASH') {
                   foreach my $key ('excluded','weights','threshold','sysmail') {
                       if (exists($contacts_hash{contacts}{lonstatus}{$key})) {
                           push(@{$changes{'lonstatus'}},$key);
                       }
                   }
               }
           }
     } else {      } else {
         my %default;          my %default;
         $default{'supportemail'} = $Apache::lonnet::perlvar{'lonSupportEMail'};          $default{'supportemail'} = $Apache::lonnet::perlvar{'lonSupportEMail'};
Line 10519  sub modify_contacts { Line 13176  sub modify_contacts {
                     }                      }
                 }                  }
             }              }
         }             }
           if (ref($contacts_hash{contacts}{lonstatus}) eq 'HASH') {
               foreach my $key ('excluded','weights','threshold','sysmail') {
                   if (exists($contacts_hash{contacts}{lonstatus}{$key})) {
                       push(@{$changes{'lonstatus'}},$key);
                   }
               }
           }
     }      }
     foreach my $item (@toggles) {      foreach my $item (@toggles) {
         if (($env{'form.'.$item} == 1) && ($currsetting{$item} == 0)) {          if (($env{'form.'.$item} == 1) && ($currsetting{$item} == 0)) {
Line 10550  sub modify_contacts { Line 13214  sub modify_contacts {
             foreach my $type (@mailings) {              foreach my $type (@mailings) {
                 if (ref($changes{$type}) eq 'ARRAY') {                  if (ref($changes{$type}) eq 'ARRAY') {
                     if (($type eq 'helpdeskmail') || ($type eq 'otherdomsmail')) {                      if (($type eq 'helpdeskmail') || ($type eq 'otherdomsmail')) {
                         $resulttext .= '<li>'.$titles->{$type}.' -- '.&mt('sent to').': ';                           $resulttext .= '<li>'.$titles->{$type}.' -- '.&mt('sent to').': ';
                     } else {                      } else {
                         $resulttext .= '<li>'.$titles->{$type}.': ';                          $resulttext .= '<li>'.$titles->{$type}.': ';
                     }                      }
Line 10569  sub modify_contacts { Line 13233  sub modify_contacts {
                         if ($bcc{$type} ne '') {                          if ($bcc{$type} ne '') {
                             my $bcctext;                              my $bcctext;
                             if (@text) {                              if (@text) {
                                 $bcctext = '&nbsp;'.&mt('with Bcc to');                                   $bcctext = '&nbsp;'.&mt('with Bcc to');
                             } else {                              } else {
                                 $bcctext = '(Bcc)';                                  $bcctext = '(Bcc)';
                             }                              }
Line 10577  sub modify_contacts { Line 13241  sub modify_contacts {
                         } elsif (!@text) {                          } elsif (!@text) {
                             $resulttext .= &mt('No one');                              $resulttext .= &mt('No one');
                         }                             }   
                         if ($includestr{$type} ne '') {                           if ($includestr{$type} ne '') {
                             if ($includeloc{$type} eq 'b') {                              if ($includeloc{$type} eq 'b') {
                                 $resulttext .= '<br />'.&mt('Text automatically added to e-mail body:').' '.$includestr{$type};                                  $resulttext .= '<br />'.&mt('Text automatically added to e-mail body:').' '.$includestr{$type};
                             } elsif ($includeloc{$type} eq 's') {                              } elsif ($includeloc{$type} eq 's') {
Line 10590  sub modify_contacts { Line 13254  sub modify_contacts {
                     $resulttext .= '</li>';                      $resulttext .= '</li>';
                 }                  }
             }              }
               if (ref($changes{'overrides'}) eq 'ARRAY') {
                   my @deletions;
                   foreach my $type (@{$changes{'overrides'}}) {
                       if ($usertypeshash{$type}) {
                           if (grep(/^\Q$type\E/,@overrides)) {
                               $resulttext .= '<li>'.&mt("Overrides based on requester's affiliation set for [_1]",
                                                         $usertypeshash{$type}).'<ul><li>';
                               if (ref($newsetting{'override_'.$type}) eq 'HASH') {
                                   my @text;
                                   foreach my $item (@contacts) {
                                       if ($newsetting{'override_'.$type}{$item}) { 
                                           push(@text,$short_titles->{$item});
                                       }
                                   }
                                   if ($newsetting{'override_'.$type}{'others'} ne '') {
                                       push(@text,$newsetting{'override_'.$type}{'others'});
                                   }
     
                                   if (@text) {
                                       $resulttext .= &mt('Helpdesk e-mail sent to: [_1]',
                                                          '<span class="LC_cusr_emph">'.join(', ',@text).'</span>');
                                   }
                                   if ($newsetting{'override_'.$type}{'bcc'} ne '') {
                                       my $bcctext;
                                       if (@text) {
                                           $bcctext = '&nbsp;'.&mt('with Bcc to');
                                       } else {
                                           $bcctext = '(Bcc)';
                                       }
                                       $resulttext .= $bcctext.': <span class="LC_cusr_emph">'.$newsetting{'override_'.$type}{'bcc'}.'</span>';
                                   } elsif (!@text) {
                                        $resulttext .= &mt('Helpdesk e-mail sent to no one');
                                   }
                                   $resulttext .= '</li>';
                                   if ($newsetting{'override_'.$type}{'include'} ne '') {
                                       my ($loc,$str) = split(/:/,$newsetting{'override_'.$type}{'include'});
                                       if ($loc eq 'b') {
                                           $resulttext .= '<li>'.&mt('Text automatically added to e-mail body:').' '.&unescape($str).'</li>';
                                       } elsif ($loc eq 's') {
                                           $resulttext .= '<li>'.&mt('Text automatically added to e-mail subject:').' '.&unescape($str).'</li>';
                                       }
                                   }
                               }
                               $resulttext .= '</li></ul></li>';
                           } else {
                               push(@deletions,$usertypeshash{$type});
                           }
                       }
                   }
                   if (@deletions) {
                       $resulttext .= '<li>'.&mt("Overrides based on requester's affiliation discontinued for: [_1]",
                                                 join(', ',@deletions)).'</li>';
                   }
               }
             my @offon = ('off','on');              my @offon = ('off','on');
               my $corelink = &core_link_msu();
             if ($changes{'reporterrors'}) {              if ($changes{'reporterrors'}) {
                 $resulttext .= '<li>'.                  $resulttext .= '<li>'.
                                &mt('E-mail error reports to [_1] set to "'.                                 &mt('E-mail error reports to [_1] set to "'.
                                    $offon[$env{'form.reporterrors'}].'".',                                     $offon[$env{'form.reporterrors'}].'".',
                                    &Apache::loncommon::modal_link('http://loncapa.org/core.html',                                     $corelink).
                                        &mt('LON-CAPA core group - MSU'),600,500)).  
                                '</li>';                                 '</li>';
             }              }
             if ($changes{'reportupdates'}) {              if ($changes{'reportupdates'}) {
                 $resulttext .= '<li>'.                  $resulttext .= '<li>'.
                                 &mt('E-mail record of completed LON-CAPA updates to [_1] set to "'.                                  &mt('E-mail record of completed LON-CAPA updates to [_1] set to "'.
                                     $offon[$env{'form.reportupdates'}].'".',                                      $offon[$env{'form.reportupdates'}].'".',
                                     &Apache::loncommon::modal_link('http://loncapa.org/core.html',                                      $corelink).
                                         &mt('LON-CAPA core group - MSU'),600,500)).                                  '</li>';
               }
               if ($changes{'reportstatus'}) {
                   $resulttext .= '<li>'.
                                   &mt('E-mail status if errors above threshold to [_1] set to "'.
                                       $offon[$env{'form.reportstatus'}].'".',
                                       $corelink).
                                 '</li>';                                  '</li>';
             }              }
               if (ref($changes{'lonstatus'}) eq 'ARRAY') {
                   $resulttext .= '<li>'.
                                  &mt('Nightly status check e-mail settings').':<ul>';
                   my (%defval,%use_def,%shown);
                   $defval{'threshold'} = $lonstatus_defs->{'threshold'};
                   $defval{'sysmail'} = $lonstatus_defs->{'sysmail'};
                   $defval{'weights'} =
                       join(', ',map { $lonstatus_names->{$_}.'='.$lonstatus_defs->{$_}; } ('E','W','N','U'));
                   $defval{'excluded'} = &mt('None');
                   if (ref($contacts_hash{'contacts'}{'lonstatus'}) eq 'HASH') {
                       foreach my $item ('threshold','sysmail','weights','excluded') {
                           if (exists($contacts_hash{'contacts'}{'lonstatus'}{$item})) {
                               if (($item eq 'threshold') || ($item eq 'sysmail')) {
                                   $shown{$item} = $contacts_hash{'contacts'}{'lonstatus'}{$item};
                               } elsif ($item eq 'weights') {
                                   if (ref($contacts_hash{'contacts'}{'lonstatus'}{$item}) eq 'HASH') {
                                       foreach my $type ('E','W','N','U') {
                                           $shown{$item} .= $lonstatus_names->{$type}.'=';
                                           if (exists($contacts_hash{'contacts'}{'lonstatus'}{$item}{$type})) {
                                               $shown{$item} .= $contacts_hash{'contacts'}{'lonstatus'}{$item}{$type};
                                           } else {
                                               $shown{$item} .= $lonstatus_defs->{$type};
                                           }
                                           $shown{$item} .= ', ';
                                       }
                                       $shown{$item} =~ s/, $//;
                                   } else {
                                       $shown{$item} = $defval{$item};
                                   }
                               } elsif ($item eq 'excluded') {
                                   if (ref($contacts_hash{'contacts'}{'lonstatus'}{$item}) eq 'ARRAY') {
                                       $shown{$item} = join(', ',@{$contacts_hash{'contacts'}{'lonstatus'}{$item}});
                                   } else {
                                       $shown{$item} = $defval{$item};
                                   }
                               }
                           } else {
                               $shown{$item} = $defval{$item};
                           }
                       }
                   } else {
                       foreach my $item ('threshold','weights','excluded','sysmail') {
                           $shown{$item} = $defval{$item};
                       }
                   }
                   foreach my $item ('threshold','weights','excluded','sysmail') {
                       $resulttext .= '<li>'.&mt($titles->{'error'.$item}.' -- [_1]',
                                             $shown{$item}).'</li>';
                   }
                   $resulttext .= '</ul></li>';
               }
             if ((ref($changes{'helpform'}) eq 'ARRAY') && (ref($fields) eq 'ARRAY')) {              if ((ref($changes{'helpform'}) eq 'ARRAY') && (ref($fields) eq 'ARRAY')) {
                 my (@optional,@required,@unused,$maxsizechg);                  my (@optional,@required,@unused,$maxsizechg);
                 foreach my $field (@{$changes{'helpform'}}) {                  foreach my $field (@{$changes{'helpform'}}) {
Line 10615  sub modify_contacts { Line 13390  sub modify_contacts {
                         next;                          next;
                     }                      }
                     if ($contacts_hash{'contacts'}{'helpform'}{$field} eq 'yes') {                      if ($contacts_hash{'contacts'}{'helpform'}{$field} eq 'yes') {
                         push(@optional,$field);                              push(@optional,$field);
                     } elsif ($contacts_hash{'contacts'}{'helpform'}{$field} eq 'no') {                      } elsif ($contacts_hash{'contacts'}{'helpform'}{$field} eq 'no') {
                         push(@unused,$field);                          push(@unused,$field);
                     } elsif ($contacts_hash{'contacts'}{'helpform'}{$field} eq 'req') {                      } elsif ($contacts_hash{'contacts'}{'helpform'}{$field} eq 'req') {
                         push(@required,$field);                             push(@required,$field);
                     }                      }
                 }                  }
                 if (@optional) {                  if (@optional) {
Line 10645  sub modify_contacts { Line 13420  sub modify_contacts {
                                    &mt('Max size for file uploaded to help form by logged-in user set to [_1] MB.',                                     &mt('Max size for file uploaded to help form by logged-in user set to [_1] MB.',
                                        $contacts_hash{'contacts'}{'helpform'}{'maxsize'}).                                         $contacts_hash{'contacts'}{'helpform'}{'maxsize'}).
                                    '</li>';                                     '</li>';
   
                 }                  }
             }              }
             $resulttext .= '</ul>';              $resulttext .= '</ul>';
         } else {          } else {
             $resulttext = &mt('No changes made to contact information');              $resulttext = &mt('No changes made to contacts and form settings');
         }          }
     } else {      } else {
         $resulttext = '<span class="LC_error">'.          $resulttext = '<span class="LC_error">'.
Line 10668  sub modify_usercreation { Line 13442  sub modify_usercreation {
             if ($key eq 'cancreate') {              if ($key eq 'cancreate') {
                 if (ref($domconfig{'usercreation'}{$key}) eq 'HASH') {                  if (ref($domconfig{'usercreation'}{$key}) eq 'HASH') {
                     foreach my $item (keys(%{$domconfig{'usercreation'}{$key}})) {                      foreach my $item (keys(%{$domconfig{'usercreation'}{$key}})) {
                         if (($item eq 'selfcreate') || ($item eq 'statustocreate') ||                          if (($item eq 'requestcrs') || ($item eq 'course') || ($item eq 'author')) {
                             ($item eq 'captcha') || ($item eq 'recaptchakeys') ||  
                             ($item eq 'recaptchaversion')) {  
                             $save_usercreate{$key}{$item} = $domconfig{'usercreation'}{$key}{$item};  
                         } else {  
                             $curr_usercreation{$key}{$item} = $domconfig{'usercreation'}{$key}{$item};                              $curr_usercreation{$key}{$item} = $domconfig{'usercreation'}{$key}{$item};
                           } else {
                               $save_usercreate{$key}{$item} = $domconfig{'usercreation'}{$key}{$item};
                         }                          }
                     }                      }
                 }                  }
Line 10745  sub modify_usercreation { Line 13517  sub modify_usercreation {
     }      }
   
     my @authen_contexts = ('author','course','domain');      my @authen_contexts = ('author','course','domain');
     my @authtypes = ('int','krb4','krb5','loc');      my @authtypes = ('int','krb4','krb5','loc','lti');
     my %authhash;      my %authhash;
     foreach my $item (@authen_contexts) {      foreach my $item (@authen_contexts) {
         my @authallowed =  &Apache::loncommon::get_env_multiple('form.'.$item.'_auth');          my @authallowed =  &Apache::loncommon::get_env_multiple('form.'.$item.'_auth');
Line 10876  sub modify_usercreation { Line 13648  sub modify_usercreation {
 }  }
   
 sub modify_selfcreation {  sub modify_selfcreation {
     my ($dom,%domconfig) = @_;      my ($dom,$lastactref,%domconfig) = @_;
     my ($resulttext,$warningmsg,%curr_usercreation,%curr_usermodify,%changes,%cancreate);      my ($resulttext,$warningmsg,%curr_usercreation,%curr_usermodify,%curr_inststatus,%changes,%cancreate);
     my (%save_usercreate,%save_usermodify);      my (%save_usercreate,%save_usermodify,%save_inststatus,@types,%usertypes);
     my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom);      my %domdefaults = &Apache::lonnet::get_domain_defaults($dom,1);
     if (ref($types) eq 'ARRAY') {      my ($othertitle,$usertypesref,$typesref) = &Apache::loncommon::sorted_inst_types($dom);
         $usertypes->{'default'} = $othertitle;      if (ref($typesref) eq 'ARRAY') {
         push(@{$types},'default');          @types = @{$typesref};
       }
       if (ref($usertypesref) eq 'HASH') {
           %usertypes = %{$usertypesref};
     }      }
       $usertypes{'default'} = $othertitle;
 #  #
 # Retrieve current domain configuration for self-creation of usernames from $domconfig{'usercreation'}.  # Retrieve current domain configuration for self-creation of usernames from $domconfig{'usercreation'}.
 #  #
Line 10893  sub modify_selfcreation { Line 13669  sub modify_selfcreation {
                 if (ref($domconfig{'usercreation'}{$key}) eq 'HASH') {                  if (ref($domconfig{'usercreation'}{$key}) eq 'HASH') {
                     foreach my $item (keys(%{$domconfig{'usercreation'}{$key}})) {                      foreach my $item (keys(%{$domconfig{'usercreation'}{$key}})) {
                         if (($item eq 'selfcreate') || ($item eq 'statustocreate') ||                          if (($item eq 'selfcreate') || ($item eq 'statustocreate') ||
                             ($item eq 'captcha') || ($item eq 'recaptchakeys') ||                               ($item eq 'captcha') || ($item eq 'recaptchakeys') ||
                             ($item eq 'recaptchaversion') ||                              ($item eq 'recaptchaversion') || ($item eq 'notify') ||
                             ($item eq 'emailusername') || ($item eq 'notify') ||                              ($item eq 'emailusername') || ($item eq 'shibenv') ||
                             ($item eq 'selfcreateprocessing') || ($item eq 'shibenv')) {                              ($item eq 'selfcreateprocessing') || ($item eq 'emailverified') ||
                               ($item eq 'emailoptions') || ($item eq 'emaildomain')) {
                             $curr_usercreation{$key}{$item} = $domconfig{'usercreation'}{$key}{$item};                              $curr_usercreation{$key}{$item} = $domconfig{'usercreation'}{$key}{$item};
                         } else {                          } else {
                             $save_usercreate{$key}{$item} = $domconfig{'usercreation'}{$key}{$item};                              $save_usercreate{$key}{$item} = $domconfig{'usercreation'}{$key}{$item};
Line 10922  sub modify_selfcreation { Line 13699  sub modify_selfcreation {
             }              }
         }          }
     }      }
   #
   # Retrieve current domain configuration for institutional status types from $domconfig{'inststatus'}.
   #
       if (ref($domconfig{'inststatus'}) eq 'HASH') {
           foreach my $key (keys(%{$domconfig{'inststatus'}})) {
               if ($key eq 'inststatusguest') {
                   $curr_inststatus{$key} = $domconfig{'inststatus'}{$key};
               } else {
                   $save_inststatus{$key} = $domconfig{'inststatus'}{$key};
               }
           }
       }
   
     my @contexts = ('selfcreate');      my @contexts = ('selfcreate');
     @{$cancreate{'selfcreate'}} = ();      @{$cancreate{'selfcreate'}} = ();
     %{$cancreate{'emailusername'}} = ();      %{$cancreate{'emailusername'}} = ();
     @{$cancreate{'statustocreate'}} = ();      if (@types) {
           @{$cancreate{'statustocreate'}} = ();
       }
     %{$cancreate{'selfcreateprocessing'}} = ();      %{$cancreate{'selfcreateprocessing'}} = ();
     %{$cancreate{'shibenv'}} = ();      %{$cancreate{'shibenv'}} = ();
       %{$cancreate{'emailverified'}} = ();
       %{$cancreate{'emailoptions'}} = ();
       %{$cancreate{'emaildomain'}} = ();
     my %selfcreatetypes = (      my %selfcreatetypes = (
                              sso   => 'users authenticated by institutional single sign on',                               sso   => 'users authenticated by institutional single sign on',
                              login => 'users authenticated by institutional log-in',                               login => 'users authenticated by institutional log-in',
                              email => 'users who provide a valid e-mail address for use as username',                               email => 'users verified by e-mail',
                           );                            );
 #  #
 # Populate $cancreate{'selfcreate'} array reference with types of user, for which self-creation of user accounts  # Populate $cancreate{'selfcreate'} array reference with types of user, for which self-creation of user accounts
 # is permitted.  # is permitted.
 #  #
       my ($emailrules,$emailruleorder) = &Apache::lonnet::inst_userrules($dom,'email');
   
     my @statuses;      my (@statuses,%email_rule);
     if (ref($domconfig{'inststatus'}) eq 'HASH') {  
         if (ref($domconfig{'inststatus'}{'inststatusguest'}) eq 'ARRAY') {  
             @statuses = @{$domconfig{'inststatus'}{'inststatusguest'}};  
         }  
     }  
     push(@statuses,'default');  
   
     foreach my $item ('login','sso','email') {      foreach my $item ('login','sso','email') {
         if ($item eq 'email') {          if ($item eq 'email') {
             if ($env{'form.cancreate_email'}) {              if ($env{'form.cancreate_email'}) {
                 push(@{$cancreate{'selfcreate'}},'email');                  if (@types) {
                 push(@contexts,'selfcreateprocessing');                      my @poss_statuses = &Apache::loncommon::get_env_multiple('form.selfassign');
                 foreach my $type (@statuses) {                      foreach my $status (@poss_statuses) {
                     if ($type eq 'default') {                          if (grep(/^\Q$status\E$/,(@types,'default'))) {
                         $cancreate{'selfcreateprocessing'}{$type} = $env{'form.cancreate_emailprocess'};                              push(@statuses,$status);
                     } else {                           }
                         $cancreate{'selfcreateprocessing'}{$type} = $env{'form.cancreate_emailprocess_'.$type};                      }
                       $save_inststatus{'inststatusguest'} = \@statuses;
                   } else {
                       push(@statuses,'default');
                   }
                   if (@statuses) {
                       my %curr_rule;
                       if (ref($curr_usercreation{'email_rule'}) eq 'ARRAY') {
                           foreach my $type (@statuses) {
                               $curr_rule{$type} = $curr_usercreation{'email_rule'};
                           }
                       } elsif (ref($curr_usercreation{'email_rule'}) eq 'HASH') {
                           foreach my $type (@statuses) {
                               $curr_rule{$type} = $curr_usercreation{'email_rule'}{$type};
                           }
                       }
                       push(@{$cancreate{'selfcreate'}},'email');
                       push(@contexts,('selfcreateprocessing','emailverified','emailoptions'));
                       my %curremaildom;
                       if (ref($curr_usercreation{'cancreate'}{'emaildomain'}) eq 'HASH') {
                           %curremaildom = %{$curr_usercreation{'cancreate'}{'emaildomain'}};
                       }
                       foreach my $type (@statuses) {
                           if ($env{'form.cancreate_emailprocess_'.$type} =~ /^(?:approval|automatic)$/) {
                               $cancreate{'selfcreateprocessing'}{$type} = $env{'form.cancreate_emailprocess_'.$type};
                           }
                           if ($env{'form.cancreate_usernameoptions_'.$type} =~ /^(?:all|first|free)$/) {
                               $cancreate{'emailverified'}{$type} = $env{'form.cancreate_usernameoptions_'.$type};
                           }
                           if ($env{'form.cancreate_emailoptions_'.$type} =~ /^(any|inst|noninst|custom)$/) {
   #
   # Retrieve rules (if any) governing types of e-mail address which may be used to verify a username.
   #
                               my $chosen = $1;
                               if (($chosen eq 'inst') || ($chosen eq 'noninst')) {
                                   my $emaildom;
                                   if ($env{'form.cancreate_emaildomain_'.$chosen.'_'.$type} =~ /^\@[^\@]+$/) {
                                       $emaildom = $env{'form.cancreate_emaildomain_'.$chosen.'_'.$type}; 
                                       $cancreate{'emaildomain'}{$type}{$chosen} = $emaildom;
                                       if (ref($curremaildom{$type}) eq 'HASH') {
                                           if (exists($curremaildom{$type}{$chosen})) {
                                               if ($curremaildom{$type}{$chosen} ne $emaildom) {
                                                   push(@{$changes{'cancreate'}},'emaildomain');
                                               }
                                           } elsif ($emaildom ne '') {
                                               push(@{$changes{'cancreate'}},'emaildomain');
                                           }
                                       } elsif ($emaildom ne '') {
                                           push(@{$changes{'cancreate'}},'emaildomain');
                                       } 
                                   }
                                   $cancreate{'emailoptions'}{$type} = $env{'form.cancreate_emailoptions_'.$type};
                               } elsif ($chosen eq 'custom') {
                                   my @possemail_rules = &Apache::loncommon::get_env_multiple('form.email_rule_'.$type);
                                   $email_rule{$type} = [];
                                   if (ref($emailrules) eq 'HASH') {
                                       foreach my $rule (@possemail_rules) {
                                           if (exists($emailrules->{$rule})) {
                                               push(@{$email_rule{$type}},$rule);
                                           }
                                       }
                                   }
                                   if (@{$email_rule{$type}}) {
                                       $cancreate{'emailoptions'}{$type} = 'custom';
                                       if (ref($curr_rule{$type}) eq 'ARRAY') {
                                           if (@{$curr_rule{$type}} > 0) {
                                               foreach my $rule (@{$curr_rule{$type}}) {
                                                   if (!grep(/^\Q$rule\E$/,@{$email_rule{$type}})) {
                                                       push(@{$changes{'email_rule'}},$type);
                                                   }
                                               }
                                           }
                                           foreach my $type (@{$email_rule{$type}}) {
                                               if (!grep(/^\Q$type\E$/,@{$curr_rule{$type}})) {
                                                   push(@{$changes{'email_rule'}},$type);
                                               }
                                           }
                                       } else {
                                           push(@{$changes{'email_rule'}},$type);
                                       }
                                   }
                               } else {
                                   $cancreate{'emailoptions'}{$type} = $env{'form.cancreate_emailoptions_'.$type};
                               }
                           }
                       }
                       if (@types) {
                           if (ref($curr_inststatus{'inststatusguest'}) eq 'ARRAY') {
                               my @changed = &Apache::loncommon::compare_arrays(\@statuses,$curr_inststatus{'inststatusguest'});
                               if (@changed) {
                                   push(@{$changes{'inststatus'}},'inststatusguest');
                               }
                           } else {
                               push(@{$changes{'inststatus'}},'inststatusguest');
                           }
                       }
                   } else {
                       delete($env{'form.cancreate_email'});
                       if (ref($curr_inststatus{'inststatusguest'}) eq 'ARRAY') {
                           if (@{$curr_inststatus{'inststatusguest'}} > 0) {
                               push(@{$changes{'inststatus'}},'inststatusguest');
                           }
                       }
                   }
               } else {
                   $save_inststatus{'inststatusguest'} = [];
                   if (ref($curr_inststatus{'inststatusguest'}) eq 'ARRAY') {
                       if (@{$curr_inststatus{'inststatusguest'}} > 0) {
                           push(@{$changes{'inststatus'}},'inststatusguest');
                     }                      }
                 }                  }
             }              }
Line 10966  sub modify_selfcreation { Line 13862  sub modify_selfcreation {
             }              }
         }          }
     }      }
     my (@email_rule,%userinfo,%savecaptcha);      my (%userinfo,%savecaptcha);
     my ($infofields,$infotitles) = &Apache::loncommon::emailusername_info();      my ($infofields,$infotitles) = &Apache::loncommon::emailusername_info();
 #  #
 # Populate $cancreate{'emailusername'}{$type} hash ref with information fields (if new user will provide data  # Populate $cancreate{'emailusername'}{$type} hash ref with information fields (if new user will provide data
Line 10975  sub modify_selfcreation { Line 13871  sub modify_selfcreation {
   
     if ($env{'form.cancreate_email'}) {      if ($env{'form.cancreate_email'}) {
         push(@contexts,'emailusername');          push(@contexts,'emailusername');
         if (ref($types) eq 'ARRAY') {          if (@statuses) {
             foreach my $type (@{$types}) {              foreach my $type (@statuses) {
                 if (ref($infofields) eq 'ARRAY') {                  if (ref($infofields) eq 'ARRAY') {
                     foreach my $field (@{$infofields}) {                      foreach my $field (@{$infofields}) {
                         if ($env{'form.canmodify_emailusername_'.$type.'_'.$field} =~ /^(required|optional)$/) {                          if ($env{'form.canmodify_emailusername_'.$type.'_'.$field} =~ /^(required|optional)$/) {
Line 10988  sub modify_selfcreation { Line 13884  sub modify_selfcreation {
         }          }
 #  #
 # Populate $cancreate{'notify'} hash ref with names of Domain Coordinators who are to be notified of  # Populate $cancreate{'notify'} hash ref with names of Domain Coordinators who are to be notified of
 # queued requests for self-creation of account using e-mail address as username  # queued requests for self-creation of account verified by e-mail.
 #  #
   
         my @approvalnotify = &Apache::loncommon::get_env_multiple('form.selfcreationnotifyapproval');          my @approvalnotify = &Apache::loncommon::get_env_multiple('form.selfcreationnotifyapproval');
Line 11008  sub modify_selfcreation { Line 13904  sub modify_selfcreation {
             push(@{$changes{'cancreate'}},'notify');              push(@{$changes{'cancreate'}},'notify');
         }          }
   
 #  
 # Retrieve rules (if any) governing types of e-mail address which may be used as a username  
 #  
         @email_rule = &Apache::loncommon::get_env_multiple('form.email_rule');  
         &process_captcha('cancreate',\%changes,\%savecaptcha,$curr_usercreation{'cancreate'});          &process_captcha('cancreate',\%changes,\%savecaptcha,$curr_usercreation{'cancreate'});
         if (ref($curr_usercreation{'email_rule'}) eq 'ARRAY') {  
             if (@{$curr_usercreation{'email_rule'}} > 0) {  
                 foreach my $type (@{$curr_usercreation{'email_rule'}}) {  
                     if (!grep(/^\Q$type\E$/,@email_rule)) {  
                         push(@{$changes{'email_rule'}},$type);  
                     }  
                 }  
             }  
             if (@email_rule > 0) {  
                 foreach my $type (@email_rule) {  
                     if (!grep(/^\Q$type\E$/,@{$curr_usercreation{'email_rule'}})) {  
                         push(@{$changes{'email_rule'}},$type);  
                     }  
                 }  
             }  
         } elsif (@email_rule > 0) {  
             push(@{$changes{'email_rule'}},@email_rule);  
         }  
     }      }
 #    #  
 # Check if domain default is set appropriately, if self-creation of accounts is to be available for  # Check if domain default is set appropriately, if self-creation of accounts is to be available for
 # institutional log-in.  # institutional log-in.
 #  #
     if (grep(/^login$/,@{$cancreate{'selfcreate'}})) {      if (grep(/^login$/,@{$cancreate{'selfcreate'}})) {
         my %domdefaults = &Apache::lonnet::get_domain_defaults($dom,1);  
         if (!((($domdefaults{'auth_def'} =~/^krb/) && ($domdefaults{'auth_arg_def'} ne '')) ||           if (!((($domdefaults{'auth_def'} =~/^krb/) && ($domdefaults{'auth_arg_def'} ne '')) || 
                ($domdefaults{'auth_def'} eq 'localauth'))) {                 ($domdefaults{'auth_def'} eq 'localauth'))) {
             $warningmsg = &mt('Although account creation has been set to be available for institutional logins, currently default authentication in this domain has not been set to support this.').' '.              $warningmsg = &mt('Although account creation has been set to be available for institutional logins, currently default authentication in this domain has not been set to support this.').' '.
Line 11056  sub modify_selfcreation { Line 13929  sub modify_selfcreation {
 # which the user may supply, if institutional data is unavailable.  # which the user may supply, if institutional data is unavailable.
 #  #
     if (($env{'form.cancreate_login'}) || ($env{'form.cancreate_sso'})) {      if (($env{'form.cancreate_login'}) || ($env{'form.cancreate_sso'})) {
         if (ref($types) eq 'ARRAY') {          if (@types) {
             if (@{$types} > 1) {              @{$cancreate{'statustocreate'}} = &Apache::loncommon::get_env_multiple('form.statustocreate');
                 @{$cancreate{'statustocreate'}} = &Apache::loncommon::get_env_multiple('form.statustocreate');              push(@contexts,'statustocreate');
                 push(@contexts,'statustocreate');              foreach my $type (@types) {
             } else {  
                 undef($cancreate{'statustocreate'});  
             }   
             foreach my $type (@{$types}) {  
                 my @modifiable =  &Apache::loncommon::get_env_multiple('form.canmodify_'.$type);                  my @modifiable =  &Apache::loncommon::get_env_multiple('form.canmodify_'.$type);
                 foreach my $field (@fields) {                  foreach my $field (@fields) {
                     if (grep(/^\Q$field\E$/,@modifiable)) {                      if (grep(/^\Q$field\E$/,@modifiable)) {
Line 11074  sub modify_selfcreation { Line 13943  sub modify_selfcreation {
                 }                  }
             }              }
             if (ref($curr_usermodify{'selfcreate'}) eq 'HASH') {              if (ref($curr_usermodify{'selfcreate'}) eq 'HASH') {
                 foreach my $type (@{$types}) {                  foreach my $type (@types) {
                     if (ref($curr_usermodify{'selfcreate'}{$type}) eq 'HASH') {                      if (ref($curr_usermodify{'selfcreate'}{$type}) eq 'HASH') {
                         foreach my $field (@fields) {                          foreach my $field (@fields) {
                             if ($save_usermodify{'selfcreate'}{$type}{$field} ne                              if ($save_usermodify{'selfcreate'}{$type}{$field} ne
Line 11086  sub modify_selfcreation { Line 13955  sub modify_selfcreation {
                     }                      }
                 }                  }
             } else {              } else {
                 foreach my $type (@{$types}) {                  foreach my $type (@types) {
                     push(@{$changes{'selfcreate'}},$type);                      push(@{$changes{'selfcreate'}},$type);
                 }                  }
             }              }
Line 11135  sub modify_selfcreation { Line 14004  sub modify_selfcreation {
             }              }
         } elsif (ref($curr_usercreation{'cancreate'}{$item}) eq 'HASH') {          } elsif (ref($curr_usercreation{'cancreate'}{$item}) eq 'HASH') {
             if (ref($cancreate{$item}) eq 'HASH') {              if (ref($cancreate{$item}) eq 'HASH') {
                 foreach my $curr (keys(%{$curr_usercreation{'cancreate'}{$item}})) {                  foreach my $type (keys(%{$curr_usercreation{'cancreate'}{$item}})) {
                     if (ref($curr_usercreation{'cancreate'}{$item}{$curr}) eq 'HASH') {                      if (ref($curr_usercreation{'cancreate'}{$item}{$type}) eq 'HASH') {
                         foreach my $field (keys(%{$curr_usercreation{'cancreate'}{$item}{$curr}})) {                          foreach my $field (keys(%{$curr_usercreation{'cancreate'}{$item}{$type}})) {
                             unless ($curr_usercreation{'cancreate'}{$item}{$curr}{$field} eq $cancreate{$item}{$curr}{$field}) {                              unless ($curr_usercreation{'cancreate'}{$item}{$type}{$field} eq $cancreate{$item}{$type}{$field}) {
                                 if (!grep(/^$item$/,@{$changes{'cancreate'}})) {                                  if (!grep(/^$item$/,@{$changes{'cancreate'}})) {
                                     push(@{$changes{'cancreate'}},$item);                                      push(@{$changes{'cancreate'}},$item);
                                 }                                  }
                             }                              }
                         }                          }
                     } elsif ($item eq 'selfcreateprocessing') {                      } elsif (($item eq 'selfcreateprocessing') || ($item eq 'emailverified') || ($item eq 'emailoptions')) {
                         if ($cancreate{$item}{$curr} ne $curr_usercreation{'cancreate'}{$item}{$curr}) {                          if ($cancreate{$item}{$type} ne $curr_usercreation{'cancreate'}{$item}{$type}) {
                             if (!grep(/^$item$/,@{$changes{'cancreate'}})) {  
                                 push(@{$changes{'cancreate'}},$item);  
                             }  
                         }  
                     } else {  
                         if (!$cancreate{$item}{$curr}) {  
                             if (!grep(/^$item$/,@{$changes{'cancreate'}})) {                              if (!grep(/^$item$/,@{$changes{'cancreate'}})) {
                                 push(@{$changes{'cancreate'}},$item);                                  push(@{$changes{'cancreate'}},$item);
                             }                              }
                         }                          }
                     }                      }
                 }                  }
                 foreach my $field (keys(%{$cancreate{$item}})) {                  foreach my $type (keys(%{$cancreate{$item}})) {
                     if (ref($cancreate{$item}{$field}) eq 'HASH') {                      if (ref($cancreate{$item}{$type}) eq 'HASH') {
                         foreach my $inner (keys(%{$cancreate{$item}{$field}})) {                          foreach my $field (keys(%{$cancreate{$item}{$type}})) {
                             if (ref($curr_usercreation{'cancreate'}{$item}{$field}) eq 'HASH') {                              if (ref($curr_usercreation{'cancreate'}{$item}{$type}) eq 'HASH') {
                                 unless ($curr_usercreation{'cancreate'}{$item}{$field}{$inner} eq $cancreate{$item}{$field}{$inner}) {                                  unless ($curr_usercreation{'cancreate'}{$item}{$type}{$field} eq $cancreate{$item}{$type}{$field}) {
                                     if (!grep(/^$item$/,@{$changes{'cancreate'}})) {                                      if (!grep(/^$item$/,@{$changes{'cancreate'}})) {
                                         push(@{$changes{'cancreate'}},$item);                                          push(@{$changes{'cancreate'}},$item);
                                     }                                      }
Line 11173  sub modify_selfcreation { Line 14036  sub modify_selfcreation {
                                 }                                  }
                             }                              }
                         }                          }
                     } elsif ($item eq 'selfcreateprocessing') {                      } elsif (($item eq 'selfcreateprocessing') || ($item eq 'emailverified') || ($item eq 'emailoptions')) {
                         if ($cancreate{$item}{$field} ne $curr_usercreation{'cancreate'}{$item}{$field}) {                          if ($cancreate{$item}{$type} ne $curr_usercreation{'cancreate'}{$item}{$type}) {
                             if (!grep(/^$item$/,@{$changes{'cancreate'}})) {  
                                 push(@{$changes{'cancreate'}},$item);  
                             }  
                         }  
                     } else {  
                         if (!$curr_usercreation{'cancreate'}{$item}{$field}) {  
                             if (!grep(/^$item$/,@{$changes{'cancreate'}})) {                              if (!grep(/^$item$/,@{$changes{'cancreate'}})) {
                                 push(@{$changes{'cancreate'}},$item);                                  push(@{$changes{'cancreate'}},$item);
                             }                              }
Line 11195  sub modify_selfcreation { Line 14052  sub modify_selfcreation {
                         push(@{$changes{'cancreate'}},$item);                          push(@{$changes{'cancreate'}},$item);
                     }                      }
                 }                  }
             } elsif (ref($cancreate{$item}) eq 'HASH') {              }
                 if (!$cancreate{$item}{$curr_usercreation{'cancreate'}{$item}}) {          } elsif (($item eq 'selfcreateprocessing') || ($item eq 'emailverified') || ($item eq 'emailoptions')) {
                     if (!grep(/^$item$/,@{$changes{'cancreate'}})) {              if (ref($cancreate{$item}) eq 'HASH') {
                         push(@{$changes{'cancreate'}},$item);                  if (!grep(/^$item$/,@{$changes{'cancreate'}})) {
                     }                      push(@{$changes{'cancreate'}},$item);
                 }                  }
             }              }
         } elsif ($item eq 'emailusername') {          } elsif ($item eq 'emailusername') {
Line 11232  sub modify_selfcreation { Line 14089  sub modify_selfcreation {
     if (ref($cancreate{'selfcreateprocessing'}) eq 'HASH') {      if (ref($cancreate{'selfcreateprocessing'}) eq 'HASH') {
         $save_usercreate{'cancreate'}{'selfcreateprocessing'} = $cancreate{'selfcreateprocessing'};          $save_usercreate{'cancreate'}{'selfcreateprocessing'} = $cancreate{'selfcreateprocessing'};
     }      }
       if (ref($cancreate{'emailverified'}) eq 'HASH') {
           $save_usercreate{'cancreate'}{'emailverified'} = $cancreate{'emailverified'};
       }
       if (ref($cancreate{'emailoptions'}) eq 'HASH') {
           $save_usercreate{'cancreate'}{'emailoptions'} = $cancreate{'emailoptions'};
       }
       if (ref($cancreate{'emaildomain'}) eq 'HASH') {
           $save_usercreate{'cancreate'}{'emaildomain'} = $cancreate{'emaildomain'};
       }
     if (ref($cancreate{'statustocreate'}) eq 'ARRAY') {      if (ref($cancreate{'statustocreate'}) eq 'ARRAY') {
         $save_usercreate{'cancreate'}{'statustocreate'} = $cancreate{'statustocreate'};          $save_usercreate{'cancreate'}{'statustocreate'} = $cancreate{'statustocreate'};
     }      }
Line 11239  sub modify_selfcreation { Line 14105  sub modify_selfcreation {
         $save_usercreate{'cancreate'}{'shibenv'} = $cancreate{'shibenv'};          $save_usercreate{'cancreate'}{'shibenv'} = $cancreate{'shibenv'};
     }      }
     $save_usercreate{'cancreate'}{'emailusername'} = $cancreate{'emailusername'};      $save_usercreate{'cancreate'}{'emailusername'} = $cancreate{'emailusername'};
     $save_usercreate{'emailrule'} = \@email_rule;      $save_usercreate{'email_rule'} = \%email_rule;
   
     my %userconfig_hash = (      my %userconfig_hash = (
             usercreation     => \%save_usercreate,              usercreation     => \%save_usercreate,
             usermodification => \%save_usermodify,              usermodification => \%save_usermodify,
               inststatus       => \%save_inststatus,
     );      );
   
     my $putresult = &Apache::lonnet::put_dom('configuration',\%userconfig_hash,      my $putresult = &Apache::lonnet::put_dom('configuration',\%userconfig_hash,
                                              $dom);                                               $dom);
 #  #
 # Accumulate details of changes to domain cofiguration for self-creation of usernames in $resulttext  # Accumulate details of changes to domain configuration for self-creation of usernames in $resulttext
 #  #
     if ($putresult eq 'ok') {      if ($putresult eq 'ok') {
         if (keys(%changes) > 0) {          if (keys(%changes) > 0) {
Line 11256  sub modify_selfcreation { Line 14124  sub modify_selfcreation {
             if (ref($changes{'cancreate'}) eq 'ARRAY') {              if (ref($changes{'cancreate'}) eq 'ARRAY') {
                 my %lt = &selfcreation_types();                  my %lt = &selfcreation_types();
                 foreach my $type (@{$changes{'cancreate'}}) {                  foreach my $type (@{$changes{'cancreate'}}) {
                     my $chgtext;                      my $chgtext = '';
                     if ($type eq 'selfcreate') {                      if ($type eq 'selfcreate') {
                         if (@{$cancreate{$type}} == 0) {                          if (@{$cancreate{$type}} == 0) {
                             $chgtext .= &mt('Self creation of a new user account is not permitted.');                              $chgtext .= &mt('Self creation of a new user account is not permitted.');
Line 11271  sub modify_selfcreation { Line 14139  sub modify_selfcreation {
                                 if (grep(/^(login|sso)$/,@{$cancreate{$type}})) {                                  if (grep(/^(login|sso)$/,@{$cancreate{$type}})) {
                                     if (ref($cancreate{'statustocreate'}) eq 'ARRAY') {                                      if (ref($cancreate{'statustocreate'}) eq 'ARRAY') {
                                         if (@{$cancreate{'statustocreate'}} == 0) {                                          if (@{$cancreate{'statustocreate'}} == 0) {
                                             $chgtext .= '<br />'.                                              $chgtext .= '<span class="LC_warning">'.
                                                         '<span class="LC_warning">'.                                                          &mt("However, no institutional affiliations (including 'other') are currently permitted to create accounts via log-in or single sign-on.").
                                                         &mt("However, no institutional affiliations (including 'other') are currently permitted to create accounts.").                                                          '</span><br />';
                                                         '</span>';  
                                         }                                          }
                                     }                                      }
                                 }                                  }
                                   if (grep(/^email$/,@{$cancreate{$type}})) {
                                       if (!@statuses) {
                                           $chgtext .= '<span class="LC_warning">'.
                                                       &mt("However, e-mail verification is currently set to 'unavailable' for all user types (including 'other'), so self-creation of accounts is not possible for non-institutional log-in.").
                                                       '</span><br />';
   
                                       }
                                   }
                             }                              }
                         }                          }
                     } elsif ($type eq 'shibenv') {                      } elsif ($type eq 'shibenv') {
                         if (keys(%{$cancreate{$type}}) == 0) {                          if (keys(%{$cancreate{$type}}) == 0) {
                             $chgtext .= &mt('Shibboleth-autheticated user does not use environment variables to set user information');                               $chgtext .= &mt('Shibboleth-autheticated user does not use environment variables to set user information').'<br />'; 
                         } else {                          } else {
                             $chgtext .= &mt('Shibboleth-autheticated user information set from environment variables, as follows:').                              $chgtext .= &mt('Shibboleth-autheticated user information set from environment variables, as follows:').
                                         '<ul>';                                          '<ul>';
Line 11295  sub modify_selfcreation { Line 14170  sub modify_selfcreation {
                                 }                                  }
                             }                              }
                             $chgtext .= '</ul>';                              $chgtext .= '</ul>';
                         }                            }
                     } elsif ($type eq 'statustocreate') {                      } elsif ($type eq 'statustocreate') {
                         if ((ref($cancreate{'selfcreate'}) eq 'ARRAY') &&                          if ((ref($cancreate{'selfcreate'}) eq 'ARRAY') &&
                             (ref($cancreate{'statustocreate'}) eq 'ARRAY')) {                              (ref($cancreate{'statustocreate'}) eq 'ARRAY')) {
Line 11308  sub modify_selfcreation { Line 14183  sub modify_selfcreation {
                                                     &mt("However, no institutional affiliations (including 'other') are currently permitted to create accounts.").                                                      &mt("However, no institutional affiliations (including 'other') are currently permitted to create accounts.").
                                                     '</span>';                                                      '</span>';
                                     }                                      }
                                 } elsif (ref($usertypes) eq 'HASH') {                                  } elsif (keys(%usertypes) > 0) {
                                     if (grep(/^(login|sso)$/,@{$cancreate{'selfcreate'}})) {                                      if (grep(/^(login|sso)$/,@{$cancreate{'selfcreate'}})) {
                                         $chgtext .= &mt('Creation of a new account for an institutional user is restricted to the following institutional affiliation(s):');                                          $chgtext .= &mt('Creation of a new account for an institutional user is restricted to the following institutional affiliation(s):');
                                     } else {                                      } else {
Line 11319  sub modify_selfcreation { Line 14194  sub modify_selfcreation {
                                         if ($case eq 'default') {                                          if ($case eq 'default') {
                                             $chgtext .= '<li>'.$othertitle.'</li>';                                              $chgtext .= '<li>'.$othertitle.'</li>';
                                         } else {                                          } else {
                                             $chgtext .= '<li>'.$usertypes->{$case}.'</li>';                                              $chgtext .= '<li>'.$usertypes{$case}.'</li>';
                                         }                                          }
                                     }                                      }
                                     $chgtext .= '</ul>';                                      $chgtext .= '</ul>';
                                     if (!grep(/^(login|sso)$/,@{$cancreate{'selfcreate'}})) {                                      if (!grep(/^(login|sso)$/,@{$cancreate{'selfcreate'}})) {
                                         $chgtext .= '<br /><span class="LC_warning">'.                                          $chgtext .= '<span class="LC_warning">'.
                                                     &mt('However, users authenticated by institutional login/single sign on are not currently permitted to create accounts.').                                                      &mt('However, users authenticated by institutional login/single sign on are not currently permitted to create accounts.').
                                                     '</span>';                                                      '</span>';
                                     }                                      }
Line 11336  sub modify_selfcreation { Line 14211  sub modify_selfcreation {
                                     $chgtext .= &mt('Although institutional affiliations permitted to create accounts were changed, self creation of accounts is not currently permitted for any authentication types.');                                      $chgtext .= &mt('Although institutional affiliations permitted to create accounts were changed, self creation of accounts is not currently permitted for any authentication types.');
                                 }                                  }
                             }                              }
                               $chgtext .= '<br />';
                         }                          }
                     } elsif ($type eq 'selfcreateprocessing') {                      } elsif ($type eq 'selfcreateprocessing') {
                         my %choices = &Apache::lonlocal::texthash (                          my %choices = &Apache::lonlocal::texthash (
                                                                     automatic => 'Automatic approval',                                                                      automatic => 'Automatic approval',
                                                                     approval  => 'Queued for approval',                                                                      approval  => 'Queued for approval',
                                                                   );                                                                    );
                         if (@statuses > 1) {                          if (@types) {
                             $chgtext .= &mt('Processing of requests to create account with e-mail address as username set as follows:').                               if (@statuses) {
                                         '<ul>';                                  $chgtext .= &mt('Processing of requests to create account with e-mail verification set as follows:'). 
                            foreach my $type (@statuses) {                                              '<ul>';
                                if ($type eq 'default') {                                  foreach my $status (@statuses) {
                                    $chgtext .= '<li>'.$othertitle.' -- '.$choices{$cancreate{'selfcreateprocessing'}{$type}}.'</li>';                                      if ($status eq 'default') {
                                } else {                                          $chgtext .= '<li>'.$othertitle.' -- '.$choices{$cancreate{'selfcreateprocessing'}{$status}}.'</li>';
                                    $chgtext .= '<li>'.$usertypes->{$type}.' -- '.$choices{$cancreate{'selfcreateprocessing'}{$type}}.'</li>';                                      } else {
                                }                                          $chgtext .= '<li>'.$usertypes{$status}.' -- '.$choices{$cancreate{'selfcreateprocessing'}{$status}}.'</li>';
                            }                                      }
                            $chgtext .= '</ul>';                                  }
                                   $chgtext .= '</ul>';
                               }
                         } else {                          } else {
                            $chgtext .= &mt('Processing of requests to create account with e-mail address as username set to: "[_1]"',                              $chgtext .= &mt('Processing of requests to create account with e-mail verification set to: "[_1]"',
                                          $choices{$cancreate{'selfcreateprocessing'}{'default'}});                                              $choices{$cancreate{'selfcreateprocessing'}{'default'}});
                           }
                       } elsif ($type eq 'emailverified') {
                           my %options = &Apache::lonlocal::texthash (
                                                                       all   => 'Same as e-mail',
                                                                       first => 'Omit @domain',
                                                                       free  => 'Free to choose',
                                                                     );
                           if (@types) {
                               if (@statuses) {
                                   $chgtext .= &mt('For self-created accounts verified by e-mail address, username is set as follows:').
                                               '<ul>';
                                   foreach my $status (@statuses) {
                                       if ($type eq 'default') {
                                           $chgtext .= '<li>'.$othertitle.' -- '.$options{$cancreate{'emailverified'}{$status}}.'</li>';
                                       } else {
                                           $chgtext .= '<li>'.$usertypes{$status}.' -- '.$options{$cancreate{'emailverified'}{$status}}.'</li>';
                                       }
                                   }
                                   $chgtext .= '</ul>';
                               }
                           } else {
                               $chgtext .= &mt("For self-created accounts verified by e-mail address, user's username is: '[_1]'",
                                               $options{$cancreate{'emailverified'}{'default'}});
                           }
                       } elsif ($type eq 'emailoptions') {
                           my %options = &Apache::lonlocal::texthash (
                                                                       any     => 'Any e-mail',
                                                                       inst    => 'Institutional only',
                                                                       noninst => 'Non-institutional only',
                                                                       custom  => 'Custom restrictions',
                                                                     );
                           if (@types) {
                               if (@statuses) {
                                   $chgtext .= &mt('For self-created accounts verified by e-mail address, requirements for e-mail address are as follows:').
                                               '<ul>';
                                   foreach my $status (@statuses) {
                                       if ($type eq 'default') {
                                           $chgtext .= '<li>'.$othertitle.' -- '.$options{$cancreate{'emailoptions'}{$status}}.'</li>';
                                       } else {
                                           $chgtext .= '<li>'.$usertypes{$status}.' -- '.$options{$cancreate{'emailoptions'}{$status}}.'</li>';
                                       }
                                   }
                                   $chgtext .= '</ul>';
                               }
                           } else {
                               if ($cancreate{'emailoptions'}{'default'} eq 'any') {
                                   $chgtext .= &mt('For self-created accounts verified by e-mail address, any e-mail may be used');
                               } else {
                                   $chgtext .= &mt('For self-created accounts verified by e-mail address, e-mail restricted to: "[_1]"',
                                                   $options{$cancreate{'emailoptions'}{'default'}});
                               }
                           }
                       } elsif ($type eq 'emaildomain') {
                           my $output;
                           if (@statuses) {
                               foreach my $type (@statuses) {
                                   if (ref($cancreate{'emaildomain'}{$type}) eq 'HASH') {
                                       if ($cancreate{'emailoptions'}{$type} eq 'inst') {
                                           if ($type eq 'default') {
                                               if ((ref($cancreate{'emaildomain'}{$type}) ne 'HASH') ||
                                                   ($cancreate{'emaildomain'}{$type}{'inst'} eq '')) {
                                                   $output = '<li>'.$othertitle.' -- '.&mt('No restriction on e-mail domain').'</li>';
                                               } else {
                                                   $output = '<li>'.$othertitle.' -- '.&mt("User's e-mail address needs to end: [_1]",
                                                                                           $cancreate{'emaildomain'}{$type}{'inst'}).'</li>';
                                               }
                                           } else {
                                               if ((ref($cancreate{'emaildomain'}{$type}) ne 'HASH') ||
                                                   ($cancreate{'emaildomain'}{$type}{'inst'} eq '')) {
                                                   $output = '<li>'.$usertypes{$type}.' -- '.&mt('No restriction on e-mail domain').'</li>';
                                               } else {
                                                   $output = '<li>'.$usertypes{$type}.' -- '.&mt("User's e-mail address needs to end: [_1]",
                                                                                                 $cancreate{'emaildomain'}{$type}{'inst'}).'</li>'; 
                                               }
                                           }
                                       } elsif ($cancreate{'emailoptions'}{$type} eq 'noninst') {
                                           if ($type eq 'default') {
                                               if ((ref($cancreate{'emaildomain'}{$type}) ne 'HASH') ||
                                                   ($cancreate{'emaildomain'}{$type}{'noninst'} eq '')) {
                                                   $output = '<li>'.$othertitle.' -- '.&mt('No restriction on e-mail domain').'</li>';
                                               } else {
                                                   $output = '<li>'.$othertitle.' -- '.&mt("User's e-mail address must not end: [_1]",
                                                                                           $cancreate{'emaildomain'}{$type}{'noninst'}).'</li>';
                                               }
                                           } else {
                                               if ((ref($cancreate{'emaildomain'}{$type}) ne 'HASH') ||
                                                   ($cancreate{'emaildomain'}{$type}{'noninst'} eq '')) {
                                                   $output = '<li>'.$usertypes{$type}.' -- '.&mt('No restriction on e-mail domain').'</li>';
                                               } else {
                                                   $output = '<li>'.$usertypes{$type}.' -- '.&mt("User's e-mail address must not end: [_1]",
                                                                                                   $cancreate{'emaildomain'}{$type}{'noninst'}).'</li>';   
                                               }
                                           }
                                       }
                                   }
                               }
                           }
                           if ($output ne '') {
                               $chgtext .= &mt('For self-created accounts verified by e-mail address:').
                                           '<ul>'.$output.'</ul>';
                         }                          }
                     } elsif ($type eq 'captcha') {                      } elsif ($type eq 'captcha') {
                         if ($savecaptcha{$type} eq 'notused') {                          if ($savecaptcha{$type} eq 'notused') {
Line 11392  sub modify_selfcreation { Line 14370  sub modify_selfcreation {
                         }                          }
                     } elsif ($type eq 'emailusername') {                      } elsif ($type eq 'emailusername') {
                         if (ref($cancreate{'emailusername'}) eq 'HASH') {                          if (ref($cancreate{'emailusername'}) eq 'HASH') {
                             if (ref($types) eq 'ARRAY') {                              if (@statuses) {
                                 foreach my $type (@{$types}) {                                  foreach my $type (@statuses) {
                                     if (ref($cancreate{'emailusername'}{$type}) eq 'HASH') {                                      if (ref($cancreate{'emailusername'}{$type}) eq 'HASH') {
                                         if (keys(%{$cancreate{'emailusername'}{$type}}) > 0) {                                          if (keys(%{$cancreate{'emailusername'}{$type}}) > 0) {
                                             $chgtext .= &mt('When self-creating account with e-mail as username, the following information will be provided by [_1]:',"'$usertypes->{$type}'").                                              $chgtext .= &mt('When self-creating account with e-mail verification, the following information will be provided by [_1]:',"'$usertypes{$type}'").
                                                     '<ul>';                                                      '<ul>';
                                             foreach my $field (@{$infofields}) {                                              foreach my $field (@{$infofields}) {
                                                 if ($cancreate{'emailusername'}{$type}{$field}) {                                                  if ($cancreate{'emailusername'}{$type}{$field}) {
Line 11405  sub modify_selfcreation { Line 14383  sub modify_selfcreation {
                                             }                                              }
                                             $chgtext .= '</ul>';                                              $chgtext .= '</ul>';
                                         } else {                                          } else {
                                             $chgtext .= &mt('When self creating account with e-mail as username, no information besides e-mail address will be provided by [_1].',"'$usertypes->{$type}'").'<br />';                                              $chgtext .= &mt('When self creating account with e-mail verification, no information besides e-mail address will be provided by [_1].',"'$usertypes{$type}'").'<br />';
                                         }                                          }
                                     } else {                                      } else {
                                         $chgtext .= &mt('When self creating account with e-mail as username, no information besides e-mail address will be provided by [_1].',"'$usertypes->{$type}'").'<br />';                                          $chgtext .= &mt('When self creating account with e-mail verification, no information besides e-mail address will be provided by [_1].',"'$usertypes{$type}'").'<br />';
                                     }                                      }
                                 }                                  }
                             }                              }
                         }                          }
                     } elsif ($type eq 'notify') {                      } elsif ($type eq 'notify') {
                         $chgtext = &mt('No Domain Coordinators will receive notification of username requests requiring approval.');                          my $numapprove = 0;
                         if (ref($changes{'cancreate'}) eq 'ARRAY') {                          if (ref($changes{'cancreate'}) eq 'ARRAY') {
                             if ((grep(/^notify$/,@{$changes{'cancreate'}})) && (ref($cancreate{'notify'}) eq 'HASH')) {                              if ((grep(/^notify$/,@{$changes{'cancreate'}})) && (ref($cancreate{'notify'}) eq 'HASH')) {
                                 if ($cancreate{'notify'}{'approval'}) {                                  if ($cancreate{'notify'}{'approval'}) {
                                     $chgtext = &mt('Notification of username requests requiring approval will be sent to: ').$cancreate{'notify'}{'approval'};                                      $chgtext .= &mt('Notification of username requests requiring approval will be sent to: ').$cancreate{'notify'}{'approval'};
                                       $numapprove ++;
                                 }                                  }
                             }                              }
                         }                          }
                           unless ($numapprove) {
                               $chgtext .= &mt('No Domain Coordinators will receive notification of username requests requiring approval.');
                           }
                     }                      }
                     if ($chgtext) {                      if ($chgtext) {
                         $resulttext .= '<li>'.$chgtext.'</li>';                          $resulttext .= '<li>'.$chgtext.'</li>';
                     }                      }
                 }                  }
             }              }
             if (ref($changes{'email_rule'}) eq 'ARRAY') {              if ((ref($changes{'email_rule'}) eq 'ARRAY') && (@{$changes{'email_rule'}} > 0)) {
                 my ($emailrules,$emailruleorder) =                  my ($emailrules,$emailruleorder) =
                     &Apache::lonnet::inst_userrules($dom,'email');                      &Apache::lonnet::inst_userrules($dom,'email');
                 my $chgtext = '<ul>';                  foreach my $type (@{$changes{'email_rule'}}) {
                 foreach my $type (@email_rule) {                      if (ref($email_rule{$type}) eq 'ARRAY') {
                     if (ref($emailrules->{$type}) eq 'HASH') {                          my $chgtext = '<ul>';
                         $chgtext .= '<li>'.$emailrules->{$type}{'name'}.'</li>';                          foreach my $rule (@{$email_rule{$type}}) {
                               if (ref($emailrules->{$rule}) eq 'HASH') {
                                   $chgtext .= '<li>'.$emailrules->{$rule}{'name'}.'</li>';
                               }
                           }
                           $chgtext .= '</ul>';
                           my $typename;
                           if (@types) {
                               if ($type eq 'default') {
                                   $typename = $othertitle;
                               } else {
                                   $typename = $usertypes{$type};
                               } 
                               $chgtext .= &mt('(Affiliation: [_1])',$typename);
                           }
                           if (@{$email_rule{$type}} > 0) {
                               $resulttext .= '<li>'.
                                              &mt('Accounts may not be created by users verified by e-mail, for e-mail addresses of the following types: ',
                                                  $usertypes{$type}).
                                              $chgtext.
                                              '</li>';
                           } else {
                               $resulttext .= '<li>'.
                                              &mt('There are now no restrictions on e-mail addresses which may be used for verification when a user requests an account.').
                                              '</li>'.
                                              &mt('(Affiliation: [_1])',$typename);
                           }
                     }                      }
                 }                  }
                 $chgtext .= '</ul>';              }
                 if (@email_rule > 0) {              if (ref($changes{'inststatus'}) eq 'ARRAY') {
                     $resulttext .= '<li>'.                  if (ref($save_inststatus{'inststatusguest'}) eq 'ARRAY') {
                                    &mt('Accounts may not be created by users self-enrolling with e-mail addresses of the following types: ').                      if (@{$save_inststatus{'inststatusguest'}} > 0) {
                                        $chgtext.                          my $chgtext = '<ul>';
                                    '</li>';                          foreach my $type (@{$save_inststatus{'inststatusguest'}}) {
                 } else {                              $chgtext .= '<li>'.$usertypes{$type}.'</li>';
                     $resulttext .= '<li>'.                          }
                                    &mt('There are now no restrictions on e-mail addresses which may be used as a username when self-enrolling.').                          $chgtext .= '</ul>';
                                    '</li>';                          $resulttext .= '<li>'.
                                          &mt('A user will self-report one of the following affiliations when requesting an account verified by e-mail: ').
                                             $chgtext.
                                          '</li>';
                       } else {
                           $resulttext .= '<li>'.
                                          &mt('No affiliations available for self-reporting when requesting an account verified by e-mail.').
                                          '</li>';
                       }
                 }                  }
             }              }
             if (ref($changes{'selfcreate'}) eq 'ARRAY') {              if (ref($changes{'selfcreate'}) eq 'ARRAY') {
Line 11454  sub modify_selfcreation { Line 14470  sub modify_selfcreation {
                 my %fieldtitles = &Apache::loncommon::personal_data_fieldtitles();                  my %fieldtitles = &Apache::loncommon::personal_data_fieldtitles();
                 foreach my $type (@{$changes{'selfcreate'}}) {                  foreach my $type (@{$changes{'selfcreate'}}) {
                     my $typename = $type;                      my $typename = $type;
                     if (ref($usertypes) eq 'HASH') {                      if (keys(%usertypes) > 0) {
                         if ($usertypes->{$type} ne '') {                          if ($usertypes{$type} ne '') {
                             $typename = $usertypes->{$type};                              $typename = $usertypes{$type};
                         }                          }
                     }                      }
                     my @modifiable;                      my @modifiable;
Line 11479  sub modify_selfcreation { Line 14495  sub modify_selfcreation {
                 $resulttext .= '</ul></li>';                  $resulttext .= '</ul></li>';
             }              }
             $resulttext .= '</ul>';              $resulttext .= '</ul>';
               my $cachetime = 24*60*60;
               $domdefaults{'inststatusguest'} = $save_inststatus{'inststatusguest'};
               &Apache::lonnet::do_cache_new('domdefaults',$dom,\%domdefaults,$cachetime);
               if (ref($lastactref) eq 'HASH') {
                   $lastactref->{'domdefaults'} = 1;
               }
         } else {          } else {
             $resulttext = &mt('No changes made to self-creation settings');              $resulttext = &mt('No changes made to self-creation settings');
         }          }
Line 11675  sub modify_defaults { Line 14697  sub modify_defaults {
     my ($dom,$lastactref,%domconfig) = @_;      my ($dom,$lastactref,%domconfig) = @_;
     my ($resulttext,$mailmsgtxt,%newvalues,%changes,@errors);      my ($resulttext,$mailmsgtxt,%newvalues,%changes,@errors);
     my %domdefaults = &Apache::lonnet::get_domain_defaults($dom,1);      my %domdefaults = &Apache::lonnet::get_domain_defaults($dom,1);
     my @items = ('auth_def','auth_arg_def','lang_def','timezone_def','datelocale_def','portal_def');      my @items = ('auth_def','auth_arg_def','lang_def','timezone_def','datelocale_def',
     my @authtypes = ('internal','krb4','krb5','localauth');                   'portal_def','intauth_cost','intauth_check','intauth_switch');
       my @authtypes = ('internal','krb4','krb5','localauth','lti');
     foreach my $item (@items) {      foreach my $item (@items) {
         $newvalues{$item} = $env{'form.'.$item};          $newvalues{$item} = $env{'form.'.$item};
         if ($item eq 'auth_def') {          if ($item eq 'auth_def') {
Line 11717  sub modify_defaults { Line 14740  sub modify_defaults {
                     push(@errors,$item);                      push(@errors,$item);
                 }                  }
             }              }
           } elsif ($item eq 'intauth_cost') {
               if ($newvalues{$item} ne '') {
                   if ($newvalues{$item} =~ /\D/) {
                       push(@errors,$item);
                   }
               }
           } elsif ($item eq 'intauth_check') {
               if ($newvalues{$item} ne '') {
                   unless ($newvalues{$item} =~ /^(0|1|2)$/) {
                       push(@errors,$item);
                   }
               }
           } elsif ($item eq 'intauth_switch') {
               if ($newvalues{$item} ne '') {
                   unless ($newvalues{$item} =~ /^(0|1|2)$/) {
                       push(@errors,$item);
                   }
               }
         }          }
         if (grep(/^\Q$item\E$/,@errors)) {          if (grep(/^\Q$item\E$/,@errors)) {
             $newvalues{$item} = $domdefaults{$item};              $newvalues{$item} = $domdefaults{$item};
Line 11743  sub modify_defaults { Line 14784  sub modify_defaults {
     }      }
     my @todelete = &Apache::loncommon::get_env_multiple('form.inststatus_delete');      my @todelete = &Apache::loncommon::get_env_multiple('form.inststatus_delete');
     my @allpos;      my @allpos;
     my %guests;  
     my %alltypes;      my %alltypes;
     my ($currtitles,$currguests,$currorder);      my @inststatusguest;
       if (ref($currinststatus->{'inststatusguest'}) eq 'ARRAY') {
           foreach my $type (@{$currinststatus->{'inststatusguest'}}) {
               unless (grep(/^\Q$type\E$/,@todelete)) {
                   push(@inststatusguest,$type);
               }
           }
       }
       my ($currtitles,$currorder);
     if (ref($currinststatus) eq 'HASH') {      if (ref($currinststatus) eq 'HASH') {
         if (ref($currinststatus->{'inststatusorder'}) eq 'ARRAY') {          if (ref($currinststatus->{'inststatusorder'}) eq 'ARRAY') {
             foreach my $type (@{$currinststatus->{'inststatusorder'}}) {              foreach my $type (@{$currinststatus->{'inststatusorder'}}) {
Line 11760  sub modify_defaults { Line 14808  sub modify_defaults {
                     $allpos[$position] = $type;                      $allpos[$position] = $type;
                     $alltypes{$type} = $env{'form.inststatus_title_'.$type};                      $alltypes{$type} = $env{'form.inststatus_title_'.$type};
                     $alltypes{$type} =~ s/`//g;                      $alltypes{$type} =~ s/`//g;
                     if ($env{'form.inststatus_guest_'.$type}) {  
                         $guests{$type} = 1;  
                     }  
                 }                  }
             }              }
             if (ref($currinststatus->{'inststatusguest'}) eq 'ARRAY') {  
                 $currguests = join(',',@{$currinststatus->{'inststatusguest'}});  
             }  
             $currorder = join(',',@{$currinststatus->{'inststatusorder'}});              $currorder = join(',',@{$currinststatus->{'inststatusorder'}});
             $currtitles =~ s/,$//;              $currtitles =~ s/,$//;
         }          }
Line 11776  sub modify_defaults { Line 14818  sub modify_defaults {
         my $newtype = $env{'form.addinststatus'};          my $newtype = $env{'form.addinststatus'};
         $newtype =~ s/\W//g;          $newtype =~ s/\W//g;
         unless (exists($alltypes{$newtype})) {          unless (exists($alltypes{$newtype})) {
             if ($env{'form.addinststatus_guest'}) {  
                 $guests{$newtype} = 1;  
             }  
             $alltypes{$newtype} = $env{'form.addinststatus_title'};              $alltypes{$newtype} = $env{'form.addinststatus_title'};
             $alltypes{$newtype} =~ s/`//g;               $alltypes{$newtype} =~ s/`//g; 
             my $position = $env{'form.addinststatus_pos'};              my $position = $env{'form.addinststatus_pos'};
Line 11788  sub modify_defaults { Line 14827  sub modify_defaults {
             }              }
         }          }
     }      }
     my (@orderedstatus,@orderedguests);      my @orderedstatus;
     foreach my $type (@allpos) {      foreach my $type (@allpos) {
         unless (($type eq '') || (grep(/^\Q$type\E$/,@orderedstatus))) {          unless (($type eq '') || (grep(/^\Q$type\E$/,@orderedstatus))) {
             push(@orderedstatus,$type);              push(@orderedstatus,$type);
             if ($guests{$type}) {  
                 push(@orderedguests,$type);  
             }  
         }          }
     }      }
     foreach my $type (keys(%alltypes)) {      foreach my $type (keys(%alltypes)) {
Line 11805  sub modify_defaults { Line 14841  sub modify_defaults {
     $defaults_hash{'inststatus'} = {      $defaults_hash{'inststatus'} = {
                                      inststatustypes => \%alltypes,                                       inststatustypes => \%alltypes,
                                      inststatusorder => \@orderedstatus,                                       inststatusorder => \@orderedstatus,
                                      inststatusguest => \@orderedguests,                                       inststatusguest => \@inststatusguest,
                                    };                                     };
     if (ref($defaults_hash{'inststatus'}) eq 'HASH') {      if (ref($defaults_hash{'inststatus'}) eq 'HASH') {
         foreach my $item ('inststatustypes','inststatusorder','inststatusguest') {          foreach my $item ('inststatustypes','inststatusorder','inststatusguest') {
Line 11815  sub modify_defaults { Line 14851  sub modify_defaults {
     if ($currorder ne join(',',@orderedstatus)) {      if ($currorder ne join(',',@orderedstatus)) {
         $changes{'inststatus'}{'inststatusorder'} = 1;          $changes{'inststatus'}{'inststatusorder'} = 1;
     }      }
     if ($currguests ne join(',',@orderedguests)) {  
         $changes{'inststatus'}{'inststatusguest'} = 1;  
     }  
     my $newtitles;      my $newtitles;
     foreach my $item (@orderedstatus) {      foreach my $item (@orderedstatus) {
         $newtitles .= $alltypes{$item}.',';          $newtitles .= $alltypes{$item}.',';
Line 11836  sub modify_defaults { Line 14869  sub modify_defaults {
             foreach my $item (sort(keys(%changes))) {              foreach my $item (sort(keys(%changes))) {
                 if ($item eq 'inststatus') {                  if ($item eq 'inststatus') {
                     if (ref($changes{'inststatus'}) eq 'HASH') {                      if (ref($changes{'inststatus'}) eq 'HASH') {
                         if (($changes{'inststatus'}{'inststatustypes'}) || $changes{'inststatus'}{'inststatusorder'}) {                          if (@orderedstatus) {
                             $resulttext .= '<li>'.&mt('Institutional user status types set to:').' ';                              $resulttext .= '<li>'.&mt('Institutional user status types set to:').' ';
                             foreach my $type (@orderedstatus) {                               foreach my $type (@orderedstatus) { 
                                 $resulttext .= $alltypes{$type}.', ';                                  $resulttext .= $alltypes{$type}.', ';
                             }                              }
                             $resulttext =~ s/, $//;                              $resulttext =~ s/, $//;
                             $resulttext .= '</li>';                              $resulttext .= '</li>';
                         }                          } else {
                         if ($changes{'inststatus'}{'inststatusguest'}) {                              $resulttext .= '<li>'.&mt('Institutional user status types deleted').'</li>'; 
                             $resulttext .= '<li>';   
                             if (@orderedguests) {  
                                 $resulttext .= &mt('Types assignable to "non-institutional" usernames set to:').' ';  
                                 foreach my $type (@orderedguests) {  
                                     $resulttext .= $alltypes{$type}.', ';  
                                 }  
                                 $resulttext =~ s/, $//;  
                             } else {  
                                 $resulttext .= &mt('Types assignable to "non-institutional" usernames set to none.');  
                             }  
                             $resulttext .= '</li>';  
                         }                          }
                     }                      }
                 } else {                  } else {
Line 11869  sub modify_defaults { Line 14891  sub modify_defaults {
                                           krb4       => 'krb4',                                            krb4       => 'krb4',
                                           krb5       => 'krb5',                                            krb5       => 'krb5',
                                           localauth  => 'loc',                                            localauth  => 'loc',
                                             lti        => 'lti',
                         );                          );
                         $value = $authnames{$shortauth{$value}};                          $value = $authnames{$shortauth{$value}};
                       } elsif ($item eq 'intauth_switch') {
                           my %optiondesc = &Apache::lonlocal::texthash (
                                               0 => 'No',
                                               1 => 'Yes',
                                               2 => 'Yes, and copy existing passwd file to passwd.bak file',
                                            );
                           if ($value =~ /^(0|1|2)$/) {
                               $value = $optiondesc{$value};
                           } else {
                               $value = &mt('none -- defaults to No');
                           }
                       } elsif ($item eq 'intauth_check') {
                           my %optiondesc = &Apache::lonlocal::texthash (
                                                0 => 'No',
                                                1 => 'Yes, allow login then update passwd file using default cost (if higher)',
                                                2 => 'Yes, disallow login if stored cost is less than domain default',
                                            );
                           if ($value =~ /^(0|1|2)$/) {
                               $value = $optiondesc{$value};
                           } else {
                               $value = &mt('none -- defaults to No');
                           }
                     }                      }
                     $resulttext .= '<li>'.&mt('[_1] set to "[_2]"',$title->{$item},$value).'</li>';                      $resulttext .= '<li>'.&mt('[_1] set to "[_2]"',$title->{$item},$value).'</li>';
                     $mailmsgtext .= "$title->{$item} set to $value\n";                        $mailmsgtext .= "$title->{$item} set to $value\n";  
Line 12455  sub modify_helpsettings { Line 15500  sub modify_helpsettings {
     my %existing=&Apache::lonnet::dump('roles',$dom,$confname,'rolesdef_');      my %existing=&Apache::lonnet::dump('roles',$dom,$confname,'rolesdef_');
     my (@allpos,%newsettings,%changedprivs,$newrole);      my (@allpos,%newsettings,%changedprivs,$newrole);
     my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom);      my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom);
     my @accesstypes = ('all','none','status','inc','exc');      my @accesstypes = ('all','dh','da','none','status','inc','exc');
     my %domhelpdesk = &Apache::lonnet::get_active_domroles($dom,['dh']);      my %domhelpdesk = &Apache::lonnet::get_active_domroles($dom,['dh','da']);
     my %lt = &Apache::lonlocal::texthash(      my %lt = &Apache::lonlocal::texthash(
                     s      => 'system',                      s      => 'system',
                     d      => 'domain',                      d      => 'domain',
                     order  => 'Display order',                      order  => 'Display order',
                     access => 'Role usage',                      access => 'Role usage',
                     all    => 'All',                      all    => 'All with domain helpdesk or helpdesk assistant role',
                       dh     => 'All with domain helpdesk role',
                       da     => 'All with domain helpdesk assistant role',
                     none   => 'None',                      none   => 'None',
                     status => 'Determined based on institutional status',                      status => 'Determined based on institutional status',
                     inc    => 'Include all, but exclude specific personnel',                      inc    => 'Include all, but exclude specific personnel',
Line 12498  sub modify_helpsettings { Line 15545  sub modify_helpsettings {
             $identifier = 'custhelp'.$num;              $identifier = 'custhelp'.$num;
             my %newprivs = &Apache::lonuserutils::custom_role_update($rolename,$identifier);              my %newprivs = &Apache::lonuserutils::custom_role_update($rolename,$identifier);
             my %currprivs;              my %currprivs;
             ($currprivs{'s'},$currprivs{'d'},$currprivs{'c'}) =               ($currprivs{'s'},$currprivs{'d'},$currprivs{'c'}) =
                 split(/\_/,$existing{'rolesdef_'.$rolename});                  split(/\_/,$existing{'rolesdef_'.$rolename});
             foreach my $level ('c','d','s') {              foreach my $level ('c','d','s') {
                 if ($newprivs{$level} ne $currprivs{$level}) {                  if ($newprivs{$level} ne $currprivs{$level}) {
Line 12540  sub modify_helpsettings { Line 15587  sub modify_helpsettings {
             if ($access eq 'status') {              if ($access eq 'status') {
                 my @statuses = &Apache::loncommon::get_env_multiple('form.'.$prefix.'_status');                  my @statuses = &Apache::loncommon::get_env_multiple('form.'.$prefix.'_status');
                 if (scalar(@statuses) == 0) {                  if (scalar(@statuses) == 0) {
                     $helphash{'helpsettings'}{'adhoc'}{$rolename}{'access'} = 'none';                       $helphash{'helpsettings'}{'adhoc'}{$rolename}{'access'} = 'none';
                 } else {                  } else {
                     my (@shownstatus,$numtypes);                      my (@shownstatus,$numtypes);
                     $helphash{'helpsettings'}{'adhoc'}{$rolename}{$access} = [];                      $helphash{'helpsettings'}{'adhoc'}{$rolename}{$access} = [];
Line 12613  sub modify_helpsettings { Line 15660  sub modify_helpsettings {
                     if (ref($current{'adhoc'}{$rolename}) eq 'HASH') {                      if (ref($current{'adhoc'}{$rolename}) eq 'HASH') {
                         if ($current{'adhoc'}{$rolename}{'order'} ne $idx) {                          if ($current{'adhoc'}{$rolename}{'order'} ne $idx) {
                             $changes{'customrole'}{$rolename}{'order'} = 1;                              $changes{'customrole'}{$rolename}{'order'} = 1;
                             $newsettings{$rolename}{'order'} = $idx+1;                               $newsettings{$rolename}{'order'} = $idx+1;
                         }                          }
                     }                      }
                 }                  }
Line 12659  sub modify_helpsettings { Line 15706  sub modify_helpsettings {
                                                                    order  => 'Order',                                                                     order  => 'Order',
                                                                    desc   => 'Role description',                                                                     desc   => 'Role description',
                                                                    access => 'Role usage',                                                                     access => 'Role usage',
                                                                    status => 'Allowed instituional types',                                                                     status => 'Allowed institutional types',
                                                                    exc    => 'Allowed personnel',                                                                     exc    => 'Allowed personnel',
                                                                    inc    => 'Disallowed personnel',                                                                     inc    => 'Disallowed personnel',
                         );                          );
Line 12758  sub modify_coursedefaults { Line 15805  sub modify_coursedefaults {
                            postsubmit           => 60,                             postsubmit           => 60,
                            mysqltables          => 172800,                             mysqltables          => 172800,
                          );                           );
       my %texoptions = (
                           MathJax  => 'MathJax',
                           mimetex  => &mt('Convert to Images'),
                           tth      => &mt('TeX to HTML'),
                        );
     $defaultshash{'coursedefaults'} = {};      $defaultshash{'coursedefaults'} = {};
   
     if (ref($domconfig{'coursedefaults'}) ne 'HASH') {      if (ref($domconfig{'coursedefaults'}) ne 'HASH') {
Line 12811  sub modify_coursedefaults { Line 15862  sub modify_coursedefaults {
                         $changes{$item} = 1;                          $changes{$item} = 1;
                     }                      }
                 } elsif ($item =~ /^(uploadquota|mysqltables)_/) {                  } elsif ($item =~ /^(uploadquota|mysqltables)_/) {
                     my $setting = $1;                       my $setting = $1;
                     unless (($currdef eq '') && ($newdef == $staticdefaults{$setting})) {                      unless (($currdef eq '') && ($newdef == $staticdefaults{$setting})) {
                         $changes{$setting} = 1;                          $changes{$setting} = 1;
                     }                      }
                 }                  }
             }              }
         }          }
           my $texengine;
           if ($env{'form.texengine'} =~ /^(MathJax|mimetex|tth)$/) {
               $texengine = $env{'form.texengine'};
               if ($defaultshash{'coursedefaults'}{'texengine'} eq '') {
                   unless ($texengine eq 'MathJax') {
                       $changes{'texengine'} = 1;
                   }
               } elsif ($defaultshash{'coursedefaults'}{'texengine'} ne $texengine) {
                   $changes{'texengine'} = 1;
               }
           }
           if ($texengine ne '') {
               $defaultshash{'coursedefaults'}{'texengine'} = $texengine;
           }
         my $currclone = $domconfig{'coursedefaults'}{'canclone'};          my $currclone = $domconfig{'coursedefaults'}{'canclone'};
         my @currclonecode;          my @currclonecode;
         if (ref($currclone) eq 'HASH') {          if (ref($currclone) eq 'HASH') {
Line 12826  sub modify_coursedefaults { Line 15891  sub modify_coursedefaults {
             }              }
         }          }
         my $newclone;          my $newclone;
         if ($env{'form.canclone'} =~ /^(none|domain|instcode)$/) {           if ($env{'form.canclone'} =~ /^(none|domain|instcode)$/) {
             $newclone = $env{'form.canclone'};              $newclone = $env{'form.canclone'};
         }          }
         if ($newclone eq 'instcode') {          if ($newclone eq 'instcode') {
Line 12849  sub modify_coursedefaults { Line 15914  sub modify_coursedefaults {
                 $newclone eq '';                  $newclone eq '';
             }              }
         } elsif ($newclone ne '') {          } elsif ($newclone ne '') {
             $defaultshash{'coursedefaults'}{'canclone'} = $newclone;               $defaultshash{'coursedefaults'}{'canclone'} = $newclone;
         }           }
         if ($newclone ne $currclone) {          if ($newclone ne $currclone) {
             $changes{'canclone'} = 1;              $changes{'canclone'} = 1;
         }          }
Line 12868  sub modify_coursedefaults { Line 15933  sub modify_coursedefaults {
                 $defaultshash{'coursedefaults'}{'coursecredits'}{$type} = $credits{$type};                  $defaultshash{'coursedefaults'}{'coursecredits'}{$type} = $credits{$type};
             }              }
         } else {          } else {
             if ($env{'form.coursecredits'} eq '1') {               if ($env{'form.coursecredits'} eq '1') {
                 foreach my $type (@types) {                  foreach my $type (@types) {
                     unless ($type eq 'community') {                      unless ($type eq 'community') {
                         if ($domconfig{'coursedefaults'}{'coursecredits'}{$type} ne $credits{$type}) {                                  if ($domconfig{'coursedefaults'}{'coursecredits'}{$type} ne $credits{$type}) {
                             $changes{'coursecredits'} = 1;                              $changes{'coursecredits'} = 1;
                         }                          }
                         $defaultshash{'coursedefaults'}{'coursecredits'}{$type} = $credits{$type};                          $defaultshash{'coursedefaults'}{'coursecredits'}{$type} = $credits{$type};
Line 12914  sub modify_coursedefaults { Line 15979  sub modify_coursedefaults {
                 }                  }
                 if (exists($currtimeout{$type})) {                  if (exists($currtimeout{$type})) {
                     if ($timeout ne $currtimeout{$type}) {                      if ($timeout ne $currtimeout{$type}) {
                         $changes{'postsubmit'} = 1;                           $changes{'postsubmit'} = 1;
                     }                      }
                 } elsif ($timeout ne '') {                  } elsif ($timeout ne '') {
                     $changes{'postsubmit'} = 1;                      $changes{'postsubmit'} = 1;
Line 12938  sub modify_coursedefaults { Line 16003  sub modify_coursedefaults {
             my %domdefaults = &Apache::lonnet::get_domain_defaults($dom,1);              my %domdefaults = &Apache::lonnet::get_domain_defaults($dom,1);
             if (($changes{'canuse_pdfforms'}) || ($changes{'uploadquota'}) || ($changes{'postsubmit'}) ||              if (($changes{'canuse_pdfforms'}) || ($changes{'uploadquota'}) || ($changes{'postsubmit'}) ||
                 ($changes{'coursecredits'}) || ($changes{'uselcmath'}) || ($changes{'usejsme'}) ||                  ($changes{'coursecredits'}) || ($changes{'uselcmath'}) || ($changes{'usejsme'}) ||
                 ($changes{'canclone'}) || ($changes{'mysqltables'})) {                  ($changes{'canclone'}) || ($changes{'mysqltables'}) || ($changes{'texengine'})) {
                 foreach my $item ('canuse_pdfforms','uselcmath','usejsme') {                   foreach my $item ('canuse_pdfforms','uselcmath','usejsme','texengine') {
                     if ($changes{$item}) {                      if ($changes{$item}) {
                         $domdefaults{$item}=$defaultshash{'coursedefaults'}{$item};                          $domdefaults{$item}=$defaultshash{'coursedefaults'}{$item};
                     }                      }
                 }                   }
                 if ($changes{'coursecredits'}) {                  if ($changes{'coursecredits'}) {
                     if (ref($defaultshash{'coursedefaults'}{'coursecredits'}) eq 'HASH') {                      if (ref($defaultshash{'coursedefaults'}{'coursecredits'}) eq 'HASH') {
                         foreach my $type (keys(%{$defaultshash{'coursedefaults'}{'coursecredits'}})) {                          foreach my $type (keys(%{$defaultshash{'coursedefaults'}{'coursecredits'}})) {
Line 13006  sub modify_coursedefaults { Line 16071  sub modify_coursedefaults {
                     if ($env{'form.'.$item} eq '1') {                      if ($env{'form.'.$item} eq '1') {
                         $resulttext .= '<li>'.&mt('Molecule editor uses JSME (HTML5), if supported by browser.').'</li>';                          $resulttext .= '<li>'.&mt('Molecule editor uses JSME (HTML5), if supported by browser.').'</li>';
                     } else {                      } else {
                         $resulttext .= '<li>'.&mt('Molecule editor uses JME (Java), if supported by client OS.').'</li>';                           $resulttext .= '<li>'.&mt('Molecule editor uses JME (Java), if supported by client OS.').'</li>';
                       }
                   } elsif ($item eq 'texengine') {
                       if ($defaultshash{'coursedefaults'}{'texengine'} ne '') {
                           $resulttext .= '<li>'.&mt('Default method to display mathematics set to: "[_1]"',
                                                     $texoptions{$defaultshash{'coursedefaults'}{'texengine'}}).'</li>';
                     }                      }
                 } elsif ($item eq 'anonsurvey_threshold') {                  } elsif ($item eq 'anonsurvey_threshold') {
                     $resulttext .= '<li>'.&mt('Responder count required for display of anonymous survey submissions set to [_1].',$defaultshash{'coursedefaults'}{'anonsurvey_threshold'}).'</li>';                      $resulttext .= '<li>'.&mt('Responder count required for display of anonymous survey submissions set to [_1].',$defaultshash{'coursedefaults'}{'anonsurvey_threshold'}).'</li>';
Line 13041  sub modify_coursedefaults { Line 16111  sub modify_coursedefaults {
                         $resulttext .= '<li>'.&mt('Submit button(s) remain enabled on page after student makes submission.');                          $resulttext .= '<li>'.&mt('Submit button(s) remain enabled on page after student makes submission.');
                     } else {                      } else {
                         $resulttext .= '<li>'.&mt('Submit button(s) disabled on page after student makes submission').'; ';                          $resulttext .= '<li>'.&mt('Submit button(s) disabled on page after student makes submission').'; ';
                         if (ref($defaultshash{'coursedefaults'}{'postsubmit'}) eq 'HASH') {                           if (ref($defaultshash{'coursedefaults'}{'postsubmit'}) eq 'HASH') {
                             $resulttext .= &mt('durations:').'<ul>';                              $resulttext .= &mt('durations:').'<ul>';
                             foreach my $type (@types) {                              foreach my $type (@types) {
                                 $resulttext .= '<li>';                                  $resulttext .= '<li>';
Line 13072  sub modify_coursedefaults { Line 16142  sub modify_coursedefaults {
                             }                              }
                             $resulttext .= '</ul>';                              $resulttext .= '</ul>';
                         }                          }
                         $resulttext .= '</li>';                              $resulttext .= '</li>';
                     }                      }
                 } elsif ($item eq 'coursecredits') {                  } elsif ($item eq 'coursecredits') {
                     if (ref($defaultshash{'coursedefaults'}{'coursecredits'}) eq 'HASH') {                      if (ref($defaultshash{'coursedefaults'}{'coursecredits'}) eq 'HASH') {
Line 13100  sub modify_coursedefaults { Line 16170  sub modify_coursedefaults {
                     } elsif ($defaultshash{'coursedefaults'}{'canclone'} eq 'domain') {                      } elsif ($defaultshash{'coursedefaults'}{'canclone'} eq 'domain') {
                         $resulttext .= '<li>'.&mt('By default, a course requester can clone any course from his/her domain.').'</li>';                          $resulttext .= '<li>'.&mt('By default, a course requester can clone any course from his/her domain.').'</li>';
                     } else {                      } else {
                         $resulttext .= '<li>'.&mt('By default, only course owner and coordinators may clone a course.').'</li>';                           $resulttext .= '<li>'.&mt('By default, only course owner and coordinators may clone a course.').'</li>';
                     }                      }
                 }                  }
             }              }
Line 13335  sub modify_selfenrollment { Line 16405  sub modify_selfenrollment {
                         $resulttext .= '</ul></li>';                           $resulttext .= '</ul></li>'; 
                     }                      }
                 }                  }
                 if ((exists($changes{'admin'})) || (exists($changes{'default'}))) {              }
                     my $cachetime = 24*60*60;              if ((exists($changes{'admin'})) || (exists($changes{'default'}))) {
                     &Apache::lonnet::do_cache_new('domdefaults',$dom,\%domdefaults,$cachetime);                  my $cachetime = 24*60*60;
                     if (ref($lastactref) eq 'HASH') {                  &Apache::lonnet::do_cache_new('domdefaults',$dom,\%domdefaults,$cachetime);
                         $lastactref->{'domdefaults'} = 1;                  if (ref($lastactref) eq 'HASH') {
                     }                      $lastactref->{'domdefaults'} = 1;
                 }                  }
             }              }
             $resulttext .= '</ul>';              $resulttext .= '</ul>';
Line 13555  sub modify_usersessions { Line 16625  sub modify_usersessions {
                 }                  }
             }              }
             unless ($changes{'offloadnow'}) {              unless ($changes{'offloadnow'}) {
                 foreach my $lonhost (keys(%{$defaultshash{'usersessions'}{'offloadnow'}})) {                   foreach my $lonhost (keys(%{$defaultshash{'usersessions'}{'offloadnow'}})) {
                     unless ($domconfig{'usersessions'}{'offloadnow'}{$lonhost}) {                      unless ($domconfig{'usersessions'}{'offloadnow'}{$lonhost}) {
                         $changes{'offloadnow'} = 1;                          $changes{'offloadnow'} = 1;
                         last;                          last;
Line 13586  sub modify_usersessions { Line 16656  sub modify_usersessions {
             }              }
             my $cachetime = 24*60*60;              my $cachetime = 24*60*60;
             &Apache::lonnet::do_cache_new('domdefaults',$dom,\%domdefaults,$cachetime);              &Apache::lonnet::do_cache_new('domdefaults',$dom,\%domdefaults,$cachetime);
               &Apache::lonnet::do_cache_new('usersessions',$dom,$defaultshash{'usersessions'},3600);
             if (ref($lastactref) eq 'HASH') {              if (ref($lastactref) eq 'HASH') {
                 $lastactref->{'domdefaults'} = 1;                  $lastactref->{'domdefaults'} = 1;
                   $lastactref->{'usersessions'} = 1;
             }              }
             if (keys(%changes) > 0) {              if (keys(%changes) > 0) {
                 my %lt = &usersession_titles();                  my %lt = &usersession_titles();
Line 13621  sub modify_usersessions { Line 16693  sub modify_usersessions {
                         } else {                          } else {
                             foreach my $type (@{$types{$prefix}}) {                              foreach my $type (@{$types{$prefix}}) {
                                 if (defined($changes{$prefix}{$type})) {                                  if (defined($changes{$prefix}{$type})) {
                                     my $newvalue;                                      my ($newvalue,$notinuse);
                                     if (ref($defaultshash{'usersessions'}) eq 'HASH') {                                      if (ref($defaultshash{'usersessions'}) eq 'HASH') {
                                         if (ref($defaultshash{'usersessions'}{$prefix})) {                                          if (ref($defaultshash{'usersessions'}{$prefix})) {
                                             if ($type eq 'version') {                                              if ($type eq 'version') {
                                                 $newvalue = $defaultshash{'usersessions'}{$prefix}{$type};                                                  $newvalue = $defaultshash{'usersessions'}{$prefix}{$type};
                                             } elsif (ref($defaultshash{'usersessions'}{$prefix}{$type}) eq 'ARRAY') {                                              } else {
                                                 if (@{$defaultshash{'usersessions'}{$prefix}{$type}} > 0) {                                                  if (ref($defaultshash{'usersessions'}{$prefix}{$type}) eq 'ARRAY') {
                                                     $newvalue = join(', ',@{$defaultshash{'usersessions'}{$prefix}{$type}});                                                      if (@{$defaultshash{'usersessions'}{$prefix}{$type}} > 0) {
                                                           $newvalue = join(', ',@{$defaultshash{'usersessions'}{$prefix}{$type}});
                                                       }
                                                   } else {
                                                       $notinuse = 1;
                                                 }                                                  }
                                             }                                              }
                                         }                                          }
Line 13636  sub modify_usersessions { Line 16712  sub modify_usersessions {
                                     if ($newvalue eq '') {                                      if ($newvalue eq '') {
                                         if ($type eq 'version') {                                          if ($type eq 'version') {
                                             $resulttext .= '<li>'.&mt('[_1] set to: off',$lt{$type}).'</li>';                                              $resulttext .= '<li>'.&mt('[_1] set to: off',$lt{$type}).'</li>';
                                           } elsif ($notinuse) {
                                               $resulttext .= '<li>'.&mt('[_1] set to: not in use',$lt{$type}).'</li>';
                                         } else {                                          } else {
                                             $resulttext .= '<li>'.&mt('[_1] set to: none',$lt{$type}).'</li>';                                              $resulttext .= '<li>'.&mt('[_1] set to: none',$lt{$type}).'</li>';
                                         }                                          }
                                     } else {                                      } else {
                                         if ($type eq 'version') {                                          if ($type eq 'version') {
                                             $newvalue .= ' '.&mt('(or later)');                                               $newvalue .= ' '.&mt('(or later)');
                                         }                                          }
                                         $resulttext .= '<li>'.&mt('[_1] set to: [_2].',$lt{$type},$newvalue).'</li>';                                          $resulttext .= '<li>'.&mt('[_1] set to: [_2].',$lt{$type},$newvalue).'</li>';
                                     }                                      }
Line 13688  sub modify_ssl { Line 16766  sub modify_ssl {
     my %servers = &Apache::lonnet::internet_dom_servers($dom);      my %servers = &Apache::lonnet::internet_dom_servers($dom);
     my (%defaultshash,%changes);      my (%defaultshash,%changes);
     my $action = 'ssl';      my $action = 'ssl';
     my @prefixes = ('connect','replication');      my @prefixes = ('connto','connfrom','replication');
     foreach my $prefix (@prefixes) {      foreach my $prefix (@prefixes) {
         $defaultshash{$action}{$prefix} = {};          $defaultshash{$action}{$prefix} = {};
     }      }
Line 13698  sub modify_ssl { Line 16776  sub modify_ssl {
     my @reptypes = ('certreq','nocertreq');      my @reptypes = ('certreq','nocertreq');
     my @connecttypes = ('dom','intdom','other');      my @connecttypes = ('dom','intdom','other');
     my %types = (      my %types = (
                   connect      => \@connecttypes,                    connto      => \@connecttypes,
                   replication  => \@reptypes,                    connfrom    => \@connecttypes,
                     replication => \@reptypes,
                 );                  );
     foreach my $prefix (sort(keys(%types))) {      foreach my $prefix (sort(keys(%types))) {
         foreach my $type (@{$types{$prefix}}) {          foreach my $type (@{$types{$prefix}}) {
             if ($prefix eq 'connect') {              if (($prefix eq 'connto') || ($prefix eq 'connfrom')) {
                 my $value = 'yes';                  my $value = 'yes';
                 if ($env{'form.'.$prefix.'_'.$type} =~ /^(no|req)$/) {                  if ($env{'form.'.$prefix.'_'.$type} =~ /^(no|req)$/) {
                     $value = $env{'form.'.$prefix.'_'.$type};                      $value = $env{'form.'.$prefix.'_'.$type};
                 }                  }
                 if (ref($domconfig{$action}{$prefix}) eq 'HASH') {                  if (ref($domconfig{$action}) eq 'HASH') {
                     if ($domconfig{$action}{$prefix}{$type} ne '') {                      if (ref($domconfig{$action}{$prefix}) eq 'HASH') {
                         if ($value ne $domconfig{$action}{$prefix}{$type}) {                          if ($domconfig{$action}{$prefix}{$type} ne '') {
                               if ($value ne $domconfig{$action}{$prefix}{$type}) {
                                   $changes{$prefix}{$type} = 1;
                               }
                               $defaultshash{$action}{$prefix}{$type} = $value;
                           } else {
                               $defaultshash{$action}{$prefix}{$type} = $value;
                             $changes{$prefix}{$type} = 1;                              $changes{$prefix}{$type} = 1;
                         }                          }
                         $defaultshash{$action}{$prefix}{$type} = $value;  
                     } else {                      } else {
                         $defaultshash{$action}{$prefix}{$type} = $value;                          $defaultshash{$action}{$prefix}{$type} = $value;
                         $changes{$prefix}{$type} = 1;                          $changes{$prefix}{$type} = 1;
Line 13783  sub modify_ssl { Line 16867  sub modify_ssl {
             }              }
         }          }
     }      }
       if (keys(%changes)) {
           foreach my $prefix (keys(%changes)) {
               if (ref($changes{$prefix}) eq 'HASH') {
                   if (scalar(keys(%{$changes{$prefix}})) == 0) {
                       delete($changes{$prefix});
                   }
               } else {
                   delete($changes{$prefix});
               }
           }
       }
     my $nochgmsg = &mt('No changes made to LON-CAPA SSL settings');      my $nochgmsg = &mt('No changes made to LON-CAPA SSL settings');
     if (keys(%changes) > 0) {      if (keys(%changes) > 0) {
         my $putresult = &Apache::lonnet::put_dom('configuration',\%defaultshash,          my $putresult = &Apache::lonnet::put_dom('configuration',\%defaultshash,
Line 13792  sub modify_ssl { Line 16887  sub modify_ssl {
                 if (ref($defaultshash{$action}{'replication'}) eq 'HASH') {                  if (ref($defaultshash{$action}{'replication'}) eq 'HASH') {
                     $domdefaults{'replication'} = $defaultshash{$action}{'replication'};                      $domdefaults{'replication'} = $defaultshash{$action}{'replication'};
                 }                  }
                 if (ref($defaultshash{$action}{'connect'}) eq 'HASH') {                  if (ref($defaultshash{$action}{'connto'}) eq 'HASH') {
                     $domdefaults{'connect'} = $domconfig{$action}{'connect'};                      $domdefaults{'connto'} = $defaultshash{$action}{'connto'};
                   }
                   if (ref($defaultshash{$action}{'connfrom'}) eq 'HASH') {
                       $domdefaults{'connfrom'} = $defaultshash{$action}{'connfrom'};
                 }                  }
             }              }
             my $cachetime = 24*60*60;              my $cachetime = 24*60*60;
Line 13809  sub modify_ssl { Line 16907  sub modify_ssl {
                         $resulttext .= '<li>'.$titles{$prefix}.'<ul>';                          $resulttext .= '<li>'.$titles{$prefix}.'<ul>';
                         foreach my $type (@{$types{$prefix}}) {                          foreach my $type (@{$types{$prefix}}) {
                             if (defined($changes{$prefix}{$type})) {                              if (defined($changes{$prefix}{$type})) {
                                 my $newvalue;                                  my ($newvalue,$notinuse);
                                 if (ref($defaultshash{$action}) eq 'HASH') {                                  if (ref($defaultshash{$action}) eq 'HASH') {
                                     if (ref($defaultshash{$action}{$prefix})) {                                      if (ref($defaultshash{$action}{$prefix})) {
                                         if ($prefix eq 'connect') {                                          if (($prefix eq 'connto') || ($prefix eq 'connfrom')) {
                                             $newvalue = $titles{$defaultshash{$action}{$prefix}{$type}};                                              $newvalue = $titles{$defaultshash{$action}{$prefix}{$type}};
                                         } elsif (ref($defaultshash{$action}{$prefix}{$type}) eq 'ARRAY') {                                          } else {
                                             if (@{$defaultshash{$action}{$prefix}{$type}} > 0) {                                              if (ref($defaultshash{$action}{$prefix}{$type}) eq 'ARRAY') {
                                                 $newvalue = join(', ',@{$defaultshash{$action}{$prefix}{$type}});                                                  if (@{$defaultshash{$action}{$prefix}{$type}} > 0) {
                                                       $newvalue = join(', ',@{$defaultshash{$action}{$prefix}{$type}});
                                                   }
                                               } else {
                                                   $notinuse = 1;
                                             }                                              }
                                         }                                          }
                                     }                                      }
                                     if ($newvalue eq '') {                                      if ($notinuse) {
                                           $resulttext .= '<li>'.&mt('[_1] set to: not in use',$titles{$type}).'</li>';
                                       } elsif ($newvalue eq '') {
                                         $resulttext .= '<li>'.&mt('[_1] set to: none',$titles{$type}).'</li>';                                          $resulttext .= '<li>'.&mt('[_1] set to: none',$titles{$type}).'</li>';
                                     } else {                                      } else {
                                         $resulttext .= '<li>'.&mt('[_1] set to: [_2].',$titles{$type},$newvalue).'</li>';                                          $resulttext .= '<li>'.&mt('[_1] set to: [_2].',$titles{$type},$newvalue).'</li>';
Line 13934  sub modify_trust { Line 17038  sub modify_trust {
                         $resulttext .= '<li>'.$lt{$prefix}.'<ul>';                          $resulttext .= '<li>'.$lt{$prefix}.'<ul>';
                         foreach my $type (@types) {                          foreach my $type (@types) {
                             if (defined($changes{$prefix}{$type})) {                              if (defined($changes{$prefix}{$type})) {
                                 my $newvalue;                                  my ($newvalue,$notinuse);
                                 if (ref($defaultshash{'trust'}) eq 'HASH') {                                  if (ref($defaultshash{'trust'}) eq 'HASH') {
                                     if (ref($defaultshash{'trust'}{$prefix})) {                                      if (ref($defaultshash{'trust'}{$prefix})) {
                                         if (ref($defaultshash{'trust'}{$prefix}{$type}) eq 'ARRAY') {                                          if (ref($defaultshash{'trust'}{$prefix}{$type}) eq 'ARRAY') {
                                             if (@{$defaultshash{'trust'}{$prefix}{$type}} > 0) {                                              if (@{$defaultshash{'trust'}{$prefix}{$type}} > 0) {
                                                 $newvalue = join(', ',@{$defaultshash{'trust'}{$prefix}{$type}});                                                  $newvalue = join(', ',@{$defaultshash{'trust'}{$prefix}{$type}});
                                             }                                              }
                                           } else {
                                               $notinuse = 1;
                                         }                                          }
                                     }                                      }
                                 }                                  }
                                 if ($newvalue eq '') {                                  if ($notinuse) {
                                       $resulttext .= '<li>'.&mt('[_1] set to: not in use',$lt{$type}).'</li>';
                                   } elsif ($newvalue eq '') {
                                     $resulttext .= '<li>'.&mt('[_1] set to: none',$lt{$type}).'</li>';                                      $resulttext .= '<li>'.&mt('[_1] set to: none',$lt{$type}).'</li>';
                                 } else {                                  } else {
                                     $resulttext .= '<li>'.&mt('[_1] set to: [_2].',$lt{$type},$newvalue).'</li>';                                      $resulttext .= '<li>'.&mt('[_1] set to: [_2].',$lt{$type},$newvalue).'</li>';
Line 13979  sub modify_loadbalancing { Line 17087  sub modify_loadbalancing {
     my @sparestypes = ('primary','default');      my @sparestypes = ('primary','default');
     my %typetitles = &sparestype_titles();      my %typetitles = &sparestype_titles();
     my $resulttext;      my $resulttext;
     my (%currbalancer,%currtargets,%currrules,%existing);      my (%currbalancer,%currtargets,%currrules,%existing,%currcookies);
     if (ref($domconfig{'loadbalancing'}) eq 'HASH') {      if (ref($domconfig{'loadbalancing'}) eq 'HASH') {
         %existing = %{$domconfig{'loadbalancing'}};          %existing = %{$domconfig{'loadbalancing'}};
     }      }
     &get_loadbalancers_config(\%servers,\%existing,\%currbalancer,      &get_loadbalancers_config(\%servers,\%existing,\%currbalancer,
                               \%currtargets,\%currrules);                                \%currtargets,\%currrules,\%currcookies);
     my ($saveloadbalancing,%defaultshash,%changes);      my ($saveloadbalancing,%defaultshash,%changes);
     my ($alltypes,$othertypes,$titles) =      my ($alltypes,$othertypes,$titles) =
         &loadbalancing_titles($dom,$intdom,$usertypes,$types);          &loadbalancing_titles($dom,$intdom,$usertypes,$types);
Line 14036  sub modify_loadbalancing { Line 17144  sub modify_loadbalancing {
             }              }
             $defaultshash{'loadbalancing'}{$balancer}{'targets'}{$sparetype} = \@offloadto;              $defaultshash{'loadbalancing'}{$balancer}{'targets'}{$sparetype} = \@offloadto;
         }          }
           if ($env{'form.loadbalancing_cookie_'.$i}) {
               $defaultshash{'loadbalancing'}{$balancer}{'cookie'} = 1;
               if (exists($currbalancer{$balancer})) { 
                   unless ($currcookies{$balancer}) {
                       $changes{'curr'}{$balancer}{'cookie'} = 1;
                   }
               }
           } elsif (exists($currbalancer{$balancer})) {
               if ($currcookies{$balancer}) {
                   $changes{'curr'}{$balancer}{'cookie'} = 1;
               }
           }
         if (ref($currtargets{$balancer}) eq 'HASH') {          if (ref($currtargets{$balancer}) eq 'HASH') {
             foreach my $sparetype (@sparestypes) {              foreach my $sparetype (@sparestypes) {
                 if (ref($currtargets{$balancer}{$sparetype}) eq 'ARRAY') {                  if (ref($currtargets{$balancer}{$sparetype}) eq 'ARRAY') {
Line 14073  sub modify_loadbalancing { Line 17193  sub modify_loadbalancing {
                 }                  }
                 if ($rule eq 'specific') {                  if ($rule eq 'specific') {
                     my $specifiedhost = $env{'form.loadbalancing_singleserver_'.$i.'_'.$type};                      my $specifiedhost = $env{'form.loadbalancing_singleserver_'.$i.'_'.$type};
                     if (exists($servers{$specifiedhost})) {                       if (exists($servers{$specifiedhost})) {
                         $rule = $specifiedhost;                          $rule = $specifiedhost;
                     }                      }
                 }                  }
Line 14149  sub modify_loadbalancing { Line 17269  sub modify_loadbalancing {
                                         if ($rule eq '') {                                          if ($rule eq '') {
                                             $balancetext =  $ruletitles{'default'};                                              $balancetext =  $ruletitles{'default'};
                                         } elsif (($rule eq 'homeserver') || ($rule eq 'externalbalancer') ||                                          } elsif (($rule eq 'homeserver') || ($rule eq 'externalbalancer') ||
                                                  ($type eq '_LC_ipchange') || ($type eq '_LC_ipchangesso')) {                                                    ($type eq '_LC_ipchange') || ($type eq '_LC_ipchangesso')) {
                                             if (($type eq '_LC_ipchange') || ($type eq '_LC_ipchangesso')) {                                              if (($type eq '_LC_ipchange') || ($type eq '_LC_ipchangesso')) {
                                                 foreach my $sparetype (@sparestypes) {                                                  foreach my $sparetype (@sparestypes) {
                                                     if (ref($defaultshash{'loadbalancing'}{$balancer}{'targets'}{$sparetype}) eq 'ARRAY') {                                                      if (ref($defaultshash{'loadbalancing'}{$balancer}{'targets'}{$sparetype}) eq 'ARRAY') {
Line 14189  sub modify_loadbalancing { Line 17309  sub modify_loadbalancing {
                                 }                                  }
                             }                              }
                         }                          }
                           if ($changes{'curr'}{$balancer}{'cookie'}) {
                               $resulttext .= '<li>'.&mt('Load Balancer: [_1] -- cookie use enabled',
                                                         $balancer).'</li>'; 
                           }
                         if (keys(%toupdate)) {                          if (keys(%toupdate)) {
                             my %thismachine;                              my %thismachine;
                             my $updatedhere;                              my $updatedhere;
Line 14270  sub recurse_cat_deletes { Line 17394  sub recurse_cat_deletes {
   
 sub active_dc_picker {  sub active_dc_picker {
     my ($dom,$numinrow,$inputtype,$name,%currhash) = @_;      my ($dom,$numinrow,$inputtype,$name,%currhash) = @_;
     my %domcoords = &get_active_dcs($dom);      my %domcoords = &Apache::lonnet::get_active_domroles($dom,['dc']);
     my @domcoord = keys(%domcoords);      my @domcoord = keys(%domcoords);
     if (keys(%currhash)) {      if (keys(%currhash)) {
         foreach my $dc (keys(%currhash)) {          foreach my $dc (keys(%currhash)) {
Line 14418  sub lonbalance_targets_js { Line 17542  sub lonbalance_targets_js {
     }      }
     push(@alltypes,'default','_LC_adv','_LC_author','_LC_internetdom','_LC_external');      push(@alltypes,'default','_LC_adv','_LC_author','_LC_internetdom','_LC_external');
     $allinsttypes = join("','",@alltypes);      $allinsttypes = join("','",@alltypes);
     my (%currbalancer,%currtargets,%currrules,%existing);      my (%currbalancer,%currtargets,%currrules,%existing,%currcookies);
     if (ref($settings) eq 'HASH') {      if (ref($settings) eq 'HASH') {
         %existing = %{$settings};          %existing = %{$settings};
     }      }
     &get_loadbalancers_config($servers,\%existing,\%currbalancer,      &get_loadbalancers_config($servers,\%existing,\%currbalancer,
                               \%currtargets,\%currrules);                                \%currtargets,\%currrules,\%currcookies);
     my $balancers = join("','",sort(keys(%currbalancer)));      my $balancers = join("','",sort(keys(%currbalancer)));
     return <<"END";      return <<"END";
   
Line 14876  function updateCaptcha(caller,context) { Line 18000  function updateCaptcha(caller,context) {
             privtext.innerHTML = "$lt{'priv'}";              privtext.innerHTML = "$lt{'priv'}";
             versionitem.type = 'text';              versionitem.type = 'text';
             versionitem.size = '3';              versionitem.size = '3';
             versiontext.innerHTML = "$lt{'ver'}";               versiontext.innerHTML = "$lt{'ver'}";
         } else {          } else {
             pubitem.type = 'hidden';              pubitem.type = 'hidden';
             privitem.type = 'hidden';              privitem.type = 'hidden';
Line 14908  function toggleDisplay(domForm,caller) { Line 18032  function toggleDisplay(domForm,caller) {
         var optionsElement = domForm.coursecredits;          var optionsElement = domForm.coursecredits;
         var checkval = 1;          var checkval = 1;
         var dispval = 'block';          var dispval = 'block';
           var selfcreateRegExp = /^cancreate_emailverified/;
         if (caller == 'emailoptions') {          if (caller == 'emailoptions') {
             optionsElement = domForm.cancreate_email;               optionsElement = domForm.cancreate_email; 
         }          }
Line 14918  function toggleDisplay(domForm,caller) { Line 18043  function toggleDisplay(domForm,caller) {
             optionsElement = domForm.canclone;              optionsElement = domForm.canclone;
             checkval = 'instcode';              checkval = 'instcode';
         }          }
           if (selfcreateRegExp.test(caller)) {
               optionsElement = domForm.elements[caller];
               checkval = 'other';
               dispval = 'inline'
           }
         if (optionsElement.length) {          if (optionsElement.length) {
             var currval;              var currval;
             for (var i=0; i<optionsElement.length; i++) {              for (var i=0; i<optionsElement.length; i++) {
Line 14949  sub captcha_phrases { Line 18079  sub captcha_phrases {
                  original  => 'original (CAPTCHA)',                   original  => 'original (CAPTCHA)',
                  recaptcha => 'successor (ReCAPTCHA)',                   recaptcha => 'successor (ReCAPTCHA)',
                  notused   => 'unused',                   notused   => 'unused',
                  ver => 'ReCAPTCHA version (1 or 2)',                    ver => 'ReCAPTCHA version (1 or 2)',
     );      );
 }  }
   
Line 14959  sub devalidate_remote_domconfs { Line 18089  sub devalidate_remote_domconfs {
     my %servers = &Apache::lonnet::internet_dom_servers($dom);      my %servers = &Apache::lonnet::internet_dom_servers($dom);
     my %thismachine;      my %thismachine;
     map { $thismachine{$_} = 1; } &Apache::lonnet::current_machine_ids();      map { $thismachine{$_} = 1; } &Apache::lonnet::current_machine_ids();
     my @posscached = ('domainconfig','domdefaults','ltitools');      my @posscached = ('domainconfig','domdefaults','ltitools','usersessions','directorysrch');
     if (keys(%servers)) {      if (keys(%servers)) {
         foreach my $server (keys(%servers)) {          foreach my $server (keys(%servers)) {
             next if ($thismachine{$server});              next if ($thismachine{$server});

Removed from v.1.286  
changed lines
  Added in v.1.345


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