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, 2 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

# The LearningOnline Network with CAPA
# Display first access times for timed (interval) items for active
# students in a course.
#
# $Id: lonaccesstimes.pm,v 1.2 2017/01/31 18:55:03 raeburn Exp $
#
# Copyright Michigan State University Board of Trustees
#
# This file is part of the LearningOnline Network with CAPA (LON-CAPA).
#
# LON-CAPA is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# LON-CAPA is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with LON-CAPA; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
#
# /home/httpd/html/adm/gpl.txt
#
# http://www.lon-capa.org/
#
##############################################################
##############################################################

=pod

=head1 NAME

lonaccesstimes - Handler to display first access times for timed (interval) 
items.

=head1 SYNOPSIS

lonaccess times provides an interface for displaying first access times
for timed (interval) items for active students in a course.

=head1 DESCRIPTION

This module is used to display first access times for items in a course 
set when a student pushes "Show Resource" to begin a timed (interval) quiz.

=head1 OVERVIEW

Users with the vgr privilege in a course can use /adm/accesstimes to view
first access times set by users with unexpired student roles in a course,
for all resources or maps for which the interval parameter is set.

The first access is stored when a student pushed the "Show Resource" button
to start the timer to gain access to a timed quiz or exam.

Users with the mgr privilege can use the "Reset Student Access Times" helper
to reset access times, in case of network trouble having prevented a student
from completing a timed quiz/exam.

This module is provided for use by helpdesk staff who may receive the vgr
privilege in a course, but not the mgr privilege, so they can advise students
or faculty who contact the helpdesk on what to do if access to a timed quiz
needs to be provided to a student after the clock has run out.

=head1 INTERNAL SUBROUTINES

=over

=item &print_selectors()

Prints page used to select a single item using the interval parameter, and
one or more enrolled students/members for whom first access times are to
be displayed for that item (specific resource, map, or course-wide).

Inputs: 2 
        $r - Request object.

        $crstype - Course type (either Course or Community).

Outputs: none

Side Effects: prints web page containing items for which timed (interval)
              parameters have been set (use radio buttons to select one),
              and also a table of users with active student roles, with
              checkboxes to select users.

=item &print_results() 

Prints first access times found for specified item (resource, map or course)
and specified students.

Inputs: 2
        $r - Request object.

        $crstype - Course type (either Course or Community).

Outputs: none

Side Effects: prints web page containing first access times.


=back 

=cut

package Apache::lonaccesstimes;

use strict;
use Apache::lonnet;
use Apache::Constants qw(:common :http);
use Apache::loncommon();
use Apache::lonblockingmenu();
use Apache::lonselstudent();
use Apache::lonlocal;
use lib '/home/httpd/lib/perl/';
use LONCAPA qw(:DEFAULT :match);

sub handler {
    my $r = shift;

    &Apache::loncommon::content_type($r,'text/html');
    $r->send_http_header;

    return OK if $r->header_only;

    #  Needs to be in a course
    if (! ($env{'request.course.fn'})) {
        # Not in a course
        $env{'user.error.msg'}=
     "/adm/accesstimes:vgr:0:0:Cannot view first access times for timed items in a course";
        return HTTP_NOT_ACCEPTABLE;
    }

# ----------------------------------------------------------- Permissions check

    unless ((&Apache::lonnet::allowed('vgr',$env{'request.course.id'})) ||
            (&Apache::lonnet::allowed('vgr',$env{'request.course.id'}.
                                      '/'.$env{'request.course.sec'}))) {
        $env{'user.error.msg'}=
     "/adm/setblock:vgr:0:0:Cannot view first access times for timed items in a course";
        return HTTP_NOT_ACCEPTABLE;
    }

# ------------------------------------------------------------------ Breadcrumbs
    &Apache::lonhtmlcommon::clear_breadcrumbs();
    &Apache::lonhtmlcommon::add_breadcrumb
        ({href=>'/adm/parmset',
         text=>'Content and Problem Settings'});
    &Apache::lonhtmlcommon::add_breadcrumb
        ({href=>'/adm/accesstimes',
          text=>'First Access times for timed quizzes/exams'});

    my $phase = $env{'form.phase'};
    my $crstype = &Apache::loncommon::course_type();

# ------------------------------------------------------- Show first access times   
    if ($phase eq 'display') {
        &Apache::lonhtmlcommon::add_breadcrumb
        ({href=>'/adm/accesstimes',
          text=>'Results'});
        $r->print(
            &Apache::loncommon::start_page('Display first access times').
            &Apache::lonhtmlcommon::breadcrumbs('First access times'));
        &print_results($r,$crstype);
    } else {
        my $js = &Apache::lonblockingmenu::details_javascript();
        $r->print(
            &Apache::loncommon::start_page('Filters for first access times',$js).
            &Apache::lonhtmlcommon::breadcrumbs('First access times'));
        &print_selectors($r,$crstype);
    }
    $r->print(&Apache::loncommon::end_page());
    return OK;
}

