File:  [LON-CAPA] / loncom / interface / loncoursequeueadmin.pm
Revision 1.39: download - view: text, annotated - select for diffs
Wed Dec 25 09:52:42 2013 UTC (10 years, 5 months ago) by raeburn
Branches: MAIN
CVS tags: HEAD
- Unique six character identifier for a course can be created automatically,
  when a course is created, if domain configuration set to include this for
  course requests.
  - Initial use case is for a separate portal (toke-based auth) where students
    enter the code to sign up for a specific "textbook" course.

# The LearningOnline Network
# Utilities to administer domain course requests and course self-enroll requests
#
# $Id: loncoursequeueadmin.pm,v 1.39 2013/12/25 09:52:42 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

Apache::loncoursequeueadmin.pm

=head1 SYNOPSIS

Utilities used by domain coordinators to administer queued course creation requests,
and by course coordinators for queued self-enrollment requests, and by general
users to display their queued self-enrollment requests.  

This is part of the LearningOnline Network with CAPA project
described at http://www.lon-capa.org.

=head1 SUBROUTINES

=over

=item send_selfserve_notification()

=item display_queued_requests()

=item build_queue_display()

=item update_request_queue()

=item get_student_counts()

=item course_creation()

=item build_batchcreatehash()
 
=item can_clone_course()

=item get_processtype()

=item queued_selfenrollment()

=item update_coursereq_status()

=item process_official_reqs()

=item is_active_author()

=item author_prompt()

=item reqauthor_check()

=item process_reqauthor()

=back

=cut

package Apache::loncoursequeueadmin;

use strict;
use Apache::lonnet;
use Apache::loncommon;
use Apache::lonmsg;
use Apache::lonlocal;
use Apache::lonuserutils;
use LONCAPA qw(:DEFAULT :match);

sub send_selfserve_notification {
    my ($notifylist,$textstr,$cid,$contextdesc,$timestamp,$context,$sender,
        $approvedlist,$rejectedlist,$crstype) = @_;
# FIXME locallocaltime needs to be able to take $sender_lh as an argument
#       so this can be localized to the recipients date display format/time zone
    $timestamp =&Apache::lonlocal::locallocaltime($timestamp);
    my ($msgcc,$rawsubj,@rawmsg,$subject,$message,$reviewer,$msgtxt);
    my ($senderuname,$senderudom) = split(':',$sender);
    if ($context eq 'coursemanagers') {
        $rawsubj = 'Self-enrollment requests processed';
        push(@rawmsg,{
                      mt => 'Enrollment requests in the following course: [_1] have been processed.',
                      args => ["\n$contextdesc"],
                     });
    } elsif ($context eq 'domainmanagers') {
        $rawsubj = 'Course/Community requests reviewed';
        push(@rawmsg,{
                      mt  => 'Course/Community creation requests in the following domain: "[_1]" have been reviewed.',
                      args => ["\n$contextdesc"],
                     });
        if (ref($textstr) eq 'ARRAY') {
            push(@rawmsg,@{$textstr});
        }
    } elsif ($context eq 'authormanagers') {
        $rawsubj = 'Authoring space requests reviewed';
        push(@rawmsg,{
                      mt  => 'Authoring requests in the following domain: "[_1]" have been reviewed.',
                      args => ["\n$contextdesc"],
                     });
        if (ref($textstr) eq 'ARRAY') {
            push(@rawmsg,@{$textstr});
        }
    } elsif ($context eq 'enroller') {
        $rawsubj = 'Enrollment request';
        if ($crstype eq 'community') {
            $msgtxt = 'Your request for enrollment in the following community: [_1]requested on [_2]has been reviewed by a Coordinator.'
        } else {
            $msgtxt = 'Your request for enrollment in the following course: [_1]requested on [_2]has been reviewed by a Course Coordinator.';
        } 
        push(@rawmsg,{
                      mt  => $msgtxt,
                      args => ["\n  ".$contextdesc.",\n",$timestamp.",\n"],

                     });
        if (ref($textstr) eq 'ARRAY') {
            push(@rawmsg,@{$textstr});
        }
    } elsif ($context eq 'courserequestor') {
        if ($crstype eq 'Community') {
            $rawsubj = 'Community request';
            $msgtxt = 'Your request for creation of the following community: [_1]requested on [_2]has been reviewed by a Domain Coordinator.';
        } else {
            $rawsubj = 'Course request';
            $msgtxt = 'Your request for creation of the following course: [_1]requested on [_2]has been reviewed by a Domain Coordinator.';
        }
        push(@rawmsg,{
                      mt  => $msgtxt,
                      args => ["\n".$contextdesc.",\n",$timestamp.",\n"],

                     });
        if (ref($textstr) eq 'ARRAY') {
            push(@rawmsg,@{$textstr});
        }
    } elsif ($context eq 'pendingrequestor') {
        if ($crstype eq 'Community') {
            $rawsubj = 'Community request';
        } else {
            $rawsubj = 'Processed course request';
        }
        if (ref($textstr) eq 'ARRAY') {
            push(@rawmsg,@{$textstr});
        }
    } elsif ($context eq 'coursereq') {
        if ($crstype eq 'community') {
            $rawsubj = 'Community request to review';
            $msgtxt = 'Creation of the following community: [_1]was requested by [_2] on [_3].';
        } else {
            $rawsubj = 'Course request to review';
            $msgtxt = 'Creation of the following course: [_1]was requested by [_2] on [_3].';
        }
        push(@rawmsg,{
                      mt  => $msgtxt,
                      args => ["\n  $contextdesc\n",$textstr,$timestamp],
                     },
                     {
                      mt =>'[_1]As Domain Coordinator, use: [_2]Main Menu -> Course and community creation -> Approve or reject requests[_3]to display a list of pending requests, which you can either approve or reject.',
                      args => ["\n","\n\n","\n\n"],
                     });
    } elsif ($context eq 'selfenrollreq') {
        $rawsubj = 'Self-enrollment request';
        if ($crstype eq 'community') {
            $msgtxt = 'Enrollment in the following community: [_1]was requested by [_2] on [_3].'
        } else {
            $msgtxt = 'Enrollment in the following course: [_1]was requested by [_2] on [_3].'
        }
        push(@rawmsg,{
                      mt  => $msgtxt,
                      args => ["\n  $contextdesc\n",$textstr,$timestamp."\n"],
                     });
        my $directions;  
        if ($crstype eq 'community') {
            $directions = 'As Coordinator, use: [_1]Main Menu -> Manage Community Users -> Enrollment Requests[_2]to display a list of pending enrollment requests, which you can either approve or reject.';
        } else {
            $directions = 'As Course Coordinator, use: [_1]Main Menu -> Manage Course Users -> Enrollment Requests[_2]to display a list of pending enrollment requests, which you can either approve or reject.';
        }
        push(@rawmsg,
                     {
                      mt   => $directions,
                      args => ["  \n\n","\n"],
                     });
    } elsif ($context eq 'authorreq') {
        $rawsubj = 'Authoring space request to review';
        $msgtxt = 'Assignment of an author role in the [_1] domain[_2]was requested by [_3] on [_4].';
        push(@rawmsg,{
                      mt  => $msgtxt,
                      args => [$contextdesc,"\n",$textstr,$timestamp],
                     },
                     {
                      mt =>'[_1]As Domain Coordinator, use: [_2]Main Menu -> Create users or modify the roles and privileges of users -> Authoring space reqests[_3]to display a list of pending requests, which you can either approve or reject.',
                      args => ["\n","\n\n  ","\n\n"],
                     });

    } elsif ($context eq 'requestauthor') {
        $rawsubj = 'Authoring space request';
        $msgtxt = 'Your request for an authoring space requested on [_1]has been reviewed by a Domain Coordinator.';
        push(@rawmsg,{
                      mt  => $msgtxt,
                      args => [$timestamp."\n"],
                     });
        if (ref($textstr) eq 'ARRAY') {
            push(@rawmsg,@{$textstr});
        }
    } elsif ($context eq 'uniquecode') {
        $rawsubj = 'Course Identifier';
        if (ref($textstr) eq 'ARRAY') {
            push(@rawmsg,@{$textstr});
        }
    }
    my @to_notify = split(/,/,$notifylist);
    my $numsent = 0;
    my @recusers;
    my @recudoms;
    foreach my $cc (@to_notify) {
        my ($ccname,$ccdom) = split(/:/,$cc);
        if (!exists($msgcc->{$ccname.':'.$ccdom})) {
            push(@recusers,$ccname);
            push(@recudoms,$ccdom);
            $msgcc->{$ccname.':'.$ccdom}='';
            $numsent ++;
        }
    }
    my %reciphash = (
                     cc => $msgcc,
    );
    my ($uname,$udom);
    if ($sender =~ /:/) {
        ($uname,$udom) = split(/:/,$sender);
    } elsif ($context eq 'course') {
        $uname = $sender;
        my %courseinfo = &Apache::lonnet::coursedescription($cid);
        $udom = $courseinfo{'num'};
    }
    my %sentmessage;
    my $stamp = time;
    my $msgcount = &Apache::lonmsg::get_uniq();
    my $sender_lh = &Apache::loncommon::user_lang($uname,$udom,$cid);
    $subject = &Apache::lonlocal::mt_user($sender_lh,$rawsubj);
    $message = '';
    foreach my $item (@rawmsg) {
        if (ref($item) eq 'HASH') {
            $message .= &Apache::lonlocal::mt_user($sender_lh,$item->{mt},@{$item->{args}})."\n";
        }
    }
    &Apache::lonmsg::process_sent_mail($subject,'',$numsent,$stamp,$uname,$udom,$msgcount,$cid,$$,$message,\@recusers,\@recudoms,undef,undef,undef,undef,$senderuname,$senderudom);
    my ($recipid,$recipstatus) = &Apache::lonmsg::store_recipients($subject,$uname,$udom,\%reciphash);
    my $status;
    foreach my $recip (sort(keys(%{$msgcc}))) {
        my ($ccname,$ccdom) = split(/:/,$recip);
        my $recip_lh = &Apache::loncommon::user_lang($ccname,$ccdom,$cid);
        my $subject = &Apache::lonlocal::mt_user($sender_lh,$rawsubj);
        my $message = '';
        foreach my $item (@rawmsg) {
            if (ref($item) eq 'HASH') {
                $message .= &Apache::lonlocal::mt_user($sender_lh,$item->{mt},
                                                       @{$item->{args}})."\n";
            }
        }
        if ($context eq 'coursemanagers') {
            if ($approvedlist) {
                $message .= "\n\n".&Apache::lonlocal::mt_user($sender_lh,'Approved enrollments:')."\n".$approvedlist;
            }
            if ($rejectedlist) {
                $message .= "\n\n".&Apache::lonlocal::mt_user($sender_lh,'Rejected enrollments:')."\n".$rejectedlist;
            }
        } elsif ($context eq 'domainmanagers') {
            if ($approvedlist) {
                $message .= "\n\n".&Apache::lonlocal::mt_user($sender_lh,'Approved course requests:')."\n".$approvedlist;
            }
            if ($rejectedlist) {
                $message .= "\n\n".&Apache::lonlocal::mt_user($sender_lh,'Rejected course requests:')."\n".$rejectedlist;
            }
        } elsif ($context eq 'authormanagers') {
            if ($approvedlist) {
                $message .= "\n\n".&Apache::lonlocal::mt_user($sender_lh,'Approved author role requests:')."\n".$approvedlist;
            }
            if ($rejectedlist) {
                $message .= "\n\n".&Apache::lonlocal::mt_user($sender_lh,'Rejected author role requests:')."\n".$rejectedlist;
            }
        }
        $status .= &Apache::lonmsg::user_normal_msg($ccname,$ccdom,$subject,$message,undef,undef,undef,1,\%sentmessage,undef,undef,undef,1,$recipid).',';
    }
    $status =~ s/,$//;
    return ($recipstatus,$status);
}

