--- loncom/interface/domainprefs.pm 2016/04/04 01:09:47 1.272 +++ loncom/interface/domainprefs.pm 2017/01/22 13:26:32 1.287 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # Handler to set domain-wide configuration settings # -# $Id: domainprefs.pm,v 1.272 2016/04/04 01:09:47 raeburn Exp $ +# $Id: domainprefs.pm,v 1.287 2017/01/22 13:26:32 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -19,7 +19,8 @@ # # You should have received a copy of the GNU General Public License # along with LON-CAPA; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA# +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# # /home/httpd/html/adm/gpl.txt # # http://www.lon-capa.org/ @@ -169,6 +170,7 @@ use Apache::loncoursequeueadmin(); use LONCAPA qw(:DEFAULT :match); use LONCAPA::Enrollment; use LONCAPA::lonauthcgi(); +use LONCAPA::SSL; use File::Copy; use Locale::Language; use DateTime::TimeZone; @@ -217,13 +219,13 @@ sub handler { 'serverstatuses','requestcourses','helpsettings', 'coursedefaults','usersessions','loadbalancing', 'requestauthor','selfenrollment','inststatus', - 'ltitools'],$dom); + 'ltitools','ssl','trust'],$dom); my @prefs_order = ('rolecolors','login','defaults','quotas','autoenroll', 'autoupdate','autocreate','directorysrch','contacts', 'usercreation','selfcreation','usermodification','scantron', 'requestcourses','requestauthor','coursecategories', 'serverstatuses','helpsettings','coursedefaults', - 'ltitools','selfenrollment','usersessions'); + 'ltitools','selfenrollment','usersessions','ssl','trust'); my %existing; if (ref($domconfig{'loadbalancing'}) eq 'HASH') { %existing = %{$domconfig{'loadbalancing'}}; @@ -306,18 +308,24 @@ sub handler { modify => \&modify_autocreate, }, 'directorysrch' => - { text => 'Institutional directory searches', + { text => 'Directory searches', help => 'Domain_Configuration_InstDirectory_Search', - header => [{col1 => 'Setting', + header => [{col1 => 'Institutional Directory Setting', + col2 => 'Value',}, + {col1 => 'LON-CAPA Directory Setting', col2 => 'Value',}], print => \&print_directorysrch, modify => \&modify_directorysrch, }, 'contacts' => - { text => 'Contact Information', + { text => 'E-mail addresses and helpform', help => 'Domain_Configuration_Contact_Info', - header => [{col1 => 'Setting', - col2 => 'Value',}], + header => [{col1 => 'Default e-mail addresses', + col2 => 'Value',}, + {col1 => 'Recipient(s) for notifications', + col2 => 'Value',}, + {col1 => 'Ask helpdesk form settings', + col2 => 'Value',},], print => \&print_contacts, modify => \&modify_contacts, }, @@ -414,10 +422,12 @@ sub handler { modify => \&modify_serverstatuses, }, 'helpsettings' => - {text => 'Help page settings', + {text => 'Support settings', help => 'Domain_Configuration_Help_Settings', - header => [{col1 => 'Help Settings (logged-in users)', - col2 => 'Value'}], + header => [{col1 => 'Help Page Settings (logged-in users)', + col2 => 'Value'}, + {col1 => 'Helpdesk Roles', + col2 => 'Settings'},], print => \&print_helpsettings, modify => \&modify_helpsettings, }, @@ -463,7 +473,7 @@ sub handler { print => \&print_usersessions, modify => \&modify_usersessions, }, - 'loadbalancing' => + 'loadbalancing' => {text => 'Dedicated Load Balancer(s)', help => 'Domain_Configuration_Load_Balancing', header => [{col1 => 'Balancers', @@ -474,7 +484,7 @@ sub handler { print => \&print_loadbalancing, modify => \&modify_loadbalancing, }, - 'ltitools' => + 'ltitools' => {text => 'External Tools (LTI)', help => 'Domain_configuration_LTI_Tools', header => [{col1 => 'Setting', @@ -482,7 +492,42 @@ sub handler { print => \&print_ltitools, modify => \&modify_ltitools, }, - + 'ssl' => + {text => 'LON-CAPA Network (SSL)', + help => 'Domain_Configuration_Network_SSL', + header => [{col1 => 'Server', + col2 => 'Certificate Status'}, + {col1 => 'Connections to other servers', + col2 => 'Rules'}, + {col1 => "Replicating domain's published content", + col2 => 'Rules'}], + print => \&print_ssl, + modify => \&modify_ssl, + }, + 'trust' => + {text => 'Trust Settings', + help => 'Domain_Configuration_Trust', + header => [{col1 => "Access to this domain's content by others", + col2 => 'Rules'}, + {col1 => "Access to other domain's content by this domain", + col2 => 'Rules'}, + {col1 => "Enrollment in this domain's courses by others", + col2 => 'Rules',}, + {col1 => "Co-author roles in this domain for others", + col2 => 'Rules',}, + {col1 => "Co-author roles for this domain's users elsewhere", + col2 => 'Rules',}, + {col1 => "Domain roles in this domain assignable to others", + col2 => 'Rules'}, + {col1 => "Course catalog for this domain displayed elsewhere", + col2 => 'Rules'}, + {col1 => "Requests for creation of courses in this domain by others", + col2 => 'Rules'}, + {col1 => "Users in other domains can send messages to this domain", + col2 => 'Rules'},], + print => \&print_trust, + modify => \&modify_trust, + }, ); if (keys(%servers) > 1) { $prefs{'login'} = { text => 'Log-in page options', @@ -536,6 +581,9 @@ $javascript_validations $coursebrowserjs END } + if (grep(/^contacts$/,@actions)) { + $js .= &contacts_javascript(); + } &Apache::lonconfigsettings::display_settings($r,$dom,$phase,$context,\@prefs_order,\%prefs,\%domconfig,$confname,$js); } else { # check if domconfig user exists for the domain. @@ -647,7 +695,7 @@ sub process_changes { } elsif ($action eq 'requestauthor') { $output = &modify_quotas($r,$dom,$action,$lastactref,%domconfig); } elsif ($action eq 'helpsettings') { - $output = &modify_helpsettings($r,$dom,$confname,%domconfig); + $output = &modify_helpsettings($r,$dom,$confname,$lastactref,%domconfig); } elsif ($action eq 'coursedefaults') { $output = &modify_coursedefaults($dom,$lastactref,%domconfig); } elsif ($action eq 'selfenrollment') { @@ -658,6 +706,10 @@ sub process_changes { $output = &modify_loadbalancing($dom,%domconfig); } elsif ($action eq 'ltitools') { $output = &modify_ltitools($r,$dom,$action,$lastactref,%domconfig); + } elsif ($action eq 'ssl') { + $output = &modify_ssl($dom,$lastactref,%domconfig); + } elsif ($action eq 'trust') { + $output = &modify_trust($dom,$lastactref,%domconfig); } return $output; } @@ -670,6 +722,22 @@ sub print_config_box { $output = &coursecategories_javascript($settings); } elsif ($action eq 'defaults') { $output = &defaults_javascript($settings); + } elsif ($action eq 'helpsettings') { + my (%privs,%levelscurrent); + my %full=(); + my %levels=( + course => {}, + domain => {}, + system => {}, + ); + my $context = 'domain'; + my $crstype = 'Course'; + my $formname = 'display'; + &Apache::lonuserutils::custom_role_privs(\%privs,\%full,\%levels,\%levelscurrent); + my @templateroles = &Apache::lonuserutils::custom_template_roles($context,$crstype); + $output = + &Apache::lonuserutils::custom_roledefs_js($context,$crstype,$formname,\%full, + \@templateroles); } $output .= ' @@ -687,6 +755,7 @@ sub print_config_box { my $colspan = ''; my $rightcolspan = ''; if (($action eq 'rolecolors') || ($action eq 'defaults') || + ($action eq 'directorysrch') || (($action eq 'login') && ($numheaders < 4))) { $colspan = ' colspan="2"'; } @@ -704,7 +773,9 @@ sub print_config_box { $rowtotal ++; if (($action eq 'autoupdate') || ($action eq 'usercreation') || ($action eq 'selfcreation') || ($action eq 'usermodification') || ($action eq 'defaults') || ($action eq 'coursedefaults') || - ($action eq 'selfenrollment') || ($action eq 'usersessions')) { + ($action eq 'selfenrollment') || ($action eq 'usersessions') || ($action eq 'ssl') || + ($action eq 'directorysrch') || ($action eq 'trust') || ($action eq 'helpsettings') || + ($action eq 'contacts')) { $output .= $item->{'print'}->('top',$dom,$settings,\$rowtotal); } elsif ($action eq 'coursecategories') { $output .= $item->{'print'}->('top',$dom,$item,$settings,\$rowtotal); @@ -734,14 +805,46 @@ sub print_config_box { $rowtotal ++; if (($action eq 'autoupdate') || ($action eq 'usercreation') || ($action eq 'selfcreation') || ($action eq 'selfenrollment') || - ($action eq 'usersessions') || ($action eq 'coursecategories')) { + ($action eq 'usersessions') || ($action eq 'coursecategories') || + ($action eq 'ssl') || ($action eq 'trust') || ($action eq 'contacts')) { if ($action eq 'coursecategories') { $output .= &print_coursecategories('middle',$dom,$item,$settings,\$rowtotal); $colspan = ' colspan="2"'; + } elsif ($action eq 'trust') { + $output .= $item->{'print'}->('shared',$dom,$settings,\$rowtotal); } else { $output .= $item->{'print'}->('middle',$dom,$settings,\$rowtotal); } - $output .= ' + if ($action eq 'trust') { + $output .= ' +
+ + '; + my @trusthdrs = qw(2 3 4 5 6 7); + my @prefixes = qw(enroll othcoau coaurem domroles catalog reqcrs); + for (my $i=0; $i<@trusthdrs; $i++) { + $output .= ' + + + + + + '. + $item->{'print'}->($prefixes[$i],$dom,$settings,\$rowtotal).' +
'.&mt($item->{'header'}->[$trusthdrs[$i]]->{'col1'}).''.&mt($item->{'header'}->[$trusthdrs[$i]]->{'col2'}).'
+ + '; + } + $output .= ' + + + + + + '. + $item->{'print'}->('bottom',$dom,$settings,\$rowtotal); + } else { + $output .= '
'.&mt($item->{'header'}->[8]->{'col1'}).''.&mt($item->{'header'}->[8]->{'col2'}).'
@@ -752,14 +855,16 @@ sub print_config_box { '.&mt($item->{'header'}->[2]->{'col1'}).' '.&mt($item->{'header'}->[2]->{'col2'}).' '."\n"; - if ($action eq 'coursecategories') { - $output .= &print_coursecategories('bottom',$dom,$item,$settings,\$rowtotal); - } else { - $output .= $item->{'print'}->('bottom',$dom,$settings,\$rowtotal); + if ($action eq 'coursecategories') { + $output .= &print_coursecategories('bottom',$dom,$item,$settings,\$rowtotal); + } else { + $output .= $item->{'print'}->('bottom',$dom,$settings,\$rowtotal); + } } $rowtotal ++; } elsif (($action eq 'usermodification') || ($action eq 'coursedefaults') || - ($action eq 'defaults')) { + ($action eq 'defaults') || ($action eq 'directorysrch') || + ($action eq 'helpsettings')) { $output .= $item->{'print'}->('bottom',$dom,$settings,\$rowtotal); } elsif ($action eq 'login') { if ($numheaders == 4) { @@ -872,7 +977,7 @@ sub print_config_box { '; - if (($action eq 'login') || ($action eq 'directorysrch')) { + if ($action eq 'login') { $output .= ' '; } elsif ($action eq 'serverstatuses') { @@ -916,14 +1021,12 @@ sub print_config_box { $rowtotal ++; if ($action eq 'quotas') { $output .= &print_quotas($dom,$settings,\$rowtotal,$action); - } elsif (($action eq 'autoenroll') || ($action eq 'autocreate') || ($action eq 'directorysrch') || - ($action eq 'contacts') || ($action eq 'serverstatuses') || ($action eq 'loadbalancing') || + } elsif (($action eq 'autoenroll') || ($action eq 'autocreate') || + ($action eq 'serverstatuses') || ($action eq 'loadbalancing') || ($action eq 'ltitools')) { $output .= $item->{'print'}->($dom,$settings,\$rowtotal); } elsif ($action eq 'scantron') { $output .= &print_scantronformat($r,$dom,$confname,$settings,\$rowtotal); - } elsif ($action eq 'helpsettings') { - $output .= &print_helpsettings($dom,$confname,$settings,\$rowtotal); } } $output .= ' @@ -2497,7 +2600,7 @@ ENDSCRIPT sub print_autoenroll { my ($dom,$settings,$rowtotal) = @_; my $autorun = &Apache::lonnet::auto_run(undef,$dom), - my ($defdom,$runon,$runoff,$coownerson,$coownersoff); + my ($defdom,$runon,$runoff,$coownerson,$coownersoff,$failsafe); if (ref($settings) eq 'HASH') { if (exists($settings->{'run'})) { if ($settings->{'run'} eq '0') { @@ -2531,6 +2634,9 @@ sub print_autoenroll { if (exists($settings->{'sender_domain'})) { $defdom = $settings->{'sender_domain'}; } + if (exists($settings->{'autofailsafe'})) { + $failsafe = $settings->{'autofailsafe'}; + } } else { if ($autorun) { $runon = ' checked="checked" '; @@ -2566,8 +2672,12 @@ sub print_autoenroll { $coownerson.' value="1" />'.&mt('Yes').' '. ''. - ''; - $$rowtotal += 3; + ''. + ''. + ''; + $$rowtotal += 4; return $datatable; } @@ -2696,233 +2806,778 @@ sub print_autocreate { } sub print_directorysrch { - my ($dom,$settings,$rowtotal) = @_; - my $srchon = ' '; - my $srchoff = ' checked="checked" '; - my ($exacton,$containson,$beginson); - my $localon = ' '; - my $localoff = ' checked="checked" '; - if (ref($settings) eq 'HASH') { - if ($settings->{'available'} eq '1') { - $srchon = $srchoff; - $srchoff = ' '; - } - if ($settings->{'localonly'} eq '1') { - $localon = $localoff; - $localoff = ' '; - } - if (ref($settings->{'searchtypes'}) eq 'ARRAY') { - foreach my $type (@{$settings->{'searchtypes'}}) { - if ($type eq 'exact') { + my ($position,$dom,$settings,$rowtotal) = @_; + my $datatable; + if ($position eq 'top') { + my $instsrchon = ' '; + my $instsrchoff = ' checked="checked" '; + my ($exacton,$containson,$beginson); + my $instlocalon = ' '; + my $instlocaloff = ' checked="checked" '; + if (ref($settings) eq 'HASH') { + if ($settings->{'available'} eq '1') { + $instsrchon = $instsrchoff; + $instsrchoff = ' '; + } + if ($settings->{'localonly'} eq '1') { + $instlocalon = $instlocaloff; + $instlocaloff = ' '; + } + if (ref($settings->{'searchtypes'}) eq 'ARRAY') { + foreach my $type (@{$settings->{'searchtypes'}}) { + if ($type eq 'exact') { + $exacton = ' checked="checked" '; + } elsif ($type eq 'contains') { + $containson = ' checked="checked" '; + } elsif ($type eq 'begins') { + $beginson = ' checked="checked" '; + } + } + } else { + if ($settings->{'searchtypes'} eq 'exact') { + $exacton = ' checked="checked" '; + } elsif ($settings->{'searchtypes'} eq 'contains') { + $containson = ' checked="checked" '; + } elsif ($settings->{'searchtypes'} eq 'specify') { $exacton = ' checked="checked" '; - } elsif ($type eq 'contains') { $containson = ' checked="checked" '; - } elsif ($type eq 'begins') { - $beginson = ' checked="checked" '; } } - } else { - if ($settings->{'searchtypes'} eq 'exact') { - $exacton = ' checked="checked" '; - } elsif ($settings->{'searchtypes'} eq 'contains') { - $containson = ' checked="checked" '; - } elsif ($settings->{'searchtypes'} eq 'specify') { - $exacton = ' checked="checked" '; - $containson = ' checked="checked" '; - } } - } - my ($searchtitles,$titleorder) = &sorted_searchtitles(); - my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom); + my ($searchtitles,$titleorder) = &sorted_searchtitles(); + my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom); - my $numinrow = 4; - my $cansrchrow = 0; - my $datatable=''. - ''. - ''. - ''. - ''. - ''. - ''; - $$rowtotal += 2; - if (ref($usertypes) eq 'HASH') { - if (keys(%{$usertypes}) > 0) { - $datatable .= &insttypes_row($settings,$types,$usertypes,$dom, - $numinrow,$othertitle,'cansearch'); - $cansrchrow = 1; + my $numinrow = 4; + my $cansrchrow = 0; + $datatable=''. + ''. + ''. + ''. + ''. + ''. + ''; + $$rowtotal += 2; + if (ref($usertypes) eq 'HASH') { + if (keys(%{$usertypes}) > 0) { + $datatable .= &insttypes_row($settings,$types,$usertypes,$dom, + $numinrow,$othertitle,'cansearch'); + $cansrchrow = 1; + } } - } - if ($cansrchrow) { - $$rowtotal ++; - $datatable .= ''; - } else { - $datatable .= ''; - } - $datatable .= ''; + $$rowtotal ++; + if ($cansrchrow) { + $datatable .= ''; + } else { + $datatable .= ''; + } + $datatable .= ''. + ''; + $$rowtotal ++; } else { - $datatable .= ''; + my $domsrchon = ' checked="checked" '; + my $domsrchoff = ' '; + my $domlocalon = ' '; + my $domlocaloff = ' checked="checked" '; + if (ref($settings) eq 'HASH') { + if ($settings->{'lclocalonly'} eq '1') { + $domlocalon = $domlocaloff; + $domlocaloff = ' '; + } + if ($settings->{'lcavailable'} eq '0') { + $domsrchoff = $domsrchon; + $domsrchon = ' '; + } + } + $datatable=''. + ''. + ''. + ''. + ''. + ''. + ''; + $$rowtotal += 2; } - $datatable .= ''. - ''; - $$rowtotal ++; return $datatable; } sub print_contacts { - my ($dom,$settings,$rowtotal) = @_; + my ($position,$dom,$settings,$rowtotal) = @_; my $datatable; my @contacts = ('adminemail','supportemail'); - my (%checked,%to,%otheremails,%bccemails); - my @mailings = ('errormail','packagesmail','lonstatusmail','helpdeskmail', - 'requestsmail','updatesmail','idconflictsmail'); + my (%checked,%to,%otheremails,%bccemails,%includestr,%includeloc,%currfield, + $maxsize,$fields,$fieldtitles,$fieldoptions,$possoptions,@mailings); foreach my $type (@mailings) { $otheremails{$type} = ''; } - $bccemails{'helpdeskmail'} = ''; - if (ref($settings) eq 'HASH') { - foreach my $item (@contacts) { - if (exists($settings->{$item})) { - $to{$item} = $settings->{$item}; + if ($position eq 'top') { + if (ref($settings) eq 'HASH') { + foreach my $item (@contacts) { + if (exists($settings->{$item})) { + $to{$item} = $settings->{$item}; + } } } - foreach my $type (@mailings) { - if (exists($settings->{$type})) { - if (ref($settings->{$type}) eq 'HASH') { - foreach my $item (@contacts) { - if ($settings->{$type}{$item}) { - $checked{$type}{$item} = ' checked="checked" '; + } elsif ($position eq 'middle') { + @mailings = ('errormail','packagesmail','lonstatusmail','requestsmail', + 'updatesmail','idconflictsmail'); + } else { + @mailings = ('helpdeskmail','otherdomsmail'); + $bccemails{'helpdeskmail'} = ''; + $bccemails{'otherdomsmail'} = ''; + $includestr{'helpdeskmail'} = ''; + $includestr{'otherdomsmail'} = ''; + ($fields,$fieldtitles,$fieldoptions,$possoptions) = &helpform_fields(); + } + if (ref($settings) eq 'HASH') { + unless ($position eq 'top') { + foreach my $type (@mailings) { + if (exists($settings->{$type})) { + if (ref($settings->{$type}) eq 'HASH') { + foreach my $item (@contacts) { + if ($settings->{$type}{$item}) { + $checked{$type}{$item} = ' checked="checked" '; + } } + $otheremails{$type} = $settings->{$type}{'others'}; + if (($type eq 'helpdeskmail') || ($type eq 'otherdomsmail')) { + $bccemails{$type} = $settings->{$type}{'bcc'}; + if ($settings->{$type}{'include'} ne '') { + ($includeloc{$type},$includestr{$type}) = split(/:/,$settings->{$type}{'include'},2); + $includestr{$type} = &unescape($includestr{$type}); + } + } + } + } elsif ($type eq 'lonstatusmail') { + $checked{'lonstatusmail'}{'adminemail'} = ' checked="checked" '; + } + } + } + if ($position eq 'bottom') { + foreach my $type (@mailings) { + $bccemails{$type} = $settings->{$type}{'bcc'}; + if ($settings->{$type}{'include'} ne '') { + ($includeloc{$type},$includestr{$type}) = split(/:/,$settings->{$type}{'include'},2); + $includestr{$type} = &unescape($includestr{$type}); + } + } + if (ref($settings->{'helpform'}) eq 'HASH') { + if (ref($fields) eq 'ARRAY') { + foreach my $field (@{$fields}) { + $currfield{$field} = $settings->{'helpform'}{$field}; } - $otheremails{$type} = $settings->{$type}{'others'}; - if ($type eq 'helpdeskmail') { - $bccemails{$type} = $settings->{$type}{'bcc'}; + } + if (exists($settings->{'helpform'}{'maxsize'})) { + $maxsize = $settings->{'helpform'}{'maxsize'}; + } else { + $maxsize = '1.0'; + } + } else { + if (ref($fields) eq 'ARRAY') { + foreach my $field (@{$fields}) { + $currfield{$field} = 'yes'; } } - } elsif ($type eq 'lonstatusmail') { - $checked{'lonstatusmail'}{'adminemail'} = ' checked="checked" '; + $maxsize = '1.0'; } } } else { - $to{'supportemail'} = $Apache::lonnet::perlvar{'lonSupportEMail'}; - $to{'adminemail'} = $Apache::lonnet::perlvar{'lonAdmEMail'}; - $checked{'errormail'}{'adminemail'} = ' checked="checked" '; - $checked{'packagesmail'}{'adminemail'} = ' checked="checked" '; - $checked{'helpdeskmail'}{'supportemail'} = ' checked="checked" '; - $checked{'lonstatusmail'}{'adminemail'} = ' checked="checked" '; - $checked{'requestsmail'}{'adminemail'} = ' checked="checked" '; - $checked{'updatesmail'}{'adminemail'} = ' checked="checked" '; - $checked{'idconflictsmail'}{'adminemail'} = ' checked="checked" '; + if ($position eq 'top') { + $to{'supportemail'} = $Apache::lonnet::perlvar{'lonSupportEMail'}; + $to{'adminemail'} = $Apache::lonnet::perlvar{'lonAdmEMail'}; + $checked{'errormail'}{'adminemail'} = ' checked="checked" '; + $checked{'packagesmail'}{'adminemail'} = ' checked="checked" '; + $checked{'lonstatusmail'}{'adminemail'} = ' checked="checked" '; + $checked{'requestsmail'}{'adminemail'} = ' checked="checked" '; + $checked{'updatesmail'}{'adminemail'} = ' checked="checked" '; + $checked{'idconflictsmail'}{'adminemail'} = ' checked="checked" '; + } elsif ($position eq 'bottom') { + $checked{'helpdeskmail'}{'supportemail'} = ' checked="checked" '; + $checked{'otherdomsmail'}{'supportemail'} = ' checked="checked" '; + if (ref($fields) eq 'ARRAY') { + foreach my $field (@{$fields}) { + $currfield{$field} = 'yes'; + } + } + $maxsize = '1.0'; + } } my ($titles,$short_titles) = &contact_titles(); my $rownum = 0; my $css_class; - foreach my $item (@contacts) { - $css_class = $rownum%2?' class="LC_odd_row"':''; - $datatable .= ''. - ''; - $rownum ++; + if ($position eq 'top') { + foreach my $item (@contacts) { + $css_class = $rownum%2?' class="LC_odd_row"':''; + $datatable .= ''. + ''; + $rownum ++; + } + } else { + foreach my $type (@mailings) { + $css_class = $rownum%2?' class="LC_odd_row"':''; + $datatable .= ''. + ''. + ''."\n"; + $rownum ++; + } } - foreach my $type (@mailings) { + if ($position eq 'middle') { + my %choices; + $choices{'reporterrors'} = &mt('E-mail error reports to [_1]', + &Apache::loncommon::modal_link('http://loncapa.org/core.html', + &mt('LON-CAPA core group - MSU'),600,500)); + $choices{'reportupdates'} = &mt('E-mail record of completed LON-CAPA updates to [_1]', + &Apache::loncommon::modal_link('http://loncapa.org/core.html', + &mt('LON-CAPA core group - MSU'),600,500)); + my @toggles = ('reporterrors','reportupdates'); + my %defaultchecked = ('reporterrors' => 'on', + 'reportupdates' => 'on'); + (my $reports,$rownum) = &radiobutton_prefs($settings,\@toggles,\%defaultchecked, + \%choices,$rownum); + $datatable .= $reports; + } elsif ($position eq 'bottom') { $css_class = $rownum%2?' class="LC_odd_row"':''; $datatable .= ''. - ''. - ''."\n"; $rownum ++; } - my %choices; - $choices{'reporterrors'} = &mt('E-mail error reports to [_1]', - &Apache::loncommon::modal_link('http://loncapa.org/core.html', - &mt('LON-CAPA core group - MSU'),600,500)); - $choices{'reportupdates'} = &mt('E-mail record of completed LON-CAPA updates to [_1]', - &Apache::loncommon::modal_link('http://loncapa.org/core.html', - &mt('LON-CAPA core group - MSU'),600,500)); - my @toggles = ('reporterrors','reportupdates'); - my %defaultchecked = ('reporterrors' => 'on', - 'reportupdates' => 'on'); - (my $reports,$rownum) = &radiobutton_prefs($settings,\@toggles,\%defaultchecked, - \%choices,$rownum); - $datatable .= $reports; $$rowtotal += $rownum; return $datatable; } +sub contacts_javascript { + return <<"ENDSCRIPT"; + + + +ENDSCRIPT +} + sub print_helpsettings { - my ($dom,$confname,$settings,$rowtotal) = @_; + my ($position,$dom,$settings,$rowtotal) = @_; + my $confname = $dom.'-domainconfig'; + my $formname = 'display'; my ($datatable,$itemcount); - $itemcount = 1; - my (%choices,%defaultchecked,@toggles); - $choices{'submitbugs'} = &mt('Display link to: [_1]?', - &Apache::loncommon::modal_link('http://bugs.loncapa.org', - &mt('LON-CAPA bug tracker'),600,500)); - %defaultchecked = ('submitbugs' => 'on'); - @toggles = ('submitbugs',); - - ($datatable,$itemcount) = &radiobutton_prefs($settings,\@toggles,\%defaultchecked, - \%choices,$itemcount); + if ($position eq 'top') { + $itemcount = 1; + my (%choices,%defaultchecked,@toggles); + $choices{'submitbugs'} = &mt('Display link to: [_1]?', + &Apache::loncommon::modal_link('http://bugs.loncapa.org', + &mt('LON-CAPA bug tracker'),600,500)); + %defaultchecked = ('submitbugs' => 'on'); + @toggles = ('submitbugs'); + ($datatable,$itemcount) = &radiobutton_prefs($settings,\@toggles,\%defaultchecked, + \%choices,$itemcount); + $$rowtotal ++; + } else { + my $css_class; + my %existing=&Apache::lonnet::dump('roles',$dom,$confname,'rolesdef_'); + my (%customroles,%ordered,%current); + if (ref($settings->{'adhoc'}) eq 'HASH') { + %current = %{$settings->{'adhoc'}}; + } + my $count = 0; + foreach my $key (sort(keys(%existing))) { + if ($key=~/^rolesdef\_(\w+)$/) { + my $rolename = $1; + my (%privs,$order); + ($privs{'system'},$privs{'domain'},$privs{'course'}) = split(/\_/,$existing{$key}); + $customroles{$rolename} = \%privs; + if (ref($current{$rolename}) eq 'HASH') { + $order = $current{$rolename}{'order'}; + } + if ($order eq '') { + $order = $count; + } + $ordered{$order} = $rolename; + $count++; + } + } + my $maxnum = scalar(keys(%ordered)); + my @roles_by_num = (); + foreach my $item (sort {$a <=> $b } (keys(%ordered))) { + push(@roles_by_num,$item); + } + my $context = 'domprefs'; + my $crstype = 'Course'; + my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom); + my @accesstypes = ('all','none'); + my ($numstatustypes,@jsarray); + if (ref($types) eq 'ARRAY') { + if (@{$types} > 0) { + $numstatustypes = scalar(@{$types}); + push(@accesstypes,'status'); + @jsarray = ('bystatus'); + } + } + my %domhelpdesk = &Apache::lonnet::get_active_domroles($dom,['dh']); + if (keys(%domhelpdesk)) { + push(@accesstypes,('inc','exc')); + push(@jsarray,('notinc','notexc')); + } + my $hiddenstr = join("','",@jsarray); + $datatable .= &helpsettings_javascript(\@roles_by_num,$maxnum,$hiddenstr,$formname); + my $context = 'domprefs'; + my $crstype = 'Course'; + my $prefix = 'helproles_'; + my $add_class = 'LC_hidden'; + foreach my $num (@roles_by_num) { + my $role = $ordered{$num}; + my ($desc,$access,@statuses); + if (ref($current{$role}) eq 'HASH') { + $desc = $current{$role}{'desc'}; + $access = $current{$role}{'access'}; + if (ref($current{$role}{'insttypes'}) eq 'ARRAY') { + @statuses = @{$current{$role}{'insttypes'}}; + } + } + if ($desc eq '') { + $desc = $role; + } + my $identifier = 'custhelp'.$num; + my %full=(); + my %levels= ( + course => {}, + domain => {}, + system => {}, + ); + my %levelscurrent=( + course => {}, + domain => {}, + system => {}, + ); + &Apache::lonuserutils::custom_role_privs($customroles{$role},\%full,\%levels,\%levelscurrent); + my @templateroles = &Apache::lonuserutils::custom_template_roles($context,$crstype); + $css_class = $itemcount%2?' class="LC_odd_row"':''; + my $chgstr = ' onchange="javascript:reorderHelpRoles(this.form,'."'helproles_".$num."_pos'".');"'; + $datatable .= ''. + ''; + $itemcount ++; + } + $css_class = $itemcount%2?' class="LC_odd_row"':''; + my $newcust = 'custhelp'.$count; + my (%privs,%levelscurrent); + my %full=(); + my %levels= ( + course => {}, + domain => {}, + system => {}, + ); + &Apache::lonuserutils::custom_role_privs(\%privs,\%full,\%levels,\%levelscurrent); + my @templateroles = &Apache::lonuserutils::custom_template_roles($context,$crstype); + my $chgstr = ' onchange="javascript:reorderHelpRoles(this.form,'."'helproles_".$count."_pos'".');"'; + $datatable .= ''. + ''; + $count ++; + $$rowtotal += $count; + } return $datatable; } +sub adhocbutton { + my ($prefix,$num,$field,$visibility) = @_; + my %lt = &Apache::lonlocal::texthash( + show => 'Show details', + hide => 'Hide details', + ); + return ''.(' 'x10). + ''.(' 'x2).''.(' 'x2); +} + +sub helpsettings_javascript { + my ($roles_by_num,$total,$hiddenstr,$formname) = @_; + return unless(ref($roles_by_num) eq 'ARRAY'); + my %html_js_lt = &Apache::lonlocal::texthash( + show => 'Show details', + hide => 'Hide details', + ); + &html_escape(\%html_js_lt); + my $jstext = ' var helproles = Array('."'".join("','",@{$roles_by_num})."'".');'."\n"; + return <<"ENDSCRIPT"; + + +ENDSCRIPT +} + +sub helpdeskroles_access { + my ($dom,$prefix,$num,$add_class,$current,$accesstypes,$othertitle, + $usertypes,$types,$domhelpdesk) = @_; + return unless ((ref($accesstypes) eq 'ARRAY') && (ref($domhelpdesk) eq 'HASH')); + my %lt = &Apache::lonlocal::texthash( + 'rou' => 'Role usage', + 'whi' => 'Which helpdesk personnel may use this role?', + 'all' => 'All', + 'none' => 'None', + 'status' => 'Determined based on institutional status', + 'inc' => 'Include all, but exclude specific personnel', + 'exc' => 'Exclude all, but include specific personnel', + ); + my %usecheck = ( + all => ' checked="checked"', + ); + my %displaydiv = ( + status => 'none', + inc => 'none', + exc => 'none', + priv => 'block', + ); + my $output; + if (ref($current) eq 'HASH') { + if (($current->{'access'} ne '') && ($current->{'access'} ne 'all')) { + if (grep(/^\Q$current->{access}\E$/,@{$accesstypes})) { + $usecheck{$current->{access}} = $usecheck{'all'}; + delete($usecheck{'all'}); + if ($current->{access} =~ /^(status|inc|exc)$/) { + my $access = $1; + $displaydiv{$access} = 'inline'; + } elsif ($current->{access} eq 'none') { + $displaydiv{'priv'} = 'none'; + } + } + } + } + $output = '
'.$lt{'rou'}.''. + '

'.$lt{'whi'}.'

'; + foreach my $access (@{$accesstypes}) { + $output .= '

'; + if ($access eq 'status') { + $output .= '

'. + &Apache::lonuserutils::adhoc_status_types($dom,$prefix,$num,$current->{$access}, + $othertitle,$usertypes,$types). + '
'; + } elsif (($access eq 'inc') && (keys(%{$domhelpdesk}) > 0)) { + $output .= '
'. + &Apache::lonuserutils::adhoc_staff($access,$prefix,$num,$current->{$access},$domhelpdesk). + '
'; + } elsif (($access eq 'exc') && (keys(%{$domhelpdesk}) > 0)) { + $output .= '
'. + &Apache::lonuserutils::adhoc_staff($access,$prefix,$num,$current->{$access},$domhelpdesk). + '
'; + } + $output .= '

'; + } + $output .= '
'; + return $output; +} + sub radiobutton_prefs { my ($settings,$toggles,$defaultchecked,$choices,$itemcount,$onclick, $additional,$align) = @_; @@ -3154,7 +3809,24 @@ sub print_ltitools { } $datatable .= ''; } - $datatable .= '
'.&mt($item->{'header'}->[0]->{'col1'}).'
'.&mt('Failsafe for no drops when institutional data missing').''. + '
'.&mt('Directory search available?').' '. - '
'.&mt('Other domains can search?').' '. - '
'.&mt('Institutional directory search available?').' '. + '
'.&mt('Other domains can search institution?').' '. + '
'.&mt('Supported search methods'). - ''; - foreach my $title (@{$titleorder}) { - if (defined($searchtitles->{$title})) { - my $check = ' '; - if (ref($settings) eq 'HASH') { - if (ref($settings->{'searchby'}) eq 'ARRAY') { - if (grep(/^\Q$title\E$/,@{$settings->{'searchby'}})) { - $check = ' checked="checked" '; + if ($cansrchrow) { + $$rowtotal ++; + $datatable .= ''; + } else { + $datatable .= ''; + } + $datatable .= ''; - $$rowtotal ++; - if ($cansrchrow) { - $datatable .= ''; + $datatable .= '
'.&mt('Supported search methods'). + ''; + foreach my $title (@{$titleorder}) { + if (defined($searchtitles->{$title})) { + my $check = ' '; + if (ref($settings) eq 'HASH') { + if (ref($settings->{'searchby'}) eq 'ARRAY') { + if (grep(/^\Q$title\E$/,@{$settings->{'searchby'}})) { + $check = ' checked="checked" '; + } } } + $datatable .= ''; } - $datatable .= ''; } - } - $datatable .= '
'. + ''. - '
'.&mt('Search latitude').''. + ' '. + ' '. + '
'.&mt('LON-CAPA directory search available?').' '. + '
'.&mt('Other domains can search LON-CAPA domain?').' '. + '
'.&mt('Search latitude').''. - ' '. - ' '. - '
'.$titles->{$item}. - ''. - '
'.$titles->{$item}. + ''. + '
'. + $titles->{$type}.': '; + if (($type eq 'helpdeskmail') || ($type eq 'otherdomsmail')) { + $datatable .= '
'.&mt('E-mail recipient(s)').''; + } + $datatable .= ''; + foreach my $item (@contacts) { + $datatable .= ' '; + } + $datatable .= '
'.&mt('Others').':  '. + ''; + my %locchecked; + if (($type eq 'helpdeskmail') || ($type eq 'otherdomsmail')) { + foreach my $loc ('s','b') { + if ($includeloc{$type} eq $loc) { + $locchecked{$loc} = ' checked="checked"'; + last; + } + } + $datatable .= '
'.&mt('Bcc:').(' 'x6). + '
'. + '
'.&mt('Optional added text').''. + &mt('Text automatically added to e-mail:').' '. + '
'. + ''.&mt('Location:').' '. + ''. + (' 'x2). + ''. + '
'; + } + $datatable .= '
'. - $titles->{$type}.': '. - ''; - foreach my $item (@contacts) { - $datatable .= ' '; - } - $datatable .= '
'.&mt('Others').':  '. - ''; - if ($type eq 'helpdeskmail') { - $datatable .= '
'.&mt('Bcc:').(' 'x6). - ''; + '
'.&mt('Extra helpdesk form fields:').'
'. + &mt('(e-mail, subject, and description always shown)'). + '
'; + if ((ref($fields) eq 'ARRAY') && (ref($fieldtitles) eq 'HASH') && + (ref($fieldoptions) eq 'HASH') && (ref($possoptions) eq 'HASH')) { + $datatable .= ''; + foreach my $field (@{$fields}) { + $datatable .= ''. + ''; + } + $datatable .= '
'.&mt('Field').''.&mt('Status').'
'.$fieldtitles->{$field}; + if (($field eq 'screenshot') || ($field eq 'cc')) { + $datatable .= ' '.&mt('(logged-in users)'); + } + $datatable .=''; + my $clickaction; + if ($field eq 'screenshot') { + $clickaction = ' onclick="screenshotSize(this);"'; + } + if (ref($possoptions->{$field}) eq 'ARRAY') { + foreach my $option (@{$possoptions->{$field}}) { + my $checked; + if ($currfield{$field} eq $option) { + $checked = ' checked="checked"'; + } + $datatable .= ''.(' 'x2); + } + } + if ($field eq 'screenshot') { + my $display; + if ($currfield{$field} eq 'no') { + $display = ' style="display:none"'; + } + $datatable .= '
'.&mt('Maximum size for upload (MB)').''. + ''; + } + $datatable .= '
'; } $datatable .= '
'.$role.'
'. + ''.(' 'x2). + ''. + '
'.&mt('Role name').''. + &mt('Name shown to users:'). + ''. + '
'. + &helpdeskroles_access($dom,$prefix,$num,$add_class,$current{$role},\@accesstypes, + $othertitle,$usertypes,$types,\%domhelpdesk). + '
'. + ''.&mt('Role privileges').&adhocbutton($prefix,$num,'privs','show').''. + &Apache::lonuserutils::custom_role_table($crstype,\%full,\%levels, + \%levelscurrent,$identifier, + 'LC_hidden',$prefix.$num.'_privs'). + '
'.&mt('Role name').''. + ''. + &mt('Internal name:'). + ''. + ''.(' 'x4). + ''. + &mt('Name shown to users:'). + ''. + '
'. + &helpdeskroles_access($dom,$prefix,$count,'',undef,\@accesstypes,$othertitle, + $usertypes,$types,\%domhelpdesk). + '
'.&mt('Role privileges').''. + &Apache::lonuserutils::custom_role_header($context,$crstype, + \@templateroles,$newcust). + &Apache::lonuserutils::custom_role_table('Course',\%full,\%levels, + \%levelscurrent,$newcust). + '
'. + $datatable .= ''; + my %courseconfig; + if (ref($settings->{$item}) eq 'HASH') { + if (ref($settings->{$item}->{'crsconf'}) eq 'HASH') { + %courseconfig = %{$settings->{$item}->{'crsconf'}}; + } + } + $datatable .= '
'.&mt('Configurable in course').''; + foreach my $item ('label','title','target') { + my $checked; + if ($courseconfig{$item}) { + $checked = ' checked="checked"'; + } + $datatable .= ''.(' ' x2)."\n"; + } + $datatable .= '
'. '
'.&mt('Custom items sent on launch').''. ''; if (ref($settings->{$item}->{'custom'}) eq 'HASH') { @@ -3260,6 +3932,13 @@ sub print_ltitools { $datatable .= ''; } $datatable .= '
'.&mt('Action').''.&mt('Name').''.&mt('Value').'
'. + '
'.&mt('Configurable in course').''; + foreach my $item ('label','title','target') { + $datatable .= ''.(' ' x2)."\n"; + } + $datatable .= '
'. '
'.&mt('Custom items sent on launch').''. ''. '
'.&mt('Action').''.&mt('Name').''.&mt('Value').'
'. @@ -3294,6 +3973,9 @@ sub ltitools_names { 'width' => 'Width', 'passback' => 'Tool can return grades:', 'roster' => 'Tool can retrieve roster:', + 'crstarget' => 'Display target', + 'crslabel' => 'Course label', + 'crstitle' => 'Course title', ); return %lt; } @@ -3310,12 +3992,14 @@ sub print_coursedefaults { uselcmath => 'Math preview uses LON-CAPA previewer (javascript) in place of DragMath (Java)', usejsme => 'Molecule editor uses JSME (HTML5) in place of JME (Java)', postsubmit => 'Disable submit button/keypress following student submission', - canclone => "People who may clone a course (besides course's owner and coordinators)", + canclone => "People who may clone a course (besides course's owner and coordinators)", + mysqltables => 'Lifetime (s) of "Temporary" MySQL tables (student performance data) on homeserver', ); my %staticdefaults = ( anonsurvey_threshold => 10, uploadquota => 500, postsubmit => 60, + mysqltables => 172800, ); if ($position eq 'top') { %defaultchecked = ( @@ -3400,7 +4084,7 @@ sub print_coursedefaults { $itemcount ++; } else { $css_class = $itemcount%2 ? ' class="LC_odd_row"' : ''; - my ($currdefresponder,%defcredits,%curruploadquota,%deftimeout); + my ($currdefresponder,%defcredits,%curruploadquota,%deftimeout,%currmysql); my $currusecredits = 0; my $postsubmitclient = 1; my @types = ('official','unofficial','community','textbook','placement'); @@ -3444,6 +4128,15 @@ sub print_coursedefaults { $deftimeout{$type} = $staticdefaults{'postsubmit'}; } } + if (ref($settings->{'mysqltables'}) eq 'HASH') { + foreach my $type (keys(%{$settings->{'mysqltables'}})) { + $currmysql{$type} = $settings->{'mysqltables'}{$type}; + } + } else { + foreach my $type (@types) { + $currmysql{$type} = $staticdefaults{'mysqltables'}; + } + } } else { foreach my $type (@types) { $deftimeout{$type} = $staticdefaults{'postsubmit'}; @@ -3521,13 +4214,27 @@ sub print_coursedefaults { $additional .= '
'."\n"; %defaultchecked = ('postsubmit' => 'on'); @toggles = ('postsubmit'); - my $current = { - 'postsubmit' => $postsubmitclient, - }; + $current = { + 'postsubmit' => $postsubmitclient, + }; ($table,$itemcount) = &radiobutton_prefs($current,\@toggles,\%defaultchecked, \%choices,$itemcount,$onclick,$additional,'left'); $datatable .= $table; + $css_class = $itemcount%2 ? ' class="LC_odd_row"' : ''; + $datatable .= ''. + $choices{'mysqltables'}. + ''. + ''. + ''; + foreach my $type (@types) { + $datatable .= ''; + } + $datatable .= '
'.&mt($type).'
'. + '
'."\n"; + $itemcount ++; + } $$rowtotal += $itemcount; return $datatable; @@ -3760,15 +4467,14 @@ sub print_validation_rows { sub print_usersessions { my ($position,$dom,$settings,$rowtotal) = @_; - my ($css_class,$datatable,%checked,%choices); - my (%by_ip,%by_location,@intdoms); - &build_location_hashes(\@intdoms,\%by_ip,\%by_location); + my ($css_class,$datatable,$itemcount,%checked,%choices); + my (%by_ip,%by_location,@intdoms,@instdoms); + &build_location_hashes(\@intdoms,\%by_ip,\%by_location,\@instdoms); my @alldoms = &Apache::lonnet::all_domains(); my %serverhomes = %Apache::lonnet::serverhomeIDs; my %servers = &Apache::lonnet::internet_dom_servers($dom); my %altids = &id_for_thisdom(%servers); - my $itemcount = 1; if ($position eq 'top') { if (keys(%serverhomes) > 1) { my %spareid = ¤t_offloads_to($dom,$settings,\%servers); @@ -3781,118 +4487,226 @@ sub print_usersessions { $datatable .= &spares_row($dom,\%servers,\%spareid,\%serverhomes,\%altids,$curroffloadnow,$rowtotal); } else { $datatable .= ''. - &mt('Nothing to set here, as the cluster to which this domain belongs only contains one server.'); + &mt('Nothing to set here, as the cluster to which this domain belongs only contains one server.'). + ''; } } else { - if (keys(%by_location) == 0) { - $datatable .= ''. - &mt('Nothing to set here, as the cluster to which this domain belongs only contains one institution.'); + my %titles = &usersession_titles(); + my ($prefix,@types); + if ($position eq 'bottom') { + $prefix = 'remote'; + @types = ('version','excludedomain','includedomain'); } else { - my %lt = &usersession_titles(); - my $numinrow = 5; - my $prefix; - my @types; - if ($position eq 'bottom') { - $prefix = 'remote'; - @types = ('version','excludedomain','includedomain'); - } else { - $prefix = 'hosted'; - @types = ('excludedomain','includedomain'); - } - my (%current,%checkedon,%checkedoff); - my @lcversions = &Apache::lonnet::all_loncaparevs(); - my @locations = sort(keys(%by_location)); - 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') { + $prefix = 'hosted'; + @types = ('excludedomain','includedomain'); + } + ($datatable,$itemcount) = &rules_by_location($settings,$prefix,\%by_location,\%by_ip,\@types,\%titles); + } + $$rowtotal += $itemcount; + return $datatable; +} + +sub rules_by_location { + my ($settings,$prefix,$by_location,$by_ip,$types,$titles) = @_; + my ($datatable,$itemcount,$css_class); + if (keys(%{$by_location}) == 0) { + $css_class = $itemcount%2 ? ' class="LC_odd_row"' : ''; + $datatable = ''. + &mt('Nothing to set here, as the cluster to which this domain belongs only contains one institution.'). + ''; + $itemcount = 1; + } else { + $itemcount = 0; + my $numinrow = 5; + my (%current,%checkedon,%checkedoff); + my @locations = sort(keys(%{$by_location})); + 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) { - next if ($type ne 'version' && !@locations); - $css_class = $itemcount%2 ? ' class="LC_odd_row"' : ''; - $datatable .= ' - '.$lt{$type}.'
-   -   - '; - if ($type eq 'version') { - my $selector = ''.&mt('Not in use').'  + '; + if ($type eq 'version') { + my @lcversions = &Apache::lonnet::all_loncaparevs(); + my $selector = ' '; - $datatable .= &mt('remote server must be version: [_1] or later',$selector); - } else { - $datatable.= '
'.(' 'x2). - ''. - "\n". - '
'; - my $rem; - for (my $i=0; $i<@locations; $i++) { - my ($showloc,$value,$checkedtype); - if (ref($by_location{$locations[$i]}) eq 'ARRAY') { - my $ip = $by_location{$locations[$i]}->[0]; - if (ref($by_ip{$ip}) eq 'ARRAY') { - $value = join(':',@{$by_ip{$ip}}); - $showloc = join(', ',@{$by_ip{$ip}}); - if (ref($current{$type}) eq 'ARRAY') { - foreach my $loc (@{$by_ip{$ip}}) { - if (grep(/^\Q$loc\E$/,@{$current{$type}})) { - $checkedtype = ' checked="checked"'; - last; - } + $selector .= ' '; + } + $selector .= ' '; + $datatable .= &mt('remote server must be version: [_1] or later',$selector); + } else { + $datatable.= '
'.(' 'x2). + ''. + "\n". + '
'; + my $rem; + for (my $i=0; $i<@locations; $i++) { + my ($showloc,$value,$checkedtype); + if (ref($by_location->{$locations[$i]}) eq 'ARRAY') { + my $ip = $by_location->{$locations[$i]}->[0]; + if (ref($by_ip->{$ip}) eq 'ARRAY') { + $value = join(':',@{$by_ip->{$ip}}); + $showloc = join(', ',@{$by_ip->{$ip}}); + if (ref($current{$type}) eq 'ARRAY') { + foreach my $loc (@{$by_ip->{$ip}}) { + if (grep(/^\Q$loc\E$/,@{$current{$type}})) { + $checkedtype = ' checked="checked"'; + last; } } } } - $rem = $i%($numinrow); - if ($rem == 0) { - if ($i > 0) { - $datatable .= ''; - } - $datatable .= ''; - } - $datatable .= ''; } - $rem = @locations%($numinrow); - my $colsleft = $numinrow - $rem; - if ($colsleft > 1 ) { - $datatable .= ''; - } elsif ($colsleft == 1) { - $datatable .= ''; + $rem = $i%($numinrow); + if ($rem == 0) { + if ($i > 0) { + $datatable .= ''; + } + $datatable .= ''; + } + $datatable .= ''; + } + $rem = @locations%($numinrow); + my $colsleft = $numinrow - $rem; + if ($colsleft > 1 ) { + $datatable .= ''; + } elsif ($colsleft == 1) { + $datatable .= ''; + } + $datatable .= '
'. - ''. - '  
'. + ''. + '  
'; + } + $datatable .= ''; + $itemcount ++; + } + } + return ($datatable,$itemcount); +} + +sub print_ssl { + my ($position,$dom,$settings,$rowtotal) = @_; + my ($css_class,$datatable); + my $itemcount = 1; + if ($position eq 'top') { + my $primary_id = &Apache::lonnet::domain($dom,'primary'); + my $intdom = &Apache::lonnet::internet_dom($primary_id); + my $same_institution; + if ($intdom ne '') { + my $internet_names = &Apache::lonnet::get_internet_names($Apache::lonnet::perlvar{'lonHostID'}); + if (ref($internet_names) eq 'ARRAY') { + if (grep(/^\Q$intdom\E$/,@{$internet_names})) { + $same_institution = 1; + } + } + } + $css_class = $itemcount%2?' class="LC_odd_row"':''; + $datatable = ''; + if ($same_institution) { + my %domservers = &Apache::lonnet::get_servers($dom); + $datatable .= &LONCAPA::SSL::print_certstatus(\%domservers,'web','domprefs'); + } else { + $datatable .= &mt("You need to be logged into one of your own domain's servers to display information about the status of LON-CAPA SSL certificates."); + } + $datatable .= ''; + $itemcount ++; + } else { + my %titles = &ssl_titles(); + my (%by_ip,%by_location,@intdoms,@instdoms); + &build_location_hashes(\@intdoms,\%by_ip,\%by_location,\@instdoms); + my @alldoms = &Apache::lonnet::all_domains(); + my %serverhomes = %Apache::lonnet::serverhomeIDs; + my @domservers = &Apache::lonnet::get_servers($dom); + my %servers = &Apache::lonnet::internet_dom_servers($dom); + my %altids = &id_for_thisdom(%servers); + if ($position eq 'middle') { + foreach my $type ('dom','intdom','other') { + my %checked; + $css_class = $itemcount%2?' class="LC_odd_row"':''; + $datatable .= ''.$titles{$type}.''. + ''; + my $skip; + if ($type eq 'dom') { + unless (keys(%servers) > 1) { + $datatable .= &mt('Nothing to set here, as there are no other servers/VMs'); + $skip = 1; + } + } + if ($type eq 'intdom') { + unless (@instdoms > 1) { + $datatable .= &mt('Nothing to set here, as there are no other domains for this institution'); + $skip = 1; + } + } elsif ($type eq 'other') { + if (keys(%by_location) == 0) { + $datatable .= &mt('Nothing to set here, as there are no other institutions'); + $skip = 1; + } + } + unless ($skip) { + $checked{'yes'} = ' checked="checked"'; + if (ref($settings) eq 'HASH') { + if (ref($settings->{'connect'}) eq 'HASH') { + if ($settings->{'connect'}->{$type} =~ /^(no|req)$/) { + $checked{$1} = $checked{'yes'}; + delete($checked{'yes'}); + } + } + } + foreach my $option ('no','yes','req') { + $datatable .= ''.(' 'x2); } - $datatable .= ''; } $datatable .= ''; + $itemcount ++; + } + } else { + my $prefix = 'replication'; + my @types = ('certreq','nocertreq'); + if (keys(%by_location) == 0) { + $datatable .= ''. + &mt('Nothing to set here, as there are no other institutions'). + ''; $itemcount ++; + } else { + ($datatable,$itemcount) = + &rules_by_location($settings,$prefix,\%by_location,\%by_ip,\@types,\%titles); } } } @@ -3900,10 +4714,59 @@ sub print_usersessions { return $datatable; } +sub ssl_titles { + return &Apache::lonlocal::texthash ( + dom => 'LON-CAPA servers/VMs from same domain', + intdom => 'LON-CAPA servers/VMs from same "internet" domain', + other => 'External LON-CAPA servers/VMs', + connect => 'Connections to other servers', + replication => 'Replicating content to other institutions', + certreq => 'Client certificate required, but specific domains exempt', + nocertreq => 'No client certificate required, except for specific domains', + no => 'SSL not used', + yes => 'SSL Optional (used if available)', + req => 'SSL Required', + ); +} + +sub print_trust { + my ($prefix,$dom,$settings,$rowtotal) = @_; + my ($css_class,$datatable,%checked,%choices); + my (%by_ip,%by_location,@intdoms,@instdoms); + &build_location_hashes(\@intdoms,\%by_ip,\%by_location,\@instdoms); + my $itemcount = 1; + my %titles = &trust_titles(); + my @types = ('exc','inc'); + if ($prefix eq 'top') { + $prefix = 'content'; + } elsif ($prefix eq 'bottom') { + $prefix = 'msg'; + } + ($datatable,$itemcount) = &rules_by_location($settings,$prefix,\%by_location,\%by_ip,\@types,\%titles); + $$rowtotal += $itemcount; + return $datatable; +} + +sub trust_titles { + return &Apache::lonlocal::texthash( + content => "Access to this domain's content by others", + shared => "Access to other domain's content by this domain", + enroll => "Enrollment in this domain's courses by others", + othcoau => "Co-author roles in this domain for others", + coaurem => "Co-author roles for this domain's users elsewhere", + domroles => "Domain roles in this domain assignable to others", + catalog => "Course Catalog for this domain displayed elsewhere", + reqcrs => "Requests for creation of courses in this domain by others", + msg => "Users in other domains can send messages to this domain", + exc => "Allow all, but exclude specific domains", + inc => "Deny all, but include specific domains", + ); +} + sub build_location_hashes { - my ($intdoms,$by_ip,$by_location) = @_; + my ($intdoms,$by_ip,$by_location,$instdoms) = @_; return unless((ref($intdoms) eq 'ARRAY') && (ref($by_ip) eq 'HASH') && - (ref($by_location) eq 'HASH')); + (ref($by_location) eq 'HASH') && (ref($instdoms) eq 'ARRAY')); my %iphost = &Apache::lonnet::get_iphost(); my $primary_id = &Apache::lonnet::domain($env{'request.role.domain'},'primary'); my $primary_ip = &Apache::lonnet::get_host_ip($primary_id); @@ -3920,7 +4783,13 @@ sub build_location_hashes { foreach my $id (@{$iphost{$ip}}) { my $location = &Apache::lonnet::internet_dom($id); if ($location) { - next if (grep(/^\Q$location\E$/,@{$intdoms})); + if (grep(/^\Q$location\E$/,@{$intdoms})) { + my $dom = &Apache::lonnet::host_domain($id); + unless (grep(/^\Q$dom\E/,@{$instdoms})) { + push(@{$instdoms},$dom); + } + next; + } if (ref($by_ip->{$ip}) eq 'ARRAY') { unless(grep(/^\Q$location\E$/,@{$by_ip->{$ip}})) { push(@{$by_ip->{$ip}},$location); @@ -4267,6 +5136,9 @@ sub print_loadbalancing { my ($numspares,@spares) = &count_servers($lonhost,%servers); my @sparestypes = ('primary','default'); my %typetitles = &sparestype_titles(); + my %hostherechecked = ( + no => ' checked="checked"', + ); foreach my $sparetype (@sparestypes) { my $targettable; for (my $i=0; $i<$numspares; $i++) { @@ -4312,6 +5184,23 @@ sub print_loadbalancing { $datatable .= ''.$typetitles{$sparetype}.'
'. ''.$targettable.'

'; } + $hostherechecked{$sparetype} = ''; + if (ref($currtargets{$lonhost}) eq 'HASH') { + if (ref($currtargets{$lonhost}{$sparetype}) eq 'ARRAY') { + if (grep(/^\Q$lonhost\E$/,@{$currtargets{$lonhost}{$sparetype}})) { + $hostherechecked{$sparetype} = ' checked="checked"'; + $hostherechecked{'no'} = ''; + } + } + } + } + $datatable .= &mt('Hosting on balancer itself').'
'. + '
'; + foreach my $sparetype (@sparestypes) { + $datatable .= '
'; } $datatable .= '
'. &loadbalancing_rules($dom,$intdom,$currrules{$lonhost}, @@ -4529,14 +5418,15 @@ sub sparestype_titles { 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', - 'lonstatusmail' => 'E-mail from nightly status check (warnings/errors)', - 'requestsmail' => 'E-mail from course requests requiring approval', - 'updatesmail' => 'E-mail from nightly check of LON-CAPA module integrity/updates', + '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 for this domain's users", + 'otherdomsmail' => 'Helpdesk requests for other (unconfigured) domains', + 'lonstatusmail' => 'E-mail from nightly status check (warnings/errors)', + 'requestsmail' => 'E-mail from course requests requiring approval', + 'updatesmail' => 'E-mail from nightly check of LON-CAPA module integrity/updates', 'idconflictsmail' => 'E-mail from bi-nightly check for multiple users sharing same student/employee ID', ); my %short_titles = &Apache::lonlocal::texthash ( @@ -4546,6 +5436,34 @@ sub contact_titles { return (\%titles,\%short_titles); } +sub helpform_fields { + my %titles = &Apache::lonlocal::texthash ( + 'username' => 'Name', + 'user' => 'Username/domain', + 'phone' => 'Phone', + 'cc' => 'Cc e-mail', + 'course' => 'Course Details', + 'section' => 'Sections', + 'screenshot' => 'File upload', + ); + my @fields = ('username','phone','user','course','section','cc','screenshot'); + my %possoptions = ( + username => ['yes','no','req'], + phone => ['yes','no','req'], + user => ['yes','no'], + cc => ['yes','no'], + course => ['yes','no'], + section => ['yes','no'], + screenshot => ['yes','no'], + ); + my %fieldoptions = &Apache::lonlocal::texthash ( + 'yes' => 'Optional', + 'req' => 'Required', + 'no' => "Not shown", + ); + return (\@fields,\%titles,\%fieldoptions,\%possoptions); +} + sub tool_titles { my %titles = &Apache::lonlocal::texthash ( aboutme => 'Personal web page', @@ -5838,9 +6756,9 @@ sub print_serverstatuses { sub serverstatus_pages { return ('userstatus','lonstatus','loncron','server-status','codeversions', - 'checksums','clusterstatus','metadata_keywords','metadata_harvest', - 'takeoffline','takeonline','showenv','toggledebug','ping','domconf', - 'uniquecodes','diskusage','coursecatalog'); + 'checksums','clusterstatus','certstatus','metadata_keywords', + 'metadata_harvest','takeoffline','takeonline','showenv','toggledebug', + 'ping','domconf','uniquecodes','diskusage','coursecatalog'); } sub defaults_javascript { @@ -7924,7 +8842,7 @@ sub modify_quotas { } if ($env{'form.validationdc'}) { my $newval = $env{'form.validationdc'}; - my %domcoords = &get_active_dcs($dom); + my %domcoords = &Apache::lonnet::get_active_domroles($dom,['dc']); if (exists($domcoords{$newval})) { $confhash{'validation'}{'dc'} = $newval; } @@ -8435,6 +9353,10 @@ sub modify_ltitools { } } } + my @courseconfig = &Apache::loncommon::get_env_multiple('form.ltitools_courseconfig'); + foreach my $item (@courseconfig) { + $confhash{$newid}{'crsconf'}{$item} = 1; + } if ($env{'form.ltitools_add_custom'}) { my $name = $env{'form.ltitools_add_custom_name'}; my $value = $env{'form.ltitools_add_custom_value'}; @@ -8522,6 +9444,19 @@ sub modify_ltitools { $changes{$itemid} = 1; } } + my @courseconfig = &Apache::loncommon::get_env_multiple('form.ltitools_courseconfig_'.$i); + foreach my $item ('label','title','target') { + if (grep(/^\Q$item\E$/,@courseconfig)) { + $confhash{$itemid}{'crsconf'}{$item} = 1; + if (ref($domconfig{$action}{$itemid}{'crsconf'}) eq 'HASH') { + if ($domconfig{$action}{$itemid}{'crsconf'}{$item} ne $confhash{$itemid}{'crsconf'}{$item}) { + $changes{$itemid} = 1; + } + } else { + $changes{$itemid} = 1; + } + } + } my @fields = &Apache::loncommon::get_env_multiple('form.ltitools_fields_'.$i); foreach my $field (@fields) { if ($possfield{$field}) { @@ -8685,6 +9620,21 @@ sub modify_ltitools { my $num = length($confhash{$itemid}{'secret'}); $resulttext .= ('*'x$num).''; } + $resulttext .= '
  • '.&mt('Configurable in course:'); + my @possconfig = ('label','title','target'); + my $numconfig = 0; + if (ref($confhash{$itemid}{'crsconf'}) eq 'HASH') { + foreach my $item (@possconfig) { + if ($confhash{$itemid}{'crsconf'}{$item}) { + $numconfig ++; + $resulttext .= ' '.$lt{'crs'.$item}; + } + } + } + if (!$numconfig) { + $resulttext .= &mt('None'); + } + $resulttext .= '
  • '; foreach my $item ('passback','roster') { $resulttext .= '
  • '.$lt{$item}.' '; if ($confhash{$itemid}{$item}) { @@ -8852,7 +9802,8 @@ sub modify_autoenroll { my $autorun = &Apache::lonnet::auto_run(undef,$dom), my %title = ( run => 'Auto-enrollment active', sender => 'Sender for notification messages', - coowners => 'Automatic assignment of co-ownership to instructors of record (institutional data)'); + coowners => 'Automatic assignment of co-ownership to instructors of record (institutional data)', + failsafe => 'Failsafe for no drops if institutional data missing for a section'); my @offon = ('off','on'); my $sender_uname = $env{'form.sender_uname'}; my $sender_domain = $env{'form.sender_domain'}; @@ -8862,11 +9813,17 @@ sub modify_autoenroll { $sender_domain = ''; } my $coowners = $env{'form.autoassign_coowners'}; + my $failsafe = $env{'form.autoenroll_failsafe'}; + $failsafe =~ s{^\s+|\s+$}{}g; + if ($failsafe =~ /\D/) { + undef($failsafe); + } my %autoenrollhash = ( autoenroll => { 'run' => $env{'form.autoenroll_run'}, 'sender_uname' => $sender_uname, 'sender_domain' => $sender_domain, 'co-owners' => $coowners, + 'autofailsafe' => $failsafe, } ); my $putresult = &Apache::lonnet::put_dom('configuration',\%autoenrollhash, @@ -8893,7 +9850,10 @@ sub modify_autoenroll { } } elsif ($coowners) { $changes{'coowners'} = 1; - } + } + if ($currautoenroll{'autofailsafe'} ne $failsafe) { + $changes{'autofailsafe'} = 1; + } if (keys(%changes) > 0) { $resulttext = &mt('Changes made:').'
      '; if ($changes{'run'}) { @@ -8913,6 +9873,17 @@ sub modify_autoenroll { $lastactref->{'domainconfig'} = 1; } } + if ($changes{'autofailsafe'}) { + if ($failsafe ne '') { + $resulttext .= '
    • '.&mt("$title{'failsafe'} set to [_1]",$failsafe).'
    • '; + } else { + $resulttext .= '
    • '.&mt("$title{'failsafe'} deleted"); + } + &Apache::lonnet::get_domain_defaults($dom,1); + if (ref($lastactref) eq 'HASH') { + $lastactref->{'domdefaults'} = 1; + } + } $resulttext .= '
    '; } else { $resulttext = &mt('No changes made to auto-enrollment settings'); @@ -9128,7 +10099,7 @@ sub modify_autocreate { $newvals{$item} = 0 if ($newvals{$item} eq ''); } $newvals{'xmldc'} = $env{'form.autocreate_xmldc'}; - my %domcoords = &get_active_dcs($dom); + my %domcoords = &Apache::lonnet::get_active_domroles($dom,['dc']); unless (exists($domcoords{$newvals{'xmldc'}})) { $newvals{'xmldc'} = ''; } @@ -9193,8 +10164,10 @@ sub modify_directorysrch { $currdirsrch{$key} = $domconfig{'directorysrch'}{$key}; } } - my %title = ( available => 'Directory search available', - localonly => 'Other domains can search', + my %title = ( available => 'Institutional directory search available', + localonly => 'Other domains can search institution', + lcavailable => 'LON-CAPA directory search available', + lclocalonly => 'Other domains can search LON-CAPA domain', searchby => 'Search types', searchtypes => 'Search latitude'); my @offon = ('off','on'); @@ -9268,7 +10241,9 @@ sub modify_directorysrch { my %dirsrch_hash = ( directorysrch => { available => $env{'form.dirsrch_available'}, cansearch => \@cansearch, - localonly => $env{'form.dirsrch_localonly'}, + localonly => $env{'form.dirsrch_instlocalonly'}, + lclocalonly => $env{'form.dirsrch_domlocalonly'}, + lcavailable => $env{'form.dirsrch_domavailable'}, searchby => \@searchby, searchtypes => \@searchtypes, } @@ -9285,24 +10260,47 @@ sub modify_directorysrch { $changes{'available'} = 1; } } + if (exists($currdirsrch{'lcavailable'})) { + if ($currdirsrch{'lcavailable'} ne $env{'form.dirsrch_domavailable'}) { + $changes{'lcavailable'} = 1; + } + } else { + if ($env{'form.dirsrch_lcavailable'} eq '1') { + $changes{'lcavailable'} = 1; + } + } if (exists($currdirsrch{'localonly'})) { - if ($currdirsrch{'localonly'} ne $env{'form.dirsrch_localonly'}) { + if ($currdirsrch{'localonly'} ne $env{'form.dirsrch_instlocalonly'}) { $changes{'localonly'} = 1; } } else { - if ($env{'form.dirsrch_localonly'} eq '1') { + if ($env{'form.dirsrch_instlocalonly'} eq '1') { $changes{'localonly'} = 1; } } + if (exists($currdirsrch{'lclocalonly'})) { + if ($currdirsrch{'lclocalonly'} ne $env{'form.dirsrch_domlocalonly'}) { + $changes{'lclocalonly'} = 1; + } + } else { + if ($env{'form.dirsrch_domlocalonly'} eq '1') { + $changes{'lclocalonly'} = 1; + } + } if (keys(%changes) > 0) { $resulttext = &mt('Changes made:').'
      '; if ($changes{'available'}) { $resulttext .= '
    • '.&mt("$title{'available'} set to: $offon[$env{'form.dirsrch_available'}]").'
    • '; } + if ($changes{'lcavailable'}) { + $resulttext .= '
    • '.&mt("$title{'lcavailable'} set to: $offon[$env{'form.dirsrch_domavailable'}]").'
    • '; + } if ($changes{'localonly'}) { - $resulttext .= '
    • '.&mt("$title{'localonly'} set to: $otherdoms[$env{'form.dirsrch_localonly'}]").'
    • '; + $resulttext .= '
    • '.&mt("$title{'localonly'} set to: $otherdoms[$env{'form.dirsrch_instlocalonly'}]").'
    • '; } - + if ($changes{'lclocalonly'}) { + $resulttext .= '
    • '.&mt("$title{'lclocalonly'} set to: $otherdoms[$env{'form.dirsrch_domlocalonly'}]").'
    • '; + } if (ref($changes{'cansearch'}) eq 'ARRAY') { my $chgtext; if (ref($usertypes) eq 'HASH') { @@ -9353,7 +10351,7 @@ sub modify_directorysrch { } $resulttext .= '
    '; } else { - $resulttext = &mt('No changes made to institution directory search settings'); + $resulttext = &mt('No changes made to directory search settings'); } } else { $resulttext = ''. @@ -9370,11 +10368,12 @@ sub modify_contacts { $currsetting{$key} = $domconfig{'contacts'}{$key}; } } - my (%others,%to,%bcc); + my (%others,%to,%bcc,%includestr,%includeloc); my @contacts = ('supportemail','adminemail'); - my @mailings = ('errormail','packagesmail','helpdeskmail','lonstatusmail', - 'requestsmail','updatesmail','idconflictsmail'); + my @mailings = ('errormail','packagesmail','helpdeskmail','otherdomsmail', + 'lonstatusmail','requestsmail','updatesmail','idconflictsmail'); my @toggles = ('reporterrors','reportupdates'); + my ($fields,$fieldtitles,$fieldoptions,$possoptions) = &helpform_fields(); foreach my $type (@mailings) { @{$newsetting{$type}} = &Apache::loncommon::get_env_multiple('form.'.$type); @@ -9387,9 +10386,14 @@ sub modify_contacts { } $others{$type} = $env{'form.'.$type.'_others'}; $contacts_hash{contacts}{$type}{'others'} = $others{$type}; - if ($type eq 'helpdeskmail') { + if (($type eq 'helpdeskmail') || ($type eq 'otherdomsmail')) { $bcc{$type} = $env{'form.'.$type.'_bcc'}; $contacts_hash{contacts}{$type}{'bcc'} = $bcc{$type}; + if (($env{'form.'.$type.'_includestr'} ne '') && ($env{'form.'.$type.'_includeloc'} =~ /^s|b$/)) { + $includestr{$type} = $env{'form.'.$type.'_includestr'}; + $includeloc{$type} = $env{'form.'.$type.'_includeloc'}; + $contacts_hash{contacts}{$type}{'include'} = $includeloc{$type}.':'.&escape($includestr{$type}); + } } } foreach my $item (@contacts) { @@ -9401,6 +10405,23 @@ sub modify_contacts { $contacts_hash{'contacts'}{$item} = $env{'form.'.$item}; } } + if ((ref($fields) eq 'ARRAY') && (ref($possoptions) eq 'HASH')) { + foreach my $field (@{$fields}) { + if (ref($possoptions->{$field}) eq 'ARRAY') { + my $value = $env{'form.helpform_'.$field}; + $value =~ s/^\s+|\s+$//g; + if (grep(/^\Q$value\E$/,@{$possoptions->{$field}})) { + $contacts_hash{contacts}{'helpform'}{$field} = $value; + if ($field eq 'screenshot') { + $env{'form.helpform_maxsize'} =~ s/^\s+|\s+$//g; + if ($env{'form.helpform_maxsize'} =~ /^\d+\.?\d*$/) { + $contacts_hash{contacts}{'helpform'}{'maxsize'} = $env{'form.helpform_maxsize'}; + } + } + } + } + } + } if (keys(%currsetting) > 0) { foreach my $item (@contacts) { if ($to{$item} ne $currsetting{$item}) { @@ -9420,10 +10441,39 @@ sub modify_contacts { if ($others{$type} ne $currsetting{$type}{'others'}) { push(@{$changes{$type}},'others'); } - if ($type eq 'helpdeskmail') { + if (($type eq 'helpdeskmail') || ($type eq 'otherdomsmail')) { if ($bcc{$type} ne $currsetting{$type}{'bcc'}) { push(@{$changes{$type}},'bcc'); } + my ($currloc,$currstr) = split(/:/,$currsetting{$type}{'include'},2); + if (($includeloc{$type} ne $currloc) || (&escape($includestr{$type}) ne $currstr)) { + push(@{$changes{$type}},'include'); + } + } + } + if (ref($fields) eq 'ARRAY') { + if (ref($currsetting{'helpform'}) eq 'HASH') { + foreach my $field (@{$fields}) { + if ($currsetting{'helpform'}{$field} ne $contacts_hash{'contacts'}{'helpform'}{$field}) { + push(@{$changes{'helpform'}},$field); + } + if (($field eq 'screenshot') && ($contacts_hash{'contacts'}{'helpform'}{'screenshot'} ne 'no')) { + if ($currsetting{'helpform'}{'maxsize'} ne $contacts_hash{'contacts'}{'helpform'}{'maxsize'}) { + push(@{$changes{'helpform'}},'maxsize'); + } + } + } + } else { + foreach my $field (@{$fields}) { + if ($contacts_hash{'contacts'}{'helpform'}{$field} ne 'yes') { + push(@{$changes{'helpform'}},$field); + } + if (($field eq 'screenshot') && ($contacts_hash{'contacts'}{'helpform'}{'screenshot'} ne 'no')) { + if ($contacts_hash{'contacts'}{'helpform'}{'maxsize'} != 1) { + push(@{$changes{'helpform'}},'maxsize'); + } + } + } } } } else { @@ -9433,28 +10483,43 @@ sub modify_contacts { $default{'errormail'} = 'adminemail'; $default{'packagesmail'} = 'adminemail'; $default{'helpdeskmail'} = 'supportemail'; + $default{'otherdomsmail'} = 'supportemail'; $default{'lonstatusmail'} = 'adminemail'; $default{'requestsmail'} = 'adminemail'; $default{'updatesmail'} = 'adminemail'; foreach my $item (@contacts) { if ($to{$item} ne $default{$item}) { - $changes{$item} = 1; + $changes{$item} = 1; } } foreach my $type (@mailings) { if ((@{$newsetting{$type}} != 1) || ($newsetting{$type}[0] ne $default{$type})) { - push(@{$changes{$type}},@{$newsetting{$type}}); } if ($others{$type} ne '') { push(@{$changes{$type}},'others'); } - if ($type eq 'helpdeskmail') { + if (($type eq 'helpdeskmail') || ($type eq 'otherdomsmail')) { if ($bcc{$type} ne '') { push(@{$changes{$type}},'bcc'); } + if (($includeloc{$type} =~ /^b|s$/) && ($includestr{$type} ne '')) { + push(@{$changes{$type}},'include'); + } } } + if (ref($fields) eq 'ARRAY') { + foreach my $field (@{$fields}) { + if ($contacts_hash{'contacts'}{'helpform'}{$field} ne 'yes') { + push(@{$changes{'helpform'}},$field); + } + if (($field eq 'screenshot') && ($contacts_hash{'contacts'}{'helpform'}{'screenshot'} ne 'no')) { + if ($contacts_hash{'contacts'}{'helpform'}{'maxsize'} != 1) { + push(@{$changes{'helpform'}},'maxsize'); + } + } + } + } } foreach my $item (@toggles) { if (($env{'form.'.$item} == 1) && ($currsetting{$item} == 0)) { @@ -9484,7 +10549,11 @@ sub modify_contacts { } foreach my $type (@mailings) { if (ref($changes{$type}) eq 'ARRAY') { - $resulttext .= '
  • '.$titles->{$type}.': '; + if (($type eq 'helpdeskmail') || ($type eq 'otherdomsmail')) { + $resulttext .= '
  • '.$titles->{$type}.' -- '.&mt('sent to').': '; + } else { + $resulttext .= '
  • '.$titles->{$type}.': '; + } my @text; foreach my $item (@{$newsetting{$type}}) { push(@text,$short_titles->{$item}); @@ -9492,12 +10561,31 @@ sub modify_contacts { if ($others{$type} ne '') { push(@text,$others{$type}); } - $resulttext .= ''. - join(', ',@text).''; - if ($type eq 'helpdeskmail') { + if (@text) { + $resulttext .= ''. + join(', ',@text).''; + } + if (($type eq 'helpdeskmail') || ($type eq 'otherdomsmail')) { if ($bcc{$type} ne '') { - $resulttext .= ' '.&mt('with Bcc to').': '.$bcc{$type}.''; + my $bcctext; + if (@text) { + $bcctext = ' '.&mt('with Bcc to'); + } else { + $bcctext = '(Bcc)'; + } + $resulttext .= $bcctext.': '.$bcc{$type}.''; + } elsif (!@text) { + $resulttext .= &mt('No one'); + } + if ($includestr{$type} ne '') { + if ($includeloc{$type} eq 'b') { + $resulttext .= '
    '.&mt('Text automatically added to e-mail body:').' '.$includestr{$type}; + } elsif ($includeloc{$type} eq 's') { + $resulttext .= '
    '.&mt('Text automatically added to e-mail subject:').' '.$includestr{$type}; + } } + } elsif (!@text) { + $resulttext .= &mt('No recipients'); } $resulttext .= '
  • '; } @@ -9519,6 +10607,47 @@ sub modify_contacts { &mt('LON-CAPA core group - MSU'),600,500)). ''; } + if ((ref($changes{'helpform'}) eq 'ARRAY') && (ref($fields) eq 'ARRAY')) { + my (@optional,@required,@unused,$maxsizechg); + foreach my $field (@{$changes{'helpform'}}) { + if ($field eq 'maxsize') { + $maxsizechg = 1; + next; + } + if ($contacts_hash{'contacts'}{'helpform'}{$field} eq 'yes') { + push(@optional,$field); + } elsif ($contacts_hash{'contacts'}{'helpform'}{$field} eq 'no') { + push(@unused,$field); + } elsif ($contacts_hash{'contacts'}{'helpform'}{$field} eq 'req') { + push(@required,$field); + } + } + if (@optional) { + $resulttext .= '
  • '. + &mt('Help form fields changed to "Optional": [_1].', + ''.join(', ',map { $fieldtitles->{$_}; } @optional)).''. + '
  • '; + } + if (@required) { + $resulttext .= '
  • '. + &mt('Help form fields changed to "Required": [_1].', + ''.join(', ',map { $fieldtitles->{$_}; } @required)).''. + '
  • '; + } + if (@unused) { + $resulttext .= '
  • '. + &mt('Help form fields changed to "Not shown": [_1].', + ''.join(', ',map { $fieldtitles->{$_}; } @unused)).''. + '
  • '; + } + if ($maxsizechg) { + $resulttext .= '
  • '. + &mt('Max size for file uploaded to help form by logged-in user set to [_1] MB.', + $contacts_hash{'contacts'}{'helpform'}{'maxsize'}). + '
  • '; + + } + } $resulttext .= ''; } else { $resulttext = &mt('No changes made to contact information'); @@ -11287,32 +12416,208 @@ sub modify_serverstatuses { } sub modify_helpsettings { - my ($r,$dom,$confname,%domconfig) = @_; + my ($r,$dom,$confname,$lastactref,%domconfig) = @_; my ($resulttext,$errors,%changes,%helphash); my %defaultchecked = ('submitbugs' => 'on'); my @offon = ('off','on'); my @toggles = ('submitbugs'); + my %current = ('submitbugs' => '', + 'adhoc' => {}, + ); if (ref($domconfig{'helpsettings'}) eq 'HASH') { - foreach my $item (@toggles) { - if ($defaultchecked{$item} eq 'on') { - if ($domconfig{'helpsettings'}{$item} eq '') { - if ($env{'form.'.$item} eq '0') { - $changes{$item} = 1; - } - } elsif ($domconfig{'helpsettings'}{$item} ne $env{'form.'.$item}) { + %current = %{$domconfig{'helpsettings'}}; + } + my %domdefaults = &Apache::lonnet::get_domain_defaults($dom,1); + foreach my $item (@toggles) { + if ($defaultchecked{$item} eq 'on') { + if ($current{$item} eq '') { + if ($env{'form.'.$item} eq '0') { $changes{$item} = 1; } - } elsif ($defaultchecked{$item} eq 'off') { - if ($domconfig{'helpsettings'}{$item} eq '') { - if ($env{'form.'.$item} eq '1') { - $changes{$item} = 1; - } - } elsif ($domconfig{'helpsettings'}{$item} ne $env{'form.'.$item}) { + } elsif ($current{$item} ne $env{'form.'.$item}) { + $changes{$item} = 1; + } + } elsif ($defaultchecked{$item} eq 'off') { + if ($current{$item} eq '') { + if ($env{'form.'.$item} eq '1') { $changes{$item} = 1; } + } elsif ($current{$item} ne $env{'form.'.$item}) { + $changes{$item} = 1; + } + } + if (($env{'form.'.$item} eq '0') || ($env{'form.'.$item} eq '1')) { + $helphash{'helpsettings'}{$item} = $env{'form.'.$item}; + } + } + my $maxnum = $env{'form.helproles_maxnum'}; + my $confname = $dom.'-domainconfig'; + my %existing=&Apache::lonnet::dump('roles',$dom,$confname,'rolesdef_'); + my (@allpos,%newsettings,%changedprivs,$newrole); + my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom); + my @accesstypes = ('all','none','status','inc','exc'); + my %domhelpdesk = &Apache::lonnet::get_active_domroles($dom,['dh']); + my %lt = &Apache::lonlocal::texthash( + s => 'system', + d => 'domain', + order => 'Display order', + access => 'Role usage', + all => 'All', + none => 'None', + status => 'Determined based on institutional status', + inc => 'Include all, but exclude specific personnel', + exc => 'Exclude all, but include specific personnel', + ); + for (my $num=0; $num<=$maxnum; $num++) { + my ($prefix,$identifier,$rolename,%curr); + if ($num == $maxnum) { + next unless ($env{'form.newcusthelp'} == $maxnum); + $identifier = 'custhelp'.$num; + $prefix = 'helproles_'.$num; + $rolename = $env{'form.custhelpname'.$num}; + $rolename=~s/[^A-Za-z0-9]//gs; + next if ($rolename eq ''); + next if (exists($existing{'rolesdef_'.$rolename})); + my %newprivs = &Apache::lonuserutils::custom_role_update($rolename,$identifier); + my $result = &Apache::lonnet::definerole($rolename,$newprivs{'s'},$newprivs{'d'}, + $newprivs{'c'},$confname,$dom); + if ($result ne 'ok') { + $errors .= '
  • '. + &mt('An error occurred storing the new custom role: [_1]', + $result).'
  • '; + next; + } else { + $changedprivs{$rolename} = \%newprivs; + $newrole = $rolename; + } + } else { + $prefix = 'helproles_'.$num; + $rolename = $env{'form.'.$prefix}; + next if ($rolename eq ''); + next unless (exists($existing{'rolesdef_'.$rolename})); + $identifier = 'custhelp'.$num; + my %newprivs = &Apache::lonuserutils::custom_role_update($rolename,$identifier); + my %currprivs; + ($currprivs{'s'},$currprivs{'d'},$currprivs{'c'}) = + split(/\_/,$existing{'rolesdef_'.$rolename}); + foreach my $level ('c','d','s') { + if ($newprivs{$level} ne $currprivs{$level}) { + my $result = &Apache::lonnet::definerole($rolename,$newprivs{'s'},$newprivs{'d'}, + $newprivs{'c'},$confname,$dom); + if ($result ne 'ok') { + $errors .= '
  • '. + &mt('An error occurred storing privileges for existing role [_1]: [_2]', + $rolename,$result).'
  • '; + } else { + $changedprivs{$rolename} = \%newprivs; + } + last; + } + } + if (ref($current{'adhoc'}) eq 'HASH') { + if (ref($current{'adhoc'}{$rolename}) eq 'HASH') { + %curr = %{$current{'adhoc'}{$rolename}}; + } } - if (($env{'form.'.$item} eq '0') || ($env{'form.'.$item} eq '1')) { - $helphash{'helpsettings'}{$item} = $env{'form.'.$item}; + } + my $newpos = $env{'form.'.$prefix.'_pos'}; + $newpos =~ s/\D+//g; + $allpos[$newpos] = $rolename; + my $newdesc = $env{'form.'.$prefix.'_desc'}; + $helphash{'helpsettings'}{'adhoc'}{$rolename}{'desc'} = $newdesc; + if ($curr{'desc'}) { + if ($curr{'desc'} ne $newdesc) { + $changes{'customrole'}{$rolename}{'desc'} = 1; + $newsettings{$rolename}{'desc'} = $newdesc; + } + } elsif ($newdesc ne '') { + $changes{'customrole'}{$rolename}{'desc'} = 1; + $newsettings{$rolename}{'desc'} = $newdesc; + } + my $access = $env{'form.'.$prefix.'_access'}; + if (grep(/^\Q$access\E$/,@accesstypes)) { + $helphash{'helpsettings'}{'adhoc'}{$rolename}{'access'} = $access; + if ($access eq 'status') { + my @statuses = &Apache::loncommon::get_env_multiple('form.'.$prefix.'_status'); + if (scalar(@statuses) == 0) { + $helphash{'helpsettings'}{'adhoc'}{$rolename}{'access'} = 'none'; + } else { + my (@shownstatus,$numtypes); + $helphash{'helpsettings'}{'adhoc'}{$rolename}{$access} = []; + if (ref($types) eq 'ARRAY') { + $numtypes = scalar(@{$types}); + foreach my $type (sort(@statuses)) { + if ($type eq 'default') { + push(@{$helphash{'helpsettings'}{'adhoc'}{$rolename}{$access}},$type); + } elsif (grep(/^\Q$type\E$/,@{$types})) { + push(@{$helphash{'helpsettings'}{'adhoc'}{$rolename}{$access}},$type); + push(@shownstatus,$usertypes->{$type}); + } + } + } + if (grep(/^default$/,@statuses)) { + push(@shownstatus,$othertitle); + } + if (scalar(@shownstatus) == 1+$numtypes) { + $helphash{'helpsettings'}{'adhoc'}{$rolename}{'access'} = 'all'; + delete($helphash{'helpsettings'}{'adhoc'}{$rolename}{'status'}); + } else { + $newsettings{$rolename}{'status'} = join(' '.&mt('or').' ',@shownstatus); + if (ref($curr{'status'}) eq 'ARRAY') { + my @diffs = &Apache::loncommon::compare_arrays($helphash{'helpsettings'}{'adhoc'}{$rolename}{$access},$curr{$access}); + if (@diffs) { + $changes{'customrole'}{$rolename}{$access} = 1; + } + } elsif (@{$helphash{'helpsettings'}{'adhoc'}{$rolename}{$access}}) { + $changes{'customrole'}{$rolename}{$access} = 1; + } + } + } + } elsif (($access eq 'inc') || ($access eq 'exc')) { + my @personnel = &Apache::loncommon::get_env_multiple('form.'.$prefix.'_staff_'.$access); + my @newspecstaff; + $helphash{'helpsettings'}{'adhoc'}{$rolename}{$access} = []; + foreach my $person (sort(@personnel)) { + if ($domhelpdesk{$person}) { + push(@{$helphash{'helpsettings'}{'adhoc'}{$rolename}{$access}},$person); + } + } + if (ref($curr{$access}) eq 'ARRAY') { + my @diffs = &Apache::loncommon::compare_arrays($helphash{'helpsettings'}{'adhoc'}{$rolename}{$access},$curr{$access}); + if (@diffs) { + $changes{'customrole'}{$rolename}{$access} = 1; + } + } elsif (@{$helphash{'helpsettings'}{'adhoc'}{$rolename}{$access}}) { + $changes{'customrole'}{$rolename}{$access} = 1; + } + foreach my $person (@{$helphash{'helpsettings'}{'adhoc'}{$rolename}{$access}}) { + my ($uname,$udom) = split(/:/,$person); + push(@newspecstaff,&Apache::loncommon::aboutmewrapper(&Apache::loncommon::plainname($uname,$udom,'lastname'),$uname,$udom)); + } + $newsettings{$rolename}{$access} = join(', ',sort(@newspecstaff)); + } + } else { + $helphash{'helpsettings'}{'adhoc'}{$rolename}{'access'}= 'all'; + } + unless ($curr{'access'} eq $access) { + $changes{'customrole'}{$rolename}{'access'} = 1; + $newsettings{$rolename}{'access'} = $lt{$helphash{'helpsettings'}{'adhoc'}{$rolename}{'access'}}; + } + } + if (@allpos > 0) { + my $idx = 0; + foreach my $rolename (@allpos) { + if ($rolename ne '') { + $helphash{'helpsettings'}{'adhoc'}{$rolename}{'order'} = $idx; + if (ref($current{'adhoc'}) eq 'HASH') { + if (ref($current{'adhoc'}{$rolename}) eq 'HASH') { + if ($current{'adhoc'}{$rolename}{'order'} ne $idx) { + $changes{'customrole'}{$rolename}{'order'} = 1; + $newsettings{$rolename}{'order'} = $idx+1; + } + } + } + $idx ++; } } } @@ -11320,25 +12625,115 @@ sub modify_helpsettings { if (keys(%changes) > 0) { $putresult = &Apache::lonnet::put_dom('configuration',\%helphash,$dom); if ($putresult eq 'ok') { - $resulttext = &mt('Changes made:').'
      '; + if (ref($helphash{'helpsettings'}) eq 'HASH') { + $domdefaults{'submitbugs'} = $helphash{'helpsettings'}{'submitbugs'}; + if (ref($helphash{'helpsettings'}{'adhoc'}) eq 'HASH') { + $domdefaults{'adhocroles'} = $helphash{'helpsettings'}{'adhoc'}; + } + } + my $cachetime = 24*60*60; + &Apache::lonnet::do_cache_new('domdefaults',$dom,\%domdefaults,$cachetime); + if (ref($lastactref) eq 'HASH') { + $lastactref->{'domdefaults'} = 1; + } + } else { + $errors .= '
    • '. + &mt('An error occurred storing the settings: [_1]', + $putresult).'
    • '; + } + } + if ((keys(%changes) && ($putresult eq 'ok')) || (keys(%changedprivs))) { + $resulttext = &mt('Changes made:').'
        '; + my (%shownprivs,@levelorder); + @levelorder = ('c','d','s'); + if ((keys(%changes)) && ($putresult eq 'ok')) { foreach my $item (sort(keys(%changes))) { if ($item eq 'submitbugs') { $resulttext .= '
      • '.&mt('Display link to: [_1] set to "'.$offon[$env{'form.'.$item}].'".', &Apache::loncommon::modal_link('http://bugs.loncapa.org', &mt('LON-CAPA bug tracker'),600,500)).'
      • '; + } elsif ($item eq 'customrole') { + if (ref($changes{'customrole'}) eq 'HASH') { + my @keyorder = ('order','desc','access','status','exc','inc'); + my %keytext = &Apache::lonlocal::texthash( + order => 'Order', + desc => 'Role description', + access => 'Role usage', + status => 'Allowed instituional types', + exc => 'Allowed personnel', + inc => 'Disallowed personnel', + ); + foreach my $role (sort(keys(%{$changes{'customrole'}}))) { + if (ref($changes{'customrole'}{$role}) eq 'HASH') { + if ($role eq $newrole) { + $resulttext .= '
      • '.&mt('New custom role added: [_1]', + $role).'
          '; + } else { + $resulttext .= '
        • '.&mt('Existing custom role modified: [_1]', + $role).'
            '; + } + foreach my $key (@keyorder) { + if ($changes{'customrole'}{$role}{$key}) { + $resulttext .= '
          • '.&mt("[_1] set to: [_2]", + $keytext{$key},$newsettings{$role}{$key}). + '
          • '; + } + } + if (ref($changedprivs{$role}) eq 'HASH') { + $shownprivs{$role} = 1; + $resulttext .= '
          • '.&mt('Privileges set to :').'
              '; + foreach my $level (@levelorder) { + foreach my $item (split(/\:/,$changedprivs{$role}{$level})) { + next if ($item eq ''); + my ($priv) = split(/\&/,$item,2); + if (&Apache::lonnet::plaintext($priv)) { + $resulttext .= '
            • '.&Apache::lonnet::plaintext($priv); + unless ($level eq 'c') { + $resulttext .= ' ('.$lt{$level}.')'; + } + $resulttext .= '
            • '; + } + } + } + $resulttext .= '
            '; + } + $resulttext .= '
        • '; + } + } + } } } - $resulttext .= '
        '; - } else { - $resulttext = &mt('No changes made to help settings'); - $errors .= '
      • '. - &mt('An error occurred storing the settings: [_1]', - $putresult).'
      • '; } + if (keys(%changedprivs)) { + foreach my $role (sort(keys(%changedprivs))) { + unless ($shownprivs{$role}) { + $resulttext .= '
      • '.&mt('Existing custom role modified: [_1]', + $role).'
          '. + '
        • '.&mt('Privileges set to :').'
            '; + foreach my $level (@levelorder) { + foreach my $item (split(/\:/,$changedprivs{$role}{$level})) { + next if ($item eq ''); + my ($priv) = split(/\&/,$item,2); + if (&Apache::lonnet::plaintext($priv)) { + $resulttext .= '
          • '.&Apache::lonnet::plaintext($priv); + unless ($level eq 'c') { + $resulttext .= ' ('.$lt{$level}.')'; + } + $resulttext .= '
          • '; + } + } + } + $resulttext .= '
      • '; + } + } + } + $resulttext .= '
      '; + } else { + $resulttext = &mt('No changes made to help settings'); } if ($errors) { $resulttext .= '
      '.&mt('The following errors occurred: ').'
        '. - $errors.'
      '; + $errors.'
    '; } return $resulttext; } @@ -11353,12 +12748,15 @@ sub modify_coursedefaults { ); my @toggles = ('canuse_pdfforms','uselcmath','usejsme'); my @numbers = ('anonsurvey_threshold','uploadquota_official','uploadquota_unofficial', - 'uploadquota_community','uploadquota_textbook','uploadquota_placement'); + 'uploadquota_community','uploadquota_textbook','uploadquota_placement', + 'mysqltables_official','mysqltables_unofficial','mysqltables_community', + 'mysqltables_textbook','mysqltables_placement'); my @types = ('official','unofficial','community','textbook','placement'); my %staticdefaults = ( anonsurvey_threshold => 10, uploadquota => 500, postsubmit => 60, + mysqltables => 172800, ); $defaultshash{'coursedefaults'} = {}; @@ -11399,12 +12797,12 @@ sub modify_coursedefaults { } $defaultshash{'coursedefaults'}{$item} = $newdef; } else { - my ($type) = ($item =~ /^\Quploadquota_\E(\w+)$/); - if (ref($domconfig{'coursedefaults'}{'uploadquota'}) eq 'HASH') { - $currdef = $domconfig{'coursedefaults'}{'uploadquota'}{$type}; + my ($setting,$type) = ($item =~ /^(uploadquota|mysqltables)_(\w+)$/); + if (ref($domconfig{'coursedefaults'}{$setting}) eq 'HASH') { + $currdef = $domconfig{'coursedefaults'}{$setting}{$type}; } $newdef =~ s/[^\w.\-]//g; - $defaultshash{'coursedefaults'}{'uploadquota'}{$type} = $newdef; + $defaultshash{'coursedefaults'}{$setting}{$type} = $newdef; } if ($currdef ne $newdef) { my $staticdef; @@ -11412,9 +12810,10 @@ sub modify_coursedefaults { unless (($currdef eq '') && ($newdef == $staticdefaults{$item})) { $changes{$item} = 1; } - } else { - unless (($currdef eq '') && ($newdef == $staticdefaults{'uploadquota'})) { - $changes{'uploadquota'} = 1; + } elsif ($item =~ /^(uploadquota|mysqltables)_/) { + my $setting = $1; + unless (($currdef eq '') && ($newdef == $staticdefaults{$setting})) { + $changes{$setting} = 1; } } } @@ -11539,7 +12938,7 @@ sub modify_coursedefaults { my %domdefaults = &Apache::lonnet::get_domain_defaults($dom,1); if (($changes{'canuse_pdfforms'}) || ($changes{'uploadquota'}) || ($changes{'postsubmit'}) || ($changes{'coursecredits'}) || ($changes{'uselcmath'}) || ($changes{'usejsme'}) || - ($changes{'canclone'})) { + ($changes{'canclone'}) || ($changes{'mysqltables'})) { foreach my $item ('canuse_pdfforms','uselcmath','usejsme') { if ($changes{$item}) { $domdefaults{$item}=$defaultshash{'coursedefaults'}{$item}; @@ -11624,6 +13023,19 @@ sub modify_coursedefaults { } else { $resulttext .= '
  • '.&mt('Default quota for content uploaded via Course Editor remains default: [_1] MB',$staticdefaults{'uploadquota'}).'
  • '; } + } elsif ($item eq 'mysqltables') { + if (ref($defaultshash{'coursedefaults'}{'mysqltables'}) eq 'HASH') { + $resulttext .= '
  • '.&mt('Lifetime of "Temporary" MySQL tables (student performance data) on homeserver').'
      '. + '
    • '.&mt('Official courses: [_1] s',''.$defaultshash{'coursedefaults'}{'mysqltables'}{'official'}.'').'
    • '. + '
    • '.&mt('Unofficial courses: [_1] s',''.$defaultshash{'coursedefaults'}{'mysqltables'}{'unofficial'}.'').'
    • '. + '
    • '.&mt('Textbook courses: [_1] s',''.$defaultshash{'coursedefaults'}{'mysqltables'}{'textbook'}.'').'
    • '. + '
    • '.&mt('Placement tests: [_1] s',''.$defaultshash{'coursedefaults'}{'mysqltables'}{'placement'}.'').'
    • '. + '
    • '.&mt('Communities: [_1] s',''.$defaultshash{'coursedefaults'}{'mysqltables'}{'community'}.'').'
    • '. + '
    '. + '
  • '; + } else { + $resulttext .= '
  • '.&mt('Lifetime of "Temporary" MySQL tables (student performance data) on homeserver remains default: [_1] s',$staticdefaults{'uploadquota'}).'
  • '; + } } elsif ($item eq 'postsubmit') { if ($domdefaults{'postsubmit'} eq 'off') { $resulttext .= '
  • '.&mt('Submit button(s) remain enabled on page after student makes submission.'); @@ -11953,8 +13365,8 @@ sub modify_usersessions { ); my @prefixes = ('remote','hosted','spares'); my @lcversions = &Apache::lonnet::all_loncaparevs(); - my (%by_ip,%by_location,@intdoms); - &build_location_hashes(\@intdoms,\%by_ip,\%by_location); + my (%by_ip,%by_location,@intdoms,@instdoms); + &build_location_hashes(\@intdoms,\%by_ip,\%by_location,\@instdoms); my @locations = sort(keys(%by_location)); my (%defaultshash,%changes); foreach my $prefix (@prefixes) { @@ -12268,6 +13680,294 @@ sub modify_usersessions { return $resulttext; } +sub modify_ssl { + my ($dom,$lastactref,%domconfig) = @_; + my (%by_ip,%by_location,@intdoms,@instdoms); + &build_location_hashes(\@intdoms,\%by_ip,\%by_location,\@instdoms); + my @locations = sort(keys(%by_location)); + my %servers = &Apache::lonnet::internet_dom_servers($dom); + my (%defaultshash,%changes); + my $action = 'ssl'; + my @prefixes = ('connect','replication'); + foreach my $prefix (@prefixes) { + $defaultshash{$action}{$prefix} = {}; + } + my %domdefaults = &Apache::lonnet::get_domain_defaults($dom,1); + my $resulttext; + my %iphost = &Apache::lonnet::get_iphost(); + my @reptypes = ('certreq','nocertreq'); + my @connecttypes = ('dom','intdom','other'); + my %types = ( + connect => \@connecttypes, + replication => \@reptypes, + ); + foreach my $prefix (sort(keys(%types))) { + foreach my $type (@{$types{$prefix}}) { + if ($prefix eq 'connect') { + my $value = 'yes'; + if ($env{'form.'.$prefix.'_'.$type} =~ /^(no|req)$/) { + $value = $env{'form.'.$prefix.'_'.$type}; + } + if (ref($domconfig{$action}{$prefix}) eq 'HASH') { + if ($domconfig{$action}{$prefix}{$type} ne '') { + if ($value ne $domconfig{$action}{$prefix}{$type}) { + $changes{$prefix}{$type} = 1; + } + $defaultshash{$action}{$prefix}{$type} = $value; + } else { + $defaultshash{$action}{$prefix}{$type} = $value; + $changes{$prefix}{$type} = 1; + } + } else { + $defaultshash{$action}{$prefix}{$type} = $value; + $changes{$prefix}{$type} = 1; + } + if (($type eq 'dom') && (keys(%servers) == 1)) { + delete($changes{$prefix}{$type}); + } elsif (($type eq 'intdom') && (@instdoms == 1)) { + delete($changes{$prefix}{$type}); + } elsif (($type eq 'other') && (keys(%by_location) == 0)) { + delete($changes{$prefix}{$type}); + } + } elsif ($prefix eq 'replication') { + if (@locations > 0) { + my $inuse = $env{'form.'.$prefix.'_'.$type.'_inuse'}; + my @vals = &Apache::loncommon::get_env_multiple('form.'.$prefix.'_'.$type); + my @okvals; + foreach my $val (@vals) { + if ($val =~ /:/) { + my @items = split(/:/,$val); + foreach my $item (@items) { + if (ref($by_location{$item}) eq 'ARRAY') { + push(@okvals,$item); + } + } + } else { + if (ref($by_location{$val}) eq 'ARRAY') { + push(@okvals,$val); + } + } + } + @okvals = sort(@okvals); + if (ref($domconfig{$action}) eq 'HASH') { + if (ref($domconfig{$action}{$prefix}) eq 'HASH') { + if (ref($domconfig{$action}{$prefix}{$type}) eq 'ARRAY') { + if ($inuse == 0) { + $changes{$prefix}{$type} = 1; + } else { + $defaultshash{$action}{$prefix}{$type} = \@okvals; + my @changed = &Apache::loncommon::compare_arrays($domconfig{$action}{$prefix}{$type},$defaultshash{$action}{$prefix}{$type}); + if (@changed > 0) { + $changes{$prefix}{$type} = 1; + } + } + } else { + if ($inuse == 1) { + $defaultshash{$action}{$prefix}{$type} = \@okvals; + $changes{$prefix}{$type} = 1; + } + } + } else { + if ($inuse == 1) { + $defaultshash{$action}{$prefix}{$type} = \@okvals; + $changes{$prefix}{$type} = 1; + } + } + } else { + if ($inuse == 1) { + $defaultshash{$action}{$prefix}{$type} = \@okvals; + $changes{$prefix}{$type} = 1; + } + } + } + } + } + } + my $nochgmsg = &mt('No changes made to LON-CAPA SSL settings'); + if (keys(%changes) > 0) { + my $putresult = &Apache::lonnet::put_dom('configuration',\%defaultshash, + $dom); + if ($putresult eq 'ok') { + if (ref($defaultshash{$action}) eq 'HASH') { + if (ref($defaultshash{$action}{'replication'}) eq 'HASH') { + $domdefaults{'replication'} = $defaultshash{$action}{'replication'}; + } + if (ref($defaultshash{$action}{'connect'}) eq 'HASH') { + $domdefaults{'connect'} = $domconfig{$action}{'connect'}; + } + } + my $cachetime = 24*60*60; + &Apache::lonnet::do_cache_new('domdefaults',$dom,\%domdefaults,$cachetime); + if (ref($lastactref) eq 'HASH') { + $lastactref->{'domdefaults'} = 1; + } + if (keys(%changes) > 0) { + my %titles = &ssl_titles(); + $resulttext = &mt('Changes made:').'
      '; + foreach my $prefix (@prefixes) { + if (ref($changes{$prefix}) eq 'HASH') { + $resulttext .= '
    • '.$titles{$prefix}.'
        '; + foreach my $type (@{$types{$prefix}}) { + if (defined($changes{$prefix}{$type})) { + my $newvalue; + if (ref($defaultshash{$action}) eq 'HASH') { + if (ref($defaultshash{$action}{$prefix})) { + if ($prefix eq 'connect') { + $newvalue = $titles{$defaultshash{$action}{$prefix}{$type}}; + } elsif (ref($defaultshash{$action}{$prefix}{$type}) eq 'ARRAY') { + if (@{$defaultshash{$action}{$prefix}{$type}} > 0) { + $newvalue = join(', ',@{$defaultshash{$action}{$prefix}{$type}}); + } + } + } + if ($newvalue eq '') { + $resulttext .= '
      • '.&mt('[_1] set to: none',$titles{$type}).'
      • '; + } else { + $resulttext .= '
      • '.&mt('[_1] set to: [_2].',$titles{$type},$newvalue).'
      • '; + } + } + } + } + $resulttext .= '
      '; + } + } + } else { + $resulttext = $nochgmsg; + } + } else { + $resulttext = ''. + &mt('An error occurred: [_1]',$putresult).''; + } + } else { + $resulttext = $nochgmsg; + } + return $resulttext; +} + +sub modify_trust { + my ($dom,$lastactref,%domconfig) = @_; + my (%by_ip,%by_location,@intdoms,@instdoms); + &build_location_hashes(\@intdoms,\%by_ip,\%by_location,\@instdoms); + my @locations = sort(keys(%by_location)); + my @prefixes = qw(content shared enroll othcoau coaurem domroles catalog reqcrs msg); + my @types = ('exc','inc'); + my (%defaultshash,%changes); + foreach my $prefix (@prefixes) { + $defaultshash{'trust'}{$prefix} = {}; + } + my %domdefaults = &Apache::lonnet::get_domain_defaults($dom,1); + my $resulttext; + foreach my $prefix (@prefixes) { + foreach my $type (@types) { + my $inuse = $env{'form.'.$prefix.'_'.$type.'_inuse'}; + my @vals = &Apache::loncommon::get_env_multiple('form.'.$prefix.'_'.$type); + my @okvals; + foreach my $val (@vals) { + if ($val =~ /:/) { + my @items = split(/:/,$val); + foreach my $item (@items) { + if (ref($by_location{$item}) eq 'ARRAY') { + push(@okvals,$item); + } + } + } else { + if (ref($by_location{$val}) eq 'ARRAY') { + push(@okvals,$val); + } + } + } + @okvals = sort(@okvals); + if (ref($domconfig{'trust'}) eq 'HASH') { + if (ref($domconfig{'trust'}{$prefix}) eq 'HASH') { + if (ref($domconfig{'trust'}{$prefix}{$type}) eq 'ARRAY') { + if ($inuse == 0) { + $changes{$prefix}{$type} = 1; + } else { + $defaultshash{'trust'}{$prefix}{$type} = \@okvals; + my @changed = &Apache::loncommon::compare_arrays($domconfig{'trust'}{$prefix}{$type},$defaultshash{'trust'}{$prefix}{$type}); + if (@changed > 0) { + $changes{$prefix}{$type} = 1; + } + } + } else { + if ($inuse == 1) { + $defaultshash{'trust'}{$prefix}{$type} = \@okvals; + $changes{$prefix}{$type} = 1; + } + } + } else { + if ($inuse == 1) { + $defaultshash{'trust'}{$prefix}{$type} = \@okvals; + $changes{$prefix}{$type} = 1; + } + } + } else { + if ($inuse == 1) { + $defaultshash{'trust'}{$prefix}{$type} = \@okvals; + $changes{$prefix}{$type} = 1; + } + } + } + } + my $nochgmsg = &mt('No changes made to trust settings.'); + if (keys(%changes) > 0) { + my $putresult = &Apache::lonnet::put_dom('configuration',\%defaultshash, + $dom); + if ($putresult eq 'ok') { + if (ref($defaultshash{'trust'}) eq 'HASH') { + foreach my $prefix (@prefixes) { + if (ref($defaultshash{'trust'}{$prefix}) eq 'HASH') { + $domdefaults{'trust'.$prefix} = $defaultshash{'trust'}{$prefix}; + } + } + } + my $cachetime = 24*60*60; + &Apache::lonnet::do_cache_new('domdefaults',$dom,\%domdefaults,$cachetime); + if (ref($lastactref) eq 'HASH') { + $lastactref->{'domdefaults'} = 1; + } + if (keys(%changes) > 0) { + my %lt = &trust_titles(); + $resulttext = &mt('Changes made:').'
        '; + foreach my $prefix (@prefixes) { + if (ref($changes{$prefix}) eq 'HASH') { + $resulttext .= '
      • '.$lt{$prefix}.'
          '; + foreach my $type (@types) { + if (defined($changes{$prefix}{$type})) { + my $newvalue; + if (ref($defaultshash{'trust'}) eq 'HASH') { + if (ref($defaultshash{'trust'}{$prefix})) { + if (ref($defaultshash{'trust'}{$prefix}{$type}) eq 'ARRAY') { + if (@{$defaultshash{'trust'}{$prefix}{$type}} > 0) { + $newvalue = join(', ',@{$defaultshash{'trust'}{$prefix}{$type}}); + } + } + } + } + if ($newvalue eq '') { + $resulttext .= '
        • '.&mt('[_1] set to: none',$lt{$type}).'
        • '; + } else { + $resulttext .= '
        • '.&mt('[_1] set to: [_2].',$lt{$type},$newvalue).'
        • '; + } + } + } + $resulttext .= '
        '; + } + } + $resulttext .= '
      '; + } else { + $resulttext = $nochgmsg; + } + } else { + $resulttext = ''. + &mt('An error occurred: [_1]',$putresult).''; + } + } else { + $resulttext = $nochgmsg; + } + return $resulttext; +} + sub modify_loadbalancing { my ($dom,%domconfig) = @_; my $primary_id = &Apache::lonnet::domain($dom,'primary'); @@ -12328,8 +14028,13 @@ sub modify_loadbalancing { push(@offloadto,$target); } } - $defaultshash{'loadbalancing'}{$balancer}{'targets'}{$sparetype} = \@offloadto; } + if ($env{'form.loadbalancing_target_'.$i.'_hosthere'} eq $sparetype) { + unless(grep(/^\Q$balancer\E$/,@offloadto)) { + push(@offloadto,$balancer); + } + } + $defaultshash{'loadbalancing'}{$balancer}{'targets'}{$sparetype} = \@offloadto; } if (ref($currtargets{$balancer}) eq 'HASH') { foreach my $sparetype (@sparestypes) { @@ -12563,24 +14268,9 @@ sub recurse_cat_deletes { return; } -sub get_active_dcs { - my ($dom) = @_; - my $now = time; - my %dompersonnel = &Apache::lonnet::get_domain_roles($dom,['dc'],$now,$now); - my %domcoords; - my $numdcs = 0; - foreach my $server (keys(%dompersonnel)) { - foreach my $user (sort(keys(%{$dompersonnel{$server}}))) { - my ($trole,$uname,$udom,$runame,$rudom,$rsec) = split(/:/,$user); - $domcoords{$uname.':'.$udom} = $dompersonnel{$server}{$user}; - } - } - return %domcoords; -} - sub active_dc_picker { my ($dom,$numinrow,$inputtype,$name,%currhash) = @_; - my %domcoords = &get_active_dcs($dom); + my %domcoords = &Apache::lonnet::get_active_domroles($dom,['dc']); my @domcoord = keys(%domcoords); if (keys(%currhash)) { foreach my $dc (keys(%currhash)) {