--- loncom/interface/lonuserutils.pm 2010/11/01 18:01:26 1.128 +++ loncom/interface/lonuserutils.pm 2012/10/04 13:41:10 1.143 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # Utility functions for managing LON-CAPA user accounts # -# $Id: lonuserutils.pm,v 1.128 2010/11/01 18:01:26 raeburn Exp $ +# $Id: lonuserutils.pm,v 1.143 2012/10/04 13:41:10 bisitz Exp $ # # Copyright Michigan State University Board of Trustees # @@ -47,8 +47,7 @@ sub modifystudent { # this one. If $csec is defined, drop them from all other sections of # this course and add them to section $csec my ($cnum,$cdom) = &get_course_identity($courseid); - my $extra = &Apache::lonnet::freeze_escape({'skipcheck' => 1}); - my %roles = &Apache::lonnet::dump('roles',$udom,$unam,'.',undef,$extra); + my %roles = &Apache::lonnet::dump('roles',$udom,$unam); my ($tmp) = keys(%roles); # Bail out if we were unable to get the students roles return "$1" if ($tmp =~ /^(con_lost|error|no_such_host)/i); @@ -534,6 +533,7 @@ END if (message!='') { message+='\\n'; } + message+='$alert{'section'}'; } if (foundemail==0) { if (message!='') { @@ -588,28 +588,43 @@ END ############################################################### sub upload_manager_javascript_forward_associate { my ($can_assign) = @_; - my $auth_update; + my ($auth_update,$numbuttons,$argreset); if (ref($can_assign) eq 'HASH') { - if (keys(%{$can_assign}) > 1) { + if ($can_assign->{'krb4'} || $can_assign->{'krb5'}) { + $argreset .= " vf.krbarg.value='';\n"; + $numbuttons ++ ; + } + if ($can_assign->{'int'}) { + $argreset .= " vf.intarg.value='';\n"; + $numbuttons ++; + } + if ($can_assign->{'loc'}) { + $argreset .= " vf.locarg.value='';\n"; + $numbuttons ++; + } + if (!$can_assign->{'int'}) { + my $warning = &mt('You may not specify an initial password for each user, as this is only available when new users use LON-CAPA internal authentication.\n'). + &mt('Your current role does not have rights to create users with that authentication type.'); + $auth_update = <<"END"; + // Currently the initial password field is only supported for internal auth + // (see bug 6368). + if (nw==9) { + eval('vf.f'+tf+'.selectedIndex=0;') + alert('$warning'); + } +END + } elsif ($numbuttons > 1) { $auth_update = <<"END"; // If we set the password, make the password form below correspond to // the new value. if (nw==9) { changed_radio('int',document.studentform); set_auth_radio_buttons('int',document.studentform); +$argreset + } + END } - if ($can_assign->{'krb4'} || $can_assign->{'krb5'}) { - $auth_update .= " vf.krbarg.value='';\n"; - } - if ($can_assign->{'int'}) { - $auth_update .= " vf.intarg.value='';\n"; - } - if ($can_assign->{'loc'}) { - $auth_update .= " vf.locarg.value='';\n"; - } - $auth_update .= " - }\n"; } return(< 1) { + if ($can_assign->{'krb4'} || $can_assign->{'krb5'}) { + $argreset .= " vf.krbarg.value='';\n"; + $numbuttons ++ ; + } + if ($can_assign->{'int'}) { + $argreset .= " vf.intarg.value='';\n"; + $numbuttons ++; + } + if ($can_assign->{'loc'}) { + $argreset .= " vf.locarg.value='';\n"; + $numbuttons ++; + } + if (!$can_assign->{'int'}) { + my $warning = &mt('You may not specify an initial password, as this is only available when new users use LON-CAPA internal authentication.\n'). + &mt('Your current role does not have rights to create users with that authentication type.'); + $auth_update = <<"END"; + // Currently the initial password field is only supported for internal auth + // (see bug 6368). + if (tf==8 && nw!=0) { + eval('vf.f'+tf+'.selectedIndex=0;') + alert('$warning'); + } +END + } elsif ($numbuttons > 1) { $auth_update = <<"END"; // initial password specified, pick internal authentication if (tf==8 && nw!=0) { changed_radio('int',document.studentform); set_auth_radio_buttons('int',document.studentform); +$argreset + } + END } - if ($can_assign->{'krb'}) { - $auth_update .= " vf.krbarg.value='';\n"; - } - if ($can_assign->{'int'}) { - $auth_update .= " vf.intarg.value='';\n"; - } - if ($can_assign->{'loc'}) { - $auth_update .= " vf.locarg.value='';\n"; - } - $auth_update .= " - }\n"; } + return(< 1}); my %rolehash=&Apache::lonnet::dump('roles'); foreach my $key (keys(%rolehash)) { if ($key=~/^rolesdef\_(\w+)$/) { @@ -1410,8 +1444,9 @@ sub print_userlist { if ($env{'form.Status'} !~ /^(Any|Expired|Active|Future)$/) { $env{'form.Status'} = 'Active'; } + my $onchange = "javascript:updateCols('Status');"; my $status_select = &Apache::lonhtmlcommon::StatusOptions - ($env{'form.Status'}); + ($env{'form.Status'},undef,undef,$onchange); if ($env{'form.showrole'} eq '') { if ($context eq 'course') { @@ -1444,12 +1479,12 @@ sub print_userlist { $r->print('
'."\n". ''); - $r->print("

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

