--- loncom/interface/loncommon.pm 2007/11/09 23:05:47 1.611 +++ loncom/interface/loncommon.pm 2007/12/21 05:19:04 1.627 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # a pile of common routines # -# $Id: loncommon.pm,v 1.611 2007/11/09 23:05:47 albertel Exp $ +# $Id: loncommon.pm,v 1.627 2007/12/21 05:19:04 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -1942,6 +1942,11 @@ sub authform_kerberos { if (defined($in{'curr_authtype'})) { if ($in{'curr_authtype'} eq 'krb') { $krbcheck = ' checked="on"'; + if (defined($in{'mode'})) { + if ($in{'mode'} eq 'modifyuser') { + $krbcheck = ''; + } + } if (defined($in{'curr_kerb_ver'})) { if ($in{'curr_krb_ver'} eq '5') { $check5 = ' checked="on"'; @@ -2039,6 +2044,11 @@ sub authform_internal{ if ($in{'curr_authtype'} eq 'int') { if ($can_assign{'int'}) { $intcheck = 'checked="on" '; + if (defined($in{'mode'})) { + if ($in{'mode'} eq 'modifyuser') { + $intcheck = ''; + } + } if (defined($in{'curr_autharg'})) { $intarg = $in{'curr_autharg'}; } @@ -2073,6 +2083,7 @@ sub authform_internal{ $result = &mt ('[_1] Internally authenticated (with initial password [_2])', ''.$autharg); + $result.="'; return $result; } @@ -2088,6 +2099,11 @@ sub authform_local{ if ($in{'curr_authtype'} eq 'loc') { if ($can_assign{'loc'}) { $loccheck = 'checked="on" '; + if (defined($in{'mode'})) { + if ($in{'mode'} eq 'modifyuser') { + $loccheck = ''; + } + } if (defined($in{'curr_autharg'})) { $locarg = $in{'curr_autharg'}; } @@ -2137,6 +2153,11 @@ sub authform_filesystem{ if ($in{'curr_authtype'} eq 'fsys') { if ($can_assign{'fsys'}) { $fsyscheck = 'checked="on" '; + if (defined($in{'mode'})) { + if ($in{'mode'} eq 'modifyuser') { + $fsyscheck = ''; + } + } } else { $result = &mt('Currently Filesystem Authenticated.'); return $result; @@ -4834,6 +4855,7 @@ table.LC_descriptive_input td.LC_descrip font-weight: bold; } div.LC_feedback_link { + clear: both; background: white; width: 100%; } @@ -5037,7 +5059,6 @@ div.LC_clear_float_footer { div.LC_grade_select_mode { - float: left; font-family: $sans; } div.LC_grade_select_mode div div { @@ -5097,13 +5118,22 @@ span.LC_grade_check_note { right: 1em; } +table.LC_scantron_action { + width: 100%; +} +table.LC_scantron_action tr th { + font: normal bold $sans; +} -div.LC_edit_problem_header { +div.LC_edit_problem_header, +div.LC_edit_problem_footer { font: normal medium $sans; margin: 2px; } div.LC_edit_problem_header, div.LC_edit_problem_header div, +div.LC_edit_problem_footer, +div.LC_edit_problem_footer div, div.LC_edit_problem_editxml_header, div.LC_edit_problem_editxml_header div { margin-top: 5px; @@ -5851,7 +5881,6 @@ sub get_course_users { my ($classlist,$keylist)=&Apache::loncoursedata::get_classlist($cdom,$cnum); my $now = time; foreach my $student (keys(%{$classlist})) { - my $status; my $match = 0; my $secmatch = 0; my $section = $$classlist{$student}[$idx{section}]; @@ -6138,24 +6167,24 @@ sub default_quota { my ($udom,$inststatus) = @_; my ($defquota,$settingstatus); my %quotahash = &Apache::lonnet::get_dom('configuration', - ['quota'],$udom); - if (ref($quotahash{'quota'}) eq 'HASH') { + ['quotas'],$udom); + if (ref($quotahash{'quotas'}) eq 'HASH') { if ($inststatus ne '') { my @statuses = split(/:/,$inststatus); foreach my $item (@statuses) { - if ($quotahash{'quota'}{$item} ne '') { + if ($quotahash{'quotas'}{$item} ne '') { if ($defquota eq '') { - $defquota = $quotahash{'quota'}{$item}; + $defquota = $quotahash{'quotas'}{$item}; $settingstatus = $item; - } elsif ($quotahash{'quota'}{$item} > $defquota) { - $defquota = $quotahash{'quota'}{$item}; + } elsif ($quotahash{'quotas'}{$item} > $defquota) { + $defquota = $quotahash{'quotas'}{$item}; $settingstatus = $item; } } } } if ($defquota eq '') { - $defquota = $quotahash{'quota'}{'default'}; + $defquota = $quotahash{'quotas'}{'default'}; $settingstatus = 'default'; } } else { @@ -6207,14 +6236,14 @@ sub get_secgrprole_info { } sub user_picker { - my ($dom,$srch,$forcenewuser,$caller) = @_; + my ($dom,$srch,$forcenewuser,$caller,$cancreate,$usertype) = @_; my $currdom = $dom; my %curr_selected = ( srchin => 'dom', srchby => 'lastname', ); my $srchterm; - if (ref($srch) eq 'HASH') { + if ((ref($srch) eq 'HASH') && ($env{'form.origform'} ne 'crtusername')) { if ($srch->{'srchby'} ne '') { $curr_selected{'srchby'} = $srch->{'srchby'}; } @@ -6301,7 +6330,16 @@ sub user_picker { if ($forcenewuser) { if (ref($srch) eq 'HASH') { if ($srch->{'srchby'} eq 'uname' && $srch->{'srchtype'} eq 'exact' && $srch->{'srchin'} eq 'dom' && $srch->{'srchdomain'} eq $env{'request.role.domain'}) { - $new_user_create = '

