--- loncom/interface/domainprefs.pm 2013/08/07 14:41:39 1.201 +++ loncom/interface/domainprefs.pm 2013/12/25 20:43:46 1.218 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # Handler to set domain-wide configuration settings # -# $Id: domainprefs.pm,v 1.201 2013/08/07 14:41:39 raeburn Exp $ +# $Id: domainprefs.pm,v 1.218 2013/12/25 20:43:46 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -86,7 +86,7 @@ $dom,$settings,$rowtotal,$action. $dom is the domain, $settings is a reference to a hash of current settings for the current context, $rowtotal is a reference to the scalar used to record the -number of rows displayed on the page, and $action is the context (quotas, +number of rows displayed on the page, and $action is the context (quotas, requestcourses or requestauthor). The print_quotas routine was orginally created to display/store information @@ -103,8 +103,8 @@ $datatable - HTML containing form eleme In the case of course requests, radio buttons are displayed for each institutional affiliate type (and also default, and _LC_adv) for each of the course types -(official, unofficial and community). In each case the radio buttons allow the -selection of one of four values: +(official, unofficial, community, and textbook). In each case the radio buttons +allow the selection of one of four values: 0, approval, validate, autolimit=N (where N is blank, or a positive integer). which have the following effects: @@ -259,7 +259,7 @@ sub handler { help => 'Domain_Configuration_Quotas', header => [{col1 => 'User affiliation', col2 => 'Available tools', - col3 => 'Quotas, Mb; (Authoring requires role)',}], + col3 => 'Quotas, MB; (Authoring requires role)',}], }, 'autoenroll' => { text => 'Auto-enrollment settings', @@ -329,7 +329,9 @@ sub handler { header => [{col1 => 'User affiliation', col2 => 'Availability/Processing of requests',}, {col1 => 'Setting', - col2 => 'Value'}], + col2 => 'Value'}, + {col1 => 'Available textbooks', + col2 => ''}], }, 'requestauthor' => {text => 'Request authoring space', @@ -416,7 +418,12 @@ sub handler { my $confname = $dom.'-domainconfig'; if ($phase eq 'process') { - &Apache::lonconfigsettings::make_changes($r,$dom,$phase,$context,\@prefs_order,\%prefs,\%domconfig,$confname,\@roles); + my $result = &Apache::lonconfigsettings::make_changes($r,$dom,$phase,$context,\@prefs_order, + \%prefs,\%domconfig,$confname,\@roles); + if (ref($result) eq 'HASH') { + $r->rflush(); + &devalidate_remote_domconfs($dom,$result); + } } elsif ($phase eq 'display') { my $js = &recaptcha_js(). &credits_js(); @@ -429,6 +436,16 @@ sub handler { &common_domprefs_js(). &Apache::loncommon::javascript_array_indexof(); } + if (grep(/^requestcourses$/,@actions)) { + my $javascript_validations; + my $coursebrowserjs=&Apache::loncommon::coursebrowser_javascript($env{'request.role.domain'}); + $js .= < +$javascript_validations + +$coursebrowserjs +END + } &Apache::lonconfigsettings::display_settings($r,$dom,$phase,$context,\@prefs_order,\%prefs,\%domconfig,$confname,$js); } else { # check if domconfig user exists for the domain. @@ -438,7 +455,7 @@ sub handler { unless ($configuserok eq 'ok') { &Apache::lonconfigsettings::print_header($r,$phase,$context); $r->print(&mt('The domain configuration user "[_1]" has yet to be created.', - $confname). + $confname). '
' ); if ($switchserver) { @@ -498,21 +515,21 @@ sub handler { } sub process_changes { - my ($r,$dom,$confname,$action,$roles,$values) = @_; + my ($r,$dom,$confname,$action,$roles,$values,$lastactref) = @_; my %domconfig; if (ref($values) eq 'HASH') { %domconfig = %{$values}; } my $output; if ($action eq 'login') { - $output = &modify_login($r,$dom,$confname,%domconfig); + $output = &modify_login($r,$dom,$confname,$lastactref,%domconfig); } elsif ($action eq 'rolecolors') { $output = &modify_rolecolors($r,$dom,$confname,$roles, - %domconfig); + $lastactref,%domconfig); } elsif ($action eq 'quotas') { - $output = &modify_quotas($dom,$action,%domconfig); + $output = &modify_quotas($r,$dom,$action,$lastactref,%domconfig); } elsif ($action eq 'autoenroll') { - $output = &modify_autoenroll($dom,%domconfig); + $output = &modify_autoenroll($dom,$lastactref,%domconfig); } elsif ($action eq 'autoupdate') { $output = &modify_autoupdate($dom,%domconfig); } elsif ($action eq 'autocreate') { @@ -524,25 +541,25 @@ sub process_changes { } elsif ($action eq 'usermodification') { $output = &modify_usermodification($dom,%domconfig); } elsif ($action eq 'contacts') { - $output = &modify_contacts($dom,%domconfig); + $output = &modify_contacts($dom,$lastactref,%domconfig); } elsif ($action eq 'defaults') { - $output = &modify_defaults($dom,$r); + $output = &modify_defaults($dom,$lastactref,%domconfig); } elsif ($action eq 'scantron') { - $output = &modify_scantron($r,$dom,$confname,%domconfig); + $output = &modify_scantron($r,$dom,$confname,$lastactref,%domconfig); } elsif ($action eq 'coursecategories') { $output = &modify_coursecategories($dom,%domconfig); } elsif ($action eq 'serverstatuses') { $output = &modify_serverstatuses($dom,%domconfig); } elsif ($action eq 'requestcourses') { - $output = &modify_quotas($dom,$action,%domconfig); + $output = &modify_quotas($r,$dom,$action,$lastactref,%domconfig); } elsif ($action eq 'requestauthor') { - $output = &modify_quotas($dom,$action,%domconfig); + $output = &modify_quotas($r,$dom,$action,$lastactref,%domconfig); } elsif ($action eq 'helpsettings') { $output = &modify_helpsettings($r,$dom,$confname,%domconfig); } elsif ($action eq 'coursedefaults') { - $output = &modify_coursedefaults($dom,%domconfig); + $output = &modify_coursedefaults($dom,$lastactref,%domconfig); } elsif ($action eq 'usersessions') { - $output = &modify_usersessions($dom,%domconfig); + $output = &modify_usersessions($dom,$lastactref,%domconfig); } elsif ($action eq 'loadbalancing') { $output = &modify_loadbalancing($dom,%domconfig); } @@ -571,7 +588,7 @@ sub print_config_box { if ($numheaders > 1) { my $colspan = ''; my $rightcolspan = ''; - if (($action eq 'rolecolors') || ($action eq 'coursecategories') || + if (($action eq 'rolecolors') || ($action eq 'coursecategories') || (($action eq 'login') && ($numheaders < 3))) { $colspan = ' colspan="2"'; } @@ -662,7 +679,7 @@ sub print_config_box { - '. + '. &print_usermodification('bottom',$dom,$settings,\$rowtotal); $rowtotal ++; } elsif ($action eq 'coursecategories') { @@ -678,14 +695,25 @@ sub print_config_box {
'.&mt($item->{'header'}->[2]->{'col1'}).''.&mt($item->{'header'}->[2]->{'col2'}).'
'.&mt($item->{'header'}->[2]->{'col2'}).'
- '. + '. &print_login('help',$dom,$confname,$phase,$settings,\$rowtotal); $rowtotal ++; } else { $output .= &print_login('help',$dom,$confname,$phase,$settings,\$rowtotal); } } elsif ($action eq 'requestcourses') { - $output .= &print_requestmail($dom,$action,$settings,\$rowtotal); + $output .= &print_requestmail($dom,$action,$settings,\$rowtotal). + &print_studentcode($settings,\$rowtotal).' +
'.&mt($item->{'header'}->[2]->{'col1'}).''.&mt($item->{'header'}->[2]->{'col2'}).'
'.&mt($item->{'header'}->[2]->{'col2'}).'
+ + + + + + + + '. + &print_textbookcourses($dom,$settings,\$rowtotal); } elsif ($action eq 'requestauthor') { $output .= &print_requestmail($dom,$action,$settings,\$rowtotal); } elsif ($action eq 'usersessions') { @@ -790,7 +818,7 @@ sub print_config_box { } elsif ($action eq 'contacts') { $output .= &print_contacts($dom,$settings,\$rowtotal); } elsif ($action eq 'defaults') { - $output .= &print_defaults($dom,\$rowtotal); + $output .= &print_defaults($dom,$settings,\$rowtotal); } elsif ($action eq 'scantron') { $output .= &print_scantronformat($r,$dom,$confname,$settings,\$rowtotal); } elsif ($action eq 'serverstatuses') { @@ -1205,8 +1233,8 @@ sub print_rolecolors { sub role_defaults { my ($role,$bgs,$links,$images,$logintext) = @_; - my %defaults; - unless ((ref($bgs) eq 'ARRAY') && (ref($links) eq 'ARRAY') && (ref($images) eq 'ARRAY')) { + my %defaults; + unless ((ref($bgs) eq 'ARRAY') && (ref($links) eq 'ARRAY') && (ref($images) eq 'ARRAY')) { return %defaults; } my %defaultdesign = %Apache::loncommon::defaultdesign; @@ -1257,7 +1285,7 @@ sub display_color_options { $datatable .= ''; unless ($role eq 'login') { $datatable .= ''. @@ -1267,7 +1295,7 @@ sub display_color_options { } else { $datatable .= ''; } - $current_color = $designs->{'fontmenu'} ? + $current_color = $designs->{'fontmenu'} ? $designs->{'fontmenu'} : $defaults->{'fontmenu'}; $datatable .= ''; - } $color_menu .= '
'.&mt($item->{'header'}->[2]->{'col1'}).''.&mt($item->{'header'}->[2]->{'col2'}).'
'. ' '. + ' value="'.$current_color.'" /> '. ' 
 '. ''.$choices->{$item}."\n"; - if ($designs->{'links'}{$item}) { $datatable.=' '; } @@ -1496,7 +1523,6 @@ sub login_text_colors { my $color = $designs->{'logintext'}{$item} ? $designs->{'logintext'}{$item} : $defaults->{'logintext'}{$item}; $color_menu .= '

'; return $color_menu; @@ -1547,14 +1573,14 @@ sub print_quotas { my $typecount = 0; my ($css_class,%titles); if ($context eq 'requestcourses') { - @usertools = ('official','unofficial','community'); + @usertools = ('official','unofficial','community','textbook'); @options =('norequest','approval','validate','autolimit'); %validations = &Apache::lonnet::auto_courserequest_checks($dom); %titles = &courserequest_titles(); } elsif ($context eq 'requestauthor') { @usertools = ('author'); @options = ('norequest','approval','automatic'); - %titles = &authorrequest_titles(); + %titles = &authorrequest_titles(); } else { @usertools = ('aboutme','blog','webdav','portfolio'); %titles = &tool_titles(); @@ -1961,7 +1987,7 @@ sub print_quotas { sub print_requestmail { my ($dom,$action,$settings,$rowtotal) = @_; - my ($now,$datatable,%currapp,$rows); + my ($now,$datatable,%currapp); $now = time; if (ref($settings) eq 'HASH') { if (ref($settings->{'notify'}) eq 'HASH') { @@ -1993,6 +2019,216 @@ sub print_requestmail { return $datatable; } +sub print_studentcode { + my ($settings,$rowtotal) = @_; + my $rownum = 0; + my ($output,%current); + my @crstypes = ('official','unofficial','community','textbook'); + if (ref($settings->{'uniquecode'}) eq 'HASH') { + foreach my $type (@crstypes) { + $current{$type} = $settings->{'uniquecode'}{$type}; + } + } + $output .= ''. + ''.&mt('Generate unique six character code as course identifier?').''. + ''; + foreach my $type (@crstypes) { + my $check = ' '; + if ($current{$type}) { + $check = ' checked="checked" '; + } + $output .= ''.(' 'x2).' '; + } + $output .= ''; + $$rowtotal ++; + return $output; +} + +sub print_textbookcourses { + my ($dom,$settings,$rowtotal) = @_; + my $rownum = 0; + my $css_class; + my $itemcount = 1; + my $maxnum = 0; + my $bookshash; + if (ref($settings) eq 'HASH') { + $bookshash = $settings->{'textbooks'}; + } + my %ordered; + if (ref($bookshash) eq 'HASH') { + foreach my $item (keys(%{$bookshash})) { + if (ref($bookshash->{$item}) eq 'HASH') { + my $num = $bookshash->{$item}{'order'}; + $ordered{$num} = $item; + } + } + } + my $confname = $dom.'-domainconfig'; + my $switchserver = &check_switchserver($dom,$confname); + my $maxnum = scalar(keys(%ordered)); + my $datatable = &textbookcourses_javascript(\%ordered); + 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 $key = $ordered{$items[$i]}; + my %coursehash=&Apache::lonnet::coursedescription($key); + my $coursetitle = $coursehash{'description'}; + my ($subject,$title,$author,$image,$imgsrc,$cdom,$cnum); + if (ref($bookshash->{$key}) eq 'HASH') { + $subject = $bookshash->{$key}->{'subject'}; + $title = $bookshash->{$key}->{'title'}; + $author = $bookshash->{$key}->{'author'}; + $image = $bookshash->{$key}->{'image'}; + if ($image ne '') { + my ($path,$imagefile) = ($image =~ m{^(.+)/([^/]+)$}); + my $imagethumb = "$path/tn-".$imagefile; + $imgsrc = ''.&mt('Textbook image').''; + } + } + my $chgstr = ' onchange="javascript:reorderBooks(this.form,'."'$key'".');"'; + $datatable .= '' + .''.(' 'x2). + ''. + ''. + ''.&mt('Subject:').' '. + (' 'x2). + ''.&mt('Title:').' '. + (' 'x2). + ''.&mt('Author(s):').' '. + (' 'x2). + ''.&mt('Thumbnail:'); + if ($image) { + $datatable .= ''. + $imgsrc. + ' '. + ' '.&mt('Replace:').' '; + } + if ($switchserver) { + $datatable .= &mt('Upload to library server: [_1]',$switchserver); + } else { + $datatable .= ''; + } + $datatable .= ' '. + ''.&mt('LON-CAPA course:').' '. + $coursetitle.''."\n"; + $itemcount ++; + } + } + $css_class = $itemcount%2?' class="LC_odd_row"':''; + my $chgstr = ' onchange="javascript:reorderBooks(this.form,'."'addbook_pos'".');"'; + $datatable .= ''."\n". + ''."\n". + ' '."\n". + ''.&mt('Add').''."\n". + ''. + ''.&mt('Subject:').' '."\n". + (' 'x2). + ''.&mt('Title:').' '."\n". + (' 'x2). + ''.&mt('Author(s):').' '."\n". + (' 'x2). + ''.&mt('Image:').' '; + if ($switchserver) { + $datatable .= &mt('Upload to library server: [_1]',$switchserver); + } else { + $datatable .= ''; + } + $datatable .= ''."\n". + ''.&mt('LON-CAPA course:').' '. + &Apache::loncommon::select_dom_form($env{'request.role.domain'},'addbook_cdom'). + ''. + &Apache::loncommon::selectcourse_link + ('display','addbook_cnum','addbook_cdom',undef,undef,undef,'Course'); + ''."\n". + ''."\n"; + $itemcount ++; + return $datatable; +} + +sub textbookcourses_javascript { + my ($textbooks) = @_; + return unless(ref($textbooks) eq 'HASH'); + my $num = scalar(keys(%{$textbooks})); + my @jsarray; + foreach my $item (sort {$a <=> $b } (keys(%{$textbooks}))) { + push(@jsarray,$textbooks->{$item}); + } + my $jstext = ' var textbooks = Array('."'".join("','",@jsarray)."'".');'."\n"; + return <<"ENDSCRIPT"; + + +ENDSCRIPT +} + sub print_autoenroll { my ($dom,$settings,$rowtotal) = @_; my $autorun = &Apache::lonnet::auto_run(undef,$dom), @@ -2154,7 +2390,7 @@ sub print_autocreate { } } } - if ($settings->{'xmldc'} ne '') { + if ($settings->{'xmldc'} ne '') { $currhash{$settings->{'xmldc'}} = 1; } } else { @@ -2311,7 +2547,7 @@ sub print_contacts { my @contacts = ('adminemail','supportemail'); my (%checked,%to,%otheremails,%bccemails); my @mailings = ('errormail','packagesmail','lonstatusmail','helpdeskmail', - 'requestsmail','updatesmail'); + 'requestsmail','updatesmail','idconflictsmail'); foreach my $type (@mailings) { $otheremails{$type} = ''; } @@ -2348,21 +2584,21 @@ sub print_contacts { $checked{'lonstatusmail'}{'adminemail'} = ' checked="checked" '; $checked{'requestsmail'}{'adminemail'} = ' checked="checked" '; $checked{'updatesmail'}{'adminemail'} = ' checked="checked" '; + $checked{'idconflictsmail'}{'adminemail'} = ' checked="checked" '; } my ($titles,$short_titles) = &contact_titles(); my $rownum = 0; my $css_class; foreach my $item (@contacts) { - $rownum ++; $css_class = $rownum%2?' class="LC_odd_row"':''; $datatable .= ''. ''.$titles->{$item}. ''. ''; + $rownum ++; } foreach my $type (@mailings) { - $rownum ++; $css_class = $rownum%2?' class="LC_odd_row"':''; $datatable .= ''. ''. @@ -2385,7 +2621,21 @@ sub print_contacts { 'value="'.$bccemails{$type}.'" />'; } $datatable .= ''."\n"; + $rownum ++; } + my %choices; + $choices{'reporterrors'} = &mt('E-mail error reports to [_1]', + &Apache::loncommon::modal_link('http://loncapa.org/core.html', + &mt('LON-CAPA core group - MSU'),600,500)); + $choices{'reportupdates'} = &mt('E-mail record of completed LON-CAPA updates to [_1]', + &Apache::loncommon::modal_link('http://loncapa.org/core.html', + &mt('LON-CAPA core group - MSU'),600,500)); + my @toggles = ('reporterrors','reportupdates'); + my %defaultchecked = ('reporterrors' => 'on', + 'reportupdates' => 'on'); + (my $reports,$rownum) = &radiobutton_prefs($settings,\@toggles,\%defaultchecked, + \%choices,$rownum); + $datatable .= $reports; $$rowtotal += $rownum; return $datatable; } @@ -2477,9 +2727,10 @@ sub print_coursedefaults { \%choices,$itemcount); } else { $css_class = $itemcount%2 ? ' class="LC_odd_row"' : ''; - my ($currdefresponder,$def_official_credits,$def_unofficial_credits,%curruploadquota); + my ($currdefresponder,$def_official_credits,$def_unofficial_credits,$def_textbook_credits, + %curruploadquota); my $currusecredits = 0; - my @types = ('official','unofficial','community'); + my @types = ('official','unofficial','community','textbook'); if (ref($settings) eq 'HASH') { $currdefresponder = $settings->{'anonsurvey_threshold'}; if (ref($settings->{'uploadquota'}) eq 'HASH') { @@ -2490,7 +2741,9 @@ sub print_coursedefaults { if (ref($settings->{'coursecredits'}) eq 'HASH') { $def_official_credits = $settings->{'coursecredits'}->{'official'}; $def_unofficial_credits = $settings->{'coursecredits'}->{'unofficial'}; - if (($def_official_credits ne '') || ($def_unofficial_credits ne '')) { + $def_textbook_credits = $settings->{'coursecredits'}->{'textbook'}; + if (($def_official_credits ne '') || ($def_unofficial_credits ne '') || + ($def_textbook_credits ne '')) { $currusecredits = 1; } } @@ -2526,7 +2779,7 @@ sub print_coursedefaults { $datatable .= ''."\n"; $itemcount += 2; my $onclick = 'toggleCredits(this.form);'; - my $display = 'none'; + my $display = 'none'; if ($currusecredits) { $display = 'block'; } @@ -2540,6 +2793,11 @@ sub print_coursedefaults { &mt('Default credits for unofficial courses [_1]', ''). + '
'. + ''. + &mt('Default credits for textbook courses [_1]', + ''). ''."\n"; %defaultchecked = ('coursecredits' => 'off'); @toggles = ('coursecredits'); @@ -2981,7 +3239,7 @@ sub print_loadbalancing { } my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom); - my $rownum = 6; + my $rownum = 8; if (ref($types) eq 'ARRAY') { $rownum += scalar(@{$types}); } @@ -3012,7 +3270,7 @@ sub print_loadbalancing { ''. '

'; if ($lonhost eq '') { - $datatable .= ''; + $datatable .= ''; if (keys(%currbalancer) > 0) { $datatable .= &mt('Add balancer:'); } else { @@ -3028,7 +3286,7 @@ sub print_loadbalancing { next if ($currbalancer{$server}); $datatable .= ''."\n"; } - $datatable .= + $datatable .= ''."\n". ' '."\n"; } else { @@ -3067,7 +3325,7 @@ sub print_loadbalancing { if (exists($currbalancer{$spares[$i]})) { $disabled = ' disabled="disabled"'; } - $targettable .= + $targettable .= ''; @@ -3151,7 +3409,7 @@ sub loadbalancing_rules { $css_class,$balnum,$islast) = @_; my $output; my $num = 0; - my ($alltypes,$othertypes,$titles) = + my ($alltypes,$othertypes,$titles) = &loadbalancing_titles($dom,$intdom,$usertypes,$types); if ((ref($alltypes) eq 'ARRAY') && (ref($titles) eq 'HASH')) { foreach my $type (@{$alltypes}) { @@ -3160,7 +3418,7 @@ sub loadbalancing_rules { if (ref($currrules) eq 'HASH') { $current = $currrules->{$type}; } - if (($type eq '_LC_external') || ($type eq '_LC_internetdom')) { + if (($type eq '_LC_external') || ($type eq '_LC_internetdom') || ($type eq '_LC_ipchange')) { if ($dom ne &Apache::lonnet::host_domain($lonhost)) { $current = ''; } @@ -3181,8 +3439,10 @@ sub loadbalancing_titles { '_LC_author' => &mt('Users from [_1] with author role',$dom), '_LC_internetdom' => &mt('Users not from [_1], but from [_2]',$dom,$intdom), '_LC_external' => &mt('Users not from [_1]',$intdom), + '_LC_ipchangesso' => &mt('SSO users from [_1], with IP mismatch',$dom), + '_LC_ipchange' => &mt('Non-SSO users with IP mismatch'), ); - my @alltypes = ('_LC_adv','_LC_author','_LC_internetdom','_LC_external'); + my @alltypes = ('_LC_adv','_LC_author','_LC_internetdom','_LC_external','_LC_ipchangesso','_LC_ipchange'); if (ref($types) eq 'ARRAY') { unshift(@alltypes,@{$types},'default'); } @@ -3207,23 +3467,28 @@ sub loadbalancing_titles { sub loadbalance_rule_row { my ($type,$title,$current,$servers,$currbalancer,$lonhost,$dom, $targets_div_style,$homedom_div_style,$css_class,$balnum,$num,$islast) = @_; - my @rulenames = ('default','homeserver'); + my @rulenames; my %ruletitles = &offloadtype_text(); - if ($type eq '_LC_external') { - push(@rulenames,'externalbalancer'); + if (($type eq '_LC_ipchangesso') || ($type eq '_LC_ipchange')) { + @rulenames = ('balancer','offloadedto'); } else { - push(@rulenames,'specific'); + @rulenames = ('default','homeserver'); + if ($type eq '_LC_external') { + push(@rulenames,'externalbalancer'); + } else { + push(@rulenames,'specific'); + } + push(@rulenames,'none'); } - push(@rulenames,'none'); my $style = $targets_div_style; - if (($type eq '_LC_external') || ($type eq '_LC_internetdom')) { + if (($type eq '_LC_external') || ($type eq '_LC_internetdom') || ($type eq '_LC_ipchange')) { $style = $homedom_div_style; } my $space; if ($islast && $num == 1) { $space = '

 
'; } - my $output = + my $output = ''.$space. '
'.$title.'
'."\n". ''.$space. @@ -3243,7 +3508,7 @@ sub loadbalance_rule_row { unless ($checked) { $default = ' selected="selected"'; } - $extra = + $extra = ': '; + $defaults{$item}.'"'.$size.' />'; } $datatable .= ''; $rownum ++; @@ -4122,7 +4400,7 @@ sub print_coursecategories { } $datatable .= ''; } - $datatable .= ''; + $datatable .= '
'; if ($parent eq 'instcode' || $parent eq 'communities') { $datatable .= '' .$default_names{$parent}.''; @@ -4152,7 +4430,8 @@ sub print_coursecategories { $datatable .= ''; } else { $datatable .= $parent - .' 
'; } my $depth = 1; @@ -4424,7 +4703,7 @@ sub build_category_rows { if (ref($cats->[$depth]{$parent}) eq 'ARRAY') { my $numchildren = @{$cats->[$depth]{$parent}}; my $css_class = $itemcount%2?' class="LC_odd_row"':''; - $text .= ''; + $text .= '
'; my ($idxnum,$parent_name,$parent_item); my $higher = $depth - 1; if ($higher == 0) { @@ -4716,7 +4995,7 @@ sub usertype_update_row { } sub modify_login { - my ($r,$dom,$confname,%domconfig) = @_; + my ($r,$dom,$confname,$lastactref,%domconfig) = @_; my ($resulttext,$errors,$colchgtext,%changes,%colchanges,%newfile,%newurl, %curr_loginvia,%loginhash,@currlangs,@newlangs,$addedfile,%title,@offon); %title = ( coursecatalog => 'Display course catalog', @@ -4896,7 +5175,7 @@ sub modify_login { } else { my $puberror = &mt("Upload of [_1] failed because an error occurred publishing the file in RES space. Error was: [_2].",$newfile{$lang},$result); $errors .= '
  • '.$puberror.'
  • '; - if ((grep(/^\Q$lang\E$/,@currlangs)) && + if ((grep(/^\Q$lang\E$/,@currlangs)) && (!grep(/^\Q$lang\E$/,@delurls))) { $loginhash{'login'}{'helpurl'}{$lang} = $domconfig{'login'}{'helpurl'}{$lang}; @@ -4954,6 +5233,9 @@ sub modify_login { } if (keys(%changes) > 0 || $colchgtext) { &Apache::loncommon::devalidate_domconfig_cache($dom); + if (ref($lastactref) eq 'HASH') { + $lastactref->{'domainconfig'} = 1; + } $resulttext = &mt('Changes made:').'
      '; foreach my $item (sort(keys(%changes))) { if ($item eq 'loginvia') { @@ -5013,7 +5295,7 @@ sub modify_login { } } elsif ($item eq 'captcha') { if (ref($loginhash{'login'}) eq 'HASH') { - my $chgtxt; + my $chgtxt; if ($loginhash{'login'}{$item} eq 'notused') { $chgtxt .= &mt('No CAPTCHA validation in use for helpdesk form.'); } else { @@ -5086,7 +5368,7 @@ sub color_font_choices { } sub modify_rolecolors { - my ($r,$dom,$confname,$roles,%domconfig) = @_; + my ($r,$dom,$confname,$roles,$lastactref,%domconfig) = @_; my ($resulttext,%rolehash); $rolehash{'rolecolors'} = {}; if (ref($domconfig{'rolecolors'}) ne 'HASH') { @@ -5101,6 +5383,9 @@ sub modify_rolecolors { if ($putresult eq 'ok') { if (keys(%changes) > 0) { &Apache::loncommon::devalidate_domconfig_cache($dom); + if (ref($lastactref) eq 'HASH') { + $lastactref->{'domainconfig'} = 1; + } $resulttext = &display_colorchgs($dom,\%changes,$roles, $rolehash{'rolecolors'}); } else { @@ -5512,7 +5797,7 @@ sub publishlogo { # See if there is anything left unless ($fname) { return ('error: no uploaded file'); } $fname="$subdir/$fname"; - my $docroot=$r->dir_config('lonDocRoot'); + my $docroot=$r->dir_config('lonDocRoot'); my $filepath="$docroot/priv"; my $relpath = "$dom/$confname"; my ($fnamepath,$file,$fetchthumb); @@ -5532,7 +5817,7 @@ sub publishlogo { if ($file=~/\.(\w+)$/ && (&Apache::loncommon::fileembstyle($1) eq 'hdn')) { $output = - &mt('Invalid file extension ([_1]) - reserved for LONCAPA use.',$1); + &mt('Invalid file extension ([_1]) - reserved for internal use.',$1); } elsif ($file=~/\.(\w+)$/ && !defined(&Apache::loncommon::fileembstyle($1))) { $output = &mt('Unrecognized file extension ([_1]) - rename the file with a proper extension and re-upload.',$1); @@ -5781,21 +6066,25 @@ sub check_switchserver { } sub modify_quotas { - my ($dom,$action,%domconfig) = @_; + my ($r,$dom,$action,$lastactref,%domconfig) = @_; my ($context,@usertools,@options,%validations,%titles,%confhash,%toolshash, - %limithash,$toolregexp,%conditions,$resulttext,%changes); + %limithash,$toolregexp,%conditions,$resulttext,%changes,$confname,$configuserok, + $author_ok,$switchserver,$errors); if ($action eq 'quotas') { $context = 'tools'; } else { $context = $action; } if ($context eq 'requestcourses') { - @usertools = ('official','unofficial','community'); + @usertools = ('official','unofficial','community','textbook'); @options =('norequest','approval','validate','autolimit'); %validations = &Apache::lonnet::auto_courserequest_checks($dom); %titles = &courserequest_titles(); $toolregexp = join('|',@usertools); %conditions = &courserequest_conditions(); + $confname = $dom.'-domainconfig'; + my $servadm = $r->dir_config('lonAdmEMail'); + ($configuserok,$author_ok,$switchserver) = &config_check($dom,$confname,$servadm); } elsif ($context eq 'requestauthor') { @usertools = ('author'); %titles = &authorrequest_titles(); @@ -5803,7 +6092,7 @@ sub modify_quotas { @usertools = ('aboutme','blog','webdav','portfolio'); %titles = &tool_titles(); } - my %domdefaults = &Apache::lonnet::get_domain_defaults($dom); + my %domdefaults = &Apache::lonnet::get_domain_defaults($dom,1); my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom); foreach my $key (keys(%env)) { if ($context eq 'requestcourses') { @@ -5834,6 +6123,36 @@ sub modify_quotas { my @approvalnotify = &Apache::loncommon::get_env_multiple('form.reqapprovalnotify'); @approvalnotify = sort(@approvalnotify); $confhash{'notify'}{'approval'} = join(',',@approvalnotify); + my @crstypes = ('official','unofficial','community','textbook'); + my @hasuniquecode = &Apache::loncommon::get_env_multiple('form.uniquecode'); + foreach my $type (@hasuniquecode) { + if (grep(/^\Q$type\E$/,@crstypes)) { + $confhash{'uniquecode'}{$type} = 1; + } + } + my ($newbook,@allpos); + if ($context eq 'requestcourses') { + if ($env{'form.addbook'}) { + if (($env{'form.addbook_cnum'} =~ /^$match_courseid$/) && + ($env{'form.addbook_cdom'} =~ /^$match_domain$/)) { + if (&Apache::lonnet::homeserver($env{'form.addbook_cnum'}, + $env{'form.addbook_cdom'}) eq 'no_host') { + $errors .= '
    • '.&mt('Invalid LON-CAPA course for textbook'). + '
    • '; + } else { + $newbook = $env{'form.addbook_cdom'}.'_'.$env{'form.addbook_cnum'}; + my $position = $env{'form.addbook_pos'}; + $position =~ s/\D+//g; + if ($position ne '') { + $allpos[$position] = $newbook; + } + } + } else { + $errors .= '
    • '.&mt('Invalid LON-CAPA course for textbook'). + '
    • '; + } + } + } if (ref($domconfig{$action}) eq 'HASH') { if (ref($domconfig{$action}{'notify'}) eq 'HASH') { if ($domconfig{$action}{'notify'}{'approval'} ne $confhash{'notify'}{'approval'}) { @@ -5844,10 +6163,131 @@ sub modify_quotas { $changes{'notify'}{'approval'} = 1; } } + if (ref($domconfig{$action}{'uniquecode'}) eq 'HASH') { + if (ref($confhash{'uniquecode'}) eq 'HASH') { + foreach my $crstype (keys(%{$domconfig{$action}{'uniquecode'}})) { + unless ($confhash{'uniquecode'}{$crstype}) { + $changes{'uniquecode'} = 1; + } + } + unless ($changes{'uniquecode'}) { + foreach my $crstype (keys(%{$confhash{'uniquecode'}})) { + unless ($domconfig{$action}{'uniquecode'}{$crstype}) { + $changes{'uniquecode'} = 1; + } + } + } + } else { + $changes{'uniquecode'} = 1; + } + } elsif (ref($confhash{'uniquecode'}) eq 'HASH') { + $changes{'uniquecode'} = 1; + } + if ($context eq 'requestcourses') { + if (ref($domconfig{$action}{'textbooks'}) eq 'HASH') { + my %deletions; + my @todelete = &Apache::loncommon::get_env_multiple('form.book_del'); + if (@todelete) { + map { $deletions{$_} = 1; } @todelete; + } + my %imgdeletions; + my @todeleteimages = &Apache::loncommon::get_env_multiple('form.book_image_del'); + if (@todeleteimages) { + map { $imgdeletions{$_} = 1; } @todeleteimages; + } + my $maxnum = $env{'form.book_maxnum'}; + for (my $i=0; $i<=$maxnum; $i++) { + my $key = $env{'form.book_id_'.$i}; + if (ref($domconfig{$action}{'textbooks'}{$key}) eq 'HASH') { + if ($deletions{$key}) { + if ($domconfig{$action}{'textbooks'}{$key}{'image'}) { + #FIXME need to obsolete item in RES space + } + next; + } else { + my $newpos = $env{'form.'.$key}; + $newpos =~ s/\D+//g; + foreach my $item ('subject','title','author') { + $confhash{'textbooks'}{$key}{$item} = $env{'form.book_'.$item.'_'.$i}; + if ($domconfig{$action}{'textbooks'}{$key}{$item} ne $confhash{'textbooks'}{$key}{$item}) { + $changes{'textbooks'}{$key} = 1; + } + } + $allpos[$newpos] = $key; + } + if ($imgdeletions{$key}) { + $changes{'textbooks'}{$key} = 1; + #FIXME need to obsolete item in RES space + } elsif ($env{'form.book_image_'.$i.'.filename'}) { + my ($cdom,$cnum) = split(/_/,$key); + my ($imgurl,$error) = &process_textbook_image($r,$dom,$confname,'book_image_'.$i, + $cdom,$cnum,$configuserok, + $switchserver,$author_ok); + if ($imgurl) { + $confhash{'textbooks'}{$key}{'image'} = $imgurl; + $changes{'textbooks'}{$key} = 1; + } + if ($error) { + &Apache::lonnet::logthis($error); + $errors .= '
    • '.$error.'
    • '; + } + } elsif ($domconfig{$action}{'textbooks'}{$key}{'image'}) { + $confhash{'textbooks'}{$key}{'image'} = + $domconfig{$action}{'textbooks'}{$key}{'image'}; + } + } + } + } + } } else { if ($confhash{'notify'}{'approval'}) { $changes{'notify'}{'approval'} = 1; } + if (ref($confhash{'uniquecode'} eq 'HASH')) { + $changes{'uniquecode'} = 1; + } + } + if ($context eq 'requestcourses') { + if ($newbook) { + $changes{'textbooks'}{$newbook} = 1; + foreach my $item ('subject','title','author') { + $env{'form.addbook_'.$item} =~ s/(`)/'/g; + if ($env{'form.addbook_'.$item}) { + $confhash{'textbooks'}{$newbook}{$item} = $env{'form.addbook_'.$item}; + } + } + if ($env{'form.addbook_image.filename'} ne '') { + my ($cdom,$cnum) = split(/_/,$newbook); + my ($imageurl,$error) = + &process_textbook_image($r,$dom,$confname,'addbook_image',$cdom,$cnum,$configuserok, + $switchserver,$author_ok); + if ($imageurl) { + $confhash{'textbooks'}{$newbook}{'image'} = $imageurl; + } + if ($error) { + &Apache::lonnet::logthis($error); + $errors .= '
    • '.$error.'
    • '; + } + } + } + if (@allpos > 0) { + my $idx = 0; + foreach my $item (@allpos) { + if ($item ne '') { + $confhash{'textbooks'}{$item}{'order'} = $idx; + if (ref($domconfig{$action}) eq 'HASH') { + if (ref($domconfig{$action}{'textbooks'}) eq 'HASH') { + if (ref($domconfig{$action}{'textbooks'}{$item}) eq 'HASH') { + if ($domconfig{$action}{'textbooks'}{$item}{'order'} ne $idx) { + $changes{'textbooks'}{$item} = 1; + } + } + } + } + $idx ++; + } + } + } } } else { $confhash{'defaultquota'}{'default'} = $env{'form.defaultquota'}; @@ -5989,7 +6429,9 @@ sub modify_quotas { $domdefaults{'requestauthor'} = \%confhash; } else { foreach my $key (keys(%confhash)) { - $domdefaults{$key} = $confhash{$key}; + unless (($context eq 'requestcourses') && ($key eq 'textbooks')) { + $domdefaults{$key} = $confhash{$key}; + } } } @@ -6002,9 +6444,11 @@ sub modify_quotas { if (keys(%changes) > 0) { my $cachetime = 24*60*60; &Apache::lonnet::do_cache_new('domdefaults',$dom,\%domdefaults,$cachetime); - + if (ref($lastactref) eq 'HASH') { + $lastactref->{'domdefaults'} = 1; + } $resulttext = &mt('Changes made:').'
        '; - unless (($context eq 'requestcourses') || + unless (($context eq 'requestcourses') || ($context eq 'requestauthor')) { if (ref($changes{'defaultquota'}) eq 'HASH') { $resulttext .= '
      • '.&mt('Portfolio default quotas').'
          '; @@ -6014,7 +6458,7 @@ sub modify_quotas { if ($type eq 'default') { $typetitle = $othertitle; } - $resulttext .= '
        • '.&mt('[_1] set to [_2] Mb',$typetitle,$confhash{'defaultquota'}{$type}).'
        • '; + $resulttext .= '
        • '.&mt('[_1] set to [_2] MB',$typetitle,$confhash{'defaultquota'}{$type}).'
        • '; } } $resulttext .= '
      • '; @@ -6027,7 +6471,7 @@ sub modify_quotas { if ($type eq 'default') { $typetitle = $othertitle; } - $resulttext .= '
      • '.&mt('[_1] set to [_2] Mb',$typetitle,$confhash{'authorquota'}{$type}).'
      • '; + $resulttext .= '
      • '.&mt('[_1] set to [_2] MB',$typetitle,$confhash{'authorquota'}{$type}).'
      • '; } } $resulttext .= '
      '; @@ -6038,7 +6482,7 @@ sub modify_quotas { my (%haschgs,%inconf); if ($context eq 'requestauthor') { %haschgs = %changes; - %inconf = %confhash; + %inconf = %confhash; } else { if (ref($changes{$item}) eq 'HASH') { %haschgs = %{$changes{$item}}; @@ -6052,7 +6496,7 @@ sub modify_quotas { &Apache::lonnet::usertools_access($env{'user.name'}, $env{'user.domain'}, $item,'reload',$context); - if (($context eq 'requestcourses') || + if (($context eq 'requestcourses') || ($context eq 'requestauthor')) { if ($env{'environment.canrequest.'.$item} ne $newacc) { $newenv{'environment.canrequest.'.$item} = $newacc; @@ -6124,6 +6568,42 @@ sub modify_quotas { } } } + if ($action eq 'requestcourses') { + my @offon = ('off','on'); + if ($changes{'uniquecode'}) { + if (ref($confhash{'uniquecode'}) eq 'HASH') { + my $codestr = join(' ',map{ &mt($_); } sort(keys(%{$confhash{'uniquecode'}}))); + $resulttext .= '
    • '. + &mt('Generation of six character code as course identifier for distribution to students set to on for: [_1].',''.$codestr.''). + '
    • '; + } else { + $resulttext .= '
    • '.&mt('Generation of six character code as course identifier for distribution to students set to off.'). + '
    • '; + } + } + if (ref($changes{'textbooks'}) eq 'HASH') { + $resulttext .= '
    • '.&mt('Available textbooks updated').'
        '; + foreach my $key (sort(keys(%{$changes{'textbooks'}}))) { + my %coursehash = &Apache::lonnet::coursedescription($key); + my $coursetitle = $coursehash{'description'}; + my $position = $confhash{'textbooks'}{$key}{'order'} + 1; + $resulttext .= '
      • '; + foreach my $item ('subject','title','author') { + my $name = $item.':'; + $name =~ s/^(\w)/\U$1/; + $resulttext .= &mt($name).' '.$confhash{'textbooks'}{$key}{$item}.'
        '; + } + $resulttext .= ' '.&mt('Order: [_1]',$position).'
        '; + if ($confhash{'textbooks'}{$key}{'image'}) { + $resulttext .= ' '.&mt('Image: [_1]', + 'Textbook cover').'
        '; + } + $resulttext .= ' '.&mt('LON-CAPA Course: [_1]',$coursetitle).'
      • '; + } + $resulttext .= '
    • '; + } + } $resulttext .= '
    '; if (keys(%newenv)) { &Apache::lonnet::appenv(\%newenv); @@ -6141,11 +6621,42 @@ sub modify_quotas { $resulttext = ''. &mt('An error occurred: [_1]',$putresult).''; } + if ($errors) { + $resulttext .= '

    '.&mt('The following errors occurred when modifying Textbook settings.'). + '

      '.$errors.'

    '; + } return $resulttext; } +sub process_textbook_image { + my ($r,$dom,$confname,$caller,$cdom,$cnum,$configuserok,$switchserver,$author_ok) = @_; + my $filename = $env{'form.'.$caller.'.filename'}; + my ($error,$url); + my ($width,$height) = (50,50); + if ($configuserok eq 'ok') { + if ($switchserver) { + $error = &mt('Upload of textbook image is not permitted to this server: [_1]', + $switchserver); + } elsif ($author_ok eq 'ok') { + my ($result,$imageurl) = + &publishlogo($r,'upload',$caller,$dom,$confname, + "textbooks/$dom/$cnum/cover",$width,$height); + if ($result eq 'ok') { + $url = $imageurl; + } else { + $error = &mt("Upload of [_1] failed because an error occurred publishing the file in RES space. Error was: [_2].",$filename,$result); + } + } else { + $error = &mt("Upload of [_1] failed because an author role could not be assigned to a Domain Configuration user ([_2]) in domain: [_3]. Error was: [_4].",$filename,$confname,$dom,$author_ok); + } + } else { + $error = &mt("Upload of [_1] failed because a Domain Configuration user ([_2]) could not be created in domain: [_3]. Error was: [_4].",$filename,$confname,$dom,$configuserok); + } + return ($url,$error); +} + sub modify_autoenroll { - my ($dom,%domconfig) = @_; + my ($dom,$lastactref,%domconfig) = @_; my ($resulttext,%changes); my %currautoenroll; if (ref($domconfig{'autoenroll'}) eq 'HASH') { @@ -6213,6 +6724,9 @@ sub modify_autoenroll { if ($changes{'coowners'}) { $resulttext .= '
  • '.&mt("$title{'coowners'} set to $offon[$env{'form.autoassign_coowners'}]").'
  • '; &Apache::loncommon::devalidate_domconfig_cache($dom); + if (ref($lastactref) eq 'HASH') { + $lastactref->{'domainconfig'} = 1; + } } $resulttext .= ''; } else { @@ -6618,7 +7132,7 @@ sub modify_directorysrch { } else { $chgtext =~ s/\; $//; } - $resulttext .= + $resulttext .= '
  • '. &mt("Users from domain '[_1]' permitted to search the institutional directory set to: [_2]", ''.$dom.'',$chgtext). @@ -6664,7 +7178,7 @@ sub modify_directorysrch { } sub modify_contacts { - my ($dom,%domconfig) = @_; + my ($dom,$lastactref,%domconfig) = @_; my ($resulttext,%currsetting,%newsetting,%changes,%contacts_hash); if (ref($domconfig{'contacts'}) eq 'HASH') { foreach my $key (keys(%{$domconfig{'contacts'}})) { @@ -6674,7 +7188,8 @@ sub modify_contacts { my (%others,%to,%bcc); my @contacts = ('supportemail','adminemail'); my @mailings = ('errormail','packagesmail','helpdeskmail','lonstatusmail', - 'requestsmail','updatesmail'); + 'requestsmail','updatesmail','idconflictsmail'); + my @toggles = ('reporterrors','reportupdates'); foreach my $type (@mailings) { @{$newsetting{$type}} = &Apache::loncommon::get_env_multiple('form.'.$type); @@ -6696,6 +7211,11 @@ sub modify_contacts { $to{$item} = $env{'form.'.$item}; $contacts_hash{'contacts'}{$item} = $to{$item}; } + foreach my $item (@toggles) { + if ($env{'form.'.$item} =~ /^(0|1)$/) { + $contacts_hash{'contacts'}{$item} = $env{'form.'.$item}; + } + } if (keys(%currsetting) > 0) { foreach my $item (@contacts) { if ($to{$item} ne $currsetting{$item}) { @@ -6734,7 +7254,7 @@ sub modify_contacts { foreach my $item (@contacts) { if ($to{$item} ne $default{$item}) { $changes{$item} = 1; - } + } } foreach my $type (@mailings) { if ((@{$newsetting{$type}} != 1) || ($newsetting{$type}[0] ne $default{$type})) { @@ -6751,10 +7271,22 @@ sub modify_contacts { } } } + foreach my $item (@toggles) { + if (($env{'form.'.$item} == 1) && ($currsetting{$item} == 0)) { + $changes{$item} = 1; + } elsif ((!$env{'form.'.$item}) && + (($currsetting{$item} eq '') || ($currsetting{$item} == 1))) { + $changes{$item} = 1; + } + } my $putresult = &Apache::lonnet::put_dom('configuration',\%contacts_hash, $dom); if ($putresult eq 'ok') { if (keys(%changes) > 0) { + &Apache::loncommon::devalidate_domconfig_cache($dom); + if (ref($lastactref) eq 'HASH') { + $lastactref->{'domainconfig'} = 1; + } my ($titles,$short_titles) = &contact_titles(); $resulttext = &mt('Changes made:').'
      '; foreach my $item (@contacts) { @@ -6785,6 +7317,23 @@ sub modify_contacts { $resulttext .= ''; } } + my @offon = ('off','on'); + if ($changes{'reporterrors'}) { + $resulttext .= '
    • '. + &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)). + '
    • '; + } + if ($changes{'reportupdates'}) { + $resulttext .= '
    • '. + &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)). + '
    • '; + } $resulttext .= '
    '; } else { $resulttext = &mt('No changes made to contact information'); @@ -6812,7 +7361,7 @@ sub modify_usercreation { foreach my $item(@contexts) { if ($item eq 'selfcreate') { @{$cancreate{$item}} = &Apache::loncommon::get_env_multiple('form.can_createuser_'.$item); - my %domdefaults = &Apache::lonnet::get_domain_defaults($dom); + my %domdefaults = &Apache::lonnet::get_domain_defaults($dom,1); if (!((($domdefaults{'auth_def'} =~/^krb/) && ($domdefaults{'auth_arg_def'} ne '')) || ($domdefaults{'auth_def'} eq 'localauth'))) { if (ref($cancreate{$item}) eq 'ARRAY') { if (grep(/^login$/,@{$cancreate{$item}})) { @@ -7085,7 +7634,7 @@ sub modify_usercreation { if ($captchas{$cancreate{$type}}) { $chgtext .= &mt("Validation for self-creation screen set to $captchas{$cancreate{$type}}."); } else { - $chgtext .= &mt('Validation for self-creation screen set to unknown type.'); + $chgtext .= &mt('Validation for self-creation screen set to unknown type.'); } } } elsif ($type eq 'recaptchakeys') { @@ -7213,7 +7762,7 @@ sub process_captcha { $newsettings->{'captcha'} = 'original'; } if ($current->{'captcha'} ne $newsettings->{'captcha'}) { - if ($container eq 'cancreate') { + if ($container eq 'cancreate') { if (ref($changes->{'cancreate'}) eq 'ARRAY') { push(@{$changes->{'cancreate'}},'captcha'); } elsif (!defined($changes->{'cancreate'})) { @@ -7252,7 +7801,7 @@ sub process_captcha { $changes->{'cancreate'} = ['recaptchakeys']; } } else { - $changes->{'recaptchakeys'} = 1; + $changes->{'recaptchakeys'} = 1; } } return; @@ -7379,9 +7928,9 @@ sub modify_usermodification { } sub modify_defaults { - my ($dom,$r) = @_; + my ($dom,$lastactref,%domconfig) = @_; my ($resulttext,$mailmsgtxt,%newvalues,%changes,@errors); - my %domdefaults = &Apache::lonnet::get_domain_defaults($dom); + my %domdefaults = &Apache::lonnet::get_domain_defaults($dom,1); my @items = ('auth_def','auth_arg_def','lang_def','timezone_def','datelocale_def','portal_def'); my @authtypes = ('internal','krb4','krb5','localauth'); foreach my $item (@items) { @@ -7441,7 +7990,7 @@ sub modify_defaults { if ($putresult eq 'ok') { if (keys(%changes) > 0) { $resulttext = &mt('Changes made:').'
      '; - my $version = $r->dir_config('lonVersion'); + my $version = &Apache::lonnet::get_server_loncaparev($dom); my $mailmsgtext = "Changes made to domain settings in a LON-CAPA installation - domain: $dom (running version: $version) - dns_domain.tab needs to be updated with the following changes, to support legacy 2.4, 2.5 and 2.6 versions of LON-CAPA.\n\n"; foreach my $item (sort(keys(%changes))) { my $value = $env{'form.'.$item}; @@ -7464,9 +8013,21 @@ sub modify_defaults { $mailmsgtext .= "\n"; my $cachetime = 24*60*60; &Apache::lonnet::do_cache_new('domdefaults',$dom,\%domdefaults,$cachetime); + if (ref($lastactref) eq 'HASH') { + $lastactref->{'domdefaults'} = 1; + } if ($changes{'auth_def'} || $changes{'auth_arg_def'} || $changes{'lang_def'} || $changes{'datelocale_def'}) { - my $sysmail = $r->dir_config('lonSysEMail'); - &Apache::lonmsg::sendemail($sysmail,"LON-CAPA Domain Settings Change - $dom",$mailmsgtext); + my $notify = 1; + if (ref($domconfig{'contacts'}) eq 'HASH') { + if ($domconfig{'contacts'}{'reportupdates'} == 0) { + $notify = 0; + } + } + if ($notify) { + &Apache::lonmsg::sendemail('installrecord@loncapa.org', + "LON-CAPA Domain Settings Change - $dom", + $mailmsgtext); + } } } else { $resulttext = &mt('No changes made to default authentication/language/timezone settings'); @@ -7486,7 +8047,7 @@ sub modify_defaults { } sub modify_scantron { - my ($r,$dom,$confname,%domconfig) = @_; + my ($r,$dom,$confname,$lastactref,%domconfig) = @_; my ($resulttext,%confhash,%changes,$errors); my $custom = 'custom.tab'; my $default = 'default.tab'; @@ -7547,6 +8108,9 @@ sub modify_scantron { } $resulttext .= '
    '; &Apache::loncommon::devalidate_domconfig_cache($dom); + if (ref($lastactref) eq 'HASH') { + $lastactref->{'domainconfig'} = 1; + } } else { $resulttext = &mt('No changes made to bubblesheet format file'); } @@ -7937,7 +8501,7 @@ sub modify_helpsettings { $changes{$item} = 1; } } - if (($env{'form.'.$item} eq '0') || ($env{'form.'.$item} eq '1')) { + if (($env{'form.'.$item} eq '0') || ($env{'form.'.$item} eq '1')) { $helphash{'helpsettings'}{$item} = $env{'form.'.$item}; } } @@ -7970,13 +8534,13 @@ sub modify_helpsettings { } sub modify_coursedefaults { - my ($dom,%domconfig) = @_; + my ($dom,$lastactref,%domconfig) = @_; my ($resulttext,$errors,%changes,%defaultshash); my %defaultchecked = ('canuse_pdfforms' => 'off'); my @toggles = ('canuse_pdfforms'); my @numbers = ('anonsurvey_threshold','uploadquota_official','uploadquota_unofficial', - 'uploadquota_community'); - my @types = ('official','unofficial','community'); + 'uploadquota_community','uploadquota_textbook'); + my @types = ('official','unofficial','community','textbook'); my %staticdefaults = ( anonsurvey_threshold => 10, uploadquota => 500, @@ -8011,7 +8575,7 @@ sub modify_coursedefaults { } foreach my $item (@numbers) { my ($currdef,$newdef); - my $newdef = $env{'form.'.$item}; + $newdef = $env{'form.'.$item}; if ($item eq 'anonsurvey_threshold') { $currdef = $domconfig{'coursedefaults'}{$item}; $newdef =~ s/\D//g; @@ -8041,30 +8605,33 @@ sub modify_coursedefaults { } } my $officialcreds = $env{'form.official_credits'}; - $officialcreds =~ s/^[^\d\.]//g; + $officialcreds =~ s/[^\d.]+//g; my $unofficialcreds = $env{'form.unofficial_credits'}; - $unofficialcreds =~ s/^[^\d\.]//g; + $unofficialcreds =~ s/[^\d.]+//g; + my $textbookcreds = $env{'form.textbook_credits'}; + $textbookcreds =~ s/[^\d.]+//g; if (ref($domconfig{'coursedefaults'}{'coursecredits'} ne 'HASH') && ($env{'form.coursecredits'} eq '1')) { $changes{'coursecredits'} = 1; } else { if (($domconfig{'coursedefaults'}{'coursecredits'}{'official'} ne $officialcreds) || - ($domconfig{'coursedefaults'}{'coursecredits'}{'unofficial'} ne $unofficialcreds)) { + ($domconfig{'coursedefaults'}{'coursecredits'}{'unofficial'} ne $unofficialcreds) || + ($domconfig{'coursedefaults'}{'coursecredits'}{'textbook'} ne $textbookcreds)) { $changes{'coursecredits'} = 1; } } $defaultshash{'coursedefaults'}{'coursecredits'} = { official => $officialcreds, unofficial => $unofficialcreds, + textbook => $textbookcreds, } } my $putresult = &Apache::lonnet::put_dom('configuration',\%defaultshash, $dom); if ($putresult eq 'ok') { - my %domdefaults; if (keys(%changes) > 0) { + my %domdefaults = &Apache::lonnet::get_domain_defaults($dom,1); if (($changes{'canuse_pdfforms'}) || ($changes{'coursecredits'}) || ($changes{'uploadquota'})) { - %domdefaults = &Apache::lonnet::get_domain_defaults($dom); if ($changes{'canuse_pdfforms'}) { $domdefaults{'canuse_pdfforms'}=$defaultshash{'coursedefaults'}{'canuse_pdfforms'}; } @@ -8074,6 +8641,8 @@ sub modify_coursedefaults { $defaultshash{'coursedefaults'}{'coursecredits'}{'official'}; $domdefaults{'unofficialcredits'} = $defaultshash{'coursedefaults'}{'coursecredits'}{'unofficial'}; + $domdefaults{'textbookcredits'} = + $domdefaults{'coursedefaults'}{'coursecredits'}{'textbook'}; } } if ($changes{'uploadquota'}) { @@ -8085,6 +8654,9 @@ sub modify_coursedefaults { } my $cachetime = 24*60*60; &Apache::lonnet::do_cache_new('domdefaults',$dom,\%domdefaults,$cachetime); + if (ref($lastactref) eq 'HASH') { + $lastactref->{'domdefaults'} = 1; + } } $resulttext = &mt('Changes made:').'
      '; foreach my $item (sort(keys(%changes))) { @@ -8101,6 +8673,8 @@ sub modify_coursedefaults { $resulttext .= '
    • '.&mt('Default quota for content uploaded to a course/community via Course Editor set as follows:').'
        '. '
      • '.&mt('Official courses: [_1] MB',''.$defaultshash{'coursedefaults'}{'uploadquota'}{'official'}.'').'
      • '. '
      • '.&mt('Unofficial courses: [_1] MB',''.$defaultshash{'coursedefaults'}{'uploadquota'}{'unofficial'}.'').'
      • '. + '
      • '.&mt('Textbook courses: [_1] MB',''.$defaultshash{'coursedefaults'}{'uploadquota'}{'textbook'}.'').'
      • '. + '
      • '.&mt('Communities: [_1] MB',''.$defaultshash{'coursedefaults'}{'uploadquota'}{'community'}.'').'
      • '. '
      '. '
    • '; @@ -8110,12 +8684,14 @@ sub modify_coursedefaults { } elsif ($item eq 'coursecredits') { if (ref($defaultshash{'coursedefaults'}{'coursecredits'}) eq 'HASH') { if (($domdefaults{'officialcredits'} eq '') && - ($domdefaults{'unofficialcredits'} eq '')) { + ($domdefaults{'unofficialcredits'} eq '') && + ($domdefaults{'textbookcredits'} eq '')) { $resulttext .= '
    • '.&mt('Student credits not in use for courses in this domain').'
    • '; } else { $resulttext .= '
    • '.&mt('Student credits can be set per course by a Domain Coordinator, with the following defaults applying:').'
        '. '
      • '.&mt('Official courses: [_1]',$defaultshash{'coursedefaults'}{'coursecredits'}{'official'}).'
      • '. '
      • '.&mt('Unofficial courses: [_1]',$defaultshash{'coursedefaults'}{'coursecredits'}{'unofficial'}).'
      • '. + '
      • '.&mt('Textbook courses: [_1]',$defaultshash{'coursedefaults'}{'coursecredits'}{'textbook'}).'
      • '. '
      '. '
    • '; } @@ -8136,7 +8712,7 @@ sub modify_coursedefaults { } sub modify_usersessions { - my ($dom,%domconfig) = @_; + my ($dom,$lastactref,%domconfig) = @_; my @hostingtypes = ('version','excludedomain','includedomain'); my @offloadtypes = ('primary','default'); my %types = ( @@ -8153,7 +8729,7 @@ sub modify_usersessions { foreach my $prefix (@prefixes) { $defaultshash{'usersessions'}{$prefix} = {}; } - my %domdefaults = &Apache::lonnet::get_domain_defaults($dom); + my %domdefaults = &Apache::lonnet::get_domain_defaults($dom,1); my $resulttext; my %iphost = &Apache::lonnet::get_iphost(); foreach my $prefix (@prefixes) { @@ -8329,6 +8905,9 @@ sub modify_usersessions { } my $cachetime = 24*60*60; &Apache::lonnet::do_cache_new('domdefaults',$dom,\%domdefaults,$cachetime); + if (ref($lastactref) eq 'HASH') { + $lastactref->{'domdefaults'} = 1; + } if (keys(%changes) > 0) { my %lt = &usersession_titles(); $resulttext = &mt('Changes made:').'
        '; @@ -8340,7 +8919,8 @@ sub modify_usersessions { foreach my $lonhost (sort(keys(%{$changes{$prefix}}))) { $resulttext .= '
      • '.$lonhost.' '; my $lonhostdom = &Apache::lonnet::host_domain($lonhost); - &Apache::lonnet::remote_devalidate_cache($lonhost,'spares',$lonhostdom); + my $cachekey = &escape('spares').':'.&escape($lonhostdom); + &Apache::lonnet::remote_devalidate_cache($lonhost,[$cachekey]); if (ref($changes{$prefix}{$lonhost}) eq 'HASH') { foreach my $type (@{$types{$prefix}}) { if ($changes{$prefix}{$lonhost}{$type}) { @@ -8430,7 +9010,7 @@ sub modify_loadbalancing { if ($balancer eq '') { next; } - if (!exists($servers{$balancer})) { + if (!exists($servers{$balancer})) { if (exists($currbalancer{$balancer})) { push(@{$changes{'delete'}},$balancer); } @@ -8481,14 +9061,14 @@ sub modify_loadbalancing { } } else { if (ref($defaultshash{'loadbalancing'}{$balancer}) eq 'HASH') { - foreach my $sparetype (@sparestypes) { + foreach my $sparetype (@sparestypes) { if (ref($defaultshash{'loadbalancing'}{$balancer}{'targets'}{$sparetype}) eq 'ARRAY') { if (@{$defaultshash{'loadbalancing'}{$balancer}{'targets'}{$sparetype}} > 0) { $changes{'curr'}{$balancer}{'targets'} = 1; } } } - } + } } my $ishomedom; if (&Apache::lonnet::host_domain($balancer) eq $dom) { @@ -8497,7 +9077,7 @@ sub modify_loadbalancing { if (ref($alltypes) eq 'ARRAY') { foreach my $type (@{$alltypes}) { my $rule; - unless ((($type eq '_LC_external') || ($type eq '_LC_internetdom')) && + unless ((($type eq '_LC_external') || ($type eq '_LC_internetdom')) && (!$ishomedom)) { $rule = $env{'form.loadbalancing_rules_'.$i.'_'.$type}; } @@ -8522,17 +9102,17 @@ sub modify_loadbalancing { } my $putresult = &Apache::lonnet::put_dom('configuration', \%defaultshash,$dom); - if ($putresult eq 'ok') { if (keys(%changes) > 0) { if (ref($changes{'delete'}) eq 'ARRAY') { foreach my $balancer (sort(@{$changes{'delete'}})) { $resulttext .= '
      • '.&mt('Load Balancing discontinued for: [_1]',$balancer).'
      • '; - &Apache::lonnet::remote_devalidate_cache($balancer,'loadbalancing',$dom); + my $cachekey = &escape('loadbalancing').':'.&escape($dom); + &Apache::lonnet::remote_devalidate_cache($balancer,[$cachekey]); } } if (ref($changes{'add'}) eq 'ARRAY') { - foreach my $balancer (sort(@{$changes{'add'}})) { + foreach my $balancer (sort(@{$changes{'add'}})) { $resulttext .= '
      • '.&mt('Load Balancing enabled for: [_1]',$balancer); } } @@ -8573,17 +9153,19 @@ sub modify_loadbalancing { my $balancetext; if ($rule eq '') { $balancetext = $ruletitles{'default'}; - } elsif (($rule eq 'homeserver') || ($rule eq 'externalbalancer')) { + } elsif (($rule eq 'homeserver') || ($rule eq 'externalbalancer') || + ($rule eq 'balancer') || ($rule eq 'offloadedto')) { $balancetext = $ruletitles{$rule}; } else { $balancetext = &mt('offload to [_1]',$defaultshash{'loadbalancing'}{$balancer}{'rules'}{$type}); } - $resulttext .= '
      • '.&mt('Load Balancer: [_1] -- balancing for [_2] set to - "[_3]"',$balancer,$titles->{$type},$balancetext).'
      • '; + $resulttext .= '
      • '.&mt('Load Balancer: [_1] -- balancing for [_2] set to - "[_3]"',$balancer,$titles->{$type},$balancetext).'
      • '; } } } } - &Apache::lonnet::remote_devalidate_cache($balancer,'loadbalancing',$dom); + my $cachekey = &escape('loadbalancing').':'.&escape($dom); + &Apache::lonnet::remote_devalidate_cache($balancer,[$cachekey]); } } if ($resulttext ne '') { @@ -8671,7 +9253,7 @@ sub active_dc_picker { } } @domcoord = sort(@domcoord); - my $numdcs = scalar(@domcoord); + my $numdcs = scalar(@domcoord); my $rows = 0; my $table; if ($numdcs > 1) { @@ -8805,7 +9387,7 @@ sub lonbalance_targets_js { } &get_loadbalancers_config($servers,\%existing,\%currbalancer, \%currtargets,\%currrules); - my $balancers = join("','",sort(keys(%currbalancer))); + my $balancers = join("','",sort(keys(%currbalancer))); return <<"END";