Diff for /loncom/interface/domainprefs.pm between versions 1.160.6.102.2.3 and 1.319

version 1.160.6.102.2.3, 2020/02/12 23:06:16 version 1.319, 2017/11/30 02:17:50
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, and textbook).  In each case the radio buttons   (official, unofficial, community, textbook, and placement).  
 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).
 which have the following effects:  which have the following effects:
Line 170  use Apache::loncoursequeueadmin(); Line 170  use Apache::loncoursequeueadmin();
 use LONCAPA qw(:DEFAULT :match);  use LONCAPA qw(:DEFAULT :match);
 use LONCAPA::Enrollment;  use LONCAPA::Enrollment;
 use LONCAPA::lonauthcgi();  use LONCAPA::lonauthcgi();
   use LONCAPA::SSL;
 use File::Copy;  use File::Copy;
 use Locale::Language;  use Locale::Language;
 use DateTime::TimeZone;  use DateTime::TimeZone;
 use DateTime::Locale;  use DateTime::Locale;
   use Time::HiRes qw( sleep );
   
 my $registered_cleanup;  my $registered_cleanup;
 my $modified_urls;  my $modified_urls;
Line 217  sub handler { Line 219  sub handler {
                 'serverstatuses','requestcourses','helpsettings',                  'serverstatuses','requestcourses','helpsettings',
                 'coursedefaults','usersessions','loadbalancing',                  'coursedefaults','usersessions','loadbalancing',
                 'requestauthor','selfenrollment','inststatus',                  'requestauthor','selfenrollment','inststatus',
                 'passwords','ltitools'],$dom);                  'ltitools','ssl','trust'],$dom);
     if (ref($domconfig{'ltitools'}) eq 'HASH') {      if (ref($domconfig{'ltitools'}) eq 'HASH') {
         my %encconfig =          my %encconfig =
             &Apache::lonnet::get_dom('encconfig',['ltitools'],$dom);              &Apache::lonnet::get_dom('encconfig',['ltitools'],$dom);
Line 231  sub handler { Line 233  sub handler {
             }              }
         }          }
     }      }
     my @prefs_order = ('rolecolors','login','defaults','passwords','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');                         'ltitools','selfenrollment','usersessions','ssl','trust');
     my %existing;      my %existing;
     if (ref($domconfig{'loadbalancing'}) eq 'HASH') {      if (ref($domconfig{'loadbalancing'}) eq 'HASH') {
         %existing = %{$domconfig{'loadbalancing'}};          %existing = %{$domconfig{'loadbalancing'}};
Line 276  sub handler { Line 278  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 => 'Name displayed'}],                                    col2 => 'Name displayed'}],
                       print => \&print_defaults,                        print => \&print_defaults,
                       modify => \&modify_defaults,                        modify => \&modify_defaults,
                     },                      },
         'passwords' =>  
                     { text => 'Passwords (Internal authentication)',  
                       help => 'Domain_Configuration_Passwords',  
                       header => [{col1 => 'Resetting Forgotten Password',  
                                   col2 => 'Settings'},  
                                  {col1 => 'Encryption of Stored Passwords (Internal Auth)',  
                                   col2 => 'Settings'},  
                                  {col1 => 'Rules for LON-CAPA Passwords',  
                                   col2 => 'Settings'},  
                                  {col1 => 'Course Owner Changing Student Passwords',  
                                   col2 => 'Settings'}],  
                       print => \&print_passwords,  
                       modify => \&modify_passwords,  
                     },  
         'quotas' =>           'quotas' => 
                     { text => 'Blogs, personal web pages, webDAV/quotas, portfolios',                      { text => 'Blogs, personal web pages, webDAV/quotas, portfolios',
                       help => 'Domain_Configuration_Quotas',                        help => 'Domain_Configuration_Quotas',
Line 389  sub handler { Line 379  sub handler {
                     modify => \&modify_usermodification,                      modify => \&modify_usermodification,
                   },                    },
         'scantron' =>          'scantron' =>
                   { text => 'Bubblesheet format',                    { text => 'Bubblesheet format file',
                     help => 'Domain_Configuration_Scantron_Format',                      help => 'Domain_Configuration_Scantron_Format',
                     header => [ {col1 => 'Bubblesheet format file',                      header => [ {col1 => 'Item',
                                  col2 => ''},                                   col2 => '',
                                 {col1 => 'Bubblesheet data upload formats',                                }],
                                  col2 => 'Settings'}],  
                     print => \&print_scantron,                      print => \&print_scantron,
                     modify => \&modify_scantron,                      modify => \&modify_scantron,
                   },                    },
Line 479  sub handler { Line 468  sub handler {
                   print => \&print_selfenrollment,                    print => \&print_selfenrollment,
                   modify => \&modify_selfenrollment,                    modify => \&modify_selfenrollment,
                  },                   },
           'privacy' => 
                    {text   => 'User Privacy',
                     help   => 'Domain_Configuration_User_Privacy',
                     header => [{col1 => 'Setting',
                                 col2 => 'Value',}],
                     print => \&print_privacy,
                     modify => \&modify_privacy,
                    },
         'usersessions' =>          'usersessions' =>
                  {text  => 'User session hosting/offloading',                   {text  => 'User session hosting/offloading',
                   help  => 'Domain_Configuration_User_Sessions',                    help  => 'Domain_Configuration_User_Sessions',
Line 502  sub handler { Line 499  sub handler {
                   print => \&print_loadbalancing,                    print => \&print_loadbalancing,
                   modify => \&modify_loadbalancing,                    modify => \&modify_loadbalancing,
                  },                   },
         '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',
Line 510  sub handler { Line 507  sub handler {
                   print => \&print_ltitools,                    print => \&print_ltitools,
                   modify => \&modify_ltitools,                    modify => \&modify_ltitools,
                  },                   },
           'ssl' =>
                    {text  => 'LON-CAPA Network (SSL)',
                     help  => 'Domain_Configuration_Network_SSL',
                     header => [{col1 => 'Server',
                                 col2 => 'Certificate Status'},
                                {col1 => 'Connections to other servers',
                                 col2 => 'Rules'},
                                {col1 => 'Connections from other servers',
                                 col2 => 'Rules'},
                                {col1 => "Replicating domain's published content",
                                 col2 => 'Rules'}],
                     print => \&print_ssl,
                     modify => \&modify_ssl,
                    },
           'trust' =>
                    {text   => 'Trust Settings',
                     help   => 'Domain_Configuration_Trust',
                     header => [{col1 => "Access to this domain's content by others",
                                 col2 => 'Rules'},
                                {col1 => "Access to other domain's content by this domain",
                                 col2 => 'Rules'},
                                {col1 => "Enrollment in this domain's courses by others",
                                 col2 => 'Rules',},
                                {col1 => "Co-author roles in this domain for others",
                                 col2 => 'Rules',},
                                {col1 => "Co-author roles for this domain's users elsewhere",
                                 col2 => 'Rules',},
                                {col1 => "Domain roles in this domain assignable to others",
                                 col2 => 'Rules'},
                                {col1 => "Course catalog for this domain displayed elsewhere",
                                 col2 => 'Rules'},
                                {col1 => "Requests for creation of courses in this domain by others",
                                 col2 => 'Rules'},
                                {col1 => "Users in other domains can send messages to this domain",
                                 col2 => 'Rules'},],
                     print => \&print_trust,
                     modify => \&modify_trust,
                    },
     );      );
     if (keys(%servers) > 1) {      if (keys(%servers) > 1) {
         $prefs{'login'}  = { text   => 'Log-in page options',          $prefs{'login'}  = { text   => 'Log-in page options',
Line 569  END Line 604  END
         if (grep(/^contacts$/,@actions)) {          if (grep(/^contacts$/,@actions)) {
             $js .= &contacts_javascript();              $js .= &contacts_javascript();
         }          }
         if (grep(/^scantron$/,@actions)) {  
             $js .= &scantron_javascript();  
         }  
         &Apache::lonconfigsettings::display_settings($r,$dom,$phase,$context,\@prefs_order,\%prefs,\%domconfig,$confname,$js);          &Apache::lonconfigsettings::display_settings($r,$dom,$phase,$context,\@prefs_order,\%prefs,\%domconfig,$confname,$js);
     } else {      } else {
 # check if domconfig user exists for the domain.  # check if domconfig user exists for the domain.
Line 692  sub process_changes { Line 724  sub process_changes {
         $output = &modify_usersessions($dom,$lastactref,%domconfig);          $output = &modify_usersessions($dom,$lastactref,%domconfig);
     } elsif ($action eq 'loadbalancing') {      } elsif ($action eq 'loadbalancing') {
         $output = &modify_loadbalancing($dom,%domconfig);          $output = &modify_loadbalancing($dom,%domconfig);
     } elsif ($action eq 'passwords') {  
         $output = &modify_passwords($r,$dom,$confname,$lastactref,%domconfig);  
     } elsif ($action eq 'ltitools') {      } elsif ($action eq 'ltitools') {
         $output = &modify_ltitools($r,$dom,$action,$lastactref,%domconfig);          $output = &modify_ltitools($r,$dom,$action,$lastactref,%domconfig);
       } elsif ($action eq 'ssl') {
           $output = &modify_ssl($dom,$lastactref,%domconfig);
       } elsif ($action eq 'trust') {
           $output = &modify_trust($dom,$lastactref,%domconfig);
     }      }
     return $output;      return $output;
 }  }
Line 708  sub print_config_box { Line 742  sub print_config_box {
         $output = &coursecategories_javascript($settings);          $output = &coursecategories_javascript($settings);
     } elsif ($action eq 'defaults') {      } elsif ($action eq 'defaults') {
         $output = &defaults_javascript($settings);           $output = &defaults_javascript($settings); 
     } elsif ($action eq 'passwords') {  
         $output = &passwords_javascript();  
     } elsif ($action eq 'helpsettings') {      } elsif ($action eq 'helpsettings') {
         my (%privs,%levelscurrent);          my (%privs,%levelscurrent);
         my %full=();          my %full=();
Line 724  sub print_config_box { Line 756  sub print_config_box {
         &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);
         $output =          $output =
             &Apache::lonuserutils::custom_roledefs_js($context,$crstype,$formname,\%full,              &Apache::lonuserutils::custom_roledefs_js($context,$crstype,$formname,\%full, 
                                                       \@templateroles);                                                        \@templateroles);
     }      }
     $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 742  sub print_config_box { Line 774  sub print_config_box {
     if ($numheaders > 1) {      if ($numheaders > 1) {
         my $colspan = '';          my $colspan = '';
         my $rightcolspan = '';          my $rightcolspan = '';
         my $leftnobr = '';  
         if (($action eq 'rolecolors') || ($action eq 'defaults') ||          if (($action eq 'rolecolors') || ($action eq 'defaults') ||
             ($action eq 'directorysrch') ||              ($action eq 'directorysrch') ||
             (($action eq 'login') && ($numheaders < 4))) {              (($action eq 'login') && ($numheaders < 4))) {
Line 751  sub print_config_box { Line 782  sub print_config_box {
         if ($action eq 'usersessions') {          if ($action eq 'usersessions') {
             $rightcolspan = ' colspan="3"';               $rightcolspan = ' colspan="3"'; 
         }          }
         if ($action eq 'passwords') {  
             $leftnobr = ' LC_nobreak';  
         }  
         $output .= '          $output .= '
           <tr>            <tr>
            <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'.$leftnobr.'"'.$colspan.'>'.&mt($item->{'header'}->[0]->{'col1'}).'</td>                <td class="LC_left_item"'.$colspan.'>'.&mt($item->{'header'}->[0]->{'col1'}).'</td>
               <td class="LC_right_item"'.$rightcolspan.'>'.&mt($item->{'header'}->[0]->{'col2'}).'</td>                <td class="LC_right_item"'.$rightcolspan.'>'.&mt($item->{'header'}->[0]->{'col2'}).'</td>
              </tr>';               </tr>';
         $rowtotal ++;          $rowtotal ++;
         if (($action eq 'autoupdate') || ($action eq 'usercreation') || ($action eq 'selfcreation') ||          if (($action eq 'autoupdate') || ($action eq 'usercreation') || ($action eq 'selfcreation') ||
             ($action eq 'usermodification') || ($action eq 'defaults') || ($action eq 'coursedefaults') ||              ($action eq 'usermodification') || ($action eq 'defaults') || ($action eq 'coursedefaults') ||
             ($action eq 'selfenrollment') || ($action eq 'usersessions') || ($action eq 'directorysrch') ||              ($action eq 'selfenrollment') || ($action eq 'usersessions') || ($action eq 'ssl') ||
             ($action eq 'helpsettings') || ($action eq 'contacts')) {              ($action eq 'directorysrch') || ($action eq 'trust') || ($action eq 'helpsettings') ||
               ($action eq 'contacts')) {
             $output .= $item->{'print'}->('top',$dom,$settings,\$rowtotal);              $output .= $item->{'print'}->('top',$dom,$settings,\$rowtotal);
         } elsif ($action eq 'passwords') {  
             $output .= $item->{'print'}->('top',$dom,$confname,$settings,\$rowtotal);  
         } elsif ($action eq 'coursecategories') {          } elsif ($action eq 'coursecategories') {
             $output .= $item->{'print'}->('top',$dom,$item,$settings,\$rowtotal);              $output .= $item->{'print'}->('top',$dom,$item,$settings,\$rowtotal);
         } elsif ($action eq 'scantron') {  
             $output .= $item->{'print'}->($r,'top',$dom,$confname,$settings,\$rowtotal);  
         } elsif ($action eq 'login') {          } elsif ($action eq 'login') {
             if ($numheaders == 4) {              if ($numheaders == 4) {
                 $colspan = ' colspan="2"';                  $colspan = ' colspan="2"';
Line 800  sub print_config_box { Line 825  sub print_config_box {
             $rowtotal ++;              $rowtotal ++;
         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 'contacts') || ($action eq 'passwords')) {              ($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"';
             } elsif ($action eq 'passwords') {              } elsif ($action eq 'trust') {
                 $output .= $item->{'print'}->('middle',$dom,$confname,$settings,\$rowtotal);                  $output .= $item->{'print'}->('shared',$dom,$settings,\$rowtotal);
             } else {              } else {
                 $output .= $item->{'print'}->('middle',$dom,$settings,\$rowtotal);                  $output .= $item->{'print'}->('middle',$dom,$settings,\$rowtotal);
             }              }
             $output .= '              if ($action eq 'trust') {
            </table>                  $output .= '
               </table>
           </td>            </td>
          </tr>           </tr>';
                   my @trusthdrs = qw(2 3 4 5 6 7);
                   my @prefixes = qw(enroll othcoau coaurem domroles catalog reqcrs);
                   for (my $i=0; $i<@trusthdrs; $i++) {
                       $output .= '
          <tr>           <tr>
            <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'.$leftnobr.'"'.$colspan.'>'.&mt($item->{'header'}->[2]->{'col1'}).'</td>                <td class="LC_left_item"'.$colspan.'>'.&mt($item->{'header'}->[$trusthdrs[$i]]->{'col1'}).'</td>
               <td class="LC_right_item">'.&mt($item->{'header'}->[2]->{'col2'}).'</td>                <td class="LC_right_item"'.$colspan.'>'.&mt($item->{'header'}->[$trusthdrs[$i]]->{'col2'}).'</td></tr>'.
              </tr>'."\n";                             $item->{'print'}->($prefixes[$i],$dom,$settings,\$rowtotal).'
             if ($action eq 'coursecategories') {  
                 $output .= &print_coursecategories('bottom',$dom,$item,$settings,\$rowtotal);  
             } elsif ($action eq 'passwords') {  
                 $output .= $item->{'print'}->('lower',$dom,$confname,$settings,\$rowtotal).'  
              </tr>  
             </table>              </table>
            </td>            </td>
           </tr>           </tr>';
           <tr>                  }
                   $output .= '
            <tr>
            <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.'>'.&mt($item->{'header'}->[3]->{'col1'}).'</td>                <td class="LC_left_item"'.$colspan.'>'.&mt($item->{'header'}->[8]->{'col1'}).'</td>
               <td class="LC_right_item"'.$colspan.'>'.&mt($item->{'header'}->[3]->{'col2'}).'</td></tr>'."\n".                <td class="LC_right_item"'.$colspan.'>'.&mt($item->{'header'}->[8]->{'col2'}).'</td></tr>'.
               $item->{'print'}->('bottom',$dom,$confname,$settings,\$rowtotal).'                             $item->{'print'}->('bottom',$dom,$settings,\$rowtotal);
             </table>              } else {
                   $output .= '
              </table>
           </td>            </td>
          </tr>           </tr>
          <tr>';           <tr>
             } else {             <td>
                 $output .= $item->{'print'}->('bottom',$dom,$settings,\$rowtotal);              <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">'.&mt($item->{'header'}->[2]->{'col2'}).'</td>
                </tr>'."\n";
                   if ($action eq 'coursecategories') {
                       $output .= &print_coursecategories('bottom',$dom,$item,$settings,\$rowtotal);
                   } else {
                       $output .= $item->{'print'}->('bottom',$dom,$settings,\$rowtotal);
                   }
             }              }
             $rowtotal ++;              $rowtotal ++;
         } elsif (($action eq 'usermodification') || ($action eq 'coursedefaults') ||          } elsif (($action eq 'usermodification') || ($action eq 'coursedefaults') ||
                  ($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 'scantron') {          } elsif ($action eq 'ssl') {
             $output .= $item->{'print'}->($r,'bottom',$dom,$confname,$settings,\$rowtotal);              $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 920  sub print_config_box { Line 978  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 936  sub print_config_box { Line 994  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 966  sub print_config_box { Line 1024  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 998  sub print_config_box { Line 1056  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 1006  sub print_config_box { Line 1064  sub print_config_box {
         if ($action eq 'quotas') {          if ($action eq 'quotas') {
             $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')) {
             $output .= $item->{'print'}->($dom,$settings,\$rowtotal);              $output .= $item->{'print'}->($dom,$settings,\$rowtotal);
           } elsif ($action eq 'scantron') {
               $output .= &print_scantronformat($r,$dom,$confname,$settings,\$rowtotal);
         }          }
     }      }
     $output .= '      $output .= '
Line 1029  sub print_login { Line 1089  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 1310  sub print_login { Line 1370  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 1353  sub print_login { Line 1413  sub print_login {
             } else {              } else {
                 $datatable .= '<input type="file" name="loginheadtag_'.$lonhost.'" />';                  $datatable .= '<input type="file" name="loginheadtag_'.$lonhost.'" />';
             }              }
             $datatable .= '</td><td><input type="text" name="loginheadtagexempt_'.$lonhost.'" value="'.$exempt.'" /></td></tr>';              $datatable .= '</td><td><input type="textbox" name="loginheadtagexempt_'.$lonhost.'" value="'.$exempt.'" /></td></tr>';
         }          }
         $datatable .= '</table></td></tr>';          $datatable .= '</table></td></tr>';
     }      }
Line 1513  sub display_color_options { Line 1573  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 class="css_default_'.$role.'_font" style="color: '.$defaults->{'font'}.';">'.$defaults->{'font'}.'</span></td>';          $datatable .=  '<td>'.&mt('Default in use:').'&nbsp;<span id="css_default_'.$role.'_font" style="color: '.$defaults->{'font'}.';">'.$defaults->{'font'}.'</span></td>';
     } else {      } else {
         $datatable .= '<td>&nbsp;</td>';          $datatable .= '<td>&nbsp;</td>';
     }      }
Line 1522  sub display_color_options { Line 1582  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;</span></td></tr>';                    '&nbsp;</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 class="css_default_'.$role.'_font" style="color: '.$defaults->{'fontmenu'}.';">'.$defaults->{'fontmenu'}.'</span></td>';              $datatable .=  '<td>'.&mt('Default in use:').'&nbsp;<span id="css_default_'.$role.'_font" style="color: '.$defaults->{'fontmenu'}.';">'.$defaults->{'fontmenu'}.'</span></td>';
         } else {          } else {
             $datatable .= '<td>&nbsp;</td>';              $datatable .= '<td>&nbsp;</td>';
         }          }
Line 1537  sub display_color_options { Line 1597  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;</span></td></tr>';                        '&nbsp;</td></tr>';
     }      }
     my $switchserver = &check_switchserver($dom,$confname);      my $switchserver = &check_switchserver($dom,$confname);
     foreach my $img (@{$images}) {      foreach my $img (@{$images}) {
Line 1655  sub display_color_options { Line 1715  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 class="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 id="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 1667  sub display_color_options { Line 1727  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 1683  sub display_color_options { Line 1743  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 class="css_default_'.$role.'_'.$item.'" style="color: '.$defaults->{'links'}{$item}.';">'.$defaults->{'links'}{$item}.'</span></td>';              $links_def .= '<td>'.$choices->{$item}.'<br /><span id="css_default_'.$role.'_'.$item.'" style="color: '.$defaults->{'links'}{$item}.';">'.$defaults->{'links'}{$item}.'</span></td>';
         }          }
     }      }
     if ($links_def) {      if ($links_def) {
Line 1695  sub display_color_options { Line 1755  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 1756  sub login_text_colors { Line 1816  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 1769  sub image_changes { Line 1829  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') {
         $output = '</td><td>'.$logincolors; # suppress image for Log-in header              # 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 ne 'login') {      if ($img eq 'login') { # suppress image for Log-in header
           $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 1789  sub image_changes { Line 1851  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 1808  sub print_quotas { Line 1870  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');          @usertools = ('official','unofficial','community','textbook','placement');
         @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 2272  sub print_studentcode { Line 2334  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');      my @crstypes = ('official','unofficial','community','textbook','placement');
     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 2368  sub print_textbookcourses { Line 2430  sub print_textbookcourses {
                               ('&nbsp;'x2).                                ('&nbsp;'x2).
                               '<span class="LC_nobreak">'.&mt('Thumbnail:');                                '<span class="LC_nobreak">'.&mt('Thumbnail:');
                 if ($image) {                  if ($image) {
                     $datatable .= '<span class="LC_nobreak">'.                      $datatable .= $imgsrc.
                                   $imgsrc.  
                                   '<label><input type="checkbox" name="'.$type.'_image_del"'.                                    '<label><input type="checkbox" name="'.$type.'_image_del"'.
                                   ' value="'.$key.'" />'.&mt('Delete?').'</label></span> '.                                    ' value="'.$key.'" />'.&mt('Delete?').'</label></span> '.
                                   '<span class="LC_nobreak">&nbsp;'.&mt('Replace:').'&nbsp;';                                    '<span class="LC_nobreak">&nbsp;'.&mt('Replace:').'&nbsp;';
Line 2400  sub print_textbookcourses { Line 2461  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').'</span></td>'."\n".                    '<input type="checkbox" name="'.$type.'_addbook" value="1" />'.&mt('Add').'</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 2417  sub print_textbookcourses { Line 2478  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 class="LC_nobreak">'.&mt('LON-CAPA course:').'&nbsp;'.      $datatable .= '</span>'."\n".
                     '<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 2525  ENDSCRIPT Line 2586  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 2543  sub ltitools_javascript { Line 2607  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 2588  $jstext Line 2652  $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';
               }
           }
       }
       return;
   }
   // ]]>
   </script>
   
 ENDSCRIPT  ENDSCRIPT
 }  }
   
Line 2670  sub print_autoenroll { Line 2776  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" /></span></td></tr>';                    ' value="'.$failsafe.'" size="4" /></td></tr>';
     $$rowtotal += 4;      $$rowtotal += 4;
     return $datatable;      return $datatable;
 }  }
Line 2963  sub print_contacts { Line 3069  sub print_contacts {
         }          }
     } elsif ($position eq 'middle') {      } elsif ($position eq 'middle') {
         @mailings = ('errormail','packagesmail','lonstatusmail','requestsmail',          @mailings = ('errormail','packagesmail','lonstatusmail','requestsmail',
                      'updatesmail','idconflictsmail','hostipmail');                       'updatesmail','idconflictsmail');
         foreach my $type (@mailings) {          foreach my $type (@mailings) {
             $otheremails{$type} = '';              $otheremails{$type} = '';
         }          }
Line 3040  sub print_contacts { Line 3146  sub print_contacts {
             $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" ';
             $checked{'hostipmail'}{'adminemail'} = ' checked="checked" ';  
         } elsif ($position eq 'bottom') {          } elsif ($position eq 'bottom') {
             $checked{'helpdeskmail'}{'supportemail'} = ' checked="checked" ';              $checked{'helpdeskmail'}{'supportemail'} = ' checked="checked" ';
             $checked{'otherdomsmail'}{'supportemail'} = ' checked="checked" ';              $checked{'otherdomsmail'}{'supportemail'} = ' checked="checked" ';
Line 3101  sub print_contacts { Line 3206  sub print_contacts {
                     if ($currfield{$field} eq 'no') {                      if ($currfield{$field} eq 'no') {
                         $display = ' style="display:none"';                          $display = ' style="display:none"';
                     }                      }
                     $datatable .= '</td></tr><tr id="help_screenshotsize"'.$display.'>'.                      $datatable .= '</td></tr><tr id="help_screenshotsize"'.$display.' />'.
                                   '<td>'.&mt('Maximum size for upload (MB)').'</td><td>'.                                    '<td>'.&mt('Maximum size for upload (MB)').'</td><td>'.
                                   '<input type="text" size="5" name="helpform_maxsize" value="'.$maxsize.'" />';                                    '<input type="text" size="5" name="helpform_maxsize" value="'.$maxsize.'" />';
                 }                  }
Line 3146  sub print_contacts { Line 3251  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 3198  sub print_contacts { Line 3303  sub print_contacts {
                             $includeloc{'override_'.$key} = '';                              $includeloc{'override_'.$key} = '';
                             $includestr{'override_'.$key} = '';                              $includestr{'override_'.$key} = '';
                             if ($settings->{'overrides'}{$key}{'include'} ne '') {                              if ($settings->{'overrides'}{$key}{'include'} ne '') {
                                 ($includeloc{'override_'.$key},$includestr{'override_'.$key}) =                                  ($includeloc{'override_'.$key},$includestr{'override_'.$key}) = 
                                     split(/:/,$settings->{'overrides'}{$key}{'include'},2);                                      split(/:/,$settings->{'overrides'}{$key}{'include'},2);
                                 $includestr{'override_'.$key} = &unescape($includestr{'override_'.$key});                                  $includestr{'override_'.$key} = &unescape($includestr{'override_'.$key});
                             }                              }
Line 3210  sub print_contacts { Line 3315  sub print_contacts {
             my $optionsprefix = 'LC_options_helpdesk_';              my $optionsprefix = 'LC_options_helpdesk_';
   
             my $onclicktypes = "toggleHelpdeskRow(this.form,'overrides','$customclass','$optionsprefix');";              my $onclicktypes = "toggleHelpdeskRow(this.form,'overrides','$customclass','$optionsprefix');";
    
             $datatable .= &insttypes_row($settings,$types,$usertypes,$dom,              $datatable .= &insttypes_row($settings,$types,$usertypes,$dom,
                                          $numinrow,$othertitle,'overrides',                                           $numinrow,$othertitle,'overrides',
                                          \$rownum,$onclicktypes,$customclass);                                           \$rownum,$onclicktypes,$customclass);
Line 3272  sub overridden_helpdesk { Line 3377  sub overridden_helpdesk {
             }              }
             my $title;              my $title;
             if (ref($short_titles) eq 'HASH') {              if (ref($short_titles) eq 'HASH') {
                 $title = $short_titles->{$item};                  $title = $short_titles->{$item}; 
             }              }
             $output .= '<label>'.              $output .= '<label>'.
                        '<input type="checkbox" name="override_'.$type.'"'.$check.                         '<input type="checkbox" name="override_'.$type.'"'.$check.
Line 3294  sub overridden_helpdesk { Line 3399  sub overridden_helpdesk {
                'value="'.$bccemails.'"  /></fieldset>'.                 'value="'.$bccemails.'"  /></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="override_'.$type.'_includestr" value="'.$includestr.'" /><br />'.                 '<input type="text" name="override_'.$type.'_includestr" value="'.$includestr.'" /><br >'.
                '<span class="LC_nobreak">'.&mt('Location:').'&nbsp;'.                 '<span class="LC_nobreak">'.&mt('Location:').'&nbsp;'.
                '<label><input type="radio" name="override_'.$type.'_includeloc" value="s"'.$locchecked{'s'}.' />'.&mt('in subject').'</label>'.                 '<label><input type="radio" name="override_'.$type.'_includeloc" value="s"'.$locchecked{'s'}.' />'.&mt('in subject').'</label>'.
                ('&nbsp;'x2).                 ('&nbsp;'x2).
Line 3351  function toggleHelpdeskRow(form,checkbox Line 3456  function toggleHelpdeskRow(form,checkbox
     return;      return;
 }  }
   
   
 // ]]>  // ]]>
 </script>  </script>
   
Line 3456  sub print_helpsettings { Line 3562  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 3495  sub print_helpsettings { Line 3601  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 3525  sub print_helpsettings { Line 3631  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>'.                        '</fieldset></td></tr>';
                       &helpsettings_javascript(\@roles_by_num,$maxnum,$hiddenstr,$formname).  
                       '</td></tr>';  
         $count ++;          $count ++;
         $$rowtotal += $count;          $$rowtotal += $count;
     }      }
Line 3776  sub radiobutton_prefs { Line 3880  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 3826  sub print_ltitools { Line 3930  sub print_ltitools {
         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,$imgsrc);
             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'};
Line 3837  sub print_ltitools { Line 3941  sub print_ltitools {
                     $imgsrc = '<img src="'.$image.'" alt="'.&mt('Tool Provider icon').'" />';                      $imgsrc = '<img src="'.$image.'" alt="'.&mt('Tool Provider icon').'" />';
                 }                  }
             }              }
             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 3864  sub print_ltitools { Line 3968  sub print_ltitools {
                 '<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="30" 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{'secret'}.':'.                  '<span class="LC_nobreak">'.$lt{'secret'}.':'.
Line 3910  sub print_ltitools { Line 4014  sub print_ltitools {
                           '<div class="LC_left_float">'.$lt{'explanation'}.'<br />'.                            '<div class="LC_left_float">'.$lt{'explanation'}.'<br />'.
                           '<textarea name="ltitools_explanation_'.$i.'" rows="5" cols="40">'.$currdisp{'explanation'}.                            '<textarea name="ltitools_explanation_'.$i.'" rows="5" cols="40">'.$currdisp{'explanation'}.
                           '</textarea></div><div style=""></div><br />';                            '</textarea></div><div style=""></div><br />';
             $datatable .= '<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 3967  sub print_ltitools { Line 4086  sub print_ltitools {
                 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 3991  sub print_ltitools { Line 4110  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','linktext','explanation') {              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 4024  sub print_ltitools { Line 4143  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 4075  sub print_ltitools { Line 4194  sub print_ltitools {
                   '<div class="LC_left_float">'.$lt{'explanation'}.'<br />'.                    '<div class="LC_left_float">'.$lt{'explanation'}.'<br />'.
                   '<textarea name=ltitools_add_explanation" rows="5" cols="40"></textarea>'.                    '<textarea name=ltitools_add_explanation" rows="5" cols="40"></textarea>'.
                   '</div><div style=""></div><br />';                    '</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 4101  sub print_ltitools { Line 4234  sub print_ltitools {
                   '<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 ($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 4112  sub print_ltitools { Line 4245  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','linktext','explanation') {      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";
Line 4139  sub ltitools_names { Line 4272  sub ltitools_names {
                                           'url'            => 'URL',                                            'url'            => 'URL',
                                           'key'            => 'Key',                                            'key'            => 'Key',
                                           'secret'         => 'Secret',                                            'secret'         => 'Secret',
                                           'icon'           => 'Icon',                                            'icon'           => 'Icon',   
                                           'user'           => 'Username:domain',                                            'user'           => 'Username:domain',
                                           'fullname'       => 'Full Name',                                            'fullname'       => 'Full Name',
                                           'firstname'      => 'First Name',                                            'firstname'      => 'First Name',
Line 4157  sub ltitools_names { Line 4290  sub ltitools_names {
                                           'roster'         => 'Tool can retrieve roster:',                                            'roster'         => 'Tool can retrieve roster:',
                                           'crstarget'      => 'Display target',                                            'crstarget'      => 'Display target',
                                           'crslabel'       => 'Course label',                                            'crslabel'       => 'Course label',
                                           'crstitle'       => 'Course title',                                            'crstitle'       => 'Course title', 
                                           'crslinktext'    => 'Link Text',                                            'crslinktext'    => 'Link Text',
                                           'crsexplanation' => 'Explanation',                                            'crsexplanation' => 'Explanation',
                                             'crsappend'      => 'Provider URL',
                                         );                                          );
   
     return %lt;      return %lt;
 }  }
   
Line 4170  sub print_coursedefaults { Line 4303  sub print_coursedefaults {
     my ($css_class,$datatable,%checkedon,%checkedoff,%defaultchecked,@toggles);      my ($css_class,$datatable,%checkedon,%checkedoff,%defaultchecked,@toggles);
     my $itemcount = 1;      my $itemcount = 1;
     my %choices =  &Apache::lonlocal::texthash (      my %choices =  &Apache::lonlocal::texthash (
           canuse_pdfforms      => 'Course/Community users can create/upload PDF forms',
         uploadquota          => 'Default quota for files uploaded directly to course/community using Course Editor (MB)',          uploadquota          => 'Default quota for files uploaded directly to course/community using Course Editor (MB)',
         anonsurvey_threshold => 'Responder count needed before showing submissions for anonymous surveys',          anonsurvey_threshold => 'Responder count needed before showing submissions for anonymous surveys',
         coursecredits        => 'Credits can be specified for courses',          coursecredits        => 'Credits can be specified for courses',
Line 4181  sub print_coursedefaults { Line 4315  sub print_coursedefaults {
         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 4188  sub print_coursedefaults { Line 4323  sub print_coursedefaults {
                          );                           );
     if ($position eq 'top') {      if ($position eq 'top') {
         %defaultchecked = (          %defaultchecked = (
                               'canuse_pdfforms' => 'off',
                             'uselcmath'       => 'on',                              'uselcmath'       => 'on',
                             'usejsme'         => 'on',                              'usejsme'         => 'on',
                             'canclone'        => 'none',                              'canclone'        => 'none',
                           );                            );
         @toggles = ('uselcmath','usejsme');          @toggles = ('canuse_pdfforms','uselcmath','usejsme');
         my $deftex = $Apache::lonnet::deftex;          my $deftex = $staticdefaults{'texengine'};
         if (ref($settings) eq 'HASH') {          if (ref($settings) eq 'HASH') {
             if ($settings->{'texengine'}) {              if ($settings->{'texengine'}) {
                 if ($settings->{'texengine'} =~ /^(MathJax|mimetex|tth)$/) {                  if ($settings->{'texengine'} =~ /^(MathJax|mimetex|tth)$/) {
Line 4225  sub print_coursedefaults { Line 4361  sub print_coursedefaults {
         $datatable = $mathdisp.$datatable;          $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 4269  sub print_coursedefaults { Line 4405  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 4299  sub print_coursedefaults { Line 4435  sub print_coursedefaults {
         my ($currdefresponder,%defcredits,%curruploadquota,%deftimeout,%currmysql);          my ($currdefresponder,%defcredits,%curruploadquota,%deftimeout,%currmysql);
         my $currusecredits = 0;          my $currusecredits = 0;
         my $postsubmitclient = 1;          my $postsubmitclient = 1;
         my @types = ('official','unofficial','community','textbook');          my @types = ('official','unofficial','community','textbook','placement');
         if (ref($settings) eq 'HASH') {          if (ref($settings) eq 'HASH') {
             $currdefresponder = $settings->{'anonsurvey_threshold'};              $currdefresponder = $settings->{'anonsurvey_threshold'};
             if (ref($settings->{'uploadquota'}) eq 'HASH') {              if (ref($settings->{'uploadquota'}) eq 'HASH') {
Line 4377  sub print_coursedefaults { Line 4513  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 4395  sub print_coursedefaults { Line 4531  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 4419  sub print_coursedefaults { Line 4555  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 4437  sub print_coursedefaults { Line 4573  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="8" /></td>';                             ' value="'.$currmysql{$type}.'" size="8" /></td>';
         }          }
Line 4456  sub print_selfenrollment { Line 4592  sub print_selfenrollment {
     my ($position,$dom,$settings,$rowtotal) = @_;      my ($position,$dom,$settings,$rowtotal) = @_;
     my ($css_class,$datatable);      my ($css_class,$datatable);
     my $itemcount = 1;      my $itemcount = 1;
     my @types = ('official','unofficial','community','textbook');      my @types = ('official','unofficial','community','textbook','placement');
     if (($position eq 'top') || ($position eq 'middle')) {      if (($position eq 'top') || ($position eq 'middle')) {
         my ($rowsref,$titlesref) = &Apache::lonuserutils::get_selfenroll_titles();          my ($rowsref,$titlesref) = &Apache::lonuserutils::get_selfenroll_titles();
         my %descs = &Apache::lonuserutils::selfenroll_default_descs();          my %descs = &Apache::lonuserutils::selfenroll_default_descs();
Line 4640  sub print_validation_rows { Line 4776  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">'.              $datatable .= '<textarea name="'.$caller.'_validation_markup" cols="50" rows="5" wrap="soft">'.
                            $currvalidation{$item}.                             $currvalidation{$item}.
                               '</textarea>';                                '</textarea>';
         }          }
Line 4662  sub print_validation_rows { Line 4798  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 .= '<tr'.$css_class.'><td>';          $datatable .= '</td></tr><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 4677  sub print_validation_rows { Line 4813  sub print_validation_rows {
     return $datatable;      return $datatable;
 }  }
   
 sub print_passwords {  sub print_usersessions {
     my ($position,$dom,$confname,$settings,$rowtotal) = @_;      my ($position,$dom,$settings,$rowtotal) = @_;
     my ($datatable,$css_class);      my ($css_class,$datatable,$itemcount,%checked,%choices);
     my $itemcount = 0;      my (%by_ip,%by_location,@intdoms,@instdoms);
     my %titles = &Apache::lonlocal::texthash (      &build_location_hashes(\@intdoms,\%by_ip,\%by_location,\@instdoms);
         captcha        => '"Forgot Password" CAPTCHA validation',  
         link           => 'Reset link expiration (hours)',      my @alldoms = &Apache::lonnet::all_domains();
         case           => 'Case-sensitive usernames/e-mail',      my %serverhomes = %Apache::lonnet::serverhomeIDs;
         prelink        => 'Information required (form 1)',      my %servers = &Apache::lonnet::internet_dom_servers($dom);
         postlink       => 'Information required (form 2)',      my %altids = &id_for_thisdom(%servers);
         emailsrc       => 'LON-CAPA e-mail address type(s)',  
         customtext     => 'Domain specific text (HTML)',  
         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',  
         permanent      => 'Permanent e-mail address',  
         critical       => 'Critical notification address',  
         notify         => 'Notification address',  
         min            => 'Minimum password length',  
         max            => 'Maximum password length',  
         chars          => 'Required characters',  
         numsaved       => 'Number of previous passwords to save and disallow reuse',  
     );  
     if ($position eq 'top') {      if ($position eq 'top') {
         my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom);          if (keys(%serverhomes) > 1) {
         my $shownlinklife = 2;              my %spareid = &current_offloads_to($dom,$settings,\%servers);
         my $prelink = 'both';              my $curroffloadnow;
         my (%casesens,%postlink,%emailsrc,$nostdtext,$customurl);              if (ref($settings) eq 'HASH') {
         if (ref($settings) eq 'HASH') {                  if (ref($settings->{'offloadnow'}) eq 'HASH') {
             if ($settings->{resetlink} =~ /^\d+(|\.\d*)$/) {                      $curroffloadnow = $settings->{'offloadnow'};
                 $shownlinklife = $settings->{resetlink};  
             }  
             if (ref($settings->{resetcase}) eq 'ARRAY') {  
                 map { $casesens{$_} = 1; } (@{$settings->{resetcase}});  
             }  
             if ($settings->{resetprelink} =~ /^(both|either)$/) {  
                 $prelink = $settings->{resetprelink};  
             }  
             if (ref($settings->{resetpostlink}) eq 'HASH') {  
                 %postlink = %{$settings->{resetpostlink}};  
             }  
             if (ref($settings->{resetemail}) eq 'ARRAY') {  
                 map { $emailsrc{$_} = 1; } (@{$settings->{resetemail}});  
             }  
             if ($settings->{resetremove}) {  
                 $nostdtext = 1;  
             }  
             if ($settings->{resetcustom}) {  
                 $customurl = $settings->{resetcustom};  
             }  
         } else {  
             if (ref($types) eq 'ARRAY') {  
                 foreach my $item (@{$types}) {  
                     $casesens{$item} = 1;  
                     $postlink{$item} = ['username','email'];  
                 }  
             }  
             $casesens{'default'} = 1;  
             $postlink{'default'} = ['username','email'];  
             $prelink = 'both';  
             %emailsrc = (  
                           permanent => 1,  
                           critical  => 1,  
                           notify    => 1,  
             );  
         }  
         $datatable = &captcha_choice('passwords',$settings,$$rowtotal);  
         $itemcount ++;  
         $css_class = $itemcount%2?' class="LC_odd_row"':'';  
         $datatable .= '<tr'.$css_class.'><td>'.$titles{'link'}.'</td>'.  
                       '<td class="LC_left_item">'.  
                       '<input type="textbox" value="'.$shownlinklife.'" '.  
                       'name="passwords_link" size="3" /></td></tr>';  
         $itemcount ++;  
         $css_class = $itemcount%2?' class="LC_odd_row"':'';  
         $datatable .= '<tr'.$css_class.'><td>'.$titles{'case'}.'</td>'.  
                       '<td class="LC_left_item">';  
         if ((ref($types) eq 'ARRAY') && (ref($usertypes) eq 'HASH')) {  
             foreach my $item (@{$types}) {  
                 my $checkedcase;  
                 if ($casesens{$item}) {  
                     $checkedcase = ' checked="checked"';  
                 }  
                 $datatable .= '<span class="LC_nobreak"><label>'.  
                               '<input type="checkbox" name="passwords_case_sensitive" value="'.  
                               $item.'"'.$checkedcase.' />'.$usertypes->{$item}.'</label>'.  
                               '</span>&nbsp;&nbsp; ';  
             }  
         }  
         my $checkedcase;  
         if ($casesens{'default'}) {  
             $checkedcase = ' checked="checked"';  
         }  
         $datatable .= '<span class="LC_nobreak"><label><input type="checkbox" '.  
                       'name="passwords_case_sensitive" value="default"'.$checkedcase.' />'.  
                       $othertitle.'</label></span></td>';  
         $itemcount ++;  
         $css_class = $itemcount%2?' class="LC_odd_row"':'';  
         my %checkedpre = (  
                              both => ' checked="checked"',  
                              either => '',  
                          );  
         if ($prelink eq 'either') {  
             $checkedpre{either} = ' checked="checked"';  
             $checkedpre{both} = '';  
         }  
         $datatable .= '<tr'.$css_class.'><td>'.$titles{'prelink'}.'</td>'.  
                       '<td class="LC_left_item"><span class="LC_nobreak">'.  
                       '<label><input type="radio" name="passwords_prelink" value="both"'.$checkedpre{'both'}.' />'.  
                       &mt('Both username and e-mail address').'</label></span>&nbsp;&nbsp; '.  
                       '<span class="LC_nobreak"><label>'.  
                       '<input type="radio" name="passwords_prelink" value="either"'.$checkedpre{'either'}.' />'.  
                       &mt('Either username or e-mail address').'</label></span></td></tr>';  
         $itemcount ++;  
         $css_class = $itemcount%2?' class="LC_odd_row"':'';  
         $datatable .= '<tr'.$css_class.'><td>'.$titles{'postlink'}.'</td>'.  
                       '<td class="LC_left_item">';  
         my %postlinked;  
         if ((ref($types) eq 'ARRAY') && (ref($usertypes) eq 'HASH')) {  
             foreach my $item (@{$types}) {  
                 undef(%postlinked);  
                 $datatable .= '<fieldset style="display: inline-block;">'.  
                               '<legend>'.$usertypes->{$item}.'</legend>';  
                 if (ref($postlink{$item}) eq 'ARRAY') {  
                     map { $postlinked{$_} = 1; } (@{$postlink{$item}});  
                 }  
                 foreach my $field ('email','username') {  
                     my $checked;  
                     if ($postlinked{$field}) {  
                         $checked = ' checked="checked"';  
                     }  
                     $datatable .= '<span class="LC_nobreak"><label>'.  
                                   '<input type="checkbox" name="passwords_postlink_'.$item.'" value="'.  
                                   $field.'"'.$checked.' />'.$field.'</label>'.  
                                   '<span>&nbsp;&nbsp; ';  
                 }                  }
                 $datatable .= '</fieldset>';  
             }  
         }  
         if (ref($postlink{'default'}) eq 'ARRAY') {  
             map { $postlinked{$_} = 1; } (@{$postlink{'default'}});  
         }  
         $datatable .= '<fieldset style="display: inline-block;">'.  
                       '<legend>'.$othertitle.'</legend>';  
         foreach my $field ('email','username') {  
             my $checked;  
             if ($postlinked{$field}) {  
                 $checked = ' checked="checked"';  
             }  
             $datatable .= '<span class="LC_nobreak"><label>'.  
                           '<input type="checkbox" name="passwords_postlink_default" value="'.  
                           $field.'"'.$checked.' />'.$field.'</label>'.  
                           '<span>&nbsp;&nbsp; ';  
         }  
         $datatable .= '</fieldset></td></tr>';  
         $itemcount ++;  
         $css_class = $itemcount%2?' class="LC_odd_row"':'';  
         $datatable .= '<tr'.$css_class.'><td>'.$titles{'emailsrc'}.'</td>'.  
                       '<td class="LC_left_item">';  
         foreach my $type ('permanent','critical','notify') {  
             my $checkedemail;  
             if ($emailsrc{$type}) {  
                 $checkedemail = ' checked="checked"';  
             }              }
             $datatable .= '<span class="LC_nobreak"><label>'.              $datatable .= &spares_row($dom,\%servers,\%spareid,\%serverhomes,\%altids,$curroffloadnow,$rowtotal);
                           '<input type="checkbox" name="passwords_emailsrc" value="'.  
                           $type.'"'.$checkedemail.' />'.$titles{$type}.'</label>'.  
                           '<span>&nbsp;&nbsp; ';  
         }  
         $datatable .= '</td></tr>';  
         $itemcount ++;  
         $css_class = $itemcount%2?' class="LC_odd_row"':'';  
         my $switchserver = &check_switchserver($dom,$confname);  
         my ($showstd,$noshowstd);  
         if ($nostdtext) {  
             $noshowstd = ' checked="checked"';  
         } else {  
             $showstd = ' checked="checked"';  
         }  
         $datatable .= '<tr'.$css_class.'><td>'.$titles{'customtext'}.'</td>'.  
                       '<td class="LC_left_item"><span class="LC_nobreak">'.  
                       &mt('Retain standard text:').  
                       '<label><input type="radio" name="passwords_stdtext" value="1"'.$showstd.' />'.  
                       &mt('Yes').'</label>'.'&nbsp;'.  
                       '<label><input type="radio" name="passwords_stdtext" value="0"'.$noshowstd.' />'.  
                       &mt('No').'</label></span><br />'.  
                       '<span class="LC_fontsize_small">'.  
                       &mt('(If you use the same account ...  reset a password from this page.)').'</span><br /><br />'.  
                       &mt('Include custom text:');  
         if ($customurl) {  
             my $link =  &Apache::loncommon::modal_link($customurl,&mt('custom text'),600,500,  
                                                        undef,undef,undef,undef,'background-color:#ffffff');  
             $datatable .= '<span class="LC_nobreak">&nbsp;'.$link.  
                           '<label><input type="checkbox" name="passwords_custom_del"'.  
                           ' value="1" />'.&mt('Delete?').'</label></span>'.  
                           ' <span class="LC_nobreak">&nbsp;'.&mt('Replace:').'</span>';  
         }  
         if ($switchserver) {  
             $datatable .= '<span class="LC_nobreak">&nbsp;'.&mt('Upload to library server: [_1]',$switchserver).'</span>';  
         } else {          } else {
             $datatable .='<span class="LC_nobreak">&nbsp;'.              $datatable .= '<tr'.$css_class.'><td colspan="2">'.
                          '<input type="file" name="passwords_customfile" /></span>';                            &mt('Nothing to set here, as the cluster to which this domain belongs only contains one server.').
                             '</td></tr>';
         }          }
         $datatable .= '</td></tr>';      } else {
     } elsif ($position eq 'middle') {          my %titles = &usersession_titles();
         my %domconf = &Apache::lonnet::get_dom('configuration',['defaults'],$dom);          my ($prefix,@types);
         my @items = ('intauth_cost','intauth_check','intauth_switch');          if ($position eq 'bottom') {
         my %defaults;              $prefix = 'remote';
         if (ref($domconf{'defaults'}) eq 'HASH') {              @types = ('version','excludedomain','includedomain');
             %defaults = %{$domconf{'defaults'}};  
             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 {          } else {
             %defaults = (              $prefix = 'hosted';
                           'intauth_cost'   => 10,              @types = ('excludedomain','includedomain');
                           'intauth_check'  => 0,  
                           'intauth_switch' => 0,  
                         );  
         }          }
         foreach my $item (@items) {          ($datatable,$itemcount) = &rules_by_location($settings,$prefix,\%by_location,\%by_ip,\@types,\%titles);
             if ($itemcount%2) {      }
                 $css_class = '';      $$rowtotal += $itemcount;
             } else {      return $datatable;
                 $css_class = ' class="LC_odd_row" ';  }
             }  
             $datatable .= '<tr'.$css_class.'>'.  sub rules_by_location {
                           '<td><span class="LC_nobreak">'.$titles{$item}.      my ($settings,$prefix,$by_location,$by_ip,$types,$titles) = @_; 
                           '</span></td><td class="LC_left_item" colspan="3">';      my ($datatable,$itemcount,$css_class);
             if ($item eq 'intauth_switch') {      if (keys(%{$by_location}) == 0) {
                 my @options = (0,1,2);          $css_class = $itemcount%2 ? ' class="LC_odd_row"' : '';
                 my %optiondesc = &Apache::lonlocal::texthash (          $datatable = '<tr'.$css_class.'><td colspan="2">'.
                                    0 => 'No',                       &mt('Nothing to set here, as the cluster to which this domain belongs only contains one institution.').
                                    1 => 'Yes',                       '</td></tr>';
                                    2 => 'Yes, and copy existing passwd file to passwd.bak file',          $itemcount = 1;
                                  );      } else {
                 $datatable .= '<table width="100%">';          $itemcount = 0;
                 foreach my $option (@options) {          my $numinrow = 5;
                     my $checked = ' ';          my (%current,%checkedon,%checkedoff);
                     if ($defaults{$item} eq $option) {          my @locations = sort(keys(%{$by_location}));
                         $checked = ' checked="checked"';          foreach my $type (@{$types}) {
                     }              $checkedon{$type} = '';
                     $datatable .= '<tr><td class="LC_left_item"><span class="LC_nobreak">'.              $checkedoff{$type} = ' checked="checked"';
                                   '<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>';  
             $itemcount ++;  
         }          }
     } elsif ($position eq 'lower') {  
         my ($min,$max,%chars,$numsaved);  
         $min = $Apache::lonnet::passwdmin;  
         if (ref($settings) eq 'HASH') {          if (ref($settings) eq 'HASH') {
             if ($settings->{min}) {              if (ref($settings->{$prefix}) eq 'HASH') {
                 $min = $settings->{min};                  foreach my $key (keys(%{$settings->{$prefix}})) {
             }                      $current{$key} = $settings->{$prefix}{$key};
             if ($settings->{max}) {                      if ($key eq 'version') {
                 $max = $settings->{max};                          if ($current{$key} ne '') {
             }                              $checkedon{$key} = ' checked="checked"';
             if (ref($settings->{chars}) eq 'ARRAY') {                              $checkedoff{$key} = '';
                 map { $chars{$_} = 1; } (@{$settings->{chars}});                          }
             }                      } elsif (ref($current{$key}) eq 'ARRAY') {
             if ($settings->{numsaved}) {                          $checkedon{$key} = ' checked="checked"';
                 $numsaved = $settings->{numsaved};                          $checkedoff{$key} = '';
             }                      }
         }  
         my %rulenames = &Apache::lonlocal::texthash(  
                                                      uc => 'At least one upper case letter',  
                                                      lc => 'At least one lower case letter',  
                                                      num => 'At least one number',  
                                                      spec => 'At least one non-alphanumeric',  
                                                    );  
         $css_class = $itemcount%2?' class="LC_odd_row"':'';  
         $datatable .= '<tr'.$css_class.'><td>'.$titles{'min'}.'</td>'.  
                       '<td class="LC_left_item"><span class="LC_nobreak">'.  
                       '<input type="text" name="passwords_min" value="'.$min.'" size="3" '.  
                       'onblur="javascript:warnIntPass(this);" />'.  
                       '<span class="LC_fontsize_small"> '.&mt('(Enter an integer: 7 or larger)').'</span>'.  
                       '</span></td></tr>';  
         $itemcount ++;  
         $css_class = $itemcount%2?' class="LC_odd_row"':'';  
         $datatable .= '<tr'.$css_class.'><td>'.$titles{'max'}.'</td>'.  
                       '<td class="LC_left_item"><span class="LC_nobreak">'.  
                       '<input type="text" name="passwords_max" value="'.$max.'" size="3" '.  
                       'onblur="javascript:warnIntPass(this);" />'.  
                       '<span class="LC_fontsize_small"> '.&mt('(Leave blank for no maximum)').'</span>'.  
                       '</span></td></tr>';  
         $itemcount ++;  
         $css_class = $itemcount%2?' class="LC_odd_row"':'';  
         $datatable .= '<tr'.$css_class.'><td>'.$titles{'chars'}.'<br />'.  
                       '<span class="LC_nobreak LC_fontsize_small">'.&mt('(Leave unchecked if not required)').  
                       '</span></td>';  
         my $numinrow = 2;  
         my @possrules = ('uc','lc','num','spec');  
         $datatable .= '<td class="LC_left_item"><table>';  
         for (my $i=0; $i<@possrules; $i++) {  
             my ($rem,$checked);  
             if ($chars{$possrules[$i]}) {  
                 $checked = ' checked="checked"';  
             }  
             $rem = $i%($numinrow);  
             if ($rem == 0) {  
                 if ($i > 0) {  
                     $datatable .= '</tr>';  
                 }                  }
                 $datatable .= '<tr>';  
             }              }
             $datatable .= '<td><span class="LC_nobreak"><label>'.  
                           '<input type="checkbox" name="passwords_chars" value="'.$possrules[$i].'"'.$checked.' />'.  
                           $rulenames{$possrules[$i]}.'</label></span></td>';  
         }  
         my $rem = @possrules%($numinrow);  
         my $colsleft = $numinrow - $rem;  
         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 .='</table></td></tr>';          foreach my $type (@{$types}) {
         $itemcount ++;              next if ($type ne 'version' && !@locations);
         $css_class = $itemcount%2?' class="LC_odd_row"':'';              $css_class = $itemcount%2 ? ' class="LC_odd_row"' : '';
         $datatable .= '<tr'.$css_class.'><td>'.$titles{'numsaved'}.'</td>'.              $datatable .= '<tr'.$css_class.'>
                       '<td class="LC_left_item"><span class="LC_nobreak">'.                             <td><span class="LC_nobreak">'.$titles->{$type}.'</span><br />
                       '<input type="text" name="passwords_numsaved" value="'.$numsaved.'" size="3" '.                             <span class="LC_nobreak">&nbsp;
                       'onblur="javascript:warnIntPass(this);" />'.                             <label><input type="radio" name="'.$prefix.'_'.$type.'_inuse" '.$checkedoff{$type}.' value="0" />'.&mt('Not in use').'</label>&nbsp;
                       '<span class="LC_fontsize_small"> '.&mt('(Leave blank to not save previous passwords)').'</span>'.                             <label><input type="radio" name="'.$prefix.'_'.$type.'_inuse" '.$checkedon{$type}.' value="1" />'.&mt('In use').'</label></span></td><td>';
                       '</span></td></tr>';              if ($type eq 'version') {
     } else {                  my @lcversions = &Apache::lonnet::all_loncaparevs();
         my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom);                  my $selector = '<select name="'.$prefix.'_version">';
         my %ownerchg = (                  foreach my $version (@lcversions) {
                           by  => {},                      my $selected = '';
                           for => {},                      if ($current{'version'} eq $version) {
                        );                          $selected = ' selected="selected"';
         my %ownertitles = &Apache::lonlocal::texthash (                      }
                             by  => 'Course owner status(es) allowed',                      $selector .= ' <option value="'.$version.'"'.
                             for => 'Student status(es) allowed',                                   $selected.'>'.$version.'</option>';
                           );  
         if (ref($settings) eq 'HASH') {  
             if (ref($settings->{crsownerchg}) eq 'HASH') {  
                 if (ref($settings->{crsownerchg}{'by'}) eq 'ARRAY') {  
                     map { $ownerchg{by}{$_} = 1; } (@{$settings->{crsownerchg}{'by'}});  
                 }  
                 if (ref($settings->{crsownerchg}{'for'}) eq 'ARRAY') {  
                     map { $ownerchg{for}{$_} = 1; } (@{$settings->{crsownerchg}{'for'}});  
                 }                  }
             }                  $selector .= '</select> ';
         }                  $datatable .= &mt('remote server must be version: [_1] or later',$selector);
         $css_class = $itemcount%2?' class="LC_odd_row"':'';              } else {
         $datatable .= '<tr '.$css_class.'>'.                  $datatable.= '<div><input type="button" value="'.&mt('check all').'" '.
                       '<td>'.                               'onclick="javascript:checkAll(document.display.'.$prefix.'_'.$type.')"'.
                       &mt('Requirements').'<ul>'.                               ' />'.('&nbsp;'x2).
                       '<li>'.&mt("Course 'type' is not a Community").'</li>'.                               '<input type="button" value="'.&mt('uncheck all').'" '.
                       '<li>'.&mt('User is Course Coordinator and also course owner').'</li>'.                               'onclick="javascript:uncheckAll(document.display.'.$prefix.'_'.$type.')" />'.
                       '<li>'.&mt("Student's only active roles are student role(s) in course(s) owned by this user").'</li>'.                               "\n".
                       '<li>'.&mt('User, course, and student share same domain').'</li>'.                               '</div><div><table>';
                       '</ul>'.                  my $rem;
                       '</td>'.                  for (my $i=0; $i<@locations; $i++) {
                       '<td class="LC_left_item">';                      my ($showloc,$value,$checkedtype);
         foreach my $item ('by','for') {                      if (ref($by_location->{$locations[$i]}) eq 'ARRAY') {
             $datatable .= '<fieldset style="display: inline-block;">'.                          my $ip = $by_location->{$locations[$i]}->[0];
                           '<legend>'.$ownertitles{$item}.'</legend>';                          if (ref($by_ip->{$ip}) eq 'ARRAY') {
             if ((ref($types) eq 'ARRAY') && (ref($usertypes) eq 'HASH')) {                              $value = join(':',@{$by_ip->{$ip}});
                 foreach my $type (@{$types}) {                              $showloc = join(', ',@{$by_ip->{$ip}});
                     my $checked;                              if (ref($current{$type}) eq 'ARRAY') {
                     if ($ownerchg{$item}{$type}) {                                  foreach my $loc (@{$by_ip->{$ip}}) {
                         $checked = ' checked="checked"';                                      if (grep(/^\Q$loc\E$/,@{$current{$type}})) {
                                           $checkedtype = ' checked="checked"';
                                           last;
                                       }
                                   }
                               }
                           }
                     }                      }
                     $datatable .= '<span class="LC_nobreak"><label>'.                      $rem = $i%($numinrow);
                                   '<input type="checkbox" name="passwords_crsowner_'.$item.'" value="'.                      if ($rem == 0) {
                                   $type.'"'.$checked.' />'.$usertypes->{$type}.'</label>'.                          if ($i > 0) {
                                   '</span>&nbsp;&nbsp; ';                              $datatable .= '</tr>';
                           }
                           $datatable .= '<tr>';
                       }
                       $datatable .= '<td class="LC_left_item">'.
                                     '<span class="LC_nobreak"><label>'.
                                     '<input type="checkbox" name="'.$prefix.'_'.$type.
                                     '" value="'.$value.'"'.$checkedtype.' />'.$showloc.
                                     '</label></span></td>';
                 }                  }
                   $rem = @locations%($numinrow);
                   my $colsleft = $numinrow - $rem;
                   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>';
             }              }
             my $checked;              $datatable .= '</td></tr>';
             if ($ownerchg{$item}{'default'}) {              $itemcount ++;
                 $checked = ' checked="checked"';  
             }  
             $datatable .= '<span class="LC_nobreak"><label><input type="checkbox" '.  
                           'name="passwords_crsowner_'.$item.'" value="default"'.$checked.' />'.  
                           $othertitle.'</label></span></fieldset>';  
         }          }
         $datatable .= '</td></tr>';  
     }      }
     return $datatable;      return ($datatable,$itemcount);
 }  }
   
 sub print_usersessions {  sub print_ssl {
     my ($position,$dom,$settings,$rowtotal) = @_;      my ($position,$dom,$settings,$rowtotal) = @_;
     my ($css_class,$datatable,%checked,%choices);      my ($css_class,$datatable);
     my (%by_ip,%by_location,@intdoms);  
     &build_location_hashes(\@intdoms,\%by_ip,\%by_location);  
   
     my @alldoms = &Apache::lonnet::all_domains();  
     my %serverhomes = %Apache::lonnet::serverhomeIDs;  
     my %servers = &Apache::lonnet::internet_dom_servers($dom);  
     my %altids = &id_for_thisdom(%servers);  
     my $itemcount = 1;      my $itemcount = 1;
     if ($position eq 'top') {      if ($position eq 'top') {
         if (keys(%serverhomes) > 1) {          my $primary_id = &Apache::lonnet::domain($dom,'primary');
             my %spareid = &current_offloads_to($dom,$settings,\%servers);          my $intdom = &Apache::lonnet::internet_dom($primary_id);
             my $curroffloadnow;          my $same_institution;
             if (ref($settings) eq 'HASH') {          if ($intdom ne '') {
                 if (ref($settings->{'offloadnow'}) eq 'HASH') {              my $internet_names = &Apache::lonnet::get_internet_names($Apache::lonnet::perlvar{'lonHostID'});
                     $curroffloadnow = $settings->{'offloadnow'};              if (ref($internet_names) eq 'ARRAY') {
                   if (grep(/^\Q$intdom\E$/,@{$internet_names})) {
                       $same_institution = 1;
                 }                  }
             }              }
             $datatable .= &spares_row($dom,\%servers,\%spareid,\%serverhomes,\%altids,$curroffloadnow,$rowtotal);          }
           $css_class = $itemcount%2?' class="LC_odd_row"':'';
           $datatable = '<tr'.$css_class.'><td colspan="2">';
           if ($same_institution) {
               my %domservers = &Apache::lonnet::get_servers($dom);
               $datatable .= &LONCAPA::SSL::print_certstatus(\%domservers,'web','domprefs');
         } else {          } else {
             $datatable .= '<tr'.$css_class.'><td colspan="2">'.              $datatable .= &mt("You need to be logged into one of your own domain's servers to display information about the status of LON-CAPA SSL certificates.");
                           &mt('Nothing to set here, as the cluster to which this domain belongs only contains one server.');  
         }          }
           $datatable .= '</td></tr>';
           $itemcount ++;
     } else {      } else {
         if (keys(%by_location) == 0) {          my %titles = &ssl_titles();
             $datatable .= '<tr'.$css_class.'><td colspan="2">'.          my (%by_ip,%by_location,@intdoms,@instdoms);
                           &mt('Nothing to set here, as the cluster to which this domain belongs only contains one institution.');          &build_location_hashes(\@intdoms,\%by_ip,\%by_location,\@instdoms);
         } else {          my @alldoms = &Apache::lonnet::all_domains();
             my %lt = &usersession_titles();          my %serverhomes = %Apache::lonnet::serverhomeIDs;
             my $numinrow = 5;          my @domservers = &Apache::lonnet::get_servers($dom);
             my $prefix;          my %servers = &Apache::lonnet::internet_dom_servers($dom);
             my @types;          my %altids = &id_for_thisdom(%servers);
             if ($position eq 'bottom') {          if (($position eq 'connto') || ($position eq 'connfrom')) {
                 $prefix = 'remote';              my $legacy;
                 @types = ('version','excludedomain','includedomain');              unless (ref($settings) eq 'HASH') {
             } else {                  my $name;
                 $prefix = 'hosted';                  if ($position eq 'connto') {
                 @types = ('excludedomain','includedomain');                      $name = 'loncAllowInsecure';
             }                  } else {
             my (%current,%checkedon,%checkedoff);                      $name = 'londAllowInsecure';
             my @lcversions = &Apache::lonnet::all_loncaparevs();                  }
             my @locations = sort(keys(%by_location));                  my $primarylibserv = &Apache::lonnet::domain($dom,'primary');
             foreach my $type (@types) {                  my @ids=&Apache::lonnet::current_machine_ids();
                 $checkedon{$type} = '';                  if (($primarylibserv ne '') && (!grep(/^\Q$primarylibserv\E$/,@ids))) {
                 $checkedoff{$type} = ' checked="checked"';                      my %what = (
             }                                     $name => 1,
             if (ref($settings) eq 'HASH') {                                 );
                 if (ref($settings->{$prefix}) eq 'HASH') {                      my ($result,$returnhash) =
                     foreach my $key (keys(%{$settings->{$prefix}})) {                          &Apache::lonnet::get_remote_globals($primarylibserv,\%what);
                         $current{$key} = $settings->{$prefix}{$key};                      if ($result eq 'ok') {
                         if ($key eq 'version') {                          if (ref($returnhash) eq 'HASH') {
                             if ($current{$key} ne '') {                              $legacy = $returnhash->{$name};
                                 $checkedon{$key} = ' checked="checked"';  
                                 $checkedoff{$key} = '';  
                             }  
                         } elsif (ref($current{$key}) eq 'ARRAY') {  
                             $checkedon{$key} = ' checked="checked"';  
                             $checkedoff{$key} = '';  
                         }                          }
                     }                      }
                   } else {
                       $legacy = $Apache::lonnet::perlvar{$name};
                 }                  }
             }              }
             foreach my $type (@types) {              foreach my $type ('dom','intdom','other') {
                 next if ($type ne 'version' && !@locations);                  my %checked;
                 $css_class = $itemcount%2 ? ' class="LC_odd_row"' : '';                  $css_class = $itemcount%2?' class="LC_odd_row"':'';
                 $datatable .= '<tr'.$css_class.'>                  $datatable .= '<tr'.$css_class.'><td>'.$titles{$type}.'</td>'.
                                <td><span class="LC_nobreak">'.$lt{$type}.'</span><br />                                '<td class="LC_right_item">';
                                <span class="LC_nobreak">&nbsp;                  my $skip; 
                                <label><input type="radio" name="'.$prefix.'_'.$type.'_inuse" '.$checkedoff{$type}.' value="0" />'.&mt('Not in use').'</label>&nbsp;                  if ($type eq 'dom') {
                                <label><input type="radio" name="'.$prefix.'_'.$type.'_inuse" '.$checkedon{$type}.' value="1" />'.&mt('In use').'</label></span></td><td>';                      unless (keys(%servers) > 1) {
                 if ($type eq 'version') {                          $datatable .= &mt('Nothing to set here, as there are no other servers/VMs');    
                     my $selector = '<select name="'.$prefix.'_version">';                          $skip = 1;
                     foreach my $version (@lcversions) {  
                         my $selected = '';  
                         if ($current{'version'} eq $version) {  
                             $selected = ' selected="selected"';  
                         }  
                         $selector .= ' <option value="'.$version.'"'.  
                                      $selected.'>'.$version.'</option>';  
                     }                      }
                     $selector .= '</select> ';                  }
                     $datatable .= &mt('remote server must be version: [_1] or later',$selector);                  if ($type eq 'intdom') {
                 } else {                      unless (@instdoms > 1) {
                     $datatable.= '<div><input type="button" value="'.&mt('check all').'" '.                          $datatable .= &mt('Nothing to set here, as there are no other domains for this institution');
                                  'onclick="javascript:checkAll(document.display.'.$prefix.'_'.$type.')"'.                          $skip = 1;
                                  ' />'.('&nbsp;'x2).                      } 
                                  '<input type="button" value="'.&mt('uncheck all').'" '.                  } elsif ($type eq 'other') {
                                  'onclick="javascript:uncheckAll(document.display.'.$prefix.'_'.$type.')" />'.                      if (keys(%by_location) == 0) {
                                  "\n".                          $datatable .= &mt('Nothing to set here, as there are no other institutions');
                                  '</div><div><table>';                          $skip = 1;
                     my $rem;                      }
                     for (my $i=0; $i<@locations; $i++) {                  }
                         my ($showloc,$value,$checkedtype);                  unless ($skip) {
                         if (ref($by_location{$locations[$i]}) eq 'ARRAY') {                      $checked{'yes'} = ' checked="checked"'; 
                             my $ip = $by_location{$locations[$i]}->[0];                      if (ref($settings) eq 'HASH') {
                             if (ref($by_ip{$ip}) eq 'ARRAY') {                          if (ref($settings->{$position}) eq 'HASH') {
                                  $value = join(':',@{$by_ip{$ip}});                              if ($settings->{$position}->{$type} =~ /^(no|req)$/) {
                                 $showloc = join(', ',@{$by_ip{$ip}});                                  $checked{$1} = $checked{'yes'};
                                 if (ref($current{$type}) eq 'ARRAY') {                                  delete($checked{'yes'}); 
                                     foreach my $loc (@{$by_ip{$ip}}) {    
                                         if (grep(/^\Q$loc\E$/,@{$current{$type}})) {  
                                             $checkedtype = ' checked="checked"';  
                                             last;  
                                         }  
                                     }  
                                 }  
                             }                              }
                         }                          }
                         $rem = $i%($numinrow);                      } else {
                         if ($rem == 0) {                          if ($legacy == 0) {
                             if ($i > 0) {                              $checked{'req'} = $checked{'yes'};
                                 $datatable .= '</tr>';                              delete($checked{'yes'});    
                             }                          }
                             $datatable .= '<tr>';  
                         }  
                         $datatable .= '<td class="LC_left_item">'.  
                                       '<span class="LC_nobreak"><label>'.  
                                       '<input type="checkbox" name="'.$prefix.'_'.$type.  
                                       '" value="'.$value.'"'.$checkedtype.' />'.$showloc.  
                                       '</label></span></td>';  
                     }                      }
                     $rem = @locations%($numinrow);                      foreach my $option ('no','yes','req') {
                     my $colsleft = $numinrow - $rem;                          $datatable .= '<span class="LC_nobreak"><label>'.
                     if ($colsleft > 1 ) {                                        '<input type="radio" name="'.$position.'_'.$type.'" '.
                         $datatable .= '<td colspan="'.$colsleft.'" class="LC_left_item">'.                                        'value="'.$option.'"'.$checked{$option}.' />'.$titles{$option}.
                                       '&nbsp;</td>';                                        '</label></span>'.('&nbsp;'x2);
                     } elsif ($colsleft == 1) {  
                         $datatable .= '<td class="LC_left_item">&nbsp;</td>';  
                     }                      }
                     $datatable .= '</tr></table>';  
                 }                  }
                 $datatable .= '</td></tr>';                  $datatable .= '</td></tr>';
                   $itemcount ++; 
               }
           } else {
               my $prefix = 'replication';
               my @types = ('certreq','nocertreq');
               if (keys(%by_location) == 0) {
                   $datatable .= '<tr'.$css_class.'><td>'.
                                 &mt('Nothing to set here, as there are no other institutions').
                                 '</td></tr>';
                 $itemcount ++;                  $itemcount ++;
               } else {
                   ($datatable,$itemcount) = 
                       &rules_by_location($settings,$prefix,\%by_location,\%by_ip,\@types,\%titles);
             }              }
         }          }
     }      }
Line 5241  sub print_usersessions { Line 5092  sub print_usersessions {
     return $datatable;      return $datatable;
 }  }
   
   sub ssl_titles {
       return &Apache::lonlocal::texthash (
                  dom           => 'LON-CAPA servers/VMs from same domain',
                  intdom        => 'LON-CAPA servers/VMs from same "internet" domain',
                  other         => 'External LON-CAPA servers/VMs',
                  connto        => 'Connections to other servers',
                  connfrom      => 'Connections from other servers',
                  replication   => 'Replicating content to other institutions',
                  certreq       => 'Client certificate required, but specific domains exempt',
                  nocertreq     => 'No client certificate required, except for specific domains',
                  no            => 'SSL not used',
                  yes           => 'SSL Optional (used if available)',
                  req           => 'SSL Required',
       );
   }
   
   sub print_trust {
       my ($prefix,$dom,$settings,$rowtotal) = @_;
       my ($css_class,$datatable,%checked,%choices);
       my (%by_ip,%by_location,@intdoms,@instdoms);
       &build_location_hashes(\@intdoms,\%by_ip,\%by_location,\@instdoms);
       my $itemcount = 1;
       my %titles = &trust_titles();
       my @types = ('exc','inc');
       if ($prefix eq 'top') {
           $prefix = 'content';
       } elsif ($prefix eq 'bottom') {
           $prefix = 'msg';
       }
       ($datatable,$itemcount) = &rules_by_location($settings,$prefix,\%by_location,\%by_ip,\@types,\%titles);
       $$rowtotal += $itemcount;
       return $datatable;
   }
   
   sub trust_titles {
       return &Apache::lonlocal::texthash(
                  content  => "Access to this domain's content by others",
                  shared   => "Access to other domain's content by this domain",
                  enroll   => "Enrollment in this domain's courses by others", 
                  othcoau  => "Co-author roles in this domain for others",
                  coaurem  => "Co-author roles for this domain's users elsewhere", 
                  domroles => "Domain roles in this domain assignable to others",
                  catalog  => "Course Catalog for this domain displayed elsewhere",
                  reqcrs   => "Requests for creation of courses in this domain by others",
                  msg      => "Users in other domains can send messages to this domain",
                  exc      => "Allow all, but exclude specific domains",
                  inc      => "Deny all, but include specific domains",
              );
   } 
   
 sub build_location_hashes {  sub build_location_hashes {
     my ($intdoms,$by_ip,$by_location) = @_;      my ($intdoms,$by_ip,$by_location,$instdoms) = @_;
     return unless((ref($intdoms) eq 'ARRAY') && (ref($by_ip) eq 'HASH') &&      return unless((ref($intdoms) eq 'ARRAY') && (ref($by_ip) eq 'HASH') &&
                   (ref($by_location) eq 'HASH'));                     (ref($by_location) eq 'HASH') && (ref($instdoms) eq 'ARRAY'));
     my %iphost = &Apache::lonnet::get_iphost();      my %iphost = &Apache::lonnet::get_iphost();
     my $primary_id = &Apache::lonnet::domain($env{'request.role.domain'},'primary');      my $primary_id = &Apache::lonnet::domain($env{'request.role.domain'},'primary');
     my $primary_ip = &Apache::lonnet::get_host_ip($primary_id);      my $primary_ip = &Apache::lonnet::get_host_ip($primary_id);
Line 5261  sub build_location_hashes { Line 5162  sub build_location_hashes {
             foreach my $id (@{$iphost{$ip}}) {              foreach my $id (@{$iphost{$ip}}) {
                 my $location = &Apache::lonnet::internet_dom($id);                  my $location = &Apache::lonnet::internet_dom($id);
                 if ($location) {                  if ($location) {
                     next if (grep(/^\Q$location\E$/,@{$intdoms}));                      if (grep(/^\Q$location\E$/,@{$intdoms})) {
                           my $dom = &Apache::lonnet::host_domain($id);
                           unless (grep(/^\Q$dom\E/,@{$instdoms})) {
                               push(@{$instdoms},$dom);
                           }
                           next;
                       }
                     if (ref($by_ip->{$ip}) eq 'ARRAY') {                      if (ref($by_ip->{$ip}) eq 'ARRAY') {
                         unless(grep(/^\Q$location\E$/,@{$by_ip->{$ip}})) {                          unless(grep(/^\Q$location\E$/,@{$by_ip->{$ip}})) {
                             push(@{$by_ip->{$ip}},$location);                              push(@{$by_ip->{$ip}},$location);
Line 5528  sub print_loadbalancing { Line 5435  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,%currcookies);      my (%currbalancer,%currtargets,%currrules,%existing);
     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,\%currcookies);                                    \%currtargets,\%currrules);
     } else {      } else {
         return;          return;
     }      }
Line 5568  sub print_loadbalancing { Line 5475  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 5601  sub print_loadbalancing { Line 5508  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 5611  sub print_loadbalancing { Line 5518  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 5669  sub print_loadbalancing { Line 5573  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 5682  sub print_loadbalancing { Line 5581  sub print_loadbalancing {
                           'value="'.$sparetype.'"'.$hostherechecked{$sparetype}.' /><i>'.$typetitles{$sparetype}.                            'value="'.$sparetype.'"'.$hostherechecked{$sparetype}.' /><i>'.$typetitles{$sparetype}.
                           '</i></label><br />';                            '</i></label><br />';
         }          }
         $datatable .= &mt('Use balancer cookie').'<br />'.          $datatable .= '</div></td></tr>'.
                       '<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 5701  sub print_loadbalancing { Line 5595  sub print_loadbalancing {
 }  }
   
 sub get_loadbalancers_config {  sub get_loadbalancers_config {
     my ($servers,$existing,$currbalancer,$currtargets,$currrules,$currcookies) = @_;      my ($servers,$existing,$currbalancer,$currtargets,$currrules) = @_;
     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 5724  sub get_loadbalancers_config { Line 5617  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 5830  sub loadbalance_rule_row { Line 5720  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 5922  sub contact_titles { Line 5812  sub contact_titles {
                    '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',
                    'hostipmail'      => 'E-mail from nightly check of hostname/IP network changes',  
                  );                   );
     my %short_titles = &Apache::lonlocal::texthash (      my %short_titles = &Apache::lonlocal::texthash (
                            adminemail   => 'Admin E-mail address',                             adminemail   => 'Admin E-mail address',
Line 5969  sub tool_titles { Line 5858  sub tool_titles {
                      unofficial => 'Unofficial courses',                       unofficial => 'Unofficial courses',
                      community  => 'Communities',                       community  => 'Communities',
                      textbook   => 'Textbook courses',                       textbook   => 'Textbook courses',
                        placement  => 'Placement tests',
                  );                   );
     return %titles;      return %titles;
 }  }
Line 5979  sub courserequest_titles { Line 5869  sub courserequest_titles {
                                    unofficial => 'Unofficial',                                     unofficial => 'Unofficial',
                                    community  => 'Communities',                                     community  => 'Communities',
                                    textbook   => 'Textbook',                                     textbook   => 'Textbook',
                                      placement  => 'Placement tests',
                                    norequest  => 'Not allowed',                                     norequest  => 'Not allowed',
                                    approval   => 'Approval by Dom. Coord.',                                     approval   => 'Approval by Dom. Coord.',
                                    validate   => 'With validation',                                     validate   => 'With validation',
Line 6069  sub print_usercreation { Line 5960  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 6191  sub print_selfcreation { Line 6082  sub print_selfcreation {
         ($datatable,$itemcount) = &radiobutton_prefs(\%radiohash,\@toggles,\%defaultchecked,          ($datatable,$itemcount) = &radiobutton_prefs(\%radiohash,\@toggles,\%defaultchecked,
                                                      \%choices,$itemcount,$onclick);                                                       \%choices,$itemcount,$onclick);
         $$rowtotal += $itemcount;          $$rowtotal += $itemcount;
           
         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,
Line 6209  sub print_selfcreation { Line 6100  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>'."\n";                       '<table><tr><td>'."\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 6328  sub print_selfcreation { Line 6219  sub print_selfcreation {
                 my $currstyle = 'display:none';                  my $currstyle = 'display:none';
                 if (grep(/^\Q$status\E$/,@ordered)) {                  if (grep(/^\Q$status\E$/,@ordered)) {
                     $currstyle = $rowstyle;                      $currstyle = $rowstyle;
                     $hidden = 0;                      $hidden = 0; 
                 }                  }
                 $datatable .= &noninst_users($processing,$emailverified,$emailoptions,$emaildomain,                  $datatable .= &noninst_users($processing,$emailverified,$emailoptions,$emaildomain,
                                              $emailrules,$emailruleorder,$settings,$status,$rowid,                                               $emailrules,$emailruleorder,$settings,$status,$rowid,
Line 6355  sub print_selfcreation { Line 6246  sub print_selfcreation {
             foreach my $status (@posstypes) {              foreach my $status (@posstypes) {
                 my $rowid = $classprefix.$status;                  my $rowid = $classprefix.$status;
                 my $datarowstyle = 'display:none';                  my $datarowstyle = 'display:none';
                 if (grep(/^\Q$status\E$/,@ordered)) {                  if (grep(/^\Q$status\E$/,@ordered)) { 
                     $datarowstyle = $rowstyle;                      $datarowstyle = $rowstyle; 
                 }                  }
                 $datatable .= &modifiable_userdata_row('cancreate','emailusername_'.$status,$settings,                  $datatable .= &modifiable_userdata_row('cancreate','emailusername_'.$status,$settings,
                                                        $numinrow,$$rowtotal,\%usertypeshash,$infofields,                                                         $numinrow,$$rowtotal,\%usertypeshash,$infofields,
Line 6458  function toggleEmailOptions(form,radio,p Line 6349  function toggleEmailOptions(form,radio,p
                     document.getElementById(altprefix+'_inst_'+status).style.display = 'none';                      document.getElementById(altprefix+'_inst_'+status).style.display = 'none';
                     document.getElementById(altprefix+'_noninst_'+status).style.display = 'none';                      document.getElementById(altprefix+'_noninst_'+status).style.display = 'none';
                     if (curr == 'custom') {                      if (curr == 'custom') {
                         if (prefix) {                          if (prefix) { 
                             document.getElementById(prefix+'_'+status).style.display = 'inline';                              document.getElementById(prefix+'_'+status).style.display = 'inline';
                         }                          }
                     } else if (curr == 'inst') {                      } else if (curr == 'inst') {
Line 6481  ENDSCRIPT Line 6372  ENDSCRIPT
   
 sub noninst_users {  sub noninst_users {
     my ($processing,$emailverified,$emailoptions,$emaildomain,$emailrules,      my ($processing,$emailverified,$emailoptions,$emaildomain,$emailrules,
         $emailruleorder,$settings,$type,$rowid,$typetitle,$css_class,$rowstyle,$intdom) = @_;          $emailruleorder,$settings,$type,$rowid,$typetitle,$css_class,$rowstyle,$intdom) = @_; 
     my $class = 'LC_left_item';      my $class = 'LC_left_item';
     if ($css_class) {      if ($css_class) {
         $css_class = ' class="'.$css_class.'"';          $css_class = ' class="'.$css_class.'"'; 
     }      }
     if ($rowid) {      if ($rowid) {
         $rowid = ' id="'.$rowid.'"';          $rowid = ' id="'.$rowid.'"';
Line 6499  sub noninst_users { Line 6390  sub noninst_users {
         $description = &mt('Requests for: [_1] (status self-reported)',$typetitle);          $description = &mt('Requests for: [_1] (status self-reported)',$typetitle);
     }      }
     $output = '<tr'.$css_class.$rowid.$rowstyle.'>'.      $output = '<tr'.$css_class.$rowid.$rowstyle.'>'.
               "<td>$description</td>\n".                "<td>$description</td>\n".           
               '<td class="'.$class.'" colspan="2">'.                '<td class="'.$class.'" colspan="2">'.
               '<table><tr>';                '<table><tr>';
     my %headers = &Apache::lonlocal::texthash(      my %headers = &Apache::lonlocal::texthash( 
               approve  => 'Processing',                approve  => 'Processing',
               email    => 'E-mail',                email    => 'E-mail',
               username => 'Username',                username => 'Username',
Line 6512  sub noninst_users { Line 6403  sub noninst_users {
     }      }
     $output .= '</tr><tr>';      $output .= '</tr><tr>';
     foreach my $item ('approve','email','username') {      foreach my $item ('approve','email','username') {
         $output .= '<td valign="top">';          $output .= '<td style="vertical-align: top">';
         my (%choices,@options,$hashref,$defoption,$name,$onclick,$hascustom);          my (%choices,@options,$hashref,$defoption,$name,$onclick,$hascustom);
         if ($item eq 'approve') {          if ($item eq 'approve') {
             %choices = &Apache::lonlocal::texthash (              %choices = &Apache::lonlocal::texthash (
Line 6627  sub noninst_users { Line 6518  sub noninst_users {
                     my $value;                      my $value;
                     if (ref($emaildomain) eq 'HASH') {                      if (ref($emaildomain) eq 'HASH') {
                         if (ref($emaildomain->{$type}) eq 'HASH') {                          if (ref($emaildomain->{$type}) eq 'HASH') {
                             $value = $emaildomain->{$type}->{$option};                              $value = $emaildomain->{$type}->{$option}; 
                         }                          }
                     }                      }
                     if ($value eq '') {                      if ($value eq '') {
Line 6654  sub noninst_users { Line 6545  sub noninst_users {
 sub captcha_choice {  sub captcha_choice {
     my ($context,$settings,$itemcount,$customcss,$rowstyle) = @_;      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();
     $keyentry = 'hidden';      $keyentry = 'hidden';
     my $colspan=2;  
     if ($context eq 'cancreate') {      if ($context eq 'cancreate') {
         $rowname = &mt('CAPTCHA validation');          $rowname = &mt('CAPTCHA validation');
     } elsif ($context eq 'login') {      } elsif ($context eq 'login') {
         $rowname =  &mt('"Contact helpdesk" CAPTCHA validation');          $rowname =  &mt('"Contact helpdesk" CAPTCHA validation');
     } elsif ($context eq 'passwords') {  
         $rowname = &mt('"Forgot Password" CAPTCHA validation');  
         $colspan=1;  
     }      }
     if (ref($settings) eq 'HASH') {      if (ref($settings) eq 'HASH') {
         if ($settings->{'captcha'}) {          if ($settings->{'captcha'}) {
Line 6704  sub captcha_choice { Line 6591  sub captcha_choice {
         $css_class .= ' style="'.$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="'.$colspan.'">'."\n".                   '<td class="LC_left_item">'.$rowname.'</td><td class="LC_left_item" colspan="2">'."\n".
                  '<table><tr><td>'."\n";                   '<table><tr><td>'."\n";
     foreach my $option ('original','recaptcha','notused') {      foreach my $option ('original','recaptcha','notused') {
         $output .= '<span class="LC_nobreak"><label><input type="radio" name="'.$context.'_captcha" value="'.          $output .= '<span class="LC_nobreak"><label><input type="radio" name="'.$context.'_captcha" value="'.
Line 6941  sub print_defaults { Line 6828  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 wisth="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') {
Line 6965  sub print_defaults { Line 6931  sub print_defaults {
                     $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></tr>';                                    '</span></td></tr>';
                 }                  }
Line 6984  sub print_defaults { Line 6950  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>'.
                               '</tr>'."\n";                                '</tr>'."\n";
Line 7033  sub defaults_titles { Line 6999  sub defaults_titles {
     return (\%titles);      return (\%titles);
 }  }
   
 sub print_scantron {  
     my ($r,$position,$dom,$confname,$settings,$rowtotal) = @_;  
     if ($position eq 'top') {  
         return &print_scantronformat($r,$dom,$confname,$settings,\$rowtotal);  
     } else {  
         return &print_scantronconfig($dom,$settings,\$rowtotal);  
     }  
 }  
   
 sub scantron_javascript {  
     return <<"ENDSCRIPT";  
   
 <script type="text/javascript">  
 // <![CDATA[  
   
 function toggleScantron(form) {  
     var csvfieldset = new Array();  
     if (document.getElementById('scantroncsv_cols')) {  
         csvfieldset.push(document.getElementById('scantroncsv_cols'));  
     }  
     if (document.getElementById('scantroncsv_options')) {  
         csvfieldset.push(document.getElementById('scantroncsv_options'));  
     }  
     if (csvfieldset.length) {  
         if (document.getElementById('scantronconfcsv')) {  
             var scantroncsv = document.getElementById('scantronconfcsv');  
             if (scantroncsv.checked) {  
                 for (var i=0; i<csvfieldset.length; i++) {  
                     csvfieldset[i].style.display = 'block';  
                 }  
             } else {  
                 for (var i=0; i<csvfieldset.length; i++) {  
                     csvfieldset[i].style.display = 'none';  
                 }  
                 var csvselects = document.getElementsByClassName('scantronconfig_csv');  
                 if (csvselects.length) {  
                     for (var j=0; j<csvselects.length; j++) {  
                         csvselects[j].selectedIndex = 0;  
                     }  
                 }  
             }  
         }  
     }  
     return;  
 }  
 // ]]>  
 </script>  
   
 ENDSCRIPT  
   
 }  
   
 sub print_scantronformat {  sub print_scantronformat {
     my ($r,$dom,$confname,$settings,$rowtotal) = @_;      my ($r,$dom,$confname,$settings,$rowtotal) = @_;
     my $itemcount = 1;      my $itemcount = 1;
Line 7111  sub print_scantronformat { Line 7025  sub print_scantronformat {
             if ($configuserok eq 'ok') {              if ($configuserok eq 'ok') {
                 if ($author_ok eq 'ok') {                  if ($author_ok eq 'ok') {
                     my %legacyfile = (                      my %legacyfile = (
  default => $Apache::lonnet::perlvar{'lonTabDir'}.'/default_scantronformat.tab',   default => $Apache::lonnet::perlvar{'lonTabDir'}.'/default_scantronformat.tab', 
  custom  => $Apache::lonnet::perlvar{'lonTabDir'}.'/scantronformat.tab',   custom  => $Apache::lonnet::perlvar{'lonTabDir'}.'/scantronformat.tab', 
                     );                      );
                     my %md5chk;                      my %md5chk;
                     foreach my $type (keys(%legacyfile)) {                      foreach my $type (keys(%legacyfile)) {
Line 7121  sub print_scantronformat { Line 7035  sub print_scantronformat {
                     }                      }
                     if ($md5chk{'default'} ne $md5chk{'custom'}) {                      if ($md5chk{'default'} ne $md5chk{'custom'}) {
                         foreach my $type (keys(%legacyfile)) {                          foreach my $type (keys(%legacyfile)) {
                             ($scantronurls{$type},my $error) =                              ($scantronurls{$type},my $error) = 
                                 &legacy_scantronformat($r,$dom,$confname,                                  &legacy_scantronformat($r,$dom,$confname,
                                                  $type,$legacyfile{$type},                                                   $type,$legacyfile{$type},
                                                  $scantronurls{$type},                                                   $scantronurls{$type},
Line 7132  sub print_scantronformat { Line 7046  sub print_scantronformat {
                         }                          }
                         if (keys(%error) == 0) {                          if (keys(%error) == 0) {
                             $is_custom = 1;                              $is_custom = 1;
                             $confhash{'scantron'}{'scantronformat'} =                              $confhash{'scantron'}{'scantronformat'} = 
                                 $scantronurls{'custom'};                                  $scantronurls{'custom'};
                             my $putresult =                              my $putresult = 
                                 &Apache::lonnet::put_dom('configuration',                                  &Apache::lonnet::put_dom('configuration',
                                                          \%confhash,$dom);                                                           \%confhash,$dom);
                             if ($putresult ne 'ok') {                              if ($putresult ne 'ok') {
                                 $error{'custom'} =                                  $error{'custom'} = 
                                     '<span class="LC_error">'.                                      '<span class="LC_error">'.
                                     &mt('An error occurred updating the domain configuration: [_1]',$putresult).'</span>';                                      &mt('An error occurred updating the domain configuration: [_1]',$putresult).'</span>';
                             }                              }
Line 7201  sub print_scantronformat { Line 7115  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 7258  sub legacy_scantronformat { Line 7172  sub legacy_scantronformat {
     return ($url,$error);      return ($url,$error);
 }  }
   
 sub print_scantronconfig {  
     my ($dom,$settings,$rowtotal) = @_;  
     my $itemcount = 2;  
     my $is_checked = ' checked="checked"';  
     my %optionson = (  
                      hdr => ' checked="checked"',  
                      pad => ' checked="checked"',  
                      rem => ' checked="checked"',  
                     );  
     my %optionsoff = (  
                       hdr => '',  
                       pad => '',  
                       rem => '',  
                      );  
     my $currcsvsty = 'none';  
     my ($datatable,%csvfields,%checked,%onclick,%csvoptions);  
     my @fields = &scantroncsv_fields();  
     my %titles = &scantronconfig_titles();  
     if (ref($settings) eq 'HASH') {  
         if (ref($settings->{config}) eq 'HASH') {  
             if ($settings->{config}->{dat}) {  
                 $checked{'dat'} = $is_checked;  
             }  
             if (ref($settings->{config}->{csv}) eq 'HASH') {  
                 if (ref($settings->{config}->{csv}->{fields}) eq 'HASH') {  
                     %csvfields = %{$settings->{config}->{csv}->{fields}};  
                     if (keys(%csvfields) > 0) {  
                         $checked{'csv'} = $is_checked;  
                         $currcsvsty = 'block';  
                     }  
                 }  
                 if (ref($settings->{config}->{csv}->{options}) eq 'HASH') {  
                     %csvoptions = %{$settings->{config}->{csv}->{options}};  
                     foreach my $option (keys(%optionson)) {  
                         unless ($csvoptions{$option}) {  
                             $optionsoff{$option} = $optionson{$option};  
                             $optionson{$option} = '';  
                         }  
                     }  
                 }  
             }  
         } else {  
             $checked{'dat'} = $is_checked;  
         }  
     } else {  
         $checked{'dat'} = $is_checked;  
     }  
     $onclick{'csv'} = ' onclick="toggleScantron(this.form);"';  
     my $css_class = $itemcount%2? ' class="LC_odd_row"':'';  
     $datatable = '<tr '.$css_class.'><td>'.&mt('Supported formats').'</td>'.  
                  '<td class="LC_left_item" valign="top"><span class="LC_nobreak">';  
     foreach my $item ('dat','csv') {  
         my $id;  
         if ($item eq 'csv') {  
             $id = 'id="scantronconfcsv" ';  
         }  
         $datatable .= '<label><input type="checkbox" name="scantronconfig" '.$id.'value="'.$item.'"'.$checked{$item}.$onclick{$item}.' />'.  
                       $titles{$item}.'</label>'.('&nbsp;'x3);  
         if ($item eq 'csv') {  
             $datatable .= '<fieldset style="display:'.$currcsvsty.'" id="scantroncsv_cols">'.  
                           '<legend>'.&mt('CSV Column Mapping').'</legend>'.  
                           '<table><tr><th>'.&mt('Field').'</th><th>'.&mt('Location').'</th></tr>'."\n";  
             foreach my $col (@fields) {  
                 my $selnone;  
                 if ($csvfields{$col} eq '') {  
                     $selnone = ' selected="selected"';  
                 }  
                 $datatable .= '<tr><td>'.$titles{$col}.'</td>'.  
                               '<td><select name="scantronconfig_csv_'.$col.'" class="scantronconfig_csv">'.  
                               '<option value=""'.$selnone.'></option>';  
                 for (my $i=0; $i<20; $i++) {  
                     my $shown = $i+1;  
                     my $sel;  
                     unless ($selnone) {  
                         if (exists($csvfields{$col})) {  
                             if ($csvfields{$col} == $i) {  
                                 $sel = ' selected="selected"';  
                             }  
                         }  
                     }  
                     $datatable .= '<option value="'.$i.'"'.$sel.'>'.$shown.'</option>';  
                 }  
                 $datatable .= '</select></td></tr>';  
            }  
            $datatable .= '</table></fieldset>'.  
                          '<fieldset style="display:'.$currcsvsty.'" id="scantroncsv_options">'.  
                          '<legend>'.&mt('CSV Options').'</legend>';  
            foreach my $option ('hdr','pad','rem') {  
                $datatable .= '<span class="LC_nobreak">'.$titles{$option}.':'.  
                          '<label><input type="radio" name="scantroncsv_'.$option.'" value="1"'.$optionson{$option}.' />'.  
                          &mt('Yes').'</label>'.('&nbsp;'x2)."\n".  
                          '<label><input type="radio" name="scantroncsv_'.$option.'" value="0"'.$optionsoff{$option}.' />'.&mt('No').'</label></span><br />';  
            }  
            $datatable .= '</fieldset>';  
            $itemcount ++;  
         }  
     }  
     $datatable .= '</td></tr>';  
     $$rowtotal ++;  
     return $datatable;  
 }  
   
 sub scantronconfig_titles {  
     return &Apache::lonlocal::texthash(  
                                           dat => 'Standard format (.dat)',  
                                           csv => 'Comma separated values (.csv)',  
                                           hdr => 'Remove first line in file (contains column titles)',  
                                           pad => 'Prepend 0s to PaperID',  
                                           rem => 'Remove leading spaces (except Question Response columns)',  
                                           CODE => 'CODE',  
                                           ID   => 'Student ID',  
                                           PaperID => 'Paper ID',  
                                           FirstName => 'First Name',  
                                           LastName => 'Last Name',  
                                           FirstQuestion => 'First Question Response',  
                                           Section => 'Section',  
     );  
 }  
   
 sub scantroncsv_fields {  
     return ('PaperID','LastName','FirstName','ID','Section','CODE','FirstQuestion');  
 }  
   
 sub print_coursecategories {  sub print_coursecategories {
     my ($position,$dom,$hdritem,$settings,$rowtotal) = @_;      my ($position,$dom,$hdritem,$settings,$rowtotal) = @_;
     my $datatable;      my $datatable;
Line 7423  sub print_coursecategories { Line 7214  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 .= '</span></td></tr>';             $datatable .= '</td></tr>';
            $itemcount ++;             $itemcount ++;
         }          }
         $$rowtotal += $itemcount;          $$rowtotal += $itemcount;
Line 7436  sub print_coursecategories { Line 7227  sub print_coursecategories {
         my $toggle_catscomm_dom = ' checked="checked" ';          my $toggle_catscomm_dom = ' checked="checked" ';
         my $can_catcomm_comm = ' ';          my $can_catcomm_comm = ' ';
         my $can_catcomm_dom = ' checked="checked" ';          my $can_catcomm_dom = ' checked="checked" ';
           my $toggle_catsplace_place = ' ';
           my $toggle_catsplace_dom = ' checked="checked" ';
           my $can_catplace_place = ' ';
           my $can_catplace_dom = ' checked="checked" ';
   
         if (ref($settings) eq 'HASH') {          if (ref($settings) eq 'HASH') {
             if ($settings->{'togglecats'} eq 'crs') {              if ($settings->{'togglecats'} eq 'crs') {
Line 7454  sub print_coursecategories { Line 7249  sub print_coursecategories {
                 $can_catcomm_comm = $can_catcomm_dom;                  $can_catcomm_comm = $can_catcomm_dom;
                 $can_catcomm_dom = ' ';                  $can_catcomm_dom = ' ';
             }              }
               if ($settings->{'togglecatsplace'} eq 'place') {
                   $toggle_catsplace_place = $toggle_catsplace_dom;
                   $toggle_catsplace_dom = ' ';
               }
               if ($settings->{'categorizeplace'} eq 'place') {
                   $can_catplace_place = $can_catplace_dom;
                   $can_catplace_dom = ' ';
               }
         }          }
         my %title = &Apache::lonlocal::texthash (          my %title = &Apache::lonlocal::texthash (
                      togglecats     => 'Show/Hide a course in catalog',                       togglecats      => 'Show/Hide a course in catalog',
                      togglecatscomm => 'Show/Hide a community in catalog',                       togglecatscomm  => 'Show/Hide a community in catalog',
                      categorize     => 'Assign a category to a course',                       togglecatsplace => 'Show/Hide a placement test in catalog',
                      categorizecomm => 'Assign a category to a community',                       categorize      => 'Assign a category to a course',
                        categorizecomm  => 'Assign a category to a community',
                        categorizeplace => 'Assign a category to a placement test',
                     );                      );
         my %level = &Apache::lonlocal::texthash (          my %level = &Apache::lonlocal::texthash (
                      dom  => 'Set in Domain',                       dom   => 'Set in Domain',
                      crs  => 'Set in Course',                       crs   => 'Set in Course',
                      comm => 'Set in Community',                       comm  => 'Set in Community',
                        place => 'Set in Placement Test',
                     );                      );
         $datatable = '<tr class="LC_odd_row">'.          $datatable = '<tr class="LC_odd_row">'.
                   '<td>'.$title{'togglecats'}.'</td>'.                    '<td>'.$title{'togglecats'}.'</td>'.
Line 7494  sub print_coursecategories { Line 7300  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>'.
                     '<td>'.$title{'togglecatsplace'}.'</td>'.
                     '<td class="LC_right_item"><span class="LC_nobreak"><label>'.
                     '<input type="radio" name="togglecatsplace"'.
                     $toggle_catsplace_dom.' value="dom" />'.$level{'dom'}.'</label>&nbsp;'.
                     '<label><input type="radio" name="togglecatscomm"'.
                     $toggle_catsplace_place.' value="comm" />'.$level{'place'}.'</label></span></td>'.
                     '</tr><tr>'.
                     '<td>'.$title{'categorizeplace'}.'</td>'.
                     '<td class="LC_right_item"><span class="LC_nobreak">'.
                     '<label><input type="radio" name="categorizeplace"'.
                     $can_catplace_dom.' value="dom" />'.$level{'dom'}.'</label>&nbsp;'.
                     '<label><input type="radio" name="categorizeplace"'.
                     $can_catplace_place.'value="place" />'.$level{'place'}.'</label></span></td>'.
                   '</tr>';                    '</tr>';
         $$rowtotal += 4;          $$rowtotal += 6;
     } else {      } else {
         my $css_class;          my $css_class;
         my $itemcount = 1;          my $itemcount = 1;
Line 7520  sub print_coursecategories { Line 7340  sub print_coursecategories {
                     my %default_names = (                      my %default_names = (
                           instcode    => &mt('Official courses'),                            instcode    => &mt('Official courses'),
                           communities => &mt('Communities'),                            communities => &mt('Communities'),
                             placement   => &mt('Placement Tests'),
                     );                      );
   
                     if ((!grep(/^instcode$/,@{$cats[0]})) ||                       if ((!grep(/^instcode$/,@{$cats[0]})) || 
                         ($cathash->{'instcode::0'} eq '') ||                          ($cathash->{'instcode::0'} eq '') ||
                         (!grep(/^communities$/,@{$cats[0]})) ||                           (!grep(/^communities$/,@{$cats[0]})) || 
                         ($cathash->{'communities::0'} eq '')) {                          ($cathash->{'communities::0'} eq '') ||
                           (!grep(/^placement$/,@{$cats[0]})) ||
                           ($cathash->{'placement::0'} eq '')) {
                         $maxnum ++;                          $maxnum ++;
                     }                      }
                     my $lastidx;                      my $lastidx;
Line 7546  sub print_coursecategories { Line 7369  sub print_coursecategories {
                             $datatable .= '<option value="'.$k.'"'.$selstr.'>'.$vpos.'</option>';                              $datatable .= '<option value="'.$k.'"'.$selstr.'>'.$vpos.'</option>';
                         }                          }
                         $datatable .= '</select></span></td><td>';                          $datatable .= '</select></span></td><td>';
                         if ($parent eq 'instcode' || $parent eq 'communities') {                          if ($parent eq 'instcode' || $parent eq 'communities' || $parent eq 'placement') {
                             $datatable .=  '<span class="LC_nobreak">'                              $datatable .=  '<span class="LC_nobreak">'
                                            .$default_names{$parent}.'</span>';                                             .$default_names{$parent}.'</span>';
                             if ($parent eq 'instcode') {                              if ($parent eq 'instcode') {
Line 7569  sub print_coursecategories { Line 7392  sub print_coursecategories {
                             $datatable .= '<label><input type="radio" name="'                              $datatable .= '<label><input type="radio" name="'
                                           .$parent.'" value="0" />'                                            .$parent.'" value="0" />'
                                           .&mt('Do not display').'</label></span>';                                            .&mt('Do not display').'</label></span>';
                             if ($parent eq 'communities') {                              if (($parent eq 'communities') || ($parent eq 'placement')) {
                                 $datatable .= '</td></tr></table>';                                  $datatable .= '</td></tr></table>';
                             }                              }
                             $datatable .= '</td>';                              $datatable .= '</td>';
Line 7601  sub print_coursecategories { Line 7424  sub print_coursecategories {
                                   .'<input type="text" size="20" name="addcategory_name" value="" /></td>'                                    .'<input type="text" size="20" name="addcategory_name" value="" /></td>'
                                   .'</tr>'."\n";                                    .'</tr>'."\n";
                     $itemcount ++;                      $itemcount ++;
                     foreach my $default ('instcode','communities') {                      foreach my $default ('instcode','communities','placement') {
                         if ((!grep(/^\Q$default\E$/,@{$cats[0]})) || ($cathash->{$default.'::0'} eq '')) {                          if ((!grep(/^\Q$default\E$/,@{$cats[0]})) || ($cathash->{$default.'::0'} eq '')) {
                             $css_class = $itemcount%2?' class="LC_odd_row"':'';                              $css_class = $itemcount%2?' class="LC_odd_row"':'';
                             my $chgstr = ' onchange="javascript:reorderCats(this.form,'."'','$default"."_pos','$lastidx'".');"';                              my $chgstr = ' onchange="javascript:reorderCats(this.form,'."'','$default"."_pos','$lastidx'".');"';
Line 7634  sub print_coursecategories { Line 7457  sub print_coursecategories {
                 $datatable .= &initialize_categories($itemcount);                  $datatable .= &initialize_categories($itemcount);
             }              }
         } else {          } else {
             $datatable .= '<tr><td class="LC_right_item">'.$hdritem->{'header'}->[1]->{'col2'}.'</td></tr>'              $datatable .= '<td class="LC_right_item">'.$hdritem->{'header'}->[1]->{'col2'}.'</td>'
                           .&initialize_categories($itemcount);                            .&initialize_categories($itemcount);
         }          }
         $$rowtotal += $itemcount;          $$rowtotal += $itemcount;
Line 7682  sub print_serverstatuses { Line 7505  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" />'.
                       '</span></td></tr>'."\n";                        '</td></tr>'."\n";
     }      }
     $$rowtotal += $rownum;      $$rowtotal += $rownum;
     return $datatable;      return $datatable;
Line 7690  sub print_serverstatuses { Line 7513  sub print_serverstatuses {
   
 sub serverstatus_pages {  sub serverstatus_pages {
     return ('userstatus','lonstatus','loncron','server-status','codeversions',      return ('userstatus','lonstatus','loncron','server-status','codeversions',
             'checksums','clusterstatus','metadata_keywords','metadata_harvest',              'checksums','clusterstatus','certstatus','metadata_keywords',
             'takeoffline','takeonline','showenv','toggledebug','ping','domconf',              'metadata_harvest','takeoffline','takeonline','showenv','toggledebug',
             'uniquecodes','diskusage','coursecatalog');              'ping','domconf','uniquecodes','diskusage','coursecatalog');
 }  }
   
 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 7751  $jstext Line 7602  $jstext
     return;      return;
 }  }
   
   $intauthjs
   
 // ]]>  // ]]>
 </script>  </script>
   
 ENDSCRIPT  ENDSCRIPT
     }  
 }  
   
 sub passwords_javascript {  
     my %intalert = &Apache::lonlocal::texthash (  
         authcheck => '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.',  
         authcost => 'Warning: bcrypt encryption cost for internal authentication must be an integer.',  
         passmin => 'Warning: minimum password length must be a positive integer greater than 6.',  
         passmax => 'Warning: maximum password length must be a positive integer (or blank).',  
         passexp => 'Warning: days before password expiration must be a positive integer (or blank).',  
         passnum => 'Warning: number of previous passwords to save must be a positive integer (or blank).',  
     );  
     &js_escape(\%intalert);  
     my $defmin = $Apache::lonnet::passwdmin;  
     my $intauthjs = <<"ENDSCRIPT";  
   
 function warnIntAuth(field) {  
     if (field.name == 'intauth_check') {  
         if (field.value == '2') {  
             alert('$intalert{authcheck}');  
         }  
     }  
     if (field.name == 'intauth_cost') {  
         field.value.replace(/\s/g,'');  
         if (field.value != '') {  
             var regexdigit=/^\\d+\$/;  
             if (!regexdigit.test(field.value)) {  
                 alert('$intalert{authcost}');  
             }  
         }  
     }  
     return;  
 }  
   
 function warnIntPass(field) {  
     field.value.replace(/^\s+/,'');  
     field.value.replace(/\s+\$/,'');  
     var regexdigit=/^\\d+\$/;  
     if (field.name == 'passwords_min') {  
         if (field.value == '') {  
             alert('$intalert{passmin}');  
             field.value = '$defmin';  
         } else {  
             if (!regexdigit.test(field.value)) {  
                 alert('$intalert{passmin}');  
                 field.value = '$defmin';  
             }  
             var minval = parseInt(field.value,10);  
             if (minval < $defmin) {  
                 alert('$intalert{passmin}');  
                 field.value = '$defmin';  
             }  
         }  
     } else {      } else {
         if (field.value == '0') {          return &Apache::lonhtmlcommon::scripttag($intauthjs);
             field.value = '';  
         }  
         if (field.value != '') {  
             if (field.name == 'passwords_expire') {  
                 var regexpposnum=/^\\d+(|\\.\\d*)\$/;  
                 if (!regexpposnum.test(field.value)) {  
                     alert('$intalert{passexp}');  
                     field.value = '';  
                 } else {  
                     var expval = parseFloat(field.value);  
                     if (expval == 0) {  
                         alert('$intalert{passexp}');  
                         field.value = '';  
                     }  
                 }  
             } else {  
                 if (!regexdigit.test(field.value)) {  
                     if (field.name == 'passwords_max') {  
                         alert('$intalert{passmax}');  
                     } else {  
                         if (field.name == 'passwords_numsaved') {  
                             alert('$intalert{passnum}');  
                         }  
                     }  
                     field.value = '';  
                 }  
             }  
         }  
     }      }
     return;  
 }  
   
 ENDSCRIPT  
     return &Apache::lonhtmlcommon::scripttag($intauthjs);  
 }  }
   
 sub coursecategories_javascript {  sub coursecategories_javascript {
Line 7870  sub coursecategories_javascript { Line 7637  sub coursecategories_javascript {
     }      }
     my $instcode_reserved = &mt('The name: [_1] is a reserved category.','"instcode"');      my $instcode_reserved = &mt('The name: [_1] is a reserved category.','"instcode"');
     my $communities_reserved = &mt('The name: [_1] is a reserved category.','"communities"');      my $communities_reserved = &mt('The name: [_1] is a reserved category.','"communities"');
       my $placement_reserved = &mt('The name: [_1] is a reserved category.','"placement"');
     my $choose_again = "\n".&mt('Please use a different name for the new top level category.');       my $choose_again = "\n".&mt('Please use a different name for the new top level category.'); 
     &js_escape(\$instcode_reserved);      &js_escape(\$instcode_reserved);
     &js_escape(\$communities_reserved);      &js_escape(\$communities_reserved);
       &js_escape(\$placement_reserved);
     &js_escape(\$choose_again);      &js_escape(\$choose_again);
     $output = <<"ENDSCRIPT";      $output = <<"ENDSCRIPT";
 <script type="text/javascript">  <script type="text/javascript">
Line 7942  function categoryCheck(form) { Line 7711  function categoryCheck(form) {
         alert('$communities_reserved\\n$choose_again');          alert('$communities_reserved\\n$choose_again');
         return false;          return false;
     }      }
       if (form.elements['addcategory_name'].value == 'placement') {
           alert('$placement_reserved\\n$choose_again');
           return false;
       }
     return true;      return true;
 }  }
   
Line 7958  sub initialize_categories { Line 7731  sub initialize_categories {
     my %default_names = (      my %default_names = (
                       instcode    => 'Official courses (with institutional codes)',                        instcode    => 'Official courses (with institutional codes)',
                       communities => 'Communities',                        communities => 'Communities',
                         placement   => 'Placement Tests',
                         );                          );
     my $select0 = ' selected="selected"';      my $select0 = ' selected="selected"';
     my $select1 = '';      my $select1 = '';
     foreach my $default ('instcode','communities') {      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') {          if (($default eq 'communities') || ($default eq 'placement')) {
             $select1 = $select0;              $select1 = $select0;
             $select0 = '';              $select0 = '';
         }          }
Line 7988  sub initialize_categories { Line 7762  sub initialize_categories {
                   .'<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" selected="selected">3</option></select>&nbsp;'
                   .&mt('Add category').'</span></td><td><span class="LC_nobreak">'.&mt('Name:')                    .&mt('Add category').'</td><td>'.&mt('Name:')
                   .'&nbsp;<input type="text" size="20" name="addcategory_name" value="" /></span>'                    .'&nbsp;<input type="text" size="20" name="addcategory_name" value="" /></td></tr>';
                   .'</td></tr>';  
     return $datatable;      return $datatable;
 }  }
   
Line 8045  sub build_category_rows { Line 7818  sub build_category_rows {
                             pop(@{$path});                              pop(@{$path});
                         }                          }
                     } else {                      } else {
                         $text .= &mt('Add subcategory:').'&nbsp;</span><input type="text" size="20" name="addcategory_name_';                          $text .= &mt('Add subcategory:').'&nbsp;</span><input type="textbox" size="20" name="addcategory_name_';
                         if ($j == $numchildren) {                          if ($j == $numchildren) {
                             $text .= $name;                              $text .= $name;
                         } else {                          } else {
Line 8068  sub build_category_rows { Line 7841  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="text" size="20" name="subcat_'.$name.'" value="" /></td>';                      $text .= '<td colspan="'.$colspan.'">'.&mt('Add subcategory:').'<input type="textbox" size="20" name="subcat_'.$name.'" value="" /></td>';
                 }                  }
             }              }
         }          }
Line 8136  sub modifiable_userdata_row { Line 7909  sub modifiable_userdata_row {
     if ($rowid) {      if ($rowid) {
         $rowid = ' id="'.$rowid.'"';          $rowid = ' id="'.$rowid.'"';
     }      }
   
     $output = '<tr '.$css_class.$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>';
Line 8171  sub modifiable_userdata_row { Line 7943  sub modifiable_userdata_row {
             }              }
         }          }
     }      }
    
     my $total = scalar(@fields);      my $total = scalar(@fields);
     for (my $i=0; $i<$total; $i++) {      for (my $i=0; $i<$total; $i++) {
         $rem = $i%($numinrow);          $rem = $i%($numinrow);
Line 8184  sub modifiable_userdata_row { Line 7956  sub modifiable_userdata_row {
         my $check = ' ';          my $check = ' ';
         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 {              } else {
                 if ($role eq 'st') {                  if ($role eq 'st') {
                     if (ref($settings) ne 'HASH') {                      if (ref($settings) ne 'HASH') {
Line 8298  sub insttypes_row { Line 8070  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.$onclick.'/>'.                             'value="'.$types->[$i].'"'.$check.$onclick.' />'.
                            $usertypes->{$types->[$i]}.'</label></span></td>';                             $usertypes->{$types->[$i]}.'</label></span></td>';
             }              }
         }          }
Line 8311  sub insttypes_row { Line 8083  sub insttypes_row {
         } else {          } else {
             $output .= '<td class="LC_left_item">';              $output .= '<td class="LC_left_item">';
         }          }
         $output .= '&nbsp;';          $output .= '&nbsp;';  
     } else {      } else {
         if ($rem == 0) {          if (($rem == 0) && (@{$types} > 0)) {
             $output .= '<tr>';              $output .= '<tr>';
         }          }
         if ($colsleft > 1) {          if ($colsleft > 1) {
Line 9243  sub display_colorchgs { Line 9015  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 9296  sub check_configuser { Line 9068  sub check_configuser {
     my ($configuserok,%currroles);      my ($configuserok,%currroles);
     if ($uhome eq 'no_host') {      if ($uhome eq 'no_host') {
         srand( time() ^ ($$ + ($$ << 15))  ); # Seed rand.          srand( time() ^ ($$ + ($$ << 15))  ); # Seed rand.
         my $configpass = &LONCAPA::Enrollment::create_password($dom);          my $configpass = &LONCAPA::Enrollment::create_password();
         $configuserok =           $configuserok = 
             &Apache::lonnet::modifyuser($dom,$confname,'','internal',              &Apache::lonnet::modifyuser($dom,$confname,'','internal',
                              $configpass,'','','','','',undef,$servadm);                               $configpass,'','','','','',undef,$servadm);
Line 9325  sub check_authorstatus { Line 9097  sub check_authorstatus {
   
 sub publishlogo {  sub publishlogo {
     my ($r,$action,$formname,$dom,$confname,$subdir,$thumbwidth,$thumbheight,$savefileas) = @_;      my ($r,$action,$formname,$dom,$confname,$subdir,$thumbwidth,$thumbheight,$savefileas) = @_;
     my ($output,$fname,$logourl);      my ($output,$fname,$logourl,$madethumb);
     if ($action eq 'upload') {      if ($action eq 'upload') {
         $fname=$env{'form.'.$formname.'.filename'};          $fname=$env{'form.'.$formname.'.filename'};
         chop($env{'form.'.$formname});          chop($env{'form.'.$formname});
Line 9454  $env{'user.name'}.':'.$env{'user.domain' Line 9226  $env{'user.name'}.':'.$env{'user.domain'
                                     $r->set_handlers('PerlCleanupHandler' => [\&notifysubscribed,@{$handlers}]);                                      $r->set_handlers('PerlCleanupHandler' => [\&notifysubscribed,@{$handlers}]);
                                     $registered_cleanup=1;                                      $registered_cleanup=1;
                                 }                                  }
                                   $madethumb = 1;
                             } else {                              } else {
                                 print $logfile "\nUnable to write ".$copyfile.                                  print $logfile "\nUnable to write ".$copyfile.
                                                ':'.$!."\n";                                                 ':'.$!."\n";
Line 9466  $env{'user.name'}.':'.$env{'user.domain' Line 9239  $env{'user.name'}.':'.$env{'user.domain'
             $output = $versionresult;              $output = $versionresult;
         }          }
     }      }
     return ($output,$logourl);      return ($output,$logourl,$madethumb);
 }  }
   
 sub logo_versioning {  sub logo_versioning {
Line 9620  sub modify_quotas { Line 9393  sub modify_quotas {
         $context = $action;          $context = $action;
     }      }
     if ($context eq 'requestcourses') {      if ($context eq 'requestcourses') {
         @usertools = ('official','unofficial','community','textbook');          @usertools = ('official','unofficial','community','textbook','placement');
         @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 9669  sub modify_quotas { Line 9442  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');          my @crstypes = ('official','unofficial','community','textbook','placement');
         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 9791  sub modify_quotas { Line 9564  sub modify_quotas {
                                             &Apache::lonnet::logthis($error);                                              &Apache::lonnet::logthis($error);
                                             $errors .= '<li><span class="LC_error">'.$error.'</span></li>';                                              $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 10356  sub modify_ltitools { Line 10129  sub modify_ltitools {
     map { $posslti{$_} = 1; } @ltiroles;      map { $posslti{$_} = 1; } @ltiroles;
     my @allfields = ('fullname','firstname','lastname','email','user','roles');      my @allfields = ('fullname','firstname','lastname','email','user','roles');
     map { $possfield{$_} = 1; } @allfields;      map { $possfield{$_} = 1; } @allfields;
     my %lt = &ltitools_names();      my %lt = &ltitools_names(); 
     if ($env{'form.ltitools_add'}) {      if ($env{'form.ltitools_add'}) {
         my $title = $env{'form.ltitools_add_title'};          my $title = $env{'form.ltitools_add_title'};
         $title =~ s/(`)/'/g;          $title =~ s/(`)/'/g;
Line 10393  sub modify_ltitools { Line 10166  sub modify_ltitools {
                     }                      }
                 } else {                  } else {
                     if ($env{'form.ltitools_add_'.$item} ne '') {                      if ($env{'form.ltitools_add_'.$item} ne '') {
                         $confhash{$newid}{'display'}{$item} = $env{'form.ltitools_add_'.$item};                          $confhash{$newid}{'display'}{$item} = $env{'form.ltitools_add_'.$item}; 
                     }                      }
                 }                  }
             }              }
Line 10405  sub modify_ltitools { Line 10178  sub modify_ltitools {
                 $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 '') {
Line 10430  sub modify_ltitools { Line 10210  sub modify_ltitools {
                             if (($choice ne '') && ($posslti{$choice})) {                              if (($choice ne '') && ($posslti{$choice})) {
                                 $confhash{$newid}{'roles'}{$role} = $choice;                                  $confhash{$newid}{'roles'}{$role} = $choice;
                                 if ($role eq 'cc') {                                  if ($role eq 'cc') {
                                     $confhash{$newid}{'roles'}{'co'} = $choice;                                      $confhash{$newid}{'roles'}{'co'} = $choice; 
                                 }                                  }
                             }                              }
                         }                          }
Line 10451  sub modify_ltitools { Line 10231  sub modify_ltitools {
                 $confhash{$newid}{'custom'}{$name} = $value;                  $confhash{$newid}{'custom'}{$name} = $value;
             }              }
         } else {          } else {
             my $error = &mt('Failed to acquire unique ID for new external tool');              my $error = &mt('Failed to acquire unique ID for new external tool');   
             $errors .= '<li><span class="LC_error">'.$error.'</span></li>';              $errors .= '<li><span class="LC_error">'.$error.'</span></li>';
         }          }
     }      }
Line 10465  sub modify_ltitools { Line 10245  sub modify_ltitools {
         my @newcustom = &Apache::loncommon::get_env_multiple('form.ltitools_customadd');          my @newcustom = &Apache::loncommon::get_env_multiple('form.ltitools_customadd');
         if (@newcustom) {          if (@newcustom) {
             map { $customadds{$_} = 1; } @newcustom;              map { $customadds{$_} = 1; } @newcustom;
         }          } 
         my %imgdeletions;          my %imgdeletions;
         my @todeleteimages = &Apache::loncommon::get_env_multiple('form.ltitools_image_del');          my @todeleteimages = &Apache::loncommon::get_env_multiple('form.ltitools_image_del');
         if (@todeleteimages) {          if (@todeleteimages) {
Line 10556  sub modify_ltitools { Line 10336  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_add'};
                                   $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','linktext','explanation') {                      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 10642  sub modify_ltitools { Line 10432  sub modify_ltitools {
                     }                      }
                 }                  }
                 my %customdels;                  my %customdels;
                 my @customdeletions = &Apache::loncommon::get_env_multiple('form.ltitools_customdel_'.$i);                  my @customdeletions = &Apache::loncommon::get_env_multiple('form.ltitools_customdel_'.$i); 
                 if (@customdeletions) {                  if (@customdeletions) {
                     $changes{$itemid} = 1;                      $changes{$itemid} = 1;
                 }                  }
Line 10651  sub modify_ltitools { Line 10441  sub modify_ltitools {
                     foreach my $key (keys(%{$domconfig{$action}{$itemid}{'custom'}})) {                      foreach my $key (keys(%{$domconfig{$action}{$itemid}{'custom'}})) {
                         unless ($customdels{$key}) {                          unless ($customdels{$key}) {
                             if ($env{'form.ltitools_customval_'.$key.'_'.$i} ne '') {                              if ($env{'form.ltitools_customval_'.$key.'_'.$i} ne '') {
                                 $confhash{$itemid}{'custom'}{$key} = $env{'form.ltitools_customval_'.$key.'_'.$i};                                  $confhash{$itemid}{'custom'}{$key} = $env{'form.ltitools_customval_'.$key.'_'.$i}; 
                             }                              }
                             if ($domconfig{$action}{$itemid}{'custom'}{$key} ne $env{'form.ltitools_customval_'.$key.'_'.$i}) {                              if ($domconfig{$action}{$itemid}{'custom'}{$key} ne $env{'form.ltitools_customval_'.$key.'_'.$i}) {
                                 $changes{$itemid} = 1;                                  $changes{$itemid} = 1;
Line 10726  sub modify_ltitools { Line 10516  sub modify_ltitools {
                 $bynum{$position} = $itemid;                  $bynum{$position} = $itemid;
             }              }
             foreach my $pos (sort { $a <=> $b } keys(%bynum)) {              foreach my $pos (sort { $a <=> $b } keys(%bynum)) {
                 my $itemid = $bynum{$pos};                  my $itemid = $bynum{$pos}; 
                 if (ref($confhash{$itemid}) ne 'HASH') {                  if (ref($confhash{$itemid}) ne 'HASH') {
                     $resulttext .= '<li>'.&mt('Deleted: [_1]',$changes{$itemid}).'</li>';                      $resulttext .= '<li>'.&mt('Deleted: [_1]',$changes{$itemid}).'</li>';
                 } else {                  } else {
Line 10753  sub modify_ltitools { Line 10543  sub modify_ltitools {
                         $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','linktext','explanation');                      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 ++;
Line 10771  sub modify_ltitools { Line 10561  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 10782  sub modify_ltitools { Line 10581  sub modify_ltitools {
                             $displaylist = &mt('Display target').':&nbsp;'.                              $displaylist = &mt('Display target').':&nbsp;'.
                                            $confhash{$itemid}{'display'}{'target'}.',';                                             $confhash{$itemid}{'display'}{'target'}.',';
                         }                          }
                         foreach my $size ('width','height') {                          foreach my $size ('width','height') { 
                             if ($confhash{$itemid}{'display'}{$size}) {                              if ($confhash{$itemid}{'display'}{$size}) {
                                 $displaylist .= ('&nbsp;'x2).$lt{$size}.':&nbsp;'.                                  $displaylist .= ('&nbsp;'x2).$lt{$size}.':&nbsp;'.
                                                 $confhash{$itemid}{'display'}{$size}.',';                                                  $confhash{$itemid}{'display'}{$size}.',';
Line 10819  sub modify_ltitools { Line 10618  sub modify_ltitools {
                             }                              }
                         }                          }
                         if ($rolemaps) {                          if ($rolemaps) {
                             $rolemaps =~ s/,$//;                              $rolemaps =~ s/,$//; 
                             $resulttext .= '<li>'.&mt('Role mapping:').$rolemaps.'</li>';                              $resulttext .= '<li>'.&mt('Role mapping:').$rolemaps.'</li>';
                         }                          }
                     }                      }
Line 10828  sub modify_ltitools { Line 10627  sub modify_ltitools {
                         if (keys(%{$confhash{$itemid}{'custom'}})) {                          if (keys(%{$confhash{$itemid}{'custom'}})) {
                             foreach my $key (sort(keys(%{$confhash{$itemid}{'custom'}}))) {                              foreach my $key (sort(keys(%{$confhash{$itemid}{'custom'}}))) {
                                 $customlist .= $key.':'.$confhash{$itemid}{'custom'}{$key}.('&nbsp;'x2);                                  $customlist .= $key.':'.$confhash{$itemid}{'custom'}{$key}.('&nbsp;'x2);
                             }                              } 
                         }                          }
                         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 10894  sub get_ltitools_id { Line 10693  sub get_ltitools_id {
     my $tries = 0;      my $tries = 0;
     my $gotlock = &Apache::lonnet::newput_dom('ltitools',$lockhash,$cdom);      my $gotlock = &Apache::lonnet::newput_dom('ltitools',$lockhash,$cdom);
     my ($id,$error);      my ($id,$error);
    
     while (($gotlock ne 'ok') && ($tries<10)) {      while (($gotlock ne 'ok') && ($tries<10)) {
         $tries ++;          $tries ++;
         sleep (0.1);          sleep (0.1);
Line 11512  sub modify_contacts { Line 11311  sub modify_contacts {
     my (%others,%to,%bcc,%includestr,%includeloc);      my (%others,%to,%bcc,%includestr,%includeloc);
     my @contacts = ('supportemail','adminemail');      my @contacts = ('supportemail','adminemail');
     my @mailings = ('errormail','packagesmail','helpdeskmail','otherdomsmail',      my @mailings = ('errormail','packagesmail','helpdeskmail','otherdomsmail',
                     'lonstatusmail','requestsmail','updatesmail','idconflictsmail','hostipmail');                      'lonstatusmail','requestsmail','updatesmail','idconflictsmail');
     my @toggles = ('reporterrors','reportupdates');      my @toggles = ('reporterrors','reportupdates');
     my ($fields,$fieldtitles,$fieldoptions,$possoptions) = &helpform_fields();      my ($fields,$fieldtitles,$fieldoptions,$possoptions) = &helpform_fields();
     foreach my $type (@mailings) {      foreach my $type (@mailings) {
Line 11600  sub modify_contacts { Line 11399  sub modify_contacts {
                     $contacts_hash{'contacts'}{'overrides'}{$type}{'include'} = $includeloc{$type}.':'.&escape($includestr{$type});                      $contacts_hash{'contacts'}{'overrides'}{$type}{'include'} = $includeloc{$type}.':'.&escape($includestr{$type});
                     $newsetting{'override_'.$type}{'include'} = $contacts_hash{'contacts'}{'overrides'}{$type}{'include'};                      $newsetting{'override_'.$type}{'include'} = $contacts_hash{'contacts'}{'overrides'}{$type}{'include'};
                 }                  }
             }                  }     
         }          }
     }      }
     if (keys(%currsetting) > 0) {      if (keys(%currsetting) > 0) {
Line 11658  sub modify_contacts { Line 11457  sub modify_contacts {
             }              }
         }          }
         if (@statuses) {          if (@statuses) {
             if (ref($currsetting{'overrides'}) eq 'HASH') {              if (ref($currsetting{'overrides'}) eq 'HASH') { 
                 foreach my $key (keys(%{$currsetting{'overrides'}})) {                  foreach my $key (keys(%{$currsetting{'overrides'}})) {
                     if (ref($currsetting{'overrides'}{$key}) eq 'HASH') {                      if (ref($currsetting{'overrides'}{$key}) eq 'HASH') {
                         if (ref($newsetting{'override_'.$key}) eq 'HASH') {                          if (ref($newsetting{'override_'.$key}) eq 'HASH') {
                             foreach my $item (@contacts,'bcc','others','include') {                              foreach my $item (@contacts,'bcc','others','include') {
                                 if ($currsetting{'overrides'}{$key}{$item} ne $newsetting{'override_'.$key}{$item}) {                                  if ($currsetting{'overrides'}{$key}{$item} ne $newsetting{'override_'.$key}{$item}) { 
                                     push(@{$changes{'overrides'}},$key);                                      push(@{$changes{'overrides'}},$key);
                                     last;                                      last;
                                 }                                  }
Line 11680  sub modify_contacts { Line 11479  sub modify_contacts {
                 }                  }
             } else {              } else {
                 foreach my $key (@overrides) {                  foreach my $key (@overrides) {
                     push(@{$changes{'overrides'}},$key);                      push(@{$changes{'overrides'}},$key); 
                 }                  }
             }              }
         }          }
Line 11695  sub modify_contacts { Line 11494  sub modify_contacts {
         $default{'lonstatusmail'} = 'adminemail';          $default{'lonstatusmail'} = 'adminemail';
         $default{'requestsmail'} = 'adminemail';          $default{'requestsmail'} = 'adminemail';
         $default{'updatesmail'} = 'adminemail';          $default{'updatesmail'} = 'adminemail';
         $default{'hostipmail'} = 'adminemail';  
         foreach my $item (@contacts) {          foreach my $item (@contacts) {
            if ($to{$item} ne $default{$item}) {             if ($to{$item} ne $default{$item}) {
                $changes{$item} = 1;                 $changes{$item} = 1;
Line 11785  sub modify_contacts { Line 11583  sub modify_contacts {
                             $resulttext .= $bcctext.': <span class="LC_cusr_emph">'.$bcc{$type}.'</span>';                              $resulttext .= $bcctext.': <span class="LC_cusr_emph">'.$bcc{$type}.'</span>';
                         } 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};
Line 11809  sub modify_contacts { Line 11607  sub modify_contacts {
                             if (ref($newsetting{'override_'.$type}) eq 'HASH') {                              if (ref($newsetting{'override_'.$type}) eq 'HASH') {
                                 my @text;                                  my @text;
                                 foreach my $item (@contacts) {                                  foreach my $item (@contacts) {
                                     if ($newsetting{'override_'.$type}{$item}) {                                      if ($newsetting{'override_'.$type}{$item}) { 
                                         push(@text,$short_titles->{$item});                                          push(@text,$short_titles->{$item});
                                     }                                      }
                                 }                                  }
                                 if ($newsetting{'override_'.$type}{'others'} ne '') {                                  if ($newsetting{'override_'.$type}{'others'} ne '') {
                                     push(@text,$newsetting{'override_'.$type}{'others'});                                      push(@text,$newsetting{'override_'.$type}{'others'});
                                 }                                  }
     
                                 if (@text) {                                  if (@text) {
                                     $resulttext .= &mt('Helpdesk e-mail sent to: [_1]',                                      $resulttext .= &mt('Helpdesk e-mail sent to: [_1]',
                                                        '<span class="LC_cusr_emph">'.join(', ',@text).'</span>');                                                         '<span class="LC_cusr_emph">'.join(', ',@text).'</span>');
Line 11921  sub modify_contacts { Line 11719  sub modify_contacts {
     return $resulttext;      return $resulttext;
 }  }
   
 sub modify_passwords {  
     my ($r,$dom,$confname,$lastactref,%domconfig) = @_;  
     my ($resulttext,%current,%changes,%newvalues,@oktypes,$errors,  
         $updatedefaults,$updateconf);  
     my $customfn = 'resetpw.html';  
     if (ref($domconfig{'passwords'}) eq 'HASH') {  
         %current = %{$domconfig{'passwords'}};  
     }  
     my %domdefaults = &Apache::lonnet::get_domain_defaults($dom,1);  
     my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom);  
     if (ref($types) eq 'ARRAY') {  
         @oktypes = @{$types};  
     }  
     push(@oktypes,'default');  
   
     my %titles = &Apache::lonlocal::texthash (  
         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',  
         permanent      => 'Permanent e-mail address',  
         critical       => 'Critical notification address',  
         notify         => 'Notification address',  
         min            => 'Minimum password length',  
         max            => 'Maximum password length',  
         chars          => 'Required characters',  
         numsaved       => 'Number of previous passwords to save',  
         reset          => 'Resetting Forgotten Password',  
         intauth        => 'Encryption of Stored Passwords (Internal Auth)',  
         rules          => 'Rules for LON-CAPA Passwords',  
         crsownerchg    => 'Course Owner Changing Student Passwords',  
         username       => 'Username',  
         email          => 'E-mail address',  
     );  
   
 #  
 # Retrieve current domain configuration for internal authentication from $domconfig{'defaults'}.  
 #  
     my (%curr_defaults,%save_defaults);  
     if (ref($domconfig{'defaults'}) eq 'HASH') {  
         foreach my $key (keys(%{$domconfig{'defaults'}})) {  
             if ($key =~ /^intauth_(cost|check|switch)$/) {  
                 $curr_defaults{$key} = $domconfig{'defaults'}{$key};  
             } else {  
                 $save_defaults{$key} = $domconfig{'defaults'}{$key};  
             }  
         }  
     }  
     my %staticdefaults = (  
         'resetlink'      => 2,  
         'resetcase'      => \@oktypes,  
         'resetprelink'   => 'both',  
         'resetemail'     => ['critical','notify','permanent'],  
         'intauth_cost'   => 10,  
         'intauth_check'  => 0,  
         'intauth_switch' => 0,  
     );  
     $staticdefaults{'min'} = $Apache::lonnet::passwdmin;  
     foreach my $type (@oktypes) {  
         $staticdefaults{'resetpostlink'}{$type} = ['email','username'];  
     }  
     my $linklife = $env{'form.passwords_link'};  
     $linklife =~ s/^\s+|\s+$//g;  
     if (($linklife =~ /^\d+(|\.\d*)$/) && ($linklife > 0)) {  
         $newvalues{'resetlink'} = $linklife;  
         if ($current{'resetlink'}) {  
             if ($current{'resetlink'} ne $linklife) {  
                 $changes{'reset'} = 1;  
             }  
         } elsif (!ref($domconfig{passwords}) eq 'HASH') {  
             if ($staticdefaults{'resetlink'} ne $linklife) {  
                 $changes{'reset'} = 1;  
             }  
         }  
     } elsif ($current{'resetlink'}) {  
         $changes{'reset'} = 1;  
     }  
     my @casesens;  
     my @posscase = &Apache::loncommon::get_env_multiple('form.passwords_case_sensitive');  
     foreach my $case (sort(@posscase)) {  
         if (grep(/^\Q$case\E$/,@oktypes)) {  
             push(@casesens,$case);  
         }  
     }  
     $newvalues{'resetcase'} = \@casesens;  
     if (ref($current{'resetcase'}) eq 'ARRAY') {  
         my @diffs = &Apache::loncommon::compare_arrays($current{'resetcase'},\@casesens);  
         if (@diffs > 0) {  
             $changes{'reset'} = 1;  
         }  
     } elsif (!ref($domconfig{passwords}) eq 'HASH') {  
         my @diffs = &Apache::loncommon::compare_arrays($staticdefaults{'resetcase'},\@casesens);  
         if (@diffs > 0) {  
             $changes{'reset'} = 1;  
         }  
     }  
     if ($env{'form.passwords_prelink'} =~ /^(both|either)$/) {  
         $newvalues{'resetprelink'} = $env{'form.passwords_prelink'};  
         if (exists($current{'resetprelink'})) {  
             if ($current{'resetprelink'} ne $newvalues{'resetprelink'}) {  
                 $changes{'reset'} = 1;  
             }  
         } elsif (!ref($domconfig{passwords}) eq 'HASH') {  
             if ($staticdefaults{'resetprelink'} ne $newvalues{'resetprelink'}) {  
                 $changes{'reset'} = 1;  
             }  
         }  
     } elsif ($current{'resetprelink'}) {  
         $changes{'reset'} = 1;  
     }  
     foreach my $type (@oktypes) {  
         my @possplink = &Apache::loncommon::get_env_multiple('form.passwords_postlink_'.$type);  
         my @postlink;  
         foreach my $item (sort(@possplink)) {  
             if ($item =~ /^(email|username)$/) {  
                 push(@postlink,$item);  
             }  
         }  
         $newvalues{'resetpostlink'}{$type} = \@postlink;  
         unless ($changes{'reset'}) {  
             if (ref($current{'resetpostlink'}) eq 'HASH') {  
                 if (ref($current{'resetpostlink'}{$type}) eq 'ARRAY') {  
                     my @diffs = &Apache::loncommon::compare_arrays($current{'resetpostlink'}{$type},\@postlink);  
                     if (@diffs > 0) {  
                         $changes{'reset'} = 1;  
                     }  
                 } else {  
                     $changes{'reset'} = 1;  
                 }  
             } elsif (!ref($domconfig{passwords}) eq 'HASH') {  
                 my @diffs = &Apache::loncommon::compare_arrays($staticdefaults{'resetpostlink'}{$type},\@postlink);  
                 if (@diffs > 0) {  
                     $changes{'reset'} = 1;  
                 }  
             }  
         }  
     }  
     my @possemailsrc = &Apache::loncommon::get_env_multiple('form.passwords_emailsrc');  
     my @resetemail;  
     foreach my $item (sort(@possemailsrc)) {  
         if ($item =~ /^(permanent|critical|notify)$/) {  
             push(@resetemail,$item);  
         }  
     }  
     $newvalues{'resetemail'} = \@resetemail;  
     unless ($changes{'reset'}) {  
         if (ref($current{'resetemail'}) eq 'ARRAY') {  
             my @diffs = &Apache::loncommon::compare_arrays($current{'resetemail'},\@resetemail);  
             if (@diffs > 0) {  
                 $changes{'reset'} = 1;  
             }  
         } elsif (!ref($domconfig{passwords}) eq 'HASH') {  
             my @diffs = &Apache::loncommon::compare_arrays($staticdefaults{'resetemail'},\@resetemail);  
             if (@diffs > 0) {  
                 $changes{'reset'} = 1;  
             }  
         }  
     }  
     if ($env{'form.passwords_stdtext'} == 0) {  
         $newvalues{'resetremove'} = 1;  
         unless ($current{'resetremove'}) {  
             $changes{'reset'} = 1;  
         }  
     } elsif ($current{'resetremove'}) {  
         $changes{'reset'} = 1;  
     }  
     if ($env{'form.passwords_customfile.filename'} ne '') {  
         my $servadm = $r->dir_config('lonAdmEMail');  
         my $servadm = $r->dir_config('lonAdmEMail');  
         my ($configuserok,$author_ok,$switchserver) =  
             &config_check($dom,$confname,$servadm);  
         my $error;  
         if ($configuserok eq 'ok') {  
             if ($switchserver) {  
                 $error = &mt("Upload of file containing domain-specific text is not permitted to this server: [_1]",$switchserver);  
             } else {  
                 if ($author_ok eq 'ok') {  
                     my ($result,$customurl) =  
                         &publishlogo($r,'upload','passwords_customfile',$dom,  
                                      $confname,'customtext/resetpw','','',$customfn);  
                     if ($result eq 'ok') {  
                         $newvalues{'resetcustom'} = $customurl;  
                         $changes{'reset'} = 1;  
                     } else {  
                         $error = &mt("Upload of [_1] failed because an error occurred publishing the file in RES space. Error was: [_2].",$customfn,$result);  
                     }  
                 } else {  
                     $error = &mt("Upload of [_1] failed because an author role could not be assigned to a Domain Configuration user ([_2]) in domain: [_3].  Error was: [_4].",$customfn,$confname,$dom,$author_ok);  
                 }  
             }  
         } else {  
             $error = &mt("Upload of [_1] failed because a Domain Configuration user ([_2]) could not be created in domain: [_3].  Error was: [_4].",$customfn,$confname,$dom,$configuserok);  
         }  
         if ($error) {  
             &Apache::lonnet::logthis($error);  
             $errors .= '<li><span class="LC_error">'.$error.'</span></li>';  
         }  
     } elsif ($current{'resetcustom'}) {  
         if ($env{'form.passwords_custom_del'}) {  
             $changes{'reset'} = 1;  
         } else {  
             $newvalues{'resetcustom'} = $current{'resetcustom'};  
         }  
     }  
     $env{'form.intauth_cost'} =~ s/^\s+|\s+$//g;  
     if (($env{'form.intauth_cost'} ne '') && ($env{'form.intauth_cost'} =~ /^\d+$/)) {  
         $save_defaults{'intauth_cost'} = $env{'form.intauth_cost'};  
         if ($save_defaults{'intauth_cost'} ne $curr_defaults{'intauth_cost'}) {  
             $changes{'intauth'} = 1;  
         }  
     } else {  
         $save_defaults{'intauth_cost'} = $curr_defaults{'intauth_cost'};  
     }  
     if ($env{'form.intauth_check'} =~ /^(0|1|2)$/) {  
         $save_defaults{'intauth_check'} = $env{'form.intauth_check'};  
         if ($save_defaults{'intauth_check'} ne $curr_defaults{'intauth_check'}) {  
             $changes{'intauth'} = 1;  
         }  
     } else {  
         $save_defaults{'intauth_check'} = $curr_defaults{'intauth_check'};  
     }  
     if ($env{'form.intauth_switch'} =~ /^(0|1|2)$/) {  
         $save_defaults{'intauth_switch'} = $env{'form.intauth_switch'};  
         if ($save_defaults{'intauth_switch'} ne $curr_defaults{'intauth_switch'}) {  
             $changes{'intauth'} = 1;  
         }  
     } else {  
         $save_defaults{'intauth_check'} = $curr_defaults{'intauth_check'};  
     }  
     foreach my $item ('cost','check','switch') {  
         if ($save_defaults{'intauth_'.$item} ne $domdefaults{'intauth_'.$item}) {  
             $domdefaults{'intauth_'.$item} = $save_defaults{'intauth_'.$item};  
             $updatedefaults = 1;  
         }  
     }  
     foreach my $rule ('min','max','numsaved') {  
         $env{'form.passwords_'.$rule} =~ s/^\s+|\s+$//g;  
         my $ruleok;  
         if ($rule eq 'min') {  
             if ($env{'form.passwords_'.$rule} =~ /^\d+$/) {  
                 if ($env{'form.passwords_'.$rule} >= $Apache::lonnet::passwdmin) {  
                     $ruleok = 1;  
                 }  
             }  
         } elsif (($env{'form.passwords_'.$rule} =~ /^\d+$/) &&  
                  ($env{'form.passwords_'.$rule} ne '0')) {  
             $ruleok = 1;  
         }  
         if ($ruleok) {  
             $newvalues{$rule} = $env{'form.passwords_'.$rule};  
             if (exists($current{$rule})) {  
                 if ($newvalues{$rule} ne $current{$rule}) {  
                     $changes{'rules'} = 1;  
                 }  
             } elsif ($rule eq 'min') {  
                 if ($staticdefaults{$rule} ne $newvalues{$rule}) {  
                     $changes{'rules'} = 1;  
                 }  
             } else {  
                 $changes{'rules'} = 1;  
             }  
         } elsif (exists($current{$rule})) {  
             $changes{'rules'} = 1;  
         }  
     }  
     my @posschars = &Apache::loncommon::get_env_multiple('form.passwords_chars');  
     my @chars;  
     foreach my $item (sort(@posschars)) {  
         if ($item =~ /^(uc|lc|num|spec)$/) {  
             push(@chars,$item);  
         }  
     }  
     $newvalues{'chars'} = \@chars;  
     unless ($changes{'rules'}) {  
         if (ref($current{'chars'}) eq 'ARRAY') {  
             my @diffs = &Apache::loncommon::compare_arrays($current{'chars'},\@chars);  
             if (@diffs > 0) {  
                 $changes{'rules'} = 1;  
             }  
         } else {  
             if (@chars > 0) {  
                 $changes{'rules'} = 1;  
             }  
         }  
     }  
     my %crsownerchg = (  
                         by => [],  
                         for => [],  
                       );  
     foreach my $item ('by','for') {  
         my @posstypes = &Apache::loncommon::get_env_multiple('form.passwords_crsowner_'.$item);  
         foreach my $type (sort(@posstypes)) {  
             if (grep(/^\Q$type\E$/,@oktypes)) {  
                 push(@{$crsownerchg{$item}},$type);  
             }  
         }  
     }  
     $newvalues{'crsownerchg'} = \%crsownerchg;  
     if (ref($current{'crsownerchg'}) eq 'HASH') {  
         foreach my $item ('by','for') {  
             if (ref($current{'crsownerchg'}{$item}) eq 'ARRAY') {  
                 my @diffs = &Apache::loncommon::compare_arrays($current{'crsownerchg'}{$item},$crsownerchg{$item});  
                 if (@diffs > 0) {  
                     $changes{'crsownerchg'} = 1;  
                     last;  
                 }  
             }  
         }  
     } elsif (!(ref($domconfig{passwords}) eq 'HASH')) {  
         foreach my $item ('by','for') {  
             if (@{$crsownerchg{$item}} > 0) {  
                 $changes{'crsownerchg'} = 1;  
                 last;  
             }  
         }  
     }  
   
     my %confighash = (  
                         defaults  => \%save_defaults,  
                         passwords => \%newvalues,  
                      );  
     &process_captcha('passwords',\%changes,$confighash{'passwords'},$domconfig{'passwords'});  
   
     my $putresult = &Apache::lonnet::put_dom('configuration',\%confighash,$dom);  
     if ($putresult eq 'ok') {  
         if (keys(%changes) > 0) {  
             $resulttext = &mt('Changes made: ').'<ul>';  
             foreach my $key ('reset','intauth','rules','crsownerchg') {  
                 if ($changes{$key}) {  
                     unless ($key eq 'intauth') {  
                         $updateconf = 1;  
                     }  
                     $resulttext .= '<li>'.$titles{$key}.':<ul>';  
                     if ($key eq 'reset') {  
                         if ($confighash{'passwords'}{'captcha'} eq 'original') {  
                             $resulttext .= '<li>'.&mt('CAPTCHA validation set to use: original CAPTCHA').'</li>';  
                         } elsif ($confighash{'passwords'}{'captcha'} eq 'recaptcha') {  
                             $resulttext .= '<li>'.&mt('CAPTCHA validation set to use: reCAPTCHA').' '.  
                                            &mt('version: [_1]',$confighash{'passwords'}{'recaptchaversion'}).'<br />';  
                             if (ref($confighash{'passwords'}{'recaptchakeys'}) eq 'HASH') {  
                                 $resulttext .= &mt('Public key: [_1]',$confighash{'passwords'}{'recaptchakeys'}{'public'}).'</br>'.  
                                                &mt('Private key: [_1]',$confighash{'passwords'}{'recaptchakeys'}{'private'}).'</li>';  
                             }  
                         } else {  
                             $resulttext .= '<li>'.&mt('No CAPTCHA validation').'</li>';  
                         }  
                         if ($confighash{'passwords'}{'resetlink'}) {  
                             $resulttext .= '<li>'.&mt('Reset link expiration set to [quant,_1,hour]',$confighash{'passwords'}{'resetlink'}).'</li>';  
                         } else {  
                             $resulttext .= '<li>'.&mt('No reset link expiration set.').' '.  
                                                   &mt('Will default to 2 hours').'</li>';  
                         }  
                         if (ref($confighash{'passwords'}{'resetcase'}) eq 'ARRAY') {  
                             if (@{$confighash{'passwords'}{'resetcase'}} == 0) {  
                                 $resulttext .= '<li>'.&mt('User input for username and/or e-mail address not case sensitive for "Forgot Password" web form').'</li>';  
                             } else {  
                                 my $casesens;  
                                 foreach my $type (@{$confighash{'passwords'}{'resetcase'}}) {  
                                     if ($type eq 'default') {  
                                         $casesens .= $othertitle.', ';  
                                     } elsif ($usertypes->{$type} ne '') {  
                                         $casesens .= $usertypes->{$type}.', ';  
                                     }  
                                 }  
                                 $casesens =~ s/\Q, \E$//;  
                                 $resulttext .= '<li>'.&mt('"Forgot Password" web form input for username and/or e-mail address is case-sensitive for: [_1]',$casesens).'</li>';  
                             }  
                         } else {  
                             $resulttext .= '<li>'.&mt('Case-sensitivity not set for "Forgot Password" web form').' '.&mt('Will default to case-sensitive for username and/or e-mail address for all').'</li>';  
                         }  
                         if ($confighash{'passwords'}{'resetprelink'} eq 'either') {  
                             $resulttext .= '<li>'.&mt('Users can enter either a username or an e-mail address in "Forgot Password" web form').'</li>';  
                         } else {  
                             $resulttext .= '<li>'.&mt('Users can enter both a username and an e-mail address in "Forgot Password" web form').'</li>';  
                         }  
                         if (ref($confighash{'passwords'}{'resetpostlink'}) eq 'HASH') {  
                             my $output;  
                             if (ref($types) eq 'ARRAY') {  
                                 foreach my $type (@{$types}) {  
                                     if (ref($confighash{'passwords'}{'resetpostlink'}{$type}) eq 'ARRAY') {  
                                         if (@{$confighash{'passwords'}{'resetpostlink'}{$type}} == 0) {  
                                             $output .= $usertypes->{$type}.' -- '.&mt('none');  
                                         } else {  
                                             $output .= $usertypes->{$type}.' -- '.  
                                                        join(', ',map { $titles{$_}; } (@{$confighash{'passwords'}{'resetpostlink'}{$type}})).'; ';  
                                         }  
                                     }  
                                 }  
                             }  
                             if (ref($confighash{'passwords'}{'resetpostlink'}{'default'}) eq 'ARRAY') {  
                                 if (@{$confighash{'passwords'}{'resetpostlink'}{'default'}} == 0) {  
                                     $output .= $othertitle.' -- '.&mt('none');  
                                 } else {  
                                     $output .= $othertitle.' -- '.  
                                                join(', ',map { $titles{$_}; } (@{$confighash{'passwords'}{'resetpostlink'}{'default'}}));  
                                 }  
                             }  
                             if ($output) {  
                                 $resulttext .= '<li>'.&mt('Information required for new password form (by user type) set to: [_1]',$output).'</li>';  
                             } else {  
                                 $resulttext .= '<li>'.&mt('Information required for new password form not set.').' '.&mt('Will default to requiring both the username and an e-mail address').'</li>';  
                             }  
                         } else {  
                             $resulttext .= '<li>'.&mt('Information required for new password form not set.').' '.&mt('Will default to requiring both the username and an e-mail address').'</li>';  
                         }  
                         if (ref($confighash{'passwords'}{'resetemail'}) eq 'ARRAY') {  
                             if (@{$confighash{'passwords'}{'resetemail'}} > 0) {  
                                 $resulttext .= '<li>'.&mt('E-mail address(es) in LON-CAPA used for verification will include: [_1]',join(', ',map { $titles{$_}; } @{$confighash{'passwords'}{'resetemail'}})).'</li>';  
                             } else {  
                                 $resulttext .= '<li>'.&mt('E-mail address(es) in LON-CAPA used for verification will include: [_1]',join(', ',map { $titles{$_}; } @{$staticdefaults{'resetemail'}})).'</li>';  
                             }  
                         } else {  
                             $resulttext .= '<li>'.&mt('E-mail address(es) in LON-CAPA usedfor verification will include: [_1]',join(', ',map { $titles{$_}; } @{$staticdefaults{'resetemail'}})).'</li>';  
                         }  
                         if ($confighash{'passwords'}{'resetremove'}) {  
                             $resulttext .= '<li>'.&mt('Preamble to "Forgot Password" web form not shown').'</li>';  
                         } else {  
                             $resulttext .= '<li>'.&mt('Preamble to "Forgot Password" web form is shown').'</li>';  
                         }  
                         if ($confighash{'passwords'}{'resetcustom'}) {  
                             my $customlink = &Apache::loncommon::modal_link($confighash{'passwords'}{'resetcustom'},  
                                                                             &mt('custom text'),600,500,undef,undef,  
                                                                             undef,undef,'background-color:#ffffff');  
                             $resulttext .= '<li>'.&mt('Preamble to "Forgot Password" form includes: [_1]',$customlink).'</li>';  
                         } else {  
                             $resulttext .= '<li>'.&mt('No custom text included in preamble to "Forgot Password" form').'</li>';  
                         }  
                     } elsif ($key eq 'intauth') {  
                         foreach my $item ('cost','switch','check') {  
                             my $value = $save_defaults{$key.'_'.$item};  
                             if ($item eq '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 '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]"',$titles{$key.'_'.$item},$value).'</li>';  
                         }  
                     } elsif ($key eq 'rules') {  
                         foreach my $rule ('min','max','numsaved') {  
                             if ($confighash{'passwords'}{$rule} eq '') {  
                                 if ($rule eq 'min') {  
                                     $resulttext .= '<li>'.&mt('[_1] not set.',$titles{$rule});  
                                                    ' '.&mt('Default of [_1] will be used',  
                                                            $Apache::lonnet::passwdmin).'</li>';  
                                 } else {  
                                     $resulttext .= '<li>'.&mt('[_1] set to none',$titles{$rule}).'</li>';  
                                 }  
                             } else {  
                                 $resulttext .= '<li>'.&mt('[_1] set to [_2]',$titles{$rule},$confighash{'passwords'}{$rule}).'</li>';  
                             }  
                         }  
                         if (ref($confighash{'passwords'}{'chars'}) eq 'ARRAY') {  
                             if (@{$confighash{'passwords'}{'chars'}} > 0) {  
                                 my %rulenames = &Apache::lonlocal::texthash(  
                                                      uc => 'At least one upper case letter',  
                                                      lc => 'At least one lower case letter',  
                                                      num => 'At least one number',  
                                                      spec => 'At least one non-alphanumeric',  
                                                    );  
                                 my $needed = '<ul><li>'.  
                                              join('</li><li>',map {$rulenames{$_} } @{$confighash{'passwords'}{'chars'}}).  
                                              '</li></ul>';  
                                 $resulttext .= '<li>'.&mt('[_1] set to: [_2]',$titles{'chars'},$needed).'</li>';  
                             } else {  
                                 $resulttext .= '<li>'.&mt('[_1] set to none',$titles{'chars'}).'</li>';  
                             }  
                         } else {  
                             $resulttext .= '<li>'.&mt('[_1] set to none',$titles{'chars'}).'</li>';  
                         }  
                     } elsif ($key eq 'crsownerchg') {  
                         if (ref($confighash{'passwords'}{'crsownerchg'}) eq 'HASH') {  
                             if ((@{$confighash{'passwords'}{'crsownerchg'}{'by'}} == 0) ||  
                                 (@{$confighash{'passwords'}{'crsownerchg'}{'for'}} == 0)) {  
                                 $resulttext .= '<li>'.&mt('Course owner may not change student passwords.').'</li>';  
                             } else {  
                                 my %crsownerstr;  
                                 foreach my $item ('by','for') {  
                                     if (ref($confighash{'passwords'}{'crsownerchg'}{$item}) eq 'ARRAY') {  
                                         foreach my $type (@{$confighash{'passwords'}{'crsownerchg'}{$item}}) {  
                                             if ($type eq 'default') {  
                                                 $crsownerstr{$item} .= $othertitle.', ';  
                                             } elsif ($usertypes->{$type} ne '') {  
                                                 $crsownerstr{$item} .= $usertypes->{$type}.', ';  
                                             }  
                                         }  
                                         $crsownerstr{$item} =~ s/\Q, \E$//;  
                                     }  
                                 }  
                                 $resulttext .= '<li>'.&mt('Course owner (with status: [_1]) may change passwords for students (with status: [_2]).',  
                                            $crsownerstr{'by'},$crsownerstr{'for'}).'</li>';  
                             }  
                         } else {  
                             $resulttext .= '<li>'.&mt('Course owner may not change student passwords.').'</li>';  
                         }  
                     }  
                     $resulttext .= '</ul></li>';  
                 }  
             }  
             $resulttext .= '</ul>';  
         } else {  
             $resulttext = &mt('No changes made to password settings');  
         }  
         my $cachetime = 24*60*60;  
         if ($updatedefaults) {  
             &Apache::lonnet::do_cache_new('domdefaults',$dom,\%domdefaults,$cachetime);  
             if (ref($lastactref) eq 'HASH') {  
                 $lastactref->{'domdefaults'} = 1;  
             }  
         }  
         if ($updateconf) {  
             &Apache::lonnet::do_cache_new('passwdconf',$dom,$confighash{'passwords'},$cachetime);  
             if (ref($lastactref) eq 'HASH') {  
                 $lastactref->{'passwdconf'} = 1;  
             }  
         }  
     } else {  
         $resulttext = '<span class="LC_error">'.  
             &mt('An error occurred: [_1]',$putresult).'</span>';  
     }  
     if ($errors) {  
         $resulttext .= '<p>'.&mt('The following errors occurred: ').'<ul>'.  
                        $errors.'</ul></p>';  
     }  
     return $resulttext;  
 }  
   
 sub modify_usercreation {  sub modify_usercreation {
     my ($dom,%domconfig) = @_;      my ($dom,%domconfig) = @_;
     my ($resulttext,%curr_usercreation,%changes,%authallowed,%cancreate,%save_usercreate);      my ($resulttext,%curr_usercreation,%changes,%authallowed,%cancreate,%save_usercreate);
Line 12763  sub modify_selfcreation { Line 12018  sub modify_selfcreation {
 # 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 ($emailrules,$emailruleorder) = &Apache::lonnet::inst_userrules($dom,'email');
   
     my (@statuses,%email_rule);      my (@statuses,%email_rule);
Line 12813  sub modify_selfcreation { Line 12067  sub modify_selfcreation {
                             if (($chosen eq 'inst') || ($chosen eq 'noninst')) {                              if (($chosen eq 'inst') || ($chosen eq 'noninst')) {
                                 my $emaildom;                                  my $emaildom;
                                 if ($env{'form.cancreate_emaildomain_'.$chosen.'_'.$type} =~ /^\@[^\@]+$/) {                                  if ($env{'form.cancreate_emaildomain_'.$chosen.'_'.$type} =~ /^\@[^\@]+$/) {
                                     $emaildom = $env{'form.cancreate_emaildomain_'.$chosen.'_'.$type};                                      $emaildom = $env{'form.cancreate_emaildomain_'.$chosen.'_'.$type}; 
                                     $cancreate{'emaildomain'}{$type}{$chosen} = $emaildom;                                      $cancreate{'emaildomain'}{$type}{$chosen} = $emaildom;
                                     if (ref($curremaildom{$type}) eq 'HASH') {                                      if (ref($curremaildom{$type}) eq 'HASH') {
                                         if (exists($curremaildom{$type}{$chosen})) {                                          if (exists($curremaildom{$type}{$chosen})) {
Line 12825  sub modify_selfcreation { Line 12079  sub modify_selfcreation {
                                         }                                          }
                                     } elsif ($emaildom ne '') {                                      } elsif ($emaildom ne '') {
                                         push(@{$changes{'cancreate'}},'emaildomain');                                          push(@{$changes{'cancreate'}},'emaildomain');
                                     }                                      } 
                                 }                                  }
                                 $cancreate{'emailoptions'}{$type} = $env{'form.cancreate_emailoptions_'.$type};                                  $cancreate{'emailoptions'}{$type} = $env{'form.cancreate_emailoptions_'.$type};
                             } elsif ($chosen eq 'custom') {                              } elsif ($chosen eq 'custom') {
Line 13252  sub modify_selfcreation { Line 12506  sub modify_selfcreation {
                                                                   );                                                                    );
                         if (@types) {                          if (@types) {
                             if (@statuses) {                              if (@statuses) {
                                 $chgtext .= &mt('Processing of requests to create account with e-mail verification set as follows:').                                  $chgtext .= &mt('Processing of requests to create account with e-mail verification set as follows:'). 
                                             '<ul>';                                              '<ul>';
                                 foreach my $status (@statuses) {                                  foreach my $status (@statuses) {
                                     if ($status eq 'default') {                                      if ($status eq 'default') {
Line 13278  sub modify_selfcreation { Line 12532  sub modify_selfcreation {
                                 $chgtext .= &mt('For self-created accounts verified by e-mail address, username is set as follows:').                                  $chgtext .= &mt('For self-created accounts verified by e-mail address, username is set as follows:').
                                             '<ul>';                                              '<ul>';
                                 foreach my $status (@statuses) {                                  foreach my $status (@statuses) {
                                     if ($status eq 'default') {                                      if ($type eq 'default') {
                                         $chgtext .= '<li>'.$othertitle.' -- '.$options{$cancreate{'emailverified'}{$status}}.'</li>';                                          $chgtext .= '<li>'.$othertitle.' -- '.$options{$cancreate{'emailverified'}{$status}}.'</li>';
                                     } else {                                      } else {
                                         $chgtext .= '<li>'.$usertypes{$status}.' -- '.$options{$cancreate{'emailverified'}{$status}}.'</li>';                                          $chgtext .= '<li>'.$usertypes{$status}.' -- '.$options{$cancreate{'emailverified'}{$status}}.'</li>';
Line 13338  sub modify_selfcreation { Line 12592  sub modify_selfcreation {
                                                 $output = '<li>'.$usertypes{$type}.' -- '.&mt('No restriction on e-mail domain').'</li>';                                                  $output = '<li>'.$usertypes{$type}.' -- '.&mt('No restriction on e-mail domain').'</li>';
                                             } else {                                              } else {
                                                 $output = '<li>'.$usertypes{$type}.' -- '.&mt("User's e-mail address needs to end: [_1]",                                                  $output = '<li>'.$usertypes{$type}.' -- '.&mt("User's e-mail address needs to end: [_1]",
                                                                                               $cancreate{'emaildomain'}{$type}{'inst'}).'</li>';                                                                                                $cancreate{'emaildomain'}{$type}{'inst'}).'</li>'; 
                                             }                                              }
                                         }                                          }
                                     } elsif ($cancreate{'emailoptions'}{$type} eq 'noninst') {                                      } elsif ($cancreate{'emailoptions'}{$type} eq 'noninst') {
Line 13356  sub modify_selfcreation { Line 12610  sub modify_selfcreation {
                                                 $output = '<li>'.$usertypes{$type}.' -- '.&mt('No restriction on e-mail domain').'</li>';                                                  $output = '<li>'.$usertypes{$type}.' -- '.&mt('No restriction on e-mail domain').'</li>';
                                             } else {                                              } else {
                                                 $output = '<li>'.$usertypes{$type}.' -- '.&mt("User's e-mail address must not end: [_1]",                                                  $output = '<li>'.$usertypes{$type}.' -- '.&mt("User's e-mail address must not end: [_1]",
                                                                                                 $cancreate{'emaildomain'}{$type}{'noninst'}).'</li>';                                                                                                  $cancreate{'emaildomain'}{$type}{'noninst'}).'</li>';   
                                             }                                              }
                                         }                                          }
                                     }                                      }
Line 13460  sub modify_selfcreation { Line 12714  sub modify_selfcreation {
                                 $typename = $othertitle;                                  $typename = $othertitle;
                             } else {                              } else {
                                 $typename = $usertypes{$type};                                  $typename = $usertypes{$type};
                             }                              } 
                             $chgtext .= &mt('(Affiliation: [_1])',$typename);                              $chgtext .= &mt('(Affiliation: [_1])',$typename);
                         }                          }
                         if (@{$email_rule{$type}} > 0) {                          if (@{$email_rule{$type}} > 0) {
Line 13547  sub modify_selfcreation { Line 12801  sub modify_selfcreation {
 }  }
   
 sub process_captcha {  sub process_captcha {
     my ($container,$changes,$newsettings,$currsettings) = @_;      my ($container,$changes,$newsettings,$current) = @_;
     return unless ((ref($changes) eq 'HASH') && (ref($newsettings) eq 'HASH'));      return unless ((ref($changes) eq 'HASH') && (ref($newsettings) eq 'HASH') || (ref($current) eq 'HASH'));
     $newsettings->{'captcha'} = $env{'form.'.$container.'_captcha'};      $newsettings->{'captcha'} = $env{'form.'.$container.'_captcha'};
     unless ($newsettings->{'captcha'} eq 'recaptcha' || $newsettings->{'captcha'} eq 'notused') {      unless ($newsettings->{'captcha'} eq 'recaptcha' || $newsettings->{'captcha'} eq 'notused') {
         $newsettings->{'captcha'} = 'original';          $newsettings->{'captcha'} = 'original';
     }      }
     my %current;      if ($current->{'captcha'} ne $newsettings->{'captcha'}) {
     if (ref($currsettings) eq 'HASH') {  
         %current = %{$currsettings};  
     }  
     if ($current{'captcha'} ne $newsettings->{'captcha'}) {  
         if ($container eq 'cancreate') {          if ($container eq 'cancreate') {
             if (ref($changes->{'cancreate'}) eq 'ARRAY') {              if (ref($changes->{'cancreate'}) eq 'ARRAY') {
                 push(@{$changes->{'cancreate'}},'captcha');                  push(@{$changes->{'cancreate'}},'captcha');
             } elsif (!defined($changes->{'cancreate'})) {              } elsif (!defined($changes->{'cancreate'})) {
                 $changes->{'cancreate'} = ['captcha'];                  $changes->{'cancreate'} = ['captcha'];
             }              }
         } elsif ($container eq 'passwords') {  
             $changes->{'reset'} = 1;  
         } else {          } else {
             $changes->{'captcha'} = 1;              $changes->{'captcha'} = 1;
         }          }
Line 13587  sub process_captcha { Line 12835  sub process_captcha {
         }          }
         $newsettings->{'recaptchaversion'} = $newversion;          $newsettings->{'recaptchaversion'} = $newversion;
     }      }
     if (ref($current{'recaptchakeys'}) eq 'HASH') {      if (ref($current->{'recaptchakeys'}) eq 'HASH') {
         $currpub = $current{'recaptchakeys'}{'public'};          $currpub = $current->{'recaptchakeys'}{'public'};
         $currpriv = $current{'recaptchakeys'}{'private'};          $currpriv = $current->{'recaptchakeys'}{'private'};
         unless ($newsettings->{'captcha'} eq 'recaptcha') {          unless ($newsettings->{'captcha'} eq 'recaptcha') {
             $newsettings->{'recaptchakeys'} = {              $newsettings->{'recaptchakeys'} = {
                                                  public  => '',                                                   public  => '',
Line 13597  sub process_captcha { Line 12845  sub process_captcha {
                                               }                                                }
         }          }
     }      }
     if ($current{'captcha'} eq 'recaptcha') {      if ($current->{'captcha'} eq 'recaptcha') {
         $currversion = $current{'recaptchaversion'};          $currversion = $current->{'recaptchaversion'};
         if ($currversion ne '2') {          if ($currversion ne '2') {
             $currversion = 1;              $currversion = 1;
         }          }
Line 13610  sub process_captcha { Line 12858  sub process_captcha {
             } elsif (!defined($changes->{'cancreate'})) {              } elsif (!defined($changes->{'cancreate'})) {
                 $changes->{'cancreate'} = ['recaptchaversion'];                  $changes->{'cancreate'} = ['recaptchaversion'];
             }              }
         } elsif ($container eq 'passwords') {  
             $changes->{'reset'} = 1;  
         } else {          } else {
             $changes->{'recaptchaversion'} = 1;              $changes->{'recaptchaversion'} = 1;
         }          }
Line 13623  sub process_captcha { Line 12869  sub process_captcha {
             } elsif (!defined($changes->{'cancreate'})) {              } elsif (!defined($changes->{'cancreate'})) {
                 $changes->{'cancreate'} = ['recaptchakeys'];                  $changes->{'cancreate'} = ['recaptchakeys'];
             }              }
         } elsif ($container eq 'passwords') {  
             $changes->{'reset'} = 1;  
         } else {          } else {
             $changes->{'recaptchakeys'} = 1;              $changes->{'recaptchakeys'} = 1;
         }          }
Line 13740  sub modify_defaults { Line 12984  sub modify_defaults {
     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',      my @items = ('auth_def','auth_arg_def','lang_def','timezone_def','datelocale_def',
                  'portal_def');                   'portal_def','intauth_cost','intauth_check','intauth_switch');
     my @authtypes = ('internal','krb4','krb5','localauth');      my @authtypes = ('internal','krb4','krb5','localauth');
     foreach my $item (@items) {      foreach my $item (@items) {
         $newvalues{$item} = $env{'form.'.$item};          $newvalues{$item} = $env{'form.'.$item};
Line 13782  sub modify_defaults { Line 13026  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 13790  sub modify_defaults { Line 13052  sub modify_defaults {
         }          }
         $domdefaults{$item} = $newvalues{$item};          $domdefaults{$item} = $newvalues{$item};
     }      }
     my %staticdefaults = (  
                            'intauth_cost'   => 10,  
                            'intauth_check'  => 0,  
                            'intauth_switch' => 0,  
                          );  
     foreach my $item ('intauth_cost','intauth_check','intauth_switch') {  
         if (exists($domdefaults{$item})) {  
             $newvalues{$item} = $domdefaults{$item};  
         } else {  
             $newvalues{$item} = $staticdefaults{$item};  
         }  
     }  
     my %defaults_hash = (      my %defaults_hash = (
                          defaults => \%newvalues,                           defaults => \%newvalues,
                         );                          );
Line 13822  sub modify_defaults { Line 13072  sub modify_defaults {
     my @allpos;      my @allpos;
     my %alltypes;      my %alltypes;
     my @inststatusguest;      my @inststatusguest;
     if (ref($currinststatus) eq 'HASH') {      if (ref($currinststatus->{'inststatusguest'}) eq 'ARRAY') {
         if (ref($currinststatus->{'inststatusguest'}) eq 'ARRAY') {          foreach my $type (@{$currinststatus->{'inststatusguest'}}) {
             foreach my $type (@{$currinststatus->{'inststatusguest'}}) {              unless (grep(/^\Q$type\E$/,@todelete)) {
                 unless (grep(/^\Q$type\E$/,@todelete)) {                  push(@inststatusguest,$type);
                     push(@inststatusguest,$type);  
                 }  
             }              }
         }          }
     }      }
Line 13915  sub modify_defaults { Line 13163  sub modify_defaults {
                             $resulttext =~ s/, $//;                              $resulttext =~ s/, $//;
                             $resulttext .= '</li>';                              $resulttext .= '</li>';
                         } else {                          } else {
                             $resulttext .= '<li>'.&mt('Institutional user status types deleted').'</li>';                              $resulttext .= '<li>'.&mt('Institutional user status types deleted').'</li>'; 
                         }                          }
                     }                      }
                 } else {                  } else {
Line 13931  sub modify_defaults { Line 13179  sub modify_defaults {
                                           localauth  => 'loc',                                            localauth  => 'loc',
                         );                          );
                         $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 13979  sub modify_scantron { Line 13249  sub modify_scantron {
     my $custom = 'custom.tab';      my $custom = 'custom.tab';
     my $default = 'default.tab';      my $default = 'default.tab';
     my $servadm = $r->dir_config('lonAdmEMail');      my $servadm = $r->dir_config('lonAdmEMail');
     my ($configuserok,$author_ok,$switchserver) =      my ($configuserok,$author_ok,$switchserver) = 
         &config_check($dom,$confname,$servadm);          &config_check($dom,$confname,$servadm);
     if ($env{'form.scantronformat.filename'} ne '') {      if ($env{'form.scantronformat.filename'} ne '') {
         my $error;          my $error;
Line 14014  sub modify_scantron { Line 13284  sub modify_scantron {
             if ($env{'form.scantronformat_del'}) {              if ($env{'form.scantronformat_del'}) {
                 $confhash{'scantron'}{'scantronformat'} = '';                  $confhash{'scantron'}{'scantronformat'} = '';
                 $changes{'scantronformat'} = 1;                  $changes{'scantronformat'} = 1;
             } else {  
                 $confhash{'scantron'}{'scantronformat'} = $domconfig{'scantron'}{'scantronformat'};  
             }  
         }  
     }  
     my @options = ('hdr','pad','rem');  
     my @fields = &scantroncsv_fields();  
     my %titles = &scantronconfig_titles();  
     my @formats = &Apache::loncommon::get_env_multiple('form.scantronconfig');  
     my ($newdat,$currdat,%newcol,%currcol);  
     if (grep(/^dat$/,@formats)) {  
         $confhash{'scantron'}{config}{dat} = 1;  
         $newdat = 1;  
     } else {  
         $newdat = 0;  
     }  
     if (grep(/^csv$/,@formats)) {  
         my %bynum;  
         foreach my $field (@fields) {  
             if ($env{'form.scantronconfig_csv_'.$field} =~ /^(\d+)$/) {  
                 my $posscol = $1;  
                 if (($posscol < 20) && (!$bynum{$posscol})) {  
                     $confhash{'scantron'}{config}{csv}{fields}{$field} = $posscol;  
                     $bynum{$posscol} = $field;  
                     $newcol{$field} = $posscol;  
                 }  
             }  
         }  
         if (keys(%newcol)) {  
             foreach my $option (@options) {  
                 if ($env{'form.scantroncsv_'.$option}) {  
                     $confhash{'scantron'}{config}{csv}{options}{$option} = 1;  
                 }  
             }  
         }  
     }  
     $currdat = 1;  
     if (ref($domconfig{'scantron'}) eq 'HASH') {  
         if (ref($domconfig{'scantron'}{'config'}) eq 'HASH') {  
             unless (exists($domconfig{'scantron'}{'config'}{'dat'})) {  
                 $currdat = 0;  
             }  
             if (ref($domconfig{'scantron'}{'config'}{'csv'}) eq 'HASH') {  
                 if (ref($domconfig{'scantron'}{'config'}{'csv'}{'fields'}) eq 'HASH') {  
                     %currcol = %{$domconfig{'scantron'}{'config'}{'csv'}{'fields'}};  
                 }  
             }  
         }  
     }  
     if ($currdat != $newdat) {  
         $changes{'config'} = 1;  
     } else {  
         foreach my $field (@fields) {  
             if ($currcol{$field} ne '') {  
                 if ($currcol{$field} ne $newcol{$field}) {  
                     $changes{'config'} = 1;  
                     last;  
                 }  
             } elsif ($newcol{$field} ne '') {  
                 $changes{'config'} = 1;  
                 last;  
             }              }
         }          }
     }      }
Line 14085  sub modify_scantron { Line 13294  sub modify_scantron {
             if (keys(%changes) > 0) {              if (keys(%changes) > 0) {
                 if (ref($confhash{'scantron'}) eq 'HASH') {                  if (ref($confhash{'scantron'}) eq 'HASH') {
                     $resulttext = &mt('Changes made:').'<ul>';                      $resulttext = &mt('Changes made:').'<ul>';
                     if ($changes{'scantronformat'}) {                      if ($confhash{'scantron'}{'scantronformat'} eq '') {
                         if ($confhash{'scantron'}{'scantronformat'} eq '') {                          $resulttext .= '<li>'.&mt('[_1] bubblesheet format file removed; [_2] file will be used for courses in this domain.',$custom,$default).'</li>';
                             $resulttext .= '<li>'.&mt('[_1] bubblesheet format file removed; [_2] file will be used for courses in this domain.',$custom,$default).'</li>';                      } else {
                         } else {                          $resulttext .= '<li>'.&mt('Custom bubblesheet format file ([_1]) uploaded for use with courses in this domain.',$custom).'</li>';
                             $resulttext .= '<li>'.&mt('Custom bubblesheet format file ([_1]) uploaded for use with courses in this domain.',$custom).'</li>';  
                         }  
                     }  
                     if ($changes{'config'}) {  
                         if (ref($confhash{'scantron'}{'config'}) eq 'HASH') {  
                             if ($confhash{'scantron'}{'config'}{'dat'}) {  
                                 $resulttext .= '<li>'.&mt('Bubblesheet data upload formats includes .dat format').'</li>';  
                             }  
                             if (ref($confhash{'scantron'}{'config'}{'csv'}) eq 'HASH') {  
                                 if (ref($confhash{'scantron'}{'config'}{'csv'}{'fields'}) eq 'HASH') {  
                                     if (keys(%{$confhash{'scantron'}{'config'}{'csv'}{'fields'}})) {  
                                         $resulttext .= '<li>'.&mt('Bubblesheet data upload formats includes .csv format, with following fields/column numbers supported:').'<ul>';  
                                         foreach my $field (@fields) {  
                                             if ($confhash{'scantron'}{'config'}{'csv'}{'fields'}{$field} ne '') {  
                                                 my $showcol = $confhash{'scantron'}{'config'}{'csv'}{'fields'}{$field} + 1;  
                                                 $resulttext .= '<li>'.$titles{$field}.': '.$showcol.'</li>';  
                                             }  
                                         }  
                                         $resulttext .= '</ul></li>';  
                                         if (ref($confhash{'scantron'}{'config'}{'csv'}{'options'}) eq 'HASH') {  
                                             if (keys(%{$confhash{'scantron'}{'config'}{'csv'}{'options'}})) {  
                                                 $resulttext .= '<li>'.&mt('Bubblesheet data upload formats includes .csv format, with following options:').'<ul>';  
                                                 foreach my $option (@options) {  
                                                     if ($confhash{'scantron'}{'config'}{'csv'}{'options'}{$option} ne '') {  
                                                         $resulttext .= '<li>'.$titles{$option}.'</li>';  
                                                     }  
                                                 }  
                                                 $resulttext .= '</ul></li>';  
                                             }  
                                         }  
                                     }  
                                 }  
                             }  
                         } else {  
                             $resulttext .= '<li>'.&mt('No bubblesheet data upload formats set -- will default to assuming .dat format').'</li>';  
                         }  
                     }                      }
                     $resulttext .= '</ul>';                      $resulttext .= '</ul>';
                 } else {                  } else {
                     $resulttext = &mt('Changes made to bubblesheet format file.');                      $resulttext = &mt('Changes made to bubblesheet format file.');
                 }                  }
                   $resulttext .= '</ul>';
                 &Apache::loncommon::devalidate_domconfig_cache($dom);                  &Apache::loncommon::devalidate_domconfig_cache($dom);
                 if (ref($lastactref) eq 'HASH') {                  if (ref($lastactref) eq 'HASH') {
                     $lastactref->{'domainconfig'} = 1;                      $lastactref->{'domainconfig'} = 1;
                 }                  }
             } else {              } else {
                 $resulttext = &mt('No changes made to bubblesheet format settings');                  $resulttext = &mt('No changes made to bubblesheet format file');
             }              }
         } else {          } else {
             $resulttext = '<span class="LC_error">'.              $resulttext = '<span class="LC_error">'.
                 &mt('An error occurred: [_1]',$putresult).'</span>';                  &mt('An error occurred: [_1]',$putresult).'</span>';
         }          }
     } else {      } else {
         $resulttext = &mt('No changes made to bubblesheet format settings');          $resulttext = &mt('No changes made to bubblesheet format file'); 
     }      }
     if ($errors) {      if ($errors) {
         $resulttext .= &mt('The following errors occurred: ').'<ul>'.          $resulttext .= &mt('The following errors occurred: ').'<ul>'.
Line 14175  sub modify_coursecategories { Line 13349  sub modify_coursecategories {
         if ($domconfig{'coursecategories'}{'categorizecomm'} ne $env{'form.categorizecomm'}) {          if ($domconfig{'coursecategories'}{'categorizecomm'} ne $env{'form.categorizecomm'}) {
             $changes{'categorizecomm'} = 1;              $changes{'categorizecomm'} = 1;
             $domconfig{'coursecategories'}{'categorizecomm'} = $env{'form.categorizecomm'};              $domconfig{'coursecategories'}{'categorizecomm'} = $env{'form.categorizecomm'};
   
           }
           if ($domconfig{'coursecategories'}{'togglecatsplace'} ne $env{'form.togglecatsplace'}) {
               $changes{'togglecatsplace'} = 1;
               $domconfig{'coursecategories'}{'togglecatsplace'} = $env{'form.togglecatsplace'};
           }
           if ($domconfig{'coursecategories'}{'categorizeplace'} ne $env{'form.categorizeplace'}) {
               $changes{'categorizeplace'} = 1;
               $domconfig{'coursecategories'}{'categorizeplace'} = $env{'form.categorizeplace'};
         }          }
         foreach my $item (@catitems) {          foreach my $item (@catitems) {
             if (grep(/^\Q$env{'form.coursecat_'.$item}\E$/,@cattypes)) {              if (grep(/^\Q$env{'form.coursecat_'.$item}\E$/,@cattypes)) {
Line 14189  sub modify_coursecategories { Line 13372  sub modify_coursecategories {
         $changes{'categorize'} = 1;          $changes{'categorize'} = 1;
         $changes{'togglecatscomm'} = 1;          $changes{'togglecatscomm'} = 1;
         $changes{'categorizecomm'} = 1;          $changes{'categorizecomm'} = 1;
           $changes{'togglecatsplace'} = 1;
           $changes{'categorizeplace'} = 1;
         $domconfig{'coursecategories'} = {          $domconfig{'coursecategories'} = {
                                              togglecats => $env{'form.togglecats'},                                               togglecats => $env{'form.togglecats'},
                                              categorize => $env{'form.categorize'},                                               categorize => $env{'form.categorize'},
                                              togglecatscomm => $env{'form.togglecatscomm'},                                               togglecatscomm => $env{'form.togglecatscomm'},
                                              categorizecomm => $env{'form.categorizecomm'},                                               categorizecomm => $env{'form.categorizecomm'},
                                                togglecatsplace => $env{'form.togglecatsplace'},
                                                categorizeplace => $env{'form.categorizeplace'},
                                          };                                           };
         foreach my $item (@catitems) {          foreach my $item (@catitems) {
             if ($env{'form.coursecat_'.$item} ne 'std') {              if ($env{'form.coursecat_'.$item} ne 'std') {
Line 14211  sub modify_coursecategories { Line 13398  sub modify_coursecategories {
         if (($domconfig{'coursecategories'}{'cats'}{'communities::0'} ne '')  && ($env{'form.communities'} == 0)) {          if (($domconfig{'coursecategories'}{'cats'}{'communities::0'} ne '')  && ($env{'form.communities'} == 0)) {
             push(@deletecategory,'communities::0');              push(@deletecategory,'communities::0');
         }          }
           if (($domconfig{'coursecategories'}{'cats'}{'placement::0'} ne '')  && ($env{'form.placement'} == 0)) {
               push(@deletecategory,'placement::0');
           }
     }      }
     my (@predelcats,@predeltrails,%predelallitems,%sort_by_deltrail);      my (@predelcats,@predeltrails,%predelallitems,%sort_by_deltrail);
     if (ref($cathash) eq 'HASH') {      if (ref($cathash) eq 'HASH') {
Line 14273  sub modify_coursecategories { Line 13463  sub modify_coursecategories {
             $adds{$newitem} = 1;              $adds{$newitem} = 1;
         }          }
     }      }
       if ($env{'form.placement'} eq '1') {
           if (ref($cathash) eq 'HASH') {
               my $newitem = 'placement::0';
               if ($cathash->{$newitem} eq '') {
                   $domconfig{'coursecategories'}{'cats'}{$newitem} = $env{'form.placement_pos'};
                   $adds{$newitem} = 1;
               }
           } else {
               my $newitem = 'placement::0';
               $domconfig{'coursecategories'}{'cats'}{$newitem} = $env{'form.placement_pos'};
               $adds{$newitem} = 1;
           }
       }
     if ($env{'form.addcategory_name'} ne '') {      if ($env{'form.addcategory_name'} ne '') {
         if (($env{'form.addcategory_name'} ne 'instcode') &&          if (($env{'form.addcategory_name'} ne 'instcode') &&
             ($env{'form.addcategory_name'} ne 'communities')) {              ($env{'form.addcategory_name'} ne 'communities') &&
               ($env{'form.addcategory_name'} ne 'placement')) {
             my $newitem = &escape($env{'form.addcategory_name'}).'::0';              my $newitem = &escape($env{'form.addcategory_name'}).'::0';
             $domconfig{'coursecategories'}{'cats'}{$newitem} = $env{'form.addcategory_pos'};              $domconfig{'coursecategories'}{'cats'}{$newitem} = $env{'form.addcategory_pos'};
             $adds{$newitem} = 1;              $adds{$newitem} = 1;
Line 14391  sub modify_coursecategories { Line 13595  sub modify_coursecategories {
                     }                      }
                     $resulttext .= '</ul></li>';                      $resulttext .= '</ul></li>';
                 }                  }
                 &Apache::lonnet::do_cache_new('cats',$dom,$cathash,3600);  
                 if (ref($lastactref) eq 'HASH') {  
                     $lastactref->{'cats'} = 1;  
                 }  
             }              }
             $resulttext .= '</ul>';              $resulttext .= '</ul>';
             if ($changes{'unauth'} || $changes{'auth'}) {              if ($changes{'unauth'} || $changes{'auth'}) {
Line 14874  sub modify_coursedefaults { Line 14074  sub modify_coursedefaults {
     my ($dom,$lastactref,%domconfig) = @_;      my ($dom,$lastactref,%domconfig) = @_;
     my ($resulttext,$errors,%changes,%defaultshash);      my ($resulttext,$errors,%changes,%defaultshash);
     my %defaultchecked = (      my %defaultchecked = (
                              'canuse_pdfforms' => 'off',
                            'uselcmath'       => 'on',                             'uselcmath'       => 'on',
                            'usejsme'         => 'on'                             'usejsme'         => 'on'
                          );                           );
     my @toggles = ('uselcmath','usejsme');      my @toggles = ('canuse_pdfforms','uselcmath','usejsme');
     my @numbers = ('anonsurvey_threshold','uploadquota_official','uploadquota_unofficial',      my @numbers = ('anonsurvey_threshold','uploadquota_official','uploadquota_unofficial',
                    'uploadquota_community','uploadquota_textbook','mysqltables_official',                     'uploadquota_community','uploadquota_textbook','uploadquota_placement',
                    'mysqltables_unofficial','mysqltables_community','mysqltables_textbook');                     'mysqltables_official','mysqltables_unofficial','mysqltables_community',
     my @types = ('official','unofficial','community','textbook');                     'mysqltables_textbook','mysqltables_placement');
       my @types = ('official','unofficial','community','textbook','placement');
     my %staticdefaults = (      my %staticdefaults = (
                            anonsurvey_threshold => 10,                             anonsurvey_threshold => 10,
                            uploadquota          => 500,                             uploadquota          => 500,
Line 14939  sub modify_coursedefaults { Line 14141  sub modify_coursedefaults {
                 $defaultshash{'coursedefaults'}{$setting}{$type} = $newdef;                  $defaultshash{'coursedefaults'}{$setting}{$type} = $newdef;
             }              }
             if ($currdef ne $newdef) {              if ($currdef ne $newdef) {
                   my $staticdef;
                 if ($item eq 'anonsurvey_threshold') {                  if ($item eq 'anonsurvey_threshold') {
                     unless (($currdef eq '') && ($newdef == $staticdefaults{$item})) {                      unless (($currdef eq '') && ($newdef == $staticdefaults{$item})) {
                         $changes{$item} = 1;                          $changes{$item} = 1;
Line 14954  sub modify_coursedefaults { Line 14157  sub modify_coursedefaults {
         my $texengine;          my $texengine;
         if ($env{'form.texengine'} =~ /^(MathJax|mimetex|tth)$/) {          if ($env{'form.texengine'} =~ /^(MathJax|mimetex|tth)$/) {
             $texengine = $env{'form.texengine'};              $texengine = $env{'form.texengine'};
             my $currdef = $domconfig{'coursedefaults'}{'texengine'};              if ($defaultshash{'coursedefaults'}{'texengine'} eq '') {
             if ($currdef eq '') {                  unless ($texengine eq 'MathJax') {
                 unless ($texengine eq $Apache::lonnet::deftex) {  
                     $changes{'texengine'} = 1;                      $changes{'texengine'} = 1;
                 }                  }
             } elsif ($currdef ne $texengine) {              } elsif ($defaultshash{'coursedefaults'}{'texengine'} ne $texengine) {
                 $changes{'texengine'} = 1;                  $changes{'texengine'} = 1;
             }              }
         }          }
Line 15084  sub modify_coursedefaults { Line 14286  sub modify_coursedefaults {
     if ($putresult eq 'ok') {      if ($putresult eq 'ok') {
         if (keys(%changes) > 0) {          if (keys(%changes) > 0) {
             my %domdefaults = &Apache::lonnet::get_domain_defaults($dom,1);              my %domdefaults = &Apache::lonnet::get_domain_defaults($dom,1);
             if (($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{'texengine'})) {                  ($changes{'canclone'}) || ($changes{'mysqltables'}) || ($changes{'texengine'})) {
                 foreach my $item ('uselcmath','usejsme','texengine') {                  foreach my $item ('canuse_pdfforms','uselcmath','usejsme','texengine') {
                     if ($changes{$item}) {                      if ($changes{$item}) {
                         $domdefaults{$item}=$defaultshash{'coursedefaults'}{$item};                          $domdefaults{$item}=$defaultshash{'coursedefaults'}{$item};
                     }                      }
Line 15138  sub modify_coursedefaults { Line 14340  sub modify_coursedefaults {
             }              }
             $resulttext = &mt('Changes made:').'<ul>';              $resulttext = &mt('Changes made:').'<ul>';
             foreach my $item (sort(keys(%changes))) {              foreach my $item (sort(keys(%changes))) {
                 if ($item eq 'uselcmath') {                  if ($item eq 'canuse_pdfforms') {
                       if ($env{'form.'.$item} eq '1') {
                           $resulttext .= '<li>'.&mt("Course/Community users can create/upload PDF forms set to 'on'").'</li>';
                       } else {
                           $resulttext .= '<li>'.&mt('Course/Community users can create/upload PDF forms set to "off"').'</li>';
                       }
                   } elsif ($item eq 'uselcmath') {
                     if ($env{'form.'.$item} eq '1') {                      if ($env{'form.'.$item} eq '1') {
                         $resulttext .= '<li>'.&mt('Math preview uses LON-CAPA previewer (javascript), if supported by browser.').'</li>';                          $resulttext .= '<li>'.&mt('Math preview uses LON-CAPA previewer (javascript), if supported by browser.').'</li>';
                     } else {                      } else {
Line 15163  sub modify_coursedefaults { Line 14371  sub modify_coursedefaults {
                                        '<li>'.&mt('Official courses: [_1] MB','<b>'.$defaultshash{'coursedefaults'}{'uploadquota'}{'official'}.'</b>').'</li>'.                                         '<li>'.&mt('Official courses: [_1] MB','<b>'.$defaultshash{'coursedefaults'}{'uploadquota'}{'official'}.'</b>').'</li>'.
                                        '<li>'.&mt('Unofficial courses: [_1] MB','<b>'.$defaultshash{'coursedefaults'}{'uploadquota'}{'unofficial'}.'</b>').'</li>'.                                         '<li>'.&mt('Unofficial courses: [_1] MB','<b>'.$defaultshash{'coursedefaults'}{'uploadquota'}{'unofficial'}.'</b>').'</li>'.
                                        '<li>'.&mt('Textbook courses: [_1] MB','<b>'.$defaultshash{'coursedefaults'}{'uploadquota'}{'textbook'}.'</b>').'</li>'.                                         '<li>'.&mt('Textbook courses: [_1] MB','<b>'.$defaultshash{'coursedefaults'}{'uploadquota'}{'textbook'}.'</b>').'</li>'.
                                          '<li>'.&mt('Placement tests: [_1] MB','<b>'.$defaultshash{'coursedefaults'}{'uploadquota'}{'placement'}.'</b>').'</li>'. 
                                        '<li>'.&mt('Communities: [_1] MB','<b>'.$defaultshash{'coursedefaults'}{'uploadquota'}{'community'}.'</b>').'</li>'.                                         '<li>'.&mt('Communities: [_1] MB','<b>'.$defaultshash{'coursedefaults'}{'uploadquota'}{'community'}.'</b>').'</li>'.
                                        '</ul>'.                                         '</ul>'.
                                        '</li>';                                         '</li>';
Line 15176  sub modify_coursedefaults { Line 14384  sub modify_coursedefaults {
                                        '<li>'.&mt('Official courses: [_1] s','<b>'.$defaultshash{'coursedefaults'}{'mysqltables'}{'official'}.'</b>').'</li>'.                                         '<li>'.&mt('Official courses: [_1] s','<b>'.$defaultshash{'coursedefaults'}{'mysqltables'}{'official'}.'</b>').'</li>'.
                                        '<li>'.&mt('Unofficial courses: [_1] s','<b>'.$defaultshash{'coursedefaults'}{'mysqltables'}{'unofficial'}.'</b>').'</li>'.                                         '<li>'.&mt('Unofficial courses: [_1] s','<b>'.$defaultshash{'coursedefaults'}{'mysqltables'}{'unofficial'}.'</b>').'</li>'.
                                        '<li>'.&mt('Textbook courses: [_1] s','<b>'.$defaultshash{'coursedefaults'}{'mysqltables'}{'textbook'}.'</b>').'</li>'.                                         '<li>'.&mt('Textbook courses: [_1] s','<b>'.$defaultshash{'coursedefaults'}{'mysqltables'}{'textbook'}.'</b>').'</li>'.
                                          '<li>'.&mt('Placement tests: [_1] s','<b>'.$defaultshash{'coursedefaults'}{'mysqltables'}{'placement'}.'</b>').'</li>'.
                                        '<li>'.&mt('Communities: [_1] s','<b>'.$defaultshash{'coursedefaults'}{'mysqltables'}{'community'}.'</b>').'</li>'.                                         '<li>'.&mt('Communities: [_1] s','<b>'.$defaultshash{'coursedefaults'}{'mysqltables'}{'community'}.'</b>').'</li>'.
                                        '</ul>'.                                         '</ul>'.
                                        '</li>';                                         '</li>';
Line 15211  sub modify_coursedefaults { Line 14420  sub modify_coursedefaults {
                                     $resulttext .= &mt('Unofficial courses');                                      $resulttext .= &mt('Unofficial courses');
                                 } elsif ($type eq 'textbook') {                                  } elsif ($type eq 'textbook') {
                                     $resulttext .= &mt('Textbook courses');                                      $resulttext .= &mt('Textbook courses');
                                   } elsif ($type eq 'placement') {
                                       $resulttext .= &mt('Placement tests');
                                 }                                  }
                                 $resulttext .= ' -- '.$display.'</li>';                                  $resulttext .= ' -- '.$display.'</li>';
                             }                              }
Line 15262  sub modify_coursedefaults { Line 14473  sub modify_coursedefaults {
 sub modify_selfenrollment {  sub modify_selfenrollment {
     my ($dom,$lastactref,%domconfig) = @_;      my ($dom,$lastactref,%domconfig) = @_;
     my ($resulttext,$errors,%changes,%selfenrollhash,%ordered);      my ($resulttext,$errors,%changes,%selfenrollhash,%ordered);
     my @types = ('official','unofficial','community','textbook');      my @types = ('official','unofficial','community','textbook','placement');
     my %titles = &tool_titles();      my %titles = &tool_titles();
     my %descs = &Apache::lonuserutils::selfenroll_default_descs();      my %descs = &Apache::lonuserutils::selfenroll_default_descs();
     ($ordered{'admin'},my $titlesref) = &Apache::lonuserutils::get_selfenroll_titles();      ($ordered{'admin'},my $titlesref) = &Apache::lonuserutils::get_selfenroll_titles();
Line 15509  sub modify_usersessions { Line 14720  sub modify_usersessions {
                 );                  );
     my @prefixes = ('remote','hosted','spares');      my @prefixes = ('remote','hosted','spares');
     my @lcversions = &Apache::lonnet::all_loncaparevs();      my @lcversions = &Apache::lonnet::all_loncaparevs();
     my (%by_ip,%by_location,@intdoms);      my (%by_ip,%by_location,@intdoms,@instdoms);
     &build_location_hashes(\@intdoms,\%by_ip,\%by_location);      &build_location_hashes(\@intdoms,\%by_ip,\%by_location,\@instdoms);
     my @locations = sort(keys(%by_location));      my @locations = sort(keys(%by_location));
     my (%defaultshash,%changes);      my (%defaultshash,%changes);
     foreach my $prefix (@prefixes) {      foreach my $prefix (@prefixes) {
Line 15826  sub modify_usersessions { Line 15037  sub modify_usersessions {
     return $resulttext;      return $resulttext;
 }  }
   
   sub modify_ssl {
       my ($dom,$lastactref,%domconfig) = @_;
       my (%by_ip,%by_location,@intdoms,@instdoms);
       &build_location_hashes(\@intdoms,\%by_ip,\%by_location,\@instdoms);
       my @locations = sort(keys(%by_location));
       my %servers = &Apache::lonnet::internet_dom_servers($dom);
       my (%defaultshash,%changes);
       my $action = 'ssl';
       my @prefixes = ('connto','connfrom','replication');
       foreach my $prefix (@prefixes) {
           $defaultshash{$action}{$prefix} = {};
       }
       my %domdefaults = &Apache::lonnet::get_domain_defaults($dom,1);
       my $resulttext;
       my %iphost = &Apache::lonnet::get_iphost();
       my @reptypes = ('certreq','nocertreq');
       my @connecttypes = ('dom','intdom','other');
       my %types = (
                     connto      => \@connecttypes,
                     connfrom    => \@connecttypes,
                     replication => \@reptypes,
                   );
       foreach my $prefix (sort(keys(%types))) {
           foreach my $type (@{$types{$prefix}}) {
               if (($prefix eq 'connto') || ($prefix eq 'connfrom')) {
                   my $value = 'yes';
                   if ($env{'form.'.$prefix.'_'.$type} =~ /^(no|req)$/) {
                       $value = $env{'form.'.$prefix.'_'.$type};
                   }
                   if (ref($domconfig{$action}{$prefix}) eq 'HASH') {
                       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;
                       }
                   } else {
                       $defaultshash{$action}{$prefix}{$type} = $value;
                       $changes{$prefix}{$type} = 1;
                   }
                   if (($type eq 'dom') && (keys(%servers) == 1)) {
                       delete($changes{$prefix}{$type});
                   } elsif (($type eq 'intdom') && (@instdoms == 1)) {
                       delete($changes{$prefix}{$type});
                   } elsif (($type eq 'other') && (keys(%by_location) == 0)) { 
                       delete($changes{$prefix}{$type});
                   }
               } elsif ($prefix eq 'replication') {
                   if (@locations > 0) {
                       my $inuse = $env{'form.'.$prefix.'_'.$type.'_inuse'};
                       my @vals = &Apache::loncommon::get_env_multiple('form.'.$prefix.'_'.$type);
                       my @okvals;
                       foreach my $val (@vals) {
                           if ($val =~ /:/) {
                               my @items = split(/:/,$val);
                               foreach my $item (@items) {
                                   if (ref($by_location{$item}) eq 'ARRAY') {
                                       push(@okvals,$item);
                                   }
                               }
                           } else {
                               if (ref($by_location{$val}) eq 'ARRAY') {
                                   push(@okvals,$val);
                               }
                           }
                       }
                       @okvals = sort(@okvals);
                       if (ref($domconfig{$action}) eq 'HASH') {
                           if (ref($domconfig{$action}{$prefix}) eq 'HASH') {
                               if (ref($domconfig{$action}{$prefix}{$type}) eq 'ARRAY') {
                                   if ($inuse == 0) {
                                       $changes{$prefix}{$type} = 1;
                                   } else {
                                       $defaultshash{$action}{$prefix}{$type} = \@okvals;
                                       my @changed = &Apache::loncommon::compare_arrays($domconfig{$action}{$prefix}{$type},$defaultshash{$action}{$prefix}{$type});
                                       if (@changed > 0) {
                                           $changes{$prefix}{$type} = 1;
                                       }
                                   }
                               } else {
                                   if ($inuse == 1) {
                                       $defaultshash{$action}{$prefix}{$type} = \@okvals;
                                       $changes{$prefix}{$type} = 1;
                                   }
                               }
                           } else {
                               if ($inuse == 1) {
                                   $defaultshash{$action}{$prefix}{$type} = \@okvals;
                                   $changes{$prefix}{$type} = 1;
                               }
                           }
                       } else {
                           if ($inuse == 1) {
                               $defaultshash{$action}{$prefix}{$type} = \@okvals;
                               $changes{$prefix}{$type} = 1;
                           }
                       }
                   }
               }
           }
       }
       my $nochgmsg = &mt('No changes made to LON-CAPA SSL settings');
       if (keys(%changes) > 0) {
           my $putresult = &Apache::lonnet::put_dom('configuration',\%defaultshash,
                                                    $dom);
           if ($putresult eq 'ok') {
               if (ref($defaultshash{$action}) eq 'HASH') {
                   if (ref($defaultshash{$action}{'replication'}) eq 'HASH') {
                       $domdefaults{'replication'} = $defaultshash{$action}{'replication'};
                   }
                   if (ref($defaultshash{$action}{'connto'}) eq 'HASH') {
                       $domdefaults{'connto'} = $domconfig{$action}{'connto'};
                   }
                   if (ref($defaultshash{$action}{'connfrom'}) eq 'HASH') {
                       $domdefaults{'connfrom'} = $domconfig{$action}{'connfrom'};
                   }
               }
               my $cachetime = 24*60*60;
               &Apache::lonnet::do_cache_new('domdefaults',$dom,\%domdefaults,$cachetime);
               if (ref($lastactref) eq 'HASH') {
                   $lastactref->{'domdefaults'} = 1;
               }
               if (keys(%changes) > 0) {
                   my %titles = &ssl_titles();
                   $resulttext = &mt('Changes made:').'<ul>';
                   foreach my $prefix (@prefixes) {
                       if (ref($changes{$prefix}) eq 'HASH') {
                           $resulttext .= '<li>'.$titles{$prefix}.'<ul>';
                           foreach my $type (@{$types{$prefix}}) {
                               if (defined($changes{$prefix}{$type})) {
                                   my $newvalue;
                                   if (ref($defaultshash{$action}) eq 'HASH') {
                                       if (ref($defaultshash{$action}{$prefix})) {
                                           if (($prefix eq 'connto') || ($prefix eq 'connfrom')) {
                                               $newvalue = $titles{$defaultshash{$action}{$prefix}{$type}};
                                           } elsif (ref($defaultshash{$action}{$prefix}{$type}) eq 'ARRAY') {
                                               if (@{$defaultshash{$action}{$prefix}{$type}} > 0) {
                                                   $newvalue = join(', ',@{$defaultshash{$action}{$prefix}{$type}});
                                               }
                                           }
                                       }
                                       if ($newvalue eq '') {
                                           $resulttext .= '<li>'.&mt('[_1] set to: none',$titles{$type}).'</li>';
                                       } else {
                                           $resulttext .= '<li>'.&mt('[_1] set to: [_2].',$titles{$type},$newvalue).'</li>';
                                       }
                                   }
                               }
                           }
                           $resulttext .= '</ul>';
                       }
                   }
               } else {
                   $resulttext = $nochgmsg;
               }
           } else {
               $resulttext = '<span class="LC_error">'.
                             &mt('An error occurred: [_1]',$putresult).'</span>';
           }
       } else {
           $resulttext = $nochgmsg;
       }
       return $resulttext;
   }
   
   sub modify_trust {
       my ($dom,$lastactref,%domconfig) = @_;
       my (%by_ip,%by_location,@intdoms,@instdoms);
       &build_location_hashes(\@intdoms,\%by_ip,\%by_location,\@instdoms);
       my @locations = sort(keys(%by_location));
       my @prefixes = qw(content shared enroll othcoau coaurem domroles catalog reqcrs msg);
       my @types = ('exc','inc');
       my (%defaultshash,%changes);
       foreach my $prefix (@prefixes) {
           $defaultshash{'trust'}{$prefix} = {};
       }
       my %domdefaults = &Apache::lonnet::get_domain_defaults($dom,1);
       my $resulttext;
       foreach my $prefix (@prefixes) {
           foreach my $type (@types) {
               my $inuse = $env{'form.'.$prefix.'_'.$type.'_inuse'};
               my @vals = &Apache::loncommon::get_env_multiple('form.'.$prefix.'_'.$type);
               my @okvals;
               foreach my $val (@vals) {
                   if ($val =~ /:/) {
                       my @items = split(/:/,$val);
                       foreach my $item (@items) {
                           if (ref($by_location{$item}) eq 'ARRAY') {
                               push(@okvals,$item);
                           }
                       }
                   } else {
                       if (ref($by_location{$val}) eq 'ARRAY') {
                           push(@okvals,$val);
                       }
                   }
               }
               @okvals = sort(@okvals);
               if (ref($domconfig{'trust'}) eq 'HASH') {
                   if (ref($domconfig{'trust'}{$prefix}) eq 'HASH') {
                       if (ref($domconfig{'trust'}{$prefix}{$type}) eq 'ARRAY') {
                           if ($inuse == 0) {
                               $changes{$prefix}{$type} = 1;
                           } else {
                               $defaultshash{'trust'}{$prefix}{$type} = \@okvals;
                               my @changed = &Apache::loncommon::compare_arrays($domconfig{'trust'}{$prefix}{$type},$defaultshash{'trust'}{$prefix}{$type});
                               if (@changed > 0) {
                                   $changes{$prefix}{$type} = 1;
                               }
                           }
                       } else {
                           if ($inuse == 1) {
                               $defaultshash{'trust'}{$prefix}{$type} = \@okvals;
                               $changes{$prefix}{$type} = 1;
                           }
                       }
                   } else {
                       if ($inuse == 1) {
                           $defaultshash{'trust'}{$prefix}{$type} = \@okvals;
                           $changes{$prefix}{$type} = 1;
                       }
                   }
               } else {
                   if ($inuse == 1) {
                       $defaultshash{'trust'}{$prefix}{$type} = \@okvals;
                       $changes{$prefix}{$type} = 1;
                   }
               }
           }
       }
       my $nochgmsg = &mt('No changes made to trust settings.');
       if (keys(%changes) > 0) {
           my $putresult = &Apache::lonnet::put_dom('configuration',\%defaultshash,
                                                    $dom);
           if ($putresult eq 'ok') {
               if (ref($defaultshash{'trust'}) eq 'HASH') {
                   foreach my $prefix (@prefixes) {
                       if (ref($defaultshash{'trust'}{$prefix}) eq 'HASH') {
                           $domdefaults{'trust'.$prefix} = $defaultshash{'trust'}{$prefix};
                       }
                   }
               }
               my $cachetime = 24*60*60;
               &Apache::lonnet::do_cache_new('domdefaults',$dom,\%domdefaults,$cachetime);
               if (ref($lastactref) eq 'HASH') {
                   $lastactref->{'domdefaults'} = 1;
               }
               if (keys(%changes) > 0) {
                   my %lt = &trust_titles();
                   $resulttext = &mt('Changes made:').'<ul>';
                   foreach my $prefix (@prefixes) {
                       if (ref($changes{$prefix}) eq 'HASH') {
                           $resulttext .= '<li>'.$lt{$prefix}.'<ul>';
                           foreach my $type (@types) {
                               if (defined($changes{$prefix}{$type})) {
                                   my $newvalue;
                                   if (ref($defaultshash{'trust'}) eq 'HASH') {
                                       if (ref($defaultshash{'trust'}{$prefix})) {
                                           if (ref($defaultshash{'trust'}{$prefix}{$type}) eq 'ARRAY') {
                                               if (@{$defaultshash{'trust'}{$prefix}{$type}} > 0) {
                                                   $newvalue = join(', ',@{$defaultshash{'trust'}{$prefix}{$type}});
                                               }
                                           }
                                       }
                                   }
                                   if ($newvalue eq '') {
                                       $resulttext .= '<li>'.&mt('[_1] set to: none',$lt{$type}).'</li>';
                                   } else {
                                       $resulttext .= '<li>'.&mt('[_1] set to: [_2].',$lt{$type},$newvalue).'</li>';
                                   }
                               }
                           }
                           $resulttext .= '</ul>';
                       }
                   }
                   $resulttext .= '</ul>';
               } else {
                   $resulttext = $nochgmsg;
               }
           } else {
               $resulttext = '<span class="LC_error">'.
                             &mt('An error occurred: [_1]',$putresult).'</span>';
           }
       } else {
           $resulttext = $nochgmsg;
       }
       return $resulttext;
   }
   
 sub modify_loadbalancing {  sub modify_loadbalancing {
     my ($dom,%domconfig) = @_;      my ($dom,%domconfig) = @_;
     my $primary_id = &Apache::lonnet::domain($dom,'primary');      my $primary_id = &Apache::lonnet::domain($dom,'primary');
Line 15837  sub modify_loadbalancing { Line 15340  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,%currcookies);      my (%currbalancer,%currtargets,%currrules,%existing);
     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,\%currcookies);                                \%currtargets,\%currrules);
     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 15894  sub modify_loadbalancing { Line 15397  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 16059  sub modify_loadbalancing { Line 15550  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 16292  sub lonbalance_targets_js { Line 15779  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,%currcookies);      my (%currbalancer,%currtargets,%currrules,%existing);
     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,\%currcookies);                                \%currtargets,\%currrules);
     my $balancers = join("','",sort(keys(%currbalancer)));      my $balancers = join("','",sort(keys(%currbalancer)));
     return <<"END";      return <<"END";
   
Line 16839  sub devalidate_remote_domconfs { Line 16326  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','usersessions',      my @posscached = ('domainconfig','domdefaults','ltitools','usersessions','directorysrch');
                       'ltitools','directorysrch','passwdconf','cats');  
     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.160.6.102.2.3  
changed lines
  Added in v.1.319


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