&"').'" onclick="javascript:setSearch(\'1\','.$caller.');" />

'; + if ($cancreate) { + $new_user_create = '

&"').'" onclick="javascript:setSearch(\'1\','.$caller.');" />

'; + } else { + my $helplink = ' href="javascript:helpMenu('."'display'".')"'; + my %usertypetext = ( + official => 'institutional', + unofficial => 'non-institutional', + ); + $new_user_create = '
'.&mt("You are not authorized to create new $usertypetext{$usertype} users in this domain.").' '.&mt('Contact the helpdesk for assistance.',$helplink).'

'; + } } } @@ -6430,57 +6468,156 @@ END_BLOCK return $output; } -sub username_rule_check { - my ($srch,$caller) = @_; - my ($response,@curr_rules,%inst_results,$rulematch); - my ($rules,$ruleorder) = &Apache::lonnet::inst_userrules($srch->{'srchdomain'}); - if (ref($srch) eq 'HASH') { - (my $inst_response,%inst_results) = - &Apache::lonnet::get_instuser($srch->{'srchdomain'}, - $srch->{'srchterm'}); - my %domconfig = &Apache::lonnet::get_dom('configuration', - ['usercreation'],$srch->{'srchdomain'}); - if (ref($domconfig{'usercreation'}) eq 'HASH') { - if (ref($domconfig{'usercreation'}{'username_rule'}) eq 'ARRAY') { - @curr_rules = @{$domconfig{'usercreation'}{'username_rule'}}; - } - } - if (@curr_rules > 0) { - my $domdesc = &Apache::lonnet::domain($srch->{'srchdomain'},'description'); - my $instuser_reqd; - my %rule_check = &Apache::lonnet::inst_rulecheck($srch->{'srchdomain'},$srch->{'srchterm'},\@curr_rules); - foreach my $rule (@curr_rules) { - if ($rule_check{$rule}) { - $rulematch = $rule; - if ($inst_response eq 'ok') { - if (keys(%inst_results) == 0) { - if ($caller eq 'new') { - $response = &mt('The username you chose matches the format of usernames defined for [_1], but the user does not exist in the institutional directory.',$domdesc).'
'.&mt("You must choose a username with a different format -- one that will not conflict with 'official' institutional usernames."); - } +sub user_rule_check { + my ($usershash,$checks,$alerts,$rulematch,$inst_results,$curr_rules,$got_rules) = @_; + my $response; + if (ref($usershash) eq 'HASH') { + foreach my $user (keys(%{$usershash})) { + my ($uname,$udom) = split(/:/,$user); + next if ($udom eq '' || $uname eq ''); + my ($id,$newuser); + if (ref($usershash->{$user}) eq 'HASH') { + $newuser = $usershash->{$user}->{'newuser'}; + $id = $usershash->{$user}->{'id'}; + } + my $inst_response; + if (ref($checks) eq 'HASH') { + if (defined($checks->{'username'})) { + ($inst_response,%{$inst_results->{$user}}) = + &Apache::lonnet::get_instuser($udom,$uname); + } elsif (defined($checks->{'id'})) { + ($inst_response,%{$inst_results->{$user}}) = + &Apache::lonnet::get_instuser($udom,undef,$id); + } + } else { + ($inst_response,%{$inst_results->{$user}}) = + &Apache::lonnet::get_instuser($udom,$uname); + return; + } + if (!$got_rules->{$udom}) { + my %domconfig = &Apache::lonnet::get_dom('configuration', + ['usercreation'],$udom); + if (ref($domconfig{'usercreation'}) eq 'HASH') { + foreach my $item ('username','id') { + if (ref($domconfig{'usercreation'}{$item.'_rule'}) eq 'ARRAY') { + $$curr_rules{$udom}{$item} = + $domconfig{'usercreation'}{$item.'_rule'}; } } - last; } + $got_rules->{$udom} = 1; } - if ($response) { - if ((ref($rules) eq 'HASH') && (ref($ruleorder) eq 'ARRAY')) { - if (@{$ruleorder} > 0) { - $response .= '
'.&mt('Usernames with the following format(s) may only be used for verified users at [_1]:',$domdesc).' '; } } } } - return ($response,$rulematch,$rules,%inst_results); + return; +} + +sub user_rule_formats { + my ($domain,$domdesc,$curr_rules,$check) = @_; + my %text = ( + 'username' => 'Usernames', + 'id' => 'IDs', + ); + my $output; + my ($rules,$ruleorder) = &Apache::lonnet::inst_userrules($domain,$check); + if ((ref($rules) eq 'HASH') && (ref($ruleorder) eq 'ARRAY')) { + if (@{$ruleorder} > 0) { + $output = '
'.&mt("$text{$check} with the following format(s) may only be used for verified users at [_1]:",$domdesc).' '; + } + } + return $output; +} + +sub instrule_disallow_msg { + my ($checkitem,$domdesc,$count,$mode) = @_; + my $response; + my %text = ( + item => 'username', + items => 'usernames', + match => 'matches', + do => 'does', + action => 'a username', + one => 'one', + ); + if ($count > 1) { + $text{'item'} = 'usernames'; + $text{'match'} ='match'; + $text{'do'} = 'do'; + $text{'action'} = 'usernames', + $text{'one'} = 'ones'; + } + if ($checkitem eq 'id') { + $text{'items'} = 'IDs'; + $text{'item'} = 'ID'; + $text{'action'} = 'an ID'; + if ($count > 1) { + $text{'item'} = 'IDs'; + $text{'action'} = 'IDs'; + } + } + $response = &mt("The $text{'item'} you chose $text{'match'} the format of $text{'items'} defined for [_1], but the $text{'item'} $text{'do'} not exist in the institutional directory.",$domdesc).'
'; + if ($mode eq 'upload') { + if ($checkitem eq 'username') { + $response .= &mt("You will need to modify your upload file so it will include $text{'action'} with a different format -- $text{'one'} that will not conflict with 'official' institutional $text{'items'}."); + } elsif ($checkitem eq 'id') { + $response .= &mt("Either upload a file which includes $text{'action'} with a different format -- $text{'one'} that will not conflict with 'official' institutional $text{'items'}, or when associating fields with data columns, omit an association for the ID/Student Number field."); + } + } else { + if ($checkitem eq 'username') { + $response .= &mt("You must choose $text{'action'} with a different format -- $text{'one'} that will not conflict with 'official' institutional $text{'items'}."); + } elsif ($checkitem eq 'id') { + $response .= &mt("You must either choose $text{'action'} with a different format -- $text{'one'} that will not conflict with 'official' institutional $text{'items'}, or leave the ID field blank."); + } + } + return $response; +} + +sub personal_data_fieldtitles { + my %fieldtitles = &Apache::lonlocal::texthash ( + id => 'Student/Employee ID', + permanentemail => 'E-mail address', + lastname => 'Last Name', + firstname => 'First Name', + middlename => 'Middle Name', + generation => 'Generation', + gen => 'Generation', + ); + return %fieldtitles; } =pod @@ -7541,6 +7678,76 @@ sub restore_settings { } } +####################################################### +####################################################### + +=pod + +=head1 Domain E-mail Routines + +=over 4 + +=item &build_recipient_list + +Build recipient lists for three types of e-mail: +(a) Error Reports, (b) Package Updates, (c) Help requests, generated by +lonerrorhandler.pm, CHECKRPMS and lonsupportreq.pm respectively. + +Inputs: +defmail (scalar - email address of default recipient), +mailing type (scalar - errormail, packagesmail, or helpdeskmail), +defdom (domain for which to retrieve configuration settings), +origmail (scalar - email address of recipient from loncapa.conf, +i.e., predates configuration by DC via domainprefs.pm + +Returns: comma separated list of addresses to which to send e-mail. + +=cut + +############################################################ +############################################################ +sub build_recipient_list { + my ($defmail,$mailing,$defdom,$origmail) = @_; + my @recipients; + my $otheremails; + my %domconfig = + &Apache::lonnet::get_dom('configuration',['contacts'],$defdom); + if (ref($domconfig{'contacts'}) eq 'HASH') { + if (ref($domconfig{'contacts'}{$mailing}) eq 'HASH') { + my @contacts = ('adminemail','supportemail'); + foreach my $item (@contacts) { + if ($domconfig{'contacts'}{$mailing}{$item}) { + my $addr = $domconfig{'contacts'}{$item}; + if (!grep(/^\Q$addr\E$/,@recipients)) { + push(@recipients,$addr); + } + } + $otheremails = $domconfig{'contacts'}{$mailing}{'others'}; + } + } + } elsif ($origmail ne '') { + push(@recipients,$origmail); + } + if ($defmail ne '') { + push(@recipients,$defmail); + } + if ($otheremails) { + my @others; + if ($otheremails =~ /,/) { + @others = split(/,/,$otheremails); + } else { + push(@others,$otheremails); + } + foreach my $addr (@others) { + if (!grep(/^\Q$addr\E$/,@recipients)) { + push(@recipients,$addr); + } + } + } + my $recipientlist = join(',',@recipients); + return $recipientlist; +} + ############################################################ ############################################################ @@ -7567,8 +7774,8 @@ sub commit_standardrole { my $result = &commit_studentrole(\$logmsg,$udom,$uname,$url,$three,$start,$end, $one,$two,$sec,$context); if (($result =~ /^error/) || ($result eq 'not_in_class') || - ($result eq 'unknown_course')) { - $output = "Error: $result\n"; + ($result eq 'unknown_course') || ($result eq 'refused')) { + $output = $logmsg.' '.&mt('Error: ').$result."\n"; } else { $output = $logmsg.$linefeed.&mt('Assigning').' '.$three.' in '.$url. ($start?', '.&mt('starting').' '.localtime($start):''). @@ -7597,7 +7804,7 @@ sub commit_standardrole { sub commit_studentrole { my ($logmsg,$udom,$uname,$url,$three,$start,$end,$one,$two,$sec,$context) = @_; - my ($result,$linefeed); + my ($result,$linefeed,$oldsecurl,$newsecurl); if ($context eq 'auto') { $linefeed = "\n"; } else { @@ -7617,6 +7824,7 @@ sub commit_studentrole { if ($oldsec) { $uurl.='/'.$oldsec; } + $oldsecurl = $uurl; $expire_role_result = &Apache::lonnet::assignrole($udom,$uname,$uurl,'st',time); $result = $expire_role_result; } @@ -7625,21 +7833,35 @@ sub commit_studentrole { $modify_section_result = &Apache::lonnet::modify_student_enrollment($udom,$uname,undef,undef,undef,undef,undef,$sec,$end,$start,'','',$cid); if ($modify_section_result =~ /^ok/) { if ($secchange == 1) { - $$logmsg .= "Section for $uname switched from old section: $oldsec to new section: $sec".$linefeed; + $$logmsg .= &mt('Section for [_1] switched from old section: [_2] to new section: [_3].',$uname,$oldsec,$sec).$linefeed; } elsif ($oldsec eq '-1') { - $$logmsg .= "New student role for $uname in section $sec in course $cid".$linefeed; + $$logmsg .= &mt('New student role for [_1] in section [_2] in course [_3].',$uname,$sec,$cid).$linefeed; } else { - $$logmsg .= "Student $uname assigned to unchanged section $sec in course $cid".$linefeed; + $$logmsg .= &mt('Student [_1] assigned to unchanged section [_2] in course [_3].',$uname,$sec,$cid).$linefeed; } } else { - $$logmsg .= "Error when attempting section change for $uname from old section $oldsec to new section: $sec in course $cid -error: $modify_section_result".$linefeed; + $$logmsg .= &mt('Error when attempting section change for [_1] from old section [_2] to new section: [_3] in course [_4] -error:',$uname,$oldsec,$sec,$cid).' '.$modify_section_result.$linefeed; } $result = $modify_section_result; } elsif ($secchange == 1) { - $$logmsg .= "Error when attempting to expire role for $uname in old section $oldsec in course $cid -error: $expire_role_result".$linefeed; + $$logmsg .= &mt('Error when attempting to expire role for [_1] in old section [_2] in course [_3] -error: ',$uname,$oldsec,$cid).' '.$expire_role_result.$linefeed; + if ($expire_role_result eq 'refused') { + my $newsecurl = '/'.$cid; + $newsecurl =~ s/\_/\//g; + if ($sec ne '') { + $newsecurl.='/'.$sec; + } + if (&Apache::lonnet::allowed('cst',$newsecurl) && !(&Apache::lonnet::allowed('cst',$oldsecurl))) { + if ($sec eq '') { + $$logmsg .= &mt('Although your current role has privileges to add students to section "[_1]", you do not have privileges to modify existing enrollments unaffiliated with any section.',$sec).$linefeed; + } else { + $$logmsg .= &mt('Although your current role has privileges to add students to section "[_1]", you do not have privileges to modify existing enrollments in other sections.',$sec).$linefeed; + } + } + } } } else { - $$logmsg .= "Incomplete course id defined. Addition of user $uname from domain $udom to course $one\_$two, section $sec not completed.$linefeed"; + $$logmsg .= &mt('Incomplete course id defined.').$linefeed.&mt('Addition of user [_1] from domain [_2] to course [_3], section [_4] not completed.',$uname,$udom,$one.'_'.$two,$sec).$linefeed; $result = "error: incomplete course id\n"; } return $result;