--- loncom/interface/domainprefs.pm 2014/10/04 02:44:18 1.160.6.54 +++ loncom/interface/domainprefs.pm 2017/11/01 08:56:25 1.160.6.84.2.8 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # Handler to set domain-wide configuration settings # -# $Id: domainprefs.pm,v 1.160.6.54 2014/10/04 02:44:18 raeburn Exp $ +# $Id: domainprefs.pm,v 1.160.6.84.2.8 2017/11/01 08:56:25 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -19,14 +19,15 @@ # # 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/ # # ############################################################### -############################################################## +############################################################### =pod @@ -213,15 +214,29 @@ sub handler { 'quotas','autoenroll','autoupdate','autocreate', 'directorysrch','usercreation','usermodification', 'contacts','defaults','scantron','coursecategories', - 'serverstatuses','requestcourses','coursedefaults', - 'usersessions','loadbalancing','requestauthor', - 'selfenrollment','inststatus'],$dom); + 'serverstatuses','requestcourses','helpsettings', + 'coursedefaults','usersessions','loadbalancing', + 'requestauthor','selfenrollment','inststatus', + 'ltitools'],$dom); + if (ref($domconfig{'ltitools'}) eq 'HASH') { + my %encconfig = + &Apache::lonnet::get_dom('encconfig',['ltitools'],$dom); + if (ref($encconfig{'ltitools'}) eq 'HASH') { + foreach my $id (keys(%{$domconfig{'ltitools'}})) { + if (ref($domconfig{'ltitools'}{$id}) eq 'HASH') { + foreach my $item ('key','secret') { + $domconfig{'ltitools'}{$id}{$item} = $encconfig{'ltitools'}{$id}{$item}; + } + } + } + } + } my @prefs_order = ('rolecolors','login','defaults','quotas','autoenroll', 'autoupdate','autocreate','directorysrch','contacts', 'usercreation','selfcreation','usermodification','scantron', 'requestcourses','requestauthor','coursecategories', - 'serverstatuses','coursedefaults','selfenrollment', - 'usersessions'); + 'serverstatuses','helpsettings','coursedefaults', + 'ltitools','selfenrollment','usersessions'); my %existing; if (ref($domconfig{'loadbalancing'}) eq 'HASH') { %existing = %{$domconfig{'loadbalancing'}}; @@ -250,6 +265,8 @@ sub handler { header => [{col1 => 'Log-in Page Items', col2 => '',}, {col1 => 'Log-in Help', + col2 => 'Value'}, + {col1 => 'Custom HTML in document head', col2 => 'Value'}], print => \&print_login, modify => \&modify_login, @@ -259,6 +276,8 @@ sub handler { help => 'Domain_Configuration_LangTZAuth', header => [{col1 => 'Setting', col2 => 'Value'}, + {col1 => 'Internal Authentication', + col2 => 'Value'}, {col1 => 'Institutional user types', col2 => 'Assignable to e-mail usernames'}], print => \&print_defaults, @@ -302,18 +321,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, }, @@ -409,10 +434,22 @@ sub handler { print => \&print_serverstatuses, modify => \&modify_serverstatuses, }, + 'helpsettings' => + {text => 'Support settings', + help => 'Domain_Configuration_Help_Settings', + header => [{col1 => 'Help Page Settings (logged-in users)', + col2 => 'Value'}, + {col1 => 'Helpdesk Roles', + col2 => 'Settings'},], + print => \&print_helpsettings, + modify => \&modify_helpsettings, + }, 'coursedefaults' => {text => 'Course/Community defaults', help => 'Domain_Configuration_Course_Defaults', - header => [{col1 => 'Defaults which can be overridden for each course by a DC', + header => [{col1 => 'Defaults which can be overridden in each course by a CC', + col2 => 'Value',}, + {col1 => 'Defaults which can be overridden for each course by a DC', col2 => 'Value',},], print => \&print_coursedefaults, modify => \&modify_coursedefaults, @@ -441,7 +478,7 @@ sub handler { print => \&print_usersessions, modify => \&modify_usersessions, }, - 'loadbalancing' => + 'loadbalancing' => {text => 'Dedicated Load Balancer(s)', help => 'Domain_Configuration_Load_Balancing', header => [{col1 => 'Balancers', @@ -452,6 +489,14 @@ sub handler { print => \&print_loadbalancing, modify => \&modify_loadbalancing, }, + 'ltitools' => + {text => 'External Tools (LTI)', + help => 'Domain_Configuration_LTI_Tools', + header => [{col1 => 'Setting', + col2 => 'Value',}], + print => \&print_ltitools, + modify => \&modify_ltitools, + }, ); if (keys(%servers) > 1) { $prefs{'login'} = { text => 'Log-in page options', @@ -461,6 +506,8 @@ sub handler { {col1 => 'Log-in Page Items', col2 => ''}, {col1 => 'Log-in Help', + col2 => 'Value'}, + {col1 => 'Custom HTML in document head', col2 => 'Value'}], print => \&print_login, modify => \&modify_login, @@ -503,6 +550,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. @@ -592,7 +642,7 @@ sub process_changes { } elsif ($action eq 'autocreate') { $output = &modify_autocreate($dom,%domconfig); } elsif ($action eq 'directorysrch') { - $output = &modify_directorysrch($dom,%domconfig); + $output = &modify_directorysrch($dom,$lastactref,%domconfig); } elsif ($action eq 'usercreation') { $output = &modify_usercreation($dom,%domconfig); } elsif ($action eq 'selfcreation') { @@ -613,6 +663,8 @@ sub process_changes { $output = &modify_quotas($r,$dom,$action,$lastactref,%domconfig); } elsif ($action eq 'requestauthor') { $output = &modify_quotas($r,$dom,$action,$lastactref,%domconfig); + } elsif ($action eq 'helpsettings') { + $output = &modify_helpsettings($r,$dom,$confname,$lastactref,%domconfig); } elsif ($action eq 'coursedefaults') { $output = &modify_coursedefaults($dom,$lastactref,%domconfig); } elsif ($action eq 'selfenrollment') { @@ -621,6 +673,8 @@ sub process_changes { $output = &modify_usersessions($dom,$lastactref,%domconfig); } elsif ($action eq 'loadbalancing') { $output = &modify_loadbalancing($dom,%domconfig); + } elsif ($action eq 'ltitools') { + $output = &modify_ltitools($r,$dom,$action,$lastactref,%domconfig); } return $output; } @@ -633,6 +687,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 .= ' @@ -650,7 +720,8 @@ sub print_config_box { my $colspan = ''; my $rightcolspan = ''; if (($action eq 'rolecolors') || ($action eq 'defaults') || - (($action eq 'login') && ($numheaders < 3))) { + ($action eq 'directorysrch') || + (($action eq 'login') && ($numheaders < 4))) { $colspan = ' colspan="2"'; } if ($action eq 'usersessions') { @@ -666,13 +737,14 @@ sub print_config_box { '; $rowtotal ++; if (($action eq 'autoupdate') || ($action eq 'usercreation') || ($action eq 'selfcreation') || - ($action eq 'usermodification') || ($action eq 'defaults') || - ($action eq 'selfenrollment') || ($action eq 'usersessions')) { + ($action eq 'usermodification') || ($action eq 'defaults') || ($action eq 'coursedefaults') || + ($action eq 'selfenrollment') || ($action eq 'usersessions') || ($action eq 'directorysrch') || + ($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); } elsif ($action eq 'login') { - if ($numheaders == 3) { + if ($numheaders == 4) { $colspan = ' colspan="2"'; $output .= &print_login('service',$dom,$confname,$phase,$settings,\$rowtotal); } else { @@ -697,7 +769,8 @@ 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 'contacts') || ($action eq 'defaults')) { if ($action eq 'coursecategories') { $output .= &print_coursecategories('middle',$dom,$item,$settings,\$rowtotal); $colspan = ' colspan="2"'; @@ -721,10 +794,12 @@ sub print_config_box { $output .= $item->{'print'}->('bottom',$dom,$settings,\$rowtotal); } $rowtotal ++; - } elsif (($action eq 'usermodification') || ($action eq 'defaults')) { + } elsif (($action eq 'usermodification') || ($action eq 'coursedefaults') || + ($action eq 'defaults') || ($action eq 'directorysrch') || + ($action eq 'helpsettings')) { $output .= $item->{'print'}->('bottom',$dom,$settings,\$rowtotal); } elsif ($action eq 'login') { - if ($numheaders == 3) { + if ($numheaders == 4) { $output .= &print_login('page',$dom,$confname,$phase,$settings,\$rowtotal).'
@@ -740,6 +815,27 @@ sub print_config_box { } else { $output .= &print_login('help',$dom,$confname,$phase,$settings,\$rowtotal); } + $output .= ' + + + + + + + '; + if ($numheaders == 4) { + $output .= ' + + + '; + } else { + $output .= ' + + + '; + } + $rowtotal ++; + $output .= &print_login('headtag',$dom,$confname,$phase,$settings,\$rowtotal); } elsif ($action eq 'requestcourses') { $output .= &print_requestmail($dom,$action,$settings,\$rowtotal); $rowtotal ++; @@ -813,7 +909,7 @@ sub print_config_box { '. + ''."\n"; $itemcount ++; + } $$rowtotal += $itemcount; return $datatable; @@ -3143,7 +4599,13 @@ sub print_usersessions { if ($position eq 'top') { if (keys(%serverhomes) > 1) { my %spareid = ¤t_offloads_to($dom,$settings,\%servers); - $datatable .= &spares_row($dom,\%servers,\%spareid,\%serverhomes,\%altids,$rowtotal); + my $curroffloadnow; + if (ref($settings) eq 'HASH') { + if (ref($settings->{'offloadnow'}) eq 'HASH') { + $curroffloadnow = $settings->{'offloadnow'}; + } + } + $datatable .= &spares_row($dom,\%servers,\%spareid,\%serverhomes,\%altids,$curroffloadnow,$rowtotal); } else { $datatable .= ''; + ''; my $rem = $i%($numinrow); if ($rem == 0) { if (($i > 0) && ($i < $numspares-1)) { @@ -3667,6 +5142,23 @@ sub print_loadbalancing { $datatable .= ''.$typetitles{$sparetype}.'
'. '
'.&mt($item->{'header'}->[3]->{'col1'}).''.&mt($item->{'header'}->[3]->{'col2'}).'
'.&mt($item->{'header'}->[2]->{'col1'}).''.&mt($item->{'header'}->[2]->{'col2'}).'
'; - if (($action eq 'login') || ($action eq 'directorysrch')) { + if ($action eq 'login') { $output .= ' '; } elsif ($action eq 'serverstatuses') { @@ -857,15 +953,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); - } elsif ($action eq 'coursedefaults') { - $output .= $item->{'print'}->('bottom',$dom,$settings,\$rowtotal); } } $output .= ' @@ -1162,6 +1255,57 @@ sub print_login { $itemcount ++; } $datatable .= &captcha_choice('login',$settings,$itemcount); + } elsif ($caller eq 'headtag') { + my %domservers = &Apache::lonnet::get_servers($dom); + my $choice = $choices{'headtag'}; + $css_class = ' class="LC_odd_row"'; + $datatable .= ''. + ''; } return $datatable; } @@ -1195,6 +1339,9 @@ sub login_choices { link => "Link", alink => "Active link", vlink => "Visited link", + headtag => "Custom markup", + action => "Action", + current => "Current", ); return %choices; } @@ -2315,10 +2462,78 @@ $jstext{'templates'}; ENDSCRIPT } +sub ltitools_javascript { + my ($settings) = @_; + return unless(ref($settings) eq 'HASH'); + my (%ordered,$total,%jstext); + $total = 0; + foreach my $item (keys(%{$settings})) { + if (ref($settings->{$item}) eq 'HASH') { + my $num = $settings->{$item}{'order'}; + $ordered{$num} = $item; + } + } + $total = scalar(keys(%{$settings})); + my @jsarray = (); + foreach my $item (sort {$a <=> $b } (keys(%ordered))) { + push(@jsarray,$ordered{$item}); + } + my $jstext = ' var ltitools = Array('."'".join("','",@jsarray)."'".');'."\n"; + return <<"ENDSCRIPT"; + + +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') { @@ -2352,6 +2567,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" '; @@ -2387,8 +2605,12 @@ sub print_autoenroll { $coownerson.' value="1" />'.&mt('Yes').' '. ''. - ''; - $$rowtotal += 3; + ''. + ''. + ''; + $$rowtotal += 4; return $datatable; } @@ -2436,7 +2658,7 @@ sub print_autoupdate { my $locknamesettings; $datatable .= &insttypes_row($settings,$types,$usertypes, $dom,$numinrow,$othertitle, - 'lockablenames'); + 'lockablenames',$rowtotal); $$rowtotal ++; } else { my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom); @@ -2517,236 +2739,949 @@ 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', + $rowtotal); + $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'); - 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}; + my (%checked,%to,%otheremails,%bccemails,%includestr,%includeloc,%currfield, + $maxsize,$fields,$fieldtitles,$fieldoptions,$possoptions,@mailings); + if ($position eq 'top') { + if (ref($settings) eq 'HASH') { + foreach my $item (@contacts) { + if (exists($settings->{$item})) { + $to{$item} = $settings->{$item}; + } } } + } elsif ($position eq 'middle') { + @mailings = ('errormail','packagesmail','lonstatusmail','requestsmail', + 'updatesmail','idconflictsmail'); 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} = ''; + } + } else { + @mailings = ('helpdeskmail','otherdomsmail'); + foreach my $type (@mailings) { + $otheremails{$type} = ''; + } + $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}); + } } } - $otheremails{$type} = $settings->{$type}{'others'}; - if ($type eq 'helpdeskmail') { - $bccemails{$type} = $settings->{$type}{'bcc'}; + } 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}; + } + } + 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 ++; - } - foreach my $type (@mailings) { + if ($position eq 'top') { + foreach my $item (@contacts) { + $css_class = $rownum%2?' class="LC_odd_row"':''; + $datatable .= ''. + ''; + $rownum ++; + } + } 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; + unless ($position eq 'top') { + foreach my $type (@mailings) { + $css_class = $rownum%2?' class="LC_odd_row"':''; + $datatable .= ''. + ''. + ''."\n"; + $rownum ++; + } + } + 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') { + my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom); + my (@posstypes,%usertypeshash); + if (ref($types) eq 'ARRAY') { + @posstypes = @{$types}; + } + if (@posstypes) { + if (ref($usertypes) eq 'HASH') { + %usertypeshash = %{$usertypes}; + } + my @overridden; + my $numinrow = 4; + if (ref($settings) eq 'HASH') { + if (ref($settings->{'overrides'}) eq 'HASH') { + foreach my $key (sort(keys(%{$settings->{'overrides'}}))) { + if (ref($settings->{'overrides'}{$key}) eq 'HASH') { + push(@overridden,$key); + foreach my $item (@contacts) { + if ($settings->{'overrides'}{$key}{$item}) { + $checked{'override_'.$key}{$item} = ' checked="checked" '; + } + } + $otheremails{'override_'.$key} = $settings->{'overrides'}{$key}{'others'}; + $bccemails{'override_'.$key} = $settings->{'overrides'}{$key}{'bcc'}; + $includeloc{'override_'.$key} = ''; + $includestr{'override_'.$key} = ''; + if ($settings->{'overrides'}{$key}{'include'} ne '') { + ($includeloc{'override_'.$key},$includestr{'override_'.$key}) = + split(/:/,$settings->{'overrides'}{$key}{'include'},2); + $includestr{'override_'.$key} = &unescape($includestr{'override_'.$key}); + } + } + } + } + } + my $customclass = 'LC_helpdesk_override'; + my $optionsprefix = 'LC_options_helpdesk_'; + + my $onclicktypes = "toggleHelpdeskRow(this.form,'overrides','$customclass','$optionsprefix');"; + + $datatable .= &insttypes_row($settings,$types,$usertypes,$dom, + $numinrow,$othertitle,'overrides', + \$rownum,$onclicktypes,$customclass); + $rownum ++; + $usertypeshash{'default'} = $othertitle; + foreach my $status (@posstypes) { + my $css_class; + if ($rownum%2) { + $css_class = 'LC_odd_row '; + } + $css_class .= $customclass; + my $rowid = $optionsprefix.$status; + my $hidden = 1; + my $currstyle = 'display:none'; + if (grep(/^\Q$status\E$/,@overridden)) { + $currstyle = 'display:table-row'; + $hidden = 0; + } + my $key = 'override_'.$status; + $datatable .= &overridden_helpdesk($checked{$key},$otheremails{$key},$bccemails{$key}, + $includeloc{$key},$includestr{$key},$status,$rowid, + $usertypeshash{$status},$css_class,$currstyle, + \@contacts,$short_titles); + unless ($hidden) { + $rownum ++; + } + } + } + } $$rowtotal += $rownum; return $datatable; } +sub overridden_helpdesk { + my ($checked,$otheremails,$bccemails,$includeloc,$includestr,$type,$rowid, + $typetitle,$css_class,$rowstyle,$contacts,$short_titles) = @_; + my $class = 'LC_left_item'; + if ($css_class) { + $css_class = ' class="'.$css_class.'"'; + } + if ($rowid) { + $rowid = ' id="'.$rowid.'"'; + } + if ($rowstyle) { + $rowstyle = ' style="'.$rowstyle.'"'; + } + my ($output,$description); + $description = &mt('Helpdesk requests from: [_1] in this domain (overrides default)',"$typetitle"); + $output = ''. + "\n". + ''."\n"; + return $output; +} + +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) eq 'HASH') { + if (ref($settings->{'adhoc'}) eq 'HASH') { + %current = %{$settings->{'adhoc'}}; + } + } + my $count = 0; + foreach my $key (sort(keys(%existing))) { + if ($key=~/^rolesdef\_(\w+)$/) { + my $rolename = $1; + my (%privs,$order); + ($privs{'system'},$privs{'domain'},$privs{'course'}) = split(/\_/,$existing{$key}); + $customroles{$rolename} = \%privs; + if (ref($current{$rolename}) eq 'HASH') { + $order = $current{$rolename}{'order'}; + } + if ($order eq '') { + $order = $count; + } + $ordered{$order} = $rolename; + $count++; + } + } + my $maxnum = scalar(keys(%ordered)); + my @roles_by_num = (); + foreach my $item (sort {$a <=> $b } (keys(%ordered))) { + push(@roles_by_num,$item); + } + my $context = 'domprefs'; + my $crstype = 'Course'; + my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom); + my @accesstypes = ('all','dh','da','none'); + my ($numstatustypes,@jsarray); + if (ref($types) eq 'ARRAY') { + if (@{$types} > 0) { + $numstatustypes = scalar(@{$types}); + push(@accesstypes,'status'); + @jsarray = ('bystatus'); + } + } + my %domhelpdesk = &Apache::lonnet::get_active_domroles($dom,['dh','da']); + if (keys(%domhelpdesk)) { + push(@accesstypes,('inc','exc')); + push(@jsarray,('notinc','notexc')); + } + my $hiddenstr = join("','",@jsarray); + $datatable .= &helpsettings_javascript(\@roles_by_num,$maxnum,$hiddenstr,$formname); + my $context = 'domprefs'; + my $crstype = 'Course'; + my $prefix = 'helproles_'; + my $add_class = 'LC_hidden'; + foreach my $num (@roles_by_num) { + my $role = $ordered{$num}; + my ($desc,$access,@statuses); + if (ref($current{$role}) eq 'HASH') { + $desc = $current{$role}{'desc'}; + $access = $current{$role}{'access'}; + if (ref($current{$role}{'insttypes'}) eq 'ARRAY') { + @statuses = @{$current{$role}{'insttypes'}}; + } + } + if ($desc eq '') { + $desc = $role; + } + my $identifier = 'custhelp'.$num; + my %full=(); + my %levels= ( + course => {}, + domain => {}, + system => {}, + ); + my %levelscurrent=( + course => {}, + domain => {}, + system => {}, + ); + &Apache::lonuserutils::custom_role_privs($customroles{$role},\%full,\%levels,\%levelscurrent); + my @templateroles = &Apache::lonuserutils::custom_template_roles($context,$crstype); + $css_class = $itemcount%2?' class="LC_odd_row"':''; + my $chgstr = ' onchange="javascript:reorderHelpRoles(this.form,'."'helproles_".$num."_pos'".');"'; + $datatable .= ''. + ''; + $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 with domain helpdesk or helpdesk assistant role', + 'dh' => 'All with domain helpdesk role', + 'da' => 'All with domain helpdesk assistant role', + 'none' => 'None', + 'status' => 'Determined based on institutional status', + 'inc' => 'Include all, but exclude specific personnel', + 'exc' => 'Exclude all, but include specific personnel', + ); + my %usecheck = ( + all => ' checked="checked"', + ); + my %displaydiv = ( + status => 'none', + inc => 'none', + exc => 'none', + priv => 'block', + ); + my $output; + if (ref($current) eq 'HASH') { + if (($current->{'access'} ne '') && ($current->{'access'} ne 'all')) { + if (grep(/^\Q$current->{access}\E$/,@{$accesstypes})) { + $usecheck{$current->{access}} = $usecheck{'all'}; + delete($usecheck{'all'}); + if ($current->{access} =~ /^(status|inc|exc)$/) { + my $access = $1; + $displaydiv{$access} = 'inline'; + } elsif ($current->{access} eq 'none') { + $displaydiv{'priv'} = 'none'; + } + } + } + } + $output = '
'.$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) = @_; + $additional,$align) = @_; return unless ((ref($toggles) eq 'ARRAY') && (ref($defaultchecked) eq 'HASH') && (ref($choices) eq 'HASH')); @@ -2780,8 +3715,14 @@ sub radiobutton_prefs { $datatable .= ''. - ''; + if ($align eq 'left') { + $datatable .= ''. + ''."\n"; + $itemcount ++; + } + } + $css_class = $itemcount%2?' class="LC_odd_row"':''; + my $chgstr = ' onchange="javascript:reorderLTI(this.form,'."'ltitools_add_pos'".');"'; + $datatable .= ''."\n". + ''."\n". + ''."\n". + ''."\n"; + $itemcount ++; + return $datatable; +} + +sub ltitools_names { + my %lt = &Apache::lonlocal::texthash( + 'title' => 'Title', + 'version' => 'Version', + 'msgtype' => 'Message Type', + 'url' => 'URL', + 'key' => 'Key', + 'secret' => 'Secret', + 'icon' => 'Icon', + 'user' => 'Username:domain', + 'fullname' => 'Full Name', + 'firstname' => 'First Name', + 'lastname' => 'Last Name', + 'email' => 'E-mail', + 'roles' => 'Role', + 'window' => 'Window', + 'tab' => 'Tab', + 'iframe' => 'iFrame', + 'height' => 'Height', + 'width' => 'Width', + 'linktext' => 'Default Link Text', + 'explanation' => 'Default Explanation', + 'passback' => 'Tool can return grades:', + 'roster' => 'Tool can retrieve roster:', + 'crstarget' => 'Display target', + 'crslabel' => 'Course label', + 'crstitle' => 'Course title', + 'crslinktext' => 'Link Text', + 'crsexplanation' => 'Explanation', + ); + + return %lt; +} + sub print_coursedefaults { my ($position,$dom,$settings,$rowtotal) = @_; my ($css_class,$datatable,%checkedon,%checkedoff,%defaultchecked,@toggles); my $itemcount = 1; my %choices = &Apache::lonlocal::texthash ( - canuse_pdfforms => 'Course/Community users can create/upload PDF forms', uploadquota => 'Default quota for files uploaded directly to course/community using Course Editor (MB)', anonsurvey_threshold => 'Responder count needed before showing submissions for anonymous surveys', coursecredits => 'Credits can be specified for courses', + uselcmath => 'Math preview uses LON-CAPA previewer (javascript) in place of DragMath (Java)', + usejsme => 'Molecule editor uses JSME (HTML5) in place of JME (Java)', + postsubmit => 'Disable submit button/keypress following student submission', + canclone => "People who may clone a course (besides course's owner and coordinators)", + mysqltables => 'Lifetime (s) of "Temporary" MySQL tables (student performance data) on homeserver', ); my %staticdefaults = ( anonsurvey_threshold => 10, uploadquota => 500, + postsubmit => 60, + mysqltables => 172800, ); if ($position eq 'top') { - %defaultchecked = ('canuse_pdfforms' => 'off'); - @toggles = ('canuse_pdfforms'); + %defaultchecked = ( + 'uselcmath' => 'on', + 'usejsme' => 'on', + 'canclone' => 'none', + ); + @toggles = ('uselcmath','usejsme'); ($datatable,$itemcount) = &radiobutton_prefs($settings,\@toggles,\%defaultchecked, - \%choices,$itemcount); + \%choices,$itemcount); + $css_class = $itemcount%2?' class="LC_odd_row"':''; + $datatable .= + ''. + ''; + $itemcount ++; } else { $css_class = $itemcount%2 ? ' class="LC_odd_row"' : ''; - my ($currdefresponder,$def_official_credits,$def_unofficial_credits,$def_textbook_credits, - %curruploadquota); + my ($currdefresponder,%defcredits,%curruploadquota,%deftimeout,%currmysql); my $currusecredits = 0; + my $postsubmitclient = 1; my @types = ('official','unofficial','community','textbook'); if (ref($settings) eq 'HASH') { $currdefresponder = $settings->{'anonsurvey_threshold'}; @@ -2827,13 +4216,50 @@ sub print_coursedefaults { } } if (ref($settings->{'coursecredits'}) eq 'HASH') { - $def_official_credits = $settings->{'coursecredits'}->{'official'}; - $def_unofficial_credits = $settings->{'coursecredits'}->{'unofficial'}; - $def_textbook_credits = $settings->{'coursecredits'}->{'textbook'}; - if (($def_official_credits ne '') || ($def_unofficial_credits ne '') || - ($def_textbook_credits ne '')) { - $currusecredits = 1; + foreach my $type (@types) { + next if ($type eq 'community'); + $defcredits{$type} = $settings->{'coursecredits'}->{$type}; + if ($defcredits{$type} ne '') { + $currusecredits = 1; + } + } + } + if (ref($settings->{'postsubmit'}) eq 'HASH') { + if ($settings->{'postsubmit'}->{'client'} eq 'off') { + $postsubmitclient = 0; + foreach my $type (@types) { + $deftimeout{$type} = $staticdefaults{'postsubmit'}; + } + } else { + foreach my $type (@types) { + if (ref($settings->{'postsubmit'}->{'timeout'}) eq 'HASH') { + if ($settings->{'postsubmit'}->{'timeout'}->{$type} =~ /^\d+$/) { + $deftimeout{$type} = $settings->{'postsubmit'}->{'timeout'}->{$type}; + } else { + $deftimeout{$type} = $staticdefaults{'postsubmit'}; + } + } else { + $deftimeout{$type} = $staticdefaults{'postsubmit'}; + } + } + } + } else { + foreach my $type (@types) { + $deftimeout{$type} = $staticdefaults{'postsubmit'}; + } + } + if (ref($settings->{'mysqltables'}) eq 'HASH') { + foreach my $type (keys(%{$settings->{'mysqltables'}})) { + $currmysql{$type} = $settings->{'mysqltables'}{$type}; } + } else { + foreach my $type (@types) { + $currmysql{$type} = $staticdefaults{'mysqltables'}; + } + } + } else { + foreach my $type (@types) { + $deftimeout{$type} = $staticdefaults{'postsubmit'}; } } if (!$currdefresponder) { @@ -2874,21 +4300,14 @@ sub print_coursedefaults { $display = 'block'; } my $additional = '
'. - ''. - &mt('Default credits for official courses [_1]', - ''). - '
'. - ''. - &mt('Default credits for unofficial courses [_1]', - ''). - '
'. - ''. - &mt('Default credits for textbook courses [_1]', - ''). - '
'."\n"; + ''.&mt('Default credits').'
'.&mt($item->{'header'}->[0]->{'col1'}).''.$choice.''. + ''. + ''. + ''."\n"; + my (%currurls,%currexempt); + if (ref($settings) eq 'HASH') { + if (ref($settings->{'headtag'}) eq 'HASH') { + foreach my $lonhost (keys(%{$settings->{'headtag'}})) { + if (ref($settings->{'headtag'}{$lonhost}) eq 'HASH') { + $currurls{$lonhost} = $settings->{'headtag'}{$lonhost}{'url'}; + $currexempt{$lonhost} = $settings->{'headtag'}{$lonhost}{'exempt'}; + } + } + } + } + my %lt = &Apache::lonlocal::texthash( + del => 'Delete?', + rep => 'Replace:', + upl => 'Upload:', + curr => 'View contents', + none => 'None', + ); + my $switchserver = &check_switchserver($dom,$confname); + foreach my $lonhost (sort(keys(%domservers))) { + my $exempt = &check_exempt_addresses($currexempt{$lonhost}); + $datatable .= ''; + if ($currurls{$lonhost}) { + $datatable .= ''. + ''; + } + $datatable .= '
'.$choices{'hostid'}.''.$choices{'current'}.''.$choices{'action'}.''.$choices{'exempt'}.'
'.$domservers{$lonhost}.''.$lt{'curr'}.' '.$lt{'rep'}.''; + } else { + $datatable .= ''.$lt{'none'}.''.$lt{'upl'}; + } + $datatable .='
'; + if ($switchserver) { + $datatable .= &mt('Upload to library server: [_1]',$switchserver); + } else { + $datatable .= ''; + } + $datatable .= '
'.&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}.': '. - ''; - 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 .= '
'. + $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 .= '
$description'. + '
'.&mt('E-mail recipient(s)').''. + ''; + if (ref($contacts) eq 'ARRAY') { + foreach my $item (@{$contacts}) { + my $check; + if (ref($checked) eq 'HASH') { + $check = $checked->{$item}; + } + my $title; + if (ref($short_titles) eq 'HASH') { + $title = $short_titles->{$item}; + } + $output .= ' '; + } + } + $output .= '
'.&mt('Others').':  '. + ''; + my %locchecked; + foreach my $loc ('s','b') { + if ($includeloc eq $loc) { + $locchecked{$loc} = ' checked="checked"'; + last; + } + } + $output .= '
'.&mt('Bcc:').(' 'x6). + '
'. + '
'.&mt('Optional added text').''. + &mt('Text automatically added to e-mail:').' '. + '
'. + ''.&mt('Location:').' '. + ''. + (' 'x2). + ''. + '
'. + '
'.$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). + '
'. ''.$choices->{$item}. - ''. + ''; + } else { + $datatable .= ''; + } + $datatable .= + ''. ' 
' + .''.(' 'x2). + ''. + '
'.&mt('Required settings').''. + ''.$lt{'title'}.': '. + (' 'x2). + ''.$lt{'version'}.': '. + (' 'x2). + ''.$lt{'msgtype'}.': '. + '