sub print_selectors {
    my ($r,$crstype) = @_;

# ------------------------------------------------------ Retrieve active students

    my ($course_personnel,
        $current_members,
        $expired_members,
        $future_members) =
            &Apache::lonselstudent::get_people_in_class($env{'request.course.sec'});

# ---------------------------------------------------- Get Time Limit parameters

    my %intervals = &Apache::lonblockingmenu::get_timed_items();

# ------------------------------------------------------------- Display selectors
 
    $r->print('<form name="accessform" method="post" action="/adm/accesstimes">'); 

    if ((ref($current_members) eq 'ARRAY') && (@{$current_members} > 0) && (keys(%intervals) > 0)) {
        my %titles = &Apache::lonlocal::texthash(
                        'intervals' => 'Select timed interval setting (for course, folder or resource)', 
                        'active'    => 'Select from currently enrolled students',
                    );
        if ($crstype eq 'Community') {
            $titles{'active'} = &mt('Select from current community members');
        }

        if ($env{'request.course.sec'}) {
            $titles{'active'} = &mt('Select from currently enrolled students in section: [_1]',
                                    $env{'request.course.sec'});
            if ($crstype eq 'Community') {
                $titles{'active'} = &mt('Select from current community members in section: [_1]',
                                        $env{'request.course.sec'});
            }
        }
        my $navmap = Apache::lonnavmaps::navmap->new();

        if (!ref($navmap)) {
            $r->print('<p class="LC_error">'.&mt('Failed to retrieve course contents').'</p>');
        } else {
            my $parmcount = 0;
            $r->print('<h4>'.$titles{'intervals'}.'</h4>'.
                      &Apache::lonblockingmenu::create_interval_form(\%intervals,$parmcount,$navmap,'accesstimes').
                      '<hr />');
            my %default;
            $r->print(
                  '<h4>'.$titles{'active'}.'</h4>'.
                  &Apache::lonselstudent::render_student_list( $current_members,
                                                               'accessform',
                                                               'current',
                                                               \%default,1,'firstaccess',1,
                                                               'accesstimes'));
        }
        $r->print('<input type="hidden" name="phase" value="display" />'.
                  '<input type="submit" name="display" value="'.&mt('Display First Access Times').'" />');
    } else {
        if ((ref($current_members) eq 'ARRAY') && (@{$current_members} == 0)) {
            if ($env{'request.course.sec'}) {
                if ($crstype eq 'Community') {
                    $r->print('<p class="LC_info">'.&mt('No current community members in section [_1]',
                                                        $env{'request.course.sec'}).'</p>');
                } else {
                    $r->print('<p class="LC_info">'.&mt('No students currently enrolled in section [_1]',
                                                        $env{'request.course.sec'}).'</p>');
                }
            } else {
                if ($crstype eq 'Community') {
                    $r->print('<p class="LC_info">'.&mt('No current community members').'</p>');
                } else {
                    $r->print('<p class="LC_info">'.&mt('No students currently enrolled').'</p>');
                }
            }
        }
        if (keys(%intervals) == 0) {
            $r->print('<p class="LC_info">'.&mt('No timed interval settings currently apply to course, folder(s) or resource(s)').'</p>');
        }
    }
    $r->print('</form>');
}

