Diff for /loncom/interface/domainprefs.pm between versions 1.427 and 1.447.2.6

version 1.427, 2023/06/20 14:03:52 version 1.447.2.6, 2025/03/15 01:07:42
Line 95  about default quota sizes for portfolio Line 95  about default quota sizes for portfolio
 institutional affiliation in the domain (e.g., Faculty, Staff, Student etc.),   institutional affiliation in the domain (e.g., Faculty, Staff, Student etc.), 
 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.
 default quota sizes for Authoring Spaces.  
   
 Outputs: 1  Outputs: 1
   
Line 223  sub handler { Line 222  sub handler {
                 'coursedefaults','usersessions','loadbalancing',                  'coursedefaults','usersessions','loadbalancing',
                 'requestauthor','selfenrollment','inststatus',                  'requestauthor','selfenrollment','inststatus',
                 'ltitools','toolsec','ssl','trust','lti','ltisec',                  'ltitools','toolsec','ssl','trust','lti','ltisec',
                 'privacy','passwords','proctoring','wafproxy','ipaccess'],$dom);                  'privacy','passwords','wafproxy',
                   'ipaccess','authordefaults'],$dom);
     my %encconfig =      my %encconfig =
         &Apache::lonnet::get_dom('encconfig',['ltitools','lti','proctoring','linkprot'],$dom,undef,1);          &Apache::lonnet::get_dom('encconfig',['ltitools','lti','linkprot'],$dom,undef,1);
     my ($checked_is_home,$is_home);      my ($checked_is_home,$is_home);
     if (ref($domconfig{'ltitools'}) eq 'HASH') {      if (ref($domconfig{'ltitools'}) eq 'HASH') {
         if (ref($encconfig{'ltitools'}) eq 'HASH') {          if (ref($encconfig{'ltitools'}) eq 'HASH') {
Line 288  sub handler { Line 288  sub handler {
             }              }
         }          }
     }      }
     if (ref($domconfig{'proctoring'}) eq 'HASH') {  
         if (ref($encconfig{'proctoring'}) eq 'HASH') {  
             foreach my $provider (keys(%{$domconfig{'proctoring'}})) {  
                 if ((ref($domconfig{'proctoring'}{$provider}) eq 'HASH') &&  
                     (ref($encconfig{'proctoring'}{$provider}) eq 'HASH')) {  
                     foreach my $item ('key','secret') {  
                         $domconfig{'proctoring'}{$provider}{$item} = $encconfig{'proctoring'}{$provider}{$item};  
                     }  
                 }  
             }  
         }  
     }  
     my @prefs_order = ('rolecolors','login','ipaccess','defaults','wafproxy','passwords',      my @prefs_order = ('rolecolors','login','ipaccess','defaults','wafproxy','passwords',
                        'quotas','autoenroll','autoupdate','autocreate','directorysrch',                         'quotas','autoenroll','autoupdate','autocreate','directorysrch',
                        'contacts','privacy','usercreation','selfcreation',                         'contacts','privacy','usercreation','selfcreation',
                        'usermodification','scantron','requestcourses','requestauthor',                         'usermodification','scantron','requestcourses','requestauthor',
                        'coursecategories','serverstatuses','helpsettings','coursedefaults',                         'coursecategories','serverstatuses','helpsettings','coursedefaults',
                        'ltitools','proctoring','selfenrollment','usersessions','ssl',                         'authordefaults','ltitools','selfenrollment',
                        'trust','lti');                         'usersessions','ssl','trust','lti');
     my %existing;      my %existing;
     if (ref($domconfig{'loadbalancing'}) eq 'HASH') {      if (ref($domconfig{'loadbalancing'}) eq 'HASH') {
         %existing = %{$domconfig{'loadbalancing'}};          %existing = %{$domconfig{'loadbalancing'}};
Line 382  sub handler { Line 370  sub handler {
                       modify => \&modify_passwords,                        modify => \&modify_passwords,
                     },                      },
         'quotas' =>           'quotas' => 
                     { text => 'Blogs, personal pages/timezones, webDAV/quotas, portfolio',                      { text => 'Blogs, personal pages/timezones, portfolio/quotas',
                       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 => 'Portfolio quota (MB)',}],
                       print => \&print_quotas,                        print => \&print_quotas,
                       modify => \&modify_quotas,                        modify => \&modify_quotas,
                     },                      },
