Diff for /loncom/interface/domainprefs.pm between versions 1.126 and 1.215

version 1.126, 2010/02/19 15:41:40 version 1.215, 2013/12/23 13:20:31
Line 45  described at http://www.lon-capa.org. Line 45  described at http://www.lon-capa.org.
 =head1 OVERVIEW  =head1 OVERVIEW
   
 Each institution using LON-CAPA will typically have a single domain designated   Each institution using LON-CAPA will typically have a single domain designated 
 for use by individuals affliated with the institution.  Accordingly, each domain  for use by individuals affiliated with the institution.  Accordingly, each domain
 may define a default set of logos and a color scheme which can be used to "brand"  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  the LON-CAPA instance. In addition, an institution will typically have a language
 and timezone which are used for the majority of courses.  and timezone which are used for the majority of courses.
Line 86  $dom,$settings,$rowtotal,$action. Line 86  $dom,$settings,$rowtotal,$action.
   
 $dom is the domain, $settings is a reference to a hash of current settings for  $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   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   number of rows displayed on the page, and $action is the context (quotas, 
 or requestcourses).  requestcourses or requestauthor).
   
 The print_quotas routine was orginally created to display/store information  The print_quotas routine was orginally created to display/store information
 about default quota sizes for portfolio spaces for the different types of   about default quota sizes for portfolio spaces for the different types of 
 institutional affiliation in the domain (e.g., Faculty, Staff, Student etc.),   institutional affiliation in the domain (e.g., Faculty, Staff, Student etc.), 
 but is now also used to manage availability of user tools:   but is now also used to manage availability of user tools: 
 i.e., blogs, aboutme page, and portfolios, and the course request tool,  i.e., blogs, aboutme page, and portfolios, and the course request tool,
 used by course owners to request creation of a course.  used by course owners to request creation of a course, and to display/store
   default quota sizes for authoring spaces.
   
 Outputs: 1  Outputs: 1
   
Line 140  autolimit Line 141  autolimit
   
 =over  =over
     
 - course requests will be processed autoatically up to a limit of  - course requests will be processed automatically up to a limit of
 N requests for the course type for the particular requestor.  N requests for the course type for the particular requestor.
 If N is undefined, there is no limit to the number of course requests  If N is undefined, there is no limit to the number of course requests
 which a course owner may submit and have processed automatically.   which a course owner may submit and have processed automatically. 
