Diff for /loncom/interface/domainprefs.pm between versions 1.160.6.102.2.2 and 1.271

version 1.160.6.102.2.2, 2020/02/04 18:51:20 version 1.271, 2016/04/02 04:30:19
Line 19 Line 19
 #  #
 # You should have received a copy of the GNU General Public License  # You should have received a copy of the GNU General Public License
 # along with LON-CAPA; if not, write to the Free Software  # along with LON-CAPA; if not, write to the Free Software
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA  # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA#
 #  
 # /home/httpd/html/adm/gpl.txt  # /home/httpd/html/adm/gpl.txt
 #  #
 # http://www.lon-capa.org/  # http://www.lon-capa.org/
Line 104  $datatable  - HTML containing form eleme Line 103  $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 174  use File::Copy; Line 173  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 217  sub handler {
                 'serverstatuses','requestcourses','helpsettings',                  'serverstatuses','requestcourses','helpsettings',
                 'coursedefaults','usersessions','loadbalancing',                  'coursedefaults','usersessions','loadbalancing',
                 'requestauthor','selfenrollment','inststatus',                  'requestauthor','selfenrollment','inststatus',
                 'passwords','ltitools'],$dom);                  'ltitools'],$dom);
     if (ref($domconfig{'ltitools'}) eq 'HASH') {      my @prefs_order = ('rolecolors','login','defaults','quotas','autoenroll',
         my %encconfig =  
             &Apache::lonnet::get_dom('encconfig',['ltitools'],$dom);  
         if (ref($encconfig{'ltitools'}) eq 'HASH') {  
             foreach my $id (keys(%{$domconfig{'ltitools'}})) {  
                 if (ref($domconfig{'ltitools'}{$id}) eq 'HASH') {  
                     foreach my $item ('key','secret') {  
                         $domconfig{'ltitools'}{$id}{$item} = $encconfig{'ltitools'}{$id}{$item};  
                     }  
                 }  
             }  
         }  
     }  
     my @prefs_order = ('rolecolors','login','defaults','passwords','quotas','autoenroll',  
                        'autoupdate','autocreate','directorysrch','contacts',                         'autoupdate','autocreate','directorysrch','contacts',
                        'usercreation','selfcreation','usermodification','scantron',                         'usercreation','selfcreation','usermodification','scantron',
                        'requestcourses','requestauthor','coursecategories',                         'requestcourses','requestauthor','coursecategories',
Line 277  sub handler { Line 264  sub handler {
                       header => [{col1 => 'Setting',                        header => [{col1 => 'Setting',
                                   col2 => 'Value'},                                    col2 => 'Value'},
                                  {col1 => 'Institutional user types',                                   {col1 => 'Institutional user types',
                                   col2 => 'Name displayed'}],                                    col2 => 'Assignable to e-mail usernames'}],
                       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 333  sub handler { Line 306  sub handler {
                      modify => \&modify_autocreate,                       modify => \&modify_autocreate,
                   },                    },
         'directorysrch' =>           'directorysrch' => 
                   { text => 'Directory searches',                    { text => 'Institutional directory searches',
                     help => 'Domain_Configuration_InstDirectory_Search',                      help => 'Domain_Configuration_InstDirectory_Search',
                     header => [{col1 => 'Institutional Directory Setting',                      header => [{col1 => 'Setting',
                                 col2 => 'Value',},  
                                {col1 => 'LON-CAPA Directory Setting',  
                                 col2 => 'Value',}],                                  col2 => 'Value',}],
                     print => \&print_directorysrch,                      print => \&print_directorysrch,
                     modify => \&modify_directorysrch,                      modify => \&modify_directorysrch,
                   },                    },
         'contacts' =>          'contacts' =>
                   { text => 'E-mail addresses and helpform',                    { text => 'Contact Information',
                     help => 'Domain_Configuration_Contact_Info',                      help => 'Domain_Configuration_Contact_Info',
                     header => [{col1 => 'Default e-mail addresses',                      header => [{col1 => 'Setting',
                                 col2 => 'Value',},                                  col2 => 'Value',}],
                                {col1 => 'Recipient(s) for notifications',  
                                 col2 => 'Value',},  
                                {col1 => 'Ask helpdesk form settings',  
                                 col2 => 'Value',},],  
                     print => \&print_contacts,                      print => \&print_contacts,
                     modify => \&modify_contacts,                      modify => \&modify_contacts,
                   },                    },
Line 373  sub handler { Line 340  sub handler {
                                 col2 => 'Enabled?'},                                  col2 => 'Enabled?'},
                                {col1 => 'Institutional user type (login/SSO self-creation)',                                 {col1 => 'Institutional user type (login/SSO self-creation)',
                                 col2 => 'Information user can enter'},                                  col2 => 'Information user can enter'},
                                {col1 => 'Self-creation with e-mail verification',                                 {col1 => 'Self-creation with e-mail as username',
                                 col2 => 'Settings'}],                                  col2 => 'Settings'}],
                     print => \&print_selfcreation,                      print => \&print_selfcreation,
                     modify => \&modify_selfcreation,                      modify => \&modify_selfcreation,
Line 389  sub handler { Line 356  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 448  sub handler { Line 414  sub handler {
                   modify => \&modify_serverstatuses,                    modify => \&modify_serverstatuses,
                  },                   },
         'helpsettings' =>          'helpsettings' =>
                  {text   => 'Support settings',                   {text   => 'Help page settings',
                   help   => 'Domain_Configuration_Help_Settings',                    help   => 'Domain_Configuration_Help_Settings',
                   header => [{col1 => 'Help Page Settings (logged-in users)',                    header => [{col1 => 'Help Settings (logged-in users)',
                               col2 => 'Value'},                                col2 => 'Value'}],
                              {col1 => 'Helpdesk Roles',  
                               col2 => 'Settings'},],  
                   print  => \&print_helpsettings,                    print  => \&print_helpsettings,
                   modify => \&modify_helpsettings,                    modify => \&modify_helpsettings,
                  },                   },
Line 479  sub handler { Line 443  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 491  sub handler { Line 463  sub handler {
                   print => \&print_usersessions,                    print => \&print_usersessions,
                   modify => \&modify_usersessions,                    modify => \&modify_usersessions,
                  },                   },
         'loadbalancing' =>           'loadbalancing' =>
                  {text  => 'Dedicated Load Balancer(s)',                   {text  => 'Dedicated Load Balancer(s)',
                   help  => 'Domain_Configuration_Load_Balancing',                    help  => 'Domain_Configuration_Load_Balancing',
                   header => [{col1 => 'Balancers',                    header => [{col1 => 'Balancers',
Line 502  sub handler { Line 474  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',
                               col2 => 'Value',}],                                col2 => 'Value',}],
                   print => \&print_ltitools,                    print => \&print_ltitools,
                   modify => \&modify_ltitools,                    modify => \&modify_ltitools,
                  },                   },
    
     );      );
     if (keys(%servers) > 1) {      if (keys(%servers) > 1) {
         $prefs{'login'}  = { text   => 'Log-in page options',          $prefs{'login'}  = { text   => 'Log-in page options',
Line 563  $javascript_validations Line 536  $javascript_validations
 $coursebrowserjs  $coursebrowserjs
 END  END
         }          }
         if (grep(/^selfcreation$/,@actions)) {  
             $js .= &selfcreate_javascript();  
         }  
         if (grep(/^contacts$/,@actions)) {  
             $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 661  sub process_changes { Line 625  sub process_changes {
     } elsif ($action eq 'autocreate') {      } elsif ($action eq 'autocreate') {
         $output = &modify_autocreate($dom,%domconfig);          $output = &modify_autocreate($dom,%domconfig);
     } elsif ($action eq 'directorysrch') {      } elsif ($action eq 'directorysrch') {
         $output = &modify_directorysrch($dom,$lastactref,%domconfig);          $output = &modify_directorysrch($dom,%domconfig);
     } elsif ($action eq 'usercreation') {      } elsif ($action eq 'usercreation') {
         $output = &modify_usercreation($dom,%domconfig);          $output = &modify_usercreation($dom,%domconfig);
     } elsif ($action eq 'selfcreation') {      } elsif ($action eq 'selfcreation') {
         $output = &modify_selfcreation($dom,$lastactref,%domconfig);          $output = &modify_selfcreation($dom,%domconfig);
     } elsif ($action eq 'usermodification') {      } elsif ($action eq 'usermodification') {
         $output = &modify_usermodification($dom,%domconfig);          $output = &modify_usermodification($dom,%domconfig);
     } elsif ($action eq 'contacts') {      } elsif ($action eq 'contacts') {
Line 683  sub process_changes { Line 647  sub process_changes {
     } elsif ($action eq 'requestauthor') {      } elsif ($action eq 'requestauthor') {
         $output = &modify_quotas($r,$dom,$action,$lastactref,%domconfig);          $output = &modify_quotas($r,$dom,$action,$lastactref,%domconfig);
     } elsif ($action eq 'helpsettings') {      } elsif ($action eq 'helpsettings') {
         $output = &modify_helpsettings($r,$dom,$confname,$lastactref,%domconfig);          $output = &modify_helpsettings($r,$dom,$confname,%domconfig);
     } elsif ($action eq 'coursedefaults') {      } elsif ($action eq 'coursedefaults') {
         $output = &modify_coursedefaults($dom,$lastactref,%domconfig);          $output = &modify_coursedefaults($dom,$lastactref,%domconfig);
     } elsif ($action eq 'selfenrollment') {      } elsif ($action eq 'selfenrollment') {
Line 692  sub process_changes { Line 656  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);
     }      }
Line 708  sub print_config_box { Line 670  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') {  
         my (%privs,%levelscurrent);  
         my %full=();  
         my %levels=(  
                      course => {},  
                      domain => {},  
                      system => {},  
                    );  
         my $context = 'domain';  
         my $crstype = 'Course';  
         my $formname = 'display';  
         &Apache::lonuserutils::custom_role_privs(\%privs,\%full,\%levels,\%levelscurrent);  
         my @templateroles = &Apache::lonuserutils::custom_template_roles($context,$crstype);  
         $output =  
             &Apache::lonuserutils::custom_roledefs_js($context,$crstype,$formname,\%full,  
                                                       \@templateroles);  
     }      }
     $output .=      $output .=
          '<table class="LC_nested_outer">           '<table class="LC_nested_outer">
Line 743  sub print_config_box { Line 687  sub print_config_box {
         my $colspan = '';          my $colspan = '';
         my $rightcolspan = '';          my $rightcolspan = '';
         if (($action eq 'rolecolors') || ($action eq 'defaults') ||          if (($action eq 'rolecolors') || ($action eq 'defaults') ||
             ($action eq 'directorysrch') ||  
             (($action eq 'login') && ($numheaders < 4))) {              (($action eq 'login') && ($numheaders < 4))) {
             $colspan = ' colspan="2"';              $colspan = ' colspan="2"';
         }          }
Line 761  sub print_config_box { Line 704  sub print_config_box {
         $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 '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 796  sub print_config_box { Line 734  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')) {  
             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') {  
                 $output .= $item->{'print'}->('middle',$dom,$confname,$settings,\$rowtotal);  
             } else {              } else {
                 $output .= $item->{'print'}->('middle',$dom,$settings,\$rowtotal);                  $output .= $item->{'print'}->('middle',$dom,$settings,\$rowtotal);
             }              }
Line 819  sub print_config_box { Line 754  sub print_config_box {
              </tr>'."\n";               </tr>'."\n";
             if ($action eq 'coursecategories') {              if ($action eq 'coursecategories') {
                 $output .= &print_coursecategories('bottom',$dom,$item,$settings,\$rowtotal);                  $output .= &print_coursecategories('bottom',$dom,$item,$settings,\$rowtotal);
             } elsif ($action eq 'passwords') {  
                 $output .= $item->{'print'}->('lower',$dom,$confname,$settings,\$rowtotal).'  
              </tr>  
             </table>  
            </td>  
           </tr>  
           <tr>  
            <td>  
             <table class="LC_nested">  
              <tr class="LC_info_row">  
               <td class="LC_left_item"'.$colspan.'>'.&mt($item->{'header'}->[3]->{'col1'}).'</td>  
               <td class="LC_right_item"'.$colspan.'>'.&mt($item->{'header'}->[3]->{'col2'}).'</td></tr>'."\n".  
               $item->{'print'}->('bottom',$dom,$confname,$settings,\$rowtotal).'  
             </table>  
           </td>  
          </tr>  
          <tr>';  
             } else {              } else {
                 $output .= $item->{'print'}->('bottom',$dom,$settings,\$rowtotal);                  $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 'helpsettings')) {  
             $output .= $item->{'print'}->('bottom',$dom,$settings,\$rowtotal);              $output .= $item->{'print'}->('bottom',$dom,$settings,\$rowtotal);
         } elsif ($action eq 'scantron') {  
             $output .= $item->{'print'}->($r,'bottom',$dom,$confname,$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 957  sub print_config_box { Line 872  sub print_config_box {
            <td>             <td>
             <table class="LC_nested">              <table class="LC_nested">
              <tr class="LC_info_row">';               <tr class="LC_info_row">';
         if ($action eq 'login') {          if (($action eq 'login') || ($action eq 'directorysrch')) {
             $output .= '                $output .= '  
               <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') {
Line 1001  sub print_config_box { Line 916  sub print_config_box {
         $rowtotal ++;          $rowtotal ++;
         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 'directorysrch') ||
                  ($action eq 'serverstatuses') || ($action eq 'loadbalancing') ||                   ($action eq 'contacts') || ($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);
           } elsif ($action eq 'helpsettings') {
               $output .= &print_helpsettings($dom,$confname,$settings,\$rowtotal);
         }          }
     }      }
     $output .= '      $output .= '
Line 1349  sub print_login { Line 1268  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 1509  sub display_color_options { Line 1428  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 1518  sub display_color_options { Line 1437  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 1533  sub display_color_options { Line 1452  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 1592  sub display_color_options { Line 1511  sub display_color_options {
                         if ($fullwidth ne '' && $fullheight ne '') {                          if ($fullwidth ne '' && $fullheight ne '') {
                             if ($fullwidth > $width && $fullheight > $height) {                               if ($fullwidth > $width && $fullheight > $height) { 
                                 my $size = $width.'x'.$height;                                  my $size = $width.'x'.$height;
                                 my @args = ('convert','-sample',$size,$input,$output);                                  system("convert -sample $size $input $output");
                                 system({$args[0]} @args);  
                                 $showfile = "/$imgdir/tn-".$filename;                                  $showfile = "/$imgdir/tn-".$filename;
                             }                              }
                         }                          }
Line 1651  sub display_color_options { Line 1569  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 1679  sub display_color_options { Line 1597  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 1765  sub image_changes { Line 1683  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 1804  sub print_quotas { Line 1724  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 2217  sub print_quotas { Line 2137  sub print_quotas {
 }  }
   
 sub print_requestmail {  sub print_requestmail {
     my ($dom,$action,$settings,$rowtotal,$customcss,$rowstyle) = @_;      my ($dom,$action,$settings,$rowtotal) = @_;
     my ($now,$datatable,%currapp);      my ($now,$datatable,%currapp);
     $now = time;      $now = time;
     if (ref($settings) eq 'HASH') {      if (ref($settings) eq 'HASH') {
Line 2229  sub print_requestmail { Line 2149  sub print_requestmail {
     }      }
     my $numinrow = 2;      my $numinrow = 2;
     my $css_class;      my $css_class;
     if ($$rowtotal%2) {      $css_class = ($$rowtotal%2? ' class="LC_odd_row"':'');
         $css_class = 'LC_odd_row';  
     }  
     if ($customcss) {  
         $css_class .= " $customcss";  
     }  
     $css_class =~ s/^\s+//;  
     if ($css_class) {  
         $css_class = ' class="'.$css_class.'"';  
     }  
     if ($rowstyle) {  
         $css_class .= ' style="'.$rowstyle.'"';  
     }  
     my $text;      my $text;
     if ($action eq 'requestcourses') {      if ($action eq 'requestcourses') {
         $text = &mt('Receive notification of course requests requiring approval');          $text = &mt('Receive notification of course requests requiring approval');
Line 2268  sub print_studentcode { Line 2176  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 2364  sub print_textbookcourses { Line 2272  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 2396  sub print_textbookcourses { Line 2303  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 2413  sub print_textbookcourses { Line 2320  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 2590  ENDSCRIPT Line 2497  ENDSCRIPT
 sub print_autoenroll {  sub print_autoenroll {
     my ($dom,$settings,$rowtotal) = @_;      my ($dom,$settings,$rowtotal) = @_;
     my $autorun = &Apache::lonnet::auto_run(undef,$dom),      my $autorun = &Apache::lonnet::auto_run(undef,$dom),
     my ($defdom,$runon,$runoff,$coownerson,$coownersoff,$failsafe);      my ($defdom,$runon,$runoff,$coownerson,$coownersoff);
     if (ref($settings) eq 'HASH') {      if (ref($settings) eq 'HASH') {
         if (exists($settings->{'run'})) {          if (exists($settings->{'run'})) {
             if ($settings->{'run'} eq '0') {              if ($settings->{'run'} eq '0') {
Line 2624  sub print_autoenroll { Line 2531  sub print_autoenroll {
         if (exists($settings->{'sender_domain'})) {          if (exists($settings->{'sender_domain'})) {
             $defdom = $settings->{'sender_domain'};              $defdom = $settings->{'sender_domain'};
         }          }
         if (exists($settings->{'autofailsafe'})) {  
             $failsafe = $settings->{'autofailsafe'};  
         }  
     } else {      } else {
         if ($autorun) {          if ($autorun) {
             $runon = ' checked="checked" ';              $runon = ' checked="checked" ';
Line 2662  sub print_autoenroll { Line 2566  sub print_autoenroll {
                   $coownerson.' value="1" />'.&mt('Yes').'</label>&nbsp;'.                    $coownerson.' value="1" />'.&mt('Yes').'</label>&nbsp;'.
                   '<label><input type="radio" name="autoassign_coowners"'.                    '<label><input type="radio" name="autoassign_coowners"'.
                   $coownersoff.' value="0" />'.&mt('No').'</label></span></td>'.                    $coownersoff.' value="0" />'.&mt('No').'</label></span></td>'.
                   '</tr><tr>'.                    '</tr>';
                   '<td>'.&mt('Failsafe for no drops when institutional data missing').'</td>'.      $$rowtotal += 3;
                   '<td class="LC_right_item"><span class="LC_nobreak">'.  
                   '<input type="text" name="autoenroll_failsafe"'.  
                   ' value="'.$failsafe.'" size="4" /></span></td></tr>';  
     $$rowtotal += 4;  
     return $datatable;      return $datatable;
 }  }
   
Line 2715  sub print_autoupdate { Line 2615  sub print_autoupdate {
         my $locknamesettings;          my $locknamesettings;
         $datatable .= &insttypes_row($settings,$types,$usertypes,          $datatable .= &insttypes_row($settings,$types,$usertypes,
                                      $dom,$numinrow,$othertitle,                                       $dom,$numinrow,$othertitle,
                                     'lockablenames',$rowtotal);                                      'lockablenames');
         $$rowtotal ++;          $$rowtotal ++;
     } else {      } else {
         my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom);          my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom);
Line 2796  sub print_autocreate { Line 2696  sub print_autocreate {
 }  }
   
 sub print_directorysrch {  sub print_directorysrch {
     my ($position,$dom,$settings,$rowtotal) = @_;      my ($dom,$settings,$rowtotal) = @_;
     my $datatable;      my $srchon = ' ';
     if ($position eq 'top') {      my $srchoff = ' checked="checked" ';
         my $instsrchon = ' ';      my ($exacton,$containson,$beginson);
         my $instsrchoff = ' checked="checked" ';      my $localon = ' ';
         my ($exacton,$containson,$beginson);      my $localoff = ' checked="checked" ';
         my $instlocalon = ' ';      if (ref($settings) eq 'HASH') {
         my $instlocaloff = ' checked="checked" ';          if ($settings->{'available'} eq '1') {
         if (ref($settings) eq 'HASH') {              $srchon = $srchoff;
             if ($settings->{'available'} eq '1') {              $srchoff = ' ';
                 $instsrchon = $instsrchoff;          }
                 $instsrchoff = ' ';          if ($settings->{'localonly'} eq '1') {
             }              $localon = $localoff;
             if ($settings->{'localonly'} eq '1') {              $localoff = ' ';
                 $instlocalon = $instlocaloff;          }
                 $instlocaloff = ' ';          if (ref($settings->{'searchtypes'}) eq 'ARRAY') {
             }              foreach my $type (@{$settings->{'searchtypes'}}) {
             if (ref($settings->{'searchtypes'}) eq 'ARRAY') {                  if ($type eq 'exact') {
                 foreach my $type (@{$settings->{'searchtypes'}}) {  
                     if ($type eq 'exact') {  
                         $exacton = ' checked="checked" ';  
                     } elsif ($type eq 'contains') {  
                         $containson = ' checked="checked" ';  
                     } elsif ($type eq 'begins') {  
                         $beginson = ' checked="checked" ';  
                     }  
                 }  
             } else {  
                 if ($settings->{'searchtypes'} eq 'exact') {  
                     $exacton = ' checked="checked" ';  
                 } elsif ($settings->{'searchtypes'} eq 'contains') {  
                     $containson = ' checked="checked" ';  
                 } elsif ($settings->{'searchtypes'} eq 'specify') {  
                     $exacton = ' checked="checked" ';                      $exacton = ' checked="checked" ';
                   } elsif ($type eq 'contains') {
                     $containson = ' checked="checked" ';                      $containson = ' checked="checked" ';
                   } elsif ($type eq 'begins') {
                       $beginson = ' checked="checked" ';
                 }                  }
             }              }
         }          } else {
         my ($searchtitles,$titleorder) = &sorted_searchtitles();              if ($settings->{'searchtypes'} eq 'exact') {
         my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom);                  $exacton = ' checked="checked" ';
               } elsif ($settings->{'searchtypes'} eq 'contains') {
         my $numinrow = 4;                  $containson = ' checked="checked" ';
         my $cansrchrow = 0;              } elsif ($settings->{'searchtypes'} eq 'specify') {
         $datatable='<tr class="LC_odd_row">'.                  $exacton = ' checked="checked" ';
                    '<td colspan="2"><span class ="LC_nobreak">'.&mt('Institutional directory search available?').'</span></td>'.                  $containson = ' checked="checked" ';
                    '<td class="LC_right_item"><span class="LC_nobreak"><label>'.  
                    '<input type="radio" name="dirsrch_available"'.  
                    $instsrchon.' value="1" />'.&mt('Yes').'</label>&nbsp;'.  
                    '<label><input type="radio" name="dirsrch_available"'.  
                    $instsrchoff.' value="0" />'.&mt('No').'</label></span></td>'.  
                    '</tr><tr>'.  
                    '<td colspan="2"><span class ="LC_nobreak">'.&mt('Other domains can search institution?').'</span></td>'.  
                    '<td class="LC_right_item"><span class="LC_nobreak"><label>'.  
                    '<input type="radio" name="dirsrch_instlocalonly"'.  
                    $instlocaloff.' value="0" />'.&mt('Yes').'</label>&nbsp;'.  
                    '<label><input type="radio" name="dirsrch_instlocalonly"'.  
                    $instlocalon.' value="1" />'.&mt('No').'</label></span></td>'.  
                    '</tr>';  
         $$rowtotal += 2;  
         if (ref($usertypes) eq 'HASH') {  
             if (keys(%{$usertypes}) > 0) {  
                 $datatable .= &insttypes_row($settings,$types,$usertypes,$dom,  
                                              $numinrow,$othertitle,'cansearch',  
                                              $rowtotal);  
                 $cansrchrow = 1;  
             }              }
         }          }
         if ($cansrchrow) {      }
             $$rowtotal ++;      my ($searchtitles,$titleorder) = &sorted_searchtitles();
             $datatable .= '<tr>';      my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom);
         } else {  
             $datatable .= '<tr class="LC_odd_row">';      my $numinrow = 4;
       my $cansrchrow = 0;
       my $datatable='<tr class="LC_odd_row">'.
                     '<td colspan="2"><span class ="LC_nobreak">'.&mt('Directory search available?').'</span></td>'.
                     '<td class="LC_right_item"><span class="LC_nobreak"><label>'.
                     '<input type="radio" name="dirsrch_available"'.
                     $srchon.' value="1" />'.&mt('Yes').'</label>&nbsp;'.
                     '<label><input type="radio" name="dirsrch_available"'.
                     $srchoff.' value="0" />'.&mt('No').'</label></span></td>'.
                     '</tr><tr>'.
                     '<td colspan="2"><span class ="LC_nobreak">'.&mt('Other domains can search?').'</span></td>'.
                     '<td class="LC_right_item"><span class="LC_nobreak"><label>'.
                     '<input type="radio" name="dirsrch_localonly"'.
                     $localoff.' value="0" />'.&mt('Yes').'</label>&nbsp;'.
                     '<label><input type="radio" name="dirsrch_localonly"'.
                     $localon.' value="1" />'.&mt('No').'</label></span></td>'.
                     '</tr>';
       $$rowtotal += 2;
       if (ref($usertypes) eq 'HASH') {
           if (keys(%{$usertypes}) > 0) {
               $datatable .= &insttypes_row($settings,$types,$usertypes,$dom,
                                            $numinrow,$othertitle,'cansearch');
               $cansrchrow = 1;
         }          }
         $datatable .= '<td><span class ="LC_nobreak">'.&mt('Supported search methods').      }
                       '</span></td><td class="LC_left_item" colspan="2"><table><tr>';      if ($cansrchrow) {
         foreach my $title (@{$titleorder}) {          $$rowtotal ++;
             if (defined($searchtitles->{$title})) {          $datatable .= '<tr>';
                 my $check = ' ';      } else {
                 if (ref($settings) eq 'HASH') {          $datatable .= '<tr class="LC_odd_row">';
                     if (ref($settings->{'searchby'}) eq 'ARRAY') {      }
                         if (grep(/^\Q$title\E$/,@{$settings->{'searchby'}})) {      $datatable .= '<td><span class ="LC_nobreak">'.&mt('Supported search methods').
                             $check = ' checked="checked" ';                    '</span></td><td class="LC_left_item" colspan="2"><table><tr>';
                         }      foreach my $title (@{$titleorder}) {
           if (defined($searchtitles->{$title})) {
               my $check = ' ';
               if (ref($settings) eq 'HASH') {
                   if (ref($settings->{'searchby'}) eq 'ARRAY') {
                       if (grep(/^\Q$title\E$/,@{$settings->{'searchby'}})) {
                           $check = ' checked="checked" ';
                     }                      }
                 }                  }
                 $datatable .= '<td class="LC_left_item">'.  
                               '<span class="LC_nobreak"><label>'.  
                               '<input type="checkbox" name="searchby" '.  
                               'value="'.$title.'"'.$check.'/>'.  
                               $searchtitles->{$title}.'</label></span></td>';  
             }              }
               $datatable .= '<td class="LC_left_item">'.
                             '<span class="LC_nobreak"><label>'.
                             '<input type="checkbox" name="searchby" '.
                             'value="'.$title.'"'.$check.'/>'.
                             $searchtitles->{$title}.'</label></span></td>';
         }          }
         $datatable .= '</tr></table></td></tr>';      }
         $$rowtotal ++;      $datatable .= '</tr></table></td></tr>';
         if ($cansrchrow) {      $$rowtotal ++;
             $datatable .= '<tr class="LC_odd_row">';      if ($cansrchrow) {
         } else {          $datatable .= '<tr class="LC_odd_row">';
             $datatable .= '<tr>';  
         }  
         $datatable .= '<td><span class ="LC_nobreak">'.&mt('Search latitude').'</span></td>'.     
                       '<td class="LC_left_item" colspan="2">'.  
                       '<span class="LC_nobreak"><label>'.  
                       '<input type="checkbox" name="searchtypes" '.  
                       $exacton.' value="exact" />'.&mt('Exact match').  
                       '</label>&nbsp;'.  
                       '<label><input type="checkbox" name="searchtypes" '.  
                       $beginson.' value="begins" />'.&mt('Begins with').  
                       '</label>&nbsp;'.  
                       '<label><input type="checkbox" name="searchtypes" '.  
                       $containson.' value="contains" />'.&mt('Contains').  
                       '</label></span></td></tr>';  
         $$rowtotal ++;  
     } else {      } else {
         my $domsrchon = ' checked="checked" ';          $datatable .= '<tr>';
         my $domsrchoff = ' ';  
         my $domlocalon = ' ';  
         my $domlocaloff = ' checked="checked" ';  
         if (ref($settings) eq 'HASH') {  
             if ($settings->{'lclocalonly'} eq '1') {  
                 $domlocalon = $domlocaloff;  
                 $domlocaloff = ' ';  
             }  
             if ($settings->{'lcavailable'} eq '0') {  
                 $domsrchoff = $domsrchon;  
                 $domsrchon = ' ';  
             }  
         }  
         $datatable='<tr class="LC_odd_row">'.  
                       '<td colspan="2"><span class ="LC_nobreak">'.&mt('LON-CAPA directory search available?').'</span></td>'.  
                       '<td class="LC_right_item"><span class="LC_nobreak"><label>'.  
                       '<input type="radio" name="dirsrch_domavailable"'.  
                       $domsrchon.' value="1" />'.&mt('Yes').'</label>&nbsp;'.  
                       '<label><input type="radio" name="dirsrch_domavailable"'.  
                       $domsrchoff.' value="0" />'.&mt('No').'</label></span></td>'.  
                       '</tr><tr>'.  
                       '<td colspan="2"><span class ="LC_nobreak">'.&mt('Other domains can search LON-CAPA domain?').'</span></td>'.  
                       '<td class="LC_right_item"><span class="LC_nobreak"><label>'.  
                       '<input type="radio" name="dirsrch_domlocalonly"'.  
                       $domlocaloff.' value="0" />'.&mt('Yes').'</label>&nbsp;'.  
                       '<label><input type="radio" name="dirsrch_domlocalonly"'.  
                       $domlocalon.' value="1" />'.&mt('No').'</label></span></td>'.  
                       '</tr>';  
         $$rowtotal += 2;  
     }      }
       $datatable .= '<td><span class ="LC_nobreak">'.&mt('Search latitude').'</span></td>'.   
                     '<td class="LC_left_item" colspan="2">'.
                     '<span class="LC_nobreak"><label>'.
                     '<input type="checkbox" name="searchtypes" '.
                     $exacton.' value="exact" />'.&mt('Exact match').
                     '</label>&nbsp;'.
                     '<label><input type="checkbox" name="searchtypes" '.
                     $beginson.' value="begins" />'.&mt('Begins with').
                     '</label>&nbsp;'.
                     '<label><input type="checkbox" name="searchtypes" '.
                     $containson.' value="contains" />'.&mt('Contains').
                     '</label></span></td></tr>';
       $$rowtotal ++;
     return $datatable;      return $datatable;
 }  }
   
 sub print_contacts {  sub print_contacts {
     my ($position,$dom,$settings,$rowtotal) = @_;      my ($dom,$settings,$rowtotal) = @_;
     my $datatable;      my $datatable;
     my @contacts = ('adminemail','supportemail');      my @contacts = ('adminemail','supportemail');
     my (%checked,%to,%otheremails,%bccemails,%includestr,%includeloc,%currfield,      my (%checked,%to,%otheremails,%bccemails);
         $maxsize,$fields,$fieldtitles,$fieldoptions,$possoptions,@mailings);      my @mailings = ('errormail','packagesmail','lonstatusmail','helpdeskmail',
     if ($position eq 'top') {                      'requestsmail','updatesmail','idconflictsmail');
         if (ref($settings) eq 'HASH') {      foreach my $type (@mailings) {
             foreach my $item (@contacts) {          $otheremails{$type} = '';
                 if (exists($settings->{$item})) {  
                     $to{$item} = $settings->{$item};  
                 }  
             }  
         }  
     } elsif ($position eq 'middle') {  
         @mailings = ('errormail','packagesmail','lonstatusmail','requestsmail',  
                      'updatesmail','idconflictsmail','hostipmail');  
         foreach my $type (@mailings) {  
             $otheremails{$type} = '';  
         }  
     } else {  
         @mailings = ('helpdeskmail','otherdomsmail');  
         foreach my $type (@mailings) {  
             $otheremails{$type} = '';  
         }  
         $bccemails{'helpdeskmail'} = '';  
         $bccemails{'otherdomsmail'} = '';  
         $includestr{'helpdeskmail'} = '';  
         $includestr{'otherdomsmail'} = '';  
         ($fields,$fieldtitles,$fieldoptions,$possoptions) = &helpform_fields();  
     }      }
       $bccemails{'helpdeskmail'} = '';
     if (ref($settings) eq 'HASH') {      if (ref($settings) eq 'HASH') {
         unless ($position eq 'top') {          foreach my $item (@contacts) {
             foreach my $type (@mailings) {              if (exists($settings->{$item})) {
                 if (exists($settings->{$type})) {                  $to{$item} = $settings->{$item};
                     if (ref($settings->{$type}) eq 'HASH') {  
                         foreach my $item (@contacts) {  
                             if ($settings->{$type}{$item}) {  
                                 $checked{$type}{$item} = ' checked="checked" ';  
                             }  
                         }  
                         $otheremails{$type} = $settings->{$type}{'others'};  
                         if (($type eq 'helpdeskmail') || ($type eq 'otherdomsmail')) {  
                             $bccemails{$type} = $settings->{$type}{'bcc'};  
                             if ($settings->{$type}{'include'} ne '') {  
                                 ($includeloc{$type},$includestr{$type}) = split(/:/,$settings->{$type}{'include'},2);  
                                 $includestr{$type} = &unescape($includestr{$type});  
                             }  
                         }  
                     }  
                 } elsif ($type eq 'lonstatusmail') {  
                     $checked{'lonstatusmail'}{'adminemail'} = ' checked="checked" ';  
                 }  
             }              }
         }          }
         if ($position eq 'bottom') {          foreach my $type (@mailings) {
             foreach my $type (@mailings) {              if (exists($settings->{$type})) {
                 $bccemails{$type} = $settings->{$type}{'bcc'};                  if (ref($settings->{$type}) eq 'HASH') {
                 if ($settings->{$type}{'include'} ne '') {                      foreach my $item (@contacts) {
                     ($includeloc{$type},$includestr{$type}) = split(/:/,$settings->{$type}{'include'},2);                          if ($settings->{$type}{$item}) {
                     $includestr{$type} = &unescape($includestr{$type});                              $checked{$type}{$item} = ' checked="checked" ';
                 }                          }
             }  
             if (ref($settings->{'helpform'}) eq 'HASH') {  
                 if (ref($fields) eq 'ARRAY') {  
                     foreach my $field (@{$fields}) {  
                         $currfield{$field} = $settings->{'helpform'}{$field};  
                     }                      }
                 }                      $otheremails{$type} = $settings->{$type}{'others'};
                 if (exists($settings->{'helpform'}{'maxsize'})) {                      if ($type eq 'helpdeskmail') {
                     $maxsize = $settings->{'helpform'}{'maxsize'};                          $bccemails{$type} = $settings->{$type}{'bcc'};
                 } else {  
                     $maxsize = '1.0';  
                 }  
             } else {  
                 if (ref($fields) eq 'ARRAY') {  
                     foreach my $field (@{$fields}) {  
                         $currfield{$field} = 'yes';  
                     }                      }
                 }                  }
                 $maxsize = '1.0';              } elsif ($type eq 'lonstatusmail') {
                   $checked{'lonstatusmail'}{'adminemail'} = ' checked="checked" ';
             }              }
         }          }
     } else {      } else {
         if ($position eq 'top') {          $to{'supportemail'} = $Apache::lonnet::perlvar{'lonSupportEMail'};
             $to{'supportemail'} = $Apache::lonnet::perlvar{'lonSupportEMail'};          $to{'adminemail'} = $Apache::lonnet::perlvar{'lonAdmEMail'};
             $to{'adminemail'} = $Apache::lonnet::perlvar{'lonAdmEMail'};          $checked{'errormail'}{'adminemail'} = ' checked="checked" ';
             $checked{'errormail'}{'adminemail'} = ' checked="checked" ';          $checked{'packagesmail'}{'adminemail'} = ' checked="checked" ';
             $checked{'packagesmail'}{'adminemail'} = ' checked="checked" ';          $checked{'helpdeskmail'}{'supportemail'} = ' checked="checked" ';
             $checked{'lonstatusmail'}{'adminemail'} = ' checked="checked" ';          $checked{'lonstatusmail'}{'adminemail'} = ' checked="checked" '; 
             $checked{'requestsmail'}{'adminemail'} = ' checked="checked" ';          $checked{'requestsmail'}{'adminemail'} = ' checked="checked" ';
             $checked{'updatesmail'}{'adminemail'} = ' checked="checked" ';          $checked{'updatesmail'}{'adminemail'} = ' checked="checked" ';
             $checked{'idconflictsmail'}{'adminemail'} = ' checked="checked" ';          $checked{'idconflictsmail'}{'adminemail'} = ' checked="checked" ';
             $checked{'hostipmail'}{'adminemail'} = ' checked="checked" ';  
         } elsif ($position eq 'bottom') {  
             $checked{'helpdeskmail'}{'supportemail'} = ' checked="checked" ';  
             $checked{'otherdomsmail'}{'supportemail'} = ' checked="checked" ';  
             if (ref($fields) eq 'ARRAY') {  
                 foreach my $field (@{$fields}) {  
                     $currfield{$field} = 'yes';  
                 }  
             }  
             $maxsize = '1.0';  
         }  
     }      }
     my ($titles,$short_titles) = &contact_titles();      my ($titles,$short_titles) = &contact_titles();
     my $rownum = 0;      my $rownum = 0;
     my $css_class;      my $css_class;
     if ($position eq 'top') {      foreach my $item (@contacts) {
         foreach my $item (@contacts) {          $css_class = $rownum%2?' class="LC_odd_row"':'';
             $css_class = $rownum%2?' class="LC_odd_row"':'';          $datatable .= '<tr'.$css_class.'>'. 
             $datatable .= '<tr'.$css_class.'>'.                     '<td><span class="LC_nobreak">'.$titles->{$item}.
                           '<td><span class="LC_nobreak">'.$titles->{$item}.                    '</span></td><td class="LC_right_item">'.
                           '</span></td><td class="LC_right_item">'.                    '<input type="text" name="'.$item.'" value="'.
                           '<input type="text" name="'.$item.'" value="'.                    $to{$item}.'" /></td></tr>';
                           $to{$item}.'" /></td></tr>';          $rownum ++;
             $rownum ++;      }
         }      foreach my $type (@mailings) {
     } elsif ($position eq 'bottom') {  
         $css_class = $rownum%2?' class="LC_odd_row"':'';          $css_class = $rownum%2?' class="LC_odd_row"':'';
         $datatable .= '<tr'.$css_class.'>'.          $datatable .= '<tr'.$css_class.'>'.
                       '<td>'.&mt('Extra helpdesk form fields:').'<br />'.                        '<td><span class="LC_nobreak">'.
                       &mt('(e-mail, subject, and description always shown)').                        $titles->{$type}.': </span></td>'.
                       '</td><td class="LC_left_item">';                        '<td class="LC_left_item">'.
         if ((ref($fields) eq 'ARRAY') && (ref($fieldtitles) eq 'HASH') &&                        '<span class="LC_nobreak">';
             (ref($fieldoptions) eq 'HASH') && (ref($possoptions) eq 'HASH')) {          foreach my $item (@contacts) {
             $datatable .= '<table><tr><th>'.&mt('Field').'</th><th>'.&mt('Status').'</th></tr>';              $datatable .= '<label>'.
             foreach my $field (@{$fields}) {                            '<input type="checkbox" name="'.$type.'"'.
                 $datatable .= '<tr><td>'.$fieldtitles->{$field};                            $checked{$type}{$item}.
                 if (($field eq 'screenshot') || ($field eq 'cc')) {                            ' value="'.$item.'" />'.$short_titles->{$item}.
                     $datatable .= ' '.&mt('(logged-in users)');                            '</label>&nbsp;';
                 }          }
                 $datatable .='</td><td>';          $datatable .= '</span><br />'.&mt('Others').':&nbsp;&nbsp;'.
                 my $clickaction;                        '<input type="text" name="'.$type.'_others" '.
                 if ($field eq 'screenshot') {                        'value="'.$otheremails{$type}.'"  />';
                     $clickaction = ' onclick="screenshotSize(this);"';          if ($type eq 'helpdeskmail') {
                 }              $datatable .= '<br />'.&mt('Bcc:').('&nbsp;'x6).
                 if (ref($possoptions->{$field}) eq 'ARRAY') {                            '<input type="text" name="'.$type.'_bcc" '.
                     foreach my $option (@{$possoptions->{$field}}) {                            'value="'.$bccemails{$type}.'"  />';
                         my $checked;  
                         if ($currfield{$field} eq $option) {  
                             $checked = ' checked="checked"';  
                         }  
                         $datatable .= '<span class="LC_nobreak"><label>'.  
                                       '<input type="radio" name="helpform_'.$field.'" '.  
                                       'value="'.$option.'"'.$checked.$clickaction.' />'.$fieldoptions->{$option}.  
                                       '</label></span>'.('&nbsp;'x2);  
                     }  
                 }  
                 if ($field eq 'screenshot') {  
                     my $display;  
                     if ($currfield{$field} eq 'no') {  
                         $display = ' style="display:none"';  
                     }  
                     $datatable .= '</td></tr><tr id="help_screenshotsize"'.$display.'>'.  
                                   '<td>'.&mt('Maximum size for upload (MB)').'</td><td>'.  
                                   '<input type="text" size="5" name="helpform_maxsize" value="'.$maxsize.'" />';  
                 }  
                 $datatable .= '</td></tr>';  
             }  
             $datatable .= '</table>';  
         }          }
         $datatable .= '</td></tr>'."\n";          $datatable .= '</td></tr>'."\n";
         $rownum ++;          $rownum ++;
     }      }
     unless ($position eq 'top') {      my %choices;
         foreach my $type (@mailings) {      $choices{'reporterrors'} = &mt('E-mail error reports to [_1]',
             $css_class = $rownum%2?' class="LC_odd_row"':'';                                     &Apache::loncommon::modal_link('http://loncapa.org/core.html',
             $datatable .= '<tr'.$css_class.'>'.                                     &mt('LON-CAPA core group - MSU'),600,500));
                           '<td><span class="LC_nobreak">'.      $choices{'reportupdates'} = &mt('E-mail record of completed LON-CAPA updates to [_1]',
                           $titles->{$type}.': </span></td>'.                                      &Apache::loncommon::modal_link('http://loncapa.org/core.html',
                           '<td class="LC_left_item">';                                      &mt('LON-CAPA core group - MSU'),600,500));
             if (($type eq 'helpdeskmail') || ($type eq 'otherdomsmail')) {      my @toggles = ('reporterrors','reportupdates');
                 $datatable .= '<fieldset><legend>'.&mt('E-mail recipient(s)').'</legend>';      my %defaultchecked = ('reporterrors'  => 'on',
             }                            'reportupdates' => 'on');
             $datatable .= '<span class="LC_nobreak">';      (my $reports,$rownum) = &radiobutton_prefs($settings,\@toggles,\%defaultchecked,
             foreach my $item (@contacts) {                                                 \%choices,$rownum);
                 $datatable .= '<label>'.      $datatable .= $reports;
                               '<input type="checkbox" name="'.$type.'"'.  
                               $checked{$type}{$item}.  
                               ' value="'.$item.'" />'.$short_titles->{$item}.  
                               '</label>&nbsp;';  
             }  
             $datatable .= '</span><br />'.&mt('Others').':&nbsp;&nbsp;'.  
                           '<input type="text" name="'.$type.'_others" '.  
                           'value="'.$otheremails{$type}.'"  />';  
             my %locchecked;  
             if (($type eq 'helpdeskmail') || ($type eq 'otherdomsmail')) {  
                 foreach my $loc ('s','b') {  
                     if ($includeloc{$type} eq $loc) {  
                         $locchecked{$loc} = ' checked="checked"';  
                         last;  
                     }  
                 }  
                 $datatable .= '<br />'.&mt('Bcc:').('&nbsp;'x6).  
                               '<input type="text" name="'.$type.'_bcc" '.  
                               'value="'.$bccemails{$type}.'"  /></fieldset>'.  
                               '<fieldset><legend>'.&mt('Optional added text').'</legend>'.  
                               &mt('Text automatically added to e-mail:').' '.  
                               '<input type="text" name="'.$type.'_includestr" value="'.$includestr{$type}.'" /><br />'.  
                               '<span class="LC_nobreak">'.&mt('Location:').'&nbsp;'.  
                               '<label><input type="radio" name="'.$type.'_includeloc" value="s"'.$locchecked{'s'}.' />'.&mt('in subject').'</label>'.  
                               ('&nbsp;'x2).  
                               '<label><input type="radio" name="'.$type.'_includeloc" value="b"'.$locchecked{'b'}.' />'.&mt('in body').'</label>'.  
                               '</span></fieldset>';  
             }  
             $datatable .= '</td></tr>'."\n";  
             $rownum ++;  
         }  
     }  
     if ($position eq 'middle') {  
         my %choices;  
         $choices{'reporterrors'} = &mt('E-mail error reports to [_1]',  
                                        &Apache::loncommon::modal_link('http://loncapa.org/core.html',  
                                        &mt('LON-CAPA core group - MSU'),600,500));  
         $choices{'reportupdates'} = &mt('E-mail record of completed LON-CAPA updates to [_1]',  
                                         &Apache::loncommon::modal_link('http://loncapa.org/core.html',  
                                         &mt('LON-CAPA core group - MSU'),600,500));  
         my @toggles = ('reporterrors','reportupdates');  
         my %defaultchecked = ('reporterrors'  => 'on',  
                               'reportupdates' => 'on');  
         (my $reports,$rownum) = &radiobutton_prefs($settings,\@toggles,\%defaultchecked,  
                                                    \%choices,$rownum);  
         $datatable .= $reports;  
     } elsif ($position eq 'bottom') {  
         my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom);  
         my (@posstypes,%usertypeshash);  
         if (ref($types) eq 'ARRAY') {  
             @posstypes = @{$types};  
         }  
         if (@posstypes) {  
             if (ref($usertypes) eq 'HASH') {  
                 %usertypeshash = %{$usertypes};  
             }  
             my @overridden;  
             my $numinrow = 4;  
             if (ref($settings) eq 'HASH') {  
                 if (ref($settings->{'overrides'}) eq 'HASH') {  
                     foreach my $key (sort(keys(%{$settings->{'overrides'}}))) {  
                         if (ref($settings->{'overrides'}{$key}) eq 'HASH') {  
                             push(@overridden,$key);  
                             foreach my $item (@contacts) {  
                                 if ($settings->{'overrides'}{$key}{$item}) {  
                                     $checked{'override_'.$key}{$item} = ' checked="checked" ';  
                                 }  
                             }  
                             $otheremails{'override_'.$key} = $settings->{'overrides'}{$key}{'others'};  
                             $bccemails{'override_'.$key} = $settings->{'overrides'}{$key}{'bcc'};  
                             $includeloc{'override_'.$key} = '';  
                             $includestr{'override_'.$key} = '';  
                             if ($settings->{'overrides'}{$key}{'include'} ne '') {  
                                 ($includeloc{'override_'.$key},$includestr{'override_'.$key}) =  
                                     split(/:/,$settings->{'overrides'}{$key}{'include'},2);  
                                 $includestr{'override_'.$key} = &unescape($includestr{'override_'.$key});  
                             }  
                         }  
                     }  
                 }  
             }  
             my $customclass = 'LC_helpdesk_override';  
             my $optionsprefix = 'LC_options_helpdesk_';  
   
             my $onclicktypes = "toggleHelpdeskRow(this.form,'overrides','$customclass','$optionsprefix');";  
   
             $datatable .= &insttypes_row($settings,$types,$usertypes,$dom,  
                                          $numinrow,$othertitle,'overrides',  
                                          \$rownum,$onclicktypes,$customclass);  
             $rownum ++;  
             $usertypeshash{'default'} = $othertitle;  
             foreach my $status (@posstypes) {  
                 my $css_class;  
                 if ($rownum%2) {  
                     $css_class = 'LC_odd_row ';  
                 }  
                 $css_class .= $customclass;  
                 my $rowid = $optionsprefix.$status;  
                 my $hidden = 1;  
                 my $currstyle = 'display:none';  
                 if (grep(/^\Q$status\E$/,@overridden)) {  
                     $currstyle = 'display:table-row';  
                     $hidden = 0;  
                 }  
                 my $key = 'override_'.$status;  
                 $datatable .= &overridden_helpdesk($checked{$key},$otheremails{$key},$bccemails{$key},  
                                                   $includeloc{$key},$includestr{$key},$status,$rowid,  
                                                   $usertypeshash{$status},$css_class,$currstyle,  
                                                   \@contacts,$short_titles);  
                 unless ($hidden) {  
                     $rownum ++;  
                 }  
             }  
         }  
     }  
     $$rowtotal += $rownum;      $$rowtotal += $rownum;
     return $datatable;      return $datatable;
 }  }
   
 sub overridden_helpdesk {  
     my ($checked,$otheremails,$bccemails,$includeloc,$includestr,$type,$rowid,  
         $typetitle,$css_class,$rowstyle,$contacts,$short_titles) = @_;  
     my $class = 'LC_left_item';  
     if ($css_class) {  
         $css_class = ' class="'.$css_class.'"';  
     }  
     if ($rowid) {  
         $rowid = ' id="'.$rowid.'"';  
     }  
     if ($rowstyle) {  
         $rowstyle = ' style="'.$rowstyle.'"';  
     }  
     my ($output,$description);  
     $description = &mt('Helpdesk requests from: [_1] in this domain (overrides default)',"<b>$typetitle</b>");  
     $output = '<tr'.$css_class.$rowid.$rowstyle.'>'.  
               "<td>$description</td>\n".  
               '<td class="'.$class.'" colspan="2">'.  
               '<fieldset><legend>'.&mt('E-mail recipient(s)').'</legend>'.  
               '<span class="LC_nobreak">';  
     if (ref($contacts) eq 'ARRAY') {  
         foreach my $item (@{$contacts}) {  
             my $check;  
             if (ref($checked) eq 'HASH') {  
                $check = $checked->{$item};  
             }  
             my $title;  
             if (ref($short_titles) eq 'HASH') {  
                 $title = $short_titles->{$item};  
             }  
             $output .= '<label>'.  
                        '<input type="checkbox" name="override_'.$type.'"'.$check.  
                        ' value="'.$item.'" />'.$title.'</label>&nbsp;';  
         }  
     }  
     $output .= '</span><br />'.&mt('Others').':&nbsp;&nbsp;'.  
                '<input type="text" name="override_'.$type.'_others" '.  
                'value="'.$otheremails.'"  />';  
     my %locchecked;  
     foreach my $loc ('s','b') {  
         if ($includeloc eq $loc) {  
             $locchecked{$loc} = ' checked="checked"';  
             last;  
         }  
     }  
     $output .= '<br />'.&mt('Bcc:').('&nbsp;'x6).  
                '<input type="text" name="override_'.$type.'_bcc" '.  
                'value="'.$bccemails.'"  /></fieldset>'.  
                '<fieldset><legend>'.&mt('Optional added text').'</legend>'.  
                &mt('Text automatically added to e-mail:').' '.  
                '<input type="text" name="override_'.$type.'_includestr" value="'.$includestr.'" /><br />'.  
                '<span class="LC_nobreak">'.&mt('Location:').'&nbsp;'.  
                '<label><input type="radio" name="override_'.$type.'_includeloc" value="s"'.$locchecked{'s'}.' />'.&mt('in subject').'</label>'.  
                ('&nbsp;'x2).  
                '<label><input type="radio" name="override_'.$type.'_includeloc" value="b"'.$locchecked{'b'}.' />'.&mt('in body').'</label>'.  
                '</span></fieldset>'.  
                '</td></tr>'."\n";  
     return $output;  
 }  
   
 sub contacts_javascript {  
     return <<"ENDSCRIPT";  
   
 <script type="text/javascript">  
 // <![CDATA[  
   
 function screenshotSize(field) {  
     if (document.getElementById('help_screenshotsize')) {  
         if (field.value == 'no') {  
             document.getElementById('help_screenshotsize').style.display="none";  
         } else {  
             document.getElementById('help_screenshotsize').style.display="";  
         }  
     }  
     return;  
 }  
   
 function toggleHelpdeskRow(form,checkbox,target,prefix,docount) {  
     if (form.elements[checkbox].length != undefined) {  
         var count = 0;  
         if (docount) {  
             for (var i=0; i<form.elements[checkbox].length; i++) {  
                 if (form.elements[checkbox][i].checked) {  
                     count ++;  
                 }  
             }  
         }  
         for (var i=0; i<form.elements[checkbox].length; i++) {  
             var type = form.elements[checkbox][i].value;  
             if (document.getElementById(prefix+type)) {  
                 if (form.elements[checkbox][i].checked) {  
                     document.getElementById(prefix+type).style.display = 'table-row';  
                     if (count % 2 == 1) {  
                         document.getElementById(prefix+type).className = target+' LC_odd_row';  
                     } else {  
                         document.getElementById(prefix+type).className = target;  
                     }  
                     count ++;  
                 } else {  
                     document.getElementById(prefix+type).style.display = 'none';  
                 }  
             }  
         }  
     }  
     return;  
 }  
   
 // ]]>  
 </script>  
   
 ENDSCRIPT  
 }  
   
 sub print_helpsettings {  sub print_helpsettings {
     my ($position,$dom,$settings,$rowtotal) = @_;      my ($dom,$confname,$settings,$rowtotal) = @_;
     my $confname = $dom.'-domainconfig';  
     my $formname = 'display';  
     my ($datatable,$itemcount);      my ($datatable,$itemcount);
     if ($position eq 'top') {      $itemcount = 1;
         $itemcount = 1;      my (%choices,%defaultchecked,@toggles);
         my (%choices,%defaultchecked,@toggles);      $choices{'submitbugs'} = &mt('Display link to: [_1]?',
         $choices{'submitbugs'} = &mt('Display link to: [_1]?',                                   &Apache::loncommon::modal_link('http://bugs.loncapa.org',
                                      &Apache::loncommon::modal_link('http://bugs.loncapa.org',                                   &mt('LON-CAPA bug tracker'),600,500));
                                      &mt('LON-CAPA bug tracker'),600,500));      %defaultchecked = ('submitbugs' => 'on');
         %defaultchecked = ('submitbugs' => 'on');      @toggles = ('submitbugs',);
         @toggles = ('submitbugs');  
         ($datatable,$itemcount) = &radiobutton_prefs($settings,\@toggles,\%defaultchecked,  
                                                      \%choices,$itemcount);  
         $$rowtotal ++;  
     } else {  
         my $css_class;  
         my %existing=&Apache::lonnet::dump('roles',$dom,$confname,'rolesdef_');  
         my (%customroles,%ordered,%current);  
         if (ref($settings) eq 'HASH') {  
             if (ref($settings->{'adhoc'}) eq 'HASH') {  
                 %current = %{$settings->{'adhoc'}};  
             }  
         }  
         my $count = 0;  
         foreach my $key (sort(keys(%existing))) {  
             if ($key=~/^rolesdef\_(\w+)$/) {  
                 my $rolename = $1;  
                 my (%privs,$order);  
                 ($privs{'system'},$privs{'domain'},$privs{'course'}) = split(/\_/,$existing{$key});  
                 $customroles{$rolename} = \%privs;  
                 if (ref($current{$rolename}) eq 'HASH') {  
                     $order = $current{$rolename}{'order'};  
                 }  
                 if ($order eq '') {  
                     $order = $count;  
                 }  
                 $ordered{$order} = $rolename;  
                 $count++;  
             }  
         }  
         my $maxnum = scalar(keys(%ordered));  
         my @roles_by_num = ();  
         foreach my $item (sort {$a <=> $b } (keys(%ordered))) {  
             push(@roles_by_num,$item);  
         }  
         my $context = 'domprefs';  
         my $crstype = 'Course';  
         my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom);  
         my @accesstypes = ('all','dh','da','none');  
         my ($numstatustypes,@jsarray);  
         if (ref($types) eq 'ARRAY') {  
             if (@{$types} > 0) {  
                 $numstatustypes = scalar(@{$types});  
                 push(@accesstypes,'status');  
                 @jsarray = ('bystatus');  
             }  
         }  
         my %domhelpdesk = &Apache::lonnet::get_active_domroles($dom,['dh','da']);  
         if (keys(%domhelpdesk)) {  
             push(@accesstypes,('inc','exc'));  
             push(@jsarray,('notinc','notexc'));  
         }  
         my $hiddenstr = join("','",@jsarray);  
         $datatable .= &helpsettings_javascript(\@roles_by_num,$maxnum,$hiddenstr,$formname);  
         my $context = 'domprefs';  
         my $crstype = 'Course';  
         my $prefix = 'helproles_';  
         my $add_class = 'LC_hidden';  
         foreach my $num (@roles_by_num) {  
             my $role = $ordered{$num};  
             my ($desc,$access,@statuses);  
             if (ref($current{$role}) eq 'HASH') {  
                 $desc = $current{$role}{'desc'};  
                 $access = $current{$role}{'access'};  
                 if (ref($current{$role}{'insttypes'}) eq 'ARRAY') {  
                     @statuses = @{$current{$role}{'insttypes'}};  
                 }  
             }  
             if ($desc eq '') {  
                 $desc = $role;  
             }  
             my $identifier = 'custhelp'.$num;  
             my %full=();  
             my %levels= (  
                          course => {},  
                          domain => {},  
                          system => {},  
                         );  
             my %levelscurrent=(  
                                course => {},  
                                domain => {},  
                                system => {},  
                               );  
             &Apache::lonuserutils::custom_role_privs($customroles{$role},\%full,\%levels,\%levelscurrent);  
             my @templateroles = &Apache::lonuserutils::custom_template_roles($context,$crstype);  
             $css_class = $itemcount%2?' class="LC_odd_row"':'';  
             my $chgstr = ' onchange="javascript:reorderHelpRoles(this.form,'."'helproles_".$num."_pos'".');"';  
             $datatable .= '<tr '.$css_class.'><td valign="top"><b>'.$role.'</b><br />'.  
                           '<select name="helproles_'.$num.'_pos"'.$chgstr.'>';  
             for (my $k=0; $k<=$maxnum; $k++) {  
                 my $vpos = $k+1;  
                 my $selstr;  
                 if ($k == $num) {  
                     $selstr = ' selected="selected" ';  
                 }  
                 $datatable .= '<option value="'.$k.'"'.$selstr.'>'.$vpos.'</option>';  
             }  
             $datatable .= '</select>'.('&nbsp;'x2).  
                           '<input type="hidden" name="helproles_'.$num.'" value="'.$role.'" />'.  
                           '</td>'.  
                           '<td><fieldset><legend>'.&mt('Role name').'</legend>'.  
                           &mt('Name shown to users:').  
                           '<input type="text" name="helproles_'.$num.'_desc" value="'.$desc.'" />'.  
                           '</fieldset>'.  
                           &helpdeskroles_access($dom,$prefix,$num,$add_class,$current{$role},\@accesstypes,  
                                                 $othertitle,$usertypes,$types,\%domhelpdesk).  
                           '<fieldset>'.  
                           '<legend>'.&mt('Role privileges').&adhocbutton($prefix,$num,'privs','show').'</legend>'.  
                           &Apache::lonuserutils::custom_role_table($crstype,\%full,\%levels,  
                                                                    \%levelscurrent,$identifier,  
                                                                    'LC_hidden',$prefix.$num.'_privs').  
                           '</fieldset></td>';  
             $itemcount ++;  
         }  
         $css_class = $itemcount%2?' class="LC_odd_row"':'';  
         my $newcust = 'custhelp'.$count;  
         my (%privs,%levelscurrent);  
         my %full=();  
         my %levels= (  
                      course => {},  
                      domain => {},  
                      system => {},  
                     );  
         &Apache::lonuserutils::custom_role_privs(\%privs,\%full,\%levels,\%levelscurrent);  
         my @templateroles = &Apache::lonuserutils::custom_template_roles($context,$crstype);  
         my $chgstr = ' onchange="javascript:reorderHelpRoles(this.form,'."'helproles_".$count."_pos'".');"';  
         $datatable .= '<tr '.$css_class.'><td valign="top"><span class="LC_nobreak"><label>'.  
                       '<input type="hidden" name="helproles_maxnum" value="'.$maxnum.'" />'."\n".  
                       '<select name="helproles_'.$count.'_pos"'.$chgstr.'>';  
         for (my $k=0; $k<$maxnum+1; $k++) {  
             my $vpos = $k+1;  
             my $selstr;  
             if ($k == $maxnum) {  
                 $selstr = ' selected="selected" ';  
             }  
             $datatable .= '<option value="'.$k.'"'.$selstr.'>'.$vpos.'</option>';  
         }  
         $datatable .= '</select>&nbsp;'."\n".  
                       '<input type="checkbox" name="newcusthelp" value="'.$count.'" />'. &mt('Add').  
                       '</label></span></td>'.  
                       '<td><fieldset><legend>'.&mt('Role name').'</legend>'.  
                       '<span class="LC_nobreak">'.  
                       &mt('Internal name:').  
                       '<input type="text" size="10" name="custhelpname'.$count.'" value="" />'.  
                       '</span>'.('&nbsp;'x4).  
                       '<span class="LC_nobreak">'.  
                       &mt('Name shown to users:').  
                       '<input type="text" size="20" name="helproles_'.$count.'_desc" value="" />'.  
                       '</span></fieldset>'.  
                        &helpdeskroles_access($dom,$prefix,$count,'',undef,\@accesstypes,$othertitle,  
                                              $usertypes,$types,\%domhelpdesk).  
                       '<fieldset><legend>'.&mt('Role privileges').'</legend>'.  
                       &Apache::lonuserutils::custom_role_header($context,$crstype,  
                                                                 \@templateroles,$newcust).  
                       &Apache::lonuserutils::custom_role_table('Course',\%full,\%levels,  
                                                                \%levelscurrent,$newcust).  
                       '</fieldset>'.  
                       &helpsettings_javascript(\@roles_by_num,$maxnum,$hiddenstr,$formname).  
                       '</td></tr>';  
         $count ++;  
         $$rowtotal += $count;  
     }  
     return $datatable;  
 }  
   
 sub adhocbutton {  
     my ($prefix,$num,$field,$visibility) = @_;  
     my %lt = &Apache::lonlocal::texthash(  
                                           show => 'Show details',  
                                           hide => 'Hide details',  
                                         );  
     return '<span style="text-decoration:line-through; font-weight: normal;">'.('&nbsp;'x10).  
            '</span>'.('&nbsp;'x2).'<input type="button" id="'.$prefix.$num.'_'.$field.'_vis"'.  
            ' value="'.$lt{$visibility}.'" style="height:20px;" '.  
            'onclick="toggleHelpdeskItem('."'$num','$field'".');" />'.('&nbsp;'x2);  
 }  
   
 sub helpsettings_javascript {  
     my ($roles_by_num,$total,$hiddenstr,$formname) = @_;  
     return unless(ref($roles_by_num) eq 'ARRAY');  
     my %html_js_lt = &Apache::lonlocal::texthash(  
                                           show => 'Show details',  
                                           hide => 'Hide details',  
                                         );  
     &html_escape(\%html_js_lt);  
     my $jstext = '    var helproles = Array('."'".join("','",@{$roles_by_num})."'".');'."\n";  
     return <<"ENDSCRIPT";  
 <script type="text/javascript">  
 // <![CDATA[  
   
 function reorderHelpRoles(form,item) {  
     var changedVal;  
 $jstext  
     var newpos = 'helproles_${total}_pos';  
     var maxh = 1 + $total;  
     var current = new Array();  
     var newitemVal = form.elements[newpos].options[form.elements[newpos].selectedIndex].value;  
     if (item == newpos) {  
         changedVal = newitemVal;  
     } else {  
         changedVal = form.elements[item].options[form.elements[item].selectedIndex].value;  
         current[newitemVal] = newpos;  
     }  
     for (var i=0; i<helproles.length; i++) {  
         var elementName = 'helproles_'+helproles[i]+'_pos';  
         if (elementName != item) {  
             if (form.elements[elementName]) {  
                 var currVal = form.elements[elementName].options[form.elements[elementName].selectedIndex].value;  
                 current[currVal] = elementName;  
             }  
         }  
     }  
     var oldVal;  
     for (var j=0; j<maxh; j++) {  
         if (current[j] == undefined) {  
             oldVal = j;  
         }  
     }  
     if (oldVal < changedVal) {  
         for (var k=oldVal+1; k<=changedVal ; k++) {  
            var elementName = current[k];  
            form.elements[elementName].selectedIndex = form.elements[elementName].selectedIndex - 1;  
         }  
     } else {  
         for (var k=changedVal; k<oldVal; k++) {  
             var elementName = current[k];  
             form.elements[elementName].selectedIndex = form.elements[elementName].selectedIndex + 1;  
         }  
     }  
     return;  
 }  
   
 function helpdeskAccess(num) {      ($datatable,$itemcount) = &radiobutton_prefs($settings,\@toggles,\%defaultchecked,
     var curraccess = null;                                                   \%choices,$itemcount);
     if (document.$formname.elements['helproles_'+num+'_access'].length) {      return $datatable;
         for (var i=0; i<document.$formname.elements['helproles_'+num+'_access'].length; i++) {  
             if (document.$formname.elements['helproles_'+num+'_access'][i].checked) {  
                 curraccess = document.$formname.elements['helproles_'+num+'_access'][i].value;  
             }  
         }  
     }  
     var shown = Array();  
     var hidden = Array();  
     if (curraccess == 'none') {  
         hidden = Array('$hiddenstr');  
     } else {  
         if (curraccess == 'status') {  
             shown = Array('bystatus');  
             hidden = Array('notinc','notexc');  
         } else {  
             if (curraccess == 'exc') {  
                 shown = Array('notexc');  
                 hidden = Array('notinc','bystatus');  
             }  
             if (curraccess == 'inc') {  
                 shown = Array('notinc');  
                 hidden = Array('notexc','bystatus');  
             }  
             if ((curraccess == 'all') || (curraccess == 'dh') || (curraccess == 'da')) {  
                 hidden = Array('notinc','notexc','bystatus');  
             }  
         }  
     }  
     if (hidden.length > 0) {  
         for (var i=0; i<hidden.length; i++) {  
             if (document.getElementById('helproles_'+num+'_'+hidden[i])) {  
                 document.getElementById('helproles_'+num+'_'+hidden[i]).style.display = 'none';  
             }  
         }  
     }  
     if (shown.length > 0) {  
         for (var i=0; i<shown.length; i++) {  
             if (document.getElementById('helproles_'+num+'_'+shown[i])) {  
                 if (shown[i] == 'privs') {  
                     document.getElementById('helproles_'+num+'_'+shown[i]).style.display = 'block';  
                 } else {  
                     document.getElementById('helproles_'+num+'_'+shown[i]).style.display = 'inline-block';  
                 }  
             }  
         }  
     }  
     return;  
 }  
   
 function toggleHelpdeskItem(num,field) {  
     if (document.getElementById('helproles_'+num+'_'+field)) {  
         if (document.getElementById('helproles_'+num+'_'+field).className.match(/(?:^|\\s)LC_hidden(?!\\S)/)) {  
             document.getElementById('helproles_'+num+'_'+field).className =  
                 document.getElementById('helproles_'+num+'_'+field).className.replace(/(?:^|\\s)LC_hidden(?!\\S)/g ,'');  
             if (document.getElementById('helproles_'+num+'_'+field+'_vis')) {  
                 document.getElementById('helproles_'+num+'_'+field+'_vis').value = '$html_js_lt{hide}';  
             }  
         } else {  
             document.getElementById('helproles_'+num+'_'+field).className += ' LC_hidden';  
             if (document.getElementById('helproles_'+num+'_'+field+'_vis')) {  
                 document.getElementById('helproles_'+num+'_'+field+'_vis').value = '$html_js_lt{show}';  
             }  
         }  
     }  
     return;  
 }  
   
 // ]]>  
 </script>  
   
 ENDSCRIPT  
 }  
   
 sub helpdeskroles_access {  
     my ($dom,$prefix,$num,$add_class,$current,$accesstypes,$othertitle,  
         $usertypes,$types,$domhelpdesk) = @_;  
     return unless ((ref($accesstypes) eq 'ARRAY') && (ref($domhelpdesk) eq 'HASH'));  
     my %lt = &Apache::lonlocal::texthash(  
                     'rou'    => 'Role usage',  
                     'whi'    => 'Which helpdesk personnel may use this role?',  
                     'all'    => 'All with domain helpdesk or helpdesk assistant role',  
                     'dh'     => 'All with domain helpdesk role',  
                     'da'     => 'All with domain helpdesk assistant role',  
                     'none'   => 'None',  
                     'status' => 'Determined based on institutional status',  
                     'inc'    => 'Include all, but exclude specific personnel',  
                     'exc'    => 'Exclude all, but include specific personnel',  
                   );  
     my %usecheck = (  
                      all => ' checked="checked"',  
                    );  
     my %displaydiv = (  
                       status => 'none',  
                       inc    => 'none',  
                       exc    => 'none',  
                       priv   => 'block',  
                      );  
     my $output;  
     if (ref($current) eq 'HASH') {  
         if (($current->{'access'} ne '') && ($current->{'access'} ne 'all')) {  
             if (grep(/^\Q$current->{access}\E$/,@{$accesstypes})) {  
                 $usecheck{$current->{access}} = $usecheck{'all'};  
                 delete($usecheck{'all'});  
                 if ($current->{access} =~ /^(status|inc|exc)$/) {  
                     my $access = $1;  
                     $displaydiv{$access} = 'inline';  
                 } elsif ($current->{access} eq 'none') {  
                     $displaydiv{'priv'} = 'none';  
                 }  
             }  
         }  
     }  
     $output = '<fieldset id="'.$prefix.$num.'_usage"><legend>'.$lt{'rou'}.'</legend>'.  
               '<p>'.$lt{'whi'}.'</p>';  
     foreach my $access (@{$accesstypes}) {  
         $output .= '<p><label><input type="radio" name="'.$prefix.$num.'_access" value="'.$access.'" '.$usecheck{$access}.  
                    ' onclick="helpdeskAccess('."'$num'".');" />'.  
                    $lt{$access}.'</label>';  
         if ($access eq 'status') {  
             $output .= '<div id="'.$prefix.$num.'_bystatus" style="display:'.$displaydiv{$access}.'">'.  
                        &Apache::lonuserutils::adhoc_status_types($dom,$prefix,$num,$current->{$access},  
                                                                  $othertitle,$usertypes,$types).  
                        '</div>';  
         } elsif (($access eq 'inc') && (keys(%{$domhelpdesk}) > 0)) {  
             $output .= '<div id="'.$prefix.$num.'_notinc" style="display:'.$displaydiv{$access}.'">'.  
                        &Apache::lonuserutils::adhoc_staff($access,$prefix,$num,$current->{$access},$domhelpdesk).  
                        '</div>';  
         } elsif (($access eq 'exc') && (keys(%{$domhelpdesk}) > 0)) {  
             $output .= '<div id="'.$prefix.$num.'_notexc" style="display:'.$displaydiv{$access}.'">'.  
                        &Apache::lonuserutils::adhoc_staff($access,$prefix,$num,$current->{$access},$domhelpdesk).  
                        '</div>';  
         }  
         $output .= '</p>';  
     }  
     $output .= '</fieldset>';  
     return $output;  
 }  }
   
 sub radiobutton_prefs {  sub radiobutton_prefs {
Line 3780  sub radiobutton_prefs { Line 2965  sub radiobutton_prefs {
         } else {          } else {
             $datatable .= '<td class="LC_right_item">';              $datatable .= '<td class="LC_right_item">';
         }          }
         $datatable .=          $datatable .= 
             '<span class="LC_nobreak">'.              '<span class="LC_nobreak">'.
             '<label><input type="radio" name="'.              '<label><input type="radio" name="'.
             $item.'" '.$checkedon{$item}.' value="1"'.$onclick.' />'.&mt('Yes').              $item.'" '.$checkedon{$item}.' value="1"'.$onclick.' />'.&mt('Yes').
Line 3874  sub print_ltitools { Line 3059  sub print_ltitools {
             if (ref($settings->{$item}->{'display'}) eq 'HASH') {              if (ref($settings->{$item}->{'display'}) eq 'HASH') {
                 if ($settings->{$item}->{'display'}->{'target'} eq 'window') {                  if ($settings->{$item}->{'display'}->{'target'} eq 'window') {
                     $currdisp{'window'} = ' checked="checked"';                      $currdisp{'window'} = ' checked="checked"';
                 } elsif ($settings->{$item}->{'display'}->{'target'} eq 'tab') {  
                     $currdisp{'tab'} = ' checked="checked"';  
                 } else {                  } else {
                     $currdisp{'iframe'} = ' checked="checked"';                      $currdisp{'iframe'} = ' checked="checked"';
                 }                  }
Line 3885  sub print_ltitools { Line 3068  sub print_ltitools {
                 if ($settings->{$item}->{'display'}->{'height'} =~ /^(\d+)$/) {                  if ($settings->{$item}->{'display'}->{'height'} =~ /^(\d+)$/) {
                      $currdisp{'height'} = $1;                       $currdisp{'height'} = $1;
                 }                  }
                 $currdisp{'linktext'} = $settings->{$item}->{'display'}->{'linktext'};  
                 $currdisp{'explanation'} = $settings->{$item}->{'display'}->{'explanation'};  
             } else {              } else {
                 $currdisp{'iframe'} = ' checked="checked"';                  $currdisp{'iframe'} = ' checked="checked"';
             }              }
             foreach my $disp ('iframe','tab','window') {              foreach my $disp ('iframe','window') {
                 $datatable .= '<label><input type="radio" name="ltitools_target_'.$i.'" value="'.$disp.'"'.$currdisp{$disp}.' />'.                  $datatable .= '<label><input type="radio" name="ltitools_target_'.$i.'" value="'.$disp.'"'.$currdisp{$disp}.' />'.
                               $lt{$disp}.'</label>'.('&nbsp;'x2);                                $lt{$disp}.'</label>'.('&nbsp;'x2);
             }              }
Line 3900  sub print_ltitools { Line 3081  sub print_ltitools {
                               '<input type="text" name="ltitools_'.$dimen.'_'.$i.'" size="5" value="'.$currdisp{$dimen}.'" /></label>'.                                '<input type="text" name="ltitools_'.$dimen.'_'.$i.'" size="5" value="'.$currdisp{$dimen}.'" /></label>'.
                               ('&nbsp;'x2);                                ('&nbsp;'x2);
             }              }
             $datatable .= '<br />'.  
                           '<div class="LC_left_float">'.$lt{'linktext'}.'<br />'.  
                           '<input type="text" name="ltitools_linktext_'.$i.'" size="25" value="'.$currdisp{'linktext'}.'" /></label></div>'.  
                           '<div class="LC_left_float">'.$lt{'explanation'}.'<br />'.  
                           '<textarea name="ltitools_explanation_'.$i.'" rows="5" cols="40">'.$currdisp{'explanation'}.  
                           '</textarea></div><div style=""></div><br />';  
             $datatable .= '<br />';              $datatable .= '<br />';
             foreach my $extra ('passback','roster') {              foreach my $extra ('passback','roster') {
                 my $checkedon = '';                  my $checkedon = '';
Line 3963  sub print_ltitools { Line 3138  sub print_ltitools {
                 if (!$rolemaps{$role}) {                  if (!$rolemaps{$role}) {
                     $selectnone = ' selected="selected"';                      $selectnone = ' selected="selected"';
                 }                  }
                 $datatable .= '<td align="center">'.                  $datatable .= '<td 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 3979  sub print_ltitools { Line 3154  sub print_ltitools {
                 }                  }
                 $datatable .= '</select></td>';                  $datatable .= '</select></td>';
             }              }
             $datatable .= '</tr></table></fieldset>';              $datatable .= '</tr></table></fieldset>'.
             my %courseconfig;  
             if (ref($settings->{$item}) eq 'HASH') {  
                 if (ref($settings->{$item}->{'crsconf'}) eq 'HASH') {  
                     %courseconfig = %{$settings->{$item}->{'crsconf'}};  
                 }  
             }  
             $datatable .= '<fieldset><legend>'.&mt('Configurable in course').'</legend><span class="LC_nobreak">';  
             foreach my $item ('label','title','target','linktext','explanation') {  
                 my $checked;  
                 if ($courseconfig{$item}) {  
                     $checked = ' checked="checked"';  
                 }  
                 $datatable .= '<label>'.  
                        '<input type="checkbox" name="ltitools_courseconfig_'.$i.'" value="'.$item.'"'.$checked.' />'.  
                        $lt{'crs'.$item}.'</label>'.('&nbsp;' x2)."\n";  
             }  
             $datatable .= '</span></fieldset>'.  
                           '<fieldset><legend>'.&mt('Custom items sent on launch').'</legend>'.                            '<fieldset><legend>'.&mt('Custom items sent on launch').'</legend>'.
                           '<table><tr><th>'.&mt('Action').'</th><th>'.&mt('Name').'</th><th>'.&mt('Value').'</th></tr>';                            '<table><tr><th>'.&mt('Action').'</th><th>'.&mt('Name').'</th><th>'.&mt('Value').'</th></tr>';
             if (ref($settings->{$item}->{'custom'}) eq 'HASH') {              if (ref($settings->{$item}->{'custom'}) eq 'HASH') {
Line 4055  sub print_ltitools { Line 3213  sub print_ltitools {
                   '<span class="LC_nobreak">'.&mt('Display target:');                    '<span class="LC_nobreak">'.&mt('Display target:');
     my %defaultdisp;      my %defaultdisp;
     $defaultdisp{'iframe'} = ' checked="checked"';      $defaultdisp{'iframe'} = ' checked="checked"';
     foreach my $disp ('iframe','tab','window') {      foreach my $disp ('iframe','window') {
         $datatable .= '<label><input type="radio" name="ltitools_add_target" value="'.$disp.'"'.$defaultdisp{$disp}.' />'.          $datatable .= '<label><input type="radio" name="ltitools_add_target" value="'.$disp.'"'.$defaultdisp{$disp}.' />'.
                       $lt{$disp}.'</label>'.('&nbsp;'x2);                        $lt{$disp}.'</label>'.('&nbsp;'x2);
     }      }
Line 4065  sub print_ltitools { Line 3223  sub print_ltitools {
                       '<input type="text" name="ltitools_add_'.$dimen.'" size="5" /></label>'.                        '<input type="text" name="ltitools_add_'.$dimen.'" size="5" /></label>'.
                       ('&nbsp;'x2);                        ('&nbsp;'x2);
     }      }
     $datatable .= '<br />'.      $datatable .= '<br />';
                   '<div class="LC_left_float">'.$lt{'linktext'}.'<br />'.  
                   '<input type="text" name="ltitools_add_linktext" size="5" /></label></div>'.  
                   '<div class="LC_left_float">'.$lt{'explanation'}.'<br />'.  
                   '<textarea name=ltitools_add_explanation" rows="5" cols="40"></textarea>'.  
                   '</div><div style=""></div><br />';  
     foreach my $extra ('passback','roster') {      foreach my $extra ('passback','roster') {
         $datatable .= $lt{$extra}.'&nbsp;'.          $datatable .= $lt{$extra}.'&nbsp;'.
                       '<label><input type="radio" name="ltitools_add_'.$extra.'" value="1" />'.                        '<label><input type="radio" name="ltitools_add_'.$extra.'" value="1" />'.
Line 4107  sub print_ltitools { Line 3260  sub print_ltitools {
         $datatable .= '</select></td>';          $datatable .= '</select></td>';
     }      }
     $datatable .= '</tr></table></fieldset>'.      $datatable .= '</tr></table></fieldset>'.
                   '<fieldset><legend>'.&mt('Configurable in course').'</legend><span class="LC_nobreak">';  
     foreach my $item ('label','title','target','linktext','explanation') {  
         $datatable .= '<label>'.  
                       '<input type="checkbox" name="ltitools_courseconfig" value="'.$item.'" checked="checked" />'.  
                       $lt{'crs'.$item}.'</label>'.('&nbsp;' x2)."\n";  
     }  
     $datatable .= '</span></fieldset>'.  
                   '<fieldset><legend>'.&mt('Custom items sent on launch').'</legend>'.                    '<fieldset><legend>'.&mt('Custom items sent on launch').'</legend>'.
                   '<table><tr><th>'.&mt('Action').'</th><th>'.&mt('Name').'</th><th>'.&mt('Value').'</th></tr>'.                    '<table><tr><th>'.&mt('Action').'</th><th>'.&mt('Name').'</th><th>'.&mt('Value').'</th></tr>'.
                   '<tr><td><span class="LC_nobreak">'.                    '<tr><td><span class="LC_nobreak">'.
Line 4129  sub print_ltitools { Line 3275  sub print_ltitools {
   
 sub ltitools_names {  sub ltitools_names {
     my %lt = &Apache::lonlocal::texthash(      my %lt = &Apache::lonlocal::texthash(
                                           'title'          => 'Title',                                            'title'     => 'Title',
                                           'version'        => 'Version',                                            'version'   => 'Version',
                                           'msgtype'        => 'Message Type',                                            'msgtype'   => 'Message Type',
                                           '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',
                                           'lastname'       => 'Last Name',                                            'lastname'  => 'Last Name',
                                           'email'          => 'E-mail',                                            'email'     => 'E-mail',
                                           'roles'          => 'Role',                                            'roles'     => 'Role',
                                           'window'         => 'Window',                                            'window'    => 'Window/Tab',
                                           'tab'            => 'Tab',                                            'iframe'    => 'iFrame',
                                           'iframe'         => 'iFrame',                                            'height'    => 'Height',
                                           'height'         => 'Height',                                            'width'     => 'Width',
                                           'width'          => 'Width',                                            'passback'  => 'Tool can return grades:',
                                           'linktext'       => 'Default Link Text',                                            'roster'    => 'Tool can retrieve roster:',
                                           'explanation'    => 'Default Explanation',  
                                           'passback'       => 'Tool can return grades:',  
                                           'roster'         => 'Tool can retrieve roster:',  
                                           'crstarget'      => 'Display target',  
                                           'crslabel'       => 'Course label',  
                                           'crstitle'       => 'Course title',  
                                           'crslinktext'    => 'Link Text',  
                                           'crsexplanation' => 'Explanation',  
                                         );                                          );
   
     return %lt;      return %lt;
 }  }
   
Line 4166  sub print_coursedefaults { Line 3303  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',
         uselcmath            => 'Math preview uses LON-CAPA previewer (javascript) in place of DragMath (Java)',          uselcmath            => 'Math preview uses LON-CAPA previewer (javascript) in place of DragMath (Java)',
         usejsme              => 'Molecule editor uses JSME (HTML5) in place of JME (Java)',          usejsme              => 'Molecule editor uses JSME (HTML5) in place of JME (Java)',
         texengine            => 'Default method to display mathematics',  
         postsubmit           => 'Disable submit button/keypress following student submission',          postsubmit           => 'Disable submit button/keypress following student submission',
         canclone             => "People who may clone a course (besides course's owner and coordinators)",          canclone             => "People who may clone a course (besides course's owner and coordinators)",     
         mysqltables          => 'Lifetime (s) of "Temporary" MySQL tables (student performance data) on homeserver',  
     );      );
     my %staticdefaults = (      my %staticdefaults = (
                            anonsurvey_threshold => 10,                             anonsurvey_threshold => 10,
                            uploadquota          => 500,                             uploadquota          => 500,
                            postsubmit           => 60,                             postsubmit           => 60,
                            mysqltables          => 172800,  
                          );                           );
     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;  
         if (ref($settings) eq 'HASH') {  
             if ($settings->{'texengine'}) {  
                 if ($settings->{'texengine'} =~ /^(MathJax|mimetex|tth)$/) {  
                     $deftex = $settings->{'texengine'};  
                 }  
             }  
         }  
         $css_class = $itemcount%2?' class="LC_odd_row"':'';  
         my $mathdisp = '<tr'.$css_class.'><td style="vertical-align: top">'.  
                        '<span class="LC_nobreak">'.$choices{'texengine'}.  
                        '</span></td><td class="LC_right_item">'.  
                        '<select name="texengine">'."\n";  
         my %texoptions = (  
                             MathJax  => 'MathJax',  
                             mimetex  => &mt('Convert to Images'),  
                             tth      => &mt('TeX to HTML'),  
                          );  
         foreach my $renderer ('MathJax','mimetex','tth') {  
             my $selected = '';  
             if ($renderer eq $deftex) {  
                 $selected = ' selected="selected"';  
             }  
             $mathdisp .= '<option value="'.$renderer.'"'.$selected.'>'.$texoptions{$renderer}.'</option>'."\n";  
         }  
         $mathdisp .= '</select></td></tr>'."\n";  
         $itemcount ++;  
         ($datatable,$itemcount) = &radiobutton_prefs($settings,\@toggles,\%defaultchecked,          ($datatable,$itemcount) = &radiobutton_prefs($settings,\@toggles,\%defaultchecked,
                                                      \%choices,$itemcount);                                                       \%choices,$itemcount);
         $datatable = $mathdisp.$datatable;  
         $css_class = $itemcount%2?' class="LC_odd_row"':'';          $css_class = $itemcount%2?' class="LC_odd_row"':'';
         $datatable .=          $datatable .=
             '<tr'.$css_class.'><td valign="top">'.              '<tr'.$css_class.'><td valign="top">'.
Line 4253  sub print_coursedefaults { Line 3361  sub print_coursedefaults {
                     $currcanclone = $settings->{'canclone'};                      $currcanclone = $settings->{'canclone'};
                 }                  }
             }              }
         }          } 
         foreach my $option (@cloneoptions) {          foreach my $option (@cloneoptions) {
             my ($checked,$additional);              my ($checked,$additional);
             if ($currcanclone eq $option) {              if ($currcanclone eq $option) {
Line 4292  sub print_coursedefaults { Line 3400  sub print_coursedefaults {
         $itemcount ++;          $itemcount ++;
     } else {      } else {
         $css_class = $itemcount%2 ? ' class="LC_odd_row"' : '';          $css_class = $itemcount%2 ? ' class="LC_odd_row"' : '';
         my ($currdefresponder,%defcredits,%curruploadquota,%deftimeout,%currmysql);          my ($currdefresponder,%defcredits,%curruploadquota,%deftimeout);
         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 4322  sub print_coursedefaults { Line 3430  sub print_coursedefaults {
                     foreach my $type (@types) {                      foreach my $type (@types) {
                         if (ref($settings->{'postsubmit'}->{'timeout'}) eq 'HASH') {                          if (ref($settings->{'postsubmit'}->{'timeout'}) eq 'HASH') {
                             if ($settings->{'postsubmit'}->{'timeout'}->{$type} =~ /^\d+$/) {                              if ($settings->{'postsubmit'}->{'timeout'}->{$type} =~ /^\d+$/) {
                                 $deftimeout{$type} = $settings->{'postsubmit'}->{'timeout'}->{$type};                                  $deftimeout{$type} = $settings->{'postsubmit'}->{'timeout'}->{$type}; 
                             } else {                              } else {
                                 $deftimeout{$type} = $staticdefaults{'postsubmit'};                                  $deftimeout{$type} = $staticdefaults{'postsubmit'};
                             }                              }
Line 4336  sub print_coursedefaults { Line 3444  sub print_coursedefaults {
                     $deftimeout{$type} = $staticdefaults{'postsubmit'};                      $deftimeout{$type} = $staticdefaults{'postsubmit'};
                 }                  }
             }              }
             if (ref($settings->{'mysqltables'}) eq 'HASH') {  
                 foreach my $type (keys(%{$settings->{'mysqltables'}})) {  
                     $currmysql{$type} = $settings->{'mysqltables'}{$type};  
                 }  
             } else {  
                 foreach my $type (@types) {  
                     $currmysql{$type} = $staticdefaults{'mysqltables'};  
                 }  
             }  
         } else {          } else {
             foreach my $type (@types) {              foreach my $type (@types) {
                 $deftimeout{$type} = $staticdefaults{'postsubmit'};                  $deftimeout{$type} = $staticdefaults{'postsubmit'};
Line 4422  sub print_coursedefaults { Line 3521  sub print_coursedefaults {
         $additional .= '</tr></table></div>'."\n";          $additional .= '</tr></table></div>'."\n";
         %defaultchecked = ('postsubmit' => 'on');          %defaultchecked = ('postsubmit' => 'on');
         @toggles = ('postsubmit');          @toggles = ('postsubmit');
         $current = {          my $current = {
                        'postsubmit' => $postsubmitclient,                          'postsubmit' => $postsubmitclient,
                    };                        };
         ($table,$itemcount) =          ($table,$itemcount) =
             &radiobutton_prefs($current,\@toggles,\%defaultchecked,              &radiobutton_prefs($current,\@toggles,\%defaultchecked,
                                \%choices,$itemcount,$onclick,$additional,'left');                                 \%choices,$itemcount,$onclick,$additional,'left');
         $datatable .= $table;          $datatable .= $table;
         $css_class = $itemcount%2 ? ' class="LC_odd_row"' : '';  
         $datatable .= '<tr'.$css_class.'><td><span class="LC_nobreak">'.  
                       $choices{'mysqltables'}.  
                       '</span></td>'.  
                       '<td align="right" class="LC_right_item">'.  
                       '<table><tr>';  
         foreach my $type (@types) {  
             $datatable .= '<td align="center">'.&mt($type).'<br />'.  
                            '<input type="text" name="mysqltables_'.$type.'"'.  
                            ' value="'.$currmysql{$type}.'" size="8" /></td>';  
         }  
         $datatable .= '</tr></table></td></tr>'."\n";  
         $itemcount ++;  
   
     }      }
     $$rowtotal += $itemcount;      $$rowtotal += $itemcount;
     return $datatable;      return $datatable;
Line 4452  sub print_selfenrollment { Line 3537  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 4636  sub print_validation_rows { Line 3721  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 4658  sub print_validation_rows { Line 3743  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 4673  sub print_validation_rows { Line 3758  sub print_validation_rows {
     return $datatable;      return $datatable;
 }  }
   
 sub print_passwords {  
     my ($position,$dom,$confname,$settings,$rowtotal) = @_;  
     my ($datatable,$css_class);  
     my $itemcount = 0;  
     my %titles = &Apache::lonlocal::texthash (  
         captcha        => '"Forgot Password" CAPTCHA validation',  
         link           => 'Reset link expiration (hours)',  
         case           => 'Case-sensitive usernames/e-mail',  
         prelink        => 'Information required (form 1)',  
         postlink       => 'Information required (form 2)',  
         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') {  
         my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom);  
         my $shownlinklife = 2;  
         my $prelink = 'both';  
         my (%casesens,%postlink,%emailsrc,$nostdtext,$customurl);  
         if (ref($settings) eq 'HASH') {  
             if ($settings->{resetlink} =~ /^\d+(|\.\d*)$/) {  
                 $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>'.  
                           '<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 file'),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 {  
             $datatable .='<span class="LC_nobreak">&nbsp;'.  
                          '<input type="file" name="passwords_customfile" /></span>';  
         }  
         $datatable .= '</td></tr>';  
     } elsif ($position eq 'middle') {  
         my %domconf = &Apache::lonnet::get_dom('configuration',['defaults'],$dom);  
         my @items = ('intauth_cost','intauth_check','intauth_switch');  
         my %defaults;  
         if (ref($domconf{'defaults'}) eq 'HASH') {  
             %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 {  
             %defaults = (  
                           'intauth_cost'   => 10,  
                           'intauth_check'  => 0,  
                           'intauth_switch' => 0,  
                         );  
         }  
         foreach my $item (@items) {  
             if ($itemcount%2) {  
                 $css_class = '';  
             } else {  
                 $css_class = ' class="LC_odd_row" ';  
             }  
             $datatable .= '<tr'.$css_class.'>'.  
                           '<td><span class="LC_nobreak">'.$titles{$item}.  
                           '</span></td><td class="LC_left_item" colspan="3">';  
             if ($item eq 'intauth_switch') {  
                 my @options = (0,1,2);  
                 my %optiondesc = &Apache::lonlocal::texthash (  
                                    0 => 'No',  
                                    1 => 'Yes',  
                                    2 => 'Yes, and copy existing passwd file to passwd.bak file',  
                                  );  
                 $datatable .= '<table width="100%">';  
                 foreach my $option (@options) {  
                     my $checked = ' ';  
                     if ($defaults{$item} eq $option) {  
                         $checked = ' checked="checked"';  
                     }  
                     $datatable .= '<tr><td class="LC_left_item"><span class="LC_nobreak">'.  
                                   '<label><input type="radio" name="'.$item.  
                                   '" value="'.$option.'"'.$checked.' />'.  
                                   $optiondesc{$option}.'</label></span></td></tr>';  
                 }  
                 $datatable .= '</table>';  
             } elsif ($item eq 'intauth_check') {  
                 my @options = (0,1,2);  
                 my %optiondesc = &Apache::lonlocal::texthash (  
                                    0 => 'No',  
                                    1 => 'Yes, allow login then update passwd file using default cost (if higher)',  
                                    2 => 'Yes, disallow login if stored cost is less than domain default',  
                                  );  
                 $datatable .= '<table width="100%">';  
                 foreach my $option (@options) {  
                     my $checked = ' ';  
                     my $onclick;  
                     if ($defaults{$item} eq $option) {  
                         $checked = ' checked="checked"';  
                     }  
                     if ($option == 2) {  
                         $onclick = ' onclick="javascript:warnIntAuth(this);"';  
                     }  
                     $datatable .= '<tr><td class="LC_left_item"><span class="LC_nobreak">'.  
                                   '<label><input type="radio" name="'.$item.  
                                   '" value="'.$option.'"'.$checked.$onclick.' />'.  
                                   $optiondesc{$option}.'</label></span></td></tr>';  
                 }  
                 $datatable .= '</table>';  
             } else {  
                 $datatable .= '<input type="text" name="'.$item.'" value="'.  
                               $defaults{$item}.'" size="3" onblur="javascript:warnIntAuth(this);" />';  
             }  
             $datatable .= '</td></tr>';  
             $itemcount ++;  
         }  
     } elsif ($position eq 'lower') {  
         my ($min,$max,%chars,$numsaved);  
         $min = $Apache::lonnet::passwdmin;  
         if (ref($settings) eq 'HASH') {  
             if ($settings->{min}) {  
                 $min = $settings->{min};  
             }  
             if ($settings->{max}) {  
                 $max = $settings->{max};  
             }  
             if (ref($settings->{chars}) eq 'ARRAY') {  
                 map { $chars{$_} = 1; } (@{$settings->{chars}});  
             }  
             if ($settings->{numsaved}) {  
                 $numsaved = $settings->{numsaved};  
             }  
         }  
         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>';  
         $itemcount ++;  
         $css_class = $itemcount%2?' class="LC_odd_row"':'';  
         $datatable .= '<tr'.$css_class.'><td>'.$titles{'numsaved'}.'</td>'.  
                       '<td class="LC_left_item"><span class="LC_nobreak">'.  
                       '<input type="text" name="passwords_numsaved" value="'.$numsaved.'" size="3" '.  
                       'onblur="javascript:warnIntPass(this);" />'.  
                       '<span class="LC_fontsize_small"> '.&mt('(Leave blank to not save previous passwords)').'</span>'.  
                       '</span></td></tr>';  
     } else {  
         my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom);  
         my %ownerchg = (  
                           by  => {},  
                           for => {},  
                        );  
         my %ownertitles = &Apache::lonlocal::texthash (  
                             by  => 'Course owner status(es) allowed',  
                             for => 'Student status(es) allowed',  
                           );  
         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'}});  
                 }  
             }  
         }  
         $css_class = $itemcount%2?' class="LC_odd_row"':'';  
         $datatable .= '<tr '.$css_class.'>'.  
                       '<td>'.  
                       &mt('Requirements').'<ul>'.  
                       '<li>'.&mt("Course 'type' is not a Community").'</li>'.  
                       '<li>'.&mt('User is Course Coordinator and also course owner').'</li>'.  
                       '<li>'.&mt("Student's only active roles are student role(s) in course(s) owned by this user").'</li>'.  
                       '<li>'.&mt('User, course, and student share same domain').'</li>'.  
                       '</ul>'.  
                       '</td>'.  
                       '<td class="LC_left_item">';  
         foreach my $item ('by','for') {  
             $datatable .= '<fieldset style="display: inline-block;">'.  
                           '<legend>'.$ownertitles{$item}.'</legend>';  
             if ((ref($types) eq 'ARRAY') && (ref($usertypes) eq 'HASH')) {  
                 foreach my $type (@{$types}) {  
                     my $checked;  
                     if ($ownerchg{$item}{$type}) {  
                         $checked = ' checked="checked"';  
                     }  
                     $datatable .= '<span class="LC_nobreak"><label>'.  
                                   '<input type="checkbox" name="passwords_crsowner_'.$item.'" value="'.  
                                   $type.'"'.$checked.' />'.$usertypes->{$type}.'</label>'.  
                                   '<span>&nbsp;&nbsp; ';  
                 }  
             }  
             my $checked;  
             if ($ownerchg{$item}{'default'}) {  
                 $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;  
 }  
   
 sub print_usersessions {  sub print_usersessions {
     my ($position,$dom,$settings,$rowtotal) = @_;      my ($position,$dom,$settings,$rowtotal) = @_;
     my ($css_class,$datatable,%checked,%choices);      my ($css_class,$datatable,%checked,%choices);
Line 5397  sub spares_row { Line 4060  sub spares_row {
                             <span class="LC_nobreak">'.                              <span class="LC_nobreak">'.
                           &mt('[_1] when busy, offloads to:'                            &mt('[_1] when busy, offloads to:'
                               ,'<b>'.$server.'</b>').'</span><br />'.                                ,'<b>'.$server.'</b>').'</span><br />'.
                           '<span class="LC_nobreak">'."\n".                            '<span class="LC_nobreak">'."\n". 
                           '<label><input type="checkbox" name="offloadnow" value="'.$server.'"'.$checkednow.' />'.                            '<label><input type="checkbox" name="offloadnow" value="'.$server.'"'.$checkednow.' />'.
                           '&nbsp;'.&mt('Switch active users on next access').'</label></span>'.                            '&nbsp;'.&mt('Switch active users on next access').'</label></span>'.
                           "\n";                            "\n";
Line 5524  sub print_loadbalancing { Line 4187  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 5604  sub print_loadbalancing { Line 4267  sub print_loadbalancing {
         my ($numspares,@spares) = &count_servers($lonhost,%servers);          my ($numspares,@spares) = &count_servers($lonhost,%servers);
         my @sparestypes = ('primary','default');          my @sparestypes = ('primary','default');
         my %typetitles = &sparestype_titles();          my %typetitles = &sparestype_titles();
         my %hostherechecked = (  
                                   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 5655  sub print_loadbalancing { Line 4312  sub print_loadbalancing {
                 $datatable .=  '<i>'.$typetitles{$sparetype}.'</i><br />'.                  $datatable .=  '<i>'.$typetitles{$sparetype}.'</i><br />'.
                                '<table><tr>'.$targettable.'</tr></table><br />';                                 '<table><tr>'.$targettable.'</tr></table><br />';
             }              }
             $hostherechecked{$sparetype} = '';  
             if (ref($currtargets{$lonhost}) eq 'HASH') {  
                 if (ref($currtargets{$lonhost}{$sparetype}) eq 'ARRAY') {  
                     if (grep(/^\Q$lonhost\E$/,@{$currtargets{$lonhost}{$sparetype}})) {  
                         $hostherechecked{$sparetype} = ' checked="checked"';  
                         $hostherechecked{'no'} = '';  
                     }  
                 }  
             }  
         }  
         if ($currcookies{$lonhost}) {  
             %balcookiechecked = (  
                                     yes => ' checked="checked"',  
                                 );  
         }          }
         $datatable .= &mt('Hosting on balancer itself').'<br />'.          $datatable .= '</div></td></tr>'.
                       '<label><input type="radio" name="loadbalancing_target_'.$balnum.'_hosthere" value="no"'.  
                       $hostherechecked{'no'}.' />'.&mt('No').'</label><br />';  
         foreach my $sparetype (@sparestypes) {  
             $datatable .= '<label><input type="radio" name="loadbalancing_target_'.$balnum.'_hosthere" '.  
                           'value="'.$sparetype.'"'.$hostherechecked{$sparetype}.' /><i>'.$typetitles{$sparetype}.  
                           '</i></label><br />';  
         }  
         $datatable .= &mt('Use balancer cookie').'<br />'.  
                       '<label><input type="radio" name="loadbalancing_cookie_'.$balnum.'" value="1"'.  
                       $balcookiechecked{'yes'}.' />'.&mt('Yes').'</label><br />'.  
                       '<label><input type="radio" name="loadbalancing_cookie_'.$balnum.'" value="0"'.  
                       $balcookiechecked{'no'}.' />'.&mt('No').'</label><br />'.  
                       '</div></td></tr>'.  
                       &loadbalancing_rules($dom,$intdom,$currrules{$lonhost},                        &loadbalancing_rules($dom,$intdom,$currrules{$lonhost},
                                            $othertitle,$usertypes,$types,\%servers,                                             $othertitle,$usertypes,$types,\%servers,
                                            \%currbalancer,$lonhost,                                             \%currbalancer,$lonhost,
Line 5697  sub print_loadbalancing { Line 4327  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 5720  sub get_loadbalancers_config { Line 4349  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 5778  sub loadbalancing_titles { Line 4404  sub loadbalancing_titles {
            '_LC_ipchange'    => &mt('Non-SSO users with IP mismatch'),             '_LC_ipchange'    => &mt('Non-SSO users with IP mismatch'),
                      );                       );
     my @alltypes = ('_LC_adv','_LC_author','_LC_internetdom','_LC_external','_LC_ipchangesso','_LC_ipchange');      my @alltypes = ('_LC_adv','_LC_author','_LC_internetdom','_LC_external','_LC_ipchangesso','_LC_ipchange');
     my @available;  
     if (ref($types) eq 'ARRAY') {      if (ref($types) eq 'ARRAY') {
         @available = @{$types};          unshift(@alltypes,@{$types},'default');
     }  
     unless (grep(/^default$/,@available)) {  
         push(@available,'default');  
     }      }
     unshift(@alltypes,@available);  
     my %titles;      my %titles;
     foreach my $type (@alltypes) {      foreach my $type (@alltypes) {
         if ($type =~ /^_LC_/) {          if ($type =~ /^_LC_/) {
Line 5908  sub sparestype_titles { Line 4529  sub sparestype_titles {
   
 sub contact_titles {  sub contact_titles {
     my %titles = &Apache::lonlocal::texthash (      my %titles = &Apache::lonlocal::texthash (
                    'supportemail'    => 'Support E-mail address',                     'supportemail' => 'Support E-mail address',
                    'adminemail'      => 'Default Server Admin E-mail address',                     'adminemail'   => 'Default Server Admin E-mail address',
                    'errormail'       => 'Error reports to be e-mailed to',                     'errormail'    => 'Error reports to be e-mailed to',
                    'packagesmail'    => 'Package update alerts to be e-mailed to',                     'packagesmail' => 'Package update alerts to be e-mailed to',
                    'helpdeskmail'    => "Helpdesk requests from all users in this domain",                     'helpdeskmail' => 'Helpdesk requests to be e-mailed to',
                    'otherdomsmail'   => 'Helpdesk requests from users in other (unconfigured) domains',                     'lonstatusmail' => 'E-mail from nightly status check (warnings/errors)',
                    'lonstatusmail'   => 'E-mail from nightly status check (warnings/errors)',                     'requestsmail' => 'E-mail from course requests requiring approval',
                    'requestsmail'    => 'E-mail from course requests requiring approval',                     'updatesmail'  => 'E-mail from nightly check of LON-CAPA module integrity/updates',
                    'updatesmail'     => 'E-mail from nightly check of LON-CAPA module integrity/updates',  
                    'idconflictsmail' => 'E-mail from bi-nightly check for multiple users sharing same student/employee ID',                     'idconflictsmail' => 'E-mail from bi-nightly check for multiple users sharing same student/employee ID',
                    '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 5927  sub contact_titles { Line 4546  sub contact_titles {
     return (\%titles,\%short_titles);      return (\%titles,\%short_titles);
 }  }
   
 sub helpform_fields {  
     my %titles =  &Apache::lonlocal::texthash (  
                        'username'   => 'Name',  
                        'user'       => 'Username/domain',  
                        'phone'      => 'Phone',  
                        'cc'         => 'Cc e-mail',  
                        'course'     => 'Course Details',  
                        'section'    => 'Sections',  
                        'screenshot' => 'File upload',  
     );  
     my @fields = ('username','phone','user','course','section','cc','screenshot');  
     my %possoptions = (  
                         username     => ['yes','no','req'],  
                         phone        => ['yes','no','req'],  
                         user         => ['yes','no'],  
                         cc           => ['yes','no'],  
                         course       => ['yes','no'],  
                         section      => ['yes','no'],  
                         screenshot   => ['yes','no'],  
                       );  
     my %fieldoptions = &Apache::lonlocal::texthash (  
                          'yes'  => 'Optional',  
                          'req'  => 'Required',  
                          'no'   => "Not shown",  
     );  
     return (\@fields,\%titles,\%fieldoptions,\%possoptions);  
 }  
   
 sub tool_titles {  sub tool_titles {
     my %titles = &Apache::lonlocal::texthash (      my %titles = &Apache::lonlocal::texthash (
                      aboutme    => 'Personal web page',                       aboutme    => 'Personal web page',
Line 5965  sub tool_titles { Line 4556  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 5975  sub courserequest_titles { Line 4567  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 6139  sub print_usercreation { Line 4732  sub print_usercreation {
   
 sub print_selfcreation {  sub print_selfcreation {
     my ($position,$dom,$settings,$rowtotal) = @_;      my ($position,$dom,$settings,$rowtotal) = @_;
     my (@selfcreate,$createsettings,$processing,$emailoptions,$emailverified,      my (@selfcreate,$createsettings,$processing,$datatable);
         $emaildomain,$datatable);  
     if (ref($settings) eq 'HASH') {      if (ref($settings) eq 'HASH') {
         if (ref($settings->{'cancreate'}) eq 'HASH') {          if (ref($settings->{'cancreate'}) eq 'HASH') {
             $createsettings = $settings->{'cancreate'};              $createsettings = $settings->{'cancreate'};
Line 6157  sub print_selfcreation { Line 4749  sub print_selfcreation {
                 if (ref($createsettings->{'selfcreateprocessing'}) eq 'HASH') {                  if (ref($createsettings->{'selfcreateprocessing'}) eq 'HASH') {
                     $processing = $createsettings->{'selfcreateprocessing'};                      $processing = $createsettings->{'selfcreateprocessing'};
                 }                  }
                 if (ref($createsettings->{'emailoptions'}) eq 'HASH') {  
                     $emailoptions = $createsettings->{'emailoptions'};  
                 }  
                 if (ref($createsettings->{'emailverified'}) eq 'HASH') {  
                     $emailverified = $createsettings->{'emailverified'};  
                 }  
                 if (ref($createsettings->{'emaildomain'}) eq 'HASH') {  
                     $emaildomain = $createsettings->{'emaildomain'};  
                 }  
             }              }
         }          }
     }      }
     my %radiohash;      my %radiohash;
     my $numinrow = 4;      my $numinrow = 4;
     map { $radiohash{'cancreate_'.$_} = 1; } @selfcreate;      map { $radiohash{'cancreate_'.$_} = 1; } @selfcreate;
     my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom);  
     if ($position eq 'top') {      if ($position eq 'top') {
         my %choices = &Apache::lonlocal::texthash (          my %choices = &Apache::lonlocal::texthash (
                                                       cancreate_login      => 'Institutional Login',                                                        cancreate_login      => 'Institutional Login',
Line 6187  sub print_selfcreation { Line 4769  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;
           
           my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom);
   
         if (ref($usertypes) eq 'HASH') {          if (ref($usertypes) eq 'HASH') {
             if (keys(%{$usertypes}) > 0) {              if (keys(%{$usertypes}) > 0) {
                 $datatable .= &insttypes_row($createsettings,$types,$usertypes,                  $datatable .= &insttypes_row($createsettings,$types,$usertypes,
                                              $dom,$numinrow,$othertitle,                                               $dom,$numinrow,$othertitle,
                                              'statustocreate',$rowtotal);                                               'statustocreate',$$rowtotal);
                 $$rowtotal ++;                  $$rowtotal ++;
             }              }
         }          }
Line 6205  sub print_selfcreation { Line 4789  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 6237  sub print_selfcreation { Line 4821  sub print_selfcreation {
         $$rowtotal ++;          $$rowtotal ++;
     } elsif ($position eq 'middle') {      } elsif ($position eq 'middle') {
         my %domconf = &Apache::lonnet::get_dom('configuration',['usermodification'],$dom);          my %domconf = &Apache::lonnet::get_dom('configuration',['usermodification'],$dom);
         my @posstypes;          my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom);
           $usertypes->{'default'} = $othertitle;
         if (ref($types) eq 'ARRAY') {          if (ref($types) eq 'ARRAY') {
             @posstypes = @{$types};              push(@{$types},'default');
         }              $usertypes->{'default'} = $othertitle;
         unless (grep(/^default$/,@posstypes)) {              foreach my $status (@{$types}) {
             push(@posstypes,'default');                  $datatable .= &modifiable_userdata_row('selfcreate',$status,$domconf{'usermodification'},
         }                                                         $numinrow,$$rowtotal,$usertypes);
         my %usertypeshash;                  $$rowtotal ++;
         if (ref($usertypes) eq 'HASH') {              }
             %usertypeshash = %{$usertypes};  
         }  
         $usertypeshash{'default'} = $othertitle;  
         foreach my $status (@posstypes) {  
             $datatable .= &modifiable_userdata_row('selfcreate',$status,$domconf{'usermodification'},  
                                                    $numinrow,$$rowtotal,\%usertypeshash);  
             $$rowtotal ++;  
         }          }
     } else {      } else {
         my %choices = &Apache::lonlocal::texthash (          my %choices = &Apache::lonlocal::texthash (
                           'cancreate_email' => 'Non-institutional username (via e-mail verification)',                                                        cancreate_email => 'E-mail address as username',
                                                   );                                                    );
         my @toggles = sort(keys(%choices));          my @toggles = sort(keys(%choices));
         my %defaultchecked = (          my %defaultchecked = (
                                'cancreate_email' => 'off',                                 'cancreate_email' => 'off',
                              );                               );
         my $customclass = 'LC_selfcreate_email';          my $itemcount = 0;
         my $classprefix = 'LC_canmodify_emailusername_';  
         my $optionsprefix = 'LC_options_emailusername_';  
         my $display = 'none';          my $display = 'none';
         my $rowstyle = 'display:none';  
         if (grep(/^\Qemail\E$/,@selfcreate)) {          if (grep(/^\Qemail\E$/,@selfcreate)) {
             $display = 'block';              $display = 'block';
             $rowstyle = 'display:table-row';  
         }          }
         my $onclick = "toggleRows(this.form,'cancreate_email','selfassign','$customclass','$classprefix','$optionsprefix');";          my $onclick = "toggleDisplay(this.form,'emailoptions');";
         ($datatable,$$rowtotal) = &radiobutton_prefs(\%radiohash,\@toggles,\%defaultchecked,          my $additional = '<div id="emailoptions" style="display: '.$display.'">';
                                                      \%choices,$$rowtotal,$onclick);  
         $datatable .= &print_requestmail($dom,'selfcreation',$createsettings,$rowtotal,$customclass,  
                                          $rowstyle);  
         $$rowtotal ++;  
         $datatable .= &captcha_choice('cancreate',$createsettings,$$rowtotal,$customclass,  
                                       $rowstyle);  
         $$rowtotal ++;  
         my (@ordered,@posstypes,%usertypeshash);  
         my %domdefaults = &Apache::lonnet::get_domain_defaults($dom);          my %domdefaults = &Apache::lonnet::get_domain_defaults($dom);
         my ($emailrules,$emailruleorder) =          my $usertypes = {};
             &Apache::lonnet::inst_userrules($dom,'email');          my $order = [];
         my $primary_id = &Apache::lonnet::domain($dom,'primary');          if ((ref($domdefaults{'inststatustypes'}) eq 'HASH') && (ref($domdefaults{'inststatusguest'}) eq 'ARRAY')) {
         my $intdom = &Apache::lonnet::internet_dom($primary_id);              $usertypes = $domdefaults{'inststatustypes'};
         if (ref($types) eq 'ARRAY') {              $order = $domdefaults{'inststatusguest'};
             @posstypes = @{$types};          }
         }          if (ref($order) eq 'ARRAY') {
         if (@posstypes) {              push(@{$order},'default');
             unless (grep(/^default$/,@posstypes)) {              if (@{$order} > 1) {
                 push(@posstypes,'default');                  $usertypes->{'default'} = &mt('Other users');
             }                  $additional .= '<table><tr>';
             if (ref($usertypes) eq 'HASH') {                  foreach my $status (@{$order}) {
                 %usertypeshash = %{$usertypes};                      $additional .= '<th>'.$usertypes->{$status}.'</th>';
             }                  }
             my $currassign;                  $additional .= '</tr><tr>';
             if (ref($domdefaults{'inststatusguest'}) eq 'ARRAY') {                  foreach my $status (@{$order}) {
                 $currassign = {                      $additional .= '<td>'.&email_as_username($rowtotal,$processing,$status).'</td>';
                                   selfassign => $domdefaults{'inststatusguest'},  
                               };  
                 @ordered = @{$domdefaults{'inststatusguest'}};  
             } else {  
                 $currassign = { selfassign => [] };  
             }  
             my $onclicktypes = "toggleDataRow(this.form,'selfassign','$customclass','$optionsprefix',);".  
                                "toggleDataRow(this.form,'selfassign','$customclass','$classprefix',1);";  
             $datatable .= &insttypes_row($currassign,$types,$usertypes,$dom,  
                                          $numinrow,$othertitle,'selfassign',  
                                          $rowtotal,$onclicktypes,$customclass,  
                                          $rowstyle);  
             $$rowtotal ++;  
             $usertypeshash{'default'} = $othertitle;  
             foreach my $status (@posstypes) {  
                 my $css_class;  
                 if ($$rowtotal%2) {  
                     $css_class = 'LC_odd_row ';  
                 }  
                 $css_class .= $customclass;  
                 my $rowid = $optionsprefix.$status;  
                 my $hidden = 1;  
                 my $currstyle = 'display:none';  
                 if (grep(/^\Q$status\E$/,@ordered)) {  
                     $currstyle = $rowstyle;  
                     $hidden = 0;  
                 }  
                 $datatable .= &noninst_users($processing,$emailverified,$emailoptions,$emaildomain,  
                                              $emailrules,$emailruleorder,$settings,$status,$rowid,  
                                              $usertypeshash{$status},$css_class,$currstyle,$intdom);  
                 unless ($hidden) {  
                     $$rowtotal ++;  
                 }                  }
                   $additional .= '</tr></table>';
               } else {
                   $usertypes->{'default'} = &mt('All users');
                   $additional .= &email_as_username($rowtotal,$processing);
             }              }
         } else {  
             my $css_class;  
             if ($$rowtotal%2) {  
                 $css_class = 'LC_odd_row ';  
             }  
             $css_class .= $customclass;  
             $usertypeshash{'default'} = $othertitle;  
             $datatable .= &noninst_users($processing,$emailverified,$emailoptions,$emaildomain,  
                                          $emailrules,$emailruleorder,$settings,'default','',  
                                          $othertitle,$css_class,$rowstyle,$intdom);  
             $$rowtotal ++;  
         }          }
           $additional .= '</div>'."\n";
   
           ($datatable,$itemcount) = &radiobutton_prefs(\%radiohash,\@toggles,\%defaultchecked,
                                                        \%choices,$$rowtotal,$onclick,$additional);
           $$rowtotal ++;
           $datatable .= &print_requestmail($dom,'selfcreation',$createsettings,$rowtotal);
           $$rowtotal ++;
         my ($infofields,$infotitles) = &Apache::loncommon::emailusername_info();          my ($infofields,$infotitles) = &Apache::loncommon::emailusername_info();
         $numinrow = 1;          $numinrow = 1;
         if (@posstypes) {          if (ref($order) eq 'ARRAY') {
             foreach my $status (@posstypes) {              foreach my $status (@{$order}) {
                 my $rowid = $classprefix.$status;  
                 my $datarowstyle = 'display:none';  
                 if (grep(/^\Q$status\E$/,@ordered)) {  
                     $datarowstyle = $rowstyle;  
                 }  
                 $datatable .= &modifiable_userdata_row('cancreate','emailusername_'.$status,$settings,                  $datatable .= &modifiable_userdata_row('cancreate','emailusername_'.$status,$settings,
                                                        $numinrow,$$rowtotal,\%usertypeshash,$infofields,                                                         $numinrow,$$rowtotal,$usertypes,$infofields,$infotitles);
                                                        $infotitles,$rowid,$customclass,$datarowstyle);                  $$rowtotal ++;
                 unless ($datarowstyle eq 'display:none') {  
                     $$rowtotal ++;  
                 }  
             }              }
         } else {  
             $datatable .= &modifiable_userdata_row('cancreate','emailusername_default',$settings,  
                                                    $numinrow,$$rowtotal,\%usertypeshash,$infofields,  
                                                    $infotitles,'',$customclass,$rowstyle);  
         }          }
     }          my ($emailrules,$emailruleorder) =
     return $datatable;              &Apache::lonnet::inst_userrules($dom,'email');
 }          if (ref($emailrules) eq 'HASH') {
               if (keys(%{$emailrules}) > 0) {
 sub selfcreate_javascript {                  $datatable .= &user_formats_row('email',$settings,$emailrules,
     return <<"ENDSCRIPT";                                                  $emailruleorder,$numinrow,$$rowtotal);
                   $$rowtotal ++;
 <script type="text/javascript">  
 // <![CDATA[  
   
 function toggleRows(form,radio,checkbox,target,prefix,altprefix) {  
     var x = document.getElementsByClassName(target);  
     var insttypes = 0;  
     var insttypeRegExp = new RegExp(prefix);  
     if ((x.length != undefined) && (x.length > 0)) {  
         if (form.elements[radio].length != undefined) {  
             for (var i=0; i<form.elements[radio].length; i++) {  
                 if (form.elements[radio][i].checked) {  
                     if (form.elements[radio][i].value == 1) {  
                         for (var j=0; j<x.length; j++) {  
                             if (x[j].id == 'undefined') {  
                                 x[j].style.display = 'table-row';  
                             } else if (insttypeRegExp.test(x[j].id)) {  
                                 insttypes ++;  
                             } else {  
                                 x[j].style.display = 'table-row';  
                             }  
                         }  
                     } else {  
                         for (var j=0; j<x.length; j++) {  
                             x[j].style.display = 'none';  
                         }  
                     }  
                     break;  
                 }  
             }  
             if (insttypes > 0) {  
                 toggleDataRow(form,checkbox,target,altprefix);  
                 toggleDataRow(form,checkbox,target,prefix,1);  
             }              }
         }          }
           $datatable .= &captcha_choice('cancreate',$createsettings,$$rowtotal);
     }      }
     return;      return $datatable;
 }  }
   
 function toggleDataRow(form,checkbox,target,prefix,docount) {  sub email_as_username {
     if (form.elements[checkbox].length != undefined) {      my ($rowtotal,$processing,$type) = @_;
         var count = 0;      my %choices =
         if (docount) {          &Apache::lonlocal::texthash (
             for (var i=0; i<form.elements[checkbox].length; i++) {                                        automatic => 'Automatic approval',
                 if (form.elements[checkbox][i].checked) {                                        approval  => 'Queued for approval',
                     count ++;                                      );
                 }      my $output;
             }      foreach my $option ('automatic','approval') {
         }          my $checked;
         for (var i=0; i<form.elements[checkbox].length; i++) {          if (ref($processing) eq 'HASH') {
             var type = form.elements[checkbox][i].value;              if ($type eq '') {   
             if (document.getElementById(prefix+type)) {                  if (!exists($processing->{'default'})) {
                 if (form.elements[checkbox][i].checked) {                      if ($option eq 'automatic') {
                     document.getElementById(prefix+type).style.display = 'table-row';                          $checked = ' checked="checked"';
                     if (count % 2 == 1) {  
                         document.getElementById(prefix+type).className = target+' LC_odd_row';  
                     } else {  
                         document.getElementById(prefix+type).className = target;  
                     }                      }
                     count ++;  
                 } else {                  } else {
                     document.getElementById(prefix+type).style.display = 'none';                      if ($processing->{'default'} eq $option) {
                 }                          $checked = ' checked="checked"';
             }  
         }  
     }  
     return;  
 }  
   
 function toggleEmailOptions(form,radio,prefix,altprefix,status) {  
     var caller = radio+'_'+status;  
     if (form.elements[caller].length != undefined) {  
         for (var i=0; i<form.elements[caller].length; i++) {  
             if (form.elements[caller][i].checked) {  
                 if (document.getElementById(altprefix+'_inst_'+status)) {  
                     var curr = form.elements[caller][i].value;  
                     if (prefix) {  
                         document.getElementById(prefix+'_'+status).style.display = 'none';  
                     }  
                     document.getElementById(altprefix+'_inst_'+status).style.display = 'none';  
                     document.getElementById(altprefix+'_noninst_'+status).style.display = 'none';  
                     if (curr == 'custom') {  
                         if (prefix) {  
                             document.getElementById(prefix+'_'+status).style.display = 'inline';  
                         }  
                     } else if (curr == 'inst') {  
                         document.getElementById(altprefix+'_inst_'+status).style.display = 'inline';  
                     } else if (curr == 'noninst') {  
                         document.getElementById(altprefix+'_noninst_'+status).style.display = 'inline';  
                     }  
                     break;  
                 }  
             }  
         }  
     }  
 }  
   
 // ]]>  
 </script>  
   
 ENDSCRIPT  
 }  
   
 sub noninst_users {  
     my ($processing,$emailverified,$emailoptions,$emaildomain,$emailrules,  
         $emailruleorder,$settings,$type,$rowid,$typetitle,$css_class,$rowstyle,$intdom) = @_;  
     my $class = 'LC_left_item';  
     if ($css_class) {  
         $css_class = ' class="'.$css_class.'"';  
     }  
     if ($rowid) {  
         $rowid = ' id="'.$rowid.'"';  
     }  
     if ($rowstyle) {  
         $rowstyle = ' style="'.$rowstyle.'"';  
     }  
     my ($output,$description);  
     if ($type eq 'default') {  
         $description = &mt('Requests for: [_1]',$typetitle);  
     } else {  
         $description = &mt('Requests for: [_1] (status self-reported)',$typetitle);  
     }  
     $output = '<tr'.$css_class.$rowid.$rowstyle.'>'.  
               "<td>$description</td>\n".  
               '<td class="'.$class.'" colspan="2">'.  
               '<table><tr>';  
     my %headers = &Apache::lonlocal::texthash(  
               approve  => 'Processing',  
               email    => 'E-mail',  
               username => 'Username',  
     );  
     foreach my $item ('approve','email','username') {  
         $output .= '<th>'.$headers{$item}.'</th>';  
     }  
     $output .= '</tr><tr>';  
     foreach my $item ('approve','email','username') {  
         $output .= '<td valign="top">';  
         my (%choices,@options,$hashref,$defoption,$name,$onclick,$hascustom);  
         if ($item eq 'approve') {  
             %choices = &Apache::lonlocal::texthash (  
                                                      automatic => 'Automatically approved',  
                                                      approval  => 'Queued for approval',  
                                                    );  
             @options = ('automatic','approval');  
             $hashref = $processing;  
             $defoption = 'automatic';  
             $name = 'cancreate_emailprocess_'.$type;  
         } elsif ($item eq 'email') {  
             %choices = &Apache::lonlocal::texthash (  
                                                      any     => 'Any e-mail',  
                                                      inst    => 'Institutional only',  
                                                      noninst => 'Non-institutional only',  
                                                      custom  => 'Custom restrictions',  
                                                    );  
             @options = ('any','inst','noninst');  
             my $showcustom;  
             if (ref($emailrules) eq 'HASH') {  
                 if (keys(%{$emailrules}) > 0) {  
                     push(@options,'custom');  
                     $showcustom = 'cancreate_emailrule';  
                     if (ref($settings) eq 'HASH') {  
                         if (ref($settings->{'email_rule'}) eq 'ARRAY') {  
                             foreach my $rule (@{$settings->{'email_rule'}}) {  
                                 if (exists($emailrules->{$rule})) {  
                                     $hascustom ++;  
                                 }  
                             }  
                         } elsif (ref($settings->{'email_rule'}) eq 'HASH') {  
                             if (ref($settings->{'email_rule'}{$type}) eq 'ARRAY') {  
                                 foreach my $rule (@{$settings->{'email_rule'}{$type}}) {  
                                     if (exists($emailrules->{$rule})) {  
                                         $hascustom ++;  
                                     }  
                                 }  
                             }  
                         }  
                     }                      }
                 }                  }
             }              } else {
             $onclick = ' onclick="toggleEmailOptions(this.form,'."'cancreate_emailoptions','$showcustom',".                  if (!exists($processing->{$type})) {
                                                      "'cancreate_emaildomain','$type'".');"';                      if ($option eq 'automatic') {
             $hashref = $emailoptions;                          $checked = ' checked="checked"';
             $defoption = 'any';  
             $name = 'cancreate_emailoptions_'.$type;  
         } elsif ($item eq 'username') {  
             %choices = &Apache::lonlocal::texthash (  
                                                      all    => 'Same as e-mail',  
                                                      first  => 'Omit @domain',  
                                                      free   => 'Free to choose',  
                                                    );  
             @options = ('all','first','free');  
             $hashref = $emailverified;  
             $defoption = 'all';  
             $name = 'cancreate_usernameoptions_'.$type;  
         }  
         foreach my $option (@options) {  
             my $checked;  
             if (ref($hashref) eq 'HASH') {  
                 if ($type eq '') {  
                     if (!exists($hashref->{'default'})) {  
                         if ($option eq $defoption) {  
                             $checked = ' checked="checked"';  
                         }  
                     } else {  
                         if ($hashref->{'default'} eq $option) {  
                             $checked = ' checked="checked"';  
                         }  
                     }                      }
                 } else {                  } else {
                     if (!exists($hashref->{$type})) {                      if ($processing->{$type} eq $option) {
                         if ($option eq $defoption) {                          $checked = ' checked="checked"';
                             $checked = ' checked="checked"';  
                         }  
                     } else {  
                         if ($hashref->{$type} eq $option) {  
                             $checked = ' checked="checked"';  
                         }  
                     }  
                 }  
             } elsif (($item eq 'email') && ($hascustom)) {  
                 if ($option eq 'custom') {  
                     $checked = ' checked="checked"';  
                 }  
             } elsif ($option eq $defoption) {  
                 $checked = ' checked="checked"';  
             }  
             $output .= '<span class="LC_nobreak"><label>'.  
                        '<input type="radio" name="'.$name.'"'.  
                        $checked.' value="'.$option.'"'.$onclick.' />'.  
                        $choices{$option}.'</label></span><br />';  
             if ($item eq 'email') {  
                 if ($option eq 'custom') {  
                     my $id = 'cancreate_emailrule_'.$type;  
                     my $display = 'none';  
                     if ($checked) {  
                         $display = 'inline';  
                     }  
                     my $numinrow = 2;  
                     $output .= '<fieldset id="'.$id.'" style="display:'.$display.';">'.  
                                '<legend>'.&mt('Disallow').'</legend><table>'.  
                                &user_formats_row('email',$settings,$emailrules,  
                                                  $emailruleorder,$numinrow,'',$type);  
                               '</table></fieldset>';  
                 } elsif (($option eq 'inst') || ($option eq 'noninst')) {  
                     my %text = &Apache::lonlocal::texthash (  
                                                              inst    => 'must end:',  
                                                              noninst => 'cannot end:',  
                                                            );  
                     my $value;  
                     if (ref($emaildomain) eq 'HASH') {  
                         if (ref($emaildomain->{$type}) eq 'HASH') {  
                             $value = $emaildomain->{$type}->{$option};  
                         }  
                     }  
                     if ($value eq '') {  
                         $value = '@'.$intdom;  
                     }  
                     my $condition = 'cancreate_emaildomain_'.$option.'_'.$type;  
                     my $display = 'none';  
                     if ($checked) {  
                         $display = 'inline';  
                     }                      }
                     $output .= '<div id="'.$condition.'" style="display:'.$display.';">'.  
                                '<span class="LC_domprefs_email">'.$text{$option}.'</span> '.  
                                '<input type="text" name="'.$condition.'" value="'.$value.'" size="10" />'.  
                                '</div>';  
                 }                  }
             }              }
           } elsif ($option eq 'automatic') {
               $checked = ' checked="checked"'; 
           }
           my $name = 'cancreate_emailprocess';
           if (($type ne '') && ($type ne 'default')) {
               $name .= '_'.$type;
           }
           $output .= '<span class="LC_nobreak"><label>'.
                      '<input type="radio" name="'.$name.'"'.
                      $checked.' value="'.$option.'" />'.
                      $choices{$option}.'</label></span>';
           if ($type eq '') {
               $output .= '&nbsp;';
           } else {
               $output .= '<br />';
         }          }
         $output .= '</td>'."\n";  
     }      }
     $output .= "</tr></table></td></tr>\n";      $$rowtotal ++;
     return $output;      return $output;
 }  }
   
 sub captcha_choice {  sub captcha_choice {
     my ($context,$settings,$itemcount,$customcss,$rowstyle) = @_;      my ($context,$settings,$itemcount) = @_;
     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 6685  sub captcha_choice { Line 4989  sub captcha_choice {
     } else {      } else {
         $checked{'original'} = ' checked="checked"';          $checked{'original'} = ' checked="checked"';
     }      }
     my $css_class;      my $css_class = $itemcount%2?' class="LC_odd_row"':'';
     if ($itemcount%2) {  
         $css_class = 'LC_odd_row';  
     }  
     if ($customcss) {  
         $css_class .= " $customcss";  
     }  
     $css_class =~ s/^\s+//;  
     if ($css_class) {  
         $css_class = ' class="'.$css_class.'"';  
     }  
     if ($rowstyle) {  
         $css_class .= ' style="'.$rowstyle.'"';  
     }  
     my $output = '<tr'.$css_class.'>'.      my $output = '<tr'.$css_class.'>'.
                  '<td class="LC_left_item">'.$rowname.'</td><td class="LC_left_item" colspan="'.$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 6717  sub captcha_choice { Line 5008  sub captcha_choice {
 # specified for use with the key should be broad enough to accommodate all servers in the LON-CAPA domain.  # specified for use with the key should be broad enough to accommodate all servers in the LON-CAPA domain.
 #  #
     $output .= '</td></tr>'."\n".      $output .= '</td></tr>'."\n".
                '<tr><td class="LC_zero_height">'."\n".                 '<tr><td>'."\n".
                '<span class="LC_nobreak"><span id="'.$context.'_recaptchapubtxt">'.$pubtext.'</span>&nbsp;'."\n".                 '<span class="LC_nobreak"><span id="'.$context.'_recaptchapubtxt">'.$pubtext.'</span>&nbsp;'."\n".
                '<input type="'.$keyentry.'" id="'.$context.'_recaptchapub" name="'.$context.'_recaptchapub" value="'.                 '<input type="'.$keyentry.'" id="'.$context.'_recaptchapub" name="'.$context.'_recaptchapub" value="'.
                $currpub.'" size="40" /></span><br />'."\n".                 $currpub.'" size="40" /></span><br />'."\n".
Line 6733  sub captcha_choice { Line 5024  sub captcha_choice {
 }  }
   
 sub user_formats_row {  sub user_formats_row {
     my ($type,$settings,$rules,$ruleorder,$numinrow,$rowcount,$status) = @_;      my ($type,$settings,$rules,$ruleorder,$numinrow,$rowcount) = @_;
     my $output;      my $output;
     my %text = (      my %text = (
                    'username' => 'new usernames',                     'username' => 'new usernames',
                    'id'       => 'IDs',                     'id'       => 'IDs',
                      'email'    => 'self-created accounts (e-mail)',
                );                 );
     unless ($type eq 'email') {      my $css_class = $rowcount%2?' class="LC_odd_row"':'';
         my $css_class = $rowcount%2?' class="LC_odd_row"':'';      $output = '<tr '.$css_class.'>'.
         $output = '<tr '.$css_class.'>'.                '<td><span class="LC_nobreak">';
                   '<td><span class="LC_nobreak">'.      if ($type eq 'email') {
                   &mt("Format rules to check for $text{$type}: ").          $output .= &mt("Formats disallowed for $text{$type}: ");
                   '</td><td class="LC_left_item" colspan="2"><table>';      } else {
           $output .= &mt("Format rules to check for $text{$type}: ");
     }      }
       $output .= '</span></td>'.
                  '<td class="LC_left_item" colspan="2"><table>';
     my $rem;      my $rem;
     if (ref($ruleorder) eq 'ARRAY') {      if (ref($ruleorder) eq 'ARRAY') {
         for (my $i=0; $i<@{$ruleorder}; $i++) {          for (my $i=0; $i<@{$ruleorder}; $i++) {
Line 6763  sub user_formats_row { Line 5058  sub user_formats_row {
                         if (grep(/^\Q$ruleorder->[$i]\E$/,@{$settings->{$type.'_rule'}})) {                          if (grep(/^\Q$ruleorder->[$i]\E$/,@{$settings->{$type.'_rule'}})) {
                             $check = ' checked="checked" ';                              $check = ' checked="checked" ';
                         }                          }
                     } elsif ((ref($settings->{$type.'_rule'}) eq 'HASH') && ($status ne '')) {  
                         if (ref($settings->{$type.'_rule'}->{$status}) eq 'ARRAY') {  
                             if (grep(/^\Q$ruleorder->[$i]\E$/,@{$settings->{$type.'_rule'}->{$status}})) {  
                                 $check = ' checked="checked" ';  
                             }  
                         }  
                     }                      }
                 }                  }
                 my $name = $type.'_rule';  
                 if ($type eq 'email') {  
                     $name .= '_'.$status;  
                 }  
                 $output .= '<td class="LC_left_item">'.                  $output .= '<td class="LC_left_item">'.
                            '<span class="LC_nobreak"><label>'.                             '<span class="LC_nobreak"><label>'.
                            '<input type="checkbox" name="'.$name.'" '.                             '<input type="checkbox" name="'.$type.'_rule" '.
                            'value="'.$ruleorder->[$i].'"'.$check.'/>'.                             'value="'.$ruleorder->[$i].'"'.$check.'/>'.
                            $rules->{$ruleorder->[$i]}{'name'}.'</label></span></td>';                             $rules->{$ruleorder->[$i]}{'name'}.'</label></span></td>';
             }              }
         }          }
         $rem = @{$ruleorder}%($numinrow);          $rem = @{$ruleorder}%($numinrow);
     }      }
     my $colsleft;      my $colsleft = $numinrow - $rem;
     if ($rem) {  
         $colsleft = $numinrow - $rem;  
     }  
     if ($colsleft > 1 ) {      if ($colsleft > 1 ) {
         $output .= '<td colspan="'.$colsleft.'" class="LC_left_item">'.          $output .= '<td colspan="'.$colsleft.'" class="LC_left_item">'.
                    '&nbsp;</td>';                     '&nbsp;</td>';
     } elsif ($colsleft == 1) {      } elsif ($colsleft == 1) {
         $output .= '<td class="LC_left_item">&nbsp;</td>';          $output .= '<td class="LC_left_item">&nbsp;</td>';
     }      }
     $output .= '</tr></table>';      $output .= '</tr></table></td></tr>';
     unless ($type eq 'email') {  
         $output .= '</td></tr>';  
     }  
     return $output;      return $output;
 }  }
   
Line 6874  sub print_usermodification { Line 5153  sub print_usermodification {
 sub print_defaults {  sub print_defaults {
     my ($position,$dom,$settings,$rowtotal) = @_;      my ($position,$dom,$settings,$rowtotal) = @_;
     my $rownum = 0;      my $rownum = 0;
     my ($datatable,$css_class,$titles);      my ($datatable,$css_class);
     unless ($position eq 'bottom') {  
         $titles = &defaults_titles($dom);  
     }  
     if ($position eq 'top') {      if ($position eq 'top') {
         my @items = ('auth_def','auth_arg_def','lang_def','timezone_def',          my @items = ('auth_def','auth_arg_def','lang_def','timezone_def',
                      'datelocale_def','portal_def');                       'datelocale_def','portal_def');
Line 6890  sub print_defaults { Line 5166  sub print_defaults {
                 $defaults{$item} = $domdefaults{$item};                  $defaults{$item} = $domdefaults{$item};
             }              }
         }          }
           my $titles = &defaults_titles($dom);
         foreach my $item (@items) {          foreach my $item (@items) {
             if ($rownum%2) {              if ($rownum%2) {
                 $css_class = '';                  $css_class = '';
Line 6938  sub print_defaults { Line 5215  sub print_defaults {
             $rownum ++;              $rownum ++;
         }          }
     } else {      } else {
         my %defaults;          my (%defaults);
         if (ref($settings) eq 'HASH') {          if (ref($settings) eq 'HASH') {
             if ((ref($settings->{'inststatusorder'}) eq 'ARRAY') && (ref($settings->{'inststatustypes'}) eq 'HASH')) {              if ((ref($settings->{'inststatusorder'}) eq 'ARRAY') && (ref($settings->{'inststatustypes'}) eq 'HASH') &&
                   (ref($settings->{'inststatusguest'}) eq 'ARRAY')) {
                 my $maxnum = @{$settings->{'inststatusorder'}};                  my $maxnum = @{$settings->{'inststatusorder'}};
                 for (my $i=0; $i<$maxnum; $i++) {                  for (my $i=0; $i<$maxnum; $i++) {
                     $css_class = $rownum%2?' class="LC_odd_row"':'';                      $css_class = $rownum%2?' class="LC_odd_row"':'';
                     my $item = $settings->{'inststatusorder'}->[$i];                      my $item = $settings->{'inststatusorder'}->[$i];
                     my $title = $settings->{'inststatustypes'}->{$item};                      my $title = $settings->{'inststatustypes'}->{$item};
                       my $guestok;
                       if (grep(/^\Q$item\E$/,@{$settings->{'inststatusguest'}})) {
                           $guestok = 1;
                       }
                     my $chgstr = ' onchange="javascript:reorderTypes(this.form,'."'$item'".');"';                      my $chgstr = ' onchange="javascript:reorderTypes(this.form,'."'$item'".');"';
                     $datatable .= '<tr'.$css_class.'>'.                      $datatable .= '<tr'.$css_class.'>'.
                                   '<td><span class="LC_nobreak">'.                                    '<td><span class="LC_nobreak">'.
Line 6958  sub print_defaults { Line 5240  sub print_defaults {
                         }                          }
                         $datatable .= '<option value="'.$k.'"'.$selstr.'>'.$vpos.'</option>';                          $datatable .= '<option value="'.$k.'"'.$selstr.'>'.$vpos.'</option>';
                     }                      }
                       my ($checkedon,$checkedoff);
                       $checkedoff = ' checked="checked"';
                       if ($guestok) {
                           $checkedon = $checkedoff;
                           $checkedoff = ''; 
                       }
                     $datatable .= '</select>&nbsp;'.&mt('Internal ID:').'&nbsp;<b>'.$item.'</b>&nbsp;'.                      $datatable .= '</select>&nbsp;'.&mt('Internal ID:').'&nbsp;<b>'.$item.'</b>&nbsp;'.
                                   '<input type="checkbox" name="inststatus_delete" value="'.$item.'" />'.                                    '<input type="checkbox" name="inststatus_delete" value="'.$item.'" />'.
                                   &mt('delete').'</span></td>'.                                    &mt('delete').'</span></td>'.
                                   '<td class="LC_left_item"><span class="LC_nobreak">'.&mt('Name displayed:').                                    '<td class="LC_left_item"><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>'.
                                     '<td class="LC_right_item"><span class="LC_nobreak">'.
                                     '<label><input type="radio" value="1" name="inststatus_guest_'.$item.'"'.$checkedon.' />'.
                                     &mt('Yes').'</label>'.('&nbsp;'x2).
                                     '<label><input type="radio" value="0" name="inststatus_guest_'.$item.'"'.$checkedoff.' />'.
                                     &mt('No').'</label></span></td></tr>';
                 }                  }
                 $css_class = $rownum%2?' class="LC_odd_row"':'';                  $css_class = $rownum%2?' class="LC_odd_row"':'';
                 my $chgstr = ' onchange="javascript:reorderTypes(this.form,'."'addinststatus_pos'".');"';                  my $chgstr = ' onchange="javascript:reorderTypes(this.form,'."'addinststatus_pos'".');"';
Line 6983  sub print_defaults { Line 5276  sub print_defaults {
                               '</span></td><td class="LC_left_item"><span class="LC_nobreak">'.                                '</span></td><td class="LC_left_item"><span class="LC_nobreak">'.
                               &mt('Name displayed:').                                &mt('Name displayed:').
                               '<input type="text" size="20" name="addinststatus_title" value="" /></span></td>'.                                '<input type="text" size="20" name="addinststatus_title" value="" /></span></td>'.
                                 '<td class="LC_right_item"><span class="LC_nobreak">'.
                                 '<label><input type="radio" value="1" name="addinststatus_guest" />'.
                                 &mt('Yes').'</label>'.('&nbsp;'x2).
                                 '<label><input type="radio" value="0" name="addinststatus_guest" />'.
                                 &mt('No').'</label></span></td></tr>';
                               '</tr>'."\n";                                '</tr>'."\n";
                 $rownum ++;                  $rownum ++;
             }              }
Line 7012  sub defaults_titles { Line 5310  sub defaults_titles {
                    'timezone_def'  => 'Default timezone',                     'timezone_def'  => 'Default timezone',
                    'datelocale_def' => 'Default locale for dates',                     'datelocale_def' => 'Default locale for dates',
                    'portal_def'     => 'Portal/Default URL',                     'portal_def'     => 'Portal/Default URL',
                    'intauth_cost'   => 'Encryption cost for bcrypt (positive integer)',  
                    'intauth_check'  => 'Check bcrypt cost if authenticated',  
                    'intauth_switch' => 'Existing crypt-based switched to bcrypt on authentication',  
                  );                   );
     if ($dom) {      if ($dom) {
         my $uprimary_id = &Apache::lonnet::domain($dom,'primary');          my $uprimary_id = &Apache::lonnet::domain($dom,'primary');
Line 7029  sub defaults_titles { Line 5324  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 7107  sub print_scantronformat { Line 5350  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 7117  sub print_scantronformat { Line 5360  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 7128  sub print_scantronformat { Line 5371  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 7254  sub legacy_scantronformat { Line 5497  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 7419  sub print_coursecategories { Line 5539  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 7630  sub print_coursecategories { Line 5750  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 7678  sub print_serverstatuses { Line 5798  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 7693  sub serverstatus_pages { Line 5813  sub serverstatus_pages {
   
 sub defaults_javascript {  sub defaults_javascript {
     my ($settings) = @_;      my ($settings) = @_;
     return unless (ref($settings) eq 'HASH');      return unless (ref($settings) eq 'HASH'); 
     if ((ref($settings->{'inststatusorder'}) eq 'ARRAY') && (ref($settings->{'inststatustypes'}) eq 'HASH')) {      if ((ref($settings->{'inststatusorder'}) eq 'ARRAY') && (ref($settings->{'inststatustypes'}) eq 'HASH')) {
         my $maxnum = scalar(@{$settings->{'inststatusorder'}});          my $maxnum = scalar(@{$settings->{'inststatusorder'}});
         if ($maxnum eq '') {          if ($maxnum eq '') {
Line 7754  ENDSCRIPT Line 5874  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 {  
         if (field.value == '0') {  
             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 {
     my ($settings) = @_;      my ($settings) = @_;
     my ($output,$jstext,$cathash);      my ($output,$jstext,$cathash);
Line 7959  sub initialize_categories { Line 5991  sub initialize_categories {
     my $select1 = '';      my $select1 = '';
     foreach my $default ('instcode','communities') {      foreach my $default ('instcode','communities') {
         $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') {
             $select1 = $select0;              $select1 = $select0;
             $select0 = '';              $select0 = '';
Line 7984  sub initialize_categories { Line 6016  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 8041  sub build_category_rows { Line 6072  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 8064  sub build_category_rows { Line 6095  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 8073  sub build_category_rows { Line 6104  sub build_category_rows {
 }  }
   
 sub modifiable_userdata_row {  sub modifiable_userdata_row {
     my ($context,$item,$settings,$numinrow,$rowcount,$usertypes,$fieldsref,$titlesref,      my ($context,$item,$settings,$numinrow,$rowcount,$usertypes,$fieldsref,$titlesref) = @_;
         $rowid,$customcss,$rowstyle) = @_;  
     my ($role,$rolename,$statustype);      my ($role,$rolename,$statustype);
     $role = $item;      $role = $item;
     if ($context eq 'cancreate') {      if ($context eq 'cancreate') {
         if ($item =~ /^(emailusername)_(.+)$/) {          if ($item =~ /^emailusername_(.+)$/) {
             $role = $1;              $statustype = $1;
             $statustype = $2;              $role = 'emailusername';
             if (ref($usertypes) eq 'HASH') {              if (ref($usertypes) eq 'HASH') {
                 if ($usertypes->{$statustype}) {                  if ($usertypes->{$statustype}) {
                     $rolename = &mt('Data provided by [_1]',$usertypes->{$statustype});                      $rolename = &mt('Data provided by [_1]',$usertypes->{$statustype});
Line 8115  sub modifiable_userdata_row { Line 6145  sub modifiable_userdata_row {
         %fieldtitles = &Apache::loncommon::personal_data_fieldtitles();          %fieldtitles = &Apache::loncommon::personal_data_fieldtitles();
     }      }
     my $output;      my $output;
     my $css_class;      my $css_class = $rowcount%2?' class="LC_odd_row"':'';
     if ($rowcount%2) {      $output = '<tr '.$css_class.'>'.
         $css_class = 'LC_odd_row';  
     }  
     if ($customcss) {  
         $css_class .= " $customcss";  
     }  
     $css_class =~ s/^\s+//;  
     if ($css_class) {  
         $css_class = ' class="'.$css_class.'"';  
     }  
     if ($rowstyle) {  
         $css_class .= ' style="'.$rowstyle.'"';  
     }  
     if ($rowid) {  
         $rowid = ' id="'.$rowid.'"';  
     }  
   
     $output = '<tr '.$css_class.$rowid.'>'.  
               '<td><span class="LC_nobreak">'.$rolename.'</span></td>'.                '<td><span class="LC_nobreak">'.$rolename.'</span></td>'.
               '<td class="LC_left_item" colspan="2"><table>';                '<td class="LC_left_item" colspan="2"><table>';
     my $rem;      my $rem;
Line 8167  sub modifiable_userdata_row { Line 6180  sub modifiable_userdata_row {
             }              }
         }          }
     }      }
        
     my $total = scalar(@fields);      for (my $i=0; $i<@fields; $i++) {
     for (my $i=0; $i<$total; $i++) {          my $rem = $i%($numinrow);
         $rem = $i%($numinrow);  
         if ($rem == 0) {          if ($rem == 0) {
             if ($i > 0) {              if ($i > 0) {
                 $output .= '</tr>';                  $output .= '</tr>';
Line 8180  sub modifiable_userdata_row { Line 6192  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 8212  sub modifiable_userdata_row { Line 6224  sub modifiable_userdata_row {
                        '</label>';                         '</label>';
         }          }
         $output .= '</span></td>';          $output .= '</span></td>';
           $rem = @fields%($numinrow);
     }      }
     $rem = $total%$numinrow;      my $colsleft = $numinrow - $rem;
     my $colsleft;      if ($colsleft > 1 ) {
     if ($rem) {  
         $colsleft = $numinrow - $rem;  
     }  
     if ($colsleft > 1) {  
         $output .= '<td colspan="'.$colsleft.'" class="LC_left_item">'.          $output .= '<td colspan="'.$colsleft.'" class="LC_left_item">'.
                    '&nbsp;</td>';                     '&nbsp;</td>';
     } elsif ($colsleft == 1) {      } elsif ($colsleft == 1) {
Line 8229  sub modifiable_userdata_row { Line 6238  sub modifiable_userdata_row {
 }  }
   
 sub insttypes_row {  sub insttypes_row {
     my ($settings,$types,$usertypes,$dom,$numinrow,$othertitle,$context,$rowtotal,$onclick,      my ($settings,$types,$usertypes,$dom,$numinrow,$othertitle,$context,$rownum) = @_;
         $customcss,$rowstyle) = @_;  
     my %lt = &Apache::lonlocal::texthash (      my %lt = &Apache::lonlocal::texthash (
                       cansearch => 'Users allowed to search',                        cansearch => 'Users allowed to search',
                       statustocreate => 'Institutional affiliation(s) able to create own account (login/SSO)',                        statustocreate => 'Institutional affiliation(s) able to create own account (login/SSO)',
                       lockablenames => 'User preference to lock name',                        lockablenames => 'User preference to lock name',
                       selfassign    => 'Self-reportable affiliations',  
                       overrides     => "Override domain's helpdesk settings based on requester's affiliation",  
              );               );
     my $showdom;      my $showdom;
     if ($context eq 'cansearch') {      if ($context eq 'cansearch') {
Line 8246  sub insttypes_row { Line 6252  sub insttypes_row {
     if ($context eq 'statustocreate') {      if ($context eq 'statustocreate') {
         $class = 'LC_right_item';          $class = 'LC_right_item';
     }      }
     my $css_class;      my $css_class = ' class="LC_odd_row"';
     if ($$rowtotal%2) {      if ($rownum ne '') { 
         $css_class = 'LC_odd_row';          $css_class = ($rownum%2? ' class="LC_odd_row"':'');
     }  
     if ($customcss) {  
         $css_class .= ' '.$customcss;  
     }  
     $css_class =~ s/^\s+//;  
     if ($css_class) {  
         $css_class = ' class="'.$css_class.'"';  
     }  
     if ($rowstyle) {  
         $css_class .= ' style="'.$rowstyle.'"';  
     }  
     if ($onclick) {  
         $onclick = 'onclick="'.$onclick.'" ';  
     }      }
     my $output = '<tr'.$css_class.'>'.      my $output = '<tr'.$css_class.'>'.
                  '<td>'.$lt{$context}.$showdom.                   '<td>'.$lt{$context}.$showdom.
Line 8283  sub insttypes_row { Line 6276  sub insttypes_row {
                         if (grep(/^\Q$types->[$i]\E$/,@{$settings->{$context}})) {                          if (grep(/^\Q$types->[$i]\E$/,@{$settings->{$context}})) {
                             $check = ' checked="checked" ';                              $check = ' checked="checked" ';
                         }                          }
                     } elsif (ref($settings->{$context}) eq 'HASH') {  
                         if (ref($settings->{$context}->{$types->[$i]}) eq 'HASH') {  
                             $check = ' checked="checked" ';  
                         }  
                     } elsif ($context eq 'statustocreate') {                      } elsif ($context eq 'statustocreate') {
                         $check = ' checked="checked" ';                          $check = ' checked="checked" ';
                     }                      }
Line 8294  sub insttypes_row { Line 6283  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.'/>'.
                            $usertypes->{$types->[$i]}.'</label></span></td>';                             $usertypes->{$types->[$i]}.'</label></span></td>';
             }              }
         }          }
         $rem = @{$types}%($numinrow);          $rem = @{$types}%($numinrow);
     }      }
     my $colsleft = $numinrow - $rem;      my $colsleft = $numinrow - $rem;
     if ($context eq 'overrides') {      if (($rem == 0) && (@{$types} > 0)) {
         if ($colsleft > 1) {          $output .= '<tr>';
             $output .= '<td colspan="'.$colsleft.'" class="LC_left_item">';      }
         } else {      if ($colsleft > 1) {
             $output .= '<td class="LC_left_item">';          $output .= '<td colspan="'.$colsleft.'" class="LC_left_item">';
         }  
         $output .= '&nbsp;';  
     } else {      } else {
         if ($rem == 0) {          $output .= '<td class="LC_left_item">';
             $output .= '<tr>';      }
         }      my $defcheck = ' ';
         if ($colsleft > 1) {      if (ref($settings) eq 'HASH') {  
             $output .= '<td colspan="'.$colsleft.'" class="LC_left_item">';          if (ref($settings->{$context}) eq 'ARRAY') {
         } else {              if (grep(/^default$/,@{$settings->{$context}})) {
             $output .= '<td class="LC_left_item">';  
         }  
         my $defcheck = ' ';  
         if (ref($settings) eq 'HASH') {    
             if (ref($settings->{$context}) eq 'ARRAY') {  
                 if (grep(/^default$/,@{$settings->{$context}})) {  
                     $defcheck = ' checked="checked" ';  
                 }  
             } elsif ($context eq 'statustocreate') {  
                 $defcheck = ' checked="checked" ';                  $defcheck = ' checked="checked" ';
             }              }
           } elsif ($context eq 'statustocreate') {
               $defcheck = ' checked="checked" ';
         }          }
         $output .= '<span class="LC_nobreak"><label>'.  
                    '<input type="checkbox" name="'.$context.'" '.  
                    'value="default"'.$defcheck.$onclick.' />'.  
                    $othertitle.'</label></span>';  
     }      }
     $output .= '</td></tr></table></td></tr>';      $output .= '<span class="LC_nobreak"><label>'.
                  '<input type="checkbox" name="'.$context.'" '.
                  'value="default"'.$defcheck.'/>'.
                  $othertitle.'</label></span></td>'.
                  '</tr></table></td></tr>';
     return $output;      return $output;
 }  }
   
Line 8617  sub modify_login { Line 6597  sub modify_login {
             } elsif ($currheadtagurls{$lonhost}) {              } elsif ($currheadtagurls{$lonhost}) {
                 $loginhash{'login'}{'headtag'}{$lonhost}{'url'} = $currheadtagurls{$lonhost};                  $loginhash{'login'}{'headtag'}{$lonhost}{'url'} = $currheadtagurls{$lonhost};
                 if ($currexempt{$lonhost}) {                  if ($currexempt{$lonhost}) {
                     if ((!exists($possexempt{$lonhost})) || ($possexempt{$lonhost} ne $currexempt{$lonhost})) {                      if ((!exists($possexempt{$lonhost})) || ($possexempt{$lonhost} ne $currexempt{$lonhost})) { 
                         $changes{'headtag'}{$lonhost} = 1;                          $changes{'headtag'}{$lonhost} = 1;
                     }                      }
                 } elsif ($possexempt{$lonhost}) {                  } elsif ($possexempt{$lonhost}) {
Line 8849  sub modify_login { Line 6829  sub modify_login {
     return $resulttext;      return $resulttext;
 }  }
   
   
 sub check_exempt_addresses {  sub check_exempt_addresses {
     my ($iplist) = @_;      my ($iplist) = @_;
     $iplist =~ s/^\s+//;      $iplist =~ s/^\s+//;
Line 9292  sub check_configuser { Line 7273  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 9321  sub check_authorstatus { Line 7302  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 9366  sub publishlogo { Line 7347  sub publishlogo {
     } else {      } else {
         my $source = $filepath.'/'.$file;          my $source = $filepath.'/'.$file;
         my $logfile;          my $logfile;
         if (!open($logfile,">>",$source.'.log')) {          if (!open($logfile,">>$source".'.log')) {
             return (&mt('No write permission to Authoring Space'));              return (&mt('No write permission to Authoring Space'));
         }          }
         print $logfile          print $logfile
 "\n================= Publish ".localtime()." ================\n".  "\n================= Publish ".localtime()." ================\n".
 $env{'user.name'}.':'.$env{'user.domain'}."\n";  $env{'user.name'}.':'.$env{'user.domain'}."\n";
 # Save the file  # Save the file
         if (!open(FH,">",$source)) {          if (!open(FH,'>'.$source)) {
             &Apache::lonnet::logthis('Failed to create '.$source);              &Apache::lonnet::logthis('Failed to create '.$source);
             return (&mt('Failed to create file'));              return (&mt('Failed to create file'));
         }          }
Line 9434  $env{'user.name'}.':'.$env{'user.domain' Line 7415  $env{'user.name'}.':'.$env{'user.domain'
                 if ($fullwidth ne '' && $fullheight ne '') {                   if ($fullwidth ne '' && $fullheight ne '') { 
                     if ($fullwidth > $thumbwidth && $fullheight > $thumbheight) {                      if ($fullwidth > $thumbwidth && $fullheight > $thumbheight) {
                         my $thumbsize = $thumbwidth.'x'.$thumbheight;                          my $thumbsize = $thumbwidth.'x'.$thumbheight;
                         my @args = ('convert','-sample',$thumbsize,$inputfile,$outfile);                          system("convert -sample $thumbsize $inputfile $outfile");
                         system({$args[0]} @args);  
                         chmod(0660, $filepath.'/tn-'.$file);                          chmod(0660, $filepath.'/tn-'.$file);
                         if (-e $outfile) {                          if (-e $outfile) {
                             my $copyfile=$targetdir.'/tn-'.$file;                              my $copyfile=$targetdir.'/tn-'.$file;
Line 9450  $env{'user.name'}.':'.$env{'user.domain' Line 7430  $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 9462  $env{'user.name'}.':'.$env{'user.domain' Line 7443  $env{'user.name'}.':'.$env{'user.domain'
             $output = $versionresult;              $output = $versionresult;
         }          }
     }      }
     return ($output,$logourl);      return ($output,$logourl,$madethumb);
 }  }
   
 sub logo_versioning {  sub logo_versioning {
Line 9514  sub write_metadata { Line 7495  sub write_metadata {
     {      {
         print $logfile "\nWrite metadata file for ".$targetdir.'/'.$file;          print $logfile "\nWrite metadata file for ".$targetdir.'/'.$file;
         my $mfh;          my $mfh;
         if (open($mfh,">",$targetdir.'/'.$file.'.meta')) {          if (open($mfh,'>'.$targetdir.'/'.$file.'.meta')) {
             foreach (sort(keys(%metadatafields))) {              foreach (sort(keys(%metadatafields))) {
                 unless ($_=~/\./) {                  unless ($_=~/\./) {
                     my $unikey=$_;                      my $unikey=$_;
Line 9548  sub notifysubscribed { Line 7529  sub notifysubscribed {
         next unless (ref($targetsource) eq 'ARRAY');          next unless (ref($targetsource) eq 'ARRAY');
         my ($target,$source)=@{$targetsource};          my ($target,$source)=@{$targetsource};
         if ($source ne '') {          if ($source ne '') {
             if (open(my $logfh,">>",$source.'.log')) {              if (open(my $logfh,'>>'.$source.'.log')) {
                 print $logfh "\nCleanup phase: Notifications\n";                  print $logfh "\nCleanup phase: Notifications\n";
                 my @subscribed=&subscribed_hosts($target);                  my @subscribed=&subscribed_hosts($target);
                 foreach my $subhost (@subscribed) {                  foreach my $subhost (@subscribed) {
Line 9574  sub notifysubscribed { Line 7555  sub notifysubscribed {
 sub subscribed_hosts {  sub subscribed_hosts {
     my ($target) = @_;      my ($target) = @_;
     my @subscribed;      my @subscribed;
     if (open(my $fh,"<","$target.subscription")) {      if (open(my $fh,"<$target.subscription")) {
         while (my $subline=<$fh>) {          while (my $subline=<$fh>) {
             if ($subline =~ /^($match_lonid):/) {              if ($subline =~ /^($match_lonid):/) {
                 my $host = $1;                  my $host = $1;
Line 9616  sub modify_quotas { Line 7597  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 9665  sub modify_quotas { Line 7646  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 9759  sub modify_quotas { Line 7740  sub modify_quotas {
                                     my $newpos = $env{'form.'.$itemid};                                      my $newpos = $env{'form.'.$itemid};
                                     $newpos =~ s/\D+//g;                                      $newpos =~ s/\D+//g;
                                     foreach my $item ('subject','title','publisher','author') {                                      foreach my $item ('subject','title','publisher','author') {
                                         next if ((($item eq 'author') || ($item eq 'publisher')) &&                                          next if ((($item eq 'author') || ($item eq 'publisher')) && 
                                                  ($type eq 'templates'));                                                   ($type eq 'templates'));
                                         $confhash{$type}{$key}{$item} = $env{'form.'.$type.'_'.$item.'_'.$i};                                          $confhash{$type}{$key}{$item} = $env{'form.'.$type.'_'.$item.'_'.$i};
                                         if ($domconfig{$action}{$type}{$key}{$item} ne $confhash{$type}{$key}{$item}) {                                          if ($domconfig{$action}{$type}{$key}{$item} ne $confhash{$type}{$key}{$item}) {
Line 9773  sub modify_quotas { Line 7754  sub modify_quotas {
                                     #FIXME need to obsolete item in RES space                                      #FIXME need to obsolete item in RES space
                                 } elsif ($env{'form.'.$type.'_image_'.$i.'.filename'}) {                                  } elsif ($env{'form.'.$type.'_image_'.$i.'.filename'}) {
                                     my ($cdom,$cnum) = split(/_/,$key);                                      my ($cdom,$cnum) = split(/_/,$key);
                                     if (&Apache::lonnet::homeserver($cnum,$cdom) eq 'no_host') {                                      my ($imgurl,$error) = &process_textbook_image($r,$dom,$confname,$type.'_image_'.$i,
                                         $errors .= '<li><span class="LC_error">'.&mt('Image not saved: could not find textbook course').'</li>';                                                                                    $cdom,$cnum,$type,$configuserok,
                                     } else {                                                                                    $switchserver,$author_ok);
                                         my ($imgurl,$error) = &process_textbook_image($r,$dom,$confname,$type.'_image_'.$i,                                      if ($imgurl) {
                                                                                       $cdom,$cnum,$type,$configuserok,                                          $confhash{$type}{$key}{'image'} = $imgurl;
                                                                                       $switchserver,$author_ok);                                          $changes{$type}{$key} = 1; 
                                         if ($imgurl) {                                      }
                                             $confhash{$type}{$key}{'image'} = $imgurl;                                      if ($error) {
                                             $changes{$type}{$key} = 1;                                           &Apache::lonnet::logthis($error);
                                         }                                          $errors .= '<li><span class="LC_error">'.$error.'</span></li>';
                                         if ($error) {  
                                             &Apache::lonnet::logthis($error);  
                                             $errors .= '<li><span class="LC_error">'.$error.'</span></li>';  
                                         }  
                                     }                                       } 
                                 } elsif ($domconfig{$action}{$type}{$key}{'image'}) {                                  } elsif ($domconfig{$action}{$type}{$key}{'image'}) {
                                     $confhash{$type}{$key}{'image'} =                                       $confhash{$type}{$key}{'image'} = 
Line 9820  sub modify_quotas { Line 7797  sub modify_quotas {
                     if ($type eq 'textbooks') {                      if ($type eq 'textbooks') {
                         if ($env{'form.'.$type.'_addbook_image.filename'} ne '') {                          if ($env{'form.'.$type.'_addbook_image.filename'} ne '') {
                             my ($cdom,$cnum) = split(/_/,$newbook{$type});                              my ($cdom,$cnum) = split(/_/,$newbook{$type});
                             if (&Apache::lonnet::homeserver($cnum,$cdom) eq 'no_host') {                              my ($imageurl,$error) =
                                 $errors .= '<li><span class="LC_error">'.&mt('Image not saved: could not find textbook course').'</li>';                                  &process_textbook_image($r,$dom,$confname,$type.'_addbook_image',$cdom,$cnum,$type,
                             } else {                                                          $configuserok,$switchserver,$author_ok);
                                 my ($imageurl,$error) =                              if ($imageurl) {
                                     &process_textbook_image($r,$dom,$confname,$type.'_addbook_image',$cdom,$cnum,$type,                                  $confhash{$type}{$newbook{$type}}{'image'} = $imageurl;
                                                             $configuserok,$switchserver,$author_ok);                              }
                                 if ($imageurl) {                              if ($error) {
                                     $confhash{$type}{$newbook{$type}}{'image'} = $imageurl;                                  &Apache::lonnet::logthis($error);
                                 }                                  $errors .= '<li><span class="LC_error">'.$error.'</span></li>';
                                 if ($error) {  
                                     &Apache::lonnet::logthis($error);  
                                     $errors .= '<li><span class="LC_error">'.$error.'</span></li>';  
                                 }  
                             }                              }
                         }                          }
                     }                      }
Line 9912  sub modify_quotas { Line 7885  sub modify_quotas {
             }              }
             if ($env{'form.validationdc'}) {              if ($env{'form.validationdc'}) {
                 my $newval = $env{'form.validationdc'};                  my $newval = $env{'form.validationdc'};
                 my %domcoords = &Apache::lonnet::get_active_domroles($dom,['dc']);                  my %domcoords = &get_active_dcs($dom);
                 if (exists($domcoords{$newval})) {                  if (exists($domcoords{$newval})) {
                     $confhash{'validation'}{'dc'} = $newval;                      $confhash{'validation'}{'dc'} = $newval;
                 }                  }
Line 9936  sub modify_quotas { Line 7909  sub modify_quotas {
                     }                      }
                 } elsif ($confhash{'validation'}{'dc'} ne '') {                  } elsif ($confhash{'validation'}{'dc'} ne '') {
                     $changes{'validation'}{'dc'} = $confhash{'validation'}{'dc'};                      $changes{'validation'}{'dc'} = $confhash{'validation'}{'dc'};
                 }                  }  
             } else {              } else {
                 if (ref($domconfig{'requestcourses'}) eq 'HASH') {                  if (ref($domconfig{'requestcourses'}) eq 'HASH') {
                     if (ref($domconfig{'requestcourses'}{'validation'}) eq 'HASH') {                      if (ref($domconfig{'requestcourses'}{'validation'}) eq 'HASH') {
Line 10324  sub process_textbook_image { Line 8297  sub process_textbook_image {
         } elsif ($author_ok eq 'ok') {          } elsif ($author_ok eq 'ok') {
             my ($result,$imageurl) =              my ($result,$imageurl) =
                 &publishlogo($r,'upload',$caller,$dom,$confname,                  &publishlogo($r,'upload',$caller,$dom,$confname,
                              "$type/$cdom/$cnum/cover",$width,$height);                               "$type/$dom/$cnum/cover",$width,$height);
             if ($result eq 'ok') {              if ($result eq 'ok') {
                 $url = $imageurl;                  $url = $imageurl;
             } else {              } else {
Line 10342  sub process_textbook_image { Line 8315  sub process_textbook_image {
 sub modify_ltitools {  sub modify_ltitools {
     my ($r,$dom,$action,$lastactref,%domconfig) = @_;      my ($r,$dom,$action,$lastactref,%domconfig) = @_;
     my %domdefaults = &Apache::lonnet::get_domain_defaults($dom,1);      my %domdefaults = &Apache::lonnet::get_domain_defaults($dom,1);
     my ($newid,@allpos,%changes,%confhash,%encconfig,$errors,$resulttext);      my ($newid,@allpos,%changes,%confhash,$errors,$resulttext);
     my $confname = $dom.'-domainconfig';      my $confname = $dom.'-domainconfig';
     my $servadm = $r->dir_config('lonAdmEMail');      my $servadm = $r->dir_config('lonAdmEMail');
     my ($configuserok,$author_ok,$switchserver) = &config_check($dom,$confname,$servadm);      my ($configuserok,$author_ok,$switchserver) = &config_check($dom,$confname,$servadm);
Line 10352  sub modify_ltitools { Line 8325  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 10367  sub modify_ltitools { Line 8340  sub modify_ltitools {
             foreach my $item ('title','url','key','secret') {              foreach my $item ('title','url','key','secret') {
                 $env{'form.ltitools_add_'.$item} =~ s/(`)/'/g;                  $env{'form.ltitools_add_'.$item} =~ s/(`)/'/g;
                 if ($env{'form.ltitools_add_'.$item}) {                  if ($env{'form.ltitools_add_'.$item}) {
                     if (($item eq 'key') || ($item eq 'secret')) {                      $confhash{$newid}{$item} = $env{'form.ltitools_add_'.$item};
                         $encconfig{$newid}{$item} = $env{'form.ltitools_add_'.$item};  
                     } else {  
                         $confhash{$newid}{$item} = $env{'form.ltitools_add_'.$item};  
                     }  
                 }                  }
             }              }
             if ($env{'form.ltitools_add_version'} eq 'LTI-1p0') {              if ($env{'form.ltitools_add_version'} eq 'LTI-1p0') {
Line 10380  sub modify_ltitools { Line 8349  sub modify_ltitools {
             if ($env{'form.ltitools_add_msgtype'} eq 'basic-lti-launch-request') {              if ($env{'form.ltitools_add_msgtype'} eq 'basic-lti-launch-request') {
                 $confhash{$newid}{'msgtype'} = $env{'form.ltitools_add_msgtype'};                  $confhash{$newid}{'msgtype'} = $env{'form.ltitools_add_msgtype'};
             }              }
             foreach my $item ('width','height','linktext','explanation') {              foreach my $item ('width','height') {
                 $env{'form.ltitools_add_'.$item} =~ s/^\s+//;                  $env{'form.ltitools_add_'.$item} =~ s/^\s+//;
                 $env{'form.ltitools_add_'.$item} =~ s/\s+$//;                  $env{'form.ltitools_add_'.$item} =~ s/\s+$//;
                 if (($item eq 'width') || ($item eq 'height')) {                  if ($env{'form.ltitools_add_'.$item} =~ /^\d+$/) {
                     if ($env{'form.ltitools_add_'.$item} =~ /^\d+$/) {                      $confhash{$newid}{'display'}{$item} = $env{'form.ltitools_add_'.$item};
                         $confhash{$newid}{'display'}{$item} = $env{'form.ltitools_add_'.$item};  
                     }  
                 } else {  
                     if ($env{'form.ltitools_add_'.$item} ne '') {  
                         $confhash{$newid}{'display'}{$item} = $env{'form.ltitools_add_'.$item};  
                     }  
                 }                  }
             }              }
             if ($env{'form.ltitools_add_target'} eq 'window') {              if ($env{'form.ltitools_add_target'} eq 'window') {
                 $confhash{$newid}{'display'}{'target'} = $env{'form.ltitools_add_target'};                  $confhash{$newid}{'display'}{'target'} = $env{'form.ltitools_add_target'};
             } elsif ($env{'form.ltitools_add_target'} eq 'tab') {  
                 $confhash{$newid}{'display'}{'target'} = $env{'form.ltitools_add_target'};  
             } else {              } else {
                 $confhash{$newid}{'display'}{'target'} = 'iframe';                  $confhash{$newid}{'display'}{'target'} = 'iframe';
             }              }
Line 10407  sub modify_ltitools { Line 8368  sub modify_ltitools {
             }              }
             if ($env{'form.ltitools_add_image.filename'} ne '') {              if ($env{'form.ltitools_add_image.filename'} ne '') {
                 my ($imageurl,$error) =                  my ($imageurl,$error) =
                     &process_ltitools_image($r,$dom,$confname,'ltitools_add_image',$newid,                      &process_ltitools_image($r,$dom,$confname,'ltitools_add_image',$dom,
                                             $configuserok,$switchserver,$author_ok);                                              $configuserok,$switchserver,$author_ok);
                 if ($imageurl) {                  if ($imageurl) {
                     $confhash{$newid}{'image'} = $imageurl;                      $confhash{$newid}{'image'} = $imageurl;
Line 10426  sub modify_ltitools { Line 8387  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 10435  sub modify_ltitools { Line 8396  sub modify_ltitools {
                     }                      }
                 }                  }
             }              }
             my @courseconfig = &Apache::loncommon::get_env_multiple('form.ltitools_courseconfig');  
             foreach my $item (@courseconfig) {  
                 $confhash{$newid}{'crsconf'}{$item} = 1;  
             }  
             if ($env{'form.ltitools_add_custom'}) {              if ($env{'form.ltitools_add_custom'}) {
                 my $name = $env{'form.ltitools_add_custom_name'};                  my $name = $env{'form.ltitools_add_custom_name'};
                 my $value = $env{'form.ltitools_add_custom_value'};                  my $value = $env{'form.ltitools_add_custom_value'};
Line 10447  sub modify_ltitools { Line 8404  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 10461  sub modify_ltitools { Line 8418  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 10470  sub modify_ltitools { Line 8427  sub modify_ltitools {
         my $maxnum = $env{'form.ltitools_maxnum'};          my $maxnum = $env{'form.ltitools_maxnum'};
         for (my $i=0; $i<=$maxnum; $i++) {          for (my $i=0; $i<=$maxnum; $i++) {
             my $itemid = $env{'form.ltitools_id_'.$i};              my $itemid = $env{'form.ltitools_id_'.$i};
             $itemid =~ s/\D+//g;  
             if (ref($domconfig{$action}{$itemid}) eq 'HASH') {              if (ref($domconfig{$action}{$itemid}) eq 'HASH') {
                 if ($deletions{$itemid}) {                  if ($deletions{$itemid}) {
                     if ($domconfig{$action}{$itemid}{'image'}) {                      if ($domconfig{$action}{$itemid}{'image'}) {
Line 10481  sub modify_ltitools { Line 8437  sub modify_ltitools {
                 } else {                  } else {
                     my $newpos = $env{'form.ltitools_'.$itemid};                      my $newpos = $env{'form.ltitools_'.$itemid};
                     $newpos =~ s/\D+//g;                      $newpos =~ s/\D+//g;
                     foreach my $item ('title','url') {                      foreach my $item ('title','url','key','secret') {
                         $confhash{$itemid}{$item} = $env{'form.ltitools_'.$item.'_'.$i};                          $confhash{$itemid}{$item} = $env{'form.ltitools_'.$item.'_'.$i};
                         if ($domconfig{$action}{$itemid}{$item} ne $confhash{$itemid}{$item}) {                          if ($domconfig{$action}{$itemid}{$item} ne $confhash{$itemid}{$item}) {
                             $changes{$itemid} = 1;                              $changes{$itemid} = 1;
                         }                          }
                     }                      }
                     foreach my $item ('key','secret') {  
                         $encconfig{$itemid}{$item} = $env{'form.ltitools_'.$item.'_'.$i};  
                         if ($domconfig{$action}{$itemid}{$item} ne $encconfig{$itemid}{$item}) {  
                             $changes{$itemid} = 1;  
                         }  
                     }  
                     if ($env{'form.ltitools_version_'.$i} eq 'LTI-1p0') {                      if ($env{'form.ltitools_version_'.$i} eq 'LTI-1p0') {
                         $confhash{$itemid}{'version'} = $env{'form.ltitools_version_'.$i};                          $confhash{$itemid}{'version'} = $env{'form.ltitools_version_'.$i};
                     }                      }
Line 10511  sub modify_ltitools { Line 8461  sub modify_ltitools {
                             } else {                              } else {
                                 $changes{$itemid} = 1;                                  $changes{$itemid} = 1;
                             }                              }
                         } elsif (ref($domconfig{$action}{$itemid}{'display'}) eq 'HASH') {  
                             if ($domconfig{$action}{$itemid}{'display'}{$size} ne '') {  
                                 $changes{$itemid} = 1;  
                             }  
                         }  
                     }  
                     foreach my $item ('linktext','explanation') {  
                         $env{'form.ltitools_'.$item.'_'.$i} =~ s/^\s+//;  
                         $env{'form.ltitools_'.$item.'_'.$i} =~ s/\s+$//;  
                         if ($env{'form.ltitools_'.$item.'_'.$i} ne '') {  
                             $confhash{$itemid}{'display'}{$item} = $env{'form.ltitools_'.$item.'_'.$i};  
                             if (ref($domconfig{$action}{$itemid}{'display'}) eq 'HASH') {  
                                 if ($domconfig{$action}{$itemid}{'display'}{$item} ne $confhash{$itemid}{'display'}{$item}) {  
                                     $changes{$itemid} = 1;  
                                 }  
                             } else {  
                                 $changes{$itemid} = 1;  
                             }  
                         } elsif (ref($domconfig{$action}{$itemid}{'display'}) eq 'HASH') {  
                             if ($domconfig{$action}{$itemid}{'display'}{$item} ne '') {  
                                 $changes{$itemid} = 1;  
                             }  
                         }                          }
                     }                      }
                     if ($env{'form.ltitools_target_'.$i} eq 'window') {                      if ($env{'form.ltitools_target_'.$i} eq 'window') {
                         $confhash{$itemid}{'display'}{'target'} = $env{'form.ltitools_target_'.$i};                          $confhash{$itemid}{'display'}{'target'} = $env{'form.ltitools_target_'.$i};
                     } elsif ($env{'form.ltitools_target_'.$i} eq 'tab') {  
                         $confhash{$itemid}{'display'}{'target'} = $env{'form.ltitools_target_'.$i};  
                     } else {                      } else {
                         $confhash{$itemid}{'display'}{'target'} = 'iframe';                          $confhash{$itemid}{'display'}{'target'} = 'iframe';
                     }                      }
Line 10557  sub modify_ltitools { Line 8483  sub modify_ltitools {
                             $changes{$itemid} = 1;                              $changes{$itemid} = 1;
                         }                          }
                     }                      }
                     my @courseconfig = &Apache::loncommon::get_env_multiple('form.ltitools_courseconfig_'.$i);  
                     foreach my $item ('label','title','target','linktext','explanation') {  
                         if (grep(/^\Q$item\E$/,@courseconfig)) {  
                             $confhash{$itemid}{'crsconf'}{$item} = 1;  
                             if (ref($domconfig{$action}{$itemid}{'crsconf'}) eq 'HASH') {  
                                 if ($domconfig{$action}{$itemid}{'crsconf'}{$item} ne $confhash{$itemid}{'crsconf'}{$item}) {  
                                     $changes{$itemid} = 1;  
                                 }  
                             } else {  
                                 $changes{$itemid} = 1;  
                             }  
                         }  
                     }  
                     my @fields = &Apache::loncommon::get_env_multiple('form.ltitools_fields_'.$i);                      my @fields = &Apache::loncommon::get_env_multiple('form.ltitools_fields_'.$i);
                     foreach my $field (@fields) {                      foreach my $field (@fields) {
                         if ($possfield{$field}) {                          if ($possfield{$field}) {
Line 10638  sub modify_ltitools { Line 8551  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 10647  sub modify_ltitools { Line 8560  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 10697  sub modify_ltitools { Line 8610  sub modify_ltitools {
     my $putresult = &Apache::lonnet::put_dom('configuration',\%ltitoolshash,      my $putresult = &Apache::lonnet::put_dom('configuration',\%ltitoolshash,
                                              $dom);                                               $dom);
     if ($putresult eq 'ok') {      if ($putresult eq 'ok') {
         my %ltienchash = (  
                              $action => { %encconfig }  
                          );  
         &Apache::lonnet::put_dom('encconfig',\%ltienchash,$dom);  
         if (keys(%changes) > 0) {          if (keys(%changes) > 0) {
             my $cachetime = 24*60*60;              my $cachetime = 24*60*60;
             my %ltiall = %confhash;              &Apache::lonnet::do_cache_new('ltitools',$dom,\%confhash,$cachetime);
             foreach my $id (keys(%ltiall)) {  
                 if (ref($encconfig{$id}) eq 'HASH') {  
                     foreach my $item ('key','secret') {  
                         $ltiall{$id}{$item} = $encconfig{$id}{$item};  
                     }  
                 }  
             }  
             &Apache::lonnet::do_cache_new('ltitools',$dom,\%ltiall,$cachetime);  
             if (ref($lastactref) eq 'HASH') {              if (ref($lastactref) eq 'HASH') {
                 $lastactref->{'ltitools'} = 1;                  $lastactref->{'ltitools'} = 1;
             }              }
Line 10722  sub modify_ltitools { Line 8623  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 10735  sub modify_ltitools { Line 8636  sub modify_ltitools {
                     $resulttext .= '</li><ul>';                      $resulttext .= '</li><ul>';
                     my $position = $pos + 1;                      my $position = $pos + 1;
                     $resulttext .= '<li>'.&mt('Order: [_1]',$position).'</li>';                      $resulttext .= '<li>'.&mt('Order: [_1]',$position).'</li>';
                     foreach my $item ('version','msgtype','url') {                      foreach my $item ('version','msgtype','url','key') {
                         if ($confhash{$itemid}{$item} ne '') {                          if ($confhash{$itemid}{$item} ne '') {
                             $resulttext .= '<li>'.$lt{$item}.':&nbsp;'.$confhash{$itemid}{$item}.'</li>';                              $resulttext .= '<li>'.$lt{$item}.':&nbsp;'.$confhash{$itemid}{$item}.'</li>';
                         }                          }
                     }                      }
                     if ($encconfig{$itemid}{'key'} ne '') {                      if ($confhash{$itemid}{'secret'} ne '') {
                         $resulttext .= '<li>'.$lt{'key'}.':&nbsp;'.$encconfig{$itemid}{'key'}.'</li>';  
                     }  
                     if ($encconfig{$itemid}{'secret'} ne '') {  
                         $resulttext .= '<li>'.$lt{'secret'}.':&nbsp;';                          $resulttext .= '<li>'.$lt{'secret'}.':&nbsp;';
                         my $num = length($encconfig{$itemid}{'secret'});                          my $num = length($confhash{$itemid}{'secret'});
                         $resulttext .= ('*'x$num).'</li>';                          $resulttext .= ('*'x$num).'</li>';
                     }                      }
                     $resulttext .= '<li>'.&mt('Configurable in course:');  
                     my @possconfig = ('label','title','target','linktext','explanation');  
                     my $numconfig = 0;  
                     if (ref($confhash{$itemid}{'crsconf'}) eq 'HASH') {  
                         foreach my $item (@possconfig) {  
                             if ($confhash{$itemid}{'crsconf'}{$item}) {  
                                 $numconfig ++;  
                                 $resulttext .= ' "'.$lt{'crs'.$item}.'"';  
                             }  
                         }  
                     }  
                     if (!$numconfig) {  
                         $resulttext .= &mt('None');  
                     }  
                     $resulttext .= '</li>';  
                     foreach my $item ('passback','roster') {                      foreach my $item ('passback','roster') {
                         $resulttext .= '<li>'.$lt{$item}.'&nbsp;';                          $resulttext .= '<li>'.$lt{$item}.'&nbsp;';
                         if ($confhash{$itemid}{$item}) {                          if ($confhash{$itemid}{$item}) {
Line 10778  sub modify_ltitools { Line 8661  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 10788  sub modify_ltitools { Line 8671  sub modify_ltitools {
                             $displaylist =~ s/,$//;                              $displaylist =~ s/,$//;
                             $resulttext .= '<li>'.$displaylist.'</li>';                              $resulttext .= '<li>'.$displaylist.'</li>';
                         }                          }
                         foreach my $item ('linktext','explanation') {                      } 
                             if ($confhash{$itemid}{'display'}{$item}) {  
                                 $resulttext .= '<li>'.$lt{$item}.':&nbsp;'.$confhash{$itemid}{'display'}{$item}.'</li>';  
                             }  
                         }  
                     }  
                     if (ref($confhash{$itemid}{'fields'}) eq 'HASH') {                      if (ref($confhash{$itemid}{'fields'}) eq 'HASH') {
                         my $fieldlist;                          my $fieldlist;
                         foreach my $field (@allfields) {                          foreach my $field (@allfields) {
Line 10815  sub modify_ltitools { Line 8693  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 10824  sub modify_ltitools { Line 8702  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 10890  sub get_ltitools_id { Line 8768  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 10935  sub modify_autoenroll { Line 8813  sub modify_autoenroll {
     my $autorun = &Apache::lonnet::auto_run(undef,$dom),      my $autorun = &Apache::lonnet::auto_run(undef,$dom),
     my %title = ( run => 'Auto-enrollment active',      my %title = ( run => 'Auto-enrollment active',
                   sender => 'Sender for notification messages',                    sender => 'Sender for notification messages',
                   coowners => 'Automatic assignment of co-ownership to instructors of record (institutional data)',                    coowners => 'Automatic assignment of co-ownership to instructors of record (institutional data)');
                   failsafe => 'Failsafe for no drops if institutional data missing for a section');  
     my @offon = ('off','on');      my @offon = ('off','on');
     my $sender_uname = $env{'form.sender_uname'};      my $sender_uname = $env{'form.sender_uname'};
     my $sender_domain = $env{'form.sender_domain'};      my $sender_domain = $env{'form.sender_domain'};
Line 10946  sub modify_autoenroll { Line 8823  sub modify_autoenroll {
         $sender_domain = '';          $sender_domain = '';
     }      }
     my $coowners = $env{'form.autoassign_coowners'};      my $coowners = $env{'form.autoassign_coowners'};
     my $failsafe = $env{'form.autoenroll_failsafe'};  
     $failsafe =~ s{^\s+|\s+$}{}g;  
     if ($failsafe =~ /\D/) {  
         undef($failsafe);  
     }  
     my %autoenrollhash =  (      my %autoenrollhash =  (
                        autoenroll => { 'run' => $env{'form.autoenroll_run'},                         autoenroll => { 'run' => $env{'form.autoenroll_run'},
                                        'sender_uname' => $sender_uname,                                         'sender_uname' => $sender_uname,
                                        'sender_domain' => $sender_domain,                                         'sender_domain' => $sender_domain,
                                        'co-owners' => $coowners,                                         'co-owners' => $coowners,
                                        'autofailsafe' => $failsafe,  
                                 }                                  }
                      );                       );
     my $putresult = &Apache::lonnet::put_dom('configuration',\%autoenrollhash,      my $putresult = &Apache::lonnet::put_dom('configuration',\%autoenrollhash,
Line 10983  sub modify_autoenroll { Line 8854  sub modify_autoenroll {
             }              }
         } elsif ($coowners) {          } elsif ($coowners) {
             $changes{'coowners'} = 1;              $changes{'coowners'} = 1;
         }          }      
         if ($currautoenroll{'autofailsafe'} ne $failsafe) {  
             $changes{'autofailsafe'} = 1;  
         }  
         if (keys(%changes) > 0) {          if (keys(%changes) > 0) {
             $resulttext = &mt('Changes made:').'<ul>';              $resulttext = &mt('Changes made:').'<ul>';
             if ($changes{'run'}) {              if ($changes{'run'}) {
Line 11006  sub modify_autoenroll { Line 8874  sub modify_autoenroll {
                     $lastactref->{'domainconfig'} = 1;                      $lastactref->{'domainconfig'} = 1;
                 }                  }
             }              }
             if ($changes{'autofailsafe'}) {  
                 if ($failsafe ne '') {  
                     $resulttext .= '<li>'.&mt('Failsafe for no drops if institutional data missing for a section set to: [_1]',$failsafe).'</li>';  
                 } else {  
                     $resulttext .= '<li>'.&mt('Failsafe for no drops if institutional data missing for a section: deleted');  
                 }  
                 &Apache::lonnet::get_domain_defaults($dom,1);  
                 if (ref($lastactref) eq 'HASH') {  
                     $lastactref->{'domdefaults'} = 1;  
                 }  
             }  
             $resulttext .= '</ul>';              $resulttext .= '</ul>';
         } else {          } else {
             $resulttext = &mt('No changes made to auto-enrollment settings');              $resulttext = &mt('No changes made to auto-enrollment settings');
Line 11232  sub modify_autocreate { Line 9089  sub modify_autocreate {
         $newvals{$item} = 0 if ($newvals{$item} eq '');          $newvals{$item} = 0 if ($newvals{$item} eq '');
     }      }
     $newvals{'xmldc'} = $env{'form.autocreate_xmldc'};      $newvals{'xmldc'} = $env{'form.autocreate_xmldc'};
     my %domcoords = &Apache::lonnet::get_active_domroles($dom,['dc']);      my %domcoords = &get_active_dcs($dom);
     unless (exists($domcoords{$newvals{'xmldc'}})) {      unless (exists($domcoords{$newvals{'xmldc'}})) {
         $newvals{'xmldc'} = '';          $newvals{'xmldc'} = '';
     }       } 
Line 11289  sub modify_autocreate { Line 9146  sub modify_autocreate {
 }  }
   
 sub modify_directorysrch {  sub modify_directorysrch {
     my ($dom,$lastactref,%domconfig) = @_;      my ($dom,%domconfig) = @_;
     my ($resulttext,%changes);      my ($resulttext,%changes);
     my %currdirsrch;      my %currdirsrch;
     if (ref($domconfig{'directorysrch'}) eq 'HASH') {      if (ref($domconfig{'directorysrch'}) eq 'HASH') {
Line 11297  sub modify_directorysrch { Line 9154  sub modify_directorysrch {
             $currdirsrch{$key} = $domconfig{'directorysrch'}{$key};              $currdirsrch{$key} = $domconfig{'directorysrch'}{$key};
         }          }
     }      }
     my %title = ( available => 'Institutional directory search available',      my %title = ( available => 'Directory search available',
                   localonly => 'Other domains can search institution',                    localonly => 'Other domains can search',
                   lcavailable => 'LON-CAPA directory search available',  
                   lclocalonly => 'Other domains can search LON-CAPA domain',  
                   searchby => 'Search types',                    searchby => 'Search types',
                   searchtypes => 'Search latitude');                    searchtypes => 'Search latitude');
     my @offon = ('off','on');      my @offon = ('off','on');
Line 11374  sub modify_directorysrch { Line 9229  sub modify_directorysrch {
     my %dirsrch_hash =  (      my %dirsrch_hash =  (
             directorysrch => { available => $env{'form.dirsrch_available'},              directorysrch => { available => $env{'form.dirsrch_available'},
                                cansearch => \@cansearch,                                 cansearch => \@cansearch,
                                localonly => $env{'form.dirsrch_instlocalonly'},                                 localonly => $env{'form.dirsrch_localonly'},
                                lclocalonly => $env{'form.dirsrch_domlocalonly'},  
                                lcavailable => $env{'form.dirsrch_domavailable'},  
                                searchby => \@searchby,                                 searchby => \@searchby,
                                searchtypes => \@searchtypes,                                 searchtypes => \@searchtypes,
                              }                               }
Line 11393  sub modify_directorysrch { Line 9246  sub modify_directorysrch {
                 $changes{'available'} = 1;                  $changes{'available'} = 1;
             }              }
         }          }
         if (exists($currdirsrch{'lcavailable'})) {  
             if ($currdirsrch{'lcavailable'} ne $env{'form.dirsrch_domavailable'}) {  
                 $changes{'lcavailable'} = 1;  
             }  
         } else {  
             if ($env{'form.dirsrch_lcavailable'} eq '1') {  
                 $changes{'lcavailable'} = 1;  
             }  
         }  
         if (exists($currdirsrch{'localonly'})) {          if (exists($currdirsrch{'localonly'})) {
             if ($currdirsrch{'localonly'} ne $env{'form.dirsrch_instlocalonly'}) {               if ($currdirsrch{'localonly'} ne $env{'form.dirsrch_localonly'}) {
                 $changes{'localonly'} = 1;                   $changes{'localonly'} = 1;
             }               }
         } else {          } else {
             if ($env{'form.dirsrch_instlocalonly'} eq '1') {              if ($env{'form.dirsrch_localonly'} eq '1') {
                 $changes{'localonly'} = 1;                  $changes{'localonly'} = 1;
             }              }
         }          }
         if (exists($currdirsrch{'lclocalonly'})) {  
             if ($currdirsrch{'lclocalonly'} ne $env{'form.dirsrch_domlocalonly'}) {  
                 $changes{'lclocalonly'} = 1;  
             }  
         } else {  
             if ($env{'form.dirsrch_domlocalonly'} eq '1') {  
                 $changes{'lclocalonly'} = 1;  
             }  
         }  
         if (keys(%changes) > 0) {          if (keys(%changes) > 0) {
             $resulttext = &mt('Changes made:').'<ul>';              $resulttext = &mt('Changes made:').'<ul>';
             if ($changes{'available'}) {              if ($changes{'available'}) {
                 $resulttext .= '<li>'.&mt("$title{'available'} set to: $offon[$env{'form.dirsrch_available'}]").'</li>';                  $resulttext .= '<li>'.&mt("$title{'available'} set to: $offon[$env{'form.dirsrch_available'}]").'</li>';
             }              }
             if ($changes{'lcavailable'}) {  
                 $resulttext .= '<li>'.&mt("$title{'lcavailable'} set to: $offon[$env{'form.dirsrch_domavailable'}]").'</li>';  
             }  
             if ($changes{'localonly'}) {              if ($changes{'localonly'}) {
                 $resulttext .= '<li>'.&mt("$title{'localonly'} set to: $otherdoms[$env{'form.dirsrch_instlocalonly'}]").'</li>';                  $resulttext .= '<li>'.&mt("$title{'localonly'} set to: $otherdoms[$env{'form.dirsrch_localonly'}]").'</li>';
             }  
             if ($changes{'lclocalonly'}) {  
                 $resulttext .= '<li>'.&mt("$title{'lclocalonly'} set to: $otherdoms[$env{'form.dirsrch_domlocalonly'}]").'</li>';  
             }              }
   
             if (ref($changes{'cansearch'}) eq 'ARRAY') {              if (ref($changes{'cansearch'}) eq 'ARRAY') {
                 my $chgtext;                  my $chgtext;
                 if (ref($usertypes) eq 'HASH') {                  if (ref($usertypes) eq 'HASH') {
Line 11483  sub modify_directorysrch { Line 9313  sub modify_directorysrch {
                 $resulttext .= '<li>'.&mt($title{'searchtypes'}.' set to: "[_1]"',$chgtext).'</li>';                  $resulttext .= '<li>'.&mt($title{'searchtypes'}.' set to: "[_1]"',$chgtext).'</li>';
             }              }
             $resulttext .= '</ul>';              $resulttext .= '</ul>';
             &Apache::lonnet::do_cache_new('directorysrch',$dom,$dirsrch_hash{'directorysrch'},3600);  
             if (ref($lastactref) eq 'HASH') {  
                 $lastactref->{'directorysrch'} = 1;  
             }  
         } else {          } else {
             $resulttext = &mt('No changes made to directory search settings');              $resulttext = &mt('No changes made to institution directory search settings');
         }          }
     } else {      } else {
         $resulttext = '<span class="LC_error">'.          $resulttext = '<span class="LC_error">'.
Line 11505  sub modify_contacts { Line 9331  sub modify_contacts {
             $currsetting{$key} = $domconfig{'contacts'}{$key};              $currsetting{$key} = $domconfig{'contacts'}{$key};
         }          }
     }      }
     my (%others,%to,%bcc,%includestr,%includeloc);      my (%others,%to,%bcc);
     my @contacts = ('supportemail','adminemail');      my @contacts = ('supportemail','adminemail');
     my @mailings = ('errormail','packagesmail','helpdeskmail','otherdomsmail',      my @mailings = ('errormail','packagesmail','helpdeskmail','lonstatusmail',
                     'lonstatusmail','requestsmail','updatesmail','idconflictsmail','hostipmail');                      'requestsmail','updatesmail','idconflictsmail');
     my @toggles = ('reporterrors','reportupdates');      my @toggles = ('reporterrors','reportupdates');
     my ($fields,$fieldtitles,$fieldoptions,$possoptions) = &helpform_fields();  
     foreach my $type (@mailings) {      foreach my $type (@mailings) {
         @{$newsetting{$type}} =           @{$newsetting{$type}} = 
             &Apache::loncommon::get_env_multiple('form.'.$type);              &Apache::loncommon::get_env_multiple('form.'.$type);
Line 11520  sub modify_contacts { Line 9345  sub modify_contacts {
             } else {              } else {
                 $contacts_hash{contacts}{$type}{$item} = 0;                  $contacts_hash{contacts}{$type}{$item} = 0;
             }              }
         }          }  
         $others{$type} = $env{'form.'.$type.'_others'};          $others{$type} = $env{'form.'.$type.'_others'};
         $contacts_hash{contacts}{$type}{'others'} = $others{$type};          $contacts_hash{contacts}{$type}{'others'} = $others{$type};
         if (($type eq 'helpdeskmail') || ($type eq 'otherdomsmail')) {          if ($type eq 'helpdeskmail') {
             $bcc{$type} = $env{'form.'.$type.'_bcc'};              $bcc{$type} = $env{'form.'.$type.'_bcc'};
             $contacts_hash{contacts}{$type}{'bcc'} = $bcc{$type};              $contacts_hash{contacts}{$type}{'bcc'} = $bcc{$type};
             if (($env{'form.'.$type.'_includestr'} ne '') && ($env{'form.'.$type.'_includeloc'} =~ /^s|b$/)) {  
                 $includestr{$type} = $env{'form.'.$type.'_includestr'};  
                 $includeloc{$type} = $env{'form.'.$type.'_includeloc'};  
                 $contacts_hash{contacts}{$type}{'include'} = $includeloc{$type}.':'.&escape($includestr{$type});  
             }  
         }          }
     }      }
     foreach my $item (@contacts) {      foreach my $item (@contacts) {
Line 11542  sub modify_contacts { Line 9362  sub modify_contacts {
             $contacts_hash{'contacts'}{$item} = $env{'form.'.$item};              $contacts_hash{'contacts'}{$item} = $env{'form.'.$item};
         }          }
     }      }
     if ((ref($fields) eq 'ARRAY') && (ref($possoptions) eq 'HASH')) {  
         foreach my $field (@{$fields}) {  
             if (ref($possoptions->{$field}) eq 'ARRAY') {  
                 my $value = $env{'form.helpform_'.$field};  
                 $value =~ s/^\s+|\s+$//g;  
                 if (grep(/^\Q$value\E$/,@{$possoptions->{$field}})) {  
                     $contacts_hash{'contacts'}{'helpform'}{$field} = $value;  
                     if ($field eq 'screenshot') {  
                         $env{'form.helpform_maxsize'} =~ s/^\s+|\s+$//g;  
                         if ($env{'form.helpform_maxsize'} =~ /^\d+\.?\d*$/) {  
                             $contacts_hash{'contacts'}{'helpform'}{'maxsize'} = $env{'form.helpform_maxsize'};  
                         }  
                     }  
                 }  
             }  
         }  
     }  
     my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom);  
     my (@statuses,%usertypeshash,@overrides);  
     if ((ref($types) eq 'ARRAY') && (@{$types} > 0)) {  
         @statuses = @{$types};  
         if (ref($usertypes) eq 'HASH') {  
             %usertypeshash = %{$usertypes};  
         }  
     }  
     if (@statuses) {  
         my @possoverrides = &Apache::loncommon::get_env_multiple('form.overrides');  
         foreach my $type (@possoverrides) {  
             if (($type ne '') && (grep(/^\Q$type\E$/,@statuses))) {  
                 push(@overrides,$type);  
             }  
         }  
         if (@overrides) {  
             foreach my $type (@overrides) {  
                 my @standard = &Apache::loncommon::get_env_multiple('form.override_'.$type);  
                 foreach my $item (@contacts) {  
                     if (grep(/^\Q$item\E$/,@standard)) {  
                         $contacts_hash{'contacts'}{'overrides'}{$type}{$item} = 1;  
                         $newsetting{'override_'.$type}{$item} = 1;  
                     } else {  
                         $contacts_hash{'contacts'}{'overrides'}{$type}{$item} = 0;  
                         $newsetting{'override_'.$type}{$item} = 0;  
                     }  
                 }  
                 $contacts_hash{'contacts'}{'overrides'}{$type}{'others'} = $env{'form.override_'.$type.'_others'};  
                 $contacts_hash{'contacts'}{'overrides'}{$type}{'bcc'} = $env{'form.override_'.$type.'_bcc'};  
                 $newsetting{'override_'.$type}{'others'} = $env{'form.override_'.$type.'_others'};  
                 $newsetting{'override_'.$type}{'bcc'} = $env{'form.override_'.$type.'_bcc'};  
                 if (($env{'form.override_'.$type.'_includestr'} ne '') && ($env{'form.override_'.$type.'_includeloc'} =~ /^s|b$/)) {  
                     $includestr{$type} = $env{'form.override_'.$type.'_includestr'};  
                     $includeloc{$type} = $env{'form.override_'.$type.'_includeloc'};  
                     $contacts_hash{'contacts'}{'overrides'}{$type}{'include'} = $includeloc{$type}.':'.&escape($includestr{$type});  
                     $newsetting{'override_'.$type}{'include'} = $contacts_hash{'contacts'}{'overrides'}{$type}{'include'};  
                 }  
             }      
         }  
     }  
     if (keys(%currsetting) > 0) {      if (keys(%currsetting) > 0) {
         foreach my $item (@contacts) {          foreach my $item (@contacts) {
             if ($to{$item} ne $currsetting{$item}) {              if ($to{$item} ne $currsetting{$item}) {
Line 11618  sub modify_contacts { Line 9381  sub modify_contacts {
             if ($others{$type} ne $currsetting{$type}{'others'}) {              if ($others{$type} ne $currsetting{$type}{'others'}) {
                 push(@{$changes{$type}},'others');                  push(@{$changes{$type}},'others');
             }              }
             if (($type eq 'helpdeskmail') || ($type eq 'otherdomsmail')) {              if ($type eq 'helpdeskmail') {   
                 if ($bcc{$type} ne $currsetting{$type}{'bcc'}) {                  if ($bcc{$type} ne $currsetting{$type}{'bcc'}) {
                     push(@{$changes{$type}},'bcc');                       push(@{$changes{$type}},'bcc'); 
                 }                  }
                 my ($currloc,$currstr) = split(/:/,$currsetting{$type}{'include'},2);  
                 if (($includeloc{$type} ne $currloc) || (&escape($includestr{$type}) ne $currstr)) {  
                     push(@{$changes{$type}},'include');  
                 }  
             }  
         }  
         if (ref($fields) eq 'ARRAY') {  
             if (ref($currsetting{'helpform'}) eq 'HASH') {  
                 foreach my $field (@{$fields}) {  
                     if ($currsetting{'helpform'}{$field} ne $contacts_hash{'contacts'}{'helpform'}{$field}) {  
                         push(@{$changes{'helpform'}},$field);  
                     }  
                     if (($field eq 'screenshot') && ($contacts_hash{'contacts'}{'helpform'}{'screenshot'} ne 'no')) {  
                         if ($currsetting{'helpform'}{'maxsize'} ne $contacts_hash{'contacts'}{'helpform'}{'maxsize'}) {  
                             push(@{$changes{'helpform'}},'maxsize');  
                         }  
                     }  
                 }  
             } else {  
                 foreach my $field (@{$fields}) {  
                     if ($contacts_hash{'contacts'}{'helpform'}{$field} ne 'yes') {  
                         push(@{$changes{'helpform'}},$field);  
                     }  
                     if (($field eq 'screenshot') && ($contacts_hash{'contacts'}{'helpform'}{'screenshot'} ne 'no')) {  
                         if ($contacts_hash{'contacts'}{'helpform'}{'maxsize'} != 1) {  
                             push(@{$changes{'helpform'}},'maxsize');  
                         }  
                     }  
                 }  
             }  
         }  
         if (@statuses) {  
             if (ref($currsetting{'overrides'}) eq 'HASH') {  
                 foreach my $key (keys(%{$currsetting{'overrides'}})) {  
                     if (ref($currsetting{'overrides'}{$key}) eq 'HASH') {  
                         if (ref($newsetting{'override_'.$key}) eq 'HASH') {  
                             foreach my $item (@contacts,'bcc','others','include') {  
                                 if ($currsetting{'overrides'}{$key}{$item} ne $newsetting{'override_'.$key}{$item}) {  
                                     push(@{$changes{'overrides'}},$key);  
                                     last;  
                                 }  
                             }  
                         } else {  
                             push(@{$changes{'overrides'}},$key);  
                         }  
                     }  
                 }  
                 foreach my $key (@overrides) {  
                     unless (exists($currsetting{'overrides'}{$key})) {  
                         push(@{$changes{'overrides'}},$key);  
                     }  
                 }  
             } else {  
                 foreach my $key (@overrides) {  
                     push(@{$changes{'overrides'}},$key);  
                 }  
             }              }
         }          }
     } else {      } else {
Line 11687  sub modify_contacts { Line 9394  sub modify_contacts {
         $default{'errormail'} = 'adminemail';          $default{'errormail'} = 'adminemail';
         $default{'packagesmail'} = 'adminemail';          $default{'packagesmail'} = 'adminemail';
         $default{'helpdeskmail'} = 'supportemail';          $default{'helpdeskmail'} = 'supportemail';
         $default{'otherdomsmail'} = 'supportemail';  
         $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;
            }             }
         }          }
         foreach my $type (@mailings) {          foreach my $type (@mailings) {
             if ((@{$newsetting{$type}} != 1) || ($newsetting{$type}[0] ne $default{$type})) {              if ((@{$newsetting{$type}} != 1) || ($newsetting{$type}[0] ne $default{$type})) {
                  
                 push(@{$changes{$type}},@{$newsetting{$type}});                  push(@{$changes{$type}},@{$newsetting{$type}});
             }              }
             if ($others{$type} ne '') {              if ($others{$type} ne '') {
                 push(@{$changes{$type}},'others');                  push(@{$changes{$type}},'others');
             }              }
             if (($type eq 'helpdeskmail') || ($type eq 'otherdomsmail')) {              if ($type eq 'helpdeskmail') {
                 if ($bcc{$type} ne '') {                  if ($bcc{$type} ne '') {
                     push(@{$changes{$type}},'bcc');                      push(@{$changes{$type}},'bcc');
                 }                  }
                 if (($includeloc{$type} =~ /^b|s$/) && ($includestr{$type} ne '')) {  
                     push(@{$changes{$type}},'include');  
                 }  
             }  
         }  
         if (ref($fields) eq 'ARRAY') {  
             foreach my $field (@{$fields}) {  
                 if ($contacts_hash{'contacts'}{'helpform'}{$field} ne 'yes') {  
                     push(@{$changes{'helpform'}},$field);  
                 }  
                 if (($field eq 'screenshot') && ($contacts_hash{'contacts'}{'helpform'}{'screenshot'} ne 'no')) {  
                     if ($contacts_hash{'contacts'}{'helpform'}{'maxsize'} != 1) {  
                         push(@{$changes{'helpform'}},'maxsize');  
                     }  
                 }  
             }              }
         }          }
     }      }
Line 11754  sub modify_contacts { Line 9445  sub modify_contacts {
             }              }
             foreach my $type (@mailings) {              foreach my $type (@mailings) {
                 if (ref($changes{$type}) eq 'ARRAY') {                  if (ref($changes{$type}) eq 'ARRAY') {
                     if (($type eq 'helpdeskmail') || ($type eq 'otherdomsmail')) {                      $resulttext .= '<li>'.$titles->{$type}.': ';
                         $resulttext .= '<li>'.$titles->{$type}.' -- '.&mt('sent to').': ';  
                     } else {  
                         $resulttext .= '<li>'.$titles->{$type}.': ';  
                     }  
                     my @text;                      my @text;
                     foreach my $item (@{$newsetting{$type}}) {                      foreach my $item (@{$newsetting{$type}}) {
                         push(@text,$short_titles->{$item});                          push(@text,$short_titles->{$item});
Line 11766  sub modify_contacts { Line 9453  sub modify_contacts {
                     if ($others{$type} ne '') {                      if ($others{$type} ne '') {
                         push(@text,$others{$type});                          push(@text,$others{$type});
                     }                      }
                     if (@text) {                      $resulttext .= '<span class="LC_cusr_emph">'.
                         $resulttext .= '<span class="LC_cusr_emph">'.                                     join(', ',@text).'</span>';
                                        join(', ',@text).'</span>';                      if ($type eq 'helpdeskmail') {
                     }  
                     if (($type eq 'helpdeskmail') || ($type eq 'otherdomsmail')) {  
                         if ($bcc{$type} ne '') {                          if ($bcc{$type} ne '') {
                             my $bcctext;                              $resulttext .= '&nbsp;'.&mt('with Bcc to').': <span class="LC_cusr_emph">'.$bcc{$type}.'</span>';
                             if (@text) {  
                                 $bcctext = '&nbsp;'.&mt('with Bcc to');  
                             } else {  
                                 $bcctext = '(Bcc)';  
                             }  
                             $resulttext .= $bcctext.': <span class="LC_cusr_emph">'.$bcc{$type}.'</span>';  
                         } elsif (!@text) {  
                             $resulttext .= &mt('No one');  
                         }  
                         if ($includestr{$type} ne '') {  
                             if ($includeloc{$type} eq 'b') {  
                                 $resulttext .= '<br />'.&mt('Text automatically added to e-mail body:').' '.$includestr{$type};  
                             } elsif ($includeloc{$type} eq 's') {  
                                 $resulttext .= '<br />'.&mt('Text automatically added to e-mail subject:').' '.$includestr{$type};  
                             }  
                         }                          }
                     } elsif (!@text) {  
                         $resulttext .= &mt('No recipients');  
                     }                      }
                     $resulttext .= '</li>';                      $resulttext .= '</li>';
                 }                  }
             }              }
             if (ref($changes{'overrides'}) eq 'ARRAY') {  
                 my @deletions;  
                 foreach my $type (@{$changes{'overrides'}}) {  
                     if ($usertypeshash{$type}) {  
                         if (grep(/^\Q$type\E/,@overrides)) {  
                             $resulttext .= '<li>'.&mt("Overrides based on requester's affiliation set for [_1]",  
                                                       $usertypeshash{$type}).'<ul><li>';  
                             if (ref($newsetting{'override_'.$type}) eq 'HASH') {  
                                 my @text;  
                                 foreach my $item (@contacts) {  
                                     if ($newsetting{'override_'.$type}{$item}) {  
                                         push(@text,$short_titles->{$item});  
                                     }  
                                 }  
                                 if ($newsetting{'override_'.$type}{'others'} ne '') {  
                                     push(@text,$newsetting{'override_'.$type}{'others'});  
                                 }  
   
                                 if (@text) {  
                                     $resulttext .= &mt('Helpdesk e-mail sent to: [_1]',  
                                                        '<span class="LC_cusr_emph">'.join(', ',@text).'</span>');  
                                 }  
                                 if ($newsetting{'override_'.$type}{'bcc'} ne '') {  
                                     my $bcctext;  
                                     if (@text) {  
                                         $bcctext = '&nbsp;'.&mt('with Bcc to');  
                                     } else {  
                                         $bcctext = '(Bcc)';  
                                     }  
                                     $resulttext .= $bcctext.': <span class="LC_cusr_emph">'.$newsetting{'override_'.$type}{'bcc'}.'</span>';  
                                 } elsif (!@text) {  
                                      $resulttext .= &mt('Helpdesk e-mail sent to no one');  
                                 }  
                                 $resulttext .= '</li>';  
                                 if ($newsetting{'override_'.$type}{'include'} ne '') {  
                                     my ($loc,$str) = split(/:/,$newsetting{'override_'.$type}{'include'});  
                                     if ($loc eq 'b') {  
                                         $resulttext .= '<li>'.&mt('Text automatically added to e-mail body:').' '.&unescape($str).'</li>';  
                                     } elsif ($loc eq 's') {  
                                         $resulttext .= '<li>'.&mt('Text automatically added to e-mail subject:').' '.&unescape($str).'</li>';  
                                     }  
                                 }  
                             }  
                             $resulttext .= '</li></ul></li>';  
                         } else {  
                             push(@deletions,$usertypeshash{$type});  
                         }  
                     }  
                 }  
                 if (@deletions) {  
                     $resulttext .= '<li>'.&mt("Overrides based on requester's affiliation discontinued for: [_1]",  
                                               join(', ',@deletions)).'</li>';  
                 }  
             }  
             my @offon = ('off','on');              my @offon = ('off','on');
             if ($changes{'reporterrors'}) {              if ($changes{'reporterrors'}) {
                 $resulttext .= '<li>'.                  $resulttext .= '<li>'.
Line 11866  sub modify_contacts { Line 9480  sub modify_contacts {
                                         &mt('LON-CAPA core group - MSU'),600,500)).                                          &mt('LON-CAPA core group - MSU'),600,500)).
                                 '</li>';                                  '</li>';
             }              }
             if ((ref($changes{'helpform'}) eq 'ARRAY') && (ref($fields) eq 'ARRAY')) {  
                 my (@optional,@required,@unused,$maxsizechg);  
                 foreach my $field (@{$changes{'helpform'}}) {  
                     if ($field eq 'maxsize') {  
                         $maxsizechg = 1;  
                         next;  
                     }  
                     if ($contacts_hash{'contacts'}{'helpform'}{$field} eq 'yes') {  
                         push(@optional,$field);  
                     } elsif ($contacts_hash{'contacts'}{'helpform'}{$field} eq 'no') {  
                         push(@unused,$field);  
                     } elsif ($contacts_hash{'contacts'}{'helpform'}{$field} eq 'req') {  
                         push(@required,$field);  
                     }  
                 }  
                 if (@optional) {  
                     $resulttext .= '<li>'.  
                                    &mt('Help form fields changed to "Optional": [_1].',  
                                        '<span class="LC_cusr_emph">'.join(', ',map { $fieldtitles->{$_}; } @optional)).'</span>'.  
                                    '</li>';  
                 }  
                 if (@required) {  
                     $resulttext .= '<li>'.  
                                    &mt('Help form fields changed to "Required": [_1].',  
                                        '<span class="LC_cusr_emph">'.join(', ',map { $fieldtitles->{$_}; } @required)).'</span>'.  
                                    '</li>';  
                 }  
                 if (@unused) {  
                     $resulttext .= '<li>'.  
                                    &mt('Help form fields changed to "Not shown": [_1].',  
                                        '<span class="LC_cusr_emph">'.join(', ',map { $fieldtitles->{$_}; } @unused)).'</span>'.  
                                    '</li>';  
                 }  
                 if ($maxsizechg) {  
                     $resulttext .= '<li>'.  
                                    &mt('Max size for file uploaded to help form by logged-in user set to [_1] MB.',  
                                        $contacts_hash{'contacts'}{'helpform'}{'maxsize'}).  
                                    '</li>';  
                 }  
             }  
             $resulttext .= '</ul>';              $resulttext .= '</ul>';
         } else {          } else {
             $resulttext = &mt('No changes made to contacts and form settings');              $resulttext = &mt('No changes made to contact information');
         }          }
     } else {      } else {
         $resulttext = '<span class="LC_error">'.          $resulttext = '<span class="LC_error">'.
Line 11917  sub modify_contacts { Line 9491  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;  
                 }  
             }  
         } 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 />'.  
                                            &mt('Public key: [_1]',$confighash{'passwords'}{'recaptchapub'}).'</br>'.  
                                            &mt('Private key: [_1]',$confighash{'passwords'}{'recaptchapriv'}).'</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'},  
                                                                             $titles{custom},600,500);  
                             $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>';  
                             }  
                         }  
                     } 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 12446  sub modify_usercreation { Line 9500  sub modify_usercreation {
             if ($key eq 'cancreate') {              if ($key eq 'cancreate') {
                 if (ref($domconfig{'usercreation'}{$key}) eq 'HASH') {                  if (ref($domconfig{'usercreation'}{$key}) eq 'HASH') {
                     foreach my $item (keys(%{$domconfig{'usercreation'}{$key}})) {                      foreach my $item (keys(%{$domconfig{'usercreation'}{$key}})) {
                         if (($item eq 'requestcrs') || ($item eq 'course') || ($item eq 'author')) {                          if (($item eq 'selfcreate') || ($item eq 'statustocreate') ||
                             $curr_usercreation{$key}{$item} = $domconfig{'usercreation'}{$key}{$item};                              ($item eq 'captcha') || ($item eq 'recaptchakeys') ||
                         } else {                              ($item eq 'recaptchaversion')) {
                             $save_usercreate{$key}{$item} = $domconfig{'usercreation'}{$key}{$item};                              $save_usercreate{$key}{$item} = $domconfig{'usercreation'}{$key}{$item};
                           } else {
                               $curr_usercreation{$key}{$item} = $domconfig{'usercreation'}{$key}{$item};
                         }                          }
                     }                      }
                 }                  }
Line 12652  sub modify_usercreation { Line 9708  sub modify_usercreation {
 }  }
   
 sub modify_selfcreation {  sub modify_selfcreation {
     my ($dom,$lastactref,%domconfig) = @_;      my ($dom,%domconfig) = @_;
     my ($resulttext,$warningmsg,%curr_usercreation,%curr_usermodify,%curr_inststatus,%changes,%cancreate);      my ($resulttext,$warningmsg,%curr_usercreation,%curr_usermodify,%changes,%cancreate);
     my (%save_usercreate,%save_usermodify,%save_inststatus,@types,%usertypes);      my (%save_usercreate,%save_usermodify);
     my %domdefaults = &Apache::lonnet::get_domain_defaults($dom,1);      my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom);
     my ($othertitle,$usertypesref,$typesref) = &Apache::loncommon::sorted_inst_types($dom);      if (ref($types) eq 'ARRAY') {
     if (ref($typesref) eq 'ARRAY') {          $usertypes->{'default'} = $othertitle;
         @types = @{$typesref};          push(@{$types},'default');
     }  
     if (ref($usertypesref) eq 'HASH') {  
         %usertypes = %{$usertypesref};  
     }      }
     $usertypes{'default'} = $othertitle;  
 #  #
 # Retrieve current domain configuration for self-creation of usernames from $domconfig{'usercreation'}.  # Retrieve current domain configuration for self-creation of usernames from $domconfig{'usercreation'}.
 #  #
Line 12673  sub modify_selfcreation { Line 9725  sub modify_selfcreation {
                 if (ref($domconfig{'usercreation'}{$key}) eq 'HASH') {                  if (ref($domconfig{'usercreation'}{$key}) eq 'HASH') {
                     foreach my $item (keys(%{$domconfig{'usercreation'}{$key}})) {                      foreach my $item (keys(%{$domconfig{'usercreation'}{$key}})) {
                         if (($item eq 'selfcreate') || ($item eq 'statustocreate') ||                          if (($item eq 'selfcreate') || ($item eq 'statustocreate') ||
                             ($item eq 'captcha') || ($item eq 'recaptchakeys') ||                              ($item eq 'captcha') || ($item eq 'recaptchakeys') || 
                             ($item eq 'recaptchaversion') || ($item eq 'notify') ||                              ($item eq 'recaptchaversion') ||
                             ($item eq 'emailusername') || ($item eq 'shibenv') ||                              ($item eq 'emailusername') || ($item eq 'notify') ||
                             ($item eq 'selfcreateprocessing') || ($item eq 'emailverified') ||                              ($item eq 'selfcreateprocessing') || ($item eq 'shibenv')) {
                             ($item eq 'emailoptions') || ($item eq 'emaildomain')) {  
                             $curr_usercreation{$key}{$item} = $domconfig{'usercreation'}{$key}{$item};                              $curr_usercreation{$key}{$item} = $domconfig{'usercreation'}{$key}{$item};
                         } else {                          } else {
                             $save_usercreate{$key}{$item} = $domconfig{'usercreation'}{$key}{$item};                              $save_usercreate{$key}{$item} = $domconfig{'usercreation'}{$key}{$item};
Line 12703  sub modify_selfcreation { Line 9754  sub modify_selfcreation {
             }              }
         }          }
     }      }
 #  
 # Retrieve current domain configuration for institutional status types from $domconfig{'inststatus'}.  
 #  
     if (ref($domconfig{'inststatus'}) eq 'HASH') {  
         foreach my $key (keys(%{$domconfig{'inststatus'}})) {  
             if ($key eq 'inststatusguest') {  
                 $curr_inststatus{$key} = $domconfig{'inststatus'}{$key};  
             } else {  
                 $save_inststatus{$key} = $domconfig{'inststatus'}{$key};  
             }  
         }  
     }  
   
     my @contexts = ('selfcreate');      my @contexts = ('selfcreate');
     @{$cancreate{'selfcreate'}} = ();      @{$cancreate{'selfcreate'}} = ();
     %{$cancreate{'emailusername'}} = ();      %{$cancreate{'emailusername'}} = ();
     if (@types) {      @{$cancreate{'statustocreate'}} = ();
         @{$cancreate{'statustocreate'}} = ();  
     }  
     %{$cancreate{'selfcreateprocessing'}} = ();      %{$cancreate{'selfcreateprocessing'}} = ();
     %{$cancreate{'shibenv'}} = ();      %{$cancreate{'shibenv'}} = ();
     %{$cancreate{'emailverified'}} = ();  
     %{$cancreate{'emailoptions'}} = ();  
     %{$cancreate{'emaildomain'}} = ();  
     my %selfcreatetypes = (      my %selfcreatetypes = (
                              sso   => 'users authenticated by institutional single sign on',                               sso   => 'users authenticated by institutional single sign on',
                              login => 'users authenticated by institutional log-in',                               login => 'users authenticated by institutional log-in',
                              email => 'users verified by e-mail',                               email => 'users who provide a valid e-mail address for use as username',
                           );                            );
 #  #
 # Populate $cancreate{'selfcreate'} array reference with types of user, for which self-creation of user accounts  # Populate $cancreate{'selfcreate'} array reference with types of user, for which self-creation of user accounts
 # is permitted.  # is permitted.
 #  #
   
     my ($emailrules,$emailruleorder) = &Apache::lonnet::inst_userrules($dom,'email');      my @statuses;
       if (ref($domconfig{'inststatus'}) eq 'HASH') {
           if (ref($domconfig{'inststatus'}{'inststatusguest'}) eq 'ARRAY') {
               @statuses = @{$domconfig{'inststatus'}{'inststatusguest'}};
           }
       }
       push(@statuses,'default');
   
     my (@statuses,%email_rule);  
     foreach my $item ('login','sso','email') {      foreach my $item ('login','sso','email') {
         if ($item eq 'email') {          if ($item eq 'email') {
             if ($env{'form.cancreate_email'}) {              if ($env{'form.cancreate_email'}) {
                 if (@types) {                  push(@{$cancreate{'selfcreate'}},'email');
                     my @poss_statuses = &Apache::loncommon::get_env_multiple('form.selfassign');                  push(@contexts,'selfcreateprocessing');
                     foreach my $status (@poss_statuses) {                  foreach my $type (@statuses) {
                         if (grep(/^\Q$status\E$/,(@types,'default'))) {                      if ($type eq 'default') {
                             push(@statuses,$status);                          $cancreate{'selfcreateprocessing'}{$type} = $env{'form.cancreate_emailprocess'};
                         }                      } else { 
                     }                          $cancreate{'selfcreateprocessing'}{$type} = $env{'form.cancreate_emailprocess_'.$type};
                     $save_inststatus{'inststatusguest'} = \@statuses;  
                 } else {  
                     push(@statuses,'default');  
                 }  
                 if (@statuses) {  
                     my %curr_rule;  
                     if (ref($curr_usercreation{'email_rule'}) eq 'ARRAY') {  
                         foreach my $type (@statuses) {  
                             $curr_rule{$type} = $curr_usercreation{'email_rule'};  
                         }  
                     } elsif (ref($curr_usercreation{'email_rule'}) eq 'HASH') {  
                         foreach my $type (@statuses) {  
                             $curr_rule{$type} = $curr_usercreation{'email_rule'}{$type};  
                         }  
                     }  
                     push(@{$cancreate{'selfcreate'}},'email');  
                     push(@contexts,('selfcreateprocessing','emailverified','emailoptions'));  
                     my %curremaildom;  
                     if (ref($curr_usercreation{'cancreate'}{'emaildomain'}) eq 'HASH') {  
                         %curremaildom = %{$curr_usercreation{'cancreate'}{'emaildomain'}};  
                     }  
                     foreach my $type (@statuses) {  
                         if ($env{'form.cancreate_emailprocess_'.$type} =~ /^(?:approval|automatic)$/) {  
                             $cancreate{'selfcreateprocessing'}{$type} = $env{'form.cancreate_emailprocess_'.$type};  
                         }  
                         if ($env{'form.cancreate_usernameoptions_'.$type} =~ /^(?:all|first|free)$/) {  
                             $cancreate{'emailverified'}{$type} = $env{'form.cancreate_usernameoptions_'.$type};  
                         }  
                         if ($env{'form.cancreate_emailoptions_'.$type} =~ /^(any|inst|noninst|custom)$/) {  
 #  
 # Retrieve rules (if any) governing types of e-mail address which may be used to verify a username.  
 #  
                             my $chosen = $1;  
                             if (($chosen eq 'inst') || ($chosen eq 'noninst')) {  
                                 my $emaildom;  
                                 if ($env{'form.cancreate_emaildomain_'.$chosen.'_'.$type} =~ /^\@[^\@]+$/) {  
                                     $emaildom = $env{'form.cancreate_emaildomain_'.$chosen.'_'.$type};  
                                     $cancreate{'emaildomain'}{$type}{$chosen} = $emaildom;  
                                     if (ref($curremaildom{$type}) eq 'HASH') {  
                                         if (exists($curremaildom{$type}{$chosen})) {  
                                             if ($curremaildom{$type}{$chosen} ne $emaildom) {  
                                                 push(@{$changes{'cancreate'}},'emaildomain');  
                                             }  
                                         } elsif ($emaildom ne '') {  
                                             push(@{$changes{'cancreate'}},'emaildomain');  
                                         }  
                                     } elsif ($emaildom ne '') {  
                                         push(@{$changes{'cancreate'}},'emaildomain');  
                                     }  
                                 }  
                                 $cancreate{'emailoptions'}{$type} = $env{'form.cancreate_emailoptions_'.$type};  
                             } elsif ($chosen eq 'custom') {  
                                 my @possemail_rules = &Apache::loncommon::get_env_multiple('form.email_rule_'.$type);  
                                 $email_rule{$type} = [];  
                                 if (ref($emailrules) eq 'HASH') {  
                                     foreach my $rule (@possemail_rules) {  
                                         if (exists($emailrules->{$rule})) {  
                                             push(@{$email_rule{$type}},$rule);  
                                         }  
                                     }  
                                 }  
                                 if (@{$email_rule{$type}}) {  
                                     $cancreate{'emailoptions'}{$type} = 'custom';  
                                     if (ref($curr_rule{$type}) eq 'ARRAY') {  
                                         if (@{$curr_rule{$type}} > 0) {  
                                             foreach my $rule (@{$curr_rule{$type}}) {  
                                                 if (!grep(/^\Q$rule\E$/,@{$email_rule{$type}})) {  
                                                     push(@{$changes{'email_rule'}},$type);  
                                                 }  
                                             }  
                                         }  
                                         foreach my $type (@{$email_rule{$type}}) {  
                                             if (!grep(/^\Q$type\E$/,@{$curr_rule{$type}})) {  
                                                 push(@{$changes{'email_rule'}},$type);  
                                             }  
                                         }  
                                     } else {  
                                         push(@{$changes{'email_rule'}},$type);  
                                     }  
                                 }  
                             } else {  
                                 $cancreate{'emailoptions'}{$type} = $env{'form.cancreate_emailoptions_'.$type};  
                             }  
                         }  
                     }  
                     if (@types) {  
                         if (ref($curr_inststatus{'inststatusguest'}) eq 'ARRAY') {  
                             my @changed = &Apache::loncommon::compare_arrays(\@statuses,$curr_inststatus{'inststatusguest'});  
                             if (@changed) {  
                                 push(@{$changes{'inststatus'}},'inststatusguest');  
                             }  
                         } else {  
                             push(@{$changes{'inststatus'}},'inststatusguest');  
                         }  
                     }  
                 } else {  
                     delete($env{'form.cancreate_email'});  
                     if (ref($curr_inststatus{'inststatusguest'}) eq 'ARRAY') {  
                         if (@{$curr_inststatus{'inststatusguest'}} > 0) {  
                             push(@{$changes{'inststatus'}},'inststatusguest');  
                         }  
                     }  
                 }  
             } else {  
                 $save_inststatus{'inststatusguest'} = [];  
                 if (ref($curr_inststatus{'inststatusguest'}) eq 'ARRAY') {  
                     if (@{$curr_inststatus{'inststatusguest'}} > 0) {  
                         push(@{$changes{'inststatus'}},'inststatusguest');  
                     }                      }
                 }                  }
             }              }
Line 12867  sub modify_selfcreation { Line 9798  sub modify_selfcreation {
             }              }
         }          }
     }      }
     my (%userinfo,%savecaptcha);      my (@email_rule,%userinfo,%savecaptcha);
     my ($infofields,$infotitles) = &Apache::loncommon::emailusername_info();      my ($infofields,$infotitles) = &Apache::loncommon::emailusername_info();
 #  #
 # Populate $cancreate{'emailusername'}{$type} hash ref with information fields (if new user will provide data  # Populate $cancreate{'emailusername'}{$type} hash ref with information fields (if new user will provide data
Line 12876  sub modify_selfcreation { Line 9807  sub modify_selfcreation {
   
     if ($env{'form.cancreate_email'}) {      if ($env{'form.cancreate_email'}) {
         push(@contexts,'emailusername');          push(@contexts,'emailusername');
         if (@statuses) {          if (ref($types) eq 'ARRAY') {
             foreach my $type (@statuses) {              foreach my $type (@{$types}) {
                 if (ref($infofields) eq 'ARRAY') {                  if (ref($infofields) eq 'ARRAY') {
                     foreach my $field (@{$infofields}) {                      foreach my $field (@{$infofields}) {
                         if ($env{'form.canmodify_emailusername_'.$type.'_'.$field} =~ /^(required|optional)$/) {                          if ($env{'form.canmodify_emailusername_'.$type.'_'.$field} =~ /^(required|optional)$/) {
Line 12889  sub modify_selfcreation { Line 9820  sub modify_selfcreation {
         }          }
 #  #
 # Populate $cancreate{'notify'} hash ref with names of Domain Coordinators who are to be notified of  # Populate $cancreate{'notify'} hash ref with names of Domain Coordinators who are to be notified of
 # queued requests for self-creation of account verified by e-mail.  # queued requests for self-creation of account using e-mail address as username
 #  #
   
         my @approvalnotify = &Apache::loncommon::get_env_multiple('form.selfcreationnotifyapproval');          my @approvalnotify = &Apache::loncommon::get_env_multiple('form.selfcreationnotifyapproval');
Line 12909  sub modify_selfcreation { Line 9840  sub modify_selfcreation {
             push(@{$changes{'cancreate'}},'notify');              push(@{$changes{'cancreate'}},'notify');
         }          }
   
   #
   # Retrieve rules (if any) governing types of e-mail address which may be used as a username
   #
           @email_rule = &Apache::loncommon::get_env_multiple('form.email_rule');
         &process_captcha('cancreate',\%changes,\%savecaptcha,$curr_usercreation{'cancreate'});          &process_captcha('cancreate',\%changes,\%savecaptcha,$curr_usercreation{'cancreate'});
           if (ref($curr_usercreation{'email_rule'}) eq 'ARRAY') {
               if (@{$curr_usercreation{'email_rule'}} > 0) {
                   foreach my $type (@{$curr_usercreation{'email_rule'}}) {
                       if (!grep(/^\Q$type\E$/,@email_rule)) {
                           push(@{$changes{'email_rule'}},$type);
                       }
                   }
               }
               if (@email_rule > 0) {
                   foreach my $type (@email_rule) {
                       if (!grep(/^\Q$type\E$/,@{$curr_usercreation{'email_rule'}})) {
                           push(@{$changes{'email_rule'}},$type);
                       }
                   }
               }
           } elsif (@email_rule > 0) {
               push(@{$changes{'email_rule'}},@email_rule);
           }
     }      }
 #    #  
 # Check if domain default is set appropriately, if self-creation of accounts is to be available for  # Check if domain default is set appropriately, if self-creation of accounts is to be available for
 # institutional log-in.  # institutional log-in.
 #  #
     if (grep(/^login$/,@{$cancreate{'selfcreate'}})) {      if (grep(/^login$/,@{$cancreate{'selfcreate'}})) {
           my %domdefaults = &Apache::lonnet::get_domain_defaults($dom,1);
         if (!((($domdefaults{'auth_def'} =~/^krb/) && ($domdefaults{'auth_arg_def'} ne '')) ||           if (!((($domdefaults{'auth_def'} =~/^krb/) && ($domdefaults{'auth_arg_def'} ne '')) || 
                ($domdefaults{'auth_def'} eq 'localauth'))) {                 ($domdefaults{'auth_def'} eq 'localauth'))) {
             $warningmsg = &mt('Although account creation has been set to be available for institutional logins, currently default authentication in this domain has not been set to support this.').' '.              $warningmsg = &mt('Although account creation has been set to be available for institutional logins, currently default authentication in this domain has not been set to support this.').' '.
Line 12934  sub modify_selfcreation { Line 9888  sub modify_selfcreation {
 # which the user may supply, if institutional data is unavailable.  # which the user may supply, if institutional data is unavailable.
 #  #
     if (($env{'form.cancreate_login'}) || ($env{'form.cancreate_sso'})) {      if (($env{'form.cancreate_login'}) || ($env{'form.cancreate_sso'})) {
         if (@types) {          if (ref($types) eq 'ARRAY') {
             @{$cancreate{'statustocreate'}} = &Apache::loncommon::get_env_multiple('form.statustocreate');              if (@{$types} > 1) {
             push(@contexts,'statustocreate');                  @{$cancreate{'statustocreate'}} = &Apache::loncommon::get_env_multiple('form.statustocreate');
             foreach my $type (@types) {                  push(@contexts,'statustocreate');
               } else {
                   undef($cancreate{'statustocreate'});
               } 
               foreach my $type (@{$types}) {
                 my @modifiable =  &Apache::loncommon::get_env_multiple('form.canmodify_'.$type);                  my @modifiable =  &Apache::loncommon::get_env_multiple('form.canmodify_'.$type);
                 foreach my $field (@fields) {                  foreach my $field (@fields) {
                     if (grep(/^\Q$field\E$/,@modifiable)) {                      if (grep(/^\Q$field\E$/,@modifiable)) {
Line 12948  sub modify_selfcreation { Line 9906  sub modify_selfcreation {
                 }                  }
             }              }
             if (ref($curr_usermodify{'selfcreate'}) eq 'HASH') {              if (ref($curr_usermodify{'selfcreate'}) eq 'HASH') {
                 foreach my $type (@types) {                  foreach my $type (@{$types}) {
                     if (ref($curr_usermodify{'selfcreate'}{$type}) eq 'HASH') {                      if (ref($curr_usermodify{'selfcreate'}{$type}) eq 'HASH') {
                         foreach my $field (@fields) {                          foreach my $field (@fields) {
                             if ($save_usermodify{'selfcreate'}{$type}{$field} ne                              if ($save_usermodify{'selfcreate'}{$type}{$field} ne
Line 12960  sub modify_selfcreation { Line 9918  sub modify_selfcreation {
                     }                      }
                 }                  }
             } else {              } else {
                 foreach my $type (@types) {                  foreach my $type (@{$types}) {
                     push(@{$changes{'selfcreate'}},$type);                      push(@{$changes{'selfcreate'}},$type);
                 }                  }
             }              }
Line 13009  sub modify_selfcreation { Line 9967  sub modify_selfcreation {
             }              }
         } elsif (ref($curr_usercreation{'cancreate'}{$item}) eq 'HASH') {          } elsif (ref($curr_usercreation{'cancreate'}{$item}) eq 'HASH') {
             if (ref($cancreate{$item}) eq 'HASH') {              if (ref($cancreate{$item}) eq 'HASH') {
                 foreach my $type (keys(%{$curr_usercreation{'cancreate'}{$item}})) {                  foreach my $curr (keys(%{$curr_usercreation{'cancreate'}{$item}})) {
                     if (ref($curr_usercreation{'cancreate'}{$item}{$type}) eq 'HASH') {                      if (ref($curr_usercreation{'cancreate'}{$item}{$curr}) eq 'HASH') {
                         foreach my $field (keys(%{$curr_usercreation{'cancreate'}{$item}{$type}})) {                          foreach my $field (keys(%{$curr_usercreation{'cancreate'}{$item}{$curr}})) {
                             unless ($curr_usercreation{'cancreate'}{$item}{$type}{$field} eq $cancreate{$item}{$type}{$field}) {                              unless ($curr_usercreation{'cancreate'}{$item}{$curr}{$field} eq $cancreate{$item}{$curr}{$field}) {
                                 if (!grep(/^$item$/,@{$changes{'cancreate'}})) {                                  if (!grep(/^$item$/,@{$changes{'cancreate'}})) {
                                     push(@{$changes{'cancreate'}},$item);                                      push(@{$changes{'cancreate'}},$item);
                                 }                                  }
                             }                              }
                         }                          }
                     } elsif (($item eq 'selfcreateprocessing') || ($item eq 'emailverified') || ($item eq 'emailoptions')) {                      } elsif ($item eq 'selfcreateprocessing') {
                         if ($cancreate{$item}{$type} ne $curr_usercreation{'cancreate'}{$item}{$type}) {                          if ($cancreate{$item}{$curr} ne $curr_usercreation{'cancreate'}{$item}{$curr}) {
                               if (!grep(/^$item$/,@{$changes{'cancreate'}})) {
                                   push(@{$changes{'cancreate'}},$item);
                               }
                           }
                       } else {
                           if (!$cancreate{$item}{$curr}) {
                             if (!grep(/^$item$/,@{$changes{'cancreate'}})) {                              if (!grep(/^$item$/,@{$changes{'cancreate'}})) {
                                 push(@{$changes{'cancreate'}},$item);                                  push(@{$changes{'cancreate'}},$item);
                             }                              }
                         }                          }
                     }                      }
                 }                  }
                 foreach my $type (keys(%{$cancreate{$item}})) {                  foreach my $field (keys(%{$cancreate{$item}})) {
                     if (ref($cancreate{$item}{$type}) eq 'HASH') {                      if (ref($cancreate{$item}{$field}) eq 'HASH') {
                         foreach my $field (keys(%{$cancreate{$item}{$type}})) {                          foreach my $inner (keys(%{$cancreate{$item}{$field}})) {
                             if (ref($curr_usercreation{'cancreate'}{$item}{$type}) eq 'HASH') {                              if (ref($curr_usercreation{'cancreate'}{$item}{$field}) eq 'HASH') {
                                 unless ($curr_usercreation{'cancreate'}{$item}{$type}{$field} eq $cancreate{$item}{$type}{$field}) {                                  unless ($curr_usercreation{'cancreate'}{$item}{$field}{$inner} eq $cancreate{$item}{$field}{$inner}) {
                                     if (!grep(/^$item$/,@{$changes{'cancreate'}})) {                                      if (!grep(/^$item$/,@{$changes{'cancreate'}})) {
                                         push(@{$changes{'cancreate'}},$item);                                          push(@{$changes{'cancreate'}},$item);
                                     }                                      }
Line 13041  sub modify_selfcreation { Line 10005  sub modify_selfcreation {
                                 }                                  }
                             }                              }
                         }                          }
                     } elsif (($item eq 'selfcreateprocessing') || ($item eq 'emailverified') || ($item eq 'emailoptions')) {                      } elsif ($item eq 'selfcreateprocessing') {
                         if ($cancreate{$item}{$type} ne $curr_usercreation{'cancreate'}{$item}{$type}) {                          if ($cancreate{$item}{$field} ne $curr_usercreation{'cancreate'}{$item}{$field}) {
                               if (!grep(/^$item$/,@{$changes{'cancreate'}})) {
                                   push(@{$changes{'cancreate'}},$item);
                               }
                           }
                       } else {
                           if (!$curr_usercreation{'cancreate'}{$item}{$field}) {
                             if (!grep(/^$item$/,@{$changes{'cancreate'}})) {                              if (!grep(/^$item$/,@{$changes{'cancreate'}})) {
                                 push(@{$changes{'cancreate'}},$item);                                  push(@{$changes{'cancreate'}},$item);
                             }                              }
Line 13057  sub modify_selfcreation { Line 10027  sub modify_selfcreation {
                         push(@{$changes{'cancreate'}},$item);                          push(@{$changes{'cancreate'}},$item);
                     }                      }
                 }                  }
             }              } elsif (ref($cancreate{$item}) eq 'HASH') {
         } elsif (($item eq 'selfcreateprocessing') || ($item eq 'emailverified') || ($item eq 'emailoptions')) {                  if (!$cancreate{$item}{$curr_usercreation{'cancreate'}{$item}}) {
             if (ref($cancreate{$item}) eq 'HASH') {                      if (!grep(/^$item$/,@{$changes{'cancreate'}})) {
                 if (!grep(/^$item$/,@{$changes{'cancreate'}})) {                          push(@{$changes{'cancreate'}},$item);
                     push(@{$changes{'cancreate'}},$item);                      }
                 }                  }
             }              }
         } elsif ($item eq 'emailusername') {          } elsif ($item eq 'emailusername') {
Line 13094  sub modify_selfcreation { Line 10064  sub modify_selfcreation {
     if (ref($cancreate{'selfcreateprocessing'}) eq 'HASH') {      if (ref($cancreate{'selfcreateprocessing'}) eq 'HASH') {
         $save_usercreate{'cancreate'}{'selfcreateprocessing'} = $cancreate{'selfcreateprocessing'};          $save_usercreate{'cancreate'}{'selfcreateprocessing'} = $cancreate{'selfcreateprocessing'};
     }      }
     if (ref($cancreate{'emailverified'}) eq 'HASH') {  
         $save_usercreate{'cancreate'}{'emailverified'} = $cancreate{'emailverified'};  
     }  
     if (ref($cancreate{'emailoptions'}) eq 'HASH') {  
         $save_usercreate{'cancreate'}{'emailoptions'} = $cancreate{'emailoptions'};  
     }  
     if (ref($cancreate{'emaildomain'}) eq 'HASH') {  
         $save_usercreate{'cancreate'}{'emaildomain'} = $cancreate{'emaildomain'};  
     }  
     if (ref($cancreate{'statustocreate'}) eq 'ARRAY') {      if (ref($cancreate{'statustocreate'}) eq 'ARRAY') {
         $save_usercreate{'cancreate'}{'statustocreate'} = $cancreate{'statustocreate'};          $save_usercreate{'cancreate'}{'statustocreate'} = $cancreate{'statustocreate'};
     }      }
Line 13110  sub modify_selfcreation { Line 10071  sub modify_selfcreation {
         $save_usercreate{'cancreate'}{'shibenv'} = $cancreate{'shibenv'};          $save_usercreate{'cancreate'}{'shibenv'} = $cancreate{'shibenv'};
     }      }
     $save_usercreate{'cancreate'}{'emailusername'} = $cancreate{'emailusername'};      $save_usercreate{'cancreate'}{'emailusername'} = $cancreate{'emailusername'};
     $save_usercreate{'email_rule'} = \%email_rule;      $save_usercreate{'emailrule'} = \@email_rule;
   
     my %userconfig_hash = (      my %userconfig_hash = (
             usercreation     => \%save_usercreate,              usercreation     => \%save_usercreate,
             usermodification => \%save_usermodify,              usermodification => \%save_usermodify,
             inststatus       => \%save_inststatus,  
     );      );
   
     my $putresult = &Apache::lonnet::put_dom('configuration',\%userconfig_hash,      my $putresult = &Apache::lonnet::put_dom('configuration',\%userconfig_hash,
                                              $dom);                                               $dom);
 #  #
 # Accumulate details of changes to domain configuration for self-creation of usernames in $resulttext  # Accumulate details of changes to domain cofiguration for self-creation of usernames in $resulttext
 #  #
     if ($putresult eq 'ok') {      if ($putresult eq 'ok') {
         if (keys(%changes) > 0) {          if (keys(%changes) > 0) {
Line 13129  sub modify_selfcreation { Line 10088  sub modify_selfcreation {
             if (ref($changes{'cancreate'}) eq 'ARRAY') {              if (ref($changes{'cancreate'}) eq 'ARRAY') {
                 my %lt = &selfcreation_types();                  my %lt = &selfcreation_types();
                 foreach my $type (@{$changes{'cancreate'}}) {                  foreach my $type (@{$changes{'cancreate'}}) {
                     my $chgtext = '';                      my $chgtext;
                     if ($type eq 'selfcreate') {                      if ($type eq 'selfcreate') {
                         if (@{$cancreate{$type}} == 0) {                          if (@{$cancreate{$type}} == 0) {
                             $chgtext .= &mt('Self creation of a new user account is not permitted.');                              $chgtext .= &mt('Self creation of a new user account is not permitted.');
Line 13144  sub modify_selfcreation { Line 10103  sub modify_selfcreation {
                                 if (grep(/^(login|sso)$/,@{$cancreate{$type}})) {                                  if (grep(/^(login|sso)$/,@{$cancreate{$type}})) {
                                     if (ref($cancreate{'statustocreate'}) eq 'ARRAY') {                                      if (ref($cancreate{'statustocreate'}) eq 'ARRAY') {
                                         if (@{$cancreate{'statustocreate'}} == 0) {                                          if (@{$cancreate{'statustocreate'}} == 0) {
                                             $chgtext .= '<span class="LC_warning">'.                                              $chgtext .= '<br />'.
                                                         &mt("However, no institutional affiliations (including 'other') are currently permitted to create accounts via log-in or single sign-on.").                                                          '<span class="LC_warning">'.
                                                         '</span><br />';                                                          &mt("However, no institutional affiliations (including 'other') are currently permitted to create accounts.").
                                                           '</span>';
                                         }                                          }
                                     }                                      }
                                 }                                  }
                                 if (grep(/^email$/,@{$cancreate{$type}})) {  
                                     if (!@statuses) {  
                                         $chgtext .= '<span class="LC_warning">'.  
                                                     &mt("However, e-mail verification is currently set to 'unavailable' for all user types (including 'other'), so self-creation of accounts is not possible for non-institutional log-in.").  
                                                     '</span><br />';  
   
                                     }  
                                 }  
                             }                              }
                         }                          }
                     } elsif ($type eq 'shibenv') {                      } elsif ($type eq 'shibenv') {
                         if (keys(%{$cancreate{$type}}) == 0) {                          if (keys(%{$cancreate{$type}}) == 0) {
                             $chgtext .= &mt('Shibboleth-autheticated user does not use environment variables to set user information').'<br />';                               $chgtext .= &mt('Shibboleth-autheticated user does not use environment variables to set user information'); 
                         } else {                          } else {
                             $chgtext .= &mt('Shibboleth-autheticated user information set from environment variables, as follows:').                              $chgtext .= &mt('Shibboleth-autheticated user information set from environment variables, as follows:').
                                         '<ul>';                                          '<ul>';
Line 13175  sub modify_selfcreation { Line 10127  sub modify_selfcreation {
                                 }                                  }
                             }                              }
                             $chgtext .= '</ul>';                              $chgtext .= '</ul>';
                         }                          }  
                     } elsif ($type eq 'statustocreate') {                      } elsif ($type eq 'statustocreate') {
                         if ((ref($cancreate{'selfcreate'}) eq 'ARRAY') &&                          if ((ref($cancreate{'selfcreate'}) eq 'ARRAY') &&
                             (ref($cancreate{'statustocreate'}) eq 'ARRAY')) {                              (ref($cancreate{'statustocreate'}) eq 'ARRAY')) {
Line 13188  sub modify_selfcreation { Line 10140  sub modify_selfcreation {
                                                     &mt("However, no institutional affiliations (including 'other') are currently permitted to create accounts.").                                                      &mt("However, no institutional affiliations (including 'other') are currently permitted to create accounts.").
                                                     '</span>';                                                      '</span>';
                                     }                                      }
                                 } elsif (keys(%usertypes) > 0) {                                  } elsif (ref($usertypes) eq 'HASH') {
                                     if (grep(/^(login|sso)$/,@{$cancreate{'selfcreate'}})) {                                      if (grep(/^(login|sso)$/,@{$cancreate{'selfcreate'}})) {
                                         $chgtext .= &mt('Creation of a new account for an institutional user is restricted to the following institutional affiliation(s):');                                          $chgtext .= &mt('Creation of a new account for an institutional user is restricted to the following institutional affiliation(s):');
                                     } else {                                      } else {
Line 13199  sub modify_selfcreation { Line 10151  sub modify_selfcreation {
                                         if ($case eq 'default') {                                          if ($case eq 'default') {
                                             $chgtext .= '<li>'.$othertitle.'</li>';                                              $chgtext .= '<li>'.$othertitle.'</li>';
                                         } else {                                          } else {
                                             $chgtext .= '<li>'.$usertypes{$case}.'</li>';                                              $chgtext .= '<li>'.$usertypes->{$case}.'</li>';
                                         }                                          }
                                     }                                      }
                                     $chgtext .= '</ul>';                                      $chgtext .= '</ul>';
                                     if (!grep(/^(login|sso)$/,@{$cancreate{'selfcreate'}})) {                                      if (!grep(/^(login|sso)$/,@{$cancreate{'selfcreate'}})) {
                                         $chgtext .= '<span class="LC_warning">'.                                          $chgtext .= '<br /><span class="LC_warning">'.
                                                     &mt('However, users authenticated by institutional login/single sign on are not currently permitted to create accounts.').                                                      &mt('However, users authenticated by institutional login/single sign on are not currently permitted to create accounts.').
                                                     '</span>';                                                      '</span>';
                                     }                                      }
Line 13216  sub modify_selfcreation { Line 10168  sub modify_selfcreation {
                                     $chgtext .= &mt('Although institutional affiliations permitted to create accounts were changed, self creation of accounts is not currently permitted for any authentication types.');                                      $chgtext .= &mt('Although institutional affiliations permitted to create accounts were changed, self creation of accounts is not currently permitted for any authentication types.');
                                 }                                  }
                             }                              }
                             $chgtext .= '<br />';  
                         }                          }
                     } elsif ($type eq 'selfcreateprocessing') {                      } elsif ($type eq 'selfcreateprocessing') {
                         my %choices = &Apache::lonlocal::texthash (                          my %choices = &Apache::lonlocal::texthash (
                                                                     automatic => 'Automatic approval',                                                                      automatic => 'Automatic approval',
                                                                     approval  => 'Queued for approval',                                                                      approval  => 'Queued for approval',
                                                                   );                                                                    );
                         if (@types) {                          if (@statuses > 1) {
                             if (@statuses) {                              $chgtext .= &mt('Processing of requests to create account with e-mail address as username set as follows:'). 
                                 $chgtext .= &mt('Processing of requests to create account with e-mail verification set as follows:').                                          '<ul>';
                                             '<ul>';                             foreach my $type (@statuses) {
                                 foreach my $status (@statuses) {                                 if ($type eq 'default') {
                                     if ($status eq 'default') {                                     $chgtext .= '<li>'.$othertitle.' -- '.$choices{$cancreate{'selfcreateprocessing'}{$type}}.'</li>';
                                         $chgtext .= '<li>'.$othertitle.' -- '.$choices{$cancreate{'selfcreateprocessing'}{$status}}.'</li>';                                 } else {
                                     } else {                                     $chgtext .= '<li>'.$usertypes->{$type}.' -- '.$choices{$cancreate{'selfcreateprocessing'}{$type}}.'</li>';
                                         $chgtext .= '<li>'.$usertypes{$status}.' -- '.$choices{$cancreate{'selfcreateprocessing'}{$status}}.'</li>';                                 }
                                     }                             }
                                 }                             $chgtext .= '</ul>';
                                 $chgtext .= '</ul>';  
                             }  
                         } else {  
                             $chgtext .= &mt('Processing of requests to create account with e-mail verification set to: "[_1]"',  
                                             $choices{$cancreate{'selfcreateprocessing'}{'default'}});  
                         }  
                     } elsif ($type eq 'emailverified') {  
                         my %options = &Apache::lonlocal::texthash (  
                                                                     all   => 'Same as e-mail',  
                                                                     first => 'Omit @domain',  
                                                                     free  => 'Free to choose',  
                                                                   );  
                         if (@types) {  
                             if (@statuses) {  
                                 $chgtext .= &mt('For self-created accounts verified by e-mail address, username is set as follows:').  
                                             '<ul>';  
                                 foreach my $status (@statuses) {  
                                     if ($status eq 'default') {  
                                         $chgtext .= '<li>'.$othertitle.' -- '.$options{$cancreate{'emailverified'}{$status}}.'</li>';  
                                     } else {  
                                         $chgtext .= '<li>'.$usertypes{$status}.' -- '.$options{$cancreate{'emailverified'}{$status}}.'</li>';  
                                     }  
                                 }  
                                 $chgtext .= '</ul>';  
                             }  
                         } else {                          } else {
                             $chgtext .= &mt("For self-created accounts verified by e-mail address, user's username is: '[_1]'",                             $chgtext .= &mt('Processing of requests to create account with e-mail address as username set to: "[_1]"',
                                             $options{$cancreate{'emailverified'}{'default'}});                                           $choices{$cancreate{'selfcreateprocessing'}{'default'}});
                         }  
                     } elsif ($type eq 'emailoptions') {  
                         my %options = &Apache::lonlocal::texthash (  
                                                                     any     => 'Any e-mail',  
                                                                     inst    => 'Institutional only',  
                                                                     noninst => 'Non-institutional only',  
                                                                     custom  => 'Custom restrictions',  
                                                                   );  
                         if (@types) {  
                             if (@statuses) {  
                                 $chgtext .= &mt('For self-created accounts verified by e-mail address, requirements for e-mail address are as follows:').  
                                             '<ul>';  
                                 foreach my $status (@statuses) {  
                                     if ($type eq 'default') {  
                                         $chgtext .= '<li>'.$othertitle.' -- '.$options{$cancreate{'emailoptions'}{$status}}.'</li>';  
                                     } else {  
                                         $chgtext .= '<li>'.$usertypes{$status}.' -- '.$options{$cancreate{'emailoptions'}{$status}}.'</li>';  
                                     }  
                                 }  
                                 $chgtext .= '</ul>';  
                             }  
                         } else {  
                             if ($cancreate{'emailoptions'}{'default'} eq 'any') {  
                                 $chgtext .= &mt('For self-created accounts verified by e-mail address, any e-mail may be used');  
                             } else {  
                                 $chgtext .= &mt('For self-created accounts verified by e-mail address, e-mail restricted to: "[_1]"',  
                                                 $options{$cancreate{'emailoptions'}{'default'}});  
                             }  
                         }  
                     } elsif ($type eq 'emaildomain') {  
                         my $output;  
                         if (@statuses) {  
                             foreach my $type (@statuses) {  
                                 if (ref($cancreate{'emaildomain'}{$type}) eq 'HASH') {  
                                     if ($cancreate{'emailoptions'}{$type} eq 'inst') {  
                                         if ($type eq 'default') {  
                                             if ((ref($cancreate{'emaildomain'}{$type}) ne 'HASH') ||  
                                                 ($cancreate{'emaildomain'}{$type}{'inst'} eq '')) {  
                                                 $output = '<li>'.$othertitle.' -- '.&mt('No restriction on e-mail domain').'</li>';  
                                             } else {  
                                                 $output = '<li>'.$othertitle.' -- '.&mt("User's e-mail address needs to end: [_1]",  
                                                                                         $cancreate{'emaildomain'}{$type}{'inst'}).'</li>';  
                                             }  
                                         } else {  
                                             if ((ref($cancreate{'emaildomain'}{$type}) ne 'HASH') ||  
                                                 ($cancreate{'emaildomain'}{$type}{'inst'} eq '')) {  
                                                 $output = '<li>'.$usertypes{$type}.' -- '.&mt('No restriction on e-mail domain').'</li>';  
                                             } else {  
                                                 $output = '<li>'.$usertypes{$type}.' -- '.&mt("User's e-mail address needs to end: [_1]",  
                                                                                               $cancreate{'emaildomain'}{$type}{'inst'}).'</li>';  
                                             }  
                                         }  
                                     } elsif ($cancreate{'emailoptions'}{$type} eq 'noninst') {  
                                         if ($type eq 'default') {  
                                             if ((ref($cancreate{'emaildomain'}{$type}) ne 'HASH') ||  
                                                 ($cancreate{'emaildomain'}{$type}{'noninst'} eq '')) {  
                                                 $output = '<li>'.$othertitle.' -- '.&mt('No restriction on e-mail domain').'</li>';  
                                             } else {  
                                                 $output = '<li>'.$othertitle.' -- '.&mt("User's e-mail address must not end: [_1]",  
                                                                                         $cancreate{'emaildomain'}{$type}{'noninst'}).'</li>';  
                                             }  
                                         } else {  
                                             if ((ref($cancreate{'emaildomain'}{$type}) ne 'HASH') ||  
                                                 ($cancreate{'emaildomain'}{$type}{'noninst'} eq '')) {  
                                                 $output = '<li>'.$usertypes{$type}.' -- '.&mt('No restriction on e-mail domain').'</li>';  
                                             } else {  
                                                 $output = '<li>'.$usertypes{$type}.' -- '.&mt("User's e-mail address must not end: [_1]",  
                                                                                                 $cancreate{'emaildomain'}{$type}{'noninst'}).'</li>';  
                                             }  
                                         }  
                                     }  
                                 }  
                             }  
                         }  
                         if ($output ne '') {  
                             $chgtext .= &mt('For self-created accounts verified by e-mail address:').  
                                         '<ul>'.$output.'</ul>';  
                         }                          }
                     } elsif ($type eq 'captcha') {                      } elsif ($type eq 'captcha') {
                         if ($savecaptcha{$type} eq 'notused') {                          if ($savecaptcha{$type} eq 'notused') {
Line 13375  sub modify_selfcreation { Line 10224  sub modify_selfcreation {
                         }                          }
                     } elsif ($type eq 'emailusername') {                      } elsif ($type eq 'emailusername') {
                         if (ref($cancreate{'emailusername'}) eq 'HASH') {                          if (ref($cancreate{'emailusername'}) eq 'HASH') {
                             if (@statuses) {                              if (ref($types) eq 'ARRAY') {
                                 foreach my $type (@statuses) {                                  foreach my $type (@{$types}) {
                                     if (ref($cancreate{'emailusername'}{$type}) eq 'HASH') {                                      if (ref($cancreate{'emailusername'}{$type}) eq 'HASH') {
                                         if (keys(%{$cancreate{'emailusername'}{$type}}) > 0) {                                          if (keys(%{$cancreate{'emailusername'}{$type}}) > 0) {
                                             $chgtext .= &mt('When self-creating account with e-mail verification, the following information will be provided by [_1]:',"'$usertypes{$type}'").                                              $chgtext .= &mt('When self-creating account with e-mail as username, the following information will be provided by [_1]:',"'$usertypes->{$type}'").
                                                     '<ul>';                                                      '<ul>';
                                             foreach my $field (@{$infofields}) {                                              foreach my $field (@{$infofields}) {
                                                 if ($cancreate{'emailusername'}{$type}{$field}) {                                                  if ($cancreate{'emailusername'}{$type}{$field}) {
Line 13388  sub modify_selfcreation { Line 10237  sub modify_selfcreation {
                                             }                                              }
                                             $chgtext .= '</ul>';                                              $chgtext .= '</ul>';
                                         } else {                                          } else {
                                             $chgtext .= &mt('When self creating account with e-mail verification, no information besides e-mail address will be provided by [_1].',"'$usertypes{$type}'").'<br />';                                              $chgtext .= &mt('When self creating account with e-mail as username, no information besides e-mail address will be provided by [_1].',"'$usertypes->{$type}'").'<br />';
                                         }                                          }
                                     } else {                                      } else {
                                         $chgtext .= &mt('When self creating account with e-mail verification, no information besides e-mail address will be provided by [_1].',"'$usertypes{$type}'").'<br />';                                          $chgtext .= &mt('When self creating account with e-mail as username, no information besides e-mail address will be provided by [_1].',"'$usertypes->{$type}'").'<br />';
                                     }                                      }
                                 }                                  }
                             }                              }
                         }                          }
                     } elsif ($type eq 'notify') {                      } elsif ($type eq 'notify') {
                         my $numapprove = 0;                          $chgtext = &mt('No Domain Coordinators will receive notification of username requests requiring approval.');
                         if (ref($changes{'cancreate'}) eq 'ARRAY') {                          if (ref($changes{'cancreate'}) eq 'ARRAY') {
                             if ((grep(/^notify$/,@{$changes{'cancreate'}})) && (ref($cancreate{'notify'}) eq 'HASH')) {                              if ((grep(/^notify$/,@{$changes{'cancreate'}})) && (ref($cancreate{'notify'}) eq 'HASH')) {
                                 if ($cancreate{'notify'}{'approval'}) {                                  if ($cancreate{'notify'}{'approval'}) {
                                     $chgtext .= &mt('Notification of username requests requiring approval will be sent to: ').$cancreate{'notify'}{'approval'};                                      $chgtext = &mt('Notification of username requests requiring approval will be sent to: ').$cancreate{'notify'}{'approval'};
                                     $numapprove ++;  
                                 }                                  }
                             }                              }
                         }                          }
                         unless ($numapprove) {  
                             $chgtext .= &mt('No Domain Coordinators will receive notification of username requests requiring approval.');  
                         }  
                     }                      }
                     if ($chgtext) {                      if ($chgtext) {
                         $resulttext .= '<li>'.$chgtext.'</li>';                          $resulttext .= '<li>'.$chgtext.'</li>';
                     }                      }
                 }                  }
             }              }
             if ((ref($changes{'email_rule'}) eq 'ARRAY') && (@{$changes{'email_rule'}} > 0)) {              if (ref($changes{'email_rule'}) eq 'ARRAY') {
                 my ($emailrules,$emailruleorder) =                  my ($emailrules,$emailruleorder) =
                     &Apache::lonnet::inst_userrules($dom,'email');                      &Apache::lonnet::inst_userrules($dom,'email');
                 foreach my $type (@{$changes{'email_rule'}}) {                  my $chgtext = '<ul>';
                     if (ref($email_rule{$type}) eq 'ARRAY') {                  foreach my $type (@email_rule) {
                         my $chgtext = '<ul>';                      if (ref($emailrules->{$type}) eq 'HASH') {
                         foreach my $rule (@{$email_rule{$type}}) {                          $chgtext .= '<li>'.$emailrules->{$type}{'name'}.'</li>';
                             if (ref($emailrules->{$rule}) eq 'HASH') {  
                                 $chgtext .= '<li>'.$emailrules->{$rule}{'name'}.'</li>';  
                             }  
                         }  
                         $chgtext .= '</ul>';  
                         my $typename;  
                         if (@types) {  
                             if ($type eq 'default') {  
                                 $typename = $othertitle;  
                             } else {  
                                 $typename = $usertypes{$type};  
                             }  
                             $chgtext .= &mt('(Affiliation: [_1])',$typename);  
                         }  
                         if (@{$email_rule{$type}} > 0) {  
                             $resulttext .= '<li>'.  
                                            &mt('Accounts may not be created by users verified by e-mail, for e-mail addresses of the following types: ',  
                                                $usertypes{$type}).  
                                            $chgtext.  
                                            '</li>';  
                         } else {  
                             $resulttext .= '<li>'.  
                                            &mt('There are now no restrictions on e-mail addresses which may be used for verification when a user requests an account.').  
                                            '</li>'.  
                                            &mt('(Affiliation: [_1])',$typename);  
                         }  
                     }                      }
                 }                  }
             }                  $chgtext .= '</ul>';
             if (ref($changes{'inststatus'}) eq 'ARRAY') {                  if (@email_rule > 0) {
                 if (ref($save_inststatus{'inststatusguest'}) eq 'ARRAY') {                      $resulttext .= '<li>'.
                     if (@{$save_inststatus{'inststatusguest'}} > 0) {                                     &mt('Accounts may not be created by users self-enrolling with e-mail addresses of the following types: ').
                         my $chgtext = '<ul>';                                         $chgtext.
                         foreach my $type (@{$save_inststatus{'inststatusguest'}}) {                                     '</li>';
                             $chgtext .= '<li>'.$usertypes{$type}.'</li>';                  } else {
                         }                      $resulttext .= '<li>'.
                         $chgtext .= '</ul>';                                     &mt('There are now no restrictions on e-mail addresses which may be used as a username when self-enrolling.').
                         $resulttext .= '<li>'.                                     '</li>';
                                        &mt('A user will self-report one of the following affiliations when requesting an account verified by e-mail: ').  
                                           $chgtext.  
                                        '</li>';  
                     } else {  
                         $resulttext .= '<li>'.  
                                        &mt('No affiliations available for self-reporting when requesting an account verified by e-mail.').  
                                        '</li>';  
                     }  
                 }                  }
             }              }
             if (ref($changes{'selfcreate'}) eq 'ARRAY') {              if (ref($changes{'selfcreate'}) eq 'ARRAY') {
Line 13475  sub modify_selfcreation { Line 10286  sub modify_selfcreation {
                 my %fieldtitles = &Apache::loncommon::personal_data_fieldtitles();                  my %fieldtitles = &Apache::loncommon::personal_data_fieldtitles();
                 foreach my $type (@{$changes{'selfcreate'}}) {                  foreach my $type (@{$changes{'selfcreate'}}) {
                     my $typename = $type;                      my $typename = $type;
                     if (keys(%usertypes) > 0) {                      if (ref($usertypes) eq 'HASH') {
                         if ($usertypes{$type} ne '') {                          if ($usertypes->{$type} ne '') {
                             $typename = $usertypes{$type};                              $typename = $usertypes->{$type};
                         }                          }
                     }                      }
                     my @modifiable;                      my @modifiable;
Line 13500  sub modify_selfcreation { Line 10311  sub modify_selfcreation {
                 $resulttext .= '</ul></li>';                  $resulttext .= '</ul></li>';
             }              }
             $resulttext .= '</ul>';              $resulttext .= '</ul>';
             my $cachetime = 24*60*60;  
             $domdefaults{'inststatusguest'} = $save_inststatus{'inststatusguest'};  
             &Apache::lonnet::do_cache_new('domdefaults',$dom,\%domdefaults,$cachetime);  
             if (ref($lastactref) eq 'HASH') {  
                 $lastactref->{'domdefaults'} = 1;  
             }  
         } else {          } else {
             $resulttext = &mt('No changes made to self-creation settings');              $resulttext = &mt('No changes made to self-creation settings');
         }          }
Line 13533  sub process_captcha { Line 10338  sub process_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 13579  sub process_captcha { Line 10382  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 13592  sub process_captcha { Line 10393  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 13708  sub modify_defaults { Line 10507  sub modify_defaults {
     my ($dom,$lastactref,%domconfig) = @_;      my ($dom,$lastactref,%domconfig) = @_;
     my ($resulttext,$mailmsgtxt,%newvalues,%changes,@errors);      my ($resulttext,$mailmsgtxt,%newvalues,%changes,@errors);
     my %domdefaults = &Apache::lonnet::get_domain_defaults($dom,1);      my %domdefaults = &Apache::lonnet::get_domain_defaults($dom,1);
     my @items = ('auth_def','auth_arg_def','lang_def','timezone_def','datelocale_def',      my @items = ('auth_def','auth_arg_def','lang_def','timezone_def','datelocale_def','portal_def');
                  'portal_def');  
     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 13759  sub modify_defaults { Line 10557  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 13789  sub modify_defaults { Line 10575  sub modify_defaults {
     }      }
     my @todelete = &Apache::loncommon::get_env_multiple('form.inststatus_delete');      my @todelete = &Apache::loncommon::get_env_multiple('form.inststatus_delete');
     my @allpos;      my @allpos;
       my %guests;
     my %alltypes;      my %alltypes;
     my @inststatusguest;      my ($currtitles,$currguests,$currorder);
     if (ref($currinststatus) eq 'HASH') {  
         if (ref($currinststatus->{'inststatusguest'}) eq 'ARRAY') {  
             foreach my $type (@{$currinststatus->{'inststatusguest'}}) {  
                 unless (grep(/^\Q$type\E$/,@todelete)) {  
                     push(@inststatusguest,$type);  
                 }  
             }  
         }  
     }  
     my ($currtitles,$currorder);  
     if (ref($currinststatus) eq 'HASH') {      if (ref($currinststatus) eq 'HASH') {
         if (ref($currinststatus->{'inststatusorder'}) eq 'ARRAY') {          if (ref($currinststatus->{'inststatusorder'}) eq 'ARRAY') {
             foreach my $type (@{$currinststatus->{'inststatusorder'}}) {              foreach my $type (@{$currinststatus->{'inststatusorder'}}) {
Line 13815  sub modify_defaults { Line 10592  sub modify_defaults {
                     $allpos[$position] = $type;                      $allpos[$position] = $type;
                     $alltypes{$type} = $env{'form.inststatus_title_'.$type};                      $alltypes{$type} = $env{'form.inststatus_title_'.$type};
                     $alltypes{$type} =~ s/`//g;                      $alltypes{$type} =~ s/`//g;
                       if ($env{'form.inststatus_guest_'.$type}) {
                           $guests{$type} = 1;
                       }
                 }                  }
             }              }
               if (ref($currinststatus->{'inststatusguest'}) eq 'ARRAY') {
                   $currguests = join(',',@{$currinststatus->{'inststatusguest'}});
               }
             $currorder = join(',',@{$currinststatus->{'inststatusorder'}});              $currorder = join(',',@{$currinststatus->{'inststatusorder'}});
             $currtitles =~ s/,$//;              $currtitles =~ s/,$//;
         }          }
Line 13825  sub modify_defaults { Line 10608  sub modify_defaults {
         my $newtype = $env{'form.addinststatus'};          my $newtype = $env{'form.addinststatus'};
         $newtype =~ s/\W//g;          $newtype =~ s/\W//g;
         unless (exists($alltypes{$newtype})) {          unless (exists($alltypes{$newtype})) {
               if ($env{'form.addinststatus_guest'}) {
                   $guests{$newtype} = 1;
               }
             $alltypes{$newtype} = $env{'form.addinststatus_title'};              $alltypes{$newtype} = $env{'form.addinststatus_title'};
             $alltypes{$newtype} =~ s/`//g;               $alltypes{$newtype} =~ s/`//g; 
             my $position = $env{'form.addinststatus_pos'};              my $position = $env{'form.addinststatus_pos'};
Line 13834  sub modify_defaults { Line 10620  sub modify_defaults {
             }              }
         }          }
     }      }
     my @orderedstatus;      my (@orderedstatus,@orderedguests);
     foreach my $type (@allpos) {      foreach my $type (@allpos) {
         unless (($type eq '') || (grep(/^\Q$type\E$/,@orderedstatus))) {          unless (($type eq '') || (grep(/^\Q$type\E$/,@orderedstatus))) {
             push(@orderedstatus,$type);              push(@orderedstatus,$type);
               if ($guests{$type}) {
                   push(@orderedguests,$type);
               }
         }          }
     }      }
     foreach my $type (keys(%alltypes)) {      foreach my $type (keys(%alltypes)) {
Line 13848  sub modify_defaults { Line 10637  sub modify_defaults {
     $defaults_hash{'inststatus'} = {      $defaults_hash{'inststatus'} = {
                                      inststatustypes => \%alltypes,                                       inststatustypes => \%alltypes,
                                      inststatusorder => \@orderedstatus,                                       inststatusorder => \@orderedstatus,
                                      inststatusguest => \@inststatusguest,                                       inststatusguest => \@orderedguests,
                                    };                                     };
     if (ref($defaults_hash{'inststatus'}) eq 'HASH') {      if (ref($defaults_hash{'inststatus'}) eq 'HASH') {
         foreach my $item ('inststatustypes','inststatusorder','inststatusguest') {          foreach my $item ('inststatustypes','inststatusorder','inststatusguest') {
Line 13858  sub modify_defaults { Line 10647  sub modify_defaults {
     if ($currorder ne join(',',@orderedstatus)) {      if ($currorder ne join(',',@orderedstatus)) {
         $changes{'inststatus'}{'inststatusorder'} = 1;          $changes{'inststatus'}{'inststatusorder'} = 1;
     }      }
       if ($currguests ne join(',',@orderedguests)) {
           $changes{'inststatus'}{'inststatusguest'} = 1;
       }
     my $newtitles;      my $newtitles;
     foreach my $item (@orderedstatus) {      foreach my $item (@orderedstatus) {
         $newtitles .= $alltypes{$item}.',';          $newtitles .= $alltypes{$item}.',';
Line 13876  sub modify_defaults { Line 10668  sub modify_defaults {
             foreach my $item (sort(keys(%changes))) {              foreach my $item (sort(keys(%changes))) {
                 if ($item eq 'inststatus') {                  if ($item eq 'inststatus') {
                     if (ref($changes{'inststatus'}) eq 'HASH') {                      if (ref($changes{'inststatus'}) eq 'HASH') {
                         if (@orderedstatus) {                          if (($changes{'inststatus'}{'inststatustypes'}) || $changes{'inststatus'}{'inststatusorder'}) {
                             $resulttext .= '<li>'.&mt('Institutional user status types set to:').' ';                              $resulttext .= '<li>'.&mt('Institutional user status types set to:').' ';
                             foreach my $type (@orderedstatus) {                               foreach my $type (@orderedstatus) { 
                                 $resulttext .= $alltypes{$type}.', ';                                  $resulttext .= $alltypes{$type}.', ';
                             }                              }
                             $resulttext =~ s/, $//;                              $resulttext =~ s/, $//;
                             $resulttext .= '</li>';                              $resulttext .= '</li>';
                         } else {                          }
                             $resulttext .= '<li>'.&mt('Institutional user status types deleted').'</li>';                          if ($changes{'inststatus'}{'inststatusguest'}) {
                               $resulttext .= '<li>'; 
                               if (@orderedguests) {
                                   $resulttext .= &mt('Types assignable to "non-institutional" usernames set to:').' ';
                                   foreach my $type (@orderedguests) {
                                       $resulttext .= $alltypes{$type}.', ';
                                   }
                                   $resulttext =~ s/, $//;
                               } else {
                                   $resulttext .= &mt('Types assignable to "non-institutional" usernames set to none.');
                               }
                               $resulttext .= '</li>';
                         }                          }
                     }                      }
                 } else {                  } else {
Line 13948  sub modify_scantron { Line 10751  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 13983  sub modify_scantron { Line 10786  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 14054  sub modify_scantron { Line 10796  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 14360  sub modify_coursecategories { Line 11067  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 14515  sub modify_serverstatuses { Line 11218  sub modify_serverstatuses {
 }  }
   
 sub modify_helpsettings {  sub modify_helpsettings {
     my ($r,$dom,$confname,$lastactref,%domconfig) = @_;      my ($r,$dom,$confname,%domconfig) = @_;
     my ($resulttext,$errors,%changes,%helphash);      my ($resulttext,$errors,%changes,%helphash);
     my %defaultchecked = ('submitbugs' => 'on');      my %defaultchecked = ('submitbugs' => 'on');
     my @offon = ('off','on');      my @offon = ('off','on');
     my @toggles = ('submitbugs');      my @toggles = ('submitbugs');
     my %current = ('submitbugs' => '',  
                    'adhoc'      => {},  
                   );  
     if (ref($domconfig{'helpsettings'}) eq 'HASH') {      if (ref($domconfig{'helpsettings'}) eq 'HASH') {
         %current = %{$domconfig{'helpsettings'}};          foreach my $item (@toggles) {
     }              if ($defaultchecked{$item} eq 'on') { 
     my %domdefaults = &Apache::lonnet::get_domain_defaults($dom,1);                  if ($domconfig{'helpsettings'}{$item} eq '') {
     foreach my $item (@toggles) {                      if ($env{'form.'.$item} eq '0') {
         if ($defaultchecked{$item} eq 'on') {                           $changes{$item} = 1;
             if ($current{$item} eq '') {  
                 if ($env{'form.'.$item} eq '0') {  
                     $changes{$item} = 1;  
                 }  
             } elsif ($current{$item} ne $env{'form.'.$item}) {  
                 $changes{$item} = 1;  
             }  
         } elsif ($defaultchecked{$item} eq 'off') {  
             if ($current{$item} eq '') {  
                 if ($env{'form.'.$item} eq '1') {  
                     $changes{$item} = 1;  
                 }  
             } elsif ($current{$item} ne $env{'form.'.$item}) {  
                 $changes{$item} = 1;  
             }  
         }  
         if (($env{'form.'.$item} eq '0') || ($env{'form.'.$item} eq '1')) {  
             $helphash{'helpsettings'}{$item} = $env{'form.'.$item};  
         }  
     }  
     my $maxnum = $env{'form.helproles_maxnum'};  
     my $confname = $dom.'-domainconfig';  
     my %existing=&Apache::lonnet::dump('roles',$dom,$confname,'rolesdef_');  
     my (@allpos,%newsettings,%changedprivs,$newrole);  
     my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom);  
     my @accesstypes = ('all','dh','da','none','status','inc','exc');  
     my %domhelpdesk = &Apache::lonnet::get_active_domroles($dom,['dh','da']);  
     my %lt = &Apache::lonlocal::texthash(  
                     s      => 'system',  
                     d      => 'domain',  
                     order  => 'Display order',  
                     access => 'Role usage',  
                     all    => 'All with domain helpdesk or helpdesk assistant role',  
                     dh     => 'All with domain helpdesk role',  
                     da     => 'All with domain helpdesk assistant role',  
                     none   => 'None',  
                     status => 'Determined based on institutional status',  
                     inc    => 'Include all, but exclude specific personnel',  
                     exc    => 'Exclude all, but include specific personnel',  
     );  
     for (my $num=0; $num<=$maxnum; $num++) {  
         my ($prefix,$identifier,$rolename,%curr);  
         if ($num == $maxnum) {  
             next unless ($env{'form.newcusthelp'} == $maxnum);  
             $identifier = 'custhelp'.$num;  
             $prefix = 'helproles_'.$num;  
             $rolename = $env{'form.custhelpname'.$num};  
             $rolename=~s/[^A-Za-z0-9]//gs;  
             next if ($rolename eq '');  
             next if (exists($existing{'rolesdef_'.$rolename}));  
             my %newprivs = &Apache::lonuserutils::custom_role_update($rolename,$identifier);  
             my $result = &Apache::lonnet::definerole($rolename,$newprivs{'s'},$newprivs{'d'},  
                                                      $newprivs{'c'},$confname,$dom);  
             if ($result ne 'ok') {  
                 $errors .= '<li><span class="LC_error">'.  
                            &mt('An error occurred storing the new custom role: [_1]',  
                            $result).'</span></li>';  
                 next;  
             } else {  
                 $changedprivs{$rolename} = \%newprivs;  
                 $newrole = $rolename;  
             }  
         } else {  
             $prefix = 'helproles_'.$num;  
             $rolename = $env{'form.'.$prefix};  
             next if ($rolename eq '');  
             next unless (exists($existing{'rolesdef_'.$rolename}));  
             $identifier = 'custhelp'.$num;  
             my %newprivs = &Apache::lonuserutils::custom_role_update($rolename,$identifier);  
             my %currprivs;  
             ($currprivs{'s'},$currprivs{'d'},$currprivs{'c'}) =  
                 split(/\_/,$existing{'rolesdef_'.$rolename});  
             foreach my $level ('c','d','s') {  
                 if ($newprivs{$level} ne $currprivs{$level}) {  
                     my $result = &Apache::lonnet::definerole($rolename,$newprivs{'s'},$newprivs{'d'},  
                                                              $newprivs{'c'},$confname,$dom);  
                     if ($result ne 'ok') {  
                         $errors .= '<li><span class="LC_error">'.  
                                    &mt('An error occurred storing privileges for existing role [_1]: [_2]',  
                                        $rolename,$result).'</span></li>';  
                     } else {  
                         $changedprivs{$rolename} = \%newprivs;  
                     }  
                     last;  
                 }  
             }  
             if (ref($current{'adhoc'}) eq 'HASH') {  
                 if (ref($current{'adhoc'}{$rolename}) eq 'HASH') {  
                     %curr = %{$current{'adhoc'}{$rolename}};  
                 }  
             }  
         }  
         my $newpos = $env{'form.'.$prefix.'_pos'};  
         $newpos =~ s/\D+//g;  
         $allpos[$newpos] = $rolename;  
         my $newdesc = $env{'form.'.$prefix.'_desc'};  
         $helphash{'helpsettings'}{'adhoc'}{$rolename}{'desc'} = $newdesc;  
         if ($curr{'desc'}) {  
             if ($curr{'desc'} ne $newdesc) {  
                 $changes{'customrole'}{$rolename}{'desc'} = 1;  
                 $newsettings{$rolename}{'desc'} = $newdesc;  
             }  
         } elsif ($newdesc ne '') {  
             $changes{'customrole'}{$rolename}{'desc'} = 1;  
             $newsettings{$rolename}{'desc'} = $newdesc;  
         }  
         my $access = $env{'form.'.$prefix.'_access'};  
         if (grep(/^\Q$access\E$/,@accesstypes)) {  
             $helphash{'helpsettings'}{'adhoc'}{$rolename}{'access'} = $access;  
             if ($access eq 'status') {  
                 my @statuses = &Apache::loncommon::get_env_multiple('form.'.$prefix.'_status');  
                 if (scalar(@statuses) == 0) {  
                     $helphash{'helpsettings'}{'adhoc'}{$rolename}{'access'} = 'none';  
                 } else {  
                     my (@shownstatus,$numtypes);  
                     $helphash{'helpsettings'}{'adhoc'}{$rolename}{$access} = [];  
                     if (ref($types) eq 'ARRAY') {  
                         $numtypes = scalar(@{$types});  
                         foreach my $type (sort(@statuses)) {  
                             if ($type eq 'default') {  
                                 push(@{$helphash{'helpsettings'}{'adhoc'}{$rolename}{$access}},$type);  
                             } elsif (grep(/^\Q$type\E$/,@{$types})) {  
                                 push(@{$helphash{'helpsettings'}{'adhoc'}{$rolename}{$access}},$type);  
                                 push(@shownstatus,$usertypes->{$type});  
                             }  
                         }  
                     }  
                     if (grep(/^default$/,@statuses)) {  
                         push(@shownstatus,$othertitle);  
                     }  
                     if (scalar(@shownstatus) == 1+$numtypes) {  
                         $helphash{'helpsettings'}{'adhoc'}{$rolename}{'access'} = 'all';  
                         delete($helphash{'helpsettings'}{'adhoc'}{$rolename}{'status'});  
                     } else {  
                         $newsettings{$rolename}{'status'} = join(' '.&mt('or').' ',@shownstatus);  
                         if (ref($curr{'status'}) eq 'ARRAY') {  
                             my @diffs = &Apache::loncommon::compare_arrays($helphash{'helpsettings'}{'adhoc'}{$rolename}{$access},$curr{$access});  
                             if (@diffs) {  
                                 $changes{'customrole'}{$rolename}{$access} = 1;  
                             }  
                         } elsif (@{$helphash{'helpsettings'}{'adhoc'}{$rolename}{$access}}) {  
                             $changes{'customrole'}{$rolename}{$access} = 1;  
                         }  
                     }  
                 }  
             } elsif (($access eq 'inc') || ($access eq 'exc')) {  
                 my @personnel = &Apache::loncommon::get_env_multiple('form.'.$prefix.'_staff_'.$access);  
                 my @newspecstaff;  
                 $helphash{'helpsettings'}{'adhoc'}{$rolename}{$access} = [];  
                 foreach my $person (sort(@personnel)) {  
                     if ($domhelpdesk{$person}) {  
                         push(@{$helphash{'helpsettings'}{'adhoc'}{$rolename}{$access}},$person);  
                     }                      }
                   } elsif ($domconfig{'helpsettings'}{$item} ne $env{'form.'.$item}) {
                       $changes{$item} = 1;
                 }                  }
                 if (ref($curr{$access}) eq 'ARRAY') {              } elsif ($defaultchecked{$item} eq 'off') {
                     my @diffs = &Apache::loncommon::compare_arrays($helphash{'helpsettings'}{'adhoc'}{$rolename}{$access},$curr{$access});                  if ($domconfig{'helpsettings'}{$item} eq '') {
                     if (@diffs) {                      if ($env{'form.'.$item} eq '1') {
                         $changes{'customrole'}{$rolename}{$access} = 1;                          $changes{$item} = 1;
                     }                      }
                 } elsif (@{$helphash{'helpsettings'}{'adhoc'}{$rolename}{$access}}) {                  } elsif ($domconfig{'helpsettings'}{$item} ne $env{'form.'.$item}) {
                     $changes{'customrole'}{$rolename}{$access} = 1;                      $changes{$item} = 1;
                 }  
                 foreach my $person (@{$helphash{'helpsettings'}{'adhoc'}{$rolename}{$access}}) {  
                     my ($uname,$udom) = split(/:/,$person);  
                         push(@newspecstaff,&Apache::loncommon::aboutmewrapper(&Apache::loncommon::plainname($uname,$udom,'lastname'),$uname,$udom));  
                 }                  }
                 $newsettings{$rolename}{$access} = join(', ',sort(@newspecstaff));  
             }              }
         } else {              if (($env{'form.'.$item} eq '0') || ($env{'form.'.$item} eq '1')) {
             $helphash{'helpsettings'}{'adhoc'}{$rolename}{'access'}= 'all';                  $helphash{'helpsettings'}{$item} = $env{'form.'.$item};
         }  
         unless ($curr{'access'} eq $access) {  
             $changes{'customrole'}{$rolename}{'access'} = 1;  
             $newsettings{$rolename}{'access'} = $lt{$helphash{'helpsettings'}{'adhoc'}{$rolename}{'access'}};  
         }  
     }  
     if (@allpos > 0) {  
         my $idx = 0;  
         foreach my $rolename (@allpos) {  
             if ($rolename ne '') {  
                 $helphash{'helpsettings'}{'adhoc'}{$rolename}{'order'} = $idx;  
                 if (ref($current{'adhoc'}) eq 'HASH') {  
                     if (ref($current{'adhoc'}{$rolename}) eq 'HASH') {  
                         if ($current{'adhoc'}{$rolename}{'order'} ne $idx) {  
                             $changes{'customrole'}{$rolename}{'order'} = 1;  
                             $newsettings{$rolename}{'order'} = $idx+1;  
                         }  
                     }  
                 }  
                 $idx ++;  
             }              }
         }          }
     }      }
Line 14726  sub modify_helpsettings { Line 11251  sub modify_helpsettings {
     if (keys(%changes) > 0) {      if (keys(%changes) > 0) {
         $putresult = &Apache::lonnet::put_dom('configuration',\%helphash,$dom);          $putresult = &Apache::lonnet::put_dom('configuration',\%helphash,$dom);
         if ($putresult eq 'ok') {          if ($putresult eq 'ok') {
             if (ref($helphash{'helpsettings'}) eq 'HASH') {              $resulttext = &mt('Changes made:').'<ul>';
                 $domdefaults{'submitbugs'} = $helphash{'helpsettings'}{'submitbugs'};  
                 if (ref($helphash{'helpsettings'}{'adhoc'}) eq 'HASH') {  
                     $domdefaults{'adhocroles'} = $helphash{'helpsettings'}{'adhoc'};  
                 }  
             }  
             my $cachetime = 24*60*60;  
             &Apache::lonnet::do_cache_new('domdefaults',$dom,\%domdefaults,$cachetime);  
             if (ref($lastactref) eq 'HASH') {  
                 $lastactref->{'domdefaults'} = 1;  
             }  
         } else {  
             $errors .= '<li><span class="LC_error">'.  
                        &mt('An error occurred storing the settings: [_1]',  
                            $putresult).'</span></li>';  
         }  
     }  
     if ((keys(%changes) && ($putresult eq 'ok')) || (keys(%changedprivs))) {  
         $resulttext = &mt('Changes made:').'<ul>';  
         my (%shownprivs,@levelorder);  
         @levelorder = ('c','d','s');  
         if ((keys(%changes)) && ($putresult eq 'ok')) {  
             foreach my $item (sort(keys(%changes))) {              foreach my $item (sort(keys(%changes))) {
                 if ($item eq 'submitbugs') {                  if ($item eq 'submitbugs') {
                     $resulttext .= '<li>'.&mt('Display link to: [_1] set to "'.$offon[$env{'form.'.$item}].'".',                      $resulttext .= '<li>'.&mt('Display link to: [_1] set to "'.$offon[$env{'form.'.$item}].'".',
                                               &Apache::loncommon::modal_link('http://bugs.loncapa.org',                                                &Apache::loncommon::modal_link('http://bugs.loncapa.org',
                                               &mt('LON-CAPA bug tracker'),600,500)).'</li>';                                                &mt('LON-CAPA bug tracker'),600,500)).'</li>';
                 } elsif ($item eq 'customrole') {  
                     if (ref($changes{'customrole'}) eq 'HASH') {  
                         my @keyorder = ('order','desc','access','status','exc','inc');  
                         my %keytext = &Apache::lonlocal::texthash(  
                                                                    order  => 'Order',  
                                                                    desc   => 'Role description',  
                                                                    access => 'Role usage',  
                                                                    status => 'Allowed institutional types',  
                                                                    exc    => 'Allowed personnel',  
                                                                    inc    => 'Disallowed personnel',  
                         );  
                         foreach my $role (sort(keys(%{$changes{'customrole'}}))) {  
                             if (ref($changes{'customrole'}{$role}) eq 'HASH') {  
                                 if ($role eq $newrole) {  
                                     $resulttext .= '<li>'.&mt('New custom role added: [_1]',  
                                                               $role).'<ul>';  
                                 } else {  
                                     $resulttext .= '<li>'.&mt('Existing custom role modified: [_1]',  
                                                               $role).'<ul>';  
                                 }  
                                 foreach my $key (@keyorder) {  
                                     if ($changes{'customrole'}{$role}{$key}) {  
                                         $resulttext .= '<li>'.&mt("[_1] set to: [_2]",  
                                                                   $keytext{$key},$newsettings{$role}{$key}).  
                                                        '</li>';  
                                     }  
                                 }  
                                 if (ref($changedprivs{$role}) eq 'HASH') {  
                                     $shownprivs{$role} = 1;  
                                     $resulttext .= '<li>'.&mt('Privileges set to :').'<ul>';  
                                     foreach my $level (@levelorder) {  
                                         foreach my $item (split(/\:/,$changedprivs{$role}{$level})) {  
                                             next if ($item eq '');  
                                             my ($priv) = split(/\&/,$item,2);  
                                             if (&Apache::lonnet::plaintext($priv)) {  
                                                 $resulttext .= '<li>'.&Apache::lonnet::plaintext($priv);  
                                                 unless ($level eq 'c') {  
                                                     $resulttext .= ' ('.$lt{$level}.')';  
                                                 }  
                                                 $resulttext .= '</li>';  
                                             }  
                                         }  
                                     }  
                                     $resulttext .= '</ul>';  
                                 }  
                                 $resulttext .= '</ul></li>';  
                             }  
                         }  
                     }  
                 }  
             }  
         }  
         if (keys(%changedprivs)) {  
             foreach my $role (sort(keys(%changedprivs))) {  
                 unless ($shownprivs{$role}) {  
                     $resulttext .= '<li>'.&mt('Existing custom role modified: [_1]',  
                                               $role).'<ul>'.  
                                    '<li>'.&mt('Privileges set to :').'<ul>';  
                     foreach my $level (@levelorder) {  
                         foreach my $item (split(/\:/,$changedprivs{$role}{$level})) {  
                             next if ($item eq '');  
                             my ($priv) = split(/\&/,$item,2);  
                             if (&Apache::lonnet::plaintext($priv)) {  
                                 $resulttext .= '<li>'.&Apache::lonnet::plaintext($priv);  
                                 unless ($level eq 'c') {  
                                     $resulttext .= ' ('.$lt{$level}.')';  
                                 }  
                                 $resulttext .= '</li>';  
                             }  
                         }  
                     }  
                     $resulttext .= '</ul></li></ul></li>';  
                 }                  }
             }              }
               $resulttext .= '</ul>';
           } else {
               $resulttext = &mt('No changes made to help settings');
               $errors .= '<li><span class="LC_error">'.
                          &mt('An error occurred storing the settings: [_1]',
                              $putresult).'</span></li>';
         }          }
         $resulttext .= '</ul>';  
     } else {  
         $resulttext = &mt('No changes made to help settings');  
     }      }
     if ($errors) {      if ($errors) {
         $resulttext .= '<br />'.&mt('The following errors occurred: ').'<ul>'.          $resulttext .= '<br />'.&mt('The following errors occurred: ').'<ul>'.
                                     $errors.'</ul>';                         $errors.'</ul>';
     }      }
     return $resulttext;      return $resulttext;
 }  }
Line 14843  sub modify_coursedefaults { Line 11278  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');      my @types = ('official','unofficial','community','textbook','placement');
     my @types = ('official','unofficial','community','textbook');  
     my %staticdefaults = (      my %staticdefaults = (
                            anonsurvey_threshold => 10,                             anonsurvey_threshold => 10,
                            uploadquota          => 500,                             uploadquota          => 500,
                            postsubmit           => 60,                             postsubmit           => 60,
                            mysqltables          => 172800,  
                          );                           );
     my %texoptions = (  
                         MathJax  => 'MathJax',  
                         mimetex  => &mt('Convert to Images'),  
                         tth      => &mt('TeX to HTML'),  
                      );  
     $defaultshash{'coursedefaults'} = {};      $defaultshash{'coursedefaults'} = {};
   
     if (ref($domconfig{'coursedefaults'}) ne 'HASH') {      if (ref($domconfig{'coursedefaults'}) ne 'HASH') {
Line 14900  sub modify_coursedefaults { Line 11330  sub modify_coursedefaults {
                 }                  }
                 $defaultshash{'coursedefaults'}{$item} = $newdef;                  $defaultshash{'coursedefaults'}{$item} = $newdef;
             } else {              } else {
                 my ($setting,$type) = ($item =~ /^(uploadquota|mysqltables)_(\w+)$/);                  my ($type) = ($item =~ /^\Quploadquota_\E(\w+)$/);
                 if (ref($domconfig{'coursedefaults'}{$setting}) eq 'HASH') {                  if (ref($domconfig{'coursedefaults'}{'uploadquota'}) eq 'HASH') {
                     $currdef = $domconfig{'coursedefaults'}{$setting}{$type};                      $currdef = $domconfig{'coursedefaults'}{'uploadquota'}{$type};
                 }                  }
                 $newdef =~ s/[^\w.\-]//g;                  $newdef =~ s/[^\w.\-]//g;
                 $defaultshash{'coursedefaults'}{$setting}{$type} = $newdef;                  $defaultshash{'coursedefaults'}{'uploadquota'}{$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;
                     }                      }
                 } elsif ($item =~ /^(uploadquota|mysqltables)_/) {                  } else {
                     my $setting = $1;                      unless (($currdef eq '') && ($newdef == $staticdefaults{'uploadquota'})) {
                     unless (($currdef eq '') && ($newdef == $staticdefaults{$setting})) {                          $changes{'uploadquota'} = 1;
                         $changes{$setting} = 1;  
                     }                      }
                 }                  }
             }              }
         }          }
         my $texengine;  
         if ($env{'form.texengine'} =~ /^(MathJax|mimetex|tth)$/) {  
             $texengine = $env{'form.texengine'};  
             my $currdef = $domconfig{'coursedefaults'}{'texengine'};  
             if ($currdef eq '') {  
                 unless ($texengine eq $Apache::lonnet::deftex) {  
                     $changes{'texengine'} = 1;  
                 }  
             } elsif ($currdef ne $texengine) {  
                 $changes{'texengine'} = 1;  
             }  
         }  
         if ($texengine ne '') {  
             $defaultshash{'coursedefaults'}{'texengine'} = $texengine;  
         }  
         my $currclone = $domconfig{'coursedefaults'}{'canclone'};          my $currclone = $domconfig{'coursedefaults'}{'canclone'};
         my @currclonecode;          my @currclonecode;
         if (ref($currclone) eq 'HASH') {          if (ref($currclone) eq 'HASH') {
Line 14943  sub modify_coursedefaults { Line 11358  sub modify_coursedefaults {
             }              }
         }          }
         my $newclone;          my $newclone;
         if ($env{'form.canclone'} =~ /^(none|domain|instcode)$/) {          if ($env{'form.canclone'} =~ /^(none|domain|instcode)$/) { 
             $newclone = $env{'form.canclone'};              $newclone = $env{'form.canclone'};
         }          }
         if ($newclone eq 'instcode') {          if ($newclone eq 'instcode') {
Line 14966  sub modify_coursedefaults { Line 11381  sub modify_coursedefaults {
                 $newclone eq '';                  $newclone eq '';
             }              }
         } elsif ($newclone ne '') {          } elsif ($newclone ne '') {
             $defaultshash{'coursedefaults'}{'canclone'} = $newclone;              $defaultshash{'coursedefaults'}{'canclone'} = $newclone; 
         }          } 
         if ($newclone ne $currclone) {          if ($newclone ne $currclone) {
             $changes{'canclone'} = 1;              $changes{'canclone'} = 1;
         }          }
Line 14985  sub modify_coursedefaults { Line 11400  sub modify_coursedefaults {
                 $defaultshash{'coursedefaults'}{'coursecredits'}{$type} = $credits{$type};                  $defaultshash{'coursedefaults'}{'coursecredits'}{$type} = $credits{$type};
             }              }
         } else {          } else {
             if ($env{'form.coursecredits'} eq '1') {              if ($env{'form.coursecredits'} eq '1') { 
                 foreach my $type (@types) {                  foreach my $type (@types) {
                     unless ($type eq 'community') {                      unless ($type eq 'community') {
                         if ($domconfig{'coursedefaults'}{'coursecredits'}{$type} ne $credits{$type}) {                          if ($domconfig{'coursedefaults'}{'coursecredits'}{$type} ne $credits{$type}) {        
                             $changes{'coursecredits'} = 1;                              $changes{'coursecredits'} = 1;
                         }                          }
                         $defaultshash{'coursedefaults'}{'coursecredits'}{$type} = $credits{$type};                          $defaultshash{'coursedefaults'}{'coursecredits'}{$type} = $credits{$type};
Line 15031  sub modify_coursedefaults { Line 11446  sub modify_coursedefaults {
                 }                  }
                 if (exists($currtimeout{$type})) {                  if (exists($currtimeout{$type})) {
                     if ($timeout ne $currtimeout{$type}) {                      if ($timeout ne $currtimeout{$type}) {
                         $changes{'postsubmit'} = 1;                          $changes{'postsubmit'} = 1; 
                     }                      }
                 } elsif ($timeout ne '') {                  } elsif ($timeout ne '') {
                     $changes{'postsubmit'} = 1;                      $changes{'postsubmit'} = 1;
Line 15053  sub modify_coursedefaults { Line 11468  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'})) {
                 foreach my $item ('uselcmath','usejsme','texengine') {                  foreach my $item ('canuse_pdfforms','uselcmath','usejsme') { 
                     if ($changes{$item}) {                      if ($changes{$item}) {
                         $domdefaults{$item}=$defaultshash{'coursedefaults'}{$item};                          $domdefaults{$item}=$defaultshash{'coursedefaults'}{$item};
                     }                      }
                 }                  } 
                 if ($changes{'coursecredits'}) {                  if ($changes{'coursecredits'}) {
                     if (ref($defaultshash{'coursedefaults'}{'coursecredits'}) eq 'HASH') {                      if (ref($defaultshash{'coursedefaults'}{'coursecredits'}) eq 'HASH') {
                         foreach my $type (keys(%{$defaultshash{'coursedefaults'}{'coursecredits'}})) {                          foreach my $type (keys(%{$defaultshash{'coursedefaults'}{'coursecredits'}})) {
Line 15107  sub modify_coursedefaults { Line 11522  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 15117  sub modify_coursedefaults { Line 11538  sub modify_coursedefaults {
                     if ($env{'form.'.$item} eq '1') {                      if ($env{'form.'.$item} eq '1') {
                         $resulttext .= '<li>'.&mt('Molecule editor uses JSME (HTML5), if supported by browser.').'</li>';                          $resulttext .= '<li>'.&mt('Molecule editor uses JSME (HTML5), if supported by browser.').'</li>';
                     } else {                      } else {
                         $resulttext .= '<li>'.&mt('Molecule editor uses JME (Java), if supported by client OS.').'</li>';                          $resulttext .= '<li>'.&mt('Molecule editor uses JME (Java), if supported by client OS.').'</li>'; 
                     }  
                 } elsif ($item eq 'texengine') {  
                     if ($defaultshash{'coursedefaults'}{'texengine'} ne '') {  
                         $resulttext .= '<li>'.&mt('Default method to display mathematics set to: "[_1]"',  
                                                   $texoptions{$defaultshash{'coursedefaults'}{'texengine'}}).'</li>';  
                     }                      }
                 } elsif ($item eq 'anonsurvey_threshold') {                  } elsif ($item eq 'anonsurvey_threshold') {
                     $resulttext .= '<li>'.&mt('Responder count required for display of anonymous survey submissions set to [_1].',$defaultshash{'coursedefaults'}{'anonsurvey_threshold'}).'</li>';                      $resulttext .= '<li>'.&mt('Responder count required for display of anonymous survey submissions set to [_1].',$defaultshash{'coursedefaults'}{'anonsurvey_threshold'}).'</li>';
Line 15132  sub modify_coursedefaults { Line 11548  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>';
                     } else {                      } else {
                         $resulttext .= '<li>'.&mt('Default quota for content uploaded via Course Editor remains default: [_1] MB',$staticdefaults{'uploadquota'}).'</li>';                          $resulttext .= '<li>'.&mt('Default quota for content uploaded via Course Editor remains default: [_1] MB',$staticdefaults{'uploadquota'}).'</li>';
                     }                      }
                 } elsif ($item eq 'mysqltables') {  
                     if (ref($defaultshash{'coursedefaults'}{'mysqltables'}) eq 'HASH') {  
                         $resulttext .= '<li>'.&mt('Lifetime of "Temporary" MySQL tables (student performance data) on homeserver').'<ul>'.  
                                        '<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('Textbook courses: [_1] s','<b>'.$defaultshash{'coursedefaults'}{'mysqltables'}{'textbook'}.'</b>').'</li>'.  
                                        '<li>'.&mt('Communities: [_1] s','<b>'.$defaultshash{'coursedefaults'}{'mysqltables'}{'community'}.'</b>').'</li>'.  
                                        '</ul>'.  
                                        '</li>';  
                     } else {  
                         $resulttext .= '<li>'.&mt('Lifetime of "Temporary" MySQL tables (student performance data) on homeserver remains default: [_1] s',$staticdefaults{'uploadquota'}).'</li>';  
                     }  
                 } elsif ($item eq 'postsubmit') {                  } elsif ($item eq 'postsubmit') {
                     if ($domdefaults{'postsubmit'} eq 'off') {                      if ($domdefaults{'postsubmit'} eq 'off') {
                         $resulttext .= '<li>'.&mt('Submit button(s) remain enabled on page after student makes submission.');                          $resulttext .= '<li>'.&mt('Submit button(s) remain enabled on page after student makes submission.');
                     } else {                      } else {
                         $resulttext .= '<li>'.&mt('Submit button(s) disabled on page after student makes submission').'; ';                          $resulttext .= '<li>'.&mt('Submit button(s) disabled on page after student makes submission').'; ';
                         if (ref($defaultshash{'coursedefaults'}{'postsubmit'}) eq 'HASH') {                          if (ref($defaultshash{'coursedefaults'}{'postsubmit'}) eq 'HASH') { 
                             $resulttext .= &mt('durations:').'<ul>';                              $resulttext .= &mt('durations:').'<ul>';
                             foreach my $type (@types) {                              foreach my $type (@types) {
                                 $resulttext .= '<li>';                                  $resulttext .= '<li>';
Line 15180  sub modify_coursedefaults { Line 11584  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>';
                             }                              }
                             $resulttext .= '</ul>';                              $resulttext .= '</ul>';
                         }                          }
                         $resulttext .= '</li>';                          $resulttext .= '</li>';    
                     }                      }
                 } elsif ($item eq 'coursecredits') {                  } elsif ($item eq 'coursecredits') {
                     if (ref($defaultshash{'coursedefaults'}{'coursecredits'}) eq 'HASH') {                      if (ref($defaultshash{'coursedefaults'}{'coursecredits'}) eq 'HASH') {
Line 15213  sub modify_coursedefaults { Line 11619  sub modify_coursedefaults {
                     } elsif ($defaultshash{'coursedefaults'}{'canclone'} eq 'domain') {                      } elsif ($defaultshash{'coursedefaults'}{'canclone'} eq 'domain') {
                         $resulttext .= '<li>'.&mt('By default, a course requester can clone any course from his/her domain.').'</li>';                          $resulttext .= '<li>'.&mt('By default, a course requester can clone any course from his/her domain.').'</li>';
                     } else {                      } else {
                         $resulttext .= '<li>'.&mt('By default, only course owner and coordinators may clone a course.').'</li>';                          $resulttext .= '<li>'.&mt('By default, only course owner and coordinators may clone a course.').'</li>'; 
                     }                      }
                 }                  }
             }              }
Line 15231  sub modify_coursedefaults { Line 11637  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 15448  sub modify_selfenrollment { Line 11854  sub modify_selfenrollment {
                         $resulttext .= '</ul></li>';                           $resulttext .= '</ul></li>'; 
                     }                      }
                 }                  }
             }                  if ((exists($changes{'admin'})) || (exists($changes{'default'}))) {
             if ((exists($changes{'admin'})) || (exists($changes{'default'}))) {                      my $cachetime = 24*60*60;
                 my $cachetime = 24*60*60;                      &Apache::lonnet::do_cache_new('domdefaults',$dom,\%domdefaults,$cachetime);
                 &Apache::lonnet::do_cache_new('domdefaults',$dom,\%domdefaults,$cachetime);                      if (ref($lastactref) eq 'HASH') {
                 if (ref($lastactref) eq 'HASH') {                          $lastactref->{'domdefaults'} = 1;
                     $lastactref->{'domdefaults'} = 1;                      }
                 }                  }
             }              }
             $resulttext .= '</ul>';              $resulttext .= '</ul>';
Line 15668  sub modify_usersessions { Line 12074  sub modify_usersessions {
                 }                  }
             }              }
             unless ($changes{'offloadnow'}) {              unless ($changes{'offloadnow'}) {
                 foreach my $lonhost (keys(%{$defaultshash{'usersessions'}{'offloadnow'}})) {                  foreach my $lonhost (keys(%{$defaultshash{'usersessions'}{'offloadnow'}})) { 
                     unless ($domconfig{'usersessions'}{'offloadnow'}{$lonhost}) {                      unless ($domconfig{'usersessions'}{'offloadnow'}{$lonhost}) {
                         $changes{'offloadnow'} = 1;                          $changes{'offloadnow'} = 1;
                         last;                          last;
Line 15699  sub modify_usersessions { Line 12105  sub modify_usersessions {
             }              }
             my $cachetime = 24*60*60;              my $cachetime = 24*60*60;
             &Apache::lonnet::do_cache_new('domdefaults',$dom,\%domdefaults,$cachetime);              &Apache::lonnet::do_cache_new('domdefaults',$dom,\%domdefaults,$cachetime);
             &Apache::lonnet::do_cache_new('usersessions',$dom,$defaultshash{'usersessions'},3600);  
             if (ref($lastactref) eq 'HASH') {              if (ref($lastactref) eq 'HASH') {
                 $lastactref->{'domdefaults'} = 1;                  $lastactref->{'domdefaults'} = 1;
                 $lastactref->{'usersessions'} = 1;  
             }              }
             if (keys(%changes) > 0) {              if (keys(%changes) > 0) {
                 my %lt = &usersession_titles();                  my %lt = &usersession_titles();
Line 15806  sub modify_loadbalancing { Line 12210  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 15855  sub modify_loadbalancing { Line 12259  sub modify_loadbalancing {
                         push(@offloadto,$target);                          push(@offloadto,$target);
                     }                      }
                 }                  }
             }                  $defaultshash{'loadbalancing'}{$balancer}{'targets'}{$sparetype} = \@offloadto;
             if ($env{'form.loadbalancing_target_'.$i.'_hosthere'} eq $sparetype) {  
                 unless(grep(/^\Q$balancer\E$/,@offloadto)) {  
                     push(@offloadto,$balancer);  
                 }  
             }  
             $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') {
Line 15912  sub modify_loadbalancing { Line 12299  sub modify_loadbalancing {
                 }                  }
                 if ($rule eq 'specific') {                  if ($rule eq 'specific') {
                     my $specifiedhost = $env{'form.loadbalancing_singleserver_'.$i.'_'.$type};                      my $specifiedhost = $env{'form.loadbalancing_singleserver_'.$i.'_'.$type};
                     if (exists($servers{$specifiedhost})) {                      if (exists($servers{$specifiedhost})) { 
                         $rule = $specifiedhost;                          $rule = $specifiedhost;
                     }                      }
                 }                  }
Line 15988  sub modify_loadbalancing { Line 12375  sub modify_loadbalancing {
                                         if ($rule eq '') {                                          if ($rule eq '') {
                                             $balancetext =  $ruletitles{'default'};                                              $balancetext =  $ruletitles{'default'};
                                         } elsif (($rule eq 'homeserver') || ($rule eq 'externalbalancer') ||                                          } elsif (($rule eq 'homeserver') || ($rule eq 'externalbalancer') ||
                                                  ($type eq '_LC_ipchange') || ($type eq '_LC_ipchangesso')) {                                                   ($type eq '_LC_ipchange') || ($type eq '_LC_ipchangesso')) { 
                                             if (($type eq '_LC_ipchange') || ($type eq '_LC_ipchangesso')) {                                              if (($type eq '_LC_ipchange') || ($type eq '_LC_ipchangesso')) {
                                                 foreach my $sparetype (@sparestypes) {                                                  foreach my $sparetype (@sparestypes) {
                                                     if (ref($defaultshash{'loadbalancing'}{$balancer}{'targets'}{$sparetype}) eq 'ARRAY') {                                                      if (ref($defaultshash{'loadbalancing'}{$balancer}{'targets'}{$sparetype}) eq 'ARRAY') {
Line 16028  sub modify_loadbalancing { Line 12415  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 16111  sub recurse_cat_deletes { Line 12494  sub recurse_cat_deletes {
     return;      return;
 }  }
   
   sub get_active_dcs {
       my ($dom) = @_;
       my $now = time;
       my %dompersonnel = &Apache::lonnet::get_domain_roles($dom,['dc'],$now,$now);
       my %domcoords;
       my $numdcs = 0;
       foreach my $server (keys(%dompersonnel)) {
           foreach my $user (sort(keys(%{$dompersonnel{$server}}))) {
               my ($trole,$uname,$udom,$runame,$rudom,$rsec) = split(/:/,$user);
               $domcoords{$uname.':'.$udom} = $dompersonnel{$server}{$user};
           }
       }
       return %domcoords;
   }
   
 sub active_dc_picker {  sub active_dc_picker {
     my ($dom,$numinrow,$inputtype,$name,%currhash) = @_;      my ($dom,$numinrow,$inputtype,$name,%currhash) = @_;
     my %domcoords = &Apache::lonnet::get_active_domroles($dom,['dc']);      my %domcoords = &get_active_dcs($dom);
     my @domcoord = keys(%domcoords);      my @domcoord = keys(%domcoords);
     if (keys(%currhash)) {      if (keys(%currhash)) {
         foreach my $dc (keys(%currhash)) {          foreach my $dc (keys(%currhash)) {
Line 16261  sub lonbalance_targets_js { Line 12659  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 16719  function updateCaptcha(caller,context) { Line 13117  function updateCaptcha(caller,context) {
             privtext.innerHTML = "$lt{'priv'}";              privtext.innerHTML = "$lt{'priv'}";
             versionitem.type = 'text';              versionitem.type = 'text';
             versionitem.size = '3';              versionitem.size = '3';
             versiontext.innerHTML = "$lt{'ver'}";              versiontext.innerHTML = "$lt{'ver'}"; 
         } else {          } else {
             pubitem.type = 'hidden';              pubitem.type = 'hidden';
             privitem.type = 'hidden';              privitem.type = 'hidden';
Line 16751  function toggleDisplay(domForm,caller) { Line 13149  function toggleDisplay(domForm,caller) {
         var optionsElement = domForm.coursecredits;          var optionsElement = domForm.coursecredits;
         var checkval = 1;          var checkval = 1;
         var dispval = 'block';          var dispval = 'block';
         var selfcreateRegExp = /^cancreate_emailverified/;  
         if (caller == 'emailoptions') {          if (caller == 'emailoptions') {
             optionsElement = domForm.cancreate_email;               optionsElement = domForm.cancreate_email; 
         }          }
Line 16762  function toggleDisplay(domForm,caller) { Line 13159  function toggleDisplay(domForm,caller) {
             optionsElement = domForm.canclone;              optionsElement = domForm.canclone;
             checkval = 'instcode';              checkval = 'instcode';
         }          }
         if (selfcreateRegExp.test(caller)) {  
             optionsElement = domForm.elements[caller];  
             checkval = 'other';  
             dispval = 'inline'  
         }  
         if (optionsElement.length) {          if (optionsElement.length) {
             var currval;              var currval;
             for (var i=0; i<optionsElement.length; i++) {              for (var i=0; i<optionsElement.length; i++) {
Line 16798  sub captcha_phrases { Line 13190  sub captcha_phrases {
                  original  => 'original (CAPTCHA)',                   original  => 'original (CAPTCHA)',
                  recaptcha => 'successor (ReCAPTCHA)',                   recaptcha => 'successor (ReCAPTCHA)',
                  notused   => 'unused',                   notused   => 'unused',
                  ver => 'ReCAPTCHA version (1 or 2)',                   ver => 'ReCAPTCHA version (1 or 2)', 
     );      );
 }  }
   
Line 16808  sub devalidate_remote_domconfs { Line 13200  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');
                       '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.2  
changed lines
  Added in v.1.271


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