sub display_queued_requests {
    my ($context,$dom,$cnum) = @_;
    my ($namespace,$formaction,$nextelement,%requesthash);
    if ($context eq 'course') {
        $formaction = '/adm/createuser';
        $namespace = 'selfenrollrequests';
        %requesthash = &Apache::lonnet::dump($namespace,$dom,$cnum);
        $nextelement = '<input type="hidden" name="state" value="done" />';
    } elsif ($context eq 'requestauthor') {
        $formaction = '/adm/createuser';
        $namespace = 'requestauthorqueue';
        %requesthash = &Apache::lonnet::dump_dom($namespace,$dom);
        $nextelement = '<input type="hidden" name="state" value="done" />';
    } else {
        $formaction = '/adm/createcourse';
        $namespace = 'courserequestqueue';
        my $disposition = 'approval';
        my $nextphase = 'requestchange';
        if ($context eq 'pending') {
            $disposition = 'pending';
            $nextphase = 'requestvalidation';
        }
        %requesthash = &Apache::lonnet::dump_dom($namespace,$dom,'_'.$disposition);
        $nextelement = '<input type="hidden" name="phase" value="'.$nextphase.'" />';
    }
    my ($output,%queue_by_date);
    if (keys(%requesthash) > 0) {
        $output = '<form method="post" name="changequeue" action="'.$formaction.'" />'."\n".
                  '<input type="hidden" name="action" value="'.$env{'form.action'}.'" />'."\n".
                  $nextelement."\n";
        foreach my $item (keys(%requesthash)) {
            my ($timestamp,$entry,$pending);
            if ($context eq 'course') {
                ($timestamp, my $usec) = split(/:/,$requesthash{$item});
                $entry = $item.':'.$usec;
            } elsif ($context eq 'requestauthor') {
                $timestamp = $requesthash{$item};
                ($entry) = ($item =~ /^($match_username)_approval$/);
            } else {
                $timestamp = $requesthash{$item}{'timestamp'};
                if (ref($requesthash{$item}) eq 'HASH') {
                    my ($cnum,$disposition) = split('_',$item);
                    $entry = $cnum.':'.$requesthash{$item}{'ownername'}.':'.
                             $requesthash{$item}{'ownerdom'}.':';
                    if ($context eq 'pending') {
                        $entry .= $requesthash{$item}{'instcode'};
                    } else {
                        $entry .= $requesthash{$item}{'crstype'};
                    }
                    $entry .= ':'.$requesthash{$item}{'description'};
                }
            }
            if ($entry ne '') {
                if (ref($queue_by_date{$timestamp}) eq 'ARRAY') {
                    push(@{$queue_by_date{$timestamp}},$entry);
                } else {
                    $queue_by_date{$timestamp} = [$entry];
                }
            }
        }
        if (keys(%queue_by_date) > 0) {
            if ($context eq 'course') {
                $output .=  '<h3>'.&mt('Self-enrollment requests queued pending approval by a Coordinator').'</h3>';
            } elsif ($context eq 'pending') {
                $output .= '<h3>'.&mt('Requests for official courses queued pending validation').'</h3>'.
                           '<p>'.&mt('Requests are validated against institutional data to confirm that the requestor is an instructor of record.').'<br />'.
                           &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.').'</p>';
            } elsif ($context eq 'requestauthor') {
                $output .= '<h3>'.&mt('Requests for authoring space queued pending approval by a Domain Coordinator').'</h3>';
            } else {
                $output .= '<h3>'.&mt('Course/Community requests queued pending approval by a Domain Coordinator').'</h3>';
            } 
            $output .= &build_queue_display($dom,$context,\%queue_by_date).
                       '<input type="hidden" name="queue" value="approval" />';
        } else {
            $output .= '<div class="LC_info">';
            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 'domain') {
                $output .= &mt('There are currently no course or community requests awaiting approval.');
            }
            $output .= '</div>'; 
        }
        if ($context eq 'pending') {
            $output .= '<br /><input type="submit" name="validationcheck" value="'.
                       &mt('Validate').'" /><br />'."\n".
                       '<p>'.&mt('Any course/community requests which are successfully validated will be created immediately.').' '.&mt('Unvalidated requests will be listed for manual approval/rejection.').'</p>';
        } else {
            $output .= '<br /><input type="submit" name="processqueue" value="'.&mt('Save').'" />';
        }
        $output .= '</form>';
    } else {
        $output .= '<div class="LC_info">';
        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.');
        } else {
            $output .= &mt('There are currently no course or community requests awaiting approval.');
        }
        $output .= '</div>';
    }
    return $output;
}

