--- loncom/interface/loncreatecourse.pm 2017/01/22 19:46:46 1.158.2.3
+++ loncom/interface/loncreatecourse.pm 2019/07/25 20:23:52 1.171
@@ -1,7 +1,7 @@
# The LearningOnline Network
# Create a course
#
-# $Id: loncreatecourse.pm,v 1.158.2.3 2017/01/22 19:46:46 raeburn Exp $
+# $Id: loncreatecourse.pm,v 1.171 2019/07/25 20:23:52 raeburn Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -82,7 +82,11 @@ use Apache::lonlocal;
use Apache::lonuserutils;
use Apache::lonclonecourse;
use LONCAPA::batchcreatecourse;
-use LONCAPA;
+use LONCAPA qw(:DEFAULT :match);
+
+my $registered_flush;
+my $registered_instcats;
+my $modified_dom;
# ===================================================== Phase one: fill-in form
@@ -91,6 +95,8 @@ sub print_course_creation_page {
my $crstype = 'Community';
if ($env{'form.phase'} eq 'courseone') {
$crstype = 'Course';
+ } elsif ($env{'form.phase'} eq 'placementone') {
+ $crstype = 'Placement';
}
my $defdom=$env{'request.role.domain'};
my %domdefaults = &Apache::lonnet::get_domain_defaults($defdom);
@@ -104,7 +110,8 @@ sub print_course_creation_page {
$course_home .= qq{>$server $host_servers{$server}};
}
$course_home .= "\n\n";
- my $domform = &Apache::loncommon::select_dom_form($defdom,'ccdomain');
+ my ($trusted,$untrusted) = &Apache::lonnet::trusted_domains('enroll',$defdom);
+ my $domform = &Apache::loncommon::select_dom_form($defdom,'ccdomain',undef,undef,undef,$trusted,$untrusted);
my $cloneform=&Apache::loncommon::select_dom_form
($env{'request.role.domain'},'clonedomain').
&Apache::loncommon::selectcourse_link
@@ -116,7 +123,7 @@ sub print_course_creation_page {
my $endtime = time+(6*30*24*60*60); # 6 months from now, approx
my $access_table = &Apache::lonuserutils::date_setting_table($starttime,
$endtime,'create_defaultdates');
- if ($crstype eq 'Course') {
+ if (($crstype eq 'Course') || ($crstype eq 'Placement')) {
$enroll_table = &Apache::lonuserutils::date_setting_table($starttime,
$endtime,'create_enrolldates');
($krbdef,$krbdefdom) =
@@ -215,6 +222,7 @@ function validate(formname) {
'cgrq' => 'Set a quota for the total disk space available for storage of course group portfolio files',
'opco' => 'Open Course',
'opcm' => 'Open Community',
+ 'oppt' => 'Open Placement Test',
);
$lt{'kaut'} = &mt('Key authority ([_1]id:domain[_2]) if other than course','','');
$lt{'toin'} = &mt('to interface with institutional data, e.g., [_1]fs13glg231[_2] for [_3]Fall 2013 Geology 231[_4]','','','','');
@@ -246,6 +254,18 @@ function validate(formname) {
$lt{'cc'} = &mt('(will be assigned Coordinator role)');
$lt{'cgrs'} = &mt('Community Group Settings');
$lt{'cgrq'} = &mt('Set a quota for the total disk space available for storage of community group portfolio files');
+ } elsif ($crstype eq 'Placement') {
+ $lt{'cinf'} = &mt('Placement Test Information');
+ $lt{'ctit'} = &mt('Placement Test Title');
+ $lt{'chsr'} = &mt('Placement Test Home Server');
+ $lt{'cidn'} = &mt('Placement Test ID/Number');
+ $lt{'crco'} = &mt('Placement Test Content');
+ $lt{'cncr'} = &mt('Completely new placement test');
+ $lt{'cecr'} = &mt('Clone an existing placement test');
+ $lt{'sacr'} = &mt('Do NOT generate as standard placement test');
+ $lt{'stco'} = &mt('standard placement tests only');
+ $lt{'navi'} = &mt('Placement Test Contents');
+ $lt{'cid'} = &mt('Placement Test ID');
}
my $js = <'.$lt{'iinf'}.'
'
- .$lt{'stat'}.' '
- .&mt('Default credits can also be specified, if different from the domain defaults (official courses: [_1]; unofficial courses: [_2]; textbook courses: [_3]).',
- $domdefaults{'officialcredits'},$domdefaults{'unofficialcredits'},$domdefaults{'textbookcredits'})
- .&Apache::lonhtmlcommon::row_closure()
-
+ .$lt{'stat'});
+ if ($crstype eq 'Course') {
+ $r->print(' '
+ .&mt('Default credits can also be specified, if different from the domain defaults (official courses: [_1]; unofficial courses: [_2]; textbook courses: [_3]).',
+ $domdefaults{'officialcredits'},$domdefaults{'unofficialcredits'},$domdefaults{'textbookcredits'}));
+ }
+ $r->print(&Apache::lonhtmlcommon::row_closure()
.&Apache::lonhtmlcommon::row_title($lt{'ccod'})
.''
.'
('.$lt{'toin'}.')'
@@ -341,7 +364,8 @@ END
.'
('.$lt{'cscs'}.')'
.&Apache::lonhtmlcommon::row_closure()
);
- if ($domdefaults{'officialcredits'} || $domdefaults{'unofficialcredits'} || $domdefaults{'textbookcredits'}) {
+ if (($crstype eq 'Course') && ($domdefaults{'officialcredits'} ||
+ $domdefaults{'unofficialcredits'} || $domdefaults{'textbookcredits'})) {
$r->print(&Apache::lonhtmlcommon::row_title($lt{'ccre'})
.''
.'
('.$lt{'cred'}.')'
@@ -353,7 +377,11 @@ END
.''.&mt('Yes').(' 'x2)
.''.&mt('No')
.&Apache::lonhtmlcommon::row_closure()
- );
+ );
+ }
+ my $blankchk;
+ if ($crstype eq 'Placement') {
+ $blankchk = ' checked="checked"';
}
# Table: New Course / Clone Course
$r->print(&Apache::lonhtmlcommon::row_headline()
@@ -379,15 +407,14 @@ END
.&Apache::lonhtmlcommon::row_closure()
.&Apache::lonhtmlcommon::row_title($lt{'fres'})
.''
- .' ');
+ .''.$lt{'blnk'}
+ .'');
if ($crstype eq 'Community') {
- $r->print('
+ + + +
' + ); } $r->print(''. $end_page); @@ -593,6 +628,8 @@ sub create_course { $crstype='Course'; $enrollstart=&Apache::lonhtmlcommon::get_date_from_form('startenroll'); $enrollend=&Apache::lonhtmlcommon::get_date_from_form('endenroll'); + } elsif ($env{'form.phase'} eq 'placementtwo') { + $crstype='Placement'; } $startaccess = &Apache::lonhtmlcommon::get_date_from_form('startaccess'); $endaccess = &Apache::lonhtmlcommon::get_date_from_form('endaccess'); @@ -731,8 +768,10 @@ sub create_course { ''.&mt('Course identifier to share with students: [_1]',$code).'
' ); } - # Flush the course logs so reverse user roles immediately updated - $r->register_cleanup(\&Apache::lonnet::flushcourselogs); + if ($env{'form.crscode'} ne '') { + &Apache::lonnet::devalidate_cache_new('instcats',$crsudom); + } + ®ister_cleanups($r,$crsudom,$env{'form.crscode'}); $r->print(''.&mt('Roles will be active at next login').'.
'); } $r->print(''.
@@ -743,7 +782,7 @@ sub create_course {
sub print_intro_page {
my ($r,$show_all_choices,$cancreate,$permission) = @_;
my $start_page =
- &Apache::loncommon::start_page('Create a New Course or Community');
+ &Apache::loncommon::start_page('Create a New Course, Community or Placement Test');
my $crumbs = &Apache::lonhtmlcommon::breadcrumbs('Creation Options','Create_Course',undef,'Create_Courses');
my $end_page =
&Apache::loncommon::end_page();
@@ -775,12 +814,20 @@ sub print_intro_page {
linktitle => 'Create a new collaborative community by completing an online form.'
},
{
- linktext => 'Create courses/communities by uploading an attributes file',
+ linktext => 'Create a single placement test',
+ url => '/adm/createcourse?phase=placementone',
+ permission => $permission->{'create'} && $cancreate->{'Placement'},
+ #help => '',
+ icon => 'crsnew.png',
+ linktitle => 'Create a new placement test by completing an online form.'
+ },
+ {
+ linktext => 'Create courses/communities/placement tests by uploading an attributes file',
url => '/adm/createcourse?phase=batchone',
permission => $permission->{'create'},
help => 'Batch_Creation',
icon => 'uplcrs.png',
- linktitle => 'Upload an attributes file containing specifications for one or more courses or communities in XML format.'
+ linktitle => 'Upload an attributes file containing specifications for one or more courses, communities or placement tests in XML format.'
},
]
},
@@ -792,7 +839,7 @@ sub print_intro_page {
permission => $show_all_choices,
#help => '',
icon => 'rcrs.png',
- linktitle => 'Display course and community creation requests submitted by authorized users, held pending approval by a Domain Coordinator.'
+ linktitle => 'Display course, community creation and placement test requests submitted by authorized users, held pending approval by a Domain Coordinator.'
},
{
linktext => 'View pending official course requests',
@@ -813,7 +860,7 @@ sub print_intro_page {
permission => $show_all_choices,
#help => '',
icon => 'document-properties.png',
- linktitle => 'Display information about when, how and by whom courses and communities were created in this domain.'
+ linktitle => 'Display information about when, how and by whom courses, communities and placement tests were created in this domain.'
},
]
},
@@ -830,60 +877,84 @@ sub print_intro_page {
sub upload_batchfile {
my $r = shift;
my $start_page =
- &Apache::loncommon::start_page('Create a New Course or Community');
- my $crumbs = &Apache::lonhtmlcommon::breadcrumbs('Upload Course/Community Attributes File','Create_Course',undef,'Create_Courses');
+ &Apache::loncommon::start_page('Create a New Course, Community, or Placement Test');
+ my $crumbs = &Apache::lonhtmlcommon::breadcrumbs('Upload Course/Community/Placement Test Attributes File','Create_Course',undef,'Create_Courses');
my $end_page =
&Apache::loncommon::end_page();
$r->print($start_page.$crumbs);
- $r->print(' '.&mt('Could not open attributes file.').' '.&mt('No uploaded attributes file found.').' '.&mt('Invalid path to attributes file.').' '.&mt("Your username, domain, and/or your current role's domain are missing or contain invalid characters.").
+ ''.&mt('Upload a courses or communities attributes file').'
');
+ $r->print(''.&mt('Upload a courses, communities or placement tests attributes file').'
');
$r->print('');
+ 'value="'.&mt('Create Courses/Communities/Placement Tests').'" />');
$r->print($end_page);
return;
}
sub process_batchfile {
my $r = shift;
- my $start_page =
- &Apache::loncommon::start_page('Create a New Course or Community');
- my $crumbs = &Apache::lonhtmlcommon::breadcrumbs('Creation Outcome','Create_Course',undef,'Create_Courses');
- my $end_page =
- &Apache::loncommon::end_page();
my $defdom=$env{'request.role.domain'};
- my $batchfilepath=&Apache::lonnet::userfileupload('coursecreatorxml',undef,
- 'batchupload',undef,undef,
- undef,undef,$defdom);
- my ($batchdir,$filename) = ($batchfilepath =~ m-^(.+)/pending/([^/]+)$-);
- my ($result,$logmsg);
- if (-e "$batchfilepath") {
- open(FILE,"<$batchfilepath");
- my @buffer =
'.&mt('No courses created.').'
'.&mt('No courses created.').'
'.&mt('No courses created.').'
'.&mt('No courses created.').'
'.
- &mt('Creation options menu').''.$end_page);
+ $r->print(&Apache::loncommon::start_page('Create a New Course, Community or Placement Test').
+ &Apache::lonhtmlcommon::breadcrumbs('Creation Outcome','Create_Course',undef,'Create_Courses').
+ $logmsg.$result.'
'.
+ &mt('Creation options menu').''.
+ &Apache::loncommon::end_page());
}
@@ -968,6 +1039,8 @@ sub print_creation_logs {
$crstype = '.';
} elsif ($curr{'type'} eq 'community') {
$crstype = 'Community';
+ } elsif ($curr{'type'} eq 'placement') {
+ $crstype = 'Placement';
}
my ($instcodefilter,$regexpok);
@@ -1058,6 +1131,8 @@ sub print_creation_logs {
my $showtype;
if ($courses{$cid}{type} eq 'Community') {
$showtype = &mt('community');
+ } elsif ($courses{$cid}{type} eq 'Placement') {
+ $showtype = &mt('placement test');
} else {
my $instcode = $courses{$cid}{inst_code};
if ($instcode ne '') {
@@ -1272,6 +1347,44 @@ sub get_permission {
return ($allowed,\%permission);
}
+sub register_cleanups {
+ my ($r,$cdom,$updatecats) = @_;
+ # Flush the course logs so reverse user roles immediately updated
+ unless ($registered_flush) {
+ my $handlers = $r->get_handlers('PerlCleanupHandler');
+ $r->set_handlers('PerlCleanupHandler' => [\&Apache::lonnet::flushcourselogs,@{$handlers}]);
+ $registered_flush=1;
+ }
+ # Update cache of self-cataloging courses on institution's server(s).
+ if ($updatecats) {
+ if (&Apache::lonnet::shared_institution($cdom)) {
+ unless ($registered_instcats) {
+ my $handlers = $r->get_handlers('PerlCleanupHandler');
+ $r->set_handlers('PerlCleanupHandler' => [\&devalidate_remote_instcats,@{$handlers}]);
+ $registered_instcats=1;
+ $modified_dom = $cdom;
+ }
+ }
+ }
+ return;
+}
+
+sub devalidate_remote_instcats {
+ if ($modified_dom ne '') {
+ my %servers = &Apache::lonnet::internet_dom_servers($modified_dom);
+ my %thismachine;
+ map { $thismachine{$_} = 1; } &Apache::lonnet::current_machine_ids();
+ if (keys(%servers)) {
+ foreach my $server (keys(%servers)) {
+ next if ($thismachine{$server});
+ &Apache::lonnet::remote_devalidate_cache($server,['instcats:'.$modified_dom]);
+ }
+ }
+ $modified_dom = '';
+ }
+ return;
+}
+
# ===================================================================== Handler
sub handler {
my $r = shift;
@@ -1282,19 +1395,24 @@ sub handler {
return OK;
}
+ $registered_flush = 0;
+ $registered_instcats = 0;
+ $modified_dom = '';
+
my ($allowed,$permission) = &get_permission($env{'request.role.domain'});
if ($allowed) {
my $show_all_choices = 0;
my $primary_rev = &Apache::lonnet::get_server_loncaparev($env{'request.role.domain'});
my %cancreate = (
Community => 0,
+ Placement => 0,
);
if (($primary_rev ne 'refused') && ($primary_rev ne 'error') &&
($primary_rev ne 'unknown_cmd') && ($primary_rev ne 'no_such_host')) {
$show_all_choices = 1;
my ($primary_major,$primary_minor) = split(/\./,$primary_rev);
foreach my $key (keys(%cancreate)) {
- my ($needsmajor,$needsminor) =
+ my ($needsmajor,$needsminor) =
split(/\./,$Apache::lonnet::needsrelease{'course:crstype:'.$key});
unless (($needsmajor > $primary_major) ||
(($needsmajor == $primary_major) && ($needsminor > $primary_minor))) {
@@ -1315,8 +1433,10 @@ sub handler {
faq=>79,bug=>'Dom Coord Interface',});
if (($permission->{'create'}) &&
(($env{'form.phase'} eq 'coursetwo') ||
- (($env{'form.phase'} eq 'grouptwo') &&
- ($cancreate{'Community'})))) {
+ (($env{'form.phase'} eq 'grouptwo') &&
+ ($cancreate{'Community'})) ||
+ (($env{'form.phase'} eq 'placementtwo') &&
+ ($cancreate{'Placement'})))) {
&Apache::lonhtmlcommon::add_breadcrumb
({href=>"/adm/createcourse?phase=$env{'form.prevphase'}",
text=>&mt('[_1] Creation Settings',),
@@ -1327,9 +1447,11 @@ sub handler {
faq=>9,bug=>'Dom Coord Interface',});
&create_course($r);
} elsif (($permission->{'create'}) &&
- (($env{'form.phase'} eq 'courseone') ||
- (($env{'form.phase'} eq 'groupone') &&
- ($cancreate{'Community'})))) {
+ (($env{'form.phase'} eq 'courseone') ||
+ (($env{'form.phase'} eq 'groupone') &&
+ ($cancreate{'Community'})) ||
+ (($env{'form.phase'} eq 'placementone') &&
+ ($cancreate{'Placement'})))) {
&Apache::lonhtmlcommon::add_breadcrumb
({href=>"/adm/createcourse?phase=$env{'form.phase'}",
text=>&mt('[_1] Creation Settings',),
@@ -1370,7 +1492,7 @@ sub handler {
$context,$env{'request.role.domain'}).''.
&Apache::loncommon::end_page());
} elsif (($permission->{'create'}) &&
- ($env{'form.phase'} eq 'requestchange') && ($show_all_choices)) {
+ ($env{'form.phase'} eq 'requestchange') && ($show_all_choices)) {
if ($env{'form.queue'} eq 'pending') {
&Apache::lonhtmlcommon::add_breadcrumb
({href=>"/adm/createcourse?phase=pendingdisplay",
@@ -1409,7 +1531,7 @@ sub handler {
$context,$env{'request.role.domain'}).''.
&Apache::loncommon::end_page());
} elsif (($permission->{'create'}) &&
- ($env{'form.phase'} eq 'requestvalidation') && ($show_all_choices)) {
+ ($env{'form.phase'} eq 'requestvalidation') && ($show_all_choices)) {
my $js = &courserequestbrowser_javascript();
&Apache::lonhtmlcommon::add_breadcrumb
({href=>"/adm/createcourse?phase=pendingdisplay",