Diff for /loncom/interface/domainprefs.pm between versions 1.201 and 1.224

version 1.201, 2013/08/07 14:41:39 version 1.224, 2014/02/12 20:37:42
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 (quotas,    number of rows displayed on the page, and $action is the context (quotas, 
 requestcourses or requestauthor).  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
Line 95  institutional affiliation in the domain Line 95  institutional affiliation in the domain
 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, and to display/store  used by course owners to request creation of a course, and to display/store
 default quota sizes for authoring spaces.  default quota sizes for Authoring Spaces.
   
 Outputs: 1  Outputs: 1
   
Line 103  $datatable  - HTML containing form eleme Line 103  $datatable  - HTML containing form eleme
   
 In the case of course requests, radio buttons are displayed for each institutional  In the case of course requests, radio buttons are displayed for each institutional
 affiliate type (and also default, and _LC_adv) for each of the course types   affiliate type (and also default, and _LC_adv) for each of the course types 
 (official, unofficial and community).  In each case the radio buttons allow the   (official, unofficial, community, and textbook).  In each case the radio buttons 
 selection of one of four values:  allow the selection of one of four values:
   
 0, approval, validate, autolimit=N (where N is blank, or a positive integer).  0, approval, validate, autolimit=N (where N is blank, or a positive integer).
 which have the following effects:  which have the following effects:
Line 216  sub handler { Line 216  sub handler {
                 'requestauthor'],$dom);                  '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','selfcreation','usermodification','scantron',
                        'requestcourses','requestauthor','coursecategories',                         'requestcourses','requestauthor','coursecategories',
                        'serverstatuses','helpsettings',                         'serverstatuses','helpsettings',
                        'coursedefaults','usersessions');                         'coursedefaults','usersessions');
