File:  [LON-CAPA] / loncom / interface / lonaccesstimes.pm
Revision 1.2: download - view: text, annotated - select for diffs
Tue Jan 31 18:55:03 2017 UTC (7 years, 3 months ago) by raeburn
Branches: MAIN
CVS tags: version_2_12_X, version_2_11_X, version_2_11_4_uiuc, version_2_11_4_msu, version_2_11_4, version_2_11_3_uiuc, version_2_11_3_msu, version_2_11_3, version_2_11_2_uiuc, version_2_11_2_msu, version_2_11_2_educog, version_2_11_2, HEAD
- Remove unused code (previously commented out).
- Include full path to &show_timer_path() in lonblockingmenu.pm

    1: # The LearningOnline Network with CAPA
    2: # Display first access times for timed (interval) items for active
    3: # students in a course.
    4: #
    5: # $Id: lonaccesstimes.pm,v 1.2 2017/01/31 18:55:03 raeburn Exp $
    6: #
    7: # Copyright Michigan State University Board of Trustees
    8: #
    9: # This file is part of the LearningOnline Network with CAPA (LON-CAPA).
   10: #
   11: # LON-CAPA is free software; you can redistribute it and/or modify
   12: # it under the terms of the GNU General Public License as published by
   13: # the Free Software Foundation; either version 2 of the License, or
   14: # (at your option) any later version.
   15: #
   16: # LON-CAPA is distributed in the hope that it will be useful,
   17: # but WITHOUT ANY WARRANTY; without even the implied warranty of
   18: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   19: # GNU General Public License for more details.
   20: #
   21: # You should have received a copy of the GNU General Public License
   22: # along with LON-CAPA; if not, write to the Free Software
   23: # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   24: #
   25: # /home/httpd/html/adm/gpl.txt
   26: #
   27: # http://www.lon-capa.org/
   28: #
   29: ##############################################################
   30: ##############################################################
   31: 
   32: =pod
   33: 
   34: =head1 NAME
   35: 
   36: lonaccesstimes - Handler to display first access times for timed (interval) 
   37: items.
   38: 
   39: =head1 SYNOPSIS
   40: 
   41: lonaccess times provides an interface for displaying first access times
   42: for timed (interval) items for active students in a course.
   43: 
   44: =head1 DESCRIPTION
   45: 
   46: This module is used to display first access times for items in a course 
   47: set when a student pushes "Show Resource" to begin a timed (interval) quiz.
   48: 
   49: =head1 OVERVIEW
   50: 
   51: Users with the vgr privilege in a course can use /adm/accesstimes to view
   52: first access times set by users with unexpired student roles in a course,
   53: for all resources or maps for which the interval parameter is set.
   54: 
   55: The first access is stored when a student pushed the "Show Resource" button
   56: to start the timer to gain access to a timed quiz or exam.
   57: 
   58: Users with the mgr privilege can use the "Reset Student Access Times" helper
   59: to reset access times, in case of network trouble having prevented a student
   60: from completing a timed quiz/exam.
   61: 
   62: This module is provided for use by helpdesk staff who may receive the vgr
   63: privilege in a course, but not the mgr privilege, so they can advise students
   64: or faculty who contact the helpdesk on what to do if access to a timed quiz
   65: needs to be provided to a student after the clock has run out.
   66: 
   67: =head1 INTERNAL SUBROUTINES
   68: 
   69: =over
   70: 
   71: =item &print_selectors()
   72: 
   73: Prints page used to select a single item using the interval parameter, and
   74: one or more enrolled students/members for whom first access times are to
   75: be displayed for that item (specific resource, map, or course-wide).
   76: 
   77: Inputs: 2 
   78:         $r - Request object.
   79: 
   80:         $crstype - Course type (either Course or Community).
   81: 
   82: Outputs: none
   83: 
   84: Side Effects: prints web page containing items for which timed (interval)
   85:               parameters have been set (use radio buttons to select one),
   86:               and also a table of users with active student roles, with
   87:               checkboxes to select users.
   88: 
   89: =item &print_results() 
   90: 
   91: Prints first access times found for specified item (resource, map or course)
   92: and specified students.
   93: 
   94: Inputs: 2
   95:         $r - Request object.
   96: 
   97:         $crstype - Course type (either Course or Community).
   98: 
   99: Outputs: none
  100: 
  101: Side Effects: prints web page containing first access times.
  102: 
  103: 
  104: =back 
  105: 
  106: =cut
  107: 
  108: package Apache::lonaccesstimes;
  109: 
  110: use strict;
  111: use Apache::lonnet;
  112: use Apache::Constants qw(:common :http);
  113: use Apache::loncommon();
  114: use Apache::lonblockingmenu();
  115: use Apache::lonselstudent();
  116: use Apache::lonlocal;
  117: use lib '/home/httpd/lib/perl/';
  118: use LONCAPA qw(:DEFAULT :match);
  119: 
  120: sub handler {
  121:     my $r = shift;
  122: 
  123:     &Apache::loncommon::content_type($r,'text/html');
  124:     $r->send_http_header;
  125: 
  126:     return OK if $r->header_only;
  127: 
  128:     #  Needs to be in a course
  129:     if (! ($env{'request.course.fn'})) {
  130:         # Not in a course
  131:         $env{'user.error.msg'}=
  132:      "/adm/accesstimes:vgr:0:0:Cannot view first access times for timed items in a course";
  133:         return HTTP_NOT_ACCEPTABLE;
  134:     }
  135: 
  136: # ----------------------------------------------------------- Permissions check
  137: 
  138:     unless ((&Apache::lonnet::allowed('vgr',$env{'request.course.id'})) ||
  139:             (&Apache::lonnet::allowed('vgr',$env{'request.course.id'}.
  140:                                       '/'.$env{'request.course.sec'}))) {
  141:         $env{'user.error.msg'}=
  142:      "/adm/setblock:vgr:0:0:Cannot view first access times for timed items in a course";
  143:         return HTTP_NOT_ACCEPTABLE;
  144:     }
  145: 
  146: # ------------------------------------------------------------------ Breadcrumbs
  147:     &Apache::lonhtmlcommon::clear_breadcrumbs();
  148:     &Apache::lonhtmlcommon::add_breadcrumb
  149:         ({href=>'/adm/parmset',
  150:          text=>'Content and Problem Settings'});
  151:     &Apache::lonhtmlcommon::add_breadcrumb
  152:         ({href=>'/adm/accesstimes',
  153:           text=>'First Access times for timed quizzes/exams'});
  154: 
  155:     my $phase = $env{'form.phase'};
  156:     my $crstype = &Apache::loncommon::course_type();
  157: 
  158: # ------------------------------------------------------- Show first access times   
  159:     if ($phase eq 'display') {
  160:         &Apache::lonhtmlcommon::add_breadcrumb
  161:         ({href=>'/adm/accesstimes',
  162:           text=>'Results'});
  163:         $r->print(
  164:             &Apache::loncommon::start_page('Display first access times').
  165:             &Apache::lonhtmlcommon::breadcrumbs('First access times'));
  166:         &print_results($r,$crstype);
  167:     } else {
  168:         my $js = &Apache::lonblockingmenu::details_javascript();
  169:         $r->print(
  170:             &Apache::loncommon::start_page('Filters for first access times',$js).
  171:             &Apache::lonhtmlcommon::breadcrumbs('First access times'));
  172:         &print_selectors($r,$crstype);
  173:     }
  174:     $r->print(&Apache::loncommon::end_page());
  175:     return OK;
  176: }
  177: 
  178: sub print_selectors {
  179:     my ($r,$crstype) = @_;
  180: 
  181: # ------------------------------------------------------ Retrieve active students
  182: 
  183:     my ($course_personnel,
  184:         $current_members,
  185:         $expired_members,
  186:         $future_members) =
  187:             &Apache::lonselstudent::get_people_in_class($env{'request.course.sec'});
  188: 
  189: # ---------------------------------------------------- Get Time Limit parameters
  190: 
  191:     my %intervals = &Apache::lonblockingmenu::get_timed_items();
  192: 
  193: # ------------------------------------------------------------- Display selectors
  194:  
  195:     $r->print('<form name="accessform" method="post" action="/adm/accesstimes">'); 
  196: 
  197:     if ((ref($current_members) eq 'ARRAY') && (@{$current_members} > 0) && (keys(%intervals) > 0)) {
  198:         my %titles = &Apache::lonlocal::texthash(
  199:                         'intervals' => 'Select timed interval setting (for course, folder or resource)', 
  200:                         'active'    => 'Select from currently enrolled students',
  201:                     );
  202:         if ($crstype eq 'Community') {
  203:             $titles{'active'} = &mt('Select from current community members');
  204:         }
  205: 
  206:         if ($env{'request.course.sec'}) {
  207:             $titles{'active'} = &mt('Select from currently enrolled students in section: [_1]',
  208:                                     $env{'request.course.sec'});
  209:             if ($crstype eq 'Community') {
  210:                 $titles{'active'} = &mt('Select from current community members in section: [_1]',
  211:                                         $env{'request.course.sec'});
  212:             }
  213:         }
  214:         my $navmap = Apache::lonnavmaps::navmap->new();
  215: 
  216:         if (!ref($navmap)) {
  217:             $r->print('<p class="LC_error">'.&mt('Failed to retrieve course contents').'</p>');
  218:         } else {
  219:             my $parmcount = 0;
  220:             $r->print('<h4>'.$titles{'intervals'}.'</h4>'.
  221:                       &Apache::lonblockingmenu::create_interval_form(\%intervals,$parmcount,$navmap,'accesstimes').
  222:                       '<hr />');
  223:             my %default;
  224:             $r->print(
  225:                   '<h4>'.$titles{'active'}.'</h4>'.
  226:                   &Apache::lonselstudent::render_student_list( $current_members,
  227:                                                                'accessform',
  228:                                                                'current',
  229:                                                                \%default,1,'firstaccess',1,
  230:                                                                'accesstimes'));
  231:         }
  232:         $r->print('<input type="hidden" name="phase" value="display" />'.
  233:                   '<input type="submit" name="display" value="'.&mt('Display First Access Times').'" />');
  234:     } else {
  235:         if ((ref($current_members) eq 'ARRAY') && (@{$current_members} == 0)) {
  236:             if ($env{'request.course.sec'}) {
  237:                 if ($crstype eq 'Community') {
  238:                     $r->print('<p class="LC_info">'.&mt('No current community members in section [_1]',
  239:                                                         $env{'request.course.sec'}).'</p>');
  240:                 } else {
  241:                     $r->print('<p class="LC_info">'.&mt('No students currently enrolled in section [_1]',
  242:                                                         $env{'request.course.sec'}).'</p>');
  243:                 }
  244:             } else {
  245:                 if ($crstype eq 'Community') {
  246:                     $r->print('<p class="LC_info">'.&mt('No current community members').'</p>');
  247:                 } else {
  248:                     $r->print('<p class="LC_info">'.&mt('No students currently enrolled').'</p>');
  249:                 }
  250:             }
  251:         }
  252:         if (keys(%intervals) == 0) {
  253:             $r->print('<p class="LC_info">'.&mt('No timed interval settings currently apply to course, folder(s) or resource(s)').'</p>');
  254:         }
  255:     }
  256:     $r->print('</form>');
  257: }
  258: 
  259: sub print_results {
  260:     my ($r,$crstype) = @_;
  261:     my $usertype = &Apache::lonnet::plaintext('st',$crstype);
  262:     my $item = $env{'form.firstaccess_0'};
  263:     my $title;
  264:     if ($item ne '') {
  265:         my $symb;
  266:         if ($item =~ /\.(sequence|page)$/) {
  267:             if (&Apache::lonnet::is_on_map($item)) {
  268:                 my $navmap = Apache::lonnavmaps::navmap->new();
  269:                 if (ref($navmap)) {
  270:                     my $mapres = $navmap->getResourceByUrl($item);
  271:                     if (ref($mapres)) {
  272:                         $symb = $mapres->symb();
  273:                         $title = $mapres->compTitle();
  274:                     } else {
  275:                         $title = &Apache::lonnet::gettitle($item);
  276:                     }
  277:                     my ($path,$hierarchy);
  278:                     $hierarchy = &Apache::lonblockingmenu::show_timer_path('map',$item,$navmap);
  279:                     if ($hierarchy) {
  280:                         $path = ' <span style="font-size:90%;">'.
  281:                                 &mt('(in: [_1])',$hierarchy).
  282:                                 '</span>';
  283:                     }
  284:                     $title = &mt('Timer for all items in folder: [_1]',
  285:                                  '<i>'.$title.'</i>').$path;
  286:                 } else {
  287:                     $r->print('<p class="LC_warning">'.&mt('Could not find time interval setting for selected item').'</p>');
  288:                 }
  289:             } else {
  290:                 $r->print('<p class="LC_warning">'.&mt('Could not find time interval setting for selected item').'</p>');
  291:             }
  292:         } elsif ($item eq 'course') {
  293:             $symb = $item; 
  294:             $title = &mt('Timer for all items in course');
  295:         } else {
  296:             my $navmap = Apache::lonnavmaps::navmap->new();
  297:             if (ref($navmap)) {
  298:                 my $resobj = $navmap->getBySymb($item);
  299:                 my ($path,$hierarchy);
  300:                 if (ref($resobj)) {
  301:                     $symb = $item;
  302:                     $title = $resobj->compTitle();
  303:                 }
  304:                 if ($title eq '') {   
  305:                     $title = &Apache::lonnet::gettitle($item);
  306:                 }
  307:                 $hierarchy = &Apache::lonblockingmenu::show_timer_path('resource',$item,$navmap);
  308:                 if ($hierarchy) {
  309:                     $path = ' <span style="font-size:90%;">'.
  310:                             &mt('(in: [_1])',$hierarchy).
  311:                             '</span>';
  312:                 }
  313:                 $title = &mt('Timer for resource: [_1]','<i>'.$title.'</i>').
  314:                          $path;
  315:             }
  316:         }
  317:         if ($symb) {
  318:             if ($title) { 
  319:                 $r->print('<h3>'.$title.'</h3>');
  320:             }
  321:             my @students = &Apache::loncommon::get_env_multiple('form.firstaccess_forminput');
  322:             if (@students) {
  323:                 my ($course_personnel,
  324:                     $current_members,
  325:                     $expired_members,
  326:                     $future_members) =
  327:                         &Apache::lonselstudent::get_people_in_class($env{'request.course.sec'});
  328:                 my %active;
  329:                 if (ref($current_members) eq 'ARRAY') {
  330:                     map { $active{$_->[0]} = 1; } @{$current_members}; 
  331:                 }
  332:                 my (@hasaccess,@noaccess);
  333:                 my $key=$env{'request.course.id'}."\0".$symb;
  334:                 foreach my $name (sort(@students)) {
  335:                     my ($uname,$udom,$sec,$fullname)=split(':',$name);
  336:                     next unless ($active{$uname.':'.$udom});
  337:                     if (!$fullname) { $fullname="$uname:$udom"; }
  338:                     my %times=&Apache::lonnet::get('firstaccesstimes',
  339:                                                    [$key],$udom,$uname);
  340:                     if (!$times{$key}) {
  341:                         push(@noaccess,[$name,$fullname]);
  342:                     } else {
  343:                         push(@hasaccess,[$name,$fullname,$times{$key}]);
  344:                     }
  345:                 }
  346:                 if ((@hasaccess == 0) && (@noaccess == 0)) {
  347:                     $r->print('<p class="LC_warning">'.&mt('No valid users selected to check for first access times').'</p>');
  348:                 } else {
  349:                     if (@hasaccess > 0) {
  350:                         $r->print('<h4>'.&mt("Access times found for [quant,_1,$usertype]",scalar(@hasaccess)).'</h4>'.
  351:                                   '<p>'.&Apache::loncommon::start_data_table().
  352:                                   &Apache::loncommon::start_data_table_header_row().
  353:                                   '<th>'.&mt('User').'</th><th>'.&mt('Fullname').'</th>'.
  354:                                   '<th>'.&mt('First access time').'</th>'.
  355:                                   &Apache::loncommon::end_data_table_header_row());
  356:                         foreach my $item (@hasaccess) {
  357:                             if (ref($item) eq 'ARRAY') {
  358:                                 $r->print(&Apache::loncommon::start_data_table_row().
  359:                                           '<td>'.$item->[0].'</td>'.
  360:                                           '<td>'.$item->[1].'</td>'.
  361:                                           '<td>'.&Apache::lonlocal::locallocaltime($item->[2]).'</td>'.
  362:                                           &Apache::loncommon::start_data_table_row());
  363:                             }
  364:                         }
  365:                         $r->print(&Apache::loncommon::end_data_table().'</p>');
  366:                     }
  367:                     if (@noaccess > 0) {
  368:                         $r->print('<h4>'.&mt("No access times found for [quant,_1,$usertype]",scalar(@noaccess)).'</h4>'.
  369:                                   '<p>'.&Apache::loncommon::start_data_table().
  370:                                   &Apache::loncommon::start_data_table_header_row().
  371:                                   '<th>'.&mt('User').'</th><th>'.&mt('Fullname').'</th>'.
  372:                                   &Apache::loncommon::end_data_table_header_row());
  373:                         foreach my $item (@noaccess) {
  374:                             if (ref($item) eq 'ARRAY') {
  375:                                 $r->print(&Apache::loncommon::start_data_table_row().
  376:                                           '<td>'.$item->[0].'</td>'.
  377:                                           '<td>'.$item->[1].'</td>'.
  378:                                           &Apache::loncommon::start_data_table_row());
  379:                             }
  380:                         }
  381:                         $r->print(&Apache::loncommon::end_data_table().'</p>');
  382:                     }
  383:                 }
  384:             } else {
  385:                 if ($crstype eq 'Community') {
  386:                     $r->print('<p class="LC_warning">'.&mt('No members selected to check for first access times').'</p>');
  387:                 } else {
  388:                     $r->print('<p class="LC_warning">'.&mt('No students selected to check for first access times').'</p>');
  389:                 }
  390:             }
  391:         } else {
  392:             $r->print('<p class="LC_warning">'.&mt('Could not find time interval setting for selected item').'</p>');
  393:         }
  394:     } else {
  395:         $r->print('<p class="LC_warning">'.&mt('No item selected to check for first access times').'</p>');
  396:     }
  397:     return;
  398: }
  399: 
  400: 1;
  401: 
  402: __END__

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>