'.&mt('Requests for official courses queued pending validation').'
'.
+ '
'.&mt('Requests are validated against institutional data to confirm that the requestor is an instructor of record.').' '.
+ &mt('Validation is attempted when the request is submitted.').' '.&mt('If unvalidated, the request will be held in a queue.').' '.&mt('Validation of pending requests is automatically repeated daily.').'
';
+ if ($context eq 'course') {
+ $output .= &mt('There are currently no enrollment requests awaiting approval.');
+ } elsif ($context eq 'pending') {
+ $output .= &mt('There are currently no requests for official courses awaiting validation.');
+ } elsif ($context eq 'requestauthor') {
+ $output .= &mt('There are currently no requests for Authoring Space awaiting approval.');
+ } elsif ($context eq 'requestusername') {
+ $output .= &mt('There are currently no requests for LON-CAPA accounts awaiting approval.');
+ } elsif ($context eq 'domain') {
+ $output .= &mt('There are currently no course or community requests awaiting approval.');
+ }
+ $output .= '
'.&mt('Any course/community requests which are successfully validated will be created immediately.').' '.&mt('Unvalidated requests will be listed for manual approval/rejection.').'
';
+ if ($context eq 'course') {
+ $output .= &mt('There are currently no enrollment requests awaiting approval.');
+ } elsif ($context eq 'pending') {
+ $output .= &mt('There are currently no requests for official courses awaiting validation.');
+ } elsif ($context eq 'requestauthor') {
+ $output .= &mt('There are currently no requests for Authoring Space awaiting approval.');
+ } elsif ($context eq 'requestusername') {
+ $output .= &mt('There are currently no requests for LON-CAPA accounts awaiting approval.');
+ } else {
+ $output .= &mt('There are currently no course or community requests awaiting approval.');
+ }
+ $output .= '
';
+ }
+ if ($notifylist ne '') {
+ &send_selfserve_notification($notifylist,$chgmsg,undef,$domdesc,
+ $now,'usernamemanagers',$sender,
+ $approvedlist,$rejectedlist);
+ }
} else {
$chgmsg = "'Action was taken on the following course and community requests by [_1].',$namelink";
if (@completed) {
@@ -741,13 +1306,16 @@ sub update_request_queue {
$output .= '
'.&mt('The following courses/communities were created:').'
';
foreach my $cnum (@completed) {
my $showcourse;
- if (ref($requesthash{$cnum.'_approval'})) {
- $showcourse = $requesthash{$cnum.'_approval'}{'description'};
+ if (ref($requesthash{$cnum.'_'.$queue})) {
+ $showcourse = $requesthash{$cnum.'_'.$queue}{'description'};
} else {
$showcourse = $cnum;
}
my $syllabuslink =
&Apache::loncommon::syllabuswrapper($showcourse,$cnum,$cdom);
+ if ($codes{$cnum}) {
+ $syllabuslink .= ' '.&mt('Unique code: [_1]',$codes{$cnum});
+ }
$output .= '
'.&mt('The following Authoring Space requests were deleted because the requestor does not have a LON-CAPA account:').'
';
+ foreach my $uname (@invalidusers) {
+ my $userlink =
+ &Apache::loncommon::aboutmewrapper(&Apache::loncommon::plainname($uname,$cdom),$uname,$cdom);
+ $output .= '
'.$userlink.'
';
+ }
+ $output .= '
';
}
}
if (@limitexceeded) {
@@ -831,17 +1426,27 @@ sub update_request_queue {
}
}
if (@nopermissions) {
- $output .= '
'.&mt('The following course/community creation requests could not be processed because the owner does not have rights to create this type of course:').'
';
- foreach my $cnum (@nopermissions) {
- my $showcourse;
- if (ref($requesthash{$cnum.'_approval'})) {
- $showcourse = $requesthash{$cnum.'_approval'}{'description'};
- } else {
- $showcourse = $cnum;
+ if ($context eq 'course') {
+ $output .= '
'.&mt('The following course/community creation requests could not be processed because the owner does not have rights to create this type of course:').'
';
+ }
}
return $output;
}
-sub enable_gci_submission {
- my ($udom,$uname,$access_end,$access_start) = @_;
- my $cdom = 'gci';
- my $cnum = '1H96711d710194bfegcil1';
- my ($stucounts,$idx,$classlist) = &get_student_counts($cdom,$cnum);
- if (exists($classlist->{$uname.':'.$udom})) {
- if (ref($classlist->{$uname.':'.$udom}) eq 'ARRAY') {
- if (($classlist->{$uname.':'.$udom}->[$idx->{'status'}] eq 'Active') ||
- ($classlist->{$uname.':'.$udom}->[$idx->{'status'}] eq 'Future')) {
- return;
- }
- }
+sub course_portal_url {
+ my ($cnum,$cdom) = @_;
+ my $chome = &Apache::lonnet::homeserver($cnum,$cdom);
+ my $hostname = &Apache::lonnet::hostname($chome);
+ my $protocol = $Apache::lonnet::protocol{$chome};
+ $protocol = 'http' if ($protocol ne 'https');
+ my %domdefaults = &Apache::lonnet::get_domain_defaults($cdom);
+ my $firsturl;
+ if ($domdefaults{'portal_def'}) {
+ $firsturl = $domdefaults{'portal_def'};
+ } else {
+ $firsturl = $protocol.'://'.$hostname;
}
- return
- &Apache::lonnet::modify_student_enrollment($udom,$uname,undef,undef,undef,undef,undef,undef,$access_end,$access_start,'selfenroll',undef,$cdom.'_'.$cnum,1);
+ return $firsturl;
}
sub get_student_counts {
@@ -945,13 +1600,24 @@ sub get_student_counts {
sub course_creation {
my ($dom,$cnum,$context,$details,$logmsg,$newusermsg,$addresult,$enrollcount,$output,
- $keysmsg,$domdefs,$longroles) = @_;
+ $keysmsg,$domdefs,$longroles,$coderef,$customhash) = @_;
unless ((ref($details) eq 'HASH') && (ref($domdefs) eq 'HASH') &&
(ref($longroles) eq 'HASH')) {
return 'error: Invalid request';
}
my ($result,$ownername,$ownerdom);
my $crstype = $details->{'crstype'};
+ my $coursedesc = $details->{'cdescr'};
+ my $accessstart = $details->{'accessstart'};
+ my $accessend = $details->{'accessend'};
+ my %domconfig = &Apache::lonnet::get_dom('configuration',['requestcourses'],$dom);
+ if (ref($domconfig{'requestcourses'}) eq 'HASH') {
+ if (ref($domconfig{'requestcourses'}{'uniquecode'}) eq 'HASH') {
+ if ($domconfig{'requestcourses'}{'uniquecode'}{$crstype}) {
+ $details->{'uniquecode'} = 1;
+ }
+ }
+ }
if ($context eq 'domain') {
$ownername = $details->{'owner'};
$ownerdom = $details->{'domain'};
@@ -959,6 +1625,7 @@ sub course_creation {
$ownername = $env{'user.name'};
$ownerdom = $env{'user.domain'};
}
+ my $fullname = &Apache::loncommon::plainname($ownername,$ownerdom);
my $owneremail;
my %emails = &Apache::loncommon::getemails($ownername,$ownerdom);
foreach my $email ('permanentemail','critnotification','notification') {
@@ -967,31 +1634,39 @@ sub course_creation {
}
my %reqdetails = &build_batchcreatehash($dom,$context,$details,$owneremail,$domdefs);
my $cid = &LONCAPA::batchcreatecourse::build_course($dom,$cnum,'requestcourses',
- \%reqdetails,$longroles,\$logmsg,\$newusermsg,\$addresult,
- \$enrollcount,\$output,\$keysmsg,$ownerdom,$ownername,$cnum,$crstype);
+ \%reqdetails,$longroles,$logmsg,$newusermsg,$addresult,
+ $enrollcount,$output,$keysmsg,$ownerdom,$ownername,$cnum,$crstype,$coderef);
+ my $postprocess;
if ($cid eq "/$dom/$cnum") {
$result = 'created';
+ my $code;
+ if (ref($coderef)) {
+ $code = $$coderef;
+ }
+ $postprocess = &Apache::lonnet::auto_crsreq_update($dom,$cnum,$crstype,$result,$ownername,
+ $ownerdom,$fullname,$coursedesc,$code,
+ $accessstart,$accessend,$customhash);
} else {
$result = 'error: '.$cid;
}
- return $result;
+ return ($result,$postprocess);
}
sub build_batchcreatehash {
my ($dom,$context,$details,$owneremail,$domdefs) = @_;
my %batchhash;
- my @items = qw{owner domain coursehome clonecrs clonedom datemode dateshift enrollstart enrollend accessstart accessend sections crosslists users};
- if ($dom eq 'gcitest') {
- push(@items,'firstres');
- }
+ my @items = qw{owner domain coursehome clonecrs clonedom datemode dateshift enrollstart enrollend accessstart accessend sections crosslists users uniquecode};
if ((ref($details) eq 'HASH') && (ref($domdefs) eq 'HASH')) {
- my $emailenc = &Apache::lonnet::escape($owneremail);
+ my $emailenc = &escape($owneremail);
my $owner = $details->{'owner'}.':'.$details->{'domain'};
foreach my $item (@items) {
$batchhash{$item} = $details->{$item};
}
$batchhash{'title'} = $details->{'cdescr'};
$batchhash{'coursecode'} = $details->{'instcode'};
+ if ($domdefs->{'officialcredits'} || $domdefs->{'unofficialcredits'}) {
+ $batchhash{'defaultcredits'} = $details->{'defaultcredits'};
+ }
$batchhash{'emailenc'} = $emailenc;
$batchhash{'adds'} = $details->{'autoadds'};
$batchhash{'drops'} = $details->{'autodrops'};
@@ -1000,6 +1675,12 @@ sub build_batchcreatehash {
if ($details->{'crstype'} eq 'community') {
$batchhash{'crstype'} = 'Community';
} else {
+ if ($details->{'crstype'} eq 'textbook') {
+ if ($details->{'clonecrs'} && $details->{'clonedom'}) {
+ my %clonedfrom = &Apache::lonnet::coursedescription($details->{'clonedom'}.'_'.$details->{'clonecrs'});
+ $batchhash{'textbook'} = $clonedfrom{'description'};
+ }
+ }
$batchhash{'crstype'} = 'Course';
}
my ($owner_firstname,$owner_lastname);
@@ -1068,8 +1749,597 @@ sub can_clone_course {
$canclone = 1;
}
}
+ unless ($canclone) {
+ if (&Apache::lonnet::is_course_owner($clonedom,$clonecrs,$uname,$udom)) {
+ $canclone = 1;
+ }
+ }
}
return $canclone;
}
+sub get_processtype {
+ my ($context,$uname,$udom,$isadv,$dom,$crstype,$inststatuses,$domconfig) = @_;
+ return unless ((ref($inststatuses) eq 'ARRAY') && (ref($domconfig) eq 'HASH'));
+ if ($uname eq '' || $udom eq '') {
+ $uname = $env{'user.name'};
+ $udom = $env{'user.domain'};
+ $isadv = $env{'user.adv'};
+ }
+ my (%userenv,%settings,$val,@options,$envkey);
+ if ($context eq 'course') {
+ @options = ('autolimit','validate','approval');
+ $envkey = 'requestcourses.'.$crstype;
+ if (ref($domconfig->{'requestcourses'}) eq 'HASH') {
+ if (ref($domconfig->{'requestcourses'}->{$crstype}) eq 'HASH') {
+ %settings = %{$domconfig->{'requestcourses'}->{$crstype}};
+ }
+ }
+ } else {
+ @options = ('automatic','approval');
+ $envkey = 'requestauthor';
+ if (ref($domconfig->{'requestauthor'}) eq 'HASH') {
+ %settings = %{$domconfig->{'requestauthor'}};
+ }
+ }
+ if (($dom eq $udom) || ($context eq 'requestauthor')) {
+ %userenv =
+ &Apache::lonnet::userenvironment($udom,$uname,$envkey,'inststatus');
+ if ($userenv{$envkey}) {
+ $val = $userenv{$envkey};
+ @{$inststatuses} = ('_custom_');
+ } else {
+ my %alltasks;
+ if (($isadv) && ($settings{'_LC_adv'} ne '')) {
+ $val = $settings{'_LC_adv'};
+ @{$inststatuses} = ('_LC_adv_');
+ } else {
+ if ($userenv{'inststatus'} ne '') {
+ @{$inststatuses} = split(',',$userenv{'inststatus'});
+ } else {
+ @{$inststatuses} = ('default');
+ }
+ foreach my $status (@{$inststatuses}) {
+ if (exists($settings{$status})) {
+ my $value = $settings{$status};
+ next unless ($value);
+ unless (exists($alltasks{$value})) {
+ if (ref($alltasks{$value}) eq 'ARRAY') {
+ unless(grep(/^\Q$status\E$/,@{$alltasks{$value}})) {
+ push(@{$alltasks{$value}},$status);
+ }
+ } else {
+ @{$alltasks{$value}} = ($status);
+ }
+ }
+ }
+ }
+ my $maxlimit = 0;
+ if ($context eq 'course') {
+ foreach my $key (sort(keys(%alltasks))) {
+ if ($key =~ /^autolimit=(\d*)$/) {
+ if ($1 eq '') {
+ $val ='autolimit=';
+ last;
+ } elsif ($1 > $maxlimit) {
+ $maxlimit = $1;
+ }
+ }
+ }
+ }
+ if (($context eq 'requestauthor') || (!$val)) {
+ if ($context eq 'course' && $maxlimit) {
+ $val = 'autolimit='.$maxlimit;
+ } else {
+ foreach my $option (@options) {
+ if ($alltasks{$option}) {
+ $val = $option;
+ last;
+ }
+ }
+ }
+ }
+ }
+ }
+ } else {
+ %userenv = &Apache::lonnet::userenvironment($udom,$uname,'reqcrsotherdom.'.$crstype);
+ if ($userenv{'reqcrsotherdom.'.$crstype}) {
+ my @doms = split(',',$userenv{'reqcrsotherdom.'.$crstype});
+ my $optregex = join('|',@options);
+ foreach my $item (@doms) {
+ my ($extdom,$extopt) = split(':',$item);
+ if ($extdom eq $dom) {
+ if ($extopt =~ /^($optregex)(=?\d*)$/) {
+ $val = $1.$2;
+ }
+ last;
+ }
+ }
+ @{$inststatuses} = ('_external_');
+ }
+ }
+ return $val;
+}
+
+sub queued_selfenrollment {
+ my ($notitle) = @_;
+ my $output;
+ my %selfenrollrequests = &Apache::lonnet::dump('selfenrollrequests');
+ my %reqs_by_date;
+ foreach my $item (keys(%selfenrollrequests)) {
+ if (ref($selfenrollrequests{$item}) eq 'HASH') {
+ if ($selfenrollrequests{$item}{'status'} eq 'request') {
+ if ($selfenrollrequests{$item}{'timestamp'}) {
+ push(@{$reqs_by_date{$selfenrollrequests{$item}{'timestamp'}}},$item);
+ }
+ }
+ }
+ }
+ if (keys(%reqs_by_date)) {
+ unless ($notitle) {
+ $output .= ' '.&mt('Enrollment requests pending Course Coordinator approval').' ';
+ }
+ $output .= &Apache::loncommon::start_data_table().
+ &Apache::loncommon::start_data_table_header_row().
+ '
'.&mt('Date requested').'
'.&mt('Course title').'
'.
+ '
'.&mt('User role').'
'.&mt('Section').'
'.
+ &Apache::loncommon::end_data_table_header_row();
+ my @sorted = sort { $a <=> $b } (keys(%reqs_by_date));
+ foreach my $item (@sorted) {
+ if (ref($reqs_by_date{$item}) eq 'ARRAY') {
+ foreach my $crs (@{$reqs_by_date{$item}}) {
+ my %courseinfo = &Apache::lonnet::coursedescription($crs);
+ my $usec = $selfenrollrequests{$crs}{'section'};
+ my $rolename = &Apache::lonnet::plaintext('st',$courseinfo{'type'},$crs);
+ if ($usec eq '') {
+ $usec = &mt('No section');
+ }
+ $output .= &Apache::loncommon::start_data_table_row().
+ '
'.&Apache::lonlocal::locallocaltime($item).'
'.
+ '
'.$courseinfo{'description'}.'
'.
+ '
'.$rolename.'
'.$usec.'
'.
+ &Apache::loncommon::end_data_table_row();
+ }
+ }
+ }
+ $output .= &Apache::loncommon::end_data_table();
+ }
+ return $output;
+}
+
+sub update_coursereq_status {
+ my ($reqhash,$dom,$cnum,$reqstatus,$context,$udom,$uname) = @_;
+ my ($storeresult,$statusresult,$output);
+ my $requestkey = $dom.'_'.$cnum;
+ if ($requestkey =~ /^($match_domain)_($match_courseid)$/) {
+ $storeresult = &Apache::lonnet::store_userdata($reqhash,$requestkey,
+ 'courserequests',$udom,$uname);
+ if ($storeresult eq 'ok') {
+ my %status = (
+ 'status:'.$dom.':'.$cnum => $reqstatus,
+ );
+ $statusresult = &Apache::lonnet::put('courserequests',\%status,$udom,$uname);
+ }
+ } else {
+ $storeresult = 'error: invalid requestkey format';
+ }
+ if ($storeresult ne 'ok') {
+ $output = &mt('An error occurred saving a record of the details of your request: [_1].',$storeresult);
+ if ($context eq 'domain') {
+ $output .= "\n";
+ } else {
+ $output = ''.$output.' ';
+ }
+ &Apache::lonnet::logthis("Error saving course request - $requestkey for $uname:$udom - $storeresult");
+ } elsif ($statusresult ne 'ok') {
+ $output = &mt('An error occurred saving a record of the status of your request: [_1].',$statusresult);
+ if ($context eq 'domain') {
+ $output .= "\n";
+ } else {
+ $output = ''.$output.' ';
+ }
+ &Apache::lonnet::logthis("Error saving course request status for $requestkey (for $uname:$udom) - $statusresult");
+ }
+ return ($storeresult,$output);
+}
+
+sub process_official_reqs {
+ my ($context,$dom,$dcname,$dcdom) = @_;
+ my $reqsnamespace = 'courserequestqueue';
+ my %requesthash =
+ &Apache::lonnet::dump_dom($reqsnamespace,$dom,'_pending');
+ my (%newcids,%longroles,%stillpending);
+ my @courseroles = ('cc','in','ta','ep','ad','st');
+ foreach my $role (@courseroles) {
+ $longroles{$role}=&Apache::lonnet::plaintext($role);
+ }
+ my %domdefs = &Apache::lonnet::get_domain_defaults($dom);
+ my ($output,$linefeed);
+ if ($context eq 'auto') {
+ $linefeed = "\n";
+ } else {
+ $linefeed = ' '."\n";
+ }
+ foreach my $key (keys(%requesthash)) {
+ my ($cnum,$status) = split('_',$key);
+ next if (&Apache::lonnet::homeserver($cnum,$dom) ne 'no_host');
+ if (ref($requesthash{$key}) eq 'HASH') {
+ my $ownername = $requesthash{$key}{'ownername'};
+ my $ownerdom = $requesthash{$key}{'ownerdom'};
+ next if (&Apache::lonnet::homeserver($ownername,$ownerdom) eq 'no_host');
+ my $inststatus;
+ my %userenv =
+ &Apache::lonnet::get('environment',['inststatus'],
+ $ownerdom,$ownername);
+ my ($tmp) = keys(%userenv);
+ if ($tmp !~ /^(con_lost|error|no_such_host)/i) {
+ $inststatus = $userenv{'inststatus'};
+ } else {
+ undef(%userenv);
+ }
+ my $reqkey = $dom.'_'.$cnum;
+ my %history = &Apache::lonnet::restore($reqkey,'courserequests',
+ $ownerdom,$ownername);
+ if (ref($history{'details'}) eq 'HASH') {
+ my $instcode = $history{'details'}{'instcode'};
+ my $crstype = $history{'details'}{'crstype'};
+ my $reqtime = $history{'details'}{'reqtime'};
+ my $cdescr = $history{'details'}{'cdescr'};
+ my @currsec;
+ my $sections = $history{'details'}{'sections'};
+ if (ref($sections) eq 'HASH') {
+ foreach my $i (sort(keys(%{$sections}))) {
+ if (ref($sections->{$i}) eq 'HASH') {
+ my $sec = $sections->{$i}{'inst'};
+ if (!grep(/^\Q$sec\E$/,@currsec)) {
+ push(@currsec,$sec);
+ }
+ }
+ }
+ }
+ my $instseclist = join(',',@currsec);
+ my ($validationchk,$disposition,$reqstatus,$message,
+ $validation,$validationerror);
+ $validationchk =
+ &Apache::lonnet::auto_courserequest_validation($dom,
+ $ownername.':'.$ownerdom,$crstype,$inststatus,
+ $instcode,$instseclist);
+ if ($validationchk =~ /:/) {
+ ($validation,$message) = split(':',$validationchk);
+ } else {
+ $validation = $validationchk;
+ }
+ if ($validation =~ /^error(.*)$/) {
+ $disposition = 'approval';
+ $validationerror = $1;
+ } else {
+ $disposition = $validation;
+ }
+ $reqstatus = $disposition;
+ if ($disposition eq 'process') {
+ my ($logmsg,$newusermsg,$addresult,$enrollcount,$response,$keysmsg,$code);
+ my %customitems;
+ my $fullname = &Apache::loncommon::plainname($ownername,$ownerdom);
+ my $inprocess = &Apache::lonnet::auto_crsreq_update($dom,$cnum,$crstype,'process',$ownername,
+ $ownerdom,$fullname,$cdescr);
+ if (ref($inprocess) eq 'HASH') {
+ foreach my $key (keys(%{$inprocess})) {
+ if (exists($history{'details'}{$key})) {
+ $customitems{$key} = $history{'details'}{$key};
+ }
+ }
+ }
+ if ($history{'details'}{'clonecrs'}) {
+ $customitems{'_LC_clonefrom'} = $history{'details'}{'clonedom'}.'_'.$history{'details'}{'clonecrs'};
+ }
+ my ($result,$postprocess) =
+ &course_creation($dom,$cnum,'domain',$history{'details'},\$logmsg,\$newusermsg,\$addresult,
+ \$enrollcount,\$response,\$keysmsg,\%domdefs,\%longroles,\$code,\%customitems);
+ if ($result eq 'created') {
+ $disposition = 'created';
+ $reqstatus = 'created';
+ my $cid = $dom.'_'.$cnum;
+ push(@{$newcids{$instcode}},$cid);
+ if ($dcname && $dcdom) {
+ my $firsturl = &course_portal_url($cnum,$dom);
+ my $beneficiary = 'pendingrequestor';
+ my $now = time;
+ my $owner = $ownername.':'.$ownerdom;
+ my $approvedmsg =
+ [{
+ mt => 'Your requested course: [_1], (queued pending validation) has now been created.',
+ args => [$cdescr],
+ },
+ {
+ mt => 'Visit [_1] to log-in and access the course.',
+ args => [$firsturl],
+ },
+ {
+ mt => 'If currently logged-in to LON-CAPA, log-out and log-in again to select your new course role.'
+ }];
+ my $sender = $dcname.':'.$dcdom;
+ if (ref($postprocess) eq 'HASH') {
+ if (ref($postprocess->{'createdmsg'}) eq 'ARRAY') {
+ foreach my $item (@{$postprocess->{'createdmsg'}}) {
+ if (ref($item) eq 'HASH') {
+ if ($item->{'mt'} ne '') {
+ push(@{$approvedmsg},$item);
+ }
+ }
+ }
+ }
+ if (ref($postprocess->{'createdactions'}) eq 'HASH') {
+ if (ref($postprocess->{'createdactions'}{'environment'}) eq 'HASH') {
+ &postprocess_crsenv($dom,$cnum,$postprocess->{'createdactions'}{'environment'});
+ }
+ }
+ }
+ &send_selfserve_notification($owner,$approvedmsg,
+ $cid,$cdescr,$now,
+ $beneficiary,$sender,
+ undef,undef,$crstype);
+ }
+ }
+ } elsif ($disposition eq 'rejected') {
+ $output .= &mt('Queued course request for [_1] submitted by [_2] with status [_3] rejected when validating.',$instcode,$ownername.':'.$ownerdom,$inststatus).$linefeed;
+ } elsif ($disposition eq 'approval') {
+ $output .= &mt('Queued course request for [_1] submitted by [_2] with status [_3] switched to "approval by DC" because of validation error: [_4].',$instcode,$ownername.':'.$ownerdom,$inststatus,$validationerror).$linefeed;
+
+ my $requestid = $cnum.'_'.$disposition;
+ my $request = {
+ $requestid => {
+ timestamp => $reqtime,
+ crstype => $crstype,
+ ownername => $ownername,
+ ownerdom => $ownerdom,
+ description => $cdescr,
+ },
+ };
+ my $putresult = &Apache::lonnet::newput_dom('courserequestqueue',$request,$dom);
+ unless ($putresult eq 'ok') {
+ $output .= &mt("An error occurred saving the modified course request for [_1] submitted by [_2] in the domain's courserequestqueue.db.",$instcode,$ownername.':'.$ownerdom).$linefeed;
+ }
+ } elsif ($disposition eq 'pending') {
+ my $instcode = $requesthash{$key}{'instcode'};
+ my $description = $requesthash{$key}{'description'};
+ my $timestamp = $requesthash{$key}{'timestamp'};
+ my $entry = $cnum.':'.$ownername.':'.$ownerdom.':'.
+ $instcode.':'.$description;
+ if (ref($stillpending{$timestamp}) eq 'ARRAY') {
+ push(@{$stillpending{$timestamp}},$entry);
+ } else {
+ $stillpending{$timestamp} = [$entry];
+ }
+ }
+ unless ($disposition eq 'pending') {
+ my ($statusresult,$output) =
+ &update_coursereq_status(\%requesthash,$dom,$cnum,
+ $reqstatus,'domain',$ownerdom,
+ $ownername);
+ unless (&Apache::lonnet::del_dom($reqsnamespace,[$cnum.'_pending'],$dom) eq 'ok') {
+ $output .= &mt('An error occurred when removing the request for [_1] submitted by [_2] from the pending queue.',$instcode,$ownername.':'.$ownerdom).$linefeed;
+ }
+ }
+ }
+ }
+ }
+ foreach my $key (sort(keys(%newcids))) {
+ if (ref($newcids{$key}) eq 'ARRAY') {
+ $output .= "created course from queued request: $key - ".join(', ',@{$newcids{$key}}).$linefeed;
+ my $newcourse = &LONCAPA::escape($key.':'.$newcids{$key});
+ }
+ }
+ unless ($context eq 'auto') {
+ if (keys(%stillpending) > 0) {
+ $output .= '
'."\n".
+ ''."\n".
+ ''.
+ '
'.&mt('For the following requests, the requestor could [_1]not[_2] be validated as official course personnel, so the request remains in the pending queue.','','').' '.&mt('Requests may be left in the queue, or you can manually approve or reject them.').'
'.
+ &build_queue_display($dom,'stillpending',\%stillpending).
+ ' '."\n".
+ ''.
+ '';
+ }
+ }
+ return $output;
+}
+
+sub postprocess_crsenv {
+ my ($dom,$cnum,$postprocessenv) = @_;
+ if (ref($postprocessenv) eq 'HASH') {
+ my $cid = $dom.'_'.$cnum;
+ my %settablecrsenv = (
+ 'internal.selfenroll_types' => 1,
+ 'internal.selfenroll_registered' => 1,
+ 'internal.selfenroll_section' => 1,
+ 'internal.selfenroll_start_access' => 1,
+ 'internal.selfenroll_end_access' => 1,
+ 'internal.selfenroll_limit' => 1,
+ 'internal.selfenroll_cap' => 1,
+ 'internal.selfenroll_approval' => 1,
+ 'internal.selfenroll_notifylist' => 1,
+ );
+ my %needcrsidput = (
+ 'internal.selfenroll_types' => 1,
+ 'internal.selfenroll_start_date' => 1,
+ 'internal. selfenroll_end_date' => 1,
+ );
+ my (@needupdate,%newcrsenv);
+ foreach my $key (keys(%{$postprocessenv})) {
+ if ($settablecrsenv{$key}) {
+ $newcrsenv{$key} = $postprocessenv->{$key};
+ if ($needcrsidput{$key}) {
+ push(@needupdate,$key);
+ }
+ }
+ if (keys(%newcrsenv)) {
+ my $putresult = &Apache::lonnet::put('environment',\%newcrsenv,$dom,$cnum);
+ if ($putresult eq 'ok') {
+ if (@needupdate) {
+ my %crsinfo =
+ &Apache::lonnet::courseiddump($dom,'.',1,'.','.',$cnum,undef,undef,'.');
+ if (ref($crsinfo{$cid}) eq 'HASH') {
+ foreach my $key (@needupdate) {
+ $crsinfo{$cid}{$key} = $newcrsenv{$key};
+ }
+ my $chome = &Apache::lonnet::homeserver($cnum,$dom);
+ &Apache::lonnet::courseidput($dom,\%crsinfo,$chome,'notime');
+ }
+ }
+ }
+ }
+ }
+ }
+ return;
+}
+
+
+sub requestcourses_validation_types {
+ my @items = ('url','fields','button','markup');
+ my %names = &Apache::lonlocal::texthash (
+ url => 'Web address of validation server/script',
+ fields => 'Form fields to send to validator',
+ button => 'Text for validation button',
+ markup => 'Validation description (HTML)',
+ );
+ my @fields = ('owner','course','coursetype','description');
+ return (\@items,\%names,\@fields);
+}
+
+sub is_active_author {
+ if ($env{'user.role.au./'.$env{'user.domain'}.'/'} =~ /^(\d*)\.(\d*)$/) {
+ if ((!$1 || $1 < time) &&
+ (!$2 || $2 > time)) {
+ return 1;
+ }
+ }
+}
+
+sub author_prompt {
+ my ($is_active_author,$offer_author);
+ if ($env{'environment.canrequest.author'}) {
+ unless (&is_active_author()) {
+ unless (&reqauthor_check() =~ /^approval:\d+$/) {
+ $offer_author = 1;
+ }
+ }
+ }
+ return $offer_author;
+}
+
+sub reqauthor_check {
+ my $queued = $env{'environment.requestauthorqueued'};
+ my %reqauthor = &Apache::lonnet::get('requestauthor',['author_status','author'],
+ $env{'user.domain'},$env{'user.name'});
+ my $reqstatus = $reqauthor{'author_status'};
+ if (($reqstatus eq '' && $queued ne '') ||
+ ($env{'environment.requestauthorqueued'} !~ /^\Q$reqstatus\E/)) {
+ if (ref($reqauthor{'author'}) eq 'HASH') {
+ $queued = $reqstatus.':'.$reqauthor{'author'}{'timestamp'};
+ } else {
+ undef($queued);
+ }
+ &Apache::lonnet::appenv({'environment.requestauthorqueued' => $queued});
+ }
+ return $queued;
+}
+
+sub process_reqauthor {
+ my ($dispositionref,$updateref) = @_;
+ if (&is_active_author()) {
+ return ''.
+ &mt('An Authoring Space has already been assigned to you.').' '.
+ &mt('Please select the Author role from your [_1]roles page[_2].','',
+ '').'';
+ }
+ unless ($env{'environment.canrequest.author'}) {
+ return ''.
+ &mt('You do not currently have rights to request an Authoring Space.').' '.
+ &mt('Please contact the [_1]helpdesk[_2] for assistance.','',
+ '').'';
+ }
+ my $queued = &reqauthor_check();
+ if ($queued =~ /^approval:(\d+)$/) {
+ my $timestamp = $1;
+ return ''.
+ &mt('A request for Authoring Space submitted on [_1] is awaiting approval',
+ &Apache::lonlocal::locallocaltime($timestamp)).
+ '';
+ } elsif ($queued =~ /^approved:(\d+)$/) {
+ my $timestamp = $1;
+ my %roleshash = &Apache::lonnet::get_my_roles($env{'user.name'},$env{'user.domain'},'userroles',
+ ['active'],['au'],[$env{'user.domain'}]);
+ if (keys(%roleshash) > 0) {
+ return ''.
+ &mt('A request for Authoring Space submitted on [_1] has been approved.',
+ &Apache::lonlocal::locallocaltime($timestamp)).
+ '';
+ }
+ }
+ my ($output,@inststatuses,%domconfig);
+ %domconfig = &Apache::lonnet::get_dom('configuration',['requestauthor'],
+ $env{'user.domain'});
+ my $val = &get_processtype('requestauthor',$env{'user.name'},$env{'user.domain'},
+ $env{'user.adv'},$env{'user.domain'},undef,
+ \@inststatuses,\%domconfig);
+ my $now = time;
+ if ($val eq 'automatic') {
+ my $start = $now-1;
+ if (&Apache::lonnet::assignrole($env{'user.domain'},$env{'user.name'},'/'.$env{'user.domain'}.'/',
+ 'au',undef,$start,undef,undef,'requestauthor') eq 'ok') {
+ $output = ''.
+ &mt('Access to Authoring Space has been activated').' ';
+ &Apache::lonroles::update_session_roles();
+ &Apache::lonnet::appenv({'user.update.time' => $now});
+ if (ref($updateref)) {
+ $$updateref = $now;
+ }
+ if (ref($dispositionref)) {
+ $$dispositionref = 'created';
+ }
+ } else {
+ $output = ''.
+ &mt('An error occurred while activating your access to Authoring Space');
+ }
+ } elsif ($val eq 'approval') {
+ my $domconfiguser = &Apache::lonnet::get_domainconfiguser($env{'user.domain'});
+ if (&Apache::lonnet::put('requestauthorqueue',{ $env{'user.name'}.'_'.$val => $now },
+ $env{'user.domain'},$domconfiguser) eq 'ok') {
+ my %userrequest = (
+ author => {
+ timestamp => $now,
+ status => $val,
+ },
+ author_status => $val,
+ );
+ my $req_notifylist;
+ if (ref($domconfig{'requestauthor'}) eq 'HASH') {
+ if (ref($domconfig{'requestauthor'}{'notify'}) eq 'HASH') {
+ my $req_notifylist = $domconfig{'requestauthor'}{'notify'}{'approval'};
+ if ($req_notifylist) {
+ my $fullname = &Apache::loncommon::plainname($env{'user.name'},
+ $env{'user.domain'});
+ my $sender = $env{'user.name'}.':'.$env{'user.domain'};
+ my $domdesc = &Apache::lonnet::domain($env{'user.domain'},'description');
+ &send_selfserve_notification($req_notifylist,
+ "$fullname ($env{'user.name'}:$env{'user.domain'})",
+ undef,$domdesc,$now,'authorreq',$sender);
+ }
+ }
+ }
+ my $userresult =
+ &Apache::lonnet::put('requestauthor',\%userrequest,$env{'user.domain'},$env{'user.name'});
+ $output = ''.
+ &mt('Your request for Authoring Space has been submitted for approval.').
+ '';
+ &Apache::lonnet::appenv({'environment.requestauthorqueued' => $val.':'.$now});
+ } else {
+ $output = ''.
+ &mt('An error occurred saving your request for Authoring Space.').
+ '';
+ }
+ }
+ return $output;
+}
+
1;
500 Internal Server Error
Internal Server Error
The server encountered an internal error or
misconfiguration and was unable to complete
your request.
Please contact the server administrator at
root@localhost to inform them of the time this error occurred,
and the actions you performed just before this error.
More information about this error may be available
in the server error log.