'. + ''.$lt{'url'}.':'. + (' 'x2). + ''.$lt{'key'}. + ' '. + (' 'x2). + ''.$lt{'secret'}.':'. + ''. + ''. + ''. + '
'. + '
'.&mt('Optional settings').''. + ''.&mt('Display target:'); + my %currdisp; + if (ref($settings->{$item}->{'display'}) eq 'HASH') { + if ($settings->{$item}->{'display'}->{'target'} eq 'window') { + $currdisp{'window'} = ' checked="checked"'; + } elsif ($settings->{$item}->{'display'}->{'target'} eq 'tab') { + $currdisp{'tab'} = ' checked="checked"'; + } else { + $currdisp{'iframe'} = ' checked="checked"'; + } + if ($settings->{$item}->{'display'}->{'width'} =~ /^(\d+)$/) { + $currdisp{'width'} = $1; + } + if ($settings->{$item}->{'display'}->{'height'} =~ /^(\d+)$/) { + $currdisp{'height'} = $1; + } + $currdisp{'linktext'} = $settings->{$item}->{'display'}->{'linktext'}; + $currdisp{'explanation'} = $settings->{$item}->{'display'}->{'explanation'}; + } else { + $currdisp{'iframe'} = ' checked="checked"'; + } + foreach my $disp ('iframe','tab','window') { + $datatable .= ''.(' 'x2); + } + $datatable .= (' 'x4); + foreach my $dimen ('width','height') { + $datatable .= ''. + (' 'x2); + } + $datatable .= '
'. + '
'.$lt{'linktext'}.'
'. + '
'. + '
'.$lt{'explanation'}.'
'. + '