sub build_queue_display {
    my ($dom,$context,$queue) = @_;
    return unless (ref($queue) eq 'HASH');
    my %crstypes;
    my $output =  &Apache::loncommon::start_data_table().
                  &Apache::loncommon::start_data_table_header_row();
    unless ($context eq 'pending') { 
        $output .= '<th>'.&mt('Action').'</th>';
    }
    $output .= '<th>'.&mt('Requestor').'</th>';
    if ($context eq 'course') {
        $output .= '<th>'.&mt('Section').'</th>'.
                   '<th>'.&mt('Date requested').'</th>';
    } elsif ($context eq 'requestauthor') {
        $output .= '<th>'.&mt('Date requested').'</th>';
    } elsif ($context eq 'pending' || $context eq 'stillpending') {
        $output .= '<th>'.&mt('Institutional code').'</th>'.
                   '<th>'.&mt('Date requested').'</th>'.
                   '<th>'.&mt('Details').'</th>';
    } else {
        %crstypes = &Apache::lonlocal::texthash (
                        official   => 'Official course',
                        unofficial => 'Unofficial course',
                        community  => 'Community',
                        textbook   => 'Textbook course',
                    );
        $output .= '<th>'.&mt('Type').'</th>'.
                   '<th>'.&mt('Date requested').'</th>'.
                   '<th>'.&mt('Details').'</th>';
    }
    $output .= &Apache::loncommon::end_data_table_header_row();
    my @sortedtimes = sort {$a <=> $b} (keys(%{$queue}));
    my $count = 0;
    foreach my $item (@sortedtimes) {
        if (ref($queue->{$item}) eq 'ARRAY') {
            foreach my $request (sort(@{$queue->{$item}})) {
                my ($row,$approve,$reject,$showtime,$showsec,$namelink,
                    $detailslink,$crstype,$instcode);
                $showtime = &Apache::lonlocal::locallocaltime($item);
                if ($context eq 'course') {
                    my ($puname,$pudom,$pusec) = split(/:/,$request);
                    $approve = $count.':'.$puname.':'.$pudom.':'.$pusec;
                    $reject = $puname.':'.$pudom;
                    $showsec = $pusec;
                    if ($showsec eq '') {
                        $showsec = &mt('none');
                    }
                    $namelink = &Apache::loncommon::aboutmewrapper(
                                &Apache::loncommon::plainname($puname,$pudom),
                                $puname,$pudom);
                } elsif ($context eq 'requestauthor') {
                    if (&Apache::lonnet::homeserver($request,$dom) ne 'no_host') {
                        $approve = $count.':'.$request;
                        $reject = $request; 
                        $namelink = &Apache::loncommon::aboutmewrapper(
                                    &Apache::loncommon::plainname($request,$dom),
                                    $request,$dom);
                    }
                } else {
                    my ($cnum,$ownername,$ownerdom,$type,$cdesc);
                    my $queue = 'approval'; 
                    if ($context eq 'pending' || $context eq 'stillpending') {
                        ($cnum,$ownername,$ownerdom,$instcode,$cdesc)=split(/:/,$request,5);
                        $queue = 'pending';                        
                    } else {
                        ($cnum,$ownername,$ownerdom,$type,$cdesc)=split(/:/,$request,5);
                        $crstype = $type;
                        if (defined($crstypes{$type})) {
                            $crstype = $crstypes{$type};
                        }
                    }
                    $detailslink='<a href="javascript:opencoursereqdisplay('.
                                  "'$dom','$cnum','$queue'".');">'.$cdesc.'</a>';
                    $approve = $count.':'.$cnum;
                    $reject = $cnum;
                    $namelink = &Apache::loncommon::aboutmewrapper(
                                &Apache::loncommon::plainname($ownername,$ownerdom),
                                $ownername,$ownerdom);
                }
                unless ($context eq 'pending') {
                    $row = '<td><span class="LC_nobreak"><label>'.
                           '<input type="radio" value="'.$approve.'" name="'.$count.'radioreq" />'.&mt('Approve').'</label>'.
                           '<label>'.('&nbsp;'x2).
                           '<input type="radio" value="'.$reject.'" name="'.$count.'radioreq" />'.&mt('Reject').'</label>'.
                           '<label>'.('&nbsp;'x2).
                           '<input type="radio" value="'."later:".$reject.'" name="'.$count.'radioreq" checked />'.&mt('Decide Later').
                           '</label></span><br /></td>';
                }
                $row .= '<td>'.$namelink.'</td>'."\n";
                if ($context eq 'course') {
                    $row .= '<td>'.$showsec.'</td>'."\n".
                            '<td>'.$showtime.'</td>'."\n";
                } elsif ($context eq 'requestauthor') {
                    $row .= '<td>'.$showtime.'</td>'."\n";
                } else { 
                    if ($context eq 'pending' || $context eq 'stillpending') {
                        $row .= '<td>'.$instcode.'</td>'."\n";
                    } else {
                        $row .= '<td>'.$crstype.'</td>'."\n";
                    }
                    $row .= '<td>'.$showtime.'</td>'."\n".
                            '<td>'.$detailslink.'</td>'."\n";
                }
                $output .= &Apache::loncommon::start_data_table_row()."\n".
                           $row.
                           &Apache::loncommon::end_data_table_row()."\n";
                $count ++;
            }
        }
    }
    $output .= &Apache::loncommon::end_data_table();
    return $output;
}