Line 472  sub handler { Line 460  sub handler {
                     header => [{col1 => 'Target user has role',                      header => [{col1 => 'Target user has role',
                                 col2 => 'User information updatable in author context'},                                  col2 => 'User information updatable in author context'},
                                {col1 => 'Target user has role',                                 {col1 => 'Target user has role',
                                   col2 => 'User information updatable by co-author manager'},
                                  {col1 => 'Target user has role',
                                 col2 => 'User information updatable in course context'}],                                  col2 => 'User information updatable in course context'}],
                     print => \&print_usermodification,                      print => \&print_usermodification,
                     modify => \&modify_usermodification,                      modify => \&modify_usermodification,
Line 573  sub handler { Line 563  sub handler {
                   header => [{col1 => 'Role assigned in different domain',                    header => [{col1 => 'Role assigned in different domain',
                               col2 => 'Approval options'},                                col2 => 'Approval options'},
                              {col1 => 'Role assigned in different domain to user of type',                               {col1 => 'Role assigned in different domain to user of type',
                               col2 => 'User information available in that domain'},                                col2 => 'User information available in that domain'}],
                              {col1 => "Role assigned in user's domain",  
                               col2 => 'Information viewable by privileged user'},  
                              {col1 => "Role assigned in user's domain",  
                               col2 => 'Information viewable by unprivileged user'}],  
                   print => \&print_privacy,                    print => \&print_privacy,
                   modify => \&modify_privacy,                    modify => \&modify_privacy,
                  },                   },
Line 616  sub handler { Line 602  sub handler {
                   print => \&print_ltitools,                    print => \&print_ltitools,
                   modify => \&modify_ltitools,                    modify => \&modify_ltitools,
                  },                   },
         'proctoring' =>  
                  {text => 'Remote Proctoring Integration',  
                   help => 'Domain_Configuration_Proctoring',  
                   header => [{col1 => 'Name',  
                               col2 => 'Configuration'}],  
                   print => \&print_proctoring,  
                   modify => \&modify_proctoring,  
                  },  
         'ssl' =>          'ssl' =>
                  {text  => 'LON-CAPA Network (SSL)',                   {text  => 'LON-CAPA Network (SSL)',
                   help  => 'Domain_Configuration_Network_SSL',                    help  => 'Domain_Configuration_Network_SSL',
Line 669  sub handler { Line 647  sub handler {
                               col2 => 'Settings'},                                col2 => 'Settings'},
                              {col1 => 'Rules for shared secrets',                               {col1 => 'Rules for shared secrets',
                               col2 => 'Settings'},                                col2 => 'Settings'},
                                {col1 => 'Link Protectors in Courses',
                                 col2 => 'Values'},
                              {col1 => 'Link Protectors',                               {col1 => 'Link Protectors',
                               col2 => 'Settings'},                                col2 => 'Settings'},
                              {col1 => 'Consumers',                               {col1 => 'Consumers',
Line 684  sub handler { Line 664  sub handler {
                         print  => \&print_ipaccess,                          print  => \&print_ipaccess,
                         modify => \&modify_ipaccess,                          modify => \&modify_ipaccess,
                        },                         },
           'authordefaults' =>
                               {text => 'Authoring Space defaults',
                                help => 'Domain_Configuration_Author_Defaults',
                                header => [{col1 => 'Defaults which can be overridden by Author',
                                            col2 => 'Settings',},
                                           {col1 => 'Defaults which can be overridden by a Dom. Coord.',
                                            col2 => 'Settings',},],
                                print => \&print_authordefaults,
                                modify => \&modify_authordefaults,
                               },
     );      );
     if (keys(%servers) > 1) {      if (keys(%servers) > 1) {
         $prefs{'login'}  = { text   => 'Log-in page options',          $prefs{'login'}  = { text   => 'Log-in page options',
Line 873  sub process_changes { Line 863  sub process_changes {
         $output = &modify_loadbalancing($dom,%domconfig);          $output = &modify_loadbalancing($dom,%domconfig);
     } elsif ($action eq 'ltitools') {      } elsif ($action eq 'ltitools') {
         $output = &modify_ltitools($r,$dom,$action,$lastactref,%domconfig);          $output = &modify_ltitools($r,$dom,$action,$lastactref,%domconfig);
     } elsif ($action eq 'proctoring') {  
         $output = &modify_proctoring($r,$dom,$action,$lastactref,%domconfig);  
     } elsif ($action eq 'ssl') {      } elsif ($action eq 'ssl') {
         $output = &modify_ssl($dom,$lastactref,%domconfig);          $output = &modify_ssl($dom,$lastactref,%domconfig);
     } elsif ($action eq 'trust') {      } elsif ($action eq 'trust') {
Line 889  sub process_changes { Line 877  sub process_changes {
         $output = &modify_wafproxy($dom,$action,$lastactref,%domconfig);          $output = &modify_wafproxy($dom,$action,$lastactref,%domconfig);
     } elsif ($action eq 'ipaccess') {      } elsif ($action eq 'ipaccess') {
         $output = &modify_ipaccess($dom,$lastactref,%domconfig);          $output = &modify_ipaccess($dom,$lastactref,%domconfig);
       } elsif ($action eq 'authordefaults') {
           $output = &modify_authordefaults($dom,$lastactref,%domconfig);
     }      }
     return $output;      return $output;
 }  }
Line 924  sub print_config_box { Line 914  sub print_config_box {
     } elsif ($action eq 'lti') {      } elsif ($action eq 'lti') {
         $output .= &passwords_javascript('ltisecrets')."\n".          $output .= &passwords_javascript('ltisecrets')."\n".
                    &lti_javascript($dom,$settings);                     &lti_javascript($dom,$settings);
     } elsif ($action eq 'proctoring') {  
         $output .= &proctoring_javascript($settings);  
     } elsif ($action eq 'wafproxy') {      } elsif ($action eq 'wafproxy') {
         $output .= &wafproxy_javascript($dom);          $output .= &wafproxy_javascript($dom);
     } elsif ($action eq 'autoupdate') {      } elsif ($action eq 'autoupdate') {
Line 936  sub print_config_box { Line 924  sub print_config_box {
         $output .= &saml_javascript();          $output .= &saml_javascript();
     } elsif ($action eq 'ipaccess') {      } elsif ($action eq 'ipaccess') {
         $output .= &ipaccess_javascript($settings);          $output .= &ipaccess_javascript($settings);
       } elsif ($action eq 'authordefaults') {
           $output .= &authordefaults_javascript();
     }      }
     $output .=      $output .=
          '<table class="LC_nested_outer">           '<table class="LC_nested_outer">
Line 978  sub print_config_box { Line 968  sub print_config_box {
             ($action eq 'selfenrollment') || ($action eq 'usersessions') || ($action eq 'ssl') ||              ($action eq 'selfenrollment') || ($action eq 'usersessions') || ($action eq 'ssl') ||
             ($action eq 'directorysrch') || ($action eq 'trust') || ($action eq 'helpsettings') ||              ($action eq 'directorysrch') || ($action eq 'trust') || ($action eq 'helpsettings') ||
             ($action eq 'contacts') || ($action eq 'privacy') || ($action eq 'wafproxy') ||              ($action eq 'contacts') || ($action eq 'privacy') || ($action eq 'wafproxy') ||
             ($action eq 'lti') || ($action eq 'ltitools')) {              ($action eq 'lti') || ($action eq 'ltitools') || ($action eq 'authordefaults')) {
             $output .= $item->{'print'}->('top',$dom,$settings,\$rowtotal);              $output .= $item->{'print'}->('top',$dom,$settings,\$rowtotal);
         } elsif ($action eq 'passwords') {          } elsif ($action eq 'passwords') {
             $output .= $item->{'print'}->('top',$dom,$confname,$settings,\$rowtotal);              $output .= $item->{'print'}->('top',$dom,$confname,$settings,\$rowtotal);
Line 1014  sub print_config_box { Line 1004  sub print_config_box {
             ($action eq 'selfcreation') || ($action eq 'selfenrollment') ||              ($action eq 'selfcreation') || ($action eq 'selfenrollment') ||
             ($action eq 'usersessions') || ($action eq 'coursecategories') ||               ($action eq 'usersessions') || ($action eq 'coursecategories') || 
             ($action eq 'trust') || ($action eq 'contacts') || ($action eq 'defaults') ||              ($action eq 'trust') || ($action eq 'contacts') || ($action eq 'defaults') ||
             ($action eq 'privacy') || ($action eq 'passwords') || ($action eq 'lti') ||              ($action eq 'passwords') || ($action eq 'lti') || ($action eq 'ltitools') ||
             ($action eq 'ltitools')) {              ($action eq 'usermodification')) {
             if ($action eq 'coursecategories') {              if ($action eq 'coursecategories') {
                 $output .= &print_coursecategories('middle',$dom,$item,$settings,\$rowtotal);                  $output .= &print_coursecategories('middle',$dom,$item,$settings,\$rowtotal);
                 $colspan = ' colspan="2"';                  $colspan = ' colspan="2"';
Line 1023  sub print_config_box { Line 1013  sub print_config_box {
                 $output .= $item->{'print'}->('shared',$dom,$settings,\$rowtotal);                  $output .= $item->{'print'}->('shared',$dom,$settings,\$rowtotal);
             } elsif ($action eq 'passwords') {              } elsif ($action eq 'passwords') {
                 $output .= $item->{'print'}->('middle',$dom,$confname,$settings,\$rowtotal);                  $output .= $item->{'print'}->('middle',$dom,$confname,$settings,\$rowtotal);
               } elsif ($action eq 'lti') {
                   $output .= $item->{'print'}->('upper',$dom,$settings,\$rowtotal).'
                              </table>
                             </td>
                            </tr>
                            <tr>
                             <td>
                             <table class="LC_nested">
                              <tr class="LC_info_row">
                               <td class="LC_left_item"'.$colspan.'>'.&mt($item->{'header'}->[2]->{'col1'}).'</td>
                               <td class="LC_right_item">'.&mt($item->{'header'}->[2]->{'col2'}).'</td>
                              </tr>'."\n".
                              $item->{'print'}->('middle',$dom,$settings,\$rowtotal);
             } else {              } else {
                 $output .= $item->{'print'}->('middle',$dom,$settings,\$rowtotal);                  $output .= $item->{'print'}->('middle',$dom,$settings,\$rowtotal);
             }              }
Line 1055  sub print_config_box { Line 1058  sub print_config_box {
               <td class="LC_right_item"'.$colspan.'>'.&mt($item->{'header'}->[8]->{'col2'}).'</td></tr>'.                <td class="LC_right_item"'.$colspan.'>'.&mt($item->{'header'}->[8]->{'col2'}).'</td></tr>'.
                            $item->{'print'}->('bottom',$dom,$settings,\$rowtotal);                             $item->{'print'}->('bottom',$dom,$settings,\$rowtotal);
             } else {              } else {
                   my $hdridx = 2;
                   if ($action eq 'lti') {
                       $hdridx = 3;
                   }
                 $output .= '                  $output .= '
            </table>             </table>
           </td>            </td>
Line 1063  sub print_config_box { Line 1070  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'}->[2]->{'col1'}).'</td>                <td class="LC_left_item"'.$colspan.'>'.&mt($item->{'header'}->[$hdridx]->{'col1'}).'</td>
               <td class="LC_right_item">'.&mt($item->{'header'}->[2]->{'col2'}).'</td>                <td class="LC_right_item">'.&mt($item->{'header'}->[$hdridx]->{'col2'}).'</td>
              </tr>'."\n";               </tr>'."\n";
                 if ($action eq 'coursecategories') {                  if ($action eq 'coursecategories') {
                     $output .= &print_coursecategories('bottom',$dom,$item,$settings,\$rowtotal);                      $output .= &print_coursecategories('bottom',$dom,$item,$settings,\$rowtotal);
                 } elsif (($action eq 'contacts') || ($action eq 'privacy') ||                   } elsif (($action eq 'contacts') || ($action eq 'passwords') || 
                          ($action eq 'passwords') || ($action eq 'lti')) {                           ($action eq 'lti')) {
                     if ($action eq 'passwords') {                      if ($action eq 'passwords') {
                         $output .= $item->{'print'}->('lower',$dom,$confname,$settings,\$rowtotal);                          $output .= $item->{'print'}->('lower',$dom,$confname,$settings,\$rowtotal);
                     } else {                      } else {
                         $output .= $item->{'print'}->('lower',$dom,$settings,\$rowtotal);                          $output .= $item->{'print'}->('lower',$dom,$settings,\$rowtotal);
                     }                      }
                       $hdridx ++;
                     $output .= '                      $output .= '
              </tr>               </tr>
             </table>              </table>
Line 1084  sub print_config_box { Line 1092  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'.$leftnobr.'"'.$colspan.'>'.&mt($item->{'header'}->[3]->{'col1'}).'</td>                <td class="LC_left_item'.$leftnobr.'"'.$colspan.'>'.&mt($item->{'header'}->[$hdridx]->{'col1'}).'</td>
               <td class="LC_right_item"'.$colspan.'>'.&mt($item->{'header'}->[3]->{'col2'}).'</td></tr>'."\n";                <td class="LC_right_item"'.$colspan.'>'.&mt($item->{'header'}->[$hdridx]->{'col2'}).'</td></tr>'."\n";
                     if ($action eq 'passwords') {                      if ($action eq 'passwords') {
                         $output .= $item->{'print'}->('bottom',$dom,$confname,$settings,\$rowtotal);                          $output .= $item->{'print'}->('bottom',$dom,$confname,$settings,\$rowtotal);
                     } else {                      } else {
Line 1101  sub print_config_box { Line 1109  sub print_config_box {
                 }                  }
             }              }
             $rowtotal ++;              $rowtotal ++;
         } elsif (($action eq 'usermodification') || ($action eq 'coursedefaults') ||          } elsif (($action eq 'coursedefaults') || ($action eq 'authordefaults') ||
                  ($action eq 'directorysrch') || ($action eq 'helpsettings') ||                   ($action eq 'directorysrch') || ($action eq 'helpsettings') ||
                  ($action eq 'wafproxy')) {                   ($action eq 'wafproxy') || ($action eq 'privacy')) {
             $output .= $item->{'print'}->('bottom',$dom,$settings,\$rowtotal);              $output .= $item->{'print'}->('bottom',$dom,$settings,\$rowtotal);
         } elsif ($action eq 'scantron') {          } elsif ($action eq 'scantron') {
             $output .= $item->{'print'}->($r,'bottom',$dom,$confname,$settings,\$rowtotal);              $output .= $item->{'print'}->($r,'bottom',$dom,$confname,$settings,\$rowtotal);
Line 1306  sub print_config_box { Line 1314  sub print_config_box {
             $output .= &print_quotas($dom,$settings,\$rowtotal,$action);              $output .= &print_quotas($dom,$settings,\$rowtotal,$action);
         } elsif (($action eq 'autoenroll') || ($action eq 'autocreate') ||           } elsif (($action eq 'autoenroll') || ($action eq 'autocreate') || 
                  ($action eq 'serverstatuses') || ($action eq 'loadbalancing') ||                    ($action eq 'serverstatuses') || ($action eq 'loadbalancing') || 
                  ($action eq 'proctoring') || ($action eq 'ipaccess')) {                   ($action eq 'ipaccess')) {
             $output .= $item->{'print'}->($dom,$settings,\$rowtotal);              $output .= $item->{'print'}->($dom,$settings,\$rowtotal);
         }          }
     }      }
Line 1973  sub commblocktype_text { Line 1981  sub commblocktype_text {
         'passwd' => 'Change Password',          'passwd' => 'Change Password',
         'grades' => 'Gradebook',          'grades' => 'Gradebook',
         'search' => 'Course search',          'search' => 'Course search',
           'index'  => 'Course content index',
         'wishlist' => 'Stored links',          'wishlist' => 'Stored links',
         'annotate' => 'Annotations',          'annotate' => 'Annotations',
     );      );
     my $typeorder = ['com','chat','boards','port','groups','blogs','about','wishlist','printout','grades','search','annotate','passwd'];      my $typeorder = ['com','chat','boards','port','groups','blogs','about','wishlist','printout','grades','search','index','annotate','passwd'];
     return ($typeorder,\%types);      return ($typeorder,\%types);
 }  }
   
Line 1985  sub print_rolecolors { Line 1994  sub print_rolecolors {
     my %choices = &color_font_choices();      my %choices = &color_font_choices();
     my @bgs = ('pgbg','tabbg','sidebg');      my @bgs = ('pgbg','tabbg','sidebg');
     my @links = ('link','alink','vlink');      my @links = ('link','alink','vlink');
     my @images = ('img');      my @images = ();
     my %alt_text = &Apache::lonlocal::texthash(img => "Banner for $role role");      my %alt_text = &Apache::lonlocal::texthash(img => "Banner for $role role");
     my %designhash = &Apache::loncommon::get_domainconf($dom);      my %designhash = &Apache::loncommon::get_domainconf($dom);
     my %defaultdesign = %Apache::loncommon::defaultdesign;      my %defaultdesign = %Apache::loncommon::defaultdesign;
Line 1993  sub print_rolecolors { Line 2002  sub print_rolecolors {
     my %defaults = &role_defaults($role,\@bgs,\@links,\@images);      my %defaults = &role_defaults($role,\@bgs,\@links,\@images);
     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 '') {  
                 $designs{'img'} = $settings->{$role}->{'img'};  
                 $is_custom{'img'} = 1;  
             }  
             if ($settings->{$role}->{'font'} ne '') {              if ($settings->{$role}->{'font'} ne '') {
                 $designs{'font'} = $settings->{$role}->{'font'};                  $designs{'font'} = $settings->{$role}->{'font'};
                 $is_custom{'font'} = 1;                  $is_custom{'font'} = 1;
Line 2019  sub print_rolecolors { Line 2024  sub print_rolecolors {
             }              }
         }          }
     } else {      } else {
         if ($designhash{$dom.'.'.$role.'.img'} ne '') {  
             $designs{img} = $designhash{$dom.'.'.$role.'.img'};  
             $is_custom{'img'} = 1;  
         }  
         if ($designhash{$dom.'.'.$role.'.fontmenu'} ne '') {          if ($designhash{$dom.'.'.$role.'.fontmenu'} ne '') {
             $designs{fontmenu} = $designhash{$dom.'.'.$role.'.fontmenu'};              $designs{fontmenu} = $designhash{$dom.'.'.$role.'.fontmenu'};
             $is_custom{'fontmenu'} = 1;               $is_custom{'fontmenu'} = 1; 
Line 2072  sub role_defaults { Line 2073  sub role_defaults {
         }          }
     } else {      } else {
         %defaults = (          %defaults = (
                        img => $defaultdesign{$role.'.img'},  
                        font => $defaultdesign{$role.'.font'},                         font => $defaultdesign{$role.'.font'},
                        fontmenu => $defaultdesign{$role.'.fontmenu'},                         fontmenu => $defaultdesign{$role.'.fontmenu'},
                     );                      );
Line 2397  sub print_quotas { Line 2397  sub print_quotas {
     } else {      } else {
         $context = $action;          $context = $action;
     }      }
     my ($datatable,$defaultquota,$authorquota,@usertools,@options,%validations);      my ($datatable,$defaultquota,@usertools,@options,%validations);
     my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom);      my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom);
     my $typecount = 0;      my $typecount = 0;
     my ($css_class,%titles);      my ($css_class,%titles);
Line 2411  sub print_quotas { Line 2411  sub print_quotas {
         @options = ('norequest','approval','automatic');          @options = ('norequest','approval','automatic');
         %titles = &authorrequest_titles();          %titles = &authorrequest_titles();
     } else {      } else {
         @usertools = ('aboutme','blog','webdav','portfolio','timezone');          @usertools = ('aboutme','blog','portfolio','portaccess','timezone');
         %titles = &tool_titles();          %titles = &tool_titles();
     }      }
     if (ref($types) eq 'ARRAY') {      if (ref($types) eq 'ARRAY') {
         foreach my $type (@{$types}) {          foreach my $type (@{$types}) {
             my ($currdefquota,$currauthorquota);              my $currdefquota;
             unless (($context eq 'requestcourses') ||              unless (($context eq 'requestcourses') ||
                     ($context eq 'requestauthor')) {                      ($context eq 'requestauthor')) {
                 if (ref($settings) eq 'HASH') {                  if (ref($settings) eq 'HASH') {
Line 2425  sub print_quotas { Line 2425  sub print_quotas {
                     } else {                      } else {
                         $currdefquota = $settings->{$type};                          $currdefquota = $settings->{$type};
                     }                      }
                     if (ref($settings->{authorquota}) eq 'HASH') {  
                         $currauthorquota = $settings->{authorquota}->{$type};  
                     }  
                 }                  }
             }              }
             if (defined($usertypes->{$type})) {              if (defined($usertypes->{$type})) {
Line 2545  sub print_quotas { Line 2542  sub print_quotas {
                         ($context eq 'requestauthor')) {                          ($context eq 'requestauthor')) {
                     $datatable .=                       $datatable .= 
                               '<td class="LC_right_item">'.                                '<td class="LC_right_item">'.
                               '<span class="LC_nobreak">'.&mt('Portfolio').':&nbsp;'.                                '<span class="LC_nobreak">'.
                               '<input type="text" name="quota_'.$type.                                '<input type="text" name="quota_'.$type.
                               '" value="'.$currdefquota.                                '" value="'.$currdefquota.
                               '" size="5" /></span>'.('&nbsp;' x 2).  
                               '<span class="LC_nobreak">'.&mt('Authoring').':&nbsp;'.  
                               '<input type="text" name="authorquota_'.$type.  
                               '" value="'.$currauthorquota.  
                               '" size="5" /></span></td>';                                '" size="5" /></span></td>';
                 }                  }
                 $datatable .= '</tr>';                  $datatable .= '</tr>';
Line 2560  sub print_quotas { Line 2553  sub print_quotas {
     }      }
     unless (($context eq 'requestcourses') || ($context eq 'requestauthor')) {      unless (($context eq 'requestcourses') || ($context eq 'requestauthor')) {
         $defaultquota = '20';          $defaultquota = '20';
         $authorquota = '500';  
         if (ref($settings) eq 'HASH') {          if (ref($settings) eq 'HASH') {
             if (ref($settings->{'defaultquota'}) eq 'HASH') {              if (ref($settings->{'defaultquota'}) eq 'HASH') {
                 $defaultquota = $settings->{'defaultquota'}->{'default'};                  $defaultquota = $settings->{'defaultquota'}->{'default'};
             } elsif (defined($settings->{'default'})) {              } elsif (defined($settings->{'default'})) {
                 $defaultquota = $settings->{'default'};                  $defaultquota = $settings->{'default'};
             }              }
             if (ref($settings->{'authorquota'}) eq 'HASH') {  
                 $authorquota = $settings->{'authorquota'}->{'default'};  
             }  
         }          }
     }      }
     $typecount ++;      $typecount ++;
Line 2681  sub print_quotas { Line 2670  sub print_quotas {
     $datatable .= '</td>';      $datatable .= '</td>';
     unless (($context eq 'requestcourses') || ($context eq 'requestauthor')) {      unless (($context eq 'requestcourses') || ($context eq 'requestauthor')) {
         $datatable .= '<td class="LC_right_item">'.          $datatable .= '<td class="LC_right_item">'.
                       '<span class="LC_nobreak">'.&mt('Portfolio').':&nbsp;'.                        '<span class="LC_nobreak">'.
                       '<input type="text" name="defaultquota" value="'.                        '<input type="text" name="defaultquota" value="'.
                       $defaultquota.'" size="5" /></span>'.('&nbsp;' x2).                        $defaultquota.'" size="5" /></span></td>';
                       '<span class="LC_nobreak">'.&mt('Authoring').':&nbsp;'.  
                       '<input type="text" name="authorquota" value="'.  
                       $authorquota.'" size="5" /></span></td>';  
     }      }
     $datatable .= '</tr>';      $datatable .= '</tr>';
     $typecount ++;      $typecount ++;
Line 3942  $jstext Line 3928  $jstext
 ENDSCRIPT  ENDSCRIPT
 }  }
   
   sub authordefaults_javascript {
       my %alert = &Apache::lonlocal::texthash (
                       reqd => 'Warning: at least one editor needs to be available.',
                       rest => 'Unchecking this editor disallowed while others unchecked.',
       );
       &js_escape(\%alert);
       return <<"ENDSCRIPT";
   <script type="text/javascript">
   // <![CDATA[
   
   function checkEditors(form,checkbox,current) {
       if (form.elements[checkbox].length != undefined) {
           var count = 0;
           for (var i=0; i<form.elements[checkbox].length; i++) {
               if (form.elements[checkbox][i].checked) {
                   count ++;
               }
           }
           if (count == 0) {
               if (current.type =='radio') {
                   current.checked = true;
                   alert('$alert{reqd}\\n$alert{rest}');
               }
           }
       }
       return;
   }
   // ]]>
   </script>
   
   ENDSCRIPT
   }
   
 sub print_autoenroll {  sub print_autoenroll {
     my ($dom,$settings,$rowtotal) = @_;      my ($dom,$settings,$rowtotal) = @_;
     my $autorun = &Apache::lonnet::auto_run(undef,$dom),      my $autorun = &Apache::lonnet::auto_run(undef,$dom),
Line 5352  sub print_ltitools { Line 5371  sub print_ltitools {
     return $datatable;      return $datatable;
 }  }
   
 sub ltitools_names {  
     my %lt = &Apache::lonlocal::texthash(  
                                           'title'          => 'Title',  
                                           'version'        => 'Version',  
                                           'msgtype'        => 'Message Type',  
                                           'sigmethod'      => 'Signature Method',  
                                           'url'            => 'URL',  
                                           'key'            => 'Key',  
                                           'lifetime'       => 'Nonce lifetime (s)',  
                                           'secret'         => 'Secret',  
                                           'icon'           => 'Icon',  
                                           'user'           => 'User',  
                                           'fullname'       => 'Full Name',  
                                           'firstname'      => 'First Name',  
                                           'lastname'       => 'Last Name',  
                                           'email'          => 'E-mail',  
                                           'roles'          => 'Role',  
                                           'window'         => 'Window',  
                                           'tab'            => 'Tab',  
                                           'iframe'         => 'iFrame',  
                                           'height'         => 'Height',  
                                           'width'          => 'Width',  
                                           'linktext'       => 'Default Link Text',  
                                           'explanation'    => 'Default Explanation',  
                                           'passback'       => 'Tool can return grades:',  
                                           'roster'         => 'Tool can retrieve roster:',  
                                           'crstarget'      => 'Display target',  
                                           'crslabel'       => 'Course label',  
                                           'crstitle'       => 'Course title',  
                                           'crslinktext'    => 'Link Text',  
                                           'crsexplanation' => 'Explanation',  
                                           'crsappend'      => 'Provider URL',  
                                         );  
     return %lt;  
 }  
   
 sub secrets_form {  sub secrets_form {
     my ($dom,$context,$encrypt,$privkeys,$rowtotal) = @_;      my ($dom,$context,$encrypt,$privkeys,$rowtotal) = @_;
     my @ids=&Apache::lonnet::current_machine_ids();      my @ids=&Apache::lonnet::current_machine_ids();
Line 6143  sub print_lti { Line 6126  sub print_lti {
     my ($position,$dom,$settings,$rowtotal) = @_;      my ($position,$dom,$settings,$rowtotal) = @_;
     my $itemcount = 1;      my $itemcount = 1;
     my ($datatable,$css_class);      my ($datatable,$css_class);
     my (%rules,%encrypt,%privkeys,%linkprot);      my (%rules,%encrypt,%privkeys,%linkprot,%suggestions);
     if (ref($settings) eq 'HASH') {      if (ref($settings) eq 'HASH') {
         if ($position eq 'top') {          if ($position eq 'top') {
             if (exists($settings->{'encrypt'})) {              if (exists($settings->{'encrypt'})) {
Line 6166  sub print_lti { Line 6149  sub print_lti {
                     }                      }
                 }                  }
             }              }
         } elsif ($position eq 'middle') {          } elsif ($position eq 'upper') {
             if (exists($settings->{'rules'})) {              if (exists($settings->{'rules'})) {
                 if (ref($settings->{'rules'}) eq 'HASH') {                  if (ref($settings->{'rules'}) eq 'HASH') {
                     %rules = %{$settings->{'rules'}};                      %rules = %{$settings->{'rules'}};
                 }                  }
             }              }
           } elsif ($position eq 'middle') {
               if (exists($settings->{'suggested'})) {
                   if (ref($settings->{'suggested'}) eq 'HASH') {
                       %suggestions = %{$settings->{'suggested'}};
                   }
               }
         } elsif ($position eq 'lower') {          } elsif ($position eq 'lower') {
             if (exists($settings->{'linkprot'})) {              if (exists($settings->{'linkprot'})) {
                 if (ref($settings->{'linkprot'}) eq 'HASH') {                  if (ref($settings->{'linkprot'}) eq 'HASH') {
Line 6182  sub print_lti { Line 6171  sub print_lti {
                 }                  }
             }              }
         } else {          } else {
             foreach my $key ('encrypt','private','rules','linkprot') {              foreach my $key ('encrypt','private','rules','linkprot','suggestions') {
                 if (exists($settings->{$key})) {                  if (exists($settings->{$key})) {
                     delete($settings->{$key});                      delete($settings->{$key});
                 }                  }
Line 6191  sub print_lti { Line 6180  sub print_lti {
     }      }
     if ($position eq 'top') {      if ($position eq 'top') {
         $datatable = &secrets_form($dom,'ltisec',\%encrypt,\%privkeys,$rowtotal);          $datatable = &secrets_form($dom,'ltisec',\%encrypt,\%privkeys,$rowtotal);
     } elsif ($position eq 'middle') {      } elsif ($position eq 'upper') {
         $datatable = &password_rules('ltisecrets',\$itemcount,\%rules);          $datatable = &password_rules('ltisecrets',\$itemcount,\%rules);
         $$rowtotal += $itemcount;          $$rowtotal += $itemcount;
       } elsif ($position eq 'middle') {
           $datatable = &linkprot_suggestions(\%suggestions,\$itemcount);
           $$rowtotal += $itemcount;
     } elsif ($position eq 'lower') {      } elsif ($position eq 'lower') {
          $datatable .= &Apache::courseprefs::print_linkprotection($dom,'',$settings,$rowtotal,'','','domain');          $datatable .= &Apache::courseprefs::print_linkprotection($dom,'',$settings,$rowtotal,'','','domain');
     } else {      } else {
         my ($switchserver,$switchmessage);          my ($switchserver,$switchmessage);
         $switchserver = &check_switchserver($dom);          $switchserver = &check_switchserver($dom);
Line 6782  sub ltimenu_titles { Line 6774  sub ltimenu_titles {
     );      );
 }  }
   
   sub linkprot_suggestions {
       my ($suggested,$itemcount) = @_;
       my $count = 0;
       my $next = 1;
       my %lt = &Apache::lonlocal::texthash(
                                             'name' => 'Suggested Launcher',
                                             'info' => 'Recommendations',
                                           );
       my ($datatable,$css_class,$dest);
       if (ref($suggested) eq 'HASH') {
           my @current = sort { $a <=> $b } keys(%{$suggested});
           $next += $current[-1];
           for (my $i=0; $i<@current; $i++) {
               my $num = $current[$i];
               my %values;
               if (ref($suggested->{$num}) eq 'HASH') {
                   %values = %{$suggested->{$num}};
               } else {
                   next;
               }
               $css_class = $$itemcount%2?' class="LC_odd_row"':'';
               $datatable .=
                   '<tr '.$css_class.'><td><span class="LC_nobreak">'."\n".
                   '<label><input type="checkbox" name="linkprot_suggested_del" value="'.$i.'" />'."\n".
                   &mt('Delete?').'</label></span></td><td>'."\n".
                   '<div class="LC_floatleft"><fieldset><legend>'.$lt{'name'}.'</legend>'."\n".
                   '<input type="text" size="15" name="linkprot_suggested_name_'.$i.'" value="'.$values{'name'}.'" autocomplete="off" />'."\n".
                   '</fieldset></div>'.
                   '<div class="LC_floatleft"><fieldset><legend>'.$lt{'info'}.'</legend>'."\n".
                   '<textarea cols="55" rows="5" name="linkprot_suggested_info_'.$i.'">'.$values{'info'}.'</textarea>'.
                   '</fieldset></div>'.
                   '<div style="padding:0;clear:both;margin:0;border:0"></div>'."\n".
                   '<input type="hidden" name="linkprot_suggested_id_'.$i.'" value="'.$num.'" /></td></tr>'."\n";
               $$itemcount ++;
           }
       }
       $css_class = $$itemcount%2?' class="LC_odd_row"':'';
       $datatable .= '<tr '.$css_class.'><td><span class="LC_nobreak">'."\n".
                     '<input type="hidden" name="linkprot_suggested_maxnum" value="'.$next.'" />'."\n".
                     '<input type="checkbox" name="linkprot_suggested_add" value="1" />'.&mt('Add').'</span></td>'."\n".
                     '<td>'."\n".
                     '<div class="LC_floatleft"><fieldset><legend>'.$lt{'name'}.'</legend>'."\n".
                     '<input type="text" size="15" name="linkprot_suggested_name_add" value="" autocomplete="off" />'."\n".
                     '</fieldset></div>'.
                     '<div class="LC_floatleft"><fieldset><legend>'.$lt{'info'}.'</legend>'."\n".
                     '<textarea cols="55" rows="5" name="linkprot_suggested_info_add"></textarea>'.
                     '</fieldset></div>'.
                     '<div style="padding:0;clear:both;margin:0;border:0"></div>'."\n".
                     '</td></tr>'."\n";
       return $datatable;
   }
   
 sub print_coursedefaults {  sub print_coursedefaults {
     my ($position,$dom,$settings,$rowtotal) = @_;      my ($position,$dom,$settings,$rowtotal) = @_;
     my ($css_class,$datatable,%checkedon,%checkedoff,%defaultchecked,@toggles);      my ($css_class,$datatable,%checkedon,%checkedoff,%defaultchecked,@toggles);
Line 6789  sub print_coursedefaults { Line 6833  sub print_coursedefaults {
     my %choices =  &Apache::lonlocal::texthash (      my %choices =  &Apache::lonlocal::texthash (
         canuse_pdfforms      => 'Course/Community users can create/upload PDF forms',          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)',
           coursequota          => 'Default cumulative quota for all group portfolio spaces in course (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)',          uselcmath            => 'Math preview uses LON-CAPA previewer (javascript) in place of DragMath (Java)',
Line 6801  sub print_coursedefaults { Line 6846  sub print_coursedefaults {
         ltiauth              => 'Student username in LTI launch of deep-linked URL can be accepted without re-authentication',          ltiauth              => 'Student username in LTI launch of deep-linked URL can be accepted without re-authentication',
         domexttool           => 'External Tools defined in the domain may be used in courses/communities (by type)',          domexttool           => 'External Tools defined in the domain may be used in courses/communities (by type)',
         exttool              => 'External Tools can be defined and configured in courses/communities (by type)',          exttool              => 'External Tools can be defined and configured in courses/communities (by type)',
           crsauthor            => 'Standard LON-CAPA problems can be created within a course/community (by type)',
           crseditors           => 'Available editors for web pages and/or problems created in a course/community',
     );      );
     my %staticdefaults = (      my %staticdefaults = (
                            anonsurvey_threshold => 10,                             anonsurvey_threshold => 10,
                            uploadquota          => 500,                             uploadquota          => 500,
                              coursequota          => 20,
                            postsubmit           => 60,                             postsubmit           => 60,
                            mysqltables          => 172800,                             mysqltables          => 172800,
                            domexttool           => 1,                             domexttool           => 1,
                            exttool              => 0,                             exttool              => 0,
                              crsauthor            => 1,
                              crseditors           => ['edit','xml'],  
                          );                           );
     if ($position eq 'top') {      if ($position eq 'top') {
         %defaultchecked = (          %defaultchecked = (
Line 6922  sub print_coursedefaults { Line 6972  sub print_coursedefaults {
         $itemcount ++;          $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,%defcredits,%curruploadquota,%currcoursequota,
               %deftimeout,%currmysql);
         my $currusecredits = 0;          my $currusecredits = 0;
         my $postsubmitclient = 1;          my $postsubmitclient = 1;
         my $ltiauth = 0;          my $ltiauth = 0;
         my %domexttool;          my %domexttool;
         my %exttool;          my %exttool;
           my %crsauthor;
           my %crseditors;
         my @types = ('official','unofficial','community','textbook','placement');          my @types = ('official','unofficial','community','textbook','placement');
         if (ref($settings) eq 'HASH') {          if (ref($settings) eq 'HASH') {
             if ($settings->{'ltiauth'}) {              if ($settings->{'ltiauth'}) {
Line 6953  sub print_coursedefaults { Line 7006  sub print_coursedefaults {
                     }                      }
                 }                  }
             }              }
               if (ref($settings->{'crsauthor'}) eq 'HASH') {
                   foreach my $type (@types) {
                       if ($settings->{'crsauthor'}->{$type}) {
                           $crsauthor{$type} = ' checked="checked"';
                       }
                   }
               } else {
                   foreach my $type (@types) {
                       if ($staticdefaults{'crsauthor'}) {
                           $crsauthor{$type} = ' checked="checked"';
                       }
                   }
               }
               if (ref($settings->{'crseditors'}) eq 'ARRAY') {
                   foreach my $editor (@{$settings->{'crseditors'}}) {
                       $crseditors{$editor} = ' checked="checked"';
                   }
               } else {
                   foreach my $editor (@{$staticdefaults{'crseditors'}}) {
                       $crseditors{$editor} = ' checked="checked"';
                   }
               }
             $currdefresponder = $settings->{'anonsurvey_threshold'};              $currdefresponder = $settings->{'anonsurvey_threshold'};
             if (ref($settings->{'uploadquota'}) eq 'HASH') {              if (ref($settings->{'uploadquota'}) eq 'HASH') {
                 foreach my $type (keys(%{$settings->{'uploadquota'}})) {                  foreach my $type (keys(%{$settings->{'uploadquota'}})) {
                     $curruploadquota{$type} = $settings->{'uploadquota'}{$type};                      $curruploadquota{$type} = $settings->{'uploadquota'}{$type};
                 }                  }
             }              }
               if (ref($settings->{'coursequota'}) eq 'HASH') {
                   foreach my $type (keys(%{$settings->{'coursequota'}})) {
                       $currcoursequota{$type} = $settings->{'coursequota'}{$type};
                   }
               }
             if (ref($settings->{'coursecredits'}) eq 'HASH') {              if (ref($settings->{'coursecredits'}) eq 'HASH') {
                 foreach my $type (@types) {                  foreach my $type (@types) {
                     next if ($type eq 'community');                      next if ($type eq 'community');
Line 7007  sub print_coursedefaults { Line 7087  sub print_coursedefaults {
                 if ($staticdefaults{'domexttool'}) {                  if ($staticdefaults{'domexttool'}) {
                     $domexttool{$type} = ' checked="checked"';                      $domexttool{$type} = ' checked="checked"';
                 }                  }
                   if ($staticdefaults{'crsauthor'}) {
                       $crsauthor{$type} = ' checked="checked"';
                   }
               }
               foreach my $editor (@{$staticdefaults{'crseditors'}}) {
                   $crseditors{$editor} = ' checked="checked"';
             }              }
         }          }
         if (!$currdefresponder) {          if (!$currdefresponder) {
Line 7018  sub print_coursedefaults { Line 7104  sub print_coursedefaults {
             if ($curruploadquota{$type} eq '') {              if ($curruploadquota{$type} eq '') {
                 $curruploadquota{$type} = $staticdefaults{'uploadquota'};                  $curruploadquota{$type} = $staticdefaults{'uploadquota'};
             }              }
               if ($currcoursequota{$type} eq '') {
                   $currcoursequota{$type} = $staticdefaults{'coursequota'};
               }
         }          }
         $datatable .=          $datatable .=
                 '<tr'.$css_class.'><td><span class="LC_nobreak">'.                  '<tr'.$css_class.'><td><span class="LC_nobreak">'.
Line 7041  sub print_coursedefaults { Line 7130  sub print_coursedefaults {
         }          }
         $datatable .= '</tr></table></td></tr>'."\n";          $datatable .= '</tr></table></td></tr>'."\n";
         $itemcount ++;          $itemcount ++;
           $css_class = $itemcount%2 ? ' class="LC_odd_row"' : '';
           $datatable .= '<tr'.$css_class.'><td><span class="LC_nobreak">'.
                         $choices{'coursequota'}.
                         '</span></td>'.
                         '<td style="text-align: right" class="LC_right_item">'.
                         '<table><tr>';
           foreach my $type (@types) {
               $datatable .= '<td style="text-align: center">'.&mt($type).'<br />'.
                              '<input type="text" name="coursequota_'.$type.'"'.
                              ' value="'.$currcoursequota{$type}.'" size="5" /></td>';
           }
           $datatable .= '</tr></table></td></tr>'."\n";
           $itemcount ++;
         my $onclick = "toggleDisplay(this.form,'credits');";          my $onclick = "toggleDisplay(this.form,'credits');";
         my $display = 'none';          my $display = 'none';
         if ($currusecredits) {          if ($currusecredits) {
Line 7119  sub print_coursedefaults { Line 7221  sub print_coursedefaults {
         foreach my $type (@types) {          foreach my $type (@types) {
             $datatable .= '<td style="text-align: left">'.              $datatable .= '<td style="text-align: left">'.
                           '<span class="LC_nobreak">'.                            '<span class="LC_nobreak">'.
                           '<input type="checkbox" name="domexttool"'.                            '<label><input type="checkbox" name="domexttool"'.
                           ' value="'.$type.'"'.$domexttool{$type}.' />'.                            ' value="'.$type.'"'.$domexttool{$type}.' />'.
                           &mt($type).'</span></td>'."\n";                            &mt($type).'</label></span></td>'."\n";
         }          }
         $datatable .= '</tr></table></td></tr>'."\n";          $datatable .= '</tr></table></td></tr>'."\n";
         $itemcount ++;          $itemcount ++;
Line 7134  sub print_coursedefaults { Line 7236  sub print_coursedefaults {
         foreach my $type (@types) {          foreach my $type (@types) {
             $datatable .= '<td style="text-align: left">'.              $datatable .= '<td style="text-align: left">'.
                           '<span class="LC_nobreak">'.                            '<span class="LC_nobreak">'.
                           '<input type="checkbox" name="exttool"'.                            '<label><input type="checkbox" name="exttool"'.
                           ' value="'.$type.'"'.$exttool{$type}.' />'.                            ' value="'.$type.'"'.$exttool{$type}.' />'.
                           &mt($type).'</span></td>'."\n";                            &mt($type).'</label></span></td>'."\n";
           }
           $datatable .= '</tr></table></td></tr>'."\n";
           $itemcount ++;
           $css_class = $itemcount%2 ? ' class="LC_odd_row"' : '';
           $datatable .= '<tr'.$css_class.'><td><span class="LC_nobreak">'.
                         $choices{'crsauthor'}.
                         '</span></td>'.
                         '<td style="text-align: right" class="LC_right_item">'.
                         '<table><tr>';
           foreach my $type (@types) {
               $datatable .= '<td style="text-align: left">'.
                             '<span class="LC_nobreak">'.
                             '<label><input type="checkbox" name="crsauthor"'.
                             ' value="'.$type.'"'.$crsauthor{$type}.' />'.
                             &mt($type).'</label></span></td>'."\n";
           }
           $datatable .= '</tr></table></td></tr>'."\n";
           $itemcount ++;
           $css_class = $itemcount%2 ? ' class="LC_odd_row"' : '';
           $datatable .= '<tr'.$css_class.'><td><span class="LC_nobreak">'.
                         $choices{'crseditors'}.
                         '</span></td>'.
                         '<td style="text-align: right" class="LC_right_item">'.
                         '<table><tr>';
           my @editors = ('edit','xml','daxe');
           my %editornames = &crseditor_titles();
           foreach my $editor (@editors) {
               $datatable .= '<td style="text-align: left">'.
                             '<span class="LC_nobreak">'.
                             '<label><input type="checkbox" name="crseditors"'.
                             ' value="'.$editor.'"'.$crseditors{$editor}.' />'.
                             $editornames{$editor}.'</label></span></td>'."\n";
         }          }
         $datatable .= '</tr></table></td></tr>'."\n";          $datatable .= '</tr></table></td></tr>'."\n";
     }      }
Line 7144  sub print_coursedefaults { Line 7278  sub print_coursedefaults {
     return $datatable;      return $datatable;
 }  }
   
   sub crseditor_titles {
       return &Apache::lonlocal::texthash(
                  edit  => 'Standard editor (Edit)',
                  xml   => 'Text editor (EditXML)',
                  daxe  => 'Daxe editor (Daxe)',
              );
   }
   
   sub print_authordefaults {
       my ($position,$dom,$settings,$rowtotal) = @_;
       my ($css_class,$datatable,%checkedon,%checkedoff);
       my $itemcount = 1;
       my %titles = &authordefaults_titles();
       if ($position eq 'top') {
           my %defaultchecked = (
                               'nocodemirror' => 'off',
                               'daxecollapse' => 'off',
                               'domcoordacc'  => 'on',
                             );
           my @toggles = ('nocodemirror','daxecollapse','domcoordacc');
           ($datatable,$itemcount) = &radiobutton_prefs($settings,\@toggles,\%defaultchecked,
                                                        \%titles,$itemcount);
           my %staticdefaults = (
                                   'copyright'    => 'default',
                                   'sourceavail'  => 'closed',
                                );
           $css_class = $itemcount%2?' class="LC_odd_row"':'';
           my %currrights;
           foreach my $item ('copyright','sourceavail') {
               $currrights{$item} = $staticdefaults{$item};
               if (ref($settings) eq 'HASH') {
                   if (exists($settings->{$item})) {
                       $currrights{$item} = $settings->{$item};
                   }
               }
           }
           $datatable .= '<tr'.$css_class.'><td style="vertical-align: top">'.
                         '<span class="LC_nobreak">'.$titles{'copyright'}.
                         '</span></td><td class="LC_right_item">'.
                         &selectbox('copyright',$currrights{'copyright'},'',
                                    \&Apache::loncommon::copyrightdescription,
                                    (grep !/^priv|custom$/,(&Apache::loncommon::copyrightids))).
                         '</td></tr>'."\n";
           $itemcount ++;
           $css_class = $itemcount%2?' class="LC_odd_row"':'';
           $datatable .= '<tr'.$css_class.'><td style="vertical-align: top">'.
                         '<span class="LC_nobreak">'.$titles{'sourceavail'}.
                         '</span></td><td class="LC_right_item">'.
                         &selectbox('sourceavail',$currrights{'sourceavail'},'',
                                    \&Apache::loncommon::source_copyrightdescription,
                                    (&Apache::loncommon::source_copyrightids)).
                         '</td></tr>'."\n";        
       } else {
           $css_class = $itemcount%2 ? ' class="LC_odd_row"' : '';
           my $curreditors;
           my %staticdefaults = (
                                   editors => ['edit','xml'],
                                   authorquota => 500,
                                   webdav => 0,
                                );
           my $curreditors = $staticdefaults{'editors'};
           if ((ref($settings) eq 'HASH') &&
               (ref($settings->{'editors'}) eq 'ARRAY')) {
               $curreditors = $settings->{'editors'};
           } else {
               $curreditors = $staticdefaults{'editors'};
           }
           my @editors = ('edit','xml','daxe');
           $datatable = '<tr'.$css_class.'>'."\n".
                        '<td>'.$titles{'editors'}.'</td>'."\n".
                        '<td class="LC_left_item">'."\n".
                        '<span class="LC_nobreak">';
           foreach my $editor (@editors) {
               my $checked;
               if (grep(/^\Q$editor\E$/,@{$curreditors})) {
                   $checked = ' checked="checked"';
               }
               $datatable .= '<label>'.
                             '<input type="checkbox" name="author_editors" '.
                             $checked.' value="'.$editor.'" '.
                             'onclick="javascript:checkEditors(this.form,'."'author_editors'".',this);" />'.
                             $titles{$editor}.'</label>&nbsp;';
           }
           $datatable .= '</span>'."\n".'</td>'."\n".'</tr>'."\n";
           $itemcount ++;
           $css_class = $itemcount%2?' class="LC_odd_row"':'';
           my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom);
           my @insttypes;
           if (ref($types) eq 'ARRAY') {
               @insttypes = @{$types};
           }
           my $typecount = 0;
           my %domconf = &Apache::lonnet::get_dom('configuration',['quotas'],$dom);
           my @items = ('webdav','authorquota');
           my %quotas;
           if (ref($domconf{'quotas'}) eq 'HASH') {
               %quotas = %{$domconf{'quotas'}};
               foreach my $item (@items) {
                   if (ref($quotas{$item}) eq 'HASH') {
                       foreach my $type (@insttypes,'default') {
                           if ($item eq 'authorquota') {
                               if ($quotas{$item}{$type} !~ /^\d+$/) {
                                   $quotas{$item}{$type} = $staticdefaults{$item};
                               }
                           } elsif ($item eq 'webdav') {
                               if ($quotas{$item}{$type} !~ /^(0|1)$/) {
                                   $quotas{$item}{$type} = $staticdefaults{$item};
                               }
                           }
                       }
                   } else {
                       foreach my $type (@insttypes,'default') {
                           $quotas{$item}{$type} = $staticdefaults{$item};
                       }
                   }
               }
           } else {
               foreach my $item (@items) {
                   foreach my $type (@insttypes,'default') {
                       $quotas{$item}{$type} = $staticdefaults{$item};
                   }
               }
           }
           if (ref($usertypes) eq 'HASH') {
               my $numinrow = 4;
               my $onclick = '';
               $datatable .= &insttypes_row(\%quotas,$types,$usertypes,$dom,
                                            $numinrow,$othertitle,'authorquota',
                                            \$itemcount,$onclick);
               $itemcount ++;
               $datatable .= &insttypes_row(\%quotas,$types,$usertypes,$dom,
                                            $numinrow,$othertitle,'webdav',
                                            \$itemcount);
               $itemcount ++;
           }
           my $checkedno = ' checked="checked"';
           my ($checkedon,$checkedoff);
           if (ref($quotas{'webdav'}) eq 'HASH') {
               if ($quotas{'webdav'}{'_LC_adv'} =~ /^0|1$/) {
                   if ($quotas{'webdav'}{'_LC_adv'}) {
                       $checkedon = $checkedno;
                   } else {
                       $checkedoff = $checkedno;
                   }
                   undef($checkedno);
               }
           }
           $css_class = $itemcount%2?' class="LC_odd_row"':'';
           $datatable .= '<tr'.$css_class.'>'.
                         '<td>'.$titles{'webdav_LC_adv'}.'<br />'.
                                $titles{'webdav_LC_adv_over'}.
                         '</td>'.
                         '<td class="LC_left_item">';
           foreach my $option ('none','off','on') {
               my ($text,$val,$checked);
               if ($option eq 'none') {
                   $text = $titles{'none'};
                   $val = '';
                   $checked = $checkedno;
               } elsif ($option eq 'off') {
                   $text = $titles{'overoff'};
                   $val = 0;
                   $checked = $checkedoff;
               } elsif ($option eq 'on') {
                   $text = $titles{'overon'};
                   $val = 1;
                   $checked = $checkedon;
               }
               $datatable .= '<span class="LC_nobreak"><label>'.
                             '<input type="radio" name="webdav_LC_adv"'.
                             ' value="'.$val.'"'.$checked.' />'.
                             $text.'</label></span>&nbsp; ';
           }
           $datatable .= '</td></tr>';
           $itemcount ++;
           my %defchecked = (
                                   'archive' => 'off',
                                );
           my @toggles = ('archive');
           (my $archive,$itemcount) = &radiobutton_prefs($settings,['archive'],
                                                         {'archive' => 'off'},
                                                         \%titles,$itemcount);
           $datatable .= $archive."\n";
           $itemcount ++;
       }
       $$rowtotal += $itemcount;
       return $datatable;
   }
   
   sub authordefaults_titles {
       return &Apache::lonlocal::texthash(
                  copyright => 'Copyright/Distribution',
                  sourceavail => ' Source Available',
                  editors => 'Available Editors',
                  webdav => 'WebDAV',
                  authorquota => 'Authoring Space quotas (MB)',
                  nocodemirror => 'Deactivate CodeMirror for EditXML editor',
                  daxecollapse => 'Daxe editor: LON-CAPA standard menus start collapsed',
                  domcoordacc => 'Dom. Coords. can enter Authoring Spaces in domain',
                  edit  => 'Standard editor (Edit)',
                  xml   => 'Text editor (EditXML)',
                  daxe  => 'Daxe editor (Daxe)',
                  webdav_LC_adv => 'WebDAV access for LON-CAPA "advanced" users',
                  webdav_LC_adv_over => '(overrides access based on affiliation, if set)',
                  none => 'No override set',
                  overon => 'Override -- webDAV on',
                  overoff => 'Override -- webDAV off',
                  archive => 'Authors can download tar.gz file of Authoring Space',
       );
   }
   
   sub selectbox {
       my ($name,$value,$readonly,$functionref,@idlist)=@_;
       my $selout = '<select name="'.$name.'">';
       foreach my $id (@idlist) {
           $selout.='<option value="'.$id.'"';
           if ($id eq $value) {
               $selout.=' selected="selected"';
           }
           if ($readonly) {
               $selout .= ' disabled="disabled"';
           }
           $selout.='>'.&{$functionref}($id).'</option>';
       }
       $selout.='</select>';
       return $selout;
   }
   
 sub print_selfenrollment {  sub print_selfenrollment {
     my ($position,$dom,$settings,$rowtotal) = @_;      my ($position,$dom,$settings,$rowtotal) = @_;
     my ($css_class,$datatable);      my ($css_class,$datatable);
Line 7387  sub print_privacy { Line 7749  sub print_privacy {
         ($othertitle,$usertypes,$types) =          ($othertitle,$usertypes,$types) =
             &Apache::loncommon::sorted_inst_types($dom);              &Apache::loncommon::sorted_inst_types($dom);
     }      }
     if (($position eq 'top') || ($position eq 'middle')) {      if (($position eq 'top') || ($position eq 'bottom')) {
         my (%by_ip,%by_location,@intdoms,@instdoms);          my (%by_ip,%by_location,@intdoms,@instdoms);
         &build_location_hashes(\@intdoms,\%by_ip,\%by_location,\@instdoms);          &build_location_hashes(\@intdoms,\%by_ip,\%by_location,\@instdoms);
         if ($position eq 'top') {          if ($position eq 'top') {
Line 7474  sub print_privacy { Line 7836  sub print_privacy {
                 $datatable .= &mt('Nothing to set here, as there are no other domains');                  $datatable .= &mt('Nothing to set here, as there are no other domains');
             }              }
             $datatable .='</td></tr>';              $datatable .='</td></tr>';
         } elsif ($position eq 'middle') {          } elsif ($position eq 'bottom') {
             if ((@instdoms > 1) || (keys(%by_location) > 0)) {              if ((@instdoms > 1) || (keys(%by_location) > 0)) {
                 if ((ref($types) eq 'ARRAY') && (ref($usertypes) eq 'HASH')) {                  if ((ref($types) eq 'ARRAY') && (ref($usertypes) eq 'HASH')) {
                     foreach my $item (@{$types}) {                      foreach my $item (@{$types}) {
Line 7511  sub print_privacy { Line 7873  sub print_privacy {
                 }                  }
             }              }
         }          }
     } else {  
         my $prefix;  
         if ($position eq 'lower') {  
             $prefix = 'priv';  
         } else {  
             $prefix = 'unpriv';  
         }  
         foreach my $item (@items) {  
             $datatable .= &modifiable_userdata_row('privacy',$prefix.'_'.$item,$settings,  
                                                    $numinrow,$itemcount,'','','','','',  
                                                    '',$names{$item});  
             $itemcount ++;  
         }  
     }      }
     if (ref($rowtotal)) {      if (ref($rowtotal)) {
         $$rowtotal += $itemcount;          $$rowtotal += $itemcount;
Line 7552  sub print_passwords { Line 7901  sub print_passwords {
         min            => 'Minimum password length',          min            => 'Minimum password length',
         max            => 'Maximum password length',          max            => 'Maximum password length',
         chars          => 'Required characters',          chars          => 'Required characters',
         expire         => 'Password expiration (days)',  
         numsaved       => 'Number of previous passwords to save and disallow reuse',          numsaved       => 'Number of previous passwords to save and disallow reuse',
     );      );
     if ($position eq 'top') {      if ($position eq 'top') {
Line 7879  sub print_passwords { Line 8227  sub print_passwords {
   
 sub password_rules {  sub password_rules {
     my ($prefix,$itemcountref,$settings) = @_;      my ($prefix,$itemcountref,$settings) = @_;
     my ($min,$max,%chars,$expire,$numsaved,$numinrow);      my ($min,$max,%chars,$numsaved,$numinrow);
     my %titles;      my %titles;
     if ($prefix eq 'passwords') {      if ($prefix eq 'passwords') {
         %titles = &Apache::lonlocal::texthash (          %titles = &Apache::lonlocal::texthash (
Line 7911  sub password_rules { Line 8259  sub password_rules {
             map { $chars{$_} = 1; } (@{$settings->{chars}});              map { $chars{$_} = 1; } (@{$settings->{chars}});
         }          }
         if ($prefix eq 'passwords') {          if ($prefix eq 'passwords') {
             if ($settings->{expire}) {  
                 $expire = $settings->{expire};  
             }  
             if ($settings->{numsaved}) {              if ($settings->{numsaved}) {
                 $numsaved = $settings->{numsaved};                  $numsaved = $settings->{numsaved};
             }              }
Line 7975  sub password_rules { Line 8320  sub password_rules {
     $datatable .='</table></td></tr>';      $datatable .='</table></td></tr>';
     $itemcount ++;      $itemcount ++;
     if ($prefix eq 'passwords') {      if ($prefix eq 'passwords') {
         $titles{'expire'} = &mt('Password expiration (days)');  
         $titles{'numsaved'} = &mt('Number of previous passwords to save and disallow reuse');          $titles{'numsaved'} = &mt('Number of previous passwords to save and disallow reuse');
         $css_class = $itemcount%2?' class="LC_odd_row"':'';          $css_class = $itemcount%2?' class="LC_odd_row"':'';
         $datatable .= '<tr'.$css_class.'><td>'.$titles{'expire'}.'</td>'.  
                       '<td class="LC_left_item"><span class="LC_nobreak">'.  
                       '<input type="text" name="'.$prefix.'_expire" value="'.$expire.'" size="4" '.  
                       'onblur="javascript:warnInt'.$prefix.'(this);" />'.  
                       '<span class="LC_fontsize_small"> '.&mt('(Leave blank for no expiration)').'</span>'.  
                       '</span></td></tr>';  
         $itemcount ++;  
         $css_class = $itemcount%2?' class="LC_odd_row"':'';  
         $datatable .= '<tr'.$css_class.'><td>'.$titles{'numsaved'}.'</td>'.          $datatable .= '<tr'.$css_class.'><td>'.$titles{'numsaved'}.'</td>'.
                       '<td class="LC_left_item"><span class="LC_nobreak">'.                        '<td class="LC_left_item"><span class="LC_nobreak">'.
                       '<input type="text" name="'.$prefix.'_numsaved" value="'.$numsaved.'" size="3" '.                        '<input type="text" name="'.$prefix.'_numsaved" value="'.$numsaved.'" size="3" '.
Line 8070  sub print_wafproxy { Line 8406  sub print_wafproxy {
             my $dom_in_effect;              my $dom_in_effect;
             my $aliasrows = '<tr>'.              my $aliasrows = '<tr>'.
                             '<td class="LC_left_item" style="vertical-align: baseline;">'.                              '<td class="LC_left_item" style="vertical-align: baseline;">'.
                             &mt('Hostname').':&nbsp;'.                              &mt('Hostname').': '.
                             '<i>'.&Apache::lonnet::hostname($server).'</i></td><td>&nbsp;</td>';                              '<span class="LC_nobreak LC_cusr_emph">'.
                               &Apache::lonnet::hostname($server).
                               '</span></td><td>&nbsp;</td>';
             if ($othercontrol{$server}) {              if ($othercontrol{$server}) {
                 $dom_in_effect = $othercontrol{$server};                  $dom_in_effect = $othercontrol{$server};
                 my ($current,$forsaml);                  my ($current,$forsaml);
Line 9386  sub tool_titles { Line 9724  sub tool_titles {
     my %titles = &Apache::lonlocal::texthash (      my %titles = &Apache::lonlocal::texthash (
                      aboutme    => 'Personal web page',                       aboutme    => 'Personal web page',
                      blog       => 'Blog',                       blog       => 'Blog',
                      webdav     => 'WebDAV',  
                      portfolio  => 'Portfolio',                       portfolio  => 'Portfolio',
                        portaccess => 'Share portfolio files',
                      timezone   => 'Can set time zone',                       timezone   => 'Can set time zone',
                      official   => 'Official courses (with institutional codes)',                       official   => 'Official courses (with institutional codes)',
                      unofficial => 'Unofficial courses',                       unofficial => 'Unofficial courses',
Line 10290  sub print_usermodification { Line 10628  sub print_usermodification {
             $$rowtotal ++;              $$rowtotal ++;
             $rowcount ++;              $rowcount ++;
         }          }
       } elsif ($position eq 'middle') {
           $rowcount = 0;
           $context = 'coauthor';
           foreach my $role ('ca','aa') {
               $datatable .= &modifiable_userdata_row($context,$role,$settings,
                                                      $numinrow,$rowcount);
               $$rowtotal ++;
               $rowcount ++;
           }
     } elsif ($position eq 'bottom') {      } elsif ($position eq 'bottom') {
         $context = 'course';          $context = 'course';
         $rowcount = 0;          $rowcount = 0;
Line 11356  function warnInt$prefix(field) { Line 11703  function warnInt$prefix(field) {
             field.value = '';              field.value = '';
         }          }
         if (field.value != '') {          if (field.value != '') {
             if (field.name == '${prefix}_expire') {              if (!regexdigit.test(field.value)) {
                 var regexpposnum=/^\\d+(|\\.\\d*)\$/;                   if (field.name == '${prefix}_max') {
                 if (!regexpposnum.test(field.value)) {                      alert('$intalert{passmax}');
                     alert('$intalert{passexp}');  
                     field.value = '';  
                 } else {                  } else {
                     var expval = parseFloat(field.value);                      if (field.name == '${prefix}_numsaved') {
                     if (expval == 0) {                          alert('$intalert{passnum}');
                         alert('$intalert{passexp}');  
                         field.value = '';  
                     }  
                 }  
             } else {  
                 if (!regexdigit.test(field.value)) {  
                     if (field.name == '${prefix}_max') {  
                         alert('$intalert{passmax}');  
                     } else {  
                         if (field.name == '${prefix}_numsaved') {  
                             alert('$intalert{passnum}');  
                         }  
                     }                      }
                     field.value = '';  
                 }                  }
                   field.value = '';
             }              }
         }          }
     }      }
Line 11703  sub modifiable_userdata_row { Line 12036  sub modifiable_userdata_row {
         my $hashref;          my $hashref;
         if ($context eq 'lti') {          if ($context eq 'lti') {
             if (ref($settings) eq 'HASH') {              if (ref($settings) eq 'HASH') {
                 $hashref = $settings->{'instdata'};                  my %instdata;
                   if (ref($settings->{'instdata'}) eq 'ARRAY') {
                       map { $instdata{$_} = 1; } @{$settings->{'instdata'}};
                   }
                   $hashref = \%instdata;
             }              }
         } elsif ($context eq 'privacy') {          } elsif ($context eq 'privacy') {
             my ($key,$inner) = split(/_/,$role);              my ($key,$inner) = split(/_/,$role);
Line 11714  sub modifiable_userdata_row { Line 12051  sub modifiable_userdata_row {
             }              }
         } elsif (ref($settings->{$context}) eq 'HASH') {          } elsif (ref($settings->{$context}) eq 'HASH') {
             if (ref($settings->{$context}->{$role}) eq 'HASH') {              if (ref($settings->{$context}->{$role}) eq 'HASH') {
                 $hashref = $settings->{'lti_instdata'};                  $hashref = $settings->{$context}->{$role};
             }              }
             if ($role eq 'emailusername') {              if ($role eq 'emailusername') {
                 if ($statustype) {                  if ($statustype) {
Line 11795  sub modifiable_userdata_row { Line 12132  sub modifiable_userdata_row {
         } else {          } else {
             if ($context eq 'lti') {              if ($context eq 'lti') {
                 $prefix = 'lti';                  $prefix = 'lti';
               } elsif ($context eq 'coauthor') {
                   $prefix = 'cacanmodify';
             } elsif ($context eq 'privacy') {              } elsif ($context eq 'privacy') {
                 $prefix = 'privacy';                  $prefix = 'privacy';
             }              }
Line 11824  sub insttypes_row { Line 12163  sub insttypes_row {
     my ($settings,$types,$usertypes,$dom,$numinrow,$othertitle,$context,$rowtotal,$onclick,      my ($settings,$types,$usertypes,$dom,$numinrow,$othertitle,$context,$rowtotal,$onclick,
         $customcss,$rowstyle) = @_;          $customcss,$rowstyle) = @_;
     my %lt = &Apache::lonlocal::texthash (      my %lt = &Apache::lonlocal::texthash (
                       cansearch => 'Users allowed to search',                        cansearch      => 'Users allowed to search',
                       statustocreate => 'Institutional affiliation(s) able to create own account (login/SSO)',                        statustocreate => 'Institutional affiliation(s) able to create own account (login/SSO)',
                       lockablenames => 'User preference to lock name',                        lockablenames  => 'User preference to lock name',
                       selfassign    => 'Self-reportable affiliations',                        selfassign     => 'Self-reportable affiliations',
                       overrides     => "Override domain's helpdesk settings based on requester's affiliation",                        overrides      => "Override domain's helpdesk settings based on requester's affiliation",
                         webdav         => 'WebDAV access available',
                         authorquota    => 'Authoring Space quota (MB)',
              );               );
     my $showdom;      my ($showdom,$defaultquota);
     if ($context eq 'cansearch') {      if ($context eq 'cansearch') {
         $showdom = ' ('.$dom.')';          $showdom = ' ('.$dom.')';
       } elsif ($context eq 'authorquota') {
           $defaultquota = 500;
     }      }
     my $class = 'LC_left_item';      my $class = 'LC_left_item';
     if ($context eq 'statustocreate') {      if ($context eq 'statustocreate') {
Line 11869  sub insttypes_row { Line 12212  sub insttypes_row {
                     }                      }
                     $output .= '<tr>';                      $output .= '<tr>';
                 }                  }
                 my $check = ' ';                  if ($context eq 'authorquota') {
                 if (ref($settings) eq 'HASH') {                      my $currquota;
                     if (ref($settings->{$context}) eq 'ARRAY') {                      if ($settings->{$context}->{$types->[$i]} =~ /^\d+$/) {
                         if (grep(/^\Q$types->[$i]\E$/,@{$settings->{$context}})) {                          $currquota = $settings->{$context}->{$types->[$i]};
                             $check = ' checked="checked" ';                      } else {
                         }                          $currquota = $defaultquota;
                     } elsif (ref($settings->{$context}) eq 'HASH') {                      }
                         if (ref($settings->{$context}->{$types->[$i]}) eq 'HASH') {                      $output .= '<td class="LC_left_item">'."\n".
                                  '<label><span class="LC_nobreak">'."\n".
                                  $usertypes->{$types->[$i]}.'</span><br />'."\n".
                                  '<input type="text" name="'.$context.'_'.$types->[$i].'" '.
                                  'value="'.$currquota.'" size="5"'.$onclick.'/>'."\n".
                                  '</label></td>';
                   } else {
                       my $check = ' ';
                       if (ref($settings) eq 'HASH') {
                           if (ref($settings->{$context}) eq 'ARRAY') {
                               if (grep(/^\Q$types->[$i]\E$/,@{$settings->{$context}})) {
                                   $check = ' checked="checked" ';
                               }
                           } elsif (ref($settings->{$context}) eq 'HASH') {
                               if (ref($settings->{$context}->{$types->[$i]}) eq 'HASH') {
                                   $check = ' checked="checked" ';
                               } elsif ($context eq 'webdav') {
                                   if ($settings->{$context}->{$types->[$i]}) {
                                       $check = ' checked="checked" ';
                                   }
                               }
                           } elsif ($context eq 'statustocreate') {
                             $check = ' checked="checked" ';                              $check = ' checked="checked" ';
                         }                          }
                     } elsif ($context eq 'statustocreate') {  
                         $check = ' checked="checked" ';  
                     }                      }
                       $output .= '<td class="LC_left_item">'.
                                  '<span class="LC_nobreak"><label>'.
                                  '<input type="checkbox" name="'.$context.'" '.
                                  'value="'.$types->[$i].'"'.$check.$onclick.'/>'.
                                  $usertypes->{$types->[$i]}.'</label></span></td>';
                 }                  }
                 $output .= '<td class="LC_left_item">'.  
                            '<span class="LC_nobreak"><label>'.  
                            '<input type="checkbox" name="'.$context.'" '.  
                            'value="'.$types->[$i].'"'.$check.$onclick.' />'.  
                            $usertypes->{$types->[$i]}.'</label></span></td>';  
             }              }
         }          }
         $rem = @{$types}%($numinrow);          $rem = @{$types}%($numinrow);
Line 11909  sub insttypes_row { Line 12271  sub insttypes_row {
         } else {          } else {
             $output .= '<td class="LC_left_item">';              $output .= '<td class="LC_left_item">';
         }          }
         my $defcheck = ' ';          if ($context eq 'authorquota') {
         if (ref($settings) eq 'HASH') {                my $currquota = 500;
             if (ref($settings->{$context}) eq 'ARRAY') {              if ((ref($settings) eq 'HASH') && (ref($settings->{$context}) eq 'HASH')) {
                 if (grep(/^default$/,@{$settings->{$context}})) {                  if ($settings->{$context}{'default'} =~ /^\d+$/) {
                       $currquota = $settings->{$context}{'default'};
                   }
               }
               $output .= '<label><span class="LC_nobreak">'.$othertitle.'</span><br />'."\n".
                          '<input type="text" name="'.$context.'_default" '.
                          'value="'.$currquota.'" size="5"'.$onclick.'/>'."\n".
                          '</label>';
           } else {
               my $defcheck = ' ';
               if (ref($settings) eq 'HASH') {
                   if (ref($settings->{$context}) eq 'ARRAY') {
                       if (grep(/^default$/,@{$settings->{$context}})) {
                           $defcheck = ' checked="checked" ';
                       }
                   } elsif (ref($settings->{$context}) eq 'HASH') {
                       if (ref($settings->{$context}->{'default'}) eq 'HASH') {
                           $defcheck = ' checked="checked" ';
                       } elsif ($context eq 'webdav') {
                           if ($settings->{$context}->{'default'}) {
                               $defcheck = ' checked="checked" ';
                           }
                       }
                   } elsif ($context eq 'statustocreate') {
                     $defcheck = ' checked="checked" ';                      $defcheck = ' checked="checked" ';
                 }                  }
             } elsif ($context eq 'statustocreate') {  
                 $defcheck = ' checked="checked" ';  
             }              }
               $output .= '<span class="LC_nobreak"><label>'.
                          '<input type="checkbox" name="'.$context.'" '.
                          'value="default"'.$defcheck.$onclick.'/>'.
                          $othertitle.'</label></span>';
         }          }
         $output .= '<span class="LC_nobreak"><label>'.  
                    '<input type="checkbox" name="'.$context.'" '.  
                    'value="default"'.$defcheck.$onclick.' />'.  
                    $othertitle.'</label></span>';  
     }      }
     $output .= '</td></tr></table></td></tr>';      $output .= '</td></tr></table></td></tr>';
     return $output;      return $output;
Line 12643  sub check_exempt_addresses { Line 13026  sub check_exempt_addresses {
 sub color_font_choices {  sub color_font_choices {
     my %choices =      my %choices =
         &Apache::lonlocal::texthash (          &Apache::lonlocal::texthash (
             img => "Header",  
             bgs => "Background colors",              bgs => "Background colors",
             links => "Link colors",              links => "Link colors",
             images => "Images",              images => "Images",
Line 12698  sub modify_ipaccess { Line 13080  sub modify_ipaccess {
     foreach my $idx (@items) {      foreach my $idx (@items) {
         my $itemid = $itemids{$idx};          my $itemid = $itemids{$idx};
         next unless ($itemid);          next unless ($itemid);
         my %current;          my ($position,%current);
         unless ($idx eq 'add') {          if ($idx eq 'add') {
               $position = $env{'form.ipaccess_pos_add'};
           } else {
               $position = $env{'form.ipaccess_pos_'.$itemid};
             if (ref($domconfig{'ipaccess'}{$itemid}) eq 'HASH') {              if (ref($domconfig{'ipaccess'}{$itemid}) eq 'HASH') {
                 %current = %{$domconfig{'ipaccess'}{$itemid}};                  %current = %{$domconfig{'ipaccess'}{$itemid}};
             }              }
         }          }
         my $position = $env{'form.ipaccess_pos_'.$itemid};  
         $position =~ s/\D+//g;          $position =~ s/\D+//g;
         if ($position ne '') {          if ($position ne '') {
             $allpos[$position] = $itemid;              $allpos[$position] = $itemid;
Line 12936  sub get_ipaccess_id { Line 13320  sub get_ipaccess_id {
     return ($id,$error);      return ($id,$error);
 }  }
   
   sub modify_authordefaults {
       my ($dom,$lastactref,%domconfig) = @_;
   #
   # Retrieve current domain configuration for webDAV and Authoring Space quotas from $domconfig{'quotas'}.
   #
       my (%curr_quotas,%save_quotas,%confhash,%changes,%newvalues);
       if (ref($domconfig{'quotas'}) eq 'HASH') {
           foreach my $key (keys(%{$domconfig{'quotas'}})) {
               if ($key =~ /^webdav|authorquota$/) {
                   $curr_quotas{$key} = $domconfig{'quotas'}{$key};
               } else {
                   $save_quotas{$key} = $domconfig{'quotas'}{$key};
               }
           }
       }
       my %staticdefaults = (
                              'copyright'    => 'default',
                              'sourceavail'  => 'closed',
                              'nocodemirror' => 'off',
                              'daxecollapse' => 'off',
                              'domcoordacc'  => 'on',
                              'editors'      => ['edit','xml'],
                              'authorquota'  => 500,
                              'webdav'       => 0,
                              'archive'      => 'off',
                            );
       my %titles = &authordefaults_titles();
       foreach my $item ('nocodemirror','daxecollapse','domcoordacc','archive') {
           if ($env{'form.'.$item} =~ /^(0|1)$/) {
               $confhash{$item} = $env{'form.'.$item};
           }
       }
       if ($env{'form.copyright'} =~ /^(default|domain|public)$/) {
           $confhash{'copyright'} = $1;
       }
       if ($env{'form.sourceavail'} =~ /^(closed|open)$/) {
           $confhash{'sourceavail'} = $1;
       }
       my @posseditors =  &Apache::loncommon::get_env_multiple('form.author_editors');
       my @okeditors = ('edit','xml','daxe');
       my @editors;
       foreach my $item (@posseditors) {
           if (grep(/^\Q$item\E$/,@okeditors)) {
               push(@editors,$item);
           }
       }
       $confhash{'editors'} = \@editors;
   
       my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom);
       my @insttypes;
       if (ref($types) eq 'ARRAY') {
           @insttypes = @{$types};
       }
       my @webdavon = &Apache::loncommon::get_env_multiple('form.webdav');
       my %webdav;
       map { $webdav{$_} = 1; } @webdavon;
       foreach my $type (@insttypes,'default') {
           my $possquota = $env{'form.authorquota_'.$type};
           if ($possquota =~ /^\d+$/) {
               $save_quotas{'authorquota'}{$type} = $possquota;
           }
           if ($webdav{$type}) {
               $save_quotas{'webdav'}{$type} = 1;
           } else {
               $save_quotas{'webdav'}{$type} = 0;
           }
       }
       if ($env{'form.webdav_LC_adv'} =~ /^(0|1)$/) {
           $save_quotas{'webdav'}{'_LC_adv'} = $env{'form.webdav_LC_adv'};
       }
       if (ref($domconfig{'authordefaults'}) eq 'HASH') {
           foreach my $item ('nocodemirror','daxecollapse','domcoordacc','copyright','sourceavail','archive') {
               if ($domconfig{'authordefaults'}{$item} ne $confhash{$item}) {
                   $changes{$item} = 1;
                }
           }
           if (ref($domconfig{'authordefaults'}{'editors'}) eq 'ARRAY') {
               my @diffs =
                   &Apache::loncommon::compare_arrays($confhash{'editors'},
                                                      $domconfig{'authordefaults'}{'editors'});
               unless (@diffs == 0) {
                   $changes{'editors'} = 1;
               }
           } else {
               my @diffs =
                   &Apache::loncommon::compare_arrays($confhash{'editors'},
                                                      $staticdefaults{'editors'});
               unless (@diffs == 0) {
                   $changes{'editors'} = 1;
               }
           }
       } else {
           my @offon = ('off','on');
           foreach my $item ('nocodemirror','daxecollapse','domcoordacc','archive') {
               if ($offon[$confhash{$item}] ne $staticdefaults{$item}) {
                   $changes{$item} = 1; 
               }
           }
           foreach my $item ('copyright','sourceavail') {
               if ($confhash{$item} ne $staticdefaults{$item}) {
                   $changes{$item} = 1;
               }
           }
           my @diffs =
               &Apache::loncommon::compare_arrays($confhash{'editors'},
                                                  $staticdefaults{'editors'});
           unless (@diffs == 0) {
               $changes{'editors'} = 1;
           }
       }
       foreach my $key ('authorquota','webdav') {
           if (ref($curr_quotas{$key}) eq 'HASH') {
               foreach my $type (@insttypes,'default') {
                   if (exists($save_quotas{$key}{$type})) {
                       if ($save_quotas{$key}{$type} ne $curr_quotas{$key}{$type}) {
                           $changes{$key}{$type} = 1;
                       }
                   } elsif (exists($curr_quotas{$key}{$type})) {
                       $save_quotas{$key}{$type} = $curr_quotas{$key}{$type};
                   } else {
                       $save_quotas{$key}{$type} = $staticdefaults{$key};
                   }
               }
           } else {
               foreach my $type (@insttypes,'default') {
                   if (exists($save_quotas{$key}{$type})) {
                       unless ($save_quotas{$key}{$type} eq $staticdefaults{$key}) {
                           $changes{$key}{$type} = 1;
                       }
                   } else {
                       $save_quotas{$key}{$type} = $staticdefaults{$key};
                   }
               }
           }
       }
       if (ref($curr_quotas{'webdav'}) eq 'HASH') {
           if (exists($save_quotas{'webdav'}{'_LC_adv'})) {
               if ($save_quotas{'webdav'}{'_LC_adv'} ne $curr_quotas{'webdav'}{'_LC_adv'}) {
                   $changes{'webdav_LC_adv'} = 1;
               }
           } elsif (exists($curr_quotas{'webdav'}{'_LC_adv'})) {
               $changes{'webdav_LC_adv'} = 1;
           }
       } elsif (exists($save_quotas{'webdav'}{'_LC_adv'})) {
           $changes{'webdav_LC_adv'} = 1;
       }
       my %confighash = (
                           quotas  => \%save_quotas,
                           authordefaults => \%confhash,
                        );
       my $putresult = &Apache::lonnet::put_dom('configuration',\%confighash,
                                                $dom);
       my $resulttext;
       if ($putresult eq 'ok') {
           if (keys(%changes)) {
               my %domdefaults = &Apache::lonnet::get_domain_defaults($dom);
               if ((exists($changes{'authorquota'})) || (exists($changes{'webdav'})) ||
                   ($changes{'webdav_LC_adv'})) {
                   if ((exists($changes{'authorquota'})) && (ref($save_quotas{'authorquota'}) eq 'HASH')) {
                       $domdefaults{'authorquota'} = $save_quotas{'authorquota'};
                   }
                   if (((exists($changes{'webdav'})) || ($changes{'webdav_LC_adv'})) &&
                       (ref($save_quotas{'webdav'}) eq 'HASH')) {
                       $domdefaults{'webdav'} = $save_quotas{'webdav'};
                   }
               }
               $resulttext = &mt('Changes made:').'<ul>';
               my $authoroverride;
               foreach my $key ('nocodemirror','daxecollapse','domcoordacc','copyright','sourceavail') {
                   if (exists($changes{$key})) {
                       $domdefaults{$key} = $confhash{$key};
                       my $shown;
                       unless ($authoroverride) {
                           $resulttext .= '<li>'.&mt('Defaults which can be overridden by Author').'<ul>';
                           $authoroverride = 1;
                       }
                       if (($key eq 'nocodemirror') || ($key eq 'daxecollapse') || ($key eq 'domcoordacc')) {
                           $shown = ($confhash{$key} ? &mt('Yes') : &mt('No'));
                       } elsif ($key eq 'copyright') {
                           $shown = &Apache::loncommon::copyrightdescription($confhash{$key});
                       } elsif ($key eq 'sourceavail') {
                           $shown = &Apache::loncommon::source_copyrightdescription($confhash{$key});
                       }
                       $resulttext .= '<li>'.&mt('[_1] set to: [_2]',$titles{$key},$shown).'</li>';
                   }
               }
               if ($authoroverride) {
                   $resulttext .= '</ul></li>';
               }
               my $domcoordoverride;
               foreach my $key ('editors','authorquota','webdav','webdav_LC_adv','archive') {
                   if (exists($changes{$key})) {
                       my $shown;
                       unless ($domcoordoverride) {
                           $resulttext .= '<li>'.&mt('Defaults which can be overridden by a Domain Coodinator').'<ul>';
                           $domcoordoverride = 1;
                       }
                       if ($key eq 'editors') {
                           if (ref($confhash{'editors'}) eq 'ARRAY') {
                               $domdefaults{'editors'} = join(',',@{$confhash{'editors'}});
                               if (@{$confhash{'editors'}}) {
                                   $shown = join(', ', map { $titles{$_} } @{$confhash{'editors'}});
                               } else {
                                   $shown = &mt('None');
                               }
                           }
                       } elsif ($key eq 'authorquota') {
                           foreach my $type (@insttypes) {
                               $shown .= $usertypes->{$type}.' -- '.$save_quotas{$key}{$type}.', ';
                           }
                           $shown .= $othertitle.' -- '.$save_quotas{$key}{'default'};
                       } elsif ($key eq 'webdav') {
                           foreach my $type (@insttypes) {
                               $shown .= $usertypes->{$type}.' -- '. ($save_quotas{$key}{$type} ? &mt('Yes') : &mt('No')).', ';
                           }
                           $shown .= $othertitle.' -- '. ($save_quotas{$key}{'default'} ? &mt('Yes') : &mt('No'));
                       } elsif ($key eq 'webdav_LC_adv') {
                           if (exists($save_quotas{'webdav'}{'_LC_adv'})) {
                               $shown = ($save_quotas{'webdav'}{'_LC_adv'} ? $titles{'overon'} : $titles{'overoff'});
                           } else {
                               $shown = $titles{'none'};
                           }
                       } elsif ($key eq 'archive') {
                           $domdefaults{$key} = $confhash{$key};
                           $shown = ($confhash{$key} ? &mt('Yes') : &mt('No'));
                       }
                       $resulttext .= '<li>'.&mt('[_1] set to: [_2]',$titles{$key},$shown).'</li>';
                   }
               }
               if ($domcoordoverride) {
                   $resulttext .= '</ul></li>';
               }
               $resulttext .= '</ul>';
               my $cachetime = 24*60*60;
               &Apache::lonnet::do_cache_new('domdefaults',$dom,\%domdefaults,$cachetime);
               if (ref($lastactref) eq 'HASH') {
                   $lastactref->{'domdefaults'} = 1;
               }
           } else {
               $resulttext = &mt('No changes made to Authoring Space defaults');
           }
       }
       return $resulttext;
   }
   
 sub modify_rolecolors {  sub modify_rolecolors {
     my ($r,$dom,$confname,$roles,$lastactref,%domconfig) = @_;      my ($r,$dom,$confname,$roles,$lastactref,%domconfig) = @_;
     my ($resulttext,%rolehash);      my ($resulttext,%rolehash);
Line 12992  sub modify_colors { Line 13621  sub modify_colors {
             @images = ('img','logo','domlogo','login');              @images = ('img','logo','domlogo','login');
             @bgs = ('pgbg','mainbg','sidebg');              @bgs = ('pgbg','mainbg','sidebg');
         } else {          } else {
             @images = ('img');              @images = ();
             @bgs = ('pgbg','tabbg','sidebg');              @bgs = ('pgbg','tabbg','sidebg');
         }          }
         my %defaults = &role_defaults($role,\@bgs,\@links,\@images,\@logintext);          my %defaults = &role_defaults($role,\@bgs,\@links,\@images,\@logintext);
         unless ($env{'form.'.$role.'_font'} eq $defaults{'font'}) {          $env{'form.'.$role.'_font'} = lc($env{'form.'.$role.'_font'});
           if ($env{'form.'.$role.'_font'} =~ /^\w+/) {
               $env{'form.'.$role.'_font'} = '#'.$env{'form.'.$role.'_font'};
           }
           unless ($env{'form.'.$role.'_font'} eq lc($defaults{'font'})) {
             $confhash->{$role}{'font'} = $env{'form.'.$role.'_font'};              $confhash->{$role}{'font'} = $env{'form.'.$role.'_font'};
         }          }
         if ($role eq 'login') {          if ($role eq 'login') {
Line 13014  sub modify_colors { Line 13647  sub modify_colors {
             if ($env{'form.'.$role.'_fontmenu'} =~ /^\w+/) {              if ($env{'form.'.$role.'_fontmenu'} =~ /^\w+/) {
                 $env{'form.'.$role.'_fontmenu'} = '#'.$env{'form.'.$role.'_fontmenu'};                  $env{'form.'.$role.'_fontmenu'} = '#'.$env{'form.'.$role.'_fontmenu'};
             }              }
             unless($env{'form.'.$role.'_fontmenu'} eq lc($defaults{'fontmenu'})) {              unless ($env{'form.'.$role.'_fontmenu'} eq lc($defaults{'fontmenu'})) {
                 $confhash->{$role}{'fontmenu'} = $env{'form.'.$role.'_fontmenu'};                  $confhash->{$role}{'fontmenu'} = $env{'form.'.$role.'_fontmenu'};
             }              }
         }          }
Line 13489  sub modify_quotas { Line 14122  sub modify_quotas {
         $author_ok,$switchserver,$errors,$validationitemsref,$validationnamesref,          $author_ok,$switchserver,$errors,$validationitemsref,$validationnamesref,
         $validationfieldsref);          $validationfieldsref);
     if ($action eq 'quotas') {      if ($action eq 'quotas') {
         $context = 'tools';           $context = 'tools';
     } else {      } else {
         $context = $action;          $context = $action;
     }      }
Line 13509  sub modify_quotas { Line 14142  sub modify_quotas {
         @usertools = ('author');          @usertools = ('author');
         %titles = &authorrequest_titles();          %titles = &authorrequest_titles();
     } else {      } else {
         @usertools = ('aboutme','blog','webdav','portfolio','timezone');          @usertools = ('aboutme','blog','portfolio','portaccess','timezone');
         %titles = &tool_titles();          %titles = &tool_titles();
     }      }
     my %domdefaults = &Apache::lonnet::get_domain_defaults($dom,1);      my %domdefaults = &Apache::lonnet::get_domain_defaults($dom,1);
Line 13532  sub modify_quotas { Line 14165  sub modify_quotas {
         } else {          } else {
             if ($key =~ /^form\.quota_(.+)$/) {              if ($key =~ /^form\.quota_(.+)$/) {
                 $confhash{'defaultquota'}{$1} = $env{$key};                  $confhash{'defaultquota'}{$1} = $env{$key};
             } elsif ($key =~ /^form\.authorquota_(.+)$/) {  
                 $confhash{'authorquota'}{$1} = $env{$key};  
             } elsif ($key =~ /^form\.\Q$context\E_(.+)$/) {              } elsif ($key =~ /^form\.\Q$context\E_(.+)$/) {
                 @{$toolshash{$1}} = &Apache::loncommon::get_env_multiple($key);                  @{$toolshash{$1}} = &Apache::loncommon::get_env_multiple($key);
             }              }
Line 13827  sub modify_quotas { Line 14458  sub modify_quotas {
         }          }
     } else {      } else {
         $confhash{'defaultquota'}{'default'} = $env{'form.defaultquota'};          $confhash{'defaultquota'}{'default'} = $env{'form.defaultquota'};
         $confhash{'authorquota'}{'default'} = $env{'form.authorquota'};  
     }      }
     foreach my $item (@usertools) {      foreach my $item (@usertools) {
         foreach my $type (@{$types},'default','_LC_adv') {          foreach my $type (@{$types},'default','_LC_adv') {
Line 13916  sub modify_quotas { Line 14546  sub modify_quotas {
                 }                  }
             }              }
             if (ref($domconfig{'quotas'}{'authorquota'}) eq 'HASH') {              if (ref($domconfig{'quotas'}{'authorquota'}) eq 'HASH') {
                 foreach my $key (keys(%{$domconfig{'quotas'}{'authorquota'}})) {                  $confhash{'authorquota'} = $domconfig{'quotas'}{'authorquota'};
                     if (exists($confhash{'authorquota'}{$key})) {              }
                         if ($confhash{'authorquota'}{$key} ne $domconfig{'quotas'}{'authorquota'}{$key}) {              if (ref($domconfig{'quotas'}{'webdav'}) eq 'HASH') {
                             $changes{'authorquota'}{$key} = 1;                  $confhash{'webdav'} = $domconfig{'quotas'}{'webdav'};
                         }  
                     } else {  
                         $confhash{'authorquota'}{$key} = $domconfig{'quotas'}{'authorquota'}{$key};  
                     }  
                 }  
             }              }
         }          }
         if (ref($confhash{'defaultquota'}) eq 'HASH') {          if (ref($confhash{'defaultquota'}) eq 'HASH') {
Line 13944  sub modify_quotas { Line 14569  sub modify_quotas {
                 }                  }
             }              }
         }          }
         if (ref($confhash{'authorquota'}) eq 'HASH') {  
             foreach my $key (keys(%{$confhash{'authorquota'}})) {  
                 if (ref($domconfig{'quotas'}) eq 'HASH') {  
                     if (ref($domconfig{'quotas'}{'authorquota'}) eq 'HASH') {  
                         if (!exists($domconfig{'quotas'}{'authorquota'}{$key})) {  
                             $changes{'authorquota'}{$key} = 1;  
                         }  
                     } else {  
                         $changes{'authorquota'}{$key} = 1;  
                     }  
                 } else {  
                     $changes{'authorquota'}{$key} = 1;  
                 }  
             }  
         }  
     }      }
   
     if ($context eq 'requestauthor') {      if ($context eq 'requestauthor') {
Line 13999  sub modify_quotas { Line 14609  sub modify_quotas {
                     }                      }
                     $resulttext .= '</ul></li>';                      $resulttext .= '</ul></li>';
                 }                  }
                 if (ref($changes{'authorquota'}) eq 'HASH') {  
                     $resulttext .= '<li>'.&mt('Authoring Space default quotas').'<ul>';  
                     foreach my $type (@{$types},'default') {  
                         if (defined($changes{'authorquota'}{$type})) {  
                             my $typetitle = $usertypes->{$type};  
                             if ($type eq 'default') {  
                                 $typetitle = $othertitle;  
                             }  
                             $resulttext .= '<li>'.&mt('[_1] set to [_2] MB',$typetitle,$confhash{'authorquota'}{$type}).'</li>';  
                         }  
                     }  
                     $resulttext .= '</ul></li>';  
                 }  
             }              }
             my %newenv;              my %newenv;
             foreach my $item (@usertools) {              foreach my $item (@usertools) {
Line 14163  sub modify_quotas { Line 14760  sub modify_quotas {
                             $resulttext .= '<li>'.&mt('Validated course requests identified as processed by: [_1]',                              $resulttext .= '<li>'.&mt('Validated course requests identified as processed by: [_1]',
                                                      '<b>'.$changes{'validation'}{'dc'}.'</b>').'</li>';                                                       '<b>'.$changes{'validation'}{'dc'}.'</b>').'</li>';
                         }                          }
                           $resulttext .= '</ul></li>';
                     }                      }
                 }                  }
             }              }
Line 14474  sub lti_security_results { Line 15072  sub lti_security_results {
                                        off => &mt('Encryption of stored external tool secrets defined in domain disabled'),                                         off => &mt('Encryption of stored external tool secrets defined in domain disabled'),
                                      },                                       },
                              );                               );
   
             }              }
             my @types= ('crs','dom');              my @types= ('crs','dom');
             if ($context eq 'lti') {              if ($context eq 'lti') {
Line 14570  sub lti_security_results { Line 15167  sub lti_security_results {
             }              }
         } elsif ($item eq 'linkprot') {          } elsif ($item eq 'linkprot') {
             next;              next;
           } elsif ($item eq 'suggested') {
               if ((ref($secchanges->{'suggested'}) eq 'HASH') &&
                   (ref($newsec->{'suggested'}) eq 'HASH')) {
                   my $suggestions;
                   foreach my $id (sort { $a <=> $b } keys(%{$secchanges->{'suggested'}})) {
                       if (ref($newsec->{'suggested'}->{$id}) eq 'HASH') {
                           my $name = $newsec->{'suggested'}->{$id}->{'name'};
                           my $info = $newsec->{'suggested'}->{$id}->{'info'};
                           $suggestions .= '<li>'.&mt('Launcher: [_1]',$name).'<br />'.
                                                  &mt('Recommend: [_1]','<pre>'.$info.'</pre>').
                                           '</li>';
                       } else {
                           $suggestions .= '<li>'.&mt('Recommendations deleted for Launcher: [_1]',
                                                      $newsec->{'suggested'}->{$id}).'</li>';
                       }
                   }
                   if ($suggestions) {
                       $output .= '<li>'.&mt('Hints in Courses for Link Protector Configuration').
                                  '<ul>'.$suggestions.'</ul>'.
                                  '</li>';
                   }
               }
         }          }
     }      }
     if ($needs_update) {      if ($needs_update) {
Line 15174  sub modify_lti { Line 15793  sub modify_lti {
         }          }
     }      }
     if (ref($currltisec{'linkprot'}) eq 'HASH') {      if (ref($currltisec{'linkprot'}) eq 'HASH') {
         foreach my $id (%{$currltisec{'linkprot'}}) {          foreach my $id (keys(%{$currltisec{'linkprot'}})) {
             next if ($id !~ /^\d+$/);              next if ($id !~ /^\d+$/);
             unless (exists($linkprotchg{$id})) {              unless (exists($linkprotchg{$id})) {
                 if (ref($currltisec{'linkprot'}{$id}) eq 'HASH') {                  if (ref($currltisec{'linkprot'}{$id}) eq 'HASH') {
Line 15196  sub modify_lti { Line 15815  sub modify_lti {
     if ($proterror) {      if ($proterror) {
         $errors .= '<li>'.$proterror.'</li>';          $errors .= '<li>'.$proterror.'</li>';
     }      }
   
       my (%delsuggested,%suggids,@suggested);;
       if (ref($currltisec{'suggested'}) eq 'HASH') {
           my $maxnum = $env{'form.linkprot_suggested_maxnum'};
           my @todelete = &Apache::loncommon::get_env_multiple('form.linkprot_suggested_del');
           for (my $i=0; $i<$maxnum; $i++) {
               my $itemid = $env{'form.linkprot_suggested_id_'.$i};
               $itemid =~ s/\D+//g;
               if ($itemid) {
                   if (ref($currltisec{'suggested'}->{$itemid}) eq 'HASH') {
                       push(@suggested,$i);
                       $suggids{$i} = $itemid;
                       if ((@todelete > 0) && (grep(/^$i$/,@todelete))) {
                           if (ref($currltisec{'suggested'}{$itemid}) eq 'HASH') {
                               $delsuggested{$itemid} = $currltisec{'suggested'}{$itemid}{'name'};
                           }
                       } else {
                           if ($env{'form.linkprot_suggested_name_'.$i} eq '') {
                               $delsuggested{$itemid} = $currltisec{'suggested'}{$itemid}{'name'};
                           } else {
                               $env{'form.linkprot_suggested_name_'.$i} =~ s/(`)/'/g;
                               $env{'form.linkprot_suggested_info_'.$i} =~ s/(`)/'/g;
                               $newltisec{'suggested'}{$itemid}{'name'} = $env{'form.linkprot_suggested_name_'.$i};
                               $newltisec{'suggested'}{$itemid}{'info'} = $env{'form.linkprot_suggested_info_'.$i};
                               if (($currltisec{'suggested'}{$itemid}{'name'} ne $newltisec{'suggested'}{$itemid}{'name'}) ||
                                   ($currltisec{'suggested'}{$itemid}{'info'} ne $newltisec{'suggested'}{$itemid}{'info'})) {
                                   $secchanges{'suggested'}{$itemid} = 1;
                               }
                           }
                       }
                   }
               }
           }
       }
       foreach my $key (keys(%delsuggested)) {
           $newltisec{'suggested'}{$key} = $delsuggested{$key};
           $secchanges{'suggested'}{$key} = 1;
       }
       if (($env{'form.linkprot_suggested_add'}) &&
           ($env{'form.linkprot_suggested_name_add'} ne '')) {
           $env{'form.linkprot_suggested_name_add'} =~ s/(`)/'/g;
           $env{'form.linkprot_suggested_info_add'} =~ s/(`)/'/g;
           my ($newsuggid,$errormsg) = &get_lti_id($dom,$env{'form.linkprot_suggested_name_add'},'suggested');
           if ($newsuggid) {
               $newltisec{'suggested'}{$newsuggid}{'name'} = $env{'form.linkprot_suggested_name_add'};
               $newltisec{'suggested'}{$newsuggid}{'info'} = $env{'form.linkprot_suggested_info_add'};
               $secchanges{'suggested'}{$newsuggid} = 1;
           } else {
               my $error = &mt('Failed to acquire unique ID for new Link Protectors in Courses Suggestion');
               if ($errormsg) {
                   $error .= ' ('.$errormsg.')';
               }
               $errors .= '<li><span class="LC_error">'.$error.'</span></li>';
           }
       }
     my (@items,%deletions,%itemids);      my (@items,%deletions,%itemids);
     if ($env{'form.lti_add'}) {      if ($env{'form.lti_add'}) {
         my $consumer = $env{'form.lti_consumer_add'};          my $consumer = $env{'form.lti_consumer_add'};
         $consumer =~ s/(`)/'/g;          $consumer =~ s/(`)/'/g;
         ($newid,my $error) = &get_lti_id($dom,$consumer);          ($newid,my $errormsg) = &get_lti_id($dom,$consumer,'lti');
         if ($newid) {          if ($newid) {
             $itemids{'add'} = $newid;              $itemids{'add'} = $newid;
             push(@items,'add');              push(@items,'add');
             $changes{$newid} = 1;              $changes{$newid} = 1;
         } else {          } else {
             my $error = &mt('Failed to acquire unique ID for new LTI configuration');              my $error = &mt('Failed to acquire unique ID for new LTI configuration');
               if ($errormsg) {
                   $error .= ' ('.$errormsg.')';
               }
             $errors .= '<li><span class="LC_error">'.$error.'</span></li>';              $errors .= '<li><span class="LC_error">'.$error.'</span></li>';
         }          }
     }      }
Line 15310  sub modify_lti { Line 15987  sub modify_lti {
             }              }
             my @possinstdata =  &Apache::loncommon::get_env_multiple('form.lti_instdata_'.$idx);              my @possinstdata =  &Apache::loncommon::get_env_multiple('form.lti_instdata_'.$idx);
             if (@possinstdata) {              if (@possinstdata) {
                 foreach my $field (@possinstdata) {                  foreach my $field (sort(@possinstdata)) {
                     if (exists($fieldtitles{$field})) {                      if (exists($fieldtitles{$field})) {
                         push(@{$confhash{$itemid}{'instdata'}});                          push(@{$confhash{$itemid}{'instdata'}},$field);
                     }                      }
                 }                  }
             }              }
Line 15474  sub modify_lti { Line 16151  sub modify_lti {
                         }                          }
                     }                      }
                     unless ($changes{$itemid}) {                      unless ($changes{$itemid}) {
                         foreach my $field ('makeuser','lcmenu') {                          foreach my $field ('makeuser','lcmenu','instdata') {
                             if (ref($currlti{$field}) eq 'ARRAY') {                              if (ref($currlti{$field}) eq 'ARRAY') {
                                 if (ref($confhash{$itemid}{$field}) eq 'ARRAY') {                                  if (ref($confhash{$itemid}{$field}) eq 'ARRAY') {
                                     my @diffs = &Apache::loncommon::compare_arrays($currlti{$field},                                      my @diffs = &Apache::loncommon::compare_arrays($currlti{$field},
Line 15688  sub modify_lti { Line 16365  sub modify_lti {
                                 $resulttext .= '<li>'.&mt('Institutional data will be used when creating a new user for: [_1]',                                  $resulttext .= '<li>'.&mt('Institutional data will be used when creating a new user for: [_1]',
                                                           join(', ',map { $fieldtitles{$_}; } @{$confhash{$itemid}{'instdata'}})).'</li>';                                                            join(', ',map { $fieldtitles{$_}; } @{$confhash{$itemid}{'instdata'}})).'</li>';
                             } else {                              } else {
                                 $resulttext .= '<li>'.&mt('No institutional data used when creating a new user.').'</li>';                                  $resulttext .= '<li>'.&mt('No institutional data used when creating a new user').'</li>';
                             }                              }
                           } else {
                               $resulttext .= '<li>'.&mt('No institutional data used when creating a new user').'</li>';
                         }                          }
                         foreach my $item ('topmenu','inlinemenu') {                          foreach my $item ('topmenu','inlinemenu') {
                             $resulttext .= '<li>'.$lt{$item}.':&nbsp;';                              $resulttext .= '<li>'.$lt{$item}.':&nbsp;';
Line 15800  sub modify_lti { Line 16479  sub modify_lti {
         }          }
         $resulttext .= '</ul>';          $resulttext .= '</ul>';
         if (ref($lastactref) eq 'HASH') {          if (ref($lastactref) eq 'HASH') {
             if (($secchanges{'encrypt'}) || ($secchanges{'private'})) {              if (($secchanges{'encrypt'}) || ($secchanges{'private'}) || (exists($secchanges{'suggested'}))) {
                   &Apache::lonnet::get_domain_defaults($dom,1);
                 $lastactref->{'domdefaults'} = 1;                  $lastactref->{'domdefaults'} = 1;
             }              }
         }          }
Line 15839  sub get_priv_creds { Line 16519  sub get_priv_creds {
 }  }
   
 sub get_lti_id {  sub get_lti_id {
     my ($domain,$consumer) = @_;      my ($domain,$consumer,$dbname) = @_;
     # get lock on lti db      unless (($dbname eq 'lti') || ($dbname eq 'suggested')) {
           return ('','invalid db');
       }
       # get lock on db
     my $lockhash = {      my $lockhash = {
                       lock => $env{'user.name'}.                        lock => $env{'user.name'}.
                               ':'.$env{'user.domain'},                                ':'.$env{'user.domain'},
                    };                     };
     my $tries = 0;      my $tries = 0;
     my $gotlock = &Apache::lonnet::newput_dom('lti',$lockhash,$domain);      my $gotlock = &Apache::lonnet::newput_dom($dbname,$lockhash,$domain);
     my ($id,$error);      my ($id,$error);
   
     while (($gotlock ne 'ok') && ($tries<10)) {      while (($gotlock ne 'ok') && ($tries<10)) {
         $tries ++;          $tries ++;
         sleep (0.1);          sleep (0.1);
         $gotlock = &Apache::lonnet::newput_dom('lti',$lockhash,$domain);          $gotlock = &Apache::lonnet::newput_dom($dbname,$lockhash,$domain);
     }      }
     if ($gotlock eq 'ok') {      if ($gotlock eq 'ok') {
         my %currids = &Apache::lonnet::dump_dom('lti',$domain);          my %currids = &Apache::lonnet::dump_dom($dbname,$domain);
         if ($currids{'lock'}) {          if ($currids{'lock'}) {
             delete($currids{'lock'});              delete($currids{'lock'});
             if (keys(%currids)) {              if (keys(%currids)) {
Line 15867  sub get_lti_id { Line 16550  sub get_lti_id {
                 $id = 1;                  $id = 1;
             }              }
             if ($id) {              if ($id) {
                 unless (&Apache::lonnet::newput_dom('lti',{ $id => $consumer },$domain) eq 'ok') {                  unless (&Apache::lonnet::newput_dom($dbname,{ $id => $consumer },$domain) eq 'ok') {
                     $error = 'nostore';                      $error = 'nostore';
                 }                  }
             } else {              } else {
                 $error = 'nonumber';                  $error = 'nonumber';
             }              }
         }          }
         my $dellockoutcome = &Apache::lonnet::del_dom('lti',['lock'],$domain);          my $dellockoutcome = &Apache::lonnet::del_dom($dbname,['lock'],$domain);
     } else {      } else {
         $error = 'nolock';          $error = 'nolock';
     }      }
Line 17147  sub modify_privacy { Line 17830  sub modify_privacy {
                                        extdom  => {},                                         extdom  => {},
                                      },                                       },
                        'othdom'   => {},                         'othdom'   => {},
                        'priv'     => {},  
                        'unpriv'   => {},  
                       );                        );
     foreach my $item (@items) {      foreach my $item (@items) {
         if (@instdoms > 1) {          if (@instdoms > 1) {
Line 17179  sub modify_privacy { Line 17860  sub modify_privacy {
                 $changes{'approval'} = 1;                  $changes{'approval'} = 1;
             }              }
         }          }
         foreach my $status ('priv','unpriv') {  
             my @possibles = sort(&Apache::loncommon::get_env_multiple('form.privacy_'.$status.'_'.$item));  
             my @newvalues;  
             foreach my $field (@possibles) {  
                 if (grep(/^\Q$field\E$/,@fields)) {  
                     $privacyhash{$status}{$item}{$field} = 1;  
                     push(@newvalues,$field);  
                 }  
             }  
             @newvalues = sort(@newvalues);  
             if (ref($current{$status}) eq 'HASH') {  
                 if (ref($current{$status}{$item}) eq 'HASH') {  
                     my @currvalues = sort(keys(%{$current{$status}{$item}}));  
                     my @diffs = &Apache::loncommon::compare_arrays(\@currvalues,\@newvalues);  
                     if (@diffs > 0) {  
                         $changes{$status} = 1;  
                     }  
                 }  
             } else {  
                 my @stdfields;  
                 foreach my $field (@fields) {  
                     if ($field eq 'id') {  
                         next if ($status eq 'unpriv');  
                         next if (($status eq 'priv') && ($item eq 'community'));  
                     }  
                     push(@stdfields,$field);  
                 }  
                 my @diffs = &Apache::loncommon::compare_arrays(\@stdfields,\@newvalues);  
                 if (@diffs > 0) {  
                     $changes{$status} = 1;  
                 }  
             }  
         }  
     }      }
     if ((@instdoms > 1) || (keys(%by_location) > 0)) {      if ((@instdoms > 1) || (keys(%by_location) > 0)) {
         my @statuses;          my @statuses;
Line 17235  sub modify_privacy { Line 17883  sub modify_privacy {
                     if (@diffs > 0) {                      if (@diffs > 0) {
                         $changes{'othdom'} = 1;                          $changes{'othdom'} = 1;
                     }                      }
                   } elsif (@newvalues > 0) {
                       $changes{'othdom'} = 1;
                 }                  }
             } else {              } else {
                 my @stdfields = ('lastname','firstname','middlename','generation','permanentemail');                  my @stdfields = ('lastname','firstname','middlename','generation','permanentemail');
Line 17264  sub modify_privacy { Line 17914  sub modify_privacy {
     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>';
             foreach my $key ('approval','notify','othdom','priv','unpriv') {              foreach my $key ('approval','notify','othdom') {
                 if ($changes{$key}) {                  if ($changes{$key}) {
                     $resulttext .= '<li>'.$titles{$key}.':<ul>';                      $resulttext .= '<li>'.$titles{$key}.':<ul>';
                     if ($key eq 'approval') {                      if ($key eq 'approval') {
Line 17315  sub modify_privacy { Line 17965  sub modify_privacy {
                                 $resulttext .= '</li>';                                  $resulttext .= '</li>';
                             }                              }
                         }                          }
                     } else {  
                         foreach my $item (@items) {  
                             if (ref($privacyhash{$key}{$item}) eq 'HASH') {  
                                 $resulttext .= '<li>'.$names{$item}.': ';  
                                 if (keys(%{$privacyhash{$key}{$item}})) {  
                                     $resulttext .= join(', ', map { $fieldnames{$_}; } (sort(keys(%{$privacyhash{$key}{$item}}))));  
                                 } else {  
                                     $resulttext .= &mt('none');  
                                 }  
                                 $resulttext .= '</li>';  
                             }  
                         }  
                     }                      }
                     $resulttext .= '</ul></li>';                      $resulttext .= '</ul></li>';
                 }                  }
Line 17389  sub modify_passwords { Line 18027  sub modify_passwords {
         min            => 'Minimum password length',          min            => 'Minimum password length',
         max            => 'Maximum password length',          max            => 'Maximum password length',
         chars          => 'Required characters',          chars          => 'Required characters',
         expire         => 'Password expiration (days)',  
         numsaved       => 'Number of previous passwords to save',          numsaved       => 'Number of previous passwords to save',
         reset          => 'Resetting Forgotten Password',          reset          => 'Resetting Forgotten Password',
         intauth        => 'Encryption of Stored Passwords (Internal Auth)',          intauth        => 'Encryption of Stored Passwords (Internal Auth)',
Line 17773  sub modify_passwords { Line 18410  sub modify_passwords {
                             $resulttext .= '<li>'.&mt('[_1] set to "[_2]"',$titles{$key.'_'.$item},$value).'</li>';                              $resulttext .= '<li>'.&mt('[_1] set to "[_2]"',$titles{$key.'_'.$item},$value).'</li>';
                         }                          }
                     } elsif ($key eq 'rules') {                      } elsif ($key eq 'rules') {
                         foreach my $rule ('min','max','expire','numsaved') {                          foreach my $rule ('min','max','numsaved') {
                             if ($confighash{'passwords'}{$rule} eq '') {                              if ($confighash{'passwords'}{$rule} eq '') {
                                 if ($rule eq 'min') {                                  if ($rule eq 'min') {
                                     $resulttext .= '<li>'.&mt('[_1] not set.',$titles{$rule});                                      $resulttext .= '<li>'.&mt('[_1] not set.',$titles{$rule});
Line 17868  sub password_rule_changes { Line 18505  sub password_rule_changes {
                    (ref($changes) eq 'HASH'));                     (ref($changes) eq 'HASH'));
     my (@rules,%staticdefaults);      my (@rules,%staticdefaults);
     if ($prefix eq 'passwords') {      if ($prefix eq 'passwords') {
         @rules = ('min','max','expire','numsaved');          @rules = ('min','max','numsaved');
     } elsif (($prefix eq 'ltisecrets') || ($prefix eq 'toolsecrets')) {      } elsif (($prefix eq 'ltisecrets') || ($prefix eq 'toolsecrets')) {
         @rules = ('min','max');          @rules = ('min','max');
     }      }
Line 17876  sub password_rule_changes { Line 18513  sub password_rule_changes {
     foreach my $rule (@rules) {      foreach my $rule (@rules) {
         $env{'form.'.$prefix.'_'.$rule} =~ s/^\s+|\s+$//g;          $env{'form.'.$prefix.'_'.$rule} =~ s/^\s+|\s+$//g;
         my $ruleok;          my $ruleok;
         if ($rule eq 'expire') {          if ($rule eq 'min') {
             if (($env{'form.'.$prefix.'_'.$rule} =~ /^\d+(|\.\d*)$/) &&  
                 ($env{'form.'.$prefix.'_'.$rule} ne '0')) {  
                 $ruleok = 1;  
             }  
         } elsif ($rule eq 'min') {  
             if ($env{'form.'.$prefix.'_'.$rule} =~ /^\d+$/) {              if ($env{'form.'.$prefix.'_'.$rule} =~ /^\d+$/) {
                 if ($env{'form.'.$prefix.'_'.$rule} >= $staticdefaults{$rule}) {                  if ($env{'form.'.$prefix.'_'.$rule} >= $staticdefaults{$rule}) {
                     $ruleok = 1;                      $ruleok = 1;
Line 19110  sub modify_usermodification { Line 19742  sub modify_usermodification {
             }              }
         }          }
     }      }
     my @contexts = ('author','course');      my @contexts = ('author','coauthor','course');
     my %context_title = (      my %context_title = (
                            author => 'In author context',                             author => 'In author context',
                              coauthor => 'As co-author manager',
                            course => 'In course context',                             course => 'In course context',
                         );                          );
     my @fields = ('lastname','firstname','middlename','generation',      my @fields = ('lastname','firstname','middlename','generation',
                   'permanentemail','id');                    'permanentemail','id');
     my %roles = (      my %roles = (
                   author => ['ca','aa'],                    author => ['ca','aa'],
                     coauthor => ['ca','aa'],
                   course => ['st','ep','ta','in','cr'],                    course => ['st','ep','ta','in','cr'],
                 );                  );
     my %fieldtitles = &Apache::loncommon::personal_data_fieldtitles();      my %fieldtitles = &Apache::loncommon::personal_data_fieldtitles();
     foreach my $context (@contexts) {      foreach my $context (@contexts) {
           my $prefix = 'canmodify';
           if ($context eq 'coauthor') {
               $prefix = 'cacanmodify';
           }
         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.'.$prefix.'_'.$role);
             foreach my $item (@fields) {              foreach my $item (@fields) {
                 if (grep(/^\Q$item\E$/,@modifiable)) {                  if (grep(/^\Q$item\E$/,@modifiable)) {
                     $modifyhash{$context}{$role}{$item} = 1;                      $modifyhash{$context}{$role}{$item} = 1;
Line 20491  sub modify_coursedefaults { Line 21129  sub modify_coursedefaults {
     my @toggles = ('canuse_pdfforms','uselcmath','usejsme','inline_chem','ltiauth');      my @toggles = ('canuse_pdfforms','uselcmath','usejsme','inline_chem','ltiauth');
     my @numbers = ('anonsurvey_threshold','uploadquota_official','uploadquota_unofficial',      my @numbers = ('anonsurvey_threshold','uploadquota_official','uploadquota_unofficial',
                    'uploadquota_community','uploadquota_textbook','uploadquota_placement',                     'uploadquota_community','uploadquota_textbook','uploadquota_placement',
                    'mysqltables_official','mysqltables_unofficial','mysqltables_community',                     'coursequota_official','coursequota_unofficial','coursequota_community',
                    'mysqltables_textbook','mysqltables_placement');                     'coursequota_textbook','coursequota_placement','mysqltables_official',
                      'mysqltables_unofficial','mysqltables_community','mysqltables_textbook',
                      'mysqltables_placement');
     my @types = ('official','unofficial','community','textbook','placement');      my @types = ('official','unofficial','community','textbook','placement');
     my %staticdefaults = (      my %staticdefaults = (
                            anonsurvey_threshold => 10,                             anonsurvey_threshold => 10,
                            uploadquota          => 500,                             uploadquota          => 500,
                              coursequota          => 20,
                            postsubmit           => 60,                             postsubmit           => 60,
                            mysqltables          => 172800,                             mysqltables          => 172800,
                            domexttool           => 1,                             domexttool           => 1,
                              crsauthor            => 1,
                              crseditors           => ['edit','xml'],
                          );                           );
     my %texoptions = (      my %texoptions = (
                         MathJax  => 'MathJax',                          MathJax  => 'MathJax',
                         mimetex  => &mt('Convert to Images'),                          mimetex  => &mt('Convert to Images'),
                         tth      => &mt('TeX to HTML'),                          tth      => &mt('TeX to HTML'),
                      );                       );
   
       my @editors = ('edit','xml','daxe');
       my %editornames = &crseditor_titles();
   
     $defaultshash{'coursedefaults'} = {};      $defaultshash{'coursedefaults'} = {};
   
     if (ref($domconfig{'coursedefaults'}) ne 'HASH') {      if (ref($domconfig{'coursedefaults'}) ne 'HASH') {
Line 20544  sub modify_coursedefaults { Line 21191  sub modify_coursedefaults {
                 }                  }
                 $defaultshash{'coursedefaults'}{$item} = $newdef;                  $defaultshash{'coursedefaults'}{$item} = $newdef;
             } else {              } else {
                 my ($setting,$type) = ($item =~ /^(uploadquota|mysqltables)_(\w+)$/);                  my ($setting,$type) = ($item =~ /^(uploadquota|coursequota|mysqltables)_(\w+)$/);
                 if (ref($domconfig{'coursedefaults'}{$setting}) eq 'HASH') {                  if (ref($domconfig{'coursedefaults'}{$setting}) eq 'HASH') {
                     $currdef = $domconfig{'coursedefaults'}{$setting}{$type};                      $currdef = $domconfig{'coursedefaults'}{$setting}{$type};
                 }                  }
Line 20556  sub modify_coursedefaults { Line 21203  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)_/) {                  } elsif ($item =~ /^(uploadquota|coursequota|mysqltables)_/) {
                     my $setting = $1;                      my $setting = $1;
                     unless (($currdef eq '') && ($newdef == $staticdefaults{$setting})) {                      unless (($currdef eq '') && ($newdef == $staticdefaults{$setting})) {
                         $changes{$setting} = 1;                          $changes{$setting} = 1;
Line 20691  sub modify_coursedefaults { Line 21338  sub modify_coursedefaults {
                 $changes{'postsubmit'} = 1;                  $changes{'postsubmit'} = 1;
             }              }
         }          }
         my (%newdomexttool,%newexttool,%olddomexttool,%oldexttool);          my (%newdomexttool,%newexttool,%newcrsauthor,%olddomexttool,%oldexttool,%oldcrsauthor,
               %posscrseditors);
         map { $newdomexttool{$_} = 1; } &Apache::loncommon::get_env_multiple('form.domexttool');          map { $newdomexttool{$_} = 1; } &Apache::loncommon::get_env_multiple('form.domexttool');
         map { $newexttool{$_} = 1; } &Apache::loncommon::get_env_multiple('form.exttool');          map { $newexttool{$_} = 1; } &Apache::loncommon::get_env_multiple('form.exttool');
           map { $newcrsauthor{$_} = 1; } &Apache::loncommon::get_env_multiple('form.crsauthor');
           map { $posscrseditors{$_} = 1; } &Apache::loncommon::get_env_multiple('form.crseditors');
         if (ref($domconfig{'coursedefaults'}{'domexttool'}) eq 'HASH') {          if (ref($domconfig{'coursedefaults'}{'domexttool'}) eq 'HASH') {
             %olddomexttool = %{$domconfig{'coursedefaults'}{'domexttool'}};              %olddomexttool = %{$domconfig{'coursedefaults'}{'domexttool'}};
         } else {          } else {
Line 20716  sub modify_coursedefaults { Line 21366  sub modify_coursedefaults {
                }                 }
             }              }
         }          }
           if (ref($domconfig{'coursedefaults'}{'crsauthor'}) eq 'HASH') {
               %oldcrsauthor = %{$domconfig{'coursedefaults'}{'crsauthor'}};
           } else {
               foreach my $type (@types) {
                  if ($staticdefaults{'crsauthor'}) {
                      $oldcrsauthor{$type} = 1;
                  } else {
                      $oldcrsauthor{$type} = 0;
                  }
               }
           }
           my @newcrseditors = ();
           foreach my $editor (@editors) {
               if ($posscrseditors{$editor}) {
                   push(@newcrseditors,$editor);
               }
           }
           if (ref($domconfig{'coursedefaults'}{'crseditors'}) eq 'ARRAY') {
               my @diffs =
                   &Apache::loncommon::compare_arrays($domconfig{'coursedefaults'}{'crseditors'},
                                                      \@newcrseditors);
               if (@diffs) {
                   $changes{'crseditors'} = 1; 
               }
           } else {
               my @diffs =
                   &Apache::loncommon::compare_arrays($staticdefaults{'crseditors'},
                                                      \@newcrseditors);
               unless (@diffs == 0) {
                   $changes{'crseditors'} = 1;
               }       
           }
         foreach my $type (@types) {          foreach my $type (@types) {
             unless ($newdomexttool{$type}) {              unless ($newdomexttool{$type}) {
                 $newdomexttool{$type} = 0;                  $newdomexttool{$type} = 0;
Line 20723  sub modify_coursedefaults { Line 21405  sub modify_coursedefaults {
             unless ($newexttool{$type}) {              unless ($newexttool{$type}) {
                 $newexttool{$type} = 0;                  $newexttool{$type} = 0;
             }              }
               unless ($newcrsauthor{$type}) {
                   $newcrsauthor{$type} = 0;
               }
             if ($newdomexttool{$type} != $olddomexttool{$type}) {              if ($newdomexttool{$type} != $olddomexttool{$type}) {
                 $changes{'domexttool'} = 1;                  $changes{'domexttool'} = 1;
             }              }
             if ($newexttool{$type} != $oldexttool{$type}) {              if ($newexttool{$type} != $oldexttool{$type}) {
                 $changes{'exttool'} = 1;                  $changes{'exttool'} = 1;
             }              }
               if ($newcrsauthor{$type} != $oldcrsauthor{$type}) {
                   $changes{'crsauthor'} = 1;
               }
         }          }
         $defaultshash{'coursedefaults'}{'domexttool'} = \%newdomexttool;          $defaultshash{'coursedefaults'}{'domexttool'} = \%newdomexttool;
         $defaultshash{'coursedefaults'}{'exttool'} = \%newexttool;          $defaultshash{'coursedefaults'}{'exttool'} = \%newexttool;
           $defaultshash{'coursedefaults'}{'crsauthor'} = \%newcrsauthor;
           $defaultshash{'coursedefaults'}{'crseditors'} = \@newcrseditors;
     }      }
     my $putresult = &Apache::lonnet::put_dom('configuration',\%defaultshash,      my $putresult = &Apache::lonnet::put_dom('configuration',\%defaultshash,
                                              $dom);                                               $dom);
Line 20742  sub modify_coursedefaults { Line 21432  sub modify_coursedefaults {
                 ($changes{'coursecredits'}) || ($changes{'uselcmath'}) || ($changes{'usejsme'}) ||                  ($changes{'coursecredits'}) || ($changes{'uselcmath'}) || ($changes{'usejsme'}) ||
                 ($changes{'canclone'}) || ($changes{'mysqltables'}) || ($changes{'texengine'}) ||                  ($changes{'canclone'}) || ($changes{'mysqltables'}) || ($changes{'texengine'}) ||
                 ($changes{'inline_chem'}) || ($changes{'ltiauth'}) || ($changes{'domexttool'}) ||                  ($changes{'inline_chem'}) || ($changes{'ltiauth'}) || ($changes{'domexttool'}) ||
                 ($changes{'exttool'}) ) {                  ($changes{'exttool'}) || ($changes{'coursequota'}) || ($changes{'crsauthor'})) {
                 foreach my $item ('canuse_pdfforms','uselcmath','usejsme','inline_chem','texengine',                  foreach my $item ('canuse_pdfforms','uselcmath','usejsme','inline_chem','texengine',
                                   'ltiauth') {                                    'ltiauth') {
                     if ($changes{$item}) {                      if ($changes{$item}) {
Line 20775  sub modify_coursedefaults { Line 21465  sub modify_coursedefaults {
                         }                          }
                     }                      }
                 }                  }
                   if ($changes{'coursequota'}) {
                       if (ref($defaultshash{'coursedefaults'}{'coursequota'}) eq 'HASH') {
                           foreach my $type (@types) {
                               $domdefaults{$type.'coursequota'}=$defaultshash{'coursedefaults'}{'coursequota'}{$type};
                           }
                       }
                   }
                 if ($changes{'canclone'}) {                  if ($changes{'canclone'}) {
                     if (ref($defaultshash{'coursedefaults'}{'canclone'}) eq 'HASH') {                      if (ref($defaultshash{'coursedefaults'}{'canclone'}) eq 'HASH') {
                         if (ref($defaultshash{'coursedefaults'}{'canclone'}{'instcode'}) eq 'ARRAY') {                          if (ref($defaultshash{'coursedefaults'}{'canclone'}{'instcode'}) eq 'ARRAY') {
Line 20801  sub modify_coursedefaults { Line 21498  sub modify_coursedefaults {
                         }                          }
                     }                      }
                 }                  }
                   if ($changes{'crsauthor'}) {
                       if (ref($defaultshash{'coursedefaults'}{'crsauthor'}) eq 'HASH') {
                           foreach my $type (@types) {
                               $domdefaults{$type.'crsauthor'}=$defaultshash{'coursedefaults'}{'crsauthor'}{$type};
                           }
                       }
                   }
                   if ($changes{'crseditors'}) {
                       if (ref($defaultshash{'coursedefaults'}{'crseditors'}) eq 'ARRAY') {
                           $domdefaults{'crseditors'}=join(',',@{$defaultshash{'coursedefaults'}{'crseditors'}});
                       }
                   }
                 my $cachetime = 24*60*60;                  my $cachetime = 24*60*60;
                 &Apache::lonnet::do_cache_new('domdefaults',$dom,\%domdefaults,$cachetime);                  &Apache::lonnet::do_cache_new('domdefaults',$dom,\%domdefaults,$cachetime);
                 if (ref($lastactref) eq 'HASH') {                  if (ref($lastactref) eq 'HASH') {
Line 20853  sub modify_coursedefaults { Line 21562  sub modify_coursedefaults {
                     } 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 'coursequota') {
                       if (ref($defaultshash{'coursedefaults'}{'coursequota'}) eq 'HASH') {
                           $resulttext .= '<li>'.&mt('Default cumulative quota for all group portfolio spaces in course set as follows:').'<ul>'.
                                          '<li>'.&mt('Official courses: [_1] MB','<b>'.$defaultshash{'coursedefaults'}{'coursequota'}{'official'}.'</b>').'</li>'.
                                          '<li>'.&mt('Unofficial courses: [_1] MB','<b>'.$defaultshash{'coursedefaults'}{'coursequota'}{'unofficial'}.'</b>').'</li>'.
                                          '<li>'.&mt('Textbook courses: [_1] MB','<b>'.$defaultshash{'coursedefaults'}{'coursequota'}{'textbook'}.'</b>').'</li>'.
                                          '<li>'.&mt('Placement tests: [_1] MB','<b>'.$defaultshash{'coursedefaults'}{'coursequota'}{'placement'}.'</b>').'</li>'.
                                          '<li>'.&mt('Communities: [_1] MB','<b>'.$defaultshash{'coursedefaults'}{'coursequota'}{'community'}.'</b>').'</li>'.
                                          '</ul>'.
                                          '</li>';
                       } else {
                           $resulttext .= '<li>'.&mt('Default cumulative quota for all group portfolio spaces in course remains default: [_1] MB',$staticdefaults{'coursequota'}).'</li>';
                       }
                 } elsif ($item eq 'mysqltables') {                  } elsif ($item eq 'mysqltables') {
                     if (ref($defaultshash{'coursedefaults'}{'mysqltables'}) eq 'HASH') {                      if (ref($defaultshash{'coursedefaults'}{'mysqltables'}) eq 'HASH') {
                         $resulttext .= '<li>'.&mt('Lifetime of "Temporary" MySQL tables (student performance data) on homeserver').'<ul>'.                          $resulttext .= '<li>'.&mt('Lifetime of "Temporary" MySQL tables (student performance data) on homeserver').'<ul>'.
Line 20938  sub modify_coursedefaults { Line 21660  sub modify_coursedefaults {
                     } else {                      } else {
                         $resulttext .= '<li>'.&mt('LTI launch of deep-linked URL will require re-authentication').'</li>';                          $resulttext .= '<li>'.&mt('LTI launch of deep-linked URL will require re-authentication').'</li>';
                     }                      }
                 } elsif ($item eq 'domexttool') {                  } elsif (($item eq 'domexttool') || ($item eq 'exttool') || ($item eq 'crsauthor')) {
                     my @noyes = (&mt('no'),&mt('yes'));                      my @noyes = (&mt('no'),&mt('yes'));
                     if (ref($defaultshash{'coursedefaults'}{'domexttool'}) eq 'HASH') {                      my %status = (
                         $resulttext .= '<li>'.&mt('External Tools defined in the domain may be used as follows:').'<ul>'.                                     domexttool => {
                                        '<li>'.&mt('Official courses: [_1]','<b>'.$noyes[$defaultshash{'coursedefaults'}{'domexttool'}{'official'}].'</b>').'</li>'.                                                    ishash => &mt('External Tools defined in the domain may be used as follows:'), 
                                        '<li>'.&mt('Unofficial courses: [_1]','<b>'.$noyes[$defaultshash{'coursedefaults'}{'domexttool'}{'unofficial'}].'</b>').'</li>'.                                                    default => &mt('External Tools defined in the domain may be used in all course types, by default'),
                                        '<li>'.&mt('Textbook courses: [_1]','<b>'.$noyes[$defaultshash{'coursedefaults'}{'domexttool'}{'textbook'}].'</b>').'</li>'.                                                   },
                                        '<li>'.&mt('Placement tests: [_1]','<b>'.$noyes[$defaultshash{'coursedefaults'}{'domexttool'}{'placement'}].'</b>').'</li>'.                                     exttool => {
                                        '<li>'.&mt('Communities: [_1]','<b>'.$noyes[$defaultshash{'coursedefaults'}{'domexttool'}{'community'}].'</b>').'</li>'.                                                    ishash => &mt('External Tools can be defined and configured in course containers as follows:'),
                                                     default => &mt('External Tools can not be defined in any course types, by default'),
                                                 },
                                      crsauthor => {
                                                     ishash => &mt('Standard Problems can be created within course containers as follows:'),
                                                     default => &mt('Standard Problems can be created within any course type, by default'),
                                                   },
                                    );
                                      
                       if (ref($defaultshash{'coursedefaults'}{$item}) eq 'HASH') {
                           $resulttext .= '<li>'.$status{$item}{'ishash'}.'<ul>'.
                                          '<li>'.&mt('Official courses: [_1]','<b>'.$noyes[$defaultshash{'coursedefaults'}{$item}{'official'}].'</b>').'</li>'.
                                          '<li>'.&mt('Unofficial courses: [_1]','<b>'.$noyes[$defaultshash{'coursedefaults'}{$item}{'unofficial'}].'</b>').'</li>'.
                                          '<li>'.&mt('Textbook courses: [_1]','<b>'.$noyes[$defaultshash{'coursedefaults'}{$item}{'textbook'}].'</b>').'</li>'.
                                          '<li>'.&mt('Placement tests: [_1]','<b>'.$noyes[$defaultshash{'coursedefaults'}{$item}{'placement'}].'</b>').'</li>'.
                                          '<li>'.&mt('Communities: [_1]','<b>'.$noyes[$defaultshash{'coursedefaults'}{$item}{'community'}].'</b>').'</li>'.
                                        '</ul>'.                                         '</ul>'.
                                        '</li>';                                         '</li>';
                     } else {                      } else {
                         $resulttext .= '<li>'.&mt('External Tools defined in the domain may be used in all course types, by default').'</li>';                          $resulttext .= '<li>'.$status{$item}{'default'}.'</li>';
                     }                      }
                 } elsif ($item eq 'exttool') {                  } elsif ($item eq 'crseditors') {
                     my @noyes = (&mt('no'),&mt('yes'));                      if (ref($defaultshash{'coursedefaults'}{$item}) eq 'ARRAY') {
                     if (ref($defaultshash{'coursedefaults'}{'exttool'}) eq 'HASH') {                          my $shown;
                         $resulttext .= '<li>'.&mt('External Tools can be defined and configured in course containers as follows:').'<ul>'.                          if (@{$defaultshash{'coursedefaults'}{$item}}) {
                                        '<li>'.&mt('Official courses: [_1]','<b>'.$noyes[$defaultshash{'coursedefaults'}{'exttool'}{'official'}].'</b>').'</li>'.                              $shown = join(', ', map { $editornames{$_} } @{$defaultshash{'coursedefaults'}{$item}});
                                        '<li>'.&mt('Unofficial courses: [_1]','<b>'.$noyes[$defaultshash{'coursedefaults'}{'exttool'}{'unofficial'}].'</b>').'</li>'.                          } else {
                                        '<li>'.&mt('Textbook courses: [_1]','<b>'.$noyes[$defaultshash{'coursedefaults'}{'exttool'}{'textbook'}].'</b>').'</li>'.                              $shown = &mt('None');
                                        '<li>'.&mt('Placement tests: [_1]','<b>'.$noyes[$defaultshash{'coursedefaults'}{'exttool'}{'placement'}].'</b>').'</li>'.                          }
                                        '<li>'.&mt('Communities: [_1]','<b>'.$noyes[$defaultshash{'coursedefaults'}{'exttool'}{'community'}].'</b>').'</li>'.                          $resulttext .= '<li>'.&mt('Available editors for course/community resources: [_1]',$shown).'</li>';
                                        '</ul>'.  
                                        '</li>';  
                     } else {  
                         $resulttext .= '<li>'.&mt('External Tools can not be defined in any course types, by default').'</li>';  
                     }                      }
                 }                  }
             }              }

Removed from v.1.427  
changed lines
  Added in v.1.447.2.6


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