'; + $datatable .= '
'; + foreach my $extra ('passback','roster') { + my $checkedon = ''; + my $checkedoff = ' checked="checked"'; + if ($settings->{$item}->{$extra}) { + $checkedon = $checkedoff; + $checkedoff = ''; + } + $datatable .= $lt{$extra}.' '. + ''.(' 'x2). + ''.(' 'x4); + } + $datatable .= '

'.$lt{'icon'}.': '; + if ($imgsrc) { + $datatable .= $imgsrc. + ' '. + ' '.&mt('Replace:').' '; + } else { + $datatable .= '('.&mt('if larger than 21x21 pixels, image will be scaled').') '; + } + if ($switchserver) { + $datatable .= &mt('Upload to library server: [_1]',$switchserver); + } else { + $datatable .= ''; + } + $datatable .= '
'; + my (%checkedfields,%rolemaps); + if (ref($settings->{$item}) eq 'HASH') { + if (ref($settings->{$item}->{'fields'}) eq 'HASH') { + %checkedfields = %{$settings->{$item}->{'fields'}}; + } + if (ref($settings->{$item}->{'roles'}) eq 'HASH') { + %rolemaps = %{$settings->{$item}->{'roles'}}; + $checkedfields{'roles'} = 1; + } + } + $datatable .= '
'.&mt('User data sent on launch').''. + ''; + foreach my $field (@fields) { + my $checked; + if ($checkedfields{$field}) { + $checked = ' checked="checked"'; + } + $datatable .= ''.(' ' x2); + } + $datatable .= '
'. + '
'.&mt('Role mapping').''; + foreach my $role (@courseroles) { + my ($selected,$selectnone); + if (!$rolemaps{$role}) { + $selectnone = ' selected="selected"'; + } + $datatable .= ''; + } + $datatable .= '
'. + &Apache::lonnet::plaintext($role,'Course').'
'. + '
'; + 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','linktext','explanation') { + 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') { + my %custom = %{$settings->{$item}->{'custom'}}; + if (keys(%custom) > 0) { + foreach my $key (sort(keys(%custom))) { + $datatable .= ''. + ''; + } + } + } + $datatable .= ''; + $datatable .= '
'.&mt('Action').''.&mt('Name').''.&mt('Value').'
'. + ''.$key.'
'. + ''. + '
'."\n". + ''."\n". + ' '."\n". + ''.&mt('Add').''. + '
'.&mt('Required settings').''. + ''.$lt{'title'}.': '."\n". + (' 'x2). + ''.$lt{'version'}.': '."\n". + (' 'x2). + ''.$lt{'msgtype'}.': '. + '
'. + ''.$lt{'url'}.': '."\n". + (' 'x2). + ''.$lt{'key'}.': '."\n". + (' 'x2). + ''.$lt{'secret'}.':'. + ' '."\n". + '
'. + '
'.&mt('Optional settings').''. + ''.&mt('Display target:'); + my %defaultdisp; + $defaultdisp{'iframe'} = ' checked="checked"'; + foreach my $disp ('iframe','tab','window') { + $datatable .= ''.(' 'x2); + } + $datatable .= (' 'x4); + foreach my $dimen ('width','height') { + $datatable .= ''. + (' 'x2); + } + $datatable .= '
'. + '
'.$lt{'linktext'}.'
'. + '
'. + '
'.$lt{'explanation'}.'
'. + ''. + '

'; + foreach my $extra ('passback','roster') { + $datatable .= $lt{$extra}.' '. + ''.(' 'x2). + ''.(' 'x4); + } + $datatable .= '

'.$lt{'icon'}.': '. + '('.&mt('if larger than 21x21 pixels, image will be scaled').') '; + if ($switchserver) { + $datatable .= &mt('Upload to library server: [_1]',$switchserver); + } else { + $datatable .= ''; + } + $datatable .= '
'. + '
'.&mt('User data sent on launch').''. + ''; + foreach my $field (@fields) { + $datatable .= ''.(' ' x2); + } + $datatable .= '
'. + '
'.&mt('Role mapping').''; + foreach my $role (@courseroles) { + my ($checked,$checkednone); + $datatable .= ''; + } + $datatable .= '
'. + &Apache::lonnet::plaintext($role,'Course').'
'. + '
'. + '
'.&mt('Configurable in course').''; + foreach my $item ('label','title','target','linktext','explanation') { + $datatable .= ''.(' ' x2)."\n"; + } + $datatable .= '
'. + '
'.&mt('Custom items sent on launch').''. + ''. + ''. + '
'.&mt('Action').''.&mt('Name').''.&mt('Value').'
'. + ''. + '
'. + ''.$choices{'canclone'}. + ''; + my $currcanclone = 'none'; + my $onclick; + my @cloneoptions = ('none','domain'); + my %clonetitles = ( + none => 'No additional course requesters', + domain => "Any course requester in course's domain", + instcode => 'Course requests for official courses ...', + ); + my (%codedefaults,@code_order,@posscodes); + if (&Apache::lonnet::auto_instcode_defaults($dom,\%codedefaults, + \@code_order) eq 'ok') { + if (@code_order > 0) { + push(@cloneoptions,'instcode'); + $onclick = ' onclick="toggleDisplay(this.form,'."'cloneinstcode'".');"'; + } + } + if (ref($settings) eq 'HASH') { + if ($settings->{'canclone'}) { + if (ref($settings->{'canclone'}) eq 'HASH') { + if (ref($settings->{'canclone'}{'instcode'}) eq 'ARRAY') { + if (@code_order > 0) { + $currcanclone = 'instcode'; + @posscodes = @{$settings->{'canclone'}{'instcode'}}; + } + } + } elsif ($settings->{'canclone'} eq 'domain') { + $currcanclone = $settings->{'canclone'}; + } + } + } + foreach my $option (@cloneoptions) { + my ($checked,$additional); + if ($currcanclone eq $option) { + $checked = ' checked="checked"'; + } + if ($option eq 'instcode') { + if (@code_order) { + my $show = 'none'; + if ($checked) { + $show = 'block'; + } + $additional = '
'. + &mt('Institutional codes for new and cloned course have identical:'). + '
'; + foreach my $item (@code_order) { + my $codechk; + if ($checked) { + if (grep(/^\Q$item\E$/,@posscodes)) { + $codechk = ' checked="checked"'; + } + } + $additional .= ''; + } + $additional .= (' 'x2).'('.&mt('check as many as needed').')
'; + } + } + $datatable .= + ' '.$additional.'
'; + } + $datatable .= '
'; + foreach my $type (@types) { + next if ($type eq 'community'); + $additional .= ''; + } + $additional .= '
'.&mt($type).'
'. + '
'."\n"; %defaultchecked = ('coursecredits' => 'off'); @toggles = ('coursecredits'); my $current = { @@ -2896,9 +4315,46 @@ sub print_coursedefaults { }; (my $table,$itemcount) = &radiobutton_prefs($current,\@toggles,\%defaultchecked, - \%choices,$itemcount,$onclick,$additional); + \%choices,$itemcount,$onclick,$additional,'left'); $datatable .= $table; + $onclick = "toggleDisplay(this.form,'studentsubmission');"; + my $display = 'none'; + if ($postsubmitclient) { + $display = 'block'; + } + $additional = '
'. + &mt('Number of seconds submit is disabled').'
'. + ''.&mt('Enter 0 to remain disabled until page reload.').'
'. + ''; + foreach my $type (@types) { + $additional .= ''; + } + $additional .= '
'.&mt($type).'
'. + '
'."\n"; + %defaultchecked = ('postsubmit' => 'on'); + @toggles = ('postsubmit'); + $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).'
'. + '
'. &mt('Nothing to set here, as the cluster to which this domain belongs only contains one server.'); @@ -3393,7 +4855,7 @@ sub current_offloads_to { } sub spares_row { - my ($dom,$servers,$spareid,$serverhomes,$altids,$rowtotal) = @_; + my ($dom,$servers,$spareid,$serverhomes,$altids,$curroffloadnow,$rowtotal) = @_; my $css_class; my $numinrow = 4; my $itemcount = 1; @@ -3413,12 +4875,21 @@ sub spares_row { } } next unless (ref($spareid->{$server}) eq 'HASH'); + my $checkednow; + if (ref($curroffloadnow) eq 'HASH') { + if ($curroffloadnow->{$server}) { + $checkednow = ' checked="checked"'; + } + } $css_class = $itemcount%2 ? ' class="LC_odd_row"' : ''; $datatable .= ' '. &mt('[_1] when busy, offloads to:' - ,''.$server.''). + ,''.$server.'').'
'. + ''."\n". + ''. "\n"; my (%current,%canselect); my @choices = @@ -3623,6 +5094,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++) { @@ -3642,9 +5116,10 @@ sub print_loadbalancing { $disabled = ' disabled="disabled"'; } $targettable .= - '
'.$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}, @@ -3734,7 +5226,7 @@ sub loadbalancing_rules { if (ref($currrules) eq 'HASH') { $current = $currrules->{$type}; } - if (($type eq '_LC_external') || ($type eq '_LC_internetdom') || ($type eq '_LC_ipchange')) { + if (($type eq '_LC_external') || ($type eq '_LC_internetdom')) { if ($dom ne &Apache::lonnet::host_domain($lonhost)) { $current = ''; } @@ -3759,9 +5251,14 @@ sub loadbalancing_titles { '_LC_ipchange' => &mt('Non-SSO users with IP mismatch'), ); my @alltypes = ('_LC_adv','_LC_author','_LC_internetdom','_LC_external','_LC_ipchangesso','_LC_ipchange'); + my @available; if (ref($types) eq 'ARRAY') { - unshift(@alltypes,@{$types},'default'); + @available = @{$types}; + } + unless (grep(/^default$/,@available)) { + push(@available,'default'); } + unshift(@alltypes,@available); my %titles; foreach my $type (@alltypes) { if ($type =~ /^_LC_/) { @@ -3786,7 +5283,7 @@ sub loadbalance_rule_row { my @rulenames; my %ruletitles = &offloadtype_text(); if (($type eq '_LC_ipchangesso') || ($type eq '_LC_ipchange')) { - @rulenames = ('balancer','offloadedto'); + @rulenames = ('balancer','offloadedto','specific'); } else { @rulenames = ('default','homeserver'); if ($type eq '_LC_external') { @@ -3797,7 +5294,7 @@ sub loadbalance_rule_row { push(@rulenames,'none'); } my $style = $targets_div_style; - if (($type eq '_LC_external') || ($type eq '_LC_internetdom') || ($type eq '_LC_ipchange')) { + if (($type eq '_LC_external') || ($type eq '_LC_internetdom')) { $style = $homedom_div_style; } my $space; @@ -3848,8 +5345,13 @@ sub loadbalance_rule_row { ' '.$ruletitles{$rulenames[$i]}. - ''.$extra.'
'."\n"; + ')"'.$checked.' /> '; + if (($rulenames[$i] eq 'specific') && ($type =~ /^_LC_ipchange/)) { + $output .= $ruletitles{'particular'}; + } else { + $output .= $ruletitles{$rulenames[$i]}; + } + $output .= ''.$extra.'
'."\n"; } $output .= ''."\n"; return $output; @@ -3864,6 +5366,7 @@ sub offloadtype_text { 'none' => 'No offload', 'balancer' => 'Session hosted on Load Balancer, after re-authentication', 'offloadedto' => 'Session hosted on offload server, after re-authentication', + 'particular' => 'Session hosted (after re-auth) on server:', ); return %ruletitles; } @@ -3878,14 +5381,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 from all users in this domain", + 'otherdomsmail' => 'Helpdesk requests from users in 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 ( @@ -3895,6 +5399,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', @@ -4102,6 +5634,7 @@ sub print_selfcreation { my %radiohash; my $numinrow = 4; map { $radiohash{'cancreate_'.$_} = 1; } @selfcreate; + my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom); if ($position eq 'top') { my %choices = &Apache::lonlocal::texthash ( cancreate_login => 'Institutional Login', @@ -4117,13 +5650,11 @@ sub print_selfcreation { \%choices,$itemcount,$onclick); $$rowtotal += $itemcount; - my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom); - if (ref($usertypes) eq 'HASH') { if (keys(%{$usertypes}) > 0) { $datatable .= &insttypes_row($createsettings,$types,$usertypes, $dom,$numinrow,$othertitle, - 'statustocreate',$$rowtotal); + 'statustocreate',$rowtotal); $$rowtotal ++; } } @@ -4168,16 +5699,22 @@ sub print_selfcreation { $$rowtotal ++; } elsif ($position eq 'middle') { my %domconf = &Apache::lonnet::get_dom('configuration',['usermodification'],$dom); - my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom); - $usertypes->{'default'} = $othertitle; + my @posstypes; if (ref($types) eq 'ARRAY') { - push(@{$types},'default'); - $usertypes->{'default'} = $othertitle; - foreach my $status (@{$types}) { - $datatable .= &modifiable_userdata_row('selfcreate',$status,$domconf{'usermodification'}, - $numinrow,$$rowtotal,$usertypes); - $$rowtotal ++; - } + @posstypes = @{$types}; + } + unless (grep(/^default$/,@posstypes)) { + push(@posstypes,'default'); + } + my %usertypeshash; + if (ref($usertypes) eq 'HASH') { + %usertypeshash = %{$usertypes}; + } + $usertypeshash{'default'} = $othertitle; + foreach my $status (@posstypes) { + $datatable .= &modifiable_userdata_row('selfcreate',$status,$domconf{'usermodification'}, + $numinrow,$$rowtotal,\%usertypeshash); + $$rowtotal ++; } } else { my %choices = &Apache::lonlocal::texthash ( @@ -4195,29 +5732,30 @@ sub print_selfcreation { my $onclick = "toggleDisplay(this.form,'emailoptions');"; my $additional = '
'; my %domdefaults = &Apache::lonnet::get_domain_defaults($dom); - my $usertypes = {}; - my $order = []; - if ((ref($domdefaults{'inststatustypes'}) eq 'HASH') && (ref($domdefaults{'inststatusguest'}) eq 'ARRAY')) { - $usertypes = $domdefaults{'inststatustypes'}; - $order = $domdefaults{'inststatusguest'}; - } - if (ref($order) eq 'ARRAY') { - push(@{$order},'default'); - if (@{$order} > 1) { - $usertypes->{'default'} = &mt('Other users'); - $additional .= ''; - foreach my $status (@{$order}) { - $additional .= ''; - } - $additional .= ''; - foreach my $status (@{$order}) { - $additional .= ''; - } - $additional .= '
'.$usertypes->{$status}.'
'.&email_as_username($rowtotal,$processing,$status).'
'; - } else { - $usertypes->{'default'} = &mt('All users'); - $additional .= &email_as_username($rowtotal,$processing); + my (@ordered,%usertypeshash); + if (ref($domdefaults{'inststatusguest'}) eq 'ARRAY') { + @ordered = @{$domdefaults{'inststatusguest'}}; + } + if (@ordered) { + unless (grep(/^default$/,@ordered)) { + push(@ordered,'default'); + } + if (ref($usertypes) eq 'HASH') { + %usertypeshash = %{$usertypes}; } + $usertypeshash{'default'} = $othertitle; + $additional .= ''; + foreach my $status (@ordered) { + $additional .= ''; + } + $additional .= ''; + foreach my $status (@ordered) { + $additional .= ''; + } + $additional .= '
'.$usertypeshash{$status}.'
'.&email_as_username($rowtotal,$processing,$status).'
'; + } else { + $usertypeshash{'default'} = $othertitle; + $additional .= &email_as_username($rowtotal,$processing); } $additional .= '
'."\n"; @@ -4228,12 +5766,10 @@ sub print_selfcreation { $$rowtotal ++; my ($infofields,$infotitles) = &Apache::loncommon::emailusername_info(); $numinrow = 1; - if (ref($order) eq 'ARRAY') { - foreach my $status (@{$order}) { - $datatable .= &modifiable_userdata_row('cancreate','emailusername_'.$status,$settings, - $numinrow,$$rowtotal,$usertypes,$infofields,$infotitles); - $$rowtotal ++; - } + foreach my $status (@ordered) { + $datatable .= &modifiable_userdata_row('cancreate','emailusername_'.$status,$settings, + $numinrow,$$rowtotal,\%usertypeshash,$infofields,$infotitles); + $$rowtotal ++; } my ($emailrules,$emailruleorder) = &Apache::lonnet::inst_userrules($dom,'email'); @@ -4304,7 +5840,8 @@ sub email_as_username { sub captcha_choice { my ($context,$settings,$itemcount) = @_; - my ($keyentry,$currpub,$currpriv,%checked,$rowname,$pubtext,$privtext); + my ($keyentry,$currpub,$currpriv,%checked,$rowname,$pubtext,$privtext, + $vertext,$currver); my %lt = &captcha_phrases(); $keyentry = 'hidden'; if ($context eq 'cancreate') { @@ -4322,6 +5859,11 @@ sub captcha_choice { $pubtext = $lt{'pub'}; $privtext = $lt{'priv'}; $keyentry = 'text'; + $vertext = $lt{'ver'}; + $currver = $settings->{'recaptchaversion'}; + if ($currver ne '2') { + $currver = 1; + } } if (ref($settings->{'recaptchakeys'}) eq 'HASH') { $currpub = $settings->{'recaptchakeys'}{'public'}; @@ -4355,7 +5897,11 @@ sub captcha_choice { $currpub.'" size="40" />
'."\n". ''.$privtext.' '."\n". ''."\n". + $currpriv.'" size="40" />
'. + ''.$vertext.' '."\n". + '
'. + ''."\n". ''; return $output; } @@ -4490,7 +6036,10 @@ sub print_usermodification { sub print_defaults { my ($position,$dom,$settings,$rowtotal) = @_; my $rownum = 0; - my ($datatable,$css_class); + my ($datatable,$css_class,$titles); + unless ($position eq 'bottom') { + $titles = &defaults_titles($dom); + } if ($position eq 'top') { my @items = ('auth_def','auth_arg_def','lang_def','timezone_def', 'datelocale_def','portal_def'); @@ -4503,7 +6052,6 @@ sub print_defaults { $defaults{$item} = $domdefaults{$item}; } } - my $titles = &defaults_titles($dom); foreach my $item (@items) { if ($rownum%2) { $css_class = ''; @@ -4538,11 +6086,8 @@ sub print_defaults { my $includeempty = 1; $datatable .= &Apache::loncommon::select_datelocale($item,$defaults{$item},undef,$includeempty); } elsif ($item eq 'lang_def') { - my %langchoices = &get_languages_hash(); - $langchoices{''} = 'No language preference'; - %langchoices = &Apache::lonlocal::texthash(%langchoices); - $datatable .= &Apache::loncommon::select_form($defaults{$item},$item, - \%langchoices); + my $includeempty = 1; + $datatable .= &Apache::loncommon::select_language($item,$defaults{$item},$includeempty); } else { my $size; if ($item eq 'portal_def') { @@ -4554,8 +6099,87 @@ sub print_defaults { $datatable .= ''; $rownum ++; } + } elsif ($position eq 'middle') { + my @items = ('intauth_cost','intauth_check','intauth_switch'); + my %defaults; + if (ref($settings) eq 'HASH') { + %defaults = %{$settings}; + if ($defaults{'intauth_cost'} !~ /^\d+$/) { + $defaults{'intauth_cost'} = 10; + } + if ($defaults{'intauth_check'} !~ /^(0|1|2)$/) { + $defaults{'intauth_check'} = 0; + } + if ($defaults{'intauth_switch'} !~ /^(0|1|2)$/) { + $defaults{'intauth_switch'} = 0; + } + } else { + %defaults = ( + 'intauth_cost' => 10, + 'intauth_check' => 0, + 'intauth_switch' => 0, + ); + } + foreach my $item (@items) { + if ($rownum%2) { + $css_class = ''; + } else { + $css_class = ' class="LC_odd_row" '; + } + $datatable .= ''. + ''.$titles->{$item}. + ''; + if ($item eq 'intauth_switch') { + my @options = (0,1,2); + my %optiondesc = &Apache::lonlocal::texthash ( + 0 => 'No', + 1 => 'Yes', + 2 => 'Yes, and copy existing passwd file to passwd.bak file', + ); + $datatable .= ''; + foreach my $option (@options) { + my $checked = ' '; + if ($defaults{$item} eq $option) { + $checked = ' checked="checked"'; + } + $datatable .= ''; + } + $datatable .= '
'. + '
'; + } elsif ($item eq 'intauth_check') { + my @options = (0,1,2); + my %optiondesc = &Apache::lonlocal::texthash ( + 0 => 'No', + 1 => 'Yes, allow login then update passwd file using default cost (if higher)', + 2 => 'Yes, disallow login if stored cost is less than domain default', + ); + $datatable .= ''; + foreach my $option (@options) { + my $checked = ' '; + my $onclick; + if ($defaults{$item} eq $option) { + $checked = ' checked="checked"'; + } + if ($option == 2) { + $onclick = ' onclick="javascript:warnIntAuth(this);"'; + } + $datatable .= ''; + } + $datatable .= '
'. + '
'; + } else { + $datatable .= ''; + } + $datatable .= ''; + $rownum ++; + } } else { - my (%defaults); + my %defaults; if (ref($settings) eq 'HASH') { if ((ref($settings->{'inststatusorder'}) eq 'ARRAY') && (ref($settings->{'inststatustypes'}) eq 'HASH') && (ref($settings->{'inststatusguest'}) eq 'ARRAY')) { @@ -4611,7 +6235,7 @@ sub print_defaults { $datatable .= ''; } $datatable .= ' '.&mt('Internal ID:'). - ''. + ''. ' '.&mt('(new)'). ''. &mt('Name displayed:'). @@ -4650,6 +6274,9 @@ sub defaults_titles { 'timezone_def' => 'Default timezone', 'datelocale_def' => 'Default locale for dates', 'portal_def' => 'Portal/Default URL', + 'intauth_cost' => 'Encryption cost for bcrypt (positive integer)', + 'intauth_check' => 'Check bcrypt cost if authenticated', + 'intauth_switch' => 'Existing crypt-based switched to bcrypt on authentication', ); if ($dom) { my $uprimary_id = &Apache::lonnet::domain($dom,'primary'); @@ -5148,12 +6775,40 @@ sub serverstatus_pages { return ('userstatus','lonstatus','loncron','server-status','codeversions', 'checksums','clusterstatus','metadata_keywords','metadata_harvest', 'takeoffline','takeonline','showenv','toggledebug','ping','domconf', - 'uniquecodes','diskusage'); + 'uniquecodes','diskusage','coursecatalog'); } sub defaults_javascript { my ($settings) = @_; - return unless (ref($settings) eq 'HASH'); + my $intauthcheck = &mt('Warning: disallowing login for an authenticated user if the stored cost is less than the default will require a password reset by/for the user.'); + my $intauthcost = &mt('Warning: bcrypt encryption cost for internal authentication must be an integer.'); + &js_escape(\$intauthcheck); + &js_escape(\$intauthcost); + my $intauthjs = <<"ENDSCRIPT"; + +function warnIntAuth(field) { + if (field.name == 'intauth_check') { + if (field.value == '2') { + alert('$intauthcheck'); + } + } + if (field.name == 'intauth_cost') { + field.value.replace(/\s/g,''); + if (field.value != '') { + var regexdigit=/^\\d+\$/; + if (!regexdigit.test(field.value)) { + alert('$intauthcost'); + } + } + } + return; +} + +ENDSCRIPT + + if (ref($settings) ne 'HASH') { + return &Apache::lonhtmlcommon::scripttag($intauthjs); + } if ((ref($settings->{'inststatusorder'}) eq 'ARRAY') && (ref($settings->{'inststatustypes'}) eq 'HASH')) { my $maxnum = scalar(@{$settings->{'inststatusorder'}}); if ($maxnum eq '') { @@ -5207,10 +6862,14 @@ $jstext return; } +$intauthjs + // ]]> ENDSCRIPT + } else { + return &Apache::lonhtmlcommon::scripttag($intauthjs); } } @@ -5238,7 +6897,10 @@ sub coursecategories_javascript { } my $instcode_reserved = &mt('The name: [_1] is a reserved category.','"instcode"'); my $communities_reserved = &mt('The name: [_1] is a reserved category.','"communities"'); - my $choose_again = '\\n'.&mt('Please use a different name for the new top level category.'); + my $choose_again = "\n".&mt('Please use a different name for the new top level category.'); + &js_escape(\$instcode_reserved); + &js_escape(\$communities_reserved); + &js_escape(\$choose_again); $output = <<"ENDSCRIPT";