sub print_results {
    my ($r,$crstype) = @_;
    my $usertype = &Apache::lonnet::plaintext('st',$crstype);
    my $item = $env{'form.firstaccess_0'};
    my $title;
    if ($item ne '') {
        my $symb;
        if ($item =~ /\.(sequence|page)$/) {
            if (&Apache::lonnet::is_on_map($item)) {
                my $navmap = Apache::lonnavmaps::navmap->new();
                if (ref($navmap)) {
                    my $mapres = $navmap->getResourceByUrl($item);
                    if (ref($mapres)) {
                        $symb = $mapres->symb();
                        $title = $mapres->compTitle();
                    } else {
                        $title = &Apache::lonnet::gettitle($item);
                    }
                    my ($path,$hierarchy);
                    $hierarchy = &Apache::lonblockingmenu::show_timer_path('map',$item,$navmap);
                    if ($hierarchy) {
                        $path = ' <span style="font-size:90%;">'.
                                &mt('(in: [_1])',$hierarchy).
                                '</span>';
                    }
                    $title = &mt('Timer for all items in folder: [_1]',
                                 '<i>'.$title.'</i>').$path;
                } else {
                    $r->print('<p class="LC_warning">'.&mt('Could not find time interval setting for selected item').'</p>');
                }
            } else {
                $r->print('<p class="LC_warning">'.&mt('Could not find time interval setting for selected item').'</p>');
            }
        } elsif ($item eq 'course') {
            $symb = $item; 
            $title = &mt('Timer for all items in course');
        } else {
            my $navmap = Apache::lonnavmaps::navmap->new();
            if (ref($navmap)) {
                my $resobj = $navmap->getBySymb($item);
                my ($path,$hierarchy);
                if (ref($resobj)) {
                    $symb = $item;
                    $title = $resobj->compTitle();
                }
                if ($title eq '') {   
                    $title = &Apache::lonnet::gettitle($item);
                }
                $hierarchy = &Apache::lonblockingmenu::show_timer_path('resource',$item,$navmap);
                if ($hierarchy) {
                    $path = ' <span style="font-size:90%;">'.
                            &mt('(in: [_1])',$hierarchy).
                            '</span>';
                }
                $title = &mt('Timer for resource: [_1]','<i>'.$title.'</i>').
                         $path;
            }
        }
        if ($symb) {
            if ($title) { 
                $r->print('<h3>'.$title.'</h3>');
            }
            my @students = &Apache::loncommon::get_env_multiple('form.firstaccess_forminput');
            if (@students) {
                my ($course_personnel,
                    $current_members,
                    $expired_members,
                    $future_members) =
                        &Apache::lonselstudent::get_people_in_class($env{'request.course.sec'});
                my %active;
                if (ref($current_members) eq 'ARRAY') {
                    map { $active{$_->[0]} = 1; } @{$current_members}; 
                }
                my (@hasaccess,@noaccess);
                my $key=$env{'request.course.id'}."\0".$symb;
                foreach my $name (sort(@students)) {
                    my ($uname,$udom,$sec,$fullname)=split(':',$name);
                    next unless ($active{$uname.':'.$udom});
                    if (!$fullname) { $fullname="$uname:$udom"; }
                    my %times=&Apache::lonnet::get('firstaccesstimes',
                                                   [$key],$udom,$uname);
                    if (!$times{$key}) {
                        push(@noaccess,[$name,$fullname]);
                    } else {
                        push(@hasaccess,[$name,$fullname,$times{$key}]);
                    }
                }
                if ((@hasaccess == 0) && (@noaccess == 0)) {
                    $r->print('<p class="LC_warning">'.&mt('No valid users selected to check for first access times').'</p>');
                } else {
                    if (@hasaccess > 0) {
                        $r->print('<h4>'.&mt("Access times found for [quant,_1,$usertype]",scalar(@hasaccess)).'</h4>'.
                                  '<p>'.&Apache::loncommon::start_data_table().
                                  &Apache::loncommon::start_data_table_header_row().
                                  '<th>'.&mt('User').'</th><th>'.&mt('Fullname').'</th>'.
                                  '<th>'.&mt('First access time').'</th>'.
                                  &Apache::loncommon::end_data_table_header_row());
                        foreach my $item (@hasaccess) {
                            if (ref($item) eq 'ARRAY') {
                                $r->print(&Apache::loncommon::start_data_table_row().
                                          '<td>'.$item->[0].'</td>'.
                                          '<td>'.$item->[1].'</td>'.
                                          '<td>'.&Apache::lonlocal::locallocaltime($item->[2]).'</td>'.
                                          &Apache::loncommon::start_data_table_row());
                            }
                        }
                        $r->print(&Apache::loncommon::end_data_table().'</p>');
                    }
                    if (@noaccess > 0) {
                        $r->print('<h4>'.&mt("No access times found for [quant,_1,$usertype]",scalar(@noaccess)).'</h4>'.
                                  '<p>'.&Apache::loncommon::start_data_table().
                                  &Apache::loncommon::start_data_table_header_row().
                                  '<th>'.&mt('User').'</th><th>'.&mt('Fullname').'</th>'.
                                  &Apache::loncommon::end_data_table_header_row());
                        foreach my $item (@noaccess) {
                            if (ref($item) eq 'ARRAY') {
                                $r->print(&Apache::loncommon::start_data_table_row().
                                          '<td>'.$item->[0].'</td>'.
                                          '<td>'.$item->[1].'</td>'.
                                          &Apache::loncommon::start_data_table_row());
                            }
                        }
                        $r->print(&Apache::loncommon::end_data_table().'</p>');
                    }
                }
            } else {
                if ($crstype eq 'Community') {
                    $r->print('<p class="LC_warning">'.&mt('No members selected to check for first access times').'</p>');
                } else {
                    $r->print('<p class="LC_warning">'.&mt('No students selected to check for first access times').'</p>');
                }
            }
        } else {
            $r->print('<p class="LC_warning">'.&mt('Could not find time interval setting for selected item').'</p>');
        }
    } else {
        $r->print('<p class="LC_warning">'.&mt('No item selected to check for first access times').'</p>');
    }
    return;
}

1;

__END__

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