Diff for /loncom/interface/domainprefs.pm between versions 1.160.6.84.4.1 and 1.282

version 1.160.6.84.4.1, 2017/08/15 23:40:33 version 1.282, 2016/10/05 13:59:46
Line 19 Line 19
 #  #
 # You should have received a copy of the GNU General Public License  # You should have received a copy of the GNU General Public License
 # along with LON-CAPA; if not, write to the Free Software  # along with LON-CAPA; if not, write to the Free Software
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA  # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA#
 #  
 # /home/httpd/html/adm/gpl.txt  # /home/httpd/html/adm/gpl.txt
 #  #
 # http://www.lon-capa.org/  # http://www.lon-capa.org/
Line 104  $datatable  - HTML containing form eleme Line 103  $datatable  - HTML containing form eleme
   
 In the case of course requests, radio buttons are displayed for each institutional  In the case of course requests, radio buttons are displayed for each institutional
 affiliate type (and also default, and _LC_adv) for each of the course types   affiliate type (and also default, and _LC_adv) for each of the course types 
 (official, unofficial, community, and textbook).  In each case the radio buttons   (official, unofficial, community, textbook, and placement).  
 allow the selection of one of four values:  In each case the radio buttons allow the selection of one of four values:  
   
 0, approval, validate, autolimit=N (where N is blank, or a positive integer).  0, approval, validate, autolimit=N (where N is blank, or a positive integer).
 which have the following effects:  which have the following effects:
Line 170  use Apache::loncoursequeueadmin(); Line 169  use Apache::loncoursequeueadmin();
 use LONCAPA qw(:DEFAULT :match);  use LONCAPA qw(:DEFAULT :match);
 use LONCAPA::Enrollment;  use LONCAPA::Enrollment;
 use LONCAPA::lonauthcgi();  use LONCAPA::lonauthcgi();
   use LONCAPA::SSL;
 use File::Copy;  use File::Copy;
 use Locale::Language;  use Locale::Language;
 use DateTime::TimeZone;  use DateTime::TimeZone;
 use DateTime::Locale;  use DateTime::Locale;
   use Time::HiRes qw( sleep );
   
 my $registered_cleanup;  my $registered_cleanup;
 my $modified_urls;  my $modified_urls;
Line 216  sub handler { Line 217  sub handler {
                 'contacts','defaults','scantron','coursecategories',                  'contacts','defaults','scantron','coursecategories',
                 'serverstatuses','requestcourses','helpsettings',                  'serverstatuses','requestcourses','helpsettings',
                 'coursedefaults','usersessions','loadbalancing',                  'coursedefaults','usersessions','loadbalancing',
                 'requestauthor','selfenrollment','inststatus'],$dom);                  'requestauthor','selfenrollment','inststatus',
                   'ltitools','ssl','trust'],$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','helpsettings','coursedefaults',                         'serverstatuses','helpsettings','coursedefaults',
                        'selfenrollment','usersessions');                         'ltitools','selfenrollment','usersessions','ssl','trust');
     my %existing;      my %existing;
     if (ref($domconfig{'loadbalancing'}) eq 'HASH') {      if (ref($domconfig{'loadbalancing'}) eq 'HASH') {
         %existing = %{$domconfig{'loadbalancing'}};          %existing = %{$domconfig{'loadbalancing'}};
Line 262  sub handler { Line 264  sub handler {
                       help => 'Domain_Configuration_LangTZAuth',                        help => 'Domain_Configuration_LangTZAuth',
                       header => [{col1 => 'Setting',                        header => [{col1 => 'Setting',
                                   col2 => 'Value'},                                    col2 => 'Value'},
                                  {col1 => 'Internal Authentication',  
                                   col2 => 'Value'},  
                                  {col1 => 'Institutional user types',                                   {col1 => 'Institutional user types',
                                   col2 => 'Name displayed'}],                                    col2 => 'Assignable to e-mail usernames'}],
                       print => \&print_defaults,                        print => \&print_defaults,
                       modify => \&modify_defaults,                        modify => \&modify_defaults,
                     },                      },
Line 317  sub handler { Line 317  sub handler {
                     modify => \&modify_directorysrch,                      modify => \&modify_directorysrch,
                   },                    },
         'contacts' =>          'contacts' =>
                   { text => 'E-mail addresses and helpform',                    { text => 'Contact Information',
                     help => 'Domain_Configuration_Contact_Info',                      help => 'Domain_Configuration_Contact_Info',
                     header => [{col1 => 'Default e-mail addresses',                      header => [{col1 => 'Setting',
                                 col2 => 'Value',},                                  col2 => 'Value',}],
                                {col1 => 'Recipient(s) for notifications',  
                                 col2 => 'Value',},  
                                {col1 => 'Ask helpdesk form settings',  
                                 col2 => 'Value',},],  
                     print => \&print_contacts,                      print => \&print_contacts,
                     modify => \&modify_contacts,                      modify => \&modify_contacts,
                   },                    },
Line 347  sub handler { Line 343  sub handler {
                                 col2 => 'Enabled?'},                                  col2 => 'Enabled?'},
                                {col1 => 'Institutional user type (login/SSO self-creation)',                                 {col1 => 'Institutional user type (login/SSO self-creation)',
                                 col2 => 'Information user can enter'},                                  col2 => 'Information user can enter'},
                                {col1 => 'Self-creation with e-mail verification',                                 {col1 => 'Self-creation with e-mail as username',
                                 col2 => 'Settings'}],                                  col2 => 'Settings'}],
                     print => \&print_selfcreation,                      print => \&print_selfcreation,
                     modify => \&modify_selfcreation,                      modify => \&modify_selfcreation,
