# The LearningOnline Network # Request a course # # $Id: lonrequestcourse.pm,v 1.28 2009/09/05 20:24:15 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/ # ### =head1 NAME Apache::lonrequestcourse.pm =head1 SYNOPSIS Allows users to request creation of new courses. This is part of the LearningOnline Network with CAPA project described at http://www.lon-capa.org. =head1 SUBROUTINES =over =item handler() =item get_breadcrumbs() =item header() =item form_elements() =item onload_action() =item check_can_request() =item course_types() =item print_main_menu() =item request_administration() =item close_popup_form() =item get_instcode() =item print_request_form() =item print_enrollment_menu() =item show_invalid_crosslists() =item inst_section_selector() =item date_setting_table() =item print_personnel_menu() =item print_request_status() =item print_request_logs() =item print_review() =item dates_from_form() =item courseinfo_form() =item clone_form() =item clone_text() =item coursecode_form() =item get_course_dom() =item display_navbuttons() =item print_request_outcome() =item get_processtype() =item check_autolimit() =item retrieve_settings() =item get_request_settings() =item extract_instcode() =item generate_date_items() =back =cut package Apache::lonrequestcourse; use strict; use Apache::Constants qw(:common :http); use Apache::lonnet; use Apache::loncommon; use Apache::lonlocal; use Apache::loncoursequeueadmin; use LONCAPA qw(:DEFAULT :match); sub handler { my ($r) = @_; &Apache::loncommon::content_type($r,'text/html'); $r->send_http_header; if ($r->header_only) { return OK; } &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'}, ['action','showdom','cnum','state']); &Apache::lonhtmlcommon::clear_breadcrumbs(); my $dom = &get_course_dom(); my $action = $env{'form.action'}; my $state = $env{'form.state'}; my (%states,%stored); my ($jscript,$uname,$udom,$result,$warning); $states{'display'} = ['details']; $states{'view'} = ['pick_request','details','cancel','removal']; $states{'log'} = ['filter','display']; $states{'new'} = ['courseinfo','enrollment','personnel','review','process']; if (($action eq 'new') && ($env{'form.crstype'} eq 'official')) { unless ($env{'form.state'} eq 'crstype') { unshift(@{$states{'new'}},'codepick'); } } foreach my $key (keys(%states)) { if (ref($states{$key}) eq 'ARRAY') { unshift (@{$states{$key}},'crstype'); } } my @invalidcrosslist; my %trail = ( crstype => 'Course Request Action', codepick => 'Category', courseinfo => 'Description', enrollment => 'Access Dates', personnel => 'Personnel', review => 'Review', process => 'Result', pick_request => 'Display Summary', details => 'Request Details', cancel => 'Cancel Request', removal => 'Outcome', ); if (($env{'form.crstype'} eq 'official') && (&Apache::lonnet::auto_run('',$dom))) { $trail{'enrollment'} = 'Enrollment'; } my ($page,$crumb,$newinstcode,$codechk,$checkedcode) = &get_breadcrumbs($dom,$action,\$state,\%states,\%trail); if ($action eq 'display') { if (($dom eq $env{'request.role.domain'}) && (&Apache::lonnet::allowed('ccc',$dom))) { my $namespace = 'courserequestqueue'; if ($env{'form.cnum'} ne '') { my $cnum = $env{'form.cnum'}; my $reqkey = $cnum.'_approval'; my $namespace = 'courserequestqueue'; my $domconfig = &Apache::lonnet::get_domainconfiguser($dom); my %queued = &Apache::lonnet::get($namespace,[$reqkey],$dom,$domconfig); if (ref($queued{$reqkey}) eq 'HASH') { $uname = $queued{$reqkey}{'ownername'}; $udom = $queued{$reqkey}{'ownerdom'}; if (($udom =~ /^$match_domain$/) && ($uname =~ /^$match_username$/)) { $result = &retrieve_settings($dom,$cnum,$udom,$uname); } else { $warning = &mt('Invalid username or domain for course requestor'); } } else { $warning = &mt('No information was found for this course request.'); } } else { $warning = &mt('No course request ID provided.'); } } else { $warning = &mt('You do not have rights to view course request information.'); } } elsif ((defined($state)) && (defined($action))) { if (($action eq 'view') && ($state eq 'details')) { if ((defined($env{'form.showdom'})) && (defined($env{'form.cnum'}))) { my $result = &retrieve_settings($env{'form.showdom'},$env{'form.cnum'}); } } elsif ($env{'form.crstype'} eq 'official') { if (&Apache::lonnet::auto_run('',$dom)) { if (($action eq 'new') && (($state eq 'enrollment') || ($state eq 'personnel'))) { my $checkcrosslist = 0; for (my $i=0; $i<$env{'form.crosslisttotal'}; $i++) { if ($env{'form.crosslist_'.$i}) { $checkcrosslist ++; } } if ($checkcrosslist) { my %codechk; my (@codetitles,%cat_titles,%cat_order,@code_order,$lastitem); &Apache::lonnet::auto_possible_instcodes($dom,\@codetitles, \%cat_titles, \%cat_order, \@code_order); my $numtitles = scalar(@codetitles); if ($numtitles) { for (my $i=0; $i<$env{'form.crosslisttotal'}; $i++) { if ($env{'form.crosslist_'.$i}) { my $codecheck; my $crosslistcode = ''; foreach my $item (@code_order) { $crosslistcode .= $env{'form.crosslist_'.$i.'_'.$item}; } if ($crosslistcode ne '') { $codechk{$i} = &Apache::lonnet::auto_validate_instcode('',$dom,$crosslistcode); } unless ($codechk{$i} eq 'valid') { $env{'form.crosslist_'.$i} = ''; push(@invalidcrosslist,$crosslistcode); } } } } } } } } my %elements = &form_elements($dom); my $elementsref = {}; if (ref($elements{$action}) eq 'HASH') { if (ref($elements{$action}{$state}) eq 'HASH') { $elementsref = $elements{$action}{$state}; } } if (($state eq 'courseinfo') && ($env{'form.clonedom'} eq '')) { $env{'form.clonedom'} = $dom; } $jscript = &Apache::lonhtmlcommon::set_form_elements($elementsref,\%stored); } if ($state eq 'personnel') { $jscript .= "\n".&Apache::loncommon::userbrowser_javascript(); } my $loaditems = &onload_action($action,$state); my %can_request; my $canreq = &check_can_request($dom,\%can_request); if ($action eq 'new') { if ($canreq) { if ($state eq 'crstype') { &print_main_menu($r,\%can_request,\%states,$dom,$jscript,$loaditems, $crumb); } else { &request_administration($r,$action,$state,$page,\%states,$dom, $jscript,$loaditems,$crumb,$newinstcode, $codechk,$checkedcode,\@invalidcrosslist); } } else { $r->print(&header('Course Requests').$crumb. '
'.&mt('Username').' '.$uname_form.' | '."\n".
''.&mt('Domain').' '.$udom_form.' | |
'.&mt('First Name').' '.$form_elems{'firstname'}.' | '."\n".
''.&mt('Last Name').' '.$form_elems{'lastname'}.' | '."\n".
''.&mt('E-mail').' '.$form_elems{'emailaddr'}.' |
'.&mt('Role').' '.$roleselector.' | '."\n".
''.&mt('Section(s)').' '.$sectionselector.' | '."\n".
'
'.&Apache::loncommon::start_data_table(). &Apache::loncommon::start_data_table_header_row(). '
'. &mt('Institutional section').' | '. ''.&mt('LON-CAPA section').' |
---|---|
'.$env{'form.secnum_'.$i}.' | '; if ($env{'form.loncapasec_'.$i} ne '') { $secinfo .= $env{'form.loncapasec_'.$i}; } else { $secinfo .= &mt('None'); } $secinfo .= ' |
'.&mt('None').' |
'. &mt('Institutional course/section').' | '. ''.&mt('LON-CAPA section').' |
---|---|
'; if (ref($code_order) eq 'ARRAY') { if (@{$code_order} > 0) { foreach my $item (@{$code_order}) { $xlistinfo .= $env{'form.crosslist_'.$i.'_'.$item}; } } } $xlistinfo .= $env{'form.crosslist_'.$i.'_instsec'}.' | '; if ($env{'form.crosslist_'.$i.'_lcsec'}) { $xlistinfo .= $env{'form.crosslist_'.$i.'_lcsec'}; } else { $xlistinfo .= &mt('None'); } $xlistinfo .= ' |
'.&mt('None').' |
'.&mt('Name').' | '. ''.&mt('Username:Domain').' | '. ''.&mt('E-mail address').' | '. '
---|---|---|
'.$ownername.' | '.$owner.' | '. ''.$owneremail.' | '. '
'.&mt('Include?').' '. ' | ';
}
foreach my $title (@{$codetitles}) {
if (ref($cat_order->{$title}) eq 'ARRAY') {
if (@{$cat_order->{$title}} > 0) {
$output .= ''.$title.' '."\n". ' | '."\n";
}
}
if ($context eq 'crosslist') {
$output .= ''.$lastitem.' '."\n". $lastinput.' | '.$instsec.' | '. ''.$lcsec.' |
'.$lastitem.' '.$lastinput.' | '.
''.$instsec.' | '.$lcsec.' | '. '
'. ''.&mt('Include?'). ''. ' | '.&mt('Institutional ID').' '. ''. ' | '.$lcsec.' |
'.&mt('Your course request has been processed and the course has been created.').
'
'.$role_result.'
'.&mt('Your course request has been updated').'
'. ¬ification_information($disposition,$req_notifylist,$cnum,$now); } if ($validationerror ne '') { $output .= ''.&mt('An error occurred validating your request with institutional data sources: [_1].',$validationerror).''; } } if ($creationresult ne '') { return ($creationresult,$output); } else { return ($storeresult,$output); } } sub update_requestors_roles { my ($dom,$cnum,$crstype,$details,$longroles) = @_; my $now = time; my ($active,$future,$numactive,$numfuture,$output); my $owner = $env{'user.name'}.':'.$env{'user.domain'}; if (ref($details) eq 'HASH') { if (ref($details->{'personnel'}) eq 'HASH') { if (ref($details->{'personnel'}{$owner}) eq 'HASH') { my @roles; if (ref($details->{'personnel'}{$owner}{'roles'}) eq 'ARRAY') { @roles = sort(@{$details->{'personnel'}{$owner}{'roles'}}); unless (grep(/^cc$/,@roles)) { push(@roles,'cc'); } } else { @roles = ('cc'); } foreach my $role (@roles) { my $start = $now; my $end = '0'; if ($role eq 'st') { if ($details->{'accessstart'} ne '') { $start = $details->{'accessstart'}; } if ($details->{'accessend'} ne '') { $end = $details->{'accessend'}; } } my @usecs; if ($role ne 'cc') { if (ref($details->{'personnel'}{$owner}{$role}{'usec'}) eq 'ARRAY') { @usecs = @{$details->{'personnel'}{$owner}{$role}{'usec'}}; } } if ($role eq 'st') { if (@usecs > 1) { my $firstsec = $usecs[0]; @usecs = ($firstsec); } } if (@usecs == 0) { push(@usecs,''); } foreach my $usec (@usecs) { my (%userroles,%newrole,%newgroups,$spec,$area); my $area = '/'.$dom.'/'.$cnum; my $spec = $role.'.'.$area; if ($usec ne '') { $spec .= '/'.$usec; $area .= '/'.$usec; } if ($role =~ /^cr\//) { &Apache::lonnet::custom_roleprivs(\%newrole,$role,$dom, $cnum,$spec,$area); } else { &Apache::lonnet::standard_roleprivs(\%newrole,$role,$dom, $spec,$cnum,$area); } &Apache::lonnet::set_userprivs(\%userroles,\%newrole, \%newgroups); $userroles{'user.role.'.$spec} = $start.'.'.$end; &Apache::lonnet::appenv(\%userroles,[$role,'cm']); if (($end == 0) || ($end > $now)) { my $showrole = $role; if ($role =~ /^cr\//) { $showrole = &Apache::lonnet::plaintext($role,$crstype); } elsif (ref($longroles) eq 'HASH') { if ($longroles->{$role} ne '') { $showrole = $longroles->{$role}; } } if ($start <= $now) { $active .= '