Line 259  sub handler { Line 259  sub handler {
                       help => 'Domain_Configuration_Quotas',                        help => 'Domain_Configuration_Quotas',
                       header => [{col1 => 'User affiliation',                        header => [{col1 => 'User affiliation',
                                   col2 => 'Available tools',                                    col2 => 'Available tools',
                                   col3 => 'Quotas, Mb; (Authoring requires role)',}],                                    col3 => 'Quotas, MB; (Authoring requires role)',}],
                     },                      },
         'autoenroll' =>          'autoenroll' =>
                    { text => 'Auto-enrollment settings',                     { text => 'Auto-enrollment settings',
Line 295  sub handler { Line 295  sub handler {
                     header => [{col1 => 'Setting',                      header => [{col1 => 'Setting',
                                 col2 => 'Value',}],                                  col2 => 'Value',}],
                   },                    },
   
         'usercreation' =>           'usercreation' => 
                   { text => 'User creation',                    { text => 'User creation',
                     help => 'Domain_Configuration_User_Creation',                      help => 'Domain_Configuration_User_Creation',
Line 306  sub handler { Line 305  sub handler {
                                {col1 => 'Context',                                 {col1 => 'Context',
                                 col2 => 'Assignable authentication types'}],                                  col2 => 'Assignable authentication types'}],
                   },                    },
           'selfcreation' => 
                     { text => 'Users self-creating accounts',
                       help => 'Domain_Configuration_Self_Creation', 
                       header => [{col1 => 'Self-creation with institutional username',
                                   col2 => 'Enabled?'},
                                  {col1 => 'Institutional user type (login/SSO self-creation)',
                                   col2 => 'Information user can enter'},
                                  {col1 => 'Self-creation with e-mail as username',
                                   col2 => 'Settings'}],
                     },
         'usermodification' =>          'usermodification' =>
                   { text => 'User modification',                    { text => 'User modification',
                     help => 'Domain_Configuration_User_Modification',                      help => 'Domain_Configuration_User_Modification',
                     header => [{col1 => 'Target user has role',                      header => [{col1 => 'Target user has role',
                                 col2 => 'User information updateable in author context'},                                  col2 => 'User information updateable in author context'},
                                {col1 => 'Target user has role',                                 {col1 => 'Target user has role',
                                 col2 => 'User information updateable in course context'},                                  col2 => 'User information updateable in course context'}],
                                {col1 => "Status of user",  
                                 col2 => 'Information settable when self-creating account (if directory data blank)'}],  
                   },                    },
         'scantron' =>          'scantron' =>
                   { text => 'Bubblesheet format file',                    { text => 'Bubblesheet format file',
Line 329  sub handler { Line 336  sub handler {
                   header => [{col1 => 'User affiliation',                    header => [{col1 => 'User affiliation',
                               col2 => 'Availability/Processing of requests',},                                col2 => 'Availability/Processing of requests',},
                              {col1 => 'Setting',                               {col1 => 'Setting',
                               col2 => 'Value'}],                                col2 => 'Value'},
                                {col1 => 'Available textbooks',
                                 col2 => ''}],
                  },                   },
         'requestauthor' =>          'requestauthor' =>
                  {text => 'Request authoring space',                   {text => 'Request Authoring Space',
                   help => 'Domain_Configuration_Request_Author',                    help => 'Domain_Configuration_Request_Author',
                   header => [{col1 => 'User affiliation',                    header => [{col1 => 'User affiliation',
                               col2 => 'Availability/Processing of requests',},                                col2 => 'Availability/Processing of requests',},
Line 416  sub handler { Line 425  sub handler {
     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') && (keys(%{$result}))) {
               $r->rflush();
               &devalidate_remote_domconfs($dom,$result);
           }
     } elsif ($phase eq 'display') {      } elsif ($phase eq 'display') {
         my $js = &recaptcha_js().          my $js = &recaptcha_js().
                  &credits_js();                   &credits_js();
Line 429  sub handler { Line 443  sub handler {
                    &common_domprefs_js().                     &common_domprefs_js().
                    &Apache::loncommon::javascript_array_indexof();                     &Apache::loncommon::javascript_array_indexof();
         }          }
           if (grep(/^requestcourses$/,@actions)) {
               my $javascript_validations;
               my $coursebrowserjs=&Apache::loncommon::coursebrowser_javascript($env{'request.role.domain'}); 
               $js .= <<END;
   <script type="text/javascript">
   $javascript_validations
   </script>
   $coursebrowserjs
   END
           }
         &Apache::lonconfigsettings::display_settings($r,$dom,$phase,$context,\@prefs_order,\%prefs,\%domconfig,$confname,$js);          &Apache::lonconfigsettings::display_settings($r,$dom,$phase,$context,\@prefs_order,\%prefs,\%domconfig,$confname,$js);
     } else {      } else {
 # check if domconfig user exists for the domain.  # check if domconfig user exists for the domain.
Line 438  sub handler { Line 462  sub handler {
         unless ($configuserok eq 'ok') {          unless ($configuserok eq 'ok') {
             &Apache::lonconfigsettings::print_header($r,$phase,$context);              &Apache::lonconfigsettings::print_header($r,$phase,$context);
             $r->print(&mt('The domain configuration user "[_1]" has yet to be created.',              $r->print(&mt('The domain configuration user "[_1]" has yet to be created.',
                            $confname).                            $confname).
                       '<br />'                        '<br />'
             );              );
             if ($switchserver) {              if ($switchserver) {
Line 498  sub handler { Line 522  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($r,$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 521  sub process_changes { Line 545  sub process_changes {
         $output = &modify_directorysrch($dom,%domconfig);          $output = &modify_directorysrch($dom,%domconfig);
     } elsif ($action eq 'usercreation') {      } elsif ($action eq 'usercreation') {
         $output = &modify_usercreation($dom,%domconfig);          $output = &modify_usercreation($dom,%domconfig);
       } elsif ($action eq 'selfcreation') {
           $output = &modify_selfcreation($dom,%domconfig);
     } elsif ($action eq 'usermodification') {      } elsif ($action eq 'usermodification') {
         $output = &modify_usermodification($dom,%domconfig);          $output = &modify_usermodification($dom,%domconfig);
     } elsif ($action eq 'contacts') {      } elsif ($action eq 'contacts') {
         $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($r,$dom,$action,$lastactref,%domconfig);
     } elsif ($action eq 'requestauthor') {      } elsif ($action eq 'requestauthor') {
         $output = &modify_quotas($dom,$action,%domconfig);          $output = &modify_quotas($r,$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') {      } elsif ($action eq 'usersessions') {
         $output = &modify_usersessions($dom,%domconfig);          $output = &modify_usersessions($dom,$lastactref,%domconfig);
     } elsif ($action eq 'loadbalancing') {      } elsif ($action eq 'loadbalancing') {
         $output = &modify_loadbalancing($dom,%domconfig);          $output = &modify_loadbalancing($dom,%domconfig);
     }      }
Line 571  sub print_config_box { Line 597  sub print_config_box {
     if ($numheaders > 1) {      if ($numheaders > 1) {
         my $colspan = '';          my $colspan = '';
         my $rightcolspan = '';          my $rightcolspan = '';
         if (($action eq 'rolecolors') || ($action eq 'coursecategories') ||           if (($action eq 'rolecolors') || ($action eq 'coursecategories') ||
             (($action eq 'login') && ($numheaders < 3))) {              (($action eq 'login') && ($numheaders < 3))) {
             $colspan = ' colspan="2"';              $colspan = ' colspan="2"';
         }          }
Line 591  sub print_config_box { Line 617  sub print_config_box {
             $output .= &print_autoupdate('top',$dom,$settings,\$rowtotal);              $output .= &print_autoupdate('top',$dom,$settings,\$rowtotal);
         } elsif ($action eq 'usercreation') {          } elsif ($action eq 'usercreation') {
             $output .= &print_usercreation('top',$dom,$settings,\$rowtotal);              $output .= &print_usercreation('top',$dom,$settings,\$rowtotal);
           } elsif ($action eq 'selfcreation') {
               $output .= &print_selfcreation('top',$dom,$settings,\$rowtotal);
         } elsif ($action eq 'usermodification') {          } elsif ($action eq 'usermodification') {
             $output .= &print_usermodification('top',$dom,$settings,\$rowtotal);              $output .= &print_usermodification('top',$dom,$settings,\$rowtotal);
         } elsif ($action eq 'coursecategories') {          } elsif ($action eq 'coursecategories') {
Line 652  sub print_config_box { Line 680  sub print_config_box {
               <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_usercreation('bottom',$dom,$settings,\$rowtotal);              &print_usercreation('bottom',$dom,$settings,\$rowtotal);
             $rowtotal ++;              $rowtotal ++;
         } elsif ($action eq 'usermodification') {          } elsif ($action eq 'selfcreation') {
             $output .= &print_usermodification('middle',$dom,$settings,\$rowtotal).'              $output .= &print_selfcreation('middle',$dom,$settings,\$rowtotal).'
            </table>             </table>
           </td>            </td>
          </tr>           </tr>
Line 662  sub print_config_box { Line 690  sub print_config_box {
             <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'}->[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>
                        &print_usermodification('bottom',$dom,$settings,\$rowtotal);               </tr>'.
               &print_selfcreation('bottom',$dom,$settings,\$rowtotal);
             $rowtotal ++;              $rowtotal ++;
           } elsif ($action eq 'usermodification') {
               $output .= &print_usermodification('middle',$dom,$settings,\$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') {
Line 678  sub print_config_box { Line 709  sub print_config_box {
             <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'}->[2]->{'col1'}).'</td>                <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>'.                <td class="LC_right_item"'.$colspan.'>'.&mt($item->{'header'}->[2]->{'col2'}).'</td></tr>'.
                        &print_login('help',$dom,$confname,$phase,$settings,\$rowtotal);                         &print_login('help',$dom,$confname,$phase,$settings,\$rowtotal);
                 $rowtotal ++;                  $rowtotal ++;
             } else {              } else {
                 $output .= &print_login('help',$dom,$confname,$phase,$settings,\$rowtotal);                  $output .= &print_login('help',$dom,$confname,$phase,$settings,\$rowtotal);
             }              }
         } elsif ($action eq 'requestcourses') {          } elsif ($action eq 'requestcourses') {
             $output .= &print_requestmail($dom,$action,$settings,\$rowtotal);              $output .= &print_requestmail($dom,$action,$settings,\$rowtotal).
                          &print_studentcode($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_textbookcourses($dom,$settings,\$rowtotal);
         } elsif ($action eq 'requestauthor') {          } elsif ($action eq 'requestauthor') {
             $output .= &print_requestmail($dom,$action,$settings,\$rowtotal);              $output .= &print_requestmail($dom,$action,$settings,\$rowtotal);
         } elsif ($action eq 'usersessions') {          } elsif ($action eq 'usersessions') {
Line 790  sub print_config_box { Line 832  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') {
Line 1205  sub print_rolecolors { Line 1247  sub print_rolecolors {
   
 sub role_defaults {  sub role_defaults {
     my ($role,$bgs,$links,$images,$logintext) = @_;      my ($role,$bgs,$links,$images,$logintext) = @_;
     my %defaults;       my %defaults;
     unless ((ref($bgs) eq 'ARRAY') && (ref($links) eq 'ARRAY') && (ref($images) eq 'ARRAY')) {       unless ((ref($bgs) eq 'ARRAY') && (ref($links) eq 'ARRAY') && (ref($images) eq 'ARRAY')) {
         return %defaults;          return %defaults;
     }      }
     my %defaultdesign = %Apache::loncommon::defaultdesign;      my %defaultdesign = %Apache::loncommon::defaultdesign;
Line 1257  sub display_color_options { Line 1299  sub display_color_options {
   
     $datatable .= '<td><span class="LC_nobreak">'.      $datatable .= '<td><span class="LC_nobreak">'.
                   '<input type="text" class="colorchooser" size="10" name="'.$role.'_font"'.                    '<input type="text" class="colorchooser" size="10" name="'.$role.'_font"'.
                   ' value="'.$current_color.'" />&nbsp;'.                     ' value="'.$current_color.'" />&nbsp;'.
                   '&nbsp;</td></tr>';                    '&nbsp;</td></tr>';
     unless ($role eq 'login') {       unless ($role eq 'login') { 
         $datatable .= '<tr'.$css_class.'>'.          $datatable .= '<tr'.$css_class.'>'.
Line 1267  sub display_color_options { Line 1309  sub display_color_options {
         } else {          } else {
             $datatable .= '<td>&nbsp;</td>';              $datatable .= '<td>&nbsp;</td>';
         }          }
  $current_color = $designs->{'fontmenu'} ?    $current_color = $designs->{'fontmenu'} ?
     $designs->{'fontmenu'} : $defaults->{'fontmenu'};      $designs->{'fontmenu'} : $defaults->{'fontmenu'};
         $datatable .= '<td><span class="LC_nobreak">'.          $datatable .= '<td><span class="LC_nobreak">'.
                       '<input class="colorchooser" type="text" size="10" name="'                        '<input class="colorchooser" type="text" size="10" name="'
Line 1431  sub display_color_options { Line 1473  sub display_color_options {
     foreach my $item (@{$links}) {      foreach my $item (@{$links}) {
  my $color = $designs->{'link'}{$item} ? $designs->{'link'}{$item} : $defaults->{'links'}{$item};   my $color = $designs->{'link'}{$item} ? $designs->{'link'}{$item} : $defaults->{'links'}{$item};
         $datatable .= '<td align="center">'.$choices->{$item}."\n";          $datatable .= '<td align="center">'.$choices->{$item}."\n";
   
         if ($designs->{'links'}{$item}) {          if ($designs->{'links'}{$item}) {
             $datatable.='&nbsp;';              $datatable.='&nbsp;';
         }          }
Line 1496  sub login_text_colors { Line 1537  sub login_text_colors {
         my $color = $designs->{'logintext'}{$item} ? $designs->{'logintext'}{$item} : $defaults->{'logintext'}{$item};          my $color = $designs->{'logintext'}{$item} ? $designs->{'logintext'}{$item} : $defaults->{'logintext'}{$item};
         $color_menu .= '<br /><input type="text" class="colorchooser" size="8" name="'.$role.'_'.$item.'" value="'.$color.          $color_menu .= '<br /><input type="text" class="colorchooser" size="8" name="'.$role.'_'.$item.'" value="'.$color.
                       '" onblur = "javascript:colchg_span('."'css_".$role.'_'.$item."'".',this);" /></td>';                        '" onblur = "javascript:colchg_span('."'css_".$role.'_'.$item."'".',this);" /></td>';
   
     }      }
     $color_menu .= '</tr></table><br />';      $color_menu .= '</tr></table><br />';
     return $color_menu;      return $color_menu;
Line 1547  sub print_quotas { Line 1587  sub print_quotas {
     my $typecount = 0;      my $typecount = 0;
     my ($css_class,%titles);      my ($css_class,%titles);
     if ($context eq 'requestcourses') {      if ($context eq 'requestcourses') {
         @usertools = ('official','unofficial','community');          @usertools = ('official','unofficial','community','textbook');
         @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') {      } elsif ($context eq 'requestauthor') {
         @usertools = ('author');          @usertools = ('author');
         @options = ('norequest','approval','automatic');          @options = ('norequest','approval','automatic');
         %titles = &authorrequest_titles();           %titles = &authorrequest_titles();
     } else {      } else {
         @usertools = ('aboutme','blog','webdav','portfolio');          @usertools = ('aboutme','blog','webdav','portfolio');
         %titles = &tool_titles();          %titles = &tool_titles();
Line 1961  sub print_quotas { Line 2001  sub print_quotas {
   
 sub print_requestmail {  sub print_requestmail {
     my ($dom,$action,$settings,$rowtotal) = @_;      my ($dom,$action,$settings,$rowtotal) = @_;
     my ($now,$datatable,%currapp,$rows);      my ($now,$datatable,%currapp);
     $now = time;      $now = time;
     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 '') {
                map {$currapp{$_}=1;} split(/,/,$settings->{'notify'}{'approval'});                  map {$currapp{$_}=1;} split(/,/,$settings->{'notify'}{'approval'});
             }              }
         }          }
     }      }
     my $numinrow = 2;      my $numinrow = 2;
     my $css_class = 'class="LC_odd_row"';      my $css_class;
       $css_class = ($$rowtotal%2? ' class="LC_odd_row"':'');
     my $text;      my $text;
     if ($action eq 'requestcourses') {      if ($action eq 'requestcourses') {
         $text = &mt('Receive notification of course requests requiring approval');          $text = &mt('Receive notification of course requests requiring approval');
       } elsif ($action eq 'requestauthor') {
           $text = &mt('Receive notification of Authoring Space requests requiring approval');
     } else {      } else {
         $text = &mt('Receive notification of authoring space requests requiring approval')         $text = &mt('Receive notification of queued requests for self-created user accounts requiring approval');
     }      }
     $datatable = '<tr '.$css_class.'>'.      $datatable = '<tr'.$css_class.'>'.
                  ' <td>'.$text.'</td>'.                   ' <td>'.$text.'</td>'.
                  ' <td class="LC_left_item">';                   ' <td class="LC_left_item">';
     my ($numdc,$table,$rows) = &active_dc_picker($dom,$numinrow,'checkbox',      my ($numdc,$table,$rows) = &active_dc_picker($dom,$numinrow,'checkbox',
                                                  'reqapprovalnotify',%currapp);                                                   $action.'notifyapproval',%currapp);
     if ($numdc > 0) {      if ($numdc > 0) {
         $datatable .= $table;          $datatable .= $table;
     } else {      } else {
Line 1993  sub print_requestmail { Line 2036  sub print_requestmail {
     return $datatable;      return $datatable;
 }  }
   
   sub print_studentcode {
       my ($settings,$rowtotal) = @_;
       my $rownum = 0; 
       my ($output,%current);
       my @crstypes = ('official','unofficial','community','textbook');
       if (ref($settings->{'uniquecode'}) eq 'HASH') {
           foreach my $type (@crstypes) {
               $current{$type} = $settings->{'uniquecode'}{$type};
           }
       }
       $output .= '<tr>'.
                  '<td class="LC_left_item">'.&mt('Generate unique six character code as course identifier?').'</td>'.
                  '<td class="LC_left_item">';
       foreach my $type (@crstypes) {
           my $check = ' ';
           if ($current{$type}) {
               $check = ' checked="checked" ';
           }
           $output .= '<span class="LC_nobreak"><label>'.
                      '<input type="checkbox" name="uniquecode" value="'.$type.'"'.$check.'/>'.
                      &mt($type).'</label></span>'.('&nbsp;'x2).' ';
       }
       $output .= '</td></tr>';
       $$rowtotal ++;
       return $output;
   }
   
   sub print_textbookcourses {
       my ($dom,$settings,$rowtotal) = @_;
       my $rownum = 0;
       my $css_class;
       my $itemcount = 1;
       my $maxnum = 0;
       my $bookshash;
       if (ref($settings) eq 'HASH') {
           $bookshash = $settings->{'textbooks'};
       }
       my %ordered;
       if (ref($bookshash) eq 'HASH') {
           foreach my $item (keys(%{$bookshash})) {
               if (ref($bookshash->{$item}) eq 'HASH') {
                   my $num = $bookshash->{$item}{'order'};
                   $ordered{$num} = $item;
               }
           }
       }
       my $confname = $dom.'-domainconfig';
       my $switchserver = &check_switchserver($dom,$confname);
       my $maxnum = scalar(keys(%ordered));
       my $datatable = &textbookcourses_javascript(\%ordered);
       if (keys(%ordered)) {
           my @items = sort { $a <=> $b } keys(%ordered);
           for (my $i=0; $i<@items; $i++) {
               $css_class = $itemcount%2?' class="LC_odd_row"':'';
               my $key = $ordered{$items[$i]};
               my %coursehash=&Apache::lonnet::coursedescription($key);
               my $coursetitle = $coursehash{'description'};
               my ($subject,$title,$author,$image,$imgsrc,$cdom,$cnum);
               if (ref($bookshash->{$key}) eq 'HASH') {
                   $subject = $bookshash->{$key}->{'subject'};
                   $title = $bookshash->{$key}->{'title'};
                   $author = $bookshash->{$key}->{'author'};
                   $image = $bookshash->{$key}->{'image'};
                   if ($image ne '') {
                       my ($path,$imagefile) = ($image =~ m{^(.+)/([^/]+)$});
                       my $imagethumb = "$path/tn-".$imagefile;
                       $imgsrc = '<img src="'.$imagethumb.'" alt="'.&mt('Textbook image').'" />';
                   }
               }
               my $chgstr = ' onchange="javascript:reorderBooks(this.form,'."'$key'".');"';
               $datatable .= '<tr '.$css_class.'><td><span class="LC_nobreak">'
                            .'<select name="'.$key.'"'.$chgstr.'>';
               for (my $k=0; $k<=$maxnum; $k++) {
                   my $vpos = $k+1;
                   my $selstr;
                   if ($k == $i) {
                       $selstr = ' selected="selected" ';
                   }
                   $datatable .= '<option value="'.$k.'"'.$selstr.'>'.$vpos.'</option>';
               }
               $datatable .= '</select>'.('&nbsp;'x2).
                   '<label><input type="checkbox" name="book_del" value="'.$key.'" />'.
                   &mt('Delete?').'</label></span></td>'.
                   '<td colspan="2">'.
                   '<span class="LC_nobreak">'.&mt('Subject:').'<input type="text" size="15" name="book_subject_'.$i.'" value="'.$subject.'" /></span> '.
                   ('&nbsp;'x2).
                   '<span class="LC_nobreak">'.&mt('Title:').'<input type="text" size="30" name="book_title_'.$i.'" value="'.$title.'" /></span> '.
                   ('&nbsp;'x2).
                   '<span class="LC_nobreak">'.&mt('Author(s):').'<input type="text" size="25" name="book_author_'.$i.'" value="'.$author.'" /></span> '.
                   ('&nbsp;'x2).
                   '<span class="LC_nobreak">'.&mt('Thumbnail:');
               if ($image) {
                   $datatable .= '<span class="LC_nobreak">'.
                                 $imgsrc.
                                 '<label><input type="checkbox" name="book_image_del"'.
                                 ' value="'.$key.'" />'.&mt('Delete?').'</label></span> '.
                                 '<span class="LC_nobreak">&nbsp;'.&mt('Replace:').'&nbsp;';
               }
               if ($switchserver) {
                   $datatable .= &mt('Upload to library server: [_1]',$switchserver);
               } else {
                   $datatable .= '<input type="file" name="book_image_'.$i.'" value="" />';
               }
               $datatable .= '<input type="hidden" name="book_id_'.$i.'" value="'.$key.'" /></span> '.
                             '<span class="LC_nobreak">'.&mt('LON-CAPA course:').'&nbsp;'.
                             $coursetitle.'</span></td></tr>'."\n";
               $itemcount ++;
           }
       }
       $css_class = $itemcount%2?' class="LC_odd_row"':'';
       my $chgstr = ' onchange="javascript:reorderBooks(this.form,'."'addbook_pos'".');"';
       $datatable .= '<tr '.$css_class.'><td><span class="LC_nobreak">'."\n".
                     '<input type="hidden" name="book_maxnum" value="'.$maxnum.'" />'."\n".
                     '<select name="addbook_pos"'.$chgstr.'>';
       for (my $k=0; $k<$maxnum+1; $k++) {
           my $vpos = $k+1;
           my $selstr;
           if ($k == $maxnum) {
               $selstr = ' selected="selected" ';
           }
           $datatable .= '<option value="'.$k.'"'.$selstr.'>'.$vpos.'</option>';
       }
       $datatable .= '</select>&nbsp;'."\n".
                     '<input type="checkbox" name="addbook" value="1" />'.&mt('Add').'</td>'."\n".
                     '<td colspan="2">'.
                     '<span class="LC_nobreak">'.&mt('Subject:').'<input type="text" size="15" name="addbook_subject" value="" /></span> '."\n".
                     ('&nbsp;'x2).
                     '<span class="LC_nobreak">'.&mt('Title:').'<input type="text" size="30" name="addbook_title" value="" /></span> '."\n".
                     ('&nbsp;'x2).
                     '<span class="LC_nobreak">'.&mt('Author(s):').'<input type="text" size="25" name="addbook_author" value="" /></span> '."\n".
                     ('&nbsp;'x2).
                     '<span class="LC_nobreak">'.&mt('Image:').'&nbsp;';
       if ($switchserver) {
           $datatable .= &mt('Upload to library server: [_1]',$switchserver);
       } else {
           $datatable .= '<input type="file" name="addbook_image" value="" />';
       }
       $datatable .= '</span>'."\n".
                     '<span class="LC_nobreak">'.&mt('LON-CAPA course:').'&nbsp;'.
                     &Apache::loncommon::select_dom_form($env{'request.role.domain'},'addbook_cdom').
                     '<input type="text" size="25" name="addbook_cnum" value="" />'.
                     &Apache::loncommon::selectcourse_link
                         ('display','addbook_cnum','addbook_cdom',undef,undef,undef,'Course');
                     '</span></td>'."\n".
                     '</tr>'."\n";
       $itemcount ++;
       return $datatable;
   }
   
   sub textbookcourses_javascript {
       my ($textbooks) = @_;
       return unless(ref($textbooks) eq 'HASH');
       my $num = scalar(keys(%{$textbooks}));
       my @jsarray;
       foreach my $item (sort {$a <=> $b } (keys(%{$textbooks}))) {
           push(@jsarray,$textbooks->{$item});
       }
       my $jstext = '    var textbooks = Array('."'".join("','",@jsarray)."'".');'."\n";
       return <<"ENDSCRIPT";
   <script type="text/javascript">
   // <![CDATA[
   function reorderBooks(form,item) {
       var changedVal;
   $jstext 
       var newpos = 'addbook_pos';
       var current = new Array;
       var maxh = 1 + $num;
       var current = new Array;
       var newitemVal = form.elements[newpos].options[form.elements[newpos].selectedIndex].value;
       if (item == newpos) {
           changedVal = newitemVal;
       } else {
           changedVal = form.elements[item].options[form.elements[item].selectedIndex].value;
           current[newitemVal] = newpos;
       }
       for (var i=0; i<textbooks.length; i++) {
           var elementName = textbooks[i];
           if (elementName != item) {
               if (form.elements[elementName]) {
                   var currVal = form.elements[elementName].options[form.elements[elementName].selectedIndex].value;
                   current[currVal] = elementName;
               }
           }
       }
       var oldVal;
       for (var j=0; j<maxh; j++) {
           if (current[j] == undefined) {
               oldVal = j;
           }
       }
       if (oldVal < changedVal) {
           for (var k=oldVal+1; k<=changedVal ; k++) {
              var elementName = current[k];
              form.elements[elementName].selectedIndex = form.elements[elementName].selectedIndex - 1;
           }
       } else {
           for (var k=changedVal; k<oldVal; k++) {
               var elementName = current[k];
               form.elements[elementName].selectedIndex = form.elements[elementName].selectedIndex + 1;
           }
       }
       return;
   }
   
   // ]]>
   </script>
   
   ENDSCRIPT
   }
   
 sub print_autoenroll {  sub print_autoenroll {
     my ($dom,$settings,$rowtotal) = @_;      my ($dom,$settings,$rowtotal) = @_;
     my $autorun = &Apache::lonnet::auto_run(undef,$dom),      my $autorun = &Apache::lonnet::auto_run(undef,$dom),
Line 2154  sub print_autocreate { Line 2407  sub print_autocreate {
                 }                  }
             }              }
         }          }
         if ($settings->{'xmldc'} ne '') {           if ($settings->{'xmldc'} ne '') {
             $currhash{$settings->{'xmldc'}} = 1;              $currhash{$settings->{'xmldc'}} = 1;
         }          }
     } else {      } else {
Line 2311  sub print_contacts { Line 2564  sub print_contacts {
     my @contacts = ('adminemail','supportemail');      my @contacts = ('adminemail','supportemail');
     my (%checked,%to,%otheremails,%bccemails);      my (%checked,%to,%otheremails,%bccemails);
     my @mailings = ('errormail','packagesmail','lonstatusmail','helpdeskmail',      my @mailings = ('errormail','packagesmail','lonstatusmail','helpdeskmail',
                     'requestsmail','updatesmail');                      'requestsmail','updatesmail','idconflictsmail');
     foreach my $type (@mailings) {      foreach my $type (@mailings) {
         $otheremails{$type} = '';          $otheremails{$type} = '';
     }      }
Line 2348  sub print_contacts { Line 2601  sub print_contacts {
         $checked{'lonstatusmail'}{'adminemail'} = ' checked="checked" ';           $checked{'lonstatusmail'}{'adminemail'} = ' checked="checked" '; 
         $checked{'requestsmail'}{'adminemail'} = ' checked="checked" ';          $checked{'requestsmail'}{'adminemail'} = ' checked="checked" ';
         $checked{'updatesmail'}{'adminemail'} = ' checked="checked" ';          $checked{'updatesmail'}{'adminemail'} = ' checked="checked" ';
           $checked{'idconflictsmail'}{'adminemail'} = ' checked="checked" ';
     }      }
     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 2385  sub print_contacts { Line 2638  sub print_contacts {
                           'value="'.$bccemails{$type}.'"  />';                            'value="'.$bccemails{$type}.'"  />';
         }          }
         $datatable .= '</td></tr>'."\n";          $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;
 }  }
Line 2477  sub print_coursedefaults { Line 2744  sub print_coursedefaults {
                                                  \%choices,$itemcount);                                                   \%choices,$itemcount);
     } else {      } else {
         $css_class = $itemcount%2 ? ' class="LC_odd_row"' : '';          $css_class = $itemcount%2 ? ' class="LC_odd_row"' : '';
         my ($currdefresponder,$def_official_credits,$def_unofficial_credits,%curruploadquota);          my ($currdefresponder,$def_official_credits,$def_unofficial_credits,$def_textbook_credits,
               %curruploadquota);
         my $currusecredits = 0;          my $currusecredits = 0;
         my @types = ('official','unofficial','community');          my @types = ('official','unofficial','community','textbook');
         if (ref($settings) eq 'HASH') {          if (ref($settings) eq 'HASH') {
             $currdefresponder = $settings->{'anonsurvey_threshold'};              $currdefresponder = $settings->{'anonsurvey_threshold'};
             if (ref($settings->{'uploadquota'}) eq 'HASH') {              if (ref($settings->{'uploadquota'}) eq 'HASH') {
Line 2490  sub print_coursedefaults { Line 2758  sub print_coursedefaults {
             if (ref($settings->{'coursecredits'}) eq 'HASH') {              if (ref($settings->{'coursecredits'}) eq 'HASH') {
                 $def_official_credits = $settings->{'coursecredits'}->{'official'};                  $def_official_credits = $settings->{'coursecredits'}->{'official'};
                 $def_unofficial_credits = $settings->{'coursecredits'}->{'unofficial'};                  $def_unofficial_credits = $settings->{'coursecredits'}->{'unofficial'};
                 if (($def_official_credits ne '') || ($def_unofficial_credits ne '')) {                  $def_textbook_credits = $settings->{'coursecredits'}->{'textbook'};
                   if (($def_official_credits ne '') || ($def_unofficial_credits ne '') ||
                       ($def_textbook_credits ne '')) {
                     $currusecredits = 1;                      $currusecredits = 1;
                 }                  }
             }              }
Line 2526  sub print_coursedefaults { Line 2796  sub print_coursedefaults {
         $datatable .= '</tr></table></td></tr>'."\n";          $datatable .= '</tr></table></td></tr>'."\n";
         $itemcount += 2;          $itemcount += 2;
         my $onclick = 'toggleCredits(this.form);';          my $onclick = 'toggleCredits(this.form);';
         my $display = 'none';            my $display = 'none';
         if ($currusecredits) {          if ($currusecredits) {
             $display = 'block';              $display = 'block';
         }          }
Line 2540  sub print_coursedefaults { Line 2810  sub print_coursedefaults {
                          &mt('Default credits for unofficial courses [_1]',                           &mt('Default credits for unofficial courses [_1]',
                          '<input type="text" name="unofficial_credits" value="'.                           '<input type="text" name="unofficial_credits" value="'.
                          $def_unofficial_credits.'" size="3" />').                           $def_unofficial_credits.'" size="3" />').
                            '</span><br />'.
                            '<span class="LC_nobreak">'.
                            &mt('Default credits for textbook courses [_1]',
                            '<input type="text" name="textbook_credits" value="'.
                            $def_textbook_credits.'" size="3" />').
                          '</span></div>'."\n";                           '</span></div>'."\n";
         %defaultchecked = ('coursecredits' => 'off');          %defaultchecked = ('coursecredits' => 'off');
         @toggles = ('coursecredits');          @toggles = ('coursecredits');
Line 2981  sub print_loadbalancing { Line 3256  sub print_loadbalancing {
     }      }
     my ($othertitle,$usertypes,$types) =      my ($othertitle,$usertypes,$types) =
         &Apache::loncommon::sorted_inst_types($dom);          &Apache::loncommon::sorted_inst_types($dom);
     my $rownum = 6;      my $rownum = 8;
     if (ref($types) eq 'ARRAY') {      if (ref($types) eq 'ARRAY') {
         $rownum += scalar(@{$types});          $rownum += scalar(@{$types});
     }      }
Line 3012  sub print_loadbalancing { Line 3287  sub print_loadbalancing {
                       '<td rowspan="'.$rownum.'" valign="top">'.                        '<td rowspan="'.$rownum.'" valign="top">'.
                       '<p>';                        '<p>';
         if ($lonhost eq '') {          if ($lonhost eq '') {
             $datatable .= '<span class="LC_nobreak">';               $datatable .= '<span class="LC_nobreak">';
             if (keys(%currbalancer) > 0) {              if (keys(%currbalancer) > 0) {
                 $datatable .= &mt('Add balancer:');                  $datatable .= &mt('Add balancer:');
             } else {              } else {
Line 3028  sub print_loadbalancing { Line 3303  sub print_loadbalancing {
                 next if ($currbalancer{$server});                  next if ($currbalancer{$server});
                 $datatable .= '<option value="'.$server.'">'.$server.'</option>'."\n";                  $datatable .= '<option value="'.$server.'">'.$server.'</option>'."\n";
             }              }
             $datatable .=               $datatable .=
                 '</select>'."\n".                  '</select>'."\n".
                 '<input type="hidden" name="loadbalancing_prevlonhost_'.$balnum.'" id="loadbalancing_prevlonhost_'.$balnum.'" value="" />&nbsp;</span>'."\n";                  '<input type="hidden" name="loadbalancing_prevlonhost_'.$balnum.'" id="loadbalancing_prevlonhost_'.$balnum.'" value="" />&nbsp;</span>'."\n";
         } else {          } else {
Line 3067  sub print_loadbalancing { Line 3342  sub print_loadbalancing {
                 if (exists($currbalancer{$spares[$i]})) {                  if (exists($currbalancer{$spares[$i]})) {
                     $disabled = ' disabled="disabled"';                      $disabled = ' disabled="disabled"';
                 }                  }
                 $targettable .=                   $targettable .=
                     '<td><label><input type="checkbox" name="loadbalancing_target_'.$balnum.'_'.$sparetype.'"'.                      '<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.                      $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>';                      '</span></label></td>';
Line 3151  sub loadbalancing_rules { Line 3426  sub loadbalancing_rules {
         $css_class,$balnum,$islast) = @_;          $css_class,$balnum,$islast) = @_;
     my $output;      my $output;
     my $num = 0;      my $num = 0;
     my ($alltypes,$othertypes,$titles) =       my ($alltypes,$othertypes,$titles) =
         &loadbalancing_titles($dom,$intdom,$usertypes,$types);          &loadbalancing_titles($dom,$intdom,$usertypes,$types);
     if ((ref($alltypes) eq 'ARRAY') && (ref($titles) eq 'HASH'))  {      if ((ref($alltypes) eq 'ARRAY') && (ref($titles) eq 'HASH'))  {
         foreach my $type (@{$alltypes}) {          foreach my $type (@{$alltypes}) {
Line 3160  sub loadbalancing_rules { Line 3435  sub loadbalancing_rules {
             if (ref($currrules) eq 'HASH') {              if (ref($currrules) eq 'HASH') {
                 $current = $currrules->{$type};                  $current = $currrules->{$type};
             }              }
             if (($type eq '_LC_external') || ($type eq '_LC_internetdom')) {              if (($type eq '_LC_external') || ($type eq '_LC_internetdom') || ($type eq '_LC_ipchange')) {
                 if ($dom ne &Apache::lonnet::host_domain($lonhost)) {                  if ($dom ne &Apache::lonnet::host_domain($lonhost)) {
                     $current = '';                      $current = '';
                 }                  }
Line 3181  sub loadbalancing_titles { Line 3456  sub loadbalancing_titles {
            '_LC_author'      => &mt('Users from [_1] with author role',$dom),             '_LC_author'      => &mt('Users from [_1] with author role',$dom),
            '_LC_internetdom' => &mt('Users not from [_1], but from [_2]',$dom,$intdom),             '_LC_internetdom' => &mt('Users not from [_1], but from [_2]',$dom,$intdom),
            '_LC_external'    => &mt('Users not from [_1]',$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');      my @alltypes = ('_LC_adv','_LC_author','_LC_internetdom','_LC_external','_LC_ipchangesso','_LC_ipchange');
     if (ref($types) eq 'ARRAY') {      if (ref($types) eq 'ARRAY') {
         unshift(@alltypes,@{$types},'default');          unshift(@alltypes,@{$types},'default');
     }      }
Line 3207  sub loadbalancing_titles { Line 3484  sub loadbalancing_titles {
 sub loadbalance_rule_row {  sub loadbalance_rule_row {
     my ($type,$title,$current,$servers,$currbalancer,$lonhost,$dom,      my ($type,$title,$current,$servers,$currbalancer,$lonhost,$dom,
         $targets_div_style,$homedom_div_style,$css_class,$balnum,$num,$islast) = @_;          $targets_div_style,$homedom_div_style,$css_class,$balnum,$num,$islast) = @_;
     my @rulenames = ('default','homeserver');      my @rulenames;
     my %ruletitles = &offloadtype_text();      my %ruletitles = &offloadtype_text();
     if ($type eq '_LC_external') {      if (($type eq '_LC_ipchangesso') || ($type eq '_LC_ipchange')) {
         push(@rulenames,'externalbalancer');          @rulenames = ('balancer','offloadedto');
     } else {      } else {
         push(@rulenames,'specific');          @rulenames = ('default','homeserver');
           if ($type eq '_LC_external') {
               push(@rulenames,'externalbalancer');
           } else {
               push(@rulenames,'specific');
           }
           push(@rulenames,'none');
     }      }
     push(@rulenames,'none');  
     my $style = $targets_div_style;      my $style = $targets_div_style;
     if (($type eq '_LC_external') || ($type eq '_LC_internetdom')) {      if (($type eq '_LC_external') || ($type eq '_LC_internetdom') || ($type eq '_LC_ipchange')) {
         $style = $homedom_div_style;          $style = $homedom_div_style;
     }      }
     my $space;      my $space;
     if ($islast && $num == 1) {      if ($islast && $num == 1) {
         $space = '<div display="inline-block">&nbsp;</div>';          $space = '<div display="inline-block">&nbsp;</div>';
     }      }
     my $output =       my $output =
         '<tr class="'.$css_class.'" id="balanceruletr_'.$balnum.'_'.$num.'"><td valign="top">'.$space.          '<tr class="'.$css_class.'" id="balanceruletr_'.$balnum.'_'.$num.'"><td valign="top">'.$space.
         '<div id="balanceruletitle_'.$balnum.'_'.$type.'" style="'.$style.'">'.$title.'</div></td>'."\n".          '<div id="balanceruletitle_'.$balnum.'_'.$type.'" style="'.$style.'">'.$title.'</div></td>'."\n".
         '<td valaign="top">'.$space.          '<td valaign="top">'.$space.
Line 3243  sub loadbalance_rule_row { Line 3525  sub loadbalance_rule_row {
                 unless ($checked) {                  unless ($checked) {
                     $default = ' selected="selected"';                      $default = ' selected="selected"';
                 }                  }
                 $extra =                   $extra =
                     ':&nbsp;<select name="loadbalancing_singleserver_'.$balnum.'_'.$type.                      ':&nbsp;<select name="loadbalancing_singleserver_'.$balnum.'_'.$type.
                     '" id="loadbalancing_singleserver_'.$balnum.'_'.$type.                      '" id="loadbalancing_singleserver_'.$balnum.'_'.$type.
                     '" onchange="singleServerToggle('."'$balnum','$type'".')">'."\n".                      '" onchange="singleServerToggle('."'$balnum','$type'".')">'."\n".
Line 3281  sub offloadtype_text { Line 3563  sub offloadtype_text {
            'externalbalancer' => "Offloads to Load Balancer in user's domain",             'externalbalancer' => "Offloads to Load Balancer in user's domain",
            'specific'         => 'Offloads to specific server',             'specific'         => 'Offloads to specific server',
            'none'             => 'No offload',             'none'             => 'No offload',
              'balancer'         => 'Session hosted on Load Balancer, after re-authentication',
              'offloadedto'      => 'Session hosted on offload server, after re-authentication',
     );      );
     return %ruletitles;      return %ruletitles;
 }  }
Line 3303  sub contact_titles { Line 3587  sub contact_titles {
                    'lonstatusmail' => 'E-mail from nightly status check (warnings/errors)',                     'lonstatusmail' => 'E-mail from nightly status check (warnings/errors)',
                    'requestsmail' => 'E-mail from course requests requiring approval',                     'requestsmail' => 'E-mail from course requests requiring approval',
                    'updatesmail'  => 'E-mail from nightly check of LON-CAPA module integrity/updates',                     'updatesmail'  => 'E-mail from nightly check of LON-CAPA module integrity/updates',
                      'idconflictsmail' => 'E-mail from bi-nightly check for multiple users sharing same student/employee ID',
                  );                   );
     my %short_titles = &Apache::lonlocal::texthash (      my %short_titles = &Apache::lonlocal::texthash (
                            adminemail   => 'Admin E-mail address',                             adminemail   => 'Admin E-mail address',
Line 3320  sub tool_titles { Line 3605  sub tool_titles {
                      official   => 'Official courses (with institutional codes)',                       official   => 'Official courses (with institutional codes)',
                      unofficial => 'Unofficial courses',                       unofficial => 'Unofficial courses',
                      community  => 'Communities',                       community  => 'Communities',
                        textbook   => 'Textbook courses',
                  );                   );
     return %titles;      return %titles;
 }  }
Line 3329  sub courserequest_titles { Line 3615  sub courserequest_titles {
                                    official   => 'Official',                                     official   => 'Official',
                                    unofficial => 'Unofficial',                                     unofficial => 'Unofficial',
                                    community  => 'Communities',                                     community  => 'Communities',
                                      textbook   => 'Textbook',
                                    norequest  => 'Not allowed',                                     norequest  => 'Not allowed',
                                    approval   => 'Approval by Dom. Coord.',                                     approval   => 'Approval by Dom. Coord.',
                                    validate   => 'With validation',                                     validate   => 'With validation',
Line 3345  sub authorrequest_titles { Line 3632  sub authorrequest_titles {
                                    automatic  => 'Automatic approval',                                     automatic  => 'Automatic approval',
                  );                   );
     return %titles;      return %titles;
 }   }
   
 sub courserequest_conditions {  sub courserequest_conditions {
     my %conditions = &Apache::lonlocal::texthash (      my %conditions = &Apache::lonlocal::texthash (
Line 3381  sub print_usercreation { Line 3668  sub print_usercreation {
                 $rowcount ++;                  $rowcount ++;
             }              }
         }          }
         my ($emailrules,$emailruleorder) =   
             &Apache::lonnet::inst_userrules($dom,'email');  
         if (ref($emailrules) eq 'HASH') {  
             if (keys(%{$emailrules}) > 0) {  
                 $datatable .= &user_formats_row('email',$settings,$emailrules,  
                                                 $emailruleorder,$numinrow,$rowcount);  
                 $$rowtotal ++;  
                 $rowcount ++;  
             }  
         }  
         if ($rowcount == 0) {          if ($rowcount == 0) {
             $datatable .= '<tr><td colspan="2">'.&mt('No format rules have been defined for usernames or IDs in this domain.').'</td></tr>';                $datatable .= '<tr><td colspan="2">'.&mt('No format rules have been defined for usernames or IDs in this domain.').'</td></tr>';  
             $$rowtotal ++;              $$rowtotal ++;
             $rowcount ++;              $rowcount ++;
         }          }
     } elsif ($position eq 'middle') {      } elsif ($position eq 'middle') {
         my @creators = ('author','course','requestcrs','selfcreate');          my @creators = ('author','course','requestcrs');
         my ($rules,$ruleorder) =          my ($rules,$ruleorder) =
             &Apache::lonnet::inst_userrules($dom,'username');              &Apache::lonnet::inst_userrules($dom,'username');
         my %lt = &usercreation_types();          my %lt = &usercreation_types();
         my %checked;          my %checked;
         my @selfcreate;   
         if (ref($settings) eq 'HASH') {          if (ref($settings) eq 'HASH') {
             if (ref($settings->{'cancreate'}) eq 'HASH') {              if (ref($settings->{'cancreate'}) eq 'HASH') {
                 foreach my $item (@creators) {                  foreach my $item (@creators) {
                     $checked{$item} = $settings->{'cancreate'}{$item};                      $checked{$item} = $settings->{'cancreate'}{$item};
                 }                  }
                 if (ref($settings->{'cancreate'}{'selfcreate'}) eq 'ARRAY') {  
                     @selfcreate = @{$settings->{'cancreate'}{'selfcreate'}};  
                 } elsif ($settings->{'cancreate'}{'selfcreate'} ne '') {  
                     if ($settings->{'cancreate'}{'selfcreate'} eq 'any') {  
                         @selfcreate = ('email','login','sso');  
                     } elsif ($settings->{'cancreate'}{'selfcreate'} ne 'none') {  
                         @selfcreate = ($settings->{'cancreate'}{'selfcreate'});  
                     }  
                 }  
             } elsif (ref($settings->{'cancreate'}) eq 'ARRAY') {              } elsif (ref($settings->{'cancreate'}) eq 'ARRAY') {
                 foreach my $item (@creators) {                  foreach my $item (@creators) {
                     if (grep(/^\Q$item\E$/,@{$settings->{'cancreate'}})) {                      if (grep(/^\Q$item\E$/,@{$settings->{'cancreate'}})) {
Line 3428  sub print_usercreation { Line 3695  sub print_usercreation {
         my $rownum = 0;          my $rownum = 0;
         foreach my $item (@creators) {          foreach my $item (@creators) {
             $rownum ++;              $rownum ++;
             if ($item ne 'selfcreate') {                if ($checked{$item} eq '') {
                 if ($checked{$item} eq '') {                  $checked{$item} = 'any';
                     $checked{$item} = 'any';  
                 }  
             }              }
             my $css_class;              my $css_class;
             if ($rownum%2) {              if ($rownum%2) {
Line 3442  sub print_usercreation { Line 3707  sub print_usercreation {
             $datatable .= '<tr'.$css_class.'>'.              $datatable .= '<tr'.$css_class.'>'.
                          '<td><span class="LC_nobreak">'.$lt{$item}.                           '<td><span class="LC_nobreak">'.$lt{$item}.
                          '</span></td><td align="right">';                           '</span></td><td align="right">';
             my @options;              my @options = ('any');
             if ($item eq 'selfcreate') {              if (ref($rules) eq 'HASH') {
                 push(@options,('email','login','sso'));                  if (keys(%{$rules}) > 0) {
             } else {                      push(@options,('official','unofficial'));
                 @options = ('any');  
                 if (ref($rules) eq 'HASH') {  
                     if (keys(%{$rules}) > 0) {  
                         push(@options,('official','unofficial'));  
                     }  
                 }                  }
                 push(@options,'none');  
             }              }
               push(@options,'none');
             foreach my $option (@options) {              foreach my $option (@options) {
                 my $type = 'radio';                  my $type = 'radio';
                 my $check = ' ';                  my $check = ' ';
                 if ($item eq 'selfcreate') {                  if ($checked{$item} eq $option) {
                     $type = 'checkbox';                      $check = ' checked="checked" ';
                     if (grep(/^\Q$option\E$/,@selfcreate)) {  
                         $check = ' checked="checked" ';  
                     }  
                 } else {  
                     if ($checked{$item} eq $option) {  
                         $check = ' checked="checked" ';  
                     }  
                 }                   } 
                 $datatable .= '<span class="LC_nobreak"><label>'.                  $datatable .= '<span class="LC_nobreak"><label>'.
                               '<input type="'.$type.'" name="can_createuser_'.                                '<input type="'.$type.'" name="can_createuser_'.
Line 3474  sub print_usercreation { Line 3727  sub print_usercreation {
             }              }
             $datatable .= '</td></tr>';              $datatable .= '</td></tr>';
         }          }
         my ($othertitle,$usertypes,$types) =  
             &Apache::loncommon::sorted_inst_types($dom);  
         my $createsettings;  
         if (ref($settings) eq 'HASH') {  
             $createsettings = $settings->{cancreate};  
         }  
         if (ref($usertypes) eq 'HASH') {  
             if (keys(%{$usertypes}) > 0) {  
                 $datatable .= &insttypes_row($createsettings,$types,$usertypes,  
                                              $dom,$numinrow,$othertitle,  
                                              'statustocreate');  
                 $$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 3541  sub print_usercreation { Line 3778  sub print_usercreation {
     return $datatable;      return $datatable;
 }  }
   
   sub print_selfcreation {
       my ($position,$dom,$settings,$rowtotal) = @_;
       my (@selfcreate,$createsettings,$datatable);
       if (ref($settings) eq 'HASH') {
           if (ref($settings->{'cancreate'}) eq 'HASH') {
               $createsettings = $settings->{'cancreate'};
               if (ref($settings->{'cancreate'}{'selfcreate'}) eq 'ARRAY') {
                   @selfcreate = @{$settings->{'cancreate'}{'selfcreate'}};
               } elsif ($settings->{'cancreate'}{'selfcreate'} ne '') {
                   if ($settings->{'cancreate'}{'selfcreate'} eq 'any') {
                       @selfcreate = ('email','login','sso');
                   } elsif ($settings->{'cancreate'}{'selfcreate'} ne 'none') {
                       @selfcreate = ($settings->{'cancreate'}{'selfcreate'});
                   }
               }
           }
       }
       my %radiohash;
       my $rownum = 0;
       my $numinrow = 4;
       map { $radiohash{'cancreate_'.$_} = 1; } @selfcreate;
       if ($position eq 'top') {
           my %choices = &Apache::lonlocal::texthash (
                                                         cancreate_login      => 'Institutional Login',
                                                         cancreate_sso        => 'Institutional Single Sign On',
                                                     );
           my @toggles = sort(keys(%choices));
           my %defaultchecked = (
                                  'cancreate_login' => 'off',
                                  'cancreate_sso'   => 'off',
                                );
           my $itemcount = 1;
           my $onclick;
           ($datatable,$itemcount) = &radiobutton_prefs(\%radiohash,\@toggles,\%defaultchecked,
                                                        \%choices,$itemcount,$onclick);
           my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom);
   
           if (ref($usertypes) eq 'HASH') {
               if (keys(%{$usertypes}) > 0) {
                   $datatable .= &insttypes_row($createsettings,$types,$usertypes,
                                                $dom,$numinrow,$othertitle,
                                                'statustocreate',$rownum);
                   $rownum ++;
                   $$rowtotal ++;
               }
           }
       } elsif ($position eq 'middle') {
           my %domconf = &Apache::lonnet::get_dom('configuration',['usermodification'],$dom);
           my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom);
           $usertypes->{'default'} = $othertitle;
           if (ref($types) eq 'ARRAY') {
               push(@{$types},'default');
               $usertypes->{'default'} = $othertitle;
               foreach my $status (@{$types}) {
                   $rownum ++;
                   $datatable .= &modifiable_userdata_row('selfcreate',$status,$domconf{'usermodification'},
                                                          $numinrow,$rownum,$usertypes);
                   $$rowtotal ++;
               }
           }
       } else {
           my $css_class = $rownum%2?' class="LC_odd_row"':'';
           my %choices =
               &Apache::lonlocal::texthash(
                                             email         => 'Approved automatically',
                                             emailapproval => 'Queued for approval by DC',
                                             off           => 'Not enabled',
                                          );
           $datatable .= '<tr'.$css_class.'>'.
                         '<td>'.&mt('E-mail address as username').
                         '</td><td class="LC_left_item">'.
                         '<span class="LC_nobreak">';
           foreach my $option ('email','emailapproval','off') {
               my $checked;
               if ($option eq 'email') {
                   if ($radiohash{'cancreate_email'}) {
                       $checked = 'checked="checked"';
                   }
               } elsif ($option eq 'emailapproval') {
                   if ($radiohash{'cancreate_emailapproval'}) {
                       $checked = 'checked="checked"';
                   }
               } else {
                   if ((!$radiohash{'cancreate_email'}) && (!$radiohash{'cancreate_emailapproval'})) {
                       $checked = 'checked="checked"';  
                   }
               }
               $datatable .= '<label>'.
                             '<input type="radio" name="cancreate_email" '.
                             $checked.' value="'.$option.'" />'.
                             $choices{$option}.'</label>&nbsp;';
           }
           $$rowtotal ++;
           $rownum ++;
           $datatable .= '</span></td></tr>'.
                         &print_requestmail($dom,'selfcreation',$createsettings,$rowtotal);
           $rownum ++;
           my ($infofields,$infotitles) = &Apache::loncommon::emailusername_info();
           $numinrow = 2;
           $datatable .= &modifiable_userdata_row('cancreate','emailusername',$settings,
                                                  $numinrow,$rownum,undef,$infofields,$infotitles);
           $$rowtotal ++;
           $rownum ++;
           my ($emailrules,$emailruleorder) =
               &Apache::lonnet::inst_userrules($dom,'email');
           if (ref($emailrules) eq 'HASH') {
               if (keys(%{$emailrules}) > 0) {
                   $datatable .= &user_formats_row('email',$settings,$emailrules,
                                                   $emailruleorder,$numinrow,$rownum);
                   $rownum ++;
                   $$rowtotal ++;
               }
           }
           $datatable .= &captcha_choice('cancreate',$createsettings,$rownum);
       }
       return $datatable;
   }
   
 sub captcha_choice {  sub captcha_choice {
     my ($context,$settings,$itemcount) = @_;      my ($context,$settings,$itemcount) = @_;
     my ($keyentry,$currpub,$currpriv,%checked,$rowname,$pubtext,$privtext);      my ($keyentry,$currpub,$currpriv,%checked,$rowname,$pubtext,$privtext);
     my %lt = &captcha_phrases();      my %lt = &captcha_phrases();
     $keyentry = 'hidden';      $keyentry = 'hidden';
     if ($context eq 'cancreate') {      if ($context eq 'cancreate') {
         $rowname = &mt('CAPTCHA validation (e-mail as username)');          $rowname = &mt('CAPTCHA validation');
     } elsif ($context eq 'login') {      } elsif ($context eq 'login') {
         $rowname =  &mt('"Contact helpdesk" CAPTCHA validation');          $rowname =  &mt('"Contact helpdesk" CAPTCHA validation');
     }      }
Line 3584  sub captcha_choice { Line 3939  sub captcha_choice {
 #  #
 # Note: If reCAPTCHA is to be used for LON-CAPA servers in a domain, a domain coordinator should visit:  # 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  # 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)   # 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.  # specified for use with the key should be broad enough to accommodate all servers in the LON-CAPA domain.
 #    #
     $output .= '</td></tr>'."\n".      $output .= '</td></tr>'."\n".
                '<tr><td>'."\n".                 '<tr><td>'."\n".
                '<span class="LC_nobreak"><span id="'.$context.'_recaptchapubtxt">'.$pubtext.'</span>&nbsp;'."\n".                 '<span class="LC_nobreak"><span id="'.$context.'_recaptchapubtxt">'.$pubtext.'</span>&nbsp;'."\n".
Line 3661  sub usercreation_types { Line 4016  sub usercreation_types {
                     author     => 'When adding a co-author',                      author     => 'When adding a co-author',
                     course     => 'When adding a user to a course',                      course     => 'When adding a user to a course',
                     requestcrs => 'When requesting a course',                      requestcrs => 'When requesting a course',
                     selfcreate => 'User creates own account',   
                     any        => 'Any',                      any        => 'Any',
                     official   => 'Institutional only ',                      official   => 'Institutional only ',
                     unofficial => 'Non-institutional only',                      unofficial => 'Non-institutional only',
                     email      => 'E-mail address',  
                     login      => 'Institutional Login',  
                     sso        => 'SSO',   
                     none       => 'None',                      none       => 'None',
     );      );
     return %lt;      return %lt;
 }  }
   
   sub selfcreation_types {
       my %lt = &Apache::lonlocal::texthash (
                       selfcreate => 'User creates own account',
                       any        => 'Any',
                       official   => 'Institutional only ',
                       unofficial => 'Non-institutional only',
                       email      => 'E-mail address',
                       login      => 'Institutional Login',
                       sso        => 'SSO',
                );
   }
   
 sub authtype_names {  sub authtype_names {
     my %lt = &Apache::lonlocal::texthash(      my %lt = &Apache::lonlocal::texthash(
                       int    => 'Internal',                        int    => 'Internal',
Line 3714  sub print_usermodification { Line 4077  sub print_usermodification {
             $$rowtotal ++;              $$rowtotal ++;
             $rowcount ++;              $rowcount ++;
         }          }
     } elsif ($position eq 'bottom') {  
         $context = 'selfcreate';  
         my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom);  
         $usertypes->{'default'} = $othertitle;  
         if (ref($types) eq 'ARRAY') {  
             push(@{$types},'default');  
             $usertypes->{'default'} = $othertitle;  
             foreach my $status (@{$types}) {  
                 $datatable .= &modifiable_userdata_row($context,$status,$settings,  
                                                        $numinrow,$rowcount,$usertypes);  
                 $$rowtotal ++;  
                 $rowcount ++;  
             }  
         }  
     }      }
     return $datatable;      return $datatable;
 }  }
   
 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','portal_def');                   'datelocale_def','portal_def');
     my %domdefaults = &Apache::lonnet::get_domain_defaults($dom);      my %defaults;
       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 $titles = &defaults_titles($dom);
     my $rownum = 0;      my $rownum = 0;
     my ($datatable,$css_class);      my ($datatable,$css_class);
Line 3760  sub print_defaults { Line 4117  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 3769  sub print_defaults { Line 4126  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);
         } elsif ($item eq 'lang_def') {          } elsif ($item eq 'lang_def') {
             my %langchoices = &get_languages_hash();              my %langchoices = &get_languages_hash();
             $langchoices{''} = 'No language preference';              $langchoices{''} = 'No language preference';
             %langchoices = &Apache::lonlocal::texthash(%langchoices);              %langchoices = &Apache::lonlocal::texthash(%langchoices);
             $datatable .= &Apache::loncommon::select_form($domdefaults{$item},$item,              $datatable .= &Apache::loncommon::select_form($defaults{$item},$item,
                                                           \%langchoices);                                                            \%langchoices);
         } else {          } else {
             my $size;              my $size;
Line 3785  sub print_defaults { Line 4142  sub print_defaults {
                 $size = ' size="25"';                  $size = ' size="25"';
             }              }
             $datatable .= '<input type="text" name="'.$item.'" value="'.              $datatable .= '<input type="text" name="'.$item.'" value="'.
                           $domdefaults{$item}.'"'.$size.' />';                            $defaults{$item}.'"'.$size.' />';
         }          }
         $datatable .= '</td></tr>';          $datatable .= '</td></tr>';
         $rownum ++;          $rownum ++;
Line 4122  sub print_coursecategories { Line 4479  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 4152  sub print_coursecategories { Line 4509  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 4267  sub print_serverstatuses { Line 4625  sub print_serverstatuses {
 sub serverstatus_pages {  sub serverstatus_pages {
     return ('userstatus','lonstatus','loncron','server-status','codeversions',      return ('userstatus','lonstatus','loncron','server-status','codeversions',
             'checksums','clusterstatus','metadata_keywords','metadata_harvest',              'checksums','clusterstatus','metadata_keywords','metadata_harvest',
             'takeoffline','takeonline','showenv','toggledebug','ping','domconf');              'takeoffline','takeonline','showenv','toggledebug','ping','domconf',
               'uniquecodes');
 }  }
   
 sub coursecategories_javascript {  sub coursecategories_javascript {
Line 4424  sub build_category_rows { Line 4783  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 4498  sub build_category_rows { Line 4857  sub build_category_rows {
 }  }
   
 sub modifiable_userdata_row {  sub modifiable_userdata_row {
     my ($context,$role,$settings,$numinrow,$rowcount,$usertypes) = @_;      my ($context,$role,$settings,$numinrow,$rowcount,$usertypes,$fieldsref,$titlesref) = @_;
     my $rolename;      my $rolename;
     if ($context eq 'selfcreate') {      if ($context eq 'cancreate') {
           if ($role eq 'emailusername') {
               $rolename = &mt('Data user provides');
           }
       } elsif ($context eq 'selfcreate') {
         if (ref($usertypes) eq 'HASH') {          if (ref($usertypes) eq 'HASH') {
             $rolename = $usertypes->{$role};              $rolename = $usertypes->{$role};
         } else {          } else {
Line 4513  sub modifiable_userdata_row { Line 4876  sub modifiable_userdata_row {
             $rolename = &Apache::lonnet::plaintext($role);              $rolename = &Apache::lonnet::plaintext($role);
         }          }
     }      }
     my @fields = ('lastname','firstname','middlename','generation',      my (@fields,%fieldtitles);
                   'permanentemail','id');      if (ref($fieldsref) eq 'ARRAY') {
     my %fieldtitles = &Apache::loncommon::personal_data_fieldtitles();          @fields = @{$fieldsref};
       } else {
           @fields = ('lastname','firstname','middlename','generation',
                      'permanentemail','id');
       }
       if ((ref($titlesref) eq 'HASH')) {
           %fieldtitles = %{$titlesref};
       } else {
           %fieldtitles = &Apache::loncommon::personal_data_fieldtitles();
       }
     my $output;      my $output;
     my $css_class = $rowcount%2?' class="LC_odd_row"':'';      my $css_class = $rowcount%2?' class="LC_odd_row"':'';
     $output = '<tr '.$css_class.'>'.      $output = '<tr '.$css_class.'>'.
Line 4571  sub modifiable_userdata_row { Line 4943  sub modifiable_userdata_row {
 }  }
   
 sub insttypes_row {  sub insttypes_row {
     my ($settings,$types,$usertypes,$dom,$numinrow,$othertitle,$context) = @_;      my ($settings,$types,$usertypes,$dom,$numinrow,$othertitle,$context,$rownum) = @_;
     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)',
Line 4585  sub insttypes_row { Line 4957  sub insttypes_row {
     if ($context eq 'statustocreate') {      if ($context eq 'statustocreate') {
         $class = 'LC_right_item';          $class = 'LC_right_item';
     }      }
     my $output =  '<tr class="LC_odd_row">'.      my $css_class = ' class="LC_odd_row"';
                   '<td>'.$lt{$context}.$showdom.      if ($rownum ne '') { 
                   '</td><td class="'.$class.'" colspan="2"><table>';          $css_class = ($rownum%2? ' class="LC_odd_row"':'');
       }
       print STDERR "rownum ||$rownum|| an css_class ||".$css_class."||\n";
       my $output = '<tr'.$css_class.'>'.
                    '<td>'.$lt{$context}.$showdom.
                    '</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 4716  sub usertype_update_row { Line 5093  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,%newfile,%newurl,      my ($resulttext,$errors,$colchgtext,%changes,%colchanges,%newfile,%newurl,
         %curr_loginvia,%loginhash,@currlangs,@newlangs,$addedfile,%title,@offon);          %curr_loginvia,%loginhash,@currlangs,@newlangs,$addedfile,%title,@offon);
     %title = ( coursecatalog => 'Display course catalog',      %title = ( coursecatalog => 'Display course catalog',
Line 4896  sub modify_login { Line 5273  sub modify_login {
                     } else {                      } else {
                         my $puberror = &mt("Upload of [_1] failed because an error occurred publishing the file in RES space. Error was: [_2].",$newfile{$lang},$result);                          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>';                          $errors .= '<li><span class="LC_error">'.$puberror.'</span></li>';
                         if ((grep(/^\Q$lang\E$/,@currlangs)) &&                           if ((grep(/^\Q$lang\E$/,@currlangs)) &&
                             (!grep(/^\Q$lang\E$/,@delurls))) {                              (!grep(/^\Q$lang\E$/,@delurls))) {
   
                             $loginhash{'login'}{'helpurl'}{$lang} = $domconfig{'login'}{'helpurl'}{$lang};                              $loginhash{'login'}{'helpurl'}{$lang} = $domconfig{'login'}{'helpurl'}{$lang};
Line 4954  sub modify_login { Line 5331  sub modify_login {
         }          }
         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 'loginvia') {                  if ($item eq 'loginvia') {
Line 5013  sub modify_login { Line 5393  sub modify_login {
                     }                      }
                 } elsif ($item eq 'captcha') {                  } elsif ($item eq 'captcha') {
                     if (ref($loginhash{'login'}) eq 'HASH') {                      if (ref($loginhash{'login'}) eq 'HASH') {
                         my $chgtxt;                           my $chgtxt;
                         if ($loginhash{'login'}{$item} eq 'notused') {                          if ($loginhash{'login'}{$item} eq 'notused') {
                             $chgtxt .= &mt('No CAPTCHA validation in use for helpdesk form.');                              $chgtxt .= &mt('No CAPTCHA validation in use for helpdesk form.');
                         } else {                          } else {
Line 5086  sub color_font_choices { Line 5466  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 5101  sub modify_rolecolors { Line 5481  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 5512  sub publishlogo { Line 5895  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 $docroot=$r->dir_config('lonDocRoot');       my $docroot=$r->dir_config('lonDocRoot');
     my $filepath="$docroot/priv";      my $filepath="$docroot/priv";
     my $relpath = "$dom/$confname";      my $relpath = "$dom/$confname";
     my ($fnamepath,$file,$fetchthumb);      my ($fnamepath,$file,$fetchthumb);
Line 5532  sub publishlogo { Line 5915  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);
Line 5781  sub check_switchserver { Line 6164  sub check_switchserver {
 }  }
   
 sub modify_quotas {  sub modify_quotas {
     my ($dom,$action,%domconfig) = @_;      my ($r,$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,$confname,$configuserok,
           $author_ok,$switchserver,$errors);
     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') {
         @usertools = ('official','unofficial','community');          @usertools = ('official','unofficial','community','textbook');
         @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();
         $toolregexp = join('|',@usertools);          $toolregexp = join('|',@usertools);
         %conditions = &courserequest_conditions();          %conditions = &courserequest_conditions();
           $confname = $dom.'-domainconfig';
           my $servadm = $r->dir_config('lonAdmEMail');
           ($configuserok,$author_ok,$switchserver) = &config_check($dom,$confname,$servadm);
     } elsif ($context eq 'requestauthor') {      } elsif ($context eq 'requestauthor') {
         @usertools = ('author');          @usertools = ('author');
         %titles = &authorrequest_titles();          %titles = &authorrequest_titles();
Line 5803  sub modify_quotas { Line 6190  sub modify_quotas {
         @usertools = ('aboutme','blog','webdav','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 5831  sub modify_quotas { Line 6218  sub modify_quotas {
         }          }
     }      }
     if (($context eq 'requestcourses') || ($context eq 'requestauthor')) {      if (($context eq 'requestcourses') || ($context eq 'requestauthor')) {
         my @approvalnotify = &Apache::loncommon::get_env_multiple('form.reqapprovalnotify');          my @approvalnotify = &Apache::loncommon::get_env_multiple('form.'.$context.'notifyapproval');
         @approvalnotify = sort(@approvalnotify);          @approvalnotify = sort(@approvalnotify);
         $confhash{'notify'}{'approval'} = join(',',@approvalnotify);          $confhash{'notify'}{'approval'} = join(',',@approvalnotify);
           my @crstypes = ('official','unofficial','community','textbook');
           my @hasuniquecode = &Apache::loncommon::get_env_multiple('form.uniquecode');
           foreach my $type (@hasuniquecode) {
               if (grep(/^\Q$type\E$/,@crstypes)) {
                   $confhash{'uniquecode'}{$type} = 1;
               }
           }
           my ($newbook,@allpos);
           if ($context eq 'requestcourses') {
               if ($env{'form.addbook'}) {
                   if (($env{'form.addbook_cnum'} =~ /^$match_courseid$/) &&
                       ($env{'form.addbook_cdom'} =~ /^$match_domain$/)) {
                       if (&Apache::lonnet::homeserver($env{'form.addbook_cnum'},
                                                       $env{'form.addbook_cdom'}) eq 'no_host') {
                           $errors .= '<li><span class="LC_error">'.&mt('Invalid LON-CAPA course for textbook').
                                      '</span></li>';
                       } else {
                           $newbook = $env{'form.addbook_cdom'}.'_'.$env{'form.addbook_cnum'};
                           my $position = $env{'form.addbook_pos'};
                           $position =~ s/\D+//g;
                           if ($position ne '') {
                               $allpos[$position] = $newbook;
                           }
                       }
                   } else {
                       $errors .= '<li><span class="LC_error">'.&mt('Invalid LON-CAPA course for textbook').
                                  '</span></li>';
                   }
               }
           }
         if (ref($domconfig{$action}) eq 'HASH') {          if (ref($domconfig{$action}) eq 'HASH') {
             if (ref($domconfig{$action}{'notify'}) eq 'HASH') {              if (ref($domconfig{$action}{'notify'}) eq 'HASH') {
                 if ($domconfig{$action}{'notify'}{'approval'} ne $confhash{'notify'}{'approval'}) {                  if ($domconfig{$action}{'notify'}{'approval'} ne $confhash{'notify'}{'approval'}) {
Line 5844  sub modify_quotas { Line 6261  sub modify_quotas {
                     $changes{'notify'}{'approval'} = 1;                      $changes{'notify'}{'approval'} = 1;
                 }                  }
             }              }
               if (ref($domconfig{$action}{'uniquecode'}) eq 'HASH') {
                   if (ref($confhash{'uniquecode'}) eq 'HASH') {
                       foreach my $crstype (keys(%{$domconfig{$action}{'uniquecode'}})) {
                           unless ($confhash{'uniquecode'}{$crstype}) {
                               $changes{'uniquecode'} = 1;
                           }
                       }
                       unless ($changes{'uniquecode'}) {
                           foreach my $crstype (keys(%{$confhash{'uniquecode'}})) {
                               unless ($domconfig{$action}{'uniquecode'}{$crstype}) {
                                   $changes{'uniquecode'} = 1;
                               }
                           }
                       }
                  } else {
                      $changes{'uniquecode'} = 1;
                  }
               } elsif (ref($confhash{'uniquecode'}) eq 'HASH') {
                   $changes{'uniquecode'} = 1;
               }
               if ($context eq 'requestcourses') {
                   if (ref($domconfig{$action}{'textbooks'}) eq 'HASH') {
                       my %deletions;
                       my @todelete = &Apache::loncommon::get_env_multiple('form.book_del');
                       if (@todelete) {
                           map { $deletions{$_} = 1; } @todelete;
                       }
                       my %imgdeletions;
                       my @todeleteimages = &Apache::loncommon::get_env_multiple('form.book_image_del');
                       if (@todeleteimages) {
                           map { $imgdeletions{$_} = 1; } @todeleteimages;
                       }
                       my $maxnum = $env{'form.book_maxnum'};
                       for (my $i=0; $i<=$maxnum; $i++) {
                           my $key = $env{'form.book_id_'.$i};
                           if (ref($domconfig{$action}{'textbooks'}{$key}) eq 'HASH') {
                               if ($deletions{$key}) {
                                   if ($domconfig{$action}{'textbooks'}{$key}{'image'}) {
                                       #FIXME need to obsolete item in RES space
                                   }
                                   next;
                               } else {
                                   my $newpos = $env{'form.'.$key};
                                   $newpos =~ s/\D+//g;
                                   foreach my $item ('subject','title','author') {
                                       $confhash{'textbooks'}{$key}{$item} = $env{'form.book_'.$item.'_'.$i};
                                       if ($domconfig{$action}{'textbooks'}{$key}{$item} ne $confhash{'textbooks'}{$key}{$item}) {
                                           $changes{'textbooks'}{$key} = 1;
                                       }
                                   }
                                   $allpos[$newpos] = $key;
                               }
                               if ($imgdeletions{$key}) {
                                   $changes{'textbooks'}{$key} = 1;
                                   #FIXME need to obsolete item in RES space
                               } elsif ($env{'form.book_image_'.$i.'.filename'}) {
                                   my ($cdom,$cnum) = split(/_/,$key);
                                   my ($imgurl,$error) = &process_textbook_image($r,$dom,$confname,'book_image_'.$i,
                                                                                 $cdom,$cnum,$configuserok,
                                                                                 $switchserver,$author_ok);
                                   if ($imgurl) {
                                       $confhash{'textbooks'}{$key}{'image'} = $imgurl;
                                       $changes{'textbooks'}{$key} = 1; 
                                   }
                                   if ($error) {
                                       &Apache::lonnet::logthis($error);
                                       $errors .= '<li><span class="LC_error">'.$error.'</span></li>';
                                   } 
                               } elsif ($domconfig{$action}{'textbooks'}{$key}{'image'}) {
                                   $confhash{'textbooks'}{$key}{'image'} = 
                                       $domconfig{$action}{'textbooks'}{$key}{'image'};
                               }
                           }
                       }
                   }
               }
         } else {          } else {
             if ($confhash{'notify'}{'approval'}) {              if ($confhash{'notify'}{'approval'}) {
                 $changes{'notify'}{'approval'} = 1;                  $changes{'notify'}{'approval'} = 1;
             }              }
               if (ref($confhash{'uniquecode'} eq 'HASH')) {
                   $changes{'uniquecode'} = 1;
               }
           }
           if ($context eq 'requestcourses') {
               if ($newbook) {
                   $changes{'textbooks'}{$newbook} = 1;
                   foreach my $item ('subject','title','author') {
                       $env{'form.addbook_'.$item} =~ s/(`)/'/g;
                       if ($env{'form.addbook_'.$item}) {
                           $confhash{'textbooks'}{$newbook}{$item} = $env{'form.addbook_'.$item};
                       }
                   }
                   if ($env{'form.addbook_image.filename'} ne '') {
                       my ($cdom,$cnum) = split(/_/,$newbook);
                       my ($imageurl,$error) = 
                           &process_textbook_image($r,$dom,$confname,'addbook_image',$cdom,$cnum,$configuserok,
                                                   $switchserver,$author_ok);
                       if ($imageurl) {
                           $confhash{'textbooks'}{$newbook}{'image'} = $imageurl;
                       }
                       if ($error) {
                           &Apache::lonnet::logthis($error);
                           $errors .= '<li><span class="LC_error">'.$error.'</span></li>';
                       }
                   }
               }
               if (@allpos > 0) {
                   my $idx = 0;
                   foreach my $item (@allpos) {
                       if ($item ne '') {
                           $confhash{'textbooks'}{$item}{'order'} = $idx;
                           if (ref($domconfig{$action}) eq 'HASH') {
                               if (ref($domconfig{$action}{'textbooks'}) eq 'HASH') {
                                   if (ref($domconfig{$action}{'textbooks'}{$item}) eq 'HASH') {
                                       if ($domconfig{$action}{'textbooks'}{$item}{'order'} ne $idx) {
                                           $changes{'textbooks'}{$item} = 1;
                                       }
                                   }
                               }
                           }
                           $idx ++;
                       }
                   }
               }
         }          }
     } else {      } else {
         $confhash{'defaultquota'}{'default'} = $env{'form.defaultquota'};          $confhash{'defaultquota'}{'default'} = $env{'form.defaultquota'};
Line 5989  sub modify_quotas { Line 6527  sub modify_quotas {
         $domdefaults{'requestauthor'} = \%confhash;          $domdefaults{'requestauthor'} = \%confhash;
     } else {      } else {
         foreach my $key (keys(%confhash)) {          foreach my $key (keys(%confhash)) {
             $domdefaults{$key} = $confhash{$key};              unless (($context eq 'requestcourses') && ($key eq 'textbooks')) {
                   $domdefaults{$key} = $confhash{$key};
               }
         }          }
     }      }
   
Line 6002  sub modify_quotas { Line 6542  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')) {                      ($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>';
Line 6014  sub modify_quotas { Line 6556  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>';                      $resulttext .= '</ul></li>';
                 }                  }
                 if (ref($changes{'authorquota'}) eq 'HASH') {                  if (ref($changes{'authorquota'}) eq 'HASH') {
                     $resulttext .= '<li>'.&mt('Authoring space default quotas').'<ul>';                      $resulttext .= '<li>'.&mt('Authoring Space default quotas').'<ul>';
                     foreach my $type (@{$types},'default') {                      foreach my $type (@{$types},'default') {
                         if (defined($changes{'authorquota'}{$type})) {                          if (defined($changes{'authorquota'}{$type})) {
                             my $typetitle = $usertypes->{$type};                              my $typetitle = $usertypes->{$type};
                             if ($type eq 'default') {                              if ($type eq 'default') {
                                 $typetitle = $othertitle;                                  $typetitle = $othertitle;
                             }                              }
                             $resulttext .= '<li>'.&mt('[_1] set to [_2] Mb',$typetitle,$confhash{'authorquota'}{$type}).'</li>';                              $resulttext .= '<li>'.&mt('[_1] set to [_2] MB',$typetitle,$confhash{'authorquota'}{$type}).'</li>';
                         }                          }
                     }                      }
                     $resulttext .= '</ul></li>';                      $resulttext .= '</ul></li>';
Line 6038  sub modify_quotas { Line 6580  sub modify_quotas {
                 my (%haschgs,%inconf);                  my (%haschgs,%inconf);
                 if ($context eq 'requestauthor') {                  if ($context eq 'requestauthor') {
                     %haschgs = %changes;                      %haschgs = %changes;
                     %inconf = %confhash;                       %inconf = %confhash;
                 } else {                  } else {
                     if (ref($changes{$item}) eq 'HASH') {                      if (ref($changes{$item}) eq 'HASH') {
                         %haschgs = %{$changes{$item}};                          %haschgs = %{$changes{$item}};
Line 6052  sub modify_quotas { Line 6594  sub modify_quotas {
                         &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')) {                          ($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 6124  sub modify_quotas { Line 6666  sub modify_quotas {
                     }                      }
                 }                  }
             }              }
               if ($action eq 'requestcourses') {
                   my @offon = ('off','on');
                   if ($changes{'uniquecode'}) {
                       if (ref($confhash{'uniquecode'}) eq 'HASH') {
                           my $codestr = join(' ',map{ &mt($_); } sort(keys(%{$confhash{'uniquecode'}})));
                           $resulttext .= '<li>'.
                                          &mt('Generation of six character code as course identifier for distribution to students set to on for: [_1].','<b>'.$codestr.'</b>').
                                          '</li>';
                       } else {
                           $resulttext .= '<li>'.&mt('Generation of six character code as course identifier for distribution to students set to off.').
                                          '</li>';
                       }
                   }
                   if (ref($changes{'textbooks'}) eq 'HASH') {
                       $resulttext .= '<li>'.&mt('Available textbooks updated').'<ul>';
                       foreach my $key (sort(keys(%{$changes{'textbooks'}}))) {
                           my %coursehash = &Apache::lonnet::coursedescription($key);
                           my $coursetitle = $coursehash{'description'};
                           my $position = $confhash{'textbooks'}{$key}{'order'} + 1;
                           $resulttext .= '<li>';
                           foreach my $item ('subject','title','author') {
                               my $name = $item.':';
                               $name =~ s/^(\w)/\U$1/;
                               $resulttext .= &mt($name).' '.$confhash{'textbooks'}{$key}{$item}.'<br />';
                           }
                           $resulttext .= ' '.&mt('Order: [_1]',$position).'<br />';
                           if ($confhash{'textbooks'}{$key}{'image'}) {
                               $resulttext .= ' '.&mt('Image: [_1]',
                                                  '<img src="'.$confhash{'textbooks'}{$key}{'image'}.'"'.
                                                  ' alt="Textbook cover" />').'<br />';
                           }
                           $resulttext .= ' '.&mt('LON-CAPA Course: [_1]',$coursetitle).'</li>';
                       }
                       $resulttext .= '</ul></li>';
                   }
               }
             $resulttext .= '</ul>';              $resulttext .= '</ul>';
             if (keys(%newenv)) {              if (keys(%newenv)) {
                 &Apache::lonnet::appenv(\%newenv);                  &Apache::lonnet::appenv(\%newenv);
Line 6141  sub modify_quotas { Line 6719  sub modify_quotas {
         $resulttext = '<span class="LC_error">'.          $resulttext = '<span class="LC_error">'.
     &mt('An error occurred: [_1]',$putresult).'</span>';      &mt('An error occurred: [_1]',$putresult).'</span>';
     }      }
       if ($errors) {
           $resulttext .= '<p>'.&mt('The following errors occurred when modifying Textbook settings.').
                          '<ul>'.$errors.'</ul></p>';
       }
     return $resulttext;      return $resulttext;
 }  }
   
   sub process_textbook_image {
       my ($r,$dom,$confname,$caller,$cdom,$cnum,$configuserok,$switchserver,$author_ok) = @_;
       my $filename = $env{'form.'.$caller.'.filename'};
       my ($error,$url);
       my ($width,$height) = (50,50);
       if ($configuserok eq 'ok') {
           if ($switchserver) {
               $error = &mt('Upload of textbook image is not permitted to this server: [_1]',
                            $switchserver);
           } elsif ($author_ok eq 'ok') {
               my ($result,$imageurl) =
                   &publishlogo($r,'upload',$caller,$dom,$confname,
                                "textbooks/$dom/$cnum/cover",$width,$height);
               if ($result eq 'ok') {
                   $url = $imageurl;
               } else {
                   $error = &mt("Upload of [_1] failed because an error occurred publishing the file in RES space. Error was: [_2].",$filename,$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].",$filename,$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].",$filename,$confname,$dom,$configuserok);
       }
       return ($url,$error);
   }
   
 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 6213  sub modify_autoenroll { Line 6822  sub modify_autoenroll {
             if ($changes{'coowners'}) {              if ($changes{'coowners'}) {
                 $resulttext .= '<li>'.&mt("$title{'coowners'} set to $offon[$env{'form.autoassign_coowners'}]").'</li>';                  $resulttext .= '<li>'.&mt("$title{'coowners'} set to $offon[$env{'form.autoassign_coowners'}]").'</li>';
                 &Apache::loncommon::devalidate_domconfig_cache($dom);                  &Apache::loncommon::devalidate_domconfig_cache($dom);
                   if (ref($lastactref) eq 'HASH') {
                       $lastactref->{'domainconfig'} = 1;
                   }
             }              }
             $resulttext .= '</ul>';              $resulttext .= '</ul>';
         } else {          } else {
Line 6618  sub modify_directorysrch { Line 7230  sub modify_directorysrch {
                         } else {                          } else {
                             $chgtext =~ s/\; $//;                              $chgtext =~ s/\; $//;
                         }                          }
                         $resulttext .=                           $resulttext .=
                             '<li>'.                              '<li>'.
                             &mt("Users from domain '[_1]' permitted to search the institutional directory set to: [_2]",                              &mt("Users from domain '[_1]' permitted to search the institutional directory set to: [_2]",
                                 '<span class="LC_cusr_emph">'.$dom.'</span>',$chgtext).                                  '<span class="LC_cusr_emph">'.$dom.'</span>',$chgtext).
Line 6664  sub modify_directorysrch { Line 7276  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'}})) {
Line 6674  sub modify_contacts { Line 7286  sub modify_contacts {
     my (%others,%to,%bcc);      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','updatesmail');                      '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 6696  sub modify_contacts { Line 7309  sub modify_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 6734  sub modify_contacts { Line 7352  sub modify_contacts {
         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 6751  sub modify_contacts { Line 7369  sub modify_contacts {
             }              }
         }          }
     }      }
       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 6785  sub modify_contacts { Line 7415  sub modify_contacts {
                     $resulttext .= '</li>';                      $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 {
             $resulttext = &mt('No changes made to contact information');              $resulttext = &mt('No changes made to contact information');
Line 6798  sub modify_contacts { Line 7445  sub modify_contacts {
   
 sub modify_usercreation {  sub modify_usercreation {
     my ($dom,%domconfig) = @_;      my ($dom,%domconfig) = @_;
     my ($resulttext,%curr_usercreation,%changes,%authallowed,%cancreate);      my ($resulttext,%curr_usercreation,%changes,%authallowed,%cancreate,%save_usercreate);
     my $warningmsg;      my $warningmsg;
     if (ref($domconfig{'usercreation'}) eq 'HASH') {      if (ref($domconfig{'usercreation'}) eq 'HASH') {
         foreach my $key (keys(%{$domconfig{'usercreation'}})) {          foreach my $key (keys(%{$domconfig{'usercreation'}})) {
             $curr_usercreation{$key} = $domconfig{'usercreation'}{$key};              if ($key eq 'cancreate') {
         }                  if (ref($domconfig{'usercreation'}{$key}) eq 'HASH') {
     }                      foreach my $item (keys(%{$domconfig{'usercreation'}{$key}})) {
     my @username_rule = &Apache::loncommon::get_env_multiple('form.username_rule');                          if (($item eq 'selfcreate') || ($item eq 'statustocreate') ||
     my @id_rule = &Apache::loncommon::get_env_multiple('form.id_rule');                              ($item eq 'captcha') || ($item eq 'recaptchakeys')) {
     my @email_rule = &Apache::loncommon::get_env_multiple('form.email_rule');                              $save_usercreate{$key}{$item} = $domconfig{'usercreation'}{$key}{$item};
     my @contexts = ('author','course','requestcrs','selfcreate');                          } else {
     foreach my $item(@contexts) {                              $curr_usercreation{$key}{$item} = $domconfig{'usercreation'}{$key}{$item};
         if ($item eq 'selfcreate') {                          }
             @{$cancreate{$item}} = &Apache::loncommon::get_env_multiple('form.can_createuser_'.$item);  
             my %domdefaults = &Apache::lonnet::get_domain_defaults($dom);  
             if (!((($domdefaults{'auth_def'} =~/^krb/) && ($domdefaults{'auth_arg_def'} ne '')) || ($domdefaults{'auth_def'} eq 'localauth'))) {  
                 if (ref($cancreate{$item}) eq 'ARRAY') {   
                     if (grep(/^login$/,@{$cancreate{$item}})) {  
                         $warningmsg = &mt('Although account creation has been set to be available for institutional logins, currently default authentication in this domain has not been set to support this.').' '.&mt('You need to set the default authentication type to Kerberos 4 or 5 (with a Kerberos domain specified), or to Local authentication, if the localauth module has been customized in your domain to authenticate institutional logins.');     
                     }                      }
                 }                  }
               } elsif ($key eq 'email_rule') {
                   $save_usercreate{$key} = $domconfig{'usercreation'}{$key};
               } else {
                   $curr_usercreation{$key} = $domconfig{'usercreation'}{$key};
             }              }
         } else {  
             $cancreate{$item} = $env{'form.can_createuser_'.$item};  
         }          }
     }      }
     my ($othertitle,$usertypes,$types) =       my @username_rule = &Apache::loncommon::get_env_multiple('form.username_rule');
         &Apache::loncommon::sorted_inst_types($dom);      my @id_rule = &Apache::loncommon::get_env_multiple('form.id_rule');
     if (ref($types) eq 'ARRAY') {      my @contexts = ('author','course','requestcrs');
         if (@{$types} > 0) {      foreach my $item(@contexts) {
             @{$cancreate{'statustocreate'}} =           $cancreate{$item} = $env{'form.can_createuser_'.$item};
                 &Apache::loncommon::get_env_multiple('form.statustocreate');  
         } else {  
             @{$cancreate{'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 ($curr_usercreation{'cancreate'}{$item} ne $cancreate{$item}) {
                 if (ref($curr_usercreation{'cancreate'}{$item}) eq 'ARRAY') {                  push(@{$changes{'cancreate'}},$item);
                     foreach my $curr (@{$curr_usercreation{'cancreate'}{$item}}) {  
                         if (ref($cancreate{$item}) eq 'ARRAY') {  
                             if (!grep(/^$curr$/,@{$cancreate{$item}})) {  
                                 if (!grep(/^$item$/,@{$changes{'cancreate'}})) {  
                                     push(@{$changes{'cancreate'}},$item);  
                                 }  
                             }  
                         }  
                     }  
                 } else {  
                     if ($curr_usercreation{'cancreate'}{$item} eq '') {  
                         if (@{$cancreate{$item}} > 0) {  
                             if (!grep(/^$item$/,@{$changes{'cancreate'}})) {  
                                 push(@{$changes{'cancreate'}},$item);  
                             }  
                         }  
                     } else {  
                         if ($curr_usercreation{'cancreate'}{$item} eq 'any') {  
                             if (@{$cancreate{$item}} < 3) {  
                                 if (!grep(/^$item$/,@{$changes{'cancreate'}})) {  
                                     push(@{$changes{'cancreate'}},$item);  
                                 }  
                             }  
                         } elsif ($curr_usercreation{'cancreate'}{$item} eq 'none') {  
                             if (@{$cancreate{$item}} > 0) {  
                                 if (!grep(/^$item$/,@{$changes{'cancreate'}})) {  
                                     push(@{$changes{'cancreate'}},$item);  
                                 }  
                             }  
                         } elsif (!grep(/^$curr_usercreation{'cancreate'}{$item}$/,@{$cancreate{$item}})) {  
                             if (!grep(/^$item$/,@{$changes{'cancreate'}})) {  
                                 push(@{$changes{'cancreate'}},$item);  
                             }  
                         }  
                     }  
                 }  
                 if (!grep(/^$item$/,@{$changes{'cancreate'}})) {  
                     foreach my $type (@{$cancreate{$item}}) {  
                         if (ref($curr_usercreation{'cancreate'}{$item}) eq 'ARRAY') {  
                             if (!grep(/^$type$/,@{$curr_usercreation{'cancreate'}{$item}})) {  
                                 if (!grep(/^$item$/,@{$changes{'cancreate'}})) {  
                                     push(@{$changes{'cancreate'}},$item);  
                                 }  
                             }  
                         } elsif (($curr_usercreation{'cancreate'}{$item} ne 'any') &&  
                                  ($curr_usercreation{'cancreate'}{$item} ne 'none')) {  
                             if ($curr_usercreation{'cancreate'}{$item} ne $type) {  
                                 if (!grep(/^$item$/,@{$changes{'cancreate'}})) {  
                                     push(@{$changes{'cancreate'}},$item);  
                                 }  
                             }  
                         }  
                     }  
                 }  
             } else {  
                 if ($curr_usercreation{'cancreate'}{$item} ne $cancreate{$item}) {  
                     push(@{$changes{'cancreate'}},$item);  
                 }  
             }              }
         }          }
     } elsif (ref($curr_usercreation{'cancreate'}) eq 'ARRAY') {      } elsif (ref($curr_usercreation{'cancreate'}) eq 'ARRAY') {
Line 6948  sub modify_usercreation { Line 7527  sub modify_usercreation {
         push(@{$changes{'id_rule'}},@id_rule);          push(@{$changes{'id_rule'}},@id_rule);
     }      }
   
     if (ref($curr_usercreation{'email_rule'}) eq 'ARRAY') {  
         foreach my $type (@{$curr_usercreation{'email_rule'}}) {  
             if (!grep(/^\Q$type\E$/,@email_rule)) {  
                 push(@{$changes{'email_rule'}},$type);  
             }  
         }  
         foreach my $type (@email_rule) {  
             if (!grep(/^\Q$type\E$/,@{$curr_usercreation{'email_rule'}})) {  
                 push(@{$changes{'email_rule'}},$type);  
             }  
         }  
     } else {  
         push(@{$changes{'email_rule'}},@email_rule);  
     }  
   
     my @authen_contexts = ('author','course','domain');      my @authen_contexts = ('author','course','domain');
     my @authtypes = ('int','krb4','krb5','loc');      my @authtypes = ('int','krb4','krb5','loc');
     my %authhash;      my %authhash;
Line 6993  sub modify_usercreation { Line 7557  sub modify_usercreation {
         }          }
     }      }
   
       $save_usercreate{'cancreate'}{'course'} = $cancreate{'course'}; 
       $save_usercreate{'cancreate'}{'author'} = $cancreate{'author'};
       $save_usercreate{'cancreate'}{'requestcrs'} = $cancreate{'requestcrs'};
       $save_usercreate{'id_rule'} = \@id_rule;
       $save_usercreate{'username_rule'} = \@username_rule,
       $save_usercreate{'authtypes'} = \%authhash;
   
     my %usercreation_hash =  (      my %usercreation_hash =  (
             usercreation => {          usercreation     => \%save_usercreate,
                               cancreate     => \%cancreate,      );
                               username_rule => \@username_rule,  
                               id_rule       => \@id_rule,  
                               email_rule    => \@email_rule,  
                               authtypes     => \%authhash,  
                             }  
             );  
   
     my $putresult = &Apache::lonnet::put_dom('configuration',\%usercreation_hash,      my $putresult = &Apache::lonnet::put_dom('configuration',\%usercreation_hash,
                                              $dom);                                               $dom);
   
       if ($putresult eq 'ok') {
           if (keys(%changes) > 0) {
               $resulttext = &mt('Changes made:').'<ul>';
               if (ref($changes{'cancreate'}) eq 'ARRAY') {
                   my %lt = &usercreation_types();
                   foreach my $type (@{$changes{'cancreate'}}) {
                       my $chgtext = $lt{$type}.', ';
                       if ($cancreate{$type} eq 'none') {
                           $chgtext .= &mt('creation of new users is not permitted, except by a Domain Coordinator.');
                       } elsif ($cancreate{$type} eq 'any') {
                           $chgtext .= &mt('creation of new users is permitted for both institutional and non-institutional usernames.');
                       } elsif ($cancreate{$type} eq 'official') {
                           $chgtext .= &mt('creation of new users is only permitted for institutional usernames.');
                       } elsif ($cancreate{$type} eq 'unofficial') {
                           $chgtext .= &mt('creation of new users is only permitted for non-institutional usernames.');
                       }
                       $resulttext .= '<li>'.$chgtext.'</li>';
                   }
               }
               if (ref($changes{'username_rule'}) eq 'ARRAY') {
                   my ($rules,$ruleorder) = 
                       &Apache::lonnet::inst_userrules($dom,'username');
                   my $chgtext = '<ul>';
                   foreach my $type (@username_rule) {
                       if (ref($rules->{$type}) eq 'HASH') {
                           $chgtext .= '<li>'.$rules->{$type}{'name'}.'</li>';
                       }
                   }
                   $chgtext .= '</ul>';
                   if (@username_rule > 0) {
                       $resulttext .= '<li>'.&mt('Usernames with the following formats are restricted to verified users in the institutional directory: ').$chgtext.'</li>';     
                   } else {
                       $resulttext .= '<li>'.&mt('There are now no username formats restricted to verified users in the institutional directory.').'</li>'; 
                   }
               }
               if (ref($changes{'id_rule'}) eq 'ARRAY') {
                   my ($idrules,$idruleorder) = 
                       &Apache::lonnet::inst_userrules($dom,'id');
                   my $chgtext = '<ul>';
                   foreach my $type (@id_rule) {
                       if (ref($idrules->{$type}) eq 'HASH') {
                           $chgtext .= '<li>'.$idrules->{$type}{'name'}.'</li>';
                       }
                   }
                   $chgtext .= '</ul>';
                   if (@id_rule > 0) {
                       $resulttext .= '<li>'.&mt('IDs with the following formats are restricted to verified users in the institutional directory: ').$chgtext.'</li>';
                   } else {
                       $resulttext .= '<li>'.&mt('There are now no ID formats restricted to verified users in the institutional directory.').'</li>';
                   }
               }
               my %authname = &authtype_names();
               my %context_title = &context_names();
               if (ref($changes{'authtypes'}) eq 'ARRAY') {
                   my $chgtext = '<ul>';
                   foreach my $type (@{$changes{'authtypes'}}) {
                       my @allowed;
                       $chgtext .= '<li><span class="LC_cusr_emph">'.$context_title{$type}.'</span> - '.&mt('assignable authentication types: ');
                       foreach my $auth (@authtypes) {
                           if ($authhash{$type}{$auth}) {
                               push(@allowed,$authname{$auth});
                           }
                       }
                       if (@allowed > 0) {
                           $chgtext .= join(', ',@allowed).'</li>';
                       } else {
                           $chgtext .= &mt('none').'</li>';
                       }
                   }
                   $chgtext .= '</ul>';
                   $resulttext .= '<li>'.&mt('Authentication types available for assignment to new users').'<br />'.$chgtext;
                   $resulttext .= '</li>';
               }
               $resulttext .= '</ul>';
           } else {
               $resulttext = &mt('No changes made to user creation settings');
           }
       } else {
           $resulttext = '<span class="LC_error">'.
               &mt('An error occurred: [_1]',$putresult).'</span>';
       }
       if ($warningmsg ne '') {
           $resulttext .= '<br /><span class="LC_warning">'.$warningmsg.'</span><br />';
       }
       return $resulttext;
   }
   
   sub modify_selfcreation {
       my ($dom,%domconfig) = @_;
       my ($resulttext,$warningmsg,%curr_usercreation,%curr_usermodify,%changes,%cancreate);
       my (%save_usercreate,%save_usermodify);
   #
   # Retrieve current domain configuration for self-creation of usernames from $domconfig{'usercreation'}.
   #
       if (ref($domconfig{'usercreation'}) eq 'HASH') {
           foreach my $key (keys(%{$domconfig{'usercreation'}})) {
               if ($key eq 'cancreate') {
                   if (ref($domconfig{'usercreation'}{$key}) eq 'HASH') {
                       foreach my $item (keys(%{$domconfig{'usercreation'}{$key}})) {
                           if (($item eq 'selfcreate') || ($item eq 'statustocreate') ||
                               ($item eq 'captcha') || ($item eq 'recaptchakeys') || 
                               ($item eq 'emailusername') || ($item eq 'notify')) {
                               $curr_usercreation{$key}{$item} = $domconfig{'usercreation'}{$key}{$item};
                           } else {
                               $save_usercreate{$key}{$item} = $domconfig{'usercreation'}{$key}{$item};
                           }
                       }
                   }
               } elsif ($key eq 'email_rule') {
                   $curr_usercreation{$key} = $domconfig{'usercreation'}{$key};
               } else {
                   $save_usercreate{$key} = $domconfig{'usercreation'}{$key};
               }
           }
       }
   #
   # Retrieve current domain configuration for self-creation of usernames from $domconfig{'usermodification'}.
   #
       if (ref($domconfig{'usermodification'}) eq 'HASH') {
           foreach my $key (keys(%{$domconfig{'usermodification'}})) {
               if ($key eq 'selfcreate') {
                   $curr_usermodify{$key} = $domconfig{'usermodification'}{$key};
               } else {
                   $save_usermodify{$key} = $domconfig{'usermodification'}{$key};
               }
           }
       }
   
       my @contexts = ('selfcreate');
       @{$cancreate{'selfcreate'}} = ();
       %{$cancreate{'emailusername'}} = ();
       @{$cancreate{'statustocreate'}} = ();
     my %selfcreatetypes = (      my %selfcreatetypes = (
                              sso   => 'users authenticated by institutional single sign on',                               sso   => 'users authenticated by institutional single sign on',
                              login => 'users authenticated by institutional log-in',                               login => 'users authenticated by institutional log-in',
                              email => 'users who provide a valid e-mail address for use as the username',                               email => 'users who provide a valid e-mail address for use as username (automatic creation)',
                                emailapproval => 'users who provide a valid e-mail address for use as username (queued for Domain Coordinator review)',
                           );                            );
   #
   # Populate $cancreate{'selfcreate'} array reference with types of user, for which self-creation of user accounts
   # is permitted.
   #
       foreach my $item ('login','sso','email') { 
           if ($item eq 'email') {
               if ($env{'form.cancreate_email'} eq 'email') {
                   push(@{$cancreate{'selfcreate'}},'email');
               } elsif ($env{'form.cancreate_email'} eq 'emailapproval') {
                   push(@{$cancreate{'selfcreate'}},'emailapproval');
               }
           } else {
               if ($env{'form.cancreate_'.$item}) {
                   push(@{$cancreate{'selfcreate'}},$item);
               }
           }
       }
       my (@email_rule,%userinfo,%savecaptcha);
       my ($infofields,$infotitles) = &Apache::loncommon::emailusername_info();
   #
   # Populate $cancreate{'emailusername'} hash ref with information types (if new user will provide data
   # value set to one), if self-creation with e-mail address permitted.
   #
       if (($env{'form.cancreate_email'} eq 'email') || ($env{'form.cancreate_email'} eq 'emailapproval')) {
           push(@contexts,'emailusername'); 
           map { $userinfo{$_} = 1; } &Apache::loncommon::get_env_multiple('form.canmodify_emailusername');
           if (ref($infofields) eq 'ARRAY') {
               foreach my $field (@{$infofields}) {
                   if ($userinfo{$field}) {
                       $cancreate{'emailusername'}{$field} = 1;
                   }
               }
           }
   
   #
   # Populate $cancreate{'notify'} hash ref with names of Domain Coordinators who are to be notified of
   # queued requests for self-creation of account using e-mail address as username
   #
   
           my @approvalnotify = &Apache::loncommon::get_env_multiple('form.selfcreationnotifyapproval');
           @approvalnotify = sort(@approvalnotify);
           $cancreate{'notify'}{'approval'} = join(',',@approvalnotify);
           if (ref($curr_usercreation{'cancreate'}) eq 'HASH') {
               if (ref($curr_usercreation{'cancreate'}{'notify'}) eq 'HASH') {
                   if ($curr_usercreation{'cancreate'}{'notify'}{'approval'} ne $cancreate{'notify'}{'approval'}) {
                       push(@{$changes{'cancreate'}},'notify');
                   }
               } else {
                   if ($cancreate{'notify'}{'approval'}) {
                       push(@{$changes{'cancreate'}},'notify');
                   }
               }
           } elsif ($cancreate{'notify'}{'approval'}) {
               push(@{$changes{'cancreate'}},'notify');
           }
   
   #
   # Retrieve rules (if any) governing types of e-mail address which may be used as a username
   #
           @email_rule = &Apache::loncommon::get_env_multiple('form.email_rule');
           &process_captcha('cancreate',\%changes,\%savecaptcha,$curr_usercreation{'cancreate'});
           if (ref($curr_usercreation{'email_rule'}) eq 'ARRAY') {
               if (@{$curr_usercreation{'email_rule'}} > 0) {
                   foreach my $type (@{$curr_usercreation{'email_rule'}}) {
                       if (!grep(/^\Q$type\E$/,@email_rule)) {
                           push(@{$changes{'email_rule'}},$type);
                       }
                   }
               }
               if (@email_rule > 0) {
                   foreach my $type (@email_rule) {
                       if (!grep(/^\Q$type\E$/,@{$curr_usercreation{'email_rule'}})) {
                           push(@{$changes{'email_rule'}},$type);
                       }
                   }
               }
           } elsif (@email_rule > 0) {
               push(@{$changes{'email_rule'}},@email_rule);
           }
       }
   #  
   # Check if domain default is set appropriately, if selef-creation of accounts is to be available for
   # institutional log-in.
   #
       if (grep(/^login$/,@{$cancreate{'selfcreate'}})) {
           my %domdefaults = &Apache::lonnet::get_domain_defaults($dom,1);
           if (!((($domdefaults{'auth_def'} =~/^krb/) && ($domdefaults{'auth_arg_def'} ne '')) || 
                  ($domdefaults{'auth_def'} eq 'localauth'))) {
               $warningmsg = &mt('Although account creation has been set to be available for institutional logins, currently default authentication in this domain has not been set to support this.').' '.
                             &mt('You need to set the default authentication type to Kerberos 4 or 5 (with a Kerberos domain specified), or to Local authentication, if the localauth module has been customized in your domain to authenticate institutional logins.');
           }
       }
       my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom);
       my @fields = ('lastname','firstname','middlename','generation',
                     'permanentemail','id');
       my %fieldtitles = &Apache::loncommon::personal_data_fieldtitles();
   #
   # Where usernames may created for institutional log-in and/or institutional single sign on:
   # (a) populate $cancreate{'statustocreate'} array reference with institutional status types who
   # may self-create accounts 
   # (b) populate $save_usermodify{'selfcreate'} hash reference with status types, and information fields
   # which the user may supply, if institutional data is unavailable.
   #
       if (($env{'form.cancreate_login'}) || ($env{'form.cancreate_sso'})) {
           if (ref($types) eq 'ARRAY') {
               if (@{$types} > 0) {
                   @{$cancreate{'statustocreate'}} = &Apache::loncommon::get_env_multiple('form.statustocreate');
                   push(@contexts,'statustocreate');
               } else {
                   undef($cancreate{'statustocreate'});
               } 
               push(@{$types},'default');
               $usertypes->{'default'} = $othertitle;
               foreach my $type (@{$types}) {
                   my @modifiable =  &Apache::loncommon::get_env_multiple('form.canmodify_'.$type);
                   foreach my $field (@fields) {
                       if (grep(/^\Q$field\E$/,@modifiable)) {
                           $save_usermodify{'selfcreate'}{$type}{$field} = 1;
                       } else {
                           $save_usermodify{'selfcreate'}{$type}{$field} = 0;
                       }
                   }
               }
               if (ref($curr_usermodify{'selfcreate'}) eq 'HASH') {
                   foreach my $type (@{$types}) {
                       if (ref($curr_usermodify{'selfcreate'}{$type}) eq 'HASH') {
                           foreach my $field (@fields) {
                               if ($save_usermodify{'selfcreate'}{$type}{$field} ne
                                   $curr_usermodify{'selfcreate'}{$type}{$field}) {
                                   push(@{$changes{'selfcreate'}},$type);
                                   last;
                               }
                           }
                       }
                   }
               } else {
                   foreach my $type (@{$types}) {
                       push(@{$changes{'selfcreate'}},$type);
                   }
               }
           }
       }
       foreach my $item (@contexts) {
           if (ref($curr_usercreation{'cancreate'}{$item}) eq 'ARRAY') {
               foreach my $curr (@{$curr_usercreation{'cancreate'}{$item}}) {
                   if (ref($cancreate{$item}) eq 'ARRAY') {
                       if (!grep(/^$curr$/,@{$cancreate{$item}})) {
                           if (!grep(/^$item$/,@{$changes{'cancreate'}})) {
                               push(@{$changes{'cancreate'}},$item);
                           }
                       }
                   }
               }
               if (ref($cancreate{$item}) eq 'ARRAY') {
                   foreach my $type (@{$cancreate{$item}}) {
                       if (!grep(/^$type$/,@{$curr_usercreation{'cancreate'}{$item}})) {
                           if (!grep(/^$item$/,@{$changes{'cancreate'}})) {
                               push(@{$changes{'cancreate'}},$item);
                           }
                       }
                   }
               }
           } elsif (ref($curr_usercreation{'cancreate'}{$item}) eq 'HASH') {
               if (ref($cancreate{$item}) eq 'HASH') {
                   foreach my $curr (keys(%{$curr_usercreation{'cancreate'}{$item}})) {
                       if (!$cancreate{$item}{$curr}) {
                           if (!grep(/^$item$/,@{$changes{'cancreate'}})) {
                               push(@{$changes{'cancreate'}},$item);
                           }
                       }
                   }
                   foreach my $field (keys(%{$cancreate{$item}})) {
                       if (!$curr_usercreation{'cancreate'}{$item}{$field}) {
                           print STDERR "field $field in cancreate but not in curr\n";
                           if (!grep(/^$item$/,@{$changes{'cancreate'}})) {
                               push(@{$changes{'cancreate'}},$item);
                           }
                       }
                   }
               }
           } elsif ($curr_usercreation{'cancreate'}{$item}) {
               if (ref($cancreate{$item}) eq 'ARRAY') {
                   if (!grep(/^\Q$curr_usercreation{'cancreate'}{$item}\E$/,@{$cancreate{$item}})) {
                       if (!grep(/^$item$/,@{$changes{'cancreate'}})) {
                           push(@{$changes{'cancreate'}},$item);
                       }
                   }
               } elsif (ref($cancreate{$item}) eq 'HASH') {
                   if (!$cancreate{$item}{$curr_usercreation{'cancreate'}{$item}}) {
                       if (!grep(/^$item$/,@{$changes{'cancreate'}})) {
                           push(@{$changes{'cancreate'}},$item);
                       }
                   }
               }
           } elsif ($item eq 'emailusername') {
               if (keys(%userinfo) > 0) {
                   push(@{$changes{'cancreate'}},$item);
               }
           }
       }
   #
   # Populate %save_usercreate hash with updates to self-creation configuration.
   #
       $save_usercreate{'cancreate'}{'captcha'} = $savecaptcha{'captcha'};
       $save_usercreate{'cancreate'}{'recaptchakeys'} = $savecaptcha{'recaptchakeys'};
       $save_usercreate{'cancreate'}{'selfcreate'} = $cancreate{'selfcreate'};
       if (ref($cancreate{'notify'}) eq 'HASH') {
           $save_usercreate{'cancreate'}{'notify'} = $cancreate{'notify'};
       }
       if (ref($cancreate{'statustocreate'}) eq 'ARRAY') {
           $save_usercreate{'cancreate'}{'statustocreate'} = $cancreate{'statustocreate'};
       }
       $save_usercreate{'cancreate'}{'emailusername'} = $cancreate{'emailusername'};
       $save_usercreate{'emailrule'} = \@email_rule;
   
       my %userconfig_hash = (
               usercreation     => \%save_usercreate,
               usermodification => \%save_usermodify,
       );
       my $putresult = &Apache::lonnet::put_dom('configuration',\%userconfig_hash,
                                                $dom);
   #
   # Accumulate details of changes to domain cofiguration for self-creation of usernames in $resulttext
   #
     if ($putresult eq 'ok') {      if ($putresult eq 'ok') {
         if (keys(%changes) > 0) {          if (keys(%changes) > 0) {
             $resulttext = &mt('Changes made:').'<ul>';              $resulttext = &mt('Changes made:').'<ul>';
             if (ref($changes{'cancreate'}) eq 'ARRAY') {              if (ref($changes{'cancreate'}) eq 'ARRAY') {
                 my %lt = &usercreation_types();                  my %lt = &selfcreation_types();
                 foreach my $type (@{$changes{'cancreate'}}) {                  foreach my $type (@{$changes{'cancreate'}}) {
                     my $chgtext;                      my $chgtext;
                     unless (($type eq 'statustocreate') || ($type eq 'captcha') || ($type eq 'recaptchakeys')) {  
                         $chgtext = $lt{$type}.', ';  
                     }  
                     if ($type eq 'selfcreate') {                      if ($type eq 'selfcreate') {
                         if (@{$cancreate{$type}} == 0) {                          if (@{$cancreate{$type}} == 0) {
                             $chgtext .= &mt('creation of a new user account is not permitted.');                              $chgtext .= &mt('Self creation of a new user account is not permitted.');
                         } else {                          } else {
                             $chgtext .= &mt('creation of a new account is permitted for:').'<ul>';                              $chgtext .= &mt('Self-creation of a new account is permitted for:').
                                           '<ul>';
                             foreach my $case (@{$cancreate{$type}}) {                              foreach my $case (@{$cancreate{$type}}) {
                                 $chgtext .= '<li>'.$selfcreatetypes{$case}.'</li>';                                  $chgtext .= '<li>'.$selfcreatetypes{$case}.'</li>';
                             }                              }
Line 7034  sub modify_usercreation { Line 7954  sub modify_usercreation {
                                 if (grep(/^(login|sso)$/,@{$cancreate{$type}})) {                                  if (grep(/^(login|sso)$/,@{$cancreate{$type}})) {
                                     if (ref($cancreate{'statustocreate'}) eq 'ARRAY') {                                      if (ref($cancreate{'statustocreate'}) eq 'ARRAY') {
                                         if (@{$cancreate{'statustocreate'}} == 0) {                                          if (@{$cancreate{'statustocreate'}} == 0) {
                                             $chgtext .= '<br /><span class="LC_warning">'.&mt("However, no institutional affiliations (including 'other') are currently permitted to create accounts.").'</span>';                                              $chgtext .= '<br />'.
                                                           '<span class="LC_warning">'.
                                                           &mt("However, no institutional affiliations (including 'other') are currently permitted to create accounts.").
                                                           '</span>';
                                         }                                          }
                                     }                                      }
                                 }                                  }
Line 7045  sub modify_usercreation { Line 7968  sub modify_usercreation {
                             (ref($cancreate{'statustocreate'}) eq 'ARRAY')) {                              (ref($cancreate{'statustocreate'}) eq 'ARRAY')) {
                             if (@{$cancreate{'selfcreate'}} > 0) {                              if (@{$cancreate{'selfcreate'}} > 0) {
                                 if (@{$cancreate{'statustocreate'}} == 0) {                                  if (@{$cancreate{'statustocreate'}} == 0) {
   
                                     $chgtext .= &mt("Institutional affiliations permitted to create accounts set to 'None'.");                                      $chgtext .= &mt("Institutional affiliations permitted to create accounts set to 'None'.");
                                     if (!grep(/^email$/,@{$cancreate{'selfcreate'}})) {                                      if (!grep(/^email$/,@{$cancreate{'selfcreate'}})) {
                                         $chgtext .= '<br /><span class="LC_warning">'.&mt("However, no institutional affiliations (including 'other') are currently permitted to create accounts.").'</span>';                                          $chgtext .= '<br />'.
                                     }                                                       '<span class="LC_warning">'.
                                                       &mt("However, no institutional affiliations (including 'other') are currently permitted to create accounts.").
                                                       '</span>';
                                       }
                                 } elsif (ref($usertypes) eq 'HASH') {                                  } elsif (ref($usertypes) eq 'HASH') {
                                     if (grep(/^(login|sso)$/,@{$cancreate{'selfcreate'}})) {                                      if (grep(/^(login|sso)$/,@{$cancreate{'selfcreate'}})) {
                                         $chgtext .= &mt('Creation of a new account for an institutional user is restricted to the following institutional affiliation(s):');                                          $chgtext .= &mt('Creation of a new account for an institutional user is restricted to the following institutional affiliation(s):');
Line 7066  sub modify_usercreation { Line 7991  sub modify_usercreation {
                                     }                                      }
                                     $chgtext .= '</ul>';                                      $chgtext .= '</ul>';
                                     if (!grep(/^(login|sso)$/,@{$cancreate{'selfcreate'}})) {                                      if (!grep(/^(login|sso)$/,@{$cancreate{'selfcreate'}})) {
                                         $chgtext .= '<br /><span class="LC_warning">'.&mt('However, users authenticated by institutional login/single sign on are not currently permitted to create accounts.').'</span>';                                          $chgtext .= '<br /><span class="LC_warning">'.
                                                       &mt('However, users authenticated by institutional login/single sign on are not currently permitted to create accounts.').
                                                       '</span>';
                                     }                                      }
                                 }                                  }
                             } else {                              } else {
Line 7078  sub modify_usercreation { Line 8005  sub modify_usercreation {
                             }                              }
                         }                          }
                     } elsif ($type eq 'captcha') {                      } elsif ($type eq 'captcha') {
                         if ($cancreate{$type} eq 'notused') {                          if ($savecaptcha{$type} eq 'notused') {
                             $chgtext .= &mt('No CAPTCHA validation in use for self-creation screen.');                              $chgtext .= &mt('No CAPTCHA validation in use for self-creation screen.');
                         } else {                          } else {
                             my %captchas = &captcha_phrases();                              my %captchas = &captcha_phrases();
                             if ($captchas{$cancreate{$type}}) {                              if ($captchas{$savecaptcha{$type}}) {
                                 $chgtext .= &mt("Validation for self-creation screen set to $captchas{$cancreate{$type}}.");                                  $chgtext .= &mt("Validation for self-creation screen set to $captchas{$savecaptcha{$type}}.");
                             } else {                              } else {
                                 $chgtext .= &mt('Validation for self-creation screen set to unknown type.');                                   $chgtext .= &mt('Validation for self-creation screen set to unknown type.');
                             }                              }
                         }                          }
                     } elsif ($type eq 'recaptchakeys') {                      } elsif ($type eq 'recaptchakeys') {
                         my ($privkey,$pubkey);                          my ($privkey,$pubkey);
                         if (ref($cancreate{$type}) eq 'HASH') {                          if (ref($savecaptcha{$type}) eq 'HASH') {
                             $pubkey = $cancreate{$type}{'public'};                              $pubkey = $savecaptcha{$type}{'public'};
                             $privkey = $cancreate{$type}{'private'};                              $privkey = $savecaptcha{$type}{'private'};
                         }                          }
                         $chgtext .= &mt('ReCAPTCHA keys changes').'<ul>';                          $chgtext .= &mt('ReCAPTCHA keys changes').'<ul>';
                         if (!$pubkey) {                          if (!$pubkey) {
Line 7106  sub modify_usercreation { Line 8033  sub modify_usercreation {
                             $chgtext .= '<li>'.&mt('Private key set to [_1]',$pubkey).'</li>';                              $chgtext .= '<li>'.&mt('Private key set to [_1]',$pubkey).'</li>';
                         }                          }
                         $chgtext .= '</ul>';                          $chgtext .= '</ul>';
                     } else {                      } elsif ($type eq 'emailusername') {
                         if ($cancreate{$type} eq 'none') {                          if (ref($cancreate{'emailusername'}) eq 'HASH') {
                             $chgtext .= &mt('creation of new users is not permitted, except by a Domain Coordinator.');                              if (keys(%{$cancreate{'emailusername'}}) > 0) {
                         } elsif ($cancreate{$type} eq 'any') {                                  $chgtext .= &mt('When self-creating account with e-mail as username, user will provide the following information:').
                             $chgtext .= &mt('creation of new users is permitted for both institutional and non-institutional usernames.');                                              '<ul>';
                         } elsif ($cancreate{$type} eq 'official') {                                  foreach my $field (@{$infofields}) {
                             $chgtext .= &mt('creation of new users is only permitted for institutional usernames.');                                      if ($cancreate{'emailusername'}{$field}) {
                         } elsif ($cancreate{$type} eq 'unofficial') {                                          $chgtext .= '<li>'.$infotitles->{$field}.'</li>';
                             $chgtext .= &mt('creation of new users is only permitted for non-institutional usernames.');                                      }
                                   }
                                   $chgtext .= '</ul>';
                               } else {
                                   $chgtext .= &mt('When self creating account with e-mail as username, user will not provide any information besides e-mail address');
                               }
                           }
                       } elsif ($type eq 'notify') {
                           $chgtext = &mt('No Domain Coordinators will receive notification of username requests requiring approval.');
                           if (ref($changes{'cancreate'}) eq 'ARRAY') {
                               if ((grep(/^notify$/,@{$changes{'cancreate'}})) && (ref($cancreate{'notify'}) eq 'HASH')) {
                                   if ($cancreate{'notify'}{'approval'}) {
                                       $chgtext = &mt('Notification of username requests requiring approval will be sent to: ').$cancreate{'notify'}{'approval'};
                                   }
                               }
                         }                          }
                     }                      }
                     $resulttext .= '<li>'.$chgtext.'</li>';                      if ($chgtext) {
                 }                          $resulttext .= '<li>'.$chgtext.'</li>';
             }  
             if (ref($changes{'username_rule'}) eq 'ARRAY') {  
                 my ($rules,$ruleorder) =   
                     &Apache::lonnet::inst_userrules($dom,'username');  
                 my $chgtext = '<ul>';  
                 foreach my $type (@username_rule) {  
                     if (ref($rules->{$type}) eq 'HASH') {  
                         $chgtext .= '<li>'.$rules->{$type}{'name'}.'</li>';  
                     }                      }
                 }                  }
                 $chgtext .= '</ul>';  
                 if (@username_rule > 0) {  
                     $resulttext .= '<li>'.&mt('Usernames with the following formats are restricted to verified users in the institutional directory: ').$chgtext.'</li>';       
                 } else {  
                     $resulttext .= '<li>'.&mt('There are now no username formats restricted to verified users in the institutional directory.').'</li>';   
                 }  
             }  
             if (ref($changes{'id_rule'}) eq 'ARRAY') {  
                 my ($idrules,$idruleorder) =   
                     &Apache::lonnet::inst_userrules($dom,'id');  
                 my $chgtext = '<ul>';  
                 foreach my $type (@id_rule) {  
                     if (ref($idrules->{$type}) eq 'HASH') {  
                         $chgtext .= '<li>'.$idrules->{$type}{'name'}.'</li>';  
                     }  
                 }  
                 $chgtext .= '</ul>';  
                 if (@id_rule > 0) {  
                     $resulttext .= '<li>'.&mt('IDs with the following formats are restricted to verified users in the institutional directory: ').$chgtext.'</li>';  
                 } else {  
                     $resulttext .= '<li>'.&mt('There are now no ID formats restricted to verified users in the institutional directory.').'</li>';  
                 }  
             }              }
             if (ref($changes{'email_rule'}) eq 'ARRAY') {              if (ref($changes{'email_rule'}) eq 'ARRAY') {
                 my ($emailrules,$emailruleorder) =                  my ($emailrules,$emailruleorder) =
Line 7163  sub modify_usercreation { Line 8074  sub modify_usercreation {
                 }                  }
                 $chgtext .= '</ul>';                  $chgtext .= '</ul>';
                 if (@email_rule > 0) {                  if (@email_rule > 0) {
                     $resulttext .= '<li>'.&mt('Accounts may not be created by users self-enrolling with e-mail addresses of the following types: ').$chgtext.'</li>';                      $resulttext .= '<li>'.
                                      &mt('Accounts may not be created by users self-enrolling with e-mail addresses of the following types: ').
                                          $chgtext.
                                      '</li>';
                 } else {                  } else {
                     $resulttext .= '<li>'.&mt('There are now no restrictions on e-mail addresses which may be used as a username when self-enrolling.').'</li>';                      $resulttext .= '<li>'.
                                      &mt('There are now no restrictions on e-mail addresses which may be used as a username when self-enrolling.').
                                      '</li>';
                 }                  }
             }              }
               if (ref($changes{'selfcreate'}) eq 'ARRAY') {
             my %authname = &authtype_names();                  $resulttext .= '<li>'.&mt('When self-creating institutional account:').'<ul>';
             my %context_title = &context_names();                  my %fieldtitles = &Apache::loncommon::personal_data_fieldtitles();
             if (ref($changes{'authtypes'}) eq 'ARRAY') {                  foreach my $type (@{$changes{'selfcreate'}}) {
                 my $chgtext = '<ul>';                      my $typename = $type;
                 foreach my $type (@{$changes{'authtypes'}}) {                      if (ref($usertypes) eq 'HASH') {
                     my @allowed;                          if ($usertypes->{$type} ne '') {
                     $chgtext .= '<li><span class="LC_cusr_emph">'.$context_title{$type}.'</span> - '.&mt('assignable authentication types: ');                              $typename = $usertypes->{$type};
                     foreach my $auth (@authtypes) {  
                         if ($authhash{$type}{$auth}) {  
                             push(@allowed,$authname{$auth});  
                         }                          }
                     }                      }
                     if (@allowed > 0) {                      my @modifiable;
                         $chgtext .= join(', ',@allowed).'</li>';                      $resulttext .= '<li>'.
                                       &mt('Self-creation of account by users with status: [_1]',
                                           '<span class="LC_cusr_emph">'.$typename.'</span>').
                                       ' - '.&mt('modifiable fields (if institutional data blank): ');
                       foreach my $field (@fields) {
                           if ($save_usermodify{'selfcreate'}{$type}{$field}) {
                               push(@modifiable,'<b>'.$fieldtitles{$field}.'</b>');
                           }
                       }
                       if (@modifiable > 0) {
                           $resulttext .= join(', ',@modifiable);
                     } else {                      } else {
                         $chgtext .= &mt('none').'</li>';                          $resulttext .= &mt('none');
                     }                      }
                       $resulttext .= '</li>';
                 }                  }
                 $chgtext .= '</ul>';                  $resulttext .= '</ul></li>';
                 $resulttext .= '<li>'.&mt('Authentication types available for assignment to new users').'<br />'.$chgtext;  
                 $resulttext .= '</li>';  
             }              }
             $resulttext .= '</ul>';              $resulttext .= '</ul>';
         } else {          } else {
             $resulttext = &mt('No changes made to user creation settings');              $resulttext = &mt('No changes made to self-creation settings');
         }          }
     } else {      } else {
         $resulttext = '<span class="LC_error">'.          $resulttext = '<span class="LC_error">'.
Line 7213  sub process_captcha { Line 8135  sub process_captcha {
         $newsettings->{'captcha'} = 'original';          $newsettings->{'captcha'} = 'original';
     }      }
     if ($current->{'captcha'} ne $newsettings->{'captcha'}) {      if ($current->{'captcha'} ne $newsettings->{'captcha'}) {
         if ($container eq 'cancreate') {           if ($container eq 'cancreate') {
             if (ref($changes->{'cancreate'}) eq 'ARRAY') {              if (ref($changes->{'cancreate'}) eq 'ARRAY') {
                 push(@{$changes->{'cancreate'}},'captcha');                  push(@{$changes->{'cancreate'}},'captcha');
             } elsif (!defined($changes->{'cancreate'})) {              } elsif (!defined($changes->{'cancreate'})) {
Line 7252  sub process_captcha { Line 8174  sub process_captcha {
                 $changes->{'cancreate'} = ['recaptchakeys'];                  $changes->{'cancreate'} = ['recaptchakeys'];
             }              }
         } else {          } else {
             $changes->{'recaptchakeys'} = 1;               $changes->{'recaptchakeys'} = 1;
         }          }
     }      }
     return;      return;
Line 7260  sub process_captcha { Line 8182  sub process_captcha {
   
 sub modify_usermodification {  sub modify_usermodification {
     my ($dom,%domconfig) = @_;      my ($dom,%domconfig) = @_;
     my ($resulttext,%curr_usermodification,%changes);      my ($resulttext,%curr_usermodification,%changes,%modifyhash);
     if (ref($domconfig{'usermodification'}) eq 'HASH') {      if (ref($domconfig{'usermodification'}) eq 'HASH') {
         foreach my $key (keys(%{$domconfig{'usermodification'}})) {          foreach my $key (keys(%{$domconfig{'usermodification'}})) {
             $curr_usermodification{$key} = $domconfig{'usermodification'}{$key};              if ($key eq 'selfcreate') {
                   $modifyhash{$key} = $domconfig{'usermodification'}{$key};
               } else {  
                   $curr_usermodification{$key} = $domconfig{'usermodification'}{$key};
               }
         }          }
     }      }
     my @contexts = ('author','course','selfcreate');      my @contexts = ('author','course');
     my %context_title = (      my %context_title = (
                            author => 'In author context',                             author => 'In author context',
                            course => 'In course context',                             course => 'In course context',
                            selfcreate => 'When self creating account',   
                         );                          );
     my @fields = ('lastname','firstname','middlename','generation',      my @fields = ('lastname','firstname','middlename','generation',
                   'permanentemail','id');                    'permanentemail','id');
Line 7278  sub modify_usermodification { Line 8203  sub modify_usermodification {
                   author => ['ca','aa'],                    author => ['ca','aa'],
                   course => ['st','ep','ta','in','cr'],                    course => ['st','ep','ta','in','cr'],
                 );                  );
     my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom);  
     if (ref($types) eq 'ARRAY') {  
         push(@{$types},'default');  
         $usertypes->{'default'} = $othertitle;  
     }  
     $roles{'selfcreate'} = $types;    
     my %fieldtitles = &Apache::loncommon::personal_data_fieldtitles();      my %fieldtitles = &Apache::loncommon::personal_data_fieldtitles();
     my %modifyhash;  
     foreach my $context (@contexts) {      foreach my $context (@contexts) {
         foreach my $role (@{$roles{$context}}) {          foreach my $role (@{$roles{$context}}) {
             my @modifiable =  &Apache::loncommon::get_env_multiple('form.canmodify_'.$role);              my @modifiable =  &Apache::loncommon::get_env_multiple('form.canmodify_'.$role);
Line 7317  sub modify_usermodification { Line 8235  sub modify_usermodification {
             }              }
         }          }
     }      }
   # FIXME need to ensure selfcreate stuff is preserved 
     my %usermodification_hash =  (      my %usermodification_hash =  (
                                    usermodification => \%modifyhash,                                     usermodification => \%modifyhash,
                                  );                                   );
Line 7331  sub modify_usermodification { Line 8250  sub modify_usermodification {
                     if (ref($changes{$context}) eq 'ARRAY') {                      if (ref($changes{$context}) eq 'ARRAY') {
                         foreach my $role (@{$changes{$context}}) {                          foreach my $role (@{$changes{$context}}) {
                             my $rolename;                              my $rolename;
                             if ($context eq 'selfcreate') {                              if ($role eq 'cr') {
                                 $rolename = $role;                                  $rolename = &mt('Custom');
                                 if (ref($usertypes) eq 'HASH') {  
                                     if ($usertypes->{$role} ne '') {  
                                         $rolename = $usertypes->{$role};  
                                     }  
                                 }  
                             } else {                              } else {
                                 if ($role eq 'cr') {                                  $rolename = &Apache::lonnet::plaintext($role);
                                     $rolename = &mt('Custom');  
                                 } else {  
                                     $rolename = &Apache::lonnet::plaintext($role);  
                                 }  
                             }                              }
                             my @modifiable;                              my @modifiable;
                             if ($context eq 'selfcreate') {                              $resulttext .= '<li><span class="LC_cusr_emph">'.&mt('Target user with [_1] role',$rolename).'</span> - '.&mt('modifiable fields: ');
                                 $resulttext .= '<li><span class="LC_cusr_emph">'.&mt('Self-creation of account by users with status: [_1]',$rolename).'</span> - '.&mt('modifiable fields (if institutional data blank): ');  
                             } else {  
                                 $resulttext .= '<li><span class="LC_cusr_emph">'.&mt('Target user with [_1] role',$rolename).'</span> - '.&mt('modifiable fields: ');  
                             }  
                             foreach my $field (@fields) {                              foreach my $field (@fields) {
                                 if ($modifyhash{$context}{$role}{$field}) {                                  if ($modifyhash{$context}{$role}{$field}) {
                                     push(@modifiable,$fieldtitles{$field});                                      push(@modifiable,$fieldtitles{$field});
Line 7379  sub modify_usermodification { Line 8285  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','portal_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) {
Line 7441  sub modify_defaults { Line 8347  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 7464  sub modify_defaults { Line 8370  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 7486  sub modify_defaults { Line 8404  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 7547  sub modify_scantron { Line 8465  sub modify_scantron {
                 }                  }
                 $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 bubblesheet format file');                  $resulttext = &mt('No changes made to bubblesheet format file');
             }              }
Line 7937  sub modify_helpsettings { Line 8858  sub modify_helpsettings {
                     $changes{$item} = 1;                      $changes{$item} = 1;
                 }                  }
             }              }
             if (($env{'form.'.$item} eq '0') || ($env{'form.'.$item} eq '1')) {               if (($env{'form.'.$item} eq '0') || ($env{'form.'.$item} eq '1')) {
                 $helphash{'helpsettings'}{$item} = $env{'form.'.$item};                  $helphash{'helpsettings'}{$item} = $env{'form.'.$item};
             }              }
         }          }
Line 7970  sub modify_helpsettings { Line 8891  sub modify_helpsettings {
 }  }
   
 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 @toggles = ('canuse_pdfforms');      my @toggles = ('canuse_pdfforms');
     my @numbers = ('anonsurvey_threshold','uploadquota_official','uploadquota_unofficial',      my @numbers = ('anonsurvey_threshold','uploadquota_official','uploadquota_unofficial',
                    'uploadquota_community');                     'uploadquota_community','uploadquota_textbook');
     my @types = ('official','unofficial','community');      my @types = ('official','unofficial','community','textbook');
     my %staticdefaults = (      my %staticdefaults = (
                            anonsurvey_threshold => 10,                             anonsurvey_threshold => 10,
                            uploadquota          => 500,                             uploadquota          => 500,
Line 8011  sub modify_coursedefaults { Line 8932  sub modify_coursedefaults {
         }          }
         foreach my $item (@numbers) {          foreach my $item (@numbers) {
             my ($currdef,$newdef);              my ($currdef,$newdef);
             my $newdef = $env{'form.'.$item};              $newdef = $env{'form.'.$item};
             if ($item eq 'anonsurvey_threshold') {              if ($item eq 'anonsurvey_threshold') {
                 $currdef = $domconfig{'coursedefaults'}{$item};                  $currdef = $domconfig{'coursedefaults'}{$item};
                 $newdef =~ s/\D//g;                  $newdef =~ s/\D//g;
Line 8041  sub modify_coursedefaults { Line 8962  sub modify_coursedefaults {
             }              }
         }          }
         my $officialcreds = $env{'form.official_credits'};          my $officialcreds = $env{'form.official_credits'};
         $officialcreds =~ s/^[^\d\.]//g;          $officialcreds =~ s/[^\d.]+//g;
         my $unofficialcreds = $env{'form.unofficial_credits'};          my $unofficialcreds = $env{'form.unofficial_credits'};
         $unofficialcreds =~ s/^[^\d\.]//g;          $unofficialcreds =~ s/[^\d.]+//g;
           my $textbookcreds = $env{'form.textbook_credits'};
           $textbookcreds =~ s/[^\d.]+//g;
         if (ref($domconfig{'coursedefaults'}{'coursecredits'} ne 'HASH') &&          if (ref($domconfig{'coursedefaults'}{'coursecredits'} ne 'HASH') &&
                 ($env{'form.coursecredits'} eq '1')) {                  ($env{'form.coursecredits'} eq '1')) {
                 $changes{'coursecredits'} = 1;                  $changes{'coursecredits'} = 1;
         } else {          } else {
             if (($domconfig{'coursedefaults'}{'coursecredits'}{'official'} ne $officialcreds)  ||              if (($domconfig{'coursedefaults'}{'coursecredits'}{'official'} ne $officialcreds)  ||
                 ($domconfig{'coursedefaults'}{'coursecredits'}{'unofficial'} ne $unofficialcreds)) {                  ($domconfig{'coursedefaults'}{'coursecredits'}{'unofficial'} ne $unofficialcreds) ||
                   ($domconfig{'coursedefaults'}{'coursecredits'}{'textbook'} ne $textbookcreds)) {
                 $changes{'coursecredits'} = 1;                  $changes{'coursecredits'} = 1;
             }              }
         }          }
         $defaultshash{'coursedefaults'}{'coursecredits'} = {          $defaultshash{'coursedefaults'}{'coursecredits'} = {
             official   => $officialcreds,              official   => $officialcreds,
             unofficial => $unofficialcreds,              unofficial => $unofficialcreds,
               textbook   => $textbookcreds,
         }          }
     }      }
     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') {
         my %domdefaults;  
         if (keys(%changes) > 0) {          if (keys(%changes) > 0) {
               my %domdefaults = &Apache::lonnet::get_domain_defaults($dom,1);
             if (($changes{'canuse_pdfforms'}) || ($changes{'coursecredits'}) || ($changes{'uploadquota'})) {              if (($changes{'canuse_pdfforms'}) || ($changes{'coursecredits'}) || ($changes{'uploadquota'})) {
                 %domdefaults = &Apache::lonnet::get_domain_defaults($dom);  
                 if ($changes{'canuse_pdfforms'}) {                  if ($changes{'canuse_pdfforms'}) {
                     $domdefaults{'canuse_pdfforms'}=$defaultshash{'coursedefaults'}{'canuse_pdfforms'};                      $domdefaults{'canuse_pdfforms'}=$defaultshash{'coursedefaults'}{'canuse_pdfforms'};
                 }                  }
Line 8074  sub modify_coursedefaults { Line 8998  sub modify_coursedefaults {
                             $defaultshash{'coursedefaults'}{'coursecredits'}{'official'};                              $defaultshash{'coursedefaults'}{'coursecredits'}{'official'};
                         $domdefaults{'unofficialcredits'} =                          $domdefaults{'unofficialcredits'} =
                             $defaultshash{'coursedefaults'}{'coursecredits'}{'unofficial'};                              $defaultshash{'coursedefaults'}{'coursecredits'}{'unofficial'};
                           $domdefaults{'textbookcredits'} =
                               $domdefaults{'coursedefaults'}{'coursecredits'}{'textbook'};
                     }                      }
                 }                  }
                 if ($changes{'uploadquota'}) {                  if ($changes{'uploadquota'}) {
Line 8085  sub modify_coursedefaults { Line 9011  sub modify_coursedefaults {
                 }                  }
                 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 8101  sub modify_coursedefaults { Line 9030  sub modify_coursedefaults {
                         $resulttext .= '<li>'.&mt('Default quota for content uploaded to a course/community via Course Editor set as follows:').'<ul>'.                          $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('Official courses: [_1] MB','<b>'.$defaultshash{'coursedefaults'}{'uploadquota'}{'official'}.'</b>').'</li>'.
                                        '<li>'.&mt('Unofficial courses: [_1] MB','<b>'.$defaultshash{'coursedefaults'}{'uploadquota'}{'unofficial'}.'</b>').'</li>'.                                         '<li>'.&mt('Unofficial courses: [_1] MB','<b>'.$defaultshash{'coursedefaults'}{'uploadquota'}{'unofficial'}.'</b>').'</li>'.
                                          '<li>'.&mt('Textbook courses: [_1] MB','<b>'.$defaultshash{'coursedefaults'}{'uploadquota'}{'textbook'}.'</b>').'</li>'.
   
                                        '<li>'.&mt('Communities: [_1] MB','<b>'.$defaultshash{'coursedefaults'}{'uploadquota'}{'community'}.'</b>').'</li>'.                                         '<li>'.&mt('Communities: [_1] MB','<b>'.$defaultshash{'coursedefaults'}{'uploadquota'}{'community'}.'</b>').'</li>'.
                                        '</ul>'.                                         '</ul>'.
                                        '</li>';                                         '</li>';
Line 8110  sub modify_coursedefaults { Line 9041  sub modify_coursedefaults {
                 } elsif ($item eq 'coursecredits') {                  } elsif ($item eq 'coursecredits') {
                     if (ref($defaultshash{'coursedefaults'}{'coursecredits'}) eq 'HASH') {                      if (ref($defaultshash{'coursedefaults'}{'coursecredits'}) eq 'HASH') {
                         if (($domdefaults{'officialcredits'} eq '') &&                          if (($domdefaults{'officialcredits'} eq '') &&
                             ($domdefaults{'unofficialcredits'} eq '')) {                              ($domdefaults{'unofficialcredits'} eq '') &&
                               ($domdefaults{'textbookcredits'} eq '')) {
                             $resulttext .= '<li>'.&mt('Student credits not in use for courses in this domain').'</li>';                              $resulttext .= '<li>'.&mt('Student credits not in use for courses in this domain').'</li>';
                         } else {                          } else {
                             $resulttext .= '<li>'.&mt('Student credits can be set per course by a Domain Coordinator, with the following defaults applying:').'<ul>'.                              $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('Official courses: [_1]',$defaultshash{'coursedefaults'}{'coursecredits'}{'official'}).'</li>'.
                                            '<li>'.&mt('Unofficial courses: [_1]',$defaultshash{'coursedefaults'}{'coursecredits'}{'unofficial'}).'</li>'.                                             '<li>'.&mt('Unofficial courses: [_1]',$defaultshash{'coursedefaults'}{'coursecredits'}{'unofficial'}).'</li>'.
                                              '<li>'.&mt('Textbook courses: [_1]',$defaultshash{'coursedefaults'}{'coursecredits'}{'textbook'}).'</li>'.
                                            '</ul>'.                                             '</ul>'.
                                            '</li>';                                             '</li>';
                         }                          }
Line 8136  sub modify_coursedefaults { Line 9069  sub modify_coursedefaults {
 }  }
   
 sub modify_usersessions {  sub modify_usersessions {
     my ($dom,%domconfig) = @_;      my ($dom,$lastactref,%domconfig) = @_;
     my @hostingtypes = ('version','excludedomain','includedomain');      my @hostingtypes = ('version','excludedomain','includedomain');
     my @offloadtypes = ('primary','default');      my @offloadtypes = ('primary','default');
     my %types = (      my %types = (
Line 8153  sub modify_usersessions { Line 9086  sub modify_usersessions {
     foreach my $prefix (@prefixes) {      foreach my $prefix (@prefixes) {
         $defaultshash{'usersessions'}{$prefix} = {};          $defaultshash{'usersessions'}{$prefix} = {};
     }      }
     my %domdefaults = &Apache::lonnet::get_domain_defaults($dom);      my %domdefaults = &Apache::lonnet::get_domain_defaults($dom,1);
     my $resulttext;      my $resulttext;
     my %iphost = &Apache::lonnet::get_iphost();      my %iphost = &Apache::lonnet::get_iphost();
     foreach my $prefix (@prefixes) {      foreach my $prefix (@prefixes) {
Line 8329  sub modify_usersessions { Line 9262  sub modify_usersessions {
             }              }
             my $cachetime = 24*60*60;              my $cachetime = 24*60*60;
             &Apache::lonnet::do_cache_new('domdefaults',$dom,\%domdefaults,$cachetime);              &Apache::lonnet::do_cache_new('domdefaults',$dom,\%domdefaults,$cachetime);
               if (ref($lastactref) eq 'HASH') {
                   $lastactref->{'domdefaults'} = 1;
               }
             if (keys(%changes) > 0) {              if (keys(%changes) > 0) {
                 my %lt = &usersession_titles();                  my %lt = &usersession_titles();
                 $resulttext = &mt('Changes made:').'<ul>';                  $resulttext = &mt('Changes made:').'<ul>';
Line 8340  sub modify_usersessions { Line 9276  sub modify_usersessions {
                                 foreach my $lonhost (sort(keys(%{$changes{$prefix}}))) {                                  foreach my $lonhost (sort(keys(%{$changes{$prefix}}))) {
                                     $resulttext .= '<li><b>'.$lonhost.'</b> ';                                      $resulttext .= '<li><b>'.$lonhost.'</b> ';
                                     my $lonhostdom = &Apache::lonnet::host_domain($lonhost);                                      my $lonhostdom = &Apache::lonnet::host_domain($lonhost);
                                     &Apache::lonnet::remote_devalidate_cache($lonhost,'spares',$lonhostdom);                                      my $cachekey = &escape('spares').':'.&escape($lonhostdom);
                                       &Apache::lonnet::remote_devalidate_cache($lonhost,[$cachekey]);
                                     if (ref($changes{$prefix}{$lonhost}) eq 'HASH') {                                      if (ref($changes{$prefix}{$lonhost}) eq 'HASH') {
                                         foreach my $type (@{$types{$prefix}}) {                                          foreach my $type (@{$types{$prefix}}) {
                                             if ($changes{$prefix}{$lonhost}{$type}) {                                              if ($changes{$prefix}{$lonhost}{$type}) {
Line 8430  sub modify_loadbalancing { Line 9367  sub modify_loadbalancing {
         if ($balancer eq '') {          if ($balancer eq '') {
             next;              next;
         }          }
         if (!exists($servers{$balancer})) {           if (!exists($servers{$balancer})) {
             if (exists($currbalancer{$balancer})) {              if (exists($currbalancer{$balancer})) {
                 push(@{$changes{'delete'}},$balancer);                  push(@{$changes{'delete'}},$balancer);
             }              }
Line 8481  sub modify_loadbalancing { Line 9418  sub modify_loadbalancing {
             }              }
         } else {          } else {
             if (ref($defaultshash{'loadbalancing'}{$balancer}) eq 'HASH') {              if (ref($defaultshash{'loadbalancing'}{$balancer}) eq 'HASH') {
                 foreach my $sparetype (@sparestypes) {                   foreach my $sparetype (@sparestypes) {
                     if (ref($defaultshash{'loadbalancing'}{$balancer}{'targets'}{$sparetype}) eq 'ARRAY') {                      if (ref($defaultshash{'loadbalancing'}{$balancer}{'targets'}{$sparetype}) eq 'ARRAY') {
                         if (@{$defaultshash{'loadbalancing'}{$balancer}{'targets'}{$sparetype}} > 0) {                          if (@{$defaultshash{'loadbalancing'}{$balancer}{'targets'}{$sparetype}} > 0) {
                             $changes{'curr'}{$balancer}{'targets'} = 1;                              $changes{'curr'}{$balancer}{'targets'} = 1;
                         }                          }
                     }                      }
                 }                  }
             }                }
         }          }
         my $ishomedom;          my $ishomedom;
         if (&Apache::lonnet::host_domain($balancer) eq $dom) {          if (&Apache::lonnet::host_domain($balancer) eq $dom) {
Line 8497  sub modify_loadbalancing { Line 9434  sub modify_loadbalancing {
         if (ref($alltypes) eq 'ARRAY') {          if (ref($alltypes) eq 'ARRAY') {
             foreach my $type (@{$alltypes}) {              foreach my $type (@{$alltypes}) {
                 my $rule;                  my $rule;
                 unless ((($type eq '_LC_external') || ($type eq '_LC_internetdom')) &&                   unless ((($type eq '_LC_external') || ($type eq '_LC_internetdom')) &&
                          (!$ishomedom)) {                           (!$ishomedom)) {
                     $rule = $env{'form.loadbalancing_rules_'.$i.'_'.$type};                      $rule = $env{'form.loadbalancing_rules_'.$i.'_'.$type};
                 }                  }
Line 8522  sub modify_loadbalancing { Line 9459  sub modify_loadbalancing {
         }          }
         my $putresult = &Apache::lonnet::put_dom('configuration',          my $putresult = &Apache::lonnet::put_dom('configuration',
                                                  \%defaultshash,$dom);                                                   \%defaultshash,$dom);
    
         if ($putresult eq 'ok') {          if ($putresult eq 'ok') {
             if (keys(%changes) > 0) {              if (keys(%changes) > 0) {
                 if (ref($changes{'delete'}) eq 'ARRAY') {                  if (ref($changes{'delete'}) eq 'ARRAY') {
                     foreach my $balancer (sort(@{$changes{'delete'}})) {                      foreach my $balancer (sort(@{$changes{'delete'}})) {
                         $resulttext .= '<li>'.&mt('Load Balancing discontinued for: [_1]',$balancer).'</li>';                          $resulttext .= '<li>'.&mt('Load Balancing discontinued for: [_1]',$balancer).'</li>';
                         &Apache::lonnet::remote_devalidate_cache($balancer,'loadbalancing',$dom);                          my $cachekey = &escape('loadbalancing').':'.&escape($dom);
                           &Apache::lonnet::remote_devalidate_cache($balancer,[$cachekey]);
                     }                      }
                 }                  }
                 if (ref($changes{'add'}) eq 'ARRAY') {                  if (ref($changes{'add'}) eq 'ARRAY') {
                     foreach my $balancer (sort(@{$changes{'add'}})) {                         foreach my $balancer (sort(@{$changes{'add'}})) {
                         $resulttext .= '<li>'.&mt('Load Balancing enabled for: [_1]',$balancer);                          $resulttext .= '<li>'.&mt('Load Balancing enabled for: [_1]',$balancer);
                     }                      }
                 }                  }
Line 8573  sub modify_loadbalancing { Line 9510  sub modify_loadbalancing {
                                         my $balancetext;                                          my $balancetext;
                                         if ($rule eq '') {                                          if ($rule eq '') {
                                             $balancetext =  $ruletitles{'default'};                                              $balancetext =  $ruletitles{'default'};
                                         } elsif (($rule eq 'homeserver') || ($rule eq 'externalbalancer')) {                                          } elsif (($rule eq 'homeserver') || ($rule eq 'externalbalancer') ||
                                                    ($rule eq 'balancer') || ($rule eq 'offloadedto')) {
                                             $balancetext =  $ruletitles{$rule};                                              $balancetext =  $ruletitles{$rule};
                                         } else {                                          } else {
                                             $balancetext = &mt('offload to [_1]',$defaultshash{'loadbalancing'}{$balancer}{'rules'}{$type});                                              $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>';                                               $resulttext .= '<li>'.&mt('Load Balancer: [_1] -- balancing for [_2] set to - "[_3]"',$balancer,$titles->{$type},$balancetext).'</li>';
                                     }                                      }
                                 }                                  }
                             }                              }
                         }                          }
                         &Apache::lonnet::remote_devalidate_cache($balancer,'loadbalancing',$dom);                          my $cachekey = &escape('loadbalancing').':'.&escape($dom);
                           &Apache::lonnet::remote_devalidate_cache($balancer,[$cachekey]);
                     }                      }
                 }                  }
                 if ($resulttext ne '') {                  if ($resulttext ne '') {
Line 8671  sub active_dc_picker { Line 9610  sub active_dc_picker {
         }          }
     }      }
     @domcoord = sort(@domcoord);      @domcoord = sort(@domcoord);
     my $numdcs = scalar(@domcoord);       my $numdcs = scalar(@domcoord);
     my $rows = 0;      my $rows = 0;
     my $table;      my $table;
     if ($numdcs > 1) {      if ($numdcs > 1) {
Line 8715  sub active_dc_picker { Line 9654  sub active_dc_picker {
                       '<input type="'.$inputtype.'" name="'.$name.'"'.                        '<input type="'.$inputtype.'" name="'.$name.'"'.
                       ' value="'.$domcoord[$i].'"'.$check.' />'.$user;                        ' value="'.$domcoord[$i].'"'.$check.' />'.$user;
             if ($user ne $dcname.':'.$dcdom) {              if ($user ne $dcname.':'.$dcdom) {
                 $table .=  ' ('.$dcname.':'.$dcdom.')'.                  $table .=  ' ('.$dcname.':'.$dcdom.')';
                            '</label></span></td>';  
             }              }
               $table .= '</label></span></td>';
         }          }
         $table .= '</tr></table>';          $table .= '</tr></table>';
     } elsif ($numdcs == 1) {      } elsif ($numdcs == 1) {
           my ($dcname,$dcdom) = split(':',$domcoord[0]);
           my $user = &Apache::loncommon::plainname($dcname,$dcdom);
         if ($inputtype eq 'radio') {          if ($inputtype eq 'radio') {
             $table .= '<input type="hidden" name="'.$name.'" value="'.$domcoord[0].'" />';              $table .= '<input type="hidden" name="'.$name.'" value="'.$domcoord[0].'" />'.$user;
               if ($user ne $dcname.':'.$dcdom) {
                   $table .=  ' ('.$dcname.':'.$dcdom.')';
               }
         } else {          } else {
             my $check;              my $check;
             if (exists($currhash{$domcoord[0]})) {              if (exists($currhash{$domcoord[0]})) {
                 $check = ' checked="checked"';                  $check = ' checked="checked"';
             }              }
             $table .= '<input type="checkbox" name="'.$name.'" '.              $table .= '<span class="LC_nobreak"><label>'.
                       'value="'.$domcoord[0].'"'.$check.' />';                        '<input type="checkbox" name="'.$name.'" '.
                         'value="'.$domcoord[0].'"'.$check.' />'.$user;
               if ($user ne $dcname.':'.$dcdom) {
                   $table .=  ' ('.$dcname.':'.$dcdom.')';
               }
               $table .= '</label></span>';
             $rows ++;              $rows ++;
         }          }
     }      }
Line 8805  sub lonbalance_targets_js { Line 9754  sub lonbalance_targets_js {
     }      }
     &get_loadbalancers_config($servers,\%existing,\%currbalancer,      &get_loadbalancers_config($servers,\%existing,\%currbalancer,
                               \%currtargets,\%currrules);                                \%currtargets,\%currrules);
     my $balancers = join("','",sort(keys(%currbalancer)));       my $balancers = join("','",sort(keys(%currbalancer)));
     return <<"END";      return <<"END";
   
 <script type="text/javascript">  <script type="text/javascript">
Line 8876  function showSpares(balancer,ishomedom,b Line 9825  function showSpares(balancer,ishomedom,b
             } else {              } else {
                 document.getElementById('balanceruletitle_'+balnum+'_'+insttypes[k]).style.display='none';                  document.getElementById('balanceruletitle_'+balnum+'_'+insttypes[k]).style.display='none';
                 document.getElementById('balancerule_'+balnum+'_'+insttypes[k]).style.display='none';                  document.getElementById('balancerule_'+balnum+'_'+insttypes[k]).style.display='none';
   
             }              }
         } else {          } else {
             document.getElementById('balanceruletitle_'+balnum+'_'+insttypes[k]).style.display='block';              document.getElementById('balanceruletitle_'+balnum+'_'+insttypes[k]).style.display='block';
Line 8888  function showSpares(balancer,ishomedom,b Line 9836  function showSpares(balancer,ishomedom,b
             var item = document.getElementById('loadbalancing_singleserver_'+balnum+'_'+insttypes[k]);              var item = document.getElementById('loadbalancing_singleserver_'+balnum+'_'+insttypes[k]);
             item.options.length = 0;              item.options.length = 0;
             item.options[0] = new Option("","",true,true);              item.options[0] = new Option("","",true,true);
             var idx = 0;                var idx = 0;
             for (var m=0; m<alltargets.length; m++) {              for (var m=0; m<alltargets.length; m++) {
                 if ((currBalancers.indexOf(alltargets[m]) == -1) && (alltargets[m] != balancer)) {                  if ((currBalancers.indexOf(alltargets[m]) == -1) && (alltargets[m] != balancer)) {
                     idx ++;                      idx ++;
                     item.options[idx] = new Option(alltargets[m],alltargets[m],false,false);                      item.options[idx] = new Option(alltargets[m],alltargets[m],false,false);
                       
                 }                  }
             }              }
         }          }
Line 9306  sub captcha_phrases { Line 10253  sub captcha_phrases {
     );      );
 }  }
   
   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.201  
changed lines
  Added in v.1.224


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