--- loncom/interface/domainprefs.pm 2020/01/15 16:55:18 1.160.6.102.2.1 +++ loncom/interface/domainprefs.pm 2021/03/07 00:32:21 1.160.6.102.2.11 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # Handler to set domain-wide configuration settings # -# $Id: domainprefs.pm,v 1.160.6.102.2.1 2020/01/15 16:55:18 raeburn Exp $ +# $Id: domainprefs.pm,v 1.160.6.102.2.11 2021/03/07 00:32:21 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -349,6 +349,8 @@ sub handler { col2 => 'Value',}, {col1 => 'Recipient(s) for notifications', col2 => 'Value',}, + {col1 => 'Nightly status check e-mail', + col2 => 'Settings',}, {col1 => 'Ask helpdesk form settings', col2 => 'Value',},], print => \&print_contacts, @@ -726,6 +728,8 @@ sub print_config_box { $output = &Apache::lonuserutils::custom_roledefs_js($context,$crstype,$formname,\%full, \@templateroles); + } elsif ($action eq 'ltitools') { + $output .= <itools_javascript($settings); } $output .= '<table class="LC_nested_outer"> @@ -742,6 +746,7 @@ sub print_config_box { if ($numheaders > 1) { my $colspan = ''; my $rightcolspan = ''; + my $leftnobr = ''; if (($action eq 'rolecolors') || ($action eq 'defaults') || ($action eq 'directorysrch') || (($action eq 'login') && ($numheaders < 4))) { @@ -750,12 +755,15 @@ sub print_config_box { if ($action eq 'usersessions') { $rightcolspan = ' colspan="3"'; } + if ($action eq 'passwords') { + $leftnobr = ' LC_nobreak'; + } $output .= ' <tr> <td> <table class="LC_nested"> <tr class="LC_info_row"> - <td class="LC_left_item"'.$colspan.'>'.&mt($item->{'header'}->[0]->{'col1'}).'</td> + <td class="LC_left_item'.$leftnobr.'"'.$colspan.'>'.&mt($item->{'header'}->[0]->{'col1'}).'</td> <td class="LC_right_item"'.$rightcolspan.'>'.&mt($item->{'header'}->[0]->{'col2'}).'</td> </tr>'; $rowtotal ++; @@ -814,13 +822,18 @@ sub print_config_box { <td> <table class="LC_nested"> <tr class="LC_info_row"> - <td class="LC_left_item"'.$colspan.'>'.&mt($item->{'header'}->[2]->{'col1'}).'</td> + <td class="LC_left_item'.$leftnobr.'"'.$colspan.'>'.&mt($item->{'header'}->[2]->{'col1'}).'</td> <td class="LC_right_item">'.&mt($item->{'header'}->[2]->{'col2'}).'</td> </tr>'."\n"; if ($action eq 'coursecategories') { $output .= &print_coursecategories('bottom',$dom,$item,$settings,\$rowtotal); - } elsif ($action eq 'passwords') { - $output .= $item->{'print'}->('lower',$dom,$confname,$settings,\$rowtotal).' + } elsif (($action eq 'contacts') || ($action eq 'passwords')) { + if ($action eq 'passwords') { + $output .= $item->{'print'}->('lower',$dom,$confname,$settings,\$rowtotal); + } else { + $output .= $item->{'print'}->('lower',$dom,$settings,\$rowtotal); + } + $output .= ' </tr> </table> </td> @@ -830,8 +843,13 @@ sub print_config_box { <table class="LC_nested"> <tr class="LC_info_row"> <td class="LC_left_item"'.$colspan.'>'.&mt($item->{'header'}->[3]->{'col1'}).'</td> - <td class="LC_right_item"'.$colspan.'>'.&mt($item->{'header'}->[3]->{'col2'}).'</td></tr>'."\n". - $item->{'print'}->('bottom',$dom,$confname,$settings,\$rowtotal).' + <td class="LC_right_item"'.$colspan.'>'.&mt($item->{'header'}->[3]->{'col2'}).'</td></tr>'."\n"; + if ($action eq 'passwords') { + $output .= $item->{'print'}->('bottom',$dom,$confname,$settings,\$rowtotal); + } else { + $output .= $item->{'print'}->('bottom',$dom,$settings,\$rowtotal); + } + $output .= ' </table> </td> </tr> @@ -2521,7 +2539,10 @@ ENDSCRIPT sub ltitools_javascript { my ($settings) = @_; - return unless(ref($settings) eq 'HASH'); + my $togglejs = <itools_toggle_js(); + unless (ref($settings) eq 'HASH') { + return $togglejs; + } my (%ordered,$total,%jstext); $total = 0; foreach my $item (keys(%{$settings})) { @@ -2539,7 +2560,7 @@ sub ltitools_javascript { return <<"ENDSCRIPT"; <script type="text/javascript"> // <![CDATA[ -function reorderLTI(form,item) { +function reorderLTITools(form,item) { var changedVal; $jstext var newpos = 'ltitools_add_pos'; @@ -2584,6 +2605,37 @@ $jstext // ]]> </script> +$togglejs + +ENDSCRIPT +} + +sub ltitools_toggle_js { + return <<"ENDSCRIPT"; +<script type="text/javascript"> +// <![CDATA[ + +function toggleLTITools(form,setting,item) { + var radioname = ''; + var divid = ''; + if (setting == 'user') { + divid = 'ltitools_'+setting+'_div_'+item; + var checkid = 'ltitools_'+setting+'_field_'+item; + if (document.getElementById(divid)) { + if (document.getElementById(checkid)) { + if (document.getElementById(checkid).checked) { + document.getElementById(divid).style.display = 'inline-block'; + } else { + document.getElementById(divid).style.display = 'none'; + } + } + } + } + return; +} +// ]]> +</script> + ENDSCRIPT } @@ -2948,7 +3000,7 @@ sub print_contacts { my $datatable; my @contacts = ('adminemail','supportemail'); my (%checked,%to,%otheremails,%bccemails,%includestr,%includeloc,%currfield, - $maxsize,$fields,$fieldtitles,$fieldoptions,$possoptions,@mailings); + $maxsize,$fields,$fieldtitles,$fieldoptions,$possoptions,@mailings,%lonstatus); if ($position eq 'top') { if (ref($settings) eq 'HASH') { foreach my $item (@contacts) { @@ -2963,6 +3015,12 @@ sub print_contacts { foreach my $type (@mailings) { $otheremails{$type} = ''; } + } elsif ($position eq 'lower') { + if (ref($settings) eq 'HASH') { + if (ref($settings->{'lonstatus'}) eq 'HASH') { + %lonstatus = %{$settings->{'lonstatus'}}; + } + } } else { @mailings = ('helpdeskmail','otherdomsmail'); foreach my $type (@mailings) { @@ -2975,7 +3033,7 @@ sub print_contacts { ($fields,$fieldtitles,$fieldoptions,$possoptions) = &helpform_fields(); } if (ref($settings) eq 'HASH') { - unless ($position eq 'top') { + unless (($position eq 'top') || ($position eq 'lower')) { foreach my $type (@mailings) { if (exists($settings->{$type})) { if (ref($settings->{$type}) eq 'HASH') { @@ -3108,7 +3166,7 @@ sub print_contacts { $datatable .= '</td></tr>'."\n"; $rownum ++; } - unless ($position eq 'top') { + unless (($position eq 'top') || ($position eq 'lower')) { foreach my $type (@mailings) { $css_class = $rownum%2?' class="LC_odd_row"':''; $datatable .= '<tr'.$css_class.'>'. @@ -3155,18 +3213,104 @@ sub print_contacts { } 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)); + my $corelink = &core_link_msu(); + $choices{'reporterrors'} = &mt('E-mail error reports to [_1]',$corelink); $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'); + $corelink); + $choices{'reportstatus'} = &mt('E-mail status if errors above threshold to [_1]',$corelink); + my @toggles = ('reporterrors','reportupdates','reportstatus'); my %defaultchecked = ('reporterrors' => 'on', - 'reportupdates' => 'on'); + 'reportupdates' => 'on', + 'reportstatus' => 'on'); (my $reports,$rownum) = &radiobutton_prefs($settings,\@toggles,\%defaultchecked, \%choices,$rownum); $datatable .= $reports; + } elsif ($position eq 'lower') { + my (%current,%excluded,%weights); + my ($defaults,$names) = &Apache::loncommon::lon_status_items(); + if ($lonstatus{'threshold'} =~ /^\d+$/) { + $current{'errorthreshold'} = $lonstatus{'threshold'}; + } else { + $current{'errorthreshold'} = $defaults->{'threshold'}; + } + if ($lonstatus{'sysmail'} =~ /^\d+$/) { + $current{'errorsysmail'} = $lonstatus{'sysmail'}; + } else { + $current{'errorsysmail'} = $defaults->{'sysmail'}; + } + if (ref($lonstatus{'weights'}) eq 'HASH') { + foreach my $type ('E','W','N','U') { + if ($lonstatus{'weights'}{$type} =~ /^\d+$/) { + $weights{$type} = $lonstatus{'weights'}{$type}; + } else { + $weights{$type} = $defaults->{$type}; + } + } + } else { + foreach my $type ('E','W','N','U') { + $weights{$type} = $defaults->{$type}; + } + } + if (ref($lonstatus{'excluded'}) eq 'ARRAY') { + if (@{$lonstatus{'excluded'}} > 0) { + map {$excluded{$_} = 1; } @{$lonstatus{'excluded'}}; + } + } + foreach my $item ('errorthreshold','errorsysmail') { + $css_class = $rownum%2?' class="LC_odd_row"':''; + $datatable .= '<tr'.$css_class.'>'. + '<td class="LC_left_item"><span class="LC_nobreak">'. + $titles->{$item}. + '</span></td><td class="LC_left_item">'. + '<input type="text" name="'.$item.'" value="'. + $current{$item}.'" size="5" /></td></tr>'; + $rownum ++; + } + $css_class = $rownum%2?' class="LC_odd_row"':''; + $datatable .= '<tr'.$css_class.'>'. + '<td class="LC_left_item">'. + '<span class="LC_nobreak">'.$titles->{'errorweights'}. + '</span></td><td class="LC_left_item"><table><tr>'; + foreach my $type ('E','W','N','U') { + $datatable .= '<td>'.$names->{$type}.'<br />'. + '<input type="text" name="errorweights_'.$type.'" value="'. + $weights{$type}.'" size="5" /></td>'; + } + $datatable .= '</tr></table></tr>'; + $rownum ++; + $css_class = $rownum%2?' class="LC_odd_row"':''; + $datatable .= '<tr'.$css_class.'><td class="LC_left_item">'. + $titles->{'errorexcluded'}.'</td>'. + '<td class="LC_left_item"><table>'; + my $numinrow = 4; + my @ids = sort(values(%Apache::lonnet::serverhomeIDs)); + for (my $i=0; $i<@ids; $i++) { + my $rem = $i%($numinrow); + if ($rem == 0) { + if ($i > 0) { + $datatable .= '</tr>'; + } + $datatable .= '<tr>'; + } + my $check; + if ($excluded{$ids[$i]}) { + $check = ' checked="checked" '; + } + $datatable .= '<td class="LC_left_item">'. + '<span class="LC_nobreak"><label>'. + '<input type="checkbox" name="errorexcluded" '. + 'value="'.$ids[$i].'"'.$check.' />'. + $ids[$i].'</label></span></td>'; + } + my $colsleft = $numinrow - @ids%($numinrow); + if ($colsleft > 1 ) { + $datatable .= '<td colspan="'.$colsleft.'" class="LC_left_item">'. + ' </td>'; + } elsif ($colsleft == 1) { + $datatable .= '<td class="LC_left_item"> </td>'; + } + $datatable .= '</tr></table></td></tr>'; + $rownum ++; } elsif ($position eq 'bottom') { my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom); my (@posstypes,%usertypeshash); @@ -3240,6 +3384,11 @@ sub print_contacts { return $datatable; } +sub core_link_msu { + return &Apache::loncommon::modal_link('http://loncapa.org/core.html', + &mt('LON-CAPA core group - MSU'),600,500); +} + sub overridden_helpdesk { my ($checked,$otheremails,$bccemails,$includeloc,$includestr,$type,$rowid, $typetitle,$css_class,$rowstyle,$contacts,$short_titles) = @_; @@ -3812,28 +3961,34 @@ sub print_ltitools { my $confname = $dom.'-domainconfig'; my $switchserver = &check_switchserver($dom,$confname); my $maxnum = scalar(keys(%ordered)); - my $datatable = <itools_javascript($settings); + my $datatable; my %lt = <itools_names(); my @courseroles = ('cc','in','ta','ep','st'); my @ltiroles = qw(Instructor ContentDeveloper TeachingAssistant Learner); - my @fields = ('fullname','firstname','lastname','email','user','roles'); + my @fields = ('fullname','firstname','lastname','email','roles','user'); if (keys(%ordered)) { my @items = sort { $a <=> $b } keys(%ordered); for (my $i=0; $i<@items; $i++) { $css_class = $itemcount%2?' class="LC_odd_row"':''; my $item = $ordered{$items[$i]}; - my ($title,$key,$secret,$url,$imgsrc,$version); + my ($title,$key,$secret,$url,$lifetime,$imgsrc,%sigsel); if (ref($settings->{$item}) eq 'HASH') { $title = $settings->{$item}->{'title'}; $url = $settings->{$item}->{'url'}; $key = $settings->{$item}->{'key'}; $secret = $settings->{$item}->{'secret'}; + $lifetime = $settings->{$item}->{'lifetime'}; my $image = $settings->{$item}->{'image'}; if ($image ne '') { $imgsrc = '<img src="'.$image.'" alt="'.&mt('Tool Provider icon').'" />'; } + if ($settings->{$item}->{'sigmethod'} eq 'HMAC-256') { + $sigsel{'HMAC-256'} = ' selected="selected"'; + } else { + $sigsel{'HMAC-SHA1'} = ' selected="selected"'; + } } - my $chgstr = ' onchange="javascript:reorderLTI(this.form,'."'ltitools_".$item."'".');"'; + my $chgstr = ' onchange="javascript:reorderLTITools(this.form,'."'ltitools_".$item."'".');"'; $datatable .= '<tr '.$css_class.'><td><span class="LC_nobreak">' .'<select name="ltitools_'.$item.'"'.$chgstr.'>'; for (my $k=0; $k<=$maxnum; $k++) { @@ -3849,20 +4004,27 @@ sub print_ltitools { &mt('Delete?').'</label></span></td>'. '<td colspan="2">'. '<fieldset><legend>'.&mt('Required settings').'</legend>'. - '<span class="LC_nobreak">'.$lt{'title'}.':<input type="text" size="30" name="ltitools_title_'.$i.'" value="'.$title.'" /></span> '. + '<span class="LC_nobreak">'.$lt{'title'}.':<input type="text" size="20" name="ltitools_title_'.$i.'" value="'.$title.'" /></span> '. (' 'x2). '<span class="LC_nobreak">'.$lt{'version'}.':<select name="ltitools_version_'.$i.'">'. '<option value="LTI-1p0" selected="selected">1.1</option></select></span> '. (' 'x2). '<span class="LC_nobreak">'.$lt{'msgtype'}.':<select name="ltitools_msgtype_'.$i.'">'. '<option value="basic-lti-launch-request" selected="selected">Launch</option></select></span> '. + (' 'x2). + '<span class="LC_nobreak">'.$lt{'sigmethod'}.':<select name="ltitools_sigmethod_'.$i.'">'. + '<option value="HMAC-SHA1"'.$sigsel{'HMAC-SHA1'}.'>HMAC-SHA1</option>'. + '<option value="HMAC-SHA256"'.$sigsel{'HMAC-SHA256'}.'>HMAC-SHA256</option></select></span>'. '<br /><br />'. - '<span class="LC_nobreak">'.$lt{'url'}.':<input type="text" size="30" name="ltitools_url_'.$i.'"'. + '<span class="LC_nobreak">'.$lt{'url'}.':<input type="text" size="40" name="ltitools_url_'.$i.'"'. ' value="'.$url.'" /></span>'. (' 'x2). - '<span class="LC_nobreak">'.$lt{'key'}. + '<span class="LC_nobreak">'.$lt{'key'}.':'. '<input type="text" size="25" name="ltitools_key_'.$i.'" value="'.$key.'" /></span> '. (' 'x2). + '<span class="LC_nobreak">'.$lt{'lifetime'}.':'. + '<input type="text" size="5" name="ltitools_lifetime_'.$i.'" value="'.$lifetime.'" /></span> '. + (' 'x2). '<span class="LC_nobreak">'.$lt{'secret'}.':'. '<input type="password" size="20" name="ltitools_secret_'.$i.'" value="'.$secret.'" />'. '<label><input type="checkbox" name="visible" onclick="if (this.checked) { this.form.ltitools_secret_'.$i.'.type='."'text'".' } else { this.form.ltitools_secret_'.$i.'.type='."'password'".' }" />'.&mt('Visible input').'</label>'. @@ -3900,27 +4062,14 @@ sub print_ltitools { '<input type="text" name="ltitools_'.$dimen.'_'.$i.'" size="5" value="'.$currdisp{$dimen}.'" /></label>'. (' 'x2); } - $datatable .= '<br />'. + $datatable .= '</span><br />'. '<div class="LC_left_float">'.$lt{'linktext'}.'<br />'. - '<input type="text" name="ltitools_linktext_'.$i.'" size="25" value="'.$currdisp{'linktext'}.'" /></label></div>'. + '<input type="text" name="ltitools_linktext_'.$i.'" size="25" value="'.$currdisp{'linktext'}.'" /></div>'. '<div class="LC_left_float">'.$lt{'explanation'}.'<br />'. '<textarea name="ltitools_explanation_'.$i.'" rows="5" cols="40">'.$currdisp{'explanation'}. - '</textarea></div><div style=""></div><br />'; - $datatable .= '<br />'; - foreach my $extra ('passback','roster') { - my $checkedon = ''; - my $checkedoff = ' checked="checked"'; - if ($settings->{$item}->{$extra}) { - $checkedon = $checkedoff; - $checkedoff = ''; - } - $datatable .= $lt{$extra}.' '. - '<label><input type="radio" name="ltitools_'.$extra.'_'.$i.'" value="1"'.$checkedon.' />'. - &mt('Yes').'</label>'.(' 'x2). - '<label><input type="radio" name="ltitools_'.$extra.'_'.$i.'" value="0"'.$checkedoff.' />'. - &mt('No').'</label>'.(' 'x4); - } - $datatable .= '<br /><br /><span class="LC_nobreak">'.$lt{'icon'}.': '; + '</textarea></div><div style=""></div>'. + '<div style="padding:0;clear:both;margin:0;border:0"></div>'; + $datatable .= '<span class="LC_nobreak">'.$lt{'icon'}.': '; if ($imgsrc) { $datatable .= $imgsrc. '<label><input type="checkbox" name="ltitools_image_del"'. @@ -3935,11 +4084,12 @@ sub print_ltitools { $datatable .= '<input type="file" name="ltitools_image_'.$i.'" value="" />'; } $datatable .= '</span></fieldset>'; - my (%checkedfields,%rolemaps); + my (%checkedfields,%rolemaps,$userincdom); if (ref($settings->{$item}) eq 'HASH') { if (ref($settings->{$item}->{'fields'}) eq 'HASH') { %checkedfields = %{$settings->{$item}->{'fields'}}; } + $userincdom = $settings->{$item}->{'incdom'}; if (ref($settings->{$item}->{'roles'}) eq 'HASH') { %rolemaps = %{$settings->{$item}->{'roles'}}; $checkedfields{'roles'} = 1; @@ -3947,16 +4097,40 @@ sub print_ltitools { } $datatable .= '<fieldset><legend>'.&mt('User data sent on launch').'</legend>'. '<span class="LC_nobreak">'; + my $userfieldstyle = 'display:none;'; + my $seluserdom = ''; + my $unseluserdom = ' selected="selected"'; foreach my $field (@fields) { - my $checked; + my ($checked,$onclick,$id,$spacer); if ($checkedfields{$field}) { $checked = ' checked="checked"'; } + if ($field eq 'user') { + $id = ' id="ltitools_user_field_'.$i.'"'; + $onclick = ' onclick="toggleLTITools(this.form,'."'$field','$i'".')"'; + if ($checked) { + $userfieldstyle = 'display:inline-block'; + if ($userincdom) { + $seluserdom = $unseluserdom; + $unseluserdom = ''; + } + } + } else { + $spacer = (' ' x2); + } $datatable .= '<label>'. - '<input type="checkbox" name="ltitools_fields_'.$i.'" value="'.$field.'"'.$checked.' />'. - $lt{$field}.'</label>'.(' ' x2); + '<input type="checkbox" name="ltitools_fields_'.$i.'" value="'.$field.'"'.$id.$checked.$onclick.' />'. + $lt{$field}.'</label>'.$spacer; } - $datatable .= '</span></fieldset>'. + $datatable .= '</span>'; + $datatable .= '<div style="'.$userfieldstyle.'" id="ltitools_user_div_'.$i.'">'. + '<span class="LC_nobreak"> : '. + '<select name="ltitools_userincdom_'.$i.'">'. + '<option value="">'.&mt('Select').'</option>'. + '<option value="0"'.$unseluserdom.'>'.&mt('username').'</option>'. + '<option value="1"'.$seluserdom.'>'.&mt('username:domain').'</option>'. + '</select></span></div>'; + $datatable .= '</fieldset>'. '<fieldset><legend>'.&mt('Role mapping').'</legend><table><tr>'; foreach my $role (@courseroles) { my ($selected,$selectnone); @@ -3987,7 +4161,7 @@ sub print_ltitools { } } $datatable .= '<fieldset><legend>'.&mt('Configurable in course').'</legend><span class="LC_nobreak">'; - foreach my $item ('label','title','target','linktext','explanation') { + foreach my $item ('label','title','target','linktext','explanation','append') { my $checked; if ($courseconfig{$item}) { $checked = ' checked="checked"'; @@ -4020,7 +4194,7 @@ sub print_ltitools { } } $css_class = $itemcount%2?' class="LC_odd_row"':''; - my $chgstr = ' onchange="javascript:reorderLTI(this.form,'."'ltitools_add_pos'".');"'; + my $chgstr = ' onchange="javascript:reorderLTITools(this.form,'."'ltitools_add_pos'".');"'; $datatable .= '<tr '.$css_class.'><td><span class="LC_nobreak">'."\n". '<input type="hidden" name="ltitools_maxnum" value="'.$maxnum.'" />'."\n". '<select name="ltitools_add_pos"'.$chgstr.'>'; @@ -4033,21 +4207,26 @@ sub print_ltitools { $datatable .= '<option value="'.$k.'"'.$selstr.'>'.$vpos.'</option>'; } $datatable .= '</select> '."\n". - '<input type="checkbox" name="ltitools_add" value="1" />'.&mt('Add').'</td>'."\n". + '<input type="checkbox" name="ltitools_add" value="1" />'.&mt('Add').'</span></td>'."\n". '<td colspan="2">'. '<fieldset><legend>'.&mt('Required settings').'</legend>'. - '<span class="LC_nobreak">'.$lt{'title'}.':<input type="text" size="30" name="ltitools_add_title" value="" /></span> '."\n". + '<span class="LC_nobreak">'.$lt{'title'}.':<input type="text" size="20" name="ltitools_add_title" value="" /></span> '."\n". (' 'x2). '<span class="LC_nobreak">'.$lt{'version'}.':<select name="ltitools_add_version">'. '<option value="LTI-1p0" selected="selected">1.1</option></select></span> '."\n". (' 'x2). '<span class="LC_nobreak">'.$lt{'msgtype'}.':<select name="ltitools_add_msgtype">'. '<option value="basic-lti-launch-request" selected="selected">Launch</option></select></span> '. + '<span class="LC_nobreak">'.$lt{'sigmethod'}.':<select name="ltitools_add_sigmethod">'. + '<option value="HMAC-SHA1" selected="selected">HMAC-SHA1</option>'. + '<option value="HMAC-SHA256">HMAC-SHA256</option></select></span>'. '<br />'. - '<span class="LC_nobreak">'.$lt{'url'}.':<input type="text" size="30" name="ltitools_add_url" value="" /></span> '."\n". + '<span class="LC_nobreak">'.$lt{'url'}.':<input type="text" size="40" name="ltitools_add_url" value="" /></span> '."\n". (' 'x2). '<span class="LC_nobreak">'.$lt{'key'}.':<input type="text" size="25" name="ltitools_add_key" value="" /></span> '."\n". (' 'x2). + '<span class="LC_nobreak">'.$lt{'lifetime'}.':<input type="text" size="5" name="ltitools_add_lifetime" value="300" /></span> '."\n". + (' 'x2). '<span class="LC_nobreak">'.$lt{'secret'}.':<input type="password" size="20" name="ltitools_add_secret" value="" />'. '<label><input type="checkbox" name="visible" onclick="if (this.checked) { this.form.ltitools_add_secret.type='."'text'".' } else { this.form.ltitools_add_secret.type='."'password'".' }" />'.&mt('Visible input').'</label></span> '."\n". '</fieldset>'. @@ -4065,20 +4244,14 @@ sub print_ltitools { '<input type="text" name="ltitools_add_'.$dimen.'" size="5" /></label>'. (' 'x2); } - $datatable .= '<br />'. + $datatable .= '</span><br />'. '<div class="LC_left_float">'.$lt{'linktext'}.'<br />'. - '<input type="text" name="ltitools_add_linktext" size="5" /></label></div>'. + '<input type="text" name="ltitools_add_linktext" size="5" /></div>'. '<div class="LC_left_float">'.$lt{'explanation'}.'<br />'. - '<textarea name=ltitools_add_explanation" rows="5" cols="40"></textarea>'. - '</div><div style=""></div><br />'; - foreach my $extra ('passback','roster') { - $datatable .= $lt{$extra}.' '. - '<label><input type="radio" name="ltitools_add_'.$extra.'" value="1" />'. - &mt('Yes').'</label>'.(' 'x2). - '<label><input type="radio" name="ltitools_add_'.$extra.'" value="0" checked="checked" />'. - &mt('No').'</label>'.(' 'x4); - } - $datatable .= '<br /><br /><span class="LC_nobreak">'.$lt{'icon'}.': '. + '<textarea name="ltitools_add_explanation" rows="5" cols="40"></textarea>'. + '</div><div style=""></div>'. + '<div style="padding:0;clear:both;margin:0;border:0"></div>'; + $datatable .= '<span class="LC_nobreak">'.$lt{'icon'}.': '. '('.&mt('if larger than 21x21 pixels, image will be scaled').') '; if ($switchserver) { $datatable .= &mt('Upload to library server: [_1]',$switchserver); @@ -4089,12 +4262,26 @@ sub print_ltitools { '<fieldset><legend>'.&mt('User data sent on launch').'</legend>'. '<span class="LC_nobreak">'; foreach my $field (@fields) { + my ($id,$onclick,$spacer); + if ($field eq 'user') { + $id = ' id="ltitools_user_field_add"'; + $onclick = ' onclick="toggleLTITools(this.form,'."'$field','add'".')"'; + } else { + $spacer = (' ' x2); + } $datatable .= '<label>'. - '<input type="checkbox" name="ltitools_add_fields" value="'.$field.'" />'. - $lt{$field}.'</label>'.(' ' x2); + '<input type="checkbox" name="ltitools_add_fields" value="'.$field.'"'.$id.$onclick.' />'. + $lt{$field}.'</label>'.$spacer; } - $datatable .= '</span></fieldset>'. - '<fieldset><legend>'.&mt('Role mapping').'</legend><table><tr>'; + $datatable .= '</span>'. + '<div style="display:none;" id="ltitools_user_div_add">'. + '<span class="LC_nobreak"> : '. + '<select name="ltitools_userincdom_add">'. + '<option value="" selected="selected">'.&mt('Select').'</option>'. + '<option value="0">'.&mt('username').'</option>'. + '<option value="1">'.&mt('username:domain').'</option>'. + '</select></span></div></fieldset>'; + $datatable .= '<fieldset><legend>'.&mt('Role mapping').'</legend><table><tr>'; foreach my $role (@courseroles) { my ($checked,$checkednone); $datatable .= '<td align="center">'. @@ -4108,7 +4295,7 @@ sub print_ltitools { } $datatable .= '</tr></table></fieldset>'. '<fieldset><legend>'.&mt('Configurable in course').'</legend><span class="LC_nobreak">'; - foreach my $item ('label','title','target','linktext','explanation') { + foreach my $item ('label','title','target','linktext','explanation','append') { $datatable .= '<label>'. '<input type="checkbox" name="ltitools_courseconfig" value="'.$item.'" checked="checked" />'. $lt{'crs'.$item}.'</label>'.(' ' x2)."\n"; @@ -4120,7 +4307,7 @@ sub print_ltitools { '<label><input type="checkbox" name="ltitools_add_custom" value="1" />'. &mt('Add').'</label></span></td><td><input type="text" name="ltitools_add_custom_name" />'. '</td><td><input type="text" name="ltitools_add_custom_value" /></td></tr>'. - '</table></fieldset></td></tr>'."\n". + '</table></fieldset>'."\n". '</td>'."\n". '</tr>'."\n"; $itemcount ++; @@ -4132,11 +4319,13 @@ sub ltitools_names { 'title' => 'Title', 'version' => 'Version', 'msgtype' => 'Message Type', + 'sigmethod' => 'Signature Method', 'url' => 'URL', 'key' => 'Key', + 'lifetime' => 'Nonce lifetime (s)', 'secret' => 'Secret', 'icon' => 'Icon', - 'user' => 'Username:domain', + 'user' => 'User', 'fullname' => 'Full Name', 'firstname' => 'First Name', 'lastname' => 'Last Name', @@ -4149,13 +4338,12 @@ sub ltitools_names { 'width' => 'Width', 'linktext' => 'Default Link Text', 'explanation' => 'Default Explanation', - 'passback' => 'Tool can return grades:', - 'roster' => 'Tool can retrieve roster:', 'crstarget' => 'Display target', 'crslabel' => 'Course label', 'crstitle' => 'Course title', 'crslinktext' => 'Link Text', 'crsexplanation' => 'Explanation', + 'crsappend' => 'Provider URL', ); return %lt; @@ -4227,7 +4415,7 @@ sub print_coursedefaults { my $currcanclone = 'none'; my $onclick; my @cloneoptions = ('none','domain'); - my %clonetitles = ( + my %clonetitles = &Apache::lonlocal::texthash ( none => 'No additional course requesters', domain => "Any course requester in course's domain", instcode => 'Course requests for official courses ...', @@ -4759,7 +4947,7 @@ sub print_passwords { $datatable .= '<span class="LC_nobreak"><label>'. '<input type="checkbox" name="passwords_case_sensitive" value="'. $item.'"'.$checkedcase.' />'.$usertypes->{$item}.'</label>'. - '<span> '; + '</span> '; } } my $checkedcase; @@ -4863,7 +5051,7 @@ sub print_passwords { &mt('(If you use the same account ... reset a password from this page.)').'</span><br /><br />'. &mt('Include custom text:'); if ($customurl) { - my $link = &Apache::loncommon::modal_link($customurl,&mt('Custom text file'),600,500, + my $link = &Apache::loncommon::modal_link($customurl,&mt('custom text'),600,500, undef,undef,undef,undef,'background-color:#ffffff'); $datatable .= '<span class="LC_nobreak"> '.$link. '<label><input type="checkbox" name="passwords_custom_del"'. @@ -5079,7 +5267,7 @@ sub print_passwords { $datatable .= '<span class="LC_nobreak"><label>'. '<input type="checkbox" name="passwords_crsowner_'.$item.'" value="'. $type.'"'.$checked.' />'.$usertypes->{$type}.'</label>'. - '<span> '; + '</span> '; } } my $checked; @@ -5109,13 +5297,18 @@ sub print_usersessions { if ($position eq 'top') { if (keys(%serverhomes) > 1) { my %spareid = ¤t_offloads_to($dom,$settings,\%servers); - my $curroffloadnow; + my ($curroffloadnow,$curroffloadoth); if (ref($settings) eq 'HASH') { if (ref($settings->{'offloadnow'}) eq 'HASH') { $curroffloadnow = $settings->{'offloadnow'}; } + if (ref($settings->{'offloadoth'}) eq 'HASH') { + $curroffloadoth = $settings->{'offloadoth'}; + } } - $datatable .= &spares_row($dom,\%servers,\%spareid,\%serverhomes,\%altids,$curroffloadnow,$rowtotal); + my $other_insts = scalar(keys(%by_location)); + $datatable .= &spares_row($dom,\%servers,\%spareid,\%serverhomes,\%altids, + $other_insts,$curroffloadnow,$curroffloadoth,$rowtotal); } else { $datatable .= '<tr'.$css_class.'><td colspan="2">'. &mt('Nothing to set here, as the cluster to which this domain belongs only contains one server.'); @@ -5365,7 +5558,8 @@ sub current_offloads_to { } sub spares_row { - my ($dom,$servers,$spareid,$serverhomes,$altids,$curroffloadnow,$rowtotal) = @_; + my ($dom,$servers,$spareid,$serverhomes,$altids,$other_insts, + $curroffloadnow,$curroffloadoth,$rowtotal) = @_; my $css_class; my $numinrow = 4; my $itemcount = 1; @@ -5385,12 +5579,17 @@ sub spares_row { } } next unless (ref($spareid->{$server}) eq 'HASH'); - my $checkednow; + my ($checkednow,$checkedoth); if (ref($curroffloadnow) eq 'HASH') { if ($curroffloadnow->{$server}) { $checkednow = ' checked="checked"'; } } + if (ref($curroffloadoth) eq 'HASH') { + if ($curroffloadoth->{$server}) { + $checkedoth = ' checked="checked"'; + } + } $css_class = $itemcount%2 ? ' class="LC_odd_row"' : ''; $datatable .= '<tr'.$css_class.'> <td rowspan="2"> @@ -5399,8 +5598,15 @@ sub spares_row { ,'<b>'.$server.'</b>').'</span><br />'. '<span class="LC_nobreak">'."\n". '<label><input type="checkbox" name="offloadnow" value="'.$server.'"'.$checkednow.' />'. - ' '.&mt('Switch active users on next access').'</label></span>'. + ' '.&mt('Switch any active user on next access').'</label></span>'. "\n"; + if ($other_insts) { + $datatable .= '<br />'. + '<span class="LC_nobreak">'."\n". + '<label><input type="checkbox" name="offloadoth" value="'.$server.'"'.$checkedoth.' />'. + ' '.&mt('Switch other institutions on next access').'</label></span>'. + "\n"; + } my (%current,%canselect); my @choices = &possible_newspares($server,$spareid->{$server},$serverhomes,$altids); @@ -5919,6 +6125,10 @@ sub contact_titles { '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', 'hostipmail' => 'E-mail from nightly check of hostname/IP network changes', + 'errorthreshold' => 'Error count threshold for status e-mail to admin(s)', + 'errorsysmail' => 'Error count threshold for e-mail to developer group', + 'errorweights' => 'Weights used to compute error count', + 'errorexcluded' => 'Servers with unsent updates excluded from count', ); my %short_titles = &Apache::lonlocal::texthash ( adminemail => 'Admin E-mail address', @@ -6961,7 +7171,7 @@ sub print_defaults { $datatable .= '</select> '.&mt('Internal ID:').' <b>'.$item.'</b> '. '<input type="checkbox" name="inststatus_delete" value="'.$item.'" />'. &mt('delete').'</span></td>'. - '<td class="LC_left_item"><span class="LC_nobreak">'.&mt('Name displayed:'). + '<td class="LC_left_item"><span class="LC_nobreak">'.&mt('Name displayed').':'. '<input type="text" size="20" name="inststatus_title_'.$item.'" value="'.$title.'" />'. '</span></td></tr>'; } @@ -6981,7 +7191,7 @@ sub print_defaults { '<input type="text" size="10" name="addinststatus" value="" />'. ' '.&mt('(new)'). '</span></td><td class="LC_left_item"><span class="LC_nobreak">'. - &mt('Name displayed:'). + &mt('Name displayed').':'. '<input type="text" size="20" name="addinststatus_title" value="" /></span></td>'. '</tr>'."\n"; $rownum ++; @@ -7830,8 +8040,8 @@ function warnIntPass(field) { alert('$intalert{passnum}'); } } + field.value = ''; } - field.value = ''; } } } @@ -7951,7 +8161,7 @@ ENDSCRIPT sub initialize_categories { my ($itemcount) = @_; my ($datatable,$css_class,$chgstr); - my %default_names = ( + my %default_names = &Apache::lonlocal::texthash ( instcode => 'Official courses (with institutional codes)', communities => 'Communities', ); @@ -7984,7 +8194,7 @@ sub initialize_categories { .'<option value="0">1</option>' .'<option value="1">2</option>' .'<option value="2" selected="selected">3</option></select> ' - .&mt('Add category').'</span></td><tda<span class="LC_nobreak">>'.&mt('Name:') + .&mt('Add category').'</span></td><td><span class="LC_nobreak">'.&mt('Name:') .' <input type="text" size="20" name="addcategory_name" value="" /></span>' .'</td></tr>'; return $datatable; @@ -10364,8 +10574,11 @@ sub modify_ltitools { $allpos[$position] = $newid; } $changes{$newid} = 1; - foreach my $item ('title','url','key','secret') { + foreach my $item ('title','url','key','secret','lifetime') { $env{'form.ltitools_add_'.$item} =~ s/(`)/'/g; + if ($item eq 'lifetime') { + $env{'form.ltitools_add_'.$item} =~ s/[^\d.]//g; + } if ($env{'form.ltitools_add_'.$item}) { if (($item eq 'key') || ($item eq 'secret')) { $encconfig{$newid}{$item} = $env{'form.ltitools_add_'.$item}; @@ -10380,6 +10593,11 @@ sub modify_ltitools { if ($env{'form.ltitools_add_msgtype'} eq 'basic-lti-launch-request') { $confhash{$newid}{'msgtype'} = $env{'form.ltitools_add_msgtype'}; } + if ($env{'form.ltitools_add_sigmethod'} eq 'HMAC-SHA256') { + $confhash{$newid}{'sigmethod'} = $env{'form.ltitools_add_sigmethod'}; + } else { + $confhash{$newid}{'sigmethod'} = 'HMAC-SHA1'; + } foreach my $item ('width','height','linktext','explanation') { $env{'form.ltitools_add_'.$item} =~ s/^\s+//; $env{'form.ltitools_add_'.$item} =~ s/\s+$//; @@ -10400,11 +10618,6 @@ sub modify_ltitools { } else { $confhash{$newid}{'display'}{'target'} = 'iframe'; } - foreach my $item ('passback','roster') { - if ($env{'form.ltitools_add_'.$item}) { - $confhash{$newid}{$item} = 1; - } - } if ($env{'form.ltitools_add_image.filename'} ne '') { my ($imageurl,$error) = &process_ltitools_image($r,$dom,$confname,'ltitools_add_image',$newid, @@ -10435,6 +10648,13 @@ sub modify_ltitools { } } } + if (ref($confhash{$newid}{'fields'}) eq 'HASH') { + if ($confhash{$newid}{'fields'}{'user'}) { + if ($env{'form.ltitools_userincdom_add'}) { + $confhash{$newid}{'incdom'} = 1; + } + } + } my @courseconfig = &Apache::loncommon::get_env_multiple('form.ltitools_courseconfig'); foreach my $item (@courseconfig) { $confhash{$newid}{'crsconf'}{$item} = 1; @@ -10481,7 +10701,7 @@ sub modify_ltitools { } else { my $newpos = $env{'form.ltitools_'.$itemid}; $newpos =~ s/\D+//g; - foreach my $item ('title','url') { + foreach my $item ('title','url','lifetime') { $confhash{$itemid}{$item} = $env{'form.ltitools_'.$item.'_'.$i}; if ($domconfig{$action}{$itemid}{$item} ne $confhash{$itemid}{$item}) { $changes{$itemid} = 1; @@ -10499,6 +10719,18 @@ sub modify_ltitools { if ($env{'form.ltitools_msgtype_'.$i} eq 'basic-lti-launch-request') { $confhash{$itemid}{'msgtype'} = $env{'form.ltitools_msgtype_'.$i}; } + if ($env{'form.ltitools_sigmethod_'.$i} eq 'HMAC-SHA256') { + $confhash{$itemid}{'sigmethod'} = $env{'form.ltitools_sigmethod_'.$i}; + } else { + $confhash{$itemid}{'sigmethod'} = 'HMAC-SHA1'; + } + if ($domconfig{$action}{$itemid}{'sigmethod'} eq '') { + if ($confhash{$itemid}{'sigmethod'} ne 'HMAC-SHA1') { + $changes{$itemid} = 1; + } + } elsif ($domconfig{$action}{$itemid}{'sigmethod'} ne $confhash{$itemid}{'sigmethod'}) { + $changes{$itemid} = 1; + } foreach my $size ('width','height') { $env{'form.ltitools_'.$size.'_'.$i} =~ s/^\s+//; $env{'form.ltitools_'.$size.'_'.$i} =~ s/\s+$//; @@ -10549,16 +10781,8 @@ sub modify_ltitools { } else { $changes{$itemid} = 1; } - foreach my $extra ('passback','roster') { - if ($env{'form.ltitools_'.$extra.'_'.$i}) { - $confhash{$itemid}{$extra} = 1; - } - if ($domconfig{$action}{$itemid}{$extra} ne $confhash{$itemid}{$extra}) { - $changes{$itemid} = 1; - } - } my @courseconfig = &Apache::loncommon::get_env_multiple('form.ltitools_courseconfig_'.$i); - foreach my $item ('label','title','target','linktext','explanation') { + foreach my $item ('label','title','target','linktext','explanation','append') { if (grep(/^\Q$item\E$/,@courseconfig)) { $confhash{$itemid}{'crsconf'}{$item} = 1; if (ref($domconfig{$action}{$itemid}{'crsconf'}) eq 'HASH') { @@ -10602,6 +10826,16 @@ sub modify_ltitools { } } } + if (ref($confhash{$itemid}{'fields'}) eq 'HASH') { + if ($confhash{$itemid}{'fields'}{'user'}) { + if ($env{'form.ltitools_userincdom_'.$i}) { + $confhash{$itemid}{'incdom'} = 1; + } + if ($domconfig{$action}{$itemid}{'incdom'} ne $confhash{$itemid}{'incdom'}) { + $changes{$itemid} = 1; + } + } + } $allpos[$newpos] = $itemid; } if ($imgdeletions{$itemid}) { @@ -10735,7 +10969,7 @@ sub modify_ltitools { $resulttext .= '</li><ul>'; my $position = $pos + 1; $resulttext .= '<li>'.&mt('Order: [_1]',$position).'</li>'; - foreach my $item ('version','msgtype','url') { + foreach my $item ('version','msgtype','sigmethod','url','lifetime') { if ($confhash{$itemid}{$item} ne '') { $resulttext .= '<li>'.$lt{$item}.': '.$confhash{$itemid}{$item}.'</li>'; } @@ -10749,7 +10983,7 @@ sub modify_ltitools { $resulttext .= ('*'x$num).'</li>'; } $resulttext .= '<li>'.&mt('Configurable in course:'); - my @possconfig = ('label','title','target','linktext','explanation'); + my @possconfig = ('label','title','target','linktext','explanation','append'); my $numconfig = 0; if (ref($confhash{$itemid}{'crsconf'}) eq 'HASH') { foreach my $item (@possconfig) { @@ -10763,15 +10997,6 @@ sub modify_ltitools { $resulttext .= &mt('None'); } $resulttext .= '</li>'; - foreach my $item ('passback','roster') { - $resulttext .= '<li>'.$lt{$item}.' '; - if ($confhash{$itemid}{$item}) { - $resulttext .= &mt('Yes'); - } else { - $resulttext .= &mt('No'); - } - $resulttext .= '</li>'; - } if (ref($confhash{$itemid}{'display'}) eq 'HASH') { my $displaylist; if ($confhash{$itemid}{'display'}{'target'}) { @@ -10803,6 +11028,13 @@ sub modify_ltitools { } if ($fieldlist) { $fieldlist =~ s/,$//; + if ($confhash{$itemid}{'fields'}{'user'}) { + if ($confhash{$itemid}{'incdom'}) { + $fieldlist .= ' ('.&mt('username:domain').')'; + } else { + $fieldlist .= ' ('.&mt('username').')'; + } + } $resulttext .= '<li>'.&mt('Data sent').':'.$fieldlist.'</li>'; } } @@ -10827,7 +11059,7 @@ sub modify_ltitools { } } if ($customlist) { - $resulttext .= '<li>'.&mt('Custom items').':'.$customlist.'</li>'; + $resulttext .= '<li>'.&mt('Custom items').': '.$customlist.'</li>'; } } $resulttext .= '</ul></li>'; @@ -11509,7 +11741,8 @@ sub modify_contacts { my @contacts = ('supportemail','adminemail'); my @mailings = ('errormail','packagesmail','helpdeskmail','otherdomsmail', 'lonstatusmail','requestsmail','updatesmail','idconflictsmail','hostipmail'); - my @toggles = ('reporterrors','reportupdates'); + my @toggles = ('reporterrors','reportupdates','reportstatus'); + my @lonstatus = ('threshold','sysmail','weights','excluded'); my ($fields,$fieldtitles,$fieldoptions,$possoptions) = &helpform_fields(); foreach my $type (@mailings) { @{$newsetting{$type}} = @@ -11542,6 +11775,41 @@ sub modify_contacts { $contacts_hash{'contacts'}{$item} = $env{'form.'.$item}; } } + my ($lonstatus_defs,$lonstatus_names) = &Apache::loncommon::lon_status_items(); + foreach my $item (@lonstatus) { + if ($item eq 'excluded') { + my (%serverhomes,@excluded); + map { $serverhomes{$_} = 1; } values(%Apache::lonnet::serverhomeIDs); + my @possexcluded = &Apache::loncommon::get_env_multiple('form.errorexcluded'); + if (@possexcluded) { + foreach my $id (sort(@possexcluded)) { + if ($serverhomes{$id}) { + push(@excluded,$id); + } + } + } + if (@excluded) { + $contacts_hash{'contacts'}{'lonstatus'}{$item} = \@excluded; + } + } elsif ($item eq 'weights') { + foreach my $type ('E','W','N','U') { + $env{'form.error'.$item.'_'.$type} =~ s/^\s+|\s+$//g; + if ($env{'form.error'.$item.'_'.$type} =~ /^\d+$/) { + unless ($env{'form.error'.$item.'_'.$type} == $lonstatus_defs->{$type}) { + $contacts_hash{'contacts'}{'lonstatus'}{$item}{$type} = + $env{'form.error'.$item.'_'.$type}; + } + } + } + } elsif (($item eq 'threshold') || ($item eq 'sysmail')) { + $env{'form.error'.$item} =~ s/^\s+|\s+$//g; + if ($env{'form.error'.$item} =~ /^\d+$/) { + unless ($env{'form.error'.$item} == $lonstatus_defs->{$item}) { + $contacts_hash{'contacts'}{'lonstatus'}{$item} = $env{'form.error'.$item}; + } + } + } + } if ((ref($fields) eq 'ARRAY') && (ref($possoptions) eq 'HASH')) { foreach my $field (@{$fields}) { if (ref($possoptions->{$field}) eq 'ARRAY') { @@ -11680,6 +11948,76 @@ sub modify_contacts { } } } + if (ref($currsetting{'lonstatus'}) eq 'HASH') { + foreach my $key ('excluded','weights','threshold','sysmail') { + if ($key eq 'excluded') { + if ((ref($contacts_hash{contacts}{lonstatus}) eq 'HASH') && + (ref($contacts_hash{contacts}{lonstatus}{excluded}) eq 'ARRAY')) { + if ((ref($currsetting{'lonstatus'}{$key}) eq 'ARRAY') && + (@{$currsetting{'lonstatus'}{$key}})) { + my @diffs = + &Apache::loncommon::compare_arrays($contacts_hash{contacts}{lonstatus}{excluded}, + $currsetting{'lonstatus'}{$key}); + if (@diffs) { + push(@{$changes{'lonstatus'}},$key); + } + } elsif (@{$contacts_hash{contacts}{lonstatus}{excluded}}) { + push(@{$changes{'lonstatus'}},$key); + } + } elsif ((ref($currsetting{'lonstatus'}{$key}) eq 'ARRAY') && + (@{$currsetting{'lonstatus'}{$key}})) { + push(@{$changes{'lonstatus'}},$key); + } + } elsif ($key eq 'weights') { + if ((ref($contacts_hash{contacts}{lonstatus}) eq 'HASH') && + (ref($contacts_hash{contacts}{lonstatus}{$key}) eq 'HASH')) { + if (ref($currsetting{'lonstatus'}{$key}) eq 'HASH') { + foreach my $type ('E','W','N','U') { + unless ($contacts_hash{contacts}{lonstatus}{$key}{$type} eq + $currsetting{'lonstatus'}{$key}{$type}) { + push(@{$changes{'lonstatus'}},$key); + last; + } + } + } else { + foreach my $type ('E','W','N','U') { + if ($contacts_hash{contacts}{lonstatus}{$key}{$type} ne '') { + push(@{$changes{'lonstatus'}},$key); + last; + } + } + } + } elsif (ref($currsetting{'lonstatus'}{$key}) eq 'HASH') { + foreach my $type ('E','W','N','U') { + if ($currsetting{'lonstatus'}{$key}{$type} ne '') { + push(@{$changes{'lonstatus'}},$key); + last; + } + } + } + } elsif (($key eq 'threshold') || ($key eq 'sysmail')) { + if (ref($contacts_hash{contacts}{lonstatus}) eq 'HASH') { + if ($currsetting{'lonstatus'}{$key} =~ /^\d+$/) { + if ($currsetting{'lonstatus'}{$key} != $contacts_hash{contacts}{lonstatus}{$key}) { + push(@{$changes{'lonstatus'}},$key); + } + } elsif ($contacts_hash{contacts}{lonstatus}{$key} =~ /^\d+$/) { + push(@{$changes{'lonstatus'}},$key); + } + } elsif ($currsetting{'lonstatus'}{$key} =~ /^\d+$/) { + push(@{$changes{'lonstatus'}},$key); + } + } + } + } else { + if (ref($contacts_hash{contacts}{lonstatus}) eq 'HASH') { + foreach my $key ('excluded','weights','threshold','sysmail') { + if (exists($contacts_hash{contacts}{lonstatus}{$key})) { + push(@{$changes{'lonstatus'}},$key); + } + } + } + } } else { my %default; $default{'supportemail'} = $Apache::lonnet::perlvar{'lonSupportEMail'}; @@ -11725,6 +12063,13 @@ sub modify_contacts { } } } + if (ref($contacts_hash{contacts}{lonstatus}) eq 'HASH') { + foreach my $key ('excluded','weights','threshold','sysmail') { + if (exists($contacts_hash{contacts}{lonstatus}{$key})) { + push(@{$changes{'lonstatus'}},$key); + } + } + } } foreach my $item (@toggles) { if (($env{'form.'.$item} == 1) && ($currsetting{$item} == 0)) { @@ -11850,22 +12195,79 @@ sub modify_contacts { } } my @offon = ('off','on'); + my $corelink = &core_link_msu(); if ($changes{'reporterrors'}) { $resulttext .= '<li>'. &mt('E-mail error reports to [_1] set to "'. $offon[$env{'form.reporterrors'}].'".', - &Apache::loncommon::modal_link('http://loncapa.org/core.html', - &mt('LON-CAPA core group - MSU'),600,500)). + $corelink). '</li>'; } if ($changes{'reportupdates'}) { $resulttext .= '<li>'. &mt('E-mail record of completed LON-CAPA updates to [_1] set to "'. $offon[$env{'form.reportupdates'}].'".', - &Apache::loncommon::modal_link('http://loncapa.org/core.html', - &mt('LON-CAPA core group - MSU'),600,500)). + $corelink). '</li>'; } + if ($changes{'reportstatus'}) { + $resulttext .= '<li>'. + &mt('E-mail status if errors above threshold to [_1] set to "'. + $offon[$env{'form.reportstatus'}].'".', + $corelink). + '</li>'; + } + if (ref($changes{'lonstatus'}) eq 'ARRAY') { + $resulttext .= '<li>'. + &mt('Nightly status check e-mail settings').':<ul>'; + my (%defval,%use_def,%shown); + $defval{'threshold'} = $lonstatus_defs->{'threshold'}; + $defval{'sysmail'} = $lonstatus_defs->{'sysmail'}; + $defval{'weights'} = + join(', ',map { $lonstatus_names->{$_}.'='.$lonstatus_defs->{$_}; } ('E','W','N','U')); + $defval{'excluded'} = &mt('None'); + if (ref($contacts_hash{'contacts'}{'lonstatus'}) eq 'HASH') { + foreach my $item ('threshold','sysmail','weights','excluded') { + if (exists($contacts_hash{'contacts'}{'lonstatus'}{$item})) { + if (($item eq 'threshold') || ($item eq 'sysmail')) { + $shown{$item} = $contacts_hash{'contacts'}{'lonstatus'}{$item}; + } elsif ($item eq 'weights') { + if (ref($contacts_hash{'contacts'}{'lonstatus'}{$item}) eq 'HASH') { + foreach my $type ('E','W','N','U') { + $shown{$item} .= $lonstatus_names->{$type}.'='; + if (exists($contacts_hash{'contacts'}{'lonstatus'}{$item}{$type})) { + $shown{$item} .= $contacts_hash{'contacts'}{'lonstatus'}{$item}{$type}; + } else { + $shown{$item} .= $lonstatus_defs->{$type}; + } + $shown{$item} .= ', '; + } + $shown{$item} =~ s/, $//; + } else { + $shown{$item} = $defval{$item}; + } + } elsif ($item eq 'excluded') { + if (ref($contacts_hash{'contacts'}{'lonstatus'}{$item}) eq 'ARRAY') { + $shown{$item} = join(', ',@{$contacts_hash{'contacts'}{'lonstatus'}{$item}}); + } else { + $shown{$item} = $defval{$item}; + } + } + } else { + $shown{$item} = $defval{$item}; + } + } + } else { + foreach my $item ('threshold','weights','excluded','sysmail') { + $shown{$item} = $defval{$item}; + } + } + foreach my $item ('threshold','weights','excluded','sysmail') { + $resulttext .= '<li>'.&mt($titles->{'error'.$item}.' -- [_1]', + $shown{$item}).'</li>'; + } + $resulttext .= '</ul></li>'; + } if ((ref($changes{'helpform'}) eq 'ARRAY') && (ref($fields) eq 'ARRAY')) { my (@optional,@required,@unused,$maxsizechg); foreach my $field (@{$changes{'helpform'}}) { @@ -12174,6 +12576,8 @@ sub modify_passwords { if ($staticdefaults{$rule} ne $newvalues{$rule}) { $changes{'rules'} = 1; } + } else { + $changes{'rules'} = 1; } } elsif (exists($current{$rule})) { $changes{'rules'} = 1; @@ -12252,9 +12656,11 @@ sub modify_passwords { $resulttext .= '<li>'.&mt('CAPTCHA validation set to use: original CAPTCHA').'</li>'; } elsif ($confighash{'passwords'}{'captcha'} eq 'recaptcha') { $resulttext .= '<li>'.&mt('CAPTCHA validation set to use: reCAPTCHA').' '. - &mt('version: [_1]',$confighash{'passwords'}{'recaptchaversion'}).'<br />'. - &mt('Public key: [_1]',$confighash{'passwords'}{'recaptchapub'}).'</br>'. - &mt('Private key: [_1]',$confighash{'passwords'}{'recaptchapriv'}).'</li>'; + &mt('version: [_1]',$confighash{'passwords'}{'recaptchaversion'}).'<br />'; + if (ref($confighash{'passwords'}{'recaptchakeys'}) eq 'HASH') { + $resulttext .= &mt('Public key: [_1]',$confighash{'passwords'}{'recaptchakeys'}{'public'}).'</br>'. + &mt('Private key: [_1]',$confighash{'passwords'}{'recaptchakeys'}{'private'}).'</li>'; + } } else { $resulttext .= '<li>'.&mt('No CAPTCHA validation').'</li>'; } @@ -12324,7 +12730,7 @@ sub modify_passwords { $resulttext .= '<li>'.&mt('E-mail address(es) in LON-CAPA used for verification will include: [_1]',join(', ',map { $titles{$_}; } @{$staticdefaults{'resetemail'}})).'</li>'; } } else { - $resulttext .= '<li>'.&mt('E-mail address(es) in LON-CAPA usedfor verification will include: [_1]',join(', ',map { $titles{$_}; } @{$staticdefaults{'resetemail'}})).'</li>'; + $resulttext .= '<li>'.&mt('E-mail address(es) in LON-CAPA used for verification will include: [_1]',join(', ',map { $titles{$_}; } @{$staticdefaults{'resetemail'}})).'</li>'; } if ($confighash{'passwords'}{'resetremove'}) { $resulttext .= '<li>'.&mt('Preamble to "Forgot Password" web form not shown').'</li>'; @@ -12333,8 +12739,9 @@ sub modify_passwords { } if ($confighash{'passwords'}{'resetcustom'}) { my $customlink = &Apache::loncommon::modal_link($confighash{'passwords'}{'resetcustom'}, - $titles{custom},600,500); - $resulttext .= '<li>'.&mt('Preamble to "Forgot Password" form includes [_1]',$customlink).'</li>'; + &mt('custom text'),600,500,undef,undef, + undef,undef,'background-color:#ffffff'); + $resulttext .= '<li>'.&mt('Preamble to "Forgot Password" form includes: [_1]',$customlink).'</li>'; } else { $resulttext .= '<li>'.&mt('No custom text included in preamble to "Forgot Password" form').'</li>'; } @@ -12380,6 +12787,24 @@ sub modify_passwords { $resulttext .= '<li>'.&mt('[_1] set to [_2]',$titles{$rule},$confighash{'passwords'}{$rule}).'</li>'; } } + if (ref($confighash{'passwords'}{'chars'}) eq 'ARRAY') { + if (@{$confighash{'passwords'}{'chars'}} > 0) { + my %rulenames = &Apache::lonlocal::texthash( + uc => 'At least one upper case letter', + lc => 'At least one lower case letter', + num => 'At least one number', + spec => 'At least one non-alphanumeric', + ); + my $needed = '<ul><li>'. + join('</li><li>',map {$rulenames{$_} } @{$confighash{'passwords'}{'chars'}}). + '</li></ul>'; + $resulttext .= '<li>'.&mt('[_1] set to: [_2]',$titles{'chars'},$needed).'</li>'; + } else { + $resulttext .= '<li>'.&mt('[_1] set to none',$titles{'chars'}).'</li>'; + } + } else { + $resulttext .= '<li>'.&mt('[_1] set to none',$titles{'chars'}).'</li>'; + } } elsif ($key eq 'crsownerchg') { if (ref($confighash{'passwords'}{'crsownerchg'}) eq 'HASH') { if ((@{$confighash{'passwords'}{'crsownerchg'}{'by'}} == 0) || @@ -13520,13 +13945,17 @@ sub modify_selfcreation { } sub process_captcha { - my ($container,$changes,$newsettings,$current) = @_; - return unless ((ref($changes) eq 'HASH') && (ref($newsettings) eq 'HASH') || (ref($current) eq 'HASH')); + my ($container,$changes,$newsettings,$currsettings) = @_; + return unless ((ref($changes) eq 'HASH') && (ref($newsettings) eq 'HASH')); $newsettings->{'captcha'} = $env{'form.'.$container.'_captcha'}; unless ($newsettings->{'captcha'} eq 'recaptcha' || $newsettings->{'captcha'} eq 'notused') { $newsettings->{'captcha'} = 'original'; } - if ($current->{'captcha'} ne $newsettings->{'captcha'}) { + my %current; + if (ref($currsettings) eq 'HASH') { + %current = %{$currsettings}; + } + if ($current{'captcha'} ne $newsettings->{'captcha'}) { if ($container eq 'cancreate') { if (ref($changes->{'cancreate'}) eq 'ARRAY') { push(@{$changes->{'cancreate'}},'captcha'); @@ -13556,9 +13985,9 @@ sub process_captcha { } $newsettings->{'recaptchaversion'} = $newversion; } - if (ref($current->{'recaptchakeys'}) eq 'HASH') { - $currpub = $current->{'recaptchakeys'}{'public'}; - $currpriv = $current->{'recaptchakeys'}{'private'}; + if (ref($current{'recaptchakeys'}) eq 'HASH') { + $currpub = $current{'recaptchakeys'}{'public'}; + $currpriv = $current{'recaptchakeys'}{'private'}; unless ($newsettings->{'captcha'} eq 'recaptcha') { $newsettings->{'recaptchakeys'} = { public => '', @@ -13566,8 +13995,8 @@ sub process_captcha { } } } - if ($current->{'captcha'} eq 'recaptcha') { - $currversion = $current->{'recaptchaversion'}; + if ($current{'captcha'} eq 'recaptcha') { + $currversion = $current{'recaptchaversion'}; if ($currversion ne '2') { $currversion = 1; } @@ -15634,6 +16063,7 @@ sub modify_usersessions { } } $defaultshash{'usersessions'}{'offloadnow'} = {}; + $defaultshash{'usersessions'}{'offloadoth'} = {}; my @offloadnow = &Apache::loncommon::get_env_multiple('form.offloadnow'); my @okoffload; if (@offloadnow) { @@ -15650,6 +16080,22 @@ sub modify_usersessions { } } } + my @offloadoth = &Apache::loncommon::get_env_multiple('form.offloadoth'); + my @okoffloadoth; + if (@offloadoth) { + foreach my $server (@offloadoth) { + if (&Apache::lonnet::hostname($server) ne '') { + unless (grep(/^\Q$server\E$/,@okoffloadoth)) { + push(@okoffloadoth,$server); + } + } + } + if (@okoffloadoth) { + foreach my $lonhost (@okoffloadoth) { + $defaultshash{'usersessions'}{'offloadoth'}{$lonhost} = 1; + } + } + } if (ref($domconfig{'usersessions'}) eq 'HASH') { if (ref($domconfig{'usersessions'}{'spares'}) eq 'HASH') { if (ref($changes{'spares'}) eq 'HASH') { @@ -15660,26 +16106,38 @@ sub modify_usersessions { } else { $savespares = 1; } - if (ref($domconfig{'usersessions'}{'offloadnow'}) eq 'HASH') { - foreach my $lonhost (keys(%{$domconfig{'usersessions'}{'offloadnow'}})) { - unless ($defaultshash{'usersessions'}{'offloadnow'}{$lonhost}) { - $changes{'offloadnow'} = 1; - last; - } - } - unless ($changes{'offloadnow'}) { - foreach my $lonhost (keys(%{$defaultshash{'usersessions'}{'offloadnow'}})) { - unless ($domconfig{'usersessions'}{'offloadnow'}{$lonhost}) { - $changes{'offloadnow'} = 1; + foreach my $offload ('offloadnow','offloadoth') { + if (ref($domconfig{'usersessions'}{$offload}) eq 'HASH') { + foreach my $lonhost (keys(%{$domconfig{'usersessions'}{$offload}})) { + unless ($defaultshash{'usersessions'}{$offload}{$lonhost}) { + $changes{$offload} = 1; last; } } + unless ($changes{$offload}) { + foreach my $lonhost (keys(%{$defaultshash{'usersessions'}{$offload}})) { + unless ($domconfig{'usersessions'}{$offload}{$lonhost}) { + $changes{$offload} = 1; + last; + } + } + } + } else { + if (($offload eq 'offloadnow') && (@okoffload)) { + $changes{'offloadnow'} = 1; + } + if (($offload eq 'offloadoth') && (@okoffloadoth)) { + $changes{'offloadoth'} = 1; + } } - } elsif (@okoffload) { + } + } else { + if (@okoffload) { $changes{'offloadnow'} = 1; } - } elsif (@okoffload) { - $changes{'offloadnow'} = 1; + if (@okoffloadoth) { + $changes{'offloadoth'} = 1; + } } my $nochgmsg = &mt('No changes made to settings for user session hosting/offloading.'); if ((keys(%changes) > 0) || ($savespares)) { @@ -15696,6 +16154,9 @@ sub modify_usersessions { if (ref($defaultshash{'usersessions'}{'offloadnow'}) eq 'HASH') { $domdefaults{'offloadnow'} = $defaultshash{'usersessions'}{'offloadnow'}; } + if (ref($defaultshash{'usersessions'}{'offloadoth'}) eq 'HASH') { + $domdefaults{'offloadoth'} = $defaultshash{'usersessions'}{'offloadoth'}; + } } my $cachetime = 24*60*60; &Apache::lonnet::do_cache_new('domdefaults',$dom,\%domdefaults,$cachetime); @@ -15769,16 +16230,31 @@ sub modify_usersessions { if ($changes{'offloadnow'}) { if (ref($defaultshash{'usersessions'}{'offloadnow'}) eq 'HASH') { if (keys(%{$defaultshash{'usersessions'}{'offloadnow'}}) > 0) { - $resulttext .= '<li>'.&mt('Switch active users on next access, for server(s):').'<ul>'; + $resulttext .= '<li>'.&mt('Switch any active user on next access, for server(s):').'<ul>'; foreach my $lonhost (sort(keys(%{$defaultshash{'usersessions'}{'offloadnow'}}))) { $resulttext .= '<li>'.$lonhost.'</li>'; } $resulttext .= '</ul>'; } else { - $resulttext .= '<li>'.&mt('No servers now set to switch active users on next access.'); + $resulttext .= '<li>'.&mt('No servers now set to switch any active user on next access.'); } } else { - $resulttext .= '<li>'.&mt('No servers now set to switch active users on next access.').'</li>'; + $resulttext .= '<li>'.&mt('No servers now set to switch any active user on next access.').'</li>'; + } + } + if ($changes{'offloadoth'}) { + if (ref($defaultshash{'usersessions'}{'offloadoth'}) eq 'HASH') { + if (keys(%{$defaultshash{'usersessions'}{'offloadoth'}}) > 0) { + $resulttext .= '<li>'.&mt('Switch other institutions on next access, for server(s):').'<ul>'; + foreach my $lonhost (sort(keys(%{$defaultshash{'usersessions'}{'offloadoth'}}))) { + $resulttext .= '<li>'.$lonhost.'</li>'; + } + $resulttext .= '</ul>'; + } else { + $resulttext .= '<li>'.&mt('No servers now set to switch other institutions on next access.'); + } + } else { + $resulttext .= '<li>'.&mt('No servers now set to switch other institutions on next access.').'</li>'; } } $resulttext .= '</ul>'; @@ -16032,24 +16508,24 @@ sub modify_loadbalancing { $resulttext .= '<li>'.&mt('Load Balancer: [_1] -- cookie use enabled', $balancer).'</li>'; } - if (keys(%toupdate)) { - my %thismachine; - my $updatedhere; - my $cachetime = 60*60*24; - map { $thismachine{$_} = 1; } &Apache::lonnet::current_machine_ids(); - foreach my $lonhost (keys(%toupdate)) { - if ($thismachine{$lonhost}) { - unless ($updatedhere) { - &Apache::lonnet::do_cache_new('loadbalancing',$dom, - $defaultshash{'loadbalancing'}, - $cachetime); - $updatedhere = 1; - } - } else { - my $cachekey = &escape('loadbalancing').':'.&escape($dom); - &Apache::lonnet::remote_devalidate_cache($lonhost,[$cachekey]); - } + } + } + if (keys(%toupdate)) { + my %thismachine; + my $updatedhere; + my $cachetime = 60*60*24; + map { $thismachine{$_} = 1; } &Apache::lonnet::current_machine_ids(); + foreach my $lonhost (keys(%toupdate)) { + if ($thismachine{$lonhost}) { + unless ($updatedhere) { + &Apache::lonnet::do_cache_new('loadbalancing',$dom, + $defaultshash{'loadbalancing'}, + $cachetime); + $updatedhere = 1; } + } else { + my $cachekey = &escape('loadbalancing').':'.&escape($dom); + &Apache::lonnet::remote_devalidate_cache($lonhost,[$cachekey]); } } }