'
.' |
'.
&loadbalancing_rules($dom,$intdom,$currrules{$lonhost},
$othertitle,$usertypes,$types,\%servers,
\%currbalancer,$lonhost,
@@ -6499,10 +8631,11 @@ sub print_loadbalancing {
}
sub get_loadbalancers_config {
- my ($servers,$existing,$currbalancer,$currtargets,$currrules) = @_;
+ my ($servers,$existing,$currbalancer,$currtargets,$currrules,$currcookies) = @_;
return unless ((ref($servers) eq 'HASH') &&
(ref($existing) eq 'HASH') && (ref($currbalancer) eq 'HASH') &&
- (ref($currtargets) eq 'HASH') && (ref($currrules) eq 'HASH'));
+ (ref($currtargets) eq 'HASH') && (ref($currrules) eq 'HASH') &&
+ (ref($currcookies) eq 'HASH'));
if (keys(%{$existing}) > 0) {
my $oldlonhost;
foreach my $key (sort(keys(%{$existing}))) {
@@ -6521,6 +8654,9 @@ sub get_loadbalancers_config {
$currbalancer->{$key} = 1;
$currtargets->{$key} = $existing->{$key}{'targets'};
$currrules->{$key} = $existing->{$key}{'rules'};
+ if ($existing->{$key}{'cookie'}) {
+ $currcookies->{$key} = 1;
+ }
}
}
} else {
@@ -6716,8 +8852,9 @@ sub contact_titles {
'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',
- 'errorthreshold' => 'Error/warning threshold for status e-mail',
- 'errorsysmail' => 'Error threshold for e-mail to core group',
+ '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',
);
@@ -7457,10 +9594,14 @@ sub captcha_choice {
$vertext,$currver);
my %lt = &captcha_phrases();
$keyentry = 'hidden';
+ my $colspan=2;
if ($context eq 'cancreate') {
$rowname = &mt('CAPTCHA validation');
} elsif ($context eq 'login') {
$rowname = &mt('"Contact helpdesk" CAPTCHA validation');
+ } elsif ($context eq 'passwords') {
+ $rowname = &mt('"Forgot Password" CAPTCHA validation');
+ $colspan=1;
}
if (ref($settings) eq 'HASH') {
if ($settings->{'captcha'}) {
@@ -7500,7 +9641,7 @@ sub captcha_choice {
$css_class .= ' style="'.$rowstyle.'"';
}
my $output = ''.
- ''.$rowname.' | '."\n".
+ ' | '.$rowname.' | '."\n".
''."\n";
foreach my $option ('original','recaptcha','notused') {
$output .= ' | ';
- $rownum ++;
- }
} else {
my %defaults;
if (ref($settings) eq 'HASH') {
@@ -7842,7 +9904,7 @@ sub print_defaults {
$datatable .= ' '.&mt('Internal ID:').' '.$item.' '.
''.
&mt('delete').''.
- ''.&mt('Name displayed:').
+ ' | '.&mt('Name displayed').':'.
''.
' | ';
}
@@ -7862,7 +9924,7 @@ sub print_defaults {
''.
' '.&mt('(new)').
''.
- &mt('Name displayed:').
+ &mt('Name displayed').':'.
' | '.
''."\n";
$rownum ++;
@@ -7910,6 +9972,58 @@ sub defaults_titles {
return (\%titles);
}
+sub print_scantron {
+ my ($r,$position,$dom,$confname,$settings,$rowtotal) = @_;
+ if ($position eq 'top') {
+ return &print_scantronformat($r,$dom,$confname,$settings,\$rowtotal);
+ } else {
+ return &print_scantronconfig($dom,$settings,\$rowtotal);
+ }
+}
+
+sub scantron_javascript {
+ return <<"ENDSCRIPT";
+
+
+
+ENDSCRIPT
+
+}
+
sub print_scantronformat {
my ($r,$dom,$confname,$settings,$rowtotal) = @_;
my $itemcount = 1;
@@ -7936,8 +10050,8 @@ sub print_scantronformat {
if ($configuserok eq 'ok') {
if ($author_ok eq 'ok') {
my %legacyfile = (
- default => $Apache::lonnet::perlvar{'lonTabDir'}.'/default_scantronformat.tab',
- custom => $Apache::lonnet::perlvar{'lonTabDir'}.'/scantronformat.tab',
+ default => $Apache::lonnet::perlvar{'lonTabDir'}.'/default_scantronformat.tab',
+ custom => $Apache::lonnet::perlvar{'lonTabDir'}.'/scantronformat.tab',
);
my %md5chk;
foreach my $type (keys(%legacyfile)) {
@@ -7946,7 +10060,7 @@ sub print_scantronformat {
}
if ($md5chk{'default'} ne $md5chk{'custom'}) {
foreach my $type (keys(%legacyfile)) {
- ($scantronurls{$type},my $error) =
+ ($scantronurls{$type},my $error) =
&legacy_scantronformat($r,$dom,$confname,
$type,$legacyfile{$type},
$scantronurls{$type},
@@ -7957,13 +10071,13 @@ sub print_scantronformat {
}
if (keys(%error) == 0) {
$is_custom = 1;
- $confhash{'scantron'}{'scantronformat'} =
+ $confhash{'scantron'}{'scantronformat'} =
$scantronurls{'custom'};
- my $putresult =
+ my $putresult =
&Apache::lonnet::put_dom('configuration',
\%confhash,$dom);
if ($putresult ne 'ok') {
- $error{'custom'} =
+ $error{'custom'} =
''.
&mt('An error occurred updating the domain configuration: [_1]',$putresult).'';
}
@@ -8083,6 +10197,129 @@ sub legacy_scantronformat {
return ($url,$error);
}
+sub print_scantronconfig {
+ my ($dom,$settings,$rowtotal) = @_;
+ my $itemcount = 2;
+ my $is_checked = ' checked="checked"';
+ my %optionson = (
+ hdr => ' checked="checked"',
+ pad => ' checked="checked"',
+ rem => ' checked="checked"',
+ );
+ my %optionsoff = (
+ hdr => '',
+ pad => '',
+ rem => '',
+ );
+ my $currcsvsty = 'none';
+ my ($datatable,%csvfields,%checked,%onclick,%csvoptions);
+ my @fields = &scantroncsv_fields();
+ my %titles = &scantronconfig_titles();
+ if (ref($settings) eq 'HASH') {
+ if (ref($settings->{config}) eq 'HASH') {
+ if ($settings->{config}->{dat}) {
+ $checked{'dat'} = $is_checked;
+ }
+ if (ref($settings->{config}->{csv}) eq 'HASH') {
+ if (ref($settings->{config}->{csv}->{fields}) eq 'HASH') {
+ %csvfields = %{$settings->{config}->{csv}->{fields}};
+ if (keys(%csvfields) > 0) {
+ $checked{'csv'} = $is_checked;
+ $currcsvsty = 'block';
+ }
+ }
+ if (ref($settings->{config}->{csv}->{options}) eq 'HASH') {
+ %csvoptions = %{$settings->{config}->{csv}->{options}};
+ foreach my $option (keys(%optionson)) {
+ unless ($csvoptions{$option}) {
+ $optionsoff{$option} = $optionson{$option};
+ $optionson{$option} = '';
+ }
+ }
+ }
+ }
+ } else {
+ $checked{'dat'} = $is_checked;
+ }
+ } else {
+ $checked{'dat'} = $is_checked;
+ }
+ $onclick{'csv'} = ' onclick="toggleScantron(this.form);"';
+ my $css_class = $itemcount%2? ' class="LC_odd_row"':'';
+ $datatable = ''.&mt('Supported formats').' | '.
+ '';
+ foreach my $item ('dat','csv') {
+ my $id;
+ if ($item eq 'csv') {
+ $id = 'id="scantronconfcsv" ';
+ }
+ $datatable .= ''.(' 'x3);
+ if ($item eq 'csv') {
+ $datatable .= ''.
+ ''.
+ ''.&mt('Field').' | '.&mt('Location').' | '."\n";
+ foreach my $col (@fields) {
+ my $selnone;
+ if ($csvfields{$col} eq '') {
+ $selnone = ' selected="selected"';
+ }
+ $datatable .= ''.$titles{$col}.' | '.
+ ' | ';
+ }
+ $datatable .= ' '.
+ ''.
+ '';
+ foreach my $option ('hdr','pad','rem') {
+ $datatable .= ''.$titles{$option}.':'.
+ ''.(' 'x2)."\n".
+ ' ';
+ }
+ $datatable .= '';
+ $itemcount ++;
+ }
+ }
+ $datatable .= ' | ';
+ $$rowtotal ++;
+ return $datatable;
+}
+
+sub scantronconfig_titles {
+ return &Apache::lonlocal::texthash(
+ dat => 'Standard format (.dat)',
+ csv => 'Comma separated values (.csv)',
+ hdr => 'Remove first line in file (contains column titles)',
+ pad => 'Prepend 0s to PaperID',
+ rem => 'Remove leading spaces (except Question Response columns)',
+ CODE => 'CODE',
+ ID => 'Student ID',
+ PaperID => 'Paper ID',
+ FirstName => 'First Name',
+ LastName => 'Last Name',
+ FirstQuestion => 'First Question Response',
+ Section => 'Section',
+ );
+}
+
+sub scantroncsv_fields {
+ return ('PaperID','LastName','FirstName','ID','Section','CODE','FirstQuestion');
+}
+
sub print_coursecategories {
my ($position,$dom,$hdritem,$settings,$rowtotal) = @_;
my $datatable;
@@ -8431,35 +10668,7 @@ sub serverstatus_pages {
sub defaults_javascript {
my ($settings) = @_;
- 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);
- }
+ return unless (ref($settings) eq 'HASH');
if ((ref($settings->{'inststatusorder'}) eq 'ARRAY') && (ref($settings->{'inststatustypes'}) eq 'HASH')) {
my $maxnum = scalar(@{$settings->{'inststatusorder'}});
if ($maxnum eq '') {
@@ -8513,15 +10722,100 @@ $jstext
return;
}
-$intauthjs
-
// ]]>
ENDSCRIPT
+ }
+ return;
+}
+
+sub passwords_javascript {
+ my %intalert = &Apache::lonlocal::texthash (
+ authcheck => '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.',
+ authcost => 'Warning: bcrypt encryption cost for internal authentication must be an integer.',
+ passmin => 'Warning: minimum password length must be a positive integer greater than 6.',
+ passmax => 'Warning: maximum password length must be a positive integer (or blank).',
+ passexp => 'Warning: days before password expiration must be a positive integer (or blank).',
+ passnum => 'Warning: number of previous passwords to save must be a positive integer (or blank).',
+ );
+ &js_escape(\%intalert);
+ my $defmin = $Apache::lonnet::passwdmin;
+ my $intauthjs = <<"ENDSCRIPT";
+
+function warnIntAuth(field) {
+ if (field.name == 'intauth_check') {
+ if (field.value == '2') {
+ alert('$intalert{authcheck}');
+ }
+ }
+ if (field.name == 'intauth_cost') {
+ field.value.replace(/\s/g,'');
+ if (field.value != '') {
+ var regexdigit=/^\\d+\$/;
+ if (!regexdigit.test(field.value)) {
+ alert('$intalert{authcost}');
+ }
+ }
+ }
+ return;
+}
+
+function warnIntPass(field) {
+ field.value.replace(/^\s+/,'');
+ field.value.replace(/\s+\$/,'');
+ var regexdigit=/^\\d+\$/;
+ if (field.name == 'passwords_min') {
+ if (field.value == '') {
+ alert('$intalert{passmin}');
+ field.value = '$defmin';
+ } else {
+ if (!regexdigit.test(field.value)) {
+ alert('$intalert{passmin}');
+ field.value = '$defmin';
+ }
+ var minval = parseInt(field.value,10);
+ if (minval < $defmin) {
+ alert('$intalert{passmin}');
+ field.value = '$defmin';
+ }
+ }
} else {
- return &Apache::lonhtmlcommon::scripttag($intauthjs);
+ if (field.value == '0') {
+ field.value = '';
+ }
+ if (field.value != '') {
+ if (field.name == 'passwords_expire') {
+ var regexpposnum=/^\\d+(|\\.\\d*)\$/;
+ if (!regexpposnum.test(field.value)) {
+ alert('$intalert{passexp}');
+ field.value = '';
+ } else {
+ var expval = parseFloat(field.value);
+ if (expval == 0) {
+ alert('$intalert{passexp}');
+ field.value = '';
+ }
+ }
+ } else {
+ if (!regexdigit.test(field.value)) {
+ if (field.name == 'passwords_max') {
+ alert('$intalert{passmax}');
+ } else {
+ if (field.name == 'passwords_numsaved') {
+ alert('$intalert{passnum}');
+ }
+ }
+ field.value = '';
+ }
+ }
+ }
}
+ return;
+}
+
+ENDSCRIPT
+ return &Apache::lonhtmlcommon::scripttag($intauthjs);
}
sub coursecategories_javascript {
@@ -8639,7 +10933,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',
placement => 'Placement Tests',
@@ -8767,7 +11061,7 @@ sub build_category_rows {
sub modifiable_userdata_row {
my ($context,$item,$settings,$numinrow,$rowcount,$usertypes,$fieldsref,$titlesref,
- $rowid,$customcss,$rowstyle) = @_;
+ $rowid,$customcss,$rowstyle,$itemdesc) = @_;
my ($role,$rolename,$statustype);
$role = $item;
if ($context eq 'cancreate') {
@@ -8790,6 +11084,8 @@ sub modifiable_userdata_row {
}
} elsif ($context eq 'lti') {
$rolename = &mt('Institutional data used (if available)');
+ } elsif ($context eq 'privacy') {
+ $rolename = $itemdesc;
} else {
if ($role eq 'cr') {
$rolename = &mt('Custom role');
@@ -8839,6 +11135,13 @@ sub modifiable_userdata_row {
if (ref($settings) eq 'HASH') {
$hashref = $settings->{'instdata'};
}
+ } elsif ($context eq 'privacy') {
+ my ($key,$inner) = split(/_/,$role);
+ if (ref($settings) eq 'HASH') {
+ if (ref($settings->{$key}) eq 'HASH') {
+ $hashref = $settings->{$key}->{$inner};
+ }
+ }
} elsif (ref($settings->{$context}) eq 'HASH') {
if (ref($settings->{$context}->{$role}) eq 'HASH') {
$hashref = $settings->{'lti_instdata'};
@@ -8876,7 +11179,25 @@ sub modifiable_userdata_row {
my $check = ' ';
unless ($role eq 'emailusername') {
if (exists($checks{$fields[$i]})) {
- $check = $checks{$fields[$i]}
+ $check = $checks{$fields[$i]};
+ } elsif ($context eq 'privacy') {
+ if ($role =~ /^priv_(domain|course)$/) {
+ if (ref($settings) ne 'HASH') {
+ $check = ' checked="checked" ';
+ }
+ } elsif ($role =~ /^priv_(author|community)$/) {
+ if (ref($settings) ne 'HASH') {
+ unless ($fields[$i] eq 'id') {
+ $check = ' checked="checked" ';
+ }
+ }
+ } elsif ($role =~ /^(unpriv|othdom)_/) {
+ if (ref($settings) ne 'HASH') {
+ if (($fields[$i] eq 'lastname') || ($fields[$i] eq 'firstname')) {
+ $check = ' checked="checked" ';
+ }
+ }
+ }
} elsif ($context ne 'lti') {
if ($role eq 'st') {
if (ref($settings) ne 'HASH') {
@@ -8905,6 +11226,8 @@ sub modifiable_userdata_row {
} else {
if ($context eq 'lti') {
$prefix = 'lti';
+ } elsif ($context eq 'privacy') {
+ $prefix = 'privacy';
}
$output .= '
|