'."\n"); if ($env{'form.action'} ne 'modifystudent') { my %lt=&Apache::lonlocal::texthash('csv' => "CSV", 'excel' => "Excel", 'html' => 'HTML'); - my $output_selector = ''; foreach my $outputformat ('html','csv','excel') { my $option = '
'. + &column_checkboxes($context,$mode,$formname). + '

'); if ($env{'form.phase'} eq '') { - $r->print('

'.&list_submit_button(&mt('Display List of Users')). - "\n

\n". + $r->print(&list_submit_button(&mt('Display List of Users'))."\n". '
'); return; } if (!(($context eq 'domain') && (($env{'form.roletype'} eq 'course') || ($env{'form.roletype'} eq 'community')))) { - $r->print( - "\n

\n" - .'

' - .&list_submit_button(&mt('Update Display')) - ."

\n" - ); + $r->print(&list_submit_button(&mt('Update Display'))."\n"); + } + + my @cols = &infocolumns($context,$mode); + if (!@cols) { + $r->print('
'. + &mt('No user information selected for display.').''. + ''."\n"); + return; } my ($indexhash,$keylist) = &make_keylist_array(); my (%userlist,%userinfo,$clearcoursepick); @@ -1531,7 +1571,7 @@ sub print_userlist { $r->print('
'.&mt('Searching').' ...
 
'); } } else { - $r->print('
'.&mt('Searching').' ...
 
'); + $r->print('
'.&mt('Searching').' ...
'); } $r->rflush(); if ($context eq 'course') { @@ -1651,21 +1691,23 @@ sub print_userlist { } } if (keys(%userlist) == 0) { + my $msg = ''; if ($context eq 'author') { - $r->print(&mt('There are no co-authors to display.')."\n"); + $msg = &mt('There are no co-authors to display.'); } elsif ($context eq 'domain') { if ($env{'form.roletype'} eq 'domain') { - $r->print(&mt('There are no users with domain roles to display.')."\n"); + $msg = &mt('There are no users with domain roles to display.'); } elsif ($env{'form.roletype'} eq 'author') { - $r->print(&mt('There are no authors or co-authors to display.')."\n"); + $msg = &mt('There are no authors or co-authors to display.'); } elsif ($env{'form.roletype'} eq 'course') { - $r->print(&mt('There are no course users to display')."\n"); + $msg = &mt('There are no course users to display'); } elsif ($env{'form.roletype'} eq 'community') { - $r->print(&mt('There are no community users to display')."\n"); + $msg = &mt('There are no community users to display'); } } elsif ($context eq 'course') { $r->print(&mt('There are no course users to display.')."\n"); } + $r->print('

