--- loncom/interface/domainprefs.pm	2009/08/06 15:14:08	1.100
+++ loncom/interface/domainprefs.pm	2009/11/16 04:03:05	1.119
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA
 # Handler to set domain-wide configuration settings
 #
-# $Id: domainprefs.pm,v 1.100 2009/08/06 15:14:08 raeburn Exp $
+# $Id: domainprefs.pm,v 1.119 2009/11/16 04:03:05 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -28,6 +28,131 @@
 ###############################################################
 ##############################################################
 
+=pod
+
+=head1 NAME
+
+Apache::domainprefs.pm
+
+=head1 SYNOPSIS
+
+Handles configuration of a LON-CAPA domain.  
+
+This is part of the LearningOnline Network with CAPA project
+described at http://www.lon-capa.org.
+
+
+=head1 OVERVIEW
+
+Each institution using LON-CAPA will typically have a single domain designated 
+for use by individuals affliated with the institution.  Accordingly, each domain
+may define a default set of logos and a color scheme which can be used to "brand"
+the LON-CAPA instance. In addition, an institution will typically have a language
+and timezone which are used for the majority of courses.
+
+LON-CAPA provides a mechanism to display and modify these defaults, as well as a 
+host of other domain-wide settings which determine the types of functionality
+available to users and courses in the domain.
+
+There is also a mechanism to configure cataloging of courses in the domain, and
+controls on the operation of automated processes which govern such things as
+roster updates, user directory updates and processing of course requests.
+
+The domain coordination manual which is built dynamically on install/update of 
+LON-CAPA from the relevant help items provides more information about domain 
+configuration.
+
+Most of the domain settings are stored in the configuration.db GDBM file which is
+housed on the primary library server for the domain in /home/httpd/lonUsers/$dom,
+where $dom is the domain.  The configuration.db stores settings in a number of 
+frozen hashes of hashes.  In a few cases, domain information must be uploaded to
+the domain as files (e.g., image files for logos etc., or plain text files for
+bubblesheet formats).  In this case the domainprefs.pm must be running in a user
+session hosted on the primary library server in the domain, as these files are 
+stored in author space belonging to a special $dom-domainconfig user.   
+
+domainprefs.pm in combination with lonconfigsettings.pm will retrieve and display
+the current settings, and provides an interface to make modifications.
+
+=head1 SUBROUTINES
+
+=over
+
+=item print_quotas()
+
+Inputs: 4 
+
+$dom,$settings,$rowtotal,$action.
+
+$dom is the domain, $settings is a reference to a hash of current settings for
+the current context, $rowtotal is a reference to the scalar used to record the 
+number of rows displayed on the page, and $action is the context (either quotas 
+or requestcourses).
+
+The print_quotas routine was orginally created to display/store information
+about default quota sizes for portfolio spaces for the different types of 
+institutional affiliation in the domain (e.g., Faculty, Staff, Student etc.), 
+but is now also used to manage availability of user tools: 
+i.e., blogs, aboutme page, and portfolios, and the course request tool,
+used by course owners to request creation of a course.
+
+Outputs: 1
+
+$datatable  - HTML containing form elements which allow settings to be changed. 
+
+In the case of course requests, radio buttons are displayed for each institutional
+affiliate type (and also default, and _LC_adv) for each of the course types 
+(official, unofficial and community).  In each case the radio buttons allow the 
+selection of one of four values:
+
+0, approval, validate, autolimit=N (where N is blank, or a positive integer).
+which have the following effects:
+
+0
+
+=over
+
+- course requests are not allowed for this course types/affiliation
+
+=back
+
+approval 
+
+=over 
+
+- course requests must be approved by a Doman Coordinator in the 
+course's domain
+
+=back
+
+validate 
+
+=over
+
+- an institutional validation (e.g., check requestor is instructor
+of record) needs to be passed before the course will be created.  The required
+validation is in localenroll.pm on the primary library server for the course 
+domain.
+
+=back
+
+autolimit 
+
+=over
+ 
+- course requests will be processed autoatically up to a limit of
+N requests for the course type for the particular requestor.
+If N is undefined, there is no limit to the number of course requests
+which a course owner may submit and have processed automatically. 
+
+=back
+
+=item modify_quotas() 
+
+=back
+
+=cut
+
 package Apache::domainprefs;
 
 use strict;
@@ -77,11 +202,11 @@ sub handler {
                 'quotas','autoenroll','autoupdate','directorysrch',
                 'usercreation','usermodification','contacts','defaults',
                 'scantron','coursecategories','serverstatuses',
-                'requestcourses'],$dom);
+                'requestcourses','helpsettings'],$dom);
     my @prefs_order = ('rolecolors','login','defaults','quotas','autoenroll',
                        'autoupdate','directorysrch','contacts',
                        'usercreation','usermodification','scantron',
-                       'requestcourses','coursecategories','serverstatuses');
+                       'requestcourses','coursecategories','serverstatuses','helpsettings');
     my %prefs = (
         'rolecolors' =>
                    { text => 'Default color schemes',
@@ -95,12 +220,13 @@ sub handler {
                                 {col1 => 'Administrator Settings',
                                  col2 => '',}],
                     },
-        'login' =>  
+        'login' =>
                     { text => 'Log-in page options',
                       help => 'Domain_Configuration_Login_Page',
                       header => [{col1 => 'Item',
                                   col2 => '',}],
                     },
+
         'defaults' => 
                     { text => 'Default authentication/language/timezone',
                       help => 'Domain_Configuration_LangTZAuth',
@@ -172,7 +298,9 @@ sub handler {
                  {text => 'Request creation of courses',
                   help => 'Domain_Configuration_Request_Courses',
                   header => [{col1 => 'User affiliation',
-                              col2 => 'Requestable course types',}],
+                              col2 => 'Availability/Processing of requests',},
+                             {col1 => 'Setting',
+                              col2 => 'Value'}],
                  },
         'coursecategories' =>
                   { text => 'Cataloging of courses',
@@ -191,7 +319,23 @@ sub handler {
                               col3 => 'Specific IPs',
                             }],
                  },
+        'helpsettings' =>
+                 {text   => 'Help page settings',
+                  help   => 'Domain_Configuration_Help_Settings',
+                  header => [{col1 => 'Setting',
+                              col2 => 'Value',}],
+                 },
     );
+    my %servers = &dom_servers($dom);
+    if (keys(%servers) > 1) {
+        $prefs{'login'}  = { text   => 'Log-in page options',
+                             help   => 'Domain_Configuration_Login_Page',
+                            header => [{col1 => 'Log-in Service',
+                                        col2 => 'Server Setting',},
+                                       {col1 => 'Log-in Page Items',
+                                        col2 => ''}],
+                           };
+    }
     my @roles = ('student','coordinator','author','admin');
     my @actions = &Apache::loncommon::get_env_multiple('form.actions');
     &Apache::lonhtmlcommon::add_breadcrumb
@@ -277,6 +421,8 @@ sub process_changes {
         $output = &modify_serverstatuses($dom,%domconfig);
     } elsif ($action eq 'requestcourses') {
         $output = &modify_quotas($dom,$action,%domconfig);
+    } elsif ($action eq 'helpsettings') {
+        $output = &modify_helpsettings($dom,%domconfig);
     }
     return $output;
 }
