Diff for /loncom/interface/domainprefs.pm between versions 1.27 and 1.144

version 1.27, 2007/09/12 12:01:04 version 1.144, 2011/07/29 14:25:36
Line 28 Line 28
 ###############################################################  ###############################################################
 ##############################################################  ##############################################################
   
   =pod
   
   =head1 NAME
   
   Apache::domainprefs.pm
   
   =head1 SYNOPSIS
   
   Handles configuration of a LON-CAPA domain.  
   
   This is part of the LearningOnline Network with CAPA project
   described at http://www.lon-capa.org.
   
   
   =head1 OVERVIEW
   
   Each institution using LON-CAPA will typically have a single domain designated 
   for use by individuals affliated with the institution.  Accordingly, each domain
   may define a default set of logos and a color scheme which can be used to "brand"
   the LON-CAPA instance. In addition, an institution will typically have a language
   and timezone which are used for the majority of courses.
   
   LON-CAPA provides a mechanism to display and modify these defaults, as well as a 
   host of other domain-wide settings which determine the types of functionality
   available to users and courses in the domain.
   
   There is also a mechanism to configure cataloging of courses in the domain, and
   controls on the operation of automated processes which govern such things as
   roster updates, user directory updates and processing of course requests.
   
   The domain coordination manual which is built dynamically on install/update of 
   LON-CAPA from the relevant help items provides more information about domain 
   configuration.
   
   Most of the domain settings are stored in the configuration.db GDBM file which is
   housed on the primary library server for the domain in /home/httpd/lonUsers/$dom,
   where $dom is the domain.  The configuration.db stores settings in a number of 
   frozen hashes of hashes.  In a few cases, domain information must be uploaded to
   the domain as files (e.g., image files for logos etc., or plain text files for
   bubblesheet formats).  In this case the domainprefs.pm must be running in a user
   session hosted on the primary library server in the domain, as these files are 
   stored in author space belonging to a special $dom-domainconfig user.   
   
   domainprefs.pm in combination with lonconfigsettings.pm will retrieve and display
   the current settings, and provides an interface to make modifications.
   
   =head1 SUBROUTINES
   
   =over
   
   =item print_quotas()
   
   Inputs: 4 
   
   $dom,$settings,$rowtotal,$action.
   
   $dom is the domain, $settings is a reference to a hash of current settings for
   the current context, $rowtotal is a reference to the scalar used to record the 
   number of rows displayed on the page, and $action is the context (either quotas 
   or requestcourses).
   
   The print_quotas routine was orginally created to display/store information
   about default quota sizes for portfolio spaces for the different types of 
   institutional affiliation in the domain (e.g., Faculty, Staff, Student etc.), 
   but is now also used to manage availability of user tools: 
   i.e., blogs, aboutme page, and portfolios, and the course request tool,
   used by course owners to request creation of a course.
   
   Outputs: 1
   
   $datatable  - HTML containing form elements which allow settings to be changed. 
   
   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 
   (official, unofficial and community).  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).
   which have the following effects:
   
   0
   
   =over
   
   - course requests are not allowed for this course types/affiliation
   
   =back
   
   approval 
   
   =over 
   
   - course requests must be approved by a Doman Coordinator in the 
   course's domain
   
   =back
   
   validate 
   
   =over
   
   - an institutional validation (e.g., check requestor is instructor
   of record) needs to be passed before the course will be created.  The required
   validation is in localenroll.pm on the primary library server for the course 
   domain.
   
   =back
   
   autolimit 
   
   =over
    
   - course requests will be processed automatically up to a limit of
   N requests for the course type for the particular requestor.
   If N is undefined, there is no limit to the number of course requests
   which a course owner may submit and have processed automatically. 
   
   =back
   
   =item modify_quotas() 
   
   =back
   
   =cut
   
 package Apache::domainprefs;  package Apache::domainprefs;
   
 use strict;  use strict;