'."\n") if $msg; } else { # Print out the available choices my $usercount; @@ -1677,7 +1719,7 @@ sub print_userlist { $permission,$env{'form.Status'},\%userlist,$keylist); } if (!$usercount) { - $r->print('
' + $r->print('
' .&mt('There are no users matching the search criteria.') .'' ); @@ -1685,6 +1727,7 @@ sub print_userlist { } $r->print(''); + return; } sub role_filter { @@ -1697,11 +1740,11 @@ sub role_filter { my ($role_select); if ($context eq 'domain') { $role_select = &domain_roles_select(); - $output = ''; + .'
'; } else { - $role_select = ''."\n". ''; my ($roletype,$crstype); @@ -1728,9 +1771,9 @@ sub role_filter { $role_select .= ''; } $role_select .= ''; - $output = ' '; + .''; } return $output; } @@ -1793,11 +1836,167 @@ sub section_group_filter { return $output; } +sub infocolumns { + my ($context,$mode) = @_; + my @cols; + if (($mode eq 'pickauthor') || ($mode eq 'autoenroll')) { + @cols = &get_cols_array($context,$mode); + } else { + my @posscols = &get_cols_array($context,$mode); + if ($env{'form.phase'} ne '') { + my @checkedcols = &Apache::loncommon::get_env_multiple('form.showcol'); + foreach my $col (@checkedcols) { + if (grep(/^$col$/,@posscols)) { + push(@cols,$col); + } + } + } else { + @cols = @posscols; + } + } + return @cols; +} + +sub get_cols_array { + my ($context,$mode) = @_; + my @cols; + if ($mode eq 'pickauthor') { + @cols = ('username','fullname','status','email'); + } else { + @cols = ('username','domain','id','fullname'); + if ($context eq 'course') { + push(@cols,'section'); + } + push(@cols,('start','end','role')); + if ($context eq 'domain') { + push (@cols,'extent'); + } + unless (($mode eq 'autoenroll') && ($env{'form.Status'} ne 'Any')) { + push(@cols,'status'); + } + if ($context eq 'course') { + push(@cols,'groups'); + } + push(@cols,'email'); + if (($context eq 'course') && ($mode ne 'autoenroll')) { + push(@cols,'lastlogin','clicker'); + } + if (($context eq 'course') && ($mode ne 'autoenroll') && + ($env{'course.'.$env{'request.course.id'}.'.internal.showphoto'})) { + push(@cols,'photos'); + } + } + return @cols; +} + +sub column_checkboxes { + my ($context,$mode,$formname) = @_; + my @cols = &get_cols_array($context,$mode); + my @showncols = &Apache::loncommon::get_env_multiple('form.showcol'); + my (%disabledchk,%unchecked); + if ($env{'form.phase'} eq '') { + $disabledchk{'status'} = 1; + if ($context eq 'course') { + $disabledchk{'role'} = 1; + $unchecked{'photo'} = 1; + } + $unchecked{'clicker'} = 1; + $unchecked{'start'} = 1; + $unchecked{'end'} = 1; + } else { + if ($env{'form.Status'} ne 'Any') { + $disabledchk{'status'} = 1; + } + if ($env{'form.showrole'} ne 'Any') { + $disabledchk{'role'} = 1; + } + } + my $numposs = scalar(@cols); + my $numinrow = 8; + my %lt = &get_column_names($context); + my $output = '

