Diff for /loncom/interface/domainprefs.pm between versions 1.160.6.84.2.5 and 1.280

version 1.160.6.84.2.5, 2017/10/17 12:58:53 version 1.280, 2016/09/16 23:42:58
Line 19 Line 19
 #  #
 # You should have received a copy of the GNU General Public License  # You should have received a copy of the GNU General Public License
 # along with LON-CAPA; if not, write to the Free Software  # along with LON-CAPA; if not, write to the Free Software
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA  # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA#
 #  
 # /home/httpd/html/adm/gpl.txt  # /home/httpd/html/adm/gpl.txt
 #  #
 # http://www.lon-capa.org/  # http://www.lon-capa.org/
 #  #
 #  #
 ###############################################################  ###############################################################
 ###############################################################  ##############################################################
   
 =pod  =pod
   
Line 104  $datatable  - HTML containing form eleme Line 103  $datatable  - HTML containing form eleme
   
 In the case of course requests, radio buttons are displayed for each institutional  In the case of course requests, radio buttons are displayed for each institutional
 affiliate type (and also default, and _LC_adv) for each of the course types   affiliate type (and also default, and _LC_adv) for each of the course types 
 (official, unofficial, community, and textbook).  In each case the radio buttons   (official, unofficial, community, textbook, and placement).  
 allow the selection of one of four values:  In each case the radio buttons allow the selection of one of four values:  
   
 0, approval, validate, autolimit=N (where N is blank, or a positive integer).  0, approval, validate, autolimit=N (where N is blank, or a positive integer).
 which have the following effects:  which have the following effects:
Line 170  use Apache::loncoursequeueadmin(); Line 169  use Apache::loncoursequeueadmin();
 use LONCAPA qw(:DEFAULT :match);  use LONCAPA qw(:DEFAULT :match);
 use LONCAPA::Enrollment;  use LONCAPA::Enrollment;
 use LONCAPA::lonauthcgi();  use LONCAPA::lonauthcgi();
   use LONCAPA::SSL;
 use File::Copy;  use File::Copy;
 use Locale::Language;  use Locale::Language;
 use DateTime::TimeZone;  use DateTime::TimeZone;
 use DateTime::Locale;  use DateTime::Locale;
   use Time::HiRes qw( sleep );
   
 my $registered_cleanup;  my $registered_cleanup;
 my $modified_urls;  my $modified_urls;
