File:  [LON-CAPA] / loncom / interface / lonpickcourse.pm
Revision 1.52: download - view: text, annotated - select for diffs
Tue Jul 11 02:28:22 2006 UTC (17 years, 10 months ago) by raeburn
Branches: MAIN
CVS tags: HEAD
Bug 4813.  Retain backwards compatibility with legacy courses in which only a course owner's username is stored in environment.internal.courseowner, and in the course's record in nohist_courseids.db.  New courses will include username:domain (escaped) in nohist_courseids.db.  MCRS can be used to update legacy course owner information (just click "Modify Settings" button, it will be necessary to select the correct course owner where the course domain is different from the owner's domain.

# The LearningOnline Network
# Pick a course
#
# $Id: lonpickcourse.pm,v 1.52 2006/07/11 02:28:22 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/
#

package Apache::lonpickcourse;

use strict;
use Apache::Constants qw(:common);
use Apache::loncommon;
use Apache::loncoursedata;
use Apache::lonnet;
use Apache::lonlocal;
use Apache::longroup;
use lib '/home/httpd/lib/perl/';
use LONCAPA;

sub handler {
    my $r = shift;
    &Apache::loncommon::content_type($r,'text/html');
    $r->send_http_header;
    return OK if $r->header_only;

# ------------------------------------------------------------ Print the screen

# Get parameters from query string
    &Apache::loncommon::get_unprocessed_cgi
        ($ENV{'QUERY_STRING'},['domainfilter','descriptfilter',
			       'sincefilter','form','cnumelement',
			       'cdomelement','cnameelement','roleelement',
                               'pickedcourse','instcodefilter',
                               'ownerfilter','coursefilter','multiple',
                               'type','ownerdomfilter']);
# domain filter and selection
    my $domainfilter=$env{'form.domainfilter'};
    $domainfilter=~s/\W//g;
    unless ($domainfilter) { $domainfilter=''; }
    my $domainselectform=&Apache::loncommon::select_dom_form($domainfilter,
                                                          'domainfilter',1);
# description filter
    my $descriptfilter=$env{'form.descriptfilter'};
    unless ($descriptfilter) { $descriptfilter=''; }
    my $listdescript=&HTML::Entities::encode($descriptfilter,'<>&"');
# institutional code filter
    my $instcodefilter=$env{'form.instcodefilter'};
    unless ($instcodefilter) { $instcodefilter=''; }
    my $listinstcode=&HTML::Entities::encode($instcodefilter,'<>&"');
# course owner filter
    my $ownerfilter=$env{'form.ownerfilter'};
    $ownerfilter=~s/\W//g;
    my $listowner=&HTML::Entities::encode($ownerfilter,'<>&"');
# course ownerdomain filter
    my $ownerdomfilter=$env{'form.ownerdomfilter'};
    $ownerdomfilter=~s/\W//g;
    my $ownerdomselectform=
       &Apache::loncommon::select_dom_form($ownerdomfilter,'ownerdomfilter',1);
# course ID filter for DCs only
    my ($courseidtag,$coursefilter);
    if ($env{'user.adv'} && $domainfilter && exists($env{'user.role.dc./'.
                        $domainfilter.'/'})) {
        $coursefilter=$env{'form.coursefilter'};
        unless ($coursefilter) { $coursefilter=''; }
        my $listcourseid=&HTML::Entities::encode($coursefilter,'<>&"');
        $courseidtag = &mt('LON-CAPA course ID');
        $courseidtag .= qq|: <input type="text" name="coursefilter" size="25" value="$listcourseid" />
        <br />
        |;
    }
# last course activity filter and selection
    my $sincefilter=$env{'form.sincefilter'};
    $sincefilter=~s/[^\d-]//g;
    unless ($sincefilter) { $sincefilter=-1; }
    my $sincefilterform=&Apache::loncommon::select_form($sincefilter,
       'sincefilter',('-1'=>'',
                      '86400' => 'today',
                      '604800' => 'last week',
                      '2592000' => 'last month',
                      '7776000' => 'last three months',
                      '15552000' => 'last six months',
                      '31104000' => 'last year',
                      'select_form_order' =>
                      ['-1','86400','604800','2592000','7776000',
		      '15552000','31104000']));
# if called from loncreateuser, report sections, then close
    my (%loaditem,$seclist,$groupslist,$roleslist,$rolesnameslist,
	$accesslist,$accessnameslist);
    my $sec_element = 'currsec';
    my $grplist_element = 'groups';
    my $num_sections = 0;
    my $num_groups = 0;
    my $num_roles = 0;
    my $num_access = 0;
    my ($cdom,$cnum);
    if ($env{'form.pickedcourse'}) {
        ($cdom,$cnum) = split/_/,$env{'form.pickedcourse'};
    }
    my $type = $env{'form.type'};
    if (!defined($env{'form.type'})) {
        $type = 'Course';
    }
    if ($env{'form.form'} eq 'cu' && $env{'form.pickedcourse'}) {
        $loaditem{'onload'} ="setSections()";
        ($seclist,$num_sections,$groupslist,$num_groups) = 
             &build_selection_lists($cdom,$cnum,$type,undef,undef,
                                    $env{'form.form'});
    }
# if called from portfolio, report roles, sections, groups and close
    my ($roles_element,$groups_element,$status_element,$setitems_function);
    if ($env{'form.form'} eq 'portform' && $env{'form.pickedcourse'}) {
        my ($row_id) = ($env{'form.cnumelement'} =~ /^crsnum_(\d+)$/);
        $roles_element = 'role_'.$row_id.'_1';
        $groups_element = 'group_'.$row_id.'_1';
        $sec_element = 'section_'.$row_id.'_1';
        $status_element = 'access_'.$row_id.'_1';
        $grplist_element = 'grplist_'.$row_id.'_1';
        $loaditem{'onload'} ="setItems()";
        ($seclist,$num_sections,$groupslist,$num_groups,$roleslist,$num_roles,
         $rolesnameslist,$accesslist,$num_access,$accessnameslist) =
               &build_selection_lists($cdom,$cnum,$type,1,1,$env{'form.form'});
        $setitems_function = qq|
function setItems() {
    opener.document.$env{"form.form"}.activate.checked = true;
    setRoles();
    setGroups();
    setStatus();
    setSections();
}

function setRoles() {
    var numRoles = $num_roles
    var rolesArray = new Array("$roleslist");
    var roleNamesArray = new Array("$rolesnameslist");
    opener.document.$env{"form.form"}.$roles_element.length = 0;
    if (numRoles == 0) {
        opener.document.$env{"form.form"}.$roles_element.multiple=false;
        opener.document.$env{"form.form"}.$roles_element.size=1;
        opener.document.$env{"form.form"}.$roles_element.options[0] = new Option('No existing roles','',false,false);
    } else {
        if (numRoles == 1) {
            opener.document.$env{"form.form"}.$roles_element.multiple=false;
            opener.document.$env{"form.form"}.$roles_element.size=1;
            opener.document.$env{"form.form"}.$roles_element.options[0] = new Option('Select','',true,true);
            opener.document.$env{"form.form"}.$roles_element.options[1] = new Option(roleNamesArray[0],rolesArray[0],false,false);
        } else {
            for (var i=0; i<numRoles; i++) {
                opener.document.$env{"form.form"}.$roles_element.options[i] = new Option(roleNamesArray[i],rolesArray[i],false,false);
            }
            opener.document.$env{"form.form"}.$roles_element.multiple=true;
            if (numRoles < 3) {
                opener.document.$env{"form.form"}.$roles_element.size=numRoles;
            } else {
                opener.document.$env{"form.form"}.$roles_element.size=3;
            }
            opener.document.$env{"form.form"}.$roles_element.options[0].selected = false;
        }
    }
}

function setStatus() {
    var numStatus = $num_access;
    var statusArray = new Array("$accesslist");
    var statusNamesArray = new Array("$accessnameslist");
    opener.document.$env{"form.form"}.$status_element.multiple=true;
    opener.document.$env{"form.form"}.$status_element.size=3;
    for (var i=0; i<numStatus; i++) {
        opener.document.$env{"form.form"}.$status_element.options[i] = new Option(statusNamesArray[i],statusArray[i],false,false);
    }
}

function setGroups() {
    var numGroups = $num_groups;
    var groupsArray = new Array("$groupslist");
    opener.document.$env{"form.form"}.$groups_element.length = 0;
    if (numGroups == 0) {
        opener.document.$env{"form.form"}.$groups_element.multiple=false;
        opener.document.$env{"form.form"}.$groups_element.size=1;
        opener.document.$env{"form.form"}.$groups_element.options[0] = new Option('No existing groups','',false,false);
    } else {
        if (numGroups == 1) {
            opener.document.$env{"form.form"}.$groups_element.multiple=false;
            opener.document.$env{"form.form"}.$groups_element.size=1;
            opener.document.$env{"form.form"}.$groups_element.options[0] = new Option('Select','',true,true);
            opener.document.$env{"form.form"}.$groups_element.options[1] = new Option('No group','',false,false);
            opener.document.$env{"form.form"}.$groups_element.options[2] = new Option(groupsArray[0],groupsArray[0],false,false);
        } else {
            for (var i=0; i<numGroups; i++) {
                opener.document.$env{"form.form"}.$groups_element.options[i] = new Option(groupsArray[i],groupsArray[i],false,false);
            }
            opener.document.$env{"form.form"}.$groups_element.multiple=true;
            if (numGroups < 3) {
                opener.document.$env{"form.form"}.$groups_element.size=numGroups;
            } else {
                opener.document.$env{"form.form"}.$groups_element.size=3;
            }
            opener.document.$env{"form.form"}.$groups_element.options[0].selected = false;
        }
    }
}

|;
    }
    my $jscript;
    my $typeselectform =  '<select name="type" size="1"';
    $typeselectform .= ">\n";
    foreach my $posstype ('Course','Group') { 
        $typeselectform.='<option value="'.$posstype.'" "'.
            ($posstype eq $type ? 'selected="selected" ' : ''). ">$posstype</option>\n";
    }
    $typeselectform.="</select>";
    my $title = &mt('Selecting a [_1]',$type);
# Setup for multiple course selections, if flag for multiples set.
    my $multiple = $env{'form.multiple'};
    my $multelement;
    if ($multiple) {
        $title = &mt('Selecting [_1](s)',lc($type));
        $jscript = &Apache::loncommon::check_uncheck_jscript();
        $multelement = '<input type="hidden" name="multiple" value="'.$multiple.'" />';
    }
    $r->print(&Apache::loncommon::start_page($title,undef,
					     {'add_entries' => \%loaditem,
					      'no_nav_bar'  => 1, }));
    my %lt = (
	      'cac' => &mt('[_1] Activity',$type),
	      'cde' => &mt('[_1] Description',$type),
	      'cdo' => &mt('[_1] Domain',$type),
              'cin' => &mt('Course Institutional Code'),
              'cow' => &mt("[_1] Owner's Username",$type),
              'cod' => &mt("[_1] Owner's Domain", $type),
              'cog' => &mt('Course or Group')
             );
   
    my ($name_code,$name_input);
    if (defined($env{'form.cnameelement'}) && $env{'form.cnameelement'} ne '') {
	$name_code = "opener.document.$env{'form.form'}.$env{'form.cnameelement'}.value=cdesc;";
	$name_input ='<input type="hidden" name="cnameelement" value="'.
	    $env{'form.cnameelement'}.'" />';
    }
    my $submitopener = '';
    my $autosubmit = '';
    my $roleelement = '';
    my $lastaction = 'self.close()';
    if ($env{'form.form'} eq 'cu') {
        $lastaction = 'document.courselist.pickedcourse.value = cdom+"_"+cname;'."\n".
                      'document.courselist.submit();';
    }
    if ($env{'form.form'} eq 'portform') {
        $lastaction = 'document.courselist.pickedcourse.value = cdom+"_"+cname;'."\n".
                      'document.courselist.submit();';
    }
    my $roledom = $env{'form.roleelement'};
    if ($roledom) {
        $roleelement = '<input type="hidden" name="roleelement" value="'.$roledom.'" />';
        $submitopener = &Apache::lonroles::processpick();
        $autosubmit = 'process_pick("'.$roledom.'")';
    }
    my $instcodeform;
    if ($type eq 'Course') {
        $instcodeform = $lt{'cin'}.': <input type="text" name="instcodefilter" 
 size="10" value="'.$listinstcode.'" /><br />';
    }
    my %elements = (
                     Course => {
                                 name  => 'coursepick',
                                 total => 'coursetotal',
                                 list  => 'courselist',
                               },
                     Group => {
                                 name  => 'grouppick',
                                 total => 'grouptotal',
                                 list  => 'grouplist',
                             },
                    );

    $r->print(<<ENDSCRIPT);
<script>
function gochoose(cname,cdom,cdesc,multiple,caller) {
    var openerForm = "$env{'form.form'}";
    courseCount = 0;
    var courses = '';
    if (multiple) {
	if (typeof(document.courselist.course_id.length) == 'undefined') {
	    // only 1 course checkbox was created
	    if (document.courselist.course_id.checked) {
		courses = courses + document.courselist.course_id.value + "&&";
		courseCount ++;
	    }
	} else {
	    for (var j=0; j<document.courselist.course_id.length; j++) {
		if (document.courselist.course_id[j].checked) {
		    courses = courses + document.courselist.course_id[j].value + "&&";
		    courseCount ++;
		}
	    }
	} 
        opener.document.$env{'form.form'}.$elements{$type}{'total'}.value = courseCount;
	if (typeof(opener.document.$env{'form.form'}.$elements{$type}{'name'}.length) ==
	    'undefined') {
	    if (opener.document.$env{'form.form'}.$elements{$type}{'name'}.value == 'specific') {  
		opener.document.$env{'form.form'}.$elements{$type}{'name'}.checked = true;
	    } else {
		opener.document.$env{'form.form'}.$elements{$type}{'name'}.checked = false;
	    }
	} else {
	    for (var j=0; j<opener.document.$env{'form.form'}.$elements{$type}{'name'}.length; j++) { 
		if (opener.document.$env{'form.form'}.$elements{$type}{'name'}\[j].value == 'specific') {  
		    opener.document.$env{'form.form'}.$elements{$type}{'name'}\[j].checked = true;
		} else {
		    opener.document.$env{'form.form'}.$elements{$type}{'name'}\[j].checked = false;
		}
	    }
	}
	if (courseCount > 0) {
	    courses = courses.substr(0,courses.length-2);
	    opener.document.$env{'form.form'}.$elements{$type}{'list'}.value = courses;
	}
    } else {
        $name_code
        opener.document.$env{'form.form'}.$env{'form.cnumelement'}.value=cname;
        var slct=opener.document.$env{'form.form'}.$env{'form.cdomelement'};
        if (slct.options == undefined) {
            opener.document.$env{'form.form'}.$env{'form.cdomelement'}.value=cdom;
        }
        else {
            var i;
            for (i=0;i<slct.length;i++) {
                if (slct.options[i].value==cdom) { slct.selectedIndex=i; }
            }
        }
    }
    $autosubmit
    $lastaction
}

function setSections() {
    var numSections = $num_sections
    var sectionsArray = new Array("$seclist")
    opener.document.$env{"form.form"}.$sec_element.length = 0
    if (numSections == 0) {
        opener.document.$env{"form.form"}.$sec_element.multiple=false
        opener.document.$env{"form.form"}.$sec_element.size=1;
        opener.document.$env{"form.form"}.$sec_element.options[0] = new Option('No existing sections','',false,false)
    } else {
        if (numSections == 1) {
            opener.document.$env{"form.form"}.$sec_element.multiple=false;
            opener.document.$env{"form.form"}.$sec_element.size=1;
            opener.document.$env{"form.form"}.$sec_element.options[0] = new Option('Select','',true,true);
            opener.document.$env{"form.form"}.$sec_element.options[1] = new Option('No section','',false,false) 
            opener.document.$env{"form.form"}.$sec_element.options[2] = new Option(sectionsArray[0],sectionsArray[0],false,false);
        } else {
            for (var i=0; i<numSections; i++) {
                opener.document.$env{"form.form"}.$sec_element.options[i] = new Option(sectionsArray[i],sectionsArray[i],false,false)
            }
            opener.document.$env{"form.form"}.$sec_element.multiple=true
            if (numSections < 3) {
                opener.document.$env{"form.form"}.$sec_element.size=numSections;
            } else {
                opener.document.$env{"form.form"}.$sec_element.size=3;
            }
            opener.document.$env{"form.form"}.$sec_element.options[0].selected = false
        }
    }
    opener.document.$env{"form.form"}.$grplist_element.value='$groupslist';
    self.close()
}

$setitems_function

$jscript
</script>
$submitopener
<form method="post" name="filterpicker" action="/adm/pickcourse">
<input type="hidden" name="cnumelement" value="$env{'form.cnumelement'}" />
<input type="hidden" name="cdomelement" value="$env{'form.cdomelement'}" />
$name_input
<input type="hidden" name="form" value="$env{'form.form'}" />
$roleelement
$multelement
$lt{'cac'}: $sincefilterform
<br />
$lt{'cdo'}: $domainselectform
<br />
$lt{'cog'}: $typeselectform
<br />
$instcodeform
$lt{'cow'}:
<input type="text" name="ownerfilter" size="10" value="$listowner" />
<br />
$lt{'cod'}: $ownerdomselectform
<br />
$courseidtag
$lt{'cde'}:
<input type="text" name="descriptfilter" size="40" value="$listdescript" />
<p><input type="submit" name="gosearch" value="Search" /></p>
</form>
<hr />
ENDSCRIPT
# ---------------------------------------------------------------- Get the data
    if ($env{'form.gosearch'}) {
        $r->print(&mt('Searching').' ...<br />&nbsp;<br />');
        $r->rflush();
	unless ($descriptfilter) { $descriptfilter='.'; }
        unless ($instcodefilter) { $instcodefilter='.'; }
        my $combownerfilter;
        if (($ownerfilter ne '') || ($ownerdomfilter ne '')) {
            $combownerfilter = $ownerfilter.':'.$ownerdomfilter;
        }
        if ($combownerfilter eq '') { $combownerfilter='.'; }
        if ($coursefilter eq '') { $coursefilter='.'; }
        if ($type eq '') { $type = '.'; }
        my $timefilter=($sincefilter==-1?1:time-$sincefilter);
	my %courses = &Apache::lonnet::courseiddump($domainfilter,$descriptfilter,
                                     $timefilter,$instcodefilter,$combownerfilter,
                                     $coursefilter,undef,undef,$type);
	$r->print('<form name="courselist" method="post" action="/adm/pickcourse">');
	my %by_descrip;
        my $numcourses = keys(%courses);
	foreach my $course (keys(%courses)) {
            my $descr;
            if ($courses{$course} =~ m/^([^:]*):/i) {
                $descr = &unescape($1);
            } else {
                $descr = &unescape($courses{$course});
            }
            my $description = $descr;
            push (@{$by_descrip{$description}}, $course);
	}
        if ($numcourses > 1 && $multiple) {
            $r->print('<input type="button" value="check all"
                    onclick="javascript:checkAll(document.courselist.course_id)" />                    &nbsp;&nbsp;<input type="button" value="uncheck all"
                    onclick="javascript:uncheckAll(document.courselist.course_id)" />
                    <br /><br />');
        }
	foreach my $description (sort 
				 { lc($a) cmp lc($b) } (keys(%by_descrip))) {
            foreach my $course (@{$by_descrip{$description}}) {
	        my $cleandesc=&HTML::Entities::encode($description,'<>&"');
	        $cleandesc=~s/'/\\'/g;
	        my ($cdom,$cnum)=split(/\_/,$course);
                my ($descr,$instcode,$owner,$ttype) = split/:/,$courses{$course};
                $r->print(&course_chooser($multiple,$cdom,$cnum,$cleandesc));
	        $r->print($description.'('.
		      ($Apache::lonnet::domaindescription{$cdom}?
                       $Apache::lonnet::domaindescription{$cdom}:$cdom).")");
                unless ($instcode eq '') {
                    $r->print(" - ".&unescape($instcode));
                }
                unless ($owner eq '') {
                    $r->print(", owner - ".&unescape($owner));
                }
                unless ($ttype eq '') {
                    $r->print('('.&Apache::lonnet::unescape($ttype).')');
                }
		if ($multiple) { $r->print("</label>\n"); }
                $r->print("<br />\n");
            }
	}
	if (!%courses) { 
            $r->print(&mt('None found'));
        } elsif ($multiple) {
            $r->print('<input type="button" value="Submit" onClick="gochoose('."'','','',1)".'" />');
        }
        $r->print('<input type="hidden" name="form" value="'.$env{'form.form'}.'" />'."\n".
                   '<input type="hidden" name="pickedcourse" value="" />'."\n".
                   '<input type="hidden" name="cnumelement" value="'.$env{'form.cnumelement'}.'" />'."\n".
                   '<input type="hidden" name="cdomelement" value="'.$env{'form.cdomelement'}.'" />'."\n".
                   '<input type="hidden" name="type" value="'.$type.'" />'."\n");
        if ((exists($env{'form.roleelement'})) && ($env{'form.form'} eq 'rolechoice')) {
           $r->print('<input type="hidden" name="roleelement" value="'.$env{'form.roleelement'}.'" />'."\n");
        }
        $r->print("</form>\n");
    }
    $r->print(&Apache::loncommon::end_page());
    return OK;
}

sub course_chooser {
    my ($multiple,$cdom,$cnum,$cleandesc) = @_;
    my $output; 
    if ($multiple) {
        $output = '<label><input type="checkbox" name="course_id" value="'.$cdom.'_'.$cnum.'" />'."\n";
    } else {
        $output = '<input type="button" value="Select" onClick="gochoose('.
                  "'".$cnum."','".$cdom."','".$cleandesc."')".'" />'."\n";
    }
    return $output;
}

sub build_selection_lists {
    my ($cdom,$cnum,$type,$needroles,$needaccess,$caller) = @_;
    my ($sections,$groups,$allroles,$roleshash,$accesshash) = 
          &Apache::loncommon::get_secgrprole_info($cdom,$cnum,$needroles,$type);
    if ($caller eq 'portform') {
        if (@{$sections} == 0) {
            @{$sections} = ('none');
        } else {
            unshift(@{$sections},('all','none'));
        }
        if (@{$groups} == 0) {
            @{$groups} = ('none');
        } else {
            unshift(@{$groups},('all','none'));
        }

    } 
    my $num_sections = scalar(@{$sections});
    my $seclist = join('","',@{$sections});
    my $num_groups = scalar(@{$groups});
    my $groupslist = join('","',@{$groups});
    my ($roleslist,$num_roles,$rolesnameslist,$num_access,$accesslist,
        $accessnameslist);
    if ($needroles) {
        $num_roles = @{$allroles};
        $roleslist = join('","',@{$allroles});
        my @allrolesnames; 
        foreach my $role (@{$allroles}) {
            push(@allrolesnames,$$roleshash{$role});
        }  
        $rolesnameslist = join('","',@allrolesnames);
    }
    if ($needaccess) {
        $num_access = keys(%{$accesshash});
        my (@allaccess,@allaccessnames);
        foreach my $key (sort(keys(%{$accesshash}))) {
            push(@allaccess,$key);
            push(@allaccessnames,$$accesshash{$key}); 
        }
        $accesslist = join('","',@allaccess);
        $accessnameslist = join('","',@allaccessnames);
    }
    return ($seclist,$num_sections,$groupslist,$num_groups,$roleslist,
            $num_roles,$rolesnameslist,$accesslist,$num_access,$accessnameslist);
}

1;
__END__

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