'.&mt('Information to show').''."\n".''. + ''. + (' 'x3). + ''. + ''; + + for (my $i=0; $i<$numposs; $i++) { + my $rem = $i%($numinrow); + if ($rem == 0) { + if ($i > 0) { + $output .= ''; + } + $output .= ''; + } + my $checked; + if ($env{'form.phase'} eq '') { + $checked = ' checked="checked"'; + if ($unchecked{$cols[$i]}) { + $checked = ''; + } + if ($disabledchk{$cols[$i]}) { + $checked = ' disabled="disabled"'; + } + } elsif (grep(/^\Q$cols[$i]\E$/,@showncols)) { + $checked = ' checked="checked"'; + } elsif ($disabledchk{$cols[$i]}) { + $checked = ' disabled="disabled"'; + } + if ($i == $numposs-1) { + my $colsleft = $numinrow-$rem; + if ($colsleft > 1) { + $output .= ''; + + } + $output .= '
'; + } else { + $output .= ''; + } + } else { + $output .= ''; + } + $output .= '
'; + return $output; +} + sub list_submit_button { my ($text) = @_; return ''; } +sub get_column_names { + my ($context) = @_; + my %lt = &Apache::lonlocal::texthash( + 'username' => "username", + 'domain' => "domain", + 'id' => 'ID', + 'fullname' => "name", + 'section' => "section", + 'groups' => "active groups", + 'start' => "start date", + 'end' => "end date", + 'status' => "status", + 'role' => "role", + 'type' => "enroll type/action", + 'email' => "e-mail address", + 'photo' => "photo", + 'lastlogin' => "last login", + 'extent' => "extent", + 'ca' => "check all", + 'ua' => "uncheck all", + 'clicker' => "clicker-ID", + ); + if ($context eq 'domain' && $env{'form.roletype'} eq 'course') { + $lt{'extent'} = &mt('Course(s): description, section(s), status'); + } elsif ($context eq 'domain' && $env{'form.roletype'} eq 'community') { + $lt{'extent'} = &mt('Communities: description, section(s), status'); + } elsif ($context eq 'author') { + $lt{'extent'} = &mt('Author'); + } + return %lt; +} + sub gather_userinfo { my ($context,$format,$userlist,$indexhash,$userinfo,$rolehash,$permission) = @_; my $viewablesec; @@ -2161,7 +2360,7 @@ sub show_users_list { $sortby = 'username'; } my $setting = $env{'form.roletype'}; - my ($cid,$cdom,$cnum,$classgroups,$displayphotos,$displayclickers,$crstype); + my ($cid,$cdom,$cnum,$classgroups,$crstype); if ($context eq 'course') { $cid = $env{'request.course.id'}; $crstype = &Apache::loncommon::course_type(); @@ -2171,14 +2370,6 @@ sub show_users_list { if ($mode eq 'autoenroll') { $env{'form.showrole'} = 'st'; } else { - if (! exists($env{'form.displayphotos'})) { - $env{'form.displayphotos'} = 'off'; - } - $displayphotos = $env{'form.displayphotos'}; - if (! exists($env{'form.displayclickers'})) { - $env{'form.displayclickers'} = 'off'; - } - $displayclickers = $env{'form.displayclickers'}; if ($env{'course.'.$cid.'.internal.showphoto'}) { $r->print(' '); } - $r->print(< - -END } } elsif ($context eq 'domain') { if ($setting eq 'community') { @@ -2207,14 +2394,12 @@ END } } if ($mode ne 'autoenroll' && $mode ne 'pickauthor') { - my $check_uncheck_js = &Apache::loncommon::check_uncheck_jscript(); my $date_sec_selector = &date_section_javascript($context,$setting,$statusmode); my $verify_action_js = &bulkaction_javascript($formname); $r->print(< // print(< END - - my %lt=&Apache::lonlocal::texthash( - 'username' => "username", - 'domain' => "domain", - 'id' => 'ID', - 'fullname' => "name", - 'section' => "section", - 'groups' => "active groups", - 'start' => "start date", - 'end' => "end date", - 'status' => "status", - 'role' => "role", - 'type' => "enroll type/action", - 'email' => "e-mail address", - 'photo' => "photo", - 'extent' => "extent", + my @cols = &infocolumns($context,$mode); + my %coltxt = &get_column_names($context); + my %acttxt = &Apache::lonlocal::texthash( 'pr' => "Proceed", - 'ca' => "check all", - 'ua' => "uncheck all", 'ac' => "Action to take for selected users", 'link' => "Behavior of clickable username link for each user", 'aboutme' => "Display a user's personal information page", 'owin' => "Open in a new window", 'modify' => "Modify a user's information", 'track' => "View a user's recent activity", - 'clicker' => "Clicker-ID", ); - if ($context eq 'domain' && $env{'form.roletype'} eq 'course') { - $lt{'extent'} = &mt('Course(s): description, section(s), status'); - } elsif ($context eq 'domain' && $env{'form.roletype'} eq 'community') { - $lt{'extent'} = &mt('Communities: description, section(s), status'); - } elsif ($context eq 'author') { - $lt{'extent'} = &mt('Author'); - } - my @cols; - if ($mode eq 'pickauthor') { - @cols = ('username','fullname','status','email'); - } else { - @cols = ('username','domain','id','fullname'); - if ($context eq 'course') { - push(@cols,'section'); - } - if (!($context eq 'domain' && ($env{'form.roletype'} eq 'course') - && ($env{'form.roletype'} eq 'community'))) { - push(@cols,('start','end')); - } - if ($env{'form.showrole'} eq 'Any' || $env{'form.showrole'} eq 'cr') { - push(@cols,'role'); - } - if ($context eq 'domain' && ($env{'form.roletype'} eq 'author' || - $env{'form.roletype'} eq 'course' || - $env{'form.roletype'} eq 'community')) { - push (@cols,'extent'); - } - if (($statusmode eq 'Any') && - (!($context eq 'domain' && (($env{'form.roletype'} eq 'course') - || ($env{'form.roletype'} eq 'community'))))) { - push(@cols,'status'); - } - if ($context eq 'course') { - push(@cols,'groups'); - } - push(@cols,'email'); - } - + my %lt = (%coltxt,%acttxt); my $rolefilter = $env{'form.showrole'}; if ($env{'form.showrole'} eq 'cr') { $rolefilter = &mt('custom'); @@ -2347,7 +2479,7 @@ END if ($mode ne 'autoenroll') { $results_description = &results_header_row($rolefilter,$statusmode, $context,$permission,$mode,$crstype); - $r->print(''.$results_description.'

