--- loncom/interface/domainprefs.pm 2008/12/09 04:46:02 1.73 +++ loncom/interface/domainprefs.pm 2010/07/17 20:02:07 1.137 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # Handler to set domain-wide configuration settings # -# $Id: domainprefs.pm,v 1.73 2008/12/09 04:46:02 raeburn Exp $ +# $Id: domainprefs.pm,v 1.137 2010/07/17 20:02:07 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -28,6 +28,131 @@ ############################################################### ############################################################## +=pod + +=head1 NAME + +Apache::domainprefs.pm + +=head1 SYNOPSIS + +Handles configuration of a LON-CAPA domain. + +This is part of the LearningOnline Network with CAPA project +described at http://www.lon-capa.org. + + +=head1 OVERVIEW + +Each institution using LON-CAPA will typically have a single domain designated +for use by individuals affliated with the institution. Accordingly, each domain +may define a default set of logos and a color scheme which can be used to "brand" +the LON-CAPA instance. In addition, an institution will typically have a language +and timezone which are used for the majority of courses. + +LON-CAPA provides a mechanism to display and modify these defaults, as well as a +host of other domain-wide settings which determine the types of functionality +available to users and courses in the domain. + +There is also a mechanism to configure cataloging of courses in the domain, and +controls on the operation of automated processes which govern such things as +roster updates, user directory updates and processing of course requests. + +The domain coordination manual which is built dynamically on install/update of +LON-CAPA from the relevant help items provides more information about domain +configuration. + +Most of the domain settings are stored in the configuration.db GDBM file which is +housed on the primary library server for the domain in /home/httpd/lonUsers/$dom, +where $dom is the domain. The configuration.db stores settings in a number of +frozen hashes of hashes. In a few cases, domain information must be uploaded to +the domain as files (e.g., image files for logos etc., or plain text files for +bubblesheet formats). In this case the domainprefs.pm must be running in a user +session hosted on the primary library server in the domain, as these files are +stored in author space belonging to a special $dom-domainconfig user. + +domainprefs.pm in combination with lonconfigsettings.pm will retrieve and display +the current settings, and provides an interface to make modifications. + +=head1 SUBROUTINES + +=over + +=item print_quotas() + +Inputs: 4 + +$dom,$settings,$rowtotal,$action. + +$dom is the domain, $settings is a reference to a hash of current settings for +the current context, $rowtotal is a reference to the scalar used to record the +number of rows displayed on the page, and $action is the context (either quotas +or requestcourses). + +The print_quotas routine was orginally created to display/store information +about default quota sizes for portfolio spaces for the different types of +institutional affiliation in the domain (e.g., Faculty, Staff, Student etc.), +but is now also used to manage availability of user tools: +i.e., blogs, aboutme page, and portfolios, and the course request tool, +used by course owners to request creation of a course. + +Outputs: 1 + +$datatable - HTML containing form elements which allow settings to be changed. + +In the case of course requests, radio buttons are displayed for each institutional +affiliate type (and also default, and _LC_adv) for each of the course types +(official, unofficial and community). In each case the radio buttons allow the +selection of one of four values: + +0, approval, validate, autolimit=N (where N is blank, or a positive integer). +which have the following effects: + +0 + +=over + +- course requests are not allowed for this course types/affiliation + +=back + +approval + +=over + +- course requests must be approved by a Doman Coordinator in the +course's domain + +=back + +validate + +=over + +- an institutional validation (e.g., check requestor is instructor +of record) needs to be passed before the course will be created. The required +validation is in localenroll.pm on the primary library server for the course +domain. + +=back + +autolimit + +=over + +- course requests will be processed autoatically up to a limit of +N requests for the course type for the particular requestor. +If N is undefined, there is no limit to the number of course requests +which a course owner may submit and have processed automatically. + +=back + +=item modify_quotas() + +=back + +=cut + package Apache::domainprefs; use strict; @@ -37,9 +162,10 @@ use Apache::loncommon(); use Apache::lonhtmlcommon(); use Apache::lonlocal; use Apache::lonmsg(); +use Apache::lonconfigsettings; use LONCAPA qw(:DEFAULT :match); use LONCAPA::Enrollment; -use LONCAPA::loncgi(); +use LONCAPA::lonauthcgi(); use File::Copy; use Locale::Language; use DateTime::TimeZone; @@ -53,6 +179,7 @@ sub handler { return OK; } + my $context = 'domain'; my $dom = $env{'request.role.domain'}; my $domdesc = &Apache::lonnet::domain($dom,'description'); if (&Apache::lonnet::allowed('mau',$dom)) { @@ -72,13 +199,16 @@ sub handler { } my %domconfig = &Apache::lonnet::get_dom('configuration',['login','rolecolors', - 'quotas','autoenroll','autoupdate','directorysrch', - 'usercreation','usermodification','contacts','defaults', - 'scantron','coursecategories','serverstatuses'],$dom); + 'quotas','autoenroll','autoupdate','autocreate', + 'directorysrch','usercreation','usermodification', + 'contacts','defaults','scantron','coursecategories', + 'serverstatuses','requestcourses','helpsettings', + 'coursedefaults','usersessions'],$dom); my @prefs_order = ('rolecolors','login','defaults','quotas','autoenroll', - 'autoupdate','directorysrch','contacts', + 'autoupdate','autocreate','directorysrch','contacts', 'usercreation','usermodification','scantron', - 'coursecategories','serverstatuses'); + 'requestcourses','coursecategories','serverstatuses','helpsettings', + 'coursedefaults','usersessions'); my %prefs = ( 'rolecolors' => { text => 'Default color schemes', @@ -92,12 +222,13 @@ sub handler { {col1 => 'Administrator Settings', col2 => '',}], }, - 'login' => + 'login' => { text => 'Log-in page options', help => 'Domain_Configuration_Login_Page', header => [{col1 => 'Item', col2 => '',}], }, + 'defaults' => { text => 'Default authentication/language/timezone', help => 'Domain_Configuration_LangTZAuth', @@ -105,9 +236,9 @@ sub handler { col2 => 'Value'}], }, 'quotas' => - { text => 'User blogs, home pages and portfolios', + { text => 'User blogs, personal information pages, portfolios', help => 'Domain_Configuration_Quotas', - header => [{col1 => 'User type', + header => [{col1 => 'User affiliation', col2 => 'Available tools', col3 => 'Portfolio quota',}], }, @@ -122,8 +253,16 @@ sub handler { help => 'Domain_Configuration_Auto_Updates', header => [{col1 => 'Setting', col2 => 'Value',}, + {col1 => 'Setting', + col2 => 'Affiliation'}, {col1 => 'User population', - col2 => 'Updataeable user data'}], + col2 => 'Updateable user data'}], + }, + 'autocreate' => + { text => 'Auto-course creation settings', + help => 'Domain_Configuration_Auto_Creation', + header => [{col1 => 'Configuration Setting', + col2 => 'Value',}], }, 'directorysrch' => { text => 'Institutional directory searches', @@ -159,14 +298,22 @@ sub handler { col2 => 'Information settable when self-creating account (if directory data blank)'}], }, 'scantron' => - { text => 'Scantron format file', + { text => 'Bubblesheet format file', help => 'Domain_Configuration_Scantron_Format', header => [ {col1 => 'Item', col2 => '', }], }, + 'requestcourses' => + {text => 'Request creation of courses', + help => 'Domain_Configuration_Request_Courses', + header => [{col1 => 'User affiliation', + col2 => 'Availability/Processing of requests',}, + {col1 => 'Setting', + col2 => 'Value'}], + }, 'coursecategories' => - { text => 'Cataloging of courses', + { text => 'Cataloging of courses/communities', help => 'Domain_Configuration_Cataloging_Courses', header => [{col1 => 'Category settings', col2 => '',}, @@ -175,113 +322,63 @@ sub handler { }], }, 'serverstatuses' => - {text => 'Access to Server Status Pages', + {text => 'Access to server status pages', help => 'Domain_Configuration_Server_Status', header => [{col1 => 'Status Page', col2 => 'Other named users', col3 => 'Specific IPs', }], }, + 'helpsettings' => + {text => 'Help page settings', + help => 'Domain_Configuration_Help_Settings', + header => [{col1 => 'Authenticated Help Settings', + col2 => ''}, + {col1 => 'Unauthenticated Help Settings', + col2 => ''}], + }, + 'coursedefaults' => + {text => 'Course/Community defaults', + help => 'Domain_Configuration_Course_Defaults', + header => [{col1 => 'Setting', + col2 => 'Value',}], + }, + 'privacy' => + {text => 'User Privacy', + help => 'Domain_Configuration_User_Privacy', + header => [{col1 => 'Setting', + col2 => 'Value',}], + }, + 'usersessions' => + {text => 'User session hosting', + help => 'Domain_Configuration_User_Sessions', + header => [{col1 => 'Hosting of users from other domains', + col2 => 'Rules'}, + {col1 => "Hosting domain's own users elsewhere", + col2 => 'Rules'}], + }, ); + my %servers = &dom_servers($dom); + if (keys(%servers) > 1) { + $prefs{'login'} = { text => 'Log-in page options', + help => 'Domain_Configuration_Login_Page', + header => [{col1 => 'Log-in Service', + col2 => 'Server Setting',}, + {col1 => 'Log-in Page Items', + col2 => ''}], + }; + } my @roles = ('student','coordinator','author','admin'); my @actions = &Apache::loncommon::get_env_multiple('form.actions'); &Apache::lonhtmlcommon::add_breadcrumb ({href=>"javascript:changePage(document.$phase,'pickactions')", - text=>"Pick functionality"}); + text=>"Settings to display/modify"}); my $confname = $dom.'-domainconfig'; if ($phase eq 'process') { - &Apache::lonhtmlcommon::add_breadcrumb - ({href=>"javascript:changePage(document.$phase,'display')", - text=>"Domain Configuration"}, - {href=>"javascript:changePage(document.$phase,'$phase')", - text=>"Updated"}); - &print_header($r,$phase); - foreach my $item (@prefs_order) { - if (grep(/^\Q$item\E$/,@actions)) { - $r->print('<h3>'.&mt($prefs{$item}{'text'}).'</h3>'. - &process_changes($r,$dom,$confname,$item, - \@roles,%domconfig)); - } - } - $r->print('<p>'); - &print_footer($r,$phase,'display','Back to configuration display', - \@actions); - $r->print('</p>'); + &Apache::lonconfigsettings::make_changes($r,$dom,$phase,$context,\@prefs_order,\%prefs,\%domconfig,$confname,\@roles); } elsif ($phase eq 'display') { - &Apache::lonhtmlcommon::add_breadcrumb - ({href=>"javascript:changePage(document.$phase,'display')", - text=>"Domain Configuration"}); - &print_header($r,$phase); - if (@actions > 0) { - my $rowsum = 0; - my (%output,%rowtotal,@items); - my $halfway = @actions/2; - foreach my $item (@prefs_order) { - if (grep(/^\Q$item\E$/,@actions)) { - push(@items,$item); - ($output{$item},$rowtotal{$item}) = - &print_config_box($r,$dom,$confname,$phase, - $item,$prefs{$item}, - $domconfig{$item}); - $rowsum += $rowtotal{$item}; - } - } - my $colend; - my $halfway = $rowsum/2; - my $aggregate = 0; - my $sumleft = 0; - my $sumright = 0; - my $crossover; - for (my $i=0; $i<@items; $i++) { - $aggregate += $rowtotal{$items[$i]}; - if ($aggregate > $halfway) { - $crossover = $i; - last; - } - } - for (my $i=0; $i<$crossover; $i++) { - $sumleft += $rowtotal{$items[$i]}; - } - for (my $i=$crossover+1; $i<@items; $i++) { - $sumright += $rowtotal{$items[$i]}; - } - if ((@items > 1) && ($env{'form.numcols'} == 2)) { - my $sumdiff = $sumright - $sumleft; - if ($sumdiff > 0) { - $colend = $crossover + 1; - } else { - $colend = $crossover; - } - } else { - $colend = @items; - } - $r->print('<p><table class="LC_double_column"><tr><td class="LC_left_col">'); - for (my $i=0; $i<$colend; $i++) { - $r->print($output{$items[$i]}); - } - $r->print('</td><td></td><td class="LC_right_col">'); - if ($colend < @items) { - for (my $i=$colend; $i<@items; $i++) { - $r->print($output{$items[$i]}); - } - } - $r->print('</td></tr></table></p>'); - $r->print(&print_footer($r,$phase,'process','Save',\@actions)); - } else { - $r->print('<input type="hidden" name="phase" value="" />'. - '<input type="hidden" name="numcols" value="'. - $env{'form.numcols'}.'" />'."\n". - '<span clas="LC_error">'.&mt('No settings chosen'). - '</span>'); - } - $r->print('</form>'); - $r->print(&Apache::loncommon::end_page()); + &Apache::lonconfigsettings::display_settings($r,$dom,$phase,$context,\@prefs_order,\%prefs,\%domconfig,$confname); } else { - if ($phase eq '') { - $phase = 'pickactions'; - } - my %helphash; - &print_header($r,$phase); if (keys(%domconfig) == 0) { my $primarylibserv = &Apache::lonnet::domain($dom,'primary'); my @ids=&Apache::lonnet::current_machine_ids(); @@ -300,6 +397,7 @@ sub handler { } } if ($custom_img_count > 0) { + &Apache::lonconfigsettings::print_header($r,$phase,$context); my $switch_server = &check_switchserver($dom,$confname); $r->print( &mt('Domain configuration settings have yet to be saved for this domain via the web-based domain preferences interface.').'<br />'. @@ -309,53 +407,22 @@ sub handler { if ($switch_server) { $r->print($switch_server.' '.&mt('to primary library server for domain: [_1]',$dom)); } + $r->print(&Apache::loncommon::end_page()); return OK; } } } - $r->print('<h3>'.&mt('Functionality to display/modify').'</h3>'); - $r->print('<script type="text/javascript">'."\n". - &Apache::loncommon::check_uncheck_jscript()."\n". - '</script>'."\n".'<p><input type="button" value="'.&mt('check all').'" '. - 'onclick="javascript:checkAll(document.pickactions.actions)"'. - ' /> '. - '<input type="button" value="'.&mt('uncheck all').'" '. - 'onclick="javascript:uncheckAll(document.pickactions.actions)"'. - ' /></p><div class="LC_left_float">'); - my ($numitems,$midpoint,$seconddiv,$count); - $numitems = @prefs_order; - $midpoint = int($numitems/2); - if ($numitems%2) { - $midpoint ++; - } - $count = 0; - foreach my $item (@prefs_order) { - $r->print('<h4>'. - &Apache::loncommon::help_open_topic($prefs{$item}->{'help'}). - '<label><input type="checkbox" name="actions" value="'.$item. - '" /> '.&mt($prefs{$item}->{'text'}).'</label></h4>'); - $count ++; - if ((!$seconddiv) && ($count >= $midpoint)) { - $r->print('</div>'."\n".'<div class="LC_left_float">'."\n"); - $seconddiv = 1; - } - } - $r->print('</div><div class="LC_clear_float_footer"></div><h3>'. - &mt('Display options').'</h3>'."\n". - '<p><span class="LC_nobreak">'.&mt('Display using: ')."\n". - '<label><input type="radio" name="numcols" value="1" />'. - &mt('one column').'</label> <label>'. - '<input type="radio" name="numcols" value="2" />'. - &mt('two columns').'</label></span></p>'); - $r->print(&print_footer($r,$phase,'display','Go')); - $r->print('</form>'); - $r->print(&Apache::loncommon::end_page()); + &Apache::lonconfigsettings::display_choices($r,$phase,$context,\@prefs_order,\%prefs); } return OK; } sub process_changes { - my ($r,$dom,$confname,$action,$roles,%domconfig) = @_; + my ($r,$dom,$confname,$action,$roles,$values) = @_; + my %domconfig; + if (ref($values) eq 'HASH') { + %domconfig = %{$values}; + } my $output; if ($action eq 'login') { $output = &modify_login($r,$dom,$confname,%domconfig); @@ -363,11 +430,13 @@ sub process_changes { $output = &modify_rolecolors($r,$dom,$confname,$roles, %domconfig); } elsif ($action eq 'quotas') { - $output = &modify_quotas($dom,%domconfig); + $output = &modify_quotas($dom,$action,%domconfig); } elsif ($action eq 'autoenroll') { $output = &modify_autoenroll($dom,%domconfig); } elsif ($action eq 'autoupdate') { $output = &modify_autoupdate($dom,%domconfig); + } elsif ($action eq 'autocreate') { + $output = &modify_autocreate($dom,%domconfig); } elsif ($action eq 'directorysrch') { $output = &modify_directorysrch($dom,%domconfig); } elsif ($action eq 'usercreation') { @@ -384,6 +453,14 @@ sub process_changes { $output = &modify_coursecategories($dom,%domconfig); } elsif ($action eq 'serverstatuses') { $output = &modify_serverstatuses($dom,%domconfig); + } elsif ($action eq 'requestcourses') { + $output = &modify_quotas($dom,$action,%domconfig); + } elsif ($action eq 'helpsettings') { + $output = &modify_helpsettings($r,$dom,$confname,%domconfig); + } elsif ($action eq 'coursedefaults') { + $output = &modify_coursedefaults($dom,%domconfig); + } elsif ($action eq 'usersessions') { + $output = &modify_usersessions($dom,%domconfig); } return $output; } @@ -394,7 +471,7 @@ sub print_config_box { my $output; if ($action eq 'coursecategories') { $output = &coursecategories_javascript($settings); - } + } $output .= '<table class="LC_nested_outer"> <tr> @@ -403,11 +480,13 @@ sub print_config_box { &Apache::loncommon::help_open_topic($item->{'help'}).'</span></th>'."\n". '</tr>'; $rowtotal ++; - if (($action eq 'autoupdate') || ($action eq 'rolecolors') || - ($action eq 'usercreation') || ($action eq 'usermodification') || - ($action eq 'coursecategories')) { + my $numheaders = 1; + if (ref($item->{'header'}) eq 'ARRAY') { + $numheaders = scalar(@{$item->{'header'}}); + } + if ($numheaders > 1) { my $colspan = ''; - if (($action eq 'rolecolors') || ($action eq 'coursecategories')) { + if (($action eq 'rolecolors') || ($action eq 'coursecategories') || ($action eq 'helpsettings')) { $colspan = ' colspan="2"'; } $output .= ' @@ -427,7 +506,16 @@ sub print_config_box { $output .= &print_usermodification('top',$dom,$settings,\$rowtotal); } elsif ($action eq 'coursecategories') { $output .= &print_coursecategories('top',$dom,$item,$settings,\$rowtotal); - } else { + } elsif ($action eq 'login') { + $output .= &print_login('top',$dom,$confname,$phase,$settings,\$rowtotal); + $colspan = ' colspan="2"'; + } elsif ($action eq 'requestcourses') { + $output .= &print_quotas($dom,$settings,\$rowtotal,$action); + } elsif ($action eq 'helpsettings') { + $output .= &print_helpsettings('top',$dom,$confname,$settings,\$rowtotal); + } elsif ($action eq 'usersessions') { + $output .= &print_usersessions('top',$dom,$settings,\$rowtotal); + } elsif ($action eq 'rolecolors') { $output .= &print_rolecolors($phase,'student',$dom,$confname,$settings,\$rowtotal); } $output .= ' @@ -444,7 +532,18 @@ sub print_config_box { </tr>'; $rowtotal ++; if ($action eq 'autoupdate') { - $output .= &print_autoupdate('bottom',$dom,$settings,\$rowtotal); + $output .= &print_autoupdate('middle',$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>'. + &print_autoupdate('bottom',$dom,$settings,\$rowtotal); + $rowtotal ++; } elsif ($action eq 'usercreation') { $output .= &print_usercreation('middle',$dom,$settings,\$rowtotal).' </table> @@ -469,12 +568,19 @@ sub print_config_box { <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>'. - &print_usermodification('bottom',$dom,$settings,\$rowtotal); $rowtotal ++; } elsif ($action eq 'coursecategories') { $output .= &print_coursecategories('bottom',$dom,$item,$settings,\$rowtotal); - } else { + } elsif ($action eq 'login') { + $output .= &print_login('bottom',$dom,$confname,$phase,$settings,\$rowtotal); + } elsif ($action eq 'requestcourses') { + $output .= &print_courserequestmail($dom,$settings,\$rowtotal); + } elsif ($action eq 'helpsettings') { + $output .= &print_helpsettings('bottom',$dom,$confname,$settings,\$rowtotal); + } elsif ($action eq 'usersessions') { + $output .= &print_usersessions('bottom',$dom,$settings,\$rowtotal); + } elsif ($action eq 'rolecolors') { $output .= &print_rolecolors($phase,'coordinator',$dom,$confname,$settings,\$rowtotal).' </table> </td> @@ -542,11 +648,14 @@ sub print_config_box { $output .= '</tr>'; $rowtotal ++; if ($action eq 'login') { - $output .= &print_login($dom,$confname,$phase,$settings,\$rowtotal); + $output .= &print_login('bottom',$dom,$confname,$phase,$settings, + \$rowtotal); } elsif ($action eq 'quotas') { - $output .= &print_quotas($dom,$settings,\$rowtotal); + $output .= &print_quotas($dom,$settings,\$rowtotal,$action); } elsif ($action eq 'autoenroll') { $output .= &print_autoenroll($dom,$settings,\$rowtotal); + } elsif ($action eq 'autocreate') { + $output .= &print_autocreate($dom,$settings,\$rowtotal); } elsif ($action eq 'directorysrch') { $output .= &print_directorysrch($dom,$settings,\$rowtotal); } elsif ($action eq 'contacts') { @@ -557,6 +666,10 @@ sub print_config_box { $output .= &print_scantronformat($r,$dom,$confname,$settings,\$rowtotal); } elsif ($action eq 'serverstatuses') { $output .= &print_serverstatuses($dom,$settings,\$rowtotal); + } elsif ($action eq 'helpsettings') { + $output .= &print_helpsettings('top',$dom,$confname,$settings,\$rowtotal); + } elsif ($action eq 'coursedefaults') { + $output .= &print_coursedefaults($dom,$settings,\$rowtotal); } } $output .= ' @@ -567,110 +680,80 @@ sub print_config_box { return ($output,$rowtotal); } -sub print_header { - my ($r,$phase) = @_; - my $alert = &mt('You must select at least one functionality type to display.'); - my $js = ' -<script type="text/javascript"> -function changePage(formname,newphase) { - formname.phase.value = newphase; - numchecked = 0; - if (formname == document.pickactions) { - if (formname.actions.length > 0) { - for (var i = 0; i<formname.actions.length; i++) { - if (formname.actions[i].checked) { - numchecked ++; - } - } - } else { - if (formname.actions.checked) { - numchecked ++; - } - } - if (numchecked > 0) { - formname.submit(); - } else { - alert("'.$alert.'"); - return; - } - } - formname.submit(); -}'."\n"; - if ($phase eq 'pickactions') { - $js .= - &Apache::lonhtmlcommon::set_form_elements({actions => 'checkbox',numcols => 'radio',})."\n". - &javascript_set_colnums(); - } elsif ($phase eq 'display') { - $js .= &color_pick_js()."\n"; - } - $js .= &Apache::loncommon::viewport_size_js().' -</script> -'; - my $additem; - if ($phase eq 'pickactions') { - my %loaditems = ( - 'onload' => "javascript:getViewportDims(document.$phase.width,document.$phase.height);setDisplayColumns();setFormElements(document.pickactions);", - ); - $additem = {'add_entries' => \%loaditems,}; - } else { - my %loaditems = ( - 'onload' => "javascript:getViewportDims(document.$phase.width,document.$phase.height);", - ); - $additem = {'add_entries' => \%loaditems,}; - } - $r->print(&Apache::loncommon::start_page('View/Modify Domain Settings', - $js,$additem)); - $r->print(&Apache::lonhtmlcommon::breadcrumbs('Domain Settings')); - $r->print(' -<form name="parmform" action=""> -<input type="hidden" name="pres_marker" /> -<input type="hidden" name="pres_type" /> -<input type="hidden" name="pres_value" /> -</form> -'); - $r->print('<form method="post" name="'.$phase.'" action="/adm/domainprefs"'. - ' enctype="multipart/form-data">'); - return; -} +sub print_login { + my ($position,$dom,$confname,$phase,$settings,$rowtotal) = @_; + my ($css_class,$datatable); + my %choices = &login_choices(); -sub print_footer { - my ($r,$phase,$newphase,$button_text,$actions) = @_; - $button_text = &mt($button_text); - $r->print('<input type="hidden" name="phase" value="" />'. - '<input type="hidden" name="width" value="'. - $env{'form.width'}.'" />'. - '<input type="hidden" name="height" value="'. - $env{'form.height'}.'" />'); - if (($phase eq 'display') || ($phase eq 'process')) { - if (ref($actions) eq 'ARRAY') { - foreach my $item (@{$actions}) { - $r->print('<input type="hidden" name="actions" value="'.$item.'" />')."\n"; + if ($position eq 'top') { + my %servers = &dom_servers($dom); + my $choice = $choices{'disallowlogin'}; + $css_class = ' class="LC_odd_row"'; + $datatable .= '<tr'.$css_class.'><td>'.$choice.'</td>'. + '<td align="right"><table><tr><th>'.$choices{'hostid'}.'</th>'. + '<th>'.$choices{'server'}.'</th>'. + '<th>'.$choices{'serverpath'}.'</th>'. + '<th>'.$choices{'custompath'}.'</th>'. + '<th><span class="LC_nobreak">'.$choices{'exempt'}.'</span></th></tr>'."\n"; + my %disallowed; + if (ref($settings) eq 'HASH') { + if (ref($settings->{'loginvia'}) eq 'HASH') { + %disallowed = %{$settings->{'loginvia'}}; } } - $r->print('<input type="hidden" name="numcols" value="'.$env{'form.numcols'}.'" />'); - } - my $dest='"javascript:changePage(document.'.$phase.','."'$newphase'".')"'; - if ($phase eq 'process') { - $r->print('<p><a href='.$dest.'>'.$button_text.'</a></p>'); - } else { - my $onclick; - if ($phase eq 'display') { - $onclick = '"javascript:changePage(document.'.$phase.','."'$newphase'".')"'; - } else { - $onclick = '"javascript:changePage(document.'.$phase.','."'$newphase'".')"'; - } - $r->print('<p><input type="button" name="store" value="'. - $button_text.'" onclick='.$onclick.' /></p>'); - } - if ($phase eq 'process') { - $r->print('</form>'.&Apache::loncommon::end_page()); + foreach my $lonhost (sort(keys(%servers))) { + my $direct = 'selected="selected"'; + if (ref($disallowed{$lonhost}) eq 'HASH') { + if ($disallowed{$lonhost}{'server'} ne '') { + $direct = ''; + } + } + $datatable .= '<tr><td>'.$servers{$lonhost}.'</td>'. + '<td><select name="'.$lonhost.'_server">'. + '<option value=""'.$direct.'>'.$choices{'directlogin'}. + '</option>'; + foreach my $hostid (keys(%servers)) { + next if ($servers{$hostid} eq $servers{$lonhost}); + my $selected = ''; + if (ref($disallowed{$lonhost}) eq 'HASH') { + if ($hostid eq $disallowed{$lonhost}{'server'}) { + $selected = 'selected="selected"'; + } + } + $datatable .= '<option value="'.$hostid.'"'.$selected.'>'. + $servers{$hostid}.'</option>'; + } + $datatable .= '</select></td>'. + '<td><select name="'.$lonhost.'_serverpath">'; + foreach my $path ('','/','/adm/login','/adm/roles','custom') { + my $pathname = $path; + if ($path eq 'custom') { + $pathname = &mt('Custom Path').' ->'; + } + my $selected = ''; + if (ref($disallowed{$lonhost}) eq 'HASH') { + if ($path eq $disallowed{$lonhost}{'serverpath'}) { + $selected = 'selected="selected"'; + } + } elsif ($path eq '') { + $selected = 'selected="selected"'; + } + $datatable .= '<option value="'.$path.'"'.$selected.'>'.$pathname.'</option>'; + } + $datatable .= '</select></td>'; + my ($custom,$exempt); + if (ref($disallowed{$lonhost}) eq 'HASH') { + $custom = $disallowed{$lonhost}{'custompath'}; + $exempt = $disallowed{$lonhost}{'exempt'}; + } + $datatable .= '<td><input type="text" name="'.$lonhost.'_custompath" size="6" value="'.$custom.'" /></td>'. + '<td><input type="text" name="'.$lonhost.'_exempt" size="8" value="'.$exempt.'" /></td>'. + '</tr>'; + } + $datatable .= '</table></td></tr>'; + return $datatable; } - return; -} -sub print_login { - my ($dom,$confname,$phase,$settings,$rowtotal) = @_; - my %choices = &login_choices(); my %defaultchecked = ( 'coursecatalog' => 'on', 'adminmail' => 'off', @@ -687,7 +770,6 @@ sub print_login { $checkedon{$item} = ' '; } } - my $loginheader = 'image'; my @images = ('img','logo','domlogo','login'); my @logintext = ('textcol','bgcol'); my @bgs = ('pgbg','mainbg','sidebg'); @@ -736,9 +818,6 @@ sub print_login { $is_custom{$item} = 1; } } - if ($settings->{'loginheader'} ne '') { - $loginheader = $settings->{'loginheader'}; - } if ($settings->{'font'} ne '') { $designs{'font'} = $settings->{'font'}; $is_custom{'font'} = 1; @@ -797,7 +876,7 @@ sub print_login { '</tr>'; $itemcount ++; } - $datatable .= &display_color_options($dom,$confname,$phase,'login',$itemcount,\%choices,\%is_custom,\%defaults,\%designs,\@images,\@bgs,\@links,\%alt_text,$rowtotal,\@logintext,$loginheader); + $datatable .= &display_color_options($dom,$confname,$phase,'login',$itemcount,\%choices,\%is_custom,\%defaults,\%designs,\@images,\@bgs,\@links,\%alt_text,$rowtotal,\@logintext); $datatable .= '</tr></table></td></tr>'; return $datatable; } @@ -805,24 +884,31 @@ sub print_login { sub login_choices { my %choices = &Apache::lonlocal::texthash ( - coursecatalog => 'Display Course Catalog link?', - adminmail => "Display Administrator's E-mail Address?", - newuser => "Link to create a user account", - img => "Header", - logo => "Main Logo", - domlogo => "Domain Logo", - login => "Log-in Header", - textcol => "Text color", - bgcol => "Box color", - bgs => "Background colors", - links => "Link colors", - font => "Font color", - pgbg => "Header", - mainbg => "Page", - sidebg => "Container", - link => "Link", - alink => "Active link", - vlink => "Visited link", + coursecatalog => 'Display Course/Community Catalog link?', + adminmail => "Display Administrator's E-mail Address?", + disallowlogin => "Login page requests redirected", + hostid => "Server", + server => "Redirect to:", + serverpath => "Path", + custompath => "Custom", + exempt => "Exempt IP(s)", + directlogin => "No redirect", + newuser => "Link to create a user account", + img => "Header", + logo => "Main Logo", + domlogo => "Domain Logo", + login => "Log-in Header", + textcol => "Text color", + bgcol => "Box color", + bgs => "Background colors", + links => "Link colors", + font => "Font color", + pgbg => "Header", + mainbg => "Page", + sidebg => "Login box", + link => "Link", + alink => "Active link", + vlink => "Visited link", ); return %choices; } @@ -840,6 +926,7 @@ sub print_rolecolors { my %defaults = ( img => $defaultdesign{$role.'.img'}, font => $defaultdesign{$role.'.font'}, + fontmenu => $defaultdesign{$role.'.fontmenu'}, ); foreach my $item (@bgs) { $defaults{'bgs'}{$item} = $defaultdesign{$role.'.'.$item}; @@ -857,6 +944,10 @@ sub print_rolecolors { $designs{'font'} = $settings->{$role}->{'font'}; $is_custom{'font'} = 1; } + if ($settings->{$role}->{'fontmenu'} ne '') { + $designs{'fontmenu'} = $settings->{$role}->{'fontmenu'}; + $is_custom{'fontmenu'} = 1; + } foreach my $item (@bgs) { if ($settings->{$role}->{$item} ne '') { $designs{'bgs'}{$item} = $settings->{$role}->{$item}; @@ -875,6 +966,10 @@ sub print_rolecolors { $designs{img} = $designhash{$dom.'.'.$role.'.img'}; $is_custom{'img'} = 1; } + if ($designhash{$dom.'.'.$role.'.fontmenu'} ne '') { + $designs{fontmenu} = $designhash{$dom.'.'.$role.'.fontmenu'}; + $is_custom{'fontmenu'} = 1; + } if ($designhash{$dom.'.'.$role.'.font'} ne '') { $designs{font} = $designhash{$dom.'.'.$role.'.font'}; $is_custom{'font'} = 1; @@ -901,7 +996,7 @@ sub print_rolecolors { sub display_color_options { my ($dom,$confname,$phase,$role,$itemcount,$choices,$is_custom,$defaults,$designs, - $images,$bgs,$links,$alt_text,$rowtotal,$logintext,$loginheader) = @_; + $images,$bgs,$links,$alt_text,$rowtotal,$logintext) = @_; my $css_class = $itemcount%2?' class="LC_odd_row"':''; my $datatable = '<tr'.$css_class.'>'. '<td>'.$choices->{'font'}.'</td>'; @@ -917,6 +1012,22 @@ sub display_color_options { ' <span id="css_'.$role.'_font" style="background-color: '. $designs->{'font'}.';"> </span>'. '</span></td></tr>'; + unless ($role eq 'login') { + $datatable .= '<tr'.$css_class.'>'. + '<td>'.$choices->{'fontmenu'}.'</td>'; + if (!$is_custom->{'fontmenu'}) { + $datatable .= '<td>'.&mt('Default in use:').' <span id="css_default_'.$role.'_font" style="color: '.$defaults->{'fontmenu'}.';">'.$defaults->{'fontmenu'}.'</span></td>'; + } else { + $datatable .= '<td> </td>'; + } + $fontlink = &color_pick($phase,$role,'fontmenu',$choices->{'fontmenu'},$designs->{'fontmenu'}); + $datatable .= '<td><span class="LC_nobreak">'. + '<input type="text" size="10" name="'.$role.'_fontmenu"'. + ' value="'.$designs->{'fontmenu'}.'" /> '.$fontlink. + ' <span id="css_'.$role.'_fontmenu" style="background-color: '. + $designs->{'fontmenu'}.';"> </span>'. + '</span></td></tr>'; + } my $switchserver = &check_switchserver($dom,$confname); foreach my $img (@{$images}) { $itemcount ++; @@ -927,8 +1038,7 @@ sub display_color_options { if ($role eq 'login') { if ($img eq 'login') { $login_hdr_pick = - &login_header_options($img,$role,$defaults,$is_custom,$choices, - $loginheader); + &login_header_options($img,$role,$defaults,$is_custom,$choices); $logincolors = &login_text_colors($img,$role,$logintext,$phase,$choices, $designs); @@ -1005,8 +1115,8 @@ sub display_color_options { } $datatable .= '<td>'; if ($img eq 'login') { - $datatable .= $login_hdr_pick; - } + $datatable .= $login_hdr_pick; + } $datatable .= &image_changes($is_custom->{$img},$alt_text->{$img},$img_import, $showfile,$fullsize,$role,$img,$imgfile,$logincolors); } else { @@ -1020,7 +1130,9 @@ sub display_color_options { if ($switchserver) { $datatable .= &mt('Upload to library server: [_1]',$switchserver); } else { - $datatable .=' <input type="file" name="'.$role.'_'.$img.'" />'; + if ($img ne 'login') { # suppress file selection for Log-in header + $datatable .=' <input type="file" name="'.$role.'_'.$img.'" />'; + } } $datatable .= '</td></tr>'; } @@ -1109,20 +1221,10 @@ sub logo_display_options { } sub login_header_options { - my ($img,$role,$defaults,$is_custom,$choices,$loginheader) = @_; - my $image_checked = ' checked="checked" '; - my $text_checked = ' '; - if ($loginheader eq 'text') { - $image_checked = ' '; - $text_checked = ' checked="checked" '; - } - my $output = '<span class="LC_nobreak"><label><input type="radio" name="'. - 'loginheader" value="image" '.$image_checked.'/>'. - &mt('use image').'</label> '. - '<label><input type="radio" name="loginheader" value="text"'. - $text_checked.'/>'.&mt('use text').'</label><br />'."\n"; + my ($img,$role,$defaults,$is_custom,$choices) = @_; + my $output = ''; if ((!$is_custom->{'textcol'}) || (!$is_custom->{'bgcol'})) { - $output .= &mt('Text default(s)').':<br />'; + $output .= &mt('Text default(s):').'<br />'; if (!$is_custom->{'textcol'}) { $output .= $choices->{'textcol'}.': '.$defaults->{'logintext'}{'textcol'}. ' '; @@ -1158,25 +1260,31 @@ sub login_text_colors { sub image_changes { my ($is_custom,$alt_text,$img_import,$showfile,$fullsize,$role,$img,$imgfile,$logincolors) = @_; my $output; - if (!$is_custom) { + if ($img eq 'login') { + # suppress image for Log-in header + } elsif (!$is_custom) { if ($img ne 'domlogo') { $output .= &mt('Default image:').'<br />'; } else { $output .= &mt('Default in use:').'<br />'; } } - if ($img_import) { - $output .= '<input type="hidden" name="'.$role.'_import_'.$img.'" value="'.$imgfile.'" />'; - } - $output .= '<a href="'.$fullsize.'" target="_blank"><img src="'. - $showfile.'" alt="'.$alt_text.'" border="0" /></a></td>'; - if ($is_custom) { - $output .= '<td>'.$logincolors.'<span class="LC_nobreak"><label>'. - '<input type="checkbox" name="'. - $role.'_del_'.$img.'" value="1" />'.&mt('Delete?'). - '</label> '.&mt('Replace:').'</span><br />'; + if ($img eq 'login') { # suppress image for Log-in header + $output .= '<td>'.$logincolors; } else { - $output .= '<td valign="bottom">'.$logincolors.&mt('Upload:').'<br />'; + if ($img_import) { + $output .= '<input type="hidden" name="'.$role.'_import_'.$img.'" value="'.$imgfile.'" />'; + } + $output .= '<a href="'.$fullsize.'" target="_blank"><img src="'. + $showfile.'" alt="'.$alt_text.'" border="0" /></a></td>'; + if ($is_custom) { + $output .= '<td>'.$logincolors.'<span class="LC_nobreak"><label>'. + '<input type="checkbox" name="'. + $role.'_del_'.$img.'" value="1" />'.&mt('Delete?'). + '</label> '.&mt('Replace:').'</span><br />'; + } else { + $output .= '<td valign="bottom">'.$logincolors.&mt('Upload:').'<br />'; + } } return $output; } @@ -1189,67 +1297,38 @@ sub color_pick { return $link; } -sub color_pick_js { - my $pjump_def = &Apache::lonhtmlcommon::pjump_javascript_definition(); - my $output = <<"ENDCOL"; - function pclose() { - parmwin=window.open("/adm/rat/empty.html","LONCAPAparms","height=350,width=350,scrollbars=no,menubar=no"); - parmwin.close(); - } - - $pjump_def - - function psub() { - pclose(); - if (document.parmform.pres_marker.value!='') { - if (document.parmform.pres_type.value!='') { - eval('document.display.'+ - document.parmform.pres_marker.value+ - '.value=document.parmform.pres_value.value;'); - } - } else { - document.parmform.pres_value.value=''; - document.parmform.pres_marker.value=''; - } - } - - function get_id (span_id) { - if (document.getElementById) { - return document.getElementById(span_id); - } - if (document.all) { - return document.all[span_id]; - } - return false; - } - - function colchg_span (span_id_str,new_color_item) { - var span_ref = get_id(span_id_str); - if (span_ref.style) { span_ref = span_ref.style; } - span_ref.background = new_color_item.value; - span_ref.backgroundColor = new_color_item.value; - span_ref.bgColor = new_color_item.value; - } - -ENDCOL - return $output; -} - sub print_quotas { - my ($dom,$settings,$rowtotal) = @_; - my $datatable; + my ($dom,$settings,$rowtotal,$action) = @_; + my $context; + if ($action eq 'quotas') { + $context = 'tools'; + } else { + $context = $action; + } + my ($datatable,$defaultquota,@usertools,@options,%validations); my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom); my $typecount = 0; - my $css_class; - my @usertools = ('aboutme','blog','portfolio'); - my %titles = &tool_titles(); + my ($css_class,%titles); + if ($context eq 'requestcourses') { + @usertools = ('official','unofficial','community'); + @options =('norequest','approval','validate','autolimit'); + %validations = &Apache::lonnet::auto_courserequest_checks($dom); + %titles = &courserequest_titles(); + } else { + @usertools = ('aboutme','blog','portfolio'); + %titles = &tool_titles(); + } if (ref($types) eq 'ARRAY') { foreach my $type (@{$types}) { my $currdefquota; - if (ref($settings->{defaultquota}) eq 'HASH') { - $currdefquota = $settings->{defaultquota}->{$type}; - } else { - $currdefquota = $settings->{$type}; + unless ($context eq 'requestcourses') { + if (ref($settings) eq 'HASH') { + if (ref($settings->{defaultquota}) eq 'HASH') { + $currdefquota = $settings->{defaultquota}->{$type}; + } else { + $currdefquota = $settings->{$type}; + } + } } if (defined($usertypes->{$type})) { $typecount ++; @@ -1257,31 +1336,105 @@ sub print_quotas { $datatable .= '<tr'.$css_class.'>'. '<td>'.$usertypes->{$type}.'</td>'. '<td class="LC_left_item">'; + if ($context eq 'requestcourses') { + $datatable .= '<table><tr>'; + } + my %cell; foreach my $item (@usertools) { - my $checked = 'checked="checked" '; - if (ref($settings->{$item}) eq 'HASH') { - if ($settings->{$item}->{$type} == 0) { - $checked = ''; + if ($context eq 'requestcourses') { + my ($curroption,$currlimit); + if (ref($settings) eq 'HASH') { + if (ref($settings->{$item}) eq 'HASH') { + $curroption = $settings->{$item}->{$type}; + if ($curroption =~ /^autolimit=(\d*)$/) { + $currlimit = $1; + } + } } - } - $datatable .= '<span class="LC_nobreak"><label>'. - '<input type="checkbox" name="tools_'.$item. - '" value="'.$type.'" '.$checked.'/>'.$titles{$item}. - '</label></span> '; - } - $datatable .= '</td><td class="LC_right_item"><span class="LC_nobreak">'. + if (!$curroption) { + $curroption = 'norequest'; + } + $datatable .= '<th>'.$titles{$item}.'</th>'; + foreach my $option (@options) { + my $val = $option; + if ($option eq 'norequest') { + $val = 0; + } + if ($option eq 'validate') { + my $canvalidate = 0; + if (ref($validations{$item}) eq 'HASH') { + if ($validations{$item}{$type}) { + $canvalidate = 1; + } + } + next if (!$canvalidate); + } + my $checked = ''; + if ($option eq $curroption) { + $checked = ' checked="checked"'; + } elsif ($option eq 'autolimit') { + if ($curroption =~ /^autolimit/) { + $checked = ' checked="checked"'; + } + } + $cell{$item} .= '<span class="LC_nobreak"><label>'. + '<input type="radio" name="crsreq_'.$item. + '_'.$type.'" value="'.$val.'"'.$checked.' />'. + $titles{$option}.'</label>'; + if ($option eq 'autolimit') { + $cell{$item} .= ' <input type="text" name="crsreq_'. + $item.'_limit_'.$type.'" size="1" '. + 'value="'.$currlimit.'" />'; + } + $cell{$item} .= '</span> '; + if ($option eq 'autolimit') { + $cell{$item} .= $titles{'unlimited'}; + } + } + } else { + my $checked = 'checked="checked" '; + if (ref($settings) eq 'HASH') { + if (ref($settings->{$item}) eq 'HASH') { + if ($settings->{$item}->{$type} == 0) { + $checked = ''; + } elsif ($settings->{$item}->{$type} == 1) { + $checked = 'checked="checked" '; + } + } + } + $datatable .= '<span class="LC_nobreak"><label>'. + '<input type="checkbox" name="'.$context.'_'.$item. + '" value="'.$type.'" '.$checked.'/>'.$titles{$item}. + '</label></span> '; + } + } + if ($context eq 'requestcourses') { + $datatable .= '</tr><tr>'; + foreach my $item (@usertools) { + $datatable .= '<td style="vertical-align: top">'.$cell{$item}.'</td>'; + } + $datatable .= '</tr></table>'; + } + $datatable .= '</td>'; + unless ($context eq 'requestcourses') { + $datatable .= + '<td class="LC_right_item"><span class="LC_nobreak">'. '<input type="text" name="quota_'.$type. '" value="'.$currdefquota. - '" size="5" /> Mb</span></td></tr>'; + '" size="5" /> Mb</span></td>'; + } + $datatable .= '</tr>'; } } } - my $defaultquota = '20'; - if (ref($settings) eq 'HASH') { - if (ref($settings->{'defaultquota'}) eq 'HASH') { - $defaultquota = $settings->{'defaultquota'}->{'default'}; - } elsif (defined($settings->{'default'})) { - $defaultquota = $settings->{'default'}; + unless ($context eq 'requestcourses') { + $defaultquota = '20'; + if (ref($settings) eq 'HASH') { + if (ref($settings->{'defaultquota'}) eq 'HASH') { + $defaultquota = $settings->{'defaultquota'}->{'default'}; + } elsif (defined($settings->{'default'})) { + $defaultquota = $settings->{'default'}; + } } } $typecount ++; @@ -1289,47 +1442,275 @@ sub print_quotas { $datatable .= '<tr'.$css_class.'>'. '<td>'.$othertitle.'</td>'. '<td class="LC_left_item">'; + if ($context eq 'requestcourses') { + $datatable .= '<table><tr>'; + } + my %defcell; foreach my $item (@usertools) { - my $checked = 'checked="checked" '; - if (ref($settings->{$item}) eq 'HASH') { - if ($settings->{$item}->{'default'} == 0) { - $checked = ''; + if ($context eq 'requestcourses') { + my ($curroption,$currlimit); + if (ref($settings) eq 'HASH') { + if (ref($settings->{$item}) eq 'HASH') { + $curroption = $settings->{$item}->{'default'}; + if ($curroption =~ /^autolimit=(\d*)$/) { + $currlimit = $1; + } + } + } + if (!$curroption) { + $curroption = 'norequest'; } + $datatable .= '<th>'.$titles{$item}.'</th>'; + foreach my $option (@options) { + my $val = $option; + if ($option eq 'norequest') { + $val = 0; + } + if ($option eq 'validate') { + my $canvalidate = 0; + if (ref($validations{$item}) eq 'HASH') { + if ($validations{$item}{'default'}) { + $canvalidate = 1; + } + } + next if (!$canvalidate); + } + my $checked = ''; + if ($option eq $curroption) { + $checked = ' checked="checked"'; + } elsif ($option eq 'autolimit') { + if ($curroption =~ /^autolimit/) { + $checked = ' checked="checked"'; + } + } + $defcell{$item} .= '<span class="LC_nobreak"><label>'. + '<input type="radio" name="crsreq_'.$item. + '_default" value="'.$val.'"'.$checked.' />'. + $titles{$option}.'</label>'; + if ($option eq 'autolimit') { + $defcell{$item} .= ' <input type="text" name="crsreq_'. + $item.'_limit_default" size="1" '. + 'value="'.$currlimit.'" />'; + } + $defcell{$item} .= '</span> '; + if ($option eq 'autolimit') { + $defcell{$item} .= $titles{'unlimited'}; + } + } + } else { + my $checked = 'checked="checked" '; + if (ref($settings) eq 'HASH') { + if (ref($settings->{$item}) eq 'HASH') { + if ($settings->{$item}->{'default'} == 0) { + $checked = ''; + } elsif ($settings->{$item}->{'default'} == 1) { + $checked = 'checked="checked" '; + } + } + } + $datatable .= '<span class="LC_nobreak"><label>'. + '<input type="checkbox" name="'.$context.'_'.$item. + '" value="default" '.$checked.'/>'.$titles{$item}. + '</label></span> '; + } + } + if ($context eq 'requestcourses') { + $datatable .= '</tr><tr>'; + foreach my $item (@usertools) { + $datatable .= '<td style="vertical-align: top">'.$defcell{$item}.'</td>'; } - $datatable .= '<span class="LC_nobreak"><label>'. - '<input type="checkbox" name="tools_'.$item. - '" value="default" '.$checked.'/>'.$titles{$item}. - '</label></span> '; - } - $datatable .= '</td><td class="LC_right_item"><span class="LC_nobreak">'. - '<input type="text" name="defaultquota" value="'. - $defaultquota.'" size="5" /> Mb</span></td></tr>'; + $datatable .= '</tr></table>'; + } + $datatable .= '</td>'; + unless ($context eq 'requestcourses') { + $datatable .= '<td class="LC_right_item"><span class="LC_nobreak">'. + '<input type="text" name="defaultquota" value="'. + $defaultquota.'" size="5" /> Mb</span></td>'; + } + $datatable .= '</tr>'; $typecount ++; $css_class = $typecount%2?' class="LC_odd_row"':''; $datatable .= '<tr'.$css_class.'>'. - '<td><br/>'.&mt('LON-CAPA Advanced Users').'</td>'. - '<td class="LC_left_item" colspan="2"><br />'; + '<td>'.&mt('LON-CAPA Advanced Users').' '; + if ($context eq 'requestcourses') { + $datatable .= &mt('(overrides affiliation, if set)'). + '</td>'. + '<td class="LC_left_item">'. + '<table><tr>'; + } else { + $datatable .= &mt('(overrides affiliation, if checked)'). + '</td>'. + '<td class="LC_left_item" colspan="2">'. + '<br />'; + } + my %advcell; foreach my $item (@usertools) { - my $checked = 'checked="checked" '; - if (ref($settings->{$item}) eq 'HASH') { - if ($settings->{$item}->{'_LC_adv'} == 0) { - $checked = ''; + if ($context eq 'requestcourses') { + my ($curroption,$currlimit); + if (ref($settings) eq 'HASH') { + if (ref($settings->{$item}) eq 'HASH') { + $curroption = $settings->{$item}->{'_LC_adv'}; + if ($curroption =~ /^autolimit=(\d*)$/) { + $currlimit = $1; + } + } + } + $datatable .= '<th>'.$titles{$item}.'</th>'; + my $checked = ''; + if ($curroption eq '') { + $checked = ' checked="checked"'; + } + $advcell{$item} .= '<span class="LC_nobreak"><label>'. + '<input type="radio" name="crsreq_'.$item. + '__LC_adv" value=""'.$checked.' />'. + &mt('No override set').'</label></span> '; + foreach my $option (@options) { + my $val = $option; + if ($option eq 'norequest') { + $val = 0; + } + if ($option eq 'validate') { + my $canvalidate = 0; + if (ref($validations{$item}) eq 'HASH') { + if ($validations{$item}{'_LC_adv'}) { + $canvalidate = 1; + } + } + next if (!$canvalidate); + } + my $checked = ''; + if ($val eq $curroption) { + $checked = ' checked="checked"'; + } elsif ($option eq 'autolimit') { + if ($curroption =~ /^autolimit/) { + $checked = ' checked="checked"'; + } + } + $advcell{$item} .= '<span class="LC_nobreak"><label>'. + '<input type="radio" name="crsreq_'.$item. + '__LC_adv" value="'.$val.'"'.$checked.' />'. + $titles{$option}.'</label>'; + if ($option eq 'autolimit') { + $advcell{$item} .= ' <input type="text" name="crsreq_'. + $item.'_limit__LC_adv" size="1" '. + 'value="'.$currlimit.'" />'; + } + $advcell{$item} .= '</span> '; + if ($option eq 'autolimit') { + $advcell{$item} .= $titles{'unlimited'}; + } + } + } else { + my $checked = 'checked="checked" '; + if (ref($settings) eq 'HASH') { + if (ref($settings->{$item}) eq 'HASH') { + if ($settings->{$item}->{'_LC_adv'} == 0) { + $checked = ''; + } elsif ($settings->{$item}->{'_LC_adv'} == 1) { + $checked = 'checked="checked" '; + } + } } + $datatable .= '<span class="LC_nobreak"><label>'. + '<input type="checkbox" name="'.$context.'_'.$item. + '" value="_LC_adv" '.$checked.'/>'.$titles{$item}. + '</label></span> '; } - $datatable .= '<span class="LC_nobreak"><label>'. - '<input type="checkbox" name="tools_'.$item. - '" value="_LC_adv" '.$checked.'/>'.$titles{$item}. - '</label></span> '; } - $datatable .= '('.&mt('overrides affiliation').')</td></tr>'; + if ($context eq 'requestcourses') { + $datatable .= '</tr><tr>'; + foreach my $item (@usertools) { + $datatable .= '<td style="vertical-align: top">'.$advcell{$item}.'</td>'; + } + $datatable .= '</tr></table>'; + } + $datatable .= '</td></tr>'; $$rowtotal += $typecount; return $datatable; } +sub print_courserequestmail { + my ($dom,$settings,$rowtotal) = @_; + my ($now,$datatable,%dompersonnel,@domcoord,@currapproval,$rows); + $now = time; + $rows = 0; + %dompersonnel = &Apache::lonnet::get_domain_roles($dom,['dc'],$now,$now); + foreach my $server (keys(%dompersonnel)) { + foreach my $user (sort(keys(%{$dompersonnel{$server}}))) { + my ($trole,$uname,$udom,$runame,$rudom,$rsec) = split(/:/,$user); + if (!grep(/^$uname:$udom$/,@domcoord)) { + push(@domcoord,$uname.':'.$udom); + } + } + } + if (ref($settings) eq 'HASH') { + if (ref($settings->{'notify'}) eq 'HASH') { + if ($settings->{'notify'}{'approval'} ne '') { + @currapproval = split(',',$settings->{'notify'}{'approval'}); + } + } + } + if (@currapproval) { + foreach my $dc (@currapproval) { + unless (grep(/^\Q$dc\E$/,@domcoord)) { + push(@domcoord,$dc); + } + } + } + @domcoord = sort(@domcoord); + my $numinrow = 4; + my $numdc = @domcoord; + my $css_class = 'class="LC_odd_row"'; + $datatable = '<tr'.$css_class.'>'. + ' <td>'.&mt('Receive notification of course requests requiring approval.'). + ' </td>'. + ' <td class="LC_left_item">'; + if (@domcoord > 0) { + $datatable .= '<table>'; + for (my $i=0; $i<$numdc; $i++) { + my $rem = $i%($numinrow); + if ($rem == 0) { + if ($i > 0) { + $datatable .= '</tr>'; + } + $datatable .= '<tr>'; + $rows ++; + } + my $check = ' '; + if (grep(/^\Q$domcoord[$i]\E$/,@currapproval)) { + $check = ' checked="checked" '; + } + my ($uname,$udom) = split(':',$domcoord[$i]); + my $fullname = &Apache::loncommon::plainname($uname,$udom); + if ($i == $numdc-1) { + my $colsleft = $numinrow-$rem; + if ($colsleft > 1) { + $datatable .= '<td colspan="'.$colsleft.'" class="LC_left_item">'; + } else { + $datatable .= '<td class="LC_left_item">'; + } + } else { + $datatable .= '<td class="LC_left_item">'; + } + $datatable .= '<span class="LC_nobreak"><label>'. + '<input type="checkbox" name="reqapprovalnotify" '. + 'value="'.$domcoord[$i].'"'.$check.'/>'. + $fullname.'</label></span></td>'; + } + $datatable .= '</tr></table>'; + } else { + $datatable .= &mt('There are no active Domain Coordinators'); + $rows ++; + } + $datatable .='</td></tr>'; + $$rowtotal += $rows; + return $datatable; +} + sub print_autoenroll { my ($dom,$settings,$rowtotal) = @_; my $autorun = &Apache::lonnet::auto_run(undef,$dom), - my ($defdom,$runon,$runoff); + my ($defdom,$runon,$runoff,$coownerson,$coownersoff); if (ref($settings) eq 'HASH') { if (exists($settings->{'run'})) { if ($settings->{'run'} eq '0') { @@ -1348,6 +1729,18 @@ sub print_autoenroll { $runon = ' '; } } + if (exists($settings->{'co-owners'})) { + if ($settings->{'co-owners'} eq '0') { + $coownersoff = ' checked="checked" '; + $coownerson = ' '; + } else { + $coownerson = ' checked="checked" '; + $coownersoff = ' '; + } + } else { + $coownersoff = ' checked="checked" '; + $coownerson = ' '; + } if (exists($settings->{'sender_domain'})) { $defdom = $settings->{'sender_domain'}; } @@ -1378,8 +1771,16 @@ sub print_autoenroll { &mt('username').': '. '<input type="text" name="sender_uname" value="'. $notif_sender.'" size="10" /> '.&mt('domain'). - ': '.$domform.'</span></td></tr>'; - $$rowtotal += 2; + ': '.$domform.'</span></td></tr>'. + '<tr class="LC_odd_row">'. + '<td>'.&mt('Automatically assign co-ownership').'</td>'. + '<td class="LC_right_item"><span class="LC_nobreak"><label>'. + '<input type="radio" name="autoassign_coowners"'. + $coownerson.' value="1" />'.&mt('Yes').'</label> '. + '<label><input type="radio" name="autoassign_coowners"'. + $coownersoff.' value="0" />'.&mt('No').'</label></span></td>'. + '</tr>'; + $$rowtotal += 3; return $datatable; } @@ -1421,9 +1822,17 @@ sub print_autoupdate { $classlistsoff.'value="0" />'.&mt('No').'</label></span></td>'. '</tr>'; $$rowtotal += 2; + } elsif ($position eq 'middle') { + my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom); + my $numinrow = 3; + my $locknamesettings; + $datatable .= &insttypes_row($settings,$types,$usertypes, + $dom,$numinrow,$othertitle, + 'lockablenames'); + $$rowtotal ++; } else { my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom); - my @fields = ('lastname','firstname','middlename','gen', + my @fields = ('lastname','firstname','middlename','generation', 'permanentemail','id'); my %fieldtitles = &Apache::loncommon::personal_data_fieldtitles(); my $numrows = 0; @@ -1444,6 +1853,57 @@ sub print_autoupdate { return $datatable; } +sub print_autocreate { + my ($dom,$settings,$rowtotal) = @_; + my (%createon,%createoff); + my $curr_dc; + my @types = ('xml','req'); + if (ref($settings) eq 'HASH') { + foreach my $item (@types) { + $createoff{$item} = ' checked="checked" '; + $createon{$item} = ' '; + if (exists($settings->{$item})) { + if ($settings->{$item}) { + $createon{$item} = ' checked="checked" '; + $createoff{$item} = ' '; + } + } + } + $curr_dc = $settings->{'xmldc'}; + } else { + foreach my $item (@types) { + $createoff{$item} = ' checked="checked" '; + $createon{$item} = ' '; + } + } + $$rowtotal += 2; + my $datatable='<tr class="LC_odd_row">'. + '<td>'.&mt('Create pending official courses from XML files').'</td>'. + '<td class="LC_right_item"><span class="LC_nobreak"><label>'. + '<input type="radio" name="autocreate_xml"'. + $createon{'xml'}.' value="1" />'.&mt('Yes').'</label> '. + '<label><input type="radio" name="autocreate_xml"'. + $createoff{'xml'}.' value="0" />'.&mt('No').'</label></span>'; + my ($numdc,$dctable) = &active_dc_picker($dom,$curr_dc); + if ($numdc > 1) { + $datatable .= '</td><tr><td>'. + &mt('XML files processed as: (choose Dom. Coord.)'). + '</td><td class="LC_left_item">'.$dctable.'</td></tr>'. + '<tr class="LC_odd_row">'; + $$rowtotal ++ ; + } else { + $datatable .= '</td></tr><tr>'; + } + $datatable .= '<td>'.&mt('Create pending requests for official courses (if validated)').'</td>'. + '<td class="LC_right_item"><span class="LC_nobreak"><label>'. + '<input type="radio" name="autocreate_req"'. + $createon{'req'}.' value="1" />'.&mt('Yes').'</label> '. + '<label><input type="radio" name="autocreate_req"'. + $createoff{'req'}.' value="0" />'.&mt('No').'</label></span></td>'. + '</tr>'; + return $datatable; +} + sub print_directorysrch { my ($dom,$settings,$rowtotal) = @_; my $srchon = ' '; @@ -1504,8 +1964,8 @@ sub print_directorysrch { $$rowtotal += 2; if (ref($usertypes) eq 'HASH') { if (keys(%{$usertypes}) > 0) { - $datatable .= &users_cansearch_row($settings,$types,$usertypes,$dom, - $numinrow,$othertitle); + $datatable .= &insttypes_row($settings,$types,$usertypes,$dom, + $numinrow,$othertitle,'cansearch'); $cansrchrow = 1; } } @@ -1520,7 +1980,7 @@ sub print_directorysrch { foreach my $title (@{$titleorder}) { if (defined($searchtitles->{$title})) { my $check = ' '; - if (ref($settings) eq 'HASH') { + if (ref($settings) eq 'HASH') { if (ref($settings->{'searchby'}) eq 'ARRAY') { if (grep(/^\Q$title\E$/,@{$settings->{'searchby'}})) { $check = ' checked="checked" '; @@ -1561,11 +2021,13 @@ sub print_contacts { my ($dom,$settings,$rowtotal) = @_; my $datatable; my @contacts = ('adminemail','supportemail'); - my (%checked,%to,%otheremails); - my @mailings = ('errormail','packagesmail','helpdeskmail'); + my (%checked,%to,%otheremails,%bccemails); + my @mailings = ('errormail','packagesmail','lonstatusmail','helpdeskmail', + 'requestsmail'); foreach my $type (@mailings) { $otheremails{$type} = ''; } + $bccemails{'helpdeskmail'} = ''; if (ref($settings) eq 'HASH') { foreach my $item (@contacts) { if (exists($settings->{$item})) { @@ -1581,7 +2043,12 @@ sub print_contacts { } } $otheremails{$type} = $settings->{$type}{'others'}; + if ($type eq 'helpdeskmail') { + $bccemails{$type} = $settings->{$type}{'bcc'}; + } } + } elsif ($type eq 'lonstatusmail') { + $checked{'lonstatusmail'}{'adminemail'} = ' checked="checked" '; } } } else { @@ -1589,7 +2056,9 @@ sub print_contacts { $to{'adminemail'} = $Apache::lonnet::perlvar{'lonAdmEMail'}; $checked{'errormail'}{'adminemail'} = ' checked="checked" '; $checked{'packagesmail'}{'adminemail'} = ' checked="checked" '; - $checked{'helpdeskmail'}{'supportemail'} = ' checked="checked" '; + $checked{'helpdeskmail'}{'supportemail'} = ' checked="checked" '; + $checked{'lonstatusmail'}{'adminemail'} = ' checked="checked" '; + $checked{'requestsmail'}{'adminemail'} = ' checked="checked" '; } my ($titles,$short_titles) = &contact_titles(); my $rownum = 0; @@ -1620,20 +2089,286 @@ sub print_contacts { } $datatable .= '</span><br />'.&mt('Others').': '. '<input type="text" name="'.$type.'_others" '. - 'value="'.$otheremails{$type}.'" />'. - '</td></tr>'."\n"; + 'value="'.$otheremails{$type}.'" />'; + if ($type eq 'helpdeskmail') { + $datatable .= '<br />'.&mt('Bcc:').(' 'x6). + '<input type="text" name="'.$type.'_bcc" '. + 'value="'.$bccemails{$type}.'" />'; + } + $datatable .= '</td></tr>'."\n"; } $$rowtotal += $rownum; return $datatable; } +sub print_helpsettings { + + my ($position,$dom,$confname,$settings,$rowtotal) = @_; + my ($css_class,$datatable); + + my $switchserver = &check_switchserver($dom,$confname); + + my $itemcount = 1; + + if ($position eq 'top') { + + my (%checkedon,%checkedoff,%choices,%defaultchecked,@toggles); + + %choices = + &Apache::lonlocal::texthash ( + submitbugs => 'Display "Submit a bug" link?', + ); + + %defaultchecked = ('submitbugs' => 'on'); + + @toggles = ('submitbugs',); + + foreach my $item (@toggles) { + if ($defaultchecked{$item} eq 'on') { + $checkedon{$item} = ' checked="checked" '; + $checkedoff{$item} = ' '; + } elsif ($defaultchecked{$item} eq 'off') { + $checkedoff{$item} = ' checked="checked" '; + $checkedon{$item} = ' '; + } + } + + if (ref($settings) eq 'HASH') { + foreach my $item (@toggles) { + if ($settings->{$item} eq '1') { + $checkedon{$item} = ' checked="checked" '; + $checkedoff{$item} = ' '; + } elsif ($settings->{$item} eq '0') { + $checkedoff{$item} = ' checked="checked" '; + $checkedon{$item} = ' '; + } + } + } + + foreach my $item (@toggles) { + $css_class = $itemcount%2 ? ' class="LC_odd_row"' : ''; + $datatable .= + '<tr'.$css_class.'> + <td><span class="LC_nobreak">'.$choices{$item}.'</span></td> + <td><span class="LC_nobreak"> </span></td> + <td class="LC_right_item"><span class="LC_nobreak"> + <label><input type="radio" name="'.$item.'" '.$checkedon{$item}.' value="1" />'.&mt('Yes').'</label> + <label><input type="radio" name="'.$item.'" '.$checkedoff{$item}.' value="0" />'.&mt('No').'</label>'. + '</span></td>'. + '</tr>'; + $itemcount ++; + } + + } else { + + $css_class = $itemcount%2 ? ' class="LC_odd_row"' : ''; + + $datatable .= '<tr'.$css_class.'>'; + + if (ref($settings) eq 'HASH') { + if ($settings->{'loginhelpurl'} ne '') { + my($directory, $filename) = $settings->{'loginhelpurl'} =~ m/(.*\/)(.*)$/; + $datatable .= '<td width="33%"><span class="LC_left_item"><label><a href="'.$settings->{'loginhelpurl'}.'" target="_blank">'.&mt('Custom Login Page Help File In Use').'</a></label></span></td>'; + $datatable .= '<td width="33%"><span class="LC_right_item"><label><input type="checkbox" name="loginhelpurl_del" value="1" />'.&mt('Delete?').'</label></span></td>' + } else { + $datatable .= '<td width="33%"><span class="LC_left_item"><label>'.&mt('Default Login Page Help File In Use').'</label></span></td>'; + $datatable .= '<td width="33%"><span class="LC_right_item"> </span></td>'; + } + } else { + $datatable .= '<td><span class="LC_left_item"> </span></td>'; + $datatable .= '<td><span class="LC_right_item"> </span></td>'; + } + + $datatable .= '<td width="33%"><span class="LC_right_item">'; + if ($switchserver) { + $datatable .= &mt('Upload to library server: [_1]',$switchserver); + } else { + $datatable .= &mt('Upload Custom Login Page Help File:'); + $datatable .='<input type="file" name="loginhelpurl" />'; + } + $datatable .= '</span></td></tr>'; + + } + + return $datatable; + +} + + +sub radiobutton_prefs { + my ($settings,$toggles,$defaultchecked,$choices,$itemcount) = @_; + return unless ((ref($toggles) eq 'ARRAY') && (ref($defaultchecked) eq 'HASH') && + (ref($choices) eq 'HASH')); + + my (%checkedon,%checkedoff,$datatable,$css_class); + + foreach my $item (@{$toggles}) { + if ($defaultchecked->{$item} eq 'on') { + $checkedon{$item} = ' checked="checked" '; + $checkedoff{$item} = ' '; + } elsif ($defaultchecked->{$item} eq 'off') { + $checkedoff{$item} = ' checked="checked" '; + $checkedon{$item} = ' '; + } + } + if (ref($settings) eq 'HASH') { + foreach my $item (@{$toggles}) { + if ($settings->{$item} eq '1') { + $checkedon{$item} = ' checked="checked" '; + $checkedoff{$item} = ' '; + } elsif ($settings->{$item} eq '0') { + $checkedoff{$item} = ' checked="checked" '; + $checkedon{$item} = ' '; + } + } + } + foreach my $item (@{$toggles}) { + $css_class = $itemcount%2?' class="LC_odd_row"':''; + $datatable .= + '<tr'.$css_class.'><td><span class="LC_nobreak">'.$choices->{$item}. + '</span></td>'. + '<td class="LC_right_item"><span class="LC_nobreak">'. + '<label><input type="radio" name="'. + $item.'" '.$checkedon{$item}.' value="1" />'.&mt('Yes'). + '</label> <label><input type="radio" name="'.$item.'" '. + $checkedoff{$item}.' value="0" />'.&mt('No').'</label>'. + '</span></td>'. + '</tr>'; + $itemcount ++; + } + return ($datatable,$itemcount); +} + +sub print_coursedefaults { + my ($dom,$settings,$rowtotal) = @_; + my ($css_class,$datatable); + my $itemcount = 1; + my (%checkedon,%checkedoff,%choices,%defaultchecked,@toggles); + %choices = + &Apache::lonlocal::texthash ( + canuse_pdfforms => 'Course/Community users can create/upload PDF forms', + ); + %defaultchecked = ('canuse_pdfforms' => 'off'); + @toggles = ('canuse_pdfforms',); + ($datatable,$itemcount) = &radiobutton_prefs($settings,\@toggles,\%defaultchecked, + \%choices,$itemcount); + $$rowtotal += $itemcount; + return $datatable; +} + +sub print_usersessions { + my ($position,$dom,$settings,$rowtotal) = @_; + my ($css_class,$datatable,%checked,%choices); + my %lt = &usersession_titles(); + my $itemcount = 1; + my $numinrow = 6; + my $prefix; + my @types; + if ($position eq 'top') { + $prefix = 'hosted'; + @types = ('excludedomain','includedomain'); + } else { + $prefix = 'remote'; + @types = ('version','excludedomain','includedomain'); + } + my (%current,%checkedon,%checkedoff); + my @lcversions = &Apache::lonnet::all_loncaparevs(); + my @alldoms = sort(&Apache::lonnet::all_domains()); + foreach my $type (@types) { + $checkedon{$type} = ''; + $checkedoff{$type} = ' checked="checked"'; + } + if (ref($settings) eq 'HASH') { + if (ref($settings->{$prefix}) eq 'HASH') { + foreach my $key (keys(%{$settings->{$prefix}})) { + $current{$key} = $settings->{$prefix}{$key}; + if ($key eq 'version') { + if ($current{$key} ne '') { + $checkedon{$key} = ' checked="checked"'; + $checkedoff{$key} = ''; + } + } elsif (ref($current{$key}) eq 'ARRAY') { + $checkedon{$key} = ' checked="checked"'; + $checkedoff{$key} = ''; + } + } + } + } + foreach my $type (@types) { + $css_class = $itemcount%2 ? ' class="LC_odd_row"' : ''; + $datatable .= '<tr'.$css_class.'> + <td><span class="LC_nobreak">'.$lt{$type}.'</span><br /> + <span class="LC_nobreak"> + <label><input type="radio" name="'.$prefix.'_'.$type.'_inuse" '.$checkedoff{$type}.' value="0" />'.&mt('Not in use').'</label> + <label><input type="radio" name="'.$prefix.'_'.$type.'_inuse" '.$checkedon{$type}.' value="1" />'.&mt('In use').'</label></span></td><td>'; + if ($type eq 'version') { + my $selector = '<select name="'.$prefix.'_version">'; + foreach my $version (@lcversions) { + my $selected = ''; + if ($current{'version'} eq $version) { + $selected = ' selected="selected"'; + } + $selector .= ' <option value="'.$version.'"'. + $selected.'>'.$version.'</option>'; + } + $selector .= '</select> '; + $datatable .= &mt('remote server must be version: [_1] or later',$selector); + } else { + $datatable.= '<div><input type="button" value="'.&mt('check all').'" '. + 'onclick="javascript:checkAll(document.display.'.$prefix.'_'.$type.')"'. + ' />'.(' 'x2). + '<input type="button" value="'.&mt('uncheck all').'" '. + 'onclick="javascript:uncheckAll(document.display.'.$prefix.'_'.$type.')" />'. + "\n". + '</div><div><table>'; + my $rem; + for (my $i=0; $i<@alldoms; $i++) { + next if ($alldoms[$i] eq $dom); + my $checkedtype; + if (ref($current{$type}) eq 'ARRAY') { + if (grep(/^\Q$alldoms[$i]\E$/,@{$current{$type}})) { + $checkedtype = ' checked="checked"'; + } + } + $rem = $i%($numinrow); + if ($rem == 0) { + if ($i > 0) { + $datatable .= '</tr>'; + } + $datatable .= '<tr>'; + } + $datatable .= '<td class="LC_left_item">'. + '<span class="LC_nobreak"><label>'. + '<input type="checkbox" name="'.$prefix.'_'.$type. + '" value="'.$alldoms[$i].'"'.$checkedtype.' />'.$alldoms[$i]. + '</label></span></td>'; + } + $rem = @alldoms%($numinrow); + my $colsleft = $numinrow - $rem; + if ($colsleft > 1 ) { + $datatable .= '<td colspan="'.$colsleft.'" class="LC_left_item">'. + ' </td>'; + } elsif ($colsleft == 1) { + $datatable .= '<td class="LC_left_item"> </td>'; + } + $datatable .= '</tr></table>'; + } + $datatable .= '</td></tr>'; + $itemcount ++; + } + $$rowtotal += $itemcount; + return $datatable; +} + sub contact_titles { my %titles = &Apache::lonlocal::texthash ( 'supportemail' => 'Support E-mail address', 'adminemail' => 'Default Server Admin E-mail address', 'errormail' => 'Error reports to be e-mailed to', 'packagesmail' => 'Package update alerts to be e-mailed to', - 'helpdeskmail' => 'Helpdesk requests to be e-mailed to' + 'helpdeskmail' => 'Helpdesk requests to be e-mailed to', + 'lonstatusmail' => 'E-mail from nightly status check (warnings/errors)', + 'requestsmail' => 'E-mail from course requests requiring approval', ); my %short_titles = &Apache::lonlocal::texthash ( adminemail => 'Admin E-mail address', @@ -1644,13 +2379,39 @@ sub contact_titles { sub tool_titles { my %titles = &Apache::lonlocal::texthash ( - aboutme => 'Personal Home Page', - blog => 'Blog', - portfolio => 'Portfolio', - ); + aboutme => 'Personal Information Page', + blog => 'Blog', + portfolio => 'Portfolio', + official => 'Official courses (with institutional codes)', + unofficial => 'Unofficial courses', + community => 'Communities', + ); return %titles; } +sub courserequest_titles { + my %titles = &Apache::lonlocal::texthash ( + official => 'Official', + unofficial => 'Unofficial', + community => 'Communities', + norequest => 'Not allowed', + approval => 'Approval by Dom. Coord.', + validate => 'With validation', + autolimit => 'Numerical limit', + unlimited => '(blank for unlimited)', + ); + return %titles; +} + +sub courserequest_conditions { + my %conditions = &Apache::lonlocal::texthash ( + approval => '(Processing of request subject to approval by Domain Coordinator).', + validate => '(Processing of request subject to instittutional validation).', + ); + return %conditions; +} + + sub print_usercreation { my ($position,$dom,$settings,$rowtotal) = @_; my $numinrow = 4; @@ -1692,7 +2453,7 @@ sub print_usercreation { $rowcount ++; } } elsif ($position eq 'middle') { - my @creators = ('author','course','selfcreate'); + my @creators = ('author','course','requestcrs','selfcreate'); my ($rules,$ruleorder) = &Apache::lonnet::inst_userrules($dom,'username'); my %lt = &usercreation_types(); @@ -1769,6 +2530,20 @@ sub print_usercreation { } $datatable .= '</td></tr>'; } + my ($othertitle,$usertypes,$types) = + &Apache::loncommon::sorted_inst_types($dom); + if (ref($usertypes) eq 'HASH') { + if (keys(%{$usertypes}) > 0) { + my $createsettings; + if (ref($settings) eq 'HASH') { + $createsettings = $settings->{cancreate}; + } + $datatable .= &insttypes_row($createsettings,$types,$usertypes, + $dom,$numinrow,$othertitle, + 'statustocreate'); + $$rowtotal ++; + } + } } else { my @contexts = ('author','course','domain'); my @authtypes = ('int','krb4','krb5','loc'); @@ -1881,11 +2656,12 @@ sub usercreation_types { my %lt = &Apache::lonlocal::texthash ( author => 'When adding a co-author', course => 'When adding a user to a course', + requestcrs => 'When requesting a course', selfcreate => 'User creates own account', any => 'Any', official => 'Institutional only ', unofficial => 'Non-institutional only', - email => 'Email address', + email => 'E-mail address', login => 'Institutional Login', sso => 'SSO', none => 'None', @@ -2022,8 +2798,8 @@ sub print_scantronformat { %confhash); my $switchserver = &check_switchserver($dom,$confname); my %lt = &Apache::lonlocal::texthash ( - default => 'Default scantron format file error', - custom => 'Custom scantron format file error', + default => 'Default bubblesheet format file error', + custom => 'Custom bubblesheet format file error', ); my %scantronfiles = ( default => 'default.tab', @@ -2096,7 +2872,7 @@ sub print_scantronformat { } } } else { - $error{'default'} = &mt("Unable to copy default scantron formatfile to domain's RES space: [_1]",$switchserver); + $error{'default'} = &mt("Unable to copy default bubblesheet formatfile to domain's RES space: [_1]",$switchserver); } } if (ref($settings) eq 'HASH') { @@ -2125,7 +2901,7 @@ sub print_scantronformat { '<span class="LC_nobreak">'; if ($scantronurl) { $datatable .= '<a href="'.$scantronurl.'" target="_blank">'. - &mt('Default scantron format file').'</a>'; + &mt('Default bubblesheet format file').'</a>'; } else { $datatable = &mt('File unavailable for display'); } @@ -2152,7 +2928,7 @@ sub print_scantronformat { } elsif ($scantronurl) { $datatable .= '<td><span class="LC_nobreak">'. '<a href="'.$scantronurl.'" target="_blank">'. - &mt('Custom scantron format file').'</a><label>'. + &mt('Custom bubblesheet format file').'</a><label>'. '<input type="checkbox" name="scantronformat_del"'. '" value="1" />'.&mt('Delete?').'</label></span></td>'. '<td><span class="LC_nobreak"> '. @@ -2181,7 +2957,7 @@ sub legacy_scantronformat { &publishlogo($r,'copy',$legacyfile,$dom,$confname,'scantron', '','',$newfile); if ($result ne 'ok') { - $error = &mt("An error occurred publishing the [_1] scantron format file in RES space. Error was: [_2].",$newfile,$result); + $error = &mt("An error occurred publishing the [_1] bubblesheet format file in RES space. Error was: [_2].",$newfile,$result); } } return ($url,$error); @@ -2195,6 +2971,11 @@ sub print_coursecategories { my $toggle_cats_dom = ' checked="checked" '; my $can_cat_crs = ' '; my $can_cat_dom = ' checked="checked" '; + my $toggle_catscomm_comm = ' '; + my $toggle_catscomm_dom = ' checked="checked" '; + my $can_catcomm_comm = ' '; + my $can_catcomm_dom = ' checked="checked" '; + if (ref($settings) eq 'HASH') { if ($settings->{'togglecats'} eq 'crs') { $toggle_cats_crs = $toggle_cats_dom; @@ -2204,14 +2985,25 @@ sub print_coursecategories { $can_cat_crs = $can_cat_dom; $can_cat_dom = ' '; } + if ($settings->{'togglecatscomm'} eq 'comm') { + $toggle_catscomm_comm = $toggle_catscomm_dom; + $toggle_catscomm_dom = ' '; + } + if ($settings->{'categorizecomm'} eq 'comm') { + $can_catcomm_comm = $can_catcomm_dom; + $can_catcomm_dom = ' '; + } } my %title = &Apache::lonlocal::texthash ( - togglecats => 'Show/Hide a course in the catalog', - categorize => 'Assign a category to a course', + togglecats => 'Show/Hide a course in catalog', + togglecatscomm => 'Show/Hide a community in catalog', + categorize => 'Assign a category to a course', + categorizecomm => 'Assign a category to a community', ); my %level = &Apache::lonlocal::texthash ( - dom => 'Set in "Modify Course" (Domain)', - crs => 'Set in "Modify Parameters" (Course)', + dom => 'Set in Domain', + crs => 'Set in Course', + comm => 'Set in Community', ); $datatable = '<tr class="LC_odd_row">'. '<td>'.$title{'togglecats'}.'</td>'. @@ -2227,8 +3019,22 @@ sub print_coursecategories { $can_cat_dom.' value="dom" />'.$level{'dom'}.'</label> '. '<label><input type="radio" name="categorize"'. $can_cat_crs.'value="crs" />'.$level{'crs'}.'</label></span></td>'. + '</tr><tr class="LC_odd_row">'. + '<td>'.$title{'togglecatscomm'}.'</td>'. + '<td class="LC_right_item"><span class="LC_nobreak"><label>'. + '<input type="radio" name="togglecatscomm"'. + $toggle_catscomm_dom.' value="dom" />'.$level{'dom'}.'</label> '. + '<label><input type="radio" name="togglecatscomm"'. + $toggle_catscomm_comm.' value="comm" />'.$level{'comm'}.'</label></span></td>'. + '</tr><tr>'. + '<td>'.$title{'categorizecomm'}.'</td>'. + '<td class="LC_right_item"><span class="LC_nobreak">'. + '<label><input type="radio" name="categorizecomm"'. + $can_catcomm_dom.' value="dom" />'.$level{'dom'}.'</label> '. + '<label><input type="radio" name="categorizecomm"'. + $can_catcomm_comm.'value="comm" />'.$level{'comm'}.'</label></span></td>'. '</tr>'; - $$rowtotal += 2; + $$rowtotal += 4; } else { my $css_class; my $itemcount = 1; @@ -2250,7 +3056,15 @@ sub print_coursecategories { if (ref($cats[0]) eq 'ARRAY') { my $numtop = @{$cats[0]}; my $maxnum = $numtop; - if ((!grep(/^instcode$/,@{$cats[0]})) || ($cathash->{'instcode::0'} eq '')) { + my %default_names = ( + instcode => &mt('Official courses'), + communities => &mt('Communities'), + ); + + if ((!grep(/^instcode$/,@{$cats[0]})) || + ($cathash->{'instcode::0'} eq '') || + (!grep(/^communities$/,@{$cats[0]})) || + ($cathash->{'communities::0'} eq '')) { $maxnum ++; } my $lastidx; @@ -2271,14 +3085,33 @@ sub print_coursecategories { $datatable .= '<option value="'.$k.'"'.$selstr.'>'.$vpos.'</option>'; } $datatable .= '</select></td><td>'; - if ($parent eq 'instcode') { - $datatable .= '<span class="LC_nobreak">'.&mt('Official courses') - .'</span><br /><span class="LC_nobreak">(' - .&mt('with institutional codes').')</span></td>' - .'<td'.$colattrib.'><span class="LC_nobreak"><label><input type="radio" name="instcode" value="1" checked="checked" />' - .&mt('Display').'</label> ' - .'<label><input type="radio" name="instcode" value="0" />' - .&mt('Do not display').'</label></span></td>'; + if ($parent eq 'instcode' || $parent eq 'communities') { + $datatable .= '<span class="LC_nobreak">' + .$default_names{$parent}.'</span>'; + if ($parent eq 'instcode') { + $datatable .= '<br /><span class="LC_nobreak">(' + .&mt('with institutional codes') + .')</span></td><td'.$colattrib.'>'; + } else { + $datatable .= '<table><tr><td>'; + } + $datatable .= '<span class="LC_nobreak">' + .'<label><input type="radio" name="' + .$parent.'" value="1" checked="checked" />' + .&mt('Display').'</label>'; + if ($parent eq 'instcode') { + $datatable .= ' '; + } else { + $datatable .= '</span></td></tr><tr><td>' + .'<span class="LC_nobreak">'; + } + $datatable .= '<label><input type="radio" name="' + .$parent.'" value="0" />' + .&mt('Do not display').'</label></span>'; + if ($parent eq 'communities') { + $datatable .= '</td></tr></table>'; + } + $datatable .= '</td>'; } else { $datatable .= $parent .' <label><input type="checkbox" name="deletecategory" ' @@ -2306,26 +3139,33 @@ sub print_coursecategories { .'<input type="text" size="20" name="addcategory_name" value="" /></td>' .'</tr>'."\n"; $itemcount ++; - if ((!grep(/^instcode$/,@{$cats[0]})) || ($cathash->{'instcode::0'} eq '')) { - $css_class = $itemcount%2?' class="LC_odd_row"':''; - my $chgstr = ' onchange="javascript:reorderCats(this.form,'."'','instcode_pos','$lastidx'".');"'; - $datatable .= '<tr><td colspan="'.$maxdepth.'" class="LC_row_separator"></td></tr><tr '.$css_class.'><td>'. - '<span class="LC_nobreak"><select name="instcode_pos"'.$chgstr.'>'; - for (my $k=0; $k<=$maxnum; $k++) { - my $vpos = $k+1; - my $selstr; - if ($k == $maxnum) { - $selstr = ' selected="selected" '; + foreach my $default ('instcode','communities') { + if ((!grep(/^\Q$default\E$/,@{$cats[0]})) || ($cathash->{$default.'::0'} eq '')) { + $css_class = $itemcount%2?' class="LC_odd_row"':''; + my $chgstr = ' onchange="javascript:reorderCats(this.form,'."'','$default"."_pos','$lastidx'".');"'; + $datatable .= '<tr><td colspan="'.$maxdepth.'" class="LC_row_separator"></td></tr><tr '.$css_class.'><td>'. + '<span class="LC_nobreak"><select name="'.$default.'_pos"'.$chgstr.'>'; + for (my $k=0; $k<=$maxnum; $k++) { + my $vpos = $k+1; + my $selstr; + if ($k == $maxnum) { + $selstr = ' selected="selected" '; + } + $datatable .= '<option value="'.$k.'"'.$selstr.'>'.$vpos.'</option>'; } - $datatable .= '<option value="'.$k.'"'.$selstr.'>'.$vpos.'</option>'; + $datatable .= '</select></span></td>'. + '<td><span class="LC_nobreak">'. + $default_names{$default}.'</span>'; + if ($default eq 'instcode') { + $datatable .= '<br /><span class="LC_nobreak">(' + .&mt('with institutional codes').')</span>'; + } + $datatable .= '</td>' + .'<td><span class="LC_nobreak"><label><input type="radio" name="'.$default.'" value="1" />' + .&mt('Display').'</label> ' + .'<label><input type="radio" name="'.$default.'" value="0" checked="checked"/>' + .&mt('Do not display').'</label></span></td></tr>'; } - $datatable .= '</select></span></td><td><span class="LC_nobreak">' - .&mt('Official courses').'</span>'.'<br /><span class="LC_nobreak">(' - .&mt('with institutional codes').')</span></td>' - .'<td><span class="LC_nobreak"><label><input type="radio" name="instcode" value="1" />' - .&mt('Display').'</label> ' - .'<label><input type="radio" name="instcode" value="0" checked="checked"/>' - .&mt('Do not display').'</label></span></td></tr>'; } } } else { @@ -2364,7 +3204,7 @@ sub print_serverstatuses { } } } - my $titles= &LONCAPA::loncgi::serverstatus_titles(); + my $titles= &LONCAPA::lonauthcgi::serverstatus_titles(); my $rownum = 0; my $css_class; foreach my $type (@pages) { @@ -2389,7 +3229,7 @@ sub print_serverstatuses { sub serverstatus_pages { return ('userstatus','lonstatus','loncron','server-status','codeversions', 'clusterstatus','metadata_keywords','metadata_harvest', - 'takeoffline','takeonline','showenv'); + 'takeoffline','takeonline','showenv','toggledebug'); } sub coursecategories_javascript { @@ -2414,8 +3254,12 @@ sub coursecategories_javascript { $jstext = ' var categories = Array(1);'."\n". ' categories[0] = Array("instcode_pos");'."\n"; } + my $instcode_reserved = &mt('The name: "instcode" is a reserved category'); + my $communities_reserved = &mt('The name: "communities" is a reserved category'); + my $choose_again = '\\n'.&mt('Please use a different name for the new top level category'); $output = <<"ENDSCRIPT"; <script type="text/javascript"> +// <![CDATA[ function reorderCats(form,parent,item,idx) { var changedVal; $jstext @@ -2472,6 +3316,20 @@ $jstext } return; } + +function categoryCheck(form) { + if (form.elements['addcategory_name'].value == 'instcode') { + alert('$instcode_reserved\\n$choose_again'); + return false; + } + if (form.elements['addcategory_name'].value == 'communities') { + alert('$communities_reserved\\n$choose_again'); + return false; + } + return true; +} + +// ]]> </script> ENDSCRIPT @@ -2480,25 +3338,40 @@ ENDSCRIPT sub initialize_categories { my ($itemcount) = @_; - my $datatable; - my $css_class = $itemcount%2?' class="LC_odd_row"':''; - my $chgstr = ' onchange="javascript:reorderCats(this.form,'."'','instcode_pos','0'".');"'; - - $datatable = '<tr '.$css_class.'><td><span class="LC_nobreak">' - .'<select name="instcode_pos"><option value="0" selected="selected">1</option>' - .'<option value="1">2</option></select> ' - .&mt('Official courses (with institutional codes)') - .'</span></td><td><span class="LC_nobreak">' - .'<label><input type="radio" name="instcode" value="1" checked="checked" />' - .&mt('Display').'</label> <label>' - .'<input type="radio" name="instcode" value="0" />'.&mt('Do not display') + my ($datatable,$css_class,$chgstr); + my %default_names = ( + instcode => 'Official courses (with institutional codes)', + communities => 'Communities', + ); + my $select0 = ' selected="selected"'; + my $select1 = ''; + foreach my $default ('instcode','communities') { + $css_class = $itemcount%2?' class="LC_odd_row"':''; + $chgstr = ' onchange="javascript:reorderCats(this.form,'."'',$default"."_pos','0'".');"'; + if ($default eq 'communities') { + $select1 = $select0; + $select0 = ''; + } + $datatable .= '<tr '.$css_class.'><td><span class="LC_nobreak">' + .'<select name="'.$default.'_pos">' + .'<option value="0"'.$select0.'>1</option>' + .'<option value="1"'.$select1.'>2</option>' + .'<option value="2">3</option></select> ' + .$default_names{$default} + .'</span></td><td><span class="LC_nobreak">' + .'<label><input type="radio" name="'.$default.'" value="1" checked="checked" />' + .&mt('Display').'</label> <label>' + .'<input type="radio" name="'.$default.'" value="0" />'.&mt('Do not display') .'</label></span></td></tr>'; - $itemcount ++; + $itemcount ++; + } $css_class = $itemcount%2?' class="LC_odd_row"':''; $chgstr = ' onchange="javascript:reorderCats(this.form,'."'','addcategory_pos','0'".');"'; $datatable .= '<tr '.$css_class.'><td><span class="LC_nobreak">' - .'<select name="addcategory_pos"'.$chgstr.'><option value="0">1</option>' - .'<option value="1" selected="selected">2</option></select> ' + .'<select name="addcategory_pos"'.$chgstr.'>' + .'<option value="0">1</option>' + .'<option value="1">2</option>' + .'<option value="2" selected="selected">3</option></select> ' .&mt('Add category').'</td><td>'.&mt('Name:') .' <input type="text" size="20" name="addcategory_name" value="" /></td></tr>'; return $datatable; @@ -2659,10 +3532,19 @@ sub modifiable_userdata_row { return $output; } -sub users_cansearch_row { - my ($settings,$types,$usertypes,$dom,$numinrow,$othertitle) = @_; +sub insttypes_row { + my ($settings,$types,$usertypes,$dom,$numinrow,$othertitle,$context) = @_; + my %lt = &Apache::lonlocal::texthash ( + cansearch => 'Users allowed to search', + statustocreate => 'Institutional affiliation(s) able to create own account (login/SSO)', + lockablenames => 'User preference to lock name', + ); + my $showdom; + if ($context eq 'cansearch') { + $showdom = ' ('.$dom.')'; + } my $output = '<tr class="LC_odd_row">'. - '<td>'.&mt('Users allowed to search').' ('.$dom.')'. + '<td>'.$lt{$context}.$showdom. '</td><td class="LC_left_item" colspan="2"><table>'; my $rem; if (ref($types) eq 'ARRAY') { @@ -2676,35 +3558,45 @@ sub users_cansearch_row { $output .= '<tr>'; } my $check = ' '; - if (ref($settings->{'cansearch'}) eq 'ARRAY') { - if (grep(/^\Q$types->[$i]\E$/,@{$settings->{'cansearch'}})) { + if (ref($settings) eq 'HASH') { + if (ref($settings->{$context}) eq 'ARRAY') { + if (grep(/^\Q$types->[$i]\E$/,@{$settings->{$context}})) { + $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="cansearch" '. + '<input type="checkbox" name="'.$context.'" '. 'value="'.$types->[$i].'"'.$check.'/>'. $usertypes->{$types->[$i]}.'</label></span></td>'; } } - $rem = @{$types}%($numinrow); } my $colsleft = $numinrow - $rem; + if (($rem == 0) && (@{$types} > 0)) { + $output .= '<tr>'; + } if ($colsleft > 1) { $output .= '<td colspan="'.$colsleft.'" class="LC_left_item">'; } else { $output .= '<td class="LC_left_item">'; } my $defcheck = ' '; - if (ref($settings->{'cansearch'}) eq 'ARRAY') { - if (grep(/^default$/,@{$settings->{'cansearch'}})) { + if (ref($settings) eq 'HASH') { + if (ref($settings->{$context}) eq 'ARRAY') { + if (grep(/^default$/,@{$settings->{$context}})) { + $defcheck = ' checked="checked" '; + } + } elsif ($context eq 'statustocreate') { $defcheck = ' checked="checked" '; } } $output .= '<span class="LC_nobreak"><label>'. - '<input type="checkbox" name="cansearch" '. + '<input type="checkbox" name="'.$context.'" '. 'value="default"'.$defcheck.'/>'. $othertitle.'</label></span></td>'. '</tr></table></td></tr>'; @@ -2789,6 +3681,14 @@ sub modify_login { newuser => 'Link for visitors to create a user account', loginheader => 'Log-in box header'); my @offon = ('off','on'); + my %curr_loginvia; + if (ref($domconfig{login}) eq 'HASH') { + if (ref($domconfig{login}{loginvia}) eq 'HASH') { + foreach my $lonhost (keys(%{$domconfig{login}{loginvia}})) { + $curr_loginvia{$lonhost} = $domconfig{login}{loginvia}{$lonhost}; + } + } + } my %loginhash; ($errors,%colchanges) = &modify_colors($r,$dom,$confname,['login'], \%domconfig,\%loginhash); @@ -2801,6 +3701,93 @@ sub modify_login { $colchgtext = &display_colorchgs($dom,\%colchanges,['login'], \%loginhash); } + + my %servers = &dom_servers($dom); + my @loginvia_attribs = ('serverpath','custompath','exempt'); + if (keys(%servers) > 1) { + foreach my $lonhost (keys(%servers)) { + next if ($env{'form.'.$lonhost.'_server'} eq $lonhost); + if (ref($curr_loginvia{$lonhost}) eq 'HASH') { + if ($env{'form.'.$lonhost.'_server'} eq $curr_loginvia{$lonhost}{'server'}) { + $loginhash{login}{loginvia}{$lonhost}{'server'} = $curr_loginvia{$lonhost}{'server'}; + } elsif ($curr_loginvia{$lonhost}{'server'} ne '') { + if (defined($servers{$env{'form.'.$lonhost.'_server'}})) { + $loginhash{login}{loginvia}{$lonhost}{'server'} = $env{'form.'.$lonhost.'_server'}; + $changes{'loginvia'}{$lonhost} = 1; + } else { + $loginhash{login}{loginvia}{$lonhost}{'server'} = ''; + $changes{'loginvia'}{$lonhost} = 1; + } + } else { + if (defined($servers{$env{'form.'.$lonhost.'_server'}})) { + $loginhash{login}{loginvia}{$lonhost}{'server'} = $env{'form.'.$lonhost.'_server'}; + $changes{'loginvia'}{$lonhost} = 1; + } + } + if ($loginhash{login}{loginvia}{$lonhost}{'server'} eq '') { + foreach my $item (@loginvia_attribs) { + $loginhash{login}{loginvia}{$lonhost}{$item} = ''; + } + } else { + foreach my $item (@loginvia_attribs) { + my $new = $env{'form.'.$lonhost.'_'.$item}; + if (($item eq 'serverpath') && ($new eq 'custom')) { + $env{'form.'.$lonhost.'_custompath'} =~ s/\s+//g; + if ($env{'form.'.$lonhost.'_custompath'} eq '') { + $new = '/'; + } + } + if (($item eq 'custompath') && + ($env{'form.'.$lonhost.'_serverpath'} ne 'custom')) { + $new = ''; + } + if ($new ne $curr_loginvia{$lonhost}{$item}) { + $changes{'loginvia'}{$lonhost} = 1; + } + if ($item eq 'exempt') { + $new =~ s/^\s+//; + $new =~ s/\s+$//; + my @poss_ips = split(/\s*[,:]\s*/,$new); + my @okips; + foreach my $ip (@poss_ips) { + if ($ip =~ /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/) { + if (($1 <= 255) && ($2 <= 255) && ($3 <= 255) && ($4 <= 255)) { + push(@okips,$ip); + } + } + } + if (@okips > 0) { + $new = join(',',@okips); + } else { + $new = ''; + } + } + + $loginhash{login}{loginvia}{$lonhost}{$item} = $new; + } + } + } else { + if (defined($servers{$env{'form.'.$lonhost.'_server'}})) { + $loginhash{login}{loginvia}{$lonhost}{'server'} = $env{'form.'.$lonhost.'_server'}; + $changes{'loginvia'}{$lonhost} = 1; + foreach my $item (@loginvia_attribs) { + my $new = $env{'form.'.$lonhost.'_'.$item}; + if (($item eq 'serverpath') && ($new eq 'custom')) { + if ($env{'form.'.$lonhost.'_custompath'} eq '') { + $new = '/'; + } + } + if (($item eq 'custompath') && + ($env{'form.'.$lonhost.'_serverpath'} ne 'custom')) { + $new = ''; + } + $loginhash{login}{loginvia}{$lonhost}{$item} = $new; + } + } + } + } + } + my $putresult = &Apache::lonnet::put_dom('configuration',\%loginhash, $dom); if ($putresult eq 'ok') { @@ -2832,21 +3819,40 @@ sub modify_login { } } } - if (($domconfig{'login'}{'loginheader'} eq 'text') && - ($env{'form.loginheader'} eq 'image')) { - $changes{'loginheader'} = 1; - } elsif (($domconfig{'login'}{'loginheader'} eq '' || - $domconfig{'login'}{'loginheader'} eq 'image') && - ($env{'form.loginheader'} eq 'text')) { - $changes{'loginheader'} = 1; - } } if (keys(%changes) > 0 || $colchgtext) { &Apache::loncommon::devalidate_domconfig_cache($dom); $resulttext = &mt('Changes made:').'<ul>'; foreach my $item (sort(keys(%changes))) { - if ($item eq 'loginheader') { - $resulttext .= '<li>'.&mt("$title{$item} set to $env{'form.loginheader'}").'</li>'; + if ($item eq 'loginvia') { + if (ref($changes{$item}) eq 'HASH') { + $resulttext .= '<li>'.&mt('Log-in page availability:').'<ul>'; + foreach my $lonhost (sort(keys(%{$changes{$item}}))) { + if (defined($servers{$loginhash{login}{loginvia}{$lonhost}{'server'}})) { + if (ref($loginhash{login}{loginvia}{$lonhost}) eq 'HASH') { + my $protocol = $Apache::lonnet::protocol{$env{'form.'.$lonhost.'_server'}}; + $protocol = 'http' if ($protocol ne 'https'); + my $target = $protocol.'://'.$servers{$env{'form.'.$lonhost.'_server'}}; + + if ($loginhash{login}{loginvia}{$lonhost}{'serverpath'} eq 'custom') { + $target .= $loginhash{login}{loginvia}{$lonhost}{'custompath'}; + } else { + $target .= $loginhash{login}{loginvia}{$lonhost}{'serverpath'}; + } + $resulttext .= '<li>'.&mt('Server: [_1] log-in page redirects to [_2].',$servers{$lonhost},'<a href="'.$target.'">'.$target.'</a>'); + if ($loginhash{login}{loginvia}{$lonhost}{'exempt'} ne '') { + $resulttext .= ' '.&mt('No redirection for clients from following IPs:').' '.$loginhash{login}{loginvia}{$lonhost}{'exempt'}; + } + $resulttext .= '</li>'; + } else { + $resulttext .= '<li>'.&mt('Server: [_1] has standard log-in page.',$lonhost).'</li>'; + } + } else { + $resulttext .= '<li>'.&mt('Server: [_1] has standard log-in page.',$servers{$lonhost}).'</li>'; + } + } + $resulttext .= '</ul></li>'; + } } else { $resulttext .= '<li>'.&mt("$title{$item} set to $offon[$env{'form.'.$item}]").'</li>'; } @@ -2874,7 +3880,8 @@ sub color_font_choices { links => "Link colors", images => "Images", font => "Font color", - pgbg => "Header", + fontmenu => "Font Menu", + pgbg => "Page", tabbg => "Header", sidebg => "Border", link => "Link", @@ -2931,6 +3938,7 @@ sub modify_colors { @logintext = ('textcol','bgcol'); } else { %choices = &color_font_choices(); + $confhash->{$role}{'fontmenu'} = $env{'form.'.$role.'_fontmenu'}; } if ($role eq 'login') { @images = ('img','logo','domlogo','login'); @@ -3053,6 +4061,17 @@ sub modify_colors { $changes{$role}{'font'} = 1; } } + if ($role ne 'login') { + if ($domconfig->{$role}{'fontmenu'} ne '') { + if ($confhash->{$role}{'fontmenu'} ne $domconfig->{$role}{'fontmenu'}) { + $changes{$role}{'fontmenu'} = 1; + } + } else { + if ($confhash->{$role}{'fontmenu'}) { + $changes{$role}{'fontmenu'} = 1; + } + } + } foreach my $item (@bgs) { if ($domconfig->{$role}{$item} ne '') { if ($confhash->{$role}{$item} ne $domconfig->{$role}{$item}) { @@ -3482,95 +4501,159 @@ sub check_switchserver { return $switchserver; } -sub javascript_set_colnums { - return <<END; -function setDisplayColumns() { - if (document.pickactions.width.value > 1100) { - document.pickactions.numcols[1].checked = true; +sub modify_quotas { + my ($dom,$action,%domconfig) = @_; + my ($context,@usertools,@options,%validations,%titles,%confhash,%toolshash, + %limithash,$toolregexp,%conditions,$resulttext,%changes); + if ($action eq 'quotas') { + $context = 'tools'; + } else { + $context = $action; + } + if ($context eq 'requestcourses') { + @usertools = ('official','unofficial','community'); + @options =('norequest','approval','validate','autolimit'); + %validations = &Apache::lonnet::auto_courserequest_checks($dom); + %titles = &courserequest_titles(); + $toolregexp = join('|',@usertools); + %conditions = &courserequest_conditions(); } else { - document.pickactions.numcols[0].checked = true; + @usertools = ('aboutme','blog','portfolio'); + %titles = &tool_titles(); } -} -END -} - -sub modify_quotas { - my ($dom,%domconfig) = @_; my %domdefaults = &Apache::lonnet::get_domain_defaults($dom); - my ($resulttext,%changes); my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom); - my @usertools = ('aboutme','blog','portfolio'); - my %titles = &tool_titles(); - my (%confhash,%toolshash); foreach my $key (keys(%env)) { - if ($key =~ /^form\.quota_(.+)$/) { - $confhash{'defaultquota'}{$1} = $env{$key}; - } elsif ($key =~ /^form\.tools_(.+)$/) { - @{$toolshash{$1}} = &Apache::loncommon::get_env_multiple($key); + if ($context eq 'requestcourses') { + if ($key =~ /^form\.crsreq_($toolregexp)_(.+)$/) { + my $item = $1; + my $type = $2; + if ($type =~ /^limit_(.+)/) { + $limithash{$item}{$1} = $env{$key}; + } else { + $confhash{$item}{$type} = $env{$key}; + } + } + } else { + if ($key =~ /^form\.quota_(.+)$/) { + $confhash{'defaultquota'}{$1} = $env{$key}; + } + if ($key =~ /^form\.\Q$context\E_(.+)$/) { + @{$toolshash{$1}} = &Apache::loncommon::get_env_multiple($key); + } + } + } + if ($context eq 'requestcourses') { + my @approvalnotify = &Apache::loncommon::get_env_multiple('form.reqapprovalnotify'); + @approvalnotify = sort(@approvalnotify); + $confhash{'notify'}{'approval'} = join(',',@approvalnotify); + if (ref($domconfig{$action}) eq 'HASH') { + if (ref($domconfig{$action}{'notify'}) eq 'HASH') { + if ($domconfig{$action}{'notify'}{'approval'} ne $confhash{'notify'}{'approval'}) { + $changes{'notify'}{'approval'} = 1; + } + } else { + if ($domconfig{$action}{'notify'}{'approval'}) { + $changes{'notify'}{'approval'} = 1; + } + } + } else { + if ($domconfig{$action}{'notify'}{'approval'}) { + $changes{'notify'}{'approval'} = 1; + } } + } else { + $confhash{'defaultquota'}{'default'} = $env{'form.defaultquota'}; } - $confhash{'defaultquota'}{'default'} = $env{'form.defaultquota'}; foreach my $item (@usertools) { foreach my $type (@{$types},'default','_LC_adv') { - if (grep(/^\Q$type\E$/,@{$toolshash{$item}})) { - $confhash{$item}{$type} = 1; + my $unset; + if ($context eq 'requestcourses') { + $unset = '0'; + if ($type eq '_LC_adv') { + $unset = ''; + } + if ($confhash{$item}{$type} eq 'autolimit') { + $confhash{$item}{$type} .= '='; + unless ($limithash{$item}{$type} =~ /\D/) { + $confhash{$item}{$type} .= $limithash{$item}{$type}; + } + } } else { - $confhash{$item}{$type} = 0; + if (grep(/^\Q$type\E$/,@{$toolshash{$item}})) { + $confhash{$item}{$type} = 1; + } else { + $confhash{$item}{$type} = 0; + } } - if (ref($domconfig{'quotas'}) eq 'HASH') { - if (ref($domconfig{'quotas'}{$item}) eq 'HASH') { - if ($domconfig{'quotas'}{$item}{$type} ne $confhash{$item}{$type}) { + if (ref($domconfig{$action}) eq 'HASH') { + if (ref($domconfig{$action}{$item}) eq 'HASH') { + if ($domconfig{$action}{$item}{$type} ne $confhash{$item}{$type}) { $changes{$item}{$type} = 1; } } else { - if (!$confhash{$item}{$type}) { - $changes{$item}{$type} = 1; + if ($context eq 'requestcourses') { + if ($confhash{$item}{$type} ne $unset) { + $changes{$item}{$type} = 1; + } + } else { + if (!$confhash{$item}{$type}) { + $changes{$item}{$type} = 1; + } } } } else { - if (!$confhash{$item}{$type}) { - $changes{$item}{$type} = 1; + if ($context eq 'requestcourses') { + if ($confhash{$item}{$type} ne $unset) { + $changes{$item}{$type} = 1; + } + } else { + if (!$confhash{$item}{$type}) { + $changes{$item}{$type} = 1; + } } } } } - if (ref($domconfig{'quotas'}) eq 'HASH') { - if (ref($domconfig{'quotas'}{'defaultquota'}) eq 'HASH') { - foreach my $key (keys(%{$domconfig{'quotas'}{'defaultquota'}})) { - if (exists($confhash{'defaultquota'}{$key})) { - if ($confhash{'defaultquota'}{$key} ne $domconfig{'quotas'}{'defaultquota'}{$key}) { - $changes{'defaultquota'}{$key} = 1; + unless ($context eq 'requestcourses') { + if (ref($domconfig{'quotas'}) eq 'HASH') { + if (ref($domconfig{'quotas'}{'defaultquota'}) eq 'HASH') { + foreach my $key (keys(%{$domconfig{'quotas'}{'defaultquota'}})) { + if (exists($confhash{'defaultquota'}{$key})) { + if ($confhash{'defaultquota'}{$key} ne $domconfig{'quotas'}{'defaultquota'}{$key}) { + $changes{'defaultquota'}{$key} = 1; + } + } else { + $confhash{'defaultquota'}{$key} = $domconfig{'quotas'}{'defaultquota'}{$key}; } - } else { - $confhash{'defaultquota'}{$key} = $domconfig{'quotas'}{'defaultquota'}{$key}; } - } - } else { - foreach my $key (keys(%{$domconfig{'quotas'}})) { - if (exists($confhash{'defaultquota'}{$key})) { - if ($confhash{'defaultquota'}{$key} ne $domconfig{'quotas'}{$key}) { - $changes{'defaultquota'}{$key} = 1; + } else { + foreach my $key (keys(%{$domconfig{'quotas'}})) { + if (exists($confhash{'defaultquota'}{$key})) { + if ($confhash{'defaultquota'}{$key} ne $domconfig{'quotas'}{$key}) { + $changes{'defaultquota'}{$key} = 1; + } + } else { + $confhash{'defaultquota'}{$key} = $domconfig{'quotas'}{$key}; } - } else { - $confhash{'defaultquota'}{$key} = $domconfig{'quotas'}{$key}; } } } - } - if (ref($confhash{'defaultquota'}) eq 'HASH') { - foreach my $key (keys(%{$confhash{'defaultquota'}})) { - if (ref($domconfig{'quotas'}) eq 'HASH') { - if (ref($domconfig{'quotas'}{'defaultquota'}) eq 'HASH') { - if (!exists($domconfig{'quotas'}{'defaultquota'}{$key})) { - $changes{'defaultquota'}{$key} = 1; + if (ref($confhash{'defaultquota'}) eq 'HASH') { + foreach my $key (keys(%{$confhash{'defaultquota'}})) { + if (ref($domconfig{'quotas'}) eq 'HASH') { + if (ref($domconfig{'quotas'}{'defaultquota'}) eq 'HASH') { + if (!exists($domconfig{'quotas'}{'defaultquota'}{$key})) { + $changes{'defaultquota'}{$key} = 1; + } + } else { + if (!exists($domconfig{'quotas'}{$key})) { + $changes{'defaultquota'}{$key} = 1; + } } } else { - if (!exists($domconfig{'quotas'}{$key})) { - $changes{'defaultquota'}{$key} = 1; - } + $changes{'defaultquota'}{$key} = 1; } - } else { - $changes{'defaultquota'}{$key} = 1; } } } @@ -3580,7 +4663,7 @@ sub modify_quotas { } my %quotahash = ( - quotas => { %confhash } + $action => { %confhash } ); my $putresult = &Apache::lonnet::put_dom('configuration',\%quotahash, $dom); @@ -3590,23 +4673,37 @@ sub modify_quotas { &Apache::lonnet::do_cache_new('domdefaults',$dom,\%domdefaults,$cachetime); $resulttext = &mt('Changes made:').'<ul>'; - if (ref($changes{'defaultquota'}) eq 'HASH') { - $resulttext .= '<li>'.&mt('Portfolio default quotas').'<ul>'; - foreach my $type (@{$types},'default') { - if (defined($changes{'defaultquota'}{$type})) { - my $typetitle = $usertypes->{$type}; - if ($type eq 'default') { - $typetitle = $othertitle; + unless ($context eq 'requestcourses') { + if (ref($changes{'defaultquota'}) eq 'HASH') { + $resulttext .= '<li>'.&mt('Portfolio default quotas').'<ul>'; + foreach my $type (@{$types},'default') { + if (defined($changes{'defaultquota'}{$type})) { + my $typetitle = $usertypes->{$type}; + if ($type eq 'default') { + $typetitle = $othertitle; + } + $resulttext .= '<li>'.&mt('[_1] set to [_2] Mb',$typetitle,$confhash{'defaultquota'}{$type}).'</li>'; } - $resulttext .= '<li>'.&mt('[_1] set to [_2] Mb',$typetitle,$confhash{'defaultquota'}{$type}).'</li>'; } + $resulttext .= '</ul></li>'; } - $resulttext .= '</ul></li>'; } + my %newenv; foreach my $item (@usertools) { if (ref($changes{$item}) eq 'HASH') { - my $hashid = $env{'user.name'}.':'.$env{'user.domain'}; - &Apache::lonnet::devalidate_cache_new('usertools.'.$item,$hashid); + my $newacc = + &Apache::lonnet::usertools_access($env{'user.name'}, + $env{'user.domain'}, + $item,'reload',$context); + if ($context eq 'requestcourses') { + if ($env{'environment.canrequest.'.$item} ne $newacc) { + $newenv{'environment.canrequest.'.$item} = $newacc; + } + } else { + if ($env{'environment.availabletools.'.$item} ne $newacc) { + $newenv{'environment.availabletools.'.$item} = $newacc; + } + } $resulttext .= '<li>'.$titles{$item}.'<ul>'; foreach my $type (@{$types},'default','_LC_adv') { if ($changes{$item}{$type}) { @@ -3617,18 +4714,60 @@ sub modify_quotas { $typetitle = 'LON-CAPA Advanced Users'; } if ($confhash{$item}{$type}) { - $resulttext .= '<li>'.&mt('Set to be available to [_1]',$typetitle).'</li>'; + if ($context eq 'requestcourses') { + my $cond; + if ($confhash{$item}{$type} =~ /^autolimit=(\d*)$/) { + if ($1 eq '') { + $cond = &mt('(Automatic processing of any request).'); + } else { + $cond = &mt('(Automatic processing of requests up to limit of [quant,_1,request] per user).',$1); + } + } else { + $cond = $conditions{$confhash{$item}{$type}}; + } + $resulttext .= '<li>'.&mt('Set to be available to [_1].',$typetitle).' '.$cond.'</li>'; + } else { + $resulttext .= '<li>'.&mt('Set to be available to [_1]',$typetitle).'</li>'; + } } else { - $resulttext .= '<li>'.&mt('Set to be unavailable to [_1]',$typetitle).'</li>'; + if ($type eq '_LC_adv') { + if ($confhash{$item}{$type} eq '0') { + $resulttext .= '<li>'.&mt('Set to be unavailable to [_1]',$typetitle).'</li>'; + } else { + $resulttext .= '<li>'.&mt('No override set for [_1]',$typetitle).'</li>'; + } + } else { + $resulttext .= '<li>'.&mt('Set to be unavailable to [_1]',$typetitle).'</li>'; + } } } } $resulttext .= '</ul></li>'; } } + if ($action eq 'requestcourses') { + if (ref($changes{'notify'}) eq 'HASH') { + if ($changes{'notify'}{'approval'}) { + if (ref($confhash{'notify'}) eq 'HASH') { + if ($confhash{'notify'}{'approval'}) { + $resulttext .= '<li>'.&mt('Notification of requests requiring approval will be sent to: ').$confhash{'notify'}{'approval'}.'</li>'; + } else { + $resulttext .= '<li>'.&mt('No Domain Coordinators will receive notification of course requests requiring approval.').'</li>'; + } + } + } + } + } $resulttext .= '</ul>'; + if (keys(%newenv)) { + &Apache::lonnet::appenv(\%newenv); + } } else { - $resulttext = &mt('No changes made to availability of home pages, blogs, portfolios or default quotas'); + if ($context eq 'requestcourses') { + $resulttext = &mt('No changes made to rights to request creation of courses.'); + } else { + $resulttext = &mt('No changes made to availability of personal information pages, blogs, portfolios or default quotas'); + } } } else { $resulttext = '<span class="LC_error">'. @@ -3648,7 +4787,8 @@ sub modify_autoenroll { } my $autorun = &Apache::lonnet::auto_run(undef,$dom), my %title = ( run => 'Auto-enrollment active', - sender => 'Sender for notification messages'); + sender => 'Sender for notification messages', + coowners => 'Automatic assignment of co-ownership to instructors of record (institutional data)'); my @offon = ('off','on'); my $sender_uname = $env{'form.sender_uname'}; my $sender_domain = $env{'form.sender_domain'}; @@ -3657,11 +4797,12 @@ sub modify_autoenroll { } elsif ($sender_uname eq '') { $sender_domain = ''; } + my $coowners = $env{'form.autoassign_coowners'}; my %autoenrollhash = ( - autoenroll => { run => $env{'form.autoenroll_run'}, - sender_uname => $sender_uname, - sender_domain => $sender_domain, - + autoenroll => { 'run' => $env{'form.autoenroll_run'}, + 'sender_uname' => $sender_uname, + 'sender_domain' => $sender_domain, + 'co-owners' => $coowners, } ); my $putresult = &Apache::lonnet::put_dom('configuration',\%autoenrollhash, @@ -3682,6 +4823,13 @@ sub modify_autoenroll { if ($currautoenroll{'sender_domain'} ne $sender_domain) { $changes{'sender'} = 1; } + if ($currautoenroll{'co-owners'} ne '') { + if ($currautoenroll{'co-owners'} ne $coowners) { + $changes{'coowners'} = 1; + } + } elsif ($coowners) { + $changes{'coowners'} = 1; + } if (keys(%changes) > 0) { $resulttext = &mt('Changes made:').'<ul>'; if ($changes{'run'}) { @@ -3694,6 +4842,10 @@ sub modify_autoenroll { $resulttext .= '<li>'.&mt("$title{'sender'} set to [_1]",$sender_uname.':'.$sender_domain).'</li>'; } } + if ($changes{'coowners'}) { + $resulttext .= '<li>'.&mt("$title{'coowners'} set to $offon[$env{'form.autoassign_coowners'}]").'</li>'; + &Apache::loncommon::devalidate_domconfig_cache($dom); + } $resulttext .= '</ul>'; } else { $resulttext = &mt('No changes made to auto-enrollment settings'); @@ -3725,7 +4877,7 @@ sub modify_autoupdate { lastname => 'Last Name', firstname => 'First Name', middlename => 'Middle Name', - gen => 'Generation', + generation => 'Generation', ); my $othertitle = &mt('All users'); if (keys(%{$usertypes}) > 0) { @@ -3733,13 +4885,35 @@ sub modify_autoupdate { } foreach my $key (keys(%env)) { if ($key =~ /^form\.updateable_(.+)_([^_]+)$/) { - push(@{$fields{$1}},$2); + my ($usertype,$item) = ($1,$2); + if (grep(/^\Q$item\E$/,keys(%fieldtitles))) { + if ($usertype eq 'default') { + push(@{$fields{$1}},$2); + } elsif (ref($types) eq 'ARRAY') { + if (grep(/^\Q$usertype\E$/,@{$types})) { + push(@{$fields{$1}},$2); + } + } + } + } + } + my @lockablenames = &Apache::loncommon::get_env_multiple('form.lockablenames'); + @lockablenames = sort(@lockablenames); + if (ref($currautoupdate{'lockablenames'}) eq 'ARRAY') { + my @changed = &Apache::loncommon::compare_arrays($currautoupdate{'lockablenames'},\@lockablenames); + if (@changed) { + $changes{'lockablenames'} = 1; + } + } else { + if (@lockablenames) { + $changes{'lockablenames'} = 1; } } my %updatehash = ( autoupdate => { run => $env{'form.autoupdate_run'}, classlists => $env{'form.classlists'}, fields => {%fields}, + lockablenames => \@lockablenames, } ); foreach my $key (keys(%currautoupdate)) { @@ -3757,9 +4931,11 @@ sub modify_autoupdate { foreach my $type (@{$currautoupdate{$key}{$item}}) { if (!exists($fields{$item})) { $change = 1; + last; } elsif (ref($fields{$item}) eq 'ARRAY') { if (!grep(/^\Q$type\E$/,@{$fields{$item}})) { $change = 1; + last; } } } @@ -3769,12 +4945,41 @@ sub modify_autoupdate { } } } + } elsif ($key eq 'lockablenames') { + if (ref($currautoupdate{$key}) eq 'ARRAY') { + my @changed = &Apache::loncommon::compare_arrays($currautoupdate{'lockablenames'},\@lockablenames); + if (@changed) { + $changes{'lockablenames'} = 1; + } + } else { + if (@lockablenames) { + $changes{'lockablenames'} = 1; + } + } + } + } + unless (grep(/^\Qlockablenames\E$/,keys(%currautoupdate))) { + if (@lockablenames) { + $changes{'lockablenames'} = 1; } } foreach my $item (@{$types},'default') { if (defined($fields{$item})) { if (ref($currautoupdate{'fields'}) eq 'HASH') { - if (!exists($currautoupdate{'fields'}{$item})) { + if (ref($currautoupdate{'fields'}{$item}) eq 'ARRAY') { + my $change = 0; + if (ref($fields{$item}) eq 'ARRAY') { + foreach my $type (@{$fields{$item}}) { + if (!grep(/^\Q$type\E$/,@{$currautoupdate{'fields'}{$item}})) { + $change = 1; + last; + } + } + } + if ($change) { + push(@{$changes{'fields'}},$item); + } + } else { push(@{$changes{'fields'}},$item); } } else { @@ -3788,7 +4993,17 @@ sub modify_autoupdate { if (keys(%changes) > 0) { $resulttext = &mt('Changes made:').'<ul>'; foreach my $key (sort(keys(%changes))) { - if (ref($changes{$key}) eq 'ARRAY') { + if ($key eq 'lockablenames') { + $resulttext .= '<li>'; + if (@lockablenames) { + $usertypes->{'default'} = $othertitle; + $resulttext .= &mt("User preference to disable replacement of user's name with institutional data (by auto-update), available for the following affiliations:").' '. + join(', ', map { $usertypes->{$_}; } @lockablenames).'</li>'; + } else { + $resulttext .= &mt("User preference to disable replacement of user's name with institutional data (by auto-update) is unavailable."); + } + $resulttext .= '</li>'; + } elsif (ref($changes{$key}) eq 'ARRAY') { foreach my $item (@{$changes{$key}}) { my @newvalues; foreach my $type (@{$fields{$item}}) { @@ -3827,6 +5042,78 @@ sub modify_autoupdate { return $resulttext; } +sub modify_autocreate { + my ($dom,%domconfig) = @_; + my ($resulttext,%changes,%currautocreate,%newvals,%autocreatehash); + if (ref($domconfig{'autocreate'}) eq 'HASH') { + foreach my $key (keys(%{$domconfig{'autocreate'}})) { + $currautocreate{$key} = $domconfig{'autocreate'}{$key}; + } + } + my %title= ( xml => 'Auto-creation of courses in XML course description files', + req => 'Auto-creation of validated requests for official courses', + xmldc => 'Identity of course creator of courses from XML files', + ); + my @types = ('xml','req'); + foreach my $item (@types) { + $newvals{$item} = $env{'form.autocreate_'.$item}; + $newvals{$item} =~ s/\D//g; + $newvals{$item} = 0 if ($newvals{$item} eq ''); + } + $newvals{'xmldc'} = $env{'form.autocreate_xmldc'}; + my %domcoords = &get_active_dcs($dom); + unless (exists($domcoords{$newvals{'xmldc'}})) { + $newvals{'xmldc'} = ''; + } + %autocreatehash = ( + autocreate => { xml => $newvals{'xml'}, + req => $newvals{'req'}, + } + ); + if ($newvals{'xmldc'} ne '') { + $autocreatehash{'autocreate'}{'xmldc'} = $newvals{'xmldc'}; + } + my $putresult = &Apache::lonnet::put_dom('configuration',\%autocreatehash, + $dom); + if ($putresult eq 'ok') { + my @items = @types; + if ($newvals{'xml'}) { + push(@items,'xmldc'); + } + foreach my $item (@items) { + if (exists($currautocreate{$item})) { + if ($currautocreate{$item} ne $newvals{$item}) { + $changes{$item} = 1; + } + } elsif ($newvals{$item}) { + $changes{$item} = 1; + } + } + if (keys(%changes) > 0) { + my @offon = ('off','on'); + $resulttext = &mt('Changes made:').'<ul>'; + foreach my $item (@types) { + if ($changes{$item}) { + my $newtxt = $offon[$newvals{$item}]; + $resulttext .= '<li>'.&mt("$title{$item} set to [_1]$newtxt [_2]",'<b>','</b>').'</li>'; + } + } + if ($changes{'xmldc'}) { + my ($dcname,$dcdom) = split(':',$newvals{'xmldc'}); + my $newtxt = &Apache::loncommon::plainname($dcname,$dcdom); + $resulttext .= '<li>'.&mt("$title{'xmldc'} set to [_1]$newtxt [_2]",'<b>','</b>').'</li>'; + } + $resulttext .= '</ul>'; + } else { + $resulttext = &mt('No changes made to auto-creation settings'); + } + } else { + $resulttext = '<span class="LC_error">'. + &mt('An error occurred: [_1]',$putresult).'</span>'; + } + return $resulttext; +} + sub modify_directorysrch { my ($dom,%domconfig) = @_; my ($resulttext,%changes); @@ -4009,9 +5296,10 @@ sub modify_contacts { $currsetting{$key} = $domconfig{'contacts'}{$key}; } } - my (%others,%to); + my (%others,%to,%bcc); my @contacts = ('supportemail','adminemail'); - my @mailings = ('errormail','packagesmail','helpdeskmail'); + my @mailings = ('errormail','packagesmail','helpdeskmail','lonstatusmail', + 'requestsmail'); foreach my $type (@mailings) { @{$newsetting{$type}} = &Apache::loncommon::get_env_multiple('form.'.$type); @@ -4024,6 +5312,10 @@ sub modify_contacts { } $others{$type} = $env{'form.'.$type.'_others'}; $contacts_hash{contacts}{$type}{'others'} = $others{$type}; + if ($type eq 'helpdeskmail') { + $bcc{$type} = $env{'form.'.$type.'_bcc'}; + $contacts_hash{contacts}{$type}{'bcc'} = $bcc{$type}; + } } foreach my $item (@contacts) { $to{$item} = $env{'form.'.$item}; @@ -4048,6 +5340,11 @@ sub modify_contacts { if ($others{$type} ne $currsetting{$type}{'others'}) { push(@{$changes{$type}},'others'); } + if ($type eq 'helpdeskmail') { + if ($bcc{$type} ne $currsetting{$type}{'bcc'}) { + push(@{$changes{$type}},'bcc'); + } + } } } else { my %default; @@ -4056,6 +5353,8 @@ sub modify_contacts { $default{'errormail'} = 'adminemail'; $default{'packagesmail'} = 'adminemail'; $default{'helpdeskmail'} = 'supportemail'; + $default{'lonstatusmail'} = 'adminemail'; + $default{'requestsmail'} = 'adminemail'; foreach my $item (@contacts) { if ($to{$item} ne $default{$item}) { $changes{$item} = 1; @@ -4068,7 +5367,12 @@ sub modify_contacts { } if ($others{$type} ne '') { push(@{$changes{$type}},'others'); - } + } + if ($type eq 'helpdeskmail') { + if ($bcc{$type} ne '') { + push(@{$changes{$type}},'bcc'); + } + } } } my $putresult = &Apache::lonnet::put_dom('configuration',\%contacts_hash, @@ -4096,7 +5400,13 @@ sub modify_contacts { push(@text,$others{$type}); } $resulttext .= '<span class="LC_cusr_emph">'. - join(', ',@text).'</span></li>'; + join(', ',@text).'</span>'; + if ($type eq 'helpdeskmail') { + if ($bcc{$type} ne '') { + $resulttext .= ' '.&mt('with Bcc to').': <span class="LC_cusr_emph">'.$bcc{$type}.'</span>'; + } + } + $resulttext .= '</li>'; } } $resulttext .= '</ul>'; @@ -4122,7 +5432,7 @@ sub modify_usercreation { my @username_rule = &Apache::loncommon::get_env_multiple('form.username_rule'); my @id_rule = &Apache::loncommon::get_env_multiple('form.id_rule'); my @email_rule = &Apache::loncommon::get_env_multiple('form.email_rule'); - my @contexts = ('author','course','selfcreate'); + my @contexts = ('author','course','requestcrs','selfcreate'); foreach my $item(@contexts) { if ($item eq 'selfcreate') { @{$cancreate{$item}} = &Apache::loncommon::get_env_multiple('form.can_createuser_'.$item); @@ -4138,14 +5448,27 @@ sub modify_usercreation { $cancreate{$item} = $env{'form.can_createuser_'.$item}; } } + my ($othertitle,$usertypes,$types) = + &Apache::loncommon::sorted_inst_types($dom); + if (ref($types) eq 'ARRAY') { + if (@{$types} > 0) { + @{$cancreate{'statustocreate'}} = + &Apache::loncommon::get_env_multiple('form.statustocreate'); + } else { + @{$cancreate{'statustocreate'}} = (); + } + push(@contexts,'statustocreate'); + } if (ref($curr_usercreation{'cancreate'}) eq 'HASH') { foreach my $item (@contexts) { - if ($item eq 'selfcreate') { - if (ref($curr_usercreation{'cancreate'}{$item}) eq 'ARRAY') { + if (($item eq 'selfcreate') || ($item eq 'statustocreate')) { + if (ref($curr_usercreation{'cancreate'}{$item}) eq 'ARRAY') { foreach my $curr (@{$curr_usercreation{'cancreate'}{$item}}) { - if (!grep(/^$curr$/,@{$cancreate{$item}})) { - if (!grep(/^$item$/,@{$changes{'cancreate'}})) { - push(@{$changes{'cancreate'}},$item); + if (ref($cancreate{$item}) eq 'ARRAY') { + if (!grep(/^$curr$/,@{$cancreate{$item}})) { + if (!grep(/^$item$/,@{$changes{'cancreate'}})) { + push(@{$changes{'cancreate'}},$item); + } } } } @@ -4317,16 +5640,65 @@ sub modify_usercreation { if (ref($changes{'cancreate'}) eq 'ARRAY') { my %lt = &usercreation_types(); foreach my $type (@{$changes{'cancreate'}}) { - my $chgtext = $lt{$type}.', '; + my $chgtext; + unless ($type eq 'statustocreate') { + $chgtext = $lt{$type}.', '; + } if ($type eq 'selfcreate') { if (@{$cancreate{$type}} == 0) { $chgtext .= &mt('creation of a new user account is not permitted.'); } else { - $chgtext .= &mt('creation of a new account is permitted for:<ul>'); + $chgtext .= &mt('creation of a new account is permitted for:').'<ul>'; foreach my $case (@{$cancreate{$type}}) { $chgtext .= '<li>'.$selfcreatetypes{$case}.'</li>'; } $chgtext .= '</ul>'; + if (ref($cancreate{$type}) eq 'ARRAY') { + if (grep(/^(login|sso)$/,@{$cancreate{$type}})) { + if (ref($cancreate{'statustocreate'}) eq 'ARRAY') { + if (@{$cancreate{'statustocreate'}} == 0) { + $chgtext .= '<br /><span class="LC_warning">'.&mt("However, no institutional affiliations (including 'other') are currently permitted to create accounts.").'</span>'; + } + } + } + } + } + } elsif ($type eq 'statustocreate') { + if ((ref($cancreate{'selfcreate'}) eq 'ARRAY') && + (ref($cancreate{'statustocreate'}) eq 'ARRAY')) { + if (@{$cancreate{'selfcreate'}} > 0) { + if (@{$cancreate{'statustocreate'}} == 0) { + + $chgtext .= &mt("Institutional affiliations permitted to create accounts set to 'None'."); + if (!grep(/^email$/,@{$cancreate{'selfcreate'}})) { + $chgtext .= '<br /><span class="LC_warning">'.&mt("However, no institutional affiliations (including 'other') are currently permitted to create accounts.").'</span>'; + } + } elsif (ref($usertypes) eq 'HASH') { + if (grep(/^(login|sso)$/,@{$cancreate{'selfcreate'}})) { + $chgtext .= &mt('Creation of a new account for an institutional user is restricted to the following institutional affiliation(s):'); + } else { + $chgtext .= &mt('Institutional affiliations permitted to create accounts with institutional authentication were set as follows:'); + } + $chgtext .= '<ul>'; + foreach my $case (@{$cancreate{$type}}) { + if ($case eq 'default') { + $chgtext .= '<li>'.$othertitle.'</li>'; + } else { + $chgtext .= '<li>'.$usertypes->{$case}.'</li>'; + } + } + $chgtext .= '</ul>'; + if (!grep(/^(login|sso)$/,@{$cancreate{'selfcreate'}})) { + $chgtext .= '<br /><span class="LC_warning">'.&mt('However, users authenticated by institutional login/single sign on are not currently permitted to create accounts.').'</span>'; + } + } + } else { + if (@{$cancreate{$type}} == 0) { + $chgtext .= &mt("Institutional affiliations permitted to create accounts were set to 'none'."); + } else { + $chgtext .= &mt('Although institutional affiliations permitted to create accounts were changed, self creation of accounts is not currently permitted for any authentication types.'); + } + } } } else { if ($cancreate{$type} eq 'none') { @@ -4516,7 +5888,7 @@ sub modify_usermodification { } my @modifiable; if ($context eq 'selfcreate') { - $resulttext .= '<li><span class="LC_cusr_emph">'.&mt('Self-creation of account by users with status: [_1] ',$rolename).'</span> - '.&mt('modifiable fields (if institutional data blank): '); + $resulttext .= '<li><span class="LC_cusr_emph">'.&mt('Self-creation of account by users with status: [_1]',$rolename).'</span> - '.&mt('modifiable fields (if institutional data blank): '); } else { $resulttext .= '<li><span class="LC_cusr_emph">'.&mt('Target user with [_1] role',$rolename).'</span> - '.&mt('modifiable fields: '); } @@ -4565,8 +5937,10 @@ sub modify_defaults { if ($newvalues{$item} ne '') { if ($newvalues{$item} =~ /^(\w+)/) { my $langcode = $1; - if (code2language($langcode) eq '') { - push(@errors,$item); + if ($langcode ne 'x_chef') { + if (code2language($langcode) eq '') { + push(@errors,$item); + } } } else { push(@errors,$item); @@ -4658,7 +6032,7 @@ sub modify_scantron { my $error; if ($configuserok eq 'ok') { if ($switchserver) { - $error = &mt("Upload of scantron format file is not permitted to this server: [_1]",$switchserver); + $error = &mt("Upload of bubblesheet format file is not permitted to this server: [_1]",$switchserver); } else { if ($author_ok eq 'ok') { my ($result,$scantronurl) = @@ -4698,25 +6072,25 @@ sub modify_scantron { if (ref($confhash{'scantron'}) eq 'HASH') { $resulttext = &mt('Changes made:').'<ul>'; if ($confhash{'scantron'}{'scantronformat'} eq '') { - $resulttext .= '<li>'.&mt('[_1] scantron format file removed; [_2] file will be used for courses in this domain.',$custom,$default).'</li>'; + $resulttext .= '<li>'.&mt('[_1] bubblesheet format file removed; [_2] file will be used for courses in this domain.',$custom,$default).'</li>'; } else { - $resulttext .= '<li>'.&mt('Custom scantron format file ([_1]) uploaded for use with courses in this domain.',$custom).'</li>'; + $resulttext .= '<li>'.&mt('Custom bubblesheet format file ([_1]) uploaded for use with courses in this domain.',$custom).'</li>'; } $resulttext .= '</ul>'; } else { - $resulttext = &mt('Changes made to scantron format file.'); + $resulttext = &mt('Changes made to bubblesheet format file.'); } $resulttext .= '</ul>'; &Apache::loncommon::devalidate_domconfig_cache($dom); } else { - $resulttext = &mt('No changes made to scantron format file'); + $resulttext = &mt('No changes made to bubblesheet format file'); } } else { $resulttext = '<span class="LC_error">'. &mt('An error occurred: [_1]',$putresult).'</span>'; } } else { - $resulttext = &mt('No changes made to scantron format file'); + $resulttext = &mt('No changes made to bubblesheet format file'); } if ($errors) { $resulttext .= &mt('The following errors occurred: ').'<ul>'. @@ -4740,16 +6114,33 @@ sub modify_coursecategories { $changes{'categorize'} = 1; $domconfig{'coursecategories'}{'categorize'} = $env{'form.categorize'}; } + if ($domconfig{'coursecategories'}{'togglecatscomm'} ne $env{'form.togglecatscomm'}) { + $changes{'togglecatscomm'} = 1; + $domconfig{'coursecategories'}{'togglecatscomm'} = $env{'form.togglecatscomm'}; + } + if ($domconfig{'coursecategories'}{'categorizecomm'} ne $env{'form.categorizecomm'}) { + $changes{'categorizecomm'} = 1; + $domconfig{'coursecategories'}{'categorizecomm'} = $env{'form.categorizecomm'}; + } } else { $changes{'togglecats'} = 1; $changes{'categorize'} = 1; - $domconfig{'coursecategories'}{'togglecats'} = $env{'form.togglecats'}; - $domconfig{'coursecategories'}{'categorize'} = $env{'form.categorize'}; + $changes{'togglecatscomm'} = 1; + $changes{'categorizecomm'} = 1; + $domconfig{'coursecategories'} = { + togglecats => $env{'form.togglecats'}, + categorize => $env{'form.categorize'}, + togglecatscomm => $env{'form.togglecatscomm'}, + categorizecomm => $env{'form.categorizecomm'}, + }; } if (ref($cathash) eq 'HASH') { if (($domconfig{'coursecategories'}{'cats'}{'instcode::0'} ne '') && ($env{'form.instcode'} == 0)) { push (@deletecategory,'instcode::0'); } + if (($domconfig{'coursecategories'}{'cats'}{'communities::0'} ne '') && ($env{'form.communities'} == 0)) { + push(@deletecategory,'communities::0'); + } } my (@predelcats,@predeltrails,%predelallitems,%sort_by_deltrail); if (ref($cathash) eq 'HASH') { @@ -4799,10 +6190,26 @@ sub modify_coursecategories { $adds{$newitem} = 1; } } + if ($env{'form.communities'} eq '1') { + if (ref($cathash) eq 'HASH') { + my $newitem = 'communities::0'; + if ($cathash->{$newitem} eq '') { + $domconfig{'coursecategories'}{'cats'}{$newitem} = $env{'form.communities_pos'}; + $adds{$newitem} = 1; + } + } else { + my $newitem = 'communities::0'; + $domconfig{'coursecategories'}{'cats'}{$newitem} = $env{'form.communities_pos'}; + $adds{$newitem} = 1; + } + } if ($env{'form.addcategory_name'} ne '') { - my $newitem = &escape($env{'form.addcategory_name'}).'::0'; - $domconfig{'coursecategories'}{'cats'}{$newitem} = $env{'form.addcategory_pos'}; - $adds{$newitem} = 1; + if (($env{'form.addcategory_name'} ne 'instcode') && + ($env{'form.addcategory_name'} ne 'communities')) { + my $newitem = &escape($env{'form.addcategory_name'}).'::0'; + $domconfig{'coursecategories'}{'cats'}{$newitem} = $env{'form.addcategory_pos'}; + $adds{$newitem} = 1; + } } my $putresult; if ((keys(%deletions) > 0) || (keys(%reorderings) > 0) || (keys(%adds) > 0)) { @@ -4839,12 +6246,15 @@ sub modify_coursecategories { $putresult = &Apache::lonnet::put_dom('configuration',\%domconfig,$dom); if ($putresult eq 'ok') { my %title = ( - togglecats => 'Show/Hide a course in the catalog', - categorize => 'Category assigned to course', + togglecats => 'Show/Hide a course in catalog', + categorize => 'Assign a category to a course', + togglecatscomm => 'Show/Hide a community in catalog', + categorizecomm => 'Assign a category to a community', ); my %level = ( - dom => 'set from "Modify Course" (Domain)', - crs => 'set from "Parameters" (Course)', + dom => 'set in Domain ("Modify Course/Community")', + crs => 'set in Course ("Course Configuration")', + comm => 'set in Community ("Community Configuration")', ); $resulttext = &mt('Changes made:').'<ul>'; if ($changes{'togglecats'}) { @@ -4853,6 +6263,12 @@ sub modify_coursecategories { if ($changes{'categorize'}) { $resulttext .= '<li>'.&mt("$title{'categorize'} $level{$env{'form.categorize'}}").'</li>'; } + if ($changes{'togglecatscomm'}) { + $resulttext .= '<li>'.&mt("$title{'togglecatscomm'} $level{$env{'form.togglecatscomm'}}").'</li>'; + } + if ($changes{'categorizecomm'}) { + $resulttext .= '<li>'.&mt("$title{'categorizecomm'} $level{$env{'form.categorizecomm'}}").'</li>'; + } if ((keys(%deletions) > 0) || (keys(%reorderings) > 0) || (keys(%adds) > 0)) { my $cathash; if (ref($domconfig{'coursecategories'}) eq 'HASH') { @@ -4902,7 +6318,7 @@ sub modify_coursecategories { &mt('An error occurred: [_1]',$putresult).'</span>'; } } else { - $resulttext = &mt('No changes made to course categories'); + $resulttext = &mt('No changes made to course and community categories'); } return $resulttext; } @@ -4959,58 +6375,57 @@ sub modify_serverstatuses { my %serverstatushash = ( serverstatuses => \%newserverstatus, ); - my $putresult = &Apache::lonnet::put_dom('configuration',\%serverstatushash, - $dom); my %changes; foreach my $type (@pages) { - if (ref($currserverstatus{$type}) eq 'HASH') { - my @currnamed = split(/,/,$currserverstatus{$type}{'namedusers'}); - my @newusers = split(/,/,$newserverstatus{$type}{'namedusers'}); - foreach my $item (@currnamed) { - if (!grep(/^\Q$item\E$/,@newusers)) { - $changes{$type}{'namedusers'} = 1; - last; - } - } - foreach my $item (@newusers) { - if (!grep(/^\Q$item\E$/,@currnamed)) { - $changes{$type}{'namedusers'} = 1; - last; - } - } - my @currmachines = split(/,/,$currserverstatus{$type}{'machines'}); - my @newmachines = split(/,/,$newserverstatus{$type}{'machines'}); - foreach my $item (@currmachines) { - if (!grep(/^\Q$item\E$/,@newmachines)) { - $changes{$type}{'machines'} = 1; - last; - } - } - foreach my $item (@newmachines) { - if (!grep(/^\Q$item\E$/,@currmachines)) { - $changes{$type}{'machines'} = 1; - last; + foreach my $setting ('namedusers','machines') { + my (@current,@new); + if (ref($currserverstatus{$type}) eq 'HASH') { + if ($currserverstatus{$type}{$setting} ne '') { + @current = split(/,/,$currserverstatus{$type}{$setting}); } } - + if ($newserverstatus{$type}{$setting} ne '') { + @new = split(/,/,$newserverstatus{$type}{$setting}); + } + if (@current > 0) { + if (@new > 0) { + foreach my $item (@current) { + if (!grep(/^\Q$item\E$/,@new)) { + $changes{$type}{$setting} = 1; + last; + } + } + foreach my $item (@new) { + if (!grep(/^\Q$item\E$/,@current)) { + $changes{$type}{$setting} = 1; + last; + } + } + } else { + $changes{$type}{$setting} = 1; + } + } elsif (@new > 0) { + $changes{$type}{$setting} = 1; + } } } if (keys(%changes) > 0) { - my $titles= &LONCAPA::loncgi::serverstatus_titles(); + my $titles= &LONCAPA::lonauthcgi::serverstatus_titles(); my $putresult = &Apache::lonnet::put_dom('configuration', \%serverstatushash,$dom); if ($putresult eq 'ok') { $resulttext .= &mt('Changes made:').'<ul>'; foreach my $type (@pages) { - if (defined($changes{$type})) { + if (ref($changes{$type}) eq 'HASH') { $resulttext .= '<li>'.$titles->{$type}.'<ul>'; - if (defined($changes{$type}{'namedusers'})) { + if ($changes{$type}{'namedusers'}) { if ($newserverstatus{$type}{'namedusers'} eq '') { $resulttext .= '<li>'.&mt("Access terminated for all specific (named) users").'</li>'."\n"; } else { $resulttext .= '<li>'.&mt("Access available for the following specified users: ").$newserverstatus{$type}{'namedusers'}.'</li>'."\n"; } - } elsif (defined($changes{$type}{'machines'})) { + } + if ($changes{$type}{'machines'}) { if ($newserverstatus{$type}{'machines'} eq '') { $resulttext .= '<li>'.&mt("Access terminated for all specific IP addresses").'</li>'."\n"; } else { @@ -5033,6 +6448,351 @@ sub modify_serverstatuses { return $resulttext; } +sub modify_helpsettings { + my ($r,$dom,$confname,%domconfig) = @_; + my ($resulttext,$errors,%changes,%helphash); + + my $customhelpfile = $env{'form.loginhelpurl.filename'}; + my $defaulthelpfile = 'defaulthelp.html'; + my $servadm = $r->dir_config('lonAdmEMail'); + my ($configuserok,$author_ok,$switchserver) = + &config_check($dom,$confname,$servadm); + + my %defaultchecked = ('submitbugs' => 'on'); + my @offon = ('off','on'); + my %title = ( submitbugs => 'Display link for users to submit a bug', + loginhelpurl => 'Unauthenticated login help page set to custom file'); + + my @toggles = ('submitbugs'); + + $helphash{'helpsettings'} = {}; + + if (ref($domconfig{'helpsettings'}) ne 'HASH') { + if ($domconfig{'helpsettings'} eq '') { + $domconfig{'helpsettings'} = {}; + } + } + + if (ref($domconfig{'helpsettings'}) eq 'HASH') { + + foreach my $item (@toggles) { + + if ($defaultchecked{$item} eq 'on') { + if (($domconfig{'helpsettings'}{$item} eq '') && + ($env{'form.'.$item} eq '0')) { + $changes{$item} = 1; + } elsif ($domconfig{'helpsettings'}{$item} ne $env{'form.'.$item}) { + $changes{$item} = 1; + } + } elsif ($defaultchecked{$item} eq 'off') { + if (($domconfig{'helpsettings'}{$item} eq '') && + ($env{'form.'.$item} eq '1')) { + $changes{$item} = 1; + } elsif ($domconfig{'helpsettings'}{$item} ne $env{'form.'.$item}) { + $changes{$item} = 1; + } + } + $helphash{'helpsettings'}{$item} = $env{'form.'.$item}; + } + + if ($customhelpfile ne '') { + my $error; + if ($configuserok eq 'ok') { + if ($switchserver) { + $error = &mt("Upload of custom help file is not permitted to this server: [_1]",$switchserver); + } else { + if ($author_ok eq 'ok') { + my ($result,$loginhelpurl) = + &publishlogo($r,'upload','loginhelpurl',$dom, + $confname,'help','','',$customhelpfile); + if ($result eq 'ok') { + $helphash{'helpsettings'}{'loginhelpurl'} = $loginhelpurl; + $changes{'loginhelpurl'} = 1; + } else { + $error = &mt("Upload of [_1] failed because an error occurred publishing the file in RES space. Error was: [_2].",$customhelpfile,$result); + } + } else { + $error = &mt("Upload of [_1] failed because an author role could not be assigned to a Domain Configuration user ([_2]) in domain: [_3]. Error was: [_4].",$customhelpfile,$confname,$dom,$author_ok); + } + } + } else { + $error = &mt("Upload of [_1] failed because a Domain Configuration user ([_2]) could not be created in domain: [_3]. Error was: [_4].",$customhelpfile,$confname,$dom,$configuserok); + } + if ($error) { + &Apache::lonnet::logthis($error); + $errors .= '<li><span class="LC_error">'.$error.'</span></li>'; + } + } + + if ($domconfig{'helpsettings'}{'loginhelpurl'} ne '') { + if ($env{'form.loginhelpurl_del'}) { + $helphash{'helpsettings'}{'loginhelpurl'} = ''; + $changes{'loginhelpurl'} = 1; + } + } + } + + + my $putresult; + + if (keys(%changes) > 0) { + $putresult = &Apache::lonnet::put_dom('configuration',\%helphash,$dom); + } else { + $putresult = 'ok'; + } + + if ($putresult eq 'ok') { + if (keys(%changes) > 0) { + $resulttext = &mt('Changes made:').'<ul>'; + foreach my $item (sort(keys(%changes))) { + if ($item eq 'submitbugs') { + $resulttext .= '<li>'.&mt("$title{$item} set to $offon[$env{'form.'.$item}]").'</li>'; + } + if ($item eq 'loginhelpurl') { + if ($helphash{'helpsettings'}{'loginhelpurl'} eq '') { + $resulttext .= '<li>'.&mt('[_1] help file removed; [_2] file will be used for the unathorized help page in this domain.',$customhelpfile,$defaulthelpfile).'</li>'; + } else { + $resulttext .= '<li>'.&mt("$title{$item} [_1]",$customhelpfile).'</li>'; + } + } + } + $resulttext .= '</ul>'; + } else { + $resulttext = &mt('No changes made to help settings'); + } + } else { + $resulttext = '<span class="LC_error">'. + &mt('An error occurred: [_1]',$putresult).'</span>'; + } + if ($errors) { + $resulttext .= &mt('The following errors occurred: ').'<ul>'. + $errors.'</ul>'; + } + return $resulttext; +} + +sub modify_coursedefaults { + my ($dom,%domconfig) = @_; + my ($resulttext,$errors,%changes,%defaultshash); + my %defaultchecked = ('canuse_pdfforms' => 'off'); + my @offon = ('off','on'); + my @toggles = ('canuse_pdfforms'); + + $defaultshash{'coursedefaults'} = {}; + + if (ref($domconfig{'coursedefaults'}) ne 'HASH') { + if ($domconfig{'coursedefaults'} eq '') { + $domconfig{'coursedefaults'} = {}; + } + } + + if (ref($domconfig{'coursedefaults'}) eq 'HASH') { + foreach my $item (@toggles) { + if ($defaultchecked{$item} eq 'on') { + if (($domconfig{'coursedefaults'}{$item} eq '') && + ($env{'form.'.$item} eq '0')) { + $changes{$item} = 1; + } elsif ($domconfig{'coursdefaults'}{$item} ne $env{'form.'.$item}) { + $changes{$item} = 1; + } + } elsif ($defaultchecked{$item} eq 'off') { + if (($domconfig{'coursedefaults'}{$item} eq '') && + ($env{'form.'.$item} eq '1')) { + $changes{$item} = 1; + } elsif ($domconfig{'coursedefaults'}{$item} ne $env{'form.'.$item}) { + $changes{$item} = 1; + } + } + $defaultshash{'coursedefaults'}{$item} = $env{'form.'.$item}; + } + } + my $putresult = &Apache::lonnet::put_dom('configuration',\%defaultshash, + $dom); + if ($putresult eq 'ok') { + if (keys(%changes) > 0) { + if ($changes{'canuse_pdfforms'}) { + my %domdefaults = &Apache::lonnet::get_domain_defaults($dom); + $domdefaults{'canuse_pdfforms'}=$defaultshash{'coursedefaults'}{'canuse_pdfforms'}; + my $cachetime = 24*60*60; + &Apache::lonnet::do_cache_new('domdefaults',$dom,\%domdefaults,$cachetime); + } + $resulttext = &mt('Changes made:').'<ul>'; + foreach my $item (sort(keys(%changes))) { + if ($item eq 'canuse_pdfforms') { + if ($env{'form.'.$item} eq '1') { + $resulttext .= '<li>'.&mt("Course/Community users can create/upload PDF forms set to 'on'").'</li>'; + } else { + $resulttext .= '<li>'.&mt('Course/Community users can create/upload PDF forms set to "off"').'</li>'; + } + } + } + $resulttext .= '</ul>'; + } else { + $resulttext = &mt('No changes made to course defaults'); + } + } else { + $resulttext = '<span class="LC_error">'. + &mt('An error occurred: [_1]',$putresult).'</span>'; + } + return $resulttext; +} + +sub modify_usersessions { + my ($dom,%domconfig) = @_; + my @types = ('version','excludedomain','includedomain'); + my @prefixes = ('remote','hosted'); + my @lcversions = &Apache::lonnet::all_loncaparevs(); + my (%defaultshash,%changes); + foreach my $prefix (@prefixes) { + $defaultshash{'usersessions'}{$prefix} = {}; + } + my %domdefaults = &Apache::lonnet::get_domain_defaults($dom); + my $resulttext; + foreach my $prefix (@prefixes) { + foreach my $type (@types) { + my $inuse = $env{'form.'.$prefix.'_'.$type.'_inuse'}; + if ($type eq 'version') { + my $value = $env{'form.'.$prefix.'_'.$type}; + my $okvalue; + if ($value ne '') { + if (grep(/^\Q$value\E$/,@lcversions)) { + $okvalue = $value; + } + } + if (ref($domconfig{'usersessions'}) eq 'HASH') { + if (ref($domconfig{'usersessions'}{$prefix}) eq 'HASH') { + if ($domconfig{'usersessions'}{$prefix}{$type} ne '') { + if ($inuse == 0) { + $changes{$prefix}{$type} = 1; + } else { + if ($okvalue ne $domconfig{'usersessions'}{$prefix}{$type}) { + $changes{$prefix}{$type} = 1; + } + if ($okvalue ne '') { + $defaultshash{'usersessions'}{$prefix}{$type} = $okvalue; + } + } + } else { + if (($inuse == 1) && ($okvalue ne '')) { + $defaultshash{'usersessions'}{$prefix}{$type} = $okvalue; + $changes{$prefix}{$type} = 1; + } + } + } else { + if (($inuse == 1) && ($okvalue ne '')) { + $defaultshash{'usersessions'}{$prefix}{$type} = $okvalue; + $changes{$prefix}{$type} = 1; + } + } + } else { + if (($inuse == 1) && ($okvalue ne '')) { + $defaultshash{'usersessions'}{$prefix}{$type} = $okvalue; + $changes{$prefix}{$type} = 1; + } + } + } else { + my @vals = &Apache::loncommon::get_env_multiple('form.'.$prefix.'_'.$type); + my @okvals; + foreach my $val (@vals) { + if (&Apache::lonnet::domain($val) ne '') { + push(@okvals,$val); + } + } + @okvals = sort(@okvals); + if (ref($domconfig{'usersessions'}) eq 'HASH') { + if (ref($domconfig{'usersessions'}{$prefix}) eq 'HASH') { + if (ref($domconfig{'usersessions'}{$prefix}{$type}) eq 'ARRAY') { + if ($inuse == 0) { + $changes{$prefix}{$type} = 1; + } else { + $defaultshash{'usersessions'}{$prefix}{$type} = \@okvals; + my @changed = &Apache::loncommon::compare_arrays($domconfig{'usersessions'}{$prefix}{$type},$defaultshash{'usersessions'}{$prefix}{$type}); + if (@changed > 0) { + $changes{$prefix}{$type} = 1; + } + } + } else { + if ($inuse == 1) { + $defaultshash{'usersessions'}{$prefix}{$type} = \@okvals; + $changes{$prefix}{$type} = 1; + } + } + } else { + if ($inuse == 1) { + $defaultshash{'usersessions'}{$prefix}{$type} = \@okvals; + $changes{$prefix}{$type} = 1; + } + } + } else { + if ($inuse == 1) { + $defaultshash{'usersessions'}{$prefix}{$type} = \@okvals; + $changes{$prefix}{$type} = 1; + } + } + } + } + } + if (keys(%changes) > 0) { + my $putresult = &Apache::lonnet::put_dom('configuration',\%defaultshash, + $dom); + if ($putresult eq 'ok') { + if (ref($defaultshash{'usersessions'}) eq 'HASH') { + if (ref($defaultshash{'usersessions'}{'remote'}) eq 'HASH') { + $domdefaults{'remotesessions'} = $defaultshash{'usersessions'}{'remote'}; + } + if (ref($defaultshash{'usersessions'}{'hosted'}) eq 'HASH') { + $domdefaults{'hostedsessions'} = $defaultshash{'usersessions'}{'hosted'}; + } + } + my $cachetime = 24*60*60; + &Apache::lonnet::do_cache_new('domdefaults',$dom,\%domdefaults,$cachetime); + my %lt = &usersession_titles(); + $resulttext = &mt('Changes made:').'<ul>'; + foreach my $prefix (@prefixes) { + if (ref($changes{$prefix}) eq 'HASH') { + $resulttext .= '<li>'.$lt{$prefix}.'<ul>'; + foreach my $type (@types) { + if (defined($changes{$prefix}{$type})) { + my $newvalue; + if (ref($defaultshash{'usersessions'}) eq 'HASH') { + if (ref($defaultshash{'usersessions'}{$prefix})) { + if ($type eq 'version') { + $newvalue = $defaultshash{'usersessions'}{$prefix}{$type}; + } elsif (ref($defaultshash{'usersessions'}{$prefix}{$type}) eq 'ARRAY') { + if (@{$defaultshash{'usersessions'}{$prefix}{$type}} > 0) { + $newvalue = join(', ',@{$defaultshash{'usersessions'}{$prefix}{$type}}); + } + } + } + } + if ($newvalue eq '') { + if ($type eq 'version') { + $resulttext .= '<li>'.&mt('[_1] set to: off',$lt{$type}).'</li>'; + } else { + $resulttext .= '<li>'.&mt('[_1] set to: none',$lt{$type}).'</li>'; + } + } else { + if ($type eq 'version') { + $newvalue .= ' '.&mt('(or later)'); + } + $resulttext .= '<li>'.&mt('[_1] set to: [_2].',$lt{$type},$newvalue).'</li>'; + } + } + } + $resulttext .= '</ul>'; + } + } + $resulttext .= '</ul>'; + } else { + $resulttext = '<span class="LC_error">'. + &mt('An error occurred: [_1]',$putresult).'</span>'; + } + } else { + $resulttext = &mt('No changes made to settings for user session hosting.'); + } + return $resulttext; +} + sub recurse_check { my ($chkcats,$categories,$depth,$name) = @_; if (ref($chkcats->[$depth]{$name}) eq 'ARRAY') { @@ -5073,4 +6833,118 @@ sub recurse_cat_deletes { return; } +sub dom_servers { + my ($dom) = @_; + my (%uniqservers,%servers); + my $primaryserver = &Apache::lonnet::hostname(&Apache::lonnet::domain($dom,'primary')); + my @machinedoms = &Apache::lonnet::machine_domains($primaryserver); + foreach my $mdom (@machinedoms) { + my %currservers = %servers; + my %server = &Apache::lonnet::get_servers($mdom); + %servers = (%currservers,%server); + } + my %by_hostname; + foreach my $id (keys(%servers)) { + push(@{$by_hostname{$servers{$id}}},$id); + } + foreach my $hostname (sort(keys(%by_hostname))) { + if (@{$by_hostname{$hostname}} > 1) { + my $match = 0; + foreach my $id (@{$by_hostname{$hostname}}) { + if (&Apache::lonnet::host_domain($id) eq $dom) { + $uniqservers{$id} = $hostname; + $match = 1; + } + } + unless ($match) { + $uniqservers{$by_hostname{$hostname}[0]} = $hostname; + } + } else { + $uniqservers{$by_hostname{$hostname}[0]} = $hostname; + } + } + return %uniqservers; +} + +sub get_active_dcs { + my ($dom) = @_; + my %dompersonnel = &Apache::lonnet::get_domain_roles($dom,['dc']); + my %domcoords; + my $numdcs = 0; + my $now = time; + foreach my $server (keys(%dompersonnel)) { + foreach my $user (sort(keys(%{$dompersonnel{$server}}))) { + my ($trole,$uname,$udom,$runame,$rudom,$rsec) = split(/:/,$user); + my ($end,$start) = split(':',$dompersonnel{$server}{$user}); + if (($end eq '') || ($end == 0) || ($end > $now)) { + if ($start <= $now) { + $domcoords{$uname.':'.$udom} = $dompersonnel{$server}{$user}; + } + } + } + } + return %domcoords; +} + +sub active_dc_picker { + my ($dom,$curr_dc) = @_; + my %domcoords = &get_active_dcs($dom); + my @dcs = sort(keys(%domcoords)); + my $numdcs = scalar(@dcs); + my $datatable; + my $numinrow = 2; + if ($numdcs > 1) { + $datatable = '<table>'; + for (my $i=0; $i<@dcs; $i++) { + my $rem = $i%($numinrow); + if ($rem == 0) { + if ($i > 0) { + $datatable .= '</tr>'; + } + $datatable .= '<tr>'; + } + my $check = ' '; + if ($curr_dc eq '') { + if (!$i) { + $check = ' checked="checked" '; + } + } elsif ($dcs[$i] eq $curr_dc) { + $check = ' checked="checked" '; + } + if ($i == @dcs - 1) { + my $colsleft = $numinrow - $rem; + if ($colsleft > 1) { + $datatable .= '<td colspan="'.$colsleft.'">'; + } else { + $datatable .= '<td>'; + } + } else { + $datatable .= '<td>'; + } + my ($dcname,$dcdom) = split(':',$dcs[$i]); + $datatable .= '<span class="LC_nobreak"><label>'. + '<input type="radio" name="autocreate_xmldc"'. + ' value="'.$dcs[$i].'"'.$check.'/>'. + &Apache::loncommon::plainname($dcname,$dcdom). + '</label></span></td>'; + } + $datatable .= '</tr></table>'; + } elsif (@dcs) { + $datatable .= '<input type="hidden" name="autocreate_dc" value="'. + $dcs[0].'" />'; + } + return ($numdcs,$datatable); +} + +sub usersession_titles { + return &Apache::lonlocal::texthash( + hosted => 'Hosting of sessions for users from other domains on servers in this domain', + + remote => 'Hosting of sessions for users in this domain on servers in other domains', + version => 'LON-CAPA version requirement', + excludedomain => 'Specific domains excluded', + includedomain => 'Specific domains included', + ); +} + 1;