[LON-CAPA-cvs] cvs: loncom /linterface lonuserutils.pm

Stuart Peter Raeburn raeburn <lon-capa-cvs-allow@mail.lon-capa.org>
Tue, 06 Nov 2007 11:25:10 -0500


raeburn		Mon Nov 5 11:39:19 2007 EDT
   Modified files:
   /loncom/interface	lonuserutils.pm 

   Log:
Bug 5422
More comprehensive listing of LON-CAPA users.  Available to Domain 
Coordinators, Authors and Course Coordinators. Lists displayable in HTML, 
CSV or Excel formats.
 - filter by status and role.
 - DCs can specify a subset of courses for display of course roles. 

lonuserutils.pm
 - Elimination of &domain_form() -- generates linked selectboxes for domain 
and server selection -- no longer required (as new users can now only be 
created in the domain of the user's current role).
 - Added &domain_roles_select() - used for linked role type and role 
selection boxes for DC, when displaying user roles.
 - Display of active advanced roles when viewing course classlist eliminated
 - replaced with selectable advanced roles in role filter for user lists. 


 --- loncom/interface/lonuserutils.pm	2007/10/22 22:16:38	1.1
+++ loncom/interface/lonuserutils.pm	2007/11/06 04:39:19	1.2
@@ -1,7 +1,7 @@
# The LearningOnline Network with CAPA
# Utility functions for managing LON-CAPA user accounts
#
 -# $Id: lonuserutils.pm,v 1.1 2007/10/22 22:16:38 raeburn Exp $
+# $Id: lonuserutils.pm,v 1.2 2007/11/06 04:39:19 raeburn Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -124,32 +124,50 @@ sub modifyuserrole { 

###############################################################
###############################################################
 -# build a domain and server selection form
 -sub domain_form {
 -    my ($defdom) = @_;
 -    # Set up domain and server selection forms
+# build a role type and role selection form
+sub domain_roles_select {
+    # Set up the role type and role selection boxes when in
+    # domain context
+    #
+    # Role types
+    my @roletypes = ('domain','construction_space','course');
+    my %lt = &role_type_names();
    #
 -    # Get the domains
 -    my @domains = &Apache::lonnet::all_domains();
    # build up the menu information to be passed to
    # &Apache::loncommon::linked_select_forms
    my %select_menus;
 -    foreach my $dom (@domains) {
+    if ($env{'form.roletype'} eq '') {
+        $env{'form.roletype'} = 'domain';
+    }
+    foreach my $roletype (@roletypes) {
        # set up the text for this domain
 -        $select_menus{$dom}->{'text'}= $dom;
+        $select_menus{$roletype}->{'text'}= $lt{$roletype};
        # we want a choice of 'default' as the default in the second menu
 -        $select_menus{$dom}->{'default'}= 'default';
 -        $select_menus{$dom}->{'select2'}->{'default'} = 'default';
+        if ($env{'form.roletype'} ne '') {
+            $select_menus{$roletype}->{'default'} = $env{'form.showrole'};
+        } else {
+            $select_menus{$roletype}->{'default'} = 'Any';
+        }
        # Now build up the other items in the second menu
 -        my %servers = &Apache::lonnet::get_servers($dom,'library');
 -        foreach my $server (keys(%servers)) {
 -            $select_menus{$dom}->{'select2'}->{$server}
 -                                            = "$server $servers{$server}";
+        my @roles;
+        if ($roletype eq 'domain') {
+            @roles = &domain_roles();
+        } elsif ($roletype eq 'construction_space') {
+            @roles = &construction_space_roles();
+        } else {
+            @roles = &course_roles('domain');
        }
+        my $order = ['Any',@roles];
+        $select_menus{$roletype}->{'order'} = $order;
+        foreach my $role (@roles) {
+            $select_menus{$roletype}->{'select2'}->{$role} =
+                          &Apache::lonnet::plaintext($role);
+        }
+        $select_menus{$roletype}->{'select2'}->{'Any'} = &mt('Any');
    }
 -    my $result  = &Apache::loncommon::linked_select_forms
 -        ('studentform',' with home server ',$defdom,
 -         'lcdomain','lcserver',\%select_menus);
+    my $result = &Apache::loncommon::linked_select_forms
+        ('studentform',('&nbsp;'x3).&mt('Role: '),$env{'form.roletype'},
+         
'roletype','showrole',\%select_menus,['domain','construction_space','course' 
]);
    return $result;
} 

@@ -616,7 +634,7 @@ sub print_upload_manager_footer {
                &mt('Role and/or section for users without one in the 
uploaded file.');
    }
    $Str .= '<br /><br />';
 -    my ($options,$cb_script,$coursepick) = 
&default_role_selector($context);
+    my ($options,$cb_script,$coursepick) = 
&default_role_selector($context,'defaultrole',1);
    if ($context eq 'domain') {
        $Str .= '<span class="LC_role_level">'.&mt('Domain 
Level').'</span><br />'.$options.'<br /><br /><span 
class="LC_role_level">'.&mt('Course Level').'</span><br 
/>'.$cb_script.$coursepick;
    } else {
@@ -847,7 +865,7 @@ sub make_dates_default {
} 

sub default_role_selector {
 -    my ($context) = @_;
+    my ($context,$checkpriv) = @_;
    my %customroles;
    my ($options,$coursepick,$cb_jscript);
    if ($context ne 'construction_space') {
@@ -863,15 +881,15 @@ sub default_role_selector {
    $options = '<select name="defaultrole">'."\n".
               ' <option value="">'.&mt('Please select').'</option>'."\n";
    if ($context eq 'course') {
 -        $options .= &default_course_roles($context,%customroles);
+        $options .= 
&default_course_roles($context,$checkpriv,%customroles);
    } elsif ($context eq 'construction_space') {
 -        my @roles = &construction_space_roles();
+        my @roles = &construction_space_roles($checkpriv);
        foreach my $role (@roles) {
           my $plrole=&Apache::lonnet::plaintext($role);
           $options .= '  <option 
value="'.$role.'">'.$plrole.'</option>'."\n";
        }
    } elsif ($context eq 'domain') {
 -        my @roles = &domain_roles();
+        my @roles = &domain_roles($checkpriv);
        foreach my $role (@roles) {
           my $plrole=&Apache::lonnet::plaintext($role);
           $options .= '  <option value="'.$role.'">'.$plrole.'</option>';
@@ -888,7 +906,7 @@ sub default_role_selector {
                      &Apache::loncommon::start_data_table_row()."\n".
                      '<td><input type="text" name="defaultdesc" value="" 
onFocus="this.blur();opencrsbrowser('."'studentform','defcourse','defdomain' 
,'coursedesc',''".')" /></td>'."\n".
                      '<td><select name="courserole">'."\n".
 -                      &default_course_roles($context,%customroles)."\n".
+                      
&default_course_roles($context,$checkpriv,%customroles)."\n".
                      '</select></td><td>'.
                      '<table class="LC_createuser">'.
                      '<tr class="LC_section_row"><td valign"top">'.
@@ -910,14 +928,15 @@ sub default_role_selector {
} 

sub default_course_roles {
 -    my ($context,%customroles) = @_;
+    my ($context,$checkpriv,%customroles) = @_;
    my $output;
 -    my @roles = &course_roles($context);
+    my @roles = &course_roles($context,$checkpriv);
    foreach my $role (@roles) {
        my $plrole=&Apache::lonnet::plaintext($role);
        $output .= '  <option value="'.$role.'">'.$plrole.'</option>';
    }
    if (keys(%customroles) > 0) {
+        my %customroles = &my_custom_roles();
        foreach my $cust (sort(keys(%customroles))) {
            my $custrole='cr_cr_'.$env{'user.domain'}.
                '_'.$env{'user.name'}.'_'.$cust;
@@ -928,47 +947,61 @@ sub default_course_roles {
} 

sub construction_space_roles {
+    my ($checkpriv) = @_;
    my @allroles = ('ca','aa');
    my @roles;
 -    foreach my $role (@allroles) {
 -        if 
(&Apache::lonnet::allowed('c'.$role,$env{'user.domain'}.'/'.$env{'user.name' 
})) {
 -            push(@roles,$role);
+    if ($checkpriv) {
+        foreach my $role (@allroles) {
+            if 
(&Apache::lonnet::allowed('c'.$role,$env{'user.domain'}.'/'.$env{'user.name' 
})) {
+                push(@roles,$role);
+            }
        }
+        return @roles;
+    } else {
+        return @allroles;
    }
 -    return @roles;
} 

sub domain_roles {
+    my ($checkpriv) = @_;
    my @allroles = ('dc','li','dg','au','sc');
    my @roles;
 -    foreach my $role (@allroles) {
 -        if 
(&Apache::lonnet::allowed('c'.$role,$env{'request.role.domain'})) {
 -            push(@roles,$role);
+    if ($checkpriv) {
+        foreach my $role (@allroles) {
+            if 
(&Apache::lonnet::allowed('c'.$role,$env{'request.role.domain'})) {
+                push(@roles,$role);
+            }
        }
+        return @roles;
+    } else {
+        return @allroles;
    }
 -    return @roles;
} 

sub course_roles {
 -    my ($context) = @_;
+    my ($context,$checkpriv) = @_;
    my @allroles = ('st','ta','ep','in','cc');
    my @roles;
    if ($context eq 'domain') {
        @roles = @allroles;
    } elsif ($context eq 'course') {
        if ($env{'request.course.id'}) {
 -            foreach my $role (@allroles) {
 -                if 
(&Apache::lonnet::allowed('c'.$role,$env{'request.course.id'})) {
 -                    push(@roles,$role);
 -                } else {
 -                    if ($role ne 'cc' && $env{'request.course.section'} ne 
'') {
 -                        if (!&Apache::lonnet::allowed('c'.$role,
 -                                         $env{'request.course.id'}.'/'.
 -                                         $env{'request.course.section'})) {
 -                            push(@roles,$role);
+            if ($checkpriv) {
+                foreach my $role (@allroles) {
+                    if 
(&Apache::lonnet::allowed('c'.$role,$env{'request.course.id'})) {
+                        push(@roles,$role);
+                    } else {
+                        if ($role ne 'cc' && $env{'request.course.section'} 
ne '') {
+                            if (!&Apache::lonnet::allowed('c'.$role,
+                                             $env{'request.course.id'}.'/'.
+                                             
$env{'request.course.section'})) {
+                                push(@roles,$role);
+                            }
                        }
                    }
                }
+            } else {
+                @roles = @allroles;
            }
        }
    }
@@ -976,18 +1009,18 @@ sub course_roles {
} 

sub curr_role_permissions {
 -    my ($context,$setting) = @_;
+    my ($context,$setting,$checkpriv) = @_;
    my @roles;
    if ($context eq 'construction_space') {
 -        @roles = &construction_space_roles();
+        @roles = &construction_space_roles($checkpriv);
    } elsif ($context eq 'domain') {
        if ($setting eq 'course') {
 -            @roles = &course_roles($context);
+            @roles = &course_roles($context,$checkpriv);
        } else {
 -            @roles = &domain_roles();
+            @roles = &domain_roles($checkpriv);
        }
    } elsif ($context eq 'course') {
 -        @roles = &course_roles($context);
+        @roles = &course_roles($context,$checkpriv);
    }
    return @roles;
}
@@ -1005,49 +1038,45 @@ sub my_custom_roles {
    return %returnhash;
} 

 -sub print_html_classlist {
 -    my ($r,$mode,$permission,$context) = @_;
+sub print_userlist {
+    my ($r,$mode,$permission,$context,$formname,$totcodes,$codetitles,
+        $idlist,$idlist_titles) = @_;
+    my $format = $env{'form.output'};
    if (! exists($env{'form.sortby'})) {
        $env{'form.sortby'} = 'username';
    }
 -    if ($env{'form.status'} !~ /^(Any|Expired|Active|Future)$/) {
 -        $env{'form.status'} = 'Active';
+    if ($env{'form.Status'} !~ /^(Any|Expired|Active|Future)$/) {
+        $env{'form.Status'} = 'Active';
    }
    my $status_select = &Apache::lonhtmlcommon::StatusOptions
 -        ($env{'form.status'});
+        ($env{'form.Status'}); 

+    if ($env{'form.showrole'} eq '') {
+        $env{'form.showrole'} = 'Any';
+    }
    if (! defined($env{'form.output'}) ||
        $env{'form.output'} !~ /^(csv|excel|html)$/ ) {
        $env{'form.output'} = 'html';
    } 

 -    if ($context eq 'course') {
 -        my $cid =$env{'request.course.id'};
 -        my $cdom=$env{'course.'.$cid.'.domain'};
 -        my $cnum=$env{'course.'.$cid.'.num'};
 -        #
 -        # List course personnel
 -        my 
%coursepersonnel=&Apache::lonnet::get_course_adv_roles($cdom.'/'.$cnum);
 -        #
 -
 -        $r->print('<br />'.&Apache::loncommon::start_data_table());
 -        foreach my $role (sort keys %coursepersonnel) {
 -            next if ($role =~ /^\s*$/);
 -            $r->print(&Apache::loncommon::start_data_table_row().
 -                      '<td>'.$role.'</td><td>');
 -            foreach my $user (split(',',$coursepersonnel{$role})) {
 -                my ($puname,$pudom)=split(':',$user);
 -                $r->print(' '.&Apache::loncommon::aboutmewrapper(
 -                          &Apache::loncommon::plainname($puname,$pudom),
 -                          $puname,$pudom));
 -            }
 -            $r->print('</td>'.&Apache::loncommon::end_data_table_row());
 -        }
 -        $r->print(&Apache::loncommon::end_data_table());
+    my @statuses;
+    if ($env{'form.Status'} eq 'Any') {
+        @statuses = ('previous','active','future');
+    } elsif ($env{'form.Status'} eq 'Expired') {
+        @statuses = ('previous');
+    } elsif ($env{'form.Status'} eq 'Active') {
+        @statuses = ('active');
+    } elsif ($env{'form.Status'} eq 'Future') {
+        @statuses = ('future');
    }
+
+#    if ($context eq 'course') {
+#        $r->print(&display_adv_courseroles());
+#    }
    #
    # Interface output
 -    $r->print('<input type="hidden" name="action" value="'.
+    $r->print('<form name="studentform" method="post" 
action="/adm/createuser">'."\n".
+              '<input type="hidden" name="action" value="'.
              $env{'form.action'}.'" />');
    $r->print("<p>\n");
    if ($env{'form.action'} ne 'modifystudent') {
@@ -1066,71 +1095,506 @@ sub print_html_classlist {
        $output_selector .= '</select>';
        $r->print('<label>'.&mt('Output Format: 
[_1]',$output_selector).'</label>'.('&nbsp;'x3));
    }
 -    $r->print('<label>'.&mt('Student Status: 
[_1]',$status_select)."</label>\n");
 -    $r->print('<input type="submit" value="'.&mt('Update Display').'" />'.
 -              "\n</p>\n");
 -
+    $r->print('<label>'.&mt('User Status: 
[_1]',$status_select).'</label>'.('&nbsp;'x3)."\n");
+    my $roleselected = '';
+    if ($env{'form.showrole'} eq 'Any') {
+       $roleselected = ' selected="selected" ';
+    }
+    my $role_select;
+    if ($context eq 'domain') {
+        $role_select = &domain_roles_select();
+        $r->print('<label>'.&mt('Role Type: 
[_1]',$role_select).'</label>');
+    } else {
+        $role_select = '<select name="showrole">'."\n".
+                       '<option value="Any" '.$roleselected.'>'.
+                       &mt('Any role').'</option>';
+        my @poss_roles = &curr_role_permissions($context);
+        foreach my $role (@poss_roles) {
+            $roleselected = '';
+            if ($role eq $env{'form.showrole'}) {
+                $roleselected = ' selected="selected" ';
+            }
+            my $plrole=&Apache::lonnet::plaintext($role);
+            $role_select .= '<option 
value="'.$role.'"'.$roleselected.'>'.$plrole.'</option>';
+        }
+        $roleselected = '';
+        if ($env{'form.showrole'} eq 'cr') {
+            $roleselected = ' selected="selected" ';
+        }
+        $role_select .= '<option value="cr"'.$roleselected.'>'.&mt('Custom 
role').'</option>'.
+                        '</select>';
+        $r->print('<label>'.&mt('Role: [_1]',$role_select).'</label>');
+    }
+    if (!(($context eq 'domain') && ($env{'form.roletype'} eq 'course'))) {
+        $r->print(&list_submit_button(&mt('Update Display'))."\n</p>\n");
+    }
+    my ($indexhash,$keylist) = &make_keylist_array();
+    my (%userlist,%userinfo);
    if ($context eq 'course') {
        #
 -        # Print the classlist
 -        $r->print('<h2>'.&mt('Current Class List').'</h2>');
 -        my ($classlist,$keylist)=&Apache::loncoursedata::get_classlist();
+        # Print the userlist
+        $r->print('<h2>'.&mt('Current User List').'</h2>');
+        (my $classlist,$keylist)=&Apache::loncoursedata::get_classlist(); 

        if (exists($permission->{'view_section'})) {
            my $sec = &Apache::loncoursedata::CL_SECTION();
            foreach my $student (keys(%{$classlist})) {
 -                if ($classlist->{$student}[$sec] ne 
$permission->{'view_section'}) {
 -                    delete($classlist->{$student});
+                if ($userlist{$student}[$sec] ne 
$permission->{'view_section'}) {
+                    delete($userlist{$student});
                }
            }
        }
 -
 -        if (! defined($classlist)) {
 -            $r->print(&mt('There are no students currently 
enrolled.')."\n");
+        foreach my $item (keys(%{$classlist})) {
+            $userlist{$item} = $classlist->{$item};
+        }
+        my $cid =$env{'request.course.id'};
+        my $cdom=$env{'course.'.$cid.'.domain'};
+        my $cnum=$env{'course.'.$cid.'.num'};
+        my $showroles;
+        if ($env{'form.showrole'} ne 'Any') {
+            $showroles = [$env{'form.showrole'}];
        } else {
 -            # Print out the available choices
 -            if ($env{'form.action'} eq 'modifystudent') {
 -                &show_users_list($r,$context,'view','modify',
 -                                 $env{'form.Status'},$classlist,$keylist);
 -            } else {
 -                &show_users_list($r,$context,$env{'form.output'},'aboutme',
 -                                 $env{'form.Status'},$classlist,$keylist);
+            $showroles = undef;
+        }
+        my %advrolehash = &Apache::lonnet::get_my_roles($cnum,$cdom,undef,
+                                                        
\@statuses,$showroles);
+        &gather_userinfo($context,$format,\%userlist,$indexhash,\%userinfo,
+                         \%advrolehash);
+    } else {
+        my (%cstr_roles,%dom_roles);
+        if ($context eq 'construction_space') {
+            # List co-authors and assistant co-authors
+            my @possroles = ('ca','aa');
+            %cstr_roles = &Apache::lonnet::get_my_roles(undef,undef,undef,
+                                              \@statuses,\@possroles);
+            
&gather_userinfo($context,$format,\%userlist,$indexhash,\%userinfo,
+                             \%cstr_roles);
+        } elsif ($context eq 'domain') {
+            if ($env{'form.roletype'} eq 'domain') {
+                %dom_roles = 
&Apache::lonnet::get_domain_roles($env{'request.role.domain'});
+                foreach my $key (keys(%dom_roles)) {
+                    if (ref($dom_roles{$key}) eq 'HASH') {
+                        
&gather_userinfo($context,$format,\%userlist,$indexhash,
+                                         \%userinfo,$dom_roles{$key});
+                    }
+                }
+            } elsif ($env{'form.roletype'} eq 'construction_space') {
+                my %dom_roles = 
&Apache::lonnet::get_domain_roles($env{'request.role.domain'},['au']);
+                my %coauthors;
+                foreach my $key (keys(%dom_roles)) {
+                    if (ref($dom_roles{$key}) eq 'HASH') {
+                        if ($env{'form.showrole'} eq 'au') {
+                            
&gather_userinfo($context,$format,\%userlist,$indexhash,
+                                             \%userinfo,$dom_roles{$key});
+                        } else {
+                            my @possroles;
+                            if ($env{'form.showrole'} eq 'Any') {
+                                @possroles = ('ca','aa');
+                            } else {
+                                @possroles = ($env{'form.showrole'});
+                            }
+                            foreach my $author 
(sort(keys(%{$dom_roles{$key}}))) {
+                                my ($role,$authorname,$authordom) = 
split(/:/,$author);
+                                my $extent = 
'/'.$authordom.'/'.$authorname;
+                                %{$coauthors{$extent}} =
+                                    
&Apache::lonnet::get_my_roles($authorname,
+                                       
$authordom,undef,\@statuses,\@possroles);
+                            }
+                            &gather_userinfo($context,$format,\%userlist,
+                                             
$indexhash,\%userinfo,\%coauthors);
+                        }
+                    }
+                }
+            } elsif ($env{'form.roletype'} eq 'course') {
+                my $courseform =
+                    
&Apache::lonhtmlcommon::course_selection($formname,$totcodes,
+                                           
$codetitles,$idlist,$idlist_titles);
+                my 
$output='<p>'.&Apache::lonhtmlcommon::start_pick_box()."\n".
+                           &Apache::lonhtmlcommon::start_pick_box()."\n".
+                     &Apache::lonhtmlcommon::row_title(&mt('Select 
Course(s)'),
+                                                       
'LC_oddrow_value')."\n".
+                           $courseform."\n".
+                           &Apache::lonhtmlcommon::row_closure(1).
+                           &Apache::lonhtmlcommon::end_pick_box().'</p>';
+                $r->print($output);
+                $r->print('<p>'.&list_submit_button(&mt('Update Display')).
+                          "\n</p>\n");
+                if ($env{'form.coursepick'}) {
+                    my %courses = &process_coursepick();
+                    my %allusers;
+                    foreach my $cid (keys(%courses)) {
+                        my %coursehash =
+                            
&Apache::lonnet::coursedescription($cid,{'one_time' => 1});
+                        my $cdom = $coursehash{'domain'};
+                        my $cnum = $coursehash{'num'};
+                        my $cdesc = $coursehash{'description'};
+                        my (@roles,@sections,%access,%users,%userdata,
+                            %users,%statushash);
+                        if ($env{'form.showrole'} eq 'Any') {
+                            @roles = &course_roles($context);
+                        } else {
+                            @roles = ($env{'form.showrole'});
+                        }
+                        foreach my $role (@roles) {
+                            %{$users{$role}} = ();
+                        }
+                        foreach my $type (@statuses) {
+                            $access{$type} = $type;
+                        }
+                        
&Apache::loncommon::get_course_users($cdom,$cnum,\%access,\@roles,\@sections 
,\%users,\%userdata,\%statushash);
+                        foreach my $user (keys(%userdata)) {
+                            next if (ref($userinfo{$user}) eq 'HASH');
+                            foreach my $item ('fullname','id') {
+                                $userinfo{$user}{$item} = 
$userdata{$user}[$indexhash->{$item}];
+                            }
+                        }
+                        foreach my $role (keys(%users)) {
+                            foreach my $user (keys(%{$users{$role}})) {
+                                my $uniqid = $user.':'.$role;
+                                $allusers{$uniqid}{$cid} = { desc => 
$cdesc,
+                                                             secs  => 
$statushash{$user}{$role},
+                                                           };
+                            }
+                        }
+                    }
+                    
&gather_userinfo($context,$format,\%userlist,$indexhash,
+                                     \%userinfo,\%allusers);
+                } else {
+                    return;
+                }
            }
        }
 -    } elsif ($context eq 'construction_space') {
 -        # List co-authors and assistant co-authors
 -        my @statuses;
 -        if ($env{'form.status'} eq 'Any') {
 -            @statuses = ('previous','active','future');
 -        } elsif ($env{'form.status'} eq 'Expired') {
 -            @statuses = ('previous');
 -        } elsif ($env{'form.status'} eq 'Active') {
 -            @statuses = ('active');
 -        } elsif ($env{'form.status'} eq 'Future') {
 -            @statuses = ('future');
 -        }
 -        my @possroles = ('ca','aa');
 -        my %cstr_roles = &Apache::lonnet::get_my_roles(undef,undef,undef,
 -                                          \@statuses,\@possroles);
 -        if (keys(%cstr_roles) == 0) {
 -             $r->print(&mt('There are no authors or co-authors.')."\n");
+        if (keys(%userlist) == 0) {
+            if ($context eq 'construction_space') {
+                $r->print(&mt('There are no co-authors to display.')."\n");
+            } elsif ($context eq 'domain') {
+                if ($env{'form.roletype'} eq 'domain') {
+                    $r->print(&mt('There are no users with domain roles to 
display.')."\n");
+                } elsif ($env{'form.roletype'} eq 'construction_space') {
+                    $r->print(&mt('There are no authors or co-authors to 
display.')."\n");
+                } elsif ($env{'form.roletype'} eq 'course') {
+                    $r->print(&mt('There are no course users to 
display')."\n");
+                }
+            } elsif ($context eq 'course') {
+                $r->print(&mt('There are no course users to 
display.')."\n");
+            }
        } else {
            # Print out the available choices
            if ($env{'form.action'} eq 'modifystudent') {
                &show_users_list($r,$context,'view','modify',
 -                                 $env{'form.Status'},\%cstr_roles);
+                                 $env{'form.Status'},\%userlist,$keylist);
            } else {
                &show_users_list($r,$context,$env{'form.output'},'aboutme',
 -                                 $env{'form.Status'},\%cstr_roles);
+                                 $env{'form.Status'},\%userlist,$keylist);
+            }
+        }
+    }
+    $r->print('</form>');
+}
+
+sub list_submit_button {
+    my ($text) = @_;
+    return '<input type="submit" value="'.$text.'" />';
+}
+
+sub gather_userinfo {
+    my ($context,$format,$userlist,$indexhash,$userinfo,$rolehash) = @_;
+    foreach my $item (keys(%{$rolehash})) {
+        @{$userlist->{$item}} = ();
+        my %userdata;
+        if ($context eq 'construction_space' || $context eq 'course') {
+            ($userdata{'username'},$userdata{'domain'},$userdata{'role'}) =
+                split(/:/,$item);
+            
($userdata{'start'},$userdata{'end'})=split(/:/,$rolehash->{$item});
+            
&build_user_record(\%userdata,$userinfo,$indexhash,$item,$userlist);
+        } elsif ($context eq 'domain') {
+            if ($env{'form.roletype'} eq 'domain') {
+                
($userdata{'role'},$userdata{'username'},$userdata{'domain'}) =
+                    split(/:/,$item);
+                
($userdata{'end'},$userdata{'start'})=split(/:/,$rolehash->{$item});
+                
&build_user_record(\%userdata,$userinfo,$indexhash,$item,$userlist);
+            } elsif ($env{'form.roletype'} eq 'construction_space') {
+                if (ref($rolehash->{$item}) eq 'HASH') {
+                    $userdata{'extent'} = $item;
+                    foreach my $key (keys(%{$rolehash->{$item}})) {
+                        
($userdata{'username'},$userdata{'domain'},$userdata{'role'}) =  
split(/:/,$key);
+                        ($userdata{'start'},$userdata{'end'}) =
+                            split(/:/,$rolehash->{$item}{$key});
+                        my $uniqid = $key.':'.$item;
+                        
&build_user_record(\%userdata,$userinfo,$indexhash,$uniqid,$userlist);
+                    }
+                }
+            } elsif ($env{'form.roletype'} eq 'course') {
+                
($userdata{'username'},$userdata{'domain'},$userdata{'role'}) =
+                    split(/:/,$item);
+                if (ref($rolehash->{$item}) eq 'HASH') {
+                    foreach my $cid (sort(keys(%{$rolehash->{$item}}))) {
+                        if (ref($rolehash->{$item}{$cid}) eq 'HASH') {
+                            my $spanstart = '';
+                            my $spanend = '; ';
+                            my $space = ', ';
+                            if ($format eq 'html' || $format eq 'view') {
+                                $spanstart = '<span class="LC_nobreak">';
+                                $spanend = '</span><br />';
+                                $space = ',&nbsp;';
+                            }
+                            $userdata{'extent'} .= $spanstart.
+                                    
$rolehash->{$item}{$cid}{'desc'}.$space;
+                            if (ref($rolehash->{$item}{$cid}{'secs'}) eq 
'HASH') {
+                                foreach my $sec 
(sort(keys(%{$rolehash->{$item}{$cid}{'secs'}}))) {
+                                    $userdata{'extent'} .= 
$sec.$space.$rolehash->{$item}{$cid}{'secs'}{$sec}.$spanend;
+                                }
+                            }
+                        }
+                    }
+                }
+                
&build_user_record(\%userdata,$userinfo,$indexhash,$item,$userlist);
+            }
+        }
+    }
+    return;
+}
+
+sub build_user_record {
+    my ($userdata,$userinfo,$indexhash,$record_key,$userlist) = @_;
+    &process_date_info($userdata);
+    my $username = $userdata->{'username'};
+    my $domain = $userdata->{'domain'};
+    if (ref($userinfo->{$username.':'.$domain}) eq 'HASH') {
+        $userdata->{'fullname'} =
+        $userinfo->{$username.':'.$domain}{'fullname'};
+        $userdata->{'id'} = $userinfo->{$username.':'.$domain}{'id'};
+    } else {
+        &aggregate_user_info($domain,$username,$userinfo);
+        $userdata->{'fullname'} = 
$userinfo->{$username.':'.$domain}{'fullname'};
+        $userdata->{'id'} = $userinfo->{$username.':'.$domain}{'id'};
+    }
+    foreach my $key (keys(%{$indexhash})) {
+        if (defined($userdata->{$key})) {
+            $userlist->{$record_key}[$indexhash->{$key}] = 
$userdata->{$key};
+        }
+    }
+    return;
+}
+
+sub courses_selector {
+    my ($cdom,$formname) = @_;
+    my %coursecodes = ();
+    my %codes = ();
+    my @codetitles = ();
+    my %cat_titles = ();
+    my %cat_order = ();
+    my %idlist = ();
+    my %idnums = ();
+    my %idlist_titles = ();
+    my $caller = 'global';
+    my $totcodes = 0;
+    my $format_reply;
+    my $jscript = '';
+
+    my $totcodes =
+        &Apache::courseclassifier::retrieve_instcodes(\%coursecodes,
+                                                      $cdom,$totcodes);
+    if ($totcodes > 0) {
+        $format_reply =
+             
&Apache::lonnet::auto_instcode_format($caller,$cdom,\%coursecodes,
+                                
\%codes,\@codetitles,\%cat_titles,\%cat_order);
+        if ($format_reply eq 'ok') {
+            my $numtypes = @codetitles;
+            
&Apache::courseclassifier::build_code_selections(\%codes,\@codetitles,\%cat_ 
titles,\%cat_order,\%idlist,\%idnums,\%idlist_titles);
+            my ($scripttext,$longtitles) = 
&Apache::courseclassifier::javascript_definitions(\@codetitles,\%idlist,\%id 
list_titles,\%idnums,\%cat_titles);
+            my $longtitles_str = join('","',@{$longtitles});
+            my $allidlist = $idlist{$codetitles[0]};
+            $jscript .= 
&Apache::courseclassifier::courseset_js_start($formname,$longtitles_str,$all 
idlist);
+            $jscript .= $scripttext;
+            $jscript .= 
&Apache::courseclassifier::javascript_code_selections($formname,@codetitles) 
;
+        }
+    }
+    my $cb_jscript = &Apache::loncommon::coursebrowser_javascript($cdom);
+
+    my %elements = (
+                     Year => 'selectbox',
+                     coursepick => 'radio',
+                     coursetotal => 'text',
+                     courselist => 'text',
+                   );
+    $jscript .= &Apache::lonhtmlcommon::set_form_elements(\%elements);
+    if ($env{'form.coursepick'} eq 'category') {
+        $jscript .= qq|
+function setCourseCat(formname) {
+    if (formname.Year.options[formname.Year.selectedIndex].value == -1) {
+        return;
+    }
+    courseSet('Year');
+    for (var j=0; j<formname.Semester.length; j++) {
+        if (formname.Semester.options[j].value == "$env{'form.Semester'}") 
{
+            formname.Semester.options[j].selected = true;
+        }
+    }
+    if (formname.Semester.options[formname.Semester.selectedIndex].value == 
 -1) {
+        return;
+    }
+    courseSet('Semester');
+    for (var j=0; j<formname.Department.length; j++) {
+        if (formname.Department.options[j].value == 
"$env{'form.Department'}") {            
formname.Department.options[j].selected = true;
+        }
+    }
+    if 
(formname.Department.options[formname.Department.selectedIndex].value == -1) 
{
+        return;
+    }
+    courseSet('Department');
+    for (var j=0; j<formname.Number.length; j++) {
+        if (formname.Number.options[j].value == "$env{'form.Number'}") {
+            formname.Number.options[j].selected = true;
+        }
+    }
+}
+|;
+    }
+    return ($cb_jscript,$jscript,$totcodes,\@codetitles,\%idlist,
+            \%idlist_titles);
+}
+
+sub course_selector_loadcode {
+    my ($formname) = @_;
+    my $loadcode;
+    if ($env{'form.coursepick'} ne '') {
+        $loadcode = 'javascript:setFormElements(document.'.$formname.')';
+        if ($env{'form.coursepick'} eq 'category') {
+            $loadcode .= 
';javascript:setCourseCat(document.'.$formname.')';
+        }
+    }
+    return $loadcode;
+}
+
+sub process_coursepick {
+    my $coursefilter = $env{'form.coursepick'};
+    my $cdom = $env{'request.role.domain'};
+    my %courses;
+    if ($coursefilter eq 'all') {
+        %courses = &Apache::lonnet::courseiddump($cdom,'.','.','.','.','.',
+                                                 undef,undef,'Course');
+    } elsif ($coursefilter eq 'category') {
+        my $instcode = &instcode_from_coursefilter();
+        %courses = 
&Apache::lonnet::courseiddump($cdom,'.','.',$instcode,'.','.',
+                                                 undef,undef,'Course');
+    } elsif ($coursefilter eq 'specific') {
+        if ($env{'form.coursetotal'} > 1) {
+            my @course_ids = split(/&&/,$env{'form.courselist'});
+            foreach my $cid (@course_ids) {
+                $courses{$cid} = '';
            }
+        } else {
+            $courses{$env{'form.courselist'}} = '';
        }
+    }
+    return %courses;
+}
+
+sub instcode_from_coursefilter {
+    my $instcode = '';
+    my @cats = ('Semester','Year','Department','Number');
+    foreach my $category (@cats) {
+        if (defined($env{'form.'.$category})) {
+            unless ($env{'form.'.$category} eq '-1') {
+                $instcode .= $env{'form.'.$category};
+           }
+        }
+    }
+    if ($instcode eq '') {
+        $instcode = '.';
+    }
+    return $instcode;
+}
+
+sub display_adv_courseroles {
+    my $output;
+    #
+    # List course personnel
+    my %coursepersonnel =
+       &Apache::lonnet::get_course_adv_roles($env{'request.course.id'});
+    #
+    $output = '<br />'.&Apache::loncommon::start_data_table();
+    foreach my $role (sort(keys(%coursepersonnel))) {
+        next if ($role =~ /^\s*$/);
+        $output .= &Apache::loncommon::start_data_table_row().
+                  '<td>'.$role.'</td><td>';
+        foreach my $user (split(',',$coursepersonnel{$role})) {
+            my ($puname,$pudom)=split(':',$user);
+            $output .= ' '.&Apache::loncommon::aboutmewrapper(
+                       &Apache::loncommon::plainname($puname,$pudom),
+                       $puname,$pudom);
+        }
+        $output .= '</td>'.&Apache::loncommon::end_data_table_row();
+    }
+    $output .= &Apache::loncommon::end_data_table();
+}
+
+sub make_keylist_array {
+    my ($index,$keylist);
+    $index->{'domain'} = &Apache::loncoursedata::CL_SDOM();
+    $index->{'username'} = &Apache::loncoursedata::CL_SNAME();
+    $index->{'end'} = &Apache::loncoursedata::CL_END();
+    $index->{'start'} = &Apache::loncoursedata::CL_START();
+    $index->{'id'} = &Apache::loncoursedata::CL_ID();
+    $index->{'section'} = &Apache::loncoursedata::CL_SECTION();
+    $index->{'fullname'} = &Apache::loncoursedata::CL_FULLNAME();
+    $index->{'status'} = &Apache::loncoursedata::CL_STATUS();
+    $index->{'type'} = &Apache::loncoursedata::CL_TYPE();
+    $index->{'lockedtype'} = &Apache::loncoursedata::CL_LOCKEDTYPE();
+    $index->{'groups'} = &Apache::loncoursedata::CL_GROUP();
+    $index->{'email'} = &Apache::loncoursedata::CL_PERMANENTEMAIL();
+    $index->{'role'} = &Apache::loncoursedata::CL_ROLE();
+    $index->{'extent'} = &Apache::loncoursedata::CL_EXTENT();
+    foreach my $key (keys(%{$index})) {
+        $keylist->[$index->{$key}] = $key;
+    }
+    return ($index,$keylist);
+}
+
+sub aggregate_user_info {
+    my ($udom,$uname,$userinfo) = @_;
+    my %info=&Apache::lonnet::get('environment',
+                                  ['firstname','middlename',
+                                   'lastname','generation','id'],
+                                   $udom,$uname);
+    my ($tmp) = keys(%info);
+    my ($fullname,$id);
+    if ($tmp =~/^(con_lost|error|no_such_host)/i) {
+        $fullname = 'not available';
+        $id = 'not available';
+        &Apache::lonnet::logthis('unable to retrieve environment '.
+                                 'for '.$uname.':'.$udom);
    } else {
+        $fullname = &Apache::lonnet::format_name(@info{qw/firstname 
middlename lastname generation/},'lastname');
+        $id = $info{'id'};
+    }
+    $userinfo->{$uname.':'.$udom} = {
+                                      fullname => $fullname,
+                                      id       => $id,
+                                    };
+    return;
+} 

+sub process_date_info {
+    my ($userdata) = @_;
+    my $now = time;
+    $userdata->{'status'} = 'Active';
+    if ($userdata->{'start'} > 0) {
+        if ($now < $userdata->{'start'}) {
+            $userdata->{'status'} = 'Future';
+        }
    }
+    if ($userdata->{'end'} > 0) {
+        if ($now > $userdata->{'end'}) {
+            $userdata->{'status'} = 'Expired';
+        }
+    }
+    return;
} 

sub show_users_list {
 -    my ($r,$context,$mode,$linkto,$statusmode,$classlist,$keylist)=@_;
+    my ($r,$context,$mode,$linkto,$statusmode,$userlist,$keylist)=@_;
    #
    # Variables for excel output
    my ($excel_workbook, $excel_sheet, $excel_filename,$row,$format);
@@ -1139,16 +1603,22 @@ sub show_users_list {
    my ($CSVfile,$CSVfilename);
    #
    my $sortby = $env{'form.sortby'};
 -    if ($sortby !~ 
/^(username|domain|section|groups|fullname|id|start|end|type)$/) {
 -        $sortby = 'username';
+    if ($context eq 'course') {
+        if ($sortby !~ 
/^(username|domain|section|groups|fullname|id|start|end|type)$/) {
+            $sortby = 'username';
+        }
+    } else {
+        if ($sortby !~ 
/^(username|domain|id|fullname|start|end|role|email|extent)$/) {
+            $sortby = 'username';
+        }
    }
 -    my ($cid,$cdom,$cnum,$classgroups,$displayphotos,$displayclickers)=@_;
+    my ($cid,$cdom,$cnum,$classgroups,$displayphotos,$displayclickers);
    if ($context eq 'course') {
        $cid=$env{'request.course.id'};
        $cdom = $env{'course.'.$cid.'.domain'};
        $cnum = $env{'course.'.$cid.'.num'};
 -        $classgroups = &Apache::loncoursedata::get_group_memberships(
 -                                     $classlist,$keylist,$cdom,$cnum);
+        ($classgroups) = &Apache::loncoursedata::get_group_memberships(
+                                     $userlist,$keylist,$cdom,$cnum);
        if (! exists($env{'form.displayphotos'})) {
            $env{'form.displayphotos'} = 'off';
        }
@@ -1194,17 +1664,34 @@ END
                       'start'      => "start date",
                       'end'        => "end date",
                       'status'     => "status",
+                       'role'       => "role",
                       'type'       => "enroll type/action",
                       'email'      => "email address",
                       'clicker'    => "clicker id",
                       'photo'      => "photo",
+                       'extent'     => "extent",
                      );
+    if ($context eq 'domain' && $env{'form.roletype'} eq 'course') {
+        $lt{'extent'} = &mt('Course(s): description, section(s), status');
+    } elsif ($context eq 'construction_space') {
+        $lt{'extent'} = &mt('Author');
+    }
    my @cols = ('username','domain','id','fullname');
    if ($context eq 'course') {
        push(@cols,'section');
    }
 -    push(@cols,('start','end'));
 -    if ($statusmode eq 'Any') {
+    if (!($context eq 'domain' && $env{'form.roletype'} eq 'course')) {
+        push(@cols,('start','end'));
+    }
+    if ($env{'form.showrole'} eq 'Any') {
+        push(@cols,'role');
+    }
+    if ($context eq 'domain' && ($env{'form.roletype'} eq 
'construction_space' ||
+                                $env{'form.roletype'} eq 'course')) {
+        push (@cols,'extent');
+    }
+    if (($statusmode eq 'Any') &&
+        (!($context eq 'domain' && $env{'form.roletype'} eq 'course'))) {
        push(@cols,'status');
    }
    if ($context eq 'course') {
@@ -1212,7 +1699,17 @@ END
    }
    push(@cols,'email'); 

+    my $rolefilter;
+    if ($env{'form.showrole'} ne 'Any') {
+        $rolefilter = &Apache::lonnet::plaintext($env{'form.showrole'});
+    }
+    my $results_description = &results_header_row($rolefilter,$statusmode,
+                                                  $context);
+
    if ($mode eq 'html' || $mode eq 'view') {
+        $r->print('<hr />'.&mt('Searching').' ...<br />&nbsp;<br />');
+        $r->rflush();
+        $r->print('<b>'.$results_description.'</b><br />');
        if ($linkto eq 'aboutme') {
            $r->print(&mt("Select a user name to view the user's personal 
page."));
        } elsif ($linkto eq 'modify') {
@@ -1222,7 +1719,6 @@ END
<input type="hidden" name="sname"  value="" />
<input type="hidden" name="sdom"   value="" />
END
 -
        $r->print("\n<p>\n".
                  &Apache::loncommon::start_data_table().
                  &Apache::loncommon::start_data_table_header_row());
@@ -1236,8 +1732,9 @@ END
            ");
        }
        foreach my $item (@cols) {
 -            $r->print('<th><a 
href="javascript:document.studentform.sortby.value='.$item.';document.studen 
tform.submit();">'.$lt{$item}.'</a></th>'."\n");
+            $r->print("<th><a 
href=\"javascript:document.studentform.sortby.value='$item';document.student 
form.submit();\">$lt{$item}</a></th>\n");
        }
+        my %role_types = &role_type_names();
        if ($context eq 'course') {
            # Clicker display on or off?
            my %clicker_options = &Apache::lonlocal::texthash(
@@ -1270,16 +1767,15 @@ END
                      
$photo_options{$photochg}.'</a>&nbsp;'.$lt{'photo'}."\n".
                      '    </th>'."\n");
            }
 -            $r->print(&Apache::end_data_table_header_row());
+            $r->print(&Apache::loncommon::end_data_table_header_row());
        }
# Done with the HTML header line
 -
    } elsif ($mode eq 'csv') {
        #
        # Open a file
        $CSVfilename = '/prtspool/'.
 -            $env{'user.name'}.'_'.$env{'user.domain'}.'_'.
 -            time.'_'.rand(1000000000).'.csv';
+                       $env{'user.name'}.'_'.$env{'user.domain'}.'_'.
+                       time.'_'.rand(1000000000).'.csv';
        unless ($CSVfile = Apache::File->new('>/home/httpd'.$CSVfilename)) {
            $r->log_error("Couldn't open $CSVfilename for output $!");
            $r->print("Problems occured in writing the csv file.  ".
@@ -1289,11 +1785,7 @@ END
        }
        #
        # Write headers and data to file
 -        if($statusmode eq 'Expired') {
 -            print $CSVfile '"'.&mt('Users with expired roles').'"'."\n";    
}
 -        if($statusmode eq 'Future') {
 -            print $CSVfile '"'.&mt('Users with future roles').'"'."\n";
 -        }
+        print $CSVfile '"'.$results_description.'"'."\n";
        print $CSVfile '"'.join('","',map {
            &Apache::loncommon::csv_translate($lt{$_})
            } (@cols)).'"'."\n";
@@ -1303,18 +1795,7 @@ END
            &Apache::loncommon::create_workbook($r);
        return if (! defined($excel_workbook));
        $excel_sheet = $excel_workbook->addworksheet('userlist');
 -        #
 -        my $description;
 -        if ($context eq 'course') {
 -            $description = &mt('Class List for ').
 -                $env{'course.'.$env{'request.course.id'}.'.description'};
 -        } elsif ($context eq 'construction_space') {
 -            $description = &mt('List of co-authors for construction space 
for [_1]',
 -                           
&Apache::loncommon::plainname($env{'user.name'},$env{'user.domain'}));
 -        } else {
 -            $description = &mt('List of users for domain: 
[_1]',&Apache::lonnet::domain($env{'request.role.domain'},'description'));
 -        }
 -        $excel_sheet->write($row++,0,$description,$format->{'h1'});
+        $excel_sheet->write($row++,0,$results_description,$format->{'h2'});
        #
        my @colnames = map {$lt{$_}} (@cols);
        $excel_sheet->write($row++,0,\@colnames,$format->{'bold'});
@@ -1322,84 +1803,284 @@ END 

# Done with header lines in all formats 

 -    #
 -    # Sort the users
    my %index;
    my $i;
 -    foreach (@$keylist) {
 -        $index{$_} = $i++;
+    foreach my $idx (@$keylist) {
+        $index{$idx} = $i++;
    }
 -    $index{'groups'} = scalar(@$keylist);
+    # Get groups, role, permanent e-mail so we can sort on them if
+    # necessary.
+    foreach my $user (keys(%{$userlist})) {
+        my ($uname,$udom,$role,$groups,$email);
+        if ($context eq 'domain') {
+            if ($env{'form.roletype'} eq 'domain') {
+                ($role,$uname,$udom) = split(/:/,$user);
+
+            } elsif ($env{'form.roletype'} eq 'construction_space') {
+                ($uname,$udom,$role) = split(/:/,$user,-1);
+            } elsif ($env{'form.roletype'} eq 'course') {
+                ($uname,$udom,$role) = split(/:/,$user);
+            }
+        } else {
+            ($uname,$udom,$role) = split(/:/,$user,-1);
+            if (($context eq 'course') && $role eq '') {
+                $role = 'st';
+            }
+        }
+        $userlist->{$user}->[$index{'role'}] = $role;
+        if (($env{'form.showrole'} ne 'Any') && (!($env{'form.showrole'}  
eq 'cr' && $role =~ /^cr\//)) && ($role ne $env{'form.showrole'})) {
+            delete($userlist->{$user});
+            next;
+        }
+        if (ref($classgroups) eq 'HASH') {
+            $groups = $classgroups->{$user};
+        }
+        if (ref($groups->{active}) eq 'HASH') {
+            $userlist->{$user}->[$index{'groups'}] = join(', 
',keys(%{$groups->{'active'}}));
+        }
+        my %emails   = &Apache::loncommon::getemails($uname,$udom);
+        if ($emails{'permanentemail'} =~ /\S/) {
+            $userlist->{$user}->[$index{'email'}] = 
$emails{'permanentemail'};
+        }
+    }
+
+    #
+    # Sort the users
    my $index  = $index{$sortby};
    my $second = $index{'username'};
    my $third  = $index{'domain'};
 -    my @Sorted_Students = sort {
 -        lc($classlist->{$a}->[$index])  cmp lc($classlist->{$b}->[$index])
+    my @sorted_users = sort {
+        lc($userlist->{$a}->[$index])  cmp lc($userlist->{$b}->[$index])
            ||
 -        lc($classlist->{$a}->[$second]) cmp lc($classlist->{$b}->[$second]) 
||
 -        lc($classlist->{$a}->[$third]) cmp lc($classlist->{$b}->[$third])
 -        } (keys(%$classlist));
 -    my $studentcount = 0;
+        lc($userlist->{$a}->[$second]) cmp lc($userlist->{$b}->[$second])   
||
+        lc($userlist->{$a}->[$third]) cmp lc($userlist->{$b}->[$third])
+        } (keys(%$userlist));
+    my $usercount = 0;
    my $autocount = 0;
    my $manualcount = 0;
 -    my $unlockcount = 0;
    my $lockcount = 0;
 -    foreach my $student (@Sorted_Students) {
 -        my $sdata = $classlist->{$student};
 -        my $groups = $classgroups->{$student};
 -        my $username = $sdata->[$index{'username'}];
 -        my $domain   = $sdata->[$index{'domain'}];
 -        my $section  = $sdata->[$index{'section'}];
 -        my $active_groups;
 -        if (ref($groups->{active}) eq 'HASH') {
 -            $active_groups = join(', ',keys(%{$groups->{'active'}}));
 -        }
 -        my $name     = $sdata->[$index{'fullname'}];
 -        my $id       = $sdata->[$index{'id'}];
 -        my $status   = $sdata->[$index{'status'}];
 -        next if (($statusmode ne 'Any') && ($status ne $statusmode));
 -        my $start    = $sdata->[$index{'start'}];
 -        my $end      = $sdata->[$index{'end'}];
 -        if (! defined($start) || $start == 0) {
 -            $start = &mt('none');
+    my $unlockcount = 0;
+    foreach my $user (@sorted_users) {
+        my $sdata = $userlist->{$user};
+        my %in;
+        foreach my $item (@{$keylist}) {
+            $in{$item} = $sdata->[$index{$item}];
+        }
+        next if (($statusmode ne 'Any') && ($in{'status'} ne $statusmode));
+        $in{'role'}=&Apache::lonnet::plaintext($sdata->[$index{'role'}]);
+        if (! defined($in{'start'}) || $in{'start'} == 0) {
+            $in{'start'} = &mt('none');
        } else {
 -            $start = &Apache::lonlocal::locallocaltime($start);
+            $in{'start'} = &Apache::lonlocal::locallocaltime($in{'start'});
        }
 -        if (! defined($end) || $end == 0) {
 -            $end = &mt('none');
+        if (! defined($in{'end'}) || $in{'end'} == 0) {
+            $in{'end'} = &mt('none');
        } else {
 -            $end = &Apache::lonlocal::locallocaltime($end);
+            $in{'end'} = &Apache::lonlocal::locallocaltime($in{'end'});
+        }
+        $usercount ++;
+        if ($mode eq 'view' || $mode eq 'html' || $mode eq 'autoenroll') {
+            $r->print(&Apache::loncommon::start_data_table_row());
+            $r->print("<td>$usercount</td>\n");
+            if ($linkto eq 'aboutme') {
+                $in{'username'} =
+                    &Apache::loncommon::aboutmewrapper($in{'username'},
+                                                       $in{'username'},
+                                                       $in{'domain'});
+            } elsif ($linkto eq 'modify') {
+                $in{'username'} = '<a href="'.
+                          "javascript:document.studentform.sname.value='".
+                           $in{'username'}.
+                           
"';document.studentform.sdom.value='".$in{'domain'}.
+                           "';document.studentform.state.value='selected".
+                           "';document.studentform.submit();".'">'.
+                           $in{'username'}."</a>\n";
+            }
+            foreach my $item (@cols) {
+                $r->print('<td>'.$in{$item}.'</td>'."\n");
+            }
+            if ($context eq 'course') {
+                if ($displayclickers eq 'on') {
+                    my $clickers =
+                   
(&Apache::lonnet::userenvironment($in{'domain'},$in{'username'},'clickers')) 
[1];
+                    if ($clickers!~/\w/) { $clickers='-'; }
+                    $r->print('<td>'.$clickers.'</td>');
+                } else {
+                    $r->print('    <td>&nbsp;</td>  ');
+                }
+                if ($displayphotos eq 'on') {
+                    if ($env{'course.'.$env{'request.course.id'}.
+                        '.internal.showphoto'}) {
+                        my $imgurl =
+               
&Apache::lonnet::retrievestudentphoto($in{'domain'},$in{'username'},'gif','t 
humbnail');
+                        $r->print('    <td align="right"><a 
href="javascript:photowindow('."'".&Apache::lonnet::studentphoto($in{'domain 
'},$in{'username'},'jpg')."'".')"><img src="'.$imgurl.'" 
border="1"></a></td>');
+                    } else {
+                        $r->print('    <td>&nbsp;</td>  ');
+                    }
+                }
+            }
+            $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});
+            }
+            print $CSVfile '"'.join('","',@line).'"'."\n";
+        } elsif ($mode eq 'excel') {
+            my $col = 0;
+            foreach my $item (@cols) {
+                if ($item eq 'start' || $item eq 'end') {
+                    if (defined($item) && $item != 0) {
+                        $excel_sheet->write($row,$col++,
+                            
&Apache::lonstathelpers::calc_serial($in{item}),
+                                    $format->{'date'});
+                    } else {
+                        $excel_sheet->write($row,$col++,'none');
+                    }
+                } else {
+                    $excel_sheet->write($row,$col++,$in{$item});
+                }
+            }
+            $row++;
        }
 -        my $status   = $sdata->[$index{'status'}];
 -        next if ($status ne 'Active');
 -        #
 -        $r->print(&Apache::loncommon::start_data_table_row());
 -        $r->print(<<"END");
 -    <td><input type="checkbox" name="droplist" value="$student"></td>
 -    <td>$username</td>
 -    <td>$domain</td>
 -    <td>$id</td>
 -    <td>$name</td>
 -    <td>$start</td>
 -    <td>$end</td>
 -END
 -        $r->print(&Apache::loncommon::end_data_table_row());
    }
 -    $r->print(&Apache::loncommon::end_data_table().'<br />');
 -    %lt=&Apache::lonlocal::texthash(
 -                       'dp'   => "Expire User Roles",
 -                       'ca'   => "check all",
 -                       'ua'   => "uncheck all",
 -                                       );
 -    $r->print(<<"END");
 -</p><p>
 -<input type="button" value="$lt{'ca'}" 
onclick="javascript:checkAll(document.studentform.droplist)"> &nbsp;
 -<input type="button" value="$lt{'ua'}" 
onclick="javascript:uncheckAll(document.studentform.droplist)">
 -<p><input type=submit value="$lt{'dp'}"></p>
 -END
+    if ($mode eq 'view' || $mode eq 'html' || $mode eq 'autoenroll') {
+            $r->print(&Apache::loncommon::end_data_table().'<br />');
+    } elsif ($mode eq 'excel') {
+        $excel_workbook->close();
+        $r->print('<p><a href="'.$excel_filename.'">'.
+                  &mt('Your Excel spreadsheet').'</a> '.&mt('is ready for 
download').'.</p>'."\n");
+    } elsif ($mode eq 'csv') {
+        close($CSVfile);
+        $r->print('<a href="'.$CSVfilename.'">'.
+                  &mt('Your CSV file').'</a> is ready for download.'.
+                  "\n");
+        $r->rflush();
+    }
+    if ($mode eq 'autoenroll') {
+        return 
($usercount,$autocount,$manualcount,$lockcount,$unlockcount);
+    }
    return;
} 

+sub role_type_names {
+    my %lt = &Apache::lonlocal::texthash (
+                         'domain'             => 'Domain Roles',
+                         'construction_space' => 'Co-Author Roles',
+                         'course'             => 'Course Roles',
+             );
+    return %lt;
+}
+
+sub results_header_row {
+    my ($rolefilter,$statusmode,$context) = @_;
+    my $description;
+    if ($context eq 'course') {
+        $description = &mt('Course - 
').$env{'course.'.env{'request.course.id'}.'.description'}.': ';
+        if ($statusmode eq 'Expired') {
+            $description .= &mt('Users in course with expired [_1] 
roles',$rolefilter);
+        }
+        if ($statusmode eq 'Future') {
+            $description .= &mt('Users in course with future [_1] 
roles',$rolefilter);
+        } elsif ($statusmode eq 'Active') {
+            $description .= &mt('Users in course with active [_1] 
roles',$rolefilter);
+        } else {
+            if ($rolefilter eq 'Any') {
+                $description .= &mt('All users in course');
+            } else {
+                $description .= &mt('All users in course with [_1] 
roles',$rolefilter);
+            }
+        }
+    } elsif ($context eq 'construction_space') {
+        $description = &mt('Author space for [_1].').' ';
+        if ($statusmode eq 'Expired') {
+            $description .= &mt('Co-authors with expired [_1] 
roles',$rolefilter);
+        } elsif ($statusmode eq 'Future') {
+            $description .= &mt('Co-authors with future [_1] 
roles',$rolefilter);
+        } elsif ($statusmode eq 'Active') {
+            $description .= &mt('Co-authors with active [_1] 
roles',$rolefilter);
+        } else {
+            if ($rolefilter eq 'Any') {
+                $description .= &mt('All co-authors',$rolefilter);
+            } else {
+                $description .= &mt('All co-authors with [_1] 
roles',$rolefilter);
+            }
+        }
+    } elsif ($context eq 'domain') {
+        my $domdesc = 
&Apache::lonnet::domain($env{'request.role.domain'},'description');
+        $description = &mt('Domain - ').$domdesc.': ';
+        if ($env{'form.roletype'} eq 'domain') {
+            if ($statusmode eq 'Expired') {
+                $description .= &mt('Users in domain with expired [_1] 
roles',$rolefilter);
+            } elsif ($statusmode eq 'Future') {
+                $description .= &mt('Users in domain with future [_1] 
roles',$rolefilter);
+            } elsif ($statusmode eq 'Active') {
+                $description .= &mt('Users in domain with active [_1] 
roles',$rolefilter);
+            } else {
+                if ($rolefilter eq 'Any') {
+                    $description .= &mt('All users in domain',$rolefilter);
+                } else {
+                    $description .= &mt('All users in domain with [_1] 
roles',$rolefilter);
+                }
+            }
+        } elsif ($env{'form.roletype'} eq 'construction_space') {
+            if ($statusmode eq 'Expired') {
+                $description .= &mt('Co-authors in domain with expired [_1] 
roles',$rolefilter);
+            } elsif ($statusmode eq 'Future') {
+                $description .= &mt('Co-authors in domain with future [_1] 
roles',$rolefilter);
+            } elsif ($statusmode eq 'Active') {
+               $description .= &mt('Co-authors in domain with active [_1] 
roles',$rolefilter);
+            } else {
+                if ($rolefilter eq 'Any') {
+                    $description .= &mt('All users with co-author roles in 
domain',$rolefilter);
+                } else {
+                    $description .= &mt('All co-authors in domain  with 
[_1] roles',$rolefilter);
+                }
+            }
+        } elsif ($env{'form.roletype'} eq 'course') {
+            my $coursefilter = $env{'form.coursepick'};
+            if ($coursefilter eq 'category') {
+                my $instcode = &instcode_from_coursefilter();
+                if ($instcode eq '.') {
+                    $description .= &mt('All courses in domain').' - ';
+                } else {
+                    $description .= &mt('Courses in domain with 
institutional code: [_1]',$instcode).' - ';
+                }
+            } elsif ($coursefilter eq 'selected') {
+                $description .= &mt('Selected courses in domain').' - ';
+            } elsif ($coursefilter eq 'all') {
+                $description .= &mt('All courses in domain').' - ';
+            }
+            if ($statusmode eq 'Expired') {
+                $description .= &mt('users with expired [_1] 
roles',$rolefilter);
+            } elsif ($statusmode eq 'Future') {
+                $description .= &mt('users with future [_1] 
roles',$rolefilter);
+            } elsif ($statusmode eq 'Active') {
+                $description .= &mt('users with active [_1] 
roles',$rolefilter);
+            } else {
+                if ($rolefilter eq 'Any') {
+                    $description .= &mt('all users');
+                } else {
+                    $description .= &mt('users with [_1] 
roles',$rolefilter);
+                }
+            }
+        }
+    }
+    return $description;
+}
+
#################################################
#################################################
sub show_drop_list {
@@ -1561,8 +2242,6 @@ END
    return;
} 

 -
 -
#
# Print out the initial form to get the file containing a list of users
#
@@ -1572,11 +2251,11 @@ sub print_first_users_upload_form {
    $str  = '<input type="hidden" name="phase" value="two">';
    $str .= '<input type="hidden" name="action" value="upload" />';
    $str .= '<input type="hidden"   name="state"  value="got_file" />';
 -    $str .= "<h3>".&mt('Upload a list of users')."</h3>\n";
+    $str .= "<h3>".&mt('Upload a file containing information about 
users')."</h3>\n";
    $str .= &Apache::loncommon::upfile_select_html();
    $str .= "<p>\n";
    $str .= '<input type="submit" name="fileupload" value="'.
 -        &mt('Upload users list').'">'."\n";
+        &mt('Upload file of users').'">'."\n";
    $str .= '<label><input type="checkbox" name="noFirstLine" /> '.
        &mt('Ignore First Line')."</label></p>\n";
    $str .= &Apache::loncommon::help_open_topic("Course_Create_Class_List",
@@ -1805,9 +2484,9 @@ sub upfile_drop_add {
                    my $role = '';
                    if (defined($fields{'role'})) {
                        if ($entries{$fields{'role'}}) {
 -                             my @poss_roles =
+                            my @poss_roles =
                                 &curr_role_permissions($context,$setting);
 -                             if 
(grep(/^\Q$entries{$fields{'role'}}\E/,@poss_roles)) {
+                            if 
(grep(/^\Q$entries{$fields{'role'}}\E/,@poss_roles)) {
                                $role=$entries{$fields{'role'}};
                            } else {
                                my $rolestr = join(', ',@poss_roles); 

_______________________________________________
LON-CAPA-cvs mailing list
LON-CAPA-cvs@mail.lon-capa.org
http://mail.lon-capa.org/mailman/listinfo/lon-capa-cvs