[LON-CAPA-cvs] cvs: loncom(GCI_3) /auth lonroles.pm /homework structuretags.pm /interface loncreateuser.pm lonmenu.pm lonuserutils.pm lonwhatsnew.pm

raeburn raeburn@source.lon-capa.org
Mon, 09 Aug 2010 23:39:59 -0000


This is a MIME encoded message

--raeburn1281397199
Content-Type: text/plain

raeburn		Mon Aug  9 23:39:59 2010 EDT

  Modified files:              (Branch: GCI_3)
    /loncom/interface	loncreateuser.pm lonuserutils.pm lonwhatsnew.pm 
                     	lonmenu.pm 
    /loncom/homework	structuretags.pm 
    /loncom/auth	lonroles.pm 
  Log:
  - Customization for GCI_3.  For Concept Tests:
    - Keep track of last course "login"
    - Keep track of submission count by students in Concep Tests.
    - New What's New item - Last login for users (day, week, month, ever).
    - Eliminate columns for groups and clickers for classlist display.
    - Add new columns for last login and test status (completed, incomplete, unattempted).  
  
  
--raeburn1281397199
Content-Type: text/plain
Content-Disposition: attachment; filename="raeburn-20100809233959.txt"

Index: loncom/interface/loncreateuser.pm
diff -u loncom/interface/loncreateuser.pm:1.329.2.2 loncom/interface/loncreateuser.pm:1.329.2.3
--- loncom/interface/loncreateuser.pm:1.329.2.2	Thu Mar 11 15:48:33 2010
+++ loncom/interface/loncreateuser.pm	Mon Aug  9 23:39:43 2010
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA
 # Create a user
 #
-# $Id: loncreateuser.pm,v 1.329.2.2 2010/03/11 15:48:33 raeburn Exp $
+# $Id: loncreateuser.pm,v 1.329.2.3 2010/08/09 23:39:43 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -497,8 +497,14 @@
                 'onload' => "javascript:setFormElements(document.$formtoset)",
                     );
     my %breadcrumb_text = &singleuser_breadcrumb($crstype);
+    my $title = 'User Management';
+    if ($context eq 'course') {
+        if (&Apache::loncommon::needs_gci_custom()) {
+            $title = 'Enrollment and Student Activity';
+        }
+    }
     my $start_page =