'); + $r->print(''.$results_description.'
'); } my ($output,$actionselect,%canchange,%canchangesec); if ($mode eq 'html' || $mode eq 'view' || $mode eq 'autoenroll' || $mode eq 'pickauthor') { @@ -2409,6 +2541,12 @@ END if (&Apache::lonnet::allowed('c'.$role,$env{'request.course.id'}.'/'.$env{'request.course.sec'})) { $canchangesec{$role} = $env{'request.course.sec'}; } + } elsif ((($role eq 'co') && ($crstype eq 'Community')) || + (($role eq 'cc') && ($crstype eq 'Course'))) { + if (&is_courseowner($env{'request.course.id'}, + $env{'course.'.$env{'request.course.id'}.'.internal.courseowner'})) { + $canchange{$role} = 1; + } } } } @@ -2443,7 +2581,7 @@ END } $output .= ''.$lt{'owin'}.''; } - $output .= "\n".''."\n". + $output .= "\n".'
'."\n". &Apache::loncommon::start_data_table(). &Apache::loncommon::start_data_table_header_row(); if ($mode eq 'autoenroll') { @@ -2460,42 +2598,6 @@ END $output .= "$lt{$item}\n"; } my %role_types = &role_type_names(); - if ($context eq 'course' && $mode ne 'autoenroll') { - if ($env{'form.showrole'} eq 'st' || $env{'form.showrole'} eq 'Any') { - # Clicker display on or off? - my %clicker_options = ( - 'on' => 'Show', - 'off' => 'Hide', - ); - my $clickerchg = 'on'; - if ($displayclickers eq 'on') { - $clickerchg = 'off'; - } - $output .= ' '."\n".' ' - .&mt('[_1]'.$clicker_options{$clickerchg}.'[_2] clicker id' - ,'' - ,'') - ."\n".' '."\n"; - - # Photo display on or off? - if ($env{'course.'.$env{'request.course.id'}.'.internal.showphoto'}) { - my %photo_options = &Apache::lonlocal::texthash( - 'on' => 'Show', - 'off' => 'Hide', - ); - my $photochg = 'on'; - if ($displayphotos eq 'on') { - $photochg = 'off'; - } - $output .= ' '."\n".' '. - ''. - $photo_options{$photochg}.' '.$lt{'photo'}."\n". - ' '."\n"; - } - } - } $output .= &Apache::loncommon::end_data_table_header_row(); # Done with the HTML header line } elsif ($mode eq 'csv') { @@ -2516,14 +2618,12 @@ END $CSVfile = undef; } # - push @cols,'clicker'; # Write headers and data to file print $CSVfile '"'.$results_description.'"'."\n"; print $CSVfile '"'.join('","',map { &Apache::loncommon::csv_translate($lt{$_}) } (@cols))."\"\n"; } elsif ($mode eq 'excel') { - push @cols,'clicker'; # Create the excel spreadsheet ($excel_workbook,$excel_filename,$format) = &Apache::loncommon::create_workbook($r); @@ -2559,6 +2659,11 @@ END Future => 'Future', Expired => 'Expired', ); + # If this is for a single course get last course "log-in". + my %crslogins; + if ($context eq 'course') { + %crslogins=&Apache::lonnet::dump('nohist_crslastlogin',$cdom,$cnum); + } # Get groups, role, permanent e-mail so we can sort on them if # necessary. foreach my $user (keys(%{$userlist})) { @@ -2642,7 +2747,7 @@ END } } if ($env{'course.'.$env{'request.course.id'}.'.internal.showphoto'}) { - if (($displayphotos eq 'on') && ($role eq 'st')) { + if ((grep/^photo$/,@cols) && ($role eq 'st')) { $userlist->{$user}->[$index{'photo'}] = &Apache::lonnet::retrievestudentphoto($udom,$uname,'jpg'); $userlist->{$user}->[$index{'thumbnail'}] = @@ -2695,15 +2800,23 @@ END $in{'clicker'} = $clickers; my $role = $in{'role'}; $in{'role'}=&Apache::lonnet::plaintext($sdata->[$index{'role'}],$crstype); - if (! defined($in{'start'}) || $in{'start'} == 0) { - $in{'start'} = &mt('none'); - } else { - $in{'start'} = &Apache::lonlocal::locallocaltime($in{'start'}); + unless ($mode eq 'excel') { + if (! defined($in{'start'}) || $in{'start'} == 0) { + $in{'start'} = &mt('none'); + } else { + $in{'start'} = &Apache::lonlocal::locallocaltime($in{'start'}); + } + if (! defined($in{'end'}) || $in{'end'} == 0) { + $in{'end'} = &mt('none'); + } else { + $in{'end'} = &Apache::lonlocal::locallocaltime($in{'end'}); + } } - if (! defined($in{'end'}) || $in{'end'} == 0) { - $in{'end'} = &mt('none'); - } else { - $in{'end'} = &Apache::lonlocal::locallocaltime($in{'end'}); + if ($context eq 'course') { + my $lastlogin = $crslogins{$in{'username'}.':'.$in{'domain'}.':'.$in{'section'}.':'.$role}; + if ($lastlogin ne '') { + $in{'lastlogin'} = &Apache::lonlocal::locallocaltime($lastlogin); + } } if ($mode eq 'view' || $mode eq 'html' || $mode eq 'autoenroll' || $mode eq 'pickauthor') { $r->print(&Apache::loncommon::start_data_table_row()); @@ -2749,17 +2862,26 @@ END if ($showcheckbox) { $checkval = $user; if ($context eq 'course') { - if ($role eq 'st') { - $checkval .= ':st'; - } - $checkval .= ':'.$in{'section'}; - if ($role eq 'st') { - $checkval .= ':'.$in{'type'}.':'. - $in{'lockedtype'}; - } + if (($role eq 'co' || $role eq 'cc') && + ($user =~ /^\Q$env{'user.name'}:$env{'user.domain'}:$role\E/)) { + $showcheckbox = 0; + } else { + if ($role eq 'st') { + $checkval .= ':st'; + } + $checkval .= ':'.$in{'section'}; + if ($role eq 'st') { + $checkval .= ':'.$in{'type'}.':'. + $in{'lockedtype'}; + } + } + } + if ($showcheckbox) { + $r->print(''); + } else { + $r->print(' '); } - $r->print(''); } else { $r->print(' '); } @@ -2778,43 +2900,34 @@ END $showitem = $ltstatus{$in{$item}}; } $r->print(''.$showitem.''."\n"); - } else { - $r->print(''.$in{$item}.''."\n"); - } - } - if (($context eq 'course') && ($mode ne 'autoenroll')) { - if ($env{'form.showrole'} eq 'st' || $env{'form.showrole'} eq 'Any') { - if ($displayclickers eq 'on') { - my $clickers = + } elsif ($item eq 'photo') { + if (($context eq 'course') && ($mode ne 'autoenroll') && + ($env{'course.'.$env{'request.course.id'}.'.internal.showphoto'})) { + if ($role eq 'st') { + $r->print(''); + } else { + $r->print(' '); + } + } + } elsif ($item eq 'clicker') { + if (($context eq 'course') && ($mode ne 'autoenroll')) { + if ($env{'form.showrole'} eq 'st' || $env{'form.showrole'} eq 'Any') { + my $clickers = (&Apache::lonnet::userenvironment($in{'domain'},$in{'username'},'clickers'))[1]; - if ($clickers!~/\w/) { $clickers='-'; } - $r->print(''.$clickers.''); - } else { - $r->print('   '); - } - if ($env{'course.'.$env{'request.course.id'}.'.internal.showphoto'}) { - if ($displayphotos eq 'on' && $role eq 'st' && $in{'photo'} ne '') { - $r->print(' '); + if ($clickers!~/\w/) { $clickers='-'; } + $r->print(''.$clickers.''); } else { - $r->print('   '); - } - } + $r->print(' '."\n"); + } + } + } else { + $r->print(''.$in{$item}.''."\n"); } } $r->print(&Apache::loncommon::end_data_table_row()); } elsif ($mode eq 'csv') { next if (! defined($CSVfile)); # no need to bother with $linkto - if (! defined($in{'start'}) || $in{'start'} == 0) { - $in{'start'} = &mt('none'); - } else { - $in{'start'} = &Apache::lonlocal::locallocaltime($in{'start'}); - } - if (! defined($in{'end'}) || $in{'end'} == 0) { - $in{'end'} = &mt('none'); - } else { - $in{'end'} = &Apache::lonlocal::locallocaltime($in{'end'}); - } my @line = (); foreach my $item (@cols) { push @line,&Apache::loncommon::csv_translate($in{$item}); @@ -2824,9 +2937,9 @@ END my $col = 0; foreach my $item (@cols) { if ($item eq 'start' || $item eq 'end') { - if (defined($item) && $item != 0) { + if ((defined($in{$item})) && ($in{$item} != 0)) { $excel_sheet->write($row,$col++, - &Apache::lonstathelpers::calc_serial($in{item}), + &Apache::lonstathelpers::calc_serial($in{$item}), $format->{'date'}); } else { $excel_sheet->write($row,$col++,'none'); @@ -3014,15 +3127,20 @@ sub select_actions { } if ($context eq 'course') { if ($env{'form.showrole'} ne 'Any') { - if (!&Apache::lonnet::allowed('c'.$env{'form.showrole'}, - $env{'request.course.id'})) { - if ($env{'request.course.sec'} eq '') { - return; - } else { - if (!&Apache::lonnet::allowed('c'.$env{'form.showrole'},$env{'request.course.id'}.'/'.$env{'request.course.sec'})) { - return; - } - } + my $showactions; + if (&Apache::lonnet::allowed('c'.$env{'form.showrole'}, + $env{'request.course.id'})) { + $showactions = 1; + } elsif ($env{'request.course.sec'} ne '') { + if (&Apache::lonnet::allowed('c'.$env{'form.showrole'},$env{'request.course.id'}.'/'.$env{'request.course.sec'})) { + $showactions = 1; + } + } + unless ($showactions) { + unless (&is_courseowner($env{'request.course.id'}, + $env{'course.'.$env{'request.course.id'}.'.internal.courseowner'})) { + return; + } } } } @@ -3548,11 +3666,13 @@ END } } if (!$studentcount) { + my $msg = ''; if ($crstype eq 'Community') { - $r->print(&mt('There are no members to drop.')); + $msg = &mt('There are no members to drop.'); } else { - $r->print(&mt('There are no students to drop.')); + $msg = &mt('There are no students to drop.'); } + $r->print('

'.$msg.'

'); return; } my ($classgroups) = &Apache::loncoursedata::get_group_memberships( @@ -3966,7 +4086,8 @@ sub upfile_drop_add { official => 'Institutional', unofficial => 'Non-institutional', ); - map { $cancreate{$_} = &can_create_user($domain,$context,$_); } keys(%longtypes); + my $newuserdom = $env{'request.role.domain'}; + map { $cancreate{$_} = &can_create_user($newuserdom,$context,$_); } keys(%longtypes); # Get new users list foreach my $line (@userdata) { my @secs; @@ -4006,6 +4127,7 @@ sub upfile_drop_add { $nowhitespace); next; } else { + $entries{$fields{'domain'}} =~ s/^\s+|\s+$//g; if ($entries{$fields{'domain'}} ne &LONCAPA::clean_domain($entries{$fields{'domain'}})) { $r->print('
'. ''.$entries{$fields{'domain'}}. @@ -4064,6 +4186,7 @@ sub upfile_drop_add { # determine email address my $email=''; if (defined($fields{'email'})) { + $entries{$fields{'email'}} =~ s/^\s+|\s+$//g; if (defined($entries{$fields{'email'}})) { $email=$entries{$fields{'email'}}; unless ($email=~/^[^\@]+\@[^\@]+$/) { $email=''; } @@ -4110,7 +4233,7 @@ sub upfile_drop_add { $role = $defaultrole; } # Clean up whitespace - foreach (\$id,\$fname,\$mname,\$lname,\$gen) { + foreach (\$id,\$fname,\$mname,\$lname,\$gen,\$inststatus) { $$_ =~ s/(\s+$|^\s+)//g; } # check against rules @@ -4119,25 +4242,33 @@ sub upfile_drop_add { my (%rulematch,%inst_results,%idinst_results); my $uhome=&Apache::lonnet::homeserver($username,$userdomain); if ($uhome eq 'no_host') { - if ($userdomain ne $domain) { - $r->print('
'. - &mt('[_1]: The domain specified ([_2]) is different to that of the course.', - ''.$username.'',$userdomain).'
'. - &mt('The user does not already exist, and you may not create a new user in a different domain.')); + if ($userdomain ne $newuserdom) { + if ($context eq 'course') { + $r->print('
'. + &mt('[_1]: The domain specified ([_2]) is different to that of the course.', + ''.$username.'',$userdomain).'
'); + } elsif ($context eq 'author') { + $r->print(&mt('[_1]: The domain specified ([_2]) is different to that of the author.', + ''.$username.'',$userdomain).'
'); + } else { + $r->print(&mt('[_1]: The domain specified ([_2]) is different to that of your current role.', + ''.$username.'',$userdomain).'
'); + } + $r->print(&mt('The user does not already exist, and you may not create a new user in a different domain.')); next; } $checkid = 1; $newuser = 1; - my $user = $username.':'.$domain; + my $user = $username.':'.$newuserdom; my $checkhash; my $checks = { 'username' => 1 }; - $checkhash->{$username.':'.$domain} = { 'newuser' => 1, }; + $checkhash->{$username.':'.$newuserdom} = { 'newuser' => 1, }; &Apache::loncommon::user_rule_check($checkhash,$checks, \%alerts,\%rulematch,\%inst_results,\%curr_rules, \%got_rules); if (ref($alerts{'username'}) eq 'HASH') { - if (ref($alerts{'username'}{$domain}) eq 'HASH') { - if ($alerts{'username'}{$domain}{$username}) { + if (ref($alerts{'username'}{$newuserdom}) eq 'HASH') { + if ($alerts{'username'}{$newuserdom}{$username}) { $r->print('
'. &mt('[_1]: matches the username format at your institution, but is not known to your directory service.',''.$username.'').'
'. &mt('Consequently, the user was not created.')); @@ -4154,7 +4285,7 @@ sub upfile_drop_add { unless ($cancreate{$usertype}) { my $showtype = $longtypes{$usertype}; $r->print('
'. - &mt("[_1]: The user does not exist, and you are not permitted to create users of type: $showtype.",''.$username.'')); + &mt('[_1]: The user does not exist, and you are not permitted to create users of type: [_2].',''.$username.'',$showtype)); next; } } else { @@ -4332,7 +4463,7 @@ sub upfile_drop_add { if (! defined($classlist)) { $r->print('
'. ''. - &mt('There are no students with current/future access to the course.'). + '

'.&mt('There are no students with current/future access to the course.').'

'. '
'."\n"); } elsif (ref($classlist) eq 'HASH') { # Remove the students we just added from the list of students. @@ -4456,11 +4587,13 @@ sub print_drop_menu { '
'."\n"); my $classlist = &Apache::loncoursedata::get_classlist(); if (! defined($classlist)) { + my $msg = ''; if ($crstype eq 'Community') { - $r->print(&mt('There are no members currently enrolled.')."\n"); + $msg = &mt('There are no members currently enrolled.'); } else { - $r->print(&mt('There are no students currently enrolled.')."\n"); + $msg = &mt('There are no students currently enrolled.'); } + $r->print('

'.$msg."

\n"); } else { &show_drop_list($r,$classlist,'nosort',$permission,$crstype); } @@ -5235,18 +5368,40 @@ sub can_modify_userinfo { } sub check_usertype { - my ($dom,$uname,$rules) = @_; + my ($dom,$uname,$rules,$curr_rules,$got_rules) = @_; my $usertype; - if (ref($rules) eq 'HASH') { - my @user_rules = keys(%{$rules}); - if (@user_rules > 0) { - my %rule_check = &Apache::lonnet::inst_rulecheck($dom,$uname,undef,'username',\@user_rules); - if (keys(%rule_check) > 0) { - $usertype = 'unofficial'; - foreach my $item (keys(%rule_check)) { - if ($rule_check{$item}) { - $usertype = 'official'; - last; + if ((ref($got_rules) eq 'HASH') && (ref($curr_rules) eq 'HASH')) { + if (!$got_rules->{$dom}) { + my %domconfig = &Apache::lonnet::get_dom('configuration', + ['usercreation'],$dom); + if (ref($domconfig{'usercreation'}) eq 'HASH') { + foreach my $item ('username','id') { + if (ref($domconfig{'usercreation'}{$item.'_rule'}) eq 'ARRAY') { + $curr_rules->{$dom}{$item} = + $domconfig{'usercreation'}{$item.'_rule'}; + } + } + } + $got_rules->{$dom} = 1; + } + if (ref($rules) eq 'HASH') { + my @user_rules; + if (ref($curr_rules->{$dom}{'username'}) eq 'ARRAY') { + foreach my $rule (keys(%{$rules})) { + if (grep(/^\Q$rule\E/,@{$curr_rules->{$dom}{'username'}})) { + push(@user_rules,$rule); + } + } + } + if (@user_rules > 0) { + my %rule_check = &Apache::lonnet::inst_rulecheck($dom,$uname,undef,'username',\@user_rules); + if (keys(%rule_check) > 0) { + $usertype = 'unofficial'; + foreach my $item (keys(%rule_check)) { + if ($rule_check{$item}) { + $usertype = 'official'; + last; + } } } } @@ -5622,5 +5777,20 @@ sub authcheck_alerts { return %alerts; } +sub is_courseowner { + my ($thiscourse,$courseowner) = @_; + if ($courseowner eq '') { + if ($env{'request.course.id'} eq $thiscourse) { + $courseowner = $env{'course.'.$env{'request.course.id'}.'.internal.courseowner'}; + } + } + if ($courseowner ne '') { + if ($courseowner eq $env{'user.name'}.':'.$env{'user.domain'}) { + return 1; + } + } + return; +} + 1; 500 Internal Server Error

Internal Server Error

The server encountered an internal error or misconfiguration and was unable to complete your request.

Please contact the server administrator at root@localhost to inform them of the time this error occurred, and the actions you performed just before this error.

More information about this error may be available in the server error log.