Line 171  use Locale::Language; Line 172  use Locale::Language;
 use DateTime::TimeZone;  use DateTime::TimeZone;
 use DateTime::Locale;  use DateTime::Locale;
   
   my $registered_cleanup;
   my $modified_urls;
   
 sub handler {  sub handler {
     my $r=shift;      my $r=shift;
     if ($r->header_only) {      if ($r->header_only) {
Line 190  sub handler { Line 194  sub handler {
         "/adm/domainprefs:mau:0:0:Cannot modify domain settings";          "/adm/domainprefs:mau:0:0:Cannot modify domain settings";
         return HTTP_NOT_ACCEPTABLE;          return HTTP_NOT_ACCEPTABLE;
     }      }
   
       $registered_cleanup=0;
       @{$modified_urls}=();
   
     &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','actions']);                                              ['phase','actions']);
Line 197  sub handler { Line 205  sub handler {
     if ( exists($env{'form.phase'}) ) {      if ( exists($env{'form.phase'}) ) {
         $phase = $env{'form.phase'};          $phase = $env{'form.phase'};
     }      }
       my %servers = &Apache::lonnet::internet_dom_servers($dom);
     my %domconfig =      my %domconfig =
       &Apache::lonnet::get_dom('configuration',['login','rolecolors',        &Apache::lonnet::get_dom('configuration',['login','rolecolors',
                 'quotas','autoenroll','autoupdate','autocreate',                  'quotas','autoenroll','autoupdate','autocreate',
                 'directorysrch','usercreation','usermodification',                  'directorysrch','usercreation','usermodification',
                 'contacts','defaults','scantron','coursecategories',                  'contacts','defaults','scantron','coursecategories',
                 'serverstatuses','requestcourses','helpsettings',                  'serverstatuses','requestcourses','helpsettings',
                 'coursedefaults'],$dom);                  'coursedefaults','usersessions','loadbalancing',
                   'requestauthor'],$dom);
     my @prefs_order = ('rolecolors','login','defaults','quotas','autoenroll',      my @prefs_order = ('rolecolors','login','defaults','quotas','autoenroll',
                        'autoupdate','autocreate','directorysrch','contacts',                         'autoupdate','autocreate','directorysrch','contacts',
                        'usercreation','usermodification','scantron',                         'usercreation','usermodification','scantron',
                        'requestcourses','coursecategories','serverstatuses','helpsettings',                         'requestcourses','requestauthor','coursecategories',
                        'coursedefaults');                         'serverstatuses','helpsettings',
                          'coursedefaults','usersessions');
       my %existing;
       if (ref($domconfig{'loadbalancing'}) eq 'HASH') {
           %existing = %{$domconfig{'loadbalancing'}};
       }
       if ((keys(%servers) > 1) || (keys(%existing) > 0)) {
           push(@prefs_order,'loadbalancing');
       }
     my %prefs = (      my %prefs = (
         'rolecolors' =>          'rolecolors' =>
                    { text => 'Default color schemes',                     { text => 'Default color schemes',
Line 225  sub handler { Line 243  sub handler {
         'login' =>          'login' =>
                     { text => 'Log-in page options',                      { text => 'Log-in page options',
                       help => 'Domain_Configuration_Login_Page',                        help => 'Domain_Configuration_Login_Page',
                       header => [{col1 => 'Item',                        header => [{col1 => 'Log-in Page Items',
                                   col2 => '',}],                                    col2 => '',},
                                    {col1 => 'Log-in Help',
                                     col2 => 'Value'}],
                     },                      },
   
         'defaults' =>           'defaults' => 
                     { text => 'Default authentication/language/timezone',                      { text => 'Default authentication/language/timezone/portal',
                       help => 'Domain_Configuration_LangTZAuth',                        help => 'Domain_Configuration_LangTZAuth',
                       header => [{col1 => 'Setting',                        header => [{col1 => 'Setting',
                                   col2 => 'Value'}],                                    col2 => 'Value'}],
                     },                      },
         'quotas' =>           'quotas' => 
                     { text => 'User blogs, personal information pages and portfolios',                      { text => 'Blogs, personal web pages, webDAV/quotas, portfolios',
                       help => 'Domain_Configuration_Quotas',                        help => 'Domain_Configuration_Quotas',
                       header => [{col1 => 'User affiliation',                        header => [{col1 => 'User affiliation',
                                   col2 => 'Available tools',                                    col2 => 'Available tools',
                                   col3 => 'Portfolio quota',}],                                    col3 => 'Quotas, MB; (Authoring requires role)',}],
                     },                      },
         'autoenroll' =>          'autoenroll' =>
                    { text => 'Auto-enrollment settings',                     { text => 'Auto-enrollment settings',
Line 253  sub handler { Line 272  sub handler {
                      help => 'Domain_Configuration_Auto_Updates',                       help => 'Domain_Configuration_Auto_Updates',
                      header => [{col1 => 'Setting',                       header => [{col1 => 'Setting',
                                  col2 => 'Value',},                                   col2 => 'Value',},
                                   {col1 => 'Setting',
                                    col2 => 'Affiliation'},
                                 {col1 => 'User population',                                  {col1 => 'User population',
                                  col2 => 'Updataeable user data'}],                                   col2 => 'Updateable user data'}],
                   },                    },
         'autocreate' =>           'autocreate' => 
                   { text => 'Auto-course creation settings',                    { text => 'Auto-course creation settings',
Line 310  sub handler { Line 331  sub handler {
                              {col1 => 'Setting',                               {col1 => 'Setting',
                               col2 => 'Value'}],                                col2 => 'Value'}],
                  },                   },
           'requestauthor' =>
                    {text => 'Request authoring space',
                     help => 'Domain_Configuration_Request_Author',
                     header => [{col1 => 'User affiliation',
                                 col2 => 'Availability/Processing of requests',},
                                {col1 => 'Setting',
                                 col2 => 'Value'}],
                    },
         'coursecategories' =>          'coursecategories' =>
                   { text => 'Cataloging of courses/communities',                    { text => 'Cataloging of courses/communities',
                     help => 'Domain_Configuration_Cataloging_Courses',                      help => 'Domain_Configuration_Cataloging_Courses',
Line 330  sub handler { Line 359  sub handler {
         'helpsettings' =>          'helpsettings' =>
                  {text   => 'Help page settings',                   {text   => 'Help page settings',
                   help   => 'Domain_Configuration_Help_Settings',                    help   => 'Domain_Configuration_Help_Settings',
                   header => [{col1 => 'Authenticated Help Settings',                    header => [{col1 => 'Help Settings (logged-in users)',
                               col2 => ''},                                col2 => 'Value'}],
                              {col1 => 'Unauthenticated Help Settings',  
                               col2 => ''}],  
                  },                   },
         'coursedefaults' =>           'coursedefaults' => 
                  {text => 'Course/Community defaults',                   {text => 'Course/Community defaults',
                   help => 'Domain_Configuration_Course_Defaults',                    help => 'Domain_Configuration_Course_Defaults',
                   header => [{col1 => 'Setting',                    header => [{col1 => 'Defaults which can be overridden in each course by a CC',
                               col2 => 'Value',}],                                col2 => 'Value',},
                                {col1 => 'Defaults which can be overridden for each course by a DC',
                                 col2 => 'Value',},],
                  },                   },
         'privacy' =>           'privacy' => 
                  {text   => 'User Privacy',                   {text   => 'User Privacy',
Line 347  sub handler { Line 376  sub handler {
                   header => [{col1 => 'Setting',                    header => [{col1 => 'Setting',
                               col2 => 'Value',}],                                col2 => 'Value',}],
                  },                   },
           'usersessions' =>
                    {text  => 'User session hosting/offloading',
                     help  => 'Domain_Configuration_User_Sessions',
                     header => [{col1 => 'Domain server',
                                 col2 => 'Servers to offload sessions to when busy'},
                                {col1 => 'Hosting of users from other domains',
                                 col2 => 'Rules'},
                                {col1 => "Hosting domain's own users elsewhere",
                                 col2 => 'Rules'}],
                    },
            'loadbalancing' =>
                    {text  => 'Dedicated Load Balancer(s)',
                     help  => 'Domain_Configuration_Load_Balancing',
                     header => [{col1 => 'Balancers',
                                 col2 => 'Default destinations',
                                 col3 => 'User affiliation',
                                 col4 => 'Overrides'},
                               ],
                    },
     );      );
     my %servers = &dom_servers($dom);  
     if (keys(%servers) > 1) {      if (keys(%servers) > 1) {
         $prefs{'login'}  = { text   => 'Log-in page options',          $prefs{'login'}  = { text   => 'Log-in page options',
                              help   => 'Domain_Configuration_Login_Page',                               help   => 'Domain_Configuration_Login_Page',
                             header => [{col1 => 'Log-in Service',                              header => [{col1 => 'Log-in Service',
                                         col2 => 'Server Setting',},                                          col2 => 'Server Setting',},
                                        {col1 => 'Log-in Page Items',                                         {col1 => 'Log-in Page Items',
                                         col2 => ''}],                                          col2 => ''},
                                          {col1 => 'Log-in Help',
                                           col2 => 'Value'}],
                            };                             };
     }      }
   
     my @roles = ('student','coordinator','author','admin');      my @roles = ('student','coordinator','author','admin');
     my @actions = &Apache::loncommon::get_env_multiple('form.actions');      my @actions = &Apache::loncommon::get_env_multiple('form.actions');
     &Apache::lonhtmlcommon::add_breadcrumb      &Apache::lonhtmlcommon::add_breadcrumb
     ({href=>"javascript:changePage(document.$phase,'pickactions')",      ({href=>"javascript:changePage(document.$phase,'pickactions')",
       text=>"Pick functionality"});        text=>"Settings to display/modify"});
     my $confname = $dom.'-domainconfig';      my $confname = $dom.'-domainconfig';
   
     if ($phase eq 'process') {      if ($phase eq 'process') {
         &Apache::lonconfigsettings::make_changes($r,$dom,$phase,$context,\@prefs_order,\%prefs,\%domconfig,$confname,\@roles);          my $result = &Apache::lonconfigsettings::make_changes($r,$dom,$phase,$context,\@prefs_order,
                                                                 \%prefs,\%domconfig,$confname,\@roles);
           if (ref($result) eq 'HASH') {
               $r->rflush();
               &devalidate_remote_domconfs($dom,$result);
           }
     } elsif ($phase eq 'display') {      } elsif ($phase eq 'display') {
         &Apache::lonconfigsettings::display_settings($r,$dom,$phase,$context,\@prefs_order,\%prefs,\%domconfig,$confname);          my $js = &recaptcha_js().
     } else {                   &credits_js();
           if ((keys(%servers) > 1) || (keys(%existing) > 0)) {
               my ($othertitle,$usertypes,$types) =
                   &Apache::loncommon::sorted_inst_types($dom);
               $js .= &lonbalance_targets_js($dom,$types,\%servers,
                                             $domconfig{'loadbalancing'}).
                      &new_spares_js().
                      &common_domprefs_js().
                      &Apache::loncommon::javascript_array_indexof();
           }
           &Apache::lonconfigsettings::display_settings($r,$dom,$phase,$context,\@prefs_order,\%prefs,\%domconfig,$confname,$js);
       } else {
   # check if domconfig user exists for the domain.
           my $servadm = $r->dir_config('lonAdmEMail');
           my ($configuserok,$author_ok,$switchserver) =
               &config_check($dom,$confname,$servadm);
           unless ($configuserok eq 'ok') {
               &Apache::lonconfigsettings::print_header($r,$phase,$context);
               $r->print(&mt('The domain configuration user "[_1]" has yet to be created.',
                             $confname).
                         '<br />'
               );
               if ($switchserver) {
                   $r->print(&mt('Ordinarily, that domain configuration user is created when the ./UPDATE script is run to install LON-CAPA for the first time.').
                             '<br />'.
                             &mt('However, that does not apply when new domains are added to a multi-domain server, and ./UPDATE has not been run recently.').
                             '<br />'.
                             &mt('The "[_1]" user can be created automatically when a Domain Coordinator visits the web-based "Set domain configuration" screen, in a session hosted on the primary library server.',$confname).
                             '<br />'.
                             &mt('To do that now, use the following link: [_1]',$switchserver)
                   );
               } else {
                   $r->print(&mt('To create that user from the command line run the ./UPDATE script found in the top level directory of the extracted LON-CAPA tarball.').
                             '<br />'.
                             &mt('Once that is done, you will be able to use the web-based "Set domain configuration" to configure the domain')
                   );
               }
               $r->print(&Apache::loncommon::end_page());
               return OK;
           }
         if (keys(%domconfig) == 0) {          if (keys(%domconfig) == 0) {
             my $primarylibserv = &Apache::lonnet::domain($dom,'primary');              my $primarylibserv = &Apache::lonnet::domain($dom,'primary');
             my @ids=&Apache::lonnet::current_machine_ids();              my @ids=&Apache::lonnet::current_machine_ids();
Line 408  sub handler { Line 503  sub handler {
 }  }
   
 sub process_changes {  sub process_changes {
     my ($r,$dom,$confname,$action,$roles,$values) = @_;      my ($r,$dom,$confname,$action,$roles,$values,$lastactref) = @_;
     my %domconfig;      my %domconfig;
     if (ref($values) eq 'HASH') {      if (ref($values) eq 'HASH') {
         %domconfig = %{$values};          %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,$lastactref,%domconfig);
     } elsif ($action eq 'rolecolors') {      } elsif ($action eq 'rolecolors') {
         $output = &modify_rolecolors($r,$dom,$confname,$roles,          $output = &modify_rolecolors($r,$dom,$confname,$roles,
                                      %domconfig);                                       $lastactref,%domconfig);
     } elsif ($action eq 'quotas') {      } elsif ($action eq 'quotas') {
         $output = &modify_quotas($dom,$action,%domconfig);          $output = &modify_quotas($dom,$action,$lastactref,%domconfig);
     } elsif ($action eq 'autoenroll') {      } elsif ($action eq 'autoenroll') {
         $output = &modify_autoenroll($dom,%domconfig);          $output = &modify_autoenroll($dom,$lastactref,%domconfig);
     } elsif ($action eq 'autoupdate') {      } elsif ($action eq 'autoupdate') {
         $output = &modify_autoupdate($dom,%domconfig);          $output = &modify_autoupdate($dom,%domconfig);
     } elsif ($action eq 'autocreate') {      } elsif ($action eq 'autocreate') {
Line 434  sub process_changes { Line 529  sub process_changes {
     } elsif ($action eq 'usermodification') {      } elsif ($action eq 'usermodification') {
         $output = &modify_usermodification($dom,%domconfig);          $output = &modify_usermodification($dom,%domconfig);
     } elsif ($action eq 'contacts') {      } elsif ($action eq 'contacts') {
         $output = &modify_contacts($dom,%domconfig);          $output = &modify_contacts($dom,$lastactref,%domconfig);
     } elsif ($action eq 'defaults') {      } elsif ($action eq 'defaults') {
         $output = &modify_defaults($dom,$r);          $output = &modify_defaults($dom,$lastactref,%domconfig);
     } elsif ($action eq 'scantron') {      } elsif ($action eq 'scantron') {
         $output = &modify_scantron($r,$dom,$confname,%domconfig);          $output = &modify_scantron($r,$dom,$confname,$lastactref,%domconfig);
     } elsif ($action eq 'coursecategories') {      } elsif ($action eq 'coursecategories') {
         $output = &modify_coursecategories($dom,%domconfig);          $output = &modify_coursecategories($dom,%domconfig);
     } elsif ($action eq 'serverstatuses') {      } elsif ($action eq 'serverstatuses') {
         $output = &modify_serverstatuses($dom,%domconfig);          $output = &modify_serverstatuses($dom,%domconfig);
     } elsif ($action eq 'requestcourses') {      } elsif ($action eq 'requestcourses') {
         $output = &modify_quotas($dom,$action,%domconfig);          $output = &modify_quotas($dom,$action,$lastactref,%domconfig);
       } elsif ($action eq 'requestauthor') {
           $output = &modify_quotas($dom,$action,$lastactref,%domconfig);
     } elsif ($action eq 'helpsettings') {      } elsif ($action eq 'helpsettings') {
         $output = &modify_helpsettings($r,$dom,$confname,%domconfig);          $output = &modify_helpsettings($r,$dom,$confname,%domconfig);
     } elsif ($action eq 'coursedefaults') {      } elsif ($action eq 'coursedefaults') {
         $output = &modify_coursedefaults($dom,%domconfig);          $output = &modify_coursedefaults($dom,$lastactref,%domconfig);
       } elsif ($action eq 'usersessions') {
           $output = &modify_usersessions($dom,$lastactref,%domconfig);
       } elsif ($action eq 'loadbalancing') {
           $output = &modify_loadbalancing($dom,%domconfig);
     }      }
     return $output;      return $output;
 }  }
Line 474  sub print_config_box { Line 575  sub print_config_box {
     }      }
     if ($numheaders > 1) {      if ($numheaders > 1) {
         my $colspan = '';          my $colspan = '';
         if (($action eq 'rolecolors') || ($action eq 'coursecategories') || ($action eq 'helpsettings')) {          my $rightcolspan = '';
           if (($action eq 'rolecolors') || ($action eq 'coursecategories') ||
               (($action eq 'login') && ($numheaders < 3))) {
             $colspan = ' colspan="2"';              $colspan = ' colspan="2"';
         }          }
           if ($action eq 'usersessions') {
               $rightcolspan = ' colspan="3"'; 
           }
         $output .= '          $output .= '
           <tr>            <tr>
            <td>             <td>
             <table class="LC_nested">              <table class="LC_nested">
              <tr class="LC_info_row">               <tr class="LC_info_row">
               <td class="LC_left_item"'.$colspan.'>'.&mt($item->{'header'}->[0]->{'col1'}).'</td>                <td class="LC_left_item"'.$colspan.'>'.&mt($item->{'header'}->[0]->{'col1'}).'</td>
               <td class="LC_right_item">'.&mt($item->{'header'}->[0]->{'col2'}).'</td>                <td class="LC_right_item"'.$rightcolspan.'>'.&mt($item->{'header'}->[0]->{'col2'}).'</td>
              </tr>';               </tr>';
         $rowtotal ++;          $rowtotal ++;
         if ($action eq 'autoupdate') {          if ($action eq 'autoupdate') {
Line 495  sub print_config_box { Line 601  sub print_config_box {
         } elsif ($action eq 'coursecategories') {          } elsif ($action eq 'coursecategories') {
             $output .= &print_coursecategories('top',$dom,$item,$settings,\$rowtotal);              $output .= &print_coursecategories('top',$dom,$item,$settings,\$rowtotal);
         } elsif ($action eq 'login') {          } elsif ($action eq 'login') {
             $output .= &print_login('top',$dom,$confname,$phase,$settings,\$rowtotal);              if ($numheaders == 3) {
             $colspan = ' colspan="2"';                  $colspan = ' colspan="2"';
                   $output .= &print_login('service',$dom,$confname,$phase,$settings,\$rowtotal);
               } else {
                   $output .= &print_login('page',$dom,$confname,$phase,$settings,\$rowtotal);
               }
         } elsif ($action eq 'requestcourses') {          } elsif ($action eq 'requestcourses') {
             $output .= &print_quotas($dom,$settings,\$rowtotal,$action);              $output .= &print_quotas($dom,$settings,\$rowtotal,$action);
         } elsif ($action eq 'helpsettings') {          } elsif ($action eq 'requestauthor') {
             $output .= &print_helpsettings('top',$dom,$confname,$settings,\$rowtotal);              $output .= &print_quotas($dom,$settings,\$rowtotal,$action);
           } elsif ($action eq 'usersessions') {
               $output .= &print_usersessions('top',$dom,$settings,\$rowtotal); 
         } elsif ($action eq 'rolecolors') {          } elsif ($action eq 'rolecolors') {
             $output .= &print_rolecolors($phase,'student',$dom,$confname,$settings,\$rowtotal);              $output .= &print_rolecolors($phase,'student',$dom,$confname,$settings,\$rowtotal);
           } elsif ($action eq 'coursedefaults') {
               $output .= &print_coursedefaults('top',$dom,$settings,\$rowtotal);
         }          }
         $output .= '          $output .= '
            </table>             </table>
Line 518  sub print_config_box { Line 632  sub print_config_box {
              </tr>';               </tr>';
             $rowtotal ++;              $rowtotal ++;
         if ($action eq 'autoupdate') {          if ($action eq 'autoupdate') {
             $output .= &print_autoupdate('bottom',$dom,$settings,\$rowtotal);              $output .= &print_autoupdate('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_autoupdate('bottom',$dom,$settings,\$rowtotal);
               $rowtotal ++;
         } elsif ($action eq 'usercreation') {          } elsif ($action eq 'usercreation') {
             $output .= &print_usercreation('middle',$dom,$settings,\$rowtotal).'              $output .= &print_usercreation('middle',$dom,$settings,\$rowtotal).'
            </table>             </table>
Line 543  sub print_config_box { Line 668  sub print_config_box {
              <tr class="LC_info_row">               <tr class="LC_info_row">
               <td class="LC_left_item"'.$colspan.'>'.&mt($item->{'header'}->[2]->{'col1'}).'</td>                <td class="LC_left_item"'.$colspan.'>'.&mt($item->{'header'}->[2]->{'col1'}).'</td>
               <td class="LC_right_item">'.&mt($item->{'header'}->[2]->{'col2'}).'</td>      </tr>'.                <td class="LC_right_item">'.&mt($item->{'header'}->[2]->{'col2'}).'</td>      </tr>'.
   
                        &print_usermodification('bottom',$dom,$settings,\$rowtotal);                         &print_usermodification('bottom',$dom,$settings,\$rowtotal);
             $rowtotal ++;              $rowtotal ++;
         } elsif ($action eq 'coursecategories') {          } elsif ($action eq 'coursecategories') {
             $output .= &print_coursecategories('bottom',$dom,$item,$settings,\$rowtotal);              $output .= &print_coursecategories('bottom',$dom,$item,$settings,\$rowtotal);
         } elsif ($action eq 'login') {          } elsif ($action eq 'login') {
             $output .= &print_login('bottom',$dom,$confname,$phase,$settings,\$rowtotal);              if ($numheaders == 3) {
                   $output .= &print_login('page',$dom,$confname,$phase,$settings,\$rowtotal).'
              </table>
             </td>
            </tr>
            <tr>
              <td>
               <table class="LC_nested">
                <tr class="LC_info_row">
                 <td class="LC_left_item"'.$colspan.'>'.&mt($item->{'header'}->[2]->{'col1'}).'</td>
                 <td class="LC_right_item"'.$colspan.'>'.&mt($item->{'header'}->[2]->{'col2'}).'</td>      </tr>'.
                          &print_login('help',$dom,$confname,$phase,$settings,\$rowtotal);
                   $rowtotal ++;
               } else {
                   $output .= &print_login('help',$dom,$confname,$phase,$settings,\$rowtotal);
               }
         } elsif ($action eq 'requestcourses') {          } elsif ($action eq 'requestcourses') {
             $output .= &print_courserequestmail($dom,$settings,\$rowtotal);              $output .= &print_requestmail($dom,$action,$settings,\$rowtotal);
         } elsif ($action eq 'helpsettings') {          } elsif ($action eq 'requestauthor') {
             $output .= &print_helpsettings('bottom',$dom,$confname,$settings,\$rowtotal);              $output .= &print_requestmail($dom,$action,$settings,\$rowtotal);
           } elsif ($action eq 'usersessions') {
               $output .= &print_usersessions('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_usersessions('bottom',$dom,$settings,\$rowtotal);
               $rowtotal ++;
           } elsif ($action eq 'coursedefaults') {
               $output .= &print_coursedefaults('bottom',$dom,$settings,\$rowtotal);
         } elsif ($action eq 'rolecolors') {          } elsif ($action eq 'rolecolors') {
             $output .= &print_rolecolors($phase,'coordinator',$dom,$confname,$settings,\$rowtotal).'              $output .= &print_rolecolors($phase,'coordinator',$dom,$confname,$settings,\$rowtotal).'
            </table>             </table>
Line 612  sub print_config_box { Line 766  sub print_config_box {
         }          }
         $output .= '</td>';          $output .= '</td>';
         if ($item->{'header'}->[0]->{'col3'}) {          if ($item->{'header'}->[0]->{'col3'}) {
             $output .= '<td class="LC_right_item" valign="top">'.              if (defined($item->{'header'}->[0]->{'col4'})) {
                        &mt($item->{'header'}->[0]->{'col3'});                  $output .= '<td class="LC_left_item" valign="top">'.
                               &mt($item->{'header'}->[0]->{'col3'});
               } else {
                   $output .= '<td class="LC_right_item" valign="top">'.
                              &mt($item->{'header'}->[0]->{'col3'});
               }
             if ($action eq 'serverstatuses') {              if ($action eq 'serverstatuses') {
                 $output .= '<br />(<tt>'.&mt('IP1,IP2 etc.').'</tt>)';                  $output .= '<br />(<tt>'.&mt('IP1,IP2 etc.').'</tt>)';
             }              }
             $output .= '</td>';              $output .= '</td>';
         }          }
           if ($item->{'header'}->[0]->{'col4'}) {
               $output .= '<td class="LC_right_item" valign="top">'.
                          &mt($item->{'header'}->[0]->{'col4'});
           }
         $output .= '</tr>';          $output .= '</tr>';
         $rowtotal ++;          $rowtotal ++;
         if ($action eq 'login') {          if ($action eq 'quotas') {
             $output .= &print_login('bottom',$dom,$confname,$phase,$settings,  
                                     \$rowtotal);  
         } elsif ($action eq 'quotas') {  
             $output .= &print_quotas($dom,$settings,\$rowtotal,$action);              $output .= &print_quotas($dom,$settings,\$rowtotal,$action);
         } elsif ($action eq 'autoenroll') {          } elsif ($action eq 'autoenroll') {
             $output .= &print_autoenroll($dom,$settings,\$rowtotal);              $output .= &print_autoenroll($dom,$settings,\$rowtotal);
Line 635  sub print_config_box { Line 795  sub print_config_box {
         } elsif ($action eq 'contacts') {          } elsif ($action eq 'contacts') {
             $output .= &print_contacts($dom,$settings,\$rowtotal);              $output .= &print_contacts($dom,$settings,\$rowtotal);
         } elsif ($action eq 'defaults') {          } elsif ($action eq 'defaults') {
             $output .= &print_defaults($dom,\$rowtotal);              $output .= &print_defaults($dom,$settings,\$rowtotal);
         } elsif ($action eq 'scantron') {          } elsif ($action eq 'scantron') {
             $output .= &print_scantronformat($r,$dom,$confname,$settings,\$rowtotal);              $output .= &print_scantronformat($r,$dom,$confname,$settings,\$rowtotal);
         } elsif ($action eq 'serverstatuses') {          } elsif ($action eq 'serverstatuses') {
             $output .= &print_serverstatuses($dom,$settings,\$rowtotal);              $output .= &print_serverstatuses($dom,$settings,\$rowtotal);
         } elsif ($action eq 'helpsettings') {          } elsif ($action eq 'helpsettings') {
             $output .= &print_helpsettings('top',$dom,$confname,$settings,\$rowtotal);              $output .= &print_helpsettings($dom,$confname,$settings,\$rowtotal);
     } elsif ($action eq 'coursedefaults') {          } elsif ($action eq 'loadbalancing') {
             $output .= &print_coursedefaults($dom,$settings,\$rowtotal);              $output .= &print_loadbalancing($dom,$settings,\$rowtotal);
         }          }
     }      }
     $output .= '      $output .= '
Line 655  sub print_config_box { Line 815  sub print_config_box {
 }  }
   
 sub print_login {  sub print_login {
     my ($position,$dom,$confname,$phase,$settings,$rowtotal) = @_;      my ($caller,$dom,$confname,$phase,$settings,$rowtotal) = @_;
     my ($css_class,$datatable);      my ($css_class,$datatable);
     my %choices = &login_choices();      my %choices = &login_choices();
     my $itemcount = 1;  
   
     if ($position eq 'top') {      if ($caller eq 'service') {
         my %servers = &dom_servers($dom);          my %servers = &Apache::lonnet::internet_dom_servers($dom);
         my $choice = $choices{'disallowlogin'};          my $choice = $choices{'disallowlogin'};
         $css_class = ' class="LC_odd_row"';          $css_class = ' class="LC_odd_row"';
         $datatable .= '<tr'.$css_class.'><td>'.$choices{'disallowlogin'}.'</td>'.          $datatable .= '<tr'.$css_class.'><td>'.$choice.'</td>'.
                       '<td align="right"><table><tr><th>'.$choices{'hostid'}.'</th>'.                        '<td align="right"><table><tr><th>'.$choices{'hostid'}.'</th>'.
                       '<th>'.$choices{'serverurl'}.'</th></tr>'."\n";                        '<th>'.$choices{'server'}.'</th>'.
                         '<th>'.$choices{'serverpath'}.'</th>'.
                         '<th>'.$choices{'custompath'}.'</th>'.
                         '<th><span class="LC_nobreak">'.$choices{'exempt'}.'</span></th></tr>'."\n";
         my %disallowed;          my %disallowed;
         if (ref($settings) eq 'HASH') {          if (ref($settings) eq 'HASH') {
             if (ref($settings->{'loginvia'}) eq 'HASH') {              if (ref($settings->{'loginvia'}) eq 'HASH') {
Line 675  sub print_login { Line 837  sub print_login {
         }          }
         foreach my $lonhost (sort(keys(%servers))) {          foreach my $lonhost (sort(keys(%servers))) {
             my $direct = 'selected="selected"';              my $direct = 'selected="selected"';
             if ($disallowed{$lonhost} eq '') {              if (ref($disallowed{$lonhost}) eq 'HASH') {
                 $direct = '';                  if ($disallowed{$lonhost}{'server'} ne '') {
                       $direct = '';
                   }
             }              }
             $datatable .= '<tr><td>'.$servers{$lonhost}.'</td>'.              $datatable .= '<tr><td>'.$servers{$lonhost}.'</td>'.
                           '<td><select name="'.$lonhost.'_serverurl">'.                            '<td><select name="'.$lonhost.'_server">'.
                           '<option value=""'.$direct.'>'.$choices{'directlogin'}.                            '<option value=""'.$direct.'>'.$choices{'directlogin'}.
                           '</option>';                            '</option>';
             foreach my $hostid (keys(%servers)) {              foreach my $hostid (sort(keys(%servers))) {
                 next if ($servers{$hostid} eq $servers{$lonhost});                  next if ($servers{$hostid} eq $servers{$lonhost});
                 my $selected = '';                  my $selected = '';
                 if ($hostid eq $disallowed{$lonhost}) {                  if (ref($disallowed{$lonhost}) eq 'HASH') {
                     $selected = 'selected="selected"';                      if ($hostid eq $disallowed{$lonhost}{'server'}) {
                           $selected = 'selected="selected"';
                       }
                 }                  }
                 $datatable .= '<option value="'.$hostid.'"'.$selected.'>'.                  $datatable .= '<option value="'.$hostid.'"'.$selected.'>'.
                               $servers{$hostid}.'</option>';                                $servers{$hostid}.'</option>';
             }              }
             $datatable .= '</select></td></tr>';              $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>';          $datatable .= '</table></td></tr>';
         return $datatable;          return $datatable;
     }      } elsif ($caller eq 'page') {
           my %defaultchecked = ( 
     my %defaultchecked = (                                  'coursecatalog' => 'on',
                            'coursecatalog' => 'on',                                 'helpdesk'      => 'on',
                            'adminmail'     => 'off',                                 'adminmail'     => 'off',
                            'newuser'       => 'off',                                 'newuser'       => 'off',
                          );                               );
     my @toggles = ('coursecatalog','adminmail','newuser');          my @toggles = ('coursecatalog','adminmail','helpdesk','newuser');
     my (%checkedon,%checkedoff);          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 $loginheader = 'image';  
     my @images = ('img','logo','domlogo','login');  
     my @logintext = ('textcol','bgcol');  
     my @bgs = ('pgbg','mainbg','sidebg');  
     my @links = ('link','alink','vlink');  
     my %designhash = &Apache::loncommon::get_domainconf($dom);  
     my %defaultdesign = %Apache::loncommon::defaultdesign;  
     my (%is_custom,%designs);  
     my %defaults = (  
                    font => $defaultdesign{'login.font'},  
                    );  
     foreach my $item (@images) {  
         $defaults{$item} = $defaultdesign{'login.'.$item};  
         $defaults{'showlogo'}{$item} = 1;  
     }  
     foreach my $item (@bgs) {  
         $defaults{'bgs'}{$item} = $defaultdesign{'login.'.$item};  
     }  
     foreach my $item (@logintext) {  
         $defaults{'logintext'}{$item} = $defaultdesign{'login.'.$item};  
     }  
     foreach my $item (@links) {  
         $defaults{'links'}{$item} = $defaultdesign{'login.'.$item};  
     }  
     if (ref($settings) eq 'HASH') {  
         foreach my $item (@toggles) {          foreach my $item (@toggles) {
             if ($settings->{$item} eq '1') {              if ($defaultchecked{$item} eq 'on') { 
                 $checkedon{$item} =  ' checked="checked" ';                  $checkedon{$item} = ' checked="checked" ';
                 $checkedoff{$item} = ' ';                  $checkedoff{$item} = ' ';
             } elsif ($settings->{$item} eq '0') {              } elsif ($defaultchecked{$item} eq 'off') {
                 $checkedoff{$item} =  ' checked="checked" ';                  $checkedoff{$item} = ' checked="checked" ';
                 $checkedon{$item} = ' ';                  $checkedon{$item} = ' ';
             }              }
         }          }
           my @images = ('img','logo','domlogo','login');
           my @logintext = ('textcol','bgcol');
           my @bgs = ('pgbg','mainbg','sidebg');
           my @links = ('link','alink','vlink');
           my %designhash = &Apache::loncommon::get_domainconf($dom);
           my %defaultdesign = %Apache::loncommon::defaultdesign;
           my (%is_custom,%designs);
           my %defaults = (
                          font => $defaultdesign{'login.font'},
                          );
         foreach my $item (@images) {          foreach my $item (@images) {
             if (defined($settings->{$item})) {              $defaults{$item} = $defaultdesign{'login.'.$item};
                 $designs{$item} = $settings->{$item};              $defaults{'showlogo'}{$item} = 1;
                 $is_custom{$item} = 1;  
             }  
             if (defined($settings->{'showlogo'}{$item})) {  
                 $designs{'showlogo'}{$item} = $settings->{'showlogo'}{$item};  
             }  
         }          }
         foreach my $item (@logintext) {          foreach my $item (@bgs) {
             if ($settings->{$item} ne '') {              $defaults{'bgs'}{$item} = $defaultdesign{'login.'.$item};
                 $designs{'logintext'}{$item} = $settings->{$item};  
                 $is_custom{$item} = 1;  
             }  
         }          }
         if ($settings->{'loginheader'} ne '') {          foreach my $item (@logintext) {
             $loginheader = $settings->{'loginheader'};              $defaults{'logintext'}{$item} = $defaultdesign{'login.'.$item};
         }          }
         if ($settings->{'font'} ne '') {          foreach my $item (@links) {
             $designs{'font'} = $settings->{'font'};              $defaults{'links'}{$item} = $defaultdesign{'login.'.$item};
             $is_custom{'font'} = 1;  
         }          }
         foreach my $item (@bgs) {          if (ref($settings) eq 'HASH') {
             if ($settings->{$item} ne '') {              foreach my $item (@toggles) {
                 $designs{'bgs'}{$item} = $settings->{$item};                  if ($settings->{$item} eq '1') {
                 $is_custom{$item} = 1;                      $checkedon{$item} =  ' checked="checked" ';
                       $checkedoff{$item} = ' ';
                   } elsif ($settings->{$item} eq '0') {
                       $checkedoff{$item} =  ' checked="checked" ';
                       $checkedon{$item} = ' ';
                   }
             }              }
         }              foreach my $item (@images) {
         foreach my $item (@links) {                  if (defined($settings->{$item})) {
             if ($settings->{$item} ne '') {                      $designs{$item} = $settings->{$item};
                 $designs{'links'}{$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) {
     } else {                  if ($settings->{$item} ne '') {
         if ($designhash{$dom.'.login.font'} ne '') {                      $designs{'logintext'}{$item} = $settings->{$item};
             $designs{'font'} = $designhash{$dom.'.login.font'};                      $is_custom{$item} = 1;
             $is_custom{'font'} = 1;                  }
         }              }
         foreach my $item (@images) {              if ($settings->{'font'} ne '') {
             if ($designhash{$dom.'.login.'.$item} ne '') {                  $designs{'font'} = $settings->{'font'};
                 $designs{$item} = $designhash{$dom.'.login.'.$item};                  $is_custom{'font'} = 1;
                 $is_custom{$item} = 1;              }
               foreach my $item (@bgs) {
                   if ($settings->{$item} ne '') {
                       $designs{'bgs'}{$item} = $settings->{$item};
                       $is_custom{$item} = 1;
                   }
               }
               foreach my $item (@links) {
                   if ($settings->{$item} ne '') {
                       $designs{'links'}{$item} = $settings->{$item};
                       $is_custom{$item} = 1;
                   }
               }
           } else {
               if ($designhash{$dom.'.login.font'} ne '') {
                   $designs{'font'} = $designhash{$dom.'.login.font'};
                   $is_custom{'font'} = 1;
               }
               foreach my $item (@images) {
                   if ($designhash{$dom.'.login.'.$item} ne '') {
                       $designs{$item} = $designhash{$dom.'.login.'.$item};
                       $is_custom{$item} = 1;
                   }
               }
               foreach my $item (@bgs) {
                   if ($designhash{$dom.'.login.'.$item} ne '') {
                       $designs{'bgs'}{$item} = $designhash{$dom.'.login.'.$item};
                       $is_custom{$item} = 1;
                   }
               }
               foreach my $item (@links) {
                   if ($designhash{$dom.'.login.'.$item} ne '') {
                       $designs{'links'}{$item} = $designhash{$dom.'.login.'.$item};
                       $is_custom{$item} = 1;
                   }
             }              }
         }          }
         foreach my $item (@bgs) {          my %alt_text = &Apache::lonlocal::texthash  ( img => 'Log-in banner',
             if ($designhash{$dom.'.login.'.$item} ne '') {                                                        logo => 'Institution Logo',
                 $designs{'bgs'}{$item} = $designhash{$dom.'.login.'.$item};                                                        domlogo => 'Domain Logo',
                 $is_custom{$item} = 1;                                                        login => 'Login box');
           my $itemcount = 1;
           foreach my $item (@toggles) {
               $css_class = $itemcount%2?' class="LC_odd_row"':'';
               $datatable .=  
                   '<tr'.$css_class.'><td colspan="2">'.$choices{$item}.
                   '</td><td>'.
                   '<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 ++;
           }
           $datatable .= &display_color_options($dom,$confname,$phase,'login',$itemcount,\%choices,\%is_custom,\%defaults,\%designs,\@images,\@bgs,\@links,\%alt_text,$rowtotal,\@logintext);
           $datatable .= '</tr></table></td></tr>';
       } elsif ($caller eq 'help') {
           my ($defaulturl,$defaulttype,%url,%type,%lt,%langchoices);
           my $switchserver = &check_switchserver($dom,$confname);
           my $itemcount = 1;
           $defaulturl = '/adm/loginproblems.html';
           $defaulttype = 'default';
           %lt = &Apache::lonlocal::texthash (
                        del     => 'Delete?',
                        rep     => 'Replace:',
                        upl     => 'Upload:',
                        default => 'Default',
                        custom  => 'Custom',
                                                );
           %langchoices = &Apache::lonlocal::texthash(&get_languages_hash());
           my @currlangs;
           if (ref($settings) eq 'HASH') {
               if (ref($settings->{'helpurl'}) eq 'HASH') {
                   foreach my $key (sort(keys(%{$settings->{'helpurl'}}))) {
                       next if ($settings->{'helpurl'}{$key} eq '');
                       $url{$key} = $settings->{'helpurl'}{$key}.'?inhibitmenu=yes';
                       $type{$key} = 'custom';
                       unless ($key eq 'nolang') {
                           push(@currlangs,$key);
                       }
                   }
               } elsif ($settings->{'helpurl'} ne '') {
                   $type{'nolang'} = 'custom';
                   $url{'nolang'} = $settings->{'helpurl'}.'?inhibitmenu=yes';
               }
           }
           foreach my $lang ('nolang',sort(@currlangs)) {
               $css_class = $itemcount%2 ? ' class="LC_odd_row"' : '';
               $datatable .= '<tr'.$css_class.'>';
               if ($url{$lang} eq '') {
                   $url{$lang} = $defaulturl;
               }
               if ($type{$lang} eq '') {
                   $type{$lang} = $defaulttype;
               }
               $datatable .= '<td colspan="2"><span class="LC_nobreak">';
               if ($lang eq 'nolang') {
                   $datatable .= &mt('Log-in help page if no specific language file: [_1]',
                                     &Apache::loncommon::modal_link($url{$lang},$lt{$type{$lang}},600,500));
               } else {
                   $datatable .= &mt('Log-in help page for language: [_1] is [_2]',
                                     $langchoices{$lang},
                                     &Apache::loncommon::modal_link($url{$lang},$lt{$type{$lang}},600,500));
               }
               $datatable .= '</span></td>'."\n".
                             '<td class="LC_left_item">';
               if ($type{$lang} eq 'custom') {
                   $datatable .= '<span class="LC_nobreak"><label>'.
                                 '<input type="checkbox" name="loginhelpurl_del" value="'.$lang.'" />'.
                                 $lt{'del'}.'</label>&nbsp;'.$lt{'rep'}.'</span>';
               } else {
                   $datatable .= $lt{'upl'};
             }              }
               $datatable .='<br />';
               if ($switchserver) {
                   $datatable .= &mt('Upload to library server: [_1]',$switchserver);
               } else {
                   $datatable .= '<input type="file" name="loginhelpurl_'.$lang.'" />';
               }
               $datatable .= '</td></tr>';
               $itemcount ++;
         }          }
         foreach my $item (@links) {          my @addlangs;
             if ($designhash{$dom.'.login.'.$item} ne '') {          foreach my $lang (sort(keys(%langchoices))) {
                 $designs{'links'}{$item} = $designhash{$dom.'.login.'.$item};              next if ((grep(/^\Q$lang\E$/,@currlangs)) || ($lang eq 'x_chef'));
                 $is_custom{$item} = 1;              push(@addlangs,$lang);
           }
           if (@addlangs > 0) {
               my %toadd;
               map { $toadd{$_} = $langchoices{$_} ; } @addlangs;
               $toadd{''} = &mt('Select');
               $css_class = $itemcount%2 ? ' class="LC_odd_row"' : '';
               $datatable .= '<tr'.$css_class.'><td class="LC_left_item" colspan="2">'.
                             &mt('Add log-in help page for a specific language:').'&nbsp;'.
                             &Apache::loncommon::select_form('','loginhelpurl_add_lang',\%toadd).
                             '</td><td class="LC_left_item">'.$lt{'upl'}.'<br />';
               if ($switchserver) {
                   $datatable .= &mt('Upload to library server: [_1]',$switchserver);
               } else {
                   $datatable .= '<input type="file" name="loginhelpurl_add_file" />';
             }              }
               $datatable .= '</td></tr>';
               $itemcount ++;
         }          }
           $datatable .= &captcha_choice('login',$settings,$itemcount);
     }      }
     my %alt_text = &Apache::lonlocal::texthash  ( img => 'Log-in banner',  
                                                   logo => 'Institution Logo',  
                                                   domlogo => 'Domain Logo',  
                                                   login => 'Login box');  
     my $itemcount = 1;  
     my ($css_class,$datatable);  
     foreach my $item (@toggles) {  
         $css_class = $itemcount%2?' class="LC_odd_row"':'';  
         $datatable .=    
             '<tr'.$css_class.'><td colspan="2">'.$choices{$item}.  
             '</td><td>'.  
             '<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 ++;  
     }  
     $datatable .= &display_color_options($dom,$confname,$phase,'login',$itemcount,\%choices,\%is_custom,\%defaults,\%designs,\@images,\@bgs,\@links,\%alt_text,$rowtotal,\@logintext,$loginheader);  
     $datatable .= '</tr></table></td></tr>';  
     return $datatable;      return $datatable;
 }  }
   
Line 833  sub login_choices { Line 1109  sub login_choices {
         &Apache::lonlocal::texthash (          &Apache::lonlocal::texthash (
             coursecatalog => 'Display Course/Community Catalog link?',              coursecatalog => 'Display Course/Community Catalog link?',
             adminmail     => "Display Administrator's E-mail Address?",              adminmail     => "Display Administrator's E-mail Address?",
               helpdesk      => 'Display "Contact Helpdesk" link',
             disallowlogin => "Login page requests redirected",              disallowlogin => "Login page requests redirected",
             hostid        => "Server",              hostid        => "Server",
             serverurl     => "Redirect to log-in via:",              server        => "Redirect to:",
               serverpath    => "Path",
               custompath    => "Custom", 
               exempt        => "Exempt IP(s)",
             directlogin   => "No redirect",              directlogin   => "No redirect",
             newuser       => "Link to create a user account",              newuser       => "Link to create a user account",
             img           => "Header",              img           => "Header",
Line 867  sub print_rolecolors { Line 1147  sub print_rolecolors {
     my %designhash = &Apache::loncommon::get_domainconf($dom);      my %designhash = &Apache::loncommon::get_domainconf($dom);
     my %defaultdesign = %Apache::loncommon::defaultdesign;      my %defaultdesign = %Apache::loncommon::defaultdesign;
     my (%is_custom,%designs);      my (%is_custom,%designs);
     my %defaults = (      my %defaults = &role_defaults($role,\@bgs,\@links,\@images);
                    img => $defaultdesign{$role.'.img'},  
                    font => $defaultdesign{$role.'.font'},  
    fontmenu => $defaultdesign{$role.'.fontmenu'},  
                    );  
     foreach my $item (@bgs) {  
         $defaults{'bgs'}{$item} = $defaultdesign{$role.'.'.$item};  
     }  
     foreach my $item (@links) {  
         $defaults{'links'}{$item} = $defaultdesign{$role.'.'.$item};  
     }  
     if (ref($settings) eq 'HASH') {      if (ref($settings) eq 'HASH') {
         if (ref($settings->{$role}) eq 'HASH') {          if (ref($settings->{$role}) eq 'HASH') {
             if ($settings->{$role}->{'img'} ne '') {              if ($settings->{$role}->{'img'} ne '') {
Line 938  sub print_rolecolors { Line 1208  sub print_rolecolors {
     return $datatable;      return $datatable;
 }  }
   
   sub role_defaults {
       my ($role,$bgs,$links,$images,$logintext) = @_;
       my %defaults;
       unless ((ref($bgs) eq 'ARRAY') && (ref($links) eq 'ARRAY') && (ref($images) eq 'ARRAY')) {
           return %defaults;
       }
       my %defaultdesign = %Apache::loncommon::defaultdesign;
       if ($role eq 'login') {
           %defaults = (
                          font => $defaultdesign{$role.'.font'},
                       );
           if (ref($logintext) eq 'ARRAY') {
               foreach my $item (@{$logintext}) {
                   $defaults{'logintext'}{$item} = $defaultdesign{$role.'.'.$item};
               }
           }
           foreach my $item (@{$images}) {
               $defaults{'showlogo'}{$item} = 1;
           }
       } else {
           %defaults = (
                          img => $defaultdesign{$role.'.img'},
                          font => $defaultdesign{$role.'.font'},
                          fontmenu => $defaultdesign{$role.'.fontmenu'},
                       );
       }
       foreach my $item (@{$bgs}) {
           $defaults{'bgs'}{$item} = $defaultdesign{$role.'.'.$item};
       }
       foreach my $item (@{$links}) {
           $defaults{'links'}{$item} = $defaultdesign{$role.'.'.$item};
       }
       foreach my $item (@{$images}) {
           $defaults{$item} = $defaultdesign{$role.'.'.$item};
       }
       return %defaults;
   }
   
 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,$rowtotal,$logintext,$loginheader) = @_;          $images,$bgs,$links,$alt_text,$rowtotal,$logintext) = @_;
       my $londocroot = $Apache::lonnet::perlvar{'lonDocRoot'};
     my $css_class = $itemcount%2?' class="LC_odd_row"':'';      my $css_class = $itemcount%2?' class="LC_odd_row"':'';
     my $datatable = '<tr>'.      my $datatable = '<tr'.$css_class.'>'.
         '<td>'.$choices->{'font'}.'</td>';          '<td>'.$choices->{'font'}.'</td>';
     if (!$is_custom->{'font'}) {      if (!$is_custom->{'font'}) {
         $datatable .=  '<td>'.&mt('Default in use:').'&nbsp;<span id="css_default_'.$role.'_font" style="color: '.$defaults->{'font'}.';">'.$defaults->{'font'}.'</span></td>';          $datatable .=  '<td>'.&mt('Default in use:').'&nbsp;<span id="css_default_'.$role.'_font" style="color: '.$defaults->{'font'}.';">'.$defaults->{'font'}.'</span></td>';
     } else {      } else {
         $datatable .= '<td>&nbsp;</td>';          $datatable .= '<td>&nbsp;</td>';
     }      }
     my $fontlink = &color_pick($phase,$role,'font',$choices->{'font'},$designs->{'font'});      my $current_color = $designs->{'font'} ? $designs->{'font'} : $defaults->{'font'};
   
     $datatable .= '<td><span class="LC_nobreak">'.      $datatable .= '<td><span class="LC_nobreak">'.
                   '<input type="text" size="10" name="'.$role.'_font"'.                    '<input type="text" class="colorchooser" size="10" name="'.$role.'_font"'.
                   ' value="'.$designs->{'font'}.'" />&nbsp;'.$fontlink.                    ' value="'.$current_color.'" />&nbsp;'.
                   '&nbsp;<span id="css_'.$role.'_font" style="background-color: '.                    '&nbsp;</td></tr>';
                   $designs->{'font'}.';">&nbsp;&nbsp;&nbsp;</span>'.  
                   '</span></td></tr>';  
     unless ($role eq 'login') {       unless ($role eq 'login') { 
         $datatable .= '<tr'.$css_class.'>'.          $datatable .= '<tr'.$css_class.'>'.
                       '<td>'.$choices->{'fontmenu'}.'</td>';                        '<td>'.$choices->{'fontmenu'}.'</td>';
Line 964  sub display_color_options { Line 1272  sub display_color_options {
         } else {          } else {
             $datatable .= '<td>&nbsp;</td>';              $datatable .= '<td>&nbsp;</td>';
         }          }
         $fontlink = &color_pick($phase,$role,'fontmenu',$choices->{'fontmenu'},$designs->{'fontmenu'});   $current_color = $designs->{'fontmenu'} ?
       $designs->{'fontmenu'} : $defaults->{'fontmenu'};
         $datatable .= '<td><span class="LC_nobreak">'.          $datatable .= '<td><span class="LC_nobreak">'.
                       '<input type="text" size="10" name="'.$role.'_fontmenu"'.                        '<input class="colorchooser" type="text" size="10" name="'
                       ' value="'.$designs->{'fontmenu'}.'" />&nbsp;'.$fontlink.        .$role.'_fontmenu"'.
                       '&nbsp;<span id="css_'.$role.'_fontmenu" style="background-color: '.                        ' value="'.$current_color.'" />&nbsp;'.
                       $designs->{'fontmenu'}.';">&nbsp;&nbsp;&nbsp;</span>'.                        '&nbsp;</td></tr>';
                       '</span></td></tr>';  
     }      }
     my $switchserver = &check_switchserver($dom,$confname);      my $switchserver = &check_switchserver($dom,$confname);
     foreach my $img (@{$images}) {      foreach my $img (@{$images}) {
Line 982  sub display_color_options { Line 1290  sub display_color_options {
         if ($role eq 'login') {          if ($role eq 'login') {
             if ($img eq 'login') {              if ($img eq 'login') {
                 $login_hdr_pick =                  $login_hdr_pick =
                     &login_header_options($img,$role,$defaults,$is_custom,$choices,                      &login_header_options($img,$role,$defaults,$is_custom,$choices);
                                           $loginheader);  
                 $logincolors =                  $logincolors =
                     &login_text_colors($img,$role,$logintext,$phase,$choices,                      &login_text_colors($img,$role,$logintext,$phase,$choices,
                                             $designs);                                         $designs,$defaults);
             } elsif ($img ne 'domlogo') {              } elsif ($img ne 'domlogo') {
                 $datatable.= &logo_display_options($img,$defaults,$designs);                  $datatable.= &logo_display_options($img,$defaults,$designs);
             }              }
Line 1019  sub display_color_options { Line 1326  sub display_color_options {
                 $showfile = $imgfile;                  $showfile = $imgfile;
                 my $imgdir = $1;                  my $imgdir = $1;
                 my $filename = $2;                  my $filename = $2;
                 if (-e "/home/httpd/html/$imgdir/tn-".$filename) {                  if (-e "$londocroot/$imgdir/tn-".$filename) {
                     $showfile = "/$imgdir/tn-".$filename;                      $showfile = "/$imgdir/tn-".$filename;
                 } else {                  } else {
                     my $input = "/home/httpd/html".$imgfile;                      my $input = $londocroot.$imgfile;
                     my $output = '/home/httpd/html/'.$imgdir.'/tn-'.$filename;                      my $output = "$londocroot/$imgdir/tn-".$filename;
                     if (!-e $output) {                      if (!-e $output) {
                         my ($width,$height) = &thumb_dimensions();                          my ($width,$height) = &thumb_dimensions();
                         my ($fullwidth,$fullheight) = &check_dimensions($input);                          my ($fullwidth,$fullheight) = &check_dimensions($input);
Line 1031  sub display_color_options { Line 1338  sub display_color_options {
                             if ($fullwidth > $width && $fullheight > $height) {                               if ($fullwidth > $width && $fullheight > $height) { 
                                 my $size = $width.'x'.$height;                                  my $size = $width.'x'.$height;
                                 system("convert -sample $size $input $output");                                  system("convert -sample $size $input $output");
                                 $showfile = '/'.$imgdir.'/tn-'.$filename;                                  $showfile = "/$imgdir/tn-".$filename;
                             }                              }
                         }                          }
                     }                      }
Line 1060  sub display_color_options { Line 1367  sub display_color_options {
                 }                  }
                 $datatable .= '<td>';                  $datatable .= '<td>';
                 if ($img eq 'login') {                  if ($img eq 'login') {
                     $datatable .= $login_hdr_pick;                          $datatable .= $login_hdr_pick;
                 }                  } 
                 $datatable .= &image_changes($is_custom->{$img},$alt_text->{$img},$img_import,                  $datatable .= &image_changes($is_custom->{$img},$alt_text->{$img},$img_import,
                                              $showfile,$fullsize,$role,$img,$imgfile,$logincolors);                                               $showfile,$fullsize,$role,$img,$imgfile,$logincolors);
             } else {              } else {
                 $datatable .= '<td colspan="2" class="LC_right_item"><br />'.                  $datatable .= '<td>&nbsp;</td><td class="LC_left_item">'.
                               &mt('Upload:');                                &mt('Upload:').'<br />';
             }              }
         } else {          } else {
             $datatable .= '<td colspan="2" class="LC_right_item"><br />'.              $datatable .= '<td>&nbsp;</td><td class="LC_left_item">'.
                           &mt('Upload:');                            &mt('Upload:').'<br />';
         }          }
         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 1096  sub display_color_options { Line 1405  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 (@{$bgs}) {      foreach my $item (@{$bgs}) {
         my $link = &color_pick($phase,$role,$item,$choices->{$item},$designs->{'bgs'}{$item});          $datatable .= '<td align="center">'.$choices->{$item};
         $datatable .= '<td align="center">'.$link;   my $color = $designs->{'bgs'}{$item} ? $designs->{'bgs'}{$item} : $defaults->{'bgs'}{$item};
         if ($designs->{'bgs'}{$item}) {          if ($designs->{'bgs'}{$item}) {
             $datatable .= '&nbsp;<span id="css_'.$role.'_'.$item.'" style="background-color: '.$designs->{'bgs'}{$item}.';">&nbsp;&nbsp;&nbsp;</span>';              $datatable .= '&nbsp;';
         }          }
         $datatable .= '<br /><input type="text" size="8" name="'.$role.'_'.$item.'" value="'.$designs->{'bgs'}{$item}.          $datatable .= '<br /><input type="text" class="colorchooser" size="8" name="'.$role.'_'.$item.'" value="'.$color.
                       '" onblur = "javascript:colchg_span('."'css_".$role.'_'.$item."'".',this);" /></td>';                        '" onblur = "javascript:colchg_span('."'css_".$role.'_'.$item."'".',this);" /></td>';
     }      }
     $datatable .= '</tr></table></td></tr>';      $datatable .= '</tr></table></td></tr>';
Line 1124  sub display_color_options { Line 1434  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">'."\n".   my $color = $designs->{'link'}{$item} ? $designs->{'link'}{$item} : $defaults->{'links'}{$item};
                       &color_pick($phase,$role,$item,$choices->{$item},          $datatable .= '<td align="center">'.$choices->{$item}."\n";
                                   $designs->{'links'}{$item});  
         if ($designs->{'links'}{$item}) {          if ($designs->{'links'}{$item}) {
             $datatable.='&nbsp;<span id="css_'.$role.'_'.$item.'" style="background-color: '.$designs->{'links'}{$item}.';">&nbsp;&nbsp;&nbsp;</span>';              $datatable.='&nbsp;';
         }          }
         $datatable .= '<br /><input type="text" size="8" name="'.$role.'_'.$item.'" value="'.$designs->{'links'}{$item}.          $datatable .= '<br /><input type="text" size="8" class="colorchooser" name="'.$role.'_'.$item.'" value="'.$color.
                       '" /></td>';                        '" /></td>';
     }      }
     $$rowtotal += $itemcount;      $$rowtotal += $itemcount;
Line 1164  sub logo_display_options { Line 1473  sub logo_display_options {
 }  }
   
 sub login_header_options  {  sub login_header_options  {
     my ($img,$role,$defaults,$is_custom,$choices,$loginheader) = @_;      my ($img,$role,$defaults,$is_custom,$choices) = @_;
     my $image_checked = ' checked="checked" ';      my $output = '';
     my $text_checked = ' ';  
     if ($loginheader eq 'text') {  
         $image_checked = ' ';  
         $text_checked = ' checked="checked" ';  
     }  
     my $output = '<span class="LC_nobreak"><label><input type="radio" name="'.  
               'loginheader" value="image" '.$image_checked.'/>'.  
               &mt('use image').'</label>&nbsp;&nbsp;&nbsp;'.  
               '<label><input type="radio" name="loginheader" value="text"'.  
               $text_checked.'/>'.&mt('use text').'</label><br />'."\n";  
     if ((!$is_custom->{'textcol'}) || (!$is_custom->{'bgcol'})) {      if ((!$is_custom->{'textcol'}) || (!$is_custom->{'bgcol'})) {
         $output .= &mt('Text default(s)').':<br />';          $output .= &mt('Text default(s):').'<br />';
         if (!$is_custom->{'textcol'}) {          if (!$is_custom->{'textcol'}) {
             $output .= $choices->{'textcol'}.':&nbsp;'.$defaults->{'logintext'}{'textcol'}.              $output .= $choices->{'textcol'}.':&nbsp;'.$defaults->{'logintext'}{'textcol'}.
                        '&nbsp;&nbsp;&nbsp;';                         '&nbsp;&nbsp;&nbsp;';
Line 1194  sub login_header_options  { Line 1493  sub login_header_options  {
 }  }
   
 sub login_text_colors {  sub login_text_colors {
     my ($img,$role,$logintext,$phase,$choices,$designs) = @_;      my ($img,$role,$logintext,$phase,$choices,$designs,$defaults) = @_;
     my $color_menu = '<table border="0"><tr>';      my $color_menu = '<table border="0"><tr>';
     foreach my $item (@{$logintext}) {      foreach my $item (@{$logintext}) {
         my $link = &color_pick($phase,$role,$item,$choices->{$item},$designs->{'logintext'}{$item});          $color_menu .= '<td align="center">'.$choices->{$item};
         $color_menu .= '<td align="center">'.$link;          my $color = $designs->{'logintext'}{$item} ? $designs->{'logintext'}{$item} : $defaults->{'logintext'}{$item};
         if ($designs->{'logintext'}{$item}) {          $color_menu .= '<br /><input type="text" class="colorchooser" size="8" name="'.$role.'_'.$item.'" value="'.$color.
             $color_menu .= '&nbsp;<span id="css_'.$role.'_'.$item.'" style="background-color: '.$designs->{'logintext'}{$item}.';">&nbsp;&nbsp;&nbsp;</span>';                        '" onblur = "javascript:colchg_span('."'css_".$role.'_'.$item."'".',this);" /></td>';
         }  
         $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 />';      $color_menu .= '</tr></table><br />';
     return $color_menu;      return $color_menu;
Line 1213  sub login_text_colors { Line 1508  sub login_text_colors {
 sub image_changes {  sub image_changes {
     my ($is_custom,$alt_text,$img_import,$showfile,$fullsize,$role,$img,$imgfile,$logincolors) = @_;      my ($is_custom,$alt_text,$img_import,$showfile,$fullsize,$role,$img,$imgfile,$logincolors) = @_;
     my $output;      my $output;
     if (!$is_custom) {      if ($img eq 'login') {
               # suppress image for Log-in header
       } elsif (!$is_custom) {
         if ($img ne 'domlogo') {          if ($img ne 'domlogo') {
             $output .= &mt('Default image:').'<br />';              $output .= &mt('Default image:').'<br />';
         } else {          } else {
             $output .= &mt('Default in use:').'<br />';              $output .= &mt('Default in use:').'<br />';
         }          }
     }      }
     if ($img_import) {      if ($img eq 'login') { # suppress image for Log-in header
         $output .= '<input type="hidden" name="'.$role.'_import_'.$img.'" value="'.$imgfile.'" />';          $output .= '<td>'.$logincolors;
     }  
     $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 {      } else {
         $output .= '<td valign="bottom">'.$logincolors.&mt('Upload:').'<br />';          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="middle">'.$logincolors.&mt('Upload:').'<br />';
           }
     }      }
     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,$rowtotal,$action) = @_;      my ($dom,$settings,$rowtotal,$action) = @_;
     my $context;      my $context;
Line 1252  sub print_quotas { Line 1545  sub print_quotas {
     } else {      } else {
         $context = $action;          $context = $action;
     }      }
     my ($datatable,$defaultquota,@usertools,@options,%validations);      my ($datatable,$defaultquota,$authorquota,@usertools,@options,%validations);
     my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom);      my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom);
     my $typecount = 0;      my $typecount = 0;
     my ($css_class,%titles);      my ($css_class,%titles);
Line 1261  sub print_quotas { Line 1554  sub print_quotas {
         @options =('norequest','approval','validate','autolimit');          @options =('norequest','approval','validate','autolimit');
         %validations = &Apache::lonnet::auto_courserequest_checks($dom);          %validations = &Apache::lonnet::auto_courserequest_checks($dom);
         %titles = &courserequest_titles();          %titles = &courserequest_titles();
       } elsif ($context eq 'requestauthor') {
           @usertools = ('author');
           @options = ('norequest','approval','automatic');
           %titles = &authorrequest_titles();
     } else {      } else {
         @usertools = ('aboutme','blog','portfolio');          @usertools = ('aboutme','blog','webdav','portfolio');
         %titles = &tool_titles();          %titles = &tool_titles();
     }      }
     if (ref($types) eq 'ARRAY') {      if (ref($types) eq 'ARRAY') {
         foreach my $type (@{$types}) {          foreach my $type (@{$types}) {
             my $currdefquota;              my ($currdefquota,$currauthorquota);
             unless ($context eq 'requestcourses') {              unless (($context eq 'requestcourses') ||
                       ($context eq 'requestauthor')) {
                 if (ref($settings) eq 'HASH') {                  if (ref($settings) eq 'HASH') {
                     if (ref($settings->{defaultquota}) eq 'HASH') {                      if (ref($settings->{defaultquota}) eq 'HASH') {
                         $currdefquota = $settings->{defaultquota}->{$type};                           $currdefquota = $settings->{defaultquota}->{$type};
                     } else {                      } else {
                         $currdefquota = $settings->{$type};                          $currdefquota = $settings->{$type};
                     }                      }
                       if (ref($settings->{authorquota}) eq 'HASH') {
                           $currauthorquota = $settings->{authorquota}->{$type};
                       }
                 }                  }
             }              }
             if (defined($usertypes->{$type})) {              if (defined($usertypes->{$type})) {
Line 1327  sub print_quotas { Line 1628  sub print_quotas {
                             $cell{$item} .= '<span class="LC_nobreak"><label>'.                              $cell{$item} .= '<span class="LC_nobreak"><label>'.
                                   '<input type="radio" name="crsreq_'.$item.                                    '<input type="radio" name="crsreq_'.$item.
                                   '_'.$type.'" value="'.$val.'"'.$checked.' />'.                                    '_'.$type.'" value="'.$val.'"'.$checked.' />'.
                                   $titles{$option}.'</label>&nbsp;';                                    $titles{$option}.'</label>';
                             if ($option eq 'autolimit') {                              if ($option eq 'autolimit') {
                                 $cell{$item} .= '<input type="text" name="crsreq_'.                                  $cell{$item} .= '&nbsp;<input type="text" name="crsreq_'.
                                                 $item.'_limit_'.$type.'" size="1" '.                                                  $item.'_limit_'.$type.'" size="1" '.
                                                 'value="'.$currlimit.'" />';                                                  'value="'.$currlimit.'" />';
                             }                              }
                             $cell{$item} .= '</span>&nbsp; ';                              $cell{$item} .= '</span> ';
                             if ($option eq 'autolimit') {                              if ($option eq 'autolimit') {
                                 $cell{$item} .= $titles{'unlimited'}                                  $cell{$item} .= $titles{'unlimited'};
                               }
                           }
                       } elsif ($context eq 'requestauthor') {
                           my $curroption;
                           if (ref($settings) eq 'HASH') {
                               $curroption = $settings->{$type};
                           }
                           if (!$curroption) {
                               $curroption = 'norequest';
                           }
                           foreach my $option (@options) {
                               my $val = $option;
                               if ($option eq 'norequest') {
                                   $val = 0;
                               }
                               my $checked = '';
                               if ($option eq $curroption) {
                                   $checked = ' checked="checked"';
                             }                              }
                               $datatable .= '<span class="LC_nobreak"><label>'.
                                     '<input type="radio" name="authorreq_'.$type.
                                     '" value="'.$val.'"'.$checked.' />'.
                                     $titles{$option}.'</label></span>&nbsp; ';
                         }                          }
                     } else {                      } else {
                         my $checked = 'checked="checked" ';                          my $checked = 'checked="checked" ';
Line 1363  sub print_quotas { Line 1686  sub print_quotas {
                     $datatable .= '</tr></table>';                      $datatable .= '</tr></table>';
                 }                  }
                 $datatable .= '</td>';                  $datatable .= '</td>';
                 unless ($context eq 'requestcourses') {                  unless (($context eq 'requestcourses') ||
                           ($context eq 'requestauthor')) {
                     $datatable .=                       $datatable .= 
                               '<td class="LC_right_item"><span class="LC_nobreak">'.                                '<td class="LC_right_item">'.
                                 '<span class="LC_nobreak">'.&mt('Portfolio').':&nbsp;'.
                               '<input type="text" name="quota_'.$type.                                '<input type="text" name="quota_'.$type.
                               '" value="'.$currdefquota.                                '" value="'.$currdefquota.
                               '" size="5" /> Mb</span></td>';                                '" size="5" /></span>'.('&nbsp;' x 2).
                                 '<span class="LC_nobreak">'.&mt('Authoring').':&nbsp;'.
                                 '<input type="text" name="authorquota_'.$type.
                                 '" value="'.$currauthorquota.
                                 '" size="5" /></span></td>';
                 }                  }
                 $datatable .= '</tr>';                  $datatable .= '</tr>';
             }              }
         }          }
     }      }
     unless ($context eq 'requestcourses') {      unless (($context eq 'requestcourses') || ($context eq 'requestauthor')) {
         $defaultquota = '20';          $defaultquota = '20';
           $authorquota = '500';
         if (ref($settings) eq 'HASH') {          if (ref($settings) eq 'HASH') {
             if (ref($settings->{'defaultquota'}) eq 'HASH') {              if (ref($settings->{'defaultquota'}) eq 'HASH') {
                 $defaultquota = $settings->{'defaultquota'}->{'default'};                  $defaultquota = $settings->{'defaultquota'}->{'default'};
             } elsif (defined($settings->{'default'})) {              } elsif (defined($settings->{'default'})) {
                 $defaultquota = $settings->{'default'};                  $defaultquota = $settings->{'default'};
             }              }
               if (ref($settings->{'authorquota'}) eq 'HASH') {
                   $authorquota = $settings->{'authorquota'}->{'default'};
               }
         }          }
     }      }
     $typecount ++;      $typecount ++;
Line 1435  sub print_quotas { Line 1768  sub print_quotas {
                                   '_default" value="'.$val.'"'.$checked.' />'.                                    '_default" value="'.$val.'"'.$checked.' />'.
                                   $titles{$option}.'</label>';                                    $titles{$option}.'</label>';
                 if ($option eq 'autolimit') {                  if ($option eq 'autolimit') {
                     $defcell{$item} .= '<input type="text" name="crsreq_'.                      $defcell{$item} .= '&nbsp;<input type="text" name="crsreq_'.
                                        $item.'_limit_default" size="1" '.                                         $item.'_limit_default" size="1" '.
                                        'value="'.$currlimit.'" />';                                         'value="'.$currlimit.'" />';
                 }                  }
                 $defcell{$item} .= '</span>&nbsp; ';                  $defcell{$item} .= '</span> ';
                 if ($option eq 'autolimit') {                  if ($option eq 'autolimit') {
                     $defcell{$item} .= $titles{'unlimited'}                      $defcell{$item} .= $titles{'unlimited'};
                 }                  }
             }              }
           } elsif ($context eq 'requestauthor') {
               my $curroption;
               if (ref($settings) eq 'HASH') {
                   $curroption = $settings->{'default'};
               }
               if (!$curroption) {
                   $curroption = 'norequest';
               }
               foreach my $option (@options) {
                   my $val = $option;
                   if ($option eq 'norequest') {
                       $val = 0;
                   }
                   my $checked = '';
                   if ($option eq $curroption) {
                       $checked = ' checked="checked"';
                   }
                   $datatable .= '<span class="LC_nobreak"><label>'.
                                 '<input type="radio" name="authorreq_default"'.
                                 ' value="'.$val.'"'.$checked.' />'.
                                 $titles{$option}.'</label></span>&nbsp; ';
               }
         } else {          } else {
             my $checked = 'checked="checked" ';              my $checked = 'checked="checked" ';
             if (ref($settings) eq 'HASH') {              if (ref($settings) eq 'HASH') {
Line 1469  sub print_quotas { Line 1824  sub print_quotas {
         $datatable .= '</tr></table>';          $datatable .= '</tr></table>';
     }      }
     $datatable .= '</td>';      $datatable .= '</td>';
     unless ($context eq 'requestcourses') {      unless (($context eq 'requestcourses') || ($context eq 'requestauthor')) {
         $datatable .= '<td class="LC_right_item"><span class="LC_nobreak">'.          $datatable .= '<td class="LC_right_item">'.
                         '<span class="LC_nobreak">'.&mt('Portfolio').':&nbsp;'.
                       '<input type="text" name="defaultquota" value="'.                        '<input type="text" name="defaultquota" value="'.
                       $defaultquota.'" size="5" /> Mb</span></td>';                        $defaultquota.'" size="5" /></span>'.('&nbsp;' x2).
                         '<span class="LC_nobreak">'.&mt('Authoring').':&nbsp;'.
                         '<input type="text" name="authorquota" value="'.
                         $authorquota.'" size="5" /></span></td>';
     }      }
     $datatable .= '</tr>';      $datatable .= '</tr>';
     $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>'.&mt('LON-CAPA Advanced Users').' ';                    '<td>'.&mt('LON-CAPA Advanced Users').'<br />';
     if ($context eq 'requestcourses') {      if ($context eq 'requestcourses') {
         $datatable .= &mt('(overrides affiliation, if set)').          $datatable .= &mt('(overrides affiliation, if set)').
                       '</td>'.                        '</td>'.
Line 1538  sub print_quotas { Line 1897  sub print_quotas {
                                   '__LC_adv" value="'.$val.'"'.$checked.' />'.                                    '__LC_adv" value="'.$val.'"'.$checked.' />'.
                                   $titles{$option}.'</label>';                                    $titles{$option}.'</label>';
                 if ($option eq 'autolimit') {                  if ($option eq 'autolimit') {
                     $advcell{$item} .= '<input type="text" name="crsreq_'.                      $advcell{$item} .= '&nbsp;<input type="text" name="crsreq_'.
                                        $item.'_limit__LC_adv" size="1" '.                                         $item.'_limit__LC_adv" size="1" '.
                                        'value="'.$currlimit.'" />';                                         'value="'.$currlimit.'" />';
                 }                  }
                 $advcell{$item} .= '</span>&nbsp; ';                  $advcell{$item} .= '</span> ';
                 if ($option eq 'autolimit') {                  if ($option eq 'autolimit') {
                     $advcell{$item} .= $titles{'unlimited'}                      $advcell{$item} .= $titles{'unlimited'};
                   }
               }
           } elsif ($context eq 'requestauthor') {
               my $curroption;
               if (ref($settings) eq 'HASH') {
                   $curroption = $settings->{'_LC_adv'};
               }
               my $checked = '';
               if ($curroption eq '') {
                   $checked = ' checked="checked"';
               }
               $datatable .= '<span class="LC_nobreak"><label>'.
                             '<input type="radio" name="authorreq__LC_adv"'.
                             ' value=""'.$checked.' />'.
                             &mt('No override set').'</label></span>&nbsp; ';
               foreach my $option (@options) {
                   my $val = $option;
                   if ($option eq 'norequest') {
                       $val = 0;
                   }
                   my $checked = '';
                   if ($val eq $curroption) {
                       $checked = ' checked="checked"';
                 }                  }
                   $datatable .= '<span class="LC_nobreak"><label>'.
                                 '<input type="radio" name="authorreq__LC_adv"'.
                                 ' value="'.$val.'"'.$checked.' />'.
                                 $titles{$option}.'</label></span>&nbsp; ';
             }              }
         } else {          } else {
             my $checked = 'checked="checked" ';              my $checked = 'checked="checked" ';
Line 1576  sub print_quotas { Line 1962  sub print_quotas {
     return $datatable;      return $datatable;
 }  }
   
 sub print_courserequestmail {  sub print_requestmail {
     my ($dom,$settings,$rowtotal) = @_;      my ($dom,$action,$settings,$rowtotal) = @_;
     my ($now,$datatable,%dompersonnel,@domcoord,@currapproval,$rows);      my ($now,$datatable,%currapp);
     $now = time;      $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) eq 'HASH') {
         if (ref($settings->{'notify'}) eq 'HASH') {          if (ref($settings->{'notify'}) eq 'HASH') {
             if ($settings->{'notify'}{'approval'} ne '') {              if ($settings->{'notify'}{'approval'} ne '') {
                @currapproval = split(',',$settings->{'notify'}{'approval'});                 map {$currapp{$_}=1;} split(/,/,$settings->{'notify'}{'approval'});
             }  
         }  
     }  
     if (@currapproval) {  
         foreach my $dc (@currapproval) {  
             unless (grep(/^\Q$dc\E$/,@domcoord)) {  
                 push(@domcoord,$dc);  
             }              }
         }          }
     }      }
     @domcoord = sort(@domcoord);      my $numinrow = 2;
     my $numinrow = 4;  
     my $numdc = @domcoord;  
     my $css_class = 'class="LC_odd_row"';      my $css_class = 'class="LC_odd_row"';
     $datatable = '<tr'.$css_class.'>'.      my $text;
                  ' <td>'.&mt('Receive notification of course requests requiring approval.').      if ($action eq 'requestcourses') {
                  ' </td>'.          $text = &mt('Receive notification of course requests requiring approval');
       } else {
           $text = &mt('Receive notification of authoring space requests requiring approval')
       }
       $datatable = '<tr '.$css_class.'>'.
                    ' <td>'.$text.'</td>'.
                  ' <td class="LC_left_item">';                   ' <td class="LC_left_item">';
     if (@domcoord > 0) {      my ($numdc,$table,$rows) = &active_dc_picker($dom,$numinrow,'checkbox',
         $datatable .= '<table>';                                                   'reqapprovalnotify',%currapp);
         for (my $i=0; $i<$numdc; $i++) {      if ($numdc > 0) {
             my $rem = $i%($numinrow);          $datatable .= $table;
             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 {      } else {
         $datatable .= &mt('There are no active Domain Coordinators');          $datatable .= &mt('There are no active Domain Coordinators');
         $rows ++;  
     }      }
     $datatable .='</td></tr>';      $datatable .='</td></tr>';
     $$rowtotal += $rows;      $$rowtotal += $rows;
Line 1657  sub print_courserequestmail { Line 1999  sub print_courserequestmail {
 sub print_autoenroll {  sub print_autoenroll {
     my ($dom,$settings,$rowtotal) = @_;      my ($dom,$settings,$rowtotal) = @_;
     my $autorun = &Apache::lonnet::auto_run(undef,$dom),      my $autorun = &Apache::lonnet::auto_run(undef,$dom),
     my ($defdom,$runon,$runoff);      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 1676  sub print_autoenroll { Line 2018  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 1706  sub print_autoenroll { Line 2060  sub print_autoenroll {
                   &mt('username').':&nbsp;'.                    &mt('username').':&nbsp;'.
                   '<input type="text" name="sender_uname" value="'.                    '<input type="text" name="sender_uname" value="'.
                   $notif_sender.'" size="10" />&nbsp;&nbsp;'.&mt('domain').                    $notif_sender.'" size="10" />&nbsp;&nbsp;'.&mt('domain').
                   ':&nbsp;'.$domform.'</span></td></tr>';                    ':&nbsp;'.$domform.'</span></td></tr>'.
     $$rowtotal += 2;                    '<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;
 }  }
   
Line 1749  sub print_autoupdate { Line 2111  sub print_autoupdate {
                   $classlistsoff.'value="0" />'.&mt('No').'</label></span></td>'.                    $classlistsoff.'value="0" />'.&mt('No').'</label></span></td>'.
                   '</tr>';                    '</tr>';
         $$rowtotal += 2;          $$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) = &Apache::loncommon::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::loncommon::personal_data_fieldtitles();          my %fieldtitles = &Apache::loncommon::personal_data_fieldtitles();
         my $numrows = 0;          my $numrows = 0;
Line 1774  sub print_autoupdate { Line 2144  sub print_autoupdate {
   
 sub print_autocreate {  sub print_autocreate {
     my ($dom,$settings,$rowtotal) = @_;      my ($dom,$settings,$rowtotal) = @_;
     my (%createon,%createoff);      my (%createon,%createoff,%currhash);
     my $curr_dc;  
     my @types = ('xml','req');      my @types = ('xml','req');
     if (ref($settings) eq 'HASH') {      if (ref($settings) eq 'HASH') {
         foreach my $item (@types) {          foreach my $item (@types) {
Line 1788  sub print_autocreate { Line 2157  sub print_autocreate {
                 }                  }
             }              }
         }          }
         $curr_dc = $settings->{'xmldc'};          if ($settings->{'xmldc'} ne '') {
               $currhash{$settings->{'xmldc'}} = 1;
           }
     } else {      } else {
         foreach my $item (@types) {          foreach my $item (@types) {
             $createoff{$item} = ' checked="checked" ';              $createoff{$item} = ' checked="checked" ';
Line 1796  sub print_autocreate { Line 2167  sub print_autocreate {
         }          }
     }      }
     $$rowtotal += 2;      $$rowtotal += 2;
       my $numinrow = 2;
     my $datatable='<tr class="LC_odd_row">'.      my $datatable='<tr class="LC_odd_row">'.
                   '<td>'.&mt('Create pending official courses from XML files').'</td>'.                    '<td>'.&mt('Create pending official courses from XML files').'</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="autocreate_xml"'.                    '<input type="radio" name="autocreate_xml"'.
                   $createon{'xml'}.' value="1" />'.&mt('Yes').'</label>&nbsp;'.                    $createon{'xml'}.' value="1" />'.&mt('Yes').'</label>&nbsp;'.
                   '<label><input type="radio" name="autocreate_xml"'.                    '<label><input type="radio" name="autocreate_xml"'.
                   $createoff{'xml'}.' value="0" />'.&mt('No').'</label></span>';                    $createoff{'xml'}.' value="0" />'.&mt('No').'</label></span>'.
     my ($numdc,$dctable) = &active_dc_picker($dom,$curr_dc);                    '</td></tr><tr>'.
     if ($numdc > 1) {                    '<td>'.&mt('Create pending requests for official courses (if validated)').'</td>'.
         $datatable .= '</td><tr><td>'.  
                       &mt('XML files processed as: (choose Dom. Coord.)').   
                       '</td><td class="LC_left_item">'.$dctable.'</td></tr>'.  
                       '<tr class="LC_odd_row">';  
         $$rowtotal ++ ;  
     } else {  
         $datatable .= '</td></tr><tr>';  
     }  
     $datatable .= '<td>'.&mt('Create pending requests for official courses (if validated)').'</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="autocreate_req"'.                    '<input type="radio" name="autocreate_req"'.
                   $createon{'req'}.' value="1" />'.&mt('Yes').'</label>&nbsp;'.                    $createon{'req'}.' value="1" />'.&mt('Yes').'</label>&nbsp;'.
                   '<label><input type="radio" name="autocreate_req"'.                    '<label><input type="radio" name="autocreate_req"'.
                   $createoff{'req'}.' value="0" />'.&mt('No').'</label></span></td>'.                    $createoff{'req'}.' value="0" />'.&mt('No').'</label></span>';
                   '</tr>';      my ($numdc,$dctable,$rows) = &active_dc_picker($dom,$numinrow,'radio',
                                                      'autocreate_xmldc',%currhash);
       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>';
       } else {
           $datatable .= $dctable.'</td></tr>';
       }
       $$rowtotal += $rows;
     return $datatable;      return $datatable;
 }  }
   
Line 1940  sub print_contacts { Line 2312  sub print_contacts {
     my ($dom,$settings,$rowtotal) = @_;      my ($dom,$settings,$rowtotal) = @_;
     my $datatable;      my $datatable;
     my @contacts = ('adminemail','supportemail');      my @contacts = ('adminemail','supportemail');
     my (%checked,%to,%otheremails);      my (%checked,%to,%otheremails,%bccemails);
     my @mailings = ('errormail','packagesmail','lonstatusmail','helpdeskmail',      my @mailings = ('errormail','packagesmail','lonstatusmail','helpdeskmail',
                     'requestsmail');                      'requestsmail','updatesmail','idconflictsmail');
     foreach my $type (@mailings) {      foreach my $type (@mailings) {
         $otheremails{$type} = '';          $otheremails{$type} = '';
     }      }
       $bccemails{'helpdeskmail'} = '';
     if (ref($settings) eq 'HASH') {      if (ref($settings) eq 'HASH') {
         foreach my $item (@contacts) {          foreach my $item (@contacts) {
             if (exists($settings->{$item})) {              if (exists($settings->{$item})) {
Line 1961  sub print_contacts { Line 2334  sub print_contacts {
                         }                          }
                     }                      }
                     $otheremails{$type} = $settings->{$type}{'others'};                      $otheremails{$type} = $settings->{$type}{'others'};
                       if ($type eq 'helpdeskmail') {
                           $bccemails{$type} = $settings->{$type}{'bcc'};
                       }
                 }                  }
             } elsif ($type eq 'lonstatusmail') {              } elsif ($type eq 'lonstatusmail') {
                 $checked{'lonstatusmail'}{'adminemail'} = ' checked="checked" ';                  $checked{'lonstatusmail'}{'adminemail'} = ' checked="checked" ';
Line 1974  sub print_contacts { Line 2350  sub print_contacts {
         $checked{'helpdeskmail'}{'supportemail'} = ' checked="checked" ';          $checked{'helpdeskmail'}{'supportemail'} = ' checked="checked" ';
         $checked{'lonstatusmail'}{'adminemail'} = ' checked="checked" ';           $checked{'lonstatusmail'}{'adminemail'} = ' checked="checked" '; 
         $checked{'requestsmail'}{'adminemail'} = ' checked="checked" ';          $checked{'requestsmail'}{'adminemail'} = ' checked="checked" ';
           $checked{'updatesmail'}{'adminemail'} = ' checked="checked" ';
           $checked{'idconflictsmail'}{'adminemail'} = ' checked="checked" ';
     }      }
     my ($titles,$short_titles) = &contact_titles();      my ($titles,$short_titles) = &contact_titles();
     my $rownum = 0;      my $rownum = 0;
     my $css_class;      my $css_class;
     foreach my $item (@contacts) {      foreach my $item (@contacts) {
         $rownum ++;  
         $css_class = $rownum%2?' class="LC_odd_row"':'';          $css_class = $rownum%2?' class="LC_odd_row"':'';
         $datatable .= '<tr'.$css_class.'>'.           $datatable .= '<tr'.$css_class.'>'. 
                   '<td><span class="LC_nobreak">'.$titles->{$item}.                    '<td><span class="LC_nobreak">'.$titles->{$item}.
                   '</span></td><td class="LC_right_item">'.                    '</span></td><td class="LC_right_item">'.
                   '<input type="text" name="'.$item.'" value="'.                    '<input type="text" name="'.$item.'" value="'.
                   $to{$item}.'" /></td></tr>';                    $to{$item}.'" /></td></tr>';
           $rownum ++;
     }      }
     foreach my $type (@mailings) {      foreach my $type (@mailings) {
         $rownum ++;  
         $css_class = $rownum%2?' class="LC_odd_row"':'';          $css_class = $rownum%2?' class="LC_odd_row"':'';
         $datatable .= '<tr'.$css_class.'>'.          $datatable .= '<tr'.$css_class.'>'.
                       '<td><span class="LC_nobreak">'.                        '<td><span class="LC_nobreak">'.
Line 2004  sub print_contacts { Line 2381  sub print_contacts {
         }          }
         $datatable .= '</span><br />'.&mt('Others').':&nbsp;&nbsp;'.          $datatable .= '</span><br />'.&mt('Others').':&nbsp;&nbsp;'.
                       '<input type="text" name="'.$type.'_others" '.                        '<input type="text" name="'.$type.'_others" '.
                       'value="'.$otheremails{$type}.'"  />'.                        'value="'.$otheremails{$type}.'"  />';
                       '</td></tr>'."\n";          if ($type eq 'helpdeskmail') {
               $datatable .= '<br />'.&mt('Bcc:').('&nbsp;'x6).
                             '<input type="text" name="'.$type.'_bcc" '.
                             'value="'.$bccemails{$type}.'"  />';
           }
           $datatable .= '</td></tr>'."\n";
           $rownum ++;
     }      }
       my %choices;
       $choices{'reporterrors'} = &mt('E-mail error reports to [_1]',
                                      &Apache::loncommon::modal_link('http://loncapa.org/core.html',
                                      &mt('LON-CAPA core group - MSU'),600,500));
       $choices{'reportupdates'} = &mt('E-mail record of completed LON-CAPA updates to [_1]',
                                       &Apache::loncommon::modal_link('http://loncapa.org/core.html',
                                       &mt('LON-CAPA core group - MSU'),600,500));
       my @toggles = ('reporterrors','reportupdates');
       my %defaultchecked = ('reporterrors'  => 'on',
                             'reportupdates' => 'on');
       (my $reports,$rownum) = &radiobutton_prefs($settings,\@toggles,\%defaultchecked,
                                                  \%choices,$rownum);
       $datatable .= $reports;
     $$rowtotal += $rownum;      $$rowtotal += $rownum;
     return $datatable;      return $datatable;
 }  }
   
 sub print_helpsettings {  sub print_helpsettings {
       my ($dom,$confname,$settings,$rowtotal) = @_;
       my ($datatable,$itemcount);
       $itemcount = 1;
       my (%choices,%defaultchecked,@toggles);
       $choices{'submitbugs'} = &mt('Display link to: [_1]?',
                                    &Apache::loncommon::modal_link('http://bugs.loncapa.org',
                                    &mt('LON-CAPA bug tracker'),600,500));
       %defaultchecked = ('submitbugs' => 'on');
       @toggles = ('submitbugs',);
   
  my ($position,$dom,$confname,$settings,$rowtotal) = @_;      ($datatable,$itemcount) = &radiobutton_prefs($settings,\@toggles,\%defaultchecked,
  my ($css_class,$datatable);                                                   \%choices,$itemcount);
       return $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 {  sub radiobutton_prefs {
     my ($settings,$toggles,$defaultchecked,$choices,$itemcount) = @_;      my ($settings,$toggles,$defaultchecked,$choices,$itemcount,$onclick,
           $additional) = @_;
     return unless ((ref($toggles) eq 'ARRAY') && (ref($defaultchecked) eq 'HASH') &&      return unless ((ref($toggles) eq 'ARRAY') && (ref($defaultchecked) eq 'HASH') &&
                    (ref($choices) eq 'HASH'));                     (ref($choices) eq 'HASH'));
   
Line 2132  sub radiobutton_prefs { Line 2451  sub radiobutton_prefs {
             }              }
         }          }
     }      }
       if ($onclick) {
           $onclick = ' onclick="'.$onclick.'"';
       }
     foreach my $item (@{$toggles}) {      foreach my $item (@{$toggles}) {
         $css_class = $itemcount%2?' class="LC_odd_row"':'';          $css_class = $itemcount%2?' class="LC_odd_row"':'';
         $datatable .=          $datatable .=
             '<tr'.$css_class.'><td><span class="LC_nobreak">'.$choices->{$item}.              '<tr'.$css_class.'><td valign="top">'.
               '<span class="LC_nobreak">'.$choices->{$item}.
             '</span></td>'.              '</span></td>'.
             '<td class="LC_right_item"><span class="LC_nobreak">'.              '<td class="LC_right_item"><span class="LC_nobreak">'.
             '<label><input type="radio" name="'.              '<label><input type="radio" name="'.
             $item.'" '.$checkedon{$item}.' value="1" />'.&mt('Yes').              $item.'" '.$checkedon{$item}.' value="1"'.$onclick.' />'.&mt('Yes').
             '</label>&nbsp;<label><input type="radio" name="'.$item.'" '.              '</label>&nbsp;<label><input type="radio" name="'.$item.'" '.
             $checkedoff{$item}.' value="0" />'.&mt('No').'</label>'.              $checkedoff{$item}.' value="0"'.$onclick.' />'.&mt('No').'</label>'.
             '</span></td>'.              '</span>'.$additional.
               '</td>'.
             '</tr>';              '</tr>';
         $itemcount ++;          $itemcount ++;
     }      }
Line 2150  sub radiobutton_prefs { Line 2474  sub radiobutton_prefs {
 }  }
   
 sub print_coursedefaults {  sub print_coursedefaults {
     my ($dom,$settings,$rowtotal) = @_;      my ($position,$dom,$settings,$rowtotal) = @_;
     my ($css_class,$datatable);      my ($css_class,$datatable,%checkedon,%checkedoff,%defaultchecked,@toggles);
     my $itemcount = 1;      my $itemcount = 1;
     my (%checkedon,%checkedoff,%choices,%defaultchecked,@toggles);      my %choices =  &Apache::lonlocal::texthash (
     %choices =          canuse_pdfforms      => 'Course/Community users can create/upload PDF forms',
         &Apache::lonlocal::texthash (          uploadquota          => 'Default quota for files uploaded directly to course/community using Course Editor (MB)',
             canuse_pdfforms => 'Course/Community users can create/upload PDF forms',          anonsurvey_threshold => 'Responder count needed before showing submissions for anonymous surveys',
           coursecredits        => 'Credits can be specified for courses',
     );      );
     %defaultchecked = ('canuse_pdfforms' => 'off');      my %staticdefaults = (
     @toggles = ('canuse_pdfforms',);                             anonsurvey_threshold => 10,
     ($datatable,$itemcount) = &radiobutton_prefs($settings,\@toggles,\%defaultchecked,                             uploadquota          => 500,
                            );
       if ($position eq 'top') {
           %defaultchecked = ('canuse_pdfforms' => 'off');
           @toggles = ('canuse_pdfforms');
           ($datatable,$itemcount) = &radiobutton_prefs($settings,\@toggles,\%defaultchecked,
                                                  \%choices,$itemcount);                                                   \%choices,$itemcount);
       } else {
           $css_class = $itemcount%2 ? ' class="LC_odd_row"' : '';
           my ($currdefresponder,$def_official_credits,$def_unofficial_credits,%curruploadquota);
           my $currusecredits = 0;
           my @types = ('official','unofficial','community');
           if (ref($settings) eq 'HASH') {
               $currdefresponder = $settings->{'anonsurvey_threshold'};
               if (ref($settings->{'uploadquota'}) eq 'HASH') {
                   foreach my $type (keys(%{$settings->{'uploadquota'}})) {
                       $curruploadquota{$type} = $settings->{'uploadquota'}{$type};
                   }
               }
               if (ref($settings->{'coursecredits'}) eq 'HASH') {
                   $def_official_credits = $settings->{'coursecredits'}->{'official'};
                   $def_unofficial_credits = $settings->{'coursecredits'}->{'unofficial'};
                   if (($def_official_credits ne '') || ($def_unofficial_credits ne '')) {
                       $currusecredits = 1;
                   }
               }
           }
           if (!$currdefresponder) {
               $currdefresponder = $staticdefaults{'anonsurvey_threshold'};
           } elsif ($currdefresponder < 1) {
               $currdefresponder = 1;
           }
           foreach my $type (@types) {
               if ($curruploadquota{$type} eq '') {
                   $curruploadquota{$type} = $staticdefaults{'uploadquota'};
               }
           }
           $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>'."\n".
                   '<tr><td><span class="LC_nobreak">'.
                   $choices{'uploadquota'}.
                   '</span></td>'.
                   '<td align="right" class="LC_right_item">'.
                   '<table><tr>';
           foreach my $type (@types) {
               $datatable .= '<td align="center">'.&mt($type).'<br />'.
                              '<input type="text" name="uploadquota_'.$type.'"'.
                              ' value="'.$curruploadquota{$type}.'" size="5" /></td>';
           }
           $datatable .= '</tr></table></td></tr>'."\n";
           $itemcount += 2;
           my $onclick = 'toggleCredits(this.form);';
           my $display = 'none';
           if ($currusecredits) {
               $display = 'block';
           }
           my $additional = '<div id="credits" style="display: '.$display.'">'.
                            '<span class="LC_nobreak">'.
                            &mt('Default credits for official courses [_1]',
                            '<input type="text" name="official_credits" value="'.
                            $def_official_credits.'" size="3" />').
                            '</span><br />'.
                            '<span class="LC_nobreak">'.
                            &mt('Default credits for unofficial courses [_1]',
                            '<input type="text" name="unofficial_credits" value="'.
                            $def_unofficial_credits.'" size="3" />').
                            '</span></div>'."\n";
           %defaultchecked = ('coursecredits' => 'off');
           @toggles = ('coursecredits');
           my $current = {
                           'coursecredits' => $currusecredits,
                         };
           (my $table,$itemcount) =
               &radiobutton_prefs($current,\@toggles,\%defaultchecked,
                                  \%choices,$itemcount,$onclick,$additional);
           $datatable .= $table;
       }
     $$rowtotal += $itemcount;      $$rowtotal += $itemcount;
     return $datatable;      return $datatable;
 }  }
   
   sub print_usersessions {
       my ($position,$dom,$settings,$rowtotal) = @_;
       my ($css_class,$datatable,%checked,%choices);
       my (%by_ip,%by_location,@intdoms);
       &build_location_hashes(\@intdoms,\%by_ip,\%by_location);
   
       my @alldoms = &Apache::lonnet::all_domains();
       my %serverhomes = %Apache::lonnet::serverhomeIDs;
       my %servers = &Apache::lonnet::internet_dom_servers($dom);
       my %altids = &id_for_thisdom(%servers);
       my $itemcount = 1;
       if ($position eq 'top') {
           if (keys(%serverhomes) > 1) {
               my %spareid = &current_offloads_to($dom,$settings,\%servers);
               $datatable .= &spares_row($dom,\%servers,\%spareid,\%serverhomes,\%altids,$rowtotal);
           } else {
               $datatable .= '<tr'.$css_class.'><td colspan="2">'.
                             &mt('Nothing to set here, as the cluster to which this domain belongs only contains one server.');
           }
       } else {
           if (keys(%by_location) == 0) {
               $datatable .= '<tr'.$css_class.'><td colspan="2">'.
                             &mt('Nothing to set here, as the cluster to which this domain belongs only contains one institution.');
           } else {
               my %lt = &usersession_titles();
               my $numinrow = 5;
               my $prefix;
               my @types;
               if ($position eq 'bottom') {
                   $prefix = 'remote';
                   @types = ('version','excludedomain','includedomain');
               } else {
                   $prefix = 'hosted';
                   @types = ('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 current_offloads_to {
       my ($dom,$settings,$servers) = @_;
       my (%spareid,%otherdomconfigs);
       if (ref($servers) eq 'HASH') {
           foreach my $lonhost (sort(keys(%{$servers}))) {
               my $gotspares;
               if (ref($settings) eq 'HASH') {
                   if (ref($settings->{'spares'}) eq 'HASH') {
                       if (ref($settings->{'spares'}{$lonhost}) eq 'HASH') {
                           $spareid{$lonhost}{'primary'} = $settings->{'spares'}{$lonhost}{'primary'};
                           $spareid{$lonhost}{'default'} = $settings->{'spares'}{$lonhost}{'default'};
                           $gotspares = 1;
                       }
                   }
               }
               unless ($gotspares) {
                   my $gotspares;
                   my $serverhomeID =
                       &Apache::lonnet::get_server_homeID($servers->{$lonhost});
                   my $serverhomedom =
                       &Apache::lonnet::host_domain($serverhomeID);
                   if ($serverhomedom ne $dom) {
                       if (ref($otherdomconfigs{$serverhomedom} eq 'HASH')) {
                           if (ref($otherdomconfigs{$serverhomedom}{'usersessions'}) eq 'HASH') {
                               if (ref($otherdomconfigs{$serverhomedom}{'usersessions'}{'spares'}) eq 'HASH') {
                                   $spareid{$lonhost}{'primary'} = $otherdomconfigs{$serverhomedom}{'usersessions'}{'spares'}{'primary'};
                                   $spareid{$lonhost}{'default'} = $otherdomconfigs{$serverhomedom}{'usersessions'}{'spares'}{'default'};
                                   $gotspares = 1;
                               }
                           }
                       } else {
                           $otherdomconfigs{$serverhomedom} =
                               &Apache::lonnet::get_dom('configuration',['usersessions'],$serverhomedom);
                           if (ref($otherdomconfigs{$serverhomedom}) eq 'HASH') {
                               if (ref($otherdomconfigs{$serverhomedom}{'usersessions'}) eq 'HASH') {
                                   if (ref($otherdomconfigs{$serverhomedom}{'usersessions'}{'spares'}) eq 'HASH') {
                                       if (ref($otherdomconfigs{$serverhomedom}{'usersessions'}{'spares'}{$lonhost}) eq 'HASH') {
                                           $spareid{$lonhost}{'primary'} = $otherdomconfigs{$serverhomedom}{'usersessions'}{'spares'}{'primary'};
                                           $spareid{$lonhost}{'default'} = $otherdomconfigs{$serverhomedom}{'usersessions'}{'spares'}{'default'};
                                           $gotspares = 1;
                                       }
                                   }
                               }
                           }
                       }
                   }
               }
               unless ($gotspares) {
                   if ($lonhost eq $Apache::lonnet::perlvar{'lonHostID'}) {
                       $spareid{$lonhost}{'primary'} = $Apache::lonnet::spareid{'primary'};
                       $spareid{$lonhost}{'default'} = $Apache::lonnet::spareid{'default'};
                  } else {
                       my $server_hostname = &Apache::lonnet::hostname($lonhost);
                       my $server_homeID = &Apache::lonnet::get_server_homeID($server_hostname);
                       if ($server_homeID eq $Apache::lonnet::perlvar{'lonHostID'}) {
                           $spareid{$lonhost}{'primary'} = $Apache::lonnet::spareid{'primary'};
                           $spareid{$lonhost}{'default'} = $Apache::lonnet::spareid{'default'};
                       } else {
                           my %what = (
                                spareid => 1,
                           );
                           my ($result,$returnhash) = 
                               &Apache::lonnet::get_remote_globals($lonhost,\%what);
                           if ($result eq 'ok') { 
                               if (ref($returnhash) eq 'HASH') {
                                   if (ref($returnhash->{'spareid'}) eq 'HASH') {
                                       $spareid{$lonhost}{'primary'} = $returnhash->{'spareid'}->{'primary'};
                                       $spareid{$lonhost}{'default'} = $returnhash->{'spareid'}->{'default'};
                                   }
                               }
                           }
                       }
                   }
               }
           }
       }
       return %spareid;
   }
   
   sub spares_row {
       my ($dom,$servers,$spareid,$serverhomes,$altids,$rowtotal) = @_;
       my $css_class;
       my $numinrow = 4;
       my $itemcount = 1;
       my $datatable;
       my %typetitles = &sparestype_titles();
       if ((ref($servers) eq 'HASH') && (ref($spareid) eq 'HASH') && (ref($altids) eq 'HASH')) {
           foreach my $server (sort(keys(%{$servers}))) {
               my $serverhome = &Apache::lonnet::get_server_homeID($servers->{$server});
               my ($othercontrol,$serverdom);
               if ($serverhome ne $server) {
                   $serverdom = &Apache::lonnet::host_domain($serverhome);
                   $othercontrol = &mt('Session offloading controlled by domain: [_1]','<b>'.$serverdom.'</b>');
               } else {
                   $serverdom = &Apache::lonnet::host_domain($server);
                   if ($serverdom ne $dom) {
                       $othercontrol = &mt('Session offloading controlled by domain: [_1]','<b>'.$serverdom.'</b>');
                   }
               }
               next unless (ref($spareid->{$server}) eq 'HASH');
               $css_class = $itemcount%2 ? ' class="LC_odd_row"' : '';
               $datatable .= '<tr'.$css_class.'>
                              <td rowspan="2">
                               <span class="LC_nobreak">'.
                             &mt('[_1] when busy, offloads to:'
                                 ,'<b>'.$server.'</b>').
                             "\n";
               my (%current,%canselect);
               my @choices = 
                   &possible_newspares($server,$spareid->{$server},$serverhomes,$altids);
               foreach my $type ('primary','default') {
                   if (ref($spareid->{$server}) eq 'HASH') {
                       if (ref($spareid->{$server}{$type}) eq 'ARRAY') {
                           my @spares = @{$spareid->{$server}{$type}};
                           if (@spares > 0) {
                               if ($othercontrol) {
                                   $current{$type} = join(', ',@spares);
                               } else {
                                   $current{$type} .= '<table>';
                                   my $numspares = scalar(@spares);
                                   for (my $i=0;  $i<@spares; $i++) {
                                       my $rem = $i%($numinrow);
                                       if ($rem == 0) {
                                           if ($i > 0) {
                                               $current{$type} .= '</tr>';
                                           }
                                           $current{$type} .= '<tr>';
                                       }
                                       $current{$type} .= '<td><label><input type="checkbox" name="spare_'.$type.'_'.$server.'" id="spare_'.$type.'_'.$server.'_'.$i.'" checked="checked" value="'.$spareid->{$server}{$type}[$i].'" onclick="updateNewSpares(this.form,'."'$server'".');" />&nbsp;'.
                                                          $spareid->{$server}{$type}[$i].
                                                          '</label></td>'."\n";
                                   }
                                   my $rem = @spares%($numinrow);
                                   my $colsleft = $numinrow - $rem;
                                   if ($colsleft > 1 ) {
                                       $current{$type} .= '<td colspan="'.$colsleft.
                                                          '" class="LC_left_item">'.
                                                          '&nbsp;</td>';
                                   } elsif ($colsleft == 1) {
                                       $current{$type} .= '<td class="LC_left_item">&nbsp;</td>'."\n";
                                   }
                                   $current{$type} .= '</tr></table>';
                               }
                           }
                       }
                       if ($current{$type} eq '') {
                           $current{$type} = &mt('None specified');
                       }
                       if ($othercontrol) {
                           if ($type eq 'primary') {
                               $canselect{$type} = $othercontrol;
                           }
                       } else {
                           $canselect{$type} = 
                               &mt('Add new [_1]'.$type.'[_2]:','<i>','</i>').'&nbsp;'.
                               '<select name="newspare_'.$type.'_'.$server.'" '.
                               'id="newspare_'.$type.'_'.$server.'" onchange="checkNewSpares('."'$server','$type'".');">'."\n".
                               '<option value="" selected ="selected">'.&mt('Select').'</option>'."\n";
                           if (@choices > 0) {
                               foreach my $lonhost (@choices) {
                                   $canselect{$type} .= '<option value="'.$lonhost.'">'.$lonhost.'</option>'."\n";
                               }
                           }
                           $canselect{$type} .= '</select>'."\n";
                       }
                   } else {
                       $current{$type} = &mt('Could not be determined');
                       if ($type eq 'primary') {
                           $canselect{$type} =  $othercontrol;
                       }
                   }
                   if ($type eq 'default') {
                       $datatable .= '<tr'.$css_class.'>';
                   }
                   $datatable .= '<td><i>'.$typetitles{$type}.'</i></td>'."\n".
                                 '<td>'.$current{$type}.'</td>'."\n".
                                 '<td>'.$canselect{$type}.'</td></tr>'."\n";
               }
               $itemcount ++;
           }
       }
       $$rowtotal += $itemcount;
       return $datatable;
   }
   
   sub possible_newspares {
       my ($server,$currspares,$serverhomes,$altids) = @_;
       my $serverhostname = &Apache::lonnet::hostname($server);
       my %excluded;
       if ($serverhostname ne '') {
           %excluded = (
                          $serverhostname => 1,
                       );
       }
       if (ref($currspares) eq 'HASH') {
           foreach my $type (keys(%{$currspares})) {
               if (ref($currspares->{$type}) eq 'ARRAY') {
                   if (@{$currspares->{$type}} > 0) {
                       foreach my $curr (@{$currspares->{$type}}) {
                           my $hostname = &Apache::lonnet::hostname($curr);
                           $excluded{$hostname} = 1;
                       }
                   }
               }
           }
       }
       my @choices;
       if ((ref($serverhomes) eq 'HASH') && (ref($altids) eq 'HASH')) {
           if (keys(%{$serverhomes}) > 1) {
               foreach my $name (sort(keys(%{$serverhomes}))) {
                   unless ($excluded{$name}) {
                       if (exists($altids->{$serverhomes->{$name}})) {
                           push(@choices,$altids->{$serverhomes->{$name}});
                       } else {
                           push(@choices,$serverhomes->{$name});
                       }
                   }
               }
           }
       }
       return sort(@choices);
   }
   
   sub print_loadbalancing {
       my ($dom,$settings,$rowtotal) = @_;
       my $primary_id = &Apache::lonnet::domain($dom,'primary');
       my $intdom = &Apache::lonnet::internet_dom($primary_id);
       my $numinrow = 1;
       my $datatable;
       my %servers = &Apache::lonnet::internet_dom_servers($dom);
       my (%currbalancer,%currtargets,%currrules,%existing);
       if (ref($settings) eq 'HASH') {
           %existing = %{$settings};
       }
       if ((keys(%servers) > 1) || (keys(%existing) > 0)) {
           &get_loadbalancers_config(\%servers,\%existing,\%currbalancer,
                                     \%currtargets,\%currrules);
       } else {
           return;
       }
       my ($othertitle,$usertypes,$types) =
           &Apache::loncommon::sorted_inst_types($dom);
       my $rownum = 8;
       if (ref($types) eq 'ARRAY') {
           $rownum += scalar(@{$types});
       }
       my @css_class = ('LC_odd_row','LC_even_row');
       my $balnum = 0;
       my $islast;
       my (@toshow,$disabledtext);
       if (keys(%currbalancer) > 0) {
           @toshow = sort(keys(%currbalancer));
           if (scalar(@toshow) < scalar(keys(%servers)) + 1) {
               push(@toshow,'');
           }
       } else {
           @toshow = ('');
           $disabledtext = &mt('No existing load balancer');
       }
       foreach my $lonhost (@toshow) {
           if ($balnum == scalar(@toshow)-1) {
               $islast = 1;
           } else {
               $islast = 0;
           }
           my $cssidx = $balnum%2;
           my $targets_div_style = 'display: none';
           my $disabled_div_style = 'display: block';
           my $homedom_div_style = 'display: none';
           $datatable .= '<tr class="'.$css_class[$cssidx].'">'.
                         '<td rowspan="'.$rownum.'" valign="top">'.
                         '<p>';
           if ($lonhost eq '') {
               $datatable .= '<span class="LC_nobreak">';
               if (keys(%currbalancer) > 0) {
                   $datatable .= &mt('Add balancer:');
               } else {
                   $datatable .= &mt('Enable balancer:');
               }
               $datatable .= '&nbsp;'.
                             '<select name="loadbalancing_lonhost_'.$balnum.'"'.
                             ' id="loadbalancing_lonhost_'.$balnum.'"'.
                             ' onchange="toggleTargets('."'$balnum'".');">'."\n".
                             '<option value="" selected="selected">'.&mt('None').
                             '</option>'."\n";
               foreach my $server (sort(keys(%servers))) {
                   next if ($currbalancer{$server});
                   $datatable .= '<option value="'.$server.'">'.$server.'</option>'."\n";
               }
               $datatable .=
                   '</select>'."\n".
                   '<input type="hidden" name="loadbalancing_prevlonhost_'.$balnum.'" id="loadbalancing_prevlonhost_'.$balnum.'" value="" />&nbsp;</span>'."\n";
           } else {
               $datatable .= '<i>'.$lonhost.'</i><br /><span class="LC_nobreak">'.
                             '<label><input type="checkbox" name="loadbalancing_delete" value="'.$balnum.'" id="loadbalancing_delete_'.$balnum.'" onclick="javascript:balancerDeleteChange('."'$balnum'".');" />&nbsp;'.
                              &mt('Stop balancing').'</label>'.
                              '<input type="hidden" name="loadbalancing_lonhost_'.$balnum.'" value="'.$lonhost.'" id="loadbalancing_lonhost_'.$balnum.'" /></span>';
               $targets_div_style = 'display: block';
               $disabled_div_style = 'display: none';
               if ($dom eq &Apache::lonnet::host_domain($lonhost)) {
                   $homedom_div_style = 'display: block';
               }
           }
           $datatable .= '</p></td><td rowspan="'.$rownum.'" valign="top">'.
                     '<div id="loadbalancing_disabled_'.$balnum.'" style="'.
                     $disabled_div_style.'">'.$disabledtext.'</div>'."\n".
                     '<div id="loadbalancing_targets_'.$balnum.'" style="'.$targets_div_style.'">'.&mt('Offloads to:').'<br />';
           my ($numspares,@spares) = &count_servers($lonhost,%servers);
           my @sparestypes = ('primary','default');
           my %typetitles = &sparestype_titles();
           foreach my $sparetype (@sparestypes) {
               my $targettable;
               for (my $i=0; $i<$numspares; $i++) {
                   my $checked;
                   if (ref($currtargets{$lonhost}) eq 'HASH') {
                       if (ref($currtargets{$lonhost}{$sparetype}) eq 'ARRAY') {
                           if (grep(/^\Q$spares[$i]\E$/,@{$currtargets{$lonhost}{$sparetype}})) {
                               $checked = ' checked="checked"';
                           }
                       }
                   }
                   my ($chkboxval,$disabled);
                   if (($lonhost ne '') && (exists($servers{$lonhost}))) {
                       $chkboxval = $spares[$i];
                   }
                   if (exists($currbalancer{$spares[$i]})) {
                       $disabled = ' disabled="disabled"';
                   }
                   $targettable .=
                       '<td><label><input type="checkbox" name="loadbalancing_target_'.$balnum.'_'.$sparetype.'"'.
                       $checked.$disabled.' value="'.$chkboxval.'" id="loadbalancing_target_'.$balnum.'_'.$sparetype.'_'.$i.'" onclick="checkOffloads('."this,'$balnum','$sparetype'".');" /><span id="loadbalancing_targettxt_'.$balnum.'_'.$sparetype.'_'.$i.'">&nbsp;'.$chkboxval.
                       '</span></label></td>';
                   my $rem = $i%($numinrow);
                   if ($rem == 0) {
                       if (($i > 0) && ($i < $numspares-1)) {
                           $targettable .= '</tr>';
                       }
                       if ($i < $numspares-1) {
                           $targettable .= '<tr>';
                       }
                   }
               }
               if ($targettable ne '') {
                   my $rem = $numspares%($numinrow);
                   my $colsleft = $numinrow - $rem;
                   if ($colsleft > 1 ) {
                       $targettable .= '<td colspan="'.$colsleft.'" class="LC_left_item">'.
                                       '&nbsp;</td>';
                   } elsif ($colsleft == 1) {
                       $targettable .= '<td class="LC_left_item">&nbsp;</td>';
                   }
                   $datatable .=  '<i>'.$typetitles{$sparetype}.'</i><br />'.
                                  '<table><tr>'.$targettable.'</tr></table><br />';
               }
           }
           $datatable .= '</div></td></tr>'.
                         &loadbalancing_rules($dom,$intdom,$currrules{$lonhost},
                                              $othertitle,$usertypes,$types,\%servers,
                                              \%currbalancer,$lonhost,
                                              $targets_div_style,$homedom_div_style,
                                              $css_class[$cssidx],$balnum,$islast);
           $$rowtotal += $rownum;
           $balnum ++;
       }
       $datatable .= '<input type="hidden" name="loadbalancing_total" id="loadbalancing_total" value="'.$balnum.'" />';
       return $datatable;
   }
   
   sub get_loadbalancers_config {
       my ($servers,$existing,$currbalancer,$currtargets,$currrules) = @_;
       return unless ((ref($servers) eq 'HASH') &&
                      (ref($existing) eq 'HASH') && (ref($currbalancer) eq 'HASH') &&
                      (ref($currtargets) eq 'HASH') && (ref($currrules) eq 'HASH'));
       if (keys(%{$existing}) > 0) {
           my $oldlonhost;
           foreach my $key (sort(keys(%{$existing}))) {
               if ($key eq 'lonhost') {
                   $oldlonhost = $existing->{'lonhost'};
                   $currbalancer->{$oldlonhost} = 1;
               } elsif ($key eq 'targets') {
                   if ($oldlonhost) {
                       $currtargets->{$oldlonhost} = $existing->{'targets'};
                   }
               } elsif ($key eq 'rules') {
                   if ($oldlonhost) {
                       $currrules->{$oldlonhost} = $existing->{'rules'};
                   }
               } elsif (ref($existing->{$key}) eq 'HASH') {
                   $currbalancer->{$key} = 1;
                   $currtargets->{$key} = $existing->{$key}{'targets'};
                   $currrules->{$key} = $existing->{$key}{'rules'};
               }
           }
       } else {
           my ($balancerref,$targetsref) =
                   &Apache::lonnet::get_lonbalancer_config($servers);
           if ((ref($balancerref) eq 'HASH') && (ref($targetsref) eq 'HASH')) {
               foreach my $server (sort(keys(%{$balancerref}))) {
                   $currbalancer->{$server} = 1;
                   $currtargets->{$server} = $targetsref->{$server};
               }
           }
       }
       return;
   }
   
   sub loadbalancing_rules {
       my ($dom,$intdom,$currrules,$othertitle,$usertypes,$types,$servers,
           $currbalancer,$lonhost,$targets_div_style,$homedom_div_style,
           $css_class,$balnum,$islast) = @_;
       my $output;
       my $num = 0;
       my ($alltypes,$othertypes,$titles) =
           &loadbalancing_titles($dom,$intdom,$usertypes,$types);
       if ((ref($alltypes) eq 'ARRAY') && (ref($titles) eq 'HASH'))  {
           foreach my $type (@{$alltypes}) {
               $num ++;
               my $current;
               if (ref($currrules) eq 'HASH') {
                   $current = $currrules->{$type};
               }
               if (($type eq '_LC_external') || ($type eq '_LC_internetdom') || ($type eq '_LC_ipchange')) {
                   if ($dom ne &Apache::lonnet::host_domain($lonhost)) {
                       $current = '';
                   }
               }
               $output .= &loadbalance_rule_row($type,$titles->{$type},$current,
                                                $servers,$currbalancer,$lonhost,$dom,
                                                $targets_div_style,$homedom_div_style,
                                                $css_class,$balnum,$num,$islast);
           }
       }
       return $output;
   }
   
   sub loadbalancing_titles {
       my ($dom,$intdom,$usertypes,$types) = @_;
       my %othertypes = (
              '_LC_adv'         => &mt('Advanced users from [_1]',$dom),
              '_LC_author'      => &mt('Users from [_1] with author role',$dom),
              '_LC_internetdom' => &mt('Users not from [_1], but from [_2]',$dom,$intdom),
              '_LC_external'    => &mt('Users not from [_1]',$intdom),
              '_LC_ipchangesso' => &mt('SSO users from [_1], with IP mismatch',$dom),
              '_LC_ipchange'    => &mt('Non-SSO users with IP mismatch'),
                        );
       my @alltypes = ('_LC_adv','_LC_author','_LC_internetdom','_LC_external','_LC_ipchangesso','_LC_ipchange');
       if (ref($types) eq 'ARRAY') {
           unshift(@alltypes,@{$types},'default');
       }
       my %titles;
       foreach my $type (@alltypes) {
           if ($type =~ /^_LC_/) {
               $titles{$type} = $othertypes{$type};
           } elsif ($type eq 'default') {
               $titles{$type} = &mt('All users from [_1]',$dom);
               if (ref($types) eq 'ARRAY') {
                   if (@{$types} > 0) {
                       $titles{$type} = &mt('Other users from [_1]',$dom);
                   }
               }
           } elsif (ref($usertypes) eq 'HASH') {
               $titles{$type} = $usertypes->{$type};
           }
       }
       return (\@alltypes,\%othertypes,\%titles);
   }
   
   sub loadbalance_rule_row {
       my ($type,$title,$current,$servers,$currbalancer,$lonhost,$dom,
           $targets_div_style,$homedom_div_style,$css_class,$balnum,$num,$islast) = @_;
       my @rulenames;
       my %ruletitles = &offloadtype_text();
       if (($type eq '_LC_ipchangesso') || ($type eq '_LC_ipchange')) {
           @rulenames = ('balancer','offloadedto');
       } else {
           @rulenames = ('default','homeserver');
           if ($type eq '_LC_external') {
               push(@rulenames,'externalbalancer');
           } else {
               push(@rulenames,'specific');
           }
           push(@rulenames,'none');
       }
       my $style = $targets_div_style;
       if (($type eq '_LC_external') || ($type eq '_LC_internetdom') || ($type eq '_LC_ipchange')) {
           $style = $homedom_div_style;
       }
       my $space;
       if ($islast && $num == 1) {
           $space = '<div display="inline-block">&nbsp;</div>';
       }
       my $output =
           '<tr class="'.$css_class.'" id="balanceruletr_'.$balnum.'_'.$num.'"><td valign="top">'.$space.
           '<div id="balanceruletitle_'.$balnum.'_'.$type.'" style="'.$style.'">'.$title.'</div></td>'."\n".
           '<td valaign="top">'.$space.
           '<div id="balancerule_'.$balnum.'_'.$type.'" style="'.$style.'">'."\n";
       for (my $i=0; $i<@rulenames; $i++) {
           my $rule = $rulenames[$i];
           my ($checked,$extra);
           if ($rulenames[$i] eq 'default') {
               $rule = '';
           }
           if ($rulenames[$i] eq 'specific') {
               if (ref($servers) eq 'HASH') {
                   my $default;
                   if (($current ne '') && (exists($servers->{$current}))) {
                       $checked = ' checked="checked"';
                   }
                   unless ($checked) {
                       $default = ' selected="selected"';
                   }
                   $extra =
                       ':&nbsp;<select name="loadbalancing_singleserver_'.$balnum.'_'.$type.
                       '" id="loadbalancing_singleserver_'.$balnum.'_'.$type.
                       '" onchange="singleServerToggle('."'$balnum','$type'".')">'."\n".
                       '<option value=""'.$default.'></option>'."\n";
                   foreach my $server (sort(keys(%{$servers}))) {
                       if (ref($currbalancer) eq 'HASH') {
                           next if (exists($currbalancer->{$server}));
                       }
                       my $selected;
                       if ($server eq $current) {
                           $selected = ' selected="selected"';
                       }
                       $extra .= '<option value="'.$server.'"'.$selected.'>'.$server.'</option>';
                   }
                   $extra .= '</select>';
               }
           } elsif ($rule eq $current) {
               $checked = ' checked="checked"';
           }
           $output .= '<span class="LC_nobreak"><label>'.
                      '<input type="radio" name="loadbalancing_rules_'.$balnum.'_'.$type.
                      '" id="loadbalancing_rules_'.$balnum.'_'.$type.'_'.$i.'" value="'.
                      $rule.'" onclick="balanceruleChange('."this.form,'$balnum','$type'".
                      ')"'.$checked.' />&nbsp;'.$ruletitles{$rulenames[$i]}.
                      '</label>'.$extra.'</span><br />'."\n";
       }
       $output .= '</div></td></tr>'."\n";
       return $output;
   }
   
   sub offloadtype_text {
       my %ruletitles = &Apache::lonlocal::texthash (
              'default'          => 'Offloads to default destinations',
              'homeserver'       => "Offloads to user's home server",
              'externalbalancer' => "Offloads to Load Balancer in user's domain",
              'specific'         => 'Offloads to specific server',
              'none'             => 'No offload',
              'balancer'         => 'Session hosted on Load Balancer, after re-authentication',
              'offloadedto'      => 'Session hosted on offload server, after re-authentication',
       );
       return %ruletitles;
   }
   
   sub sparestype_titles {
       my %typestitles = &Apache::lonlocal::texthash (
                             'primary' => 'primary',
                             'default' => 'default',
                         );
       return %typestitles;
   }
   
 sub contact_titles {  sub contact_titles {
     my %titles = &Apache::lonlocal::texthash (      my %titles = &Apache::lonlocal::texthash (
                    'supportemail' => 'Support E-mail address',                     'supportemail' => 'Support E-mail address',
Line 2175  sub contact_titles { Line 3328  sub contact_titles {
                    'helpdeskmail' => 'Helpdesk requests to be e-mailed to',                     'helpdeskmail' => 'Helpdesk requests to be e-mailed to',
                    'lonstatusmail' => 'E-mail from nightly status check (warnings/errors)',                     'lonstatusmail' => 'E-mail from nightly status check (warnings/errors)',
                    'requestsmail' => 'E-mail from course requests requiring approval',                     'requestsmail' => 'E-mail from course requests requiring approval',
                      'updatesmail'  => 'E-mail from nightly check of LON-CAPA module integrity/updates',
                      'idconflictsmail' => 'E-mail from bi-nightly check for multiple users sharing same student/employee ID',
                  );                   );
     my %short_titles = &Apache::lonlocal::texthash (      my %short_titles = &Apache::lonlocal::texthash (
                            adminemail   => 'Admin E-mail address',                             adminemail   => 'Admin E-mail address',
Line 2185  sub contact_titles { Line 3340  sub contact_titles {
   
 sub tool_titles {  sub tool_titles {
     my %titles = &Apache::lonlocal::texthash (      my %titles = &Apache::lonlocal::texthash (
                      aboutme    => 'Personal Information Page',                       aboutme    => 'Personal web page',
                      blog       => 'Blog',                       blog       => 'Blog',
                        webdav     => 'WebDAV',
                      portfolio  => 'Portfolio',                       portfolio  => 'Portfolio',
                      official   => 'Official courses (with institutional codes)',                       official   => 'Official courses (with institutional codes)',
                      unofficial => 'Unofficial courses',                       unofficial => 'Unofficial courses',
Line 2209  sub courserequest_titles { Line 3365  sub courserequest_titles {
     return %titles;      return %titles;
 }  }
   
   sub authorrequest_titles {
       my %titles = &Apache::lonlocal::texthash (
                                      norequest  => 'Not allowed',
                                      approval   => 'Approval by Dom. Coord.',
                                      automatic  => 'Automatic approval',
                    );
       return %titles;
   }
   
 sub courserequest_conditions {  sub courserequest_conditions {
     my %conditions = &Apache::lonlocal::texthash (      my %conditions = &Apache::lonlocal::texthash (
        approval    => '(Processing of request subject to approval by Domain Coordinator).',         approval    => '(Processing of request subject to approval by Domain Coordinator).',
        validate   => '(Processing of request subject to instittutional validation).',         validate   => '(Processing of request subject to institutional validation).',
                  );                   );
     return %conditions;      return %conditions;
 }  }
Line 2338  sub print_usercreation { Line 3503  sub print_usercreation {
         }          }
         my ($othertitle,$usertypes,$types) =          my ($othertitle,$usertypes,$types) =
             &Apache::loncommon::sorted_inst_types($dom);              &Apache::loncommon::sorted_inst_types($dom);
           my $createsettings;
           if (ref($settings) eq 'HASH') {
               $createsettings = $settings->{cancreate};
           }
         if (ref($usertypes) eq 'HASH') {          if (ref($usertypes) eq 'HASH') {
             if (keys(%{$usertypes}) > 0) {              if (keys(%{$usertypes}) > 0) {
                 my $createsettings;  
                 if (ref($settings) eq 'HASH') {  
                     $createsettings = $settings->{cancreate};  
                 }  
                 $datatable .= &insttypes_row($createsettings,$types,$usertypes,                  $datatable .= &insttypes_row($createsettings,$types,$usertypes,
                                              $dom,$numinrow,$othertitle,                                               $dom,$numinrow,$othertitle,
                                              'statustocreate');                                               'statustocreate');
                 $$rowtotal ++;                  $$rowtotal ++;
                   $rownum ++;
             }              }
         }          }
           $datatable .= &captcha_choice('cancreate',$createsettings,$rownum);
     } else {      } else {
         my @contexts = ('author','course','domain');          my @contexts = ('author','course','domain');
         my @authtypes = ('int','krb4','krb5','loc');          my @authtypes = ('int','krb4','krb5','loc');
Line 2401  sub print_usercreation { Line 3568  sub print_usercreation {
     return $datatable;      return $datatable;
 }  }
   
   sub captcha_choice {
       my ($context,$settings,$itemcount) = @_;
       my ($keyentry,$currpub,$currpriv,%checked,$rowname,$pubtext,$privtext);
       my %lt = &captcha_phrases();
       $keyentry = 'hidden';
       if ($context eq 'cancreate') {
           $rowname = &mt('CAPTCHA validation (e-mail as username)');
       } elsif ($context eq 'login') {
           $rowname =  &mt('"Contact helpdesk" CAPTCHA validation');
       }
       if (ref($settings) eq 'HASH') {
           if ($settings->{'captcha'}) {
               $checked{$settings->{'captcha'}} = ' checked="checked"';
           } else {
               $checked{'original'} = ' checked="checked"';
           }
           if ($settings->{'captcha'} eq 'recaptcha') {
               $pubtext = $lt{'pub'};
               $privtext = $lt{'priv'};
               $keyentry = 'text';
           }
           if (ref($settings->{'recaptchakeys'}) eq 'HASH') {
               $currpub = $settings->{'recaptchakeys'}{'public'};
               $currpriv = $settings->{'recaptchakeys'}{'private'};
           }
       } else {
           $checked{'original'} = ' checked="checked"';
       }
       my $css_class = $itemcount%2?' class="LC_odd_row"':'';
       my $output = '<tr'.$css_class.'>'.
                    '<td class="LC_left_item">'.$rowname.'</td><td class="LC_left_item" colspan="2">'."\n".
                    '<table><tr><td>'."\n";
       foreach my $option ('original','recaptcha','notused') {
           $output .= '<span class="LC_nobreak"><label><input type="radio" name="'.$context.'_captcha" value="'.
                      $option.'" '.$checked{$option}.' onchange="javascript:updateCaptcha('."this,'$context'".');" />'.
                      $lt{$option}.'</label></span>';
           unless ($option eq 'notused') {
               $output .= ('&nbsp;'x2)."\n";
           }
       }
   #
   # Note: If reCAPTCHA is to be used for LON-CAPA servers in a domain, a domain coordinator should visit:
   # https://www.google.com/recaptcha and generate a Public and Private key. For domains with multiple
   # servers a single key pair will be used for all servers, so the internet domain (e.g., yourcollege.edu)
   # specified for use with the key should be broad enough to accommodate all servers in the LON-CAPA domain.
   #
       $output .= '</td></tr>'."\n".
                  '<tr><td>'."\n".
                  '<span class="LC_nobreak"><span id="'.$context.'_recaptchapubtxt">'.$pubtext.'</span>&nbsp;'."\n".
                  '<input type="'.$keyentry.'" id="'.$context.'_recaptchapub" name="'.$context.'_recaptchapub" value="'.
                  $currpub.'" size="40" /></span><br />'."\n".
                  '<span class="LC_nobreak"><span id="'.$context.'_recaptchaprivtxt">'.$privtext.'</span>&nbsp;'."\n".
                  '<input type="'.$keyentry.'" id="'.$context.'_recaptchapriv" name="'.$context.'_recaptchapriv" value="'.
                  $currpriv.'" size="40" /></span></td></tr></table>'."\n".
                  '</td></tr>';
       return $output;
   }
   
 sub user_formats_row {  sub user_formats_row {
     my ($type,$settings,$rules,$ruleorder,$numinrow,$rowcount) = @_;      my ($type,$settings,$rules,$ruleorder,$numinrow,$rowcount) = @_;
     my $output;      my $output;
Line 2535  sub print_usermodification { Line 3760  sub print_usermodification {
 }  }
   
 sub print_defaults {  sub print_defaults {
     my ($dom,$rowtotal) = @_;      my ($dom,$settings,$rowtotal) = @_;
     my @items = ('auth_def','auth_arg_def','lang_def','timezone_def',      my @items = ('auth_def','auth_arg_def','lang_def','timezone_def',
                  'datelocale_def');                   'datelocale_def','portal_def');
     my %domdefaults = &Apache::lonnet::get_domain_defaults($dom);      my %defaults;
     my $titles = &defaults_titles();      if (ref($settings) eq 'HASH') {
           %defaults = %{$settings};
       } else {
           my %domdefaults = &Apache::lonnet::get_domain_defaults($dom,1);
           foreach my $item (@items) {
               $defaults{$item} = $domdefaults{$item};
           }
       }
       my $titles = &defaults_titles($dom);
     my $rownum = 0;      my $rownum = 0;
     my ($datatable,$css_class);      my ($datatable,$css_class);
     foreach my $item (@items) {      foreach my $item (@items) {
Line 2562  sub print_defaults { Line 3795  sub print_defaults {
             my %authnames = &authtype_names();              my %authnames = &authtype_names();
             foreach my $auth (@authtypes) {              foreach my $auth (@authtypes) {
                 my $checked = ' ';                  my $checked = ' ';
                 if ($domdefaults{$item} eq $auth) {                  if ($defaults{$item} eq $auth) {
                     $checked = ' checked="checked" ';                      $checked = ' checked="checked" ';
                 }                  }
                 $datatable .= '<label><input type="radio" name="'.$item.                  $datatable .= '<label><input type="radio" name="'.$item.
Line 2571  sub print_defaults { Line 3804  sub print_defaults {
             }              }
         } elsif ($item eq 'timezone_def') {          } elsif ($item eq 'timezone_def') {
             my $includeempty = 1;              my $includeempty = 1;
             $datatable .= &Apache::loncommon::select_timezone($item,$domdefaults{$item},undef,$includeempty);              $datatable .= &Apache::loncommon::select_timezone($item,$defaults{$item},undef,$includeempty);
         } elsif ($item eq 'datelocale_def') {          } elsif ($item eq 'datelocale_def') {
             my $includeempty = 1;              my $includeempty = 1;
             $datatable .= &Apache::loncommon::select_datelocale($item,$domdefaults{$item},undef,$includeempty);              $datatable .= &Apache::loncommon::select_datelocale($item,$defaults{$item},undef,$includeempty);
         } else {          } elsif ($item eq 'lang_def') {
               my %langchoices = &get_languages_hash();
               $langchoices{''} = 'No language preference';
               %langchoices = &Apache::lonlocal::texthash(%langchoices);
               $datatable .= &Apache::loncommon::select_form($defaults{$item},$item,
                                                             \%langchoices);
           } else {
               my $size;
               if ($item eq 'portal_def') {
                   $size = ' size="25"';
               }
             $datatable .= '<input type="text" name="'.$item.'" value="'.              $datatable .= '<input type="text" name="'.$item.'" value="'.
                           $domdefaults{$item}.'" />';                            $defaults{$item}.'"'.$size.' />';
         }          }
         $datatable .= '</td></tr>';          $datatable .= '</td></tr>';
         $rownum ++;          $rownum ++;
Line 2586  sub print_defaults { Line 3829  sub print_defaults {
     return $datatable;      return $datatable;
 }  }
   
   sub get_languages_hash {
       my %langchoices;
       foreach my $id (&Apache::loncommon::languageids()) {
           my $code = &Apache::loncommon::supportedlanguagecode($id);
           if ($code ne '') {
               $langchoices{$code} =  &Apache::loncommon::plainlanguagedescription($id);
           }
       }
       return %langchoices;
   }
   
 sub defaults_titles {  sub defaults_titles {
       my ($dom) = @_;
     my %titles = &Apache::lonlocal::texthash (      my %titles = &Apache::lonlocal::texthash (
                    'auth_def'      => 'Default authentication type',                     'auth_def'      => 'Default authentication type',
                    'auth_arg_def'  => 'Default authentication argument',                     'auth_arg_def'  => 'Default authentication argument',
                    'lang_def'      => 'Default language',                     'lang_def'      => 'Default language',
                    'timezone_def'  => 'Default timezone',                     'timezone_def'  => 'Default timezone',
                    'datelocale_def' => 'Default locale for dates',                     'datelocale_def' => 'Default locale for dates',
                      'portal_def'     => 'Portal/Default URL',
                  );                   );
       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);      return (\%titles);
 }  }
   
Line 2706  sub print_scantronformat { Line 3972  sub print_scantronformat {
         $datatable .= '<td>'.&mt('Default in use:').'<br />'.          $datatable .= '<td>'.&mt('Default in use:').'<br />'.
                       '<span class="LC_nobreak">';                        '<span class="LC_nobreak">';
         if ($scantronurl) {          if ($scantronurl) {
             $datatable .= '<a href="'.$scantronurl.'" target="_blank">'.              $datatable .= &Apache::loncommon::modal_link($scantronurl,&mt('Default bubblesheet format file'),600,500,
                           &mt('Default scantron format file').'</a>';                                                           undef,undef,undef,undef,'background-color:#ffffff');
         } else {          } else {
             $datatable = &mt('File unavailable for display');              $datatable = &mt('File unavailable for display');
         }          }
Line 2732  sub print_scantronformat { Line 3998  sub print_scantronformat {
             }               } 
             $datatable .= '<td>'.$errorstr.'</td><td>&nbsp;';              $datatable .= '<td>'.$errorstr.'</td><td>&nbsp;';
         } elsif ($scantronurl) {          } elsif ($scantronurl) {
               my $link =  &Apache::loncommon::modal_link($scantronurl,&mt('Custom bubblesheet format file'),600,500,
                                                          undef,undef,undef,undef,'background-color:#ffffff');
             $datatable .= '<td><span class="LC_nobreak">'.              $datatable .= '<td><span class="LC_nobreak">'.
                           '<a href="'.$scantronurl.'" target="_blank">'.                            $link.
                           &mt('Custom scantron format file').'</a><label>'.                            '<label><input type="checkbox" name="scantronformat_del"'.
                           '<input type="checkbox" name="scantronformat_del"'.                            ' value="1" />'.&mt('Delete?').'</label></span></td>'.
                           '" value="1" />'.&mt('Delete?').'</label></span></td>'.  
                           '<td><span class="LC_nobreak">&nbsp;'.                            '<td><span class="LC_nobreak">&nbsp;'.
                           &mt('Replace:').'</span><br />';                            &mt('Replace:').'</span><br />';
         }          }
Line 2763  sub legacy_scantronformat { Line 4030  sub legacy_scantronformat {
             &publishlogo($r,'copy',$legacyfile,$dom,$confname,'scantron',              &publishlogo($r,'copy',$legacyfile,$dom,$confname,'scantron',
                          '','',$newfile);                           '','',$newfile);
         if ($result ne 'ok') {          if ($result ne 'ok') {
             $error = &mt("An error occurred publishing the [_1] scantron format file in RES space. Error was: [_2].",$newfile,$result);              $error = &mt("An error occurred publishing the [_1] bubblesheet format file in RES space. Error was: [_2].",$newfile,$result);
         }          }
     }      }
     return ($url,$error);      return ($url,$error);
Line 2890  sub print_coursecategories { Line 4157  sub print_coursecategories {
                             }                              }
                             $datatable .= '<option value="'.$k.'"'.$selstr.'>'.$vpos.'</option>';                              $datatable .= '<option value="'.$k.'"'.$selstr.'>'.$vpos.'</option>';
                         }                          }
                         $datatable .= '</select></td><td>';                          $datatable .= '</select></span></td><td>';
                         if ($parent eq 'instcode' || $parent eq 'communities') {                          if ($parent eq 'instcode' || $parent eq 'communities') {
                             $datatable .=  '<span class="LC_nobreak">'                              $datatable .=  '<span class="LC_nobreak">'
                                            .$default_names{$parent}.'</span>';                                             .$default_names{$parent}.'</span>';
Line 2920  sub print_coursecategories { Line 4187  sub print_coursecategories {
                             $datatable .= '</td>';                              $datatable .= '</td>';
                         } else {                          } else {
                             $datatable .= $parent                              $datatable .= $parent
                                           .'&nbsp;<label><input type="checkbox" name="deletecategory" '                                            .'&nbsp;<span class="LC_nobreak"><label>'
                                             .'<input type="checkbox" name="deletecategory" '
                                           .'value="'.$item.'" />'.&mt('Delete').'</label></span></td>';                                            .'value="'.$item.'" />'.&mt('Delete').'</label></span></td>';
                         }                          }
                         my $depth = 1;                          my $depth = 1;
Line 3034  sub print_serverstatuses { Line 4302  sub print_serverstatuses {
   
 sub serverstatus_pages {  sub serverstatus_pages {
     return ('userstatus','lonstatus','loncron','server-status','codeversions',      return ('userstatus','lonstatus','loncron','server-status','codeversions',
             'clusterstatus','metadata_keywords','metadata_harvest',              'checksums','clusterstatus','metadata_keywords','metadata_harvest',
             'takeoffline','takeonline','showenv','toggledebug');              'takeoffline','takeonline','showenv','toggledebug','ping','domconf');
 }  }
   
 sub coursecategories_javascript {  sub coursecategories_javascript {
Line 3192  sub build_category_rows { Line 4460  sub build_category_rows {
             if (ref($cats->[$depth]{$parent}) eq 'ARRAY') {              if (ref($cats->[$depth]{$parent}) eq 'ARRAY') {
                 my $numchildren = @{$cats->[$depth]{$parent}};                  my $numchildren = @{$cats->[$depth]{$parent}};
                 my $css_class = $itemcount%2?' class="LC_odd_row"':'';                  my $css_class = $itemcount%2?' class="LC_odd_row"':'';
                 $text .= '<td><table class="LC_datatable">';                  $text .= '<td><table class="LC_data_table">';
                 my ($idxnum,$parent_name,$parent_item);                  my ($idxnum,$parent_name,$parent_item);
                 my $higher = $depth - 1;                  my $higher = $depth - 1;
                 if ($higher == 0) {                  if ($higher == 0) {
Line 3343  sub insttypes_row { Line 4611  sub insttypes_row {
     my %lt = &Apache::lonlocal::texthash (      my %lt = &Apache::lonlocal::texthash (
                       cansearch => 'Users allowed to search',                        cansearch => 'Users allowed to search',
                       statustocreate => 'Institutional affiliation(s) able to create own account (login/SSO)',                        statustocreate => 'Institutional affiliation(s) able to create own account (login/SSO)',
                         lockablenames => 'User preference to lock name',
              );               );
     my $showdom;      my $showdom;
     if ($context eq 'cansearch') {      if ($context eq 'cansearch') {
         $showdom = ' ('.$dom.')';          $showdom = ' ('.$dom.')';
     }      }
       my $class = 'LC_left_item';
       if ($context eq 'statustocreate') {
           $class = 'LC_right_item';
       }
     my $output =  '<tr class="LC_odd_row">'.      my $output =  '<tr class="LC_odd_row">'.
                   '<td>'.$lt{$context}.$showdom.                    '<td>'.$lt{$context}.$showdom.
                   '</td><td class="LC_left_item" colspan="2"><table>';                    '</td><td class="'.$class.'" colspan="2"><table>';
     my $rem;      my $rem;
     if (ref($types) eq 'ARRAY') {      if (ref($types) eq 'ARRAY') {
         for (my $i=0; $i<@{$types}; $i++) {          for (my $i=0; $i<@{$types}; $i++) {
Line 3379  sub insttypes_row { Line 4652  sub insttypes_row {
                            $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 {
Line 3477  sub usertype_update_row { Line 4752  sub usertype_update_row {
 }  }
   
 sub modify_login {  sub modify_login {
     my ($r,$dom,$confname,%domconfig) = @_;      my ($r,$dom,$confname,$lastactref,%domconfig) = @_;
     my ($resulttext,$errors,$colchgtext,%changes,%colchanges);      my ($resulttext,$errors,$colchgtext,%changes,%colchanges,%newfile,%newurl,
     my %title = ( coursecatalog => 'Display course catalog',          %curr_loginvia,%loginhash,@currlangs,@newlangs,$addedfile,%title,@offon);
                   adminmail => 'Display administrator E-mail address',      %title = ( coursecatalog => 'Display course catalog',
                   newuser => 'Link for visitors to create a user account',                 adminmail => 'Display administrator E-mail address',
                   loginheader => 'Log-in box header');                 helpdesk  => 'Display "Contact Helpdesk" link',
     my @offon = ('off','on');                 newuser => 'Link for visitors to create a user account',
     my %curr_loginvia;                 loginheader => 'Log-in box header');
       @offon = ('off','on');
     if (ref($domconfig{login}) eq 'HASH') {      if (ref($domconfig{login}) eq 'HASH') {
         if (ref($domconfig{login}{loginvia}) eq 'HASH') {          if (ref($domconfig{login}{loginvia}) eq 'HASH') {
             foreach my $lonhost (keys(%{$domconfig{login}{loginvia}})) {              foreach my $lonhost (keys(%{$domconfig{login}{loginvia}})) {
Line 3492  sub modify_login { Line 4768  sub modify_login {
             }              }
         }          }
     }      }
     my %loginhash;  
     ($errors,%colchanges) = &modify_colors($r,$dom,$confname,['login'],      ($errors,%colchanges) = &modify_colors($r,$dom,$confname,['login'],
                                            \%domconfig,\%loginhash);                                             \%domconfig,\%loginhash);
     my @toggles = ('coursecatalog','adminmail','newuser');      my @toggles = ('coursecatalog','adminmail','helpdesk','newuser');
     foreach my $item (@toggles) {      foreach my $item (@toggles) {
         $loginhash{login}{$item} = $env{'form.'.$item};          $loginhash{login}{$item} = $env{'form.'.$item};
     }      }
Line 3505  sub modify_login { Line 4780  sub modify_login {
                                          \%loginhash);                                           \%loginhash);
     }      }
   
     my %servers = &dom_servers($dom);      my %servers = &Apache::lonnet::internet_dom_servers($dom);
       my @loginvia_attribs = ('serverpath','custompath','exempt');
     if (keys(%servers) > 1) {      if (keys(%servers) > 1) {
         foreach my $lonhost (keys(%servers)) {          foreach my $lonhost (keys(%servers)) {
             next if ($env{'form.'.$lonhost.'_serverurl'} eq $lonhost);              next if ($env{'form.'.$lonhost.'_server'} eq $lonhost);
             if ($env{'form.'.$lonhost.'_serverurl'} eq $curr_loginvia{$lonhost}) {              if (ref($curr_loginvia{$lonhost}) eq 'HASH') {
                 $loginhash{login}{loginvia}{$lonhost} = $curr_loginvia{$lonhost};                next;                  if ($env{'form.'.$lonhost.'_server'} eq $curr_loginvia{$lonhost}{'server'}) {
             }                      $loginhash{login}{loginvia}{$lonhost}{'server'} = $curr_loginvia{$lonhost}{'server'};
             if ($curr_loginvia{$lonhost} ne '') {                  } elsif ($curr_loginvia{$lonhost}{'server'} ne '') {
                 $loginhash{login}{loginvia}{$lonhost} = $env{'form.'.$lonhost.'_serverurl'};                      if (defined($servers{$env{'form.'.$lonhost.'_server'}})) {
                 $changes{'loginvia'}{$lonhost} = 1;                          $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 {              } else {
                 if (defined($servers{$env{'form.'.$lonhost.'_serverurl'}})) {                  if (defined($servers{$env{'form.'.$lonhost.'_server'}})) {
                     $loginhash{login}{loginvia}{$lonhost} = $env{'form.'.$lonhost.'_serverurl'};                      $loginhash{login}{loginvia}{$lonhost}{'server'} = $env{'form.'.$lonhost.'_server'};
                     $changes{'loginvia'}{$lonhost} = 1;                      $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 $servadm = $r->dir_config('lonAdmEMail');
       my %langchoices = &Apache::lonlocal::texthash(&get_languages_hash());
       if (ref($domconfig{'login'}) eq 'HASH') {
           if (ref($domconfig{'login'}{'helpurl'}) eq 'HASH') {
               foreach my $lang (sort(keys(%{$domconfig{'login'}{'helpurl'}}))) {
                   if ($lang eq 'nolang') {
                       push(@currlangs,$lang);
                   } elsif (defined($langchoices{$lang})) {
                       push(@currlangs,$lang);
                   } else {
                       next;
                   }
               }
           }
       }
       my @delurls = &Apache::loncommon::get_env_multiple('form.loginhelpurl_del');
       if (@currlangs > 0) {
           foreach my $lang (@currlangs) {
               if (grep(/^\Q$lang\E$/,@delurls)) {
                   $changes{'helpurl'}{$lang} = 1;
               } elsif ($env{'form.loginhelpurl_'.$lang.'.filename'}) {
                   $changes{'helpurl'}{$lang} = 1;
                   $newfile{$lang} = $env{'form.loginhelpurl_'.$lang.'.filename'};
                   push(@newlangs,$lang);
               } else {
                   $loginhash{'login'}{'helpurl'}{$lang} = $domconfig{'login'}{'helpurl'}{$lang};
               }
           }
       }
       unless (grep(/^nolang$/,@currlangs)) {
           if ($env{'form.loginhelpurl_nolang.filename'}) {
               $changes{'helpurl'}{'nolang'} = 1;
               $newfile{'nolang'} = $env{'form.loginhelpurl_nolang.filename'};
               push(@newlangs,'nolang');
           }
       }
       if ($env{'form.loginhelpurl_add_lang'}) {
           if ((defined($langchoices{$env{'form.loginhelpurl_add_lang'}})) &&
               ($env{'form.loginhelpurl_add_file.filename'})) {
               $newfile{$env{'form.loginhelpurl_add_lang'}} = $env{'form.loginhelpurl_add_file.filename'};
               $addedfile = $env{'form.loginhelpurl_add_lang'};
           }
       }
       if ((@newlangs > 0) || ($addedfile)) {
           my $error;
           my ($configuserok,$author_ok,$switchserver) = &config_check($dom,$confname,$servadm);
           if ($configuserok eq 'ok') {
               if ($switchserver) {
                   $error = &mt("Upload of custom help file is not permitted to this server: [_1]",$switchserver);
               } elsif ($author_ok eq 'ok') {
                   my @allnew = @newlangs;
                   if ($addedfile ne '') {
                       push(@allnew,$addedfile);
                   }
                   foreach my $lang (@allnew) {
                       my $formelem = 'loginhelpurl_'.$lang;
                       if ($lang eq $env{'form.loginhelpurl_add_lang'}) {
                           $formelem = 'loginhelpurl_add_file';
                       }
                       (my $result,$newurl{$lang}) = &publishlogo($r,'upload',$formelem,$dom,$confname,
                                                                  "help/$lang",'','',$newfile{$lang});
                       if ($result eq 'ok') {
                           $loginhash{'login'}{'helpurl'}{$lang} = $newurl{$lang};
                           $changes{'helpurl'}{$lang} = 1;
                       } else {
                           my $puberror = &mt("Upload of [_1] failed because an error occurred publishing the file in RES space. Error was: [_2].",$newfile{$lang},$result);
                           $errors .= '<li><span class="LC_error">'.$puberror.'</span></li>';
                           if ((grep(/^\Q$lang\E$/,@currlangs)) &&
                               (!grep(/^\Q$lang\E$/,@delurls))) {
   
                               $loginhash{'login'}{'helpurl'}{$lang} = $domconfig{'login'}{'helpurl'}{$lang};
                           }
                       }
                 }                  }
               } else {
                   $error = &mt("Upload of custom log-in help file(s) failed because an author role could not be assigned to a Domain Configuration user ([_1]) in domain: [_2].  Error was: [_3].",$confname,$dom,$author_ok);
             }              }
           } else {
               $error = &mt("Upload of custom log-in help file(s) failed because a Domain Configuration user ([_1]) could not be created in domain: [_2].  Error was: [_3].",$confname,$dom,$configuserok);
           }
           if ($error) {
               &Apache::lonnet::logthis($error);
               $errors .= '<li><span class="LC_error">'.$error.'</span></li>';
         }          }
     }      }
       &process_captcha('login',\%changes,$loginhash{'login'},$domconfig{'login'});
   
       my $defaulthelpfile = '/adm/loginproblems.html';
       my $defaulttext = &mt('Default in use');
   
     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') {
         my @toggles = ('coursecatalog','adminmail','newuser');          my @toggles = ('coursecatalog','adminmail','helpdesk','newuser');
         my %defaultchecked = (          my %defaultchecked = (
                     'coursecatalog' => 'on',                      'coursecatalog' => 'on',
                       'helpdesk'      => 'on',
                     'adminmail'     => 'off',                      'adminmail'     => 'off',
                     'newuser'       => 'off',                      'newuser'       => 'off',
         );          );
Line 3555  sub modify_login { Line 4987  sub modify_login {
                     }                      }
                 }                  }
             }              }
             if (($domconfig{'login'}{'loginheader'} eq 'text') &&   
                 ($env{'form.loginheader'} eq 'image')) {  
                 $changes{'loginheader'} = 1;  
             } elsif (($domconfig{'login'}{'loginheader'} eq '' ||  
                       $domconfig{'login'}{'loginheader'} eq 'image') &&  
                      ($env{'form.loginheader'} eq 'text')) {  
                 $changes{'loginheader'} = 1;  
             }  
         }          }
         if (keys(%changes) > 0 || $colchgtext) {          if (keys(%changes) > 0 || $colchgtext) {
             &Apache::loncommon::devalidate_domconfig_cache($dom);              &Apache::loncommon::devalidate_domconfig_cache($dom);
               if (ref($lastactref) eq 'HASH') {
                   $lastactref->{'domainconfig'} = 1;
               }
             $resulttext = &mt('Changes made:').'<ul>';              $resulttext = &mt('Changes made:').'<ul>';
             foreach my $item (sort(keys(%changes))) {              foreach my $item (sort(keys(%changes))) {
                 if ($item eq 'loginheader') {                  if ($item eq 'loginvia') {
                     $resulttext .= '<li>'.&mt("$title{$item} set to $env{'form.loginheader'}").'</li>';  
                 } elsif ($item eq 'loginvia') {  
                     if (ref($changes{$item}) eq 'HASH') {                      if (ref($changes{$item}) eq 'HASH') {
                         $resulttext .= '<li>'.&mt('Log-in page availability:').'<ul>';                          $resulttext .= '<li>'.&mt('Log-in page availability:').'<ul>';
                         foreach my $lonhost (sort(keys(%{$changes{$item}}))) {                          foreach my $lonhost (sort(keys(%{$changes{$item}}))) {
                             if ($servers{$env{'form.'.$lonhost.'_serverurl'}} ne '') {                              if (defined($servers{$loginhash{login}{loginvia}{$lonhost}{'server'}})) {
                                 $resulttext .= '<li>'.&mt('Server: [_1] log-in page now redirects to [_2]',$lonhost,$servers{$env{'form.'.$lonhost.'_serverurl'}}).'</li>';                                  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 {                              } else {
                                 $resulttext .= '<li>'.&mt('Server: [_1] now has standard log-in page.',$lonhost).'</li>';                                  $resulttext .= '<li>'.&mt('Server: [_1] has standard log-in page.',$servers{$lonhost}).'</li>';
                             }                              }
                         }                          }
                         $resulttext .= '</ul></li>';                           $resulttext .= '</ul></li>';
                       }
                   } elsif ($item eq 'helpurl') {
                       if (ref($changes{$item}) eq 'HASH') {
                           foreach my $lang (sort(keys(%{$changes{$item}}))) {
                               if (grep(/^\Q$lang\E$/,@delurls)) {
                                   my ($chg,$link);
                                   $link = &Apache::loncommon::modal_link($defaulthelpfile,$defaulttext,600,500);
                                   if ($lang eq 'nolang') {
                                       $chg = &mt('custom log-in help file removed for no preferred language; [_1]',$link);
                                   } else {
                                       $chg = &mt('custom log-in help file removed for specific language: [_1]; [_2]',$langchoices{$lang},$link);
                                   }
                                   $resulttext .= '<li>'.$chg.'</li>';
                               } else {
                                   my $chg;
                                   if ($lang eq 'nolang') {
                                       $chg = &mt('custom log-in help file for no preferred language');
                                   } else {
                                       $chg = &mt('custom log-in help file for specific language: [_1]',$langchoices{$lang});
                                   }
                                   $resulttext .= '<li>'.&Apache::loncommon::modal_link(
                                                         $loginhash{'login'}{'helpurl'}{$lang}.
                                                         '?inhibitmenu=yes',$chg,600,500).
                                                  '</li>';
                               }
                           }
                       }
                   } elsif ($item eq 'captcha') {
                       if (ref($loginhash{'login'}) eq 'HASH') {
                           my $chgtxt;
                           if ($loginhash{'login'}{$item} eq 'notused') {
                               $chgtxt .= &mt('No CAPTCHA validation in use for helpdesk form.');
                           } else {
                               my %captchas = &captcha_phrases();
                               if ($captchas{$loginhash{'login'}{$item}}) {
                                   $chgtxt .= &mt("Validation for helpdesk form set to $captchas{$loginhash{'login'}{$item}}.");
                               } else {
                                   $chgtxt .= &mt('Validation for helpdesk form set to unknown type.');
                               }
                           }
                           $resulttext .= '<li>'.$chgtxt.'</li>';
                       }
                   } elsif ($item eq 'recaptchakeys') {
                       if (ref($loginhash{'login'}) eq 'HASH') {
                           my ($privkey,$pubkey);
                           if (ref($loginhash{'login'}{$item}) eq 'HASH') {
                               $pubkey = $loginhash{'login'}{$item}{'public'};
                               $privkey = $loginhash{'login'}{$item}{'private'};
                           }
                           my $chgtxt .= &mt('ReCAPTCHA keys changes').'<ul>';
                           if (!$pubkey) {
                               $chgtxt .= '<li>'.&mt('Public key deleted').'</li>';
                           } else {
                               $chgtxt .= '<li>'.&mt('Public key set to [_1]',$pubkey).'</li>';
                           }
                           if (!$privkey) {
                               $chgtxt .= '<li>'.&mt('Private key deleted').'</li>';
                           } else {
                               $chgtxt .= '<li>'.&mt('Private key set to [_1]',$pubkey).'</li>';
                           }
                           $chgtxt .= '</ul>';
                           $resulttext .= '<li>'.$chgtxt.'</li>';
                     }                      }
                 } else {                  } else {
                     $resulttext .= '<li>'.&mt("$title{$item} set to $offon[$env{'form.'.$item}]").'</li>';                      $resulttext .= '<li>'.&mt("$title{$item} set to $offon[$env{'form.'.$item}]").'</li>';
Line 3609  sub color_font_choices { Line 5113  sub color_font_choices {
             links => "Link colors",              links => "Link colors",
             images => "Images",              images => "Images",
             font => "Font color",              font => "Font color",
             fontmenu => "Font Menu",              fontmenu => "Font menu",
             pgbg => "Page",              pgbg => "Page",
             tabbg => "Header",              tabbg => "Header",
             sidebg => "Border",              sidebg => "Border",
Line 3621  sub color_font_choices { Line 5125  sub color_font_choices {
 }  }
   
 sub modify_rolecolors {  sub modify_rolecolors {
     my ($r,$dom,$confname,$roles,%domconfig) = @_;      my ($r,$dom,$confname,$roles,$lastactref,%domconfig) = @_;
     my ($resulttext,%rolehash);      my ($resulttext,%rolehash);
     $rolehash{'rolecolors'} = {};      $rolehash{'rolecolors'} = {};
     if (ref($domconfig{'rolecolors'}) ne 'HASH') {      if (ref($domconfig{'rolecolors'}) ne 'HASH') {
Line 3636  sub modify_rolecolors { Line 5140  sub modify_rolecolors {
     if ($putresult eq 'ok') {      if ($putresult eq 'ok') {
         if (keys(%changes) > 0) {          if (keys(%changes) > 0) {
             &Apache::loncommon::devalidate_domconfig_cache($dom);              &Apache::loncommon::devalidate_domconfig_cache($dom);
               if (ref($lastactref) eq 'HASH') {
                   $lastactref->{'domainconfig'} = 1;
               }
             $resulttext = &display_colorchgs($dom,\%changes,$roles,              $resulttext = &display_colorchgs($dom,\%changes,$roles,
                                              $rolehash{'rolecolors'});                                               $rolehash{'rolecolors'});
         } else {          } else {
Line 3661  sub modify_colors { Line 5168  sub modify_colors {
     my @images;      my @images;
     my $servadm = $r->dir_config('lonAdmEMail');      my $servadm = $r->dir_config('lonAdmEMail');
     my $errors;      my $errors;
       my %defaults;
     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');              @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','login');              @images = ('img','logo','domlogo','login');
             @bgs = ('pgbg','mainbg','sidebg');              @bgs = ('pgbg','mainbg','sidebg');
         } else {          } else {
             @images = ('img');              @images = ('img');
             @bgs = ('pgbg','tabbg','sidebg');               @bgs = ('pgbg','tabbg','sidebg');
           }
           my %defaults = &role_defaults($role,\@bgs,\@links,\@images,\@logintext);
           unless ($env{'form.'.$role.'_font'} eq $defaults{'font'}) {
               $confhash->{$role}{'font'} = $env{'form.'.$role.'_font'};
           }
           if ($role eq 'login') {
               foreach my $item (@logintext) {
                   unless ($env{'form.'.$role.'_'.$item} eq  $defaults{'logintext'}{$item}) {
                       $confhash->{$role}{$item} = $env{'form.'.$role.'_'.$item};
                   }
               }
           } else {
               unless($env{'form.'.$role.'_fontmenu'} eq $defaults{'fontmenu'}) {
                   $confhash->{$role}{'fontmenu'} = $env{'form.'.$role.'_fontmenu'};
               }
           }
           foreach my $item (@bgs) {
               unless ($env{'form.'.$role.'_'.$item} eq $defaults{'bgs'}{$item} ) {
                   $confhash->{$role}{$item} = $env{'form.'.$role.'_'.$item};
               }
         }          }
         $confhash->{$role}{'font'} = $env{'form.'.$role.'_font'};          foreach my $item (@links) {
         foreach my $item (@bgs,@links,@logintext) {              unless ($env{'form.'.$role.'_'.$item} eq  $defaults{'links'}{$item}) {
             $confhash->{$role}{$item} = $env{'form.'.$role.'_'.$item};                  $confhash->{$role}{$item} = $env{'form.'.$role.'_'.$item};
               }
         }          }
         my ($configuserok,$author_ok,$switchserver) =           my ($configuserok,$author_ok,$switchserver) = 
             &config_check($dom,$confname,$servadm);              &config_check($dom,$confname,$servadm);
Line 4026  sub publishlogo { Line 5554  sub publishlogo {
 # 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'); }
     $fname="$subdir/$fname";      $fname="$subdir/$fname";
     my $filepath='/home/'.$confname.'/public_html';      my $docroot=$r->dir_config('lonDocRoot');
       my $filepath="$docroot/priv";
       my $relpath = "$dom/$confname";
     my ($fnamepath,$file,$fetchthumb);      my ($fnamepath,$file,$fetchthumb);
     $file=$fname;      $file=$fname;
     if ($fname=~m|/|) {      if ($fname=~m|/|) {
         ($fnamepath,$file) = ($fname =~ m|^(.*)/([^/]+)$|);          ($fnamepath,$file) = ($fname =~ m|^(.*)/([^/]+)$|);
     }      }
     my @parts=split(/\//,$filepath.'/'.$fnamepath);      my @parts=split(/\//,"$filepath/$relpath/$fnamepath");
     my $count;      my $count;
     for ($count=4;$count<=$#parts;$count++) {      for ($count=5;$count<=$#parts;$count++) {
         $filepath.="/$parts[$count]";          $filepath.="/$parts[$count]";
         if ((-e $filepath)!=1) {          if ((-e $filepath)!=1) {
             mkdir($filepath,02770);              mkdir($filepath,02770);
Line 4044  sub publishlogo { Line 5574  sub publishlogo {
     if ($file=~/\.(\w+)$/ &&      if ($file=~/\.(\w+)$/ &&
         (&Apache::loncommon::fileembstyle($1) eq 'hdn')) {          (&Apache::loncommon::fileembstyle($1) eq 'hdn')) {
         $output =           $output = 
             &mt('Invalid file extension ([_1]) - reserved for LONCAPA use.',$1);               &mt('Invalid file extension ([_1]) - reserved for internal use.',$1); 
     } elsif ($file=~/\.(\w+)$/ &&      } elsif ($file=~/\.(\w+)$/ &&
         !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 - rename the file to remove the number immediately before the file extension([_1]) and re-upload.',$2);          $output = &mt('Filename 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('Filename is a directory name - rename the file and re-upload');
     } else {      } else {
         my $source = $filepath.'/'.$file;          my $source = $filepath.'/'.$file;
         my $logfile;          my $logfile;
         if (!open($logfile,">>$source".'.log')) {          if (!open($logfile,">>$source".'.log')) {
             return (&mt('No write permission to Construction Space'));              return (&mt('No write permission to Authoring Space'));
         }          }
         print $logfile          print $logfile
 "\n================= Publish ".localtime()." ================\n".  "\n================= Publish ".localtime()." ================\n".
Line 4081  $env{'user.name'}.':'.$env{'user.domain' Line 5611  $env{'user.name'}.':'.$env{'user.domain'
         close(FH);          close(FH);
         chmod(0660, $source); # Permissions to rw-rw---.          chmod(0660, $source); # Permissions to rw-rw---.
   
         my $docroot=$r->dir_config('lonDocRoot');  
         my $targetdir=$docroot.'/res/'.$dom.'/'.$confname .'/'.$fnamepath;          my $targetdir=$docroot.'/res/'.$dom.'/'.$confname .'/'.$fnamepath;
         my $copyfile=$targetdir.'/'.$file;          my $copyfile=$targetdir.'/'.$file;
   
Line 4104  $env{'user.name'}.':'.$env{'user.domain' Line 5633  $env{'user.name'}.':'.$env{'user.domain'
             if (copy($source,$copyfile)) {              if (copy($source,$copyfile)) {
                 print $logfile "\nCopied original source to ".$copyfile."\n";                  print $logfile "\nCopied original source to ".$copyfile."\n";
                 $output = 'ok';                  $output = 'ok';
                 &write_metadata($dom,$confname,$formname,$targetdir,$file,$logfile);  
                 $logourl = '/res/'.$dom.'/'.$confname.'/'.$fname;                  $logourl = '/res/'.$dom.'/'.$confname.'/'.$fname;
                   push(@{$modified_urls},[$copyfile,$source]);
                   my $metaoutput = 
                       &write_metadata($dom,$confname,$formname,$targetdir,$file,$logfile);
                   unless ($registered_cleanup) {
                       my $handlers = $r->get_handlers('PerlCleanupHandler');
                       $r->set_handlers('PerlCleanupHandler' => [\&notifysubscribed,@{$handlers}]);
                       $registered_cleanup=1;
                   }
             } else {              } else {
                 print $logfile "\nUnable to write ".$copyfile.':'.$!."\n";                  print $logfile "\nUnable to write ".$copyfile.':'.$!."\n";
                 $output = &mt('Failed to copy file to RES space').", $!";                  $output = &mt('Failed to copy file to RES space').", $!";
Line 4123  $env{'user.name'}.':'.$env{'user.domain' Line 5659  $env{'user.name'}.':'.$env{'user.domain'
                             my $copyfile=$targetdir.'/tn-'.$file;                              my $copyfile=$targetdir.'/tn-'.$file;
                             if (copy($outfile,$copyfile)) {                              if (copy($outfile,$copyfile)) {
                                 print $logfile "\nCopied source to ".$copyfile."\n";                                  print $logfile "\nCopied source to ".$copyfile."\n";
                                 &write_metadata($dom,$confname,$formname,                                  my $thumb_metaoutput = 
                                                 $targetdir,'tn-'.$file,$logfile);                                      &write_metadata($dom,$confname,$formname,
                                                       $targetdir,'tn-'.$file,$logfile);
                                   push(@{$modified_urls},[$copyfile,$outfile]);
                                   unless ($registered_cleanup) {
                                       my $handlers = $r->get_handlers('PerlCleanupHandler');
                                       $r->set_handlers('PerlCleanupHandler' => [\&notifysubscribed,@{$handlers}]);
                                       $registered_cleanup=1;
                                   }
                             } else {                              } else {
                                 print $logfile "\nUnable to write ".$copyfile.                                  print $logfile "\nUnable to write ".$copyfile.
                                                ':'.$!."\n";                                                 ':'.$!."\n";
Line 4189  sub write_metadata { Line 5732  sub write_metadata {
     {      {
         print $logfile "\nWrite metadata file for ".$targetdir.'/'.$file;          print $logfile "\nWrite metadata file for ".$targetdir.'/'.$file;
         my $mfh;          my $mfh;
         unless (open($mfh,'>'.$targetdir.'/'.$file.'.meta')) {          if (open($mfh,'>'.$targetdir.'/'.$file.'.meta')) {
               foreach (sort(keys(%metadatafields))) {
                   unless ($_=~/\./) {
                       my $unikey=$_;
                       $unikey=~/^([A-Za-z]+)/;
                       my $tag=$1;
                       $tag=~tr/A-Z/a-z/;
                       print $mfh "\n\<$tag";
                       foreach (split(/\,/,$metadatakeys{$unikey})) {
                           my $value=$metadatafields{$unikey.'.'.$_};
                           $value=~s/\"/\'\'/g;
                           print $mfh ' '.$_.'="'.$value.'"';
                       }
                       print $mfh '>'.
                           &HTML::Entities::encode($metadatafields{$unikey},'<>&"')
                               .'</'.$tag.'>';
                   }
               }
               $output = 'ok';
               print $logfile "\nWrote metadata";
               close($mfh);
           } else {
               print $logfile "\nFailed to open metadata file";
             $output = &mt('Could not write metadata');              $output = &mt('Could not write metadata');
         }          }
         foreach (sort keys %metadatafields) {  
             unless ($_=~/\./) {  
                 my $unikey=$_;  
                 $unikey=~/^([A-Za-z]+)/;  
                 my $tag=$1;  
                 $tag=~tr/A-Z/a-z/;  
                 print $mfh "\n\<$tag";  
                 foreach (split(/\,/,$metadatakeys{$unikey})) {  
                     my $value=$metadatafields{$unikey.'.'.$_};  
                     $value=~s/\"/\'\'/g;  
                     print $mfh ' '.$_.'="'.$value.'"';  
                 }  
                 print $mfh '>'.  
                     &HTML::Entities::encode($metadatafields{$unikey},'<>&"')  
                         .'</'.$tag.'>';  
             }  
         }  
         $output = 'ok';  
         print $logfile "\nWrote metadata";  
         close($mfh);  
     }      }
       return $output;
   }
   
   sub notifysubscribed {
       foreach my $targetsource (@{$modified_urls}){
           next unless (ref($targetsource) eq 'ARRAY');
           my ($target,$source)=@{$targetsource};
           if ($source ne '') {
               if (open(my $logfh,'>>'.$source.'.log')) {
                   print $logfh "\nCleanup phase: Notifications\n";
                   my @subscribed=&subscribed_hosts($target);
                   foreach my $subhost (@subscribed) {
                       print $logfh "\nNotifying host ".$subhost.':';
                       my $reply=&Apache::lonnet::critical('update:'.$target,$subhost);
                       print $logfh $reply;
                   }
                   my @subscribedmeta=&subscribed_hosts("$target.meta");
                   foreach my $subhost (@subscribedmeta) {
                       print $logfh "\nNotifying host for metadata only ".$subhost.':';
                       my $reply=&Apache::lonnet::critical('update:'.$target.'.meta',
                                                           $subhost);
                       print $logfh $reply;
                   }
                   print $logfh "\n============ Done ============\n";
                   close($logfh);
               }
           }
       }
       return OK;
   }
   
   sub subscribed_hosts {
       my ($target) = @_;
       my @subscribed;
       if (open(my $fh,"<$target.subscription")) {
           while (my $subline=<$fh>) {
               if ($subline =~ /^($match_lonid):/) {
                   my $host = $1;
                   if ($host ne $Apache::lonnet::perlvar{'lonHostID'}) {
                       unless (grep(/^\Q$host\E$/,@subscribed)) {
                           push(@subscribed,$host);
                       }
                   }
               }
           }
       }
       return @subscribed;
 }  }
   
 sub check_switchserver {  sub check_switchserver {
Line 4225  sub check_switchserver { Line 5817  sub check_switchserver {
     my @ids=&Apache::lonnet::current_machine_ids();      my @ids=&Apache::lonnet::current_machine_ids();
     foreach my $id (@ids) { if ($id eq $home) { $allowed=1; } }      foreach my $id (@ids) { if ($id eq $home) { $allowed=1; } }
     if (!$allowed) {      if (!$allowed) {
  $switchserver='<a href="/adm/switchserver?otherserver='.$home.'&role=dc./'.$dom.'/">'.&mt('Switch Server').'</a>';   $switchserver='<a href="/adm/switchserver?otherserver='.$home.'&amp;role=dc./'.$dom.'/&amp;destinationurl=/adm/domainprefs">'.&mt('Switch Server').'</a>';
     }      }
     return $switchserver;      return $switchserver;
 }  }
   
 sub modify_quotas {  sub modify_quotas {
     my ($dom,$action,%domconfig) = @_;      my ($dom,$action,$lastactref,%domconfig) = @_;
     my ($context,@usertools,@options,%validations,%titles,%confhash,%toolshash,      my ($context,@usertools,@options,%validations,%titles,%confhash,%toolshash,
         %limithash,$toolregexp,%conditions,$resulttext,%changes);          %limithash,$toolregexp,%conditions,$resulttext,%changes);
     if ($action eq 'quotas') {      if ($action eq 'quotas') {
         $context = 'tools';           $context = 'tools'; 
     } else {       } else {
         $context = $action;          $context = $action;
     }      }
     if ($context eq 'requestcourses') {      if ($context eq 'requestcourses') {
Line 4246  sub modify_quotas { Line 5838  sub modify_quotas {
         %titles = &courserequest_titles();          %titles = &courserequest_titles();
         $toolregexp = join('|',@usertools);          $toolregexp = join('|',@usertools);
         %conditions = &courserequest_conditions();          %conditions = &courserequest_conditions();
       } elsif ($context eq 'requestauthor') {
           @usertools = ('author');
           %titles = &authorrequest_titles();
     } else {      } else {
         @usertools = ('aboutme','blog','portfolio');          @usertools = ('aboutme','blog','webdav','portfolio');
         %titles = &tool_titles();          %titles = &tool_titles();
     }      }
     my %domdefaults = &Apache::lonnet::get_domain_defaults($dom);      my %domdefaults = &Apache::lonnet::get_domain_defaults($dom,1);
     my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom);      my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom);
     foreach my $key (keys(%env)) {      foreach my $key (keys(%env)) {
         if ($context eq 'requestcourses') {          if ($context eq 'requestcourses') {
Line 4263  sub modify_quotas { Line 5858  sub modify_quotas {
                     $confhash{$item}{$type} = $env{$key};                      $confhash{$item}{$type} = $env{$key};
                 }                  }
             }              }
           } elsif ($context eq 'requestauthor') {
               if ($key =~ /^\Qform.authorreq_\E(.+)$/) {
                   $confhash{$1} = $env{$key};
               }
         } else {          } else {
             if ($key =~ /^form\.quota_(.+)$/) {              if ($key =~ /^form\.quota_(.+)$/) {
                 $confhash{'defaultquota'}{$1} = $env{$key};                  $confhash{'defaultquota'}{$1} = $env{$key};
             }              } elsif ($key =~ /^form\.authorquota_(.+)$/) {
             if ($key =~ /^form\.\Q$context\E_(.+)$/) {                  $confhash{'authorquota'}{$1} = $env{$key};
               } elsif ($key =~ /^form\.\Q$context\E_(.+)$/) {
                 @{$toolshash{$1}} = &Apache::loncommon::get_env_multiple($key);                  @{$toolshash{$1}} = &Apache::loncommon::get_env_multiple($key);
             }              }
         }          }
     }      }
     if ($context eq 'requestcourses') {      if (($context eq 'requestcourses') || ($context eq 'requestauthor')) {
         my @approvalnotify = &Apache::loncommon::get_env_multiple('form.reqapprovalnotify');          my @approvalnotify = &Apache::loncommon::get_env_multiple('form.reqapprovalnotify');
         @approvalnotify = sort(@approvalnotify);          @approvalnotify = sort(@approvalnotify);
         $confhash{'notify'}{'approval'} = join(',',@approvalnotify);          $confhash{'notify'}{'approval'} = join(',',@approvalnotify);
Line 4282  sub modify_quotas { Line 5882  sub modify_quotas {
                     $changes{'notify'}{'approval'} = 1;                      $changes{'notify'}{'approval'} = 1;
                 }                  }
             } else {              } else {
                 if ($domconfig{$action}{'notify'}{'approval'}) {                  if ($confhash{'notify'}{'approval'}) {
                     $changes{'notify'}{'approval'} = 1;                      $changes{'notify'}{'approval'} = 1;
                 }                  }
             }              }
         } else {          } else {
             if ($domconfig{$action}{'notify'}{'approval'}) {              if ($confhash{'notify'}{'approval'}) {
                 $changes{'notify'}{'approval'} = 1;                  $changes{'notify'}{'approval'} = 1;
             }              }
         }          }
     } else {      } else {
         $confhash{'defaultquota'}{'default'} = $env{'form.defaultquota'};          $confhash{'defaultquota'}{'default'} = $env{'form.defaultquota'};
           $confhash{'authorquota'}{'default'} = $env{'form.authorquota'};
     }      }
     foreach my $item (@usertools) {      foreach my $item (@usertools) {
         foreach my $type (@{$types},'default','_LC_adv') {          foreach my $type (@{$types},'default','_LC_adv') {
Line 4308  sub modify_quotas { Line 5909  sub modify_quotas {
                         $confhash{$item}{$type} .= $limithash{$item}{$type};                          $confhash{$item}{$type} .= $limithash{$item}{$type};
                     }                      }
                 }                  }
               } elsif ($context eq 'requestauthor') {
                   $unset = '0';
                   if ($type eq '_LC_adv') {
                       $unset = '';
                   }
             } else {              } else {
                 if (grep(/^\Q$type\E$/,@{$toolshash{$item}})) {                  if (grep(/^\Q$type\E$/,@{$toolshash{$item}})) {
                     $confhash{$item}{$type} = 1;                      $confhash{$item}{$type} = 1;
Line 4316  sub modify_quotas { Line 5922  sub modify_quotas {
                 }                  }
             }              }
             if (ref($domconfig{$action}) eq 'HASH') {              if (ref($domconfig{$action}) eq 'HASH') {
                 if (ref($domconfig{$action}{$item}) eq 'HASH') {                  if ($action eq 'requestauthor') {
                       if ($domconfig{$action}{$type} ne $confhash{$type}) {
                           $changes{$type} = 1;
                       }
                   } elsif (ref($domconfig{$action}{$item}) eq 'HASH') {
                     if ($domconfig{$action}{$item}{$type} ne $confhash{$item}{$type}) {                      if ($domconfig{$action}{$item}{$type} ne $confhash{$item}{$type}) {
                         $changes{$item}{$type} = 1;                          $changes{$item}{$type} = 1;
                     }                      }
Line 4336  sub modify_quotas { Line 5946  sub modify_quotas {
                     if ($confhash{$item}{$type} ne $unset) {                      if ($confhash{$item}{$type} ne $unset) {
                         $changes{$item}{$type} = 1;                          $changes{$item}{$type} = 1;
                     }                      }
                   } elsif ($context eq 'requestauthor') {
                       if ($confhash{$type} ne $unset) {
                           $changes{$type} = 1;
                       }
                 } else {                  } else {
                     if (!$confhash{$item}{$type}) {                      if (!$confhash{$item}{$type}) {
                         $changes{$item}{$type} = 1;                          $changes{$item}{$type} = 1;
Line 4344  sub modify_quotas { Line 5958  sub modify_quotas {
             }              }
         }          }
     }      }
     unless ($context eq 'requestcourses') {      unless (($context eq 'requestcourses') || ($context eq 'requestauthor')) {
         if (ref($domconfig{'quotas'}) eq 'HASH') {          if (ref($domconfig{'quotas'}) eq 'HASH') {
             if (ref($domconfig{'quotas'}{'defaultquota'}) eq 'HASH') {              if (ref($domconfig{'quotas'}{'defaultquota'}) eq 'HASH') {
                 foreach my $key (keys(%{$domconfig{'quotas'}{'defaultquota'}})) {                  foreach my $key (keys(%{$domconfig{'quotas'}{'defaultquota'}})) {
Line 4367  sub modify_quotas { Line 5981  sub modify_quotas {
                     }                      }
                 }                  }
             }              }
               if (ref($domconfig{'quotas'}{'authorquota'}) eq 'HASH') {
                   foreach my $key (keys(%{$domconfig{'quotas'}{'authorquota'}})) {
                       if (exists($confhash{'authorquota'}{$key})) {
                           if ($confhash{'authorquota'}{$key} ne $domconfig{'quotas'}{'authorquota'}{$key}) {
                               $changes{'authorquota'}{$key} = 1;
                           }
                       } else {
                           $confhash{'authorquota'}{$key} = $domconfig{'quotas'}{'authorquota'}{$key};
                       }
                   }
               }
         }          }
         if (ref($confhash{'defaultquota'}) eq 'HASH') {          if (ref($confhash{'defaultquota'}) eq 'HASH') {
             foreach my $key (keys(%{$confhash{'defaultquota'}})) {              foreach my $key (keys(%{$confhash{'defaultquota'}})) {
Line 4385  sub modify_quotas { Line 6010  sub modify_quotas {
                 }                  }
             }              }
         }          }
           if (ref($confhash{'authorquota'}) eq 'HASH') {
               foreach my $key (keys(%{$confhash{'authorquota'}})) {
                   if (ref($domconfig{'quotas'}) eq 'HASH') {
                       if (ref($domconfig{'quotas'}{'authorquota'}) eq 'HASH') {
                           if (!exists($domconfig{'quotas'}{'authorquota'}{$key})) {
                               $changes{'authorquota'}{$key} = 1;
                           }
                       } else {
                           $changes{'authorquota'}{$key} = 1;
                       }
                   } else {
                       $changes{'authorquota'}{$key} = 1;
                   }
               }
           }
     }      }
   
     foreach my $key (keys(%confhash)) {      if ($context eq 'requestauthor') {
         $domdefaults{$key} = $confhash{$key};          $domdefaults{'requestauthor'} = \%confhash;
       } else {
           foreach my $key (keys(%confhash)) {
               $domdefaults{$key} = $confhash{$key};
           }
     }      }
      
     my %quotahash = (      my %quotahash = (
                       $action => { %confhash }                        $action => { %confhash }
                     );                      );
Line 4400  sub modify_quotas { Line 6044  sub modify_quotas {
         if (keys(%changes) > 0) {          if (keys(%changes) > 0) {
             my $cachetime = 24*60*60;              my $cachetime = 24*60*60;
             &Apache::lonnet::do_cache_new('domdefaults',$dom,\%domdefaults,$cachetime);              &Apache::lonnet::do_cache_new('domdefaults',$dom,\%domdefaults,$cachetime);
               if (ref($lastactref) eq 'HASH') {
                   $lastactref->{'domdefaults'} = 1;
               }
             $resulttext = &mt('Changes made:').'<ul>';              $resulttext = &mt('Changes made:').'<ul>';
             unless ($context eq 'requestcourses') {              unless (($context eq 'requestcourses') ||
                       ($context eq 'requestauthor')) {
                 if (ref($changes{'defaultquota'}) eq 'HASH') {                  if (ref($changes{'defaultquota'}) eq 'HASH') {
                     $resulttext .= '<li>'.&mt('Portfolio default quotas').'<ul>';                      $resulttext .= '<li>'.&mt('Portfolio default quotas').'<ul>';
                     foreach my $type (@{$types},'default') {                      foreach my $type (@{$types},'default') {
Line 4411  sub modify_quotas { Line 6058  sub modify_quotas {
                             if ($type eq 'default') {                              if ($type eq 'default') {
                                 $typetitle = $othertitle;                                  $typetitle = $othertitle;
                             }                              }
                             $resulttext .= '<li>'.&mt('[_1] set to [_2] Mb',$typetitle,$confhash{'defaultquota'}{$type}).'</li>';                              $resulttext .= '<li>'.&mt('[_1] set to [_2] MB',$typetitle,$confhash{'defaultquota'}{$type}).'</li>';
                           }
                       }
                       $resulttext .= '</ul></li>';
                   }
                   if (ref($changes{'authorquota'}) eq 'HASH') {
                       $resulttext .= '<li>'.&mt('Authoring space default quotas').'<ul>';
                       foreach my $type (@{$types},'default') {
                           if (defined($changes{'authorquota'}{$type})) {
                               my $typetitle = $usertypes->{$type};
                               if ($type eq 'default') {
                                   $typetitle = $othertitle;
                               }
                               $resulttext .= '<li>'.&mt('[_1] set to [_2] MB',$typetitle,$confhash{'authorquota'}{$type}).'</li>';
                         }                          }
                     }                      }
                     $resulttext .= '</ul></li>';                      $resulttext .= '</ul></li>';
Line 4419  sub modify_quotas { Line 6079  sub modify_quotas {
             }              }
             my %newenv;              my %newenv;
             foreach my $item (@usertools) {              foreach my $item (@usertools) {
                 if (ref($changes{$item}) eq 'HASH') {                  my (%haschgs,%inconf);
                   if ($context eq 'requestauthor') {
                       %haschgs = %changes;
                       %inconf = %confhash;
                   } else {
                       if (ref($changes{$item}) eq 'HASH') {
                           %haschgs = %{$changes{$item}};
                       }
                       if (ref($confhash{$item}) eq 'HASH') {
                           %inconf = %{$confhash{$item}};
                       }
                   }
                   if (keys(%haschgs) > 0) {
                     my $newacc =                       my $newacc = 
                         &Apache::lonnet::usertools_access($env{'user.name'},                          &Apache::lonnet::usertools_access($env{'user.name'},
                                                           $env{'user.domain'},                                                            $env{'user.domain'},
                                                           $item,'reload',$context);                                                            $item,'reload',$context);
                     if ($context eq 'requestcourses') {                      if (($context eq 'requestcourses') ||
                           ($context eq 'requestauthor')) {
                         if ($env{'environment.canrequest.'.$item} ne $newacc) {                          if ($env{'environment.canrequest.'.$item} ne $newacc) {
                             $newenv{'environment.canrequest.'.$item} = $newacc;                              $newenv{'environment.canrequest.'.$item} = $newacc;
                         }                          }
Line 4433  sub modify_quotas { Line 6106  sub modify_quotas {
                             $newenv{'environment.availabletools.'.$item} = $newacc;                              $newenv{'environment.availabletools.'.$item} = $newacc;
                         }                          }
                     }                      }
                     $resulttext .= '<li>'.$titles{$item}.'<ul>';                      unless ($context eq 'requestauthor') {
                           $resulttext .= '<li>'.$titles{$item}.'<ul>';
                       }
                     foreach my $type (@{$types},'default','_LC_adv') {                      foreach my $type (@{$types},'default','_LC_adv') {
                         if ($changes{$item}{$type}) {                          if ($haschgs{$type}) {
                             my $typetitle = $usertypes->{$type};                              my $typetitle = $usertypes->{$type};
                             if ($type eq 'default') {                              if ($type eq 'default') {
                                 $typetitle = $othertitle;                                  $typetitle = $othertitle;
                             } elsif ($type eq '_LC_adv') {                              } elsif ($type eq '_LC_adv') {
                                 $typetitle = 'LON-CAPA Advanced Users';                                   $typetitle = 'LON-CAPA Advanced Users'; 
                             }                              }
                             if ($confhash{$item}{$type}) {                              if ($inconf{$type}) {
                                 if ($context eq 'requestcourses') {                                  if ($context eq 'requestcourses') {
                                     my $cond;                                      my $cond;
                                     if ($confhash{$item}{$type} =~ /^autolimit=(\d*)$/) {                                      if ($inconf{$type} =~ /^autolimit=(\d*)$/) {
                                         if ($1 eq '') {                                          if ($1 eq '') {
                                             $cond = &mt('(Automatic processing of any request).');                                              $cond = &mt('(Automatic processing of any request).');
                                         } else {                                          } else {
                                             $cond = &mt('(Automatic processing of requests up to limit of [quant,_1,request] per user).',$1);                                              $cond = &mt('(Automatic processing of requests up to limit of [quant,_1,request] per user).',$1);
                                         }                                          }
                                     } else {                                       } else { 
                                         $cond = $conditions{$confhash{$item}{$type}};                                          $cond = $conditions{$inconf{$type}};
                                     }                                      }
                                     $resulttext .= '<li>'.&mt('Set to be available to [_1].',$typetitle).' '.$cond.'</li>';                                      $resulttext .= '<li>'.&mt('Set to be available to [_1].',$typetitle).' '.$cond.'</li>';
                                   } elsif ($context eq 'requestauthor') {
                                       $resulttext .= '<li>'.&mt('Set to "[_1]" for "[_2]".',
                                                                $titles{$inconf{$type}},$typetitle);
   
                                 } else {                                  } else {
                                     $resulttext .= '<li>'.&mt('Set to be available to [_1]',$typetitle).'</li>';                                      $resulttext .= '<li>'.&mt('Set to be available to [_1]',$typetitle).'</li>';
                                 }                                  }
                             } else {                              } else {
                                 if ($type eq '_LC_adv') {                                  if ($type eq '_LC_adv') {
                                     if ($confhash{$item}{$type} eq '0') {                                      if ($inconf{$type} eq '0') {
                                         $resulttext .= '<li>'.&mt('Set to be unavailable to [_1]',$typetitle).'</li>';                                          $resulttext .= '<li>'.&mt('Set to be unavailable to [_1]',$typetitle).'</li>';
                                     } else {                                       } else { 
                                         $resulttext .= '<li>'.&mt('No override set for [_1]',$typetitle).'</li>';                                          $resulttext .= '<li>'.&mt('No override set for [_1]',$typetitle).'</li>';
Line 4471  sub modify_quotas { Line 6150  sub modify_quotas {
                             }                              }
                         }                          }
                     }                      }
                     $resulttext .= '</ul></li>';                      unless ($context eq 'requestauthor') {
                           $resulttext .= '</ul></li>';
                       }
                 }                  }
             }              }
             if ($action eq 'requestcourses') {              if (($action eq 'requestcourses') || ($action eq 'requestauthor')) {
                 if (ref($changes{'notify'}) eq 'HASH') {                  if (ref($changes{'notify'}) eq 'HASH') {
                     if ($changes{'notify'}{'approval'}) {                      if ($changes{'notify'}{'approval'}) {
                         if (ref($confhash{'notify'}) eq 'HASH') {                          if (ref($confhash{'notify'}) eq 'HASH') {
                             if ($confhash{'notify'}{'approval'}) {                              if ($confhash{'notify'}{'approval'}) {
                                 $resulttext .= '<li>'.&mt('Notification of requests requiring approval will be sent to: ').$confhash{'notify'}{'approval'}.'</li>';                                  $resulttext .= '<li>'.&mt('Notification of requests requiring approval will be sent to: ').$confhash{'notify'}{'approval'}.'</li>';
                             } else {                              } else {
                                 $resulttext .= '<li>'.&mt('No Domain Coordinators will receive notification of course requests requiring approval.').'</li>';                                  $resulttext .= '<li>'.&mt('No Domain Coordinators will receive notification of requests requiring approval.').'</li>';
                             }                              }
                         }                          }
                     }                      }
Line 4494  sub modify_quotas { Line 6175  sub modify_quotas {
         } else {          } else {
             if ($context eq 'requestcourses') {              if ($context eq 'requestcourses') {
                 $resulttext = &mt('No changes made to rights to request creation of courses.');                  $resulttext = &mt('No changes made to rights to request creation of courses.');
               } elsif ($context eq 'requestauthor') {
                   $resulttext = &mt('No changes made to rights to request author space.');
             } else {              } else {
                 $resulttext = &mt('No changes made to availability of personal information pages, blogs, portfolios or default quotas');                  $resulttext = &mt('No changes made to availability of personal information pages, blogs, portfolios or default quotas');
             }              }
Line 4506  sub modify_quotas { Line 6189  sub modify_quotas {
 }  }
   
 sub modify_autoenroll {  sub modify_autoenroll {
     my ($dom,%domconfig) = @_;      my ($dom,$lastactref,%domconfig) = @_;
     my ($resulttext,%changes);      my ($resulttext,%changes);
     my %currautoenroll;      my %currautoenroll;
     if (ref($domconfig{'autoenroll'}) eq 'HASH') {      if (ref($domconfig{'autoenroll'}) eq 'HASH') {
Line 4516  sub modify_autoenroll { Line 6199  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 4525  sub modify_autoenroll { Line 6209  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 4550  sub modify_autoenroll { Line 6235  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 4562  sub modify_autoenroll { Line 6254  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);
                   if (ref($lastactref) eq 'HASH') {
                       $lastactref->{'domainconfig'} = 1;
                   }
               }
             $resulttext .= '</ul>';              $resulttext .= '</ul>';
         } else {          } else {
             $resulttext = &mt('No changes made to auto-enrollment settings');              $resulttext = &mt('No changes made to auto-enrollment settings');
Line 4593  sub modify_autoupdate { Line 6292  sub modify_autoupdate {
                         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 4625  sub modify_autoupdate { Line 6346  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 4637  sub modify_autoupdate { Line 6360  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 4656  sub modify_autoupdate { Line 6408  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 4748  sub modify_autocreate { Line 6510  sub modify_autocreate {
             foreach my $item (@types) {              foreach my $item (@types) {
                 if ($changes{$item}) {                  if ($changes{$item}) {
                     my $newtxt = $offon[$newvals{$item}];                      my $newtxt = $offon[$newvals{$item}];
                     $resulttext .= '<li>'.&mt("$title{$item} set to [_1]$newtxt [_2]",'<b>','</b>').'</li>';                      $resulttext .= '<li>'.
                                      &mt("$title{$item} set to [_1]$newtxt [_2]",
                                          '<b>','</b>').
                                      '</li>';
                 }                  }
             }              }
             if ($changes{'xmldc'}) {              if ($changes{'xmldc'}) {
                 my ($dcname,$dcdom) = split(':',$newvals{'xmldc'});                  my ($dcname,$dcdom) = split(':',$newvals{'xmldc'});
                 my $newtxt = &Apache::loncommon::plainname($dcname,$dcdom);                  my $newtxt = &Apache::loncommon::plainname($dcname,$dcdom);
                 $resulttext .= '<li>'.&mt("$title{'xmldc'} set to [_1]$newtxt [_2]",'<b>','</b>').'</li>';                   $resulttext .= '<li>'.&mt("$title{'xmldc'} set to [_1]",'<b>'.$newtxt.'</b>').'</li>'; 
             }              }
             $resulttext .= '</ul>';              $resulttext .= '</ul>';
         } else {          } else {
Line 4900  sub modify_directorysrch { Line 6665  sub modify_directorysrch {
                         } else {                          } else {
                             $chgtext =~ s/\; $//;                              $chgtext =~ s/\; $//;
                         }                          }
                         $resulttext .= '<li>'.&mt("Users from domain '<span class=\"LC_cusr_emph\">[_1]</span>' permitted to search the institutional directory set to: [_2]",$dom,$chgtext).'</li>';                          $resulttext .=
                               '<li>'.
                               &mt("Users from domain '[_1]' permitted to search the institutional directory set to: [_2]",
                                   '<span class="LC_cusr_emph">'.$dom.'</span>',$chgtext).
                               '</li>';
                     }                      }
                 }                  }
             }              }
Line 4928  sub modify_directorysrch { Line 6697  sub modify_directorysrch {
                     }                      }
                 }                  }
                 $chgtext =~ s/\; $//;                  $chgtext =~ s/\; $//;
                 $resulttext .= '<li>'.&mt("$title{'searchtypes'} set to: \"[_1]\"",$chgtext).'</li>';                  $resulttext .= '<li>'.&mt($title{'searchtypes'}.' set to: "[_1]"',$chgtext).'</li>';
             }              }
             $resulttext .= '</ul>';              $resulttext .= '</ul>';
         } else {          } else {
Line 4942  sub modify_directorysrch { Line 6711  sub modify_directorysrch {
 }  }
   
 sub modify_contacts {  sub modify_contacts {
     my ($dom,%domconfig) = @_;      my ($dom,$lastactref,%domconfig) = @_;
     my ($resulttext,%currsetting,%newsetting,%changes,%contacts_hash);      my ($resulttext,%currsetting,%newsetting,%changes,%contacts_hash);
     if (ref($domconfig{'contacts'}) eq 'HASH') {      if (ref($domconfig{'contacts'}) eq 'HASH') {
         foreach my $key (keys(%{$domconfig{'contacts'}})) {          foreach my $key (keys(%{$domconfig{'contacts'}})) {
             $currsetting{$key} = $domconfig{'contacts'}{$key};              $currsetting{$key} = $domconfig{'contacts'}{$key};
         }          }
     }      }
     my (%others,%to);      my (%others,%to,%bcc);
     my @contacts = ('supportemail','adminemail');      my @contacts = ('supportemail','adminemail');
     my @mailings = ('errormail','packagesmail','helpdeskmail','lonstatusmail',      my @mailings = ('errormail','packagesmail','helpdeskmail','lonstatusmail',
                     'requestsmail');                      'requestsmail','updatesmail','idconflictsmail');
       my @toggles = ('reporterrors','reportupdates');
     foreach my $type (@mailings) {      foreach my $type (@mailings) {
         @{$newsetting{$type}} =           @{$newsetting{$type}} = 
             &Apache::loncommon::get_env_multiple('form.'.$type);              &Apache::loncommon::get_env_multiple('form.'.$type);
Line 4965  sub modify_contacts { Line 6735  sub modify_contacts {
         }            }  
         $others{$type} = $env{'form.'.$type.'_others'};          $others{$type} = $env{'form.'.$type.'_others'};
         $contacts_hash{contacts}{$type}{'others'} = $others{$type};          $contacts_hash{contacts}{$type}{'others'} = $others{$type};
           if ($type eq 'helpdeskmail') {
               $bcc{$type} = $env{'form.'.$type.'_bcc'};
               $contacts_hash{contacts}{$type}{'bcc'} = $bcc{$type};
           }
     }      }
     foreach my $item (@contacts) {      foreach my $item (@contacts) {
         $to{$item} = $env{'form.'.$item};          $to{$item} = $env{'form.'.$item};
         $contacts_hash{'contacts'}{$item} = $to{$item};          $contacts_hash{'contacts'}{$item} = $to{$item};
     }      }
       foreach my $item (@toggles) {
           if ($env{'form.'.$item} =~ /^(0|1)$/) {
               $contacts_hash{'contacts'}{$item} = $env{'form.'.$item};
           }
       }
     if (keys(%currsetting) > 0) {      if (keys(%currsetting) > 0) {
         foreach my $item (@contacts) {          foreach my $item (@contacts) {
             if ($to{$item} ne $currsetting{$item}) {              if ($to{$item} ne $currsetting{$item}) {
Line 4989  sub modify_contacts { Line 6768  sub modify_contacts {
             if ($others{$type} ne $currsetting{$type}{'others'}) {              if ($others{$type} ne $currsetting{$type}{'others'}) {
                 push(@{$changes{$type}},'others');                  push(@{$changes{$type}},'others');
             }              }
               if ($type eq 'helpdeskmail') {   
                   if ($bcc{$type} ne $currsetting{$type}{'bcc'}) {
                       push(@{$changes{$type}},'bcc'); 
                   }
               }
         }          }
     } else {      } else {
         my %default;          my %default;
Line 4999  sub modify_contacts { Line 6783  sub modify_contacts {
         $default{'helpdeskmail'} = 'supportemail';          $default{'helpdeskmail'} = 'supportemail';
         $default{'lonstatusmail'} = 'adminemail';          $default{'lonstatusmail'} = 'adminemail';
         $default{'requestsmail'} = 'adminemail';          $default{'requestsmail'} = 'adminemail';
           $default{'updatesmail'} = 'adminemail';
         foreach my $item (@contacts) {          foreach my $item (@contacts) {
            if ($to{$item} ne $default{$item}) {             if ($to{$item} ne $default{$item}) {
               $changes{$item} = 1;                $changes{$item} = 1;
            }              }
         }          }
         foreach my $type (@mailings) {          foreach my $type (@mailings) {
             if ((@{$newsetting{$type}} != 1) || ($newsetting{$type}[0] ne $default{$type})) {              if ((@{$newsetting{$type}} != 1) || ($newsetting{$type}[0] ne $default{$type})) {
Line 5011  sub modify_contacts { Line 6796  sub modify_contacts {
             }              }
             if ($others{$type} ne '') {              if ($others{$type} ne '') {
                 push(@{$changes{$type}},'others');                  push(@{$changes{$type}},'others');
             }               }
               if ($type eq 'helpdeskmail') {
                   if ($bcc{$type} ne '') {
                       push(@{$changes{$type}},'bcc');
                   }
               }
           }
       }
       foreach my $item (@toggles) {
           if (($env{'form.'.$item} == 1) && ($currsetting{$item} == 0)) {
               $changes{$item} = 1;
           } elsif ((!$env{'form.'.$item}) &&
                    (($currsetting{$item} eq '') || ($currsetting{$item} == 1))) {
               $changes{$item} = 1;
         }          }
     }      }
     my $putresult = &Apache::lonnet::put_dom('configuration',\%contacts_hash,      my $putresult = &Apache::lonnet::put_dom('configuration',\%contacts_hash,
                                              $dom);                                               $dom);
     if ($putresult eq 'ok') {      if ($putresult eq 'ok') {
         if (keys(%changes) > 0) {          if (keys(%changes) > 0) {
               &Apache::loncommon::devalidate_domconfig_cache($dom);
               if (ref($lastactref) eq 'HASH') {
                   $lastactref->{'domainconfig'} = 1;
               }
             my ($titles,$short_titles)  = &contact_titles();              my ($titles,$short_titles)  = &contact_titles();
             $resulttext = &mt('Changes made:').'<ul>';              $resulttext = &mt('Changes made:').'<ul>';
             foreach my $item (@contacts) {              foreach my $item (@contacts) {
Line 5039  sub modify_contacts { Line 6841  sub modify_contacts {
                         push(@text,$others{$type});                          push(@text,$others{$type});
                     }                      }
                     $resulttext .= '<span class="LC_cusr_emph">'.                      $resulttext .= '<span class="LC_cusr_emph">'.
                                    join(', ',@text).'</span></li>';                                     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>';
                   }
               }
               my @offon = ('off','on');
               if ($changes{'reporterrors'}) {
                   $resulttext .= '<li>'.
                                  &mt('E-mail error reports to [_1] set to "'.
                                      $offon[$env{'form.reporterrors'}].'".',
                                      &Apache::loncommon::modal_link('http://loncapa.org/core.html',
                                          &mt('LON-CAPA core group - MSU'),600,500)).
                                  '</li>';
               }
               if ($changes{'reportupdates'}) {
                   $resulttext .= '<li>'.
                                   &mt('E-mail record of completed LON-CAPA updates to [_1] set to "'.
                                       $offon[$env{'form.reportupdates'}].'".',
                                       &Apache::loncommon::modal_link('http://loncapa.org/core.html',
                                           &mt('LON-CAPA core group - MSU'),600,500)).
                                   '</li>';
             }              }
             $resulttext .= '</ul>';              $resulttext .= '</ul>';
         } else {          } else {
Line 5069  sub modify_usercreation { Line 6894  sub modify_usercreation {
     foreach my $item(@contexts) {      foreach my $item(@contexts) {
         if ($item eq 'selfcreate') {          if ($item eq 'selfcreate') {
             @{$cancreate{$item}} = &Apache::loncommon::get_env_multiple('form.can_createuser_'.$item);              @{$cancreate{$item}} = &Apache::loncommon::get_env_multiple('form.can_createuser_'.$item);
             my %domdefaults = &Apache::lonnet::get_domain_defaults($dom);              my %domdefaults = &Apache::lonnet::get_domain_defaults($dom,1);
             if (!((($domdefaults{'auth_def'} =~/^krb/) && ($domdefaults{'auth_arg_def'} ne '')) || ($domdefaults{'auth_def'} eq 'localauth'))) {              if (!((($domdefaults{'auth_def'} =~/^krb/) && ($domdefaults{'auth_arg_def'} ne '')) || ($domdefaults{'auth_def'} eq 'localauth'))) {
                 if (ref($cancreate{$item}) eq 'ARRAY') {                   if (ref($cancreate{$item}) eq 'ARRAY') { 
                     if (grep(/^login$/,@{$cancreate{$item}})) {                      if (grep(/^login$/,@{$cancreate{$item}})) {
Line 5092  sub modify_usercreation { Line 6917  sub modify_usercreation {
         }          }
         push(@contexts,'statustocreate');          push(@contexts,'statustocreate');
     }      }
       &process_captcha('cancreate',\%changes,\%cancreate,\%curr_usercreation);
     if (ref($curr_usercreation{'cancreate'}) eq 'HASH') {      if (ref($curr_usercreation{'cancreate'}) eq 'HASH') {
         foreach my $item (@contexts) {          foreach my $item (@contexts) {
             if (($item eq 'selfcreate') || ($item eq 'statustocreate')) {              if (($item eq 'selfcreate') || ($item eq 'statustocreate')) {
Line 5274  sub modify_usercreation { Line 7100  sub modify_usercreation {
                 my %lt = &usercreation_types();                  my %lt = &usercreation_types();
                 foreach my $type (@{$changes{'cancreate'}}) {                  foreach my $type (@{$changes{'cancreate'}}) {
                     my $chgtext;                      my $chgtext;
                     unless ($type eq 'statustocreate') {                      unless (($type eq 'statustocreate') || ($type eq 'captcha') || ($type eq 'recaptchakeys')) {
                         $chgtext = $lt{$type}.', ';                          $chgtext = $lt{$type}.', ';
                     }                      }
                     if ($type eq 'selfcreate') {                      if ($type eq 'selfcreate') {
Line 5333  sub modify_usercreation { Line 7159  sub modify_usercreation {
                                 }                                  }
                             }                              }
                         }                          }
                       } elsif ($type eq 'captcha') {
                           if ($cancreate{$type} eq 'notused') {
                               $chgtext .= &mt('No CAPTCHA validation in use for self-creation screen.');
                           } else {
                               my %captchas = &captcha_phrases();
                               if ($captchas{$cancreate{$type}}) {
                                   $chgtext .= &mt("Validation for self-creation screen set to $captchas{$cancreate{$type}}.");
                               } else {
                                   $chgtext .= &mt('Validation for self-creation screen set to unknown type.');
                               }
                           }
                       } elsif ($type eq 'recaptchakeys') {
                           my ($privkey,$pubkey);
                           if (ref($cancreate{$type}) eq 'HASH') {
                               $pubkey = $cancreate{$type}{'public'};
                               $privkey = $cancreate{$type}{'private'};
                           }
                           $chgtext .= &mt('ReCAPTCHA keys changes').'<ul>';
                           if (!$pubkey) {
                               $chgtext .= '<li>'.&mt('Public key deleted').'</li>';
                           } else {
                               $chgtext .= '<li>'.&mt('Public key set to [_1]',$pubkey).'</li>';
                           }
                           if (!$privkey) {
                               $chgtext .= '<li>'.&mt('Private key deleted').'</li>';
                           } else {
                               $chgtext .= '<li>'.&mt('Private key set to [_1]',$pubkey).'</li>';
                           }
                           $chgtext .= '</ul>';
                     } else {                      } else {
                         if ($cancreate{$type} eq 'none') {                          if ($cancreate{$type} eq 'none') {
                             $chgtext .= &mt('creation of new users is not permitted, except by a Domain Coordinator.');                              $chgtext .= &mt('creation of new users is not permitted, except by a Domain Coordinator.');
Line 5432  sub modify_usercreation { Line 7287  sub modify_usercreation {
     return $resulttext;      return $resulttext;
 }  }
   
   sub process_captcha {
       my ($container,$changes,$newsettings,$current) = @_;
       return unless ((ref($changes) eq 'HASH') && (ref($newsettings) eq 'HASH') || (ref($current) eq 'HASH'));
       $newsettings->{'captcha'} = $env{'form.'.$container.'_captcha'};
       unless ($newsettings->{'captcha'} eq 'recaptcha' || $newsettings->{'captcha'} eq 'notused') {
           $newsettings->{'captcha'} = 'original';
       }
       if ($current->{'captcha'} ne $newsettings->{'captcha'}) {
           if ($container eq 'cancreate') {
               if (ref($changes->{'cancreate'}) eq 'ARRAY') {
                   push(@{$changes->{'cancreate'}},'captcha');
               } elsif (!defined($changes->{'cancreate'})) {
                   $changes->{'cancreate'} = ['captcha'];
               }
           } else {
               $changes->{'captcha'} = 1;
           }
       }
       my ($newpub,$newpriv,$currpub,$currpriv);
       if ($newsettings->{'captcha'} eq 'recaptcha') {
           $newpub = $env{'form.'.$container.'_recaptchapub'};
           $newpriv = $env{'form.'.$container.'_recaptchapriv'};
           $newpub =~ s/\W//g;
           $newpriv =~ s/\W//g;
           $newsettings->{'recaptchakeys'} = {
                                                public  => $newpub,
                                                private => $newpriv,
                                             };
       }
       if (ref($current->{'recaptchakeys'}) eq 'HASH') {
           $currpub = $current->{'recaptchakeys'}{'public'};
           $currpriv = $current->{'recaptchakeys'}{'private'};
           unless ($newsettings->{'captcha'} eq 'recaptcha') {
               $newsettings->{'recaptchakeys'} = {
                                                    public  => '',
                                                    private => '',
                                                 }
           }
       }
       if (($newpub ne $currpub) || ($newpriv ne $currpriv)) {
           if ($container eq 'cancreate') {
               if (ref($changes->{'cancreate'}) eq 'ARRAY') {
                   push(@{$changes->{'cancreate'}},'recaptchakeys');
               } elsif (!defined($changes->{'cancreate'})) {
                   $changes->{'cancreate'} = ['recaptchakeys'];
               }
           } else {
               $changes->{'recaptchakeys'} = 1;
           }
       }
       return;
   }
   
 sub modify_usermodification {  sub modify_usermodification {
     my ($dom,%domconfig) = @_;      my ($dom,%domconfig) = @_;
     my ($resulttext,%curr_usermodification,%changes);      my ($resulttext,%curr_usermodification,%changes);
Line 5553  sub modify_usermodification { Line 7461  sub modify_usermodification {
 }  }
   
 sub modify_defaults {  sub modify_defaults {
     my ($dom,$r) = @_;      my ($dom,$lastactref,%domconfig) = @_;
     my ($resulttext,$mailmsgtxt,%newvalues,%changes,@errors);      my ($resulttext,$mailmsgtxt,%newvalues,%changes,@errors);
     my %domdefaults = &Apache::lonnet::get_domain_defaults($dom);      my %domdefaults = &Apache::lonnet::get_domain_defaults($dom,1);
     my @items = ('auth_def','auth_arg_def','lang_def','timezone_def','datelocale_def');      my @items = ('auth_def','auth_arg_def','lang_def','timezone_def','datelocale_def','portal_def');
     my @authtypes = ('internal','krb4','krb5','localauth');      my @authtypes = ('internal','krb4','krb5','localauth');
     foreach my $item (@items) {      foreach my $item (@items) {
         $newvalues{$item} = $env{'form.'.$item};          $newvalues{$item} = $env{'form.'.$item};
Line 5592  sub modify_defaults { Line 7500  sub modify_defaults {
                     push(@errors,$item);                      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)) {          if (grep(/^\Q$item\E$/,@errors)) {
             $newvalues{$item} = $domdefaults{$item};              $newvalues{$item} = $domdefaults{$item};
Line 5609  sub modify_defaults { Line 7523  sub modify_defaults {
     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 $version = $r->dir_config('lonVersion');              my $version = &Apache::lonnet::get_server_loncaparev($dom);
             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";              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))) {              foreach my $item (sort(keys(%changes))) {
                 my $value = $env{'form.'.$item};                  my $value = $env{'form.'.$item};
Line 5632  sub modify_defaults { Line 7546  sub modify_defaults {
             $mailmsgtext .= "\n";              $mailmsgtext .= "\n";
             my $cachetime = 24*60*60;              my $cachetime = 24*60*60;
             &Apache::lonnet::do_cache_new('domdefaults',$dom,\%domdefaults,$cachetime);              &Apache::lonnet::do_cache_new('domdefaults',$dom,\%domdefaults,$cachetime);
               if (ref($lastactref) eq 'HASH') {
                   $lastactref->{'domdefaults'} = 1;
               }
             if ($changes{'auth_def'} || $changes{'auth_arg_def'} || $changes{'lang_def'} || $changes{'datelocale_def'}) {              if ($changes{'auth_def'} || $changes{'auth_arg_def'} || $changes{'lang_def'} || $changes{'datelocale_def'}) {
                 my $sysmail = $r->dir_config('lonSysEMail');                  my $notify = 1;
                 &Apache::lonmsg::sendemail($sysmail,"LON-CAPA Domain Settings Change - $dom",$mailmsgtext);                  if (ref($domconfig{'contacts'}) eq 'HASH') {
                       if ($domconfig{'contacts'}{'reportupdates'} == 0) {
                           $notify = 0;
                       }
                   }
                   if ($notify) {
                       &Apache::lonmsg::sendemail('installrecord@loncapa.org',
                                                  "LON-CAPA Domain Settings Change - $dom",
                                                  $mailmsgtext);
                   }
             }              }
         } else {          } else {
             $resulttext = &mt('No changes made to default authentication/language/timezone settings');              $resulttext = &mt('No changes made to default authentication/language/timezone settings');
Line 5654  sub modify_defaults { Line 7580  sub modify_defaults {
 }  }
   
 sub modify_scantron {  sub modify_scantron {
     my ($r,$dom,$confname,%domconfig) = @_;      my ($r,$dom,$confname,$lastactref,%domconfig) = @_;
     my ($resulttext,%confhash,%changes,$errors);      my ($resulttext,%confhash,%changes,$errors);
     my $custom = 'custom.tab';      my $custom = 'custom.tab';
     my $default = 'default.tab';      my $default = 'default.tab';
Line 5665  sub modify_scantron { Line 7591  sub modify_scantron {
         my $error;          my $error;
         if ($configuserok eq 'ok') {          if ($configuserok eq 'ok') {
             if ($switchserver) {              if ($switchserver) {
                 $error = &mt("Upload of scantron format file is not permitted to this server: [_1]",$switchserver);                  $error = &mt("Upload of bubblesheet format file is not permitted to this server: [_1]",$switchserver);
             } else {              } else {
                 if ($author_ok eq 'ok') {                  if ($author_ok eq 'ok') {
                     my ($result,$scantronurl) =                      my ($result,$scantronurl) =
Line 5705  sub modify_scantron { Line 7631  sub modify_scantron {
                 if (ref($confhash{'scantron'}) eq 'HASH') {                  if (ref($confhash{'scantron'}) eq 'HASH') {
                     $resulttext = &mt('Changes made:').'<ul>';                      $resulttext = &mt('Changes made:').'<ul>';
                     if ($confhash{'scantron'}{'scantronformat'} eq '') {                      if ($confhash{'scantron'}{'scantronformat'} eq '') {
                         $resulttext .= '<li>'.&mt('[_1] scantron format file removed; [_2] file will be used for courses in this domain.',$custom,$default).'</li>';                          $resulttext .= '<li>'.&mt('[_1] bubblesheet format file removed; [_2] file will be used for courses in this domain.',$custom,$default).'</li>';
                     } else {                      } else {
                         $resulttext .= '<li>'.&mt('Custom scantron format file ([_1]) uploaded for use with courses in this domain.',$custom).'</li>';                          $resulttext .= '<li>'.&mt('Custom bubblesheet format file ([_1]) uploaded for use with courses in this domain.',$custom).'</li>';
                     }                      }
                     $resulttext .= '</ul>';                      $resulttext .= '</ul>';
                 } else {                  } else {
                     $resulttext = &mt('Changes made to scantron format file.');                      $resulttext = &mt('Changes made to bubblesheet format file.');
                 }                  }
                 $resulttext .= '</ul>';                  $resulttext .= '</ul>';
                 &Apache::loncommon::devalidate_domconfig_cache($dom);                  &Apache::loncommon::devalidate_domconfig_cache($dom);
                   if (ref($lastactref) eq 'HASH') {
                       $lastactref->{'domainconfig'} = 1;
                   }
             } else {              } else {
                 $resulttext = &mt('No changes made to scantron format file');                  $resulttext = &mt('No changes made to bubblesheet format file');
             }              }
         } else {          } else {
             $resulttext = '<span class="LC_error">'.              $resulttext = '<span class="LC_error">'.
                 &mt('An error occurred: [_1]',$putresult).'</span>';                  &mt('An error occurred: [_1]',$putresult).'</span>';
         }          }
     } else {      } else {
         $resulttext = &mt('No changes made to scantron format file');           $resulttext = &mt('No changes made to bubblesheet format file'); 
     }      }
     if ($errors) {      if ($errors) {
         $resulttext .= &mt('The following errors occurred: ').'<ul>'.          $resulttext .= &mt('The following errors occurred: ').'<ul>'.
Line 6008  sub modify_serverstatuses { Line 7937  sub modify_serverstatuses {
     my %serverstatushash =  (      my %serverstatushash =  (
                                 serverstatuses => \%newserverstatus,                                  serverstatuses => \%newserverstatus,
                             );                              );
     my %changes;  
     foreach my $type (@pages) {      foreach my $type (@pages) {
         foreach my $setting ('namedusers','machines') {          foreach my $setting ('namedusers','machines') {
             my (@current,@new);              my (@current,@new);
Line 6083  sub modify_serverstatuses { Line 8011  sub modify_serverstatuses {
   
 sub modify_helpsettings {  sub modify_helpsettings {
     my ($r,$dom,$confname,%domconfig) = @_;      my ($r,$dom,$confname,%domconfig) = @_;
   my ($resulttext,$errors,%changes,%helphash);      my ($resulttext,$errors,%changes,%helphash);
        my %defaultchecked = ('submitbugs' => 'on');
   my $customhelpfile  = $env{'form.loginhelpurl.filename'};      my @offon = ('off','on');
     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');      my @toggles = ('submitbugs');
   
     $helphash{'helpsettings'} = {};  
       
     if (ref($domconfig{'helpsettings'}) ne 'HASH') {  
         if ($domconfig{'helpsettings'} eq '') {  
             $domconfig{'helpsettings'} = {};  
         }  
     }  
       
     if (ref($domconfig{'helpsettings'}) eq 'HASH') {      if (ref($domconfig{'helpsettings'}) eq 'HASH') {
      
         foreach my $item (@toggles) {          foreach my $item (@toggles) {
                      if ($defaultchecked{$item} eq 'on') { 
  if ($defaultchecked{$item} eq 'on') {                   if ($domconfig{'helpsettings'}{$item} eq '') {
  if (($domconfig{'helpsettings'}{$item} eq '') &&                      if ($env{'form.'.$item} eq '0') {
  ($env{'form.'.$item} eq '0')) {                          $changes{$item} = 1;
  $changes{$item} = 1;                      }
  } elsif ($domconfig{'helpsettings'}{$item} ne $env{'form.'.$item}) {                  } elsif ($domconfig{'helpsettings'}{$item} ne $env{'form.'.$item}) {
  $changes{$item} = 1;                      $changes{$item} = 1;
  }                  }
  } elsif ($defaultchecked{$item} eq 'off') {              } elsif ($defaultchecked{$item} eq 'off') {
  if (($domconfig{'helpsettings'}{$item} eq '') &&                  if ($domconfig{'helpsettings'}{$item} eq '') {
  ($env{'form.'.$item} eq '1')) {                      if ($env{'form.'.$item} eq '1') {
  $changes{$item} = 1;                          $changes{$item} = 1;
  } elsif ($domconfig{'helpsettings'}{$item} ne $env{'form.'.$item}) {                      }
  $changes{$item} = 1;                  } elsif ($domconfig{'helpsettings'}{$item} ne $env{'form.'.$item}) {
  }                      $changes{$item} = 1;
  }                  }
  $helphash{'helpsettings'}{$item} = $env{'form.'.$item};              }
  }              if (($env{'form.'.$item} eq '0') || ($env{'form.'.$item} eq '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;      my $putresult;
       
     if (keys(%changes) > 0) {      if (keys(%changes) > 0) {
     $putresult = &Apache::lonnet::put_dom('configuration',\%helphash,$dom);          $putresult = &Apache::lonnet::put_dom('configuration',\%helphash,$dom);
     } else {          if ($putresult eq 'ok') {
     $putresult = 'ok';              $resulttext = &mt('Changes made:').'<ul>';
     }              foreach my $item (sort(keys(%changes))) {
                                                                if ($item eq 'submitbugs') {
     if ($putresult eq 'ok') {                      $resulttext .= '<li>'.&mt('Display link to: [_1] set to "'.$offon[$env{'form.'.$item}].'".',
         if (keys(%changes) > 0) {                                                &Apache::loncommon::modal_link('http://bugs.loncapa.org',
  $resulttext = &mt('Changes made:').'<ul>';                                                &mt('LON-CAPA bug tracker'),600,500)).'</li>';
  foreach my $item (sort(keys(%changes))) {                  }
  if ($item eq 'submitbugs') {              }
  $resulttext .= '<li>'.&mt("$title{$item} set to $offon[$env{'form.'.$item}]").'</li>';              $resulttext .= '</ul>';
  }          } else {
  if ($item eq 'loginhelpurl') {              $resulttext = &mt('No changes made to help settings');
  if ($helphash{'helpsettings'}{'loginhelpurl'} eq '') {              $errors .= '<li><span class="LC_error">'.
                         $resulttext .= '<li>'.&mt('[_1] help file removed; [_2] file will be used for the unathorized help page in this domain.',$customhelpfile,$defaulthelpfile).'</li>';                         &mt('An error occurred storing the settings: [_1]',
                     } else {                             $putresult).'</span></li>';
                         $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) {      if ($errors) {
         $resulttext .= &mt('The following errors occurred: ').'<ul>'.          $resulttext .= '<br />'.&mt('The following errors occurred: ').'<ul>'.
                        $errors.'</ul>';                         $errors.'</ul>';
     }      }
     return $resulttext;      return $resulttext;
 }  }
   
 sub modify_coursedefaults {  sub modify_coursedefaults {
     my ($dom,%domconfig) = @_;      my ($dom,$lastactref,%domconfig) = @_;
     my ($resulttext,$errors,%changes,%defaultshash);      my ($resulttext,$errors,%changes,%defaultshash);
     my %defaultchecked = ('canuse_pdfforms' => 'off');      my %defaultchecked = ('canuse_pdfforms' => 'off');
     my @offon = ('off','on');  
     my @toggles = ('canuse_pdfforms');      my @toggles = ('canuse_pdfforms');
       my @numbers = ('anonsurvey_threshold','uploadquota_official','uploadquota_unofficial',
                      'uploadquota_community');
       my @types = ('official','unofficial','community');
       my %staticdefaults = (
                              anonsurvey_threshold => 10,
                              uploadquota          => 500,
                            );
   
     $defaultshash{'coursedefaults'} = {};      $defaultshash{'coursedefaults'} = {};
   
Line 6225  sub modify_coursedefaults { Line 8093  sub modify_coursedefaults {
                 if (($domconfig{'coursedefaults'}{$item} eq '') &&                  if (($domconfig{'coursedefaults'}{$item} eq '') &&
                     ($env{'form.'.$item} eq '0')) {                      ($env{'form.'.$item} eq '0')) {
                     $changes{$item} = 1;                      $changes{$item} = 1;
                 } elsif ($domconfig{'coursdefaults'}{$item} ne $env{'form.'.$item}) {                  } elsif ($domconfig{'coursedefaults'}{$item} ne $env{'form.'.$item}) {
                     $changes{$item} = 1;                      $changes{$item} = 1;
                 }                  }
             } elsif ($defaultchecked{$item} eq 'off') {              } elsif ($defaultchecked{$item} eq 'off') {
Line 6238  sub modify_coursedefaults { Line 8106  sub modify_coursedefaults {
             }              }
             $defaultshash{'coursedefaults'}{$item} = $env{'form.'.$item};              $defaultshash{'coursedefaults'}{$item} = $env{'form.'.$item};
         }          }
           foreach my $item (@numbers) {
               my ($currdef,$newdef);
               $newdef = $env{'form.'.$item};
               if ($item eq 'anonsurvey_threshold') {
                   $currdef = $domconfig{'coursedefaults'}{$item};
                   $newdef =~ s/\D//g;
                   if ($newdef eq '' || $newdef < 1) {
                       $newdef = 1;
                   }
                   $defaultshash{'coursedefaults'}{$item} = $newdef;
               } else {
                   my ($type) = ($item =~ /^\Quploadquota_\E(\w+)$/);
                   if (ref($domconfig{'coursedefaults'}{'uploadquota'}) eq 'HASH') {
                       $currdef = $domconfig{'coursedefaults'}{'uploadquota'}{$type};
                   }
                   $newdef =~ s/[^\w.\-]//g;
                   $defaultshash{'coursedefaults'}{'uploadquota'}{$type} = $newdef;
               }
               if ($currdef ne $newdef) {
                   my $staticdef;
                   if ($item eq 'anonsurvey_threshold') {
                       unless (($currdef eq '') && ($newdef == $staticdefaults{$item})) {
                           $changes{$item} = 1;
                       }
                   } else {
                       unless (($currdef eq '') && ($newdef == $staticdefaults{'uploadquota'})) {
                           $changes{'uploadquota'} = 1;
                       }
                   }
               }
           }
           my $officialcreds = $env{'form.official_credits'};
           $officialcreds =~ s/^[^\d\.]//g;
           my $unofficialcreds = $env{'form.unofficial_credits'};
           $unofficialcreds =~ s/^[^\d\.]//g;
           if (ref($domconfig{'coursedefaults'}{'coursecredits'} ne 'HASH') &&
                   ($env{'form.coursecredits'} eq '1')) {
                   $changes{'coursecredits'} = 1;
           } else {
               if (($domconfig{'coursedefaults'}{'coursecredits'}{'official'} ne $officialcreds)  ||
                   ($domconfig{'coursedefaults'}{'coursecredits'}{'unofficial'} ne $unofficialcreds)) {
                   $changes{'coursecredits'} = 1;
               }
           }
           $defaultshash{'coursedefaults'}{'coursecredits'} = {
               official   => $officialcreds,
               unofficial => $unofficialcreds,
           }
     }      }
     my $putresult = &Apache::lonnet::put_dom('configuration',\%defaultshash,      my $putresult = &Apache::lonnet::put_dom('configuration',\%defaultshash,
                                              $dom);                                               $dom);
     if ($putresult eq 'ok') {      if ($putresult eq 'ok') {
         if (keys(%changes) > 0) {          if (keys(%changes) > 0) {
             if ($changes{'canuse_pdfforms'}) {              my %domdefaults = &Apache::lonnet::get_domain_defaults($dom,1);
                 my %domdefaults = &Apache::lonnet::get_domain_defaults($dom);              if (($changes{'canuse_pdfforms'}) || ($changes{'coursecredits'}) || ($changes{'uploadquota'})) {
                 $domdefaults{'canuse_pdfforms'}=$defaultshash{'coursedefaults'}{'canuse_pdfforms'};                  if ($changes{'canuse_pdfforms'}) {
                       $domdefaults{'canuse_pdfforms'}=$defaultshash{'coursedefaults'}{'canuse_pdfforms'};
                   }
                   if ($changes{'coursecredits'}) {
                       if (ref($defaultshash{'coursedefaults'}{'coursecredits'}) eq 'HASH') {
                           $domdefaults{'officialcredits'} =
                               $defaultshash{'coursedefaults'}{'coursecredits'}{'official'};
                           $domdefaults{'unofficialcredits'} =
                               $defaultshash{'coursedefaults'}{'coursecredits'}{'unofficial'};
                       }
                   }
                   if ($changes{'uploadquota'}) {
                       if (ref($defaultshash{'coursedefaults'}{'uploadquota'}) eq 'HASH') {
                           foreach my $type (@types) {
                               $domdefaults{$type.'quota'}=$defaultshash{'coursedefaults'}{'uploadquota'}{$type};
                           }
                       }
                   }
                 my $cachetime = 24*60*60;                  my $cachetime = 24*60*60;
                 &Apache::lonnet::do_cache_new('domdefaults',$dom,\%domdefaults,$cachetime);                  &Apache::lonnet::do_cache_new('domdefaults',$dom,\%domdefaults,$cachetime);
                   if (ref($lastactref) eq 'HASH') {
                       $lastactref->{'domdefaults'} = 1;
                   }
             }              }
             $resulttext = &mt('Changes made:').'<ul>';              $resulttext = &mt('Changes made:').'<ul>';
             foreach my $item (sort(keys(%changes))) {              foreach my $item (sort(keys(%changes))) {
Line 6257  sub modify_coursedefaults { Line 8193  sub modify_coursedefaults {
                     } else {                      } else {
                         $resulttext .= '<li>'.&mt('Course/Community users can create/upload PDF forms set to "off"').'</li>';                          $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>';
                   } elsif ($item eq 'uploadquota') {
                       if (ref($defaultshash{'coursedefaults'}{'uploadquota'}) eq 'HASH') {
                           $resulttext .= '<li>'.&mt('Default quota for content uploaded to a course/community via Course Editor set as follows:').'<ul>'.
                                          '<li>'.&mt('Official courses: [_1] MB','<b>'.$defaultshash{'coursedefaults'}{'uploadquota'}{'official'}.'</b>').'</li>'.
                                          '<li>'.&mt('Unofficial courses: [_1] MB','<b>'.$defaultshash{'coursedefaults'}{'uploadquota'}{'unofficial'}.'</b>').'</li>'.
                                          '<li>'.&mt('Communities: [_1] MB','<b>'.$defaultshash{'coursedefaults'}{'uploadquota'}{'community'}.'</b>').'</li>'.
                                          '</ul>'.
                                          '</li>';
                       } else {
                           $resulttext .= '<li>'.&mt('Default quota for content uploaded via Course Editor remains default: [_1] MB',$staticdefaults{'uploadquota'}).'</li>';
                       }
                   } elsif ($item eq 'coursecredits') {
                       if (ref($defaultshash{'coursedefaults'}{'coursecredits'}) eq 'HASH') {
                           if (($domdefaults{'officialcredits'} eq '') &&
                               ($domdefaults{'unofficialcredits'} eq '')) {
                               $resulttext .= '<li>'.&mt('Student credits not in use for courses in this domain').'</li>';
                           } else {
                               $resulttext .= '<li>'.&mt('Student credits can be set per course by a Domain Coordinator, with the following defaults applying:').'<ul>'.
                                              '<li>'.&mt('Official courses: [_1]',$defaultshash{'coursedefaults'}{'coursecredits'}{'official'}).'</li>'.
                                              '<li>'.&mt('Unofficial courses: [_1]',$defaultshash{'coursedefaults'}{'coursecredits'}{'unofficial'}).'</li>'.
                                              '</ul>'.
                                              '</li>';
                           }
                       } else {
                           $resulttext .= '<li>'.&mt('Student credits not in use for courses in this domain').'</li>';
                       }
                 }                  }
             }              }
             $resulttext .= '</ul>';              $resulttext .= '</ul>';
Line 6270  sub modify_coursedefaults { Line 8234  sub modify_coursedefaults {
     return $resulttext;      return $resulttext;
 }  }
   
   sub modify_usersessions {
       my ($dom,$lastactref,%domconfig) = @_;
       my @hostingtypes = ('version','excludedomain','includedomain');
       my @offloadtypes = ('primary','default');
       my %types = (
                     remote => \@hostingtypes,
                     hosted => \@hostingtypes,
                     spares => \@offloadtypes,
                   );
       my @prefixes = ('remote','hosted','spares');
       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,1);
       my $resulttext;
       my %iphost = &Apache::lonnet::get_iphost();
       foreach my $prefix (@prefixes) {
           next if ($prefix eq 'spares');
           foreach my $type (@{$types{$prefix}}) {
               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;
                       }
                   }
               }
           }
       }
   
       my @alldoms = &Apache::lonnet::all_domains();
       my %servers = &Apache::lonnet::internet_dom_servers($dom);
       my %spareid = &current_offloads_to($dom,$domconfig{'usersessions'},\%servers);
       my $savespares;
   
       foreach my $lonhost (sort(keys(%servers))) {
           my $serverhomeID =
               &Apache::lonnet::get_server_homeID($servers{$lonhost});
           my $serverhostname = &Apache::lonnet::hostname($lonhost);
           $defaultshash{'usersessions'}{'spares'}{$lonhost} = {};
           my %spareschg;
           foreach my $type (@{$types{'spares'}}) {
               my @okspares;
               my @checked = &Apache::loncommon::get_env_multiple('form.spare_'.$type.'_'.$lonhost);
               foreach my $server (@checked) {
                   if (&Apache::lonnet::hostname($server) ne '') {
                       unless (&Apache::lonnet::hostname($server) eq $serverhostname) {
                           unless (grep(/^\Q$server\E$/,@okspares)) {
                               push(@okspares,$server);
                           }
                       }
                   }
               }
               my $new = $env{'form.newspare_'.$type.'_'.$lonhost};
               my $newspare;
               if (($new ne '') && (&Apache::lonnet::hostname($new))) {
                   unless (&Apache::lonnet::hostname($new) eq $serverhostname) {
                       $newspare = $new;
                   }
               }
               my @spares;
               if (($newspare ne '') && (!grep(/^\Q$newspare\E$/,@okspares))) {
                   @spares = sort(@okspares,$newspare);
               } else {
                   @spares = sort(@okspares);
               }
               $defaultshash{'usersessions'}{'spares'}{$lonhost}{$type} = \@spares;
               if (ref($spareid{$lonhost}) eq 'HASH') {
                   if (ref($spareid{$lonhost}{$type}) eq 'ARRAY') {
                       my @diffs = &Apache::loncommon::compare_arrays($spareid{$lonhost}{$type},\@spares);
                       if (@diffs > 0) {
                           $spareschg{$type} = 1;
                       }
                   }
               }
           }
           if (keys(%spareschg) > 0) {
               $changes{'spares'}{$lonhost} = \%spareschg;
           }
       }
   
       if (ref($domconfig{'usersessions'}) eq 'HASH') {
           if (ref($domconfig{'usersessions'}{'spares'}) eq 'HASH') {
               if (ref($changes{'spares'}) eq 'HASH') {
                   if (keys(%{$changes{'spares'}}) > 0) {
                       $savespares = 1;
                   }
               }
           } else {
               $savespares = 1;
           }
       }
   
       my $nochgmsg = &mt('No changes made to settings for user session hosting/offloading.');
       if ((keys(%changes) > 0) || ($savespares)) {
           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);
               if (ref($lastactref) eq 'HASH') {
                   $lastactref->{'domdefaults'} = 1;
               }
               if (keys(%changes) > 0) {
                   my %lt = &usersession_titles();
                   $resulttext = &mt('Changes made:').'<ul>';
                   foreach my $prefix (@prefixes) {
                       if (ref($changes{$prefix}) eq 'HASH') {
                           $resulttext .= '<li>'.$lt{$prefix}.'<ul>';
                           if ($prefix eq 'spares') {
                               if (ref($changes{$prefix}) eq 'HASH') {
                                   foreach my $lonhost (sort(keys(%{$changes{$prefix}}))) {
                                       $resulttext .= '<li><b>'.$lonhost.'</b> ';
                                       my $lonhostdom = &Apache::lonnet::host_domain($lonhost);
                                       my $cachekey = &escape('spares').':'.&escape($lonhostdom);
                                       &Apache::lonnet::remote_devalidate_cache($lonhost,[$cachekey]);
                                       if (ref($changes{$prefix}{$lonhost}) eq 'HASH') {
                                           foreach my $type (@{$types{$prefix}}) {
                                               if ($changes{$prefix}{$lonhost}{$type}) {
                                                   my $offloadto = &mt('None');
                                                   if (ref($defaultshash{'usersessions'}{'spares'}{$lonhost}{$type}) eq 'ARRAY') {
                                                       if (@{$defaultshash{'usersessions'}{'spares'}{$lonhost}{$type}} > 0) {   
                                                           $offloadto = join(', ',@{$defaultshash{'usersessions'}{'spares'}{$lonhost}{$type}});
                                                       }
                                                   }
                                                   $resulttext .= &mt('[_1] set to: [_2].','<i>'.$lt{$type}.'</i>',$offloadto).('&nbsp;'x3);
                                               }
                                           }
                                       }
                                       $resulttext .= '</li>';
                                   }
                               }
                           } else {
                               foreach my $type (@{$types{$prefix}}) {
                                   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 = $nochgmsg;
               }
           } else {
               $resulttext = '<span class="LC_error">'.
                             &mt('An error occurred: [_1]',$putresult).'</span>';
           }
       } else {
           $resulttext = $nochgmsg;
       }
       return $resulttext;
   }
   
   sub modify_loadbalancing {
       my ($dom,%domconfig) = @_;
       my $primary_id = &Apache::lonnet::domain($dom,'primary');
       my $intdom = &Apache::lonnet::internet_dom($primary_id);
       my ($othertitle,$usertypes,$types) =
           &Apache::loncommon::sorted_inst_types($dom);
       my %servers = &Apache::lonnet::internet_dom_servers($dom);
       my @sparestypes = ('primary','default');
       my %typetitles = &sparestype_titles();
       my $resulttext;
       my (%currbalancer,%currtargets,%currrules,%existing);
       if (ref($domconfig{'loadbalancing'}) eq 'HASH') {
           %existing = %{$domconfig{'loadbalancing'}};
       }
       &get_loadbalancers_config(\%servers,\%existing,\%currbalancer,
                                 \%currtargets,\%currrules);
       my ($saveloadbalancing,%defaultshash,%changes);
       my ($alltypes,$othertypes,$titles) =
           &loadbalancing_titles($dom,$intdom,$usertypes,$types);
       my %ruletitles = &offloadtype_text();
       my @deletions = &Apache::loncommon::get_env_multiple('form.loadbalancing_delete');
       for (my $i=0; $i<$env{'form.loadbalancing_total'}; $i++) {
           my $balancer = $env{'form.loadbalancing_lonhost_'.$i};
           if ($balancer eq '') {
               next;
           }
           if (!exists($servers{$balancer})) {
               if (exists($currbalancer{$balancer})) {
                   push(@{$changes{'delete'}},$balancer);
               }
               next;
           }
           if ((@deletions > 0) && (grep(/^\Q$i\E$/,@deletions))) {
               push(@{$changes{'delete'}},$balancer);
               next;
           }
           if (!exists($currbalancer{$balancer})) {
               push(@{$changes{'add'}},$balancer);
           }
           $defaultshash{'loadbalancing'}{$balancer}{'targets'}{'primary'} = [];
           $defaultshash{'loadbalancing'}{$balancer}{'targets'}{'default'} = [];
           $defaultshash{'loadbalancing'}{$balancer}{'rules'} = {};
           unless (ref($domconfig{'loadbalancing'}) eq 'HASH') {
               $saveloadbalancing = 1;
           }
           foreach my $sparetype (@sparestypes) {
               my @targets = &Apache::loncommon::get_env_multiple('form.loadbalancing_target_'.$i.'_'.$sparetype);
               my @offloadto;
               foreach my $target (@targets) {
                   if (($servers{$target}) && ($target ne $balancer)) {
                       if ($sparetype eq 'default') {
                           if (ref($defaultshash{'loadbalancing'}{$balancer}{'targets'}{'primary'}) eq 'ARRAY') {
                               next if (grep(/^\Q$target\E$/,@{$defaultshash{'loadbalancing'}{$balancer}{'targets'}{'primary'}}));
                           }
                       }
                       unless(grep(/^\Q$target\E$/,@offloadto)) {
                           push(@offloadto,$target);
                       }
                   }
                   $defaultshash{'loadbalancing'}{$balancer}{'targets'}{$sparetype} = \@offloadto;
               }
           }
           if (ref($currtargets{$balancer}) eq 'HASH') {
               foreach my $sparetype (@sparestypes) {
                   if (ref($currtargets{$balancer}{$sparetype}) eq 'ARRAY') {
                       my @targetdiffs = &Apache::loncommon::compare_arrays($currtargets{$balancer}{$sparetype},$defaultshash{'loadbalancing'}{$balancer}{'targets'}{$sparetype});
                       if (@targetdiffs > 0) {
                           $changes{'curr'}{$balancer}{'targets'} = 1;
                       }
                   } elsif (ref($defaultshash{'loadbalancing'}{$balancer}{'targets'}{$sparetype}) eq 'ARRAY') {
                       if (@{$defaultshash{'loadbalancing'}{$balancer}{'targets'}{$sparetype}} > 0) {
                           $changes{'curr'}{$balancer}{'targets'} = 1;
                       }
                   }
               }
           } else {
               if (ref($defaultshash{'loadbalancing'}{$balancer}) eq 'HASH') {
                   foreach my $sparetype (@sparestypes) {
                       if (ref($defaultshash{'loadbalancing'}{$balancer}{'targets'}{$sparetype}) eq 'ARRAY') {
                           if (@{$defaultshash{'loadbalancing'}{$balancer}{'targets'}{$sparetype}} > 0) {
                               $changes{'curr'}{$balancer}{'targets'} = 1;
                           }
                       }
                   }
               }
           }
           my $ishomedom;
           if (&Apache::lonnet::host_domain($balancer) eq $dom) {
               $ishomedom = 1;
           }
           if (ref($alltypes) eq 'ARRAY') {
               foreach my $type (@{$alltypes}) {
                   my $rule;
                   unless ((($type eq '_LC_external') || ($type eq '_LC_internetdom')) &&
                            (!$ishomedom)) {
                       $rule = $env{'form.loadbalancing_rules_'.$i.'_'.$type};
                   }
                   if ($rule eq 'specific') {
                       $rule = $env{'form.loadbalancing_singleserver_'.$i.'_'.$type};
                   }
                   $defaultshash{'loadbalancing'}{$balancer}{'rules'}{$type} = $rule;
                   if (ref($currrules{$balancer}) eq 'HASH') {
                       if ($rule ne $currrules{$balancer}{$type}) {
                           $changes{'curr'}{$balancer}{'rules'}{$type} = 1;
                       }
                   } elsif ($rule ne '') {
                       $changes{'curr'}{$balancer}{'rules'}{$type} = 1;
                   }
               }
           }
       }
       my $nochgmsg = &mt('No changes made to Load Balancer settings.');
       if ((keys(%changes) > 0) || ($saveloadbalancing)) {
           unless (ref($defaultshash{'loadbalancing'}) eq 'HASH') {
               $defaultshash{'loadbalancing'} = {};
           }
           my $putresult = &Apache::lonnet::put_dom('configuration',
                                                    \%defaultshash,$dom);
           if ($putresult eq 'ok') {
               if (keys(%changes) > 0) {
                   if (ref($changes{'delete'}) eq 'ARRAY') {
                       foreach my $balancer (sort(@{$changes{'delete'}})) {
                           $resulttext .= '<li>'.&mt('Load Balancing discontinued for: [_1]',$balancer).'</li>';
                           my $cachekey = &escape('loadbalancing').':'.&escape($dom);
                           &Apache::lonnet::remote_devalidate_cache($balancer,[$cachekey]);
                       }
                   }
                   if (ref($changes{'add'}) eq 'ARRAY') {
                       foreach my $balancer (sort(@{$changes{'add'}})) {
                           $resulttext .= '<li>'.&mt('Load Balancing enabled for: [_1]',$balancer);
                       }
                   }
                   if (ref($changes{'curr'}) eq 'HASH') {
                       foreach my $balancer (sort(keys(%{$changes{'curr'}}))) {
                           if (ref($changes{'curr'}{$balancer}) eq 'HASH') {
                               if ($changes{'curr'}{$balancer}{'targets'}) {
                                   my %offloadstr;
                                   foreach my $sparetype (@sparestypes) {
                                       if (ref($defaultshash{'loadbalancing'}{$balancer}{'targets'}{$sparetype}) eq 'ARRAY') {
                                           if (@{$defaultshash{'loadbalancing'}{$balancer}{'targets'}{$sparetype}} > 0) {
                                               $offloadstr{$sparetype} = join(', ',@{$defaultshash{'loadbalancing'}{$balancer}{'targets'}{$sparetype}});
                                           }
                                       }
                                   }
                                   if (keys(%offloadstr) == 0) {
                                       $resulttext .= '<li>'.&mt("Servers to which Load Balance server offloads set to 'None', by default").'</li>';
                                   } else {
                                       my $showoffload;
                                       foreach my $sparetype (@sparestypes) {
                                           $showoffload .= '<i>'.$typetitles{$sparetype}.'</i>:&nbsp;';
                                           if (defined($offloadstr{$sparetype})) {
                                               $showoffload .= $offloadstr{$sparetype};
                                           } else {
                                               $showoffload .= &mt('None');
                                           }
                                           $showoffload .= ('&nbsp;'x3);
                                       }
                                       $resulttext .= '<li>'.&mt('By default, Load Balancer: [_1] set to offload to - [_2]',$balancer,$showoffload).'</li>';
                                   }
                               }
                           }
                           if (ref($changes{'curr'}{$balancer}{'rules'}) eq 'HASH') {
                               if ((ref($alltypes) eq 'ARRAY') && (ref($titles) eq 'HASH')) {
                                   foreach my $type (@{$alltypes}) {
                                       if ($changes{'curr'}{$balancer}{'rules'}{$type}) {
                                           my $rule = $defaultshash{'loadbalancing'}{$balancer}{'rules'}{$type};
                                           my $balancetext;
                                           if ($rule eq '') {
                                               $balancetext =  $ruletitles{'default'};
                                           } elsif (($rule eq 'homeserver') || ($rule eq 'externalbalancer') ||
                                                    ($rule eq 'balancer') || ($rule eq 'offloadedto')) {
                                               $balancetext =  $ruletitles{$rule};
                                           } else {
                                               $balancetext = &mt('offload to [_1]',$defaultshash{'loadbalancing'}{$balancer}{'rules'}{$type});
                                           }
                                           $resulttext .= '<li>'.&mt('Load Balancer: [_1] -- balancing for [_2] set to - "[_3]"',$balancer,$titles->{$type},$balancetext).'</li>';
                                       }
                                   }
                               }
                           }
                           my $cachekey = &escape('loadbalancing').':'.&escape($dom);
                           &Apache::lonnet::remote_devalidate_cache($balancer,[$cachekey]);
                       }
                   }
                   if ($resulttext ne '') {
                       $resulttext = &mt('Changes made:').'<ul>'.$resulttext.'</ul>';
                   } else {
                       $resulttext = $nochgmsg;
                   }
               } else {
                   $resulttext = $nochgmsg;
               }
           } else {
               $resulttext = '<span class="LC_error">'.
                             &mt('An error occurred: [_1]',$putresult).'</span>';
           }
       } else {
           $resulttext = $nochgmsg;
       }
       return $resulttext;
   }
   
 sub recurse_check {  sub recurse_check {
     my ($chkcats,$categories,$depth,$name) = @_;      my ($chkcats,$categories,$depth,$name) = @_;
     if (ref($chkcats->[$depth]{$name}) eq 'ARRAY') {      if (ref($chkcats->[$depth]{$name}) eq 'ARRAY') {
Line 6304  sub recurse_cat_deletes { Line 8743  sub recurse_cat_deletes {
                 delete($coursecategories->{$subitem});                  delete($coursecategories->{$subitem});
                 $deletions->{$subitem} = 1;                  $deletions->{$subitem} = 1;
                 &recurse_cat_deletes($subitem,$coursecategories,$deletions);                  &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;      return;
 }  }
   
 sub get_active_dcs {  sub get_active_dcs {
     my ($dom) = @_;      my ($dom) = @_;
     my %dompersonnel = &Apache::lonnet::get_domain_roles($dom,['dc']);      my $now = time;
       my %dompersonnel = &Apache::lonnet::get_domain_roles($dom,['dc'],$now,$now);
     my %domcoords;      my %domcoords;
     my $numdcs = 0;      my $numdcs = 0;
     my $now = time;  
     foreach my $server (keys(%dompersonnel)) {      foreach my $server (keys(%dompersonnel)) {
         foreach my $user (sort(keys(%{$dompersonnel{$server}}))) {          foreach my $user (sort(keys(%{$dompersonnel{$server}}))) {
             my ($trole,$uname,$udom,$runame,$rudom,$rsec) = split(/:/,$user);              my ($trole,$uname,$udom,$runame,$rudom,$rsec) = split(/:/,$user);
             my ($end,$start) = split(':',$dompersonnel{$server}{$user});              $domcoords{$uname.':'.$udom} = $dompersonnel{$server}{$user};
             if (($end eq '') || ($end == 0) || ($end > $now)) {  
                 if ($start <= $now) {  
                     $domcoords{$uname.':'.$udom} = $dompersonnel{$server}{$user};  
                 }  
             }  
         }          }
     }      }
     return %domcoords;      return %domcoords;
 }  }
   
 sub active_dc_picker {  sub active_dc_picker {
     my ($dom,$curr_dc) = @_;      my ($dom,$numinrow,$inputtype,$name,%currhash) = @_;
     my %domcoords = &get_active_dcs($dom);       my %domcoords = &get_active_dcs($dom); 
     my @dcs = sort(keys(%domcoords));      my @domcoord = keys(%domcoords);
     my $numdcs = scalar(@dcs);       if (keys(%currhash)) {
     my $datatable;          foreach my $dc (keys(%currhash)) {
     my $numinrow = 2;              unless (exists($domcoords{$dc})) {
                   push(@domcoord,$dc);
               }
           }
       }
       @domcoord = sort(@domcoord);
       my $numdcs = scalar(@domcoord);
       my $rows = 0;
       my $table;
     if ($numdcs > 1) {      if ($numdcs > 1) {
         $datatable = '<table>';          $table = '<table>';
         for (my $i=0; $i<@dcs; $i++) {          for (my $i=0; $i<@domcoord; $i++) {
             my $rem = $i%($numinrow);              my $rem = $i%($numinrow);
             if ($rem == 0) {              if ($rem == 0) {
                 if ($i > 0) {                  if ($i > 0) {
                     $datatable .= '</tr>';                      $table .= '</tr>';
                 }                  }
                 $datatable .= '<tr>';                  $table .= '<tr>';
                   $rows ++;
             }              }
             my $check = ' ';              my $check = '';
             if ($curr_dc eq '') {              if ($inputtype eq 'radio') {
                 if (!$i) {                   if (keys(%currhash) == 0) {
                     $check = ' checked="checked" ';                      if (!$i) {
                           $check = ' checked="checked"';
                       }
                   } elsif (exists($currhash{$domcoord[$i]})) {
                       $check = ' checked="checked"';
                   }
               } else {
                   if (exists($currhash{$domcoord[$i]})) {
                       $check = ' checked="checked"';
                 }                  }
             } elsif ($dcs[$i] eq $curr_dc) {  
                 $check = ' checked="checked" ';  
             }              }
             if ($i == @dcs - 1) {              if ($i == @domcoord - 1) {
                 my $colsleft = $numinrow - $rem;                  my $colsleft = $numinrow - $rem;
                 if ($colsleft > 1) {                  if ($colsleft > 1) {
                     $datatable .= '<td colspan="'.$colsleft.'">';                      $table .= '<td class="LC_left_item" colspan="'.$colsleft.'">';
                 } else {                  } else {
                     $datatable .= '<td>';                      $table .= '<td class="LC_left_item">';
                 }                  }
             } else {              } else {
                 $datatable .= '<td>';                  $table .= '<td class="LC_left_item">';
               }
               my ($dcname,$dcdom) = split(':',$domcoord[$i]);
               my $user = &Apache::loncommon::plainname($dcname,$dcdom);
               $table .= '<span class="LC_nobreak"><label>'.
                         '<input type="'.$inputtype.'" name="'.$name.'"'.
                         ' value="'.$domcoord[$i].'"'.$check.' />'.$user;
               if ($user ne $dcname.':'.$dcdom) {
                   $table .=  ' ('.$dcname.':'.$dcdom.')'.
                              '</label></span></td>';
               }
           }
           $table .= '</tr></table>';
       } elsif ($numdcs == 1) {
           if ($inputtype eq 'radio') {
               $table .= '<input type="hidden" name="'.$name.'" value="'.$domcoord[0].'" />';
           } else {
               my $check;
               if (exists($currhash{$domcoord[0]})) {
                   $check = ' checked="checked"';
               }
               $table .= '<input type="checkbox" name="'.$name.'" '.
                         'value="'.$domcoord[0].'"'.$check.' />';
               $rows ++;
           }
       }
       return ($numdcs,$table,$rows);
   }
   
   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',
                  spares => 'Servers offloaded to, when busy',
                  version => 'LON-CAPA version requirement',
                  excludedomain => 'Allow all, but exclude specific domains',
                  includedomain => 'Deny all, but include specific domains',
                  primary => 'Primary (checked first)',
                  default => 'Default',
              );
   }
   
   sub id_for_thisdom {
       my (%servers) = @_;
       my %altids;
       foreach my $server (keys(%servers)) {
           my $serverhome = &Apache::lonnet::get_server_homeID($servers{$server});
           if ($serverhome ne $server) {
               $altids{$serverhome} = $server;
           }
       }
       return %altids;
   }
   
   sub count_servers {
       my ($currbalancer,%servers) = @_;
       my (@spares,$numspares);
       foreach my $lonhost (sort(keys(%servers))) {
           next if ($currbalancer eq $lonhost);
           push(@spares,$lonhost);
       }
       if ($currbalancer) {
           $numspares = scalar(@spares);
       } else {
           $numspares = scalar(@spares) - 1;
       }
       return ($numspares,@spares);
   }
   
   sub lonbalance_targets_js {
       my ($dom,$types,$servers,$settings) = @_;
       my $select = &mt('Select');
       my ($alltargets,$allishome,$allinsttypes,@alltypes);
       if (ref($servers) eq 'HASH') {
           $alltargets = join("','",sort(keys(%{$servers})));
           my @homedoms;
           foreach my $server (sort(keys(%{$servers}))) {
               if (&Apache::lonnet::host_domain($server) eq $dom) {
                   push(@homedoms,'1');
               } else {
                   push(@homedoms,'0');
               }
           }
           $allishome = join("','",@homedoms);
       }
       if (ref($types) eq 'ARRAY') {
           if (@{$types} > 0) {
               @alltypes = @{$types};
           }
       }
       push(@alltypes,'default','_LC_adv','_LC_author','_LC_internetdom','_LC_external');
       $allinsttypes = join("','",@alltypes);
       my (%currbalancer,%currtargets,%currrules,%existing);
       if (ref($settings) eq 'HASH') {
           %existing = %{$settings};
       }
       &get_loadbalancers_config($servers,\%existing,\%currbalancer,
                                 \%currtargets,\%currrules);
       my $balancers = join("','",sort(keys(%currbalancer)));
       return <<"END";
   
   <script type="text/javascript">
   // <![CDATA[
   
   currBalancers = new Array('$balancers');
   
   function toggleTargets(balnum) {
       var lonhostitem = document.getElementById('loadbalancing_lonhost_'+balnum);
       var prevhostitem = document.getElementById('loadbalancing_prevlonhost_'+balnum);
       var balancer = lonhostitem.options[lonhostitem.selectedIndex].value;
       var prevbalancer = prevhostitem.value;
       var baltotal = document.getElementById('loadbalancing_total').value;
       prevhostitem.value = balancer;
       if (prevbalancer != '') {
           var prevIdx = currBalancers.indexOf(prevbalancer);
           if (prevIdx != -1) {
               currBalancers.splice(prevIdx,1);
           }
       }
       if (balancer == '') {
           hideSpares(balnum);
       } else {
           var currIdx = currBalancers.indexOf(balancer);
           if (currIdx == -1) {
               currBalancers.push(balancer);
           }
           var homedoms = new Array('$allishome');
           var ishomedom = homedoms[lonhostitem.selectedIndex];
           showSpares(balancer,ishomedom,balnum);
       }
       balancerChange(balnum,baltotal,'change',prevbalancer,balancer);
       return;
   }
   
   function showSpares(balancer,ishomedom,balnum) {
       var alltargets = new Array('$alltargets');
       var insttypes = new Array('$allinsttypes');
       var offloadtypes = new Array('primary','default');
   
       document.getElementById('loadbalancing_targets_'+balnum).style.display='block';
       document.getElementById('loadbalancing_disabled_'+balnum).style.display='none';
    
       for (var i=0; i<offloadtypes.length; i++) {
           var count = 0;
           for (var j=0; j<alltargets.length; j++) {
               if (alltargets[j] != balancer) {
                   var item = document.getElementById('loadbalancing_target_'+balnum+'_'+offloadtypes[i]+'_'+count);
                   item.value = alltargets[j];
                   item.style.textAlign='left';
                   item.style.textFace='normal';
                   document.getElementById('loadbalancing_targettxt_'+balnum+'_'+offloadtypes[i]+'_'+count).innerHTML = alltargets[j];
                   if (currBalancers.indexOf(alltargets[j]) == -1) {
                       item.disabled = '';
                   } else {
                       item.disabled = 'disabled';
                       item.checked = false;
                   }
                   count ++;
               }
           }
       }
       for (var k=0; k<insttypes.length; k++) {
           if ((insttypes[k] == '_LC_external') || (insttypes[k] == '_LC_internetdom')) {
               if (ishomedom == 1) {
                   document.getElementById('balanceruletitle_'+balnum+'_'+insttypes[k]).style.display='block';
                   document.getElementById('balancerule_'+balnum+'_'+insttypes[k]).style.display='block';
               } else {
                   document.getElementById('balanceruletitle_'+balnum+'_'+insttypes[k]).style.display='none';
                   document.getElementById('balancerule_'+balnum+'_'+insttypes[k]).style.display='none';
               }
           } else {
               document.getElementById('balanceruletitle_'+balnum+'_'+insttypes[k]).style.display='block';
               document.getElementById('balancerule_'+balnum+'_'+insttypes[k]).style.display='block';
           }
           if ((insttypes[k] != '_LC_external') && 
               ((insttypes[k] != '_LC_internetdom') ||
                ((insttypes[k] == '_LC_internetdom') && (ishomedom == 1)))) {
               var item = document.getElementById('loadbalancing_singleserver_'+balnum+'_'+insttypes[k]);
               item.options.length = 0;
               item.options[0] = new Option("","",true,true);
               var idx = 0;
               for (var m=0; m<alltargets.length; m++) {
                   if ((currBalancers.indexOf(alltargets[m]) == -1) && (alltargets[m] != balancer)) {
                       idx ++;
                       item.options[idx] = new Option(alltargets[m],alltargets[m],false,false);
                   }
             }              }
             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);      return;
   }
   
   function hideSpares(balnum) {
       var alltargets = new Array('$alltargets');
       var insttypes = new Array('$allinsttypes');
       var offloadtypes = new Array('primary','default');
   
       document.getElementById('loadbalancing_targets_'+balnum).style.display='none';
       document.getElementById('loadbalancing_disabled_'+balnum).style.display='block';
   
       var total = alltargets.length - 1;
       for (var i=0; i<offloadtypes; i++) {
           for (var j=0; j<total; j++) {
              document.getElementById('loadbalancing_target_'+balnum+'_'+offloadtypes[i]+'_'+j).checked = false;
              document.getElementById('loadbalancing_target_'+balnum+'_'+offloadtypes[i]+'_'+j).value = '';
              document.getElementById('loadbalancing_targettxt_'+balnum+'_'+offloadtypes[i]+'_'+j).innerHTML = '';
           }
       }
       for (var k=0; k<insttypes.length; k++) {
           document.getElementById('balanceruletitle_'+balnum+'_'+insttypes[k]).style.display='none';
           document.getElementById('balancerule_'+balnum+'_'+insttypes[k]).style.display='none';
           if (insttypes[k] != '_LC_external') {
               document.getElementById('loadbalancing_singleserver_'+balnum+'_'+insttypes[k]).length = 0;
               document.getElementById('loadbalancing_singleserver_'+balnum+'_'+insttypes[k]).options[0] = new Option("","",true,true);
           }
       }
       return;
   }
   
   function checkOffloads(item,balnum,type) {
       var alltargets = new Array('$alltargets');
       var offloadtypes = new Array('primary','default');
       if (item.checked) {
           var total = alltargets.length - 1;
           var other;
           if (type == offloadtypes[0]) {
               other = offloadtypes[1];
           } else {
               other = offloadtypes[0];
           }
           for (var i=0; i<total; i++) {
               var server = document.getElementById('loadbalancing_target_'+balnum+'_'+other+'_'+i).value;
               if (server == item.value) {
                   if (document.getElementById('loadbalancing_target_'+balnum+'_'+other+'_'+i).checked) {
                       document.getElementById('loadbalancing_target_'+balnum+'_'+other+'_'+i).checked = false;
                   }
               }
           }
       }
       return;
   }
   
   function singleServerToggle(balnum,type) {
       var offloadtoSelIdx = document.getElementById('loadbalancing_singleserver_'+balnum+'_'+type).selectedIndex;
       if (offloadtoSelIdx == 0) {
           document.getElementById('loadbalancing_rules_'+balnum+'_'+type+'_0').checked = true;
           document.getElementById('loadbalancing_singleserver_'+balnum+'_'+type).options[0].text = '';
   
       } else {
           document.getElementById('loadbalancing_rules_'+balnum+'_'+type+'_2').checked = true;
           document.getElementById('loadbalancing_singleserver_'+balnum+'_'+type).options[0].text = '$select';
       }
       return;
   }
   
   function balanceruleChange(formname,balnum,type) {
       if (type == '_LC_external') {
           return;
       }
       var typesRules = getIndicesByName(formname,'loadbalancing_rules_'+balnum+'_'+type);
       for (var i=0; i<typesRules.length; i++) {
           if (formname.elements[typesRules[i]].checked) {
               if (formname.elements[typesRules[i]].value != 'specific') {
                   document.getElementById('loadbalancing_singleserver_'+balnum+'_'+type).selectedIndex = 0;
                   document.getElementById('loadbalancing_singleserver_'+balnum+'_'+type).options[0].text = '';
               } else {
                   document.getElementById('loadbalancing_singleserver_'+balnum+'_'+type).options[0].text = '$select';
               }
           }
       }
       return;
   }
   
   function balancerDeleteChange(balnum) {
       var hostitem = document.getElementById('loadbalancing_lonhost_'+balnum);
       var baltotal = document.getElementById('loadbalancing_total').value;
       var addtarget;
       var removetarget;
       var action = 'delete';
       if (document.getElementById('loadbalancing_delete_'+balnum)) {
           var lonhost = hostitem.value;
           var currIdx = currBalancers.indexOf(lonhost);
           if (document.getElementById('loadbalancing_delete_'+balnum).checked) {
               if (currIdx != -1) {
                   currBalancers.splice(currIdx,1);
               }
               addtarget = lonhost;
           } else {
               if (currIdx == -1) {
                   currBalancers.push(lonhost);
               }
               removetarget = lonhost;
               action = 'undelete';
           }
           balancerChange(balnum,baltotal,action,addtarget,removetarget);
       }
       return;
   }
   
   function balancerChange(balnum,baltotal,action,addtarget,removetarget) {
       if (baltotal > 1) {
           var offloadtypes = new Array('primary','default');
           var alltargets = new Array('$alltargets');
           var insttypes = new Array('$allinsttypes');
           for (var i=0; i<baltotal; i++) {
               if (i != balnum) {
                   for (var j=0; j<offloadtypes.length; j++) {
                       var total = alltargets.length - 1;
                       for (var k=0; k<total; k++) {
                           var serveritem = document.getElementById('loadbalancing_target_'+i+'_'+offloadtypes[j]+'_'+k);
                           var server = serveritem.value;
                           if ((action == 'delete') || (action == 'change' && addtarget != ''))  {
                               if (server == addtarget) {
                                   serveritem.disabled = '';
                               }
                           }
                           if ((action == 'undelete') || (action == 'change' && removetarget != '')) {
                               if (server == removetarget) {
                                   serveritem.disabled = 'disabled';
                                   serveritem.checked = false;
                               }
                           }
                       }
                   }
                   for (var j=0; j<insttypes.length; j++) {
                       if (insttypes[j] != '_LC_external') {
                           if (document.getElementById('loadbalancing_singleserver_'+i+'_'+insttypes[j])) {
                               var singleserver = document.getElementById('loadbalancing_singleserver_'+i+'_'+insttypes[j]);
                               var currSel = singleserver.selectedIndex;
                               var currVal = singleserver.options[currSel].value;
                               if ((action == 'delete') || (action == 'change' && addtarget != '')) {
                                   var numoptions = singleserver.options.length;
                                   var needsnew = 1;
                                   for (var k=0; k<numoptions; k++) {
                                       if (singleserver.options[k] == addtarget) {
                                           needsnew = 0;
                                           break;
                                       }
                                   }
                                   if (needsnew == 1) {
                                       singleserver.options[numoptions] = new Option(addtarget,addtarget,false,false);
                                   }
                               }
                               if ((action == 'undelete') || (action == 'change' && removetarget != '')) {
                                   singleserver.options.length = 0;
                                   if ((currVal) && (currVal != removetarget)) {
                                       singleserver.options[0] = new Option("","",false,false);
                                   } else {
                                       singleserver.options[0] = new Option("","",true,true);
                                   }
                                   var idx = 0;
                                   for (var m=0; m<alltargets.length; m++) {
                                       if (currBalancers.indexOf(alltargets[m]) == -1) {
                                           idx ++;
                                           if (currVal == alltargets[m]) {
                                               singleserver.options[idx] = new Option(alltargets[m],alltargets[m],true,true);
                                           } else {
                                               singleserver.options[idx] = new Option(alltargets[m],alltargets[m],false,false);
                                           }
                                       }
                                   }
                               }
                           }
                       }
                   }
               }
           }
       }
       return;
   }
   
   // ]]>
   </script>
   
   END
   }
   
   sub new_spares_js {
       my @sparestypes = ('primary','default');
       my $types = join("','",@sparestypes);
       my $select = &mt('Select');
       return <<"END";
   
   <script type="text/javascript">
   // <![CDATA[
   
   function updateNewSpares(formname,lonhost) {
       var types = new Array('$types');
       var include = new Array();
       var exclude = new Array();
       for (var i=0; i<types.length; i++) {
           var spareboxes = getIndicesByName(formname,'spare_'+types[i]+'_'+lonhost);
           for (var j=0; j<spareboxes.length; j++) {
               if (formname.elements[spareboxes[j]].checked) {
                   exclude.push(formname.elements[spareboxes[j]].value);
               } else {
                   include.push(formname.elements[spareboxes[j]].value);
               }
           }
       }
       for (var i=0; i<types.length; i++) {
           var newSpare = document.getElementById('newspare_'+types[i]+'_'+lonhost);
           var selIdx = newSpare.selectedIndex;
           var currnew = newSpare.options[selIdx].value;
           var okSpares = new Array();
           for (var j=0; j<newSpare.options.length; j++) {
               var possible = newSpare.options[j].value;
               if (possible != '') {
                   if (exclude.indexOf(possible) == -1) {
                       okSpares.push(possible);
                   } else {
                       if (currnew == possible) {
                           selIdx = 0;
                       }
                   }
               }
           }
           for (var k=0; k<include.length; k++) {
               if (okSpares.indexOf(include[k]) == -1) {
                   okSpares.push(include[k]);
               }
           }
           okSpares.sort();
           newSpare.options.length = 0;
           if (selIdx == 0) {
               newSpare.options[0] = new Option("$select","",true,true);
           } else {
               newSpare.options[0] = new Option("$select","",false,false);
           }
           for (var m=0; m<okSpares.length; m++) {
               var idx = m+1;
               var selThis = 0;
               if (selIdx != 0) {
                   if (okSpares[m] == currnew) {
                       selThis = 1;
                   }
               }
               if (selThis == 1) {
                   newSpare.options[idx] = new Option(okSpares[m],okSpares[m],true,true);
               } else {
                   newSpare.options[idx] = new Option(okSpares[m],okSpares[m],false,false);
               }
           }
       }
       return;
   }
   
   function checkNewSpares(lonhost,type) {
       var newSpare = document.getElementById('newspare_'+type+'_'+lonhost);
       var chosen =  newSpare.options[newSpare.selectedIndex].value;
       if (chosen != '') { 
           var othertype;
           var othernewSpare;
           if (type == 'primary') {
               othernewSpare = document.getElementById('newspare_default_'+lonhost);
           }
           if (type == 'default') {
               othernewSpare = document.getElementById('newspare_primary_'+lonhost);
           }
           if (othernewSpare.options[othernewSpare.selectedIndex].value == chosen) {
               othernewSpare.selectedIndex = 0;
           }
       }
       return;
   }
   
   // ]]>
   </script>
   
   END
   
   }
   
   sub common_domprefs_js {
       return <<"END";
   
   <script type="text/javascript">
   // <![CDATA[
   
   function getIndicesByName(formname,item) {
       var group = new Array();
       for (var i=0;i<formname.elements.length;i++) {
           if (formname.elements[i].name == item) {
               group.push(formname.elements[i].id);
           }
       }
       return group;
   }
   
   // ]]>
   </script>
   
   END
   
   }
   
   sub recaptcha_js {
       my %lt = &captcha_phrases();
       return <<"END";
   
   <script type="text/javascript">
   // <![CDATA[
   
   function updateCaptcha(caller,context) {
       var privitem;
       var pubitem;
       var privtext;
       var pubtext;
       if (document.getElementById(context+'_recaptchapub')) {
           pubitem = document.getElementById(context+'_recaptchapub');
       } else {
           return;
       }
       if (document.getElementById(context+'_recaptchapriv')) {
           privitem = document.getElementById(context+'_recaptchapriv');
       } else {
           return;
       }
       if (document.getElementById(context+'_recaptchapubtxt')) {
           pubtext = document.getElementById(context+'_recaptchapubtxt');
       } else {
           return;
       }
       if (document.getElementById(context+'_recaptchaprivtxt')) {
           privtext = document.getElementById(context+'_recaptchaprivtxt');
       } else {
           return;
       }
       if (caller.checked) {
           if (caller.value == 'recaptcha') {
               pubitem.type = 'text';
               privitem.type = 'text';
               pubitem.size = '40';
               privitem.size = '40';
               pubtext.innerHTML = "$lt{'pub'}";
               privtext.innerHTML = "$lt{'priv'}";
           } else {
               pubitem.type = 'hidden';
               privitem.type = 'hidden';
               pubtext.innerHTML = '';
               privtext.innerHTML = '';
           }
       }
       return;
   }
   
   // ]]>
   </script>
   
   END
   
   }
   
   sub credits_js {
       return <<"END";
   
   <script type="text/javascript">
   // <![CDATA[
   
   function toggleCredits(domForm) {
       if (document.getElementById('credits')) {
           creditsitem = document.getElementById('credits');
           var creditsLength = domForm.coursecredits.length;
           if (creditsLength) {
               var currval;
               for (var i=0; i<creditsLength; i++) {
                   if (domForm.coursecredits[i].checked) {
                      currval = domForm.coursecredits[i].value;
                   }
               }
               if (currval == 1) {
                   creditsitem.style.display = 'block';
               } else {
                   creditsitem.style.display = 'none';
               }
           }
       }
       return;
   }
   
   // ]]>
   </script>
   
   END
   
   }
   
   sub captcha_phrases {
       return &Apache::lonlocal::texthash (
                    priv => 'Private key',
                    pub  => 'Public key',
                    original  => 'original (CAPTCHA)',
                    recaptcha => 'successor (ReCAPTCHA)',
                    notused   => 'unused',
       );
   }
   
   sub devalidate_remote_domconfs {
       my ($dom,$cachekeys) = @_;
       return unless (ref($cachekeys) eq 'HASH');
       my %servers = &Apache::lonnet::internet_dom_servers($dom);
       my %thismachine;
       map { $thismachine{$_} = 1; } &Apache::lonnet::current_machine_ids();
       my @posscached = ('domainconfig','domdefaults');
       if (keys(%servers) > 1) {
           foreach my $server (keys(%servers)) {
               next if ($thismachine{$server});
               my @cached;
               foreach my $name (@posscached) {
                   if ($cachekeys->{$name}) {
                       push(@cached,&escape($name).':'.&escape($dom));
                   }
               }
               if (@cached) {
                   &Apache::lonnet::remote_devalidate_cache($server,\@cached);
               }
           }
       }
       return;
 }  }
   
 1;  1;

Removed from v.1.126  
changed lines
  Added in v.1.215


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