Line 217  sub handler { Line 218  sub handler {
                 'serverstatuses','requestcourses','helpsettings',                  'serverstatuses','requestcourses','helpsettings',
                 'coursedefaults','usersessions','loadbalancing',                  'coursedefaults','usersessions','loadbalancing',
                 'requestauthor','selfenrollment','inststatus',                  'requestauthor','selfenrollment','inststatus',
                 'ltitools'],$dom);                  'ltitools','ssl','trust'],$dom);
     if (ref($domconfig{'ltitools'}) eq 'HASH') {  
         my %encconfig =  
             &Apache::lonnet::get_dom('encconfig',['ltitools'],$dom);  
         if (ref($encconfig{'ltitools'}) eq 'HASH') {  
             foreach my $id (keys(%{$domconfig{'ltitools'}})) {  
                 if (ref($domconfig{'ltitools'}{$id}) eq 'HASH') {  
                     foreach my $item ('key','secret') {  
                         $domconfig{'ltitools'}{$id}{$item} = $encconfig{'ltitools'}{$id}{$item};  
                     }  
                 }  
             }  
         }  
     }  
     my @prefs_order = ('rolecolors','login','defaults','quotas','autoenroll',      my @prefs_order = ('rolecolors','login','defaults','quotas','autoenroll',
                        'autoupdate','autocreate','directorysrch','contacts',                         'autoupdate','autocreate','directorysrch','contacts',
                        'usercreation','selfcreation','usermodification','scantron',                         'usercreation','selfcreation','usermodification','scantron',
                        'requestcourses','requestauthor','coursecategories',                         'requestcourses','requestauthor','coursecategories',
                        'serverstatuses','helpsettings','coursedefaults',                         'serverstatuses','helpsettings','coursedefaults',
                        'ltitools','selfenrollment','usersessions');                         'ltitools','selfenrollment','usersessions','ssl','trust');
     my %existing;      my %existing;
     if (ref($domconfig{'loadbalancing'}) eq 'HASH') {      if (ref($domconfig{'loadbalancing'}) eq 'HASH') {
         %existing = %{$domconfig{'loadbalancing'}};          %existing = %{$domconfig{'loadbalancing'}};
Line 276  sub handler { Line 264  sub handler {
                       help => 'Domain_Configuration_LangTZAuth',                        help => 'Domain_Configuration_LangTZAuth',
                       header => [{col1 => 'Setting',                        header => [{col1 => 'Setting',
                                   col2 => 'Value'},                                    col2 => 'Value'},
                                  {col1 => 'Internal Authentication',  
                                   col2 => 'Value'},  
                                  {col1 => 'Institutional user types',                                   {col1 => 'Institutional user types',
                                   col2 => 'Assignable to e-mail usernames'}],                                    col2 => 'Assignable to e-mail usernames'}],
                       print => \&print_defaults,                        print => \&print_defaults,
Line 331  sub handler { Line 317  sub handler {
                     modify => \&modify_directorysrch,                      modify => \&modify_directorysrch,
                   },                    },
         'contacts' =>          'contacts' =>
                   { text => 'E-mail addresses and helpform',                    { text => 'Contact Information',
                     help => 'Domain_Configuration_Contact_Info',                      help => 'Domain_Configuration_Contact_Info',
                     header => [{col1 => 'Default e-mail addresses',                      header => [{col1 => 'Setting',
                                 col2 => 'Value',},                                  col2 => 'Value',}],
                                {col1 => 'Recipient(s) for notifications',  
                                 col2 => 'Value',},  
                                {col1 => 'Ask helpdesk form settings',  
                                 col2 => 'Value',},],  
                     print => \&print_contacts,                      print => \&print_contacts,
                     modify => \&modify_contacts,                      modify => \&modify_contacts,
                   },                    },
Line 435  sub handler { Line 417  sub handler {
                   modify => \&modify_serverstatuses,                    modify => \&modify_serverstatuses,
                  },                   },
         'helpsettings' =>          'helpsettings' =>
                  {text   => 'Support settings',                   {text   => 'Help page settings',
                   help   => 'Domain_Configuration_Help_Settings',                    help   => 'Domain_Configuration_Help_Settings',
                   header => [{col1 => 'Help Page Settings (logged-in users)',                    header => [{col1 => 'Help Settings (logged-in users)',
                               col2 => 'Value'},                                col2 => 'Value'}],
                              {col1 => 'Helpdesk Roles',  
                               col2 => 'Settings'},],  
                   print  => \&print_helpsettings,                    print  => \&print_helpsettings,
                   modify => \&modify_helpsettings,                    modify => \&modify_helpsettings,
                  },                   },
Line 466  sub handler { Line 446  sub handler {
                   print => \&print_selfenrollment,                    print => \&print_selfenrollment,
                   modify => \&modify_selfenrollment,                    modify => \&modify_selfenrollment,
                  },                   },
           'privacy' => 
                    {text   => 'User Privacy',
                     help   => 'Domain_Configuration_User_Privacy',
                     header => [{col1 => 'Setting',
                                 col2 => 'Value',}],
                     print => \&print_privacy,
                     modify => \&modify_privacy,
                    },
         'usersessions' =>          'usersessions' =>
                  {text  => 'User session hosting/offloading',                   {text  => 'User session hosting/offloading',
                   help  => 'Domain_Configuration_User_Sessions',                    help  => 'Domain_Configuration_User_Sessions',
Line 489  sub handler { Line 477  sub handler {
                   print => \&print_loadbalancing,                    print => \&print_loadbalancing,
                   modify => \&modify_loadbalancing,                    modify => \&modify_loadbalancing,
                  },                   },
         'ltitools' =>          'ltitools' => 
                  {text => 'External Tools (LTI)',                   {text => 'External Tools (LTI)',
                   help => 'Domain_Configuration_LTI_Tools',                    help => 'Domain_configuration_LTI_Tools',
                   header => [{col1 => 'Setting',                    header => [{col1 => 'Setting',
                               col2 => 'Value',}],                                col2 => 'Value',}],
                   print => \&print_ltitools,                    print => \&print_ltitools,
                   modify => \&modify_ltitools,                    modify => \&modify_ltitools,
                  },                   },
           'ssl' =>
                    {text  => 'LON-CAPA Network (SSL)',
                     help  => 'Domain_Configuration_Network_SSL',
                     header => [{col1 => 'Server',
                                 col2 => 'Certificate Status'},
                                {col1 => 'Connections to other servers',
                                 col2 => 'Rules'},
                                {col1 => "Replicating domain's published content",
                                 col2 => 'Rules'}],
                     print => \&print_ssl,
                     modify => \&modify_ssl,
                    },
           'trust' =>
                    {text   => 'Trust Settings',
                     help   => 'Domain_Configuration_Trust',
                     header => [{col1 => "Access to this domain's content by others",
                                 col2 => 'Rules'},
                                {col1 => "Access to other domain's content by this domain",
                                 col2 => 'Rules'},
                                {col1 => "Enrollment in this domain's courses by others",
                                 col2 => 'Rules',},
                                {col1 => "Co-author roles in this domain for others",
                                 col2 => 'Rules',},
                                {col1 => "Co-author roles for this domain's users elsewhere",
                                 col2 => 'Rules',},
                                {col1 => "Domain roles in this domain assignable to others",
                                 col2 => 'Rules'},
                                {col1 => "Course catalog for this domain displayed elsewhere",
                                 col2 => 'Rules'},
                                {col1 => "Requests for creation of courses in this domain by others",
                                 col2 => 'Rules'},
                                {col1 => "Users in other domains can send messages to this domain",
                                 col2 => 'Rules'},],
                     print => \&print_trust,
                     modify => \&modify_trust,
                    },
     );      );
     if (keys(%servers) > 1) {      if (keys(%servers) > 1) {
         $prefs{'login'}  = { text   => 'Log-in page options',          $prefs{'login'}  = { text   => 'Log-in page options',
Line 550  $javascript_validations Line 574  $javascript_validations
 $coursebrowserjs  $coursebrowserjs
 END  END
         }          }
         if (grep(/^contacts$/,@actions)) {  
             $js .= &contacts_javascript();  
         }  
         &Apache::lonconfigsettings::display_settings($r,$dom,$phase,$context,\@prefs_order,\%prefs,\%domconfig,$confname,$js);          &Apache::lonconfigsettings::display_settings($r,$dom,$phase,$context,\@prefs_order,\%prefs,\%domconfig,$confname,$js);
     } else {      } else {
 # check if domconfig user exists for the domain.  # check if domconfig user exists for the domain.
Line 642  sub process_changes { Line 663  sub process_changes {
     } elsif ($action eq 'autocreate') {      } elsif ($action eq 'autocreate') {
         $output = &modify_autocreate($dom,%domconfig);          $output = &modify_autocreate($dom,%domconfig);
     } elsif ($action eq 'directorysrch') {      } elsif ($action eq 'directorysrch') {
         $output = &modify_directorysrch($dom,$lastactref,%domconfig);          $output = &modify_directorysrch($dom,%domconfig);
     } elsif ($action eq 'usercreation') {      } elsif ($action eq 'usercreation') {
         $output = &modify_usercreation($dom,%domconfig);          $output = &modify_usercreation($dom,%domconfig);
     } elsif ($action eq 'selfcreation') {      } elsif ($action eq 'selfcreation') {
Line 664  sub process_changes { Line 685  sub process_changes {
     } elsif ($action eq 'requestauthor') {      } elsif ($action eq 'requestauthor') {
         $output = &modify_quotas($r,$dom,$action,$lastactref,%domconfig);          $output = &modify_quotas($r,$dom,$action,$lastactref,%domconfig);
     } elsif ($action eq 'helpsettings') {      } elsif ($action eq 'helpsettings') {
         $output = &modify_helpsettings($r,$dom,$confname,$lastactref,%domconfig);          $output = &modify_helpsettings($r,$dom,$confname,%domconfig);
     } elsif ($action eq 'coursedefaults') {      } elsif ($action eq 'coursedefaults') {
         $output = &modify_coursedefaults($dom,$lastactref,%domconfig);          $output = &modify_coursedefaults($dom,$lastactref,%domconfig);
     } elsif ($action eq 'selfenrollment') {      } elsif ($action eq 'selfenrollment') {
Line 675  sub process_changes { Line 696  sub process_changes {
         $output = &modify_loadbalancing($dom,%domconfig);          $output = &modify_loadbalancing($dom,%domconfig);
     } elsif ($action eq 'ltitools') {      } elsif ($action eq 'ltitools') {
         $output = &modify_ltitools($r,$dom,$action,$lastactref,%domconfig);          $output = &modify_ltitools($r,$dom,$action,$lastactref,%domconfig);
       } elsif ($action eq 'ssl') {
           $output = &modify_ssl($dom,$lastactref,%domconfig);
       } elsif ($action eq 'trust') {
           $output = &modify_trust($dom,$lastactref,%domconfig);
     }      }
     return $output;      return $output;
 }  }
Line 687  sub print_config_box { Line 712  sub print_config_box {
         $output = &coursecategories_javascript($settings);          $output = &coursecategories_javascript($settings);
     } elsif ($action eq 'defaults') {      } elsif ($action eq 'defaults') {
         $output = &defaults_javascript($settings);           $output = &defaults_javascript($settings); 
     } elsif ($action eq 'helpsettings') {  
         my (%privs,%levelscurrent);  
         my %full=();  
         my %levels=(  
                      course => {},  
                      domain => {},  
                      system => {},  
                    );  
         my $context = 'domain';  
         my $crstype = 'Course';  
         my $formname = 'display';  
         &Apache::lonuserutils::custom_role_privs(\%privs,\%full,\%levels,\%levelscurrent);  
         my @templateroles = &Apache::lonuserutils::custom_template_roles($context,$crstype);  
         $output =  
             &Apache::lonuserutils::custom_roledefs_js($context,$crstype,$formname,\%full,  
                                                       \@templateroles);  
     }      }
     $output .=      $output .=
          '<table class="LC_nested_outer">           '<table class="LC_nested_outer">
Line 738  sub print_config_box { Line 747  sub print_config_box {
         $rowtotal ++;          $rowtotal ++;
         if (($action eq 'autoupdate') || ($action eq 'usercreation') || ($action eq 'selfcreation') ||          if (($action eq 'autoupdate') || ($action eq 'usercreation') || ($action eq 'selfcreation') ||
             ($action eq 'usermodification') || ($action eq 'defaults') || ($action eq 'coursedefaults') ||              ($action eq 'usermodification') || ($action eq 'defaults') || ($action eq 'coursedefaults') ||
             ($action eq 'selfenrollment') || ($action eq 'usersessions') || ($action eq 'directorysrch') ||              ($action eq 'selfenrollment') || ($action eq 'usersessions') || ($action eq 'ssl') ||
             ($action eq 'helpsettings') || ($action eq 'contacts')) {              ($action eq 'directorysrch') || ($action eq 'trust')) {
             $output .= $item->{'print'}->('top',$dom,$settings,\$rowtotal);              $output .= $item->{'print'}->('top',$dom,$settings,\$rowtotal);
         } elsif ($action eq 'coursecategories') {          } elsif ($action eq 'coursecategories') {
             $output .= $item->{'print'}->('top',$dom,$item,$settings,\$rowtotal);              $output .= $item->{'print'}->('top',$dom,$item,$settings,\$rowtotal);
Line 769  sub print_config_box { Line 778  sub print_config_box {
             $rowtotal ++;              $rowtotal ++;
         if (($action eq 'autoupdate') || ($action eq 'usercreation') ||          if (($action eq 'autoupdate') || ($action eq 'usercreation') ||
             ($action eq 'selfcreation') || ($action eq 'selfenrollment') ||              ($action eq 'selfcreation') || ($action eq 'selfenrollment') ||
             ($action eq 'usersessions') || ($action eq 'coursecategories') ||              ($action eq 'usersessions') || ($action eq 'coursecategories') || 
             ($action eq 'contacts') || ($action eq 'defaults')) {              ($action eq 'ssl') || ($action eq 'trust')) {
             if ($action eq 'coursecategories') {              if ($action eq 'coursecategories') {
                 $output .= &print_coursecategories('middle',$dom,$item,$settings,\$rowtotal);                  $output .= &print_coursecategories('middle',$dom,$item,$settings,\$rowtotal);
                 $colspan = ' colspan="2"';                  $colspan = ' colspan="2"';
               } elsif ($action eq 'trust') {
                   $output .= $item->{'print'}->('shared',$dom,$settings,\$rowtotal);
             } else {              } else {
                 $output .= $item->{'print'}->('middle',$dom,$settings,\$rowtotal);                  $output .= $item->{'print'}->('middle',$dom,$settings,\$rowtotal);
             }              }
             $output .= '              if ($action eq 'trust') {
                   $output .= '
               </table>
             </td>
            </tr>';
                   my @trusthdrs = qw(2 3 4 5 6 7);
                   my @prefixes = qw(enroll othcoau coaurem domroles catalog reqcrs);
                   for (my $i=0; $i<@trusthdrs; $i++) {
                       $output .= '
            <tr>
              <td>
               <table class="LC_nested">
                <tr class="LC_info_row">
                 <td class="LC_left_item"'.$colspan.'>'.&mt($item->{'header'}->[$trusthdrs[$i]]->{'col1'}).'</td>
                 <td class="LC_right_item"'.$colspan.'>'.&mt($item->{'header'}->[$trusthdrs[$i]]->{'col2'}).'</td></tr>'.
                              $item->{'print'}->($prefixes[$i],$dom,$settings,\$rowtotal).'
               </table>
             </td>
            </tr>';
                   }
                   $output .= '
            <tr>
              <td>
               <table class="LC_nested">
                <tr class="LC_info_row">
                 <td class="LC_left_item"'.$colspan.'>'.&mt($item->{'header'}->[8]->{'col1'}).'</td>
                 <td class="LC_right_item"'.$colspan.'>'.&mt($item->{'header'}->[8]->{'col2'}).'</td></tr>'.
                              $item->{'print'}->('bottom',$dom,$settings,\$rowtotal);
               } else {
                   $output .= '
            </table>             </table>
           </td>            </td>
          </tr>           </tr>
Line 788  sub print_config_box { Line 828  sub print_config_box {
               <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>                <td class="LC_right_item">'.&mt($item->{'header'}->[2]->{'col2'}).'</td>
              </tr>'."\n";               </tr>'."\n";
             if ($action eq 'coursecategories') {                  if ($action eq 'coursecategories') {
                 $output .= &print_coursecategories('bottom',$dom,$item,$settings,\$rowtotal);                      $output .= &print_coursecategories('bottom',$dom,$item,$settings,\$rowtotal);
             } else {                  } else {
                 $output .= $item->{'print'}->('bottom',$dom,$settings,\$rowtotal);                      $output .= $item->{'print'}->('bottom',$dom,$settings,\$rowtotal);
                   }
             }              }
             $rowtotal ++;              $rowtotal ++;
         } elsif (($action eq 'usermodification') || ($action eq 'coursedefaults') ||          } elsif (($action eq 'usermodification') || ($action eq 'coursedefaults') ||
                  ($action eq 'defaults') || ($action eq 'directorysrch') ||                   ($action eq 'defaults') || ($action eq 'directorysrch')) {
                  ($action eq 'helpsettings')) {  
             $output .= $item->{'print'}->('bottom',$dom,$settings,\$rowtotal);              $output .= $item->{'print'}->('bottom',$dom,$settings,\$rowtotal);
         } elsif ($action eq 'login') {          } elsif ($action eq 'login') {
             if ($numheaders == 4) {              if ($numheaders == 4) {
Line 954  sub print_config_box { Line 994  sub print_config_box {
         if ($action eq 'quotas') {          if ($action eq 'quotas') {
             $output .= &print_quotas($dom,$settings,\$rowtotal,$action);              $output .= &print_quotas($dom,$settings,\$rowtotal,$action);
         } elsif (($action eq 'autoenroll') || ($action eq 'autocreate') ||           } elsif (($action eq 'autoenroll') || ($action eq 'autocreate') || 
                  ($action eq 'serverstatuses') || ($action eq 'loadbalancing') ||                   ($action eq 'contacts') || ($action eq 'serverstatuses') || 
                  ($action eq 'ltitools')) {                   ($action eq 'loadbalancing') || ($action eq 'ltitools')) {
             $output .= $item->{'print'}->($dom,$settings,\$rowtotal);              $output .= $item->{'print'}->($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 'helpsettings') {
               $output .= &print_helpsettings($dom,$confname,$settings,\$rowtotal);
         }          }
     }      }
     $output .= '      $output .= '
Line 1759  sub print_quotas { Line 1801  sub print_quotas {
     my $typecount = 0;      my $typecount = 0;
     my ($css_class,%titles);      my ($css_class,%titles);
     if ($context eq 'requestcourses') {      if ($context eq 'requestcourses') {
         @usertools = ('official','unofficial','community','textbook');          @usertools = ('official','unofficial','community','textbook','placement');
         @options =('norequest','approval','validate','autolimit');          @options =('norequest','approval','validate','autolimit');
         %validations = &Apache::lonnet::auto_courserequest_checks($dom);          %validations = &Apache::lonnet::auto_courserequest_checks($dom);
         %titles = &courserequest_titles();          %titles = &courserequest_titles();
Line 2211  sub print_studentcode { Line 2253  sub print_studentcode {
     my ($settings,$rowtotal) = @_;      my ($settings,$rowtotal) = @_;
     my $rownum = 0;       my $rownum = 0; 
     my ($output,%current);      my ($output,%current);
     my @crstypes = ('official','unofficial','community','textbook');      my @crstypes = ('official','unofficial','community','textbook','placement');
     if (ref($settings) eq 'HASH') {      if (ref($settings) eq 'HASH') {
         if (ref($settings->{'uniquecode'}) eq 'HASH') {          if (ref($settings->{'uniquecode'}) eq 'HASH') {
             foreach my $type (@crstypes) {              foreach my $type (@crstypes) {
Line 2307  sub print_textbookcourses { Line 2349  sub print_textbookcourses {
                               ('&nbsp;'x2).                                ('&nbsp;'x2).
                               '<span class="LC_nobreak">'.&mt('Thumbnail:');                                '<span class="LC_nobreak">'.&mt('Thumbnail:');
                 if ($image) {                  if ($image) {
                     $datatable .= '<span class="LC_nobreak">'.                      $datatable .= $imgsrc.
                                   $imgsrc.  
                                   '<label><input type="checkbox" name="'.$type.'_image_del"'.                                    '<label><input type="checkbox" name="'.$type.'_image_del"'.
                                   ' value="'.$key.'" />'.&mt('Delete?').'</label></span> '.                                    ' value="'.$key.'" />'.&mt('Delete?').'</label></span> '.
                                   '<span class="LC_nobreak">&nbsp;'.&mt('Replace:').'&nbsp;';                                    '<span class="LC_nobreak">&nbsp;'.&mt('Replace:').'&nbsp;';
Line 2658  sub print_autoupdate { Line 2699  sub print_autoupdate {
         my $locknamesettings;          my $locknamesettings;
         $datatable .= &insttypes_row($settings,$types,$usertypes,          $datatable .= &insttypes_row($settings,$types,$usertypes,
                                      $dom,$numinrow,$othertitle,                                       $dom,$numinrow,$othertitle,
                                     'lockablenames',$rowtotal);                                      'lockablenames');
         $$rowtotal ++;          $$rowtotal ++;
     } else {      } else {
         my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom);          my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom);
Line 2801  sub print_directorysrch { Line 2842  sub print_directorysrch {
         if (ref($usertypes) eq 'HASH') {          if (ref($usertypes) eq 'HASH') {
             if (keys(%{$usertypes}) > 0) {              if (keys(%{$usertypes}) > 0) {
                 $datatable .= &insttypes_row($settings,$types,$usertypes,$dom,                  $datatable .= &insttypes_row($settings,$types,$usertypes,$dom,
                                              $numinrow,$othertitle,'cansearch',                                               $numinrow,$othertitle,'cansearch');
                                              $rowtotal);  
                 $cansrchrow = 1;                  $cansrchrow = 1;
             }              }
         }          }
Line 2887  sub print_directorysrch { Line 2927  sub print_directorysrch {
 }  }
   
 sub print_contacts {  sub print_contacts {
     my ($position,$dom,$settings,$rowtotal) = @_;      my ($dom,$settings,$rowtotal) = @_;
     my $datatable;      my $datatable;
     my @contacts = ('adminemail','supportemail');      my @contacts = ('adminemail','supportemail');
     my (%checked,%to,%otheremails,%bccemails,%includestr,%includeloc,%currfield,      my (%checked,%to,%otheremails,%bccemails);
         $maxsize,$fields,$fieldtitles,$fieldoptions,$possoptions,@mailings);      my @mailings = ('errormail','packagesmail','lonstatusmail','helpdeskmail',
     if ($position eq 'top') {                      'requestsmail','updatesmail','idconflictsmail');
         if (ref($settings) eq 'HASH') {      foreach my $type (@mailings) {
             foreach my $item (@contacts) {          $otheremails{$type} = '';
                 if (exists($settings->{$item})) {  
                     $to{$item} = $settings->{$item};  
                 }  
             }  
         }  
     } elsif ($position eq 'middle') {  
         @mailings = ('errormail','packagesmail','lonstatusmail','requestsmail',  
                      'updatesmail','idconflictsmail');  
         foreach my $type (@mailings) {  
             $otheremails{$type} = '';  
         }  
     } else {  
         @mailings = ('helpdeskmail','otherdomsmail');  
         foreach my $type (@mailings) {  
             $otheremails{$type} = '';  
         }  
         $bccemails{'helpdeskmail'} = '';  
         $bccemails{'otherdomsmail'} = '';  
         $includestr{'helpdeskmail'} = '';  
         $includestr{'otherdomsmail'} = '';  
         ($fields,$fieldtitles,$fieldoptions,$possoptions) = &helpform_fields();  
     }      }
       $bccemails{'helpdeskmail'} = '';
     if (ref($settings) eq 'HASH') {      if (ref($settings) eq 'HASH') {
         unless ($position eq 'top') {          foreach my $item (@contacts) {
             foreach my $type (@mailings) {              if (exists($settings->{$item})) {
                 if (exists($settings->{$type})) {                  $to{$item} = $settings->{$item};
                     if (ref($settings->{$type}) eq 'HASH') {  
                         foreach my $item (@contacts) {  
                             if ($settings->{$type}{$item}) {  
                                 $checked{$type}{$item} = ' checked="checked" ';  
                             }  
                         }  
                         $otheremails{$type} = $settings->{$type}{'others'};  
                         if (($type eq 'helpdeskmail') || ($type eq 'otherdomsmail')) {  
                             $bccemails{$type} = $settings->{$type}{'bcc'};  
                             if ($settings->{$type}{'include'} ne '') {  
                                 ($includeloc{$type},$includestr{$type}) = split(/:/,$settings->{$type}{'include'},2);  
                                 $includestr{$type} = &unescape($includestr{$type});  
                             }  
                         }  
                     }  
                 } elsif ($type eq 'lonstatusmail') {  
                     $checked{'lonstatusmail'}{'adminemail'} = ' checked="checked" ';  
                 }  
             }              }
         }          }
         if ($position eq 'bottom') {          foreach my $type (@mailings) {
             foreach my $type (@mailings) {              if (exists($settings->{$type})) {
                 $bccemails{$type} = $settings->{$type}{'bcc'};                  if (ref($settings->{$type}) eq 'HASH') {
                 if ($settings->{$type}{'include'} ne '') {                      foreach my $item (@contacts) {
                     ($includeloc{$type},$includestr{$type}) = split(/:/,$settings->{$type}{'include'},2);                          if ($settings->{$type}{$item}) {
                     $includestr{$type} = &unescape($includestr{$type});                              $checked{$type}{$item} = ' checked="checked" ';
                 }                          }
             }  
             if (ref($settings->{'helpform'}) eq 'HASH') {  
                 if (ref($fields) eq 'ARRAY') {  
                     foreach my $field (@{$fields}) {  
                         $currfield{$field} = $settings->{'helpform'}{$field};  
                     }                      }
                 }                      $otheremails{$type} = $settings->{$type}{'others'};
                 if (exists($settings->{'helpform'}{'maxsize'})) {                      if ($type eq 'helpdeskmail') {
                     $maxsize = $settings->{'helpform'}{'maxsize'};                          $bccemails{$type} = $settings->{$type}{'bcc'};
                 } else {  
                     $maxsize = '1.0';  
                 }  
             } else {  
                 if (ref($fields) eq 'ARRAY') {  
                     foreach my $field (@{$fields}) {  
                         $currfield{$field} = 'yes';  
                     }                      }
                 }                  }
                 $maxsize = '1.0';              } elsif ($type eq 'lonstatusmail') {
                   $checked{'lonstatusmail'}{'adminemail'} = ' checked="checked" ';
             }              }
         }          }
     } else {      } else {
         if ($position eq 'top') {          $to{'supportemail'} = $Apache::lonnet::perlvar{'lonSupportEMail'};
             $to{'supportemail'} = $Apache::lonnet::perlvar{'lonSupportEMail'};          $to{'adminemail'} = $Apache::lonnet::perlvar{'lonAdmEMail'};
             $to{'adminemail'} = $Apache::lonnet::perlvar{'lonAdmEMail'};          $checked{'errormail'}{'adminemail'} = ' checked="checked" ';
             $checked{'errormail'}{'adminemail'} = ' checked="checked" ';          $checked{'packagesmail'}{'adminemail'} = ' checked="checked" ';
             $checked{'packagesmail'}{'adminemail'} = ' checked="checked" ';          $checked{'helpdeskmail'}{'supportemail'} = ' checked="checked" ';
             $checked{'lonstatusmail'}{'adminemail'} = ' checked="checked" ';          $checked{'lonstatusmail'}{'adminemail'} = ' checked="checked" '; 
             $checked{'requestsmail'}{'adminemail'} = ' checked="checked" ';          $checked{'requestsmail'}{'adminemail'} = ' checked="checked" ';
             $checked{'updatesmail'}{'adminemail'} = ' checked="checked" ';          $checked{'updatesmail'}{'adminemail'} = ' checked="checked" ';
             $checked{'idconflictsmail'}{'adminemail'} = ' checked="checked" ';          $checked{'idconflictsmail'}{'adminemail'} = ' checked="checked" ';
         } elsif ($position eq 'bottom') {  
             $checked{'helpdeskmail'}{'supportemail'} = ' checked="checked" ';  
             $checked{'otherdomsmail'}{'supportemail'} = ' checked="checked" ';  
             if (ref($fields) eq 'ARRAY') {  
                 foreach my $field (@{$fields}) {  
                     $currfield{$field} = 'yes';  
                 }  
             }  
             $maxsize = '1.0';  
         }  
     }      }
     my ($titles,$short_titles) = &contact_titles();      my ($titles,$short_titles) = &contact_titles();
     my $rownum = 0;      my $rownum = 0;
     my $css_class;      my $css_class;
     if ($position eq 'top') {      foreach my $item (@contacts) {
         foreach my $item (@contacts) {          $css_class = $rownum%2?' class="LC_odd_row"':'';
             $css_class = $rownum%2?' class="LC_odd_row"':'';          $datatable .= '<tr'.$css_class.'>'. 
             $datatable .= '<tr'.$css_class.'>'.                     '<td><span class="LC_nobreak">'.$titles->{$item}.
                           '<td><span class="LC_nobreak">'.$titles->{$item}.                    '</span></td><td class="LC_right_item">'.
                           '</span></td><td class="LC_right_item">'.                    '<input type="text" name="'.$item.'" value="'.
                           '<input type="text" name="'.$item.'" value="'.                    $to{$item}.'" /></td></tr>';
                           $to{$item}.'" /></td></tr>';          $rownum ++;
             $rownum ++;      }
         }      foreach my $type (@mailings) {
     } elsif ($position eq 'bottom') {  
         $css_class = $rownum%2?' class="LC_odd_row"':'';          $css_class = $rownum%2?' class="LC_odd_row"':'';
         $datatable .= '<tr'.$css_class.'>'.          $datatable .= '<tr'.$css_class.'>'.
                       '<td>'.&mt('Extra helpdesk form fields:').'<br />'.                        '<td><span class="LC_nobreak">'.
                       &mt('(e-mail, subject, and description always shown)').                        $titles->{$type}.': </span></td>'.
                       '</td><td class="LC_left_item">';                        '<td class="LC_left_item">'.
         if ((ref($fields) eq 'ARRAY') && (ref($fieldtitles) eq 'HASH') &&                        '<span class="LC_nobreak">';
             (ref($fieldoptions) eq 'HASH') && (ref($possoptions) eq 'HASH')) {          foreach my $item (@contacts) {
             $datatable .= '<table><tr><th>'.&mt('Field').'</th><th>'.&mt('Status').'</th></tr>';              $datatable .= '<label>'.
             foreach my $field (@{$fields}) {                            '<input type="checkbox" name="'.$type.'"'.
                 $datatable .= '<tr><td>'.$fieldtitles->{$field};                            $checked{$type}{$item}.
                 if (($field eq 'screenshot') || ($field eq 'cc')) {                            ' value="'.$item.'" />'.$short_titles->{$item}.
                     $datatable .= ' '.&mt('(logged-in users)');                            '</label>&nbsp;';
                 }          }
                 $datatable .='</td><td>';          $datatable .= '</span><br />'.&mt('Others').':&nbsp;&nbsp;'.
                 my $clickaction;                        '<input type="text" name="'.$type.'_others" '.
                 if ($field eq 'screenshot') {                        'value="'.$otheremails{$type}.'"  />';
                     $clickaction = ' onclick="screenshotSize(this);"';          if ($type eq 'helpdeskmail') {
                 }              $datatable .= '<br />'.&mt('Bcc:').('&nbsp;'x6).
                 if (ref($possoptions->{$field}) eq 'ARRAY') {                            '<input type="text" name="'.$type.'_bcc" '.
                     foreach my $option (@{$possoptions->{$field}}) {                            'value="'.$bccemails{$type}.'"  />';
                         my $checked;  
                         if ($currfield{$field} eq $option) {  
                             $checked = ' checked="checked"';  
                         }  
                         $datatable .= '<span class="LC_nobreak"><label>'.  
                                       '<input type="radio" name="helpform_'.$field.'" '.  
                                       'value="'.$option.'"'.$checked.$clickaction.' />'.$fieldoptions->{$option}.  
                                       '</label></span>'.('&nbsp;'x2);  
                     }  
                 }  
                 if ($field eq 'screenshot') {  
                     my $display;  
                     if ($currfield{$field} eq 'no') {  
                         $display = ' style="display:none"';  
                     }  
                     $datatable .= '</td></tr><tr id="help_screenshotsize"'.$display.' />'.  
                                   '<td>'.&mt('Maximum size for upload (MB)').'</td><td>'.  
                                   '<input type="text" size="5" name="helpform_maxsize" value="'.$maxsize.'" />';  
                 }  
                 $datatable .= '</td></tr>';  
             }  
             $datatable .= '</table>';  
         }          }
         $datatable .= '</td></tr>'."\n";          $datatable .= '</td></tr>'."\n";
         $rownum ++;          $rownum ++;
     }      }
     unless ($position eq 'top') {      my %choices;
         foreach my $type (@mailings) {      $choices{'reporterrors'} = &mt('E-mail error reports to [_1]',
             $css_class = $rownum%2?' class="LC_odd_row"':'';                                     &Apache::loncommon::modal_link('http://loncapa.org/core.html',
             $datatable .= '<tr'.$css_class.'>'.                                     &mt('LON-CAPA core group - MSU'),600,500));
                           '<td><span class="LC_nobreak">'.      $choices{'reportupdates'} = &mt('E-mail record of completed LON-CAPA updates to [_1]',
                           $titles->{$type}.': </span></td>'.                                      &Apache::loncommon::modal_link('http://loncapa.org/core.html',
                           '<td class="LC_left_item">';                                      &mt('LON-CAPA core group - MSU'),600,500));
             if (($type eq 'helpdeskmail') || ($type eq 'otherdomsmail')) {      my @toggles = ('reporterrors','reportupdates');
                 $datatable .= '<fieldset><legend>'.&mt('E-mail recipient(s)').'</legend>';      my %defaultchecked = ('reporterrors'  => 'on',
             }                            'reportupdates' => 'on');
             $datatable .= '<span class="LC_nobreak">';      (my $reports,$rownum) = &radiobutton_prefs($settings,\@toggles,\%defaultchecked,
             foreach my $item (@contacts) {                                                 \%choices,$rownum);
                 $datatable .= '<label>'.      $datatable .= $reports;
                               '<input type="checkbox" name="'.$type.'"'.  
                               $checked{$type}{$item}.  
                               ' value="'.$item.'" />'.$short_titles->{$item}.  
                               '</label>&nbsp;';  
             }  
             $datatable .= '</span><br />'.&mt('Others').':&nbsp;&nbsp;'.  
                           '<input type="text" name="'.$type.'_others" '.  
                           'value="'.$otheremails{$type}.'"  />';  
             my %locchecked;  
             if (($type eq 'helpdeskmail') || ($type eq 'otherdomsmail')) {  
                 foreach my $loc ('s','b') {  
                     if ($includeloc{$type} eq $loc) {  
                         $locchecked{$loc} = ' checked="checked"';  
                         last;  
                     }  
                 }  
                 $datatable .= '<br />'.&mt('Bcc:').('&nbsp;'x6).  
                               '<input type="text" name="'.$type.'_bcc" '.  
                               'value="'.$bccemails{$type}.'"  /></fieldset>'.  
                               '<fieldset><legend>'.&mt('Optional added text').'</legend>'.  
                               &mt('Text automatically added to e-mail:').' '.  
                               '<input type="text" name="'.$type.'_includestr" value="'.$includestr{$type}.'" /><br >'.  
                               '<span class="LC_nobreak">'.&mt('Location:').'&nbsp;'.  
                               '<label><input type="radio" name="'.$type.'_includeloc" value="s"'.$locchecked{'s'}.' />'.&mt('in subject').'</label>'.  
                               ('&nbsp;'x2).  
                               '<label><input type="radio" name="'.$type.'_includeloc" value="b"'.$locchecked{'b'}.' />'.&mt('in body').'</label>'.  
                               '</span></fieldset>';  
             }  
             $datatable .= '</td></tr>'."\n";  
             $rownum ++;  
         }  
     }  
     if ($position eq 'middle') {  
         my %choices;  
         $choices{'reporterrors'} = &mt('E-mail error reports to [_1]',  
                                        &Apache::loncommon::modal_link('http://loncapa.org/core.html',  
                                        &mt('LON-CAPA core group - MSU'),600,500));  
         $choices{'reportupdates'} = &mt('E-mail record of completed LON-CAPA updates to [_1]',  
                                         &Apache::loncommon::modal_link('http://loncapa.org/core.html',  
                                         &mt('LON-CAPA core group - MSU'),600,500));  
         my @toggles = ('reporterrors','reportupdates');  
         my %defaultchecked = ('reporterrors'  => 'on',  
                               'reportupdates' => 'on');  
         (my $reports,$rownum) = &radiobutton_prefs($settings,\@toggles,\%defaultchecked,  
                                                    \%choices,$rownum);  
         $datatable .= $reports;  
     } elsif ($position eq 'bottom') {  
         my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom);  
         my (@posstypes,%usertypeshash);  
         if (ref($types) eq 'ARRAY') {  
             @posstypes = @{$types};  
         }  
         if (@posstypes) {  
             if (ref($usertypes) eq 'HASH') {  
                 %usertypeshash = %{$usertypes};  
             }  
             my @overridden;  
             my $numinrow = 4;  
             if (ref($settings) eq 'HASH') {  
                 if (ref($settings->{'overrides'}) eq 'HASH') {  
                     foreach my $key (sort(keys(%{$settings->{'overrides'}}))) {  
                         if (ref($settings->{'overrides'}{$key}) eq 'HASH') {  
                             push(@overridden,$key);  
                             foreach my $item (@contacts) {  
                                 if ($settings->{'overrides'}{$key}{$item}) {  
                                     $checked{'override_'.$key}{$item} = ' checked="checked" ';  
                                 }  
                             }  
                             $otheremails{'override_'.$key} = $settings->{'overrides'}{$key}{'others'};  
                             $bccemails{'override_'.$key} = $settings->{'overrides'}{$key}{'bcc'};  
                             $includeloc{'override_'.$key} = '';  
                             $includestr{'override_'.$key} = '';  
                             if ($settings->{'overrides'}{$key}{'include'} ne '') {  
                                 ($includeloc{'override_'.$key},$includestr{'override_'.$key}) =  
                                     split(/:/,$settings->{'overrides'}{$key}{'include'},2);  
                                 $includestr{'override_'.$key} = &unescape($includestr{'override_'.$key});  
                             }  
                         }  
                     }  
                 }  
             }  
             my $customclass = 'LC_helpdesk_override';  
             my $optionsprefix = 'LC_options_helpdesk_';  
   
             my $onclicktypes = "toggleHelpdeskRow(this.form,'overrides','$customclass','$optionsprefix');";  
   
             $datatable .= &insttypes_row($settings,$types,$usertypes,$dom,  
                                          $numinrow,$othertitle,'overrides',  
                                          \$rownum,$onclicktypes,$customclass);  
             $rownum ++;  
             $usertypeshash{'default'} = $othertitle;  
             foreach my $status (@posstypes) {  
                 my $css_class;  
                 if ($rownum%2) {  
                     $css_class = 'LC_odd_row ';  
                 }  
                 $css_class .= $customclass;  
                 my $rowid = $optionsprefix.$status;  
                 my $hidden = 1;  
                 my $currstyle = 'display:none';  
                 if (grep(/^\Q$status\E$/,@overridden)) {  
                     $currstyle = 'display:table-row';  
                     $hidden = 0;  
                 }  
                 my $key = 'override_'.$status;  
                 $datatable .= &overridden_helpdesk($checked{$key},$otheremails{$key},$bccemails{$key},  
                                                   $includeloc{$key},$includestr{$key},$status,$rowid,  
                                                   $usertypeshash{$status},$css_class,$currstyle,  
                                                   \@contacts,$short_titles);  
                 unless ($hidden) {  
                     $rownum ++;  
                 }  
             }  
         }  
     }  
     $$rowtotal += $rownum;      $$rowtotal += $rownum;
     return $datatable;      return $datatable;
 }  }
   
 sub overridden_helpdesk {  
     my ($checked,$otheremails,$bccemails,$includeloc,$includestr,$type,$rowid,  
         $typetitle,$css_class,$rowstyle,$contacts,$short_titles) = @_;  
     my $class = 'LC_left_item';  
     if ($css_class) {  
         $css_class = ' class="'.$css_class.'"';  
     }  
     if ($rowid) {  
         $rowid = ' id="'.$rowid.'"';  
     }  
     if ($rowstyle) {  
         $rowstyle = ' style="'.$rowstyle.'"';  
     }  
     my ($output,$description);  
     $description = &mt('Helpdesk requests from: [_1] in this domain (overrides default)',"<b>$typetitle</b>");  
     $output = '<tr'.$css_class.$rowid.$rowstyle.'>'.  
               "<td>$description</td>\n".  
               '<td class="'.$class.'" colspan="2">'.  
               '<fieldset><legend>'.&mt('E-mail recipient(s)').'</legend>'.  
               '<span class="LC_nobreak">';  
     if (ref($contacts) eq 'ARRAY') {  
         foreach my $item (@{$contacts}) {  
             my $check;  
             if (ref($checked) eq 'HASH') {  
                $check = $checked->{$item};  
             }  
             my $title;  
             if (ref($short_titles) eq 'HASH') {  
                 $title = $short_titles->{$item};  
             }  
             $output .= '<label>'.  
                        '<input type="checkbox" name="override_'.$type.'"'.$check.  
                        ' value="'.$item.'" />'.$title.'</label>&nbsp;';  
         }  
     }  
     $output .= '</span><br />'.&mt('Others').':&nbsp;&nbsp;'.  
                '<input type="text" name="override_'.$type.'_others" '.  
                'value="'.$otheremails.'"  />';  
     my %locchecked;  
     foreach my $loc ('s','b') {  
         if ($includeloc eq $loc) {  
             $locchecked{$loc} = ' checked="checked"';  
             last;  
         }  
     }  
     $output .= '<br />'.&mt('Bcc:').('&nbsp;'x6).  
                '<input type="text" name="override_'.$type.'_bcc" '.  
                'value="'.$bccemails.'"  /></fieldset>'.  
                '<fieldset><legend>'.&mt('Optional added text').'</legend>'.  
                &mt('Text automatically added to e-mail:').' '.  
                '<input type="text" name="override_'.$type.'_includestr" value="'.$includestr.'" /><br >'.  
                '<span class="LC_nobreak">'.&mt('Location:').'&nbsp;'.  
                '<label><input type="radio" name="override_'.$type.'_includeloc" value="s"'.$locchecked{'s'}.' />'.&mt('in subject').'</label>'.  
                ('&nbsp;'x2).  
                '<label><input type="radio" name="override_'.$type.'_includeloc" value="b"'.$locchecked{'b'}.' />'.&mt('in body').'</label>'.  
                '</span></fieldset>'.  
                '</td></tr>'."\n";  
     return $output;  
 }  
   
 sub contacts_javascript {  
     return <<"ENDSCRIPT";  
   
 <script type="text/javascript">  
 // <![CDATA[  
   
 function screenshotSize(field) {  
     if (document.getElementById('help_screenshotsize')) {  
         if (field.value == 'no') {  
             document.getElementById('help_screenshotsize').style.display="none";  
         } else {  
             document.getElementById('help_screenshotsize').style.display="";  
         }  
     }  
     return;  
 }  
   
 function toggleHelpdeskRow(form,checkbox,target,prefix,docount) {  
     if (form.elements[checkbox].length != undefined) {  
         var count = 0;  
         if (docount) {  
             for (var i=0; i<form.elements[checkbox].length; i++) {  
                 if (form.elements[checkbox][i].checked) {  
                     count ++;  
                 }  
             }  
         }  
         for (var i=0; i<form.elements[checkbox].length; i++) {  
             var type = form.elements[checkbox][i].value;  
             if (document.getElementById(prefix+type)) {  
                 if (form.elements[checkbox][i].checked) {  
                     document.getElementById(prefix+type).style.display = 'table-row';  
                     if (count % 2 == 1) {  
                         document.getElementById(prefix+type).className = target+' LC_odd_row';  
                     } else {  
                         document.getElementById(prefix+type).className = target;  
                     }  
                     count ++;  
                 } else {  
                     document.getElementById(prefix+type).style.display = 'none';  
                 }  
             }  
         }  
     }  
     return;  
 }  
   
   
 // ]]>  
 </script>  
   
 ENDSCRIPT  
 }  
   
 sub print_helpsettings {  sub print_helpsettings {
     my ($position,$dom,$settings,$rowtotal) = @_;      my ($dom,$confname,$settings,$rowtotal) = @_;
     my $confname = $dom.'-domainconfig';  
     my $formname = 'display';  
     my ($datatable,$itemcount);      my ($datatable,$itemcount);
     if ($position eq 'top') {      $itemcount = 1;
         $itemcount = 1;      my (%choices,%defaultchecked,@toggles);
         my (%choices,%defaultchecked,@toggles);      $choices{'submitbugs'} = &mt('Display link to: [_1]?',
         $choices{'submitbugs'} = &mt('Display link to: [_1]?',                                   &Apache::loncommon::modal_link('http://bugs.loncapa.org',
                                      &Apache::loncommon::modal_link('http://bugs.loncapa.org',                                   &mt('LON-CAPA bug tracker'),600,500));
                                      &mt('LON-CAPA bug tracker'),600,500));      %defaultchecked = ('submitbugs' => 'on');
         %defaultchecked = ('submitbugs' => 'on');      @toggles = ('submitbugs',);
         @toggles = ('submitbugs');  
         ($datatable,$itemcount) = &radiobutton_prefs($settings,\@toggles,\%defaultchecked,  
                                                      \%choices,$itemcount);  
         $$rowtotal ++;  
     } else {  
         my $css_class;  
         my %existing=&Apache::lonnet::dump('roles',$dom,$confname,'rolesdef_');  
         my (%customroles,%ordered,%current);  
         if (ref($settings) eq 'HASH') {  
             if (ref($settings->{'adhoc'}) eq 'HASH') {  
                 %current = %{$settings->{'adhoc'}};  
             }  
         }  
         my $count = 0;  
         foreach my $key (sort(keys(%existing))) {  
             if ($key=~/^rolesdef\_(\w+)$/) {  
                 my $rolename = $1;  
                 my (%privs,$order);  
                 ($privs{'system'},$privs{'domain'},$privs{'course'}) = split(/\_/,$existing{$key});  
                 $customroles{$rolename} = \%privs;  
                 if (ref($current{$rolename}) eq 'HASH') {  
                     $order = $current{$rolename}{'order'};  
                 }  
                 if ($order eq '') {  
                     $order = $count;  
                 }  
                 $ordered{$order} = $rolename;  
                 $count++;  
             }  
         }  
         my $maxnum = scalar(keys(%ordered));  
         my @roles_by_num = ();  
         foreach my $item (sort {$a <=> $b } (keys(%ordered))) {  
             push(@roles_by_num,$item);  
         }  
         my $context = 'domprefs';  
         my $crstype = 'Course';  
         my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom);  
         my @accesstypes = ('all','dh','da','none');  
         my ($numstatustypes,@jsarray);  
         if (ref($types) eq 'ARRAY') {  
             if (@{$types} > 0) {  
                 $numstatustypes = scalar(@{$types});  
                 push(@accesstypes,'status');  
                 @jsarray = ('bystatus');  
             }  
         }  
         my %domhelpdesk = &Apache::lonnet::get_active_domroles($dom,['dh'.'da']);  
         if (keys(%domhelpdesk)) {  
             push(@accesstypes,('inc','exc'));  
             push(@jsarray,('notinc','notexc'));  
         }  
         my $hiddenstr = join("','",@jsarray);  
         $datatable .= &helpsettings_javascript(\@roles_by_num,$maxnum,$hiddenstr,$formname);  
         my $context = 'domprefs';  
         my $crstype = 'Course';  
         my $prefix = 'helproles_';  
         my $add_class = 'LC_hidden';  
         foreach my $num (@roles_by_num) {  
             my $role = $ordered{$num};  
             my ($desc,$access,@statuses);  
             if (ref($current{$role}) eq 'HASH') {  
                 $desc = $current{$role}{'desc'};  
                 $access = $current{$role}{'access'};  
                 if (ref($current{$role}{'insttypes'}) eq 'ARRAY') {  
                     @statuses = @{$current{$role}{'insttypes'}};  
                 }  
             }  
             if ($desc eq '') {  
                 $desc = $role;  
             }  
             my $identifier = 'custhelp'.$num;  
             my %full=();  
             my %levels= (  
                          course => {},  
                          domain => {},  
                          system => {},  
                         );  
             my %levelscurrent=(  
                                course => {},  
                                domain => {},  
                                system => {},  
                               );  
             &Apache::lonuserutils::custom_role_privs($customroles{$role},\%full,\%levels,\%levelscurrent);  
             my @templateroles = &Apache::lonuserutils::custom_template_roles($context,$crstype);  
             $css_class = $itemcount%2?' class="LC_odd_row"':'';  
             my $chgstr = ' onchange="javascript:reorderHelpRoles(this.form,'."'helproles_".$num."_pos'".');"';  
             $datatable .= '<tr '.$css_class.'><td valign="top"><b>'.$role.'</b><br />'.  
                           '<select name="helproles_'.$num.'_pos"'.$chgstr.'>';  
             for (my $k=0; $k<=$maxnum; $k++) {  
                 my $vpos = $k+1;  
                 my $selstr;  
                 if ($k == $num) {  
                     $selstr = ' selected="selected" ';  
                 }  
                 $datatable .= '<option value="'.$k.'"'.$selstr.'>'.$vpos.'</option>';  
             }  
             $datatable .= '</select>'.('&nbsp;'x2).  
                           '<input type="hidden" name="helproles_'.$num.'" value="'.$role.'" />'.  
                           '</td>'.  
                           '<td><fieldset><legend>'.&mt('Role name').'</legend>'.  
                           &mt('Name shown to users:').  
                           '<input type="text" name="helproles_'.$num.'_desc" value="'.$desc.'" />'.  
                           '</fieldset>'.  
                           &helpdeskroles_access($dom,$prefix,$num,$add_class,$current{$role},\@accesstypes,  
                                                 $othertitle,$usertypes,$types,\%domhelpdesk).  
                           '<fieldset>'.  
                           '<legend>'.&mt('Role privileges').&adhocbutton($prefix,$num,'privs','show').'</legend>'.  
                           &Apache::lonuserutils::custom_role_table($crstype,\%full,\%levels,  
                                                                    \%levelscurrent,$identifier,  
                                                                    'LC_hidden',$prefix.$num.'_privs').  
                           '</fieldset></td>';  
             $itemcount ++;  
         }  
         $css_class = $itemcount%2?' class="LC_odd_row"':'';  
         my $newcust = 'custhelp'.$count;  
         my (%privs,%levelscurrent);  
         my %full=();  
         my %levels= (  
                      course => {},  
                      domain => {},  
                      system => {},  
                     );  
         &Apache::lonuserutils::custom_role_privs(\%privs,\%full,\%levels,\%levelscurrent);  
         my @templateroles = &Apache::lonuserutils::custom_template_roles($context,$crstype);  
         my $chgstr = ' onchange="javascript:reorderHelpRoles(this.form,'."'helproles_".$count."_pos'".');"';  
         $datatable .= '<tr '.$css_class.'><td valign="top"><span class="LC_nobreak"><label>'.  
                       '<input type="hidden" name="helproles_maxnum" value="'.$maxnum.'" />'."\n".  
                       '<select name="helproles_'.$count.'_pos"'.$chgstr.'>';  
         for (my $k=0; $k<$maxnum+1; $k++) {  
             my $vpos = $k+1;  
             my $selstr;  
             if ($k == $maxnum) {  
                 $selstr = ' selected="selected" ';  
             }  
             $datatable .= '<option value="'.$k.'"'.$selstr.'>'.$vpos.'</option>';  
         }  
         $datatable .= '</select>&nbsp;'."\n".  
                       '<input type="checkbox" name="newcusthelp" value="'.$count.'" />'. &mt('Add').  
                       '</label></span></td>'.  
                       '<td><fieldset><legend>'.&mt('Role name').'</legend>'.  
                       '<span class="LC_nobreak">'.  
                       &mt('Internal name:').  
                       '<input type="text" size="10" name="custhelpname'.$count.'" value="" />'.  
                       '</span>'.('&nbsp;'x4).  
                       '<span class="LC_nobreak">'.  
                       &mt('Name shown to users:').  
                       '<input type="text" size="20" name="helproles_'.$count.'_desc" value="" />'.  
                       '</span></fieldset>'.  
                        &helpdeskroles_access($dom,$prefix,$count,'',undef,\@accesstypes,$othertitle,  
                                              $usertypes,$types,\%domhelpdesk).  
                       '<fieldset><legend>'.&mt('Role privileges').'</legend>'.  
                       &Apache::lonuserutils::custom_role_header($context,$crstype,  
                                                                 \@templateroles,$newcust).  
                       &Apache::lonuserutils::custom_role_table('Course',\%full,\%levels,  
                                                                \%levelscurrent,$newcust).  
                       '</fieldset></td></tr>';  
         $count ++;  
         $$rowtotal += $count;  
     }  
     return $datatable;  
 }  
   
 sub adhocbutton {  
     my ($prefix,$num,$field,$visibility) = @_;  
     my %lt = &Apache::lonlocal::texthash(  
                                           show => 'Show details',  
                                           hide => 'Hide details',  
                                         );  
     return '<span style="text-decoration:line-through; font-weight: normal;">'.('&nbsp;'x10).  
            '</span>'.('&nbsp;'x2).'<input type="button" id="'.$prefix.$num.'_'.$field.'_vis"'.  
            ' value="'.$lt{$visibility}.'" style="height:20px;" '.  
            'onclick="toggleHelpdeskItem('."'$num','$field'".');" />'.('&nbsp;'x2);  
 }  
   
 sub helpsettings_javascript {      ($datatable,$itemcount) = &radiobutton_prefs($settings,\@toggles,\%defaultchecked,
     my ($roles_by_num,$total,$hiddenstr,$formname) = @_;                                                   \%choices,$itemcount);
     return unless(ref($roles_by_num) eq 'ARRAY');      return $datatable;
     my %html_js_lt = &Apache::lonlocal::texthash(  
                                           show => 'Show details',  
                                           hide => 'Hide details',  
                                         );  
     &html_escape(\%html_js_lt);  
     my $jstext = '    var helproles = Array('."'".join("','",@{$roles_by_num})."'".');'."\n";  
     return <<"ENDSCRIPT";  
 <script type="text/javascript">  
 // <![CDATA[  
   
 function reorderHelpRoles(form,item) {  
     var changedVal;  
 $jstext  
     var newpos = 'helproles_${total}_pos';  
     var maxh = 1 + $total;  
     var current = new Array();  
     var newitemVal = form.elements[newpos].options[form.elements[newpos].selectedIndex].value;  
     if (item == newpos) {  
         changedVal = newitemVal;  
     } else {  
         changedVal = form.elements[item].options[form.elements[item].selectedIndex].value;  
         current[newitemVal] = newpos;  
     }  
     for (var i=0; i<helproles.length; i++) {  
         var elementName = 'helproles_'+helproles[i]+'_pos';  
         if (elementName != item) {  
             if (form.elements[elementName]) {  
                 var currVal = form.elements[elementName].options[form.elements[elementName].selectedIndex].value;  
                 current[currVal] = elementName;  
             }  
         }  
     }  
     var oldVal;  
     for (var j=0; j<maxh; j++) {  
         if (current[j] == undefined) {  
             oldVal = j;  
         }  
     }  
     if (oldVal < changedVal) {  
         for (var k=oldVal+1; k<=changedVal ; k++) {  
            var elementName = current[k];  
            form.elements[elementName].selectedIndex = form.elements[elementName].selectedIndex - 1;  
         }  
     } else {  
         for (var k=changedVal; k<oldVal; k++) {  
             var elementName = current[k];  
             form.elements[elementName].selectedIndex = form.elements[elementName].selectedIndex + 1;  
         }  
     }  
     return;  
 }  
   
 function helpdeskAccess(num) {  
     var curraccess = null;  
     if (document.$formname.elements['helproles_'+num+'_access'].length) {  
         for (var i=0; i<document.$formname.elements['helproles_'+num+'_access'].length; i++) {  
             if (document.$formname.elements['helproles_'+num+'_access'][i].checked) {  
                 curraccess = document.$formname.elements['helproles_'+num+'_access'][i].value;  
             }  
         }  
     }  
     var shown = Array();  
     var hidden = Array();  
     if (curraccess == 'none') {  
         hidden = Array('$hiddenstr');  
     } else {  
         if (curraccess == 'status') {  
             shown = Array('bystatus');  
             hidden = Array('notinc','notexc');  
         } else {  
             if (curraccess == 'exc') {  
                 shown = Array('notexc');  
                 hidden = Array('notinc','bystatus');  
             }  
             if (curraccess == 'inc') {  
                 shown = Array('notinc');  
                 hidden = Array('notexc','bystatus');  
             }  
             if ((curraccess == 'all') || (curraccess == 'dh') || (curraccess == 'da')) {  
                 hidden = Array('notinc','notexc','bystatus');  
             }  
         }  
     }  
     if (hidden.length > 0) {  
         for (var i=0; i<hidden.length; i++) {  
             if (document.getElementById('helproles_'+num+'_'+hidden[i])) {  
                 document.getElementById('helproles_'+num+'_'+hidden[i]).style.display = 'none';  
             }  
         }  
     }  
     if (shown.length > 0) {  
         for (var i=0; i<shown.length; i++) {  
             if (document.getElementById('helproles_'+num+'_'+shown[i])) {  
                 if (shown[i] == 'privs') {  
                     document.getElementById('helproles_'+num+'_'+shown[i]).style.display = 'block';  
                 } else {  
                     document.getElementById('helproles_'+num+'_'+shown[i]).style.display = 'inline-block';  
                 }  
             }  
         }  
     }  
     return;  
 }  
   
 function toggleHelpdeskItem(num,field) {  
     if (document.getElementById('helproles_'+num+'_'+field)) {  
         if (document.getElementById('helproles_'+num+'_'+field).className.match(/(?:^|\\s)LC_hidden(?!\\S)/)) {  
             document.getElementById('helproles_'+num+'_'+field).className =  
                 document.getElementById('helproles_'+num+'_'+field).className.replace(/(?:^|\\s)LC_hidden(?!\\S)/g ,'');  
             if (document.getElementById('helproles_'+num+'_'+field+'_vis')) {  
                 document.getElementById('helproles_'+num+'_'+field+'_vis').value = '$html_js_lt{hide}';  
             }  
         } else {  
             document.getElementById('helproles_'+num+'_'+field).className += ' LC_hidden';  
             if (document.getElementById('helproles_'+num+'_'+field+'_vis')) {  
                 document.getElementById('helproles_'+num+'_'+field+'_vis').value = '$html_js_lt{show}';  
             }  
         }  
     }  
     return;  
 }  
   
 // ]]>  
 </script>  
   
 ENDSCRIPT  
 }  
   
 sub helpdeskroles_access {  
     my ($dom,$prefix,$num,$add_class,$current,$accesstypes,$othertitle,  
         $usertypes,$types,$domhelpdesk) = @_;  
     return unless ((ref($accesstypes) eq 'ARRAY') && (ref($domhelpdesk) eq 'HASH'));  
     my %lt = &Apache::lonlocal::texthash(  
                     'rou'    => 'Role usage',  
                     'whi'    => 'Which helpdesk personnel may use this role?',  
                     'all'    => 'All with domain helpdesk or helpdesk assistant role',  
                     'dh'     => 'All with domain helpdesk role',  
                     'da'     => 'All with domain helpdesk assistant role',  
                     'none'   => 'None',  
                     'status' => 'Determined based on institutional status',  
                     'inc'    => 'Include all, but exclude specific personnel',  
                     'exc'    => 'Exclude all, but include specific personnel',  
                   );  
     my %usecheck = (  
                      all => ' checked="checked"',  
                    );  
     my %displaydiv = (  
                       status => 'none',  
                       inc    => 'none',  
                       exc    => 'none',  
                       priv   => 'block',  
                      );  
     my $output;  
     if (ref($current) eq 'HASH') {  
         if (($current->{'access'} ne '') && ($current->{'access'} ne 'all')) {  
             if (grep(/^\Q$current->{access}\E$/,@{$accesstypes})) {  
                 $usecheck{$current->{access}} = $usecheck{'all'};  
                 delete($usecheck{'all'});  
                 if ($current->{access} =~ /^(status|inc|exc)$/) {  
                     my $access = $1;  
                     $displaydiv{$access} = 'inline';  
                 } elsif ($current->{access} eq 'none') {  
                     $displaydiv{'priv'} = 'none';  
                 }  
             }  
         }  
     }  
     $output = '<fieldset id="'.$prefix.$num.'_usage"><legend>'.$lt{'rou'}.'</legend>'.  
               '<p>'.$lt{'whi'}.'</p>';  
     foreach my $access (@{$accesstypes}) {  
         $output .= '<p><label><input type="radio" name="'.$prefix.$num.'_access" value="'.$access.'" '.$usecheck{$access}.  
                    ' onclick="helpdeskAccess('."'$num'".');" />'.  
                    $lt{$access}.'</label>';  
         if ($access eq 'status') {  
             $output .= '<div id="'.$prefix.$num.'_bystatus" style="display:'.$displaydiv{$access}.'">'.  
                        &Apache::lonuserutils::adhoc_status_types($dom,$prefix,$num,$current->{$access},  
                                                                  $othertitle,$usertypes,$types).  
                        '</div>';  
         } elsif (($access eq 'inc') && (keys(%{$domhelpdesk}) > 0)) {  
             $output .= '<div id="'.$prefix.$num.'_notinc" style="display:'.$displaydiv{$access}.'">'.  
                        &Apache::lonuserutils::adhoc_staff($access,$prefix,$num,$current->{$access},$domhelpdesk).  
                        '</div>';  
         } elsif (($access eq 'exc') && (keys(%{$domhelpdesk}) > 0)) {  
             $output .= '<div id="'.$prefix.$num.'_notexc" style="display:'.$displaydiv{$access}.'">'.  
                        &Apache::lonuserutils::adhoc_staff($access,$prefix,$num,$current->{$access},$domhelpdesk).  
                        '</div>';  
         }  
         $output .= '</p>';  
     }  
     $output .= '</fieldset>';  
     return $output;  
 }  }
   
 sub radiobutton_prefs {  sub radiobutton_prefs {
Line 3721  sub radiobutton_prefs { Line 3083  sub radiobutton_prefs {
         } else {          } else {
             $datatable .= '<td class="LC_right_item">';              $datatable .= '<td class="LC_right_item">';
         }          }
         $datatable .=          $datatable .= 
             '<span class="LC_nobreak">'.              '<span class="LC_nobreak">'.
             '<label><input type="radio" name="'.              '<label><input type="radio" name="'.
             $item.'" '.$checkedon{$item}.' value="1"'.$onclick.' />'.&mt('Yes').              $item.'" '.$checkedon{$item}.' value="1"'.$onclick.' />'.&mt('Yes').
Line 3815  sub print_ltitools { Line 3177  sub print_ltitools {
             if (ref($settings->{$item}->{'display'}) eq 'HASH') {              if (ref($settings->{$item}->{'display'}) eq 'HASH') {
                 if ($settings->{$item}->{'display'}->{'target'} eq 'window') {                  if ($settings->{$item}->{'display'}->{'target'} eq 'window') {
                     $currdisp{'window'} = ' checked="checked"';                      $currdisp{'window'} = ' checked="checked"';
                 } elsif ($settings->{$item}->{'display'}->{'target'} eq 'tab') {  
                     $currdisp{'tab'} = ' checked="checked"';  
                 } else {                  } else {
                     $currdisp{'iframe'} = ' checked="checked"';                      $currdisp{'iframe'} = ' checked="checked"';
                 }                  }
Line 3826  sub print_ltitools { Line 3186  sub print_ltitools {
                 if ($settings->{$item}->{'display'}->{'height'} =~ /^(\d+)$/) {                  if ($settings->{$item}->{'display'}->{'height'} =~ /^(\d+)$/) {
                      $currdisp{'height'} = $1;                       $currdisp{'height'} = $1;
                 }                  }
                 $currdisp{'linktext'} = $settings->{$item}->{'display'}->{'linktext'};  
                 $currdisp{'explanation'} = $settings->{$item}->{'display'}->{'explanation'};  
             } else {              } else {
                 $currdisp{'iframe'} = ' checked="checked"';                  $currdisp{'iframe'} = ' checked="checked"';
             }              }
             foreach my $disp ('iframe','tab','window') {              foreach my $disp ('iframe','window') {
                 $datatable .= '<label><input type="radio" name="ltitools_target_'.$i.'" value="'.$disp.'"'.$currdisp{$disp}.' />'.                  $datatable .= '<label><input type="radio" name="ltitools_target_'.$i.'" value="'.$disp.'"'.$currdisp{$disp}.' />'.
                               $lt{$disp}.'</label>'.('&nbsp;'x2);                                $lt{$disp}.'</label>'.('&nbsp;'x2);
             }              }
Line 3841  sub print_ltitools { Line 3199  sub print_ltitools {
                               '<input type="text" name="ltitools_'.$dimen.'_'.$i.'" size="5" value="'.$currdisp{$dimen}.'" /></label>'.                                '<input type="text" name="ltitools_'.$dimen.'_'.$i.'" size="5" value="'.$currdisp{$dimen}.'" /></label>'.
                               ('&nbsp;'x2);                                ('&nbsp;'x2);
             }              }
             $datatable .= '<br />'.  
                           '<div class="LC_left_float">'.$lt{'linktext'}.'<br />'.  
                           '<input type="text" name="ltitools_linktext_'.$i.'" size="25" value="'.$currdisp{'linktext'}.'" /></label></div>'.  
                           '<div class="LC_left_float">'.$lt{'explanation'}.'<br />'.  
                           '<textarea name="ltitools_explanation_'.$i.'" rows="5" cols="40">'.$currdisp{'explanation'}.  
                           '</textarea></div><div style=""></div><br />';  
             $datatable .= '<br />';              $datatable .= '<br />';
             foreach my $extra ('passback','roster') {              foreach my $extra ('passback','roster') {
                 my $checkedon = '';                  my $checkedon = '';
Line 3904  sub print_ltitools { Line 3256  sub print_ltitools {
                 if (!$rolemaps{$role}) {                  if (!$rolemaps{$role}) {
                     $selectnone = ' selected="selected"';                      $selectnone = ' selected="selected"';
                 }                  }
                 $datatable .= '<td align="center">'.                  $datatable .= '<td align="center">'. 
                               &Apache::lonnet::plaintext($role,'Course').'<br />'.                                &Apache::lonnet::plaintext($role,'Course').'<br />'.
                               '<select name="ltitools_roles_'.$role.'_'.$i.'">'.                                '<select name="ltitools_roles_'.$role.'_'.$i.'">'.
                               '<option value=""'.$selectnone.'>'.&mt('Select').'</option>';                                '<option value=""'.$selectnone.'>'.&mt('Select').'</option>';
Line 3928  sub print_ltitools { Line 3280  sub print_ltitools {
                 }                  }
             }              }
             $datatable .= '<fieldset><legend>'.&mt('Configurable in course').'</legend><span class="LC_nobreak">';              $datatable .= '<fieldset><legend>'.&mt('Configurable in course').'</legend><span class="LC_nobreak">';
             foreach my $item ('label','title','target','linktext','explanation') {              foreach my $item ('label','title','target') {
                 my $checked;                  my $checked;
                 if ($courseconfig{$item}) {                  if ($courseconfig{$item}) {
                     $checked = ' checked="checked"';                      $checked = ' checked="checked"';
Line 3996  sub print_ltitools { Line 3348  sub print_ltitools {
                   '<span class="LC_nobreak">'.&mt('Display target:');                    '<span class="LC_nobreak">'.&mt('Display target:');
     my %defaultdisp;      my %defaultdisp;
     $defaultdisp{'iframe'} = ' checked="checked"';      $defaultdisp{'iframe'} = ' checked="checked"';
     foreach my $disp ('iframe','tab','window') {      foreach my $disp ('iframe','window') {
         $datatable .= '<label><input type="radio" name="ltitools_add_target" value="'.$disp.'"'.$defaultdisp{$disp}.' />'.          $datatable .= '<label><input type="radio" name="ltitools_add_target" value="'.$disp.'"'.$defaultdisp{$disp}.' />'.
                       $lt{$disp}.'</label>'.('&nbsp;'x2);                        $lt{$disp}.'</label>'.('&nbsp;'x2);
     }      }
Line 4006  sub print_ltitools { Line 3358  sub print_ltitools {
                       '<input type="text" name="ltitools_add_'.$dimen.'" size="5" /></label>'.                        '<input type="text" name="ltitools_add_'.$dimen.'" size="5" /></label>'.
                       ('&nbsp;'x2);                        ('&nbsp;'x2);
     }      }
     $datatable .= '<br />'.      $datatable .= '<br />';
                   '<div class="LC_left_float">'.$lt{'linktext'}.'<br />'.  
                   '<input type="text" name="ltitools_add_linktext" size="5" /></label></div>'.  
                   '<div class="LC_left_float">'.$lt{'explanation'}.'<br />'.  
                   '<textarea name=ltitools_add_explanation" rows="5" cols="40"></textarea>'.  
                   '</div><div style=""></div><br />';  
     foreach my $extra ('passback','roster') {      foreach my $extra ('passback','roster') {
         $datatable .= $lt{$extra}.'&nbsp;'.          $datatable .= $lt{$extra}.'&nbsp;'.
                       '<label><input type="radio" name="ltitools_add_'.$extra.'" value="1" />'.                        '<label><input type="radio" name="ltitools_add_'.$extra.'" value="1" />'.
Line 4049  sub print_ltitools { Line 3396  sub print_ltitools {
     }      }
     $datatable .= '</tr></table></fieldset>'.      $datatable .= '</tr></table></fieldset>'.
                   '<fieldset><legend>'.&mt('Configurable in course').'</legend><span class="LC_nobreak">';                    '<fieldset><legend>'.&mt('Configurable in course').'</legend><span class="LC_nobreak">';
     foreach my $item ('label','title','target','linktext','explanation') {      foreach my $item ('label','title','target') {
         $datatable .= '<label>'.           $datatable .= '<label>'.
                       '<input type="checkbox" name="ltitools_courseconfig" value="'.$item.'" checked="checked" />'.                         '<input type="checkbox" name="ltitools_courseconfig" value="'.$item.'" checked="checked" />'.
                       $lt{'crs'.$item}.'</label>'.('&nbsp;' x2)."\n";                         $lt{'crs'.$item}.'</label>'.('&nbsp;' x2)."\n";
     }      }
     $datatable .= '</span></fieldset>'.      $datatable .= '</span></fieldset>'.
                   '<fieldset><legend>'.&mt('Custom items sent on launch').'</legend>'.                    '<fieldset><legend>'.&mt('Custom items sent on launch').'</legend>'.
Line 4070  sub print_ltitools { Line 3417  sub print_ltitools {
   
 sub ltitools_names {  sub ltitools_names {
     my %lt = &Apache::lonlocal::texthash(      my %lt = &Apache::lonlocal::texthash(
                                           'title'          => 'Title',                                            'title'     => 'Title',
                                           'version'        => 'Version',                                            'version'   => 'Version',
                                           'msgtype'        => 'Message Type',                                            'msgtype'   => 'Message Type',
                                           'url'            => 'URL',                                            'url'       => 'URL',
                                           'key'            => 'Key',                                            'key'       => 'Key',
                                           'secret'         => 'Secret',                                            'secret'    => 'Secret',
                                           'icon'           => 'Icon',                                            'icon'      => 'Icon',   
                                           'user'           => 'Username:domain',                                            'user'      => 'Username:domain',
                                           'fullname'       => 'Full Name',                                            'fullname'  => 'Full Name',
                                           'firstname'      => 'First Name',                                            'firstname' => 'First Name',
                                           'lastname'       => 'Last Name',                                            'lastname'  => 'Last Name',
                                           'email'          => 'E-mail',                                            'email'     => 'E-mail',
                                           'roles'          => 'Role',                                            'roles'     => 'Role',
                                           'window'         => 'Window',                                            'window'    => 'Window/Tab',
                                           'tab'            => 'Tab',                                            'iframe'    => 'iFrame',
                                           'iframe'         => 'iFrame',                                            'height'    => 'Height',
                                           'height'         => 'Height',                                            'width'     => 'Width',
                                           'width'          => 'Width',                                            'passback'  => 'Tool can return grades:',
                                           'linktext'       => 'Default Link Text',                                            'roster'    => 'Tool can retrieve roster:',
                                           'explanation'    => 'Default Explanation',                                            'crstarget' => 'Display target',
                                           'passback'       => 'Tool can return grades:',                                            'crslabel'  => 'Course label',
                                           'roster'         => 'Tool can retrieve roster:',                                            'crstitle'  => 'Course title', 
                                           'crstarget'      => 'Display target',  
                                           'crslabel'       => 'Course label',  
                                           'crstitle'       => 'Course title',  
                                           'crslinktext'    => 'Link Text',  
                                           'crsexplanation' => 'Explanation',  
                                         );                                          );
   
     return %lt;      return %lt;
 }  }
   
Line 4107  sub print_coursedefaults { Line 3448  sub print_coursedefaults {
     my ($css_class,$datatable,%checkedon,%checkedoff,%defaultchecked,@toggles);      my ($css_class,$datatable,%checkedon,%checkedoff,%defaultchecked,@toggles);
     my $itemcount = 1;      my $itemcount = 1;
     my %choices =  &Apache::lonlocal::texthash (      my %choices =  &Apache::lonlocal::texthash (
           canuse_pdfforms      => 'Course/Community users can create/upload PDF forms',
         uploadquota          => 'Default quota for files uploaded directly to course/community using Course Editor (MB)',          uploadquota          => 'Default quota for files uploaded directly to course/community using Course Editor (MB)',
         anonsurvey_threshold => 'Responder count needed before showing submissions for anonymous surveys',          anonsurvey_threshold => 'Responder count needed before showing submissions for anonymous surveys',
         coursecredits        => 'Credits can be specified for courses',          coursecredits        => 'Credits can be specified for courses',
Line 4124  sub print_coursedefaults { Line 3466  sub print_coursedefaults {
                          );                           );
     if ($position eq 'top') {      if ($position eq 'top') {
         %defaultchecked = (          %defaultchecked = (
                               'canuse_pdfforms' => 'off',
                             'uselcmath'       => 'on',                              'uselcmath'       => 'on',
                             'usejsme'         => 'on',                              'usejsme'         => 'on',
                             'canclone'        => 'none',                              'canclone'        => 'none', 
                           );                            );
         @toggles = ('uselcmath','usejsme');          @toggles = ('canuse_pdfforms','uselcmath','usejsme');
         ($datatable,$itemcount) = &radiobutton_prefs($settings,\@toggles,\%defaultchecked,          ($datatable,$itemcount) = &radiobutton_prefs($settings,\@toggles,\%defaultchecked,
                                                      \%choices,$itemcount);                                                       \%choices,$itemcount);
         $css_class = $itemcount%2?' class="LC_odd_row"':'';          $css_class = $itemcount%2?' class="LC_odd_row"':'';
Line 4165  sub print_coursedefaults { Line 3508  sub print_coursedefaults {
                     $currcanclone = $settings->{'canclone'};                      $currcanclone = $settings->{'canclone'};
                 }                  }
             }              }
         }          } 
         foreach my $option (@cloneoptions) {          foreach my $option (@cloneoptions) {
             my ($checked,$additional);              my ($checked,$additional);
             if ($currcanclone eq $option) {              if ($currcanclone eq $option) {
Line 4207  sub print_coursedefaults { Line 3550  sub print_coursedefaults {
         my ($currdefresponder,%defcredits,%curruploadquota,%deftimeout,%currmysql);          my ($currdefresponder,%defcredits,%curruploadquota,%deftimeout,%currmysql);
         my $currusecredits = 0;          my $currusecredits = 0;
         my $postsubmitclient = 1;          my $postsubmitclient = 1;
         my @types = ('official','unofficial','community','textbook');          my @types = ('official','unofficial','community','textbook','placement');
         if (ref($settings) eq 'HASH') {          if (ref($settings) eq 'HASH') {
             $currdefresponder = $settings->{'anonsurvey_threshold'};              $currdefresponder = $settings->{'anonsurvey_threshold'};
             if (ref($settings->{'uploadquota'}) eq 'HASH') {              if (ref($settings->{'uploadquota'}) eq 'HASH') {
Line 4234  sub print_coursedefaults { Line 3577  sub print_coursedefaults {
                     foreach my $type (@types) {                      foreach my $type (@types) {
                         if (ref($settings->{'postsubmit'}->{'timeout'}) eq 'HASH') {                          if (ref($settings->{'postsubmit'}->{'timeout'}) eq 'HASH') {
                             if ($settings->{'postsubmit'}->{'timeout'}->{$type} =~ /^\d+$/) {                              if ($settings->{'postsubmit'}->{'timeout'}->{$type} =~ /^\d+$/) {
                                 $deftimeout{$type} = $settings->{'postsubmit'}->{'timeout'}->{$type};                                  $deftimeout{$type} = $settings->{'postsubmit'}->{'timeout'}->{$type}; 
                             } else {                              } else {
                                 $deftimeout{$type} = $staticdefaults{'postsubmit'};                                  $deftimeout{$type} = $staticdefaults{'postsubmit'};
                             }                              }
Line 4350  sub print_coursedefaults { Line 3693  sub print_coursedefaults {
         foreach my $type (@types) {          foreach my $type (@types) {
             $datatable .= '<td align="center">'.&mt($type).'<br />'.              $datatable .= '<td align="center">'.&mt($type).'<br />'.
                            '<input type="text" name="mysqltables_'.$type.'"'.                             '<input type="text" name="mysqltables_'.$type.'"'.
                            ' value="'.$currmysql{$type}.'" size="8" /></td>';                             ' value="'.$currmysql{$type}.'" size="5" /></td>';
         }          }
         $datatable .= '</tr></table></td></tr>'."\n";          $datatable .= '</tr></table></td></tr>'."\n";
         $itemcount ++;          $itemcount ++;
Line 4364  sub print_selfenrollment { Line 3707  sub print_selfenrollment {
     my ($position,$dom,$settings,$rowtotal) = @_;      my ($position,$dom,$settings,$rowtotal) = @_;
     my ($css_class,$datatable);      my ($css_class,$datatable);
     my $itemcount = 1;      my $itemcount = 1;
     my @types = ('official','unofficial','community','textbook');      my @types = ('official','unofficial','community','textbook','placement');
     if (($position eq 'top') || ($position eq 'middle')) {      if (($position eq 'top') || ($position eq 'middle')) {
         my ($rowsref,$titlesref) = &Apache::lonuserutils::get_selfenroll_titles();          my ($rowsref,$titlesref) = &Apache::lonuserutils::get_selfenroll_titles();
         my %descs = &Apache::lonuserutils::selfenroll_default_descs();          my %descs = &Apache::lonuserutils::selfenroll_default_descs();
Line 4587  sub print_validation_rows { Line 3930  sub print_validation_rows {
   
 sub print_usersessions {  sub print_usersessions {
     my ($position,$dom,$settings,$rowtotal) = @_;      my ($position,$dom,$settings,$rowtotal) = @_;
     my ($css_class,$datatable,%checked,%choices);      my ($css_class,$datatable,$itemcount,%checked,%choices);
     my (%by_ip,%by_location,@intdoms);      my (%by_ip,%by_location,@intdoms,@instdoms);
     &build_location_hashes(\@intdoms,\%by_ip,\%by_location);      &build_location_hashes(\@intdoms,\%by_ip,\%by_location,\@instdoms);
   
     my @alldoms = &Apache::lonnet::all_domains();      my @alldoms = &Apache::lonnet::all_domains();
     my %serverhomes = %Apache::lonnet::serverhomeIDs;      my %serverhomes = %Apache::lonnet::serverhomeIDs;
     my %servers = &Apache::lonnet::internet_dom_servers($dom);      my %servers = &Apache::lonnet::internet_dom_servers($dom);
     my %altids = &id_for_thisdom(%servers);      my %altids = &id_for_thisdom(%servers);
     my $itemcount = 1;  
     if ($position eq 'top') {      if ($position eq 'top') {
         if (keys(%serverhomes) > 1) {          if (keys(%serverhomes) > 1) {
             my %spareid = &current_offloads_to($dom,$settings,\%servers);              my %spareid = &current_offloads_to($dom,$settings,\%servers);
Line 4608  sub print_usersessions { Line 3950  sub print_usersessions {
             $datatable .= &spares_row($dom,\%servers,\%spareid,\%serverhomes,\%altids,$curroffloadnow,$rowtotal);              $datatable .= &spares_row($dom,\%servers,\%spareid,\%serverhomes,\%altids,$curroffloadnow,$rowtotal);
         } else {          } else {
             $datatable .= '<tr'.$css_class.'><td colspan="2">'.              $datatable .= '<tr'.$css_class.'><td colspan="2">'.
                           &mt('Nothing to set here, as the cluster to which this domain belongs only contains one server.');                            &mt('Nothing to set here, as the cluster to which this domain belongs only contains one server.').
                             '</td></tr>';
         }          }
     } else {      } else {
         if (keys(%by_location) == 0) {          my %titles = &usersession_titles();
             $datatable .= '<tr'.$css_class.'><td colspan="2">'.          my ($prefix,@types);
                           &mt('Nothing to set here, as the cluster to which this domain belongs only contains one institution.');          if ($position eq 'bottom') {
               $prefix = 'remote';
               @types = ('version','excludedomain','includedomain');
         } else {          } else {
             my %lt = &usersession_titles();              $prefix = 'hosted';
             my $numinrow = 5;              @types = ('excludedomain','includedomain');
             my $prefix;          }
             my @types;          ($datatable,$itemcount) = &rules_by_location($settings,$prefix,\%by_location,\%by_ip,\@types,\%titles);
             if ($position eq 'bottom') {      }
                 $prefix = 'remote';      $$rowtotal += $itemcount;
                 @types = ('version','excludedomain','includedomain');      return $datatable;
             } else {  }
                 $prefix = 'hosted';  
                 @types = ('excludedomain','includedomain');  sub rules_by_location {
             }      my ($settings,$prefix,$by_location,$by_ip,$types,$titles) = @_; 
             my (%current,%checkedon,%checkedoff);      my ($datatable,$itemcount,$css_class);
             my @lcversions = &Apache::lonnet::all_loncaparevs();      if (keys(%{$by_location}) == 0) {
             my @locations = sort(keys(%by_location));          $css_class = $itemcount%2 ? ' class="LC_odd_row"' : '';
             foreach my $type (@types) {          $datatable = '<tr'.$css_class.'><td colspan="2">'.
                 $checkedon{$type} = '';                       &mt('Nothing to set here, as the cluster to which this domain belongs only contains one institution.').
                 $checkedoff{$type} = ' checked="checked"';                       '</td></tr>';
             }          $itemcount = 1;
             if (ref($settings) eq 'HASH') {      } else {
                 if (ref($settings->{$prefix}) eq 'HASH') {          $itemcount = 0;
                     foreach my $key (keys(%{$settings->{$prefix}})) {          my $numinrow = 5;
                         $current{$key} = $settings->{$prefix}{$key};          my (%current,%checkedon,%checkedoff);
                         if ($key eq 'version') {          my @locations = sort(keys(%{$by_location}));
                             if ($current{$key} ne '') {          foreach my $type (@{$types}) {
                                 $checkedon{$key} = ' checked="checked"';              $checkedon{$type} = '';
                                 $checkedoff{$key} = '';              $checkedoff{$type} = ' checked="checked"';
                             }          }
                         } elsif (ref($current{$key}) eq 'ARRAY') {          if (ref($settings) eq 'HASH') {
               if (ref($settings->{$prefix}) eq 'HASH') {
                   foreach my $key (keys(%{$settings->{$prefix}})) {
                       $current{$key} = $settings->{$prefix}{$key};
                       if ($key eq 'version') {
                           if ($current{$key} ne '') {
                             $checkedon{$key} = ' checked="checked"';                              $checkedon{$key} = ' checked="checked"';
                             $checkedoff{$key} = '';                              $checkedoff{$key} = '';
                         }                          }
                       } elsif (ref($current{$key}) eq 'ARRAY') {
                           $checkedon{$key} = ' checked="checked"';
                           $checkedoff{$key} = '';
                     }                      }
                 }                  }
             }              }
             foreach my $type (@types) {          }
                 next if ($type ne 'version' && !@locations);          foreach my $type (@{$types}) {
                 $css_class = $itemcount%2 ? ' class="LC_odd_row"' : '';              next if ($type ne 'version' && !@locations);
                 $datatable .= '<tr'.$css_class.'>              $css_class = $itemcount%2 ? ' class="LC_odd_row"' : '';
                                <td><span class="LC_nobreak">'.$lt{$type}.'</span><br />              $datatable .= '<tr'.$css_class.'>
                                <span class="LC_nobreak">&nbsp;                             <td><span class="LC_nobreak">'.$titles->{$type}.'</span><br />
                                <label><input type="radio" name="'.$prefix.'_'.$type.'_inuse" '.$checkedoff{$type}.' value="0" />'.&mt('Not in use').'</label>&nbsp;                             <span class="LC_nobreak">&nbsp;
                                <label><input type="radio" name="'.$prefix.'_'.$type.'_inuse" '.$checkedon{$type}.' value="1" />'.&mt('In use').'</label></span></td><td>';                             <label><input type="radio" name="'.$prefix.'_'.$type.'_inuse" '.$checkedoff{$type}.' value="0" />'.&mt('Not in use').'</label>&nbsp;
                 if ($type eq 'version') {                             <label><input type="radio" name="'.$prefix.'_'.$type.'_inuse" '.$checkedon{$type}.' value="1" />'.&mt('In use').'</label></span></td><td>';
                     my $selector = '<select name="'.$prefix.'_version">';              if ($type eq 'version') {
                     foreach my $version (@lcversions) {                  my @lcversions = &Apache::lonnet::all_loncaparevs();
                         my $selected = '';                  my $selector = '<select name="'.$prefix.'_version">';
                         if ($current{'version'} eq $version) {                  foreach my $version (@lcversions) {
                             $selected = ' selected="selected"';                      my $selected = '';
                         }                      if ($current{'version'} eq $version) {
                         $selector .= ' <option value="'.$version.'"'.                          $selected = ' selected="selected"';
                                      $selected.'>'.$version.'</option>';  
                     }                      }
                     $selector .= '</select> ';                      $selector .= ' <option value="'.$version.'"'.
                     $datatable .= &mt('remote server must be version: [_1] or later',$selector);                                   $selected.'>'.$version.'</option>';
                 } else {                  }
                     $datatable.= '<div><input type="button" value="'.&mt('check all').'" '.                  $selector .= '</select> ';
                                  'onclick="javascript:checkAll(document.display.'.$prefix.'_'.$type.')"'.                  $datatable .= &mt('remote server must be version: [_1] or later',$selector);
                                  ' />'.('&nbsp;'x2).              } else {
                                  '<input type="button" value="'.&mt('uncheck all').'" '.                  $datatable.= '<div><input type="button" value="'.&mt('check all').'" '.
                                  'onclick="javascript:uncheckAll(document.display.'.$prefix.'_'.$type.')" />'.                               'onclick="javascript:checkAll(document.display.'.$prefix.'_'.$type.')"'.
                                  "\n".                               ' />'.('&nbsp;'x2).
                                  '</div><div><table>';                               '<input type="button" value="'.&mt('uncheck all').'" '.
                     my $rem;                               'onclick="javascript:uncheckAll(document.display.'.$prefix.'_'.$type.')" />'.
                     for (my $i=0; $i<@locations; $i++) {                               "\n".
                         my ($showloc,$value,$checkedtype);                               '</div><div><table>';
                         if (ref($by_location{$locations[$i]}) eq 'ARRAY') {                  my $rem;
                             my $ip = $by_location{$locations[$i]}->[0];                  for (my $i=0; $i<@locations; $i++) {
                             if (ref($by_ip{$ip}) eq 'ARRAY') {                      my ($showloc,$value,$checkedtype);
                                  $value = join(':',@{$by_ip{$ip}});                      if (ref($by_location->{$locations[$i]}) eq 'ARRAY') {
                                 $showloc = join(', ',@{$by_ip{$ip}});                          my $ip = $by_location->{$locations[$i]}->[0];
                                 if (ref($current{$type}) eq 'ARRAY') {                          if (ref($by_ip->{$ip}) eq 'ARRAY') {
                                     foreach my $loc (@{$by_ip{$ip}}) {                                $value = join(':',@{$by_ip->{$ip}});
                                         if (grep(/^\Q$loc\E$/,@{$current{$type}})) {                              $showloc = join(', ',@{$by_ip->{$ip}});
                                             $checkedtype = ' checked="checked"';                              if (ref($current{$type}) eq 'ARRAY') {
                                             last;                                  foreach my $loc (@{$by_ip->{$ip}}) {
                                         }                                      if (grep(/^\Q$loc\E$/,@{$current{$type}})) {
                                           $checkedtype = ' checked="checked"';
                                           last;
                                     }                                      }
                                 }                                  }
                             }                              }
                         }                          }
                         $rem = $i%($numinrow);  
                         if ($rem == 0) {  
                             if ($i > 0) {  
                                 $datatable .= '</tr>';  
                             }  
                             $datatable .= '<tr>';  
                         }  
                         $datatable .= '<td class="LC_left_item">'.  
                                       '<span class="LC_nobreak"><label>'.  
                                       '<input type="checkbox" name="'.$prefix.'_'.$type.  
                                       '" value="'.$value.'"'.$checkedtype.' />'.$showloc.  
                                       '</label></span></td>';  
                     }                      }
                     $rem = @locations%($numinrow);                      $rem = $i%($numinrow);
                     my $colsleft = $numinrow - $rem;                      if ($rem == 0) {
                     if ($colsleft > 1 ) {                          if ($i > 0) {
                         $datatable .= '<td colspan="'.$colsleft.'" class="LC_left_item">'.                              $datatable .= '</tr>';
                                       '&nbsp;</td>';                          }
                     } elsif ($colsleft == 1) {                          $datatable .= '<tr>';
                         $datatable .= '<td class="LC_left_item">&nbsp;</td>';                      }
                       $datatable .= '<td class="LC_left_item">'.
                                     '<span class="LC_nobreak"><label>'.
                                     '<input type="checkbox" name="'.$prefix.'_'.$type.
                                     '" value="'.$value.'"'.$checkedtype.' />'.$showloc.
                                     '</label></span></td>';
                   }
                   $rem = @locations%($numinrow);
                   my $colsleft = $numinrow - $rem;
                   if ($colsleft > 1 ) {
                       $datatable .= '<td colspan="'.$colsleft.'" class="LC_left_item">'.
                                     '&nbsp;</td>';
                   } elsif ($colsleft == 1) {
                       $datatable .= '<td class="LC_left_item">&nbsp;</td>';
                   }
                   $datatable .= '</tr></table>';
               }
               $datatable .= '</td></tr>';
               $itemcount ++;
           }
       }
       return ($datatable,$itemcount);
   }
   
   sub print_ssl {
       my ($position,$dom,$settings,$rowtotal) = @_;
       my ($css_class,$datatable);
       my $lonhost = '';
       my $itemcount = 1;
       if ($position eq 'top') {
           my %domservers = &Apache::lonnet::get_servers($dom);
           $css_class = $itemcount%2?' class="LC_odd_row"':'';
           $datatable = '<tr'.$css_class.'><td colspan="2">'.
                        &LONCAPA::SSL::print_certstatus(\%domservers,'web','domprefs').
                        '</td></tr>';
           $itemcount ++;
       } else {
           my %titles = &ssl_titles();
           my (%by_ip,%by_location,@intdoms,@instdoms);
           &build_location_hashes(\@intdoms,\%by_ip,\%by_location,\@instdoms);
           my @alldoms = &Apache::lonnet::all_domains();
           my %serverhomes = %Apache::lonnet::serverhomeIDs;
           my @domservers = &Apache::lonnet::get_servers($dom);
           my %servers = &Apache::lonnet::internet_dom_servers($dom);
           my %altids = &id_for_thisdom(%servers);
           if ($position eq 'middle') {
               foreach my $type ('dom','intdom','other') {
                   my %checked;
                   $css_class = $itemcount%2?' class="LC_odd_row"':'';
                   $datatable .= '<tr'.$css_class.'><td>'.$titles{$type}.'</td>'.
                                 '<td class="LC_right_item">';
                   my $skip; 
                   if ($type eq 'dom') {
                       unless (keys(%servers) > 1) {
                           $datatable .= &mt('Nothing to set here, as there are no other servers/VMs');    
                           $skip = 1;
                       }
                   }
                   if ($type eq 'intdom') {
                       unless (@instdoms > 1) {
                           $datatable .= &mt('Nothing to set here, as there are no other domains for this institution');
                           $skip = 1;
                       } 
                   } elsif ($type eq 'other') {
                       if (keys(%by_location) == 0) {
                           $datatable .= &mt('Nothing to set here, as there are no other institutions');
                           $skip = 1;
                       }
                   }
                   unless ($skip) {
                       $checked{'yes'} = ' checked="checked"'; 
                       if (ref($settings) eq 'HASH') {
                           if (ref($settings->{'connect'}) eq 'HASH') {
                               if ($settings->{'connect'}->{$type} =~ /^(no|req)$/) {
                                   $checked{$1} = $checked{'yes'};
                                   delete($checked{'yes'}); 
                               }
                           }
                       }
                       foreach my $option ('no','yes','req') {
                           $datatable .= '<span class="LC_nobreak"><label>'.
                                         '<input type="radio" name="connect_'.$type.'" '.
                                         'value="'.$option.'"'.$checked{$option}.' />'.$titles{$option}.
                                         '</label></span>'.('&nbsp;'x2);
                     }                      }
                     $datatable .= '</tr></table>';  
                 }                  }
                 $datatable .= '</td></tr>';                  $datatable .= '</td></tr>';
                   $itemcount ++; 
               }
           } else {
               my $prefix = 'replication';
               my @types = ('certreq','nocertreq');
               if (keys(%by_location) == 0) {
                   $datatable .= '<tr'.$css_class.'><td>'.
                                 &mt('Nothing to set here, as there are no other institutions').
                                 '</td></tr>';
                 $itemcount ++;                  $itemcount ++;
               } else {
                   ($datatable,$itemcount) = 
                       &rules_by_location($settings,$prefix,\%by_location,\%by_ip,\@types,\%titles);
             }              }
         }          }
     }      }
Line 4727  sub print_usersessions { Line 4163  sub print_usersessions {
     return $datatable;      return $datatable;
 }  }
   
   sub ssl_titles {
       return &Apache::lonlocal::texthash (
                  dom           => 'LON-CAPA servers/VMs from same domain',
                  intdom        => 'LON-CAPA servers/VMs from same "internet" domain',
                  other         => 'External LON-CAPA servers/VMs',
                  connect       => 'Connections to other servers',
                  replication   => 'Replicating content to other institutions',
                  certreq       => 'Client certificate required, but specific domains exempt',
                  nocertreq     => 'No client certificate required, except for specific domains',
                  no            => 'SSL not used',
                  yes           => 'SSL Optional (used if available)',
                  req           => 'SSL Required',
       );
   }
   
   sub print_trust {
       my ($prefix,$dom,$settings,$rowtotal) = @_;
       my ($css_class,$datatable,%checked,%choices);
       my (%by_ip,%by_location,@intdoms,@instdoms);
       &build_location_hashes(\@intdoms,\%by_ip,\%by_location,\@instdoms);
       my $itemcount = 1;
       my %titles = &trust_titles();
       my @types = ('exc','inc');
       if ($prefix eq 'top') {
           $prefix = 'content';
       } elsif ($prefix eq 'bottom') {
           $prefix = 'msg';
       }
       ($datatable,$itemcount) = &rules_by_location($settings,$prefix,\%by_location,\%by_ip,\@types,\%titles);
       $$rowtotal += $itemcount;
       return $datatable;
   }
   
   sub trust_titles {
       return &Apache::lonlocal::texthash(
                  content  => "Access to this domain's content by others",
                  shared   => "Access to other domain's content by this domain",
                  enroll   => "Enrollment in this domain's courses by others", 
                  othcoau  => "Co-author roles in this domain for others",
                  coaurem  => "Co-author roles for this domain's users elsewhere", 
                  domroles => "Domain roles in this domain assignable to others",
                  catalog  => "Course Catalog for this domain displayed elsewhere",
                  reqcrs   => "Requests for creation of courses in this domain by others",
                  msg      => "Users in other domains can send messages to this domain",
                  exc      => "Allow all, but exclude specific domains",
                  inc      => "Deny all, but include specific domains",
              );
   } 
   
 sub build_location_hashes {  sub build_location_hashes {
     my ($intdoms,$by_ip,$by_location) = @_;      my ($intdoms,$by_ip,$by_location,$instdoms) = @_;
     return unless((ref($intdoms) eq 'ARRAY') && (ref($by_ip) eq 'HASH') &&      return unless((ref($intdoms) eq 'ARRAY') && (ref($by_ip) eq 'HASH') &&
                   (ref($by_location) eq 'HASH'));                     (ref($by_location) eq 'HASH') && (ref($instdoms) eq 'ARRAY'));
     my %iphost = &Apache::lonnet::get_iphost();      my %iphost = &Apache::lonnet::get_iphost();
     my $primary_id = &Apache::lonnet::domain($env{'request.role.domain'},'primary');      my $primary_id = &Apache::lonnet::domain($env{'request.role.domain'},'primary');
     my $primary_ip = &Apache::lonnet::get_host_ip($primary_id);      my $primary_ip = &Apache::lonnet::get_host_ip($primary_id);
Line 4747  sub build_location_hashes { Line 4232  sub build_location_hashes {
             foreach my $id (@{$iphost{$ip}}) {              foreach my $id (@{$iphost{$ip}}) {
                 my $location = &Apache::lonnet::internet_dom($id);                  my $location = &Apache::lonnet::internet_dom($id);
                 if ($location) {                  if ($location) {
                     next if (grep(/^\Q$location\E$/,@{$intdoms}));                      if (grep(/^\Q$location\E$/,@{$intdoms})) {
                           my $dom = &Apache::lonnet::host_domain($id);
                           unless (grep(/^\Q$dom\E/,@{$instdoms})) {
                               push(@{$instdoms},$dom);
                           }
                           next;
                       }
                     if (ref($by_ip->{$ip}) eq 'ARRAY') {                      if (ref($by_ip->{$ip}) eq 'ARRAY') {
                         unless(grep(/^\Q$location\E$/,@{$by_ip->{$ip}})) {                          unless(grep(/^\Q$location\E$/,@{$by_ip->{$ip}})) {
                             push(@{$by_ip->{$ip}},$location);                              push(@{$by_ip->{$ip}},$location);
Line 4887  sub spares_row { Line 4378  sub spares_row {
                             <span class="LC_nobreak">'.                              <span class="LC_nobreak">'.
                           &mt('[_1] when busy, offloads to:'                            &mt('[_1] when busy, offloads to:'
                               ,'<b>'.$server.'</b>').'</span><br />'.                                ,'<b>'.$server.'</b>').'</span><br />'.
                           '<span class="LC_nobreak">'."\n".                            '<span class="LC_nobreak">'."\n". 
                           '<label><input type="checkbox" name="offloadnow" value="'.$server.'"'.$checkednow.' />'.                            '<label><input type="checkbox" name="offloadnow" value="'.$server.'"'.$checkednow.' />'.
                           '&nbsp;'.&mt('Switch active users on next access').'</label></span>'.                            '&nbsp;'.&mt('Switch active users on next access').'</label></span>'.
                           "\n";                            "\n";
Line 5094  sub print_loadbalancing { Line 4585  sub print_loadbalancing {
         my ($numspares,@spares) = &count_servers($lonhost,%servers);          my ($numspares,@spares) = &count_servers($lonhost,%servers);
         my @sparestypes = ('primary','default');          my @sparestypes = ('primary','default');
         my %typetitles = &sparestype_titles();          my %typetitles = &sparestype_titles();
         my %hostherechecked = (  
                                   no => ' checked="checked"',  
                               );  
         foreach my $sparetype (@sparestypes) {          foreach my $sparetype (@sparestypes) {
             my $targettable;              my $targettable;
             for (my $i=0; $i<$numspares; $i++) {              for (my $i=0; $i<$numspares; $i++) {
Line 5142  sub print_loadbalancing { Line 4630  sub print_loadbalancing {
                 $datatable .=  '<i>'.$typetitles{$sparetype}.'</i><br />'.                  $datatable .=  '<i>'.$typetitles{$sparetype}.'</i><br />'.
                                '<table><tr>'.$targettable.'</tr></table><br />';                                 '<table><tr>'.$targettable.'</tr></table><br />';
             }              }
             $hostherechecked{$sparetype} = '';  
             if (ref($currtargets{$lonhost}) eq 'HASH') {  
                 if (ref($currtargets{$lonhost}{$sparetype}) eq 'ARRAY') {  
                     if (grep(/^\Q$lonhost\E$/,@{$currtargets{$lonhost}{$sparetype}})) {  
                         $hostherechecked{$sparetype} = ' checked="checked"';  
                         $hostherechecked{'no'} = '';  
                     }  
                 }  
             }  
         }  
         $datatable .= &mt('Hosting on balancer itself').'<br />'.  
                       '<label><input type="radio" name="loadbalancing_target_'.$balnum.'_hosthere" value="no"'.  
                       $hostherechecked{'no'}.' />'.&mt('No').'</label><br />';  
         foreach my $sparetype (@sparestypes) {  
             $datatable .= '<label><input type="radio" name="loadbalancing_target_'.$balnum.'_hosthere" '.  
                           'value="'.$sparetype.'"'.$hostherechecked{$sparetype}.' /><i>'.$typetitles{$sparetype}.  
                           '</i></label><br />';  
         }          }
         $datatable .= '</div></td></tr>'.          $datatable .= '</div></td></tr>'.
                       &loadbalancing_rules($dom,$intdom,$currrules{$lonhost},                        &loadbalancing_rules($dom,$intdom,$currrules{$lonhost},
Line 5251  sub loadbalancing_titles { Line 4722  sub loadbalancing_titles {
            '_LC_ipchange'    => &mt('Non-SSO users with IP mismatch'),             '_LC_ipchange'    => &mt('Non-SSO users with IP mismatch'),
                      );                       );
     my @alltypes = ('_LC_adv','_LC_author','_LC_internetdom','_LC_external','_LC_ipchangesso','_LC_ipchange');      my @alltypes = ('_LC_adv','_LC_author','_LC_internetdom','_LC_external','_LC_ipchangesso','_LC_ipchange');
     my @available;  
     if (ref($types) eq 'ARRAY') {      if (ref($types) eq 'ARRAY') {
         @available = @{$types};          unshift(@alltypes,@{$types},'default');
     }      }
     unless (grep(/^default$/,@available)) {  
         push(@available,'default');  
     }  
     unshift(@alltypes,@available);  
     my %titles;      my %titles;
     foreach my $type (@alltypes) {      foreach my $type (@alltypes) {
         if ($type =~ /^_LC_/) {          if ($type =~ /^_LC_/) {
Line 5381  sub sparestype_titles { Line 4847  sub sparestype_titles {
   
 sub contact_titles {  sub contact_titles {
     my %titles = &Apache::lonlocal::texthash (      my %titles = &Apache::lonlocal::texthash (
                    'supportemail'    => 'Support E-mail address',                     'supportemail' => 'Support E-mail address',
                    'adminemail'      => 'Default Server Admin E-mail address',                     'adminemail'   => 'Default Server Admin E-mail address',
                    'errormail'       => 'Error reports to be e-mailed to',                     'errormail'    => 'Error reports to be e-mailed to',
                    'packagesmail'    => 'Package update alerts to be e-mailed to',                     'packagesmail' => 'Package update alerts to be e-mailed to',
                    'helpdeskmail'    => "Helpdesk requests from all users in this domain",                     'helpdeskmail' => 'Helpdesk requests to be e-mailed to',
                    'otherdomsmail'   => 'Helpdesk requests from users in other (unconfigured) domains',                     'lonstatusmail' => 'E-mail from nightly status check (warnings/errors)',
                    'lonstatusmail'   => 'E-mail from nightly status check (warnings/errors)',                     'requestsmail' => 'E-mail from course requests requiring approval',
                    'requestsmail'    => 'E-mail from course requests requiring approval',                     'updatesmail'  => 'E-mail from nightly check of LON-CAPA module integrity/updates',
                    'updatesmail'     => 'E-mail from nightly check of LON-CAPA module integrity/updates',  
                    'idconflictsmail' => 'E-mail from bi-nightly check for multiple users sharing same student/employee ID',                     'idconflictsmail' => 'E-mail from bi-nightly check for multiple users sharing same student/employee ID',
                  );                   );
     my %short_titles = &Apache::lonlocal::texthash (      my %short_titles = &Apache::lonlocal::texthash (
Line 5399  sub contact_titles { Line 4864  sub contact_titles {
     return (\%titles,\%short_titles);      return (\%titles,\%short_titles);
 }  }
   
 sub helpform_fields {  
     my %titles =  &Apache::lonlocal::texthash (  
                        'username'   => 'Name',  
                        'user'       => 'Username/domain',  
                        'phone'      => 'Phone',  
                        'cc'         => 'Cc e-mail',  
                        'course'     => 'Course Details',  
                        'section'    => 'Sections',  
                        'screenshot' => 'File upload',  
     );  
     my @fields = ('username','phone','user','course','section','cc','screenshot');  
     my %possoptions = (  
                         username     => ['yes','no','req'],  
                         phone        => ['yes','no','req'],  
                         user         => ['yes','no'],  
                         cc           => ['yes','no'],  
                         course       => ['yes','no'],  
                         section      => ['yes','no'],  
                         screenshot   => ['yes','no'],  
                       );  
     my %fieldoptions = &Apache::lonlocal::texthash (  
                          'yes'  => 'Optional',  
                          'req'  => 'Required',  
                          'no'   => "Not shown",  
     );  
     return (\@fields,\%titles,\%fieldoptions,\%possoptions);  
 }  
   
 sub tool_titles {  sub tool_titles {
     my %titles = &Apache::lonlocal::texthash (      my %titles = &Apache::lonlocal::texthash (
                      aboutme    => 'Personal web page',                       aboutme    => 'Personal web page',
Line 5437  sub tool_titles { Line 4874  sub tool_titles {
                      unofficial => 'Unofficial courses',                       unofficial => 'Unofficial courses',
                      community  => 'Communities',                       community  => 'Communities',
                      textbook   => 'Textbook courses',                       textbook   => 'Textbook courses',
                        placement  => 'Placement tests',
                  );                   );
     return %titles;      return %titles;
 }  }
Line 5447  sub courserequest_titles { Line 4885  sub courserequest_titles {
                                    unofficial => 'Unofficial',                                     unofficial => 'Unofficial',
                                    community  => 'Communities',                                     community  => 'Communities',
                                    textbook   => 'Textbook',                                     textbook   => 'Textbook',
                                      placement  => 'Placement tests',
                                    norequest  => 'Not allowed',                                     norequest  => 'Not allowed',
                                    approval   => 'Approval by Dom. Coord.',                                     approval   => 'Approval by Dom. Coord.',
                                    validate   => 'With validation',                                     validate   => 'With validation',
Line 5634  sub print_selfcreation { Line 5073  sub print_selfcreation {
     my %radiohash;      my %radiohash;
     my $numinrow = 4;      my $numinrow = 4;
     map { $radiohash{'cancreate_'.$_} = 1; } @selfcreate;      map { $radiohash{'cancreate_'.$_} = 1; } @selfcreate;
     my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom);  
     if ($position eq 'top') {      if ($position eq 'top') {
         my %choices = &Apache::lonlocal::texthash (          my %choices = &Apache::lonlocal::texthash (
                                                       cancreate_login      => 'Institutional Login',                                                        cancreate_login      => 'Institutional Login',
Line 5650  sub print_selfcreation { Line 5088  sub print_selfcreation {
                                                      \%choices,$itemcount,$onclick);                                                       \%choices,$itemcount,$onclick);
         $$rowtotal += $itemcount;          $$rowtotal += $itemcount;
                   
           my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom);
   
         if (ref($usertypes) eq 'HASH') {          if (ref($usertypes) eq 'HASH') {
             if (keys(%{$usertypes}) > 0) {              if (keys(%{$usertypes}) > 0) {
                 $datatable .= &insttypes_row($createsettings,$types,$usertypes,                  $datatable .= &insttypes_row($createsettings,$types,$usertypes,
                                              $dom,$numinrow,$othertitle,                                               $dom,$numinrow,$othertitle,
                                              'statustocreate',$rowtotal);                                               'statustocreate',$$rowtotal);
                 $$rowtotal ++;                  $$rowtotal ++;
             }              }
         }          }
Line 5699  sub print_selfcreation { Line 5139  sub print_selfcreation {
         $$rowtotal ++;          $$rowtotal ++;
     } elsif ($position eq 'middle') {      } elsif ($position eq 'middle') {
         my %domconf = &Apache::lonnet::get_dom('configuration',['usermodification'],$dom);          my %domconf = &Apache::lonnet::get_dom('configuration',['usermodification'],$dom);
         my @posstypes;          my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom);
           $usertypes->{'default'} = $othertitle;
         if (ref($types) eq 'ARRAY') {          if (ref($types) eq 'ARRAY') {
             @posstypes = @{$types};              push(@{$types},'default');
         }              $usertypes->{'default'} = $othertitle;
         unless (grep(/^default$/,@posstypes)) {              foreach my $status (@{$types}) {
             push(@posstypes,'default');                  $datatable .= &modifiable_userdata_row('selfcreate',$status,$domconf{'usermodification'},
         }                                                         $numinrow,$$rowtotal,$usertypes);
         my %usertypeshash;                  $$rowtotal ++;
         if (ref($usertypes) eq 'HASH') {              }
             %usertypeshash = %{$usertypes};  
         }  
         $usertypeshash{'default'} = $othertitle;  
         foreach my $status (@posstypes) {  
             $datatable .= &modifiable_userdata_row('selfcreate',$status,$domconf{'usermodification'},  
                                                    $numinrow,$$rowtotal,\%usertypeshash);  
             $$rowtotal ++;  
         }          }
     } else {      } else {
         my %choices = &Apache::lonlocal::texthash (          my %choices = &Apache::lonlocal::texthash (
Line 5732  sub print_selfcreation { Line 5166  sub print_selfcreation {
         my $onclick = "toggleDisplay(this.form,'emailoptions');";          my $onclick = "toggleDisplay(this.form,'emailoptions');";
         my $additional = '<div id="emailoptions" style="display: '.$display.'">';          my $additional = '<div id="emailoptions" style="display: '.$display.'">';
         my %domdefaults = &Apache::lonnet::get_domain_defaults($dom);          my %domdefaults = &Apache::lonnet::get_domain_defaults($dom);
         if (ref($domdefaults{'inststatusguest'}) eq 'ARRAY') {          my $usertypes = {};
           my $order = [];
           if ((ref($domdefaults{'inststatustypes'}) eq 'HASH') && (ref($domdefaults{'inststatusguest'}) eq 'ARRAY')) {
               $usertypes = $domdefaults{'inststatustypes'};
             $order = $domdefaults{'inststatusguest'};              $order = $domdefaults{'inststatusguest'};
         }          }
         my (@ordered,%usertypeshash);  
         if (ref($order) eq 'ARRAY') {          if (ref($order) eq 'ARRAY') {
             @ordered = @{$order};              push(@{$order},'default');
         }              if (@{$order} > 1) {
         if (@ordered) {                  $usertypes->{'default'} = &mt('Other users');
             unless (grep(/^default$/,@ordered)) {                  $additional .= '<table><tr>';
                 push(@ordered,'default');                  foreach my $status (@{$order}) {
             }                      $additional .= '<th>'.$usertypes->{$status}.'</th>';
             if (ref($usertypes) eq 'HASH') {                  }
                 %usertypeshash = %{$usertypes};                  $additional .= '</tr><tr>';
             }                  foreach my $status (@{$order}) {
             $usertypeshash{'default'} = $othertitle;                      $additional .= '<td>'.&email_as_username($rowtotal,$processing,$status).'</td>';
             $additional .= '<table><tr>';                  }
             foreach my $status (@ordered) {                  $additional .= '</tr></table>';
                 $additional .= '<th>'.$usertypeshash{$status}.'</th>';              } else {
             }                  $usertypes->{'default'} = &mt('All users');
             $additional .= '</tr><tr>';                  $additional .= &email_as_username($rowtotal,$processing);
             foreach my $status (@ordered) {  
                 $additional .= '<td>'.&email_as_username($rowtotal,$processing,$status).'</td>';  
             }              }
             $additional .= '</tr></table>';  
         } else {  
             $usertypeshash{'default'} = $othertitle;  
             $additional .= &email_as_username($rowtotal,$processing);  
         }          }
         $additional .= '</div>'."\n";          $additional .= '</div>'."\n";
   
Line 5769  sub print_selfcreation { Line 5199  sub print_selfcreation {
         $$rowtotal ++;          $$rowtotal ++;
         my ($infofields,$infotitles) = &Apache::loncommon::emailusername_info();          my ($infofields,$infotitles) = &Apache::loncommon::emailusername_info();
         $numinrow = 1;          $numinrow = 1;
         foreach my $status (@ordered) {          if (ref($order) eq 'ARRAY') {
             $datatable .= &modifiable_userdata_row('cancreate','emailusername_'.$status,$settings,              foreach my $status (@{$order}) {
                                                    $numinrow,$$rowtotal,\%usertypeshash,$infofields,$infotitles);                  $datatable .= &modifiable_userdata_row('cancreate','emailusername_'.$status,$settings,
             $$rowtotal ++;                                                         $numinrow,$$rowtotal,$usertypes,$infofields,$infotitles);
                   $$rowtotal ++;
               }
         }          }
         my ($emailrules,$emailruleorder) =          my ($emailrules,$emailruleorder) =
             &Apache::lonnet::inst_userrules($dom,'email');              &Apache::lonnet::inst_userrules($dom,'email');
Line 5844  sub email_as_username { Line 5276  sub email_as_username {
 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,
         $vertext,$currver);           $vertext,$currver);
     my %lt = &captcha_phrases();      my %lt = &captcha_phrases();
     $keyentry = 'hidden';      $keyentry = 'hidden';
     if ($context eq 'cancreate') {      if ($context eq 'cancreate') {
Line 6039  sub print_usermodification { Line 5471  sub print_usermodification {
 sub print_defaults {  sub print_defaults {
     my ($position,$dom,$settings,$rowtotal) = @_;      my ($position,$dom,$settings,$rowtotal) = @_;
     my $rownum = 0;      my $rownum = 0;
     my ($datatable,$css_class,$titles);      my ($datatable,$css_class);
     unless ($position eq 'bottom') {  
         $titles = &defaults_titles($dom);  
     }  
     if ($position eq 'top') {      if ($position eq 'top') {
         my @items = ('auth_def','auth_arg_def','lang_def','timezone_def',          my @items = ('auth_def','auth_arg_def','lang_def','timezone_def',
                      'datelocale_def','portal_def');                       'datelocale_def','portal_def');
Line 6055  sub print_defaults { Line 5484  sub print_defaults {
                 $defaults{$item} = $domdefaults{$item};                  $defaults{$item} = $domdefaults{$item};
             }              }
         }          }
           my $titles = &defaults_titles($dom);
         foreach my $item (@items) {          foreach my $item (@items) {
             if ($rownum%2) {              if ($rownum%2) {
                 $css_class = '';                  $css_class = '';
Line 6102  sub print_defaults { Line 5532  sub print_defaults {
             $datatable .= '</td></tr>';              $datatable .= '</td></tr>';
             $rownum ++;              $rownum ++;
         }          }
     } elsif ($position eq 'middle') {  
         my @items = ('intauth_cost','intauth_check','intauth_switch');  
         my %defaults;  
         if (ref($settings) eq 'HASH') {  
             %defaults = %{$settings};  
             if ($defaults{'intauth_cost'} !~ /^\d+$/) {  
                 $defaults{'intauth_cost'} = 10;  
             }  
             if ($defaults{'intauth_check'} !~ /^(0|1|2)$/) {  
                 $defaults{'intauth_check'} = 0;  
             }  
             if ($defaults{'intauth_switch'} !~ /^(0|1|2)$/) {  
                 $defaults{'intauth_switch'} = 0;  
             }  
         } else {  
             %defaults = (  
                           'intauth_cost'   => 10,  
                           'intauth_check'  => 0,  
                           'intauth_switch' => 0,  
                         );  
         }  
         foreach my $item (@items) {  
             if ($rownum%2) {  
                 $css_class = '';  
             } else {  
                 $css_class = ' class="LC_odd_row" ';  
             }  
             $datatable .= '<tr'.$css_class.'>'.  
                           '<td><span class="LC_nobreak">'.$titles->{$item}.  
                           '</span></td><td class="LC_left_item" colspan="3">';  
             if ($item eq 'intauth_switch') {  
                 my @options = (0,1,2);  
                 my %optiondesc = &Apache::lonlocal::texthash (  
                                    0 => 'No',  
                                    1 => 'Yes',  
                                    2 => 'Yes, and copy existing passwd file to passwd.bak file',  
                                  );  
                 $datatable .= '<table width="100%">';  
                 foreach my $option (@options) {  
                     my $checked = ' ';  
                     if ($defaults{$item} eq $option) {  
                         $checked = ' checked="checked"';  
                     }  
                     $datatable .= '<tr><td class="LC_left_item"><span class="LC_nobreak">'.  
                                   '<label><input type="radio" name="'.$item.  
                                   '" value="'.$option.'"'.$checked.' />'.  
                                   $optiondesc{$option}.'</label></span></td></tr>';  
                 }  
                 $datatable .= '</table>';  
             } elsif ($item eq 'intauth_check') {  
                 my @options = (0,1,2);  
                 my %optiondesc = &Apache::lonlocal::texthash (  
                                    0 => 'No',  
                                    1 => 'Yes, allow login then update passwd file using default cost (if higher)',  
                                    2 => 'Yes, disallow login if stored cost is less than domain default',  
                                  );  
                 $datatable .= '<table wisth="100%">';  
                 foreach my $option (@options) {  
                     my $checked = ' ';  
                     my $onclick;  
                     if ($defaults{$item} eq $option) {  
                         $checked = ' checked="checked"';  
                     }  
                     if ($option == 2) {  
                         $onclick = ' onclick="javascript:warnIntAuth(this);"';  
                     }  
                     $datatable .= '<tr><td class="LC_left_item"><span class="LC_nobreak">'.  
                                   '<label><input type="radio" name="'.$item.  
                                   '" value="'.$option.'"'.$checked.$onclick.' />'.  
                                   $optiondesc{$option}.'</label></span></td></tr>';  
                 }  
                 $datatable .= '</table>';  
             } else {  
                 $datatable .= '<input type="text" name="'.$item.'" value="'.  
                               $defaults{$item}.'" size="3" onblur="javascript:warnIntAuth(this);" />';  
             }  
             $datatable .= '</td></tr>';  
             $rownum ++;  
         }  
     } else {      } else {
         my %defaults;          my (%defaults);
         if (ref($settings) eq 'HASH') {          if (ref($settings) eq 'HASH') {
             if ((ref($settings->{'inststatusorder'}) eq 'ARRAY') && (ref($settings->{'inststatustypes'}) eq 'HASH') &&              if ((ref($settings->{'inststatusorder'}) eq 'ARRAY') && (ref($settings->{'inststatustypes'}) eq 'HASH') &&
                 (ref($settings->{'inststatusguest'}) eq 'ARRAY')) {                  (ref($settings->{'inststatusguest'}) eq 'ARRAY')) {
Line 6277  sub defaults_titles { Line 5628  sub defaults_titles {
                    'timezone_def'  => 'Default timezone',                     'timezone_def'  => 'Default timezone',
                    'datelocale_def' => 'Default locale for dates',                     'datelocale_def' => 'Default locale for dates',
                    'portal_def'     => 'Portal/Default URL',                     'portal_def'     => 'Portal/Default URL',
                    'intauth_cost'   => 'Encryption cost for bcrypt (positive integer)',  
                    'intauth_check'  => 'Check bcrypt cost if authenticated',  
                    'intauth_switch' => 'Existing crypt-based switched to bcrypt on authentication',  
                  );                   );
     if ($dom) {      if ($dom) {
         my $uprimary_id = &Apache::lonnet::domain($dom,'primary');          my $uprimary_id = &Apache::lonnet::domain($dom,'primary');
Line 6522  sub print_coursecategories { Line 5870  sub print_coursecategories {
         my $toggle_catscomm_dom = ' checked="checked" ';          my $toggle_catscomm_dom = ' checked="checked" ';
         my $can_catcomm_comm = ' ';          my $can_catcomm_comm = ' ';
         my $can_catcomm_dom = ' checked="checked" ';          my $can_catcomm_dom = ' checked="checked" ';
           my $toggle_catsplace_place = ' ';
           my $toggle_catsplace_dom = ' checked="checked" ';
           my $can_catplace_place = ' ';
           my $can_catplace_dom = ' checked="checked" ';
   
         if (ref($settings) eq 'HASH') {          if (ref($settings) eq 'HASH') {
             if ($settings->{'togglecats'} eq 'crs') {              if ($settings->{'togglecats'} eq 'crs') {
Line 6540  sub print_coursecategories { Line 5892  sub print_coursecategories {
                 $can_catcomm_comm = $can_catcomm_dom;                  $can_catcomm_comm = $can_catcomm_dom;
                 $can_catcomm_dom = ' ';                  $can_catcomm_dom = ' ';
             }              }
               if ($settings->{'togglecatsplace'} eq 'place') {
                   $toggle_catsplace_place = $toggle_catsplace_dom;
                   $toggle_catsplace_dom = ' ';
               }
               if ($settings->{'categorizeplace'} eq 'place') {
                   $can_catplace_place = $can_catplace_dom;
                   $can_catplace_dom = ' ';
               }
         }          }
         my %title = &Apache::lonlocal::texthash (          my %title = &Apache::lonlocal::texthash (
                      togglecats     => 'Show/Hide a course in catalog',                       togglecats      => 'Show/Hide a course in catalog',
                      togglecatscomm => 'Show/Hide a community in catalog',                       togglecatscomm  => 'Show/Hide a community in catalog',
                      categorize     => 'Assign a category to a course',                       togglecatsplace => 'Show/Hide a placement test in catalog',
                      categorizecomm => 'Assign a category to a community',                       categorize      => 'Assign a category to a course',
                        categorizecomm  => 'Assign a category to a community',
                        categorizeplace => 'Assign a category to a placement test',
                     );                      );
         my %level = &Apache::lonlocal::texthash (          my %level = &Apache::lonlocal::texthash (
                      dom  => 'Set in Domain',                       dom   => 'Set in Domain',
                      crs  => 'Set in Course',                       crs   => 'Set in Course',
                      comm => 'Set in Community',                       comm  => 'Set in Community',
                        place => 'Set in Placement Test',
                     );                      );
         $datatable = '<tr class="LC_odd_row">'.          $datatable = '<tr class="LC_odd_row">'.
                   '<td>'.$title{'togglecats'}.'</td>'.                    '<td>'.$title{'togglecats'}.'</td>'.
Line 6580  sub print_coursecategories { Line 5943  sub print_coursecategories {
                   $can_catcomm_dom.' value="dom" />'.$level{'dom'}.'</label>&nbsp;'.                    $can_catcomm_dom.' value="dom" />'.$level{'dom'}.'</label>&nbsp;'.
                   '<label><input type="radio" name="categorizecomm"'.                    '<label><input type="radio" name="categorizecomm"'.
                   $can_catcomm_comm.'value="comm" />'.$level{'comm'}.'</label></span></td>'.                    $can_catcomm_comm.'value="comm" />'.$level{'comm'}.'</label></span></td>'.
                     '</tr><tr>'.
                     '<td>'.$title{'togglecatsplace'}.'</td>'.
                     '<td class="LC_right_item"><span class="LC_nobreak"><label>'.
                     '<input type="radio" name="togglecatsplace"'.
                     $toggle_catsplace_dom.' value="dom" />'.$level{'dom'}.'</label>&nbsp;'.
                     '<label><input type="radio" name="togglecatscomm"'.
                     $toggle_catsplace_place.' value="comm" />'.$level{'place'}.'</label></span></td>'.
                     '</tr><tr>'.
                     '<td>'.$title{'categorizeplace'}.'</td>'.
                     '<td class="LC_right_item"><span class="LC_nobreak">'.
                     '<label><input type="radio" name="categorizeplace"'.
                     $can_catplace_dom.' value="dom" />'.$level{'dom'}.'</label>&nbsp;'.
                     '<label><input type="radio" name="categorizeplace"'.
                     $can_catplace_place.'value="place" />'.$level{'place'}.'</label></span></td>'.
                   '</tr>';                    '</tr>';
         $$rowtotal += 4;          $$rowtotal += 6;
     } else {      } else {
         my $css_class;          my $css_class;
         my $itemcount = 1;          my $itemcount = 1;
Line 6606  sub print_coursecategories { Line 5983  sub print_coursecategories {
                     my %default_names = (                      my %default_names = (
                           instcode    => &mt('Official courses'),                            instcode    => &mt('Official courses'),
                           communities => &mt('Communities'),                            communities => &mt('Communities'),
                             placement   => &mt('Placement Tests'),
                     );                      );
   
                     if ((!grep(/^instcode$/,@{$cats[0]})) ||                       if ((!grep(/^instcode$/,@{$cats[0]})) || 
                         ($cathash->{'instcode::0'} eq '') ||                          ($cathash->{'instcode::0'} eq '') ||
                         (!grep(/^communities$/,@{$cats[0]})) ||                           (!grep(/^communities$/,@{$cats[0]})) || 
                         ($cathash->{'communities::0'} eq '')) {                          ($cathash->{'communities::0'} eq '') ||
                           (!grep(/^placement$/,@{$cats[0]})) ||
                           ($cathash->{'placement::0'} eq '')) {
                         $maxnum ++;                          $maxnum ++;
                     }                      }
                     my $lastidx;                      my $lastidx;
Line 6632  sub print_coursecategories { Line 6012  sub print_coursecategories {
                             $datatable .= '<option value="'.$k.'"'.$selstr.'>'.$vpos.'</option>';                              $datatable .= '<option value="'.$k.'"'.$selstr.'>'.$vpos.'</option>';
                         }                          }
                         $datatable .= '</select></span></td><td>';                          $datatable .= '</select></span></td><td>';
                         if ($parent eq 'instcode' || $parent eq 'communities') {                          if ($parent eq 'instcode' || $parent eq 'communities' || $parent eq 'placement') {
                             $datatable .=  '<span class="LC_nobreak">'                              $datatable .=  '<span class="LC_nobreak">'
                                            .$default_names{$parent}.'</span>';                                             .$default_names{$parent}.'</span>';
                             if ($parent eq 'instcode') {                              if ($parent eq 'instcode') {
Line 6655  sub print_coursecategories { Line 6035  sub print_coursecategories {
                             $datatable .= '<label><input type="radio" name="'                              $datatable .= '<label><input type="radio" name="'
                                           .$parent.'" value="0" />'                                            .$parent.'" value="0" />'
                                           .&mt('Do not display').'</label></span>';                                            .&mt('Do not display').'</label></span>';
                             if ($parent eq 'communities') {                              if (($parent eq 'communities') || ($parent eq 'placement')) {
                                 $datatable .= '</td></tr></table>';                                  $datatable .= '</td></tr></table>';
                             }                              }
                             $datatable .= '</td>';                              $datatable .= '</td>';
Line 6687  sub print_coursecategories { Line 6067  sub print_coursecategories {
                                   .'<input type="text" size="20" name="addcategory_name" value="" /></td>'                                    .'<input type="text" size="20" name="addcategory_name" value="" /></td>'
                                   .'</tr>'."\n";                                    .'</tr>'."\n";
                     $itemcount ++;                      $itemcount ++;
                     foreach my $default ('instcode','communities') {                      foreach my $default ('instcode','communities','placement') {
                         if ((!grep(/^\Q$default\E$/,@{$cats[0]})) || ($cathash->{$default.'::0'} eq '')) {                          if ((!grep(/^\Q$default\E$/,@{$cats[0]})) || ($cathash->{$default.'::0'} eq '')) {
                             $css_class = $itemcount%2?' class="LC_odd_row"':'';                              $css_class = $itemcount%2?' class="LC_odd_row"':'';
                             my $chgstr = ' onchange="javascript:reorderCats(this.form,'."'','$default"."_pos','$lastidx'".');"';                              my $chgstr = ' onchange="javascript:reorderCats(this.form,'."'','$default"."_pos','$lastidx'".');"';
Line 6776  sub print_serverstatuses { Line 6156  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','certstatus','metadata_keywords',
             'takeoffline','takeonline','showenv','toggledebug','ping','domconf',              'metadata_harvest','takeoffline','takeonline','showenv','toggledebug',
             'uniquecodes','diskusage','coursecatalog');              'ping','domconf','uniquecodes','diskusage','coursecatalog');
 }  }
   
 sub defaults_javascript {  sub defaults_javascript {
     my ($settings) = @_;      my ($settings) = @_;
     my $intauthcheck = &mt('Warning: disallowing login for an authenticated user if the stored cost is less than the default will require a password reset by/for the user.');      return unless (ref($settings) eq 'HASH'); 
     my $intauthcost = &mt('Warning: bcrypt encryption cost for internal authentication must be an integer.');  
     &js_escape(\$intauthcheck);  
     &js_escape(\$intauthcost);  
     my $intauthjs = <<"ENDSCRIPT";  
   
 function warnIntAuth(field) {  
     if (field.name == 'intauth_check') {  
         if (field.value == '2') {  
             alert('$intauthcheck');  
         }  
     }  
     if (field.name == 'intauth_cost') {  
         field.value.replace(/\s/g,'');  
         if (field.value != '') {  
             var regexdigit=/^\\d+\$/;  
             if (!regexdigit.test(field.value)) {  
                 alert('$intauthcost');  
             }  
         }  
     }  
     return;  
 }  
   
 ENDSCRIPT  
   
     if (ref($settings) ne 'HASH') {  
         return &Apache::lonhtmlcommon::scripttag($intauthjs);  
     }  
     if ((ref($settings->{'inststatusorder'}) eq 'ARRAY') && (ref($settings->{'inststatustypes'}) eq 'HASH')) {      if ((ref($settings->{'inststatusorder'}) eq 'ARRAY') && (ref($settings->{'inststatustypes'}) eq 'HASH')) {
         my $maxnum = scalar(@{$settings->{'inststatusorder'}});          my $maxnum = scalar(@{$settings->{'inststatusorder'}});
         if ($maxnum eq '') {          if ($maxnum eq '') {
Line 6865  $jstext Line 6217  $jstext
     return;      return;
 }  }
   
 $intauthjs  
   
 // ]]>  // ]]>
 </script>  </script>
   
 ENDSCRIPT  ENDSCRIPT
     } else {  
         return &Apache::lonhtmlcommon::scripttag($intauthjs);  
     }      }
 }  }
   
Line 6900  sub coursecategories_javascript { Line 6248  sub coursecategories_javascript {
     }      }
     my $instcode_reserved = &mt('The name: [_1] is a reserved category.','"instcode"');      my $instcode_reserved = &mt('The name: [_1] is a reserved category.','"instcode"');
     my $communities_reserved = &mt('The name: [_1] is a reserved category.','"communities"');      my $communities_reserved = &mt('The name: [_1] is a reserved category.','"communities"');
       my $placement_reserved = &mt('The name: [_1] is a reserved category.','"placement"');
     my $choose_again = "\n".&mt('Please use a different name for the new top level category.');       my $choose_again = "\n".&mt('Please use a different name for the new top level category.'); 
     &js_escape(\$instcode_reserved);      &js_escape(\$instcode_reserved);
     &js_escape(\$communities_reserved);      &js_escape(\$communities_reserved);
       &js_escape(\$placement_reserved);
     &js_escape(\$choose_again);      &js_escape(\$choose_again);
     $output = <<"ENDSCRIPT";      $output = <<"ENDSCRIPT";
 <script type="text/javascript">  <script type="text/javascript">
Line 6972  function categoryCheck(form) { Line 6322  function categoryCheck(form) {
         alert('$communities_reserved\\n$choose_again');          alert('$communities_reserved\\n$choose_again');
         return false;          return false;
     }      }
       if (form.elements['addcategory_name'].value == 'placement') {
           alert('$placement_reserved\\n$choose_again');
           return false;
       }
     return true;      return true;
 }  }
   
Line 6988  sub initialize_categories { Line 6342  sub initialize_categories {
     my %default_names = (      my %default_names = (
                       instcode    => 'Official courses (with institutional codes)',                        instcode    => 'Official courses (with institutional codes)',
                       communities => 'Communities',                        communities => 'Communities',
                         placement   => 'Placement Tests',
                         );                          );
     my $select0 = ' selected="selected"';      my $select0 = ' selected="selected"';
     my $select1 = '';      my $select1 = '';
     foreach my $default ('instcode','communities') {      foreach my $default ('instcode','communities','placement') {
         $css_class = $itemcount%2?' class="LC_odd_row"':'';          $css_class = $itemcount%2?' class="LC_odd_row"':'';
         $chgstr = ' onchange="javascript:reorderCats(this.form,'."'',$default"."_pos','0'".');"';          $chgstr = ' onchange="javascript:reorderCats(this.form,'."'',$default"."_pos','0'".');"';
         if ($default eq 'communities') {          if (($default eq 'communities') || ($default eq 'placement')) {
             $select1 = $select0;              $select1 = $select0;
             $select0 = '';              $select0 = '';
         }          }
Line 7240  sub modifiable_userdata_row { Line 6595  sub modifiable_userdata_row {
 }  }
   
 sub insttypes_row {  sub insttypes_row {
     my ($settings,$types,$usertypes,$dom,$numinrow,$othertitle,$context,$rowtotal,$onclick,      my ($settings,$types,$usertypes,$dom,$numinrow,$othertitle,$context,$rownum) = @_;
         $customcss,$rowstyle) = @_;  
     my %lt = &Apache::lonlocal::texthash (      my %lt = &Apache::lonlocal::texthash (
                       cansearch => 'Users allowed to search',                        cansearch => 'Users allowed to search',
                       statustocreate => 'Institutional affiliation(s) able to create own account (login/SSO)',                        statustocreate => 'Institutional affiliation(s) able to create own account (login/SSO)',
                       lockablenames => 'User preference to lock name',                        lockablenames => 'User preference to lock name',
                       overrides     => "Override domain's helpdesk settings based on requester's affiliation",  
              );               );
     my $showdom;      my $showdom;
     if ($context eq 'cansearch') {      if ($context eq 'cansearch') {
Line 7256  sub insttypes_row { Line 6609  sub insttypes_row {
     if ($context eq 'statustocreate') {      if ($context eq 'statustocreate') {
         $class = 'LC_right_item';          $class = 'LC_right_item';
     }      }
     my $css_class;      my $css_class = ' class="LC_odd_row"';
     if ($$rowtotal%2) {      if ($rownum ne '') { 
         $css_class = 'LC_odd_row';          $css_class = ($rownum%2? ' class="LC_odd_row"':'');
     }  
     if ($customcss) {  
         $css_class .= ' '.$customcss;  
     }  
     $css_class =~ s/^\s+//;  
     if ($css_class) {  
         $css_class = ' class="'.$css_class.'"';  
     }  
     if ($rowstyle) {  
         $css_class .= ' style="'.$rowstyle.'"';  
     }  
     if ($onclick) {  
         $onclick = 'onclick="'.$onclick.'" ';  
     }      }
     my $output = '<tr'.$css_class.'>'.      my $output = '<tr'.$css_class.'>'.
                  '<td>'.$lt{$context}.$showdom.                   '<td>'.$lt{$context}.$showdom.
Line 7293  sub insttypes_row { Line 6633  sub insttypes_row {
                         if (grep(/^\Q$types->[$i]\E$/,@{$settings->{$context}})) {                          if (grep(/^\Q$types->[$i]\E$/,@{$settings->{$context}})) {
                             $check = ' checked="checked" ';                              $check = ' checked="checked" ';
                         }                          }
                     } elsif (ref($settings->{$context}) eq 'HASH') {  
                         if (ref($settings->{$context}->{$types->[$i]}) eq 'HASH') {  
                             $check = ' checked="checked" ';  
                         }  
                     } elsif ($context eq 'statustocreate') {                      } elsif ($context eq 'statustocreate') {
                         $check = ' checked="checked" ';                          $check = ' checked="checked" ';
                     }                      }
Line 7311  sub insttypes_row { Line 6647  sub insttypes_row {
         $rem = @{$types}%($numinrow);          $rem = @{$types}%($numinrow);
     }      }
     my $colsleft = $numinrow - $rem;      my $colsleft = $numinrow - $rem;
     if ($context eq 'overrides') {      if (($rem == 0) && (@{$types} > 0)) {
         if ($colsleft > 1) {          $output .= '<tr>';
             $output .= '<td colspan="'.$colsleft.'" class="LC_left_item">';      }
         } else {      if ($colsleft > 1) {
             $output .= '<td class="LC_left_item">';          $output .= '<td colspan="'.$colsleft.'" class="LC_left_item">';
         }  
         $output .= '&nbsp;';  
     } else {      } else {
         if (($rem == 0) && (@{$types} > 0)) {          $output .= '<td class="LC_left_item">';
             $output .= '<tr>';      }
         }      my $defcheck = ' ';
         if ($colsleft > 1) {      if (ref($settings) eq 'HASH') {  
             $output .= '<td colspan="'.$colsleft.'" class="LC_left_item">';          if (ref($settings->{$context}) eq 'ARRAY') {
         } else {              if (grep(/^default$/,@{$settings->{$context}})) {
             $output .= '<td class="LC_left_item">';  
         }  
         my $defcheck = ' ';  
         if (ref($settings) eq 'HASH') {    
             if (ref($settings->{$context}) eq 'ARRAY') {  
                 if (grep(/^default$/,@{$settings->{$context}})) {  
                     $defcheck = ' checked="checked" ';  
                 }  
             } elsif ($context eq 'statustocreate') {  
                 $defcheck = ' checked="checked" ';                  $defcheck = ' checked="checked" ';
             }              }
           } elsif ($context eq 'statustocreate') {
               $defcheck = ' checked="checked" ';
         }          }
         $output .= '<span class="LC_nobreak"><label>'.  
                    '<input type="checkbox" name="'.$context.'" '.  
                    'value="default"'.$defcheck.'/>'.  
                    $othertitle.'</label></span>';  
     }      }
     $output .= '</td></tr></table></td></tr>';      $output .= '<span class="LC_nobreak"><label>'.
                  '<input type="checkbox" name="'.$context.'" '.
                  'value="default"'.$defcheck.'/>'.
                  $othertitle.'</label></span></td>'.
                  '</tr></table></td></tr>';
     return $output;      return $output;
 }  }
   
Line 7627  sub modify_login { Line 6954  sub modify_login {
             } elsif ($currheadtagurls{$lonhost}) {              } elsif ($currheadtagurls{$lonhost}) {
                 $loginhash{'login'}{'headtag'}{$lonhost}{'url'} = $currheadtagurls{$lonhost};                  $loginhash{'login'}{'headtag'}{$lonhost}{'url'} = $currheadtagurls{$lonhost};
                 if ($currexempt{$lonhost}) {                  if ($currexempt{$lonhost}) {
                     if ((!exists($possexempt{$lonhost})) || ($possexempt{$lonhost} ne $currexempt{$lonhost})) {                      if ((!exists($possexempt{$lonhost})) || ($possexempt{$lonhost} ne $currexempt{$lonhost})) { 
                         $changes{'headtag'}{$lonhost} = 1;                          $changes{'headtag'}{$lonhost} = 1;
                     }                      }
                 } elsif ($possexempt{$lonhost}) {                  } elsif ($possexempt{$lonhost}) {
Line 7859  sub modify_login { Line 7186  sub modify_login {
     return $resulttext;      return $resulttext;
 }  }
   
   
 sub check_exempt_addresses {  sub check_exempt_addresses {
     my ($iplist) = @_;      my ($iplist) = @_;
     $iplist =~ s/^\s+//;      $iplist =~ s/^\s+//;
Line 8331  sub check_authorstatus { Line 7659  sub check_authorstatus {
   
 sub publishlogo {  sub publishlogo {
     my ($r,$action,$formname,$dom,$confname,$subdir,$thumbwidth,$thumbheight,$savefileas) = @_;      my ($r,$action,$formname,$dom,$confname,$subdir,$thumbwidth,$thumbheight,$savefileas) = @_;
     my ($output,$fname,$logourl);      my ($output,$fname,$logourl,$madethumb);
     if ($action eq 'upload') {      if ($action eq 'upload') {
         $fname=$env{'form.'.$formname.'.filename'};          $fname=$env{'form.'.$formname.'.filename'};
         chop($env{'form.'.$formname});          chop($env{'form.'.$formname});
Line 8459  $env{'user.name'}.':'.$env{'user.domain' Line 7787  $env{'user.name'}.':'.$env{'user.domain'
                                     $r->set_handlers('PerlCleanupHandler' => [\&notifysubscribed,@{$handlers}]);                                      $r->set_handlers('PerlCleanupHandler' => [\&notifysubscribed,@{$handlers}]);
                                     $registered_cleanup=1;                                      $registered_cleanup=1;
                                 }                                  }
                                   $madethumb = 1;
                             } else {                              } else {
                                 print $logfile "\nUnable to write ".$copyfile.                                  print $logfile "\nUnable to write ".$copyfile.
                                                ':'.$!."\n";                                                 ':'.$!."\n";
Line 8471  $env{'user.name'}.':'.$env{'user.domain' Line 7800  $env{'user.name'}.':'.$env{'user.domain'
             $output = $versionresult;              $output = $versionresult;
         }          }
     }      }
     return ($output,$logourl);      return ($output,$logourl,$madethumb);
 }  }
   
 sub logo_versioning {  sub logo_versioning {
Line 8625  sub modify_quotas { Line 7954  sub modify_quotas {
         $context = $action;          $context = $action;
     }      }
     if ($context eq 'requestcourses') {      if ($context eq 'requestcourses') {
         @usertools = ('official','unofficial','community','textbook');          @usertools = ('official','unofficial','community','textbook','placement');
         @options =('norequest','approval','validate','autolimit');          @options =('norequest','approval','validate','autolimit');
         %validations = &Apache::lonnet::auto_courserequest_checks($dom);          %validations = &Apache::lonnet::auto_courserequest_checks($dom);
         %titles = &courserequest_titles();          %titles = &courserequest_titles();
Line 8674  sub modify_quotas { Line 8003  sub modify_quotas {
         my @approvalnotify = &Apache::loncommon::get_env_multiple('form.'.$context.'notifyapproval');          my @approvalnotify = &Apache::loncommon::get_env_multiple('form.'.$context.'notifyapproval');
         @approvalnotify = sort(@approvalnotify);          @approvalnotify = sort(@approvalnotify);
         $confhash{'notify'}{'approval'} = join(',',@approvalnotify);          $confhash{'notify'}{'approval'} = join(',',@approvalnotify);
         my @crstypes = ('official','unofficial','community','textbook');          my @crstypes = ('official','unofficial','community','textbook','placement');
         my @hasuniquecode = &Apache::loncommon::get_env_multiple('form.uniquecode');          my @hasuniquecode = &Apache::loncommon::get_env_multiple('form.uniquecode');
         foreach my $type (@hasuniquecode) {          foreach my $type (@hasuniquecode) {
             if (grep(/^\Q$type\E$/,@crstypes)) {              if (grep(/^\Q$type\E$/,@crstypes)) {
Line 8768  sub modify_quotas { Line 8097  sub modify_quotas {
                                     my $newpos = $env{'form.'.$itemid};                                      my $newpos = $env{'form.'.$itemid};
                                     $newpos =~ s/\D+//g;                                      $newpos =~ s/\D+//g;
                                     foreach my $item ('subject','title','publisher','author') {                                      foreach my $item ('subject','title','publisher','author') {
                                         next if ((($item eq 'author') || ($item eq 'publisher')) &&                                          next if ((($item eq 'author') || ($item eq 'publisher')) && 
                                                  ($type eq 'templates'));                                                   ($type eq 'templates'));
                                         $confhash{$type}{$key}{$item} = $env{'form.'.$type.'_'.$item.'_'.$i};                                          $confhash{$type}{$key}{$item} = $env{'form.'.$type.'_'.$item.'_'.$i};
                                         if ($domconfig{$action}{$type}{$key}{$item} ne $confhash{$type}{$key}{$item}) {                                          if ($domconfig{$action}{$type}{$key}{$item} ne $confhash{$type}{$key}{$item}) {
Line 8913  sub modify_quotas { Line 8242  sub modify_quotas {
             }              }
             if ($env{'form.validationdc'}) {              if ($env{'form.validationdc'}) {
                 my $newval = $env{'form.validationdc'};                  my $newval = $env{'form.validationdc'};
                 my %domcoords = &Apache::lonnet::get_active_domroles($dom,['dc']);                  my %domcoords = &get_active_dcs($dom);
                 if (exists($domcoords{$newval})) {                  if (exists($domcoords{$newval})) {
                     $confhash{'validation'}{'dc'} = $newval;                      $confhash{'validation'}{'dc'} = $newval;
                 }                  }
Line 8937  sub modify_quotas { Line 8266  sub modify_quotas {
                     }                      }
                 } elsif ($confhash{'validation'}{'dc'} ne '') {                  } elsif ($confhash{'validation'}{'dc'} ne '') {
                     $changes{'validation'}{'dc'} = $confhash{'validation'}{'dc'};                      $changes{'validation'}{'dc'} = $confhash{'validation'}{'dc'};
                 }                  }  
             } else {              } else {
                 if (ref($domconfig{'requestcourses'}) eq 'HASH') {                  if (ref($domconfig{'requestcourses'}) eq 'HASH') {
                     if (ref($domconfig{'requestcourses'}{'validation'}) eq 'HASH') {                      if (ref($domconfig{'requestcourses'}{'validation'}) eq 'HASH') {
Line 9343  sub process_textbook_image { Line 8672  sub process_textbook_image {
 sub modify_ltitools {  sub modify_ltitools {
     my ($r,$dom,$action,$lastactref,%domconfig) = @_;      my ($r,$dom,$action,$lastactref,%domconfig) = @_;
     my %domdefaults = &Apache::lonnet::get_domain_defaults($dom,1);      my %domdefaults = &Apache::lonnet::get_domain_defaults($dom,1);
     my ($newid,@allpos,%changes,%confhash,%encconfig,$errors,$resulttext);      my ($newid,@allpos,%changes,%confhash,$errors,$resulttext);
     my $confname = $dom.'-domainconfig';      my $confname = $dom.'-domainconfig';
     my $servadm = $r->dir_config('lonAdmEMail');      my $servadm = $r->dir_config('lonAdmEMail');
     my ($configuserok,$author_ok,$switchserver) = &config_check($dom,$confname,$servadm);      my ($configuserok,$author_ok,$switchserver) = &config_check($dom,$confname,$servadm);
Line 9353  sub modify_ltitools { Line 8682  sub modify_ltitools {
     map { $posslti{$_} = 1; } @ltiroles;      map { $posslti{$_} = 1; } @ltiroles;
     my @allfields = ('fullname','firstname','lastname','email','user','roles');      my @allfields = ('fullname','firstname','lastname','email','user','roles');
     map { $possfield{$_} = 1; } @allfields;      map { $possfield{$_} = 1; } @allfields;
     my %lt = &ltitools_names();      my %lt = &ltitools_names(); 
     if ($env{'form.ltitools_add'}) {      if ($env{'form.ltitools_add'}) {
         my $title = $env{'form.ltitools_add_title'};          my $title = $env{'form.ltitools_add_title'};
         $title =~ s/(`)/'/g;          $title =~ s/(`)/'/g;
Line 9368  sub modify_ltitools { Line 8697  sub modify_ltitools {
             foreach my $item ('title','url','key','secret') {              foreach my $item ('title','url','key','secret') {
                 $env{'form.ltitools_add_'.$item} =~ s/(`)/'/g;                  $env{'form.ltitools_add_'.$item} =~ s/(`)/'/g;
                 if ($env{'form.ltitools_add_'.$item}) {                  if ($env{'form.ltitools_add_'.$item}) {
                     if (($item eq 'key') || ($item eq 'secret')) {                      $confhash{$newid}{$item} = $env{'form.ltitools_add_'.$item};
                         $encconfig{$newid}{$item} = $env{'form.ltitools_add_'.$item};  
                     } else {  
                         $confhash{$newid}{$item} = $env{'form.ltitools_add_'.$item};  
                     }  
                 }                  }
             }              }
             if ($env{'form.ltitools_add_version'} eq 'LTI-1p0') {              if ($env{'form.ltitools_add_version'} eq 'LTI-1p0') {
Line 9381  sub modify_ltitools { Line 8706  sub modify_ltitools {
             if ($env{'form.ltitools_add_msgtype'} eq 'basic-lti-launch-request') {              if ($env{'form.ltitools_add_msgtype'} eq 'basic-lti-launch-request') {
                 $confhash{$newid}{'msgtype'} = $env{'form.ltitools_add_msgtype'};                  $confhash{$newid}{'msgtype'} = $env{'form.ltitools_add_msgtype'};
             }              }
             foreach my $item ('width','height','linktext','explanation') {              foreach my $item ('width','height') {
                 $env{'form.ltitools_add_'.$item} =~ s/^\s+//;                  $env{'form.ltitools_add_'.$item} =~ s/^\s+//;
                 $env{'form.ltitools_add_'.$item} =~ s/\s+$//;                  $env{'form.ltitools_add_'.$item} =~ s/\s+$//;
                 if (($item eq 'width') || ($item eq 'height')) {                  if ($env{'form.ltitools_add_'.$item} =~ /^\d+$/) {
                     if ($env{'form.ltitools_add_'.$item} =~ /^\d+$/) {                      $confhash{$newid}{'display'}{$item} = $env{'form.ltitools_add_'.$item};
                         $confhash{$newid}{'display'}{$item} = $env{'form.ltitools_add_'.$item};  
                     }  
                 } else {  
                     if ($env{'form.ltitools_add_'.$item} ne '') {  
                         $confhash{$newid}{'display'}{$item} = $env{'form.ltitools_add_'.$item};  
                     }  
                 }                  }
             }              }
             if ($env{'form.ltitools_add_target'} eq 'window') {              if ($env{'form.ltitools_add_target'} eq 'window') {
                 $confhash{$newid}{'display'}{'target'} = $env{'form.ltitools_add_target'};                  $confhash{$newid}{'display'}{'target'} = $env{'form.ltitools_add_target'};
             } elsif ($env{'form.ltitools_add_target'} eq 'tab') {  
                 $confhash{$newid}{'display'}{'target'} = $env{'form.ltitools_add_target'};  
             } else {              } else {
                 $confhash{$newid}{'display'}{'target'} = 'iframe';                  $confhash{$newid}{'display'}{'target'} = 'iframe';
             }              }
Line 9408  sub modify_ltitools { Line 8725  sub modify_ltitools {
             }              }
             if ($env{'form.ltitools_add_image.filename'} ne '') {              if ($env{'form.ltitools_add_image.filename'} ne '') {
                 my ($imageurl,$error) =                  my ($imageurl,$error) =
                     &process_ltitools_image($r,$dom,$confname,'ltitools_add_image',$newid,                      &process_ltitools_image($r,$dom,$confname,'ltitools_add_image',$dom,
                                             $configuserok,$switchserver,$author_ok);                                              $configuserok,$switchserver,$author_ok);
                 if ($imageurl) {                  if ($imageurl) {
                     $confhash{$newid}{'image'} = $imageurl;                      $confhash{$newid}{'image'} = $imageurl;
Line 9427  sub modify_ltitools { Line 8744  sub modify_ltitools {
                             if (($choice ne '') && ($posslti{$choice})) {                              if (($choice ne '') && ($posslti{$choice})) {
                                 $confhash{$newid}{'roles'}{$role} = $choice;                                  $confhash{$newid}{'roles'}{$role} = $choice;
                                 if ($role eq 'cc') {                                  if ($role eq 'cc') {
                                     $confhash{$newid}{'roles'}{'co'} = $choice;                                      $confhash{$newid}{'roles'}{'co'} = $choice; 
                                 }                                  }
                             }                              }
                         }                          }
Line 9448  sub modify_ltitools { Line 8765  sub modify_ltitools {
                 $confhash{$newid}{'custom'}{$name} = $value;                  $confhash{$newid}{'custom'}{$name} = $value;
             }              }
         } else {          } else {
             my $error = &mt('Failed to acquire unique ID for new external tool');              my $error = &mt('Failed to acquire unique ID for new external tool');   
             $errors .= '<li><span class="LC_error">'.$error.'</span></li>';              $errors .= '<li><span class="LC_error">'.$error.'</span></li>';
         }          }
     }      }
Line 9462  sub modify_ltitools { Line 8779  sub modify_ltitools {
         my @newcustom = &Apache::loncommon::get_env_multiple('form.ltitools_customadd');          my @newcustom = &Apache::loncommon::get_env_multiple('form.ltitools_customadd');
         if (@newcustom) {          if (@newcustom) {
             map { $customadds{$_} = 1; } @newcustom;              map { $customadds{$_} = 1; } @newcustom;
         }          } 
         my %imgdeletions;          my %imgdeletions;
         my @todeleteimages = &Apache::loncommon::get_env_multiple('form.ltitools_image_del');          my @todeleteimages = &Apache::loncommon::get_env_multiple('form.ltitools_image_del');
         if (@todeleteimages) {          if (@todeleteimages) {
Line 9481  sub modify_ltitools { Line 8798  sub modify_ltitools {
                 } else {                  } else {
                     my $newpos = $env{'form.ltitools_'.$itemid};                      my $newpos = $env{'form.ltitools_'.$itemid};
                     $newpos =~ s/\D+//g;                      $newpos =~ s/\D+//g;
                     foreach my $item ('title','url') {                      foreach my $item ('title','url','key','secret') {
                         $confhash{$itemid}{$item} = $env{'form.ltitools_'.$item.'_'.$i};                          $confhash{$itemid}{$item} = $env{'form.ltitools_'.$item.'_'.$i};
                         if ($domconfig{$action}{$itemid}{$item} ne $confhash{$itemid}{$item}) {                          if ($domconfig{$action}{$itemid}{$item} ne $confhash{$itemid}{$item}) {
                             $changes{$itemid} = 1;                              $changes{$itemid} = 1;
                         }                          }
                     }                      }
                     foreach my $item ('key','secret') {  
                         $encconfig{$itemid}{$item} = $env{'form.ltitools_'.$item.'_'.$i};  
                         if ($domconfig{$action}{$itemid}{$item} ne $encconfig{$itemid}{$item}) {  
                             $changes{$itemid} = 1;  
                         }  
                     }  
                     if ($env{'form.ltitools_version_'.$i} eq 'LTI-1p0') {                      if ($env{'form.ltitools_version_'.$i} eq 'LTI-1p0') {
                         $confhash{$itemid}{'version'} = $env{'form.ltitools_version_'.$i};                          $confhash{$itemid}{'version'} = $env{'form.ltitools_version_'.$i};
                     }                      }
Line 9511  sub modify_ltitools { Line 8822  sub modify_ltitools {
                             } else {                              } else {
                                 $changes{$itemid} = 1;                                  $changes{$itemid} = 1;
                             }                              }
                         } elsif (ref($domconfig{$action}{$itemid}{'display'}) eq 'HASH') {  
                             if ($domconfig{$action}{$itemid}{'display'}{$size} ne '') {  
                                 $changes{$itemid} = 1;  
                             }  
                         }  
                     }  
                     foreach my $item ('linktext','explanation') {  
                         $env{'form.ltitools_'.$item.'_'.$i} =~ s/^\s+//;  
                         $env{'form.ltitools_'.$item.'_'.$i} =~ s/\s+$//;  
                         if ($env{'form.ltitools_'.$item.'_'.$i} ne '') {  
                             $confhash{$itemid}{'display'}{$item} = $env{'form.ltitools_'.$item.'_'.$i};  
                             if (ref($domconfig{$action}{$itemid}{'display'}) eq 'HASH') {  
                                 if ($domconfig{$action}{$itemid}{'display'}{$item} ne $confhash{$itemid}{'display'}{$item}) {  
                                     $changes{$itemid} = 1;  
                                 }  
                             } else {  
                                 $changes{$itemid} = 1;  
                             }  
                         } elsif (ref($domconfig{$action}{$itemid}{'display'}) eq 'HASH') {  
                             if ($domconfig{$action}{$itemid}{'display'}{$item} ne '') {  
                                 $changes{$itemid} = 1;  
                             }  
                         }                          }
                     }                      }
                     if ($env{'form.ltitools_target_'.$i} eq 'window') {                      if ($env{'form.ltitools_target_'.$i} eq 'window') {
                         $confhash{$itemid}{'display'}{'target'} = $env{'form.ltitools_target_'.$i};                          $confhash{$itemid}{'display'}{'target'} = $env{'form.ltitools_target_'.$i};
                     } elsif ($env{'form.ltitools_target_'.$i} eq 'tab') {  
                         $confhash{$itemid}{'display'}{'target'} = $env{'form.ltitools_target_'.$i};  
                     } else {                      } else {
                         $confhash{$itemid}{'display'}{'target'} = 'iframe';                          $confhash{$itemid}{'display'}{'target'} = 'iframe';
                     }                      }
Line 9558  sub modify_ltitools { Line 8845  sub modify_ltitools {
                         }                          }
                     }                      }
                     my @courseconfig = &Apache::loncommon::get_env_multiple('form.ltitools_courseconfig_'.$i);                      my @courseconfig = &Apache::loncommon::get_env_multiple('form.ltitools_courseconfig_'.$i);
                     foreach my $item ('label','title','target','linktext','explanation') {                      foreach my $item ('label','title','target') {
                         if (grep(/^\Q$item\E$/,@courseconfig)) {                          if (grep(/^\Q$item\E$/,@courseconfig)) {
                             $confhash{$itemid}{'crsconf'}{$item} = 1;                              $confhash{$itemid}{'crsconf'}{$item} = 1;
                             if (ref($domconfig{$action}{$itemid}{'crsconf'}) eq 'HASH') {                              if (ref($domconfig{$action}{$itemid}{'crsconf'}) eq 'HASH') {
Line 9638  sub modify_ltitools { Line 8925  sub modify_ltitools {
                     }                      }
                 }                  }
                 my %customdels;                  my %customdels;
                 my @customdeletions = &Apache::loncommon::get_env_multiple('form.ltitools_customdel_'.$i);                  my @customdeletions = &Apache::loncommon::get_env_multiple('form.ltitools_customdel_'.$i); 
                 if (@customdeletions) {                  if (@customdeletions) {
                     $changes{$itemid} = 1;                      $changes{$itemid} = 1;
                 }                  }
Line 9647  sub modify_ltitools { Line 8934  sub modify_ltitools {
                     foreach my $key (keys(%{$domconfig{$action}{$itemid}{'custom'}})) {                      foreach my $key (keys(%{$domconfig{$action}{$itemid}{'custom'}})) {
                         unless ($customdels{$key}) {                          unless ($customdels{$key}) {
                             if ($env{'form.ltitools_customval_'.$key.'_'.$i} ne '') {                              if ($env{'form.ltitools_customval_'.$key.'_'.$i} ne '') {
                                 $confhash{$itemid}{'custom'}{$key} = $env{'form.ltitools_customval_'.$key.'_'.$i};                                  $confhash{$itemid}{'custom'}{$key} = $env{'form.ltitools_customval_'.$key.'_'.$i}; 
                             }                              }
                             if ($domconfig{$action}{$itemid}{'custom'}{$key} ne $env{'form.ltitools_customval_'.$key.'_'.$i}) {                              if ($domconfig{$action}{$itemid}{'custom'}{$key} ne $env{'form.ltitools_customval_'.$key.'_'.$i}) {
                                 $changes{$itemid} = 1;                                  $changes{$itemid} = 1;
Line 9697  sub modify_ltitools { Line 8984  sub modify_ltitools {
     my $putresult = &Apache::lonnet::put_dom('configuration',\%ltitoolshash,      my $putresult = &Apache::lonnet::put_dom('configuration',\%ltitoolshash,
                                              $dom);                                               $dom);
     if ($putresult eq 'ok') {      if ($putresult eq 'ok') {
         my %ltienchash = (  
                              $action => { %encconfig }  
                          );  
         &Apache::lonnet::put_dom('encconfig',\%ltienchash,$dom);  
         if (keys(%changes) > 0) {          if (keys(%changes) > 0) {
             my $cachetime = 24*60*60;              my $cachetime = 24*60*60;
             my %ltiall = %confhash;              &Apache::lonnet::do_cache_new('ltitools',$dom,\%confhash,$cachetime);
             foreach my $id (keys(%ltiall)) {  
                 if (ref($encconfig{$id}) eq 'HASH') {  
                     foreach my $item ('key','secret') {  
                         $ltiall{$id}{$item} = $encconfig{$id}{$item};  
                     }  
                 }  
             }  
             &Apache::lonnet::do_cache_new('ltitools',$dom,\%ltiall,$cachetime);  
             if (ref($lastactref) eq 'HASH') {              if (ref($lastactref) eq 'HASH') {
                 $lastactref->{'ltitools'} = 1;                  $lastactref->{'ltitools'} = 1;
             }              }
Line 9722  sub modify_ltitools { Line 8997  sub modify_ltitools {
                 $bynum{$position} = $itemid;                  $bynum{$position} = $itemid;
             }              }
             foreach my $pos (sort { $a <=> $b } keys(%bynum)) {              foreach my $pos (sort { $a <=> $b } keys(%bynum)) {
                 my $itemid = $bynum{$pos};                  my $itemid = $bynum{$pos}; 
                 if (ref($confhash{$itemid}) ne 'HASH') {                  if (ref($confhash{$itemid}) ne 'HASH') {
                     $resulttext .= '<li>'.&mt('Deleted: [_1]',$changes{$itemid}).'</li>';                      $resulttext .= '<li>'.&mt('Deleted: [_1]',$changes{$itemid}).'</li>';
                 } else {                  } else {
Line 9735  sub modify_ltitools { Line 9010  sub modify_ltitools {
                     $resulttext .= '</li><ul>';                      $resulttext .= '</li><ul>';
                     my $position = $pos + 1;                      my $position = $pos + 1;
                     $resulttext .= '<li>'.&mt('Order: [_1]',$position).'</li>';                      $resulttext .= '<li>'.&mt('Order: [_1]',$position).'</li>';
                     foreach my $item ('version','msgtype','url') {                      foreach my $item ('version','msgtype','url','key') {
                         if ($confhash{$itemid}{$item} ne '') {                          if ($confhash{$itemid}{$item} ne '') {
                             $resulttext .= '<li>'.$lt{$item}.':&nbsp;'.$confhash{$itemid}{$item}.'</li>';                              $resulttext .= '<li>'.$lt{$item}.':&nbsp;'.$confhash{$itemid}{$item}.'</li>';
                         }                          }
                     }                      }
                     if ($encconfig{$itemid}{'key'} ne '') {                      if ($confhash{$itemid}{'secret'} ne '') {
                         $resulttext .= '<li>'.$lt{'key'}.':&nbsp;'.$encconfig{$itemid}{'key'}.'</li>';  
                     }  
                     if ($encconfig{$itemid}{'secret'} ne '') {  
                         $resulttext .= '<li>'.$lt{'secret'}.':&nbsp;';                          $resulttext .= '<li>'.$lt{'secret'}.':&nbsp;';
                         my $num = length($encconfig{$itemid}{'secret'});                          my $num = length($confhash{$itemid}{'secret'});
                         $resulttext .= ('*'x$num).'</li>';                          $resulttext .= ('*'x$num).'</li>';
                     }                      }
                     $resulttext .= '<li>'.&mt('Configurable in course:');                      $resulttext .= '<li>'.&mt('Configurable in course:');
                     my @possconfig = ('label','title','target','linktext','explanation');                      my @possconfig = ('label','title','target');
                     my $numconfig = 0;                      my $numconfig = 0; 
                     if (ref($confhash{$itemid}{'crsconf'}) eq 'HASH') {                      if (ref($confhash{$itemid}{'crsconf'}) eq 'HASH') { 
                         foreach my $item (@possconfig) {                          foreach my $item (@possconfig) {
                             if ($confhash{$itemid}{'crsconf'}{$item}) {                              if ($confhash{$itemid}{'crsconf'}{$item}) {
                                 $numconfig ++;                                  $numconfig ++;
                                 $resulttext .= ' "'.$lt{'crs'.$item}.'"';                                  $resulttext .= ' '.$lt{'crs'.$item};
                             }                              }
                         }                          }
                     }                      }
Line 9778  sub modify_ltitools { Line 9050  sub modify_ltitools {
                             $displaylist = &mt('Display target').':&nbsp;'.                              $displaylist = &mt('Display target').':&nbsp;'.
                                            $confhash{$itemid}{'display'}{'target'}.',';                                             $confhash{$itemid}{'display'}{'target'}.',';
                         }                          }
                         foreach my $size ('width','height') {                          foreach my $size ('width','height') { 
                             if ($confhash{$itemid}{'display'}{$size}) {                              if ($confhash{$itemid}{'display'}{$size}) {
                                 $displaylist .= ('&nbsp;'x2).$lt{$size}.':&nbsp;'.                                  $displaylist .= ('&nbsp;'x2).$lt{$size}.':&nbsp;'.
                                                 $confhash{$itemid}{'display'}{$size}.',';                                                  $confhash{$itemid}{'display'}{$size}.',';
Line 9788  sub modify_ltitools { Line 9060  sub modify_ltitools {
                             $displaylist =~ s/,$//;                              $displaylist =~ s/,$//;
                             $resulttext .= '<li>'.$displaylist.'</li>';                              $resulttext .= '<li>'.$displaylist.'</li>';
                         }                          }
                         foreach my $item ('linktext','explanation') {                      } 
                             if ($confhash{$itemid}{'display'}{$item}) {  
                                 $resulttext .= '<li>'.$lt{$item}.':&nbsp;'.$confhash{$itemid}{'display'}{$item}.'</li>';  
                             }  
                         }  
                     }  
                     if (ref($confhash{$itemid}{'fields'}) eq 'HASH') {                      if (ref($confhash{$itemid}{'fields'}) eq 'HASH') {
                         my $fieldlist;                          my $fieldlist;
                         foreach my $field (@allfields) {                          foreach my $field (@allfields) {
Line 9815  sub modify_ltitools { Line 9082  sub modify_ltitools {
                             }                              }
                         }                          }
                         if ($rolemaps) {                          if ($rolemaps) {
                             $rolemaps =~ s/,$//;                              $rolemaps =~ s/,$//; 
                             $resulttext .= '<li>'.&mt('Role mapping:').$rolemaps.'</li>';                              $resulttext .= '<li>'.&mt('Role mapping:').$rolemaps.'</li>';
                         }                          }
                     }                      }
Line 9824  sub modify_ltitools { Line 9091  sub modify_ltitools {
                         if (keys(%{$confhash{$itemid}{'custom'}})) {                          if (keys(%{$confhash{$itemid}{'custom'}})) {
                             foreach my $key (sort(keys(%{$confhash{$itemid}{'custom'}}))) {                              foreach my $key (sort(keys(%{$confhash{$itemid}{'custom'}}))) {
                                 $customlist .= $key.':'.$confhash{$itemid}{'custom'}{$key}.('&nbsp;'x2);                                  $customlist .= $key.':'.$confhash{$itemid}{'custom'}{$key}.('&nbsp;'x2);
                             }                              } 
                         }                          }
                         if ($customlist) {                          if ($customlist) {
                             $resulttext .= '<li>'.&mt('Custom items').':'.$customlist.'</li>';                              $resulttext .= '<li>'.&mt('Custom items').':'.$customlist.'</li>';
                         }                          }
                     }                      } 
                     $resulttext .= '</ul></li>';                      $resulttext .= '</ul></li>';
                 }                  }
             }              }
Line 9890  sub get_ltitools_id { Line 9157  sub get_ltitools_id {
     my $tries = 0;      my $tries = 0;
     my $gotlock = &Apache::lonnet::newput_dom('ltitools',$lockhash,$cdom);      my $gotlock = &Apache::lonnet::newput_dom('ltitools',$lockhash,$cdom);
     my ($id,$error);      my ($id,$error);
    
     while (($gotlock ne 'ok') && ($tries<10)) {      while (($gotlock ne 'ok') && ($tries<10)) {
         $tries ++;          $tries ++;
         sleep (0.1);          sleep (0.1);
Line 10008  sub modify_autoenroll { Line 9275  sub modify_autoenroll {
             }              }
             if ($changes{'autofailsafe'}) {              if ($changes{'autofailsafe'}) {
                 if ($failsafe ne '') {                  if ($failsafe ne '') {
                     $resulttext .= '<li>'.&mt('Failsafe for no drops if institutional data missing for a section set to: [_1]',$failsafe).'</li>';                      $resulttext .= '<li>'.&mt("$title{'failsafe'} set to [_1]",$failsafe).'</li>';
                 } else {                  } else {
                     $resulttext .= '<li>'.&mt('Failsafe for no drops if institutional data missing for a section: deleted');                      $resulttext .= '<li>'.&mt("$title{'failsafe'} deleted");
                 }                  }
                 &Apache::lonnet::get_domain_defaults($dom,1);                  &Apache::lonnet::get_domain_defaults($dom,1);
                 if (ref($lastactref) eq 'HASH') {                  if (ref($lastactref) eq 'HASH') {
Line 10232  sub modify_autocreate { Line 9499  sub modify_autocreate {
         $newvals{$item} = 0 if ($newvals{$item} eq '');          $newvals{$item} = 0 if ($newvals{$item} eq '');
     }      }
     $newvals{'xmldc'} = $env{'form.autocreate_xmldc'};      $newvals{'xmldc'} = $env{'form.autocreate_xmldc'};
     my %domcoords = &Apache::lonnet::get_active_domroles($dom,['dc']);      my %domcoords = &get_active_dcs($dom);
     unless (exists($domcoords{$newvals{'xmldc'}})) {      unless (exists($domcoords{$newvals{'xmldc'}})) {
         $newvals{'xmldc'} = '';          $newvals{'xmldc'} = '';
     }       } 
Line 10289  sub modify_autocreate { Line 9556  sub modify_autocreate {
 }  }
   
 sub modify_directorysrch {  sub modify_directorysrch {
     my ($dom,$lastactref,%domconfig) = @_;      my ($dom,%domconfig) = @_;
     my ($resulttext,%changes);      my ($resulttext,%changes);
     my %currdirsrch;      my %currdirsrch;
     if (ref($domconfig{'directorysrch'}) eq 'HASH') {      if (ref($domconfig{'directorysrch'}) eq 'HASH') {
Line 10300  sub modify_directorysrch { Line 9567  sub modify_directorysrch {
     my %title = ( available => 'Institutional directory search available',      my %title = ( available => 'Institutional directory search available',
                   localonly => 'Other domains can search institution',                    localonly => 'Other domains can search institution',
                   lcavailable => 'LON-CAPA directory search available',                    lcavailable => 'LON-CAPA directory search available',
                   lclocalonly => 'Other domains can search LON-CAPA domain',                    lclocalonly => 'Other domains can search LON-CAPA domain', 
                   searchby => 'Search types',                    searchby => 'Search types',
                   searchtypes => 'Search latitude');                    searchtypes => 'Search latitude');
     my @offon = ('off','on');      my @offon = ('off','on');
Line 10394  sub modify_directorysrch { Line 9661  sub modify_directorysrch {
             }              }
         }          }
         if (exists($currdirsrch{'lcavailable'})) {          if (exists($currdirsrch{'lcavailable'})) {
             if ($currdirsrch{'lcavailable'} ne $env{'form.dirsrch_domavailable'}) {               if ($currdirsrch{'lcavailable'} ne $env{'form.dirsrch_domavailable'}) {
                 $changes{'lcavailable'} = 1;                   $changes{'lcavailable'} = 1;
             }               }
         } else {          } else {
             if ($env{'form.dirsrch_lcavailable'} eq '1') {              if ($env{'form.dirsrch_lcavailable'} eq '1') {
                 $changes{'lcavailable'} = 1;                  $changes{'lcavailable'} = 1;
             }              }
         }          }
         if (exists($currdirsrch{'localonly'})) {          if (exists($currdirsrch{'localonly'})) {
             if ($currdirsrch{'localonly'} ne $env{'form.dirsrch_instlocalonly'}) {               if ($currdirsrch{'localonly'} ne $env{'form.dirsrch_instlocalonly'}) {
                 $changes{'localonly'} = 1;                   $changes{'localonly'} = 1;
             }               }
         } else {          } else {
             if ($env{'form.dirsrch_instlocalonly'} eq '1') {              if ($env{'form.dirsrch_instlocalonly'} eq '1') {
                 $changes{'localonly'} = 1;                  $changes{'localonly'} = 1;
             }              }
         }          }
         if (exists($currdirsrch{'lclocalonly'})) {          if (exists($currdirsrch{'lclocalonly'})) {
             if ($currdirsrch{'lclocalonly'} ne $env{'form.dirsrch_domlocalonly'}) {               if ($currdirsrch{'lclocalonly'} ne $env{'form.dirsrch_domlocalonly'}) {
                 $changes{'lclocalonly'} = 1;                   $changes{'lclocalonly'} = 1;
             }               }
         } else {          } else {
             if ($env{'form.dirsrch_domlocalonly'} eq '1') {              if ($env{'form.dirsrch_domlocalonly'} eq '1') {
                 $changes{'lclocalonly'} = 1;                  $changes{'lclocalonly'} = 1;
Line 10433  sub modify_directorysrch { Line 9700  sub modify_directorysrch {
             }              }
             if ($changes{'lclocalonly'}) {              if ($changes{'lclocalonly'}) {
                 $resulttext .= '<li>'.&mt("$title{'lclocalonly'} set to: $otherdoms[$env{'form.dirsrch_domlocalonly'}]").'</li>';                  $resulttext .= '<li>'.&mt("$title{'lclocalonly'} set to: $otherdoms[$env{'form.dirsrch_domlocalonly'}]").'</li>';
             }              }   
             if (ref($changes{'cansearch'}) eq 'ARRAY') {              if (ref($changes{'cansearch'}) eq 'ARRAY') {
                 my $chgtext;                  my $chgtext;
                 if (ref($usertypes) eq 'HASH') {                  if (ref($usertypes) eq 'HASH') {
Line 10483  sub modify_directorysrch { Line 9750  sub modify_directorysrch {
                 $resulttext .= '<li>'.&mt($title{'searchtypes'}.' set to: "[_1]"',$chgtext).'</li>';                  $resulttext .= '<li>'.&mt($title{'searchtypes'}.' set to: "[_1]"',$chgtext).'</li>';
             }              }
             $resulttext .= '</ul>';              $resulttext .= '</ul>';
             &Apache::lonnet::do_cache_new('directorysrch',$dom,$dirsrch_hash{'directorysrch'},3600);  
             if (ref($lastactref) eq 'HASH') {  
                 $lastactref->{'directorysrch'} = 1;  
             }  
         } else {          } else {
             $resulttext = &mt('No changes made to directory search settings');              $resulttext = &mt('No changes made to directory search settings');
         }          }
Line 10505  sub modify_contacts { Line 9768  sub modify_contacts {
             $currsetting{$key} = $domconfig{'contacts'}{$key};              $currsetting{$key} = $domconfig{'contacts'}{$key};
         }          }
     }      }
     my (%others,%to,%bcc,%includestr,%includeloc);      my (%others,%to,%bcc);
     my @contacts = ('supportemail','adminemail');      my @contacts = ('supportemail','adminemail');
     my @mailings = ('errormail','packagesmail','helpdeskmail','otherdomsmail',      my @mailings = ('errormail','packagesmail','helpdeskmail','lonstatusmail',
                     'lonstatusmail','requestsmail','updatesmail','idconflictsmail');                      'requestsmail','updatesmail','idconflictsmail');
     my @toggles = ('reporterrors','reportupdates');      my @toggles = ('reporterrors','reportupdates');
     my ($fields,$fieldtitles,$fieldoptions,$possoptions) = &helpform_fields();  
     foreach my $type (@mailings) {      foreach my $type (@mailings) {
         @{$newsetting{$type}} =           @{$newsetting{$type}} = 
             &Apache::loncommon::get_env_multiple('form.'.$type);              &Apache::loncommon::get_env_multiple('form.'.$type);
Line 10520  sub modify_contacts { Line 9782  sub modify_contacts {
             } else {              } else {
                 $contacts_hash{contacts}{$type}{$item} = 0;                  $contacts_hash{contacts}{$type}{$item} = 0;
             }              }
         }          }  
         $others{$type} = $env{'form.'.$type.'_others'};          $others{$type} = $env{'form.'.$type.'_others'};
         $contacts_hash{contacts}{$type}{'others'} = $others{$type};          $contacts_hash{contacts}{$type}{'others'} = $others{$type};
         if (($type eq 'helpdeskmail') || ($type eq 'otherdomsmail')) {          if ($type eq 'helpdeskmail') {
             $bcc{$type} = $env{'form.'.$type.'_bcc'};              $bcc{$type} = $env{'form.'.$type.'_bcc'};
             $contacts_hash{contacts}{$type}{'bcc'} = $bcc{$type};              $contacts_hash{contacts}{$type}{'bcc'} = $bcc{$type};
             if (($env{'form.'.$type.'_includestr'} ne '') && ($env{'form.'.$type.'_includeloc'} =~ /^s|b$/)) {  
                 $includestr{$type} = $env{'form.'.$type.'_includestr'};  
                 $includeloc{$type} = $env{'form.'.$type.'_includeloc'};  
                 $contacts_hash{contacts}{$type}{'include'} = $includeloc{$type}.':'.&escape($includestr{$type});  
             }  
         }          }
     }      }
     foreach my $item (@contacts) {      foreach my $item (@contacts) {
Line 10542  sub modify_contacts { Line 9799  sub modify_contacts {
             $contacts_hash{'contacts'}{$item} = $env{'form.'.$item};              $contacts_hash{'contacts'}{$item} = $env{'form.'.$item};
         }          }
     }      }
     if ((ref($fields) eq 'ARRAY') && (ref($possoptions) eq 'HASH')) {  
         foreach my $field (@{$fields}) {  
             if (ref($possoptions->{$field}) eq 'ARRAY') {  
                 my $value = $env{'form.helpform_'.$field};  
                 $value =~ s/^\s+|\s+$//g;  
                 if (grep(/^\Q$value\E$/,@{$possoptions->{$field}})) {  
                     $contacts_hash{'contacts'}{'helpform'}{$field} = $value;  
                     if ($field eq 'screenshot') {  
                         $env{'form.helpform_maxsize'} =~ s/^\s+|\s+$//g;  
                         if ($env{'form.helpform_maxsize'} =~ /^\d+\.?\d*$/) {  
                             $contacts_hash{'contacts'}{'helpform'}{'maxsize'} = $env{'form.helpform_maxsize'};  
                         }  
                     }  
                 }  
             }  
         }  
     }  
     my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom);  
     my (@statuses,%usertypeshash,@overrides);  
     if ((ref($types) eq 'ARRAY') && (@{$types} > 0)) {  
         @statuses = @{$types};  
         if (ref($usertypes) eq 'HASH') {  
             %usertypeshash = %{$usertypes};  
         }  
     }  
     if (@statuses) {  
         my @possoverrides = &Apache::loncommon::get_env_multiple('form.overrides');  
         foreach my $type (@possoverrides) {  
             if (($type ne '') && (grep(/^\Q$type\E$/,@statuses))) {  
                 push(@overrides,$type);  
             }  
         }  
         if (@overrides) {  
             foreach my $type (@overrides) {  
                 my @standard = &Apache::loncommon::get_env_multiple('form.override_'.$type);  
                 foreach my $item (@contacts) {  
                     if (grep(/^\Q$item\E$/,@standard)) {  
                         $contacts_hash{'contacts'}{'overrides'}{$type}{$item} = 1;  
                         $newsetting{'override_'.$type}{$item} = 1;  
                     } else {  
                         $contacts_hash{'contacts'}{'overrides'}{$type}{$item} = 0;  
                         $newsetting{'override_'.$type}{$item} = 0;  
                     }  
                 }  
                 $contacts_hash{'contacts'}{'overrides'}{$type}{'others'} = $env{'form.override_'.$type.'_others'};  
                 $contacts_hash{'contacts'}{'overrides'}{$type}{'bcc'} = $env{'form.override_'.$type.'_bcc'};  
                 $newsetting{'override_'.$type}{'others'} = $env{'form.override_'.$type.'_others'};  
                 $newsetting{'override_'.$type}{'bcc'} = $env{'form.override_'.$type.'_bcc'};  
                 if (($env{'form.override_'.$type.'_includestr'} ne '') && ($env{'form.override_'.$type.'_includeloc'} =~ /^s|b$/)) {  
                     $includestr{$type} = $env{'form.override_'.$type.'_includestr'};  
                     $includeloc{$type} = $env{'form.override_'.$type.'_includeloc'};  
                     $contacts_hash{'contacts'}{'overrides'}{$type}{'include'} = $includeloc{$type}.':'.&escape($includestr{$type});  
                     $newsetting{'override_'.$type}{'include'} = $contacts_hash{'contacts'}{'overrides'}{$type}{'include'};  
                 }  
             }  
         }  
     }  
     if (keys(%currsetting) > 0) {      if (keys(%currsetting) > 0) {
         foreach my $item (@contacts) {          foreach my $item (@contacts) {
             if ($to{$item} ne $currsetting{$item}) {              if ($to{$item} ne $currsetting{$item}) {
Line 10618  sub modify_contacts { Line 9818  sub modify_contacts {
             if ($others{$type} ne $currsetting{$type}{'others'}) {              if ($others{$type} ne $currsetting{$type}{'others'}) {
                 push(@{$changes{$type}},'others');                  push(@{$changes{$type}},'others');
             }              }
             if (($type eq 'helpdeskmail') || ($type eq 'otherdomsmail')) {              if ($type eq 'helpdeskmail') {   
                 if ($bcc{$type} ne $currsetting{$type}{'bcc'}) {                  if ($bcc{$type} ne $currsetting{$type}{'bcc'}) {
                     push(@{$changes{$type}},'bcc');                       push(@{$changes{$type}},'bcc'); 
                 }                  }
                 my ($currloc,$currstr) = split(/:/,$currsetting{$type}{'include'},2);  
                 if (($includeloc{$type} ne $currloc) || (&escape($includestr{$type}) ne $currstr)) {  
                     push(@{$changes{$type}},'include');  
                 }  
             }  
         }  
         if (ref($fields) eq 'ARRAY') {  
             if (ref($currsetting{'helpform'}) eq 'HASH') {  
                 foreach my $field (@{$fields}) {  
                     if ($currsetting{'helpform'}{$field} ne $contacts_hash{'contacts'}{'helpform'}{$field}) {  
                         push(@{$changes{'helpform'}},$field);  
                     }  
                     if (($field eq 'screenshot') && ($contacts_hash{'contacts'}{'helpform'}{'screenshot'} ne 'no')) {  
                         if ($currsetting{'helpform'}{'maxsize'} ne $contacts_hash{'contacts'}{'helpform'}{'maxsize'}) {  
                             push(@{$changes{'helpform'}},'maxsize');  
                         }  
                     }  
                 }  
             } else {  
                 foreach my $field (@{$fields}) {  
                     if ($contacts_hash{'contacts'}{'helpform'}{$field} ne 'yes') {  
                         push(@{$changes{'helpform'}},$field);  
                     }  
                     if (($field eq 'screenshot') && ($contacts_hash{'contacts'}{'helpform'}{'screenshot'} ne 'no')) {  
                         if ($contacts_hash{'contacts'}{'helpform'}{'maxsize'} != 1) {  
                             push(@{$changes{'helpform'}},'maxsize');  
                         }  
                     }  
                 }  
             }  
         }  
         if (@statuses) {  
             if (ref($currsetting{'overrides'}) eq 'HASH') {  
                 foreach my $key (keys(%{$currsetting{'overrides'}})) {  
                     if (ref($currsetting{'overrides'}{$key}) eq 'HASH') {  
                         if (ref($newsetting{'override_'.$key}) eq 'HASH') {  
                             foreach my $item (@contacts,'bcc','others','include') {  
                                 if ($currsetting{'overrides'}{$key}{$item} ne $newsetting{'override_'.$key}{$item}) {  
                                     push(@{$changes{'overrides'}},$key);  
                                     last;  
                                 }  
                             }  
                         } else {  
                             push(@{$changes{'overrides'}},$key);  
                         }  
                     }  
                 }  
                 foreach my $key (@overrides) {  
                     unless (exists($currsetting{'overrides'}{$key})) {  
                         push(@{$changes{'overrides'}},$key);  
                     }  
                 }  
             } else {  
                 foreach my $key (@overrides) {  
                     push(@{$changes{'overrides'}},$key);  
                 }  
             }              }
         }          }
     } else {      } else {
Line 10687  sub modify_contacts { Line 9831  sub modify_contacts {
         $default{'errormail'} = 'adminemail';          $default{'errormail'} = 'adminemail';
         $default{'packagesmail'} = 'adminemail';          $default{'packagesmail'} = 'adminemail';
         $default{'helpdeskmail'} = 'supportemail';          $default{'helpdeskmail'} = 'supportemail';
         $default{'otherdomsmail'} = 'supportemail';  
         $default{'lonstatusmail'} = 'adminemail';          $default{'lonstatusmail'} = 'adminemail';
         $default{'requestsmail'} = 'adminemail';          $default{'requestsmail'} = 'adminemail';
         $default{'updatesmail'} = 'adminemail';          $default{'updatesmail'} = 'adminemail';
         foreach my $item (@contacts) {          foreach my $item (@contacts) {
            if ($to{$item} ne $default{$item}) {             if ($to{$item} ne $default{$item}) {
                $changes{$item} = 1;                $changes{$item} = 1;
            }             }
         }          }
         foreach my $type (@mailings) {          foreach my $type (@mailings) {
             if ((@{$newsetting{$type}} != 1) || ($newsetting{$type}[0] ne $default{$type})) {              if ((@{$newsetting{$type}} != 1) || ($newsetting{$type}[0] ne $default{$type})) {
                  
                 push(@{$changes{$type}},@{$newsetting{$type}});                  push(@{$changes{$type}},@{$newsetting{$type}});
             }              }
             if ($others{$type} ne '') {              if ($others{$type} ne '') {
                 push(@{$changes{$type}},'others');                  push(@{$changes{$type}},'others');
             }              }
             if (($type eq 'helpdeskmail') || ($type eq 'otherdomsmail')) {              if ($type eq 'helpdeskmail') {
                 if ($bcc{$type} ne '') {                  if ($bcc{$type} ne '') {
                     push(@{$changes{$type}},'bcc');                      push(@{$changes{$type}},'bcc');
                 }                  }
                 if (($includeloc{$type} =~ /^b|s$/) && ($includestr{$type} ne '')) {  
                     push(@{$changes{$type}},'include');  
                 }  
             }  
         }  
         if (ref($fields) eq 'ARRAY') {  
             foreach my $field (@{$fields}) {  
                 if ($contacts_hash{'contacts'}{'helpform'}{$field} ne 'yes') {  
                     push(@{$changes{'helpform'}},$field);  
                 }  
                 if (($field eq 'screenshot') && ($contacts_hash{'contacts'}{'helpform'}{'screenshot'} ne 'no')) {  
                     if ($contacts_hash{'contacts'}{'helpform'}{'maxsize'} != 1) {  
                         push(@{$changes{'helpform'}},'maxsize');  
                     }  
                 }  
             }              }
         }          }
     }      }
Line 10753  sub modify_contacts { Line 9882  sub modify_contacts {
             }              }
             foreach my $type (@mailings) {              foreach my $type (@mailings) {
                 if (ref($changes{$type}) eq 'ARRAY') {                  if (ref($changes{$type}) eq 'ARRAY') {
                     if (($type eq 'helpdeskmail') || ($type eq 'otherdomsmail')) {                      $resulttext .= '<li>'.$titles->{$type}.': ';
                         $resulttext .= '<li>'.$titles->{$type}.' -- '.&mt('sent to').': ';  
                     } else {  
                         $resulttext .= '<li>'.$titles->{$type}.': ';  
                     }  
                     my @text;                      my @text;
                     foreach my $item (@{$newsetting{$type}}) {                      foreach my $item (@{$newsetting{$type}}) {
                         push(@text,$short_titles->{$item});                          push(@text,$short_titles->{$item});
Line 10765  sub modify_contacts { Line 9890  sub modify_contacts {
                     if ($others{$type} ne '') {                      if ($others{$type} ne '') {
                         push(@text,$others{$type});                          push(@text,$others{$type});
                     }                      }
                     if (@text) {                      $resulttext .= '<span class="LC_cusr_emph">'.
                         $resulttext .= '<span class="LC_cusr_emph">'.                                     join(', ',@text).'</span>';
                                        join(', ',@text).'</span>';                      if ($type eq 'helpdeskmail') {
                     }  
                     if (($type eq 'helpdeskmail') || ($type eq 'otherdomsmail')) {  
                         if ($bcc{$type} ne '') {                          if ($bcc{$type} ne '') {
                             my $bcctext;                              $resulttext .= '&nbsp;'.&mt('with Bcc to').': <span class="LC_cusr_emph">'.$bcc{$type}.'</span>';
                             if (@text) {  
                                 $bcctext = '&nbsp;'.&mt('with Bcc to');  
                             } else {  
                                 $bcctext = '(Bcc)';  
                             }  
                             $resulttext .= $bcctext.': <span class="LC_cusr_emph">'.$bcc{$type}.'</span>';  
                         } elsif (!@text) {  
                             $resulttext .= &mt('No one');  
                         }  
                         if ($includestr{$type} ne '') {  
                             if ($includeloc{$type} eq 'b') {  
                                 $resulttext .= '<br />'.&mt('Text automatically added to e-mail body:').' '.$includestr{$type};  
                             } elsif ($includeloc{$type} eq 's') {  
                                 $resulttext .= '<br />'.&mt('Text automatically added to e-mail subject:').' '.$includestr{$type};  
                             }  
                         }                          }
                     } elsif (!@text) {  
                         $resulttext .= &mt('No recipients');  
                     }                      }
                     $resulttext .= '</li>';                      $resulttext .= '</li>';
                 }                  }
             }              }
             if (ref($changes{'overrides'}) eq 'ARRAY') {  
                 my @deletions;  
                 foreach my $type (@{$changes{'overrides'}}) {  
                     if ($usertypeshash{$type}) {  
                         if (grep(/^\Q$type\E/,@overrides)) {  
                             $resulttext .= '<li>'.&mt("Overrides based on requester's affiliation set for [_1]",  
                                                       $usertypeshash{$type}).'<ul><li>';  
                             if (ref($newsetting{'override_'.$type}) eq 'HASH') {  
                                 my @text;  
                                 foreach my $item (@contacts) {  
                                     if ($newsetting{'override_'.$type}{$item}) {  
                                         push(@text,$short_titles->{$item});  
                                     }  
                                 }  
                                 if ($newsetting{'override_'.$type}{'others'} ne '') {  
                                     push(@text,$newsetting{'override_'.$type}{'others'});  
                                 }  
   
                                 if (@text) {  
                                     $resulttext .= &mt('Helpdesk e-mail sent to: [_1]',  
                                                        '<span class="LC_cusr_emph">'.join(', ',@text).'</span>');  
                                 }  
                                 if ($newsetting{'override_'.$type}{'bcc'} ne '') {  
                                     my $bcctext;  
                                     if (@text) {  
                                         $bcctext = '&nbsp;'.&mt('with Bcc to');  
                                     } else {  
                                         $bcctext = '(Bcc)';  
                                     }  
                                     $resulttext .= $bcctext.': <span class="LC_cusr_emph">'.$newsetting{'override_'.$type}{'bcc'}.'</span>';  
                                 } elsif (!@text) {  
                                      $resulttext .= &mt('Helpdesk e-mail sent to no one');  
                                 }  
                                 $resulttext .= '</li>';  
                                 if ($newsetting{'override_'.$type}{'include'} ne '') {  
                                     my ($loc,$str) = split(/:/,$newsetting{'override_'.$type}{'include'});  
                                     if ($loc eq 'b') {  
                                         $resulttext .= '<li>'.&mt('Text automatically added to e-mail body:').' '.&unescape($str).'</li>';  
                                     } elsif ($loc eq 's') {  
                                         $resulttext .= '<li>'.&mt('Text automatically added to e-mail subject:').' '.&unescape($str).'</li>';  
                                     }  
                                 }  
                             }  
                             $resulttext .= '</li></ul></li>';  
                         } else {  
                             push(@deletions,$usertypeshash{$type});  
                         }  
                     }  
                 }  
                 if (@deletions) {  
                     $resulttext .= '<li>'.&mt("Overrides based on requester's affiliation discontinued for: [_1]",  
                                               join(', ',@deletions)).'</li>';  
                 }  
             }  
             my @offon = ('off','on');              my @offon = ('off','on');
             if ($changes{'reporterrors'}) {              if ($changes{'reporterrors'}) {
                 $resulttext .= '<li>'.                  $resulttext .= '<li>'.
Line 10865  sub modify_contacts { Line 9917  sub modify_contacts {
                                         &mt('LON-CAPA core group - MSU'),600,500)).                                          &mt('LON-CAPA core group - MSU'),600,500)).
                                 '</li>';                                  '</li>';
             }              }
             if ((ref($changes{'helpform'}) eq 'ARRAY') && (ref($fields) eq 'ARRAY')) {  
                 my (@optional,@required,@unused,$maxsizechg);  
                 foreach my $field (@{$changes{'helpform'}}) {  
                     if ($field eq 'maxsize') {  
                         $maxsizechg = 1;  
                         next;  
                     }  
                     if ($contacts_hash{'contacts'}{'helpform'}{$field} eq 'yes') {  
                         push(@optional,$field);  
                     } elsif ($contacts_hash{'contacts'}{'helpform'}{$field} eq 'no') {  
                         push(@unused,$field);  
                     } elsif ($contacts_hash{'contacts'}{'helpform'}{$field} eq 'req') {  
                         push(@required,$field);  
                     }  
                 }  
                 if (@optional) {  
                     $resulttext .= '<li>'.  
                                    &mt('Help form fields changed to "Optional": [_1].',  
                                        '<span class="LC_cusr_emph">'.join(', ',map { $fieldtitles->{$_}; } @optional)).'</span>'.  
                                    '</li>';  
                 }  
                 if (@required) {  
                     $resulttext .= '<li>'.  
                                    &mt('Help form fields changed to "Required": [_1].',  
                                        '<span class="LC_cusr_emph">'.join(', ',map { $fieldtitles->{$_}; } @required)).'</span>'.  
                                    '</li>';  
                 }  
                 if (@unused) {  
                     $resulttext .= '<li>'.  
                                    &mt('Help form fields changed to "Not shown": [_1].',  
                                        '<span class="LC_cusr_emph">'.join(', ',map { $fieldtitles->{$_}; } @unused)).'</span>'.  
                                    '</li>';  
                 }  
                 if ($maxsizechg) {  
                     $resulttext .= '<li>'.  
                                    &mt('Max size for file uploaded to help form by logged-in user set to [_1] MB.',  
                                        $contacts_hash{'contacts'}{'helpform'}{'maxsize'}).  
                                    '</li>';  
                 }  
             }  
             $resulttext .= '</ul>';              $resulttext .= '</ul>';
         } else {          } else {
             $resulttext = &mt('No changes made to contacts and form settings');              $resulttext = &mt('No changes made to contact information');
         }          }
     } else {      } else {
         $resulttext = '<span class="LC_error">'.          $resulttext = '<span class="LC_error">'.
Line 11496  sub modify_selfcreation { Line 10508  sub modify_selfcreation {
         $save_usercreate{'cancreate'}{'shibenv'} = $cancreate{'shibenv'};          $save_usercreate{'cancreate'}{'shibenv'} = $cancreate{'shibenv'};
     }      }
     $save_usercreate{'cancreate'}{'emailusername'} = $cancreate{'emailusername'};      $save_usercreate{'cancreate'}{'emailusername'} = $cancreate{'emailusername'};
     $save_usercreate{'email_rule'} = \@email_rule;      $save_usercreate{'emailrule'} = \@email_rule;
   
     my %userconfig_hash = (      my %userconfig_hash = (
             usercreation     => \%save_usercreate,              usercreation     => \%save_usercreate,
Line 11932  sub modify_defaults { Line 10944  sub modify_defaults {
     my ($dom,$lastactref,%domconfig) = @_;      my ($dom,$lastactref,%domconfig) = @_;
     my ($resulttext,$mailmsgtxt,%newvalues,%changes,@errors);      my ($resulttext,$mailmsgtxt,%newvalues,%changes,@errors);
     my %domdefaults = &Apache::lonnet::get_domain_defaults($dom,1);      my %domdefaults = &Apache::lonnet::get_domain_defaults($dom,1);
     my @items = ('auth_def','auth_arg_def','lang_def','timezone_def','datelocale_def',      my @items = ('auth_def','auth_arg_def','lang_def','timezone_def','datelocale_def','portal_def');
                  'portal_def','intauth_cost','intauth_check','intauth_switch');  
     my @authtypes = ('internal','krb4','krb5','localauth');      my @authtypes = ('internal','krb4','krb5','localauth');
     foreach my $item (@items) {      foreach my $item (@items) {
         $newvalues{$item} = $env{'form.'.$item};          $newvalues{$item} = $env{'form.'.$item};
Line 11975  sub modify_defaults { Line 10986  sub modify_defaults {
                     push(@errors,$item);                      push(@errors,$item);
                 }                  }
             }              }
         } elsif ($item eq 'intauth_cost') {  
             if ($newvalues{$item} ne '') {  
                 if ($newvalues{$item} =~ /\D/) {  
                     push(@errors,$item);  
                 }  
             }  
         } elsif ($item eq 'intauth_check') {  
             if ($newvalues{$item} ne '') {  
                 unless ($newvalues{$item} =~ /^(0|1|2)$/) {  
                     push(@errors,$item);  
                 }  
             }  
         } elsif ($item eq 'intauth_switch') {  
             if ($newvalues{$item} ne '') {  
                 unless ($newvalues{$item} =~ /^(0|1|2)$/) {  
                     push(@errors,$item);  
                 }  
             }  
         }          }
         if (grep(/^\Q$item\E$/,@errors)) {          if (grep(/^\Q$item\E$/,@errors)) {
             $newvalues{$item} = $domdefaults{$item};              $newvalues{$item} = $domdefaults{$item};
Line 12147  sub modify_defaults { Line 11140  sub modify_defaults {
                                           localauth  => 'loc',                                            localauth  => 'loc',
                         );                          );
                         $value = $authnames{$shortauth{$value}};                          $value = $authnames{$shortauth{$value}};
                     } elsif ($item eq 'intauth_switch') {  
                         my %optiondesc = &Apache::lonlocal::texthash (  
                                             0 => 'No',  
                                             1 => 'Yes',  
                                             2 => 'Yes, and copy existing passwd file to passwd.bak file',  
                                          );  
                         if ($value =~ /^(0|1|2)$/) {  
                             $value = $optiondesc{$value};  
                         } else {  
                             $value = &mt('none -- defaults to No');  
                         }  
                     } elsif ($item eq 'intauth_check') {  
                         my %optiondesc = &Apache::lonlocal::texthash (  
                                              0 => 'No',  
                                              1 => 'Yes, allow login then update passwd file using default cost (if higher)',  
                                              2 => 'Yes, disallow login if stored cost is less than domain default',  
                                          );  
                         if ($value =~ /^(0|1|2)$/) {  
                             $value = $optiondesc{$value};  
                         } else {  
                             $value = &mt('none -- defaults to No');  
                         }  
                     }                      }
                     $resulttext .= '<li>'.&mt('[_1] set to "[_2]"',$title->{$item},$value).'</li>';                      $resulttext .= '<li>'.&mt('[_1] set to "[_2]"',$title->{$item},$value).'</li>';
                     $mailmsgtext .= "$title->{$item} set to $value\n";                        $mailmsgtext .= "$title->{$item} set to $value\n";  
Line 12317  sub modify_coursecategories { Line 11288  sub modify_coursecategories {
         if ($domconfig{'coursecategories'}{'categorizecomm'} ne $env{'form.categorizecomm'}) {          if ($domconfig{'coursecategories'}{'categorizecomm'} ne $env{'form.categorizecomm'}) {
             $changes{'categorizecomm'} = 1;              $changes{'categorizecomm'} = 1;
             $domconfig{'coursecategories'}{'categorizecomm'} = $env{'form.categorizecomm'};              $domconfig{'coursecategories'}{'categorizecomm'} = $env{'form.categorizecomm'};
   
           }
           if ($domconfig{'coursecategories'}{'togglecatsplace'} ne $env{'form.togglecatsplace'}) {
               $changes{'togglecatsplace'} = 1;
               $domconfig{'coursecategories'}{'togglecatsplace'} = $env{'form.togglecatsplace'};
           }
           if ($domconfig{'coursecategories'}{'categorizeplace'} ne $env{'form.categorizeplace'}) {
               $changes{'categorizeplace'} = 1;
               $domconfig{'coursecategories'}{'categorizeplace'} = $env{'form.categorizeplace'};
         }          }
         foreach my $item (@catitems) {          foreach my $item (@catitems) {
             if (grep(/^\Q$env{'form.coursecat_'.$item}\E$/,@cattypes)) {              if (grep(/^\Q$env{'form.coursecat_'.$item}\E$/,@cattypes)) {
Line 12331  sub modify_coursecategories { Line 11311  sub modify_coursecategories {
         $changes{'categorize'} = 1;          $changes{'categorize'} = 1;
         $changes{'togglecatscomm'} = 1;          $changes{'togglecatscomm'} = 1;
         $changes{'categorizecomm'} = 1;          $changes{'categorizecomm'} = 1;
           $changes{'togglecatsplace'} = 1;
           $changes{'categorizeplace'} = 1;
         $domconfig{'coursecategories'} = {          $domconfig{'coursecategories'} = {
                                              togglecats => $env{'form.togglecats'},                                               togglecats => $env{'form.togglecats'},
                                              categorize => $env{'form.categorize'},                                               categorize => $env{'form.categorize'},
                                              togglecatscomm => $env{'form.togglecatscomm'},                                               togglecatscomm => $env{'form.togglecatscomm'},
                                              categorizecomm => $env{'form.categorizecomm'},                                               categorizecomm => $env{'form.categorizecomm'},
                                                togglecatsplace => $env{'form.togglecatsplace'},
                                                categorizeplace => $env{'form.categorizeplace'},
                                          };                                           };
         foreach my $item (@catitems) {          foreach my $item (@catitems) {
             if ($env{'form.coursecat_'.$item} ne 'std') {              if ($env{'form.coursecat_'.$item} ne 'std') {
Line 12353  sub modify_coursecategories { Line 11337  sub modify_coursecategories {
         if (($domconfig{'coursecategories'}{'cats'}{'communities::0'} ne '')  && ($env{'form.communities'} == 0)) {          if (($domconfig{'coursecategories'}{'cats'}{'communities::0'} ne '')  && ($env{'form.communities'} == 0)) {
             push(@deletecategory,'communities::0');              push(@deletecategory,'communities::0');
         }          }
           if (($domconfig{'coursecategories'}{'cats'}{'placement::0'} ne '')  && ($env{'form.placement'} == 0)) {
               push(@deletecategory,'placement::0');
           }
     }      }
     my (@predelcats,@predeltrails,%predelallitems,%sort_by_deltrail);      my (@predelcats,@predeltrails,%predelallitems,%sort_by_deltrail);
     if (ref($cathash) eq 'HASH') {      if (ref($cathash) eq 'HASH') {
Line 12415  sub modify_coursecategories { Line 11402  sub modify_coursecategories {
             $adds{$newitem} = 1;              $adds{$newitem} = 1;
         }          }
     }      }
       if ($env{'form.placement'} eq '1') {
           if (ref($cathash) eq 'HASH') {
               my $newitem = 'placement::0';
               if ($cathash->{$newitem} eq '') {
                   $domconfig{'coursecategories'}{'cats'}{$newitem} = $env{'form.placement_pos'};
                   $adds{$newitem} = 1;
               }
           } else {
               my $newitem = 'placement::0';
               $domconfig{'coursecategories'}{'cats'}{$newitem} = $env{'form.placement_pos'};
               $adds{$newitem} = 1;
           }
       }
     if ($env{'form.addcategory_name'} ne '') {      if ($env{'form.addcategory_name'} ne '') {
         if (($env{'form.addcategory_name'} ne 'instcode') &&          if (($env{'form.addcategory_name'} ne 'instcode') &&
             ($env{'form.addcategory_name'} ne 'communities')) {              ($env{'form.addcategory_name'} ne 'communities') &&
               ($env{'form.addcategory_name'} ne 'placement')) {
             my $newitem = &escape($env{'form.addcategory_name'}).'::0';              my $newitem = &escape($env{'form.addcategory_name'}).'::0';
             $domconfig{'coursecategories'}{'cats'}{$newitem} = $env{'form.addcategory_pos'};              $domconfig{'coursecategories'}{'cats'}{$newitem} = $env{'form.addcategory_pos'};
             $adds{$newitem} = 1;              $adds{$newitem} = 1;
Line 12684  sub modify_serverstatuses { Line 11685  sub modify_serverstatuses {
 }  }
   
 sub modify_helpsettings {  sub modify_helpsettings {
     my ($r,$dom,$confname,$lastactref,%domconfig) = @_;      my ($r,$dom,$confname,%domconfig) = @_;
     my ($resulttext,$errors,%changes,%helphash);      my ($resulttext,$errors,%changes,%helphash);
     my %defaultchecked = ('submitbugs' => 'on');      my %defaultchecked = ('submitbugs' => 'on');
     my @offon = ('off','on');      my @offon = ('off','on');
     my @toggles = ('submitbugs');      my @toggles = ('submitbugs');
     my %current = ('submitbugs' => '',  
                    'adhoc'      => {},  
                   );  
     if (ref($domconfig{'helpsettings'}) eq 'HASH') {      if (ref($domconfig{'helpsettings'}) eq 'HASH') {
         %current = %{$domconfig{'helpsettings'}};          foreach my $item (@toggles) {
     }              if ($defaultchecked{$item} eq 'on') { 
     my %domdefaults = &Apache::lonnet::get_domain_defaults($dom,1);                  if ($domconfig{'helpsettings'}{$item} eq '') {
     foreach my $item (@toggles) {                      if ($env{'form.'.$item} eq '0') {
         if ($defaultchecked{$item} eq 'on') {                           $changes{$item} = 1;
             if ($current{$item} eq '') {  
                 if ($env{'form.'.$item} eq '0') {  
                     $changes{$item} = 1;  
                 }  
             } elsif ($current{$item} ne $env{'form.'.$item}) {  
                 $changes{$item} = 1;  
             }  
         } elsif ($defaultchecked{$item} eq 'off') {  
             if ($current{$item} eq '') {  
                 if ($env{'form.'.$item} eq '1') {  
                     $changes{$item} = 1;  
                 }  
             } elsif ($current{$item} ne $env{'form.'.$item}) {  
                 $changes{$item} = 1;  
             }  
         }  
         if (($env{'form.'.$item} eq '0') || ($env{'form.'.$item} eq '1')) {  
             $helphash{'helpsettings'}{$item} = $env{'form.'.$item};  
         }  
     }  
     my $maxnum = $env{'form.helproles_maxnum'};  
     my $confname = $dom.'-domainconfig';  
     my %existing=&Apache::lonnet::dump('roles',$dom,$confname,'rolesdef_');  
     my (@allpos,%newsettings,%changedprivs,$newrole);  
     my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom);  
     my @accesstypes = ('all','dh','da','none','status','inc','exc');  
     my %domhelpdesk = &Apache::lonnet::get_active_domroles($dom,['dh','da']);  
     my %lt = &Apache::lonlocal::texthash(  
                     s      => 'system',  
                     d      => 'domain',  
                     order  => 'Display order',  
                     access => 'Role usage',  
                     all    => 'All with domain helpdesk or helpdesk assistant role',  
                     dh     => 'All with domain helpdesk role',  
                     da     => 'All with domain helpdesk assistant role',  
                     none   => 'None',  
                     status => 'Determined based on institutional status',  
                     inc    => 'Include all, but exclude specific personnel',  
                     exc    => 'Exclude all, but include specific personnel',  
     );  
     for (my $num=0; $num<=$maxnum; $num++) {  
         my ($prefix,$identifier,$rolename,%curr);  
         if ($num == $maxnum) {  
             next unless ($env{'form.newcusthelp'} == $maxnum);  
             $identifier = 'custhelp'.$num;  
             $prefix = 'helproles_'.$num;  
             $rolename = $env{'form.custhelpname'.$num};  
             $rolename=~s/[^A-Za-z0-9]//gs;  
             next if ($rolename eq '');  
             next if (exists($existing{'rolesdef_'.$rolename}));  
             my %newprivs = &Apache::lonuserutils::custom_role_update($rolename,$identifier);  
             my $result = &Apache::lonnet::definerole($rolename,$newprivs{'s'},$newprivs{'d'},  
                                                      $newprivs{'c'},$confname,$dom);  
             if ($result ne 'ok') {  
                 $errors .= '<li><span class="LC_error">'.  
                            &mt('An error occurred storing the new custom role: [_1]',  
                            $result).'</span></li>';  
                 next;  
             } else {  
                 $changedprivs{$rolename} = \%newprivs;  
                 $newrole = $rolename;  
             }  
         } else {  
             $prefix = 'helproles_'.$num;  
             $rolename = $env{'form.'.$prefix};  
             next if ($rolename eq '');  
             next unless (exists($existing{'rolesdef_'.$rolename}));  
             $identifier = 'custhelp'.$num;  
             my %newprivs = &Apache::lonuserutils::custom_role_update($rolename,$identifier);  
             my %currprivs;  
             ($currprivs{'s'},$currprivs{'d'},$currprivs{'c'}) =  
                 split(/\_/,$existing{'rolesdef_'.$rolename});  
             foreach my $level ('c','d','s') {  
                 if ($newprivs{$level} ne $currprivs{$level}) {  
                     my $result = &Apache::lonnet::definerole($rolename,$newprivs{'s'},$newprivs{'d'},  
                                                              $newprivs{'c'},$confname,$dom);  
                     if ($result ne 'ok') {  
                         $errors .= '<li><span class="LC_error">'.  
                                    &mt('An error occurred storing privileges for existing role [_1]: [_2]',  
                                        $rolename,$result).'</span></li>';  
                     } else {  
                         $changedprivs{$rolename} = \%newprivs;  
                     }  
                     last;  
                 }  
             }  
             if (ref($current{'adhoc'}) eq 'HASH') {  
                 if (ref($current{'adhoc'}{$rolename}) eq 'HASH') {  
                     %curr = %{$current{'adhoc'}{$rolename}};  
                 }  
             }  
         }  
         my $newpos = $env{'form.'.$prefix.'_pos'};  
         $newpos =~ s/\D+//g;  
         $allpos[$newpos] = $rolename;  
         my $newdesc = $env{'form.'.$prefix.'_desc'};  
         $helphash{'helpsettings'}{'adhoc'}{$rolename}{'desc'} = $newdesc;  
         if ($curr{'desc'}) {  
             if ($curr{'desc'} ne $newdesc) {  
                 $changes{'customrole'}{$rolename}{'desc'} = 1;  
                 $newsettings{$rolename}{'desc'} = $newdesc;  
             }  
         } elsif ($newdesc ne '') {  
             $changes{'customrole'}{$rolename}{'desc'} = 1;  
             $newsettings{$rolename}{'desc'} = $newdesc;  
         }  
         my $access = $env{'form.'.$prefix.'_access'};  
         if (grep(/^\Q$access\E$/,@accesstypes)) {  
             $helphash{'helpsettings'}{'adhoc'}{$rolename}{'access'} = $access;  
             if ($access eq 'status') {  
                 my @statuses = &Apache::loncommon::get_env_multiple('form.'.$prefix.'_status');  
                 if (scalar(@statuses) == 0) {  
                     $helphash{'helpsettings'}{'adhoc'}{$rolename}{'access'} = 'none';  
                 } else {  
                     my (@shownstatus,$numtypes);  
                     $helphash{'helpsettings'}{'adhoc'}{$rolename}{$access} = [];  
                     if (ref($types) eq 'ARRAY') {  
                         $numtypes = scalar(@{$types});  
                         foreach my $type (sort(@statuses)) {  
                             if ($type eq 'default') {  
                                 push(@{$helphash{'helpsettings'}{'adhoc'}{$rolename}{$access}},$type);  
                             } elsif (grep(/^\Q$type\E$/,@{$types})) {  
                                 push(@{$helphash{'helpsettings'}{'adhoc'}{$rolename}{$access}},$type);  
                                 push(@shownstatus,$usertypes->{$type});  
                             }  
                         }  
                     }  
                     if (grep(/^default$/,@statuses)) {  
                         push(@shownstatus,$othertitle);  
                     }  
                     if (scalar(@shownstatus) == 1+$numtypes) {  
                         $helphash{'helpsettings'}{'adhoc'}{$rolename}{'access'} = 'all';  
                         delete($helphash{'helpsettings'}{'adhoc'}{$rolename}{'status'});  
                     } else {  
                         $newsettings{$rolename}{'status'} = join(' '.&mt('or').' ',@shownstatus);  
                         if (ref($curr{'status'}) eq 'ARRAY') {  
                             my @diffs = &Apache::loncommon::compare_arrays($helphash{'helpsettings'}{'adhoc'}{$rolename}{$access},$curr{$access});  
                             if (@diffs) {  
                                 $changes{'customrole'}{$rolename}{$access} = 1;  
                             }  
                         } elsif (@{$helphash{'helpsettings'}{'adhoc'}{$rolename}{$access}}) {  
                             $changes{'customrole'}{$rolename}{$access} = 1;  
                         }  
                     }  
                 }  
             } elsif (($access eq 'inc') || ($access eq 'exc')) {  
                 my @personnel = &Apache::loncommon::get_env_multiple('form.'.$prefix.'_staff_'.$access);  
                 my @newspecstaff;  
                 $helphash{'helpsettings'}{'adhoc'}{$rolename}{$access} = [];  
                 foreach my $person (sort(@personnel)) {  
                     if ($domhelpdesk{$person}) {  
                         push(@{$helphash{'helpsettings'}{'adhoc'}{$rolename}{$access}},$person);  
                     }                      }
                   } elsif ($domconfig{'helpsettings'}{$item} ne $env{'form.'.$item}) {
                       $changes{$item} = 1;
                 }                  }
                 if (ref($curr{$access}) eq 'ARRAY') {              } elsif ($defaultchecked{$item} eq 'off') {
                     my @diffs = &Apache::loncommon::compare_arrays($helphash{'helpsettings'}{'adhoc'}{$rolename}{$access},$curr{$access});                  if ($domconfig{'helpsettings'}{$item} eq '') {
                     if (@diffs) {                      if ($env{'form.'.$item} eq '1') {
                         $changes{'customrole'}{$rolename}{$access} = 1;                          $changes{$item} = 1;
                     }                      }
                 } elsif (@{$helphash{'helpsettings'}{'adhoc'}{$rolename}{$access}}) {                  } elsif ($domconfig{'helpsettings'}{$item} ne $env{'form.'.$item}) {
                     $changes{'customrole'}{$rolename}{$access} = 1;                      $changes{$item} = 1;
                 }  
                 foreach my $person (@{$helphash{'helpsettings'}{'adhoc'}{$rolename}{$access}}) {  
                     my ($uname,$udom) = split(/:/,$person);  
                         push(@newspecstaff,&Apache::loncommon::aboutmewrapper(&Apache::loncommon::plainname($uname,$udom,'lastname'),$uname,$udom));  
                 }                  }
                 $newsettings{$rolename}{$access} = join(', ',sort(@newspecstaff));  
             }              }
         } else {              if (($env{'form.'.$item} eq '0') || ($env{'form.'.$item} eq '1')) {
             $helphash{'helpsettings'}{'adhoc'}{$rolename}{'access'}= 'all';                  $helphash{'helpsettings'}{$item} = $env{'form.'.$item};
         }  
         unless ($curr{'access'} eq $access) {  
             $changes{'customrole'}{$rolename}{'access'} = 1;  
             $newsettings{$rolename}{'access'} = $lt{$helphash{'helpsettings'}{'adhoc'}{$rolename}{'access'}};  
         }  
     }  
     if (@allpos > 0) {  
         my $idx = 0;  
         foreach my $rolename (@allpos) {  
             if ($rolename ne '') {  
                 $helphash{'helpsettings'}{'adhoc'}{$rolename}{'order'} = $idx;  
                 if (ref($current{'adhoc'}) eq 'HASH') {  
                     if (ref($current{'adhoc'}{$rolename}) eq 'HASH') {  
                         if ($current{'adhoc'}{$rolename}{'order'} ne $idx) {  
                             $changes{'customrole'}{$rolename}{'order'} = 1;  
                             $newsettings{$rolename}{'order'} = $idx+1;  
                         }  
                     }  
                 }  
                 $idx ++;  
             }              }
         }          }
     }      }
Line 12895  sub modify_helpsettings { Line 11718  sub modify_helpsettings {
     if (keys(%changes) > 0) {      if (keys(%changes) > 0) {
         $putresult = &Apache::lonnet::put_dom('configuration',\%helphash,$dom);          $putresult = &Apache::lonnet::put_dom('configuration',\%helphash,$dom);
         if ($putresult eq 'ok') {          if ($putresult eq 'ok') {
             if (ref($helphash{'helpsettings'}) eq 'HASH') {              $resulttext = &mt('Changes made:').'<ul>';
                 $domdefaults{'submitbugs'} = $helphash{'helpsettings'}{'submitbugs'};  
                 if (ref($helphash{'helpsettings'}{'adhoc'}) eq 'HASH') {  
                     $domdefaults{'adhocroles'} = $helphash{'helpsettings'}{'adhoc'};  
                 }  
             }  
             my $cachetime = 24*60*60;  
             &Apache::lonnet::do_cache_new('domdefaults',$dom,\%domdefaults,$cachetime);  
             if (ref($lastactref) eq 'HASH') {  
                 $lastactref->{'domdefaults'} = 1;  
             }  
         } else {  
             $errors .= '<li><span class="LC_error">'.  
                        &mt('An error occurred storing the settings: [_1]',  
                            $putresult).'</span></li>';  
         }  
     }  
     if ((keys(%changes) && ($putresult eq 'ok')) || (keys(%changedprivs))) {  
         $resulttext = &mt('Changes made:').'<ul>';  
         my (%shownprivs,@levelorder);  
         @levelorder = ('c','d','s');  
         if ((keys(%changes)) && ($putresult eq 'ok')) {  
             foreach my $item (sort(keys(%changes))) {              foreach my $item (sort(keys(%changes))) {
                 if ($item eq 'submitbugs') {                  if ($item eq 'submitbugs') {
                     $resulttext .= '<li>'.&mt('Display link to: [_1] set to "'.$offon[$env{'form.'.$item}].'".',                      $resulttext .= '<li>'.&mt('Display link to: [_1] set to "'.$offon[$env{'form.'.$item}].'".',
                                               &Apache::loncommon::modal_link('http://bugs.loncapa.org',                                                &Apache::loncommon::modal_link('http://bugs.loncapa.org',
                                               &mt('LON-CAPA bug tracker'),600,500)).'</li>';                                                &mt('LON-CAPA bug tracker'),600,500)).'</li>';
                 } elsif ($item eq 'customrole') {  
                     if (ref($changes{'customrole'}) eq 'HASH') {  
                         my @keyorder = ('order','desc','access','status','exc','inc');  
                         my %keytext = &Apache::lonlocal::texthash(  
                                                                    order  => 'Order',  
                                                                    desc   => 'Role description',  
                                                                    access => 'Role usage',  
                                                                    status => 'Allowed institutional types',  
                                                                    exc    => 'Allowed personnel',  
                                                                    inc    => 'Disallowed personnel',  
                         );  
                         foreach my $role (sort(keys(%{$changes{'customrole'}}))) {  
                             if (ref($changes{'customrole'}{$role}) eq 'HASH') {  
                                 if ($role eq $newrole) {  
                                     $resulttext .= '<li>'.&mt('New custom role added: [_1]',  
                                                               $role).'<ul>';  
                                 } else {  
                                     $resulttext .= '<li>'.&mt('Existing custom role modified: [_1]',  
                                                               $role).'<ul>';  
                                 }  
                                 foreach my $key (@keyorder) {  
                                     if ($changes{'customrole'}{$role}{$key}) {  
                                         $resulttext .= '<li>'.&mt("[_1] set to: [_2]",  
                                                                   $keytext{$key},$newsettings{$role}{$key}).  
                                                        '</li>';  
                                     }  
                                 }  
                                 if (ref($changedprivs{$role}) eq 'HASH') {  
                                     $shownprivs{$role} = 1;  
                                     $resulttext .= '<li>'.&mt('Privileges set to :').'<ul>';  
                                     foreach my $level (@levelorder) {  
                                         foreach my $item (split(/\:/,$changedprivs{$role}{$level})) {  
                                             next if ($item eq '');  
                                             my ($priv) = split(/\&/,$item,2);  
                                             if (&Apache::lonnet::plaintext($priv)) {  
                                                 $resulttext .= '<li>'.&Apache::lonnet::plaintext($priv);  
                                                 unless ($level eq 'c') {  
                                                     $resulttext .= ' ('.$lt{$level}.')';  
                                                 }  
                                                 $resulttext .= '</li>';  
                                             }  
                                         }  
                                     }  
                                     $resulttext .= '</ul>';  
                                 }  
                                 $resulttext .= '</ul></li>';  
                             }  
                         }  
                     }  
                 }  
             }  
         }  
         if (keys(%changedprivs)) {  
             foreach my $role (sort(keys(%changedprivs))) {  
                 unless ($shownprivs{$role}) {  
                     $resulttext .= '<li>'.&mt('Existing custom role modified: [_1]',  
                                               $role).'<ul>'.  
                                    '<li>'.&mt('Privileges set to :').'<ul>';  
                     foreach my $level (@levelorder) {  
                         foreach my $item (split(/\:/,$changedprivs{$role}{$level})) {  
                             next if ($item eq '');  
                             my ($priv) = split(/\&/,$item,2);  
                             if (&Apache::lonnet::plaintext($priv)) {  
                                 $resulttext .= '<li>'.&Apache::lonnet::plaintext($priv);  
                                 unless ($level eq 'c') {  
                                     $resulttext .= ' ('.$lt{$level}.')';  
                                 }  
                                 $resulttext .= '</li>';  
                             }  
                         }  
                     }  
                     $resulttext .= '</ul></li></ul></li>';  
                 }                  }
             }              }
               $resulttext .= '</ul>';
           } else {
               $resulttext = &mt('No changes made to help settings');
               $errors .= '<li><span class="LC_error">'.
                          &mt('An error occurred storing the settings: [_1]',
                              $putresult).'</span></li>';
         }          }
         $resulttext .= '</ul>';  
     } else {  
         $resulttext = &mt('No changes made to help settings');  
     }      }
     if ($errors) {      if ($errors) {
         $resulttext .= '<br />'.&mt('The following errors occurred: ').'<ul>'.          $resulttext .= '<br />'.&mt('The following errors occurred: ').'<ul>'.
                                     $errors.'</ul>';                         $errors.'</ul>';
     }      }
     return $resulttext;      return $resulttext;
 }  }
Line 13012  sub modify_coursedefaults { Line 11745  sub modify_coursedefaults {
     my ($dom,$lastactref,%domconfig) = @_;      my ($dom,$lastactref,%domconfig) = @_;
     my ($resulttext,$errors,%changes,%defaultshash);      my ($resulttext,$errors,%changes,%defaultshash);
     my %defaultchecked = (      my %defaultchecked = (
                              'canuse_pdfforms' => 'off',
                            'uselcmath'       => 'on',                             'uselcmath'       => 'on',
                            'usejsme'         => 'on'                             'usejsme'         => 'on'
                          );                           );
     my @toggles = ('uselcmath','usejsme');      my @toggles = ('canuse_pdfforms','uselcmath','usejsme');
     my @numbers = ('anonsurvey_threshold','uploadquota_official','uploadquota_unofficial',      my @numbers = ('anonsurvey_threshold','uploadquota_official','uploadquota_unofficial',
                    'uploadquota_community','uploadquota_textbook','mysqltables_official',                     'uploadquota_community','uploadquota_textbook','uploadquota_placement',
                    'mysqltables_unofficial','mysqltables_community','mysqltables_textbook');                     'mysqltables_official','mysqltables_unofficial','mysqltables_community',
     my @types = ('official','unofficial','community','textbook');                     'mysqltables_textbook','mysqltables_placement');
       my @types = ('official','unofficial','community','textbook','placement');
     my %staticdefaults = (      my %staticdefaults = (
                            anonsurvey_threshold => 10,                             anonsurvey_threshold => 10,
                            uploadquota          => 500,                             uploadquota          => 500,
Line 13079  sub modify_coursedefaults { Line 11814  sub modify_coursedefaults {
                         $changes{$item} = 1;                          $changes{$item} = 1;
                     }                      }
                 } elsif ($item =~ /^(uploadquota|mysqltables)_/) {                  } elsif ($item =~ /^(uploadquota|mysqltables)_/) {
                     my $setting = $1;                      my $setting = $1; 
                     unless (($currdef eq '') && ($newdef == $staticdefaults{$setting})) {                      unless (($currdef eq '') && ($newdef == $staticdefaults{$setting})) {
                         $changes{$setting} = 1;                          $changes{$setting} = 1;
                     }                      }
Line 13094  sub modify_coursedefaults { Line 11829  sub modify_coursedefaults {
             }              }
         }          }
         my $newclone;          my $newclone;
         if ($env{'form.canclone'} =~ /^(none|domain|instcode)$/) {          if ($env{'form.canclone'} =~ /^(none|domain|instcode)$/) { 
             $newclone = $env{'form.canclone'};              $newclone = $env{'form.canclone'};
         }          }
         if ($newclone eq 'instcode') {          if ($newclone eq 'instcode') {
Line 13117  sub modify_coursedefaults { Line 11852  sub modify_coursedefaults {
                 $newclone eq '';                  $newclone eq '';
             }              }
         } elsif ($newclone ne '') {          } elsif ($newclone ne '') {
             $defaultshash{'coursedefaults'}{'canclone'} = $newclone;              $defaultshash{'coursedefaults'}{'canclone'} = $newclone; 
         }          } 
         if ($newclone ne $currclone) {          if ($newclone ne $currclone) {
             $changes{'canclone'} = 1;              $changes{'canclone'} = 1;
         }          }
Line 13136  sub modify_coursedefaults { Line 11871  sub modify_coursedefaults {
                 $defaultshash{'coursedefaults'}{'coursecredits'}{$type} = $credits{$type};                  $defaultshash{'coursedefaults'}{'coursecredits'}{$type} = $credits{$type};
             }              }
         } else {          } else {
             if ($env{'form.coursecredits'} eq '1') {              if ($env{'form.coursecredits'} eq '1') { 
                 foreach my $type (@types) {                  foreach my $type (@types) {
                     unless ($type eq 'community') {                      unless ($type eq 'community') {
                         if ($domconfig{'coursedefaults'}{'coursecredits'}{$type} ne $credits{$type}) {                          if ($domconfig{'coursedefaults'}{'coursecredits'}{$type} ne $credits{$type}) {        
                             $changes{'coursecredits'} = 1;                              $changes{'coursecredits'} = 1;
                         }                          }
                         $defaultshash{'coursedefaults'}{'coursecredits'}{$type} = $credits{$type};                          $defaultshash{'coursedefaults'}{'coursecredits'}{$type} = $credits{$type};
Line 13182  sub modify_coursedefaults { Line 11917  sub modify_coursedefaults {
                 }                  }
                 if (exists($currtimeout{$type})) {                  if (exists($currtimeout{$type})) {
                     if ($timeout ne $currtimeout{$type}) {                      if ($timeout ne $currtimeout{$type}) {
                         $changes{'postsubmit'} = 1;                          $changes{'postsubmit'} = 1; 
                     }                      }
                 } elsif ($timeout ne '') {                  } elsif ($timeout ne '') {
                     $changes{'postsubmit'} = 1;                      $changes{'postsubmit'} = 1;
Line 13204  sub modify_coursedefaults { Line 11939  sub modify_coursedefaults {
     if ($putresult eq 'ok') {      if ($putresult eq 'ok') {
         if (keys(%changes) > 0) {          if (keys(%changes) > 0) {
             my %domdefaults = &Apache::lonnet::get_domain_defaults($dom,1);              my %domdefaults = &Apache::lonnet::get_domain_defaults($dom,1);
             if (($changes{'uploadquota'}) || ($changes{'postsubmit'}) ||              if (($changes{'canuse_pdfforms'}) || ($changes{'uploadquota'}) || ($changes{'postsubmit'}) ||
                 ($changes{'coursecredits'}) || ($changes{'uselcmath'}) || ($changes{'usejsme'}) ||                  ($changes{'coursecredits'}) || ($changes{'uselcmath'}) || ($changes{'usejsme'}) ||
                 ($changes{'canclone'}) || ($changes{'mysqltables'})) {                  ($changes{'canclone'}) || ($changes{'mysqltables'})) {
                 foreach my $item ('uselcmath','usejsme') {                  foreach my $item ('canuse_pdfforms','uselcmath','usejsme') { 
                     if ($changes{$item}) {                      if ($changes{$item}) {
                         $domdefaults{$item}=$defaultshash{'coursedefaults'}{$item};                          $domdefaults{$item}=$defaultshash{'coursedefaults'}{$item};
                     }                      }
                 }                  } 
                 if ($changes{'coursecredits'}) {                  if ($changes{'coursecredits'}) {
                     if (ref($defaultshash{'coursedefaults'}{'coursecredits'}) eq 'HASH') {                      if (ref($defaultshash{'coursedefaults'}{'coursecredits'}) eq 'HASH') {
                         foreach my $type (keys(%{$defaultshash{'coursedefaults'}{'coursecredits'}})) {                          foreach my $type (keys(%{$defaultshash{'coursedefaults'}{'coursecredits'}})) {
Line 13258  sub modify_coursedefaults { Line 11993  sub modify_coursedefaults {
             }              }
             $resulttext = &mt('Changes made:').'<ul>';              $resulttext = &mt('Changes made:').'<ul>';
             foreach my $item (sort(keys(%changes))) {              foreach my $item (sort(keys(%changes))) {
                 if ($item eq 'uselcmath') {                  if ($item eq 'canuse_pdfforms') {
                       if ($env{'form.'.$item} eq '1') {
                           $resulttext .= '<li>'.&mt("Course/Community users can create/upload PDF forms set to 'on'").'</li>';
                       } else {
                           $resulttext .= '<li>'.&mt('Course/Community users can create/upload PDF forms set to "off"').'</li>';
                       }
                   } elsif ($item eq 'uselcmath') {
                     if ($env{'form.'.$item} eq '1') {                      if ($env{'form.'.$item} eq '1') {
                         $resulttext .= '<li>'.&mt('Math preview uses LON-CAPA previewer (javascript), if supported by browser.').'</li>';                          $resulttext .= '<li>'.&mt('Math preview uses LON-CAPA previewer (javascript), if supported by browser.').'</li>';
                     } else {                      } else {
Line 13268  sub modify_coursedefaults { Line 12009  sub modify_coursedefaults {
                     if ($env{'form.'.$item} eq '1') {                      if ($env{'form.'.$item} eq '1') {
                         $resulttext .= '<li>'.&mt('Molecule editor uses JSME (HTML5), if supported by browser.').'</li>';                          $resulttext .= '<li>'.&mt('Molecule editor uses JSME (HTML5), if supported by browser.').'</li>';
                     } else {                      } else {
                         $resulttext .= '<li>'.&mt('Molecule editor uses JME (Java), if supported by client OS.').'</li>';                          $resulttext .= '<li>'.&mt('Molecule editor uses JME (Java), if supported by client OS.').'</li>'; 
                     }                      }
                 } elsif ($item eq 'anonsurvey_threshold') {                  } elsif ($item eq 'anonsurvey_threshold') {
                     $resulttext .= '<li>'.&mt('Responder count required for display of anonymous survey submissions set to [_1].',$defaultshash{'coursedefaults'}{'anonsurvey_threshold'}).'</li>';                      $resulttext .= '<li>'.&mt('Responder count required for display of anonymous survey submissions set to [_1].',$defaultshash{'coursedefaults'}{'anonsurvey_threshold'}).'</li>';
Line 13278  sub modify_coursedefaults { Line 12019  sub modify_coursedefaults {
                                        '<li>'.&mt('Official courses: [_1] MB','<b>'.$defaultshash{'coursedefaults'}{'uploadquota'}{'official'}.'</b>').'</li>'.                                         '<li>'.&mt('Official courses: [_1] MB','<b>'.$defaultshash{'coursedefaults'}{'uploadquota'}{'official'}.'</b>').'</li>'.
                                        '<li>'.&mt('Unofficial courses: [_1] MB','<b>'.$defaultshash{'coursedefaults'}{'uploadquota'}{'unofficial'}.'</b>').'</li>'.                                         '<li>'.&mt('Unofficial courses: [_1] MB','<b>'.$defaultshash{'coursedefaults'}{'uploadquota'}{'unofficial'}.'</b>').'</li>'.
                                        '<li>'.&mt('Textbook courses: [_1] MB','<b>'.$defaultshash{'coursedefaults'}{'uploadquota'}{'textbook'}.'</b>').'</li>'.                                         '<li>'.&mt('Textbook courses: [_1] MB','<b>'.$defaultshash{'coursedefaults'}{'uploadquota'}{'textbook'}.'</b>').'</li>'.
                                          '<li>'.&mt('Placement tests: [_1] MB','<b>'.$defaultshash{'coursedefaults'}{'uploadquota'}{'placement'}.'</b>').'</li>'. 
                                        '<li>'.&mt('Communities: [_1] MB','<b>'.$defaultshash{'coursedefaults'}{'uploadquota'}{'community'}.'</b>').'</li>'.                                         '<li>'.&mt('Communities: [_1] MB','<b>'.$defaultshash{'coursedefaults'}{'uploadquota'}{'community'}.'</b>').'</li>'.
                                        '</ul>'.                                         '</ul>'.
                                        '</li>';                                         '</li>';
Line 13291  sub modify_coursedefaults { Line 12032  sub modify_coursedefaults {
                                        '<li>'.&mt('Official courses: [_1] s','<b>'.$defaultshash{'coursedefaults'}{'mysqltables'}{'official'}.'</b>').'</li>'.                                         '<li>'.&mt('Official courses: [_1] s','<b>'.$defaultshash{'coursedefaults'}{'mysqltables'}{'official'}.'</b>').'</li>'.
                                        '<li>'.&mt('Unofficial courses: [_1] s','<b>'.$defaultshash{'coursedefaults'}{'mysqltables'}{'unofficial'}.'</b>').'</li>'.                                         '<li>'.&mt('Unofficial courses: [_1] s','<b>'.$defaultshash{'coursedefaults'}{'mysqltables'}{'unofficial'}.'</b>').'</li>'.
                                        '<li>'.&mt('Textbook courses: [_1] s','<b>'.$defaultshash{'coursedefaults'}{'mysqltables'}{'textbook'}.'</b>').'</li>'.                                         '<li>'.&mt('Textbook courses: [_1] s','<b>'.$defaultshash{'coursedefaults'}{'mysqltables'}{'textbook'}.'</b>').'</li>'.
                                          '<li>'.&mt('Placement tests: [_1] s','<b>'.$defaultshash{'coursedefaults'}{'mysqltables'}{'placement'}.'</b>').'</li>'.
                                        '<li>'.&mt('Communities: [_1] s','<b>'.$defaultshash{'coursedefaults'}{'mysqltables'}{'community'}.'</b>').'</li>'.                                         '<li>'.&mt('Communities: [_1] s','<b>'.$defaultshash{'coursedefaults'}{'mysqltables'}{'community'}.'</b>').'</li>'.
                                        '</ul>'.                                         '</ul>'.
                                        '</li>';                                         '</li>';
Line 13302  sub modify_coursedefaults { Line 12044  sub modify_coursedefaults {
                         $resulttext .= '<li>'.&mt('Submit button(s) remain enabled on page after student makes submission.');                          $resulttext .= '<li>'.&mt('Submit button(s) remain enabled on page after student makes submission.');
                     } else {                      } else {
                         $resulttext .= '<li>'.&mt('Submit button(s) disabled on page after student makes submission').'; ';                          $resulttext .= '<li>'.&mt('Submit button(s) disabled on page after student makes submission').'; ';
                         if (ref($defaultshash{'coursedefaults'}{'postsubmit'}) eq 'HASH') {                          if (ref($defaultshash{'coursedefaults'}{'postsubmit'}) eq 'HASH') { 
                             $resulttext .= &mt('durations:').'<ul>';                              $resulttext .= &mt('durations:').'<ul>';
                             foreach my $type (@types) {                              foreach my $type (@types) {
                                 $resulttext .= '<li>';                                  $resulttext .= '<li>';
Line 13326  sub modify_coursedefaults { Line 12068  sub modify_coursedefaults {
                                     $resulttext .= &mt('Unofficial courses');                                      $resulttext .= &mt('Unofficial courses');
                                 } elsif ($type eq 'textbook') {                                  } elsif ($type eq 'textbook') {
                                     $resulttext .= &mt('Textbook courses');                                      $resulttext .= &mt('Textbook courses');
                                   } elsif ($type eq 'placement') {
                                       $resulttext .= &mt('Placement tests');
                                 }                                  }
                                 $resulttext .= ' -- '.$display.'</li>';                                  $resulttext .= ' -- '.$display.'</li>';
                             }                              }
                             $resulttext .= '</ul>';                              $resulttext .= '</ul>';
                         }                          }
                         $resulttext .= '</li>';                          $resulttext .= '</li>';    
                     }                      }
                 } elsif ($item eq 'coursecredits') {                  } elsif ($item eq 'coursecredits') {
                     if (ref($defaultshash{'coursedefaults'}{'coursecredits'}) eq 'HASH') {                      if (ref($defaultshash{'coursedefaults'}{'coursecredits'}) eq 'HASH') {
Line 13359  sub modify_coursedefaults { Line 12103  sub modify_coursedefaults {
                     } elsif ($defaultshash{'coursedefaults'}{'canclone'} eq 'domain') {                      } elsif ($defaultshash{'coursedefaults'}{'canclone'} eq 'domain') {
                         $resulttext .= '<li>'.&mt('By default, a course requester can clone any course from his/her domain.').'</li>';                          $resulttext .= '<li>'.&mt('By default, a course requester can clone any course from his/her domain.').'</li>';
                     } else {                      } else {
                         $resulttext .= '<li>'.&mt('By default, only course owner and coordinators may clone a course.').'</li>';                          $resulttext .= '<li>'.&mt('By default, only course owner and coordinators may clone a course.').'</li>'; 
                     }                      }
                 }                  }
             }              }
Line 13377  sub modify_coursedefaults { Line 12121  sub modify_coursedefaults {
 sub modify_selfenrollment {  sub modify_selfenrollment {
     my ($dom,$lastactref,%domconfig) = @_;      my ($dom,$lastactref,%domconfig) = @_;
     my ($resulttext,$errors,%changes,%selfenrollhash,%ordered);      my ($resulttext,$errors,%changes,%selfenrollhash,%ordered);
     my @types = ('official','unofficial','community','textbook');      my @types = ('official','unofficial','community','textbook','placement');
     my %titles = &tool_titles();      my %titles = &tool_titles();
     my %descs = &Apache::lonuserutils::selfenroll_default_descs();      my %descs = &Apache::lonuserutils::selfenroll_default_descs();
     ($ordered{'admin'},my $titlesref) = &Apache::lonuserutils::get_selfenroll_titles();      ($ordered{'admin'},my $titlesref) = &Apache::lonuserutils::get_selfenroll_titles();
Line 13624  sub modify_usersessions { Line 12368  sub modify_usersessions {
                 );                  );
     my @prefixes = ('remote','hosted','spares');      my @prefixes = ('remote','hosted','spares');
     my @lcversions = &Apache::lonnet::all_loncaparevs();      my @lcversions = &Apache::lonnet::all_loncaparevs();
     my (%by_ip,%by_location,@intdoms);      my (%by_ip,%by_location,@intdoms,@instdoms);
     &build_location_hashes(\@intdoms,\%by_ip,\%by_location);      &build_location_hashes(\@intdoms,\%by_ip,\%by_location,\@instdoms);
     my @locations = sort(keys(%by_location));      my @locations = sort(keys(%by_location));
     my (%defaultshash,%changes);      my (%defaultshash,%changes);
     foreach my $prefix (@prefixes) {      foreach my $prefix (@prefixes) {
Line 13814  sub modify_usersessions { Line 12558  sub modify_usersessions {
                 }                  }
             }              }
             unless ($changes{'offloadnow'}) {              unless ($changes{'offloadnow'}) {
                 foreach my $lonhost (keys(%{$defaultshash{'usersessions'}{'offloadnow'}})) {                  foreach my $lonhost (keys(%{$defaultshash{'usersessions'}{'offloadnow'}})) { 
                     unless ($domconfig{'usersessions'}{'offloadnow'}{$lonhost}) {                      unless ($domconfig{'usersessions'}{'offloadnow'}{$lonhost}) {
                         $changes{'offloadnow'} = 1;                          $changes{'offloadnow'} = 1;
                         last;                          last;
Line 13845  sub modify_usersessions { Line 12589  sub modify_usersessions {
             }              }
             my $cachetime = 24*60*60;              my $cachetime = 24*60*60;
             &Apache::lonnet::do_cache_new('domdefaults',$dom,\%domdefaults,$cachetime);              &Apache::lonnet::do_cache_new('domdefaults',$dom,\%domdefaults,$cachetime);
             &Apache::lonnet::do_cache_new('usersessions',$dom,$defaultshash{'usersessions'},3600);  
             if (ref($lastactref) eq 'HASH') {              if (ref($lastactref) eq 'HASH') {
                 $lastactref->{'domdefaults'} = 1;                  $lastactref->{'domdefaults'} = 1;
                 $lastactref->{'usersessions'} = 1;  
             }              }
             if (keys(%changes) > 0) {              if (keys(%changes) > 0) {
                 my %lt = &usersession_titles();                  my %lt = &usersession_titles();
Line 13941  sub modify_usersessions { Line 12683  sub modify_usersessions {
     return $resulttext;      return $resulttext;
 }  }
   
   sub modify_ssl {
       my ($dom,$lastactref,%domconfig) = @_;
       my (%by_ip,%by_location,@intdoms,@instdoms);
       &build_location_hashes(\@intdoms,\%by_ip,\%by_location,\@instdoms);
       my @locations = sort(keys(%by_location));
       my %servers = &Apache::lonnet::internet_dom_servers($dom);
       my (%defaultshash,%changes);
       my $action = 'ssl';
       my @prefixes = ('connect','replication');
       foreach my $prefix (@prefixes) {
           $defaultshash{$action}{$prefix} = {};
       }
       my %domdefaults = &Apache::lonnet::get_domain_defaults($dom,1);
       my $resulttext;
       my %iphost = &Apache::lonnet::get_iphost();
       my @reptypes = ('certreq','nocertreq');
       my @connecttypes = ('dom','intdom','other');
       my %types = (
                     connect      => \@connecttypes,
                     replication  => \@reptypes,
                   );
       foreach my $prefix (sort(keys(%types))) {
           foreach my $type (@{$types{$prefix}}) {
               if ($prefix eq 'connect') {
                   my $value = 'yes';
                   if ($env{'form.'.$prefix.'_'.$type} =~ /^(no|req)$/) {
                       $value = $env{'form.'.$prefix.'_'.$type};
                   }
                   if (ref($domconfig{$action}{$prefix}) eq 'HASH') {
                       if ($domconfig{$action}{$prefix}{$type} ne '') {
                           if ($value ne $domconfig{$action}{$prefix}{$type}) {
                               $changes{$prefix}{$type} = 1;
                           }
                           $defaultshash{$action}{$prefix}{$type} = $value;
                       } else {
                           $defaultshash{$action}{$prefix}{$type} = $value;
                           $changes{$prefix}{$type} = 1;
                       }
                   } else {
                       $defaultshash{$action}{$prefix}{$type} = $value;
                       $changes{$prefix}{$type} = 1;
                   }
                   if (($type eq 'dom') && (keys(%servers) == 1)) {
                       delete($changes{$prefix}{$type});
                   } elsif (($type eq 'intdom') && (@instdoms == 1)) {
                       delete($changes{$prefix}{$type});
                   } elsif (($type eq 'other') && (keys(%by_location) == 0)) { 
                       delete($changes{$prefix}{$type});
                   }
               } elsif ($prefix eq 'replication') {
                   if (@locations > 0) {
                       my $inuse = $env{'form.'.$prefix.'_'.$type.'_inuse'};
                       my @vals = &Apache::loncommon::get_env_multiple('form.'.$prefix.'_'.$type);
                       my @okvals;
                       foreach my $val (@vals) {
                           if ($val =~ /:/) {
                               my @items = split(/:/,$val);
                               foreach my $item (@items) {
                                   if (ref($by_location{$item}) eq 'ARRAY') {
                                       push(@okvals,$item);
                                   }
                               }
                           } else {
                               if (ref($by_location{$val}) eq 'ARRAY') {
                                   push(@okvals,$val);
                               }
                           }
                       }
                       @okvals = sort(@okvals);
                       if (ref($domconfig{$action}) eq 'HASH') {
                           if (ref($domconfig{$action}{$prefix}) eq 'HASH') {
                               if (ref($domconfig{$action}{$prefix}{$type}) eq 'ARRAY') {
                                   if ($inuse == 0) {
                                       $changes{$prefix}{$type} = 1;
                                   } else {
                                       $defaultshash{$action}{$prefix}{$type} = \@okvals;
                                       my @changed = &Apache::loncommon::compare_arrays($domconfig{$action}{$prefix}{$type},$defaultshash{$action}{$prefix}{$type});
                                       if (@changed > 0) {
                                           $changes{$prefix}{$type} = 1;
                                       }
                                   }
                               } else {
                                   if ($inuse == 1) {
                                       $defaultshash{$action}{$prefix}{$type} = \@okvals;
                                       $changes{$prefix}{$type} = 1;
                                   }
                               }
                           } else {
                               if ($inuse == 1) {
                                   $defaultshash{$action}{$prefix}{$type} = \@okvals;
                                   $changes{$prefix}{$type} = 1;
                               }
                           }
                       } else {
                           if ($inuse == 1) {
                               $defaultshash{$action}{$prefix}{$type} = \@okvals;
                               $changes{$prefix}{$type} = 1;
                           }
                       }
                   }
               }
           }
       }
       my $nochgmsg = &mt('No changes made to LON-CAPA SSL settings');
       if (keys(%changes) > 0) {
           my $putresult = &Apache::lonnet::put_dom('configuration',\%defaultshash,
                                                    $dom);
           if ($putresult eq 'ok') {
               if (ref($defaultshash{$action}) eq 'HASH') {
                   if (ref($defaultshash{$action}{'replication'}) eq 'HASH') {
                       $domdefaults{'replication'} = $defaultshash{$action}{'replication'};
                   }
                   if (ref($defaultshash{$action}{'connect'}) eq 'HASH') {
                       $domdefaults{'connect'} = $domconfig{$action}{'connect'};
                   }
               }
               my $cachetime = 24*60*60;
               &Apache::lonnet::do_cache_new('domdefaults',$dom,\%domdefaults,$cachetime);
               if (ref($lastactref) eq 'HASH') {
                   $lastactref->{'domdefaults'} = 1;
               }
               if (keys(%changes) > 0) {
                   my %titles = &ssl_titles();
                   $resulttext = &mt('Changes made:').'<ul>';
                   foreach my $prefix (@prefixes) {
                       if (ref($changes{$prefix}) eq 'HASH') {
                           $resulttext .= '<li>'.$titles{$prefix}.'<ul>';
                           foreach my $type (@{$types{$prefix}}) {
                               if (defined($changes{$prefix}{$type})) {
                                   my $newvalue;
                                   if (ref($defaultshash{$action}) eq 'HASH') {
                                       if (ref($defaultshash{$action}{$prefix})) {
                                           if ($prefix eq 'connect') {
                                               $newvalue = $titles{$defaultshash{$action}{$prefix}{$type}};
                                           } elsif (ref($defaultshash{$action}{$prefix}{$type}) eq 'ARRAY') {
                                               if (@{$defaultshash{$action}{$prefix}{$type}} > 0) {
                                                   $newvalue = join(', ',@{$defaultshash{$action}{$prefix}{$type}});
                                               }
                                           }
                                       }
                                       if ($newvalue eq '') {
                                           $resulttext .= '<li>'.&mt('[_1] set to: none',$titles{$type}).'</li>';
                                       } else {
                                           $resulttext .= '<li>'.&mt('[_1] set to: [_2].',$titles{$type},$newvalue).'</li>';
                                       }
                                   }
                               }
                           }
                           $resulttext .= '</ul>';
                       }
                   }
               } else {
                   $resulttext = $nochgmsg;
               }
           } else {
               $resulttext = '<span class="LC_error">'.
                             &mt('An error occurred: [_1]',$putresult).'</span>';
           }
       } else {
           $resulttext = $nochgmsg;
       }
       return $resulttext;
   }
   
   sub modify_trust {
       my ($dom,$lastactref,%domconfig) = @_;
       my (%by_ip,%by_location,@intdoms,@instdoms);
       &build_location_hashes(\@intdoms,\%by_ip,\%by_location,\@instdoms);
       my @locations = sort(keys(%by_location));
       my @prefixes = qw(content shared enroll othcoau coaurem domroles catalog reqcrs msg);
       my @types = ('exc','inc');
       my (%defaultshash,%changes);
       foreach my $prefix (@prefixes) {
           $defaultshash{'trust'}{$prefix} = {};
       }
       my %domdefaults = &Apache::lonnet::get_domain_defaults($dom,1);
       my $resulttext;
       foreach my $prefix (@prefixes) {
           foreach my $type (@types) {
               my $inuse = $env{'form.'.$prefix.'_'.$type.'_inuse'};
               my @vals = &Apache::loncommon::get_env_multiple('form.'.$prefix.'_'.$type);
               my @okvals;
               foreach my $val (@vals) {
                   if ($val =~ /:/) {
                       my @items = split(/:/,$val);
                       foreach my $item (@items) {
                           if (ref($by_location{$item}) eq 'ARRAY') {
                               push(@okvals,$item);
                           }
                       }
                   } else {
                       if (ref($by_location{$val}) eq 'ARRAY') {
                           push(@okvals,$val);
                       }
                   }
               }
               @okvals = sort(@okvals);
               if (ref($domconfig{'trust'}) eq 'HASH') {
                   if (ref($domconfig{'trust'}{$prefix}) eq 'HASH') {
                       if (ref($domconfig{'trust'}{$prefix}{$type}) eq 'ARRAY') {
                           if ($inuse == 0) {
                               $changes{$prefix}{$type} = 1;
                           } else {
                               $defaultshash{'trust'}{$prefix}{$type} = \@okvals;
                               my @changed = &Apache::loncommon::compare_arrays($domconfig{'trust'}{$prefix}{$type},$defaultshash{'trust'}{$prefix}{$type});
                               if (@changed > 0) {
                                   $changes{$prefix}{$type} = 1;
                               }
                           }
                       } else {
                           if ($inuse == 1) {
                               $defaultshash{'trust'}{$prefix}{$type} = \@okvals;
                               $changes{$prefix}{$type} = 1;
                           }
                       }
                   } else {
                       if ($inuse == 1) {
                           $defaultshash{'trust'}{$prefix}{$type} = \@okvals;
                           $changes{$prefix}{$type} = 1;
                       }
                   }
               } else {
                   if ($inuse == 1) {
                       $defaultshash{'trust'}{$prefix}{$type} = \@okvals;
                       $changes{$prefix}{$type} = 1;
                   }
               }
           }
       }
       my $nochgmsg = &mt('No changes made to trust settings.');
       if (keys(%changes) > 0) {
           my $putresult = &Apache::lonnet::put_dom('configuration',\%defaultshash,
                                                    $dom);
           if ($putresult eq 'ok') {
               if (ref($defaultshash{'trust'}) eq 'HASH') {
                   foreach my $prefix (@prefixes) {
                       if (ref($defaultshash{'trust'}{$prefix}) eq 'HASH') {
                           $domdefaults{'trust'.$prefix} = $defaultshash{'trust'}{$prefix};
                       }
                   }
               }
               my $cachetime = 24*60*60;
               &Apache::lonnet::do_cache_new('domdefaults',$dom,\%domdefaults,$cachetime);
               if (ref($lastactref) eq 'HASH') {
                   $lastactref->{'domdefaults'} = 1;
               }
               if (keys(%changes) > 0) {
                   my %lt = &trust_titles();
                   $resulttext = &mt('Changes made:').'<ul>';
                   foreach my $prefix (@prefixes) {
                       if (ref($changes{$prefix}) eq 'HASH') {
                           $resulttext .= '<li>'.$lt{$prefix}.'<ul>';
                           foreach my $type (@types) {
                               if (defined($changes{$prefix}{$type})) {
                                   my $newvalue;
                                   if (ref($defaultshash{'trust'}) eq 'HASH') {
                                       if (ref($defaultshash{'trust'}{$prefix})) {
                                           if (ref($defaultshash{'trust'}{$prefix}{$type}) eq 'ARRAY') {
                                               if (@{$defaultshash{'trust'}{$prefix}{$type}} > 0) {
                                                   $newvalue = join(', ',@{$defaultshash{'trust'}{$prefix}{$type}});
                                               }
                                           }
                                       }
                                   }
                                   if ($newvalue eq '') {
                                       $resulttext .= '<li>'.&mt('[_1] set to: none',$lt{$type}).'</li>';
                                   } else {
                                       $resulttext .= '<li>'.&mt('[_1] set to: [_2].',$lt{$type},$newvalue).'</li>';
                                   }
                               }
                           }
                           $resulttext .= '</ul>';
                       }
                   }
                   $resulttext .= '</ul>';
               } else {
                   $resulttext = $nochgmsg;
               }
           } else {
               $resulttext = '<span class="LC_error">'.
                             &mt('An error occurred: [_1]',$putresult).'</span>';
           }
       } else {
           $resulttext = $nochgmsg;
       }
       return $resulttext;
   }
   
 sub modify_loadbalancing {  sub modify_loadbalancing {
     my ($dom,%domconfig) = @_;      my ($dom,%domconfig) = @_;
     my $primary_id = &Apache::lonnet::domain($dom,'primary');      my $primary_id = &Apache::lonnet::domain($dom,'primary');
Line 14001  sub modify_loadbalancing { Line 13031  sub modify_loadbalancing {
                         push(@offloadto,$target);                          push(@offloadto,$target);
                     }                      }
                 }                  }
                   $defaultshash{'loadbalancing'}{$balancer}{'targets'}{$sparetype} = \@offloadto;
             }              }
             if ($env{'form.loadbalancing_target_'.$i.'_hosthere'} eq $sparetype) {  
                 unless(grep(/^\Q$balancer\E$/,@offloadto)) {  
                     push(@offloadto,$balancer);  
                 }  
             }  
             $defaultshash{'loadbalancing'}{$balancer}{'targets'}{$sparetype} = \@offloadto;  
         }          }
         if (ref($currtargets{$balancer}) eq 'HASH') {          if (ref($currtargets{$balancer}) eq 'HASH') {
             foreach my $sparetype (@sparestypes) {              foreach my $sparetype (@sparestypes) {
Line 14046  sub modify_loadbalancing { Line 13071  sub modify_loadbalancing {
                 }                  }
                 if ($rule eq 'specific') {                  if ($rule eq 'specific') {
                     my $specifiedhost = $env{'form.loadbalancing_singleserver_'.$i.'_'.$type};                      my $specifiedhost = $env{'form.loadbalancing_singleserver_'.$i.'_'.$type};
                     if (exists($servers{$specifiedhost})) {                      if (exists($servers{$specifiedhost})) { 
                         $rule = $specifiedhost;                          $rule = $specifiedhost;
                     }                      }
                 }                  }
Line 14122  sub modify_loadbalancing { Line 13147  sub modify_loadbalancing {
                                         if ($rule eq '') {                                          if ($rule eq '') {
                                             $balancetext =  $ruletitles{'default'};                                              $balancetext =  $ruletitles{'default'};
                                         } elsif (($rule eq 'homeserver') || ($rule eq 'externalbalancer') ||                                          } elsif (($rule eq 'homeserver') || ($rule eq 'externalbalancer') ||
                                                  ($type eq '_LC_ipchange') || ($type eq '_LC_ipchangesso')) {                                                   ($type eq '_LC_ipchange') || ($type eq '_LC_ipchangesso')) { 
                                             if (($type eq '_LC_ipchange') || ($type eq '_LC_ipchangesso')) {                                              if (($type eq '_LC_ipchange') || ($type eq '_LC_ipchangesso')) {
                                                 foreach my $sparetype (@sparestypes) {                                                  foreach my $sparetype (@sparestypes) {
                                                     if (ref($defaultshash{'loadbalancing'}{$balancer}{'targets'}{$sparetype}) eq 'ARRAY') {                                                      if (ref($defaultshash{'loadbalancing'}{$balancer}{'targets'}{$sparetype}) eq 'ARRAY') {
Line 14241  sub recurse_cat_deletes { Line 13266  sub recurse_cat_deletes {
     return;      return;
 }  }
   
   sub get_active_dcs {
       my ($dom) = @_;
       my $now = time;
       my %dompersonnel = &Apache::lonnet::get_domain_roles($dom,['dc'],$now,$now);
       my %domcoords;
       my $numdcs = 0;
       foreach my $server (keys(%dompersonnel)) {
           foreach my $user (sort(keys(%{$dompersonnel{$server}}))) {
               my ($trole,$uname,$udom,$runame,$rudom,$rsec) = split(/:/,$user);
               $domcoords{$uname.':'.$udom} = $dompersonnel{$server}{$user};
           }
       }
       return %domcoords;
   }
   
 sub active_dc_picker {  sub active_dc_picker {
     my ($dom,$numinrow,$inputtype,$name,%currhash) = @_;      my ($dom,$numinrow,$inputtype,$name,%currhash) = @_;
     my %domcoords = &Apache::lonnet::get_active_domroles($dom,['dc']);      my %domcoords = &get_active_dcs($dom);
     my @domcoord = keys(%domcoords);      my @domcoord = keys(%domcoords);
     if (keys(%currhash)) {      if (keys(%currhash)) {
         foreach my $dc (keys(%currhash)) {          foreach my $dc (keys(%currhash)) {
Line 14849  function updateCaptcha(caller,context) { Line 13889  function updateCaptcha(caller,context) {
             privtext.innerHTML = "$lt{'priv'}";              privtext.innerHTML = "$lt{'priv'}";
             versionitem.type = 'text';              versionitem.type = 'text';
             versionitem.size = '3';              versionitem.size = '3';
             versiontext.innerHTML = "$lt{'ver'}";              versiontext.innerHTML = "$lt{'ver'}"; 
         } else {          } else {
             pubitem.type = 'hidden';              pubitem.type = 'hidden';
             privitem.type = 'hidden';              privitem.type = 'hidden';
Line 14922  sub captcha_phrases { Line 13962  sub captcha_phrases {
                  original  => 'original (CAPTCHA)',                   original  => 'original (CAPTCHA)',
                  recaptcha => 'successor (ReCAPTCHA)',                   recaptcha => 'successor (ReCAPTCHA)',
                  notused   => 'unused',                   notused   => 'unused',
                  ver => 'ReCAPTCHA version (1 or 2)',                   ver => 'ReCAPTCHA version (1 or 2)', 
     );      );
 }  }
   
Line 14932  sub devalidate_remote_domconfs { Line 13972  sub devalidate_remote_domconfs {
     my %servers = &Apache::lonnet::internet_dom_servers($dom);      my %servers = &Apache::lonnet::internet_dom_servers($dom);
     my %thismachine;      my %thismachine;
     map { $thismachine{$_} = 1; } &Apache::lonnet::current_machine_ids();      map { $thismachine{$_} = 1; } &Apache::lonnet::current_machine_ids();
     my @posscached = ('domainconfig','domdefaults','ltitools','usersessions','directorysrch');      my @posscached = ('domainconfig','domdefaults','ltitools');
     if (keys(%servers)) {      if (keys(%servers)) {
         foreach my $server (keys(%servers)) {          foreach my $server (keys(%servers)) {
             next if ($thismachine{$server});              next if ($thismachine{$server});

Removed from v.1.160.6.84.2.5  
changed lines
  Added in v.1.280


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