sub update_request_queue {
    my ($context,$cdom,$cnum,$coursedesc) = @_;
    my ($output,$access_start,$access_end,$limit,$cap,$notifylist,$namespace,
        $stucounts,$idx,$classlist,%requesthash,$cid,$domdesc,$now,
        $sender,$approvedmsg,$rejectedmsg,$beneficiary,
        @existing,@missingreq,@invalidusers,@limitexceeded,@completed,
        @processing_errors,@warn_approves,@warn_rejects,@approvals,@warn_dels,
        @rejections,@rejectionerrors,@nopermissions,%courseroles,@toremove,
        %communityroles,%domdefs,%approvalmsg,%rejectionmsg,$crstype,$queue,
        $firsturl,$uniquecode,%codes);
    my $count=0;
    while (my @course = &Apache::loncommon::get_env_multiple('form.'.$count.'radioreq')) {
        if ($course[0] =~ /^\d+:.*/) {
            push(@approvals,$course[0]);
        } elsif ($course[0] =~ /^later:.*/) {
            #decide later
        } else {
            push(@rejections,$course[0]);
        }
        $count+=1;
    }

    $now = time;
    $sender = $env{'user.name'}.':'.$env{'user.domain'};
    if ($context eq 'course') {
        $namespace = 'selfenrollrequests';
        $beneficiary = 'enroller';
        $cid = $env{'request.course.id'};
        $crstype = lc(&Apache::loncommon::course_type());
        $firsturl = &course_portal_url($cnum,$cdom);
        %requesthash = &Apache::lonnet::dump($namespace,$cdom,$cnum);
        $access_start =  $env{'course.'.$cid.'.internal.selfenroll_start_access'};
        $access_end =  $env{'course.'.$cid.'.internal.selfenroll_end_access'};
        $limit = $env{'course.'.$cid.'.internal.selfenroll_limit'};
        $cap = $env{'course.'.$cid.'.internal.selfenroll_cap'};
        $notifylist = $env{'course.'.$cid.'.internal.selfenroll_notifylist'};
        ($stucounts,$idx,$classlist) = &get_student_counts($cdom,$cnum);
        $approvedmsg = [{
                            mt => 'Your request for enrollment has been approved.',
                        },
                        {
                            mt   => 'Visit [_1] to log-in and access the course',
                            args => [$firsturl],
                        }];
        $rejectedmsg =  [{
                            mt => 'Your request for enrollment has not been approved.',
                        }];
    } elsif ($context eq 'requestauthor') {
        $namespace = 'requestauthorqueue';
        $beneficiary = 'requestauthor';
        %requesthash = &Apache::lonnet::dump_dom($namespace,$cdom);
        my %domdefs = &Apache::lonnet::get_domain_defaults($cdom);
        if (ref($domdefs{'requestauthor'}) eq 'HASH') {
            if (ref($domdefs{'requestauthor'}{'notify'}) eq 'HASH') {
                $notifylist = $domdefs{'requestauthor'}{'notify'}{'approval'};
            }
        }
        my $domconfiguser = &Apache::lonnet::get_domainconfiguser($cdom);
        $firsturl = &course_portal_url($domconfiguser,$cdom);
        $approvedmsg = [{
                            mt => 'Your request for authoring space has been approved.',
                        },
                        {
                            mt   => 'Visit [_1] to log-in and select your author role',
                            args => [$firsturl],
                        }];
        $rejectedmsg =  [{
                            mt => 'Your request for authoring space has not been approved.',
                        }];
        $domdesc = &Apache::lonnet::domain($cdom);
    } else {
        $domdesc = &Apache::lonnet::domain($cdom);
        $namespace = 'courserequestqueue';
        $beneficiary = 'courserequestor';
        $queue = 'approval';
        if ($env{'form.queue'} eq 'pending') {
            $queue = 'pending';
        }
        %requesthash = &Apache::lonnet::dump_dom($namespace,$cdom,'_'.$queue);
        my %domconfig = &Apache::lonnet::get_dom('configuration',['requestcourses'],$cdom);
        if (ref($domconfig{'requestcourses'}) eq 'HASH') {
            if (ref($domconfig{'requestcourses'}{'notify'}) eq 'HASH') { 
                $notifylist = $domconfig{'requestcourses'}{'notify'}{'approval'};
            }
            if ($domconfig{'requestcourses'}{'uniquecode'}) {
                $uniquecode = 1;
            }
        }
        $approvalmsg{'course'} = 
                        [{
                            mt => 'Your course request has been approved.',
                        },
                        {
                            mt   => 'Visit [_1] to log-in and access the course',
                            args => [],
                        }];
        $rejectionmsg{'course'} =
                        [{
                            mt => 'Your course request has not been approved.',
                        }];

        $approvalmsg{'community'} = 
                        [{
                            mt => 'Your community request has been approved.',
                        },
                        {
                            mt   => 'Visit [_1] to log-in and access the community',
                            args => [],
                        }];

        $rejectionmsg{'community'} = 
                        [{
                            mt => 'Your community request has not been approved.',
                        }];

        %domdefs = &Apache::lonnet::get_domain_defaults($cdom);
        my @roles = &Apache::lonuserutils::roles_by_context('course');
        foreach my $role (@roles) {
            $courseroles{$role}=&Apache::lonnet::plaintext($role,'Course');
        }
        foreach my $role (@roles) {
            $communityroles{$role}=&Apache::lonnet::plaintext($role,'Community');
        }
    }
    foreach my $item (sort {$a <=> $b} @approvals) {
        if ($context eq 'course') {
            my ($num,$uname,$udom,$usec) = split(/:/,$item);
            my $uhome = &Apache::lonnet::homeserver($uname,$udom);
            if ($uhome ne 'no_host') {
                if (exists($requesthash{$uname.':'.$udom})) {
                    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')) {
                                push(@existing,$uname.':'.$udom);
                                next;
                            }
                        }
                    }
                } else {
                    push(@missingreq,$uname.':'.$udom);
                    next;
                }
                if (!grep(/^\Q$item\E$/,@rejections)) {
                    if ($limit eq 'allstudents') {
                        if ($stucounts->{$limit} >= $cap) {
                            push(@limitexceeded,$uname.':'.$udom);
                            last;
                        }
                    } elsif ($limit eq 'selfenrolled') {
                        if ($stucounts->{$limit} >= $cap) {
                            push(@limitexceeded,$uname.':'.$udom);
                            last;
                        }
                    }
                    my $result =
                        &Apache::lonnet::modify_student_enrollment($udom,$uname,undef,undef,undef,undef,undef,$usec,$access_end,$access_start,'selfenroll',undef,$cdom.'_'.$cnum,1);
                    if ($result eq 'ok') {
                        push(@completed,$uname.':'.$udom);
                        $stucounts->{'allstudents'} ++;
                        $stucounts->{'selfenrolled'} ++;
                        &send_selfserve_notification($uname.':'.$udom,$approvedmsg,
                                       $cid,$coursedesc,$now,$beneficiary,$sender,
                                       undef,undef,$crstype);
                        my %userrequest = (
                            $cdom.'_'.$cnum => {
                                timestamp   => $now,
                                section     => $usec,
                                adjudicator => $env{'user.name'}.':'.$env{'user.domain'},
                                status      => 'approved',
                            }
                        );
                        my $userresult =
                            &Apache::lonnet::put($namespace,\%userrequest,$udom,$uname);
                        if ($userresult ne 'ok') {
                            push(@warn_approves,$uname.':'.$udom);
                        }
                    } else {
                        push(@processing_errors,$uname.':'.$udom);
                    }
                }
            } else {
                push(@invalidusers,$uname.':'.$udom);
            }
        } elsif ($context eq 'requestauthor') {
            my ($num,$uname) = split(/:/,$item);
            my $uhome = &Apache::lonnet::homeserver($uname,$cdom);
            if ($uhome ne 'no_host') {
                my ($user_is_adv,$user_is_author) = &Apache::lonnet::is_advanced_user($cdom,$uname);
                if ($user_is_author) {
                    push(@existing,$uname);
                } elsif (&Apache::lonnet::usertools_access($uname,$cdom,'requestauthor',
                                                           undef,'requestauthor')) {
                    if (&Apache::lonnet::allowed('cau',$cdom)) {
                        if (&Apache::lonnet::assignrole($cdom,$uname,'/'.$cdom.'/','au',undef,time,undef,undef,'requestauthor') eq 'ok') {
                            push(@completed,$uname);
                            unless (&Apache::lonnet::del_dom($namespace,[$uname.'_approval'],$cdom) eq 'ok') {
                                push(@warn_dels,$uname);
                            }
                            &send_selfserve_notification($uname.':'.$cdom,
                                                         $approvedmsg,undef,undef,$now,
                                                         $beneficiary,$sender);
                            my %userrequest = (
                                author => {
                                          timestamp   => $now,
                                          adjudicator => $env{'user.name'}.':'.$env{'user.domain'},
                                          status      => 'approved',
                                        },
                                author_status => 'approved',
                            );
                            my $userresult =
                                &Apache::lonnet::put('requestauthor',\%userrequest,$cdom,$uname);
                            if ($userresult ne 'ok') {
                                push(@warn_approves,$item);
                            }
                        } else {
                            push(@processing_errors,$uname);
                        }
                    } else {
                        push(@nopermissions,$uname);
                    }
                } else {
                    push(@nopermissions,$uname);
                }
            } else {
                push(@invalidusers,$uname.':'.$cdom);
            }
            push(@toremove,(@invalidusers,@nopermissions));
        } else {
            my ($num,$cnum) = split(':',$item);
            if (ref($requesthash{$cnum.'_'.$queue}) eq 'HASH') {
                if (&Apache::lonnet::homeserver($cnum,$cdom) eq 'no_host') {
                    my $ownername = $requesthash{$cnum.'_'.$queue}{'ownername'};
                    my $ownerdom = $requesthash{$cnum.'_'.$queue}{'ownerdom'};
                    $crstype = $requesthash{$cnum.'_'.$queue}{'crstype'};
                    my $coursedesc = $requesthash{$cnum.'_'.$queue}{'description'};
                    my $longroles = \%courseroles;
                    if ($crstype eq 'community') {
                        $longroles = \%communityroles;
                    }
                    my $cancreate;
                    if ($cdom eq $ownerdom) {
                        if (&Apache::lonnet::usertools_access($ownername,$ownerdom,$crstype,
                                                              undef,'requestcourses')) {
                            $cancreate = 1;
                        }
                    } else {
                        my %userenv = &Apache::lonnet::userenvironment($ownerdom,$ownername,'reqcrsotherdom.'.$crstype);
                        if ($userenv{'reqcrsotherdom.'.$crstype}) {
                            my @doms = split(',',$userenv{'reqcrsotherdom.'.$crstype});
                            if (grep(/^\Q$cdom\E:/,@doms)) {
                                $cancreate = 1;
                            }
                        }
                    }
                    if ($cancreate) {
                        my $requestkey = $cdom.'_'.$cnum;
                        my %history = 
                            &Apache::lonnet::restore($requestkey,'courserequests',
                                                     $ownerdom,$ownername);
                        if ((ref($history{'details'}) eq 'HASH') && 
                            ($history{'disposition'} eq $queue)) {
                            my ($logmsg,$newusermsg,$addresult,$enrollcount,$response,$keysmsg,$code);
                            my $result = &course_creation($cdom,$cnum,$context,$history{'details'},\$logmsg,
                                                      \$newusermsg,\$addresult,\$enrollcount,
                                                      \$response,\$keysmsg,\%domdefs,$longroles,\$code);
                            if ($result eq 'created') {
                                if ($crstype eq 'community') {
                                    $approvedmsg = $approvalmsg{'community'};
                                } else {
                                    $approvedmsg = $approvalmsg{'course'};
                                }
                                my $firsturl = &course_portal_url($cnum,$cdom);
                                if (ref($approvedmsg) eq 'ARRAY') {
                                    if (ref($approvedmsg->[1]) eq 'HASH') {
                                        $approvedmsg->[1]->{'args'} = [$firsturl];
                                    }
                                    if ($code) {
                                        push(@{$approvedmsg},
                                            {
                                              mt   => 'Students can automatically select your course by entering this code: [_1]',
                                              args => [$code],
                                            });
                                        $codes{$cnum} = $code;
                                    }
                                }
                                push(@completed,$cnum);
                                
                                unless (&Apache::lonnet::del_dom($namespace,[$cnum.'_'.$queue],$cdom) eq 'ok') {
                                    push(@warn_dels,$cnum);
                                }
                                &send_selfserve_notification($ownername.':'.$ownerdom,
                                              $approvedmsg,$cid,$coursedesc,$now,
                                              $beneficiary,$sender,undef,undef,$crstype);
                                my %reqhash = (
                                                reqtime     => $history{'reqtime'},
                                                crstype     => $history{'crstype'},
                                                details     => $history{'details'},
                                                disposition => $history{'disposition'},
                                                status      => 'created',
                                                adjudicator => $env{'user.name'}.':'.
                                                               $env{'user.domain'},
                                              );
                                my $userresult =
                                    &Apache::lonnet::store_userdata(\%reqhash,$requestkey,
                                                   'courserequests',$ownerdom,$ownername);
                                if ($userresult eq 'ok') {
                                    my %status = (
                                                   'status:'.$cdom.':'.$cnum => 'created'
                                                 );
                                    my $statusresult = 
                                        &Apache::lonnet::put('courserequests',\%status,
                                                             $ownerdom,$ownername);
                                    if ($statusresult ne 'ok') {
                                        push(@warn_approves,$cnum);
                                    }
                                }
                                if ($userresult ne 'ok') {
                                    push(@warn_approves,$cnum);
                                }
                            } else {
                                push(@processing_errors,$cnum);
                            }
                        } else {
                            push(@processing_errors,$cnum);
                        }
                    } else {
                        push(@nopermissions,$cnum);
                    }
                } else {
                    push(@existing,$cnum);
                }
            } else {
                push(@missingreq,$cnum);
            }
        }
    }
    my @changes = (@completed,@rejections);
    if ($context eq 'domain') {
        @changes = map {$_.'_'.$queue} (@changes);
    } elsif ($context eq 'requestauthor') {
        @changes = map {$_.'_approval'} (@changes);
    }
    if (@rejections) {
        foreach my $item (@rejections) {
            if (($context eq 'course') || ($context eq 'requestauthor')) {
                my ($user,$uname,$udom,%userrequest,$key);
                if ($context eq 'requestauthor') {
                    $uname = $item;
                    $udom = $cdom;
                    $user = $uname.':'.$udom;
                    $key = 'author';
                } else {
                    $user = $item;
                    ($uname,$udom) = split(/:/,$user);
                    $key = $cdom.'_'.$cnum;
                }
                &send_selfserve_notification($user,$rejectedmsg,$cid,$coursedesc,
                                             $now,$beneficiary,$sender,undef,undef,
                                             $crstype);
                %userrequest = (
                    $key => {
                        timestamp   => $now,
                        adjudicator => $env{'user.name'}.':'.$env{'user.domain'},
                        status      => 'rejection',
                    }
                );
                if ($context eq 'requestauthor') {
                    $userrequest{'author_status'} = 'rejection';  
                }
                my $userresult =
                    &Apache::lonnet::put('requestauthor',\%userrequest,$udom,$uname);
                if ($userresult ne 'ok') {
                    push(@warn_rejects,$item);
                }
            } else {
                my $cnum = $item;
                if (ref($requesthash{$cnum.'_'.$queue}) eq 'HASH') {
                    if (&Apache::lonnet::homeserver($cnum,$cdom) eq 'no_host') {
                        my $requestkey = $cdom.'_'.$cnum;
                        my $ownername = $requesthash{$cnum.'_'.$queue}{'ownername'};
                        my $ownerdom = $requesthash{$cnum.'_'.$queue}{'ownerdom'};
                        my $coursedesc = $requesthash{$cnum.'_'.$queue}{'description'};
                        $crstype = $requesthash{$cnum.'_'.$queue}{'crstype'};
                        if ($crstype eq 'community') {
                            $rejectedmsg = $rejectionmsg{'community'};
                        } else {
                            $rejectedmsg = $rejectionmsg{'course'};
                        }
                        &send_selfserve_notification($ownername.':'.$ownerdom,$rejectedmsg,
                                                     $cid,$coursedesc,$now,$beneficiary,
                                                     $sender,undef,undef,$crstype);
                        my %history =
                            &Apache::lonnet::restore($requestkey,'courserequests',
                                                     $ownerdom,$ownername);
                        if ((ref($history{'details'}) eq 'HASH') &&
                            ($history{'disposition'} eq $queue)) {
                            my %reqhash = (
                                            reqtime     => $history{'reqtime'},
                                            crstype     => $history{'crstype'},
                                            details     => $history{'details'},
                                            disposition => $history{'disposition'},
                                            status      => 'rejected',
                                            adjudicator => $env{'user.name'}.':'.$env{'user.domain'},
                                              );
                            my $userresult =
                                &Apache::lonnet::store_userdata(\%reqhash,$requestkey,
                                                'courserequests',$ownerdom,$ownername);
                            if ($userresult eq 'ok') {
                                my %status = (
                                               'status:'.$cdom.':'.$cnum => 'rejected'
                                             );
                                my $statusresult =
                                    &Apache::lonnet::put('courserequests',\%status,
                                                         $ownerdom,$ownername);
                                if ($statusresult ne 'ok') {
                                    push(@warn_rejects,$cnum);
                                }
                            } else {
                                push(@warn_rejects,$cnum);
                            }
                            unless (&Apache::lonnet::del_dom($namespace,[$cnum.'_'.$queue],$cdom) eq 'ok') {
                                push(@warn_dels,$cnum);
                            }
                        } else {
                            push(@warn_rejects,$cnum);
                        }
                    } else {
                        push(@existing,$cnum);
                    }
                } else {
                    push(@rejectionerrors,$cnum);
                }
            }
        }
    }
    if (@toremove) {
        foreach my $item (@toremove) {
            my %userrequest = (
                author => {
                            timestamp   => $now,
                            adjudicator => $env{'user.name'}.':'.$env{'user.domain'},
                            status      => 'deleted',
                          },
                          author_status => 'deleted',
            );
            &Apache::lonnet::put('requestauthor',\%userrequest,$cdom,$item);
        }
        @toremove = map {$_.'_approval'} (@toremove);
        my $delresult = &Apache::lonnet::del_dom($namespace,\@toremove,$cdom);
    }
    if (@changes) {
        my $delresult;
        if ($context eq 'course') {
            $delresult = &Apache::lonnet::del($namespace,\@changes,$cdom,$cnum);
        } else {
            $delresult = &Apache::lonnet::del_dom($namespace,\@changes,$cdom);
        }
        if ($delresult eq 'ok') {
            my $namelink =
                &Apache::loncommon::plainname($env{'user.name'},$env{'user.domain'}).' ('.$env{'user.name'}.':'.$env{'user.domain'}.')';
            my ($chgmsg,$approvedlist,$rejectedlist);
            if ($context eq 'course') {
                $chgmsg = "'Action was taken on the following enrollment requests by [_1].',$namelink";
                if (@completed) {
                    $approvedlist = join("\n",@completed);
                    if ($crstype eq 'community') {
                        $output .= '<p>'.&mt('The following were enrolled in the community:').'<ul>';
                    } else {
                        $output .= '<p>'.&mt('The following were enrolled in the course:').'<ul>';
                    }
                    foreach my $user (@completed) {
                        my ($uname,$udom) = split(/:/,$user);
                        my $userlink =
                            &Apache::loncommon::aboutmewrapper(&Apache::loncommon::plainname($uname,$udom),$uname,$udom);
                        $output .= '<li>'.$userlink.'</li>';
                    }
                    $output .= '</ul></p>';
                }
                if (@rejections) {
                    $rejectedlist = join("\n",@rejections);
                    $output .= '<p>'.&mt('The following enrollment requests were rejected:').'<ul>';
                    foreach my $user (@rejections) {
                        $output .= '<li>'.$user.'</li>';
                    }
                    $output .= '</ul></p>';
                }
                if ($notifylist ne '') {
                    &send_selfserve_notification($notifylist,$chgmsg,$cid,$coursedesc,
                                                 $now,'coursemanagers',$sender,
                                                 $approvedlist,$rejectedlist,$crstype);
                }
            } elsif ($context eq 'requestauthor') {
                $chgmsg = "'Action was taken on the following authoring space requests by [_1].',$namelink";
                if (@completed) {
                    $approvedlist = join("\n",@completed);
                    $output .= '<p>'.&mt('The following requests were approved:').'<ul>';
                    foreach my $uname (@completed) {
                        my $userlink =
                            &Apache::loncommon::aboutmewrapper(&Apache::loncommon::plainname($uname,$cdom),$uname,$cdom);
                        $output .= '<li>'.$userlink.'</li>';
                        
                    }
                    $output .= '</ul></p>';
                }
                if (@rejections) {
                    $rejectedlist = join("\n",@rejections);
                    $output .= '<p>'.&mt('The following requests were rejected:').'<ul>';
                    foreach my $uname (@rejections) {
                        my $userlink =
                            &Apache::loncommon::aboutmewrapper(&Apache::loncommon::plainname($uname,$cdom),$uname,$cdom);
                        $output .= '<li>'.$userlink.'</li>';
                    }
                    $output .= '</ul></p>';
                }
                if ($notifylist ne '') {
                    &send_selfserve_notification($notifylist,$chgmsg,undef,$domdesc,
                                                 $now,'authormanagers',$sender,
                                                 $approvedlist,$rejectedlist);
                }
            } else {
                $chgmsg = "'Action was taken on the following course and community requests by [_1].',$namelink";
                if (@completed) {
                    $approvedlist = join("\n",@completed);
                    $output .= '<p>'.&mt('The following courses/communities were created:').'<ul>';
                    foreach my $cnum (@completed) {
                        my $showcourse;
                        if (ref($requesthash{$cnum.'_'.$queue})) {
                            $showcourse = $requesthash{$cnum.'_'.$queue}{'description'};
                        } else {
                            $showcourse = $cnum;
                        }
                        my $syllabuslink =
                            &Apache::loncommon::syllabuswrapper($showcourse,$cnum,$cdom);
                        if ($uniquecode && $codes{$cnum}) {
                            $syllabuslink .= &mt('Unique code: [_1]',$codes{$cnum});
                        }
                        $output .= '<li>'.$syllabuslink.'</li>';
                    }
                    $output .= '</ul></p>';
                }
                if (@rejections) {
                    $rejectedlist = join("\n",@rejections);
                    $output .= '<p>'.&mt('The following requests were rejected:').'<ul>';
                    foreach my $cnum (@rejections) {
                        my $showcourse;
                        if (ref($requesthash{$cnum.'_'.$queue})) {
                            $showcourse = $requesthash{$cnum.'_'.$queue}{'description'};
                        } else {
                            $showcourse = $cnum;
                        }
                        $output .= '<li>'.$showcourse.'</li>';
                    }
                    $output .= '</ul></p>';
                }
                if ($notifylist ne '') {
                    &send_selfserve_notification($notifylist,$chgmsg,$cid,$domdesc,
                                                 $now,'domainmanagers',$sender,
                                                 $approvedlist,$rejectedlist,$crstype);
                }
            }
        }
    }
    if (@existing) {
        if ($context eq 'course') {
            $output .= '<p>'.&mt('The following enrollment requests were deleted because the user is already enrolled in the course:').'<ul>';
            foreach my $user (@existing) {
                $output .= '<li>'.$user.'</li>';
            }
            $output .= '</ul></p>';
        } elsif ($context eq 'requestauthor') {
            $output .= '<p>'.&mt('Authoring space requests from the following users were deleted because one already exists:').'<ul>';
            foreach my $uname (@existing) {
                my $userlink =
                    &Apache::loncommon::aboutmewrapper(&Apache::loncommon::plainname($uname,$cdom),$uname,$cdom);
                $output .= '<li>'.$userlink.'</li>';
            }
            $output .= '</ul></p>';
        } else {
            $output .= '<p>'.&mt('The following course/community creation requests were deleted because the course or community has already been created:').'<ul>';
            foreach my $cnum (@existing) {
                my $showcourse;
                my %coursehash = &Apache::lonnet::coursedescription($cdom.'/'.$cnum);
                if ($coursehash{'description'} ne '') {
                    $showcourse = $coursehash{'description'};
                } else {
                    $showcourse = $cnum;
                }
                $output .= '<li>'.$showcourse.'</li>';
            }
            $output .= '</ul></p>';
        }
    }
    if (@missingreq) {
        if ($context eq 'course') {
            $output .= '<p>'.&mt('The following enrollment requests were ignored because the request is no longer in the enrollment queue:').'<ul>';
            foreach my $user (@missingreq) {
                $output .= '<li>'.$user.'</li>';
            }
            $output .= '</ul></p>';
        } elsif ($context eq 'requestauthor') {
            $output .= '<p>'.&mt('The following requests were ignored because the request is no longer in the queue:').'<ul>';
            foreach my $uname (@missingreq) {
                my $userlink =
                    &Apache::loncommon::aboutmewrapper(&Apache::loncommon::plainname($uname,$cdom),$uname,$cdom);
                $output .= '<li>'.$userlink.'</li>';
            }
            $output .= '</ul></p>';
        } else {
            $output .= '<p>'.&mt('The following course/community creation requests were ignored because the request is no longer in the queue:').'<ul>';
            foreach my $cnum (@missingreq) {
                $output .= '<li>'.$cnum.'</li>';
            }
            $output .= '</ul></p>';
        }
    }
    if (@invalidusers) {
        if ($context eq 'course') {
            $output .= '<p>'.&mt('The following enrollment requests were deleted because the requestor does not have a LON-CAPA account:').'<ul>';
            foreach my $user (@invalidusers) {
                $output .= '<li>'.$user.'</li>';
            }
            $output .= '</ul></p>';
        } elsif ($context eq 'requestauthor') {
            $output .= '<p>'.&mt('The following authoring space requests were deleted because the requestor does not have a LON-CAPA account:').'<ul>';
            foreach my $uname (@invalidusers) {
                my $userlink =
                    &Apache::loncommon::aboutmewrapper(&Apache::loncommon::plainname($uname,$cdom),$uname,$cdom);
                $output .= '<li>'.$userlink.'</li>';
            }
            $output .= '</ul></p>';
        }
    }
    if (@limitexceeded) {
        if ($context eq 'course') {
            $output .= '<p>'.&mt('The following enrollment requests were skipped because the enrollment limit has been reached for the course:').'<ul>';
            foreach my $user (@limitexceeded) {
                $output .= '<li>'.$user.'</li>';
            }
            $output .= '</ul></p>';
        }
    }
    if (@nopermissions) {
        if ($context eq 'course') {
            $output .= '<p>'.&mt('The following course/community creation requests could not be processed because the owner does not have rights to create this type of course:').'<ul>';
            foreach my $cnum (@nopermissions) {
                my $showcourse;
                if (ref($requesthash{$cnum.'_'.$queue})) {
                    $showcourse = $requesthash{$cnum.'_'.$queue}{'description'};
                } else {
                    $showcourse = $cnum;
                }
                $output .= '<li>'.$showcourse.'</li>';
            }
            $output .= '</ul></p>';
        } elsif ($context eq 'requestauthor') {
            $output .= '<p>'.&mt('The following requests could not be processed because the requestor does not have rights to request an authoring space:').'<ul>';
            foreach my $uname (@nopermissions) {
                my $userlink =
                    &Apache::loncommon::aboutmewrapper(&Apache::loncommon::plainname($uname,$cdom),$uname,$cdom);
                $output .= '<li>'.$userlink.'</li>';
            }
            $output .= '</ul></p>';
        }
    }
    if (@processing_errors) {
        if ($context eq 'course') {
            $output .= '<p>'.&mt('The following enrollment requests could not be processed because an error occurred:').'<ul>';
            foreach my $user (@processing_errors) {
                $output .= '<li>'.$user.'</li>';
            }
            $output .= '</ul></p>';
        } elsif ($context eq 'requestauthor') {
            $output .= '<p>'.&mt('The following requests could not be processed because an error occurred:').'<ul>';
            foreach my $uname (@processing_errors) {
                my $userlink =
                    &Apache::loncommon::aboutmewrapper(&Apache::loncommon::plainname($uname,$cdom),$uname,$cdom);
                $output .= '<li>'.$userlink.'</li>';
            }
            $output .= '</ul></p>';
        } else {
            $output .= '<p>'.&mt('The following course/community creation requests could not be processed because an error occurred:').'<ul>';
            foreach my $cnum (@processing_errors) {
                my $showcourse;
                if (ref($requesthash{$cnum.'_'.$queue})) {
                    $showcourse = $requesthash{$cnum.'_'.$queue}{'description'};
                } else {
                    $showcourse = $cnum;
                }
                $output .= '<li>'.$showcourse.'</li>';
            }
            $output .= '</ul></p>';
        }
    }
    if (@rejectionerrors) {
        $output .= '<p>'.&mt('The following course/community creation request rejections could not be fully processed because an error occurred:').'<ul>';
        foreach my $cnum (@rejectionerrors) {
            my $showcourse;
            if (ref($requesthash{$cnum.'_'.$queue})) {
                $showcourse = $requesthash{$cnum.'_'.$queue}{'description'};
            } else {
                $showcourse = $cnum;
            }
            $output .= '<li>'.$showcourse.'</li>';
        }
        $output .= '</ul></p>';
    }
    if (@warn_approves || @warn_rejects) {
        if ($context eq 'course') {
            $output .= '<p>'.&mt("For the following users, an error occurred when updating the user's own self-enroll requests record:").'<ul>';
            foreach my $user (@warn_approves) {
                $output .= '<li>'.$user.'</li>';
            }
            $output .= '</ul></p>';
        } elsif ($context eq 'requestauthor') {
            $output .= '<p>'.&mt("For the following users, an error occurred when updating the user's own author request record:").'<ul>';
            foreach my $uname (@warn_approves,@warn_rejects) {
                my $userlink =
                    &Apache::loncommon::aboutmewrapper(&Apache::loncommon::plainname($uname,$cdom),$uname,$cdom);
                $output .= '<li>'.$userlink.'</li>';
            }
            $output .= '</ul></p>';
        } else {
            $output .= '<p>'.&mt("For the following course/community requests an error occurred when updating the requestor's own requests record:").'<ul>';
            foreach my $cnum (@warn_approves,@warn_rejects) {
                my $showcourse;
                if (ref($requesthash{$cnum.'_'.$queue})) {
                    $showcourse = $requesthash{$cnum.'_'.$queue}{'description'};
                } else {
                    $showcourse = $cnum;
                }
                $output .= '<li>'.$showcourse.'</li>';
            }
            $output .= '</ul></p>';
        }
    }
    if (@warn_dels) {
        if ($context eq 'requestauthor') {
            $output .= '<p>'.&mt("For the following requests an error occurred when removing the request from the queue:").'<ul>';
            foreach my $uname (@warn_dels) {
                my $userlink =
                    &Apache::loncommon::aboutmewrapper(&Apache::loncommon::plainname($uname,$cdom),$uname,$cdom);
                $output .= '<li>'.$userlink.'</li>';
            }
            $output .= '</ul></p>';
        } else {
            $output .= '<p>'.&mt("For the following course/community requests an error occurred when removing requests from the pending queue:").'<ul>';
            foreach my $cnum (@warn_dels) {
                my $showcourse;
                if (ref($requesthash{$cnum.'_'.$queue})) {
                    $showcourse = $requesthash{$cnum.'_'.$queue}{'description'};
                } else {
                    $showcourse = $cnum;
                }
                $output .= '<li>'.$showcourse.'</li>';
            }
            $output .= '</ul></p>';
        }
    }
    return $output;
}

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 $firsturl;
}