Line 36  use Apache::lonnet; Line 161  use Apache::lonnet;
 use Apache::loncommon();  use Apache::loncommon();
 use Apache::lonhtmlcommon();  use Apache::lonhtmlcommon();
 use Apache::lonlocal;  use Apache::lonlocal;
 use LONCAPA();  use Apache::lonmsg();
   use Apache::lonconfigsettings;
   use LONCAPA qw(:DEFAULT :match);
 use LONCAPA::Enrollment;  use LONCAPA::Enrollment;
   use LONCAPA::lonauthcgi();
 use File::Copy;  use File::Copy;
   use Locale::Language;
   use DateTime::TimeZone;
   use DateTime::Locale;
   
 sub handler {  sub handler {
     my $r=shift;      my $r=shift;
Line 48  sub handler { Line 179  sub handler {
         return OK;          return OK;
     }      }
   
       my $context = 'domain';
     my $dom = $env{'request.role.domain'};      my $dom = $env{'request.role.domain'};
     my $domdesc = &Apache::lonnet::domain($dom,'description');      my $domdesc = &Apache::lonnet::domain($dom,'description');
     if (&Apache::lonnet::allowed('mau',$dom)) {      if (&Apache::lonnet::allowed('mau',$dom)) {
Line 60  sub handler { Line 192  sub handler {
     }      }
     &Apache::lonhtmlcommon::clear_breadcrumbs();      &Apache::lonhtmlcommon::clear_breadcrumbs();
     &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},      &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
                                             ['phase']);                                              ['phase','actions']);
     my $phase = "display";      my $phase = 'pickactions';
     if ( exists($env{'form.phase'}) ) {      if ( exists($env{'form.phase'}) ) {
         $phase = $env{'form.phase'};          $phase = $env{'form.phase'};
     }      }
     my %domconfig =      my %domconfig =
       &Apache::lonnet::get_dom('configuration',['login','rolecolors',        &Apache::lonnet::get_dom('configuration',['login','rolecolors',
                 'quotas','autoenroll','autoupdate','directorysrch',                  'quotas','autoenroll','autoupdate','autocreate',
                 'usercreation'],$dom);                  'directorysrch','usercreation','usermodification',
     my @prefs = (                  'contacts','defaults','scantron','coursecategories',
       { text => 'Default color schemes',                  'serverstatuses','requestcourses','helpsettings',
         help => 'Default_Color_Schemes',                  'coursedefaults','usersessions'],$dom);
         action => 'rolecolors',      my @prefs_order = ('rolecolors','login','defaults','quotas','autoenroll',
         header => [{col1 => 'Student Settings',                         'autoupdate','autocreate','directorysrch','contacts',
                     col2 => '',},                         'usercreation','usermodification','scantron',
                    {col1 => 'Coordinator Settings',                         'requestcourses','coursecategories','serverstatuses','helpsettings',
                     col2 => '',},                         'coursedefaults','usersessions');
                    {col1 => 'Author Settings',      my %prefs = (
                     col2 => '',},          'rolecolors' =>
                    {col1 => 'Administrator Settings',                     { text => 'Default color schemes',
                     col2 => '',}],                       help => 'Domain_Configuration_Color_Schemes',
         },                       header => [{col1 => 'Student Settings',
       { text => 'Log-in page options',                                   col2 => '',},
         help => 'Domain_Log-in_Page',                                  {col1 => 'Coordinator Settings',
         action => 'login',                                   col2 => '',},
         header => [{col1 => 'Item',                                  {col1 => 'Author Settings',
                     col2 => '',}],                                   col2 => '',},
         },                                  {col1 => 'Administrator Settings',
       { text => 'Default quotas for user portfolios',                                   col2 => '',}],
         help => 'Default_User_Quota',                      },
         action => 'quotas',          'login' =>
         header => [{col1 => 'User type',                      { text => 'Log-in page options',
                     col2 => 'Default quota'}],                        help => 'Domain_Configuration_Login_Page',
         },                        header => [{col1 => 'Item',
       { text => 'Auto-enrollment settings',                                    col2 => '',}],
         help => 'Domain_Auto_Enrollment',                      },
         action => 'autoenroll',  
         header => [{col1 => 'Configuration setting',          'defaults' => 
                     col2 => 'Value(s)'}],                      { text => 'Default authentication/language/timezone/portal',
         },                        help => 'Domain_Configuration_LangTZAuth',
       { text => 'Auto-update settings',                        header => [{col1 => 'Setting',
         help => 'Domain_Auto_Update',                                    col2 => 'Value'}],
         action => 'autoupdate',                      },
         header => [{col1 => 'Setting',          'quotas' => 
                     col2 => 'Value',},                      { text => 'User blogs, personal information pages, portfolios',
                    {col1 => 'User Population',                        help => 'Domain_Configuration_Quotas',
                     col2 => 'Updataeable user data'}],                        header => [{col1 => 'User affiliation',
         },                                    col2 => 'Available tools',
       { text => 'Institutional directory searches',                                    col3 => 'Portfolio quota',}],
         help => 'Domain_Directory_Search',                      },
         action => 'directorysrch',          'autoenroll' =>
         header => [{col1 => 'Setting',                     { text => 'Auto-enrollment settings',
                     col2 => 'Value',}],                       help => 'Domain_Configuration_Auto_Enrollment',
         },                       header => [{col1 => 'Configuration setting',
       { text => 'User creation',                                   col2 => 'Value(s)'}],
         help => 'Domain_User_Creation',                     },
         action => 'usercreation',          'autoupdate' => 
         header => [{col1 => 'Setting',                     { text => 'Auto-update settings',
                     col2 => 'Value',}],                       help => 'Domain_Configuration_Auto_Updates',
         },                       header => [{col1 => 'Setting',
                                    col2 => 'Value',},
                                   {col1 => 'Setting',
                                    col2 => 'Affiliation'},
                                   {col1 => 'User population',
                                    col2 => 'Updateable user data'}],
                     },
           'autocreate' => 
                     { text => 'Auto-course creation settings',
                        help => 'Domain_Configuration_Auto_Creation',
                        header => [{col1 => 'Configuration Setting',
                                    col2 => 'Value',}],
                     },
           'directorysrch' => 
                     { text => 'Institutional directory searches',
                       help => 'Domain_Configuration_InstDirectory_Search',
                       header => [{col1 => 'Setting',
                                   col2 => 'Value',}],
                     },
           'contacts' =>
                     { text => 'Contact Information',
                       help => 'Domain_Configuration_Contact_Info',
                       header => [{col1 => 'Setting',
                                   col2 => 'Value',}],
                     },
   
           'usercreation' => 
                     { text => 'User creation',
                       help => 'Domain_Configuration_User_Creation',
                       header => [{col1 => 'Format rule type',
                                   col2 => 'Format rules in force'},
                                  {col1 => 'User account creation',
                                   col2 => 'Usernames which may be created',},
                                  {col1 => 'Context',
                                   col2 => 'Assignable authentication types'}],
                     },
           'usermodification' =>
                     { text => 'User modification',
                       help => 'Domain_Configuration_User_Modification',
                       header => [{col1 => 'Target user has role',
                                   col2 => 'User information updateable in author context'},
                                  {col1 => 'Target user has role',
                                   col2 => 'User information updateable in course context'},
                                  {col1 => "Status of user",
                                   col2 => 'Information settable when self-creating account (if directory data blank)'}],
                     },
           'scantron' =>
                     { text => 'Bubblesheet format file',
                       help => 'Domain_Configuration_Scantron_Format',
                       header => [ {col1 => 'Item',
                                    col2 => '',
                                 }],
                     },
           'requestcourses' => 
                    {text => 'Request creation of courses',
                     help => 'Domain_Configuration_Request_Courses',
                     header => [{col1 => 'User affiliation',
                                 col2 => 'Availability/Processing of requests',},
                                {col1 => 'Setting',
                                 col2 => 'Value'}],
                    },
           'coursecategories' =>
                     { text => 'Cataloging of courses/communities',
                       help => 'Domain_Configuration_Cataloging_Courses',
                       header => [{col1 => 'Category settings',
                                   col2 => '',},
                                  {col1 => 'Categories',
                                   col2 => '',
                                  }],
                     },
           'serverstatuses' =>
                    {text   => 'Access to server status pages',
                     help   => 'Domain_Configuration_Server_Status',
                     header => [{col1 => 'Status Page',
                                 col2 => 'Other named users',
                                 col3 => 'Specific IPs',
                               }],
                    },
           'helpsettings' =>
                    {text   => 'Help page settings',
                     help   => 'Domain_Configuration_Help_Settings',
                     header => [{col1 => 'Authenticated Help Settings',
                                 col2 => ''},
                                {col1 => 'Unauthenticated Help Settings',
                                 col2 => ''}],
                    },
           'coursedefaults' => 
                    {text => 'Course/Community defaults',
                     help => 'Domain_Configuration_Course_Defaults',
                     header => [{col1 => 'Defaults which can be overridden in each course by a CC',
                                 col2 => 'Value',},
                                {col1 => 'Defaults which can be overridden for each course by a DC',
                                 col2 => 'Value',},],
                    },
           'privacy' => 
                    {text   => 'User Privacy',
                     help   => 'Domain_Configuration_User_Privacy',
                     header => [{col1 => 'Setting',
                                 col2 => 'Value',}],
                    },
           'usersessions' =>
                    {text  => 'User session hosting',
                     help  => 'Domain_Configuration_User_Sessions',
                     header => [{col1 => 'Hosting of users from other domains',
                                 col2 => 'Rules'},
                                {col1 => "Hosting domain's own users elsewhere",
                                 col2 => 'Rules'}],
                    },
     );      );
       my %servers = &dom_servers($dom);
       if (keys(%servers) > 1) {
           $prefs{'login'}  = { text   => 'Log-in page options',
                                help   => 'Domain_Configuration_Login_Page',
                               header => [{col1 => 'Log-in Service',
                                           col2 => 'Server Setting',},
                                          {col1 => 'Log-in Page Items',
                                           col2 => ''}],
                              };
       }
     my @roles = ('student','coordinator','author','admin');      my @roles = ('student','coordinator','author','admin');
       my @actions = &Apache::loncommon::get_env_multiple('form.actions');
     &Apache::lonhtmlcommon::add_breadcrumb      &Apache::lonhtmlcommon::add_breadcrumb
     ({href=>"javascript:changePage(document.$phase,'display')",      ({href=>"javascript:changePage(document.$phase,'pickactions')",
       text=>"Domain Configuration"});        text=>"Settings to display/modify"});
     my $confname = $dom.'-domainconfig';      my $confname = $dom.'-domainconfig';
     if ($phase eq 'process') {      if ($phase eq 'process') {
         &Apache::lonhtmlcommon::add_breadcrumb          &Apache::lonconfigsettings::make_changes($r,$dom,$phase,$context,\@prefs_order,\%prefs,\%domconfig,$confname,\@roles);
           ({href=>"javascript:changePage(document.$phase,'$phase')",      } elsif ($phase eq 'display') {
             text=>"Updated"});          &Apache::lonconfigsettings::display_settings($r,$dom,$phase,$context,\@prefs_order,\%prefs,\%domconfig,$confname);
         &print_header($r,$phase);      } else {
         foreach my $item (@prefs) {  
             $r->print('<h3>'.&mt($item->{'text'}).'</h3>'.  
                       &process_changes($r,$dom,$confname,  
                         $item->{'action'},\@roles,%domconfig));  
         }  
         $r->print('<p>');  
         &print_footer($r,$phase,'display','Back to actions menu');  
         $r->print('</p>');  
     } else {  
         if ($phase eq '') {  
             $phase = 'display';  
         }  
         my %helphash;     
         my $numprefs = @prefs;  
         &print_header($r,$phase);  
         if (keys(%domconfig) == 0) {          if (keys(%domconfig) == 0) {
             my $primarylibserv = &Apache::lonnet::domain($dom,'primary');              my $primarylibserv = &Apache::lonnet::domain($dom,'primary');
             my $perlvarref = &LONCAPA::Configuration::read_conf('loncapa.conf');              my @ids=&Apache::lonnet::current_machine_ids();
             my $hostid = $perlvarref->{'lonHostID'};              if (!grep(/^\Q$primarylibserv\E$/,@ids)) {
             if ($hostid ne $primarylibserv) {  
                 my %designhash = &Apache::loncommon::get_domainconf($dom);                  my %designhash = &Apache::loncommon::get_domainconf($dom);
                 my @loginimages = ('img','logo','domlogo');                  my @loginimages = ('img','logo','domlogo','login');
                 my $custom_img_count = 0;                  my $custom_img_count = 0;
                 foreach my $img (@loginimages) {                  foreach my $img (@loginimages) {
                     if ($designhash{$dom.'.login.'.$img} ne '') {                      if ($designhash{$dom.'.login.'.$img} ne '') {
Line 165  sub handler { Line 399  sub handler {
                     }                      }
                 }                  }
                 if ($custom_img_count > 0) {                  if ($custom_img_count > 0) {
                       &Apache::lonconfigsettings::print_header($r,$phase,$context);
                     my $switch_server = &check_switchserver($dom,$confname);                      my $switch_server = &check_switchserver($dom,$confname);
                     $r->print(&mt('Domain configuration settings have yet to be saved for this domain via the web-based domain preferences interface.').'<br />'.&mt("While this remains so, you must switch to the domain's primary library server in order to update settings.").'<br /><br />'.&mt("Thereafter, you will be able to update settings from this screen when logged in to any server in the LON-CAPA network (with a DC role selected in the domain), although you will still need to switch to the domain's primary library server to upload new images or logos.").'<br /><br />'.$switch_server.' '.&mt('to primary library server for domain: [_1]',$dom));                      $r->print(
       &mt('Domain configuration settings have yet to be saved for this domain via the web-based domain preferences interface.').'<br />'.
       &mt("While this remains so, you must switch to the domain's primary library server in order to update settings.").'<br /><br />'.
       &mt("Thereafter, (with a Domain Coordinator role selected in the domain) you will be able to update settings when logged in to any server in the LON-CAPA network.").'<br />'.
       &mt("However, you will still need to switch to the domain's primary library server to upload new images or logos.").'<br /><br />');
                       if ($switch_server) {
                           $r->print($switch_server.' '.&mt('to primary library server for domain: [_1]',$dom));
                       }
                       $r->print(&Apache::loncommon::end_page());
                     return OK;                      return OK;
                 }                  }
             }              }
         }          }
         $r->print('<table border="0" width="100%" cellpadding="2" cellspacing="4"><tr><td align="left" valign="top" width="45%">');          &Apache::lonconfigsettings::display_choices($r,$phase,$context,\@prefs_order,\%prefs);
         foreach my $item (@prefs) {  
             if ($item->{'action'} eq 'login') {  
                 $r->print('</td><td width="6%">&nbsp;</td><td align="left" valign="top" width="47%">');  
             }  
             &print_config_box($r,$dom,$confname,$phase,$item->{'action'},  
                               $item,$domconfig{$item->{'action'}});  
         }  
         $r->print('  
       </td>  
     </tr>  
    </table>');  
         &print_footer($r,$phase,'process','Save changes');  
     }      }
     return OK;      return OK;
 }  }
   
 sub process_changes {  sub process_changes {
     my ($r,$dom,$confname,$action,$roles,%domconfig) = @_;      my ($r,$dom,$confname,$action,$roles,$values) = @_;
       my %domconfig;
       if (ref($values) eq 'HASH') {
           %domconfig = %{$values};
       }
     my $output;      my $output;
     if ($action eq 'login') {      if ($action eq 'login') {
         $output = &modify_login($r,$dom,$confname,%domconfig);          $output = &modify_login($r,$dom,$confname,%domconfig);
Line 197  sub process_changes { Line 432  sub process_changes {
         $output = &modify_rolecolors($r,$dom,$confname,$roles,          $output = &modify_rolecolors($r,$dom,$confname,$roles,
                                      %domconfig);                                       %domconfig);
     } elsif ($action eq 'quotas') {      } elsif ($action eq 'quotas') {
         $output = &modify_quotas($dom,%domconfig);          $output = &modify_quotas($dom,$action,%domconfig);
     } elsif ($action eq 'autoenroll') {      } elsif ($action eq 'autoenroll') {
         $output = &modify_autoenroll($dom,%domconfig);          $output = &modify_autoenroll($dom,%domconfig);
     } elsif ($action eq 'autoupdate') {      } elsif ($action eq 'autoupdate') {
         $output = &modify_autoupdate($dom,%domconfig);          $output = &modify_autoupdate($dom,%domconfig);
       } elsif ($action eq 'autocreate') {
           $output = &modify_autocreate($dom,%domconfig);
     } elsif ($action eq 'directorysrch') {      } elsif ($action eq 'directorysrch') {
         $output = &modify_directorysrch($dom,%domconfig);          $output = &modify_directorysrch($dom,%domconfig);
     } elsif ($action eq 'usercreation') {      } elsif ($action eq 'usercreation') {
         $output = &modify_user_creation($dom,%domconfig);          $output = &modify_usercreation($dom,%domconfig);
       } elsif ($action eq 'usermodification') {
           $output = &modify_usermodification($dom,%domconfig);
       } elsif ($action eq 'contacts') {
           $output = &modify_contacts($dom,%domconfig);
       } elsif ($action eq 'defaults') {
           $output = &modify_defaults($dom,$r);
       } elsif ($action eq 'scantron') {
           $output = &modify_scantron($r,$dom,$confname,%domconfig);
       } elsif ($action eq 'coursecategories') {
           $output = &modify_coursecategories($dom,%domconfig);
       } elsif ($action eq 'serverstatuses') {
           $output = &modify_serverstatuses($dom,%domconfig);
       } elsif ($action eq 'requestcourses') {
           $output = &modify_quotas($dom,$action,%domconfig);
       } elsif ($action eq 'helpsettings') {
           $output = &modify_helpsettings($r,$dom,$confname,%domconfig);
       } elsif ($action eq 'coursedefaults') {
           $output = &modify_coursedefaults($dom,%domconfig);
       } elsif ($action eq 'usersessions') {
           $output = &modify_usersessions($dom,%domconfig);
     }      }
     return $output;      return $output;
 }  }
   
 sub print_config_box {  sub print_config_box {
     my ($r,$dom,$confname,$phase,$action,$item,$settings) = @_;      my ($r,$dom,$confname,$phase,$action,$item,$settings) = @_;
     $r->print('      my $rowtotal = 0;
          <table class="LC_nested_outer">      my $output;
       if ($action eq 'coursecategories') {
           $output = &coursecategories_javascript($settings);
       }
       $output .= 
            '<table class="LC_nested_outer">
           <tr>            <tr>
            <th>'.&mt($item->{text}).'&nbsp;</th></tr>');             <th align="left" valign="middle"><span class="LC_nobreak">'.
 #              &mt($item->{text}).'&nbsp;'.
 # FIXME - put the help link back in when the help files exist             &Apache::loncommon::help_open_topic($item->{'help'}).'</span></th>'."\n".
 #           <th>'.&mt($item->{text}).'&nbsp;'.            '</tr>';
 #           &Apache::loncommon::help_open_topic($item->{'help'}).'</th>      $rowtotal ++;
 #          </tr>');      my $numheaders = 1;
     if (($action eq 'autoupdate') || ($action eq 'rolecolors')) {      if (ref($item->{'header'}) eq 'ARRAY') {
         my $colspan = ($action eq 'rolecolors')?' colspan="2"':'';          $numheaders = scalar(@{$item->{'header'}});
         $r->print('      }
       if ($numheaders > 1) {
           my $colspan = '';
           if (($action eq 'rolecolors') || ($action eq 'coursecategories') || ($action eq 'helpsettings')) {
               $colspan = ' colspan="2"';
           }
           $output .= '
           <tr>            <tr>
            <td>             <td>
             <table class="LC_nested">              <table class="LC_nested">
              <tr class="LC_info_row">               <tr class="LC_info_row">
               <td class="LC_left_item"'.$colspan.'>'.$item->{'header'}->[0]->{'col1'}.'</td>                <td class="LC_left_item"'.$colspan.'>'.&mt($item->{'header'}->[0]->{'col1'}).'</td>
               <td class="LC_right_item">'.$item->{'header'}->[0]->{'col2'}.'</td>                <td class="LC_right_item">'.&mt($item->{'header'}->[0]->{'col2'}).'</td>
              </tr>');               </tr>';
           $rowtotal ++;
         if ($action eq 'autoupdate') {          if ($action eq 'autoupdate') {
             $r->print(&print_autoupdate('top',$dom,$settings));              $output .= &print_autoupdate('top',$dom,$settings,\$rowtotal);
         } else {          } elsif ($action eq 'usercreation') {
             $r->print(&print_rolecolors($phase,'student',$dom,$confname,$settings));              $output .= &print_usercreation('top',$dom,$settings,\$rowtotal);
           } elsif ($action eq 'usermodification') {
               $output .= &print_usermodification('top',$dom,$settings,\$rowtotal);
           } elsif ($action eq 'coursecategories') {
               $output .= &print_coursecategories('top',$dom,$item,$settings,\$rowtotal);
           } elsif ($action eq 'login') {
               $output .= &print_login('top',$dom,$confname,$phase,$settings,\$rowtotal);
               $colspan = ' colspan="2"';
           } elsif ($action eq 'requestcourses') {
               $output .= &print_quotas($dom,$settings,\$rowtotal,$action);
           } elsif ($action eq 'helpsettings') {
               $output .= &print_helpsettings('top',$dom,$confname,$settings,\$rowtotal);
           } elsif ($action eq 'usersessions') {
               $output .= &print_usersessions('top',$dom,$settings,\$rowtotal); 
           } elsif ($action eq 'rolecolors') {
               $output .= &print_rolecolors($phase,'student',$dom,$confname,$settings,\$rowtotal);
           } elsif ($action eq 'coursedefaults') {
               $output .= &print_coursedefaults('top',$dom,$settings,\$rowtotal);
         }          }
         $r->print('          $output .= '
            </table>             </table>
           </td>            </td>
          </tr>           </tr>
Line 244  sub print_config_box { Line 530  sub print_config_box {
            <td>             <td>
             <table class="LC_nested">              <table class="LC_nested">
              <tr class="LC_info_row">               <tr class="LC_info_row">
               <td class="LC_left_item"'.$colspan.'>'.$item->{'header'}->[1]->{'col1'}.'</td>                <td class="LC_left_item"'.$colspan.'>'.&mt($item->{'header'}->[1]->{'col1'}).'</td>';
               <td class="LC_right_item">'.$item->{'header'}->[1]->{'col2'}.'</td>          $output .= '
              </tr>');                <td class="LC_right_item"'.$colspan.'>'.&mt($item->{'header'}->[1]->{'col2'}).'</td>
                </tr>';
               $rowtotal ++;
         if ($action eq 'autoupdate') {          if ($action eq 'autoupdate') {
             $r->print(&print_autoupdate('bottom',$dom,$settings));              $output .= &print_autoupdate('middle',$dom,$settings,\$rowtotal).'
         } else {  
             $r->print(&print_rolecolors($phase,'coordinator',$dom,$confname,$settings).'  
            </table>             </table>
           </td>            </td>
          </tr>           </tr>
Line 258  sub print_config_box { Line 544  sub print_config_box {
            <td>             <td>
             <table class="LC_nested">              <table class="LC_nested">
              <tr class="LC_info_row">               <tr class="LC_info_row">
               <td class="LC_left_item"'.$colspan.'>'.$item->{'header'}->[2]->{'col1'}.'</td>                <td class="LC_left_item"'.$colspan.'>'.&mt($item->{'header'}->[2]->{'col1'}).'</td>
               <td class="LC_right_item">'.$item->{'header'}->[2]->{'col2'}.'</td>                <td class="LC_right_item">'.&mt($item->{'header'}->[2]->{'col2'}).'</td>      </tr>'.
               &print_autoupdate('bottom',$dom,$settings,\$rowtotal);
               $rowtotal ++;
           } elsif ($action eq 'usercreation') {
               $output .= &print_usercreation('middle',$dom,$settings,\$rowtotal).'
              </table>
             </td>
            </tr>
            <tr>
              <td>
               <table class="LC_nested">
                <tr class="LC_info_row">
                 <td class="LC_left_item"'.$colspan.'>'.&mt($item->{'header'}->[2]->{'col1'}).'</td>
                 <td class="LC_right_item">'.&mt($item->{'header'}->[2]->{'col2'}).'</td>             </tr>'.
               &print_usercreation('bottom',$dom,$settings,\$rowtotal);
               $rowtotal ++;
           } elsif ($action eq 'usermodification') {
               $output .= &print_usermodification('middle',$dom,$settings,\$rowtotal).'
              </table>
             </td>
            </tr>
            <tr>
              <td>
               <table class="LC_nested">
                <tr class="LC_info_row">
                 <td class="LC_left_item"'.$colspan.'>'.&mt($item->{'header'}->[2]->{'col1'}).'</td>
                 <td class="LC_right_item">'.&mt($item->{'header'}->[2]->{'col2'}).'</td>      </tr>'.
                          &print_usermodification('bottom',$dom,$settings,\$rowtotal);
               $rowtotal ++;
           } elsif ($action eq 'coursecategories') {
               $output .= &print_coursecategories('bottom',$dom,$item,$settings,\$rowtotal);
           } elsif ($action eq 'login') {
               $output .= &print_login('bottom',$dom,$confname,$phase,$settings,\$rowtotal);
           } elsif ($action eq 'requestcourses') {
               $output .= &print_courserequestmail($dom,$settings,\$rowtotal);
           } elsif ($action eq 'helpsettings') {
               $output .= &print_helpsettings('bottom',$dom,$confname,$settings,\$rowtotal);
           } elsif ($action eq 'usersessions') {
               $output .= &print_usersessions('bottom',$dom,$settings,\$rowtotal);
           } elsif ($action eq 'coursedefaults') {
               $output .= &print_coursedefaults('bottom',$dom,$settings,\$rowtotal);
           } elsif ($action eq 'rolecolors') {
               $output .= &print_rolecolors($phase,'coordinator',$dom,$confname,$settings,\$rowtotal).'
              </table>
             </td>
            </tr>
            <tr>
              <td>
               <table class="LC_nested">
                <tr class="LC_info_row">
                 <td class="LC_left_item"'.$colspan.' valign="top">'.
                  &mt($item->{'header'}->[2]->{'col1'}).'</td>
                 <td class="LC_right_item" valign="top">'.
                  &mt($item->{'header'}->[2]->{'col2'}).'</td>
              </tr>'.               </tr>'.
             &print_rolecolors($phase,'author',$dom,$confname,$settings).'              &print_rolecolors($phase,'author',$dom,$confname,$settings,\$rowtotal).'
            </table>             </table>
           </td>            </td>
          </tr>           </tr>
Line 269  sub print_config_box { Line 608  sub print_config_box {
            <td>             <td>
             <table class="LC_nested">              <table class="LC_nested">
              <tr class="LC_info_row">               <tr class="LC_info_row">
               <td class="LC_left_item"'.$colspan.'>'.$item->{'header'}->[3]->{'col1'}.'</td>                <td class="LC_left_item"'.$colspan.'>'.&mt($item->{'header'}->[3]->{'col1'}).'</td>
               <td class="LC_right_item">'.$item->{'header'}->[3]->{'col2'}.'</td>                <td class="LC_right_item">'.&mt($item->{'header'}->[3]->{'col2'}).'</td>
              </tr>'.               </tr>'.
             &print_rolecolors($phase,'admin',$dom,$confname,$settings));              &print_rolecolors($phase,'admin',$dom,$confname,$settings,\$rowtotal);
               $rowtotal += 2;
         }          }
     } else {      } else {
         $r->print('          $output .= '
           <tr>            <tr>
            <td>             <td>
             <table class="LC_nested">              <table class="LC_nested">
              <tr class="LC_info_row">');               <tr class="LC_info_row">';
         if (($action eq 'login') || ($action eq 'directorysrch')) {          if (($action eq 'login') || ($action eq 'directorysrch')) {
             $r->print('                $output .= '  
               <td class="LC_left_item" colspan="2">'.$item->{'header'}->[0]->{'col1'}.'</td>');                <td class="LC_left_item" colspan="2">'.&mt($item->{'header'}->[0]->{'col1'}).'</td>';
           } elsif ($action eq 'serverstatuses') {
               $output .= '
                 <td class="LC_left_item" valign="top">'.&mt($item->{'header'}->[0]->{'col1'}).
                 '<br />('.&mt('Automatic access for Dom. Coords.').')</td>';
   
           } else {
               $output .= '
                 <td class="LC_left_item" valign="top">'.&mt($item->{'header'}->[0]->{'col1'}).'</td>';
           }
           if (defined($item->{'header'}->[0]->{'col3'})) {
               $output .= '<td class="LC_left_item" valign="top">'.
                          &mt($item->{'header'}->[0]->{'col2'});
               if ($action eq 'serverstatuses') {
                   $output .= '<br />(<tt>'.&mt('user1:domain1,user2:domain2 etc.').'</tt>)';
               } 
         } else {          } else {
             $r->print('              $output .= '<td class="LC_right_item" valign="top">'.
               <td class="LC_left_item">'.$item->{'header'}->[0]->{'col1'}.'</td>');                         &mt($item->{'header'}->[0]->{'col2'});
           }
           $output .= '</td>';
           if ($item->{'header'}->[0]->{'col3'}) {
               $output .= '<td class="LC_right_item" valign="top">'.
                          &mt($item->{'header'}->[0]->{'col3'});
               if ($action eq 'serverstatuses') {
                   $output .= '<br />(<tt>'.&mt('IP1,IP2 etc.').'</tt>)';
               }
               $output .= '</td>';
         }          }
         $r->print('          $output .= '</tr>';
               <td class="LC_right_item">'.$item->{'header'}->[0]->{'col2'}.'</td>          $rowtotal ++;
              </tr>');  
         if ($action eq 'login') {          if ($action eq 'login') {
            $r->print(&print_login($dom,$confname,$phase,$settings));              $output .= &print_login('bottom',$dom,$confname,$phase,$settings,
                                       \$rowtotal);
         } elsif ($action eq 'quotas') {          } elsif ($action eq 'quotas') {
            $r->print(&print_quotas($dom,$settings));              $output .= &print_quotas($dom,$settings,\$rowtotal,$action);
         } elsif ($action eq 'autoenroll') {          } elsif ($action eq 'autoenroll') {
            $r->print(&print_autoenroll($dom,$settings));              $output .= &print_autoenroll($dom,$settings,\$rowtotal);
           } elsif ($action eq 'autocreate') {
               $output .= &print_autocreate($dom,$settings,\$rowtotal);
         } elsif ($action eq 'directorysrch') {          } elsif ($action eq 'directorysrch') {
            $r->print(&print_directorysrch($dom,$settings));              $output .= &print_directorysrch($dom,$settings,\$rowtotal);
         } elsif ($action eq 'usercreation') {          } elsif ($action eq 'contacts') {
            $r->print(&print_usercreation($dom,$settings));              $output .= &print_contacts($dom,$settings,\$rowtotal);
           } elsif ($action eq 'defaults') {
               $output .= &print_defaults($dom,\$rowtotal);
           } elsif ($action eq 'scantron') {
               $output .= &print_scantronformat($r,$dom,$confname,$settings,\$rowtotal);
           } elsif ($action eq 'serverstatuses') {
               $output .= &print_serverstatuses($dom,$settings,\$rowtotal);
           } elsif ($action eq 'helpsettings') {
               $output .= &print_helpsettings('top',$dom,$confname,$settings,\$rowtotal);
         }          }
     }      }
     $r->print('      $output .= '
    </table>     </table>
   </td>    </td>
  </tr>   </tr>
 </table><br />');  </table><br />';
     return;      return ($output,$rowtotal);
 }  }
   
 sub print_header {  sub print_login {
     my ($r,$phase) = @_;      my ($position,$dom,$confname,$phase,$settings,$rowtotal) = @_;
     my $js = '      my ($css_class,$datatable);
 <script type="text/javascript">      my %choices = &login_choices();
 function changePage(formname,newphase) {  
     formname.phase.value = newphase;  
     formname.submit();  
 }  
 '.  
 &color_pick_js().'  
 </script>  
 ';  
     $r->print(&Apache::loncommon::start_page('View/Modify Domain Settings',  
                                            $js));  
     $r->print(&Apache::lonhtmlcommon::breadcrumbs('Domain Settings'));  
     $r->print('  
 <form name="parmform" action="">  
 <input type="hidden" name="pres_marker" />  
 <input type="hidden" name="pres_type" />  
 <input type="hidden" name="pres_value" />  
 </form>  
 ');  
     $r->print('<form method="post" name="'.$phase.'" action="/adm/domainprefs"'.  
               ' enctype="multipart/form-data">');  
     return;  
 }  
   
 sub print_footer {      if ($position eq 'top') {
     my ($r,$phase,$newphase,$button_text) = @_;          my %servers = &dom_servers($dom);
     $button_text = &mt($button_text);          my $choice = $choices{'disallowlogin'};
     $r->print('<input type="hidden" name="phase" value="" />');          $css_class = ' class="LC_odd_row"';
     my $dest='"javascript:changePage(document.'.$phase.','."'$newphase'".')"';          $datatable .= '<tr'.$css_class.'><td>'.$choice.'</td>'.
     if ($phase eq 'process') {                        '<td align="right"><table><tr><th>'.$choices{'hostid'}.'</th>'.
         $r->print('<a href='.$dest.'>'.$button_text.'</a>');                        '<th>'.$choices{'server'}.'</th>'.
     } else {                        '<th>'.$choices{'serverpath'}.'</th>'.
         $r->print('<input type="button" name="store" value="'.                        '<th>'.$choices{'custompath'}.'</th>'.
                   $button_text.'" onclick='.$dest.' />');                        '<th><span class="LC_nobreak">'.$choices{'exempt'}.'</span></th></tr>'."\n";
           my %disallowed;
           if (ref($settings) eq 'HASH') {
               if (ref($settings->{'loginvia'}) eq 'HASH') {
                  %disallowed = %{$settings->{'loginvia'}};
               }
           }
           foreach my $lonhost (sort(keys(%servers))) {
               my $direct = 'selected="selected"';
               if (ref($disallowed{$lonhost}) eq 'HASH') {
                   if ($disallowed{$lonhost}{'server'} ne '') {
                       $direct = '';
                   }
               }
               $datatable .= '<tr><td>'.$servers{$lonhost}.'</td>'.
                             '<td><select name="'.$lonhost.'_server">'.
                             '<option value=""'.$direct.'>'.$choices{'directlogin'}.
                             '</option>';
               foreach my $hostid (keys(%servers)) {
                   next if ($servers{$hostid} eq $servers{$lonhost});
                   my $selected = '';
                   if (ref($disallowed{$lonhost}) eq 'HASH') {
                       if ($hostid eq $disallowed{$lonhost}{'server'}) {
                           $selected = 'selected="selected"';
                       }
                   }
                   $datatable .= '<option value="'.$hostid.'"'.$selected.'>'.
                                 $servers{$hostid}.'</option>';
               }
               $datatable .= '</select></td>'.
                             '<td><select name="'.$lonhost.'_serverpath">';
               foreach my $path ('','/','/adm/login','/adm/roles','custom') {
                   my $pathname = $path;
                   if ($path eq 'custom') {
                       $pathname = &mt('Custom Path').' ->';
                   }
                   my $selected = '';
                   if (ref($disallowed{$lonhost}) eq 'HASH') {
                       if ($path eq $disallowed{$lonhost}{'serverpath'}) {
                           $selected = 'selected="selected"';
                       }
                   } elsif ($path eq '') {
                       $selected = 'selected="selected"';
                   }
                   $datatable .= '<option value="'.$path.'"'.$selected.'>'.$pathname.'</option>';
               }
               $datatable .= '</select></td>';
               my ($custom,$exempt);
               if (ref($disallowed{$lonhost}) eq 'HASH') {
                   $custom = $disallowed{$lonhost}{'custompath'};
                   $exempt = $disallowed{$lonhost}{'exempt'};
               }
               $datatable .= '<td><input type="text" name="'.$lonhost.'_custompath" size="6" value="'.$custom.'" /></td>'.
                             '<td><input type="text" name="'.$lonhost.'_exempt" size="8" value="'.$exempt.'" /></td>'.
                             '</tr>';
           }
           $datatable .= '</table></td></tr>';
           return $datatable;
     }      }
     $r->print('</form>');  
     $r->print('<br />'.&Apache::loncommon::end_page());  
     return;  
 }  
   
 sub print_login {      my %defaultchecked = ( 
     my ($dom,$confname,$phase,$settings) = @_;                             'coursecatalog' => 'on',
     my %choices = &login_choices();                             'adminmail'     => 'off',
     my ($catalogon,$catalogoff,$adminmailon,$adminmailoff);                             'newuser'       => 'off',
     $catalogon = ' checked="checked" ';                           );
     $adminmailoff = ' checked="checked" ';      my @toggles = ('coursecatalog','adminmail','newuser');
     my @images = ('img','logo','domlogo');      my (%checkedon,%checkedoff);
       foreach my $item (@toggles) {
           if ($defaultchecked{$item} eq 'on') { 
               $checkedon{$item} = ' checked="checked" ';
               $checkedoff{$item} = ' ';
           } elsif ($defaultchecked{$item} eq 'off') {
               $checkedoff{$item} = ' checked="checked" ';
               $checkedon{$item} = ' ';
           }
       }
       my @images = ('img','logo','domlogo','login');
       my @logintext = ('textcol','bgcol');
     my @bgs = ('pgbg','mainbg','sidebg');      my @bgs = ('pgbg','mainbg','sidebg');
     my @links = ('link','alink','vlink');      my @links = ('link','alink','vlink');
     my %designhash = &Apache::loncommon::get_domainconf($dom);      my %designhash = &Apache::loncommon::get_domainconf($dom);
Line 370  sub print_login { Line 786  sub print_login {
                    );                     );
     foreach my $item (@images) {      foreach my $item (@images) {
         $defaults{$item} = $defaultdesign{'login.'.$item};          $defaults{$item} = $defaultdesign{'login.'.$item};
           $defaults{'showlogo'}{$item} = 1;
     }      }
     foreach my $item (@bgs) {      foreach my $item (@bgs) {
         $defaults{'bgs'}{$item} = $defaultdesign{'login.'.$item};          $defaults{'bgs'}{$item} = $defaultdesign{'login.'.$item};
     }      }
       foreach my $item (@logintext) {
           $defaults{'logintext'}{$item} = $defaultdesign{'login.'.$item};
       }
     foreach my $item (@links) {      foreach my $item (@links) {
         $defaults{'links'}{$item} = $defaultdesign{'login.'.$item};          $defaults{'links'}{$item} = $defaultdesign{'login.'.$item};
     }      }
     if (ref($settings) eq 'HASH') {      if (ref($settings) eq 'HASH') {
         if ($settings->{'coursecatalog'} eq '0') {          foreach my $item (@toggles) {
             $catalogoff = $catalogon;              if ($settings->{$item} eq '1') {
             $catalogon = ' ';                  $checkedon{$item} =  ' checked="checked" ';
         }                  $checkedoff{$item} = ' ';
         if ($settings->{'adminmail'} eq '1') {              } elsif ($settings->{$item} eq '0') {
             $adminmailon = $adminmailoff;                  $checkedoff{$item} =  ' checked="checked" ';
             $adminmailoff = ' ';                  $checkedon{$item} = ' ';
               }
         }          }
         foreach my $item (@images) {          foreach my $item (@images) {
             if ($settings->{$item} ne '') {              if (defined($settings->{$item})) {
                 $designs{$item} = $settings->{$item};                  $designs{$item} = $settings->{$item};
                 $is_custom{$item} = 1;                  $is_custom{$item} = 1;
             }              }
               if (defined($settings->{'showlogo'}{$item})) {
                   $designs{'showlogo'}{$item} = $settings->{'showlogo'}{$item};
               }
           }
           foreach my $item (@logintext) {
               if ($settings->{$item} ne '') {
                   $designs{'logintext'}{$item} = $settings->{$item};
                   $is_custom{$item} = 1;
               }
         }          }
         if ($settings->{'font'} ne '') {          if ($settings->{'font'} ne '') {
             $designs{'font'} = $settings->{'font'};              $designs{'font'} = $settings->{'font'};
Line 434  sub print_login { Line 864  sub print_login {
     }      }
     my %alt_text = &Apache::lonlocal::texthash  ( img => 'Log-in banner',      my %alt_text = &Apache::lonlocal::texthash  ( img => 'Log-in banner',
                                                   logo => 'Institution Logo',                                                    logo => 'Institution Logo',
                                                   domlogo => 'Domain Logo');                                                    domlogo => 'Domain Logo',
                                                     login => 'Login box');
     my $itemcount = 1;      my $itemcount = 1;
     my $css_class = $itemcount%2?' class="LC_odd_row"':'';      foreach my $item (@toggles) {
     my $datatable =           $css_class = $itemcount%2?' class="LC_odd_row"':'';
         '<tr'.$css_class.'><td colspan="2">'.$choices{'coursecatalog'}.          $datatable .=  
         '</td><td>'.              '<tr'.$css_class.'><td colspan="2">'.$choices{$item}.
         '<span class="LC_nobreak"><label><input type="radio" name="coursecatalog"'.              '</td><td>'.
         $catalogon.' value="1" />'.&mt('Yes').'</label>&nbsp;'.              '<span class="LC_nobreak"><label><input type="radio" name="'.
         '<label><input type="radio" name="coursecatalog"'.              $item.'"'.$checkedon{$item}.' value="1" />'.&mt('Yes').
         $catalogoff.'value="0" />'.&mt('No').'</label></span></td>'.              '</label>&nbsp;<label><input type="radio" name="'.$item.'"'.
         '</tr>';              $checkedoff{$item}.' value="0" />'.&mt('No').'</label></span></td>'.
     $itemcount ++;              '</tr>';
     $css_class = $itemcount%2?' class="LC_odd_row"':'';          $itemcount ++;
     $datatable .= '<tr'.$css_class.'>'.      }
         '<td colspan="2">'.$choices{'adminmail'}.'</td>'.      $datatable .= &display_color_options($dom,$confname,$phase,'login',$itemcount,\%choices,\%is_custom,\%defaults,\%designs,\@images,\@bgs,\@links,\%alt_text,$rowtotal,\@logintext);
         '<td><span class="LC_nobreak">'.  
         '<label><input type="radio" name="adminmail"'.  
         $adminmailon.' value="1" />'.&mt('Yes').'</label>&nbsp;'.  
         '<label><input type="radio" name="adminmail"'.  
         $adminmailoff.'value="0" />'.&mt('No').'</label></span></td></tr>';  
     $itemcount ++;  
     $datatable .= &display_color_options($dom,$confname,$phase,'login',$itemcount,\%choices,\%is_custom,\%defaults,\%designs,\@images,\@bgs,\@links,\%alt_text);  
     $datatable .= '</tr></table></td></tr>';      $datatable .= '</tr></table></td></tr>';
     return $datatable;      return $datatable;
 }  }
Line 463  sub print_login { Line 887  sub print_login {
 sub login_choices {  sub login_choices {
     my %choices =      my %choices =
         &Apache::lonlocal::texthash (          &Apache::lonlocal::texthash (
             coursecatalog => 'Display Course Catalog link?',              coursecatalog => 'Display Course/Community Catalog link?',
             adminmail => "Display Administrator's E-mail Address?",              adminmail     => "Display Administrator's E-mail Address?",
             img => "Header",              disallowlogin => "Login page requests redirected",
             logo => "Main Logo",              hostid        => "Server",
             domlogo => "Domain Logo",              server        => "Redirect to:",
             bgs => "Background colors",              serverpath    => "Path",
             links => "Link colors",              custompath    => "Custom", 
             font => "Font color",              exempt        => "Exempt IP(s)",
             pgbg => "Page",              directlogin   => "No redirect",
             mainbg => "Main panel",              newuser       => "Link to create a user account",
             sidebg => "Side panel",              img           => "Header",
             link => "Link",              logo          => "Main Logo",
             alink => "Active link",              domlogo       => "Domain Logo",
             vlink => "Visited link",              login         => "Log-in Header", 
               textcol       => "Text color",
               bgcol         => "Box color",
               bgs           => "Background colors",
               links         => "Link colors",
               font          => "Font color",
               pgbg          => "Header",
               mainbg        => "Page",
               sidebg        => "Login box",
               link          => "Link",
               alink         => "Active link",
               vlink         => "Visited link",
         );          );
     return %choices;      return %choices;
 }  }
   
 sub print_rolecolors {  sub print_rolecolors {
     my ($phase,$role,$dom,$confname,$settings) = @_;      my ($phase,$role,$dom,$confname,$settings,$rowtotal) = @_;
     my %choices = &color_font_choices();      my %choices = &color_font_choices();
     my @bgs = ('pgbg','tabbg','sidebg');      my @bgs = ('pgbg','tabbg','sidebg');
     my @links = ('link','alink','vlink');      my @links = ('link','alink','vlink');
Line 494  sub print_rolecolors { Line 929  sub print_rolecolors {
     my %defaults = (      my %defaults = (
                    img => $defaultdesign{$role.'.img'},                     img => $defaultdesign{$role.'.img'},
                    font => $defaultdesign{$role.'.font'},                     font => $defaultdesign{$role.'.font'},
      fontmenu => $defaultdesign{$role.'.fontmenu'},
                    );                     );
     foreach my $item (@bgs) {      foreach my $item (@bgs) {
         $defaults{'bgs'}{$item} = $defaultdesign{$role.'.'.$item};          $defaults{'bgs'}{$item} = $defaultdesign{$role.'.'.$item};
Line 511  sub print_rolecolors { Line 947  sub print_rolecolors {
                 $designs{'font'} = $settings->{$role}->{'font'};                  $designs{'font'} = $settings->{$role}->{'font'};
                 $is_custom{'font'} = 1;                  $is_custom{'font'} = 1;
             }              }
               if ($settings->{$role}->{'fontmenu'} ne '') {
                   $designs{'fontmenu'} = $settings->{$role}->{'fontmenu'};
                   $is_custom{'fontmenu'} = 1;
               }
             foreach my $item (@bgs) {              foreach my $item (@bgs) {
                 if ($settings->{$role}->{$item} ne '') {                  if ($settings->{$role}->{$item} ne '') {
                     $designs{'bgs'}{$item} = $settings->{$role}->{$item};                      $designs{'bgs'}{$item} = $settings->{$role}->{$item};
Line 529  sub print_rolecolors { Line 969  sub print_rolecolors {
             $designs{img} = $designhash{$dom.'.'.$role.'.img'};              $designs{img} = $designhash{$dom.'.'.$role.'.img'};
             $is_custom{'img'} = 1;              $is_custom{'img'} = 1;
         }          }
           if ($designhash{$dom.'.'.$role.'.fontmenu'} ne '') {
               $designs{fontmenu} = $designhash{$dom.'.'.$role.'.fontmenu'};
               $is_custom{'fontmenu'} = 1; 
           }
         if ($designhash{$dom.'.'.$role.'.font'} ne '') {          if ($designhash{$dom.'.'.$role.'.font'} ne '') {
             $designs{font} = $designhash{$dom.'.'.$role.'.font'};              $designs{font} = $designhash{$dom.'.'.$role.'.font'};
             $is_custom{'font'} = 1;              $is_custom{'font'} = 1;
Line 548  sub print_rolecolors { Line 992  sub print_rolecolors {
         }          }
     }      }
     my $itemcount = 1;      my $itemcount = 1;
     my $datatable = &display_color_options($dom,$confname,$phase,$role,$itemcount,\%choices,\%is_custom,\%defaults,\%designs,\@images,\@bgs,\@links,\%alt_text);      my $datatable = &display_color_options($dom,$confname,$phase,$role,$itemcount,\%choices,\%is_custom,\%defaults,\%designs,\@images,\@bgs,\@links,\%alt_text,$rowtotal);
     $datatable .= '</tr></table></td></tr>';      $datatable .= '</tr></table></td></tr>';
     return $datatable;      return $datatable;
 }  }
   
 sub display_color_options {  sub display_color_options {
     my ($dom,$confname,$phase,$role,$itemcount,$choices,$is_custom,$defaults,$designs,      my ($dom,$confname,$phase,$role,$itemcount,$choices,$is_custom,$defaults,$designs,
         $images,$bgs,$links,$alt_text) = @_;          $images,$bgs,$links,$alt_text,$rowtotal,$logintext) = @_;
     my $css_class = $itemcount%2?' class="LC_odd_row"':'';      my $css_class = $itemcount%2?' class="LC_odd_row"':'';
     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;'.$defaults->{'font'}.'</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 568  sub display_color_options { Line 1012  sub display_color_options {
     $datatable .= '<td><span class="LC_nobreak">'.      $datatable .= '<td><span class="LC_nobreak">'.
                   '<input type="text" size="10" name="'.$role.'_font"'.                    '<input type="text" size="10" name="'.$role.'_font"'.
                   ' value="'.$designs->{'font'}.'" />&nbsp;'.$fontlink.                    ' value="'.$designs->{'font'}.'" />&nbsp;'.$fontlink.
                     '&nbsp;<span id="css_'.$role.'_font" style="background-color: '.
                     $designs->{'font'}.';">&nbsp;&nbsp;&nbsp;</span>'.
                   '</span></td></tr>';                    '</span></td></tr>';
       unless ($role eq 'login') { 
           $datatable .= '<tr'.$css_class.'>'.
                         '<td>'.$choices->{'fontmenu'}.'</td>';
           if (!$is_custom->{'fontmenu'}) {
               $datatable .=  '<td>'.&mt('Default in use:').'&nbsp;<span id="css_default_'.$role.'_font" style="color: '.$defaults->{'fontmenu'}.';">'.$defaults->{'fontmenu'}.'</span></td>';
           } else {
               $datatable .= '<td>&nbsp;</td>';
           }
           $fontlink = &color_pick($phase,$role,'fontmenu',$choices->{'fontmenu'},$designs->{'fontmenu'});
           $datatable .= '<td><span class="LC_nobreak">'.
                         '<input type="text" size="10" name="'.$role.'_fontmenu"'.
                         ' value="'.$designs->{'fontmenu'}.'" />&nbsp;'.$fontlink.
                         '&nbsp;<span id="css_'.$role.'_fontmenu" style="background-color: '.
                         $designs->{'fontmenu'}.';">&nbsp;&nbsp;&nbsp;</span>'.
                         '</span></td></tr>';
       }
     my $switchserver = &check_switchserver($dom,$confname);      my $switchserver = &check_switchserver($dom,$confname);
     foreach my $img (@{$images}) {      foreach my $img (@{$images}) {
  $itemcount ++;   $itemcount ++;
         $css_class = $itemcount%2?' class="LC_odd_row"':'';          $css_class = $itemcount%2?' class="LC_odd_row"':'';
         $datatable .= '<tr'.$css_class.'>'.          $datatable .= '<tr'.$css_class.'>'.
                       '<td>'.$choices->{$img}.'</td>';                        '<td>'.$choices->{$img};
         my ($imgfile, $img_import);          my ($imgfile,$img_import,$login_hdr_pick,$logincolors);
           if ($role eq 'login') {
               if ($img eq 'login') {
                   $login_hdr_pick =
                       &login_header_options($img,$role,$defaults,$is_custom,$choices);
                   $logincolors =
                       &login_text_colors($img,$role,$logintext,$phase,$choices,
                                               $designs);
               } elsif ($img ne 'domlogo') {
                   $datatable.= &logo_display_options($img,$defaults,$designs);
               }
           }
           $datatable .= '</td>';
         if ($designs->{$img} ne '') {          if ($designs->{$img} ne '') {
             $imgfile = $designs->{$img};              $imgfile = $designs->{$img};
     $img_import = ($imgfile =~ m{^/adm/});      $img_import = ($imgfile =~ m{^/adm/});
Line 622  sub display_color_options { Line 1096  sub display_color_options {
                 }                  }
             }              }
             if ($showfile) {              if ($showfile) {
                 $showfile = &Apache::loncommon::lonhttpdurl($showfile);                  if ($showfile =~ m{^/(adm|res)/}) {
                 $fullsize =  &Apache::loncommon::lonhttpdurl($imgfile);                      if ($showfile =~ m{^/res/}) {
                 $datatable.= '<td>';                          my $local_showfile =
                 if (!$is_custom->{$img}) {                              &Apache::lonnet::filelocation('',$showfile);
                     $datatable .= &mt('Default in use:').'<br />';                          &Apache::lonnet::repcopy($local_showfile);
                       }
                       $showfile = &Apache::loncommon::lonhttpdurl($showfile);
                 }                  }
  if ($img_import) {                  if ($imgfile) {
     $datatable.= '<input type="hidden" name="'.$role.'_import_'.$img.'" value="'.$imgfile.'" />';                      if ($imgfile  =~ m{^/(adm|res)/}) {
  }                          if ($imgfile =~ m{^/res/}) {
                 $datatable.= '<a href="'.$fullsize.'" target="_blank"><img src="'.                              my $local_imgfile =
                              $showfile.'" alt="'.$alt_text->{$img}.                                  &Apache::lonnet::filelocation('',$imgfile);
                              '" border="0" /></a></td>';                              &Apache::lonnet::repcopy($local_imgfile);
                 if ($is_custom->{$img}) {                          }
                     $datatable.='<td><span class="LC_nobreak"><label><input type="checkbox" name="'.                          $fullsize = &Apache::loncommon::lonhttpdurl($imgfile);
                                 $role.'_del_'.$img.'" value="1" />'.&mt('Delete?').                      } else {
                                 '</label>&nbsp;'.&mt('Replace:').'</span><br />';                          $fullsize = $imgfile;
                 } else {                      }
                     $datatable.='<td valign="bottom">'.&mt('Upload:').'<br />';  
                 }                  }
                   $datatable .= '<td>';
                   if ($img eq 'login') {
                       $datatable .= $login_hdr_pick;
                   } 
                   $datatable .= &image_changes($is_custom->{$img},$alt_text->{$img},$img_import,
                                                $showfile,$fullsize,$role,$img,$imgfile,$logincolors);
             } else {              } else {
                 $datatable .= '<td colspan="2" class="LC_right_item"><br />'.                  $datatable .= '<td colspan="2" class="LC_right_item"><br />'.
                               &mt('Upload:');                                &mt('Upload:');
Line 652  sub display_color_options { Line 1133  sub display_color_options {
         if ($switchserver) {          if ($switchserver) {
             $datatable .= &mt('Upload to library server: [_1]',$switchserver);              $datatable .= &mt('Upload to library server: [_1]',$switchserver);
         } else {          } else {
             $datatable .='&nbsp;<input type="file" name="'.$role.'_'.$img.'" />';              if ($img ne 'login') { # suppress file selection for Log-in header
                   $datatable .='&nbsp;<input type="file" name="'.$role.'_'.$img.'" />';
               }
         }          }
         $datatable .= '</td></tr>';          $datatable .= '</td></tr>';
     }      }
Line 663  sub display_color_options { Line 1146  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>'.$choices->{$item}.'<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 677  sub display_color_options { Line 1160  sub display_color_options {
         my $link = &color_pick($phase,$role,$item,$choices->{$item},$designs->{'bgs'}{$item});          my $link = &color_pick($phase,$role,$item,$choices->{$item},$designs->{'bgs'}{$item});
         $datatable .= '<td align="center">'.$link;          $datatable .= '<td align="center">'.$link;
         if ($designs->{'bgs'}{$item}) {          if ($designs->{'bgs'}{$item}) {
             $datatable .= '<span style="background-color:'.$designs->{'bgs'}{$item}.'width: 10px">&nbsp;</span>';              $datatable .= '&nbsp;<span id="css_'.$role.'_'.$item.'" style="background-color: '.$designs->{'bgs'}{$item}.';">&nbsp;&nbsp;&nbsp;</span>';
         }          }
         $datatable .= '<br /><input type="text" size="8" name="'.$role.'_'.$item.'" value="'.$designs->{'bgs'}{$item}.          $datatable .= '<br /><input type="text" size="8" name="'.$role.'_'.$item.'" value="'.$designs->{'bgs'}{$item}.
                       '" /></td>';                        '" onblur = "javascript:colchg_span('."'css_".$role.'_'.$item."'".',this);" /></td>';
     }      }
     $datatable .= '</tr></table></td></tr>';      $datatable .= '</tr></table></td></tr>';
     $itemcount ++;      $itemcount ++;
Line 690  sub display_color_options { Line 1173  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 />'.$defaults->{'links'}{$item}.'</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 701  sub display_color_options { Line 1184  sub display_color_options {
     $datatable .= '<td class="LC_right_item">'.      $datatable .= '<td class="LC_right_item">'.
                   '<table border="0"><tr>';                    '<table border="0"><tr>';
     foreach my $item (@{$links}) {      foreach my $item (@{$links}) {
         $datatable .= '<td align="center">';          $datatable .= '<td align="center">'."\n".
         my $link = &color_pick($phase,$role,$item,$choices->{$item},$designs->{'links'}{$item});                        &color_pick($phase,$role,$item,$choices->{$item},
                                     $designs->{'links'}{$item});
         if ($designs->{'links'}{$item}) {          if ($designs->{'links'}{$item}) {
             $datatable.='<span style="color: '.$designs->{'links'}{$item}.';">'.              $datatable.='&nbsp;<span id="css_'.$role.'_'.$item.'" style="background-color: '.$designs->{'links'}{$item}.';">&nbsp;&nbsp;&nbsp;</span>';
                         $link.'</span>';  
         } else {  
             $datatable .= $link;  
         }          }
         $datatable .= '<br /><input type="text" size="8" name="'.$role.'_'.$item.'" value="'.$designs->{'links'}{$item}.          $datatable .= '<br /><input type="text" size="8" name="'.$role.'_'.$item.'" value="'.$designs->{'links'}{$item}.
                       '" /></td>';                        '" /></td>';
     }      }
       $$rowtotal += $itemcount;
     return $datatable;      return $datatable;
 }  }
   
 sub color_pick {  sub logo_display_options {
     my ($phase,$role,$item,$desc,$curcol) = @_;      my ($img,$defaults,$designs) = @_;
     my $link = '<a href="javascript:pjump('."'color_custom','".$desc.      my $checkedon;
                "','".$curcol."','".$role.'_'.$item."','parmform.pres','psub'".      if (ref($defaults) eq 'HASH') {
                ');">'.$desc.'</a>';          if (ref($defaults->{'showlogo'}) eq 'HASH') {
     return $link;              if ($defaults->{'showlogo'}{$img}) {
                   $checkedon = 'checked="checked" ';     
               }
           } 
       }
       if (ref($designs) eq 'HASH') {
           if (ref($designs->{'showlogo'}) eq 'HASH') {
               if (defined($designs->{'showlogo'}{$img})) {
                   if ($designs->{'showlogo'}{$img} == 0) {
                       $checkedon = '';
                   } elsif ($designs->{'showlogo'}{$img} == 1) {
                       $checkedon = 'checked="checked" ';
                   }
               }
           }
       }
       return '<br /><label>&nbsp;&nbsp;<input type="checkbox" name="'.
              'login_showlogo_'.$img.'" value="1" '.$checkedon.'/>'.
              &mt('show').'</label>'."\n";
 }  }
   
 sub color_pick_js {  sub login_header_options  {
     my $pjump_def = &Apache::lonhtmlcommon::pjump_javascript_definition();      my ($img,$role,$defaults,$is_custom,$choices) = @_;
     my $output = <<"ENDCOL";      my $output = '';
     function pclose() {      if ((!$is_custom->{'textcol'}) || (!$is_custom->{'bgcol'})) {
         parmwin=window.open("/adm/rat/empty.html","LONCAPAparms","height=350,width=350,scrollbars=no,menubar=no");          $output .= &mt('Text default(s):').'<br />';
         parmwin.close();          if (!$is_custom->{'textcol'}) {
               $output .= $choices->{'textcol'}.':&nbsp;'.$defaults->{'logintext'}{'textcol'}.
                          '&nbsp;&nbsp;&nbsp;';
           }
           if (!$is_custom->{'bgcol'}) {
               $output .= $choices->{'bgcol'}.':&nbsp;'.
                          '<span id="css_'.$role.'_font" style="background-color: '.
                          $defaults->{'logintext'}{'bgcol'}.';">&nbsp;&nbsp;&nbsp;</span>';
           }
           $output .= '<br />';
     }      }
       $output .='<br />';
       return $output;
   }
   
     $pjump_def  sub login_text_colors {
       my ($img,$role,$logintext,$phase,$choices,$designs) = @_;
       my $color_menu = '<table border="0"><tr>';
       foreach my $item (@{$logintext}) {
           my $link = &color_pick($phase,$role,$item,$choices->{$item},$designs->{'logintext'}{$item});
           $color_menu .= '<td align="center">'.$link;
           if ($designs->{'logintext'}{$item}) {
               $color_menu .= '&nbsp;<span id="css_'.$role.'_'.$item.'" style="background-color: '.$designs->{'logintext'}{$item}.';">&nbsp;&nbsp;&nbsp;</span>';
           }
           $color_menu .= '<br /><input type="text" size="8" name="'.$role.'_'.$item.'" value="'.
                          $designs->{'logintext'}{$item}.'" onblur = "javascript:colchg_span('."'css_".$role.'_'.$item."'".',this);" /></td>'.
                          '<td>&nbsp;</td>';
       }
       $color_menu .= '</tr></table><br />';
       return $color_menu;
   }
   
     function psub() {  sub image_changes {
         pclose();      my ($is_custom,$alt_text,$img_import,$showfile,$fullsize,$role,$img,$imgfile,$logincolors) = @_;
         if (document.parmform.pres_marker.value!='') {      my $output;
             if (document.parmform.pres_type.value!='') {      if ($img eq 'login') {
                 eval('document.display.'+              # suppress image for Log-in header
                      document.parmform.pres_marker.value+      } elsif (!$is_custom) {
                      '.value=document.parmform.pres_value.value;');          if ($img ne 'domlogo') {
             }              $output .= &mt('Default image:').'<br />';
         } else {          } else {
             document.parmform.pres_value.value='';              $output .= &mt('Default in use:').'<br />';
             document.parmform.pres_marker.value='';          }
       }
       if ($img eq 'login') { # suppress image for Log-in header
           $output .= '<td>'.$logincolors;
       } else {
           if ($img_import) {
               $output .= '<input type="hidden" name="'.$role.'_import_'.$img.'" value="'.$imgfile.'" />';
           }
           $output .= '<a href="'.$fullsize.'" target="_blank"><img src="'.
                      $showfile.'" alt="'.$alt_text.'" border="0" /></a></td>';
           if ($is_custom) {
               $output .= '<td>'.$logincolors.'<span class="LC_nobreak"><label>'.
                          '<input type="checkbox" name="'.
                          $role.'_del_'.$img.'" value="1" />'.&mt('Delete?').
                          '</label>&nbsp;'.&mt('Replace:').'</span><br />';
           } else {
               $output .= '<td valign="bottom">'.$logincolors.&mt('Upload:').'<br />';
         }          }
     }      }
 ENDCOL  
     return $output;      return $output;
 }  }
   
   sub color_pick {
       my ($phase,$role,$item,$desc,$curcol) = @_;
       my $link = '<a href="javascript:pjump('."'color_custom','".$desc.
                  "','".$curcol."','".$role.'_'.$item."','parmform.pres','psub'".
                  ');">'.$desc.'</a>';
       return $link;
   }
   
 sub print_quotas {  sub print_quotas {
     my ($dom,$settings) = @_;      my ($dom,$settings,$rowtotal,$action) = @_;
     my $datatable;      my $context;
     my ($othertitle,$usertypes,$types) = &sorted_inst_types($dom);      if ($action eq 'quotas') {
           $context = 'tools';
       } else {
           $context = $action;
       }
       my ($datatable,$defaultquota,@usertools,@options,%validations);
       my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom);
     my $typecount = 0;      my $typecount = 0;
     my $css_class;      my ($css_class,%titles);
       if ($context eq 'requestcourses') {
           @usertools = ('official','unofficial','community');
           @options =('norequest','approval','validate','autolimit');
           %validations = &Apache::lonnet::auto_courserequest_checks($dom);
           %titles = &courserequest_titles();
       } else {
           @usertools = ('aboutme','blog','portfolio');
           %titles = &tool_titles();
       }
     if (ref($types) eq 'ARRAY') {      if (ref($types) eq 'ARRAY') {
         foreach my $type (@{$types}) {          foreach my $type (@{$types}) {
               my $currdefquota;
               unless ($context eq 'requestcourses') {
                   if (ref($settings) eq 'HASH') {
                       if (ref($settings->{defaultquota}) eq 'HASH') {
                           $currdefquota = $settings->{defaultquota}->{$type}; 
                       } else {
                           $currdefquota = $settings->{$type};
                       }
                   }
               }
             if (defined($usertypes->{$type})) {              if (defined($usertypes->{$type})) {
                 $typecount ++;                  $typecount ++;
                 $css_class = $typecount%2?' class="LC_odd_row"':'';                  $css_class = $typecount%2?' class="LC_odd_row"':'';
                 $datatable .= '<tr'.$css_class.'>'.                   $datatable .= '<tr'.$css_class.'>'.
                               '<td>'.$usertypes->{$type}.'</td>'.                                '<td>'.$usertypes->{$type}.'</td>'.
                                 '<td class="LC_left_item">';
                   if ($context eq 'requestcourses') {
                       $datatable .= '<table><tr>';
                   }
                   my %cell;  
                   foreach my $item (@usertools) {
                       if ($context eq 'requestcourses') {
                           my ($curroption,$currlimit);
                           if (ref($settings) eq 'HASH') {
                               if (ref($settings->{$item}) eq 'HASH') {
                                   $curroption = $settings->{$item}->{$type};
                                   if ($curroption =~ /^autolimit=(\d*)$/) {
                                       $currlimit = $1; 
                                   }
                               }
                           }
                           if (!$curroption) {
                               $curroption = 'norequest';
                           }
                           $datatable .= '<th>'.$titles{$item}.'</th>';
                           foreach my $option (@options) {
                               my $val = $option;
                               if ($option eq 'norequest') {
                                   $val = 0;  
                               }
                               if ($option eq 'validate') {
                                   my $canvalidate = 0;
                                   if (ref($validations{$item}) eq 'HASH') { 
                                       if ($validations{$item}{$type}) {
                                           $canvalidate = 1;
                                       }
                                   }
                                   next if (!$canvalidate);
                               }
                               my $checked = '';
                               if ($option eq $curroption) {
                                   $checked = ' checked="checked"';
                               } elsif ($option eq 'autolimit') {
                                   if ($curroption =~ /^autolimit/) {
                                       $checked = ' checked="checked"';
                                   }                       
                               } 
                               $cell{$item} .= '<span class="LC_nobreak"><label>'.
                                     '<input type="radio" name="crsreq_'.$item.
                                     '_'.$type.'" value="'.$val.'"'.$checked.' />'.
                                     $titles{$option}.'</label>';
                               if ($option eq 'autolimit') {
                                   $cell{$item} .= '&nbsp;<input type="text" name="crsreq_'.
                                                   $item.'_limit_'.$type.'" size="1" '.
                                                   'value="'.$currlimit.'" />';
                               }
                               $cell{$item} .= '</span> ';
                               if ($option eq 'autolimit') {
                                   $cell{$item} .= $titles{'unlimited'};
                               }
                           }
                       } else {
                           my $checked = 'checked="checked" ';
                           if (ref($settings) eq 'HASH') {
                               if (ref($settings->{$item}) eq 'HASH') {
                                   if ($settings->{$item}->{$type} == 0) {
                                       $checked = '';
                                   } elsif ($settings->{$item}->{$type} == 1) {
                                       $checked =  'checked="checked" ';
                                   }
                               }
                           }
                           $datatable .= '<span class="LC_nobreak"><label>'.
                                         '<input type="checkbox" name="'.$context.'_'.$item.
                                         '" value="'.$type.'" '.$checked.'/>'.$titles{$item}.
                                         '</label></span>&nbsp; ';
                       }
                   }
                   if ($context eq 'requestcourses') {
                       $datatable .= '</tr><tr>';
                       foreach my $item (@usertools) {
                           $datatable .= '<td style="vertical-align: top">'.$cell{$item}.'</td>';  
                       }
                       $datatable .= '</tr></table>';
                   }
                   $datatable .= '</td>';
                   unless ($context eq 'requestcourses') {
                       $datatable .= 
                               '<td class="LC_right_item"><span class="LC_nobreak">'.                                '<td class="LC_right_item"><span class="LC_nobreak">'.
                               '<input type="text" name="quota_'.$type.                                '<input type="text" name="quota_'.$type.
                               '" value="'.$settings->{$type}.                                '" value="'.$currdefquota.
                               '" size="5" /> Mb</span></td></tr>';                                '" size="5" /> Mb</span></td>';
                   }
                   $datatable .= '</tr>';
             }              }
         }          }
     }      }
     my $defaultquota = '20';      unless ($context eq 'requestcourses') {
     if (ref($settings) eq 'HASH') {          $defaultquota = '20';
         if (defined($settings->{'default'})) {          if (ref($settings) eq 'HASH') {
             $defaultquota = $settings->{'default'};              if (ref($settings->{'defaultquota'}) eq 'HASH') {
                   $defaultquota = $settings->{'defaultquota'}->{'default'};
               } elsif (defined($settings->{'default'})) {
                   $defaultquota = $settings->{'default'};
               }
         }          }
     }      }
     $typecount ++;      $typecount ++;
     $css_class = $typecount%2?' class="LC_odd_row"':'';      $css_class = $typecount%2?' class="LC_odd_row"':'';
     $datatable .= '<tr'.$css_class.'>'.      $datatable .= '<tr'.$css_class.'>'.
                   '<td>'.$othertitle.'</td>'.                    '<td>'.$othertitle.'</td>'.
                   '<td class="LC_right_item"><span class="LC_nobreak">'.                    '<td class="LC_left_item">';
                   '<input type="text" name="defaultquota" value="'.      if ($context eq 'requestcourses') {
                   $defaultquota.'" size="5" /> Mb</span></td></tr>';          $datatable .= '<table><tr>';
       }
       my %defcell;
       foreach my $item (@usertools) {
           if ($context eq 'requestcourses') {
               my ($curroption,$currlimit);
               if (ref($settings) eq 'HASH') {
                   if (ref($settings->{$item}) eq 'HASH') {
                       $curroption = $settings->{$item}->{'default'};
                       if ($curroption =~ /^autolimit=(\d*)$/) {
                           $currlimit = $1;
                       }
                   }
               }
               if (!$curroption) {
                   $curroption = 'norequest';
               }
               $datatable .= '<th>'.$titles{$item}.'</th>';
               foreach my $option (@options) {
                   my $val = $option;
                   if ($option eq 'norequest') {
                       $val = 0;
                   }
                   if ($option eq 'validate') {
                       my $canvalidate = 0;
                       if (ref($validations{$item}) eq 'HASH') {
                           if ($validations{$item}{'default'}) {
                               $canvalidate = 1;
                           }
                       }
                       next if (!$canvalidate);
                   }
                   my $checked = '';
                   if ($option eq $curroption) {
                       $checked = ' checked="checked"';
                   } elsif ($option eq 'autolimit') {
                       if ($curroption =~ /^autolimit/) {
                           $checked = ' checked="checked"';
                       }
                   }
                   $defcell{$item} .= '<span class="LC_nobreak"><label>'.
                                     '<input type="radio" name="crsreq_'.$item.
                                     '_default" value="'.$val.'"'.$checked.' />'.
                                     $titles{$option}.'</label>';
                   if ($option eq 'autolimit') {
                       $defcell{$item} .= '&nbsp;<input type="text" name="crsreq_'.
                                          $item.'_limit_default" size="1" '.
                                          'value="'.$currlimit.'" />';
                   }
                   $defcell{$item} .= '</span> ';
                   if ($option eq 'autolimit') {
                       $defcell{$item} .= $titles{'unlimited'};
                   }
               }
           } else {
               my $checked = 'checked="checked" ';
               if (ref($settings) eq 'HASH') {
                   if (ref($settings->{$item}) eq 'HASH') {
                       if ($settings->{$item}->{'default'} == 0) {
                           $checked = '';
                       } elsif ($settings->{$item}->{'default'} == 1) {
                           $checked = 'checked="checked" ';
                       }
                   }
               }
               $datatable .= '<span class="LC_nobreak"><label>'.
                             '<input type="checkbox" name="'.$context.'_'.$item.
                             '" value="default" '.$checked.'/>'.$titles{$item}.
                             '</label></span>&nbsp; ';
           }
       }
       if ($context eq 'requestcourses') {
           $datatable .= '</tr><tr>';
           foreach my $item (@usertools) {
               $datatable .= '<td style="vertical-align: top">'.$defcell{$item}.'</td>';
           }
           $datatable .= '</tr></table>';
       }
       $datatable .= '</td>';
       unless ($context eq 'requestcourses') {
           $datatable .= '<td class="LC_right_item"><span class="LC_nobreak">'.
                         '<input type="text" name="defaultquota" value="'.
                         $defaultquota.'" size="5" /> Mb</span></td>';
       }
       $datatable .= '</tr>';
       $typecount ++;
       $css_class = $typecount%2?' class="LC_odd_row"':'';
       $datatable .= '<tr'.$css_class.'>'.
                     '<td>'.&mt('LON-CAPA Advanced Users').' ';
       if ($context eq 'requestcourses') {
           $datatable .= &mt('(overrides affiliation, if set)').
                         '</td>'.
                         '<td class="LC_left_item">'.
                         '<table><tr>';
       } else {
           $datatable .= &mt('(overrides affiliation, if checked)').
                         '</td>'.
                         '<td class="LC_left_item" colspan="2">'.
                         '<br />';
       }
       my %advcell;
       foreach my $item (@usertools) {
           if ($context eq 'requestcourses') {
               my ($curroption,$currlimit);
               if (ref($settings) eq 'HASH') {
                   if (ref($settings->{$item}) eq 'HASH') {
                       $curroption = $settings->{$item}->{'_LC_adv'};
                       if ($curroption =~ /^autolimit=(\d*)$/) {
                           $currlimit = $1;
                       }
                   }
               }
               $datatable .= '<th>'.$titles{$item}.'</th>';
               my $checked = '';
               if ($curroption eq '') {
                   $checked = ' checked="checked"';
               }
               $advcell{$item} .= '<span class="LC_nobreak"><label>'.
                                  '<input type="radio" name="crsreq_'.$item.
                                  '__LC_adv" value=""'.$checked.' />'.
                                  &mt('No override set').'</label></span>&nbsp; ';
               foreach my $option (@options) {
                   my $val = $option;
                   if ($option eq 'norequest') {
                       $val = 0;
                   }
                   if ($option eq 'validate') {
                       my $canvalidate = 0;
                       if (ref($validations{$item}) eq 'HASH') {
                           if ($validations{$item}{'_LC_adv'}) {
                               $canvalidate = 1;
                           }
                       }
                       next if (!$canvalidate);
                   }
                   my $checked = '';
                   if ($val eq $curroption) {
                       $checked = ' checked="checked"';
                   } elsif ($option eq 'autolimit') {
                       if ($curroption =~ /^autolimit/) {
                           $checked = ' checked="checked"';
                       }
                   }
                   $advcell{$item} .= '<span class="LC_nobreak"><label>'.
                                     '<input type="radio" name="crsreq_'.$item.
                                     '__LC_adv" value="'.$val.'"'.$checked.' />'.
                                     $titles{$option}.'</label>';
                   if ($option eq 'autolimit') {
                       $advcell{$item} .= '&nbsp;<input type="text" name="crsreq_'.
                                          $item.'_limit__LC_adv" size="1" '.
                                          'value="'.$currlimit.'" />';
                   }
                   $advcell{$item} .= '</span> ';
                   if ($option eq 'autolimit') {
                       $advcell{$item} .= $titles{'unlimited'};
                   }
               }
           } else {
               my $checked = 'checked="checked" ';
               if (ref($settings) eq 'HASH') {
                   if (ref($settings->{$item}) eq 'HASH') {
                       if ($settings->{$item}->{'_LC_adv'} == 0) {
                           $checked = '';
                       } elsif ($settings->{$item}->{'_LC_adv'} == 1) {
                           $checked = 'checked="checked" ';
                       }
                   }
               }
               $datatable .= '<span class="LC_nobreak"><label>'.
                             '<input type="checkbox" name="'.$context.'_'.$item.
                             '" value="_LC_adv" '.$checked.'/>'.$titles{$item}.
                             '</label></span>&nbsp; ';
           }
       }
       if ($context eq 'requestcourses') {
           $datatable .= '</tr><tr>';
           foreach my $item (@usertools) {
               $datatable .= '<td style="vertical-align: top">'.$advcell{$item}.'</td>';
           }
           $datatable .= '</tr></table>';
       }
       $datatable .= '</td></tr>';
       $$rowtotal += $typecount;
       return $datatable;
   }
   
   sub print_courserequestmail {
       my ($dom,$settings,$rowtotal) = @_;
       my ($now,$datatable,%dompersonnel,@domcoord,@currapproval,$rows);
       $now = time;
       $rows = 0;
       %dompersonnel = &Apache::lonnet::get_domain_roles($dom,['dc'],$now,$now);
       foreach my $server (keys(%dompersonnel)) {
           foreach my $user (sort(keys(%{$dompersonnel{$server}}))) {
               my ($trole,$uname,$udom,$runame,$rudom,$rsec) = split(/:/,$user);
               if (!grep(/^$uname:$udom$/,@domcoord)) {
                   push(@domcoord,$uname.':'.$udom);
               }
           }
       }
       if (ref($settings) eq 'HASH') {
           if (ref($settings->{'notify'}) eq 'HASH') {
               if ($settings->{'notify'}{'approval'} ne '') {
                  @currapproval = split(',',$settings->{'notify'}{'approval'});
               }
           }
       }
       if (@currapproval) {
           foreach my $dc (@currapproval) {
               unless (grep(/^\Q$dc\E$/,@domcoord)) {
                   push(@domcoord,$dc);
               }
           }
       }
       @domcoord = sort(@domcoord);
       my $numinrow = 4;
       my $numdc = @domcoord;
       my $css_class = 'class="LC_odd_row"';
       $datatable = '<tr'.$css_class.'>'.
                    ' <td>'.&mt('Receive notification of course requests requiring approval.').
                    ' </td>'.
                    ' <td class="LC_left_item">';
       if (@domcoord > 0) {
           $datatable .= '<table>';
           for (my $i=0; $i<$numdc; $i++) {
               my $rem = $i%($numinrow);
               if ($rem == 0) {
                   if ($i > 0) {
                       $datatable .= '</tr>';
                   }
                   $datatable .= '<tr>';
                   $rows ++;
               }
               my $check = ' ';
               if (grep(/^\Q$domcoord[$i]\E$/,@currapproval)) {
                   $check = ' checked="checked" ';
               }
               my ($uname,$udom) = split(':',$domcoord[$i]);
               my $fullname = &Apache::loncommon::plainname($uname,$udom);
               if ($i == $numdc-1) {
                   my $colsleft = $numinrow-$rem;
                   if ($colsleft > 1) {
                       $datatable .= '<td colspan="'.$colsleft.'" class="LC_left_item">';
                   } else {
                       $datatable .= '<td class="LC_left_item">';
                   }
               } else {
                   $datatable .= '<td class="LC_left_item">';
               }
               $datatable .= '<span class="LC_nobreak"><label>'.
                             '<input type="checkbox" name="reqapprovalnotify" '.
                             'value="'.$domcoord[$i].'"'.$check.'/>'.
                             $fullname.'</label></span></td>';
           }
           $datatable .= '</tr></table>';
       } else {
           $datatable .= &mt('There are no active Domain Coordinators');
           $rows ++;
       }
       $datatable .='</td></tr>';
       $$rowtotal += $rows;
     return $datatable;      return $datatable;
 }  }
   
 sub print_autoenroll {  sub print_autoenroll {
     my ($dom,$settings) = @_;      my ($dom,$settings,$rowtotal) = @_;
     my $autorun = &Apache::lonnet::auto_run(undef,$dom),      my $autorun = &Apache::lonnet::auto_run(undef,$dom),
     my ($defdom,$runon,$runoff);      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 808  sub print_autoenroll { Line 1732  sub print_autoenroll {
                 $runon = ' ';                  $runon = ' ';
             }              }
         }          }
           if (exists($settings->{'co-owners'})) {
               if ($settings->{'co-owners'} eq '0') {
                   $coownersoff = ' checked="checked" ';
                   $coownerson = ' ';
               } else {
                   $coownerson = ' checked="checked" ';
                   $coownersoff = ' ';
               }
           } else {
               $coownersoff = ' checked="checked" ';
               $coownerson = ' ';
           }
         if (exists($settings->{'sender_domain'})) {          if (exists($settings->{'sender_domain'})) {
             $defdom = $settings->{'sender_domain'};              $defdom = $settings->{'sender_domain'};
         }          }
Line 821  sub print_autoenroll { Line 1757  sub print_autoenroll {
         }          }
     }      }
     my $domform = &Apache::loncommon::select_dom_form($defdom,'sender_domain',1);      my $domform = &Apache::loncommon::select_dom_form($defdom,'sender_domain',1);
       my $notif_sender;
       if (ref($settings) eq 'HASH') {
           $notif_sender = $settings->{'sender_uname'};
       }
     my $datatable='<tr class="LC_odd_row">'.      my $datatable='<tr class="LC_odd_row">'.
                   '<td>'.&mt('Auto-enrollment active?').'</td>'.                    '<td>'.&mt('Auto-enrollment active?').'</td>'.
                   '<td class="LC_right_item"><span class="LC_nobreak"><label>'.                    '<td class="LC_right_item"><span class="LC_nobreak"><label>'.
Line 833  sub print_autoenroll { Line 1773  sub print_autoenroll {
                   '</td><td class="LC_right_item"><span class="LC_nobreak">'.                    '</td><td class="LC_right_item"><span class="LC_nobreak">'.
                   &mt('username').':&nbsp;'.                    &mt('username').':&nbsp;'.
                   '<input type="text" name="sender_uname" value="'.                    '<input type="text" name="sender_uname" value="'.
                   $settings->{'sender_uname'}.                    $notif_sender.'" size="10" />&nbsp;&nbsp;'.&mt('domain').
                   '" size="10" />&nbsp;&nbsp;'.&mt('domain').                    ':&nbsp;'.$domform.'</span></td></tr>'.
                   ':&nbsp;'.$domform.'</span></td></tr>';                    '<tr class="LC_odd_row">'.
                     '<td>'.&mt('Automatically assign co-ownership').'</td>'.
                     '<td class="LC_right_item"><span class="LC_nobreak"><label>'.
                     '<input type="radio" name="autoassign_coowners"'.
                     $coownerson.' value="1" />'.&mt('Yes').'</label>&nbsp;'.
                     '<label><input type="radio" name="autoassign_coowners"'.
                     $coownersoff.' value="0" />'.&mt('No').'</label></span></td>'.
                     '</tr>';
       $$rowtotal += 3;
     return $datatable;      return $datatable;
 }  }
   
 sub print_autoupdate {  sub print_autoupdate {
     my ($position,$dom,$settings) = @_;      my ($position,$dom,$settings,$rowtotal) = @_;
     my $datatable;      my $datatable;
     if ($position eq 'top') {      if ($position eq 'top') {
         my $updateon = ' ';          my $updateon = ' ';
Line 876  sub print_autoupdate { Line 1824  sub print_autoupdate {
                   '<label><input type="radio" name="classlists"'.                    '<label><input type="radio" name="classlists"'.
                   $classlistsoff.'value="0" />'.&mt('No').'</label></span></td>'.                    $classlistsoff.'value="0" />'.&mt('No').'</label></span></td>'.
                   '</tr>';                    '</tr>';
           $$rowtotal += 2;
       } elsif ($position eq 'middle') {
           my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom);
           my $numinrow = 3;
           my $locknamesettings;
           $datatable .= &insttypes_row($settings,$types,$usertypes,
                                        $dom,$numinrow,$othertitle,
                                       'lockablenames');
           $$rowtotal ++;
     } else {      } else {
         my ($othertitle,$usertypes,$types) = &sorted_inst_types($dom);          my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom);
         my @fields = ('lastname','firstname','middlename','gen',          my @fields = ('lastname','firstname','middlename','generation',
                       'permanentemail','id');                        'permanentemail','id');
         my %fieldtitles = &Apache::lonlocal::texthash (          my %fieldtitles = &Apache::loncommon::personal_data_fieldtitles();
                             id => 'Student/Employee ID',  
                             permanentemail => 'E-mail address',  
                             lastname => 'Last Name',  
                             firstname => 'First Name',  
                             middlename => 'Middle Name',  
                             gen => 'Generation',  
                       );  
         my $numrows = 0;          my $numrows = 0;
         if (ref($types) eq 'ARRAY') {          if (ref($types) eq 'ARRAY') {
             if (@{$types} > 0) {              if (@{$types} > 0) {
                 $datatable =                   $datatable = 
                     &usertype_update_row($settings,$usertypes,\%fieldtitles,                      &usertype_update_row($settings,$usertypes,\%fieldtitles,
                                          \@fields,$types,\$numrows);                                           \@fields,$types,\$numrows);
                       $$rowtotal += @{$types}; 
             }              }
         }          }
         $datatable .=           $datatable .= 
             &usertype_update_row($settings,{'default' => $othertitle},              &usertype_update_row($settings,{'default' => $othertitle},
                                  \%fieldtitles,\@fields,['default'],                                   \%fieldtitles,\@fields,['default'],
                                  \$numrows);                                   \$numrows);
           $$rowtotal ++;     
       }
       return $datatable;
   }
   
   sub print_autocreate {
       my ($dom,$settings,$rowtotal) = @_;
       my (%createon,%createoff);
       my $curr_dc;
       my @types = ('xml','req');
       if (ref($settings) eq 'HASH') {
           foreach my $item (@types) {
               $createoff{$item} = ' checked="checked" ';
               $createon{$item} = ' ';
               if (exists($settings->{$item})) {
                   if ($settings->{$item}) {
                       $createon{$item} = ' checked="checked" ';
                       $createoff{$item} = ' ';
                   }
               }
           }
           $curr_dc = $settings->{'xmldc'};
       } else {
           foreach my $item (@types) {
               $createoff{$item} = ' checked="checked" ';
               $createon{$item} = ' ';
           }
       }
       $$rowtotal += 2;
       my $datatable='<tr class="LC_odd_row">'.
                     '<td>'.&mt('Create pending official courses from XML files').'</td>'.
                     '<td class="LC_right_item"><span class="LC_nobreak"><label>'.
                     '<input type="radio" name="autocreate_xml"'.
                     $createon{'xml'}.' value="1" />'.&mt('Yes').'</label>&nbsp;'.
                     '<label><input type="radio" name="autocreate_xml"'.
                     $createoff{'xml'}.' value="0" />'.&mt('No').'</label></span>'.
                     '</td></tr><tr>'.
                     '<td>'.&mt('Create pending requests for official courses (if validated)').'</td>'.
                     '<td class="LC_right_item"><span class="LC_nobreak"><label>'.
                     '<input type="radio" name="autocreate_req"'.
                     $createon{'req'}.' value="1" />'.&mt('Yes').'</label>&nbsp;'.
                     '<label><input type="radio" name="autocreate_req"'.
                     $createoff{'req'}.' value="0" />'.&mt('No').'</label></span>';
       my ($numdc,$dctable) = &active_dc_picker($dom,$curr_dc);
       if ($numdc > 1) {
           $datatable .= '</td></tr><tr class="LC_odd_row"><td>'.
                         &mt('Course creation processed as: (choose Dom. Coord.)').
                         '</td><td class="LC_left_item">'.$dctable.'</td></tr>';
           $$rowtotal ++ ;
       } else {
           $datatable .= $dctable.'</td></tr>';
     }      }
     return $datatable;      return $datatable;
 }  }
   
 sub print_directorysrch {  sub print_directorysrch {
     my ($dom,$settings) = @_;      my ($dom,$settings,$rowtotal) = @_;
     my $srchon = ' ';      my $srchon = ' ';
     my $srchoff = ' checked="checked" ';      my $srchoff = ' checked="checked" ';
     my ($exacton,$containson,$beginson);      my ($exacton,$containson,$beginson);
Line 942  sub print_directorysrch { Line 1944  sub print_directorysrch {
         }          }
     }      }
     my ($searchtitles,$titleorder) = &sorted_searchtitles();      my ($searchtitles,$titleorder) = &sorted_searchtitles();
     my ($othertitle,$usertypes,$types) = &sorted_inst_types($dom);      my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom);
   
     my $numinrow = 4;      my $numinrow = 4;
     my $cansrchrow = 0;      my $cansrchrow = 0;
     my $datatable='<tr class="LC_odd_row">'.      my $datatable='<tr class="LC_odd_row">'.
                   '<td colspan="2">'.&mt('Directory search available?').'</td>'.                    '<td colspan="2"><span class ="LC_nobreak">'.&mt('Directory search available?').'</span></td>'.
                   '<td class="LC_right_item"><span class="LC_nobreak"><label>'.                    '<td class="LC_right_item"><span class="LC_nobreak"><label>'.
                   '<input type="radio" name="dirsrch_available"'.                    '<input type="radio" name="dirsrch_available"'.
                   $srchon.' value="1" />'.&mt('Yes').'</label>&nbsp;'.                    $srchon.' value="1" />'.&mt('Yes').'</label>&nbsp;'.
                   '<label><input type="radio" name="dirsrch_available"'.                    '<label><input type="radio" name="dirsrch_available"'.
                   $srchoff.' value="0" />'.&mt('No').'</label></span></td>'.                    $srchoff.' value="0" />'.&mt('No').'</label></span></td>'.
                   '</tr><tr>'.                    '</tr><tr>'.
                   '<td colspan="2">'.&mt('Other domains can search?').'</td>'.                    '<td colspan="2"><span class ="LC_nobreak">'.&mt('Other domains can search?').'</span></td>'.
                   '<td class="LC_right_item"><span class="LC_nobreak"><label>'.                    '<td class="LC_right_item"><span class="LC_nobreak"><label>'.
                   '<input type="radio" name="dirsrch_localonly"'.                    '<input type="radio" name="dirsrch_localonly"'.
                   $localoff.' value="0" />'.&mt('Yes').'</label>&nbsp;'.                    $localoff.' value="0" />'.&mt('Yes').'</label>&nbsp;'.
                   '<label><input type="radio" name="dirsrch_localonly"'.                    '<label><input type="radio" name="dirsrch_localonly"'.
                   $localon.' value="1" />'.&mt('No').'</label></span></td>'.                    $localon.' value="1" />'.&mt('No').'</label></span></td>'.
                   '</tr>';                    '</tr>';
       $$rowtotal += 2;
     if (ref($usertypes) eq 'HASH') {      if (ref($usertypes) eq 'HASH') {
         if (keys(%{$usertypes}) > 0) {          if (keys(%{$usertypes}) > 0) {
             $datatable .= &users_cansearch_row($settings,$types,$usertypes,$dom,              $datatable .= &insttypes_row($settings,$types,$usertypes,$dom,
                                                $numinrow,$othertitle);                                           $numinrow,$othertitle,'cansearch');
             $cansrchrow = 1;              $cansrchrow = 1;
         }          }
     }      }
     if ($cansrchrow) {      if ($cansrchrow) {
           $$rowtotal ++;
         $datatable .= '<tr>';          $datatable .= '<tr>';
     } else {      } else {
         $datatable .= '<tr class="LC_odd_row">';          $datatable .= '<tr class="LC_odd_row">';
     }      }
     $datatable .= '<td>'.&mt('Supported search methods').      $datatable .= '<td><span class ="LC_nobreak">'.&mt('Supported search methods').
                   '</td><td class="LC_left_item" colspan="2"><table><tr>';                    '</span></td><td class="LC_left_item" colspan="2"><table><tr>';
     foreach my $title (@{$titleorder}) {      foreach my $title (@{$titleorder}) {
         if (defined($searchtitles->{$title})) {          if (defined($searchtitles->{$title})) {
             my $check = ' ';              my $check = ' ';
             if (ref($settings->{'searchby'}) eq 'ARRAY') {              if (ref($settings) eq 'HASH') {
                 if (grep(/^\Q$title\E$/,@{$settings->{'searchby'}})) {                  if (ref($settings->{'searchby'}) eq 'ARRAY') {
                     $check = ' checked="checked" ';                      if (grep(/^\Q$title\E$/,@{$settings->{'searchby'}})) {
                           $check = ' checked="checked" ';
                       }
                 }                  }
             }              }
             $datatable .= '<td class="LC_left_item">'.              $datatable .= '<td class="LC_left_item">'.
Line 991  sub print_directorysrch { Line 1997  sub print_directorysrch {
         }          }
     }      }
     $datatable .= '</tr></table></td></tr>';      $datatable .= '</tr></table></td></tr>';
       $$rowtotal ++;
     if ($cansrchrow) {      if ($cansrchrow) {
         $datatable .= '<tr class="LC_odd_row">';          $datatable .= '<tr class="LC_odd_row">';
     } else {      } else {
         $datatable .= '<tr>';          $datatable .= '<tr>';
     }      }
     $datatable .= '<td>'.&mt('Search latitude').'</td>'.         $datatable .= '<td><span class ="LC_nobreak">'.&mt('Search latitude').'</span></td>'.   
                   '<td class="LC_left_item" colspan="2">'.                    '<td class="LC_left_item" colspan="2">'.
                   '<span class="LC_nobreak"><label>'.                    '<span class="LC_nobreak"><label>'.
                   '<input type="checkbox" name="searchtypes" '.                    '<input type="checkbox" name="searchtypes" '.
Line 1008  sub print_directorysrch { Line 2015  sub print_directorysrch {
                   '<label><input type="checkbox" name="searchtypes" '.                    '<label><input type="checkbox" name="searchtypes" '.
                   $containson.' value="contains" />'.&mt('Contains').                    $containson.' value="contains" />'.&mt('Contains').
                   '</label></span></td></tr>';                    '</label></span></td></tr>';
       $$rowtotal ++;
     return $datatable;      return $datatable;
 }  }
   
 sub print_usercreation {  sub print_contacts {
     my ($dom,$settings) = @_;      my ($dom,$settings,$rowtotal) = @_;
     my $numinrow = 4;      my $datatable;
     my ($rules,$ruleorder) = &Apache::lonnet::inst_userrules($dom);      my @contacts = ('adminemail','supportemail');
     my %checked;      my (%checked,%to,%otheremails,%bccemails);
       my @mailings = ('errormail','packagesmail','lonstatusmail','helpdeskmail',
                       'requestsmail');
       foreach my $type (@mailings) {
           $otheremails{$type} = '';
       }
       $bccemails{'helpdeskmail'} = '';
       if (ref($settings) eq 'HASH') {
           foreach my $item (@contacts) {
               if (exists($settings->{$item})) {
                   $to{$item} = $settings->{$item};
               }
           }
           foreach my $type (@mailings) {
               if (exists($settings->{$type})) {
                   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') {
                           $bccemails{$type} = $settings->{$type}{'bcc'};
                       }
                   }
               } elsif ($type eq 'lonstatusmail') {
                   $checked{'lonstatusmail'}{'adminemail'} = ' checked="checked" ';
               }
           }
       } else {
           $to{'supportemail'} = $Apache::lonnet::perlvar{'lonSupportEMail'};
           $to{'adminemail'} = $Apache::lonnet::perlvar{'lonAdmEMail'};
           $checked{'errormail'}{'adminemail'} = ' checked="checked" ';
           $checked{'packagesmail'}{'adminemail'} = ' checked="checked" ';
           $checked{'helpdeskmail'}{'supportemail'} = ' checked="checked" ';
           $checked{'lonstatusmail'}{'adminemail'} = ' checked="checked" '; 
           $checked{'requestsmail'}{'adminemail'} = ' checked="checked" ';
       }
       my ($titles,$short_titles) = &contact_titles();
       my $rownum = 0;
       my $css_class;
       foreach my $item (@contacts) {
           $rownum ++;
           $css_class = $rownum%2?' class="LC_odd_row"':'';
           $datatable .= '<tr'.$css_class.'>'. 
                     '<td><span class="LC_nobreak">'.$titles->{$item}.
                     '</span></td><td class="LC_right_item">'.
                     '<input type="text" name="'.$item.'" value="'.
                     $to{$item}.'" /></td></tr>';
       }
       foreach my $type (@mailings) {
           $rownum ++;
           $css_class = $rownum%2?' class="LC_odd_row"':'';
           $datatable .= '<tr'.$css_class.'>'.
                         '<td><span class="LC_nobreak">'.
                         $titles->{$type}.': </span></td>'.
                         '<td class="LC_left_item">'.
                         '<span class="LC_nobreak">';
           foreach my $item (@contacts) {
               $datatable .= '<label>'.
                             '<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}.'"  />';
           if ($type eq 'helpdeskmail') {
               $datatable .= '<br />'.&mt('Bcc:').('&nbsp;'x6).
                             '<input type="text" name="'.$type.'_bcc" '.
                             'value="'.$bccemails{$type}.'"  />';
           }
           $datatable .= '</td></tr>'."\n";
       }
       $$rowtotal += $rownum;
       return $datatable;
   }
   
   sub print_helpsettings {
   
    my ($position,$dom,$confname,$settings,$rowtotal) = @_;
    my ($css_class,$datatable);
   
    my $switchserver = &check_switchserver($dom,$confname);
   
    my $itemcount = 1;
   
    if ($position eq 'top') {
   
    my (%checkedon,%checkedoff,%choices,%defaultchecked,@toggles);
   
    %choices =
    &Apache::lonlocal::texthash (
    submitbugs => 'Display &quot;Submit a bug&quot; link?',
    );
   
    %defaultchecked = ('submitbugs' => 'on');
   
    @toggles = ('submitbugs',);
   
    foreach my $item (@toggles) {
    if ($defaultchecked{$item} eq 'on') { 
    $checkedon{$item} = ' checked="checked" ';
    $checkedoff{$item} = ' ';
    } elsif ($defaultchecked{$item} eq 'off') {
    $checkedoff{$item} = ' checked="checked" ';
    $checkedon{$item} = ' ';
    }
    }
   
    if (ref($settings) eq 'HASH') {
    foreach my $item (@toggles) {
    if ($settings->{$item} eq '1') {
    $checkedon{$item} =  ' checked="checked" ';
    $checkedoff{$item} = ' ';
    } elsif ($settings->{$item} eq '0') {
    $checkedoff{$item} =  ' checked="checked" ';
    $checkedon{$item} = ' ';
    }
    }
    }
   
    foreach my $item (@toggles) {
    $css_class = $itemcount%2 ? ' class="LC_odd_row"' : '';
    $datatable .=  
    '<tr'.$css_class.'>
    <td><span class="LC_nobreak">'.$choices{$item}.'</span></td>
    <td><span class="LC_nobreak">&nbsp;</span></td>
    <td class="LC_right_item"><span class="LC_nobreak">
    <label><input type="radio" name="'.$item.'" '.$checkedon{$item}.' value="1" />'.&mt('Yes').'</label>&nbsp;
    <label><input type="radio" name="'.$item.'" '.$checkedoff{$item}.' value="0" />'.&mt('No').'</label>'.
    '</span></td>'.
    '</tr>';
    $itemcount ++;
    }
        
        } else {
        
         $css_class = $itemcount%2 ? ' class="LC_odd_row"' : '';
        
         $datatable .= '<tr'.$css_class.'>';
        
         if (ref($settings) eq 'HASH') {
    if ($settings->{'loginhelpurl'} ne '') {
    my($directory, $filename) = $settings->{'loginhelpurl'} =~ m/(.*\/)(.*)$/;
    $datatable .= '<td width="33%"><span class="LC_left_item"><label><a href="'.$settings->{'loginhelpurl'}.'" target="_blank">'.&mt('Custom Login Page Help File In Use').'</a></label></span></td>';
    $datatable .= '<td width="33%"><span class="LC_right_item"><label><input type="checkbox" name="loginhelpurl_del" value="1" />'.&mt('Delete?').'</label></span></td>'
    } else {
    $datatable .= '<td width="33%"><span class="LC_left_item"><label>'.&mt('Default Login Page Help File In Use').'</label></span></td>';
    $datatable .= '<td width="33%"><span class="LC_right_item">&nbsp;</span></td>';
    }
    } else {
    $datatable .= '<td><span class="LC_left_item">&nbsp;</span></td>';
    $datatable .= '<td><span class="LC_right_item">&nbsp;</span></td>';
    }
      
         $datatable .= '<td width="33%"><span class="LC_right_item">';
         if ($switchserver) {
               $datatable .= &mt('Upload to library server: [_1]',$switchserver);
           } else {
           $datatable .= &mt('Upload Custom Login Page Help File:');
               $datatable .='<input type="file" name="loginhelpurl" />';
           }
           $datatable .= '</span></td></tr>';
           
        }
        
        return $datatable;
   
   }
   
   
   sub radiobutton_prefs {
       my ($settings,$toggles,$defaultchecked,$choices,$itemcount) = @_;
       return unless ((ref($toggles) eq 'ARRAY') && (ref($defaultchecked) eq 'HASH') &&
                      (ref($choices) eq 'HASH'));
   
       my (%checkedon,%checkedoff,$datatable,$css_class);
   
       foreach my $item (@{$toggles}) {
           if ($defaultchecked->{$item} eq 'on') {
               $checkedon{$item} = ' checked="checked" ';
               $checkedoff{$item} = ' ';
           } elsif ($defaultchecked->{$item} eq 'off') {
               $checkedoff{$item} = ' checked="checked" ';
               $checkedon{$item} = ' ';
           }
       }
     if (ref($settings) eq 'HASH') {      if (ref($settings) eq 'HASH') {
         if (ref($settings->{'cancreate'}) eq 'ARRAY') {          foreach my $item (@{$toggles}) {
             foreach my $item (@{$settings->{'cancreate'}}) {               if ($settings->{$item} eq '1') {
                 $checked{$item} = ' checked="checked" ';                  $checkedon{$item} =  ' checked="checked" ';
                   $checkedoff{$item} = ' ';
               } elsif ($settings->{$item} eq '0') {
                   $checkedoff{$item} =  ' checked="checked" ';
                   $checkedon{$item} = ' ';
             }              }
         }          }
     }      }
     my $datatable = '<td>'.&mt('User creation other than by DC: ').'</td>'.      foreach my $item (@{$toggles}) {
                     '<td class="LC_left_item"><table><tr><td>'.          $css_class = $itemcount%2?' class="LC_odd_row"':'';
                     '<span class="LC_nobreak"><label>'.          $datatable .=
                     '<input type="checkbox" name="can_createuser" '.              '<tr'.$css_class.'><td><span class="LC_nobreak">'.$choices->{$item}.
                     $checked{'author'}.' value="author" />'.              '</span></td>'.
                     &mt('When adding a co-author/assistant author').              '<td class="LC_right_item"><span class="LC_nobreak">'.
             '</label><span></td></tr>'.              '<label><input type="radio" name="'.
                     '<tr><td>'.              $item.'" '.$checkedon{$item}.' value="1" />'.&mt('Yes').
                     '<span class="LC_nobreak"><label>'.              '</label>&nbsp;<label><input type="radio" name="'.$item.'" '.
                     '<input type="checkbox" name="can_createuser" '.              $checkedoff{$item}.' value="0" />'.&mt('No').'</label>'.
                     $checked{'course'}.' value="course" />'.              '</span></td>'.
                     &mt('When adding users to a course').              '</tr>';
                     '</label><span></td></tr></table></td></tr>';          $itemcount ++;
     if (ref($rules) eq 'HASH') {      }
         if (keys(%{$rules}) > 0) {      return ($datatable,$itemcount);
             $datatable .= &username_formats_row($settings,$rules,$ruleorder,  }
                                                 $numinrow);  
   sub print_coursedefaults {
       my ($position,$dom,$settings,$rowtotal) = @_;
       my ($css_class,$datatable);
       my $itemcount = 1;
       if ($position eq 'top') {
           my (%checkedon,%checkedoff,%choices,%defaultchecked,@toggles);
           %choices =
               &Apache::lonlocal::texthash (
                   canuse_pdfforms => 'Course/Community users can create/upload PDF forms',
           );
           %defaultchecked = ('canuse_pdfforms' => 'off');
           @toggles = ('canuse_pdfforms',);
           ($datatable,$itemcount) = &radiobutton_prefs($settings,\@toggles,\%defaultchecked,
                                                    \%choices,$itemcount);
           $$rowtotal += $itemcount;
       } else {
           $css_class = $itemcount%2 ? ' class="LC_odd_row"' : '';
           my %choices =
               &Apache::lonlocal::texthash (
                   anonsurvey_threshold => 'Responder count needed before showing submissions for anonymous surveys',
           );
           my $currdefresponder;
           if (ref($settings) eq 'HASH') {
               $currdefresponder = $settings->{'anonsurvey_threshold'};
         }          }
           if (!$currdefresponder) {
               $currdefresponder = 10;
           } elsif ($currdefresponder < 1) {
               $currdefresponder = 1;
           }
           $datatable .=
                  '<tr'.$css_class.'><td><span class="LC_nobreak">'.$choices{'anonsurvey_threshold'}.
                   '</span></td>'.
                   '<td class="LC_right_item"><span class="LC_nobreak">'.
                   '<input type="text" name="anonsurvey_threshold"'.
                   ' value="'.$currdefresponder.'" size="5" /></span>'.
                   '</td></tr>';
     }      }
     return $datatable;      return $datatable;
 }  }
   
 sub username_formats_row {  sub print_usersessions {
     my ($settings,$rules,$ruleorder,$numinrow) = @_;      my ($position,$dom,$settings,$rowtotal) = @_;
     my $output =  '<tr class="LC_odd_row">'.      my ($css_class,$datatable,%checked,%choices);
                   '<td>'.&mt('Format rules to check for new usernames').      my (%by_ip,%by_location,@intdoms);
                   '</td><td class="LC_left_item" colspan="2"><table>';      &build_location_hashes(\@intdoms,\%by_ip,\%by_location);
       if (keys(%by_location) == 0) {
           if ($position eq 'top') {
               $datatable .= '<tr'.$css_class.'><td colspan="2">'.
                             &mt('Nothing to set here, as the cluster to which this domain belongs only contains this institution.');
           }
       }
       my %lt = &usersession_titles();
       my $itemcount = 1;
       my $numinrow = 5;
       my $prefix;
       my @types;
       if ($position eq 'top') {
           $prefix = 'hosted';
           @types = ('excludedomain','includedomain');
       } else {
           $prefix = 'remote';
           @types = ('version','excludedomain','includedomain');
       }
       my (%current,%checkedon,%checkedoff);
       my @lcversions = &Apache::lonnet::all_loncaparevs();
       my @locations = sort(keys(%by_location));
       foreach my $type (@types) {
           $checkedon{$type} = '';
           $checkedoff{$type} = ' checked="checked"';
       }
       if (ref($settings) eq 'HASH') {
           if (ref($settings->{$prefix}) eq 'HASH') {
               foreach my $key (keys(%{$settings->{$prefix}})) {
                   $current{$key} = $settings->{$prefix}{$key};
                   if ($key eq 'version') {
                       if ($current{$key} ne '') {
                           $checkedon{$key} = ' checked="checked"';
                           $checkedoff{$key} = '';
                       }
                   } elsif (ref($current{$key}) eq 'ARRAY') {
                       $checkedon{$key} = ' checked="checked"';
                       $checkedoff{$key} = '';
                   }
               }
           }
       }
       foreach my $type (@types) {
           next if ($type ne 'version' && !@locations);
           $css_class = $itemcount%2 ? ' class="LC_odd_row"' : '';
           $datatable .= '<tr'.$css_class.'>
                          <td><span class="LC_nobreak">'.$lt{$type}.'</span><br />
                              <span class="LC_nobreak">&nbsp;
                              <label><input type="radio" name="'.$prefix.'_'.$type.'_inuse" '.$checkedoff{$type}.' value="0" />'.&mt('Not in use').'</label>&nbsp;
                              <label><input type="radio" name="'.$prefix.'_'.$type.'_inuse" '.$checkedon{$type}.' value="1" />'.&mt('In use').'</label></span></td><td>';
           if ($type eq 'version') {
               my $selector = '<select name="'.$prefix.'_version">';
               foreach my $version (@lcversions) {
                   my $selected = '';
                   if ($current{'version'} eq $version) {
                       $selected = ' selected="selected"';
                   }
                   $selector .= ' <option value="'.$version.'"'.
                                $selected.'>'.$version.'</option>';
               }
               $selector .= '</select> ';
               $datatable .= &mt('remote server must be version: [_1] or later',$selector);
           } else {
               $datatable.= '<div><input type="button" value="'.&mt('check all').'" '.
                            'onclick="javascript:checkAll(document.display.'.$prefix.'_'.$type.')"'.
                            ' />'.('&nbsp;'x2).
                            '<input type="button" value="'.&mt('uncheck all').'" '.
                            'onclick="javascript:uncheckAll(document.display.'.$prefix.'_'.$type.')" />'.
                            "\n".
                            '</div><div><table>';
               my $rem;
               for (my $i=0; $i<@locations; $i++) {
                   my ($showloc,$value,$checkedtype);
                   if (ref($by_location{$locations[$i]}) eq 'ARRAY') {
                       my $ip = $by_location{$locations[$i]}->[0];
                       if (ref($by_ip{$ip}) eq 'ARRAY') {
                           $value = join(':',@{$by_ip{$ip}});
                           $showloc = join(', ',@{$by_ip{$ip}});
                           if (ref($current{$type}) eq 'ARRAY') {
                               foreach my $loc (@{$by_ip{$ip}}) {  
                                   if (grep(/^\Q$loc\E$/,@{$current{$type}})) {
                                       $checkedtype = ' checked="checked"';
                                       last;
                                   }
                               }
                           }
                       }
                   }
                   $rem = $i%($numinrow);
                   if ($rem == 0) {
                       if ($i > 0) {
                           $datatable .= '</tr>';
                       }
                       $datatable .= '<tr>';
                   }
                   $datatable .= '<td class="LC_left_item">'.
                                 '<span class="LC_nobreak"><label>'.
                                 '<input type="checkbox" name="'.$prefix.'_'.$type.
                                 '" value="'.$value.'"'.$checkedtype.' />'.$showloc.
                                 '</label></span></td>';
               }
               $rem = @locations%($numinrow);
               my $colsleft = $numinrow - $rem;
               if ($colsleft > 1 ) {
                   $datatable .= '<td colspan="'.$colsleft.'" class="LC_left_item">'.
                                 '&nbsp;</td>';
               } elsif ($colsleft == 1) {
                   $datatable .= '<td class="LC_left_item">&nbsp;</td>';
               }
               $datatable .= '</tr></table>';
           }
           $datatable .= '</td></tr>';
           $itemcount ++;
       }
       $$rowtotal += $itemcount;
       return $datatable;
   }
   
   sub build_location_hashes {
       my ($intdoms,$by_ip,$by_location) = @_;
       return unless((ref($intdoms) eq 'ARRAY') && (ref($by_ip) eq 'HASH') &&
                     (ref($by_location) eq 'HASH')); 
       my %iphost = &Apache::lonnet::get_iphost();
       my $primary_id = &Apache::lonnet::domain($env{'request.role.domain'},'primary');
       my $primary_ip = &Apache::lonnet::get_host_ip($primary_id);
       if (ref($iphost{$primary_ip}) eq 'ARRAY') {
           foreach my $id (@{$iphost{$primary_ip}}) {
               my $intdom = &Apache::lonnet::internet_dom($id);
               unless(grep(/^\Q$intdom\E$/,@{$intdoms})) {
                   push(@{$intdoms},$intdom);
               }
           }
       }
       foreach my $ip (keys(%iphost)) {
           if (ref($iphost{$ip}) eq 'ARRAY') {
               foreach my $id (@{$iphost{$ip}}) {
                   my $location = &Apache::lonnet::internet_dom($id);
                   if ($location) {
                       next if (grep(/^\Q$location\E$/,@{$intdoms}));
                       if (ref($by_ip->{$ip}) eq 'ARRAY') {
                           unless(grep(/^\Q$location\E$/,@{$by_ip->{$ip}})) {
                               push(@{$by_ip->{$ip}},$location);
                           }
                       } else {
                           $by_ip->{$ip} = [$location];
                       }
                   }
               }
           }
       }
       foreach my $ip (sort(keys(%{$by_ip}))) {
           if (ref($by_ip->{$ip}) eq 'ARRAY') {
               @{$by_ip->{$ip}} = sort(@{$by_ip->{$ip}});
               my $first = $by_ip->{$ip}->[0];
               if (ref($by_location->{$first}) eq 'ARRAY') {
                   unless (grep(/^\Q$ip\E$/,@{$by_location->{$first}})) {
                       push(@{$by_location->{$first}},$ip);
                   }
               } else {
                   $by_location->{$first} = [$ip];
               }
           }
       }
       return;
   }
   
   sub contact_titles {
       my %titles = &Apache::lonlocal::texthash (
                      'supportemail' => 'Support E-mail address',
                      'adminemail'   => 'Default Server Admin E-mail address',
                      'errormail'    => 'Error reports to be e-mailed to',
                      'packagesmail' => 'Package update alerts to be e-mailed to',
                      'helpdeskmail' => 'Helpdesk requests to be e-mailed to',
                      'lonstatusmail' => 'E-mail from nightly status check (warnings/errors)',
                      'requestsmail' => 'E-mail from course requests requiring approval',
                    );
       my %short_titles = &Apache::lonlocal::texthash (
                              adminemail   => 'Admin E-mail address',
                              supportemail => 'Support E-mail',
                          );   
       return (\%titles,\%short_titles);
   }
   
   sub tool_titles {
       my %titles = &Apache::lonlocal::texthash (
                        aboutme    => 'Personal Information Page',
                        blog       => 'Blog',
                        portfolio  => 'Portfolio',
                        official   => 'Official courses (with institutional codes)',
                        unofficial => 'Unofficial courses',
                        community  => 'Communities',
                    );
       return %titles;
   }
   
   sub courserequest_titles {
       my %titles = &Apache::lonlocal::texthash (
                                      official   => 'Official',
                                      unofficial => 'Unofficial',
                                      community  => 'Communities',
                                      norequest  => 'Not allowed',
                                      approval   => 'Approval by Dom. Coord.',
                                      validate   => 'With validation',
                                      autolimit  => 'Numerical limit',
                                      unlimited  => '(blank for unlimited)',
                    );
       return %titles;
   }
   
   sub courserequest_conditions {
       my %conditions = &Apache::lonlocal::texthash (
          approval    => '(Processing of request subject to approval by Domain Coordinator).',
          validate   => '(Processing of request subject to instittutional validation).',
                    );
       return %conditions;
   }
   
   
   sub print_usercreation {
       my ($position,$dom,$settings,$rowtotal) = @_;
       my $numinrow = 4;
       my $datatable;
       if ($position eq 'top') {
           $$rowtotal ++;
           my $rowcount = 0;
           my ($rules,$ruleorder) = &Apache::lonnet::inst_userrules($dom,'username');
           if (ref($rules) eq 'HASH') {
               if (keys(%{$rules}) > 0) {
                   $datatable .= &user_formats_row('username',$settings,$rules,
                                                   $ruleorder,$numinrow,$rowcount);
                   $$rowtotal ++;
                   $rowcount ++;
               }
           }
           my ($idrules,$idruleorder) = &Apache::lonnet::inst_userrules($dom,'id');
           if (ref($idrules) eq 'HASH') {
               if (keys(%{$idrules}) > 0) {
                   $datatable .= &user_formats_row('id',$settings,$idrules,
                                                   $idruleorder,$numinrow,$rowcount);
                   $$rowtotal ++;
                   $rowcount ++;
               }
           }
           my ($emailrules,$emailruleorder) = 
               &Apache::lonnet::inst_userrules($dom,'email');
           if (ref($emailrules) eq 'HASH') {
               if (keys(%{$emailrules}) > 0) {
                   $datatable .= &user_formats_row('email',$settings,$emailrules,
                                                   $emailruleorder,$numinrow,$rowcount);
                   $$rowtotal ++;
                   $rowcount ++;
               }
           }
           if ($rowcount == 0) {
               $datatable .= '<tr><td colspan="2">'.&mt('No format rules have been defined for usernames or IDs in this domain.').'</td></tr>';  
               $$rowtotal ++;
               $rowcount ++;
           }
       } elsif ($position eq 'middle') {
           my @creators = ('author','course','requestcrs','selfcreate');
           my ($rules,$ruleorder) =
               &Apache::lonnet::inst_userrules($dom,'username');
           my %lt = &usercreation_types();
           my %checked;
           my @selfcreate; 
           if (ref($settings) eq 'HASH') {
               if (ref($settings->{'cancreate'}) eq 'HASH') {
                   foreach my $item (@creators) {
                       $checked{$item} = $settings->{'cancreate'}{$item};
                   }
                   if (ref($settings->{'cancreate'}{'selfcreate'}) eq 'ARRAY') {
                       @selfcreate = @{$settings->{'cancreate'}{'selfcreate'}};
                   } elsif ($settings->{'cancreate'}{'selfcreate'} ne '') {
                       if ($settings->{'cancreate'}{'selfcreate'} eq 'any') {
                           @selfcreate = ('email','login','sso');
                       } elsif ($settings->{'cancreate'}{'selfcreate'} ne 'none') {
                           @selfcreate = ($settings->{'cancreate'}{'selfcreate'});
                       }
                   }
               } elsif (ref($settings->{'cancreate'}) eq 'ARRAY') {
                   foreach my $item (@creators) {
                       if (grep(/^\Q$item\E$/,@{$settings->{'cancreate'}})) {
                           $checked{$item} = 'none';
                       }
                   }
               }
           }
           my $rownum = 0;
           foreach my $item (@creators) {
               $rownum ++;
               if ($item ne 'selfcreate') {  
                   if ($checked{$item} eq '') {
                       $checked{$item} = 'any';
                   }
               }
               my $css_class;
               if ($rownum%2) {
                   $css_class = '';
               } else {
                   $css_class = ' class="LC_odd_row" ';
               }
               $datatable .= '<tr'.$css_class.'>'.
                            '<td><span class="LC_nobreak">'.$lt{$item}.
                            '</span></td><td align="right">';
               my @options;
               if ($item eq 'selfcreate') {
                   push(@options,('email','login','sso'));
               } else {
                   @options = ('any');
                   if (ref($rules) eq 'HASH') {
                       if (keys(%{$rules}) > 0) {
                           push(@options,('official','unofficial'));
                       }
                   }
                   push(@options,'none');
               }
               foreach my $option (@options) {
                   my $type = 'radio';
                   my $check = ' ';
                   if ($item eq 'selfcreate') {
                       $type = 'checkbox';
                       if (grep(/^\Q$option\E$/,@selfcreate)) {
                           $check = ' checked="checked" ';
                       }
                   } else {
                       if ($checked{$item} eq $option) {
                           $check = ' checked="checked" ';
                       }
                   } 
                   $datatable .= '<span class="LC_nobreak"><label>'.
                                 '<input type="'.$type.'" name="can_createuser_'.
                                 $item.'" value="'.$option.'"'.$check.'/>&nbsp;'.
                                 $lt{$option}.'</label>&nbsp;&nbsp;</span>';
               }
               $datatable .= '</td></tr>';
           }
           my ($othertitle,$usertypes,$types) =
               &Apache::loncommon::sorted_inst_types($dom);
           if (ref($usertypes) eq 'HASH') {
               if (keys(%{$usertypes}) > 0) {
                   my $createsettings;
                   if (ref($settings) eq 'HASH') {
                       $createsettings = $settings->{cancreate};
                   }
                   $datatable .= &insttypes_row($createsettings,$types,$usertypes,
                                                $dom,$numinrow,$othertitle,
                                                'statustocreate');
                   $$rowtotal ++;
               }
           }
       } else {
           my @contexts = ('author','course','domain');
           my @authtypes = ('int','krb4','krb5','loc');
           my %checked;
           if (ref($settings) eq 'HASH') {
               if (ref($settings->{'authtypes'}) eq 'HASH') {
                   foreach my $item (@contexts) {
                       if (ref($settings->{'authtypes'}{$item}) eq 'HASH') {
                           foreach my $auth (@authtypes) {
                               if ($settings->{'authtypes'}{$item}{$auth}) {
                                   $checked{$item}{$auth} = ' checked="checked" ';
                               }
                           }
                       }
                   }
               }
           } else {
               foreach my $item (@contexts) {
                   foreach my $auth (@authtypes) {
                       $checked{$item}{$auth} = ' checked="checked" ';
                   }
               }
           }
           my %title = &context_names();
           my %authname = &authtype_names();
           my $rownum = 0;
           my $css_class; 
           foreach my $item (@contexts) {
               if ($rownum%2) {
                   $css_class = '';
               } else {
                   $css_class = ' class="LC_odd_row" ';
               }
               $datatable .=   '<tr'.$css_class.'>'.
                               '<td>'.$title{$item}.
                               '</td><td class="LC_left_item">'.
                               '<span class="LC_nobreak">';
               foreach my $auth (@authtypes) {
                   $datatable .= '<label>'. 
                                 '<input type="checkbox" name="'.$item.'_auth" '.
                                 $checked{$item}{$auth}.' value="'.$auth.'" />'.
                                 $authname{$auth}.'</label>&nbsp;';
               }
               $datatable .= '</span></td></tr>';
               $rownum ++;
           }
           $$rowtotal += $rownum;
       }
       return $datatable;
   }
   
   sub user_formats_row {
       my ($type,$settings,$rules,$ruleorder,$numinrow,$rowcount) = @_;
       my $output;
       my %text = (
                      'username' => 'new usernames',
                      'id'       => 'IDs',
                      'email'    => 'self-created accounts (e-mail)',
                  );
       my $css_class = $rowcount%2?' class="LC_odd_row"':'';
       $output = '<tr '.$css_class.'>'.
                 '<td><span class="LC_nobreak">';
       if ($type eq 'email') {
           $output .= &mt("Formats disallowed for $text{$type}: ");
       } 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 1062  sub username_formats_row { Line 2717  sub username_formats_row {
                     $output .= '<tr>';                      $output .= '<tr>';
                 }                  }
                 my $check = ' ';                  my $check = ' ';
                 if (ref($settings->{'username_rule'}) eq 'ARRAY') {                  if (ref($settings) eq 'HASH') {
                     if (grep(/^\Q$ruleorder->[$i]\E$/,@{$settings->{'username_rule'}})) {                      if (ref($settings->{$type.'_rule'}) eq 'ARRAY') {
                         $check = ' checked="checked" ';                          if (grep(/^\Q$ruleorder->[$i]\E$/,@{$settings->{$type.'_rule'}})) {
                               $check = ' checked="checked" ';
                           }
                     }                      }
                 }                  }
                 $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="username_rule" '.                             '<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>';
             }              }
Line 1087  sub username_formats_row { Line 2744  sub username_formats_row {
     return $output;      return $output;
 }  }
   
 sub users_cansearch_row {  sub usercreation_types {
     my ($settings,$types,$usertypes,$dom,$numinrow,$othertitle) = @_;      my %lt = &Apache::lonlocal::texthash (
                       author     => 'When adding a co-author',
                       course     => 'When adding a user to a course',
                       requestcrs => 'When requesting a course',
                       selfcreate => 'User creates own account', 
                       any        => 'Any',
                       official   => 'Institutional only ',
                       unofficial => 'Non-institutional only',
                       email      => 'E-mail address',
                       login      => 'Institutional Login',
                       sso        => 'SSO', 
                       none       => 'None',
       );
       return %lt;
   }
   
   sub authtype_names {
       my %lt = &Apache::lonlocal::texthash(
                         int    => 'Internal',
                         krb4   => 'Kerberos 4',
                         krb5   => 'Kerberos 5',
                         loc    => 'Local',
                     );
       return %lt;
   }
   
   sub context_names {
       my %context_title = &Apache::lonlocal::texthash(
          author => 'Creating users when an Author',
          course => 'Creating users when in a course',
          domain => 'Creating users when a Domain Coordinator',
       );
       return %context_title;
   }
   
   sub print_usermodification {
       my ($position,$dom,$settings,$rowtotal) = @_;
       my $numinrow = 4;
       my ($context,$datatable,$rowcount);
       if ($position eq 'top') {
           $rowcount = 0;
           $context = 'author'; 
           foreach my $role ('ca','aa') {
               $datatable .= &modifiable_userdata_row($context,$role,$settings,
                                                      $numinrow,$rowcount);
               $$rowtotal ++;
               $rowcount ++;
           }
       } elsif ($position eq 'middle') {
           $context = 'course';
           $rowcount = 0;
           foreach my $role ('st','ep','ta','in','cr') {
               $datatable .= &modifiable_userdata_row($context,$role,$settings,
                                                      $numinrow,$rowcount);
               $$rowtotal ++;
               $rowcount ++;
           }
       } elsif ($position eq 'bottom') {
           $context = 'selfcreate';
           my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom);
           $usertypes->{'default'} = $othertitle;
           if (ref($types) eq 'ARRAY') {
               push(@{$types},'default');
               $usertypes->{'default'} = $othertitle;
               foreach my $status (@{$types}) {
                   $datatable .= &modifiable_userdata_row($context,$status,$settings,
                                                          $numinrow,$rowcount,$usertypes);
                   $$rowtotal ++;
                   $rowcount ++;
               }
           }
       }
       return $datatable;
   }
   
   sub print_defaults {
       my ($dom,$rowtotal) = @_;
       my @items = ('auth_def','auth_arg_def','lang_def','timezone_def',
                    'datelocale_def','portal_def');
       my %domdefaults = &Apache::lonnet::get_domain_defaults($dom);
       my $titles = &defaults_titles($dom);
       my $rownum = 0;
       my ($datatable,$css_class);
       foreach my $item (@items) {
           if ($rownum%2) {
               $css_class = '';
           } else {
               $css_class = ' class="LC_odd_row" ';
           }
           $datatable .= '<tr'.$css_class.'>'.
                     '<td><span class="LC_nobreak">'.$titles->{$item}.
                     '</span></td><td class="LC_right_item">';
           if ($item eq 'auth_def') {
               my @authtypes = ('internal','krb4','krb5','localauth');
               my %shortauth = (
                                internal => 'int',
                                krb4 => 'krb4',
                                krb5 => 'krb5',
                                localauth  => 'loc'
                              );
               my %authnames = &authtype_names();
               foreach my $auth (@authtypes) {
                   my $checked = ' ';
                   if ($domdefaults{$item} eq $auth) {
                       $checked = ' checked="checked" ';
                   }
                   $datatable .= '<label><input type="radio" name="'.$item.
                                 '" value="'.$auth.'"'.$checked.'/>'.
                                 $authnames{$shortauth{$auth}}.'</label>&nbsp;&nbsp;';
               }
           } elsif ($item eq 'timezone_def') {
               my $includeempty = 1;
               $datatable .= &Apache::loncommon::select_timezone($item,$domdefaults{$item},undef,$includeempty);
           } elsif ($item eq 'datelocale_def') {
               my $includeempty = 1;
               $datatable .= &Apache::loncommon::select_datelocale($item,$domdefaults{$item},undef,$includeempty);
           } else {
               my $size;
               if ($item eq 'portal_def') {
                   $size = ' size="25"';
               }
               $datatable .= '<input type="text" name="'.$item.'" value="'.
                             $domdefaults{$item}.'"'.$size.' />';
           }
           $datatable .= '</td></tr>';
           $rownum ++;
       }
       $$rowtotal += $rownum;
       return $datatable;
   }
   
   sub defaults_titles {
       my ($dom) = @_;
       my %titles = &Apache::lonlocal::texthash (
                      'auth_def'      => 'Default authentication type',
                      'auth_arg_def'  => 'Default authentication argument',
                      'lang_def'      => 'Default language',
                      'timezone_def'  => 'Default timezone',
                      'datelocale_def' => 'Default locale for dates',
                      'portal_def'     => 'Portal/Default URL',
                    );
       if ($dom) {
           my $uprimary_id = &Apache::lonnet::domain($dom,'primary');
           my $uint_dom = &Apache::lonnet::internet_dom($uprimary_id);
           my $protocol = $Apache::lonnet::protocol{$uprimary_id};
           $protocol = 'http' if ($protocol ne 'https');
           if ($uint_dom) {
               $titles{'portal_def'} .= ' '.&mt('(for example: [_1])',$protocol.'://loncapa.'.
                                            $uint_dom);
           }
       }
       return (\%titles);
   }
   
   sub print_scantronformat {
       my ($r,$dom,$confname,$settings,$rowtotal) = @_;
       my $itemcount = 1;
       my ($datatable,$css_class,$scantronurl,$is_custom,%error,%scantronurls,
           %confhash);
       my $switchserver = &check_switchserver($dom,$confname);
       my %lt = &Apache::lonlocal::texthash (
                   default => 'Default bubblesheet format file error',
                   custom  => 'Custom bubblesheet format file error',
                );
       my %scantronfiles = (
           default => 'default.tab',
           custom => 'custom.tab',
       );
       foreach my $key (keys(%scantronfiles)) {
           $scantronurls{$key} = '/res/'.$dom.'/'.$confname.'/scantron/'
                                 .$scantronfiles{$key};
       }
       my @defaultinfo = &Apache::lonnet::stat_file($scantronurls{'default'});
       if ((!@defaultinfo) || ($defaultinfo[0] eq 'no_such_dir')) {
           if (!$switchserver) {
               my $servadm = $r->dir_config('lonAdmEMail');
               my ($configuserok,$author_ok) = &config_check($dom,$confname,$servadm);
               if ($configuserok eq 'ok') {
                   if ($author_ok eq 'ok') {
                       my %legacyfile = (
    default => $Apache::lonnet::perlvar{'lonTabDir'}.'/default_scantronformat.tab', 
    custom  => $Apache::lonnet::perlvar{'lonTabDir'}.'/scantronformat.tab', 
                       );
                       my %md5chk;
                       foreach my $type (keys(%legacyfile)) {
                           ($md5chk{$type}) = split(/ /,`md5sum $legacyfile{$type}`);
                           chomp($md5chk{$type});
                       }
                       if ($md5chk{'default'} ne $md5chk{'custom'}) {
                           foreach my $type (keys(%legacyfile)) {
                               ($scantronurls{$type},my $error) = 
                                   &legacy_scantronformat($r,$dom,$confname,
                                                    $type,$legacyfile{$type},
                                                    $scantronurls{$type},
                                                    $scantronfiles{$type});
                               if ($error ne '') {
                                   $error{$type} = $error;
                               }
                           }
                           if (keys(%error) == 0) {
                               $is_custom = 1;
                               $confhash{'scantron'}{'scantronformat'} = 
                                   $scantronurls{'custom'};
                               my $putresult = 
                                   &Apache::lonnet::put_dom('configuration',
                                                            \%confhash,$dom);
                               if ($putresult ne 'ok') {
                                   $error{'custom'} = 
                                       '<span class="LC_error">'.
                                       &mt('An error occurred updating the domain configuration: [_1]',$putresult).'</span>';
                               }
                           }
                       } else {
                           ($scantronurls{'default'},my $error) =
                               &legacy_scantronformat($r,$dom,$confname,
                                             'default',$legacyfile{'default'},
                                             $scantronurls{'default'},
                                             $scantronfiles{'default'});
                           if ($error eq '') {
                               $confhash{'scantron'}{'scantronformat'} = ''; 
                               my $putresult =
                                   &Apache::lonnet::put_dom('configuration',
                                                            \%confhash,$dom);
                               if ($putresult ne 'ok') {
                                   $error{'default'} =
                                       '<span class="LC_error">'.
                                       &mt('An error occurred updating the domain configuration: [_1]',$putresult).'</span>';
                               }
                           } else {
                               $error{'default'} = $error;
                           }
                       }
                   }
               }
           } else {
               $error{'default'} = &mt("Unable to copy default bubblesheet formatfile to domain's RES space: [_1]",$switchserver);
           }
       }
       if (ref($settings) eq 'HASH') {
           if ($settings->{'scantronformat'} eq "/res/$dom/$confname/scantron/custom.tab") {
               my @info = &Apache::lonnet::stat_file($settings->{'scantronformat'});
               if ((!@info) || ($info[0] eq 'no_such_dir')) {
                   $scantronurl = '';
               } else {
                   $scantronurl = $settings->{'scantronformat'};
               }
               $is_custom = 1;
           } else {
               $scantronurl = $scantronurls{'default'};
           }
       } else {
           if ($is_custom) {
               $scantronurl = $scantronurls{'custom'};
           } else {
               $scantronurl = $scantronurls{'default'};
           }
       }
       $css_class = $itemcount%2?' class="LC_odd_row"':'';
       $datatable .= '<tr'.$css_class.'>';
       if (!$is_custom) {
           $datatable .= '<td>'.&mt('Default in use:').'<br />'.
                         '<span class="LC_nobreak">';
           if ($scantronurl) {
               $datatable .= '<a href="'.$scantronurl.'" target="_blank">'.
                             &mt('Default bubblesheet format file').'</a>';
           } else {
               $datatable = &mt('File unavailable for display');
           }
           $datatable .= '</span></td>';
           if (keys(%error) == 0) { 
               $datatable .= '<td valign="bottom">';
               if (!$switchserver) {
                   $datatable .= &mt('Upload:').'<br />';
               }
           } else {
               my $errorstr;
               foreach my $key (sort(keys(%error))) {
                   $errorstr .= $lt{$key}.': '.$error{$key}.'<br />';
               }
               $datatable .= '<td>'.$errorstr;
           }
       } else {
           if (keys(%error) > 0) {
               my $errorstr;
               foreach my $key (sort(keys(%error))) {
                   $errorstr .= $lt{$key}.': '.$error{$key}.'<br />';
               } 
               $datatable .= '<td>'.$errorstr.'</td><td>&nbsp;';
           } elsif ($scantronurl) {
               $datatable .= '<td><span class="LC_nobreak">'.
                             '<a href="'.$scantronurl.'" target="_blank">'.
                             &mt('Custom bubblesheet format file').'</a><label>'.
                             '<input type="checkbox" name="scantronformat_del"'.
                             '" value="1" />'.&mt('Delete?').'</label></span></td>'.
                             '<td><span class="LC_nobreak">&nbsp;'.
                             &mt('Replace:').'</span><br />';
           }
       }
       if (keys(%error) == 0) {
           if ($switchserver) {
               $datatable .= &mt('Upload to library server: [_1]',$switchserver);
           } else {
               $datatable .='<span class="LC_nobreak">&nbsp;'.
                            '<input type="file" name="scantronformat" /></span>';
           }
       }
       $datatable .= '</td></tr>';
       $$rowtotal ++;
       return $datatable;
   }
   
   sub legacy_scantronformat {
       my ($r,$dom,$confname,$file,$legacyfile,$newurl,$newfile) = @_;
       my ($url,$error);
       my @statinfo = &Apache::lonnet::stat_file($newurl);
       if ((!@statinfo) || ($statinfo[0] eq 'no_such_dir')) {
           (my $result,$url) =
               &publishlogo($r,'copy',$legacyfile,$dom,$confname,'scantron',
                            '','',$newfile);
           if ($result ne 'ok') {
               $error = &mt("An error occurred publishing the [_1] bubblesheet format file in RES space. Error was: [_2].",$newfile,$result);
           }
       }
       return ($url,$error);
   }
   
   sub print_coursecategories {
       my ($position,$dom,$hdritem,$settings,$rowtotal) = @_;
       my $datatable;
       if ($position eq 'top') {
           my $toggle_cats_crs = ' ';
           my $toggle_cats_dom = ' checked="checked" ';
           my $can_cat_crs = ' ';
           my $can_cat_dom = ' checked="checked" ';
           my $toggle_catscomm_comm = ' ';
           my $toggle_catscomm_dom = ' checked="checked" ';
           my $can_catcomm_comm = ' ';
           my $can_catcomm_dom = ' checked="checked" ';
   
           if (ref($settings) eq 'HASH') {
               if ($settings->{'togglecats'} eq 'crs') {
                   $toggle_cats_crs = $toggle_cats_dom;
                   $toggle_cats_dom = ' ';
               }
               if ($settings->{'categorize'} eq 'crs') {
                   $can_cat_crs = $can_cat_dom;
                   $can_cat_dom = ' ';
               }
               if ($settings->{'togglecatscomm'} eq 'comm') {
                   $toggle_catscomm_comm = $toggle_catscomm_dom;
                   $toggle_catscomm_dom = ' ';
               }
               if ($settings->{'categorizecomm'} eq 'comm') {
                   $can_catcomm_comm = $can_catcomm_dom;
                   $can_catcomm_dom = ' ';
               }
           }
           my %title = &Apache::lonlocal::texthash (
                        togglecats     => 'Show/Hide a course in catalog',
                        togglecatscomm => 'Show/Hide a community in catalog',
                        categorize     => 'Assign a category to a course',
                        categorizecomm => 'Assign a category to a community',
                       );
           my %level = &Apache::lonlocal::texthash (
                        dom  => 'Set in Domain',
                        crs  => 'Set in Course',
                        comm => 'Set in Community',
                       );
           $datatable = '<tr class="LC_odd_row">'.
                     '<td>'.$title{'togglecats'}.'</td>'.
                     '<td class="LC_right_item"><span class="LC_nobreak"><label>'.
                     '<input type="radio" name="togglecats"'.
                     $toggle_cats_dom.' value="dom" />'.$level{'dom'}.'</label>&nbsp;'.
                     '<label><input type="radio" name="togglecats"'.
                     $toggle_cats_crs.' value="crs" />'.$level{'crs'}.'</label></span></td>'.
                     '</tr><tr>'.
                     '<td>'.$title{'categorize'}.'</td>'.
                     '<td class="LC_right_item"><span class="LC_nobreak">'.
                     '<label><input type="radio" name="categorize"'.
                     $can_cat_dom.' value="dom" />'.$level{'dom'}.'</label>&nbsp;'.
                     '<label><input type="radio" name="categorize"'.
                     $can_cat_crs.'value="crs" />'.$level{'crs'}.'</label></span></td>'.
                     '</tr><tr class="LC_odd_row">'.
                     '<td>'.$title{'togglecatscomm'}.'</td>'.
                     '<td class="LC_right_item"><span class="LC_nobreak"><label>'.
                     '<input type="radio" name="togglecatscomm"'.
                     $toggle_catscomm_dom.' value="dom" />'.$level{'dom'}.'</label>&nbsp;'.
                     '<label><input type="radio" name="togglecatscomm"'.
                     $toggle_catscomm_comm.' value="comm" />'.$level{'comm'}.'</label></span></td>'.
                     '</tr><tr>'.
                     '<td>'.$title{'categorizecomm'}.'</td>'.
                     '<td class="LC_right_item"><span class="LC_nobreak">'.
                     '<label><input type="radio" name="categorizecomm"'.
                     $can_catcomm_dom.' value="dom" />'.$level{'dom'}.'</label>&nbsp;'.
                     '<label><input type="radio" name="categorizecomm"'.
                     $can_catcomm_comm.'value="comm" />'.$level{'comm'}.'</label></span></td>'.
                     '</tr>';
           $$rowtotal += 4;
       } else {
           my $css_class;
           my $itemcount = 1;
           my $cathash; 
           if (ref($settings) eq 'HASH') {
               $cathash = $settings->{'cats'};
           }
           if (ref($cathash) eq 'HASH') {
               my (@cats,@trails,%allitems,%idx,@jsarray);
               &Apache::loncommon::extract_categories($cathash,\@cats,\@trails,
                                                      \%allitems,\%idx,\@jsarray);
               my $maxdepth = scalar(@cats);
               my $colattrib = '';
               if ($maxdepth > 2) {
                   $colattrib = ' colspan="2" ';
               }
               my @path;
               if (@cats > 0) {
                   if (ref($cats[0]) eq 'ARRAY') {
                       my $numtop = @{$cats[0]};
                       my $maxnum = $numtop;
                       my %default_names = (
                             instcode    => &mt('Official courses'),
                             communities => &mt('Communities'),
                       );
   
                       if ((!grep(/^instcode$/,@{$cats[0]})) || 
                           ($cathash->{'instcode::0'} eq '') ||
                           (!grep(/^communities$/,@{$cats[0]})) || 
                           ($cathash->{'communities::0'} eq '')) {
                           $maxnum ++;
                       }
                       my $lastidx;
                       for (my $i=0; $i<$numtop; $i++) {
                           my $parent = $cats[0][$i];
                           $css_class = $itemcount%2?' class="LC_odd_row"':'';
                           my $item = &escape($parent).'::0';
                           my $chgstr = ' onchange="javascript:reorderCats(this.form,'."'','$item','$idx{$item}'".');"';
                           $lastidx = $idx{$item};
                           $datatable .= '<tr '.$css_class.'><td><span class="LC_nobreak">'
                                         .'<select name="'.$item.'"'.$chgstr.'>';
                           for (my $k=0; $k<=$maxnum; $k++) {
                               my $vpos = $k+1;
                               my $selstr;
                               if ($k == $i) {
                                   $selstr = ' selected="selected" ';
                               }
                               $datatable .= '<option value="'.$k.'"'.$selstr.'>'.$vpos.'</option>';
                           }
                           $datatable .= '</select></td><td>';
                           if ($parent eq 'instcode' || $parent eq 'communities') {
                               $datatable .=  '<span class="LC_nobreak">'
                                              .$default_names{$parent}.'</span>';
                               if ($parent eq 'instcode') {
                                   $datatable .= '<br /><span class="LC_nobreak">('
                                                 .&mt('with institutional codes')
                                                 .')</span></td><td'.$colattrib.'>';
                               } else {
                                   $datatable .= '<table><tr><td>';
                               }
                               $datatable .= '<span class="LC_nobreak">'
                                             .'<label><input type="radio" name="'
                                             .$parent.'" value="1" checked="checked" />'
                                             .&mt('Display').'</label>';
                               if ($parent eq 'instcode') {
                                   $datatable .= '&nbsp;';
                               } else {
                                   $datatable .= '</span></td></tr><tr><td>'
                                                 .'<span class="LC_nobreak">';
                               }
                               $datatable .= '<label><input type="radio" name="'
                                             .$parent.'" value="0" />'
                                             .&mt('Do not display').'</label></span>';
                               if ($parent eq 'communities') {
                                   $datatable .= '</td></tr></table>';
                               }
                               $datatable .= '</td>';
                           } else {
                               $datatable .= $parent
                                             .'&nbsp;<label><input type="checkbox" name="deletecategory" '
                                             .'value="'.$item.'" />'.&mt('Delete').'</label></span></td>';
                           }
                           my $depth = 1;
                           push(@path,$parent);
                           $datatable .= &build_category_rows($itemcount,\@cats,$depth,$parent,\@path,\%idx);
                           pop(@path);
                           $datatable .= '</tr><tr><td colspan="'.$maxdepth.'" class="LC_row_separator"></td></tr>';
                           $itemcount ++;
                       }
                       $css_class = $itemcount%2?' class="LC_odd_row"':'';
                       my $chgstr = ' onchange="javascript:reorderCats(this.form,'."'','addcategory_pos','$lastidx'".');"';
                       $datatable .= '<tr '.$css_class.'><td><span class="LC_nobreak"><select name="addcategory_pos"'.$chgstr.'>';
                       for (my $k=0; $k<=$maxnum; $k++) {
                           my $vpos = $k+1;
                           my $selstr;
                           if ($k == $numtop) {
                               $selstr = ' selected="selected" ';
                           }
                           $datatable .= '<option value="'.$k.'"'.$selstr.'>'.$vpos.'</option>';
                       }
                       $datatable .= '</select></span></td><td colspan="2">'.&mt('Add category:').'&nbsp;'
                                     .'<input type="text" size="20" name="addcategory_name" value="" /></td>'
                                     .'</tr>'."\n";
                       $itemcount ++;
                       foreach my $default ('instcode','communities') {
                           if ((!grep(/^\Q$default\E$/,@{$cats[0]})) || ($cathash->{$default.'::0'} eq '')) {
                               $css_class = $itemcount%2?' class="LC_odd_row"':'';
                               my $chgstr = ' onchange="javascript:reorderCats(this.form,'."'','$default"."_pos','$lastidx'".');"';
                               $datatable .= '<tr><td colspan="'.$maxdepth.'" class="LC_row_separator"></td></tr><tr '.$css_class.'><td>'.
                                             '<span class="LC_nobreak"><select name="'.$default.'_pos"'.$chgstr.'>';
                               for (my $k=0; $k<=$maxnum; $k++) {
                                   my $vpos = $k+1;
                                   my $selstr;
                                   if ($k == $maxnum) {
                                       $selstr = ' selected="selected" ';
                                   }
                                   $datatable .= '<option value="'.$k.'"'.$selstr.'>'.$vpos.'</option>';
                               }
                               $datatable .= '</select></span></td>'.
                                             '<td><span class="LC_nobreak">'.
                                             $default_names{$default}.'</span>';
                               if ($default eq 'instcode') {
                                   $datatable .= '<br /><span class="LC_nobreak">(' 
                                                 .&mt('with institutional codes').')</span>';
                               }
                               $datatable .= '</td>'
                                             .'<td><span class="LC_nobreak"><label><input type="radio" name="'.$default.'" value="1" />'
                                             .&mt('Display').'</label>&nbsp;'
                                             .'<label><input type="radio" name="'.$default.'" value="0" checked="checked"/>'
                                             .&mt('Do not display').'</label></span></td></tr>';
                           }
                       }
                   }
               } else {
                   $datatable .= &initialize_categories($itemcount);
               }
           } else {
               $datatable .= '<td class="LC_right_item">'.$hdritem->{'header'}->[0]->{'col2'}.'</td>'
                             .&initialize_categories($itemcount);
           }
           $$rowtotal += $itemcount;
       }
       return $datatable;
   }
   
   sub print_serverstatuses {
       my ($dom,$settings,$rowtotal) = @_;
       my $datatable;
       my @pages = &serverstatus_pages();
       my (%namedaccess,%machineaccess);
       foreach my $type (@pages) {
           $namedaccess{$type} = '';
           $machineaccess{$type}= '';
       }
       if (ref($settings) eq 'HASH') {
           foreach my $type (@pages) {
               if (exists($settings->{$type})) {
                   if (ref($settings->{$type}) eq 'HASH') {
                       foreach my $key (keys(%{$settings->{$type}})) {
                           if ($key eq 'namedusers') {
                               $namedaccess{$type} = $settings->{$type}->{$key};
                           } elsif ($key eq 'machines') {
                               $machineaccess{$type} = $settings->{$type}->{$key};
                           }
                       }
                   }
               }
           }
       }
       my $titles= &LONCAPA::lonauthcgi::serverstatus_titles();
       my $rownum = 0;
       my $css_class;
       foreach my $type (@pages) {
           $rownum ++;
           $css_class = $rownum%2?' class="LC_odd_row"':'';
           $datatable .= '<tr'.$css_class.'>'.
                         '<td><span class="LC_nobreak">'.
                         $titles->{$type}.'</span></td>'.
                         '<td class="LC_left_item">'.
                         '<input type="text" name="'.$type.'_namedusers" '.
                         'value="'.$namedaccess{$type}.'" size="30" /></td>'.
                         '<td class="LC_right_item">'.
                         '<span class="LC_nobreak">'.
                         '<input type="text" name="'.$type.'_machines" '.
                         'value="'.$machineaccess{$type}.'" size="10" />'.
                         '</td></tr>'."\n";
       }
       $$rowtotal += $rownum;
       return $datatable;
   }
   
   sub serverstatus_pages {
       return ('userstatus','lonstatus','loncron','server-status','codeversions',
               'clusterstatus','metadata_keywords','metadata_harvest',
               'takeoffline','takeonline','showenv','toggledebug');
   }
   
   sub coursecategories_javascript {
       my ($settings) = @_;
       my ($output,$jstext,$cathash);
       if (ref($settings) eq 'HASH') {
           $cathash = $settings->{'cats'};
       }
       if (ref($cathash) eq 'HASH') {
           my (@cats,@jsarray,%idx);
           &Apache::loncommon::gather_categories($cathash,\@cats,\%idx,\@jsarray);
           if (@jsarray > 0) {
               $jstext = '    var categories = Array('.scalar(@jsarray).');'."\n";
               for (my $i=0; $i<@jsarray; $i++) {
                   if (ref($jsarray[$i]) eq 'ARRAY') {
                       my $catstr = join('","',@{$jsarray[$i]});
                       $jstext .= '    categories['.$i.'] = Array("'.$catstr.'");'."\n";
                   }
               }
           }
       } else {
           $jstext  = '    var categories = Array(1);'."\n".
                      '    categories[0] = Array("instcode_pos");'."\n"; 
       }
       my $instcode_reserved = &mt('The name: "instcode" is a reserved category');
       my $communities_reserved = &mt('The name: "communities" is a reserved category');
       my $choose_again = '\\n'.&mt('Please use a different name for the new top level category'); 
       $output = <<"ENDSCRIPT";
   <script type="text/javascript">
   // <![CDATA[
   function reorderCats(form,parent,item,idx) {
       var changedVal;
   $jstext
       var newpos = 'addcategory_pos';
       var current = new Array;
       if (parent == '') {
           var has_instcode = 0;
           var maxtop = categories[idx].length;
           for (var j=0; j<maxtop; j++) {
               if (categories[idx][j] == 'instcode::0') {
                   has_instcode == 1;
               }
           }
           if (has_instcode == 0) {
               categories[idx][maxtop] = 'instcode_pos';
           }
       } else {
           newpos += '_'+parent;
       }
       var maxh = 1 + categories[idx].length;
       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<categories[idx].length; i++) {
           var elementName = categories[idx][i];
           if (elementName != item) {
               if (form.elements[elementName]) {
                   var currVal = form.elements[elementName].options[form.elements[elementName].selectedIndex].value;
                   current[currVal] = elementName;
               }
           }
       }
       var oldVal;
       for (var j=0; j<maxh; j++) {
           if (current[j] == undefined) {
               oldVal = j;
           }
       }
       if (oldVal < changedVal) {
           for (var k=oldVal+1; k<=changedVal ; k++) {
              var elementName = current[k];
              form.elements[elementName].selectedIndex = form.elements[elementName].selectedIndex - 1;
           }
       } else {
           for (var k=changedVal; k<oldVal; k++) {
               var elementName = current[k];
               form.elements[elementName].selectedIndex = form.elements[elementName].selectedIndex + 1;
           }
       }
       return;
   }
   
   function categoryCheck(form) {
       if (form.elements['addcategory_name'].value == 'instcode') {
           alert('$instcode_reserved\\n$choose_again');
           return false;
       }
       if (form.elements['addcategory_name'].value == 'communities') {
           alert('$communities_reserved\\n$choose_again');
           return false;
       }
       return true;
   }
   
   // ]]>
   </script>
   
   ENDSCRIPT
       return $output;
   }
   
   sub initialize_categories {
       my ($itemcount) = @_;
       my ($datatable,$css_class,$chgstr);
       my %default_names = (
                         instcode    => 'Official courses (with institutional codes)',
                         communities => 'Communities',
                           );
       my $select0 = ' selected="selected"';
       my $select1 = '';
       foreach my $default ('instcode','communities') {
           $css_class = $itemcount%2?' class="LC_odd_row"':'';
           $chgstr = ' onchange="javascript:reorderCats(this.form,'."'',$default"."_pos','0'".');"';
           if ($default eq 'communities') {
               $select1 = $select0;
               $select0 = '';
           }
           $datatable .= '<tr '.$css_class.'><td><span class="LC_nobreak">'
                        .'<select name="'.$default.'_pos">'
                        .'<option value="0"'.$select0.'>1</option>'
                        .'<option value="1"'.$select1.'>2</option>'
                        .'<option value="2">3</option></select>&nbsp;'
                        .$default_names{$default}
                        .'</span></td><td><span class="LC_nobreak">'
                        .'<label><input type="radio" name="'.$default.'" value="1" checked="checked" />'
                        .&mt('Display').'</label>&nbsp;<label>'
                        .'<input type="radio" name="'.$default.'" value="0" />'.&mt('Do not display')
                    .'</label></span></td></tr>';
           $itemcount ++;
       }
       $css_class = $itemcount%2?' class="LC_odd_row"':'';
       $chgstr = ' onchange="javascript:reorderCats(this.form,'."'','addcategory_pos','0'".');"';
       $datatable .= '<tr '.$css_class.'><td><span class="LC_nobreak">'
                     .'<select name="addcategory_pos"'.$chgstr.'>'
                     .'<option value="0">1</option>'
                     .'<option value="1">2</option>'
                     .'<option value="2" selected="selected">3</option></select>&nbsp;'
                     .&mt('Add category').'</td><td>'.&mt('Name:')
                     .'&nbsp;<input type="text" size="20" name="addcategory_name" value="" /></td></tr>';
       return $datatable;
   }
   
   sub build_category_rows {
       my ($itemcount,$cats,$depth,$parent,$path,$idx) = @_;
       my ($text,$name,$item,$chgstr);
       if (ref($cats) eq 'ARRAY') {
           my $maxdepth = scalar(@{$cats});
           if (ref($cats->[$depth]) eq 'HASH') {
               if (ref($cats->[$depth]{$parent}) eq 'ARRAY') {
                   my $numchildren = @{$cats->[$depth]{$parent}};
                   my $css_class = $itemcount%2?' class="LC_odd_row"':'';
                   $text .= '<td><table class="LC_datatable">';
                   my ($idxnum,$parent_name,$parent_item);
                   my $higher = $depth - 1;
                   if ($higher == 0) {
                       $parent_name = &escape($parent).'::'.$higher;
                   } else {
                       if (ref($path) eq 'ARRAY') {
                           $parent_name = &escape($parent).':'.&escape($path->[-2]).':'.$higher;
                       }
                   }
                   $parent_item = 'addcategory_pos_'.$parent_name;
                   for (my $j=0; $j<=$numchildren; $j++) {
                       if ($j < $numchildren) {
                           $name = $cats->[$depth]{$parent}[$j];
                           $item = &escape($name).':'.&escape($parent).':'.$depth;
                           $idxnum = $idx->{$item};
                       } else {
                           $name = $parent_name;
                           $item = $parent_item;
                       }
                       $chgstr = ' onchange="javascript:reorderCats(this.form,'."'$parent_name','$item','$idxnum'".');"';
                       $text .= '<tr '.$css_class.'><td><span class="LC_nobreak"><select name="'.$item.'"'.$chgstr.'>';
                       for (my $i=0; $i<=$numchildren; $i++) {
                           my $vpos = $i+1;
                           my $selstr;
                           if ($j == $i) {
                               $selstr = ' selected="selected" ';
                           }
                           $text .= '<option value="'.$i.'"'.$selstr.'>'.$vpos.'</option>';
                       }
                       $text .= '</select>&nbsp;';
                       if ($j < $numchildren) {
                           my $deeper = $depth+1;
                           $text .= $name.'&nbsp;'
                                    .'<label><input type="checkbox" name="deletecategory" value="'
                                    .$item.'" />'.&mt('Delete').'</label></span></td><td>';
                           if(ref($path) eq 'ARRAY') {
                               push(@{$path},$name);
                               $text .= &build_category_rows($itemcount,$cats,$deeper,$name,$path,$idx);
                               pop(@{$path});
                           }
                       } else {
                           $text .= &mt('Add subcategory:').'&nbsp;</span><input type="textbox" size="20" name="addcategory_name_';
                           if ($j == $numchildren) {
                               $text .= $name;
                           } else {
                               $text .= $item;
                           }
                           $text .= '" value="" />';
                       }
                       $text .= '</td></tr>';
                   }
                   $text .= '</table></td>';
               } else {
                   my $higher = $depth-1;
                   if ($higher == 0) {
                       $name = &escape($parent).'::'.$higher;
                   } else {
                       if (ref($path) eq 'ARRAY') {
                           $name = &escape($parent).':'.&escape($path->[-2]).':'.$higher;
                       }
                   }
                   my $colspan;
                   if ($parent ne 'instcode') {
                       $colspan = $maxdepth - $depth - 1;
                       $text .= '<td colspan="'.$colspan.'">'.&mt('Add subcategory:').'<input type="textbox" size="20" name="subcat_'.$name.'" value="" /></td>';
                   }
               }
           }
       }
       return $text;
   }
   
   sub modifiable_userdata_row {
       my ($context,$role,$settings,$numinrow,$rowcount,$usertypes) = @_;
       my $rolename;
       if ($context eq 'selfcreate') {
           if (ref($usertypes) eq 'HASH') {
               $rolename = $usertypes->{$role};
           } else {
               $rolename = $role;
           }
       } else {
           if ($role eq 'cr') {
               $rolename = &mt('Custom role');
           } else {
               $rolename = &Apache::lonnet::plaintext($role);
           }
       }
       my @fields = ('lastname','firstname','middlename','generation',
                     'permanentemail','id');
       my %fieldtitles = &Apache::loncommon::personal_data_fieldtitles();
       my $output;
       my $css_class = $rowcount%2?' class="LC_odd_row"':'';
       $output = '<tr '.$css_class.'>'.
                 '<td><span class="LC_nobreak">'.$rolename.'</span></td>'.
                 '<td class="LC_left_item" colspan="2"><table>';
       my $rem;
       my %checks;
       if (ref($settings) eq 'HASH') {
           if (ref($settings->{$context}) eq 'HASH') {
               if (ref($settings->{$context}->{$role}) eq 'HASH') {
                   foreach my $field (@fields) {
                       if ($settings->{$context}->{$role}->{$field}) {
                           $checks{$field} = ' checked="checked" ';
                       }
                   }
               }
           }
       }
       for (my $i=0; $i<@fields; $i++) {
           my $rem = $i%($numinrow);
           if ($rem == 0) {
               if ($i > 0) {
                   $output .= '</tr>';
               }
               $output .= '<tr>';
           }
           my $check = ' ';
           if (exists($checks{$fields[$i]})) {
               $check = $checks{$fields[$i]}
           } else {
               if ($role eq 'st') {
                   if (ref($settings) ne 'HASH') {
                       $check = ' checked="checked" '; 
                   }
               }
           }
           $output .= '<td class="LC_left_item">'.
                      '<span class="LC_nobreak"><label>'.
                      '<input type="checkbox" name="canmodify_'.$role.'" '.
                      'value="'.$fields[$i].'"'.$check.'/>'.$fieldtitles{$fields[$i]}.
                      '</label></span></td>';
           $rem = @fields%($numinrow);
       }
       my $colsleft = $numinrow - $rem;
       if ($colsleft > 1 ) {
           $output .= '<td colspan="'.$colsleft.'" class="LC_left_item">'.
                      '&nbsp;</td>';
       } elsif ($colsleft == 1) {
           $output .= '<td class="LC_left_item">&nbsp;</td>';
       }
       $output .= '</tr></table></td></tr>';
       return $output;
   }
   
   sub insttypes_row {
       my ($settings,$types,$usertypes,$dom,$numinrow,$othertitle,$context) = @_;
       my %lt = &Apache::lonlocal::texthash (
                         cansearch => 'Users allowed to search',
                         statustocreate => 'Institutional affiliation(s) able to create own account (login/SSO)',
                         lockablenames => 'User preference to lock name',
                );
       my $showdom;
       if ($context eq 'cansearch') {
           $showdom = ' ('.$dom.')';
       }
     my $output =  '<tr class="LC_odd_row">'.      my $output =  '<tr class="LC_odd_row">'.
                   '<td>'.&mt('Users allowed to search').' ('.$dom.')'.                    '<td>'.$lt{$context}.$showdom.
                   '</td><td class="LC_left_item" colspan="2"><table>';                    '</td><td class="LC_left_item" colspan="2"><table>';
     my $rem;      my $rem;
     if (ref($types) eq 'ARRAY') {      if (ref($types) eq 'ARRAY') {
Line 1104  sub users_cansearch_row { Line 3666  sub users_cansearch_row {
                     $output .= '<tr>';                      $output .= '<tr>';
                 }                  }
                 my $check = ' ';                  my $check = ' ';
                 if (ref($settings->{'cansearch'}) eq 'ARRAY') {                  if (ref($settings) eq 'HASH') {
                     if (grep(/^\Q$types->[$i]\E$/,@{$settings->{'cansearch'}})) {                      if (ref($settings->{$context}) eq 'ARRAY') {
                           if (grep(/^\Q$types->[$i]\E$/,@{$settings->{$context}})) {
                               $check = ' checked="checked" ';
                           }
                       } elsif ($context eq 'statustocreate') {
                         $check = ' checked="checked" ';                          $check = ' checked="checked" ';
                     }                      }
                 }                  }
                 $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="cansearch" '.                             '<input type="checkbox" name="'.$context.'" '.
                            'value="'.$types->[$i].'"'.$check.'/>'.                             '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 (($rem == 0) && (@{$types} > 0)) {
           $output .= '<tr>';
       }
     if ($colsleft > 1) {      if ($colsleft > 1) {
         $output .= '<td colspan="'.$colsleft.'" class="LC_left_item">';          $output .= '<td colspan="'.$colsleft.'" class="LC_left_item">';
     } else {      } else {
         $output .= '<td class="LC_left_item">';          $output .= '<td class="LC_left_item">';
     }      }
     my $defcheck = ' ';      my $defcheck = ' ';
     if (ref($settings->{'cansearch'}) eq 'ARRAY') {      if (ref($settings) eq 'HASH') {  
         if (grep(/^default$/,@{$settings->{'cansearch'}})) {          if (ref($settings->{$context}) eq 'ARRAY') {
               if (grep(/^default$/,@{$settings->{$context}})) {
                   $defcheck = ' checked="checked" ';
               }
           } elsif ($context eq 'statustocreate') {
             $defcheck = ' checked="checked" ';              $defcheck = ' checked="checked" ';
         }          }
     }      }
     $output .= '<span class="LC_nobreak"><label>'.      $output .= '<span class="LC_nobreak"><label>'.
                '<input type="checkbox" name="cansearch" '.                 '<input type="checkbox" name="'.$context.'" '.
                'value="default"'.$defcheck.'/>'.                 'value="default"'.$defcheck.'/>'.
                $othertitle.'</label></span></td>'.                 $othertitle.'</label></span></td>'.
                '</tr></table></td></tr>';                 '</tr></table></td></tr>';
     return $output;      return $output;
 }  }
   
 sub sorted_inst_types {  
     my ($dom) = @_;  
     my ($usertypes,$order) = &Apache::lonnet::retrieve_inst_usertypes($dom);  
     my $othertitle = &mt('All users');  
     my @types;  
     if (ref($order) eq 'ARRAY') {  
         @types = @{$order};  
     }  
     if (@types == 0) {  
         if (ref($usertypes) eq 'HASH') {  
             @types = sort(keys(%{$usertypes}));  
         }  
     }  
     if (keys(%{$usertypes}) > 0) {  
         $othertitle = &mt('Other users');  
     }  
     return ($othertitle,$usertypes,\@types);  
 }  
   
 sub sorted_searchtitles {  sub sorted_searchtitles {
     my %searchtitles = &Apache::lonlocal::texthash(      my %searchtitles = &Apache::lonlocal::texthash(
                          'uname' => 'username',                           'uname' => 'username',
Line 1197  sub usertype_update_row { Line 3750  sub usertype_update_row {
                     $datatable .= '<tr>';                      $datatable .= '<tr>';
                 }                  }
                 my $check = ' ';                  my $check = ' ';
                 if (ref($settings->{'fields'}) eq 'HASH') {                  if (ref($settings) eq 'HASH') {
                     if (ref($settings->{'fields'}{$type}) eq 'ARRAY') {                      if (ref($settings->{'fields'}) eq 'HASH') {
                         if (grep(/^\Q$fields->[$i]\E$/,@{$settings->{'fields'}{$type}})) {                          if (ref($settings->{'fields'}{$type}) eq 'ARRAY') {
                             $check = ' checked="checked" ';                              if (grep(/^\Q$fields->[$i]\E$/,@{$settings->{'fields'}{$type}})) {
                                   $check = ' checked="checked" ';
                               }
                         }                          }
                     }                      }
                 }                  }
Line 1230  sub modify_login { Line 3785  sub modify_login {
     my ($r,$dom,$confname,%domconfig) = @_;      my ($r,$dom,$confname,%domconfig) = @_;
     my ($resulttext,$errors,$colchgtext,%changes,%colchanges);      my ($resulttext,$errors,$colchgtext,%changes,%colchanges);
     my %title = ( coursecatalog => 'Display course catalog',      my %title = ( coursecatalog => 'Display course catalog',
                   adminmail => 'Display administrator E-mail address');                    adminmail => 'Display administrator E-mail address',
                     newuser => 'Link for visitors to create a user account',
                     loginheader => 'Log-in box header');
     my @offon = ('off','on');      my @offon = ('off','on');
       my %curr_loginvia;
       if (ref($domconfig{login}) eq 'HASH') {
           if (ref($domconfig{login}{loginvia}) eq 'HASH') {
               foreach my $lonhost (keys(%{$domconfig{login}{loginvia}})) {
                   $curr_loginvia{$lonhost} = $domconfig{login}{loginvia}{$lonhost};
               }
           }
       }
     my %loginhash;      my %loginhash;
     ($errors,%colchanges) = &modify_colors($r,$dom,$confname,['login'],      ($errors,%colchanges) = &modify_colors($r,$dom,$confname,['login'],
                                            \%domconfig,\%loginhash);                                             \%domconfig,\%loginhash);
     $loginhash{login}{coursecatalog} = $env{'form.coursecatalog'};      my @toggles = ('coursecatalog','adminmail','newuser');
     $loginhash{login}{adminmail} = $env{'form.adminmail'};      foreach my $item (@toggles) {
           $loginhash{login}{$item} = $env{'form.'.$item};
       }
       $loginhash{login}{loginheader} = $env{'form.loginheader'};
     if (ref($colchanges{'login'}) eq 'HASH') {        if (ref($colchanges{'login'}) eq 'HASH') {  
         $colchgtext = &display_colorchgs($dom,\%colchanges,['login'],          $colchgtext = &display_colorchgs($dom,\%colchanges,['login'],
                                          \%loginhash);                                           \%loginhash);
     }      }
   
       my %servers = &dom_servers($dom);
       my @loginvia_attribs = ('serverpath','custompath','exempt');
       if (keys(%servers) > 1) {
           foreach my $lonhost (keys(%servers)) {
               next if ($env{'form.'.$lonhost.'_server'} eq $lonhost);
               if (ref($curr_loginvia{$lonhost}) eq 'HASH') {
                   if ($env{'form.'.$lonhost.'_server'} eq $curr_loginvia{$lonhost}{'server'}) {
                       $loginhash{login}{loginvia}{$lonhost}{'server'} = $curr_loginvia{$lonhost}{'server'};
                   } elsif ($curr_loginvia{$lonhost}{'server'} ne '') {
                       if (defined($servers{$env{'form.'.$lonhost.'_server'}})) {
                           $loginhash{login}{loginvia}{$lonhost}{'server'} = $env{'form.'.$lonhost.'_server'};
                           $changes{'loginvia'}{$lonhost} = 1;
                       } else {
                           $loginhash{login}{loginvia}{$lonhost}{'server'} = '';
                           $changes{'loginvia'}{$lonhost} = 1;
                       }
                   } else {
                       if (defined($servers{$env{'form.'.$lonhost.'_server'}})) {
                           $loginhash{login}{loginvia}{$lonhost}{'server'} = $env{'form.'.$lonhost.'_server'};
                           $changes{'loginvia'}{$lonhost} = 1;
                       }
                   }
                   if ($loginhash{login}{loginvia}{$lonhost}{'server'} eq '') {
                       foreach my $item (@loginvia_attribs) {
                           $loginhash{login}{loginvia}{$lonhost}{$item} = '';
                       }
                   } else {
                       foreach my $item (@loginvia_attribs) {
                           my $new = $env{'form.'.$lonhost.'_'.$item};
                           if (($item eq 'serverpath') && ($new eq 'custom')) {
                               $env{'form.'.$lonhost.'_custompath'} =~ s/\s+//g;
                               if ($env{'form.'.$lonhost.'_custompath'} eq '') {
                                   $new = '/';
                               }
                           }
                           if (($item eq 'custompath') && 
                               ($env{'form.'.$lonhost.'_serverpath'} ne 'custom')) {
                               $new = '';
                           }
                           if ($new ne $curr_loginvia{$lonhost}{$item}) {
                               $changes{'loginvia'}{$lonhost} = 1;
                           }
                           if ($item eq 'exempt') {
                               $new =~ s/^\s+//;
                               $new =~ s/\s+$//;
                               my @poss_ips = split(/\s*[,:]\s*/,$new);
                               my @okips;
                               foreach my $ip (@poss_ips) {
                                   if ($ip =~ /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/) {
                                       if (($1 <= 255) && ($2 <= 255) && ($3 <= 255) && ($4 <= 255)) {
                                           push(@okips,$ip); 
                                       }
                                   }
                               }
                               if (@okips > 0) {
                                   $new = join(',',@okips); 
                               } else {
                                   $new = ''; 
                               }
                           }
   
                           $loginhash{login}{loginvia}{$lonhost}{$item} = $new;
                       }
                   }
               } else {
                   if (defined($servers{$env{'form.'.$lonhost.'_server'}})) {
                       $loginhash{login}{loginvia}{$lonhost}{'server'} = $env{'form.'.$lonhost.'_server'};
                       $changes{'loginvia'}{$lonhost} = 1;
                       foreach my $item (@loginvia_attribs) {
                           my $new = $env{'form.'.$lonhost.'_'.$item};
                           if (($item eq 'serverpath') && ($new eq 'custom')) {
                               if ($env{'form.'.$lonhost.'_custompath'} eq '') {
                                   $new = '/';
                               }
                           }
                           if (($item eq 'custompath') && 
                               ($env{'form.'.$lonhost.'_serverpath'} ne 'custom')) {
                               $new = '';
                           }
                           $loginhash{login}{loginvia}{$lonhost}{$item} = $new;
                       }
                   }
               }
           }
       }
   
     my $putresult = &Apache::lonnet::put_dom('configuration',\%loginhash,      my $putresult = &Apache::lonnet::put_dom('configuration',\%loginhash,
                                              $dom);                                               $dom);
     if ($putresult eq 'ok') {      if ($putresult eq 'ok') {
         if (($domconfig{'login'}{'coursecatalog'} eq '0') &&          my @toggles = ('coursecatalog','adminmail','newuser');
             ($env{'form.coursecatalog'} eq '1')) {          my %defaultchecked = (
             $changes{'coursecatalog'} = 1;                      'coursecatalog' => 'on',
         } elsif (($domconfig{'login'}{'coursecatalog'} eq '' ||                      'adminmail'     => 'off',
                  $domconfig{'login'}{'coursecatalog'} eq '1') &&                      'newuser'       => 'off',
                  ($env{'form.coursecatalog'} eq '0')) {          );
             $changes{'coursecatalog'} = 1;          if (ref($domconfig{'login'}) eq 'HASH') {
         }              foreach my $item (@toggles) {
         if (($domconfig{'login'}{'adminmail'} eq '1') &&                  if ($defaultchecked{$item} eq 'on') { 
                 ($env{'form.adminmail'} eq '0')) {                      if (($domconfig{'login'}{$item} eq '0') &&
             $changes{'adminmail'} = 1;                          ($env{'form.'.$item} eq '1')) {
         } elsif (($domconfig{'login'}{'adminmail'} eq '' ||                          $changes{$item} = 1;
                  $domconfig{'login'}{'adminmail'} eq '0') &&                      } elsif (($domconfig{'login'}{$item} eq '' ||
                  ($env{'form.adminmail'} eq '1')) {                                $domconfig{'login'}{$item} eq '1') &&
             $changes{'adminmail'} = 1;                               ($env{'form.'.$item} eq '0')) {
                           $changes{$item} = 1;
                       }
                   } elsif ($defaultchecked{$item} eq 'off') {
                       if (($domconfig{'login'}{$item} eq '1') &&
                           ($env{'form.'.$item} eq '0')) {
                           $changes{$item} = 1;
                       } elsif (($domconfig{'login'}{$item} eq '' ||
                                 $domconfig{'login'}{$item} eq '0') &&
                                ($env{'form.'.$item} eq '1')) {
                           $changes{$item} = 1;
                       }
                   }
               }
         }          }
         if (keys(%changes) > 0 || $colchgtext) {          if (keys(%changes) > 0 || $colchgtext) {
               &Apache::loncommon::devalidate_domconfig_cache($dom);
             $resulttext = &mt('Changes made:').'<ul>';              $resulttext = &mt('Changes made:').'<ul>';
             foreach my $item (sort(keys(%changes))) {              foreach my $item (sort(keys(%changes))) {
                 $resulttext .= '<li>'.&mt("$title{$item} set to $offon[$env{'form.'.$item}]").'</li>';                  if ($item eq 'loginvia') {
                       if (ref($changes{$item}) eq 'HASH') {
                           $resulttext .= '<li>'.&mt('Log-in page availability:').'<ul>';
                           foreach my $lonhost (sort(keys(%{$changes{$item}}))) {
                               if (defined($servers{$loginhash{login}{loginvia}{$lonhost}{'server'}})) {
                                   if (ref($loginhash{login}{loginvia}{$lonhost}) eq 'HASH') {
                                       my $protocol = $Apache::lonnet::protocol{$env{'form.'.$lonhost.'_server'}};
                                       $protocol = 'http' if ($protocol ne 'https');
                                       my $target = $protocol.'://'.$servers{$env{'form.'.$lonhost.'_server'}};
   
                                       if ($loginhash{login}{loginvia}{$lonhost}{'serverpath'} eq 'custom') {
                                           $target .= $loginhash{login}{loginvia}{$lonhost}{'custompath'};
                                       } else {
                                           $target .= $loginhash{login}{loginvia}{$lonhost}{'serverpath'}; 
                                       }
                                       $resulttext .= '<li>'.&mt('Server: [_1] log-in page redirects to [_2].',$servers{$lonhost},'<a href="'.$target.'">'.$target.'</a>');
                                       if ($loginhash{login}{loginvia}{$lonhost}{'exempt'} ne '') {
                                           $resulttext .= '&nbsp;'.&mt('No redirection for clients from following IPs:').'&nbsp;'.$loginhash{login}{loginvia}{$lonhost}{'exempt'};
                                       }
                                       $resulttext .= '</li>';
                                   } else {
                                       $resulttext .= '<li>'.&mt('Server: [_1] has standard log-in page.',$lonhost).'</li>';
                                   }
                               } else {
                                   $resulttext .= '<li>'.&mt('Server: [_1] has standard log-in page.',$servers{$lonhost}).'</li>';
                               }
                           }
                           $resulttext .= '</ul></li>';
                       }
                   } else {
                       $resulttext .= '<li>'.&mt("$title{$item} set to $offon[$env{'form.'.$item}]").'</li>';
                   }
             }              }
             $resulttext .= $colchgtext.'</ul>';              $resulttext .= $colchgtext.'</ul>';
         } else {          } else {
Line 1286  sub color_font_choices { Line 3986  sub color_font_choices {
             img => "Header",              img => "Header",
             bgs => "Background colors",              bgs => "Background colors",
             links => "Link colors",              links => "Link colors",
               images => "Images",
             font => "Font color",              font => "Font color",
               fontmenu => "Font Menu",
             pgbg => "Page",              pgbg => "Page",
             tabbg => "Header",              tabbg => "Header",
             sidebg => "Border",              sidebg => "Border",
Line 1301  sub modify_rolecolors { Line 4003  sub modify_rolecolors {
     my ($r,$dom,$confname,$roles,%domconfig) = @_;      my ($r,$dom,$confname,$roles,%domconfig) = @_;
     my ($resulttext,%rolehash);      my ($resulttext,%rolehash);
     $rolehash{'rolecolors'} = {};      $rolehash{'rolecolors'} = {};
       if (ref($domconfig{'rolecolors'}) ne 'HASH') {
           if ($domconfig{'rolecolors'} eq '') {
               $domconfig{'rolecolors'} = {};
           }
       }
     my ($errors,%changes) = &modify_colors($r,$dom,$confname,$roles,      my ($errors,%changes) = &modify_colors($r,$dom,$confname,$roles,
                          $domconfig{'rolecolors'},$rolehash{'rolecolors'});                           $domconfig{'rolecolors'},$rolehash{'rolecolors'});
     my $putresult = &Apache::lonnet::put_dom('configuration',\%rolehash,      my $putresult = &Apache::lonnet::put_dom('configuration',\%rolehash,
                                              $dom);                                               $dom);
     if ($putresult eq 'ok') {      if ($putresult eq 'ok') {
         if (keys(%changes) > 0) {          if (keys(%changes) > 0) {
               &Apache::loncommon::devalidate_domconfig_cache($dom);
             $resulttext = &display_colorchgs($dom,\%changes,$roles,              $resulttext = &display_colorchgs($dom,\%changes,$roles,
                                              $rolehash{'rolecolors'});                                               $rolehash{'rolecolors'});
         } else {          } else {
Line 1326  sub modify_rolecolors { Line 4034  sub modify_rolecolors {
 sub modify_colors {  sub modify_colors {
     my ($r,$dom,$confname,$roles,$domconfig,$confhash) = @_;      my ($r,$dom,$confname,$roles,$domconfig,$confhash) = @_;
     my (%changes,%choices);      my (%changes,%choices);
     my @bgs = ('pgbg','mainbg','sidebg');      my @bgs;
     my @links = ('link','alink','vlink');      my @links = ('link','alink','vlink');
       my @logintext;
     my @images;      my @images;
     my $servadm = $r->dir_config('lonAdmEMail');      my $servadm = $r->dir_config('lonAdmEMail');
     my $errors;      my $errors;
     foreach my $role (@{$roles}) {      foreach my $role (@{$roles}) {
         if ($role eq 'login') {          if ($role eq 'login') {
             %choices = &login_choices();              %choices = &login_choices();
               @logintext = ('textcol','bgcol');
         } else {          } else {
             %choices = &color_font_choices();              %choices = &color_font_choices();
               $confhash->{$role}{'fontmenu'} = $env{'form.'.$role.'_fontmenu'};
         }          }
         if ($role eq 'login') {          if ($role eq 'login') {
             @images = ('img','logo','domlogo');              @images = ('img','logo','domlogo','login');
               @bgs = ('pgbg','mainbg','sidebg');
         } else {          } else {
             @images = ('img');              @images = ('img');
               @bgs = ('pgbg','tabbg','sidebg'); 
         }          }
         $confhash->{$role}{'font'} = $env{'form.'.$role.'_font'};          $confhash->{$role}{'font'} = $env{'form.'.$role.'_font'};
         foreach my $item (@bgs,@links) {          foreach my $item (@bgs,@links,@logintext) {
             $confhash->{$role}{$item} = $env{'form.'.$role.'_'.$item};              $confhash->{$role}{$item} = $env{'form.'.$role.'_'.$item};
         }          }
         my ($configuserok,$author_ok,$switchserver,%currroles);          my ($configuserok,$author_ok,$switchserver) = 
         my $uhome = &Apache::lonnet::homeserver($confname,$dom,1);              &config_check($dom,$confname,$servadm);
         ($configuserok,%currroles) = &check_configuser($uhome,$dom,  
                                                        $confname,$servadm);  
         if ($configuserok eq 'ok') {  
             $switchserver = &check_switchserver($dom,$confname);  
             if ($switchserver eq '') {  
                 $author_ok = &check_authorstatus($dom,$confname,%currroles);  
             }  
         }  
         my ($width,$height) = &thumb_dimensions();          my ($width,$height) = &thumb_dimensions();
           if (ref($domconfig->{$role}) ne 'HASH') {
               $domconfig->{$role} = {};
           }
         foreach my $img (@images) {          foreach my $img (@images) {
               if (($role eq 'login') && (($img eq 'img') || ($img eq 'logo'))) {  
                   if (defined($env{'form.login_showlogo_'.$img})) {
                       $confhash->{$role}{'showlogo'}{$img} = 1;
                   } else { 
                       $confhash->{$role}{'showlogo'}{$img} = 0;
                   }
               } 
     if ( ! $env{'form.'.$role.'_'.$img.'.filename'}       if ( ! $env{'form.'.$role.'_'.$img.'.filename'} 
  && !defined($domconfig->{$role}{$img})   && !defined($domconfig->{$role}{$img})
  && !$env{'form.'.$role.'_del_'.$img}   && !$env{'form.'.$role.'_del_'.$img}
Line 1384  sub modify_colors { Line 4099  sub modify_colors {
                                 $error = &mt("Upload of [_1] image for $role page(s) failed because an error occurred publishing the file in RES space. Error was: [_2].",$choices{img},$result);                                  $error = &mt("Upload of [_1] image for $role page(s) failed because an error occurred publishing the file in RES space. Error was: [_2].",$choices{img},$result);
                             }                              }
                         } else {                          } else {
                             $error = &mt("Upload of [_1] image for $role page(s) failed because an author role could not be assigned to a Domain Configuation user ([_2]) in domain: [_3].  Error was: [_4].",$choices{$img},$confname,$dom,$author_ok);                              $error = &mt("Upload of [_1] image for $role page(s) failed because an author role could not be assigned to a Domain Configuration user ([_2]) in domain: [_3].  Error was: [_4].",$choices{$img},$confname,$dom,$author_ok);
                         }                          }
                     }                      }
                 } else {                  } else {
                     $error = &mt("Upload of [_1] image for $role page(s) failed because a Domain Configuation user ([_2]) could not be created in domain: [_3].  Error was: [_4].",$choices{$img},$confname,$dom,$configuserok);                      $error = &mt("Upload of [_1] image for $role page(s) failed because a Domain Configuration user ([_2]) could not be created in domain: [_3].  Error was: [_4].",$choices{$img},$confname,$dom,$configuserok);
                 }                  }
                 if ($error) {                  if ($error) {
                     &Apache::lonnet::logthis($error);                      &Apache::lonnet::logthis($error);
Line 1432  sub modify_colors { Line 4147  sub modify_colors {
                             $changes{$role}{'images'}{$img} = 1;                              $changes{$role}{'images'}{$img} = 1;
                         }                           } 
                     }                      }
                 }                        if (($role eq 'login') && (($img eq 'logo') || ($img eq 'img'))) {
                           if (ref($domconfig->{'login'}{'showlogo'}) eq 'HASH') {
                               if ($confhash->{$role}{'showlogo'}{$img} ne 
                                   $domconfig->{$role}{'showlogo'}{$img}) {
                                   $changes{$role}{'showlogo'}{$img} = 1; 
                               }
                           } else {
                               if ($confhash->{$role}{'showlogo'}{$img} == 0) {
                                   $changes{$role}{'showlogo'}{$img} = 1;
                               }
                           }
                       }
                   }
                 if ($domconfig->{$role}{'font'} ne '') {                  if ($domconfig->{$role}{'font'} ne '') {
                     if ($confhash->{$role}{'font'} ne $domconfig->{$role}{'font'}) {                      if ($confhash->{$role}{'font'} ne $domconfig->{$role}{'font'}) {
                         $changes{$role}{'font'} = 1;                          $changes{$role}{'font'} = 1;
Line 1442  sub modify_colors { Line 4169  sub modify_colors {
                         $changes{$role}{'font'} = 1;                          $changes{$role}{'font'} = 1;
                     }                      }
                 }                  }
                   if ($role ne 'login') {
                       if ($domconfig->{$role}{'fontmenu'} ne '') {
                           if ($confhash->{$role}{'fontmenu'} ne $domconfig->{$role}{'fontmenu'}) {
                               $changes{$role}{'fontmenu'} = 1;
                           }
                       } else {
                           if ($confhash->{$role}{'fontmenu'}) {
                               $changes{$role}{'fontmenu'} = 1;
                           }
                       }
                   }
                 foreach my $item (@bgs) {                  foreach my $item (@bgs) {
                     if ($domconfig->{$role}{$item} ne '') {                      if ($domconfig->{$role}{$item} ne '') {
                         if ($confhash->{$role}{$item} ne $domconfig->{$role}{$item}) {                          if ($confhash->{$role}{$item} ne $domconfig->{$role}{$item}) {
Line 1464  sub modify_colors { Line 4202  sub modify_colors {
                         }                          }
                     }                      }
                 }                  }
                   foreach my $item (@logintext) {
                       if ($domconfig->{$role}{$item} ne '') {
                           if ($confhash->{$role}{$item} ne $domconfig->{$role}{$item}) {
                               $changes{$role}{'logintext'}{$item} = 1;
                           }
                       } else {
                           if ($confhash->{$role}{$item}) {
                               $changes{$role}{'logintext'}{$item} = 1;
                           }
                       }
                   }
             } else {              } else {
                 &default_change_checker($role,\@images,\@links,\@bgs,                  &default_change_checker($role,\@images,\@links,\@bgs,
                                         $confhash,\%changes);                                           \@logintext,$confhash,\%changes); 
             }              }
         } else {          } else {
             &default_change_checker($role,\@images,\@links,\@bgs,              &default_change_checker($role,\@images,\@links,\@bgs,
                                     $confhash,\%changes);                                       \@logintext,$confhash,\%changes); 
         }          }
     }      }
     return ($errors,%changes);      return ($errors,%changes);
 }  }
   
   sub config_check {
       my ($dom,$confname,$servadm) = @_;
       my ($configuserok,$author_ok,$switchserver,%currroles);
       my $uhome = &Apache::lonnet::homeserver($confname,$dom,1);
       ($configuserok,%currroles) = &check_configuser($uhome,$dom,
                                                      $confname,$servadm);
       if ($configuserok eq 'ok') {
           $switchserver = &check_switchserver($dom,$confname);
           if ($switchserver eq '') {
               $author_ok = &check_authorstatus($dom,$confname,%currroles);
           }
       }
       return ($configuserok,$author_ok,$switchserver);
   }
   
 sub default_change_checker {  sub default_change_checker {
     my ($role,$images,$links,$bgs,$confhash,$changes) = @_;      my ($role,$images,$links,$bgs,$logintext,$confhash,$changes) = @_;
     foreach my $item (@{$links}) {      foreach my $item (@{$links}) {
         if ($confhash->{$role}{$item}) {          if ($confhash->{$role}{$item}) {
             $changes->{$role}{'links'}{$item} = 1;              $changes->{$role}{'links'}{$item} = 1;
Line 1488  sub default_change_checker { Line 4252  sub default_change_checker {
             $changes->{$role}{'bgs'}{$item} = 1;              $changes->{$role}{'bgs'}{$item} = 1;
         }          }
     }      }
       foreach my $item (@{$logintext}) {
           if ($confhash->{$role}{$item}) {
               $changes->{$role}{'logintext'}{$item} = 1;
           }
       }
     foreach my $img (@{$images}) {      foreach my $img (@{$images}) {
         if ($env{'form.'.$role.'_del_'.$img}) {          if ($env{'form.'.$role.'_del_'.$img}) {
             $confhash->{$role}{$img} = '';              $confhash->{$role}{$img} = '';
             $changes->{$role}{'images'}{$img} = 1;              $changes->{$role}{'images'}{$img} = 1;
         }          }
           if ($role eq 'login') {
               if ($confhash->{$role}{'showlogo'}{$img} == 0) {
                   $changes->{$role}{'showlogo'}{$img} = 1;
               }
           }
     }      }
     if ($confhash->{$role}{'font'}) {      if ($confhash->{$role}{'font'}) {
         $changes->{$role}{'font'} = 1;          $changes->{$role}{'font'} = 1;
     }      }
 }   }
   
 sub display_colorchgs {  sub display_colorchgs {
     my ($dom,$changes,$roles,$confhash) = @_;      my ($dom,$changes,$roles,$confhash) = @_;
     my (%choices,$resulttext);      my (%choices,$resulttext);
     &Apache::loncommon::devalidate_domconfig_cache($dom);  
     if (!grep(/^login$/,@{$roles})) {      if (!grep(/^login$/,@{$roles})) {
         $resulttext = &mt('Changes made:').'<br />';          $resulttext = &mt('Changes made:').'<br />';
     }      }
Line 1525  sub display_colorchgs { Line 4298  sub display_colorchgs {
                         $resulttext .= '<li>'.&mt($choices{$key}).':<ul>';                          $resulttext .= '<li>'.&mt($choices{$key}).':<ul>';
                     }                      }
                     foreach my $item (sort(keys(%{$changes->{$role}{$key}}))) {                      foreach my $item (sort(keys(%{$changes->{$role}{$key}}))) {
                         if ($confhash->{$role}{$item} eq '') {                          if (($role eq 'login') && ($key eq 'showlogo')) {
                               if ($confhash->{$role}{$key}{$item}) {
                                   $resulttext .= '<li>'.&mt("$choices{$item} set to be displayed").'</li>';
                               } else {
                                   $resulttext .= '<li>'.&mt("$choices{$item} set to not be displayed").'</li>';
                               }
                           } elsif ($confhash->{$role}{$item} eq '') {
                             $resulttext .= '<li>'.&mt("$choices{$item} set to default").'</li>';                              $resulttext .= '<li>'.&mt("$choices{$item} set to default").'</li>';
                         } else {                          } else {
                             my $newitem = $confhash->{$role}{$item};                              my $newitem = $confhash->{$role}{$item};
Line 1603  sub check_authorstatus { Line 4382  sub check_authorstatus {
         my $end = 0;          my $end = 0;
         $author_ok =           $author_ok = 
             &Apache::lonnet::assignrole($dom,$confname,'/'.$dom.'/',              &Apache::lonnet::assignrole($dom,$confname,'/'.$dom.'/',
                                         'au',$end,$start);                                          'au',$end,$start,'','','domconfig');
     } else {      } else {
         $author_ok = 'ok';          $author_ok = 'ok';
     }      }
Line 1611  sub check_authorstatus { Line 4390  sub check_authorstatus {
 }  }
   
 sub publishlogo {  sub publishlogo {
     my ($r,$action,$formname,$dom,$confname,$subdir,$thumbwidth,$thumbheight) = @_;      my ($r,$action,$formname,$dom,$confname,$subdir,$thumbwidth,$thumbheight,$savefileas) = @_;
     my ($output,$fname,$logourl);      my ($output,$fname,$logourl);
     if ($action eq 'upload') {      if ($action eq 'upload') {
         $fname=$env{'form.'.$formname.'.filename'};          $fname=$env{'form.'.$formname.'.filename'};
Line 1619  sub publishlogo { Line 4398  sub publishlogo {
     } else {      } else {
         ($fname) = ($formname =~ /([^\/]+)$/);          ($fname) = ($formname =~ /([^\/]+)$/);
     }      }
       if ($savefileas ne '') {
           $fname = $savefileas;
       }
     $fname=&Apache::lonnet::clean_filename($fname);      $fname=&Apache::lonnet::clean_filename($fname);
 # See if there is anything left  # See if there is anything left
     unless ($fname) { return ('error: no uploaded file'); }      unless ($fname) { return ('error: no uploaded file'); }
Line 1646  sub publishlogo { Line 4428  sub publishlogo {
         !defined(&Apache::loncommon::fileembstyle($1))) {          !defined(&Apache::loncommon::fileembstyle($1))) {
         $output = &mt('Unrecognized file extension ([_1]) - rename the file with a proper extension and re-upload.',$1);          $output = &mt('Unrecognized file extension ([_1]) - rename the file with a proper extension and re-upload.',$1);
     } elsif ($file=~/\.(\d+)\.(\w+)$/) {      } elsif ($file=~/\.(\d+)\.(\w+)$/) {
         $output = &mt('File name not allowed a rename the file to remove the number immediately before the file extension([_1]) and re-upload.',$2);          $output = &mt('File name not allowed - rename the file to remove the number immediately before the file extension([_1]) and re-upload.',$2);
     } elsif (-d "$filepath/$file") {      } elsif (-d "$filepath/$file") {
         $output = &mt('File name is a directory name - rename the file and re-upload');          $output = &mt('File name is a directory name - rename the file and re-upload');
     } else {      } else {
Line 1828  sub check_switchserver { Line 4610  sub check_switchserver {
 }  }
   
 sub modify_quotas {  sub modify_quotas {
     my ($dom,%domconfig) = @_;      my ($dom,$action,%domconfig) = @_;
     my ($resulttext,%changes);      my ($context,@usertools,@options,%validations,%titles,%confhash,%toolshash,
     my ($othertitle,$usertypes,$types) = &sorted_inst_types($dom);          %limithash,$toolregexp,%conditions,$resulttext,%changes);
     my %formhash;      if ($action eq 'quotas') {
           $context = 'tools'; 
       } else { 
           $context = $action;
       }
       if ($context eq 'requestcourses') {
           @usertools = ('official','unofficial','community');
           @options =('norequest','approval','validate','autolimit');
           %validations = &Apache::lonnet::auto_courserequest_checks($dom);
           %titles = &courserequest_titles();
           $toolregexp = join('|',@usertools);
           %conditions = &courserequest_conditions();
       } else {
           @usertools = ('aboutme','blog','portfolio');
           %titles = &tool_titles();
       }
       my %domdefaults = &Apache::lonnet::get_domain_defaults($dom);
       my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom);
     foreach my $key (keys(%env)) {      foreach my $key (keys(%env)) {
         if ($key =~ /^form\.quota_(.+)$/) {          if ($context eq 'requestcourses') {
             $formhash{$1} = $env{$key};              if ($key =~ /^form\.crsreq_($toolregexp)_(.+)$/) {
                   my $item = $1;
                   my $type = $2;
                   if ($type =~ /^limit_(.+)/) {
                       $limithash{$item}{$1} = $env{$key};
                   } else {
                       $confhash{$item}{$type} = $env{$key};
                   }
               }
           } else {
               if ($key =~ /^form\.quota_(.+)$/) {
                   $confhash{'defaultquota'}{$1} = $env{$key};
               }
               if ($key =~ /^form\.\Q$context\E_(.+)$/) {
                   @{$toolshash{$1}} = &Apache::loncommon::get_env_multiple($key);
               }
         }          }
     }      }
     $formhash{'default'} = $env{'form.defaultquota'};      if ($context eq 'requestcourses') {
     if (ref($domconfig{'quotas'}) eq 'HASH') {          my @approvalnotify = &Apache::loncommon::get_env_multiple('form.reqapprovalnotify');
         foreach my $key (keys(%{$domconfig{'quotas'}})) {          @approvalnotify = sort(@approvalnotify);
             if (exists($formhash{$key})) {          $confhash{'notify'}{'approval'} = join(',',@approvalnotify);
                 if ($formhash{$key} ne $domconfig{'quotas'}{$key}) {          if (ref($domconfig{$action}) eq 'HASH') {
                     $changes{$key} = 1;              if (ref($domconfig{$action}{'notify'}) eq 'HASH') {
                   if ($domconfig{$action}{'notify'}{'approval'} ne $confhash{'notify'}{'approval'}) {
                       $changes{'notify'}{'approval'} = 1;
                 }                  }
             } else {              } else {
                 $formhash{$key} = $domconfig{'quotas'}{$key};                  if ($confhash{'notify'}{'approval'}) {
                       $changes{'notify'}{'approval'} = 1;
                   }
               }
           } else {
               if ($confhash{'notify'}{'approval'}) {
                   $changes{'notify'}{'approval'} = 1;
             }              }
         }          }
       } else {
           $confhash{'defaultquota'}{'default'} = $env{'form.defaultquota'};
     }      }
     foreach my $key (keys(%formhash)) {      foreach my $item (@usertools) {
         if ($formhash{$key} ne '') {          foreach my $type (@{$types},'default','_LC_adv') {
             if (!exists($domconfig{'quotas'}{$key})) {              my $unset; 
                 $changes{$key} = 1;              if ($context eq 'requestcourses') {
                   $unset = '0';
                   if ($type eq '_LC_adv') {
                       $unset = '';
                   }
                   if ($confhash{$item}{$type} eq 'autolimit') {
                       $confhash{$item}{$type} .= '=';
                       unless ($limithash{$item}{$type} =~ /\D/) {
                           $confhash{$item}{$type} .= $limithash{$item}{$type};
                       }
                   }
               } else {
                   if (grep(/^\Q$type\E$/,@{$toolshash{$item}})) {
                       $confhash{$item}{$type} = 1;
                   } else {
                       $confhash{$item}{$type} = 0;
                   }
               }
               if (ref($domconfig{$action}) eq 'HASH') {
                   if (ref($domconfig{$action}{$item}) eq 'HASH') {
                       if ($domconfig{$action}{$item}{$type} ne $confhash{$item}{$type}) {
                           $changes{$item}{$type} = 1;
                       }
                   } else {
                       if ($context eq 'requestcourses') {
                           if ($confhash{$item}{$type} ne $unset) {
                               $changes{$item}{$type} = 1;
                           }
                       } else {
                           if (!$confhash{$item}{$type}) {
                               $changes{$item}{$type} = 1;
                           }
                       }
                   }
               } else {
                   if ($context eq 'requestcourses') {
                       if ($confhash{$item}{$type} ne $unset) {
                           $changes{$item}{$type} = 1;
                       }
                   } else {
                       if (!$confhash{$item}{$type}) {
                           $changes{$item}{$type} = 1;
                       }
                   }
               }
           }
       }
       unless ($context eq 'requestcourses') {
           if (ref($domconfig{'quotas'}) eq 'HASH') {
               if (ref($domconfig{'quotas'}{'defaultquota'}) eq 'HASH') {
                   foreach my $key (keys(%{$domconfig{'quotas'}{'defaultquota'}})) {
                       if (exists($confhash{'defaultquota'}{$key})) {
                           if ($confhash{'defaultquota'}{$key} ne $domconfig{'quotas'}{'defaultquota'}{$key}) {
                               $changes{'defaultquota'}{$key} = 1;
                           }
                       } else {
                           $confhash{'defaultquota'}{$key} = $domconfig{'quotas'}{'defaultquota'}{$key};
                       }
                   }
               } else {
                   foreach my $key (keys(%{$domconfig{'quotas'}})) {
                       if (exists($confhash{'defaultquota'}{$key})) {
                           if ($confhash{'defaultquota'}{$key} ne $domconfig{'quotas'}{$key}) {
                               $changes{'defaultquota'}{$key} = 1;
                           }
                       } else {
                           $confhash{'defaultquota'}{$key} = $domconfig{'quotas'}{$key};
                       }
                   }
               }
           }
           if (ref($confhash{'defaultquota'}) eq 'HASH') {
               foreach my $key (keys(%{$confhash{'defaultquota'}})) {
                   if (ref($domconfig{'quotas'}) eq 'HASH') {
                       if (ref($domconfig{'quotas'}{'defaultquota'}) eq 'HASH') {
                           if (!exists($domconfig{'quotas'}{'defaultquota'}{$key})) {
                               $changes{'defaultquota'}{$key} = 1;
                           }
                       } else {
                           if (!exists($domconfig{'quotas'}{$key})) {
                               $changes{'defaultquota'}{$key} = 1;
                           }
                       }
                   } else {
                       $changes{'defaultquota'}{$key} = 1;
                   }
             }              }
         }          }
     }      }
   
       foreach my $key (keys(%confhash)) {
           $domdefaults{$key} = $confhash{$key};
       }
      
     my %quotahash = (      my %quotahash = (
                       quotas => {%formhash},                        $action => { %confhash }
                     );                      );
     my $putresult = &Apache::lonnet::put_dom('configuration',\%quotahash,      my $putresult = &Apache::lonnet::put_dom('configuration',\%quotahash,
                                              $dom);                                               $dom);
     if ($putresult eq 'ok') {      if ($putresult eq 'ok') {
         if (keys(%changes) > 0) {          if (keys(%changes) > 0) {
               my $cachetime = 24*60*60;
               &Apache::lonnet::do_cache_new('domdefaults',$dom,\%domdefaults,$cachetime);
   
             $resulttext = &mt('Changes made:').'<ul>';              $resulttext = &mt('Changes made:').'<ul>';
             foreach my $type (@{$types},'default') {              unless ($context eq 'requestcourses') {
                 if (defined($changes{$type})) {                   if (ref($changes{'defaultquota'}) eq 'HASH') {
                     my $typetitle = $usertypes->{$type};                      $resulttext .= '<li>'.&mt('Portfolio default quotas').'<ul>';
                     if ($type eq 'default') {                      foreach my $type (@{$types},'default') {
                         $typetitle = $othertitle;                          if (defined($changes{'defaultquota'}{$type})) {
                               my $typetitle = $usertypes->{$type};
                               if ($type eq 'default') {
                                   $typetitle = $othertitle;
                               }
                               $resulttext .= '<li>'.&mt('[_1] set to [_2] Mb',$typetitle,$confhash{'defaultquota'}{$type}).'</li>';
                           }
                       }
                       $resulttext .= '</ul></li>';
                   }
               }
               my %newenv;
               foreach my $item (@usertools) {
                   if (ref($changes{$item}) eq 'HASH') {
                       my $newacc = 
                           &Apache::lonnet::usertools_access($env{'user.name'},
                                                             $env{'user.domain'},
                                                             $item,'reload',$context);
                       if ($context eq 'requestcourses') {
                           if ($env{'environment.canrequest.'.$item} ne $newacc) {
                               $newenv{'environment.canrequest.'.$item} = $newacc;
                           }
                       } else {
                           if ($env{'environment.availabletools.'.$item} ne $newacc) { 
                               $newenv{'environment.availabletools.'.$item} = $newacc;
                           }
                       }
                       $resulttext .= '<li>'.$titles{$item}.'<ul>';
                       foreach my $type (@{$types},'default','_LC_adv') {
                           if ($changes{$item}{$type}) {
                               my $typetitle = $usertypes->{$type};
                               if ($type eq 'default') {
                                   $typetitle = $othertitle;
                               } elsif ($type eq '_LC_adv') {
                                   $typetitle = 'LON-CAPA Advanced Users'; 
                               }
                               if ($confhash{$item}{$type}) {
                                   if ($context eq 'requestcourses') {
                                       my $cond;
                                       if ($confhash{$item}{$type} =~ /^autolimit=(\d*)$/) {
                                           if ($1 eq '') {
                                               $cond = &mt('(Automatic processing of any request).');
                                           } else {
                                               $cond = &mt('(Automatic processing of requests up to limit of [quant,_1,request] per user).',$1);
                                           }
                                       } else { 
                                           $cond = $conditions{$confhash{$item}{$type}};
                                       }
                                       $resulttext .= '<li>'.&mt('Set to be available to [_1].',$typetitle).' '.$cond.'</li>';
                                   } else {
                                       $resulttext .= '<li>'.&mt('Set to be available to [_1]',$typetitle).'</li>';
                                   }
                               } else {
                                   if ($type eq '_LC_adv') {
                                       if ($confhash{$item}{$type} eq '0') {
                                           $resulttext .= '<li>'.&mt('Set to be unavailable to [_1]',$typetitle).'</li>';
                                       } else { 
                                           $resulttext .= '<li>'.&mt('No override set for [_1]',$typetitle).'</li>';
                                       }
                                   } else {
                                       $resulttext .= '<li>'.&mt('Set to be unavailable to [_1]',$typetitle).'</li>';
                                   }
                               }
                           }
                       }
                       $resulttext .= '</ul></li>';
                   }
               }
               if ($action eq 'requestcourses') {
                   if (ref($changes{'notify'}) eq 'HASH') {
                       if ($changes{'notify'}{'approval'}) {
                           if (ref($confhash{'notify'}) eq 'HASH') {
                               if ($confhash{'notify'}{'approval'}) {
                                   $resulttext .= '<li>'.&mt('Notification of requests requiring approval will be sent to: ').$confhash{'notify'}{'approval'}.'</li>';
                               } else {
                                   $resulttext .= '<li>'.&mt('No Domain Coordinators will receive notification of course requests requiring approval.').'</li>';
                               }
                           }
                     }                      }
                     $resulttext .= '<li>'.&mt('[_1] set to [_2] Mb',$typetitle,$formhash{$type}).'</li>';  
                 }                  }
             }              }
             $resulttext .= '</ul>';              $resulttext .= '</ul>';
               if (keys(%newenv)) {
                   &Apache::lonnet::appenv(\%newenv);
               }
         } else {          } else {
             $resulttext = &mt('No changes made to default quotas');              if ($context eq 'requestcourses') {
                   $resulttext = &mt('No changes made to rights to request creation of courses.');
               } else {
                   $resulttext = &mt('No changes made to availability of personal information pages, blogs, portfolios or default quotas');
               }
         }          }
     } else {      } else {
         $resulttext = '<span class="LC_error">'.          $resulttext = '<span class="LC_error">'.
Line 1895  sub modify_autoenroll { Line 4895  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)');
     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 1904  sub modify_autoenroll { Line 4905  sub modify_autoenroll {
     } elsif ($sender_uname eq '') {      } elsif ($sender_uname eq '') {
         $sender_domain = '';          $sender_domain = '';
     }      }
       my $coowners = $env{'form.autoassign_coowners'};
     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,
                                 }                                  }
                      );                       );
     my $putresult = &Apache::lonnet::put_dom('configuration',\%autoenrollhash,      my $putresult = &Apache::lonnet::put_dom('configuration',\%autoenrollhash,
Line 1929  sub modify_autoenroll { Line 4931  sub modify_autoenroll {
         if ($currautoenroll{'sender_domain'} ne $sender_domain) {          if ($currautoenroll{'sender_domain'} ne $sender_domain) {
             $changes{'sender'} = 1;              $changes{'sender'} = 1;
         }          }
           if ($currautoenroll{'co-owners'} ne '') {
               if ($currautoenroll{'co-owners'} ne $coowners) {
                   $changes{'coowners'} = 1;
               }
           } elsif ($coowners) {
               $changes{'coowners'} = 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 1941  sub modify_autoenroll { Line 4950  sub modify_autoenroll {
                     $resulttext .= '<li>'.&mt("$title{'sender'} set to [_1]",$sender_uname.':'.$sender_domain).'</li>';                      $resulttext .= '<li>'.&mt("$title{'sender'} set to [_1]",$sender_uname.':'.$sender_domain).'</li>';
                 }                  }
             }              }
               if ($changes{'coowners'}) {
                   $resulttext .= '<li>'.&mt("$title{'coowners'} set to $offon[$env{'form.autoassign_coowners'}]").'</li>';
                   &Apache::loncommon::devalidate_domconfig_cache($dom);
               }
             $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 1965  sub modify_autoupdate { Line 4978  sub modify_autoupdate {
                    run => 'Auto-update:',                     run => 'Auto-update:',
                    classlists => 'Updates to user information in classlists?'                     classlists => 'Updates to user information in classlists?'
                 );                  );
     my ($othertitle,$usertypes,$types) = &sorted_inst_types($dom);      my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom);
     my %fieldtitles = &Apache::lonlocal::texthash (      my %fieldtitles = &Apache::lonlocal::texthash (
                         id => 'Student/Employee ID',                          id => 'Student/Employee ID',
                         permanentemail => 'E-mail address',                          permanentemail => 'E-mail address',
                         lastname => 'Last Name',                          lastname => 'Last Name',
                         firstname => 'First Name',                          firstname => 'First Name',
                         middlename => 'Middle Name',                          middlename => 'Middle Name',
                         gen => 'Generation',                          generation => 'Generation',
                       );                        );
     my $othertitle = &mt('All users');      $othertitle = &mt('All users');
     if (keys(%{$usertypes}) >  0) {      if (keys(%{$usertypes}) >  0) {
         $othertitle = &mt('Other users');          $othertitle = &mt('Other users');
     }      }
     foreach my $key (keys(%env)) {      foreach my $key (keys(%env)) {
         if ($key =~ /^form\.updateable_(.+)_([^_]+)$/) {          if ($key =~ /^form\.updateable_(.+)_([^_]+)$/) {
             push(@{$fields{$1}},$2);              my ($usertype,$item) = ($1,$2);
               if (grep(/^\Q$item\E$/,keys(%fieldtitles))) {
                   if ($usertype eq 'default') {   
                       push(@{$fields{$1}},$2);
                   } elsif (ref($types) eq 'ARRAY') {
                       if (grep(/^\Q$usertype\E$/,@{$types})) {
                           push(@{$fields{$1}},$2);
                       }
                   }
               }
           }
       }
       my @lockablenames = &Apache::loncommon::get_env_multiple('form.lockablenames');
       @lockablenames = sort(@lockablenames);
       if (ref($currautoupdate{'lockablenames'}) eq 'ARRAY') {
           my @changed = &Apache::loncommon::compare_arrays($currautoupdate{'lockablenames'},\@lockablenames);
           if (@changed) {
               $changes{'lockablenames'} = 1;
           }
       } else {
           if (@lockablenames) {
               $changes{'lockablenames'} = 1;
         }          }
     }      }
     my %updatehash = (      my %updatehash = (
                       autoupdate => { run => $env{'form.autoupdate_run'},                        autoupdate => { run => $env{'form.autoupdate_run'},
                                       classlists => $env{'form.classlists'},                                        classlists => $env{'form.classlists'},
                                       fields => {%fields},                                        fields => {%fields},
                                         lockablenames => \@lockablenames,
                                     }                                      }
                      );                       );
     foreach my $key (keys(%currautoupdate)) {      foreach my $key (keys(%currautoupdate)) {
Line 2004  sub modify_autoupdate { Line 5039  sub modify_autoupdate {
                         foreach my $type (@{$currautoupdate{$key}{$item}}) {                          foreach my $type (@{$currautoupdate{$key}{$item}}) {
                             if (!exists($fields{$item})) {                              if (!exists($fields{$item})) {
                                 $change = 1;                                  $change = 1;
                                   last;
                             } elsif (ref($fields{$item}) eq 'ARRAY') {                              } elsif (ref($fields{$item}) eq 'ARRAY') {
                                 if (!grep(/^\Q$type\E$/,@{$fields{$item}})) {                                  if (!grep(/^\Q$type\E$/,@{$fields{$item}})) {
                                     $change = 1;                                      $change = 1;
                                       last;
                                 }                                  }
                             }                              }
                         }                          }
Line 2016  sub modify_autoupdate { Line 5053  sub modify_autoupdate {
                     }                       } 
                 }                  }
             }              }
           } elsif ($key eq 'lockablenames') {
               if (ref($currautoupdate{$key}) eq 'ARRAY') {
                   my @changed = &Apache::loncommon::compare_arrays($currautoupdate{'lockablenames'},\@lockablenames);
                   if (@changed) {
                       $changes{'lockablenames'} = 1;
                   }
               } else {
                   if (@lockablenames) {
                       $changes{'lockablenames'} = 1;
                   }
               }
           }
       }
       unless (grep(/^\Qlockablenames\E$/,keys(%currautoupdate))) {
           if (@lockablenames) {
               $changes{'lockablenames'} = 1;
         }          }
     }      }
     foreach my $item (@{$types},'default') {      foreach my $item (@{$types},'default') {
         if (defined($fields{$item})) {          if (defined($fields{$item})) {
             if (ref($currautoupdate{'fields'}) eq 'HASH') {              if (ref($currautoupdate{'fields'}) eq 'HASH') {
                 if (!exists($currautoupdate{'fields'}{$item})) {                  if (ref($currautoupdate{'fields'}{$item}) eq 'ARRAY') {
                       my $change = 0;
                       if (ref($fields{$item}) eq 'ARRAY') {
                           foreach my $type (@{$fields{$item}}) {
                               if (!grep(/^\Q$type\E$/,@{$currautoupdate{'fields'}{$item}})) {
                                   $change = 1;
                                   last;
                               }
                           }
                       }
                       if ($change) {
                           push(@{$changes{'fields'}},$item);
                       }
                   } else {
                     push(@{$changes{'fields'}},$item);                      push(@{$changes{'fields'}},$item);
                 }                  }
             } else {              } else {
Line 2035  sub modify_autoupdate { Line 5101  sub modify_autoupdate {
         if (keys(%changes) > 0) {          if (keys(%changes) > 0) {
             $resulttext = &mt('Changes made:').'<ul>';              $resulttext = &mt('Changes made:').'<ul>';
             foreach my $key (sort(keys(%changes))) {              foreach my $key (sort(keys(%changes))) {
                 if (ref($changes{$key}) eq 'ARRAY') {                  if ($key eq 'lockablenames') {
                       $resulttext .= '<li>';
                       if (@lockablenames) {
                           $usertypes->{'default'} = $othertitle;
                           $resulttext .= &mt("User preference to disable replacement of user's name with institutional data (by auto-update), available for the following affiliations:").' '.
                                      join(', ', map { $usertypes->{$_}; } @lockablenames).'</li>';
                       } else {
                           $resulttext .= &mt("User preference to disable replacement of user's name with institutional data (by auto-update) is unavailable.");
                       }
                       $resulttext .= '</li>';
                   } elsif (ref($changes{$key}) eq 'ARRAY') {
                     foreach my $item (@{$changes{$key}}) {                      foreach my $item (@{$changes{$key}}) {
                         my @newvalues;                          my @newvalues;
                         foreach my $type (@{$fields{$item}}) {                          foreach my $type (@{$fields{$item}}) {
Line 2074  sub modify_autoupdate { Line 5150  sub modify_autoupdate {
     return $resulttext;      return $resulttext;
 }  }
   
   sub modify_autocreate {
       my ($dom,%domconfig) = @_;
       my ($resulttext,%changes,%currautocreate,%newvals,%autocreatehash);
       if (ref($domconfig{'autocreate'}) eq 'HASH') {
           foreach my $key (keys(%{$domconfig{'autocreate'}})) {
               $currautocreate{$key} = $domconfig{'autocreate'}{$key};
           }
       }
       my %title= ( xml => 'Auto-creation of courses in XML course description files',
                    req => 'Auto-creation of validated requests for official courses',
                    xmldc => 'Identity of course creator of courses from XML files',
                  );
       my @types = ('xml','req');
       foreach my $item (@types) {
           $newvals{$item} = $env{'form.autocreate_'.$item};
           $newvals{$item} =~ s/\D//g;
           $newvals{$item} = 0 if ($newvals{$item} eq '');
       }
       $newvals{'xmldc'} = $env{'form.autocreate_xmldc'};
       my %domcoords = &get_active_dcs($dom);
       unless (exists($domcoords{$newvals{'xmldc'}})) {
           $newvals{'xmldc'} = '';
       } 
       %autocreatehash =  (
                           autocreate => { xml => $newvals{'xml'},
                                           req => $newvals{'req'},
                                         }
                          );
       if ($newvals{'xmldc'} ne '') {
           $autocreatehash{'autocreate'}{'xmldc'} = $newvals{'xmldc'};
       }
       my $putresult = &Apache::lonnet::put_dom('configuration',\%autocreatehash,
                                                $dom);
       if ($putresult eq 'ok') {
           my @items = @types;
           if ($newvals{'xml'}) {
               push(@items,'xmldc');
           }
           foreach my $item (@items) {
               if (exists($currautocreate{$item})) {
                   if ($currautocreate{$item} ne $newvals{$item}) {
                       $changes{$item} = 1;
                   }
               } elsif ($newvals{$item}) {
                   $changes{$item} = 1;
               }
           }
           if (keys(%changes) > 0) {
               my @offon = ('off','on'); 
               $resulttext = &mt('Changes made:').'<ul>';
               foreach my $item (@types) {
                   if ($changes{$item}) {
                       my $newtxt = $offon[$newvals{$item}];
                       $resulttext .= '<li>'.&mt("$title{$item} set to [_1]$newtxt [_2]",'<b>','</b>').'</li>';
                   }
               }
               if ($changes{'xmldc'}) {
                   my ($dcname,$dcdom) = split(':',$newvals{'xmldc'});
                   my $newtxt = &Apache::loncommon::plainname($dcname,$dcdom);
                   $resulttext .= '<li>'.&mt("$title{'xmldc'} set to [_1]$newtxt [_2]",'<b>','</b>').'</li>'; 
               }
               $resulttext .= '</ul>';
           } else {
               $resulttext = &mt('No changes made to auto-creation settings');
           }
       } else {
           $resulttext = '<span class="LC_error">'.
               &mt('An error occurred: [_1]',$putresult).'</span>';
       }
       return $resulttext;
   }
   
 sub modify_directorysrch {  sub modify_directorysrch {
     my ($dom,%domconfig) = @_;      my ($dom,%domconfig) = @_;
     my ($resulttext,%changes);      my ($resulttext,%changes);
Line 2094  sub modify_directorysrch { Line 5242  sub modify_directorysrch {
     my @cansearch = &Apache::loncommon::get_env_multiple('form.cansearch');      my @cansearch = &Apache::loncommon::get_env_multiple('form.cansearch');
     my @searchby = &Apache::loncommon::get_env_multiple('form.searchby');      my @searchby = &Apache::loncommon::get_env_multiple('form.searchby');
   
     my ($othertitle,$usertypes,$types) = &sorted_inst_types($dom);      my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom);
     if (keys(%{$usertypes}) == 0) {      if (keys(%{$usertypes}) == 0) {
         @cansearch = ('default');          @cansearch = ('default');
     } else {      } else {
Line 2248  sub modify_directorysrch { Line 5396  sub modify_directorysrch {
     return $resulttext;      return $resulttext;
 }  }
   
 sub modify_user_creation {  sub modify_contacts {
     my ($dom,%domconfig) = @_;      my ($dom,%domconfig) = @_;
     my ($resulttext,%curr_usercreation,%changes);      my ($resulttext,%currsetting,%newsetting,%changes,%contacts_hash);
       if (ref($domconfig{'contacts'}) eq 'HASH') {
           foreach my $key (keys(%{$domconfig{'contacts'}})) {
               $currsetting{$key} = $domconfig{'contacts'}{$key};
           }
       }
       my (%others,%to,%bcc);
       my @contacts = ('supportemail','adminemail');
       my @mailings = ('errormail','packagesmail','helpdeskmail','lonstatusmail',
                       'requestsmail');
       foreach my $type (@mailings) {
           @{$newsetting{$type}} = 
               &Apache::loncommon::get_env_multiple('form.'.$type);
           foreach my $item (@contacts) {
               if (grep(/^\Q$item\E$/,@{$newsetting{$type}})) {
                   $contacts_hash{contacts}{$type}{$item} = 1;
               } else {
                   $contacts_hash{contacts}{$type}{$item} = 0;
               }
           }  
           $others{$type} = $env{'form.'.$type.'_others'};
           $contacts_hash{contacts}{$type}{'others'} = $others{$type};
           if ($type eq 'helpdeskmail') {
               $bcc{$type} = $env{'form.'.$type.'_bcc'};
               $contacts_hash{contacts}{$type}{'bcc'} = $bcc{$type};
           }
       }
       foreach my $item (@contacts) {
           $to{$item} = $env{'form.'.$item};
           $contacts_hash{'contacts'}{$item} = $to{$item};
       }
       if (keys(%currsetting) > 0) {
           foreach my $item (@contacts) {
               if ($to{$item} ne $currsetting{$item}) {
                   $changes{$item} = 1;
               }
           }
           foreach my $type (@mailings) {
               foreach my $item (@contacts) {
                   if (ref($currsetting{$type}) eq 'HASH') {
                       if ($currsetting{$type}{$item} ne $contacts_hash{contacts}{$type}{$item}) {
                           push(@{$changes{$type}},$item);
                       }
                   } else {
                       push(@{$changes{$type}},@{$newsetting{$type}});
                   }
               }
               if ($others{$type} ne $currsetting{$type}{'others'}) {
                   push(@{$changes{$type}},'others');
               }
               if ($type eq 'helpdeskmail') {   
                   if ($bcc{$type} ne $currsetting{$type}{'bcc'}) {
                       push(@{$changes{$type}},'bcc'); 
                   }
               }
           }
       } else {
           my %default;
           $default{'supportemail'} = $Apache::lonnet::perlvar{'lonSupportEMail'};
           $default{'adminemail'} = $Apache::lonnet::perlvar{'lonAdmEMail'};
           $default{'errormail'} = 'adminemail';
           $default{'packagesmail'} = 'adminemail';
           $default{'helpdeskmail'} = 'supportemail';
           $default{'lonstatusmail'} = 'adminemail';
           $default{'requestsmail'} = 'adminemail';
           foreach my $item (@contacts) {
              if ($to{$item} ne $default{$item}) {
                 $changes{$item} = 1;
              } 
           }
           foreach my $type (@mailings) {
               if ((@{$newsetting{$type}} != 1) || ($newsetting{$type}[0] ne $default{$type})) {
                  
                   push(@{$changes{$type}},@{$newsetting{$type}});
               }
               if ($others{$type} ne '') {
                   push(@{$changes{$type}},'others');
               }
               if ($type eq 'helpdeskmail') {
                   if ($bcc{$type} ne '') {
                       push(@{$changes{$type}},'bcc');
                   }
               }
           }
       }
       my $putresult = &Apache::lonnet::put_dom('configuration',\%contacts_hash,
                                                $dom);
       if ($putresult eq 'ok') {
           if (keys(%changes) > 0) {
               my ($titles,$short_titles)  = &contact_titles();
               $resulttext = &mt('Changes made:').'<ul>';
               foreach my $item (@contacts) {
                   if ($changes{$item}) {
                       $resulttext .= '<li>'.$titles->{$item}.
                                       &mt(' set to: ').
                                       '<span class="LC_cusr_emph">'.
                                       $to{$item}.'</span></li>';
                   }
               }
               foreach my $type (@mailings) {
                   if (ref($changes{$type}) eq 'ARRAY') {
                       $resulttext .= '<li>'.$titles->{$type}.': ';
                       my @text;
                       foreach my $item (@{$newsetting{$type}}) {
                           push(@text,$short_titles->{$item});
                       }
                       if ($others{$type} ne '') {
                           push(@text,$others{$type});
                       }
                       $resulttext .= '<span class="LC_cusr_emph">'.
                                      join(', ',@text).'</span>';
                       if ($type eq 'helpdeskmail') {
                           if ($bcc{$type} ne '') {
                               $resulttext .= '&nbsp;'.&mt('with Bcc to').': <span class="LC_cusr_emph">'.$bcc{$type}.'</span>';
                           }
                       }
                       $resulttext .= '</li>';
                   }
               }
               $resulttext .= '</ul>';
           } else {
               $resulttext = &mt('No changes made to contact information');
           }
       } else {
           $resulttext = '<span class="LC_error">'.
               &mt('An error occurred: [_1].',$putresult).'</span>';
       }
       return $resulttext;
   }
   
   sub modify_usercreation {
       my ($dom,%domconfig) = @_;
       my ($resulttext,%curr_usercreation,%changes,%authallowed,%cancreate);
       my $warningmsg;
     if (ref($domconfig{'usercreation'}) eq 'HASH') {      if (ref($domconfig{'usercreation'}) eq 'HASH') {
         foreach my $key (keys(%{$domconfig{'usercreation'}})) {          foreach my $key (keys(%{$domconfig{'usercreation'}})) {
             $curr_usercreation{$key} = $domconfig{'usercreation'}{$key};              $curr_usercreation{$key} = $domconfig{'usercreation'}{$key};
         }          }
     }      }
     my %title = &Apache::lonlocal::texthash (  
                    author => 'adding co-authors/assistant authors',  
                    course => 'adding users to a course',  
                 );  
     my @username_rule = &Apache::loncommon::get_env_multiple('form.username_rule');      my @username_rule = &Apache::loncommon::get_env_multiple('form.username_rule');
     my @cancreate = &Apache::loncommon::get_env_multiple('form.can_createuser');      my @id_rule = &Apache::loncommon::get_env_multiple('form.id_rule');
     if (ref($curr_usercreation{'cancreate'}) eq 'ARRAY') {      my @email_rule = &Apache::loncommon::get_env_multiple('form.email_rule');
         foreach my $type (@{$curr_usercreation{'cancreate'}}) {      my @contexts = ('author','course','requestcrs','selfcreate');
             if (!grep(/^\Q$type\E$/,@cancreate)) {      foreach my $item(@contexts) {
                 push(@{$changes{'cancreate'}},$type);          if ($item eq 'selfcreate') {
               @{$cancreate{$item}} = &Apache::loncommon::get_env_multiple('form.can_createuser_'.$item);
               my %domdefaults = &Apache::lonnet::get_domain_defaults($dom);
               if (!((($domdefaults{'auth_def'} =~/^krb/) && ($domdefaults{'auth_arg_def'} ne '')) || ($domdefaults{'auth_def'} eq 'localauth'))) {
                   if (ref($cancreate{$item}) eq 'ARRAY') { 
                       if (grep(/^login$/,@{$cancreate{$item}})) {
                           $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.').' '.&mt('You need to set the default authentication type to Kerberos 4 or 5 (with a Kerberos domain specified), or to Local authentication, if the localauth module has been customized in your domain to authenticate institutional logins.');   
                       }
                   }
             }              }
           } else {
               $cancreate{$item} = $env{'form.can_createuser_'.$item};
         }          }
         foreach my $type (@cancreate) {      }
             if (!grep(/^\Q$type\E$/,@{$curr_usercreation{'cancreate'}})) {      my ($othertitle,$usertypes,$types) = 
                 push(@{$changes{'cancreate'}},$type);          &Apache::loncommon::sorted_inst_types($dom);
       if (ref($types) eq 'ARRAY') {
           if (@{$types} > 0) {
               @{$cancreate{'statustocreate'}} = 
                   &Apache::loncommon::get_env_multiple('form.statustocreate');
           } else {
               @{$cancreate{'statustocreate'}} = ();
           }
           push(@contexts,'statustocreate');
       }
       if (ref($curr_usercreation{'cancreate'}) eq 'HASH') {
           foreach my $item (@contexts) {
               if (($item eq 'selfcreate') || ($item eq 'statustocreate')) {
                   if (ref($curr_usercreation{'cancreate'}{$item}) eq 'ARRAY') {
                       foreach my $curr (@{$curr_usercreation{'cancreate'}{$item}}) {
                           if (ref($cancreate{$item}) eq 'ARRAY') {
                               if (!grep(/^$curr$/,@{$cancreate{$item}})) {
                                   if (!grep(/^$item$/,@{$changes{'cancreate'}})) {
                                       push(@{$changes{'cancreate'}},$item);
                                   }
                               }
                           }
                       }
                   } else {
                       if ($curr_usercreation{'cancreate'}{$item} eq '') {
                           if (@{$cancreate{$item}} > 0) {
                               if (!grep(/^$item$/,@{$changes{'cancreate'}})) {
                                   push(@{$changes{'cancreate'}},$item);
                               }
                           }
                       } else {
                           if ($curr_usercreation{'cancreate'}{$item} eq 'any') {
                               if (@{$cancreate{$item}} < 3) {
                                   if (!grep(/^$item$/,@{$changes{'cancreate'}})) {
                                       push(@{$changes{'cancreate'}},$item);
                                   }
                               }
                           } elsif ($curr_usercreation{'cancreate'}{$item} eq 'none') {
                               if (@{$cancreate{$item}} > 0) {
                                   if (!grep(/^$item$/,@{$changes{'cancreate'}})) {
                                       push(@{$changes{'cancreate'}},$item);
                                   }
                               }
                           } elsif (!grep(/^$curr_usercreation{'cancreate'}{$item}$/,@{$cancreate{$item}})) {
                               if (!grep(/^$item$/,@{$changes{'cancreate'}})) {
                                   push(@{$changes{'cancreate'}},$item);
                               }
                           }
                       }
                   }
                   if (!grep(/^$item$/,@{$changes{'cancreate'}})) {
                       foreach my $type (@{$cancreate{$item}}) {
                           if (ref($curr_usercreation{'cancreate'}{$item}) eq 'ARRAY') {
                               if (!grep(/^$type$/,@{$curr_usercreation{'cancreate'}{$item}})) {
                                   if (!grep(/^$item$/,@{$changes{'cancreate'}})) {
                                       push(@{$changes{'cancreate'}},$item);
                                   }
                               }
                           } elsif (($curr_usercreation{'cancreate'}{$item} ne 'any') &&
                                    ($curr_usercreation{'cancreate'}{$item} ne 'none')) {
                               if ($curr_usercreation{'cancreate'}{$item} ne $type) {
                                   if (!grep(/^$item$/,@{$changes{'cancreate'}})) {
                                       push(@{$changes{'cancreate'}},$item);
                                   }
                               }
                           }
                       }
                   }
               } else {
                   if ($curr_usercreation{'cancreate'}{$item} ne $cancreate{$item}) {
                       push(@{$changes{'cancreate'}},$item);
                   }
               }
           }
       } elsif (ref($curr_usercreation{'cancreate'}) eq 'ARRAY') {
           foreach my $item (@contexts) {
               if (!grep(/^\Q$item\E$/,@{$curr_usercreation{'cancreate'}})) {
                   if ($cancreate{$item} ne 'any') {
                       push(@{$changes{'cancreate'}},$item);
                   }
               } else {
                   if ($cancreate{$item} ne 'none') {
                       push(@{$changes{'cancreate'}},$item);
                   }
             }              }
         }          }
     } else {      } else {
         push(@{$changes{'cancreate'}},@cancreate);          foreach my $item (@contexts)  {
               push(@{$changes{'cancreate'}},$item);
           }
     }      }
   
     if (ref($curr_usercreation{'username_rule'}) eq 'ARRAY') {      if (ref($curr_usercreation{'username_rule'}) eq 'ARRAY') {
         foreach my $type (@{$curr_usercreation{'username_rule'}}) {          foreach my $type (@{$curr_usercreation{'username_rule'}}) {
             if (!grep(/^\Q$type\E$/,@username_rule)) {              if (!grep(/^\Q$type\E$/,@username_rule)) {
Line 2291  sub modify_user_creation { Line 5664  sub modify_user_creation {
         push(@{$changes{'username_rule'}},@username_rule);          push(@{$changes{'username_rule'}},@username_rule);
     }      }
   
       if (ref($curr_usercreation{'id_rule'}) eq 'ARRAY') {
           foreach my $type (@{$curr_usercreation{'id_rule'}}) {
               if (!grep(/^\Q$type\E$/,@id_rule)) {
                   push(@{$changes{'id_rule'}},$type);
               }
           }
           foreach my $type (@id_rule) {
               if (!grep(/^\Q$type\E$/,@{$curr_usercreation{'id_rule'}})) {
                   push(@{$changes{'id_rule'}},$type);
               }
           }
       } else {
           push(@{$changes{'id_rule'}},@id_rule);
       }
   
       if (ref($curr_usercreation{'email_rule'}) eq 'ARRAY') {
           foreach my $type (@{$curr_usercreation{'email_rule'}}) {
               if (!grep(/^\Q$type\E$/,@email_rule)) {
                   push(@{$changes{'email_rule'}},$type);
               }
           }
           foreach my $type (@email_rule) {
               if (!grep(/^\Q$type\E$/,@{$curr_usercreation{'email_rule'}})) {
                   push(@{$changes{'email_rule'}},$type);
               }
           }
       } else {
           push(@{$changes{'email_rule'}},@email_rule);
       }
   
       my @authen_contexts = ('author','course','domain');
       my @authtypes = ('int','krb4','krb5','loc');
       my %authhash;
       foreach my $item (@authen_contexts) {
           my @authallowed =  &Apache::loncommon::get_env_multiple('form.'.$item.'_auth');
           foreach my $auth (@authtypes) {
               if (grep(/^\Q$auth\E$/,@authallowed)) {
                   $authhash{$item}{$auth} = 1;
               } else {
                   $authhash{$item}{$auth} = 0;
               }
           }
       }
       if (ref($curr_usercreation{'authtypes'}) eq 'HASH') {
           foreach my $item (@authen_contexts) {
               if (ref($curr_usercreation{'authtypes'}{$item}) eq 'HASH') {
                   foreach my $auth (@authtypes) {
                       if ($authhash{$item}{$auth} ne $curr_usercreation{'authtypes'}{$item}{$auth}) {
                           push(@{$changes{'authtypes'}},$item);
                           last;
                       }
                   }
               }
           }
       } else {
           foreach my $item (@authen_contexts) {
               push(@{$changes{'authtypes'}},$item);
           }
       }
   
     my %usercreation_hash =  (      my %usercreation_hash =  (
             usercreation => {               usercreation => {
                               cancreate     => \@cancreate,                                cancreate     => \%cancreate,
                               username_rule => \@username_rule,                                username_rule => \@username_rule,
                                 id_rule       => \@id_rule,
                                 email_rule    => \@email_rule,
                                 authtypes     => \%authhash,
                             }                              }
             );              );
   
     my $putresult = &Apache::lonnet::put_dom('configuration',\%usercreation_hash,      my $putresult = &Apache::lonnet::put_dom('configuration',\%usercreation_hash,
                                              $dom);                                               $dom);
   
       my %selfcreatetypes = (
                                sso   => 'users authenticated by institutional single sign on',
                                login => 'users authenticated by institutional log-in',
                                email => 'users who provide a valid e-mail address for use as the username',
                             );
     if ($putresult eq 'ok') {      if ($putresult eq 'ok') {
         if (keys(%changes) > 0) {          if (keys(%changes) > 0) {
             $resulttext = &mt('Changes made:').'<ul>';              $resulttext = &mt('Changes made:').'<ul>';
             my $chgtext;  
             if (ref($changes{'cancreate'}) eq 'ARRAY') {              if (ref($changes{'cancreate'}) eq 'ARRAY') {
                 my $chgtext = '<ul>';                  my %lt = &usercreation_types();
                 foreach my $type (@cancreate) {                  foreach my $type (@{$changes{'cancreate'}}) {
                     $chgtext .= '<li>'.$title{$type}.'</li>';                      my $chgtext;
                 }                      unless ($type eq 'statustocreate') {
                 $chgtext .= '</ul>';                          $chgtext = $lt{$type}.', ';
                 if (@cancreate > 0) {                      }
                     $resulttext .= '<li>'.&mt('Creation of new users is permitted by a Domain Coordinator, and also by other users when: ').$chgtext.'</li>';                      if ($type eq 'selfcreate') {
                 } else {                          if (@{$cancreate{$type}} == 0) {
                     $resulttext .= '<li>'.&mt("Creation of new users is now only allowed when the user's role is Domain Coordinator.").'</li>';                              $chgtext .= &mt('creation of a new user account is not permitted.');
                           } else {
                               $chgtext .= &mt('creation of a new account is permitted for:').'<ul>';
                               foreach my $case (@{$cancreate{$type}}) {
                                   $chgtext .= '<li>'.$selfcreatetypes{$case}.'</li>';
                               }
                               $chgtext .= '</ul>';
                               if (ref($cancreate{$type}) eq 'ARRAY') {
                                   if (grep(/^(login|sso)$/,@{$cancreate{$type}})) {
                                       if (ref($cancreate{'statustocreate'}) eq 'ARRAY') {
                                           if (@{$cancreate{'statustocreate'}} == 0) {
                                               $chgtext .= '<br /><span class="LC_warning">'.&mt("However, no institutional affiliations (including 'other') are currently permitted to create accounts.").'</span>';
                                           }
                                       }
                                   }
                               }
                           }
                       } elsif ($type eq 'statustocreate') {
                           if ((ref($cancreate{'selfcreate'}) eq 'ARRAY') &&
                               (ref($cancreate{'statustocreate'}) eq 'ARRAY')) {
                               if (@{$cancreate{'selfcreate'}} > 0) {
                                   if (@{$cancreate{'statustocreate'}} == 0) {
   
                                       $chgtext .= &mt("Institutional affiliations permitted to create accounts set to 'None'.");
                                       if (!grep(/^email$/,@{$cancreate{'selfcreate'}})) {
                                           $chgtext .= '<br /><span class="LC_warning">'.&mt("However, no institutional affiliations (including 'other') are currently permitted to create accounts.").'</span>';
                                       } 
                                   } elsif (ref($usertypes) eq 'HASH') {
                                       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):');
                                       } else {
                                           $chgtext .= &mt('Institutional affiliations permitted to create accounts with institutional authentication were set as follows:');
                                       }
                                       $chgtext .= '<ul>';
                                       foreach my $case (@{$cancreate{$type}}) {
                                           if ($case eq 'default') {
                                               $chgtext .= '<li>'.$othertitle.'</li>';
                                           } else {
                                               $chgtext .= '<li>'.$usertypes->{$case}.'</li>';
                                           }
                                       }
                                       $chgtext .= '</ul>';
                                       if (!grep(/^(login|sso)$/,@{$cancreate{'selfcreate'}})) {
                                           $chgtext .= '<br /><span class="LC_warning">'.&mt('However, users authenticated by institutional login/single sign on are not currently permitted to create accounts.').'</span>';
                                       }
                                   }
                               } else {
                                   if (@{$cancreate{$type}} == 0) {
                                       $chgtext .= &mt("Institutional affiliations permitted to create accounts were set to 'none'.");
                                   } else {
                                       $chgtext .= &mt('Although institutional affiliations permitted to create accounts were changed, self creation of accounts is not currently permitted for any authentication types.');
                                   }
                               }
                           }
                       } else {
                           if ($cancreate{$type} eq 'none') {
                               $chgtext .= &mt('creation of new users is not permitted, except by a Domain Coordinator.');
                           } elsif ($cancreate{$type} eq 'any') {
                               $chgtext .= &mt('creation of new users is permitted for both institutional and non-institutional usernames.');
                           } elsif ($cancreate{$type} eq 'official') {
                               $chgtext .= &mt('creation of new users is only permitted for institutional usernames.');
                           } elsif ($cancreate{$type} eq 'unofficial') {
                               $chgtext .= &mt('creation of new users is only permitted for non-institutional usernames.');
                           }
                       }
                       $resulttext .= '<li>'.$chgtext.'</li>';
                 }                  }
             }              }
             if (ref($changes{'username_rule'}) eq 'ARRAY') {              if (ref($changes{'username_rule'}) eq 'ARRAY') {
                 my ($rules,$ruleorder) = &Apache::lonnet::inst_userrules($dom);                  my ($rules,$ruleorder) = 
                       &Apache::lonnet::inst_userrules($dom,'username');
                 my $chgtext = '<ul>';                  my $chgtext = '<ul>';
                 foreach my $type (@username_rule) {                  foreach my $type (@username_rule) {
                     if (ref($rules->{$type}) eq 'HASH') {                      if (ref($rules->{$type}) eq 'HASH') {
Line 2328  sub modify_user_creation { Line 5835  sub modify_user_creation {
                 if (@username_rule > 0) {                  if (@username_rule > 0) {
                     $resulttext .= '<li>'.&mt('Usernames with the following formats are restricted to verified users in the institutional directory: ').$chgtext.'</li>';                           $resulttext .= '<li>'.&mt('Usernames with the following formats are restricted to verified users in the institutional directory: ').$chgtext.'</li>';     
                 } else {                  } else {
                     $resulttext .= '<li>'.&mt('There are now no username formats currenty restricted to verified users in the institutional directory.').'</li>';                       $resulttext .= '<li>'.&mt('There are now no username formats restricted to verified users in the institutional directory.').'</li>'; 
                   }
               }
               if (ref($changes{'id_rule'}) eq 'ARRAY') {
                   my ($idrules,$idruleorder) = 
                       &Apache::lonnet::inst_userrules($dom,'id');
                   my $chgtext = '<ul>';
                   foreach my $type (@id_rule) {
                       if (ref($idrules->{$type}) eq 'HASH') {
                           $chgtext .= '<li>'.$idrules->{$type}{'name'}.'</li>';
                       }
                   }
                   $chgtext .= '</ul>';
                   if (@id_rule > 0) {
                       $resulttext .= '<li>'.&mt('IDs with the following formats are restricted to verified users in the institutional directory: ').$chgtext.'</li>';
                   } else {
                       $resulttext .= '<li>'.&mt('There are now no ID formats restricted to verified users in the institutional directory.').'</li>';
                   }
               }
               if (ref($changes{'email_rule'}) eq 'ARRAY') {
                   my ($emailrules,$emailruleorder) =
                       &Apache::lonnet::inst_userrules($dom,'email');
                   my $chgtext = '<ul>';
                   foreach my $type (@email_rule) {
                       if (ref($emailrules->{$type}) eq 'HASH') {
                           $chgtext .= '<li>'.$emailrules->{$type}{'name'}.'</li>';
                       }
                   }
                   $chgtext .= '</ul>';
                   if (@email_rule > 0) {
                       $resulttext .= '<li>'.&mt('Accounts may not be created by users self-enrolling with e-mail addresses of the following types: ').$chgtext.'</li>';
                   } else {
                       $resulttext .= '<li>'.&mt('There are now no restrictions on e-mail addresses which may be used as a username when self-enrolling.').'</li>';
                   }
               }
   
               my %authname = &authtype_names();
               my %context_title = &context_names();
               if (ref($changes{'authtypes'}) eq 'ARRAY') {
                   my $chgtext = '<ul>';
                   foreach my $type (@{$changes{'authtypes'}}) {
                       my @allowed;
                       $chgtext .= '<li><span class="LC_cusr_emph">'.$context_title{$type}.'</span> - '.&mt('assignable authentication types: ');
                       foreach my $auth (@authtypes) {
                           if ($authhash{$type}{$auth}) {
                               push(@allowed,$authname{$auth});
                           }
                       }
                       if (@allowed > 0) {
                           $chgtext .= join(', ',@allowed).'</li>';
                       } else {
                           $chgtext .= &mt('none').'</li>';
                       }
                   }
                   $chgtext .= '</ul>';
                   $resulttext .= '<li>'.&mt('Authentication types available for assignment to new users').'<br />'.$chgtext;
                   $resulttext .= '</li>';
               }
               $resulttext .= '</ul>';
           } else {
               $resulttext = &mt('No changes made to user creation settings');
           }
       } else {
           $resulttext = '<span class="LC_error">'.
               &mt('An error occurred: [_1]',$putresult).'</span>';
       }
       if ($warningmsg ne '') {
           $resulttext .= '<br /><span class="LC_warning">'.$warningmsg.'</span><br />';
       }
       return $resulttext;
   }
   
   sub modify_usermodification {
       my ($dom,%domconfig) = @_;
       my ($resulttext,%curr_usermodification,%changes);
       if (ref($domconfig{'usermodification'}) eq 'HASH') {
           foreach my $key (keys(%{$domconfig{'usermodification'}})) {
               $curr_usermodification{$key} = $domconfig{'usermodification'}{$key};
           }
       }
       my @contexts = ('author','course','selfcreate');
       my %context_title = (
                              author => 'In author context',
                              course => 'In course context',
                              selfcreate => 'When self creating account', 
                           );
       my @fields = ('lastname','firstname','middlename','generation',
                     'permanentemail','id');
       my %roles = (
                     author => ['ca','aa'],
                     course => ['st','ep','ta','in','cr'],
                   );
       my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom);
       if (ref($types) eq 'ARRAY') {
           push(@{$types},'default');
           $usertypes->{'default'} = $othertitle;
       }
       $roles{'selfcreate'} = $types;  
       my %fieldtitles = &Apache::loncommon::personal_data_fieldtitles();
       my %modifyhash;
       foreach my $context (@contexts) {
           foreach my $role (@{$roles{$context}}) {
               my @modifiable =  &Apache::loncommon::get_env_multiple('form.canmodify_'.$role);
               foreach my $item (@fields) {
                   if (grep(/^\Q$item\E$/,@modifiable)) {
                       $modifyhash{$context}{$role}{$item} = 1;
                   } else {
                       $modifyhash{$context}{$role}{$item} = 0;
                   }
               }
           }
           if (ref($curr_usermodification{$context}) eq 'HASH') {
               foreach my $role (@{$roles{$context}}) {
                   if (ref($curr_usermodification{$context}{$role}) eq 'HASH') {
                       foreach my $field (@fields) {
                           if ($modifyhash{$context}{$role}{$field} ne 
                                   $curr_usermodification{$context}{$role}{$field}) {
                               push(@{$changes{$context}},$role);
                               last;
                           }
                       }
                   }
               }
           } else {
               foreach my $context (@contexts) {
                   foreach my $role (@{$roles{$context}}) {
                       push(@{$changes{$context}},$role);
                   }
               }
           }
       }
       my %usermodification_hash =  (
                                      usermodification => \%modifyhash,
                                    );
       my $putresult = &Apache::lonnet::put_dom('configuration',
                                                \%usermodification_hash,$dom);
       if ($putresult eq 'ok') {
           if (keys(%changes) > 0) {
               $resulttext = &mt('Changes made: ').'<ul>';
               foreach my $context (@contexts) {
                   if (ref($changes{$context}) eq 'ARRAY') {
                       $resulttext .= '<li>'.$context_title{$context}.':<ul>';
                       if (ref($changes{$context}) eq 'ARRAY') {
                           foreach my $role (@{$changes{$context}}) {
                               my $rolename;
                               if ($context eq 'selfcreate') {
                                   $rolename = $role;
                                   if (ref($usertypes) eq 'HASH') {
                                       if ($usertypes->{$role} ne '') {
                                           $rolename = $usertypes->{$role};
                                       }
                                   }
                               } else {
                                   if ($role eq 'cr') {
                                       $rolename = &mt('Custom');
                                   } else {
                                       $rolename = &Apache::lonnet::plaintext($role);
                                   }
                               }
                               my @modifiable;
                               if ($context eq 'selfcreate') {
                                   $resulttext .= '<li><span class="LC_cusr_emph">'.&mt('Self-creation of account by users with status: [_1]',$rolename).'</span> - '.&mt('modifiable fields (if institutional data blank): ');
                               } else {
                                   $resulttext .= '<li><span class="LC_cusr_emph">'.&mt('Target user with [_1] role',$rolename).'</span> - '.&mt('modifiable fields: ');
                               }
                               foreach my $field (@fields) {
                                   if ($modifyhash{$context}{$role}{$field}) {
                                       push(@modifiable,$fieldtitles{$field});
                                   }
                               }
                               if (@modifiable > 0) {
                                   $resulttext .= join(', ',@modifiable);
                               } else {
                                   $resulttext .= &mt('none'); 
                               }
                               $resulttext .= '</li>';
                           }
                           $resulttext .= '</ul></li>';
                       }
                 }                  }
             }              }
             $resulttext .= '</ul>';              $resulttext .= '</ul>';
         } else {          } else {
             $resulttext = &mt('No changes made to log-in page settings');              $resulttext = &mt('No changes made to user modification settings');
           }
       } else {
           $resulttext = '<span class="LC_error">'.
               &mt('An error occurred: [_1]',$putresult).'</span>';
       }
       return $resulttext;
   }
   
   sub modify_defaults {
       my ($dom,$r) = @_;
       my ($resulttext,$mailmsgtxt,%newvalues,%changes,@errors);
       my %domdefaults = &Apache::lonnet::get_domain_defaults($dom);
       my @items = ('auth_def','auth_arg_def','lang_def','timezone_def','datelocale_def','portal_def');
       my @authtypes = ('internal','krb4','krb5','localauth');
       foreach my $item (@items) {
           $newvalues{$item} = $env{'form.'.$item};
           if ($item eq 'auth_def') {
               if ($newvalues{$item} ne '') {
                   if (!grep(/^\Q$newvalues{$item}\E$/,@authtypes)) {
                       push(@errors,$item);
                   }
               }
           } elsif ($item eq 'lang_def') {
               if ($newvalues{$item} ne '') {
                   if ($newvalues{$item} =~ /^(\w+)/) {
                       my $langcode = $1;
                       if ($langcode ne 'x_chef') {
                           if (code2language($langcode) eq '') {
                               push(@errors,$item);
                           }
                       }
                   } else {
                       push(@errors,$item);
                   }
               }
           } elsif ($item eq 'timezone_def') {
               if ($newvalues{$item} ne '') {
                   if (!DateTime::TimeZone->is_valid_name($newvalues{$item})) {
                       push(@errors,$item);   
                   }
               }
           } elsif ($item eq 'datelocale_def') {
               if ($newvalues{$item} ne '') {
                   my @datelocale_ids = DateTime::Locale->ids();
                   if (!grep(/^\Q$newvalues{$item}\E$/,@datelocale_ids)) {
                       push(@errors,$item);
                   }
               }
           } elsif ($item eq 'portal_def') {
               if ($newvalues{$item} ne '') {
                   unless ($newvalues{$item} =~ /^https?\:\/\/(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z]|[A-Za-z][A-Za-z0-9\-]*[A-Za-z0-9])\/?$/) {
                       push(@errors,$item);
                   }
               }
           }
           if (grep(/^\Q$item\E$/,@errors)) {
               $newvalues{$item} = $domdefaults{$item};
           } elsif ($domdefaults{$item} ne $newvalues{$item}) {
               $changes{$item} = 1;
           }
           $domdefaults{$item} = $newvalues{$item};
       }
       my %defaults_hash = (
                            defaults => \%newvalues,
                           );
       my $title = &defaults_titles();
       my $putresult = &Apache::lonnet::put_dom('configuration',\%defaults_hash,
                                                $dom);
       if ($putresult eq 'ok') {
           if (keys(%changes) > 0) {
               $resulttext = &mt('Changes made:').'<ul>';
               my $version = $r->dir_config('lonVersion');
               my $mailmsgtext = "Changes made to domain settings in a LON-CAPA installation - domain: $dom (running version: $version) - dns_domain.tab needs to be updated with the following changes, to support legacy 2.4, 2.5 and 2.6 versions of LON-CAPA.\n\n";
               foreach my $item (sort(keys(%changes))) {
                   my $value = $env{'form.'.$item};
                   if ($value eq '') {
                       $value = &mt('none');
                   } elsif ($item eq 'auth_def') {
                       my %authnames = &authtype_names();
                       my %shortauth = (
                                internal => 'int',
                                krb4 => 'krb4',
                                krb5 => 'krb5',
                                localauth  => 'loc',
                       );
                       $value = $authnames{$shortauth{$value}};
                   }
                   $resulttext .= '<li>'.&mt('[_1] set to "[_2]"',$title->{$item},$value).'</li>';
                   $mailmsgtext .= "$title->{$item} set to $value\n";  
               }
               $resulttext .= '</ul>';
               $mailmsgtext .= "\n";
               my $cachetime = 24*60*60;
               &Apache::lonnet::do_cache_new('domdefaults',$dom,\%domdefaults,$cachetime);
               if ($changes{'auth_def'} || $changes{'auth_arg_def'} || $changes{'lang_def'} || $changes{'datelocale_def'}) {
                   my $sysmail = $r->dir_config('lonSysEMail');
                   &Apache::lonmsg::sendemail($sysmail,"LON-CAPA Domain Settings Change - $dom",$mailmsgtext);
               }
           } else {
               $resulttext = &mt('No changes made to default authentication/language/timezone settings');
           }
       } else {
           $resulttext = '<span class="LC_error">'.
               &mt('An error occurred: [_1]',$putresult).'</span>';
       }
       if (@errors > 0) {
           $resulttext .= '<br />'.&mt('The following were left unchanged because the values entered were invalid:');
           foreach my $item (@errors) {
               $resulttext .= ' "'.$title->{$item}.'",';
           }
           $resulttext =~ s/,$//;
       }
       return $resulttext;
   }
   
   sub modify_scantron {
       my ($r,$dom,$confname,%domconfig) = @_;
       my ($resulttext,%confhash,%changes,$errors);
       my $custom = 'custom.tab';
       my $default = 'default.tab';
       my $servadm = $r->dir_config('lonAdmEMail');
       my ($configuserok,$author_ok,$switchserver) = 
           &config_check($dom,$confname,$servadm);
       if ($env{'form.scantronformat.filename'} ne '') {
           my $error;
           if ($configuserok eq 'ok') {
               if ($switchserver) {
                   $error = &mt("Upload of bubblesheet format file is not permitted to this server: [_1]",$switchserver);
               } else {
                   if ($author_ok eq 'ok') {
                       my ($result,$scantronurl) =
                           &publishlogo($r,'upload','scantronformat',$dom,
                                        $confname,'scantron','','',$custom);
                       if ($result eq 'ok') {
                           $confhash{'scantron'}{'scantronformat'} = $scantronurl;
                           $changes{'scantronformat'} = 1;
                       } else {
                           $error = &mt("Upload of [_1] failed because an error occurred publishing the file in RES space. Error was: [_2].",$custom,$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].",$custom,$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].",$custom,$confname,$dom,$configuserok);
           }
           if ($error) {
               &Apache::lonnet::logthis($error);
               $errors .= '<li><span class="LC_error">'.$error.'</span></li>';
           }
       }
       if (ref($domconfig{'scantron'}) eq 'HASH') {
           if ($domconfig{'scantron'}{'scantronformat'} ne '') {
               if ($env{'form.scantronformat_del'}) {
                   $confhash{'scantron'}{'scantronformat'} = '';
                   $changes{'scantronformat'} = 1;
               }
           }
       }
       if (keys(%confhash) > 0) {
           my $putresult = &Apache::lonnet::put_dom('configuration',\%confhash,
                                                    $dom);
           if ($putresult eq 'ok') {
               if (keys(%changes) > 0) {
                   if (ref($confhash{'scantron'}) eq 'HASH') {
                       $resulttext = &mt('Changes made:').'<ul>';
                       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>';
                       } else {
                           $resulttext .= '<li>'.&mt('Custom bubblesheet format file ([_1]) uploaded for use with courses in this domain.',$custom).'</li>';
                       }
                       $resulttext .= '</ul>';
                   } else {
                       $resulttext = &mt('Changes made to bubblesheet format file.');
                   }
                   $resulttext .= '</ul>';
                   &Apache::loncommon::devalidate_domconfig_cache($dom);
               } else {
                   $resulttext = &mt('No changes made to bubblesheet format file');
               }
           } else {
               $resulttext = '<span class="LC_error">'.
                   &mt('An error occurred: [_1]',$putresult).'</span>';
           }
       } else {
           $resulttext = &mt('No changes made to bubblesheet format file'); 
       }
       if ($errors) {
           $resulttext .= &mt('The following errors occurred: ').'<ul>'.
                          $errors.'</ul>';
       }
       return $resulttext;
   }
   
   sub modify_coursecategories {
       my ($dom,%domconfig) = @_;
       my ($resulttext,%deletions,%reorderings,%needreordering,%adds,%changes,$errors,
           $cathash);
       my @deletecategory = &Apache::loncommon::get_env_multiple('form.deletecategory');
       if (ref($domconfig{'coursecategories'}) eq 'HASH') {
           $cathash = $domconfig{'coursecategories'}{'cats'};
           if ($domconfig{'coursecategories'}{'togglecats'} ne $env{'form.togglecats'}) {
               $changes{'togglecats'} = 1;
               $domconfig{'coursecategories'}{'togglecats'} = $env{'form.togglecats'};
           }
           if ($domconfig{'coursecategories'}{'categorize'} ne $env{'form.categorize'}) {
               $changes{'categorize'} = 1;
               $domconfig{'coursecategories'}{'categorize'} = $env{'form.categorize'};
           }
           if ($domconfig{'coursecategories'}{'togglecatscomm'} ne $env{'form.togglecatscomm'}) {
               $changes{'togglecatscomm'} = 1;
               $domconfig{'coursecategories'}{'togglecatscomm'} = $env{'form.togglecatscomm'};
           }
           if ($domconfig{'coursecategories'}{'categorizecomm'} ne $env{'form.categorizecomm'}) {
               $changes{'categorizecomm'} = 1;
               $domconfig{'coursecategories'}{'categorizecomm'} = $env{'form.categorizecomm'};
           }
       } else {
           $changes{'togglecats'} = 1;
           $changes{'categorize'} = 1;
           $changes{'togglecatscomm'} = 1;
           $changes{'categorizecomm'} = 1;
           $domconfig{'coursecategories'} = {
                                                togglecats => $env{'form.togglecats'},
                                                categorize => $env{'form.categorize'},
                                                togglecatscomm => $env{'form.togglecatscomm'},
                                                categorizecomm => $env{'form.categorizecomm'},
                                            };
       }
       if (ref($cathash) eq 'HASH') {
           if (($domconfig{'coursecategories'}{'cats'}{'instcode::0'} ne '')  && ($env{'form.instcode'} == 0)) {
               push (@deletecategory,'instcode::0');
           }
           if (($domconfig{'coursecategories'}{'cats'}{'communities::0'} ne '')  && ($env{'form.communities'} == 0)) {
               push(@deletecategory,'communities::0');
           }
       }
       my (@predelcats,@predeltrails,%predelallitems,%sort_by_deltrail);
       if (ref($cathash) eq 'HASH') {
           if (@deletecategory > 0) {
               #FIXME Need to remove category from all courses using a deleted category 
               &Apache::loncommon::extract_categories($cathash,\@predelcats,\@predeltrails,\%predelallitems);
               foreach my $item (@deletecategory) {
                   if ($domconfig{'coursecategories'}{'cats'}{$item} ne '') {
                       delete($domconfig{'coursecategories'}{'cats'}{$item});
                       $deletions{$item} = 1;
                       &recurse_cat_deletes($item,$cathash,\%deletions);
                   }
               }
           }
           foreach my $item (keys(%{$cathash})) {
               my ($cat,$container,$depth) = map { &unescape($_); } split(/:/,$item);
               if ($cathash->{$item} ne $env{'form.'.$item}) {
                   $reorderings{$item} = 1;
                   $domconfig{'coursecategories'}{'cats'}{$item} = $env{'form.'.$item};
               }
               if ($env{'form.addcategory_name_'.$item} ne '') {
                   my $newcat = $env{'form.addcategory_name_'.$item};
                   my $newdepth = $depth+1;
                   my $newitem = &escape($newcat).':'.&escape($cat).':'.$newdepth;
                   $domconfig{'coursecategories'}{'cats'}{$newitem} = $env{'form.addcategory_pos_'.$item};
                   $adds{$newitem} = 1; 
               }
               if ($env{'form.subcat_'.$item} ne '') {
                   my $newcat = $env{'form.subcat_'.$item};
                   my $newdepth = $depth+1;
                   my $newitem = &escape($newcat).':'.&escape($cat).':'.$newdepth;
                   $domconfig{'coursecategories'}{'cats'}{$newitem} = 0;
                   $adds{$newitem} = 1;
               }
           }
       }
       if ($env{'form.instcode'} eq '1') {
           if (ref($cathash) eq 'HASH') {
               my $newitem = 'instcode::0';
               if ($cathash->{$newitem} eq '') {  
                   $domconfig{'coursecategories'}{'cats'}{$newitem} = $env{'form.instcode_pos'};
                   $adds{$newitem} = 1;
               }
           } else {
               my $newitem = 'instcode::0';
               $domconfig{'coursecategories'}{'cats'}{$newitem} = $env{'form.instcode_pos'};
               $adds{$newitem} = 1;
           }
       }
       if ($env{'form.communities'} eq '1') {
           if (ref($cathash) eq 'HASH') {
               my $newitem = 'communities::0';
               if ($cathash->{$newitem} eq '') {
                   $domconfig{'coursecategories'}{'cats'}{$newitem} = $env{'form.communities_pos'};
                   $adds{$newitem} = 1;
               }
           } else {
               my $newitem = 'communities::0';
               $domconfig{'coursecategories'}{'cats'}{$newitem} = $env{'form.communities_pos'};
               $adds{$newitem} = 1;
           }
       }
       if ($env{'form.addcategory_name'} ne '') {
           if (($env{'form.addcategory_name'} ne 'instcode') &&
               ($env{'form.addcategory_name'} ne 'communities')) {
               my $newitem = &escape($env{'form.addcategory_name'}).'::0';
               $domconfig{'coursecategories'}{'cats'}{$newitem} = $env{'form.addcategory_pos'};
               $adds{$newitem} = 1;
           }
       }
       my $putresult;
       if ((keys(%deletions) > 0) || (keys(%reorderings) > 0) || (keys(%adds) > 0)) {
           if (keys(%deletions) > 0) {
               foreach my $key (keys(%deletions)) {
                   if ($predelallitems{$key} ne '') {
                       $sort_by_deltrail{$predelallitems{$key}} = $predeltrails[$predelallitems{$key}];
                   }
               }
           }
           my (@chkcats,@chktrails,%chkallitems);
           &Apache::loncommon::extract_categories($domconfig{'coursecategories'}{'cats'},\@chkcats,\@chktrails,\%chkallitems);
           if (ref($chkcats[0]) eq 'ARRAY') {
               my $depth = 0;
               my $chg = 0;
               for (my $i=0; $i<@{$chkcats[0]}; $i++) {
                   my $name = $chkcats[0][$i];
                   my $item;
                   if ($name eq '') {
                       $chg ++;
                   } else {
                       $item = &escape($name).'::0';
                       if ($chg) {
                           $domconfig{'coursecategories'}{'cats'}{$item} -= $chg;
                       }
                       $depth ++; 
                       &recurse_check(\@chkcats,$domconfig{'coursecategories'}{'cats'},$depth,$name);
                       $depth --;
                   }
               }
           }
       }
       if ((keys(%changes) > 0) || (keys(%deletions) > 0) || (keys(%reorderings) > 0) || (keys(%adds) > 0)) {
           $putresult = &Apache::lonnet::put_dom('configuration',\%domconfig,$dom);
           if ($putresult eq 'ok') {
               my %title = (
                            togglecats     => 'Show/Hide a course in catalog',
                            categorize     => 'Assign a category to a course',
                            togglecatscomm => 'Show/Hide a community in catalog',
                            categorizecomm => 'Assign a category to a community',
                           );
               my %level = (
                            dom  => 'set in Domain ("Modify Course/Community")',
                            crs  => 'set in Course ("Course Configuration")',
                            comm => 'set in Community ("Community Configuration")',
                           );
               $resulttext = &mt('Changes made:').'<ul>';
               if ($changes{'togglecats'}) {
                   $resulttext .= '<li>'.&mt("$title{'togglecats'} $level{$env{'form.togglecats'}}").'</li>'; 
               }
               if ($changes{'categorize'}) {
                   $resulttext .= '<li>'.&mt("$title{'categorize'} $level{$env{'form.categorize'}}").'</li>';
               }
               if ($changes{'togglecatscomm'}) {
                   $resulttext .= '<li>'.&mt("$title{'togglecatscomm'} $level{$env{'form.togglecatscomm'}}").'</li>';
               }
               if ($changes{'categorizecomm'}) {
                   $resulttext .= '<li>'.&mt("$title{'categorizecomm'} $level{$env{'form.categorizecomm'}}").'</li>';
               }
               if ((keys(%deletions) > 0) || (keys(%reorderings) > 0) || (keys(%adds) > 0)) {
                   my $cathash;
                   if (ref($domconfig{'coursecategories'}) eq 'HASH') {
                       $cathash = $domconfig{'coursecategories'}{'cats'};
                   } else {
                       $cathash = {};
                   } 
                   my (@cats,@trails,%allitems);
                       &Apache::loncommon::extract_categories($cathash,\@cats,\@trails,\%allitems);
                   if (keys(%deletions) > 0) {
                       $resulttext .= '<li>'.&mt('Deleted categories:').'<ul>';
                       foreach my $predeltrail (sort {$a <=> $b } (keys(%sort_by_deltrail))) { 
                           $resulttext .= '<li>'.$predeltrails[$predeltrail].'</li>';
                       }
                       $resulttext .= '</ul></li>';
                   }
                   if (keys(%reorderings) > 0) {
                       my %sort_by_trail;
                       $resulttext .= '<li>'.&mt('Reordered categories:').'<ul>';
                       foreach my $key (keys(%reorderings)) {
                           if ($allitems{$key} ne '') {
                               $sort_by_trail{$allitems{$key}} = $trails[$allitems{$key}];
                           }
                       }
                       foreach my $trail (sort {$a <=> $b } (keys(%sort_by_trail))) {
                           $resulttext .= '<li>'.$trails[$trail].'</li>';
                       }
                       $resulttext .= '</ul></li>';
                   }
                   if (keys(%adds) > 0) {
                       my %sort_by_trail;
                       $resulttext .= '<li>'.&mt('Added categories:').'<ul>';
                       foreach my $key (keys(%adds)) {
                           if ($allitems{$key} ne '') {
                               $sort_by_trail{$allitems{$key}} = $trails[$allitems{$key}];
                           }
                       }
                       foreach my $trail (sort {$a <=> $b } (keys(%sort_by_trail))) {
                           $resulttext .= '<li>'.$trails[$trail].'</li>';
                       }
                       $resulttext .= '</ul></li>';
                   }
               }
               $resulttext .= '</ul>';
           } else {
               $resulttext = '<span class="LC_error">'.
                             &mt('An error occurred: [_1]',$putresult).'</span>';
           }
       } else {
           $resulttext = &mt('No changes made to course and community categories');
       }
       return $resulttext;
   }
   
   sub modify_serverstatuses {
       my ($dom,%domconfig) = @_;
       my ($resulttext,%changes,%currserverstatus,%newserverstatus);
       if (ref($domconfig{'serverstatuses'}) eq 'HASH') {
           %currserverstatus = %{$domconfig{'serverstatuses'}};
       }
       my @pages = &serverstatus_pages();
       foreach my $type (@pages) {
           $newserverstatus{$type}{'namedusers'} = '';
           $newserverstatus{$type}{'machines'} = '';
           if (defined($env{'form.'.$type.'_namedusers'})) {
               my @users = split(/,/,$env{'form.'.$type.'_namedusers'});
               my @okusers;
               foreach my $user (@users) {
                   my ($uname,$udom) = split(/:/,$user);
                   if (($udom =~ /^$match_domain$/) &&   
                       (&Apache::lonnet::domain($udom)) &&
                       ($uname =~ /^$match_username$/)) {
                       if (!grep(/^\Q$user\E/,@okusers)) {
                           push(@okusers,$user);
                       }
                   }
               }
               if (@okusers > 0) {
                    @okusers = sort(@okusers);
                    $newserverstatus{$type}{'namedusers'} = join(',',@okusers);
               }
           }
           if (defined($env{'form.'.$type.'_machines'})) {
               my @machines = split(/,/,$env{'form.'.$type.'_machines'});
               my @okmachines;
               foreach my $ip (@machines) {
                   my @parts = split(/\./,$ip);
                   next if (@parts < 4);
                   my $badip = 0;
                   for (my $i=0; $i<4; $i++) {
                       if (!(($parts[$i] >= 0) && ($parts[$i] <= 255))) {
                           $badip = 1;
                           last;
                       }
                   }
                   if (!$badip) {
                       push(@okmachines,$ip);     
                   }
               }
               @okmachines = sort(@okmachines);
               $newserverstatus{$type}{'machines'} = join(',',@okmachines);
           }
       }
       my %serverstatushash =  (
                                   serverstatuses => \%newserverstatus,
                               );
       foreach my $type (@pages) {
           foreach my $setting ('namedusers','machines') {
               my (@current,@new);
               if (ref($currserverstatus{$type}) eq 'HASH') {
                   if ($currserverstatus{$type}{$setting} ne '') { 
                       @current = split(/,/,$currserverstatus{$type}{$setting});
                   }
               }
               if ($newserverstatus{$type}{$setting} ne '') {
                   @new = split(/,/,$newserverstatus{$type}{$setting});
               }
               if (@current > 0) {
                   if (@new > 0) {
                       foreach my $item (@current) {
                           if (!grep(/^\Q$item\E$/,@new)) {
                               $changes{$type}{$setting} = 1;
                               last;
                           }
                       }
                       foreach my $item (@new) {
                           if (!grep(/^\Q$item\E$/,@current)) {
                               $changes{$type}{$setting} = 1;
                               last;
                           }
                       }
                   } else {
                       $changes{$type}{$setting} = 1;
                   }
               } elsif (@new > 0) {
                   $changes{$type}{$setting} = 1;
               }
           }
       }
       if (keys(%changes) > 0) {
           my $titles= &LONCAPA::lonauthcgi::serverstatus_titles();
           my $putresult = &Apache::lonnet::put_dom('configuration',
                                                    \%serverstatushash,$dom);
           if ($putresult eq 'ok') {
               $resulttext .= &mt('Changes made:').'<ul>';
               foreach my $type (@pages) {
                   if (ref($changes{$type}) eq 'HASH') {
                       $resulttext .= '<li>'.$titles->{$type}.'<ul>';
                       if ($changes{$type}{'namedusers'}) {
                           if ($newserverstatus{$type}{'namedusers'} eq '') {
                               $resulttext .= '<li>'.&mt("Access terminated for all specific (named) users").'</li>'."\n";
                           } else {
                               $resulttext .= '<li>'.&mt("Access available for the following specified users: ").$newserverstatus{$type}{'namedusers'}.'</li>'."\n";
                           }
                       }
                       if ($changes{$type}{'machines'}) {
                           if ($newserverstatus{$type}{'machines'} eq '') {
                               $resulttext .= '<li>'.&mt("Access terminated for all specific IP addresses").'</li>'."\n";
                           } else {
                               $resulttext .= '<li>'.&mt("Access available for the following specified IP addresses: ").$newserverstatus{$type}{'machines'}.'</li>'."\n";
                           }
   
                       }
                       $resulttext .= '</ul></li>';
                   }
               }
               $resulttext .= '</ul>';
           } else {
               $resulttext = '<span class="LC_error">'.
                             &mt('An error occurred saving access settings for server status pages: [_1].',$putresult).'</span>';
   
           }
       } else {
           $resulttext = &mt('No changes made to access to server status pages');
       }
       return $resulttext;
   }
   
   sub modify_helpsettings {
       my ($r,$dom,$confname,%domconfig) = @_;
     my ($resulttext,$errors,%changes,%helphash);
    
     my $customhelpfile  = $env{'form.loginhelpurl.filename'};
       my $defaulthelpfile = 'defaulthelp.html';
     my $servadm = $r->dir_config('lonAdmEMail');
       my ($configuserok,$author_ok,$switchserver) = 
           &config_check($dom,$confname,$servadm);
    
     my %defaultchecked = ('submitbugs' => 'on');
     my @offon = ('off','on');
       my %title = ( submitbugs     => 'Display link for users to submit a bug', 
        loginhelpurl  => 'Unauthenticated login help page set to custom file');
        
       my @toggles = ('submitbugs');
   
       $helphash{'helpsettings'} = {};
       
       if (ref($domconfig{'helpsettings'}) ne 'HASH') {
           if ($domconfig{'helpsettings'} eq '') {
               $domconfig{'helpsettings'} = {};
           }
       }
       
       if (ref($domconfig{'helpsettings'}) eq 'HASH') {
      
           foreach my $item (@toggles) {
          
    if ($defaultchecked{$item} eq 'on') { 
    if (($domconfig{'helpsettings'}{$item} eq '') &&
    ($env{'form.'.$item} eq '0')) {
    $changes{$item} = 1;
    } elsif ($domconfig{'helpsettings'}{$item} ne $env{'form.'.$item}) {
    $changes{$item} = 1;
    }
    } elsif ($defaultchecked{$item} eq 'off') {
    if (($domconfig{'helpsettings'}{$item} eq '') &&
    ($env{'form.'.$item} eq '1')) {
    $changes{$item} = 1;
    } elsif ($domconfig{'helpsettings'}{$item} ne $env{'form.'.$item}) {
    $changes{$item} = 1;
    }
    }
    $helphash{'helpsettings'}{$item} = $env{'form.'.$item};
    }
   
    if ($customhelpfile ne '') {
    my $error;
    if ($configuserok eq 'ok') {
    if ($switchserver) {
    $error = &mt("Upload of custom help file is not permitted to this server: [_1]",$switchserver);
    } else {
    if ($author_ok eq 'ok') {
    my ($result,$loginhelpurl) =
    &publishlogo($r,'upload','loginhelpurl',$dom,
    $confname,'help','','',$customhelpfile);
    if ($result eq 'ok') {
    $helphash{'helpsettings'}{'loginhelpurl'} = $loginhelpurl;
    $changes{'loginhelpurl'} = 1;
    } else {
    $error = &mt("Upload of [_1] failed because an error occurred publishing the file in RES space. Error was: [_2].",$customhelpfile,$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].",$customhelpfile,$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].",$customhelpfile,$confname,$dom,$configuserok);
    }
    if ($error) {
    &Apache::lonnet::logthis($error);
    $errors .= '<li><span class="LC_error">'.$error.'</span></li>';
    }
    }
   
           if ($domconfig{'helpsettings'}{'loginhelpurl'} ne '') {
               if ($env{'form.loginhelpurl_del'}) {
                   $helphash{'helpsettings'}{'loginhelpurl'} = '';
                   $changes{'loginhelpurl'} = 1;
               }
           }
       }
       
       
       my $putresult;
       
       if (keys(%changes) > 0) {
       $putresult = &Apache::lonnet::put_dom('configuration',\%helphash,$dom);
       } else {
       $putresult = 'ok';
       }
                                                
       if ($putresult eq 'ok') {
           if (keys(%changes) > 0) {
    $resulttext = &mt('Changes made:').'<ul>';
    foreach my $item (sort(keys(%changes))) {
    if ($item eq 'submitbugs') {
    $resulttext .= '<li>'.&mt("$title{$item} set to $offon[$env{'form.'.$item}]").'</li>';
    }
    if ($item eq 'loginhelpurl') {
    if ($helphash{'helpsettings'}{'loginhelpurl'} eq '') {
                           $resulttext .= '<li>'.&mt('[_1] help file removed; [_2] file will be used for the unathorized help page in this domain.',$customhelpfile,$defaulthelpfile).'</li>';
                       } else {
                           $resulttext .= '<li>'.&mt("$title{$item} [_1]",$customhelpfile).'</li>';
                       }
    }
    }
    $resulttext .= '</ul>';
    } else {
    $resulttext = &mt('No changes made to help settings');
    }
       } else {
           $resulttext = '<span class="LC_error">'.
       &mt('An error occurred: [_1]',$putresult).'</span>';
       }
       if ($errors) {
           $resulttext .= &mt('The following errors occurred: ').'<ul>'.
                          $errors.'</ul>';
       }
       return $resulttext;
   }
   
   sub modify_coursedefaults {
       my ($dom,%domconfig) = @_;
       my ($resulttext,$errors,%changes,%defaultshash);
       my %defaultchecked = ('canuse_pdfforms' => 'off');
       my @offon = ('off','on');
       my @toggles = ('canuse_pdfforms');
   
       $defaultshash{'coursedefaults'} = {};
   
       if (ref($domconfig{'coursedefaults'}) ne 'HASH') {
           if ($domconfig{'coursedefaults'} eq '') {
               $domconfig{'coursedefaults'} = {};
           }
       }
   
       if (ref($domconfig{'coursedefaults'}) eq 'HASH') {
           foreach my $item (@toggles) {
               if ($defaultchecked{$item} eq 'on') {
                   if (($domconfig{'coursedefaults'}{$item} eq '') &&
                       ($env{'form.'.$item} eq '0')) {
                       $changes{$item} = 1;
                   } elsif ($domconfig{'coursdefaults'}{$item} ne $env{'form.'.$item}) {
                       $changes{$item} = 1;
                   }
               } elsif ($defaultchecked{$item} eq 'off') {
                   if (($domconfig{'coursedefaults'}{$item} eq '') &&
                       ($env{'form.'.$item} eq '1')) {
                       $changes{$item} = 1;
                   } elsif ($domconfig{'coursedefaults'}{$item} ne $env{'form.'.$item}) {
                       $changes{$item} = 1;
                   }
               }
               $defaultshash{'coursedefaults'}{$item} = $env{'form.'.$item};
           }
           my $currdefresponder = $domconfig{'coursedefaults'}{'anonsurvey_threshold'};
           my $newdefresponder = $env{'form.anonsurvey_threshold'};
           $newdefresponder =~ s/\D//g;
           if ($newdefresponder eq '' || $newdefresponder < 1) {
               $newdefresponder = 1;
           }
           $defaultshash{'coursedefaults'}{'anonsurvey_threshold'} = $newdefresponder;
           if ($currdefresponder ne $newdefresponder) {
               unless ($currdefresponder eq '' && $newdefresponder == 10) {
                   $changes{'anonsurvey_threshold'} = 1;
               }
           }
       }
       my $putresult = &Apache::lonnet::put_dom('configuration',\%defaultshash,
                                                $dom);
       if ($putresult eq 'ok') {
           if (keys(%changes) > 0) {
               if ($changes{'canuse_pdfforms'}) {
                   my %domdefaults = &Apache::lonnet::get_domain_defaults($dom);
                   $domdefaults{'canuse_pdfforms'}=$defaultshash{'coursedefaults'}{'canuse_pdfforms'};
                   my $cachetime = 24*60*60;
                   &Apache::lonnet::do_cache_new('domdefaults',$dom,\%domdefaults,$cachetime);
               }
               $resulttext = &mt('Changes made:').'<ul>';
               foreach my $item (sort(keys(%changes))) {
                   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 'anonsurvey_threshold') {
                           $resulttext .= '<li>'.&mt('Responder count required for display of anonymous survey submissions set to [_1].',$defaultshash{'coursedefaults'}{'anonsurvey_threshold'}).'</li>';
                   }
               }
               $resulttext .= '</ul>';
           } else {
               $resulttext = &mt('No changes made to course defaults');
         }          }
     } else {      } else {
         $resulttext = '<span class="LC_error">'.          $resulttext = '<span class="LC_error">'.
Line 2342  sub modify_user_creation { Line 6764  sub modify_user_creation {
     return $resulttext;      return $resulttext;
 }  }
   
   sub modify_usersessions {
       my ($dom,%domconfig) = @_;
       my @types = ('version','excludedomain','includedomain');
       my @prefixes = ('remote','hosted');
       my @lcversions = &Apache::lonnet::all_loncaparevs();
       my (%by_ip,%by_location,@intdoms);
       &build_location_hashes(\@intdoms,\%by_ip,\%by_location);
       my @locations = sort(keys(%by_location));
       my (%defaultshash,%changes);
       foreach my $prefix (@prefixes) {
           $defaultshash{'usersessions'}{$prefix} = {};
       }
       my %domdefaults = &Apache::lonnet::get_domain_defaults($dom);
       my $resulttext;
       my %iphost = &Apache::lonnet::get_iphost();
       foreach my $prefix (@prefixes) {
           foreach my $type (@types) {
               my $inuse = $env{'form.'.$prefix.'_'.$type.'_inuse'};
               if ($type eq 'version') {
                   my $value = $env{'form.'.$prefix.'_'.$type};
                   my $okvalue;
                   if ($value ne '') {
                       if (grep(/^\Q$value\E$/,@lcversions)) {
                           $okvalue = $value;
                       }
                   }
                   if (ref($domconfig{'usersessions'}) eq 'HASH') {
                       if (ref($domconfig{'usersessions'}{$prefix}) eq 'HASH') {
                           if ($domconfig{'usersessions'}{$prefix}{$type} ne '') {
                               if ($inuse == 0) {
                                   $changes{$prefix}{$type} = 1;
                               } else {
                                   if ($okvalue ne $domconfig{'usersessions'}{$prefix}{$type}) {
                                       $changes{$prefix}{$type} = 1;
                                   }
                                   if ($okvalue ne '') {
                                       $defaultshash{'usersessions'}{$prefix}{$type} = $okvalue;
                                   } 
                               }
                           } else {
                               if (($inuse == 1) && ($okvalue ne '')) {
                                   $defaultshash{'usersessions'}{$prefix}{$type} = $okvalue;
                                   $changes{$prefix}{$type} = 1;
                               }
                           }
                       } else {
                           if (($inuse == 1) && ($okvalue ne '')) {
                               $defaultshash{'usersessions'}{$prefix}{$type} = $okvalue;
                               $changes{$prefix}{$type} = 1;
                           }
                       }
                   } else {
                       if (($inuse == 1) && ($okvalue ne '')) {
                           $defaultshash{'usersessions'}{$prefix}{$type} = $okvalue;
                           $changes{$prefix}{$type} = 1;
                       }
                   }
               } else {
                   my @vals = &Apache::loncommon::get_env_multiple('form.'.$prefix.'_'.$type);
                   my @okvals;
                   foreach my $val (@vals) {
                       if ($val =~ /:/) {
                           my @items = split(/:/,$val);
                           foreach my $item (@items) {
                               if (ref($by_location{$item}) eq 'ARRAY') {
                                   push(@okvals,$item);
                               }
                           }
                       } else {
                           if (ref($by_location{$val}) eq 'ARRAY') {
                               push(@okvals,$val);
                           }
                       }
                   }
                   @okvals = sort(@okvals);
                   if (ref($domconfig{'usersessions'}) eq 'HASH') {
                       if (ref($domconfig{'usersessions'}{$prefix}) eq 'HASH') {
                           if (ref($domconfig{'usersessions'}{$prefix}{$type}) eq 'ARRAY') {
                               if ($inuse == 0) {
                                   $changes{$prefix}{$type} = 1; 
                               } else {
                                   $defaultshash{'usersessions'}{$prefix}{$type} = \@okvals;
                                   my @changed = &Apache::loncommon::compare_arrays($domconfig{'usersessions'}{$prefix}{$type},$defaultshash{'usersessions'}{$prefix}{$type});
                                   if (@changed > 0) {
                                       $changes{$prefix}{$type} = 1;
                                   }
                               }
                           } else {
                               if ($inuse == 1) {
                                   $defaultshash{'usersessions'}{$prefix}{$type} = \@okvals;
                                   $changes{$prefix}{$type} = 1;
                               }
                           } 
                       } else {
                           if ($inuse == 1) {
                               $defaultshash{'usersessions'}{$prefix}{$type} = \@okvals;
                               $changes{$prefix}{$type} = 1;
                           }
                       }
                   } else {
                       if ($inuse == 1) {
                           $defaultshash{'usersessions'}{$prefix}{$type} = \@okvals;
                           $changes{$prefix}{$type} = 1;
                       }
                   }
               }
           }
       }
       if (keys(%changes) > 0) {
           my $putresult = &Apache::lonnet::put_dom('configuration',\%defaultshash,
                                                    $dom);
           if ($putresult eq 'ok') {
               if (ref($defaultshash{'usersessions'}) eq 'HASH') {
                   if (ref($defaultshash{'usersessions'}{'remote'}) eq 'HASH') {
                       $domdefaults{'remotesessions'} = $defaultshash{'usersessions'}{'remote'};
                   }
                   if (ref($defaultshash{'usersessions'}{'hosted'}) eq 'HASH') {
                       $domdefaults{'hostedsessions'} = $defaultshash{'usersessions'}{'hosted'};
                   }
               }
               my $cachetime = 24*60*60;
               &Apache::lonnet::do_cache_new('domdefaults',$dom,\%domdefaults,$cachetime);
               my %lt = &usersession_titles();
               $resulttext = &mt('Changes made:').'<ul>';
               foreach my $prefix (@prefixes) {
                   if (ref($changes{$prefix}) eq 'HASH') {
                       $resulttext .= '<li>'.$lt{$prefix}.'<ul>';
                       foreach my $type (@types) {
                           if (defined($changes{$prefix}{$type})) {
                               my $newvalue;
                               if (ref($defaultshash{'usersessions'}) eq 'HASH') {
                                   if (ref($defaultshash{'usersessions'}{$prefix})) {
                                       if ($type eq 'version') {
                                           $newvalue = $defaultshash{'usersessions'}{$prefix}{$type};
                                       } elsif (ref($defaultshash{'usersessions'}{$prefix}{$type}) eq 'ARRAY') {
                                           if (@{$defaultshash{'usersessions'}{$prefix}{$type}} > 0) {
                                               $newvalue = join(', ',@{$defaultshash{'usersessions'}{$prefix}{$type}});
                                           }
                                       }
                                   }
                               }
                               if ($newvalue eq '') {
                                   if ($type eq 'version') {
                                       $resulttext .= '<li>'.&mt('[_1] set to: off',$lt{$type}).'</li>';
                                   } else {
                                       $resulttext .= '<li>'.&mt('[_1] set to: none',$lt{$type}).'</li>';
                                   }
                               } else {
                                   if ($type eq 'version') {
                                       $newvalue .= ' '.&mt('(or later)'); 
                                   } 
                                   $resulttext .= '<li>'.&mt('[_1] set to: [_2].',$lt{$type},$newvalue).'</li>'; 
                               }
                           }
                       }
                       $resulttext .= '</ul>';
                   }
               }
               $resulttext .= '</ul>';
           } else {
               $resulttext = '<span class="LC_error">'.
                             &mt('An error occurred: [_1]',$putresult).'</span>';
           }
       } else {
           $resulttext =  &mt('No changes made to settings for user session hosting.');
       }
       return $resulttext;
   }
   
   sub recurse_check {
       my ($chkcats,$categories,$depth,$name) = @_;
       if (ref($chkcats->[$depth]{$name}) eq 'ARRAY') {
           my $chg = 0;
           for (my $j=0; $j<@{$chkcats->[$depth]{$name}}; $j++) {
               my $category = $chkcats->[$depth]{$name}[$j];
               my $item;
               if ($category eq '') {
                   $chg ++;
               } else {
                   my $deeper = $depth + 1;
                   $item = &escape($category).':'.&escape($name).':'.$depth;
                   if ($chg) {
                       $categories->{$item} -= $chg;
                   }
                   &recurse_check($chkcats,$categories,$deeper,$category);
                   $deeper --;
               }
           }
       }
       return;
   }
   
   sub recurse_cat_deletes {
       my ($item,$coursecategories,$deletions) = @_;
       my ($deleted,$container,$depth) = map { &unescape($_); } split(/:/,$item);
       my $subdepth = $depth + 1;
       if (ref($coursecategories) eq 'HASH') {
           foreach my $subitem (keys(%{$coursecategories})) {
               my ($child,$parent,$itemdepth) = map { &unescape($_); } split(/:/,$subitem);
               if (($parent eq $deleted) && ($itemdepth == $subdepth)) {
                   delete($coursecategories->{$subitem});
                   $deletions->{$subitem} = 1;
                   &recurse_cat_deletes($subitem,$coursecategories,$deletions);
               }  
           }
       }
       return;
   }
   
   sub dom_servers {
       my ($dom) = @_;
       my (%uniqservers,%servers);
       my $primaryserver = &Apache::lonnet::hostname(&Apache::lonnet::domain($dom,'primary'));
       my @machinedoms = &Apache::lonnet::machine_domains($primaryserver);
       foreach my $mdom (@machinedoms) {
           my %currservers = %servers;
           my %server = &Apache::lonnet::get_servers($mdom);
           %servers = (%currservers,%server);
       }
       my %by_hostname;
       foreach my $id (keys(%servers)) {
           push(@{$by_hostname{$servers{$id}}},$id);
       }
       foreach my $hostname (sort(keys(%by_hostname))) {
           if (@{$by_hostname{$hostname}} > 1) {
               my $match = 0;
               foreach my $id (@{$by_hostname{$hostname}}) {
                   if (&Apache::lonnet::host_domain($id) eq $dom) {
                       $uniqservers{$id} = $hostname;
                       $match = 1;
                   }
               }
               unless ($match) {
                   $uniqservers{$by_hostname{$hostname}[0]} = $hostname;
               }
           } else {
               $uniqservers{$by_hostname{$hostname}[0]} = $hostname;
           }
       }
       return %uniqservers;
   }
   
   sub get_active_dcs {
       my ($dom) = @_;
       my %dompersonnel = &Apache::lonnet::get_domain_roles($dom,['dc']);
       my %domcoords;
       my $numdcs = 0;
       my $now = time;
       foreach my $server (keys(%dompersonnel)) {
           foreach my $user (sort(keys(%{$dompersonnel{$server}}))) {
               my ($trole,$uname,$udom,$runame,$rudom,$rsec) = split(/:/,$user);
               my ($end,$start) = split(':',$dompersonnel{$server}{$user});
               if (($end eq '') || ($end == 0) || ($end > $now)) {
                   if ($start <= $now) {
                       $domcoords{$uname.':'.$udom} = $dompersonnel{$server}{$user};
                   }
               }
           }
       }
       return %domcoords;
   }
   
   sub active_dc_picker {
       my ($dom,$curr_dc) = @_;
       my %domcoords = &get_active_dcs($dom); 
       my @dcs = sort(keys(%domcoords));
       my $numdcs = scalar(@dcs); 
       my $datatable;
       my $numinrow = 2;
       if ($numdcs > 1) {
           $datatable = '<table>';
           for (my $i=0; $i<@dcs; $i++) {
               my $rem = $i%($numinrow);
               if ($rem == 0) {
                   if ($i > 0) {
                       $datatable .= '</tr>';
                   }
                   $datatable .= '<tr>';
               }
               my $check = ' ';
               if ($curr_dc eq '') {
                   if (!$i) { 
                       $check = ' checked="checked" ';
                   }
               } elsif ($dcs[$i] eq $curr_dc) {
                   $check = ' checked="checked" ';
               }
               if ($i == @dcs - 1) {
                   my $colsleft = $numinrow - $rem;
                   if ($colsleft > 1) {
                       $datatable .= '<td colspan="'.$colsleft.'">';
                   } else {
                       $datatable .= '<td>';
                   }
               } else {
                   $datatable .= '<td>';
               }
               my ($dcname,$dcdom) = split(':',$dcs[$i]);
               $datatable .= '<span class="LC_nobreak"><label>'.
                             '<input type="radio" name="autocreate_xmldc"'.
                             ' value="'.$dcs[$i].'"'.$check.'/>'.
                             &Apache::loncommon::plainname($dcname,$dcdom).
                             '</label></span></td>';
           }
           $datatable .= '</tr></table>';
       } elsif (@dcs) {
           $datatable .= '<input type="hidden" name="autocreate_dc" value="'.
                         $dcs[0].'" />';
       }
       return ($numdcs,$datatable);
   }
   
   sub usersession_titles {
       return &Apache::lonlocal::texthash(
                  hosted => 'Hosting of sessions for users from other domains on servers in this domain',
   
                  remote => 'Hosting of sessions for users in this domain on servers in other domains',
                  version => 'LON-CAPA version requirement',
                  excludedomain => 'Allow all, but exclude specific domains',
                  includedomain => 'Deny all, but include specific domains',
              );
   }
   
 1;  1;

Removed from v.1.27  
changed lines
  Added in v.1.144


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