Line 452  sub handler { Line 448  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 475  sub handler { Line 479  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,
                    },
           'trust' =>
                    {text   => 'Trust Settings',
                     help   => 'Domain_Configuration_Trust',
                     header => [{col1 => "Access to this domain's content by others",
                                 col2 => 'Rules'},
                                {col1 => "Access to other domain's content by this domain",
                                 col2 => 'Rules'},
                                {col1 => "Enrollment in this domain's courses by others",
                                 col2 => 'Rules',},
                                {col1 => "Co-author roles in this domain for others",
                                 col2 => 'Rules',},
                                {col1 => "Co-author roles for this domain's users elsewhere",
                                 col2 => 'Rules',},
                                {col1 => "Domain roles in this domain assignable to others",
                                 col2 => 'Rules'},
                                {col1 => "Course catalog for this domain displayed elsewhere",
                                 col2 => 'Rules'},
                                {col1 => "Requests for creation of courses in this domain by others",
                                 col2 => 'Rules'},
                                {col1 => "Users in other domains can send messages to this domain",
                                 col2 => 'Rules'},],
                     print => \&print_trust,
                     modify => \&modify_trust,
                    },
     );      );
     if (keys(%servers) > 1) {      if (keys(%servers) > 1) {
         $prefs{'login'}  = { text   => 'Log-in page options',          $prefs{'login'}  = { text   => 'Log-in page options',
Line 528  $javascript_validations Line 576  $javascript_validations
 $coursebrowserjs  $coursebrowserjs
 END  END
         }          }
         if (grep(/^selfcreation$/,@actions)) {  
             $js .= &selfcreate_javascript();  
         }  
         if (grep(/^contacts$/,@actions)) {  
             $js .= &contacts_javascript();  
         }  
         &Apache::lonconfigsettings::display_settings($r,$dom,$phase,$context,\@prefs_order,\%prefs,\%domconfig,$confname,$js);          &Apache::lonconfigsettings::display_settings($r,$dom,$phase,$context,\@prefs_order,\%prefs,\%domconfig,$confname,$js);
     } else {      } else {
 # check if domconfig user exists for the domain.  # check if domconfig user exists for the domain.
Line 623  sub process_changes { Line 665  sub process_changes {
     } elsif ($action eq 'autocreate') {      } elsif ($action eq 'autocreate') {
         $output = &modify_autocreate($dom,%domconfig);          $output = &modify_autocreate($dom,%domconfig);
     } elsif ($action eq 'directorysrch') {      } elsif ($action eq 'directorysrch') {
         $output = &modify_directorysrch($dom,$lastactref,%domconfig);          $output = &modify_directorysrch($dom,%domconfig);
     } elsif ($action eq 'usercreation') {      } elsif ($action eq 'usercreation') {
         $output = &modify_usercreation($dom,%domconfig);          $output = &modify_usercreation($dom,%domconfig);
     } elsif ($action eq 'selfcreation') {      } elsif ($action eq 'selfcreation') {
         $output = &modify_selfcreation($dom,$lastactref,%domconfig);          $output = &modify_selfcreation($dom,%domconfig);
     } elsif ($action eq 'usermodification') {      } elsif ($action eq 'usermodification') {
         $output = &modify_usermodification($dom,%domconfig);          $output = &modify_usermodification($dom,%domconfig);
     } elsif ($action eq 'contacts') {      } elsif ($action eq 'contacts') {
Line 645  sub process_changes { Line 687  sub process_changes {
     } elsif ($action eq 'requestauthor') {      } elsif ($action eq 'requestauthor') {
         $output = &modify_quotas($r,$dom,$action,$lastactref,%domconfig);          $output = &modify_quotas($r,$dom,$action,$lastactref,%domconfig);
     } elsif ($action eq 'helpsettings') {      } elsif ($action eq 'helpsettings') {
         $output = &modify_helpsettings($r,$dom,$confname,$lastactref,%domconfig);          $output = &modify_helpsettings($r,$dom,$confname,%domconfig);
     } elsif ($action eq 'coursedefaults') {      } elsif ($action eq 'coursedefaults') {
         $output = &modify_coursedefaults($dom,$lastactref,%domconfig);          $output = &modify_coursedefaults($dom,$lastactref,%domconfig);
     } elsif ($action eq 'selfenrollment') {      } elsif ($action eq 'selfenrollment') {
Line 654  sub process_changes { Line 696  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);
       } elsif ($action eq 'trust') {
           $output = &modify_trust($dom,$lastactref,%domconfig);
     }      }
     return $output;      return $output;
 }  }
Line 680  sub print_config_box { Line 728  sub print_config_box {
         &Apache::lonuserutils::custom_role_privs(\%privs,\%full,\%levels,\%levelscurrent);          &Apache::lonuserutils::custom_role_privs(\%privs,\%full,\%levels,\%levelscurrent);
         my @templateroles = &Apache::lonuserutils::custom_template_roles($context,$crstype);          my @templateroles = &Apache::lonuserutils::custom_template_roles($context,$crstype);
         $output =          $output =
             &Apache::lonuserutils::custom_roledefs_js($context,$crstype,$formname,\%full,              &Apache::lonuserutils::custom_roledefs_js($context,$crstype,$formname,\%full, 
                                                       \@templateroles);                                                        \@templateroles);
     }      }
     $output .=      $output .=
Line 717  sub print_config_box { Line 765  sub print_config_box {
         $rowtotal ++;          $rowtotal ++;
         if (($action eq 'autoupdate') || ($action eq 'usercreation') || ($action eq 'selfcreation') ||          if (($action eq 'autoupdate') || ($action eq 'usercreation') || ($action eq 'selfcreation') ||
             ($action eq 'usermodification') || ($action eq 'defaults') || ($action eq 'coursedefaults') ||              ($action eq 'usermodification') || ($action eq 'defaults') || ($action eq 'coursedefaults') ||
             ($action eq 'selfenrollment') || ($action eq 'usersessions') || ($action eq 'directorysrch') ||              ($action eq 'selfenrollment') || ($action eq 'usersessions') || ($action eq 'ssl') ||
             ($action eq 'helpsettings') || ($action eq 'contacts')) {              ($action eq 'directorysrch') || ($action eq 'trust') || ($action eq 'helpsettings')) {
             $output .= $item->{'print'}->('top',$dom,$settings,\$rowtotal);              $output .= $item->{'print'}->('top',$dom,$settings,\$rowtotal);
         } elsif ($action eq 'coursecategories') {          } elsif ($action eq 'coursecategories') {
             $output .= $item->{'print'}->('top',$dom,$item,$settings,\$rowtotal);              $output .= $item->{'print'}->('top',$dom,$item,$settings,\$rowtotal);
Line 748  sub print_config_box { Line 796  sub print_config_box {
             $rowtotal ++;              $rowtotal ++;
         if (($action eq 'autoupdate') || ($action eq 'usercreation') ||          if (($action eq 'autoupdate') || ($action eq 'usercreation') ||
             ($action eq 'selfcreation') || ($action eq 'selfenrollment') ||              ($action eq 'selfcreation') || ($action eq 'selfenrollment') ||
             ($action eq 'usersessions') || ($action eq 'coursecategories') ||              ($action eq 'usersessions') || ($action eq 'coursecategories') || 
             ($action eq 'contacts') || ($action eq 'defaults')) {              ($action eq 'ssl') || ($action eq 'trust')) {
             if ($action eq 'coursecategories') {              if ($action eq 'coursecategories') {
                 $output .= &print_coursecategories('middle',$dom,$item,$settings,\$rowtotal);                  $output .= &print_coursecategories('middle',$dom,$item,$settings,\$rowtotal);
                 $colspan = ' colspan="2"';                  $colspan = ' colspan="2"';
               } elsif ($action eq 'trust') {
                   $output .= $item->{'print'}->('shared',$dom,$settings,\$rowtotal);
             } else {              } else {
                 $output .= $item->{'print'}->('middle',$dom,$settings,\$rowtotal);                  $output .= $item->{'print'}->('middle',$dom,$settings,\$rowtotal);
             }              }
             $output .= '              if ($action eq 'trust') {
                   $output .= '
               </table>
             </td>
            </tr>';
                   my @trusthdrs = qw(2 3 4 5 6 7);
                   my @prefixes = qw(enroll othcoau coaurem domroles catalog reqcrs);
                   for (my $i=0; $i<@trusthdrs; $i++) {
                       $output .= '
            <tr>
              <td>
               <table class="LC_nested">
                <tr class="LC_info_row">
                 <td class="LC_left_item"'.$colspan.'>'.&mt($item->{'header'}->[$trusthdrs[$i]]->{'col1'}).'</td>
                 <td class="LC_right_item"'.$colspan.'>'.&mt($item->{'header'}->[$trusthdrs[$i]]->{'col2'}).'</td></tr>'.
                              $item->{'print'}->($prefixes[$i],$dom,$settings,\$rowtotal).'
               </table>
             </td>
            </tr>';
                   }
                   $output .= '
            <tr>
              <td>
               <table class="LC_nested">
                <tr class="LC_info_row">
                 <td class="LC_left_item"'.$colspan.'>'.&mt($item->{'header'}->[8]->{'col1'}).'</td>
                 <td class="LC_right_item"'.$colspan.'>'.&mt($item->{'header'}->[8]->{'col2'}).'</td></tr>'.
                              $item->{'print'}->('bottom',$dom,$settings,\$rowtotal);
               } else {
                   $output .= '
            </table>             </table>
           </td>            </td>
          </tr>           </tr>
Line 767  sub print_config_box { Line 846  sub print_config_box {
               <td class="LC_left_item"'.$colspan.'>'.&mt($item->{'header'}->[2]->{'col1'}).'</td>                <td class="LC_left_item"'.$colspan.'>'.&mt($item->{'header'}->[2]->{'col1'}).'</td>
               <td class="LC_right_item">'.&mt($item->{'header'}->[2]->{'col2'}).'</td>                <td class="LC_right_item">'.&mt($item->{'header'}->[2]->{'col2'}).'</td>
              </tr>'."\n";               </tr>'."\n";
             if ($action eq 'coursecategories') {                  if ($action eq 'coursecategories') {
                 $output .= &print_coursecategories('bottom',$dom,$item,$settings,\$rowtotal);                      $output .= &print_coursecategories('bottom',$dom,$item,$settings,\$rowtotal);
             } else {                  } else {
                 $output .= $item->{'print'}->('bottom',$dom,$settings,\$rowtotal);                      $output .= $item->{'print'}->('bottom',$dom,$settings,\$rowtotal);
                   }
             }              }
             $rowtotal ++;              $rowtotal ++;
         } elsif (($action eq 'usermodification') || ($action eq 'coursedefaults') ||          } elsif (($action eq 'usermodification') || ($action eq 'coursedefaults') ||
Line 933  sub print_config_box { Line 1013  sub print_config_box {
         if ($action eq 'quotas') {          if ($action eq 'quotas') {
             $output .= &print_quotas($dom,$settings,\$rowtotal,$action);              $output .= &print_quotas($dom,$settings,\$rowtotal,$action);
         } elsif (($action eq 'autoenroll') || ($action eq 'autocreate') ||           } elsif (($action eq 'autoenroll') || ($action eq 'autocreate') || 
                  ($action eq 'serverstatuses') || ($action eq 'loadbalancing')) {                   ($action eq 'contacts') || ($action eq 'serverstatuses') || 
                    ($action eq '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 1737  sub print_quotas { Line 1818  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 2150  sub print_quotas { Line 2231  sub print_quotas {
 }  }
   
 sub print_requestmail {  sub print_requestmail {
     my ($dom,$action,$settings,$rowtotal,$customcss,$rowstyle) = @_;      my ($dom,$action,$settings,$rowtotal) = @_;
     my ($now,$datatable,%currapp);      my ($now,$datatable,%currapp);
     $now = time;      $now = time;
     if (ref($settings) eq 'HASH') {      if (ref($settings) eq 'HASH') {
Line 2162  sub print_requestmail { Line 2243  sub print_requestmail {
     }      }
     my $numinrow = 2;      my $numinrow = 2;
     my $css_class;      my $css_class;
     if ($$rowtotal%2) {      $css_class = ($$rowtotal%2? ' class="LC_odd_row"':'');
         $css_class = 'LC_odd_row';  
     }  
     if ($customcss) {  
         $css_class .= " $customcss";  
     }  
     $css_class =~ s/^\s+//;  
     if ($css_class) {  
         $css_class = ' class="'.$css_class.'"';  
     }  
     if ($rowstyle) {  
         $css_class .= ' style="'.$rowstyle.'"';  
     }  
     my $text;      my $text;
     if ($action eq 'requestcourses') {      if ($action eq 'requestcourses') {
         $text = &mt('Receive notification of course requests requiring approval');          $text = &mt('Receive notification of course requests requiring approval');
Line 2201  sub print_studentcode { Line 2270  sub print_studentcode {
     my ($settings,$rowtotal) = @_;      my ($settings,$rowtotal) = @_;
     my $rownum = 0;       my $rownum = 0; 
     my ($output,%current);      my ($output,%current);
     my @crstypes = ('official','unofficial','community','textbook');      my @crstypes = ('official','unofficial','community','textbook','placement');
     if (ref($settings) eq 'HASH') {      if (ref($settings) eq 'HASH') {
         if (ref($settings->{'uniquecode'}) eq 'HASH') {          if (ref($settings->{'uniquecode'}) eq 'HASH') {
             foreach my $type (@crstypes) {              foreach my $type (@crstypes) {
Line 2297  sub print_textbookcourses { Line 2366  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 2452  $jstext{'templates'}; Line 2520  $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),
Line 2580  sub print_autoupdate { Line 2716  sub print_autoupdate {
         my $locknamesettings;          my $locknamesettings;
         $datatable .= &insttypes_row($settings,$types,$usertypes,          $datatable .= &insttypes_row($settings,$types,$usertypes,
                                      $dom,$numinrow,$othertitle,                                       $dom,$numinrow,$othertitle,
                                     'lockablenames',$rowtotal);                                      'lockablenames');
         $$rowtotal ++;          $$rowtotal ++;
     } else {      } else {
         my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom);          my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom);
Line 2723  sub print_directorysrch { Line 2859  sub print_directorysrch {
         if (ref($usertypes) eq 'HASH') {          if (ref($usertypes) eq 'HASH') {
             if (keys(%{$usertypes}) > 0) {              if (keys(%{$usertypes}) > 0) {
                 $datatable .= &insttypes_row($settings,$types,$usertypes,$dom,                  $datatable .= &insttypes_row($settings,$types,$usertypes,$dom,
                                              $numinrow,$othertitle,'cansearch',                                               $numinrow,$othertitle,'cansearch');
                                              $rowtotal);  
                 $cansrchrow = 1;                  $cansrchrow = 1;
             }              }
         }          }
Line 2809  sub print_directorysrch { Line 2944  sub print_directorysrch {
 }  }
   
 sub print_contacts {  sub print_contacts {
     my ($position,$dom,$settings,$rowtotal) = @_;      my ($dom,$settings,$rowtotal) = @_;
     my $datatable;      my $datatable;
     my @contacts = ('adminemail','supportemail');      my @contacts = ('adminemail','supportemail');
     my (%checked,%to,%otheremails,%bccemails,%includestr,%includeloc,%currfield,      my (%checked,%to,%otheremails,%bccemails);
         $maxsize,$fields,$fieldtitles,$fieldoptions,$possoptions,@mailings);      my @mailings = ('errormail','packagesmail','lonstatusmail','helpdeskmail',
     if ($position eq 'top') {                      'requestsmail','updatesmail','idconflictsmail');
         if (ref($settings) eq 'HASH') {      foreach my $type (@mailings) {
             foreach my $item (@contacts) {          $otheremails{$type} = '';
                 if (exists($settings->{$item})) {  
                     $to{$item} = $settings->{$item};  
                 }  
             }  
         }  
     } elsif ($position eq 'middle') {  
         @mailings = ('errormail','packagesmail','lonstatusmail','requestsmail',  
                      'updatesmail','idconflictsmail');  
         foreach my $type (@mailings) {  
             $otheremails{$type} = '';  
         }  
     } else {  
         @mailings = ('helpdeskmail','otherdomsmail');  
         foreach my $type (@mailings) {  
             $otheremails{$type} = '';  
         }  
         $bccemails{'helpdeskmail'} = '';  
         $bccemails{'otherdomsmail'} = '';  
         $includestr{'helpdeskmail'} = '';  
         $includestr{'otherdomsmail'} = '';  
         ($fields,$fieldtitles,$fieldoptions,$possoptions) = &helpform_fields();  
     }      }
       $bccemails{'helpdeskmail'} = '';
     if (ref($settings) eq 'HASH') {      if (ref($settings) eq 'HASH') {
         unless ($position eq 'top') {          foreach my $item (@contacts) {
             foreach my $type (@mailings) {              if (exists($settings->{$item})) {
                 if (exists($settings->{$type})) {                  $to{$item} = $settings->{$item};
                     if (ref($settings->{$type}) eq 'HASH') {  
                         foreach my $item (@contacts) {  
                             if ($settings->{$type}{$item}) {  
                                 $checked{$type}{$item} = ' checked="checked" ';  
                             }  
                         }  
                         $otheremails{$type} = $settings->{$type}{'others'};  
                         if (($type eq 'helpdeskmail') || ($type eq 'otherdomsmail')) {  
                             $bccemails{$type} = $settings->{$type}{'bcc'};  
                             if ($settings->{$type}{'include'} ne '') {  
                                 ($includeloc{$type},$includestr{$type}) = split(/:/,$settings->{$type}{'include'},2);  
                                 $includestr{$type} = &unescape($includestr{$type});  
                             }  
                         }  
                     }  
                 } elsif ($type eq 'lonstatusmail') {  
                     $checked{'lonstatusmail'}{'adminemail'} = ' checked="checked" ';  
                 }  
             }              }
         }          }
         if ($position eq 'bottom') {          foreach my $type (@mailings) {
             foreach my $type (@mailings) {              if (exists($settings->{$type})) {
                 $bccemails{$type} = $settings->{$type}{'bcc'};                  if (ref($settings->{$type}) eq 'HASH') {
                 if ($settings->{$type}{'include'} ne '') {                      foreach my $item (@contacts) {
                     ($includeloc{$type},$includestr{$type}) = split(/:/,$settings->{$type}{'include'},2);                          if ($settings->{$type}{$item}) {
                     $includestr{$type} = &unescape($includestr{$type});                              $checked{$type}{$item} = ' checked="checked" ';
                 }                          }
             }  
             if (ref($settings->{'helpform'}) eq 'HASH') {  
                 if (ref($fields) eq 'ARRAY') {  
                     foreach my $field (@{$fields}) {  
                         $currfield{$field} = $settings->{'helpform'}{$field};  
                     }                      }
                 }                      $otheremails{$type} = $settings->{$type}{'others'};
                 if (exists($settings->{'helpform'}{'maxsize'})) {                      if ($type eq 'helpdeskmail') {
                     $maxsize = $settings->{'helpform'}{'maxsize'};                          $bccemails{$type} = $settings->{$type}{'bcc'};
                 } else {  
                     $maxsize = '1.0';  
                 }  
             } else {  
                 if (ref($fields) eq 'ARRAY') {  
                     foreach my $field (@{$fields}) {  
                         $currfield{$field} = 'yes';  
                     }                      }
                 }                  }
                 $maxsize = '1.0';              } elsif ($type eq 'lonstatusmail') {
                   $checked{'lonstatusmail'}{'adminemail'} = ' checked="checked" ';
             }              }
         }          }
     } else {      } else {
         if ($position eq 'top') {          $to{'supportemail'} = $Apache::lonnet::perlvar{'lonSupportEMail'};
             $to{'supportemail'} = $Apache::lonnet::perlvar{'lonSupportEMail'};          $to{'adminemail'} = $Apache::lonnet::perlvar{'lonAdmEMail'};
             $to{'adminemail'} = $Apache::lonnet::perlvar{'lonAdmEMail'};          $checked{'errormail'}{'adminemail'} = ' checked="checked" ';
             $checked{'errormail'}{'adminemail'} = ' checked="checked" ';          $checked{'packagesmail'}{'adminemail'} = ' checked="checked" ';
             $checked{'packagesmail'}{'adminemail'} = ' checked="checked" ';          $checked{'helpdeskmail'}{'supportemail'} = ' checked="checked" ';
             $checked{'lonstatusmail'}{'adminemail'} = ' checked="checked" ';          $checked{'lonstatusmail'}{'adminemail'} = ' checked="checked" '; 
             $checked{'requestsmail'}{'adminemail'} = ' checked="checked" ';          $checked{'requestsmail'}{'adminemail'} = ' checked="checked" ';
             $checked{'updatesmail'}{'adminemail'} = ' checked="checked" ';          $checked{'updatesmail'}{'adminemail'} = ' checked="checked" ';
             $checked{'idconflictsmail'}{'adminemail'} = ' checked="checked" ';          $checked{'idconflictsmail'}{'adminemail'} = ' checked="checked" ';
         } elsif ($position eq 'bottom') {  
             $checked{'helpdeskmail'}{'supportemail'} = ' checked="checked" ';  
             $checked{'otherdomsmail'}{'supportemail'} = ' checked="checked" ';  
             if (ref($fields) eq 'ARRAY') {  
                 foreach my $field (@{$fields}) {  
                     $currfield{$field} = 'yes';  
                 }  
             }  
             $maxsize = '1.0';  
         }  
     }      }
     my ($titles,$short_titles) = &contact_titles();      my ($titles,$short_titles) = &contact_titles();
     my $rownum = 0;      my $rownum = 0;
     my $css_class;      my $css_class;
     if ($position eq 'top') {      foreach my $item (@contacts) {
         foreach my $item (@contacts) {          $css_class = $rownum%2?' class="LC_odd_row"':'';
             $css_class = $rownum%2?' class="LC_odd_row"':'';          $datatable .= '<tr'.$css_class.'>'. 
             $datatable .= '<tr'.$css_class.'>'.                     '<td><span class="LC_nobreak">'.$titles->{$item}.
                           '<td><span class="LC_nobreak">'.$titles->{$item}.                    '</span></td><td class="LC_right_item">'.
                           '</span></td><td class="LC_right_item">'.                    '<input type="text" name="'.$item.'" value="'.
                           '<input type="text" name="'.$item.'" value="'.                    $to{$item}.'" /></td></tr>';
                           $to{$item}.'" /></td></tr>';          $rownum ++;
             $rownum ++;  
         }  
     } else {  
         foreach my $type (@mailings) {  
             $css_class = $rownum%2?' class="LC_odd_row"':'';  
             $datatable .= '<tr'.$css_class.'>'.  
                           '<td><span class="LC_nobreak">'.  
                           $titles->{$type}.': </span></td>'.  
                           '<td class="LC_left_item">';  
             if (($type eq 'helpdeskmail') || ($type eq 'otherdomsmail')) {  
                 $datatable .= '<fieldset><legend>'.&mt('E-mail recipient(s)').'</legend>';  
             }  
             $datatable .= '<span class="LC_nobreak">';  
             foreach my $item (@contacts) {  
                 $datatable .= '<label>'.  
                               '<input type="checkbox" name="'.$type.'"'.  
                               $checked{$type}{$item}.  
                               ' value="'.$item.'" />'.$short_titles->{$item}.  
                               '</label>&nbsp;';  
             }  
             $datatable .= '</span><br />'.&mt('Others').':&nbsp;&nbsp;'.  
                           '<input type="text" name="'.$type.'_others" '.  
                           'value="'.$otheremails{$type}.'"  />';  
             my %locchecked;  
             if (($type eq 'helpdeskmail') || ($type eq 'otherdomsmail')) {  
                 foreach my $loc ('s','b') {  
                     if ($includeloc{$type} eq $loc) {  
                         $locchecked{$loc} = ' checked="checked"';  
                         last;  
                     }  
                 }  
                 $datatable .= '<br />'.&mt('Bcc:').('&nbsp;'x6).  
                               '<input type="text" name="'.$type.'_bcc" '.  
                               'value="'.$bccemails{$type}.'"  /></fieldset>'.  
                               '<fieldset><legend>'.&mt('Optional added text').'</legend>'.  
                               &mt('Text automatically added to e-mail:').' '.  
                               '<input type="text" name="'.$type.'_includestr" value="'.$includestr{$type}.'" /><br >'.  
                               '<span class="LC_nobreak">'.&mt('Location:').'&nbsp;'.  
                               '<label><input type="radio" name="'.$type.'_includeloc" value="s"'.$locchecked{'s'}.' />'.&mt('in subject').'</label>'.  
                               ('&nbsp;'x2).  
                               '<label><input type="radio" name="'.$type.'_includeloc" value="b"'.$locchecked{'b'}.' />'.&mt('in body').'</label>'.  
                               '</span></fieldset>';  
             }  
             $datatable .= '</td></tr>'."\n";  
             $rownum ++;  
         }  
     }      }
     if ($position eq 'middle') {      foreach my $type (@mailings) {
         my %choices;  
         $choices{'reporterrors'} = &mt('E-mail error reports to [_1]',  
                                        &Apache::loncommon::modal_link('http://loncapa.org/core.html',  
                                        &mt('LON-CAPA core group - MSU'),600,500));  
         $choices{'reportupdates'} = &mt('E-mail record of completed LON-CAPA updates to [_1]',  
                                         &Apache::loncommon::modal_link('http://loncapa.org/core.html',  
                                         &mt('LON-CAPA core group - MSU'),600,500));  
         my @toggles = ('reporterrors','reportupdates');  
         my %defaultchecked = ('reporterrors'  => 'on',  
                               'reportupdates' => 'on');  
         (my $reports,$rownum) = &radiobutton_prefs($settings,\@toggles,\%defaultchecked,  
                                                    \%choices,$rownum);  
         $datatable .= $reports;  
     } elsif ($position eq 'bottom') {  
         $css_class = $rownum%2?' class="LC_odd_row"':'';          $css_class = $rownum%2?' class="LC_odd_row"':'';
         $datatable .= '<tr'.$css_class.'>'.          $datatable .= '<tr'.$css_class.'>'.
                       '<td>'.&mt('Extra helpdesk form fields:').'<br />'.                        '<td><span class="LC_nobreak">'.
                       &mt('(e-mail, subject, and description always shown)').                        $titles->{$type}.': </span></td>'.
                       '</td><td class="LC_left_item">';                        '<td class="LC_left_item">'.
         if ((ref($fields) eq 'ARRAY') && (ref($fieldtitles) eq 'HASH') &&                        '<span class="LC_nobreak">';
             (ref($fieldoptions) eq 'HASH') && (ref($possoptions) eq 'HASH')) {          foreach my $item (@contacts) {
             $datatable .= '<table><tr><th>'.&mt('Field').'</th><th>'.&mt('Status').'</th></tr>';              $datatable .= '<label>'.
             foreach my $field (@{$fields}) {                            '<input type="checkbox" name="'.$type.'"'.
                 $datatable .= '<tr><td>'.$fieldtitles->{$field};                            $checked{$type}{$item}.
                 if (($field eq 'screenshot') || ($field eq 'cc')) {                            ' value="'.$item.'" />'.$short_titles->{$item}.
                     $datatable .= ' '.&mt('(logged-in users)');                            '</label>&nbsp;';
                 }          }
                 $datatable .='</td><td>';          $datatable .= '</span><br />'.&mt('Others').':&nbsp;&nbsp;'.
                 my $clickaction;                        '<input type="text" name="'.$type.'_others" '.
                 if ($field eq 'screenshot') {                        'value="'.$otheremails{$type}.'"  />';
                     $clickaction = ' onclick="screenshotSize(this);"';          if ($type eq 'helpdeskmail') {
                 }              $datatable .= '<br />'.&mt('Bcc:').('&nbsp;'x6).
                 if (ref($possoptions->{$field}) eq 'ARRAY') {                            '<input type="text" name="'.$type.'_bcc" '.
                     foreach my $option (@{$possoptions->{$field}}) {                            'value="'.$bccemails{$type}.'"  />';
                         my $checked;  
                         if ($currfield{$field} eq $option) {  
                             $checked = ' checked="checked"';  
                         }  
                         $datatable .= '<span class="LC_nobreak"><label>'.  
                                       '<input type="radio" name="helpform_'.$field.'" '.  
                                       'value="'.$option.'"'.$checked.$clickaction.' />'.$fieldoptions->{$option}.  
                                       '</label></span>'.('&nbsp;'x2);  
                     }  
                 }  
                 if ($field eq 'screenshot') {  
                     my $display;  
                     if ($currfield{$field} eq 'no') {  
                         $display = ' style="display:none"';  
                     }  
                     $datatable .= '</td></tr><tr id="help_screenshotsize"'.$display.' />'.  
                                   '<td>'.&mt('Maximum size for upload (MB)').'</td><td>'.  
                                   '<input type="text" size="5" name="helpform_maxsize" value="'.$maxsize.'" />';  
                 }  
                 $datatable .= '</td></tr>';  
             }  
             $datatable .= '</table>';  
         }          }
         $datatable .= '</td></tr>'."\n";          $datatable .= '</td></tr>'."\n";
         $rownum ++;          $rownum ++;
     }      }
       my %choices;
       $choices{'reporterrors'} = &mt('E-mail error reports to [_1]',
                                      &Apache::loncommon::modal_link('http://loncapa.org/core.html',
                                      &mt('LON-CAPA core group - MSU'),600,500));
       $choices{'reportupdates'} = &mt('E-mail record of completed LON-CAPA updates to [_1]',
                                       &Apache::loncommon::modal_link('http://loncapa.org/core.html',
                                       &mt('LON-CAPA core group - MSU'),600,500));
       my @toggles = ('reporterrors','reportupdates');
       my %defaultchecked = ('reporterrors'  => 'on',
                             'reportupdates' => 'on');
       (my $reports,$rownum) = &radiobutton_prefs($settings,\@toggles,\%defaultchecked,
                                                  \%choices,$rownum);
       $datatable .= $reports;
     $$rowtotal += $rownum;      $$rowtotal += $rownum;
     return $datatable;      return $datatable;
 }  }
   
 sub contacts_javascript {  
     return <<"ENDSCRIPT";  
   
 <script type="text/javascript">  
 // <![CDATA[  
   
 function screenshotSize(field) {  
     if (document.getElementById('help_screenshotsize')) {  
         if (field.value == 'no') {  
             document.getElementById('help_screenshotsize').style.display="none";  
         } else {  
             document.getElementById('help_screenshotsize').style.display="";  
         }  
     }  
     return;  
 }  
   
 // ]]>  
 </script>  
   
 ENDSCRIPT  
 }  
   
 sub print_helpsettings {  sub print_helpsettings {
     my ($position,$dom,$settings,$rowtotal) = @_;      my ($position,$dom,$settings,$rowtotal) = @_;
     my $confname = $dom.'-domainconfig';      my $confname = $dom.'-domainconfig';
     my $formname = 'display';  
     my ($datatable,$itemcount);      my ($datatable,$itemcount);
     if ($position eq 'top') {      if ($position eq 'top') {
         $itemcount = 1;          $itemcount = 1;
Line 3077  sub print_helpsettings { Line 3060  sub print_helpsettings {
     } else {      } else {
         my $css_class;          my $css_class;
         my %existing=&Apache::lonnet::dump('roles',$dom,$confname,'rolesdef_');          my %existing=&Apache::lonnet::dump('roles',$dom,$confname,'rolesdef_');
         my (%customroles,%ordered,%current);          my %customroles;
         if (ref($settings) eq 'HASH') {          foreach my $key (keys(%existing)) {
             if (ref($settings->{'adhoc'}) eq 'HASH') {  
                 %current = %{$settings->{'adhoc'}};  
             }  
         }  
         my $count = 0;  
         foreach my $key (sort(keys(%existing))) {  
             if ($key=~/^rolesdef\_(\w+)$/) {              if ($key=~/^rolesdef\_(\w+)$/) {
                 my $rolename = $1;                  my $rolename = $1;
                 my (%privs,$order);                  my %privs;
                 ($privs{'system'},$privs{'domain'},$privs{'course'}) = split(/\_/,$existing{$key});                  ($privs{'system'},$privs{'domain'},$privs{'course'}) = split(/\_/,$existing{$key});
                 $customroles{$rolename} = \%privs;                  $customroles{$rolename} = \%privs;
                 if (ref($current{$rolename}) eq 'HASH') {  
                     $order = $current{$rolename}{'order'};  
                 }  
                 if ($order eq '') {  
                     $order = $count;  
                 }  
                 $ordered{$order} = $rolename;  
                 $count++;  
             }  
         }  
         my $maxnum = scalar(keys(%ordered));  
         my @roles_by_num = ();  
         foreach my $item (sort {$a <=> $b } (keys(%ordered))) {  
             push(@roles_by_num,$item);  
         }  
         my $context = 'domprefs';  
         my $crstype = 'Course';  
         my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom);  
         my @accesstypes = ('all','dh','da','none');  
         my ($numstatustypes,@jsarray);  
         if (ref($types) eq 'ARRAY') {  
             if (@{$types} > 0) {  
                 $numstatustypes = scalar(@{$types});  
                 push(@accesstypes,'status');  
                 @jsarray = ('bystatus');  
             }              }
         }          }
         my %domhelpdesk = &Apache::lonnet::get_active_domroles($dom,['dh'.'da']);          my $count = 0;
         if (keys(%domhelpdesk)) {  
             push(@accesstypes,('inc','exc'));  
             push(@jsarray,('notinc','notexc'));  
         }  
         my $hiddenstr = join("','",@jsarray);  
         $datatable .= &helpsettings_javascript(\@roles_by_num,$maxnum,$hiddenstr,$formname);  
         my $context = 'domprefs';          my $context = 'domprefs';
         my $crstype = 'Course';          my $crstype = 'Course';
         my $prefix = 'helproles_';          foreach my $role (sort(keys(%customroles))) {
         my $add_class = 'LC_hidden';              my $prefix = 'custhelp'.$count;
         foreach my $num (@roles_by_num) {  
             my $role = $ordered{$num};  
             my ($desc,$access,@statuses);  
             if (ref($current{$role}) eq 'HASH') {  
                 $desc = $current{$role}{'desc'};  
                 $access = $current{$role}{'access'};  
                 if (ref($current{$role}{'insttypes'}) eq 'ARRAY') {  
                     @statuses = @{$current{$role}{'insttypes'}};  
                 }  
             }  
             if ($desc eq '') {  
                 $desc = $role;  
             }  
             my $identifier = 'custhelp'.$num;  
             my %full=();              my %full=();
             my %levels= (              my %levels= (
                          course => {},                           course => {},
Line 3156  sub print_helpsettings { Line 3088  sub print_helpsettings {
             &Apache::lonuserutils::custom_role_privs($customroles{$role},\%full,\%levels,\%levelscurrent);              &Apache::lonuserutils::custom_role_privs($customroles{$role},\%full,\%levels,\%levelscurrent);
             my @templateroles = &Apache::lonuserutils::custom_template_roles($context,$crstype);              my @templateroles = &Apache::lonuserutils::custom_template_roles($context,$crstype);
             $css_class = $itemcount%2?' class="LC_odd_row"':'';              $css_class = $itemcount%2?' class="LC_odd_row"':'';
             my $chgstr = ' onchange="javascript:reorderHelpRoles(this.form,'."'helproles_".$num."_pos'".');"';              $datatable .= '<tr '.$css_class.'><td><label>'.
             $datatable .= '<tr '.$css_class.'><td valign="top"><b>'.$role.'</b><br />'.                            '<input type="checkbox" name="modifycusthelp" value="'.$count.'" />'.
                           '<select name="helproles_'.$num.'_pos"'.$chgstr.'>';                            '<input type="hidden" name="custhelprole'.$count.'" value="'.$role.'" />'. 
             for (my $k=0; $k<=$maxnum; $k++) {                            &mt('Modify').'</label></td>'.
                 my $vpos = $k+1;                            '<td>'.&mt('Existing helpdesk role:').'&nbsp;'.
                 my $selstr;                            '<b>'.$role.'</b><br />'.
                 if ($k == $num) {                            &Apache::lonuserutils::custom_role_header($context,$crstype,
                     $selstr = ' selected="selected" ';                                                                      \@templateroles,$prefix).
                 }  
                 $datatable .= '<option value="'.$k.'"'.$selstr.'>'.$vpos.'</option>';  
             }  
             $datatable .= '</select>'.('&nbsp;'x2).  
                           '<input type="hidden" name="helproles_'.$num.'" value="'.$role.'" />'.  
                           '</td>'.  
                           '<td><fieldset><legend>'.&mt('Role name').'</legend>'.  
                           &mt('Name shown to users:').  
                           '<input type="text" name="helproles_'.$num.'_desc" value="'.$desc.'" />'.  
                           '</fieldset>'.  
                           &helpdeskroles_access($dom,$prefix,$num,$add_class,$current{$role},\@accesstypes,  
                                                 $othertitle,$usertypes,$types,\%domhelpdesk).  
                           '<fieldset>'.  
                           '<legend>'.&mt('Role privileges').&adhocbutton($prefix,$num,'privs','show').'</legend>'.  
                           &Apache::lonuserutils::custom_role_table($crstype,\%full,\%levels,                            &Apache::lonuserutils::custom_role_table($crstype,\%full,\%levels,
                                                                    \%levelscurrent,$identifier,                                                                     \%levelscurrent,$prefix).
                                                                    'LC_hidden',$prefix.$num.'_privs').                            '<br /></td>';
                           '</fieldset></td>';              $count ++;
             $itemcount ++;              $itemcount ++;
         }          }
         $css_class = $itemcount%2?' class="LC_odd_row"':'';          $css_class = $itemcount%2?' class="LC_odd_row"':'';
Line 3195  sub print_helpsettings { Line 3113  sub print_helpsettings {
                     );                      );
         &Apache::lonuserutils::custom_role_privs(\%privs,\%full,\%levels,\%levelscurrent);          &Apache::lonuserutils::custom_role_privs(\%privs,\%full,\%levels,\%levelscurrent);
         my @templateroles = &Apache::lonuserutils::custom_template_roles($context,$crstype);          my @templateroles = &Apache::lonuserutils::custom_template_roles($context,$crstype);
         my $chgstr = ' onchange="javascript:reorderHelpRoles(this.form,'."'helproles_".$count."_pos'".');"';          $datatable .= '<tr '.$css_class.'><td><span class="LC_nobreak"><label>'.
         $datatable .= '<tr '.$css_class.'><td valign="top"><span class="LC_nobreak"><label>'.  
                       '<input type="hidden" name="helproles_maxnum" value="'.$maxnum.'" />'."\n".  
                       '<select name="helproles_'.$count.'_pos"'.$chgstr.'>';  
         for (my $k=0; $k<$maxnum+1; $k++) {  
             my $vpos = $k+1;  
             my $selstr;  
             if ($k == $maxnum) {  
                 $selstr = ' selected="selected" ';  
             }  
             $datatable .= '<option value="'.$k.'"'.$selstr.'>'.$vpos.'</option>';  
         }  
         $datatable .= '</select>&nbsp;'."\n".  
                       '<input type="checkbox" name="newcusthelp" value="'.$count.'" />'. &mt('Add').                        '<input type="checkbox" name="newcusthelp" value="'.$count.'" />'. &mt('Add').
                       '</label></span></td>'.                        '</label></span></td>'.
                       '<td><fieldset><legend>'.&mt('Role name').'</legend>'.                        '<td><span class="LC_nobreak">'.
                       '<span class="LC_nobreak">'.                        '<b>'.&mt('Name of new helpdesk role:').'</b>&nbsp;'.
                       &mt('Internal name:').                        '<input type="text" size="20" name="newcusthelpname" value="" />'.
                       '<input type="text" size="10" name="custhelpname'.$count.'" value="" />'.                        '</span><br />'.
                       '</span>'.('&nbsp;'x4).  
                       '<span class="LC_nobreak">'.  
                       &mt('Name shown to users:').  
                       '<input type="text" size="20" name="helproles_'.$count.'_desc" value="" />'.  
                       '</span></fieldset>'.  
                        &helpdeskroles_access($dom,$prefix,$count,'',undef,\@accesstypes,$othertitle,  
                                              $usertypes,$types,\%domhelpdesk).  
                       '<fieldset><legend>'.&mt('Role privileges').'</legend>'.  
                       &Apache::lonuserutils::custom_role_header($context,$crstype,                        &Apache::lonuserutils::custom_role_header($context,$crstype,
                                                                 \@templateroles,$newcust).                                                                  \@templateroles,$newcust).
                       &Apache::lonuserutils::custom_role_table('Course',\%full,\%levels,                        &Apache::lonuserutils::custom_role_table('Course',\%full,\%levels,
                                                                \%levelscurrent,$newcust).                                                                 \%levelscurrent,$newcust).
                       '</fieldset></td></tr>';                        '<br /><br />'.
                         '</td></tr>';
         $count ++;          $count ++;
         $$rowtotal += $count;          $$rowtotal += $count;
     }      }
     return $datatable;      return $datatable;
 }  }
   
 sub adhocbutton {  
     my ($prefix,$num,$field,$visibility) = @_;  
     my %lt = &Apache::lonlocal::texthash(  
                                           show => 'Show details',  
                                           hide => 'Hide details',  
                                         );  
     return '<span style="text-decoration:line-through; font-weight: normal;">'.('&nbsp;'x10).  
            '</span>'.('&nbsp;'x2).'<input type="button" id="'.$prefix.$num.'_'.$field.'_vis"'.  
            ' value="'.$lt{$visibility}.'" style="height:20px;" '.  
            'onclick="toggleHelpdeskItem('."'$num','$field'".');" />'.('&nbsp;'x2);  
 }  
   
 sub helpsettings_javascript {  
     my ($roles_by_num,$total,$hiddenstr,$formname) = @_;  
     return unless(ref($roles_by_num) eq 'ARRAY');  
     my %html_js_lt = &Apache::lonlocal::texthash(  
                                           show => 'Show details',  
                                           hide => 'Hide details',  
                                         );  
     &html_escape(\%html_js_lt);  
     my $jstext = '    var helproles = Array('."'".join("','",@{$roles_by_num})."'".');'."\n";  
     return <<"ENDSCRIPT";  
 <script type="text/javascript">  
 // <![CDATA[  
   
 function reorderHelpRoles(form,item) {  
     var changedVal;  
 $jstext  
     var newpos = 'helproles_${total}_pos';  
     var maxh = 1 + $total;  
     var current = new Array();  
     var newitemVal = form.elements[newpos].options[form.elements[newpos].selectedIndex].value;  
     if (item == newpos) {  
         changedVal = newitemVal;  
     } else {  
         changedVal = form.elements[item].options[form.elements[item].selectedIndex].value;  
         current[newitemVal] = newpos;  
     }  
     for (var i=0; i<helproles.length; i++) {  
         var elementName = 'helproles_'+helproles[i]+'_pos';  
         if (elementName != item) {  
             if (form.elements[elementName]) {  
                 var currVal = form.elements[elementName].options[form.elements[elementName].selectedIndex].value;  
                 current[currVal] = elementName;  
             }  
         }  
     }  
     var oldVal;  
     for (var j=0; j<maxh; j++) {  
         if (current[j] == undefined) {  
             oldVal = j;  
         }  
     }  
     if (oldVal < changedVal) {  
         for (var k=oldVal+1; k<=changedVal ; k++) {  
            var elementName = current[k];  
            form.elements[elementName].selectedIndex = form.elements[elementName].selectedIndex - 1;  
         }  
     } else {  
         for (var k=changedVal; k<oldVal; k++) {  
             var elementName = current[k];  
             form.elements[elementName].selectedIndex = form.elements[elementName].selectedIndex + 1;  
         }  
     }  
     return;  
 }  
   
 function helpdeskAccess(num) {  
     var curraccess = null;  
     if (document.$formname.elements['helproles_'+num+'_access'].length) {  
         for (var i=0; i<document.$formname.elements['helproles_'+num+'_access'].length; i++) {  
             if (document.$formname.elements['helproles_'+num+'_access'][i].checked) {  
                 curraccess = document.$formname.elements['helproles_'+num+'_access'][i].value;  
             }  
         }  
     }  
     var shown = Array();  
     var hidden = Array();  
     if (curraccess == 'none') {  
         hidden = Array('$hiddenstr');  
     } else {  
         if (curraccess == 'status') {  
             shown = Array('bystatus');  
             hidden = Array('notinc','notexc');  
         } else {  
             if (curraccess == 'exc') {  
                 shown = Array('notexc');  
                 hidden = Array('notinc','bystatus');  
             }  
             if (curraccess == 'inc') {  
                 shown = Array('notinc');  
                 hidden = Array('notexc','bystatus');  
             }  
             if ((curraccess == 'all') || (curraccess == 'dh') || (curraccess == 'da')) {  
                 hidden = Array('notinc','notexc','bystatus');  
             }  
         }  
     }  
     if (hidden.length > 0) {  
         for (var i=0; i<hidden.length; i++) {  
             if (document.getElementById('helproles_'+num+'_'+hidden[i])) {  
                 document.getElementById('helproles_'+num+'_'+hidden[i]).style.display = 'none';  
             }  
         }  
     }  
     if (shown.length > 0) {  
         for (var i=0; i<shown.length; i++) {  
             if (document.getElementById('helproles_'+num+'_'+shown[i])) {  
                 if (shown[i] == 'privs') {  
                     document.getElementById('helproles_'+num+'_'+shown[i]).style.display = 'block';  
                 } else {  
                     document.getElementById('helproles_'+num+'_'+shown[i]).style.display = 'inline-block';  
                 }  
             }  
         }  
     }  
     return;  
 }  
   
 function toggleHelpdeskItem(num,field) {  
     if (document.getElementById('helproles_'+num+'_'+field)) {  
         if (document.getElementById('helproles_'+num+'_'+field).className.match(/(?:^|\\s)LC_hidden(?!\\S)/)) {  
             document.getElementById('helproles_'+num+'_'+field).className =  
                 document.getElementById('helproles_'+num+'_'+field).className.replace(/(?:^|\\s)LC_hidden(?!\\S)/g ,'');  
             if (document.getElementById('helproles_'+num+'_'+field+'_vis')) {  
                 document.getElementById('helproles_'+num+'_'+field+'_vis').value = '$html_js_lt{hide}';  
             }  
         } else {  
             document.getElementById('helproles_'+num+'_'+field).className += ' LC_hidden';  
             if (document.getElementById('helproles_'+num+'_'+field+'_vis')) {  
                 document.getElementById('helproles_'+num+'_'+field+'_vis').value = '$html_js_lt{show}';  
             }  
         }  
     }  
     return;  
 }  
   
 // ]]>  
 </script>  
   
 ENDSCRIPT  
 }  
   
 sub helpdeskroles_access {  
     my ($dom,$prefix,$num,$add_class,$current,$accesstypes,$othertitle,  
         $usertypes,$types,$domhelpdesk) = @_;  
     return unless ((ref($accesstypes) eq 'ARRAY') && (ref($domhelpdesk) eq 'HASH'));  
     my %lt = &Apache::lonlocal::texthash(  
                     'rou'    => 'Role usage',  
                     'whi'    => 'Which helpdesk personnel may use this role?',  
                     'all'    => 'All with domain helpdesk or helpdesk assistant role',  
                     'dh'     => 'All with domain helpdesk role',  
                     'da'     => 'All with domain helpdesk assistant role',  
                     'none'   => 'None',  
                     'status' => 'Determined based on institutional status',  
                     'inc'    => 'Include all, but exclude specific personnel',  
                     'exc'    => 'Exclude all, but include specific personnel',  
                   );  
     my %usecheck = (  
                      all => ' checked="checked"',  
                    );  
     my %displaydiv = (  
                       status => 'none',  
                       inc    => 'none',  
                       exc    => 'none',  
                       priv   => 'block',  
                      );  
     my $output;  
     if (ref($current) eq 'HASH') {  
         if (($current->{'access'} ne '') && ($current->{'access'} ne 'all')) {  
             if (grep(/^\Q$current->{access}\E$/,@{$accesstypes})) {  
                 $usecheck{$current->{access}} = $usecheck{'all'};  
                 delete($usecheck{'all'});  
                 if ($current->{access} =~ /^(status|inc|exc)$/) {  
                     my $access = $1;  
                     $displaydiv{$access} = 'inline';  
                 } elsif ($current->{access} eq 'none') {  
                     $displaydiv{'priv'} = 'none';  
                 }  
             }  
         }  
     }  
     $output = '<fieldset id="'.$prefix.$num.'_usage"><legend>'.$lt{'rou'}.'</legend>'.  
               '<p>'.$lt{'whi'}.'</p>';  
     foreach my $access (@{$accesstypes}) {  
         $output .= '<p><label><input type="radio" name="'.$prefix.$num.'_access" value="'.$access.'" '.$usecheck{$access}.  
                    ' onclick="helpdeskAccess('."'$num'".');" />'.  
                    $lt{$access}.'</label>';  
         if ($access eq 'status') {  
             $output .= '<div id="'.$prefix.$num.'_bystatus" style="display:'.$displaydiv{$access}.'">'.  
                        &Apache::lonuserutils::adhoc_status_types($dom,$prefix,$num,$current->{$access},  
                                                                  $othertitle,$usertypes,$types).  
                        '</div>';  
         } elsif (($access eq 'inc') && (keys(%{$domhelpdesk}) > 0)) {  
             $output .= '<div id="'.$prefix.$num.'_notinc" style="display:'.$displaydiv{$access}.'">'.  
                        &Apache::lonuserutils::adhoc_staff($access,$prefix,$num,$current->{$access},$domhelpdesk).  
                        '</div>';  
         } elsif (($access eq 'exc') && (keys(%{$domhelpdesk}) > 0)) {  
             $output .= '<div id="'.$prefix.$num.'_notexc" style="display:'.$displaydiv{$access}.'">'.  
                        &Apache::lonuserutils::adhoc_staff($access,$prefix,$num,$current->{$access},$domhelpdesk).  
                        '</div>';  
         }  
         $output .= '</p>';  
     }  
     $output .= '</fieldset>';  
     return $output;  
 }  
   
 sub radiobutton_prefs {  sub radiobutton_prefs {
     my ($settings,$toggles,$defaultchecked,$choices,$itemcount,$onclick,      my ($settings,$toggles,$defaultchecked,$choices,$itemcount,$onclick,
         $additional,$align) = @_;          $additional,$align) = @_;
Line 3483  sub radiobutton_prefs { Line 3174  sub radiobutton_prefs {
         } else {          } else {
             $datatable .= '<td class="LC_right_item">';              $datatable .= '<td class="LC_right_item">';
         }          }
         $datatable .=          $datatable .= 
             '<span class="LC_nobreak">'.              '<span class="LC_nobreak">'.
             '<label><input type="radio" name="'.              '<label><input type="radio" name="'.
             $item.'" '.$checkedon{$item}.' value="1"'.$onclick.' />'.&mt('Yes').              $item.'" '.$checkedon{$item}.' value="1"'.$onclick.' />'.&mt('Yes').
Line 3497  sub radiobutton_prefs { Line 3188  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);
     my $itemcount = 1;      my $itemcount = 1;
     my %choices =  &Apache::lonlocal::texthash (      my %choices =  &Apache::lonlocal::texthash (
           canuse_pdfforms      => 'Course/Community users can create/upload PDF forms',
         uploadquota          => 'Default quota for files uploaded directly to course/community using Course Editor (MB)',          uploadquota          => 'Default quota for files uploaded directly to course/community using Course Editor (MB)',
         anonsurvey_threshold => 'Responder count needed before showing submissions for anonymous surveys',          anonsurvey_threshold => 'Responder count needed before showing submissions for anonymous surveys',
         coursecredits        => 'Credits can be specified for courses',          coursecredits        => 'Credits can be specified for courses',
Line 3519  sub print_coursedefaults { Line 3557  sub print_coursedefaults {
                          );                           );
     if ($position eq 'top') {      if ($position eq 'top') {
         %defaultchecked = (          %defaultchecked = (
                               'canuse_pdfforms' => 'off',
                             'uselcmath'       => 'on',                              'uselcmath'       => 'on',
                             'usejsme'         => 'on',                              'usejsme'         => 'on',
                             'canclone'        => 'none',                              'canclone'        => 'none', 
                           );                            );
         @toggles = ('uselcmath','usejsme');          @toggles = ('canuse_pdfforms','uselcmath','usejsme');
         ($datatable,$itemcount) = &radiobutton_prefs($settings,\@toggles,\%defaultchecked,          ($datatable,$itemcount) = &radiobutton_prefs($settings,\@toggles,\%defaultchecked,
                                                      \%choices,$itemcount);                                                       \%choices,$itemcount);
         $css_class = $itemcount%2?' class="LC_odd_row"':'';          $css_class = $itemcount%2?' class="LC_odd_row"':'';
Line 3560  sub print_coursedefaults { Line 3599  sub print_coursedefaults {
                     $currcanclone = $settings->{'canclone'};                      $currcanclone = $settings->{'canclone'};
                 }                  }
             }              }
         }          } 
         foreach my $option (@cloneoptions) {          foreach my $option (@cloneoptions) {
             my ($checked,$additional);              my ($checked,$additional);
             if ($currcanclone eq $option) {              if ($currcanclone eq $option) {
Line 3602  sub print_coursedefaults { Line 3641  sub print_coursedefaults {
         my ($currdefresponder,%defcredits,%curruploadquota,%deftimeout,%currmysql);          my ($currdefresponder,%defcredits,%curruploadquota,%deftimeout,%currmysql);
         my $currusecredits = 0;          my $currusecredits = 0;
         my $postsubmitclient = 1;          my $postsubmitclient = 1;
         my @types = ('official','unofficial','community','textbook');          my @types = ('official','unofficial','community','textbook','placement');
         if (ref($settings) eq 'HASH') {          if (ref($settings) eq 'HASH') {
             $currdefresponder = $settings->{'anonsurvey_threshold'};              $currdefresponder = $settings->{'anonsurvey_threshold'};
             if (ref($settings->{'uploadquota'}) eq 'HASH') {              if (ref($settings->{'uploadquota'}) eq 'HASH') {
Line 3629  sub print_coursedefaults { Line 3668  sub print_coursedefaults {
                     foreach my $type (@types) {                      foreach my $type (@types) {
                         if (ref($settings->{'postsubmit'}->{'timeout'}) eq 'HASH') {                          if (ref($settings->{'postsubmit'}->{'timeout'}) eq 'HASH') {
                             if ($settings->{'postsubmit'}->{'timeout'}->{$type} =~ /^\d+$/) {                              if ($settings->{'postsubmit'}->{'timeout'}->{$type} =~ /^\d+$/) {
                                 $deftimeout{$type} = $settings->{'postsubmit'}->{'timeout'}->{$type};                                  $deftimeout{$type} = $settings->{'postsubmit'}->{'timeout'}->{$type}; 
                             } else {                              } else {
                                 $deftimeout{$type} = $staticdefaults{'postsubmit'};                                  $deftimeout{$type} = $staticdefaults{'postsubmit'};
                             }                              }
Line 3745  sub print_coursedefaults { Line 3784  sub print_coursedefaults {
         foreach my $type (@types) {          foreach my $type (@types) {
             $datatable .= '<td align="center">'.&mt($type).'<br />'.              $datatable .= '<td align="center">'.&mt($type).'<br />'.
                            '<input type="text" name="mysqltables_'.$type.'"'.                             '<input type="text" name="mysqltables_'.$type.'"'.
                            ' value="'.$currmysql{$type}.'" size="8" /></td>';                             ' value="'.$currmysql{$type}.'" size="5" /></td>';
         }          }
         $datatable .= '</tr></table></td></tr>'."\n";          $datatable .= '</tr></table></td></tr>'."\n";
         $itemcount ++;          $itemcount ++;
Line 3759  sub print_selfenrollment { Line 3798  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 3982  sub print_validation_rows { Line 4021  sub print_validation_rows {
   
 sub print_usersessions {  sub print_usersessions {
     my ($position,$dom,$settings,$rowtotal) = @_;      my ($position,$dom,$settings,$rowtotal) = @_;
     my ($css_class,$datatable,%checked,%choices);      my ($css_class,$datatable,$itemcount,%checked,%choices);
     my (%by_ip,%by_location,@intdoms);      my (%by_ip,%by_location,@intdoms,@instdoms);
     &build_location_hashes(\@intdoms,\%by_ip,\%by_location);      &build_location_hashes(\@intdoms,\%by_ip,\%by_location,\@instdoms);
   
     my @alldoms = &Apache::lonnet::all_domains();      my @alldoms = &Apache::lonnet::all_domains();
     my %serverhomes = %Apache::lonnet::serverhomeIDs;      my %serverhomes = %Apache::lonnet::serverhomeIDs;
     my %servers = &Apache::lonnet::internet_dom_servers($dom);      my %servers = &Apache::lonnet::internet_dom_servers($dom);
     my %altids = &id_for_thisdom(%servers);      my %altids = &id_for_thisdom(%servers);
     my $itemcount = 1;  
     if ($position eq 'top') {      if ($position eq 'top') {
         if (keys(%serverhomes) > 1) {          if (keys(%serverhomes) > 1) {
             my %spareid = &current_offloads_to($dom,$settings,\%servers);              my %spareid = &current_offloads_to($dom,$settings,\%servers);
Line 4003  sub print_usersessions { Line 4041  sub print_usersessions {
             $datatable .= &spares_row($dom,\%servers,\%spareid,\%serverhomes,\%altids,$curroffloadnow,$rowtotal);              $datatable .= &spares_row($dom,\%servers,\%spareid,\%serverhomes,\%altids,$curroffloadnow,$rowtotal);
         } else {          } else {
             $datatable .= '<tr'.$css_class.'><td colspan="2">'.              $datatable .= '<tr'.$css_class.'><td colspan="2">'.
                           &mt('Nothing to set here, as the cluster to which this domain belongs only contains one server.');                            &mt('Nothing to set here, as the cluster to which this domain belongs only contains one server.').
                             '</td></tr>';
         }          }
     } else {      } else {
         if (keys(%by_location) == 0) {          my %titles = &usersession_titles();
             $datatable .= '<tr'.$css_class.'><td colspan="2">'.          my ($prefix,@types);
                           &mt('Nothing to set here, as the cluster to which this domain belongs only contains one institution.');          if ($position eq 'bottom') {
               $prefix = 'remote';
               @types = ('version','excludedomain','includedomain');
         } else {          } else {
             my %lt = &usersession_titles();              $prefix = 'hosted';
             my $numinrow = 5;              @types = ('excludedomain','includedomain');
             my $prefix;          }
             my @types;          ($datatable,$itemcount) = &rules_by_location($settings,$prefix,\%by_location,\%by_ip,\@types,\%titles);
             if ($position eq 'bottom') {      }
                 $prefix = 'remote';      $$rowtotal += $itemcount;
                 @types = ('version','excludedomain','includedomain');      return $datatable;
             } else {  }
                 $prefix = 'hosted';  
                 @types = ('excludedomain','includedomain');  sub rules_by_location {
             }      my ($settings,$prefix,$by_location,$by_ip,$types,$titles) = @_; 
             my (%current,%checkedon,%checkedoff);      my ($datatable,$itemcount,$css_class);
             my @lcversions = &Apache::lonnet::all_loncaparevs();      if (keys(%{$by_location}) == 0) {
             my @locations = sort(keys(%by_location));          $css_class = $itemcount%2 ? ' class="LC_odd_row"' : '';
             foreach my $type (@types) {          $datatable = '<tr'.$css_class.'><td colspan="2">'.
                 $checkedon{$type} = '';                       &mt('Nothing to set here, as the cluster to which this domain belongs only contains one institution.').
                 $checkedoff{$type} = ' checked="checked"';                       '</td></tr>';
             }          $itemcount = 1;
             if (ref($settings) eq 'HASH') {      } else {
                 if (ref($settings->{$prefix}) eq 'HASH') {          $itemcount = 0;
                     foreach my $key (keys(%{$settings->{$prefix}})) {          my $numinrow = 5;
                         $current{$key} = $settings->{$prefix}{$key};          my (%current,%checkedon,%checkedoff);
                         if ($key eq 'version') {          my @locations = sort(keys(%{$by_location}));
                             if ($current{$key} ne '') {          foreach my $type (@{$types}) {
                                 $checkedon{$key} = ' checked="checked"';              $checkedon{$type} = '';
                                 $checkedoff{$key} = '';              $checkedoff{$type} = ' checked="checked"';
                             }          }
                         } elsif (ref($current{$key}) eq 'ARRAY') {          if (ref($settings) eq 'HASH') {
               if (ref($settings->{$prefix}) eq 'HASH') {
                   foreach my $key (keys(%{$settings->{$prefix}})) {
                       $current{$key} = $settings->{$prefix}{$key};
                       if ($key eq 'version') {
                           if ($current{$key} ne '') {
                             $checkedon{$key} = ' checked="checked"';                              $checkedon{$key} = ' checked="checked"';
                             $checkedoff{$key} = '';                              $checkedoff{$key} = '';
                         }                          }
                       } elsif (ref($current{$key}) eq 'ARRAY') {
                           $checkedon{$key} = ' checked="checked"';
                           $checkedoff{$key} = '';
                     }                      }
                 }                  }
             }              }
             foreach my $type (@types) {          }
                 next if ($type ne 'version' && !@locations);          foreach my $type (@{$types}) {
                 $css_class = $itemcount%2 ? ' class="LC_odd_row"' : '';              next if ($type ne 'version' && !@locations);
                 $datatable .= '<tr'.$css_class.'>              $css_class = $itemcount%2 ? ' class="LC_odd_row"' : '';
                                <td><span class="LC_nobreak">'.$lt{$type}.'</span><br />              $datatable .= '<tr'.$css_class.'>
                                <span class="LC_nobreak">&nbsp;                             <td><span class="LC_nobreak">'.$titles->{$type}.'</span><br />
                                <label><input type="radio" name="'.$prefix.'_'.$type.'_inuse" '.$checkedoff{$type}.' value="0" />'.&mt('Not in use').'</label>&nbsp;                             <span class="LC_nobreak">&nbsp;
                                <label><input type="radio" name="'.$prefix.'_'.$type.'_inuse" '.$checkedon{$type}.' value="1" />'.&mt('In use').'</label></span></td><td>';                             <label><input type="radio" name="'.$prefix.'_'.$type.'_inuse" '.$checkedoff{$type}.' value="0" />'.&mt('Not in use').'</label>&nbsp;
                 if ($type eq 'version') {                             <label><input type="radio" name="'.$prefix.'_'.$type.'_inuse" '.$checkedon{$type}.' value="1" />'.&mt('In use').'</label></span></td><td>';
                     my $selector = '<select name="'.$prefix.'_version">';              if ($type eq 'version') {
                     foreach my $version (@lcversions) {                  my @lcversions = &Apache::lonnet::all_loncaparevs();
                         my $selected = '';                  my $selector = '<select name="'.$prefix.'_version">';
                         if ($current{'version'} eq $version) {                  foreach my $version (@lcversions) {
                             $selected = ' selected="selected"';                      my $selected = '';
                         }                      if ($current{'version'} eq $version) {
                         $selector .= ' <option value="'.$version.'"'.                          $selected = ' selected="selected"';
                                      $selected.'>'.$version.'</option>';  
                     }                      }
                     $selector .= '</select> ';                      $selector .= ' <option value="'.$version.'"'.
                     $datatable .= &mt('remote server must be version: [_1] or later',$selector);                                   $selected.'>'.$version.'</option>';
                 } else {                  }
                     $datatable.= '<div><input type="button" value="'.&mt('check all').'" '.                  $selector .= '</select> ';
                                  'onclick="javascript:checkAll(document.display.'.$prefix.'_'.$type.')"'.                  $datatable .= &mt('remote server must be version: [_1] or later',$selector);
                                  ' />'.('&nbsp;'x2).              } else {
                                  '<input type="button" value="'.&mt('uncheck all').'" '.                  $datatable.= '<div><input type="button" value="'.&mt('check all').'" '.
                                  'onclick="javascript:uncheckAll(document.display.'.$prefix.'_'.$type.')" />'.                               'onclick="javascript:checkAll(document.display.'.$prefix.'_'.$type.')"'.
                                  "\n".                               ' />'.('&nbsp;'x2).
                                  '</div><div><table>';                               '<input type="button" value="'.&mt('uncheck all').'" '.
                     my $rem;                               'onclick="javascript:uncheckAll(document.display.'.$prefix.'_'.$type.')" />'.
                     for (my $i=0; $i<@locations; $i++) {                               "\n".
                         my ($showloc,$value,$checkedtype);                               '</div><div><table>';
                         if (ref($by_location{$locations[$i]}) eq 'ARRAY') {                  my $rem;
                             my $ip = $by_location{$locations[$i]}->[0];                  for (my $i=0; $i<@locations; $i++) {
                             if (ref($by_ip{$ip}) eq 'ARRAY') {                      my ($showloc,$value,$checkedtype);
                                  $value = join(':',@{$by_ip{$ip}});                      if (ref($by_location->{$locations[$i]}) eq 'ARRAY') {
                                 $showloc = join(', ',@{$by_ip{$ip}});                          my $ip = $by_location->{$locations[$i]}->[0];
                                 if (ref($current{$type}) eq 'ARRAY') {                          if (ref($by_ip->{$ip}) eq 'ARRAY') {
                                     foreach my $loc (@{$by_ip{$ip}}) {                                $value = join(':',@{$by_ip->{$ip}});
                                         if (grep(/^\Q$loc\E$/,@{$current{$type}})) {                              $showloc = join(', ',@{$by_ip->{$ip}});
                                             $checkedtype = ' checked="checked"';                              if (ref($current{$type}) eq 'ARRAY') {
                                             last;                                  foreach my $loc (@{$by_ip->{$ip}}) {
                                         }                                      if (grep(/^\Q$loc\E$/,@{$current{$type}})) {
                                           $checkedtype = ' checked="checked"';
                                           last;
                                     }                                      }
                                 }                                  }
                             }                              }
                         }                          }
                         $rem = $i%($numinrow);  
                         if ($rem == 0) {  
                             if ($i > 0) {  
                                 $datatable .= '</tr>';  
                             }  
                             $datatable .= '<tr>';  
                         }  
                         $datatable .= '<td class="LC_left_item">'.  
                                       '<span class="LC_nobreak"><label>'.  
                                       '<input type="checkbox" name="'.$prefix.'_'.$type.  
                                       '" value="'.$value.'"'.$checkedtype.' />'.$showloc.  
                                       '</label></span></td>';  
                     }                      }
                     $rem = @locations%($numinrow);                      $rem = $i%($numinrow);
                     my $colsleft = $numinrow - $rem;                      if ($rem == 0) {
                     if ($colsleft > 1 ) {                          if ($i > 0) {
                         $datatable .= '<td colspan="'.$colsleft.'" class="LC_left_item">'.                              $datatable .= '</tr>';
                                       '&nbsp;</td>';                          }
                     } elsif ($colsleft == 1) {                          $datatable .= '<tr>';
                         $datatable .= '<td class="LC_left_item">&nbsp;</td>';                      }
                       $datatable .= '<td class="LC_left_item">'.
                                     '<span class="LC_nobreak"><label>'.
                                     '<input type="checkbox" name="'.$prefix.'_'.$type.
                                     '" value="'.$value.'"'.$checkedtype.' />'.$showloc.
                                     '</label></span></td>';
                   }
                   $rem = @locations%($numinrow);
                   my $colsleft = $numinrow - $rem;
                   if ($colsleft > 1 ) {
                       $datatable .= '<td colspan="'.$colsleft.'" class="LC_left_item">'.
                                     '&nbsp;</td>';
                   } elsif ($colsleft == 1) {
                       $datatable .= '<td class="LC_left_item">&nbsp;</td>';
                   }
                   $datatable .= '</tr></table>';
               }
               $datatable .= '</td></tr>';
               $itemcount ++;
           }
       }
       return ($datatable,$itemcount);
   }
   
   sub print_ssl {
       my ($position,$dom,$settings,$rowtotal) = @_;
       my ($css_class,$datatable);
       my $itemcount = 1;
       if ($position eq 'top') {
           my $primary_id = &Apache::lonnet::domain($dom,'primary');
           my $intdom = &Apache::lonnet::internet_dom($primary_id);
           my $same_institution;
           if ($intdom ne '') {
               my $internet_names = &Apache::lonnet::get_internet_names($Apache::lonnet::perlvar{'lonHostID'});
               if (ref($internet_names) eq 'ARRAY') {
                   if (grep(/^\Q$intdom\E$/,@{$internet_names})) {
                       $same_institution = 1;
                   }
               }
           }
           $css_class = $itemcount%2?' class="LC_odd_row"':'';
           $datatable = '<tr'.$css_class.'><td colspan="2">';
           if ($same_institution) {
               my %domservers = &Apache::lonnet::get_servers($dom);
               $datatable .= &LONCAPA::SSL::print_certstatus(\%domservers,'web','domprefs');
           } else {
               $datatable .= &mt("You need to be logged into one of your own domain's servers to display information about the status of LON-CAPA SSL certificates.");
           }
           $datatable .= '</td></tr>';
           $itemcount ++;
       } else {
           my %titles = &ssl_titles();
           my (%by_ip,%by_location,@intdoms,@instdoms);
           &build_location_hashes(\@intdoms,\%by_ip,\%by_location,\@instdoms);
           my @alldoms = &Apache::lonnet::all_domains();
           my %serverhomes = %Apache::lonnet::serverhomeIDs;
           my @domservers = &Apache::lonnet::get_servers($dom);
           my %servers = &Apache::lonnet::internet_dom_servers($dom);
           my %altids = &id_for_thisdom(%servers);
           if ($position eq 'middle') {
               foreach my $type ('dom','intdom','other') {
                   my %checked;
                   $css_class = $itemcount%2?' class="LC_odd_row"':'';
                   $datatable .= '<tr'.$css_class.'><td>'.$titles{$type}.'</td>'.
                                 '<td class="LC_right_item">';
                   my $skip; 
                   if ($type eq 'dom') {
                       unless (keys(%servers) > 1) {
                           $datatable .= &mt('Nothing to set here, as there are no other servers/VMs');    
                           $skip = 1;
                       }
                   }
                   if ($type eq 'intdom') {
                       unless (@instdoms > 1) {
                           $datatable .= &mt('Nothing to set here, as there are no other domains for this institution');
                           $skip = 1;
                       } 
                   } elsif ($type eq 'other') {
                       if (keys(%by_location) == 0) {
                           $datatable .= &mt('Nothing to set here, as there are no other institutions');
                           $skip = 1;
                       }
                   }
                   unless ($skip) {
                       $checked{'yes'} = ' checked="checked"'; 
                       if (ref($settings) eq 'HASH') {
                           if (ref($settings->{'connect'}) eq 'HASH') {
                               if ($settings->{'connect'}->{$type} =~ /^(no|req)$/) {
                                   $checked{$1} = $checked{'yes'};
                                   delete($checked{'yes'}); 
                               }
                           }
                       }
                       foreach my $option ('no','yes','req') {
                           $datatable .= '<span class="LC_nobreak"><label>'.
                                         '<input type="radio" name="connect_'.$type.'" '.
                                         'value="'.$option.'"'.$checked{$option}.' />'.$titles{$option}.
                                         '</label></span>'.('&nbsp;'x2);
                     }                      }
                     $datatable .= '</tr></table>';  
                 }                  }
                 $datatable .= '</td></tr>';                  $datatable .= '</td></tr>';
                   $itemcount ++; 
               }
           } else {
               my $prefix = 'replication';
               my @types = ('certreq','nocertreq');
               if (keys(%by_location) == 0) {
                   $datatable .= '<tr'.$css_class.'><td>'.
                                 &mt('Nothing to set here, as there are no other institutions').
                                 '</td></tr>';
                 $itemcount ++;                  $itemcount ++;
               } else {
                   ($datatable,$itemcount) = 
                       &rules_by_location($settings,$prefix,\%by_location,\%by_ip,\@types,\%titles);
             }              }
         }          }
     }      }
Line 4122  sub print_usersessions { Line 4268  sub print_usersessions {
     return $datatable;      return $datatable;
 }  }
   
   sub ssl_titles {
       return &Apache::lonlocal::texthash (
                  dom           => 'LON-CAPA servers/VMs from same domain',
                  intdom        => 'LON-CAPA servers/VMs from same "internet" domain',
                  other         => 'External LON-CAPA servers/VMs',
                  connect       => 'Connections to other servers',
                  replication   => 'Replicating content to other institutions',
                  certreq       => 'Client certificate required, but specific domains exempt',
                  nocertreq     => 'No client certificate required, except for specific domains',
                  no            => 'SSL not used',
                  yes           => 'SSL Optional (used if available)',
                  req           => 'SSL Required',
       );
   }
   
   sub print_trust {
       my ($prefix,$dom,$settings,$rowtotal) = @_;
       my ($css_class,$datatable,%checked,%choices);
       my (%by_ip,%by_location,@intdoms,@instdoms);
       &build_location_hashes(\@intdoms,\%by_ip,\%by_location,\@instdoms);
       my $itemcount = 1;
       my %titles = &trust_titles();
       my @types = ('exc','inc');
       if ($prefix eq 'top') {
           $prefix = 'content';
       } elsif ($prefix eq 'bottom') {
           $prefix = 'msg';
       }
       ($datatable,$itemcount) = &rules_by_location($settings,$prefix,\%by_location,\%by_ip,\@types,\%titles);
       $$rowtotal += $itemcount;
       return $datatable;
   }
   
   sub trust_titles {
       return &Apache::lonlocal::texthash(
                  content  => "Access to this domain's content by others",
                  shared   => "Access to other domain's content by this domain",
                  enroll   => "Enrollment in this domain's courses by others", 
                  othcoau  => "Co-author roles in this domain for others",
                  coaurem  => "Co-author roles for this domain's users elsewhere", 
                  domroles => "Domain roles in this domain assignable to others",
                  catalog  => "Course Catalog for this domain displayed elsewhere",
                  reqcrs   => "Requests for creation of courses in this domain by others",
                  msg      => "Users in other domains can send messages to this domain",
                  exc      => "Allow all, but exclude specific domains",
                  inc      => "Deny all, but include specific domains",
              );
   } 
   
 sub build_location_hashes {  sub build_location_hashes {
     my ($intdoms,$by_ip,$by_location) = @_;      my ($intdoms,$by_ip,$by_location,$instdoms) = @_;
     return unless((ref($intdoms) eq 'ARRAY') && (ref($by_ip) eq 'HASH') &&      return unless((ref($intdoms) eq 'ARRAY') && (ref($by_ip) eq 'HASH') &&
                   (ref($by_location) eq 'HASH'));                     (ref($by_location) eq 'HASH') && (ref($instdoms) eq 'ARRAY'));
     my %iphost = &Apache::lonnet::get_iphost();      my %iphost = &Apache::lonnet::get_iphost();
     my $primary_id = &Apache::lonnet::domain($env{'request.role.domain'},'primary');      my $primary_id = &Apache::lonnet::domain($env{'request.role.domain'},'primary');
     my $primary_ip = &Apache::lonnet::get_host_ip($primary_id);      my $primary_ip = &Apache::lonnet::get_host_ip($primary_id);
Line 4142  sub build_location_hashes { Line 4337  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 4282  sub spares_row { Line 4483  sub spares_row {
                             <span class="LC_nobreak">'.                              <span class="LC_nobreak">'.
                           &mt('[_1] when busy, offloads to:'                            &mt('[_1] when busy, offloads to:'
                               ,'<b>'.$server.'</b>').'</span><br />'.                                ,'<b>'.$server.'</b>').'</span><br />'.
                           '<span class="LC_nobreak">'."\n".                            '<span class="LC_nobreak">'."\n". 
                           '<label><input type="checkbox" name="offloadnow" value="'.$server.'"'.$checkednow.' />'.                            '<label><input type="checkbox" name="offloadnow" value="'.$server.'"'.$checkednow.' />'.
                           '&nbsp;'.&mt('Switch active users on next access').'</label></span>'.                            '&nbsp;'.&mt('Switch active users on next access').'</label></span>'.
                           "\n";                            "\n";
Line 4489  sub print_loadbalancing { Line 4690  sub print_loadbalancing {
         my ($numspares,@spares) = &count_servers($lonhost,%servers);          my ($numspares,@spares) = &count_servers($lonhost,%servers);
         my @sparestypes = ('primary','default');          my @sparestypes = ('primary','default');
         my %typetitles = &sparestype_titles();          my %typetitles = &sparestype_titles();
         my %hostherechecked = (  
                                   no => ' checked="checked"',  
                               );  
         foreach my $sparetype (@sparestypes) {          foreach my $sparetype (@sparestypes) {
             my $targettable;              my $targettable;
             for (my $i=0; $i<$numspares; $i++) {              for (my $i=0; $i<$numspares; $i++) {
Line 4537  sub print_loadbalancing { Line 4735  sub print_loadbalancing {
                 $datatable .=  '<i>'.$typetitles{$sparetype}.'</i><br />'.                  $datatable .=  '<i>'.$typetitles{$sparetype}.'</i><br />'.
                                '<table><tr>'.$targettable.'</tr></table><br />';                                 '<table><tr>'.$targettable.'</tr></table><br />';
             }              }
             $hostherechecked{$sparetype} = '';  
             if (ref($currtargets{$lonhost}) eq 'HASH') {  
                 if (ref($currtargets{$lonhost}{$sparetype}) eq 'ARRAY') {  
                     if (grep(/^\Q$lonhost\E$/,@{$currtargets{$lonhost}{$sparetype}})) {  
                         $hostherechecked{$sparetype} = ' checked="checked"';  
                         $hostherechecked{'no'} = '';  
                     }  
                 }  
             }  
         }  
         $datatable .= &mt('Hosting on balancer itself').'<br />'.  
                       '<label><input type="radio" name="loadbalancing_target_'.$balnum.'_hosthere" value="no"'.  
                       $hostherechecked{'no'}.' />'.&mt('No').'</label><br />';  
         foreach my $sparetype (@sparestypes) {  
             $datatable .= '<label><input type="radio" name="loadbalancing_target_'.$balnum.'_hosthere" '.  
                           'value="'.$sparetype.'"'.$hostherechecked{$sparetype}.' /><i>'.$typetitles{$sparetype}.  
                           '</i></label><br />';  
         }          }
         $datatable .= '</div></td></tr>'.          $datatable .= '</div></td></tr>'.
                       &loadbalancing_rules($dom,$intdom,$currrules{$lonhost},                        &loadbalancing_rules($dom,$intdom,$currrules{$lonhost},
Line 4646  sub loadbalancing_titles { Line 4827  sub loadbalancing_titles {
            '_LC_ipchange'    => &mt('Non-SSO users with IP mismatch'),             '_LC_ipchange'    => &mt('Non-SSO users with IP mismatch'),
                      );                       );
     my @alltypes = ('_LC_adv','_LC_author','_LC_internetdom','_LC_external','_LC_ipchangesso','_LC_ipchange');      my @alltypes = ('_LC_adv','_LC_author','_LC_internetdom','_LC_external','_LC_ipchangesso','_LC_ipchange');
     my @available;  
     if (ref($types) eq 'ARRAY') {      if (ref($types) eq 'ARRAY') {
         @available = @{$types};          unshift(@alltypes,@{$types},'default');
     }  
     unless (grep(/^default$/,@available)) {  
         push(@available,'default');  
     }      }
     unshift(@alltypes,@available);  
     my %titles;      my %titles;
     foreach my $type (@alltypes) {      foreach my $type (@alltypes) {
         if ($type =~ /^_LC_/) {          if ($type =~ /^_LC_/) {
Line 4776  sub sparestype_titles { Line 4952  sub sparestype_titles {
   
 sub contact_titles {  sub contact_titles {
     my %titles = &Apache::lonlocal::texthash (      my %titles = &Apache::lonlocal::texthash (
                    'supportemail'    => 'Support E-mail address',                     'supportemail' => 'Support E-mail address',
                    'adminemail'      => 'Default Server Admin E-mail address',                     'adminemail'   => 'Default Server Admin E-mail address',
                    'errormail'       => 'Error reports to be e-mailed to',                     'errormail'    => 'Error reports to be e-mailed to',
                    'packagesmail'    => 'Package update alerts to be e-mailed to',                     'packagesmail' => 'Package update alerts to be e-mailed to',
                    'helpdeskmail'    => "Helpdesk requests for this domain's users",                     'helpdeskmail' => 'Helpdesk requests to be e-mailed to',
                    'otherdomsmail'   => 'Helpdesk requests for other (unconfigured) domains',                     'lonstatusmail' => 'E-mail from nightly status check (warnings/errors)',
                    'lonstatusmail'   => 'E-mail from nightly status check (warnings/errors)',                     'requestsmail' => 'E-mail from course requests requiring approval',
                    'requestsmail'    => 'E-mail from course requests requiring approval',                     'updatesmail'  => 'E-mail from nightly check of LON-CAPA module integrity/updates',
                    'updatesmail'     => 'E-mail from nightly check of LON-CAPA module integrity/updates',  
                    'idconflictsmail' => 'E-mail from bi-nightly check for multiple users sharing same student/employee ID',                     'idconflictsmail' => 'E-mail from bi-nightly check for multiple users sharing same student/employee ID',
                  );                   );
     my %short_titles = &Apache::lonlocal::texthash (      my %short_titles = &Apache::lonlocal::texthash (
Line 4794  sub contact_titles { Line 4969  sub contact_titles {
     return (\%titles,\%short_titles);      return (\%titles,\%short_titles);
 }  }
   
 sub helpform_fields {  
     my %titles =  &Apache::lonlocal::texthash (  
                        'username'   => 'Name',  
                        'user'       => 'Username/domain',  
                        'phone'      => 'Phone',  
                        'cc'         => 'Cc e-mail',  
                        'course'     => 'Course Details',  
                        'section'    => 'Sections',  
                        'screenshot' => 'File upload',  
     );  
     my @fields = ('username','phone','user','course','section','cc','screenshot');  
     my %possoptions = (  
                         username     => ['yes','no','req'],  
                         phone        => ['yes','no','req'],  
                         user         => ['yes','no'],  
                         cc           => ['yes','no'],  
                         course       => ['yes','no'],  
                         section      => ['yes','no'],  
                         screenshot   => ['yes','no'],  
                       );  
     my %fieldoptions = &Apache::lonlocal::texthash (  
                          'yes'  => 'Optional',  
                          'req'  => 'Required',  
                          'no'   => "Not shown",  
     );  
     return (\@fields,\%titles,\%fieldoptions,\%possoptions);  
 }  
   
 sub tool_titles {  sub tool_titles {
     my %titles = &Apache::lonlocal::texthash (      my %titles = &Apache::lonlocal::texthash (
                      aboutme    => 'Personal web page',                       aboutme    => 'Personal web page',
Line 4832  sub tool_titles { Line 4979  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 4842  sub courserequest_titles { Line 4990  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 5006  sub print_usercreation { Line 5155  sub print_usercreation {
   
 sub print_selfcreation {  sub print_selfcreation {
     my ($position,$dom,$settings,$rowtotal) = @_;      my ($position,$dom,$settings,$rowtotal) = @_;
     my (@selfcreate,$createsettings,$processing,$emailoptions,$emailverified,      my (@selfcreate,$createsettings,$processing,$datatable);
         $emaildomain,$datatable);  
     if (ref($settings) eq 'HASH') {      if (ref($settings) eq 'HASH') {
         if (ref($settings->{'cancreate'}) eq 'HASH') {          if (ref($settings->{'cancreate'}) eq 'HASH') {
             $createsettings = $settings->{'cancreate'};              $createsettings = $settings->{'cancreate'};
Line 5024  sub print_selfcreation { Line 5172  sub print_selfcreation {
                 if (ref($createsettings->{'selfcreateprocessing'}) eq 'HASH') {                  if (ref($createsettings->{'selfcreateprocessing'}) eq 'HASH') {
                     $processing = $createsettings->{'selfcreateprocessing'};                      $processing = $createsettings->{'selfcreateprocessing'};
                 }                  }
                 if (ref($createsettings->{'emailoptions'}) eq 'HASH') {  
                     $emailoptions = $createsettings->{'emailoptions'};  
                 }  
                 if (ref($createsettings->{'emailverified'}) eq 'HASH') {  
                     $emailverified = $createsettings->{'emailverified'};  
                 }  
                 if (ref($createsettings->{'emaildomain'}) eq 'HASH') {  
                     $emaildomain = $createsettings->{'emaildomain'};  
                 }  
             }              }
         }          }
     }      }
     my %radiohash;      my %radiohash;
     my $numinrow = 4;      my $numinrow = 4;
     map { $radiohash{'cancreate_'.$_} = 1; } @selfcreate;      map { $radiohash{'cancreate_'.$_} = 1; } @selfcreate;
     my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom);  
     if ($position eq 'top') {      if ($position eq 'top') {
         my %choices = &Apache::lonlocal::texthash (          my %choices = &Apache::lonlocal::texthash (
                                                       cancreate_login      => 'Institutional Login',                                                        cancreate_login      => 'Institutional Login',
Line 5055  sub print_selfcreation { Line 5193  sub print_selfcreation {
                                                      \%choices,$itemcount,$onclick);                                                       \%choices,$itemcount,$onclick);
         $$rowtotal += $itemcount;          $$rowtotal += $itemcount;
                   
           my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom);
   
         if (ref($usertypes) eq 'HASH') {          if (ref($usertypes) eq 'HASH') {
             if (keys(%{$usertypes}) > 0) {              if (keys(%{$usertypes}) > 0) {
                 $datatable .= &insttypes_row($createsettings,$types,$usertypes,                  $datatable .= &insttypes_row($createsettings,$types,$usertypes,
                                              $dom,$numinrow,$othertitle,                                               $dom,$numinrow,$othertitle,
                                              'statustocreate',$rowtotal);                                               'statustocreate',$$rowtotal);
                 $$rowtotal ++;                  $$rowtotal ++;
             }              }
         }          }
Line 5104  sub print_selfcreation { Line 5244  sub print_selfcreation {
         $$rowtotal ++;          $$rowtotal ++;
     } elsif ($position eq 'middle') {      } elsif ($position eq 'middle') {
         my %domconf = &Apache::lonnet::get_dom('configuration',['usermodification'],$dom);          my %domconf = &Apache::lonnet::get_dom('configuration',['usermodification'],$dom);
         my @posstypes;          my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom);
           $usertypes->{'default'} = $othertitle;
         if (ref($types) eq 'ARRAY') {          if (ref($types) eq 'ARRAY') {
             @posstypes = @{$types};              push(@{$types},'default');
         }              $usertypes->{'default'} = $othertitle;
         unless (grep(/^default$/,@posstypes)) {              foreach my $status (@{$types}) {
             push(@posstypes,'default');                  $datatable .= &modifiable_userdata_row('selfcreate',$status,$domconf{'usermodification'},
         }                                                         $numinrow,$$rowtotal,$usertypes);
         my %usertypeshash;                  $$rowtotal ++;
         if (ref($usertypes) eq 'HASH') {              }
             %usertypeshash = %{$usertypes};  
         }  
         $usertypeshash{'default'} = $othertitle;  
         foreach my $status (@posstypes) {  
             $datatable .= &modifiable_userdata_row('selfcreate',$status,$domconf{'usermodification'},  
                                                    $numinrow,$$rowtotal,\%usertypeshash);  
             $$rowtotal ++;  
         }          }
     } else {      } else {
         my %choices = &Apache::lonlocal::texthash (          my %choices = &Apache::lonlocal::texthash (
                           'cancreate_email' => 'Non-institutional username (via e-mail verification)',                                                        cancreate_email => 'E-mail address as username',
                                                   );                                                    );
         my @toggles = sort(keys(%choices));          my @toggles = sort(keys(%choices));
         my %defaultchecked = (          my %defaultchecked = (
                                'cancreate_email' => 'off',                                 'cancreate_email' => 'off',
                              );                               );
         my $customclass = 'LC_selfcreate_email';          my $itemcount = 0;
         my $classprefix = 'LC_canmodify_emailusername_';  
         my $optionsprefix = 'LC_options_emailusername_';  
         my $display = 'none';          my $display = 'none';
         my $rowstyle = 'display:none';  
         if (grep(/^\Qemail\E$/,@selfcreate)) {          if (grep(/^\Qemail\E$/,@selfcreate)) {
             $display = 'block';              $display = 'block';
             $rowstyle = 'display:table-row';  
         }          }
         my $onclick = "toggleRows(this.form,'cancreate_email','selfassign','$customclass','$classprefix','$optionsprefix');";          my $onclick = "toggleDisplay(this.form,'emailoptions');";
         ($datatable,$$rowtotal) = &radiobutton_prefs(\%radiohash,\@toggles,\%defaultchecked,          my $additional = '<div id="emailoptions" style="display: '.$display.'">';
                                                      \%choices,$$rowtotal,$onclick);  
         $datatable .= &print_requestmail($dom,'selfcreation',$createsettings,$rowtotal,$customclass,  
                                          $rowstyle);  
         $$rowtotal ++;  
         $datatable .= &captcha_choice('cancreate',$createsettings,$$rowtotal,$customclass,  
                                       $rowstyle);  
         $$rowtotal ++;  
         my (@ordered,@posstypes,%usertypeshash);  
         my %domdefaults = &Apache::lonnet::get_domain_defaults($dom);          my %domdefaults = &Apache::lonnet::get_domain_defaults($dom);
         my ($emailrules,$emailruleorder) =          my $usertypes = {};
             &Apache::lonnet::inst_userrules($dom,'email');          my $order = [];
         my $primary_id = &Apache::lonnet::domain($dom,'primary');          if ((ref($domdefaults{'inststatustypes'}) eq 'HASH') && (ref($domdefaults{'inststatusguest'}) eq 'ARRAY')) {
         my $intdom = &Apache::lonnet::internet_dom($primary_id);              $usertypes = $domdefaults{'inststatustypes'};
         if (ref($types) eq 'ARRAY') {              $order = $domdefaults{'inststatusguest'};
             @posstypes = @{$types};          }
         }          if (ref($order) eq 'ARRAY') {
         if (@posstypes) {              push(@{$order},'default');
             unless (grep(/^default$/,@posstypes)) {              if (@{$order} > 1) {
                 push(@posstypes,'default');                  $usertypes->{'default'} = &mt('Other users');
             }                  $additional .= '<table><tr>';
             if (ref($usertypes) eq 'HASH') {                  foreach my $status (@{$order}) {
                 %usertypeshash = %{$usertypes};                      $additional .= '<th>'.$usertypes->{$status}.'</th>';
             }                  }
             my $currassign;                  $additional .= '</tr><tr>';
             if (ref($domdefaults{'inststatusguest'}) eq 'ARRAY') {                  foreach my $status (@{$order}) {
                 $currassign = {                      $additional .= '<td>'.&email_as_username($rowtotal,$processing,$status).'</td>';
                                   selfassign => $domdefaults{'inststatusguest'},  
                               };  
                 @ordered = @{$domdefaults{'inststatusguest'}};  
             } else {  
                 $currassign = { selfassign => [] };  
             }  
             my $onclicktypes = "toggleDataRow(this.form,'selfassign','$customclass','$optionsprefix',);".  
                                "toggleDataRow(this.form,'selfassign','$customclass','$classprefix',1);";  
             $datatable .= &insttypes_row($currassign,$types,$usertypes,$dom,  
                                          $numinrow,$othertitle,'selfassign',  
                                          $rowtotal,$onclicktypes,$customclass,  
                                          $rowstyle);  
             $$rowtotal ++;  
             $usertypeshash{'default'} = $othertitle;  
             foreach my $status (@posstypes) {  
                 my $css_class;  
                 if ($$rowtotal%2) {  
                     $css_class = 'LC_odd_row ';  
                 }  
                 $css_class .= $customclass;  
                 my $rowid = $optionsprefix.$status;  
                 my $hidden = 1;  
                 my $currstyle = 'display:none';  
                 if (grep(/^\Q$status\E$/,@ordered)) {  
                     $currstyle = $rowstyle;  
                     $hidden = 0;  
                 }  
                 $datatable .= &noninst_users($processing,$emailverified,$emailoptions,$emaildomain,  
                                              $emailrules,$emailruleorder,$settings,$status,$rowid,  
                                              $usertypeshash{$status},$css_class,$currstyle,$intdom);  
                 unless ($hidden) {  
                     $$rowtotal ++;  
                 }                  }
                   $additional .= '</tr></table>';
               } else {
                   $usertypes->{'default'} = &mt('All users');
                   $additional .= &email_as_username($rowtotal,$processing);
             }              }
         } else {  
             my $css_class;  
             if ($$rowtotal%2) {  
                 $css_class = 'LC_odd_row ';  
             }  
             $css_class .= $customclass;  
             $usertypeshash{'default'} = $othertitle;  
             $datatable .= &noninst_users($processing,$emailverified,$emailoptions,$emaildomain,  
                                          $emailrules,$emailruleorder,$settings,'default','',  
                                          $othertitle,$css_class,$rowstyle,$intdom);  
             $$rowtotal ++;  
         }          }
           $additional .= '</div>'."\n";
   
           ($datatable,$itemcount) = &radiobutton_prefs(\%radiohash,\@toggles,\%defaultchecked,
                                                        \%choices,$$rowtotal,$onclick,$additional);
           $$rowtotal ++;
           $datatable .= &print_requestmail($dom,'selfcreation',$createsettings,$rowtotal);
           $$rowtotal ++;
         my ($infofields,$infotitles) = &Apache::loncommon::emailusername_info();          my ($infofields,$infotitles) = &Apache::loncommon::emailusername_info();
         $numinrow = 1;          $numinrow = 1;
         if (@posstypes) {          if (ref($order) eq 'ARRAY') {
             foreach my $status (@posstypes) {              foreach my $status (@{$order}) {
                 my $rowid = $classprefix.$status;  
                 my $datarowstyle = 'display:none';  
                 if (grep(/^\Q$status\E$/,@ordered)) {  
                     $datarowstyle = $rowstyle;  
                 }  
                 $datatable .= &modifiable_userdata_row('cancreate','emailusername_'.$status,$settings,                  $datatable .= &modifiable_userdata_row('cancreate','emailusername_'.$status,$settings,
                                                        $numinrow,$$rowtotal,\%usertypeshash,$infofields,                                                         $numinrow,$$rowtotal,$usertypes,$infofields,$infotitles);
                                                        $infotitles,$rowid,$customclass,$datarowstyle);                  $$rowtotal ++;
                 unless ($datarowstyle eq 'display:none') {  
                     $$rowtotal ++;  
                 }  
             }              }
         } else {  
             $datatable .= &modifiable_userdata_row('cancreate','emailusername_default',$settings,  
                                                    $numinrow,$$rowtotal,\%usertypeshash,$infofields,  
                                                    $infotitles,'',$customclass,$rowstyle);  
         }          }
     }          my ($emailrules,$emailruleorder) =
     return $datatable;              &Apache::lonnet::inst_userrules($dom,'email');
 }          if (ref($emailrules) eq 'HASH') {
               if (keys(%{$emailrules}) > 0) {
 sub selfcreate_javascript {                  $datatable .= &user_formats_row('email',$settings,$emailrules,
     return <<"ENDSCRIPT";                                                  $emailruleorder,$numinrow,$$rowtotal);
                   $$rowtotal ++;
 <script type="text/javascript">  
 // <![CDATA[  
   
 function toggleRows(form,radio,checkbox,target,prefix,altprefix) {  
     var x = document.getElementsByClassName(target);  
     var insttypes = 0;  
     var insttypeRegExp = new RegExp(prefix);  
     if ((x.length != undefined) && (x.length > 0)) {  
         if (form.elements[radio].length != undefined) {  
             for (var i=0; i<form.elements[radio].length; i++) {  
                 if (form.elements[radio][i].checked) {  
                     if (form.elements[radio][i].value == 1) {  
                         for (var j=0; j<x.length; j++) {  
                             if (x[j].id == 'undefined') {  
                                 x[j].style.display = 'table-row';  
                             } else if (insttypeRegExp.test(x[j].id)) {  
                                 insttypes ++;  
                             } else {  
                                 x[j].style.display = 'table-row';  
                             }  
                         }  
                     } else {  
                         for (var j=0; j<x.length; j++) {  
                             x[j].style.display = 'none';  
                         }  
                     }  
                     break;  
                 }  
             }  
             if (insttypes > 0) {  
                 toggleDataRow(form,checkbox,target,altprefix);  
                 toggleDataRow(form,checkbox,target,prefix,1);  
             }              }
         }          }
           $datatable .= &captcha_choice('cancreate',$createsettings,$$rowtotal);
     }      }
     return;      return $datatable;
 }  }
   
 function toggleDataRow(form,checkbox,target,prefix,docount) {  sub email_as_username {
     if (form.elements[checkbox].length != undefined) {      my ($rowtotal,$processing,$type) = @_;
         var count = 0;      my %choices =
         if (docount) {          &Apache::lonlocal::texthash (
             for (var i=0; i<form.elements[checkbox].length; i++) {                                        automatic => 'Automatic approval',
                 if (form.elements[checkbox][i].checked) {                                        approval  => 'Queued for approval',
                     count ++;                                      );
                 }      my $output;
             }      foreach my $option ('automatic','approval') {
         }          my $checked;
         for (var i=0; i<form.elements[checkbox].length; i++) {          if (ref($processing) eq 'HASH') {
             var type = form.elements[checkbox][i].value;              if ($type eq '') {   
             if (document.getElementById(prefix+type)) {                  if (!exists($processing->{'default'})) {
                 if (form.elements[checkbox][i].checked) {                      if ($option eq 'automatic') {
                     document.getElementById(prefix+type).style.display = 'table-row';                          $checked = ' checked="checked"';
                     if (count % 2 == 1) {  
                         document.getElementById(prefix+type).className = target+' LC_odd_row';  
                     } else {  
                         document.getElementById(prefix+type).className = target;  
                     }                      }
                     count ++;  
                 } else {                  } else {
                     document.getElementById(prefix+type).style.display = 'none';                      if ($processing->{'default'} eq $option) {
                 }                          $checked = ' checked="checked"';
             }  
         }  
     }  
     return;  
 }  
   
 function toggleEmailOptions(form,radio,prefix,altprefix,status) {  
     var caller = radio+'_'+status;  
     if (form.elements[caller].length != undefined) {  
         for (var i=0; i<form.elements[caller].length; i++) {  
             if (form.elements[caller][i].checked) {  
                 if (document.getElementById(altprefix+'_inst_'+status)) {  
                     var curr = form.elements[caller][i].value;  
                     if (prefix) {  
                         document.getElementById(prefix+'_'+status).style.display = 'none';  
                     }  
                     document.getElementById(altprefix+'_inst_'+status).style.display = 'none';  
                     document.getElementById(altprefix+'_noninst_'+status).style.display = 'none';  
                     if (curr == 'custom') {  
                         if (prefix) {  
                             document.getElementById(prefix+'_'+status).style.display = 'inline';  
                         }  
                     } else if (curr == 'inst') {  
                         document.getElementById(altprefix+'_inst_'+status).style.display = 'inline';  
                     } else if (curr == 'noninst') {  
                         document.getElementById(altprefix+'_noninst_'+status).style.display = 'inline';  
                     }  
                     break;  
                 }  
             }  
         }  
     }  
 }  
   
 // ]]>  
 </script>  
   
 ENDSCRIPT  
 }  
   
 sub noninst_users {  
     my ($processing,$emailverified,$emailoptions,$emaildomain,$emailrules,  
         $emailruleorder,$settings,$type,$rowid,$typetitle,$css_class,$rowstyle,$intdom) = @_;  
     my $class = 'LC_left_item';  
     if ($css_class) {  
         $css_class = ' class="'.$css_class.'"';  
     }  
     if ($rowid) {  
         $rowid = ' id="'.$rowid.'"';  
     }  
     if ($rowstyle) {  
         $rowstyle = ' style="'.$rowstyle.'"';  
     }  
     my ($output,$description);  
     if ($type eq 'default') {  
         $description = &mt('Requests for: [_1]',$typetitle);  
     } else {  
         $description = &mt('Requests for: [_1] (status self-reported)',$typetitle);  
     }  
     $output = '<tr'.$css_class.$rowid.$rowstyle.'>'.  
               "<td>$description</td>\n".  
               '<td class="'.$class.'" colspan="2">'.  
               '<table><tr>';  
     my %headers = &Apache::lonlocal::texthash(  
               approve  => 'Processing',  
               email    => 'E-mail',  
               username => 'Username',  
     );  
     foreach my $item ('approve','email','username') {  
         $output .= '<th>'.$headers{$item}.'</th>';  
     }  
     $output .= '</tr><tr>';  
     foreach my $item ('approve','email','username') {  
         $output .= '<td valign="top">';  
         my (%choices,@options,$hashref,$defoption,$name,$onclick,$hascustom);  
         if ($item eq 'approve') {  
             %choices = &Apache::lonlocal::texthash (  
                                                      automatic => 'Automatically approved',  
                                                      approval  => 'Queued for approval',  
                                                    );  
             @options = ('automatic','approval');  
             $hashref = $processing;  
             $defoption = 'automatic';  
             $name = 'cancreate_emailprocess_'.$type;  
         } elsif ($item eq 'email') {  
             %choices = &Apache::lonlocal::texthash (  
                                                      any     => 'Any e-mail',  
                                                      inst    => 'Institutional only',  
                                                      noninst => 'Non-institutional only',  
                                                      custom  => 'Custom restrictions',  
                                                    );  
             @options = ('any','inst','noninst');  
             my $showcustom;  
             if (ref($emailrules) eq 'HASH') {  
                 if (keys(%{$emailrules}) > 0) {  
                     push(@options,'custom');  
                     $showcustom = 'cancreate_emailrule';  
                     if (ref($settings) eq 'HASH') {  
                         if (ref($settings->{'email_rule'}) eq 'ARRAY') {  
                             foreach my $rule (@{$settings->{'email_rule'}}) {  
                                 if (exists($emailrules->{$rule})) {  
                                     $hascustom ++;  
                                 }  
                             }  
                         } elsif (ref($settings->{'email_rule'}) eq 'HASH') {  
                             if (ref($settings->{'email_rule'}{$type}) eq 'ARRAY') {  
                                 foreach my $rule (@{$settings->{'email_rule'}{$type}}) {  
                                     if (exists($emailrules->{$rule})) {  
                                         $hascustom ++;  
                                     }  
                                 }  
                             }  
                         }  
                     }                      }
                 }                  }
             }              } else {
             $onclick = ' onclick="toggleEmailOptions(this.form,'."'cancreate_emailoptions','$showcustom',".                  if (!exists($processing->{$type})) {
                                                      "'cancreate_emaildomain','$type'".');"';                      if ($option eq 'automatic') {
             $hashref = $emailoptions;                          $checked = ' checked="checked"';
             $defoption = 'any';  
             $name = 'cancreate_emailoptions_'.$type;  
         } elsif ($item eq 'username') {  
             %choices = &Apache::lonlocal::texthash (  
                                                      all    => 'Same as e-mail',  
                                                      first  => 'Omit @domain',  
                                                      free   => 'Free to choose',  
                                                    );  
             @options = ('all','first','free');  
             $hashref = $emailverified;  
             $defoption = 'all';  
             $name = 'cancreate_usernameoptions_'.$type;  
         }  
         foreach my $option (@options) {  
             my $checked;  
             if (ref($hashref) eq 'HASH') {  
                 if ($type eq '') {  
                     if (!exists($hashref->{'default'})) {  
                         if ($option eq $defoption) {  
                             $checked = ' checked="checked"';  
                         }  
                     } else {  
                         if ($hashref->{'default'} eq $option) {  
                             $checked = ' checked="checked"';  
                         }  
                     }                      }
                 } else {                  } else {
                     if (!exists($hashref->{$type})) {                      if ($processing->{$type} eq $option) {
                         if ($option eq $defoption) {                          $checked = ' checked="checked"';
                             $checked = ' checked="checked"';  
                         }  
                     } else {  
                         if ($hashref->{$type} eq $option) {  
                             $checked = ' checked="checked"';  
                         }  
                     }  
                 }  
             } elsif (($item eq 'email') && ($hascustom)) {  
                 if ($option eq 'custom') {  
                     $checked = ' checked="checked"';  
                 }  
             } elsif ($option eq $defoption) {  
                 $checked = ' checked="checked"';  
             }  
             $output .= '<span class="LC_nobreak"><label>'.  
                        '<input type="radio" name="'.$name.'"'.  
                        $checked.' value="'.$option.'"'.$onclick.' />'.  
                        $choices{$option}.'</label></span><br />';  
             if ($item eq 'email') {  
                 if ($option eq 'custom') {  
                     my $id = 'cancreate_emailrule_'.$type;  
                     my $display = 'none';  
                     if ($checked) {  
                         $display = 'inline';  
                     }  
                     my $numinrow = 2;  
                     $output .= '<fieldset id="'.$id.'" style="display:'.$display.';">'.  
                                '<legend>'.&mt('Disallow').'</legend><table>'.  
                                &user_formats_row('email',$settings,$emailrules,  
                                                  $emailruleorder,$numinrow,'',$type);  
                               '</table></fieldset>';  
                 } elsif (($option eq 'inst') || ($option eq 'noninst')) {  
                     my %text = &Apache::lonlocal::texthash (  
                                                              inst    => 'must end:',  
                                                              noninst => 'cannot end:',  
                                                            );  
                     my $value;  
                     if (ref($emaildomain) eq 'HASH') {  
                         if (ref($emaildomain->{$type}) eq 'HASH') {  
                             $value = $emaildomain->{$type}->{$option};  
                         }  
                     }  
                     if ($value eq '') {  
                         $value = '@'.$intdom;  
                     }  
                     my $condition = 'cancreate_emaildomain_'.$option.'_'.$type;  
                     my $display = 'none';  
                     if ($checked) {  
                         $display = 'inline';  
                     }                      }
                     $output .= '<div id="'.$condition.'" style="display:'.$display.';">'.  
                                '<span class="LC_domprefs_email">'.$text{$option}.'</span> '.  
                                '<input type="text" name="'.$condition.'" value="'.$value.'" size="10" />'.  
                                '</div>';  
                 }                  }
             }              }
           } elsif ($option eq 'automatic') {
               $checked = ' checked="checked"'; 
           }
           my $name = 'cancreate_emailprocess';
           if (($type ne '') && ($type ne 'default')) {
               $name .= '_'.$type;
           }
           $output .= '<span class="LC_nobreak"><label>'.
                      '<input type="radio" name="'.$name.'"'.
                      $checked.' value="'.$option.'" />'.
                      $choices{$option}.'</label></span>';
           if ($type eq '') {
               $output .= '&nbsp;';
           } else {
               $output .= '<br />';
         }          }
         $output .= '</td>'."\n";  
     }      }
     $output .= "</tr></table></td></tr>\n";      $$rowtotal ++;
     return $output;      return $output;
 }  }
   
 sub captcha_choice {  sub captcha_choice {
     my ($context,$settings,$itemcount,$customcss,$rowstyle) = @_;      my ($context,$settings,$itemcount) = @_;
     my ($keyentry,$currpub,$currpriv,%checked,$rowname,$pubtext,$privtext,      my ($keyentry,$currpub,$currpriv,%checked,$rowname,$pubtext,$privtext,
         $vertext,$currver);           $vertext,$currver);
     my %lt = &captcha_phrases();      my %lt = &captcha_phrases();
     $keyentry = 'hidden';      $keyentry = 'hidden';
     if ($context eq 'cancreate') {      if ($context eq 'cancreate') {
Line 5548  sub captcha_choice { Line 5412  sub captcha_choice {
     } else {      } else {
         $checked{'original'} = ' checked="checked"';          $checked{'original'} = ' checked="checked"';
     }      }
     my $css_class;      my $css_class = $itemcount%2?' class="LC_odd_row"':'';
     if ($itemcount%2) {  
         $css_class = 'LC_odd_row';  
     }  
     if ($customcss) {  
         $css_class .= " $customcss";  
     }  
     $css_class =~ s/^\s+//;  
     if ($css_class) {  
         $css_class = ' class="'.$css_class.'"';  
     }  
     if ($rowstyle) {  
         $css_class .= ' style="'.$rowstyle.'"';  
     }  
     my $output = '<tr'.$css_class.'>'.      my $output = '<tr'.$css_class.'>'.
                  '<td class="LC_left_item">'.$rowname.'</td><td class="LC_left_item" colspan="2">'."\n".                   '<td class="LC_left_item">'.$rowname.'</td><td class="LC_left_item" colspan="2">'."\n".
                  '<table><tr><td>'."\n";                   '<table><tr><td>'."\n";
Line 5580  sub captcha_choice { Line 5431  sub captcha_choice {
 # specified for use with the key should be broad enough to accommodate all servers in the LON-CAPA domain.  # specified for use with the key should be broad enough to accommodate all servers in the LON-CAPA domain.
 #  #
     $output .= '</td></tr>'."\n".      $output .= '</td></tr>'."\n".
                '<tr><td class="LC_zero_height">'."\n".                 '<tr><td>'."\n".
                '<span class="LC_nobreak"><span id="'.$context.'_recaptchapubtxt">'.$pubtext.'</span>&nbsp;'."\n".                 '<span class="LC_nobreak"><span id="'.$context.'_recaptchapubtxt">'.$pubtext.'</span>&nbsp;'."\n".
                '<input type="'.$keyentry.'" id="'.$context.'_recaptchapub" name="'.$context.'_recaptchapub" value="'.                 '<input type="'.$keyentry.'" id="'.$context.'_recaptchapub" name="'.$context.'_recaptchapub" value="'.
                $currpub.'" size="40" /></span><br />'."\n".                 $currpub.'" size="40" /></span><br />'."\n".
Line 5596  sub captcha_choice { Line 5447  sub captcha_choice {
 }  }
   
 sub user_formats_row {  sub user_formats_row {
     my ($type,$settings,$rules,$ruleorder,$numinrow,$rowcount,$status) = @_;      my ($type,$settings,$rules,$ruleorder,$numinrow,$rowcount) = @_;
     my $output;      my $output;
     my %text = (      my %text = (
                    'username' => 'new usernames',                     'username' => 'new usernames',
                    'id'       => 'IDs',                     'id'       => 'IDs',
                      'email'    => 'self-created accounts (e-mail)',
                );                 );
     unless ($type eq 'email') {      my $css_class = $rowcount%2?' class="LC_odd_row"':'';
         my $css_class = $rowcount%2?' class="LC_odd_row"':'';      $output = '<tr '.$css_class.'>'.
         $output = '<tr '.$css_class.'>'.                '<td><span class="LC_nobreak">';
                   '<td><span class="LC_nobreak">'.      if ($type eq 'email') {
                   &mt("Format rules to check for $text{$type}: ").          $output .= &mt("Formats disallowed for $text{$type}: ");
                   '</td><td class="LC_left_item" colspan="2"><table>';      } else {
           $output .= &mt("Format rules to check for $text{$type}: ");
     }      }
       $output .= '</span></td>'.
                  '<td class="LC_left_item" colspan="2"><table>';
     my $rem;      my $rem;
     if (ref($ruleorder) eq 'ARRAY') {      if (ref($ruleorder) eq 'ARRAY') {
         for (my $i=0; $i<@{$ruleorder}; $i++) {          for (my $i=0; $i<@{$ruleorder}; $i++) {
Line 5626  sub user_formats_row { Line 5481  sub user_formats_row {
                         if (grep(/^\Q$ruleorder->[$i]\E$/,@{$settings->{$type.'_rule'}})) {                          if (grep(/^\Q$ruleorder->[$i]\E$/,@{$settings->{$type.'_rule'}})) {
                             $check = ' checked="checked" ';                              $check = ' checked="checked" ';
                         }                          }
                     } elsif ((ref($settings->{$type.'_rule'}) eq 'HASH') && ($status ne '')) {  
                         if (ref($settings->{$type.'_rule'}->{$status}) eq 'ARRAY') {  
                             if (grep(/^\Q$ruleorder->[$i]\E$/,@{$settings->{$type.'_rule'}->{$status}})) {  
                                 $check = ' checked="checked" ';  
                             }  
                         }  
                     }                      }
                 }                  }
                 my $name = $type.'_rule';  
                 if ($type eq 'email') {  
                     $name .= '_'.$status;  
                 }  
                 $output .= '<td class="LC_left_item">'.                  $output .= '<td class="LC_left_item">'.
                            '<span class="LC_nobreak"><label>'.                             '<span class="LC_nobreak"><label>'.
                            '<input type="checkbox" name="'.$name.'" '.                             '<input type="checkbox" name="'.$type.'_rule" '.
                            'value="'.$ruleorder->[$i].'"'.$check.'/>'.                             'value="'.$ruleorder->[$i].'"'.$check.'/>'.
                            $rules->{$ruleorder->[$i]}{'name'}.'</label></span></td>';                             $rules->{$ruleorder->[$i]}{'name'}.'</label></span></td>';
             }              }
         }          }
         $rem = @{$ruleorder}%($numinrow);          $rem = @{$ruleorder}%($numinrow);
     }      }
     my $colsleft;      my $colsleft = $numinrow - $rem;
     if ($rem) {  
         $colsleft = $numinrow - $rem;  
     }  
     if ($colsleft > 1 ) {      if ($colsleft > 1 ) {
         $output .= '<td colspan="'.$colsleft.'" class="LC_left_item">'.          $output .= '<td colspan="'.$colsleft.'" class="LC_left_item">'.
                    '&nbsp;</td>';                     '&nbsp;</td>';
     } elsif ($colsleft == 1) {      } elsif ($colsleft == 1) {
         $output .= '<td class="LC_left_item">&nbsp;</td>';          $output .= '<td class="LC_left_item">&nbsp;</td>';
     }      }
     $output .= '</tr></table>';      $output .= '</tr></table></td></tr>';
     unless ($type eq 'email') {  
         $output .= '</td></tr>';  
     }  
     return $output;      return $output;
 }  }
   
Line 5737  sub print_usermodification { Line 5576  sub print_usermodification {
 sub print_defaults {  sub print_defaults {
     my ($position,$dom,$settings,$rowtotal) = @_;      my ($position,$dom,$settings,$rowtotal) = @_;
     my $rownum = 0;      my $rownum = 0;
     my ($datatable,$css_class,$titles);      my ($datatable,$css_class);
     unless ($position eq 'bottom') {  
         $titles = &defaults_titles($dom);  
     }  
     if ($position eq 'top') {      if ($position eq 'top') {
         my @items = ('auth_def','auth_arg_def','lang_def','timezone_def',          my @items = ('auth_def','auth_arg_def','lang_def','timezone_def',
                      'datelocale_def','portal_def');                       'datelocale_def','portal_def');
Line 5753  sub print_defaults { Line 5589  sub print_defaults {
                 $defaults{$item} = $domdefaults{$item};                  $defaults{$item} = $domdefaults{$item};
             }              }
         }          }
           my $titles = &defaults_titles($dom);
         foreach my $item (@items) {          foreach my $item (@items) {
             if ($rownum%2) {              if ($rownum%2) {
                 $css_class = '';                  $css_class = '';
Line 5800  sub print_defaults { Line 5637  sub print_defaults {
             $datatable .= '</td></tr>';              $datatable .= '</td></tr>';
             $rownum ++;              $rownum ++;
         }          }
     } elsif ($position eq 'middle') {  
         my @items = ('intauth_cost','intauth_check','intauth_switch');  
         my %defaults;  
         if (ref($settings) eq 'HASH') {  
             %defaults = %{$settings};  
             if ($defaults{'intauth_cost'} !~ /^\d+$/) {  
                 $defaults{'intauth_cost'} = 10;  
             }  
             if ($defaults{'intauth_check'} !~ /^(0|1|2)$/) {  
                 $defaults{'intauth_check'} = 0;  
             }  
             if ($defaults{'intauth_switch'} !~ /^(0|1|2)$/) {  
                 $defaults{'intauth_switch'} = 0;  
             }  
         } else {  
             %defaults = (  
                           'intauth_cost'   => 10,  
                           'intauth_check'  => 0,  
                           'intauth_switch' => 0,  
                         );  
         }  
         foreach my $item (@items) {  
             if ($rownum%2) {  
                 $css_class = '';  
             } else {  
                 $css_class = ' class="LC_odd_row" ';  
             }  
             $datatable .= '<tr'.$css_class.'>'.  
                           '<td><span class="LC_nobreak">'.$titles->{$item}.  
                           '</span></td><td class="LC_left_item" colspan="3">';  
             if ($item eq 'intauth_switch') {  
                 my @options = (0,1,2);  
                 my %optiondesc = &Apache::lonlocal::texthash (  
                                    0 => 'No',  
                                    1 => 'Yes',  
                                    2 => 'Yes, and copy existing passwd file to passwd.bak file',  
                                  );  
                 $datatable .= '<table width="100%">';  
                 foreach my $option (@options) {  
                     my $checked = ' ';  
                     if ($defaults{$item} eq $option) {  
                         $checked = ' checked="checked"';  
                     }  
                     $datatable .= '<tr><td class="LC_left_item"><span class="LC_nobreak">'.  
                                   '<label><input type="radio" name="'.$item.  
                                   '" value="'.$option.'"'.$checked.' />'.  
                                   $optiondesc{$option}.'</label></span></td></tr>';  
                 }  
                 $datatable .= '</table>';  
             } elsif ($item eq 'intauth_check') {  
                 my @options = (0,1,2);  
                 my %optiondesc = &Apache::lonlocal::texthash (  
                                    0 => 'No',  
                                    1 => 'Yes, allow login then update passwd file using default cost (if higher)',  
                                    2 => 'Yes, disallow login if stored cost is less than domain default',  
                                  );  
                 $datatable .= '<table wisth="100%">';  
                 foreach my $option (@options) {  
                     my $checked = ' ';  
                     my $onclick;  
                     if ($defaults{$item} eq $option) {  
                         $checked = ' checked="checked"';  
                     }  
                     if ($option == 2) {  
                         $onclick = ' onclick="javascript:warnIntAuth(this);"';  
                     }  
                     $datatable .= '<tr><td class="LC_left_item"><span class="LC_nobreak">'.  
                                   '<label><input type="radio" name="'.$item.  
                                   '" value="'.$option.'"'.$checked.$onclick.' />'.  
                                   $optiondesc{$option}.'</label></span></td></tr>';  
                 }  
                 $datatable .= '</table>';  
             } else {  
                 $datatable .= '<input type="text" name="'.$item.'" value="'.  
                               $defaults{$item}.'" size="3" onblur="javascript:warnIntAuth(this);" />';  
             }  
             $datatable .= '</td></tr>';  
             $rownum ++;  
         }  
     } else {      } else {
         my %defaults;          my (%defaults);
         if (ref($settings) eq 'HASH') {          if (ref($settings) eq 'HASH') {
             if ((ref($settings->{'inststatusorder'}) eq 'ARRAY') && (ref($settings->{'inststatustypes'}) eq 'HASH')) {              if ((ref($settings->{'inststatusorder'}) eq 'ARRAY') && (ref($settings->{'inststatustypes'}) eq 'HASH') &&
                   (ref($settings->{'inststatusguest'}) eq 'ARRAY')) {
                 my $maxnum = @{$settings->{'inststatusorder'}};                  my $maxnum = @{$settings->{'inststatusorder'}};
                 for (my $i=0; $i<$maxnum; $i++) {                  for (my $i=0; $i<$maxnum; $i++) {
                     $css_class = $rownum%2?' class="LC_odd_row"':'';                      $css_class = $rownum%2?' class="LC_odd_row"':'';
                     my $item = $settings->{'inststatusorder'}->[$i];                      my $item = $settings->{'inststatusorder'}->[$i];
                     my $title = $settings->{'inststatustypes'}->{$item};                      my $title = $settings->{'inststatustypes'}->{$item};
                       my $guestok;
                       if (grep(/^\Q$item\E$/,@{$settings->{'inststatusguest'}})) {
                           $guestok = 1;
                       }
                     my $chgstr = ' onchange="javascript:reorderTypes(this.form,'."'$item'".');"';                      my $chgstr = ' onchange="javascript:reorderTypes(this.form,'."'$item'".');"';
                     $datatable .= '<tr'.$css_class.'>'.                      $datatable .= '<tr'.$css_class.'>'.
                                   '<td><span class="LC_nobreak">'.                                    '<td><span class="LC_nobreak">'.
Line 5900  sub print_defaults { Line 5663  sub print_defaults {
                         }                          }
                         $datatable .= '<option value="'.$k.'"'.$selstr.'>'.$vpos.'</option>';                          $datatable .= '<option value="'.$k.'"'.$selstr.'>'.$vpos.'</option>';
                     }                      }
                       my ($checkedon,$checkedoff);
                       $checkedoff = ' checked="checked"';
                       if ($guestok) {
                           $checkedon = $checkedoff;
                           $checkedoff = ''; 
                       }
                     $datatable .= '</select>&nbsp;'.&mt('Internal ID:').'&nbsp;<b>'.$item.'</b>&nbsp;'.                      $datatable .= '</select>&nbsp;'.&mt('Internal ID:').'&nbsp;<b>'.$item.'</b>&nbsp;'.
                                   '<input type="checkbox" name="inststatus_delete" value="'.$item.'" />'.                                    '<input type="checkbox" name="inststatus_delete" value="'.$item.'" />'.
                                   &mt('delete').'</span></td>'.                                    &mt('delete').'</span></td>'.
                                   '<td class="LC_left_item" colspan="2"><span class="LC_nobreak">'.&mt('Name displayed:').                                    '<td class="LC_left_item"><span class="LC_nobreak">'.&mt('Name displayed:').
                                   '<input type="text" size="20" name="inststatus_title_'.$item.'" value="'.$title.'" />'.                                    '<input type="text" size="20" name="inststatus_title_'.$item.'" value="'.$title.'" />'.
                                   '</span></td></tr>';                                    '</span></td>'.
                                     '<td class="LC_right_item"><span class="LC_nobreak">'.
                                     '<label><input type="radio" value="1" name="inststatus_guest_'.$item.'"'.$checkedon.' />'.
                                     &mt('Yes').'</label>'.('&nbsp;'x2).
                                     '<label><input type="radio" value="0" name="inststatus_guest_'.$item.'"'.$checkedoff.' />'.
                                     &mt('No').'</label></span></td></tr>';
                 }                  }
                 $css_class = $rownum%2?' class="LC_odd_row"':'';                  $css_class = $rownum%2?' class="LC_odd_row"':'';
                 my $chgstr = ' onchange="javascript:reorderTypes(this.form,'."'addinststatus_pos'".');"';                  my $chgstr = ' onchange="javascript:reorderTypes(this.form,'."'addinststatus_pos'".');"';
Line 5922  sub print_defaults { Line 5696  sub print_defaults {
                 $datatable .= '</select>&nbsp;'.&mt('Internal ID:').                  $datatable .= '</select>&nbsp;'.&mt('Internal ID:').
                               '<input type="text" size="10" name="addinststatus" value="" />'.                                '<input type="text" size="10" name="addinststatus" value="" />'.
                               '&nbsp;'.&mt('(new)').                                '&nbsp;'.&mt('(new)').
                               '</span></td><td class="LC_left_item" colspan="2"><span class="LC_nobreak">'.                                '</span></td><td class="LC_left_item"><span class="LC_nobreak">'.
                               &mt('Name displayed:').                                &mt('Name displayed:').
                               '<input type="text" size="20" name="addinststatus_title" value="" /></span></td>'.                                '<input type="text" size="20" name="addinststatus_title" value="" /></span></td>'.
                                 '<td class="LC_right_item"><span class="LC_nobreak">'.
                                 '<label><input type="radio" value="1" name="addinststatus_guest" />'.
                                 &mt('Yes').'</label>'.('&nbsp;'x2).
                                 '<label><input type="radio" value="0" name="addinststatus_guest" />'.
                                 &mt('No').'</label></span></td></tr>';
                               '</tr>'."\n";                                '</tr>'."\n";
                 $rownum ++;                  $rownum ++;
             }              }
Line 5954  sub defaults_titles { Line 5733  sub defaults_titles {
                    'timezone_def'  => 'Default timezone',                     'timezone_def'  => 'Default timezone',
                    'datelocale_def' => 'Default locale for dates',                     'datelocale_def' => 'Default locale for dates',
                    'portal_def'     => 'Portal/Default URL',                     'portal_def'     => 'Portal/Default URL',
                    'intauth_cost'   => 'Encryption cost for bcrypt (positive integer)',  
                    'intauth_check'  => 'Check bcrypt cost if authenticated',  
                    'intauth_switch' => 'Existing crypt-based switched to bcrypt on authentication',  
                  );                   );
     if ($dom) {      if ($dom) {
         my $uprimary_id = &Apache::lonnet::domain($dom,'primary');          my $uprimary_id = &Apache::lonnet::domain($dom,'primary');
Line 6199  sub print_coursecategories { Line 5975  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 6217  sub print_coursecategories { Line 5997  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 6257  sub print_coursecategories { Line 6048  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 6283  sub print_coursecategories { Line 6088  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 6309  sub print_coursecategories { Line 6117  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 6332  sub print_coursecategories { Line 6140  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 6364  sub print_coursecategories { Line 6172  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 6453  sub print_serverstatuses { Line 6261  sub print_serverstatuses {
   
 sub serverstatus_pages {  sub serverstatus_pages {
     return ('userstatus','lonstatus','loncron','server-status','codeversions',      return ('userstatus','lonstatus','loncron','server-status','codeversions',
             'checksums','clusterstatus','metadata_keywords','metadata_harvest',              'checksums','clusterstatus','certstatus','metadata_keywords',
             'takeoffline','takeonline','showenv','toggledebug','ping','domconf',              'metadata_harvest','takeoffline','takeonline','showenv','toggledebug',
             'uniquecodes','diskusage','coursecatalog');              'ping','domconf','uniquecodes','diskusage','coursecatalog');
 }  }
   
 sub defaults_javascript {  sub defaults_javascript {
     my ($settings) = @_;      my ($settings) = @_;
     my $intauthcheck = &mt('Warning: disallowing login for an authenticated user if the stored cost is less than the default will require a password reset by/for the user.');      return unless (ref($settings) eq 'HASH'); 
     my $intauthcost = &mt('Warning: bcrypt encryption cost for internal authentication must be an integer.');  
     &js_escape(\$intauthcheck);  
     &js_escape(\$intauthcost);  
     my $intauthjs = <<"ENDSCRIPT";  
   
 function warnIntAuth(field) {  
     if (field.name == 'intauth_check') {  
         if (field.value == '2') {  
             alert('$intauthcheck');  
         }  
     }  
     if (field.name == 'intauth_cost') {  
         field.value.replace(/\s/g,'');  
         if (field.value != '') {  
             var regexdigit=/^\\d+\$/;  
             if (!regexdigit.test(field.value)) {  
                 alert('$intauthcost');  
             }  
         }  
     }  
     return;  
 }  
   
 ENDSCRIPT  
   
     if (ref($settings) ne 'HASH') {  
         return &Apache::lonhtmlcommon::scripttag($intauthjs);  
     }  
     if ((ref($settings->{'inststatusorder'}) eq 'ARRAY') && (ref($settings->{'inststatustypes'}) eq 'HASH')) {      if ((ref($settings->{'inststatusorder'}) eq 'ARRAY') && (ref($settings->{'inststatustypes'}) eq 'HASH')) {
         my $maxnum = scalar(@{$settings->{'inststatusorder'}});          my $maxnum = scalar(@{$settings->{'inststatusorder'}});
         if ($maxnum eq '') {          if ($maxnum eq '') {
Line 6542  $jstext Line 6322  $jstext
     return;      return;
 }  }
   
 $intauthjs  
   
 // ]]>  // ]]>
 </script>  </script>
   
 ENDSCRIPT  ENDSCRIPT
     } else {  
         return &Apache::lonhtmlcommon::scripttag($intauthjs);  
     }      }
 }  }
   
Line 6577  sub coursecategories_javascript { Line 6353  sub coursecategories_javascript {
     }      }
     my $instcode_reserved = &mt('The name: [_1] is a reserved category.','"instcode"');      my $instcode_reserved = &mt('The name: [_1] is a reserved category.','"instcode"');
     my $communities_reserved = &mt('The name: [_1] is a reserved category.','"communities"');      my $communities_reserved = &mt('The name: [_1] is a reserved category.','"communities"');
       my $placement_reserved = &mt('The name: [_1] is a reserved category.','"placement"');
     my $choose_again = "\n".&mt('Please use a different name for the new top level category.');       my $choose_again = "\n".&mt('Please use a different name for the new top level category.'); 
     &js_escape(\$instcode_reserved);      &js_escape(\$instcode_reserved);
     &js_escape(\$communities_reserved);      &js_escape(\$communities_reserved);
       &js_escape(\$placement_reserved);
     &js_escape(\$choose_again);      &js_escape(\$choose_again);
     $output = <<"ENDSCRIPT";      $output = <<"ENDSCRIPT";
 <script type="text/javascript">  <script type="text/javascript">
Line 6649  function categoryCheck(form) { Line 6427  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 6665  sub initialize_categories { Line 6447  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 6783  sub build_category_rows { Line 6566  sub build_category_rows {
 }  }
   
 sub modifiable_userdata_row {  sub modifiable_userdata_row {
     my ($context,$item,$settings,$numinrow,$rowcount,$usertypes,$fieldsref,$titlesref,      my ($context,$item,$settings,$numinrow,$rowcount,$usertypes,$fieldsref,$titlesref) = @_;
         $rowid,$customcss,$rowstyle) = @_;  
     my ($role,$rolename,$statustype);      my ($role,$rolename,$statustype);
     $role = $item;      $role = $item;
     if ($context eq 'cancreate') {      if ($context eq 'cancreate') {
         if ($item =~ /^(emailusername)_(.+)$/) {          if ($item =~ /^emailusername_(.+)$/) {
             $role = $1;              $statustype = $1;
             $statustype = $2;              $role = 'emailusername';
             if (ref($usertypes) eq 'HASH') {              if (ref($usertypes) eq 'HASH') {
                 if ($usertypes->{$statustype}) {                  if ($usertypes->{$statustype}) {
                     $rolename = &mt('Data provided by [_1]',$usertypes->{$statustype});                      $rolename = &mt('Data provided by [_1]',$usertypes->{$statustype});
Line 6825  sub modifiable_userdata_row { Line 6607  sub modifiable_userdata_row {
         %fieldtitles = &Apache::loncommon::personal_data_fieldtitles();          %fieldtitles = &Apache::loncommon::personal_data_fieldtitles();
     }      }
     my $output;      my $output;
     my $css_class;      my $css_class = $rowcount%2?' class="LC_odd_row"':'';
     if ($rowcount%2) {      $output = '<tr '.$css_class.'>'.
         $css_class = 'LC_odd_row';  
     }  
     if ($customcss) {  
         $css_class .= " $customcss";  
     }  
     $css_class =~ s/^\s+//;  
     if ($css_class) {  
         $css_class = ' class="'.$css_class.'"';  
     }  
     if ($rowstyle) {  
         $css_class .= ' style="'.$rowstyle.'"';  
     }  
     if ($rowid) {  
         $rowid = ' id="'.$rowid.'"';  
     }  
   
     $output = '<tr '.$css_class.$rowid.'>'.  
               '<td><span class="LC_nobreak">'.$rolename.'</span></td>'.                '<td><span class="LC_nobreak">'.$rolename.'</span></td>'.
               '<td class="LC_left_item" colspan="2"><table>';                '<td class="LC_left_item" colspan="2"><table>';
     my $rem;      my $rem;
Line 6877  sub modifiable_userdata_row { Line 6642  sub modifiable_userdata_row {
             }              }
         }          }
     }      }
        
     my $total = scalar(@fields);      for (my $i=0; $i<@fields; $i++) {
     for (my $i=0; $i<$total; $i++) {          my $rem = $i%($numinrow);
         $rem = $i%($numinrow);  
         if ($rem == 0) {          if ($rem == 0) {
             if ($i > 0) {              if ($i > 0) {
                 $output .= '</tr>';                  $output .= '</tr>';
Line 6922  sub modifiable_userdata_row { Line 6686  sub modifiable_userdata_row {
                        '</label>';                         '</label>';
         }          }
         $output .= '</span></td>';          $output .= '</span></td>';
           $rem = @fields%($numinrow);
     }      }
     $rem = $total%$numinrow;      my $colsleft = $numinrow - $rem;
     my $colsleft;      if ($colsleft > 1 ) {
     if ($rem) {  
         $colsleft = $numinrow - $rem;  
     }  
     if ($colsleft > 1) {  
         $output .= '<td colspan="'.$colsleft.'" class="LC_left_item">'.          $output .= '<td colspan="'.$colsleft.'" class="LC_left_item">'.
                    '&nbsp;</td>';                     '&nbsp;</td>';
     } elsif ($colsleft == 1) {      } elsif ($colsleft == 1) {
Line 6939  sub modifiable_userdata_row { Line 6700  sub modifiable_userdata_row {
 }  }
   
 sub insttypes_row {  sub insttypes_row {
     my ($settings,$types,$usertypes,$dom,$numinrow,$othertitle,$context,$rowtotal,$onclick,      my ($settings,$types,$usertypes,$dom,$numinrow,$othertitle,$context,$rownum) = @_;
         $customcss,$rowstyle) = @_;  
     my %lt = &Apache::lonlocal::texthash (      my %lt = &Apache::lonlocal::texthash (
                       cansearch => 'Users allowed to search',                        cansearch => 'Users allowed to search',
                       statustocreate => 'Institutional affiliation(s) able to create own account (login/SSO)',                        statustocreate => 'Institutional affiliation(s) able to create own account (login/SSO)',
                       lockablenames => 'User preference to lock name',                        lockablenames => 'User preference to lock name',
                       selfassign    => 'Self-reportable affiliations',  
              );               );
     my $showdom;      my $showdom;
     if ($context eq 'cansearch') {      if ($context eq 'cansearch') {
Line 6955  sub insttypes_row { Line 6714  sub insttypes_row {
     if ($context eq 'statustocreate') {      if ($context eq 'statustocreate') {
         $class = 'LC_right_item';          $class = 'LC_right_item';
     }      }
     my $css_class;      my $css_class = ' class="LC_odd_row"';
     if ($$rowtotal%2) {      if ($rownum ne '') { 
         $css_class = 'LC_odd_row';          $css_class = ($rownum%2? ' class="LC_odd_row"':'');
     }  
     if ($customcss) {  
         $css_class .= ' '.$customcss;  
     }  
     $css_class =~ s/^\s+//;  
     if ($css_class) {  
         $css_class = ' class="'.$css_class.'"';  
     }  
     if ($rowstyle) {  
         $css_class .= ' style="'.$rowstyle.'"';  
     }  
     if ($onclick) {  
         $onclick = 'onclick="'.$onclick.'" ';  
     }      }
     my $output = '<tr'.$css_class.'>'.      my $output = '<tr'.$css_class.'>'.
                  '<td>'.$lt{$context}.$showdom.                   '<td>'.$lt{$context}.$showdom.
Line 6999  sub insttypes_row { Line 6745  sub insttypes_row {
                 $output .= '<td class="LC_left_item">'.                  $output .= '<td class="LC_left_item">'.
                            '<span class="LC_nobreak"><label>'.                             '<span class="LC_nobreak"><label>'.
                            '<input type="checkbox" name="'.$context.'" '.                             '<input type="checkbox" name="'.$context.'" '.
                            'value="'.$types->[$i].'"'.$check.$onclick.' />'.                             'value="'.$types->[$i].'"'.$check.'/>'.
                            $usertypes->{$types->[$i]}.'</label></span></td>';                             $usertypes->{$types->[$i]}.'</label></span></td>';
             }              }
         }          }
Line 7026  sub insttypes_row { Line 6772  sub insttypes_row {
     }      }
     $output .= '<span class="LC_nobreak"><label>'.      $output .= '<span class="LC_nobreak"><label>'.
                '<input type="checkbox" name="'.$context.'" '.                 '<input type="checkbox" name="'.$context.'" '.
                'value="default"'.$defcheck.$onclick.' />'.                 'value="default"'.$defcheck.'/>'.
                $othertitle.'</label></span></td>'.                 $othertitle.'</label></span></td>'.
                '</tr></table></td></tr>';                 '</tr></table></td></tr>';
     return $output;      return $output;
Line 7313  sub modify_login { Line 7059  sub modify_login {
             } elsif ($currheadtagurls{$lonhost}) {              } elsif ($currheadtagurls{$lonhost}) {
                 $loginhash{'login'}{'headtag'}{$lonhost}{'url'} = $currheadtagurls{$lonhost};                  $loginhash{'login'}{'headtag'}{$lonhost}{'url'} = $currheadtagurls{$lonhost};
                 if ($currexempt{$lonhost}) {                  if ($currexempt{$lonhost}) {
                     if ((!exists($possexempt{$lonhost})) || ($possexempt{$lonhost} ne $currexempt{$lonhost})) {                      if ((!exists($possexempt{$lonhost})) || ($possexempt{$lonhost} ne $currexempt{$lonhost})) { 
                         $changes{'headtag'}{$lonhost} = 1;                          $changes{'headtag'}{$lonhost} = 1;
                     }                      }
                 } elsif ($possexempt{$lonhost}) {                  } elsif ($possexempt{$lonhost}) {
Line 7545  sub modify_login { Line 7291  sub modify_login {
     return $resulttext;      return $resulttext;
 }  }
   
   
 sub check_exempt_addresses {  sub check_exempt_addresses {
     my ($iplist) = @_;      my ($iplist) = @_;
     $iplist =~ s/^\s+//;      $iplist =~ s/^\s+//;
Line 8017  sub check_authorstatus { Line 7764  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 8145  $env{'user.name'}.':'.$env{'user.domain' Line 7892  $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 8157  $env{'user.name'}.':'.$env{'user.domain' Line 7905  $env{'user.name'}.':'.$env{'user.domain'
             $output = $versionresult;              $output = $versionresult;
         }          }
     }      }
     return ($output,$logourl);      return ($output,$logourl,$madethumb);
 }  }
   
 sub logo_versioning {  sub logo_versioning {
Line 8311  sub modify_quotas { Line 8059  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 8360  sub modify_quotas { Line 8108  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 8454  sub modify_quotas { Line 8202  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 8599  sub modify_quotas { Line 8347  sub modify_quotas {
             }              }
             if ($env{'form.validationdc'}) {              if ($env{'form.validationdc'}) {
                 my $newval = $env{'form.validationdc'};                  my $newval = $env{'form.validationdc'};
                 my %domcoords = &Apache::lonnet::get_active_domroles($dom,['dc']);                  my %domcoords = &get_active_dcs($dom);
                 if (exists($domcoords{$newval})) {                  if (exists($domcoords{$newval})) {
                     $confhash{'validation'}{'dc'} = $newval;                      $confhash{'validation'}{'dc'} = $newval;
                 }                  }
Line 8623  sub modify_quotas { Line 8371  sub modify_quotas {
                     }                      }
                 } elsif ($confhash{'validation'}{'dc'} ne '') {                  } elsif ($confhash{'validation'}{'dc'} ne '') {
                     $changes{'validation'}{'dc'} = $confhash{'validation'}{'dc'};                      $changes{'validation'}{'dc'} = $confhash{'validation'}{'dc'};
                 }                  }  
             } else {              } else {
                 if (ref($domconfig{'requestcourses'}) eq 'HASH') {                  if (ref($domconfig{'requestcourses'}) eq 'HASH') {
                     if (ref($domconfig{'requestcourses'}{'validation'}) eq 'HASH') {                      if (ref($domconfig{'requestcourses'}{'validation'}) eq 'HASH') {
Line 9026  sub process_textbook_image { Line 8774  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 9111  sub modify_autoenroll { Line 9380  sub modify_autoenroll {
             }              }
             if ($changes{'autofailsafe'}) {              if ($changes{'autofailsafe'}) {
                 if ($failsafe ne '') {                  if ($failsafe ne '') {
                     $resulttext .= '<li>'.&mt('Failsafe for no drops if institutional data missing for a section set to: [_1]',$failsafe).'</li>';                      $resulttext .= '<li>'.&mt("$title{'failsafe'} set to [_1]",$failsafe).'</li>';
                 } else {                  } else {
                     $resulttext .= '<li>'.&mt('Failsafe for no drops if institutional data missing for a section: deleted');                      $resulttext .= '<li>'.&mt("$title{'failsafe'} deleted");
                 }                  }
                 &Apache::lonnet::get_domain_defaults($dom,1);                  &Apache::lonnet::get_domain_defaults($dom,1);
                 if (ref($lastactref) eq 'HASH') {                  if (ref($lastactref) eq 'HASH') {
Line 9335  sub modify_autocreate { Line 9604  sub modify_autocreate {
         $newvals{$item} = 0 if ($newvals{$item} eq '');          $newvals{$item} = 0 if ($newvals{$item} eq '');
     }      }
     $newvals{'xmldc'} = $env{'form.autocreate_xmldc'};      $newvals{'xmldc'} = $env{'form.autocreate_xmldc'};
     my %domcoords = &Apache::lonnet::get_active_domroles($dom,['dc']);      my %domcoords = &get_active_dcs($dom);
     unless (exists($domcoords{$newvals{'xmldc'}})) {      unless (exists($domcoords{$newvals{'xmldc'}})) {
         $newvals{'xmldc'} = '';          $newvals{'xmldc'} = '';
     }       } 
Line 9392  sub modify_autocreate { Line 9661  sub modify_autocreate {
 }  }
   
 sub modify_directorysrch {  sub modify_directorysrch {
     my ($dom,$lastactref,%domconfig) = @_;      my ($dom,%domconfig) = @_;
     my ($resulttext,%changes);      my ($resulttext,%changes);
     my %currdirsrch;      my %currdirsrch;
     if (ref($domconfig{'directorysrch'}) eq 'HASH') {      if (ref($domconfig{'directorysrch'}) eq 'HASH') {
Line 9403  sub modify_directorysrch { Line 9672  sub modify_directorysrch {
     my %title = ( available => 'Institutional directory search available',      my %title = ( available => 'Institutional directory search available',
                   localonly => 'Other domains can search institution',                    localonly => 'Other domains can search institution',
                   lcavailable => 'LON-CAPA directory search available',                    lcavailable => 'LON-CAPA directory search available',
                   lclocalonly => 'Other domains can search LON-CAPA domain',                    lclocalonly => 'Other domains can search LON-CAPA domain', 
                   searchby => 'Search types',                    searchby => 'Search types',
                   searchtypes => 'Search latitude');                    searchtypes => 'Search latitude');
     my @offon = ('off','on');      my @offon = ('off','on');
Line 9497  sub modify_directorysrch { Line 9766  sub modify_directorysrch {
             }              }
         }          }
         if (exists($currdirsrch{'lcavailable'})) {          if (exists($currdirsrch{'lcavailable'})) {
             if ($currdirsrch{'lcavailable'} ne $env{'form.dirsrch_domavailable'}) {               if ($currdirsrch{'lcavailable'} ne $env{'form.dirsrch_domavailable'}) {
                 $changes{'lcavailable'} = 1;                   $changes{'lcavailable'} = 1;
             }               }
         } else {          } else {
             if ($env{'form.dirsrch_lcavailable'} eq '1') {              if ($env{'form.dirsrch_lcavailable'} eq '1') {
                 $changes{'lcavailable'} = 1;                  $changes{'lcavailable'} = 1;
             }              }
         }          }
         if (exists($currdirsrch{'localonly'})) {          if (exists($currdirsrch{'localonly'})) {
             if ($currdirsrch{'localonly'} ne $env{'form.dirsrch_instlocalonly'}) {               if ($currdirsrch{'localonly'} ne $env{'form.dirsrch_instlocalonly'}) {
                 $changes{'localonly'} = 1;                   $changes{'localonly'} = 1;
             }               }
         } else {          } else {
             if ($env{'form.dirsrch_instlocalonly'} eq '1') {              if ($env{'form.dirsrch_instlocalonly'} eq '1') {
                 $changes{'localonly'} = 1;                  $changes{'localonly'} = 1;
             }              }
         }          }
         if (exists($currdirsrch{'lclocalonly'})) {          if (exists($currdirsrch{'lclocalonly'})) {
             if ($currdirsrch{'lclocalonly'} ne $env{'form.dirsrch_domlocalonly'}) {               if ($currdirsrch{'lclocalonly'} ne $env{'form.dirsrch_domlocalonly'}) {
                 $changes{'lclocalonly'} = 1;                   $changes{'lclocalonly'} = 1;
             }               }
         } else {          } else {
             if ($env{'form.dirsrch_domlocalonly'} eq '1') {              if ($env{'form.dirsrch_domlocalonly'} eq '1') {
                 $changes{'lclocalonly'} = 1;                  $changes{'lclocalonly'} = 1;
Line 9536  sub modify_directorysrch { Line 9805  sub modify_directorysrch {
             }              }
             if ($changes{'lclocalonly'}) {              if ($changes{'lclocalonly'}) {
                 $resulttext .= '<li>'.&mt("$title{'lclocalonly'} set to: $otherdoms[$env{'form.dirsrch_domlocalonly'}]").'</li>';                  $resulttext .= '<li>'.&mt("$title{'lclocalonly'} set to: $otherdoms[$env{'form.dirsrch_domlocalonly'}]").'</li>';
             }              }   
             if (ref($changes{'cansearch'}) eq 'ARRAY') {              if (ref($changes{'cansearch'}) eq 'ARRAY') {
                 my $chgtext;                  my $chgtext;
                 if (ref($usertypes) eq 'HASH') {                  if (ref($usertypes) eq 'HASH') {
Line 9586  sub modify_directorysrch { Line 9855  sub modify_directorysrch {
                 $resulttext .= '<li>'.&mt($title{'searchtypes'}.' set to: "[_1]"',$chgtext).'</li>';                  $resulttext .= '<li>'.&mt($title{'searchtypes'}.' set to: "[_1]"',$chgtext).'</li>';
             }              }
             $resulttext .= '</ul>';              $resulttext .= '</ul>';
             &Apache::lonnet::do_cache_new('directorysrch',$dom,$dirsrch_hash{'directorysrch'},3600);  
             if (ref($lastactref) eq 'HASH') {  
                 $lastactref->{'directorysrch'} = 1;  
             }  
         } else {          } else {
             $resulttext = &mt('No changes made to directory search settings');              $resulttext = &mt('No changes made to directory search settings');
         }          }
Line 9608  sub modify_contacts { Line 9873  sub modify_contacts {
             $currsetting{$key} = $domconfig{'contacts'}{$key};              $currsetting{$key} = $domconfig{'contacts'}{$key};
         }          }
     }      }
     my (%others,%to,%bcc,%includestr,%includeloc);      my (%others,%to,%bcc);
     my @contacts = ('supportemail','adminemail');      my @contacts = ('supportemail','adminemail');
     my @mailings = ('errormail','packagesmail','helpdeskmail','otherdomsmail',      my @mailings = ('errormail','packagesmail','helpdeskmail','lonstatusmail',
                     'lonstatusmail','requestsmail','updatesmail','idconflictsmail');                      'requestsmail','updatesmail','idconflictsmail');
     my @toggles = ('reporterrors','reportupdates');      my @toggles = ('reporterrors','reportupdates');
     my ($fields,$fieldtitles,$fieldoptions,$possoptions) = &helpform_fields();  
     foreach my $type (@mailings) {      foreach my $type (@mailings) {
         @{$newsetting{$type}} =           @{$newsetting{$type}} = 
             &Apache::loncommon::get_env_multiple('form.'.$type);              &Apache::loncommon::get_env_multiple('form.'.$type);
Line 9623  sub modify_contacts { Line 9887  sub modify_contacts {
             } else {              } else {
                 $contacts_hash{contacts}{$type}{$item} = 0;                  $contacts_hash{contacts}{$type}{$item} = 0;
             }              }
         }          }  
         $others{$type} = $env{'form.'.$type.'_others'};          $others{$type} = $env{'form.'.$type.'_others'};
         $contacts_hash{contacts}{$type}{'others'} = $others{$type};          $contacts_hash{contacts}{$type}{'others'} = $others{$type};
         if (($type eq 'helpdeskmail') || ($type eq 'otherdomsmail')) {          if ($type eq 'helpdeskmail') {
             $bcc{$type} = $env{'form.'.$type.'_bcc'};              $bcc{$type} = $env{'form.'.$type.'_bcc'};
             $contacts_hash{contacts}{$type}{'bcc'} = $bcc{$type};              $contacts_hash{contacts}{$type}{'bcc'} = $bcc{$type};
             if (($env{'form.'.$type.'_includestr'} ne '') && ($env{'form.'.$type.'_includeloc'} =~ /^s|b$/)) {  
                 $includestr{$type} = $env{'form.'.$type.'_includestr'};  
                 $includeloc{$type} = $env{'form.'.$type.'_includeloc'};  
                 $contacts_hash{contacts}{$type}{'include'} = $includeloc{$type}.':'.&escape($includestr{$type});  
             }  
         }          }
     }      }
     foreach my $item (@contacts) {      foreach my $item (@contacts) {
Line 9645  sub modify_contacts { Line 9904  sub modify_contacts {
             $contacts_hash{'contacts'}{$item} = $env{'form.'.$item};              $contacts_hash{'contacts'}{$item} = $env{'form.'.$item};
         }          }
     }      }
     if ((ref($fields) eq 'ARRAY') && (ref($possoptions) eq 'HASH')) {  
         foreach my $field (@{$fields}) {  
             if (ref($possoptions->{$field}) eq 'ARRAY') {  
                 my $value = $env{'form.helpform_'.$field};  
                 $value =~ s/^\s+|\s+$//g;  
                 if (grep(/^\Q$value\E$/,@{$possoptions->{$field}})) {  
                     $contacts_hash{contacts}{'helpform'}{$field} = $value;  
                     if ($field eq 'screenshot') {  
                         $env{'form.helpform_maxsize'} =~ s/^\s+|\s+$//g;  
                         if ($env{'form.helpform_maxsize'} =~ /^\d+\.?\d*$/) {  
                             $contacts_hash{contacts}{'helpform'}{'maxsize'} = $env{'form.helpform_maxsize'};  
                         }  
                     }  
                 }  
             }  
         }  
     }  
     if (keys(%currsetting) > 0) {      if (keys(%currsetting) > 0) {
         foreach my $item (@contacts) {          foreach my $item (@contacts) {
             if ($to{$item} ne $currsetting{$item}) {              if ($to{$item} ne $currsetting{$item}) {
Line 9681  sub modify_contacts { Line 9923  sub modify_contacts {
             if ($others{$type} ne $currsetting{$type}{'others'}) {              if ($others{$type} ne $currsetting{$type}{'others'}) {
                 push(@{$changes{$type}},'others');                  push(@{$changes{$type}},'others');
             }              }
             if (($type eq 'helpdeskmail') || ($type eq 'otherdomsmail')) {              if ($type eq 'helpdeskmail') {   
                 if ($bcc{$type} ne $currsetting{$type}{'bcc'}) {                  if ($bcc{$type} ne $currsetting{$type}{'bcc'}) {
                     push(@{$changes{$type}},'bcc');                       push(@{$changes{$type}},'bcc'); 
                 }                  }
                 my ($currloc,$currstr) = split(/:/,$currsetting{$type}{'include'},2);  
                 if (($includeloc{$type} ne $currloc) || (&escape($includestr{$type}) ne $currstr)) {  
                     push(@{$changes{$type}},'include');  
                 }  
             }  
         }  
         if (ref($fields) eq 'ARRAY') {  
             if (ref($currsetting{'helpform'}) eq 'HASH') {  
                 foreach my $field (@{$fields}) {  
                     if ($currsetting{'helpform'}{$field} ne $contacts_hash{'contacts'}{'helpform'}{$field}) {  
                         push(@{$changes{'helpform'}},$field);  
                     }  
                     if (($field eq 'screenshot') && ($contacts_hash{'contacts'}{'helpform'}{'screenshot'} ne 'no')) {  
                         if ($currsetting{'helpform'}{'maxsize'} ne $contacts_hash{'contacts'}{'helpform'}{'maxsize'}) {  
                             push(@{$changes{'helpform'}},'maxsize');  
                         }  
                     }  
                 }  
             } else {  
                 foreach my $field (@{$fields}) {  
                     if ($contacts_hash{'contacts'}{'helpform'}{$field} ne 'yes') {  
                         push(@{$changes{'helpform'}},$field);  
                     }  
                     if (($field eq 'screenshot') && ($contacts_hash{'contacts'}{'helpform'}{'screenshot'} ne 'no')) {  
                         if ($contacts_hash{'contacts'}{'helpform'}{'maxsize'} != 1) {  
                             push(@{$changes{'helpform'}},'maxsize');  
                         }  
                     }  
                 }  
             }              }
         }          }
     } else {      } else {
Line 9723  sub modify_contacts { Line 9936  sub modify_contacts {
         $default{'errormail'} = 'adminemail';          $default{'errormail'} = 'adminemail';
         $default{'packagesmail'} = 'adminemail';          $default{'packagesmail'} = 'adminemail';
         $default{'helpdeskmail'} = 'supportemail';          $default{'helpdeskmail'} = 'supportemail';
         $default{'otherdomsmail'} = 'supportemail';  
         $default{'lonstatusmail'} = 'adminemail';          $default{'lonstatusmail'} = 'adminemail';
         $default{'requestsmail'} = 'adminemail';          $default{'requestsmail'} = 'adminemail';
         $default{'updatesmail'} = 'adminemail';          $default{'updatesmail'} = 'adminemail';
         foreach my $item (@contacts) {          foreach my $item (@contacts) {
            if ($to{$item} ne $default{$item}) {             if ($to{$item} ne $default{$item}) {
                $changes{$item} = 1;                $changes{$item} = 1;
            }             }
         }          }
         foreach my $type (@mailings) {          foreach my $type (@mailings) {
             if ((@{$newsetting{$type}} != 1) || ($newsetting{$type}[0] ne $default{$type})) {              if ((@{$newsetting{$type}} != 1) || ($newsetting{$type}[0] ne $default{$type})) {
                  
                 push(@{$changes{$type}},@{$newsetting{$type}});                  push(@{$changes{$type}},@{$newsetting{$type}});
             }              }
             if ($others{$type} ne '') {              if ($others{$type} ne '') {
                 push(@{$changes{$type}},'others');                  push(@{$changes{$type}},'others');
             }              }
             if (($type eq 'helpdeskmail') || ($type eq 'otherdomsmail')) {              if ($type eq 'helpdeskmail') {
                 if ($bcc{$type} ne '') {                  if ($bcc{$type} ne '') {
                     push(@{$changes{$type}},'bcc');                      push(@{$changes{$type}},'bcc');
                 }                  }
                 if (($includeloc{$type} =~ /^b|s$/) && ($includestr{$type} ne '')) {  
                     push(@{$changes{$type}},'include');  
                 }  
             }  
         }  
         if (ref($fields) eq 'ARRAY') {  
             foreach my $field (@{$fields}) {  
                 if ($contacts_hash{'contacts'}{'helpform'}{$field} ne 'yes') {  
                     push(@{$changes{'helpform'}},$field);  
                 }  
                 if (($field eq 'screenshot') && ($contacts_hash{'contacts'}{'helpform'}{'screenshot'} ne 'no')) {  
                     if ($contacts_hash{'contacts'}{'helpform'}{'maxsize'} != 1) {  
                         push(@{$changes{'helpform'}},'maxsize');  
                     }  
                 }  
             }              }
         }          }
     }      }
Line 9789  sub modify_contacts { Line 9987  sub modify_contacts {
             }              }
             foreach my $type (@mailings) {              foreach my $type (@mailings) {
                 if (ref($changes{$type}) eq 'ARRAY') {                  if (ref($changes{$type}) eq 'ARRAY') {
                     if (($type eq 'helpdeskmail') || ($type eq 'otherdomsmail')) {                      $resulttext .= '<li>'.$titles->{$type}.': ';
                         $resulttext .= '<li>'.$titles->{$type}.' -- '.&mt('sent to').': ';  
                     } else {  
                         $resulttext .= '<li>'.$titles->{$type}.': ';  
                     }  
                     my @text;                      my @text;
                     foreach my $item (@{$newsetting{$type}}) {                      foreach my $item (@{$newsetting{$type}}) {
                         push(@text,$short_titles->{$item});                          push(@text,$short_titles->{$item});
Line 9801  sub modify_contacts { Line 9995  sub modify_contacts {
                     if ($others{$type} ne '') {                      if ($others{$type} ne '') {
                         push(@text,$others{$type});                          push(@text,$others{$type});
                     }                      }
                     if (@text) {                      $resulttext .= '<span class="LC_cusr_emph">'.
                         $resulttext .= '<span class="LC_cusr_emph">'.                                     join(', ',@text).'</span>';
                                        join(', ',@text).'</span>';                      if ($type eq 'helpdeskmail') {
                     }  
                     if (($type eq 'helpdeskmail') || ($type eq 'otherdomsmail')) {  
                         if ($bcc{$type} ne '') {                          if ($bcc{$type} ne '') {
                             my $bcctext;                              $resulttext .= '&nbsp;'.&mt('with Bcc to').': <span class="LC_cusr_emph">'.$bcc{$type}.'</span>';
                             if (@text) {  
                                 $bcctext = '&nbsp;'.&mt('with Bcc to');  
                             } else {  
                                 $bcctext = '(Bcc)';  
                             }  
                             $resulttext .= $bcctext.': <span class="LC_cusr_emph">'.$bcc{$type}.'</span>';  
                         } elsif (!@text) {  
                             $resulttext .= &mt('No one');  
                         }                          }
                         if ($includestr{$type} ne '') {  
                             if ($includeloc{$type} eq 'b') {  
                                 $resulttext .= '<br />'.&mt('Text automatically added to e-mail body:').' '.$includestr{$type};  
                             } elsif ($includeloc{$type} eq 's') {  
                                 $resulttext .= '<br />'.&mt('Text automatically added to e-mail subject:').' '.$includestr{$type};  
                             }  
                         }  
                     } elsif (!@text) {  
                         $resulttext .= &mt('No recipients');  
                     }                      }
                     $resulttext .= '</li>';                      $resulttext .= '</li>';
                 }                  }
Line 9847  sub modify_contacts { Line 10022  sub modify_contacts {
                                         &mt('LON-CAPA core group - MSU'),600,500)).                                          &mt('LON-CAPA core group - MSU'),600,500)).
                                 '</li>';                                  '</li>';
             }              }
             if ((ref($changes{'helpform'}) eq 'ARRAY') && (ref($fields) eq 'ARRAY')) {  
                 my (@optional,@required,@unused,$maxsizechg);  
                 foreach my $field (@{$changes{'helpform'}}) {  
                     if ($field eq 'maxsize') {  
                         $maxsizechg = 1;  
                         next;  
                     }  
                     if ($contacts_hash{'contacts'}{'helpform'}{$field} eq 'yes') {  
                         push(@optional,$field);  
                     } elsif ($contacts_hash{'contacts'}{'helpform'}{$field} eq 'no') {  
                         push(@unused,$field);  
                     } elsif ($contacts_hash{'contacts'}{'helpform'}{$field} eq 'req') {  
                         push(@required,$field);  
                     }  
                 }  
                 if (@optional) {  
                     $resulttext .= '<li>'.  
                                    &mt('Help form fields changed to "Optional": [_1].',  
                                        '<span class="LC_cusr_emph">'.join(', ',map { $fieldtitles->{$_}; } @optional)).'</span>'.  
                                    '</li>';  
                 }  
                 if (@required) {  
                     $resulttext .= '<li>'.  
                                    &mt('Help form fields changed to "Required": [_1].',  
                                        '<span class="LC_cusr_emph">'.join(', ',map { $fieldtitles->{$_}; } @required)).'</span>'.  
                                    '</li>';  
                 }  
                 if (@unused) {  
                     $resulttext .= '<li>'.  
                                    &mt('Help form fields changed to "Not shown": [_1].',  
                                        '<span class="LC_cusr_emph">'.join(', ',map { $fieldtitles->{$_}; } @unused)).'</span>'.  
                                    '</li>';  
                 }  
                 if ($maxsizechg) {  
                     $resulttext .= '<li>'.  
                                    &mt('Max size for file uploaded to help form by logged-in user set to [_1] MB.',  
                                        $contacts_hash{'contacts'}{'helpform'}{'maxsize'}).  
                                    '</li>';  
   
                 }  
             }  
             $resulttext .= '</ul>';              $resulttext .= '</ul>';
         } else {          } else {
             $resulttext = &mt('No changes made to contacts and form settings');              $resulttext = &mt('No changes made to contact information');
         }          }
     } else {      } else {
         $resulttext = '<span class="LC_error">'.          $resulttext = '<span class="LC_error">'.
Line 9908  sub modify_usercreation { Line 10042  sub modify_usercreation {
             if ($key eq 'cancreate') {              if ($key eq 'cancreate') {
                 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 'requestcrs') || ($item eq 'course') || ($item eq 'author')) {                          if (($item eq 'selfcreate') || ($item eq 'statustocreate') ||
                             $curr_usercreation{$key}{$item} = $domconfig{'usercreation'}{$key}{$item};                              ($item eq 'captcha') || ($item eq 'recaptchakeys') ||
                         } else {                              ($item eq 'recaptchaversion')) {
                             $save_usercreate{$key}{$item} = $domconfig{'usercreation'}{$key}{$item};                              $save_usercreate{$key}{$item} = $domconfig{'usercreation'}{$key}{$item};
                           } else {
                               $curr_usercreation{$key}{$item} = $domconfig{'usercreation'}{$key}{$item};
                         }                          }
                     }                      }
                 }                  }
Line 10114  sub modify_usercreation { Line 10250  sub modify_usercreation {
 }  }
   
 sub modify_selfcreation {  sub modify_selfcreation {
     my ($dom,$lastactref,%domconfig) = @_;      my ($dom,%domconfig) = @_;
     my ($resulttext,$warningmsg,%curr_usercreation,%curr_usermodify,%curr_inststatus,%changes,%cancreate);      my ($resulttext,$warningmsg,%curr_usercreation,%curr_usermodify,%changes,%cancreate);
     my (%save_usercreate,%save_usermodify,%save_inststatus,@types,%usertypes);      my (%save_usercreate,%save_usermodify);
     my %domdefaults = &Apache::lonnet::get_domain_defaults($dom,1);      my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom);
     my ($othertitle,$usertypesref,$typesref) = &Apache::loncommon::sorted_inst_types($dom);      if (ref($types) eq 'ARRAY') {
     if (ref($typesref) eq 'ARRAY') {          $usertypes->{'default'} = $othertitle;
         @types = @{$typesref};          push(@{$types},'default');
     }  
     if (ref($usertypesref) eq 'HASH') {  
         %usertypes = %{$usertypesref};  
     }      }
     $usertypes{'default'} = $othertitle;  
 #  #
 # Retrieve current domain configuration for self-creation of usernames from $domconfig{'usercreation'}.  # Retrieve current domain configuration for self-creation of usernames from $domconfig{'usercreation'}.
 #  #
Line 10135  sub modify_selfcreation { Line 10267  sub modify_selfcreation {
                 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') || ($item eq 'notify') ||                              ($item eq 'recaptchaversion') ||
                             ($item eq 'emailusername') || ($item eq 'shibenv') ||                              ($item eq 'emailusername') || ($item eq 'notify') ||
                             ($item eq 'selfcreateprocessing') || ($item eq 'emailverified') ||                              ($item eq 'selfcreateprocessing') || ($item eq 'shibenv')) {
                             ($item eq 'emailoptions') || ($item eq 'emaildomain')) {  
                             $curr_usercreation{$key}{$item} = $domconfig{'usercreation'}{$key}{$item};                              $curr_usercreation{$key}{$item} = $domconfig{'usercreation'}{$key}{$item};
                         } else {                          } else {
                             $save_usercreate{$key}{$item} = $domconfig{'usercreation'}{$key}{$item};                              $save_usercreate{$key}{$item} = $domconfig{'usercreation'}{$key}{$item};
Line 10165  sub modify_selfcreation { Line 10296  sub modify_selfcreation {
             }              }
         }          }
     }      }
 #  
 # Retrieve current domain configuration for institutional status types from $domconfig{'inststatus'}.  
 #  
     if (ref($domconfig{'inststatus'}) eq 'HASH') {  
         foreach my $key (keys(%{$domconfig{'inststatus'}})) {  
             if ($key eq 'inststatusguest') {  
                 $curr_inststatus{$key} = $domconfig{'inststatus'}{$key};  
             } else {  
                 $save_inststatus{$key} = $domconfig{'inststatus'}{$key};  
             }  
         }  
     }  
   
     my @contexts = ('selfcreate');      my @contexts = ('selfcreate');
     @{$cancreate{'selfcreate'}} = ();      @{$cancreate{'selfcreate'}} = ();
     %{$cancreate{'emailusername'}} = ();      %{$cancreate{'emailusername'}} = ();
     if (@types) {      @{$cancreate{'statustocreate'}} = ();
         @{$cancreate{'statustocreate'}} = ();  
     }  
     %{$cancreate{'selfcreateprocessing'}} = ();      %{$cancreate{'selfcreateprocessing'}} = ();
     %{$cancreate{'shibenv'}} = ();      %{$cancreate{'shibenv'}} = ();
     %{$cancreate{'emailverified'}} = ();  
     %{$cancreate{'emailoptions'}} = ();  
     %{$cancreate{'emaildomain'}} = ();  
     my %selfcreatetypes = (      my %selfcreatetypes = (
                              sso   => 'users authenticated by institutional single sign on',                               sso   => 'users authenticated by institutional single sign on',
                              login => 'users authenticated by institutional log-in',                               login => 'users authenticated by institutional log-in',
                              email => 'users verified by e-mail',                               email => 'users who provide a valid e-mail address for use as username',
                           );                            );
 #  #
 # Populate $cancreate{'selfcreate'} array reference with types of user, for which self-creation of user accounts  # Populate $cancreate{'selfcreate'} array reference with types of user, for which self-creation of user accounts
 # is permitted.  # is permitted.
 #  #
   
     my ($emailrules,$emailruleorder) = &Apache::lonnet::inst_userrules($dom,'email');      my @statuses;
       if (ref($domconfig{'inststatus'}) eq 'HASH') {
           if (ref($domconfig{'inststatus'}{'inststatusguest'}) eq 'ARRAY') {
               @statuses = @{$domconfig{'inststatus'}{'inststatusguest'}};
           }
       }
       push(@statuses,'default');
   
     my (@statuses,%email_rule);  
     foreach my $item ('login','sso','email') {      foreach my $item ('login','sso','email') {
         if ($item eq 'email') {          if ($item eq 'email') {
             if ($env{'form.cancreate_email'}) {              if ($env{'form.cancreate_email'}) {
                 if (@types) {                  push(@{$cancreate{'selfcreate'}},'email');
                     my @poss_statuses = &Apache::loncommon::get_env_multiple('form.selfassign');                  push(@contexts,'selfcreateprocessing');
                     foreach my $status (@poss_statuses) {                  foreach my $type (@statuses) {
                         if (grep(/^\Q$status\E$/,(@types,'default'))) {                      if ($type eq 'default') {
                             push(@statuses,$status);                          $cancreate{'selfcreateprocessing'}{$type} = $env{'form.cancreate_emailprocess'};
                         }                      } else { 
                     }                          $cancreate{'selfcreateprocessing'}{$type} = $env{'form.cancreate_emailprocess_'.$type};
                     $save_inststatus{'inststatusguest'} = \@statuses;  
                 } else {  
                     push(@statuses,'default');  
                 }  
                 if (@statuses) {  
                     my %curr_rule;  
                     if (ref($curr_usercreation{'email_rule'}) eq 'ARRAY') {  
                         foreach my $type (@statuses) {  
                             $curr_rule{$type} = $curr_usercreation{'email_rule'};  
                         }  
                     } elsif (ref($curr_usercreation{'email_rule'}) eq 'HASH') {  
                         foreach my $type (@statuses) {  
                             $curr_rule{$type} = $curr_usercreation{'email_rule'}{$type};  
                         }  
                     }  
                     push(@{$cancreate{'selfcreate'}},'email');  
                     push(@contexts,('selfcreateprocessing','emailverified','emailoptions'));  
                     my %curremaildom;  
                     if (ref($curr_usercreation{'cancreate'}{'emaildomain'}) eq 'HASH') {  
                         %curremaildom = %{$curr_usercreation{'cancreate'}{'emaildomain'}};  
                     }  
                     foreach my $type (@statuses) {  
                         if ($env{'form.cancreate_emailprocess_'.$type} =~ /^(?:approval|automatic)$/) {  
                             $cancreate{'selfcreateprocessing'}{$type} = $env{'form.cancreate_emailprocess_'.$type};  
                         }  
                         if ($env{'form.cancreate_usernameoptions_'.$type} =~ /^(?:all|first|free)$/) {  
                             $cancreate{'emailverified'}{$type} = $env{'form.cancreate_usernameoptions_'.$type};  
                         }  
                         if ($env{'form.cancreate_emailoptions_'.$type} =~ /^(any|inst|noninst|custom)$/) {  
 #  
 # Retrieve rules (if any) governing types of e-mail address which may be used to verify a username.  
 #  
                             my $chosen = $1;  
                             if (($chosen eq 'inst') || ($chosen eq 'noninst')) {  
                                 my $emaildom;  
                                 if ($env{'form.cancreate_emaildomain_'.$chosen.'_'.$type} =~ /^\@[^\@]+$/) {  
                                     $emaildom = $env{'form.cancreate_emaildomain_'.$chosen.'_'.$type};  
                                     $cancreate{'emaildomain'}{$type}{$chosen} = $emaildom;  
                                     if (ref($curremaildom{$type}) eq 'HASH') {  
                                         if (exists($curremaildom{$type}{$chosen})) {  
                                             if ($curremaildom{$type}{$chosen} ne $emaildom) {  
                                                 push(@{$changes{'cancreate'}},'emaildomain');  
                                             }  
                                         } elsif ($emaildom ne '') {  
                                             push(@{$changes{'cancreate'}},'emaildomain');  
                                         }  
                                     } elsif ($emaildom ne '') {  
                                         push(@{$changes{'cancreate'}},'emaildomain');  
                                     }  
                                 }  
                                 $cancreate{'emailoptions'}{$type} = $env{'form.cancreate_emailoptions_'.$type};  
                             } elsif ($chosen eq 'custom') {  
                                 my @possemail_rules = &Apache::loncommon::get_env_multiple('form.email_rule_'.$type);  
                                 $email_rule{$type} = [];  
                                 if (ref($emailrules) eq 'HASH') {  
                                     foreach my $rule (@possemail_rules) {  
                                         if (exists($emailrules->{$rule})) {  
                                             push(@{$email_rule{$type}},$rule);  
                                         }  
                                     }  
                                 }  
                                 if (@{$email_rule{$type}}) {  
                                     $cancreate{'emailoptions'}{$type} = 'custom';  
                                     if (ref($curr_rule{$type}) eq 'ARRAY') {  
                                         if (@{$curr_rule{$type}} > 0) {  
                                             foreach my $rule (@{$curr_rule{$type}}) {  
                                                 if (!grep(/^\Q$rule\E$/,@{$email_rule{$type}})) {  
                                                     push(@{$changes{'email_rule'}},$type);  
                                                 }  
                                             }  
                                         }  
                                         foreach my $type (@{$email_rule{$type}}) {  
                                             if (!grep(/^\Q$type\E$/,@{$curr_rule{$type}})) {  
                                                 push(@{$changes{'email_rule'}},$type);  
                                             }  
                                         }  
                                     } else {  
                                         push(@{$changes{'email_rule'}},$type);  
                                     }  
                                 }  
                             } else {  
                                 $cancreate{'emailoptions'}{$type} = $env{'form.cancreate_emailoptions_'.$type};  
                             }  
                         }  
                     }  
                     if (@types) {  
                         if (ref($curr_inststatus{'inststatusguest'}) eq 'ARRAY') {  
                             my @changed = &Apache::loncommon::compare_arrays(\@statuses,$curr_inststatus{'inststatusguest'});  
                             if (@changed) {  
                                 push(@{$changes{'inststatus'}},'inststatusguest');  
                             }  
                         } else {  
                             push(@{$changes{'inststatus'}},'inststatusguest');  
                         }  
                     }  
                 } else {  
                     delete($env{'form.cancreate_email'});  
                     if (ref($curr_inststatus{'inststatusguest'}) eq 'ARRAY') {  
                         if (@{$curr_inststatus{'inststatusguest'}} > 0) {  
                             push(@{$changes{'inststatus'}},'inststatusguest');  
                         }  
                     }  
                 }  
             } else {  
                 $save_inststatus{'inststatusguest'} = [];  
                 if (ref($curr_inststatus{'inststatusguest'}) eq 'ARRAY') {  
                     if (@{$curr_inststatus{'inststatusguest'}} > 0) {  
                         push(@{$changes{'inststatus'}},'inststatusguest');  
                     }                      }
                 }                  }
             }              }
Line 10329  sub modify_selfcreation { Line 10340  sub modify_selfcreation {
             }              }
         }          }
     }      }
     my (%userinfo,%savecaptcha);      my (@email_rule,%userinfo,%savecaptcha);
     my ($infofields,$infotitles) = &Apache::loncommon::emailusername_info();      my ($infofields,$infotitles) = &Apache::loncommon::emailusername_info();
 #  #
 # Populate $cancreate{'emailusername'}{$type} hash ref with information fields (if new user will provide data  # Populate $cancreate{'emailusername'}{$type} hash ref with information fields (if new user will provide data
Line 10338  sub modify_selfcreation { Line 10349  sub modify_selfcreation {
   
     if ($env{'form.cancreate_email'}) {      if ($env{'form.cancreate_email'}) {
         push(@contexts,'emailusername');          push(@contexts,'emailusername');
         if (@statuses) {          if (ref($types) eq 'ARRAY') {
             foreach my $type (@statuses) {              foreach my $type (@{$types}) {
                 if (ref($infofields) eq 'ARRAY') {                  if (ref($infofields) eq 'ARRAY') {
                     foreach my $field (@{$infofields}) {                      foreach my $field (@{$infofields}) {
                         if ($env{'form.canmodify_emailusername_'.$type.'_'.$field} =~ /^(required|optional)$/) {                          if ($env{'form.canmodify_emailusername_'.$type.'_'.$field} =~ /^(required|optional)$/) {
Line 10351  sub modify_selfcreation { Line 10362  sub modify_selfcreation {
         }          }
 #  #
 # Populate $cancreate{'notify'} hash ref with names of Domain Coordinators who are to be notified of  # Populate $cancreate{'notify'} hash ref with names of Domain Coordinators who are to be notified of
 # queued requests for self-creation of account verified by e-mail.  # queued requests for self-creation of account using e-mail address as username
 #  #
   
         my @approvalnotify = &Apache::loncommon::get_env_multiple('form.selfcreationnotifyapproval');          my @approvalnotify = &Apache::loncommon::get_env_multiple('form.selfcreationnotifyapproval');
Line 10371  sub modify_selfcreation { Line 10382  sub modify_selfcreation {
             push(@{$changes{'cancreate'}},'notify');              push(@{$changes{'cancreate'}},'notify');
         }          }
   
   #
   # Retrieve rules (if any) governing types of e-mail address which may be used as a username
   #
           @email_rule = &Apache::loncommon::get_env_multiple('form.email_rule');
         &process_captcha('cancreate',\%changes,\%savecaptcha,$curr_usercreation{'cancreate'});          &process_captcha('cancreate',\%changes,\%savecaptcha,$curr_usercreation{'cancreate'});
           if (ref($curr_usercreation{'email_rule'}) eq 'ARRAY') {
               if (@{$curr_usercreation{'email_rule'}} > 0) {
                   foreach my $type (@{$curr_usercreation{'email_rule'}}) {
                       if (!grep(/^\Q$type\E$/,@email_rule)) {
                           push(@{$changes{'email_rule'}},$type);
                       }
                   }
               }
               if (@email_rule > 0) {
                   foreach my $type (@email_rule) {
                       if (!grep(/^\Q$type\E$/,@{$curr_usercreation{'email_rule'}})) {
                           push(@{$changes{'email_rule'}},$type);
                       }
                   }
               }
           } elsif (@email_rule > 0) {
               push(@{$changes{'email_rule'}},@email_rule);
           }
     }      }
 #    #  
 # Check if domain default is set appropriately, if self-creation of accounts is to be available for  # Check if domain default is set appropriately, if self-creation of accounts is to be available for
 # institutional log-in.  # institutional log-in.
 #  #
     if (grep(/^login$/,@{$cancreate{'selfcreate'}})) {      if (grep(/^login$/,@{$cancreate{'selfcreate'}})) {
           my %domdefaults = &Apache::lonnet::get_domain_defaults($dom,1);
         if (!((($domdefaults{'auth_def'} =~/^krb/) && ($domdefaults{'auth_arg_def'} ne '')) ||           if (!((($domdefaults{'auth_def'} =~/^krb/) && ($domdefaults{'auth_arg_def'} ne '')) || 
                ($domdefaults{'auth_def'} eq 'localauth'))) {                 ($domdefaults{'auth_def'} eq 'localauth'))) {
             $warningmsg = &mt('Although account creation has been set to be available for institutional logins, currently default authentication in this domain has not been set to support this.').' '.              $warningmsg = &mt('Although account creation has been set to be available for institutional logins, currently default authentication in this domain has not been set to support this.').' '.
Line 10396  sub modify_selfcreation { Line 10430  sub modify_selfcreation {
 # which the user may supply, if institutional data is unavailable.  # which the user may supply, if institutional data is unavailable.
 #  #
     if (($env{'form.cancreate_login'}) || ($env{'form.cancreate_sso'})) {      if (($env{'form.cancreate_login'}) || ($env{'form.cancreate_sso'})) {
         if (@types) {          if (ref($types) eq 'ARRAY') {
             @{$cancreate{'statustocreate'}} = &Apache::loncommon::get_env_multiple('form.statustocreate');              if (@{$types} > 1) {
             push(@contexts,'statustocreate');                  @{$cancreate{'statustocreate'}} = &Apache::loncommon::get_env_multiple('form.statustocreate');
             foreach my $type (@types) {                  push(@contexts,'statustocreate');
               } else {
                   undef($cancreate{'statustocreate'});
               } 
               foreach my $type (@{$types}) {
                 my @modifiable =  &Apache::loncommon::get_env_multiple('form.canmodify_'.$type);                  my @modifiable =  &Apache::loncommon::get_env_multiple('form.canmodify_'.$type);
                 foreach my $field (@fields) {                  foreach my $field (@fields) {
                     if (grep(/^\Q$field\E$/,@modifiable)) {                      if (grep(/^\Q$field\E$/,@modifiable)) {
Line 10410  sub modify_selfcreation { Line 10448  sub modify_selfcreation {
                 }                  }
             }              }
             if (ref($curr_usermodify{'selfcreate'}) eq 'HASH') {              if (ref($curr_usermodify{'selfcreate'}) eq 'HASH') {
                 foreach my $type (@types) {                  foreach my $type (@{$types}) {
                     if (ref($curr_usermodify{'selfcreate'}{$type}) eq 'HASH') {                      if (ref($curr_usermodify{'selfcreate'}{$type}) eq 'HASH') {
                         foreach my $field (@fields) {                          foreach my $field (@fields) {
                             if ($save_usermodify{'selfcreate'}{$type}{$field} ne                              if ($save_usermodify{'selfcreate'}{$type}{$field} ne
Line 10422  sub modify_selfcreation { Line 10460  sub modify_selfcreation {
                     }                      }
                 }                  }
             } else {              } else {
                 foreach my $type (@types) {                  foreach my $type (@{$types}) {
                     push(@{$changes{'selfcreate'}},$type);                      push(@{$changes{'selfcreate'}},$type);
                 }                  }
             }              }
Line 10471  sub modify_selfcreation { Line 10509  sub modify_selfcreation {
             }              }
         } elsif (ref($curr_usercreation{'cancreate'}{$item}) eq 'HASH') {          } elsif (ref($curr_usercreation{'cancreate'}{$item}) eq 'HASH') {
             if (ref($cancreate{$item}) eq 'HASH') {              if (ref($cancreate{$item}) eq 'HASH') {
                 foreach my $type (keys(%{$curr_usercreation{'cancreate'}{$item}})) {                  foreach my $curr (keys(%{$curr_usercreation{'cancreate'}{$item}})) {
                     if (ref($curr_usercreation{'cancreate'}{$item}{$type}) eq 'HASH') {                      if (ref($curr_usercreation{'cancreate'}{$item}{$curr}) eq 'HASH') {
                         foreach my $field (keys(%{$curr_usercreation{'cancreate'}{$item}{$type}})) {                          foreach my $field (keys(%{$curr_usercreation{'cancreate'}{$item}{$curr}})) {
                             unless ($curr_usercreation{'cancreate'}{$item}{$type}{$field} eq $cancreate{$item}{$type}{$field}) {                              unless ($curr_usercreation{'cancreate'}{$item}{$curr}{$field} eq $cancreate{$item}{$curr}{$field}) {
                                 if (!grep(/^$item$/,@{$changes{'cancreate'}})) {                                  if (!grep(/^$item$/,@{$changes{'cancreate'}})) {
                                     push(@{$changes{'cancreate'}},$item);                                      push(@{$changes{'cancreate'}},$item);
                                 }                                  }
                             }                              }
                         }                          }
                     } elsif (($item eq 'selfcreateprocessing') || ($item eq 'emailverified') || ($item eq 'emailoptions')) {                      } elsif ($item eq 'selfcreateprocessing') {
                         if ($cancreate{$item}{$type} ne $curr_usercreation{'cancreate'}{$item}{$type}) {                          if ($cancreate{$item}{$curr} ne $curr_usercreation{'cancreate'}{$item}{$curr}) {
                               if (!grep(/^$item$/,@{$changes{'cancreate'}})) {
                                   push(@{$changes{'cancreate'}},$item);
                               }
                           }
                       } else {
                           if (!$cancreate{$item}{$curr}) {
                             if (!grep(/^$item$/,@{$changes{'cancreate'}})) {                              if (!grep(/^$item$/,@{$changes{'cancreate'}})) {
                                 push(@{$changes{'cancreate'}},$item);                                  push(@{$changes{'cancreate'}},$item);
                             }                              }
                         }                          }
                     }                      }
                 }                  }
                 foreach my $type (keys(%{$cancreate{$item}})) {                  foreach my $field (keys(%{$cancreate{$item}})) {
                     if (ref($cancreate{$item}{$type}) eq 'HASH') {                      if (ref($cancreate{$item}{$field}) eq 'HASH') {
                         foreach my $field (keys(%{$cancreate{$item}{$type}})) {                          foreach my $inner (keys(%{$cancreate{$item}{$field}})) {
                             if (ref($curr_usercreation{'cancreate'}{$item}{$type}) eq 'HASH') {                              if (ref($curr_usercreation{'cancreate'}{$item}{$field}) eq 'HASH') {
                                 unless ($curr_usercreation{'cancreate'}{$item}{$type}{$field} eq $cancreate{$item}{$type}{$field}) {                                  unless ($curr_usercreation{'cancreate'}{$item}{$field}{$inner} eq $cancreate{$item}{$field}{$inner}) {
                                     if (!grep(/^$item$/,@{$changes{'cancreate'}})) {                                      if (!grep(/^$item$/,@{$changes{'cancreate'}})) {
                                         push(@{$changes{'cancreate'}},$item);                                          push(@{$changes{'cancreate'}},$item);
                                     }                                      }
Line 10503  sub modify_selfcreation { Line 10547  sub modify_selfcreation {
                                 }                                  }
                             }                              }
                         }                          }
                     } elsif (($item eq 'selfcreateprocessing') || ($item eq 'emailverified') || ($item eq 'emailoptions')) {                      } elsif ($item eq 'selfcreateprocessing') {
                         if ($cancreate{$item}{$type} ne $curr_usercreation{'cancreate'}{$item}{$type}) {                          if ($cancreate{$item}{$field} ne $curr_usercreation{'cancreate'}{$item}{$field}) {
                               if (!grep(/^$item$/,@{$changes{'cancreate'}})) {
                                   push(@{$changes{'cancreate'}},$item);
                               }
                           }
                       } else {
                           if (!$curr_usercreation{'cancreate'}{$item}{$field}) {
                             if (!grep(/^$item$/,@{$changes{'cancreate'}})) {                              if (!grep(/^$item$/,@{$changes{'cancreate'}})) {
                                 push(@{$changes{'cancreate'}},$item);                                  push(@{$changes{'cancreate'}},$item);
                             }                              }
Line 10519  sub modify_selfcreation { Line 10569  sub modify_selfcreation {
                         push(@{$changes{'cancreate'}},$item);                          push(@{$changes{'cancreate'}},$item);
                     }                      }
                 }                  }
             }              } elsif (ref($cancreate{$item}) eq 'HASH') {
         } elsif (($item eq 'selfcreateprocessing') || ($item eq 'emailverified') || ($item eq 'emailoptions')) {                  if (!$cancreate{$item}{$curr_usercreation{'cancreate'}{$item}}) {
             if (ref($cancreate{$item}) eq 'HASH') {                      if (!grep(/^$item$/,@{$changes{'cancreate'}})) {
                 if (!grep(/^$item$/,@{$changes{'cancreate'}})) {                          push(@{$changes{'cancreate'}},$item);
                     push(@{$changes{'cancreate'}},$item);                      }
                 }                  }
             }              }
         } elsif ($item eq 'emailusername') {          } elsif ($item eq 'emailusername') {
Line 10556  sub modify_selfcreation { Line 10606  sub modify_selfcreation {
     if (ref($cancreate{'selfcreateprocessing'}) eq 'HASH') {      if (ref($cancreate{'selfcreateprocessing'}) eq 'HASH') {
         $save_usercreate{'cancreate'}{'selfcreateprocessing'} = $cancreate{'selfcreateprocessing'};          $save_usercreate{'cancreate'}{'selfcreateprocessing'} = $cancreate{'selfcreateprocessing'};
     }      }
     if (ref($cancreate{'emailverified'}) eq 'HASH') {  
         $save_usercreate{'cancreate'}{'emailverified'} = $cancreate{'emailverified'};  
     }  
     if (ref($cancreate{'emailoptions'}) eq 'HASH') {  
         $save_usercreate{'cancreate'}{'emailoptions'} = $cancreate{'emailoptions'};  
     }  
     if (ref($cancreate{'emaildomain'}) eq 'HASH') {  
         $save_usercreate{'cancreate'}{'emaildomain'} = $cancreate{'emaildomain'};  
     }  
     if (ref($cancreate{'statustocreate'}) eq 'ARRAY') {      if (ref($cancreate{'statustocreate'}) eq 'ARRAY') {
         $save_usercreate{'cancreate'}{'statustocreate'} = $cancreate{'statustocreate'};          $save_usercreate{'cancreate'}{'statustocreate'} = $cancreate{'statustocreate'};
     }      }
Line 10572  sub modify_selfcreation { Line 10613  sub modify_selfcreation {
         $save_usercreate{'cancreate'}{'shibenv'} = $cancreate{'shibenv'};          $save_usercreate{'cancreate'}{'shibenv'} = $cancreate{'shibenv'};
     }      }
     $save_usercreate{'cancreate'}{'emailusername'} = $cancreate{'emailusername'};      $save_usercreate{'cancreate'}{'emailusername'} = $cancreate{'emailusername'};
     $save_usercreate{'email_rule'} = \%email_rule;      $save_usercreate{'emailrule'} = \@email_rule;
   
     my %userconfig_hash = (      my %userconfig_hash = (
             usercreation     => \%save_usercreate,              usercreation     => \%save_usercreate,
             usermodification => \%save_usermodify,              usermodification => \%save_usermodify,
             inststatus       => \%save_inststatus,  
     );      );
   
     my $putresult = &Apache::lonnet::put_dom('configuration',\%userconfig_hash,      my $putresult = &Apache::lonnet::put_dom('configuration',\%userconfig_hash,
                                              $dom);                                               $dom);
 #  #
 # Accumulate details of changes to domain configuration for self-creation of usernames in $resulttext  # Accumulate details of changes to domain cofiguration for self-creation of usernames in $resulttext
 #  #
     if ($putresult eq 'ok') {      if ($putresult eq 'ok') {
         if (keys(%changes) > 0) {          if (keys(%changes) > 0) {
Line 10591  sub modify_selfcreation { Line 10630  sub modify_selfcreation {
             if (ref($changes{'cancreate'}) eq 'ARRAY') {              if (ref($changes{'cancreate'}) eq 'ARRAY') {
                 my %lt = &selfcreation_types();                  my %lt = &selfcreation_types();
                 foreach my $type (@{$changes{'cancreate'}}) {                  foreach my $type (@{$changes{'cancreate'}}) {
                     my $chgtext = '';                      my $chgtext;
                     if ($type eq 'selfcreate') {                      if ($type eq 'selfcreate') {
                         if (@{$cancreate{$type}} == 0) {                          if (@{$cancreate{$type}} == 0) {
                             $chgtext .= &mt('Self creation of a new user account is not permitted.');                              $chgtext .= &mt('Self creation of a new user account is not permitted.');
Line 10606  sub modify_selfcreation { Line 10645  sub modify_selfcreation {
                                 if (grep(/^(login|sso)$/,@{$cancreate{$type}})) {                                  if (grep(/^(login|sso)$/,@{$cancreate{$type}})) {
                                     if (ref($cancreate{'statustocreate'}) eq 'ARRAY') {                                      if (ref($cancreate{'statustocreate'}) eq 'ARRAY') {
                                         if (@{$cancreate{'statustocreate'}} == 0) {                                          if (@{$cancreate{'statustocreate'}} == 0) {
                                             $chgtext .= '<span class="LC_warning">'.                                              $chgtext .= '<br />'.
                                                         &mt("However, no institutional affiliations (including 'other') are currently permitted to create accounts via log-in or single sign-on.").                                                          '<span class="LC_warning">'.
                                                         '</span><br />';                                                          &mt("However, no institutional affiliations (including 'other') are currently permitted to create accounts.").
                                                           '</span>';
                                         }                                          }
                                     }                                      }
                                 }                                  }
                                 if (grep(/^email$/,@{$cancreate{$type}})) {  
                                     if (!@statuses) {  
                                         $chgtext .= '<span class="LC_warning">'.  
                                                     &mt("However, e-mail verification is currently set to 'unavailable' for all user types (including 'other'), so self-creation of accounts is not possible for non-institutional log-in.").  
                                                     '</span><br />';  
   
                                     }  
                                 }  
                             }                              }
                         }                          }
                     } elsif ($type eq 'shibenv') {                      } elsif ($type eq 'shibenv') {
                         if (keys(%{$cancreate{$type}}) == 0) {                          if (keys(%{$cancreate{$type}}) == 0) {
                             $chgtext .= &mt('Shibboleth-autheticated user does not use environment variables to set user information').'<br />';                               $chgtext .= &mt('Shibboleth-autheticated user does not use environment variables to set user information'); 
                         } else {                          } else {
                             $chgtext .= &mt('Shibboleth-autheticated user information set from environment variables, as follows:').                              $chgtext .= &mt('Shibboleth-autheticated user information set from environment variables, as follows:').
                                         '<ul>';                                          '<ul>';
Line 10637  sub modify_selfcreation { Line 10669  sub modify_selfcreation {
                                 }                                  }
                             }                              }
                             $chgtext .= '</ul>';                              $chgtext .= '</ul>';
                         }                          }  
                     } elsif ($type eq 'statustocreate') {                      } elsif ($type eq 'statustocreate') {
                         if ((ref($cancreate{'selfcreate'}) eq 'ARRAY') &&                          if ((ref($cancreate{'selfcreate'}) eq 'ARRAY') &&
                             (ref($cancreate{'statustocreate'}) eq 'ARRAY')) {                              (ref($cancreate{'statustocreate'}) eq 'ARRAY')) {
Line 10650  sub modify_selfcreation { Line 10682  sub modify_selfcreation {
                                                     &mt("However, no institutional affiliations (including 'other') are currently permitted to create accounts.").                                                      &mt("However, no institutional affiliations (including 'other') are currently permitted to create accounts.").
                                                     '</span>';                                                      '</span>';
                                     }                                      }
                                 } elsif (keys(%usertypes) > 0) {                                  } elsif (ref($usertypes) eq 'HASH') {
                                     if (grep(/^(login|sso)$/,@{$cancreate{'selfcreate'}})) {                                      if (grep(/^(login|sso)$/,@{$cancreate{'selfcreate'}})) {
                                         $chgtext .= &mt('Creation of a new account for an institutional user is restricted to the following institutional affiliation(s):');                                          $chgtext .= &mt('Creation of a new account for an institutional user is restricted to the following institutional affiliation(s):');
                                     } else {                                      } else {
Line 10661  sub modify_selfcreation { Line 10693  sub modify_selfcreation {
                                         if ($case eq 'default') {                                          if ($case eq 'default') {
                                             $chgtext .= '<li>'.$othertitle.'</li>';                                              $chgtext .= '<li>'.$othertitle.'</li>';
                                         } else {                                          } else {
                                             $chgtext .= '<li>'.$usertypes{$case}.'</li>';                                              $chgtext .= '<li>'.$usertypes->{$case}.'</li>';
                                         }                                          }
                                     }                                      }
                                     $chgtext .= '</ul>';                                      $chgtext .= '</ul>';
                                     if (!grep(/^(login|sso)$/,@{$cancreate{'selfcreate'}})) {                                      if (!grep(/^(login|sso)$/,@{$cancreate{'selfcreate'}})) {
                                         $chgtext .= '<span class="LC_warning">'.                                          $chgtext .= '<br /><span class="LC_warning">'.
                                                     &mt('However, users authenticated by institutional login/single sign on are not currently permitted to create accounts.').                                                      &mt('However, users authenticated by institutional login/single sign on are not currently permitted to create accounts.').
                                                     '</span>';                                                      '</span>';
                                     }                                      }
Line 10678  sub modify_selfcreation { Line 10710  sub modify_selfcreation {
                                     $chgtext .= &mt('Although institutional affiliations permitted to create accounts were changed, self creation of accounts is not currently permitted for any authentication types.');                                      $chgtext .= &mt('Although institutional affiliations permitted to create accounts were changed, self creation of accounts is not currently permitted for any authentication types.');
                                 }                                  }
                             }                              }
                             $chgtext .= '<br />';  
                         }                          }
                     } elsif ($type eq 'selfcreateprocessing') {                      } elsif ($type eq 'selfcreateprocessing') {
                         my %choices = &Apache::lonlocal::texthash (                          my %choices = &Apache::lonlocal::texthash (
                                                                     automatic => 'Automatic approval',                                                                      automatic => 'Automatic approval',
                                                                     approval  => 'Queued for approval',                                                                      approval  => 'Queued for approval',
                                                                   );                                                                    );
                         if (@types) {                          if (@statuses > 1) {
                             if (@statuses) {                              $chgtext .= &mt('Processing of requests to create account with e-mail address as username set as follows:'). 
                                 $chgtext .= &mt('Processing of requests to create account with e-mail verification set as follows:').                                           '<ul>';
                                                 '<ul>';                             foreach my $type (@statuses) {
                                 foreach my $status (@statuses) {                                 if ($type eq 'default') {
                                     if ($status eq 'default') {                                     $chgtext .= '<li>'.$othertitle.' -- '.$choices{$cancreate{'selfcreateprocessing'}{$type}}.'</li>';
                                         $chgtext .= '<li>'.$othertitle.' -- '.$choices{$cancreate{'selfcreateprocessing'}{$status}}.'</li>';                                 } else {
                                     } else {                                     $chgtext .= '<li>'.$usertypes->{$type}.' -- '.$choices{$cancreate{'selfcreateprocessing'}{$type}}.'</li>';
                                         $chgtext .= '<li>'.$usertypes{$status}.' -- '.$choices{$cancreate{'selfcreateprocessing'}{$status}.'</li>';                                 }
                                     }                             }
                                 }                             $chgtext .= '</ul>';
                                 $chgtext .= '</ul>';  
                             }  
                         } else {  
                             $chgtext .= &mt('Processing of requests to create account with e-mail verification set to: "[_1]"',  
                                             $choices{$cancreate{'selfcreateprocessing'}{'default'}});  
                         }  
                     } elsif ($type eq 'emailverified') {  
                         my %options = &Apache::lonlocal::texthash (  
                                                                     all   => 'Same as e-mail',  
                                                                     first => 'Omit @domain',  
                                                                     free  => 'Free to choose',  
                                                                   );  
                         if (@types) {  
                             if (@statuses) {  
                                 $chgtext .= &mt('For self-created accounts verified by e-mail address, username is set as follows:').  
                                             '<ul>';  
                                 foreach my $status (@statuses) {  
                                     if ($type eq 'default') {  
                                         $chgtext .= '<li>'.$othertitle.' -- '.$options{$cancreate{'emailverified'}{$status}}.'</li>';  
                                     } else {  
                                         $chgtext .= '<li>'.$usertypes{$status}.' -- '.$options{$cancreate{'emailverified'}{$status}}.'</li>';  
                                     }  
                                 }  
                                 $chgtext .= '</ul>';  
                             }  
                         } else {  
                             $chgtext .= &mt("For self-created accounts verified by e-mail address, user's username is: '[_1]'",  
                                             $options{$cancreate{'emailverified'}{'default'}});  
                         }  
                     } elsif ($type eq 'emailoptions') {  
                         my %options = &Apache::lonlocal::texthash (  
                                                                     any     => 'Any e-mail',  
                                                                     inst    => 'Institutional only',  
                                                                     noninst => 'Non-institutional only',  
                                                                     custom  => 'Custom restrictions',  
                                                                   );  
                         if (@types) {  
                             if (@statuses) {  
                                 $chgtext .= &mt('For self-created accounts verified by e-mail address, requirements for e-mail address are as follows:').  
                                             '<ul>';  
                                 foreach my $status (@statuses) {  
                                     if ($type eq 'default') {  
                                         $chgtext .= '<li>'.$othertitle.' -- '.$options{$cancreate{'emailoptions'}{$status}}.'</li>';  
                                     } else {  
                                         $chgtext .= '<li>'.$usertypes{$status}.' -- '.$options{$cancreate{'emailoptions'}{$status}}.'</li>';  
                                     }  
                                 }  
                                 $chgtext .= '</ul>';  
                             }  
                         } else {                          } else {
                             if ($cancreate{'emailoptions'}{'default'} eq 'any') {                             $chgtext .= &mt('Processing of requests to create account with e-mail address as username set to: "[_1]"',
                                 $chgtext .= &mt('For self-created accounts verified by e-mail address, any e-mail may be used');                                           $choices{$cancreate{'selfcreateprocessing'}{'default'}});
                             } else {  
                                 $chgtext .= &mt('For self-created accounts verified by e-mail address, e-mail restricted to: "[_1]"',  
                                                 $options{$cancreate{'emailoptions'}{'default'}});  
                             }  
                         }  
                     } elsif ($type eq 'emaildomain') {  
                         my $output;  
                         if (@statuses) {  
                             foreach my $type (@statuses) {  
                                 if (ref($cancreate{'emaildomain'}{$type}) eq 'HASH') {  
                                     if ($cancreate{'emailoptions'}{$type} eq 'inst') {  
                                         if ($type eq 'default') {  
                                             if ((ref($cancreate{'emaildomain'}{$type}) ne 'HASH') ||  
                                                 ($cancreate{'emaildomain'}{$type}{'inst'} eq '')) {  
                                                 $output = '<li>'.$othertitle.' -- '.&mt('No restriction on e-mail domain').'</li>';  
                                             } else {  
                                                 $output = '<li>'.$othertitle.' -- '.&mt("User's e-mail address needs to end: [_1]",  
                                                                                         $cancreate{'emaildomain'}{$type}{'inst'}).'</li>';  
                                             }  
                                         } else {  
                                             if ((ref($cancreate{'emaildomain'}{$type}) ne 'HASH') ||  
                                                 ($cancreate{'emaildomain'}{$type}{'inst'} eq '')) {  
                                                 $output = '<li>'.$usertypes{$type}.' -- '.&mt('No restriction on e-mail domain').'</li>';  
                                             } else {  
                                                 $output = '<li>'.$usertypes{$type}.' -- '.&mt("User's e-mail address needs to end: [_1]",  
                                                                                               $cancreate{'emaildomain'}{$type}{'inst'}).'</li>';  
                                             }  
                                         }  
                                     } elsif ($cancreate{'emailoptions'}{$type} eq 'noninst') {  
                                         if ($type eq 'default') {  
                                             if ((ref($cancreate{'emaildomain'}{$type}) ne 'HASH') ||  
                                                 ($cancreate{'emaildomain'}{$type}{'noninst'} eq '')) {  
                                                 $output = '<li>'.$othertitle.' -- '.&mt('No restriction on e-mail domain').'</li>';  
                                             } else {  
                                                 $output = '<li>'.$othertitle.' -- '.&mt("User's e-mail address must not end: [_1]",  
                                                                                         $cancreate{'emaildomain'}{$type}{'noninst'}).'</li>';  
                                             }  
                                         } else {  
                                             if ((ref($cancreate{'emaildomain'}{$type}) ne 'HASH') ||  
                                                 ($cancreate{'emaildomain'}{$type}{'noninst'} eq '')) {  
                                                 $output = '<li>'.$usertypes{$type}.' -- '.&mt('No restriction on e-mail domain').'</li>';  
                                             } else {  
                                                 $output = '<li>'.$usertypes{$type}.' -- '.&mt("User's e-mail address must not end: [_1]",  
                                                                                                 $cancreate{'emaildomain'}{$type}{'noninst'}).'</li>';  
                                             }  
                                         }  
                                     }  
                                 }  
                             }  
                         }  
                         if ($output ne '') {  
                             $chgtext .= &mt('For self-created accounts verified by e-mail address:').  
                                         '<ul>'.$output.'</ul>';  
                         }                          }
                     } elsif ($type eq 'captcha') {                      } elsif ($type eq 'captcha') {
                         if ($savecaptcha{$type} eq 'notused') {                          if ($savecaptcha{$type} eq 'notused') {
Line 10837  sub modify_selfcreation { Line 10766  sub modify_selfcreation {
                         }                          }
                     } elsif ($type eq 'emailusername') {                      } elsif ($type eq 'emailusername') {
                         if (ref($cancreate{'emailusername'}) eq 'HASH') {                          if (ref($cancreate{'emailusername'}) eq 'HASH') {
                             if (@statuses) {                              if (ref($types) eq 'ARRAY') {
                                 foreach my $type (@statuses) {                                  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 verification, 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}) {
Line 10850  sub modify_selfcreation { Line 10779  sub modify_selfcreation {
                                             }                                              }
                                             $chgtext .= '</ul>';                                              $chgtext .= '</ul>';
                                         } else {                                          } else {
                                             $chgtext .= &mt('When self creating account with e-mail verification, 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 />';
                                         }                                          }
                                     } else {                                      } else {
                                         $chgtext .= &mt('When self creating account with e-mail verficiation, 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 />';
                                     }                                      }
                                 }                                  }
                             }                              }
                         }                          }
                     } elsif ($type eq 'notify') {                      } elsif ($type eq 'notify') {
                         my $numapprove = 0;                           $chgtext = &mt('No Domain Coordinators will receive notification of username requests requiring approval.');
                         if (ref($changes{'cancreate'}) eq 'ARRAY') {                          if (ref($changes{'cancreate'}) eq 'ARRAY') {
                             if ((grep(/^notify$/,@{$changes{'cancreate'}})) && (ref($cancreate{'notify'}) eq 'HASH')) {                              if ((grep(/^notify$/,@{$changes{'cancreate'}})) && (ref($cancreate{'notify'}) eq 'HASH')) {
                                 if ($cancreate{'notify'}{'approval'}) {                                  if ($cancreate{'notify'}{'approval'}) {
                                     $chgtext .= &mt('Notification of username requests requiring approval will be sent to: ').$cancreate{'notify'}{'approval'};                                      $chgtext = &mt('Notification of username requests requiring approval will be sent to: ').$cancreate{'notify'}{'approval'};
                                     $numapprove ++;  
                                 }                                  }
                             }                              }
                         }                          }
                         unless ($numapprove) {  
                             $chgtext .= &mt('No Domain Coordinators will receive notification of username requests requiring approval.');  
                         }  
                     }                      }
                     if ($chgtext) {                      if ($chgtext) {
                         $resulttext .= '<li>'.$chgtext.'</li>';                          $resulttext .= '<li>'.$chgtext.'</li>';
                     }                      }
                 }                  }
             }              }
             if ((ref($changes{'email_rule'}) eq 'ARRAY') && (@{$changes{'email_rule'}} > 0)) {              if (ref($changes{'email_rule'}) eq 'ARRAY') {
                 my ($emailrules,$emailruleorder) =                  my ($emailrules,$emailruleorder) =
                     &Apache::lonnet::inst_userrules($dom,'email');                      &Apache::lonnet::inst_userrules($dom,'email');
                 foreach my $type (@{$changes{'email_rule'}}) {                  my $chgtext = '<ul>';
                     if (ref($email_rule{$type}) eq 'ARRAY') {                  foreach my $type (@email_rule) {
                         my $chgtext = '<ul>';                      if (ref($emailrules->{$type}) eq 'HASH') {
                         foreach my $rule (@{$email_rule{$type}}) {                          $chgtext .= '<li>'.$emailrules->{$type}{'name'}.'</li>';
                             if (ref($emailrules->{$rule}) eq 'HASH') {  
                                 $chgtext .= '<li>'.$emailrules->{$rule}{'name'}.'</li>';  
                             }  
                         }  
                         $chgtext .= '</ul>';  
                         my $typename;  
                         if (@types) {  
                             if ($type eq 'default') {  
                                 $typename = $othertitle;  
                             } else {  
                                 $typename = $usertypes{$type};  
                             }  
                             $chgtext .= &mt('(Affiliation: [_1])',$typename);  
                         }  
                         if (@{$email_rule{$type}} > 0) {  
                             $resulttext .= '<li>'.  
                                            &mt('Accounts may not be created by users verified by e-mail, for e-mail addresses of the following types: ',  
                                                $usertypes{$type}).  
                                            $chgtext.  
                                            '</li>';  
                         } else {  
                             $resulttext .= '<li>'.  
                                            &mt('There are now no restrictions on e-mail addresses which may be used for verification when a user requests an account.').  
                                            '</li>'.  
                                            &mt('(Affiliation: [_1])',$typename);  
                         }  
                     }                      }
                 }                  }
             }                  $chgtext .= '</ul>';
             if (ref($changes{'inststatus'}) eq 'ARRAY') {                  if (@email_rule > 0) {
                 if (ref($save_inststatus{'inststatusguest'}) eq 'ARRAY') {                      $resulttext .= '<li>'.
                     if (@{$save_inststatus{'inststatusguest'}} > 0) {                                     &mt('Accounts may not be created by users self-enrolling with e-mail addresses of the following types: ').
                         my $chgtext = '<ul>';                                         $chgtext.
                         foreach my $type (@{$save_inststatus{'inststatusguest'}}) {                                     '</li>';
                             $chgtext .= '<li>'.$usertypes{$type}.'</li>';                  } else {
                         }                      $resulttext .= '<li>'.
                         $chgtext .= '</ul>';                                     &mt('There are now no restrictions on e-mail addresses which may be used as a username when self-enrolling.').
                         $resulttext .= '<li>'.                                     '</li>';
                                        &mt('A user will self-report one of the following affiliations when requesting an account verified by e-mail: ').  
                                           $chgtext.  
                                        '</li>';  
                     } else {  
                         $resulttext .= '<li>'.  
                                        &mt('No affiliations available for self-reporting when requesting an account verified by e-mail.').  
                                        '</li>';  
                     }  
                 }                  }
             }              }
             if (ref($changes{'selfcreate'}) eq 'ARRAY') {              if (ref($changes{'selfcreate'}) eq 'ARRAY') {
Line 10937  sub modify_selfcreation { Line 10828  sub modify_selfcreation {
                 my %fieldtitles = &Apache::loncommon::personal_data_fieldtitles();                  my %fieldtitles = &Apache::loncommon::personal_data_fieldtitles();
                 foreach my $type (@{$changes{'selfcreate'}}) {                  foreach my $type (@{$changes{'selfcreate'}}) {
                     my $typename = $type;                      my $typename = $type;
                     if (keys(%usertypes) > 0) {                      if (ref($usertypes) eq 'HASH') {
                         if ($usertypes{$type} ne '') {                          if ($usertypes->{$type} ne '') {
                             $typename = $usertypes{$type};                              $typename = $usertypes->{$type};
                         }                          }
                     }                      }
                     my @modifiable;                      my @modifiable;
Line 10962  sub modify_selfcreation { Line 10853  sub modify_selfcreation {
                 $resulttext .= '</ul></li>';                  $resulttext .= '</ul></li>';
             }              }
             $resulttext .= '</ul>';              $resulttext .= '</ul>';
             my $cachetime = 24*60*60;  
             $domdefaults{'inststatusguest'} = $save_inststatus{'inststatusguest'};  
             &Apache::lonnet::do_cache_new('domdefaults',$dom,\%domdefaults,$cachetime);  
             if (ref($lastactref) eq 'HASH') {  
                 $lastactref->{'domdefaults'} = 1;  
             }  
         } else {          } else {
             $resulttext = &mt('No changes made to self-creation settings');              $resulttext = &mt('No changes made to self-creation settings');
         }          }
Line 11164  sub modify_defaults { Line 11049  sub modify_defaults {
     my ($dom,$lastactref,%domconfig) = @_;      my ($dom,$lastactref,%domconfig) = @_;
     my ($resulttext,$mailmsgtxt,%newvalues,%changes,@errors);      my ($resulttext,$mailmsgtxt,%newvalues,%changes,@errors);
     my %domdefaults = &Apache::lonnet::get_domain_defaults($dom,1);      my %domdefaults = &Apache::lonnet::get_domain_defaults($dom,1);
     my @items = ('auth_def','auth_arg_def','lang_def','timezone_def','datelocale_def',      my @items = ('auth_def','auth_arg_def','lang_def','timezone_def','datelocale_def','portal_def');
                  'portal_def','intauth_cost','intauth_check','intauth_switch');  
     my @authtypes = ('internal','krb4','krb5','localauth');      my @authtypes = ('internal','krb4','krb5','localauth');
     foreach my $item (@items) {      foreach my $item (@items) {
         $newvalues{$item} = $env{'form.'.$item};          $newvalues{$item} = $env{'form.'.$item};
Line 11207  sub modify_defaults { Line 11091  sub modify_defaults {
                     push(@errors,$item);                      push(@errors,$item);
                 }                  }
             }              }
         } elsif ($item eq 'intauth_cost') {  
             if ($newvalues{$item} ne '') {  
                 if ($newvalues{$item} =~ /\D/) {  
                     push(@errors,$item);  
                 }  
             }  
         } elsif ($item eq 'intauth_check') {  
             if ($newvalues{$item} ne '') {  
                 unless ($newvalues{$item} =~ /^(0|1|2)$/) {  
                     push(@errors,$item);  
                 }  
             }  
         } elsif ($item eq 'intauth_switch') {  
             if ($newvalues{$item} ne '') {  
                 unless ($newvalues{$item} =~ /^(0|1|2)$/) {  
                     push(@errors,$item);  
                 }  
             }  
         }          }
         if (grep(/^\Q$item\E$/,@errors)) {          if (grep(/^\Q$item\E$/,@errors)) {
             $newvalues{$item} = $domdefaults{$item};              $newvalues{$item} = $domdefaults{$item};
Line 11251  sub modify_defaults { Line 11117  sub modify_defaults {
     }      }
     my @todelete = &Apache::loncommon::get_env_multiple('form.inststatus_delete');      my @todelete = &Apache::loncommon::get_env_multiple('form.inststatus_delete');
     my @allpos;      my @allpos;
       my %guests;
     my %alltypes;      my %alltypes;
     my @inststatusguest;      my ($currtitles,$currguests,$currorder);
     if (ref($currinststatus) eq 'HASH') {  
         if (ref($currinststatus->{'inststatusguest'}) eq 'ARRAY') {  
             foreach my $type (@{$currinststatus->{'inststatusguest'}}) {  
                 unless (grep(/^\Q$type\E$/,@todelete)) {  
                     push(@inststatusguest,$type);  
                 }  
             }  
         }  
     }  
     my ($currtitles,$currorder);  
     if (ref($currinststatus) eq 'HASH') {      if (ref($currinststatus) eq 'HASH') {
         if (ref($currinststatus->{'inststatusorder'}) eq 'ARRAY') {          if (ref($currinststatus->{'inststatusorder'}) eq 'ARRAY') {
             foreach my $type (@{$currinststatus->{'inststatusorder'}}) {              foreach my $type (@{$currinststatus->{'inststatusorder'}}) {
Line 11277  sub modify_defaults { Line 11134  sub modify_defaults {
                     $allpos[$position] = $type;                      $allpos[$position] = $type;
                     $alltypes{$type} = $env{'form.inststatus_title_'.$type};                      $alltypes{$type} = $env{'form.inststatus_title_'.$type};
                     $alltypes{$type} =~ s/`//g;                      $alltypes{$type} =~ s/`//g;
                       if ($env{'form.inststatus_guest_'.$type}) {
                           $guests{$type} = 1;
                       }
                 }                  }
             }              }
               if (ref($currinststatus->{'inststatusguest'}) eq 'ARRAY') {
                   $currguests = join(',',@{$currinststatus->{'inststatusguest'}});
               }
             $currorder = join(',',@{$currinststatus->{'inststatusorder'}});              $currorder = join(',',@{$currinststatus->{'inststatusorder'}});
             $currtitles =~ s/,$//;              $currtitles =~ s/,$//;
         }          }
Line 11287  sub modify_defaults { Line 11150  sub modify_defaults {
         my $newtype = $env{'form.addinststatus'};          my $newtype = $env{'form.addinststatus'};
         $newtype =~ s/\W//g;          $newtype =~ s/\W//g;
         unless (exists($alltypes{$newtype})) {          unless (exists($alltypes{$newtype})) {
               if ($env{'form.addinststatus_guest'}) {
                   $guests{$newtype} = 1;
               }
             $alltypes{$newtype} = $env{'form.addinststatus_title'};              $alltypes{$newtype} = $env{'form.addinststatus_title'};
             $alltypes{$newtype} =~ s/`//g;               $alltypes{$newtype} =~ s/`//g; 
             my $position = $env{'form.addinststatus_pos'};              my $position = $env{'form.addinststatus_pos'};
Line 11296  sub modify_defaults { Line 11162  sub modify_defaults {
             }              }
         }          }
     }      }
     my @orderedstatus;      my (@orderedstatus,@orderedguests);
     foreach my $type (@allpos) {      foreach my $type (@allpos) {
         unless (($type eq '') || (grep(/^\Q$type\E$/,@orderedstatus))) {          unless (($type eq '') || (grep(/^\Q$type\E$/,@orderedstatus))) {
             push(@orderedstatus,$type);              push(@orderedstatus,$type);
               if ($guests{$type}) {
                   push(@orderedguests,$type);
               }
         }          }
     }      }
     foreach my $type (keys(%alltypes)) {      foreach my $type (keys(%alltypes)) {
Line 11310  sub modify_defaults { Line 11179  sub modify_defaults {
     $defaults_hash{'inststatus'} = {      $defaults_hash{'inststatus'} = {
                                      inststatustypes => \%alltypes,                                       inststatustypes => \%alltypes,
                                      inststatusorder => \@orderedstatus,                                       inststatusorder => \@orderedstatus,
                                      inststatusguest => \@inststatusguest,                                       inststatusguest => \@orderedguests,
                                    };                                     };
     if (ref($defaults_hash{'inststatus'}) eq 'HASH') {      if (ref($defaults_hash{'inststatus'}) eq 'HASH') {
         foreach my $item ('inststatustypes','inststatusorder','inststatusguest') {          foreach my $item ('inststatustypes','inststatusorder','inststatusguest') {
Line 11320  sub modify_defaults { Line 11189  sub modify_defaults {
     if ($currorder ne join(',',@orderedstatus)) {      if ($currorder ne join(',',@orderedstatus)) {
         $changes{'inststatus'}{'inststatusorder'} = 1;          $changes{'inststatus'}{'inststatusorder'} = 1;
     }      }
       if ($currguests ne join(',',@orderedguests)) {
           $changes{'inststatus'}{'inststatusguest'} = 1;
       }
     my $newtitles;      my $newtitles;
     foreach my $item (@orderedstatus) {      foreach my $item (@orderedstatus) {
         $newtitles .= $alltypes{$item}.',';          $newtitles .= $alltypes{$item}.',';
Line 11338  sub modify_defaults { Line 11210  sub modify_defaults {
             foreach my $item (sort(keys(%changes))) {              foreach my $item (sort(keys(%changes))) {
                 if ($item eq 'inststatus') {                  if ($item eq 'inststatus') {
                     if (ref($changes{'inststatus'}) eq 'HASH') {                      if (ref($changes{'inststatus'}) eq 'HASH') {
                         if (@orderedstatus) {                          if (($changes{'inststatus'}{'inststatustypes'}) || $changes{'inststatus'}{'inststatusorder'}) {
                             $resulttext .= '<li>'.&mt('Institutional user status types set to:').' ';                              $resulttext .= '<li>'.&mt('Institutional user status types set to:').' ';
                             foreach my $type (@orderedstatus) {                               foreach my $type (@orderedstatus) { 
                                 $resulttext .= $alltypes{$type}.', ';                                  $resulttext .= $alltypes{$type}.', ';
                             }                              }
                             $resulttext =~ s/, $//;                              $resulttext =~ s/, $//;
                             $resulttext .= '</li>';                              $resulttext .= '</li>';
                         } else {                          }
                             $resulttext .= '<li>'.&mt('Institutional user status types deleted').'</li>';                          if ($changes{'inststatus'}{'inststatusguest'}) {
                               $resulttext .= '<li>'; 
                               if (@orderedguests) {
                                   $resulttext .= &mt('Types assignable to "non-institutional" usernames set to:').' ';
                                   foreach my $type (@orderedguests) {
                                       $resulttext .= $alltypes{$type}.', ';
                                   }
                                   $resulttext =~ s/, $//;
                               } else {
                                   $resulttext .= &mt('Types assignable to "non-institutional" usernames set to none.');
                               }
                               $resulttext .= '</li>';
                         }                          }
                     }                      }
                 } else {                  } else {
Line 11362  sub modify_defaults { Line 11245  sub modify_defaults {
                                           localauth  => 'loc',                                            localauth  => 'loc',
                         );                          );
                         $value = $authnames{$shortauth{$value}};                          $value = $authnames{$shortauth{$value}};
                     } elsif ($item eq 'intauth_switch') {  
                         my %optiondesc = &Apache::lonlocal::texthash (  
                                             0 => 'No',  
                                             1 => 'Yes',  
                                             2 => 'Yes, and copy existing passwd file to passwd.bak file',  
                                          );  
                         if ($value =~ /^(0|1|2)$/) {  
                             $value = $optiondesc{$value};  
                         } else {  
                             $value = &mt('none -- defaults to No');  
                         }  
                     } elsif ($item eq 'intauth_check') {  
                         my %optiondesc = &Apache::lonlocal::texthash (  
                                              0 => 'No',  
                                              1 => 'Yes, allow login then update passwd file using default cost (if higher)',  
                                              2 => 'Yes, disallow login if stored cost is less than domain default',  
                                          );  
                         if ($value =~ /^(0|1|2)$/) {  
                             $value = $optiondesc{$value};  
                         } else {  
                             $value = &mt('none -- defaults to No');  
                         }  
                     }                      }
                     $resulttext .= '<li>'.&mt('[_1] set to "[_2]"',$title->{$item},$value).'</li>';                      $resulttext .= '<li>'.&mt('[_1] set to "[_2]"',$title->{$item},$value).'</li>';
                     $mailmsgtext .= "$title->{$item} set to $value\n";                        $mailmsgtext .= "$title->{$item} set to $value\n";  
Line 11532  sub modify_coursecategories { Line 11393  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 11546  sub modify_coursecategories { Line 11416  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 11568  sub modify_coursecategories { Line 11442  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 11630  sub modify_coursecategories { Line 11507  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 11899  sub modify_serverstatuses { Line 11790  sub modify_serverstatuses {
 }  }
   
 sub modify_helpsettings {  sub modify_helpsettings {
     my ($r,$dom,$confname,$lastactref,%domconfig) = @_;      my ($r,$dom,$confname,%domconfig) = @_;
     my ($resulttext,$errors,%changes,%helphash);      my ($resulttext,$errors,%changes,%helphash);
     my %defaultchecked = ('submitbugs' => 'on');      my %defaultchecked = ('submitbugs' => 'on');
     my @offon = ('off','on');      my @offon = ('off','on');
     my @toggles = ('submitbugs');      my @toggles = ('submitbugs');
     my %current = ('submitbugs' => '',      my %current = ('submitbugs' => '');  
                    'adhoc'      => {},  
                   );  
     if (ref($domconfig{'helpsettings'}) eq 'HASH') {      if (ref($domconfig{'helpsettings'}) eq 'HASH') {
         %current = %{$domconfig{'helpsettings'}};          %current = %{$domconfig{'helpsettings'}};
     }      }
     my %domdefaults = &Apache::lonnet::get_domain_defaults($dom,1);  
     foreach my $item (@toggles) {      foreach my $item (@toggles) {
         if ($defaultchecked{$item} eq 'on') {           if ($defaultchecked{$item} eq 'on') { 
             if ($current{$item} eq '') {              if ($current{$item} eq '') {
Line 11933  sub modify_helpsettings { Line 11821  sub modify_helpsettings {
             $helphash{'helpsettings'}{$item} = $env{'form.'.$item};              $helphash{'helpsettings'}{$item} = $env{'form.'.$item};
         }          }
     }      }
     my $maxnum = $env{'form.helproles_maxnum'};  
       my @modify = &Apache::loncommon::get_env_multiple('form.modifycusthelp');
     my $confname = $dom.'-domainconfig';      my $confname = $dom.'-domainconfig';
     my %existing=&Apache::lonnet::dump('roles',$dom,$confname,'rolesdef_');      my %existing=&Apache::lonnet::dump('roles',$dom,$confname,'rolesdef_');
     my (@allpos,%newsettings,%changedprivs,$newrole);      if (@modify) {
     my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom);          foreach my $num (@modify) {
     my @accesstypes = ('all','dh','da','none','status','inc','exc');              my $rolename = $env{'form.custhelprole'.$num};
     my %domhelpdesk = &Apache::lonnet::get_active_domroles($dom,['dh','da']);              if ($rolename ne '') {
     my %lt = &Apache::lonlocal::texthash(                  if (exists($existing{'rolesdef_'.$rolename})) {
                     s      => 'system',                      my $prefix = 'custhelp'.$num;
                     d      => 'domain',                      my %newprivs = &Apache::lonuserutils::custom_role_update($rolename,$prefix);
                     order  => 'Display order',                      my %currprivs;
                     access => 'Role usage',                      ($currprivs{'s'},$currprivs{'d'},$currprivs{'c'}) = 
                     all    => 'All with domain helpdesk or helpdesk assistant role',                          split(/\_/,$existing{'rolesdef_'.$rolename});
                     dh     => 'All with domain helpdesk role',                      foreach my $level ('c','d','s') {
                     da     => 'All with domain helpdesk assistant role',                          if ($newprivs{$level} ne $currprivs{$level}) {
                     none   => 'None',                              $changes{'customrole'}{$rolename} = 1;
                     status => 'Determined based on institutional status',                              my $result = &Apache::lonnet::definerole($rolename,$newprivs{'s'},$newprivs{'d'},
                     inc    => 'Include all, but exclude specific personnel',                                                                       $newprivs{'c'},$confname,$dom);
                     exc    => 'Exclude all, but include specific personnel',                              last;
     );  
     for (my $num=0; $num<=$maxnum; $num++) {  
         my ($prefix,$identifier,$rolename,%curr);  
         if ($num == $maxnum) {  
             next unless ($env{'form.newcusthelp'} == $maxnum);  
             $identifier = 'custhelp'.$num;  
             $prefix = 'helproles_'.$num;  
             $rolename = $env{'form.custhelpname'.$num};  
             $rolename=~s/[^A-Za-z0-9]//gs;  
             next if ($rolename eq '');  
             next if (exists($existing{'rolesdef_'.$rolename}));  
             my %newprivs = &Apache::lonuserutils::custom_role_update($rolename,$identifier);  
             my $result = &Apache::lonnet::definerole($rolename,$newprivs{'s'},$newprivs{'d'},  
                                                      $newprivs{'c'},$confname,$dom);  
             if ($result ne 'ok') {  
                 $errors .= '<li><span class="LC_error">'.  
                            &mt('An error occurred storing the new custom role: [_1]',  
                            $result).'</span></li>';  
                 next;  
             } else {  
                 $changedprivs{$rolename} = \%newprivs;  
                 $newrole = $rolename;  
             }  
         } else {  
             $prefix = 'helproles_'.$num;  
             $rolename = $env{'form.'.$prefix};  
             next if ($rolename eq '');  
             next unless (exists($existing{'rolesdef_'.$rolename}));  
             $identifier = 'custhelp'.$num;  
             my %newprivs = &Apache::lonuserutils::custom_role_update($rolename,$identifier);  
             my %currprivs;  
             ($currprivs{'s'},$currprivs{'d'},$currprivs{'c'}) =  
                 split(/\_/,$existing{'rolesdef_'.$rolename});  
             foreach my $level ('c','d','s') {  
                 if ($newprivs{$level} ne $currprivs{$level}) {  
                     my $result = &Apache::lonnet::definerole($rolename,$newprivs{'s'},$newprivs{'d'},  
                                                              $newprivs{'c'},$confname,$dom);  
                     if ($result ne 'ok') {  
                         $errors .= '<li><span class="LC_error">'.  
                                    &mt('An error occurred storing privileges for existing role [_1]: [_2]',  
                                        $rolename,$result).'</span></li>';  
                     } else {  
                         $changedprivs{$rolename} = \%newprivs;  
                     }  
                     last;  
                 }  
             }  
             if (ref($current{'adhoc'}) eq 'HASH') {  
                 if (ref($current{'adhoc'}{$rolename}) eq 'HASH') {  
                     %curr = %{$current{'adhoc'}{$rolename}};  
                 }  
             }  
         }  
         my $newpos = $env{'form.'.$prefix.'_pos'};  
         $newpos =~ s/\D+//g;  
         $allpos[$newpos] = $rolename;  
         my $newdesc = $env{'form.'.$prefix.'_desc'};  
         $helphash{'helpsettings'}{'adhoc'}{$rolename}{'desc'} = $newdesc;  
         if ($curr{'desc'}) {  
             if ($curr{'desc'} ne $newdesc) {  
                 $changes{'customrole'}{$rolename}{'desc'} = 1;  
                 $newsettings{$rolename}{'desc'} = $newdesc;  
             }  
         } elsif ($newdesc ne '') {  
             $changes{'customrole'}{$rolename}{'desc'} = 1;  
             $newsettings{$rolename}{'desc'} = $newdesc;  
         }  
         my $access = $env{'form.'.$prefix.'_access'};  
         if (grep(/^\Q$access\E$/,@accesstypes)) {  
             $helphash{'helpsettings'}{'adhoc'}{$rolename}{'access'} = $access;  
             if ($access eq 'status') {  
                 my @statuses = &Apache::loncommon::get_env_multiple('form.'.$prefix.'_status');  
                 if (scalar(@statuses) == 0) {  
                     $helphash{'helpsettings'}{'adhoc'}{$rolename}{'access'} = 'none';  
                 } else {  
                     my (@shownstatus,$numtypes);  
                     $helphash{'helpsettings'}{'adhoc'}{$rolename}{$access} = [];  
                     if (ref($types) eq 'ARRAY') {  
                         $numtypes = scalar(@{$types});  
                         foreach my $type (sort(@statuses)) {  
                             if ($type eq 'default') {  
                                 push(@{$helphash{'helpsettings'}{'adhoc'}{$rolename}{$access}},$type);  
                             } elsif (grep(/^\Q$type\E$/,@{$types})) {  
                                 push(@{$helphash{'helpsettings'}{'adhoc'}{$rolename}{$access}},$type);  
                                 push(@shownstatus,$usertypes->{$type});  
                             }  
                         }  
                     }  
                     if (grep(/^default$/,@statuses)) {  
                         push(@shownstatus,$othertitle);  
                     }  
                     if (scalar(@shownstatus) == 1+$numtypes) {  
                         $helphash{'helpsettings'}{'adhoc'}{$rolename}{'access'} = 'all';  
                         delete($helphash{'helpsettings'}{'adhoc'}{$rolename}{'status'});  
                     } else {  
                         $newsettings{$rolename}{'status'} = join(' '.&mt('or').' ',@shownstatus);  
                         if (ref($curr{'status'}) eq 'ARRAY') {  
                             my @diffs = &Apache::loncommon::compare_arrays($helphash{'helpsettings'}{'adhoc'}{$rolename}{$access},$curr{$access});  
                             if (@diffs) {  
                                 $changes{'customrole'}{$rolename}{$access} = 1;  
                             }  
                         } elsif (@{$helphash{'helpsettings'}{'adhoc'}{$rolename}{$access}}) {  
                             $changes{'customrole'}{$rolename}{$access} = 1;  
                         }                          }
                     }                      }
                 }                  }
             } elsif (($access eq 'inc') || ($access eq 'exc')) {  
                 my @personnel = &Apache::loncommon::get_env_multiple('form.'.$prefix.'_staff_'.$access);  
                 my @newspecstaff;  
                 $helphash{'helpsettings'}{'adhoc'}{$rolename}{$access} = [];  
                 foreach my $person (sort(@personnel)) {  
                     if ($domhelpdesk{$person}) {  
                         push(@{$helphash{'helpsettings'}{'adhoc'}{$rolename}{$access}},$person);  
                     }  
                 }  
                 if (ref($curr{$access}) eq 'ARRAY') {  
                     my @diffs = &Apache::loncommon::compare_arrays($helphash{'helpsettings'}{'adhoc'}{$rolename}{$access},$curr{$access});  
                     if (@diffs) {  
                         $changes{'customrole'}{$rolename}{$access} = 1;  
                     }  
                 } elsif (@{$helphash{'helpsettings'}{'adhoc'}{$rolename}{$access}}) {  
                     $changes{'customrole'}{$rolename}{$access} = 1;  
                 }  
                 foreach my $person (@{$helphash{'helpsettings'}{'adhoc'}{$rolename}{$access}}) {  
                     my ($uname,$udom) = split(/:/,$person);  
                         push(@newspecstaff,&Apache::loncommon::aboutmewrapper(&Apache::loncommon::plainname($uname,$udom,'lastname'),$uname,$udom));  
                 }  
                 $newsettings{$rolename}{$access} = join(', ',sort(@newspecstaff));  
             }              }
         } else {  
             $helphash{'helpsettings'}{'adhoc'}{$rolename}{'access'}= 'all';  
         }  
         unless ($curr{'access'} eq $access) {  
             $changes{'customrole'}{$rolename}{'access'} = 1;  
             $newsettings{$rolename}{'access'} = $lt{$helphash{'helpsettings'}{'adhoc'}{$rolename}{'access'}};  
         }          }
     }      }
     if (@allpos > 0) {      if ($env{'form.newcusthelp'} ne '') {
         my $idx = 0;          my $prefix = 'custhelp'.$env{'form.newcusthelp'};
         foreach my $rolename (@allpos) {          my $rolename = $env{'form.newcusthelpname'};
             if ($rolename ne '') {          $rolename=~s/[^A-Za-z0-9]//gs;
                 $helphash{'helpsettings'}{'adhoc'}{$rolename}{'order'} = $idx;          if ($rolename ne '') {
                 if (ref($current{'adhoc'}) eq 'HASH') {              unless(exists($existing{'rolesdef_'.$rolename})) {
                     if (ref($current{'adhoc'}{$rolename}) eq 'HASH') {                  my $errmsg;
                         if ($current{'adhoc'}{$rolename}{'order'} ne $idx) {                  my $result = &Apache::lonuserutils::store_custom_role($rolename,$prefix,
                             $changes{'customrole'}{$rolename}{'order'} = 1;                                                                        $confname,$dom);
                             $newsettings{$rolename}{'order'} = $idx+1;                  if ($result eq 'ok') {
                         }                      $changes{'newcustomrole'} = $rolename;
                     }                  } else {
                       $errmsg = ': '.$result;
                 }                  }
                 $idx ++;  
             }              }
         }          }
     }      }
   
     my $putresult;      my $putresult;
     if (keys(%changes) > 0) {      if (keys(%changes) > 0) {
         $putresult = &Apache::lonnet::put_dom('configuration',\%helphash,$dom);          $putresult = &Apache::lonnet::put_dom('configuration',\%helphash,$dom);
         if ($putresult eq 'ok') {          if ($putresult eq 'ok') {
             if (ref($helphash{'helpsettings'}) eq 'HASH') {              $resulttext = &mt('Changes made:').'<ul>';
                 $domdefaults{'submitbugs'} = $helphash{'helpsettings'}{'submitbugs'};  
                 if (ref($helphash{'helpsettings'}{'adhoc'}) eq 'HASH') {  
                     $domdefaults{'adhocroles'} = $helphash{'helpsettings'}{'adhoc'};  
                 }  
             }  
             my $cachetime = 24*60*60;  
             &Apache::lonnet::do_cache_new('domdefaults',$dom,\%domdefaults,$cachetime);  
             if (ref($lastactref) eq 'HASH') {  
                 $lastactref->{'domdefaults'} = 1;  
             }  
         } else {  
             $errors .= '<li><span class="LC_error">'.  
                        &mt('An error occurred storing the settings: [_1]',  
                            $putresult).'</span></li>';  
         }  
     }  
     if ((keys(%changes) && ($putresult eq 'ok')) || (keys(%changedprivs))) {  
         $resulttext = &mt('Changes made:').'<ul>';  
         my (%shownprivs,@levelorder);  
         @levelorder = ('c','d','s');  
         if ((keys(%changes)) && ($putresult eq 'ok')) {  
             foreach my $item (sort(keys(%changes))) {              foreach my $item (sort(keys(%changes))) {
                 if ($item eq 'submitbugs') {                  if ($item eq 'submitbugs') {
                     $resulttext .= '<li>'.&mt('Display link to: [_1] set to "'.$offon[$env{'form.'.$item}].'".',                      $resulttext .= '<li>'.&mt('Display link to: [_1] set to "'.$offon[$env{'form.'.$item}].'".',
Line 12139  sub modify_helpsettings { Line 11877  sub modify_helpsettings {
                                               &mt('LON-CAPA bug tracker'),600,500)).'</li>';                                                &mt('LON-CAPA bug tracker'),600,500)).'</li>';
                 } elsif ($item eq 'customrole') {                  } elsif ($item eq 'customrole') {
                     if (ref($changes{'customrole'}) eq 'HASH') {                      if (ref($changes{'customrole'}) eq 'HASH') {
                         my @keyorder = ('order','desc','access','status','exc','inc');  
                         my %keytext = &Apache::lonlocal::texthash(  
                                                                    order  => 'Order',  
                                                                    desc   => 'Role description',  
                                                                    access => 'Role usage',  
                                                                    status => 'Allowed institutional types',  
                                                                    exc    => 'Allowed personnel',  
                                                                    inc    => 'Disallowed personnel',  
                         );  
                         foreach my $role (sort(keys(%{$changes{'customrole'}}))) {                          foreach my $role (sort(keys(%{$changes{'customrole'}}))) {
                             if (ref($changes{'customrole'}{$role}) eq 'HASH') {                              $resulttext .= '<li>'.&mt('Existing custom role modified: [_1]',
                                 if ($role eq $newrole) {                                                       $role).'</li>';
                                     $resulttext .= '<li>'.&mt('New custom role added: [_1]',  
                                                               $role).'<ul>';  
                                 } else {  
                                     $resulttext .= '<li>'.&mt('Existing custom role modified: [_1]',  
                                                               $role).'<ul>';  
                                 }  
                                 foreach my $key (@keyorder) {  
                                     if ($changes{'customrole'}{$role}{$key}) {  
                                         $resulttext .= '<li>'.&mt("[_1] set to: [_2]",  
                                                                   $keytext{$key},$newsettings{$role}{$key}).  
                                                        '</li>';  
                                     }  
                                 }  
                                 if (ref($changedprivs{$role}) eq 'HASH') {  
                                     $shownprivs{$role} = 1;  
                                     $resulttext .= '<li>'.&mt('Privileges set to :').'<ul>';  
                                     foreach my $level (@levelorder) {  
                                         foreach my $item (split(/\:/,$changedprivs{$role}{$level})) {  
                                             next if ($item eq '');  
                                             my ($priv) = split(/\&/,$item,2);  
                                             if (&Apache::lonnet::plaintext($priv)) {  
                                                 $resulttext .= '<li>'.&Apache::lonnet::plaintext($priv);  
                                                 unless ($level eq 'c') {  
                                                     $resulttext .= ' ('.$lt{$level}.')';  
                                                 }  
                                                 $resulttext .= '</li>';  
                                             }  
                                         }  
                                     }  
                                     $resulttext .= '</ul>';  
                                 }  
                                 $resulttext .= '</ul></li>';  
                             }  
                         }  
                     }  
                 }  
             }  
         }  
         if (keys(%changedprivs)) {  
             foreach my $role (sort(keys(%changedprivs))) {  
                 unless ($shownprivs{$role}) {  
                     $resulttext .= '<li>'.&mt('Existing custom role modified: [_1]',  
                                               $role).'<ul>'.  
                                    '<li>'.&mt('Privileges set to :').'<ul>';  
                     foreach my $level (@levelorder) {  
                         foreach my $item (split(/\:/,$changedprivs{$role}{$level})) {  
                             next if ($item eq '');  
                             my ($priv) = split(/\&/,$item,2);  
                             if (&Apache::lonnet::plaintext($priv)) {  
                                 $resulttext .= '<li>'.&Apache::lonnet::plaintext($priv);  
                                 unless ($level eq 'c') {  
                                     $resulttext .= ' ('.$lt{$level}.')';  
                                 }  
                                 $resulttext .= '</li>';  
                             }  
                         }                          }
                     }                      }
                     $resulttext .= '</ul></li></ul></li>';                  } elsif ($item eq 'newcustomrole') {
                       $resulttext .= '<li>'.&mt('New custom role added: [_1]',
                                                 $changes{'newcustomrole'}).'</li>';
                 }                  }
             }              }
               $resulttext .= '</ul>';
           } else {
               $resulttext = &mt('No changes made to help settings');
               $errors .= '<li><span class="LC_error">'.
                          &mt('An error occurred storing the settings: [_1]',
                              $putresult).'</span></li>';
         }          }
         $resulttext .= '</ul>';  
     } else {  
         $resulttext = &mt('No changes made to help settings');  
     }      }
     if ($errors) {      if ($errors) {
         $resulttext .= '<br />'.&mt('The following errors occurred: ').'<ul>'.          $resulttext .= '<br />'.&mt('The following errors occurred: ').'<ul>'.
                                     $errors.'</ul>';                         $errors.'</ul>';
     }      }
     return $resulttext;      return $resulttext;
 }  }
Line 12227  sub modify_coursedefaults { Line 11906  sub modify_coursedefaults {
     my ($dom,$lastactref,%domconfig) = @_;      my ($dom,$lastactref,%domconfig) = @_;
     my ($resulttext,$errors,%changes,%defaultshash);      my ($resulttext,$errors,%changes,%defaultshash);
     my %defaultchecked = (      my %defaultchecked = (
                              'canuse_pdfforms' => 'off',
                            'uselcmath'       => 'on',                             'uselcmath'       => 'on',
                            'usejsme'         => 'on'                             'usejsme'         => 'on'
                          );                           );
     my @toggles = ('uselcmath','usejsme');      my @toggles = ('canuse_pdfforms','uselcmath','usejsme');
     my @numbers = ('anonsurvey_threshold','uploadquota_official','uploadquota_unofficial',      my @numbers = ('anonsurvey_threshold','uploadquota_official','uploadquota_unofficial',
                    'uploadquota_community','uploadquota_textbook','mysqltables_official',                     'uploadquota_community','uploadquota_textbook','uploadquota_placement',
                    'mysqltables_unofficial','mysqltables_community','mysqltables_textbook');                     'mysqltables_official','mysqltables_unofficial','mysqltables_community',
     my @types = ('official','unofficial','community','textbook');                     'mysqltables_textbook','mysqltables_placement');
       my @types = ('official','unofficial','community','textbook','placement');
     my %staticdefaults = (      my %staticdefaults = (
                            anonsurvey_threshold => 10,                             anonsurvey_threshold => 10,
                            uploadquota          => 500,                             uploadquota          => 500,
Line 12294  sub modify_coursedefaults { Line 11975  sub modify_coursedefaults {
                         $changes{$item} = 1;                          $changes{$item} = 1;
                     }                      }
                 } elsif ($item =~ /^(uploadquota|mysqltables)_/) {                  } elsif ($item =~ /^(uploadquota|mysqltables)_/) {
                     my $setting = $1;                      my $setting = $1; 
                     unless (($currdef eq '') && ($newdef == $staticdefaults{$setting})) {                      unless (($currdef eq '') && ($newdef == $staticdefaults{$setting})) {
                         $changes{$setting} = 1;                          $changes{$setting} = 1;
                     }                      }
Line 12309  sub modify_coursedefaults { Line 11990  sub modify_coursedefaults {
             }              }
         }          }
         my $newclone;          my $newclone;
         if ($env{'form.canclone'} =~ /^(none|domain|instcode)$/) {          if ($env{'form.canclone'} =~ /^(none|domain|instcode)$/) { 
             $newclone = $env{'form.canclone'};              $newclone = $env{'form.canclone'};
         }          }
         if ($newclone eq 'instcode') {          if ($newclone eq 'instcode') {
Line 12332  sub modify_coursedefaults { Line 12013  sub modify_coursedefaults {
                 $newclone eq '';                  $newclone eq '';
             }              }
         } elsif ($newclone ne '') {          } elsif ($newclone ne '') {
             $defaultshash{'coursedefaults'}{'canclone'} = $newclone;              $defaultshash{'coursedefaults'}{'canclone'} = $newclone; 
         }          } 
         if ($newclone ne $currclone) {          if ($newclone ne $currclone) {
             $changes{'canclone'} = 1;              $changes{'canclone'} = 1;
         }          }
Line 12351  sub modify_coursedefaults { Line 12032  sub modify_coursedefaults {
                 $defaultshash{'coursedefaults'}{'coursecredits'}{$type} = $credits{$type};                  $defaultshash{'coursedefaults'}{'coursecredits'}{$type} = $credits{$type};
             }              }
         } else {          } else {
             if ($env{'form.coursecredits'} eq '1') {              if ($env{'form.coursecredits'} eq '1') { 
                 foreach my $type (@types) {                  foreach my $type (@types) {
                     unless ($type eq 'community') {                      unless ($type eq 'community') {
                         if ($domconfig{'coursedefaults'}{'coursecredits'}{$type} ne $credits{$type}) {                          if ($domconfig{'coursedefaults'}{'coursecredits'}{$type} ne $credits{$type}) {        
                             $changes{'coursecredits'} = 1;                              $changes{'coursecredits'} = 1;
                         }                          }
                         $defaultshash{'coursedefaults'}{'coursecredits'}{$type} = $credits{$type};                          $defaultshash{'coursedefaults'}{'coursecredits'}{$type} = $credits{$type};
Line 12397  sub modify_coursedefaults { Line 12078  sub modify_coursedefaults {
                 }                  }
                 if (exists($currtimeout{$type})) {                  if (exists($currtimeout{$type})) {
                     if ($timeout ne $currtimeout{$type}) {                      if ($timeout ne $currtimeout{$type}) {
                         $changes{'postsubmit'} = 1;                          $changes{'postsubmit'} = 1; 
                     }                      }
                 } elsif ($timeout ne '') {                  } elsif ($timeout ne '') {
                     $changes{'postsubmit'} = 1;                      $changes{'postsubmit'} = 1;
Line 12419  sub modify_coursedefaults { Line 12100  sub modify_coursedefaults {
     if ($putresult eq 'ok') {      if ($putresult eq 'ok') {
         if (keys(%changes) > 0) {          if (keys(%changes) > 0) {
             my %domdefaults = &Apache::lonnet::get_domain_defaults($dom,1);              my %domdefaults = &Apache::lonnet::get_domain_defaults($dom,1);
             if (($changes{'uploadquota'}) || ($changes{'postsubmit'}) ||              if (($changes{'canuse_pdfforms'}) || ($changes{'uploadquota'}) || ($changes{'postsubmit'}) ||
                 ($changes{'coursecredits'}) || ($changes{'uselcmath'}) || ($changes{'usejsme'}) ||                  ($changes{'coursecredits'}) || ($changes{'uselcmath'}) || ($changes{'usejsme'}) ||
                 ($changes{'canclone'}) || ($changes{'mysqltables'})) {                  ($changes{'canclone'}) || ($changes{'mysqltables'})) {
                 foreach my $item ('uselcmath','usejsme') {                  foreach my $item ('canuse_pdfforms','uselcmath','usejsme') { 
                     if ($changes{$item}) {                      if ($changes{$item}) {
                         $domdefaults{$item}=$defaultshash{'coursedefaults'}{$item};                          $domdefaults{$item}=$defaultshash{'coursedefaults'}{$item};
                     }                      }
                 }                  } 
                 if ($changes{'coursecredits'}) {                  if ($changes{'coursecredits'}) {
                     if (ref($defaultshash{'coursedefaults'}{'coursecredits'}) eq 'HASH') {                      if (ref($defaultshash{'coursedefaults'}{'coursecredits'}) eq 'HASH') {
                         foreach my $type (keys(%{$defaultshash{'coursedefaults'}{'coursecredits'}})) {                          foreach my $type (keys(%{$defaultshash{'coursedefaults'}{'coursecredits'}})) {
Line 12473  sub modify_coursedefaults { Line 12154  sub modify_coursedefaults {
             }              }
             $resulttext = &mt('Changes made:').'<ul>';              $resulttext = &mt('Changes made:').'<ul>';
             foreach my $item (sort(keys(%changes))) {              foreach my $item (sort(keys(%changes))) {
                 if ($item eq 'uselcmath') {                  if ($item eq 'canuse_pdfforms') {
                       if ($env{'form.'.$item} eq '1') {
                           $resulttext .= '<li>'.&mt("Course/Community users can create/upload PDF forms set to 'on'").'</li>';
                       } else {
                           $resulttext .= '<li>'.&mt('Course/Community users can create/upload PDF forms set to "off"').'</li>';
                       }
                   } elsif ($item eq 'uselcmath') {
                     if ($env{'form.'.$item} eq '1') {                      if ($env{'form.'.$item} eq '1') {
                         $resulttext .= '<li>'.&mt('Math preview uses LON-CAPA previewer (javascript), if supported by browser.').'</li>';                          $resulttext .= '<li>'.&mt('Math preview uses LON-CAPA previewer (javascript), if supported by browser.').'</li>';
                     } else {                      } else {
Line 12483  sub modify_coursedefaults { Line 12170  sub modify_coursedefaults {
                     if ($env{'form.'.$item} eq '1') {                      if ($env{'form.'.$item} eq '1') {
                         $resulttext .= '<li>'.&mt('Molecule editor uses JSME (HTML5), if supported by browser.').'</li>';                          $resulttext .= '<li>'.&mt('Molecule editor uses JSME (HTML5), if supported by browser.').'</li>';
                     } else {                      } else {
                         $resulttext .= '<li>'.&mt('Molecule editor uses JME (Java), if supported by client OS.').'</li>';                          $resulttext .= '<li>'.&mt('Molecule editor uses JME (Java), if supported by client OS.').'</li>'; 
                     }                      }
                 } elsif ($item eq 'anonsurvey_threshold') {                  } elsif ($item eq 'anonsurvey_threshold') {
                     $resulttext .= '<li>'.&mt('Responder count required for display of anonymous survey submissions set to [_1].',$defaultshash{'coursedefaults'}{'anonsurvey_threshold'}).'</li>';                      $resulttext .= '<li>'.&mt('Responder count required for display of anonymous survey submissions set to [_1].',$defaultshash{'coursedefaults'}{'anonsurvey_threshold'}).'</li>';
Line 12493  sub modify_coursedefaults { Line 12180  sub modify_coursedefaults {
                                        '<li>'.&mt('Official courses: [_1] MB','<b>'.$defaultshash{'coursedefaults'}{'uploadquota'}{'official'}.'</b>').'</li>'.                                         '<li>'.&mt('Official courses: [_1] MB','<b>'.$defaultshash{'coursedefaults'}{'uploadquota'}{'official'}.'</b>').'</li>'.
                                        '<li>'.&mt('Unofficial courses: [_1] MB','<b>'.$defaultshash{'coursedefaults'}{'uploadquota'}{'unofficial'}.'</b>').'</li>'.                                         '<li>'.&mt('Unofficial courses: [_1] MB','<b>'.$defaultshash{'coursedefaults'}{'uploadquota'}{'unofficial'}.'</b>').'</li>'.
                                        '<li>'.&mt('Textbook courses: [_1] MB','<b>'.$defaultshash{'coursedefaults'}{'uploadquota'}{'textbook'}.'</b>').'</li>'.                                         '<li>'.&mt('Textbook courses: [_1] MB','<b>'.$defaultshash{'coursedefaults'}{'uploadquota'}{'textbook'}.'</b>').'</li>'.
                                          '<li>'.&mt('Placement tests: [_1] MB','<b>'.$defaultshash{'coursedefaults'}{'uploadquota'}{'placement'}.'</b>').'</li>'. 
                                        '<li>'.&mt('Communities: [_1] MB','<b>'.$defaultshash{'coursedefaults'}{'uploadquota'}{'community'}.'</b>').'</li>'.                                         '<li>'.&mt('Communities: [_1] MB','<b>'.$defaultshash{'coursedefaults'}{'uploadquota'}{'community'}.'</b>').'</li>'.
                                        '</ul>'.                                         '</ul>'.
                                        '</li>';                                         '</li>';
Line 12506  sub modify_coursedefaults { Line 12193  sub modify_coursedefaults {
                                        '<li>'.&mt('Official courses: [_1] s','<b>'.$defaultshash{'coursedefaults'}{'mysqltables'}{'official'}.'</b>').'</li>'.                                         '<li>'.&mt('Official courses: [_1] s','<b>'.$defaultshash{'coursedefaults'}{'mysqltables'}{'official'}.'</b>').'</li>'.
                                        '<li>'.&mt('Unofficial courses: [_1] s','<b>'.$defaultshash{'coursedefaults'}{'mysqltables'}{'unofficial'}.'</b>').'</li>'.                                         '<li>'.&mt('Unofficial courses: [_1] s','<b>'.$defaultshash{'coursedefaults'}{'mysqltables'}{'unofficial'}.'</b>').'</li>'.
                                        '<li>'.&mt('Textbook courses: [_1] s','<b>'.$defaultshash{'coursedefaults'}{'mysqltables'}{'textbook'}.'</b>').'</li>'.                                         '<li>'.&mt('Textbook courses: [_1] s','<b>'.$defaultshash{'coursedefaults'}{'mysqltables'}{'textbook'}.'</b>').'</li>'.
                                          '<li>'.&mt('Placement tests: [_1] s','<b>'.$defaultshash{'coursedefaults'}{'mysqltables'}{'placement'}.'</b>').'</li>'.
                                        '<li>'.&mt('Communities: [_1] s','<b>'.$defaultshash{'coursedefaults'}{'mysqltables'}{'community'}.'</b>').'</li>'.                                         '<li>'.&mt('Communities: [_1] s','<b>'.$defaultshash{'coursedefaults'}{'mysqltables'}{'community'}.'</b>').'</li>'.
                                        '</ul>'.                                         '</ul>'.
                                        '</li>';                                         '</li>';
Line 12517  sub modify_coursedefaults { Line 12205  sub modify_coursedefaults {
                         $resulttext .= '<li>'.&mt('Submit button(s) remain enabled on page after student makes submission.');                          $resulttext .= '<li>'.&mt('Submit button(s) remain enabled on page after student makes submission.');
                     } else {                      } else {
                         $resulttext .= '<li>'.&mt('Submit button(s) disabled on page after student makes submission').'; ';                          $resulttext .= '<li>'.&mt('Submit button(s) disabled on page after student makes submission').'; ';
                         if (ref($defaultshash{'coursedefaults'}{'postsubmit'}) eq 'HASH') {                          if (ref($defaultshash{'coursedefaults'}{'postsubmit'}) eq 'HASH') { 
                             $resulttext .= &mt('durations:').'<ul>';                              $resulttext .= &mt('durations:').'<ul>';
                             foreach my $type (@types) {                              foreach my $type (@types) {
                                 $resulttext .= '<li>';                                  $resulttext .= '<li>';
Line 12541  sub modify_coursedefaults { Line 12229  sub modify_coursedefaults {
                                     $resulttext .= &mt('Unofficial courses');                                      $resulttext .= &mt('Unofficial courses');
                                 } elsif ($type eq 'textbook') {                                  } elsif ($type eq 'textbook') {
                                     $resulttext .= &mt('Textbook courses');                                      $resulttext .= &mt('Textbook courses');
                                   } elsif ($type eq 'placement') {
                                       $resulttext .= &mt('Placement tests');
                                 }                                  }
                                 $resulttext .= ' -- '.$display.'</li>';                                  $resulttext .= ' -- '.$display.'</li>';
                             }                              }
                             $resulttext .= '</ul>';                              $resulttext .= '</ul>';
                         }                          }
                         $resulttext .= '</li>';                          $resulttext .= '</li>';    
                     }                      }
                 } elsif ($item eq 'coursecredits') {                  } elsif ($item eq 'coursecredits') {
                     if (ref($defaultshash{'coursedefaults'}{'coursecredits'}) eq 'HASH') {                      if (ref($defaultshash{'coursedefaults'}{'coursecredits'}) eq 'HASH') {
Line 12574  sub modify_coursedefaults { Line 12264  sub modify_coursedefaults {
                     } elsif ($defaultshash{'coursedefaults'}{'canclone'} eq 'domain') {                      } elsif ($defaultshash{'coursedefaults'}{'canclone'} eq 'domain') {
                         $resulttext .= '<li>'.&mt('By default, a course requester can clone any course from his/her domain.').'</li>';                          $resulttext .= '<li>'.&mt('By default, a course requester can clone any course from his/her domain.').'</li>';
                     } else {                      } else {
                         $resulttext .= '<li>'.&mt('By default, only course owner and coordinators may clone a course.').'</li>';                          $resulttext .= '<li>'.&mt('By default, only course owner and coordinators may clone a course.').'</li>'; 
                     }                      }
                 }                  }
             }              }
Line 12592  sub modify_coursedefaults { Line 12282  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 12809  sub modify_selfenrollment { Line 12499  sub modify_selfenrollment {
                         $resulttext .= '</ul></li>';                           $resulttext .= '</ul></li>'; 
                     }                      }
                 }                  }
             }                  if ((exists($changes{'admin'})) || (exists($changes{'default'}))) {
             if ((exists($changes{'admin'})) || (exists($changes{'default'}))) {                      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') {                          $lastactref->{'domdefaults'} = 1;
                     $lastactref->{'domdefaults'} = 1;                      }
                 }                  }
             }              }
             $resulttext .= '</ul>';              $resulttext .= '</ul>';
Line 12839  sub modify_usersessions { Line 12529  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 13029  sub modify_usersessions { Line 12719  sub modify_usersessions {
                 }                  }
             }              }
             unless ($changes{'offloadnow'}) {              unless ($changes{'offloadnow'}) {
                 foreach my $lonhost (keys(%{$defaultshash{'usersessions'}{'offloadnow'}})) {                  foreach my $lonhost (keys(%{$defaultshash{'usersessions'}{'offloadnow'}})) { 
                     unless ($domconfig{'usersessions'}{'offloadnow'}{$lonhost}) {                      unless ($domconfig{'usersessions'}{'offloadnow'}{$lonhost}) {
                         $changes{'offloadnow'} = 1;                          $changes{'offloadnow'} = 1;
                         last;                          last;
Line 13060  sub modify_usersessions { Line 12750  sub modify_usersessions {
             }              }
             my $cachetime = 24*60*60;              my $cachetime = 24*60*60;
             &Apache::lonnet::do_cache_new('domdefaults',$dom,\%domdefaults,$cachetime);              &Apache::lonnet::do_cache_new('domdefaults',$dom,\%domdefaults,$cachetime);
             &Apache::lonnet::do_cache_new('usersessions',$dom,$defaultshash{'usersessions'},3600);  
             if (ref($lastactref) eq 'HASH') {              if (ref($lastactref) eq 'HASH') {
                 $lastactref->{'domdefaults'} = 1;                  $lastactref->{'domdefaults'} = 1;
                 $lastactref->{'usersessions'} = 1;  
             }              }
             if (keys(%changes) > 0) {              if (keys(%changes) > 0) {
                 my %lt = &usersession_titles();                  my %lt = &usersession_titles();
Line 13156  sub modify_usersessions { Line 12844  sub modify_usersessions {
     return $resulttext;      return $resulttext;
 }  }
   
   sub modify_ssl {
       my ($dom,$lastactref,%domconfig) = @_;
       my (%by_ip,%by_location,@intdoms,@instdoms);
       &build_location_hashes(\@intdoms,\%by_ip,\%by_location,\@instdoms);
       my @locations = sort(keys(%by_location));
       my %servers = &Apache::lonnet::internet_dom_servers($dom);
       my (%defaultshash,%changes);
       my $action = 'ssl';
       my @prefixes = ('connect','replication');
       foreach my $prefix (@prefixes) {
           $defaultshash{$action}{$prefix} = {};
       }
       my %domdefaults = &Apache::lonnet::get_domain_defaults($dom,1);
       my $resulttext;
       my %iphost = &Apache::lonnet::get_iphost();
       my @reptypes = ('certreq','nocertreq');
       my @connecttypes = ('dom','intdom','other');
       my %types = (
                     connect      => \@connecttypes,
                     replication  => \@reptypes,
                   );
       foreach my $prefix (sort(keys(%types))) {
           foreach my $type (@{$types{$prefix}}) {
               if ($prefix eq 'connect') {
                   my $value = 'yes';
                   if ($env{'form.'.$prefix.'_'.$type} =~ /^(no|req)$/) {
                       $value = $env{'form.'.$prefix.'_'.$type};
                   }
                   if (ref($domconfig{$action}{$prefix}) eq 'HASH') {
                       if ($domconfig{$action}{$prefix}{$type} ne '') {
                           if ($value ne $domconfig{$action}{$prefix}{$type}) {
                               $changes{$prefix}{$type} = 1;
                           }
                           $defaultshash{$action}{$prefix}{$type} = $value;
                       } else {
                           $defaultshash{$action}{$prefix}{$type} = $value;
                           $changes{$prefix}{$type} = 1;
                       }
                   } else {
                       $defaultshash{$action}{$prefix}{$type} = $value;
                       $changes{$prefix}{$type} = 1;
                   }
                   if (($type eq 'dom') && (keys(%servers) == 1)) {
                       delete($changes{$prefix}{$type});
                   } elsif (($type eq 'intdom') && (@instdoms == 1)) {
                       delete($changes{$prefix}{$type});
                   } elsif (($type eq 'other') && (keys(%by_location) == 0)) { 
                       delete($changes{$prefix}{$type});
                   }
               } elsif ($prefix eq 'replication') {
                   if (@locations > 0) {
                       my $inuse = $env{'form.'.$prefix.'_'.$type.'_inuse'};
                       my @vals = &Apache::loncommon::get_env_multiple('form.'.$prefix.'_'.$type);
                       my @okvals;
                       foreach my $val (@vals) {
                           if ($val =~ /:/) {
                               my @items = split(/:/,$val);
                               foreach my $item (@items) {
                                   if (ref($by_location{$item}) eq 'ARRAY') {
                                       push(@okvals,$item);
                                   }
                               }
                           } else {
                               if (ref($by_location{$val}) eq 'ARRAY') {
                                   push(@okvals,$val);
                               }
                           }
                       }
                       @okvals = sort(@okvals);
                       if (ref($domconfig{$action}) eq 'HASH') {
                           if (ref($domconfig{$action}{$prefix}) eq 'HASH') {
                               if (ref($domconfig{$action}{$prefix}{$type}) eq 'ARRAY') {
                                   if ($inuse == 0) {
                                       $changes{$prefix}{$type} = 1;
                                   } else {
                                       $defaultshash{$action}{$prefix}{$type} = \@okvals;
                                       my @changed = &Apache::loncommon::compare_arrays($domconfig{$action}{$prefix}{$type},$defaultshash{$action}{$prefix}{$type});
                                       if (@changed > 0) {
                                           $changes{$prefix}{$type} = 1;
                                       }
                                   }
                               } else {
                                   if ($inuse == 1) {
                                       $defaultshash{$action}{$prefix}{$type} = \@okvals;
                                       $changes{$prefix}{$type} = 1;
                                   }
                               }
                           } else {
                               if ($inuse == 1) {
                                   $defaultshash{$action}{$prefix}{$type} = \@okvals;
                                   $changes{$prefix}{$type} = 1;
                               }
                           }
                       } else {
                           if ($inuse == 1) {
                               $defaultshash{$action}{$prefix}{$type} = \@okvals;
                               $changes{$prefix}{$type} = 1;
                           }
                       }
                   }
               }
           }
       }
       my $nochgmsg = &mt('No changes made to LON-CAPA SSL settings');
       if (keys(%changes) > 0) {
           my $putresult = &Apache::lonnet::put_dom('configuration',\%defaultshash,
                                                    $dom);
           if ($putresult eq 'ok') {
               if (ref($defaultshash{$action}) eq 'HASH') {
                   if (ref($defaultshash{$action}{'replication'}) eq 'HASH') {
                       $domdefaults{'replication'} = $defaultshash{$action}{'replication'};
                   }
                   if (ref($defaultshash{$action}{'connect'}) eq 'HASH') {
                       $domdefaults{'connect'} = $domconfig{$action}{'connect'};
                   }
               }
               my $cachetime = 24*60*60;
               &Apache::lonnet::do_cache_new('domdefaults',$dom,\%domdefaults,$cachetime);
               if (ref($lastactref) eq 'HASH') {
                   $lastactref->{'domdefaults'} = 1;
               }
               if (keys(%changes) > 0) {
                   my %titles = &ssl_titles();
                   $resulttext = &mt('Changes made:').'<ul>';
                   foreach my $prefix (@prefixes) {
                       if (ref($changes{$prefix}) eq 'HASH') {
                           $resulttext .= '<li>'.$titles{$prefix}.'<ul>';
                           foreach my $type (@{$types{$prefix}}) {
                               if (defined($changes{$prefix}{$type})) {
                                   my $newvalue;
                                   if (ref($defaultshash{$action}) eq 'HASH') {
                                       if (ref($defaultshash{$action}{$prefix})) {
                                           if ($prefix eq 'connect') {
                                               $newvalue = $titles{$defaultshash{$action}{$prefix}{$type}};
                                           } elsif (ref($defaultshash{$action}{$prefix}{$type}) eq 'ARRAY') {
                                               if (@{$defaultshash{$action}{$prefix}{$type}} > 0) {
                                                   $newvalue = join(', ',@{$defaultshash{$action}{$prefix}{$type}});
                                               }
                                           }
                                       }
                                       if ($newvalue eq '') {
                                           $resulttext .= '<li>'.&mt('[_1] set to: none',$titles{$type}).'</li>';
                                       } else {
                                           $resulttext .= '<li>'.&mt('[_1] set to: [_2].',$titles{$type},$newvalue).'</li>';
                                       }
                                   }
                               }
                           }
                           $resulttext .= '</ul>';
                       }
                   }
               } else {
                   $resulttext = $nochgmsg;
               }
           } else {
               $resulttext = '<span class="LC_error">'.
                             &mt('An error occurred: [_1]',$putresult).'</span>';
           }
       } else {
           $resulttext = $nochgmsg;
       }
       return $resulttext;
   }
   
   sub modify_trust {
       my ($dom,$lastactref,%domconfig) = @_;
       my (%by_ip,%by_location,@intdoms,@instdoms);
       &build_location_hashes(\@intdoms,\%by_ip,\%by_location,\@instdoms);
       my @locations = sort(keys(%by_location));
       my @prefixes = qw(content shared enroll othcoau coaurem domroles catalog reqcrs msg);
       my @types = ('exc','inc');
       my (%defaultshash,%changes);
       foreach my $prefix (@prefixes) {
           $defaultshash{'trust'}{$prefix} = {};
       }
       my %domdefaults = &Apache::lonnet::get_domain_defaults($dom,1);
       my $resulttext;
       foreach my $prefix (@prefixes) {
           foreach my $type (@types) {
               my $inuse = $env{'form.'.$prefix.'_'.$type.'_inuse'};
               my @vals = &Apache::loncommon::get_env_multiple('form.'.$prefix.'_'.$type);
               my @okvals;
               foreach my $val (@vals) {
                   if ($val =~ /:/) {
                       my @items = split(/:/,$val);
                       foreach my $item (@items) {
                           if (ref($by_location{$item}) eq 'ARRAY') {
                               push(@okvals,$item);
                           }
                       }
                   } else {
                       if (ref($by_location{$val}) eq 'ARRAY') {
                           push(@okvals,$val);
                       }
                   }
               }
               @okvals = sort(@okvals);
               if (ref($domconfig{'trust'}) eq 'HASH') {
                   if (ref($domconfig{'trust'}{$prefix}) eq 'HASH') {
                       if (ref($domconfig{'trust'}{$prefix}{$type}) eq 'ARRAY') {
                           if ($inuse == 0) {
                               $changes{$prefix}{$type} = 1;
                           } else {
                               $defaultshash{'trust'}{$prefix}{$type} = \@okvals;
                               my @changed = &Apache::loncommon::compare_arrays($domconfig{'trust'}{$prefix}{$type},$defaultshash{'trust'}{$prefix}{$type});
                               if (@changed > 0) {
                                   $changes{$prefix}{$type} = 1;
                               }
                           }
                       } else {
                           if ($inuse == 1) {
                               $defaultshash{'trust'}{$prefix}{$type} = \@okvals;
                               $changes{$prefix}{$type} = 1;
                           }
                       }
                   } else {
                       if ($inuse == 1) {
                           $defaultshash{'trust'}{$prefix}{$type} = \@okvals;
                           $changes{$prefix}{$type} = 1;
                       }
                   }
               } else {
                   if ($inuse == 1) {
                       $defaultshash{'trust'}{$prefix}{$type} = \@okvals;
                       $changes{$prefix}{$type} = 1;
                   }
               }
           }
       }
       my $nochgmsg = &mt('No changes made to trust settings.');
       if (keys(%changes) > 0) {
           my $putresult = &Apache::lonnet::put_dom('configuration',\%defaultshash,
                                                    $dom);
           if ($putresult eq 'ok') {
               if (ref($defaultshash{'trust'}) eq 'HASH') {
                   foreach my $prefix (@prefixes) {
                       if (ref($defaultshash{'trust'}{$prefix}) eq 'HASH') {
                           $domdefaults{'trust'.$prefix} = $defaultshash{'trust'}{$prefix};
                       }
                   }
               }
               my $cachetime = 24*60*60;
               &Apache::lonnet::do_cache_new('domdefaults',$dom,\%domdefaults,$cachetime);
               if (ref($lastactref) eq 'HASH') {
                   $lastactref->{'domdefaults'} = 1;
               }
               if (keys(%changes) > 0) {
                   my %lt = &trust_titles();
                   $resulttext = &mt('Changes made:').'<ul>';
                   foreach my $prefix (@prefixes) {
                       if (ref($changes{$prefix}) eq 'HASH') {
                           $resulttext .= '<li>'.$lt{$prefix}.'<ul>';
                           foreach my $type (@types) {
                               if (defined($changes{$prefix}{$type})) {
                                   my $newvalue;
                                   if (ref($defaultshash{'trust'}) eq 'HASH') {
                                       if (ref($defaultshash{'trust'}{$prefix})) {
                                           if (ref($defaultshash{'trust'}{$prefix}{$type}) eq 'ARRAY') {
                                               if (@{$defaultshash{'trust'}{$prefix}{$type}} > 0) {
                                                   $newvalue = join(', ',@{$defaultshash{'trust'}{$prefix}{$type}});
                                               }
                                           }
                                       }
                                   }
                                   if ($newvalue eq '') {
                                       $resulttext .= '<li>'.&mt('[_1] set to: none',$lt{$type}).'</li>';
                                   } else {
                                       $resulttext .= '<li>'.&mt('[_1] set to: [_2].',$lt{$type},$newvalue).'</li>';
                                   }
                               }
                           }
                           $resulttext .= '</ul>';
                       }
                   }
                   $resulttext .= '</ul>';
               } else {
                   $resulttext = $nochgmsg;
               }
           } else {
               $resulttext = '<span class="LC_error">'.
                             &mt('An error occurred: [_1]',$putresult).'</span>';
           }
       } else {
           $resulttext = $nochgmsg;
       }
       return $resulttext;
   }
   
 sub modify_loadbalancing {  sub modify_loadbalancing {
     my ($dom,%domconfig) = @_;      my ($dom,%domconfig) = @_;
     my $primary_id = &Apache::lonnet::domain($dom,'primary');      my $primary_id = &Apache::lonnet::domain($dom,'primary');
Line 13216  sub modify_loadbalancing { Line 13192  sub modify_loadbalancing {
                         push(@offloadto,$target);                          push(@offloadto,$target);
                     }                      }
                 }                  }
                   $defaultshash{'loadbalancing'}{$balancer}{'targets'}{$sparetype} = \@offloadto;
             }              }
             if ($env{'form.loadbalancing_target_'.$i.'_hosthere'} eq $sparetype) {  
                 unless(grep(/^\Q$balancer\E$/,@offloadto)) {  
                     push(@offloadto,$balancer);  
                 }  
             }  
             $defaultshash{'loadbalancing'}{$balancer}{'targets'}{$sparetype} = \@offloadto;  
         }          }
         if (ref($currtargets{$balancer}) eq 'HASH') {          if (ref($currtargets{$balancer}) eq 'HASH') {
             foreach my $sparetype (@sparestypes) {              foreach my $sparetype (@sparestypes) {
Line 13261  sub modify_loadbalancing { Line 13232  sub modify_loadbalancing {
                 }                  }
                 if ($rule eq 'specific') {                  if ($rule eq 'specific') {
                     my $specifiedhost = $env{'form.loadbalancing_singleserver_'.$i.'_'.$type};                      my $specifiedhost = $env{'form.loadbalancing_singleserver_'.$i.'_'.$type};
                     if (exists($servers{$specifiedhost})) {                      if (exists($servers{$specifiedhost})) { 
                         $rule = $specifiedhost;                          $rule = $specifiedhost;
                     }                      }
                 }                  }
Line 13337  sub modify_loadbalancing { Line 13308  sub modify_loadbalancing {
                                         if ($rule eq '') {                                          if ($rule eq '') {
                                             $balancetext =  $ruletitles{'default'};                                              $balancetext =  $ruletitles{'default'};
                                         } elsif (($rule eq 'homeserver') || ($rule eq 'externalbalancer') ||                                          } elsif (($rule eq 'homeserver') || ($rule eq 'externalbalancer') ||
                                                  ($type eq '_LC_ipchange') || ($type eq '_LC_ipchangesso')) {                                                   ($type eq '_LC_ipchange') || ($type eq '_LC_ipchangesso')) { 
                                             if (($type eq '_LC_ipchange') || ($type eq '_LC_ipchangesso')) {                                              if (($type eq '_LC_ipchange') || ($type eq '_LC_ipchangesso')) {
                                                 foreach my $sparetype (@sparestypes) {                                                  foreach my $sparetype (@sparestypes) {
                                                     if (ref($defaultshash{'loadbalancing'}{$balancer}{'targets'}{$sparetype}) eq 'ARRAY') {                                                      if (ref($defaultshash{'loadbalancing'}{$balancer}{'targets'}{$sparetype}) eq 'ARRAY') {
Line 13456  sub recurse_cat_deletes { Line 13427  sub recurse_cat_deletes {
     return;      return;
 }  }
   
   sub get_active_dcs {
       my ($dom) = @_;
       my $now = time;
       my %dompersonnel = &Apache::lonnet::get_domain_roles($dom,['dc'],$now,$now);
       my %domcoords;
       my $numdcs = 0;
       foreach my $server (keys(%dompersonnel)) {
           foreach my $user (sort(keys(%{$dompersonnel{$server}}))) {
               my ($trole,$uname,$udom,$runame,$rudom,$rsec) = split(/:/,$user);
               $domcoords{$uname.':'.$udom} = $dompersonnel{$server}{$user};
           }
       }
       return %domcoords;
   }
   
 sub active_dc_picker {  sub active_dc_picker {
     my ($dom,$numinrow,$inputtype,$name,%currhash) = @_;      my ($dom,$numinrow,$inputtype,$name,%currhash) = @_;
     my %domcoords = &Apache::lonnet::get_active_domroles($dom,['dc']);      my %domcoords = &get_active_dcs($dom);
     my @domcoord = keys(%domcoords);      my @domcoord = keys(%domcoords);
     if (keys(%currhash)) {      if (keys(%currhash)) {
         foreach my $dc (keys(%currhash)) {          foreach my $dc (keys(%currhash)) {
Line 14064  function updateCaptcha(caller,context) { Line 14050  function updateCaptcha(caller,context) {
             privtext.innerHTML = "$lt{'priv'}";              privtext.innerHTML = "$lt{'priv'}";
             versionitem.type = 'text';              versionitem.type = 'text';
             versionitem.size = '3';              versionitem.size = '3';
             versiontext.innerHTML = "$lt{'ver'}";              versiontext.innerHTML = "$lt{'ver'}"; 
         } else {          } else {
             pubitem.type = 'hidden';              pubitem.type = 'hidden';
             privitem.type = 'hidden';              privitem.type = 'hidden';
Line 14096  function toggleDisplay(domForm,caller) { Line 14082  function toggleDisplay(domForm,caller) {
         var optionsElement = domForm.coursecredits;          var optionsElement = domForm.coursecredits;
         var checkval = 1;          var checkval = 1;
         var dispval = 'block';          var dispval = 'block';
         var selfcreateRegExp = /^cancreate_emailverified/;  
         if (caller == 'emailoptions') {          if (caller == 'emailoptions') {
             optionsElement = domForm.cancreate_email;               optionsElement = domForm.cancreate_email; 
         }          }
Line 14107  function toggleDisplay(domForm,caller) { Line 14092  function toggleDisplay(domForm,caller) {
             optionsElement = domForm.canclone;              optionsElement = domForm.canclone;
             checkval = 'instcode';              checkval = 'instcode';
         }          }
         if (selfcreateRegExp.test(caller)) {  
             optionsElement = domForm.elements[caller];  
             checkval = 'other';  
             dispval = 'inline'  
         }  
         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 14143  sub captcha_phrases { Line 14123  sub captcha_phrases {
                  original  => 'original (CAPTCHA)',                   original  => 'original (CAPTCHA)',
                  recaptcha => 'successor (ReCAPTCHA)',                   recaptcha => 'successor (ReCAPTCHA)',
                  notused   => 'unused',                   notused   => 'unused',
                  ver => 'ReCAPTCHA version (1 or 2)',                   ver => 'ReCAPTCHA version (1 or 2)', 
     );      );
 }  }
   
Line 14153  sub devalidate_remote_domconfs { Line 14133  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','usersessions','directorysrch');      my @posscached = ('domainconfig','domdefaults','ltitools');
     if (keys(%servers)) {      if (keys(%servers)) {
         foreach my $server (keys(%servers)) {          foreach my $server (keys(%servers)) {
             next if ($thismachine{$server});              next if ($thismachine{$server});

Removed from v.1.160.6.84.4.1  
changed lines
  Added in v.1.282


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