@@ -296,9 +442,11 @@ sub print_config_box {
            &Apache::loncommon::help_open_topic($item->{'help'}).'</span></th>'."\n".
           '</tr>';
     $rowtotal ++;
-    if (($action eq 'autoupdate') || ($action eq 'rolecolors') || 
-        ($action eq 'usercreation') || ($action eq 'usermodification') ||
-        ($action eq 'coursecategories')) {
+    my $numheaders = 1;
+    if (ref($item->{'header'}) eq 'ARRAY') {
+        $numheaders = scalar(@{$item->{'header'}});
+    }
+    if ($numheaders > 1) {
         my $colspan = '';
         if (($action eq 'rolecolors') || ($action eq 'coursecategories')) {
             $colspan = ' colspan="2"';
@@ -320,6 +468,13 @@ sub print_config_box {
             $output .= &print_usermodification('top',$dom,$settings,\$rowtotal);
         } elsif ($action eq 'coursecategories') {
             $output .= &print_coursecategories('top',$dom,$item,$settings,\$rowtotal);
+        } elsif ($action eq 'login') {
+            $output .= &print_login('top',$dom,$confname,$phase,$settings,\$rowtotal);
+            $colspan = ' colspan="2"';
+        } elsif ($action eq 'requestcourses') {
+            $output .= &print_quotas($dom,$settings,\$rowtotal,$action);
+        } elsif ($action eq 'helpsettings') {
+            $output .= &print_helpsettings($dom,$settings,\$rowtotal);
         } else {
             $output .= &print_rolecolors($phase,'student',$dom,$confname,$settings,\$rowtotal);
         }
@@ -367,6 +522,10 @@ sub print_config_box {
             $rowtotal ++;
         } elsif ($action eq 'coursecategories') {
             $output .= &print_coursecategories('bottom',$dom,$item,$settings,\$rowtotal);
+        } elsif ($action eq 'login') {
+            $output .= &print_login('bottom',$dom,$confname,$phase,$settings,\$rowtotal);
+        } elsif ($action eq 'requestcourses') {
+            $output .= &print_courserequestmail($dom,$settings,\$rowtotal);
         } else {
             $output .= &print_rolecolors($phase,'coordinator',$dom,$confname,$settings,\$rowtotal).'
            </table>
@@ -435,7 +594,8 @@ sub print_config_box {
         $output .= '</tr>';
         $rowtotal ++;
         if ($action eq 'login') {
-            $output .= &print_login($dom,$confname,$phase,$settings,\$rowtotal);
+            $output .= &print_login('bottom',$dom,$confname,$phase,$settings,
+                                    \$rowtotal);
         } elsif ($action eq 'quotas') {
             $output .= &print_quotas($dom,$settings,\$rowtotal,$action);
         } elsif ($action eq 'autoenroll') {
@@ -450,9 +610,9 @@ sub print_config_box {
             $output .= &print_scantronformat($r,$dom,$confname,$settings,\$rowtotal);
         } elsif ($action eq 'serverstatuses') {
             $output .= &print_serverstatuses($dom,$settings,\$rowtotal);
-        } elsif ($action eq 'requestcourses') {
-            $output .= &print_quotas($dom,$settings,\$rowtotal,$action);
-        }
+        } elsif ($action eq 'helpsettings') {
+        	$output .= &print_helpsettings($dom,$settings,\$rowtotal);
+    	}
     }
     $output .= '
    </table>
@@ -463,8 +623,48 @@ sub print_config_box {
 }
 
 sub print_login {
-    my ($dom,$confname,$phase,$settings,$rowtotal) = @_;
+    my ($position,$dom,$confname,$phase,$settings,$rowtotal) = @_;
+    my ($css_class,$datatable);
     my %choices = &login_choices();
+    my $itemcount = 1;
+
+    if ($position eq 'top') {
+        my %servers = &dom_servers($dom);
+        my $choice = $choices{'disallowlogin'};
+        $css_class = ' class="LC_odd_row"';
+        $datatable .= '<tr'.$css_class.'><td>'.$choices{'disallowlogin'}.'</td>'.
+                      '<td align="right"><table><tr><th>'.$choices{'hostid'}.'</th>'.
+                      '<th>'.$choices{'serverurl'}.'</th></tr>'."\n";
+        my %disallowed;
+        if (ref($settings) eq 'HASH') {
+            if (ref($settings->{'loginvia'}) eq 'HASH') {
+               %disallowed = %{$settings->{'loginvia'}};
+            }
+        }
+        foreach my $lonhost (sort(keys(%servers))) {
+            my $direct = 'selected="selected"';
+            if ($disallowed{$lonhost} eq '') {
+                $direct = '';
+            }
+            $datatable .= '<tr><td>'.$servers{$lonhost}.'</td>'.
+                          '<td><select name="'.$lonhost.'_serverurl">'.
+                          '<option value=""'.$direct.'>'.$choices{'directlogin'}.
+                          '</option>';
+            foreach my $hostid (keys(%servers)) {
+                next if ($servers{$hostid} eq $servers{$lonhost});
+                my $selected = '';
+                if ($hostid eq $disallowed{$lonhost}) {
+                    $selected = 'selected="selected"';
+                }
+                $datatable .= '<option value="'.$hostid.'"'.$selected.'>'.
+                              $servers{$hostid}.'</option>';
+            }
+            $datatable .= '</select></td></tr>';
+        }
+        $datatable .= '</table></td></tr>';
+        return $datatable;
+    }
+
     my %defaultchecked = ( 
                            'coursecatalog' => 'on',
                            'adminmail'     => 'off',
@@ -599,24 +799,28 @@ sub print_login {
 sub login_choices {
     my %choices =
         &Apache::lonlocal::texthash (
-            coursecatalog => 'Display Course Catalog link?',
-            adminmail => "Display Administrator's E-mail Address?",
-            newuser   => "Link to create a user account",
-            img => "Header",
-            logo => "Main Logo",
-            domlogo => "Domain Logo",
-            login => "Log-in Header", 
-            textcol => "Text color",
-            bgcol   => "Box color",
-            bgs => "Background colors",
-            links => "Link colors",
-            font => "Font color",
-            pgbg => "Header",
-            mainbg => "Page",
-            sidebg => "Login box",
-            link => "Link",
-            alink => "Active link",
-            vlink => "Visited link",
+            coursecatalog => 'Display Course/Community Catalog link?',
+            adminmail     => "Display Administrator's E-mail Address?",
+            disallowlogin => "Login page requests redirected",
+            hostid        => "Server",
+            serverurl     => "Redirect to log-in via:",
+            directlogin   => "No redirect",
+            newuser       => "Link to create a user account",
+            img           => "Header",
+            logo          => "Main Logo",
+            domlogo       => "Domain Logo",
+            login         => "Log-in Header", 
+            textcol       => "Text color",
+            bgcol         => "Box color",
+            bgs           => "Background colors",
+            links         => "Link colors",
+            font          => "Font color",
+            pgbg          => "Header",
+            mainbg        => "Page",
+            sidebg        => "Login box",
+            link          => "Link",
+            alink         => "Active link",
+            vlink         => "Visited link",
         );
     return %choices;
 }
@@ -720,20 +924,22 @@ sub display_color_options {
                   '&nbsp;<span id="css_'.$role.'_font" style="background-color: '.
                   $designs->{'font'}.';">&nbsp;&nbsp;&nbsp;</span>'.
                   '</span></td></tr>';
-    $datatable .= '<tr'.$css_class.'>'.
-        '<td>'.$choices->{'fontmenu'}.'</td>';
-    if (!$is_custom->{'fontmenu'}) {
-        $datatable .=  '<td>'.&mt('Default in use:').'&nbsp;<span id="css_default_'.$role.'_font" style="color: '.$defaults->{'fontmenu'}.';">'.$defaults->{'fontmenu'}.'</span></td>';
-    } else {
-        $datatable .= '<td>&nbsp;</td>';
+    unless ($role eq 'login') { 
+        $datatable .= '<tr'.$css_class.'>'.
+                      '<td>'.$choices->{'fontmenu'}.'</td>';
+        if (!$is_custom->{'fontmenu'}) {
+            $datatable .=  '<td>'.&mt('Default in use:').'&nbsp;<span id="css_default_'.$role.'_font" style="color: '.$defaults->{'fontmenu'}.';">'.$defaults->{'fontmenu'}.'</span></td>';
+        } else {
+            $datatable .= '<td>&nbsp;</td>';
+        }
+        $fontlink = &color_pick($phase,$role,'fontmenu',$choices->{'fontmenu'},$designs->{'fontmenu'});
+        $datatable .= '<td><span class="LC_nobreak">'.
+                      '<input type="text" size="10" name="'.$role.'_fontmenu"'.
+                      ' value="'.$designs->{'fontmenu'}.'" />&nbsp;'.$fontlink.
+                      '&nbsp;<span id="css_'.$role.'_fontmenu" style="background-color: '.
+                      $designs->{'fontmenu'}.';">&nbsp;&nbsp;&nbsp;</span>'.
+                      '</span></td></tr>';
     }
-    $fontlink = &color_pick($phase,$role,'fontmenu',$choices->{'fontmenu'},$designs->{'fontmenu'});
-    $datatable .= '<td><span class="LC_nobreak">'.
-                  '<input type="text" size="10" name="'.$role.'_fontmenu"'.
-                  ' value="'.$designs->{'fontmenu'}.'" />&nbsp;'.$fontlink.
-                  '&nbsp;<span id="css_'.$role.'_fontmenu" style="background-color: '.
-                  $designs->{'fontmenu'}.';">&nbsp;&nbsp;&nbsp;</span>'.
-                  '</span></td></tr>';
     my $switchserver = &check_switchserver($dom,$confname);
     foreach my $img (@{$images}) {
 	$itemcount ++;
@@ -1014,16 +1220,19 @@ sub print_quotas {
     } else {
         $context = $action;
     }
-    my ($datatable,$defaultquota,@usertools);
+    my ($datatable,$defaultquota,@usertools,@options,%validations);
     my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom);
     my $typecount = 0;
-    my $css_class;
+    my ($css_class,%titles);
     if ($context eq 'requestcourses') {
         @usertools = ('official','unofficial','community');
+        @options =('norequest','approval','validate','autolimit');
+        %validations = &Apache::lonnet::auto_courserequest_checks($dom);
+        %titles = &courserequest_titles();
     } else {
         @usertools = ('aboutme','blog','portfolio');
+        %titles = &tool_titles();
     }
-    my %titles = &tool_titles();
     if (ref($types) eq 'ARRAY') {
         foreach my $type (@{$types}) {
             my $currdefquota;
@@ -1042,24 +1251,84 @@ sub print_quotas {
                 $datatable .= '<tr'.$css_class.'>'.
                               '<td>'.$usertypes->{$type}.'</td>'.
                               '<td class="LC_left_item">';
+                if ($context eq 'requestcourses') {
+                    $datatable .= '<table><tr>';
+                }
+                my %cell;  
                 foreach my $item (@usertools) {
-                    my $checked;
-                    unless ($context eq 'requestcourses') {
-                        $checked = 'checked="checked" ';
-                    }
-                    if (ref($settings) eq 'HASH') {
-                        if (ref($settings->{$item}) eq 'HASH') {
-                            if ($settings->{$item}->{$type} == 0) {
-                                $checked = '';
-                            } elsif ($settings->{$item}->{$type} == 1) {
-                                $checked =  'checked="checked" ';
+                    if ($context eq 'requestcourses') {
+                        my ($curroption,$currlimit);
+                        if (ref($settings) eq 'HASH') {
+                            if (ref($settings->{$item}) eq 'HASH') {
+                                $curroption = $settings->{$item}->{$type};
+                                if ($curroption =~ /^autolimit=(\d*)$/) {
+                                    $currlimit = $1; 
+                                }
+                            }
+                        }
+                        if (!$curroption) {
+                            $curroption = 'norequest';
+                        }
+                        $datatable .= '<th>'.$titles{$item}.'</th>';
+                        foreach my $option (@options) {
+                            my $val = $option;
+                            if ($option eq 'norequest') {
+                                $val = 0;  
+                            }
+                            if ($option eq 'validate') {
+                                my $canvalidate = 0;
+                                if (ref($validations{$item}) eq 'HASH') { 
+                                    if ($validations{$item}{$type}) {
+                                        $canvalidate = 1;
+                                    }
+                                }
+                                next if (!$canvalidate);
+                            }
+                            my $checked = '';
+                            if ($option eq $curroption) {
+                                $checked = ' checked="checked"';
+                            } elsif ($option eq 'autolimit') {
+                                if ($curroption =~ /^autolimit/) {
+                                    $checked = ' checked="checked"';
+                                }                       
+                            } 
+                            $cell{$item} .= '<span class="LC_nobreak"><label>'.
+                                  '<input type="radio" name="crsreq_'.$item.
+                                  '_'.$type.'" value="'.$val.'"'.$checked.' />'.
+                                  $titles{$option}.'</label>&nbsp;';
+                            if ($option eq 'autolimit') {
+                                $cell{$item} .= '<input type="text" name="crsreq_'.
+                                                $item.'_limit_'.$type.'" size="1" '.
+                                                'value="'.$currlimit.'" />';
+                            }
+                            $cell{$item} .= '</span>&nbsp; ';
+                            if ($option eq 'autolimit') {
+                                $cell{$item} .= $titles{'unlimited'}
                             }
                         }
+                    } else {
+                        my $checked = 'checked="checked" ';
+                        if (ref($settings) eq 'HASH') {
+                            if (ref($settings->{$item}) eq 'HASH') {
+                                if ($settings->{$item}->{$type} == 0) {
+                                    $checked = '';
+                                } elsif ($settings->{$item}->{$type} == 1) {
+                                    $checked =  'checked="checked" ';
+                                }
+                            }
+                        }
+                        $datatable .= '<span class="LC_nobreak"><label>'.
+                                      '<input type="checkbox" name="'.$context.'_'.$item.
+                                      '" value="'.$type.'" '.$checked.'/>'.$titles{$item}.
+                                      '</label></span>&nbsp; ';
                     }
-                    $datatable .= '<span class="LC_nobreak"><label>'.
-                                  '<input type="checkbox" name="'.$context.'_'.$item.
-                                  '" value="'.$type.'" '.$checked.'/>'.$titles{$item}.
-                                  '</label></span>&nbsp; ';
+                }
+                if ($context eq 'requestcourses') {
+                    $datatable .= '</tr><tr>';
+                    foreach my $item (@usertools) {
+                        $datatable .= '<td style="vertical-align: top">'.$cell{$item}.'</td>';  
+                    }
+                    $datatable .= '</tr></table>';
                 }
                 $datatable .= '</td>';
                 unless ($context eq 'requestcourses') {
@@ -1088,24 +1357,84 @@ sub print_quotas {
     $datatable .= '<tr'.$css_class.'>'.
                   '<td>'.$othertitle.'</td>'.
                   '<td class="LC_left_item">';
+    if ($context eq 'requestcourses') {
+        $datatable .= '<table><tr>';
+    }
+    my %defcell;
     foreach my $item (@usertools) {
-        my $checked;
-        unless ($context eq 'requestcourses') {
-            $checked = 'checked="checked" ';
-        }
-        if (ref($settings) eq 'HASH') {
-            if (ref($settings->{$item}) eq 'HASH') {
-                if ($settings->{$item}->{'default'} == 0) {
-                    $checked = '';
-                } elsif ($settings->{$item}->{'default'} == 1) {
-                    $checked = 'checked="checked" ';
+        if ($context eq 'requestcourses') {
+            my ($curroption,$currlimit);
+            if (ref($settings) eq 'HASH') {
+                if (ref($settings->{$item}) eq 'HASH') {
+                    $curroption = $settings->{$item}->{'default'};
+                    if ($curroption =~ /^autolimit=(\d*)$/) {
+                        $currlimit = $1;
+                    }
                 }
             }
+            if (!$curroption) {
+                $curroption = 'norequest';
+            }
+            $datatable .= '<th>'.$titles{$item}.'</th>';
+            foreach my $option (@options) {
+                my $val = $option;
+                if ($option eq 'norequest') {
+                    $val = 0;
+                }
+                if ($option eq 'validate') {
+                    my $canvalidate = 0;
+                    if (ref($validations{$item}) eq 'HASH') {
+                        if ($validations{$item}{'default'}) {
+                            $canvalidate = 1;
+                        }
+                    }
+                    next if (!$canvalidate);
+                }
+                my $checked = '';
+                if ($option eq $curroption) {
+                    $checked = ' checked="checked"';
+                } elsif ($option eq 'autolimit') {
+                    if ($curroption =~ /^autolimit/) {
+                        $checked = ' checked="checked"';
+                    }
+                }
+                $defcell{$item} .= '<span class="LC_nobreak"><label>'.
+                                  '<input type="radio" name="crsreq_'.$item.
+                                  '_default" value="'.$val.'"'.$checked.' />'.
+                                  $titles{$option}.'</label>';
+                if ($option eq 'autolimit') {
+                    $defcell{$item} .= '<input type="text" name="crsreq_'.
+                                       $item.'_limit_default" size="1" '.
+                                       'value="'.$currlimit.'" />';
+                }
+                $defcell{$item} .= '</span>&nbsp; ';
+                if ($option eq 'autolimit') {
+                    $defcell{$item} .= $titles{'unlimited'}
+                }
+            }
+        } else {
+            my $checked = 'checked="checked" ';
+            if (ref($settings) eq 'HASH') {
+                if (ref($settings->{$item}) eq 'HASH') {
+                    if ($settings->{$item}->{'default'} == 0) {
+                        $checked = '';
+                    } elsif ($settings->{$item}->{'default'} == 1) {
+                        $checked = 'checked="checked" ';
+                    }
+                }
+            }
+            $datatable .= '<span class="LC_nobreak"><label>'.
+                          '<input type="checkbox" name="'.$context.'_'.$item.
+                          '" value="default" '.$checked.'/>'.$titles{$item}.
+                          '</label></span>&nbsp; ';
         }
-        $datatable .= '<span class="LC_nobreak"><label>'.
-                      '<input type="checkbox" name="'.$context.'_'.$item.
-                      '" value="default" '.$checked.'/>'.$titles{$item}.
-                      '</label></span>&nbsp; ';
+    }
+    if ($context eq 'requestcourses') {
+        $datatable .= '</tr><tr>';
+        foreach my $item (@usertools) {
+            $datatable .= '<td style="vertical-align: top">'.$defcell{$item}.'</td>';
+        }
+        $datatable .= '</tr></table>';
     }
     $datatable .= '</td>';
     unless ($context eq 'requestcourses') {
@@ -1117,34 +1446,182 @@ sub print_quotas {
     $typecount ++;
     $css_class = $typecount%2?' class="LC_odd_row"':'';
     $datatable .= '<tr'.$css_class.'>'.
-                  '<td>'.&mt('LON-CAPA Advanced Users').
-                  ' <span class="LC_nobreak">('.
-                  &mt('overrides affiliation').')</span></td>'.
-                  '<td class="LC_left_item" colspan="2"><br />';
+                  '<td>'.&mt('LON-CAPA Advanced Users').' ';
+    if ($context eq 'requestcourses') {
+        $datatable .= &mt('(overrides affiliation, if set)').
+                      '</td>'.
+                      '<td class="LC_left_item">'.
+                      '<table><tr>';
+    } else {
+        $datatable .= &mt('(overrides affiliation, if checked)').
+                      '</td>'.
+                      '<td class="LC_left_item" colspan="2">'.
+                      '<br />';
+    }
+    my %advcell;
     foreach my $item (@usertools) {
-        my $checked;
-        unless ($context eq 'requestcourses') {
-            $checked = 'checked="checked" ';
-        }
-        if (ref($settings) eq 'HASH') {
-            if (ref($settings->{$item}) eq 'HASH') {
-                if ($settings->{$item}->{'_LC_adv'} == 0) {
-                    $checked = '';
-                } elsif ($settings->{$item}->{'_LC_adv'} == 1) {
-                    $checked = 'checked="checked" ';
+        if ($context eq 'requestcourses') {
+            my ($curroption,$currlimit);
+            if (ref($settings) eq 'HASH') {
+                if (ref($settings->{$item}) eq 'HASH') {
+                    $curroption = $settings->{$item}->{'_LC_adv'};
+                    if ($curroption =~ /^autolimit=(\d*)$/) {
+                        $currlimit = $1;
+                    }
                 }
             }
+            $datatable .= '<th>'.$titles{$item}.'</th>';
+            my $checked = '';
+            if ($curroption eq '') {
+                $checked = ' checked="checked"';
+            }
+            $advcell{$item} .= '<span class="LC_nobreak"><label>'.
+                               '<input type="radio" name="crsreq_'.$item.
+                               '__LC_adv" value=""'.$checked.' />'.
+                               &mt('No override set').'</label></span>&nbsp; ';
+            foreach my $option (@options) {
+                my $val = $option;
+                if ($option eq 'norequest') {
+                    $val = 0;
+                }
+                if ($option eq 'validate') {
+                    my $canvalidate = 0;
+                    if (ref($validations{$item}) eq 'HASH') {
+                        if ($validations{$item}{'_LC_adv'}) {
+                            $canvalidate = 1;
+                        }
+                    }
+                    next if (!$canvalidate);
+                }
+                my $checked = '';
+                if ($val eq $curroption) {
+                    $checked = ' checked="checked"';
+                } elsif ($option eq 'autolimit') {
+                    if ($curroption =~ /^autolimit/) {
+                        $checked = ' checked="checked"';
+                    }
+                }
+                $advcell{$item} .= '<span class="LC_nobreak"><label>'.
+                                  '<input type="radio" name="crsreq_'.$item.
+                                  '__LC_adv" value="'.$val.'"'.$checked.' />'.
+                                  $titles{$option}.'</label>';
+                if ($option eq 'autolimit') {
+                    $advcell{$item} .= '<input type="text" name="crsreq_'.
+                                       $item.'_limit__LC_adv" size="1" '.
+                                       'value="'.$currlimit.'" />';
+                }
+                $advcell{$item} .= '</span>&nbsp; ';
+                if ($option eq 'autolimit') {
+                    $advcell{$item} .= $titles{'unlimited'}
+                }
+            }
+        } else {
+            my $checked = 'checked="checked" ';
+            if (ref($settings) eq 'HASH') {
+                if (ref($settings->{$item}) eq 'HASH') {
+                    if ($settings->{$item}->{'_LC_adv'} == 0) {
+                        $checked = '';
+                    } elsif ($settings->{$item}->{'_LC_adv'} == 1) {
+                        $checked = 'checked="checked" ';
+                    }
+                }
+            }
+            $datatable .= '<span class="LC_nobreak"><label>'.
+                          '<input type="checkbox" name="'.$context.'_'.$item.
+                          '" value="_LC_adv" '.$checked.'/>'.$titles{$item}.
+                          '</label></span>&nbsp; ';
+        }
+    }
+    if ($context eq 'requestcourses') {
+        $datatable .= '</tr><tr>';
+        foreach my $item (@usertools) {
+            $datatable .= '<td style="vertical-align: top">'.$advcell{$item}.'</td>';
         }
-        $datatable .= '<span class="LC_nobreak"><label>'.
-                      '<input type="checkbox" name="'.$context.'_'.$item.
-                      '" value="_LC_adv" '.$checked.'/>'.$titles{$item}.
-                      '</label></span>&nbsp; ';
+        $datatable .= '</tr></table>';
     }
     $datatable .= '</td></tr>';
     $$rowtotal += $typecount;
     return $datatable;
 }
 
+sub print_courserequestmail {
+    my ($dom,$settings,$rowtotal) = @_;
+    my ($now,$datatable,%dompersonnel,@domcoord,@currapproval,$rows);
+    $now = time;
+    $rows = 0;
+    %dompersonnel = &Apache::lonnet::get_domain_roles($dom,['dc'],$now,$now);
+    foreach my $server (keys(%dompersonnel)) {
+        foreach my $user (sort(keys(%{$dompersonnel{$server}}))) {
+            my ($trole,$uname,$udom,$runame,$rudom,$rsec) = split(/:/,$user);
+            if (!grep(/^$uname:$udom$/,@domcoord)) {
+                push(@domcoord,$uname.':'.$udom);
+            }
+        }
+    }
+    if (ref($settings) eq 'HASH') {
+        if (ref($settings->{'notify'}) eq 'HASH') {
+            if ($settings->{'notify'}{'approval'} ne '') {
+               @currapproval = split(',',$settings->{'notify'}{'approval'});
+            }
+        }
+    }
+    if (@currapproval) {
+        foreach my $dc (@currapproval) {
+            unless (grep(/^\Q$dc\E$/,@domcoord)) {
+                push(@domcoord,$dc);
+            }
+        }
+    }
+    @domcoord = sort(@domcoord);
+    my $numinrow = 4;
+    my $numdc = @domcoord;
+    my $css_class = 'class="LC_odd_row"';
+    $datatable = '<tr'.$css_class.'>'.
+                 ' <td>'.&mt('Receive notification of course requests requiring approval.').
+                 ' </td>'.
+                 ' <td class="LC_left_item">';
+    if (@domcoord > 0) {
+        $datatable .= '<table>';
+        for (my $i=0; $i<$numdc; $i++) {
+            my $rem = $i%($numinrow);
+            if ($rem == 0) {
+                if ($i > 0) {
+                    $datatable .= '</tr>';
+                }
+                $datatable .= '<tr>';
+                $rows ++;
+            }
+            my $check = ' ';
+            if (grep(/^\Q$domcoord[$i]\E$/,@currapproval)) {
+                $check = ' checked="checked" ';
+            }
+            my ($uname,$udom) = split(':',$domcoord[$i]);
+            my $fullname = &Apache::loncommon::plainname($uname,$udom);
+            if ($i == $numdc-1) {
+                my $colsleft = $numinrow-$rem;
+                if ($colsleft > 1) {
+                    $datatable .= '<td colspan="'.$colsleft.'" class="LC_left_item">';
+                } else {
+                    $datatable .= '<td class="LC_left_item">';
+                }
+            } else {
+                $datatable .= '<td class="LC_left_item">';
+            }
+            $datatable .= '<span class="LC_nobreak"><label>'.
+                          '<input type="checkbox" name="reqapprovalnotify" '.
+                          'value="'.$domcoord[$i].'"'.$check.'/>'.
+                          $fullname.'</label></span></td>';
+        }
+        $datatable .= '</tr></table>';
+    } else {
+        $datatable .= &mt('There are no active Domain Coordinators');
+        $rows ++;
+    }
+    $datatable .='</td></tr>';
+    $$rowtotal += $rows;
+    return $datatable;
+}
+
 sub print_autoenroll {
     my ($dom,$settings,$rowtotal) = @_;
     my $autorun = &Apache::lonnet::auto_run(undef,$dom),
@@ -1381,7 +1858,8 @@ sub print_contacts {
     my $datatable;
     my @contacts = ('adminemail','supportemail');
     my (%checked,%to,%otheremails);
-    my @mailings = ('errormail','packagesmail','lonstatusmail','helpdeskmail');
+    my @mailings = ('errormail','packagesmail','lonstatusmail','helpdeskmail',
+                    'requestsmail');
     foreach my $type (@mailings) {
         $otheremails{$type} = '';
     }
@@ -1412,6 +1890,7 @@ sub print_contacts {
         $checked{'packagesmail'}{'adminemail'} = ' checked="checked" ';
         $checked{'helpdeskmail'}{'supportemail'} = ' checked="checked" ';
         $checked{'lonstatusmail'}{'adminemail'} = ' checked="checked" '; 
+        $checked{'requestsmail'}{'adminemail'} = ' checked="checked" ';
     }
     my ($titles,$short_titles) = &contact_titles();
     my $rownum = 0;
@@ -1449,6 +1928,62 @@ sub print_contacts {
     return $datatable;
 }
 
+sub print_helpsettings {
+
+	my ($dom,$settings,$rowtotal) = @_;
+	my ($css_class,$datatable);
+	my $itemcount = 1;
+	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 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 ++;
+     }
+     return $datatable;
+	
+}
+
 sub contact_titles {
     my %titles = &Apache::lonlocal::texthash (
                    'supportemail' => 'Support E-mail address',
@@ -1457,6 +1992,7 @@ sub contact_titles {
                    'packagesmail' => 'Package update alerts to be e-mailed to',
                    'helpdeskmail' => 'Helpdesk requests to be e-mailed to',
                    'lonstatusmail' => 'E-mail from nightly status check (warnings/errors)',
+                   'requestsmail' => 'E-mail from course requests requiring approval',
                  );
     my %short_titles = &Apache::lonlocal::texthash (
                            adminemail   => 'Admin E-mail address',
@@ -1477,6 +2013,29 @@ sub tool_titles {
     return %titles;
 }
 
+sub courserequest_titles {
+    my %titles = &Apache::lonlocal::texthash (
+                                   official   => 'Official',
+                                   unofficial => 'Unofficial',
+                                   community  => 'Communities',
+                                   norequest  => 'Not allowed',
+                                   approval   => 'Approval by Dom. Coord.',
+                                   validate   => 'With validation',
+                                   autolimit  => 'Numerical limit',
+                                   unlimited  => '(blank for unlimited)',
+                 );
+    return %titles;
+}
+
+sub courserequest_conditions {
+    my %conditions = &Apache::lonlocal::texthash (
+       approval    => '(Processing of request subject to approval by Domain Coordinator).',
+       validate   => '(Processing of request subject to instittutional validation).',
+                 );
+    return %conditions;
+}
+
+
 sub print_usercreation {
     my ($position,$dom,$settings,$rowtotal) = @_;
     my $numinrow = 4;
@@ -2230,7 +2789,7 @@ sub print_serverstatuses {
 sub serverstatus_pages {
     return ('userstatus','lonstatus','loncron','server-status','codeversions',
             'clusterstatus','metadata_keywords','metadata_harvest',
-            'takeoffline','takeonline','showenv');
+            'takeoffline','takeonline','showenv','toggledebug');
 }
 
 sub coursecategories_javascript {
@@ -2257,6 +2816,7 @@ sub coursecategories_javascript {
     }
     $output = <<"ENDSCRIPT";
 <script type="text/javascript">
+// <![CDATA[
 function reorderCats(form,parent,item,idx) {
     var changedVal;
 $jstext
@@ -2313,6 +2873,7 @@ $jstext
     }
     return;
 }
+// ]]>
 </script>
 
 ENDSCRIPT
@@ -2646,6 +3207,14 @@ sub modify_login {
                   newuser => 'Link for visitors to create a user account',
                   loginheader => 'Log-in box header');
     my @offon = ('off','on');
+    my %curr_loginvia;
+    if (ref($domconfig{login}) eq 'HASH') {
+        if (ref($domconfig{login}{loginvia}) eq 'HASH') {
+            foreach my $lonhost (keys(%{$domconfig{login}{loginvia}})) {
+                $curr_loginvia{$lonhost} = $domconfig{login}{loginvia}{$lonhost};
+            }
+        }
+    }
     my %loginhash;
     ($errors,%colchanges) = &modify_colors($r,$dom,$confname,['login'],
                                            \%domconfig,\%loginhash);
@@ -2658,6 +3227,26 @@ sub modify_login {
         $colchgtext = &display_colorchgs($dom,\%colchanges,['login'],
                                          \%loginhash);
     }
+
+    my %servers = &dom_servers($dom);
+    if (keys(%servers) > 1) {
+        foreach my $lonhost (keys(%servers)) {
+            next if ($env{'form.'.$lonhost.'_serverurl'} eq $lonhost);
+            if ($env{'form.'.$lonhost.'_serverurl'} eq $curr_loginvia{$lonhost}) {
+                $loginhash{login}{loginvia}{$lonhost} = $curr_loginvia{$lonhost};                next;
+            }
+            if ($curr_loginvia{$lonhost} ne '') {
+                $loginhash{login}{loginvia}{$lonhost} = $env{'form.'.$lonhost.'_serverurl'};
+                $changes{'loginvia'}{$lonhost} = 1;
+            } else {
+                if (defined($servers{$env{'form.'.$lonhost.'_serverurl'}})) {
+                    $loginhash{login}{loginvia}{$lonhost} = $env{'form.'.$lonhost.'_serverurl'};
+                    $changes{'loginvia'}{$lonhost} = 1;
+                }
+            }
+        }
+    }
+
     my $putresult = &Apache::lonnet::put_dom('configuration',\%loginhash,
                                              $dom);
     if ($putresult eq 'ok') {
@@ -2704,6 +3293,18 @@ sub modify_login {
             foreach my $item (sort(keys(%changes))) {
                 if ($item eq 'loginheader') {
                     $resulttext .= '<li>'.&mt("$title{$item} set to $env{'form.loginheader'}").'</li>';
+                } elsif ($item eq 'loginvia') {
+                    if (ref($changes{$item}) eq 'HASH') {
+                        $resulttext .= '<li>'.&mt('Log-in page availability:').'<ul>';
+                        foreach my $lonhost (sort(keys(%{$changes{$item}}))) {
+                            if ($servers{$env{'form.'.$lonhost.'_serverurl'}} ne '') {
+                                $resulttext .= '<li>'.&mt('Server: [_1] log-in page now redirects to [_2]',$lonhost,$servers{$env{'form.'.$lonhost.'_serverurl'}}).'</li>';
+                            } else {
+                                $resulttext .= '<li>'.&mt('Server: [_1] now has standard log-in page.',$lonhost).'</li>';
+                            }
+                        }
+                        $resulttext .= '</ul></li>'; 
+                    }
                 } else {
                     $resulttext .= '<li>'.&mt("$title{$item} set to $offon[$env{'form.'.$item}]").'</li>';
                 }
@@ -2789,6 +3390,7 @@ sub modify_colors {
             @logintext = ('textcol','bgcol');
         } else {
             %choices = &color_font_choices();
+            $confhash->{$role}{'fontmenu'} = $env{'form.'.$role.'_fontmenu'};
         }
         if ($role eq 'login') {
             @images = ('img','logo','domlogo','login');
@@ -2798,7 +3400,6 @@ sub modify_colors {
             @bgs = ('pgbg','tabbg','sidebg'); 
         }
         $confhash->{$role}{'font'} = $env{'form.'.$role.'_font'};
-	$confhash->{$role}{'fontmenu'} = $env{'form.'.$role.'_fontmenu'};
         foreach my $item (@bgs,@links,@logintext) {
             $confhash->{$role}{$item} = $env{'form.'.$role.'_'.$item};
         }
@@ -2912,13 +3513,15 @@ sub modify_colors {
                         $changes{$role}{'font'} = 1;
                     }
                 }
-                if ($domconfig->{$role}{'fontmenu'} ne '') {
-                    if ($confhash->{$role}{'fontmenu'} ne $domconfig->{$role}{'fontmenu'}) {
-                        $changes{$role}{'fontmenu'} = 1;
-                    }
-                } else {
-                    if ($confhash->{$role}{'fontmenu'}) {
-                        $changes{$role}{'fontmenu'} = 1;
+                if ($role ne 'login') {
+                    if ($domconfig->{$role}{'fontmenu'} ne '') {
+                        if ($confhash->{$role}{'fontmenu'} ne $domconfig->{$role}{'fontmenu'}) {
+                            $changes{$role}{'fontmenu'} = 1;
+                        }
+                    } else {
+                        if ($confhash->{$role}{'fontmenu'}) {
+                            $changes{$role}{'fontmenu'} = 1;
+                        }
                     }
                 }
                 foreach my $item (@bgs) {
@@ -3352,7 +3955,8 @@ sub check_switchserver {
 
 sub modify_quotas {
     my ($dom,$action,%domconfig) = @_;
-    my ($context,@usertools);
+    my ($context,@usertools,@options,%validations,%titles,%confhash,%toolshash,
+        %limithash,$toolregexp,%conditions,$resulttext,%changes);
     if ($action eq 'quotas') {
         $context = 'tools'; 
     } else { 
@@ -3360,33 +3964,79 @@ sub modify_quotas {
     }
     if ($context eq 'requestcourses') {
         @usertools = ('official','unofficial','community');
+        @options =('norequest','approval','validate','autolimit');
+        %validations = &Apache::lonnet::auto_courserequest_checks($dom);
+        %titles = &courserequest_titles();
+        $toolregexp = join('|',@usertools);
+        %conditions = &courserequest_conditions();
     } else {
         @usertools = ('aboutme','blog','portfolio');
+        %titles = &tool_titles();
     }
     my %domdefaults = &Apache::lonnet::get_domain_defaults($dom);
-    my ($resulttext,%changes);
     my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom);
-    my %titles = &tool_titles();
-    my (%confhash,%toolshash);
     foreach my $key (keys(%env)) {
-        unless ($context eq 'requestcourses') {
+        if ($context eq 'requestcourses') {
+            if ($key =~ /^form\.crsreq_($toolregexp)_(.+)$/) {
+                my $item = $1;
+                my $type = $2;
+                if ($type =~ /^limit_(.+)/) {
+                    $limithash{$item}{$1} = $env{$key};
+                } else {
+                    $confhash{$item}{$type} = $env{$key};
+                }
+            }
+        } else {
             if ($key =~ /^form\.quota_(.+)$/) {
                 $confhash{'defaultquota'}{$1} = $env{$key};
             }
-        }
-        if ($key =~ /^form\.\Q$context\E_(.+)$/) {
-            @{$toolshash{$1}} = &Apache::loncommon::get_env_multiple($key);
+            if ($key =~ /^form\.\Q$context\E_(.+)$/) {
+                @{$toolshash{$1}} = &Apache::loncommon::get_env_multiple($key);
+            }
         }
     }
-    unless ($context eq 'requestcourses') {
+    if ($context eq 'requestcourses') {
+        my @approvalnotify = &Apache::loncommon::get_env_multiple('form.reqapprovalnotify');
+        @approvalnotify = sort(@approvalnotify);
+        $confhash{'notify'}{'approval'} = join(',',@approvalnotify);
+        if (ref($domconfig{$action}) eq 'HASH') {
+            if (ref($domconfig{$action}{'notify'}) eq 'HASH') {
+                if ($domconfig{$action}{'notify'}{'approval'} ne $confhash{'notify'}{'approval'}) {
+                    $changes{'notify'}{'approval'} = 1;
+                }
+            } else {
+                if ($domconfig{$action}{'notify'}{'approval'}) {
+                    $changes{'notify'}{'approval'} = 1;
+                }
+            }
+        } else {
+            if ($domconfig{$action}{'notify'}{'approval'}) {
+                $changes{'notify'}{'approval'} = 1;
+            }
+        }
+    } else {
         $confhash{'defaultquota'}{'default'} = $env{'form.defaultquota'};
     }
     foreach my $item (@usertools) {
         foreach my $type (@{$types},'default','_LC_adv') {
-            if (grep(/^\Q$type\E$/,@{$toolshash{$item}})) {
-                $confhash{$item}{$type} = 1;
+            my $unset; 
+            if ($context eq 'requestcourses') {
+                $unset = '0';
+                if ($type eq '_LC_adv') {
+                    $unset = '';
+                }
+                if ($confhash{$item}{$type} eq 'autolimit') {
+                    $confhash{$item}{$type} .= '=';
+                    unless ($limithash{$item}{$type} =~ /\D/) {
+                        $confhash{$item}{$type} .= $limithash{$item}{$type};
+                    }
+                }
             } else {
-                $confhash{$item}{$type} = 0;
+                if (grep(/^\Q$type\E$/,@{$toolshash{$item}})) {
+                    $confhash{$item}{$type} = 1;
+                } else {
+                    $confhash{$item}{$type} = 0;
+                }
             }
             if (ref($domconfig{$action}) eq 'HASH') {
                 if (ref($domconfig{$action}{$item}) eq 'HASH') {
@@ -3395,7 +4045,7 @@ sub modify_quotas {
                     }
                 } else {
                     if ($context eq 'requestcourses') {
-                        if ($confhash{$item}{$type}) {
+                        if ($confhash{$item}{$type} ne $unset) {
                             $changes{$item}{$type} = 1;
                         }
                     } else {
@@ -3406,7 +4056,7 @@ sub modify_quotas {
                 }
             } else {
                 if ($context eq 'requestcourses') {
-                    if ($confhash{$item}{$type}) {
+                    if ($confhash{$item}{$type} ne $unset) {
                         $changes{$item}{$type} = 1;
                     }
                 } else {
@@ -3516,15 +4166,50 @@ sub modify_quotas {
                                 $typetitle = 'LON-CAPA Advanced Users'; 
                             }
                             if ($confhash{$item}{$type}) {
-                                $resulttext .= '<li>'.&mt('Set to be available to [_1]',$typetitle).'</li>';
+                                if ($context eq 'requestcourses') {
+                                    my $cond;
+                                    if ($confhash{$item}{$type} =~ /^autolimit=(\d*)$/) {
+                                        if ($1 eq '') {
+                                            $cond = &mt('(Automatic processing of any request).');
+                                        } else {
+                                            $cond = &mt('(Automatic processing of requests up to limit of [quant,_1,request] per user).',$1);
+                                        }
+                                    } else { 
+                                        $cond = $conditions{$confhash{$item}{$type}};
+                                    }
+                                    $resulttext .= '<li>'.&mt('Set to be available to [_1].',$typetitle).' '.$cond.'</li>';
+                                } else {
+                                    $resulttext .= '<li>'.&mt('Set to be available to [_1]',$typetitle).'</li>';
+                                }
                             } else {
-                                $resulttext .= '<li>'.&mt('Set to be unavailable to [_1]',$typetitle).'</li>';
+                                if ($type eq '_LC_adv') {
+                                    if ($confhash{$item}{$type} eq '0') {
+                                        $resulttext .= '<li>'.&mt('Set to be unavailable to [_1]',$typetitle).'</li>';
+                                    } else { 
+                                        $resulttext .= '<li>'.&mt('No override set for [_1]',$typetitle).'</li>';
+                                    }
+                                } else {
+                                    $resulttext .= '<li>'.&mt('Set to be unavailable to [_1]',$typetitle).'</li>';
+                                }
                             }
                         }
                     }
                     $resulttext .= '</ul></li>';
                 }
             }
+            if ($action eq 'requestcourses') {
+                if (ref($changes{'notify'}) eq 'HASH') {
+                    if ($changes{'notify'}{'approval'}) {
+                        if (ref($confhash{'notify'}) eq 'HASH') {
+                            if ($confhash{'notify'}{'approval'}) {
+                                $resulttext .= '<li>'.&mt('Notification of requests requiring approval will be sent to: ').$confhash{'notify'}{'approval'}.'</li>';
+                            } else {
+                                $resulttext .= '<li>'.&mt('No Domain Coordinators will receive notification of course requests requiring approval.').'</li>';
+                            }
+                        }
+                    }
+                }
+            }
             $resulttext .= '</ul>';
             if (keys(%newenv)) {
                 &Apache::lonnet::appenv(\%newenv);
@@ -3917,7 +4602,8 @@ sub modify_contacts {
     }
     my (%others,%to);
     my @contacts = ('supportemail','adminemail');
-    my @mailings = ('errormail','packagesmail','helpdeskmail','lonstatusmail');
+    my @mailings = ('errormail','packagesmail','helpdeskmail','lonstatusmail',
+                    'requestsmail');
     foreach my $type (@mailings) {
         @{$newsetting{$type}} = 
             &Apache::loncommon::get_env_multiple('form.'.$type);
@@ -3963,6 +4649,7 @@ sub modify_contacts {
         $default{'packagesmail'} = 'adminemail';
         $default{'helpdeskmail'} = 'supportemail';
         $default{'lonstatusmail'} = 'adminemail';
+        $default{'requestsmail'} = 'adminemail';
         foreach my $item (@contacts) {
            if ($to{$item} ne $default{$item}) {
               $changes{$item} = 1;
@@ -4051,6 +4738,8 @@ sub modify_usercreation {
         if (@{$types} > 0) {
             @{$cancreate{'statustocreate'}} = 
                 &Apache::loncommon::get_env_multiple('form.statustocreate');
+        } else {
+            @{$cancreate{'statustocreate'}} = ();
         }
         push(@contexts,'statustocreate');
     }
@@ -4059,9 +4748,11 @@ sub modify_usercreation {
             if (($item eq 'selfcreate') || ($item eq 'statustocreate')) {
                 if (ref($curr_usercreation{'cancreate'}{$item}) eq 'ARRAY') {
                     foreach my $curr (@{$curr_usercreation{'cancreate'}{$item}}) {
-                        if (!grep(/^$curr$/,@{$cancreate{$item}})) {
-                            if (!grep(/^$item$/,@{$changes{'cancreate'}})) {
-                                push(@{$changes{'cancreate'}},$item);
+                        if (ref($cancreate{$item}) eq 'ARRAY') {
+                            if (!grep(/^$curr$/,@{$cancreate{$item}})) {
+                                if (!grep(/^$item$/,@{$changes{'cancreate'}})) {
+                                    push(@{$changes{'cancreate'}},$item);
+                                }
                             }
                         }
                     }
@@ -4530,8 +5221,10 @@ sub modify_defaults {
             if ($newvalues{$item} ne '') {
                 if ($newvalues{$item} =~ /^(\w+)/) {
                     my $langcode = $1;
-                    if (code2language($langcode) eq '') {
-                        push(@errors,$item);
+                    if ($langcode ne 'x_chef') {
+                        if (code2language($langcode) eq '') {
+                            push(@errors,$item);
+                        }
                     }
                 } else {
                     push(@errors,$item);
@@ -4999,6 +5692,72 @@ sub modify_serverstatuses {
     return $resulttext;
 }
 
+sub modify_helpsettings {
+    my ($dom,%domconfig) = @_;
+ 	my ($resulttext,$errors,%changes,%helphash);
+ 	
+ 	my %defaultchecked = ('submitbugs'	=> 'on');
+ 	my @offon = ('off','on');
+    my %title = ( submitbugs => 'Display link for users to submit a bug');
+    my @toggles = ('submitbugs');
+
+    $helphash{'helpsettings'} = {};
+    
+    if (ref($domconfig{'helpsettings'}) ne 'HASH') {
+        if ($domconfig{'helpsettings'} eq '') {
+            $domconfig{'helpsettings'} = {};
+        }
+    }
+    
+    if (ref($domconfig{'helpsettings'}) eq 'HASH') {
+    	
+        foreach my $item (@toggles) {
+        	
+			if ($defaultchecked{$item} eq 'on') { 
+				if (($domconfig{'helpsettings'}{$item} eq '') &&
+					 ($env{'form.'.$item} eq '0')) {
+					$changes{$item} = 1;
+				} elsif ($domconfig{'helpsettings'}{$item} ne $env{'form.'.$item}) {
+					$changes{$item} = 1;
+				}
+			} elsif ($defaultchecked{$item} eq 'off') {
+				if (($domconfig{'helpsettings'}{$item} eq '') &&
+					 ($env{'form.'.$item} eq '1')) {
+					$changes{$item} = 1;
+				} elsif ($domconfig{'helpsettings'}{$item} ne $env{'form.'.$item}) {
+					$changes{$item} = 1;
+				}
+			}
+			$helphash{'helpsettings'}{$item} = $env{'form.'.$item};
+		}  
+    }
+    
+    my $putresult = &Apache::lonnet::put_dom('configuration',\%helphash,
+                                             $dom);
+                                             
+    if ($putresult eq 'ok') {
+        if (keys(%changes) > 0) {
+			$resulttext = &mt('Changes made:').'<ul>';
+			foreach my $item (sort(keys(%changes))) {
+				if ($item eq 'submitbugs') {
+					$resulttext .= '<li>'.&mt("$title{$item} set to $offon[$env{'form.'.$item}]").'</li>';
+				}
+			}
+			$resulttext .= '</ul>';
+		} else {
+			$resulttext = &mt('No changes made to help settings');
+		}
+    } else {
+        $resulttext = '<span class="LC_error">'.
+	    &mt('An error occurred: [_1]',$putresult).'</span>';
+    }
+    if ($errors) {
+        $resulttext .= &mt('The following errors occurred: ').'<ul>'.
+                       $errors.'</ul>';
+    }
+    return $resulttext;
+}
+
 sub recurse_check {
     my ($chkcats,$categories,$depth,$name) = @_;
     if (ref($chkcats->[$depth]{$name}) eq 'ARRAY') {
@@ -5039,4 +5798,37 @@ sub recurse_cat_deletes {
     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;
+}
+
 1;