--- loncom/interface/domainprefs.pm 2008/05/08 22:13:32 1.49 +++ loncom/interface/domainprefs.pm 2008/06/24 15:01:23 1.56 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # Handler to set domain-wide configuration settings # -# $Id: domainprefs.pm,v 1.49 2008/05/08 22:13:32 raeburn Exp $ +# $Id: domainprefs.pm,v 1.56 2008/06/24 15:01:23 bisitz Exp $ # # Copyright Michigan State University Board of Trustees # @@ -96,7 +96,7 @@ sub handler { col2 => '',}], }, 'defaults' => - { text => 'Default authentication/language', + { text => 'Default authentication/language/timezone', help => '', header => [{col1 => 'Setting', col2 => 'Value'}], @@ -300,10 +300,10 @@ sub handler { $r->print('

'.&mt('Functionality to display/modify').'

'); $r->print(''."\n".'

'."\n".'

  '. - '

'); my ($numitems,$midpoint,$seconddiv,$count); @@ -314,7 +314,7 @@ sub handler { } $count = 0; foreach my $item (@prefs_order) { - $r->print('

'); + $r->print('

'); $count ++; if ((!$seconddiv) && ($count >= $midpoint)) { $r->print('
'."\n".'
'."\n"); @@ -1543,11 +1543,21 @@ sub print_usercreation { &Apache::lonnet::inst_userrules($dom,'username'); my %lt = &usercreation_types(); my %checked; + my @selfcreate; if (ref($settings) eq 'HASH') { if (ref($settings->{'cancreate'}) eq 'HASH') { foreach my $item (@creators) { $checked{$item} = $settings->{'cancreate'}{$item}; } + if (ref($settings->{'cancreate'}{'selfcreate'}) eq 'ARRAY') { + @selfcreate = @{$settings->{'cancreate'}{'selfcreate'}}; + } elsif ($settings->{'cancreate'}{'selfcreate'} ne '') { + if ($settings->{'cancreate'}{'selfcreate'} eq 'any') { + @selfcreate = ('email','login','sso'); + } elsif ($settings->{'cancreate'}{'selfcreate'} ne 'none') { + @selfcreate = ($settings->{'cancreate'}{'selfcreate'}); + } + } } elsif (ref($settings->{'cancreate'}) eq 'ARRAY') { foreach my $item (@creators) { if (grep(/^\Q$item\E$/,@{$settings->{'cancreate'}})) { @@ -1559,10 +1569,8 @@ sub print_usercreation { my $rownum = 0; foreach my $item (@creators) { $rownum ++; - if ($checked{$item} eq '') { - if ($item eq 'selfcreate') { - $checked{$item} = 'none'; - } else { + if ($item ne 'selfcreate') { + if ($checked{$item} eq '') { $checked{$item} = 'any'; } } @@ -1575,24 +1583,33 @@ sub print_usercreation { $datatable .= ''. ''.$lt{$item}. ''; - my @options = ('any'); + my @options; if ($item eq 'selfcreate') { push(@options,('email','login','sso')); } else { + @options = ('any'); if (ref($rules) eq 'HASH') { if (keys(%{$rules}) > 0) { push(@options,('official','unofficial')); } } + push(@options,'none'); } - push(@options,'none'); foreach my $option (@options) { + my $type = 'radio'; my $check = ' '; - if ($checked{$item} eq $option) { - $check = ' checked="checked" '; + if ($item eq 'selfcreate') { + $type = 'checkbox'; + if (grep(/^\Q$option\E$/,@selfcreate)) { + $check = ' checked="checked" '; + } + } else { + if ($checked{$item} eq $option) { + $check = ' checked="checked" '; + } } $datatable .= '  '; } @@ -1765,7 +1782,7 @@ sub print_usermodification { sub print_defaults { my ($dom,$rowtotal) = @_; - my @items = ('auth_def','auth_arg_def','lang_def'); + my @items = ('auth_def','auth_arg_def','lang_def','timezone_def'); my %domdefaults = &Apache::lonnet::get_domain_defaults($dom); my $titles = &defaults_titles(); my $rownum = 0; @@ -1797,6 +1814,9 @@ sub print_defaults { '" value="'.$auth.'"'.$checked.'/>'. $authnames{$shortauth{$auth}}.'  '; } + } elsif ($item eq 'timezone_def') { + my $includeempty = 1; + $datatable .= &Apache::loncommon::select_timezone($item,$domdefaults{$item},undef,$includeempty); } else { $datatable .= ''; @@ -1813,6 +1833,7 @@ sub defaults_titles { 'auth_def' => 'Default authentication type', 'auth_arg_def' => 'Default authentication argument', 'lang_def' => 'Default language', + 'timezone_def' => 'Default timezone', ); return (\%titles); } @@ -1945,7 +1966,8 @@ sub print_coursecategories { my $itemcount = 1; if (ref($settings) eq 'HASH') { my (@cats,@trails,%allitems,%idx,@jsarray); - &extract_categories($settings,\@cats,\@trails,\%allitems,\%idx,\@jsarray); + &Apache::loncommon::extract_categories($settings,\@cats,\@trails, + \%allitems,\%idx,\@jsarray); my $maxdepth = scalar(@cats); my $colattrib = ''; if ($maxdepth > 2) { @@ -2050,7 +2072,7 @@ sub coursecategories_javascript { my ($output,$jstext); if (ref($settings) eq 'HASH') { my (@cats,@jsarray,%idx); - &gather_categories($settings,\@cats,\%idx,\@jsarray); + &Apache::loncommon::gather_categories($settings,\@cats,\%idx,\@jsarray); if (@jsarray > 0) { $jstext = ' var categories = Array('.scalar(@jsarray).');'."\n"; for (my $i=0; $i<@jsarray; $i++) { @@ -2147,7 +2169,7 @@ sub initialize_categories { $css_class = $itemcount%2?' class="LC_odd_row"':''; $chgstr = ' onchange="javascript:reorderCats(this.form,'."'','addcategory_pos','0'".');"'; $datatable .= '' - .'' .' ' .&mt('Add category').''.&mt('Name:') .' '; @@ -2452,34 +2474,36 @@ sub modify_login { 'adminmail' => 'off', 'newuser' => 'off', ); - foreach my $item (@toggles) { - if ($defaultchecked{$item} eq 'on') { - if (($domconfig{'login'}{$item} eq '0') && - ($env{'form.'.$item} eq '1')) { - $changes{$item} = 1; - } elsif (($domconfig{'login'}{$item} eq '' || - $domconfig{'login'}{$item} eq '1') && - ($env{'form.'.$item} eq '0')) { - $changes{$item} = 1; - } - } elsif ($defaultchecked{$item} eq 'off') { - if (($domconfig{'login'}{$item} eq '1') && - ($env{'form.'.$item} eq '0')) { - $changes{$item} = 1; - } elsif (($domconfig{'login'}{$item} eq '' || - $domconfig{'login'}{$item} eq '0') && - ($env{'form.'.$item} eq '1')) { - $changes{$item} = 1; + if (ref($domconfig{'login'}) eq 'HASH') { + foreach my $item (@toggles) { + if ($defaultchecked{$item} eq 'on') { + if (($domconfig{'login'}{$item} eq '0') && + ($env{'form.'.$item} eq '1')) { + $changes{$item} = 1; + } elsif (($domconfig{'login'}{$item} eq '' || + $domconfig{'login'}{$item} eq '1') && + ($env{'form.'.$item} eq '0')) { + $changes{$item} = 1; + } + } elsif ($defaultchecked{$item} eq 'off') { + if (($domconfig{'login'}{$item} eq '1') && + ($env{'form.'.$item} eq '0')) { + $changes{$item} = 1; + } elsif (($domconfig{'login'}{$item} eq '' || + $domconfig{'login'}{$item} eq '0') && + ($env{'form.'.$item} eq '1')) { + $changes{$item} = 1; + } } } - } - if (($domconfig{'login'}{'loginheader'} eq 'text') && - ($env{'form.loginheader'} eq 'image')) { - $changes{'loginheader'} = 1; - } elsif (($domconfig{'login'}{'loginheader'} eq '' || - $domconfig{'login'}{'loginheader'} eq 'image') && - ($env{'form.loginheader'} eq 'text')) { - $changes{'loginheader'} = 1; + if (($domconfig{'login'}{'loginheader'} eq 'text') && + ($env{'form.loginheader'} eq 'image')) { + $changes{'loginheader'} = 1; + } elsif (($domconfig{'login'}{'loginheader'} eq '' || + $domconfig{'login'}{'loginheader'} eq 'image') && + ($env{'form.loginheader'} eq 'text')) { + $changes{'loginheader'} = 1; + } } if (keys(%changes) > 0 || $colchgtext) { &Apache::loncommon::devalidate_domconfig_cache($dom); @@ -2512,6 +2536,7 @@ sub color_font_choices { img => "Header", bgs => "Background colors", links => "Link colors", + images => "Images", font => "Font color", pgbg => "Page", tabbg => "Header", @@ -2527,6 +2552,11 @@ sub modify_rolecolors { my ($r,$dom,$confname,$roles,%domconfig) = @_; my ($resulttext,%rolehash); $rolehash{'rolecolors'} = {}; + if (ref($domconfig{'rolecolors'}) ne 'HASH') { + if ($domconfig{'rolecolors'} eq '') { + $domconfig{'rolecolors'} = {}; + } + } my ($errors,%changes) = &modify_colors($r,$dom,$confname,$roles, $domconfig{'rolecolors'},$rolehash{'rolecolors'}); my $putresult = &Apache::lonnet::put_dom('configuration',\%rolehash, @@ -2553,7 +2583,7 @@ sub modify_rolecolors { sub modify_colors { my ($r,$dom,$confname,$roles,$domconfig,$confhash) = @_; my (%changes,%choices); - my @bgs = ('pgbg','mainbg','sidebg'); + my @bgs; my @links = ('link','alink','vlink'); my @logintext; my @images; @@ -2568,8 +2598,10 @@ sub modify_colors { } if ($role eq 'login') { @images = ('img','logo','domlogo','login'); + @bgs = ('pgbg','mainbg','sidebg'); } else { @images = ('img'); + @bgs = ('pgbg','tabbg','sidebg'); } $confhash->{$role}{'font'} = $env{'form.'.$role.'_font'}; foreach my $item (@bgs,@links,@logintext) { @@ -3120,7 +3152,11 @@ sub modify_quotas { } foreach my $key (keys(%formhash)) { if ($formhash{$key} ne '') { - if (!exists($domconfig{'quotas'}{$key})) { + if (ref($domconfig{'quotas'}) eq 'HASH') { + if (!exists($domconfig{'quotas'}{$key})) { + $changes{$key} = 1; + } + } else { $changes{$key} = 1; } } @@ -3640,21 +3676,81 @@ sub modify_usercreation { my @email_rule = &Apache::loncommon::get_env_multiple('form.email_rule'); my @contexts = ('author','course','selfcreate'); foreach my $item(@contexts) { - $cancreate{$item} = $env{'form.can_createuser_'.$item}; if ($item eq 'selfcreate') { + @{$cancreate{$item}} = &Apache::loncommon::get_env_multiple('form.can_createuser_'.$item); my %domdefaults = &Apache::lonnet::get_domain_defaults($dom); if (!((($domdefaults{'auth_def'} =~/^krb/) && ($domdefaults{'auth_arg_def'} ne '')) || ($domdefaults{'auth_def'} eq 'localauth'))) { - if (($cancreate{$item} eq 'any') || ($cancreate{$item} eq 'login')) { - $warningmsg = &mt('Although account creation has been set to be available for institutional logins, currently default authentication in this domain has not been set to support this.').' '.&mt('You need to set the default authentication type to Kerberos 4 or 5 (with a Kerberos domain specified), or to Local authentication, if the localauth module has been customized in your domain to authenticate institutional logins.'); + if (ref($cancreate{$item}) eq 'ARRAY') { + if (grep(/^login$/,@{$cancreate{$item}})) { + $warningmsg = &mt('Although account creation has been set to be available for institutional logins, currently default authentication in this domain has not been set to support this.').' '.&mt('You need to set the default authentication type to Kerberos 4 or 5 (with a Kerberos domain specified), or to Local authentication, if the localauth module has been customized in your domain to authenticate institutional logins.'); + } } } + } else { + $cancreate{$item} = $env{'form.can_createuser_'.$item}; } } if (ref($curr_usercreation{'cancreate'}) eq 'HASH') { foreach my $item (@contexts) { - if ($curr_usercreation{'cancreate'}{$item} ne $cancreate{$item}) { - push(@{$changes{'cancreate'}},$item); - } + if ($item eq 'selfcreate') { + if (ref($curr_usercreation{'cancreate'}{$item}) eq 'ARRAY') { + foreach my $curr (@{$curr_usercreation{'cancreate'}{$item}}) { + if (!grep(/^$curr$/,@{$cancreate{$item}})) { + if (!grep(/^$item$/,@{$changes{'cancreate'}})) { + push(@{$changes{'cancreate'}},$item); + } + } + } + } else { + if ($curr_usercreation{'cancreate'}{$item} eq '') { + if (@{$cancreate{$item}} > 0) { + if (!grep(/^$item$/,@{$changes{'cancreate'}})) { + push(@{$changes{'cancreate'}},$item); + } + } + } else { + if ($curr_usercreation{'cancreate'}{$item} eq 'any') { + if (@{$cancreate{$item}} < 3) { + if (!grep(/^$item$/,@{$changes{'cancreate'}})) { + push(@{$changes{'cancreate'}},$item); + } + } + } elsif ($curr_usercreation{'cancreate'}{$item} eq 'none') { + if (@{$cancreate{$item}} > 0) { + if (!grep(/^$item$/,@{$changes{'cancreate'}})) { + push(@{$changes{'cancreate'}},$item); + } + } + } elsif (!grep(/^$curr_usercreation{'cancreate'}{$item}$/,@{$cancreate{$item}})) { + if (!grep(/^$item$/,@{$changes{'cancreate'}})) { + push(@{$changes{'cancreate'}},$item); + } + } + } + } + if (!grep(/^$item$/,@{$changes{'cancreate'}})) { + foreach my $type (@{$cancreate{$item}}) { + if (ref($curr_usercreation{'cancreate'}{$item}) eq 'ARRAY') { + if (!grep(/^$type$/,@{$curr_usercreation{'cancreate'}{$item}})) { + if (!grep(/^$item$/,@{$changes{'cancreate'}})) { + push(@{$changes{'cancreate'}},$item); + } + } + } elsif (($curr_usercreation{'cancreate'}{$item} ne 'any') && + ($curr_usercreation{'cancreate'}{$item} ne 'none')) { + if ($curr_usercreation{'cancreate'}{$item} ne $type) { + if (!grep(/^$item$/,@{$changes{'cancreate'}})) { + push(@{$changes{'cancreate'}},$item); + } + } + } + } + } + } else { + if ($curr_usercreation{'cancreate'}{$item} ne $cancreate{$item}) { + push(@{$changes{'cancreate'}},$item); + } + } } } elsif (ref($curr_usercreation{'cancreate'}) eq 'ARRAY') { foreach my $item (@contexts) { @@ -3761,6 +3857,12 @@ sub modify_usercreation { my $putresult = &Apache::lonnet::put_dom('configuration',\%usercreation_hash, $dom); + + my %selfcreatetypes = ( + sso => 'users authenticated by institutional single sign on', + login => 'users authenticated by institutional log-in', + email => 'users who provide a valid e-mail address for use as the username', + ); if ($putresult eq 'ok') { if (keys(%changes) > 0) { $resulttext = &mt('Changes made:').'
    '; @@ -3769,16 +3871,14 @@ sub modify_usercreation { foreach my $type (@{$changes{'cancreate'}}) { my $chgtext = $lt{$type}.', '; if ($type eq 'selfcreate') { - if ($cancreate{$type} eq 'none') { + if (@{$cancreate{$type}} == 0) { $chgtext .= &mt('creation of a new user account is not permitted.'); - } elsif ($cancreate{$type} eq 'any') { - $chgtext .= &mt('creation of a new account is permitted for users authenticated by institutional log-in and SSO, and also for e-mail addresses used as usernames.'); - } elsif ($cancreate{$type} eq 'login') { - $chgtext .= &mt('creation of a new account is only permitted for users authenticated by institutional log-in.'); - } elsif ($cancreate{$type} eq 'sso') { - $chgtext .= &mt('creation of a new account is only permitted for users authenticated by institutional single sign on.'); - } elsif ($cancreate{$type} eq 'email') { - $chgtext .= &mt('creation of a new account is only permitted for users who provide a valid e-mail address for use as the username.'); + } else { + $chgtext .= &mt('creation of a new account is permitted for:
      '); + foreach my $case (@{$cancreate{$type}}) { + $chgtext .= '
    • '.$selfcreatetypes{$case}.'
    • '; + } + $chgtext .= '
    '; } } else { if ($cancreate{$type} eq 'none') { @@ -3983,7 +4083,7 @@ sub modify_defaults { my ($dom,$r) = @_; my ($resulttext,$mailmsgtxt,%newvalues,%changes,@errors); my %domdefaults = &Apache::lonnet::get_domain_defaults($dom); - my @items = ('auth_def','auth_arg_def','lang_def'); + my @items = ('auth_def','auth_arg_def','lang_def','timezone_def'); my @authtypes = ('internal','krb4','krb5','localauth'); foreach my $item (@items) { $newvalues{$item} = $env{'form.'.$item}; @@ -4004,6 +4104,13 @@ sub modify_defaults { push(@errors,$item); } } + } elsif ($item eq 'timezone_def') { + if ($newvalues{$item} ne '') { + my @timezones = &DateTime::TimeZone->all_names; + if (!grep(/^\Q$newvalues{$item}\E/,@timezones)) { + push(@errors,$item); + } + } } if (grep(/^\Q$item\E$/,@errors)) { $newvalues{$item} = $domdefaults{$item}; @@ -4015,6 +4122,7 @@ sub modify_defaults { defaults => { auth_def => $newvalues{'auth_def'}, auth_arg_def => $newvalues{'auth_arg_def'}, lang_def => $newvalues{'lang_def'}, + timezone_def => $newvalues{'timezone_def'}, } ); my $title = &defaults_titles(); @@ -4047,10 +4155,12 @@ sub modify_defaults { my $cachetime = 24*60*60; &Apache::lonnet::do_cache_new('domdefaults',$dom, $defaults_hash{'defaults'},$cachetime); - my $sysmail = $r->dir_config('lonSysEMail'); - &Apache::lonmsg::sendemail($sysmail,"LON-CAPA Domain Settings Change - $dom",$mailmsgtext); + if ($changes{'auth_def'} || $changes{'auth_arg_def'} || $changes{'lang_def'}) { + my $sysmail = $r->dir_config('lonSysEMail'); + &Apache::lonmsg::sendemail($sysmail,"LON-CAPA Domain Settings Change - $dom",$mailmsgtext); + } } else { - $resulttext = &mt('No changes made to default authentication/language settings'); + $resulttext = &mt('No changes made to default authentication/language/timezone settings'); } } else { $resulttext = ''. @@ -4149,14 +4259,16 @@ sub modify_coursecategories { my ($dom,%domconfig) = @_; my ($resulttext,%deletions,%reorderings,%needreordering,%adds,$errors); my @deletecategory = &Apache::loncommon::get_env_multiple('form.deletecategory'); - if (($domconfig{'coursecategories'}{'instcode::0'} ne '') && ($env{'form.instcode'} == 0)) { - push (@deletecategory,'instcode::0'); + if (ref($domconfig{'coursecategories'}) eq 'HASH') { + if (($domconfig{'coursecategories'}{'instcode::0'} ne '') && ($env{'form.instcode'} == 0)) { + push (@deletecategory,'instcode::0'); + } } my (@predelcats,@predeltrails,%predelallitems); if (ref($domconfig{'coursecategories'}) eq 'HASH') { if (@deletecategory > 0) { #FIXME Need to remove category from all courses using a deleted category - &extract_categories($domconfig{'coursecategories'},\@predelcats,\@predeltrails,\%predelallitems); + &Apache::loncommon::extract_categories($domconfig{'coursecategories'},\@predelcats,\@predeltrails,\%predelallitems); foreach my $item (@deletecategory) { if ($domconfig{'coursecategories'}{$item} ne '') { delete($domconfig{'coursecategories'}{$item}); @@ -4216,7 +4328,7 @@ sub modify_coursecategories { } } my (@chkcats,@chktrails,%chkallitems); - &extract_categories($domconfig{'coursecategories'},\@chkcats,\@chktrails,\%chkallitems); + &Apache::loncommon::extract_categories($domconfig{'coursecategories'},\@chkcats,\@chktrails,\%chkallitems); if (ref($chkcats[0]) eq 'ARRAY') { my $depth = 0; my $chg = 0; @@ -4238,7 +4350,7 @@ sub modify_coursecategories { } my $putresult = &Apache::lonnet::put_dom('configuration',\%domconfig,$dom); my (@cats,@trails,%allitems); - &extract_categories($domconfig{'coursecategories'},\@cats,\@trails,\%allitems); + &Apache::loncommon::extract_categories($domconfig{'coursecategories'},\@cats,\@trails,\%allitems); if ($putresult eq 'ok') { $resulttext = &mt('Changes made:').'
      '; if (keys(%deletions) > 0) { @@ -4323,91 +4435,6 @@ sub recurse_cat_deletes { } } return; -} - -sub gather_categories { - my ($categories,$cats,$idx,$jsarray) = @_; - my %counters; - my $num = 0; - foreach my $item (keys(%{$categories})) { - my ($cat,$container,$depth) = map { &unescape($_); } split(/:/,$item); - if ($container eq '' && $depth == 0) { - $cats->[$depth][$categories->{$item}] = $cat; - } else { - $cats->[$depth]{$container}[$categories->{$item}] = $cat; - } - my ($escitem,$tail) = split(/:/,$item,2); - if ($counters{$tail} eq '') { - $counters{$tail} = $num; - $num ++; - } - if (ref($idx) eq 'HASH') { - $idx->{$item} = $counters{$tail}; - } - if (ref($jsarray) eq 'ARRAY') { - push(@{$jsarray->[$counters{$tail}]},$item); - } - } - return; -} - -sub extract_categories { - my ($categories,$cats,$trails,$allitems,$idx,$jsarray) = @_; - if (ref($categories) eq 'HASH') { - &gather_categories($categories,$cats,$idx,$jsarray); - if (ref($cats->[0]) eq 'ARRAY') { - for (my $i=0; $i<@{$cats->[0]}; $i++) { - my $name = $cats->[0][$i]; - my $item = &escape($name).'::0'; - my $trailstr; - if ($name eq 'instcode') { - $trailstr = &mt('Official courses (with institutional codes)'); - } else { - $trailstr = $name; - } - if ($allitems->{$item} eq '') { - push(@{$trails},$trailstr); - $allitems->{$item} = scalar(@{$trails})-1; - } - my @parents = ($name); - if (ref($cats->[1]{$name}) eq 'ARRAY') { - for (my $j=0; $j<@{$cats->[1]{$name}}; $j++) { - my $category = $cats->[1]{$name}[$j]; - &recurse_categories($cats,2,$category,$trails,$allitems,\@parents); - } - } - } - } - } - return; -} - -sub recurse_categories { - my ($cats,$depth,$category,$trails,$allitems,$parents) = @_; - my $shallower = $depth - 1; - if (ref($cats->[$depth]{$category}) eq 'ARRAY') { - for (my $k=0; $k<@{$cats->[$depth]{$category}}; $k++) { - my $name = $cats->[$depth]{$category}[$k]; - my $item = &escape($category).':'.&escape($parents->[-1]).':'.$shallower; - my $trailstr = join(' -> ',(@{$parents},$category)); - if ($allitems->{$item} eq '') { - push(@{$trails},$trailstr); - $allitems->{$item} = scalar(@{$trails})-1; - } - my $deeper = $depth+1; - push(@{$parents},$category); - &recurse_categories($cats,$deeper,$name,$trails,$allitems,$parents); - pop(@{$parents}); - } - } else { - my $item = &escape($category).':'.&escape($parents->[-1]).':'.$shallower; - my $trailstr = join(' -> ',(@{$parents},$category)); - if ($allitems->{$item} eq '') { - push(@{$trails},$trailstr); - $allitems->{$item} = scalar(@{$trails})-1; - } - } - return; } 1;