Diff for /loncom/interface/domainprefs.pm between versions 1.160.6.89 and 1.199

version 1.160.6.89, 2018/09/15 15:15:32 version 1.199, 2013/07/15 17:42:11
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 87  $dom,$settings,$rowtotal,$action. Line 86  $dom,$settings,$rowtotal,$action.
   
 $dom is the domain, $settings is a reference to a hash of current settings for  $dom is the domain, $settings is a reference to a hash of current settings for
 the current context, $rowtotal is a reference to the scalar used to record the   the current context, $rowtotal is a reference to the scalar used to record the 
 number of rows displayed on the page, and $action is the context (quotas,   number of rows displayed on the page, and $action is the context (quotas,  
 requestcourses or requestauthor).  requestcourses or requestauthor).
   
 The print_quotas routine was orginally created to display/store information  The print_quotas routine was orginally created to display/store information
Line 96  institutional affiliation in the domain Line 95  institutional affiliation in the domain
 but is now also used to manage availability of user tools:   but is now also used to manage availability of user tools: 
 i.e., blogs, aboutme page, and portfolios, and the course request tool,  i.e., blogs, aboutme page, and portfolios, and the course request tool,
 used by course owners to request creation of a course, and to display/store  used by course owners to request creation of a course, and to display/store
 default quota sizes for Authoring Spaces.  default quota sizes for authoring spaces.
   
 Outputs: 1  Outputs: 1
   
Line 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 and community).  In each case the radio buttons allow the 
 allow the selection of one of four values:  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 165  use Apache::lonhtmlcommon(); Line 164  use Apache::lonhtmlcommon();
 use Apache::lonlocal;  use Apache::lonlocal;
 use Apache::lonmsg();  use Apache::lonmsg();
 use Apache::lonconfigsettings;  use Apache::lonconfigsettings;
 use Apache::lonuserutils();  
 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();
Line 216  sub handler { Line 213  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'],$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','usermodification','scantron',
                        'requestcourses','requestauthor','coursecategories',                         'requestcourses','requestauthor','coursecategories',
                        'serverstatuses','helpsettings','coursedefaults',                         'serverstatuses','helpsettings',
                        'selfenrollment','usersessions');                         'coursedefaults','usersessions');
     my %existing;      my %existing;
     if (ref($domconfig{'loadbalancing'}) eq 'HASH') {      if (ref($domconfig{'loadbalancing'}) eq 'HASH') {
         %existing = %{$domconfig{'loadbalancing'}};          %existing = %{$domconfig{'loadbalancing'}};
Line 242  sub handler { Line 239  sub handler {
                                  col2 => '',},                                   col2 => '',},
                                 {col1 => 'Administrator Settings',                                  {col1 => 'Administrator Settings',
                                  col2 => '',}],                                   col2 => '',}],
                       print => \&print_rolecolors,  
                       modify => \&modify_rolecolors,  
                     },                      },
         'login' =>          'login' =>
                     { text => 'Log-in page options',                      { text => 'Log-in page options',
Line 251  sub handler { Line 246  sub handler {
                       header => [{col1 => 'Log-in Page Items',                        header => [{col1 => 'Log-in Page Items',
                                   col2 => '',},                                    col2 => '',},
                                  {col1 => 'Log-in Help',                                   {col1 => 'Log-in Help',
                                   col2 => 'Value'},  
                                  {col1 => 'Custom HTML in document head',  
                                   col2 => 'Value'}],                                    col2 => 'Value'}],
                       print => \&print_login,  
                       modify => \&modify_login,  
                     },                      },
         'defaults' =>           'defaults' => 
                     { text => 'Default authentication/language/timezone/portal/types',                      { text => 'Default authentication/language/timezone/portal',
                       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',  
                                   col2 => 'Assignable to e-mail usernames'}],  
                       print => \&print_defaults,  
                       modify => \&modify_defaults,  
                     },                      },
         'quotas' =>           'quotas' => 
                     { text => 'Blogs, personal web pages, webDAV/quotas, portfolios',                      { text => 'Blogs, personal web pages, webDAV/quotas, portfolios',
                       help => 'Domain_Configuration_Quotas',                        help => 'Domain_Configuration_Quotas',
                       header => [{col1 => 'User affiliation',                        header => [{col1 => 'User affiliation',
                                   col2 => 'Available tools',                                    col2 => 'Available tools',
                                   col3 => 'Quotas, MB; (Authoring requires role)',}],                                    col3 => 'Quotas, Mb; (Authoring requires role)',}],
                       print => \&print_quotas,  
                       modify => \&modify_quotas,  
                     },                      },
         'autoenroll' =>          'autoenroll' =>
                    { text => 'Auto-enrollment settings',                     { text => 'Auto-enrollment settings',
                      help => 'Domain_Configuration_Auto_Enrollment',                       help => 'Domain_Configuration_Auto_Enrollment',
                      header => [{col1 => 'Configuration setting',                       header => [{col1 => 'Configuration setting',
                                  col2 => 'Value(s)'}],                                   col2 => 'Value(s)'}],
                      print => \&print_autoenroll,  
                      modify => \&modify_autoenroll,  
                    },                     },
         'autoupdate' =>           'autoupdate' => 
                    { text => 'Auto-update settings',                     { text => 'Auto-update settings',
Line 294  sub handler { Line 275  sub handler {
                                 {col1 => 'Setting',                                  {col1 => 'Setting',
                                  col2 => 'Affiliation'},                                   col2 => 'Affiliation'},
                                 {col1 => 'User population',                                  {col1 => 'User population',
                                  col2 => 'Updatable user data'}],                                   col2 => 'Updateable user data'}],
                      print => \&print_autoupdate,  
                      modify => \&modify_autoupdate,  
                   },                    },
         'autocreate' =>           'autocreate' => 
                   { text => 'Auto-course creation settings',                    { text => 'Auto-course creation settings',
                      help => 'Domain_Configuration_Auto_Creation',                       help => 'Domain_Configuration_Auto_Creation',
                      header => [{col1 => 'Configuration Setting',                       header => [{col1 => 'Configuration Setting',
                                  col2 => 'Value',}],                                   col2 => 'Value',}],
                      print => \&print_autocreate,  
                      modify => \&modify_autocreate,  
                   },                    },
         'directorysrch' =>           'directorysrch' => 
                   { text => 'Directory searches',                    { text => 'Institutional directory searches',
                     help => 'Domain_Configuration_InstDirectory_Search',                      help => 'Domain_Configuration_InstDirectory_Search',
                     header => [{col1 => 'Institutional Directory Setting',                      header => [{col1 => 'Setting',
                                 col2 => 'Value',},  
                                {col1 => 'LON-CAPA Directory Setting',  
                                 col2 => 'Value',}],                                  col2 => 'Value',}],
                     print => \&print_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,  
                     modify => \&modify_contacts,  
                   },                    },
   
         'usercreation' =>           'usercreation' => 
                   { text => 'User creation',                    { text => 'User creation',
                     help => 'Domain_Configuration_User_Creation',                      help => 'Domain_Configuration_User_Creation',
Line 337  sub handler { Line 305  sub handler {
                                 col2 => 'Usernames which may be created',},                                  col2 => 'Usernames which may be created',},
                                {col1 => 'Context',                                 {col1 => 'Context',
                                 col2 => 'Assignable authentication types'}],                                  col2 => 'Assignable authentication types'}],
                     print => \&print_usercreation,  
                     modify => \&modify_usercreation,  
                   },  
         'selfcreation' =>   
                   { text => 'Users self-creating accounts',  
                     help => 'Domain_Configuration_Self_Creation',   
                     header => [{col1 => 'Self-creation with institutional username',  
                                 col2 => 'Enabled?'},  
                                {col1 => 'Institutional user type (login/SSO self-creation)',  
                                 col2 => 'Information user can enter'},  
                                {col1 => 'Self-creation with e-mail as username',  
                                 col2 => 'Settings'}],  
                     print => \&print_selfcreation,  
                     modify => \&modify_selfcreation,  
                   },                    },
         'usermodification' =>          'usermodification' =>
                   { text => 'User modification',                    { text => 'User modification',
                     help => 'Domain_Configuration_User_Modification',                      help => 'Domain_Configuration_User_Modification',
                     header => [{col1 => 'Target user has role',                      header => [{col1 => 'Target user has role',
                                 col2 => 'User information updatable in author context'},                                  col2 => 'User information updateable in author context'},
                                {col1 => 'Target user has role',                                 {col1 => 'Target user has role',
                                 col2 => 'User information updatable in course context'}],                                  col2 => 'User information updateable in course context'},
                     print => \&print_usermodification,                                 {col1 => "Status of user",
                     modify => \&modify_usermodification,                                  col2 => 'Information settable when self-creating account (if directory data blank)'}],
                   },                    },
         'scantron' =>          'scantron' =>
                   { text => 'Bubblesheet format file',                    { text => 'Bubblesheet format file',
Line 368  sub handler { Line 322  sub handler {
                     header => [ {col1 => 'Item',                      header => [ {col1 => 'Item',
                                  col2 => '',                                   col2 => '',
                               }],                                }],
                     print => \&print_scantron,  
                     modify => \&modify_scantron,  
                   },                    },
         'requestcourses' =>           'requestcourses' => 
                  {text => 'Request creation of courses',                   {text => 'Request creation of courses',
Line 377  sub handler { Line 329  sub handler {
                   header => [{col1 => 'User affiliation',                    header => [{col1 => 'User affiliation',
                               col2 => 'Availability/Processing of requests',},                                col2 => 'Availability/Processing of requests',},
                              {col1 => 'Setting',                               {col1 => 'Setting',
                               col2 => 'Value'},                                col2 => 'Value'}],
                              {col1 => 'Available textbooks',  
                               col2 => ''},  
                              {col1 => 'Available templates',  
                               col2 => ''},  
                              {col1 => 'Validation (not official courses)',  
                               col2 => 'Value'},],  
                   print => \&print_quotas,  
                   modify => \&modify_quotas,  
                  },                   },
         'requestauthor' =>          'requestauthor' =>
                  {text => 'Request Authoring Space',                   {text => 'Request authoring space',
                   help => 'Domain_Configuration_Request_Author',                    help => 'Domain_Configuration_Request_Author',
                   header => [{col1 => 'User affiliation',                    header => [{col1 => 'User affiliation',
                               col2 => 'Availability/Processing of requests',},                                col2 => 'Availability/Processing of requests',},
                              {col1 => 'Setting',                               {col1 => 'Setting',
                               col2 => 'Value'}],                                col2 => 'Value'}],
                   print => \&print_quotas,  
                   modify => \&modify_quotas,  
                  },                   },
         'coursecategories' =>          'coursecategories' =>
                   { text => 'Cataloging of courses/communities',                    { text => 'Cataloging of courses/communities',
                     help => 'Domain_Configuration_Cataloging_Courses',                      help => 'Domain_Configuration_Cataloging_Courses',
                     header => [{col1 => 'Catalog type/availability',                      header => [{col1 => 'Category settings',
                                 col2 => '',},  
                                {col1 => 'Category settings for standard catalog',  
                                 col2 => '',},                                  col2 => '',},
                                {col1 => 'Categories',                                 {col1 => 'Categories',
                                 col2 => '',                                  col2 => '',
                                }],                                 }],
                     print => \&print_coursecategories,  
                     modify => \&modify_coursecategories,  
                   },                    },
         'serverstatuses' =>          'serverstatuses' =>
                  {text   => 'Access to server status pages',                   {text   => 'Access to server status pages',
Line 417  sub handler { Line 355  sub handler {
                               col2 => 'Other named users',                                col2 => 'Other named users',
                               col3 => 'Specific IPs',                                col3 => 'Specific IPs',
                             }],                              }],
                   print => \&print_serverstatuses,  
                   modify => \&modify_serverstatuses,  
                  },                   },
         'helpsettings' =>          'helpsettings' =>
                  {text   => 'Support settings',                   {text   => 'Help page settings',
                   help   => 'Domain_Configuration_Help_Settings',                    help   => 'Domain_Configuration_Help_Settings',
                   header => [{col1 => 'Help Page Settings (logged-in users)',                    header => [{col1 => 'Help Settings (logged-in users)',
                               col2 => 'Value'},                                col2 => 'Value'}],
                              {col1 => 'Helpdesk Roles',  
                               col2 => 'Settings'},],  
                   print  => \&print_helpsettings,  
                   modify => \&modify_helpsettings,  
                  },                   },
         'coursedefaults' =>           'coursedefaults' => 
                  {text => 'Course/Community defaults',                   {text => 'Course/Community defaults',
Line 437  sub handler { Line 369  sub handler {
                               col2 => 'Value',},                                col2 => 'Value',},
                              {col1 => 'Defaults which can be overridden for each course by a DC',                               {col1 => 'Defaults which can be overridden for each course by a DC',
                               col2 => 'Value',},],                                col2 => 'Value',},],
                   print => \&print_coursedefaults,  
                   modify => \&modify_coursedefaults,  
                  },                   },
         'selfenrollment' =>           'privacy' => 
                  {text   => 'Self-enrollment in Course/Community',                   {text   => 'User Privacy',
                   help   => 'Domain_Configuration_Selfenrollment',                    help   => 'Domain_Configuration_User_Privacy',
                   header => [{col1 => 'Configuration Rights',                    header => [{col1 => 'Setting',
                               col2 => 'Configured by Course Personnel or Domain Coordinator?'},                                col2 => 'Value',}],
                              {col1 => 'Defaults',  
                               col2 => 'Value'},  
                              {col1 => 'Self-enrollment validation (optional)',  
                               col2 => 'Value'},],  
                   print => \&print_selfenrollment,  
                   modify => \&modify_selfenrollment,  
                  },                   },
         'usersessions' =>          'usersessions' =>
                  {text  => 'User session hosting/offloading',                   {text  => 'User session hosting/offloading',
Line 461  sub handler { Line 385  sub handler {
                               col2 => 'Rules'},                                col2 => 'Rules'},
                              {col1 => "Hosting domain's own users elsewhere",                               {col1 => "Hosting domain's own users elsewhere",
                               col2 => 'Rules'}],                                col2 => 'Rules'}],
                   print => \&print_usersessions,  
                   modify => \&modify_usersessions,  
                  },                   },
         'loadbalancing' =>           'loadbalancing' =>
                  {text  => 'Dedicated Load Balancer(s)',                   {text  => 'Dedicated Load Balancer(s)',
                   help  => 'Domain_Configuration_Load_Balancing',                    help  => 'Domain_Configuration_Load_Balancing',
                   header => [{col1 => 'Balancers',                    header => [{col1 => 'Balancers',
Line 472  sub handler { Line 394  sub handler {
                               col3 => 'User affiliation',                                col3 => 'User affiliation',
                               col4 => 'Overrides'},                                col4 => 'Overrides'},
                             ],                              ],
                   print => \&print_loadbalancing,  
                   modify => \&modify_loadbalancing,  
                  },                   },
     );      );
     if (keys(%servers) > 1) {      if (keys(%servers) > 1) {
Line 484  sub handler { Line 404  sub handler {
                                        {col1 => 'Log-in Page Items',                                         {col1 => 'Log-in Page Items',
                                         col2 => ''},                                          col2 => ''},
                                        {col1 => 'Log-in Help',                                         {col1 => 'Log-in Help',
                                         col2 => 'Value'},  
                                        {col1 => 'Custom HTML in document head',  
                                         col2 => 'Value'}],                                          col2 => 'Value'}],
                             print => \&print_login,  
                             modify => \&modify_login,  
                            };                             };
     }      }
   
Line 500  sub handler { Line 416  sub handler {
     my $confname = $dom.'-domainconfig';      my $confname = $dom.'-domainconfig';
   
     if ($phase eq 'process') {      if ($phase eq 'process') {
         my $result = &Apache::lonconfigsettings::make_changes($r,$dom,$phase,$context,\@prefs_order,          &Apache::lonconfigsettings::make_changes($r,$dom,$phase,$context,\@prefs_order,\%prefs,\%domconfig,$confname,\@roles);
                                                               \%prefs,\%domconfig,$confname,\@roles);  
         if ((ref($result) eq 'HASH') && (keys(%{$result}))) {  
             $r->rflush();  
             &devalidate_remote_domconfs($dom,$result);  
         }  
     } elsif ($phase eq 'display') {      } elsif ($phase eq 'display') {
         my $js = &recaptcha_js().          my $js = &recaptcha_js().
                  &toggle_display_js();                   &credits_js();
         if ((keys(%servers) > 1) || (keys(%existing) > 0)) {          if ((keys(%servers) > 1) || (keys(%existing) > 0)) {
             my ($othertitle,$usertypes,$types) =              my ($othertitle,$usertypes,$types) =
                 &Apache::loncommon::sorted_inst_types($dom);                  &Apache::loncommon::sorted_inst_types($dom);
Line 518  sub handler { Line 429  sub handler {
                    &common_domprefs_js().                     &common_domprefs_js().
                    &Apache::loncommon::javascript_array_indexof();                     &Apache::loncommon::javascript_array_indexof();
         }          }
         if (grep(/^requestcourses$/,@actions)) {  
             my $javascript_validations;  
             my $coursebrowserjs=&Apache::loncommon::coursebrowser_javascript($env{'request.role.domain'});   
             $js .= <<END;  
 <script type="text/javascript">  
 $javascript_validations  
 </script>  
 $coursebrowserjs  
 END  
         }  
         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 540  END Line 438  END
         unless ($configuserok eq 'ok') {          unless ($configuserok eq 'ok') {
             &Apache::lonconfigsettings::print_header($r,$phase,$context);              &Apache::lonconfigsettings::print_header($r,$phase,$context);
             $r->print(&mt('The domain configuration user "[_1]" has yet to be created.',              $r->print(&mt('The domain configuration user "[_1]" has yet to be created.',
                           $confname).                             $confname).
                       '<br />'                        '<br />'
             );              );
             if ($switchserver) {              if ($switchserver) {
Line 600  END Line 498  END
 }  }
   
 sub process_changes {  sub process_changes {
     my ($r,$dom,$confname,$action,$roles,$values,$lastactref) = @_;      my ($r,$dom,$confname,$action,$roles,$values) = @_;
     my %domconfig;      my %domconfig;
     if (ref($values) eq 'HASH') {      if (ref($values) eq 'HASH') {
         %domconfig = %{$values};          %domconfig = %{$values};
     }      }
     my $output;      my $output;
     if ($action eq 'login') {      if ($action eq 'login') {
         $output = &modify_login($r,$dom,$confname,$lastactref,%domconfig);          $output = &modify_login($r,$dom,$confname,%domconfig);
     } elsif ($action eq 'rolecolors') {      } elsif ($action eq 'rolecolors') {
         $output = &modify_rolecolors($r,$dom,$confname,$roles,          $output = &modify_rolecolors($r,$dom,$confname,$roles,
                                      $lastactref,%domconfig);                                       %domconfig);
     } elsif ($action eq 'quotas') {      } elsif ($action eq 'quotas') {
         $output = &modify_quotas($r,$dom,$action,$lastactref,%domconfig);          $output = &modify_quotas($dom,$action,%domconfig);
     } elsif ($action eq 'autoenroll') {      } elsif ($action eq 'autoenroll') {
         $output = &modify_autoenroll($dom,$lastactref,%domconfig);          $output = &modify_autoenroll($dom,%domconfig);
     } elsif ($action eq 'autoupdate') {      } elsif ($action eq 'autoupdate') {
         $output = &modify_autoupdate($dom,%domconfig);          $output = &modify_autoupdate($dom,%domconfig);
     } elsif ($action eq 'autocreate') {      } elsif ($action eq 'autocreate') {
         $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') {  
         $output = &modify_selfcreation($dom,%domconfig);  
     } elsif ($action eq 'usermodification') {      } elsif ($action eq 'usermodification') {
         $output = &modify_usermodification($dom,%domconfig);          $output = &modify_usermodification($dom,%domconfig);
     } elsif ($action eq 'contacts') {      } elsif ($action eq 'contacts') {
         $output = &modify_contacts($dom,$lastactref,%domconfig);          $output = &modify_contacts($dom,%domconfig);
     } elsif ($action eq 'defaults') {      } elsif ($action eq 'defaults') {
         $output = &modify_defaults($dom,$lastactref,%domconfig);          $output = &modify_defaults($dom,$r);
     } elsif ($action eq 'scantron') {      } elsif ($action eq 'scantron') {
         $output = &modify_scantron($r,$dom,$confname,$lastactref,%domconfig);          $output = &modify_scantron($r,$dom,$confname,%domconfig);
     } elsif ($action eq 'coursecategories') {      } elsif ($action eq 'coursecategories') {
         $output = &modify_coursecategories($dom,$lastactref,%domconfig);          $output = &modify_coursecategories($dom,%domconfig);
     } elsif ($action eq 'serverstatuses') {      } elsif ($action eq 'serverstatuses') {
         $output = &modify_serverstatuses($dom,%domconfig);          $output = &modify_serverstatuses($dom,%domconfig);
     } elsif ($action eq 'requestcourses') {      } elsif ($action eq 'requestcourses') {
         $output = &modify_quotas($r,$dom,$action,$lastactref,%domconfig);          $output = &modify_quotas($dom,$action,%domconfig);
     } elsif ($action eq 'requestauthor') {      } elsif ($action eq 'requestauthor') {
         $output = &modify_quotas($r,$dom,$action,$lastactref,%domconfig);          $output = &modify_quotas($dom,$action,%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,%domconfig);
     } elsif ($action eq 'selfenrollment') {  
         $output = &modify_selfenrollment($dom,$lastactref,%domconfig)  
     } elsif ($action eq 'usersessions') {      } elsif ($action eq 'usersessions') {
         $output = &modify_usersessions($dom,$lastactref,%domconfig);          $output = &modify_usersessions($dom,%domconfig);
     } elsif ($action eq 'loadbalancing') {      } elsif ($action eq 'loadbalancing') {
         $output = &modify_loadbalancing($dom,%domconfig);          $output = &modify_loadbalancing($dom,%domconfig);
     }      }
Line 661  sub print_config_box { Line 555  sub print_config_box {
     my $output;      my $output;
     if ($action eq 'coursecategories') {      if ($action eq 'coursecategories') {
         $output = &coursecategories_javascript($settings);          $output = &coursecategories_javascript($settings);
     } elsif ($action eq 'defaults') {  
         $output = &defaults_javascript($settings);   
     } elsif ($action eq 'helpsettings') {  
         my (%privs,%levelscurrent);  
         my %full=();  
         my %levels=(  
                      course => {},  
                      domain => {},  
                      system => {},  
                    );  
         my $context = 'domain';  
         my $crstype = 'Course';  
         my $formname = 'display';  
         &Apache::lonuserutils::custom_role_privs(\%privs,\%full,\%levels,\%levelscurrent);  
         my @templateroles = &Apache::lonuserutils::custom_template_roles($context,$crstype);  
         $output =  
             &Apache::lonuserutils::custom_roledefs_js($context,$crstype,$formname,\%full,  
                                                       \@templateroles);  
     }      }
     $output .=      $output .= 
          '<table class="LC_nested_outer">           '<table class="LC_nested_outer">
           <tr>            <tr>
            <th align="left" valign="middle"><span class="LC_nobreak">'.             <th align="left" valign="middle"><span class="LC_nobreak">'.
Line 695  sub print_config_box { Line 571  sub print_config_box {
     if ($numheaders > 1) {      if ($numheaders > 1) {
         my $colspan = '';          my $colspan = '';
         my $rightcolspan = '';          my $rightcolspan = '';
         if (($action eq 'rolecolors') || ($action eq 'defaults') ||          if (($action eq 'rolecolors') || ($action eq 'coursecategories') || 
             ($action eq 'directorysrch') ||              (($action eq 'login') && ($numheaders < 3))) {
             (($action eq 'login') && ($numheaders < 4))) {  
             $colspan = ' colspan="2"';              $colspan = ' colspan="2"';
         }          }
         if ($action eq 'usersessions') {          if ($action eq 'usersessions') {
Line 712  sub print_config_box { Line 587  sub print_config_box {
               <td class="LC_right_item"'.$rightcolspan.'>'.&mt($item->{'header'}->[0]->{'col2'}).'</td>                <td class="LC_right_item"'.$rightcolspan.'>'.&mt($item->{'header'}->[0]->{'col2'}).'</td>
              </tr>';               </tr>';
         $rowtotal ++;          $rowtotal ++;
         if (($action eq 'autoupdate') || ($action eq 'usercreation') || ($action eq 'selfcreation') ||          if ($action eq 'autoupdate') {
             ($action eq 'usermodification') || ($action eq 'defaults') || ($action eq 'coursedefaults') ||              $output .= &print_autoupdate('top',$dom,$settings,\$rowtotal);
             ($action eq 'selfenrollment') || ($action eq 'usersessions') || ($action eq 'directorysrch') ||          } elsif ($action eq 'usercreation') {
             ($action eq 'helpsettings') || ($action eq 'contacts')) {              $output .= &print_usercreation('top',$dom,$settings,\$rowtotal);
             $output .= $item->{'print'}->('top',$dom,$settings,\$rowtotal);          } elsif ($action eq 'usermodification') {
               $output .= &print_usermodification('top',$dom,$settings,\$rowtotal);
         } elsif ($action eq 'coursecategories') {          } elsif ($action eq 'coursecategories') {
             $output .= $item->{'print'}->('top',$dom,$item,$settings,\$rowtotal);              $output .= &print_coursecategories('top',$dom,$item,$settings,\$rowtotal);
         } elsif ($action eq 'login') {          } elsif ($action eq 'login') {
             if ($numheaders == 4) {              if ($numheaders == 3) {
                 $colspan = ' colspan="2"';                  $colspan = ' colspan="2"';
                 $output .= &print_login('service',$dom,$confname,$phase,$settings,\$rowtotal);                  $output .= &print_login('service',$dom,$confname,$phase,$settings,\$rowtotal);
             } else {              } else {
                 $output .= &print_login('page',$dom,$confname,$phase,$settings,\$rowtotal);                  $output .= &print_login('page',$dom,$confname,$phase,$settings,\$rowtotal);
             }              }
         } elsif (($action eq 'requestcourses') || ($action eq 'requestauthor')) {          } elsif ($action eq 'requestcourses') {
               $output .= &print_quotas($dom,$settings,\$rowtotal,$action);
           } elsif ($action eq 'requestauthor') {
             $output .= &print_quotas($dom,$settings,\$rowtotal,$action);              $output .= &print_quotas($dom,$settings,\$rowtotal,$action);
           } elsif ($action eq 'usersessions') {
               $output .= &print_usersessions('top',$dom,$settings,\$rowtotal); 
         } elsif ($action eq 'rolecolors') {          } elsif ($action eq 'rolecolors') {
             $output .= &print_rolecolors($phase,'student',$dom,$confname,$settings,\$rowtotal);              $output .= &print_rolecolors($phase,'student',$dom,$confname,$settings,\$rowtotal);
           } elsif ($action eq 'coursedefaults') {
               $output .= &print_coursedefaults('top',$dom,$settings,\$rowtotal);
         }          }
         $output .= '          $output .= '
            </table>             </table>
Line 739  sub print_config_box { Line 621  sub print_config_box {
            <td>             <td>
             <table class="LC_nested">              <table class="LC_nested">
              <tr class="LC_info_row">               <tr class="LC_info_row">
               <td class="LC_left_item"'.$colspan.'>'.&mt($item->{'header'}->[1]->{'col1'}).'</td>                <td class="LC_left_item"'.$colspan.'>'.&mt($item->{'header'}->[1]->{'col1'}).'</td>';
           $output .= '
               <td class="LC_right_item"'.$colspan.'>'.&mt($item->{'header'}->[1]->{'col2'}).'</td>                <td class="LC_right_item"'.$colspan.'>'.&mt($item->{'header'}->[1]->{'col2'}).'</td>
              </tr>';               </tr>';
             $rowtotal ++;              $rowtotal ++;
         if (($action eq 'autoupdate') || ($action eq 'usercreation') ||          if ($action eq 'autoupdate') {
             ($action eq 'selfcreation') || ($action eq 'selfenrollment') ||              $output .= &print_autoupdate('middle',$dom,$settings,\$rowtotal).'
             ($action eq 'usersessions') || ($action eq 'coursecategories') ||  
             ($action eq 'contacts') || ($action eq 'defaults')) {  
             if ($action eq 'coursecategories') {  
                 $output .= &print_coursecategories('middle',$dom,$item,$settings,\$rowtotal);  
                 $colspan = ' colspan="2"';  
             } else {  
                 $output .= $item->{'print'}->('middle',$dom,$settings,\$rowtotal);  
             }  
             $output .= '  
            </table>             </table>
           </td>            </td>
          </tr>           </tr>
Line 762  sub print_config_box { Line 636  sub print_config_box {
             <table class="LC_nested">              <table class="LC_nested">
              <tr class="LC_info_row">               <tr class="LC_info_row">
               <td class="LC_left_item"'.$colspan.'>'.&mt($item->{'header'}->[2]->{'col1'}).'</td>                <td class="LC_left_item"'.$colspan.'>'.&mt($item->{'header'}->[2]->{'col1'}).'</td>
               <td class="LC_right_item">'.&mt($item->{'header'}->[2]->{'col2'}).'</td>                <td class="LC_right_item">'.&mt($item->{'header'}->[2]->{'col2'}).'</td>      </tr>'.
              </tr>'."\n";              &print_autoupdate('bottom',$dom,$settings,\$rowtotal);
             if ($action eq 'coursecategories') {  
                 $output .= &print_coursecategories('bottom',$dom,$item,$settings,\$rowtotal);  
             } else {  
                 $output .= $item->{'print'}->('bottom',$dom,$settings,\$rowtotal);  
             }  
             $rowtotal ++;              $rowtotal ++;
         } elsif (($action eq 'usermodification') || ($action eq 'coursedefaults') ||          } elsif ($action eq 'usercreation') {
                  ($action eq 'defaults') || ($action eq 'directorysrch') ||              $output .= &print_usercreation('middle',$dom,$settings,\$rowtotal).'
                  ($action eq 'helpsettings')) {  
             $output .= $item->{'print'}->('bottom',$dom,$settings,\$rowtotal);  
         } elsif ($action eq 'login') {  
             if ($numheaders == 4) {  
                 $output .= &print_login('page',$dom,$confname,$phase,$settings,\$rowtotal).'  
            </table>             </table>
           </td>            </td>
          </tr>           </tr>
Line 785  sub print_config_box { Line 649  sub print_config_box {
             <table class="LC_nested">              <table class="LC_nested">
              <tr class="LC_info_row">               <tr class="LC_info_row">
               <td class="LC_left_item"'.$colspan.'>'.&mt($item->{'header'}->[2]->{'col1'}).'</td>                <td class="LC_left_item"'.$colspan.'>'.&mt($item->{'header'}->[2]->{'col1'}).'</td>
               <td class="LC_right_item"'.$colspan.'>'.&mt($item->{'header'}->[2]->{'col2'}).'</td></tr>'.                <td class="LC_right_item">'.&mt($item->{'header'}->[2]->{'col2'}).'</td>             </tr>'.
                        &print_login('help',$dom,$confname,$phase,$settings,\$rowtotal);              &print_usercreation('bottom',$dom,$settings,\$rowtotal);
                 $rowtotal ++;              $rowtotal ++;
             } else {          } elsif ($action eq 'usermodification') {
                 $output .= &print_login('help',$dom,$confname,$phase,$settings,\$rowtotal);              $output .= &print_usermodification('middle',$dom,$settings,\$rowtotal).'
             }  
             $output .= '  
            </table>             </table>
           </td>            </td>
          </tr>           </tr>
          <tr>           <tr>
            <td>             <td>
             <table class="LC_nested">              <table class="LC_nested">
              <tr class="LC_info_row">';               <tr class="LC_info_row">
             if ($numheaders == 4) {  
                 $output .= '  
               <td class="LC_left_item"'.$colspan.'>'.&mt($item->{'header'}->[3]->{'col1'}).'</td>  
               <td class="LC_right_item"'.$colspan.'>'.&mt($item->{'header'}->[3]->{'col2'}).'</td>  
              </tr>';  
             } else {  
                 $output .= '  
               <td class="LC_left_item"'.$colspan.'>'.&mt($item->{'header'}->[2]->{'col1'}).'</td>                <td class="LC_left_item"'.$colspan.'>'.&mt($item->{'header'}->[2]->{'col1'}).'</td>
               <td class="LC_right_item"'.$colspan.'>'.&mt($item->{'header'}->[2]->{'col2'}).'</td>                <td class="LC_right_item">'.&mt($item->{'header'}->[2]->{'col2'}).'</td>      </tr>'.
              </tr>';                         &print_usermodification('bottom',$dom,$settings,\$rowtotal);
             }  
             $rowtotal ++;  
             $output .= &print_login('headtag',$dom,$confname,$phase,$settings,\$rowtotal);  
         } elsif ($action eq 'requestcourses') {  
             $output .= &print_requestmail($dom,$action,$settings,\$rowtotal);  
             $rowtotal ++;              $rowtotal ++;
             $output .= &print_studentcode($settings,\$rowtotal).'          } elsif ($action eq 'coursecategories') {
               $output .= &print_coursecategories('bottom',$dom,$item,$settings,\$rowtotal);
           } elsif ($action eq 'login') {
               if ($numheaders == 3) {
                   $output .= &print_login('page',$dom,$confname,$phase,$settings,\$rowtotal).'
            </table>             </table>
           </td>            </td>
          </tr>           </tr>
Line 824  sub print_config_box { Line 678  sub print_config_box {
             <table class="LC_nested">              <table class="LC_nested">
              <tr class="LC_info_row">               <tr class="LC_info_row">
               <td class="LC_left_item"'.$colspan.'>'.&mt($item->{'header'}->[2]->{'col1'}).'</td>                <td class="LC_left_item"'.$colspan.'>'.&mt($item->{'header'}->[2]->{'col1'}).'</td>
               <td class="LC_right_item">'.&mt($item->{'header'}->[2]->{'col2'}).'</td> </tr>'.                <td class="LC_right_item"'.$colspan.'>'.&mt($item->{'header'}->[2]->{'col2'}).'</td>      </tr>'.
                        &textbookcourses_javascript($settings).                         &print_login('help',$dom,$confname,$phase,$settings,\$rowtotal);
                        &print_textbookcourses($dom,'textbooks',$settings,\$rowtotal).'                  $rowtotal ++;
             </table>              } else {
            </td>                  $output .= &print_login('help',$dom,$confname,$phase,$settings,\$rowtotal);
           </tr>              }
           } elsif ($action eq 'requestcourses') {
               $output .= &print_requestmail($dom,$action,$settings,\$rowtotal);
           } elsif ($action eq 'requestauthor') {
               $output .= &print_requestmail($dom,$action,$settings,\$rowtotal);
           } elsif ($action eq 'usersessions') {
               $output .= &print_usersessions('middle',$dom,$settings,\$rowtotal).'
              </table>
             </td>
            </tr>
          <tr>           <tr>
            <td>             <td>
             <table class="LC_nested">              <table class="LC_nested">
              <tr class="LC_info_row">               <tr class="LC_info_row">
               <td class="LC_left_item"'.$colspan.'>'.&mt($item->{'header'}->[3]->{'col1'}).'</td>                <td class="LC_left_item"'.$colspan.'>'.&mt($item->{'header'}->[2]->{'col1'}).'</td>
               <td class="LC_right_item">'.&mt($item->{'header'}->[3]->{'col2'}).'</td> </tr>'.                <td class="LC_right_item">'.&mt($item->{'header'}->[2]->{'col2'}).'</td>      </tr>'.
                        &print_textbookcourses($dom,'templates',$settings,\$rowtotal).'                         &print_usersessions('bottom',$dom,$settings,\$rowtotal);
             </table>  
            </td>  
           </tr>  
           <tr>  
            <td>  
             <table class="LC_nested">  
              <tr class="LC_info_row">  
               <td class="LC_left_item"'.$colspan.' valign="top">'.&mt($item->{'header'}->[4]->{'col1'}).'</td>  
               <td class="LC_right_item" valign="top">'.&mt($item->{'header'}->[4]->{'col2'}).'</td>  
              </tr>'.  
             &print_validation_rows('requestcourses',$dom,$settings,\$rowtotal);  
         } elsif ($action eq 'requestauthor') {  
             $output .= &print_requestmail($dom,$action,$settings,\$rowtotal);  
             $rowtotal ++;              $rowtotal ++;
           } elsif ($action eq 'coursedefaults') {
               $output .= &print_coursedefaults('bottom',$dom,$settings,\$rowtotal);
         } elsif ($action eq 'rolecolors') {          } elsif ($action eq 'rolecolors') {
             $output .= &print_rolecolors($phase,'coordinator',$dom,$confname,$settings,\$rowtotal).'              $output .= &print_rolecolors($phase,'coordinator',$dom,$confname,$settings,\$rowtotal).'
            </table>             </table>
Line 885  sub print_config_box { Line 737  sub print_config_box {
            <td>             <td>
             <table class="LC_nested">              <table class="LC_nested">
              <tr class="LC_info_row">';               <tr class="LC_info_row">';
         if ($action eq 'login') {          if (($action eq 'login') || ($action eq 'directorysrch')) {
             $output .= '                $output .= '  
               <td class="LC_left_item" colspan="2">'.&mt($item->{'header'}->[0]->{'col1'}).'</td>';                <td class="LC_left_item" colspan="2">'.&mt($item->{'header'}->[0]->{'col1'}).'</td>';
         } elsif ($action eq 'serverstatuses') {          } elsif ($action eq 'serverstatuses') {
Line 929  sub print_config_box { Line 781  sub print_config_box {
         $rowtotal ++;          $rowtotal ++;
         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 'serverstatuses') || ($action eq 'loadbalancing')) {              $output .= &print_autoenroll($dom,$settings,\$rowtotal);
             $output .= $item->{'print'}->($dom,$settings,\$rowtotal);          } elsif ($action eq 'autocreate') {
               $output .= &print_autocreate($dom,$settings,\$rowtotal);
           } elsif ($action eq 'directorysrch') {
               $output .= &print_directorysrch($dom,$settings,\$rowtotal);
           } elsif ($action eq 'contacts') {
               $output .= &print_contacts($dom,$settings,\$rowtotal);
           } elsif ($action eq 'defaults') {
               $output .= &print_defaults($dom,\$rowtotal);
         } elsif ($action eq 'scantron') {          } elsif ($action eq 'scantron') {
             $output .= &print_scantronformat($r,$dom,$confname,$settings,\$rowtotal);              $output .= &print_scantronformat($r,$dom,$confname,$settings,\$rowtotal);
           } elsif ($action eq 'serverstatuses') {
               $output .= &print_serverstatuses($dom,$settings,\$rowtotal);
           } elsif ($action eq 'helpsettings') {
               $output .= &print_helpsettings($dom,$confname,$settings,\$rowtotal);
           } elsif ($action eq 'loadbalancing') {
               $output .= &print_loadbalancing($dom,$settings,\$rowtotal);
         }          }
     }      }
     $output .= '      $output .= '
Line 1230  sub print_login { Line 1095  sub print_login {
             $itemcount ++;              $itemcount ++;
         }          }
         $datatable .= &captcha_choice('login',$settings,$itemcount);          $datatable .= &captcha_choice('login',$settings,$itemcount);
     } elsif ($caller eq 'headtag') {  
         my %domservers = &Apache::lonnet::get_servers($dom);  
         my $choice = $choices{'headtag'};  
         $css_class = ' class="LC_odd_row"';  
         $datatable .= '<tr'.$css_class.'><td colspan="2">'.$choice.'</td>'.  
                       '<td align="left"><table><tr><th>'.$choices{'hostid'}.'</th>'.  
                       '<th>'.$choices{'current'}.'</th>'.  
                       '<th>'.$choices{'action'}.'</th>'.  
                       '<th>'.$choices{'exempt'}.'</th></tr>'."\n";  
         my (%currurls,%currexempt);  
         if (ref($settings) eq 'HASH') {  
             if (ref($settings->{'headtag'}) eq 'HASH') {  
                 foreach my $lonhost (keys(%{$settings->{'headtag'}})) {  
                     if (ref($settings->{'headtag'}{$lonhost}) eq 'HASH') {  
                         $currurls{$lonhost} = $settings->{'headtag'}{$lonhost}{'url'};  
                         $currexempt{$lonhost} = $settings->{'headtag'}{$lonhost}{'exempt'};  
                     }  
                 }  
             }  
         }  
         my %lt = &Apache::lonlocal::texthash(  
                                                del  => 'Delete?',  
                                                rep  => 'Replace:',  
                                                upl  => 'Upload:',  
                                                curr => 'View contents',  
                                                none => 'None',  
         );  
         my $switchserver = &check_switchserver($dom,$confname);  
         foreach my $lonhost (sort(keys(%domservers))) {  
             my $exempt = &check_exempt_addresses($currexempt{$lonhost});  
             $datatable .= '<tr><td>'.$domservers{$lonhost}.'</td>';  
             if ($currurls{$lonhost}) {  
                 $datatable .= '<td class="LC_right_item"><a href="'.  
                               "javascript:void(open('$currurls{$lonhost}?inhibitmenu=yes','Custom_HeadTag',  
                               'menubar=0,toolbar=1,scrollbars=1,width=600,height=500,resizable=yes'))".  
                               '">'.$lt{'curr'}.'</a></td>'.  
                               '<td><span class="LC_nobreak"><label>'.  
                               '<input type="checkbox" name="loginheadtag_del" value="'.$lonhost.'" />'.  
                               $lt{'del'}.'</label>&nbsp;'.$lt{'rep'}.'</span>';  
             } else {  
                 $datatable .= '<td class="LC_right_item">'.$lt{'none'}.'</td><td>'.$lt{'upl'};  
             }  
             $datatable .='<br />';  
             if ($switchserver) {  
                 $datatable .= &mt('Upload to library server: [_1]',$switchserver);  
             } else {  
                 $datatable .= '<input type="file" name="loginheadtag_'.$lonhost.'" />';  
             }  
             $datatable .= '</td><td><input type="text" name="loginheadtagexempt_'.$lonhost.'" value="'.$exempt.'" /></td></tr>';  
         }  
         $datatable .= '</table></td></tr>';  
     }      }
     return $datatable;      return $datatable;
 }  }
Line 1314  sub login_choices { Line 1128  sub login_choices {
             link          => "Link",              link          => "Link",
             alink         => "Active link",              alink         => "Active link",
             vlink         => "Visited link",              vlink         => "Visited link",
             headtag       => "Custom markup",  
             action        => "Action",  
             current       => "Current",  
         );          );
     return %choices;      return %choices;
 }  }
Line 1331  sub print_rolecolors { Line 1142  sub print_rolecolors {
     my %designhash = &Apache::loncommon::get_domainconf($dom);      my %designhash = &Apache::loncommon::get_domainconf($dom);
     my %defaultdesign = %Apache::loncommon::defaultdesign;      my %defaultdesign = %Apache::loncommon::defaultdesign;
     my (%is_custom,%designs);      my (%is_custom,%designs);
     my %defaults = &role_defaults($role,\@bgs,\@links,\@images);      my %defaults = (
                      img => $defaultdesign{$role.'.img'},
                      font => $defaultdesign{$role.'.font'},
      fontmenu => $defaultdesign{$role.'.fontmenu'},
                      );
       foreach my $item (@bgs) {
           $defaults{'bgs'}{$item} = $defaultdesign{$role.'.'.$item};
       }
       foreach my $item (@links) {
           $defaults{'links'}{$item} = $defaultdesign{$role.'.'.$item};
       }
     if (ref($settings) eq 'HASH') {      if (ref($settings) eq 'HASH') {
         if (ref($settings->{$role}) eq 'HASH') {          if (ref($settings->{$role}) eq 'HASH') {
             if ($settings->{$role}->{'img'} ne '') {              if ($settings->{$role}->{'img'} ne '') {
Line 1392  sub print_rolecolors { Line 1213  sub print_rolecolors {
     return $datatable;      return $datatable;
 }  }
   
 sub role_defaults {  
     my ($role,$bgs,$links,$images,$logintext) = @_;  
     my %defaults;  
     unless ((ref($bgs) eq 'ARRAY') && (ref($links) eq 'ARRAY') && (ref($images) eq 'ARRAY')) {  
         return %defaults;  
     }  
     my %defaultdesign = %Apache::loncommon::defaultdesign;  
     if ($role eq 'login') {  
         %defaults = (  
                        font => $defaultdesign{$role.'.font'},  
                     );  
         if (ref($logintext) eq 'ARRAY') {  
             foreach my $item (@{$logintext}) {  
                 $defaults{'logintext'}{$item} = $defaultdesign{$role.'.'.$item};  
             }  
         }  
         foreach my $item (@{$images}) {  
             $defaults{'showlogo'}{$item} = 1;  
         }  
     } else {  
         %defaults = (  
                        img => $defaultdesign{$role.'.img'},  
                        font => $defaultdesign{$role.'.font'},  
                        fontmenu => $defaultdesign{$role.'.fontmenu'},  
                     );  
     }  
     foreach my $item (@{$bgs}) {  
         $defaults{'bgs'}{$item} = $defaultdesign{$role.'.'.$item};  
     }  
     foreach my $item (@{$links}) {  
         $defaults{'links'}{$item} = $defaultdesign{$role.'.'.$item};  
     }  
     foreach my $item (@{$images}) {  
         $defaults{$item} = $defaultdesign{$role.'.'.$item};  
     }  
     return %defaults;  
 }  
   
 sub display_color_options {  sub display_color_options {
     my ($dom,$confname,$phase,$role,$itemcount,$choices,$is_custom,$defaults,$designs,      my ($dom,$confname,$phase,$role,$itemcount,$choices,$is_custom,$defaults,$designs,
         $images,$bgs,$links,$alt_text,$rowtotal,$logintext) = @_;          $images,$bgs,$links,$alt_text,$rowtotal,$logintext) = @_;
Line 1438  sub display_color_options { Line 1221  sub display_color_options {
     my $datatable = '<tr'.$css_class.'>'.      my $datatable = '<tr'.$css_class.'>'.
         '<td>'.$choices->{'font'}.'</td>';          '<td>'.$choices->{'font'}.'</td>';
     if (!$is_custom->{'font'}) {      if (!$is_custom->{'font'}) {
         $datatable .=  '<td>'.&mt('Default in use:').'&nbsp;<span class="css_default_'.$role.'_font" style="color: '.$defaults->{'font'}.';">'.$defaults->{'font'}.'</span></td>';          $datatable .=  '<td>'.&mt('Default in use:').'&nbsp;<span id="css_default_'.$role.'_font" style="color: '.$defaults->{'font'}.';">'.$defaults->{'font'}.'</span></td>';
     } else {      } else {
         $datatable .= '<td>&nbsp;</td>';          $datatable .= '<td>&nbsp;</td>';
     }      }
Line 1446  sub display_color_options { Line 1229  sub display_color_options {
   
     $datatable .= '<td><span class="LC_nobreak">'.      $datatable .= '<td><span class="LC_nobreak">'.
                   '<input type="text" class="colorchooser" size="10" name="'.$role.'_font"'.                    '<input type="text" class="colorchooser" size="10" name="'.$role.'_font"'.
                   ' value="'.$current_color.'" />&nbsp;'.                    ' value="'.$current_color.'" />&nbsp;'. 
                   '&nbsp;</span></td></tr>';                    '&nbsp;</td></tr>';
     unless ($role eq 'login') {       unless ($role eq 'login') { 
         $datatable .= '<tr'.$css_class.'>'.          $datatable .= '<tr'.$css_class.'>'.
                       '<td>'.$choices->{'fontmenu'}.'</td>';                        '<td>'.$choices->{'fontmenu'}.'</td>';
         if (!$is_custom->{'fontmenu'}) {          if (!$is_custom->{'fontmenu'}) {
             $datatable .=  '<td>'.&mt('Default in use:').'&nbsp;<span class="css_default_'.$role.'_font" style="color: '.$defaults->{'fontmenu'}.';">'.$defaults->{'fontmenu'}.'</span></td>';              $datatable .=  '<td>'.&mt('Default in use:').'&nbsp;<span id="css_default_'.$role.'_font" style="color: '.$defaults->{'fontmenu'}.';">'.$defaults->{'fontmenu'}.'</span></td>';
         } else {          } else {
             $datatable .= '<td>&nbsp;</td>';              $datatable .= '<td>&nbsp;</td>';
         }          }
  $current_color = $designs->{'fontmenu'} ?   $current_color = $designs->{'fontmenu'} ? 
     $designs->{'fontmenu'} : $defaults->{'fontmenu'};      $designs->{'fontmenu'} : $defaults->{'fontmenu'};
         $datatable .= '<td><span class="LC_nobreak">'.          $datatable .= '<td><span class="LC_nobreak">'.
                       '<input class="colorchooser" type="text" size="10" name="'                        '<input class="colorchooser" type="text" size="10" name="'
       .$role.'_fontmenu"'.        .$role.'_fontmenu"'.
                       ' value="'.$current_color.'" />&nbsp;'.                        ' value="'.$current_color.'" />&nbsp;'.
                       '&nbsp;</span></td></tr>';                        '&nbsp;</td></tr>';
     }      }
     my $switchserver = &check_switchserver($dom,$confname);      my $switchserver = &check_switchserver($dom,$confname);
     foreach my $img (@{$images}) {      foreach my $img (@{$images}) {
Line 1477  sub display_color_options { Line 1260  sub display_color_options {
                     &login_header_options($img,$role,$defaults,$is_custom,$choices);                      &login_header_options($img,$role,$defaults,$is_custom,$choices);
                 $logincolors =                  $logincolors =
                     &login_text_colors($img,$role,$logintext,$phase,$choices,                      &login_text_colors($img,$role,$logintext,$phase,$choices,
                                        $designs,$defaults);                                              $designs);
             } elsif ($img ne 'domlogo') {              } elsif ($img ne 'domlogo') {
                 $datatable.= &logo_display_options($img,$defaults,$designs);                  $datatable.= &logo_display_options($img,$defaults,$designs);
             }              }
Line 1521  sub display_color_options { Line 1304  sub display_color_options {
                         if ($fullwidth ne '' && $fullheight ne '') {                          if ($fullwidth ne '' && $fullheight ne '') {
                             if ($fullwidth > $width && $fullheight > $height) {                               if ($fullwidth > $width && $fullheight > $height) { 
                                 my $size = $width.'x'.$height;                                  my $size = $width.'x'.$height;
                                 my @args = ('convert','-sample',$size,$input,$output);                                  system("convert -sample $size $input $output");
                                 system({$args[0]} @args);  
                                 $showfile = "/$imgdir/tn-".$filename;                                  $showfile = "/$imgdir/tn-".$filename;
                             }                              }
                         }                          }
Line 1557  sub display_color_options { Line 1339  sub display_color_options {
                 $datatable .= &image_changes($is_custom->{$img},$alt_text->{$img},$img_import,                  $datatable .= &image_changes($is_custom->{$img},$alt_text->{$img},$img_import,
                                              $showfile,$fullsize,$role,$img,$imgfile,$logincolors);                                               $showfile,$fullsize,$role,$img,$imgfile,$logincolors);
             } else {              } else {
                 $datatable .= '<td>&nbsp;</td><td class="LC_left_item">'.                  $datatable .= '<td colspan="2" class="LC_right_item"><br />'.
                               &mt('Upload:').'<br />';                                &mt('Upload:');
             }              }
         } else {          } else {
             $datatable .= '<td>&nbsp;</td><td class="LC_left_item">'.              $datatable .= '<td colspan="2" class="LC_right_item"><br />'.
                           &mt('Upload:').'<br />';                            &mt('Upload:');
         }          }
         if ($switchserver) {          if ($switchserver) {
             $datatable .= &mt('Upload to library server: [_1]',$switchserver);              $datatable .= &mt('Upload to library server: [_1]',$switchserver);
Line 1580  sub display_color_options { Line 1362  sub display_color_options {
     my $bgs_def;      my $bgs_def;
     foreach my $item (@{$bgs}) {      foreach my $item (@{$bgs}) {
         if (!$is_custom->{$item}) {          if (!$is_custom->{$item}) {
             $bgs_def .= '<td><span class="LC_nobreak">'.$choices->{$item}.'</span>&nbsp;<span class="css_default_'.$role.'_'.$item.'" style="background-color: '.$defaults->{'bgs'}{$item}.';">&nbsp;&nbsp;&nbsp;</span><br />'.$defaults->{'bgs'}{$item}.'</td>';              $bgs_def .= '<td><span class="LC_nobreak">'.$choices->{$item}.'</span>&nbsp;<span id="css_default_'.$role.'_'.$item.'" style="background-color: '.$defaults->{'bgs'}{$item}.';">&nbsp;&nbsp;&nbsp;</span><br />'.$defaults->{'bgs'}{$item}.'</td>';
         }          }
     }      }
     if ($bgs_def) {      if ($bgs_def) {
Line 1592  sub display_color_options { Line 1374  sub display_color_options {
                   '<table border="0"><tr>';                    '<table border="0"><tr>';
   
     foreach my $item (@{$bgs}) {      foreach my $item (@{$bgs}) {
         $datatable .= '<td align="center">'.$choices->{$item};          $datatable .= '<td align="center">';
  my $color = $designs->{'bgs'}{$item} ? $designs->{'bgs'}{$item} : $defaults->{'bgs'}{$item};   my $color = $designs->{'bgs'}{$item} ? $designs->{'bgs'}{$item} : $defaults->{'bgs'}{$item};
         if ($designs->{'bgs'}{$item}) {          if ($designs->{'bgs'}{$item}) {
             $datatable .= '&nbsp;';              $datatable .= '&nbsp;';
Line 1608  sub display_color_options { Line 1390  sub display_color_options {
     my $links_def;      my $links_def;
     foreach my $item (@{$links}) {      foreach my $item (@{$links}) {
         if (!$is_custom->{$item}) {          if (!$is_custom->{$item}) {
             $links_def .= '<td>'.$choices->{$item}.'<br /><span class="css_default_'.$role.'_'.$item.'" style="color: '.$defaults->{'links'}{$item}.';">'.$defaults->{'links'}{$item}.'</span></td>';              $links_def .= '<td>'.$choices->{$item}.'<br /><span id="css_default_'.$role.'_'.$item.'" style="color: '.$defaults->{'links'}{$item}.';">'.$defaults->{'links'}{$item}.'</span></td>';
         }          }
     }      }
     if ($links_def) {      if ($links_def) {
Line 1619  sub display_color_options { Line 1401  sub display_color_options {
     $datatable .= '<td class="LC_right_item">'.      $datatable .= '<td class="LC_right_item">'.
                   '<table border="0"><tr>';                    '<table border="0"><tr>';
     foreach my $item (@{$links}) {      foreach my $item (@{$links}) {
  my $color = $designs->{'links'}{$item} ? $designs->{'links'}{$item} : $defaults->{'links'}{$item};   my $color = $designs->{'link'}{$item} ? $designs->{'link'}{$item} : $defaults->{'links'}{$item};
         $datatable .= '<td align="center">'.$choices->{$item}."\n";          $datatable .= '<td align="center">'."\n";
   
         if ($designs->{'links'}{$item}) {          if ($designs->{'links'}{$item}) {
             $datatable.='&nbsp;';              $datatable.='&nbsp;';
         }          }
Line 1678  sub login_header_options  { Line 1461  sub login_header_options  {
 }  }
   
 sub login_text_colors {  sub login_text_colors {
     my ($img,$role,$logintext,$phase,$choices,$designs,$defaults) = @_;      my ($img,$role,$logintext,$phase,$choices,$designs) = @_;
     my $color_menu = '<table border="0"><tr>';      my $color_menu = '<table border="0"><tr>';
     foreach my $item (@{$logintext}) {      foreach my $item (@{$logintext}) {
         $color_menu .= '<td align="center">'.$choices->{$item};          my $link = &color_pick($phase,$role,$item,$choices->{$item},$designs->{'logintext'}{$item});
         my $color = $designs->{'logintext'}{$item} ? $designs->{'logintext'}{$item} : $defaults->{'logintext'}{$item};          $color_menu .= '<td align="center">'.$link;
         $color_menu .= '<br /><input type="text" class="colorchooser" size="8" name="'.$role.'_'.$item.'" value="'.$color.          if ($designs->{'logintext'}{$item}) {
                       '" onblur = "javascript:colchg_span('."'css_".$role.'_'.$item."'".',this);" /></td>';              $color_menu .= '&nbsp;<span id="css_'.$role.'_'.$item.'" style="background-color: '.$designs->{'logintext'}{$item}.';">&nbsp;&nbsp;&nbsp;</span>';
           }
           $color_menu .= '<br /><input type="text" size="8" name="'.$role.'_'.$item.'" value="'.
                          $designs->{'logintext'}{$item}.'" onblur = "javascript:colchg_span('."'css_".$role.'_'.$item."'".',this);" /></td>'.
                          '<td>&nbsp;</td>';
     }      }
     $color_menu .= '</tr></table><br />';      $color_menu .= '</tr></table><br />';
     return $color_menu;      return $color_menu;
Line 1694  sub image_changes { Line 1481  sub image_changes {
     my ($is_custom,$alt_text,$img_import,$showfile,$fullsize,$role,$img,$imgfile,$logincolors) = @_;      my ($is_custom,$alt_text,$img_import,$showfile,$fullsize,$role,$img,$imgfile,$logincolors) = @_;
     my $output;      my $output;
     if ($img eq 'login') {      if ($img eq 'login') {
         $output = '</td><td>'.$logincolors; # suppress image for Log-in header              # suppress image for Log-in header
     } elsif (!$is_custom) {      } elsif (!$is_custom) {
         if ($img ne 'domlogo') {          if ($img ne 'domlogo') {
             $output = &mt('Default image:').'<br />';              $output .= &mt('Default image:').'<br />';
         } else {          } else {
             $output = &mt('Default in use:').'<br />';              $output .= &mt('Default in use:').'<br />';
         }          }
     }      }
     if ($img ne 'login') {      if ($img eq 'login') { # suppress image for Log-in header
           $output .= '<td>'.$logincolors;
       } else {
         if ($img_import) {          if ($img_import) {
             $output .= '<input type="hidden" name="'.$role.'_import_'.$img.'" value="'.$imgfile.'" />';              $output .= '<input type="hidden" name="'.$role.'_import_'.$img.'" value="'.$imgfile.'" />';
         }          }
Line 1714  sub image_changes { Line 1503  sub image_changes {
                        $role.'_del_'.$img.'" value="1" />'.&mt('Delete?').                         $role.'_del_'.$img.'" value="1" />'.&mt('Delete?').
                        '</label>&nbsp;'.&mt('Replace:').'</span><br />';                         '</label>&nbsp;'.&mt('Replace:').'</span><br />';
         } else {          } else {
             $output .= '<td valign="middle">'.$logincolors.&mt('Upload:').'<br />';              $output .= '<td valign="bottom">'.$logincolors.&mt('Upload:').'<br />';
         }          }
     }      }
     return $output;      return $output;
 }  }
   
   sub color_pick {
       my ($phase,$role,$item,$desc,$curcol) = @_;
       my $link = '<a href="javascript:pjump('."'color_custom','".$desc.
                  "','".$curcol."','".$role.'_'.$item."','parmform.pres','psub'".
                  ');">'.$desc.'</a>';
       return $link;
   }
   
 sub print_quotas {  sub print_quotas {
     my ($dom,$settings,$rowtotal,$action) = @_;      my ($dom,$settings,$rowtotal,$action) = @_;
     my $context;      my $context;
Line 1733  sub print_quotas { Line 1530  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');
         @options =('norequest','approval','validate','autolimit');          @options =('norequest','approval','validate','autolimit');
         %validations = &Apache::lonnet::auto_courserequest_checks($dom);          %validations = &Apache::lonnet::auto_courserequest_checks($dom);
         %titles = &courserequest_titles();          %titles = &courserequest_titles();
     } elsif ($context eq 'requestauthor') {      } elsif ($context eq 'requestauthor') {
         @usertools = ('author');          @usertools = ('author');
         @options = ('norequest','approval','automatic');          @options = ('norequest','approval','automatic');
         %titles = &authorrequest_titles();          %titles = &authorrequest_titles(); 
     } else {      } else {
         @usertools = ('aboutme','blog','webdav','portfolio');          @usertools = ('aboutme','blog','webdav','portfolio');
         %titles = &tool_titles();          %titles = &tool_titles();
Line 2147  sub print_quotas { Line 1944  sub print_quotas {
   
 sub print_requestmail {  sub print_requestmail {
     my ($dom,$action,$settings,$rowtotal) = @_;      my ($dom,$action,$settings,$rowtotal) = @_;
     my ($now,$datatable,%currapp);      my ($now,$datatable,%currapp,$rows);
     $now = time;      $now = time;
     if (ref($settings) eq 'HASH') {      if (ref($settings) eq 'HASH') {
         if (ref($settings->{'notify'}) eq 'HASH') {          if (ref($settings->{'notify'}) eq 'HASH') {
             if ($settings->{'notify'}{'approval'} ne '') {              if ($settings->{'notify'}{'approval'} ne '') {
                 map {$currapp{$_}=1;} split(/,/,$settings->{'notify'}{'approval'});                 map {$currapp{$_}=1;} split(/,/,$settings->{'notify'}{'approval'});
             }              }
         }          }
     }      }
     my $numinrow = 2;      my $numinrow = 2;
     my $css_class;      my $css_class = 'class="LC_odd_row"';
     $css_class = ($$rowtotal%2? ' class="LC_odd_row"':'');  
     my $text;      my $text;
     if ($action eq 'requestcourses') {      if ($action eq 'requestcourses') {
         $text = &mt('Receive notification of course requests requiring approval');          $text = &mt('Receive notification of course requests requiring approval');
     } elsif ($action eq 'requestauthor') {  
         $text = &mt('Receive notification of Authoring Space requests requiring approval');  
     } else {      } else {
        $text = &mt('Receive notification of queued requests for self-created user accounts requiring approval');          $text = &mt('Receive notification of authoring space requests requiring approval')
     }      }
     $datatable = '<tr'.$css_class.'>'.      $datatable = '<tr '.$css_class.'>'.
                  ' <td>'.$text.'</td>'.                   ' <td>'.$text.'</td>'.
                  ' <td class="LC_left_item">';                   ' <td class="LC_left_item">';
     my ($numdc,$table,$rows) = &active_dc_picker($dom,$numinrow,'checkbox',      my ($numdc,$table,$rows) = &active_dc_picker($dom,$numinrow,'checkbox',
                                                  $action.'notifyapproval',%currapp);                                                   'reqapprovalnotify',%currapp);
     if ($numdc > 0) {      if ($numdc > 0) {
         $datatable .= $table;          $datatable .= $table;
     } else {      } else {
         $datatable .= &mt('There are no active Domain Coordinators');          $datatable .= &mt('There are no active Domain Coordinators');
     }      }
     $datatable .='</td></tr>';      $datatable .='</td></tr>';
       $$rowtotal += $rows;
     return $datatable;      return $datatable;
 }  }
   
 sub print_studentcode {  
     my ($settings,$rowtotal) = @_;  
     my $rownum = 0;   
     my ($output,%current);  
     my @crstypes = ('official','unofficial','community','textbook');  
     if (ref($settings) eq 'HASH') {  
         if (ref($settings->{'uniquecode'}) eq 'HASH') {  
             foreach my $type (@crstypes) {  
                 $current{$type} = $settings->{'uniquecode'}{$type};  
             }  
         }  
     }  
     $output .= '<tr>'.  
                '<td class="LC_left_item">'.&mt('Generate unique six character code as course identifier?').'</td>'.  
                '<td class="LC_left_item">';  
     foreach my $type (@crstypes) {  
         my $check = ' ';  
         if ($current{$type}) {  
             $check = ' checked="checked" ';  
         }  
         $output .= '<span class="LC_nobreak"><label>'.  
                    '<input type="checkbox" name="uniquecode" value="'.$type.'"'.$check.'/>'.  
                    &mt($type).'</label></span>'.('&nbsp;'x2).' ';  
     }  
     $output .= '</td></tr>';  
     $$rowtotal ++;  
     return $output;  
 }  
   
 sub print_textbookcourses {  
     my ($dom,$type,$settings,$rowtotal) = @_;  
     my $rownum = 0;  
     my $css_class;  
     my $itemcount = 1;  
     my $maxnum = 0;  
     my $bookshash;  
     if (ref($settings) eq 'HASH') {  
         $bookshash = $settings->{$type};  
     }  
     my %ordered;  
     if (ref($bookshash) eq 'HASH') {  
         foreach my $item (keys(%{$bookshash})) {  
             if (ref($bookshash->{$item}) eq 'HASH') {  
                 my $num = $bookshash->{$item}{'order'};  
                 $ordered{$num} = $item;  
             }  
         }  
     }  
     my $confname = $dom.'-domainconfig';  
     my $switchserver = &check_switchserver($dom,$confname);  
     my $maxnum = scalar(keys(%ordered));  
     my $datatable;  
     if (keys(%ordered)) {  
         my @items = sort { $a <=> $b } keys(%ordered);  
         for (my $i=0; $i<@items; $i++) {  
             $css_class = $itemcount%2?' class="LC_odd_row"':'';  
             my $key = $ordered{$items[$i]};  
             my %coursehash=&Apache::lonnet::coursedescription($key);  
             my $coursetitle = $coursehash{'description'};  
             my ($subject,$title,$author,$publisher,$image,$imgsrc,$cdom,$cnum);  
             if (ref($bookshash->{$key}) eq 'HASH') {  
                 $subject = $bookshash->{$key}->{'subject'};  
                 $title = $bookshash->{$key}->{'title'};  
                 if ($type eq 'textbooks') {  
                     $publisher = $bookshash->{$key}->{'publisher'};  
                     $author = $bookshash->{$key}->{'author'};  
                     $image = $bookshash->{$key}->{'image'};  
                     if ($image ne '') {  
                         my ($path,$imagefile) = ($image =~ m{^(.+)/([^/]+)$});  
                         my $imagethumb = "$path/tn-".$imagefile;  
                         $imgsrc = '<img src="'.$imagethumb.'" alt="'.&mt('Textbook image').'" />';  
                     }  
                 }  
             }  
             my $chgstr = ' onchange="javascript:reorderBooks(this.form,'."'$type".'_'."$key','$type'".');"';  
             $datatable .= '<tr '.$css_class.'><td><span class="LC_nobreak">'  
                          .'<select name="'.$type.'_'.$key.'"'.$chgstr.'>';  
             for (my $k=0; $k<=$maxnum; $k++) {  
                 my $vpos = $k+1;  
                 my $selstr;  
                 if ($k == $i) {  
                     $selstr = ' selected="selected" ';  
                 }  
                 $datatable .= '<option value="'.$k.'"'.$selstr.'>'.$vpos.'</option>';  
             }  
             $datatable .= '</select>'.('&nbsp;'x2).  
                 '<label><input type="checkbox" name="'.$type.'_del" value="'.$key.'" />'.  
                 &mt('Delete?').'</label></span></td>'.  
                 '<td colspan="2">'.  
                 '<span class="LC_nobreak">'.&mt('Subject:').'<input type="text" size="15" name="'.$type.'_subject_'.$i.'" value="'.$subject.'" /></span> '.  
                 ('&nbsp;'x2).  
                 '<span class="LC_nobreak">'.&mt('Title:').'<input type="text" size="30" name="'.$type.'_title_'.$i.'" value="'.$title.'" /></span> ';  
             if ($type eq 'textbooks') {  
                 $datatable .= ('&nbsp;'x2).  
                               '<span class="LC_nobreak">'.&mt('Publisher:').'<input type="text" size="10" name="'.$type.'_publisher_'.$i.'" value="'.$publisher.'" /></span> '.  
                               ('&nbsp;'x2).  
                               '<span class="LC_nobreak">'.&mt('Author(s):').'<input type="text" size="25" name="'.$type.'_author_'.$i.'" value="'.$author.'" /></span> '.  
                               ('&nbsp;'x2).  
                               '<span class="LC_nobreak">'.&mt('Thumbnail:');  
                 if ($image) {  
                     $datatable .= '<span class="LC_nobreak">'.  
                                   $imgsrc.  
                                   '<label><input type="checkbox" name="'.$type.'_image_del"'.  
                                   ' value="'.$key.'" />'.&mt('Delete?').'</label></span> '.  
                                   '<span class="LC_nobreak">&nbsp;'.&mt('Replace:').'&nbsp;';  
                 }  
                 if ($switchserver) {  
                     $datatable .= &mt('Upload to library server: [_1]',$switchserver);  
                 } else {  
                     $datatable .= '<input type="file" name="'.$type.'_image_'.$i.'" value="" />';  
                 }  
             }  
             $datatable .= '<input type="hidden" name="'.$type.'_id_'.$i.'" value="'.$type.'_'.$key.'" /></span> '.  
                           '<span class="LC_nobreak">'.&mt('LON-CAPA course:').'&nbsp;'.  
                           $coursetitle.'</span></td></tr>'."\n";  
             $itemcount ++;  
         }  
     }  
     $css_class = $itemcount%2?' class="LC_odd_row"':'';  
     my $chgstr = ' onchange="javascript:reorderBooks(this.form,'."'$type"."_addbook_pos','$type'".');"';  
     $datatable .= '<tr '.$css_class.'><td><span class="LC_nobreak">'."\n".  
                   '<input type="hidden" name="'.$type.'_maxnum" value="'.$maxnum.'" />'."\n".  
                   '<select name="'.$type.'_addbook_pos"'.$chgstr.'>';  
     for (my $k=0; $k<$maxnum+1; $k++) {  
         my $vpos = $k+1;  
         my $selstr;  
         if ($k == $maxnum) {  
             $selstr = ' selected="selected" ';  
         }  
         $datatable .= '<option value="'.$k.'"'.$selstr.'>'.$vpos.'</option>';  
     }  
     $datatable .= '</select>&nbsp;'."\n".  
                   '<input type="checkbox" name="'.$type.'_addbook" value="1" />'.&mt('Add').'</span></td>'."\n".  
                   '<td colspan="2">'.  
                   '<span class="LC_nobreak">'.&mt('Subject:').'<input type="text" size="15" name="'.$type.'_addbook_subject" value="" /></span> '."\n".  
                   ('&nbsp;'x2).  
                   '<span class="LC_nobreak">'.&mt('Title:').'<input type="text" size="30" name="'.$type.'_addbook_title" value="" /></span> '."\n".  
                   ('&nbsp;'x2);  
     if ($type eq 'textbooks') {  
         $datatable .= '<span class="LC_nobreak">'.&mt('Publisher:').'<input type="text" size="10" name="'.$type.'_addbook_publisher" value="" /></span> '."\n".  
                       ('&nbsp;'x2).  
                       '<span class="LC_nobreak">'.&mt('Author(s):').'<input type="text" size="25" name="'.$type.'_addbook_author" value="" /></span> '."\n".  
                       ('&nbsp;'x2).  
                       '<span class="LC_nobreak">'.&mt('Image:').'&nbsp;';  
         if ($switchserver) {  
             $datatable .= &mt('Upload to library server: [_1]',$switchserver);  
         } else {  
             $datatable .= '<input type="file" name="'.$type.'_addbook_image" value="" />';  
         }  
         $datatable .= '</span>'."\n";  
     }  
     $datatable .= '<span class="LC_nobreak">'.&mt('LON-CAPA course:').'&nbsp;'.  
                   &Apache::loncommon::select_dom_form($env{'request.role.domain'},$type.'_addbook_cdom').  
                   '<input type="text" size="25" name="'.$type.'_addbook_cnum" value="" />'.  
                   &Apache::loncommon::selectcourse_link  
                       ('display',$type.'_addbook_cnum',$type.'_addbook_cdom',undef,undef,undef,'Course').  
                   '</span></td>'."\n".  
                   '</tr>'."\n";  
     $itemcount ++;  
     return $datatable;  
 }  
   
 sub textbookcourses_javascript {  
     my ($settings) = @_;  
     return unless(ref($settings) eq 'HASH');  
     my (%ordered,%total,%jstext);  
     foreach my $type ('textbooks','templates') {  
         $total{$type} = 0;  
         if (ref($settings->{$type}) eq 'HASH') {  
             foreach my $item (keys(%{$settings->{$type}})) {  
                 if (ref($settings->{$type}->{$item}) eq 'HASH') {  
                     my $num = $settings->{$type}->{$item}{'order'};  
                     $ordered{$type}{$num} = $item;  
                 }  
             }  
             $total{$type} = scalar(keys(%{$settings->{$type}}));  
         }  
         my @jsarray = ();  
         foreach my $item (sort {$a <=> $b } (keys(%{$ordered{$type}}))) {  
             push(@jsarray,$ordered{$type}{$item});  
         }  
         $jstext{$type} = '    var '.$type.' = Array('."'".join("','",@jsarray)."'".');'."\n";  
     }  
     return <<"ENDSCRIPT";  
 <script type="text/javascript">  
 // <![CDATA[  
 function reorderBooks(form,item,caller) {  
     var changedVal;  
 $jstext{'textbooks'};  
 $jstext{'templates'};  
     var newpos;  
     var maxh;  
     if (caller == 'textbooks') {    
         newpos = 'textbooks_addbook_pos';  
         maxh = 1 + $total{'textbooks'};  
     } else {  
         newpos = 'templates_addbook_pos';  
         maxh = 1 + $total{'templates'};  
     }  
     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;  
     }  
     if (caller == 'textbooks') {  
         for (var i=0; i<textbooks.length; i++) {  
             var elementName = 'textbooks_'+textbooks[i];  
             if (elementName != item) {  
                 if (form.elements[elementName]) {  
                     var currVal = form.elements[elementName].options[form.elements[elementName].selectedIndex].value;  
                     current[currVal] = elementName;  
                 }  
             }  
         }  
     }  
     if (caller == 'templates') {  
         for (var i=0; i<templates.length; i++) {  
             var elementName = 'templates_'+templates[i];  
             if (elementName != item) {  
                 if (form.elements[elementName]) {  
                     var currVal = form.elements[elementName].options[form.elements[elementName].selectedIndex].value;  
                     current[currVal] = elementName;  
                 }  
             }  
         }  
     }  
     var oldVal;  
     for (var j=0; j<maxh; j++) {  
         if (current[j] == undefined) {  
             oldVal = j;  
         }  
     }  
     if (oldVal < changedVal) {  
         for (var k=oldVal+1; k<=changedVal ; k++) {  
            var elementName = current[k];  
            form.elements[elementName].selectedIndex = form.elements[elementName].selectedIndex - 1;  
         }  
     } else {  
         for (var k=changedVal; k<oldVal; k++) {  
             var elementName = current[k];  
             form.elements[elementName].selectedIndex = form.elements[elementName].selectedIndex + 1;  
         }  
     }  
     return;  
 }  
   
 // ]]>  
 </script>  
   
 ENDSCRIPT  
 }  
   
 sub print_autoenroll {  sub print_autoenroll {
     my ($dom,$settings,$rowtotal) = @_;      my ($dom,$settings,$rowtotal) = @_;
     my $autorun = &Apache::lonnet::auto_run(undef,$dom),      my $autorun = &Apache::lonnet::auto_run(undef,$dom),
     my ($defdom,$runon,$runoff,$coownerson,$coownersoff,$failsafe);      my ($defdom,$runon,$runoff,$coownerson,$coownersoff);
     if (ref($settings) eq 'HASH') {      if (ref($settings) eq 'HASH') {
         if (exists($settings->{'run'})) {          if (exists($settings->{'run'})) {
             if ($settings->{'run'} eq '0') {              if ($settings->{'run'} eq '0') {
Line 2473  sub print_autoenroll { Line 2013  sub print_autoenroll {
         if (exists($settings->{'sender_domain'})) {          if (exists($settings->{'sender_domain'})) {
             $defdom = $settings->{'sender_domain'};              $defdom = $settings->{'sender_domain'};
         }          }
         if (exists($settings->{'autofailsafe'})) {  
             $failsafe = $settings->{'autofailsafe'};  
         }  
     } else {      } else {
         if ($autorun) {          if ($autorun) {
             $runon = ' checked="checked" ';              $runon = ' checked="checked" ';
Line 2511  sub print_autoenroll { Line 2048  sub print_autoenroll {
                   $coownerson.' value="1" />'.&mt('Yes').'</label>&nbsp;'.                    $coownerson.' value="1" />'.&mt('Yes').'</label>&nbsp;'.
                   '<label><input type="radio" name="autoassign_coowners"'.                    '<label><input type="radio" name="autoassign_coowners"'.
                   $coownersoff.' value="0" />'.&mt('No').'</label></span></td>'.                    $coownersoff.' value="0" />'.&mt('No').'</label></span></td>'.
                   '</tr><tr>'.                    '</tr>';
                   '<td>'.&mt('Failsafe for no drops when institutional data missing').'</td>'.      $$rowtotal += 3;
                   '<td class="LC_right_item"><span class="LC_nobreak">'.  
                   '<input type="text" name="autoenroll_failsafe"'.  
                   ' value="'.$failsafe.'" size="4" /></span></td></tr>';  
     $$rowtotal += 4;  
     return $datatable;      return $datatable;
 }  }
   
Line 2604  sub print_autocreate { Line 2137  sub print_autocreate {
                 }                  }
             }              }
         }          }
         if ($settings->{'xmldc'} ne '') {          if ($settings->{'xmldc'} ne '') { 
             $currhash{$settings->{'xmldc'}} = 1;              $currhash{$settings->{'xmldc'}} = 1;
         }          }
     } else {      } else {
Line 2631  sub print_autocreate { Line 2164  sub print_autocreate {
                   $createoff{'req'}.' value="0" />'.&mt('No').'</label></span>';                    $createoff{'req'}.' value="0" />'.&mt('No').'</label></span>';
     my ($numdc,$dctable,$rows) = &active_dc_picker($dom,$numinrow,'radio',      my ($numdc,$dctable,$rows) = &active_dc_picker($dom,$numinrow,'radio',
                                                    'autocreate_xmldc',%currhash);                                                     'autocreate_xmldc',%currhash);
     $datatable .= '</td></tr><tr class="LC_odd_row"><td>';  
     if ($numdc > 1) {      if ($numdc > 1) {
         $datatable .= &mt('Course creation processed as: (choose Dom. Coord.)').          $datatable .= '</td></tr><tr class="LC_odd_row"><td>'.
                       '</td><td class="LC_left_item">';                        &mt('Course creation processed as: (choose Dom. Coord.)').
                         '</td><td class="LC_left_item">'.$dctable.'</td></tr>';
     } else {      } else {
         $datatable .= &mt('Course creation processed as:').          $datatable .= $dctable.'</td></tr>';
                       '</td><td class="LC_right_item">';  
     }      }
     $datatable .= $dctable.'</td></tr>';  
     $$rowtotal += $rows;      $$rowtotal += $rows;
     return $datatable;      return $datatable;
 }  }
   
 sub print_directorysrch {  sub print_directorysrch {
     my ($position,$dom,$settings,$rowtotal) = @_;      my ($dom,$settings,$rowtotal) = @_;
     my $datatable;      my $srchon = ' ';
     if ($position eq 'top') {      my $srchoff = ' checked="checked" ';
         my $instsrchon = ' ';      my ($exacton,$containson,$beginson);
         my $instsrchoff = ' checked="checked" ';      my $localon = ' ';
         my ($exacton,$containson,$beginson);      my $localoff = ' checked="checked" ';
         my $instlocalon = ' ';      if (ref($settings) eq 'HASH') {
         my $instlocaloff = ' checked="checked" ';          if ($settings->{'available'} eq '1') {
         if (ref($settings) eq 'HASH') {              $srchon = $srchoff;
             if ($settings->{'available'} eq '1') {              $srchoff = ' ';
                 $instsrchon = $instsrchoff;          }
                 $instsrchoff = ' ';          if ($settings->{'localonly'} eq '1') {
             }              $localon = $localoff;
             if ($settings->{'localonly'} eq '1') {              $localoff = ' ';
                 $instlocalon = $instlocaloff;          }
                 $instlocaloff = ' ';          if (ref($settings->{'searchtypes'}) eq 'ARRAY') {
             }              foreach my $type (@{$settings->{'searchtypes'}}) {
             if (ref($settings->{'searchtypes'}) eq 'ARRAY') {                  if ($type eq 'exact') {
                 foreach my $type (@{$settings->{'searchtypes'}}) {  
                     if ($type eq 'exact') {  
                         $exacton = ' checked="checked" ';  
                     } elsif ($type eq 'contains') {  
                         $containson = ' checked="checked" ';  
                     } elsif ($type eq 'begins') {  
                         $beginson = ' checked="checked" ';  
                     }  
                 }  
             } else {  
                 if ($settings->{'searchtypes'} eq 'exact') {  
                     $exacton = ' checked="checked" ';  
                 } elsif ($settings->{'searchtypes'} eq 'contains') {  
                     $containson = ' checked="checked" ';  
                 } elsif ($settings->{'searchtypes'} eq 'specify') {  
                     $exacton = ' checked="checked" ';                      $exacton = ' checked="checked" ';
                   } elsif ($type eq 'contains') {
                     $containson = ' checked="checked" ';                      $containson = ' checked="checked" ';
                   } elsif ($type eq 'begins') {
                       $beginson = ' checked="checked" ';
                 }                  }
             }              }
         }          } else {
         my ($searchtitles,$titleorder) = &sorted_searchtitles();              if ($settings->{'searchtypes'} eq 'exact') {
         my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom);                  $exacton = ' checked="checked" ';
               } elsif ($settings->{'searchtypes'} eq 'contains') {
         my $numinrow = 4;                  $containson = ' checked="checked" ';
         my $cansrchrow = 0;              } elsif ($settings->{'searchtypes'} eq 'specify') {
         $datatable='<tr class="LC_odd_row">'.                  $exacton = ' checked="checked" ';
                    '<td colspan="2"><span class ="LC_nobreak">'.&mt('Institutional directory search available?').'</span></td>'.                  $containson = ' checked="checked" ';
                    '<td class="LC_right_item"><span class="LC_nobreak"><label>'.  
                    '<input type="radio" name="dirsrch_available"'.  
                    $instsrchon.' value="1" />'.&mt('Yes').'</label>&nbsp;'.  
                    '<label><input type="radio" name="dirsrch_available"'.  
                    $instsrchoff.' value="0" />'.&mt('No').'</label></span></td>'.  
                    '</tr><tr>'.  
                    '<td colspan="2"><span class ="LC_nobreak">'.&mt('Other domains can search institution?').'</span></td>'.  
                    '<td class="LC_right_item"><span class="LC_nobreak"><label>'.  
                    '<input type="radio" name="dirsrch_instlocalonly"'.  
                    $instlocaloff.' value="0" />'.&mt('Yes').'</label>&nbsp;'.  
                    '<label><input type="radio" name="dirsrch_instlocalonly"'.  
                    $instlocalon.' value="1" />'.&mt('No').'</label></span></td>'.  
                    '</tr>';  
         $$rowtotal += 2;  
         if (ref($usertypes) eq 'HASH') {  
             if (keys(%{$usertypes}) > 0) {  
                 $datatable .= &insttypes_row($settings,$types,$usertypes,$dom,  
                                              $numinrow,$othertitle,'cansearch');  
                 $cansrchrow = 1;  
             }              }
         }          }
         if ($cansrchrow) {      }
             $$rowtotal ++;      my ($searchtitles,$titleorder) = &sorted_searchtitles();
             $datatable .= '<tr>';      my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom);
         } else {  
             $datatable .= '<tr class="LC_odd_row">';      my $numinrow = 4;
       my $cansrchrow = 0;
       my $datatable='<tr class="LC_odd_row">'.
                     '<td colspan="2"><span class ="LC_nobreak">'.&mt('Directory search available?').'</span></td>'.
                     '<td class="LC_right_item"><span class="LC_nobreak"><label>'.
                     '<input type="radio" name="dirsrch_available"'.
                     $srchon.' value="1" />'.&mt('Yes').'</label>&nbsp;'.
                     '<label><input type="radio" name="dirsrch_available"'.
                     $srchoff.' value="0" />'.&mt('No').'</label></span></td>'.
                     '</tr><tr>'.
                     '<td colspan="2"><span class ="LC_nobreak">'.&mt('Other domains can search?').'</span></td>'.
                     '<td class="LC_right_item"><span class="LC_nobreak"><label>'.
                     '<input type="radio" name="dirsrch_localonly"'.
                     $localoff.' value="0" />'.&mt('Yes').'</label>&nbsp;'.
                     '<label><input type="radio" name="dirsrch_localonly"'.
                     $localon.' value="1" />'.&mt('No').'</label></span></td>'.
                     '</tr>';
       $$rowtotal += 2;
       if (ref($usertypes) eq 'HASH') {
           if (keys(%{$usertypes}) > 0) {
               $datatable .= &insttypes_row($settings,$types,$usertypes,$dom,
                                            $numinrow,$othertitle,'cansearch');
               $cansrchrow = 1;
         }          }
         $datatable .= '<td><span class ="LC_nobreak">'.&mt('Supported search methods').      }
                       '</span></td><td class="LC_left_item" colspan="2"><table><tr>';      if ($cansrchrow) {
         foreach my $title (@{$titleorder}) {          $$rowtotal ++;
             if (defined($searchtitles->{$title})) {          $datatable .= '<tr>';
                 my $check = ' ';      } else {
                 if (ref($settings) eq 'HASH') {          $datatable .= '<tr class="LC_odd_row">';
                     if (ref($settings->{'searchby'}) eq 'ARRAY') {      }
                         if (grep(/^\Q$title\E$/,@{$settings->{'searchby'}})) {      $datatable .= '<td><span class ="LC_nobreak">'.&mt('Supported search methods').
                             $check = ' checked="checked" ';                    '</span></td><td class="LC_left_item" colspan="2"><table><tr>';
                         }      foreach my $title (@{$titleorder}) {
           if (defined($searchtitles->{$title})) {
               my $check = ' ';
               if (ref($settings) eq 'HASH') {
                   if (ref($settings->{'searchby'}) eq 'ARRAY') {
                       if (grep(/^\Q$title\E$/,@{$settings->{'searchby'}})) {
                           $check = ' checked="checked" ';
                     }                      }
                 }                  }
                 $datatable .= '<td class="LC_left_item">'.  
                               '<span class="LC_nobreak"><label>'.  
                               '<input type="checkbox" name="searchby" '.  
                               'value="'.$title.'"'.$check.'/>'.  
                               $searchtitles->{$title}.'</label></span></td>';  
             }              }
               $datatable .= '<td class="LC_left_item">'.
                             '<span class="LC_nobreak"><label>'.
                             '<input type="checkbox" name="searchby" '.
                             'value="'.$title.'"'.$check.'/>'.
                             $searchtitles->{$title}.'</label></span></td>';
         }          }
         $datatable .= '</tr></table></td></tr>';      }
         $$rowtotal ++;      $datatable .= '</tr></table></td></tr>';
         if ($cansrchrow) {      $$rowtotal ++;
             $datatable .= '<tr class="LC_odd_row">';      if ($cansrchrow) {
         } else {          $datatable .= '<tr class="LC_odd_row">';
             $datatable .= '<tr>';  
         }  
         $datatable .= '<td><span class ="LC_nobreak">'.&mt('Search latitude').'</span></td>'.     
                       '<td class="LC_left_item" colspan="2">'.  
                       '<span class="LC_nobreak"><label>'.  
                       '<input type="checkbox" name="searchtypes" '.  
                       $exacton.' value="exact" />'.&mt('Exact match').  
                       '</label>&nbsp;'.  
                       '<label><input type="checkbox" name="searchtypes" '.  
                       $beginson.' value="begins" />'.&mt('Begins with').  
                       '</label>&nbsp;'.  
                       '<label><input type="checkbox" name="searchtypes" '.  
                       $containson.' value="contains" />'.&mt('Contains').  
                       '</label></span></td></tr>';  
         $$rowtotal ++;  
     } else {      } else {
         my $domsrchon = ' checked="checked" ';          $datatable .= '<tr>';
         my $domsrchoff = ' ';  
         my $domlocalon = ' ';  
         my $domlocaloff = ' checked="checked" ';  
         if (ref($settings) eq 'HASH') {  
             if ($settings->{'lclocalonly'} eq '1') {  
                 $domlocalon = $domlocaloff;  
                 $domlocaloff = ' ';  
             }  
             if ($settings->{'lcavailable'} eq '0') {  
                 $domsrchoff = $domsrchon;  
                 $domsrchon = ' ';  
             }  
         }  
         $datatable='<tr class="LC_odd_row">'.  
                       '<td colspan="2"><span class ="LC_nobreak">'.&mt('LON-CAPA directory search available?').'</span></td>'.  
                       '<td class="LC_right_item"><span class="LC_nobreak"><label>'.  
                       '<input type="radio" name="dirsrch_domavailable"'.  
                       $domsrchon.' value="1" />'.&mt('Yes').'</label>&nbsp;'.  
                       '<label><input type="radio" name="dirsrch_domavailable"'.  
                       $domsrchoff.' value="0" />'.&mt('No').'</label></span></td>'.  
                       '</tr><tr>'.  
                       '<td colspan="2"><span class ="LC_nobreak">'.&mt('Other domains can search LON-CAPA domain?').'</span></td>'.  
                       '<td class="LC_right_item"><span class="LC_nobreak"><label>'.  
                       '<input type="radio" name="dirsrch_domlocalonly"'.  
                       $domlocaloff.' value="0" />'.&mt('Yes').'</label>&nbsp;'.  
                       '<label><input type="radio" name="dirsrch_domlocalonly"'.  
                       $domlocalon.' value="1" />'.&mt('No').'</label></span></td>'.  
                       '</tr>';  
         $$rowtotal += 2;  
     }      }
       $datatable .= '<td><span class ="LC_nobreak">'.&mt('Search latitude').'</span></td>'.   
                     '<td class="LC_left_item" colspan="2">'.
                     '<span class="LC_nobreak"><label>'.
                     '<input type="checkbox" name="searchtypes" '.
                     $exacton.' value="exact" />'.&mt('Exact match').
                     '</label>&nbsp;'.
                     '<label><input type="checkbox" name="searchtypes" '.
                     $beginson.' value="begins" />'.&mt('Begins with').
                     '</label>&nbsp;'.
                     '<label><input type="checkbox" name="searchtypes" '.
                     $containson.' value="contains" />'.&mt('Contains').
                     '</label></span></td></tr>';
       $$rowtotal ++;
     return $datatable;      return $datatable;
 }  }
   
 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');
         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" ';  
         } 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) {          $rownum ++;
             $css_class = $rownum%2?' class="LC_odd_row"':'';          $css_class = $rownum%2?' class="LC_odd_row"':'';
             $datatable .= '<tr'.$css_class.'>'.           $datatable .= '<tr'.$css_class.'>'. 
                           '<td><span class="LC_nobreak">'.$titles->{$item}.                    '<td><span class="LC_nobreak">'.$titles->{$item}.
                           '</span></td><td class="LC_right_item">'.                    '</span></td><td class="LC_right_item">'.
                           '<input type="text" name="'.$item.'" value="'.                    '<input type="text" name="'.$item.'" value="'.
                           $to{$item}.'" /></td></tr>';                    $to{$item}.'" /></td></tr>';
             $rownum ++;  
         }  
     } 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;          $rownum ++;
         $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 ++;  
     }      }
     $$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 ($dom,$confname,$settings,$rowtotal) = @_;
     my $confname = $dom.'-domainconfig';  
     my $formname = 'display';  
     my ($datatable,$itemcount);      my ($datatable,$itemcount);
     if ($position eq 'top') {      $itemcount = 1;
         $itemcount = 1;      my (%choices,%defaultchecked,@toggles);
         my (%choices,%defaultchecked,@toggles);      $choices{'submitbugs'} = &mt('Display link to: [_1]?',
         $choices{'submitbugs'} = &mt('Display link to: [_1]?',                                   &Apache::loncommon::modal_link('http://bugs.loncapa.org',
                                      &Apache::loncommon::modal_link('http://bugs.loncapa.org',                                   &mt('LON-CAPA bug tracker'),600,500));
                                      &mt('LON-CAPA bug tracker'),600,500));      %defaultchecked = ('submitbugs' => 'on');
         %defaultchecked = ('submitbugs' => 'on');      @toggles = ('submitbugs',);
         @toggles = ('submitbugs');  
         ($datatable,$itemcount) = &radiobutton_prefs($settings,\@toggles,\%defaultchecked,  
                                                      \%choices,$itemcount);  
         $$rowtotal ++;  
     } else {  
         my $css_class;  
         my %existing=&Apache::lonnet::dump('roles',$dom,$confname,'rolesdef_');  
         my (%customroles,%ordered,%current);  
         if (ref($settings) eq 'HASH') {  
             if (ref($settings->{'adhoc'}) eq 'HASH') {  
                 %current = %{$settings->{'adhoc'}};  
             }  
         }  
         my $count = 0;  
         foreach my $key (sort(keys(%existing))) {  
             if ($key=~/^rolesdef\_(\w+)$/) {  
                 my $rolename = $1;  
                 my (%privs,$order);  
                 ($privs{'system'},$privs{'domain'},$privs{'course'}) = split(/\_/,$existing{$key});  
                 $customroles{$rolename} = \%privs;  
                 if (ref($current{$rolename}) eq 'HASH') {  
                     $order = $current{$rolename}{'order'};  
                 }  
                 if ($order eq '') {  
                     $order = $count;  
                 }  
                 $ordered{$order} = $rolename;  
                 $count++;  
             }  
         }  
         my $maxnum = scalar(keys(%ordered));  
         my @roles_by_num = ();  
         foreach my $item (sort {$a <=> $b } (keys(%ordered))) {  
             push(@roles_by_num,$item);  
         }  
         my $context = 'domprefs';  
         my $crstype = 'Course';  
         my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom);  
         my @accesstypes = ('all','dh','da','none');  
         my ($numstatustypes,@jsarray);  
         if (ref($types) eq 'ARRAY') {  
             if (@{$types} > 0) {  
                 $numstatustypes = scalar(@{$types});  
                 push(@accesstypes,'status');  
                 @jsarray = ('bystatus');  
             }  
         }  
         my %domhelpdesk = &Apache::lonnet::get_active_domroles($dom,['dh','da']);  
         if (keys(%domhelpdesk)) {  
             push(@accesstypes,('inc','exc'));  
             push(@jsarray,('notinc','notexc'));  
         }  
         my $hiddenstr = join("','",@jsarray);  
         $datatable .= &helpsettings_javascript(\@roles_by_num,$maxnum,$hiddenstr,$formname);  
         my $context = 'domprefs';  
         my $crstype = 'Course';  
         my $prefix = 'helproles_';  
         my $add_class = 'LC_hidden';  
         foreach my $num (@roles_by_num) {  
             my $role = $ordered{$num};  
             my ($desc,$access,@statuses);  
             if (ref($current{$role}) eq 'HASH') {  
                 $desc = $current{$role}{'desc'};  
                 $access = $current{$role}{'access'};  
                 if (ref($current{$role}{'insttypes'}) eq 'ARRAY') {  
                     @statuses = @{$current{$role}{'insttypes'}};  
                 }  
             }  
             if ($desc eq '') {  
                 $desc = $role;  
             }  
             my $identifier = 'custhelp'.$num;  
             my %full=();  
             my %levels= (  
                          course => {},  
                          domain => {},  
                          system => {},  
                         );  
             my %levelscurrent=(  
                                course => {},  
                                domain => {},  
                                system => {},  
                               );  
             &Apache::lonuserutils::custom_role_privs($customroles{$role},\%full,\%levels,\%levelscurrent);  
             my @templateroles = &Apache::lonuserutils::custom_template_roles($context,$crstype);  
             $css_class = $itemcount%2?' class="LC_odd_row"':'';  
             my $chgstr = ' onchange="javascript:reorderHelpRoles(this.form,'."'helproles_".$num."_pos'".');"';  
             $datatable .= '<tr '.$css_class.'><td valign="top"><b>'.$role.'</b><br />'.  
                           '<select name="helproles_'.$num.'_pos"'.$chgstr.'>';  
             for (my $k=0; $k<=$maxnum; $k++) {  
                 my $vpos = $k+1;  
                 my $selstr;  
                 if ($k == $num) {  
                     $selstr = ' selected="selected" ';  
                 }  
                 $datatable .= '<option value="'.$k.'"'.$selstr.'>'.$vpos.'</option>';  
             }  
             $datatable .= '</select>'.('&nbsp;'x2).  
                           '<input type="hidden" name="helproles_'.$num.'" value="'.$role.'" />'.  
                           '</td>'.  
                           '<td><fieldset><legend>'.&mt('Role name').'</legend>'.  
                           &mt('Name shown to users:').  
                           '<input type="text" name="helproles_'.$num.'_desc" value="'.$desc.'" />'.  
                           '</fieldset>'.  
                           &helpdeskroles_access($dom,$prefix,$num,$add_class,$current{$role},\@accesstypes,  
                                                 $othertitle,$usertypes,$types,\%domhelpdesk).  
                           '<fieldset>'.  
                           '<legend>'.&mt('Role privileges').&adhocbutton($prefix,$num,'privs','show').'</legend>'.  
                           &Apache::lonuserutils::custom_role_table($crstype,\%full,\%levels,  
                                                                    \%levelscurrent,$identifier,  
                                                                    'LC_hidden',$prefix.$num.'_privs').  
                           '</fieldset></td>';  
             $itemcount ++;  
         }  
         $css_class = $itemcount%2?' class="LC_odd_row"':'';  
         my $newcust = 'custhelp'.$count;  
         my (%privs,%levelscurrent);  
         my %full=();  
         my %levels= (  
                      course => {},  
                      domain => {},  
                      system => {},  
                     );  
         &Apache::lonuserutils::custom_role_privs(\%privs,\%full,\%levels,\%levelscurrent);  
         my @templateroles = &Apache::lonuserutils::custom_template_roles($context,$crstype);  
         my $chgstr = ' onchange="javascript:reorderHelpRoles(this.form,'."'helproles_".$count."_pos'".');"';  
         $datatable .= '<tr '.$css_class.'><td valign="top"><span class="LC_nobreak"><label>'.  
                       '<input type="hidden" name="helproles_maxnum" value="'.$maxnum.'" />'."\n".  
                       '<select name="helproles_'.$count.'_pos"'.$chgstr.'>';  
         for (my $k=0; $k<$maxnum+1; $k++) {  
             my $vpos = $k+1;  
             my $selstr;  
             if ($k == $maxnum) {  
                 $selstr = ' selected="selected" ';  
             }  
             $datatable .= '<option value="'.$k.'"'.$selstr.'>'.$vpos.'</option>';  
         }  
         $datatable .= '</select>&nbsp;'."\n".  
                       '<input type="checkbox" name="newcusthelp" value="'.$count.'" />'. &mt('Add').  
                       '</label></span></td>'.  
                       '<td><fieldset><legend>'.&mt('Role name').'</legend>'.  
                       '<span class="LC_nobreak">'.  
                       &mt('Internal name:').  
                       '<input type="text" size="10" name="custhelpname'.$count.'" value="" />'.  
                       '</span>'.('&nbsp;'x4).  
                       '<span class="LC_nobreak">'.  
                       &mt('Name shown to users:').  
                       '<input type="text" size="20" name="helproles_'.$count.'_desc" value="" />'.  
                       '</span></fieldset>'.  
                        &helpdeskroles_access($dom,$prefix,$count,'',undef,\@accesstypes,$othertitle,  
                                              $usertypes,$types,\%domhelpdesk).  
                       '<fieldset><legend>'.&mt('Role privileges').'</legend>'.  
                       &Apache::lonuserutils::custom_role_header($context,$crstype,  
                                                                 \@templateroles,$newcust).  
                       &Apache::lonuserutils::custom_role_table('Course',\%full,\%levels,  
                                                                \%levelscurrent,$newcust).  
                       '</fieldset>'.  
                       &helpsettings_javascript(\@roles_by_num,$maxnum,$hiddenstr,$formname).  
                       '</td></tr>';  
         $count ++;  
         $$rowtotal += $count;  
     }  
     return $datatable;  
 }  
   
 sub adhocbutton {  
     my ($prefix,$num,$field,$visibility) = @_;  
     my %lt = &Apache::lonlocal::texthash(  
                                           show => 'Show details',  
                                           hide => 'Hide details',  
                                         );  
     return '<span style="text-decoration:line-through; font-weight: normal;">'.('&nbsp;'x10).  
            '</span>'.('&nbsp;'x2).'<input type="button" id="'.$prefix.$num.'_'.$field.'_vis"'.  
            ' value="'.$lt{$visibility}.'" style="height:20px;" '.  
            'onclick="toggleHelpdeskItem('."'$num','$field'".');" />'.('&nbsp;'x2);  
 }  
   
 sub helpsettings_javascript {  
     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) {      ($datatable,$itemcount) = &radiobutton_prefs($settings,\@toggles,\%defaultchecked,
     if (document.getElementById('helproles_'+num+'_'+field)) {                                                   \%choices,$itemcount);
         if (document.getElementById('helproles_'+num+'_'+field).className.match(/(?:^|\\s)LC_hidden(?!\\S)/)) {      return $datatable;
             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) = @_;
     return unless ((ref($toggles) eq 'ARRAY') && (ref($defaultchecked) eq 'HASH') &&      return unless ((ref($toggles) eq 'ARRAY') && (ref($defaultchecked) eq 'HASH') &&
                    (ref($choices) eq 'HASH'));                     (ref($choices) eq 'HASH'));
   
Line 3462  sub radiobutton_prefs { Line 2425  sub radiobutton_prefs {
         $datatable .=          $datatable .=
             '<tr'.$css_class.'><td valign="top">'.              '<tr'.$css_class.'><td valign="top">'.
             '<span class="LC_nobreak">'.$choices->{$item}.              '<span class="LC_nobreak">'.$choices->{$item}.
             '</span></td>';              '</span></td>'.
         if ($align eq 'left') {              '<td class="LC_right_item"><span class="LC_nobreak">'.
             $datatable .= '<td class="LC_left_item">';  
         } else {  
             $datatable .= '<td class="LC_right_item">';  
         }  
         $datatable .=  
             '<span class="LC_nobreak">'.  
             '<label><input type="radio" name="'.              '<label><input type="radio" name="'.
             $item.'" '.$checkedon{$item}.' value="1"'.$onclick.' />'.&mt('Yes').              $item.'" '.$checkedon{$item}.' value="1"'.$onclick.' />'.&mt('Yes').
             '</label>&nbsp;<label><input type="radio" name="'.$item.'" '.              '</label>&nbsp;<label><input type="radio" name="'.$item.'" '.
Line 3487  sub print_coursedefaults { Line 2444  sub print_coursedefaults {
     my ($css_class,$datatable,%checkedon,%checkedoff,%defaultchecked,@toggles);      my ($css_class,$datatable,%checkedon,%checkedoff,%defaultchecked,@toggles);
     my $itemcount = 1;      my $itemcount = 1;
     my %choices =  &Apache::lonlocal::texthash (      my %choices =  &Apache::lonlocal::texthash (
           canuse_pdfforms      => 'Course/Community users can create/upload PDF forms',
         uploadquota          => 'Default quota for files uploaded directly to course/community using Course Editor (MB)',          uploadquota          => 'Default quota for files uploaded directly to course/community using Course Editor (MB)',
         anonsurvey_threshold => 'Responder count needed before showing submissions for anonymous surveys',          anonsurvey_threshold => 'Responder count needed before showing submissions for anonymous surveys',
         coursecredits        => 'Credits can be specified for courses',          coursecredits        => 'Credits can be specified for courses',
         uselcmath            => 'Math preview uses LON-CAPA previewer (javascript) in place of DragMath (Java)',  
         usejsme              => 'Molecule editor uses JSME (HTML5) in place of JME (Java)',  
         postsubmit           => 'Disable submit button/keypress following student submission',  
         canclone             => "People who may clone a course (besides course's owner and coordinators)",  
         mysqltables          => 'Lifetime (s) of "Temporary" MySQL tables (student performance data) on homeserver',  
     );      );
     my %staticdefaults = (      my %staticdefaults = (
                            anonsurvey_threshold => 10,                             anonsurvey_threshold => 10,
                            uploadquota          => 500,                             uploadquota          => 500,
                            postsubmit           => 60,  
                            mysqltables          => 172800,  
                          );                           );
     if ($position eq 'top') {      if ($position eq 'top') {
         %defaultchecked = (          %defaultchecked = ('canuse_pdfforms' => 'off');
                             'uselcmath'       => 'on',          @toggles = ('canuse_pdfforms');
                             'usejsme'         => 'on',  
                             'canclone'        => 'none',  
                           );  
         @toggles = ('uselcmath','usejsme');  
         ($datatable,$itemcount) = &radiobutton_prefs($settings,\@toggles,\%defaultchecked,          ($datatable,$itemcount) = &radiobutton_prefs($settings,\@toggles,\%defaultchecked,
                                                      \%choices,$itemcount);                                                   \%choices,$itemcount);
         $css_class = $itemcount%2?' class="LC_odd_row"':'';  
         $datatable .=  
             '<tr'.$css_class.'><td valign="top">'.  
             '<span class="LC_nobreak">'.$choices{'canclone'}.  
             '</span></td><td class="LC_left_item">';  
         my $currcanclone = 'none';  
         my $onclick;  
         my @cloneoptions = ('none','domain');  
         my %clonetitles = (  
                              none     => 'No additional course requesters',  
                              domain   => "Any course requester in course's domain",  
                              instcode => 'Course requests for official courses ...',  
                           );  
         my (%codedefaults,@code_order,@posscodes);  
         if (&Apache::lonnet::auto_instcode_defaults($dom,\%codedefaults,  
                                                     \@code_order) eq 'ok') {  
             if (@code_order > 0) {  
                 push(@cloneoptions,'instcode');  
                 $onclick = ' onclick="toggleDisplay(this.form,'."'cloneinstcode'".');"';  
             }  
         }  
         if (ref($settings) eq 'HASH') {  
             if ($settings->{'canclone'}) {  
                 if (ref($settings->{'canclone'}) eq 'HASH') {  
                     if (ref($settings->{'canclone'}{'instcode'}) eq 'ARRAY') {  
                         if (@code_order > 0) {  
                             $currcanclone = 'instcode';  
                             @posscodes = @{$settings->{'canclone'}{'instcode'}};  
                         }  
                     }  
                 } elsif ($settings->{'canclone'} eq 'domain') {  
                     $currcanclone = $settings->{'canclone'};  
                 }  
             }  
         }  
         foreach my $option (@cloneoptions) {  
             my ($checked,$additional);  
             if ($currcanclone eq $option) {  
                 $checked = ' checked="checked"';  
             }  
             if ($option eq 'instcode') {  
                 if (@code_order) {  
                     my $show = 'none';  
                     if ($checked) {  
                         $show = 'block';  
                     }  
                     $additional = '<div id="cloneinstcode" style="display:'.$show.'" />'.  
                                   &mt('Institutional codes for new and cloned course have identical:').  
                                   '<br />';  
                     foreach my $item (@code_order) {  
                         my $codechk;  
                         if ($checked) {  
                             if (grep(/^\Q$item\E$/,@posscodes)) {  
                                 $codechk = ' checked="checked"';  
                             }  
                         }  
                         $additional .= '<label>'.  
                                        '<input type="checkbox" name="clonecode" value="'.$item.'"'.$codechk.' />'.  
                                        $item.'</label>';  
                     }  
                     $additional .= ('&nbsp;'x2).'('.&mt('check as many as needed').')</div>';  
                 }  
             }  
             $datatable .=  
                 '<span class="LC_nobreak"><label><input type="radio" name="canclone"'.$checked.  
                 ' value="'.$option.'"'.$onclick.' />'.$clonetitles{$option}.  
                 '</label>&nbsp;'.$additional.'</span><br />';  
         }  
         $datatable .= '</td>'.  
                       '</tr>';  
         $itemcount ++;  
     } else {      } else {
         $css_class = $itemcount%2 ? ' class="LC_odd_row"' : '';          $css_class = $itemcount%2 ? ' class="LC_odd_row"' : '';
         my ($currdefresponder,%defcredits,%curruploadquota,%deftimeout,%currmysql);          my ($currdefresponder,$def_official_credits,$def_unofficial_credits,%curruploadquota);
         my $currusecredits = 0;          my $currusecredits = 0;
         my $postsubmitclient = 1;          my @types = ('official','unofficial','community');
         my @types = ('official','unofficial','community','textbook');  
         if (ref($settings) eq 'HASH') {          if (ref($settings) eq 'HASH') {
             $currdefresponder = $settings->{'anonsurvey_threshold'};              $currdefresponder = $settings->{'anonsurvey_threshold'};
             if (ref($settings->{'uploadquota'}) eq 'HASH') {              if (ref($settings->{'uploadquota'}) eq 'HASH') {
Line 3596  sub print_coursedefaults { Line 2471  sub print_coursedefaults {
                 }                  }
             }              }
             if (ref($settings->{'coursecredits'}) eq 'HASH') {              if (ref($settings->{'coursecredits'}) eq 'HASH') {
                 foreach my $type (@types) {                  $def_official_credits = $settings->{'coursecredits'}->{'official'};
                     next if ($type eq 'community');                  $def_unofficial_credits = $settings->{'coursecredits'}->{'unofficial'};
                     $defcredits{$type} = $settings->{'coursecredits'}->{$type};                  if (($def_official_credits ne '') || ($def_unofficial_credits ne '')) {
                     if ($defcredits{$type} ne '') {                      $currusecredits = 1;
                         $currusecredits = 1;  
                     }  
                 }  
             }  
             if (ref($settings->{'postsubmit'}) eq 'HASH') {  
                 if ($settings->{'postsubmit'}->{'client'} eq 'off') {  
                     $postsubmitclient = 0;  
                     foreach my $type (@types) {  
                         $deftimeout{$type} = $staticdefaults{'postsubmit'};  
                     }  
                 } else {  
                     foreach my $type (@types) {  
                         if (ref($settings->{'postsubmit'}->{'timeout'}) eq 'HASH') {  
                             if ($settings->{'postsubmit'}->{'timeout'}->{$type} =~ /^\d+$/) {  
                                 $deftimeout{$type} = $settings->{'postsubmit'}->{'timeout'}->{$type};  
                             } else {  
                                 $deftimeout{$type} = $staticdefaults{'postsubmit'};  
                             }  
                         } else {  
                             $deftimeout{$type} = $staticdefaults{'postsubmit'};  
                         }  
                     }  
                 }  
             } else {  
                 foreach my $type (@types) {  
                     $deftimeout{$type} = $staticdefaults{'postsubmit'};  
                 }  
             }  
             if (ref($settings->{'mysqltables'}) eq 'HASH') {  
                 foreach my $type (keys(%{$settings->{'mysqltables'}})) {  
                     $currmysql{$type} = $settings->{'mysqltables'}{$type};  
                 }  
             } else {  
                 foreach my $type (@types) {  
                     $currmysql{$type} = $staticdefaults{'mysqltables'};  
                 }                  }
             }              }
         } else {  
             foreach my $type (@types) {  
                 $deftimeout{$type} = $staticdefaults{'postsubmit'};  
             }  
         }          }
         if (!$currdefresponder) {          if (!$currdefresponder) {
             $currdefresponder = $staticdefaults{'anonsurvey_threshold'};              $currdefresponder = $staticdefaults{'anonsurvey_threshold'};
Line 3659  sub print_coursedefaults { Line 2495  sub print_coursedefaults {
                 '<td class="LC_right_item"><span class="LC_nobreak">'.                  '<td class="LC_right_item"><span class="LC_nobreak">'.
                 '<input type="text" name="anonsurvey_threshold"'.                  '<input type="text" name="anonsurvey_threshold"'.
                 ' value="'.$currdefresponder.'" size="5" /></span>'.                  ' value="'.$currdefresponder.'" size="5" /></span>'.
                 '</td></tr>'."\n";                  '</td></tr>'."\n".
         $itemcount ++;                  '<tr><td><span class="LC_nobreak">'.
         $css_class = $itemcount%2 ? ' class="LC_odd_row"' : '';                  $choices{'uploadquota'}.
         $datatable .= '<tr'.$css_class.'><td><span class="LC_nobreak">'.                  '</span></td>'.
                       $choices{'uploadquota'}.                  '<td align="right" class="LC_right_item">'.
                       '</span></td>'.                  '<table><tr>';
                       '<td align="right" class="LC_right_item">'.  
                       '<table><tr>';  
         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="uploadquota_'.$type.'"'.                             '<input type="text" name="uploadquota_'.$type.'"'.
                            ' value="'.$curruploadquota{$type}.'" size="5" /></td>';                             ' value="'.$curruploadquota{$type}.'" size="5" /></td>';
         }          }
         $datatable .= '</tr></table></td></tr>'."\n";          $datatable .= '</tr></table></td></tr>'."\n";
         $itemcount ++;          $itemcount += 2;
         my $onclick = "toggleDisplay(this.form,'credits');";          my $onclick = 'toggleCredits(this.form);';
         my $display = 'none';          my $display = 'none';  
         if ($currusecredits) {          if ($currusecredits) {
             $display = 'block';              $display = 'block';
         }          }
         my $additional = '<div id="credits" style="display: '.$display.'">'.          my $additional = '<div id="credits" style="display: '.$display.'">'.
                          '<i>'.&mt('Default credits').'</i><br /><table><tr>';                           '<span class="LC_nobreak">'.
         foreach my $type (@types) {                           &mt('Default credits for official courses [_1]',
             next if ($type eq 'community');                           '<input type="text" name="official_credits" value="'.
             $additional .= '<td align="center">'.&mt($type).'<br />'.                           $def_official_credits.'" size="3" />').
                            '<input type="text" name="'.$type.'_credits"'.                           '</span><br />'.
                            ' value="'.$defcredits{$type}.'" size="3" /></td>';                           '<span class="LC_nobreak">'.
         }                           &mt('Default credits for unofficial courses [_1]',
         $additional .= '</tr></table></div>'."\n";                           '<input type="text" name="unofficial_credits" value="'.
                            $def_unofficial_credits.'" size="3" />').
                            '</span></div>'."\n";
         %defaultchecked = ('coursecredits' => 'off');          %defaultchecked = ('coursecredits' => 'off');
         @toggles = ('coursecredits');          @toggles = ('coursecredits');
         my $current = {          my $current = {
Line 3695  sub print_coursedefaults { Line 2531  sub print_coursedefaults {
                       };                        };
         (my $table,$itemcount) =          (my $table,$itemcount) =
             &radiobutton_prefs($current,\@toggles,\%defaultchecked,              &radiobutton_prefs($current,\@toggles,\%defaultchecked,
                                \%choices,$itemcount,$onclick,$additional,'left');                                 \%choices,$itemcount,$onclick,$additional);
         $datatable .= $table;  
         $onclick = "toggleDisplay(this.form,'studentsubmission');";  
         my $display = 'none';  
         if ($postsubmitclient) {  
             $display = 'block';  
         }  
         $additional = '<div id="studentsubmission" style="display: '.$display.'">'.  
                       &mt('Number of seconds submit is disabled').'<br />'.  
                       '<i>'.&mt('Enter 0 to remain disabled until page reload.').'</i><br />'.  
                       '<table><tr>';  
         foreach my $type (@types) {  
             $additional .= '<td align="center">'.&mt($type).'<br />'.  
                            '<input type="text" name="'.$type.'_timeout" value="'.  
                            $deftimeout{$type}.'" size="5" /></td>';  
         }  
         $additional .= '</tr></table></div>'."\n";  
         %defaultchecked = ('postsubmit' => 'on');  
         @toggles = ('postsubmit');  
         $current = {  
                        'postsubmit' => $postsubmitclient,  
                    };  
         ($table,$itemcount) =  
             &radiobutton_prefs($current,\@toggles,\%defaultchecked,  
                                \%choices,$itemcount,$onclick,$additional,'left');  
         $datatable .= $table;          $datatable .= $table;
         $css_class = $itemcount%2 ? ' class="LC_odd_row"' : '';  
         $datatable .= '<tr'.$css_class.'><td><span class="LC_nobreak">'.  
                       $choices{'mysqltables'}.  
                       '</span></td>'.  
                       '<td align="right" class="LC_right_item">'.  
                       '<table><tr>';  
         foreach my $type (@types) {  
             $datatable .= '<td align="center">'.&mt($type).'<br />'.  
                            '<input type="text" name="mysqltables_'.$type.'"'.  
                            ' value="'.$currmysql{$type}.'" size="8" /></td>';  
         }  
         $datatable .= '</tr></table></td></tr>'."\n";  
         $itemcount ++;  
   
     }      }
     $$rowtotal += $itemcount;      $$rowtotal += $itemcount;
     return $datatable;      return $datatable;
 }  }
   
 sub print_selfenrollment {  
     my ($position,$dom,$settings,$rowtotal) = @_;  
     my ($css_class,$datatable);  
     my $itemcount = 1;  
     my @types = ('official','unofficial','community','textbook');  
     if (($position eq 'top') || ($position eq 'middle')) {  
         my ($rowsref,$titlesref) = &Apache::lonuserutils::get_selfenroll_titles();  
         my %descs = &Apache::lonuserutils::selfenroll_default_descs();  
         my @rows;  
         my $key;  
         if ($position eq 'top') {  
             $key = 'admin';   
             if (ref($rowsref) eq 'ARRAY') {  
                 @rows = @{$rowsref};  
             }  
         } elsif ($position eq 'middle') {  
             $key = 'default';  
             @rows = ('types','registered','approval','limit');  
         }  
         foreach my $row (@rows) {  
             if (defined($titlesref->{$row})) {  
                 $itemcount ++;  
                 $css_class = $itemcount%2?' class="LC_odd_row"':'';  
                 $datatable .= '<tr'.$css_class.'>'.  
                               '<td>'.$titlesref->{$row}.'</td>'.  
                               '<td class="LC_left_item">'.  
                               '<table><tr>';  
                 my (%current,%currentcap);  
                 if (ref($settings) eq 'HASH') {  
                     if (ref($settings->{$key}) eq 'HASH') {  
                         foreach my $type (@types) {  
                             if (ref($settings->{$key}->{$type}) eq 'HASH') {  
                                 $current{$type} = $settings->{$key}->{$type}->{$row};  
                             }  
                             if (($row eq 'limit') && ($key eq 'default')) {  
                                 if (ref($settings->{$key}->{$type}) eq 'HASH') {  
                                     $currentcap{$type} = $settings->{$key}->{$type}->{'cap'};  
                                 }  
                             }  
                         }  
                     }  
                 }  
                 my %roles = (  
                              '0' => &Apache::lonnet::plaintext('dc'),  
                             );   
               
                 foreach my $type (@types) {  
                     unless (($row eq 'registered') && ($key eq 'default')) {  
                         $datatable .= '<th>'.&mt($type).'</th>';  
                     }  
                 }  
                 unless (($row eq 'registered') && ($key eq 'default')) {  
                     $datatable .= '</tr><tr>';  
                 }  
                 foreach my $type (@types) {  
                     if ($type eq 'community') {  
                         $roles{'1'} = &mt('Community personnel');  
                     } else {  
                         $roles{'1'} = &mt('Course personnel');  
                     }  
                     $datatable .= '<td style="vertical-align: top">';  
                     if ($position eq 'top') {  
                         my %checked;  
                         if ($current{$type} eq '0') {  
                             $checked{'0'} = ' checked="checked"';  
                         } else {  
                             $checked{'1'} = ' checked="checked"';  
                         }  
                         foreach my $role ('1','0') {  
                             $datatable .= '<span class="LC_nobreak"><label>'.  
                                           '<input type="radio" name="selfenrolladmin_'.$row.'_'.$type.'" '.  
                                           'value="'.$role.'"'.$checked{$role}.' />'.  
                                           $roles{$role}.'</label></span> ';  
                         }  
                     } else {  
                         if ($row eq 'types') {  
                             my %checked;  
                             if ($current{$type} =~ /^(all|dom)$/) {  
                                 $checked{$1} = ' checked="checked"';  
                             } else {  
                                 $checked{''} = ' checked="checked"';  
                             }  
                             foreach my $val ('','dom','all') {  
                                 $datatable .= '<span class="LC_nobreak"><label>'.  
                                               '<input type ="radio" name="selfenrolldefault_'.$row.'_'.$type.'" '.  
                                               'value="'.$val.'"'.$checked{$val}.' />'.$descs{$row}{$val}.'</label></span> ';  
                             }  
                         } elsif ($row eq 'registered') {  
                             my %checked;  
                             if ($current{$type} eq '1') {  
                                 $checked{'1'} = ' checked="checked"';  
                             } else {  
                                 $checked{'0'} = ' checked="checked"';  
                             }  
                             foreach my $val ('0','1') {  
                                 $datatable .= '<span class="LC_nobreak"><label>'.  
                                               '<input type ="radio" name="selfenrolldefault_'.$row.'_'.$type.'" '.  
                                               'value="'.$val.'"'.$checked{$val}.' />'.$descs{$row}{$val}.'</label></span> ';  
                             }  
                         } elsif ($row eq 'approval') {  
                             my %checked;  
                             if ($current{$type} =~ /^([12])$/) {  
                                 $checked{$1} = ' checked="checked"';  
                             } else {  
                                 $checked{'0'} = ' checked="checked"';  
                             }  
                             for my $val (0..2) {  
                                 $datatable .= '<span class="LC_nobreak"><label>'.  
                                               '<input type="radio" name="selfenrolldefault_'.$row.'_'.$type.'" '.  
                                               'value="'.$val.'"'.$checked{$val}.' />'.$descs{$row}{$val}.'</label></span> ';  
                             }  
                         } elsif ($row eq 'limit') {  
                             my %checked;  
                             if ($current{$type} =~ /^(allstudents|selfenrolled)$/) {  
                                 $checked{$1} = ' checked="checked"';  
                             } else {  
                                 $checked{'none'} = ' checked="checked"';  
                             }  
                             my $cap;  
                             if ($currentcap{$type} =~ /^\d+$/) {  
                                 $cap = $currentcap{$type};  
                             }  
                             foreach my $val ('none','allstudents','selfenrolled') {  
                                 $datatable .= '<span class="LC_nobreak"><label>'.  
                                               '<input type="radio" name="selfenrolldefault_'.$row.'_'.$type.'" '.  
                                               'value="'.$val.'"'.$checked{$val}.' />'.$descs{$row}{$val}.'</label></span> ';  
                             }  
                             $datatable .= '<br />'.  
                                           '<span class="LC_nobreak">'.&mt('Maximum allowed: ').  
                                           '<input type="text" name="selfenrolldefault_cap_'.$type.'" size = "5" value="'.$cap.'" />'.  
                                           '</span>';   
                         }  
                     }  
                     $datatable .= '</td>';  
                 }  
                 $datatable .= '</tr>';  
             }  
             $datatable .= '</table></td></tr>';  
         }  
     } elsif ($position eq 'bottom') {  
         $datatable .= &print_validation_rows('selfenroll',$dom,$settings,\$itemcount);  
     }  
     $$rowtotal += $itemcount;  
     return $datatable;  
 }  
   
 sub print_validation_rows {  
     my ($caller,$dom,$settings,$rowtotal) = @_;  
     my ($itemsref,$namesref,$fieldsref);  
     if ($caller eq 'selfenroll') {   
         ($itemsref,$namesref,$fieldsref) = &Apache::lonuserutils::selfenroll_validation_types();  
     } elsif ($caller eq 'requestcourses') {  
         ($itemsref,$namesref,$fieldsref) = &Apache::loncoursequeueadmin::requestcourses_validation_types();  
     }  
     my %currvalidation;  
     if (ref($settings) eq 'HASH') {  
         if (ref($settings->{'validation'}) eq 'HASH') {  
             %currvalidation = %{$settings->{'validation'}};  
         }  
     }  
     my $datatable;  
     my $itemcount = 0;  
     foreach my $item (@{$itemsref}) {  
         my $css_class = $itemcount%2 ? ' class="LC_odd_row"' : '';  
         $datatable .= '<tr'.$css_class.'><td><span class="LC_nobreak">'.  
                       $namesref->{$item}.  
                       '</span></td>'.  
                       '<td class="LC_left_item">';  
         if (($item eq 'url') || ($item eq 'button')) {  
             $datatable .= '<span class="LC_nobreak">'.  
                           '<input type="text" name="'.$caller.'_validation_'.$item.'"'.  
                           ' value="'.$currvalidation{$item}.'" size="50" /></span>';  
         } elsif ($item eq 'fields') {  
             my @currfields;  
             if (ref($currvalidation{$item}) eq 'ARRAY') {  
                 @currfields = @{$currvalidation{$item}};  
             }  
             foreach my $field (@{$fieldsref}) {  
                 my $check = '';  
                 if (grep(/^\Q$field\E$/,@currfields)) {  
                     $check = ' checked="checked"';  
                 }  
                 $datatable .= '<span class="LC_nobreak"><label>'.  
                               '<input type="checkbox" name="'.$caller.'_validation_fields"'.  
                               ' value="'.$field.'"'.$check.' />'.$field.  
                               '</label></span> ';  
             }  
         } elsif ($item eq 'markup') {  
             $datatable .= '<textarea name="'.$caller.'_validation_markup" cols="50" rows="5">'.  
                            $currvalidation{$item}.  
                               '</textarea>';  
         }  
         $datatable .= '</td></tr>'."\n";  
         if (ref($rowtotal)) {  
             $itemcount ++;  
         }  
     }  
     if ($caller eq 'requestcourses') {  
         my %currhash;  
         if (ref($settings) eq 'HASH') {  
             if (ref($settings->{'validation'}) eq 'HASH') {  
                 if ($settings->{'validation'}{'dc'} ne '') {  
                     $currhash{$settings->{'validation'}{'dc'}} = 1;  
                 }  
             }  
         }  
         my $numinrow = 2;  
         my ($numdc,$dctable,$rows) = &active_dc_picker($dom,$numinrow,'radio',  
                                                        'validationdc',%currhash);  
         my $css_class = $itemcount%2 ? ' class="LC_odd_row"' : '';  
         $datatable .= '<tr'.$css_class.'><td>';  
         if ($numdc > 1) {  
             $datatable .= &mt('Course creation processed as: (choose Dom. Coord.)');  
         } else {  
             $datatable .=  &mt('Course creation processed as: ');  
         }  
         $datatable .= '</td><td class="LC_left_item">'.$dctable.'</td></tr>';  
         $itemcount ++;  
     }  
     if (ref($rowtotal)) {  
         $$rowtotal += $itemcount;  
     }  
     return $datatable;  
 }  
   
 sub print_usersessions {  sub print_usersessions {
     my ($position,$dom,$settings,$rowtotal) = @_;      my ($position,$dom,$settings,$rowtotal) = @_;
     my ($css_class,$datatable,%checked,%choices);      my ($css_class,$datatable,%checked,%choices);
Line 3979  sub print_usersessions { Line 2552  sub print_usersessions {
     if ($position eq 'top') {      if ($position eq 'top') {
         if (keys(%serverhomes) > 1) {          if (keys(%serverhomes) > 1) {
             my %spareid = &current_offloads_to($dom,$settings,\%servers);              my %spareid = &current_offloads_to($dom,$settings,\%servers);
             my $curroffloadnow;              $datatable .= &spares_row($dom,\%servers,\%spareid,\%serverhomes,\%altids,$rowtotal);
             if (ref($settings) eq 'HASH') {  
                 if (ref($settings->{'offloadnow'}) eq 'HASH') {  
                     $curroffloadnow = $settings->{'offloadnow'};  
                 }  
             }  
             $datatable .= &spares_row($dom,\%servers,\%spareid,\%serverhomes,\%altids,$curroffloadnow,$rowtotal);  
         } else {          } else {
             $datatable .= '<tr'.$css_class.'><td colspan="2">'.              $datatable .= '<tr'.$css_class.'><td colspan="2">'.
                           &mt('Nothing to set here, as the cluster to which this domain belongs only contains one server.');                            &mt('Nothing to set here, as the cluster to which this domain belongs only contains one server.');
Line 4235  sub current_offloads_to { Line 2802  sub current_offloads_to {
 }  }
   
 sub spares_row {  sub spares_row {
     my ($dom,$servers,$spareid,$serverhomes,$altids,$curroffloadnow,$rowtotal) = @_;      my ($dom,$servers,$spareid,$serverhomes,$altids,$rowtotal) = @_;
     my $css_class;      my $css_class;
     my $numinrow = 4;      my $numinrow = 4;
     my $itemcount = 1;      my $itemcount = 1;
Line 4255  sub spares_row { Line 2822  sub spares_row {
                 }                  }
             }              }
             next unless (ref($spareid->{$server}) eq 'HASH');              next unless (ref($spareid->{$server}) eq 'HASH');
             my $checkednow;  
             if (ref($curroffloadnow) eq 'HASH') {  
                 if ($curroffloadnow->{$server}) {  
                     $checkednow = ' checked="checked"';  
                 }  
             }  
             $css_class = $itemcount%2 ? ' class="LC_odd_row"' : '';              $css_class = $itemcount%2 ? ' class="LC_odd_row"' : '';
             $datatable .= '<tr'.$css_class.'>              $datatable .= '<tr'.$css_class.'>
                            <td rowspan="2">                             <td rowspan="2">
                             <span class="LC_nobreak">'.                              <span class="LC_nobreak">'.
                           &mt('[_1] when busy, offloads to:'                            &mt('[_1] when busy, offloads to:'
                               ,'<b>'.$server.'</b>').'</span><br />'.                                ,'<b>'.$server.'</b>').
                           '<span class="LC_nobreak">'."\n".  
                           '<label><input type="checkbox" name="offloadnow" value="'.$server.'"'.$checkednow.' />'.  
                           '&nbsp;'.&mt('Switch active users on next access').'</label></span>'.  
                           "\n";                            "\n";
             my (%current,%canselect);              my (%current,%canselect);
             my @choices =               my @choices = 
Line 4406  sub print_loadbalancing { Line 2964  sub print_loadbalancing {
     }      }
     my ($othertitle,$usertypes,$types) =      my ($othertitle,$usertypes,$types) =
         &Apache::loncommon::sorted_inst_types($dom);          &Apache::loncommon::sorted_inst_types($dom);
     my $rownum = 8;      my $rownum = 6;
     if (ref($types) eq 'ARRAY') {      if (ref($types) eq 'ARRAY') {
         $rownum += scalar(@{$types});          $rownum += scalar(@{$types});
     }      }
Line 4437  sub print_loadbalancing { Line 2995  sub print_loadbalancing {
                       '<td rowspan="'.$rownum.'" valign="top">'.                        '<td rowspan="'.$rownum.'" valign="top">'.
                       '<p>';                        '<p>';
         if ($lonhost eq '') {          if ($lonhost eq '') {
             $datatable .= '<span class="LC_nobreak">';              $datatable .= '<span class="LC_nobreak">'; 
             if (keys(%currbalancer) > 0) {              if (keys(%currbalancer) > 0) {
                 $datatable .= &mt('Add balancer:');                  $datatable .= &mt('Add balancer:');
             } else {              } else {
Line 4453  sub print_loadbalancing { Line 3011  sub print_loadbalancing {
                 next if ($currbalancer{$server});                  next if ($currbalancer{$server});
                 $datatable .= '<option value="'.$server.'">'.$server.'</option>'."\n";                  $datatable .= '<option value="'.$server.'">'.$server.'</option>'."\n";
             }              }
             $datatable .=              $datatable .= 
                 '</select>'."\n".                  '</select>'."\n".
                 '<input type="hidden" name="loadbalancing_prevlonhost_'.$balnum.'" id="loadbalancing_prevlonhost_'.$balnum.'" value="" />&nbsp;</span>'."\n";                  '<input type="hidden" name="loadbalancing_prevlonhost_'.$balnum.'" id="loadbalancing_prevlonhost_'.$balnum.'" value="" />&nbsp;</span>'."\n";
         } else {          } else {
Line 4474  sub print_loadbalancing { Line 3032  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 4495  sub print_loadbalancing { Line 3050  sub print_loadbalancing {
                 if (exists($currbalancer{$spares[$i]})) {                  if (exists($currbalancer{$spares[$i]})) {
                     $disabled = ' disabled="disabled"';                      $disabled = ' disabled="disabled"';
                 }                  }
                 $targettable .=                  $targettable .= 
                     '<td><span class="LC_nobreak"><label>'.                      '<td><label><input type="checkbox" name="loadbalancing_target_'.$balnum.'_'.$sparetype.'"'.
                     '<input type="checkbox" name="loadbalancing_target_'.$balnum.'_'.$sparetype.'"'.  
                     $checked.$disabled.' value="'.$chkboxval.'" id="loadbalancing_target_'.$balnum.'_'.$sparetype.'_'.$i.'" onclick="checkOffloads('."this,'$balnum','$sparetype'".');" /><span id="loadbalancing_targettxt_'.$balnum.'_'.$sparetype.'_'.$i.'">&nbsp;'.$chkboxval.                      $checked.$disabled.' value="'.$chkboxval.'" id="loadbalancing_target_'.$balnum.'_'.$sparetype.'_'.$i.'" onclick="checkOffloads('."this,'$balnum','$sparetype'".');" /><span id="loadbalancing_targettxt_'.$balnum.'_'.$sparetype.'_'.$i.'">&nbsp;'.$chkboxval.
                     '</span></label></span></td>';                      '</span></label></td>';
                 my $rem = $i%($numinrow);                  my $rem = $i%($numinrow);
                 if ($rem == 0) {                  if ($rem == 0) {
                     if (($i > 0) && ($i < $numspares-1)) {                      if (($i > 0) && ($i < $numspares-1)) {
Line 4522  sub print_loadbalancing { Line 3076  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 4597  sub loadbalancing_rules { Line 3134  sub loadbalancing_rules {
         $css_class,$balnum,$islast) = @_;          $css_class,$balnum,$islast) = @_;
     my $output;      my $output;
     my $num = 0;      my $num = 0;
     my ($alltypes,$othertypes,$titles) =      my ($alltypes,$othertypes,$titles) = 
         &loadbalancing_titles($dom,$intdom,$usertypes,$types);          &loadbalancing_titles($dom,$intdom,$usertypes,$types);
     if ((ref($alltypes) eq 'ARRAY') && (ref($titles) eq 'HASH'))  {      if ((ref($alltypes) eq 'ARRAY') && (ref($titles) eq 'HASH'))  {
         foreach my $type (@{$alltypes}) {          foreach my $type (@{$alltypes}) {
Line 4627  sub loadbalancing_titles { Line 3164  sub loadbalancing_titles {
            '_LC_author'      => &mt('Users from [_1] with author role',$dom),             '_LC_author'      => &mt('Users from [_1] with author role',$dom),
            '_LC_internetdom' => &mt('Users not from [_1], but from [_2]',$dom,$intdom),             '_LC_internetdom' => &mt('Users not from [_1], but from [_2]',$dom,$intdom),
            '_LC_external'    => &mt('Users not from [_1]',$intdom),             '_LC_external'    => &mt('Users not from [_1]',$intdom),
            '_LC_ipchangesso' => &mt('SSO users from [_1], with IP mismatch',$dom),  
            '_LC_ipchange'    => &mt('Non-SSO users with IP mismatch'),  
                      );                       );
     my @alltypes = ('_LC_adv','_LC_author','_LC_internetdom','_LC_external','_LC_ipchangesso','_LC_ipchange');      my @alltypes = ('_LC_adv','_LC_author','_LC_internetdom','_LC_external');
     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 4660  sub loadbalancing_titles { Line 3190  sub loadbalancing_titles {
 sub loadbalance_rule_row {  sub loadbalance_rule_row {
     my ($type,$title,$current,$servers,$currbalancer,$lonhost,$dom,      my ($type,$title,$current,$servers,$currbalancer,$lonhost,$dom,
         $targets_div_style,$homedom_div_style,$css_class,$balnum,$num,$islast) = @_;          $targets_div_style,$homedom_div_style,$css_class,$balnum,$num,$islast) = @_;
     my @rulenames;      my @rulenames = ('default','homeserver');
     my %ruletitles = &offloadtype_text();      my %ruletitles = &offloadtype_text();
     if (($type eq '_LC_ipchangesso') || ($type eq '_LC_ipchange')) {      if ($type eq '_LC_external') {
         @rulenames = ('balancer','offloadedto','specific');          push(@rulenames,'externalbalancer');
     } else {      } else {
         @rulenames = ('default','homeserver');          push(@rulenames,'specific');
         if ($type eq '_LC_external') {  
             push(@rulenames,'externalbalancer');  
         } else {  
             push(@rulenames,'specific');  
         }  
         push(@rulenames,'none');  
     }      }
       push(@rulenames,'none');
     my $style = $targets_div_style;      my $style = $targets_div_style;
     if (($type eq '_LC_external') || ($type eq '_LC_internetdom')) {      if (($type eq '_LC_external') || ($type eq '_LC_internetdom')) {
         $style = $homedom_div_style;          $style = $homedom_div_style;
Line 4681  sub loadbalance_rule_row { Line 3206  sub loadbalance_rule_row {
     if ($islast && $num == 1) {      if ($islast && $num == 1) {
         $space = '<div display="inline-block">&nbsp;</div>';          $space = '<div display="inline-block">&nbsp;</div>';
     }      }
     my $output =      my $output = 
         '<tr class="'.$css_class.'" id="balanceruletr_'.$balnum.'_'.$num.'"><td valign="top">'.$space.          '<tr class="'.$css_class.'" id="balanceruletr_'.$balnum.'_'.$num.'"><td valign="top">'.$space.
         '<div id="balanceruletitle_'.$balnum.'_'.$type.'" style="'.$style.'">'.$title.'</div></td>'."\n".          '<div id="balanceruletitle_'.$balnum.'_'.$type.'" style="'.$style.'">'.$title.'</div></td>'."\n".
         '<td valaign="top">'.$space.          '<td valaign="top">'.$space.
Line 4701  sub loadbalance_rule_row { Line 3226  sub loadbalance_rule_row {
                 unless ($checked) {                  unless ($checked) {
                     $default = ' selected="selected"';                      $default = ' selected="selected"';
                 }                  }
                 $extra =                  $extra = 
                     ':&nbsp;<select name="loadbalancing_singleserver_'.$balnum.'_'.$type.                      ':&nbsp;<select name="loadbalancing_singleserver_'.$balnum.'_'.$type.
                     '" id="loadbalancing_singleserver_'.$balnum.'_'.$type.                      '" id="loadbalancing_singleserver_'.$balnum.'_'.$type.
                     '" onchange="singleServerToggle('."'$balnum','$type'".')">'."\n".                      '" onchange="singleServerToggle('."'$balnum','$type'".')">'."\n".
Line 4725  sub loadbalance_rule_row { Line 3250  sub loadbalance_rule_row {
                    '<input type="radio" name="loadbalancing_rules_'.$balnum.'_'.$type.                     '<input type="radio" name="loadbalancing_rules_'.$balnum.'_'.$type.
                    '" id="loadbalancing_rules_'.$balnum.'_'.$type.'_'.$i.'" value="'.                     '" id="loadbalancing_rules_'.$balnum.'_'.$type.'_'.$i.'" value="'.
                    $rule.'" onclick="balanceruleChange('."this.form,'$balnum','$type'".                     $rule.'" onclick="balanceruleChange('."this.form,'$balnum','$type'".
                    ')"'.$checked.' />&nbsp;';                     ')"'.$checked.' />&nbsp;'.$ruletitles{$rulenames[$i]}.
         if (($rulenames[$i] eq 'specific') && ($type =~ /^_LC_ipchange/)) {                     '</label>'.$extra.'</span><br />'."\n";
             $output .= $ruletitles{'particular'};  
         } else {  
             $output .= $ruletitles{$rulenames[$i]};  
         }  
         $output .= '</label>'.$extra.'</span><br />'."\n";  
     }      }
     $output .= '</div></td></tr>'."\n";      $output .= '</div></td></tr>'."\n";
     return $output;      return $output;
Line 4744  sub offloadtype_text { Line 3264  sub offloadtype_text {
            'externalbalancer' => "Offloads to Load Balancer in user's domain",             'externalbalancer' => "Offloads to Load Balancer in user's domain",
            'specific'         => 'Offloads to specific server',             'specific'         => 'Offloads to specific server',
            'none'             => 'No offload',             'none'             => 'No offload',
            'balancer'         => 'Session hosted on Load Balancer, after re-authentication',  
            'offloadedto'      => 'Session hosted on offload server, after re-authentication',  
            'particular'       => 'Session hosted (after re-auth) on server:',  
     );      );
     return %ruletitles;      return %ruletitles;
 }  }
Line 4761  sub sparestype_titles { Line 3278  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',  
                  );                   );
     my %short_titles = &Apache::lonlocal::texthash (      my %short_titles = &Apache::lonlocal::texthash (
                            adminemail   => 'Admin E-mail address',                             adminemail   => 'Admin E-mail address',
Line 4779  sub contact_titles { Line 3294  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 4816  sub tool_titles { Line 3303  sub tool_titles {
                      official   => 'Official courses (with institutional codes)',                       official   => 'Official courses (with institutional codes)',
                      unofficial => 'Unofficial courses',                       unofficial => 'Unofficial courses',
                      community  => 'Communities',                       community  => 'Communities',
                      textbook   => 'Textbook courses',  
                  );                   );
     return %titles;      return %titles;
 }  }
Line 4826  sub courserequest_titles { Line 3312  sub courserequest_titles {
                                    official   => 'Official',                                     official   => 'Official',
                                    unofficial => 'Unofficial',                                     unofficial => 'Unofficial',
                                    community  => 'Communities',                                     community  => 'Communities',
                                    textbook   => 'Textbook',  
                                    norequest  => 'Not allowed',                                     norequest  => 'Not allowed',
                                    approval   => 'Approval by Dom. Coord.',                                     approval   => 'Approval by Dom. Coord.',
                                    validate   => 'With validation',                                     validate   => 'With validation',
Line 4843  sub authorrequest_titles { Line 3328  sub authorrequest_titles {
                                    automatic  => 'Automatic approval',                                     automatic  => 'Automatic approval',
                  );                   );
     return %titles;      return %titles;
 }  } 
   
 sub courserequest_conditions {  sub courserequest_conditions {
     my %conditions = &Apache::lonlocal::texthash (      my %conditions = &Apache::lonlocal::texthash (
Line 4879  sub print_usercreation { Line 3364  sub print_usercreation {
                 $rowcount ++;                  $rowcount ++;
             }              }
         }          }
           my ($emailrules,$emailruleorder) = 
               &Apache::lonnet::inst_userrules($dom,'email');
           if (ref($emailrules) eq 'HASH') {
               if (keys(%{$emailrules}) > 0) {
                   $datatable .= &user_formats_row('email',$settings,$emailrules,
                                                   $emailruleorder,$numinrow,$rowcount);
                   $$rowtotal ++;
                   $rowcount ++;
               }
           }
         if ($rowcount == 0) {          if ($rowcount == 0) {
             $datatable .= '<tr><td colspan="2">'.&mt('No format rules have been defined for usernames or IDs in this domain.').'</td></tr>';                $datatable .= '<tr><td colspan="2">'.&mt('No format rules have been defined for usernames or IDs in this domain.').'</td></tr>';  
             $$rowtotal ++;              $$rowtotal ++;
             $rowcount ++;              $rowcount ++;
         }          }
     } elsif ($position eq 'middle') {      } elsif ($position eq 'middle') {
         my @creators = ('author','course','requestcrs');          my @creators = ('author','course','requestcrs','selfcreate');
         my ($rules,$ruleorder) =          my ($rules,$ruleorder) =
             &Apache::lonnet::inst_userrules($dom,'username');              &Apache::lonnet::inst_userrules($dom,'username');
         my %lt = &usercreation_types();          my %lt = &usercreation_types();
         my %checked;          my %checked;
           my @selfcreate; 
         if (ref($settings) eq 'HASH') {          if (ref($settings) eq 'HASH') {
             if (ref($settings->{'cancreate'}) eq 'HASH') {              if (ref($settings->{'cancreate'}) eq 'HASH') {
                 foreach my $item (@creators) {                  foreach my $item (@creators) {
                     $checked{$item} = $settings->{'cancreate'}{$item};                      $checked{$item} = $settings->{'cancreate'}{$item};
                 }                  }
                   if (ref($settings->{'cancreate'}{'selfcreate'}) eq 'ARRAY') {
                       @selfcreate = @{$settings->{'cancreate'}{'selfcreate'}};
                   } elsif ($settings->{'cancreate'}{'selfcreate'} ne '') {
                       if ($settings->{'cancreate'}{'selfcreate'} eq 'any') {
                           @selfcreate = ('email','login','sso');
                       } elsif ($settings->{'cancreate'}{'selfcreate'} ne 'none') {
                           @selfcreate = ($settings->{'cancreate'}{'selfcreate'});
                       }
                   }
             } elsif (ref($settings->{'cancreate'}) eq 'ARRAY') {              } elsif (ref($settings->{'cancreate'}) eq 'ARRAY') {
                 foreach my $item (@creators) {                  foreach my $item (@creators) {
                     if (grep(/^\Q$item\E$/,@{$settings->{'cancreate'}})) {                      if (grep(/^\Q$item\E$/,@{$settings->{'cancreate'}})) {
Line 4906  sub print_usercreation { Line 3411  sub print_usercreation {
         my $rownum = 0;          my $rownum = 0;
         foreach my $item (@creators) {          foreach my $item (@creators) {
             $rownum ++;              $rownum ++;
             if ($checked{$item} eq '') {              if ($item ne 'selfcreate') {  
                 $checked{$item} = 'any';                  if ($checked{$item} eq '') {
                       $checked{$item} = 'any';
                   }
             }              }
             my $css_class;              my $css_class;
             if ($rownum%2) {              if ($rownum%2) {
Line 4918  sub print_usercreation { Line 3425  sub print_usercreation {
             $datatable .= '<tr'.$css_class.'>'.              $datatable .= '<tr'.$css_class.'>'.
                          '<td><span class="LC_nobreak">'.$lt{$item}.                           '<td><span class="LC_nobreak">'.$lt{$item}.
                          '</span></td><td align="right">';                           '</span></td><td align="right">';
             my @options = ('any');              my @options;
             if (ref($rules) eq 'HASH') {              if ($item eq 'selfcreate') {
                 if (keys(%{$rules}) > 0) {                  push(@options,('email','login','sso'));
                     push(@options,('official','unofficial'));              } else {
                   @options = ('any');
                   if (ref($rules) eq 'HASH') {
                       if (keys(%{$rules}) > 0) {
                           push(@options,('official','unofficial'));
                       }
                 }                  }
                   push(@options,'none');
             }              }
             push(@options,'none');  
             foreach my $option (@options) {              foreach my $option (@options) {
                 my $type = 'radio';                  my $type = 'radio';
                 my $check = ' ';                  my $check = ' ';
                 if ($checked{$item} eq $option) {                  if ($item eq 'selfcreate') {
                     $check = ' checked="checked" ';                      $type = 'checkbox';
                       if (grep(/^\Q$option\E$/,@selfcreate)) {
                           $check = ' checked="checked" ';
                       }
                   } else {
                       if ($checked{$item} eq $option) {
                           $check = ' checked="checked" ';
                       }
                 }                   } 
                 $datatable .= '<span class="LC_nobreak"><label>'.                  $datatable .= '<span class="LC_nobreak"><label>'.
                               '<input type="'.$type.'" name="can_createuser_'.                                '<input type="'.$type.'" name="can_createuser_'.
Line 4938  sub print_usercreation { Line 3457  sub print_usercreation {
             }              }
             $datatable .= '</td></tr>';              $datatable .= '</td></tr>';
         }          }
           my ($othertitle,$usertypes,$types) =
               &Apache::loncommon::sorted_inst_types($dom);
           my $createsettings;
           if (ref($settings) eq 'HASH') {
               $createsettings = $settings->{cancreate};
           }
           if (ref($usertypes) eq 'HASH') {
               if (keys(%{$usertypes}) > 0) {
                   $datatable .= &insttypes_row($createsettings,$types,$usertypes,
                                                $dom,$numinrow,$othertitle,
                                                'statustocreate');
                   $$rowtotal ++;
                   $rownum ++;
               }
           }
           $datatable .= &captcha_choice('cancreate',$createsettings,$rownum);
     } else {      } else {
         my @contexts = ('author','course','domain');          my @contexts = ('author','course','domain');
         my @authtypes = ('int','krb4','krb5','loc');          my @authtypes = ('int','krb4','krb5','loc');
Line 4989  sub print_usercreation { Line 3524  sub print_usercreation {
     return $datatable;      return $datatable;
 }  }
   
 sub print_selfcreation {  
     my ($position,$dom,$settings,$rowtotal) = @_;  
     my (@selfcreate,$createsettings,$processing,$datatable);  
     if (ref($settings) eq 'HASH') {  
         if (ref($settings->{'cancreate'}) eq 'HASH') {  
             $createsettings = $settings->{'cancreate'};  
             if (ref($createsettings) eq 'HASH') {  
                 if (ref($createsettings->{'selfcreate'}) eq 'ARRAY') {  
                     @selfcreate = @{$createsettings->{'selfcreate'}};  
                 } elsif ($createsettings->{'selfcreate'} ne '') {  
                     if ($settings->{'cancreate'}{'selfcreate'} eq 'any') {  
                         @selfcreate = ('email','login','sso');  
                     } elsif ($createsettings->{'selfcreate'} ne 'none') {  
                         @selfcreate = ($createsettings->{'selfcreate'});  
                     }  
                 }  
                 if (ref($createsettings->{'selfcreateprocessing'}) eq 'HASH') {  
                     $processing = $createsettings->{'selfcreateprocessing'};  
                 }  
             }  
         }  
     }  
     my %radiohash;  
     my $numinrow = 4;  
     map { $radiohash{'cancreate_'.$_} = 1; } @selfcreate;  
     my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom);  
     if ($position eq 'top') {  
         my %choices = &Apache::lonlocal::texthash (  
                                                       cancreate_login      => 'Institutional Login',  
                                                       cancreate_sso        => 'Institutional Single Sign On',  
                                                   );  
         my @toggles = sort(keys(%choices));  
         my %defaultchecked = (  
                                'cancreate_login' => 'off',  
                                'cancreate_sso'   => 'off',  
                              );  
         my ($onclick,$itemcount);  
         ($datatable,$itemcount) = &radiobutton_prefs(\%radiohash,\@toggles,\%defaultchecked,  
                                                      \%choices,$itemcount,$onclick);  
         $$rowtotal += $itemcount;  
   
         if (ref($usertypes) eq 'HASH') {  
             if (keys(%{$usertypes}) > 0) {  
                 $datatable .= &insttypes_row($createsettings,$types,$usertypes,  
                                              $dom,$numinrow,$othertitle,  
                                              'statustocreate',$rowtotal);  
                 $$rowtotal ++;  
             }  
         }  
         my @fields = ('lastname','firstname','middlename','permanentemail','id','inststatus');  
         my %fieldtitles = &Apache::loncommon::personal_data_fieldtitles();  
         $fieldtitles{'inststatus'} = &mt('Institutional status');  
         my $rem;  
         my $numperrow = 2;  
         my $css_class = $$rowtotal%2?' class="LC_odd_row"':'';  
         $datatable .= '<tr'.$css_class.'>'.  
                      '<td class="LC_left_item">'.&mt('Mapping of Shibboleth environment variable names to user data fields (SSO auth)').'</td>'.  
                      '<td class="LC_left_item">'."\n".  
                      '<table>'."\n";  
         for (my $i=0; $i<@fields; $i++) {  
             $rem = $i%($numperrow);  
             if ($rem == 0) {  
                 if ($i > 0) {  
                     $datatable .= '</tr>';  
                 }  
                 $datatable .= '<tr>';  
             }  
             my $currval;  
             if (ref($createsettings) eq 'HASH') {  
                 if (ref($createsettings->{'shibenv'}) eq 'HASH') {  
                     $currval = $createsettings->{'shibenv'}{$fields[$i]};  
                 }  
             }  
             $datatable .= '<td class="LC_left_item">'.  
                           '<span class="LC_nobreak">'.  
                           '<input type="text" name="shibenv_'.$fields[$i].'" '.  
                           'value="'.$currval.'" size="10" />&nbsp;'.  
                           $fieldtitles{$fields[$i]}.'</span></td>';  
         }  
         my $colsleft = $numperrow - $rem;  
         if ($colsleft > 1 ) {  
             $datatable .= '<td colspan="'.$colsleft.'" class="LC_left_item">'.  
                          '&nbsp;</td>';  
         } elsif ($colsleft == 1) {  
             $datatable .= '<td class="LC_left_item">&nbsp;</td>';  
         }  
         $datatable .= '</tr></table></td></tr>';  
         $$rowtotal ++;  
     } elsif ($position eq 'middle') {  
         my %domconf = &Apache::lonnet::get_dom('configuration',['usermodification'],$dom);  
         my @posstypes;  
         if (ref($types) eq 'ARRAY') {  
             @posstypes = @{$types};  
         }  
         unless (grep(/^default$/,@posstypes)) {  
             push(@posstypes,'default');  
         }  
         my %usertypeshash;  
         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 {  
         my %choices = &Apache::lonlocal::texthash (  
                                                       cancreate_email => 'E-mail address as username',  
                                                   );  
         my @toggles = sort(keys(%choices));  
         my %defaultchecked = (  
                                'cancreate_email' => 'off',  
                              );  
         my $itemcount = 0;  
         my $display = 'none';  
         if (grep(/^\Qemail\E$/,@selfcreate)) {  
             $display = 'block';  
         }  
         my $onclick = "toggleDisplay(this.form,'emailoptions');";  
         my $additional = '<div id="emailoptions" style="display: '.$display.'">';  
         my %domdefaults = &Apache::lonnet::get_domain_defaults($dom);  
         my (@ordered,%usertypeshash);  
         if (ref($domdefaults{'inststatusguest'}) eq 'ARRAY') {  
             @ordered = @{$domdefaults{'inststatusguest'}};  
         }  
         if (@ordered) {  
             unless (grep(/^default$/,@ordered)) {  
                 push(@ordered,'default');  
             }  
             if (ref($usertypes) eq 'HASH') {  
                 %usertypeshash = %{$usertypes};  
             }  
             $usertypeshash{'default'} = $othertitle;  
             $additional .= '<table><tr>';  
             foreach my $status (@ordered) {  
                 $additional .= '<th>'.$usertypeshash{$status}.'</th>';  
             }  
             $additional .= '</tr><tr>';  
             foreach my $status (@ordered) {  
                 $additional .= '<td>'.&email_as_username($rowtotal,$processing,$status).'</td>';  
             }  
             $additional .= '</tr></table>';  
         } else {  
             $usertypeshash{'default'} = $othertitle;  
             $additional .= &email_as_username($rowtotal,$processing);  
         }  
         $additional .= '</div>'."\n";  
   
         ($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();  
         $numinrow = 1;  
         foreach my $status (@ordered) {  
             $datatable .= &modifiable_userdata_row('cancreate','emailusername_'.$status,$settings,  
                                                    $numinrow,$$rowtotal,\%usertypeshash,$infofields,$infotitles);  
             $$rowtotal ++;  
         }  
         my ($emailrules,$emailruleorder) =  
             &Apache::lonnet::inst_userrules($dom,'email');  
         if (ref($emailrules) eq 'HASH') {  
             if (keys(%{$emailrules}) > 0) {  
                 $datatable .= &user_formats_row('email',$settings,$emailrules,  
                                                 $emailruleorder,$numinrow,$$rowtotal);  
                 $$rowtotal ++;  
             }  
         }  
         $datatable .= &captcha_choice('cancreate',$createsettings,$$rowtotal);  
     }  
     return $datatable;  
 }  
   
 sub email_as_username {  
     my ($rowtotal,$processing,$type) = @_;  
     my %choices =  
         &Apache::lonlocal::texthash (  
                                       automatic => 'Automatic approval',  
                                       approval  => 'Queued for approval',  
                                     );  
     my $output;  
     foreach my $option ('automatic','approval') {  
         my $checked;  
         if (ref($processing) eq 'HASH') {  
             if ($type eq '') {     
                 if (!exists($processing->{'default'})) {  
                     if ($option eq 'automatic') {  
                         $checked = ' checked="checked"';  
                     }  
                 } else {  
                     if ($processing->{'default'} eq $option) {  
                         $checked = ' checked="checked"';  
                     }  
                 }  
             } else {  
                 if (!exists($processing->{$type})) {  
                     if ($option eq 'automatic') {  
                         $checked = ' checked="checked"';  
                     }  
                 } else {  
                     if ($processing->{$type} eq $option) {  
                         $checked = ' checked="checked"';  
                     }  
                 }  
             }  
         } 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 />';  
         }  
     }  
     $$rowtotal ++;  
     return $output;  
 }  
   
 sub captcha_choice {  sub captcha_choice {
     my ($context,$settings,$itemcount) = @_;      my ($context,$settings,$itemcount) = @_;
     my ($keyentry,$currpub,$currpriv,%checked,$rowname,$pubtext,$privtext,      my ($keyentry,$currpub,$currpriv,%checked,$rowname,$pubtext,$privtext);
         $vertext,$currver);   
     my %lt = &captcha_phrases();      my %lt = &captcha_phrases();
     $keyentry = 'hidden';      $keyentry = 'hidden';
     if ($context eq 'cancreate') {      if ($context eq 'cancreate') {
         $rowname = &mt('CAPTCHA validation');          $rowname = &mt('CAPTCHA validation (e-mail as username)');
     } elsif ($context eq 'login') {      } elsif ($context eq 'login') {
         $rowname =  &mt('"Contact helpdesk" CAPTCHA validation');          $rowname =  &mt('"Contact helpdesk" CAPTCHA validation');
     }      }
Line 5239  sub captcha_choice { Line 3544  sub captcha_choice {
             $pubtext = $lt{'pub'};              $pubtext = $lt{'pub'};
             $privtext = $lt{'priv'};              $privtext = $lt{'priv'};
             $keyentry = 'text';              $keyentry = 'text';
             $vertext = $lt{'ver'};  
             $currver = $settings->{'recaptchaversion'};  
             if ($currver ne '2') {  
                 $currver = 1;  
             }  
         }          }
         if (ref($settings->{'recaptchakeys'}) eq 'HASH') {          if (ref($settings->{'recaptchakeys'}) eq 'HASH') {
             $currpub = $settings->{'recaptchakeys'}{'public'};              $currpub = $settings->{'recaptchakeys'}{'public'};
Line 5267  sub captcha_choice { Line 3567  sub captcha_choice {
 #  #
 # Note: If reCAPTCHA is to be used for LON-CAPA servers in a domain, a domain coordinator should visit:  # Note: If reCAPTCHA is to be used for LON-CAPA servers in a domain, a domain coordinator should visit:
 # https://www.google.com/recaptcha and generate a Public and Private key. For domains with multiple  # https://www.google.com/recaptcha and generate a Public and Private key. For domains with multiple
 # servers a single key pair will be used for all servers, so the internet domain (e.g., yourcollege.edu)  # servers a single key pair will be used for all servers, so the internet domain (e.g., yourcollege.edu) 
 # specified for use with the key should be broad enough to accommodate all servers in the LON-CAPA domain.  # specified for use with the key should be broad enough to accommodate all servers in the LON-CAPA domain.
 #  #  
     $output .= '</td></tr>'."\n".      $output .= '</td></tr>'."\n".
                '<tr><td>'."\n".                 '<tr><td>'."\n".
                '<span class="LC_nobreak"><span id="'.$context.'_recaptchapubtxt">'.$pubtext.'</span>&nbsp;'."\n".                 '<span class="LC_nobreak"><span id="'.$context.'_recaptchapubtxt">'.$pubtext.'</span>&nbsp;'."\n".
Line 5277  sub captcha_choice { Line 3577  sub captcha_choice {
                $currpub.'" size="40" /></span><br />'."\n".                 $currpub.'" size="40" /></span><br />'."\n".
                '<span class="LC_nobreak"><span id="'.$context.'_recaptchaprivtxt">'.$privtext.'</span>&nbsp;'."\n".                 '<span class="LC_nobreak"><span id="'.$context.'_recaptchaprivtxt">'.$privtext.'</span>&nbsp;'."\n".
                '<input type="'.$keyentry.'" id="'.$context.'_recaptchapriv" name="'.$context.'_recaptchapriv" value="'.                 '<input type="'.$keyentry.'" id="'.$context.'_recaptchapriv" name="'.$context.'_recaptchapriv" value="'.
                $currpriv.'" size="40" /></span><br />'.                 $currpriv.'" size="40" /></span></td></tr></table>'."\n".
                '<span class="LC_nobreak"><span id="'.$context.'_recaptchavertxt">'.$vertext.'</span>&nbsp;'."\n".  
                '<input type="'.$keyentry.'" id="'.$context.'_recaptchaversion" name="'.$context.'_recaptchaversion" value="'.  
                $currver.'" size="3" /></span><br />'.  
                '</td></tr></table>'."\n".  
                '</td></tr>';                 '</td></tr>';
     return $output;      return $output;
 }  }
Line 5348  sub usercreation_types { Line 3644  sub usercreation_types {
                     author     => 'When adding a co-author',                      author     => 'When adding a co-author',
                     course     => 'When adding a user to a course',                      course     => 'When adding a user to a course',
                     requestcrs => 'When requesting a course',                      requestcrs => 'When requesting a course',
                       selfcreate => 'User creates own account', 
                     any        => 'Any',                      any        => 'Any',
                     official   => 'Institutional only ',                      official   => 'Institutional only ',
                     unofficial => 'Non-institutional only',                      unofficial => 'Non-institutional only',
                       email      => 'E-mail address',
                       login      => 'Institutional Login',
                       sso        => 'SSO', 
                     none       => 'None',                      none       => 'None',
     );      );
     return %lt;      return %lt;
 }  }
   
 sub selfcreation_types {  
     my %lt = &Apache::lonlocal::texthash (  
                     selfcreate => 'User creates own account',  
                     any        => 'Any',  
                     official   => 'Institutional only ',  
                     unofficial => 'Non-institutional only',  
                     email      => 'E-mail address',  
                     login      => 'Institutional Login',  
                     sso        => 'SSO',  
              );  
 }  
   
 sub authtype_names {  sub authtype_names {
     my %lt = &Apache::lonlocal::texthash(      my %lt = &Apache::lonlocal::texthash(
                       int    => 'Internal',                        int    => 'Internal',
Line 5400  sub print_usermodification { Line 3688  sub print_usermodification {
             $$rowtotal ++;              $$rowtotal ++;
             $rowcount ++;              $rowcount ++;
         }          }
     } elsif ($position eq 'bottom') {      } elsif ($position eq 'middle') {
         $context = 'course';          $context = 'course';
         $rowcount = 0;          $rowcount = 0;
         foreach my $role ('st','ep','ta','in','cr') {          foreach my $role ('st','ep','ta','in','cr') {
Line 5409  sub print_usermodification { Line 3697  sub print_usermodification {
             $$rowtotal ++;              $$rowtotal ++;
             $rowcount ++;              $rowcount ++;
         }          }
       } elsif ($position eq 'bottom') {
           $context = 'selfcreate';
           my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom);
           $usertypes->{'default'} = $othertitle;
           if (ref($types) eq 'ARRAY') {
               push(@{$types},'default');
               $usertypes->{'default'} = $othertitle;
               foreach my $status (@{$types}) {
                   $datatable .= &modifiable_userdata_row($context,$status,$settings,
                                                          $numinrow,$rowcount,$usertypes);
                   $$rowtotal ++;
                   $rowcount ++;
               }
           }
     }      }
     return $datatable;      return $datatable;
 }  }
   
 sub print_defaults {  sub print_defaults {
     my ($position,$dom,$settings,$rowtotal) = @_;      my ($dom,$rowtotal) = @_;
       my @items = ('auth_def','auth_arg_def','lang_def','timezone_def',
                    'datelocale_def','portal_def');
       my %domdefaults = &Apache::lonnet::get_domain_defaults($dom);
       my $titles = &defaults_titles($dom);
     my $rownum = 0;      my $rownum = 0;
     my ($datatable,$css_class,$titles);      my ($datatable,$css_class);
     unless ($position eq 'bottom') {      foreach my $item (@items) {
         $titles = &defaults_titles($dom);          if ($rownum%2) {
     }              $css_class = '';
     if ($position eq 'top') {  
         my @items = ('auth_def','auth_arg_def','lang_def','timezone_def',  
                      'datelocale_def','portal_def');  
         my %defaults;  
         if (ref($settings) eq 'HASH') {  
             %defaults = %{$settings};  
         } else {  
             my %domdefaults = &Apache::lonnet::get_domain_defaults($dom,1);  
             foreach my $item (@items) {  
                 $defaults{$item} = $domdefaults{$item};  
             }  
         }  
         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_right_item" colspan="3">';  
             if ($item eq 'auth_def') {  
                 my @authtypes = ('internal','krb4','krb5','localauth');  
                 my %shortauth = (  
                                  internal => 'int',  
                                  krb4 => 'krb4',  
                                  krb5 => 'krb5',  
                                  localauth  => 'loc'  
                                 );  
                 my %authnames = &authtype_names();  
                 foreach my $auth (@authtypes) {  
                     my $checked = ' ';  
                     if ($defaults{$item} eq $auth) {  
                         $checked = ' checked="checked" ';  
                     }  
                     $datatable .= '<label><input type="radio" name="'.$item.  
                                   '" value="'.$auth.'"'.$checked.'/>'.  
                                   $authnames{$shortauth{$auth}}.'</label>&nbsp;&nbsp;';  
                 }  
             } elsif ($item eq 'timezone_def') {  
                 my $includeempty = 1;  
                 $datatable .= &Apache::loncommon::select_timezone($item,$defaults{$item},undef,$includeempty);  
             } elsif ($item eq 'datelocale_def') {  
                 my $includeempty = 1;  
                 $datatable .= &Apache::loncommon::select_datelocale($item,$defaults{$item},undef,$includeempty);  
             } elsif ($item eq 'lang_def') {  
                 my $includeempty = 1;  
                 $datatable .= &Apache::loncommon::select_language($item,$defaults{$item},$includeempty);  
             } else {  
                 my $size;  
                 if ($item eq 'portal_def') {  
                     $size = ' size="25"';  
                 }  
                 $datatable .= '<input type="text" name="'.$item.'" value="'.  
                               $defaults{$item}.'"'.$size.' />';  
             }  
             $datatable .= '</td></tr>';  
             $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 {          } else {
             %defaults = (              $css_class = ' class="LC_odd_row" ';
                           'intauth_cost'   => 10,  
                           'intauth_check'  => 0,  
                           'intauth_switch' => 0,  
                         );  
         }          }
         foreach my $item (@items) {          $datatable .= '<tr'.$css_class.'>'.
             if ($rownum%2) {                    '<td><span class="LC_nobreak">'.$titles->{$item}.
                 $css_class = '';                    '</span></td><td class="LC_right_item">';
             } else {          if ($item eq 'auth_def') {
                 $css_class = ' class="LC_odd_row" ';              my @authtypes = ('internal','krb4','krb5','localauth');
             }              my %shortauth = (
             $datatable .= '<tr'.$css_class.'>'.                               internal => 'int',
                           '<td><span class="LC_nobreak">'.$titles->{$item}.                               krb4 => 'krb4',
                           '</span></td><td class="LC_left_item" colspan="3">';                               krb5 => 'krb5',
             if ($item eq 'intauth_switch') {                               localauth  => 'loc'
                 my @options = (0,1,2);                             );
                 my %optiondesc = &Apache::lonlocal::texthash (              my %authnames = &authtype_names();
                                    0 => 'No',              foreach my $auth (@authtypes) {
                                    1 => 'Yes',                  my $checked = ' ';
                                    2 => 'Yes, and copy existing passwd file to passwd.bak file',                  if ($domdefaults{$item} eq $auth) {
                                  );                      $checked = ' checked="checked" ';
                 $datatable .= '<table width="100%">';                  }
                 foreach my $option (@options) {                  $datatable .= '<label><input type="radio" name="'.$item.
                     my $checked = ' ';                                '" value="'.$auth.'"'.$checked.'/>'.
                     if ($defaults{$item} eq $option) {                                $authnames{$shortauth{$auth}}.'</label>&nbsp;&nbsp;';
                         $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 width="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>';          } elsif ($item eq 'timezone_def') {
             $rownum ++;              my $includeempty = 1;
         }              $datatable .= &Apache::loncommon::select_timezone($item,$domdefaults{$item},undef,$includeempty);
     } else {          } elsif ($item eq 'datelocale_def') {
         my %defaults;              my $includeempty = 1;
         if (ref($settings) eq 'HASH') {              $datatable .= &Apache::loncommon::select_datelocale($item,$domdefaults{$item},undef,$includeempty);
             if ((ref($settings->{'inststatusorder'}) eq 'ARRAY') && (ref($settings->{'inststatustypes'}) eq 'HASH') &&          } elsif ($item eq 'lang_def') {
                 (ref($settings->{'inststatusguest'}) eq 'ARRAY')) {              my %langchoices = &get_languages_hash();
                 my $maxnum = @{$settings->{'inststatusorder'}};              $langchoices{''} = 'No language preference';
                 for (my $i=0; $i<$maxnum; $i++) {              %langchoices = &Apache::lonlocal::texthash(%langchoices);
                     $css_class = $rownum%2?' class="LC_odd_row"':'';              $datatable .= &Apache::loncommon::select_form($domdefaults{$item},$item,
                     my $item = $settings->{'inststatusorder'}->[$i];                                                            \%langchoices);
                     my $title = $settings->{'inststatustypes'}->{$item};          } else {
                     my $guestok;              my $size;
                     if (grep(/^\Q$item\E$/,@{$settings->{'inststatusguest'}})) {              if ($item eq 'portal_def') {
                         $guestok = 1;                  $size = ' size="25"';
                     }  
                     my $chgstr = ' onchange="javascript:reorderTypes(this.form,'."'$item'".');"';  
                     $datatable .= '<tr'.$css_class.'>'.  
                                   '<td><span class="LC_nobreak">'.  
                                   '<select name="inststatus_pos_'.$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>';  
                     }  
                     my ($checkedon,$checkedoff);  
                     $checkedoff = ' checked="checked"';  
                     if ($guestok) {  
                         $checkedon = $checkedoff;  
                         $checkedoff = '';   
                     }  
                     $datatable .= '</select>&nbsp;'.&mt('Internal ID:').'&nbsp;<b>'.$item.'</b>&nbsp;'.  
                                   '<input type="checkbox" name="inststatus_delete" value="'.$item.'" />'.  
                                   &mt('delete').'</span></td>'.  
                                   '<td class="LC_left_item"><span class="LC_nobreak">'.&mt('Name displayed:').  
                                   '<input type="text" size="20" name="inststatus_title_'.$item.'" value="'.$title.'" />'.  
                                   '</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"':'';  
                 my $chgstr = ' onchange="javascript:reorderTypes(this.form,'."'addinststatus_pos'".');"';  
                 $datatable .= '<tr '.$css_class.'>'.  
                               '<td><span class="LC_nobreak"><select name="addinststatus_pos"'.$chgstr.'>';  
                 for (my $k=0; $k<=$maxnum; $k++) {  
                     my $vpos = $k+1;  
                     my $selstr;  
                     if ($k == $maxnum) {  
                         $selstr = ' selected="selected" ';  
                     }  
                     $datatable .= '<option value="'.$k.'"'.$selstr.'>'.$vpos.'</option>';  
                 }  
                 $datatable .= '</select>&nbsp;'.&mt('Internal ID:').  
                               '<input type="text" size="10" name="addinststatus" value="" />'.  
                               '&nbsp;'.&mt('(new)').  
                               '</span></td><td class="LC_left_item"><span class="LC_nobreak">'.  
                               &mt('Name displayed:').  
                               '<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";  
                 $rownum ++;  
             }              }
               $datatable .= '<input type="text" name="'.$item.'" value="'.
                             $domdefaults{$item}.'"'.$size.' />';
         }          }
           $datatable .= '</td></tr>';
           $rownum ++;
     }      }
     $$rowtotal += $rownum;      $$rowtotal += $rownum;
     return $datatable;      return $datatable;
Line 5654  sub defaults_titles { Line 3797  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 5848  sub print_coursecategories { Line 3988  sub print_coursecategories {
     my ($position,$dom,$hdritem,$settings,$rowtotal) = @_;      my ($position,$dom,$hdritem,$settings,$rowtotal) = @_;
     my $datatable;      my $datatable;
     if ($position eq 'top') {      if ($position eq 'top') {
         my (%checked);  
         my @catitems = ('unauth','auth');  
         my @cattypes = ('std','domonly','codesrch','none');  
         $checked{'unauth'} = 'std';  
         $checked{'auth'} = 'std';  
         if (ref($settings) eq 'HASH') {  
             foreach my $type (@cattypes) {  
                 if ($type eq $settings->{'unauth'}) {  
                     $checked{'unauth'} = $type;  
                 }  
                 if ($type eq $settings->{'auth'}) {  
                     $checked{'auth'} = $type;  
                 }  
             }  
         }  
         my %lt = &Apache::lonlocal::texthash (  
                                                unauth   => 'Catalog type for unauthenticated users',  
                                                auth     => 'Catalog type for authenticated users',  
                                                none     => 'No catalog',  
                                                std      => 'Standard catalog',  
                                                domonly  => 'Domain-only catalog',  
                                                codesrch => "Code search form",  
                                              );  
        my $itemcount = 0;  
        foreach my $item (@catitems) {  
            my $css_class = $itemcount%2? ' class="LC_odd_row"':'';  
            $datatable .= '<tr '.$css_class.'>'.  
                          '<td>'.$lt{$item}.'</td>'.  
                          '<td class="LC_right_item"><span class="LC_nobreak">';  
            foreach my $type (@cattypes) {  
                my $ischecked;  
                if ($checked{$item} eq $type) {  
                    $ischecked=' checked="checked"';  
                }  
                $datatable .= '<label>'.  
                              '<input type="radio" name="coursecat_'.$item.'" value="'.$type.'"'.$ischecked.  
                              ' />'.$lt{$type}.'</label>&nbsp;';  
            }  
            $datatable .= '</span></td></tr>';  
            $itemcount ++;  
         }  
         $$rowtotal += $itemcount;  
     } elsif ($position eq 'middle') {  
         my $toggle_cats_crs = ' ';          my $toggle_cats_crs = ' ';
         my $toggle_cats_dom = ' checked="checked" ';          my $toggle_cats_dom = ' checked="checked" ';
         my $can_cat_crs = ' ';          my $can_cat_crs = ' ';
Line 6008  sub print_coursecategories { Line 4105  sub print_coursecategories {
                             }                              }
                             $datatable .= '<option value="'.$k.'"'.$selstr.'>'.$vpos.'</option>';                              $datatable .= '<option value="'.$k.'"'.$selstr.'>'.$vpos.'</option>';
                         }                          }
                         $datatable .= '</select></span></td><td>';                          $datatable .= '</select></td><td>';
                         if ($parent eq 'instcode' || $parent eq 'communities') {                          if ($parent eq 'instcode' || $parent eq 'communities') {
                             $datatable .=  '<span class="LC_nobreak">'                              $datatable .=  '<span class="LC_nobreak">'
                                            .$default_names{$parent}.'</span>';                                             .$default_names{$parent}.'</span>';
Line 6038  sub print_coursecategories { Line 4135  sub print_coursecategories {
                             $datatable .= '</td>';                              $datatable .= '</td>';
                         } else {                          } else {
                             $datatable .= $parent                              $datatable .= $parent
                                           .'&nbsp;<span class="LC_nobreak"><label>'                                            .'&nbsp;<label><input type="checkbox" name="deletecategory" '
                                           .'<input type="checkbox" name="deletecategory" '  
                                           .'value="'.$item.'" />'.&mt('Delete').'</label></span></td>';                                            .'value="'.$item.'" />'.&mt('Delete').'</label></span></td>';
                         }                          }
                         my $depth = 1;                          my $depth = 1;
Line 6097  sub print_coursecategories { Line 4193  sub print_coursecategories {
                 $datatable .= &initialize_categories($itemcount);                  $datatable .= &initialize_categories($itemcount);
             }              }
         } else {          } else {
             $datatable .= '<tr><td class="LC_right_item">'.$hdritem->{'header'}->[1]->{'col2'}.'</td></tr>'              $datatable .= '<td class="LC_right_item">'.$hdritem->{'header'}->[0]->{'col2'}.'</td>'
                           .&initialize_categories($itemcount);                            .&initialize_categories($itemcount);
         }          }
         $$rowtotal += $itemcount;          $$rowtotal += $itemcount;
Line 6145  sub print_serverstatuses { Line 4241  sub print_serverstatuses {
                       '<span class="LC_nobreak">'.                        '<span class="LC_nobreak">'.
                       '<input type="text" name="'.$type.'_machines" '.                        '<input type="text" name="'.$type.'_machines" '.
                       'value="'.$machineaccess{$type}.'" size="10" />'.                        'value="'.$machineaccess{$type}.'" size="10" />'.
                       '</span></td></tr>'."\n";                        '</td></tr>'."\n";
     }      }
     $$rowtotal += $rownum;      $$rowtotal += $rownum;
     return $datatable;      return $datatable;
Line 6154  sub print_serverstatuses { Line 4250  sub print_serverstatuses {
 sub serverstatus_pages {  sub serverstatus_pages {
     return ('userstatus','lonstatus','loncron','server-status','codeversions',      return ('userstatus','lonstatus','loncron','server-status','codeversions',
             'checksums','clusterstatus','metadata_keywords','metadata_harvest',              'checksums','clusterstatus','metadata_keywords','metadata_harvest',
             'takeoffline','takeonline','showenv','toggledebug','ping','domconf',              'takeoffline','takeonline','showenv','toggledebug','ping','domconf');
             'uniquecodes','diskusage','coursecatalog');  
 }  
   
 sub defaults_javascript {  
     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.');  
     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')) {  
         my $maxnum = scalar(@{$settings->{'inststatusorder'}});  
         if ($maxnum eq '') {  
             $maxnum = 0;  
         }  
         $maxnum ++;  
         my $jstext = '    var inststatuses = Array('."'".join("','",@{$settings->{'inststatusorder'}})."'".');';    
         return <<"ENDSCRIPT";  
 <script type="text/javascript">  
 // <![CDATA[  
 function reorderTypes(form,caller) {  
     var changedVal;  
 $jstext   
     var newpos = 'addinststatus_pos';  
     var current = new Array;  
     var maxh = $maxnum;  
     var newitemVal = form.elements[newpos].options[form.elements[newpos].selectedIndex].value;  
     var oldVal;  
     if (caller == newpos) {  
         changedVal = newitemVal;  
     } else {  
         var curritem = 'inststatus_pos_'+caller;  
         changedVal = form.elements[curritem].options[form.elements[curritem].selectedIndex].value;  
         current[newitemVal] = newpos;  
     }  
     for (var i=0; i<inststatuses.length; i++) {  
         if (inststatuses[i] != caller) {  
             var elementName = 'inststatus_pos_'+inststatuses[i];  
             if (form.elements[elementName]) {  
                 var currVal = form.elements[elementName].options[form.elements[elementName].selectedIndex].value;  
                 current[currVal] = elementName;  
             }  
         }  
     }  
     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;  
 }  
   
 $intauthjs  
   
 // ]]>  
 </script>  
   
 ENDSCRIPT  
     } else {  
         return &Apache::lonhtmlcommon::scripttag($intauthjs);  
     }  
 }  }
   
 sub coursecategories_javascript {  sub coursecategories_javascript {
Line 6275  sub coursecategories_javascript { Line 4275  sub coursecategories_javascript {
         $jstext  = '    var categories = Array(1);'."\n".          $jstext  = '    var categories = Array(1);'."\n".
                    '    categories[0] = Array("instcode_pos");'."\n";                      '    categories[0] = Array("instcode_pos");'."\n"; 
     }      }
     my $instcode_reserved = &mt('The name: [_1] is a reserved category.','"instcode"');      my $instcode_reserved = &mt('The name: "instcode" is a reserved category');
     my $communities_reserved = &mt('The name: [_1] is a reserved category.','"communities"');      my $communities_reserved = &mt('The name: "communities" is a reserved category');
     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(\$communities_reserved);  
     &js_escape(\$choose_again);  
     $output = <<"ENDSCRIPT";      $output = <<"ENDSCRIPT";
 <script type="text/javascript">  <script type="text/javascript">
 // <![CDATA[  // <![CDATA[
Line 6288  function reorderCats(form,parent,item,id Line 4285  function reorderCats(form,parent,item,id
     var changedVal;      var changedVal;
 $jstext  $jstext
     var newpos = 'addcategory_pos';      var newpos = 'addcategory_pos';
       var current = new Array;
     if (parent == '') {      if (parent == '') {
         var has_instcode = 0;          var has_instcode = 0;
         var maxtop = categories[idx].length;          var maxtop = categories[idx].length;
Line 6370  sub initialize_categories { Line 4368  sub initialize_categories {
     my $select1 = '';      my $select1 = '';
     foreach my $default ('instcode','communities') {      foreach my $default ('instcode','communities') {
         $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') {
             $select1 = $select0;              $select1 = $select0;
             $select0 = '';              $select0 = '';
Line 6395  sub initialize_categories { Line 4393  sub initialize_categories {
                   .'<option value="0">1</option>'                    .'<option value="0">1</option>'
                   .'<option value="1">2</option>'                    .'<option value="1">2</option>'
                   .'<option value="2" selected="selected">3</option></select>&nbsp;'                    .'<option value="2" selected="selected">3</option></select>&nbsp;'
                   .&mt('Add category').'</span></td><tda<span class="LC_nobreak">>'.&mt('Name:')                    .&mt('Add category').'</td><td>'.&mt('Name:')
                   .'&nbsp;<input type="text" size="20" name="addcategory_name" value="" /></span>'                    .'&nbsp;<input type="text" size="20" name="addcategory_name" value="" /></td></tr>';
                   .'</td></tr>';  
     return $datatable;      return $datatable;
 }  }
   
Line 6410  sub build_category_rows { Line 4407  sub build_category_rows {
             if (ref($cats->[$depth]{$parent}) eq 'ARRAY') {              if (ref($cats->[$depth]{$parent}) eq 'ARRAY') {
                 my $numchildren = @{$cats->[$depth]{$parent}};                  my $numchildren = @{$cats->[$depth]{$parent}};
                 my $css_class = $itemcount%2?' class="LC_odd_row"':'';                  my $css_class = $itemcount%2?' class="LC_odd_row"':'';
                 $text .= '<td><table class="LC_data_table">';                  $text .= '<td><table class="LC_datatable">';
                 my ($idxnum,$parent_name,$parent_item);                  my ($idxnum,$parent_name,$parent_item);
                 my $higher = $depth - 1;                  my $higher = $depth - 1;
                 if ($higher == 0) {                  if ($higher == 0) {
Line 6452  sub build_category_rows { Line 4449  sub build_category_rows {
                             pop(@{$path});                              pop(@{$path});
                         }                          }
                     } else {                      } else {
                         $text .= &mt('Add subcategory:').'&nbsp;</span><input type="text" size="20" name="addcategory_name_';                          $text .= &mt('Add subcategory:').'&nbsp;</span><input type="textbox" size="20" name="addcategory_name_';
                         if ($j == $numchildren) {                          if ($j == $numchildren) {
                             $text .= $name;                              $text .= $name;
                         } else {                          } else {
Line 6475  sub build_category_rows { Line 4472  sub build_category_rows {
                 my $colspan;                  my $colspan;
                 if ($parent ne 'instcode') {                  if ($parent ne 'instcode') {
                     $colspan = $maxdepth - $depth - 1;                      $colspan = $maxdepth - $depth - 1;
                     $text .= '<td colspan="'.$colspan.'">'.&mt('Add subcategory:').'<input type="text" size="20" name="subcat_'.$name.'" value="" /></td>';                      $text .= '<td colspan="'.$colspan.'">'.&mt('Add subcategory:').'<input type="textbox" size="20" name="subcat_'.$name.'" value="" /></td>';
                 }                  }
             }              }
         }          }
Line 6484  sub build_category_rows { Line 4481  sub build_category_rows {
 }  }
   
 sub modifiable_userdata_row {  sub modifiable_userdata_row {
     my ($context,$item,$settings,$numinrow,$rowcount,$usertypes,$fieldsref,$titlesref) = @_;      my ($context,$role,$settings,$numinrow,$rowcount,$usertypes) = @_;
     my ($role,$rolename,$statustype);      my $rolename;
     $role = $item;      if ($context eq 'selfcreate') {
     if ($context eq 'cancreate') {  
         if ($item =~ /^emailusername_(.+)$/) {  
             $statustype = $1;  
             $role = 'emailusername';  
             if (ref($usertypes) eq 'HASH') {  
                 if ($usertypes->{$statustype}) {  
                     $rolename = &mt('Data provided by [_1]',$usertypes->{$statustype});  
                 } else {  
                     $rolename = &mt('Data provided by user');  
                 }  
             }  
         }  
     } elsif ($context eq 'selfcreate') {  
         if (ref($usertypes) eq 'HASH') {          if (ref($usertypes) eq 'HASH') {
             $rolename = $usertypes->{$role};              $rolename = $usertypes->{$role};
         } else {          } else {
Line 6512  sub modifiable_userdata_row { Line 4496  sub modifiable_userdata_row {
             $rolename = &Apache::lonnet::plaintext($role);              $rolename = &Apache::lonnet::plaintext($role);
         }          }
     }      }
     my (@fields,%fieldtitles);      my @fields = ('lastname','firstname','middlename','generation',
     if (ref($fieldsref) eq 'ARRAY') {                    'permanentemail','id');
         @fields = @{$fieldsref};      my %fieldtitles = &Apache::loncommon::personal_data_fieldtitles();
     } else {  
         @fields = ('lastname','firstname','middlename','generation',  
                    'permanentemail','id');  
     }  
     if ((ref($titlesref) eq 'HASH')) {  
         %fieldtitles = %{$titlesref};  
     } else {  
         %fieldtitles = &Apache::loncommon::personal_data_fieldtitles();  
     }  
     my $output;      my $output;
     my $css_class = $rowcount%2?' class="LC_odd_row"':'';      my $css_class = $rowcount%2?' class="LC_odd_row"':'';
     $output = '<tr '.$css_class.'>'.      $output = '<tr '.$css_class.'>'.
Line 6534  sub modifiable_userdata_row { Line 4509  sub modifiable_userdata_row {
     if (ref($settings) eq 'HASH') {      if (ref($settings) eq 'HASH') {
         if (ref($settings->{$context}) eq 'HASH') {          if (ref($settings->{$context}) eq 'HASH') {
             if (ref($settings->{$context}->{$role}) eq 'HASH') {              if (ref($settings->{$context}->{$role}) eq 'HASH') {
                 my $hashref = $settings->{$context}->{$role};                  foreach my $field (@fields) {
                 if ($role eq 'emailusername') {                      if ($settings->{$context}->{$role}->{$field}) {
                     if ($statustype) {                          $checks{$field} = ' checked="checked" ';
                         if (ref($settings->{$context}->{$role}->{$statustype}) eq 'HASH') {  
                             $hashref = $settings->{$context}->{$role}->{$statustype};  
                             if (ref($hashref) eq 'HASH') {   
                                 foreach my $field (@fields) {  
                                     if ($hashref->{$field}) {  
                                         $checks{$field} = $hashref->{$field};  
                                     }  
                                 }  
                             }  
                         }  
                     }  
                 } else {  
                     if (ref($hashref) eq 'HASH') {  
                         foreach my $field (@fields) {  
                             if ($hashref->{$field}) {  
                                 $checks{$field} = ' checked="checked" ';  
                             }  
                         }  
                     }                      }
                 }                  }
             }              }
         }          }
     }      }
        
     for (my $i=0; $i<@fields; $i++) {      for (my $i=0; $i<@fields; $i++) {
         my $rem = $i%($numinrow);          my $rem = $i%($numinrow);
         if ($rem == 0) {          if ($rem == 0) {
Line 6570  sub modifiable_userdata_row { Line 4526  sub modifiable_userdata_row {
             $output .= '<tr>';              $output .= '<tr>';
         }          }
         my $check = ' ';          my $check = ' ';
         unless ($role eq 'emailusername') {          if (exists($checks{$fields[$i]})) {
             if (exists($checks{$fields[$i]})) {              $check = $checks{$fields[$i]}
                 $check = $checks{$fields[$i]}          } else {
             } else {              if ($role eq 'st') {
                 if ($role eq 'st') {                  if (ref($settings) ne 'HASH') {
                     if (ref($settings) ne 'HASH') {                      $check = ' checked="checked" '; 
                         $check = ' checked="checked" ';   
                     }  
                 }                  }
             }              }
         }          }
         $output .= '<td class="LC_left_item">'.          $output .= '<td class="LC_left_item">'.
                    '<span class="LC_nobreak">';                     '<span class="LC_nobreak"><label>'.
         if ($role eq 'emailusername') {                     '<input type="checkbox" name="canmodify_'.$role.'" '.
             unless ($checks{$fields[$i]} =~ /^(required|optional)$/) {                     'value="'.$fields[$i].'"'.$check.'/>'.$fieldtitles{$fields[$i]}.
                 $checks{$fields[$i]} = 'omit';                     '</label></span></td>';
             }  
             foreach my $option ('required','optional','omit') {  
                 my $checked='';  
                 if ($checks{$fields[$i]} eq $option) {  
                     $checked='checked="checked" ';  
                 }  
                 $output .= '<label>'.  
                            '<input type="radio" name="canmodify_'.$item.'_'.$fields[$i].'" value="'.$option.'" '.$checked.'/>'.  
                            &mt($option).'</label>'.('&nbsp;' x2);  
             }  
             $output .= '<i>'.$fieldtitles{$fields[$i]}.'</i>';  
         } else {  
             $output .= '<label>'.  
                        '<input type="checkbox" name="canmodify_'.$role.'" '.  
                        'value="'.$fields[$i].'"'.$check.'/>'.$fieldtitles{$fields[$i]}.  
                        '</label>';  
         }  
         $output .= '</span></td>';  
         $rem = @fields%($numinrow);          $rem = @fields%($numinrow);
     }      }
     my $colsleft = $numinrow - $rem;      my $colsleft = $numinrow - $rem;
Line 6618  sub modifiable_userdata_row { Line 4554  sub modifiable_userdata_row {
 }  }
   
 sub insttypes_row {  sub insttypes_row {
     my ($settings,$types,$usertypes,$dom,$numinrow,$othertitle,$context,$rownum) = @_;      my ($settings,$types,$usertypes,$dom,$numinrow,$othertitle,$context) = @_;
     my %lt = &Apache::lonlocal::texthash (      my %lt = &Apache::lonlocal::texthash (
                       cansearch => 'Users allowed to search',                        cansearch => 'Users allowed to search',
                       statustocreate => 'Institutional affiliation(s) able to create own account (login/SSO)',                        statustocreate => 'Institutional affiliation(s) able to create own account (login/SSO)',
Line 6632  sub insttypes_row { Line 4568  sub insttypes_row {
     if ($context eq 'statustocreate') {      if ($context eq 'statustocreate') {
         $class = 'LC_right_item';          $class = 'LC_right_item';
     }      }
     my $css_class = ' class="LC_odd_row"';      my $output =  '<tr class="LC_odd_row">'.
     if ($rownum ne '') {                     '<td>'.$lt{$context}.$showdom.
         $css_class = ($rownum%2? ' class="LC_odd_row"':'');                    '</td><td class="'.$class.'" colspan="2"><table>';
     }  
     my $output = '<tr'.$css_class.'>'.  
                  '<td>'.$lt{$context}.$showdom.  
                  '</td><td class="'.$class.'" colspan="2"><table>';  
     my $rem;      my $rem;
     if (ref($types) eq 'ARRAY') {      if (ref($types) eq 'ARRAY') {
         for (my $i=0; $i<@{$types}; $i++) {          for (my $i=0; $i<@{$types}; $i++) {
Line 6670  sub insttypes_row { Line 4602  sub insttypes_row {
         $rem = @{$types}%($numinrow);          $rem = @{$types}%($numinrow);
     }      }
     my $colsleft = $numinrow - $rem;      my $colsleft = $numinrow - $rem;
     if ($rem == 0) {      if (($rem == 0) && (@{$types} > 0)) {
         $output .= '<tr>';          $output .= '<tr>';
     }      }
     if ($colsleft > 1) {      if ($colsleft > 1) {
Line 6767  sub usertype_update_row { Line 4699  sub usertype_update_row {
 }  }
   
 sub modify_login {  sub modify_login {
     my ($r,$dom,$confname,$lastactref,%domconfig) = @_;      my ($r,$dom,$confname,%domconfig) = @_;
     my ($resulttext,$errors,$colchgtext,%changes,%colchanges,%newfile,%newurl,      my ($resulttext,$errors,$colchgtext,%changes,%colchanges,%newfile,%newurl,
         %curr_loginvia,%loginhash,@currlangs,@newlangs,$addedfile,%title,@offon);          %curr_loginvia,%loginhash,@currlangs,@newlangs,$addedfile,%title,@offon);
     %title = ( coursecatalog => 'Display course catalog',      %title = ( coursecatalog => 'Display course catalog',
Line 6796  sub modify_login { Line 4728  sub modify_login {
     }      }
   
     my %servers = &Apache::lonnet::internet_dom_servers($dom);      my %servers = &Apache::lonnet::internet_dom_servers($dom);
     my %domservers = &Apache::lonnet::get_servers($dom);  
     my @loginvia_attribs = ('serverpath','custompath','exempt');      my @loginvia_attribs = ('serverpath','custompath','exempt');
     if (keys(%servers) > 1) {      if (keys(%servers) > 1) {
         foreach my $lonhost (keys(%servers)) {          foreach my $lonhost (keys(%servers)) {
Line 6839  sub modify_login { Line 4770  sub modify_login {
                             $changes{'loginvia'}{$lonhost} = 1;                              $changes{'loginvia'}{$lonhost} = 1;
                         }                          }
                         if ($item eq 'exempt') {                          if ($item eq 'exempt') {
                             $new = &check_exempt_addresses($new);                              $new =~ s/^\s+//;
                               $new =~ s/\s+$//;
                               my @poss_ips = split(/\s*[,:]\s*/,$new);
                               my @okips;
                               foreach my $ip (@poss_ips) {
                                   if ($ip =~ /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/) {
                                       if (($1 <= 255) && ($2 <= 255) && ($3 <= 255) && ($4 <= 255)) {
                                           push(@okips,$ip); 
                                       }
                                   }
                               }
                               if (@okips > 0) {
                                   $new = join(',',@okips); 
                               } else {
                                   $new = ''; 
                               }
                         }                          }
                         $loginhash{login}{loginvia}{$lonhost}{$item} = $new;                          $loginhash{login}{loginvia}{$lonhost}{$item} = $new;
                     }                      }
Line 6933  sub modify_login { Line 4879  sub modify_login {
                     } else {                      } else {
                         my $puberror = &mt("Upload of [_1] failed because an error occurred publishing the file in RES space. Error was: [_2].",$newfile{$lang},$result);                          my $puberror = &mt("Upload of [_1] failed because an error occurred publishing the file in RES space. Error was: [_2].",$newfile{$lang},$result);
                         $errors .= '<li><span class="LC_error">'.$puberror.'</span></li>';                          $errors .= '<li><span class="LC_error">'.$puberror.'</span></li>';
                         if ((grep(/^\Q$lang\E$/,@currlangs)) &&                          if ((grep(/^\Q$lang\E$/,@currlangs)) && 
                             (!grep(/^\Q$lang\E$/,@delurls))) {                              (!grep(/^\Q$lang\E$/,@delurls))) {
   
                             $loginhash{'login'}{'helpurl'}{$lang} = $domconfig{'login'}{'helpurl'}{$lang};                              $loginhash{'login'}{'helpurl'}{$lang} = $domconfig{'login'}{'helpurl'}{$lang};
                         }                          }
                     }                      }
Line 6950  sub modify_login { Line 4897  sub modify_login {
             $errors .= '<li><span class="LC_error">'.$error.'</span></li>';              $errors .= '<li><span class="LC_error">'.$error.'</span></li>';
         }          }
     }      }
   
     my (%currheadtagurls,%currexempt,@newhosts,%newheadtagurls,%possexempt);  
     if (ref($domconfig{'login'}) eq 'HASH') {  
         if (ref($domconfig{'login'}{'headtag'}) eq 'HASH') {  
             foreach my $lonhost (keys(%{$domconfig{'login'}{'headtag'}})) {  
                 if ($domservers{$lonhost}) {  
                     if (ref($domconfig{'login'}{'headtag'}{$lonhost}) eq 'HASH') {  
                         $currheadtagurls{$lonhost} = $domconfig{'login'}{'headtag'}{$lonhost}{'url'};  
                         $currexempt{$lonhost} = $domconfig{'login'}{'headtag'}{$lonhost}{'exempt'};  
                     }  
                 }  
             }  
         }  
     }  
     my @delheadtagurls = &Apache::loncommon::get_env_multiple('form.loginheadtag_del');  
     foreach my $lonhost (sort(keys(%domservers))) {  
         if (grep(/^\Q$lonhost\E$/,@delheadtagurls)) {  
             $changes{'headtag'}{$lonhost} = 1;  
         } else {  
             if ($env{'form.loginheadtagexempt_'.$lonhost}) {  
                 $possexempt{$lonhost} = &check_exempt_addresses($env{'form.loginheadtagexempt_'.$lonhost});  
             }  
             if ($env{'form.loginheadtag_'.$lonhost.'.filename'}) {  
                 push(@newhosts,$lonhost);  
             } elsif ($currheadtagurls{$lonhost}) {  
                 $loginhash{'login'}{'headtag'}{$lonhost}{'url'} = $currheadtagurls{$lonhost};  
                 if ($currexempt{$lonhost}) {  
                     if ((!exists($possexempt{$lonhost})) || ($possexempt{$lonhost} ne $currexempt{$lonhost})) {  
                         $changes{'headtag'}{$lonhost} = 1;  
                     }  
                 } elsif ($possexempt{$lonhost}) {  
                     $changes{'headtag'}{$lonhost} = 1;  
                 }  
                 if ($possexempt{$lonhost}) {  
                     $loginhash{'login'}{'headtag'}{$lonhost}{'exempt'} = $possexempt{$lonhost};  
                 }  
             }  
         }  
     }  
     if (@newhosts) {  
         my $error;  
         my ($configuserok,$author_ok,$switchserver) = &config_check($dom,$confname,$servadm);  
         if ($configuserok eq 'ok') {  
             if ($switchserver) {  
                 $error = &mt("Upload of custom markup is not permitted to this server: [_1]",$switchserver);  
             } elsif ($author_ok eq 'ok') {  
                 foreach my $lonhost (@newhosts) {  
                     my $formelem = 'loginheadtag_'.$lonhost;  
                     (my $result,$newheadtagurls{$lonhost}) = &publishlogo($r,'upload',$formelem,$dom,$confname,  
                                                                           "login/headtag/$lonhost",'','',  
                                                                           $env{'form.loginheadtag_'.$lonhost.'.filename'});  
                     if ($result eq 'ok') {  
                         $loginhash{'login'}{'headtag'}{$lonhost}{'url'} = $newheadtagurls{$lonhost};  
                         $changes{'headtag'}{$lonhost} = 1;  
                         if ($possexempt{$lonhost}) {  
                             $loginhash{'login'}{'headtag'}{$lonhost}{'exempt'} = $possexempt{$lonhost};  
                         }  
                     } else {  
                         my $puberror = &mt("Upload of [_1] failed because an error occurred publishing the file in RES space. Error was: [_2].",  
                                            $newheadtagurls{$lonhost},$result);  
                         $errors .= '<li><span class="LC_error">'.$puberror.'</span></li>';  
                         if ((grep(/^\Q$lonhost\E$/,keys(%currheadtagurls))) &&  
                             (!grep(/^\Q$lonhost\E$/,@delheadtagurls))) {  
                             $loginhash{'login'}{'headtag'}{$lonhost} = $currheadtagurls{$lonhost};  
                         }  
                     }  
                 }  
             } else {  
                 $error = &mt("Upload of custom markup file(s) failed because an author role could not be assigned to a Domain Configuration user ([_1]) in domain: [_2].  Error was: [_3].",$confname,$dom,$author_ok);  
             }  
         } else {  
             $error = &mt("Upload of custom markup file(s) failed because a Domain Configuration user ([_1]) could not be created in domain: [_2].  Error was: [_3].",$confname,$dom,$configuserok);  
         }  
         if ($error) {  
             &Apache::lonnet::logthis($error);  
             $errors .= '<li><span class="LC_error">'.$error.'</span></li>';  
         }  
     }  
     &process_captcha('login',\%changes,$loginhash{'login'},$domconfig{'login'});      &process_captcha('login',\%changes,$loginhash{'login'},$domconfig{'login'});
   
     my $defaulthelpfile = '/adm/loginproblems.html';      my $defaulthelpfile = '/adm/loginproblems.html';
Line 7068  sub modify_login { Line 4937  sub modify_login {
         }          }
         if (keys(%changes) > 0 || $colchgtext) {          if (keys(%changes) > 0 || $colchgtext) {
             &Apache::loncommon::devalidate_domconfig_cache($dom);              &Apache::loncommon::devalidate_domconfig_cache($dom);
             if (ref($lastactref) eq 'HASH') {  
                 $lastactref->{'domainconfig'} = 1;  
             }  
             $resulttext = &mt('Changes made:').'<ul>';              $resulttext = &mt('Changes made:').'<ul>';
             foreach my $item (sort(keys(%changes))) {              foreach my $item (sort(keys(%changes))) {
                 if ($item eq 'loginvia') {                  if ($item eq 'loginvia') {
Line 7128  sub modify_login { Line 4994  sub modify_login {
                             }                              }
                         }                          }
                     }                      }
                 } elsif ($item eq 'headtag') {  
                     if (ref($changes{$item}) eq 'HASH') {  
                         foreach my $lonhost (sort(keys(%{$changes{$item}}))) {  
                             if (grep(/^\Q$lonhost\E$/,@delheadtagurls)) {  
                                 $resulttext .= '<li>'.&mt('custom markup file removed for [_1]',$domservers{$lonhost}).'</li>';  
                             } elsif (ref($loginhash{'login'}{'headtag'}{$lonhost}) eq 'HASH') {  
                                 $resulttext .= '<li><a href="'.  
                                                "javascript:void(open('$loginhash{'login'}{'headtag'}{$lonhost}{'url'}?inhibitmenu=yes','Custom_HeadTag',  
                                                'menubar=0,toolbar=1,scrollbars=1,width=600,height=500,resizable=yes'))".  
                                                '">'.&mt('custom markup').'</a> '.&mt('(for [_1])',$servers{$lonhost}).' ';  
                                 if ($possexempt{$lonhost}) {  
                                     $resulttext .= &mt('not included for client IP(s): [_1]',$possexempt{$lonhost});  
                                 } else {  
                                     $resulttext .= &mt('included for any client IP');  
                                 }  
                                 $resulttext .= '</li>';  
                             }  
                         }  
                     }  
                 } elsif ($item eq 'captcha') {                  } elsif ($item eq 'captcha') {
                     if (ref($loginhash{'login'}) eq 'HASH') {                      if (ref($loginhash{'login'}) eq 'HASH') {
                         my $chgtxt;                          my $chgtxt; 
                         if ($loginhash{'login'}{$item} eq 'notused') {                          if ($loginhash{'login'}{$item} eq 'notused') {
                             $chgtxt .= &mt('No CAPTCHA validation in use for helpdesk form.');                              $chgtxt .= &mt('No CAPTCHA validation in use for helpdesk form.');
                         } else {                          } else {
Line 7178  sub modify_login { Line 5025  sub modify_login {
                         if (!$privkey) {                          if (!$privkey) {
                             $chgtxt .= '<li>'.&mt('Private key deleted').'</li>';                              $chgtxt .= '<li>'.&mt('Private key deleted').'</li>';
                         } else {                          } else {
                             $chgtxt .= '<li>'.&mt('Private key set to [_1]',$privkey).'</li>';                              $chgtxt .= '<li>'.&mt('Private key set to [_1]',$pubkey).'</li>';
                         }                          }
                         $chgtxt .= '</ul>';                          $chgtxt .= '</ul>';
                         $resulttext .= '<li>'.$chgtxt.'</li>';                          $resulttext .= '<li>'.$chgtxt.'</li>';
                     }                      }
                 } elsif ($item eq 'recaptchaversion') {  
                     if (ref($loginhash{'login'}) eq 'HASH') {  
                         if ($loginhash{'login'}{'captcha'} eq 'recaptcha') {  
                             $resulttext .= '<li>'.&mt('ReCAPTCHA for helpdesk form set to version [_1]',$loginhash{'login'}{'recaptchaversion'}).  
                                            '</li>';  
                         }  
                     }  
                 } else {                  } else {
                     $resulttext .= '<li>'.&mt("$title{$item} set to $offon[$env{'form.'.$item}]").'</li>';                      $resulttext .= '<li>'.&mt("$title{$item} set to $offon[$env{'form.'.$item}]").'</li>';
                 }                  }
Line 7209  sub modify_login { Line 5049  sub modify_login {
     return $resulttext;      return $resulttext;
 }  }
   
 sub check_exempt_addresses {  
     my ($iplist) = @_;  
     $iplist =~ s/^\s+//;  
     $iplist =~ s/\s+$//;  
     my @poss_ips = split(/\s*[,:]\s*/,$iplist);  
     my (@okips,$new);  
     foreach my $ip (@poss_ips) {  
         if ($ip =~ /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/) {  
             if (($1 <= 255) && ($2 <= 255) && ($3 <= 255) && ($4 <= 255)) {  
                 push(@okips,$ip);  
             }  
         }  
     }  
     if (@okips > 0) {  
         $new = join(',',@okips);  
     } else {  
         $new = '';  
     }  
     return $new;  
 }  
   
 sub color_font_choices {  sub color_font_choices {
     my %choices =      my %choices =
         &Apache::lonlocal::texthash (          &Apache::lonlocal::texthash (
Line 7238  sub color_font_choices { Line 5057  sub color_font_choices {
             links => "Link colors",              links => "Link colors",
             images => "Images",              images => "Images",
             font => "Font color",              font => "Font color",
             fontmenu => "Font menu",              fontmenu => "Font Menu",
             pgbg => "Page",              pgbg => "Page",
             tabbg => "Header",              tabbg => "Header",
             sidebg => "Border",              sidebg => "Border",
Line 7250  sub color_font_choices { Line 5069  sub color_font_choices {
 }  }
   
 sub modify_rolecolors {  sub modify_rolecolors {
     my ($r,$dom,$confname,$roles,$lastactref,%domconfig) = @_;      my ($r,$dom,$confname,$roles,%domconfig) = @_;
     my ($resulttext,%rolehash);      my ($resulttext,%rolehash);
     $rolehash{'rolecolors'} = {};      $rolehash{'rolecolors'} = {};
     if (ref($domconfig{'rolecolors'}) ne 'HASH') {      if (ref($domconfig{'rolecolors'}) ne 'HASH') {
Line 7265  sub modify_rolecolors { Line 5084  sub modify_rolecolors {
     if ($putresult eq 'ok') {      if ($putresult eq 'ok') {
         if (keys(%changes) > 0) {          if (keys(%changes) > 0) {
             &Apache::loncommon::devalidate_domconfig_cache($dom);              &Apache::loncommon::devalidate_domconfig_cache($dom);
             if (ref($lastactref) eq 'HASH') {  
                 $lastactref->{'domainconfig'} = 1;  
             }  
             $resulttext = &display_colorchgs($dom,\%changes,$roles,              $resulttext = &display_colorchgs($dom,\%changes,$roles,
                                              $rolehash{'rolecolors'});                                               $rolehash{'rolecolors'});
         } else {          } else {
Line 7293  sub modify_colors { Line 5109  sub modify_colors {
     my @images;      my @images;
     my $servadm = $r->dir_config('lonAdmEMail');      my $servadm = $r->dir_config('lonAdmEMail');
     my $errors;      my $errors;
     my %defaults;  
     foreach my $role (@{$roles}) {      foreach my $role (@{$roles}) {
         if ($role eq 'login') {          if ($role eq 'login') {
             %choices = &login_choices();              %choices = &login_choices();
             @logintext = ('textcol','bgcol');              @logintext = ('textcol','bgcol');
         } else {          } else {
             %choices = &color_font_choices();              %choices = &color_font_choices();
               $confhash->{$role}{'fontmenu'} = $env{'form.'.$role.'_fontmenu'};
         }          }
         if ($role eq 'login') {          if ($role eq 'login') {
             @images = ('img','logo','domlogo','login');              @images = ('img','logo','domlogo','login');
             @bgs = ('pgbg','mainbg','sidebg');              @bgs = ('pgbg','mainbg','sidebg');
         } else {          } else {
             @images = ('img');              @images = ('img');
             @bgs = ('pgbg','tabbg','sidebg');              @bgs = ('pgbg','tabbg','sidebg'); 
         }          }
         my %defaults = &role_defaults($role,\@bgs,\@links,\@images,\@logintext);          $confhash->{$role}{'font'} = $env{'form.'.$role.'_font'};
         unless ($env{'form.'.$role.'_font'} eq $defaults{'font'}) {          foreach my $item (@bgs,@links,@logintext) {
             $confhash->{$role}{'font'} = $env{'form.'.$role.'_font'};              $confhash->{$role}{$item} = $env{'form.'.$role.'_'.$item};
         }  
         if ($role eq 'login') {  
             foreach my $item (@logintext) {  
                 $env{'form.'.$role.'_'.$item} = lc($env{'form.'.$role.'_'.$item});  
                 if ($env{'form.'.$role.'_'.$item} =~ /^\w+/) {  
                     $env{'form.'.$role.'_'.$item} = '#'.$env{'form.'.$role.'_'.$item};  
                 }  
                 unless ($env{'form.'.$role.'_'.$item} eq lc($defaults{'logintext'}{$item})) {  
                     $confhash->{$role}{$item} = $env{'form.'.$role.'_'.$item};  
                 }  
             }  
         } else {  
             $env{'form.'.$role.'_fontmenu'} = lc($env{'form.'.$role.'_fontmenu'});  
             if ($env{'form.'.$role.'_fontmenu'} =~ /^\w+/) {  
                 $env{'form.'.$role.'_fontmenu'} = '#'.$env{'form.'.$role.'_fontmenu'};  
             }  
             unless($env{'form.'.$role.'_fontmenu'} eq lc($defaults{'fontmenu'})) {  
                 $confhash->{$role}{'fontmenu'} = $env{'form.'.$role.'_fontmenu'};  
             }  
         }  
         foreach my $item (@bgs) {  
             $env{'form.'.$role.'_'.$item} = lc($env{'form.'.$role.'_'.$item});  
             if ($env{'form.'.$role.'_'.$item} =~ /^\w+/) {  
                 $env{'form.'.$role.'_'.$item} = '#'.$env{'form.'.$role.'_'.$item};  
             }  
             unless ($env{'form.'.$role.'_'.$item} eq lc($defaults{'bgs'}{$item})) {  
                 $confhash->{$role}{$item} = $env{'form.'.$role.'_'.$item};  
             }  
         }  
         foreach my $item (@links) {  
             $env{'form.'.$role.'_'.$item} = lc($env{'form.'.$role.'_'.$item});  
             if ($env{'form.'.$role.'_'.$item} =~ /^\w+/) {  
                 $env{'form.'.$role.'_'.$item} = '#'.$env{'form.'.$role.'_'.$item};  
             }  
             unless ($env{'form.'.$role.'_'.$item} eq lc($defaults{'links'}{$item})) {  
                 $confhash->{$role}{$item} = $env{'form.'.$role.'_'.$item};  
             }  
         }          }
         my ($configuserok,$author_ok,$switchserver) =           my ($configuserok,$author_ok,$switchserver) = 
             &config_check($dom,$confname,$servadm);              &config_check($dom,$confname,$servadm);
Line 7695  sub publishlogo { Line 5474  sub publishlogo {
 # See if there is anything left  # See if there is anything left
     unless ($fname) { return ('error: no uploaded file'); }      unless ($fname) { return ('error: no uploaded file'); }
     $fname="$subdir/$fname";      $fname="$subdir/$fname";
     my $docroot=$r->dir_config('lonDocRoot');      my $docroot=$r->dir_config('lonDocRoot'); 
     my $filepath="$docroot/priv";      my $filepath="$docroot/priv";
     my $relpath = "$dom/$confname";      my $relpath = "$dom/$confname";
     my ($fnamepath,$file,$fetchthumb);      my ($fnamepath,$file,$fetchthumb);
Line 7715  sub publishlogo { Line 5494  sub publishlogo {
     if ($file=~/\.(\w+)$/ &&      if ($file=~/\.(\w+)$/ &&
         (&Apache::loncommon::fileembstyle($1) eq 'hdn')) {          (&Apache::loncommon::fileembstyle($1) eq 'hdn')) {
         $output =           $output = 
             &mt('Invalid file extension ([_1]) - reserved for internal use.',$1);               &mt('Invalid file extension ([_1]) - reserved for LONCAPA use.',$1); 
     } elsif ($file=~/\.(\w+)$/ &&      } elsif ($file=~/\.(\w+)$/ &&
         !defined(&Apache::loncommon::fileembstyle($1))) {          !defined(&Apache::loncommon::fileembstyle($1))) {
         $output = &mt('Unrecognized file extension ([_1]) - rename the file with a proper extension and re-upload.',$1);          $output = &mt('Unrecognized file extension ([_1]) - rename the file with a proper extension and re-upload.',$1);
Line 7726  sub publishlogo { Line 5505  sub publishlogo {
     } else {      } else {
         my $source = $filepath.'/'.$file;          my $source = $filepath.'/'.$file;
         my $logfile;          my $logfile;
         if (!open($logfile,">>",$source.'.log')) {          if (!open($logfile,">>$source".'.log')) {
             return (&mt('No write permission to Authoring Space'));              return (&mt('No write permission to Authoring Space'));
         }          }
         print $logfile          print $logfile
 "\n================= Publish ".localtime()." ================\n".  "\n================= Publish ".localtime()." ================\n".
 $env{'user.name'}.':'.$env{'user.domain'}."\n";  $env{'user.name'}.':'.$env{'user.domain'}."\n";
 # Save the file  # Save the file
         if (!open(FH,">",$source)) {          if (!open(FH,'>'.$source)) {
             &Apache::lonnet::logthis('Failed to create '.$source);              &Apache::lonnet::logthis('Failed to create '.$source);
             return (&mt('Failed to create file'));              return (&mt('Failed to create file'));
         }          }
Line 7794  $env{'user.name'}.':'.$env{'user.domain' Line 5573  $env{'user.name'}.':'.$env{'user.domain'
                 if ($fullwidth ne '' && $fullheight ne '') {                   if ($fullwidth ne '' && $fullheight ne '') { 
                     if ($fullwidth > $thumbwidth && $fullheight > $thumbheight) {                      if ($fullwidth > $thumbwidth && $fullheight > $thumbheight) {
                         my $thumbsize = $thumbwidth.'x'.$thumbheight;                          my $thumbsize = $thumbwidth.'x'.$thumbheight;
                         my @args = ('convert','-sample',$thumbsize,$inputfile,$outfile);                          system("convert -sample $thumbsize $inputfile $outfile");
                         system({$args[0]} @args);  
                         chmod(0660, $filepath.'/tn-'.$file);                          chmod(0660, $filepath.'/tn-'.$file);
                         if (-e $outfile) {                          if (-e $outfile) {
                             my $copyfile=$targetdir.'/tn-'.$file;                              my $copyfile=$targetdir.'/tn-'.$file;
Line 7874  sub write_metadata { Line 5652  sub write_metadata {
     {      {
         print $logfile "\nWrite metadata file for ".$targetdir.'/'.$file;          print $logfile "\nWrite metadata file for ".$targetdir.'/'.$file;
         my $mfh;          my $mfh;
         if (open($mfh,">",$targetdir.'/'.$file.'.meta')) {          if (open($mfh,'>'.$targetdir.'/'.$file.'.meta')) {
             foreach (sort(keys(%metadatafields))) {              foreach (sort(keys(%metadatafields))) {
                 unless ($_=~/\./) {                  unless ($_=~/\./) {
                     my $unikey=$_;                      my $unikey=$_;
Line 7908  sub notifysubscribed { Line 5686  sub notifysubscribed {
         next unless (ref($targetsource) eq 'ARRAY');          next unless (ref($targetsource) eq 'ARRAY');
         my ($target,$source)=@{$targetsource};          my ($target,$source)=@{$targetsource};
         if ($source ne '') {          if ($source ne '') {
             if (open(my $logfh,">>",$source.'.log')) {              if (open(my $logfh,'>>'.$source.'.log')) {
                 print $logfh "\nCleanup phase: Notifications\n";                  print $logfh "\nCleanup phase: Notifications\n";
                 my @subscribed=&subscribed_hosts($target);                  my @subscribed=&subscribed_hosts($target);
                 foreach my $subhost (@subscribed) {                  foreach my $subhost (@subscribed) {
Line 7934  sub notifysubscribed { Line 5712  sub notifysubscribed {
 sub subscribed_hosts {  sub subscribed_hosts {
     my ($target) = @_;      my ($target) = @_;
     my @subscribed;      my @subscribed;
     if (open(my $fh,"<","$target.subscription")) {      if (open(my $fh,"<$target.subscription")) {
         while (my $subline=<$fh>) {          while (my $subline=<$fh>) {
             if ($subline =~ /^($match_lonid):/) {              if ($subline =~ /^($match_lonid):/) {
                 my $host = $1;                  my $host = $1;
Line 7965  sub check_switchserver { Line 5743  sub check_switchserver {
 }  }
   
 sub modify_quotas {  sub modify_quotas {
     my ($r,$dom,$action,$lastactref,%domconfig) = @_;      my ($dom,$action,%domconfig) = @_;
     my ($context,@usertools,@options,%validations,%titles,%confhash,%toolshash,      my ($context,@usertools,@options,%validations,%titles,%confhash,%toolshash,
         %limithash,$toolregexp,%conditions,$resulttext,%changes,$confname,$configuserok,          %limithash,$toolregexp,%conditions,$resulttext,%changes);
         $author_ok,$switchserver,$errors,$validationitemsref,$validationnamesref,  
         $validationfieldsref);  
     if ($action eq 'quotas') {      if ($action eq 'quotas') {
         $context = 'tools';           $context = 'tools'; 
     } else {      } else {
         $context = $action;          $context = $action;
     }      }
     if ($context eq 'requestcourses') {      if ($context eq 'requestcourses') {
         @usertools = ('official','unofficial','community','textbook');          @usertools = ('official','unofficial','community');
         @options =('norequest','approval','validate','autolimit');          @options =('norequest','approval','validate','autolimit');
         %validations = &Apache::lonnet::auto_courserequest_checks($dom);          %validations = &Apache::lonnet::auto_courserequest_checks($dom);
         %titles = &courserequest_titles();          %titles = &courserequest_titles();
         $toolregexp = join('|',@usertools);          $toolregexp = join('|',@usertools);
         %conditions = &courserequest_conditions();          %conditions = &courserequest_conditions();
         $confname = $dom.'-domainconfig';  
         my $servadm = $r->dir_config('lonAdmEMail');  
         ($configuserok,$author_ok,$switchserver) = &config_check($dom,$confname,$servadm);  
         ($validationitemsref,$validationnamesref,$validationfieldsref) =   
             &Apache::loncoursequeueadmin::requestcourses_validation_types();  
     } elsif ($context eq 'requestauthor') {      } elsif ($context eq 'requestauthor') {
         @usertools = ('author');          @usertools = ('author');
         %titles = &authorrequest_titles();          %titles = &authorrequest_titles();
Line 7994  sub modify_quotas { Line 5765  sub modify_quotas {
         @usertools = ('aboutme','blog','webdav','portfolio');          @usertools = ('aboutme','blog','webdav','portfolio');
         %titles = &tool_titles();          %titles = &tool_titles();
     }      }
     my %domdefaults = &Apache::lonnet::get_domain_defaults($dom,1);      my %domdefaults = &Apache::lonnet::get_domain_defaults($dom);
     my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom);      my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom);
     foreach my $key (keys(%env)) {      foreach my $key (keys(%env)) {
         if ($context eq 'requestcourses') {          if ($context eq 'requestcourses') {
Line 8022  sub modify_quotas { Line 5793  sub modify_quotas {
         }          }
     }      }
     if (($context eq 'requestcourses') || ($context eq 'requestauthor')) {      if (($context eq 'requestcourses') || ($context eq 'requestauthor')) {
         my @approvalnotify = &Apache::loncommon::get_env_multiple('form.'.$context.'notifyapproval');          my @approvalnotify = &Apache::loncommon::get_env_multiple('form.reqapprovalnotify');
         @approvalnotify = sort(@approvalnotify);          @approvalnotify = sort(@approvalnotify);
         $confhash{'notify'}{'approval'} = join(',',@approvalnotify);          $confhash{'notify'}{'approval'} = join(',',@approvalnotify);
         my @crstypes = ('official','unofficial','community','textbook');  
         my @hasuniquecode = &Apache::loncommon::get_env_multiple('form.uniquecode');  
         foreach my $type (@hasuniquecode) {  
             if (grep(/^\Q$type\E$/,@crstypes)) {  
                 $confhash{'uniquecode'}{$type} = 1;  
             }  
         }  
         my (%newbook,%allpos);  
         if ($context eq 'requestcourses') {  
             foreach my $type ('textbooks','templates') {  
                 @{$allpos{$type}} = ();   
                 my $invalid;  
                 if ($type eq 'textbooks') {  
                     $invalid = &mt('Invalid LON-CAPA course for textbook');  
                 } else {  
                     $invalid = &mt('Invalid LON-CAPA course for template');  
                 }  
                 if ($env{'form.'.$type.'_addbook'}) {  
                     if (($env{'form.'.$type.'_addbook_cnum'} =~ /^$match_courseid$/) &&  
                         ($env{'form.'.$type.'_addbook_cdom'} =~ /^$match_domain$/)) {  
                         if (&Apache::lonnet::homeserver($env{'form.'.$type.'_addbook_cnum'},  
                                                         $env{'form.'.$type.'_addbook_cdom'}) eq 'no_host') {  
                             $errors .= '<li><span class="LC_error">'.$invalid.'</span></li>';  
                         } else {  
                             $newbook{$type} = $env{'form.'.$type.'_addbook_cdom'}.'_'.$env{'form.'.$type.'_addbook_cnum'};  
                             my $position = $env{'form.'.$type.'_addbook_pos'};  
                             $position =~ s/\D+//g;  
                             if ($position ne '') {  
                                 $allpos{$type}[$position] = $newbook{$type};  
                             }  
                         }  
                     } else {  
                         $errors .= '<li><span class="LC_error">'.$invalid.'</span></li>';  
                     }  
                 }  
             }   
         }  
         if (ref($domconfig{$action}) eq 'HASH') {          if (ref($domconfig{$action}) eq 'HASH') {
             if (ref($domconfig{$action}{'notify'}) eq 'HASH') {              if (ref($domconfig{$action}{'notify'}) eq 'HASH') {
                 if ($domconfig{$action}{'notify'}{'approval'} ne $confhash{'notify'}{'approval'}) {                  if ($domconfig{$action}{'notify'}{'approval'} ne $confhash{'notify'}{'approval'}) {
Line 8072  sub modify_quotas { Line 5806  sub modify_quotas {
                     $changes{'notify'}{'approval'} = 1;                      $changes{'notify'}{'approval'} = 1;
                 }                  }
             }              }
             if (ref($domconfig{$action}{'uniquecode'}) eq 'HASH') {  
                 if (ref($confhash{'uniquecode'}) eq 'HASH') {  
                     foreach my $crstype (keys(%{$domconfig{$action}{'uniquecode'}})) {  
                         unless ($confhash{'uniquecode'}{$crstype}) {  
                             $changes{'uniquecode'} = 1;  
                         }  
                     }  
                     unless ($changes{'uniquecode'}) {  
                         foreach my $crstype (keys(%{$confhash{'uniquecode'}})) {  
                             unless ($domconfig{$action}{'uniquecode'}{$crstype}) {  
                                 $changes{'uniquecode'} = 1;  
                             }  
                         }  
                     }  
                } else {  
                    $changes{'uniquecode'} = 1;  
                }  
             } elsif (ref($confhash{'uniquecode'}) eq 'HASH') {  
                 $changes{'uniquecode'} = 1;  
             }  
             if ($context eq 'requestcourses') {  
                 foreach my $type ('textbooks','templates') {  
                     if (ref($domconfig{$action}{$type}) eq 'HASH') {  
                         my %deletions;  
                         my @todelete = &Apache::loncommon::get_env_multiple('form.'.$type.'_del');  
                         if (@todelete) {  
                             map { $deletions{$_} = 1; } @todelete;  
                         }  
                         my %imgdeletions;  
                         my @todeleteimages = &Apache::loncommon::get_env_multiple('form.'.$type.'_image_del');  
                         if (@todeleteimages) {  
                             map { $imgdeletions{$_} = 1; } @todeleteimages;  
                         }  
                         my $maxnum = $env{'form.'.$type.'_maxnum'};  
                         for (my $i=0; $i<=$maxnum; $i++) {  
                             my $itemid = $env{'form.'.$type.'_id_'.$i};  
                             my ($key) = ($itemid =~ /^\Q$type\E_(\w+)$/);   
                             if (ref($domconfig{$action}{$type}{$key}) eq 'HASH') {  
                                 if ($deletions{$key}) {  
                                     if ($domconfig{$action}{$type}{$key}{'image'}) {  
                                         #FIXME need to obsolete item in RES space  
                                     }  
                                     next;  
                                 } else {  
                                     my $newpos = $env{'form.'.$itemid};  
                                     $newpos =~ s/\D+//g;  
                                     foreach my $item ('subject','title','publisher','author') {  
                                         next if ((($item eq 'author') || ($item eq 'publisher')) &&  
                                                  ($type eq 'templates'));  
                                         $confhash{$type}{$key}{$item} = $env{'form.'.$type.'_'.$item.'_'.$i};  
                                         if ($domconfig{$action}{$type}{$key}{$item} ne $confhash{$type}{$key}{$item}) {  
                                             $changes{$type}{$key} = 1;  
                                         }  
                                     }  
                                     $allpos{$type}[$newpos] = $key;  
                                 }  
                                 if ($imgdeletions{$key}) {  
                                     $changes{$type}{$key} = 1;  
                                     #FIXME need to obsolete item in RES space  
                                 } elsif ($env{'form.'.$type.'_image_'.$i.'.filename'}) {  
                                     my ($cdom,$cnum) = split(/_/,$key);  
                                     if (&Apache::lonnet::homeserver($cnum,$cdom) eq 'no_host') {  
                                         $errors .= '<li><span class="LC_error">'.&mt('Image not saved: could not find textbook course').'</li>';  
                                     } else {  
                                         my ($imgurl,$error) = &process_textbook_image($r,$dom,$confname,$type.'_image_'.$i,  
                                                                                       $cdom,$cnum,$type,$configuserok,  
                                                                                       $switchserver,$author_ok);  
                                         if ($imgurl) {  
                                             $confhash{$type}{$key}{'image'} = $imgurl;  
                                             $changes{$type}{$key} = 1;   
                                         }  
                                         if ($error) {  
                                             &Apache::lonnet::logthis($error);  
                                             $errors .= '<li><span class="LC_error">'.$error.'</span></li>';  
                                         }  
                                     }   
                                 } elsif ($domconfig{$action}{$type}{$key}{'image'}) {  
                                     $confhash{$type}{$key}{'image'} =   
                                         $domconfig{$action}{$type}{$key}{'image'};  
                                 }  
                             }  
                         }  
                     }  
                 }  
             }  
         } else {          } else {
             if ($confhash{'notify'}{'approval'}) {              if ($confhash{'notify'}{'approval'}) {
                 $changes{'notify'}{'approval'} = 1;                  $changes{'notify'}{'approval'} = 1;
             }              }
             if (ref($confhash{'uniquecode'} eq 'HASH')) {  
                 $changes{'uniquecode'} = 1;  
             }  
         }  
         if ($context eq 'requestcourses') {  
             foreach my $type ('textbooks','templates') {  
                 if ($newbook{$type}) {  
                     $changes{$type}{$newbook{$type}} = 1;  
                     foreach my $item ('subject','title','publisher','author') {  
                         next if ((($item eq 'author') || ($item eq 'publisher')) &&  
                                  ($type eq 'template'));  
                         $env{'form.'.$type.'_addbook_'.$item} =~ s/(`)/'/g;  
                         if ($env{'form.'.$type.'_addbook_'.$item}) {  
                             $confhash{$type}{$newbook{$type}}{$item} = $env{'form.'.$type.'_addbook_'.$item};  
                         }  
                     }  
                     if ($type eq 'textbooks') {  
                         if ($env{'form.'.$type.'_addbook_image.filename'} ne '') {  
                             my ($cdom,$cnum) = split(/_/,$newbook{$type});  
                             if (&Apache::lonnet::homeserver($cnum,$cdom) eq 'no_host') {  
                                 $errors .= '<li><span class="LC_error">'.&mt('Image not saved: could not find textbook course').'</li>';  
                             } else {  
                                 my ($imageurl,$error) =  
                                     &process_textbook_image($r,$dom,$confname,$type.'_addbook_image',$cdom,$cnum,$type,  
                                                             $configuserok,$switchserver,$author_ok);  
                                 if ($imageurl) {  
                                     $confhash{$type}{$newbook{$type}}{'image'} = $imageurl;  
                                 }  
                                 if ($error) {  
                                     &Apache::lonnet::logthis($error);  
                                     $errors .= '<li><span class="LC_error">'.$error.'</span></li>';  
                                 }  
                             }  
                         }  
                     }  
                 }  
                 if (@{$allpos{$type}} > 0) {  
                     my $idx = 0;  
                     foreach my $item (@{$allpos{$type}}) {  
                         if ($item ne '') {  
                             $confhash{$type}{$item}{'order'} = $idx;  
                             if (ref($domconfig{$action}) eq 'HASH') {  
                                 if (ref($domconfig{$action}{$type}) eq 'HASH') {  
                                     if (ref($domconfig{$action}{$type}{$item}) eq 'HASH') {  
                                         if ($domconfig{$action}{$type}{$item}{'order'} ne $idx) {  
                                             $changes{$type}{$item} = 1;  
                                         }  
                                     }  
                                 }  
                             }  
                             $idx ++;  
                         }  
                     }  
                 }  
             }  
             if (ref($validationitemsref) eq 'ARRAY') {  
                 foreach my $item (@{$validationitemsref}) {  
                     if ($item eq 'fields') {  
                         my @changed;  
                         @{$confhash{'validation'}{$item}} = &Apache::loncommon::get_env_multiple('form.requestcourses_validation_'.$item);  
                         if (@{$confhash{'validation'}{$item}} > 0) {  
                             @{$confhash{'validation'}{$item}} = sort(@{$confhash{'validation'}{$item}});  
                         }  
                         if (ref($domconfig{'requestcourses'}) eq 'HASH') {  
                             if (ref($domconfig{'requestcourses'}{'validation'}) eq 'HASH') {  
                                 if (ref($domconfig{'requestcourses'}{'validation'}{$item}) eq 'ARRAY') {  
                                     @changed = &Apache::loncommon::compare_arrays($confhash{'validation'}{$item},  
                                                                                   $domconfig{'requestcourses'}{'validation'}{$item});  
                                 } else {  
                                     @changed = @{$confhash{'validation'}{$item}};  
                                 }  
                             } else {  
                                 @changed = @{$confhash{'validation'}{$item}};  
                             }  
                         } else {  
                             @changed = @{$confhash{'validation'}{$item}};  
                         }  
                         if (@changed) {  
                             if ($confhash{'validation'}{$item}) {  
                                 $changes{'validation'}{$item} = join(', ',@{$confhash{'validation'}{$item}});  
                             } else {  
                                 $changes{'validation'}{$item} = &mt('None');  
                             }  
                         }  
                     } else {  
                         $confhash{'validation'}{$item} = $env{'form.requestcourses_validation_'.$item};  
                         if ($item eq 'markup') {  
                             if ($env{'form.requestcourses_validation_'.$item}) {  
                                 $env{'form.requestcourses_validation_'.$item} =~ s/[\n\r\f]+/\s/gs;  
                             }  
                         }  
                         if (ref($domconfig{'requestcourses'}) eq 'HASH') {  
                             if (ref($domconfig{'requestcourses'}{'validation'}) eq 'HASH') {  
                                 if ($domconfig{'requestcourses'}{'validation'}{$item} ne $confhash{'validation'}{$item}) {  
                                     $changes{'validation'}{$item} = $confhash{'validation'}{$item};  
                                 }  
                             } else {  
                                 if ($confhash{'validation'}{$item} ne '') {  
                                     $changes{'validation'}{$item} = $confhash{'validation'}{$item};  
                                 }  
                             }  
                         } else {  
                             if ($confhash{'validation'}{$item} ne '') {  
                                 $changes{'validation'}{$item} = $confhash{'validation'}{$item};  
                             }  
                         }  
                     }  
                 }  
             }  
             if ($env{'form.validationdc'}) {  
                 my $newval = $env{'form.validationdc'};  
                 my %domcoords = &Apache::lonnet::get_active_domroles($dom,['dc']);  
                 if (exists($domcoords{$newval})) {  
                     $confhash{'validation'}{'dc'} = $newval;  
                 }  
             }  
             if (ref($confhash{'validation'}) eq 'HASH') {  
                 if (ref($domconfig{'requestcourses'}) eq 'HASH') {  
                     if (ref($domconfig{'requestcourses'}{'validation'}) eq 'HASH') {  
                         if ($domconfig{'requestcourses'}{'validation'}{'dc'}) {  
                             unless ($confhash{'validation'}{'dc'} eq $domconfig{'requestcourses'}{'validation'}{'dc'}) {  
                                 if ($confhash{'validation'}{'dc'} eq '') {  
                                     $changes{'validation'}{'dc'} = &mt('None');  
                                 } else {  
                                     $changes{'validation'}{'dc'} = $confhash{'validation'}{'dc'};  
                                 }  
                             }  
                         } elsif ($confhash{'validation'}{'dc'} ne '') {  
                             $changes{'validation'}{'dc'} = $confhash{'validation'}{'dc'};  
                         }  
                     } elsif ($confhash{'validation'}{'dc'} ne '') {  
                         $changes{'validation'}{'dc'} = $confhash{'validation'}{'dc'};  
                     }  
                 } elsif ($confhash{'validation'}{'dc'} ne '') {  
                     $changes{'validation'}{'dc'} = $confhash{'validation'}{'dc'};  
                 }  
             } else {  
                 if (ref($domconfig{'requestcourses'}) eq 'HASH') {  
                     if (ref($domconfig{'requestcourses'}{'validation'}) eq 'HASH') {  
                         if ($domconfig{'requestcourses'}{'validation'}{'dc'}) {  
                             $changes{'validation'}{'dc'} = &mt('None');  
                         }  
                     }  
                 }  
             }  
         }          }
     } else {      } else {
         $confhash{'defaultquota'}{'default'} = $env{'form.defaultquota'};          $confhash{'defaultquota'}{'default'} = $env{'form.defaultquota'};
Line 8447  sub modify_quotas { Line 5951  sub modify_quotas {
         $domdefaults{'requestauthor'} = \%confhash;          $domdefaults{'requestauthor'} = \%confhash;
     } else {      } else {
         foreach my $key (keys(%confhash)) {          foreach my $key (keys(%confhash)) {
             unless (($context eq 'requestcourses') && (($key eq 'textbooks') || ($key eq 'templates'))) {              $domdefaults{$key} = $confhash{$key};
                 $domdefaults{$key} = $confhash{$key};  
             }  
         }          }
     }      }
   
Line 8462  sub modify_quotas { Line 5964  sub modify_quotas {
         if (keys(%changes) > 0) {          if (keys(%changes) > 0) {
             my $cachetime = 24*60*60;              my $cachetime = 24*60*60;
             &Apache::lonnet::do_cache_new('domdefaults',$dom,\%domdefaults,$cachetime);              &Apache::lonnet::do_cache_new('domdefaults',$dom,\%domdefaults,$cachetime);
             if (ref($lastactref) eq 'HASH') {  
                 $lastactref->{'domdefaults'} = 1;  
             }  
             $resulttext = &mt('Changes made:').'<ul>';              $resulttext = &mt('Changes made:').'<ul>';
             unless (($context eq 'requestcourses') ||              unless (($context eq 'requestcourses') || 
                     ($context eq 'requestauthor')) {                      ($context eq 'requestauthor')) {
                 if (ref($changes{'defaultquota'}) eq 'HASH') {                  if (ref($changes{'defaultquota'}) eq 'HASH') {
                     $resulttext .= '<li>'.&mt('Portfolio default quotas').'<ul>';                      $resulttext .= '<li>'.&mt('Portfolio default quotas').'<ul>';
Line 8476  sub modify_quotas { Line 5976  sub modify_quotas {
                             if ($type eq 'default') {                              if ($type eq 'default') {
                                 $typetitle = $othertitle;                                  $typetitle = $othertitle;
                             }                              }
                             $resulttext .= '<li>'.&mt('[_1] set to [_2] MB',$typetitle,$confhash{'defaultquota'}{$type}).'</li>';                              $resulttext .= '<li>'.&mt('[_1] set to [_2] Mb',$typetitle,$confhash{'defaultquota'}{$type}).'</li>';
                         }                          }
                     }                      }
                     $resulttext .= '</ul></li>';                      $resulttext .= '</ul></li>';
                 }                  }
                 if (ref($changes{'authorquota'}) eq 'HASH') {                  if (ref($changes{'authorquota'}) eq 'HASH') {
                     $resulttext .= '<li>'.&mt('Authoring Space default quotas').'<ul>';                      $resulttext .= '<li>'.&mt('Authoring space default quotas').'<ul>';
                     foreach my $type (@{$types},'default') {                      foreach my $type (@{$types},'default') {
                         if (defined($changes{'authorquota'}{$type})) {                          if (defined($changes{'authorquota'}{$type})) {
                             my $typetitle = $usertypes->{$type};                              my $typetitle = $usertypes->{$type};
                             if ($type eq 'default') {                              if ($type eq 'default') {
                                 $typetitle = $othertitle;                                  $typetitle = $othertitle;
                             }                              }
                             $resulttext .= '<li>'.&mt('[_1] set to [_2] MB',$typetitle,$confhash{'authorquota'}{$type}).'</li>';                              $resulttext .= '<li>'.&mt('[_1] set to [_2] Mb',$typetitle,$confhash{'authorquota'}{$type}).'</li>';
                         }                          }
                     }                      }
                     $resulttext .= '</ul></li>';                      $resulttext .= '</ul></li>';
Line 8500  sub modify_quotas { Line 6000  sub modify_quotas {
                 my (%haschgs,%inconf);                  my (%haschgs,%inconf);
                 if ($context eq 'requestauthor') {                  if ($context eq 'requestauthor') {
                     %haschgs = %changes;                      %haschgs = %changes;
                     %inconf = %confhash;                      %inconf = %confhash; 
                 } else {                  } else {
                     if (ref($changes{$item}) eq 'HASH') {                      if (ref($changes{$item}) eq 'HASH') {
                         %haschgs = %{$changes{$item}};                          %haschgs = %{$changes{$item}};
Line 8514  sub modify_quotas { Line 6014  sub modify_quotas {
                         &Apache::lonnet::usertools_access($env{'user.name'},                          &Apache::lonnet::usertools_access($env{'user.name'},
                                                           $env{'user.domain'},                                                            $env{'user.domain'},
                                                           $item,'reload',$context);                                                            $item,'reload',$context);
                     if (($context eq 'requestcourses') ||                      if (($context eq 'requestcourses') || 
                         ($context eq 'requestauthor')) {                          ($context eq 'requestauthor')) {
                         if ($env{'environment.canrequest.'.$item} ne $newacc) {                          if ($env{'environment.canrequest.'.$item} ne $newacc) {
                             $newenv{'environment.canrequest.'.$item} = $newacc;                              $newenv{'environment.canrequest.'.$item} = $newacc;
Line 8586  sub modify_quotas { Line 6086  sub modify_quotas {
                     }                      }
                 }                  }
             }              }
             if ($action eq 'requestcourses') {  
                 my @offon = ('off','on');  
                 if ($changes{'uniquecode'}) {  
                     if (ref($confhash{'uniquecode'}) eq 'HASH') {  
                         my $codestr = join(' ',map{ &mt($_); } sort(keys(%{$confhash{'uniquecode'}})));  
                         $resulttext .= '<li>'.  
                                        &mt('Generation of six character code as course identifier for distribution to students set to on for: [_1].','<b>'.$codestr.'</b>').  
                                        '</li>';  
                     } else {  
                         $resulttext .= '<li>'.&mt('Generation of six character code as course identifier for distribution to students set to off.').  
                                        '</li>';  
                     }  
                 }  
                 foreach my $type ('textbooks','templates') {  
                     if (ref($changes{$type}) eq 'HASH') {  
                         $resulttext .= '<li>'.&mt("Available $type updated").'<ul>';  
                         foreach my $key (sort(keys(%{$changes{$type}}))) {  
                             my %coursehash = &Apache::lonnet::coursedescription($key);  
                             my $coursetitle = $coursehash{'description'};  
                             my $position = $confhash{$type}{$key}{'order'} + 1;  
                             $resulttext .= '<li>';  
                             foreach my $item ('subject','title','publisher','author') {  
                                 next if ((($item eq 'author') || ($item eq 'publisher')) &&  
                                          ($type eq 'templates'));  
                                 my $name = $item.':';  
                                 $name =~ s/^(\w)/\U$1/;  
                                 $resulttext .= &mt($name).' '.$confhash{$type}{$key}{$item}.'<br />';  
                             }  
                             $resulttext .= ' '.&mt('Order: [_1]',$position).'<br />';  
                             if ($type eq 'textbooks') {  
                                 if ($confhash{$type}{$key}{'image'}) {  
                                     $resulttext .= ' '.&mt('Image: [_1]',  
                                                    '<img src="'.$confhash{$type}{$key}{'image'}.'"'.  
                                                    ' alt="Textbook cover" />').'<br />';  
                                 }  
                             }  
                             $resulttext .= ' '.&mt('LON-CAPA Course: [_1]',$coursetitle).'</li>';  
                         }  
                         $resulttext .= '</ul></li>';  
                     }  
                 }  
                 if (ref($changes{'validation'}) eq 'HASH') {  
                     if ((ref($validationitemsref) eq 'ARRAY') && (ref($validationnamesref) eq 'HASH')) {  
                         $resulttext .= '<li>'.&mt('Validation of courses/communities updated').'<ul>';  
                         foreach my $item (@{$validationitemsref}) {  
                             if (exists($changes{'validation'}{$item})) {  
                                 if ($item eq 'markup') {  
                                     $resulttext .= '<li>'.&mt('[_1] set to: [_2]',$validationnamesref->{$item},  
                                                               '<br /><pre>'.$changes{'validation'}{$item}.'</pre>').'</li>';  
                                 } else {  
                                     $resulttext .= '<li>'.&mt('[_1] set to: [_2]',$validationnamesref->{$item},  
                                                               '<b>'.$changes{'validation'}{$item}.'</b>').'</li>';  
                                 }  
                             }  
                         }  
                         if (exists($changes{'validation'}{'dc'})) {  
                             $resulttext .= '<li>'.&mt('Validated course requests identified as processed by: [_1]',  
                                                      '<b>'.$changes{'validation'}{'dc'}.'</b>').'</li>';  
                         }  
                     }  
                 }  
             }  
             $resulttext .= '</ul>';              $resulttext .= '</ul>';
             if (keys(%newenv)) {              if (keys(%newenv)) {
                 &Apache::lonnet::appenv(\%newenv);                  &Apache::lonnet::appenv(\%newenv);
Line 8665  sub modify_quotas { Line 6103  sub modify_quotas {
         $resulttext = '<span class="LC_error">'.          $resulttext = '<span class="LC_error">'.
     &mt('An error occurred: [_1]',$putresult).'</span>';      &mt('An error occurred: [_1]',$putresult).'</span>';
     }      }
     if ($errors) {  
         $resulttext .= '<p>'.&mt('The following errors occurred when modifying Textbook settings.').  
                        '<ul>'.$errors.'</ul></p>';  
     }  
     return $resulttext;      return $resulttext;
 }  }
   
 sub process_textbook_image {  
     my ($r,$dom,$confname,$caller,$cdom,$cnum,$type,$configuserok,$switchserver,$author_ok) = @_;  
     my $filename = $env{'form.'.$caller.'.filename'};  
     my ($error,$url);  
     my ($width,$height) = (50,50);  
     if ($configuserok eq 'ok') {  
         if ($switchserver) {  
             $error = &mt('Upload of textbook image is not permitted to this server: [_1]',  
                          $switchserver);  
         } elsif ($author_ok eq 'ok') {  
             my ($result,$imageurl) =  
                 &publishlogo($r,'upload',$caller,$dom,$confname,  
                              "$type/$cdom/$cnum/cover",$width,$height);  
             if ($result eq 'ok') {  
                 $url = $imageurl;  
             } else {  
                 $error = &mt("Upload of [_1] failed because an error occurred publishing the file in RES space. Error was: [_2].",$filename,$result);  
             }  
         } else {  
             $error = &mt("Upload of [_1] failed because an author role could not be assigned to a Domain Configuration user ([_2]) in domain: [_3].  Error was: [_4].",$filename,$confname,$dom,$author_ok);  
         }  
     } else {  
         $error = &mt("Upload of [_1] failed because a Domain Configuration user ([_2]) could not be created in domain: [_3].  Error was: [_4].",$filename,$confname,$dom,$configuserok);  
     }  
     return ($url,$error);  
 }  
   
 sub modify_autoenroll {  sub modify_autoenroll {
     my ($dom,$lastactref,%domconfig) = @_;      my ($dom,%domconfig) = @_;
     my ($resulttext,%changes);      my ($resulttext,%changes);
     my %currautoenroll;      my %currautoenroll;
     if (ref($domconfig{'autoenroll'}) eq 'HASH') {      if (ref($domconfig{'autoenroll'}) eq 'HASH') {
Line 8711  sub modify_autoenroll { Line 6118  sub modify_autoenroll {
     my $autorun = &Apache::lonnet::auto_run(undef,$dom),      my $autorun = &Apache::lonnet::auto_run(undef,$dom),
     my %title = ( run => 'Auto-enrollment active',      my %title = ( run => 'Auto-enrollment active',
                   sender => 'Sender for notification messages',                    sender => 'Sender for notification messages',
                   coowners => 'Automatic assignment of co-ownership to instructors of record (institutional data)',                    coowners => 'Automatic assignment of co-ownership to instructors of record (institutional data)');
                   failsafe => 'Failsafe for no drops if institutional data missing for a section');  
     my @offon = ('off','on');      my @offon = ('off','on');
     my $sender_uname = $env{'form.sender_uname'};      my $sender_uname = $env{'form.sender_uname'};
     my $sender_domain = $env{'form.sender_domain'};      my $sender_domain = $env{'form.sender_domain'};
Line 8722  sub modify_autoenroll { Line 6128  sub modify_autoenroll {
         $sender_domain = '';          $sender_domain = '';
     }      }
     my $coowners = $env{'form.autoassign_coowners'};      my $coowners = $env{'form.autoassign_coowners'};
     my $failsafe = $env{'form.autoenroll_failsafe'};  
     $failsafe =~ s{^\s+|\s+$}{}g;  
     if ($failsafe =~ /\D/) {  
         undef($failsafe);  
     }  
     my %autoenrollhash =  (      my %autoenrollhash =  (
                        autoenroll => { 'run' => $env{'form.autoenroll_run'},                         autoenroll => { 'run' => $env{'form.autoenroll_run'},
                                        'sender_uname' => $sender_uname,                                         'sender_uname' => $sender_uname,
                                        'sender_domain' => $sender_domain,                                         'sender_domain' => $sender_domain,
                                        'co-owners' => $coowners,                                         'co-owners' => $coowners,
                                        'autofailsafe' => $failsafe,  
                                 }                                  }
                      );                       );
     my $putresult = &Apache::lonnet::put_dom('configuration',\%autoenrollhash,      my $putresult = &Apache::lonnet::put_dom('configuration',\%autoenrollhash,
Line 8759  sub modify_autoenroll { Line 6159  sub modify_autoenroll {
             }              }
         } elsif ($coowners) {          } elsif ($coowners) {
             $changes{'coowners'} = 1;              $changes{'coowners'} = 1;
         }          }      
         if ($currautoenroll{'autofailsafe'} ne $failsafe) {  
             $changes{'autofailsafe'} = 1;  
         }  
         if (keys(%changes) > 0) {          if (keys(%changes) > 0) {
             $resulttext = &mt('Changes made:').'<ul>';              $resulttext = &mt('Changes made:').'<ul>';
             if ($changes{'run'}) {              if ($changes{'run'}) {
Line 8778  sub modify_autoenroll { Line 6175  sub modify_autoenroll {
             if ($changes{'coowners'}) {              if ($changes{'coowners'}) {
                 $resulttext .= '<li>'.&mt("$title{'coowners'} set to $offon[$env{'form.autoassign_coowners'}]").'</li>';                  $resulttext .= '<li>'.&mt("$title{'coowners'} set to $offon[$env{'form.autoassign_coowners'}]").'</li>';
                 &Apache::loncommon::devalidate_domconfig_cache($dom);                  &Apache::loncommon::devalidate_domconfig_cache($dom);
                 if (ref($lastactref) eq 'HASH') {  
                     $lastactref->{'domainconfig'} = 1;  
                 }  
             }  
             if ($changes{'autofailsafe'}) {  
                 if ($failsafe ne '') {  
                     $resulttext .= '<li>'.&mt('Failsafe for no drops if institutional data missing for a section set to: [_1]',$failsafe).'</li>';  
                 } else {  
                     $resulttext .= '<li>'.&mt('Failsafe for no drops if institutional data missing for a section: deleted');  
                 }  
                 &Apache::lonnet::get_domain_defaults($dom,1);  
                 if (ref($lastactref) eq 'HASH') {  
                     $lastactref->{'domdefaults'} = 1;  
                 }  
             }              }
             $resulttext .= '</ul>';              $resulttext .= '</ul>';
         } else {          } else {
Line 9008  sub modify_autocreate { Line 6391  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 9065  sub modify_autocreate { Line 6448  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 9073  sub modify_directorysrch { Line 6456  sub modify_directorysrch {
             $currdirsrch{$key} = $domconfig{'directorysrch'}{$key};              $currdirsrch{$key} = $domconfig{'directorysrch'}{$key};
         }          }
     }      }
     my %title = ( available => 'Institutional directory search available',      my %title = ( available => 'Directory search available',
                   localonly => 'Other domains can search institution',                    localonly => 'Other domains can search',
                   lcavailable => 'LON-CAPA directory search available',  
                   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 9150  sub modify_directorysrch { Line 6531  sub modify_directorysrch {
     my %dirsrch_hash =  (      my %dirsrch_hash =  (
             directorysrch => { available => $env{'form.dirsrch_available'},              directorysrch => { available => $env{'form.dirsrch_available'},
                                cansearch => \@cansearch,                                 cansearch => \@cansearch,
                                localonly => $env{'form.dirsrch_instlocalonly'},                                 localonly => $env{'form.dirsrch_localonly'},
                                lclocalonly => $env{'form.dirsrch_domlocalonly'},  
                                lcavailable => $env{'form.dirsrch_domavailable'},  
                                searchby => \@searchby,                                 searchby => \@searchby,
                                searchtypes => \@searchtypes,                                 searchtypes => \@searchtypes,
                              }                               }
Line 9169  sub modify_directorysrch { Line 6548  sub modify_directorysrch {
                 $changes{'available'} = 1;                  $changes{'available'} = 1;
             }              }
         }          }
         if (exists($currdirsrch{'lcavailable'})) {  
             if ($currdirsrch{'lcavailable'} ne $env{'form.dirsrch_domavailable'}) {  
                 $changes{'lcavailable'} = 1;  
             }  
         } else {  
             if ($env{'form.dirsrch_lcavailable'} eq '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_localonly'}) {
                 $changes{'localonly'} = 1;                   $changes{'localonly'} = 1;
             }               }
         } else {          } else {
             if ($env{'form.dirsrch_instlocalonly'} eq '1') {              if ($env{'form.dirsrch_localonly'} eq '1') {
                 $changes{'localonly'} = 1;                  $changes{'localonly'} = 1;
             }              }
         }          }
         if (exists($currdirsrch{'lclocalonly'})) {  
             if ($currdirsrch{'lclocalonly'} ne $env{'form.dirsrch_domlocalonly'}) {  
                 $changes{'lclocalonly'} = 1;  
             }  
         } else {  
             if ($env{'form.dirsrch_domlocalonly'} eq '1') {  
                 $changes{'lclocalonly'} = 1;  
             }  
         }  
         if (keys(%changes) > 0) {          if (keys(%changes) > 0) {
             $resulttext = &mt('Changes made:').'<ul>';              $resulttext = &mt('Changes made:').'<ul>';
             if ($changes{'available'}) {              if ($changes{'available'}) {
                 $resulttext .= '<li>'.&mt("$title{'available'} set to: $offon[$env{'form.dirsrch_available'}]").'</li>';                  $resulttext .= '<li>'.&mt("$title{'available'} set to: $offon[$env{'form.dirsrch_available'}]").'</li>';
             }              }
             if ($changes{'lcavailable'}) {  
                 $resulttext .= '<li>'.&mt("$title{'lcavailable'} set to: $offon[$env{'form.dirsrch_domavailable'}]").'</li>';  
             }  
             if ($changes{'localonly'}) {              if ($changes{'localonly'}) {
                 $resulttext .= '<li>'.&mt("$title{'localonly'} set to: $otherdoms[$env{'form.dirsrch_instlocalonly'}]").'</li>';                  $resulttext .= '<li>'.&mt("$title{'localonly'} set to: $otherdoms[$env{'form.dirsrch_localonly'}]").'</li>';
             }  
             if ($changes{'lclocalonly'}) {  
                 $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 9224  sub modify_directorysrch { Line 6580  sub modify_directorysrch {
                         } else {                          } else {
                             $chgtext =~ s/\; $//;                              $chgtext =~ s/\; $//;
                         }                          }
                         $resulttext .=                          $resulttext .= 
                             '<li>'.                              '<li>'.
                             &mt("Users from domain '[_1]' permitted to search the institutional directory set to: [_2]",                              &mt("Users from domain '[_1]' permitted to search the institutional directory set to: [_2]",
                                 '<span class="LC_cusr_emph">'.$dom.'</span>',$chgtext).                                  '<span class="LC_cusr_emph">'.$dom.'</span>',$chgtext).
Line 9259  sub modify_directorysrch { Line 6615  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 institution directory search settings');
         }          }
     } else {      } else {
         $resulttext = '<span class="LC_error">'.          $resulttext = '<span class="LC_error">'.
Line 9274  sub modify_directorysrch { Line 6626  sub modify_directorysrch {
 }  }
   
 sub modify_contacts {  sub modify_contacts {
     my ($dom,$lastactref,%domconfig) = @_;      my ($dom,%domconfig) = @_;
     my ($resulttext,%currsetting,%newsetting,%changes,%contacts_hash);      my ($resulttext,%currsetting,%newsetting,%changes,%contacts_hash);
     if (ref($domconfig{'contacts'}) eq 'HASH') {      if (ref($domconfig{'contacts'}) eq 'HASH') {
         foreach my $key (keys(%{$domconfig{'contacts'}})) {          foreach my $key (keys(%{$domconfig{'contacts'}})) {
             $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');
     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 9296  sub modify_contacts { Line 6646  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) {
         $to{$item} = $env{'form.'.$item};          $to{$item} = $env{'form.'.$item};
         $contacts_hash{'contacts'}{$item} = $to{$item};          $contacts_hash{'contacts'}{$item} = $to{$item};
     }      }
     foreach my $item (@toggles) {  
         if ($env{'form.'.$item} =~ /^(0|1)$/) {  
             $contacts_hash{'contacts'}{$item} = $env{'form.'.$item};  
         }  
     }  
     if ((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 9354  sub modify_contacts { Line 6677  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 9396  sub modify_contacts { Line 6690  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');  
                     }  
                 }  
             }              }
         }          }
     }      }
     foreach my $item (@toggles) {  
         if (($env{'form.'.$item} == 1) && ($currsetting{$item} == 0)) {  
             $changes{$item} = 1;  
         } elsif ((!$env{'form.'.$item}) &&  
                  (($currsetting{$item} eq '') || ($currsetting{$item} == 1))) {  
             $changes{$item} = 1;  
         }  
     }  
     my $putresult = &Apache::lonnet::put_dom('configuration',\%contacts_hash,      my $putresult = &Apache::lonnet::put_dom('configuration',\%contacts_hash,
                                              $dom);                                               $dom);
     if ($putresult eq 'ok') {      if ($putresult eq 'ok') {
         if (keys(%changes) > 0) {          if (keys(%changes) > 0) {
             &Apache::loncommon::devalidate_domconfig_cache($dom);  
             if (ref($lastactref) eq 'HASH') {  
                 $lastactref->{'domainconfig'} = 1;  
             }  
             my ($titles,$short_titles)  = &contact_titles();              my ($titles,$short_titles)  = &contact_titles();
             $resulttext = &mt('Changes made:').'<ul>';              $resulttext = &mt('Changes made:').'<ul>';
             foreach my $item (@contacts) {              foreach my $item (@contacts) {
Line 9462  sub modify_contacts { Line 6729  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 9474  sub modify_contacts { Line 6737  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>';
                 }                  }
             }              }
             my @offon = ('off','on');  
             if ($changes{'reporterrors'}) {  
                 $resulttext .= '<li>'.  
                                &mt('E-mail error reports to [_1] set to "'.  
                                    $offon[$env{'form.reporterrors'}].'".',  
                                    &Apache::loncommon::modal_link('http://loncapa.org/core.html',  
                                        &mt('LON-CAPA core group - MSU'),600,500)).  
                                '</li>';  
             }  
             if ($changes{'reportupdates'}) {  
                 $resulttext .= '<li>'.  
                                 &mt('E-mail record of completed LON-CAPA updates to [_1] set to "'.  
                                     $offon[$env{'form.reportupdates'}].'".',  
                                     &Apache::loncommon::modal_link('http://loncapa.org/core.html',  
                                         &mt('LON-CAPA core group - MSU'),600,500)).  
                                 '</li>';  
             }  
             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 9574  sub modify_contacts { Line 6760  sub modify_contacts {
   
 sub modify_usercreation {  sub modify_usercreation {
     my ($dom,%domconfig) = @_;      my ($dom,%domconfig) = @_;
     my ($resulttext,%curr_usercreation,%changes,%authallowed,%cancreate,%save_usercreate);      my ($resulttext,%curr_usercreation,%changes,%authallowed,%cancreate);
     my $warningmsg;      my $warningmsg;
     if (ref($domconfig{'usercreation'}) eq 'HASH') {      if (ref($domconfig{'usercreation'}) eq 'HASH') {
         foreach my $key (keys(%{$domconfig{'usercreation'}})) {          foreach my $key (keys(%{$domconfig{'usercreation'}})) {
             if ($key eq 'cancreate') {              $curr_usercreation{$key} = $domconfig{'usercreation'}{$key};
                 if (ref($domconfig{'usercreation'}{$key}) eq 'HASH') {  
                     foreach my $item (keys(%{$domconfig{'usercreation'}{$key}})) {  
                         if (($item eq 'selfcreate') || ($item eq 'statustocreate') ||  
                             ($item eq 'captcha') || ($item eq 'recaptchakeys') ||  
                             ($item eq 'recaptchaversion')) {  
                             $save_usercreate{$key}{$item} = $domconfig{'usercreation'}{$key}{$item};  
                         } else {  
                             $curr_usercreation{$key}{$item} = $domconfig{'usercreation'}{$key}{$item};  
                         }  
                     }  
                 }  
             } elsif ($key eq 'email_rule') {  
                 $save_usercreate{$key} = $domconfig{'usercreation'}{$key};  
             } else {  
                 $curr_usercreation{$key} = $domconfig{'usercreation'}{$key};  
             }  
         }          }
     }      }
     my @username_rule = &Apache::loncommon::get_env_multiple('form.username_rule');      my @username_rule = &Apache::loncommon::get_env_multiple('form.username_rule');
     my @id_rule = &Apache::loncommon::get_env_multiple('form.id_rule');      my @id_rule = &Apache::loncommon::get_env_multiple('form.id_rule');
     my @contexts = ('author','course','requestcrs');      my @email_rule = &Apache::loncommon::get_env_multiple('form.email_rule');
       my @contexts = ('author','course','requestcrs','selfcreate');
     foreach my $item(@contexts) {      foreach my $item(@contexts) {
         $cancreate{$item} = $env{'form.can_createuser_'.$item};          if ($item eq 'selfcreate') {
               @{$cancreate{$item}} = &Apache::loncommon::get_env_multiple('form.can_createuser_'.$item);
               my %domdefaults = &Apache::lonnet::get_domain_defaults($dom);
               if (!((($domdefaults{'auth_def'} =~/^krb/) && ($domdefaults{'auth_arg_def'} ne '')) || ($domdefaults{'auth_def'} eq 'localauth'))) {
                   if (ref($cancreate{$item}) eq 'ARRAY') { 
                       if (grep(/^login$/,@{$cancreate{$item}})) {
                           $warningmsg = &mt('Although account creation has been set to be available for institutional logins, currently default authentication in this domain has not been set to support this.').' '.&mt('You need to set the default authentication type to Kerberos 4 or 5 (with a Kerberos domain specified), or to Local authentication, if the localauth module has been customized in your domain to authenticate institutional logins.');   
                       }
                   }
               }
           } else {
               $cancreate{$item} = $env{'form.can_createuser_'.$item};
           }
       }
       my ($othertitle,$usertypes,$types) = 
           &Apache::loncommon::sorted_inst_types($dom);
       if (ref($types) eq 'ARRAY') {
           if (@{$types} > 0) {
               @{$cancreate{'statustocreate'}} = 
                   &Apache::loncommon::get_env_multiple('form.statustocreate');
           } else {
               @{$cancreate{'statustocreate'}} = ();
           }
           push(@contexts,'statustocreate');
     }      }
       &process_captcha('cancreate',\%changes,\%cancreate,\%curr_usercreation);
     if (ref($curr_usercreation{'cancreate'}) eq 'HASH') {      if (ref($curr_usercreation{'cancreate'}) eq 'HASH') {
         foreach my $item (@contexts) {          foreach my $item (@contexts) {
             if ($curr_usercreation{'cancreate'}{$item} ne $cancreate{$item}) {              if (($item eq 'selfcreate') || ($item eq 'statustocreate')) {
                 push(@{$changes{'cancreate'}},$item);                  if (ref($curr_usercreation{'cancreate'}{$item}) eq 'ARRAY') {
                       foreach my $curr (@{$curr_usercreation{'cancreate'}{$item}}) {
                           if (ref($cancreate{$item}) eq 'ARRAY') {
                               if (!grep(/^$curr$/,@{$cancreate{$item}})) {
                                   if (!grep(/^$item$/,@{$changes{'cancreate'}})) {
                                       push(@{$changes{'cancreate'}},$item);
                                   }
                               }
                           }
                       }
                   } else {
                       if ($curr_usercreation{'cancreate'}{$item} eq '') {
                           if (@{$cancreate{$item}} > 0) {
                               if (!grep(/^$item$/,@{$changes{'cancreate'}})) {
                                   push(@{$changes{'cancreate'}},$item);
                               }
                           }
                       } else {
                           if ($curr_usercreation{'cancreate'}{$item} eq 'any') {
                               if (@{$cancreate{$item}} < 3) {
                                   if (!grep(/^$item$/,@{$changes{'cancreate'}})) {
                                       push(@{$changes{'cancreate'}},$item);
                                   }
                               }
                           } elsif ($curr_usercreation{'cancreate'}{$item} eq 'none') {
                               if (@{$cancreate{$item}} > 0) {
                                   if (!grep(/^$item$/,@{$changes{'cancreate'}})) {
                                       push(@{$changes{'cancreate'}},$item);
                                   }
                               }
                           } elsif (!grep(/^$curr_usercreation{'cancreate'}{$item}$/,@{$cancreate{$item}})) {
                               if (!grep(/^$item$/,@{$changes{'cancreate'}})) {
                                   push(@{$changes{'cancreate'}},$item);
                               }
                           }
                       }
                   }
                   if (!grep(/^$item$/,@{$changes{'cancreate'}})) {
                       foreach my $type (@{$cancreate{$item}}) {
                           if (ref($curr_usercreation{'cancreate'}{$item}) eq 'ARRAY') {
                               if (!grep(/^$type$/,@{$curr_usercreation{'cancreate'}{$item}})) {
                                   if (!grep(/^$item$/,@{$changes{'cancreate'}})) {
                                       push(@{$changes{'cancreate'}},$item);
                                   }
                               }
                           } elsif (($curr_usercreation{'cancreate'}{$item} ne 'any') &&
                                    ($curr_usercreation{'cancreate'}{$item} ne 'none')) {
                               if ($curr_usercreation{'cancreate'}{$item} ne $type) {
                                   if (!grep(/^$item$/,@{$changes{'cancreate'}})) {
                                       push(@{$changes{'cancreate'}},$item);
                                   }
                               }
                           }
                       }
                   }
               } else {
                   if ($curr_usercreation{'cancreate'}{$item} ne $cancreate{$item}) {
                       push(@{$changes{'cancreate'}},$item);
                   }
             }              }
         }          }
     } elsif (ref($curr_usercreation{'cancreate'}) eq 'ARRAY') {      } elsif (ref($curr_usercreation{'cancreate'}) eq 'ARRAY') {
Line 9657  sub modify_usercreation { Line 6910  sub modify_usercreation {
         push(@{$changes{'id_rule'}},@id_rule);          push(@{$changes{'id_rule'}},@id_rule);
     }      }
   
       if (ref($curr_usercreation{'email_rule'}) eq 'ARRAY') {
           foreach my $type (@{$curr_usercreation{'email_rule'}}) {
               if (!grep(/^\Q$type\E$/,@email_rule)) {
                   push(@{$changes{'email_rule'}},$type);
               }
           }
           foreach my $type (@email_rule) {
               if (!grep(/^\Q$type\E$/,@{$curr_usercreation{'email_rule'}})) {
                   push(@{$changes{'email_rule'}},$type);
               }
           }
       } else {
           push(@{$changes{'email_rule'}},@email_rule);
       }
   
     my @authen_contexts = ('author','course','domain');      my @authen_contexts = ('author','course','domain');
     my @authtypes = ('int','krb4','krb5','loc');      my @authtypes = ('int','krb4','krb5','loc');
     my %authhash;      my %authhash;
Line 9687  sub modify_usercreation { Line 6955  sub modify_usercreation {
         }          }
     }      }
   
     $save_usercreate{'cancreate'}{'course'} = $cancreate{'course'};   
     $save_usercreate{'cancreate'}{'author'} = $cancreate{'author'};  
     $save_usercreate{'cancreate'}{'requestcrs'} = $cancreate{'requestcrs'};  
     $save_usercreate{'id_rule'} = \@id_rule;  
     $save_usercreate{'username_rule'} = \@username_rule,  
     $save_usercreate{'authtypes'} = \%authhash;  
   
     my %usercreation_hash =  (      my %usercreation_hash =  (
         usercreation     => \%save_usercreate,              usercreation => {
     );                                cancreate     => \%cancreate,
                                 username_rule => \@username_rule,
                                 id_rule       => \@id_rule,
                                 email_rule    => \@email_rule,
                                 authtypes     => \%authhash,
                               }
               );
   
     my $putresult = &Apache::lonnet::put_dom('configuration',\%usercreation_hash,      my $putresult = &Apache::lonnet::put_dom('configuration',\%usercreation_hash,
                                              $dom);                                               $dom);
   
     if ($putresult eq 'ok') {  
         if (keys(%changes) > 0) {  
             $resulttext = &mt('Changes made:').'<ul>';  
             if (ref($changes{'cancreate'}) eq 'ARRAY') {  
                 my %lt = &usercreation_types();  
                 foreach my $type (@{$changes{'cancreate'}}) {  
                     my $chgtext = $lt{$type}.', ';  
                     if ($cancreate{$type} eq 'none') {  
                         $chgtext .= &mt('creation of new users is not permitted, except by a Domain Coordinator.');  
                     } elsif ($cancreate{$type} eq 'any') {  
                         $chgtext .= &mt('creation of new users is permitted for both institutional and non-institutional usernames.');  
                     } elsif ($cancreate{$type} eq 'official') {  
                         $chgtext .= &mt('creation of new users is only permitted for institutional usernames.');  
                     } elsif ($cancreate{$type} eq 'unofficial') {  
                         $chgtext .= &mt('creation of new users is only permitted for non-institutional usernames.');  
                     }  
                     $resulttext .= '<li>'.$chgtext.'</li>';  
                 }  
             }  
             if (ref($changes{'username_rule'}) eq 'ARRAY') {  
                 my ($rules,$ruleorder) =   
                     &Apache::lonnet::inst_userrules($dom,'username');  
                 my $chgtext = '<ul>';  
                 foreach my $type (@username_rule) {  
                     if (ref($rules->{$type}) eq 'HASH') {  
                         $chgtext .= '<li>'.$rules->{$type}{'name'}.'</li>';  
                     }  
                 }  
                 $chgtext .= '</ul>';  
                 if (@username_rule > 0) {  
                     $resulttext .= '<li>'.&mt('Usernames with the following formats are restricted to verified users in the institutional directory: ').$chgtext.'</li>';       
                 } else {  
                     $resulttext .= '<li>'.&mt('There are now no username formats restricted to verified users in the institutional directory.').'</li>';   
                 }  
             }  
             if (ref($changes{'id_rule'}) eq 'ARRAY') {  
                 my ($idrules,$idruleorder) =   
                     &Apache::lonnet::inst_userrules($dom,'id');  
                 my $chgtext = '<ul>';  
                 foreach my $type (@id_rule) {  
                     if (ref($idrules->{$type}) eq 'HASH') {  
                         $chgtext .= '<li>'.$idrules->{$type}{'name'}.'</li>';  
                     }  
                 }  
                 $chgtext .= '</ul>';  
                 if (@id_rule > 0) {  
                     $resulttext .= '<li>'.&mt('IDs with the following formats are restricted to verified users in the institutional directory: ').$chgtext.'</li>';  
                 } else {  
                     $resulttext .= '<li>'.&mt('There are now no ID formats restricted to verified users in the institutional directory.').'</li>';  
                 }  
             }  
             my %authname = &authtype_names();  
             my %context_title = &context_names();  
             if (ref($changes{'authtypes'}) eq 'ARRAY') {  
                 my $chgtext = '<ul>';  
                 foreach my $type (@{$changes{'authtypes'}}) {  
                     my @allowed;  
                     $chgtext .= '<li><span class="LC_cusr_emph">'.$context_title{$type}.'</span> - '.&mt('assignable authentication types: ');  
                     foreach my $auth (@authtypes) {  
                         if ($authhash{$type}{$auth}) {  
                             push(@allowed,$authname{$auth});  
                         }  
                     }  
                     if (@allowed > 0) {  
                         $chgtext .= join(', ',@allowed).'</li>';  
                     } else {  
                         $chgtext .= &mt('none').'</li>';  
                     }  
                 }  
                 $chgtext .= '</ul>';  
                 $resulttext .= '<li>'.&mt('Authentication types available for assignment to new users').'<br />'.$chgtext;  
                 $resulttext .= '</li>';  
             }  
             $resulttext .= '</ul>';  
         } else {  
             $resulttext = &mt('No changes made to user creation settings');  
         }  
     } else {  
         $resulttext = '<span class="LC_error">'.  
             &mt('An error occurred: [_1]',$putresult).'</span>';  
     }  
     if ($warningmsg ne '') {  
         $resulttext .= '<br /><span class="LC_warning">'.$warningmsg.'</span><br />';  
     }  
     return $resulttext;  
 }  
   
 sub modify_selfcreation {  
     my ($dom,%domconfig) = @_;  
     my ($resulttext,$warningmsg,%curr_usercreation,%curr_usermodify,%changes,%cancreate);  
     my (%save_usercreate,%save_usermodify);  
     my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom);  
     if (ref($types) eq 'ARRAY') {  
         $usertypes->{'default'} = $othertitle;  
         push(@{$types},'default');  
     }  
 #  
 # Retrieve current domain configuration for self-creation of usernames from $domconfig{'usercreation'}.  
 #  
     if (ref($domconfig{'usercreation'}) eq 'HASH') {  
         foreach my $key (keys(%{$domconfig{'usercreation'}})) {  
             if ($key eq 'cancreate') {  
                 if (ref($domconfig{'usercreation'}{$key}) eq 'HASH') {  
                     foreach my $item (keys(%{$domconfig{'usercreation'}{$key}})) {  
                         if (($item eq 'selfcreate') || ($item eq 'statustocreate') ||  
                             ($item eq 'captcha') || ($item eq 'recaptchakeys') ||   
                             ($item eq 'recaptchaversion') ||  
                             ($item eq 'emailusername') || ($item eq 'notify') ||  
                             ($item eq 'selfcreateprocessing') || ($item eq 'shibenv')) {  
                             $curr_usercreation{$key}{$item} = $domconfig{'usercreation'}{$key}{$item};  
                         } else {  
                             $save_usercreate{$key}{$item} = $domconfig{'usercreation'}{$key}{$item};  
                         }  
                     }  
                 }  
             } elsif ($key eq 'email_rule') {  
                 $curr_usercreation{$key} = $domconfig{'usercreation'}{$key};  
             } else {  
                 $save_usercreate{$key} = $domconfig{'usercreation'}{$key};  
             }  
         }  
     }  
 #  
 # Retrieve current domain configuration for self-creation of usernames from $domconfig{'usermodification'}.  
 #  
     if (ref($domconfig{'usermodification'}) eq 'HASH') {  
         foreach my $key (keys(%{$domconfig{'usermodification'}})) {  
             if ($key eq 'selfcreate') {  
                 $curr_usermodify{$key} = $domconfig{'usermodification'}{$key};  
             } else {  
                 $save_usermodify{$key} = $domconfig{'usermodification'}{$key};  
             }  
         }  
     }  
   
     my @contexts = ('selfcreate');  
     @{$cancreate{'selfcreate'}} = ();  
     %{$cancreate{'emailusername'}} = ();  
     @{$cancreate{'statustocreate'}} = ();  
     %{$cancreate{'selfcreateprocessing'}} = ();  
     %{$cancreate{'shibenv'}} = ();  
     my %selfcreatetypes = (      my %selfcreatetypes = (
                              sso   => 'users authenticated by institutional single sign on',                               sso   => 'users authenticated by institutional single sign on',
                              login => 'users authenticated by institutional log-in',                               login => 'users authenticated by institutional log-in',
                              email => 'users who provide a valid e-mail address for use as username',                               email => 'users who provide a valid e-mail address for use as the username',
                           );                            );
 #  
 # Populate $cancreate{'selfcreate'} array reference with types of user, for which self-creation of user accounts  
 # is permitted.  
 #  
   
     my @statuses;  
     if (ref($domconfig{'inststatus'}) eq 'HASH') {  
         if (ref($domconfig{'inststatus'}{'inststatusguest'}) eq 'ARRAY') {  
             @statuses = @{$domconfig{'inststatus'}{'inststatusguest'}};  
         }  
     }  
     push(@statuses,'default');  
   
     foreach my $item ('login','sso','email') {  
         if ($item eq 'email') {  
             if ($env{'form.cancreate_email'}) {  
                 push(@{$cancreate{'selfcreate'}},'email');  
                 push(@contexts,'selfcreateprocessing');  
                 foreach my $type (@statuses) {  
                     if ($type eq 'default') {  
                         $cancreate{'selfcreateprocessing'}{$type} = $env{'form.cancreate_emailprocess'};  
                     } else {   
                         $cancreate{'selfcreateprocessing'}{$type} = $env{'form.cancreate_emailprocess_'.$type};  
                     }  
                 }  
             }  
         } else {  
             if ($env{'form.cancreate_'.$item}) {  
                 push(@{$cancreate{'selfcreate'}},$item);  
             }  
         }  
     }  
     my (@email_rule,%userinfo,%savecaptcha);  
     my ($infofields,$infotitles) = &Apache::loncommon::emailusername_info();  
 #  
 # Populate $cancreate{'emailusername'}{$type} hash ref with information fields (if new user will provide data  
 # value set to one), if self-creation with e-mail address permitted, where $type is user type: faculty, staff, student etc.  
 #  
   
     if ($env{'form.cancreate_email'}) {  
         push(@contexts,'emailusername');  
         if (ref($types) eq 'ARRAY') {  
             foreach my $type (@{$types}) {  
                 if (ref($infofields) eq 'ARRAY') {  
                     foreach my $field (@{$infofields}) {  
                         if ($env{'form.canmodify_emailusername_'.$type.'_'.$field} =~ /^(required|optional)$/) {  
                             $cancreate{'emailusername'}{$type}{$field} = $1;  
                         }  
                     }  
                 }  
             }  
         }  
 #  
 # Populate $cancreate{'notify'} hash ref with names of Domain Coordinators who are to be notified of  
 # queued requests for self-creation of account using e-mail address as username  
 #  
   
         my @approvalnotify = &Apache::loncommon::get_env_multiple('form.selfcreationnotifyapproval');  
         @approvalnotify = sort(@approvalnotify);  
         $cancreate{'notify'}{'approval'} = join(',',@approvalnotify);  
         if (ref($curr_usercreation{'cancreate'}) eq 'HASH') {  
             if (ref($curr_usercreation{'cancreate'}{'notify'}) eq 'HASH') {  
                 if ($curr_usercreation{'cancreate'}{'notify'}{'approval'} ne $cancreate{'notify'}{'approval'}) {  
                     push(@{$changes{'cancreate'}},'notify');  
                 }  
             } else {  
                 if ($cancreate{'notify'}{'approval'}) {  
                     push(@{$changes{'cancreate'}},'notify');  
                 }  
             }  
         } elsif ($cancreate{'notify'}{'approval'}) {  
             push(@{$changes{'cancreate'}},'notify');  
         }  
   
 #  
 # Retrieve rules (if any) governing types of e-mail address which may be used as a username  
 #  
         @email_rule = &Apache::loncommon::get_env_multiple('form.email_rule');  
         &process_captcha('cancreate',\%changes,\%savecaptcha,$curr_usercreation{'cancreate'});  
         if (ref($curr_usercreation{'email_rule'}) eq 'ARRAY') {  
             if (@{$curr_usercreation{'email_rule'}} > 0) {  
                 foreach my $type (@{$curr_usercreation{'email_rule'}}) {  
                     if (!grep(/^\Q$type\E$/,@email_rule)) {  
                         push(@{$changes{'email_rule'}},$type);  
                     }  
                 }  
             }  
             if (@email_rule > 0) {  
                 foreach my $type (@email_rule) {  
                     if (!grep(/^\Q$type\E$/,@{$curr_usercreation{'email_rule'}})) {  
                         push(@{$changes{'email_rule'}},$type);  
                     }  
                 }  
             }  
         } elsif (@email_rule > 0) {  
             push(@{$changes{'email_rule'}},@email_rule);  
         }  
     }  
 #    
 # Check if domain default is set appropriately, if self-creation of accounts is to be available for  
 # institutional log-in.  
 #  
     if (grep(/^login$/,@{$cancreate{'selfcreate'}})) {  
         my %domdefaults = &Apache::lonnet::get_domain_defaults($dom,1);  
         if (!((($domdefaults{'auth_def'} =~/^krb/) && ($domdefaults{'auth_arg_def'} ne '')) ||   
                ($domdefaults{'auth_def'} eq 'localauth'))) {  
             $warningmsg = &mt('Although account creation has been set to be available for institutional logins, currently default authentication in this domain has not been set to support this.').' '.  
                           &mt('You need to set the default authentication type to Kerberos 4 or 5 (with a Kerberos domain specified), or to Local authentication, if the localauth module has been customized in your domain to authenticate institutional logins.');  
         }  
     }  
     my @fields = ('lastname','firstname','middlename','generation',  
                   'permanentemail','id');  
     my @shibfields = (@fields,'inststatus');  
     my %fieldtitles = &Apache::loncommon::personal_data_fieldtitles();  
 #  
 # Where usernames may created for institutional log-in and/or institutional single sign on:  
 # (a) populate $cancreate{'statustocreate'} array reference with institutional status types who  
 # may self-create accounts   
 # (b) populate $save_usermodify{'selfcreate'} hash reference with status types, and information fields  
 # which the user may supply, if institutional data is unavailable.  
 #  
     if (($env{'form.cancreate_login'}) || ($env{'form.cancreate_sso'})) {  
         if (ref($types) eq 'ARRAY') {  
             if (@{$types} > 1) {  
                 @{$cancreate{'statustocreate'}} = &Apache::loncommon::get_env_multiple('form.statustocreate');  
                 push(@contexts,'statustocreate');  
             } else {  
                 undef($cancreate{'statustocreate'});  
             }   
             foreach my $type (@{$types}) {  
                 my @modifiable =  &Apache::loncommon::get_env_multiple('form.canmodify_'.$type);  
                 foreach my $field (@fields) {  
                     if (grep(/^\Q$field\E$/,@modifiable)) {  
                         $save_usermodify{'selfcreate'}{$type}{$field} = 1;  
                     } else {  
                         $save_usermodify{'selfcreate'}{$type}{$field} = 0;  
                     }  
                 }  
             }  
             if (ref($curr_usermodify{'selfcreate'}) eq 'HASH') {  
                 foreach my $type (@{$types}) {  
                     if (ref($curr_usermodify{'selfcreate'}{$type}) eq 'HASH') {  
                         foreach my $field (@fields) {  
                             if ($save_usermodify{'selfcreate'}{$type}{$field} ne  
                                 $curr_usermodify{'selfcreate'}{$type}{$field}) {  
                                 push(@{$changes{'selfcreate'}},$type);  
                                 last;  
                             }  
                         }  
                     }  
                 }  
             } else {  
                 foreach my $type (@{$types}) {  
                     push(@{$changes{'selfcreate'}},$type);  
                 }  
             }  
         }  
         foreach my $field (@shibfields) {  
             if ($env{'form.shibenv_'.$field} ne '') {  
                 $cancreate{'shibenv'}{$field} = $env{'form.shibenv_'.$field};  
             }  
         }  
         if (ref($curr_usercreation{'cancreate'}) eq 'HASH') {  
             if (ref($curr_usercreation{'cancreate'}{'shibenv'}) eq 'HASH') {  
                 foreach my $field (@shibfields) {  
                     if ($env{'form.shibenv_'.$field} ne $curr_usercreation{'cancreate'}{'shibenv'}{$field}) {  
                         push(@{$changes{'cancreate'}},'shibenv');  
                     }  
                 }  
             } else {  
                 foreach my $field (@shibfields) {  
                     if ($env{'form.shibenv_'.$field}) {  
                         push(@{$changes{'cancreate'}},'shibenv');  
                         last;  
                     }  
                 }  
             }  
         }  
     }  
     foreach my $item (@contexts) {  
         if (ref($curr_usercreation{'cancreate'}{$item}) eq 'ARRAY') {  
             foreach my $curr (@{$curr_usercreation{'cancreate'}{$item}}) {  
                 if (ref($cancreate{$item}) eq 'ARRAY') {  
                     if (!grep(/^$curr$/,@{$cancreate{$item}})) {  
                         if (!grep(/^$item$/,@{$changes{'cancreate'}})) {  
                             push(@{$changes{'cancreate'}},$item);  
                         }  
                     }  
                 }  
             }  
             if (ref($cancreate{$item}) eq 'ARRAY') {  
                 foreach my $type (@{$cancreate{$item}}) {  
                     if (!grep(/^$type$/,@{$curr_usercreation{'cancreate'}{$item}})) {  
                         if (!grep(/^$item$/,@{$changes{'cancreate'}})) {  
                             push(@{$changes{'cancreate'}},$item);  
                         }  
                     }  
                 }  
             }  
         } elsif (ref($curr_usercreation{'cancreate'}{$item}) eq 'HASH') {  
             if (ref($cancreate{$item}) eq 'HASH') {  
                 foreach my $curr (keys(%{$curr_usercreation{'cancreate'}{$item}})) {  
                     if (ref($curr_usercreation{'cancreate'}{$item}{$curr}) eq 'HASH') {  
                         foreach my $field (keys(%{$curr_usercreation{'cancreate'}{$item}{$curr}})) {  
                             unless ($curr_usercreation{'cancreate'}{$item}{$curr}{$field} eq $cancreate{$item}{$curr}{$field}) {  
                                 if (!grep(/^$item$/,@{$changes{'cancreate'}})) {  
                                     push(@{$changes{'cancreate'}},$item);  
                                 }  
                             }  
                         }  
                     } elsif ($item eq 'selfcreateprocessing') {  
                         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'}})) {  
                                 push(@{$changes{'cancreate'}},$item);  
                             }  
                         }  
                     }  
                 }  
                 foreach my $field (keys(%{$cancreate{$item}})) {  
                     if (ref($cancreate{$item}{$field}) eq 'HASH') {  
                         foreach my $inner (keys(%{$cancreate{$item}{$field}})) {  
                             if (ref($curr_usercreation{'cancreate'}{$item}{$field}) eq 'HASH') {  
                                 unless ($curr_usercreation{'cancreate'}{$item}{$field}{$inner} eq $cancreate{$item}{$field}{$inner}) {  
                                     if (!grep(/^$item$/,@{$changes{'cancreate'}})) {  
                                         push(@{$changes{'cancreate'}},$item);  
                                     }  
                                 }  
                             } else {  
                                 if (!grep(/^$item$/,@{$changes{'cancreate'}})) {  
                                     push(@{$changes{'cancreate'}},$item);  
                                 }  
                             }  
                         }  
                     } elsif ($item eq 'selfcreateprocessing') {  
                         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'}})) {  
                                 push(@{$changes{'cancreate'}},$item);  
                             }  
                         }  
                     }  
                 }  
             }  
         } elsif ($curr_usercreation{'cancreate'}{$item}) {  
             if (ref($cancreate{$item}) eq 'ARRAY') {  
                 if (!grep(/^\Q$curr_usercreation{'cancreate'}{$item}\E$/,@{$cancreate{$item}})) {  
                     if (!grep(/^$item$/,@{$changes{'cancreate'}})) {  
                         push(@{$changes{'cancreate'}},$item);  
                     }  
                 }  
             } elsif (ref($cancreate{$item}) eq 'HASH') {  
                 if (!$cancreate{$item}{$curr_usercreation{'cancreate'}{$item}}) {  
                     if (!grep(/^$item$/,@{$changes{'cancreate'}})) {  
                         push(@{$changes{'cancreate'}},$item);  
                     }  
                 }  
             }  
         } elsif ($item eq 'emailusername') {  
             if (ref($cancreate{$item}) eq 'HASH') {  
                 foreach my $type (keys(%{$cancreate{$item}})) {  
                     if (ref($cancreate{$item}{$type}) eq 'HASH') {  
                         foreach my $field (keys(%{$cancreate{$item}{$type}})) {  
                             if ($cancreate{$item}{$type}{$field}) {  
                                 if (!grep(/^$item$/,@{$changes{'cancreate'}})) {  
                                     push(@{$changes{'cancreate'}},$item);  
                                 }  
                                 last;  
                             }  
                         }  
                     }  
                 }  
             }  
         }  
     }  
 #  
 # Populate %save_usercreate hash with updates to self-creation configuration.  
 #  
     $save_usercreate{'cancreate'}{'captcha'} = $savecaptcha{'captcha'};  
     $save_usercreate{'cancreate'}{'recaptchakeys'} = $savecaptcha{'recaptchakeys'};  
     $save_usercreate{'cancreate'}{'recaptchaversion'} = $savecaptcha{'recaptchaversion'};  
     $save_usercreate{'cancreate'}{'selfcreate'} = $cancreate{'selfcreate'};  
     if (ref($cancreate{'notify'}) eq 'HASH') {  
         $save_usercreate{'cancreate'}{'notify'} = $cancreate{'notify'};  
     }  
     if (ref($cancreate{'selfcreateprocessing'}) eq 'HASH') {  
         $save_usercreate{'cancreate'}{'selfcreateprocessing'} = $cancreate{'selfcreateprocessing'};  
     }  
     if (ref($cancreate{'statustocreate'}) eq 'ARRAY') {  
         $save_usercreate{'cancreate'}{'statustocreate'} = $cancreate{'statustocreate'};  
     }  
     if (ref($cancreate{'shibenv'}) eq 'HASH') {  
         $save_usercreate{'cancreate'}{'shibenv'} = $cancreate{'shibenv'};  
     }  
     $save_usercreate{'cancreate'}{'emailusername'} = $cancreate{'emailusername'};  
     $save_usercreate{'email_rule'} = \@email_rule;  
   
     my %userconfig_hash = (  
             usercreation     => \%save_usercreate,  
             usermodification => \%save_usermodify,  
     );  
     my $putresult = &Apache::lonnet::put_dom('configuration',\%userconfig_hash,  
                                              $dom);  
 #  
 # Accumulate details of changes to domain cofiguration for self-creation of usernames in $resulttext  
 #  
     if ($putresult eq 'ok') {      if ($putresult eq 'ok') {
         if (keys(%changes) > 0) {          if (keys(%changes) > 0) {
             $resulttext = &mt('Changes made:').'<ul>';              $resulttext = &mt('Changes made:').'<ul>';
             if (ref($changes{'cancreate'}) eq 'ARRAY') {              if (ref($changes{'cancreate'}) eq 'ARRAY') {
                 my %lt = &selfcreation_types();                  my %lt = &usercreation_types();
                 foreach my $type (@{$changes{'cancreate'}}) {                  foreach my $type (@{$changes{'cancreate'}}) {
                     my $chgtext;                      my $chgtext;
                       unless (($type eq 'statustocreate') || ($type eq 'captcha') || ($type eq 'recaptchakeys')) {
                           $chgtext = $lt{$type}.', ';
                       }
                     if ($type eq 'selfcreate') {                      if ($type eq 'selfcreate') {
                         if (@{$cancreate{$type}} == 0) {                          if (@{$cancreate{$type}} == 0) {
                             $chgtext .= &mt('Self creation of a new user account is not permitted.');                              $chgtext .= &mt('creation of a new user account is not permitted.');
                         } else {                          } else {
                             $chgtext .= &mt('Self-creation of a new account is permitted for:').                              $chgtext .= &mt('creation of a new account is permitted for:').'<ul>';
                                         '<ul>';  
                             foreach my $case (@{$cancreate{$type}}) {                              foreach my $case (@{$cancreate{$type}}) {
                                 $chgtext .= '<li>'.$selfcreatetypes{$case}.'</li>';                                  $chgtext .= '<li>'.$selfcreatetypes{$case}.'</li>';
                             }                              }
Line 10184  sub modify_selfcreation { Line 6996  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 .= '<br />'.                                              $chgtext .= '<br /><span class="LC_warning">'.&mt("However, no institutional affiliations (including 'other') are currently permitted to create accounts.").'</span>';
                                                         '<span class="LC_warning">'.  
                                                         &mt("However, no institutional affiliations (including 'other') are currently permitted to create accounts.").  
                                                         '</span>';  
                                         }                                          }
                                     }                                      }
                                 }                                  }
                             }                              }
                         }                          }
                     } elsif ($type eq 'shibenv') {  
                         if (keys(%{$cancreate{$type}}) == 0) {  
                             $chgtext .= &mt('Shibboleth-autheticated user does not use environment variables to set user information');   
                         } else {  
                             $chgtext .= &mt('Shibboleth-autheticated user information set from environment variables, as follows:').  
                                         '<ul>';  
                             foreach my $field (@shibfields) {  
                                 next if ($cancreate{$type}{$field} eq '');  
                                 if ($field eq 'inststatus') {  
                                     $chgtext .= '<li>'.&mt('Institutional status').' -- '.$cancreate{$type}{$field}.'</li>';  
                                 } else {  
                                     $chgtext .= '<li>'.$fieldtitles{$field}.' -- '.$cancreate{$type}{$field}.'</li>';  
                                 }  
                             }  
                             $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')) {
                             if (@{$cancreate{'selfcreate'}} > 0) {                              if (@{$cancreate{'selfcreate'}} > 0) {
                                 if (@{$cancreate{'statustocreate'}} == 0) {                                  if (@{$cancreate{'statustocreate'}} == 0) {
   
                                     $chgtext .= &mt("Institutional affiliations permitted to create accounts set to 'None'.");                                      $chgtext .= &mt("Institutional affiliations permitted to create accounts set to 'None'.");
                                     if (!grep(/^email$/,@{$cancreate{'selfcreate'}})) {                                      if (!grep(/^email$/,@{$cancreate{'selfcreate'}})) {
                                         $chgtext .= '<br />'.                                          $chgtext .= '<br /><span class="LC_warning">'.&mt("However, no institutional affiliations (including 'other') are currently permitted to create accounts.").'</span>';
                                                     '<span class="LC_warning">'.                                      } 
                                                     &mt("However, no institutional affiliations (including 'other') are currently permitted to create accounts.").  
                                                     '</span>';  
                                     }  
                                 } elsif (ref($usertypes) eq 'HASH') {                                  } elsif (ref($usertypes) eq 'HASH') {
                                     if (grep(/^(login|sso)$/,@{$cancreate{'selfcreate'}})) {                                      if (grep(/^(login|sso)$/,@{$cancreate{'selfcreate'}})) {
                                         $chgtext .= &mt('Creation of a new account for an institutional user is restricted to the following institutional affiliation(s):');                                          $chgtext .= &mt('Creation of a new account for an institutional user is restricted to the following institutional affiliation(s):');
Line 10237  sub modify_selfcreation { Line 7028  sub modify_selfcreation {
                                     }                                      }
                                     $chgtext .= '</ul>';                                      $chgtext .= '</ul>';
                                     if (!grep(/^(login|sso)$/,@{$cancreate{'selfcreate'}})) {                                      if (!grep(/^(login|sso)$/,@{$cancreate{'selfcreate'}})) {
                                         $chgtext .= '<br /><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.').'</span>';
                                                     &mt('However, users authenticated by institutional login/single sign on are not currently permitted to create accounts.').  
                                                     '</span>';  
                                     }                                      }
                                 }                                  }
                             } else {                              } else {
Line 10250  sub modify_selfcreation { Line 7039  sub modify_selfcreation {
                                 }                                  }
                             }                              }
                         }                          }
                     } elsif ($type eq 'selfcreateprocessing') {  
                         my %choices = &Apache::lonlocal::texthash (  
                                                                     automatic => 'Automatic approval',  
                                                                     approval  => 'Queued for approval',  
                                                                   );  
                         if (@statuses > 1) {  
                             $chgtext .= &mt('Processing of requests to create account with e-mail address as username set as follows:').   
                                         '<ul>';  
                            foreach my $type (@statuses) {  
                                if ($type eq 'default') {  
                                    $chgtext .= '<li>'.$othertitle.' -- '.$choices{$cancreate{'selfcreateprocessing'}{$type}}.'</li>';  
                                } else {  
                                    $chgtext .= '<li>'.$usertypes->{$type}.' -- '.$choices{$cancreate{'selfcreateprocessing'}{$type}}.'</li>';  
                                }  
                            }  
                            $chgtext .= '</ul>';  
                         } else {  
                            $chgtext .= &mt('Processing of requests to create account with e-mail address as username set to: "[_1]"',  
                                          $choices{$cancreate{'selfcreateprocessing'}{'default'}});  
                         }  
                     } elsif ($type eq 'captcha') {                      } elsif ($type eq 'captcha') {
                         if ($savecaptcha{$type} eq 'notused') {                          if ($cancreate{$type} eq 'notused') {
                             $chgtext .= &mt('No CAPTCHA validation in use for self-creation screen.');                              $chgtext .= &mt('No CAPTCHA validation in use for self-creation screen.');
                         } else {                          } else {
                             my %captchas = &captcha_phrases();                              my %captchas = &captcha_phrases();
                             if ($captchas{$savecaptcha{$type}}) {                              if ($captchas{$cancreate{$type}}) {
                                 $chgtext .= &mt("Validation for self-creation screen set to $captchas{$savecaptcha{$type}}.");                                  $chgtext .= &mt("Validation for self-creation screen set to $captchas{$cancreate{$type}}.");
                             } else {                              } else {
                                 $chgtext .= &mt('Validation for self-creation screen set to unknown type.');                                  $chgtext .= &mt('Validation for self-creation screen set to unknown type.'); 
                             }                              }
                         }                          }
                     } elsif ($type eq 'recaptchakeys') {                      } elsif ($type eq 'recaptchakeys') {
                         my ($privkey,$pubkey);                          my ($privkey,$pubkey);
                         if (ref($savecaptcha{$type}) eq 'HASH') {                          if (ref($cancreate{$type}) eq 'HASH') {
                             $pubkey = $savecaptcha{$type}{'public'};                              $pubkey = $cancreate{$type}{'public'};
                             $privkey = $savecaptcha{$type}{'private'};                              $privkey = $cancreate{$type}{'private'};
                         }                          }
                         $chgtext .= &mt('ReCAPTCHA keys changes').'<ul>';                          $chgtext .= &mt('ReCAPTCHA keys changes').'<ul>';
                         if (!$pubkey) {                          if (!$pubkey) {
Line 10299  sub modify_selfcreation { Line 7068  sub modify_selfcreation {
                             $chgtext .= '<li>'.&mt('Private key set to [_1]',$pubkey).'</li>';                              $chgtext .= '<li>'.&mt('Private key set to [_1]',$pubkey).'</li>';
                         }                          }
                         $chgtext .= '</ul>';                          $chgtext .= '</ul>';
                     } elsif ($type eq 'recaptchaversion') {                      } else {
                         if ($savecaptcha{'captcha'} eq 'recaptcha') {                          if ($cancreate{$type} eq 'none') {
                             $chgtext .= &mt('ReCAPTCHA set to version [_1]',$savecaptcha{$type});                              $chgtext .= &mt('creation of new users is not permitted, except by a Domain Coordinator.');
                         }                          } elsif ($cancreate{$type} eq 'any') {
                     } elsif ($type eq 'emailusername') {                              $chgtext .= &mt('creation of new users is permitted for both institutional and non-institutional usernames.');
                         if (ref($cancreate{'emailusername'}) eq 'HASH') {                          } elsif ($cancreate{$type} eq 'official') {
                             if (ref($types) eq 'ARRAY') {                              $chgtext .= &mt('creation of new users is only permitted for institutional usernames.');
                                 foreach my $type (@{$types}) {                          } elsif ($cancreate{$type} eq 'unofficial') {
                                     if (ref($cancreate{'emailusername'}{$type}) eq 'HASH') {                              $chgtext .= &mt('creation of new users is only permitted for non-institutional usernames.');
                                         if (keys(%{$cancreate{'emailusername'}{$type}}) > 0) {  
                                             $chgtext .= &mt('When self-creating account with e-mail as username, the following information will be provided by [_1]:',"'$usertypes->{$type}'").  
                                                     '<ul>';  
                                             foreach my $field (@{$infofields}) {  
                                                 if ($cancreate{'emailusername'}{$type}{$field}) {  
                                                     $chgtext .= '<li>'.$infotitles->{$field}.'</li>';  
                                                 }  
                                             }  
                                             $chgtext .= '</ul>';  
                                         } else {  
                                             $chgtext .= &mt('When self creating account with e-mail as username, no information besides e-mail address will be provided by [_1].',"'$usertypes->{$type}'").'<br />';  
                                         }  
                                     } else {  
                                         $chgtext .= &mt('When self creating account with e-mail as username, no information besides e-mail address will be provided by [_1].',"'$usertypes->{$type}'").'<br />';  
                                     }  
                                 }  
                             }  
                         }  
                     } elsif ($type eq 'notify') {  
                         $chgtext = &mt('No Domain Coordinators will receive notification of username requests requiring approval.');  
                         if (ref($changes{'cancreate'}) eq 'ARRAY') {  
                             if ((grep(/^notify$/,@{$changes{'cancreate'}})) && (ref($cancreate{'notify'}) eq 'HASH')) {  
                                 if ($cancreate{'notify'}{'approval'}) {  
                                     $chgtext = &mt('Notification of username requests requiring approval will be sent to: ').$cancreate{'notify'}{'approval'};  
                                 }  
                             }  
                         }                          }
                     }                      }
                     if ($chgtext) {                      $resulttext .= '<li>'.$chgtext.'</li>';
                         $resulttext .= '<li>'.$chgtext.'</li>';                  }
               }
               if (ref($changes{'username_rule'}) eq 'ARRAY') {
                   my ($rules,$ruleorder) = 
                       &Apache::lonnet::inst_userrules($dom,'username');
                   my $chgtext = '<ul>';
                   foreach my $type (@username_rule) {
                       if (ref($rules->{$type}) eq 'HASH') {
                           $chgtext .= '<li>'.$rules->{$type}{'name'}.'</li>';
                     }                      }
                 }                  }
                   $chgtext .= '</ul>';
                   if (@username_rule > 0) {
                       $resulttext .= '<li>'.&mt('Usernames with the following formats are restricted to verified users in the institutional directory: ').$chgtext.'</li>';     
                   } else {
                       $resulttext .= '<li>'.&mt('There are now no username formats restricted to verified users in the institutional directory.').'</li>'; 
                   }
               }
               if (ref($changes{'id_rule'}) eq 'ARRAY') {
                   my ($idrules,$idruleorder) = 
                       &Apache::lonnet::inst_userrules($dom,'id');
                   my $chgtext = '<ul>';
                   foreach my $type (@id_rule) {
                       if (ref($idrules->{$type}) eq 'HASH') {
                           $chgtext .= '<li>'.$idrules->{$type}{'name'}.'</li>';
                       }
                   }
                   $chgtext .= '</ul>';
                   if (@id_rule > 0) {
                       $resulttext .= '<li>'.&mt('IDs with the following formats are restricted to verified users in the institutional directory: ').$chgtext.'</li>';
                   } else {
                       $resulttext .= '<li>'.&mt('There are now no ID formats restricted to verified users in the institutional directory.').'</li>';
                   }
             }              }
             if (ref($changes{'email_rule'}) eq 'ARRAY') {              if (ref($changes{'email_rule'}) eq 'ARRAY') {
                 my ($emailrules,$emailruleorder) =                  my ($emailrules,$emailruleorder) =
Line 10352  sub modify_selfcreation { Line 7125  sub modify_selfcreation {
                 }                  }
                 $chgtext .= '</ul>';                  $chgtext .= '</ul>';
                 if (@email_rule > 0) {                  if (@email_rule > 0) {
                     $resulttext .= '<li>'.                      $resulttext .= '<li>'.&mt('Accounts may not be created by users self-enrolling with e-mail addresses of the following types: ').$chgtext.'</li>';
                                    &mt('Accounts may not be created by users self-enrolling with e-mail addresses of the following types: ').  
                                        $chgtext.  
                                    '</li>';  
                 } else {                  } else {
                     $resulttext .= '<li>'.                      $resulttext .= '<li>'.&mt('There are now no restrictions on e-mail addresses which may be used as a username when self-enrolling.').'</li>';
                                    &mt('There are now no restrictions on e-mail addresses which may be used as a username when self-enrolling.').  
                                    '</li>';  
                 }                  }
             }              }
             if (ref($changes{'selfcreate'}) eq 'ARRAY') {  
                 $resulttext .= '<li>'.&mt('When self-creating institutional account:').'<ul>';              my %authname = &authtype_names();
                 my %fieldtitles = &Apache::loncommon::personal_data_fieldtitles();              my %context_title = &context_names();
                 foreach my $type (@{$changes{'selfcreate'}}) {              if (ref($changes{'authtypes'}) eq 'ARRAY') {
                     my $typename = $type;                  my $chgtext = '<ul>';
                     if (ref($usertypes) eq 'HASH') {                  foreach my $type (@{$changes{'authtypes'}}) {
                         if ($usertypes->{$type} ne '') {                      my @allowed;
                             $typename = $usertypes->{$type};                      $chgtext .= '<li><span class="LC_cusr_emph">'.$context_title{$type}.'</span> - '.&mt('assignable authentication types: ');
                         }                      foreach my $auth (@authtypes) {
                     }                          if ($authhash{$type}{$auth}) {
                     my @modifiable;                              push(@allowed,$authname{$auth});
                     $resulttext .= '<li>'.  
                                     &mt('Self-creation of account by users with status: [_1]',  
                                         '<span class="LC_cusr_emph">'.$typename.'</span>').  
                                     ' - '.&mt('modifiable fields (if institutional data blank): ');  
                     foreach my $field (@fields) {  
                         if ($save_usermodify{'selfcreate'}{$type}{$field}) {  
                             push(@modifiable,'<b>'.$fieldtitles{$field}.'</b>');  
                         }                          }
                     }                      }
                     if (@modifiable > 0) {                      if (@allowed > 0) {
                         $resulttext .= join(', ',@modifiable);                          $chgtext .= join(', ',@allowed).'</li>';
                     } else {                      } else {
                         $resulttext .= &mt('none');                          $chgtext .= &mt('none').'</li>';
                     }                      }
                     $resulttext .= '</li>';  
                 }                  }
                 $resulttext .= '</ul></li>';                  $chgtext .= '</ul>';
                   $resulttext .= '<li>'.&mt('Authentication types available for assignment to new users').'<br />'.$chgtext;
                   $resulttext .= '</li>';
             }              }
             $resulttext .= '</ul>';              $resulttext .= '</ul>';
         } else {          } else {
             $resulttext = &mt('No changes made to self-creation settings');              $resulttext = &mt('No changes made to user creation settings');
         }          }
     } else {      } else {
         $resulttext = '<span class="LC_error">'.          $resulttext = '<span class="LC_error">'.
Line 10413  sub process_captcha { Line 7175  sub process_captcha {
         $newsettings->{'captcha'} = 'original';          $newsettings->{'captcha'} = 'original';
     }      }
     if ($current->{'captcha'} ne $newsettings->{'captcha'}) {      if ($current->{'captcha'} ne $newsettings->{'captcha'}) {
         if ($container eq 'cancreate') {          if ($container eq 'cancreate') { 
             if (ref($changes->{'cancreate'}) eq 'ARRAY') {              if (ref($changes->{'cancreate'}) eq 'ARRAY') {
                 push(@{$changes->{'cancreate'}},'captcha');                  push(@{$changes->{'cancreate'}},'captcha');
             } elsif (!defined($changes->{'cancreate'})) {              } elsif (!defined($changes->{'cancreate'})) {
Line 10423  sub process_captcha { Line 7185  sub process_captcha {
             $changes->{'captcha'} = 1;              $changes->{'captcha'} = 1;
         }          }
     }      }
     my ($newpub,$newpriv,$currpub,$currpriv,$newversion,$currversion);      my ($newpub,$newpriv,$currpub,$currpriv);
     if ($newsettings->{'captcha'} eq 'recaptcha') {      if ($newsettings->{'captcha'} eq 'recaptcha') {
         $newpub = $env{'form.'.$container.'_recaptchapub'};          $newpub = $env{'form.'.$container.'_recaptchapub'};
         $newpriv = $env{'form.'.$container.'_recaptchapriv'};          $newpriv = $env{'form.'.$container.'_recaptchapriv'};
         $newpub =~ s/[^\w\-]//g;          $newpub =~ s/\W//g;
         $newpriv =~ s/[^\w\-]//g;          $newpriv =~ s/\W//g;
         $newsettings->{'recaptchakeys'} = {          $newsettings->{'recaptchakeys'} = {
                                              public  => $newpub,                                               public  => $newpub,
                                              private => $newpriv,                                               private => $newpriv,
                                           };                                            };
         $newversion = $env{'form.'.$container.'_recaptchaversion'};  
         $newversion =~ s/\D//g;  
         if ($newversion ne '2') {  
             $newversion = 1;  
         }  
         $newsettings->{'recaptchaversion'} = $newversion;  
     }      }
     if (ref($current->{'recaptchakeys'}) eq 'HASH') {      if (ref($current->{'recaptchakeys'}) eq 'HASH') {
         $currpub = $current->{'recaptchakeys'}{'public'};          $currpub = $current->{'recaptchakeys'}{'public'};
Line 10450  sub process_captcha { Line 7206  sub process_captcha {
                                               }                                                }
         }          }
     }      }
     if ($current->{'captcha'} eq 'recaptcha') {  
         $currversion = $current->{'recaptchaversion'};  
         if ($currversion ne '2') {  
             $currversion = 1;  
         }  
     }  
     if ($currversion ne $newversion) {  
         if ($container eq 'cancreate') {  
             if (ref($changes->{'cancreate'}) eq 'ARRAY') {  
                 push(@{$changes->{'cancreate'}},'recaptchaversion');  
             } elsif (!defined($changes->{'cancreate'})) {  
                 $changes->{'cancreate'} = ['recaptchaversion'];  
             }  
         } else {  
             $changes->{'recaptchaversion'} = 1;  
         }  
     }  
     if (($newpub ne $currpub) || ($newpriv ne $currpriv)) {      if (($newpub ne $currpub) || ($newpriv ne $currpriv)) {
         if ($container eq 'cancreate') {          if ($container eq 'cancreate') {
             if (ref($changes->{'cancreate'}) eq 'ARRAY') {              if (ref($changes->{'cancreate'}) eq 'ARRAY') {
Line 10475  sub process_captcha { Line 7214  sub process_captcha {
                 $changes->{'cancreate'} = ['recaptchakeys'];                  $changes->{'cancreate'} = ['recaptchakeys'];
             }              }
         } else {          } else {
             $changes->{'recaptchakeys'} = 1;              $changes->{'recaptchakeys'} = 1; 
         }          }
     }      }
     return;      return;
Line 10483  sub process_captcha { Line 7222  sub process_captcha {
   
 sub modify_usermodification {  sub modify_usermodification {
     my ($dom,%domconfig) = @_;      my ($dom,%domconfig) = @_;
     my ($resulttext,%curr_usermodification,%changes,%modifyhash);      my ($resulttext,%curr_usermodification,%changes);
     if (ref($domconfig{'usermodification'}) eq 'HASH') {      if (ref($domconfig{'usermodification'}) eq 'HASH') {
         foreach my $key (keys(%{$domconfig{'usermodification'}})) {          foreach my $key (keys(%{$domconfig{'usermodification'}})) {
             if ($key eq 'selfcreate') {              $curr_usermodification{$key} = $domconfig{'usermodification'}{$key};
                 $modifyhash{$key} = $domconfig{'usermodification'}{$key};  
             } else {    
                 $curr_usermodification{$key} = $domconfig{'usermodification'}{$key};  
             }  
         }          }
     }      }
     my @contexts = ('author','course');      my @contexts = ('author','course','selfcreate');
     my %context_title = (      my %context_title = (
                            author => 'In author context',                             author => 'In author context',
                            course => 'In course context',                             course => 'In course context',
                              selfcreate => 'When self creating account', 
                         );                          );
     my @fields = ('lastname','firstname','middlename','generation',      my @fields = ('lastname','firstname','middlename','generation',
                   'permanentemail','id');                    'permanentemail','id');
Line 10504  sub modify_usermodification { Line 7240  sub modify_usermodification {
                   author => ['ca','aa'],                    author => ['ca','aa'],
                   course => ['st','ep','ta','in','cr'],                    course => ['st','ep','ta','in','cr'],
                 );                  );
       my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom);
       if (ref($types) eq 'ARRAY') {
           push(@{$types},'default');
           $usertypes->{'default'} = $othertitle;
       }
       $roles{'selfcreate'} = $types;  
     my %fieldtitles = &Apache::loncommon::personal_data_fieldtitles();      my %fieldtitles = &Apache::loncommon::personal_data_fieldtitles();
       my %modifyhash;
     foreach my $context (@contexts) {      foreach my $context (@contexts) {
         foreach my $role (@{$roles{$context}}) {          foreach my $role (@{$roles{$context}}) {
             my @modifiable =  &Apache::loncommon::get_env_multiple('form.canmodify_'.$role);              my @modifiable =  &Apache::loncommon::get_env_multiple('form.canmodify_'.$role);
Line 10550  sub modify_usermodification { Line 7293  sub modify_usermodification {
                     if (ref($changes{$context}) eq 'ARRAY') {                      if (ref($changes{$context}) eq 'ARRAY') {
                         foreach my $role (@{$changes{$context}}) {                          foreach my $role (@{$changes{$context}}) {
                             my $rolename;                              my $rolename;
                             if ($role eq 'cr') {                              if ($context eq 'selfcreate') {
                                 $rolename = &mt('Custom');                                  $rolename = $role;
                                   if (ref($usertypes) eq 'HASH') {
                                       if ($usertypes->{$role} ne '') {
                                           $rolename = $usertypes->{$role};
                                       }
                                   }
                             } else {                              } else {
                                 $rolename = &Apache::lonnet::plaintext($role);                                  if ($role eq 'cr') {
                                       $rolename = &mt('Custom');
                                   } else {
                                       $rolename = &Apache::lonnet::plaintext($role);
                                   }
                             }                              }
                             my @modifiable;                              my @modifiable;
                             $resulttext .= '<li><span class="LC_cusr_emph">'.&mt('Target user with [_1] role',$rolename).'</span> - '.&mt('modifiable fields: ');                              if ($context eq 'selfcreate') {
                                   $resulttext .= '<li><span class="LC_cusr_emph">'.&mt('Self-creation of account by users with status: [_1]',$rolename).'</span> - '.&mt('modifiable fields (if institutional data blank): ');
                               } else {
                                   $resulttext .= '<li><span class="LC_cusr_emph">'.&mt('Target user with [_1] role',$rolename).'</span> - '.&mt('modifiable fields: ');
                               }
                             foreach my $field (@fields) {                              foreach my $field (@fields) {
                                 if ($modifyhash{$context}{$role}{$field}) {                                  if ($modifyhash{$context}{$role}{$field}) {
                                     push(@modifiable,$fieldtitles{$field});                                      push(@modifiable,$fieldtitles{$field});
Line 10585  sub modify_usermodification { Line 7341  sub modify_usermodification {
 }  }
   
 sub modify_defaults {  sub modify_defaults {
     my ($dom,$lastactref,%domconfig) = @_;      my ($dom,$r) = @_;
     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);
     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 10631  sub modify_defaults { Line 7386  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 10661  sub modify_defaults { Line 7398  sub modify_defaults {
                          defaults => \%newvalues,                           defaults => \%newvalues,
                         );                          );
     my $title = &defaults_titles();      my $title = &defaults_titles();
   
     my $currinststatus;  
     if (ref($domconfig{'inststatus'}) eq 'HASH') {  
         $currinststatus = $domconfig{'inststatus'};  
     } else {  
         my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom);  
         $currinststatus = {  
                              inststatustypes => $usertypes,  
                              inststatusorder => $types,  
                              inststatusguest => [],  
                           };  
     }  
     my @todelete = &Apache::loncommon::get_env_multiple('form.inststatus_delete');  
     my @allpos;  
     my %guests;  
     my %alltypes;  
     my ($currtitles,$currguests,$currorder);  
     if (ref($currinststatus) eq 'HASH') {  
         if (ref($currinststatus->{'inststatusorder'}) eq 'ARRAY') {  
             foreach my $type (@{$currinststatus->{'inststatusorder'}}) {  
                 if (ref($currinststatus->{inststatustypes}) eq 'HASH') {  
                     if ($currinststatus->{inststatustypes}->{$type} ne '') {  
                         $currtitles .= $currinststatus->{inststatustypes}->{$type}.',';  
                     }  
                 }  
                 unless (grep(/^\Q$type\E$/,@todelete)) {   
                     my $position = $env{'form.inststatus_pos_'.$type};  
                     $position =~ s/\D+//g;  
                     $allpos[$position] = $type;  
                     $alltypes{$type} = $env{'form.inststatus_title_'.$type};  
                     $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'}});  
             $currtitles =~ s/,$//;  
         }  
     }  
     if ($env{'form.addinststatus'}) {  
         my $newtype = $env{'form.addinststatus'};  
         $newtype =~ s/\W//g;  
         unless (exists($alltypes{$newtype})) {  
             if ($env{'form.addinststatus_guest'}) {  
                 $guests{$newtype} = 1;  
             }  
             $alltypes{$newtype} = $env{'form.addinststatus_title'};  
             $alltypes{$newtype} =~ s/`//g;   
             my $position = $env{'form.addinststatus_pos'};  
             $position =~ s/\D+//g;  
             if ($position ne '') {  
                 $allpos[$position] = $newtype;  
             }  
         }  
     }  
     my (@orderedstatus,@orderedguests);  
     foreach my $type (@allpos) {  
         unless (($type eq '') || (grep(/^\Q$type\E$/,@orderedstatus))) {  
             push(@orderedstatus,$type);  
             if ($guests{$type}) {  
                 push(@orderedguests,$type);  
             }  
         }  
     }  
     foreach my $type (keys(%alltypes)) {  
         unless (grep(/^\Q$type\E$/,@orderedstatus)) {  
             delete($alltypes{$type});  
         }  
     }  
     $defaults_hash{'inststatus'} = {  
                                      inststatustypes => \%alltypes,  
                                      inststatusorder => \@orderedstatus,  
                                      inststatusguest => \@orderedguests,  
                                    };  
     if (ref($defaults_hash{'inststatus'}) eq 'HASH') {  
         foreach my $item ('inststatustypes','inststatusorder','inststatusguest') {  
             $domdefaults{$item} = $defaults_hash{'inststatus'}{$item};  
         }  
     }  
     if ($currorder ne join(',',@orderedstatus)) {  
         $changes{'inststatus'}{'inststatusorder'} = 1;  
     }  
     if ($currguests ne join(',',@orderedguests)) {  
         $changes{'inststatus'}{'inststatusguest'} = 1;  
     }  
     my $newtitles;  
     foreach my $item (@orderedstatus) {  
         $newtitles .= $alltypes{$item}.',';  
     }  
     $newtitles =~ s/,$//;  
     if ($currtitles ne $newtitles) {  
         $changes{'inststatus'}{'inststatustypes'} = 1;  
     }  
     my $putresult = &Apache::lonnet::put_dom('configuration',\%defaults_hash,      my $putresult = &Apache::lonnet::put_dom('configuration',\%defaults_hash,
                                              $dom);                                               $dom);
     if ($putresult eq 'ok') {      if ($putresult eq 'ok') {
         if (keys(%changes) > 0) {          if (keys(%changes) > 0) {
             $resulttext = &mt('Changes made:').'<ul>';              $resulttext = &mt('Changes made:').'<ul>';
             my $version = &Apache::lonnet::get_server_loncaparev($dom);              my $version = $r->dir_config('lonVersion');
             my $mailmsgtext = "Changes made to domain settings in a LON-CAPA installation - domain: $dom (running version: $version) - dns_domain.tab needs to be updated with the following changes, to support legacy 2.4, 2.5 and 2.6 versions of LON-CAPA.\n\n";              my $mailmsgtext = "Changes made to domain settings in a LON-CAPA installation - domain: $dom (running version: $version) - dns_domain.tab needs to be updated with the following changes, to support legacy 2.4, 2.5 and 2.6 versions of LON-CAPA.\n\n";
             foreach my $item (sort(keys(%changes))) {              foreach my $item (sort(keys(%changes))) {
                 if ($item eq 'inststatus') {                  my $value = $env{'form.'.$item};
                     if (ref($changes{'inststatus'}) eq 'HASH') {                  if ($value eq '') {
                         if (($changes{'inststatus'}{'inststatustypes'}) || $changes{'inststatus'}{'inststatusorder'}) {                      $value = &mt('none');
                             $resulttext .= '<li>'.&mt('Institutional user status types set to:').' ';                  } elsif ($item eq 'auth_def') {
                             foreach my $type (@orderedstatus) {                       my %authnames = &authtype_names();
                                 $resulttext .= $alltypes{$type}.', ';                      my %shortauth = (
                             }                               internal => 'int',
                             $resulttext =~ s/, $//;                               krb4 => 'krb4',
                             $resulttext .= '</li>';                               krb5 => 'krb5',
                         }                               localauth  => 'loc',
                         if ($changes{'inststatus'}{'inststatusguest'}) {                      );
                             $resulttext .= '<li>';                       $value = $authnames{$shortauth{$value}};
                             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 {  
                     my $value = $env{'form.'.$item};  
                     if ($value eq '') {  
                         $value = &mt('none');  
                     } elsif ($item eq 'auth_def') {  
                         my %authnames = &authtype_names();  
                         my %shortauth = (  
                                           internal   => 'int',  
                                           krb4       => 'krb4',  
                                           krb5       => 'krb5',  
                                           localauth  => 'loc',  
                         );  
                         $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>';  
                     $mailmsgtext .= "$title->{$item} set to $value\n";    
                 }                  }
                   $resulttext .= '<li>'.&mt('[_1] set to "[_2]"',$title->{$item},$value).'</li>';
                   $mailmsgtext .= "$title->{$item} set to $value\n";  
             }              }
             $resulttext .= '</ul>';              $resulttext .= '</ul>';
             $mailmsgtext .= "\n";              $mailmsgtext .= "\n";
             my $cachetime = 24*60*60;              my $cachetime = 24*60*60;
             &Apache::lonnet::do_cache_new('domdefaults',$dom,\%domdefaults,$cachetime);              &Apache::lonnet::do_cache_new('domdefaults',$dom,\%domdefaults,$cachetime);
             if (ref($lastactref) eq 'HASH') {  
                 $lastactref->{'domdefaults'} = 1;  
             }  
             if ($changes{'auth_def'} || $changes{'auth_arg_def'} || $changes{'lang_def'} || $changes{'datelocale_def'}) {              if ($changes{'auth_def'} || $changes{'auth_arg_def'} || $changes{'lang_def'} || $changes{'datelocale_def'}) {
                 my $notify = 1;                  my $sysmail = $r->dir_config('lonSysEMail');
                 if (ref($domconfig{'contacts'}) eq 'HASH') {                  &Apache::lonmsg::sendemail($sysmail,"LON-CAPA Domain Settings Change - $dom",$mailmsgtext);
                     if ($domconfig{'contacts'}{'reportupdates'} == 0) {  
                         $notify = 0;  
                     }  
                 }  
                 if ($notify) {  
                     &Apache::lonmsg::sendemail('installrecord@loncapa.org',  
                                                "LON-CAPA Domain Settings Change - $dom",  
                                                $mailmsgtext);  
                 }  
             }              }
         } else {          } else {
             $resulttext = &mt('No changes made to default authentication/language/timezone settings');              $resulttext = &mt('No changes made to default authentication/language/timezone settings');
Line 10868  sub modify_defaults { Line 7448  sub modify_defaults {
 }  }
   
 sub modify_scantron {  sub modify_scantron {
     my ($r,$dom,$confname,$lastactref,%domconfig) = @_;      my ($r,$dom,$confname,%domconfig) = @_;
     my ($resulttext,%confhash,%changes,$errors);      my ($resulttext,%confhash,%changes,$errors);
     my $custom = 'custom.tab';      my $custom = 'custom.tab';
     my $default = 'default.tab';      my $default = 'default.tab';
Line 10929  sub modify_scantron { Line 7509  sub modify_scantron {
                 }                  }
                 $resulttext .= '</ul>';                  $resulttext .= '</ul>';
                 &Apache::loncommon::devalidate_domconfig_cache($dom);                  &Apache::loncommon::devalidate_domconfig_cache($dom);
                 if (ref($lastactref) eq 'HASH') {  
                     $lastactref->{'domainconfig'} = 1;  
                 }  
             } else {              } else {
                 $resulttext = &mt('No changes made to bubblesheet format file');                  $resulttext = &mt('No changes made to bubblesheet format file');
             }              }
Line 10950  sub modify_scantron { Line 7527  sub modify_scantron {
 }  }
   
 sub modify_coursecategories {  sub modify_coursecategories {
     my ($dom,$lastactref,%domconfig) = @_;      my ($dom,%domconfig) = @_;
     my ($resulttext,%deletions,%reorderings,%needreordering,%adds,%changes,$errors,      my ($resulttext,%deletions,%reorderings,%needreordering,%adds,%changes,$errors,
         $cathash);          $cathash);
     my @deletecategory = &Apache::loncommon::get_env_multiple('form.deletecategory');      my @deletecategory = &Apache::loncommon::get_env_multiple('form.deletecategory');
     my @catitems = ('unauth','auth');  
     my @cattypes = ('std','domonly','codesrch','none');  
     if (ref($domconfig{'coursecategories'}) eq 'HASH') {      if (ref($domconfig{'coursecategories'}) eq 'HASH') {
         $cathash = $domconfig{'coursecategories'}{'cats'};          $cathash = $domconfig{'coursecategories'}{'cats'};
         if ($domconfig{'coursecategories'}{'togglecats'} ne $env{'form.togglecats'}) {          if ($domconfig{'coursecategories'}{'togglecats'} ne $env{'form.togglecats'}) {
Line 10974  sub modify_coursecategories { Line 7549  sub modify_coursecategories {
             $changes{'categorizecomm'} = 1;              $changes{'categorizecomm'} = 1;
             $domconfig{'coursecategories'}{'categorizecomm'} = $env{'form.categorizecomm'};              $domconfig{'coursecategories'}{'categorizecomm'} = $env{'form.categorizecomm'};
         }          }
         foreach my $item (@catitems) {  
             if (grep(/^\Q$env{'form.coursecat_'.$item}\E$/,@cattypes)) {  
                 if ($domconfig{'coursecategories'}{$item} ne $env{'form.coursecat_'.$item}) {  
                     $changes{$item} = 1;  
                     $domconfig{'coursecategories'}{$item} = $env{'form.coursecat_'.$item};  
                 }  
             }  
         }  
     } else {      } else {
         $changes{'togglecats'} = 1;          $changes{'togglecats'} = 1;
         $changes{'categorize'} = 1;          $changes{'categorize'} = 1;
Line 10993  sub modify_coursecategories { Line 7560  sub modify_coursecategories {
                                              togglecatscomm => $env{'form.togglecatscomm'},                                               togglecatscomm => $env{'form.togglecatscomm'},
                                              categorizecomm => $env{'form.categorizecomm'},                                               categorizecomm => $env{'form.categorizecomm'},
                                          };                                           };
         foreach my $item (@catitems) {  
             if ($env{'form.coursecat_'.$item} ne 'std') {  
                 $changes{$item} = 1;  
             }  
             if (grep(/^\Q$env{'form.coursecat_'.$item}\E$/,@cattypes)) {  
                 $domconfig{'coursecategories'}{$item} = $env{'form.coursecat_'.$item};  
             }  
         }  
     }      }
     if (ref($cathash) eq 'HASH') {      if (ref($cathash) eq 'HASH') {
         if (($domconfig{'coursecategories'}{'cats'}{'instcode::0'} ne '')  && ($env{'form.instcode'} == 0)) {          if (($domconfig{'coursecategories'}{'cats'}{'instcode::0'} ne '')  && ($env{'form.instcode'} == 0)) {
Line 11123  sub modify_coursecategories { Line 7682  sub modify_coursecategories {
                          dom  => 'set in Domain ("Modify Course/Community")',                           dom  => 'set in Domain ("Modify Course/Community")',
                          crs  => 'set in Course ("Course Configuration")',                           crs  => 'set in Course ("Course Configuration")',
                          comm => 'set in Community ("Community Configuration")',                           comm => 'set in Community ("Community Configuration")',
                          none     => 'No catalog',  
                          std      => 'Standard catalog',  
                          domonly  => 'Domain-only catalog',  
                          codesrch => 'Code search form',  
                         );                          );
             $resulttext = &mt('Changes made:').'<ul>';              $resulttext = &mt('Changes made:').'<ul>';
             if ($changes{'togglecats'}) {              if ($changes{'togglecats'}) {
Line 11141  sub modify_coursecategories { Line 7696  sub modify_coursecategories {
             if ($changes{'categorizecomm'}) {              if ($changes{'categorizecomm'}) {
                 $resulttext .= '<li>'.&mt("$title{'categorizecomm'} $level{$env{'form.categorizecomm'}}").'</li>';                  $resulttext .= '<li>'.&mt("$title{'categorizecomm'} $level{$env{'form.categorizecomm'}}").'</li>';
             }              }
             if ($changes{'unauth'}) {  
                 $resulttext .= '<li>'.&mt('Catalog type for unauthenticated users set to "'.$level{$env{'form.coursecat_unauth'}}.'"').'</li>';  
             }  
             if ($changes{'auth'}) {  
                 $resulttext .= '<li>'.&mt('Catalog type for authenticated users set to "'.$level{$env{'form.coursecat_auth'}}.'"').'</li>';  
             }  
             if ((keys(%deletions) > 0) || (keys(%reorderings) > 0) || (keys(%adds) > 0)) {              if ((keys(%deletions) > 0) || (keys(%reorderings) > 0) || (keys(%adds) > 0)) {
                 my $cathash;                  my $cathash;
                 if (ref($domconfig{'coursecategories'}) eq 'HASH') {                  if (ref($domconfig{'coursecategories'}) eq 'HASH') {
Line 11191  sub modify_coursecategories { Line 7740  sub modify_coursecategories {
                 }                  }
             }              }
             $resulttext .= '</ul>';              $resulttext .= '</ul>';
             if ($changes{'unauth'} || $changes{'auth'}) {  
                 my %domdefaults = &Apache::lonnet::get_domain_defaults($dom);  
                 if ($changes{'auth'}) {  
                     $domdefaults{'catauth'} = $domconfig{'coursecategories'}{'auth'};  
                 }  
                 if ($changes{'unauth'}) {  
                     $domdefaults{'catunauth'} = $domconfig{'coursecategories'}{'unauth'};  
                 }  
                 my $cachetime = 24*60*60;  
                 &Apache::lonnet::do_cache_new('domdefaults',$dom,\%domdefaults,$cachetime);  
                 if (ref($lastactref) eq 'HASH') {  
                     $lastactref->{'domdefaults'} = 1;  
                 }  
             }  
         } else {          } else {
             $resulttext = '<span class="LC_error">'.              $resulttext = '<span class="LC_error">'.
                           &mt('An error occurred: [_1]',$putresult).'</span>';                            &mt('An error occurred: [_1]',$putresult).'</span>';
Line 11340  sub modify_serverstatuses { Line 7875  sub modify_serverstatuses {
 }  }
   
 sub modify_helpsettings {  sub modify_helpsettings {
     my ($r,$dom,$confname,$lastactref,%domconfig) = @_;      my ($r,$dom,$confname,%domconfig) = @_;
     my ($resulttext,$errors,%changes,%helphash);      my ($resulttext,$errors,%changes,%helphash);
     my %defaultchecked = ('submitbugs' => 'on');      my %defaultchecked = ('submitbugs' => 'on');
     my @offon = ('off','on');      my @offon = ('off','on');
     my @toggles = ('submitbugs');      my @toggles = ('submitbugs');
     my %current = ('submitbugs' => '',  
                    'adhoc'      => {},  
                   );  
     if (ref($domconfig{'helpsettings'}) eq 'HASH') {      if (ref($domconfig{'helpsettings'}) eq 'HASH') {
         %current = %{$domconfig{'helpsettings'}};          foreach my $item (@toggles) {
     }              if ($defaultchecked{$item} eq 'on') { 
     my %domdefaults = &Apache::lonnet::get_domain_defaults($dom,1);                  if ($domconfig{'helpsettings'}{$item} eq '') {
     foreach my $item (@toggles) {                      if ($env{'form.'.$item} eq '0') {
         if ($defaultchecked{$item} eq 'on') {                           $changes{$item} = 1;
             if ($current{$item} eq '') {  
                 if ($env{'form.'.$item} eq '0') {  
                     $changes{$item} = 1;  
                 }  
             } elsif ($current{$item} ne $env{'form.'.$item}) {  
                 $changes{$item} = 1;  
             }  
         } elsif ($defaultchecked{$item} eq 'off') {  
             if ($current{$item} eq '') {  
                 if ($env{'form.'.$item} eq '1') {  
                     $changes{$item} = 1;  
                 }  
             } elsif ($current{$item} ne $env{'form.'.$item}) {  
                 $changes{$item} = 1;  
             }  
         }  
         if (($env{'form.'.$item} eq '0') || ($env{'form.'.$item} eq '1')) {  
             $helphash{'helpsettings'}{$item} = $env{'form.'.$item};  
         }  
     }  
     my $maxnum = $env{'form.helproles_maxnum'};  
     my $confname = $dom.'-domainconfig';  
     my %existing=&Apache::lonnet::dump('roles',$dom,$confname,'rolesdef_');  
     my (@allpos,%newsettings,%changedprivs,$newrole);  
     my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom);  
     my @accesstypes = ('all','dh','da','none','status','inc','exc');  
     my %domhelpdesk = &Apache::lonnet::get_active_domroles($dom,['dh','da']);  
     my %lt = &Apache::lonlocal::texthash(  
                     s      => 'system',  
                     d      => 'domain',  
                     order  => 'Display order',  
                     access => 'Role usage',  
                     all    => 'All with domain helpdesk or helpdesk assistant role',  
                     dh     => 'All with domain helpdesk role',  
                     da     => 'All with domain helpdesk assistant role',  
                     none   => 'None',  
                     status => 'Determined based on institutional status',  
                     inc    => 'Include all, but exclude specific personnel',  
                     exc    => 'Exclude all, but include specific personnel',  
     );  
     for (my $num=0; $num<=$maxnum; $num++) {  
         my ($prefix,$identifier,$rolename,%curr);  
         if ($num == $maxnum) {  
             next unless ($env{'form.newcusthelp'} == $maxnum);  
             $identifier = 'custhelp'.$num;  
             $prefix = 'helproles_'.$num;  
             $rolename = $env{'form.custhelpname'.$num};  
             $rolename=~s/[^A-Za-z0-9]//gs;  
             next if ($rolename eq '');  
             next if (exists($existing{'rolesdef_'.$rolename}));  
             my %newprivs = &Apache::lonuserutils::custom_role_update($rolename,$identifier);  
             my $result = &Apache::lonnet::definerole($rolename,$newprivs{'s'},$newprivs{'d'},  
                                                      $newprivs{'c'},$confname,$dom);  
             if ($result ne 'ok') {  
                 $errors .= '<li><span class="LC_error">'.  
                            &mt('An error occurred storing the new custom role: [_1]',  
                            $result).'</span></li>';  
                 next;  
             } else {  
                 $changedprivs{$rolename} = \%newprivs;  
                 $newrole = $rolename;  
             }  
         } else {  
             $prefix = 'helproles_'.$num;  
             $rolename = $env{'form.'.$prefix};  
             next if ($rolename eq '');  
             next unless (exists($existing{'rolesdef_'.$rolename}));  
             $identifier = 'custhelp'.$num;  
             my %newprivs = &Apache::lonuserutils::custom_role_update($rolename,$identifier);  
             my %currprivs;  
             ($currprivs{'s'},$currprivs{'d'},$currprivs{'c'}) =  
                 split(/\_/,$existing{'rolesdef_'.$rolename});  
             foreach my $level ('c','d','s') {  
                 if ($newprivs{$level} ne $currprivs{$level}) {  
                     my $result = &Apache::lonnet::definerole($rolename,$newprivs{'s'},$newprivs{'d'},  
                                                              $newprivs{'c'},$confname,$dom);  
                     if ($result ne 'ok') {  
                         $errors .= '<li><span class="LC_error">'.  
                                    &mt('An error occurred storing privileges for existing role [_1]: [_2]',  
                                        $rolename,$result).'</span></li>';  
                     } else {  
                         $changedprivs{$rolename} = \%newprivs;  
                     }  
                     last;  
                 }  
             }  
             if (ref($current{'adhoc'}) eq 'HASH') {  
                 if (ref($current{'adhoc'}{$rolename}) eq 'HASH') {  
                     %curr = %{$current{'adhoc'}{$rolename}};  
                 }  
             }  
         }  
         my $newpos = $env{'form.'.$prefix.'_pos'};  
         $newpos =~ s/\D+//g;  
         $allpos[$newpos] = $rolename;  
         my $newdesc = $env{'form.'.$prefix.'_desc'};  
         $helphash{'helpsettings'}{'adhoc'}{$rolename}{'desc'} = $newdesc;  
         if ($curr{'desc'}) {  
             if ($curr{'desc'} ne $newdesc) {  
                 $changes{'customrole'}{$rolename}{'desc'} = 1;  
                 $newsettings{$rolename}{'desc'} = $newdesc;  
             }  
         } elsif ($newdesc ne '') {  
             $changes{'customrole'}{$rolename}{'desc'} = 1;  
             $newsettings{$rolename}{'desc'} = $newdesc;  
         }  
         my $access = $env{'form.'.$prefix.'_access'};  
         if (grep(/^\Q$access\E$/,@accesstypes)) {  
             $helphash{'helpsettings'}{'adhoc'}{$rolename}{'access'} = $access;  
             if ($access eq 'status') {  
                 my @statuses = &Apache::loncommon::get_env_multiple('form.'.$prefix.'_status');  
                 if (scalar(@statuses) == 0) {  
                     $helphash{'helpsettings'}{'adhoc'}{$rolename}{'access'} = 'none';  
                 } else {  
                     my (@shownstatus,$numtypes);  
                     $helphash{'helpsettings'}{'adhoc'}{$rolename}{$access} = [];  
                     if (ref($types) eq 'ARRAY') {  
                         $numtypes = scalar(@{$types});  
                         foreach my $type (sort(@statuses)) {  
                             if ($type eq 'default') {  
                                 push(@{$helphash{'helpsettings'}{'adhoc'}{$rolename}{$access}},$type);  
                             } elsif (grep(/^\Q$type\E$/,@{$types})) {  
                                 push(@{$helphash{'helpsettings'}{'adhoc'}{$rolename}{$access}},$type);  
                                 push(@shownstatus,$usertypes->{$type});  
                             }  
                         }  
                     }  
                     if (grep(/^default$/,@statuses)) {  
                         push(@shownstatus,$othertitle);  
                     }  
                     if (scalar(@shownstatus) == 1+$numtypes) {  
                         $helphash{'helpsettings'}{'adhoc'}{$rolename}{'access'} = 'all';  
                         delete($helphash{'helpsettings'}{'adhoc'}{$rolename}{'status'});  
                     } else {  
                         $newsettings{$rolename}{'status'} = join(' '.&mt('or').' ',@shownstatus);  
                         if (ref($curr{'status'}) eq 'ARRAY') {  
                             my @diffs = &Apache::loncommon::compare_arrays($helphash{'helpsettings'}{'adhoc'}{$rolename}{$access},$curr{$access});  
                             if (@diffs) {  
                                 $changes{'customrole'}{$rolename}{$access} = 1;  
                             }  
                         } elsif (@{$helphash{'helpsettings'}{'adhoc'}{$rolename}{$access}}) {  
                             $changes{'customrole'}{$rolename}{$access} = 1;  
                         }  
                     }  
                 }  
             } elsif (($access eq 'inc') || ($access eq 'exc')) {  
                 my @personnel = &Apache::loncommon::get_env_multiple('form.'.$prefix.'_staff_'.$access);  
                 my @newspecstaff;  
                 $helphash{'helpsettings'}{'adhoc'}{$rolename}{$access} = [];  
                 foreach my $person (sort(@personnel)) {  
                     if ($domhelpdesk{$person}) {  
                         push(@{$helphash{'helpsettings'}{'adhoc'}{$rolename}{$access}},$person);  
                     }                      }
                   } elsif ($domconfig{'helpsettings'}{$item} ne $env{'form.'.$item}) {
                       $changes{$item} = 1;
                 }                  }
                 if (ref($curr{$access}) eq 'ARRAY') {              } elsif ($defaultchecked{$item} eq 'off') {
                     my @diffs = &Apache::loncommon::compare_arrays($helphash{'helpsettings'}{'adhoc'}{$rolename}{$access},$curr{$access});                  if ($domconfig{'helpsettings'}{$item} eq '') {
                     if (@diffs) {                      if ($env{'form.'.$item} eq '1') {
                         $changes{'customrole'}{$rolename}{$access} = 1;                          $changes{$item} = 1;
                     }                      }
                 } elsif (@{$helphash{'helpsettings'}{'adhoc'}{$rolename}{$access}}) {                  } elsif ($domconfig{'helpsettings'}{$item} ne $env{'form.'.$item}) {
                     $changes{'customrole'}{$rolename}{$access} = 1;                      $changes{$item} = 1;
                 }  
                 foreach my $person (@{$helphash{'helpsettings'}{'adhoc'}{$rolename}{$access}}) {  
                     my ($uname,$udom) = split(/:/,$person);  
                         push(@newspecstaff,&Apache::loncommon::aboutmewrapper(&Apache::loncommon::plainname($uname,$udom,'lastname'),$uname,$udom));  
                 }                  }
                 $newsettings{$rolename}{$access} = join(', ',sort(@newspecstaff));  
             }              }
         } else {              if (($env{'form.'.$item} eq '0') || ($env{'form.'.$item} eq '1')) { 
             $helphash{'helpsettings'}{'adhoc'}{$rolename}{'access'}= 'all';                  $helphash{'helpsettings'}{$item} = $env{'form.'.$item};
         }  
         unless ($curr{'access'} eq $access) {  
             $changes{'customrole'}{$rolename}{'access'} = 1;  
             $newsettings{$rolename}{'access'} = $lt{$helphash{'helpsettings'}{'adhoc'}{$rolename}{'access'}};  
         }  
     }  
     if (@allpos > 0) {  
         my $idx = 0;  
         foreach my $rolename (@allpos) {  
             if ($rolename ne '') {  
                 $helphash{'helpsettings'}{'adhoc'}{$rolename}{'order'} = $idx;  
                 if (ref($current{'adhoc'}) eq 'HASH') {  
                     if (ref($current{'adhoc'}{$rolename}) eq 'HASH') {  
                         if ($current{'adhoc'}{$rolename}{'order'} ne $idx) {  
                             $changes{'customrole'}{$rolename}{'order'} = 1;  
                             $newsettings{$rolename}{'order'} = $idx+1;  
                         }  
                     }  
                 }  
                 $idx ++;  
             }              }
         }          }
     }      }
Line 11551  sub modify_helpsettings { Line 7908  sub modify_helpsettings {
     if (keys(%changes) > 0) {      if (keys(%changes) > 0) {
         $putresult = &Apache::lonnet::put_dom('configuration',\%helphash,$dom);          $putresult = &Apache::lonnet::put_dom('configuration',\%helphash,$dom);
         if ($putresult eq 'ok') {          if ($putresult eq 'ok') {
             if (ref($helphash{'helpsettings'}) eq 'HASH') {              $resulttext = &mt('Changes made:').'<ul>';
                 $domdefaults{'submitbugs'} = $helphash{'helpsettings'}{'submitbugs'};  
                 if (ref($helphash{'helpsettings'}{'adhoc'}) eq 'HASH') {  
                     $domdefaults{'adhocroles'} = $helphash{'helpsettings'}{'adhoc'};  
                 }  
             }  
             my $cachetime = 24*60*60;  
             &Apache::lonnet::do_cache_new('domdefaults',$dom,\%domdefaults,$cachetime);  
             if (ref($lastactref) eq 'HASH') {  
                 $lastactref->{'domdefaults'} = 1;  
             }  
         } else {  
             $errors .= '<li><span class="LC_error">'.  
                        &mt('An error occurred storing the settings: [_1]',  
                            $putresult).'</span></li>';  
         }  
     }  
     if ((keys(%changes) && ($putresult eq 'ok')) || (keys(%changedprivs))) {  
         $resulttext = &mt('Changes made:').'<ul>';  
         my (%shownprivs,@levelorder);  
         @levelorder = ('c','d','s');  
         if ((keys(%changes)) && ($putresult eq 'ok')) {  
             foreach my $item (sort(keys(%changes))) {              foreach my $item (sort(keys(%changes))) {
                 if ($item eq 'submitbugs') {                  if ($item eq 'submitbugs') {
                     $resulttext .= '<li>'.&mt('Display link to: [_1] set to "'.$offon[$env{'form.'.$item}].'".',                      $resulttext .= '<li>'.&mt('Display link to: [_1] set to "'.$offon[$env{'form.'.$item}].'".',
                                               &Apache::loncommon::modal_link('http://bugs.loncapa.org',                                                &Apache::loncommon::modal_link('http://bugs.loncapa.org',
                                               &mt('LON-CAPA bug tracker'),600,500)).'</li>';                                                &mt('LON-CAPA bug tracker'),600,500)).'</li>';
                 } elsif ($item eq 'customrole') {  
                     if (ref($changes{'customrole'}) eq 'HASH') {  
                         my @keyorder = ('order','desc','access','status','exc','inc');  
                         my %keytext = &Apache::lonlocal::texthash(  
                                                                    order  => 'Order',  
                                                                    desc   => 'Role description',  
                                                                    access => 'Role usage',  
                                                                    status => 'Allowed institutional types',  
                                                                    exc    => 'Allowed personnel',  
                                                                    inc    => 'Disallowed personnel',  
                         );  
                         foreach my $role (sort(keys(%{$changes{'customrole'}}))) {  
                             if (ref($changes{'customrole'}{$role}) eq 'HASH') {  
                                 if ($role eq $newrole) {  
                                     $resulttext .= '<li>'.&mt('New custom role added: [_1]',  
                                                               $role).'<ul>';  
                                 } else {  
                                     $resulttext .= '<li>'.&mt('Existing custom role modified: [_1]',  
                                                               $role).'<ul>';  
                                 }  
                                 foreach my $key (@keyorder) {  
                                     if ($changes{'customrole'}{$role}{$key}) {  
                                         $resulttext .= '<li>'.&mt("[_1] set to: [_2]",  
                                                                   $keytext{$key},$newsettings{$role}{$key}).  
                                                        '</li>';  
                                     }  
                                 }  
                                 if (ref($changedprivs{$role}) eq 'HASH') {  
                                     $shownprivs{$role} = 1;  
                                     $resulttext .= '<li>'.&mt('Privileges set to :').'<ul>';  
                                     foreach my $level (@levelorder) {  
                                         foreach my $item (split(/\:/,$changedprivs{$role}{$level})) {  
                                             next if ($item eq '');  
                                             my ($priv) = split(/\&/,$item,2);  
                                             if (&Apache::lonnet::plaintext($priv)) {  
                                                 $resulttext .= '<li>'.&Apache::lonnet::plaintext($priv);  
                                                 unless ($level eq 'c') {  
                                                     $resulttext .= ' ('.$lt{$level}.')';  
                                                 }  
                                                 $resulttext .= '</li>';  
                                             }  
                                         }  
                                     }  
                                     $resulttext .= '</ul>';  
                                 }  
                                 $resulttext .= '</ul></li>';  
                             }  
                         }  
                     }  
                 }  
             }  
         }  
         if (keys(%changedprivs)) {  
             foreach my $role (sort(keys(%changedprivs))) {  
                 unless ($shownprivs{$role}) {  
                     $resulttext .= '<li>'.&mt('Existing custom role modified: [_1]',  
                                               $role).'<ul>'.  
                                    '<li>'.&mt('Privileges set to :').'<ul>';  
                     foreach my $level (@levelorder) {  
                         foreach my $item (split(/\:/,$changedprivs{$role}{$level})) {  
                             next if ($item eq '');  
                             my ($priv) = split(/\&/,$item,2);  
                             if (&Apache::lonnet::plaintext($priv)) {  
                                 $resulttext .= '<li>'.&Apache::lonnet::plaintext($priv);  
                                 unless ($level eq 'c') {  
                                     $resulttext .= ' ('.$lt{$level}.')';  
                                 }  
                                 $resulttext .= '</li>';  
                             }  
                         }  
                     }  
                     $resulttext .= '</ul></li></ul></li>';  
                 }                  }
             }              }
               $resulttext .= '</ul>';
           } else {
               $resulttext = &mt('No changes made to help settings');
               $errors .= '<li><span class="LC_error">'.
                          &mt('An error occurred storing the settings: [_1]',
                              $putresult).'</span></li>';
         }          }
         $resulttext .= '</ul>';  
     } else {  
         $resulttext = &mt('No changes made to help settings');  
     }      }
     if ($errors) {      if ($errors) {
         $resulttext .= '<br />'.&mt('The following errors occurred: ').'<ul>'.          $resulttext .= '<br />'.&mt('The following errors occurred: ').'<ul>'.
                                     $errors.'</ul>';                         $errors.'</ul>';
     }      }
     return $resulttext;      return $resulttext;
 }  }
   
 sub modify_coursedefaults {  sub modify_coursedefaults {
     my ($dom,$lastactref,%domconfig) = @_;      my ($dom,%domconfig) = @_;
     my ($resulttext,$errors,%changes,%defaultshash);      my ($resulttext,$errors,%changes,%defaultshash);
     my %defaultchecked = (      my %defaultchecked = ('canuse_pdfforms' => 'off');
                            'uselcmath'       => 'on',      my @toggles = ('canuse_pdfforms');
                            'usejsme'         => 'on'  
                          );  
     my @toggles = ('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');
                    'mysqltables_unofficial','mysqltables_community','mysqltables_textbook');      my @types = ('official','unofficial','community');
     my @types = ('official','unofficial','community','textbook');  
     my %staticdefaults = (      my %staticdefaults = (
                            anonsurvey_threshold => 10,                             anonsurvey_threshold => 10,
                            uploadquota          => 500,                             uploadquota          => 500,
                            postsubmit           => 60,  
                            mysqltables          => 172800,  
                          );                           );
   
     $defaultshash{'coursedefaults'} = {};      $defaultshash{'coursedefaults'} = {};
Line 11712  sub modify_coursedefaults { Line 7973  sub modify_coursedefaults {
         }          }
         foreach my $item (@numbers) {          foreach my $item (@numbers) {
             my ($currdef,$newdef);              my ($currdef,$newdef);
             $newdef = $env{'form.'.$item};              my $newdef = $env{'form.'.$item};
             if ($item eq 'anonsurvey_threshold') {              if ($item eq 'anonsurvey_threshold') {
                 $currdef = $domconfig{'coursedefaults'}{$item};                  $currdef = $domconfig{'coursedefaults'}{$item};
                 $newdef =~ s/\D//g;                  $newdef =~ s/\D//g;
Line 11721  sub modify_coursedefaults { Line 7982  sub modify_coursedefaults {
                 }                  }
                 $defaultshash{'coursedefaults'}{$item} = $newdef;                  $defaultshash{'coursedefaults'}{$item} = $newdef;
             } else {              } else {
                 my ($setting,$type) = ($item =~ /^(uploadquota|mysqltables)_(\w+)$/);                  my ($type) = ($item =~ /^\Quploadquota_\E(\w+)$/);
                 if (ref($domconfig{'coursedefaults'}{$setting}) eq 'HASH') {                  if (ref($domconfig{'coursedefaults'}{'uploadquota'}) eq 'HASH') {
                     $currdef = $domconfig{'coursedefaults'}{$setting}{$type};                      $currdef = $domconfig{'coursedefaults'}{'uploadquota'}{$type};
                 }                  }
                 $newdef =~ s/[^\w.\-]//g;                  $newdef =~ s/[^\w.\-]//g;
                 $defaultshash{'coursedefaults'}{$setting}{$type} = $newdef;                  $defaultshash{'coursedefaults'}{'uploadquota'}{$type} = $newdef;
             }              }
             if ($currdef ne $newdef) {              if ($currdef ne $newdef) {
                 my $staticdef;                  my $staticdef;
Line 11734  sub modify_coursedefaults { Line 7995  sub modify_coursedefaults {
                     unless (($currdef eq '') && ($newdef == $staticdefaults{$item})) {                      unless (($currdef eq '') && ($newdef == $staticdefaults{$item})) {
                         $changes{$item} = 1;                          $changes{$item} = 1;
                     }                      }
                 } elsif ($item =~ /^(uploadquota|mysqltables)_/) {                  } else {
                     my $setting = $1;                      unless (($currdef eq '') && ($newdef == $staticdefaults{'uploadquota'})) {
                     unless (($currdef eq '') && ($newdef == $staticdefaults{$setting})) {                          $changes{'uploadquota'} = 1;
                         $changes{$setting} = 1;  
                     }                      }
                 }                  }
             }              }
         }          }
         my $currclone = $domconfig{'coursedefaults'}{'canclone'};          my $officialcreds = $env{'form.official_credits'};
         my @currclonecode;          $officialcreds =~ s/^[^\d\.]//g;
         if (ref($currclone) eq 'HASH') {          my $unofficialcreds = $env{'form.unofficial_credits'};
             if (ref($currclone->{'instcode'}) eq 'ARRAY') {          $unofficialcreds =~ s/^[^\d\.]//g;
                 @currclonecode = @{$currclone->{'instcode'}};          if (ref($domconfig{'coursedefaults'}{'coursecredits'} ne 'HASH') &&
             }                  ($env{'form.coursecredits'} eq '1')) {
         }                  $changes{'coursecredits'} = 1;
         my $newclone;  
         if ($env{'form.canclone'} =~ /^(none|domain|instcode)$/) {  
             $newclone = $env{'form.canclone'};  
         }  
         if ($newclone eq 'instcode') {  
             my @newcodes = &Apache::loncommon::get_env_multiple('form.clonecode');  
             my (%codedefaults,@code_order,@clonecode);  
             &Apache::lonnet::auto_instcode_defaults($dom,\%codedefaults,  
                                                     \@code_order);  
             foreach my $item (@code_order) {  
                 if (grep(/^\Q$item\E$/,@newcodes)) {  
                     push(@clonecode,$item);  
                 }  
             }  
             if (@clonecode) {  
                 $defaultshash{'coursedefaults'}{'canclone'} = { $newclone => \@clonecode };  
                 my @diffs = &Apache::loncommon::compare_arrays(\@currclonecode,\@clonecode);  
                 if (@diffs) {  
                     $changes{'canclone'} = 1;  
                 }  
             } else {  
                 $newclone eq '';  
             }  
         } elsif ($newclone ne '') {  
             $defaultshash{'coursedefaults'}{'canclone'} = $newclone;  
         }  
         if ($newclone ne $currclone) {  
             $changes{'canclone'} = 1;  
         }  
         my %credits;  
         foreach my $type (@types) {  
             unless ($type eq 'community') {  
                 $credits{$type} = $env{'form.'.$type.'_credits'};  
                 $credits{$type} =~ s/[^\d.]+//g;  
             }  
         }  
         if ((ref($domconfig{'coursedefaults'}{'coursecredits'}) ne 'HASH') &&  
             ($env{'form.coursecredits'} eq '1')) {  
             $changes{'coursecredits'} = 1;  
             foreach my $type (keys(%credits)) {  
                 $defaultshash{'coursedefaults'}{'coursecredits'}{$type} = $credits{$type};  
             }  
         } else {          } else {
             if ($env{'form.coursecredits'} eq '1') {              if (($domconfig{'coursedefaults'}{'coursecredits'}{'official'} ne $officialcreds)  ||
                 foreach my $type (@types) {                  ($domconfig{'coursedefaults'}{'coursecredits'}{'unofficial'} ne $unofficialcreds)) {
                     unless ($type eq 'community') {                  $changes{'coursecredits'} = 1;
                         if ($domconfig{'coursedefaults'}{'coursecredits'}{$type} ne $credits{$type}) {  
                             $changes{'coursecredits'} = 1;  
                         }  
                         $defaultshash{'coursedefaults'}{'coursecredits'}{$type} = $credits{$type};  
                     }  
                 }  
             } elsif (ref($domconfig{'coursedefaults'}{'coursecredits'}) eq 'HASH') {  
                 foreach my $type (@types) {  
                     unless ($type eq 'community') {  
                         if ($domconfig{'coursedefaults'}{'coursecredits'}{$type}) {  
                             $changes{'coursecredits'} = 1;  
                             last;  
                         }  
                     }  
                 }  
             }              }
         }          }
         if ($env{'form.postsubmit'} eq '1') {          $defaultshash{'coursedefaults'}{'coursecredits'} = {
             $defaultshash{'coursedefaults'}{'postsubmit'}{'client'} = 'on';              official   => $officialcreds,
             my %currtimeout;              unofficial => $unofficialcreds,
             if (ref($domconfig{'coursedefaults'}{'postsubmit'}) eq 'HASH') {  
                 if ($domconfig{'coursedefaults'}{'postsubmit'}{'client'} eq 'off') {  
                     $changes{'postsubmit'} = 1;  
                 }  
                 if (ref($domconfig{'coursedefaults'}{'postsubmit'}{'timeout'}) eq 'HASH') {  
                     %currtimeout = %{$domconfig{'coursedefaults'}{'postsubmit'}{'timeout'}};  
                 }  
             } else {  
                 $changes{'postsubmit'} = 1;  
             }  
             foreach my $type (@types) {  
                 my $timeout = $env{'form.'.$type.'_timeout'};  
                 $timeout =~ s/\D//g;  
                 if ($timeout == $staticdefaults{'postsubmit'}) {  
                     $timeout = '';  
                 } elsif (($timeout eq '') || ($timeout =~ /^0+$/)) {  
                     $timeout = '0';  
                 }  
                 unless ($timeout eq '') {  
                     $defaultshash{'coursedefaults'}{'postsubmit'}{'timeout'}{$type} = $timeout;  
                 }  
                 if (exists($currtimeout{$type})) {  
                     if ($timeout ne $currtimeout{$type}) {  
                         $changes{'postsubmit'} = 1;  
                     }  
                 } elsif ($timeout ne '') {  
                     $changes{'postsubmit'} = 1;  
                 }  
             }  
         } else {  
             $defaultshash{'coursedefaults'}{'postsubmit'}{'client'} = 'off';  
             if (ref($domconfig{'coursedefaults'}{'postsubmit'}) eq 'HASH') {  
                 if ($domconfig{'coursedefaults'}{'postsubmit'}{'client'} eq 'on') {  
                     $changes{'postsubmit'} = 1;  
                 }  
             } else {  
                 $changes{'postsubmit'} = 1;  
             }  
         }          }
     }      }
     my $putresult = &Apache::lonnet::put_dom('configuration',\%defaultshash,      my $putresult = &Apache::lonnet::put_dom('configuration',\%defaultshash,
                                              $dom);                                               $dom);
     if ($putresult eq 'ok') {      if ($putresult eq 'ok') {
           my %domdefaults;
         if (keys(%changes) > 0) {          if (keys(%changes) > 0) {
             my %domdefaults = &Apache::lonnet::get_domain_defaults($dom,1);              if (($changes{'canuse_pdfforms'}) || ($changes{'coursecredits'}) || ($changes{'uploadquota'})) {
             if (($changes{'uploadquota'}) || ($changes{'postsubmit'}) ||                  %domdefaults = &Apache::lonnet::get_domain_defaults($dom);
                 ($changes{'coursecredits'}) || ($changes{'uselcmath'}) || ($changes{'usejsme'}) ||                  if ($changes{'canuse_pdfforms'}) {
                 ($changes{'canclone'}) || ($changes{'mysqltables'})) {                      $domdefaults{'canuse_pdfforms'}=$defaultshash{'coursedefaults'}{'canuse_pdfforms'};
                 foreach my $item ('uselcmath','usejsme') {  
                     if ($changes{$item}) {  
                         $domdefaults{$item}=$defaultshash{'coursedefaults'}{$item};  
                     }  
                 }                  }
                 if ($changes{'coursecredits'}) {                  if ($changes{'coursecredits'}) {
                     if (ref($defaultshash{'coursedefaults'}{'coursecredits'}) eq 'HASH') {                      if (ref($defaultshash{'coursedefaults'}{'coursecredits'}) eq 'HASH') {
                         foreach my $type (keys(%{$defaultshash{'coursedefaults'}{'coursecredits'}})) {                          $domdefaults{'officialcredits'} =
                             $domdefaults{$type.'credits'} =                              $defaultshash{'coursedefaults'}{'coursecredits'}{'official'};
                                 $defaultshash{'coursedefaults'}{'coursecredits'}{$type};                          $domdefaults{'unofficialcredits'} =
                         }                              $defaultshash{'coursedefaults'}{'coursecredits'}{'unofficial'};
                     }  
                 }  
                 if ($changes{'postsubmit'}) {  
                     if (ref($defaultshash{'coursedefaults'}{'postsubmit'}) eq 'HASH') {  
                         $domdefaults{'postsubmit'} = $defaultshash{'coursedefaults'}{'postsubmit'}{'client'};  
                         if (ref($defaultshash{'coursedefaults'}{'postsubmit'}{'timeout'}) eq 'HASH') {  
                             foreach my $type (keys(%{$defaultshash{'coursedefaults'}{'postsubmit'}{'timeout'}})) {  
                                 $domdefaults{$type.'postsubtimeout'} =  
                                     $defaultshash{'coursedefaults'}{'postsubmit'}{'timeout'}{$type};  
                             }  
                         }  
                     }                      }
                 }                  }
                 if ($changes{'uploadquota'}) {                  if ($changes{'uploadquota'}) {
Line 11894  sub modify_coursedefaults { Line 8045  sub modify_coursedefaults {
                         }                          }
                     }                      }
                 }                  }
                 if ($changes{'canclone'}) {  
                     if (ref($defaultshash{'coursedefaults'}{'canclone'}) eq 'HASH') {  
                         if (ref($defaultshash{'coursedefaults'}{'canclone'}{'instcode'}) eq 'ARRAY') {  
                             my @clonecodes = @{$defaultshash{'coursedefaults'}{'canclone'}{'instcode'}};  
                             if (@clonecodes) {  
                                 $domdefaults{'canclone'} = join('+',@clonecodes);  
                             }  
                         }  
                     } else {  
                         $domdefaults{'canclone'}=$defaultshash{'coursedefaults'}{'canclone'};  
                     }  
                 }  
                 my $cachetime = 24*60*60;                  my $cachetime = 24*60*60;
                 &Apache::lonnet::do_cache_new('domdefaults',$dom,\%domdefaults,$cachetime);                  &Apache::lonnet::do_cache_new('domdefaults',$dom,\%domdefaults,$cachetime);
                 if (ref($lastactref) eq 'HASH') {  
                     $lastactref->{'domdefaults'} = 1;  
                 }  
             }              }
             $resulttext = &mt('Changes made:').'<ul>';              $resulttext = &mt('Changes made:').'<ul>';
             foreach my $item (sort(keys(%changes))) {              foreach my $item (sort(keys(%changes))) {
                 if ($item eq 'uselcmath') {                  if ($item eq 'canuse_pdfforms') {
                     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("Course/Community users can create/upload PDF forms set to 'on'").'</li>';
                     } else {                      } else {
                         $resulttext .= '<li>'.&mt('Math preview uses DragMath (Java), if supported by client OS.').'</li>';                          $resulttext .= '<li>'.&mt('Course/Community users can create/upload PDF forms set to "off"').'</li>';
                     }  
                 } elsif ($item eq 'usejsme') {  
                     if ($env{'form.'.$item} eq '1') {  
                         $resulttext .= '<li>'.&mt('Molecule editor uses JSME (HTML5), if supported by browser.').'</li>';  
                     } else {  
                         $resulttext .= '<li>'.&mt('Molecule editor uses JME (Java), if supported by client OS.').'</li>';  
                     }                      }
                 } elsif ($item eq 'anonsurvey_threshold') {                  } elsif ($item eq 'anonsurvey_threshold') {
                     $resulttext .= '<li>'.&mt('Responder count required for display of anonymous survey submissions set to [_1].',$defaultshash{'coursedefaults'}{'anonsurvey_threshold'}).'</li>';                      $resulttext .= '<li>'.&mt('Responder count required for display of anonymous survey submissions set to [_1].',$defaultshash{'coursedefaults'}{'anonsurvey_threshold'}).'</li>';
Line 11933  sub modify_coursedefaults { Line 8063  sub modify_coursedefaults {
                         $resulttext .= '<li>'.&mt('Default quota for content uploaded to a course/community via Course Editor set as follows:').'<ul>'.                          $resulttext .= '<li>'.&mt('Default quota for content uploaded to a course/community via Course Editor set as follows:').'<ul>'.
                                        '<li>'.&mt('Official courses: [_1] MB','<b>'.$defaultshash{'coursedefaults'}{'uploadquota'}{'official'}.'</b>').'</li>'.                                         '<li>'.&mt('Official courses: [_1] MB','<b>'.$defaultshash{'coursedefaults'}{'uploadquota'}{'official'}.'</b>').'</li>'.
                                        '<li>'.&mt('Unofficial courses: [_1] MB','<b>'.$defaultshash{'coursedefaults'}{'uploadquota'}{'unofficial'}.'</b>').'</li>'.                                         '<li>'.&mt('Unofficial courses: [_1] MB','<b>'.$defaultshash{'coursedefaults'}{'uploadquota'}{'unofficial'}.'</b>').'</li>'.
                                        '<li>'.&mt('Textbook courses: [_1] MB','<b>'.$defaultshash{'coursedefaults'}{'uploadquota'}{'textbook'}.'</b>').'</li>'.  
   
                                        '<li>'.&mt('Communities: [_1] MB','<b>'.$defaultshash{'coursedefaults'}{'uploadquota'}{'community'}.'</b>').'</li>'.                                         '<li>'.&mt('Communities: [_1] MB','<b>'.$defaultshash{'coursedefaults'}{'uploadquota'}{'community'}.'</b>').'</li>'.
                                        '</ul>'.                                         '</ul>'.
                                        '</li>';                                         '</li>';
                     } else {                      } else {
                         $resulttext .= '<li>'.&mt('Default quota for content uploaded via Course Editor remains default: [_1] MB',$staticdefaults{'uploadquota'}).'</li>';                          $resulttext .= '<li>'.&mt('Default quota for content uploaded via Course Editor remains default: [_1] MB',$staticdefaults{'uploadquota'}).'</li>';
                     }                      }
                 } elsif ($item eq 'mysqltables') {  
                     if (ref($defaultshash{'coursedefaults'}{'mysqltables'}) eq 'HASH') {  
                         $resulttext .= '<li>'.&mt('Lifetime of "Temporary" MySQL tables (student performance data) on homeserver').'<ul>'.  
                                        '<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('Textbook courses: [_1] s','<b>'.$defaultshash{'coursedefaults'}{'mysqltables'}{'textbook'}.'</b>').'</li>'.  
                                        '<li>'.&mt('Communities: [_1] s','<b>'.$defaultshash{'coursedefaults'}{'mysqltables'}{'community'}.'</b>').'</li>'.  
                                        '</ul>'.  
                                        '</li>';  
                     } else {  
                         $resulttext .= '<li>'.&mt('Lifetime of "Temporary" MySQL tables (student performance data) on homeserver remains default: [_1] s',$staticdefaults{'uploadquota'}).'</li>';  
                     }  
                 } elsif ($item eq 'postsubmit') {  
                     if ($domdefaults{'postsubmit'} eq 'off') {  
                         $resulttext .= '<li>'.&mt('Submit button(s) remain enabled on page after student makes submission.');  
                     } else {  
                         $resulttext .= '<li>'.&mt('Submit button(s) disabled on page after student makes submission').'; ';  
                         if (ref($defaultshash{'coursedefaults'}{'postsubmit'}) eq 'HASH') {  
                             $resulttext .= &mt('durations:').'<ul>';  
                             foreach my $type (@types) {  
                                 $resulttext .= '<li>';  
                                 my $timeout;  
                                 if (ref($defaultshash{'coursedefaults'}{'postsubmit'}{'timeout'}) eq 'HASH') {  
                                     $timeout = $defaultshash{'coursedefaults'}{'postsubmit'}{'timeout'}{$type};  
                                 }  
                                 my $display;  
                                 if ($timeout eq '0') {  
                                     $display = &mt('unlimited');  
                                 } elsif ($timeout eq '') {  
                                     $display = &mt('[quant,_1,second] (default)',$staticdefaults{'postsubmit'});  
                                 } else {  
                                     $display = &mt('[quant,_1,second]',$timeout);  
                                 }  
                                 if ($type eq 'community') {  
                                     $resulttext .= &mt('Communities');  
                                 } elsif ($type eq 'official') {  
                                     $resulttext .= &mt('Official courses');  
                                 } elsif ($type eq 'unofficial') {  
                                     $resulttext .= &mt('Unofficial courses');  
                                 } elsif ($type eq 'textbook') {  
                                     $resulttext .= &mt('Textbook courses');  
                                 }  
                                 $resulttext .= ' -- '.$display.'</li>';  
                             }  
                             $resulttext .= '</ul>';  
                         }  
                         $resulttext .= '</li>';  
                     }  
                 } elsif ($item eq 'coursecredits') {                  } elsif ($item eq 'coursecredits') {
                     if (ref($defaultshash{'coursedefaults'}{'coursecredits'}) eq 'HASH') {                      if (ref($defaultshash{'coursedefaults'}{'coursecredits'}) eq 'HASH') {
                         if (($domdefaults{'officialcredits'} eq '') &&                          if (($domdefaults{'officialcredits'} eq '') &&
                             ($domdefaults{'unofficialcredits'} eq '') &&                              ($domdefaults{'unofficialcredits'} eq '')) {
                             ($domdefaults{'textbookcredits'} eq '')) {  
                             $resulttext .= '<li>'.&mt('Student credits not in use for courses in this domain').'</li>';                              $resulttext .= '<li>'.&mt('Student credits not in use for courses in this domain').'</li>';
                         } else {                          } else {
                             $resulttext .= '<li>'.&mt('Student credits can be set per course by a Domain Coordinator, with the following defaults applying:').'<ul>'.                              $resulttext .= '<li>'.&mt('Student credits can be set per course by a Domain Coordinator, with the following defaults applying:').'<ul>'.
                                            '<li>'.&mt('Official courses: [_1]',$defaultshash{'coursedefaults'}{'coursecredits'}{'official'}).'</li>'.                                             '<li>'.&mt('Official courses: [_1]',$defaultshash{'coursedefaults'}{'coursecredits'}{'official'}).'</li>'.
                                            '<li>'.&mt('Unofficial courses: [_1]',$defaultshash{'coursedefaults'}{'coursecredits'}{'unofficial'}).'</li>'.                                             '<li>'.&mt('Unofficial courses: [_1]',$defaultshash{'coursedefaults'}{'coursecredits'}{'unofficial'}).'</li>'.
                                            '<li>'.&mt('Textbook courses: [_1]',$defaultshash{'coursedefaults'}{'coursecredits'}{'textbook'}).'</li>'.  
                                            '</ul>'.                                             '</ul>'.
                                            '</li>';                                             '</li>';
                         }                          }
                     } else {                      } else {
                         $resulttext .= '<li>'.&mt('Student credits not in use for courses in this domain').'</li>';                          $resulttext .= '<li>'.&mt('Student credits not in use for courses in this domain').'</li>';
                     }                      }
                 } elsif ($item eq 'canclone') {  
                     if (ref($defaultshash{'coursedefaults'}{'canclone'}) eq 'HASH') {  
                         if (ref($defaultshash{'coursedefaults'}{'canclone'}{'instcode'}) eq 'ARRAY') {  
                             my $clonecodes = join(' '.&mt('and').' ',@{$defaultshash{'coursedefaults'}{'canclone'}{'instcode'}});  
                             $resulttext .= '<li>'.&mt('By default, official courses can be cloned from existing courses with the same: [_1]','<b>'.$clonecodes.'</b>').'</li>';  
                         }  
                     } elsif ($defaultshash{'coursedefaults'}{'canclone'} eq 'domain') {  
                         $resulttext .= '<li>'.&mt('By default, a course requester can clone any course from his/her domain.').'</li>';  
                     } else {  
                         $resulttext .= '<li>'.&mt('By default, only course owner and coordinators may clone a course.').'</li>';  
                     }  
                 }                  }
             }              }
             $resulttext .= '</ul>';              $resulttext .= '</ul>';
Line 12030  sub modify_coursedefaults { Line 8097  sub modify_coursedefaults {
     return $resulttext;      return $resulttext;
 }  }
   
 sub modify_selfenrollment {  
     my ($dom,$lastactref,%domconfig) = @_;  
     my ($resulttext,$errors,%changes,%selfenrollhash,%ordered);  
     my @types = ('official','unofficial','community','textbook');  
     my %titles = &tool_titles();  
     my %descs = &Apache::lonuserutils::selfenroll_default_descs();  
     ($ordered{'admin'},my $titlesref) = &Apache::lonuserutils::get_selfenroll_titles();  
     $ordered{'default'} = ['types','registered','approval','limit'];  
   
     my (%roles,%shown,%toplevel);  
     $roles{'0'} = &Apache::lonnet::plaintext('dc');  
   
     if (ref($domconfig{'selfenrollment'}) ne 'HASH') {  
         if ($domconfig{'selfenrollment'} eq '') {  
             $domconfig{'selfenrollment'} = {};  
         }  
     }  
     %toplevel = (  
                   admin      => 'Configuration Rights',  
                   default    => 'Default settings',  
                   validation => 'Validation of self-enrollment requests',  
                 );  
     my ($itemsref,$namesref,$fieldsref) = &Apache::lonuserutils::selfenroll_validation_types();  
   
     if (ref($ordered{'admin'}) eq 'ARRAY') {  
         foreach my $item (@{$ordered{'admin'}}) {  
             foreach my $type (@types) {  
                 if ($env{'form.selfenrolladmin_'.$item.'_'.$type}) {  
                     $selfenrollhash{'admin'}{$type}{$item} = 1;  
                 } else {  
                     $selfenrollhash{'admin'}{$type}{$item} = 0;  
                 }  
                 if (ref($domconfig{'selfenrollment'}{'admin'}) eq 'HASH') {  
                     if (ref($domconfig{'selfenrollment'}{'admin'}{$type}) eq 'HASH') {  
                         if ($selfenrollhash{'admin'}{$type}{$item} ne  
                             $domconfig{'selfenrollment'}{'admin'}{$type}{$item})  {  
                             push(@{$changes{'admin'}{$type}},$item);  
                         }  
                     } else {  
                         if (!$selfenrollhash{'admin'}{$type}{$item}) {  
                             push(@{$changes{'admin'}{$type}},$item);  
                         }  
                     }  
                 } elsif (!$selfenrollhash{'admin'}{$type}{$item}) {  
                     push(@{$changes{'admin'}{$type}},$item);  
                 }  
             }  
         }  
     }  
   
     foreach my $item (@{$ordered{'default'}}) {  
         foreach my $type (@types) {  
             my $value = $env{'form.selfenrolldefault_'.$item.'_'.$type};  
             if ($item eq 'types') {  
                 unless (($value eq 'all') || ($value eq 'dom')) {  
                     $value = '';  
                 }  
             } elsif ($item eq 'registered') {  
                 unless ($value eq '1') {  
                     $value = 0;  
                 }  
             } elsif ($item eq 'approval') {  
                 unless ($value =~ /^[012]$/) {  
                     $value = 0;  
                 }  
             } else {  
                 unless (($value eq 'allstudents') || ($value eq 'selfenrolled')) {  
                     $value = 'none';  
                 }  
             }  
             $selfenrollhash{'default'}{$type}{$item} = $value;  
             if (ref($domconfig{'selfenrollment'}{'default'}) eq 'HASH') {  
                 if (ref($domconfig{'selfenrollment'}{'default'}{$type}) eq 'HASH') {  
                     if ($selfenrollhash{'default'}{$type}{$item} ne  
                          $domconfig{'selfenrollment'}{'default'}{$type}{$item})  {  
                          push(@{$changes{'default'}{$type}},$item);  
                     }  
                 } else {  
                     push(@{$changes{'default'}{$type}},$item);  
                 }  
             } else {  
                 push(@{$changes{'default'}{$type}},$item);  
             }  
             if ($item eq 'limit') {  
                 if (($value eq 'allstudents') || ($value eq 'selfenrolled')) {  
                     $env{'form.selfenrolldefault_cap_'.$type} =~ s/\D//g;  
                     if ($env{'form.selfenrolldefault_cap_'.$type} ne '') {  
                         $selfenrollhash{'default'}{$type}{'cap'} = $env{'form.selfenrolldefault_cap_'.$type};  
                     }  
                 } else {  
                     $selfenrollhash{'default'}{$type}{'cap'} = '';  
                 }  
                 if (ref($domconfig{'selfenrollment'}{'default'}{$type}) eq 'HASH') {  
                     if ($selfenrollhash{'default'}{$type}{'cap'} ne  
                          $domconfig{'selfenrollment'}{'admin'}{$type}{'cap'})  {  
                          push(@{$changes{'default'}{$type}},'cap');  
                     }  
                 } elsif ($selfenrollhash{'default'}{$type}{'cap'} ne '') {  
                     push(@{$changes{'default'}{$type}},'cap');  
                 }  
             }  
         }  
     }  
   
     foreach my $item (@{$itemsref}) {  
         if ($item eq 'fields') {  
             my @changed;  
             @{$selfenrollhash{'validation'}{$item}} = &Apache::loncommon::get_env_multiple('form.selfenroll_validation_'.$item);  
             if (@{$selfenrollhash{'validation'}{$item}} > 0) {  
                 @{$selfenrollhash{'validation'}{$item}} = sort(@{$selfenrollhash{'validation'}{$item}});  
             }  
             if (ref($domconfig{'selfenrollment'}{'validation'}) eq 'HASH') {  
                 if (ref($domconfig{'selfenrollment'}{'validation'}{$item}) eq 'ARRAY') {  
                     @changed = &Apache::loncommon::compare_arrays($selfenrollhash{'validation'}{$item},  
                                                                   $domconfig{'selfenrollment'}{'validation'}{$item});  
                 } else {  
                     @changed = @{$selfenrollhash{'validation'}{$item}};  
                 }  
             } else {  
                 @changed = @{$selfenrollhash{'validation'}{$item}};  
             }  
             if (@changed) {  
                 if ($selfenrollhash{'validation'}{$item}) {   
                     $changes{'validation'}{$item} = join(', ',@{$selfenrollhash{'validation'}{$item}});  
                 } else {  
                     $changes{'validation'}{$item} = &mt('None');  
                 }  
             }  
         } else {  
             $selfenrollhash{'validation'}{$item} = $env{'form.selfenroll_validation_'.$item};  
             if ($item eq 'markup') {  
                if ($env{'form.selfenroll_validation_'.$item}) {  
                    $env{'form.selfenroll_validation_'.$item} =~ s/[\n\r\f]+/\s/gs;  
                }  
             }  
             if (ref($domconfig{'selfenrollment'}{'validation'}) eq 'HASH') {  
                 if ($domconfig{'selfenrollment'}{'validation'}{$item} ne $selfenrollhash{'validation'}{$item}) {  
                     $changes{'validation'}{$item} = $selfenrollhash{'validation'}{$item};  
                 }  
             }  
         }  
     }  
   
     my $putresult = &Apache::lonnet::put_dom('configuration',{'selfenrollment' => \%selfenrollhash},  
                                              $dom);  
     if ($putresult eq 'ok') {  
         if (keys(%changes) > 0) {  
             my %domdefaults = &Apache::lonnet::get_domain_defaults($dom,1);  
             $resulttext = &mt('Changes made:').'<ul>';  
             foreach my $key ('admin','default','validation') {  
                 if (ref($changes{$key}) eq 'HASH') {  
                     $resulttext .= '<li>'.$toplevel{$key}.'<ul>';  
                     if ($key eq 'validation') {  
                         foreach my $item (@{$itemsref}) {  
                             if (exists($changes{$key}{$item})) {  
                                 if ($item eq 'markup') {  
                                     $resulttext .= '<li>'.&mt('[_1] set to: [_2]',$namesref->{$item},  
                                                               '<br /><pre>'.$changes{$key}{$item}.'</pre>').'</li>';  
                                 } else {    
                                     $resulttext .= '<li>'.&mt('[_1] set to: [_2]',$namesref->{$item},  
                                                               '<b>'.$changes{$key}{$item}.'</b>').'</li>';  
                                 }  
                             }  
                         }  
                     } else {  
                         foreach my $type (@types) {  
                             if ($type eq 'community') {  
                                 $roles{'1'} = &mt('Community personnel');  
                             } else {  
                                 $roles{'1'} = &mt('Course personnel');  
                             }  
                             if (ref($changes{$key}{$type}) eq 'ARRAY') {  
                                 if (ref($selfenrollhash{$key}{$type}) eq 'HASH') {  
                                     if ($key eq 'admin') {  
                                         my @mgrdc = ();  
                                         if (ref($ordered{$key}) eq 'ARRAY') {  
                                             foreach my $item (@{$ordered{'admin'}}) {  
                                                 if (ref($selfenrollhash{$key}{$type}) eq 'HASH') {   
                                                     if ($selfenrollhash{$key}{$type}{$item} eq '0') {  
                                                         push(@mgrdc,$item);  
                                                     }  
                                                 }  
                                             }  
                                             if (@mgrdc) {  
                                                 $domdefaults{$type.'selfenrolladmdc'} = join(',',@mgrdc);  
                                             } else {  
                                                 delete($domdefaults{$type.'selfenrolladmdc'});  
                                             }  
                                         }  
                                     } else {  
                                         if (ref($ordered{$key}) eq 'ARRAY') {  
                                             foreach my $item (@{$ordered{$key}}) {  
                                                 if (grep(/^\Q$item\E$/,@{$changes{$key}{$type}})) {  
                                                     $domdefaults{$type.'selfenroll'.$item} =  
                                                         $selfenrollhash{$key}{$type}{$item};  
                                                 }  
                                             }  
                                         }  
                                     }  
                                 }  
                                 $resulttext .= '<li>'.$titles{$type}.'<ul>';  
                                 foreach my $item (@{$ordered{$key}}) {  
                                     if (grep(/^\Q$item\E$/,@{$changes{$key}{$type}})) {  
                                         $resulttext .= '<li>';  
                                         if ($key eq 'admin') {  
                                             $resulttext .= &mt('[_1] -- management by: [_2]',$titlesref->{$item},  
                                                                '<b>'.$roles{$selfenrollhash{'admin'}{$type}{$item}}.'</b>');  
                                         } else {  
                                             $resulttext .= &mt('[_1] set to: [_2]',$titlesref->{$item},  
                                                                '<b>'.$descs{$item}{$selfenrollhash{'default'}{$type}{$item}}.'</b>');  
                                         }  
                                         $resulttext .= '</li>';  
                                     }  
                                 }  
                                 $resulttext .= '</ul></li>';  
                             }  
                         }  
                         $resulttext .= '</ul></li>';   
                     }  
                 }  
                 if ((exists($changes{'admin'})) || (exists($changes{'default'}))) {  
                     my $cachetime = 24*60*60;  
                     &Apache::lonnet::do_cache_new('domdefaults',$dom,\%domdefaults,$cachetime);  
                     if (ref($lastactref) eq 'HASH') {  
                         $lastactref->{'domdefaults'} = 1;  
                     }  
                 }  
             }  
             $resulttext .= '</ul>';  
         } else {  
             $resulttext = &mt('No changes made to self-enrollment settings');  
         }  
     } else {  
         $resulttext = '<span class="LC_error">'.  
             &mt('An error occurred: [_1]',$putresult).'</span>';  
     }  
     return $resulttext;  
 }  
   
 sub modify_usersessions {  sub modify_usersessions {
     my ($dom,$lastactref,%domconfig) = @_;      my ($dom,%domconfig) = @_;
     my @hostingtypes = ('version','excludedomain','includedomain');      my @hostingtypes = ('version','excludedomain','includedomain');
     my @offloadtypes = ('primary','default');      my @offloadtypes = ('primary','default');
     my %types = (      my %types = (
Line 12287  sub modify_usersessions { Line 8115  sub modify_usersessions {
     foreach my $prefix (@prefixes) {      foreach my $prefix (@prefixes) {
         $defaultshash{'usersessions'}{$prefix} = {};          $defaultshash{'usersessions'}{$prefix} = {};
     }      }
     my %domdefaults = &Apache::lonnet::get_domain_defaults($dom,1);      my %domdefaults = &Apache::lonnet::get_domain_defaults($dom);
     my $resulttext;      my $resulttext;
     my %iphost = &Apache::lonnet::get_iphost();      my %iphost = &Apache::lonnet::get_iphost();
     foreach my $prefix (@prefixes) {      foreach my $prefix (@prefixes) {
Line 12435  sub modify_usersessions { Line 8263  sub modify_usersessions {
             $changes{'spares'}{$lonhost} = \%spareschg;              $changes{'spares'}{$lonhost} = \%spareschg;
         }          }
     }      }
     $defaultshash{'usersessions'}{'offloadnow'} = {};  
     my @offloadnow = &Apache::loncommon::get_env_multiple('form.offloadnow');  
     my @okoffload;  
     if (@offloadnow) {  
         foreach my $server (@offloadnow) {  
             if (&Apache::lonnet::hostname($server) ne '') {  
                 unless (grep(/^\Q$server\E$/,@okoffload)) {  
                     push(@okoffload,$server);  
                 }  
             }  
         }  
         if (@okoffload) {  
             foreach my $lonhost (@okoffload) {  
                 $defaultshash{'usersessions'}{'offloadnow'}{$lonhost} = 1;  
             }  
         }  
     }  
     if (ref($domconfig{'usersessions'}) eq 'HASH') {      if (ref($domconfig{'usersessions'}) eq 'HASH') {
         if (ref($domconfig{'usersessions'}{'spares'}) eq 'HASH') {          if (ref($domconfig{'usersessions'}{'spares'}) eq 'HASH') {
             if (ref($changes{'spares'}) eq 'HASH') {              if (ref($changes{'spares'}) eq 'HASH') {
Line 12462  sub modify_usersessions { Line 8274  sub modify_usersessions {
         } else {          } else {
             $savespares = 1;              $savespares = 1;
         }          }
         if (ref($domconfig{'usersessions'}{'offloadnow'}) eq 'HASH') {  
             foreach my $lonhost (keys(%{$domconfig{'usersessions'}{'offloadnow'}})) {  
                 unless ($defaultshash{'usersessions'}{'offloadnow'}{$lonhost}) {  
                     $changes{'offloadnow'} = 1;  
                     last;  
                 }  
             }  
             unless ($changes{'offloadnow'}) {  
                 foreach my $lonhost (keys(%{$defaultshash{'usersessions'}{'offloadnow'}})) {  
                     unless ($domconfig{'usersessions'}{'offloadnow'}{$lonhost}) {  
                         $changes{'offloadnow'} = 1;  
                         last;  
                     }  
                 }  
             }  
         } elsif (@okoffload) {  
             $changes{'offloadnow'} = 1;  
         }  
     } elsif (@okoffload) {  
         $changes{'offloadnow'} = 1;  
     }      }
   
     my $nochgmsg = &mt('No changes made to settings for user session hosting/offloading.');      my $nochgmsg = &mt('No changes made to settings for user session hosting/offloading.');
     if ((keys(%changes) > 0) || ($savespares)) {      if ((keys(%changes) > 0) || ($savespares)) {
         my $putresult = &Apache::lonnet::put_dom('configuration',\%defaultshash,          my $putresult = &Apache::lonnet::put_dom('configuration',\%defaultshash,
Line 12495  sub modify_usersessions { Line 8288  sub modify_usersessions {
                 if (ref($defaultshash{'usersessions'}{'hosted'}) eq 'HASH') {                  if (ref($defaultshash{'usersessions'}{'hosted'}) eq 'HASH') {
                     $domdefaults{'hostedsessions'} = $defaultshash{'usersessions'}{'hosted'};                      $domdefaults{'hostedsessions'} = $defaultshash{'usersessions'}{'hosted'};
                 }                  }
                 if (ref($defaultshash{'usersessions'}{'offloadnow'}) eq 'HASH') {  
                     $domdefaults{'offloadnow'} = $defaultshash{'usersessions'}{'offloadnow'};  
                 }  
             }              }
             my $cachetime = 24*60*60;              my $cachetime = 24*60*60;
             &Apache::lonnet::do_cache_new('domdefaults',$dom,\%domdefaults,$cachetime);              &Apache::lonnet::do_cache_new('domdefaults',$dom,\%domdefaults,$cachetime);
             &Apache::lonnet::do_cache_new('usersessions',$dom,$defaultshash{'usersessions'},3600);  
             if (ref($lastactref) eq 'HASH') {  
                 $lastactref->{'domdefaults'} = 1;  
                 $lastactref->{'usersessions'} = 1;  
             }  
             if (keys(%changes) > 0) {              if (keys(%changes) > 0) {
                 my %lt = &usersession_titles();                  my %lt = &usersession_titles();
                 $resulttext = &mt('Changes made:').'<ul>';                  $resulttext = &mt('Changes made:').'<ul>';
Line 12517  sub modify_usersessions { Line 8302  sub modify_usersessions {
                                 foreach my $lonhost (sort(keys(%{$changes{$prefix}}))) {                                  foreach my $lonhost (sort(keys(%{$changes{$prefix}}))) {
                                     $resulttext .= '<li><b>'.$lonhost.'</b> ';                                      $resulttext .= '<li><b>'.$lonhost.'</b> ';
                                     my $lonhostdom = &Apache::lonnet::host_domain($lonhost);                                      my $lonhostdom = &Apache::lonnet::host_domain($lonhost);
                                     my $cachekey = &escape('spares').':'.&escape($lonhostdom);                                      &Apache::lonnet::remote_devalidate_cache($lonhost,'spares',$lonhostdom);
                                     &Apache::lonnet::remote_devalidate_cache($lonhost,[$cachekey]);  
                                     if (ref($changes{$prefix}{$lonhost}) eq 'HASH') {                                      if (ref($changes{$prefix}{$lonhost}) eq 'HASH') {
                                         foreach my $type (@{$types{$prefix}}) {                                          foreach my $type (@{$types{$prefix}}) {
                                             if ($changes{$prefix}{$lonhost}{$type}) {                                              if ($changes{$prefix}{$lonhost}{$type}) {
Line 12568  sub modify_usersessions { Line 8352  sub modify_usersessions {
                         $resulttext .= '</ul>';                          $resulttext .= '</ul>';
                     }                      }
                 }                  }
                 if ($changes{'offloadnow'}) {  
                     if (ref($defaultshash{'usersessions'}{'offloadnow'}) eq 'HASH') {  
                         if (keys(%{$defaultshash{'usersessions'}{'offloadnow'}}) > 0) {  
                             $resulttext .= '<li>'.&mt('Switch active users on next access, for server(s):').'<ul>';  
                             foreach my $lonhost (sort(keys(%{$defaultshash{'usersessions'}{'offloadnow'}}))) {  
                                 $resulttext .= '<li>'.$lonhost.'</li>';  
                             }  
                             $resulttext .= '</ul>';  
                         } else {  
                             $resulttext .= '<li>'.&mt('No servers now set to switch active users on next access.');  
                         }  
                     } else {  
                         $resulttext .= '<li>'.&mt('No servers now set to switch active users on next access.').'</li>';  
                     }  
                 }  
                 $resulttext .= '</ul>';                  $resulttext .= '</ul>';
             } else {              } else {
                 $resulttext = $nochgmsg;                  $resulttext = $nochgmsg;
Line 12604  sub modify_loadbalancing { Line 8373  sub modify_loadbalancing {
     my ($othertitle,$usertypes,$types) =      my ($othertitle,$usertypes,$types) =
         &Apache::loncommon::sorted_inst_types($dom);          &Apache::loncommon::sorted_inst_types($dom);
     my %servers = &Apache::lonnet::internet_dom_servers($dom);      my %servers = &Apache::lonnet::internet_dom_servers($dom);
     my %libraryservers = &Apache::lonnet::get_servers($dom,'library');  
     my @sparestypes = ('primary','default');      my @sparestypes = ('primary','default');
     my %typetitles = &sparestype_titles();      my %typetitles = &sparestype_titles();
     my $resulttext;      my $resulttext;
Line 12624  sub modify_loadbalancing { Line 8392  sub modify_loadbalancing {
         if ($balancer eq '') {          if ($balancer eq '') {
             next;              next;
         }          }
         if (!exists($servers{$balancer})) {          if (!exists($servers{$balancer})) { 
             if (exists($currbalancer{$balancer})) {              if (exists($currbalancer{$balancer})) {
                 push(@{$changes{'delete'}},$balancer);                  push(@{$changes{'delete'}},$balancer);
             }              }
Line 12657  sub modify_loadbalancing { Line 8425  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 12680  sub modify_loadbalancing { Line 8443  sub modify_loadbalancing {
             }              }
         } else {          } else {
             if (ref($defaultshash{'loadbalancing'}{$balancer}) eq 'HASH') {              if (ref($defaultshash{'loadbalancing'}{$balancer}) eq 'HASH') {
                 foreach my $sparetype (@sparestypes) {                  foreach my $sparetype (@sparestypes) { 
                     if (ref($defaultshash{'loadbalancing'}{$balancer}{'targets'}{$sparetype}) eq 'ARRAY') {                      if (ref($defaultshash{'loadbalancing'}{$balancer}{'targets'}{$sparetype}) eq 'ARRAY') {
                         if (@{$defaultshash{'loadbalancing'}{$balancer}{'targets'}{$sparetype}} > 0) {                          if (@{$defaultshash{'loadbalancing'}{$balancer}{'targets'}{$sparetype}} > 0) {
                             $changes{'curr'}{$balancer}{'targets'} = 1;                              $changes{'curr'}{$balancer}{'targets'} = 1;
                         }                          }
                     }                      }
                 }                  }
             }              }  
         }          }
         my $ishomedom;          my $ishomedom;
         if (&Apache::lonnet::host_domain($balancer) eq $dom) {          if (&Apache::lonnet::host_domain($balancer) eq $dom) {
Line 12696  sub modify_loadbalancing { Line 8459  sub modify_loadbalancing {
         if (ref($alltypes) eq 'ARRAY') {          if (ref($alltypes) eq 'ARRAY') {
             foreach my $type (@{$alltypes}) {              foreach my $type (@{$alltypes}) {
                 my $rule;                  my $rule;
                 unless ((($type eq '_LC_external') || ($type eq '_LC_internetdom')) &&                  unless ((($type eq '_LC_external') || ($type eq '_LC_internetdom')) && 
                          (!$ishomedom)) {                           (!$ishomedom)) {
                     $rule = $env{'form.loadbalancing_rules_'.$i.'_'.$type};                      $rule = $env{'form.loadbalancing_rules_'.$i.'_'.$type};
                 }                  }
                 if ($rule eq 'specific') {                  if ($rule eq 'specific') {
                     my $specifiedhost = $env{'form.loadbalancing_singleserver_'.$i.'_'.$type};                      $rule = $env{'form.loadbalancing_singleserver_'.$i.'_'.$type};
                     if (exists($servers{$specifiedhost})) {  
                         $rule = $specifiedhost;  
                     }  
                 }                  }
                 $defaultshash{'loadbalancing'}{$balancer}{'rules'}{$type} = $rule;                  $defaultshash{'loadbalancing'}{$balancer}{'rules'}{$type} = $rule;
                 if (ref($currrules{$balancer}) eq 'HASH') {                  if (ref($currrules{$balancer}) eq 'HASH') {
Line 12724  sub modify_loadbalancing { Line 8484  sub modify_loadbalancing {
         }          }
         my $putresult = &Apache::lonnet::put_dom('configuration',          my $putresult = &Apache::lonnet::put_dom('configuration',
                                                  \%defaultshash,$dom);                                                   \%defaultshash,$dom);
    
         if ($putresult eq 'ok') {          if ($putresult eq 'ok') {
             if (keys(%changes) > 0) {              if (keys(%changes) > 0) {
                 my %toupdate;  
                 if (ref($changes{'delete'}) eq 'ARRAY') {                  if (ref($changes{'delete'}) eq 'ARRAY') {
                     foreach my $balancer (sort(@{$changes{'delete'}})) {                      foreach my $balancer (sort(@{$changes{'delete'}})) {
                         $resulttext .= '<li>'.&mt('Load Balancing discontinued for: [_1]',$balancer).'</li>';                          $resulttext .= '<li>'.&mt('Load Balancing discontinued for: [_1]',$balancer).'</li>';
                         $toupdate{$balancer} = 1;                          &Apache::lonnet::remote_devalidate_cache($balancer,'loadbalancing',$dom);
                     }                      }
                 }                  }
                 if (ref($changes{'add'}) eq 'ARRAY') {                  if (ref($changes{'add'}) eq 'ARRAY') {
                     foreach my $balancer (sort(@{$changes{'add'}})) {                      foreach my $balancer (sort(@{$changes{'add'}})) {   
                         $resulttext .= '<li>'.&mt('Load Balancing enabled for: [_1]',$balancer);                          $resulttext .= '<li>'.&mt('Load Balancing enabled for: [_1]',$balancer);
                         $toupdate{$balancer} = 1;  
                     }                      }
                 }                  }
                 if (ref($changes{'curr'}) eq 'HASH') {                  if (ref($changes{'curr'}) eq 'HASH') {
                     foreach my $balancer (sort(keys(%{$changes{'curr'}}))) {                      foreach my $balancer (sort(keys(%{$changes{'curr'}}))) {
                         $toupdate{$balancer} = 1;  
                         if (ref($changes{'curr'}{$balancer}) eq 'HASH') {                          if (ref($changes{'curr'}{$balancer}) eq 'HASH') {
                             if ($changes{'curr'}{$balancer}{'targets'}) {                              if ($changes{'curr'}{$balancer}{'targets'}) {
                                 my %offloadstr;                                  my %offloadstr;
Line 12777  sub modify_loadbalancing { Line 8535  sub modify_loadbalancing {
                                         my $balancetext;                                          my $balancetext;
                                         if ($rule eq '') {                                          if ($rule eq '') {
                                             $balancetext =  $ruletitles{'default'};                                              $balancetext =  $ruletitles{'default'};
                                         } elsif (($rule eq 'homeserver') || ($rule eq 'externalbalancer') ||                                          } elsif (($rule eq 'homeserver') || ($rule eq 'externalbalancer')) {
                                                  ($type eq '_LC_ipchange') || ($type eq '_LC_ipchangesso')) {                                              $balancetext =  $ruletitles{$rule};
                                             if (($type eq '_LC_ipchange') || ($type eq '_LC_ipchangesso')) {  
                                                 foreach my $sparetype (@sparestypes) {  
                                                     if (ref($defaultshash{'loadbalancing'}{$balancer}{'targets'}{$sparetype}) eq 'ARRAY') {  
                                                         map { $toupdate{$_} = 1; } (@{$defaultshash{'loadbalancing'}{$balancer}{'targets'}{$sparetype}});  
                                                     }  
                                                 }  
                                                 foreach my $item (@{$alltypes}) {  
                                                     next if ($item =~  /^_LC_ipchange/);  
                                                     my $hasrule = $defaultshash{'loadbalancing'}{$balancer}{'rules'}{$item};  
                                                     if ($hasrule eq 'homeserver') {  
                                                         map { $toupdate{$_} = 1; } (keys(%libraryservers));  
                                                     } else {  
                                                         unless (($hasrule eq 'default') || ($hasrule eq 'none') || ($hasrule eq 'externalbalancer')) {  
                                                             if ($servers{$hasrule}) {  
                                                                 $toupdate{$hasrule} = 1;  
                                                             }  
                                                         }  
                                                     }  
                                                 }  
                                                 if (($rule eq 'balancer') || ($rule eq 'offloadedto')) {  
                                                     $balancetext =  $ruletitles{$rule};  
                                                 } else {  
                                                     my $receiver = $defaultshash{'loadbalancing'}{$balancer}{'rules'}{$type};  
                                                     $balancetext = $ruletitles{'particular'}.' '.$receiver;  
                                                     if ($receiver) {  
                                                         $toupdate{$receiver};  
                                                     }  
                                                 }  
                                             } else {  
                                                 $balancetext =  $ruletitles{$rule};  
                                             }  
                                         } else {                                          } else {
                                             $balancetext = &mt('offload to [_1]',$defaultshash{'loadbalancing'}{$balancer}{'rules'}{$type});                                              $balancetext = &mt('offload to [_1]',$defaultshash{'loadbalancing'}{$balancer}{'rules'}{$type});
                                         }                                          }
                                         $resulttext .= '<li>'.&mt('Load Balancer: [_1] -- balancing for [_2] set to - "[_3]"',$balancer,$titles->{$type},$balancetext).'</li>';                                          $resulttext .= '<li>'.&mt('Load Balancer: [_1] -- balancing for [_2] set to - "[_3]"',$balancer,$titles->{$type},$balancetext).'</li>';     
                                     }                                      }
                                 }                                  }
                             }                              }
                         }                          }
                         if (keys(%toupdate)) {                          &Apache::lonnet::remote_devalidate_cache($balancer,'loadbalancing',$dom);
                             my %thismachine;  
                             my $updatedhere;  
                             my $cachetime = 60*60*24;  
                             map { $thismachine{$_} = 1; } &Apache::lonnet::current_machine_ids();  
                             foreach my $lonhost (keys(%toupdate)) {  
                                 if ($thismachine{$lonhost}) {  
                                     unless ($updatedhere) {  
                                         &Apache::lonnet::do_cache_new('loadbalancing',$dom,  
                                                                       $defaultshash{'loadbalancing'},  
                                                                       $cachetime);  
                                         $updatedhere = 1;  
                                     }  
                                 } else {  
                                     my $cachekey = &escape('loadbalancing').':'.&escape($dom);  
                                     &Apache::lonnet::remote_devalidate_cache($lonhost,[$cachekey]);  
                                 }  
                             }  
                         }  
                     }                      }
                 }                  }
                 if ($resulttext ne '') {                  if ($resulttext ne '') {
Line 12897  sub recurse_cat_deletes { Line 8606  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 12909  sub active_dc_picker { Line 8633  sub active_dc_picker {
         }          }
     }      }
     @domcoord = sort(@domcoord);      @domcoord = sort(@domcoord);
     my $numdcs = scalar(@domcoord);      my $numdcs = scalar(@domcoord); 
     my $rows = 0;      my $rows = 0;
     my $table;      my $table;
     if ($numdcs > 1) {      if ($numdcs > 1) {
Line 12953  sub active_dc_picker { Line 8677  sub active_dc_picker {
                       '<input type="'.$inputtype.'" name="'.$name.'"'.                        '<input type="'.$inputtype.'" name="'.$name.'"'.
                       ' value="'.$domcoord[$i].'"'.$check.' />'.$user;                        ' value="'.$domcoord[$i].'"'.$check.' />'.$user;
             if ($user ne $dcname.':'.$dcdom) {              if ($user ne $dcname.':'.$dcdom) {
                 $table .=  ' ('.$dcname.':'.$dcdom.')';                  $table .=  ' ('.$dcname.':'.$dcdom.')'.
                              '</label></span></td>';
             }              }
             $table .= '</label></span></td>';  
         }          }
         $table .= '</tr></table>';          $table .= '</tr></table>';
     } elsif ($numdcs == 1) {      } elsif ($numdcs == 1) {
         my ($dcname,$dcdom) = split(':',$domcoord[0]);  
         my $user = &Apache::loncommon::plainname($dcname,$dcdom);  
         if ($inputtype eq 'radio') {          if ($inputtype eq 'radio') {
             $table = '<input type="hidden" name="'.$name.'" value="'.$domcoord[0].'" />'.$user;              $table .= '<input type="hidden" name="'.$name.'" value="'.$domcoord[0].'" />';
             if ($user ne $dcname.':'.$dcdom) {  
                 $table .=  ' ('.$dcname.':'.$dcdom.')';  
             }  
         } else {          } else {
             my $check;              my $check;
             if (exists($currhash{$domcoord[0]})) {              if (exists($currhash{$domcoord[0]})) {
                 $check = ' checked="checked"';                  $check = ' checked="checked"';
             }              }
             $table = '<span class="LC_nobreak"><label>'.              $table .= '<input type="checkbox" name="'.$name.'" '.
                      '<input type="checkbox" name="'.$name.'" '.                        'value="'.$domcoord[0].'"'.$check.' />';
                      'value="'.$domcoord[0].'"'.$check.' />'.$user;  
             if ($user ne $dcname.':'.$dcdom) {  
                 $table .=  ' ('.$dcname.':'.$dcdom.')';  
             }  
             $table .= '</label></span>';  
             $rows ++;              $rows ++;
         }          }
     }      }
Line 13053  sub lonbalance_targets_js { Line 8767  sub lonbalance_targets_js {
     }      }
     &get_loadbalancers_config($servers,\%existing,\%currbalancer,      &get_loadbalancers_config($servers,\%existing,\%currbalancer,
                               \%currtargets,\%currrules);                                \%currtargets,\%currrules);
     my $balancers = join("','",sort(keys(%currbalancer)));      my $balancers = join("','",sort(keys(%currbalancer))); 
     return <<"END";      return <<"END";
   
 <script type="text/javascript">  <script type="text/javascript">
Line 13124  function showSpares(balancer,ishomedom,b Line 8838  function showSpares(balancer,ishomedom,b
             } else {              } else {
                 document.getElementById('balanceruletitle_'+balnum+'_'+insttypes[k]).style.display='none';                  document.getElementById('balanceruletitle_'+balnum+'_'+insttypes[k]).style.display='none';
                 document.getElementById('balancerule_'+balnum+'_'+insttypes[k]).style.display='none';                  document.getElementById('balancerule_'+balnum+'_'+insttypes[k]).style.display='none';
   
             }              }
         } else {          } else {
             document.getElementById('balanceruletitle_'+balnum+'_'+insttypes[k]).style.display='block';              document.getElementById('balanceruletitle_'+balnum+'_'+insttypes[k]).style.display='block';
Line 13135  function showSpares(balancer,ishomedom,b Line 8850  function showSpares(balancer,ishomedom,b
             var item = document.getElementById('loadbalancing_singleserver_'+balnum+'_'+insttypes[k]);              var item = document.getElementById('loadbalancing_singleserver_'+balnum+'_'+insttypes[k]);
             item.options.length = 0;              item.options.length = 0;
             item.options[0] = new Option("","",true,true);              item.options[0] = new Option("","",true,true);
             var idx = 0;              var idx = 0;  
             for (var m=0; m<alltargets.length; m++) {              for (var m=0; m<alltargets.length; m++) {
                 if ((currBalancers.indexOf(alltargets[m]) == -1) && (alltargets[m] != balancer)) {                  if ((currBalancers.indexOf(alltargets[m]) == -1) && (alltargets[m] != balancer)) {
                     idx ++;                      idx ++;
                     item.options[idx] = new Option(alltargets[m],alltargets[m],false,false);                      item.options[idx] = new Option(alltargets[m],alltargets[m],false,false);
                       
                 }                  }
             }              }
         }          }
Line 13463  function updateCaptcha(caller,context) { Line 9179  function updateCaptcha(caller,context) {
     var pubitem;      var pubitem;
     var privtext;      var privtext;
     var pubtext;      var pubtext;
     var versionitem;  
     var versiontext;  
     if (document.getElementById(context+'_recaptchapub')) {      if (document.getElementById(context+'_recaptchapub')) {
         pubitem = document.getElementById(context+'_recaptchapub');          pubitem = document.getElementById(context+'_recaptchapub');
     } else {      } else {
Line 13485  function updateCaptcha(caller,context) { Line 9199  function updateCaptcha(caller,context) {
     } else {      } else {
         return;          return;
     }      }
     if (document.getElementById(context+'_recaptchaversion')) {  
         versionitem = document.getElementById(context+'_recaptchaversion');  
     } else {  
         return;  
     }  
     if (document.getElementById(context+'_recaptchavertxt')) {  
         versiontext = document.getElementById(context+'_recaptchavertxt');  
     } else {  
         return;  
     }  
     if (caller.checked) {      if (caller.checked) {
         if (caller.value == 'recaptcha') {          if (caller.value == 'recaptcha') {
             pubitem.type = 'text';              pubitem.type = 'text';
Line 13503  function updateCaptcha(caller,context) { Line 9207  function updateCaptcha(caller,context) {
             privitem.size = '40';              privitem.size = '40';
             pubtext.innerHTML = "$lt{'pub'}";              pubtext.innerHTML = "$lt{'pub'}";
             privtext.innerHTML = "$lt{'priv'}";              privtext.innerHTML = "$lt{'priv'}";
             versionitem.type = 'text';  
             versionitem.size = '3';  
             versiontext.innerHTML = "$lt{'ver'}";  
         } else {          } else {
             pubitem.type = 'hidden';              pubitem.type = 'hidden';
             privitem.type = 'hidden';              privitem.type = 'hidden';
             versionitem.type = 'hidden';  
             pubtext.innerHTML = '';              pubtext.innerHTML = '';
             privtext.innerHTML = '';              privtext.innerHTML = '';
             versiontext.innerHTML = '';  
         }          }
     }      }
     return;      return;
Line 13525  END Line 9224  END
   
 }  }
   
 sub toggle_display_js {  sub credits_js {
     return <<"END";      return <<"END";
   
 <script type="text/javascript">  <script type="text/javascript">
 // <![CDATA[  // <![CDATA[
   
 function toggleDisplay(domForm,caller) {  function toggleCredits(domForm) {
     if (document.getElementById(caller)) {      if (document.getElementById('credits')) {
         var divitem = document.getElementById(caller);          creditsitem = document.getElementById('credits');
         var optionsElement = domForm.coursecredits;          var creditsLength = domForm.coursecredits.length;
         var checkval = 1;          if (creditsLength) {
         var dispval = 'block';  
         if (caller == 'emailoptions') {  
             optionsElement = domForm.cancreate_email;   
         }  
         if (caller == 'studentsubmission') {  
             optionsElement = domForm.postsubmit;  
         }  
         if (caller == 'cloneinstcode') {  
             optionsElement = domForm.canclone;  
             checkval = 'instcode';  
         }  
         if (optionsElement.length) {  
             var currval;              var currval;
             for (var i=0; i<optionsElement.length; i++) {              for (var i=0; i<creditsLength; i++) {
                 if (optionsElement[i].checked) {                  if (domForm.coursecredits[i].checked) {
                    currval = optionsElement[i].value;                     currval = domForm.coursecredits[i].value;
                 }                  }
             }              }
             if (currval == checkval) {              if (currval == 1) {
                 divitem.style.display = dispval;                  creditsitem.style.display = 'block';
             } else {              } else {
                 divitem.style.display = 'none';                  creditsitem.style.display = 'none';
             }              }
         }          }
     }      }
Line 13578  sub captcha_phrases { Line 9265  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)',  
     );      );
 }  }
   
 sub devalidate_remote_domconfs {  
     my ($dom,$cachekeys) = @_;  
     return unless (ref($cachekeys) eq 'HASH');  
     my %servers = &Apache::lonnet::internet_dom_servers($dom);  
     my %thismachine;  
     map { $thismachine{$_} = 1; } &Apache::lonnet::current_machine_ids();  
     my @posscached = ('domainconfig','domdefaults','usersessions','directorysrch');  
     if (keys(%servers)) {  
         foreach my $server (keys(%servers)) {  
             next if ($thismachine{$server});  
             my @cached;  
             foreach my $name (@posscached) {  
                 if ($cachekeys->{$name}) {  
                     push(@cached,&escape($name).':'.&escape($dom));  
                 }  
             }  
             if (@cached) {  
                 &Apache::lonnet::remote_devalidate_cache($server,\@cached);  
             }  
         }  
     }  
     return;  
 }  
   
 1;  1;

Removed from v.1.160.6.89  
changed lines
  Added in v.1.199


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