--- loncom/interface/domainprefs.pm 2007/11/10 03:51:46 1.32 +++ loncom/interface/domainprefs.pm 2009/09/23 02:41:24 1.102.4.2 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # Handler to set domain-wide configuration settings # -# $Id: domainprefs.pm,v 1.32 2007/11/10 03:51:46 raeburn Exp $ +# $Id: domainprefs.pm,v 1.102.4.2 2009/09/23 02:41:24 gci 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; @@ -36,9 +161,15 @@ use Apache::lonnet; use Apache::loncommon(); use Apache::lonhtmlcommon(); use Apache::lonlocal; -use LONCAPA(); +use Apache::lonmsg(); +use Apache::lonconfigsettings; +use LONCAPA qw(:DEFAULT :match); use LONCAPA::Enrollment; +use LONCAPA::lonauthcgi(); use File::Copy; +use Locale::Language; +use DateTime::TimeZone; +use DateTime::Locale; sub handler { my $r=shift; @@ -48,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)) { @@ -60,7 +192,7 @@ sub handler { } &Apache::lonhtmlcommon::clear_breadcrumbs(); &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'}, - ['phase']); + ['phase','actions']); my $phase = 'pickactions'; if ( exists($env{'form.phase'}) ) { $phase = $env{'form.phase'}; @@ -68,14 +200,17 @@ sub handler { my %domconfig = &Apache::lonnet::get_dom('configuration',['login','rolecolors', 'quotas','autoenroll','autoupdate','directorysrch', - 'usercreation','contacts'],$dom); - my @prefs_order = ('rolecolors','login','quotas','autoenroll', + 'usercreation','usermodification','contacts','defaults', + 'scantron','coursecategories','serverstatuses', + 'requestcourses'],$dom); + my @prefs_order = ('rolecolors','login','defaults','quotas','autoenroll', 'autoupdate','directorysrch','contacts', - 'usercreation'); + 'usercreation','usermodification','scantron', + 'requestcourses','coursecategories','serverstatuses'); my %prefs = ( 'rolecolors' => { text => 'Default color schemes', - help => 'Default_Color_Schemes', + help => 'Domain_Configuration_Color_Schemes', header => [{col1 => 'Student Settings', col2 => '',}, {col1 => 'Coordinator Settings', @@ -87,51 +222,102 @@ sub handler { }, 'login' => { text => 'Log-in page options', - help => 'Domain_Log-in_Page', + help => 'Domain_Configuration_Login_Page', header => [{col1 => 'Item', col2 => '',}], }, + 'defaults' => + { text => 'Default authentication/language/timezone', + help => 'Domain_Configuration_LangTZAuth', + header => [{col1 => 'Setting', + col2 => 'Value'}], + }, 'quotas' => - { text => 'Default quotas for user portfolios', - help => 'Default_User_Quota', - header => [{col1 => 'User type', - col2 => 'Default quota'}], + { text => 'User blogs, personal information pages and portfolios', + help => 'Domain_Configuration_Quotas', + header => [{col1 => 'User affiliation', + col2 => 'Available tools', + col3 => 'Portfolio quota',}], }, 'autoenroll' => { text => 'Auto-enrollment settings', - help => 'Domain_Auto_Enrollment', + help => 'Domain_Configuration_Auto_Enrollment', header => [{col1 => 'Configuration setting', col2 => 'Value(s)'}], }, 'autoupdate' => { text => 'Auto-update settings', - help => 'Domain_Auto_Update', + help => 'Domain_Configuration_Auto_Updates', header => [{col1 => 'Setting', col2 => 'Value',}, - {col1 => 'User Population', + {col1 => 'User population', col2 => 'Updataeable user data'}], }, 'directorysrch' => { text => 'Institutional directory searches', - help => 'Domain_Directory_Search', + help => 'Domain_Configuration_InstDirectory_Search', header => [{col1 => 'Setting', col2 => 'Value',}], }, 'contacts' => { text => 'Contact Information', - help => 'Domain_Contact_Information', + help => 'Domain_Configuration_Contact_Info', header => [{col1 => 'Setting', col2 => 'Value',}], }, 'usercreation' => { text => 'User creation', - help => 'Domain_User_Creation', - header => [{col1 => 'Setting', - col2 => 'Value',}, + help => 'Domain_Configuration_User_Creation', + header => [{col1 => 'Format rule type', + col2 => 'Format rules in force'}, + {col1 => 'User account creation', + col2 => 'Usernames which may be created',}, {col1 => 'Context', - col2 => 'Assignable Authentication Types'}], + col2 => 'Assignable authentication types'}], + }, + 'usermodification' => + { text => 'User modification', + help => 'Domain_Configuration_User_Modification', + header => [{col1 => 'Target user has role', + col2 => 'User information updateable in author context'}, + {col1 => 'Target user has role', + col2 => 'User information updateable in course context'}, + {col1 => "Status of user", + col2 => 'Information settable when self-creating account (if directory data blank)'}], + }, + 'scantron' => + { 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', + help => 'Domain_Configuration_Cataloging_Courses', + header => [{col1 => 'Category settings', + col2 => '',}, + {col1 => 'Categories', + col2 => '', + }], + }, + 'serverstatuses' => + {text => 'Access to server status pages', + help => 'Domain_Configuration_Server_Status', + header => [{col1 => 'Status Page', + col2 => 'Other named users', + col3 => 'Specific IPs', + }], + }, ); my @roles = ('student','coordinator','author','admin'); my @actions = &Apache::loncommon::get_env_multiple('form.actions'); @@ -140,104 +326,16 @@ sub handler { text=>"Pick functionality"}); 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('