sub get_student_counts {
    my ($cdom,$cnum) = @_;
    my (%idx,%stucounts);
    my $classlist = &Apache::loncoursedata::get_classlist($cdom,$cnum);
    $idx{'type'} = &Apache::loncoursedata::CL_TYPE();
    $idx{'status'} = &Apache::loncoursedata::CL_STATUS();
    while (my ($student,$data) = each(%$classlist)) {
        if (($data->[$idx{'status'}] eq 'Active') ||
            ($data->[$idx{'status'}] eq 'Future')) {
            if ($data->[$idx{'type'}] eq 'selfenroll') {
                $stucounts{'selfenroll'} ++;
            }
            $stucounts{'allstudents'} ++;
        }
    }
    return (\%stucounts,\%idx,$classlist);
}

sub course_creation {
    my ($dom,$cnum,$context,$details,$logmsg,$newusermsg,$addresult,$enrollcount,$output,
        $keysmsg,$domdefs,$longroles,$coderef) =  @_;
    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'};
    if ($context eq 'domain') {
        $ownername = $details->{'owner'};
        $ownerdom  = $details->{'domain'};
    } else {
        $ownername = $env{'user.name'};
        $ownerdom  = $env{'user.domain'};
    }
    my $owneremail;
    my %emails = &Apache::loncommon::getemails($ownername,$ownerdom);
    foreach my $email ('permanentemail','critnotification','notification') {
        $owneremail = $emails{$email};
        last if ($owneremail ne '');
    }
    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,$coderef);
    if ($cid eq "/$dom/$cnum") {
        $result = 'created';
    } else {
        $result = 'error: '.$cid;
    }
    return $result;
}

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 uniquecode};
    if ((ref($details) eq 'HASH') && (ref($domdefs) eq 'HASH')) {
        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'};
        $batchhash{'authtype'} = $domdefs->{'auth_def'};
        $batchhash{'authparam'} = $domdefs->{'auth_arg_def'};
        if ($details->{'crstype'} eq 'community') {
            $batchhash{'crstype'} = 'Community';
        } else {
            $batchhash{'crstype'} = 'Course';
        }
        my ($owner_firstname,$owner_lastname);
        if ($context eq 'domain') {
            my %userenv = &Apache::lonnet::userenvironment($details->{'domain'},
                                                           $details->{'owner'},
                                                           'firstname','lastname');
            $owner_firstname = $userenv{'firstname'};
            $owner_lastname = $userenv{'lastname'};
        } else {
            $owner_firstname = $env{'environment.firstname'};
            $owner_lastname = $env{'environment.lastname'};
        }
        if (ref($details->{'personnel'}) eq 'HASH') {
            %{$batchhash{'users'}} = %{$details->{'personnel'}};
            if (ref($batchhash{'users'}) eq 'HASH') {  
                foreach my $userkey (keys(%{$batchhash{'users'}})) {
                    if (ref($batchhash{'users'}{$userkey}) eq 'HASH') {
                        if (ref($batchhash{'users'}{$userkey}{'roles'}) eq 'ARRAY') {
                            foreach my $role (@{$batchhash{'users'}{$userkey}{'roles'}}) {
                                my $start = '';
                                my $end = '';
                                if ($role eq 'st') {
                                    $start = $details->{'accessstart'};
                                    $end = $details->{'accessend'};
                                }
                                $batchhash{'users'}{$userkey}{$role}{'start'} = $start;
                                $batchhash{'users'}{$userkey}{$role}{'end'} = $end;
                            } 
                        }
                    }
                }
            }
        }
        $batchhash{'users'}{$owner}{firstname} = $owner_firstname;
        $batchhash{'users'}{$owner}{lastname} = $owner_lastname;
        $batchhash{'users'}{$owner}{emailenc} = $emailenc;
        $batchhash{'users'}{$owner}{owneremail} = $owneremail;
    }
    return %batchhash;
}

