Diff for /loncom/interface/domainprefs.pm between versions 1.160.6.48 and 1.275

version 1.160.6.48, 2014/05/23 08:34:54 version 1.275, 2016/07/25 19:50:30
Line 103  $datatable  - HTML containing form eleme Line 103  $datatable  - HTML containing form eleme
   
 In the case of course requests, radio buttons are displayed for each institutional  In the case of course requests, radio buttons are displayed for each institutional
 affiliate type (and also default, and _LC_adv) for each of the course types   affiliate type (and also default, and _LC_adv) for each of the course types 
 (official, unofficial, 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 169  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 213  sub handler { Line 215  sub handler {
                 'quotas','autoenroll','autoupdate','autocreate',                  'quotas','autoenroll','autoupdate','autocreate',
                 'directorysrch','usercreation','usermodification',                  'directorysrch','usercreation','usermodification',
                 'contacts','defaults','scantron','coursecategories',                  'contacts','defaults','scantron','coursecategories',
                 'serverstatuses','requestcourses','coursedefaults',                  'serverstatuses','requestcourses','helpsettings',
                 'usersessions','loadbalancing','requestauthor',                  'coursedefaults','usersessions','loadbalancing',
                 'selfenrollment','inststatus'],$dom);                  'requestauthor','selfenrollment','inststatus',
                   'ltitools','ssl'],$dom);
     my @prefs_order = ('rolecolors','login','defaults','quotas','autoenroll',      my @prefs_order = ('rolecolors','login','defaults','quotas','autoenroll',
                        'autoupdate','autocreate','directorysrch','contacts',                         'autoupdate','autocreate','directorysrch','contacts',
                        'usercreation','selfcreation','usermodification','scantron',                         'usercreation','selfcreation','usermodification','scantron',
                        'requestcourses','requestauthor','coursecategories',                         'requestcourses','requestauthor','coursecategories',
                        'serverstatuses','coursedefaults','selfenrollment',                         'serverstatuses','helpsettings','coursedefaults',
                        'usersessions');                         'ltitools','selfenrollment','usersessions','ssl');
     my %existing;      my %existing;
     if (ref($domconfig{'loadbalancing'}) eq 'HASH') {      if (ref($domconfig{'loadbalancing'}) eq 'HASH') {
         %existing = %{$domconfig{'loadbalancing'}};          %existing = %{$domconfig{'loadbalancing'}};
Line 250  sub handler { Line 253  sub handler {
                       header => [{col1 => 'Log-in Page Items',                        header => [{col1 => 'Log-in Page Items',
                                   col2 => '',},                                    col2 => '',},
                                  {col1 => 'Log-in Help',                                   {col1 => 'Log-in Help',
                                     col2 => 'Value'},
                                    {col1 => 'Custom HTML in document head',
                                   col2 => 'Value'}],                                    col2 => 'Value'}],
                       print => \&print_login,                        print => \&print_login,
                       modify => \&modify_login,                        modify => \&modify_login,
Line 409  sub handler { Line 414  sub handler {
                   print => \&print_serverstatuses,                    print => \&print_serverstatuses,
                   modify => \&modify_serverstatuses,                    modify => \&modify_serverstatuses,
                  },                   },
           'helpsettings' =>
                    {text   => 'Help page settings',
                     help   => 'Domain_Configuration_Help_Settings',
                     header => [{col1 => 'Help Settings (logged-in users)',
                                 col2 => 'Value'}],
                     print  => \&print_helpsettings,
                     modify => \&modify_helpsettings,
                    },
         'coursedefaults' =>           'coursedefaults' => 
                  {text => 'Course/Community defaults',                   {text => 'Course/Community defaults',
                   help => 'Domain_Configuration_Course_Defaults',                    help => 'Domain_Configuration_Course_Defaults',
Line 431  sub handler { Line 444  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 454  sub handler { Line 475  sub handler {
                   print => \&print_loadbalancing,                    print => \&print_loadbalancing,
                   modify => \&modify_loadbalancing,                    modify => \&modify_loadbalancing,
                  },                   },
            'ltitools' => 
                    {text => 'External Tools (LTI)',
                     help => 'Domain_configuration_LTI_Tools',
                     header => [{col1 => 'Setting',
                                 col2 => 'Value',}],
                     print => \&print_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,
                    },
     );      );
     if (keys(%servers) > 1) {      if (keys(%servers) > 1) {
         $prefs{'login'}  = { text   => 'Log-in page options',          $prefs{'login'}  = { text   => 'Log-in page options',
Line 463  sub handler { Line 504  sub handler {
                                        {col1 => 'Log-in Page Items',                                         {col1 => 'Log-in Page Items',
                                         col2 => ''},                                          col2 => ''},
                                        {col1 => 'Log-in Help',                                         {col1 => 'Log-in Help',
                                           col2 => 'Value'},
                                          {col1 => 'Custom HTML in document head',
                                         col2 => 'Value'}],                                          col2 => 'Value'}],
                             print => \&print_login,                              print => \&print_login,
                             modify => \&modify_login,                              modify => \&modify_login,
Line 615  sub process_changes { Line 658  sub process_changes {
         $output = &modify_quotas($r,$dom,$action,$lastactref,%domconfig);          $output = &modify_quotas($r,$dom,$action,$lastactref,%domconfig);
     } 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') {
           $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 623  sub process_changes { Line 668  sub process_changes {
         $output = &modify_usersessions($dom,$lastactref,%domconfig);          $output = &modify_usersessions($dom,$lastactref,%domconfig);
     } elsif ($action eq 'loadbalancing') {      } elsif ($action eq 'loadbalancing') {
         $output = &modify_loadbalancing($dom,%domconfig);          $output = &modify_loadbalancing($dom,%domconfig);
       } elsif ($action eq 'ltitools') {
           $output = &modify_ltitools($r,$dom,$action,$lastactref,%domconfig);
       } elsif ($action eq 'ssl') {
           $output = &modify_ssl($dom,$lastactref,%domconfig);
     }      }
     return $output;      return $output;
 }  }
Line 652  sub print_config_box { Line 701  sub print_config_box {
         my $colspan = '';          my $colspan = '';
         my $rightcolspan = '';          my $rightcolspan = '';
         if (($action eq 'rolecolors') || ($action eq 'defaults') ||          if (($action eq 'rolecolors') || ($action eq 'defaults') ||
             (($action eq 'login') && ($numheaders < 3))) {              (($action eq 'login') && ($numheaders < 4))) {
             $colspan = ' colspan="2"';              $colspan = ' colspan="2"';
         }          }
         if ($action eq 'usersessions') {          if ($action eq 'usersessions') {
Line 668  sub print_config_box { Line 717  sub print_config_box {
              </tr>';               </tr>';
         $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 'usermodification') || ($action eq 'defaults') || ($action eq 'coursedefaults') ||
             ($action eq 'selfenrollment') || ($action eq 'usersessions')) {              ($action eq 'selfenrollment') || ($action eq 'usersessions') || ($action eq 'ssl')) {
             $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);
         } elsif ($action eq 'login') {          } elsif ($action eq 'login') {
             if ($numheaders == 3) {              if ($numheaders == 4) {
                 $colspan = ' colspan="2"';                  $colspan = ' colspan="2"';
                 $output .= &print_login('service',$dom,$confname,$phase,$settings,\$rowtotal);                  $output .= &print_login('service',$dom,$confname,$phase,$settings,\$rowtotal);
             } else {              } else {
Line 699  sub print_config_box { Line 748  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 'ssl')) {
             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"';
Line 727  sub print_config_box { Line 777  sub print_config_box {
                   ($action eq 'defaults')) {                    ($action eq 'defaults')) {
             $output .= $item->{'print'}->('bottom',$dom,$settings,\$rowtotal);              $output .= $item->{'print'}->('bottom',$dom,$settings,\$rowtotal);
         } elsif ($action eq 'login') {          } elsif ($action eq 'login') {
             if ($numheaders == 3) {              if ($numheaders == 4) {
                 $output .= &print_login('page',$dom,$confname,$phase,$settings,\$rowtotal).'                  $output .= &print_login('page',$dom,$confname,$phase,$settings,\$rowtotal).'
            </table>             </table>
           </td>            </td>
Line 743  sub print_config_box { Line 793  sub print_config_box {
             } else {              } else {
                 $output .= &print_login('help',$dom,$confname,$phase,$settings,\$rowtotal);                  $output .= &print_login('help',$dom,$confname,$phase,$settings,\$rowtotal);
             }              }
               $output .= '
              </table>
             </td>
            </tr>
            <tr>
              <td>
               <table class="LC_nested">
                <tr class="LC_info_row">';
               if ($numheaders == 4) {
                   $output .= '
                 <td class="LC_left_item"'.$colspan.'>'.&mt($item->{'header'}->[3]->{'col1'}).'</td>
                 <td class="LC_right_item"'.$colspan.'>'.&mt($item->{'header'}->[3]->{'col2'}).'</td>
                </tr>';
               } else {
                   $output .= '
                 <td class="LC_left_item"'.$colspan.'>'.&mt($item->{'header'}->[2]->{'col1'}).'</td>
                 <td class="LC_right_item"'.$colspan.'>'.&mt($item->{'header'}->[2]->{'col2'}).'</td>
                </tr>';
               }
               $rowtotal ++;
               $output .= &print_login('headtag',$dom,$confname,$phase,$settings,\$rowtotal);
         } elsif ($action eq 'requestcourses') {          } elsif ($action eq 'requestcourses') {
             $output .= &print_requestmail($dom,$action,$settings,\$rowtotal).              $output .= &print_requestmail($dom,$action,$settings,\$rowtotal);
                        &print_studentcode($settings,\$rowtotal).'              $rowtotal ++;
               $output .= &print_studentcode($settings,\$rowtotal).'
            </table>             </table>
           </td>            </td>
          </tr>           </tr>
Line 780  sub print_config_box { Line 852  sub print_config_box {
             &print_validation_rows('requestcourses',$dom,$settings,\$rowtotal);              &print_validation_rows('requestcourses',$dom,$settings,\$rowtotal);
         } elsif ($action eq 'requestauthor') {          } elsif ($action eq 'requestauthor') {
             $output .= &print_requestmail($dom,$action,$settings,\$rowtotal);              $output .= &print_requestmail($dom,$action,$settings,\$rowtotal);
               $rowtotal ++;
         } elsif ($action eq 'rolecolors') {          } elsif ($action eq 'rolecolors') {
             $output .= &print_rolecolors($phase,'coordinator',$dom,$confname,$settings,\$rowtotal).'              $output .= &print_rolecolors($phase,'coordinator',$dom,$confname,$settings,\$rowtotal).'
            </table>             </table>
Line 859  sub print_config_box { Line 932  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') || ($action eq 'directorysrch') ||          } elsif (($action eq 'autoenroll') || ($action eq 'autocreate') || ($action eq 'directorysrch') ||
                  ($action eq 'contacts') || ($action eq 'serverstatuses') || ($action eq 'loadbalancing')) {                   ($action eq 'contacts') || ($action eq 'serverstatuses') || ($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);
Line 1161  sub print_login { Line 1235  sub print_login {
             $itemcount ++;              $itemcount ++;
         }          }
         $datatable .= &captcha_choice('login',$settings,$itemcount);          $datatable .= &captcha_choice('login',$settings,$itemcount);
       } elsif ($caller eq 'headtag') {
           my %domservers = &Apache::lonnet::get_servers($dom);
           my $choice = $choices{'headtag'};
           $css_class = ' class="LC_odd_row"';
           $datatable .= '<tr'.$css_class.'><td colspan="2">'.$choice.'</td>'.
                         '<td align="left"><table><tr><th>'.$choices{'hostid'}.'</th>'.
                         '<th>'.$choices{'current'}.'</th>'.
                         '<th>'.$choices{'action'}.'</th>'.
                         '<th>'.$choices{'exempt'}.'</th></tr>'."\n";
           my (%currurls,%currexempt);
           if (ref($settings) eq 'HASH') {
               if (ref($settings->{'headtag'}) eq 'HASH') {
                   foreach my $lonhost (keys(%{$settings->{'headtag'}})) {
                       if (ref($settings->{'headtag'}{$lonhost}) eq 'HASH') {
                           $currurls{$lonhost} = $settings->{'headtag'}{$lonhost}{'url'};
                           $currexempt{$lonhost} = $settings->{'headtag'}{$lonhost}{'exempt'};
                       }
                   }
               }
           }
           my %lt = &Apache::lonlocal::texthash(
                                                  del  => 'Delete?',
                                                  rep  => 'Replace:',
                                                  upl  => 'Upload:',
                                                  curr => 'View contents',
                                                  none => 'None',
           );
           my $switchserver = &check_switchserver($dom,$confname);
           foreach my $lonhost (sort(keys(%domservers))) {
               my $exempt = &check_exempt_addresses($currexempt{$lonhost});
               $datatable .= '<tr><td>'.$domservers{$lonhost}.'</td>';
               if ($currurls{$lonhost}) {
                   $datatable .= '<td class="LC_right_item"><a href="'.
                                 "javascript:void(open('$currurls{$lonhost}?inhibitmenu=yes','Custom_HeadTag',
                                 'menubar=0,toolbar=1,scrollbars=1,width=600,height=500,resizable=yes'))".
                                 '">'.$lt{'curr'}.'</a></td>'.
                                 '<td><span class="LC_nobreak"><label>'.
                                 '<input type="checkbox" name="loginheadtag_del" value="'.$lonhost.'" />'.
                                 $lt{'del'}.'</label>&nbsp;'.$lt{'rep'}.'</span>';
               } else {
                   $datatable .= '<td class="LC_right_item">'.$lt{'none'}.'</td><td>'.$lt{'upl'};
               }
               $datatable .='<br />';
               if ($switchserver) {
                   $datatable .= &mt('Upload to library server: [_1]',$switchserver);
               } else {
                   $datatable .= '<input type="file" name="loginheadtag_'.$lonhost.'" />';
               }
               $datatable .= '</td><td><input type="textbox" name="loginheadtagexempt_'.$lonhost.'" value="'.$exempt.'" /></td></tr>';
           }
           $datatable .= '</table></td></tr>';
     }      }
     return $datatable;      return $datatable;
 }  }
Line 1194  sub login_choices { Line 1319  sub login_choices {
             link          => "Link",              link          => "Link",
             alink         => "Active link",              alink         => "Active link",
             vlink         => "Visited link",              vlink         => "Visited link",
               headtag       => "Custom markup",
               action        => "Action",
               current       => "Current",
         );          );
     return %choices;      return %choices;
 }  }
Line 1611  sub print_quotas { Line 1739  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 2056  sub print_requestmail { Line 2184  sub print_requestmail {
         $datatable .= &mt('There are no active Domain Coordinators');          $datatable .= &mt('There are no active Domain Coordinators');
     }      }
     $datatable .='</td></tr>';      $datatable .='</td></tr>';
     $$rowtotal += $rows;  
     return $datatable;      return $datatable;
 }  }
   
Line 2064  sub print_studentcode { Line 2191  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->{'uniquecode'}) eq 'HASH') {      if (ref($settings) eq 'HASH') {
         foreach my $type (@crstypes) {          if (ref($settings->{'uniquecode'}) eq 'HASH') {
             $current{$type} = $settings->{'uniquecode'}{$type};              foreach my $type (@crstypes) {
                   $current{$type} = $settings->{'uniquecode'}{$type};
               }
         }          }
     }      }
     $output .= '<tr>'.      $output .= '<tr>'.
Line 2158  sub print_textbookcourses { Line 2287  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 2313  $jstext{'templates'}; Line 2441  $jstext{'templates'};
 ENDSCRIPT  ENDSCRIPT
 }  }
   
   sub ltitools_javascript {
       my ($settings) = @_;
       return unless(ref($settings) eq 'HASH');
       my (%ordered,$total,%jstext);
       $total = 0;
       foreach my $item (keys(%{$settings})) {
           if (ref($settings->{$item}) eq 'HASH') {
               my $num = $settings->{$item}{'order'};
               $ordered{$num} = $item;
           }
       }
       $total = scalar(keys(%{$settings}));
       my @jsarray = ();
       foreach my $item (sort {$a <=> $b } (keys(%ordered))) {
           push(@jsarray,$ordered{$item});
       }
       my $jstext = '    var ltitools = Array('."'".join("','",@jsarray)."'".');'."\n";
       return <<"ENDSCRIPT";
   <script type="text/javascript">
   // <![CDATA[
   function reorderLTI(form,item) {
       var changedVal;
   $jstext
       var newpos = 'ltitools_add_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<ltitools.length; i++) {
           var elementName = 'ltitools_'+ltitools[i];
           if (elementName != item) {
               if (form.elements[elementName]) {
                   var currVal = form.elements[elementName].options[form.elements[elementName].selectedIndex].value;
                   current[currVal] = elementName;
               }
           }
       }
       var oldVal;
       for (var j=0; j<maxh; j++) {
           if (current[j] == undefined) {
               oldVal = j;
           }
       }
       if (oldVal < changedVal) {
           for (var k=oldVal+1; k<=changedVal ; k++) {
              var elementName = current[k];
              form.elements[elementName].selectedIndex = form.elements[elementName].selectedIndex - 1;
           }
       } else {
           for (var k=changedVal; k<oldVal; k++) {
               var elementName = current[k];
               form.elements[elementName].selectedIndex = form.elements[elementName].selectedIndex + 1;
           }
       }
       return;
   }
   
   // ]]>
   </script>
   
   ENDSCRIPT
   }
   
 sub print_autoenroll {  sub print_autoenroll {
     my ($dom,$settings,$rowtotal) = @_;      my ($dom,$settings,$rowtotal) = @_;
     my $autorun = &Apache::lonnet::auto_run(undef,$dom),      my $autorun = &Apache::lonnet::auto_run(undef,$dom),
     my ($defdom,$runon,$runoff,$coownerson,$coownersoff);      my ($defdom,$runon,$runoff,$coownerson,$coownersoff,$failsafe);
     if (ref($settings) eq 'HASH') {      if (ref($settings) eq 'HASH') {
         if (exists($settings->{'run'})) {          if (exists($settings->{'run'})) {
             if ($settings->{'run'} eq '0') {              if ($settings->{'run'} eq '0') {
Line 2350  sub print_autoenroll { Line 2546  sub print_autoenroll {
         if (exists($settings->{'sender_domain'})) {          if (exists($settings->{'sender_domain'})) {
             $defdom = $settings->{'sender_domain'};              $defdom = $settings->{'sender_domain'};
         }          }
           if (exists($settings->{'autofailsafe'})) {
               $failsafe = $settings->{'autofailsafe'};
           }
     } else {      } else {
         if ($autorun) {          if ($autorun) {
             $runon = ' checked="checked" ';              $runon = ' checked="checked" ';
Line 2385  sub print_autoenroll { Line 2584  sub print_autoenroll {
                   $coownerson.' value="1" />'.&mt('Yes').'</label>&nbsp;'.                    $coownerson.' value="1" />'.&mt('Yes').'</label>&nbsp;'.
                   '<label><input type="radio" name="autoassign_coowners"'.                    '<label><input type="radio" name="autoassign_coowners"'.
                   $coownersoff.' value="0" />'.&mt('No').'</label></span></td>'.                    $coownersoff.' value="0" />'.&mt('No').'</label></span></td>'.
                   '</tr>';                    '</tr><tr>'.
     $$rowtotal += 3;                    '<td>'.&mt('Failsafe for no drops when institutional data missing').'</td>'.
                     '<td class="LC_right_item"><span class="LC_nobreak">'.
                     '<input type="text" name="autoenroll_failsafe"'.
                     ' value="'.$failsafe.'" size="4" /></td></tr>';
       $$rowtotal += 4;
     return $datatable;      return $datatable;
 }  }
   
Line 2501  sub print_autocreate { Line 2704  sub print_autocreate {
                   $createoff{'req'}.' value="0" />'.&mt('No').'</label></span>';                    $createoff{'req'}.' value="0" />'.&mt('No').'</label></span>';
     my ($numdc,$dctable,$rows) = &active_dc_picker($dom,$numinrow,'radio',      my ($numdc,$dctable,$rows) = &active_dc_picker($dom,$numinrow,'radio',
                                                    'autocreate_xmldc',%currhash);                                                     'autocreate_xmldc',%currhash);
       $datatable .= '</td></tr><tr class="LC_odd_row"><td>';
     if ($numdc > 1) {      if ($numdc > 1) {
         $datatable .= '</td></tr><tr class="LC_odd_row"><td>'.          $datatable .= &mt('Course creation processed as: (choose Dom. Coord.)').
                       &mt('Course creation processed as: (choose Dom. Coord.)').                        '</td><td class="LC_left_item">';
                       '</td><td class="LC_left_item">'.$dctable.'</td></tr>';  
     } else {      } else {
         $datatable .= $dctable.'</td></tr>';          $datatable .= &mt('Course creation processed as:').
                         '</td><td class="LC_right_item">';
     }      }
       $datatable .= $dctable.'</td></tr>';
     $$rowtotal += $rows;      $$rowtotal += $rows;
     return $datatable;      return $datatable;
 }  }
Line 2742  sub print_helpsettings { Line 2947  sub print_helpsettings {
   
 sub radiobutton_prefs {  sub radiobutton_prefs {
     my ($settings,$toggles,$defaultchecked,$choices,$itemcount,$onclick,      my ($settings,$toggles,$defaultchecked,$choices,$itemcount,$onclick,
         $additional) = @_;          $additional,$align) = @_;
     return unless ((ref($toggles) eq 'ARRAY') && (ref($defaultchecked) eq 'HASH') &&      return unless ((ref($toggles) eq 'ARRAY') && (ref($defaultchecked) eq 'HASH') &&
                    (ref($choices) eq 'HASH'));                     (ref($choices) eq 'HASH'));
   
Line 2776  sub radiobutton_prefs { Line 2981  sub radiobutton_prefs {
         $datatable .=          $datatable .=
             '<tr'.$css_class.'><td valign="top">'.              '<tr'.$css_class.'><td valign="top">'.
             '<span class="LC_nobreak">'.$choices->{$item}.              '<span class="LC_nobreak">'.$choices->{$item}.
             '</span></td>'.              '</span></td>';
             '<td class="LC_right_item"><span class="LC_nobreak">'.          if ($align eq 'left') {
               $datatable .= '<td class="LC_left_item">';
           } else {
               $datatable .= '<td class="LC_right_item">';
           }
           $datatable .= 
               '<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').
             '</label>&nbsp;<label><input type="radio" name="'.$item.'" '.              '</label>&nbsp;<label><input type="radio" name="'.$item.'" '.
Line 2790  sub radiobutton_prefs { Line 3001  sub radiobutton_prefs {
     return ($datatable,$itemcount);      return ($datatable,$itemcount);
 }  }
   
   sub print_ltitools {
       my ($dom,$settings,$rowtotal) = @_;
       my $rownum = 0;
       my $css_class;
       my $itemcount = 1;
       my $maxnum = 0;
       my %ordered;
       if (ref($settings) eq 'HASH') {
           foreach my $item (keys(%{$settings})) {
               if (ref($settings->{$item}) eq 'HASH') {
                   my $num = $settings->{$item}{'order'};
                   $ordered{$num} = $item;
               }
           }
       }
       my $confname = $dom.'-domainconfig';
       my $switchserver = &check_switchserver($dom,$confname);
       my $maxnum = scalar(keys(%ordered));
       my $datatable = &ltitools_javascript($settings);
       my %lt = &ltitools_names();
       my @courseroles = ('cc','in','ta','ep','st');
       my @ltiroles = qw(Instructor ContentDeveloper TeachingAssistant Learner);
       my @fields = ('fullname','firstname','lastname','email','user','roles');
       if (keys(%ordered)) {
           my @items = sort { $a <=> $b } keys(%ordered);
           for (my $i=0; $i<@items; $i++) {
               $css_class = $itemcount%2?' class="LC_odd_row"':'';
               my $item = $ordered{$items[$i]};
               my ($title,$key,$secret,$url,$imgsrc,$version);
               if (ref($settings->{$item}) eq 'HASH') {
                   $title = $settings->{$item}->{'title'};
                   $url = $settings->{$item}->{'url'};
                   $key = $settings->{$item}->{'key'};
                   $secret = $settings->{$item}->{'secret'};
                   my $image = $settings->{$item}->{'image'};
                   if ($image ne '') {
                       $imgsrc = '<img src="'.$image.'" alt="'.&mt('Tool Provider icon').'" />';
                   }
               }
               my $chgstr = ' onchange="javascript:reorderLTI(this.form,'."'ltitools_".$item."'".');"';
               $datatable .= '<tr '.$css_class.'><td><span class="LC_nobreak">'
                            .'<select name="ltitools_'.$item.'"'.$chgstr.'>';
               for (my $k=0; $k<=$maxnum; $k++) {
                   my $vpos = $k+1;
                   my $selstr;
                   if ($k == $i) {
                       $selstr = ' selected="selected" ';
                   }
                   $datatable .= '<option value="'.$k.'"'.$selstr.'>'.$vpos.'</option>';
               }
               $datatable .= '</select>'.('&nbsp;'x2).
                   '<label><input type="checkbox" name="ltitools_del" value="'.$item.'" />'.
                   &mt('Delete?').'</label></span></td>'.
                   '<td colspan="2">'.
                   '<fieldset><legend>'.&mt('Required settings').'</legend>'.
                   '<span class="LC_nobreak">'.$lt{'title'}.':<input type="text" size="30" name="ltitools_title_'.$i.'" value="'.$title.'" /></span> '.
                   ('&nbsp;'x2).
                   '<span class="LC_nobreak">'.$lt{'version'}.':<select name="ltitools_version_'.$i.'">'.
                   '<option value="LTI-1p0" selected="selected">1.1</option></select></span> '.
                   ('&nbsp;'x2).
                   '<span class="LC_nobreak">'.$lt{'msgtype'}.':<select name="ltitools_msgtype_'.$i.'">'.
                   '<option value="basic-lti-launch-request" selected="selected">Launch</option></select></span> '.
                   '<br /><br />'.
                   '<span class="LC_nobreak">'.$lt{'url'}.':<input type="text" size="30" name="ltitools_url_'.$i.'"'.
                   ' value="'.$url.'" /></span>'.
                   ('&nbsp;'x2).
                   '<span class="LC_nobreak">'.$lt{'key'}.
                   '<input type="text" size="25" name="ltitools_key_'.$i.'" value="'.$key.'" /></span> '.
                   ('&nbsp;'x2).
                   '<span class="LC_nobreak">'.$lt{'secret'}.':'.
                   '<input type="password" size="20" name="ltitools_secret_'.$i.'" value="'.$secret.'" />'.
                   '<label><input type="checkbox" name="visible" onclick="if (this.checked) { this.form.ltitools_secret_'.$i.'.type='."'text'".' } else { this.form.ltitools_secret_'.$i.'.type='."'password'".' }" />'.&mt('Visible input').'</label>'.
                   '<input type="hidden" name="ltitools_id_'.$i.'" value="'.$item.'" /></span>'.
                   '</fieldset>'.
                   '<fieldset><legend>'.&mt('Optional settings').'</legend>'.
                   '<span class="LC_nobreak">'.&mt('Display target:');
               my %currdisp;
               if (ref($settings->{$item}->{'display'}) eq 'HASH') {
                   if ($settings->{$item}->{'display'}->{'target'} eq 'window') {
                       $currdisp{'window'} = ' checked="checked"';
                   } else {
                       $currdisp{'iframe'} = ' checked="checked"';
                   }
                   if ($settings->{$item}->{'display'}->{'width'} =~ /^(\d+)$/) {
                       $currdisp{'width'} = $1;
                   }
                   if ($settings->{$item}->{'display'}->{'height'} =~ /^(\d+)$/) {
                        $currdisp{'height'} = $1;
                   }
               } else {
                   $currdisp{'iframe'} = ' checked="checked"';
               }
               foreach my $disp ('iframe','window') {
                   $datatable .= '<label><input type="radio" name="ltitools_target_'.$i.'" value="'.$disp.'"'.$currdisp{$disp}.' />'.
                                 $lt{$disp}.'</label>'.('&nbsp;'x2);
               }
               $datatable .= ('&nbsp;'x4);
               foreach my $dimen ('width','height') {
                   $datatable .= '<label>'.$lt{$dimen}.'&nbsp;'.
                                 '<input type="text" name="ltitools_'.$dimen.'_'.$i.'" size="5" value="'.$currdisp{$dimen}.'" /></label>'.
                                 ('&nbsp;'x2);
               }
               $datatable .= '<br />';
               foreach my $extra ('passback','roster') {
                   my $checkedon = '';
                   my $checkedoff = ' checked="checked"';
                   if ($settings->{$item}->{$extra}) {
                       $checkedon = $checkedoff;
                       $checkedoff = '';
                   }
                   $datatable .= $lt{$extra}.'&nbsp;'.
                                 '<label><input type="radio" name="ltitools_'.$extra.'_'.$i.'" value="1"'.$checkedon.' />'.
                                 &mt('Yes').'</label>'.('&nbsp;'x2).
                                 '<label><input type="radio" name="ltitools_'.$extra.'_'.$i.'" value="0"'.$checkedoff.' />'.
                                 &mt('No').'</label>'.('&nbsp;'x4);
               }
               $datatable .= '<br /><br /><span class="LC_nobreak">'.$lt{'icon'}.':&nbsp;';
               if ($imgsrc) {
                   $datatable .= $imgsrc.
                                 '<label><input type="checkbox" name="ltitools_image_del"'.
                                 ' value="'.$item.'" />'.&mt('Delete?').'</label></span> '.
                                 '<span class="LC_nobreak">&nbsp;'.&mt('Replace:').'&nbsp;';
               } else {
                   $datatable .= '('.&mt('if larger than 21x21 pixels, image will be scaled').')&nbsp;';
               }
               if ($switchserver) {
                   $datatable .= &mt('Upload to library server: [_1]',$switchserver);
               } else {
                   $datatable .= '<input type="file" name="ltitools_image_'.$i.'" value="" />';
               }
               $datatable .= '</span></fieldset>';
               my (%checkedfields,%rolemaps);
               if (ref($settings->{$item}) eq 'HASH') {
                   if (ref($settings->{$item}->{'fields'}) eq 'HASH') {
                       %checkedfields = %{$settings->{$item}->{'fields'}};
                   }
                   if (ref($settings->{$item}->{'roles'}) eq 'HASH') {
                       %rolemaps = %{$settings->{$item}->{'roles'}};
                       $checkedfields{'roles'} = 1;
                   }
               }
               $datatable .= '<fieldset><legend>'.&mt('User data sent on launch').'</legend>'.
                             '<span class="LC_nobreak">';
               foreach my $field (@fields) {
                   my $checked;
                   if ($checkedfields{$field}) {
                       $checked = ' checked="checked"';
                   }
                   $datatable .= '<label>'.
                                 '<input type="checkbox" name="ltitools_fields_'.$i.'" value="'.$field.'"'.$checked.' />'.
                                 $lt{$field}.'</label>'.('&nbsp;' x2);
               }
               $datatable .= '</span></fieldset>'.
                             '<fieldset><legend>'.&mt('Role mapping').'</legend><table><tr>';
               foreach my $role (@courseroles) {
                   my ($selected,$selectnone);
                   if (!$rolemaps{$role}) {
                       $selectnone = ' selected="selected"';
                   }
                   $datatable .= '<td align="center">'. 
                                 &Apache::lonnet::plaintext($role,'Course').'<br />'.
                                 '<select name="ltitools_roles_'.$role.'_'.$i.'">'.
                                 '<option value=""'.$selectnone.'>'.&mt('Select').'</option>';
                   foreach my $ltirole (@ltiroles) {
                       unless ($selectnone) {
                           if ($rolemaps{$role} eq $ltirole) {
                               $selected = ' selected="selected"';
                           } else {
                               $selected = '';
                           }
                       }
                       $datatable .= '<option value="'.$ltirole.'"'.$selected.'>'.$ltirole.'</option>';
                   }
                   $datatable .= '</select></td>';
               }
               $datatable .= '</tr></table></fieldset>';
               my %courseconfig;
               if (ref($settings->{$item}) eq 'HASH') {
                   if (ref($settings->{$item}->{'crsconf'}) eq 'HASH') {
                       %courseconfig = %{$settings->{$item}->{'crsconf'}};
                   }
               }
               $datatable .= '<fieldset><legend>'.&mt('Configurable in course').'</legend><span class="LC_nobreak">';
               foreach my $item ('label','title','target') {
                   my $checked;
                   if ($courseconfig{$item}) {
                       $checked = ' checked="checked"';
                   }
                   $datatable .= '<label>'.
                          '<input type="checkbox" name="ltitools_courseconfig_'.$i.'" value="'.$item.'"'.$checked.' />'.
                          $lt{'crs'.$item}.'</label>'.('&nbsp;' x2)."\n";
               }
               $datatable .= '</span></fieldset>'.
                             '<fieldset><legend>'.&mt('Custom items sent on launch').'</legend>'.
                             '<table><tr><th>'.&mt('Action').'</th><th>'.&mt('Name').'</th><th>'.&mt('Value').'</th></tr>';
               if (ref($settings->{$item}->{'custom'}) eq 'HASH') {
                   my %custom = %{$settings->{$item}->{'custom'}};
                   if (keys(%custom) > 0) {
                       foreach my $key (sort(keys(%custom))) {
                           $datatable .= '<tr><td><span class="LC_nobreak">'.
                                         '<label><input type="checkbox" name="ltitools_customdel_'.$i.'" value="'.
                                         $key.'" />'.&mt('Delete').'</label></span></td><td>'.$key.'</td>'.
                                         '<td><input type="text" name="ltitools_customval_'.$key.'_'.$i.'"'.
                                         ' value="'.$custom{$key}.'" /></td></tr>';
                       }
                   }
               }
               $datatable .= '<tr><td><span class="LC_nobreak">'.
                             '<label><input type="checkbox" name="ltitools_customadd" value="'.$i.'" />'.
                             &mt('Add').'</label></span></td><td><input type="text" name="ltitools_custom_name_'.$i.'" />'.
                             '</td><td><input type="text" name="ltitools_custom_value_'.$i.'" /></td></tr>';
               $datatable .= '</table></fieldset></td></tr>'."\n";
               $itemcount ++;
           }
       }
       $css_class = $itemcount%2?' class="LC_odd_row"':'';
       my $chgstr = ' onchange="javascript:reorderLTI(this.form,'."'ltitools_add_pos'".');"';
       $datatable .= '<tr '.$css_class.'><td><span class="LC_nobreak">'."\n".
                     '<input type="hidden" name="ltitools_maxnum" value="'.$maxnum.'" />'."\n".
                     '<select name="ltitools_add_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="ltitools_add" value="1" />'.&mt('Add').'</td>'."\n".
                     '<td colspan="2">'.
                     '<fieldset><legend>'.&mt('Required settings').'</legend>'.
                     '<span class="LC_nobreak">'.$lt{'title'}.':<input type="text" size="30" name="ltitools_add_title" value="" /></span> '."\n".
                     ('&nbsp;'x2).
                     '<span class="LC_nobreak">'.$lt{'version'}.':<select name="ltitools_add_version">'.
                     '<option value="LTI-1p0" selected="selected">1.1</option></select></span> '."\n".
                     ('&nbsp;'x2).
                     '<span class="LC_nobreak">'.$lt{'msgtype'}.':<select name="ltitools_add_msgtype">'.
                     '<option value="basic-lti-launch-request" selected="selected">Launch</option></select></span> '.
                     '<br />'.
                     '<span class="LC_nobreak">'.$lt{'url'}.':<input type="text" size="30" name="ltitools_add_url" value="" /></span> '."\n".
                     ('&nbsp;'x2).
                     '<span class="LC_nobreak">'.$lt{'key'}.':<input type="text" size="25" name="ltitools_add_key" value="" /></span> '."\n".
                     ('&nbsp;'x2).
                     '<span class="LC_nobreak">'.$lt{'secret'}.':<input type="password" size="20" name="ltitools_add_secret" value="" />'.
                     '<label><input type="checkbox" name="visible" onclick="if (this.checked) { this.form.ltitools_add_secret.type='."'text'".' } else { this.form.ltitools_add_secret.type='."'password'".' }" />'.&mt('Visible input').'</label></span> '."\n".
                     '</fieldset>'.
                     '<fieldset><legend>'.&mt('Optional settings').'</legend>'.
                     '<span class="LC_nobreak">'.&mt('Display target:');
       my %defaultdisp;
       $defaultdisp{'iframe'} = ' checked="checked"';
       foreach my $disp ('iframe','window') {
           $datatable .= '<label><input type="radio" name="ltitools_add_target" value="'.$disp.'"'.$defaultdisp{$disp}.' />'.
                         $lt{$disp}.'</label>'.('&nbsp;'x2);
       }
       $datatable .= ('&nbsp;'x4);
       foreach my $dimen ('width','height') {
           $datatable .= '<label>'.$lt{$dimen}.'&nbsp;'.
                         '<input type="text" name="ltitools_add_'.$dimen.'" size="5" /></label>'.
                         ('&nbsp;'x2);
       }
       $datatable .= '<br />';
       foreach my $extra ('passback','roster') {
           $datatable .= $lt{$extra}.'&nbsp;'.
                         '<label><input type="radio" name="ltitools_add_'.$extra.'" value="1" />'.
                         &mt('Yes').'</label>'.('&nbsp;'x2).
                         '<label><input type="radio" name="ltitools_add_'.$extra.'" value="0" checked="checked" />'.
                         &mt('No').'</label>'.('&nbsp;'x4);
       }
       $datatable .= '<br /><br /><span class="LC_nobreak">'.$lt{'icon'}.':&nbsp;'.
                     '('.&mt('if larger than 21x21 pixels, image will be scaled').')&nbsp;';
       if ($switchserver) {
           $datatable .= &mt('Upload to library server: [_1]',$switchserver);
       } else {
           $datatable .= '<input type="file" name="ltitools_add_image" value="" />';
       }
       $datatable .= '</span></fieldset>'.
                     '<fieldset><legend>'.&mt('User data sent on launch').'</legend>'.
                     '<span class="LC_nobreak">';
       foreach my $field (@fields) {
           $datatable .= '<label>'.
                         '<input type="checkbox" name="ltitools_add_fields" value="'.$field.'" />'.
                         $lt{$field}.'</label>'.('&nbsp;' x2);
       }
       $datatable .= '</span></fieldset>'.
                     '<fieldset><legend>'.&mt('Role mapping').'</legend><table><tr>';
       foreach my $role (@courseroles) {
           my ($checked,$checkednone);
           $datatable .= '<td align="center">'.
                         &Apache::lonnet::plaintext($role,'Course').'<br />'.
                         '<select name="ltitools_add_roles_'.$role.'">'.
                         '<option value="" selected="selected">'.&mt('Select').'</option>';
           foreach my $ltirole (@ltiroles) {
               $datatable .= '<option value="'.$ltirole.'">'.$ltirole.'</option>';
           }
           $datatable .= '</select></td>';
       }
       $datatable .= '</tr></table></fieldset>'.
                     '<fieldset><legend>'.&mt('Configurable in course').'</legend><span class="LC_nobreak">';
       foreach my $item ('label','title','target') {
            $datatable .= '<label>'.
                          '<input type="checkbox" name="ltitools_courseconfig" value="'.$item.'" checked="checked" />'.
                          $lt{'crs'.$item}.'</label>'.('&nbsp;' x2)."\n";
       }
       $datatable .= '</span></fieldset>'.
                     '<fieldset><legend>'.&mt('Custom items sent on launch').'</legend>'.
                     '<table><tr><th>'.&mt('Action').'</th><th>'.&mt('Name').'</th><th>'.&mt('Value').'</th></tr>'.
                     '<tr><td><span class="LC_nobreak">'.
                     '<label><input type="checkbox" name="ltitools_add_custom" value="1" />'.
                     &mt('Add').'</label></span></td><td><input type="text" name="ltitools_add_custom_name" />'.
                     '</td><td><input type="text" name="ltitools_add_custom_value" /></td></tr>'.
                     '</table></fieldset></td></tr>'."\n".
                     '</td>'."\n".
                     '</tr>'."\n";
       $itemcount ++;
       return $datatable;
   }
   
   sub ltitools_names {
       my %lt = &Apache::lonlocal::texthash(
                                             'title'     => 'Title',
                                             'version'   => 'Version',
                                             'msgtype'   => 'Message Type',
                                             'url'       => 'URL',
                                             'key'       => 'Key',
                                             'secret'    => 'Secret',
                                             'icon'      => 'Icon',   
                                             'user'      => 'Username:domain',
                                             'fullname'  => 'Full Name',
                                             'firstname' => 'First Name',
                                             'lastname'  => 'Last Name',
                                             'email'     => 'E-mail',
                                             'roles'     => 'Role',
                                             'window'    => 'Window/Tab',
                                             'iframe'    => 'iFrame',
                                             'height'    => 'Height',
                                             'width'     => 'Width',
                                             'passback'  => 'Tool can return grades:',
                                             'roster'    => 'Tool can retrieve roster:',
                                             'crstarget' => 'Display target',
                                             'crslabel'  => 'Course label',
                                             'crstitle'  => 'Course title', 
                                           );
       return %lt;
   }
   
 sub print_coursedefaults {  sub print_coursedefaults {
     my ($position,$dom,$settings,$rowtotal) = @_;      my ($position,$dom,$settings,$rowtotal) = @_;
     my ($css_class,$datatable,%checkedon,%checkedoff,%defaultchecked,@toggles);      my ($css_class,$datatable,%checkedon,%checkedoff,%defaultchecked,@toggles);
Line 2799  sub print_coursedefaults { Line 3356  sub print_coursedefaults {
         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',
           uselcmath            => 'Math preview uses LON-CAPA previewer (javascript) in place of DragMath (Java)',
           usejsme              => 'Molecule editor uses JSME (HTML5) in place of JME (Java)',
           postsubmit           => 'Disable submit button/keypress following student submission',
           canclone             => "People who may clone a course (besides course's owner and coordinators)",     
     );      );
     my %staticdefaults = (      my %staticdefaults = (
                            anonsurvey_threshold => 10,                             anonsurvey_threshold => 10,
                            uploadquota          => 500,                             uploadquota          => 500,
                              postsubmit           => 60,
                          );                           );
     if ($position eq 'top') {      if ($position eq 'top') {
         %defaultchecked = ('canuse_pdfforms' => 'off');          %defaultchecked = (
         @toggles = ('canuse_pdfforms');                              'canuse_pdfforms' => 'off',
                               'uselcmath'       => 'on',
                               'usejsme'         => 'on',
                               'canclone'        => 'none', 
                             );
           @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"':'';
           $datatable .=
               '<tr'.$css_class.'><td valign="top">'.
               '<span class="LC_nobreak">'.$choices{'canclone'}.
               '</span></td><td class="LC_left_item">';
           my $currcanclone = 'none';
           my $onclick;
           my @cloneoptions = ('none','domain');
           my %clonetitles = (
                                none     => 'No additional course requesters',
                                domain   => "Any course requester in course's domain",
                                instcode => 'Course requests for official courses ...',
                             );
           my (%codedefaults,@code_order,@posscodes);
           if (&Apache::lonnet::auto_instcode_defaults($dom,\%codedefaults,
                                                       \@code_order) eq 'ok') {
               if (@code_order > 0) {
                   push(@cloneoptions,'instcode');
                   $onclick = ' onclick="toggleDisplay(this.form,'."'cloneinstcode'".');"';
               }
           }
           if (ref($settings) eq 'HASH') {
               if ($settings->{'canclone'}) {
                   if (ref($settings->{'canclone'}) eq 'HASH') {
                       if (ref($settings->{'canclone'}{'instcode'}) eq 'ARRAY') {
                           if (@code_order > 0) {
                               $currcanclone = 'instcode';
                               @posscodes = @{$settings->{'canclone'}{'instcode'}};
                           }
                       }
                   } elsif ($settings->{'canclone'} eq 'domain') {
                       $currcanclone = $settings->{'canclone'};
                   }
               }
           } 
           foreach my $option (@cloneoptions) {
               my ($checked,$additional);
               if ($currcanclone eq $option) {
                   $checked = ' checked="checked"';
               }
               if ($option eq 'instcode') {
                   if (@code_order) {
                       my $show = 'none';
                       if ($checked) {
                           $show = 'block';
                       }
                       $additional = '<div id="cloneinstcode" style="display:'.$show.'" />'.
                                     &mt('Institutional codes for new and cloned course have identical:').
                                     '<br />';
                       foreach my $item (@code_order) {
                           my $codechk;
                           if ($checked) {
                               if (grep(/^\Q$item\E$/,@posscodes)) {
                                   $codechk = ' checked="checked"';
                               }
                           }
                           $additional .= '<label>'.
                                          '<input type="checkbox" name="clonecode" value="'.$item.'"'.$codechk.' />'.
                                          $item.'</label>';
                       }
                       $additional .= ('&nbsp;'x2).'('.&mt('check as many as needed').')</div>';
                   }
               }
               $datatable .=
                   '<span class="LC_nobreak"><label><input type="radio" name="canclone"'.$checked.
                   ' value="'.$option.'"'.$onclick.' />'.$clonetitles{$option}.
                   '</label>&nbsp;'.$additional.'</span><br />';
           }
           $datatable .= '</td>'.
                         '</tr>';
           $itemcount ++;
     } else {      } else {
         $css_class = $itemcount%2 ? ' class="LC_odd_row"' : '';          $css_class = $itemcount%2 ? ' class="LC_odd_row"' : '';
         my ($currdefresponder,$def_official_credits,$def_unofficial_credits,$def_textbook_credits,          my ($currdefresponder,%defcredits,%curruploadquota,%deftimeout);
             %curruploadquota);  
         my $currusecredits = 0;          my $currusecredits = 0;
         my @types = ('official','unofficial','community','textbook');          my $postsubmitclient = 1;
           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 2823  sub print_coursedefaults { Line 3461  sub print_coursedefaults {
                 }                  }
             }              }
             if (ref($settings->{'coursecredits'}) eq 'HASH') {              if (ref($settings->{'coursecredits'}) eq 'HASH') {
                 $def_official_credits = $settings->{'coursecredits'}->{'official'};                  foreach my $type (@types) {
                 $def_unofficial_credits = $settings->{'coursecredits'}->{'unofficial'};                      next if ($type eq 'community');
                 $def_textbook_credits = $settings->{'coursecredits'}->{'textbook'};                      $defcredits{$type} = $settings->{'coursecredits'}->{$type};
                 if (($def_official_credits ne '') || ($def_unofficial_credits ne '') ||                      if ($defcredits{$type} ne '') {
                     ($def_textbook_credits ne '')) {                          $currusecredits = 1;
                     $currusecredits = 1;                      }
                 }                  }
             }              }
               if (ref($settings->{'postsubmit'}) eq 'HASH') {
                   if ($settings->{'postsubmit'}->{'client'} eq 'off') {
                       $postsubmitclient = 0;
                       foreach my $type (@types) {
                           $deftimeout{$type} = $staticdefaults{'postsubmit'};
                       }
                   } else {
                       foreach my $type (@types) {
                           if (ref($settings->{'postsubmit'}->{'timeout'}) eq 'HASH') {
                               if ($settings->{'postsubmit'}->{'timeout'}->{$type} =~ /^\d+$/) {
                                   $deftimeout{$type} = $settings->{'postsubmit'}->{'timeout'}->{$type}; 
                               } else {
                                   $deftimeout{$type} = $staticdefaults{'postsubmit'};
                               }
                           } else {
                               $deftimeout{$type} = $staticdefaults{'postsubmit'};
                           }
                       }
                   }
               } else {
                   foreach my $type (@types) {
                       $deftimeout{$type} = $staticdefaults{'postsubmit'};
                   }
               }
           } else {
               foreach my $type (@types) {
                   $deftimeout{$type} = $staticdefaults{'postsubmit'};
               }
         }          }
         if (!$currdefresponder) {          if (!$currdefresponder) {
             $currdefresponder = $staticdefaults{'anonsurvey_threshold'};              $currdefresponder = $staticdefaults{'anonsurvey_threshold'};
Line 2870  sub print_coursedefaults { Line 3536  sub print_coursedefaults {
             $display = 'block';              $display = 'block';
         }          }
         my $additional = '<div id="credits" style="display: '.$display.'">'.          my $additional = '<div id="credits" style="display: '.$display.'">'.
                          '<span class="LC_nobreak">'.                           '<i>'.&mt('Default credits').'</i><br /><table><tr>';
                          &mt('Default credits for official courses [_1]',          foreach my $type (@types) {
                          '<input type="text" name="official_credits" value="'.              next if ($type eq 'community');
                          $def_official_credits.'" size="3" />').              $additional .= '<td align="center">'.&mt($type).'<br />'.
                          '</span><br />'.                             '<input type="text" name="'.$type.'_credits"'.
                          '<span class="LC_nobreak">'.                             ' value="'.$defcredits{$type}.'" size="3" /></td>';
                          &mt('Default credits for unofficial courses [_1]',          }
                          '<input type="text" name="unofficial_credits" value="'.          $additional .= '</tr></table></div>'."\n";
                          $def_unofficial_credits.'" size="3" />').  
                          '</span><br />'.  
                          '<span class="LC_nobreak">'.  
                          &mt('Default credits for textbook courses [_1]',  
                          '<input type="text" name="textbook_credits" value="'.  
                          $def_textbook_credits.'" size="3" />').  
                          '</span></div>'."\n";  
         %defaultchecked = ('coursecredits' => 'off');          %defaultchecked = ('coursecredits' => 'off');
         @toggles = ('coursecredits');          @toggles = ('coursecredits');
         my $current = {          my $current = {
Line 2892  sub print_coursedefaults { Line 3551  sub print_coursedefaults {
                       };                        };
         (my $table,$itemcount) =          (my $table,$itemcount) =
             &radiobutton_prefs($current,\@toggles,\%defaultchecked,              &radiobutton_prefs($current,\@toggles,\%defaultchecked,
                                \%choices,$itemcount,$onclick,$additional);                                 \%choices,$itemcount,$onclick,$additional,'left');
           $datatable .= $table;
           $onclick = "toggleDisplay(this.form,'studentsubmission');";
           my $display = 'none';
           if ($postsubmitclient) {
               $display = 'block';
           }
           $additional = '<div id="studentsubmission" style="display: '.$display.'">'.
                         &mt('Number of seconds submit is disabled').'<br />'.
                         '<i>'.&mt('Enter 0 to remain disabled until page reload.').'</i><br />'.
                         '<table><tr>';
           foreach my $type (@types) {
               $additional .= '<td align="center">'.&mt($type).'<br />'.
                              '<input type="text" name="'.$type.'_timeout" value="'.
                              $deftimeout{$type}.'" size="5" /></td>';
           }
           $additional .= '</tr></table></div>'."\n";
           %defaultchecked = ('postsubmit' => 'on');
           @toggles = ('postsubmit');
           my $current = {
                           'postsubmit' => $postsubmitclient,
                         };
           ($table,$itemcount) =
               &radiobutton_prefs($current,\@toggles,\%defaultchecked,
                                  \%choices,$itemcount,$onclick,$additional,'left');
         $datatable .= $table;          $datatable .= $table;
         $itemcount ++;  
     }      }
     $$rowtotal += $itemcount;      $$rowtotal += $itemcount;
     return $datatable;      return $datatable;
Line 2904  sub print_selfenrollment { Line 3586  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 3099  sub print_validation_rows { Line 3781  sub print_validation_rows {
     }      }
     if ($caller eq 'requestcourses') {      if ($caller eq 'requestcourses') {
         my %currhash;          my %currhash;
         if (ref($settings->{'validation'}) eq 'HASH') {          if (ref($settings) eq 'HASH') {
             if ($settings->{'validation'}{'dc'} ne '') {              if (ref($settings->{'validation'}) eq 'HASH') {
                 $currhash{$settings->{'validation'}{'dc'}} = 1;                  if ($settings->{'validation'}{'dc'} ne '') {
                       $currhash{$settings->{'validation'}{'dc'}} = 1;
                   }
             }              }
         }          }
         my $numinrow = 2;          my $numinrow = 2;
         my ($numdc,$dctable,$rows) = &active_dc_picker($dom,$numinrow,'radio',          my ($numdc,$dctable,$rows) = &active_dc_picker($dom,$numinrow,'radio',
                                                        'validationdc',%currhash);                                                         'validationdc',%currhash);
           my $css_class = $itemcount%2 ? ' class="LC_odd_row"' : '';
           $datatable .= '</td></tr><tr'.$css_class.'><td>';
         if ($numdc > 1) {          if ($numdc > 1) {
             $datatable .= '</td></tr><tr class="LC_odd_row"><td>'.              $datatable .= &mt('Course creation processed as: (choose Dom. Coord.)');
                           &mt('Course creation processed as: (choose Dom. Coord.)').  
                           '</td><td class="LC_left_item">'.$dctable.'</td></tr>';  
         } else {          } else {
             $datatable .= $dctable.'</td></tr>';              $datatable .=  &mt('Course creation processed as: ');
         }          }
           $datatable .= '</td><td class="LC_left_item">'.$dctable.'</td></tr>';
         $itemcount ++;          $itemcount ++;
     }      }
     if (ref($rowtotal)) {      if (ref($rowtotal)) {
Line 3125  sub print_validation_rows { Line 3810  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,%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;
Line 3136  sub print_usersessions { Line 3821  sub print_usersessions {
     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);
             $datatable .= &spares_row($dom,\%servers,\%spareid,\%serverhomes,\%altids,$rowtotal);              my $curroffloadnow;
               if (ref($settings) eq 'HASH') {
                   if (ref($settings->{'offloadnow'}) eq 'HASH') {
                       $curroffloadnow = $settings->{'offloadnow'};
                   }
               }
               $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.');
Line 3258  sub print_usersessions { Line 3949  sub print_usersessions {
     return $datatable;      return $datatable;
 }  }
   
   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 .= '</td></tr>';
                   $itemcount ++; 
               }
           } else {
               my $numinrow = 5;
               my $prefix = 'replication';
               my @types = ('certreq','nocertreq');
               my (%current,%checkedon,%checkedoff);
               my @locations = sort(keys(%by_location));
               foreach my $type (@types) {
                   $checkedon{$type} = '';
                   $checkedoff{$type} = ' checked="checked"';
               }
               if (ref($settings) eq 'HASH') {
                   if (ref($settings->{$prefix}) eq 'HASH') {
                       foreach my $key (keys(%{$settings->{$prefix}})) {
                           $current{$key} = $settings->{$prefix}{$key};
                           if (ref($current{$key}) eq 'ARRAY') {
                               $checkedon{$key} = ' checked="checked"';
                               $checkedoff{$key} = '';
                           }
                       }
                   }
               }
               if (@locations > 0) {
                   foreach my $type (@types) {
                       $css_class = $itemcount%2?' class="LC_odd_row"':'';
                       $datatable .= '<tr'.$css_class.'>
                                      <td><span class="LC_nobreak LC_right_item">'.$titles{$type}.'</span><br />
                                      <span class="LC_nobreak">&nbsp;
                                      <label><input type="radio" name="'.$prefix.'_'.$type.'_inuse" '.$checkedoff{$type}.' value="0" />'.&mt('Not in use').'</label>&nbsp;
                                      <label><input type="radio" name="'.$prefix.'_'.$type.'_inuse" '.$checkedon{$type}.' value="1" />'.&mt('In use').'</label></span></td><td>
                                      <div><input type="button" value="'.&mt('check all').'" '.
                                      'onclick="javascript:checkAll(document.display.'.$prefix.'_'.$type.')"'.
                                      ' />'.('&nbsp;'x2)."\n".
                                      '<input type="button" value="'.&mt('uncheck all').'" '.
                                      'onclick="javascript:uncheckAll(document.display.'.$prefix.'_'.$type.')" />'.
                                      "\n".
                                      '</div><div><table>';
                       my $rem;
                       for (my $i=0; $i<@locations; $i++) {
                           my ($showloc,$value,$checkedtype);
                           if (ref($by_location{$locations[$i]}) eq 'ARRAY') {
                               my $ip = $by_location{$locations[$i]}->[0];
                               if (ref($by_ip{$ip}) eq 'ARRAY') {
                                   $value = join(':',@{$by_ip{$ip}});
                                   $showloc = join(', ',@{$by_ip{$ip}});
                                   if (ref($current{$type}) eq 'ARRAY') {
                                       foreach my $loc (@{$by_ip{$ip}}) {
                                           if (grep(/^\Q$loc\E$/,@{$current{$type}})) {
                                               $checkedtype = ' checked="checked"';
                                               last;
                                           }
                                       }
                                   }
                               }
                           }
                           $rem = $i%($numinrow);
                           if ($rem == 0) {
                               if ($i > 0) {
                                  $datatable .= '</tr>';
                               }
                               $datatable .= '<tr>';
                           }
                           $datatable .= '<td class="LC_left_item">'.
                                         '<span class="LC_nobreak"><label>'.
                                         '<input type="checkbox" name="'.$prefix.'_'.$type.
                                         '" value="'.$value.'"'.$checkedtype.' />'.$showloc.
                                         '</label></span></td>';
                       }
                       $rem = @locations%($numinrow);
                       my $colsleft = $numinrow - $rem;
                       if ($colsleft > 1 ) {
                           $datatable .= '<td colspan="'.$colsleft.'" class="LC_left_item">'.
                                         '&nbsp;</td>';
                       } elsif ($colsleft == 1) {
                           $datatable .= '<td class="LC_left_item">&nbsp;</td>';
                       }
                       $datatable .= '</tr></table></td></tr>';
                       $itemcount ++;
                   }
               } else {
                   $datatable .= '<tr'.$css_class.'><td>'.&mt('Nothing to set here, as there are no other institutions').'</td></tr>';
                   $itemcount ++;
               }
           }
       }
       $$rowtotal += $itemcount;
       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 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 3278  sub build_location_hashes { Line 4137  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 3386  sub current_offloads_to { Line 4251  sub current_offloads_to {
 }  }
   
 sub spares_row {  sub spares_row {
     my ($dom,$servers,$spareid,$serverhomes,$altids,$rowtotal) = @_;      my ($dom,$servers,$spareid,$serverhomes,$altids,$curroffloadnow,$rowtotal) = @_;
     my $css_class;      my $css_class;
     my $numinrow = 4;      my $numinrow = 4;
     my $itemcount = 1;      my $itemcount = 1;
Line 3406  sub spares_row { Line 4271  sub spares_row {
                 }                  }
             }              }
             next unless (ref($spareid->{$server}) eq 'HASH');              next unless (ref($spareid->{$server}) eq 'HASH');
               my $checkednow;
               if (ref($curroffloadnow) eq 'HASH') {
                   if ($curroffloadnow->{$server}) {
                       $checkednow = ' checked="checked"';
                   }
               }
             $css_class = $itemcount%2 ? ' class="LC_odd_row"' : '';              $css_class = $itemcount%2 ? ' class="LC_odd_row"' : '';
             $datatable .= '<tr'.$css_class.'>              $datatable .= '<tr'.$css_class.'>
                            <td rowspan="2">                             <td rowspan="2">
                             <span class="LC_nobreak">'.                              <span class="LC_nobreak">'.
                           &mt('[_1] when busy, offloads to:'                            &mt('[_1] when busy, offloads to:'
                               ,'<b>'.$server.'</b>').                                ,'<b>'.$server.'</b>').'</span><br />'.
                             '<span class="LC_nobreak">'."\n". 
                             '<label><input type="checkbox" name="offloadnow" value="'.$server.'"'.$checkednow.' />'.
                             '&nbsp;'.&mt('Switch active users on next access').'</label></span>'.
                           "\n";                            "\n";
             my (%current,%canselect);              my (%current,%canselect);
             my @choices =               my @choices = 
Line 3635  sub print_loadbalancing { Line 4509  sub print_loadbalancing {
                     $disabled = ' disabled="disabled"';                      $disabled = ' disabled="disabled"';
                 }                  }
                 $targettable .=                  $targettable .=
                     '<td><label><input type="checkbox" name="loadbalancing_target_'.$balnum.'_'.$sparetype.'"'.                      '<td><span class="LC_nobreak"><label>'.
                       '<input type="checkbox" name="loadbalancing_target_'.$balnum.'_'.$sparetype.'"'.
                     $checked.$disabled.' value="'.$chkboxval.'" id="loadbalancing_target_'.$balnum.'_'.$sparetype.'_'.$i.'" onclick="checkOffloads('."this,'$balnum','$sparetype'".');" /><span id="loadbalancing_targettxt_'.$balnum.'_'.$sparetype.'_'.$i.'">&nbsp;'.$chkboxval.                      $checked.$disabled.' value="'.$chkboxval.'" id="loadbalancing_target_'.$balnum.'_'.$sparetype.'_'.$i.'" onclick="checkOffloads('."this,'$balnum','$sparetype'".');" /><span id="loadbalancing_targettxt_'.$balnum.'_'.$sparetype.'_'.$i.'">&nbsp;'.$chkboxval.
                     '</span></label></td>';                      '</span></label></span></td>';
                 my $rem = $i%($numinrow);                  my $rem = $i%($numinrow);
                 if ($rem == 0) {                  if ($rem == 0) {
                     if (($i > 0) && ($i < $numspares-1)) {                      if (($i > 0) && ($i < $numspares-1)) {
Line 3727  sub loadbalancing_rules { Line 4602  sub loadbalancing_rules {
             if (ref($currrules) eq 'HASH') {              if (ref($currrules) eq 'HASH') {
                 $current = $currrules->{$type};                  $current = $currrules->{$type};
             }              }
             if (($type eq '_LC_external') || ($type eq '_LC_internetdom') || ($type eq '_LC_ipchange')) {              if (($type eq '_LC_external') || ($type eq '_LC_internetdom')) {
                 if ($dom ne &Apache::lonnet::host_domain($lonhost)) {                  if ($dom ne &Apache::lonnet::host_domain($lonhost)) {
                     $current = '';                      $current = '';
                 }                  }
Line 3779  sub loadbalance_rule_row { Line 4654  sub loadbalance_rule_row {
     my @rulenames;      my @rulenames;
     my %ruletitles = &offloadtype_text();      my %ruletitles = &offloadtype_text();
     if (($type eq '_LC_ipchangesso') || ($type eq '_LC_ipchange')) {      if (($type eq '_LC_ipchangesso') || ($type eq '_LC_ipchange')) {
         @rulenames = ('balancer','offloadedto');          @rulenames = ('balancer','offloadedto','specific');
     } else {      } else {
         @rulenames = ('default','homeserver');          @rulenames = ('default','homeserver');
         if ($type eq '_LC_external') {          if ($type eq '_LC_external') {
Line 3790  sub loadbalance_rule_row { Line 4665  sub loadbalance_rule_row {
         push(@rulenames,'none');          push(@rulenames,'none');
     }      }
     my $style = $targets_div_style;      my $style = $targets_div_style;
     if (($type eq '_LC_external') || ($type eq '_LC_internetdom') || ($type eq '_LC_ipchange')) {      if (($type eq '_LC_external') || ($type eq '_LC_internetdom')) {
         $style = $homedom_div_style;          $style = $homedom_div_style;
     }      }
     my $space;      my $space;
Line 3841  sub loadbalance_rule_row { Line 4716  sub loadbalance_rule_row {
                    '<input type="radio" name="loadbalancing_rules_'.$balnum.'_'.$type.                     '<input type="radio" name="loadbalancing_rules_'.$balnum.'_'.$type.
                    '" id="loadbalancing_rules_'.$balnum.'_'.$type.'_'.$i.'" value="'.                     '" id="loadbalancing_rules_'.$balnum.'_'.$type.'_'.$i.'" value="'.
                    $rule.'" onclick="balanceruleChange('."this.form,'$balnum','$type'".                     $rule.'" onclick="balanceruleChange('."this.form,'$balnum','$type'".
                    ')"'.$checked.' />&nbsp;'.$ruletitles{$rulenames[$i]}.                     ')"'.$checked.' />&nbsp;';
                    '</label>'.$extra.'</span><br />'."\n";          if (($rulenames[$i] eq 'specific') && ($type =~ /^_LC_ipchange/)) {
               $output .= $ruletitles{'particular'};
           } else {
               $output .= $ruletitles{$rulenames[$i]};
           }
           $output .= '</label>'.$extra.'</span><br />'."\n";
     }      }
     $output .= '</div></td></tr>'."\n";      $output .= '</div></td></tr>'."\n";
     return $output;      return $output;
Line 3857  sub offloadtype_text { Line 4737  sub offloadtype_text {
            'none'             => 'No offload',             'none'             => 'No offload',
            'balancer'         => 'Session hosted on Load Balancer, after re-authentication',             'balancer'         => 'Session hosted on Load Balancer, after re-authentication',
            'offloadedto'      => 'Session hosted on offload server, after re-authentication',             'offloadedto'      => 'Session hosted on offload server, after re-authentication',
              'particular'       => 'Session hosted (after re-auth) on server:',
     );      );
     return %ruletitles;      return %ruletitles;
 }  }
Line 3898  sub tool_titles { Line 4779  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 3908  sub courserequest_titles { Line 4790  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 4139  sub print_selfcreation { Line 5022  sub print_selfcreation {
                 $datatable .= '<tr>';                  $datatable .= '<tr>';
             }              }
             my $currval;              my $currval;
             if (ref($createsettings->{'shibenv'}) eq 'HASH') {              if (ref($createsettings) eq 'HASH') {
                 $currval = $createsettings->{'shibenv'}{$fields[$i]};                  if (ref($createsettings->{'shibenv'}) eq 'HASH') {
                       $currval = $createsettings->{'shibenv'}{$fields[$i]};
                   }
             }              }
             $datatable .= '<td class="LC_left_item">'.              $datatable .= '<td class="LC_left_item">'.
                           '<span class="LC_nobreak">'.                            '<span class="LC_nobreak">'.
Line 4295  sub email_as_username { Line 5180  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);
     my %lt = &captcha_phrases();      my %lt = &captcha_phrases();
     $keyentry = 'hidden';      $keyentry = 'hidden';
     if ($context eq 'cancreate') {      if ($context eq 'cancreate') {
Line 4313  sub captcha_choice { Line 5199  sub captcha_choice {
             $pubtext = $lt{'pub'};              $pubtext = $lt{'pub'};
             $privtext = $lt{'priv'};              $privtext = $lt{'priv'};
             $keyentry = 'text';              $keyentry = 'text';
               $vertext = $lt{'ver'};
               $currver = $settings->{'recaptchaversion'};
               if ($currver ne '2') {
                   $currver = 1;
               }
         }          }
         if (ref($settings->{'recaptchakeys'}) eq 'HASH') {          if (ref($settings->{'recaptchakeys'}) eq 'HASH') {
             $currpub = $settings->{'recaptchakeys'}{'public'};              $currpub = $settings->{'recaptchakeys'}{'public'};
Line 4346  sub captcha_choice { Line 5237  sub captcha_choice {
                $currpub.'" size="40" /></span><br />'."\n".                 $currpub.'" size="40" /></span><br />'."\n".
                '<span class="LC_nobreak"><span id="'.$context.'_recaptchaprivtxt">'.$privtext.'</span>&nbsp;'."\n".                 '<span class="LC_nobreak"><span id="'.$context.'_recaptchaprivtxt">'.$privtext.'</span>&nbsp;'."\n".
                '<input type="'.$keyentry.'" id="'.$context.'_recaptchapriv" name="'.$context.'_recaptchapriv" value="'.                 '<input type="'.$keyentry.'" id="'.$context.'_recaptchapriv" name="'.$context.'_recaptchapriv" value="'.
                $currpriv.'" size="40" /></span></td></tr></table>'."\n".                 $currpriv.'" size="40" /></span><br />'.
                  '<span class="LC_nobreak"><span id="'.$context.'_recaptchavertxt">'.$vertext.'</span>&nbsp;'."\n".
                  '<input type="'.$keyentry.'" id="'.$context.'_recaptchaversion" name="'.$context.'_recaptchaversion" value="'.
                  $currver.'" size="3" /></span><br />'.
                  '</td></tr></table>'."\n".
                '</td></tr>';                 '</td></tr>';
     return $output;      return $output;
 }  }
Line 4529  sub print_defaults { Line 5424  sub print_defaults {
                 my $includeempty = 1;                  my $includeempty = 1;
                 $datatable .= &Apache::loncommon::select_datelocale($item,$defaults{$item},undef,$includeempty);                  $datatable .= &Apache::loncommon::select_datelocale($item,$defaults{$item},undef,$includeempty);
             } elsif ($item eq 'lang_def') {              } elsif ($item eq 'lang_def') {
                 my %langchoices = &get_languages_hash();                  my $includeempty = 1;
                 $langchoices{''} = 'No language preference';                  $datatable .= &Apache::loncommon::select_language($item,$defaults{$item},$includeempty);
                 %langchoices = &Apache::lonlocal::texthash(%langchoices);  
                 $datatable .= &Apache::loncommon::select_form($defaults{$item},$item,  
                                                               \%langchoices);  
             } else {              } else {
                 my $size;                  my $size;
                 if ($item eq 'portal_def') {                  if ($item eq 'portal_def') {
Line 4602  sub print_defaults { Line 5494  sub print_defaults {
                     $datatable .= '<option value="'.$k.'"'.$selstr.'>'.$vpos.'</option>';                      $datatable .= '<option value="'.$k.'"'.$selstr.'>'.$vpos.'</option>';
                 }                  }
                 $datatable .= '</select>&nbsp;'.&mt('Internal ID:').                  $datatable .= '</select>&nbsp;'.&mt('Internal ID:').
                               '<input type="text" size="10" name="addinststatus" value="" /></span>'.                                '<input type="text" size="10" name="addinststatus" value="" />'.
                               '&nbsp;'.&mt('(new)').                                '&nbsp;'.&mt('(new)').
                               '</span></td><td class="LC_left_item"><span class="LC_nobreak">'.                                '</span></td><td class="LC_left_item"><span class="LC_nobreak">'.
                               &mt('Name displayed:').                                &mt('Name displayed:').
Line 4883  sub print_coursecategories { Line 5775  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 4901  sub print_coursecategories { Line 5797  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 4941  sub print_coursecategories { Line 5848  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 4967  sub print_coursecategories { Line 5888  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 4993  sub print_coursecategories { Line 5917  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 5016  sub print_coursecategories { Line 5940  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 5048  sub print_coursecategories { Line 5972  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 5137  sub print_serverstatuses { Line 6061  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');              'ping','domconf','uniquecodes','diskusage','coursecatalog');
 }  }
   
 sub defaults_javascript {  sub defaults_javascript {
     my ($settings) = @_;      my ($settings) = @_;
     my ($output,$jstext);       return unless (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')) {
         my $maxnum = scalar(@{$settings->{'inststatusorder'}});          my $maxnum = scalar(@{$settings->{'inststatusorder'}});
         if ($maxnum eq '') {          if ($maxnum eq '') {
             $maxnum = 0;              $maxnum = 0;
         }          }
         $maxnum ++;          $maxnum ++;
         $jstext = '    var inststatuses = Array('."'".join("','",@{$settings->{'inststatusorder'}})."'".');';            my $jstext = '    var inststatuses = Array('."'".join("','",@{$settings->{'inststatusorder'}})."'".');';  
         return <<"ENDSCRIPT";          return <<"ENDSCRIPT";
 <script type="text/javascript">  <script type="text/javascript">
 // <![CDATA[  // <![CDATA[
Line 5229  sub coursecategories_javascript { Line 6153  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 $choose_again = '\\n'.&mt('Please use a different name for the new top level category.');       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.'); 
       &js_escape(\$instcode_reserved);
       &js_escape(\$communities_reserved);
       &js_escape(\$placement_reserved);
       &js_escape(\$choose_again);
     $output = <<"ENDSCRIPT";      $output = <<"ENDSCRIPT";
 <script type="text/javascript">  <script type="text/javascript">
 // <![CDATA[  // <![CDATA[
Line 5298  function categoryCheck(form) { Line 6227  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 5314  sub initialize_categories { Line 6247  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 5744  sub modify_login { Line 6678  sub modify_login {
     }      }
   
     my %servers = &Apache::lonnet::internet_dom_servers($dom);      my %servers = &Apache::lonnet::internet_dom_servers($dom);
       my %domservers = &Apache::lonnet::get_servers($dom);
     my @loginvia_attribs = ('serverpath','custompath','exempt');      my @loginvia_attribs = ('serverpath','custompath','exempt');
     if (keys(%servers) > 1) {      if (keys(%servers) > 1) {
         foreach my $lonhost (keys(%servers)) {          foreach my $lonhost (keys(%servers)) {
Line 5786  sub modify_login { Line 6721  sub modify_login {
                             $changes{'loginvia'}{$lonhost} = 1;                              $changes{'loginvia'}{$lonhost} = 1;
                         }                          }
                         if ($item eq 'exempt') {                          if ($item eq 'exempt') {
                             $new =~ s/^\s+//;                              $new = &check_exempt_addresses($new);
                             $new =~ s/\s+$//;  
                             my @poss_ips = split(/\s*[,:]\s*/,$new);  
                             my @okips;  
                             foreach my $ip (@poss_ips) {  
                                 if ($ip =~ /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/) {  
                                     if (($1 <= 255) && ($2 <= 255) && ($3 <= 255) && ($4 <= 255)) {  
                                         push(@okips,$ip);   
                                     }  
                                 }  
                             }  
                             if (@okips > 0) {  
                                 $new = join(',',@okips);   
                             } else {  
                                 $new = '';   
                             }  
                         }                          }
                         $loginhash{login}{loginvia}{$lonhost}{$item} = $new;                          $loginhash{login}{loginvia}{$lonhost}{$item} = $new;
                     }                      }
Line 5897  sub modify_login { Line 6817  sub modify_login {
                         $errors .= '<li><span class="LC_error">'.$puberror.'</span></li>';                          $errors .= '<li><span class="LC_error">'.$puberror.'</span></li>';
                         if ((grep(/^\Q$lang\E$/,@currlangs)) &&                          if ((grep(/^\Q$lang\E$/,@currlangs)) &&
                             (!grep(/^\Q$lang\E$/,@delurls))) {                              (!grep(/^\Q$lang\E$/,@delurls))) {
   
                             $loginhash{'login'}{'helpurl'}{$lang} = $domconfig{'login'}{'helpurl'}{$lang};                              $loginhash{'login'}{'helpurl'}{$lang} = $domconfig{'login'}{'helpurl'}{$lang};
                         }                          }
                     }                      }
Line 5913  sub modify_login { Line 6832  sub modify_login {
             $errors .= '<li><span class="LC_error">'.$error.'</span></li>';              $errors .= '<li><span class="LC_error">'.$error.'</span></li>';
         }          }
     }      }
   
       my (%currheadtagurls,%currexempt,@newhosts,%newheadtagurls,%possexempt);
       if (ref($domconfig{'login'}) eq 'HASH') {
           if (ref($domconfig{'login'}{'headtag'}) eq 'HASH') {
               foreach my $lonhost (keys(%{$domconfig{'login'}{'headtag'}})) {
                   if ($domservers{$lonhost}) {
                       if (ref($domconfig{'login'}{'headtag'}{$lonhost}) eq 'HASH') {
                           $currheadtagurls{$lonhost} = $domconfig{'login'}{'headtag'}{$lonhost}{'url'};
                           $currexempt{$lonhost} = $domconfig{'login'}{'headtag'}{$lonhost}{'exempt'};
                       }
                   }
               }
           }
       }
       my @delheadtagurls = &Apache::loncommon::get_env_multiple('form.loginheadtag_del');
       foreach my $lonhost (sort(keys(%domservers))) {
           if (grep(/^\Q$lonhost\E$/,@delheadtagurls)) {
               $changes{'headtag'}{$lonhost} = 1;
           } else {
               if ($env{'form.loginheadtagexempt_'.$lonhost}) {
                   $possexempt{$lonhost} = &check_exempt_addresses($env{'form.loginheadtagexempt_'.$lonhost});
               }
               if ($env{'form.loginheadtag_'.$lonhost.'.filename'}) {
                   push(@newhosts,$lonhost);
               } elsif ($currheadtagurls{$lonhost}) {
                   $loginhash{'login'}{'headtag'}{$lonhost}{'url'} = $currheadtagurls{$lonhost};
                   if ($currexempt{$lonhost}) {
                       if ((!exists($possexempt{$lonhost})) || ($possexempt{$lonhost} ne $currexempt{$lonhost})) { 
                           $changes{'headtag'}{$lonhost} = 1;
                       }
                   } elsif ($possexempt{$lonhost}) {
                       $changes{'headtag'}{$lonhost} = 1;
                   }
                   if ($possexempt{$lonhost}) {
                       $loginhash{'login'}{'headtag'}{$lonhost}{'exempt'} = $possexempt{$lonhost};
                   }
               }
           }
       }
       if (@newhosts) {
           my $error;
           my ($configuserok,$author_ok,$switchserver) = &config_check($dom,$confname,$servadm);
           if ($configuserok eq 'ok') {
               if ($switchserver) {
                   $error = &mt("Upload of custom markup is not permitted to this server: [_1]",$switchserver);
               } elsif ($author_ok eq 'ok') {
                   foreach my $lonhost (@newhosts) {
                       my $formelem = 'loginheadtag_'.$lonhost;
                       (my $result,$newheadtagurls{$lonhost}) = &publishlogo($r,'upload',$formelem,$dom,$confname,
                                                                             "login/headtag/$lonhost",'','',
                                                                             $env{'form.loginheadtag_'.$lonhost.'.filename'});
                       if ($result eq 'ok') {
                           $loginhash{'login'}{'headtag'}{$lonhost}{'url'} = $newheadtagurls{$lonhost};
                           $changes{'headtag'}{$lonhost} = 1;
                           if ($possexempt{$lonhost}) {
                               $loginhash{'login'}{'headtag'}{$lonhost}{'exempt'} = $possexempt{$lonhost};
                           }
                       } else {
                           my $puberror = &mt("Upload of [_1] failed because an error occurred publishing the file in RES space. Error was: [_2].",
                                              $newheadtagurls{$lonhost},$result);
                           $errors .= '<li><span class="LC_error">'.$puberror.'</span></li>';
                           if ((grep(/^\Q$lonhost\E$/,keys(%currheadtagurls))) &&
                               (!grep(/^\Q$lonhost\E$/,@delheadtagurls))) {
                               $loginhash{'login'}{'headtag'}{$lonhost} = $currheadtagurls{$lonhost};
                           }
                       }
                   }
               } else {
                   $error = &mt("Upload of custom markup file(s) failed because an author role could not be assigned to a Domain Configuration user ([_1]) in domain: [_2].  Error was: [_3].",$confname,$dom,$author_ok);
               }
           } else {
               $error = &mt("Upload of custom markup file(s) failed because a Domain Configuration user ([_1]) could not be created in domain: [_2].  Error was: [_3].",$confname,$dom,$configuserok);
           }
           if ($error) {
               &Apache::lonnet::logthis($error);
               $errors .= '<li><span class="LC_error">'.$error.'</span></li>';
           }
       }
     &process_captcha('login',\%changes,$loginhash{'login'},$domconfig{'login'});      &process_captcha('login',\%changes,$loginhash{'login'},$domconfig{'login'});
   
     my $defaulthelpfile = '/adm/loginproblems.html';      my $defaulthelpfile = '/adm/loginproblems.html';
Line 6013  sub modify_login { Line 7010  sub modify_login {
                             }                              }
                         }                          }
                     }                      }
                   } elsif ($item eq 'headtag') {
                       if (ref($changes{$item}) eq 'HASH') {
                           foreach my $lonhost (sort(keys(%{$changes{$item}}))) {
                               if (grep(/^\Q$lonhost\E$/,@delheadtagurls)) {
                                   $resulttext .= '<li>'.&mt('custom markup file removed for [_1]',$domservers{$lonhost}).'</li>';
                               } elsif (ref($loginhash{'login'}{'headtag'}{$lonhost}) eq 'HASH') {
                                   $resulttext .= '<li><a href="'.
                                                  "javascript:void(open('$loginhash{'login'}{'headtag'}{$lonhost}{'url'}?inhibitmenu=yes','Custom_HeadTag',
                                                  'menubar=0,toolbar=1,scrollbars=1,width=600,height=500,resizable=yes'))".
                                                  '">'.&mt('custom markup').'</a> '.&mt('(for [_1])',$servers{$lonhost}).' ';
                                   if ($possexempt{$lonhost}) {
                                       $resulttext .= &mt('not included for client IP(s): [_1]',$possexempt{$lonhost});
                                   } else {
                                       $resulttext .= &mt('included for any client IP');
                                   }
                                   $resulttext .= '</li>';
                               }
                           }
                       }
                 } elsif ($item eq 'captcha') {                  } elsif ($item eq 'captcha') {
                     if (ref($loginhash{'login'}) eq 'HASH') {                      if (ref($loginhash{'login'}) eq 'HASH') {
                         my $chgtxt;                          my $chgtxt;
Line 6044  sub modify_login { Line 7060  sub modify_login {
                         if (!$privkey) {                          if (!$privkey) {
                             $chgtxt .= '<li>'.&mt('Private key deleted').'</li>';                              $chgtxt .= '<li>'.&mt('Private key deleted').'</li>';
                         } else {                          } else {
                             $chgtxt .= '<li>'.&mt('Private key set to [_1]',$pubkey).'</li>';                              $chgtxt .= '<li>'.&mt('Private key set to [_1]',$privkey).'</li>';
                         }                          }
                         $chgtxt .= '</ul>';                          $chgtxt .= '</ul>';
                         $resulttext .= '<li>'.$chgtxt.'</li>';                          $resulttext .= '<li>'.$chgtxt.'</li>';
                     }                      }
                   } elsif ($item eq 'recaptchaversion') {
                       if (ref($loginhash{'login'}) eq 'HASH') {
                           if ($loginhash{'login'}{'captcha'} eq 'recaptcha') {
                               $resulttext .= '<li>'.&mt('ReCAPTCHA for helpdesk form set to version [_1]',$loginhash{'login'}{'recaptchaversion'}).
                                              '</li>';
                           }
                       }
                 } else {                  } else {
                     $resulttext .= '<li>'.&mt("$title{$item} set to $offon[$env{'form.'.$item}]").'</li>';                      $resulttext .= '<li>'.&mt("$title{$item} set to $offon[$env{'form.'.$item}]").'</li>';
                 }                  }
Line 6068  sub modify_login { Line 7091  sub modify_login {
     return $resulttext;      return $resulttext;
 }  }
   
   
   sub check_exempt_addresses {
       my ($iplist) = @_;
       $iplist =~ s/^\s+//;
       $iplist =~ s/\s+$//;
       my @poss_ips = split(/\s*[,:]\s*/,$iplist);
       my (@okips,$new);
       foreach my $ip (@poss_ips) {
           if ($ip =~ /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/) {
               if (($1 <= 255) && ($2 <= 255) && ($3 <= 255) && ($4 <= 255)) {
                   push(@okips,$ip);
               }
           }
       }
       if (@okips > 0) {
           $new = join(',',@okips);
       } else {
           $new = '';
       }
       return $new;
   }
   
 sub color_font_choices {  sub color_font_choices {
     my %choices =      my %choices =
         &Apache::lonlocal::texthash (          &Apache::lonlocal::texthash (
Line 6519  sub check_authorstatus { Line 7564  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 6647  $env{'user.name'}.':'.$env{'user.domain' Line 7692  $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 6659  $env{'user.name'}.':'.$env{'user.domain' Line 7705  $env{'user.name'}.':'.$env{'user.domain'
             $output = $versionresult;              $output = $versionresult;
         }          }
     }      }
     return ($output,$logourl);      return ($output,$logourl,$madethumb);
 }  }
   
 sub logo_versioning {  sub logo_versioning {
Line 6813  sub modify_quotas { Line 7859  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 6862  sub modify_quotas { Line 7908  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 6956  sub modify_quotas { Line 8002  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 7053  sub modify_quotas { Line 8099  sub modify_quotas {
                         if (@{$confhash{'validation'}{$item}} > 0) {                          if (@{$confhash{'validation'}{$item}} > 0) {
                             @{$confhash{'validation'}{$item}} = sort(@{$confhash{'validation'}{$item}});                              @{$confhash{'validation'}{$item}} = sort(@{$confhash{'validation'}{$item}});
                         }                          }
                         if (ref($domconfig{'requestcourses'}{'validation'}) eq 'HASH') {                          if (ref($domconfig{'requestcourses'}) eq 'HASH') {
                             if (ref($domconfig{'requestcourses'}{'validation'}{$item}) eq 'ARRAY') {                              if (ref($domconfig{'requestcourses'}{'validation'}) eq 'HASH') {
                                 @changed = &Apache::loncommon::compare_arrays($confhash{'validation'}{$item},                                  if (ref($domconfig{'requestcourses'}{'validation'}{$item}) eq 'ARRAY') {
                                                                               $domconfig{'requestcourses'}{'validation'}{$item});                                      @changed = &Apache::loncommon::compare_arrays($confhash{'validation'}{$item},
                                                                                     $domconfig{'requestcourses'}{'validation'}{$item});
                                   } else {
                                       @changed = @{$confhash{'validation'}{$item}};
                                   }
                             } else {                              } else {
                                 @changed = @{$confhash{'validation'}{$item}};                                  @changed = @{$confhash{'validation'}{$item}};
                             }                              }
Line 7077  sub modify_quotas { Line 8127  sub modify_quotas {
                                 $env{'form.requestcourses_validation_'.$item} =~ s/[\n\r\f]+/\s/gs;                                  $env{'form.requestcourses_validation_'.$item} =~ s/[\n\r\f]+/\s/gs;
                             }                              }
                         }                          }
                         if (ref($domconfig{'requestcourses'}{'validation'}) eq 'HASH') {                          if (ref($domconfig{'requestcourses'}) eq 'HASH') {
                             if ($domconfig{'requestcourses'}{'validation'}{$item} ne $confhash{'validation'}{$item}) {                              if (ref($domconfig{'requestcourses'}{'validation'}) eq 'HASH') {
                                 $changes{'validation'}{$item} = $confhash{'validation'}{$item};                                  if ($domconfig{'requestcourses'}{'validation'}{$item} ne $confhash{'validation'}{$item}) {
                                       $changes{'validation'}{$item} = $confhash{'validation'}{$item};
                                   }
                               } else {
                                   if ($confhash{'validation'}{$item} ne '') {
                                       $changes{'validation'}{$item} = $confhash{'validation'}{$item};
                                   }
                             }                              }
                         } else {                          } else {
                             if ($confhash{'validation'}{$item} ne '') {                              if ($confhash{'validation'}{$item} ne '') {
Line 7097  sub modify_quotas { Line 8153  sub modify_quotas {
                 }                  }
             }              }
             if (ref($confhash{'validation'}) eq 'HASH') {              if (ref($confhash{'validation'}) eq 'HASH') {
                 if (ref($domconfig{'requestcourses'}{'validation'}) eq 'HASH') {                  if (ref($domconfig{'requestcourses'}) eq 'HASH') {
                     if ($domconfig{'requestcourses'}{'validation'}{'dc'}) {                      if (ref($domconfig{'requestcourses'}{'validation'}) eq 'HASH') {
                         unless ($confhash{'validation'}{'dc'} eq $domconfig{'requestcourses'}{'validation'}{'dc'}) {                          if ($domconfig{'requestcourses'}{'validation'}{'dc'}) {
                             if ($confhash{'validation'}{'dc'} eq '') {                              unless ($confhash{'validation'}{'dc'} eq $domconfig{'requestcourses'}{'validation'}{'dc'}) {
                                 $changes{'validation'}{'dc'} = &mt('None');                                  if ($confhash{'validation'}{'dc'} eq '') {
                             } else {                                      $changes{'validation'}{'dc'} = &mt('None');
                                 $changes{'validation'}{'dc'} = $confhash{'validation'}{'dc'};                                  } else {
                                       $changes{'validation'}{'dc'} = $confhash{'validation'}{'dc'};
                                   }
                             }                              }
                           } elsif ($confhash{'validation'}{'dc'} ne '') {
                               $changes{'validation'}{'dc'} = $confhash{'validation'}{'dc'};
                         }                          }
                     } elsif ($confhash{'validation'}{'dc'} ne '') {                      } elsif ($confhash{'validation'}{'dc'} ne '') {
                         $changes{'validation'}{'dc'} = $confhash{'validation'}{'dc'};                          $changes{'validation'}{'dc'} = $confhash{'validation'}{'dc'};
                     }                      }
                 } elsif ($confhash{'validation'}{'dc'} ne '') {                  } elsif ($confhash{'validation'}{'dc'} ne '') {
                     $changes{'validation'}{'dc'} = $confhash{'validation'}{'dc'};                      $changes{'validation'}{'dc'} = $confhash{'validation'}{'dc'};
                 }                  }  
             } elsif (ref($domconfig{'requestcourses'}{'validation'}) eq 'HASH') {              } else {
                 if ($domconfig{'requestcourses'}{'validation'}{'dc'}) {                  if (ref($domconfig{'requestcourses'}) eq 'HASH') {
                     $changes{'validation'}{'dc'} = &mt('None');                      if (ref($domconfig{'requestcourses'}{'validation'}) eq 'HASH') {
                           if ($domconfig{'requestcourses'}{'validation'}{'dc'}) {
                               $changes{'validation'}{'dc'} = &mt('None');
                           }
                       }
                 }                  }
             }              }
         }          }
Line 7510  sub process_textbook_image { Line 8574  sub process_textbook_image {
     return ($url,$error);      return ($url,$error);
 }  }
   
   sub modify_ltitools {
       my ($r,$dom,$action,$lastactref,%domconfig) = @_;
       my %domdefaults = &Apache::lonnet::get_domain_defaults($dom,1);
       my ($newid,@allpos,%changes,%confhash,$errors,$resulttext);
       my $confname = $dom.'-domainconfig';
       my $servadm = $r->dir_config('lonAdmEMail');
       my ($configuserok,$author_ok,$switchserver) = &config_check($dom,$confname,$servadm);
       my (%posslti,%possfield);
       my @courseroles = ('cc','in','ta','ep','st');
       my @ltiroles = qw(Instructor ContentDeveloper TeachingAssistant Learner);
       map { $posslti{$_} = 1; } @ltiroles;
       my @allfields = ('fullname','firstname','lastname','email','user','roles');
       map { $possfield{$_} = 1; } @allfields;
       my %lt = &ltitools_names(); 
       if ($env{'form.ltitools_add'}) {
           my $title = $env{'form.ltitools_add_title'};
           $title =~ s/(`)/'/g;
           ($newid,my $error) = &get_ltitools_id($dom,$title);
           if ($newid) {
               my $position = $env{'form.ltitools_add_pos'};
               $position =~ s/\D+//g;
               if ($position ne '') {
                   $allpos[$position] = $newid;
               }
               $changes{$newid} = 1;
               foreach my $item ('title','url','key','secret') {
                   $env{'form.ltitools_add_'.$item} =~ s/(`)/'/g;
                   if ($env{'form.ltitools_add_'.$item}) {
                       $confhash{$newid}{$item} = $env{'form.ltitools_add_'.$item};
                   }
               }
               if ($env{'form.ltitools_add_version'} eq 'LTI-1p0') {
                   $confhash{$newid}{'version'} = $env{'form.ltitools_add_version'};
               }
               if ($env{'form.ltitools_add_msgtype'} eq 'basic-lti-launch-request') {
                   $confhash{$newid}{'msgtype'} = $env{'form.ltitools_add_msgtype'};
               }
               foreach my $item ('width','height') {
                   $env{'form.ltitools_add_'.$item} =~ s/^\s+//;
                   $env{'form.ltitools_add_'.$item} =~ s/\s+$//;
                   if ($env{'form.ltitools_add_'.$item} =~ /^\d+$/) {
                       $confhash{$newid}{'display'}{$item} = $env{'form.ltitools_add_'.$item};
                   }
               }
               if ($env{'form.ltitools_add_target'} eq 'window') {
                   $confhash{$newid}{'display'}{'target'} = $env{'form.ltitools_add_target'};
               } else {
                   $confhash{$newid}{'display'}{'target'} = 'iframe';
               }
               foreach my $item ('passback','roster') {
                   if ($env{'form.ltitools_add_'.$item}) {
                       $confhash{$newid}{$item} = 1;
                   }
               }
               if ($env{'form.ltitools_add_image.filename'} ne '') {
                   my ($imageurl,$error) =
                       &process_ltitools_image($r,$dom,$confname,'ltitools_add_image',$dom,
                                               $configuserok,$switchserver,$author_ok);
                   if ($imageurl) {
                       $confhash{$newid}{'image'} = $imageurl;
                   }
                   if ($error) {
                       &Apache::lonnet::logthis($error);
                       $errors .= '<li><span class="LC_error">'.$error.'</span></li>';
                   }
               }
               my @fields = &Apache::loncommon::get_env_multiple('form.ltitools_add_fields');
               foreach my $field (@fields) {
                   if ($possfield{$field}) {
                       if ($field eq 'roles') {
                           foreach my $role (@courseroles) {
                               my $choice = $env{'form.ltitools_add_roles_'.$role};
                               if (($choice ne '') && ($posslti{$choice})) {
                                   $confhash{$newid}{'roles'}{$role} = $choice;
                                   if ($role eq 'cc') {
                                       $confhash{$newid}{'roles'}{'co'} = $choice; 
                                   }
                               }
                           }
                       } else {
                           $confhash{$newid}{'fields'}{$field} = 1;
                       }
                   }
               }
               my @courseconfig = &Apache::loncommon::get_env_multiple('form.ltitools_courseconfig');
               foreach my $item (@courseconfig) {
                   $confhash{$newid}{'crsconf'}{$item} = 1;
               }
               if ($env{'form.ltitools_add_custom'}) {
                   my $name = $env{'form.ltitools_add_custom_name'};
                   my $value = $env{'form.ltitools_add_custom_value'};
                   $value =~ s/(`)/'/g;
                   $name =~ s/(`)/'/g;
                   $confhash{$newid}{'custom'}{$name} = $value;
               }
           } else {
               my $error = &mt('Failed to acquire unique ID for new external tool');   
               $errors .= '<li><span class="LC_error">'.$error.'</span></li>';
           }
       }
       if (ref($domconfig{$action}) eq 'HASH') {
           my %deletions;
           my @todelete = &Apache::loncommon::get_env_multiple('form.ltitools_del');
           if (@todelete) {
               map { $deletions{$_} = 1; } @todelete;
           }
           my %customadds;
           my @newcustom = &Apache::loncommon::get_env_multiple('form.ltitools_customadd');
           if (@newcustom) {
               map { $customadds{$_} = 1; } @newcustom;
           } 
           my %imgdeletions;
           my @todeleteimages = &Apache::loncommon::get_env_multiple('form.ltitools_image_del');
           if (@todeleteimages) {
               map { $imgdeletions{$_} = 1; } @todeleteimages;
           }
           my $maxnum = $env{'form.ltitools_maxnum'};
           for (my $i=0; $i<=$maxnum; $i++) {
               my $itemid = $env{'form.ltitools_id_'.$i};
               if (ref($domconfig{$action}{$itemid}) eq 'HASH') {
                   if ($deletions{$itemid}) {
                       if ($domconfig{$action}{$itemid}{'image'}) {
                           #FIXME need to obsolete item in RES space
                       }
                       $changes{$itemid} = $domconfig{$action}{$itemid}{'title'};
                       next;
                   } else {
                       my $newpos = $env{'form.ltitools_'.$itemid};
                       $newpos =~ s/\D+//g;
                       foreach my $item ('title','url','key','secret') {
                           $confhash{$itemid}{$item} = $env{'form.ltitools_'.$item.'_'.$i};
                           if ($domconfig{$action}{$itemid}{$item} ne $confhash{$itemid}{$item}) {
                               $changes{$itemid} = 1;
                           }
                       }
                       if ($env{'form.ltitools_version_'.$i} eq 'LTI-1p0') {
                           $confhash{$itemid}{'version'} = $env{'form.ltitools_version_'.$i};
                       }
                       if ($env{'form.ltitools_msgtype_'.$i} eq 'basic-lti-launch-request') {
                           $confhash{$itemid}{'msgtype'} = $env{'form.ltitools_msgtype_'.$i};
                       }
                       foreach my $size ('width','height') {
                           $env{'form.ltitools_'.$size.'_'.$i} =~ s/^\s+//;
                           $env{'form.ltitools_'.$size.'_'.$i} =~ s/\s+$//;
                           if ($env{'form.ltitools_'.$size.'_'.$i} =~ /^\d+$/) {
                               $confhash{$itemid}{'display'}{$size} = $env{'form.ltitools_'.$size.'_'.$i};
                               if (ref($domconfig{$action}{$itemid}{'display'}) eq 'HASH') {
                                   if ($domconfig{$action}{$itemid}{'display'}{$size} ne $confhash{$itemid}{'display'}{$size}) {
                                       $changes{$itemid} = 1;
                                   }
                               } else {
                                   $changes{$itemid} = 1;
                               }
                           }
                       }
                       if ($env{'form.ltitools_target_'.$i} eq 'window') {
                           $confhash{$itemid}{'display'}{'target'} = $env{'form.ltitools_target_'.$i};
                       } else {
                           $confhash{$itemid}{'display'}{'target'} = 'iframe';
                       }
                       if (ref($domconfig{$action}{$itemid}{'display'}) eq 'HASH') {
                           if ($domconfig{$action}{$itemid}{'display'}{'target'} ne $confhash{$itemid}{'display'}{'target'}) {
                               $changes{$itemid} = 1;
                           }
                       } else {
                           $changes{$itemid} = 1;
                       }
                       foreach my $extra ('passback','roster') {
                           if ($env{'form.ltitools_'.$extra.'_'.$i}) {
                               $confhash{$itemid}{$extra} = 1;
                           }
                           if ($domconfig{$action}{$itemid}{$extra} ne $confhash{$itemid}{$extra}) {
                               $changes{$itemid} = 1;
                           }
                       }
                       my @courseconfig = &Apache::loncommon::get_env_multiple('form.ltitools_courseconfig_'.$i);
                       foreach my $item ('label','title','target') {
                           if (grep(/^\Q$item\E$/,@courseconfig)) {
                               $confhash{$itemid}{'crsconf'}{$item} = 1;
                               if (ref($domconfig{$action}{$itemid}{'crsconf'}) eq 'HASH') {
                                   if ($domconfig{$action}{$itemid}{'crsconf'}{$item} ne $confhash{$itemid}{'crsconf'}{$item}) {
                                       $changes{$itemid} = 1;
                                   }
                               } else {
                                   $changes{$itemid} = 1;
                               }
                           }
                       }
                       my @fields = &Apache::loncommon::get_env_multiple('form.ltitools_fields_'.$i);
                       foreach my $field (@fields) {
                           if ($possfield{$field}) {
                               if ($field eq 'roles') {
                                   foreach my $role (@courseroles) {
                                       my $choice = $env{'form.ltitools_roles_'.$role.'_'.$i};
                                       if (($choice ne '') && ($posslti{$choice})) {
                                           $confhash{$itemid}{'roles'}{$role} = $choice;
                                           if ($role eq 'cc') {
                                               $confhash{$itemid}{'roles'}{'co'} = $choice;
                                           }
                                       }
                                       if (ref($domconfig{$action}{$itemid}{'roles'}) eq 'HASH') {
                                           if ($domconfig{$action}{$itemid}{'roles'}{$role} ne $confhash{$itemid}{'roles'}{$role}) {
                                               $changes{$itemid} = 1;
                                           }
                                       } elsif ($confhash{$itemid}{'roles'}{$role}) {
                                           $changes{$itemid} = 1;
                                       }
                                   }
                               } else {
                                   $confhash{$itemid}{'fields'}{$field} = 1;
                                   if (ref($domconfig{$action}{$itemid}{'fields'}) eq 'HASH') {
                                       if ($domconfig{$action}{$itemid}{'fields'}{$field} ne $confhash{$itemid}{'fields'}{$field}) {
                                           $changes{$itemid} = 1;
                                       }
                                   } else {
                                       $changes{$itemid} = 1;
                                   }
                               }
                           }
                       }
                       $allpos[$newpos] = $itemid;
                   }
                   if ($imgdeletions{$itemid}) {
                       $changes{$itemid} = 1;
                       #FIXME need to obsolete item in RES space
                   } elsif ($env{'form.ltitools_image_'.$i.'.filename'}) {
                       my ($imgurl,$error) = &process_ltitools_image($r,$dom,$confname,'ltitools_image_'.$i,
                                                                    $itemid,$configuserok,$switchserver,
                                                                    $author_ok);
                       if ($imgurl) {
                           $confhash{$itemid}{'image'} = $imgurl;
                           $changes{$itemid} = 1;
                       }
                       if ($error) {
                           &Apache::lonnet::logthis($error);
                           $errors .= '<li><span class="LC_error">'.$error.'</span></li>';
                       }
                   } elsif ($domconfig{$action}{$itemid}{'image'}) {
                       $confhash{$itemid}{'image'} =
                          $domconfig{$action}{$itemid}{'image'};
                   }
                   if ($customadds{$i}) {
                       my $name = $env{'form.ltitools_custom_name_'.$i};
                       $name =~ s/(`)/'/g;
                       $name =~ s/^\s+//;
                       $name =~ s/\s+$//;
                       my $value = $env{'form.ltitools_custom_value_'.$i};
                       $value =~ s/(`)/'/g;
                       $value =~ s/^\s+//;
                       $value =~ s/\s+$//;
                       if ($name ne '') {
                           $confhash{$itemid}{'custom'}{$name} = $value;
                           $changes{$itemid} = 1;
                       }
                   }
                   my %customdels;
                   my @customdeletions = &Apache::loncommon::get_env_multiple('form.ltitools_customdel_'.$i); 
                   if (@customdeletions) {
                       $changes{$itemid} = 1;
                   }
                   map { $customdels{$_} = 1; } @customdeletions;
                   if (ref($domconfig{$action}{$itemid}{'custom'}) eq 'HASH') {
                       foreach my $key (keys(%{$domconfig{$action}{$itemid}{'custom'}})) {
                           unless ($customdels{$key}) {
                               if ($env{'form.ltitools_customval_'.$key.'_'.$i} ne '') {
                                   $confhash{$itemid}{'custom'}{$key} = $env{'form.ltitools_customval_'.$key.'_'.$i}; 
                               }
                               if ($domconfig{$action}{$itemid}{'custom'}{$key} ne $env{'form.ltitools_customval_'.$key.'_'.$i}) {
                                   $changes{$itemid} = 1;
                               }
                           }
                       }
                   }
                   unless ($changes{$itemid}) {
                       foreach my $key (keys(%{$domconfig{$action}{$itemid}})) {
                           if (ref($domconfig{$action}{$itemid}{$key}) eq 'HASH') {
                               if (ref($confhash{$itemid}{$key}) eq 'HASH') {
                                   foreach my $innerkey (keys(%{$domconfig{$action}{$itemid}{$key}})) {
                                       unless (exists($confhash{$itemid}{$key}{$innerkey})) {
                                           $changes{$itemid} = 1;
                                           last;
                                       }
                                   }
                               } elsif (keys(%{$domconfig{$action}{$itemid}{$key}}) > 0) {
                                   $changes{$itemid} = 1;
                               }
                           }
                           last if ($changes{$itemid});
                       }
                   }
               }
           }
       }
       if (@allpos > 0) {
           my $idx = 0;
           foreach my $itemid (@allpos) {
               if ($itemid ne '') {
                   $confhash{$itemid}{'order'} = $idx;
                   if (ref($domconfig{$action}) eq 'HASH') {
                       if (ref($domconfig{$action}{$itemid}) eq 'HASH') {
                           if ($domconfig{$action}{$itemid}{'order'} ne $idx) {
                               $changes{$itemid} = 1;
                           }
                       }
                   }
                   $idx ++;
               }
           }
       }
       my %ltitoolshash = (
                             $action => { %confhash }
                          );
       my $putresult = &Apache::lonnet::put_dom('configuration',\%ltitoolshash,
                                                $dom);
       if ($putresult eq 'ok') {
           if (keys(%changes) > 0) {
               my $cachetime = 24*60*60;
               &Apache::lonnet::do_cache_new('ltitools',$dom,\%confhash,$cachetime);
               if (ref($lastactref) eq 'HASH') {
                   $lastactref->{'ltitools'} = 1;
               }
               $resulttext = &mt('Changes made:').'<ul>';
               my %bynum;
               foreach my $itemid (sort(keys(%changes))) {
                   my $position = $confhash{$itemid}{'order'};
                   $bynum{$position} = $itemid;
               }
               foreach my $pos (sort { $a <=> $b } keys(%bynum)) {
                   my $itemid = $bynum{$pos}; 
                   if (ref($confhash{$itemid}) ne 'HASH') {
                       $resulttext .= '<li>'.&mt('Deleted: [_1]',$changes{$itemid}).'</li>';
                   } else {
                       $resulttext .= '<li><b>'.$confhash{$itemid}{'title'}.'</b>';
                       if ($confhash{$itemid}{'image'}) {
                           $resulttext .= '&nbsp;'.
                                          '<img src="'.$confhash{$itemid}{'image'}.'"'.
                                          ' alt="'.&mt('Tool Provider icon').'" />';
                       }
                       $resulttext .= '</li><ul>';
                       my $position = $pos + 1;
                       $resulttext .= '<li>'.&mt('Order: [_1]',$position).'</li>';
                       foreach my $item ('version','msgtype','url','key') {
                           if ($confhash{$itemid}{$item} ne '') {
                               $resulttext .= '<li>'.$lt{$item}.':&nbsp;'.$confhash{$itemid}{$item}.'</li>';
                           }
                       }
                       if ($confhash{$itemid}{'secret'} ne '') {
                           $resulttext .= '<li>'.$lt{'secret'}.':&nbsp;';
                           my $num = length($confhash{$itemid}{'secret'});
                           $resulttext .= ('*'x$num).'</li>';
                       }
                       $resulttext .= '<li>'.&mt('Configurable in course:');
                       my @possconfig = ('label','title','target');
                       my $numconfig = 0; 
                       if (ref($confhash{$itemid}{'crsconf'}) eq 'HASH') { 
                           foreach my $item (@possconfig) {
                               if ($confhash{$itemid}{'crsconf'}{$item}) {
                                   $numconfig ++;
                                   $resulttext .= ' '.$lt{'crs'.$item};
                               }
                           }
                       }
                       if (!$numconfig) {
                           $resulttext .= &mt('None');
                       }
                       $resulttext .= '</li>';
                       foreach my $item ('passback','roster') {
                           $resulttext .= '<li>'.$lt{$item}.'&nbsp;';
                           if ($confhash{$itemid}{$item}) {
                               $resulttext .= &mt('Yes');
                           } else {
                               $resulttext .= &mt('No');
                           }
                           $resulttext .= '</li>';
                       }
                       if (ref($confhash{$itemid}{'display'}) eq 'HASH') {
                           my $displaylist;
                           if ($confhash{$itemid}{'display'}{'target'}) {
                               $displaylist = &mt('Display target').':&nbsp;'.
                                              $confhash{$itemid}{'display'}{'target'}.',';
                           }
                           foreach my $size ('width','height') { 
                               if ($confhash{$itemid}{'display'}{$size}) {
                                   $displaylist .= ('&nbsp;'x2).$lt{$size}.':&nbsp;'.
                                                   $confhash{$itemid}{'display'}{$size}.',';
                               }
                           }
                           if ($displaylist) {
                               $displaylist =~ s/,$//;
                               $resulttext .= '<li>'.$displaylist.'</li>';
                           }
                       } 
                       if (ref($confhash{$itemid}{'fields'}) eq 'HASH') {
                           my $fieldlist;
                           foreach my $field (@allfields) {
                               if ($confhash{$itemid}{'fields'}{$field}) {
                                   $fieldlist .= ('&nbsp;'x2).$lt{$field}.',';
                               }
                           }
                           if ($fieldlist) {
                               $fieldlist =~ s/,$//;
                               $resulttext .= '<li>'.&mt('Data sent').':'.$fieldlist.'</li>';
                           }
                       }
                       if (ref($confhash{$itemid}{'roles'}) eq 'HASH') {
                           my $rolemaps;
                           foreach my $role (@courseroles) {
                               if ($confhash{$itemid}{'roles'}{$role}) {
                                   $rolemaps .= ('&nbsp;'x2).&Apache::lonnet::plaintext($role,'Course').'='.
                                                $confhash{$itemid}{'roles'}{$role}.',';
                               }
                           }
                           if ($rolemaps) {
                               $rolemaps =~ s/,$//; 
                               $resulttext .= '<li>'.&mt('Role mapping:').$rolemaps.'</li>';
                           }
                       }
                       if (ref($confhash{$itemid}{'custom'}) eq 'HASH') {
                           my $customlist;
                           if (keys(%{$confhash{$itemid}{'custom'}})) {
                               foreach my $key (sort(keys(%{$confhash{$itemid}{'custom'}}))) {
                                   $customlist .= $key.':'.$confhash{$itemid}{'custom'}{$key}.('&nbsp;'x2);
                               } 
                           }
                           if ($customlist) {
                               $resulttext .= '<li>'.&mt('Custom items').':'.$customlist.'</li>';
                           }
                       } 
                       $resulttext .= '</ul></li>';
                   }
               }
               $resulttext .= '</ul>';
           } else {
               $resulttext = &mt('No changes made.');
           }
       } else {
           $errors .= '<li><span class="LC_error">'.&mt('Failed to save changes').'</span></li>';
       }
       if ($errors) {
           $resulttext .= &mt('The following errors occurred: ').'<ul>'.
                          $errors.'</ul>';
       }
       return $resulttext;
   }
   
   sub process_ltitools_image {
       my ($r,$dom,$confname,$caller,$itemid,$configuserok,$switchserver,$author_ok) = @_;
       my $filename = $env{'form.'.$caller.'.filename'};
       my ($error,$url);
       my ($width,$height) = (21,21);
       if ($configuserok eq 'ok') {
           if ($switchserver) {
               $error = &mt('Upload of Tool Provider (LTI) icon is not permitted to this server: [_1]',
                            $switchserver);
           } elsif ($author_ok eq 'ok') {
               my ($result,$imageurl,$madethumb) =
                   &publishlogo($r,'upload',$caller,$dom,$confname,
                                "ltitools/$itemid/icon",$width,$height);
               if ($result eq 'ok') {
                   if ($madethumb) {
                       my ($path,$imagefile) = ($imageurl =~ m{^(.+)/([^/]+)$});
                       my $imagethumb = "$path/tn-".$imagefile;
                       $url = $imagethumb;
                   } else {
                       $url = $imageurl;
                   }
               } else {
                   $error = &mt("Upload of [_1] failed because an error occurred publishing the file in RES space. Error was: [_2].",$filename,$result);
               }
           } else {
               $error = &mt("Upload of [_1] failed because an author role could not be assigned to a Domain Configuration user ([_2]) in domain: [_3].  Error was: [_4].",$filename,$confname,$dom,$author_ok);
           }
       } else {
           $error = &mt("Upload of [_1] failed because a Domain Configuration user ([_2]) could not be created in domain: [_3].  Error was: [_4].",$filename,$confname,$dom,$configuserok);
       }
       return ($url,$error);
   }
   
   sub get_ltitools_id {
       my ($cdom,$title) = @_;
       # get lock on ltitools db
       my $lockhash = {
                         lock => $env{'user.name'}.
                                 ':'.$env{'user.domain'},
                      };
       my $tries = 0;
       my $gotlock = &Apache::lonnet::newput_dom('ltitools',$lockhash,$cdom);
       my ($id,$error);
    
       while (($gotlock ne 'ok') && ($tries<10)) {
           $tries ++;
           sleep (0.1);
           $gotlock = &Apache::lonnet::newput_dom('ltitools',$lockhash,$cdom);
       }
       if ($gotlock eq 'ok') {
           my %currids = &Apache::lonnet::dump_dom('ltitools',$cdom);
           if ($currids{'lock'}) {
               delete($currids{'lock'});
               if (keys(%currids)) {
                   my @curr = sort { $a <=> $b } keys(%currids);
                   if ($curr[-1] =~ /^\d+$/) {
                       $id = 1 + $curr[-1];
                   }
               } else {
                   $id = 1;
               }
               if ($id) {
                   unless (&Apache::lonnet::newput_dom('ltitools',{ $id => $title },$cdom) eq 'ok') {
                       $error = 'nostore';
                   }
               } else {
                   $error = 'nonumber';
               }
           }
           my $dellockoutcome = &Apache::lonnet::del_dom('ltitools',['lock'],$cdom);
       } else {
           $error = 'nolock';
       }
       return ($id,$error);
   }
   
 sub modify_autoenroll {  sub modify_autoenroll {
     my ($dom,$lastactref,%domconfig) = @_;      my ($dom,$lastactref,%domconfig) = @_;
     my ($resulttext,%changes);      my ($resulttext,%changes);
Line 7522  sub modify_autoenroll { Line 9107  sub modify_autoenroll {
     my $autorun = &Apache::lonnet::auto_run(undef,$dom),      my $autorun = &Apache::lonnet::auto_run(undef,$dom),
     my %title = ( run => 'Auto-enrollment active',      my %title = ( run => 'Auto-enrollment active',
                   sender => 'Sender for notification messages',                    sender => 'Sender for notification messages',
                   coowners => 'Automatic assignment of co-ownership to instructors of record (institutional data)');                    coowners => 'Automatic assignment of co-ownership to instructors of record (institutional data)',
                     failsafe => 'Failsafe for no drops if institutional data missing for a section');
     my @offon = ('off','on');      my @offon = ('off','on');
     my $sender_uname = $env{'form.sender_uname'};      my $sender_uname = $env{'form.sender_uname'};
     my $sender_domain = $env{'form.sender_domain'};      my $sender_domain = $env{'form.sender_domain'};
Line 7532  sub modify_autoenroll { Line 9118  sub modify_autoenroll {
         $sender_domain = '';          $sender_domain = '';
     }      }
     my $coowners = $env{'form.autoassign_coowners'};      my $coowners = $env{'form.autoassign_coowners'};
       my $failsafe = $env{'form.autoenroll_failsafe'};
       $failsafe =~ s{^\s+|\s+$}{}g;
       if ($failsafe =~ /\D/) {
           undef($failsafe);
       }
     my %autoenrollhash =  (      my %autoenrollhash =  (
                        autoenroll => { 'run' => $env{'form.autoenroll_run'},                         autoenroll => { 'run' => $env{'form.autoenroll_run'},
                                        'sender_uname' => $sender_uname,                                         'sender_uname' => $sender_uname,
                                        'sender_domain' => $sender_domain,                                         'sender_domain' => $sender_domain,
                                        'co-owners' => $coowners,                                         'co-owners' => $coowners,
                                          'autofailsafe' => $failsafe,
                                 }                                  }
                      );                       );
     my $putresult = &Apache::lonnet::put_dom('configuration',\%autoenrollhash,      my $putresult = &Apache::lonnet::put_dom('configuration',\%autoenrollhash,
Line 7563  sub modify_autoenroll { Line 9155  sub modify_autoenroll {
             }              }
         } elsif ($coowners) {          } elsif ($coowners) {
             $changes{'coowners'} = 1;              $changes{'coowners'} = 1;
         }                }
           if ($currautoenroll{'autofailsafe'} ne $failsafe) {
               $changes{'autofailsafe'} = 1;
           }
         if (keys(%changes) > 0) {          if (keys(%changes) > 0) {
             $resulttext = &mt('Changes made:').'<ul>';              $resulttext = &mt('Changes made:').'<ul>';
             if ($changes{'run'}) {              if ($changes{'run'}) {
Line 7583  sub modify_autoenroll { Line 9178  sub modify_autoenroll {
                     $lastactref->{'domainconfig'} = 1;                      $lastactref->{'domainconfig'} = 1;
                 }                  }
             }              }
               if ($changes{'autofailsafe'}) {
                   if ($failsafe ne '') {
                       $resulttext .= '<li>'.&mt("$title{'failsafe'} set to [_1]",$failsafe).'</li>';
                   } else {
                       $resulttext .= '<li>'.&mt("$title{'failsafe'} deleted");
                   }
                   &Apache::lonnet::get_domain_defaults($dom,1);
                   if (ref($lastactref) eq 'HASH') {
                       $lastactref->{'domdefaults'} = 1;
                   }
               }
             $resulttext .= '</ul>';              $resulttext .= '</ul>';
         } else {          } else {
             $resulttext = &mt('No changes made to auto-enrollment settings');              $resulttext = &mt('No changes made to auto-enrollment settings');
Line 8210  sub modify_usercreation { Line 9816  sub modify_usercreation {
                 if (ref($domconfig{'usercreation'}{$key}) eq 'HASH') {                  if (ref($domconfig{'usercreation'}{$key}) eq 'HASH') {
                     foreach my $item (keys(%{$domconfig{'usercreation'}{$key}})) {                      foreach my $item (keys(%{$domconfig{'usercreation'}{$key}})) {
                         if (($item eq 'selfcreate') || ($item eq 'statustocreate') ||                          if (($item eq 'selfcreate') || ($item eq 'statustocreate') ||
                             ($item eq 'captcha') || ($item eq 'recaptchakeys')) {                              ($item eq 'captcha') || ($item eq 'recaptchakeys') ||
                               ($item eq 'recaptchaversion')) {
                             $save_usercreate{$key}{$item} = $domconfig{'usercreation'}{$key}{$item};                              $save_usercreate{$key}{$item} = $domconfig{'usercreation'}{$key}{$item};
                         } else {                          } else {
                             $curr_usercreation{$key}{$item} = $domconfig{'usercreation'}{$key}{$item};                              $curr_usercreation{$key}{$item} = $domconfig{'usercreation'}{$key}{$item};
Line 8434  sub modify_selfcreation { Line 10041  sub modify_selfcreation {
                     foreach my $item (keys(%{$domconfig{'usercreation'}{$key}})) {                      foreach my $item (keys(%{$domconfig{'usercreation'}{$key}})) {
                         if (($item eq 'selfcreate') || ($item eq 'statustocreate') ||                          if (($item eq 'selfcreate') || ($item eq 'statustocreate') ||
                             ($item eq 'captcha') || ($item eq 'recaptchakeys') ||                               ($item eq 'captcha') || ($item eq 'recaptchakeys') || 
                               ($item eq 'recaptchaversion') ||
                             ($item eq 'emailusername') || ($item eq 'notify') ||                              ($item eq 'emailusername') || ($item eq 'notify') ||
                             ($item eq 'selfcreateprocessing') || ($item eq 'shibenv')) {                              ($item eq 'selfcreateprocessing') || ($item eq 'shibenv')) {
                             $curr_usercreation{$key}{$item} = $domconfig{'usercreation'}{$key}{$item};                              $curr_usercreation{$key}{$item} = $domconfig{'usercreation'}{$key}{$item};
Line 8763  sub modify_selfcreation { Line 10371  sub modify_selfcreation {
 #  #
     $save_usercreate{'cancreate'}{'captcha'} = $savecaptcha{'captcha'};      $save_usercreate{'cancreate'}{'captcha'} = $savecaptcha{'captcha'};
     $save_usercreate{'cancreate'}{'recaptchakeys'} = $savecaptcha{'recaptchakeys'};      $save_usercreate{'cancreate'}{'recaptchakeys'} = $savecaptcha{'recaptchakeys'};
       $save_usercreate{'cancreate'}{'recaptchaversion'} = $savecaptcha{'recaptchaversion'};
     $save_usercreate{'cancreate'}{'selfcreate'} = $cancreate{'selfcreate'};      $save_usercreate{'cancreate'}{'selfcreate'} = $cancreate{'selfcreate'};
     if (ref($cancreate{'notify'}) eq 'HASH') {      if (ref($cancreate{'notify'}) eq 'HASH') {
         $save_usercreate{'cancreate'}{'notify'} = $cancreate{'notify'};          $save_usercreate{'cancreate'}{'notify'} = $cancreate{'notify'};
Line 8924  sub modify_selfcreation { Line 10533  sub modify_selfcreation {
                             $chgtext .= '<li>'.&mt('Private key set to [_1]',$pubkey).'</li>';                              $chgtext .= '<li>'.&mt('Private key set to [_1]',$pubkey).'</li>';
                         }                          }
                         $chgtext .= '</ul>';                          $chgtext .= '</ul>';
                       } elsif ($type eq 'recaptchaversion') {
                           if ($savecaptcha{'captcha'} eq 'recaptcha') {
                               $chgtext .= &mt('ReCAPTCHA set to version [_1]',$savecaptcha{$type});
                           }
                     } elsif ($type eq 'emailusername') {                      } elsif ($type eq 'emailusername') {
                         if (ref($cancreate{'emailusername'}) eq 'HASH') {                          if (ref($cancreate{'emailusername'}) eq 'HASH') {
                             if (ref($types) eq 'ARRAY') {                              if (ref($types) eq 'ARRAY') {
                                 foreach my $type (@{$types}) {                                  foreach my $type (@{$types}) {
                                     if (ref($cancreate{'emailusername'}{$type}) eq 'HASH') {                                      if (ref($cancreate{'emailusername'}{$type}) eq 'HASH') {
                                         if (keys(%{$cancreate{'emailusername'}{$type}}) > 0) {                                          if (keys(%{$cancreate{'emailusername'}{$type}}) > 0) {
                                             $chgtext .= &mt('When self-creating account with e-mail as username, the following information will be provided by [_1]:',$usertypes->{$type}).                                              $chgtext .= &mt('When self-creating account with e-mail as username, the following information will be provided by [_1]:',"'$usertypes->{$type}'").
                                                     '<ul>';                                                      '<ul>';
                                             foreach my $field (@{$infofields}) {                                              foreach my $field (@{$infofields}) {
                                                 if ($cancreate{'emailusername'}{$type}{$field}) {                                                  if ($cancreate{'emailusername'}{$type}{$field}) {
                                                     $chgtext .= '<li>'.$infotitles->{$field}.'</li>';                                                      $chgtext .= '<li>'.$infotitles->{$field}.'</li>';
                                                 }                                                  }
                                             }                                              }
                                               $chgtext .= '</ul>';
                                           } else {
                                               $chgtext .= &mt('When self creating account with e-mail as username, no information besides e-mail address will be provided by [_1].',"'$usertypes->{$type}'").'<br />';
                                         }                                          }
                                         $chgtext .= '</ul>';  
                                     } else {                                      } else {
                                         $chgtext .= &mt('When self creating account with e-mail as username, no information besides e-mail address will be provided by [_1].',$usertypes->{$type}).'<br />';                                          $chgtext .= &mt('When self creating account with e-mail as username, no information besides e-mail address will be provided by [_1].',"'$usertypes->{$type}'").'<br />';
                                     }                                      }
                                 }                                  }
                             }                              }
Line 9042  sub process_captcha { Line 10657  sub process_captcha {
             $changes->{'captcha'} = 1;              $changes->{'captcha'} = 1;
         }          }
     }      }
     my ($newpub,$newpriv,$currpub,$currpriv);      my ($newpub,$newpriv,$currpub,$currpriv,$newversion,$currversion);
     if ($newsettings->{'captcha'} eq 'recaptcha') {      if ($newsettings->{'captcha'} eq 'recaptcha') {
         $newpub = $env{'form.'.$container.'_recaptchapub'};          $newpub = $env{'form.'.$container.'_recaptchapub'};
         $newpriv = $env{'form.'.$container.'_recaptchapriv'};          $newpriv = $env{'form.'.$container.'_recaptchapriv'};
         $newpub =~ s/\W//g;          $newpub =~ s/[^\w\-]//g;
         $newpriv =~ s/\W//g;          $newpriv =~ s/[^\w\-]//g;
         $newsettings->{'recaptchakeys'} = {          $newsettings->{'recaptchakeys'} = {
                                              public  => $newpub,                                               public  => $newpub,
                                              private => $newpriv,                                               private => $newpriv,
                                           };                                            };
           $newversion = $env{'form.'.$container.'_recaptchaversion'};
           $newversion =~ s/\D//g;
           if ($newversion ne '2') {
               $newversion = 1;
           }
           $newsettings->{'recaptchaversion'} = $newversion;
     }      }
     if (ref($current->{'recaptchakeys'}) eq 'HASH') {      if (ref($current->{'recaptchakeys'}) eq 'HASH') {
         $currpub = $current->{'recaptchakeys'}{'public'};          $currpub = $current->{'recaptchakeys'}{'public'};
Line 9063  sub process_captcha { Line 10684  sub process_captcha {
                                               }                                                }
         }          }
     }      }
       if ($current->{'captcha'} eq 'recaptcha') {
           $currversion = $current->{'recaptchaversion'};
           if ($currversion ne '2') {
               $currversion = 1;
           }
       }
       if ($currversion ne $newversion) {
           if ($container eq 'cancreate') {
               if (ref($changes->{'cancreate'}) eq 'ARRAY') {
                   push(@{$changes->{'cancreate'}},'recaptchaversion');
               } elsif (!defined($changes->{'cancreate'})) {
                   $changes->{'cancreate'} = ['recaptchaversion'];
               }
           } else {
               $changes->{'recaptchaversion'} = 1;
           }
       }
     if (($newpub ne $currpub) || ($newpriv ne $currpriv)) {      if (($newpub ne $currpub) || ($newpriv ne $currpriv)) {
         if ($container eq 'cancreate') {          if ($container eq 'cancreate') {
             if (ref($changes->{'cancreate'}) eq 'ARRAY') {              if (ref($changes->{'cancreate'}) eq 'ARRAY') {
Line 9528  sub modify_coursecategories { Line 11166  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 9542  sub modify_coursecategories { Line 11189  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 9564  sub modify_coursecategories { Line 11215  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 9626  sub modify_coursecategories { Line 11280  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 9747  sub modify_coursecategories { Line 11415  sub modify_coursecategories {
             }              }
             $resulttext .= '</ul>';              $resulttext .= '</ul>';
             if ($changes{'unauth'} || $changes{'auth'}) {              if ($changes{'unauth'} || $changes{'auth'}) {
                 &Apache::loncommon::devalidate_domconfig_cache($dom);                  my %domdefaults = &Apache::lonnet::get_domain_defaults($dom);
                   if ($changes{'auth'}) {
                       $domdefaults{'catauth'} = $domconfig{'coursecategories'}{'auth'};
                   }
                   if ($changes{'unauth'}) {
                       $domdefaults{'catunauth'} = $domconfig{'coursecategories'}{'unauth'};
                   }
                   my $cachetime = 24*60*60;
                   &Apache::lonnet::do_cache_new('domdefaults',$dom,\%domdefaults,$cachetime);
                 if (ref($lastactref) eq 'HASH') {                  if (ref($lastactref) eq 'HASH') {
                     $lastactref->{'domainconfig'} = 1;                      $lastactref->{'domdefaults'} = 1;
                 }                  }
             }              }
         } else {          } else {
Line 9946  sub modify_helpsettings { Line 11622  sub modify_helpsettings {
 sub modify_coursedefaults {  sub modify_coursedefaults {
     my ($dom,$lastactref,%domconfig) = @_;      my ($dom,$lastactref,%domconfig) = @_;
     my ($resulttext,$errors,%changes,%defaultshash);      my ($resulttext,$errors,%changes,%defaultshash);
     my %defaultchecked = ('canuse_pdfforms' => 'off');      my %defaultchecked = (
     my @toggles = ('canuse_pdfforms');                             'canuse_pdfforms' => 'off',
                              'uselcmath'       => 'on',
                              'usejsme'         => 'on'
                            );
       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');                     'uploadquota_community','uploadquota_textbook','uploadquota_placement');
     my @types = ('official','unofficial','community','textbook');      my @types = ('official','unofficial','community','textbook','placement');
     my %staticdefaults = (      my %staticdefaults = (
                            anonsurvey_threshold => 10,                             anonsurvey_threshold => 10,
                            uploadquota          => 500,                             uploadquota          => 500,
                              postsubmit           => 60,
                          );                           );
   
     $defaultshash{'coursedefaults'} = {};      $defaultshash{'coursedefaults'} = {};
Line 10014  sub modify_coursedefaults { Line 11695  sub modify_coursedefaults {
                 }                  }
             }              }
         }          }
           my $currclone = $domconfig{'coursedefaults'}{'canclone'};
         my $officialcreds = $env{'form.official_credits'};          my @currclonecode;
         $officialcreds =~ s/[^\d.]+//g;          if (ref($currclone) eq 'HASH') {
         my $unofficialcreds = $env{'form.unofficial_credits'};              if (ref($currclone->{'instcode'}) eq 'ARRAY') {
         $unofficialcreds =~ s/[^\d.]+//g;                  @currclonecode = @{$currclone->{'instcode'}};
         my $textbookcreds = $env{'form.textbook_credits'};              }
         $textbookcreds =~ s/[^\d.]+//g;          }
         if (ref($domconfig{'coursedefaults'}{'coursecredits'} ne 'HASH') &&          my $newclone;
                 ($env{'form.coursecredits'} eq '1')) {          if ($env{'form.canclone'} =~ /^(none|domain|instcode)$/) { 
                 $changes{'coursecredits'} = 1;              $newclone = $env{'form.canclone'};
         } else {          }
             if (($domconfig{'coursedefaults'}{'coursecredits'}{'official'} ne $officialcreds)  ||          if ($newclone eq 'instcode') {
                 ($domconfig{'coursedefaults'}{'coursecredits'}{'unofficial'} ne $unofficialcreds) ||              my @newcodes = &Apache::loncommon::get_env_multiple('form.clonecode');
                 ($domconfig{'coursedefaults'}{'coursecredits'}{'textbook'} ne $textbookcreds)) {              my (%codedefaults,@code_order,@clonecode);
                 $changes{'coursecredits'} = 1;              &Apache::lonnet::auto_instcode_defaults($dom,\%codedefaults,
             }                                                      \@code_order);
         }              foreach my $item (@code_order) {
         $defaultshash{'coursedefaults'}{'coursecredits'} = {                  if (grep(/^\Q$item\E$/,@newcodes)) {
             official   => $officialcreds,                      push(@clonecode,$item);
             unofficial => $unofficialcreds,                  }
             textbook   => $textbookcreds,              }
               if (@clonecode) {
                   $defaultshash{'coursedefaults'}{'canclone'} = { $newclone => \@clonecode };
                   my @diffs = &Apache::loncommon::compare_arrays(\@currclonecode,\@clonecode);
                   if (@diffs) {
                       $changes{'canclone'} = 1;
                   }
               } else {
                   $newclone eq '';
               }
           } elsif ($newclone ne '') {
               $defaultshash{'coursedefaults'}{'canclone'} = $newclone; 
           } 
           if ($newclone ne $currclone) {
               $changes{'canclone'} = 1;
           }
           my %credits;
           foreach my $type (@types) {
               unless ($type eq 'community') {
                   $credits{$type} = $env{'form.'.$type.'_credits'};
                   $credits{$type} =~ s/[^\d.]+//g;
               }
           }
           if ((ref($domconfig{'coursedefaults'}{'coursecredits'}) ne 'HASH') &&
               ($env{'form.coursecredits'} eq '1')) {
               $changes{'coursecredits'} = 1;
               foreach my $type (keys(%credits)) {
                   $defaultshash{'coursedefaults'}{'coursecredits'}{$type} = $credits{$type};
               }
           } else {
               if ($env{'form.coursecredits'} eq '1') { 
                   foreach my $type (@types) {
                       unless ($type eq 'community') {
                           if ($domconfig{'coursedefaults'}{'coursecredits'}{$type} ne $credits{$type}) {        
                               $changes{'coursecredits'} = 1;
                           }
                           $defaultshash{'coursedefaults'}{'coursecredits'}{$type} = $credits{$type};
                       }
                   }
               } elsif (ref($domconfig{'coursedefaults'}{'coursecredits'}) eq 'HASH') {
                   foreach my $type (@types) {
                       unless ($type eq 'community') {
                           if ($domconfig{'coursedefaults'}{'coursecredits'}{$type}) {
                               $changes{'coursecredits'} = 1;
                               last;
                           }
                       }
                   }
               }
           }
           if ($env{'form.postsubmit'} eq '1') {
               $defaultshash{'coursedefaults'}{'postsubmit'}{'client'} = 'on';
               my %currtimeout;
               if (ref($domconfig{'coursedefaults'}{'postsubmit'}) eq 'HASH') {
                   if ($domconfig{'coursedefaults'}{'postsubmit'}{'client'} eq 'off') {
                       $changes{'postsubmit'} = 1;
                   }
                   if (ref($domconfig{'coursedefaults'}{'postsubmit'}{'timeout'}) eq 'HASH') {
                       %currtimeout = %{$domconfig{'coursedefaults'}{'postsubmit'}{'timeout'}};
                   }
               } else {
                   $changes{'postsubmit'} = 1;
               }
               foreach my $type (@types) {
                   my $timeout = $env{'form.'.$type.'_timeout'};
                   $timeout =~ s/\D//g;
                   if ($timeout == $staticdefaults{'postsubmit'}) {
                       $timeout = '';
                   } elsif (($timeout eq '') || ($timeout =~ /^0+$/)) {
                       $timeout = '0';
                   }
                   unless ($timeout eq '') {
                       $defaultshash{'coursedefaults'}{'postsubmit'}{'timeout'}{$type} = $timeout;
                   }
                   if (exists($currtimeout{$type})) {
                       if ($timeout ne $currtimeout{$type}) {
                           $changes{'postsubmit'} = 1; 
                       }
                   } elsif ($timeout ne '') {
                       $changes{'postsubmit'} = 1;
                   }
               }
           } else {
               $defaultshash{'coursedefaults'}{'postsubmit'}{'client'} = 'off';
               if (ref($domconfig{'coursedefaults'}{'postsubmit'}) eq 'HASH') {
                   if ($domconfig{'coursedefaults'}{'postsubmit'}{'client'} eq 'on') {
                       $changes{'postsubmit'} = 1;
                   }
               } else {
                   $changes{'postsubmit'} = 1;
               }
         }          }
     }      }
     my $putresult = &Apache::lonnet::put_dom('configuration',\%defaultshash,      my $putresult = &Apache::lonnet::put_dom('configuration',\%defaultshash,
Line 10042  sub modify_coursedefaults { Line 11813  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{'canuse_pdfforms'}) || ($changes{'coursecredits'}) ||               if (($changes{'canuse_pdfforms'}) || ($changes{'uploadquota'}) || ($changes{'postsubmit'}) ||
                 ($changes{'uploadquota'})) {                   ($changes{'coursecredits'}) || ($changes{'uselcmath'}) || ($changes{'usejsme'}) ||
                 if ($changes{'canuse_pdfforms'}) {                  ($changes{'canclone'})) {
                     $domdefaults{'canuse_pdfforms'}=$defaultshash{'coursedefaults'}{'canuse_pdfforms'};                  foreach my $item ('canuse_pdfforms','uselcmath','usejsme') { 
                 }                      if ($changes{$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') {
                         $domdefaults{'officialcredits'} =                          foreach my $type (keys(%{$defaultshash{'coursedefaults'}{'coursecredits'}})) {
                             $defaultshash{'coursedefaults'}{'coursecredits'}{'official'};                              $domdefaults{$type.'credits'} =
                         $domdefaults{'unofficialcredits'} =                                  $defaultshash{'coursedefaults'}{'coursecredits'}{$type};
                             $defaultshash{'coursedefaults'}{'coursecredits'}{'unofficial'};                          }
                         $domdefaults{'textbookcredits'} =                      }
                             $domdefaults{'coursedefaults'}{'coursecredits'}{'textbook'};                  }
                   if ($changes{'postsubmit'}) {
                       if (ref($defaultshash{'coursedefaults'}{'postsubmit'}) eq 'HASH') {
                           $domdefaults{'postsubmit'} = $defaultshash{'coursedefaults'}{'postsubmit'}{'client'};
                           if (ref($defaultshash{'coursedefaults'}{'postsubmit'}{'timeout'}) eq 'HASH') {
                               foreach my $type (keys(%{$defaultshash{'coursedefaults'}{'postsubmit'}{'timeout'}})) {
                                   $domdefaults{$type.'postsubtimeout'} =
                                       $defaultshash{'coursedefaults'}{'postsubmit'}{'timeout'}{$type};
                               }
                           }
                     }                      }
                 }                  }
                 if ($changes{'uploadquota'}) {                  if ($changes{'uploadquota'}) {
Line 10064  sub modify_coursedefaults { Line 11847  sub modify_coursedefaults {
                         }                          }
                     }                      }
                 }                  }
                   if ($changes{'canclone'}) {
                       if (ref($defaultshash{'coursedefaults'}{'canclone'}) eq 'HASH') {
                           if (ref($defaultshash{'coursedefaults'}{'canclone'}{'instcode'}) eq 'ARRAY') {
                               my @clonecodes = @{$defaultshash{'coursedefaults'}{'canclone'}{'instcode'}};
                               if (@clonecodes) {
                                   $domdefaults{'canclone'} = join('+',@clonecodes);
                               }
                           }
                       } else {
                           $domdefaults{'canclone'}=$defaultshash{'coursedefaults'}{'canclone'};
                       }
                   }
                 my $cachetime = 24*60*60;                  my $cachetime = 24*60*60;
                 &Apache::lonnet::do_cache_new('domdefaults',$dom,\%domdefaults,$cachetime);                  &Apache::lonnet::do_cache_new('domdefaults',$dom,\%domdefaults,$cachetime);
                 if (ref($lastactref) eq 'HASH') {                  if (ref($lastactref) eq 'HASH') {
Line 10078  sub modify_coursedefaults { Line 11873  sub modify_coursedefaults {
                     } else {                      } else {
                         $resulttext .= '<li>'.&mt('Course/Community users can create/upload PDF forms set to "off"').'</li>';                          $resulttext .= '<li>'.&mt('Course/Community users can create/upload PDF forms set to "off"').'</li>';
                     }                      }
                   } elsif ($item eq 'uselcmath') {
                       if ($env{'form.'.$item} eq '1') {
                           $resulttext .= '<li>'.&mt('Math preview uses LON-CAPA previewer (javascript), if supported by browser.').'</li>';
                       } else {
                           $resulttext .= '<li>'.&mt('Math preview uses DragMath (Java), if supported by client OS.').'</li>';
                       }
                   } elsif ($item eq 'usejsme') {
                       if ($env{'form.'.$item} eq '1') {
                           $resulttext .= '<li>'.&mt('Molecule editor uses JSME (HTML5), if supported by browser.').'</li>';
                       } else {
                           $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>';
                 } elsif ($item eq 'uploadquota') {                  } elsif ($item eq 'uploadquota') {
Line 10086  sub modify_coursedefaults { Line 11893  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>';
                     } else {                      } else {
                         $resulttext .= '<li>'.&mt('Default quota for content uploaded via Course Editor remains default: [_1] MB',$staticdefaults{'uploadquota'}).'</li>';                          $resulttext .= '<li>'.&mt('Default quota for content uploaded via Course Editor remains default: [_1] MB',$staticdefaults{'uploadquota'}).'</li>';
                     }                      }
                   } elsif ($item eq 'postsubmit') {
                       if ($domdefaults{'postsubmit'} eq 'off') {
                           $resulttext .= '<li>'.&mt('Submit button(s) remain enabled on page after student makes submission.');
                       } else {
                           $resulttext .= '<li>'.&mt('Submit button(s) disabled on page after student makes submission').'; ';
                           if (ref($defaultshash{'coursedefaults'}{'postsubmit'}) eq 'HASH') { 
                               $resulttext .= &mt('durations:').'<ul>';
                               foreach my $type (@types) {
                                   $resulttext .= '<li>';
                                   my $timeout;
                                   if (ref($defaultshash{'coursedefaults'}{'postsubmit'}{'timeout'}) eq 'HASH') {
                                       $timeout = $defaultshash{'coursedefaults'}{'postsubmit'}{'timeout'}{$type};
                                   }
                                   my $display;
                                   if ($timeout eq '0') {
                                       $display = &mt('unlimited');
                                   } elsif ($timeout eq '') {
                                       $display = &mt('[quant,_1,second] (default)',$staticdefaults{'postsubmit'});
                                   } else {
                                       $display = &mt('[quant,_1,second]',$timeout);
                                   }
                                   if ($type eq 'community') {
                                       $resulttext .= &mt('Communities');
                                   } elsif ($type eq 'official') {
                                       $resulttext .= &mt('Official courses');
                                   } elsif ($type eq 'unofficial') {
                                       $resulttext .= &mt('Unofficial courses');
                                   } elsif ($type eq 'textbook') {
                                       $resulttext .= &mt('Textbook courses');
                                   } elsif ($type eq 'placement') {
                                       $resulttext .= &mt('Placement tests');
                                   }
                                   $resulttext .= ' -- '.$display.'</li>';
                               }
                               $resulttext .= '</ul>';
                           }
                           $resulttext .= '</li>';    
                       }
                 } elsif ($item eq 'coursecredits') {                  } elsif ($item eq 'coursecredits') {
                     if (ref($defaultshash{'coursedefaults'}{'coursecredits'}) eq 'HASH') {                      if (ref($defaultshash{'coursedefaults'}{'coursecredits'}) eq 'HASH') {
                         if (($domdefaults{'officialcredits'} eq '') &&                          if (($domdefaults{'officialcredits'} eq '') &&
Line 10110  sub modify_coursedefaults { Line 11955  sub modify_coursedefaults {
                     } else {                      } else {
                         $resulttext .= '<li>'.&mt('Student credits not in use for courses in this domain').'</li>';                          $resulttext .= '<li>'.&mt('Student credits not in use for courses in this domain').'</li>';
                     }                      }
                   } elsif ($item eq 'canclone') {
                       if (ref($defaultshash{'coursedefaults'}{'canclone'}) eq 'HASH') {
                           if (ref($defaultshash{'coursedefaults'}{'canclone'}{'instcode'}) eq 'ARRAY') {
                               my $clonecodes = join(' '.&mt('and').' ',@{$defaultshash{'coursedefaults'}{'canclone'}{'instcode'}});
                               $resulttext .= '<li>'.&mt('By default, official courses can be cloned from existing courses with the same: [_1]','<b>'.$clonecodes.'</b>').'</li>';
                           }
                       } elsif ($defaultshash{'coursedefaults'}{'canclone'} eq 'domain') {
                           $resulttext .= '<li>'.&mt('By default, a course requester can clone any course from his/her domain.').'</li>';
                       } else {
                           $resulttext .= '<li>'.&mt('By default, only course owner and coordinators may clone a course.').'</li>'; 
                       }
                 }                  }
             }              }
             $resulttext .= '</ul>';              $resulttext .= '</ul>';
Line 10126  sub modify_coursedefaults { Line 11982  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 10373  sub modify_usersessions { Line 12229  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 10528  sub modify_usersessions { Line 12384  sub modify_usersessions {
             $changes{'spares'}{$lonhost} = \%spareschg;              $changes{'spares'}{$lonhost} = \%spareschg;
         }          }
     }      }
       $defaultshash{'usersessions'}{'offloadnow'} = {};
       my @offloadnow = &Apache::loncommon::get_env_multiple('form.offloadnow');
       my @okoffload;
       if (@offloadnow) {
           foreach my $server (@offloadnow) {
               if (&Apache::lonnet::hostname($server) ne '') {
                   unless (grep(/^\Q$server\E$/,@okoffload)) {
                       push(@okoffload,$server);
                   }
               }
           }
           if (@okoffload) {
               foreach my $lonhost (@okoffload) {
                   $defaultshash{'usersessions'}{'offloadnow'}{$lonhost} = 1;
               }
           }
       }
     if (ref($domconfig{'usersessions'}) eq 'HASH') {      if (ref($domconfig{'usersessions'}) eq 'HASH') {
         if (ref($domconfig{'usersessions'}{'spares'}) eq 'HASH') {          if (ref($domconfig{'usersessions'}{'spares'}) eq 'HASH') {
             if (ref($changes{'spares'}) eq 'HASH') {              if (ref($changes{'spares'}) eq 'HASH') {
Line 10539  sub modify_usersessions { Line 12411  sub modify_usersessions {
         } else {          } else {
             $savespares = 1;              $savespares = 1;
         }          }
           if (ref($domconfig{'usersessions'}{'offloadnow'}) eq 'HASH') {
               foreach my $lonhost (keys(%{$domconfig{'usersessions'}{'offloadnow'}})) {
                   unless ($defaultshash{'usersessions'}{'offloadnow'}{$lonhost}) {
                       $changes{'offloadnow'} = 1;
                       last;
                   }
               }
               unless ($changes{'offloadnow'}) {
                   foreach my $lonhost (keys(%{$defaultshash{'usersessions'}{'offloadnow'}})) { 
                       unless ($domconfig{'usersessions'}{'offloadnow'}{$lonhost}) {
                           $changes{'offloadnow'} = 1;
                           last;
                       }
                   }
               }
           } elsif (@okoffload) {
               $changes{'offloadnow'} = 1;
           }
       } elsif (@okoffload) {
           $changes{'offloadnow'} = 1;
     }      }
   
     my $nochgmsg = &mt('No changes made to settings for user session hosting/offloading.');      my $nochgmsg = &mt('No changes made to settings for user session hosting/offloading.');
     if ((keys(%changes) > 0) || ($savespares)) {      if ((keys(%changes) > 0) || ($savespares)) {
         my $putresult = &Apache::lonnet::put_dom('configuration',\%defaultshash,          my $putresult = &Apache::lonnet::put_dom('configuration',\%defaultshash,
Line 10553  sub modify_usersessions { Line 12444  sub modify_usersessions {
                 if (ref($defaultshash{'usersessions'}{'hosted'}) eq 'HASH') {                  if (ref($defaultshash{'usersessions'}{'hosted'}) eq 'HASH') {
                     $domdefaults{'hostedsessions'} = $defaultshash{'usersessions'}{'hosted'};                      $domdefaults{'hostedsessions'} = $defaultshash{'usersessions'}{'hosted'};
                 }                  }
                   if (ref($defaultshash{'usersessions'}{'offloadnow'}) eq 'HASH') {
                       $domdefaults{'offloadnow'} = $defaultshash{'usersessions'}{'offloadnow'};
                   }
             }              }
             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);
Line 10621  sub modify_usersessions { Line 12515  sub modify_usersessions {
                         $resulttext .= '</ul>';                          $resulttext .= '</ul>';
                     }                      }
                 }                  }
                   if ($changes{'offloadnow'}) {
                       if (ref($defaultshash{'usersessions'}{'offloadnow'}) eq 'HASH') {
                           if (keys(%{$defaultshash{'usersessions'}{'offloadnow'}}) > 0) {
                               $resulttext .= '<li>'.&mt('Switch active users on next access, for server(s):').'<ul>';
                               foreach my $lonhost (sort(keys(%{$defaultshash{'usersessions'}{'offloadnow'}}))) {
                                   $resulttext .= '<li>'.$lonhost.'</li>';
                               }
                               $resulttext .= '</ul>';
                           } else {
                               $resulttext .= '<li>'.&mt('No servers now set to switch active users on next access.');
                           }
                       } else {
                           $resulttext .= '<li>'.&mt('No servers now set to switch active users on next access.').'</li>';
                       }
                   }
                 $resulttext .= '</ul>';                  $resulttext .= '</ul>';
             } else {              } else {
                 $resulttext = $nochgmsg;                  $resulttext = $nochgmsg;
Line 10635  sub modify_usersessions { Line 12544  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,
                   );
       my $action = 'ssl';
       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_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 10642  sub modify_loadbalancing { Line 12716  sub modify_loadbalancing {
     my ($othertitle,$usertypes,$types) =      my ($othertitle,$usertypes,$types) =
         &Apache::loncommon::sorted_inst_types($dom);          &Apache::loncommon::sorted_inst_types($dom);
     my %servers = &Apache::lonnet::internet_dom_servers($dom);      my %servers = &Apache::lonnet::internet_dom_servers($dom);
       my %libraryservers = &Apache::lonnet::get_servers($dom,'library');
     my @sparestypes = ('primary','default');      my @sparestypes = ('primary','default');
     my %typetitles = &sparestype_titles();      my %typetitles = &sparestype_titles();
     my $resulttext;      my $resulttext;
Line 10733  sub modify_loadbalancing { Line 12808  sub modify_loadbalancing {
                     $rule = $env{'form.loadbalancing_rules_'.$i.'_'.$type};                      $rule = $env{'form.loadbalancing_rules_'.$i.'_'.$type};
                 }                  }
                 if ($rule eq 'specific') {                  if ($rule eq 'specific') {
                     $rule = $env{'form.loadbalancing_singleserver_'.$i.'_'.$type};                      my $specifiedhost = $env{'form.loadbalancing_singleserver_'.$i.'_'.$type};
                       if (exists($servers{$specifiedhost})) { 
                           $rule = $specifiedhost;
                       }
                 }                  }
                 $defaultshash{'loadbalancing'}{$balancer}{'rules'}{$type} = $rule;                  $defaultshash{'loadbalancing'}{$balancer}{'rules'}{$type} = $rule;
                 if (ref($currrules{$balancer}) eq 'HASH') {                  if (ref($currrules{$balancer}) eq 'HASH') {
Line 10755  sub modify_loadbalancing { Line 12833  sub modify_loadbalancing {
                                                  \%defaultshash,$dom);                                                   \%defaultshash,$dom);
         if ($putresult eq 'ok') {          if ($putresult eq 'ok') {
             if (keys(%changes) > 0) {              if (keys(%changes) > 0) {
                   my %toupdate;
                 if (ref($changes{'delete'}) eq 'ARRAY') {                  if (ref($changes{'delete'}) eq 'ARRAY') {
                     foreach my $balancer (sort(@{$changes{'delete'}})) {                      foreach my $balancer (sort(@{$changes{'delete'}})) {
                         $resulttext .= '<li>'.&mt('Load Balancing discontinued for: [_1]',$balancer).'</li>';                          $resulttext .= '<li>'.&mt('Load Balancing discontinued for: [_1]',$balancer).'</li>';
                         my $cachekey = &escape('loadbalancing').':'.&escape($dom);                          $toupdate{$balancer} = 1;
                         &Apache::lonnet::remote_devalidate_cache($balancer,[$cachekey]);  
                     }                      }
                 }                  }
                 if (ref($changes{'add'}) eq 'ARRAY') {                  if (ref($changes{'add'}) eq 'ARRAY') {
                     foreach my $balancer (sort(@{$changes{'add'}})) {                      foreach my $balancer (sort(@{$changes{'add'}})) {
                         $resulttext .= '<li>'.&mt('Load Balancing enabled for: [_1]',$balancer);                          $resulttext .= '<li>'.&mt('Load Balancing enabled for: [_1]',$balancer);
                           $toupdate{$balancer} = 1;
                     }                      }
                 }                  }
                 if (ref($changes{'curr'}) eq 'HASH') {                  if (ref($changes{'curr'}) eq 'HASH') {
                     foreach my $balancer (sort(keys(%{$changes{'curr'}}))) {                      foreach my $balancer (sort(keys(%{$changes{'curr'}}))) {
                           $toupdate{$balancer} = 1;
                         if (ref($changes{'curr'}{$balancer}) eq 'HASH') {                          if (ref($changes{'curr'}{$balancer}) eq 'HASH') {
                             if ($changes{'curr'}{$balancer}{'targets'}) {                              if ($changes{'curr'}{$balancer}{'targets'}) {
                                 my %offloadstr;                                  my %offloadstr;
Line 10805  sub modify_loadbalancing { Line 12885  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') ||
                                                  ($rule eq 'balancer') || ($rule eq 'offloadedto')) {                                                   ($type eq '_LC_ipchange') || ($type eq '_LC_ipchangesso')) { 
                                             $balancetext =  $ruletitles{$rule};                                              if (($type eq '_LC_ipchange') || ($type eq '_LC_ipchangesso')) {
                                                   foreach my $sparetype (@sparestypes) {
                                                       if (ref($defaultshash{'loadbalancing'}{$balancer}{'targets'}{$sparetype}) eq 'ARRAY') {
                                                           map { $toupdate{$_} = 1; } (@{$defaultshash{'loadbalancing'}{$balancer}{'targets'}{$sparetype}});
                                                       }
                                                   }
                                                   foreach my $item (@{$alltypes}) {
                                                       next if ($item =~  /^_LC_ipchange/);
                                                       my $hasrule = $defaultshash{'loadbalancing'}{$balancer}{'rules'}{$item};
                                                       if ($hasrule eq 'homeserver') {
                                                           map { $toupdate{$_} = 1; } (keys(%libraryservers));
                                                       } else {
                                                           unless (($hasrule eq 'default') || ($hasrule eq 'none') || ($hasrule eq 'externalbalancer')) {
                                                               if ($servers{$hasrule}) {
                                                                   $toupdate{$hasrule} = 1;
                                                               }
                                                           }
                                                       }
                                                   }
                                                   if (($rule eq 'balancer') || ($rule eq 'offloadedto')) {
                                                       $balancetext =  $ruletitles{$rule};
                                                   } else {
                                                       my $receiver = $defaultshash{'loadbalancing'}{$balancer}{'rules'}{$type};
                                                       $balancetext = $ruletitles{'particular'}.' '.$receiver;
                                                       if ($receiver) {
                                                           $toupdate{$receiver};
                                                       }
                                                   }
                                               } else {
                                                   $balancetext =  $ruletitles{$rule};
                                               }
                                         } else {                                          } else {
                                             $balancetext = &mt('offload to [_1]',$defaultshash{'loadbalancing'}{$balancer}{'rules'}{$type});                                              $balancetext = &mt('offload to [_1]',$defaultshash{'loadbalancing'}{$balancer}{'rules'}{$type});
                                         }                                          }
Line 10815  sub modify_loadbalancing { Line 12925  sub modify_loadbalancing {
                                 }                                  }
                             }                              }
                         }                          }
                         my $cachekey = &escape('loadbalancing').':'.&escape($dom);                          if (keys(%toupdate)) {
                         &Apache::lonnet::remote_devalidate_cache($balancer,[$cachekey]);                              my %thismachine;
                               my $updatedhere;
                               my $cachetime = 60*60*24;
                               map { $thismachine{$_} = 1; } &Apache::lonnet::current_machine_ids();
                               foreach my $lonhost (keys(%toupdate)) {
                                   if ($thismachine{$lonhost}) {
                                       unless ($updatedhere) {
                                           &Apache::lonnet::do_cache_new('loadbalancing',$dom,
                                                                         $defaultshash{'loadbalancing'},
                                                                         $cachetime);
                                           $updatedhere = 1;
                                       }
                                   } else {
                                       my $cachekey = &escape('loadbalancing').':'.&escape($dom);
                                       &Apache::lonnet::remote_devalidate_cache($lonhost,[$cachekey]);
                                   }
                               }
                           }
                     }                      }
                 }                  }
                 if ($resulttext ne '') {                  if ($resulttext ne '') {
Line 10957  sub active_dc_picker { Line 13084  sub active_dc_picker {
         my ($dcname,$dcdom) = split(':',$domcoord[0]);          my ($dcname,$dcdom) = split(':',$domcoord[0]);
         my $user = &Apache::loncommon::plainname($dcname,$dcdom);          my $user = &Apache::loncommon::plainname($dcname,$dcdom);
         if ($inputtype eq 'radio') {          if ($inputtype eq 'radio') {
             $table .= '<input type="hidden" name="'.$name.'" value="'.$domcoord[0].'" />'.$user;              $table = '<input type="hidden" name="'.$name.'" value="'.$domcoord[0].'" />'.$user;
             if ($user ne $dcname.':'.$dcdom) {              if ($user ne $dcname.':'.$dcdom) {
                 $table .=  ' ('.$dcname.':'.$dcdom.')';                  $table .=  ' ('.$dcname.':'.$dcdom.')';
             }              }
Line 10966  sub active_dc_picker { Line 13093  sub active_dc_picker {
             if (exists($currhash{$domcoord[0]})) {              if (exists($currhash{$domcoord[0]})) {
                 $check = ' checked="checked"';                  $check = ' checked="checked"';
             }              }
             $table .= '<span class="LC_nobreak"><label>'.              $table = '<span class="LC_nobreak"><label>'.
                       '<input type="checkbox" name="'.$name.'" '.                       '<input type="checkbox" name="'.$name.'" '.
                       'value="'.$domcoord[0].'"'.$check.' />'.$user;                       'value="'.$domcoord[0].'"'.$check.' />'.$user;
             if ($user ne $dcname.':'.$dcdom) {              if ($user ne $dcname.':'.$dcdom) {
                 $table .=  ' ('.$dcname.':'.$dcdom.')';                  $table .=  ' ('.$dcname.':'.$dcdom.')';
             }              }
Line 11458  function updateCaptcha(caller,context) { Line 13585  function updateCaptcha(caller,context) {
     var pubitem;      var pubitem;
     var privtext;      var privtext;
     var pubtext;      var pubtext;
       var versionitem;
       var versiontext;
     if (document.getElementById(context+'_recaptchapub')) {      if (document.getElementById(context+'_recaptchapub')) {
         pubitem = document.getElementById(context+'_recaptchapub');          pubitem = document.getElementById(context+'_recaptchapub');
     } else {      } else {
Line 11478  function updateCaptcha(caller,context) { Line 13607  function updateCaptcha(caller,context) {
     } else {      } else {
         return;          return;
     }      }
       if (document.getElementById(context+'_recaptchaversion')) {
           versionitem = document.getElementById(context+'_recaptchaversion');
       } else {
           return;
       }
       if (document.getElementById(context+'_recaptchavertxt')) {
           versiontext = document.getElementById(context+'_recaptchavertxt');
       } else {
           return;
       }
     if (caller.checked) {      if (caller.checked) {
         if (caller.value == 'recaptcha') {          if (caller.value == 'recaptcha') {
             pubitem.type = 'text';              pubitem.type = 'text';
Line 11486  function updateCaptcha(caller,context) { Line 13625  function updateCaptcha(caller,context) {
             privitem.size = '40';              privitem.size = '40';
             pubtext.innerHTML = "$lt{'pub'}";              pubtext.innerHTML = "$lt{'pub'}";
             privtext.innerHTML = "$lt{'priv'}";              privtext.innerHTML = "$lt{'priv'}";
               versionitem.type = 'text';
               versionitem.size = '3';
               versiontext.innerHTML = "$lt{'ver'}"; 
         } else {          } else {
             pubitem.type = 'hidden';              pubitem.type = 'hidden';
             privitem.type = 'hidden';              privitem.type = 'hidden';
               versionitem.type = 'hidden';
             pubtext.innerHTML = '';              pubtext.innerHTML = '';
             privtext.innerHTML = '';              privtext.innerHTML = '';
               versiontext.innerHTML = '';
         }          }
     }      }
     return;      return;
Line 11513  function toggleDisplay(domForm,caller) { Line 13657  function toggleDisplay(domForm,caller) {
     if (document.getElementById(caller)) {      if (document.getElementById(caller)) {
         var divitem = document.getElementById(caller);          var divitem = document.getElementById(caller);
         var optionsElement = domForm.coursecredits;          var optionsElement = domForm.coursecredits;
           var checkval = 1;
           var dispval = 'block';
         if (caller == 'emailoptions') {          if (caller == 'emailoptions') {
             optionsElement = domForm.cancreate_email;               optionsElement = domForm.cancreate_email; 
         }          }
           if (caller == 'studentsubmission') {
               optionsElement = domForm.postsubmit;
           }
           if (caller == 'cloneinstcode') {
               optionsElement = domForm.canclone;
               checkval = 'instcode';
           }
         if (optionsElement.length) {          if (optionsElement.length) {
             var currval;              var currval;
             for (var i=0; i<optionsElement.length; i++) {              for (var i=0; i<optionsElement.length; i++) {
Line 11523  function toggleDisplay(domForm,caller) { Line 13676  function toggleDisplay(domForm,caller) {
                    currval = optionsElement[i].value;                     currval = optionsElement[i].value;
                 }                  }
             }              }
             if (currval == 1) {              if (currval == checkval) {
                 divitem.style.display = 'block';                  divitem.style.display = dispval;
             } else {              } else {
                 divitem.style.display = 'none';                  divitem.style.display = 'none';
             }              }
Line 11547  sub captcha_phrases { Line 13700  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)', 
     );      );
 }  }
   
Line 11556  sub devalidate_remote_domconfs { Line 13710  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');      my @posscached = ('domainconfig','domdefaults','ltitools');
     if (keys(%servers) > 1) {      if (keys(%servers)) {
         foreach my $server (keys(%servers)) {          foreach my $server (keys(%servers)) {
             next if ($thismachine{$server});              next if ($thismachine{$server});
             my @cached;              my @cached;

Removed from v.1.160.6.48  
changed lines
  Added in v.1.275


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