'.&mt($prefs{$item}{'text'}).'

'. - &process_changes($r,$dom,$confname,$item, - \@roles,%domconfig)); - } - } - $r->print('

'); - &print_footer($r,$phase,'display','Back to configuration display', - \@actions); - $r->print('

'); + &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('

'); - for (my $i=0; $i<$colend; $i++) { - $r->print($output{$items[$i]}); - } - $r->print(''); - if ($colend < @items) { - for (my $i=$colend; $i<@items; $i++) { - $r->print($output{$items[$i]}); - } - } - $r->print('

'); - $r->print(&print_footer($r,$phase,'process','Save',\@actions)); - } else { - $r->print(''. - ''."\n". - ''.&mt('No settings chosen'). - ''); - } - $r->print(''); - $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(); if (!grep(/^\Q$primarylibserv\E$/,@ids)) { my %designhash = &Apache::loncommon::get_domainconf($dom); - my @loginimages = ('img','logo','domlogo'); + my @loginimages = ('img','logo','domlogo','login'); my $custom_img_count = 0; foreach my $img (@loginimages) { if ($designhash{$dom.'.login.'.$img} ne '') { @@ -250,6 +348,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.').'
'. @@ -259,37 +358,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('

'.&mt('Functionality to display/modify').'

'); - $r->print(''."\n".'

  '. - '

'); - foreach my $item (@prefs_order) { - $r->print('

'); - } - $r->print('

'.&mt('Display options').'

'."\n". - '

'.&mt('Display using: ')."\n". - '  '. - ''. - &mt('two columns').'