-	&Apache::loncommon::start_page('User Management',
+	&Apache::loncommon::start_page($title,
 				       $jscript,{'add_entries' => \%loaditems,});
     if ($env{'form.action'} eq 'custom') {
         &Apache::lonhtmlcommon::add_breadcrumb
@@ -516,7 +522,7 @@
     } elsif ($env{'form.action'} eq 'singlestudent') {
         $helpitem = 'Course_Add_Student';
     }
-    my $crumbs = &Apache::lonhtmlcommon::breadcrumbs('User Management',
+    my $crumbs = &Apache::lonhtmlcommon::breadcrumbs($title,
                                                      $helpitem);
     my %lt=&Apache::lonlocal::texthash(
                     'srst' => 'Search for a user and enroll as a student',
@@ -792,7 +798,13 @@
     if ($context eq 'requestcrs') {
         $r->print('<div>');
     } else {
-        $r->print(&Apache::loncommon::start_page('User Management',$jscript));
+        my $title = 'User Management';
+        if ($context eq 'course') {
+            if (&Apache::loncommon::needs_gci_custom()) {
+                $title = 'Enrollment and Student Activity';
+            }
+        }
+        $r->print(&Apache::loncommon::start_page($title,$jscript));
 
         my %breadcrumb_text = &singleuser_breadcrumb($crstype);
         &Apache::lonhtmlcommon::add_breadcrumb
@@ -803,13 +815,13 @@
               text=>$breadcrumb_text{'userpicked'},
               faq=>282,bug=>'Instructor Interface',});
         if ($env{'form.action'} eq 'singleuser') {
-            $r->print(&Apache::lonhtmlcommon::breadcrumbs('User Management',
+            $r->print(&Apache::lonhtmlcommon::breadcrumbs($title,
                                                           'Course_Change_Privileges'));
             $r->print("<b>$lt{'usrch'}</b><br />");
             $r->print(&entry_form($srch->{'srchdomain'},$srch,undef,$context,undef,$crstype));
             $r->print('<h3>'.$lt{'usel'}.'</h3>');
         } elsif ($env{'form.action'} eq 'singlestudent') {
-            $r->print(&Apache::lonhtmlcommon::breadcrumbs('User Management',
+            $r->print(&Apache::lonhtmlcommon::breadcrumbs($title,
                                                           'Course_Add_Student'));
             $r->print($jscript."<b>");
             if ($crstype eq 'Community') {
@@ -994,8 +1006,14 @@
     if ($env{'form.popup'}) {
        $args->{'no_nav_bar'} = 1; 
     }
+    my $title = 'User Management';
+    if ($context eq 'course') {
+        if (&Apache::loncommon::needs_gci_custom()) {
+            $title = 'Enrollment and Student Activity';
+        }
+    }
     my $start_page = 
-	&Apache::loncommon::start_page('User Management',$js,$args);
+	&Apache::loncommon::start_page($title,$js,$args);
     my %breadcrumb_text = &singleuser_breadcrumb($crstype);
     &Apache::lonhtmlcommon::add_breadcrumb
      ({href=>"javascript:backPage($form)",
@@ -1016,7 +1034,7 @@
     if ($env{'form.action'} eq 'singlestudent') {
         $helpitem = 'Course_Add_Student';
     }
-    my $crumbs = &Apache::lonhtmlcommon::breadcrumbs('User Management',
+    my $crumbs = &Apache::lonhtmlcommon::breadcrumbs($title,
                                                      $helpitem);
 
     my $forminfo =<<"ENDFORMINFO";
@@ -2204,7 +2222,13 @@
     if ($env{'form.action'} eq 'singlestudent') {
         $helpitem = 'Course_Add_Student';
     }
-    $r->print(&Apache::lonhtmlcommon::breadcrumbs('User Management',
+    my $title = 'User Management';
+    if ($context eq 'course') {
+        if (&Apache::loncommon::needs_gci_custom()) {
+            $title = 'Enrollment and Student Activity';
+        }
+    }
+    $r->print(&Apache::lonhtmlcommon::breadcrumbs($title,
                                                  $helpitem));
     $r->print(&update_result_form($uhome));
     # Check Inputs
@@ -3631,6 +3655,12 @@
         $context = 'domain';
         $crstype = $env{'form.templatecrstype'};
     }
+    my $title = 'User Management';
+    if ($context eq 'course') {
+        if (&Apache::loncommon::needs_gci_custom()) {
+            $title = 'Enrollment and Student Activity';
+        }
+    }
 # ------------------------------------------------------- What can be assigned?
     my %full=();
     my %courselevel=();
@@ -3746,7 +3776,7 @@
       {href=>"javascript:backPage(document.form1,'','')",
          text=>"Edit custom role",
          faq=>282,bug=>'Instructor Interface',});
-    $r->print(&Apache::lonhtmlcommon::breadcrumbs('User Management',
+    $r->print(&Apache::lonhtmlcommon::breadcrumbs($title,
                                                   'Course_Editing_Custom_Roles'));
 
     $r->print($body_top);
@@ -3899,7 +3929,12 @@
                  .$jsback."\n"
                  .'// ]]>'."\n"
                  .'</script>'."\n";
-
+    my $title = 'User Management';
+    if ($context eq 'course') {
+        if (&Apache::loncommon::needs_gci_custom()) {
+            $title = 'Enrollment and Student Activity';
+        }
+    }
     $r->print(&Apache::loncommon::start_page('Save Custom Role'),$jscript);
     &Apache::lonhtmlcommon::add_breadcrumb
         ({href=>"javascript:backPage(document.customresult,'pickrole','')",
@@ -3911,7 +3946,7 @@
          {href=>"javascript:backPage(document.customresult,'set_custom_roles','')",
           text=>"Result",
           faq=>282,bug=>'Instructor Interface',});
-    $r->print(&Apache::lonhtmlcommon::breadcrumbs('User Management',
+    $r->print(&Apache::lonhtmlcommon::breadcrumbs($title,
                                                   'Course_Editing_Custom_Roles'));
 
     my ($rdummy,$roledef)=
@@ -3989,6 +4024,12 @@
     } else {
         $context = 'domain';
     }
+    my $title = 'User Management';
+    if ($context eq 'course') {
+        if (&Apache::loncommon::needs_gci_custom()) {
+            $title = 'Enrollment and Student Activity';
+        }
+    }
     &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
         ['action','state','callingform','roletype','showrole','bulkaction','popup','phase',
          'username','domain','srchterm','srchdomain','srchin','srchby','srchtype']);
@@ -3996,7 +4037,7 @@
     if ($env{'form.action'} ne 'dateselect') {
         &Apache::lonhtmlcommon::add_breadcrumb
             ({href=>"/adm/createuser",
-              text=>"User Management",
+              text=>$title,
               help=>'Course_Create_Class_List,Course_Change_Privileges,Course_View_Class_List,Course_Editing_Custom_Roles,Course_Add_Student,Course_Drop_Student,Course_Automated_Enrollment,Course_Self_Enrollment,Course_Manage_Group'});
     }
     #SD Following files not added to help, because the corresponding .tex-files seem to
@@ -4016,7 +4057,7 @@
     # Main switch on form.action and form.state, as appropriate
     if (! exists($env{'form.action'})) {
         $r->print(&header());
-        $r->print(&Apache::lonhtmlcommon::breadcrumbs('User Management'));
+        $r->print(&Apache::lonhtmlcommon::breadcrumbs($title));
         $r->print(&print_main_menu($permission,$context,$crstype));
         $r->print(&Apache::loncommon::end_page());
     } elsif ($env{'form.action'} eq 'upload' && $permission->{'cusr'}) {
@@ -4272,7 +4313,7 @@
         $r->print(&Apache::loncommon::end_page());        
     } else {
         $r->print(&header());
-        $r->print(&Apache::lonhtmlcommon::breadcrumbs('User Management'));
+        $r->print(&Apache::lonhtmlcommon::breadcrumbs($title));
         $r->print(&print_main_menu($permission,$context,$crstype));
         $r->print(&Apache::loncommon::end_page());
     }
@@ -4552,7 +4593,7 @@
                     drop       => 'Drop Students',
                     upload     => 'Upload a File of Course Users',
                     singleuser => 'Add/Modify a Course User',
-                    listusers  => 'Manage Course Users',
+                    listusers  => 'Concept Test Roster and Student Activity',
                   },
      );
      my %linktitles = (
Index: loncom/interface/lonuserutils.pm
diff -u loncom/interface/lonuserutils.pm:1.109.2.2 loncom/interface/lonuserutils.pm:1.109.2.3
--- loncom/interface/lonuserutils.pm:1.109.2.2	Tue Jan  5 22:08:48 2010
+++ loncom/interface/lonuserutils.pm	Mon Aug  9 23:39:43 2010
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA
 # Utility functions for managing LON-CAPA user accounts
 #
-# $Id: lonuserutils.pm,v 1.109.2.2 2010/01/05 22:08:48 raeburn Exp $
+# $Id: lonuserutils.pm,v 1.109.2.3 2010/08/09 23:39:43 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -36,6 +36,7 @@
 use Apache::lonhtmlcommon;
 use Apache::lonlocal;
 use Apache::longroup;
+use Apache::lonnavmaps;
 use LONCAPA qw(:DEFAULT :match);
 
 ###############################################################
@@ -2095,6 +2096,7 @@
 
 sub show_users_list {
     my ($r,$context,$mode,$permission,$statusmode,$userlist,$keylist,$formname)=@_;
+    my $custommenu; 
     if ($formname eq '') {
         $formname = 'studentform';
     }
@@ -2119,11 +2121,17 @@
         $sortby = 'username';
     }
     my $setting = $env{'form.roletype'};
-    my ($cid,$cdom,$cnum,$classgroups,$displayphotos,$displayclickers,$crstype);
+    my ($cid,$cdom,$cnum,$classgroups,$displayphotos,$displayclickers,$crstype,
+        $clickersupport,$displaygroups);
     if ($context eq 'course') {
         $cid = $env{'request.course.id'};
         $crstype = &Apache::loncommon::course_type();
         ($cnum,$cdom) = &get_course_identity($cid);
+        $custommenu = &Apache::loncommon::needs_gci_custom();
+        unless ($custommenu) {
+            $clickersupport = 1;
+            $displaygroups = 1;
+        }
         ($classgroups) = &Apache::loncoursedata::get_group_memberships(
                                      $userlist,$keylist,$cdom,$cnum);
         if ($mode eq 'autoenroll') {
@@ -2244,6 +2252,8 @@
                        'role'       => "role",
                        'type'       => "enroll type/action",
                        'email'      => "e-mail address",
+                       'lastlogin'  => "last login",
+                       'submissions' => "test status",
                        'photo'      => "photo",
                        'extent'     => "extent",
                        'pr'         => "Proceed",
@@ -2290,9 +2300,19 @@
             push(@cols,'status');
         }
         if ($context eq 'course') {
-            push(@cols,'groups');
+            if ($displaygroups) {
+                push(@cols,'groups');
+            }
         }
         push(@cols,'email');
+        if ($context eq 'course') {
+            if ($custommenu) {
+                push(@cols,'lastlogin');
+                if (($env{'form.showrole'} eq 'Any') || ($env{'form.showrole'} eq 'st')) {
+                    push(@cols,'submissions');
+                }
+            }
+        }
     }
 
     my $rolefilter = $env{'form.showrole'};
@@ -2415,27 +2435,32 @@
             }
         }
         foreach my $item (@cols) {
-            $output .= "<th><a href=\"javascript:document.$formname.sortby.value='$item';document.$formname.submit();\">$lt{$item}</a></th>\n";
+            if (grep(/^\Q$item\E$/,@sortable)) {
+                $output .= "<th><a href=\"javascript:document.$formname.sortby.value='$item';document.$formname.submit();\">$lt{$item}</a></th>\n";
+            } else {
+                $output .= "<th>$lt{$item}</th>\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 .= '    <th>'."\n".'     '
-                        .&mt('[_1]'.$clicker_options{$clickerchg}.'[_2] clicker id'
+                if ($clickersupport) {
+                    my %clicker_options = (
+                                            'on' => 'Show',
+                                            'off' => 'Hide',
+                                          );
+                    my $clickerchg = 'on';
+                    if ($displayclickers eq 'on') {
+                        $clickerchg = 'off';
+                    }
+                    $output .= '    <th>'."\n".'     '
+                       .&mt('[_1]'.$clicker_options{$clickerchg}.'[_2] clicker id'
                             ,'<a href="javascript:document.'.$formname.'.displayclickers.value='
                              ."'".$clickerchg."'".';document.'.$formname.'.submit();">'
                             ,'</a>')
                         ."\n".'    </th>'."\n";
-
+                }
                 # Photo display on or off?
                 if ($env{'course.'.$env{'request.course.id'}.'.internal.showphoto'}) {
                     my %photo_options = &Apache::lonlocal::texthash(
@@ -2474,14 +2499,18 @@
             $CSVfile = undef;
         }
         #
-        push @cols,'clicker';
+        if ($clickersupport) {
+            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';
+        if ($clickersupport) {
+            push @cols,'clicker';
+        }
         # Create the excel spreadsheet
         ($excel_workbook,$excel_filename,$format) =
             &Apache::loncommon::create_workbook($r);
@@ -2517,6 +2546,40 @@
                                                 Future  => 'Future',
                                                 Expired => 'Expired',
                                                );
+    # If this is for a single course get last course "log-in" and submissions.
+    my (%crslogins,%stusubmissions,%elapsed,$numparts,%nummultipart,$multipart);
+    my $now = time;
+    if ($context eq 'course') {
+        if ($custommenu) {
+            %crslogins=&Apache::lonnet::dump('nohist_crslastlogin',$cdom,$cnum);
+            %stusubmissions=&Apache::lonnet::dump('nohist_submissiontracker',$cdom,$cnum);
+            %elapsed = &Apache::lonlocal::texthash(    
+                                         -1 => 'more than a month ago',
+                                    2592000 => 'within last 30 days',
+                                     604800 => 'within last 7 days',
+                                      86400 => 'within last 24 hours',
+                                   );
+            my $navmap = Apache::lonnavmaps::navmap->new();
+            if (defined($navmap)) {
+                my @allres=$navmap->retrieveResources('/uploaded/'.$cdom.'/'.$cnum.'/default_1261144274.sequence',sub { $_[0]->is_problem() },0);
+                foreach my $resource (@allres) {
+                    my @parts = $resource->parts();
+                    my $count = scalar(@parts);
+                    if ($count > 1) {
+                        $nummultipart{$count} ++;
+                    }
+                    $numparts += $count;
+                }
+                if (keys(%nummultipart) > 0) {
+                   $multipart = '<br />'.'contains';
+                   foreach my $key (sort {$a <=> $b} keys(%nummultipart)) {
+                       $multipart .= " nummultipart{$key} multipart questions (with $key parts)";
+                   }
+                }
+            }
+        }
+    }
+
     # Get groups, role, permanent e-mail so we can sort on them if
     # necessary.
     foreach my $user (keys(%{$userlist})) {
@@ -2663,6 +2726,34 @@
         } else {
             $in{'end'} = &Apache::lonlocal::locallocaltime($in{'end'});
         }
+        if ($context eq 'course') {
+            if ($custommenu) {
+                my $lastlogin = $crslogins{$in{'username'}.':'.$in{'domain'}.':'.$in{'section'}.':'.$role};
+                if ($lastlogin ne '') {
+                    my $sincelogin = $now - $lastlogin;
+                    if ($sincelogin < 86400) {
+                        $in{'lastlogin'} = $elapsed{'86400'};
+                    } elsif ($sincelogin < 604800) {
+                        $in{'lastlogin'} = $elapsed{'604800'};
+                    } elsif ($sincelogin < 2592000 ) {
+                        $in{'lastlogin'} = $elapsed{'2592000'};
+                    } else {
+                        $in{'lastlogin'} = $elapsed{'-1'};
+                    }
+                }
+            }
+            if ($role eq 'st') {
+                my $numsub = $stusubmissions{$in{'username'}.':'.$in{'domain'}."\0attempts"} + 
+                             $stusubmissions{$in{'username'}.':'.$in{'domain'}."\0pilotsubs"};
+                if (!$numsub) {
+                    $in{'submissions'} = 'unattempted';
+                } elsif ($numsub < $numparts) {
+                    $in{'submissions'} = 'incomplete ('.$numsub.'/'.$numparts.')';
+                } else {
+                    $in{'submissions'} = 'completed';
+                }
+            }
+        }
         if ($mode eq 'view' || $mode eq 'html' || $mode eq 'autoenroll' || $mode eq 'pickauthor') {
             $r->print(&Apache::loncommon::start_data_table_row());
             my $checkval;
@@ -2736,19 +2827,27 @@
                         $showitem = $ltstatus{$in{$item}};
                     }
                     $r->print('<td>'.$showitem.'</td>'."\n");
+                } elsif ($item eq 'submissions') {
+                    if ($in{$item} =~ /^incomplete/) { 
+                        $r->print('<td>'.$in{$item}.$multipart.'</td>');
+                    } else {
+                        $r->print('<td>'.$in{$item}.'</td>'."\n");
+                    }
                 } else {
                     $r->print('<td>'.$in{$item}.'</td>'."\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 =
+                    if ($clickersupport) {
+                        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 ($clickers!~/\w/) { $clickers='-'; }
+                            $r->print('<td>'.$clickers.'</td>');
+                        } else {
+                            $r->print('    <td>&nbsp;</td>  ');
+                        }
                     }
                     if ($env{'course.'.$env{'request.course.id'}.'.internal.showphoto'}) {
                         if ($displayphotos eq 'on' && $role eq 'st' && $in{'photo'} ne '') {
@@ -3464,6 +3563,10 @@
     my ($r,$classlist,$nosort,$permission,$crstype) = @_;
     my $cid = $env{'request.course.id'};
     my ($cnum,$cdom) = &get_course_identity($cid);
+    my $displaygroups;
+    unless (&Apache::loncommon::needs_gci_custom()) {
+        $displaygroups = 1;
+    }
     if (! exists($env{'form.sortby'})) {
         &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
                                                 ['sortby']);
@@ -3541,8 +3644,10 @@
     <th>$lt{'sec'}</th>
     <th>$lt{'start'}</th>
     <th>$lt{'end'}</th>
-    <th>$lt{'groups'}</th>
 END
+        if ($displaygroups) {
+            $r->print("    <th>$lt{'groups'}</th>\n");
+        }
         $r->print(&Apache::loncommon::end_data_table_header_row());
     } else  {
         $r->print(&Apache::loncommon::start_data_table().
@@ -3563,10 +3668,13 @@
        <a href="/adm/createuser?action=$action&sortby=start">$lt{'start'}</a>
     </th><th>
        <a href="/adm/createuser?action=$action&sortby=end">$lt{'end'}</a>
-    </th><th>
-       <a href="/adm/createuser?action=$action&sortby=groups">$lt{'groups'}</a>
     </th>
 END
+       if ($displaygroups) {
+           $r->print("<th>
+       <a href=\"/adm/createuser?action=$action&sortby=groups\">$lt{'groups'}</a>
+    </th>\n");
+        }
         $r->print(&Apache::loncommon::end_data_table_header_row());
     }
     #
@@ -3619,8 +3727,10 @@
     <td>$section</td>
     <td>$start $startitem</td>
     <td>$end</td>
-    <td>$active_groups</td>
 END
+        if ($displaygroups) {
+            $r->print("    <td>$active_groups</td>\n");
+        }
         $r->print(&Apache::loncommon::end_data_table_row());
     }
     $r->print(&Apache::loncommon::end_data_table().'<br />');
Index: loncom/interface/lonwhatsnew.pm
diff -u loncom/interface/lonwhatsnew.pm:1.98.2.1 loncom/interface/lonwhatsnew.pm:1.98.2.2
--- loncom/interface/lonwhatsnew.pm:1.98.2.1	Mon Dec 14 22:24:31 2009
+++ loncom/interface/lonwhatsnew.pm	Mon Aug  9 23:39:43 2010
@@ -1,5 +1,5 @@
 #
-# $Id: lonwhatsnew.pm,v 1.98.2.1 2009/12/14 22:24:31 raeburn Exp $
+# $Id: lonwhatsnew.pm,v 1.98.2.2 2010/08/09 23:39:43 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -72,6 +72,7 @@
 			    ['mdc','versionchanges',0],
                             ['vcl','newroles',1],
                             ['vcl','oldroles',1],
+                            ['whn','crslogin',1],
 			    ) {
 	my ($perm,$key,$check_section) = @{ $perm_check };
 	my $scope = $env{'request.course.id'};
@@ -143,6 +144,13 @@
         $r->print(&Apache::lonhtmlcommon::breadcrumbs
             ("What's New?",#'Course_Action_Items_Intervals'
              ));
+    } elsif ($command eq 'chgcrslogininterval' && $checkallowed{'crslogin'}) {
+        &Apache::lonhtmlcommon::add_breadcrumb
+            ({href=>'/adm/whatsnew?command=chgcrslogininterval&amp;refpage='.$refpage,
+              text=>"Change interval"});
+        $r->print(&Apache::lonhtmlcommon::breadcrumbs
+            ("What's New?",#'Course_Action_Items_Intervals'
+             ));
     } else {
         $r->print(&Apache::lonhtmlcommon::breadcrumbs
             ("What's New?",#'Course_Action_Items_Display'
@@ -188,10 +196,17 @@
                    604800 => 'roles which expired since last week',
                     86400 => 'roles which expired since yesterday',
                    );
+    my %crslogins = (
+                       -1 => 'last login for anyone who has ever logged in',
+                  2592000 => 'last login for users in last 30 days',
+                   604800 => 'last login for users in last 7 days',
+                    86400 => 'last login for users in last 24 hours',
+                   );
     my %interval_titles = (
         versions => \%versions,
         newroles => \%newroles,
         oldroles => \%oldroles,
+        crslogin => \%crslogins,
     );
     my %initpage = &Apache::lonlocal::texthash (
                      firstres => "first resource in the $lctype",
@@ -220,6 +235,9 @@
     } elsif (($command eq 'chgoldroleinterval')
              && $checkallowed->{'oldroles'}) {
         &display_interval_config($r,$refpage,\%interval_titles,'oldroles');
+    } elsif (($command eq 'chgcrslogininterval')
+             && $checkallowed->{'crslogin'}) {
+        &display_interval_config($r,$refpage,\%interval_titles,'crslogin'); 
     } else {
         &display_actions_box($r,$command,$refpage,\%threshold_titles,
                         \%interval_titles,\%initpage,$cdom,$crs,$checkallowed);
@@ -245,7 +263,8 @@
     
     my $scripttag;
     unless ($command eq 'chgthreshold' || $command eq 'chginterval' || 
-            $command eq 'chgoldroleinterval' || $command eq 'chgnewroleinterval') {
+            $command eq 'chgoldroleinterval' || 
+            $command eq 'chgnewroleinterval' || $command eq 'chgcrslogininterval') {
        $scripttag = <<"END";
 <script type="text/javascript">
 function change_display(caller,change) {
@@ -264,6 +283,51 @@
         }
         $scripttag.='document.visible.submit();
 }
+
+function togglelogins() {
+    var total = document.visible.logincount.value;
+    var sumrow = document.visible.loginrow.value;
+    if (total == 0) {
+        return;
+    }
+    var showlogindetails = 0;
+    for (var i=0; i<document.visible.logindetails.length; i++) {
+        if (document.visible.logindetails[i].checked) {
+            showlogindetails = document.visible.logindetails[i].value;
+        }
+    }
+    var detval = "none";
+    var sumval = "";
+    if (showlogindetails == 1) {
+        detval = "";
+        sumval = "none";   
+    }
+    for (var j=0; j<total; j++) {
+        var counter = j+1;
+        var itemid = "logindet_"+counter; 
+        personele = document.getElementById(itemid);
+        if (personele != null) {
+            personele.style.display = detval;
+        }
+    }
+    var detheaderele = document.getElementById("logintitledet");
+    if (detheaderele != null) {
+        detheaderele.style.display = detval;
+    }
+    for (var k=0; k<sumrow; k++) {
+        var counter = k+1;
+        var itemid = "loginsum_"+counter;
+        logincatele = document.getElementById(itemid);
+        if (logincatele != null) {
+            logincatele.style.display = sumval;
+        }
+    }
+    var sumheaderele = document.getElementById("logintitlesum");
+    if (sumheaderele != null) {
+        sumheaderele.style.display = sumval;
+    }
+    return;
+}
 </script>
 ';
     }
@@ -316,6 +380,8 @@
     my %expired;
     my $activecount;
     my %activated;
+    my %loggedin;
+    my $logincount;
     my %res_title = ();
     my %show = ();
     my $needitems = 0;
@@ -448,6 +514,20 @@
         $headings{'newroles'} = &mt('Roles for which access to '.$lctype.' has become available since yesterday');
     }
 
+    $timediff{'crslogin'} = $display_settings{$cid.':crslogininterval'};
+    unless (defined($timediff{'crslogin'})) { $timediff{'crslogin'} = 604800; }
+    $interval{'crslogin'} = $interval_titles->{'crslogin'}->{$timediff{'crslogin'}};
+
+    if ($timediff{'crslogin'} == -1) {
+        $headings{'crslogin'} = &mt('Last login for anyone who has ever logged in');
+    } elsif ($timediff{'crslogin'} == 2592000) {
+        $headings{'crslogin'} = &mt('Last login for users in last 30 days');
+    } elsif ($timediff{'crslogin'} == 604800) {
+        $headings{'crslogin'} = &mt('Last login for users in last 7 days');
+    } elsif ($timediff{'crslogin'} == 86400) {
+        $headings{'crslogin'} = &mt('Last login for users in last 24 hours');
+    }
+
     my $now = time;
     if ($timediff{'versions'} == -1) {
         $timediff{'versions'} = time;
@@ -462,8 +542,15 @@
     if ($timediff{'oldroles'} == -1) {
         $timediff{'oldroles'} = time;
     }
+
     my $expiredstart = $now - $timediff{'oldroles'};
 
+    if ($timediff{'crslogin'} == -1) {
+        $timediff{'crslogin'} = time;
+    }
+
+    my $crsloginstart = $now - $timediff{'crslogin'};
+
     my $countunread = $display_settings{$cid.':countunread'};
     unless (defined($countunread)) {
         $countunread = 'on';
@@ -479,7 +566,7 @@
 
     my @actionorder;
     if ($custommenu) {
-        @actionorder = ('coursenormalmail','coursecritmail','newroles','oldroles');
+        @actionorder = ('coursenormalmail','coursecritmail','newroles','oldroles','crslogin');
     } else {
         @actionorder = ('handgrading','haserrors','abovethreshold','versionchanges','coursediscussion','coursenormalmail','coursecritmail','newroles','oldroles');
     }
@@ -520,6 +607,10 @@
     if ($show{'newroles'}) {
         $activecount = &getactivated(\%activated,$activatedstart,'active');
     }
+    if ($show{'crslogin'}) {
+        $logincount = &getloggedin($cdom,$crs,\%loggedin,$crsloginstart);
+    }
+
     $r->print(qq|<a href="javascript:changeAll('hide');">$lt{'hial'}</a>
      &nbsp;&nbsp;<a href="javascript:changeAll('show');">$lt{'shal'}</a>
      <form method="post" name="visible" action="/adm/whatsnew">\n|);
@@ -530,7 +621,7 @@
         }
     }
 
-    $r->print('<input type="hidden" name="refpage" value="'.$refpage.'" /></form><table class="LC_double_column"><tr><td class="LC_left_col">');
+    $r->print('<input type="hidden" name="refpage" value="'.$refpage.'" /><table class="LC_double_column"><tr><td class="LC_left_col">');
 
     my $displayed = 0;
     my $totalboxes = 0;
@@ -551,12 +642,12 @@
             if ($displayed == $halfway) {
                 $r->print('</td><td>&nbsp;</td><td class="LC_right_col" >');
             }
-            &display_launcher($r,$actionitem,$refpage,$checkallowed,\%show,\%headings,\%res_title,\@tograde,\%ungraded,\@bombs,\%bombed,\%changed,\@warnings,\%triggered,\@newdiscussions,\%unread,$msgcount,\@newmsgs,$critmsgcount,\@critmsgs,\%interval,$countunread,\%expired,$expirecount,\%activated,$activecount,$crstype,$itemserror);
+            &display_launcher($r,$actionitem,$refpage,$checkallowed,\%show,\%headings,\%res_title,\@tograde,\%ungraded,\@bombs,\%bombed,\%changed,\@warnings,\%triggered,\@newdiscussions,\%unread,$msgcount,\@newmsgs,$critmsgcount,\@critmsgs,\%interval,$countunread,\%expired,$expirecount,\%activated,$activecount,$crstype,$itemserror,\%loggedin,$logincount);
             $displayed ++; 
         }
     }
     $r->print('
-      </td>
+      </td></form>
     </tr>
    </table>
 ');
@@ -639,6 +730,8 @@
         $r->print('<br />'.&mt('Choose the time window to use to display roles for which access to the '.$lctype.' expired.').'<br />');
     } elsif ($context eq 'newroles') {
         $r->print('<br />'.&mt('Choose the time window to use to display roles for which access to the '.$lctype.' became available.').'<br />');
+    } elsif ($context eq 'crslogin') {
+        $r->print('<br />'.&mt('Choose the time window to use to display the last login by a user in the '.$lctype).'<br />');
     } else {
         $r->print('<br />'.&mt('Choose the time window to use to display resources in the '.$lctype.' with version changes.').'<br />');
     }
@@ -804,7 +897,7 @@
         $tograde,$ungraded,$bombs,$bombed,$changed,$warnings,$triggered,
         $newdiscussions,$unread,$msgcount,$newmsgs,$critmsgcount,$critmsgs,
         $interval,$countunread,$expired,$expirecount,$activated,$activecount,
-        $crstype,$itemserror) = @_;
+        $crstype,$itemserror,$loggedin,$logincount) = @_;
 
     if ($$checkallowed{$action}) {
         &start_box($r,$show,$headings,$action,$refpage,$action);
@@ -831,6 +924,10 @@
             } elsif ($action eq 'oldroles') { # EXPIRED ROLES
                 &display_rolechanges($r,$expirecount,$expired,$interval->{'oldroles'},
                                      $crstype);
+            } elsif ($action eq 'crslogin') { #LAST LOGIN
+                &display_crslogins($r,$logincount,$loggedin,$interval->{'crslogin'},
+                                   $crstype);
+                                     
             }
         }
         &end_box($r);
@@ -1428,6 +1525,39 @@
     return $rolechgcount;
 }
 
+sub getloggedin {
+    my ($cdom,$crs,$lastlogins,$starttime) = @_;
+    my $context = 'course';
+    my ($permission,$allowed) =
+        &Apache::lonuserutils::get_permission($context);
+    my $viewablesec = &Apache::lonuserutils::viewable_section($permission);
+    my %crslogins=&Apache::lonnet::dump('nohist_crslastlogin',$cdom,$crs);
+    my $logincount = 0;
+    my ($tmp) = keys(%crslogins);
+    unless ($tmp =~ /^(con_lost|error|no_such_host)/i) {
+        if (keys(%crslogins) > 0) {
+            foreach my $key (keys(%crslogins)) {
+                my ($uname,$udom,$section,$role) = split(/:/,$key);
+                my $eventtime = $crslogins{$key};
+                if ($eventtime > $starttime) {
+                    if (($viewablesec ne '') && ($section ne '')) {
+                        next if ($viewablesec ne $section);
+                    }
+                    my %chginfo = (
+                                   'section' => $section,
+                                   'uname'   => $uname,
+                                   'udom'    => $udom,
+                                   'role'    => $role,
+                    );
+                    $logincount ++;
+                    push (@{$lastlogins->{$eventtime}},\%chginfo);
+                }
+            }
+        }
+    }
+    return $logincount;
+} 
+
 sub checkversions {
     my ($cdom,$crs,$navmap,$changed,$starttime) = @_;
     my %changes=&Apache::lonnet::dump('versionupdate',$cdom,$crs);
@@ -1684,6 +1814,90 @@
     }
     return;
 }
+
+sub display_crslogins {
+    my ($r,$logincount,$loggedin,$interval,$crstype) = @_;
+    my %lt = &Apache::lonlocal::texthash(
+        'user'   => 'User',
+        'role'   => 'Role',
+        'sec'    => 'Section',
+        'number' => 'Total number of logins',
+    );
+    if ($logincount) {
+        $r->print('<tr class="LC_info_row" style="display:none" id="logintitledet">'.
+                  '<td class="LC_left_item">'.$lt{'user'}.'</td>'.
+                  '<td class="LC_left_item">'.$lt{'role'}.'</td>'.
+                  '<td class="LC_left_item">'.$lt{'sec'}.'</td></tr>'.
+                  '<tr class="LC_info_row" id="logintitlesum">'.
+                  '<td class="LC_left_item">'.$lt{'number'}.'</td>'.
+                  '<td class="LC_left_item">'.$lt{'role'}.'</td>'.
+                  '<td class="LC_left_item">'.$lt{'sec'}.'</td></tr>');
+        my (%bylastname,%counts);
+        if (ref($loggedin) eq 'HASH') {
+            my @logins = sort { $b <=> $a } (keys(%{$loggedin}));
+            my $numlogin = 0;
+            foreach my $item (@logins) {
+                if (ref($loggedin->{$item}) eq 'ARRAY') {
+                    foreach my $user (@{$loggedin->{$item}}) {
+                        if (ref($user) eq 'HASH') {
+                            my $section;
+                            my $role =
+                                &Apache::lonnet::plaintext($user->{'role'},$crstype);
+                            my $status = &mt($user->{'status'});
+                            if ($user->{'section'} eq '') {
+                                $section = &mt('none');
+                            } else {
+                                $section = $user->{'section'};
+                            }
+                            $counts{$user->{'role'}}{$section} ++;
+                            my $uname = $user->{'uname'};
+                            my $udom = $user->{'udom'};
+                            my $fullname = &Apache::loncommon::plainname($uname,$udom,'lastname');
+                            my $link =
+                                &Apache::loncommon::aboutmewrapper($fullname,$uname,$udom);
+                            push(@{$bylastname{$fullname}},
+                                                          '<td>'.$link.'</td>'.
+                                                          '<td>'.$role.'</td>'.
+                                                          '<td>'.$section.'</td>');
+                        }
+                    }
+                }
+            }
+            foreach my $person (sort(keys(%bylastname))) {
+                if (ref($bylastname{$person}) eq 'ARRAY') { 
+                    foreach my $item (@{$bylastname{$person}}) { 
+                        $numlogin ++;
+                        my $css_class = $numlogin%2?' class="LC_odd_row"':'';
+                        $r->print('<tr'.$css_class.' style="display:none;"  id="logindet_'.$numlogin.'">'.$item.'</td></tr>'); 
+                    }
+                }
+            }
+            my $numrow = 0;
+            foreach my $role (sort(keys(%counts))) {
+                my $showrole = &Apache::lonnet::plaintext($role,$crstype);
+                if (ref($counts{$role}) eq 'HASH') { 
+                    foreach my $sec (sort { $b <=> $a } (keys(%{$counts{$role}}))) {
+                        $numrow ++;
+                        my $css_class = $numrow%2?' class="LC_odd_row"':'';
+                        $r->print('<tr '.$css_class.' id="loginsum_'.$numrow.'">'.
+                                  '<td>'.$counts{$role}{$sec}.'</td>'.
+                                  '<td>'.$showrole.'</td>'.
+                                  '<td>'.$sec.'</td></tr>');
+                   }
+                }
+            }
+            $r->print('<input type="hidden" name="logincount" value="'.$numlogin.
+                      '" /><input type="hidden" name="loginrow" value="'.$numrow.
+                      '" />');
+        }
+    } else {
+        $r->print('<tr class="LC_empty_row"><td>'.
+                  &mt('There are no '.$interval).
+                  '<input type="hidden" name="logincount" value="'.$logincount.
+                  '." /></td></tr>');
+    }
+    return;
+}
  
 sub display_coursediscussion {
     my ($r,$newdiscussions,$unread,$countunread,$res_title,$itemserror) = @_;
@@ -1845,6 +2059,8 @@
             $interval_settings{$cid.':oldroleinterval'} = $env{'form.interval'};
         } elsif ($context eq 'newroles') {
             $interval_settings{$cid.':newroleinterval'} = $env{'form.interval'};
+        } elsif ($context eq 'crslogin') {
+            $interval_settings{$cid.':crslogininterval'} = $env{'form.interval'};
         } else {
             $interval_settings{$cid.':interval'} = $env{'form.interval'};
         }
@@ -2000,7 +2216,15 @@
                 <td class="LC_subheader" colspan="2"><a href="/adm/whatsnew?command=chgoldroleinterval&amp;refpage='.$refpage.'">'.$lt{'chin'}.'</a></td>
               </tr>');
          }
+     } elsif (($caller eq 'crslogin') && ($$show{$caller})) {
+         if ($$show{$caller}) {
+             $r->print('
+              <tr>
+                <td class="LC_subheader" align="left"><span class="LC_nobreak"><label><input type="radio" name="logindetails" value="0" checked="checked" onclick="javascript:togglelogins();" />&nbsp;'.&mt('Summary').'</label><label><input type="radio" name="logindetails" value="1" onclick="javascript:togglelogins();" />&nbsp;'.&mt('Details').'</label></span></td><td class="LC_subheader"><a href="/adm/whatsnew?command=chgcrslogininterval&amp;refpage='.$refpage.'">'.$lt{'chin'}.'</a></td>
+              </tr>');
+         }
      }
+
     $r->print('
               <tr>
                <td colspan="2">
Index: loncom/interface/lonmenu.pm
diff -u loncom/interface/lonmenu.pm:1.309.2.13 loncom/interface/lonmenu.pm:1.309.2.14
--- loncom/interface/lonmenu.pm:1.309.2.13	Thu Feb 25 04:21:01 2010
+++ loncom/interface/lonmenu.pm	Mon Aug  9 23:39:43 2010
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA
 # Routines to control the menu
 #
-# $Id: lonmenu.pm,v 1.309.2.13 2010/02/25 04:21:01 raeburn Exp $
+# $Id: lonmenu.pm,v 1.309.2.14 2010/08/09 23:39:43 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -1408,7 +1408,7 @@
                           '<h3 class="LC_hcell">'.&mt('Test Management').'</h3>'.
                           '<table><tr><td align="left"><a href="javascript:gonav('."'/adm/navmaps'".');"><img alt="course contents" src="/res/adm/pages/nav.png" align="left" class="LC_icon" /></a></td><td class="LC_menubuttons_text" colspan="3"><a class="LC_menubuttons_link" href="javascript:gonav('."'/adm/navmaps'".');"><span class="LC_menubuttons_inline_text">Concept Test Contents</span></a></td></tr>'."\n".
                           '<tr><td align="left"><a href="javascript:go('."'/adm/coursedocs'".');"><img alt="assemble test" src="/res/adm/pages/docs.png" align="left" class="LC_icon" /></a></td><td class="LC_menubuttons_text" colspan="3"><a class="LC_menubuttons_link" href="javascript:go('."'/adm/coursedocs'".');"><span class="LC_menubuttons_inline_text">Assemble Concept Test</span></a></td></tr>'."\n".
-                          '<tr><td align="left"><a href="javascript:go('."'/adm/createuser'".');"><img alt="user privs" src="/res/adm/pages/cprv.png" align="left" class="LC_icon" /></a></td><td class="LC_menubuttons_text" colspan="3"><a class="LC_menubuttons_link" href="javascript:go('."'/adm/createuser'".');"><span class="LC_menubuttons_inline_text">'.&mt('Manage Enrollment').'</span></a></td></tr>'."\n".
+                          '<tr><td align="left"><a href="javascript:go('."'/adm/createuser'".');"><img alt="user privs" src="/res/adm/pages/cprv.png" align="left" class="LC_icon" /></a></td><td class="LC_menubuttons_text" colspan="3"><a class="LC_menubuttons_link" href="javascript:go('."'/adm/createuser'".');"><span class="LC_menubuttons_inline_text">'.&mt('Enrollment and Student Activity').'</span></a></td></tr>'."\n".
                          '<tr><td align="left"><a href="javascript:go('."'/adm/whatsnew'".');"><img alt="what is new" src="/res/adm/pages/new.png" align="left" class="LC_icon" /></a></td><td class="LC_menubuttons_text" colspan="3"><a class="LC_menubuttons_link" href="javascript:go('."'/adm/whatsnew'".');"><span class="LC_menubuttons_inline_text">'.&mt("What's New?").'</span></a></td></tr>'.
                          '<tr><td align="left"><a href="javascript:go('."'/adm/printout'".');"><img alt="print concept test" src="/res/adm/pages/prnt.png" align="left" class="LC_icon" /></a></td><td class="LC_menubuttons_text" colspan="3"><a class="LC_menubuttons_link" href="javascript:go('."'/adm/printout'".');"><span class="LC_menubuttons_inline_text">'.&mt("Prepare Printable Concept Test").'</span></a></td></tr>'.
                          '<tr><td align="left"><a href="javascript:go('."'/adm/statistics'".');"><img alt="Test Statistics" src="/res/adm/pages/chrt.png" align="left" class="LC_icon" /></a></td><td class="LC_menubuttons_text" colspan="3"><a class="LC_menubuttons_link" href="javascript:go('."'/adm/statistics'".');"><span class="LC_menubuttons_inline_text">'.&mt("Concept Test Statistics").'</span></a></td></tr></table></div></td>';
Index: loncom/homework/structuretags.pm
diff -u loncom/homework/structuretags.pm:1.461 loncom/homework/structuretags.pm:1.461.2.1
--- loncom/homework/structuretags.pm:1.461	Sun Dec  6 21:18:24 2009
+++ loncom/homework/structuretags.pm	Mon Aug  9 23:39:50 2010
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA 
 # definition of tags that give a structure to a document
 #
-# $Id: structuretags.pm,v 1.461 2009/12/06 21:18:24 raeburn Exp $
+# $Id: structuretags.pm,v 1.461.2.1 2010/08/09 23:39:50 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -654,7 +654,11 @@
 
 sub store_aggregates {
     my ($symb,$courseid) = @_;
-    my %aggregate;
+    my (%aggregate,%subtracker);
+    my $tracksub;
+    if ($symb =~ m{^uploaded/gcitest/$LONCAPA::match_courseid/default_1261144274.sequence___\d+___gci/gci/}) {
+        $tracksub = 1;
+    }
     my @parts;
     my $cdomain = $env{'course.'.$env{'request.course.id'}.'.domain'};
     my $cname = $env{'course.'.$env{'request.course.id'}.'.num'};
@@ -669,6 +673,9 @@
 	    $Apache::lonhomework::results{'resource.'.$part.'.award'}
 	    eq 'EXACT_ANS') {
             $aggregate{$symb."\0".$part."\0correct"} = 1;
+            if ($tracksub) {
+                $subtracker{$env{'user.name'}.':'.$env{'user.domain'}."\0correct"} ++;
+            }
         }
         if ($Apache::lonhomework::results{'resource.'.$part.'.tries'} == 1) {
             $aggregate{$symb."\0".$part."\0users"} = 1;
@@ -681,11 +688,22 @@
             }
         }
         $aggregate{$symb."\0".$part."\0attempts"} = 1;
+        if ($tracksub) {
+            if ($Apache::lonhomework::type eq 'survey') {
+                $subtracker{$env{'user.name'}.':'.$env{'user.domain'}."\0surveysubs"} ++;
+            } else {
+                $subtracker{$env{'user.name'}.':'.$env{'user.domain'}."\0attempts"} ++;
+            }
+        }
     }
     if (keys (%aggregate) > 0) {
 	&Apache::lonnet::cinc('nohist_resourcetracker',\%aggregate,
                             $cdomain,$cname);
     }
+    if (keys(%subtracker) > 0) {
+        &Apache::lonnet::cinc('nohist_submissiontracker',\%subtracker,
+                            $cdomain,$cname);
+    }
 }
 
 sub checkout_msg {
Index: loncom/auth/lonroles.pm
diff -u loncom/auth/lonroles.pm:1.240.2.14 loncom/auth/lonroles.pm:1.240.2.15
--- loncom/auth/lonroles.pm:1.240.2.14	Mon Jan 18 17:16:58 2010
+++ loncom/auth/lonroles.pm	Mon Aug  9 23:39:59 2010
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA
 # User Roles Screen
 #
-# $Id: lonroles.pm,v 1.240.2.14 2010/01/18 17:16:58 raeburn Exp $
+# $Id: lonroles.pm,v 1.240.2.15 2010/08/09 23:39:59 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -455,6 +455,12 @@
                         &Apache::lonnet::appenv({'request.role.adv'=>$tadv});
 			my ($furl,$ferr)=
 			    &Apache::lonuserstate::readmap($cdom.'/'.$cnum);
+                        if ($custommenu) {
+                            unless (($ferr) || ($env{'form.switchrole'})) {
+                                &Apache::lonnet::put('nohist_crslastlogin',{$env{'user.name'}.':'.$env{'user.domain'}.':'.$csec.':'.$role => $now},
+                                                     $cdom,$cnum);
+                            }
+                        }
 			if (($env{'form.orgurl'}) && 
 			    ($env{'form.orgurl'}!~/^\/adm\/flip/)) {
 			    my $dest=$env{'form.orgurl'};

--raeburn1281397199--