sub can_clone_course {
    my ($uname,$udom,$clonecrs,$clonedom,$crstype) = @_;
    my $canclone;
    my $ccrole = 'cc';
    if ($crstype eq 'community') {
        $ccrole = 'co';
    }
    my %roleshash = &Apache::lonnet::get_my_roles($uname,$udom,'userroles',['active'],
                                                  [$ccrole],[$clonedom]);
    if (exists($roleshash{$clonecrs.':'.$clonedom.':'.$ccrole})) {
        $canclone = 1;
    } else {
        my %courseenv = &Apache::lonnet::userenvironment($clonedom,$clonecrs,('cloners'));
        my $cloners = $courseenv{'cloners'};
        if ($cloners ne '') {
            my @cloneable = split(',',$cloners);
            if (grep(/^\*$/,@cloneable)) {
                $canclone = 1;
            }
            if (grep(/^\*:\Q$udom\E$/,@cloneable)) {
                $canclone = 1;
            }
            if (grep(/^\Q$uname\E:\Q$udom\E$/,@cloneable)) {
                $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 .= '<br /><b>'.&mt('Enrollment requests pending Course Coordinator approval').'</b><br />';
        }
        $output .= &Apache::loncommon::start_data_table().
                   &Apache::loncommon::start_data_table_header_row().
                   '<th>'.&mt('Date requested').'</th><th>'.&mt('Course title').'</th>'.
                   '<th>'.&mt('User role').'</th><th>'.&mt('Section').'</th>'.
                   &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().
                               '<td>'.&Apache::lonlocal::locallocaltime($item).'</td>'.
                               '<td>'.$courseinfo{'description'}.'</td>'.
                               '<td>'.$rolename.'</td><td>'.$usec.'</td>'.
                               &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 =  '<span class="LC_warning">'.$output.'</span><br />';
        }
        &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 = '<span class="LC_warning">'.$output.'</span><br />';
        }
        &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 = '<br />'."\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 $result = &course_creation($dom,$cnum,'domain',$history{'details'},\$logmsg,\$newusermsg,\$addresult,\$enrollcount,\$response,\$keysmsg,\%domdefs,\%longroles,\$code);
                    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;
                            &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 .= '<form method="post" name="changequeue" action="/adm/createcourse" />'."\n".
                       '<input type="hidden" name="action" value="'.$env{'form.action'}.'" />'."\n".
                       '<input type="hidden" name="phase" value="requestchange" />'.
                       '<p>'.&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.','<b>','</b>').'<br />'.&mt('Requests may be left in the queue, or you can manually approve or reject them.').'</p>'.
                       &build_queue_display($dom,'stillpending',\%stillpending).
                       '<br /><input type="hidden" name="queue" value="pending" />'."\n".
                       '<input type="submit" name="processqueue" value="'.&mt('Save').'" />'.
                       '</form>';
        }
    }
    return $output;
}

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 '<span class="LC_warning">'.
                &mt('An authoring space has already been assigned to you.').'<br />'.
                &mt('Please select the Author role from your [_1]roles page[_2].','<a href="/adm/roles">',
                '</a>').'</span>';
    }
    unless ($env{'environment.canrequest.author'}) {
        return '<span class="LC_warning">'.
                &mt('You do not currently have rights to request an authoring space.').'<br />'.
                &mt('Please contact the [_1]helpdesk[_2] for assistance.','<a href="/adm/helpdesk">',
                '</a>').'</span>';
    }
    my $queued = &reqauthor_check();
    if ($queued =~ /^approval:(\d+)$/) {
        my $timestamp = $1;
        return '<span class="LC_info">'.
               &mt('A request for authoring space submitted on [_1] is awaiting approval',
               &Apache::lonlocal::locallocaltime($timestamp)).
               '</span>';
    } 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 '<span class="LC_info">'.
                   &mt('A request for authoring space submitted on [_1] has been approved.',
                   &Apache::lonlocal::locallocaltime($timestamp)).
                   '</span>';
        }
    }
    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 = '<span class="LC_info">'.
                      &mt('Access to authoring space has been activated').'</span><br />';
                      &Apache::lonroles::update_session_roles();
            &Apache::lonnet::appenv({'user.update.time'  => $now});
            if (ref($updateref)) {
                $$updateref = $now;
            }
            if (ref($dispositionref)) {
                $$dispositionref = 'created';
            }
        } else {
            $output = '<span class="LC_info">'.
                      &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 = '<span class="LC_info">'.
                      &mt('Your request for authoring space has been submitted for approval.').
                      '</span>';
            &Apache::lonnet::appenv({'environment.requestauthorqueued' => $val.':'.$now});
        } else {
            $output = '<span class="LC_info">'.
                      &mt('An error occurred saving your request for authoring space.').
                      '</span>';
        }
    }
    return $output;
}

1;

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>
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.