'); - $r->print(&print_footer($r,$phase,'display','Go')); - $r->print(''); - $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); @@ -297,7 +381,7 @@ 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') { @@ -306,8 +390,20 @@ sub process_changes { $output = &modify_directorysrch($dom,%domconfig); } elsif ($action eq 'usercreation') { $output = &modify_usercreation($dom,%domconfig); + } elsif ($action eq 'usermodification') { + $output = &modify_usermodification($dom,%domconfig); } elsif ($action eq 'contacts') { $output = &modify_contacts($dom,%domconfig); + } elsif ($action eq 'defaults') { + $output = &modify_defaults($dom,$r); + } elsif ($action eq 'scantron') { + $output = &modify_scantron($r,$dom,$confname,%domconfig); + } elsif ($action eq 'coursecategories') { + $output = &modify_coursecategories($dom,%domconfig); + } elsif ($action eq 'serverstatuses') { + $output = &modify_serverstatuses($dom,%domconfig); + } elsif ($action eq 'requestcourses') { + $output = &modify_quotas($dom,$action,%domconfig); } return $output; } @@ -315,33 +411,44 @@ sub process_changes { sub print_config_box { my ($r,$dom,$confname,$phase,$action,$item,$settings) = @_; my $rowtotal = 0; - my $output = + my $output; + if ($action eq 'coursecategories') { + $output = &coursecategories_javascript($settings); + } + $output .= ' - '; -# -# FIXME - put the help link back in when the help files exist -# -# '); + '."\n". + ''; $rowtotal ++; if (($action eq 'autoupdate') || ($action eq 'rolecolors') || - ($action eq 'usercreation')) { - my $colspan = ($action eq 'rolecolors')?' colspan="2"':''; + ($action eq 'usercreation') || ($action eq 'usermodification') || + ($action eq 'coursecategories') || ($action eq 'requestcourses')) { + my $colspan = ''; + if (($action eq 'rolecolors') || ($action eq 'coursecategories')) { + $colspan = ' colspan="2"'; + } $output .= ' '; $itemcount ++; @@ -888,78 +1005,523 @@ sub display_color_options { return $datatable; } -sub color_pick { - my ($phase,$role,$item,$desc,$curcol) = @_; - my $link = ''.$desc.''; - return $link; +sub logo_display_options { + my ($img,$defaults,$designs) = @_; + my $checkedon; + if (ref($defaults) eq 'HASH') { + if (ref($defaults->{'showlogo'}) eq 'HASH') { + if ($defaults->{'showlogo'}{$img}) { + $checkedon = 'checked="checked" '; + } + } + } + if (ref($designs) eq 'HASH') { + if (ref($designs->{'showlogo'}) eq 'HASH') { + if (defined($designs->{'showlogo'}{$img})) { + if ($designs->{'showlogo'}{$img} == 0) { + $checkedon = ''; + } elsif ($designs->{'showlogo'}{$img} == 1) { + $checkedon = 'checked="checked" '; + } + } + } + } + return '
'."\n"; +} + +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 = '   '. + '
'."\n"; + if ((!$is_custom->{'textcol'}) || (!$is_custom->{'bgcol'})) { + $output .= &mt('Text default(s)').':
'; + if (!$is_custom->{'textcol'}) { + $output .= $choices->{'textcol'}.': '.$defaults->{'logintext'}{'textcol'}. + '   '; + } + if (!$is_custom->{'bgcol'}) { + $output .= $choices->{'bgcol'}.': '. + '   '; + } + $output .= '
'; + } + $output .='
'; + return $output; } -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(); +sub login_text_colors { + my ($img,$role,$logintext,$phase,$choices,$designs) = @_; + my $color_menu = '
'.&mt($item->{text}). - ' 
'.&mt($item->{text}).' '. -# &Apache::loncommon::help_open_topic($item->{'help'}).'
'. + &mt($item->{text}).' '. + &Apache::loncommon::help_open_topic($item->{'help'}).'
- - + + '; - $rowtotal ++; + $rowtotal ++; if ($action eq 'autoupdate') { $output .= &print_autoupdate('top',$dom,$settings,\$rowtotal); } elsif ($action eq 'usercreation') { - $output .= &print_usercreation('top',$dom,$settings,\$rowtotal); + $output .= &print_usercreation('top',$dom,$settings,\$rowtotal); + } elsif ($action eq 'usermodification') { + $output .= &print_usermodification('top',$dom,$settings,\$rowtotal); + } elsif ($action eq 'coursecategories') { + $output .= &print_coursecategories('top',$dom,$item,$settings,\$rowtotal); + } elsif ($action eq 'requestcourses') { + $output .= &print_quotas($dom,$settings,\$rowtotal,$action); } else { $output .= &print_rolecolors($phase,'student',$dom,$confname,$settings,\$rowtotal); } @@ -353,14 +460,44 @@ sub print_config_box { + + + + + + '; return $datatable; } @@ -637,15 +730,19 @@ sub login_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 => "Page", - mainbg => "Main panel", - sidebg => "Side panel", + pgbg => "Header", + mainbg => "Page", + sidebg => "Login box", link => "Link", alink => "Active link", vlink => "Visited link", @@ -727,7 +824,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) = @_; + $images,$bgs,$links,$alt_text,$rowtotal,$logintext,$loginheader) = @_; my $css_class = $itemcount%2?' class="LC_odd_row"':''; my $datatable = ''. ''; @@ -748,8 +845,21 @@ sub display_color_options { $itemcount ++; $css_class = $itemcount%2?' class="LC_odd_row"':''; $datatable .= ''. - ''; - my ($imgfile, $img_import); + ''; if ($designs->{$img} ne '') { $imgfile = $designs->{$img}; $img_import = ($imgfile =~ m{^/adm/}); @@ -796,25 +906,32 @@ sub display_color_options { } } if ($showfile) { - $showfile = &Apache::loncommon::lonhttpdurl($showfile); - $fullsize = &Apache::loncommon::lonhttpdurl($imgfile); - $datatable.= ''; - if ($is_custom->{$img}) { - $datatable.=''; + $bgs_def .= ''; } } if ($bgs_def) { @@ -854,7 +971,7 @@ sub display_color_options { $datatable .= '    '; } $datatable .= '
'; + '" onblur = "javascript:colchg_span('."'css_".$role.'_'.$item."'".',this);" />'; } $datatable .= '
'.$item->{'header'}->[0]->{'col1'}.''.$item->{'header'}->[0]->{'col2'}.''.&mt($item->{'header'}->[0]->{'col1'}).''.&mt($item->{'header'}->[0]->{'col2'}).'
- - + '; + $output .= ' + '; $rowtotal ++; if ($action eq 'autoupdate') { $output .= &print_autoupdate('bottom',$dom,$settings,\$rowtotal); } elsif ($action eq 'usercreation') { - $output .= &print_usercreation('bottom',$dom,$settings,\$rowtotal); + $output .= &print_usercreation('middle',$dom,$settings,\$rowtotal).' +
'.$item->{'header'}->[1]->{'col1'}.''.$item->{'header'}->[1]->{'col2'}.''.&mt($item->{'header'}->[1]->{'col1'}).''.&mt($item->{'header'}->[1]->{'col2'}).'
+
+ + + + '. + &print_usercreation('bottom',$dom,$settings,\$rowtotal); + $rowtotal ++; + } elsif ($action eq 'usermodification') { + $output .= &print_usermodification('middle',$dom,$settings,\$rowtotal).' +
'.&mt($item->{'header'}->[2]->{'col1'}).''.&mt($item->{'header'}->[2]->{'col2'}).'
+
+ + + + '. + + &print_usermodification('bottom',$dom,$settings,\$rowtotal); + $rowtotal ++; + } elsif ($action eq 'coursecategories') { + $output .= &print_coursecategories('bottom',$dom,$item,$settings,\$rowtotal); + } elsif ($action eq 'requestcourses') { + $output .= &print_courserequestmail($dom,$settings,\$rowtotal); } else { $output .= &print_rolecolors($phase,'coordinator',$dom,$confname,$settings,\$rowtotal).'
'.&mt($item->{'header'}->[2]->{'col1'}).''.&mt($item->{'header'}->[2]->{'col2'}).'
@@ -370,8 +507,10 @@ sub print_config_box {
- - + + '. &print_rolecolors($phase,'author',$dom,$confname,$settings,\$rowtotal).'
'.$item->{'header'}->[2]->{'col1'}.''.$item->{'header'}->[2]->{'col2'}.''. + &mt($item->{'header'}->[2]->{'col1'}).''. + &mt($item->{'header'}->[2]->{'col2'}).'
@@ -381,8 +520,8 @@ sub print_config_box {
- - + + '. &print_rolecolors($phase,'admin',$dom,$confname,$settings,\$rowtotal); $rowtotal += 2; @@ -395,25 +534,53 @@ sub print_config_box { '; if (($action eq 'login') || ($action eq 'directorysrch')) { $output .= ' - '; + '; + } elsif ($action eq 'serverstatuses') { + $output .= ' + '; + } else { $output .= ' - '; + '; } - $output .= ' - - '; - $rowtotal ++; + if (defined($item->{'header'}->[0]->{'col3'})) { + $output .= ''; + if ($item->{'header'}->[0]->{'col3'}) { + $output .= ''; + } + $output .= ''; + $rowtotal ++; if ($action eq 'login') { $output .= &print_login($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 'directorysrch') { $output .= &print_directorysrch($dom,$settings,\$rowtotal); } elsif ($action eq 'contacts') { $output .= &print_contacts($dom,$settings,\$rowtotal); + } elsif ($action eq 'defaults') { + $output .= &print_defaults($dom,\$rowtotal); + } elsif ($action eq 'scantron') { + $output .= &print_scantronformat($r,$dom,$confname,$settings,\$rowtotal); + } elsif ($action eq 'serverstatuses') { + $output .= &print_serverstatuses($dom,$settings,\$rowtotal); } } $output .= ' @@ -424,114 +591,28 @@ 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 = ' - -'; - 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(' - - - - - -'); - $r->print(''); - return; -} - -sub print_footer { - my ($r,$phase,$newphase,$button_text,$actions) = @_; - $button_text = &mt($button_text); - $r->print(''. - ''. - ''); - if (($phase eq 'display') || ($phase eq 'process')) { - if (ref($actions) eq 'ARRAY') { - foreach my $item (@{$actions}) { - $r->print('')."\n"; - } - } - $r->print(''); - } - my $dest='"javascript:changePage(document.'.$phase.','."'$newphase'".')"'; - if ($phase eq 'process') { - $r->print('

'.$button_text.'

'); - } else { - my $onclick; - if ($phase eq 'display') { - $onclick = '"javascript:changePage(document.'.$phase.','."'$newphase'".')"'; - } else { - $onclick = '"javascript:changePage(document.'.$phase.','."'$newphase'".')"'; - } - $r->print('

'); - } - if ($phase eq 'process') { - $r->print(''.&Apache::loncommon::end_page()); - } - return; -} - sub print_login { my ($dom,$confname,$phase,$settings,$rowtotal) = @_; my %choices = &login_choices(); - my ($catalogon,$catalogoff,$adminmailon,$adminmailoff); - $catalogon = ' checked="checked" '; - $adminmailoff = ' checked="checked" '; - my @images = ('img','logo','domlogo'); + my %defaultchecked = ( + 'coursecatalog' => 'on', + 'adminmail' => 'off', + 'newuser' => 'off', + ); + my @toggles = ('coursecatalog','adminmail','newuser'); + my (%checkedon,%checkedoff); + 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} = ' '; + } + } + my $loginheader = 'image'; + my @images = ('img','logo','domlogo','login'); + my @logintext = ('textcol','bgcol'); my @bgs = ('pgbg','mainbg','sidebg'); my @links = ('link','alink','vlink'); my %designhash = &Apache::loncommon::get_domainconf($dom); @@ -542,27 +623,44 @@ sub print_login { ); foreach my $item (@images) { $defaults{$item} = $defaultdesign{'login.'.$item}; + $defaults{'showlogo'}{$item} = 1; } foreach my $item (@bgs) { $defaults{'bgs'}{$item} = $defaultdesign{'login.'.$item}; } + foreach my $item (@logintext) { + $defaults{'logintext'}{$item} = $defaultdesign{'login.'.$item}; + } foreach my $item (@links) { $defaults{'links'}{$item} = $defaultdesign{'login.'.$item}; } if (ref($settings) eq 'HASH') { - if ($settings->{'coursecatalog'} eq '0') { - $catalogoff = $catalogon; - $catalogon = ' '; - } - if ($settings->{'adminmail'} eq '1') { - $adminmailon = $adminmailoff; - $adminmailoff = ' '; + 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 (@images) { - if ($settings->{$item} ne '') { + if (defined($settings->{$item})) { $designs{$item} = $settings->{$item}; $is_custom{$item} = 1; } + if (defined($settings->{'showlogo'}{$item})) { + $designs{'showlogo'}{$item} = $settings->{'showlogo'}{$item}; + } + } + foreach my $item (@logintext) { + if ($settings->{$item} ne '') { + $designs{'logintext'}{$item} = $settings->{$item}; + $is_custom{$item} = 1; + } + } + if ($settings->{'loginheader'} ne '') { + $loginheader = $settings->{'loginheader'}; } if ($settings->{'font'} ne '') { $designs{'font'} = $settings->{'font'}; @@ -606,28 +704,23 @@ sub print_login { } my %alt_text = &Apache::lonlocal::texthash ( img => 'Log-in banner', logo => 'Institution Logo', - domlogo => 'Domain Logo'); + domlogo => 'Domain Logo', + login => 'Login box'); my $itemcount = 1; - my $css_class = $itemcount%2?' class="LC_odd_row"':''; - my $datatable = - ''. - ''; - $itemcount ++; - $css_class = $itemcount%2?' class="LC_odd_row"':''; - $datatable .= ''. - ''. - ''; - $itemcount ++; - $datatable .= &display_color_options($dom,$confname,$phase,'login',$itemcount,\%choices,\%is_custom,\%defaults,\%designs,\@images,\@bgs,\@links,\%alt_text,$rowtotal); + my ($css_class,$datatable); + foreach my $item (@toggles) { + $css_class = $itemcount%2?' class="LC_odd_row"':''; + $datatable .= + ''. + ''; + $itemcount ++; + } + $datatable .= &display_color_options($dom,$confname,$phase,'login',$itemcount,\%choices,\%is_custom,\%defaults,\%designs,\@images,\@bgs,\@links,\%alt_text,$rowtotal,\@logintext,$loginheader); $datatable .= '
'.$item->{'header'}->[3]->{'col1'}.''.$item->{'header'}->[3]->{'col2'}.''.&mt($item->{'header'}->[3]->{'col1'}).''.&mt($item->{'header'}->[3]->{'col2'}).'
'.$item->{'header'}->[0]->{'col1'}.''.&mt($item->{'header'}->[0]->{'col1'}).''.&mt($item->{'header'}->[0]->{'col1'}). + '
('.&mt('Automatic access for Dom. Coords.').')
'.$item->{'header'}->[0]->{'col1'}.''.&mt($item->{'header'}->[0]->{'col1'}).''.$item->{'header'}->[0]->{'col2'}.'
'. + &mt($item->{'header'}->[0]->{'col2'}); + if ($action eq 'serverstatuses') { + $output .= '
('.&mt('user1:domain1,user2:domain2 etc.').')'; + } + } else { + $output .= '
'. + &mt($item->{'header'}->[0]->{'col2'}); + } + $output .= ''. + &mt($item->{'header'}->[0]->{'col3'}); + if ($action eq 'serverstatuses') { + $output .= '
('.&mt('IP1,IP2 etc.').')'; + } + $output .= '
'.$choices{'coursecatalog'}. - ''. - ' '. - '
'.$choices{'adminmail'}.''. - ' '. - '
'.$choices{$item}. + ''. + ' 
'.$choices->{'font'}.''.$choices->{$img}.''.$choices->{$img}; + my ($imgfile,$img_import,$login_hdr_pick,$logincolors); + if ($role eq 'login') { + if ($img eq 'login') { + $login_hdr_pick = + &login_header_options($img,$role,$defaults,$is_custom,$choices, + $loginheader); + $logincolors = + &login_text_colors($img,$role,$logintext,$phase,$choices, + $designs); + } elsif ($img ne 'domlogo') { + $datatable.= &logo_display_options($img,$defaults,$designs); + } + } + $datatable .= ''; - if (!$is_custom->{$img}) { - $datatable .= &mt('Default in use:').'
'; - } - if ($img_import) { - $datatable.= ''; - } - $datatable.= ''.$alt_text->{$img}.
-                             '
 '.&mt('Replace:').'
'; - } else { - $datatable.='
'.&mt('Upload:').'
'; + if ($showfile =~ m{^/(adm|res)/}) { + if ($showfile =~ m{^/res/}) { + my $local_showfile = + &Apache::lonnet::filelocation('',$showfile); + &Apache::lonnet::repcopy($local_showfile); + } + $showfile = &Apache::loncommon::lonhttpdurl($showfile); + } + if ($imgfile) { + if ($imgfile =~ m{^/(adm|res)/}) { + if ($imgfile =~ m{^/res/}) { + my $local_imgfile = + &Apache::lonnet::filelocation('',$imgfile); + &Apache::lonnet::repcopy($local_imgfile); + } + $fullsize = &Apache::loncommon::lonhttpdurl($imgfile); + } else { + $fullsize = $imgfile; + } } + $datatable .= '
'; + if ($img eq 'login') { + $datatable .= $login_hdr_pick; + } + $datatable .= &image_changes($is_custom->{$img},$alt_text->{$img},$img_import, + $showfile,$fullsize,$role,$img,$imgfile,$logincolors); } else { $datatable .= '
'. &mt('Upload:'); @@ -837,7 +954,7 @@ sub display_color_options { my $bgs_def; foreach my $item (@{$bgs}) { if (!$is_custom->{$item}) { - $bgs_def .= '
'.$choices->{$item}.'    
'.$defaults->{'bgs'}{$item}.'
'.$choices->{$item}.'    
'.$defaults->{'bgs'}{$item}.'
'; + foreach my $item (@{$logintext}) { + my $link = &color_pick($phase,$role,$item,$choices->{$item},$designs->{'logintext'}{$item}); + $color_menu .= ''. + ''; } + $color_menu .= '
'.$link; + if ($designs->{'logintext'}{$item}) { + $color_menu .= '    '; + } + $color_menu .= '
 

'; + return $color_menu; +} - $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;'); - } +sub image_changes { + my ($is_custom,$alt_text,$img_import,$showfile,$fullsize,$role,$img,$imgfile,$logincolors) = @_; + my $output; + if (!$is_custom) { + if ($img ne 'domlogo') { + $output .= &mt('Default image:').'
'; } else { - document.parmform.pres_value.value=''; - document.parmform.pres_marker.value=''; + $output .= &mt('Default in use:').'
'; } } -ENDCOL + if ($img_import) { + $output .= ''; + } + $output .= ''.$alt_text.''; + if ($is_custom) { + $output .= ''.$logincolors.' '.&mt('Replace:').'
'; + } else { + $output .= ''.$logincolors.&mt('Upload:').'
'; + } return $output; } +sub color_pick { + my ($phase,$role,$item,$desc,$curcol) = @_; + my $link = ''.$desc.''; + return $link; +} + sub print_quotas { - my ($dom,$settings,$rowtotal) = @_; - my $datatable; - my ($othertitle,$usertypes,$types) = &sorted_inst_types($dom); + 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 ($css_class,%titles); + if ($context eq 'requestcourses') { + @usertools = ('official','unofficial','community'); + @options =('norequest','approval','autolimit','validate'); + %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; + 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 ++; $css_class = $typecount%2?' class="LC_odd_row"':''; - $datatable .= ''. + $datatable .= ''. ''.$usertypes->{$type}.''. + ''; + if ($context eq 'requestcourses') { + $datatable .= ''; + } + my %cell; + foreach my $item (@usertools) { + 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; + } + } + } + if (!$curroption) { + $curroption = 'norequest'; + } + $datatable .= ''; + 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} .= ' '; + if ($option eq 'autolimit') { + $cell{$item} .= ''; + } + if ($option eq 'autolimit') { + $cell{$item} .= $titles{'unlimited'}; + } + $cell{$item} .= '  '; + } + } 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 .= '  '; + } + } + if ($context eq 'requestcourses') { + $datatable .= ''; + foreach my $item (@usertools) { + $datatable .= ''; + } + $datatable .= '
'.$titles{$item}.'
'.$cell{$item}.'
'; + } + $datatable .= ''; + unless ($context eq 'requestcourses') { + $datatable .= ''. ' Mb'; + '" value="'.$currdefquota. + '" size="5" /> Mb'; + } + $datatable .= ''; } } } - my $defaultquota = '20'; - if (ref($settings) eq 'HASH') { - if (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 ++; $css_class = $typecount%2?' class="LC_odd_row"':''; $datatable .= ''. ''.$othertitle.''. - ''. - ' Mb'; + ''; + if ($context eq 'requestcourses') { + $datatable .= ''; + } + my %defcell; + foreach my $item (@usertools) { + 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 .= ''; + 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} .= ''; + if ($option eq 'autolimit') { + $defcell{$item} .= ''; + } + $defcell{$item} .= '  '; + 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 .= '  '; + } + } + if ($context eq 'requestcourses') { + $datatable .= ''; + foreach my $item (@usertools) { + $datatable .= ''; + } + $datatable .= '
'.$titles{$item}.'
'.$defcell{$item}.'
'; + } + $datatable .= ''; + unless ($context eq 'requestcourses') { + $datatable .= ''. + ' Mb'; + } + $datatable .= ''; + $typecount ++; + $css_class = $typecount%2?' class="LC_odd_row"':''; + $datatable .= ''. + ''.&mt('LON-CAPA Advanced Users').' '; + if ($context eq 'requestcourses') { + $datatable .= &mt('(overrides affiliation, if set)'). + ''. + ''. + ''; + } else { + $datatable .= &mt('(overrides affiliation, if checked)'). + ''. + ''; + my $checked = ''; + if ($curroption eq '') { + $checked = ' checked="checked"'; + } + $advcell{$item} .= '  '; + 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} .= ''; + if ($option eq 'autolimit') { + $advcell{$item} .= ''; + } + $advcell{$item} .= '  '; + 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 .= '  '; + } + } + if ($context eq 'requestcourses') { + $datatable .= ''; + foreach my $item (@usertools) { + $datatable .= ''; + } + $datatable .= '
'. + '
'; + } + my %advcell; + foreach my $item (@usertools) { + 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 .= '
'.$titles{$item}.'
'.$advcell{$item}.'
'; + } + $datatable .= ''; $$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 = ''. + ' '.&mt('Receive notification of course requests requiring approval.'). + ' '. + ' '; + if (@domcoord > 0) { + $datatable .= ''; + for (my $i=0; $i<$numdc; $i++) { + my $rem = $i%($numinrow); + if ($rem == 0) { + if ($i > 0) { + $datatable .= ''; + } + $datatable .= ''; + $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 .= ''; + } + $datatable .= '
'; + } else { + $datatable .= ''; + } + } else { + $datatable .= ''; + } + $datatable .= '
'; + } else { + $datatable .= &mt('There are no active Domain Coordinators'); + $rows ++; + } + $datatable .=''; + $$rowtotal += $rows; + return $datatable; +} + sub print_autoenroll { my ($dom,$settings,$rowtotal) = @_; my $autorun = &Apache::lonnet::auto_run(undef,$dom), @@ -995,6 +1557,10 @@ sub print_autoenroll { } } my $domform = &Apache::loncommon::select_dom_form($defdom,'sender_domain',1); + my $notif_sender; + if (ref($settings) eq 'HASH') { + $notif_sender = $settings->{'sender_uname'}; + } my $datatable=''. ''.&mt('Auto-enrollment active?').''. '